@lunora/values 1.0.0-alpha.5 → 1.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.mjs +3 -7
- package/dist/packem_shared/{DEFER_VALIDATION-Cpy5SwBo.mjs → DEFER_VALIDATION-CIKr17sW.mjs} +2 -2
- package/dist/packem_shared/{ValidationError-CdSwhYHu.mjs → ValidationError-CoyFtkxj.mjs} +18 -14
- package/dist/packem_shared/{isOrWrapsFromValidator-Bg1o5VFG.mjs → isOrWrapsFromValidator-UlWeMhFL.mjs} +5 -5
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -27,8 +27,16 @@ declare class ValidationError extends LunoraError {
|
|
|
27
27
|
* capped) literal so messages distinguish `string "7"` from `number 7`;
|
|
28
28
|
* non-plain objects carry their constructor name (e.g. `Date`) so a class
|
|
29
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.
|
|
30
36
|
*/
|
|
31
|
-
declare const describeValue: (value: unknown
|
|
37
|
+
declare const describeValue: (value: unknown, options?: {
|
|
38
|
+
literal?: boolean;
|
|
39
|
+
}) => string;
|
|
32
40
|
declare const formatPath: (path: ValidationPath) => string;
|
|
33
41
|
/** Branded id type, e.g. `Id<"users">`. */
|
|
34
42
|
type Id<TableName extends string> = string & {
|
|
@@ -238,8 +246,17 @@ declare const id: <TableName extends string>(tableName: TableName) => ColumnVali
|
|
|
238
246
|
declare const storage: (bucket?: string) => ColumnValidator<string, string>;
|
|
239
247
|
declare const literal: <T extends bigint | boolean | number | string | null>(literalValue: T) => ColumnValidator<T, T>;
|
|
240
248
|
declare const array: <V extends Validator>(inner: V) => ColumnValidator<Infer<V>[], Infer<V>[]>;
|
|
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] };
|
|
241
258
|
type ObjectShape = Record<string, Validator>;
|
|
242
|
-
type ObjectShapeType<S extends ObjectShape> =
|
|
259
|
+
type ObjectShapeType<S extends ObjectShape> = OptionalizeShape<{ [K in keyof S]: Infer<S[K]> }>;
|
|
243
260
|
declare const objectValidator: <S extends ObjectShape>(shape: S) => ColumnValidator<ObjectShapeType<S>, ObjectShapeType<S>>;
|
|
244
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>>>;
|
|
245
262
|
declare const union: <Vs extends ReadonlyArray<Validator>>(...members: Vs) => ColumnValidator<Infer<Vs[number]>, Infer<Vs[number]>>;
|
|
@@ -403,8 +420,13 @@ declare const toJsonSchema: (validator: Validator) => JsonSchema;
|
|
|
403
420
|
declare const argsToJsonSchema: (args: Record<string, Validator>) => JsonSchema;
|
|
404
421
|
/** Map of validators describing a record of named fields (a function's args, a step's args, an HTTP query/body/params). */
|
|
405
422
|
type ValidatorMap = Record<string, Validator>;
|
|
406
|
-
/**
|
|
407
|
-
|
|
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]> }>;
|
|
408
430
|
/**
|
|
409
431
|
* A precompiled fast-path parser for one {@link ValidatorMap}. Returns the fully
|
|
410
432
|
* built, validated record on a confident success, or the {@link DEFER_VALIDATION}
|
|
@@ -462,5 +484,4 @@ declare const installCompiledValidatorMap: (validators: object, compiled: Compil
|
|
|
462
484
|
* which case the interpreted loop below runs and owns the result (and any error).
|
|
463
485
|
*/
|
|
464
486
|
declare const parseValidatorMap: (validators: ValidatorMap, source: Record<string, unknown>, label: string) => Record<string, unknown>;
|
|
465
|
-
|
|
466
|
-
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, VERSION, ValidationError, type ValidationPath, type Validator, type ValidatorKind, type ValidatorMap, argsToJsonSchema, describeValue, formatPath, installCompiledValidatorMap, isOrWrapsFromValidator, jsonSchemaFromNode, objectSchemaFromNodes, optionalInner, parseValidatorMap, toJsonSchema, v };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -27,8 +27,16 @@ declare class ValidationError extends LunoraError {
|
|
|
27
27
|
* capped) literal so messages distinguish `string "7"` from `number 7`;
|
|
28
28
|
* non-plain objects carry their constructor name (e.g. `Date`) so a class
|
|
29
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.
|
|
30
36
|
*/
|
|
31
|
-
declare const describeValue: (value: unknown
|
|
37
|
+
declare const describeValue: (value: unknown, options?: {
|
|
38
|
+
literal?: boolean;
|
|
39
|
+
}) => string;
|
|
32
40
|
declare const formatPath: (path: ValidationPath) => string;
|
|
33
41
|
/** Branded id type, e.g. `Id<"users">`. */
|
|
34
42
|
type Id<TableName extends string> = string & {
|
|
@@ -238,8 +246,17 @@ declare const id: <TableName extends string>(tableName: TableName) => ColumnVali
|
|
|
238
246
|
declare const storage: (bucket?: string) => ColumnValidator<string, string>;
|
|
239
247
|
declare const literal: <T extends bigint | boolean | number | string | null>(literalValue: T) => ColumnValidator<T, T>;
|
|
240
248
|
declare const array: <V extends Validator>(inner: V) => ColumnValidator<Infer<V>[], Infer<V>[]>;
|
|
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] };
|
|
241
258
|
type ObjectShape = Record<string, Validator>;
|
|
242
|
-
type ObjectShapeType<S extends ObjectShape> =
|
|
259
|
+
type ObjectShapeType<S extends ObjectShape> = OptionalizeShape<{ [K in keyof S]: Infer<S[K]> }>;
|
|
243
260
|
declare const objectValidator: <S extends ObjectShape>(shape: S) => ColumnValidator<ObjectShapeType<S>, ObjectShapeType<S>>;
|
|
244
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>>>;
|
|
245
262
|
declare const union: <Vs extends ReadonlyArray<Validator>>(...members: Vs) => ColumnValidator<Infer<Vs[number]>, Infer<Vs[number]>>;
|
|
@@ -403,8 +420,13 @@ declare const toJsonSchema: (validator: Validator) => JsonSchema;
|
|
|
403
420
|
declare const argsToJsonSchema: (args: Record<string, Validator>) => JsonSchema;
|
|
404
421
|
/** Map of validators describing a record of named fields (a function's args, a step's args, an HTTP query/body/params). */
|
|
405
422
|
type ValidatorMap = Record<string, Validator>;
|
|
406
|
-
/**
|
|
407
|
-
|
|
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]> }>;
|
|
408
430
|
/**
|
|
409
431
|
* A precompiled fast-path parser for one {@link ValidatorMap}. Returns the fully
|
|
410
432
|
* built, validated record on a confident success, or the {@link DEFER_VALIDATION}
|
|
@@ -462,5 +484,4 @@ declare const installCompiledValidatorMap: (validators: object, compiled: Compil
|
|
|
462
484
|
* which case the interpreted loop below runs and owns the result (and any error).
|
|
463
485
|
*/
|
|
464
486
|
declare const parseValidatorMap: (validators: ValidatorMap, source: Record<string, unknown>, label: string) => Record<string, unknown>;
|
|
465
|
-
|
|
466
|
-
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, VERSION, ValidationError, type ValidationPath, type Validator, type ValidatorKind, type ValidatorMap, argsToJsonSchema, describeValue, formatPath, installCompiledValidatorMap, isOrWrapsFromValidator, jsonSchemaFromNode, objectSchemaFromNodes, optionalInner, parseValidatorMap, toJsonSchema, v };
|
|
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 };
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
export { ValidationError, describeValue, formatPath } from './packem_shared/ValidationError-
|
|
1
|
+
export { ValidationError, describeValue, formatPath } from './packem_shared/ValidationError-CoyFtkxj.mjs';
|
|
2
2
|
export { jsonSchemaFromNode, objectSchemaFromNodes } from './packem_shared/jsonSchemaFromNode-weszUOQG.mjs';
|
|
3
3
|
export { argsToJsonSchema, toJsonSchema } from './packem_shared/argsToJsonSchema-DdHmmamC.mjs';
|
|
4
|
-
export { isOrWrapsFromValidator, optionalInner, v } from './packem_shared/isOrWrapsFromValidator-
|
|
5
|
-
export { DEFER_VALIDATION, installCompiledValidatorMap, parseValidatorMap } from './packem_shared/DEFER_VALIDATION-
|
|
6
|
-
|
|
7
|
-
const VERSION = "0.0.0";
|
|
8
|
-
|
|
9
|
-
export { VERSION };
|
|
4
|
+
export { isOrWrapsFromValidator, optionalInner, v } from './packem_shared/isOrWrapsFromValidator-UlWeMhFL.mjs';
|
|
5
|
+
export { DEFER_VALIDATION, installCompiledValidatorMap, parseValidatorMap } from './packem_shared/DEFER_VALIDATION-CIKr17sW.mjs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ValidationError } from './ValidationError-
|
|
1
|
+
import { ValidationError } from './ValidationError-CoyFtkxj.mjs';
|
|
2
2
|
|
|
3
3
|
const DEFER_VALIDATION = /* @__PURE__ */ Symbol("lunora.deferValidation");
|
|
4
4
|
const COMPILED_PARSERS = /* @__PURE__ */ new WeakMap();
|
|
@@ -19,7 +19,7 @@ const parseValidatorMap = (validators, source, label) => {
|
|
|
19
19
|
if (!validator) {
|
|
20
20
|
continue;
|
|
21
21
|
}
|
|
22
|
-
const candidate = source[key];
|
|
22
|
+
const candidate = Object.hasOwn(source, key) ? source[key] : void 0;
|
|
23
23
|
if (candidate === void 0 && validator.kind === "optional") {
|
|
24
24
|
continue;
|
|
25
25
|
}
|
|
@@ -2,6 +2,18 @@ import { LunoraError } from '@lunora/errors';
|
|
|
2
2
|
|
|
3
3
|
const MAX_DESCRIBED_LENGTH = 80;
|
|
4
4
|
const truncate = (text) => text.length > MAX_DESCRIBED_LENGTH ? `${text.slice(0, MAX_DESCRIBED_LENGTH)}…` : text;
|
|
5
|
+
const describeObject = (value) => {
|
|
6
|
+
try {
|
|
7
|
+
const { constructor } = value;
|
|
8
|
+
const constructorName = constructor?.name;
|
|
9
|
+
if (constructorName !== void 0 && constructorName !== "Object") {
|
|
10
|
+
return `object ${constructorName}`;
|
|
11
|
+
}
|
|
12
|
+
} catch {
|
|
13
|
+
return "object";
|
|
14
|
+
}
|
|
15
|
+
return "object";
|
|
16
|
+
};
|
|
5
17
|
class ValidationError extends LunoraError {
|
|
6
18
|
path;
|
|
7
19
|
expected;
|
|
@@ -13,7 +25,8 @@ class ValidationError extends LunoraError {
|
|
|
13
25
|
this.received = options.received;
|
|
14
26
|
}
|
|
15
27
|
}
|
|
16
|
-
const describeValue = (value) => {
|
|
28
|
+
const describeValue = (value, options) => {
|
|
29
|
+
const literal = options?.literal ?? true;
|
|
17
30
|
if (value === null) {
|
|
18
31
|
return "null";
|
|
19
32
|
}
|
|
@@ -24,25 +37,16 @@ const describeValue = (value) => {
|
|
|
24
37
|
return "ArrayBuffer";
|
|
25
38
|
}
|
|
26
39
|
if (typeof value === "string") {
|
|
27
|
-
return `string ${truncate(JSON.stringify(value))}
|
|
40
|
+
return literal ? `string ${truncate(JSON.stringify(value))}` : "string";
|
|
28
41
|
}
|
|
29
42
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
30
|
-
return `${typeof value} ${String(value)}
|
|
43
|
+
return literal ? `${typeof value} ${String(value)}` : typeof value;
|
|
31
44
|
}
|
|
32
45
|
if (typeof value === "bigint") {
|
|
33
|
-
return `bigint ${value.toString()}n
|
|
46
|
+
return literal ? `bigint ${value.toString()}n` : "bigint";
|
|
34
47
|
}
|
|
35
48
|
if (typeof value === "object") {
|
|
36
|
-
|
|
37
|
-
const { constructor } = value;
|
|
38
|
-
const constructorName = constructor?.name;
|
|
39
|
-
if (constructorName !== void 0 && constructorName !== "Object") {
|
|
40
|
-
return `object ${constructorName}`;
|
|
41
|
-
}
|
|
42
|
-
} catch {
|
|
43
|
-
return "object";
|
|
44
|
-
}
|
|
45
|
-
return "object";
|
|
49
|
+
return describeObject(value);
|
|
46
50
|
}
|
|
47
51
|
return typeof value;
|
|
48
52
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { LunoraError } from '@lunora/errors';
|
|
2
|
-
import { ValidationError, formatPath, describeValue } from './ValidationError-
|
|
2
|
+
import { ValidationError, formatPath, describeValue } from './ValidationError-CoyFtkxj.mjs';
|
|
3
3
|
|
|
4
|
-
function fail(context, expected, received) {
|
|
4
|
+
function fail(context, expected, received, options) {
|
|
5
5
|
const path = [...context.path];
|
|
6
|
-
const receivedDescription = describeValue(received);
|
|
6
|
+
const receivedDescription = describeValue(received, { literal: !options?.redactValue });
|
|
7
7
|
throw new ValidationError(`Expected ${expected} at ${formatPath(path)}, received ${receivedDescription}`, {
|
|
8
8
|
expected,
|
|
9
9
|
path,
|
|
@@ -78,7 +78,7 @@ const createValidator = (kind, parser, meta) => {
|
|
|
78
78
|
const refinedParser = (value, context) => {
|
|
79
79
|
const parsed = parser(value, context);
|
|
80
80
|
if (!predicate(parsed)) {
|
|
81
|
-
fail(context, message ?? "value matching refinement", parsed);
|
|
81
|
+
fail(context, message ?? "value matching refinement", parsed, { redactValue: true });
|
|
82
82
|
}
|
|
83
83
|
return parsed;
|
|
84
84
|
};
|
|
@@ -223,7 +223,7 @@ const objectValidator = (shape) => {
|
|
|
223
223
|
const out = {};
|
|
224
224
|
const { path } = context;
|
|
225
225
|
for (const { child, isOptional, key } of entries) {
|
|
226
|
-
const fieldValue = input[key];
|
|
226
|
+
const fieldValue = Object.hasOwn(input, key) ? input[key] : void 0;
|
|
227
227
|
if (fieldValue === void 0 && isOptional) {
|
|
228
228
|
continue;
|
|
229
229
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/values",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.7",
|
|
4
4
|
"description": "Validators for Lunora: the v.* validator suite with end-to-end return-type inference",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
49
|
+
"@lunora/errors": "1.0.0-alpha.4"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": "^22.15.0 || >=24.11.0"
|