Setting the file. One moment.
Wix CLI · Wix Headless Templates · wix/skills · Skills Docs
ContentsBack to the top of the page shared/seed/ wix-cli.mjs
JavaScript · 79 lines · 4 KB
12 import { execFileSync, spawnSync } from "node:child_process" ;
13
14 // The CLI version the fallback installs; equal to `@wix/cli` in wix-headless-kit/install/pins.json.
15 const WIX_CLI_VERSION = "1.1.258" ;
16 const isWin = process.platform === "win32" ;
17
18 // The JS file a @wix/cli install runs (package.json `bin`), or null.
19 function cliEntry ( pkgDir ) {
20 try {
21 const { bin } = JSON . parse ( readFileSync ( join (pkgDir, "package.json" ), "utf8" ));
22 const rel = typeof bin === "string" ? bin : bin?.wix;
23 return rel && existsSync ( join (pkgDir, rel)) ? join (pkgDir, rel) : null ;
24 } catch {
25 return null ;
26 }
27 }
28
29 function viaNpx () {
30 const pkg = `@wix/cli@${ WIX_CLI_VERSION }` ;
31 if ( ! isWin) return { file: "npx" , prefix: [ "-y" , pkg] };
32 const js = join ( dirname (process.execPath), "node_modules" , "npm" , "bin" , "npx-cli.js" );
33 if ( existsSync (js)) return { file: process.execPath, prefix: [js, "-y" , pkg] };
34 return { file: "npx.cmd" , prefix: [ "-y" , pkg], shell: true };
35 }
36
37 export function resolveWixCli ( cwd = process. cwd ()) {
38 // The project's copy counts only once its install has finished: the seed runs beside a detached
39 // npm install, and mid-install the .bin shim can exist before the package it points at does
40 // (seen live: "Cannot find module node_modules/.bin/wix"). npm writes node_modules/.package-lock.json
41 // last, the same marker the kit's install step syncs on.
42 const pkgDir = join (cwd, "node_modules" , "@wix" , "cli" );
43 const installed = existsSync ( join (cwd, "node_modules" , ".package-lock.json" )) && existsSync ( join (pkgDir, "package.json" ));
44 if (installed) {
45 const local = join (cwd, "node_modules" , ".bin" , "wix" );
46 if ( ! isWin && existsSync (local)) return { file: local, prefix: [] };
47 const entry = isWin && cliEntry (pkgDir);
48 if (entry) return { file: process.execPath, prefix: [entry] };
49 }
50 for ( const dir of (process.env. PATH ?? "" ). split (delimiter)) {
51 if ( ! dir) continue ;
52 if ( ! isWin && existsSync ( join (dir, "wix" ))) return { file: join (dir, "wix" ), prefix: [] };
53 // A global npm install on Windows: wix.cmd in the prefix, the package beside it.
54 const entry = isWin && existsSync ( join (dir, "wix.cmd" )) && cliEntry ( join (dir, "node_modules" , "@wix" , "cli" ));
55 if (entry) return { file: process.execPath, prefix: [entry] };
56 }
57 return viaNpx ();
58 }
59
60 /**
61 * A site token for the API calls. Throws when the CLI is not logged in. The CLI may print a
62 * notice (an update box, a project warning) around the token, so the token is extracted from
63 * the output rather than taken whole.
64 */
65 export function wixToken ( siteId , cwd = process. cwd ()) {
66 const cli = resolveWixCli (cwd);
67 const out = execFileSync (cli.file, [ ... cli.prefix, "token" , "--site" , siteId], { encoding: "utf8" , cwd, shell: cli.shell, windowsHide: true });
68 // An older CLI starts its "update available" box on the token's own line, so a line split is
69 // not enough: the token is the first long run of token characters.
70 const token = out. match ( / [A-Za-z0-9._-] {40,} / )?.[ 0 ];
71 if ( ! token) throw new Error ( `The Wix CLI returned no token — run \` wix login \` (or \` npx @wix/cli@${ WIX_CLI_VERSION } login \` ) first.` );
72 return token;
73 }
74
75 /** Runs a Wix CLI command synchronously; same return shape as spawnSync. */
76 export function runWix ( args , { cwd = process. cwd (), ... opts } = {}) {
77 const cli = resolveWixCli (cwd);
78 return spawnSync (cli.file, [ ... cli.prefix, ... args], { cwd, shell: cli.shell, windowsHide: true , ... opts });
79 }