@woodsportal/hubspot-kit 1.0.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 +31 -0
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/SECURITY.md +27 -0
- package/dist/chunk-JDGIAYHX.js +87 -0
- package/dist/chunk-JDGIAYHX.js.map +1 -0
- package/dist/chunk-U4KFGTEW.js +136 -0
- package/dist/chunk-U4KFGTEW.js.map +1 -0
- package/dist/cli.js +1849 -0
- package/dist/cli.js.map +1 -0
- package/dist/exec-K5C6LZP4.js +10 -0
- package/dist/exec-K5C6LZP4.js.map +1 -0
- package/dist/index.d.ts +228 -0
- package/dist/index.js +204 -0
- package/dist/index.js.map +1 -0
- package/dist/vite/index.d.ts +17 -0
- package/dist/vite/index.js +9 -0
- package/dist/vite/index.js.map +1 -0
- package/examples/README.md +12 -0
- package/examples/fixtures/adopted-module-hybrid/public/fields.json +1 -0
- package/examples/fixtures/adopted-module-hybrid/public/module.html +1 -0
- package/examples/fixtures/adopted-module-hybrid/woodscli.json +7 -0
- package/examples/fixtures/adopted-module-monolith/public/fields.json +1 -0
- package/examples/fixtures/adopted-module-monolith/woodscli.json +7 -0
- package/examples/fixtures/adopted-theme-minimal/src/theme/templates/page.html +1 -0
- package/examples/fixtures/adopted-theme-minimal/src/theme/theme.json +1 -0
- package/examples/fixtures/adopted-theme-minimal/woodscli.json +7 -0
- package/examples/fixtures/existing-module-hybrid/public/fields.json +1 -0
- package/examples/fixtures/existing-module-hybrid/public/module.html +1 -0
- package/examples/fixtures/existing-theme-minimal/templates/page.html +1 -0
- package/examples/fixtures/existing-theme-minimal/theme.json +1 -0
- package/examples/greenfield/module-hybrid-cdn/README.md +9 -0
- package/examples/greenfield/module-hybrid-cdn/index.html +1 -0
- package/examples/greenfield/module-hybrid-cdn/package.json +14 -0
- package/examples/greenfield/module-hybrid-cdn/public/fields.json +1 -0
- package/examples/greenfield/module-hybrid-cdn/public/module.html +1 -0
- package/examples/greenfield/module-hybrid-cdn/src/main.tsx +2 -0
- package/examples/greenfield/module-hybrid-cdn/vite.config.dev.mjs +1 -0
- package/examples/greenfield/module-hybrid-cdn/vite.config.hubspot.mjs +1 -0
- package/examples/greenfield/module-hybrid-cdn/woodscli.json +8 -0
- package/examples/greenfield/module-hybrid-cdn/wphs.adapter.ts +7 -0
- package/examples/greenfield/module-monolith/package.json +12 -0
- package/examples/greenfield/module-monolith/public/fields.json +1 -0
- package/examples/greenfield/module-monolith/vite.config.dev.mjs +1 -0
- package/examples/greenfield/module-monolith/vite.config.monolith.mjs +1 -0
- package/examples/greenfield/module-monolith/woodscli.json +25 -0
- package/examples/greenfield/module-monolith/wphs.adapter.ts +7 -0
- package/examples/greenfield/theme-starter/package.json +11 -0
- package/examples/greenfield/theme-starter/src/theme/css/main.css +1 -0
- package/examples/greenfield/theme-starter/src/theme/templates/base.html +1 -0
- package/examples/greenfield/theme-starter/src/theme/templates/page.html +1 -0
- package/examples/greenfield/theme-starter/src/theme/theme.json +1 -0
- package/examples/greenfield/theme-starter/theme.json +6 -0
- package/examples/greenfield/theme-starter/vite.config.dev.mjs +1 -0
- package/examples/greenfield/theme-starter/woodscli.json +7 -0
- package/examples/manifest.json +20 -0
- package/examples/smoke/run-matrix.mjs +100 -0
- package/package.json +94 -0
- package/scripts/audit-module-config-fields.mjs +73 -0
- package/scripts/audit-parity.mjs +22 -0
- package/scripts/audit-tdz-split.mjs +111 -0
- package/scripts/build-cdn.mjs +36 -0
- package/scripts/check-hubspot-bundle-size.mjs +58 -0
- package/scripts/config-files.mjs +53 -0
- package/scripts/detect-layout.mjs +70 -0
- package/scripts/ensure-wphs-workspace.mjs +53 -0
- package/scripts/generate-cdn-manifest.mjs +92 -0
- package/scripts/generate-module-config-example.mjs +57 -0
- package/scripts/hubspot-module-postbuild.mjs +151 -0
- package/scripts/load-portal-cdn-config.mjs +91 -0
- package/scripts/migrate-sdk-3-api.mjs +144 -0
- package/scripts/module-config-dir.mjs +12 -0
- package/scripts/portal-env-mode.mjs +24 -0
- package/scripts/portal-vite-env.mjs +39 -0
- package/scripts/project-root.mjs +30 -0
- package/scripts/publish-cdn-github.mjs +273 -0
- package/scripts/read-woodsportal-config.mjs +40 -0
- package/scripts/resolve-cdn-base-url.mjs +32 -0
- package/scripts/resolve-consumer-dep.mjs +25 -0
- package/scripts/resolve-portal-build-id.mjs +67 -0
- package/scripts/run-dev.mjs +93 -0
- package/scripts/run-hubspot-module-postbuild.mjs +19 -0
- package/scripts/run-vite-build.mjs +33 -0
- package/scripts/tailwind/prefix-plugin.js +291 -0
- package/scripts/tailwind/prefix.env.js +11 -0
- package/scripts/tailwind/tailwind-content-plugin.js +27 -0
- package/scripts/tailwind/tailwind-content.js +267 -0
- package/scripts/verify-cdn-api-endpoint.mjs +68 -0
- package/scripts/vite/ensure-dev-kit-shims.js +49 -0
- package/scripts/vite/ensure-dev-module-config-shim.js +1 -0
- package/scripts/vite/module-config-store.js +242 -0
- package/scripts/vite/plugins.d.ts +9 -0
- package/scripts/vite/portal-build-shared.js +110 -0
- package/scripts/vite/react-dev-plugin-options.js +21 -0
- package/scripts/vite/resolve-from-project-root.js +31 -0
- package/scripts/vite/sdk-log-bridge.js +104 -0
- package/scripts/watch-hubspot.mjs +86 -0
- package/scripts/wphs-paths.mjs +115 -0
- package/scripts/write-audit-artifacts.mjs +56 -0
- package/templates/hubspot.config.yml.example +10 -0
- package/templates/module-hybrid-cdn/README.md +9 -0
- package/templates/module-hybrid-cdn/hubspot.config.yml.example +10 -0
- package/templates/module-hybrid-cdn/index.html +1 -0
- package/templates/module-hybrid-cdn/package.json +14 -0
- package/templates/module-hybrid-cdn/public/fields.json +1 -0
- package/templates/module-hybrid-cdn/public/module.html +1 -0
- package/templates/module-hybrid-cdn/src/main.tsx +2 -0
- package/templates/module-hybrid-cdn/vite.config.dev.mjs +1 -0
- package/templates/module-hybrid-cdn/vite.config.hubspot.mjs +1 -0
- package/templates/module-hybrid-cdn/woodscli.json +8 -0
- package/templates/module-hybrid-cdn/wphs.adapter.ts +7 -0
- package/templates/module-monolith/hubspot.config.yml.example +10 -0
- package/templates/module-monolith/package.json +12 -0
- package/templates/module-monolith/public/fields.json +1 -0
- package/templates/module-monolith/vite.config.dev.mjs +1 -0
- package/templates/module-monolith/vite.config.monolith.mjs +1 -0
- package/templates/module-monolith/woodscli.json +25 -0
- package/templates/module-monolith/wphs.adapter.ts +7 -0
- package/templates/theme-starter/hubspot.config.yml.example +10 -0
- package/templates/theme-starter/package.json +11 -0
- package/templates/theme-starter/src/theme/css/main.css +1 -0
- package/templates/theme-starter/src/theme/templates/base.html +1 -0
- package/templates/theme-starter/src/theme/templates/page.html +1 -0
- package/templates/theme-starter/src/theme/theme.json +1 -0
- package/templates/theme-starter/theme.json +6 -0
- package/templates/theme-starter/vite.config.dev.mjs +1 -0
- package/templates/theme-starter/woodscli.json +7 -0
- package/vite/vite.config.audit.mjs +33 -0
- package/vite/vite.config.cdn-app.mjs +44 -0
- package/vite/vite.config.cdn-esm.mjs +35 -0
- package/vite/vite.config.cdn-vendor.mjs +33 -0
- package/vite/vite.config.dev.mjs +62 -0
- package/vite/vite.config.hubspot.mjs +33 -0
- package/vite/vite.config.monolith.mjs +55 -0
- package/vite/vite.config.tdz-audit.mjs +58 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.2 — 2026-06-07
|
|
4
|
+
|
|
5
|
+
### WoodsCLI product positioning
|
|
6
|
+
- Rebrand CLI/docs as **WoodsCLI** — HubSpot CMS dev kit by WoodsPortal
|
|
7
|
+
- Canonical dev command **`wp dev`** (`wp local` remains alias)
|
|
8
|
+
- **`.wphs/`** workspace (config, assets, fixtures, cache, audit baseline)
|
|
9
|
+
- `wp migrate`, `wp adopt`, `wp examples list|smoke`, `wp fields sync`, `wp audit secrets`
|
|
10
|
+
- `HubSpotKitAdapter` + `wphs.adapter.ts` consumer hook
|
|
11
|
+
- `projectType`-aware build/upload/watch; monolith Vite preset in kit
|
|
12
|
+
- Complete `module-hybrid-cdn`, `module-monolith`, `theme-starter` templates
|
|
13
|
+
- Examples smoke matrix + `npm run test:examples` in CI
|
|
14
|
+
- Production upload guard (`--yes` / `WP_HS_CONFIRM_PROD=1`)
|
|
15
|
+
- `--tier stg` support across build/deploy/publish
|
|
16
|
+
|
|
17
|
+
## 1.0.1 — 2026-06-07
|
|
18
|
+
|
|
19
|
+
- Fix module-config overlay drawer width (CSS fallback + Tailwind scan kit sources)
|
|
20
|
+
- Default local workspace dir `.dev` (was `dev`); `moduleConfigDir` in `woodsportal.hs.json`
|
|
21
|
+
- Module-config UI: drill-down panel stack, toggle isolation, menu-options parity fixes
|
|
22
|
+
- Overlay shortcut `Ctrl+Shift+Z` / `Cmd+Shift+Z` (was `Ctrl+Shift+M`)
|
|
23
|
+
- Extract canonical routing helpers to `src/routing/` (`build-api-routes`, `route-format`)
|
|
24
|
+
- Tailwind content plugin scans kit `dev-module-config` paths on HMR
|
|
25
|
+
|
|
26
|
+
## 1.0.0 — 2026-06-07
|
|
27
|
+
|
|
28
|
+
- Initial release: `wp` CLI with `doctor`, `init`, `dev`, `build`, `deploy`, `audit`
|
|
29
|
+
- Vite presets for hybrid CDN + HubSpot module builds
|
|
30
|
+
- Local module-config dev tooling (extracted from woodsportal-client-frontend)
|
|
31
|
+
- `woodsportal.hs.json` project configuration schema
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Digital Woods
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# WoodsCLI
|
|
2
|
+
|
|
3
|
+
> HubSpot CMS dev kit by WoodsPortal — modules and themes.
|
|
4
|
+
> `npm i @woodsportal/hubspot-kit` · `wp dev`
|
|
5
|
+
|
|
6
|
+
WoodsCLI (`wp`) is the development CLI for **HubSpot CMS custom modules** (React/JS + `fields.json`) and **themes** (templates, CSS, theme fields). It wraps `@hubspot/cli` for upload/watch and adds local preview, Content/Styles field editing (**Ctrl+Shift+Z**), and hybrid CDN or monolith build pipelines.
|
|
7
|
+
|
|
8
|
+
## Two tracks
|
|
9
|
+
|
|
10
|
+
| Track | `projectType` | Quick start |
|
|
11
|
+
|-------|---------------|-------------|
|
|
12
|
+
| **Module (hybrid CDN)** | `module-hybrid-cdn` | `wp init -t module-hybrid-cdn` → `wp dev` → `wp deploy` |
|
|
13
|
+
| **Module (monolith)** | `module-monolith` | `wp init -t module-monolith` → `wp dev` → `wp build --hubspot-only` |
|
|
14
|
+
| **Theme** | `theme-starter` | `wp init -t theme-starter` → `wp dev` → `wp upload` |
|
|
15
|
+
|
|
16
|
+
WoodsPortal client-frontend is the **reference advanced module** (hybrid CDN + full app adapter).
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx wp init -t module-hybrid-cdn
|
|
22
|
+
cd my-project && npm install
|
|
23
|
+
wp doctor
|
|
24
|
+
wp dev # alias: wp local
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Existing repo:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
wp adopt
|
|
31
|
+
wp migrate --yes # if migrating from .dev/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
| Command | Description |
|
|
37
|
+
|---------|-------------|
|
|
38
|
+
| `wp dev` | Local Vite server + CMS dev tool |
|
|
39
|
+
| `wp build` | CDN + module (or theme no-op) |
|
|
40
|
+
| `wp deploy` | Build, publish CDN, upload module |
|
|
41
|
+
| `wp adopt` | Detect module/theme and add config + `.wphs/` |
|
|
42
|
+
| `wp migrate` | `.dev/` → `.wphs/` |
|
|
43
|
+
| `wp examples smoke` | Run examples matrix (CI) |
|
|
44
|
+
| `wp audit secrets` | Scan for hardcoded credentials |
|
|
45
|
+
|
|
46
|
+
See [docs/CLI-REFERENCE.md](./docs/CLI-REFERENCE.md), [docs/MODULES.md](./docs/MODULES.md), [docs/THEMES.md](./docs/THEMES.md), [docs/EXAMPLES.md](./docs/EXAMPLES.md).
|
|
47
|
+
|
|
48
|
+
## Config
|
|
49
|
+
|
|
50
|
+
**Config:** `woodscli.json` at project root. Legacy `woodsportal.hs.json` → run `wp migrate --yes`.
|
|
51
|
+
|
|
52
|
+
Local workspace: **`.wphs/`** only. Consumer hook: **`wphs.adapter.ts`**.
|
|
53
|
+
|
|
54
|
+
HubSpot upload/watch: **`hubspot.config.yml`** — [setup guide](./docs/HUBSPOT-CLI-SETUP.md).
|
|
55
|
+
|
|
56
|
+
## Prerequisites
|
|
57
|
+
|
|
58
|
+
Node 20+, `@hubspot/cli`, HubSpot account with CMS.
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT — Digital Woods
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
## Reporting
|
|
4
|
+
|
|
5
|
+
Report vulnerabilities to Digital Woods security contact (see repository maintainers).
|
|
6
|
+
|
|
7
|
+
## Secrets
|
|
8
|
+
|
|
9
|
+
- Never commit HubSpot PATs, OAuth client secrets, or Stripe keys.
|
|
10
|
+
- Use env files (`.env.dev`, `.env.prod`) — gitignored.
|
|
11
|
+
- Run `wp audit secrets` before release.
|
|
12
|
+
|
|
13
|
+
## Production upload
|
|
14
|
+
|
|
15
|
+
`wp upload --tier prod` requires `--yes` or `WP_HS_CONFIRM_PROD=1` to prevent accidental Design Manager overwrites.
|
|
16
|
+
|
|
17
|
+
## HubSpot CLI
|
|
18
|
+
|
|
19
|
+
`wp auth` delegates to `hs auth`. Use least-privilege CMS scopes for upload accounts.
|
|
20
|
+
|
|
21
|
+
## WoodsCLI workspace
|
|
22
|
+
|
|
23
|
+
`.wphs/config/module-config.local.json` and `.wphs/assets/` are gitignored — may contain customer branding URLs; do not log full contents in production.
|
|
24
|
+
|
|
25
|
+
## Dependency hygiene
|
|
26
|
+
|
|
27
|
+
`npm run verify` on publish; address CVEs in direct dependencies promptly.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/exec.ts
|
|
4
|
+
import { spawnSync } from "child_process";
|
|
5
|
+
|
|
6
|
+
// src/lib/errors.ts
|
|
7
|
+
var ExitCode = {
|
|
8
|
+
SUCCESS: 0,
|
|
9
|
+
USER_ERROR: 1,
|
|
10
|
+
PREREQUISITE: 2,
|
|
11
|
+
BUILD_FAILED: 3,
|
|
12
|
+
PUBLISH_FAILED: 4,
|
|
13
|
+
AUDIT_FAILED: 5,
|
|
14
|
+
INTERNAL: 10
|
|
15
|
+
};
|
|
16
|
+
var WpHsError = class extends Error {
|
|
17
|
+
exitCode;
|
|
18
|
+
remediation;
|
|
19
|
+
constructor(message, options = {}) {
|
|
20
|
+
super(message, { cause: options.cause });
|
|
21
|
+
this.name = "WpHsError";
|
|
22
|
+
this.exitCode = options.exitCode ?? ExitCode.USER_ERROR;
|
|
23
|
+
this.remediation = options.remediation;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function isWpHsError(error) {
|
|
27
|
+
return error instanceof WpHsError;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/lib/exec.ts
|
|
31
|
+
var SECRET_PATTERN = /(token|secret|password|pat|key)=/i;
|
|
32
|
+
function maskEnv(env) {
|
|
33
|
+
const masked = { ...env };
|
|
34
|
+
for (const key of Object.keys(masked)) {
|
|
35
|
+
if (/token|secret|password|pat|auth/i.test(key) && masked[key]) {
|
|
36
|
+
masked[key] = "[redacted]";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return masked;
|
|
40
|
+
}
|
|
41
|
+
function runCommand(command, args, options) {
|
|
42
|
+
const { cwd, env = process.env, logger, dryRun = false, okCodes = [0] } = options;
|
|
43
|
+
if (dryRun) {
|
|
44
|
+
logger?.info(`[dry-run] ${command} ${args.join(" ")}`, { cwd });
|
|
45
|
+
return { status: 0, stdout: "", stderr: "" };
|
|
46
|
+
}
|
|
47
|
+
logger?.debug(`exec: ${command} ${args.join(" ")}`, {
|
|
48
|
+
cwd,
|
|
49
|
+
env: logger ? maskEnv(env) : void 0
|
|
50
|
+
});
|
|
51
|
+
const spawnOpts = {
|
|
52
|
+
cwd,
|
|
53
|
+
env,
|
|
54
|
+
encoding: "utf8",
|
|
55
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
56
|
+
};
|
|
57
|
+
const result = spawnSync(command, args, spawnOpts);
|
|
58
|
+
const status = result.status ?? 1;
|
|
59
|
+
const stdout = typeof result.stdout === "string" ? result.stdout : "";
|
|
60
|
+
const stderr = typeof result.stderr === "string" ? result.stderr : "";
|
|
61
|
+
if (!okCodes.includes(status)) {
|
|
62
|
+
const detail = stderr.trim() || stdout.trim() || `exit ${status}`;
|
|
63
|
+
if (SECRET_PATTERN.test(detail)) {
|
|
64
|
+
throw new WpHsError(`Command failed: ${command}`, {
|
|
65
|
+
exitCode: ExitCode.USER_ERROR,
|
|
66
|
+
remediation: "Re-run with --verbose for details (secrets are never logged)."
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
throw new WpHsError(`Command failed: ${command} ${args.join(" ")}
|
|
70
|
+
${detail}`, {
|
|
71
|
+
exitCode: ExitCode.USER_ERROR
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return { status, stdout, stderr };
|
|
75
|
+
}
|
|
76
|
+
function runNodeScript(scriptPath, args, options) {
|
|
77
|
+
runCommand(process.execPath, [scriptPath, ...args], options);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export {
|
|
81
|
+
ExitCode,
|
|
82
|
+
WpHsError,
|
|
83
|
+
isWpHsError,
|
|
84
|
+
runCommand,
|
|
85
|
+
runNodeScript
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=chunk-JDGIAYHX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/exec.ts","../src/lib/errors.ts"],"sourcesContent":["import { spawnSync, type SpawnSyncOptions } from 'node:child_process'\n\nimport { WpHsError, ExitCode } from './errors.js'\nimport type { Logger } from './logger.js'\n\nconst SECRET_PATTERN = /(token|secret|password|pat|key)=/i\n\nfunction maskEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const masked: NodeJS.ProcessEnv = { ...env }\n for (const key of Object.keys(masked)) {\n if (/token|secret|password|pat|auth/i.test(key) && masked[key]) {\n masked[key] = '[redacted]'\n }\n }\n return masked\n}\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}\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] } = options\n\n if (dryRun) {\n logger?.info(`[dry-run] ${command} ${args.join(' ')}`, { cwd })\n return { status: 0, stdout: '', stderr: '' }\n }\n\n logger?.debug(`exec: ${command} ${args.join(' ')}`, {\n cwd,\n env: logger ? maskEnv(env) : undefined,\n })\n\n const spawnOpts: SpawnSyncOptions = {\n cwd,\n env,\n encoding: 'utf8',\n stdio: ['inherit', 'pipe', 'pipe'],\n }\n\n const result = spawnSync(command, 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 if (!okCodes.includes(status)) {\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 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","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"],"mappings":";;;AAAA,SAAS,iBAAwC;;;ACA1C,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;;;ADxBA,IAAM,iBAAiB;AAEvB,SAAS,QAAQ,KAA2C;AAC1D,QAAM,SAA4B,EAAE,GAAG,IAAI;AAC3C,aAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,QAAI,kCAAkC,KAAK,GAAG,KAAK,OAAO,GAAG,GAAG;AAC9D,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAYO,SAAS,WACd,SACA,MACA,SACoD;AACpD,QAAM,EAAE,KAAK,MAAM,QAAQ,KAAK,QAAQ,SAAS,OAAO,UAAU,CAAC,CAAC,EAAE,IAAI;AAE1E,MAAI,QAAQ;AACV,YAAQ,KAAK,aAAa,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC;AAC9D,WAAO,EAAE,QAAQ,GAAG,QAAQ,IAAI,QAAQ,GAAG;AAAA,EAC7C;AAEA,UAAQ,MAAM,SAAS,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI;AAAA,IAClD;AAAA,IACA,KAAK,SAAS,QAAQ,GAAG,IAAI;AAAA,EAC/B,CAAC;AAED,QAAM,YAA8B;AAAA,IAClC;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,EACnC;AAEA,QAAM,SAAS,UAAU,SAAS,MAAM,SAAS;AACjD,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AACnE,QAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAEnE,MAAI,CAAC,QAAQ,SAAS,MAAM,GAAG;AAC7B,UAAM,SAAS,OAAO,KAAK,KAAK,OAAO,KAAK,KAAK,QAAQ,MAAM;AAC/D,QAAI,eAAe,KAAK,MAAM,GAAG;AAC/B,YAAM,IAAI,UAAU,mBAAmB,OAAO,IAAI;AAAA,QAChD,UAAU,SAAS;AAAA,QACnB,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AACA,UAAM,IAAI,UAAU,mBAAmB,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,EAAK,MAAM,IAAI;AAAA,MAC7E,UAAU,SAAS;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,QAAQ,QAAQ,OAAO;AAClC;AAEO,SAAS,cACd,YACA,MACA,SACM;AACN,aAAW,QAAQ,UAAU,CAAC,YAAY,GAAG,IAAI,GAAG,OAAO;AAC7D;","names":[]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// src/lib/paths.ts
|
|
2
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
3
|
+
import { dirname, resolve as resolve2 } from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
|
|
6
|
+
// src/lib/config-files.ts
|
|
7
|
+
import { existsSync } from "fs";
|
|
8
|
+
import { resolve } from "path";
|
|
9
|
+
var WOODSCLI_CONFIG_FILE = "woodscli.json";
|
|
10
|
+
function envConfigPath(projectRoot) {
|
|
11
|
+
const fromEnv = process.env.WOODSCLI_CONFIG?.trim() || process.env.WP_HS_CONFIG?.trim() || null;
|
|
12
|
+
if (!fromEnv) return null;
|
|
13
|
+
return resolve(projectRoot, fromEnv);
|
|
14
|
+
}
|
|
15
|
+
function woodscliConfigPath(projectRoot) {
|
|
16
|
+
return resolve(projectRoot, WOODSCLI_CONFIG_FILE);
|
|
17
|
+
}
|
|
18
|
+
function resolveProjectConfig(projectRoot) {
|
|
19
|
+
const envPath = envConfigPath(projectRoot);
|
|
20
|
+
if (envPath) {
|
|
21
|
+
if (!existsSync(envPath)) return null;
|
|
22
|
+
return { path: envPath, fileName: WOODSCLI_CONFIG_FILE };
|
|
23
|
+
}
|
|
24
|
+
const path = woodscliConfigPath(projectRoot);
|
|
25
|
+
if (existsSync(path)) {
|
|
26
|
+
return { path, fileName: WOODSCLI_CONFIG_FILE };
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
function findProjectRoot(from = process.cwd()) {
|
|
31
|
+
if (process.env.WP_HS_PROJECT_ROOT?.trim()) {
|
|
32
|
+
return resolve(process.env.WP_HS_PROJECT_ROOT.trim());
|
|
33
|
+
}
|
|
34
|
+
let dir = resolve(from);
|
|
35
|
+
while (true) {
|
|
36
|
+
if (resolveProjectConfig(dir)) {
|
|
37
|
+
return dir;
|
|
38
|
+
}
|
|
39
|
+
const parent = resolve(dir, "..");
|
|
40
|
+
if (parent === dir) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
dir = parent;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/lib/errors.ts
|
|
48
|
+
var ExitCode = {
|
|
49
|
+
SUCCESS: 0,
|
|
50
|
+
USER_ERROR: 1,
|
|
51
|
+
PREREQUISITE: 2,
|
|
52
|
+
BUILD_FAILED: 3,
|
|
53
|
+
PUBLISH_FAILED: 4,
|
|
54
|
+
AUDIT_FAILED: 5,
|
|
55
|
+
INTERNAL: 10
|
|
56
|
+
};
|
|
57
|
+
var WpHsError = class extends Error {
|
|
58
|
+
exitCode;
|
|
59
|
+
remediation;
|
|
60
|
+
constructor(message, options = {}) {
|
|
61
|
+
super(message, { cause: options.cause });
|
|
62
|
+
this.name = "WpHsError";
|
|
63
|
+
this.exitCode = options.exitCode ?? ExitCode.USER_ERROR;
|
|
64
|
+
this.remediation = options.remediation;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// src/lib/paths.ts
|
|
69
|
+
var KIT_PACKAGE_NAME = "@woodsportal/hubspot-kit";
|
|
70
|
+
function resolveKitRoot() {
|
|
71
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
72
|
+
while (true) {
|
|
73
|
+
const pkgPath = resolve2(dir, "package.json");
|
|
74
|
+
if (existsSync2(pkgPath)) {
|
|
75
|
+
try {
|
|
76
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
77
|
+
if (pkg.name === KIT_PACKAGE_NAME) {
|
|
78
|
+
return dir;
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const parent = dirname(dir);
|
|
84
|
+
if (parent === dir) {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
dir = parent;
|
|
88
|
+
}
|
|
89
|
+
throw new WpHsError("Could not resolve @woodsportal/hubspot-kit package root.", {
|
|
90
|
+
exitCode: ExitCode.INTERNAL
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
var kitRoot = resolveKitRoot();
|
|
94
|
+
function getKitRoot() {
|
|
95
|
+
return kitRoot;
|
|
96
|
+
}
|
|
97
|
+
function findProjectRoot2(from = process.cwd()) {
|
|
98
|
+
const root = findProjectRoot(from);
|
|
99
|
+
if (!root) {
|
|
100
|
+
throw new WpHsError("Could not find woodscli.json in this directory or any parent.", {
|
|
101
|
+
exitCode: ExitCode.USER_ERROR,
|
|
102
|
+
remediation: "Run wp init, wp adopt, or pass --project <path>. Legacy config: wp migrate --yes."
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return root;
|
|
106
|
+
}
|
|
107
|
+
function kitPath(...segments) {
|
|
108
|
+
return resolve2(kitRoot, ...segments);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/vite/paths.ts
|
|
112
|
+
function getViteConfigPath(preset) {
|
|
113
|
+
return kitPath("vite", `vite.config.${preset}.mjs`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/vite/create-vite-config.ts
|
|
117
|
+
function createViteConfig(presetOrOptions) {
|
|
118
|
+
const options = typeof presetOrOptions === "string" ? { preset: presetOrOptions } : presetOrOptions;
|
|
119
|
+
if (options.projectRoot?.trim()) {
|
|
120
|
+
process.env.WP_HS_PROJECT_ROOT = options.projectRoot.trim();
|
|
121
|
+
}
|
|
122
|
+
return getViteConfigPath(options.preset);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
WOODSCLI_CONFIG_FILE,
|
|
127
|
+
resolveProjectConfig,
|
|
128
|
+
ExitCode,
|
|
129
|
+
WpHsError,
|
|
130
|
+
getKitRoot,
|
|
131
|
+
findProjectRoot2 as findProjectRoot,
|
|
132
|
+
kitPath,
|
|
133
|
+
getViteConfigPath,
|
|
134
|
+
createViteConfig
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=chunk-U4KFGTEW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/paths.ts","../src/lib/config-files.ts","../src/lib/errors.ts","../src/vite/paths.ts","../src/vite/create-vite-config.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { findProjectRoot as findConfigProjectRoot } from './config-files.js'\nimport { WpHsError, ExitCode } from './errors.js'\n\nconst KIT_PACKAGE_NAME = '@woodsportal/hubspot-kit'\n\nfunction resolveKitRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n while (true) {\n const pkgPath = resolve(dir, 'package.json')\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as { name?: string }\n if (pkg.name === KIT_PACKAGE_NAME) {\n return dir\n }\n } catch {\n // keep walking\n }\n }\n const parent = dirname(dir)\n if (parent === dir) {\n break\n }\n dir = parent\n }\n\n throw new WpHsError('Could not resolve @woodsportal/hubspot-kit package root.', {\n exitCode: ExitCode.INTERNAL,\n })\n}\n\nconst kitRoot = resolveKitRoot()\n\nexport function getKitRoot(): string {\n return kitRoot\n}\n\nexport function findProjectRoot(from = process.cwd()): string {\n const root = findConfigProjectRoot(from)\n if (!root) {\n throw new WpHsError('Could not find woodscli.json in this directory or any parent.', {\n exitCode: ExitCode.USER_ERROR,\n remediation: 'Run wp init, wp adopt, or pass --project <path>. Legacy config: wp migrate --yes.',\n })\n }\n return root\n}\n\nexport function kitPath(...segments: string[]): string {\n return resolve(kitRoot, ...segments)\n}\n\nexport { resolveProjectConfig, WOODSCLI_CONFIG_FILE, LEGACY_WOODSPORTAL_HS_FILE } from './config-files.js'\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\n/** Canonical WoodsCLI project config — the only supported filename. */\nexport const WOODSCLI_CONFIG_FILE = 'woodscli.json'\n\n/** Removed in v1.0.2+ — detected only for migrate/doctor messaging. */\nexport const LEGACY_WOODSPORTAL_HS_FILE = 'woodsportal.hs.json'\n\nexport type ResolvedProjectConfig = {\n path: string\n fileName: typeof WOODSCLI_CONFIG_FILE\n}\n\nfunction envConfigPath(projectRoot: string): string | null {\n const fromEnv = process.env.WOODSCLI_CONFIG?.trim() || process.env.WP_HS_CONFIG?.trim() || null\n if (!fromEnv) return null\n return resolve(projectRoot, fromEnv)\n}\n\nexport function legacyConfigPath(projectRoot: string): string {\n return resolve(projectRoot, LEGACY_WOODSPORTAL_HS_FILE)\n}\n\nexport function woodscliConfigPath(projectRoot: string): string {\n return resolve(projectRoot, WOODSCLI_CONFIG_FILE)\n}\n\n/** @returns null | 'legacy-only' | 'duplicate' */\nexport function legacyConfigConflict(projectRoot: string): 'legacy-only' | 'duplicate' | null {\n const hasWoodscli = existsSync(woodscliConfigPath(projectRoot))\n const hasLegacy = existsSync(legacyConfigPath(projectRoot))\n if (hasLegacy && hasWoodscli) return 'duplicate'\n if (hasLegacy && !hasWoodscli) return 'legacy-only'\n return null\n}\n\n/**\n * Resolve the active project config file (`woodscli.json` only).\n */\nexport function resolveProjectConfig(projectRoot: string): ResolvedProjectConfig | null {\n const envPath = envConfigPath(projectRoot)\n if (envPath) {\n if (!existsSync(envPath)) return null\n return { path: envPath, fileName: WOODSCLI_CONFIG_FILE }\n }\n\n const path = woodscliConfigPath(projectRoot)\n if (existsSync(path)) {\n return { path, fileName: WOODSCLI_CONFIG_FILE }\n }\n\n return null\n}\n\nexport function findProjectRoot(from = process.cwd()): string | null {\n if (process.env.WP_HS_PROJECT_ROOT?.trim()) {\n return resolve(process.env.WP_HS_PROJECT_ROOT.trim())\n }\n\n let dir = resolve(from)\n while (true) {\n if (resolveProjectConfig(dir)) {\n return dir\n }\n const parent = resolve(dir, '..')\n if (parent === dir) {\n return null\n }\n dir = parent\n }\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 { kitPath } from '../lib/paths.js'\n\nexport type VitePreset = 'dev' | 'hubspot' | 'cdn-vendor' | 'cdn-app' | 'cdn-esm'\n\nexport function getViteConfigPath(preset: VitePreset): string {\n return kitPath('vite', `vite.config.${preset}.mjs`)\n}\n","import { getViteConfigPath, type VitePreset } from './paths.js'\n\nexport type CreateViteConfigOptions = {\n /** Vite preset shipped with @woodsportal/hubspot-kit */\n preset: VitePreset\n /** Consumer project root (sets WP_HS_PROJECT_ROOT for kit scripts) */\n projectRoot?: string\n}\n\n/**\n * Returns the absolute path to a kit Vite config preset.\n * Consumer repos typically re-export: `export { default } from '@woodsportal/hubspot-kit/vite/vite.config.hubspot.mjs'`\n * or use this helper in a thin wrapper config.\n */\nexport function createViteConfig(\n presetOrOptions: VitePreset | CreateViteConfigOptions,\n): string {\n const options: CreateViteConfigOptions =\n typeof presetOrOptions === 'string' ? { preset: presetOrOptions } : presetOrOptions\n\n if (options.projectRoot?.trim()) {\n process.env.WP_HS_PROJECT_ROOT = options.projectRoot.trim()\n }\n\n return getViteConfigPath(options.preset)\n}\n"],"mappings":"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","names":["existsSync","resolve","resolve","existsSync","findProjectRoot"]}
|