Setting the file. One moment.
Resolve Home Page · Wix Headless Replatform · wix/skills · Skills Docs
ContentsBack to the top of the page 28.10
Workflow
scripts/resolve-home-page.mjs
scripts/ resolve-home-page.mjs
JavaScript · 96 lines · 4 KB
8
export
async
function
resolveHomePage
(
requestedUrl
, {
fetchImpl
=
fetch }
=
{}) {
9 const requested = normalizeUrl (requestedUrl);
10 requested.search = "" ;
11 const candidate = homeCandidate (requested);
12 let response;
13 try {
14 response = await fetchImpl (candidate, {
15 redirect: "follow" ,
16 signal: AbortSignal. timeout ( 15_000 ),
17 headers: { accept: "text/html,application/xhtml+xml" , "user-agent" : "wix-headless-replatform/0083" },
18 });
19 } catch (error) {
20 const gap = createGap ({
21 id: "gap:page-resolution:navigation" ,
22 ownerUnitId: "page-resolution:home" ,
23 scope: "global" ,
24 missingFields: [ "source.resolvedUrl" ],
25 reason: `Home-page candidate could not be resolved: ${ error . message }` ,
26 evidenceRefs: [],
27 unblockAction: "Provide a reachable public home-page URL or restore source availability." ,
28 });
29 return { artifact: null , gaps: [gap] };
30 }
31 if ( ! response.ok) {
32 const gap = createGap ({
33 id: "gap:page-resolution:http" ,
34 ownerUnitId: "page-resolution:home" ,
35 scope: "global" ,
36 missingFields: [ "source.resolvedUrl" ],
37 reason: `Home-page candidate returned HTTP ${ response . status }.` ,
38 evidenceRefs: [],
39 unblockAction: "Provide a public home-page URL that returns a successful HTML response." ,
40 });
41 return { artifact: null , gaps: [gap] };
42 }
43 const resolved = normalizeUrl (response.url || candidate);
44 resolved.hash = "" ;
45 const html = await response. text ();
46 const canonical = extractCanonical (html, resolved) || resolved. toString ();
47 const artifact = freezeSpec ({
48 schemaVersion: EXTRACTION_SCHEMA_VERSION ,
49 kind: "page-resolution" ,
50 id: "page-resolution:home" ,
51 pageKey: "home" ,
52 destinationRoute: "/" ,
53 status: "accepted" ,
54 source: {
55 requestedUrl: requested. toString (),
56 candidateUrl: candidate,
57 resolvedUrl: resolved. toString (),
58 canonicalUrl: canonical,
59 redirectsFollowed: requested. toString () !== resolved. toString (),
60 },
61 evidence: [{ kind: "read-only-navigation" , responseStatus: response.status }],
62 gapRefs: [],
63 });
64 return { artifact, gaps: [] };
65 }
66
67 function homeCandidate ( requested ) {
68 const parts = requested.pathname. split ( "/" ). filter (Boolean);
69 const localePrefix = parts[ 0 ] && LOCALE_SEGMENT . test (parts[ 0 ]) ? `/${ parts [ 0 ] }/` : "/" ;
70 return new URL (localePrefix, requested.origin). toString ();
71 }
72
73 function extractCanonical ( html , baseUrl ) {
74 const match = String (html). match ( /<link \b [ ^ >] * rel= ["'][ ^ "'] * canonical [ ^ "'] * ["'][ ^ >] * href= ["'] ( [ ^ "'] + ) ["'][ ^ >] * > | <link \b [ ^ >] * href= ["'] ( [ ^ "'] + ) ["'][ ^ >] * rel= ["'][ ^ "'] * canonical [ ^ "'] * ["'][ ^ >] * >/ i );
75 const href = match?.[ 1 ] || match?.[ 2 ];
76 if ( ! href) return null ;
77 try { return new URL (href, baseUrl). toString (); } catch { return null ; }
78 }
79
80 async function main () {
81 const args = parseArgs ();
82 const sourceUrl = args._[ 0 ] || args.url;
83 if ( ! sourceUrl) throw new Error ( "source URL is required" );
84 const outputDir = resolveOutputDir (sourceUrl, args.out);
85 const result = await resolveHomePage (sourceUrl);
86 const target = path. join ( docsDir (outputDir), "page-resolution.spec.json" );
87 await writeJson (target, result.artifact || { schemaVersion: EXTRACTION_SCHEMA_VERSION , kind: "page-resolution" , gaps: result.gaps });
88 if (result.gaps. some (( gap ) => gap.scope === "global" )) {
89 const error = new Error (result.gaps[ 0 ].reason);
90 error.code = "PAGE_RESOLUTION_BLOCKED" ;
91 throw error;
92 }
93 console. log ( JSON . stringify ({ path: target, resolvedUrl: result.artifact.source.resolvedUrl, hash: result.artifact.hash }, null , 2 ));
94 }
95
96 if ( import . meta .url === `file://${ process . argv [ 1 ] }` ) main (). catch (( error ) => { console. error (error.stack || error.message); process. exit ( 1 ); });