Setting the file. One moment.
Compose · Wix Headless Templates · wix/skills · Skills Docs
ContentsBack to the top of the page compose.mjs
compose.mjs
JavaScript · 83 lines · 6 KB
14 // substitutes the configured registry at install time. The root entry of the lock is brought in
15 // line with package.json (install/lock.mjs), and the result is checked: every dependency in
16 // package.json is in the lock's root entry with the same range, or the script exits 1.
17 import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs" ;
18 import { tmpdir } from "node:os" ;
19 import { basename, dirname, join, resolve } from "node:path" ;
20 import { spawnSync } from "node:child_process" ;
21 import { fileURLToPath } from "node:url" ;
22 import { listVerticals } from "../wix-headless-kit/install/templates.mjs" ;
23 import { syncLockRoot } from "../wix-headless-kit/install/lock.mjs" ;
24
25 const TEMPLATES = dirname ( fileURLToPath ( import . meta .url));
26 const DEPLOY = resolve ( TEMPLATES , ".." , "wix-headless-kit" , "install" , "deploy.mjs" );
27 const argv = process.argv. slice ( 2 );
28 const flag = ( n ) => { const i = argv. indexOf ( `--${ n }` ); return i !== - 1 && argv[i + 1 ] && ! argv[i + 1 ]. startsWith ( "--" ) ? argv[i + 1 ] : null ; };
29 const relock = argv. includes ( "--relock" );
30 const lockFrom = flag ( "lock-from" );
31 const skip = new Set ([ "--relock" , "--lock-from" , lockFrom]. filter (Boolean));
32 const requested = argv. filter (( a ) => ! skip. has (a));
33 const all = listVerticals ( TEMPLATES );
34 const verticals = requested. length ? requested : all;
35 for ( const v of verticals) if ( ! all. includes (v)) { console. error ( `unknown vertical "${ v }" — ${ all . join ( ", " ) }` ); process. exit ( 1 ); }
36 if (lockFrom && verticals. length !== 1 ) { console. error ( "--lock-from takes exactly one vertical" ); process. exit ( 1 ); }
37
38 const canonical = ( lock ) => {
39 for ( const [ key , p ] of Object. entries (lock.packages ?? {})) {
40 if ( ! key || ! p.resolved || ! / ^ https ? : \/\/ / . test (p.resolved)) continue ;
41 const name = key. slice (key. lastIndexOf ( "node_modules/" ) + "node_modules/" . length );
42 p.resolved = `https://registry.npmjs.org/${ name }/-/${ basename ( new URL ( p . resolved ). pathname ) }` ;
43 }
44 return lock;
45 };
46
47 let failed = false ;
48 for ( const v of verticals) {
49 const project = join ( TEMPLATES , v, "project" );
50 const lockPath = join (project, "package-lock.json" );
51 const kept = ! relock && ! lockFrom && existsSync (lockPath) ? readFileSync (lockPath, "utf8" ) : null ;
52 rmSync (project, { recursive: true , force: true });
53 cpSync ( join ( TEMPLATES , "blank" , "project" ), project, { recursive: true });
54 const d = spawnSync ( "node" , [ DEPLOY , v, "--stack" , "astro" ], { cwd: project, encoding: "utf8" });
55 let deployed = {};
56 try { deployed = JSON . parse (d.stdout); } catch { /* below */ }
57 if (d.status !== 0 || deployed.error) { console. log ( JSON . stringify ({ vertical: v, error: deployed.error ?? (d.stderr || d.stdout). slice ( - 400 ) })); failed = true ; continue ; }
58 let lock = "kept" ;
59 if (kept) writeFileSync (lockPath, kept);
60 else if (lockFrom) { cpSync ( resolve (lockFrom), lockPath); lock = `from ${ lockFrom }` ; }
61 else {
62 const tmp = mkdtempSync ( join ( tmpdir (), "compose-" ));
63 cpSync ( join (project, "package.json" ), join (tmp, "package.json" ));
64 const r = spawnSync ( "npm" , [ "install" , "--package-lock-only" , "--ignore-scripts" , "--no-audit" , "--no-fund" ], { cwd: tmp, encoding: "utf8" , timeout: 600_000 });
65 if (r.status !== 0 ) { console. log ( JSON . stringify ({ vertical: v, error: `lock resolution failed: ${ ( r . stderr || r . stdout ). slice ( - 400 ) }` })); failed = true ; rmSync (tmp, { recursive: true , force: true }); continue ; }
66 writeFileSync (lockPath, JSON . stringify ( canonical ( JSON . parse ( readFileSync ( join (tmp, "package-lock.json" ), "utf8" ))), null , 2 ) + " \n " );
67 rmSync (tmp, { recursive: true , force: true });
68 lock = "resolved" ;
69 }
70 const sync = syncLockRoot (project);
71 // the project is a template: nothing site-specific, nothing generated
72 for ( const f of [ "wix.config.json" , ".env.local" , ".env" , "AGENTS.md" , "CLAUDE.md" , ".gemini" , "node_modules" , ".wix" , ".astro" , "dist" ]) rmSync ( join (project, f), { recursive: true , force: true });
73 const lockRoot = JSON . parse ( readFileSync (lockPath, "utf8" )).packages?.[ "" ] ?? {};
74 const pkg = JSON . parse ( readFileSync ( join (project, "package.json" ), "utf8" ));
75 const diff = [];
76 for ( const field of [ "dependencies" , "devDependencies" ]) {
77 for ( const [ n , r ] of Object. entries (pkg[field] ?? {})) if (lockRoot[field]?.[n] !== r) diff. push ( `${ n }: package.json ${ r }, lock ${ lockRoot [ field ]?.[ n ] ?? "absent"}` );
78 for ( const n of Object. keys (lockRoot[field] ?? {})) if ( ! (n in (pkg[field] ?? {}))) diff. push ( `${ n }: only in the lock` );
79 }
80 if (diff. length ) failed = true ;
81 console. log ( JSON . stringify ({ vertical: v, lock, promoted: sync?.promoted ?? [], packages: Object. keys ( JSON . parse ( readFileSync (lockPath, "utf8" )).packages ?? {}). length , depsAdded: deployed.depsAdded, astroConfig: deployed.astroConfig, ... (diff. length ? { error: `lock root out of line: ${ diff . join ( "; " ) }` } : {}) }));
82 }
83 process. exit (failed ? 1 : 0 );