Setting the file. One moment. Execution State · Replatform · wix/skills · Skills DocsBundled file Execution Manifest
lib/execution-state.js
JavaScript·173 lines·5 KB
9
dryRunCrosswalkPath
,
10 loadCrosswalk,
11 rebuildCrosswalkIndexes,
12 seedCrosswalkFromCmsMirror,
13 wixRequestCapturesPath,
14} = require('./local-state.js');
15const { initUrlPreservationState } = require('./url-preservation-state.js');
16
17function importTasks(manifest) {
18 return (manifest.tasks || [])
19 .filter((task) => task && task.kind === 'import')
20 .sort((a, b) => Number(hasDownloadMirror(b)) - Number(hasDownloadMirror(a)));
21}
22
23function hasDownloadMirror(task) {
24 const mirror = task.state && task.state.cmsMirror;
25 if (!mirror || mirror.mode === 'none') {
26 return false;
27 }
28 return mirror.mode === 'download' || mirror.mode === 'download-and-upload' || mirror.downloadBeforeRun === true;
29}
30
31function hasLocalCrosswalk(task) {
32 return Boolean(task.state && task.state.crosswalkPath);
33}
34
35async function pathExists(filePath) {
36 try {
37 await fs.access(filePath);
38 return true;
39 } catch (error) {
40 if (error && error.code === 'ENOENT') {
41 return false;
42 }
43 throw error;
44 }
45}
46
47async function ensureEmptyNdjson(filePath) {
48 await fs.mkdir(path.dirname(filePath), { recursive: true });
49 if (!(await pathExists(filePath))) {
50 await fs.writeFile(filePath, '', 'utf8');
51 return true;
52 }
53 return false;
54}
55
56async function readMirrorRowsFromMap(task, rowsByTaskId) {
57 if (!rowsByTaskId || !Object.prototype.hasOwnProperty.call(rowsByTaskId, task.id)) {
58 return undefined;
59 }
60 return rowsByTaskId[task.id];
61}
62
63async function prepareExecutionState(projectDir, manifest, options = {}) {
64 const validation = validateManifest(manifest);
65 if (!validation.ok) {
66 return {
67 ok: false,
68 status: 'blocked',
69 errors: validation.errors,
70 actions: [],
71 };
72 }
73
74 const actions = [];
75 const errors = [];
76 const mirrorRowsByTaskId = options.cmsMirrorRowsByTaskId || {};
77 const dryRun = options.dryRun === true;
78
79 if (dryRun) {
80 const requestCapturesCreated = await ensureEmptyNdjson(wixRequestCapturesPath(projectDir));
81 actions.push({
82 action: requestCapturesCreated ? 'initialized_wix_request_captures' : 'kept_wix_request_captures',
83 path: 'state/attempts/wix-request-captures.ndjson',
84 });
85 const dryRunCrosswalkCreated = await ensureEmptyNdjson(dryRunCrosswalkPath(projectDir));
86 actions.push({
87 action: dryRunCrosswalkCreated ? 'initialized_dry_run_crosswalk' : 'kept_dry_run_crosswalk',
88 path: 'state/crosswalk/dry-run-crosswalk.ndjson',
89 });
90 }
91
92 for (const task of importTasks(manifest)) {
93 if (task.urlPreservation && task.urlPreservation.enabled === true) {
94 const urlActions = await initUrlPreservationState(projectDir);
95 for (const action of urlActions) {
96 actions.push({
97 taskId: task.id,
98 ...action,
99 });
100 }
101 }
102
103 if (!hasLocalCrosswalk(task)) {
104 continue;
105 }
106
107 const localPath = crosswalkPath(projectDir);
108 const localExists = await pathExists(localPath);
109
110 if (localExists) {
111 await loadCrosswalk(projectDir);
112 await rebuildCrosswalkIndexes(projectDir);
113 actions.push({
114 taskId: task.id,
115 action: 'rebuilt_crosswalk_indexes',
116 path: task.state.crosswalkPath,
117 });
118 } else if (hasDownloadMirror(task)) {
119 let rows = await readMirrorRowsFromMap(task, mirrorRowsByTaskId);
120 if (rows === undefined && typeof options.downloadCmsMirrorRows === 'function') {
121 rows = await options.downloadCmsMirrorRows(task);
122 }
123 if (rows === undefined) {
124 errors.push(`CMS mirror download configured for ${task.id}, but no CMS mirror rows provider was supplied`);
125 continue;
126 }
127 const seeded = await seedCrosswalkFromCmsMirror(projectDir, rows);
128 actions.push({
129 taskId: task.id,
130 action: seeded.seeded ? 'seeded_crosswalk_from_cms_mirror' : 'skipped_cms_seed',
131 ...seeded,
132 });
133 } else {
134 await ensureEmptyNdjson(localPath);
135 await rebuildCrosswalkIndexes(projectDir);
136 actions.push({
137 taskId: task.id,
138 action: 'initialized_empty_crosswalk',
139 path: task.state.crosswalkPath,
140 });
141 }
142
143 if (task.state.attemptJournalPath) {
144 const created = await ensureEmptyNdjson(attemptJournalPath(projectDir));
145 actions.push({
146 taskId: task.id,
147 action: created ? 'initialized_attempt_journal' : 'kept_attempt_journal',
148 path: task.state.attemptJournalPath,
149 });
150 }
151
152 }
153
154 if (errors.length) {
155 return {
156 ok: false,
157 status: 'blocked',
158 errors,
159 actions,
160 };
161 }
162
163 return {
164 ok: true,
165 status: 'ready',
166 errors: [],
167 actions,
168 };
169}
170
171module.exports = {
172 prepareExecutionState,
173};