@woodsportal/hubspot-kit 1.0.42-dev.0 → 1.0.42-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -1
- package/dist/{chunk-WHYTQEZX.js → chunk-4UFWXPQG.js} +2 -2
- package/dist/{chunk-4GOJPOW3.js → chunk-GXYUGXF5.js} +82 -23
- package/dist/chunk-GXYUGXF5.js.map +1 -0
- package/dist/cli.js +61 -26
- package/dist/cli.js.map +1 -1
- package/dist/{exec-VY6BGWF3.js → exec-NS4GKXZS.js} +2 -2
- package/dist/{scaffold-page-lifecycle-EHMPWPPE.js → scaffold-page-lifecycle-53AWWGFR.js} +3 -3
- package/examples/greenfield/module-hybrid-cdn/README.md +2 -1
- package/examples/greenfield/module-hybrid-cdn-auth-full/README.md +2 -1
- package/examples/greenfield/module-hybrid-cdn-auth-full/src/features/auth/components/starter-login.tsx +2 -6
- package/examples/greenfield/module-hybrid-cdn-auth-full/src/features/auth/sso-callback.ts +6 -0
- package/examples/greenfield/module-hybrid-cdn-auth-sso/README.md +2 -1
- package/examples/greenfield/module-hybrid-cdn-auth-sso/src/features/auth/sso-callback.ts +6 -0
- package/examples/greenfield/module-hybrid-cdn-auth-starter/README.md +2 -1
- package/examples/greenfield/module-hybrid-cdn-auth-starter-sidebar/README.md +2 -1
- package/package.json +3 -2
- package/scripts/build-cdn.mjs +6 -5
- package/scripts/dist-cli-pack-smoke.test.mjs +79 -0
- package/scripts/ensure-wphs-workspace.mjs +7 -2
- package/scripts/resolve-hubspot-cli.mjs +51 -0
- package/scripts/resolve-vite-config.mjs +2 -3
- package/scripts/resolve-vite-spawn.mjs +48 -0
- package/scripts/run-vite-build.mjs +5 -6
- package/scripts/watch-hubspot.mjs +11 -13
- package/templates/module-hybrid-cdn/README.md +2 -1
- package/templates/module-monolith/README.md +2 -1
- package/templates/scaffold/auth/_full/src/features/auth/components/starter-login.tsx +79 -0
- package/templates/scaffold/auth/_shared/src/app.tsx +8 -3
- package/templates/scaffold/auth/_shared/src/features/auth/components/starter-login.tsx +10 -3
- package/templates/scaffold/auth/_shared/src/integrations/woodsportal-sdk.ts +1 -0
- package/templates/scaffold/auth/_sso/src/features/auth/components/starter-login.tsx +10 -3
- package/templates/scaffold/auth/_sso/src/features/auth/sso-callback.ts +6 -0
- package/dist/chunk-4GOJPOW3.js.map +0 -1
- package/dist/ensure-wphs-workspace-5S3GTO6K.js +0 -234
- package/dist/ensure-wphs-workspace-5S3GTO6K.js.map +0 -1
- /package/dist/{chunk-WHYTQEZX.js.map → chunk-4UFWXPQG.js.map} +0 -0
- /package/dist/{exec-VY6BGWF3.js.map → exec-NS4GKXZS.js.map} +0 -0
- /package/dist/{scaffold-page-lifecycle-EHMPWPPE.js.map → scaffold-page-lifecycle-53AWWGFR.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
5
|
### Portal auth scaffold
|
|
6
|
-
- **`wp init --auth`** —
|
|
6
|
+
- **`wp init --auth full`** — fix `starter-login` importing `MFA_REQUIRED_SCAFFOLD_MESSAGE` after full-tier `login-session-bridge` merge; add full-tier `starter-login` layer
|
|
7
|
+
- **SSO callback** — export `clearLegacySsoCallbackInFlight` in auth scaffold (`mount-portal` boot)
|
|
8
|
+
- **`wp init` hint** — Getting started uses `npm install` (not `yarn install`); template READMEs aligned
|
|
7
9
|
- **Interactive `wp init` wizard** — sequential prompts: type → name → router → auth → CDN → confirm
|
|
8
10
|
- **`templates/scaffold/auth/`** — layered `_shared`, `_sso`, `_full` files merged at init; `woodscli.json` records `scaffold.auth`
|
|
9
11
|
- **Greenfield examples** — `examples/greenfield/module-hybrid-cdn-auth-{starter,sso,full}`
|
|
@@ -30,9 +32,13 @@
|
|
|
30
32
|
- **`wp doctor`** — CSS pipeline checks (prefix, `.temp` @source, `skipRuntimeCss`, `module.css` dw utilities, CDN `require_css` warning)
|
|
31
33
|
|
|
32
34
|
### Windows / fresh init
|
|
35
|
+
- **`wp init` crash** — load unbundled `scripts/ensure-wphs-workspace.mjs` at runtime (fixes tsup double-shebang `Invalid or unexpected token` in published `wp`)
|
|
33
36
|
- **`wp doctor`** — scaffold `.wphs/` in-process (no swallowed subprocess); surface `wphs-scaffold` errors; re-run ensure before layout checks
|
|
34
37
|
- **CLI exit** — deferred `process.exit` after @clack spinners (fixes libuv `UV_HANDLE_CLOSING` crash on Windows)
|
|
35
38
|
- **`wp doctor` severity** — HubSpot CLI missing and placeholder `portal.cdn.json` github slug are warnings (local `wp dev` still works); hard errors remain for real CDN misconfigurations
|
|
39
|
+
- **HubSpot CLI spawn** — resolve `hs.cmd` / shell fallback on Windows (`wp auth`, `upload`, `watch`, `portal use`, doctor checks)
|
|
40
|
+
- **CDN build** — `build-cdn.mjs` / `run-vite-build.mjs` use cross-platform Vite spawn (no hardcoded `yarn`)
|
|
41
|
+
- **CI** — `windows-latest` verify job + packed `dist/cli.js` doctor smoke
|
|
36
42
|
- **Docs** — Windows notes in [TROUBLESHOOTING.md](./docs/TROUBLESHOOTING.md)
|
|
37
43
|
|
|
38
44
|
## 1.0.39 — 2026-06-08
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ExitCode,
|
|
4
4
|
WpHsError,
|
|
5
5
|
runCommand
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GXYUGXF5.js";
|
|
7
7
|
|
|
8
8
|
// src/schema/woodsportal-hs.ts
|
|
9
9
|
import { z } from "zod";
|
|
@@ -551,4 +551,4 @@ export {
|
|
|
551
551
|
normalizePagePath,
|
|
552
552
|
scaffoldPage
|
|
553
553
|
};
|
|
554
|
-
//# sourceMappingURL=chunk-
|
|
554
|
+
//# sourceMappingURL=chunk-4UFWXPQG.js.map
|
|
@@ -83,6 +83,52 @@ function isWpHsError(error) {
|
|
|
83
83
|
return error instanceof WpHsError;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
// src/lib/resolve-external-cli.ts
|
|
87
|
+
import { existsSync } from "fs";
|
|
88
|
+
import { platform } from "os";
|
|
89
|
+
import { resolve } from "path";
|
|
90
|
+
function resolveBin(name, projectRoot) {
|
|
91
|
+
const roots = projectRoot ? [projectRoot] : [];
|
|
92
|
+
if (!roots.includes(process.cwd())) {
|
|
93
|
+
roots.push(process.cwd());
|
|
94
|
+
}
|
|
95
|
+
for (const root of roots) {
|
|
96
|
+
const binDir = resolve(root, "node_modules", ".bin");
|
|
97
|
+
if (platform() === "win32") {
|
|
98
|
+
const cmd = resolve(binDir, `${name}.cmd`);
|
|
99
|
+
if (existsSync(cmd)) {
|
|
100
|
+
return { command: cmd, prefixArgs: [] };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const shim = resolve(binDir, name);
|
|
104
|
+
if (existsSync(shim)) {
|
|
105
|
+
return { command: shim, prefixArgs: [] };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
function resolveHubSpotCliSpawn(projectRoot) {
|
|
111
|
+
const local = resolveBin("hs", projectRoot);
|
|
112
|
+
if (local) {
|
|
113
|
+
return local;
|
|
114
|
+
}
|
|
115
|
+
if (platform() === "win32") {
|
|
116
|
+
return { command: "hs", prefixArgs: [], shell: true };
|
|
117
|
+
}
|
|
118
|
+
return { command: "hs", prefixArgs: [] };
|
|
119
|
+
}
|
|
120
|
+
function applyExternalCliSpawn(command, args, options) {
|
|
121
|
+
if (command === "hs") {
|
|
122
|
+
const spawn2 = resolveHubSpotCliSpawn(options.projectRoot ?? options.cwd);
|
|
123
|
+
return {
|
|
124
|
+
command: spawn2.command,
|
|
125
|
+
args: [...spawn2.prefixArgs, ...args],
|
|
126
|
+
shell: spawn2.shell
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return { command, args };
|
|
130
|
+
}
|
|
131
|
+
|
|
86
132
|
// src/lib/exec.ts
|
|
87
133
|
var SECRET_PATTERN = /(token|secret|password|pat|key)=/i;
|
|
88
134
|
function logExec(logger, command, args, options) {
|
|
@@ -98,29 +144,35 @@ function runCommand(command, args, options) {
|
|
|
98
144
|
logger?.info(`[dry-run] ${formatExecDebugLine(command, args, cwd, env, options.projectRoot)}`);
|
|
99
145
|
return { status: 0, stdout: "", stderr: "" };
|
|
100
146
|
}
|
|
101
|
-
|
|
147
|
+
const resolved = applyExternalCliSpawn(command, args, {
|
|
148
|
+
projectRoot: options.projectRoot,
|
|
149
|
+
cwd
|
|
150
|
+
});
|
|
151
|
+
logExec(logger, resolved.command, resolved.args, options);
|
|
102
152
|
if (streamOutput) {
|
|
103
|
-
const result2 = spawnSync(command, args, {
|
|
153
|
+
const result2 = spawnSync(resolved.command, resolved.args, {
|
|
104
154
|
cwd,
|
|
105
155
|
env,
|
|
106
156
|
encoding: "utf8",
|
|
107
|
-
stdio: "inherit"
|
|
157
|
+
stdio: "inherit",
|
|
158
|
+
shell: resolved.shell
|
|
108
159
|
});
|
|
109
160
|
const status2 = result2.status ?? 1;
|
|
110
|
-
throwOnBadExit(command, args, status2, "", "", okCodes);
|
|
161
|
+
throwOnBadExit(resolved.command, resolved.args, status2, "", "", okCodes);
|
|
111
162
|
return { status: status2, stdout: "", stderr: "" };
|
|
112
163
|
}
|
|
113
164
|
const spawnOpts = {
|
|
114
165
|
cwd,
|
|
115
166
|
env,
|
|
116
167
|
encoding: "utf8",
|
|
117
|
-
stdio: ["inherit", "pipe", "pipe"]
|
|
168
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
169
|
+
shell: resolved.shell
|
|
118
170
|
};
|
|
119
|
-
const result = spawnSync(command, args, spawnOpts);
|
|
171
|
+
const result = spawnSync(resolved.command, resolved.args, spawnOpts);
|
|
120
172
|
const status = result.status ?? 1;
|
|
121
173
|
const stdout = typeof result.stdout === "string" ? result.stdout : "";
|
|
122
174
|
const stderr = typeof result.stderr === "string" ? result.stderr : "";
|
|
123
|
-
throwOnBadExit(command, args, status, stdout, stderr, okCodes);
|
|
175
|
+
throwOnBadExit(resolved.command, resolved.args, status, stdout, stderr, okCodes);
|
|
124
176
|
return { status, stdout, stderr };
|
|
125
177
|
}
|
|
126
178
|
function runNodeScript(scriptPath, args, options) {
|
|
@@ -148,13 +200,18 @@ function runCommandAsync(command, args, options) {
|
|
|
148
200
|
logger?.info(`[dry-run] ${formatExecDebugLine(command, args, cwd, env, options.projectRoot)}`);
|
|
149
201
|
return Promise.resolve({ status: 0, stdout: "", stderr: "" });
|
|
150
202
|
}
|
|
151
|
-
|
|
203
|
+
const resolved = applyExternalCliSpawn(command, args, {
|
|
204
|
+
projectRoot: options.projectRoot,
|
|
205
|
+
cwd
|
|
206
|
+
});
|
|
207
|
+
logExec(logger, resolved.command, resolved.args, options);
|
|
152
208
|
if (streamOutput) {
|
|
153
|
-
return new Promise((
|
|
154
|
-
const child = spawn(command, args, {
|
|
209
|
+
return new Promise((resolve2, reject) => {
|
|
210
|
+
const child = spawn(resolved.command, resolved.args, {
|
|
155
211
|
cwd,
|
|
156
212
|
env,
|
|
157
|
-
stdio: "inherit"
|
|
213
|
+
stdio: "inherit",
|
|
214
|
+
shell: resolved.shell
|
|
158
215
|
});
|
|
159
216
|
child.on("error", (error) => {
|
|
160
217
|
reject(error);
|
|
@@ -162,19 +219,20 @@ function runCommandAsync(command, args, options) {
|
|
|
162
219
|
child.on("close", (code) => {
|
|
163
220
|
const status = code ?? 1;
|
|
164
221
|
try {
|
|
165
|
-
throwOnBadExit(command, args, status, "", "", okCodes);
|
|
166
|
-
|
|
222
|
+
throwOnBadExit(resolved.command, resolved.args, status, "", "", okCodes);
|
|
223
|
+
resolve2({ status, stdout: "", stderr: "" });
|
|
167
224
|
} catch (error) {
|
|
168
225
|
reject(error);
|
|
169
226
|
}
|
|
170
227
|
});
|
|
171
228
|
});
|
|
172
229
|
}
|
|
173
|
-
return new Promise((
|
|
174
|
-
const child = spawn(command, args, {
|
|
230
|
+
return new Promise((resolve2, reject) => {
|
|
231
|
+
const child = spawn(resolved.command, resolved.args, {
|
|
175
232
|
cwd,
|
|
176
233
|
env,
|
|
177
|
-
stdio: ["inherit", "pipe", "pipe"]
|
|
234
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
235
|
+
shell: resolved.shell
|
|
178
236
|
});
|
|
179
237
|
let stdout = "";
|
|
180
238
|
let stderr = "";
|
|
@@ -192,8 +250,8 @@ function runCommandAsync(command, args, options) {
|
|
|
192
250
|
child.on("close", (code) => {
|
|
193
251
|
const status = code ?? 1;
|
|
194
252
|
try {
|
|
195
|
-
throwOnBadExit(command, args, status, stdout, stderr, okCodes);
|
|
196
|
-
|
|
253
|
+
throwOnBadExit(resolved.command, resolved.args, status, stdout, stderr, okCodes);
|
|
254
|
+
resolve2({ status, stdout, stderr });
|
|
197
255
|
} catch (error) {
|
|
198
256
|
reject(error);
|
|
199
257
|
}
|
|
@@ -211,7 +269,7 @@ function runNodeScriptLongRunning(scriptPath, args, options) {
|
|
|
211
269
|
);
|
|
212
270
|
return Promise.resolve(0);
|
|
213
271
|
}
|
|
214
|
-
return new Promise((
|
|
272
|
+
return new Promise((resolve2, reject) => {
|
|
215
273
|
const child = spawn(process.execPath, [scriptPath, ...args], {
|
|
216
274
|
cwd,
|
|
217
275
|
env,
|
|
@@ -233,14 +291,14 @@ function runNodeScriptLongRunning(scriptPath, args, options) {
|
|
|
233
291
|
process.off("SIGINT", forwardSignal);
|
|
234
292
|
process.off("SIGTERM", forwardSignal);
|
|
235
293
|
if (signal === "SIGINT") {
|
|
236
|
-
|
|
294
|
+
resolve2(130);
|
|
237
295
|
return;
|
|
238
296
|
}
|
|
239
297
|
if (signal === "SIGTERM") {
|
|
240
|
-
|
|
298
|
+
resolve2(143);
|
|
241
299
|
return;
|
|
242
300
|
}
|
|
243
|
-
|
|
301
|
+
resolve2(code ?? 1);
|
|
244
302
|
});
|
|
245
303
|
});
|
|
246
304
|
}
|
|
@@ -249,10 +307,11 @@ export {
|
|
|
249
307
|
ExitCode,
|
|
250
308
|
WpHsError,
|
|
251
309
|
isWpHsError,
|
|
310
|
+
resolveHubSpotCliSpawn,
|
|
252
311
|
runCommand,
|
|
253
312
|
runNodeScript,
|
|
254
313
|
runCommandAsync,
|
|
255
314
|
runNodeScriptAsync,
|
|
256
315
|
runNodeScriptLongRunning
|
|
257
316
|
};
|
|
258
|
-
//# sourceMappingURL=chunk-
|
|
317
|
+
//# sourceMappingURL=chunk-GXYUGXF5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/exec.ts","../src/lib/exec-debug.ts","../src/lib/errors.ts","../src/lib/resolve-external-cli.ts"],"sourcesContent":["import { spawn, spawnSync, type SpawnSyncOptions } from 'node:child_process'\n\nimport { formatExecDebugLine } from './exec-debug.js'\nimport { WpHsError, ExitCode } from './errors.js'\nimport { applyExternalCliSpawn } from './resolve-external-cli.js'\nimport type { Logger } from './logger.js'\n\nconst SECRET_PATTERN = /(token|secret|password|pat|key)=/i\n\nexport type RunOptions = {\n cwd: string\n env?: NodeJS.ProcessEnv\n logger?: Logger\n dryRun?: boolean\n timeoutMs?: number\n /** Expected exit code on success (default 0) */\n okCodes?: number[]\n /** Stream child stdout/stderr to the terminal (verbose mode). */\n streamOutput?: boolean\n /** Shorten cwd paths in debug logs. */\n projectRoot?: string\n}\n\nfunction logExec(logger: Logger | undefined, command: string, args: string[], options: RunOptions): void {\n if (!logger) return\n const env = options.env ?? process.env\n logger.debug(\n formatExecDebugLine(command, args, options.cwd, env, options.projectRoot),\n )\n}\n\nexport function runCommand(\n command: string,\n args: string[],\n options: RunOptions,\n): { status: number; stdout: string; stderr: string } {\n const { cwd, env = process.env, logger, dryRun = false, okCodes = [0], streamOutput = false } =\n options\n\n if (dryRun) {\n logger?.info(`[dry-run] ${formatExecDebugLine(command, args, cwd, env, options.projectRoot)}`)\n return { status: 0, stdout: '', stderr: '' }\n }\n\n const resolved = applyExternalCliSpawn(command, args, {\n projectRoot: options.projectRoot,\n cwd,\n })\n\n logExec(logger, resolved.command, resolved.args, options)\n\n if (streamOutput) {\n const result = spawnSync(resolved.command, resolved.args, {\n cwd,\n env,\n encoding: 'utf8',\n stdio: 'inherit',\n shell: resolved.shell,\n })\n const status = result.status ?? 1\n throwOnBadExit(resolved.command, resolved.args, status, '', '', okCodes)\n return { status, stdout: '', stderr: '' }\n }\n\n const spawnOpts: SpawnSyncOptions = {\n cwd,\n env,\n encoding: 'utf8',\n stdio: ['inherit', 'pipe', 'pipe'],\n shell: resolved.shell,\n }\n\n const result = spawnSync(resolved.command, resolved.args, spawnOpts)\n const status = result.status ?? 1\n const stdout = typeof result.stdout === 'string' ? result.stdout : ''\n const stderr = typeof result.stderr === 'string' ? result.stderr : ''\n\n throwOnBadExit(resolved.command, resolved.args, status, stdout, stderr, okCodes)\n\n return { status, stdout, stderr }\n}\n\nexport function runNodeScript(\n scriptPath: string,\n args: string[],\n options: RunOptions,\n): void {\n runCommand(process.execPath, [scriptPath, ...args], options)\n}\n\nfunction throwOnBadExit(\n command: string,\n args: string[],\n status: number,\n stdout: string,\n stderr: string,\n okCodes: number[],\n): void {\n if (okCodes.includes(status)) {\n return\n }\n const detail = stderr.trim() || stdout.trim() || `exit ${status}`\n if (SECRET_PATTERN.test(detail)) {\n throw new WpHsError(`Command failed: ${command}`, {\n exitCode: ExitCode.USER_ERROR,\n remediation: 'Re-run with --verbose for details (secrets are never logged).',\n })\n }\n throw new WpHsError(`Command failed: ${command} ${args.join(' ')}\\n${detail}`, {\n exitCode: ExitCode.USER_ERROR,\n })\n}\n\n/**\n * Non-blocking spawn — keeps the Node event loop alive so @clack spinners animate.\n */\nexport function runCommandAsync(\n command: string,\n args: string[],\n options: RunOptions,\n): Promise<{ status: number; stdout: string; stderr: string }> {\n const { cwd, env = process.env, logger, dryRun = false, okCodes = [0], streamOutput = false } =\n options\n\n if (dryRun) {\n logger?.info(`[dry-run] ${formatExecDebugLine(command, args, cwd, env, options.projectRoot)}`)\n return Promise.resolve({ status: 0, stdout: '', stderr: '' })\n }\n\n const resolved = applyExternalCliSpawn(command, args, {\n projectRoot: options.projectRoot,\n cwd,\n })\n\n logExec(logger, resolved.command, resolved.args, options)\n\n if (streamOutput) {\n return new Promise((resolve, reject) => {\n const child = spawn(resolved.command, resolved.args, {\n cwd,\n env,\n stdio: 'inherit',\n shell: resolved.shell,\n })\n\n child.on('error', (error) => {\n reject(error)\n })\n\n child.on('close', (code) => {\n const status = code ?? 1\n try {\n throwOnBadExit(resolved.command, resolved.args, status, '', '', okCodes)\n resolve({ status, stdout: '', stderr: '' })\n } catch (error) {\n reject(error)\n }\n })\n })\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(resolved.command, resolved.args, {\n cwd,\n env,\n stdio: ['inherit', 'pipe', 'pipe'],\n shell: resolved.shell,\n })\n\n let stdout = ''\n let stderr = ''\n\n child.stdout?.setEncoding('utf8')\n child.stderr?.setEncoding('utf8')\n child.stdout?.on('data', (chunk: string) => {\n stdout += chunk\n })\n child.stderr?.on('data', (chunk: string) => {\n stderr += chunk\n })\n\n child.on('error', (error) => {\n reject(error)\n })\n\n child.on('close', (code) => {\n const status = code ?? 1\n try {\n throwOnBadExit(resolved.command, resolved.args, status, stdout, stderr, okCodes)\n resolve({ status, stdout, stderr })\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nexport function runNodeScriptAsync(\n scriptPath: string,\n args: string[],\n options: RunOptions,\n): Promise<void> {\n return runCommandAsync(process.execPath, [scriptPath, ...args], options).then(() => undefined)\n}\n\n/**\n * Spawn a Node script with inherited stdio and forward SIGINT/SIGTERM (wp watch, long-running tools).\n * Unlike spawnSync, the parent event loop stays alive so Ctrl+C works while the child runs.\n */\nexport function runNodeScriptLongRunning(\n scriptPath: string,\n args: string[],\n options: RunOptions,\n): Promise<number> {\n const { cwd, env = process.env, logger, dryRun = false } = options\n\n if (dryRun) {\n logger?.info(\n `[dry-run] ${formatExecDebugLine(process.execPath, [scriptPath, ...args], cwd, env, options.projectRoot)}`,\n )\n return Promise.resolve(0)\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, [scriptPath, ...args], {\n cwd,\n env,\n stdio: 'inherit',\n })\n\n const forwardSignal = (signal: NodeJS.Signals) => {\n if (!child.killed) {\n child.kill(signal)\n }\n }\n\n process.on('SIGINT', forwardSignal)\n process.on('SIGTERM', forwardSignal)\n\n child.on('error', (error) => {\n process.off('SIGINT', forwardSignal)\n process.off('SIGTERM', forwardSignal)\n reject(error)\n })\n\n child.on('exit', (code, signal) => {\n process.off('SIGINT', forwardSignal)\n process.off('SIGTERM', forwardSignal)\n\n if (signal === 'SIGINT') {\n resolve(130)\n return\n }\n if (signal === 'SIGTERM') {\n resolve(143)\n return\n }\n\n resolve(code ?? 1)\n })\n })\n}\n","import { basename, relative } from 'node:path'\n\nconst SECRET_ENV_KEY =\n /(_KEY|_TOKEN|_SECRET|_PASSWORD|_PAT|AUTH|CREDENTIAL|GITHUB|NPM_|ERASER|LINEAR|AWS_|SSH_)/i\n\nconst RELEVANT_ENV_PREFIX = /^WP_HS_|^WP_/\n\nexport function isSecretEnvKey(key: string): boolean {\n return SECRET_ENV_KEY.test(key)\n}\n\nexport function maskEnvForLog(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const masked: NodeJS.ProcessEnv = {}\n for (const [key, value] of Object.entries(env)) {\n if (value === undefined) continue\n masked[key] = isSecretEnvKey(key) ? '[redacted]' : value\n }\n return masked\n}\n\nexport function formatRelevantEnv(env: NodeJS.ProcessEnv): string | undefined {\n const pairs = Object.entries(env)\n .filter(([key, value]) => value !== undefined && RELEVANT_ENV_PREFIX.test(key))\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => {\n const shown = isSecretEnvKey(key) ? '[redacted]' : value\n return `${key}=${shown}`\n })\n\n return pairs.length > 0 ? pairs.join(' ') : undefined\n}\n\nfunction shortenScriptPath(scriptPath: string): string {\n const marker = '/scripts/'\n const idx = scriptPath.lastIndexOf(marker)\n if (idx >= 0) {\n return `scripts/${scriptPath.slice(idx + marker.length)}`\n }\n return basename(scriptPath)\n}\n\nexport function formatExecCommand(command: string, args: string[]): string {\n if (command === process.execPath && args.length > 0) {\n const rest = args.slice(1).join(' ')\n return `node ${shortenScriptPath(args[0])}${rest ? ` ${rest}` : ''}`\n }\n return [command, ...args].join(' ')\n}\n\nexport function formatExecCwd(cwd: string, projectRoot?: string): string {\n if (projectRoot) {\n try {\n const rel = relative(projectRoot, cwd)\n if (!rel.startsWith('..')) {\n return rel === '' ? '.' : rel\n }\n } catch {\n // fall through\n }\n }\n const parts = cwd.split('/')\n if (parts.length > 3) {\n return `…/${parts.slice(-2).join('/')}`\n }\n return cwd\n}\n\n/** One-line verbose exec label for developers (no full env dump). */\nexport function formatExecDebugLine(\n command: string,\n args: string[],\n cwd: string,\n env: NodeJS.ProcessEnv,\n projectRoot?: string,\n): string {\n const cmd = formatExecCommand(command, args)\n const cwdLabel = formatExecCwd(cwd, projectRoot)\n const envLabel = formatRelevantEnv(env)\n const parts = [cmd, `cwd=${cwdLabel}`]\n if (envLabel) {\n parts.push(envLabel)\n }\n return parts.join(' ')\n}\n","export const ExitCode = {\n SUCCESS: 0,\n USER_ERROR: 1,\n PREREQUISITE: 2,\n BUILD_FAILED: 3,\n PUBLISH_FAILED: 4,\n AUDIT_FAILED: 5,\n INTERNAL: 10,\n} as const\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode]\n\nexport class WpHsError extends Error {\n readonly exitCode: ExitCodeValue\n readonly remediation?: string\n\n constructor(\n message: string,\n options: { exitCode?: ExitCodeValue; remediation?: string; cause?: unknown } = {},\n ) {\n super(message, { cause: options.cause })\n this.name = 'WpHsError'\n this.exitCode = options.exitCode ?? ExitCode.USER_ERROR\n this.remediation = options.remediation\n }\n}\n\nexport function isWpHsError(error: unknown): error is WpHsError {\n return error instanceof WpHsError\n}\n","import { existsSync } from 'node:fs'\nimport { platform } from 'node:os'\nimport { resolve } from 'node:path'\n\nexport type ExternalCliSpawn = {\n command: string\n prefixArgs: string[]\n shell?: boolean\n}\n\nfunction resolveBin(name: string, projectRoot?: string): ExternalCliSpawn | null {\n const roots = projectRoot ? [projectRoot] : []\n if (!roots.includes(process.cwd())) {\n roots.push(process.cwd())\n }\n\n for (const root of roots) {\n const binDir = resolve(root, 'node_modules', '.bin')\n if (platform() === 'win32') {\n const cmd = resolve(binDir, `${name}.cmd`)\n if (existsSync(cmd)) {\n return { command: cmd, prefixArgs: [] }\n }\n }\n const shim = resolve(binDir, name)\n if (existsSync(shim)) {\n return { command: shim, prefixArgs: [] }\n }\n }\n\n return null\n}\n\n/** Resolve HubSpot CLI (`hs`) for cross-platform spawn (Windows `.cmd` shims). */\nexport function resolveHubSpotCliSpawn(projectRoot?: string): ExternalCliSpawn {\n const local = resolveBin('hs', projectRoot)\n if (local) {\n return local\n }\n\n if (platform() === 'win32') {\n return { command: 'hs', prefixArgs: [], shell: true }\n }\n\n return { command: 'hs', prefixArgs: [] }\n}\n\n/** Resolve consumer `wp` binary for watch rebuild subprocesses. */\nexport function resolveWpBinSpawn(projectRoot: string, kitCliPath?: string): ExternalCliSpawn {\n if (kitCliPath && existsSync(kitCliPath)) {\n return { command: process.execPath, prefixArgs: [kitCliPath] }\n }\n\n const local = resolveBin('wp', projectRoot)\n if (local) {\n return local\n }\n\n if (platform() === 'win32') {\n return { command: 'wp', prefixArgs: [], shell: true }\n }\n\n return { command: 'wp', prefixArgs: [] }\n}\n\nexport function applyExternalCliSpawn(\n command: string,\n args: string[],\n options: { projectRoot?: string; cwd?: string },\n): { command: string; args: string[]; shell?: boolean } {\n if (command === 'hs') {\n const spawn = resolveHubSpotCliSpawn(options.projectRoot ?? options.cwd)\n return {\n command: spawn.command,\n args: [...spawn.prefixArgs, ...args],\n shell: spawn.shell,\n }\n }\n\n return { command, args }\n}\n"],"mappings":";;;AAAA,SAAS,OAAO,iBAAwC;;;ACAxD,SAAS,UAAU,gBAAgB;AAEnC,IAAM,iBACJ;AAEF,IAAM,sBAAsB;AAErB,SAAS,eAAe,KAAsB;AACnD,SAAO,eAAe,KAAK,GAAG;AAChC;AAWO,SAAS,kBAAkB,KAA4C;AAC5E,QAAM,QAAQ,OAAO,QAAQ,GAAG,EAC7B,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,UAAU,UAAa,oBAAoB,KAAK,GAAG,CAAC,EAC7E,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AACrB,UAAM,QAAQ,eAAe,GAAG,IAAI,eAAe;AACnD,WAAO,GAAG,GAAG,IAAI,KAAK;AAAA,EACxB,CAAC;AAEH,SAAO,MAAM,SAAS,IAAI,MAAM,KAAK,GAAG,IAAI;AAC9C;AAEA,SAAS,kBAAkB,YAA4B;AACrD,QAAM,SAAS;AACf,QAAM,MAAM,WAAW,YAAY,MAAM;AACzC,MAAI,OAAO,GAAG;AACZ,WAAO,WAAW,WAAW,MAAM,MAAM,OAAO,MAAM,CAAC;AAAA,EACzD;AACA,SAAO,SAAS,UAAU;AAC5B;AAEO,SAAS,kBAAkB,SAAiB,MAAwB;AACzE,MAAI,YAAY,QAAQ,YAAY,KAAK,SAAS,GAAG;AACnD,UAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG;AACnC,WAAO,QAAQ,kBAAkB,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,IAAI,KAAK,EAAE;AAAA,EACpE;AACA,SAAO,CAAC,SAAS,GAAG,IAAI,EAAE,KAAK,GAAG;AACpC;AAEO,SAAS,cAAc,KAAa,aAA8B;AACvE,MAAI,aAAa;AACf,QAAI;AACF,YAAM,MAAM,SAAS,aAAa,GAAG;AACrC,UAAI,CAAC,IAAI,WAAW,IAAI,GAAG;AACzB,eAAO,QAAQ,KAAK,MAAM;AAAA,MAC5B;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO,UAAK,MAAM,MAAM,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA,EACvC;AACA,SAAO;AACT;AAGO,SAAS,oBACd,SACA,MACA,KACA,KACA,aACQ;AACR,QAAM,MAAM,kBAAkB,SAAS,IAAI;AAC3C,QAAM,WAAW,cAAc,KAAK,WAAW;AAC/C,QAAM,WAAW,kBAAkB,GAAG;AACtC,QAAM,QAAQ,CAAC,KAAK,OAAO,QAAQ,EAAE;AACrC,MAAI,UAAU;AACZ,UAAM,KAAK,QAAQ;AAAA,EACrB;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACnFO,IAAM,WAAW;AAAA,EACtB,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,UAAU;AACZ;AAIO,IAAM,YAAN,cAAwB,MAAM;AAAA,EAC1B;AAAA,EACA;AAAA,EAET,YACE,SACA,UAA+E,CAAC,GAChF;AACA,UAAM,SAAS,EAAE,OAAO,QAAQ,MAAM,CAAC;AACvC,SAAK,OAAO;AACZ,SAAK,WAAW,QAAQ,YAAY,SAAS;AAC7C,SAAK,cAAc,QAAQ;AAAA,EAC7B;AACF;AAEO,SAAS,YAAY,OAAoC;AAC9D,SAAO,iBAAiB;AAC1B;;;AC7BA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAQxB,SAAS,WAAW,MAAc,aAA+C;AAC/E,QAAM,QAAQ,cAAc,CAAC,WAAW,IAAI,CAAC;AAC7C,MAAI,CAAC,MAAM,SAAS,QAAQ,IAAI,CAAC,GAAG;AAClC,UAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,EAC1B;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,QAAQ,MAAM,gBAAgB,MAAM;AACnD,QAAI,SAAS,MAAM,SAAS;AAC1B,YAAM,MAAM,QAAQ,QAAQ,GAAG,IAAI,MAAM;AACzC,UAAI,WAAW,GAAG,GAAG;AACnB,eAAO,EAAE,SAAS,KAAK,YAAY,CAAC,EAAE;AAAA,MACxC;AAAA,IACF;AACA,UAAM,OAAO,QAAQ,QAAQ,IAAI;AACjC,QAAI,WAAW,IAAI,GAAG;AACpB,aAAO,EAAE,SAAS,MAAM,YAAY,CAAC,EAAE;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,uBAAuB,aAAwC;AAC7E,QAAM,QAAQ,WAAW,MAAM,WAAW;AAC1C,MAAI,OAAO;AACT,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,MAAM,SAAS;AAC1B,WAAO,EAAE,SAAS,MAAM,YAAY,CAAC,GAAG,OAAO,KAAK;AAAA,EACtD;AAEA,SAAO,EAAE,SAAS,MAAM,YAAY,CAAC,EAAE;AACzC;AAoBO,SAAS,sBACd,SACA,MACA,SACsD;AACtD,MAAI,YAAY,MAAM;AACpB,UAAMA,SAAQ,uBAAuB,QAAQ,eAAe,QAAQ,GAAG;AACvE,WAAO;AAAA,MACL,SAASA,OAAM;AAAA,MACf,MAAM,CAAC,GAAGA,OAAM,YAAY,GAAG,IAAI;AAAA,MACnC,OAAOA,OAAM;AAAA,IACf;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,KAAK;AACzB;;;AHzEA,IAAM,iBAAiB;AAgBvB,SAAS,QAAQ,QAA4B,SAAiB,MAAgB,SAA2B;AACvG,MAAI,CAAC,OAAQ;AACb,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,SAAO;AAAA,IACL,oBAAoB,SAAS,MAAM,QAAQ,KAAK,KAAK,QAAQ,WAAW;AAAA,EAC1E;AACF;AAEO,SAAS,WACd,SACA,MACA,SACoD;AACpD,QAAM,EAAE,KAAK,MAAM,QAAQ,KAAK,QAAQ,SAAS,OAAO,UAAU,CAAC,CAAC,GAAG,eAAe,MAAM,IAC1F;AAEF,MAAI,QAAQ;AACV,YAAQ,KAAK,aAAa,oBAAoB,SAAS,MAAM,KAAK,KAAK,QAAQ,WAAW,CAAC,EAAE;AAC7F,WAAO,EAAE,QAAQ,GAAG,QAAQ,IAAI,QAAQ,GAAG;AAAA,EAC7C;AAEA,QAAM,WAAW,sBAAsB,SAAS,MAAM;AAAA,IACpD,aAAa,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AAED,UAAQ,QAAQ,SAAS,SAAS,SAAS,MAAM,OAAO;AAExD,MAAI,cAAc;AAChB,UAAMC,UAAS,UAAU,SAAS,SAAS,SAAS,MAAM;AAAA,MACxD;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,MACP,OAAO,SAAS;AAAA,IAClB,CAAC;AACD,UAAMC,UAASD,QAAO,UAAU;AAChC,mBAAe,SAAS,SAAS,SAAS,MAAMC,SAAQ,IAAI,IAAI,OAAO;AACvE,WAAO,EAAE,QAAAA,SAAQ,QAAQ,IAAI,QAAQ,GAAG;AAAA,EAC1C;AAEA,QAAM,YAA8B;AAAA,IAClC;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,IACjC,OAAO,SAAS;AAAA,EAClB;AAEA,QAAM,SAAS,UAAU,SAAS,SAAS,SAAS,MAAM,SAAS;AACnE,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AACnE,QAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAEnE,iBAAe,SAAS,SAAS,SAAS,MAAM,QAAQ,QAAQ,QAAQ,OAAO;AAE/E,SAAO,EAAE,QAAQ,QAAQ,OAAO;AAClC;AAEO,SAAS,cACd,YACA,MACA,SACM;AACN,aAAW,QAAQ,UAAU,CAAC,YAAY,GAAG,IAAI,GAAG,OAAO;AAC7D;AAEA,SAAS,eACP,SACA,MACA,QACA,QACA,QACA,SACM;AACN,MAAI,QAAQ,SAAS,MAAM,GAAG;AAC5B;AAAA,EACF;AACA,QAAM,SAAS,OAAO,KAAK,KAAK,OAAO,KAAK,KAAK,QAAQ,MAAM;AAC/D,MAAI,eAAe,KAAK,MAAM,GAAG;AAC/B,UAAM,IAAI,UAAU,mBAAmB,OAAO,IAAI;AAAA,MAChD,UAAU,SAAS;AAAA,MACnB,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AACA,QAAM,IAAI,UAAU,mBAAmB,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,EAAK,MAAM,IAAI;AAAA,IAC7E,UAAU,SAAS;AAAA,EACrB,CAAC;AACH;AAKO,SAAS,gBACd,SACA,MACA,SAC6D;AAC7D,QAAM,EAAE,KAAK,MAAM,QAAQ,KAAK,QAAQ,SAAS,OAAO,UAAU,CAAC,CAAC,GAAG,eAAe,MAAM,IAC1F;AAEF,MAAI,QAAQ;AACV,YAAQ,KAAK,aAAa,oBAAoB,SAAS,MAAM,KAAK,KAAK,QAAQ,WAAW,CAAC,EAAE;AAC7F,WAAO,QAAQ,QAAQ,EAAE,QAAQ,GAAG,QAAQ,IAAI,QAAQ,GAAG,CAAC;AAAA,EAC9D;AAEA,QAAM,WAAW,sBAAsB,SAAS,MAAM;AAAA,IACpD,aAAa,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AAED,UAAQ,QAAQ,SAAS,SAAS,SAAS,MAAM,OAAO;AAExD,MAAI,cAAc;AAChB,WAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACtC,YAAM,QAAQ,MAAM,SAAS,SAAS,SAAS,MAAM;AAAA,QACnD;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,OAAO,SAAS;AAAA,MAClB,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,UAAU;AAC3B,eAAO,KAAK;AAAA,MACd,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,cAAM,SAAS,QAAQ;AACvB,YAAI;AACF,yBAAe,SAAS,SAAS,SAAS,MAAM,QAAQ,IAAI,IAAI,OAAO;AACvE,UAAAA,SAAQ,EAAE,QAAQ,QAAQ,IAAI,QAAQ,GAAG,CAAC;AAAA,QAC5C,SAAS,OAAO;AACd,iBAAO,KAAK;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,UAAM,QAAQ,MAAM,SAAS,SAAS,SAAS,MAAM;AAAA,MACnD;AAAA,MACA;AAAA,MACA,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,MACjC,OAAO,SAAS;AAAA,IAClB,CAAC;AAED,QAAI,SAAS;AACb,QAAI,SAAS;AAEb,UAAM,QAAQ,YAAY,MAAM;AAChC,UAAM,QAAQ,YAAY,MAAM;AAChC,UAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC1C,gBAAU;AAAA,IACZ,CAAC;AACD,UAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC1C,gBAAU;AAAA,IACZ,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,UAAU;AAC3B,aAAO,KAAK;AAAA,IACd,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,YAAM,SAAS,QAAQ;AACvB,UAAI;AACF,uBAAe,SAAS,SAAS,SAAS,MAAM,QAAQ,QAAQ,QAAQ,OAAO;AAC/E,QAAAA,SAAQ,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAAA,MACpC,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEO,SAAS,mBACd,YACA,MACA,SACe;AACf,SAAO,gBAAgB,QAAQ,UAAU,CAAC,YAAY,GAAG,IAAI,GAAG,OAAO,EAAE,KAAK,MAAM,MAAS;AAC/F;AAMO,SAAS,yBACd,YACA,MACA,SACiB;AACjB,QAAM,EAAE,KAAK,MAAM,QAAQ,KAAK,QAAQ,SAAS,MAAM,IAAI;AAE3D,MAAI,QAAQ;AACV,YAAQ;AAAA,MACN,aAAa,oBAAoB,QAAQ,UAAU,CAAC,YAAY,GAAG,IAAI,GAAG,KAAK,KAAK,QAAQ,WAAW,CAAC;AAAA,IAC1G;AACA,WAAO,QAAQ,QAAQ,CAAC;AAAA,EAC1B;AAEA,SAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,UAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,YAAY,GAAG,IAAI,GAAG;AAAA,MAC3D;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AAED,UAAM,gBAAgB,CAAC,WAA2B;AAChD,UAAI,CAAC,MAAM,QAAQ;AACjB,cAAM,KAAK,MAAM;AAAA,MACnB;AAAA,IACF;AAEA,YAAQ,GAAG,UAAU,aAAa;AAClC,YAAQ,GAAG,WAAW,aAAa;AAEnC,UAAM,GAAG,SAAS,CAAC,UAAU;AAC3B,cAAQ,IAAI,UAAU,aAAa;AACnC,cAAQ,IAAI,WAAW,aAAa;AACpC,aAAO,KAAK;AAAA,IACd,CAAC;AAED,UAAM,GAAG,QAAQ,CAAC,MAAM,WAAW;AACjC,cAAQ,IAAI,UAAU,aAAa;AACnC,cAAQ,IAAI,WAAW,aAAa;AAEpC,UAAI,WAAW,UAAU;AACvB,QAAAA,SAAQ,GAAG;AACX;AAAA,MACF;AACA,UAAI,WAAW,WAAW;AACxB,QAAAA,SAAQ,GAAG;AACX;AAAA,MACF;AAEA,MAAAA,SAAQ,QAAQ,CAAC;AAAA,IACnB,CAAC;AAAA,EACH,CAAC;AACH;","names":["spawn","result","status","resolve"]}
|
package/dist/cli.js
CHANGED
|
@@ -19,16 +19,17 @@ import {
|
|
|
19
19
|
scaffoldPage,
|
|
20
20
|
titleFromSlug,
|
|
21
21
|
usesCdnPipeline
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-4UFWXPQG.js";
|
|
23
23
|
import {
|
|
24
24
|
ExitCode,
|
|
25
25
|
WpHsError,
|
|
26
26
|
isWpHsError,
|
|
27
|
+
resolveHubSpotCliSpawn,
|
|
27
28
|
runCommand,
|
|
28
29
|
runCommandAsync,
|
|
29
30
|
runNodeScriptAsync,
|
|
30
31
|
runNodeScriptLongRunning
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-GXYUGXF5.js";
|
|
32
33
|
|
|
33
34
|
// src/cli/program.ts
|
|
34
35
|
import { Command } from "commander";
|
|
@@ -391,12 +392,14 @@ var PLACEHOLDER_PATTERNS = [
|
|
|
391
392
|
/portalId:\s*12345678\b/
|
|
392
393
|
];
|
|
393
394
|
function spawnHs(args, options = {}) {
|
|
394
|
-
|
|
395
|
+
const spawn = resolveHubSpotCliSpawn(options.cwd);
|
|
396
|
+
return spawnSync(spawn.command, [...spawn.prefixArgs, ...args], {
|
|
395
397
|
cwd: options.cwd,
|
|
396
398
|
encoding: "utf8",
|
|
397
399
|
timeout: options.timeoutMs ?? HS_ACCOUNTS_TIMEOUT_MS,
|
|
398
400
|
// Keep HubSpot CLI off the interactive TTY (avoids hangs under @clack spinners)
|
|
399
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
401
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
402
|
+
shell: spawn.shell
|
|
400
403
|
});
|
|
401
404
|
}
|
|
402
405
|
function hsTimedOut(result) {
|
|
@@ -749,13 +752,20 @@ function formatCdnSetupNote(_projectRoot) {
|
|
|
749
752
|
}
|
|
750
753
|
|
|
751
754
|
// src/lib/wphs-workspace.ts
|
|
755
|
+
import { pathToFileURL } from "url";
|
|
752
756
|
var ensureModulePromise;
|
|
757
|
+
function ensureScriptUrl() {
|
|
758
|
+
return pathToFileURL(kitPath("scripts", "ensure-wphs-workspace.mjs")).href;
|
|
759
|
+
}
|
|
753
760
|
function loadEnsureModule() {
|
|
754
761
|
if (!ensureModulePromise) {
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
762
|
+
const scriptUrl = ensureScriptUrl();
|
|
763
|
+
ensureModulePromise = import(
|
|
764
|
+
/* webpackIgnore: true */
|
|
765
|
+
scriptUrl
|
|
766
|
+
).then(
|
|
767
|
+
(mod) => mod
|
|
768
|
+
);
|
|
759
769
|
}
|
|
760
770
|
return ensureModulePromise;
|
|
761
771
|
}
|
|
@@ -2677,7 +2687,7 @@ async function runAuditSecrets(ctx) {
|
|
|
2677
2687
|
|
|
2678
2688
|
// src/cli/commands/init.ts
|
|
2679
2689
|
import { cpSync as cpSync3, existsSync as existsSync13, mkdirSync as mkdirSync5, readdirSync as readdirSync2, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "fs";
|
|
2680
|
-
import { basename as
|
|
2690
|
+
import { basename as basename3, resolve as resolve17 } from "path";
|
|
2681
2691
|
import * as p5 from "@clack/prompts";
|
|
2682
2692
|
|
|
2683
2693
|
// src/lib/init-router-scaffold.ts
|
|
@@ -2948,6 +2958,7 @@ function patchStarterOnlyBlocks(targetDir, mode) {
|
|
|
2948
2958
|
let content = readFileSync11(filePath, "utf8");
|
|
2949
2959
|
content = stripMarkedBlock(content, "WPHS_AUTH_SSO", hasSso);
|
|
2950
2960
|
content = stripMarkedBlock(content, "WPHS_AUTH_FULL", hasFull);
|
|
2961
|
+
content = stripMarkedBlock(content, "WPHS_AUTH_NOT_FULL", !hasFull);
|
|
2951
2962
|
if (!hasFull && relative === "src/integrations/configure-woodsportal-sdk.ts") {
|
|
2952
2963
|
content = content.replace(
|
|
2953
2964
|
/^import \{ isMfaPendingSession \} from '@\/features\/auth\/auth-session'\n/m,
|
|
@@ -3033,6 +3044,21 @@ function assertFullTierAuthScaffold(targetDir) {
|
|
|
3033
3044
|
exitCode: ExitCode.INTERNAL
|
|
3034
3045
|
});
|
|
3035
3046
|
}
|
|
3047
|
+
const starterLoginPath = resolve15(targetDir, "src/features/auth/components/starter-login.tsx");
|
|
3048
|
+
if (existsSync11(starterLoginPath)) {
|
|
3049
|
+
const starterLogin = readFileSync11(starterLoginPath, "utf8");
|
|
3050
|
+
if (starterLogin.includes("WPHS_AUTH_")) {
|
|
3051
|
+
throw new WpHsError('Auth scaffold tier "full" left WPHS_AUTH_* markers in starter-login.tsx', {
|
|
3052
|
+
exitCode: ExitCode.INTERNAL
|
|
3053
|
+
});
|
|
3054
|
+
}
|
|
3055
|
+
if (starterLogin.includes("MFA_REQUIRED_SCAFFOLD_MESSAGE")) {
|
|
3056
|
+
throw new WpHsError(
|
|
3057
|
+
'Auth scaffold tier "full" starter-login.tsx must not import MFA_REQUIRED_SCAFFOLD_MESSAGE',
|
|
3058
|
+
{ exitCode: ExitCode.INTERNAL }
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3036
3062
|
}
|
|
3037
3063
|
function patchPackageJson(targetDir) {
|
|
3038
3064
|
const pkgPath = resolve15(targetDir, "package.json");
|
|
@@ -3215,6 +3241,7 @@ function readProjectAuthTier(targetDir) {
|
|
|
3215
3241
|
|
|
3216
3242
|
// src/lib/init-wizard.ts
|
|
3217
3243
|
import * as p4 from "@clack/prompts";
|
|
3244
|
+
import { basename } from "path";
|
|
3218
3245
|
|
|
3219
3246
|
// src/lib/project-name.ts
|
|
3220
3247
|
var PROJECT_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
@@ -3280,7 +3307,7 @@ async function runInitWizard(options) {
|
|
|
3280
3307
|
projectName = normalizeProjectName(nameAnswer);
|
|
3281
3308
|
}
|
|
3282
3309
|
if (!projectName && options.directory) {
|
|
3283
|
-
projectName = normalizeProjectName(options.directory
|
|
3310
|
+
projectName = normalizeProjectName(basename(options.directory) || "my-portal");
|
|
3284
3311
|
}
|
|
3285
3312
|
if (!projectName) {
|
|
3286
3313
|
throw new WpHsError("Project name is required", {
|
|
@@ -3387,7 +3414,10 @@ async function runInitWizard(options) {
|
|
|
3387
3414
|
`Auth: ${auth}`,
|
|
3388
3415
|
...auth !== "none" ? [`Nav: ${nav}`] : []
|
|
3389
3416
|
] : [],
|
|
3390
|
-
...template === "module-hybrid-cdn" ? [
|
|
3417
|
+
...template === "module-hybrid-cdn" ? [
|
|
3418
|
+
`CDN repo: ${cdnSetup?.github ?? "(skipped \u2014 configure later)"}`,
|
|
3419
|
+
...cdnSetup?.github && /your-org|your-portal-cdn-mirror/i.test(cdnSetup.github) ? [" (placeholder \u2014 run wp setup before wp deploy)"] : []
|
|
3420
|
+
] : []
|
|
3391
3421
|
].join("\n");
|
|
3392
3422
|
p4.note(summary, "Scaffold summary");
|
|
3393
3423
|
const confirmed = cancelIfNeeded(
|
|
@@ -3412,7 +3442,7 @@ async function runInitWizard(options) {
|
|
|
3412
3442
|
|
|
3413
3443
|
// src/lib/project-setup.ts
|
|
3414
3444
|
import { copyFileSync, existsSync as existsSync12, writeFileSync as writeFileSync7 } from "fs";
|
|
3415
|
-
import { basename, resolve as resolve16 } from "path";
|
|
3445
|
+
import { basename as basename2, resolve as resolve16 } from "path";
|
|
3416
3446
|
function envFileForTier2(tier) {
|
|
3417
3447
|
return tier === "dev" ? ".env.dev" : tier === "stg" ? ".env.stg" : ".env.prod";
|
|
3418
3448
|
}
|
|
@@ -3442,7 +3472,7 @@ function copyMissingFile(projectRoot, targetName, sourceCandidates, dryRun) {
|
|
|
3442
3472
|
if (!dryRun) {
|
|
3443
3473
|
copyFileSync(source, target);
|
|
3444
3474
|
}
|
|
3445
|
-
const from =
|
|
3475
|
+
const from = basename2(source);
|
|
3446
3476
|
return {
|
|
3447
3477
|
action: "copied",
|
|
3448
3478
|
path: targetName,
|
|
@@ -3723,7 +3753,7 @@ async function runInit(ctx, options) {
|
|
|
3723
3753
|
});
|
|
3724
3754
|
}
|
|
3725
3755
|
const targetDir = resolveInitTargetDir(options, projectName);
|
|
3726
|
-
const slug = projectName ??
|
|
3756
|
+
const slug = projectName ?? basename3(targetDir);
|
|
3727
3757
|
assertTargetDirIsScaffoldable(targetDir);
|
|
3728
3758
|
const templateDir = kitPath("templates", template);
|
|
3729
3759
|
if (!existsSync13(templateDir)) {
|
|
@@ -3793,7 +3823,7 @@ ${toAppend}
|
|
|
3793
3823
|
}
|
|
3794
3824
|
if (!nonInteractive) {
|
|
3795
3825
|
p5.log.success(`Scaffolded ${template} in ${targetDir}`);
|
|
3796
|
-
p5.note(`cd ${slug} &&
|
|
3826
|
+
p5.note(`cd ${slug} && npm install && wp setup && wp doctor && wp dev`, "Getting started");
|
|
3797
3827
|
} else {
|
|
3798
3828
|
ctx.logger.success(`Scaffolded ${template} in ${targetDir}`);
|
|
3799
3829
|
}
|
|
@@ -3951,7 +3981,7 @@ async function runExamplesSmoke(ctx, options = {}) {
|
|
|
3951
3981
|
const tier = options.tier ?? "static";
|
|
3952
3982
|
const args = ["--tier", tier];
|
|
3953
3983
|
if (options.scenario) args.push("--scenario", options.scenario);
|
|
3954
|
-
const { runNodeScript } = await import("./exec-
|
|
3984
|
+
const { runNodeScript } = await import("./exec-NS4GKXZS.js");
|
|
3955
3985
|
runNodeScript(kitPath("examples", "smoke", "run-matrix.mjs"), args, {
|
|
3956
3986
|
cwd: ctx.projectRoot,
|
|
3957
3987
|
logger: ctx.logger,
|
|
@@ -4281,7 +4311,8 @@ async function runPortalUse(ctx, options = {}) {
|
|
|
4281
4311
|
runCommand("hs", ["accounts", "use", portal.name], {
|
|
4282
4312
|
cwd: ctx.projectRoot,
|
|
4283
4313
|
logger: ctx.logger,
|
|
4284
|
-
dryRun: false
|
|
4314
|
+
dryRun: false,
|
|
4315
|
+
projectRoot: ctx.projectRoot
|
|
4285
4316
|
});
|
|
4286
4317
|
if (!ctx.global.json && !ctx.global.quiet) {
|
|
4287
4318
|
printCommandDone(ctx, `Default portal \u2192 ${portal.name}`);
|
|
@@ -4466,7 +4497,7 @@ async function runPageAdd(ctx, options) {
|
|
|
4466
4497
|
return ExitCode.SUCCESS;
|
|
4467
4498
|
}
|
|
4468
4499
|
async function runPageList(ctx) {
|
|
4469
|
-
const { listScaffoldedPages } = await import("./scaffold-page-lifecycle-
|
|
4500
|
+
const { listScaffoldedPages } = await import("./scaffold-page-lifecycle-53AWWGFR.js");
|
|
4470
4501
|
const pages = listScaffoldedPages(ctx.projectRoot, ctx.config);
|
|
4471
4502
|
if (ctx.global.json) {
|
|
4472
4503
|
ctx.logger.json({ pages });
|
|
@@ -4492,7 +4523,7 @@ async function runPageList(ctx) {
|
|
|
4492
4523
|
return ExitCode.SUCCESS;
|
|
4493
4524
|
}
|
|
4494
4525
|
async function runPageRemove(ctx, options) {
|
|
4495
|
-
const { removeScaffoldedPage } = await import("./scaffold-page-lifecycle-
|
|
4526
|
+
const { removeScaffoldedPage } = await import("./scaffold-page-lifecycle-53AWWGFR.js");
|
|
4496
4527
|
const result = removeScaffoldedPage({
|
|
4497
4528
|
projectRoot: ctx.projectRoot,
|
|
4498
4529
|
config: ctx.config,
|
|
@@ -4855,14 +4886,18 @@ function createProgram() {
|
|
|
4855
4886
|
});
|
|
4856
4887
|
program2.command("auth").description("Authenticate HubSpot CLI (hs auth)").action(async () => {
|
|
4857
4888
|
const global = program2.opts();
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4889
|
+
await handle(async () => {
|
|
4890
|
+
const ctx = buildContext(global);
|
|
4891
|
+
const { runCommand: runCommand2 } = await import("./exec-NS4GKXZS.js");
|
|
4892
|
+
runCommand2("hs", ["auth"], {
|
|
4893
|
+
cwd: ctx.projectRoot,
|
|
4894
|
+
logger: ctx.logger,
|
|
4895
|
+
dryRun: ctx.global.dryRun,
|
|
4896
|
+
projectRoot: ctx.projectRoot,
|
|
4897
|
+
streamOutput: true
|
|
4898
|
+
});
|
|
4899
|
+
return ExitCode.SUCCESS;
|
|
4864
4900
|
});
|
|
4865
|
-
process.exit(ExitCode.SUCCESS);
|
|
4866
4901
|
});
|
|
4867
4902
|
const portal = program2.command("portal").description("HubSpot default portal selection");
|
|
4868
4903
|
portal.command("list").alias("ls").description("List portals from hubspot.config.yml").action(async () => {
|