@politty/zod 0.1.2 → 0.2.0
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/README.md +31 -0
- package/dist/augment.js +1 -1
- package/dist/cli-main-C8D_mKfv.js +2 -0
- package/dist/cli-main-ClQaGXB3.js +1 -0
- package/dist/cli-run-BFXIag27.js +1 -0
- package/dist/cli.js +1 -15
- package/dist/command-Mbdt0bmN.js +1 -0
- package/dist/compile-cache-VuUbFWIo.js +1 -0
- package/dist/compile-cache.js +1 -3
- package/dist/completion-D8DMrPqg.js +116 -0
- package/dist/completion-DUMcvXkT.js +1 -0
- package/dist/completion.d.ts +86 -6
- package/dist/completion.js +1 -4
- package/dist/docs.js +84 -3063
- package/dist/dynamic-CMtee4tD.js +1 -0
- package/dist/dynamic-CrnlveHj.js +6 -0
- package/dist/field-meta-COGya7xp.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -27
- package/dist/log-collector-hiFa3sNm.js +1 -0
- package/dist/logger-CJsyJ8sb.js +1 -0
- package/dist/prompt-CqmGq1_N.js +1 -0
- package/dist/prompt-clack.js +1 -32
- package/dist/prompt-inquirer.js +1 -47
- package/dist/prompt.js +1 -4
- package/dist/register-C1WbbeYH.js +1 -0
- package/dist/runner-C_wCXh6X.js +1 -0
- package/dist/runner-uPmkI9Gb.js +29 -0
- package/dist/schema-BiUP_KyV.js +1 -0
- package/dist/schema-extractor-DU0Vuhbd.js +1 -0
- package/dist/skill.js +2 -1837
- package/dist/subcommand-router-D8GTMXYL.js +1 -0
- package/dist/with-completion-command-DDohm8U6.js +3 -0
- package/dist/{index-B4NylQOW.d.ts → with-completion-command-xaVZtAga.d.ts} +3 -74
- package/package.json +3 -3
- package/dist/cli-main-CAa5KwCo.js +0 -314
- package/dist/cli-main-DIRMduj1.js +0 -3
- package/dist/cli-run-B--tZW_I.js +0 -8
- package/dist/command-k-4yAz4J.js +0 -42
- package/dist/compile-cache-BC65o7MH.js +0 -103
- package/dist/completion-Ot2qpNNw.js +0 -5616
- package/dist/field-meta-CO38jOvl.js +0 -148
- package/dist/log-collector-CoUkLVJB.js +0 -114
- package/dist/logger-i_bb-Jhc.js +0 -133
- package/dist/prompt-BjIZThsH.js +0 -169
- package/dist/register-DdcsbNwM.js +0 -440
- package/dist/runner-Bz3arOqh.js +0 -3051
- package/dist/runner-Cs-Mz9JN.js +0 -3
- package/dist/schema-extractor-CVNDs07l.js +0 -250
- package/dist/src-D4QGGgW1.js +0 -6
- package/dist/src-DhQVU2hG.js +0 -12
- package/dist/subcommand-router-Cskpofdk.js +0 -134
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=`__politty_lazy__`;function t(t){return typeof t==`object`&&!!t&&e in t&&t[e]===!0}function n(t,n){return{[e]:!0,meta:t,load:n}}function r(e){return t(e)?e.meta:typeof e==`function`?null:e}async function i(e){return t(e)?await e.load():typeof e==`function`?await e():e}async function a(e,t){if(!e.subCommands)return;let n=Object.hasOwn(e.subCommands,t)?e.subCommands[t]:void 0;if(n)return{command:await i(n),aliasFor:void 0};let r=o(e,t);if(r)return{command:await i(e.subCommands[r]),aliasFor:r}}function o(e,t){if(e.subCommands){for(let[n,i]of Object.entries(e.subCommands))if(r(i)?.aliases?.includes(t))return n}}function s(e){let t=new Set;if(!e.subCommands)return t;for(let[n,i]of Object.entries(e.subCommands)){t.add(n);let e=r(i);if(e?.aliases)for(let n of e.aliases)t.add(n)}return t}function c(e){return e.subCommands?Object.keys(e.subCommands):[]}export{a,r as c,o as i,c as n,t as o,i as r,n as s,s as t};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{a as e,i as t}from"./schema-extractor-DU0Vuhbd.js";import{n}from"./command-Mbdt0bmN.js";import{s as r}from"./subcommand-router-D8GTMXYL.js";import{t as i}from"./schema-BiUP_KyV.js";import{existsSync as a,readFileSync as o}from"node:fs";import{join as s}from"node:path";import{spawn as c}from"node:child_process";function l(){let e=(process.env.SHELL||``).split(`/`).pop()?.toLowerCase()||``;return e.includes(`bash`)?`bash`:e.includes(`zsh`)?`zsh`:e.includes(`fish`)?`fish`:null}function u(e){return`${process.env.XDG_CACHE_HOME??`${process.env.HOME??``}/.cache`}/${e}`}function d(e,t,n){if(t===`fish`){let t=process.env.XDG_CONFIG_HOME??`${process.env.HOME??``}/.config`;return s(t,`fish`,`completions`,`${e}.fish`)}let r=n??u(e);return s(r,`completion.${t}`)}function f(e){try{if(!a(e))return null;let t=o(e,`utf8`).split(`
|
|
2
|
+
`,6).join(`
|
|
3
|
+
`).match(/^# politty-bin-sig: (\S+)/m);return t?t[1]:null}catch{return null}}function p(e,t){return f(d(e.programName,t,e.cacheDir))!==null}function m(e,t){try{c(process.execPath,[e,`__refresh-completion`,t],{detached:!0,stdio:`ignore`}).unref()}catch{}}const h=t({shell:e.optionalEnum([`bash`,`zsh`,`fish`],{positional:!0,description:`Shell type (bash, zsh, or fish)`,placeholder:`SHELL`}),instructions:e.boolean({alias:`i`,description:`Show installation instructions`}),loader:e.boolean({description:`Print just the rc loader snippet (bash/zsh). Add it to ~/.bashrc or ~/.zshrc; it auto-regenerates the cache when the binary changes.`}),install:e.boolean({description:`Write the completion script to its on-disk cache (bash/zsh) or autoload location (fish) instead of printing it.`}),static:e.boolean({description:`Generate the legacy static completion script with command metadata baked in.`}),dispatcher:e.boolean({description:`Generate the runtime dispatcher completion script. This is the default.`}),worker:e.boolean({description:`Generate an internal static worker artifact for dispatcher mode.`})}),g=t({shell:e.enum([`bash`,`zsh`,`fish`],{positional:!0,description:`Shell to refresh`,placeholder:`SHELL`}),target:e.optionalString({positional:!0,description:`Existing politty-generated completion file to refresh`,placeholder:`TARGET`}),static:e.boolean({description:`Refresh using the legacy static completion script mode.`}),worker:e.boolean({description:`Refresh an internal static worker completion script.`})}),_=t({shell:e.enum([`bash`,`zsh`,`fish`],{positional:!0,description:`Shell worker to locate`,placeholder:`SHELL`})});function v(e,t){let{programName:a,globalArgsSchema:o,cacheDir:s,programVersion:c,bundledWorker:l}=typeof t==`string`?{programName:t}:t??{},u=a??e.name,d={...s!==void 0&&{cacheDir:s},...c!==void 0&&{programVersion:c},...o!==void 0&&{globalArgsSchema:o},...l!==void 0&&{bundledWorker:l}},f={...e};return f.subCommands={...e.subCommands,completion:r(n({name:`completion`,description:`Generate shell completion script`,args:h,run(){}}),()=>import(`./completion-DUMcvXkT.js`).then(e=>e.createCompletionCommand(f,a,o,d))),__complete:r(n({name:`__complete`,args:i,run(){}}),()=>import(`./dynamic-CMtee4tD.js`).then(e=>e.createDynamicCompleteCommand(f,a,o))),"__refresh-completion":r(n({name:`__refresh-completion`,description:`(internal) Refresh the on-disk completion cache if stale.`,args:g,run(){}}),()=>import(`./completion-DUMcvXkT.js`).then(e=>e.createRefreshCompletionCommand(f,u,d))),"__completion-worker-path":r(n({name:`__completion-worker-path`,description:`(internal) Print the bundled completion worker path when available.`,args:_,run(){}}),()=>import(`./completion-DUMcvXkT.js`).then(e=>e.createCompletionWorkerPathCommand(u,d)))},f.runMainHook=e=>{y(e,{programName:u,...s!==void 0&&{cacheDir:s}})},f}function y(e,t){if(process.env.POLITTY_NO_COMPLETION_REFRESH)return;let n=e.find(e=>!e.startsWith(`-`));if(n===`__complete`||n===`__refresh-completion`||n===`__completion-worker-path`||n===`completion`)return;let r=l();if(!r)return;let i=process.argv[1];i&&p(t,r)&&m(i,r)}export{d as a,_ as i,h as n,f as o,g as r,l as s,v as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Q as UnknownKeysMode, b as ArgsSchema, f as ResolvedExpandCandidate, g as DynamicCompletionResolver, n as ArgMeta, v as AnyCommand } from "./arg-registry-Be4GJADw.js";
|
|
2
2
|
//#region ../core/src/adapter/internal-args.d.ts
|
|
3
3
|
/** Runtime brand distinguishing internal descriptors from library schemas. */
|
|
4
4
|
declare const INTERNAL_ARGS_BRAND = "__polittyInternalArgs";
|
|
@@ -338,78 +338,7 @@ declare function defaultBundledWorkerOutputPath(shell: ShellType): string;
|
|
|
338
338
|
declare function validateBundledWorkerFile(path: string, programName: string, shell: ShellType): void;
|
|
339
339
|
declare function generateBundledCompletionWorker(options: GenerateBundledCompletionWorkerOptions): Promise<GenerateBundledCompletionWorkerResult>;
|
|
340
340
|
//#endregion
|
|
341
|
-
//#region ../core/src/completion/
|
|
342
|
-
/**
|
|
343
|
-
* Generate completion script for the specified shell
|
|
344
|
-
*/
|
|
345
|
-
declare function generateCompletion(command: AnyCommand, options: CompletionOptions): CompletionResult;
|
|
346
|
-
/**
|
|
347
|
-
* Get the list of supported shells
|
|
348
|
-
*/
|
|
349
|
-
declare function getSupportedShells(): ShellType[];
|
|
350
|
-
/**
|
|
351
|
-
* Detect the current shell from environment
|
|
352
|
-
*/
|
|
353
|
-
declare function detectShell(): ShellType | null;
|
|
354
|
-
/**
|
|
355
|
-
* Schema for the completion command arguments
|
|
356
|
-
*/
|
|
357
|
-
declare const completionArgsSchema: InternalArgsSchema<{
|
|
358
|
-
shell: "bash" | "fish" | "zsh" | undefined;
|
|
359
|
-
instructions: boolean;
|
|
360
|
-
loader: boolean;
|
|
361
|
-
install: boolean;
|
|
362
|
-
static: boolean;
|
|
363
|
-
dispatcher: boolean;
|
|
364
|
-
worker: boolean;
|
|
365
|
-
}>;
|
|
366
|
-
type CompletionArgs = InferInternalArgs<typeof completionArgsSchema>;
|
|
367
|
-
declare const refreshArgsSchema: InternalArgsSchema<{
|
|
368
|
-
shell: "bash" | "fish" | "zsh";
|
|
369
|
-
target: string | undefined;
|
|
370
|
-
static: boolean;
|
|
371
|
-
worker: boolean;
|
|
372
|
-
}>;
|
|
373
|
-
type RefreshArgs = InferInternalArgs<typeof refreshArgsSchema>;
|
|
374
|
-
declare const workerPathArgsSchema: InternalArgsSchema<{
|
|
375
|
-
shell: "bash" | "fish" | "zsh";
|
|
376
|
-
}>;
|
|
377
|
-
type WorkerPathArgs = InferInternalArgs<typeof workerPathArgsSchema>;
|
|
378
|
-
/**
|
|
379
|
-
* Create a completion subcommand for your CLI
|
|
380
|
-
*
|
|
381
|
-
* This creates a ready-to-use subcommand that generates completion scripts.
|
|
382
|
-
*
|
|
383
|
-
* @example
|
|
384
|
-
* ```typescript
|
|
385
|
-
* const mainCommand = defineCommand({
|
|
386
|
-
* name: "mycli",
|
|
387
|
-
* subCommands: {
|
|
388
|
-
* completion: createCompletionCommand(mainCommand)
|
|
389
|
-
* }
|
|
390
|
-
* });
|
|
391
|
-
* ```
|
|
392
|
-
*/
|
|
393
|
-
declare function createCompletionCommand(rootCommand: AnyCommand, programName?: string, globalArgsSchema?: ArgsSchema, extra?: {
|
|
394
|
-
cacheDir?: string;
|
|
395
|
-
programVersion?: string;
|
|
396
|
-
bundledWorker?: BundledWorkerOptions;
|
|
397
|
-
}): Command<typeof completionArgsSchema, CompletionArgs, any>;
|
|
398
|
-
/**
|
|
399
|
-
* Hidden subcommand that the runMain background hook spawns. It does
|
|
400
|
-
* the same stat-compare + atomic rewrite as the rc loader, but in a
|
|
401
|
-
* detached child process so it's invisible to the user.
|
|
402
|
-
*/
|
|
403
|
-
declare function createRefreshCompletionCommand(rootCommand: AnyCommand, programName: string, extra?: {
|
|
404
|
-
cacheDir?: string;
|
|
405
|
-
programVersion?: string;
|
|
406
|
-
globalArgsSchema?: ArgsSchema;
|
|
407
|
-
bundledWorker?: BundledWorkerOptions;
|
|
408
|
-
}): Command<typeof refreshArgsSchema, RefreshArgs, any>;
|
|
409
|
-
declare function createCompletionWorkerPathCommand(programName: string, extra?: {
|
|
410
|
-
binPath?: string;
|
|
411
|
-
bundledWorker?: BundledWorkerOptions;
|
|
412
|
-
}): Command<typeof workerPathArgsSchema, WorkerPathArgs, any>;
|
|
341
|
+
//#region ../core/src/completion/with-completion-command.d.ts
|
|
413
342
|
/**
|
|
414
343
|
* Options for withCompletionCommand
|
|
415
344
|
*/
|
|
@@ -452,4 +381,4 @@ interface WithCompletionOptions {
|
|
|
452
381
|
*/
|
|
453
382
|
declare function withCompletionCommand<T extends AnyCommand>(command: T, options?: string | WithCompletionOptions): T;
|
|
454
383
|
//#endregion
|
|
455
|
-
export { CompletionResult as
|
|
384
|
+
export { CompletionResult as _, bundledWorkerShellExtension as a, InferInternalArgs as b, validateBundledWorkerFile as c, CompletablePositional as d, CompletableSubcommand as f, CompletionOptions as g, CompletionMode as h, GenerateBundledCompletionWorkerResult as i, BundledWorkerOptions as l, CompletionGenerator as m, withCompletionCommand as n, defaultBundledWorkerOutputPath as o, CompletionData as p, GenerateBundledCompletionWorkerOptions as r, generateBundledCompletionWorker as s, WithCompletionOptions as t, CompletableOption as u, ShellType as v, InternalArgsSchema as x, ValueCompletion as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@politty/zod",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A lightweight CLI framework inspired by citty with zod v4 registry integration for type-safe metadata management",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"argument-parser",
|
|
@@ -74,12 +74,12 @@
|
|
|
74
74
|
"yaml": "^2.9.0"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
+
"@politty/core": "0.1.0",
|
|
77
78
|
"@types/node": "25.9.5",
|
|
78
79
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
79
80
|
"tsdown": "0.22.14",
|
|
80
81
|
"typescript": "7.0.2",
|
|
81
|
-
"zod": "4.4.3"
|
|
82
|
-
"@politty/core": "0.1.0"
|
|
82
|
+
"zod": "4.4.3"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
85
|
"@clack/prompts": "^0.10.0 || ^0.11.0 || ^1.0.0",
|
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
import { a as internalField, i as internalArgs } from "./schema-extractor-CVNDs07l.js";
|
|
2
|
-
import { n as defineCommand } from "./command-k-4yAz4J.js";
|
|
3
|
-
import { n as runMain } from "./runner-Bz3arOqh.js";
|
|
4
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
7
|
-
|
|
8
|
-
//#region ../core/src/compile-cache-shim.ts
|
|
9
|
-
/**
|
|
10
|
-
* Generator for compile-cache bin shims.
|
|
11
|
-
*
|
|
12
|
-
* Emits the minimal entry file described in docs/recipes.md ("Faster
|
|
13
|
-
* Startup"): a shim that enables the Node.js on-disk compile cache and then
|
|
14
|
-
* loads the real CLI with a dynamic import. Meant to be wired into a
|
|
15
|
-
* `postbuild` or `prepack` script via `politty generate-shim` so the shim
|
|
16
|
-
* never has to live in source.
|
|
17
|
-
*
|
|
18
|
-
* Each politty package binds its own generator with
|
|
19
|
-
* {@link createCompileCacheShimGenerator}, so the shim imports the cache
|
|
20
|
-
* helper from the package that generated it.
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* Marker identifying files this generator wrote (overwrite guard). Must be
|
|
24
|
-
* shim-specific: other politty artifacts (e.g. completion scripts) also say
|
|
25
|
-
* "Generated by politty", and those must never be treated as overwritable.
|
|
26
|
-
*/
|
|
27
|
-
const SHIM_MARKER = "Generated by politty: compile-cache bin shim";
|
|
28
|
-
/** Entry candidates tried, in order, when `entry` is omitted. */
|
|
29
|
-
const DEFAULT_ENTRY_CANDIDATES = [
|
|
30
|
-
"./cli.js",
|
|
31
|
-
"./cli.mjs",
|
|
32
|
-
"./index.js",
|
|
33
|
-
"./index.mjs"
|
|
34
|
-
];
|
|
35
|
-
/**
|
|
36
|
-
* Read the nearest `package.json`, walking up from `startDir` to the
|
|
37
|
-
* filesystem root. A malformed file is a real error and propagates.
|
|
38
|
-
*/
|
|
39
|
-
function readNearestPackageJson(startDir) {
|
|
40
|
-
let dir = resolve(startDir);
|
|
41
|
-
for (;;) {
|
|
42
|
-
const candidate = join(dir, "package.json");
|
|
43
|
-
if (existsSync(candidate)) return {
|
|
44
|
-
pkg: JSON.parse(readFileSync(candidate, "utf8")),
|
|
45
|
-
dir
|
|
46
|
-
};
|
|
47
|
-
const parent = dirname(dir);
|
|
48
|
-
if (parent === dir) return void 0;
|
|
49
|
-
dir = parent;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* `bin` entries as `[name, path]` pairs: the object form's entries in
|
|
54
|
-
* declaration order, or the string form as a single pair named after the
|
|
55
|
-
* package (npm's own convention for `"bin": "path"`).
|
|
56
|
-
*/
|
|
57
|
-
function binEntries(pkg) {
|
|
58
|
-
if (!pkg) return [];
|
|
59
|
-
if (typeof pkg.bin === "string" && pkg.bin) {
|
|
60
|
-
const name = defaultProgramName(pkg);
|
|
61
|
-
return name ? [[name, pkg.bin]] : [];
|
|
62
|
-
}
|
|
63
|
-
if (typeof pkg.bin === "object" && pkg.bin !== null) return Object.entries(pkg.bin).filter((pair) => typeof pair[1] === "string" && pair[1] !== "");
|
|
64
|
-
return [];
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Derive the fallback program name from a package.json: the first `bin`
|
|
68
|
-
* command name when present (that is the name users type in their shell),
|
|
69
|
-
* else the package name without its scope.
|
|
70
|
-
*/
|
|
71
|
-
function defaultProgramName(pkg) {
|
|
72
|
-
if (!pkg) return void 0;
|
|
73
|
-
if (typeof pkg.bin === "object" && pkg.bin !== null) {
|
|
74
|
-
const [first] = Object.keys(pkg.bin);
|
|
75
|
-
if (first) return first;
|
|
76
|
-
}
|
|
77
|
-
if (typeof pkg.name === "string" && pkg.name) {
|
|
78
|
-
const name = pkg.name;
|
|
79
|
-
return name.startsWith("@") ? name.split("/")[1] ?? name : name;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Pick the default entry: the first {@link DEFAULT_ENTRY_CANDIDATES} that
|
|
84
|
-
* exists next to the shim (never the shim itself).
|
|
85
|
-
*/
|
|
86
|
-
function defaultEntry(outputPath) {
|
|
87
|
-
const dir = dirname(outputPath);
|
|
88
|
-
const self = basename(outputPath);
|
|
89
|
-
for (const candidate of DEFAULT_ENTRY_CANDIDATES) {
|
|
90
|
-
if (basename(candidate) === self) continue;
|
|
91
|
-
if (existsSync(join(dir, candidate))) return candidate;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function shimContent(program, entry, compileCacheSpecifier) {
|
|
95
|
-
return [
|
|
96
|
-
"#!/usr/bin/env node",
|
|
97
|
-
"",
|
|
98
|
-
`// ${SHIM_MARKER}.`,
|
|
99
|
-
"// Enables the Node.js on-disk compile cache (V8 code cache) before the",
|
|
100
|
-
"// CLI module graph is compiled, so warm starts skip recompilation",
|
|
101
|
-
"// (Node >= 22.8.0; silent no-op otherwise).",
|
|
102
|
-
"try {",
|
|
103
|
-
` const { enableCompileCache } = await import(${JSON.stringify(compileCacheSpecifier)});`,
|
|
104
|
-
` enableCompileCache(${JSON.stringify(program)});`,
|
|
105
|
-
"} catch {",
|
|
106
|
-
` // ${compileCacheSpecifier} is not resolvable from here (e.g. a fully`,
|
|
107
|
-
" // bundled CLI) — start without the compile cache rather than failing",
|
|
108
|
-
" // the CLI.",
|
|
109
|
-
"}",
|
|
110
|
-
`await import(${JSON.stringify(entry)});`,
|
|
111
|
-
""
|
|
112
|
-
].join("\n");
|
|
113
|
-
}
|
|
114
|
-
function toArray(value) {
|
|
115
|
-
if (value === void 0) return [];
|
|
116
|
-
return Array.isArray(value) ? value : [value];
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Build the shim generator for one politty package.
|
|
120
|
-
*
|
|
121
|
-
* `ownerPackage` is the npm name of the package the generator is exported
|
|
122
|
-
* from (`@politty/zod`, `@politty/valibot`, `politty`), and the shim imports
|
|
123
|
-
* `enableCompileCache` from its `compile-cache` subpath. Taking the name from
|
|
124
|
-
* the owner rather than guessing it is what makes the specifier reliable:
|
|
125
|
-
* reaching this generator at all — through that package's bin or through an
|
|
126
|
-
* import of it — means the package is installed in the host, so the specifier
|
|
127
|
-
* resolves from the shim that lands there. The alternative, reading the host's
|
|
128
|
-
* `package.json`, could only guess which of the three politty packages was
|
|
129
|
-
* meant.
|
|
130
|
-
*
|
|
131
|
-
* The returned function generates executable shims. With no explicit paths,
|
|
132
|
-
* one is generated per `bin` entry of the nearest `package.json`, each
|
|
133
|
-
* importing a conventional built module next to it — so a bare
|
|
134
|
-
* `politty generate-shim` in a `postbuild` script is usually enough. Explicit
|
|
135
|
-
* `entry` values are paired in order with the `bin` entries (or with explicit
|
|
136
|
-
* `out` values of the same count).
|
|
137
|
-
*
|
|
138
|
-
* The generated files are ESM (they use top-level `await import`), so `.js`
|
|
139
|
-
* output requires `"type": "module"` in the package; use a `.mjs` extension
|
|
140
|
-
* otherwise. Refuses to overwrite an existing file it did not generate, so
|
|
141
|
-
* a `bin` path still pointing at the real CLI entry fails loudly instead of
|
|
142
|
-
* clobbering the build output.
|
|
143
|
-
*/
|
|
144
|
-
function createCompileCacheShimGenerator(ownerPackage) {
|
|
145
|
-
return (options = {}) => generateShims(`${ownerPackage}/compile-cache`, options);
|
|
146
|
-
}
|
|
147
|
-
function generateShims(defaultCompileCacheSpecifier, options) {
|
|
148
|
-
const cwd = options.cwd ?? process.cwd();
|
|
149
|
-
const found = readNearestPackageJson(cwd);
|
|
150
|
-
const pkg = found?.pkg;
|
|
151
|
-
const entries = toArray(options.entry);
|
|
152
|
-
const outs = toArray(options.out);
|
|
153
|
-
const bins = binEntries(pkg);
|
|
154
|
-
let outputPaths;
|
|
155
|
-
if (outs.length > 0) {
|
|
156
|
-
if (entries.length > 0 && entries.length !== outs.length) throw new Error(`--entry count (${entries.length}) does not match --out count (${outs.length}); pass one --out per --entry or omit --out entirely.`);
|
|
157
|
-
outputPaths = outs.map((out) => isAbsolute(out) ? out : resolve(cwd, out));
|
|
158
|
-
} else {
|
|
159
|
-
if (bins.length === 0 || found === void 0) throw new Error("Cannot derive the output path: no bin entry in package.json. Pass --out explicitly.");
|
|
160
|
-
if (entries.length > 0 && entries.length !== bins.length) throw new Error(`--entry count (${entries.length}) does not match the package's bin entries (${bins.length}); pass one --entry per bin (in declaration order) or matching --out paths.`);
|
|
161
|
-
outputPaths = bins.map(([, path]) => resolve(found.dir, path));
|
|
162
|
-
}
|
|
163
|
-
if (new Set(outputPaths).size !== outputPaths.length) throw new Error("Duplicate output paths; each shim needs a distinct output file. Check the --out values (or the bin paths in package.json when --out is omitted).");
|
|
164
|
-
const binNameByPath = /* @__PURE__ */ new Map();
|
|
165
|
-
if (found) for (const [name, path] of bins) binNameByPath.set(resolve(found.dir, path), name);
|
|
166
|
-
const warnings = [];
|
|
167
|
-
const compileCacheSpecifier = options.compileCacheSpecifier ?? defaultCompileCacheSpecifier;
|
|
168
|
-
if (/[\r\n\u2028\u2029]/.test(compileCacheSpecifier)) throw new Error(`Invalid compile-cache specifier ${JSON.stringify(compileCacheSpecifier)}: a module specifier cannot contain a line terminator.`);
|
|
169
|
-
const plans = outputPaths.map((outputPath, index) => {
|
|
170
|
-
const matchedBinName = binNameByPath.get(outputPath);
|
|
171
|
-
const program = options.program ?? matchedBinName ?? defaultProgramName(pkg);
|
|
172
|
-
if (!program) throw new Error("Cannot derive a program name: no bin or name in package.json. Pass --program explicitly.");
|
|
173
|
-
if (options.program === void 0 && matchedBinName === void 0 && outs.length > 0) warnings.push(`Warning: ${formatShimPath(outputPath, cwd)} does not match any bin path in package.json, so its cache directory uses the program name ${JSON.stringify(program)}. Pass --program to override.`);
|
|
174
|
-
if (outputPath.endsWith(".cjs")) throw new Error("The generated shim is an ES module and cannot be written to a .cjs file. Use a .mjs (or .js in a \"type\": \"module\" package) output path.");
|
|
175
|
-
if (extname(outputPath) === "") throw new Error("The generated shim is an ES module and cannot be written to an extensionless file (it would not load on every supported Node.js version). Use a .mjs (or .js in a \"type\": \"module\" package) output path.");
|
|
176
|
-
if (outputPath.endsWith(".js") && pkg?.type !== "module") throw new Error(pkg === void 0 ? "The generated shim is an ES module, and no package.json was found to confirm .js files are treated as ESM. Write it to a .mjs file instead (e.g. --out dist/bin.mjs)." : "The generated shim is an ES module, but the package is not \"type\": \"module\". Write it to a .mjs file instead (e.g. --out dist/bin.mjs).");
|
|
177
|
-
const entry = entries[index] ?? defaultEntry(outputPath);
|
|
178
|
-
if (entry === void 0) throw new Error(`Cannot derive an entry: none of ${DEFAULT_ENTRY_CANDIDATES.join(", ")} exist next to ${outputPath}. Pass --entry explicitly.`);
|
|
179
|
-
if (!entry.startsWith("./") && !entry.startsWith("../") && !entry.startsWith("file:")) throw new Error(`Invalid entry ${entry}: pass a specifier relative to the shim file ("./..." or "../...") or a file: URL.`);
|
|
180
|
-
let entryPath;
|
|
181
|
-
if (entry.startsWith("file:")) try {
|
|
182
|
-
entryPath = fileURLToPath(entry);
|
|
183
|
-
} catch {
|
|
184
|
-
entryPath = void 0;
|
|
185
|
-
}
|
|
186
|
-
else entryPath = resolve(dirname(outputPath), entry);
|
|
187
|
-
if (entryPath === outputPath) throw new Error(`The shim at ${outputPath} would import itself (entry ${entry}). Point bin at a separate shim path (e.g. dist/bin.js) or pass a different --entry.`);
|
|
188
|
-
if (existsSync(outputPath) && !readFileSync(outputPath, "utf8").includes(SHIM_MARKER)) throw new Error(`Refusing to overwrite ${outputPath}: it exists and was not generated by politty. If bin currently points at your real CLI entry, point it at a separate shim path (e.g. dist/bin.js) or pass --out explicitly.`);
|
|
189
|
-
return {
|
|
190
|
-
outputPath,
|
|
191
|
-
program,
|
|
192
|
-
entry,
|
|
193
|
-
compileCacheSpecifier
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
for (const warning of warnings) console.warn(warning);
|
|
197
|
-
for (const { outputPath, program, entry } of plans) {
|
|
198
|
-
mkdirSync(dirname(outputPath), { recursive: true });
|
|
199
|
-
writeFileSync(outputPath, shimContent(program, entry, compileCacheSpecifier));
|
|
200
|
-
chmodSync(outputPath, 493);
|
|
201
|
-
}
|
|
202
|
-
return plans;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Format a generated path for CLI output: relative to `cwd` when inside it.
|
|
206
|
-
*/
|
|
207
|
-
function formatShimPath(outputPath, cwd) {
|
|
208
|
-
const rel = relative(cwd, outputPath);
|
|
209
|
-
return rel && !rel.startsWith("..") ? rel : outputPath;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
//#endregion
|
|
213
|
-
//#region ../core/src/cli-main.ts
|
|
214
|
-
const generateWorkerArgsSchema = internalArgs({
|
|
215
|
-
bin: internalField.string({
|
|
216
|
-
description: "CLI binary or built JS entry file to invoke",
|
|
217
|
-
placeholder: "PATH"
|
|
218
|
-
}),
|
|
219
|
-
program: internalField.string({
|
|
220
|
-
description: "Program name embedded in worker metadata",
|
|
221
|
-
placeholder: "NAME"
|
|
222
|
-
}),
|
|
223
|
-
shell: internalField.enum([
|
|
224
|
-
"bash",
|
|
225
|
-
"zsh",
|
|
226
|
-
"fish"
|
|
227
|
-
], {
|
|
228
|
-
description: "Shell worker to generate",
|
|
229
|
-
placeholder: "SHELL"
|
|
230
|
-
}),
|
|
231
|
-
out: internalField.optionalString({
|
|
232
|
-
description: "Output worker path (defaults to dist/completion/<shell>-worker.<ext>)",
|
|
233
|
-
placeholder: "PATH"
|
|
234
|
-
}),
|
|
235
|
-
verify: internalField.boolean({ description: "Verify __completion-worker-path resolves to the generated worker" })
|
|
236
|
-
});
|
|
237
|
-
const generateWorkerCommand = defineCommand({
|
|
238
|
-
name: "generate-worker",
|
|
239
|
-
description: "Generate and verify a bundled shell completion worker",
|
|
240
|
-
args: generateWorkerArgsSchema,
|
|
241
|
-
async run(args) {
|
|
242
|
-
const { generateBundledCompletionWorker } = await import("./src-DhQVU2hG.js");
|
|
243
|
-
await generateBundledCompletionWorker({
|
|
244
|
-
bin: args.bin,
|
|
245
|
-
programName: args.program,
|
|
246
|
-
shell: args.shell,
|
|
247
|
-
...args.out !== void 0 && { outputPath: args.out },
|
|
248
|
-
verify: args.verify
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
const generateShimArgsSchema = internalArgs({
|
|
253
|
-
entry: internalField.optionalStringArray({
|
|
254
|
-
description: "Module specifier the shim imports, relative to the shim file; repeatable, one per bin/--out (defaults to ./cli.js, ./cli.mjs, ./index.js, or ./index.mjs next to each shim)",
|
|
255
|
-
placeholder: "SPECIFIER"
|
|
256
|
-
}),
|
|
257
|
-
out: internalField.optionalStringArray({
|
|
258
|
-
description: "Output path for the generated shim; repeatable, one per --entry (defaults to the bin paths in package.json)",
|
|
259
|
-
placeholder: "PATH"
|
|
260
|
-
}),
|
|
261
|
-
program: internalField.optionalString({
|
|
262
|
-
description: "Program name for the cache directory, applied to all shims (defaults per shim to its bin name)",
|
|
263
|
-
placeholder: "NAME"
|
|
264
|
-
}),
|
|
265
|
-
compileCacheSpecifier: internalField.optionalString({
|
|
266
|
-
description: "Module specifier the shim imports enableCompileCache from (defaults to the compile-cache subpath of the politty package running this command)",
|
|
267
|
-
placeholder: "SPECIFIER"
|
|
268
|
-
})
|
|
269
|
-
});
|
|
270
|
-
/**
|
|
271
|
-
* Run politty's own development CLI (`generate-shim`, `generate-worker`).
|
|
272
|
-
*
|
|
273
|
-
* `ownerPackage` is the npm name of the politty package providing the `politty`
|
|
274
|
-
* bin that invoked this — `@politty/zod`, `@politty/valibot`, or `politty`. It
|
|
275
|
-
* is threaded through to {@link createCompileCacheShimGenerator} so a generated
|
|
276
|
-
* shim imports the cache helper from the package the user actually installed,
|
|
277
|
-
* which is the one guaranteed to resolve from their own package.
|
|
278
|
-
*
|
|
279
|
-
* Never returns: it exits the process, like `runMain`.
|
|
280
|
-
*/
|
|
281
|
-
function runPolittyCli(ownerPackage) {
|
|
282
|
-
const generateCompileCacheShim = createCompileCacheShimGenerator(ownerPackage);
|
|
283
|
-
const generateShimCommand = defineCommand({
|
|
284
|
-
name: "generate-shim",
|
|
285
|
-
description: "Generate a compile-cache bin shim that loads the real CLI via dynamic import",
|
|
286
|
-
args: generateShimArgsSchema,
|
|
287
|
-
run(args) {
|
|
288
|
-
const cwd = process.cwd();
|
|
289
|
-
const results = generateCompileCacheShim({
|
|
290
|
-
...args.entry !== void 0 && { entry: args.entry },
|
|
291
|
-
...args.out !== void 0 && { out: args.out },
|
|
292
|
-
...args.program !== void 0 && { program: args.program },
|
|
293
|
-
...args.compileCacheSpecifier !== void 0 && { compileCacheSpecifier: args.compileCacheSpecifier },
|
|
294
|
-
cwd
|
|
295
|
-
});
|
|
296
|
-
for (const result of results) console.log(`Generated compile-cache shim: ${formatShimPath(result.outputPath, cwd)} (program: ${result.program}, entry: ${result.entry}, compile-cache: ${result.compileCacheSpecifier})`);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
const cli = defineCommand({
|
|
300
|
-
name: "politty",
|
|
301
|
-
description: "politty development utilities",
|
|
302
|
-
subCommands: {
|
|
303
|
-
"generate-shim": generateShimCommand,
|
|
304
|
-
"generate-worker": generateWorkerCommand
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
return runMain(cli).catch((error) => {
|
|
308
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
309
|
-
process.exit(1);
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
//#endregion
|
|
314
|
-
export { createCompileCacheShimGenerator as n, runPolittyCli as t };
|
package/dist/cli-run-B--tZW_I.js
DELETED
package/dist/command-k-4yAz4J.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
//#region ../core/src/core/command.ts
|
|
2
|
-
function defineCommand(config) {
|
|
3
|
-
return {
|
|
4
|
-
name: config.name,
|
|
5
|
-
description: config.description,
|
|
6
|
-
aliases: config.aliases,
|
|
7
|
-
args: config.args,
|
|
8
|
-
subCommands: config.subCommands,
|
|
9
|
-
setup: config.setup,
|
|
10
|
-
run: config.run,
|
|
11
|
-
cleanup: config.cleanup,
|
|
12
|
-
notes: config.notes,
|
|
13
|
-
examples: config.examples
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Create a typed defineCommand factory with pre-bound global args type.
|
|
18
|
-
* This is the recommended pattern for type-safe global options.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* // global-args.ts
|
|
23
|
-
* type GlobalArgsType = { verbose: boolean; config?: string };
|
|
24
|
-
* export const defineAppCommand = createDefineCommand<GlobalArgsType>();
|
|
25
|
-
*
|
|
26
|
-
* // commands/build.ts
|
|
27
|
-
* export const buildCommand = defineAppCommand({
|
|
28
|
-
* name: "build",
|
|
29
|
-
* args: z.object({ output: arg(z.string().default("dist")) }),
|
|
30
|
-
* run: (args) => {
|
|
31
|
-
* args.verbose; // typed via GlobalArgsType
|
|
32
|
-
* args.output; // typed via local args
|
|
33
|
-
* },
|
|
34
|
-
* });
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
function createDefineCommand() {
|
|
38
|
-
return defineCommand;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
//#endregion
|
|
42
|
-
export { defineCommand as n, createDefineCommand as t };
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import * as nodeModule from "node:module";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
|
|
5
|
-
//#region ../core/src/compile-cache.ts
|
|
6
|
-
/**
|
|
7
|
-
* Node.js on-disk compile cache (V8 code cache) helpers.
|
|
8
|
-
*
|
|
9
|
-
* `node:module`'s `enableCompileCache` (Node.js >= 22.8.0) persists compiled
|
|
10
|
-
* bytecode to disk so warm starts skip recompilation. Because ESM static
|
|
11
|
-
* import graphs are compiled during the link phase — before any user code
|
|
12
|
-
* runs — enabling the cache inside `runMain` only covers modules imported
|
|
13
|
-
* *after* the call (e.g. `lazy()` subcommands). To cover the whole CLI,
|
|
14
|
-
* enable it from a minimal bin shim that dynamically imports the real entry:
|
|
15
|
-
*
|
|
16
|
-
* ```ts
|
|
17
|
-
* #!/usr/bin/env node
|
|
18
|
-
* // Import from the `compile-cache` subpath of the politty package your CLI
|
|
19
|
-
* // depends on — `politty generate-shim` writes that specifier for you,
|
|
20
|
-
* // naming whichever package's bin generated the shim.
|
|
21
|
-
* import { enableCompileCache } from "<your-politty-package>/compile-cache";
|
|
22
|
-
*
|
|
23
|
-
* enableCompileCache("my-cli");
|
|
24
|
-
* await import("./cli.js");
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* This module must stay dependency-free (node builtins only) so the shim's
|
|
28
|
-
* static graph — the part that can never be cached — stays tiny.
|
|
29
|
-
*/
|
|
30
|
-
/**
|
|
31
|
-
* Reduce a program name to a single safe path segment. Path separators and
|
|
32
|
-
* a leading scope marker are collapsed (`@scope/cli` → `scope-cli`) so the
|
|
33
|
-
* name cannot escape the cache root; names that reduce to nothing (or to
|
|
34
|
-
* `.`/`..`) yield `undefined`. Realistic command names pass through
|
|
35
|
-
* unchanged.
|
|
36
|
-
*/
|
|
37
|
-
function sanitizeProgramName(programName) {
|
|
38
|
-
const safe = programName.replace(/^@/, "").replace(/[/\\]+/g, "-").trim();
|
|
39
|
-
if (!safe || /^[.-]+$/.test(safe)) return void 0;
|
|
40
|
-
return safe;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Compute the cache directory for a program following the same XDG
|
|
44
|
-
* convention as the shell-completion dispatcher scripts
|
|
45
|
-
* (`src/completion/dispatcher.ts`), so direct CLI runs and completion
|
|
46
|
-
* workers share one warm cache:
|
|
47
|
-
* `${XDG_CACHE_HOME:-$HOME/.cache}/<sanitized programName>/node-compile-cache`.
|
|
48
|
-
* The program name is first reduced to a single safe path segment by
|
|
49
|
-
* {@link sanitizeProgramName} (e.g. `@scope/cli` → `scope-cli`). The
|
|
50
|
-
* dispatcher scripts use the raw name, but a completion program name is a
|
|
51
|
-
* single shell word resolved on PATH and can never contain separators, so
|
|
52
|
-
* for every name that can actually reach both sides the two paths coincide.
|
|
53
|
-
*
|
|
54
|
-
* Returns `undefined` when no home directory can be resolved or the program
|
|
55
|
-
* name does not reduce to a safe path segment; callers fall back to Node's
|
|
56
|
-
* default location (`NODE_COMPILE_CACHE` or the OS tmpdir).
|
|
57
|
-
*/
|
|
58
|
-
function compileCacheDir(programName) {
|
|
59
|
-
const safeName = sanitizeProgramName(programName);
|
|
60
|
-
if (safeName === void 0) return void 0;
|
|
61
|
-
const xdg = process.env.XDG_CACHE_HOME;
|
|
62
|
-
if (xdg) return join(xdg, safeName, "node-compile-cache");
|
|
63
|
-
try {
|
|
64
|
-
const home = homedir();
|
|
65
|
-
if (!home) return void 0;
|
|
66
|
-
return join(home, ".cache", safeName, "node-compile-cache");
|
|
67
|
-
} catch {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Enable the Node.js on-disk compile cache for this process.
|
|
73
|
-
*
|
|
74
|
-
* - No-ops (returns `{ enabled: false }`) on runtimes without
|
|
75
|
-
* `module.enableCompileCache` (Node.js < 22.8.0) and never throws.
|
|
76
|
-
* - When the `NODE_COMPILE_CACHE` environment variable is set it always
|
|
77
|
-
* wins, keeping runs spawned by completion scripts (which set the same
|
|
78
|
-
* variable) consistent with direct runs.
|
|
79
|
-
* - Repeat calls are harmless: Node keeps the directory from the first
|
|
80
|
-
* successful call.
|
|
81
|
-
*
|
|
82
|
-
* @param options - Program name (string shorthand) or {@link CompileCacheOptions}.
|
|
83
|
-
*/
|
|
84
|
-
function enableCompileCache(options) {
|
|
85
|
-
const opts = typeof options === "string" ? { programName: options } : options ?? {};
|
|
86
|
-
try {
|
|
87
|
-
const enable = nodeModule.enableCompileCache;
|
|
88
|
-
if (typeof enable !== "function") return { enabled: false };
|
|
89
|
-
let dir;
|
|
90
|
-
if (!process.env.NODE_COMPILE_CACHE) dir = opts.cacheDir ?? (opts.programName !== void 0 ? compileCacheDir(opts.programName) : void 0);
|
|
91
|
-
const result = dir === void 0 ? enable() : enable(dir);
|
|
92
|
-
const status = nodeModule.constants?.compileCacheStatus;
|
|
93
|
-
return {
|
|
94
|
-
enabled: status !== void 0 ? result.status === status.ENABLED || result.status === status.ALREADY_ENABLED : result.status === 0 || result.status === 1,
|
|
95
|
-
...result.directory !== void 0 && { directory: result.directory }
|
|
96
|
-
};
|
|
97
|
-
} catch {
|
|
98
|
-
return { enabled: false };
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
//#endregion
|
|
103
|
-
export { enableCompileCache as n, compileCacheDir as t };
|