@crustjs/validate 0.0.1 → 0.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/README.md +69 -69
- package/dist/effect/index.d.ts +183 -87
- package/dist/effect/index.js +105 -121
- package/dist/shared/chunk-p8pzhj6c.js +120 -0
- package/dist/zod/index.d.ts +177 -135
- package/dist/zod/index.js +105 -116
- package/package.json +1 -1
- package/dist/shared/chunk-zfhm7pmv.js +0 -196
package/dist/zod/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CommandContext, CommandDef } from "@crustjs/core";
|
|
1
|
+
import { ArgDef, ArgsDef, FlagDef, FlagsDef } from "@crustjs/core";
|
|
3
2
|
import * as z from "zod/v4/core";
|
|
4
3
|
import { AnyCommand } from "@crustjs/core";
|
|
5
4
|
/**
|
|
@@ -29,162 +28,162 @@ interface ValidatedContext<
|
|
|
29
28
|
flags: Record<string, unknown>;
|
|
30
29
|
};
|
|
31
30
|
}
|
|
32
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Unique symbol used to attach a Zod schema to a core `ArgDef` or `FlagDef`.
|
|
33
|
+
*
|
|
34
|
+
* Survives `{ ...def }` spread in `defineCommand` and `Object.freeze`,
|
|
35
|
+
* making the schema available at runtime via `def[ZOD_SCHEMA]`.
|
|
36
|
+
*/
|
|
37
|
+
declare const ZOD_SCHEMA: unique symbol;
|
|
38
|
+
type ZOD_SCHEMA = typeof ZOD_SCHEMA;
|
|
39
|
+
/** A Zod schema used by the validate/zod entrypoint. */
|
|
33
40
|
type ZodSchemaLike<
|
|
34
41
|
Input = unknown,
|
|
35
42
|
Output = Input
|
|
36
43
|
> = z.$ZodType<Output, Input>;
|
|
37
|
-
/**
|
|
38
|
-
type
|
|
39
|
-
/** Optional metadata for a positional argument declared with `arg()`. */
|
|
40
|
-
interface ArgOptions {
|
|
41
|
-
/** Collect remaining positionals into this arg as an array. */
|
|
42
|
-
readonly variadic?: true;
|
|
43
|
-
}
|
|
44
|
+
/** CLI value type literals. */
|
|
45
|
+
type ValueType = "string" | "number" | "boolean";
|
|
44
46
|
/**
|
|
45
|
-
*
|
|
47
|
+
* Resolve the CLI `ValueType` from a Zod schema at the type level.
|
|
46
48
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
49
|
+
* Unwraps common wrappers (optional, default, nullable, pipe, catch,
|
|
50
|
+
* prefault, nonoptional, readonly) and maps leaf schemas to their
|
|
51
|
+
* primitive type string.
|
|
50
52
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* - `ArgSpec<N, S>` (default) — type-erased form used in constraints
|
|
53
|
+
* Falls back to `ValueType` (the union) for unrecognized schemas — the
|
|
54
|
+
* runtime introspection always produces the correct narrow value.
|
|
54
55
|
*/
|
|
55
|
-
|
|
56
|
+
type ResolveZodValueType<S> = S extends z.$ZodString ? "string" : S extends z.$ZodNumber ? "number" : S extends z.$ZodBoolean ? "boolean" : S extends z.$ZodEnum ? "string" : S extends z.$ZodLiteral<infer L> ? L extends string ? "string" : L extends number ? "number" : L extends boolean ? "boolean" : ValueType : S extends z.$ZodOptional<infer Inner> ? ResolveZodValueType<Inner> : S extends z.$ZodDefault<infer Inner> ? ResolveZodValueType<Inner> : S extends z.$ZodNullable<infer Inner> ? ResolveZodValueType<Inner> : S extends z.$ZodCatch<infer Inner> ? ResolveZodValueType<Inner> : S extends z.$ZodPrefault<infer Inner> ? ResolveZodValueType<Inner> : S extends z.$ZodNonOptional<infer Inner> ? ResolveZodValueType<Inner> : S extends z.$ZodReadonly<infer Inner> ? ResolveZodValueType<Inner> : S extends z.$ZodPipe<infer In, infer _Out> ? ResolveZodValueType<In> : ValueType;
|
|
57
|
+
/**
|
|
58
|
+
* An `ArgDef` enriched with a hidden Zod schema.
|
|
59
|
+
*
|
|
60
|
+
* The `Type` parameter is resolved from the schema at the type level via
|
|
61
|
+
* `ResolveZodValueType`, producing a narrow literal (e.g. `"number"`) that
|
|
62
|
+
* matches exactly one variant of core's discriminated `ArgDef` union.
|
|
63
|
+
*
|
|
64
|
+
* The `ZOD_SCHEMA` symbol key carries the schema for runtime validation.
|
|
65
|
+
*/
|
|
66
|
+
interface ZodArgDef<
|
|
56
67
|
Name extends string = string,
|
|
57
68
|
Schema extends ZodSchemaLike = ZodSchemaLike,
|
|
58
|
-
Variadic extends true | undefined = true | undefined
|
|
69
|
+
Variadic extends true | undefined = true | undefined,
|
|
70
|
+
Type extends ValueType = ResolveZodValueType<Schema>
|
|
59
71
|
> {
|
|
60
|
-
readonly kind: "arg";
|
|
61
72
|
readonly name: Name;
|
|
62
|
-
readonly
|
|
73
|
+
readonly type: Type;
|
|
74
|
+
readonly description?: string;
|
|
75
|
+
readonly required?: true;
|
|
76
|
+
/**
|
|
77
|
+
* Non-optional so `ValidateVariadicArgs` can match `{ variadic: true }`.
|
|
78
|
+
* When `Variadic` is `undefined`, the runtime value is `undefined`.
|
|
79
|
+
*/
|
|
63
80
|
readonly variadic: Variadic;
|
|
64
|
-
|
|
65
|
-
/** Ordered positional argument specs. */
|
|
66
|
-
type ArgSpecs = readonly ArgSpec[];
|
|
67
|
-
/** Output type for one ArgSpec in the validated handler context. */
|
|
68
|
-
type InferArgValue<S extends ArgSpec> = S["variadic"] extends true ? InferSchemaOutput<S["schema"]>[] : InferSchemaOutput<S["schema"]>;
|
|
69
|
-
/** Flattens an intersection of objects for readable inferred types. */
|
|
70
|
-
type Simplify<T> = { [K in keyof T] : T[K] };
|
|
71
|
-
/** Recursively maps ordered ArgSpec entries to a named output object type. */
|
|
72
|
-
type InferArgsFromTuple<A extends readonly ArgSpec[]> = A extends readonly [infer Head extends ArgSpec, ...infer Tail extends readonly ArgSpec[]] ? { [K in Head["name"]] : InferArgValue<Head> } & InferArgsFromTuple<Tail> : {};
|
|
73
|
-
/** Infer validated args object type from ordered ArgSpec entries. */
|
|
74
|
-
type InferArgsFromSpecs<A extends ArgSpecs> = Simplify<InferArgsFromTuple<A>>;
|
|
75
|
-
/** Optional metadata for a flag declared with `flag()`. */
|
|
76
|
-
interface FlagOptions {
|
|
77
|
-
/** Short alias or array of aliases (e.g. `"v"` or `["v", "V"]`). */
|
|
78
|
-
readonly alias?: string | readonly string[];
|
|
81
|
+
readonly [ZOD_SCHEMA]: Schema;
|
|
79
82
|
}
|
|
80
83
|
/**
|
|
81
|
-
* A
|
|
84
|
+
* A `FlagDef` enriched with a hidden Zod schema.
|
|
82
85
|
*
|
|
83
|
-
* The `
|
|
84
|
-
* `readonly ["v", "V"]`) from `flag()` calls so `ValidateFlagAliases` can
|
|
85
|
-
* detect collisions at compile time.
|
|
86
|
+
* The `Type` parameter is resolved from the schema at the type level.
|
|
86
87
|
*
|
|
87
|
-
*
|
|
88
|
-
* - `FlagSpec<S, undefined>` — flag without an alias
|
|
89
|
-
* - `FlagSpec<S>` (default) — type-erased form used in constraints
|
|
88
|
+
* The `ZOD_SCHEMA` symbol key carries the schema for runtime validation.
|
|
90
89
|
*/
|
|
91
|
-
interface
|
|
90
|
+
interface ZodFlagDef<
|
|
92
91
|
Schema extends ZodSchemaLike = ZodSchemaLike,
|
|
93
|
-
Alias extends string | readonly string[] | undefined = string | readonly string[] | undefined
|
|
92
|
+
Alias extends string | readonly string[] | undefined = string | readonly string[] | undefined,
|
|
93
|
+
Type extends ValueType = ResolveZodValueType<Schema>
|
|
94
94
|
> {
|
|
95
|
-
readonly
|
|
96
|
-
readonly
|
|
97
|
-
readonly
|
|
95
|
+
readonly type: Type;
|
|
96
|
+
readonly description?: string;
|
|
97
|
+
readonly required?: true;
|
|
98
|
+
/**
|
|
99
|
+
* Non-optional so `ValidateFlagAliases` can extract narrow alias literals.
|
|
100
|
+
* When `Alias` is `undefined`, the runtime value is `undefined` (no alias).
|
|
101
|
+
*/
|
|
102
|
+
readonly alias: Alias extends string | readonly string[] ? Alias : undefined;
|
|
103
|
+
readonly [ZOD_SCHEMA]: Schema;
|
|
98
104
|
}
|
|
99
|
-
/**
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
type
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
/** Options for `arg()`. */
|
|
106
|
+
interface ArgOptions {
|
|
107
|
+
/** Collect remaining positionals into this arg as an array. */
|
|
108
|
+
readonly variadic?: true;
|
|
109
|
+
}
|
|
110
|
+
/** Options for `flag()`. */
|
|
111
|
+
interface FlagOptions {
|
|
112
|
+
/** Short alias or array of aliases (e.g. `"v"` or `["v", "V"]`). */
|
|
113
|
+
readonly alias?: string | readonly string[];
|
|
114
|
+
}
|
|
115
|
+
/** Infer Zod output type from a schema. */
|
|
116
|
+
type InferSchemaOutput<S> = S extends z.$ZodType ? z.output<S> : never;
|
|
117
|
+
/** Output type for a single arg: variadic → `output[]`, scalar → `output`. */
|
|
118
|
+
type InferValidatedArgValue<D> = D extends {
|
|
119
|
+
readonly [ZOD_SCHEMA]: infer S;
|
|
120
|
+
readonly variadic: true;
|
|
121
|
+
} ? InferSchemaOutput<S>[] : D extends {
|
|
122
|
+
readonly [ZOD_SCHEMA]: infer S;
|
|
123
|
+
} ? InferSchemaOutput<S> : never;
|
|
124
|
+
/** Flattens an intersection of objects for readable inferred types. */
|
|
125
|
+
type Simplify<T> = { [K in keyof T] : T[K] };
|
|
126
|
+
/** Recursively maps args tuple to a named output object. */
|
|
127
|
+
type InferValidatedArgsTuple<A extends readonly ArgDef[]> = A extends readonly [infer Head extends ArgDef, ...infer Tail extends readonly ArgDef[]] ? Head extends {
|
|
128
|
+
readonly name: infer N extends string;
|
|
129
|
+
} ? { [K in N] : InferValidatedArgValue<Head> } & InferValidatedArgsTuple<Tail> : InferValidatedArgsTuple<Tail> : {};
|
|
114
130
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* - `args` / `flags`: Zod schema-based definitions replace core's `ArgsDef`/`FlagsDef`
|
|
118
|
-
* - `run`: receives `ValidatedContext` instead of raw `CommandContext`
|
|
119
|
-
* - `preRun` / `postRun`: use raw `CommandContext` (no `NoInfer` wrapper)
|
|
120
|
-
*
|
|
121
|
-
* All remaining `CommandDef` keys (e.g. `meta`, `subCommands`) are inherited
|
|
122
|
-
* automatically via `Omit`. If a new passthrough field is added to `CommandDef`,
|
|
123
|
-
* it propagates here without changes. The compile-time key exhaustiveness
|
|
124
|
-
* assertion in `command.test.ts` will fail, forcing a review.
|
|
131
|
+
* Infer the validated args output type from an `ArgsDef` tuple
|
|
132
|
+
* where each element carries a `[ZOD_SCHEMA]` brand.
|
|
125
133
|
*/
|
|
126
|
-
type
|
|
134
|
+
type InferValidatedArgs<A> = A extends readonly ArgDef[] ? Simplify<InferValidatedArgsTuple<A>> : Record<string, never>;
|
|
127
135
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* Extends `CommandDef` (minus overridden keys) so passthrough fields like
|
|
131
|
-
* `meta` and `subCommands` stay in sync automatically. If a new field is
|
|
132
|
-
* added to `CommandDef`, the key exhaustiveness assertion in
|
|
133
|
-
* `command.test.ts` fails at compile time, forcing a review.
|
|
136
|
+
* Infer the validated flags output type from a `FlagsDef` record
|
|
137
|
+
* where each value carries a `[ZOD_SCHEMA]` brand.
|
|
134
138
|
*/
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
readonly
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
* Receives raw parser output (`CommandContext`), not schema-transformed values.
|
|
147
|
-
*/
|
|
148
|
-
readonly preRun?: (context: CommandContext) => void | Promise<void>;
|
|
149
|
-
/** Main handler with validated/transformed args and flags. */
|
|
150
|
-
readonly run?: ZodCommandRunHandler<InferArgsFromConfig<A>, InferFlagsFromConfig<F>>;
|
|
151
|
-
/**
|
|
152
|
-
* Optional teardown hook after command execution.
|
|
153
|
-
*
|
|
154
|
-
* Receives raw parser output (`CommandContext`), not schema-transformed values.
|
|
155
|
-
*/
|
|
156
|
-
readonly postRun?: (context: CommandContext) => void | Promise<void>;
|
|
157
|
-
}
|
|
139
|
+
type InferValidatedFlags<F> = F extends Record<string, FlagDef> ? Simplify<{ [K in keyof F] : F[K] extends {
|
|
140
|
+
readonly [ZOD_SCHEMA]: infer S;
|
|
141
|
+
} ? InferSchemaOutput<S> : never }> : Record<string, never>;
|
|
142
|
+
/** Check that every arg in a tuple carries the `[ZOD_SCHEMA]` brand. */
|
|
143
|
+
type AllArgsHaveSchema<A extends ArgsDef> = A extends readonly [infer Head, ...infer Tail extends readonly ArgDef[]] ? Head extends {
|
|
144
|
+
readonly [ZOD_SCHEMA]: unknown;
|
|
145
|
+
} ? AllArgsHaveSchema<Tail> : false : true;
|
|
146
|
+
/** Check that every flag in a record carries the `[ZOD_SCHEMA]` brand. */
|
|
147
|
+
type AllFlagsHaveSchema<F extends FlagsDef> = string extends keyof F ? true : { [K in keyof F] : F[K] extends {
|
|
148
|
+
readonly [ZOD_SCHEMA]: unknown;
|
|
149
|
+
} ? true : false }[keyof F] extends true ? true : false;
|
|
158
150
|
/**
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
151
|
+
* Resolves to `true` only when all args and flags carry schema metadata.
|
|
152
|
+
* Used by `withZod` to enforce strict mode at compile time.
|
|
153
|
+
*/
|
|
154
|
+
type HasAllSchemas<
|
|
155
|
+
A extends ArgsDef,
|
|
156
|
+
F extends FlagsDef
|
|
157
|
+
> = AllArgsHaveSchema<A> extends true ? AllFlagsHaveSchema<F> extends true ? true : false : false;
|
|
158
|
+
/**
|
|
159
|
+
* The validated handler type for `withZod()`.
|
|
166
160
|
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
161
|
+
* When all args/flags carry schema metadata, resolves to a typed handler
|
|
162
|
+
* receiving `ValidatedContext`. Otherwise resolves to `never`, causing
|
|
163
|
+
* a compile error at the call site.
|
|
170
164
|
*/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
>(
|
|
175
|
-
args?: A extends readonly object[] ? ValidateVariadicArgs<A> : A;
|
|
176
|
-
flags?: F extends Record<string, unknown> ? ValidateFlagAliases<F> : F;
|
|
177
|
-
}): AnyCommand2;
|
|
165
|
+
type WithZodHandler<
|
|
166
|
+
A extends ArgsDef,
|
|
167
|
+
F extends FlagsDef
|
|
168
|
+
> = HasAllSchemas<A, F> extends true ? (context: ValidatedContext<InferValidatedArgs<A>, InferValidatedFlags<F>>) => void | Promise<void> : never;
|
|
178
169
|
/**
|
|
179
|
-
* Define a named positional argument
|
|
170
|
+
* Define a named positional argument from a Zod schema.
|
|
171
|
+
*
|
|
172
|
+
* Returns a core `ArgDef` (accepted by `defineCommand`) enriched with hidden
|
|
173
|
+
* schema metadata (via `[ZOD_SCHEMA]` symbol) for runtime validation by `withZod`.
|
|
180
174
|
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* validation in `defineZodCommand()`.
|
|
175
|
+
* CLI metadata (`type`, `required`, `description`, `variadic`) is derived
|
|
176
|
+
* from the schema automatically — single source of truth.
|
|
184
177
|
*
|
|
185
178
|
* @param name - Positional arg name used in parser output and help text
|
|
186
|
-
* @param schema - Zod schema
|
|
187
|
-
* @param options - Optional CLI metadata (
|
|
179
|
+
* @param schema - Zod schema (source of truth for type/optionality/description)
|
|
180
|
+
* @param options - Optional CLI metadata (`variadic`)
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```ts
|
|
184
|
+
* arg("port", z.number().int().min(1).describe("Port to listen on"))
|
|
185
|
+
* arg("files", z.string(), { variadic: true })
|
|
186
|
+
* ```
|
|
188
187
|
*/
|
|
189
188
|
declare function arg<
|
|
190
189
|
Name extends string,
|
|
@@ -192,21 +191,64 @@ declare function arg<
|
|
|
192
191
|
const Variadic extends true | undefined = undefined
|
|
193
192
|
>(name: Name, schema: Schema, options?: ArgOptions & {
|
|
194
193
|
variadic?: Variadic;
|
|
195
|
-
}):
|
|
194
|
+
}): ZodArgDef<Name, Schema, Variadic>;
|
|
196
195
|
/**
|
|
197
|
-
* Define a flag
|
|
196
|
+
* Define a flag from a Zod schema with optional alias.
|
|
197
|
+
*
|
|
198
|
+
* Returns a core `FlagDef` (accepted by `defineCommand`) enriched with hidden
|
|
199
|
+
* schema metadata (via `[ZOD_SCHEMA]` symbol) for runtime validation by `withZod`.
|
|
200
|
+
*
|
|
201
|
+
* CLI metadata (`type`, `multiple`, `required`, `description`) is derived
|
|
202
|
+
* from the schema automatically — single source of truth.
|
|
198
203
|
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* collision detection in `defineZodCommand()`.
|
|
204
|
+
* @param schema - Zod schema (source of truth for type/optionality/description)
|
|
205
|
+
* @param options - Optional flag metadata (`alias`)
|
|
202
206
|
*
|
|
203
|
-
* @
|
|
204
|
-
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* flag(z.boolean().default(false).describe("Enable verbose logging"), { alias: "v" })
|
|
210
|
+
* flag(z.enum(["json", "text"]).default("text"))
|
|
211
|
+
* ```
|
|
205
212
|
*/
|
|
206
213
|
declare function flag<
|
|
207
214
|
Schema extends ZodSchemaLike,
|
|
208
215
|
const Alias extends string | readonly string[] | undefined = undefined
|
|
209
216
|
>(schema: Schema, options?: FlagOptions & {
|
|
210
217
|
alias?: Alias;
|
|
211
|
-
}):
|
|
212
|
-
|
|
218
|
+
}): ZodFlagDef<Schema, Alias>;
|
|
219
|
+
import { ArgsDef as ArgsDef2, CommandContext, FlagsDef as FlagsDef2 } from "@crustjs/core";
|
|
220
|
+
/**
|
|
221
|
+
* Create a validated `run` handler for `defineCommand`.
|
|
222
|
+
*
|
|
223
|
+
* Reads Zod schemas from the command's `arg()` / `flag()` definitions,
|
|
224
|
+
* validates parsed CLI input against them, and calls `handler` with
|
|
225
|
+
* the transformed, fully-typed result.
|
|
226
|
+
*
|
|
227
|
+
* **Strict mode**: all args and flags in the command must be created with
|
|
228
|
+
* `arg()` / `flag()` from `@crustjs/validate/zod`. Plain core defs cause
|
|
229
|
+
* a compile-time error (handler parameter becomes `never`).
|
|
230
|
+
*
|
|
231
|
+
* @param handler - Receives `ValidatedContext` with typed args/flags after validation
|
|
232
|
+
* @returns A `run` function compatible with `defineCommand`
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```ts
|
|
236
|
+
* import { defineCommand } from "@crustjs/core";
|
|
237
|
+
* import { z } from "zod";
|
|
238
|
+
* import { arg, flag, withZod } from "@crustjs/validate/zod";
|
|
239
|
+
*
|
|
240
|
+
* const serve = defineCommand({
|
|
241
|
+
* meta: { name: "serve" },
|
|
242
|
+
* args: [arg("port", z.number().min(1))],
|
|
243
|
+
* flags: { verbose: flag(z.boolean().default(false), { alias: "v" }) },
|
|
244
|
+
* run: withZod(({ args, flags }) => {
|
|
245
|
+
* // args.port: number, flags.verbose: boolean
|
|
246
|
+
* }),
|
|
247
|
+
* });
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
declare function withZod<
|
|
251
|
+
A extends ArgsDef2 = ArgsDef2,
|
|
252
|
+
F extends FlagsDef2 = FlagsDef2
|
|
253
|
+
>(handler: WithZodHandler<A, F>): (context: CommandContext<A, F>) => Promise<void>;
|
|
254
|
+
export { withZod, flag, arg, ZodSchemaLike, ZodFlagDef, ZodArgDef, WithZodHandler, InferValidatedFlags, InferValidatedArgs, InferSchemaOutput, FlagOptions, ArgOptions };
|
package/dist/zod/index.js
CHANGED
|
@@ -1,92 +1,19 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
buildFlagDefinitions,
|
|
5
|
-
buildRunHandler,
|
|
3
|
+
buildValidatedRunner,
|
|
6
4
|
normalizeIssues
|
|
7
|
-
} from "../shared/chunk-
|
|
5
|
+
} from "../shared/chunk-p8pzhj6c.js";
|
|
8
6
|
|
|
9
|
-
// src/zod/
|
|
10
|
-
import {
|
|
11
|
-
import { safeParseAsync } from "zod/v4/core";
|
|
7
|
+
// src/zod/schema.ts
|
|
8
|
+
import { CrustError } from "@crustjs/core";
|
|
12
9
|
|
|
13
|
-
// src/zod/
|
|
14
|
-
|
|
10
|
+
// src/zod/types.ts
|
|
11
|
+
var ZOD_SCHEMA = Symbol.for("crustjs.validate.zod");
|
|
15
12
|
|
|
16
13
|
// src/zod/schema.ts
|
|
17
|
-
import { CrustError } from "@crustjs/core";
|
|
18
14
|
function isZodSchema(value) {
|
|
19
|
-
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
if (!("_zod" in value)) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
function arg(name, schema, options) {
|
|
28
|
-
if (!name.trim()) {
|
|
29
|
-
throw new CrustError("DEFINITION", "arg(): name is required and must be a non-empty string");
|
|
30
|
-
}
|
|
31
|
-
if (!isZodSchema(schema)) {
|
|
32
|
-
throw new CrustError("DEFINITION", `arg("${name}"): schema must be a Zod schema`);
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
kind: "arg",
|
|
36
|
-
name,
|
|
37
|
-
schema,
|
|
38
|
-
variadic: options?.variadic
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
function flag(schema, options) {
|
|
42
|
-
if (!isZodSchema(schema)) {
|
|
43
|
-
throw new CrustError("DEFINITION", "flag(): schema must be a Zod schema");
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
kind: "flag",
|
|
47
|
-
schema,
|
|
48
|
-
alias: options?.alias
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function resolveDescription(schema) {
|
|
52
|
-
let current = schema;
|
|
53
|
-
const seen = new Set;
|
|
54
|
-
for (;; ) {
|
|
55
|
-
if (current === undefined || current === null || seen.has(current)) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
seen.add(current);
|
|
59
|
-
if (typeof current !== "object") {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if ("description" in current && typeof current.description === "string") {
|
|
63
|
-
return current.description;
|
|
64
|
-
}
|
|
65
|
-
const type = "type" in current ? current.type : undefined;
|
|
66
|
-
if (typeof type !== "string") {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (type === "pipe" || type === "transform") {
|
|
70
|
-
const input = current.in;
|
|
71
|
-
if (input !== undefined) {
|
|
72
|
-
current = input;
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
if (type === "optional" || type === "nullable" || type === "default" || type === "prefault" || type === "nonoptional" || type === "readonly" || type === "catch") {
|
|
78
|
-
const unwrap = current.unwrap;
|
|
79
|
-
if (typeof unwrap === "function") {
|
|
80
|
-
current = unwrap();
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
15
|
+
return typeof value === "object" && value !== null && "_zod" in value;
|
|
87
16
|
}
|
|
88
|
-
|
|
89
|
-
// src/zod/definitions.ts
|
|
90
17
|
function asRuntimeSchema(value) {
|
|
91
18
|
if (typeof value !== "object" || value === null) {
|
|
92
19
|
return;
|
|
@@ -102,7 +29,12 @@ function getSchemaType(schema) {
|
|
|
102
29
|
}
|
|
103
30
|
function unwrapInputSchema(schema) {
|
|
104
31
|
let current = schema;
|
|
32
|
+
const seen = new Set;
|
|
105
33
|
for (;; ) {
|
|
34
|
+
if (seen.has(current)) {
|
|
35
|
+
return current;
|
|
36
|
+
}
|
|
37
|
+
seen.add(current);
|
|
106
38
|
const type = getSchemaType(current);
|
|
107
39
|
const runtime = asRuntimeSchema(current);
|
|
108
40
|
if (!type || !runtime) {
|
|
@@ -159,24 +91,29 @@ function resolveInputShape(schema, label) {
|
|
|
159
91
|
if (getSchemaType(inputSchema) === "array") {
|
|
160
92
|
const runtime = asRuntimeSchema(inputSchema);
|
|
161
93
|
if (typeof runtime?.unwrap !== "function") {
|
|
162
|
-
throw new
|
|
94
|
+
throw new CrustError("DEFINITION", `${label}: unable to inspect array element schema`);
|
|
163
95
|
}
|
|
164
96
|
const elementSchema = unwrapInputSchema(runtime.unwrap());
|
|
165
97
|
const primitive2 = resolvePrimitiveInputType(elementSchema);
|
|
166
98
|
if (primitive2) {
|
|
167
99
|
return { type: primitive2, multiple: true };
|
|
168
100
|
}
|
|
169
|
-
throw new
|
|
101
|
+
throw new CrustError("DEFINITION", `${label}: array element type must be string, number, or boolean`);
|
|
170
102
|
}
|
|
171
103
|
const primitive = resolvePrimitiveInputType(inputSchema);
|
|
172
104
|
if (primitive) {
|
|
173
105
|
return { type: primitive, multiple: false };
|
|
174
106
|
}
|
|
175
|
-
throw new
|
|
107
|
+
throw new CrustError("DEFINITION", `${label}: unsupported schema type for CLI parsing. Use string, number, boolean, enum/literal, or array of these.`);
|
|
176
108
|
}
|
|
177
109
|
function isOptionalInputSchema(schema) {
|
|
178
110
|
let current = schema;
|
|
111
|
+
const seen = new Set;
|
|
179
112
|
for (;; ) {
|
|
113
|
+
if (seen.has(current)) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
seen.add(current);
|
|
180
117
|
const type = getSchemaType(current);
|
|
181
118
|
const runtime = asRuntimeSchema(current);
|
|
182
119
|
if (!type || !runtime) {
|
|
@@ -202,21 +139,90 @@ function isOptionalInputSchema(schema) {
|
|
|
202
139
|
return false;
|
|
203
140
|
}
|
|
204
141
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
142
|
+
function resolveDescription(schema) {
|
|
143
|
+
let current = schema;
|
|
144
|
+
const seen = new Set;
|
|
145
|
+
for (;; ) {
|
|
146
|
+
if (current === undefined || current === null || seen.has(current)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
seen.add(current);
|
|
150
|
+
if (typeof current !== "object") {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if ("description" in current && typeof current.description === "string") {
|
|
154
|
+
return current.description;
|
|
155
|
+
}
|
|
156
|
+
const type = "type" in current ? current.type : undefined;
|
|
157
|
+
if (typeof type !== "string") {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (type === "pipe" || type === "transform") {
|
|
161
|
+
const input = current.in;
|
|
162
|
+
if (input !== undefined) {
|
|
163
|
+
current = input;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (type === "optional" || type === "nullable" || type === "default" || type === "prefault" || type === "nonoptional" || type === "readonly" || type === "catch") {
|
|
169
|
+
const unwrap = current.unwrap;
|
|
170
|
+
if (typeof unwrap === "function") {
|
|
171
|
+
current = unwrap();
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
214
178
|
}
|
|
215
|
-
function
|
|
216
|
-
|
|
179
|
+
function arg(name, schema, options) {
|
|
180
|
+
if (!name.trim()) {
|
|
181
|
+
throw new CrustError("DEFINITION", "arg(): name is required and must be a non-empty string");
|
|
182
|
+
}
|
|
183
|
+
if (!isZodSchema(schema)) {
|
|
184
|
+
throw new CrustError("DEFINITION", `arg("${name}"): schema must be a Zod schema`);
|
|
185
|
+
}
|
|
186
|
+
const shape = resolveInputShape(schema, `arg "${name}"`);
|
|
187
|
+
const variadic = options?.variadic;
|
|
188
|
+
if (variadic && shape.multiple) {
|
|
189
|
+
throw new CrustError("DEFINITION", `arg "${name}": variadic args must use a scalar schema; do not wrap the schema in z.array(...)`);
|
|
190
|
+
}
|
|
191
|
+
if (!variadic && shape.multiple) {
|
|
192
|
+
throw new CrustError("DEFINITION", `arg "${name}": array schema requires { variadic: true }`);
|
|
193
|
+
}
|
|
194
|
+
const description = resolveDescription(schema);
|
|
195
|
+
const required = !isOptionalInputSchema(schema);
|
|
196
|
+
const def = {
|
|
197
|
+
name,
|
|
198
|
+
type: shape.type,
|
|
199
|
+
...description !== undefined && { description },
|
|
200
|
+
variadic,
|
|
201
|
+
...required && { required: true },
|
|
202
|
+
[ZOD_SCHEMA]: schema
|
|
203
|
+
};
|
|
204
|
+
return def;
|
|
217
205
|
}
|
|
218
|
-
|
|
219
|
-
|
|
206
|
+
function flag(schema, options) {
|
|
207
|
+
if (!isZodSchema(schema)) {
|
|
208
|
+
throw new CrustError("DEFINITION", "flag(): schema must be a Zod schema");
|
|
209
|
+
}
|
|
210
|
+
const shape = resolveInputShape(schema, "flag");
|
|
211
|
+
const required = !isOptionalInputSchema(schema);
|
|
212
|
+
const description = resolveDescription(schema);
|
|
213
|
+
const alias = options?.alias === undefined ? undefined : typeof options.alias === "string" ? options.alias : [...options.alias];
|
|
214
|
+
const def = {
|
|
215
|
+
type: shape.type,
|
|
216
|
+
...shape.multiple && { multiple: true },
|
|
217
|
+
alias,
|
|
218
|
+
...description !== undefined && { description },
|
|
219
|
+
...required && { required: true },
|
|
220
|
+
[ZOD_SCHEMA]: schema
|
|
221
|
+
};
|
|
222
|
+
return def;
|
|
223
|
+
}
|
|
224
|
+
// src/zod/withZod.ts
|
|
225
|
+
import { safeParseAsync } from "zod/v4/core";
|
|
220
226
|
async function validateValue(schema, value, prefix) {
|
|
221
227
|
const parseResult = await safeParseAsync(schema, value);
|
|
222
228
|
if (parseResult.success) {
|
|
@@ -228,28 +234,11 @@ async function validateValue(schema, value, prefix) {
|
|
|
228
234
|
}));
|
|
229
235
|
return { ok: false, issues: normalizeIssues(prefixed) };
|
|
230
236
|
}
|
|
231
|
-
function
|
|
232
|
-
|
|
233
|
-
args: zodArgs,
|
|
234
|
-
flags: zodFlags,
|
|
235
|
-
run: userRun,
|
|
236
|
-
...passthrough
|
|
237
|
-
} = config;
|
|
238
|
-
const argSpecs = zodArgs ?? [];
|
|
239
|
-
const generatedArgs = argsToDefinitions(argSpecs);
|
|
240
|
-
const generatedFlags = flagsToDefinitions(zodFlags);
|
|
241
|
-
const command = defineCommand({
|
|
242
|
-
...passthrough,
|
|
243
|
-
...generatedArgs.length > 0 && { args: generatedArgs },
|
|
244
|
-
...Object.keys(generatedFlags).length > 0 && { flags: generatedFlags },
|
|
245
|
-
...userRun && {
|
|
246
|
-
run: buildRunHandler(argSpecs, zodFlags, userRun, validateValue)
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
return command;
|
|
237
|
+
function withZod(handler) {
|
|
238
|
+
return buildValidatedRunner(handler, validateValue, ZOD_SCHEMA, "withZod");
|
|
250
239
|
}
|
|
251
240
|
export {
|
|
241
|
+
withZod,
|
|
252
242
|
flag,
|
|
253
|
-
defineZodCommand,
|
|
254
243
|
arg
|
|
255
244
|
};
|