Setting the file. One moment.
Orchestration Decisions · Wix Replatform · wix/skills · Skills Docs
ContentsBack to the top of the page This file
Number 45.115
Position 115 of 182
Type JavaScript
Size 10 KB
Lines 278 lib/ orchestration-decisions.js
JavaScript · 278 lines · 10 KB
],
9 websiteScope: [ 'websiteScope' , 'frontendScope' ],
10 faceliftMode: [ 'faceliftMode' , 'facelift' ],
11 fileInputPaths: [ 'fileInputPaths' ],
12 sourcePlatform: [ 'sourcePlatform' ],
13 sourceCredentialRef: [ 'sourceCredentialRef' ],
14 managementImportMode: [ 'managementImportMode' , 'importMode' ],
15 includeAdditionalFiles: [ 'includeAdditionalFiles' ],
16 targetSiteType: [ 'targetSiteType' ],
17 targetSiteBusinessType: [ 'targetSiteBusinessType' ],
18 editorWebsiteDecision: [ 'editorWebsiteDecision' ],
19 };
20
21 function readDecisionValue ( decisions , keys ) {
22 for ( const key of keys) {
23 const entry = decisions && decisions[key];
24 if (entry && Object . prototype .hasOwnProperty. call (entry, 'value' ) && entry.value != null ) {
25 return entry.value;
26 }
27 }
28 return null ;
29 }
30
31 function getDecisionEntry ( decisions , canonicalKey ) {
32 const keys = DECISION_ALIASES [canonicalKey] || [canonicalKey];
33 for ( const key of keys) {
34 const entry = decisions && decisions[key];
35 if (entry && Object . prototype .hasOwnProperty. call (entry, 'value' ) && entry.value != null ) {
36 return entry;
37 }
38 }
39 return null ;
40 }
41
42 // The only sourceMode values the router and preflight understand. Anything else is an
43 // intake error: an unknown mode must never fall through to the public credential set.
44 const CANONICAL_SOURCE_MODES = Object. freeze ([ 'private_data' , 'public_content' , 'files_only' ]);
45
46 // `authenticated_api` is an alias because preflight already treats it as private mode.
47 const SOURCE_MODE_ALIASES = Object. freeze ({
48 private_authenticated: 'private_data' ,
49 public_content_only: 'public_content' ,
50 authenticated_api: 'private_data' ,
51 });
52
53 // Decision keys that record sourceMode (see DECISION_ALIASES.sourceMode).
54 const SOURCE_MODE_DECISION_KEYS = Object. freeze ([ ... DECISION_ALIASES .sourceMode]);
55
56 // Returns the canonical mode for a known value or alias, and the raw value otherwise.
57 // Never throws: callers check validity with isKnownSourceMode().
58 function normalizeSourceMode ( value ) {
59 if (value == null ) return null ;
60 if ( typeof value === 'string' && Object . prototype .hasOwnProperty. call ( SOURCE_MODE_ALIASES , value)) {
61 return SOURCE_MODE_ALIASES [value];
62 }
63 return value;
64 }
65
66 function isKnownSourceMode ( value ) {
67 if ( typeof value !== 'string' ) return false ;
68 return CANONICAL_SOURCE_MODES . includes (value) || Object . prototype .hasOwnProperty. call ( SOURCE_MODE_ALIASES , value);
69 }
70
71 function invalidSourceModeMessage ( value ) {
72 const aliases = Object. entries ( SOURCE_MODE_ALIASES ). map (([ alias , target ]) => `${ alias } -> ${ target }` ). join ( ', ' );
73 return `invalid sourceMode ${ JSON . stringify ( value ) }; use one of ${ CANONICAL_SOURCE_MODES . join ( ', ' ) } (aliases: ${ aliases })` ;
74 }
75
76 function normalizeTargetSiteStrategy ( value ) {
77 if (value == null ) return null ;
78 switch (value) {
79 case 'new' :
80 return 'new_site' ;
81 case 'existing' :
82 return 'existing_site' ;
83 default :
84 return value;
85 }
86 }
87
88 function normalizeAutomationMode ( value ) {
89 if (value == null ) return null ;
90 switch (value) {
91 case '1-click' :
92 case '1click' :
93 case 'one-click' :
94 case 'one_click' :
95 return 'one_click' ;
96 case 'manual' :
97 return 'manual' ;
98 default :
99 return value;
100 }
101 }
102
103 function normalizeDeliveryMode ( value ) {
104 if (value == null ) return null ;
105 switch ( String (value). trim (). toLowerCase ()) {
106 case 'both' :
107 case 'management+website' :
108 case 'management_and_website' :
109 return 'management_and_website' ;
110 case 'management' :
111 case 'website' :
112 return String (value). trim (). toLowerCase ();
113 default :
114 return value;
115 }
116 }
117
118 function normalizeManagementImportMode ( value ) {
119 if (value == null ) return null ;
120 switch ( String (value). trim (). toLowerCase ()) {
121 case 'quick' :
122 case 'quick_mode' :
123 return 'quick' ;
124 case 'standard' :
125 case 'normal' :
126 return 'standard' ;
127 default :
128 return value;
129 }
130 }
131
132 function normalizeFaceliftMode ( value ) {
133 if (value === true ) return 'requested' ;
134 if (value === false || value == null ) return 'off' ;
135 return [ 'requested' , 'facelift' , 'on' , 'true' ]. includes ( String (value). trim (). toLowerCase ()) ? 'requested' : 'off' ;
136 }
137
138 function getDecisionValue ( decisions , canonicalKey ) {
139 const keys = DECISION_ALIASES [canonicalKey] || [canonicalKey];
140 const value = readDecisionValue (decisions, keys);
141 if (canonicalKey === 'sourceMode' ) {
142 return normalizeSourceMode (value);
143 }
144 if (canonicalKey === 'targetSiteStrategy' ) {
145 return normalizeTargetSiteStrategy (value);
146 }
147 if (canonicalKey === 'automationMode' ) {
148 return normalizeAutomationMode (value);
149 }
150 if (canonicalKey === 'deliveryMode' ) {
151 return normalizeDeliveryMode (value);
152 }
153 if (canonicalKey === 'managementImportMode' ) {
154 return normalizeManagementImportMode (value);
155 }
156 if (canonicalKey === 'faceliftMode' ) return normalizeFaceliftMode (value);
157 return value;
158 }
159
160 // `management_only` is the durable answer to the Editor scope question. It also
161 // narrows a stale combined-delivery decision so every downstream reader agrees that
162 // this run owes backend data only.
163 function getEffectiveDeliveryMode ( decisions ) {
164 const deliveryMode = getDecisionValue (decisions, 'deliveryMode' );
165 return getDecisionValue (decisions, 'editorWebsiteDecision' ) === 'management_only'
166 ? 'management'
167 : deliveryMode;
168 }
169
170 function isWebsiteDeliveryMode ( value ) {
171 return [ 'website' , 'management_and_website' ]. includes ( normalizeDeliveryMode (value));
172 }
173
174 function requiresWebsiteContinuation ( decisions ) {
175 return isWebsiteDeliveryMode ( getEffectiveDeliveryMode (decisions));
176 }
177
178 // The destination site type is an explicit operator choice for a new site.
179 // "editor" is deliberately not a value: it is an incomplete answer until Studio or Harmony
180 // is known, and the classic Wix Editor is not a supported choice.
181 const SITE_TYPES = Object. freeze ([ 'headless' , 'studio' , 'harmony' ]);
182 const EDITOR_SITE_TYPES = Object. freeze ([ 'studio' , 'harmony' ]);
183 const SITE_BUSINESS_TYPES = Object. freeze ([ 'store' , 'bookings' , 'other' , 'unknown' ]);
184 const SITE_BUSINESS_TYPE_SOURCES = Object. freeze ([ 'user' , 'context' , 'not_asked' ]);
185
186 // The one site-type request's choice ids, each mapped to the decision pair it records.
187 const SITE_TYPE_CHOICES = Object. freeze ({
188 headless: { siteType: 'headless' , businessType: null },
189 studio: { siteType: 'studio' , businessType: null },
190 harmony_store: { siteType: 'harmony' , businessType: 'store' },
191 harmony_bookings: { siteType: 'harmony' , businessType: 'bookings' },
192 harmony_other: { siteType: 'harmony' , businessType: 'other' },
193 harmony: { siteType: 'harmony' , businessType: 'unknown' },
194 });
195
196 function isNewSiteStrategy ( value ) {
197 return normalizeTargetSiteStrategy (value) === 'new_site' ;
198 }
199
200 function isEditorSiteType ( value ) {
201 return EDITOR_SITE_TYPES . includes (value);
202 }
203
204 // Returns the persisted pair, or null when no type is recorded. `errors` names a recorded
205 // value the router must not act on (unknown type, Harmony without its business type, or a
206 // business type recorded for a non-Harmony site).
207 function readSiteTypeDecision ( decisions ) {
208 const typeEntry = getDecisionEntry (decisions, 'targetSiteType' );
209 const businessEntry = getDecisionEntry (decisions, 'targetSiteBusinessType' );
210 if ( ! typeEntry) {
211 return businessEntry
212 ? { siteType: null , businessType: null , errors: [ 'targetSiteBusinessType is recorded without targetSiteType' ] }
213 : null ;
214 }
215 const errors = [];
216 const siteType = typeEntry.value;
217 if ( ! SITE_TYPES . includes (siteType)) errors. push ( `targetSiteType must be one of ${ SITE_TYPES . join ( ', ' ) } (got ${ JSON . stringify ( siteType ) })` );
218 let businessType = null ;
219 let businessTypeSource = null ;
220 if (businessEntry) {
221 businessType = businessEntry.value;
222 businessTypeSource = businessEntry.source;
223 if (siteType !== 'harmony' ) errors. push ( 'targetSiteBusinessType is valid only with targetSiteType=harmony' );
224 if ( ! SITE_BUSINESS_TYPES . includes (businessType)) errors. push ( `targetSiteBusinessType must be one of ${ SITE_BUSINESS_TYPES . join ( ', ' ) } (got ${ JSON . stringify ( businessType ) })` );
225 if ( ! SITE_BUSINESS_TYPE_SOURCES . includes (businessTypeSource)) errors. push ( `targetSiteBusinessType source must be one of ${ SITE_BUSINESS_TYPE_SOURCES . join ( ', ' ) }` );
226 } else if (siteType === 'harmony' ) {
227 errors. push ( 'targetSiteType=harmony requires targetSiteBusinessType in the same decision write' );
228 }
229 return {
230 siteType,
231 businessType,
232 businessTypeSource,
233 businessTypeEvidenceRef: businessEntry && businessEntry.evidenceRef ? businessEntry.evidenceRef : null ,
234 errors,
235 };
236 }
237
238 function isExplicitUserOneClick ( decisions ) {
239 const entry = getDecisionEntry (decisions, 'automationMode' );
240 return Boolean (entry && entry.source === 'user' && normalizeAutomationMode (entry.value) === 'one_click' );
241 }
242
243 // When this run first became a user-chosen one-click run, or null. Survives later mode changes.
244 function oneClickRunStart ( decisions ) {
245 const entry = getDecisionEntry (decisions || {}, 'automationMode' );
246 if ( ! entry) return null ;
247 if ( typeof entry.oneClickRunSince === 'string' && entry.oneClickRunSince) return entry.oneClickRunSince;
248 return entry.source === 'user' && normalizeAutomationMode (entry.value) === 'one_click' ? entry.decidedAt || 'unknown' : null ;
249 }
250
251 module . exports = {
252 oneClickRunStart,
253 EDITOR_SITE_TYPES,
254 SITE_BUSINESS_TYPES,
255 SITE_BUSINESS_TYPE_SOURCES,
256 SITE_TYPE_CHOICES,
257 SITE_TYPES,
258 isEditorSiteType,
259 isNewSiteStrategy,
260 readSiteTypeDecision,
261 CANONICAL_SOURCE_MODES,
262 SOURCE_MODE_ALIASES,
263 SOURCE_MODE_DECISION_KEYS,
264 invalidSourceModeMessage,
265 isKnownSourceMode,
266 getDecisionEntry,
267 getDecisionValue,
268 getEffectiveDeliveryMode,
269 isExplicitUserOneClick,
270 isWebsiteDeliveryMode,
271 requiresWebsiteContinuation,
272 normalizeAutomationMode,
273 normalizeDeliveryMode,
274 normalizeManagementImportMode,
275 normalizeFaceliftMode,
276 normalizeSourceMode,
277 normalizeTargetSiteStrategy,
278 };