@lunora/values 1.0.0-alpha.8 → 1.0.0-alpha.9

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.
Files changed (3) hide show
  1. package/dist/index.d.mts +264 -264
  2. package/dist/index.d.ts +264 -264
  3. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -2,15 +2,15 @@ import { LunoraError } from '@lunora/errors';
2
2
  import { StandardSchemaV1 } from '@standard-schema/spec';
3
3
  type ValidationPath = ReadonlyArray<number | string>;
4
4
  /**
5
- * Thrown by `validator.parse` (or returned inside `safeParse`) when input does
6
- * not match the validator's shape. `path` walks from the root to the offending
7
- * value, e.g. `["users", 0, "email"]`.
8
- *
9
- * A `LunoraError` subclass: carries `code: "VALIDATION_ERROR"` and `status: 400`
10
- * so the runtime/DO transport mappers surface it structurally (a request that
11
- * fails validation is a 400), while keeping the `name: "ValidationError"` and the
12
- * `path`/`expected`/`received` diagnostics.
13
- */
5
+ * Thrown by `validator.parse` (or returned inside `safeParse`) when input does
6
+ * not match the validator's shape. `path` walks from the root to the offending
7
+ * value, e.g. `["users", 0, "email"]`.
8
+ *
9
+ * A `LunoraError` subclass: carries `code: "VALIDATION_ERROR"` and `status: 400`
10
+ * so the runtime/DO transport mappers surface it structurally (a request that
11
+ * fails validation is a 400), while keeping the `name: "ValidationError"` and the
12
+ * `path`/`expected`/`received` diagnostics.
13
+ */
14
14
  declare class ValidationError extends LunoraError {
15
15
  readonly path: ValidationPath;
16
16
  readonly expected: string;
@@ -22,18 +22,18 @@ declare class ValidationError extends LunoraError {
22
22
  });
23
23
  }
24
24
  /**
25
- * Render a short, diagnostic description of a runtime value for the `received`
26
- * field of a {@link ValidationError}. Primitives carry their concrete (length-
27
- * capped) literal so messages distinguish `string "7"` from `number 7`;
28
- * non-plain objects carry their constructor name (e.g. `Date`) so a class
29
- * instance is not flattened to a bare `"object"`.
30
- *
31
- * Pass `{ literal: false }` to suppress the concrete primitive literal and
32
- * return only the type tag (`"string"`, `"number"`, `"bigint"`, …). This is used
33
- * on `.check()` refinement failures — where the value already passed its type
34
- * check — so a secret-bearing field (password, token) never surfaces its value
35
- * in the `ValidationError.message`/`received` that goes to the wire and logs.
36
- */
25
+ * Render a short, diagnostic description of a runtime value for the `received`
26
+ * field of a {@link ValidationError}. Primitives carry their concrete (length-
27
+ * capped) literal so messages distinguish `string "7"` from `number 7`;
28
+ * non-plain objects carry their constructor name (e.g. `Date`) so a class
29
+ * instance is not flattened to a bare `"object"`.
30
+ *
31
+ * Pass `{ literal: false }` to suppress the concrete primitive literal and
32
+ * return only the type tag (`"string"`, `"number"`, `"bigint"`, …). This is used
33
+ * on `.check()` refinement failures — where the value already passed its type
34
+ * check — so a secret-bearing field (password, token) never surfaces its value
35
+ * in the `ValidationError.message`/`received` that goes to the wire and logs.
36
+ */
37
37
  declare const describeValue: (value: unknown, options?: {
38
38
  literal?: boolean;
39
39
  }) => string;
@@ -43,22 +43,22 @@ type Id<TableName extends string> = string & {
43
43
  readonly __table: TableName;
44
44
  };
45
45
  /**
46
- * A JSON Schema fragment (Draft 2020-12 / OpenAPI 3.1 compatible). Intentionally
47
- * a loose bag — a `.check()`/`.meta()` caller contributes keywords like
48
- * `minLength`/`pattern`/`minimum` that `toJsonSchema` shallow-merges onto the
49
- * node for the enclosing validator. Mirrors the `JsonSchema` shape exported by
50
- * `./to-json-schema`; kept structurally identical and local so `v.ts` never
51
- * imports the converter and the two files stay decoupled.
52
- */
46
+ * A JSON Schema fragment (Draft 2020-12 / OpenAPI 3.1 compatible). Intentionally
47
+ * a loose bag — a `.check()`/`.meta()` caller contributes keywords like
48
+ * `minLength`/`pattern`/`minimum` that `toJsonSchema` shallow-merges onto the
49
+ * node for the enclosing validator. Mirrors the `JsonSchema` shape exported by
50
+ * `./to-json-schema`; kept structurally identical and local so `v.ts` never
51
+ * imports the converter and the two files stay decoupled.
52
+ */
53
53
  interface JsonSchemaFragment {
54
54
  [keyword: string]: unknown;
55
55
  }
56
56
  /**
57
- * Options for a {@link Validator.check} refinement. Lets a predicate carry both
58
- * a human-facing `message` and an introspectable JSON Schema `schema` fragment
59
- * (e.g. `{ minLength: 1 }`) so the constraint flows into `toJsonSchema`. The
60
- * legacy `.check(pred, "message")` string form remains supported.
61
- */
57
+ * Options for a {@link Validator.check} refinement. Lets a predicate carry both
58
+ * a human-facing `message` and an introspectable JSON Schema `schema` fragment
59
+ * (e.g. `{ minLength: 1 }`) so the constraint flows into `toJsonSchema`. The
60
+ * legacy `.check(pred, "message")` string form remains supported.
61
+ */
62
62
  interface CheckOptions {
63
63
  /** Failure message thrown on the `ValidationError` (default `"value matching refinement"`). */
64
64
  message?: string;
@@ -66,10 +66,10 @@ interface CheckOptions {
66
66
  schema?: JsonSchemaFragment;
67
67
  }
68
68
  /**
69
- * Options for {@link Validator.meta} — pure metadata with no runtime parsing
70
- * effect, used to enrich the emitted JSON Schema node (description + constraint
71
- * keywords) without attaching a predicate.
72
- */
69
+ * Options for {@link Validator.meta} — pure metadata with no runtime parsing
70
+ * effect, used to enrich the emitted JSON Schema node (description + constraint
71
+ * keywords) without attaching a predicate.
72
+ */
73
73
  interface MetaOptions {
74
74
  /** A human description merged onto this validator's JSON Schema node. */
75
75
  description?: string;
@@ -77,36 +77,36 @@ interface MetaOptions {
77
77
  schema?: JsonSchemaFragment;
78
78
  }
79
79
  /**
80
- * Runtime "kind" tag attached to every validator. Codegen and reflective tools
81
- * use this to inspect the shape without crawling the closure.
82
- */
80
+ * Runtime "kind" tag attached to every validator. Codegen and reflective tools
81
+ * use this to inspect the shape without crawling the closure.
82
+ */
83
83
  type ValidatorKind = "any" | "array" | "bigint" | "boolean" | "bytes" | "date" | "from" | "id" | "literal" | "null" | "number" | "object" | "optional" | "record" | "storage" | "string" | "timestamp" | "union";
84
84
  interface Validator<T = unknown> extends StandardSchemaV1<T, T> {
85
85
  readonly __type: T;
86
86
  /**
87
- * Attach a refinement predicate. The returned validator parses with the
88
- * original rules first; if the result satisfies `predicate` it passes
89
- * through, otherwise it throws a {@link ValidationError} carrying
90
- * `message` (default: `"value matching refinement"`). Multiple `.check()`
91
- * calls chain — every predicate must return true.
92
- *
93
- * The second argument may be a plain message string (legacy form) or a
94
- * {@link CheckOptions} object that additionally carries a JSON Schema
95
- * `schema` fragment (e.g. `{ minLength: 1 }`) reflected by `toJsonSchema`.
96
- *
97
- * Works in any context — argument validators, column validators, or
98
- * standalone — so it can encode invariants like
99
- * `v.number().check(n => n >= 0)` or
100
- * `v.string().check(s => s.length > 0, { message: "non-empty", schema: { minLength: 1 } })`.
101
- */
87
+ * Attach a refinement predicate. The returned validator parses with the
88
+ * original rules first; if the result satisfies `predicate` it passes
89
+ * through, otherwise it throws a {@link ValidationError} carrying
90
+ * `message` (default: `"value matching refinement"`). Multiple `.check()`
91
+ * calls chain — every predicate must return true.
92
+ *
93
+ * The second argument may be a plain message string (legacy form) or a
94
+ * {@link CheckOptions} object that additionally carries a JSON Schema
95
+ * `schema` fragment (e.g. `{ minLength: 1 }`) reflected by `toJsonSchema`.
96
+ *
97
+ * Works in any context — argument validators, column validators, or
98
+ * standalone — so it can encode invariants like
99
+ * `v.number().check(n => n >= 0)` or
100
+ * `v.string().check(s => s.length > 0, { message: "non-empty", schema: { minLength: 1 } })`.
101
+ */
102
102
  check: (predicate: (value: T) => boolean, options?: CheckOptions | string) => Validator<T>;
103
103
  readonly kind: ValidatorKind;
104
104
  /**
105
- * Attach pure metadata (description + JSON Schema constraint fragment) with
106
- * no effect on runtime parsing. The fragment is shallow-merged onto this
107
- * validator's emitted JSON Schema node, composing with any `.check()`
108
- * `schema` fragments (later wins on conflicting keys).
109
- */
105
+ * Attach pure metadata (description + JSON Schema constraint fragment) with
106
+ * no effect on runtime parsing. The fragment is shallow-merged onto this
107
+ * validator's emitted JSON Schema node, composing with any `.check()`
108
+ * `schema` fragments (later wins on conflicting keys).
109
+ */
110
110
  meta: (options: MetaOptions) => Validator<T>;
111
111
  parse: (value: unknown) => T;
112
112
  safeParse: (value: unknown) => {
@@ -120,10 +120,10 @@ interface Validator<T = unknown> extends StandardSchemaV1<T, T> {
120
120
  /** Extract the TS type a validator describes (the **select** type). */
121
121
  type Infer<V> = V extends Validator<infer T> ? T : never;
122
122
  /**
123
- * Column constraints/defaults collected from the `v.*` modifier chain used
124
- * inside `defineTable`. Inert in argument position. Persisted on the
125
- * validator's internal `_meta.column` and mirrored into codegen IR.
126
- */
123
+ * Column constraints/defaults collected from the `v.*` modifier chain used
124
+ * inside `defineTable`. Inert in argument position. Persisted on the
125
+ * validator's internal `_meta.column` and mirrored into codegen IR.
126
+ */
127
127
  interface ColumnMeta {
128
128
  /** `.$defaultFn(fn)` — default factory; field is optional on insert. */
129
129
  defaultFn?: () => unknown;
@@ -134,24 +134,24 @@ interface ColumnMeta {
134
134
  /** `.$onUpdateFn(fn)` — recomputed on every patch/replace. */
135
135
  onUpdateFn?: () => unknown;
136
136
  /**
137
- * `.serverDefault(fn)` — a SERVER-trusted value factory. Unlike
138
- * `.$defaultFn` (which only fills an absent field), this runs on every
139
- * insert/update and SILENTLY OVERWRITES any client-supplied value with
140
- * `fn({ auth })`, so the column is never client-controllable (e.g.
141
- * `ownerId`/`tenantId` stamped from `auth.userId`). Field is optional on
142
- * insert. The factory runs server-side with the resolved request auth.
143
- */
137
+ * `.serverDefault(fn)` — a SERVER-trusted value factory. Unlike
138
+ * `.$defaultFn` (which only fills an absent field), this runs on every
139
+ * insert/update and SILENTLY OVERWRITES any client-supplied value with
140
+ * `fn({ auth })`, so the column is never client-controllable (e.g.
141
+ * `ownerId`/`tenantId` stamped from `auth.userId`). Field is optional on
142
+ * insert. The factory runs server-side with the resolved request auth.
143
+ */
144
144
  serverDefault?: (context: ServerDefaultContext) => unknown;
145
145
  /** `.unique()` — synthesizes a UNIQUE index. */
146
146
  unique?: boolean;
147
147
  }
148
148
  /**
149
- * Context handed to a `.serverDefault(fn)` factory at write time. Carries the
150
- * resolved request identity so a column can be stamped from the caller
151
- * (`auth.userId`) rather than trusted from the client. Structurally mirrors the
152
- * `auth` slice of the server's procedure context without depending on
153
- * `@lunora/server`.
154
- */
149
+ * Context handed to a `.serverDefault(fn)` factory at write time. Carries the
150
+ * resolved request identity so a column can be stamped from the caller
151
+ * (`auth.userId`) rather than trusted from the client. Structurally mirrors the
152
+ * `auth` slice of the server's procedure context without depending on
153
+ * `@lunora/server`.
154
+ */
155
155
  interface ServerDefaultContext {
156
156
  readonly auth: {
157
157
  /** The raw identity claims, or `null` for the anonymous/no-resolver case. */
@@ -161,9 +161,9 @@ interface ServerDefaultContext {
161
161
  };
162
162
  }
163
163
  /**
164
- * Phantom carrier of a column's select/insert types. Never present at runtime;
165
- * `defineTable` reads it to derive `$inferSelect` / `$inferInsert`.
166
- */
164
+ * Phantom carrier of a column's select/insert types. Never present at runtime;
165
+ * `defineTable` reads it to derive `$inferSelect` / `$inferInsert`.
166
+ */
167
167
  interface Column<TSelect, TInsert> {
168
168
  /** Phantom carrier — type-only, never present at runtime. */
169
169
  readonly __column: {
@@ -172,11 +172,11 @@ interface Column<TSelect, TInsert> {
172
172
  };
173
173
  }
174
174
  /**
175
- * A {@link Validator} carrying the chainable column-modifier API. The factories
176
- * (`v.string()`, …) return this so modifiers are available inside `defineTable`.
177
- * `TSelect` is the read type; `TInsert` is the write type (modifiers may make it
178
- * `| undefined`, marking the field optional on insert).
179
- */
175
+ * A {@link Validator} carrying the chainable column-modifier API. The factories
176
+ * (`v.string()`, …) return this so modifiers are available inside `defineTable`.
177
+ * `TSelect` is the read type; `TInsert` is the write type (modifiers may make it
178
+ * `| undefined`, marking the field optional on insert).
179
+ */
180
180
  interface ColumnValidator<TSelect, TInsert> extends Column<TSelect, TInsert>, Validator<TSelect> {
181
181
  /** Default factory applied in the write layer; field becomes optional on insert. */
182
182
  $defaultFn: (function_: () => TSelect) => ColumnValidator<TSelect, TInsert | undefined>;
@@ -193,20 +193,20 @@ interface ColumnValidator<TSelect, TInsert> extends Column<TSelect, TInsert>, Va
193
193
  /** Allow SQL NULL — widens the select type to `T | null`. */
194
194
  nullable: () => ColumnValidator<null | TSelect, null | TInsert>;
195
195
  /**
196
- * Stamp this column SERVER-side from the request auth on every write,
197
- * overwriting any client-supplied value. The field becomes optional on
198
- * insert (the server fills it). Use for owner/tenant columns that must never
199
- * be client-controllable — e.g. `v.string().serverDefault(({ auth }) => auth.userId)`.
200
- */
196
+ * Stamp this column SERVER-side from the request auth on every write,
197
+ * overwriting any client-supplied value. The field becomes optional on
198
+ * insert (the server fills it). Use for owner/tenant columns that must never
199
+ * be client-controllable — e.g. `v.string().serverDefault(({ auth }) => auth.userId)`.
200
+ */
201
201
  serverDefault: (function_: (context: ServerDefaultContext) => TSelect) => ColumnValidator<TSelect, TInsert | undefined>;
202
202
  /** Enforce a UNIQUE constraint (synthesizes a unique index). */
203
203
  unique: () => ColumnValidator<TSelect, TInsert>;
204
204
  }
205
205
  /**
206
- * A time-valued {@link ColumnValidator} (epoch milliseconds). Adds
207
- * {@link TimestampColumnValidator.defaultNow} so the field can default to the
208
- * insert-time clock.
209
- */
206
+ * A time-valued {@link ColumnValidator} (epoch milliseconds). Adds
207
+ * {@link TimestampColumnValidator.defaultNow} so the field can default to the
208
+ * insert-time clock.
209
+ */
210
210
  interface TimestampColumnValidator extends ColumnValidator<number, number> {
211
211
  /** Default to the current epoch-ms (`Date.now()`) at insert time; field becomes optional on insert. */
212
212
  defaultNow: () => ColumnValidator<number, number | undefined>;
@@ -216,13 +216,13 @@ type InferSelect<V> = V extends Validator<infer T> ? T : never;
216
216
  /** The type a validator/column accepts on **insert** (writes). */
217
217
  type InferInsert<V> = V extends Column<unknown, infer I> ? I : V extends Validator<infer T> ? T : never;
218
218
  /** Derive the read shape of a table's column map. */
219
- type SelectShape<S extends Record<string, Validator>> = { [K in keyof S]: InferSelect<S[K]> };
219
+ type SelectShape<S extends Record<string, Validator>> = { [K in keyof S]: InferSelect<S[K]>; };
220
220
  /**
221
- * Derive the write shape of a table's column map. Columns whose insert type
222
- * includes `undefined` (via `.default()` / `.$defaultFn()` / `v.optional`)
223
- * become optional keys.
224
- */
225
- type InsertShape<S extends Record<string, Validator>> = { [K in keyof S as undefined extends InferInsert<S[K]> ? K : never]?: Exclude<InferInsert<S[K]>, undefined> } & { [K in keyof S as undefined extends InferInsert<S[K]> ? never : K]: InferInsert<S[K]> };
221
+ * Derive the write shape of a table's column map. Columns whose insert type
222
+ * includes `undefined` (via `.default()` / `.$defaultFn()` / `v.optional`)
223
+ * become optional keys.
224
+ */
225
+ type InsertShape<S extends Record<string, Validator>> = { [K in keyof S as undefined extends InferInsert<S[K]> ? K : never]?: Exclude<InferInsert<S[K]>, undefined>; } & { [K in keyof S as undefined extends InferInsert<S[K]> ? never : K]: InferInsert<S[K]>; };
226
226
  declare const string: () => ColumnValidator<string, string>;
227
227
  declare const number: () => ColumnValidator<number, number>;
228
228
  /** Epoch-millisecond timestamp (`number`). Pair with `.defaultNow()` for an insert-time clock. */
@@ -235,77 +235,77 @@ declare const nullValidator: () => ColumnValidator<null, null>;
235
235
  declare const bytes: () => ColumnValidator<ArrayBuffer, ArrayBuffer>;
236
236
  declare const id: <TableName extends string>(tableName: TableName) => ColumnValidator<Id<TableName>, Id<TableName>>;
237
237
  /**
238
- * A reference to a stored R2 object: the column holds the object's **key** (a
239
- * string), the same key `@lunora/storage` puts/gets by. Functionally it parses
240
- * like `v.string()`, but the distinct `"storage"` kind lets codegen and the
241
- * studio join the data model to R2 — the file browser uses it to show which
242
- * record owns a file and to flag orphaned objects no row references. The
243
- * optional `bucket` names the typed bucket the key lives in (for app-context
244
- * signed URLs); omit it for the app's default bucket.
245
- */
238
+ * A reference to a stored R2 object: the column holds the object's **key** (a
239
+ * string), the same key `@lunora/storage` puts/gets by. Functionally it parses
240
+ * like `v.string()`, but the distinct `"storage"` kind lets codegen and the
241
+ * studio join the data model to R2 — the file browser uses it to show which
242
+ * record owns a file and to flag orphaned objects no row references. The
243
+ * optional `bucket` names the typed bucket the key lives in (for app-context
244
+ * signed URLs); omit it for the app's default bucket.
245
+ */
246
246
  declare const storage: (bucket?: string) => ColumnValidator<string, string>;
247
247
  declare const literal: <T extends bigint | boolean | number | string | null>(literalValue: T) => ColumnValidator<T, T>;
248
248
  declare const array: <V extends Validator>(inner: V) => ColumnValidator<Infer<V>[], Infer<V>[]>;
249
249
  /**
250
- * Split a value-type map into optional + required keys: any member whose value
251
- * type includes `undefined` becomes an optional key. The single optionality rule
252
- * shared by object-shape inference ({@link ObjectShapeType}) and args-map
253
- * inference (`InferValidatorMap` in `./validator-map`), so the two can never
254
- * drift. (`InsertShape` stays separate — it additionally `Exclude`s `undefined`
255
- * from the optional value, a deliberate insert-type difference.)
256
- */
257
- type OptionalizeShape<M> = { [K in keyof M as undefined extends M[K] ? K : never]?: M[K] } & { [K in keyof M as undefined extends M[K] ? never : K]: M[K] };
250
+ * Split a value-type map into optional + required keys: any member whose value
251
+ * type includes `undefined` becomes an optional key. The single optionality rule
252
+ * shared by object-shape inference ({@link ObjectShapeType}) and args-map
253
+ * inference (`InferValidatorMap` in `./validator-map`), so the two can never
254
+ * drift. (`InsertShape` stays separate — it additionally `Exclude`s `undefined`
255
+ * from the optional value, a deliberate insert-type difference.)
256
+ */
257
+ type OptionalizeShape<M> = { [K in keyof M as undefined extends M[K] ? K : never]?: M[K]; } & { [K in keyof M as undefined extends M[K] ? never : K]: M[K]; };
258
258
  type ObjectShape = Record<string, Validator>;
259
- type ObjectShapeType<S extends ObjectShape> = OptionalizeShape<{ [K in keyof S]: Infer<S[K]> }>;
259
+ type ObjectShapeType<S extends ObjectShape> = OptionalizeShape<{ [K in keyof S]: Infer<S[K]>; }>;
260
260
  declare const objectValidator: <S extends ObjectShape>(shape: S) => ColumnValidator<ObjectShapeType<S>, ObjectShapeType<S>>;
261
261
  declare const record: <K extends Validator<string>, V extends Validator>(keyValidator: K, valueValidator: V) => ColumnValidator<Record<Infer<K>, Infer<V>>, Record<Infer<K>, Infer<V>>>;
262
262
  declare const union: <Vs extends ReadonlyArray<Validator>>(...members: Vs) => ColumnValidator<Infer<Vs[number]>, Infer<Vs[number]>>;
263
263
  declare const optional: <V extends Validator>(inner: V) => ColumnValidator<Infer<V> | undefined, Infer<V> | undefined>;
264
264
  declare const any: () => ColumnValidator<unknown, unknown>;
265
265
  /**
266
- * Infer the output type of a Standard Schema v1 object. When the schema omits
267
- * `~standard.types` (it is optional in the spec), falls back to `unknown` so
268
- * callers always get a usable type rather than `never`.
269
- */
266
+ * Infer the output type of a Standard Schema v1 object. When the schema omits
267
+ * `~standard.types` (it is optional in the spec), falls back to `unknown` so
268
+ * callers always get a usable type rather than `never`.
269
+ */
270
270
  type InferStandardOutput<S extends StandardSchemaV1> = S["~standard"]["types"] extends {
271
271
  output: infer O;
272
272
  } ? O : unknown;
273
273
  /**
274
- * Wrap any Standard Schema v1 validator (`zod`, `valibot`, `arktype`, …) so it
275
- * can be used as an **args** validator in `query`/`mutation`/`action`. The
276
- * wrapped validator's output type is inferred from `~standard.types.output`
277
- * when declared; falls back to `unknown` when the schema omits the types field.
278
- *
279
- * **Args-only.** `v.from(...)` validators must not be used as table columns —
280
- * `defineTable` checks the `kind` and throws a clear error if you try.
281
- *
282
- * **Sync-only.** Standard Schema allows async `validate`; Lunora args
283
- * validation is synchronous and throws when a Promise is returned.
284
- */
274
+ * Wrap any Standard Schema v1 validator (`zod`, `valibot`, `arktype`, …) so it
275
+ * can be used as an **args** validator in `query`/`mutation`/`action`. The
276
+ * wrapped validator's output type is inferred from `~standard.types.output`
277
+ * when declared; falls back to `unknown` when the schema omits the types field.
278
+ *
279
+ * **Args-only.** `v.from(...)` validators must not be used as table columns —
280
+ * `defineTable` checks the `kind` and throws a clear error if you try.
281
+ *
282
+ * **Sync-only.** Standard Schema allows async `validate`; Lunora args
283
+ * validation is synchronous and throws when a Promise is returned.
284
+ */
285
285
  declare const from: <S extends StandardSchemaV1>(schema: S) => ColumnValidator<InferStandardOutput<S>, InferStandardOutput<S>>;
286
286
  /**
287
- * True when `validator` is `v.from(...)` or structurally wraps one through
288
- * `v.optional` / `v.array` / `v.object` / `v.record` / `v.union`. `defineTable`
289
- * uses it to reject Standard-Schema-backed validators anywhere in a column —
290
- * not just at the top level — since they are args-only and have no SQL column
291
- * type. The nested children live on the validator's `_meta` (`inner`, `shape`,
292
- * `members`, `keyValidator`/`valueValidator`) and are themselves validators.
293
- */
287
+ * True when `validator` is `v.from(...)` or structurally wraps one through
288
+ * `v.optional` / `v.array` / `v.object` / `v.record` / `v.union`. `defineTable`
289
+ * uses it to reject Standard-Schema-backed validators anywhere in a column —
290
+ * not just at the top level — since they are args-only and have no SQL column
291
+ * type. The nested children live on the validator's `_meta` (`inner`, `shape`,
292
+ * `members`, `keyValidator`/`valueValidator`) and are themselves validators.
293
+ */
294
294
  declare const isOrWrapsFromValidator: (validator: Validator) => boolean;
295
295
  /**
296
- * The inner validator wrapped by `v.optional(inner)`, or `undefined` for any
297
- * other validator. The nested child lives on the validator's internal `_meta`
298
- * bag; this accessor keeps that knowledge inside `@lunora/values` (the package
299
- * that owns validator internals) so consumers don't reach into `_meta`
300
- * themselves. Used by `@lunora/server`'s `defineEnv` to coerce through a leading
301
- * `v.optional(...)`.
302
- * @returns The inner validator if `v.optional(...)`, otherwise `undefined`.
303
- */
296
+ * The inner validator wrapped by `v.optional(inner)`, or `undefined` for any
297
+ * other validator. The nested child lives on the validator's internal `_meta`
298
+ * bag; this accessor keeps that knowledge inside `@lunora/values` (the package
299
+ * that owns validator internals) so consumers don't reach into `_meta`
300
+ * themselves. Used by `@lunora/server`'s `defineEnv` to coerce through a leading
301
+ * `v.optional(...)`.
302
+ * @returns The inner validator if `v.optional(...)`, otherwise `undefined`.
303
+ */
304
304
  declare const optionalInner: (validator: Validator) => Validator | undefined;
305
305
  /**
306
- * Validator/codec namespace. Each factory returns a {@link Validator} with a
307
- * runtime `parse`/`safeParse` plus a phantom `__type` field for inference.
308
- */
306
+ * Validator/codec namespace. Each factory returns a {@link Validator} with a
307
+ * runtime `parse`/`safeParse` plus a phantom `__type` field for inference.
308
+ */
309
309
  declare const v: {
310
310
  any: typeof any;
311
311
  array: typeof array;
@@ -327,35 +327,35 @@ declare const v: {
327
327
  union: typeof union;
328
328
  };
329
329
  /**
330
- * A JSON Schema node (Draft 2020-12 / OpenAPI 3.1 compatible). Intentionally a
331
- * loose bag — Lunora only emits a known subset, but consumers (OpenAPI/OpenRPC
332
- * builders, Swagger UI, form generators) treat it as an opaque schema object.
333
- */
330
+ * A JSON Schema node (Draft 2020-12 / OpenAPI 3.1 compatible). Intentionally a
331
+ * loose bag — Lunora only emits a known subset, but consumers (OpenAPI/OpenRPC
332
+ * builders, Swagger UI, form generators) treat it as an opaque schema object.
333
+ */
334
334
  interface JsonSchema {
335
335
  [keyword: string]: unknown;
336
336
  }
337
337
  /**
338
- * Structural reader over a validator-like node. The shared mapping algorithm
339
- * ({@link jsonSchemaFromNode}) is parameterized by this interface so the same
340
- * switch/recursion serves both inputs Lunora maps to JSON Schema: the runtime
341
- * `@lunora/values` validator (children + metadata live on `_meta`), and the
342
- * build-time validator IR consumed by codegen (children are plain fields, with
343
- * no runtime metadata — so `constraints`/`isNullable` may be inert there).
344
- *
345
- * A reader normalizes a `TNode` to the small set of children/leaves the mapper
346
- * recurses over. Composite accessors (`inner`/`shape`/`members`/`valueChild`)
347
- * return the same `TNode` type so the mapper can recurse uniformly; leaf concerns
348
- * that differ between the two sources — how a literal's `const` is computed,
349
- * whether a `.check()`/`.meta()` constraint fragment exists, whether `.nullable()`
350
- * was applied — are delegated wholesale to the reader.
351
- */
338
+ * Structural reader over a validator-like node. The shared mapping algorithm
339
+ * ({@link jsonSchemaFromNode}) is parameterized by this interface so the same
340
+ * switch/recursion serves both inputs Lunora maps to JSON Schema: the runtime
341
+ * `@lunora/values` validator (children + metadata live on `_meta`), and the
342
+ * build-time validator IR consumed by codegen (children are plain fields, with
343
+ * no runtime metadata — so `constraints`/`isNullable` may be inert there).
344
+ *
345
+ * A reader normalizes a `TNode` to the small set of children/leaves the mapper
346
+ * recurses over. Composite accessors (`inner`/`shape`/`members`/`valueChild`)
347
+ * return the same `TNode` type so the mapper can recurse uniformly; leaf concerns
348
+ * that differ between the two sources — how a literal's `const` is computed,
349
+ * whether a `.check()`/`.meta()` constraint fragment exists, whether `.nullable()`
350
+ * was applied — are delegated wholesale to the reader.
351
+ */
352
352
  interface SchemaNodeReader<TNode> {
353
353
  /**
354
- * The `.check()`/`.meta()` JSON Schema fragment to shallow-merge onto the
355
- * node, or `undefined` when none (the IR side never carries one). Constraint
356
- * keys win over the base on conflict so a refinement can tighten — never
357
- * silently weaken — the schema.
358
- */
354
+ * The `.check()`/`.meta()` JSON Schema fragment to shallow-merge onto the
355
+ * node, or `undefined` when none (the IR side never carries one). Constraint
356
+ * keys win over the base on conflict so a refinement can tighten — never
357
+ * silently weaken — the schema.
358
+ */
359
359
  constraints: (node: TNode) => JsonSchema | undefined;
360
360
  /** Inner child of an `array`/`optional` node. May be absent on the IR side. */
361
361
  inner: (node: TNode) => TNode | undefined;
@@ -364,10 +364,10 @@ interface SchemaNodeReader<TNode> {
364
364
  /** Discriminating validator kind. */
365
365
  kind: (node: TNode) => ValidatorKind;
366
366
  /**
367
- * The JSON Schema `const` fragment for a `literal` node. Computed differently
368
- * per source — runtime reads the live `_meta.value`; the IR parses verbatim
369
- * source text — so the reader owns it entirely.
370
- */
367
+ * The JSON Schema `const` fragment for a `literal` node. Computed differently
368
+ * per source — runtime reads the live `_meta.value`; the IR parses verbatim
369
+ * source text — so the reader owns it entirely.
370
+ */
371
371
  literalSchema: (node: TNode) => JsonSchema;
372
372
  /** Member nodes of a `union`. */
373
373
  members: (node: TNode) => ReadonlyArray<TNode>;
@@ -379,109 +379,109 @@ interface SchemaNodeReader<TNode> {
379
379
  valueChild: (node: TNode) => TNode | undefined;
380
380
  }
381
381
  /**
382
- * The single validator→JSON-Schema mapping algorithm, shared by the runtime
383
- * `toJsonSchema` (over `@lunora/values` validators) and codegen's IR-backed
384
- * mapper. It walks a node recursively via the supplied {@link SchemaNodeReader},
385
- * so nested objects/arrays/unions/records are fully expanded (never collapsed to
386
- * one level).
387
- *
388
- * `date`/`timestamp` are epoch-millisecond numbers in Lunora (not ISO strings),
389
- * so they schema as integers; `bigint` schemas as an int64 (JSON has no bigint
390
- * type, so `format: int64` is the conventional OpenAPI carrier); `bytes` is an
391
- * `ArrayBuffer`, surfaced as base64 per JSON Schema 2020-12 content encoding.
392
- *
393
- * A `.check()`/`.meta()` JSON Schema fragment (when the reader exposes one) is
394
- * shallow-merged onto the node — constraint keys win on conflict. A `.nullable()`
395
- * node widens to also accept `null`; constraints describe the underlying value,
396
- * so they ride inside the non-null branch rather than on the wrapping `anyOf`.
397
- */
382
+ * The single validator→JSON-Schema mapping algorithm, shared by the runtime
383
+ * `toJsonSchema` (over `@lunora/values` validators) and codegen's IR-backed
384
+ * mapper. It walks a node recursively via the supplied {@link SchemaNodeReader},
385
+ * so nested objects/arrays/unions/records are fully expanded (never collapsed to
386
+ * one level).
387
+ *
388
+ * `date`/`timestamp` are epoch-millisecond numbers in Lunora (not ISO strings),
389
+ * so they schema as integers; `bigint` schemas as an int64 (JSON has no bigint
390
+ * type, so `format: int64` is the conventional OpenAPI carrier); `bytes` is an
391
+ * `ArrayBuffer`, surfaced as base64 per JSON Schema 2020-12 content encoding.
392
+ *
393
+ * A `.check()`/`.meta()` JSON Schema fragment (when the reader exposes one) is
394
+ * shallow-merged onto the node — constraint keys win on conflict. A `.nullable()`
395
+ * node widens to also accept `null`; constraints describe the underlying value,
396
+ * so they ride inside the non-null branch rather than on the wrapping `anyOf`.
397
+ */
398
398
  declare const jsonSchemaFromNode: <TNode>(node: TNode, reader: SchemaNodeReader<TNode>) => JsonSchema;
399
399
  /**
400
- * Build `{ type: "object", properties, required, additionalProperties: false }`
401
- * from a node shape. A `v.optional(...)` property is the only thing that drops
402
- * out of `required`; every other property is required.
403
- */
400
+ * Build `{ type: "object", properties, required, additionalProperties: false }`
401
+ * from a node shape. A `v.optional(...)` property is the only thing that drops
402
+ * out of `required`; every other property is required.
403
+ */
404
404
  declare const objectSchemaFromNodes: <TNode>(shape: Record<string, TNode>, reader: SchemaNodeReader<TNode>) => JsonSchema;
405
405
  /**
406
- * Convert a single `@lunora/values` validator to a JSON Schema node (Draft
407
- * 2020-12 / OpenAPI 3.1). A thin wrapper over the shared {@link jsonSchemaFromNode}
408
- * core with the runtime {@link validatorReader}; see that core for the full
409
- * kind→schema mapping (date/timestamp → epoch-ms integer, bigint → int64, bytes →
410
- * base64, id → annotated string, literal → `const`, optionality via the parent
411
- * `required` list, `.nullable()` widening, `.check()`/`.meta()` constraint merge).
412
- */
406
+ * Convert a single `@lunora/values` validator to a JSON Schema node (Draft
407
+ * 2020-12 / OpenAPI 3.1). A thin wrapper over the shared {@link jsonSchemaFromNode}
408
+ * core with the runtime {@link validatorReader}; see that core for the full
409
+ * kind→schema mapping (date/timestamp → epoch-ms integer, bigint → int64, bytes →
410
+ * base64, id → annotated string, literal → `const`, optionality via the parent
411
+ * `required` list, `.nullable()` widening, `.check()`/`.meta()` constraint merge).
412
+ */
413
413
  declare const toJsonSchema: (validator: Validator) => JsonSchema;
414
414
  /**
415
- * Convert a function's argument validators (a name-to-validator map) into a
416
- * single JSON Schema object. Non-`optional` arguments are `required`; the result
417
- * is the request `params`/`args` schema an OpenAPI operation or OpenRPC method
418
- * advertises. An empty arg map yields an empty (but valid) object schema.
419
- */
415
+ * Convert a function's argument validators (a name-to-validator map) into a
416
+ * single JSON Schema object. Non-`optional` arguments are `required`; the result
417
+ * is the request `params`/`args` schema an OpenAPI operation or OpenRPC method
418
+ * advertises. An empty arg map yields an empty (but valid) object schema.
419
+ */
420
420
  declare const argsToJsonSchema: (args: Record<string, Validator>) => JsonSchema;
421
421
  /** Map of validators describing a record of named fields (a function's args, a step's args, an HTTP query/body/params). */
422
422
  type ValidatorMap = Record<string, Validator>;
423
423
  /**
424
- * Infer the object type from a {@link ValidatorMap} — optional validators
425
- * (`v.optional`) become optional keys. Shares the single optionality rule with
426
- * `ObjectShapeType` via {@link OptionalizeShape}, so args-map and object-shape
427
- * inference can never drift.
428
- */
429
- type InferValidatorMap<A extends ValidatorMap> = OptionalizeShape<{ [K in keyof A]: Infer<A[K]> }>;
424
+ * Infer the object type from a {@link ValidatorMap} — optional validators
425
+ * (`v.optional`) become optional keys. Shares the single optionality rule with
426
+ * `ObjectShapeType` via {@link OptionalizeShape}, so args-map and object-shape
427
+ * inference can never drift.
428
+ */
429
+ type InferValidatorMap<A extends ValidatorMap> = OptionalizeShape<{ [K in keyof A]: Infer<A[K]>; }>;
430
430
  /**
431
- * A precompiled fast-path parser for one {@link ValidatorMap}. Returns the fully
432
- * built, validated record on a confident success, or the {@link DEFER_VALIDATION}
433
- * sentinel to hand the input back to the interpreted parser.
434
- *
435
- * The contract is soundness, not completeness: a compiled parser may return
436
- * {@link DEFER_VALIDATION} for any input it is not certain about (the interpreted
437
- * path then runs and either succeeds or throws the canonical error), but it must
438
- * NEVER return a built record for input the interpreted parser would reject, and
439
- * the record it returns must be byte-for-byte what the interpreted parser would
440
- * have produced. This lets `@lunora/codegen` emit zero-allocation structural
441
- * checks (the common case) while every error message and every tricky validator
442
- * still flows through the single interpreted implementation below — so error
443
- * contracts can never drift.
444
- *
445
- * The `source` parameter is intentionally `any`: the codegen-emitted body is
446
- * plain JavaScript (no type annotations — it must also be loadable via
447
- * `new Function` in the compiler's differential tests) that index-walks the input
448
- * to arbitrary depth, which strict TypeScript forbids on `unknown`/`object`. An
449
- * `any` input lets the emitted structural checks type-check cleanly while the
450
- * RESULT stays strongly typed; soundness is enforced by the differential test
451
- * harness, not the input type.
452
- */
431
+ * A precompiled fast-path parser for one {@link ValidatorMap}. Returns the fully
432
+ * built, validated record on a confident success, or the {@link DEFER_VALIDATION}
433
+ * sentinel to hand the input back to the interpreted parser.
434
+ *
435
+ * The contract is soundness, not completeness: a compiled parser may return
436
+ * {@link DEFER_VALIDATION} for any input it is not certain about (the interpreted
437
+ * path then runs and either succeeds or throws the canonical error), but it must
438
+ * NEVER return a built record for input the interpreted parser would reject, and
439
+ * the record it returns must be byte-for-byte what the interpreted parser would
440
+ * have produced. This lets `@lunora/codegen` emit zero-allocation structural
441
+ * checks (the common case) while every error message and every tricky validator
442
+ * still flows through the single interpreted implementation below — so error
443
+ * contracts can never drift.
444
+ *
445
+ * The `source` parameter is intentionally `any`: the codegen-emitted body is
446
+ * plain JavaScript (no type annotations — it must also be loadable via
447
+ * `new Function` in the compiler's differential tests) that index-walks the input
448
+ * to arbitrary depth, which strict TypeScript forbids on `unknown`/`object`. An
449
+ * `any` input lets the emitted structural checks type-check cleanly while the
450
+ * RESULT stays strongly typed; soundness is enforced by the differential test
451
+ * harness, not the input type.
452
+ */
453
453
  type CompiledValidatorMap = (source: any) => Record<string, unknown> | typeof DEFER_VALIDATION;
454
454
  /**
455
- * Sentinel a {@link CompiledValidatorMap} returns to defer to the interpreted
456
- * parser. A unique symbol (never a valid parse result — {@link parseValidatorMap}
457
- * always yields a record) so the seam can distinguish "compiled handled it" from
458
- * "compiled bailed" with a single identity check and no per-call allocation.
459
- */
455
+ * Sentinel a {@link CompiledValidatorMap} returns to defer to the interpreted
456
+ * parser. A unique symbol (never a valid parse result — {@link parseValidatorMap}
457
+ * always yields a record) so the seam can distinguish "compiled handled it" from
458
+ * "compiled bailed" with a single identity check and no per-call allocation.
459
+ */
460
460
  declare const DEFER_VALIDATION: unique symbol;
461
461
  /**
462
- * Install a compiled fast-path parser for `validators`. Idempotent-ish: a second
463
- * install overwrites the first (codegen emits each map once, so this only matters
464
- * if a host installs by hand). See {@link CompiledValidatorMap} for the contract
465
- * the parser must honour.
466
- */
462
+ * Install a compiled fast-path parser for `validators`. Idempotent-ish: a second
463
+ * install overwrites the first (codegen emits each map once, so this only matters
464
+ * if a host installs by hand). See {@link CompiledValidatorMap} for the contract
465
+ * the parser must honour.
466
+ */
467
467
  declare const installCompiledValidatorMap: (validators: object, compiled: CompiledValidatorMap) => void;
468
468
  /**
469
- * Validate each declared field of `source` through its validator, re-wrapping
470
- * any {@link ValidationError} with a `label.&lt;key>:` prefix and the rebuilt path
471
- * `[key, ...error.path]` so the failure points at the offending field. Optional
472
- * fields absent from the source are skipped (so `v.optional` passes and a
473
- * required validator fails on `undefined`).
474
- *
475
- * The single arg-/field-parsing implementation shared across the framework — the
476
- * procedure builder (label `args`), the HTTP route builder (`searchParams` /
477
- * `body` / `params`), and `@lunora/workflow`'s reusable steps (`step args`) — so
478
- * the error-prefixing and optional-skip semantics can't drift apart. The `label`
479
- * is the only thing each caller varies.
480
- *
481
- * When a codegen-emitted {@link CompiledValidatorMap} is installed for this exact
482
- * `validators` object, the fast path runs first; it either returns the finished
483
- * record (a confident success — the common case) or {@link DEFER_VALIDATION}, in
484
- * which case the interpreted loop below runs and owns the result (and any error).
485
- */
469
+ * Validate each declared field of `source` through its validator, re-wrapping
470
+ * any {@link ValidationError} with a `label.&lt;key>:` prefix and the rebuilt path
471
+ * `[key, ...error.path]` so the failure points at the offending field. Optional
472
+ * fields absent from the source are skipped (so `v.optional` passes and a
473
+ * required validator fails on `undefined`).
474
+ *
475
+ * The single arg-/field-parsing implementation shared across the framework — the
476
+ * procedure builder (label `args`), the HTTP route builder (`searchParams` /
477
+ * `body` / `params`), and `@lunora/workflow`'s reusable steps (`step args`) — so
478
+ * the error-prefixing and optional-skip semantics can't drift apart. The `label`
479
+ * is the only thing each caller varies.
480
+ *
481
+ * When a codegen-emitted {@link CompiledValidatorMap} is installed for this exact
482
+ * `validators` object, the fast path runs first; it either returns the finished
483
+ * record (a confident success — the common case) or {@link DEFER_VALIDATION}, in
484
+ * which case the interpreted loop below runs and owns the result (and any error).
485
+ */
486
486
  declare const parseValidatorMap: (validators: ValidatorMap, source: Record<string, unknown>, label: string) => Record<string, unknown>;
487
487
  export { type CheckOptions, type Column, type ColumnMeta, type ColumnValidator, type CompiledValidatorMap, DEFER_VALIDATION, type Id, type Infer, type InferInsert, type InferSelect, type InferStandardOutput, type InferValidatorMap, type InsertShape, type JsonSchema, type JsonSchemaFragment, type MetaOptions, type SchemaNodeReader, type SelectShape, type ServerDefaultContext, type TimestampColumnValidator, ValidationError, type ValidationPath, type Validator, type ValidatorKind, type ValidatorMap, argsToJsonSchema, describeValue, formatPath, installCompiledValidatorMap, isOrWrapsFromValidator, jsonSchemaFromNode, objectSchemaFromNodes, optionalInner, parseValidatorMap, toJsonSchema, v };