@sfmc-bds/devkit 0.1.0-beta.2 → 1.0.0-beta.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/LICENSE +663 -0
- package/README.md +7 -8
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -3
- package/dist/index.js.map +4 -4
- package/package.json +13 -15
- package/dist/scaffold.d.ts +0 -14
- package/dist/scaffold.js +0 -55
- package/scripts/new-module.mjs +0 -659
package/README.md
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
# @sfmc-bds/devkit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
模块作者工具核心:Watch、重建部署、启停。供 VS Code/Cursor 扩展与脚本直接 import,**不**经 `sfmc` CLI。
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
import { startModuleWatch, rebuildAndDeploy, scaffoldModule } from "@sfmc-bds/devkit";
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
脚手架 CLI:
|
|
5
|
+
建仓请用:
|
|
10
6
|
|
|
11
7
|
```bash
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
npm create @sfmc-bds/module@latest
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { startModuleWatch, rebuildAndDeploy, setModuleEnabled } from "@sfmc-bds/devkit";
|
|
14
13
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @sfmc-bds/devkit — 模块作者工具核心(扩展 / CI 共用)
|
|
3
|
-
* Watch /
|
|
3
|
+
* Watch / rebuild / 启停;建仓请用 @sfmc-bds/create-module(npm create @sfmc-bds/module)。
|
|
4
4
|
*/
|
|
5
5
|
export { resolveLocalModuleRoot } from "./paths.js";
|
|
6
6
|
export { isValidModuleRoot, readModuleRootInfo, findModuleRootFromFile, type ModuleRootInfo, } from "./module-root.js";
|
|
7
7
|
export { isValidSfmcRoot } from "./sfmc-root.js";
|
|
8
|
-
export { resolveSfmcCli, type ResolveSfmcCliOptions } from "./sfmc-cli.js";
|
|
8
|
+
export { resolveSfmcCli, runSfmcCli, type ResolveSfmcCliOptions, type RunSfmcCliOptions, type RunSfmcCliResult } from "./sfmc-cli.js";
|
|
9
9
|
export { startModuleWatch, type ModuleWatchOptions } from "./watch.js";
|
|
10
|
-
export { scaffoldModule, type ScaffoldOptions } from "./scaffold.js";
|
|
11
10
|
export { rebuildAndDeploy, type RebuildOptions, type RebuildResult } from "./rebuild.js";
|
|
12
11
|
export { setModuleEnabled, type SetModuleEnabledOptions, type SetModuleEnabledResult, } from "./module-toggle.js";
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @sfmc-bds/devkit — 模块作者工具核心(扩展 / CI 共用)
|
|
3
|
-
* Watch /
|
|
3
|
+
* Watch / rebuild / 启停;建仓请用 @sfmc-bds/create-module(npm create @sfmc-bds/module)。
|
|
4
4
|
*/
|
|
5
5
|
export { resolveLocalModuleRoot } from "./paths.js";
|
|
6
6
|
export { isValidModuleRoot, readModuleRootInfo, findModuleRootFromFile, } from "./module-root.js";
|
|
7
7
|
export { isValidSfmcRoot } from "./sfmc-root.js";
|
|
8
|
-
export { resolveSfmcCli } from "./sfmc-cli.js";
|
|
8
|
+
export { resolveSfmcCli, runSfmcCli } from "./sfmc-cli.js";
|
|
9
9
|
export { startModuleWatch } from "./watch.js";
|
|
10
|
-
export { scaffoldModule } from "./scaffold.js";
|
|
11
10
|
export { rebuildAndDeploy } from "./rebuild.js";
|
|
12
11
|
export { setModuleEnabled, } from "./module-toggle.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/paths.ts", "../src/module-root.ts", "../src/sfmc-root.ts", "../src/sfmc-cli.ts", "../src/watch.ts", "../src/
|
|
4
|
-
"sourcesContent": ["import path from \"node:path\";\n\n/** \u89E3\u6790 `--from local[:path]` / `dir:` \u6216 cwd \u4E3A\u6A21\u5757\u6839\u3002 */\nexport function resolveLocalModuleRoot(args: { from?: string | null; cwd: string }): string {\n const raw = (args.from ?? \"\").trim();\n if (!raw) return path.resolve(args.cwd);\n if (raw === \"local\") return path.resolve(args.cwd);\n if (raw.startsWith(\"local:\")) {\n const p = raw.slice(\"local:\".length).trim();\n if (!p) return path.resolve(args.cwd);\n return path.isAbsolute(p) ? path.resolve(p) : path.resolve(args.cwd, p);\n }\n if (raw.startsWith(\"dir:\")) {\n const p = raw.slice(\"dir:\".length).trim();\n return path.isAbsolute(p) ? path.resolve(p) : path.resolve(args.cwd, p);\n }\n return path.resolve(args.cwd);\n}\n", "/**\n * \u6709\u6548\u6A21\u5757\u6839\u5224\u5B9A\uFF08\u6269\u5C55\u4E0E CLI \u5171\u7528\u6743\u5A01\uFF09\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport type ModuleRootInfo = {\n root: string;\n id: string;\n name?: string;\n schemaVersion: number;\n};\n\n/** \u76EE\u5F55\u662F\u5426\u4E3A\u6709\u6548 SFMC \u6A21\u5757\u6839\uFF1Apackage.json + sapi/manifest.json schemaVersion===2 + \u975E\u7A7A id */\nexport function isValidModuleRoot(dir: string): boolean {\n return readModuleRootInfo(dir) !== null;\n}\n\nexport function readModuleRootInfo(dir: string): ModuleRootInfo | null {\n const pkg = path.join(dir, \"package.json\");\n const manifestPath = path.join(dir, \"sapi\", \"manifest.json\");\n if (!fs.existsSync(pkg) || !fs.existsSync(manifestPath)) return null;\n try {\n const m = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as {\n schemaVersion?: number;\n id?: string;\n name?: string;\n };\n if (m.schemaVersion !== 2) return null;\n if (typeof m.id !== \"string\" || !m.id.trim()) return null;\n return {\n root: path.resolve(dir),\n id: m.id.trim(),\n name: typeof m.name === \"string\" ? m.name : undefined,\n schemaVersion: 2,\n };\n } catch {\n return null;\n }\n}\n\n/** \u81EA filePath \u5411\u4E0A\u627E\u6700\u8FD1\u6709\u6548\u6A21\u5757\u6839\uFF1B\u627E\u4E0D\u5230\u8FD4\u56DE null */\nexport function findModuleRootFromFile(filePath: string): string | null {\n let cur = path.dirname(path.resolve(filePath));\n const root = path.parse(cur).root;\n while (true) {\n if (isValidModuleRoot(cur)) return cur;\n if (cur === root) return null;\n const parent = path.dirname(cur);\n if (parent === cur) return null;\n cur = parent;\n }\n}\n", "/**\n * SFMC \u5DE5\u4F5C\u76EE\u5F55\u5224\u5B9A\uFF08\u8FD0\u884C\u65F6\u6839\uFF1Aconfigs/\u3001modules/\uFF1B\u4E0D\u662F\u6E90\u7801\u4ED3\u5E93\u6839\uFF09\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\n/** \u76EE\u5F55\u662F\u5426\u4E3A\u6709\u6548 SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF08\u542B configs/ \u4E0E modules/\uFF09\u3002 */\nexport function isValidSfmcRoot(dir: string): boolean {\n if (!dir || !dir.trim()) return false;\n const root = path.resolve(dir);\n try {\n return (\n fs.statSync(path.join(root, \"configs\")).isDirectory() &&\n fs.statSync(path.join(root, \"modules\")).isDirectory()\n );\n } catch {\n return false;\n }\n}\n", "/**\n * \u89E3\u6790\u5E76 spawn sfmc CLI\u3002\n * CLI \u4E0E SFMC \u5DE5\u4F5C\u76EE\u5F55\u65E0\u5173\uFF1A\u4ECE\u672C\u5305/\u6269\u5C55\u5B89\u88C5\u6811\u3001PATH \u6216\u663E\u5F0F\u914D\u7F6E\u89E3\u6790\uFF1B\n * \u5DE5\u4F5C\u76EE\u5F55\u53EA\u4F5C\u4E3A spawn \u7684 cwd \u4E0E SFMC_ROOT\u3002\n */\n\nimport { spawn } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { isValidSfmcRoot } from \"./sfmc-root.js\";\n\n/** chalk.hex(\"#e06c75\") \u7684\u771F\u5F69\u5E8F\u5217\uFF1BCLI \u5931\u8D25\u6587\u6848\u7ECF c.red() \u5305\u88C5\u3002 */\nconst CLI_ANSI_RED = \"\\u001b[38;2;224;108;117m\";\n\nexport interface ResolveSfmcCliOptions {\n /** \u663E\u5F0F CLI \u5165\u53E3\uFF08.js/.mjs\uFF09\uFF1B\u4E5F\u53EF\u7528\u73AF\u5883\u53D8\u91CF SFMC_CLI\u3002 */\n cliPath?: string;\n}\n\nfunction tryRequireCli(from: string): string | null {\n try {\n const resolved = createRequire(from).resolve(\"@sfmc-bds/cli/cli\");\n return fs.existsSync(resolved) ? resolved : null;\n } catch {\n return null;\n }\n}\n\n/** \u81EA PATH \u4E0A\u7684 sfmc \u53EF\u6267\u884C\u6587\u4EF6\u65C1\u89E3\u6790 @sfmc-bds/cli\uFF08npm global / \u672C\u5730 .bin\uFF09\u3002 */\nfunction resolveCliFromPathEnv(): string | null {\n const pathEnv = process.env.PATH ?? \"\";\n const names =\n process.platform === \"win32\" ? [\"sfmc.cmd\", \"sfmc.exe\", \"sfmc.ps1\", \"sfmc\"] : [\"sfmc\"];\n for (const dir of pathEnv.split(path.delimiter)) {\n if (!dir) continue;\n let hit = false;\n for (const name of names) {\n if (fs.existsSync(path.join(dir, name))) {\n hit = true;\n break;\n }\n }\n if (!hit) continue;\n const nearCli = path.join(dir, \"..\", \"@sfmc-bds\", \"cli\", \"dist\", \"main.js\");\n if (fs.existsSync(nearCli)) return nearCli;\n const nearMeta = path.join(dir, \"..\", \"@sfmc-bds\", \"sfmc\", \"bin\", \"sfmc.mjs\");\n if (fs.existsSync(nearMeta)) return nearMeta;\n const fromBin = tryRequireCli(path.join(dir, \"..\", \"package.json\"));\n if (fromBin) return fromBin;\n }\n return null;\n}\n\n/**\n * \u89E3\u6790 sfmc CLI \u811A\u672C\u8DEF\u5F84\u3002\n * \u987A\u5E8F\uFF1A\u663E\u5F0F cliPath / SFMC_CLI \u2192 \u672C\u5305\u5B89\u88C5\u6811\uFF08@sfmc-bds/cli\uFF09\u2192 cwd \u7684 node_modules \u2192 PATH\u3002\n */\nexport function resolveSfmcCli(opts: ResolveSfmcCliOptions = {}): string {\n const explicit = (opts.cliPath || process.env.SFMC_CLI || \"\").trim();\n if (explicit) {\n const p = path.resolve(explicit);\n if (!fs.existsSync(p)) {\n throw new Error(`\u6307\u5B9A\u7684 sfmc CLI \u4E0D\u5B58\u5728\uFF1A${p}\uFF08\u68C0\u67E5 SFMC_CLI / sfmc.cliPath\uFF09`);\n }\n return p;\n }\n\n const here = fileURLToPath(import.meta.url);\n const fromInstall = tryRequireCli(here);\n if (fromInstall) return fromInstall;\n\n const fromCwd = tryRequireCli(path.join(process.cwd(), \"package.json\"));\n if (fromCwd) return fromCwd;\n\n const fromPath = resolveCliFromPathEnv();\n if (fromPath) return fromPath;\n\n throw new Error(\n \"\u65E0\u6CD5\u89E3\u6790 sfmc CLI\u3002\u8BF7\u5B89\u88C5 @sfmc-bds/cli\uFF08\u6216\u786E\u4FDD PATH \u4E0A\u6709 sfmc\uFF09\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF SFMC_CLI / \u6269\u5C55\u914D\u7F6E sfmc.cliPath\u3002\"\n );\n}\n\nfunction looksLikeCliFailure(output: string): boolean {\n if (output.includes(CLI_ANSI_RED)) return true;\n if (/\\[pack-manager\\].*required/.test(output)) return true;\n if (/^Error:/m.test(output)) return true;\n return false;\n}\n\nexport interface RunSfmcCliResult {\n ok: boolean;\n output: string;\n}\n\nexport interface RunSfmcCliOptions {\n cliPath?: string;\n}\n\n/** \u5728 SFMC \u5DE5\u4F5C\u76EE\u5F55\u4E0B\u6267\u884C `node <sfmc-cli> ...args`\uFF08env.SFMC_ROOT = \u5DE5\u4F5C\u76EE\u5F55\uFF09\u3002 */\nexport async function runSfmcCli(\n sfmcRoot: string,\n args: string[],\n opts: RunSfmcCliOptions = {}\n): Promise<RunSfmcCliResult> {\n const root = path.resolve(sfmcRoot);\n if (!isValidSfmcRoot(root)) {\n return {\n ok: false,\n output: `\u65E0\u6548\u7684 SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF1A${root}\uFF08\u9700\u8981\u542B configs/ \u4E0E modules/\uFF0C\u4E0D\u5FC5\u542B\u6E90\u7801\u4ED3\u5E93\uFF09`,\n };\n }\n\n let script: string;\n try {\n script = resolveSfmcCli({ cliPath: opts.cliPath });\n } catch (e) {\n return { ok: false, output: e instanceof Error ? e.message : String(e) };\n }\n\n const r = await new Promise<{ code: number | null; output: string }>((resolve) => {\n const proc = spawn(process.execPath, [script, ...args], {\n cwd: root,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: root },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => resolve({ code, output: out }));\n proc.on(\"error\", (e) => resolve({ code: 1, output: e.message }));\n });\n\n const ok = r.code === 0 && !looksLikeCliFailure(r.output);\n return { ok, output: r.output };\n}\n", "/**\n * \u76D1\u542C\u6A21\u5757 sapi/src\uFF0C\u9632\u6296\u540E\u56DE\u8C03 onRebuild\uFF08\u7531\u8C03\u7528\u65B9\u6CE8\u5165 rebuildAndDeploy / \u5176\u5B83\uFF09\u3002\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport interface ModuleWatchOptions {\n moduleRoot: string;\n debounceMs?: number;\n log?: (line: string) => void;\n onRebuild: () => Promise<{ ok: boolean; message?: string }>;\n}\n\nexport function startModuleWatch(opts: ModuleWatchOptions): { stop: () => void } {\n const log = opts.log ?? ((line: string) => console.log(line));\n const debounceMs = opts.debounceMs ?? 200;\n const sapiDir = path.join(opts.moduleRoot, \"sapi\");\n const srcDir = path.join(sapiDir, \"src\");\n\n if (!fs.existsSync(sapiDir)) {\n log(`[devkit:watch] \u65E0 sapi \u76EE\u5F55: ${sapiDir}`);\n return { stop: () => {} };\n }\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let pending = new Set<string>();\n let running = false;\n let stopped = false;\n\n log(`[devkit:watch] \u76D1\u542C ${opts.moduleRoot}`);\n\n const runOnce = async () => {\n if (running || stopped) return;\n running = true;\n const changed = [...pending];\n pending = new Set();\n const t0 = Date.now();\n log(`[devkit:watch] rebuild (${changed.length})\u2026`);\n try {\n const r = await opts.onRebuild();\n const ms = Date.now() - t0;\n if (r.ok) log(`[devkit:watch] ok ${ms}ms`);\n else log(`[devkit:watch] fail ${ms}ms ${r.message ?? \"\"}`);\n } catch (e) {\n log(`[devkit:watch] error ${(e as Error).message}`);\n } finally {\n running = false;\n }\n };\n\n const onSrc = (rel: string) => {\n if (stopped) return;\n if (rel.includes(\"node_modules\") || rel.includes(\"dist\") || rel.endsWith(\".tgz\")) return;\n pending.add(rel);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => void runOnce(), debounceMs);\n };\n\n const watchers: fs.FSWatcher[] = [];\n if (fs.existsSync(srcDir)) {\n try {\n watchers.push(\n fs.watch(srcDir, { recursive: true, persistent: true }, (_e, filename) => {\n if (filename) onSrc(filename.toString());\n })\n );\n } catch {\n watchers.push(\n fs.watch(srcDir, { persistent: true }, (_e, filename) => {\n if (filename) onSrc(filename.toString());\n })\n );\n }\n }\n\n const watchMeta = (file: string, kind: string) => {\n if (!fs.existsSync(file)) return;\n watchers.push(\n fs.watch(file, { persistent: true }, (event) => {\n if (event === \"change\") log(`[devkit:watch] ${kind} \u5DF2\u6539\uFF0C\u9700\u91CD\u542F BDS\uFF08SAPI \u542F\u52A8\u671F\u7F13\u5B58\uFF09`);\n })\n );\n };\n watchMeta(path.join(sapiDir, \"manifest.json\"), \"manifest\");\n watchMeta(path.join(sapiDir, \"tsconfig.json\"), \"tsconfig\");\n\n return {\n stop() {\n stopped = true;\n if (debounceTimer) clearTimeout(debounceTimer);\n for (const w of watchers) {\n try {\n w.close();\n } catch {\n /* ignore */\n }\n }\n log(\"[devkit:watch] stopped\");\n },\n };\n}\n", "/**\n * \u811A\u624B\u67B6\uFF1A\u59D4\u6258 @sfmc-bds/devkit/scripts/new-module.mjs\u3002\n */\n\nimport { spawn } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { findMonorepoRoot } from \"@sfmc-bds/sdk/node/config\";\n\nexport interface ScaffoldOptions {\n /** \u76EE\u6807\u76EE\u5F55\uFF08\u987B\u4E3A\u7A7A\u6216\u53EF\u521B\u5EFA\uFF09\u3002 */\n targetDir: string;\n moduleId: string;\n displayName?: string;\n official?: boolean;\n}\n\nfunction resolveNewModuleScript(): string {\n const require = createRequire(import.meta.url);\n try {\n return require.resolve(\"@sfmc-bds/devkit/new-module.mjs\");\n } catch {\n /* monorepo \u56DE\u9000 */\n }\n const monoRoot = findMonorepoRoot(process.cwd());\n const mono = monoRoot\n ? path.join(monoRoot, \"packages\", \"devkit\", \"scripts\", \"new-module.mjs\")\n : path.resolve(process.cwd(), \"packages/devkit/scripts/new-module.mjs\");\n if (fs.existsSync(mono)) return mono;\n throw new Error(\"\u65E0\u6CD5\u89E3\u6790 new-module.mjs\uFF08\u5B89\u88C5 @sfmc-bds/devkit \u6216\u5728 monorepo \u6839\u8FD0\u884C\uFF09\");\n}\n\nexport async function scaffoldModule(opts: ScaffoldOptions): Promise<{ ok: boolean; message: string }> {\n const dir = path.resolve(opts.targetDir);\n fs.mkdirSync(dir, { recursive: true });\n const script = resolveNewModuleScript();\n const args = [script, opts.moduleId];\n if (opts.displayName) args.push(\"--name\", opts.displayName);\n if (opts.official) args.push(\"--official\");\n\n return new Promise((resolve) => {\n const proc = spawn(process.execPath, args, {\n cwd: dir,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: process.env,\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve({\n ok: code === 0,\n message: out.trim() || (code === 0 ? `scaffolded ${opts.moduleId}` : `exit ${code}`),\n });\n });\n proc.on(\"error\", (e) => resolve({ ok: false, message: e.message }));\n });\n}\n", "/**\n * \u7EC4\u88C5\u5E76\u90E8\u7F72\u884C\u4E3A\u5305\uFF1A\u5728 SFMC_ROOT \u4E0B spawn `sfmc mod reload`\n * \uFF08\u4E0E CLI \u540C\u4E00\u5165\u53E3\uFF0C\u5B8C\u6574\u4F20\u53C2\uFF1B\u52FF\u76F4\u63A5\u88F8\u8C03 pack-manager verb\uFF09\u3002\n */\n\nimport { runSfmcCli } from \"./sfmc-cli.js\";\n\nexport interface RebuildOptions {\n /** SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF08\u542B configs/\u3001modules/\uFF09\u3002 */\n sfmcRoot: string;\n /** \u4EC5\u6784\u5EFA\u90E8\u7F72\uFF0C\u4E0D\u5411 BDS \u53D1 reload\uFF08\u5BF9\u5E94 `mod reload --build-only`\uFF09\u3002 */\n buildOnly?: boolean;\n /** \u53EF\u9009\uFF1A\u663E\u5F0F sfmc CLI \u5165\u53E3\uFF1B\u9ED8\u8BA4\u7531\u5B89\u88C5\u6811 / PATH / SFMC_CLI \u89E3\u6790\u3002 */\n cliPath?: string;\n}\n\nexport interface RebuildResult {\n ok: boolean;\n output: string;\n}\n\nexport async function rebuildAndDeploy(opts: RebuildOptions): Promise<RebuildResult> {\n const args = [\"mod\", \"reload\"];\n if (opts.buildOnly) args.push(\"--build-only\");\n return runSfmcCli(opts.sfmcRoot, args, { cliPath: opts.cliPath });\n}\n", "/**\n * \u6A21\u5757\u542F\u505C\uFF1Aspawn `sfmc mod enable|disable`\uFF08\u5199 module-lock + best-effort \u70ED\u540C\u6B65\uFF09\u3002\n */\n\nimport { runSfmcCli, type RunSfmcCliResult } from \"./sfmc-cli.js\";\n\nexport interface SetModuleEnabledOptions {\n /** SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF08\u542B modules/module-lock.json\uFF09\u3002 */\n sfmcRoot: string;\n /** \u6A21\u5757 logicalId / folderId / configKey\uFF08\u4E0E CLI `mod enable` \u4E00\u81F4\uFF09\u3002 */\n moduleId: string;\n enabled: boolean;\n /** \u53EF\u9009\uFF1A\u663E\u5F0F sfmc CLI \u5165\u53E3\uFF1B\u9ED8\u8BA4\u7531\u5B89\u88C5\u6811 / PATH / SFMC_CLI \u89E3\u6790\u3002 */\n cliPath?: string;\n}\n\nexport type SetModuleEnabledResult = RunSfmcCliResult;\n\n/** \u542F\u7528\u6216\u5173\u95ED\u6A21\u5757\uFF08\u4E0E CLI `mod enable|disable` \u540C\u6E90\uFF09\u3002 */\nexport async function setModuleEnabled(opts: SetModuleEnabledOptions): Promise<SetModuleEnabledResult> {\n const id = String(opts.moduleId || \"\").trim();\n if (!id) {\n return { ok: false, output: \"moduleId \u4E3A\u7A7A\" };\n }\n const action = opts.enabled ? \"enable\" : \"disable\";\n return runSfmcCli(opts.sfmcRoot, [\"mod\", action, id], { cliPath: opts.cliPath });\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
6
|
-
"names": ["path", "fs", "path", "fs", "path", "fs", "path", "fs", "path"
|
|
3
|
+
"sources": ["../src/paths.ts", "../src/module-root.ts", "../src/sfmc-root.ts", "../src/sfmc-cli.ts", "../src/watch.ts", "../src/rebuild.ts", "../src/module-toggle.ts"],
|
|
4
|
+
"sourcesContent": ["import path from \"node:path\";\n\n/** \u89E3\u6790 `--from local[:path]` / `dir:` \u6216 cwd \u4E3A\u6A21\u5757\u6839\u3002 */\nexport function resolveLocalModuleRoot(args: { from?: string | null; cwd: string }): string {\n const raw = (args.from ?? \"\").trim();\n if (!raw) return path.resolve(args.cwd);\n if (raw === \"local\") return path.resolve(args.cwd);\n if (raw.startsWith(\"local:\")) {\n const p = raw.slice(\"local:\".length).trim();\n if (!p) return path.resolve(args.cwd);\n return path.isAbsolute(p) ? path.resolve(p) : path.resolve(args.cwd, p);\n }\n if (raw.startsWith(\"dir:\")) {\n const p = raw.slice(\"dir:\".length).trim();\n return path.isAbsolute(p) ? path.resolve(p) : path.resolve(args.cwd, p);\n }\n return path.resolve(args.cwd);\n}\n", "/**\n * \u6709\u6548\u6A21\u5757\u6839\u5224\u5B9A\uFF08\u6269\u5C55\u4E0E CLI \u5171\u7528\u6743\u5A01\uFF09\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport type ModuleRootInfo = {\n root: string;\n id: string;\n name?: string;\n schemaVersion: number;\n};\n\n/** \u76EE\u5F55\u662F\u5426\u4E3A\u6709\u6548 SFMC \u6A21\u5757\u6839\uFF1Apackage.json + sapi/manifest.json schemaVersion===2 + \u975E\u7A7A id */\nexport function isValidModuleRoot(dir: string): boolean {\n return readModuleRootInfo(dir) !== null;\n}\n\nexport function readModuleRootInfo(dir: string): ModuleRootInfo | null {\n const pkg = path.join(dir, \"package.json\");\n const manifestPath = path.join(dir, \"sapi\", \"manifest.json\");\n if (!fs.existsSync(pkg) || !fs.existsSync(manifestPath)) return null;\n try {\n const m = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as {\n schemaVersion?: number;\n id?: string;\n name?: string;\n };\n if (m.schemaVersion !== 2) return null;\n if (typeof m.id !== \"string\" || !m.id.trim()) return null;\n return {\n root: path.resolve(dir),\n id: m.id.trim(),\n name: typeof m.name === \"string\" ? m.name : undefined,\n schemaVersion: 2,\n };\n } catch {\n return null;\n }\n}\n\n/** \u81EA filePath \u5411\u4E0A\u627E\u6700\u8FD1\u6709\u6548\u6A21\u5757\u6839\uFF1B\u627E\u4E0D\u5230\u8FD4\u56DE null */\nexport function findModuleRootFromFile(filePath: string): string | null {\n let cur = path.dirname(path.resolve(filePath));\n const root = path.parse(cur).root;\n while (true) {\n if (isValidModuleRoot(cur)) return cur;\n if (cur === root) return null;\n const parent = path.dirname(cur);\n if (parent === cur) return null;\n cur = parent;\n }\n}\n", "/**\n * SFMC \u5DE5\u4F5C\u76EE\u5F55\u5224\u5B9A\uFF08\u8FD0\u884C\u65F6\u6839\uFF1Aconfigs/\u3001modules/\uFF1B\u4E0D\u662F\u6E90\u7801\u4ED3\u5E93\u6839\uFF09\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\n/** \u76EE\u5F55\u662F\u5426\u4E3A\u6709\u6548 SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF08\u542B configs/ \u4E0E modules/\uFF09\u3002 */\nexport function isValidSfmcRoot(dir: string): boolean {\n if (!dir || !dir.trim()) return false;\n const root = path.resolve(dir);\n try {\n return (\n fs.statSync(path.join(root, \"configs\")).isDirectory() &&\n fs.statSync(path.join(root, \"modules\")).isDirectory()\n );\n } catch {\n return false;\n }\n}\n", "/**\n * \u89E3\u6790\u5E76 spawn sfmc CLI\u3002\n * CLI \u4E0E SFMC \u5DE5\u4F5C\u76EE\u5F55\u65E0\u5173\uFF1A\u4ECE\u672C\u5305/\u6269\u5C55\u5B89\u88C5\u6811\u3001PATH \u6216\u663E\u5F0F\u914D\u7F6E\u89E3\u6790\uFF1B\n * \u5DE5\u4F5C\u76EE\u5F55\u53EA\u4F5C\u4E3A spawn \u7684 cwd \u4E0E SFMC_ROOT\u3002\n */\n\nimport { spawn } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { isValidSfmcRoot } from \"./sfmc-root.js\";\n\n/** chalk.hex(\"#e06c75\") \u7684\u771F\u5F69\u5E8F\u5217\uFF1BCLI \u5931\u8D25\u6587\u6848\u7ECF c.red() \u5305\u88C5\u3002 */\nconst CLI_ANSI_RED = \"\\u001b[38;2;224;108;117m\";\n\nexport interface ResolveSfmcCliOptions {\n /** \u663E\u5F0F CLI \u5165\u53E3\uFF08.js/.mjs\uFF09\uFF1B\u4E5F\u53EF\u7528\u73AF\u5883\u53D8\u91CF SFMC_CLI\u3002 */\n cliPath?: string;\n}\n\nfunction tryRequireCli(from: string): string | null {\n try {\n const resolved = createRequire(from).resolve(\"@sfmc-bds/cli/cli\");\n return fs.existsSync(resolved) ? resolved : null;\n } catch {\n return null;\n }\n}\n\n/** \u81EA PATH \u4E0A\u7684 sfmc \u53EF\u6267\u884C\u6587\u4EF6\u65C1\u89E3\u6790 @sfmc-bds/cli\uFF08npm global / \u672C\u5730 .bin\uFF09\u3002 */\nfunction resolveCliFromPathEnv(): string | null {\n const pathEnv = process.env.PATH ?? \"\";\n const names =\n process.platform === \"win32\" ? [\"sfmc.cmd\", \"sfmc.exe\", \"sfmc.ps1\", \"sfmc\"] : [\"sfmc\"];\n for (const dir of pathEnv.split(path.delimiter)) {\n if (!dir) continue;\n let hit = false;\n for (const name of names) {\n if (fs.existsSync(path.join(dir, name))) {\n hit = true;\n break;\n }\n }\n if (!hit) continue;\n const nearCli = path.join(dir, \"..\", \"@sfmc-bds\", \"cli\", \"dist\", \"main.js\");\n if (fs.existsSync(nearCli)) return nearCli;\n const nearMeta = path.join(dir, \"..\", \"@sfmc-bds\", \"sfmc\", \"bin\", \"sfmc.mjs\");\n if (fs.existsSync(nearMeta)) return nearMeta;\n const fromBin = tryRequireCli(path.join(dir, \"..\", \"package.json\"));\n if (fromBin) return fromBin;\n }\n return null;\n}\n\n/**\n * \u89E3\u6790 sfmc CLI \u811A\u672C\u8DEF\u5F84\u3002\n * \u987A\u5E8F\uFF1A\u663E\u5F0F cliPath / SFMC_CLI \u2192 \u672C\u5305\u5B89\u88C5\u6811\uFF08@sfmc-bds/cli\uFF09\u2192 cwd \u7684 node_modules \u2192 PATH\u3002\n */\nexport function resolveSfmcCli(opts: ResolveSfmcCliOptions = {}): string {\n const explicit = (opts.cliPath || process.env.SFMC_CLI || \"\").trim();\n if (explicit) {\n const p = path.resolve(explicit);\n if (!fs.existsSync(p)) {\n throw new Error(`\u6307\u5B9A\u7684 sfmc CLI \u4E0D\u5B58\u5728\uFF1A${p}\uFF08\u68C0\u67E5 SFMC_CLI / sfmc.cliPath\uFF09`);\n }\n return p;\n }\n\n const here = fileURLToPath(import.meta.url);\n const fromInstall = tryRequireCli(here);\n if (fromInstall) return fromInstall;\n\n const fromCwd = tryRequireCli(path.join(process.cwd(), \"package.json\"));\n if (fromCwd) return fromCwd;\n\n const fromPath = resolveCliFromPathEnv();\n if (fromPath) return fromPath;\n\n throw new Error(\n \"\u65E0\u6CD5\u89E3\u6790 sfmc CLI\u3002\u8BF7\u5B89\u88C5 @sfmc-bds/cli\uFF08\u6216\u786E\u4FDD PATH \u4E0A\u6709 sfmc\uFF09\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF SFMC_CLI / \u6269\u5C55\u914D\u7F6E sfmc.cliPath\u3002\"\n );\n}\n\nfunction looksLikeCliFailure(output: string): boolean {\n if (output.includes(CLI_ANSI_RED)) return true;\n if (/\\[pack-manager\\].*required/.test(output)) return true;\n if (/^Error:/m.test(output)) return true;\n return false;\n}\n\nexport interface RunSfmcCliResult {\n ok: boolean;\n output: string;\n}\n\nexport interface RunSfmcCliOptions {\n cliPath?: string;\n}\n\n/** \u5728 SFMC \u5DE5\u4F5C\u76EE\u5F55\u4E0B\u6267\u884C `node <sfmc-cli> ...args`\uFF08env.SFMC_ROOT = \u5DE5\u4F5C\u76EE\u5F55\uFF09\u3002 */\nexport async function runSfmcCli(\n sfmcRoot: string,\n args: string[],\n opts: RunSfmcCliOptions = {}\n): Promise<RunSfmcCliResult> {\n const root = path.resolve(sfmcRoot);\n if (!isValidSfmcRoot(root)) {\n return {\n ok: false,\n output: `\u65E0\u6548\u7684 SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF1A${root}\uFF08\u9700\u8981\u542B configs/ \u4E0E modules/\uFF0C\u4E0D\u5FC5\u542B\u6E90\u7801\u4ED3\u5E93\uFF09`,\n };\n }\n\n let script: string;\n try {\n script = resolveSfmcCli({ cliPath: opts.cliPath });\n } catch (e) {\n return { ok: false, output: e instanceof Error ? e.message : String(e) };\n }\n\n const r = await new Promise<{ code: number | null; output: string }>((resolve) => {\n const proc = spawn(process.execPath, [script, ...args], {\n cwd: root,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: root },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => resolve({ code, output: out }));\n proc.on(\"error\", (e) => resolve({ code: 1, output: e.message }));\n });\n\n const ok = r.code === 0 && !looksLikeCliFailure(r.output);\n return { ok, output: r.output };\n}\n", "/**\n * \u76D1\u542C\u6A21\u5757 sapi/src\uFF0C\u9632\u6296\u540E\u56DE\u8C03 onRebuild\uFF08\u7531\u8C03\u7528\u65B9\u6CE8\u5165 rebuildAndDeploy / \u5176\u5B83\uFF09\u3002\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport interface ModuleWatchOptions {\n moduleRoot: string;\n debounceMs?: number;\n log?: (line: string) => void;\n onRebuild: () => Promise<{ ok: boolean; message?: string }>;\n}\n\nexport function startModuleWatch(opts: ModuleWatchOptions): { stop: () => void } {\n const log = opts.log ?? ((line: string) => console.log(line));\n const debounceMs = opts.debounceMs ?? 200;\n const sapiDir = path.join(opts.moduleRoot, \"sapi\");\n const srcDir = path.join(sapiDir, \"src\");\n\n if (!fs.existsSync(sapiDir)) {\n log(`[devkit:watch] \u65E0 sapi \u76EE\u5F55: ${sapiDir}`);\n return { stop: () => {} };\n }\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let pending = new Set<string>();\n let running = false;\n let stopped = false;\n\n log(`[devkit:watch] \u76D1\u542C ${opts.moduleRoot}`);\n\n const runOnce = async () => {\n if (running || stopped) return;\n running = true;\n const changed = [...pending];\n pending = new Set();\n const t0 = Date.now();\n log(`[devkit:watch] rebuild (${changed.length})\u2026`);\n try {\n const r = await opts.onRebuild();\n const ms = Date.now() - t0;\n if (r.ok) log(`[devkit:watch] ok ${ms}ms`);\n else log(`[devkit:watch] fail ${ms}ms ${r.message ?? \"\"}`);\n } catch (e) {\n log(`[devkit:watch] error ${(e as Error).message}`);\n } finally {\n running = false;\n }\n };\n\n const onSrc = (rel: string) => {\n if (stopped) return;\n if (rel.includes(\"node_modules\") || rel.includes(\"dist\") || rel.endsWith(\".tgz\")) return;\n pending.add(rel);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => void runOnce(), debounceMs);\n };\n\n const watchers: fs.FSWatcher[] = [];\n if (fs.existsSync(srcDir)) {\n try {\n watchers.push(\n fs.watch(srcDir, { recursive: true, persistent: true }, (_e, filename) => {\n if (filename) onSrc(filename.toString());\n })\n );\n } catch {\n watchers.push(\n fs.watch(srcDir, { persistent: true }, (_e, filename) => {\n if (filename) onSrc(filename.toString());\n })\n );\n }\n }\n\n const watchMeta = (file: string, kind: string) => {\n if (!fs.existsSync(file)) return;\n watchers.push(\n fs.watch(file, { persistent: true }, (event) => {\n if (event === \"change\") log(`[devkit:watch] ${kind} \u5DF2\u6539\uFF0C\u9700\u91CD\u542F BDS\uFF08SAPI \u542F\u52A8\u671F\u7F13\u5B58\uFF09`);\n })\n );\n };\n watchMeta(path.join(sapiDir, \"manifest.json\"), \"manifest\");\n watchMeta(path.join(sapiDir, \"tsconfig.json\"), \"tsconfig\");\n\n return {\n stop() {\n stopped = true;\n if (debounceTimer) clearTimeout(debounceTimer);\n for (const w of watchers) {\n try {\n w.close();\n } catch {\n /* ignore */\n }\n }\n log(\"[devkit:watch] stopped\");\n },\n };\n}\n", "/**\n * \u7EC4\u88C5\u5E76\u90E8\u7F72\u884C\u4E3A\u5305\uFF1A\u5728 SFMC_ROOT \u4E0B spawn `sfmc mod reload`\n * \uFF08\u4E0E CLI \u540C\u4E00\u5165\u53E3\uFF0C\u5B8C\u6574\u4F20\u53C2\uFF1B\u52FF\u76F4\u63A5\u88F8\u8C03 pack-manager verb\uFF09\u3002\n */\n\nimport { runSfmcCli } from \"./sfmc-cli.js\";\n\nexport interface RebuildOptions {\n /** SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF08\u542B configs/\u3001modules/\uFF09\u3002 */\n sfmcRoot: string;\n /** \u4EC5\u6784\u5EFA\u90E8\u7F72\uFF0C\u4E0D\u5411 BDS \u53D1 reload\uFF08\u5BF9\u5E94 `mod reload --build-only`\uFF09\u3002 */\n buildOnly?: boolean;\n /** \u53EF\u9009\uFF1A\u663E\u5F0F sfmc CLI \u5165\u53E3\uFF1B\u9ED8\u8BA4\u7531\u5B89\u88C5\u6811 / PATH / SFMC_CLI \u89E3\u6790\u3002 */\n cliPath?: string;\n}\n\nexport interface RebuildResult {\n ok: boolean;\n output: string;\n}\n\nexport async function rebuildAndDeploy(opts: RebuildOptions): Promise<RebuildResult> {\n const args = [\"mod\", \"reload\"];\n if (opts.buildOnly) args.push(\"--build-only\");\n return runSfmcCli(opts.sfmcRoot, args, { cliPath: opts.cliPath });\n}\n", "/**\n * \u6A21\u5757\u542F\u505C\uFF1Aspawn `sfmc mod enable|disable`\uFF08\u5199 module-lock + best-effort \u70ED\u540C\u6B65\uFF09\u3002\n */\n\nimport { runSfmcCli, type RunSfmcCliResult } from \"./sfmc-cli.js\";\n\nexport interface SetModuleEnabledOptions {\n /** SFMC \u5DE5\u4F5C\u76EE\u5F55\uFF08\u542B modules/module-lock.json\uFF09\u3002 */\n sfmcRoot: string;\n /** \u6A21\u5757 logicalId / folderId / configKey\uFF08\u4E0E CLI `mod enable` \u4E00\u81F4\uFF09\u3002 */\n moduleId: string;\n enabled: boolean;\n /** \u53EF\u9009\uFF1A\u663E\u5F0F sfmc CLI \u5165\u53E3\uFF1B\u9ED8\u8BA4\u7531\u5B89\u88C5\u6811 / PATH / SFMC_CLI \u89E3\u6790\u3002 */\n cliPath?: string;\n}\n\nexport type SetModuleEnabledResult = RunSfmcCliResult;\n\n/** \u542F\u7528\u6216\u5173\u95ED\u6A21\u5757\uFF08\u4E0E CLI `mod enable|disable` \u540C\u6E90\uFF09\u3002 */\nexport async function setModuleEnabled(opts: SetModuleEnabledOptions): Promise<SetModuleEnabledResult> {\n const id = String(opts.moduleId || \"\").trim();\n if (!id) {\n return { ok: false, output: \"moduleId \u4E3A\u7A7A\" };\n }\n const action = opts.enabled ? \"enable\" : \"disable\";\n return runSfmcCli(opts.sfmcRoot, [\"mod\", action, id], { cliPath: opts.cliPath });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["path", "fs", "path", "fs", "path", "fs", "path", "fs", "path"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfmc-bds/devkit",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "SFMC module authoring toolkit — watch,
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
|
+
"description": "SFMC module authoring toolkit — watch, rebuild, enable/disable (for VS Code extension & tooling)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
7
7
|
"engines": {
|
|
@@ -15,28 +15,26 @@
|
|
|
15
15
|
"import": "./dist/index.js",
|
|
16
16
|
"default": "./dist/index.js"
|
|
17
17
|
},
|
|
18
|
-
"./new-module.mjs": "./scripts/new-module.mjs",
|
|
19
18
|
"./package.json": "./package.json"
|
|
20
19
|
},
|
|
21
|
-
"bin": {
|
|
22
|
-
"sfmc-new-module": "./scripts/new-module.mjs"
|
|
23
|
-
},
|
|
24
20
|
"files": [
|
|
25
21
|
"dist",
|
|
26
|
-
"scripts",
|
|
27
22
|
"README.md"
|
|
28
23
|
],
|
|
29
|
-
"scripts": {
|
|
30
|
-
"build": "node build.mjs",
|
|
31
|
-
"typecheck": "tsc7 --noEmit -p tsconfig.json"
|
|
32
|
-
},
|
|
33
24
|
"dependencies": {
|
|
34
|
-
"@sfmc-bds/bds-tools": "
|
|
35
|
-
"@sfmc-bds/cli": "
|
|
36
|
-
"@sfmc-bds/sdk": "
|
|
25
|
+
"@sfmc-bds/bds-tools": "0.2.0-beta.9",
|
|
26
|
+
"@sfmc-bds/cli": "0.2.0-beta.11",
|
|
27
|
+
"@sfmc-bds/sdk": "0.2.0-beta.9"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@sfmc-bds/tools": "0.2.0-beta.10"
|
|
37
31
|
},
|
|
38
32
|
"publishConfig": {
|
|
39
33
|
"access": "public",
|
|
40
34
|
"registry": "https://registry.npmjs.org/"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "node build.mjs",
|
|
38
|
+
"typecheck": "tsc7 --noEmit -p tsconfig.json"
|
|
41
39
|
}
|
|
42
|
-
}
|
|
40
|
+
}
|
package/dist/scaffold.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 脚手架:委托 @sfmc-bds/devkit/scripts/new-module.mjs。
|
|
3
|
-
*/
|
|
4
|
-
export interface ScaffoldOptions {
|
|
5
|
-
/** 目标目录(须为空或可创建)。 */
|
|
6
|
-
targetDir: string;
|
|
7
|
-
moduleId: string;
|
|
8
|
-
displayName?: string;
|
|
9
|
-
official?: boolean;
|
|
10
|
-
}
|
|
11
|
-
export declare function scaffoldModule(opts: ScaffoldOptions): Promise<{
|
|
12
|
-
ok: boolean;
|
|
13
|
-
message: string;
|
|
14
|
-
}>;
|
package/dist/scaffold.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 脚手架:委托 @sfmc-bds/devkit/scripts/new-module.mjs。
|
|
3
|
-
*/
|
|
4
|
-
import { spawn } from "node:child_process";
|
|
5
|
-
import { createRequire } from "node:module";
|
|
6
|
-
import fs from "node:fs";
|
|
7
|
-
import path from "node:path";
|
|
8
|
-
import { findMonorepoRoot } from "@sfmc-bds/sdk/node/config";
|
|
9
|
-
function resolveNewModuleScript() {
|
|
10
|
-
const require = createRequire(import.meta.url);
|
|
11
|
-
try {
|
|
12
|
-
return require.resolve("@sfmc-bds/devkit/new-module.mjs");
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
/* monorepo 回退 */
|
|
16
|
-
}
|
|
17
|
-
const monoRoot = findMonorepoRoot(process.cwd());
|
|
18
|
-
const mono = monoRoot
|
|
19
|
-
? path.join(monoRoot, "packages", "devkit", "scripts", "new-module.mjs")
|
|
20
|
-
: path.resolve(process.cwd(), "packages/devkit/scripts/new-module.mjs");
|
|
21
|
-
if (fs.existsSync(mono))
|
|
22
|
-
return mono;
|
|
23
|
-
throw new Error("无法解析 new-module.mjs(安装 @sfmc-bds/devkit 或在 monorepo 根运行)");
|
|
24
|
-
}
|
|
25
|
-
export async function scaffoldModule(opts) {
|
|
26
|
-
const dir = path.resolve(opts.targetDir);
|
|
27
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
28
|
-
const script = resolveNewModuleScript();
|
|
29
|
-
const args = [script, opts.moduleId];
|
|
30
|
-
if (opts.displayName)
|
|
31
|
-
args.push("--name", opts.displayName);
|
|
32
|
-
if (opts.official)
|
|
33
|
-
args.push("--official");
|
|
34
|
-
return new Promise((resolve) => {
|
|
35
|
-
const proc = spawn(process.execPath, args, {
|
|
36
|
-
cwd: dir,
|
|
37
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
38
|
-
env: process.env,
|
|
39
|
-
});
|
|
40
|
-
let out = "";
|
|
41
|
-
proc.stdout?.on("data", (d) => {
|
|
42
|
-
out += d.toString();
|
|
43
|
-
});
|
|
44
|
-
proc.stderr?.on("data", (d) => {
|
|
45
|
-
out += d.toString();
|
|
46
|
-
});
|
|
47
|
-
proc.on("exit", (code) => {
|
|
48
|
-
resolve({
|
|
49
|
-
ok: code === 0,
|
|
50
|
-
message: out.trim() || (code === 0 ? `scaffolded ${opts.moduleId}` : `exit ${code}`),
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
proc.on("error", (e) => resolve({ ok: false, message: e.message }));
|
|
54
|
-
});
|
|
55
|
-
}
|