@twobirds/microcomponents 0.13.1 → 0.13.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/dist/cli/dispatch.d.ts +27 -1
- package/dist/cli/dispatch.d.ts.map +1 -1
- package/dist/cli/index.js +45 -10
- package/dist/docs/cli.d.ts +1 -1
- package/dist/mcp/api.json +1 -1
- package/package.json +1 -1
package/dist/cli/dispatch.d.ts
CHANGED
|
@@ -18,12 +18,38 @@ export type Runner = (script: string, options?: {
|
|
|
18
18
|
/** Asks the user to confirm a namespace long enough to be worth a second look. */
|
|
19
19
|
export type Confirmer = (namespace: string) => Promise<boolean>;
|
|
20
20
|
/**
|
|
21
|
+
Whether `mc <command>` runs the project's package.json script or the CLI's own
|
|
22
|
+
implementation.
|
|
23
|
+
|
|
24
|
+
A script that is a thin wrapper around the same command must not be delegated:
|
|
25
|
+
`mc dev` would spawn `pnpm run dev`, which runs `mc dev`, which spawns
|
|
26
|
+
`pnpm run dev`, forever. The scaffold writes exactly that shape (`"dev": "mc dev"`,
|
|
27
|
+
`"preview": "mc preview"`), so this guard is what keeps `pnpm dev` in a scaffolded
|
|
28
|
+
project from looping.
|
|
29
|
+
|
|
30
|
+
@example
|
|
31
|
+
```ts
|
|
32
|
+
scriptTarget('mc dev', 'dev'); // 'self'
|
|
33
|
+
scriptTarget('mc dev --port 5173', 'dev'); // 'self'
|
|
34
|
+
scriptTarget('npx mc preview', 'preview'); // 'self'
|
|
35
|
+
scriptTarget('vite preview --outDir build', 'dev'); // 'delegate'
|
|
36
|
+
scriptTarget('tsc -p tsconfig.json && mc bundle', 'bundle'); // 'delegate'
|
|
37
|
+
scriptTarget(undefined, 'clean'); // 'self'
|
|
38
|
+
```
|
|
39
|
+
@param body - The script body, or `undefined` when the project declares no such script.
|
|
40
|
+
@param command - The `mc` command being run.
|
|
41
|
+
@returns `'delegate'` to run the project script, `'self'` to run the CLI's implementation.
|
|
42
|
+
*/
|
|
43
|
+
export declare function scriptTarget(body: string | undefined, command: string): 'delegate' | 'self';
|
|
44
|
+
/**
|
|
21
45
|
Runs a package.json script through pnpm and resolves with its exit code.
|
|
22
46
|
|
|
23
47
|
Thin wrappers like `clean` and `check` delegate here so the script — not the
|
|
24
48
|
CLI — remains the single source of truth for what each command does. If the
|
|
25
49
|
current project defines no such script, the CLI runs its own implementation
|
|
26
|
-
against the current project, so the command works in any consumer project.
|
|
50
|
+
against the current project, so the command works in any consumer project. A script
|
|
51
|
+
that is a thin wrapper around the command itself is not delegated, because
|
|
52
|
+
delegating makes the CLI run itself forever — see {@link scriptTarget}.
|
|
27
53
|
|
|
28
54
|
@example
|
|
29
55
|
```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;AAwEF,MAAM,MAAM,MAAM,GAAG,CACpB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACtC,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,kFAAkF;AAClF,MAAM,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;AAwEF,MAAM,MAAM,MAAM,GAAG,CACpB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACtC,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,kFAAkF;AAClF,MAAM,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAgFhE;;;;;;;;;;;;;;;;;;;;;;EAsBE;AACF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAQ3F;AAgED;;;;;;;;;;;;;;EAcE;AACF,wBAAsB,SAAS,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,CAAC,CAajB;AAED;;;;;;;;;;;;;;;;;;;;EAoBE;AACF,wBAAsB,IAAI,CACzB,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,MAAkB,EACvB,OAAO,GAAE,SAA4B,GACnC,OAAO,CAAC,MAAM,CAAC,CA4IjB"}
|
package/dist/cli/index.js
CHANGED
|
@@ -267,7 +267,7 @@ function packageJson(namespace) {
|
|
|
267
267
|
typecheck: "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
|
|
268
268
|
test: "vitest run"
|
|
269
269
|
},
|
|
270
|
-
dependencies: { "@twobirds/microcomponents": "^0.13.
|
|
270
|
+
dependencies: { "@twobirds/microcomponents": "^0.13.2" },
|
|
271
271
|
devDependencies: {
|
|
272
272
|
typescript: "^6.0.3",
|
|
273
273
|
vitest: "^4.1.10",
|
|
@@ -1721,23 +1721,56 @@ function spawnProcess(command, args, cwd) {
|
|
|
1721
1721
|
});
|
|
1722
1722
|
}
|
|
1723
1723
|
/**
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
the CLI's own implementation when the project defines no such script.
|
|
1724
|
+
The body of a package.json script in the current directory, or `undefined` when the
|
|
1725
|
+
project declares no such script. Consumers get this check so `mc clean`/`mc check`
|
|
1726
|
+
can fall back to the CLI's own implementation when the project defines no such script.
|
|
1727
1727
|
|
|
1728
1728
|
@example
|
|
1729
1729
|
```ts
|
|
1730
|
-
|
|
1730
|
+
await scriptBody('clean'); // 'rm -rf dist'
|
|
1731
|
+
await scriptBody('nope'); // undefined
|
|
1731
1732
|
```
|
|
1732
1733
|
@param script - Script name to look up.
|
|
1733
1734
|
*/
|
|
1734
|
-
async function
|
|
1735
|
+
async function scriptBody(script) {
|
|
1735
1736
|
try {
|
|
1736
|
-
|
|
1737
|
+
const body = JSON.parse(await readFile(path.join(process.cwd(), "package.json"), "utf8"))?.scripts?.[script];
|
|
1738
|
+
return typeof body === "string" ? body : void 0;
|
|
1737
1739
|
} catch {
|
|
1738
|
-
return
|
|
1740
|
+
return;
|
|
1739
1741
|
}
|
|
1740
1742
|
}
|
|
1743
|
+
/** The CLI's own bin names, so a script that wraps this command is recognized. */
|
|
1744
|
+
var SELF_BINS = /* @__PURE__ */ new Set(["mc", "microcomponents"]);
|
|
1745
|
+
/**
|
|
1746
|
+
Whether `mc <command>` runs the project's package.json script or the CLI's own
|
|
1747
|
+
implementation.
|
|
1748
|
+
|
|
1749
|
+
A script that is a thin wrapper around the same command must not be delegated:
|
|
1750
|
+
`mc dev` would spawn `pnpm run dev`, which runs `mc dev`, which spawns
|
|
1751
|
+
`pnpm run dev`, forever. The scaffold writes exactly that shape (`"dev": "mc dev"`,
|
|
1752
|
+
`"preview": "mc preview"`), so this guard is what keeps `pnpm dev` in a scaffolded
|
|
1753
|
+
project from looping.
|
|
1754
|
+
|
|
1755
|
+
@example
|
|
1756
|
+
```ts
|
|
1757
|
+
scriptTarget('mc dev', 'dev'); // 'self'
|
|
1758
|
+
scriptTarget('mc dev --port 5173', 'dev'); // 'self'
|
|
1759
|
+
scriptTarget('npx mc preview', 'preview'); // 'self'
|
|
1760
|
+
scriptTarget('vite preview --outDir build', 'dev'); // 'delegate'
|
|
1761
|
+
scriptTarget('tsc -p tsconfig.json && mc bundle', 'bundle'); // 'delegate'
|
|
1762
|
+
scriptTarget(undefined, 'clean'); // 'self'
|
|
1763
|
+
```
|
|
1764
|
+
@param body - The script body, or `undefined` when the project declares no such script.
|
|
1765
|
+
@param command - The `mc` command being run.
|
|
1766
|
+
@returns `'delegate'` to run the project script, `'self'` to run the CLI's implementation.
|
|
1767
|
+
*/
|
|
1768
|
+
function scriptTarget(body, command) {
|
|
1769
|
+
if (!body) return "self";
|
|
1770
|
+
const tokens = body.trim().split(/\s+/);
|
|
1771
|
+
while (tokens[0] === "npx" || tokens[0] === "pnpm" && tokens[1] === "exec") tokens.splice(0, tokens[0] === "npx" ? 1 : 2);
|
|
1772
|
+
return SELF_BINS.has(tokens[0]) && tokens[1] === command ? "self" : "delegate";
|
|
1773
|
+
}
|
|
1741
1774
|
/** Build artifacts to remove, relative to the project root. */
|
|
1742
1775
|
var CLEAN_DIRS = [
|
|
1743
1776
|
"dist",
|
|
@@ -1811,7 +1844,9 @@ Runs a package.json script through pnpm and resolves with its exit code.
|
|
|
1811
1844
|
Thin wrappers like `clean` and `check` delegate here so the script — not the
|
|
1812
1845
|
CLI — remains the single source of truth for what each command does. If the
|
|
1813
1846
|
current project defines no such script, the CLI runs its own implementation
|
|
1814
|
-
against the current project, so the command works in any consumer project.
|
|
1847
|
+
against the current project, so the command works in any consumer project. A script
|
|
1848
|
+
that is a thin wrapper around the command itself is not delegated, because
|
|
1849
|
+
delegating makes the CLI run itself forever — see {@link scriptTarget}.
|
|
1815
1850
|
|
|
1816
1851
|
@example
|
|
1817
1852
|
```ts
|
|
@@ -1819,7 +1854,7 @@ const code = await runScript('check');
|
|
|
1819
1854
|
```
|
|
1820
1855
|
*/
|
|
1821
1856
|
async function runScript(script, options) {
|
|
1822
|
-
if (await
|
|
1857
|
+
if (scriptTarget(await scriptBody(script), script) === "delegate") return spawnProcess("pnpm", ["run", script]);
|
|
1823
1858
|
if (script === "clean") return cleanSelf();
|
|
1824
1859
|
if (script === "check") return checkSelf();
|
|
1825
1860
|
if (script === "dev") return runDev(process.cwd(), void 0, options?.port ?? 5173, options?.host ?? "127.0.0.1");
|
package/dist/docs/cli.d.ts
CHANGED
package/dist/mcp/api.json
CHANGED