ts-fortress 11.0.1 → 11.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/dist/brand/branded-number.d.mts +1 -5
- package/dist/brand/branded-number.d.mts.map +1 -1
- package/dist/brand/branded-string.d.mts +1 -5
- package/dist/brand/branded-string.d.mts.map +1 -1
- package/dist/record/at.mjs +1 -1
- package/dist/record/at.mjs.map +1 -1
- package/dist/utils/validation-error.mjs +2 -2
- package/dist/utils/validation-error.mjs.map +1 -1
- package/package.json +17 -16
- package/src/record/at.mts +1 -1
- package/src/utils/validation-error.mts +2 -2
|
@@ -10,9 +10,5 @@ export declare const brandedNumber: <K extends string>({ defaultValue, is, typeN
|
|
|
10
10
|
*
|
|
11
11
|
* @deprecated use `brandedNumber`
|
|
12
12
|
*/
|
|
13
|
-
export declare const simpleBrandedNumber:
|
|
14
|
-
typeName: K;
|
|
15
|
-
defaultValue: number;
|
|
16
|
-
is?: (u: number) => u is Brand<number, K>;
|
|
17
|
-
}>) => Type<Brand<number, K>>;
|
|
13
|
+
export declare const simpleBrandedNumber: typeof brandedNumber;
|
|
18
14
|
//# sourceMappingURL=branded-number.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branded-number.d.mts","sourceRoot":"","sources":["../../src/brand/branded-number.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,mCAI3C,QAAQ,CAAC;IACV,QAAQ,EAAE,CAAC,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAC3C,CAAC,KAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAStB,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"branded-number.d.mts","sourceRoot":"","sources":["../../src/brand/branded-number.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,mCAI3C,QAAQ,CAAC;IACV,QAAQ,EAAE,CAAC,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAC3C,CAAC,KAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAStB,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,sBAAgB,CAAC"}
|
|
@@ -10,9 +10,5 @@ export declare const brandedString: <K extends string>({ defaultValue, is, typeN
|
|
|
10
10
|
*
|
|
11
11
|
* @deprecated use `brandedString`
|
|
12
12
|
*/
|
|
13
|
-
export declare const simpleBrandedString:
|
|
14
|
-
typeName: K;
|
|
15
|
-
defaultValue: string;
|
|
16
|
-
is?: (u: string) => u is Brand<string, K>;
|
|
17
|
-
}>) => Type<Brand<string, K>>;
|
|
13
|
+
export declare const simpleBrandedString: typeof brandedString;
|
|
18
14
|
//# sourceMappingURL=branded-string.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branded-string.d.mts","sourceRoot":"","sources":["../../src/brand/branded-string.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,mCAI3C,QAAQ,CAAC;IACV,QAAQ,EAAE,CAAC,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAC3C,CAAC,KAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAStB,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"branded-string.d.mts","sourceRoot":"","sources":["../../src/brand/branded-string.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,mCAI3C,QAAQ,CAAC;IACV,QAAQ,EAAE,CAAC,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAC3C,CAAC,KAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAStB,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,sBAAgB,CAAC"}
|
package/dist/record/at.mjs
CHANGED
|
@@ -28,7 +28,7 @@ function at(type, keyOrIndex) {
|
|
|
28
28
|
return memberType === void 0 ? [] : [memberType];
|
|
29
29
|
});
|
|
30
30
|
const hasOptionalMember = memberTypes.some(isOptionalProperty);
|
|
31
|
-
const collected = hasOptionalMember ?
|
|
31
|
+
const collected = hasOptionalMember ? Arr.toPushed(memberTypes, undefinedType) : memberTypes;
|
|
32
32
|
if (Arr.isMinLengthTuple(collected, 2)) {
|
|
33
33
|
return union(collected, {
|
|
34
34
|
typeName: `${type.typeName}[${JSON.stringify(keyOrIndex)}]`
|
package/dist/record/at.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"at.mjs","sources":["../../src/record/at.mts"],"sourcesContent":["import { Arr } from 'ts-data-forge';\nimport { type IndexOfTuple, type UnknownRecord } from 'ts-type-forge';\nimport { union } from '../compose/index.mjs';\nimport { undefinedType } from '../primitives/index.mjs';\nimport {\n expandShapeStructure,\n hasRecordInternals,\n hasTupleInternals,\n type Type,\n} from '../type.mjs';\nimport { isOptionalProperty } from './optional.mjs';\n\n/**\n * Extracts the {@link Type} stored at a single key of a record type.\n *\n * The first argument must be a record type (i.e. it must extend\n * `Type<UnknownRecord>`, like {@link pick} and {@link keyof}), and the second\n * argument is constrained to the keys declared on that record.\n *\n * The record type may be a simple record, an intersection (e.g. the result of\n * {@link mergeRecords}), a union, a recursive type, or any combination of\n * these — the underlying shape is expanded and, when a key resolves to\n * multiple member types (as in a union), the resulting types are combined with\n * {@link union}.\n *\n * @example\n * ```ts\n * import * as t from 'ts-fortress';\n *\n * const ymd = t.record({\n * year: t.number(1900),\n * month: t.number(1),\n * date: t.number(1),\n * });\n *\n * const year = t.at(ymd, 'year'); // Type<number>\n *\n * year.is(2000); // true\n * ```\n */\nexport function at<\n const R extends UnknownRecord,\n const K extends keyof R & string,\n>(recordType: Type<R>, key: K): Type<R[K]>;\n\n/**\n * Extracts the {@link Type} stored at a single index of a tuple type.\n *\n * @example\n * ```ts\n * import * as t from 'ts-fortress';\n *\n * const tup = t.tuple([t.number(), t.string(), t.boolean()]);\n *\n * const second = t.at(tup, 1); // Type<string>\n *\n * second.is('hello'); // true\n * ```\n */\nexport function at<\n const T extends readonly unknown[],\n const N extends IndexOfTuple<T>,\n>(tupleType: Type<T>, index: N): Type<T[N]>;\n\nexport function at(\n type: Type<UnknownRecord> | Type<readonly unknown[]>,\n keyOrIndex: string | number,\n): Type<unknown> {\n // --- Tuple index access ---\n if (typeof keyOrIndex === 'number') {\n if (!hasTupleInternals(type)) {\n throw new Error(`Expected a tuple type but received: ${type.typeName}`);\n }\n\n const elementType = type.elementTypes[keyOrIndex];\n\n if (elementType === undefined) {\n throw new Error(\n `Index ${keyOrIndex} is out of range for tuple type: ${type.typeName}`,\n );\n }\n\n return elementType;\n }\n\n // --- Record key access ---\n if (!hasRecordInternals(type)) {\n throw new Error(`Expected a record type but received: ${type.typeName}`);\n }\n\n const shapes = expandShapeStructure(type.shapeStructure);\n\n const memberTypes: readonly Type<unknown>[] = shapes.flatMap((shape) => {\n const memberType = shape[keyOrIndex];\n\n return memberType === undefined ? [] : [memberType];\n });\n\n // If the key is optional in any member, the accessed value may be undefined,\n // matching the `T | undefined` produced by `R[K]` for optional keys.\n const hasOptionalMember = memberTypes.some(isOptionalProperty);\n\n const collected: readonly Type<unknown>[] = hasOptionalMember\n ? (
|
|
1
|
+
{"version":3,"file":"at.mjs","sources":["../../src/record/at.mts"],"sourcesContent":["import { Arr } from 'ts-data-forge';\nimport { type IndexOfTuple, type UnknownRecord } from 'ts-type-forge';\nimport { union } from '../compose/index.mjs';\nimport { undefinedType } from '../primitives/index.mjs';\nimport {\n expandShapeStructure,\n hasRecordInternals,\n hasTupleInternals,\n type Type,\n} from '../type.mjs';\nimport { isOptionalProperty } from './optional.mjs';\n\n/**\n * Extracts the {@link Type} stored at a single key of a record type.\n *\n * The first argument must be a record type (i.e. it must extend\n * `Type<UnknownRecord>`, like {@link pick} and {@link keyof}), and the second\n * argument is constrained to the keys declared on that record.\n *\n * The record type may be a simple record, an intersection (e.g. the result of\n * {@link mergeRecords}), a union, a recursive type, or any combination of\n * these — the underlying shape is expanded and, when a key resolves to\n * multiple member types (as in a union), the resulting types are combined with\n * {@link union}.\n *\n * @example\n * ```ts\n * import * as t from 'ts-fortress';\n *\n * const ymd = t.record({\n * year: t.number(1900),\n * month: t.number(1),\n * date: t.number(1),\n * });\n *\n * const year = t.at(ymd, 'year'); // Type<number>\n *\n * year.is(2000); // true\n * ```\n */\nexport function at<\n const R extends UnknownRecord,\n const K extends keyof R & string,\n>(recordType: Type<R>, key: K): Type<R[K]>;\n\n/**\n * Extracts the {@link Type} stored at a single index of a tuple type.\n *\n * @example\n * ```ts\n * import * as t from 'ts-fortress';\n *\n * const tup = t.tuple([t.number(), t.string(), t.boolean()]);\n *\n * const second = t.at(tup, 1); // Type<string>\n *\n * second.is('hello'); // true\n * ```\n */\nexport function at<\n const T extends readonly unknown[],\n const N extends IndexOfTuple<T>,\n>(tupleType: Type<T>, index: N): Type<T[N]>;\n\nexport function at(\n type: Type<UnknownRecord> | Type<readonly unknown[]>,\n keyOrIndex: string | number,\n): Type<unknown> {\n // --- Tuple index access ---\n if (typeof keyOrIndex === 'number') {\n if (!hasTupleInternals(type)) {\n throw new Error(`Expected a tuple type but received: ${type.typeName}`);\n }\n\n const elementType = type.elementTypes[keyOrIndex];\n\n if (elementType === undefined) {\n throw new Error(\n `Index ${keyOrIndex} is out of range for tuple type: ${type.typeName}`,\n );\n }\n\n return elementType;\n }\n\n // --- Record key access ---\n if (!hasRecordInternals(type)) {\n throw new Error(`Expected a record type but received: ${type.typeName}`);\n }\n\n const shapes = expandShapeStructure(type.shapeStructure);\n\n const memberTypes: readonly Type<unknown>[] = shapes.flatMap((shape) => {\n const memberType = shape[keyOrIndex];\n\n return memberType === undefined ? [] : [memberType];\n });\n\n // If the key is optional in any member, the accessed value may be undefined,\n // matching the `T | undefined` produced by `R[K]` for optional keys.\n const hasOptionalMember = memberTypes.some(isOptionalProperty);\n\n const collected: readonly Type<unknown>[] = hasOptionalMember\n ? Arr.toPushed(memberTypes, undefinedType)\n : memberTypes;\n\n if (Arr.isMinLengthTuple(collected, 2)) {\n return union(collected, {\n typeName: `${type.typeName}[${JSON.stringify(keyOrIndex)}]`,\n });\n }\n\n if (Arr.isNonEmpty(collected)) {\n return collected[0];\n }\n\n throw new Error(\n `Key ${JSON.stringify(keyOrIndex)} does not exist on record type: ${type.typeName}`,\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAgEO,SAAS,EAAA,CACd,MACA,UAAA,EACe;AAEf,EAAA,IAAI,OAAO,eAAe,QAAA,EAAU;AAClC,IAAA,IAAI,CAAC,iBAAA,CAAkB,IAAI,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,oCAAA,EAAuC,IAAA,CAAK,QAAQ,CAAA,CAAE,CAAA;AAAA,IACxE;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA;AAEhD,IAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,MAAA,EAAS,UAAU,CAAA,iCAAA,EAAoC,IAAA,CAAK,QAAQ,CAAA;AAAA,OACtE;AAAA,IACF;AAEA,IAAA,OAAO,WAAA;AAAA,EACT;AAGA,EAAA,IAAI,CAAC,kBAAA,CAAmB,IAAI,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qCAAA,EAAwC,IAAA,CAAK,QAAQ,CAAA,CAAE,CAAA;AAAA,EACzE;AAEA,EAAA,MAAM,MAAA,GAAS,oBAAA,CAAqB,IAAA,CAAK,cAAc,CAAA;AAEvD,EAAA,MAAM,WAAA,GAAwC,MAAA,CAAO,OAAA,CAAQ,CAAC,KAAA,KAAU;AACtE,IAAA,MAAM,UAAA,GAAa,MAAM,UAAU,CAAA;AAEnC,IAAA,OAAO,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,CAAC,UAAU,CAAA;AAAA,EACpD,CAAC,CAAA;AAID,EAAA,MAAM,iBAAA,GAAoB,WAAA,CAAY,IAAA,CAAK,kBAAkB,CAAA;AAE7D,EAAA,MAAM,YAAsC,iBAAA,GACxC,GAAA,CAAI,QAAA,CAAS,WAAA,EAAa,aAAa,CAAA,GACvC,WAAA;AAEJ,EAAA,IAAI,GAAA,CAAI,gBAAA,CAAiB,SAAA,EAAW,CAAC,CAAA,EAAG;AACtC,IAAA,OAAO,MAAM,SAAA,EAAW;AAAA,MACtB,QAAA,EAAU,GAAG,IAAA,CAAK,QAAQ,IAAI,IAAA,CAAK,SAAA,CAAU,UAAU,CAAC,CAAA,CAAA;AAAA,KACzD,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AAC7B,IAAA,OAAO,UAAU,CAAC,CAAA;AAAA,EACpB;AAEA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,OAAO,IAAA,CAAK,SAAA,CAAU,UAAU,CAAC,CAAA,gCAAA,EAAmC,KAAK,QAAQ,CAAA;AAAA,GACnF;AACF;;;;"}
|
|
@@ -48,7 +48,7 @@ const createDetailsMessage = (error, maxLengthToPrintActualValue) => {
|
|
|
48
48
|
case "intersection":
|
|
49
49
|
return `expected value to match all types of <${error.details.typeNames.join(">, <")}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;
|
|
50
50
|
case "enum":
|
|
51
|
-
return `expected one of { ${error.details.values.map(
|
|
51
|
+
return `expected one of { ${error.details.values.map(String).join(", ")} } but${actualValueStr} was passed.`;
|
|
52
52
|
case "union":
|
|
53
53
|
return `expected one of <${error.details.typeNames.join(">, <")}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;
|
|
54
54
|
case "record-entry":
|
|
@@ -138,7 +138,7 @@ const numericConstraintToMessage = (numericType, violation, actualValueStr) => {
|
|
|
138
138
|
const validationErrorsToMessages = (errors, maxLengthToPrintActualValue = 20) => errors.map((e) => validationErrorToMessage(e, maxLengthToPrintActualValue));
|
|
139
139
|
const prependPathToValidationErrors = (errors, pathSegment) => errors.map((error) => ({
|
|
140
140
|
...error,
|
|
141
|
-
path:
|
|
141
|
+
path: Arr.toUnshifted(pathSegment)(error.path)
|
|
142
142
|
}));
|
|
143
143
|
const prependIndexToValidationErrors = (errors, index) => prependPathToValidationErrors(errors, index.toString());
|
|
144
144
|
const createPrimitiveValidationError = ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-error.mjs","sources":["../../src/utils/validation-error.mts"],"sourcesContent":["import { Arr, isString, match, pipe, unknownToString } from 'ts-data-forge';\n\nexport type ValidationErrorDetails = Readonly<\n | {\n kind: 'custom';\n message: string;\n }\n | {\n kind: 'template-literal';\n }\n | {\n kind: 'enum';\n values: readonly unknown[];\n }\n | {\n kind: 'integer-range';\n start: number;\n endExclusive: number;\n }\n | {\n kind: 'tuple-length';\n expectedLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-length';\n expectedLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-min-length';\n minLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-max-length';\n maxLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-range-length';\n minLength: number;\n maxLength: number;\n actualLength: number;\n }\n | {\n kind: 'non-empty-array';\n }\n | {\n kind: 'missing-key';\n key: string;\n }\n | {\n kind: 'excess-key';\n key: string;\n }\n | {\n kind: 'intersection';\n typeNames: readonly string[];\n }\n | {\n kind: 'union';\n typeNames: readonly string[];\n }\n | {\n kind: 'record-entry';\n entry: 'key' | 'value';\n expectedType: string;\n }\n | {\n kind: 'map-entry';\n entry: 'key' | 'value';\n expectedType: string;\n }\n | {\n kind: 'set-element';\n expectedType: string;\n }\n | {\n kind: 'brand';\n description: string;\n }\n | {\n kind: 'string-constraint';\n violation: StringConstraintViolation;\n }\n | {\n kind: 'numeric-constraint';\n numericType: 'bigint' | 'number';\n violation: NumericConstraintViolation;\n }\n>;\n\n/**\n * Describes which `string` constraint (see the `string` codec) a value failed,\n * together with the constraint's configured value. `value` doubles as the\n * value shown in the constructor-time \"defaultValue ... does not satisfy the\n * constraint ...\" message, so it mirrors the raw constraint input (the flag\n * constraints carry `true`, `regex` carries its `source`).\n */\nexport type StringConstraintViolation = Readonly<\n | {\n constraint: 'nonempty' | 'lowercase' | 'uppercase';\n value: true;\n }\n | {\n constraint: 'minLength' | 'maxLength';\n value: number;\n }\n | {\n constraint: 'startsWith' | 'endsWith' | 'includes';\n value: string;\n }\n | {\n constraint: 'regex';\n value: string;\n }\n>;\n\n/**\n * Describes which numeric constraint (see the `number` / `bigint` codecs) a\n * value failed. Range bounds are stringified so a single type can describe both\n * `number` and `bigint` violations; `value` doubles as the value shown in the\n * constructor-time \"defaultValue ... does not satisfy the constraint ...\"\n * message.\n */\nexport type NumericConstraintViolation = Readonly<\n | {\n constraint:\n | 'finite'\n | 'int'\n | 'safeInteger'\n | 'nonZero'\n | 'negative'\n | 'nonNegative'\n | 'positive'\n | 'nonPositive';\n value: true;\n }\n | {\n constraint:\n 'gt' | 'gte' | 'min' | 'lt' | 'lte' | 'max' | 'multipleOf' | 'step';\n value: string;\n }\n>;\n\n/**\n * Represents a validation error with structured information\n */\nexport type ValidationError = Readonly<{\n /** The path to the field that failed validation (e.g., 'user.address.street') */\n path: readonly string[];\n /** The actual value that failed validation */\n actualValue: unknown;\n /** The expected type or constraint */\n expectedType: string;\n /** The name of the type that was being validated */\n typeName: string;\n /** Optional structured information used to construct a descriptive message */\n details?: ValidationErrorDetails | undefined;\n}>;\n\n/**\n * Converts a validation error to a human-readable string message\n */\nexport const validationErrorToMessage = (\n error: ValidationError,\n maxLengthToPrintActualValue: number = 20,\n): string => {\n const pathPrefix = Arr.isNonEmpty(error.path)\n ? (`Error at ${error.path.join('.')}: ` as const)\n : 'Error: ';\n\n const detailsMessage = createDetailsMessage(\n error,\n maxLengthToPrintActualValue,\n );\n\n if (detailsMessage !== undefined) {\n return `${pathPrefix}${detailsMessage}`;\n }\n\n const actualTypeStr = typeof error.actualValue;\n\n const actualValueStr: string = isString(error.actualValue)\n ? error.actualValue.length <= maxLengthToPrintActualValue\n ? (` \"${error.actualValue}\"` as const)\n : ''\n : pipe(unknownToString(error.actualValue)).map((s) =>\n s.length <= maxLengthToPrintActualValue ? ` \\`${s}\\`` : '',\n ).value;\n\n return `${pathPrefix}expected <${error.expectedType}> type but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n};\n\nconst createDetailsMessage = (\n error: ValidationError,\n maxLengthToPrintActualValue: number,\n): string | undefined => {\n const actualTypeStr = typeof error.actualValue;\n\n const actualValueStr: string = isString(error.actualValue)\n ? error.actualValue.length <= maxLengthToPrintActualValue\n ? (` \"${error.actualValue}\"` as const)\n : ''\n : pipe(unknownToString(error.actualValue)).map((s) =>\n s.length <= maxLengthToPrintActualValue ? ` \\`${s}\\`` : '',\n ).value;\n\n switch (error.details?.kind) {\n case undefined:\n return undefined;\n\n case 'custom':\n return error.details.message;\n\n case 'template-literal':\n return `expected <${error.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'integer-range':\n return `expected an integer between ${error.details.start} and ${error.details.endExclusive - 1} but${actualValueStr} was passed.`;\n\n case 'tuple-length':\n return `expected tuple of length ${error.details.expectedLength} but length ${error.details.actualLength} was passed.`;\n\n case 'array-length':\n return `expected array of length ${error.details.expectedLength} but length ${error.details.actualLength} was passed.`;\n\n case 'array-min-length':\n return `expected array of length ${error.details.minLength} or more but length ${error.details.actualLength} was passed.`;\n\n case 'array-max-length':\n return `expected array of length ${error.details.maxLength} or less but length ${error.details.actualLength} was passed.`;\n\n case 'array-range-length':\n return `expected array of length between ${error.details.minLength} and ${error.details.maxLength} but length ${error.details.actualLength} was passed.`;\n\n case 'non-empty-array':\n return 'expected non-empty array but empty array was passed.';\n\n case 'missing-key':\n return `missing required key \"${error.details.key}\".`;\n\n case 'excess-key':\n return `excess property \"${error.details.key}\" is not allowed.`;\n\n case 'intersection':\n return `expected value to match all types of <${error.details.typeNames.join('>, <')}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'enum':\n return `expected one of { ${error.details.values\n .map((value) => String(value))\n .join(', ')} } but${actualValueStr} was passed.`;\n\n case 'union':\n return `expected one of <${error.details.typeNames.join('>, <')}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'record-entry':\n return match(error.details.entry, {\n key: `expected record key type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n value: `expected record value type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n });\n\n case 'map-entry':\n return match(error.details.entry, {\n key: `expected Map key type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n value: `expected Map value type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n });\n\n case 'set-element':\n return `expected Set element type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'brand':\n return `expected value to satisfy constraint: ${error.details.description}.`;\n\n case 'string-constraint':\n return stringConstraintToMessage(\n error.details.violation,\n error.actualValue,\n actualValueStr,\n );\n\n case 'numeric-constraint':\n return numericConstraintToMessage(\n error.details.numericType,\n error.details.violation,\n actualValueStr,\n );\n }\n};\n\nconst stringConstraintToMessage = (\n violation: StringConstraintViolation,\n actualValue: unknown,\n actualValueStr: string,\n): string => {\n const actualLength = isString(actualValue) ? actualValue.length : 0;\n\n switch (violation.constraint) {\n case 'nonempty':\n return 'expected a non-empty string but an empty string was passed.';\n\n case 'minLength':\n return `expected a string of length ${violation.value} or more but a string of length ${actualLength}${actualValueStr} was passed.`;\n\n case 'maxLength':\n return `expected a string of length ${violation.value} or less but a string of length ${actualLength}${actualValueStr} was passed.`;\n\n case 'startsWith':\n return `expected a string starting with \"${violation.value}\" but${actualValueStr} was passed.`;\n\n case 'endsWith':\n return `expected a string ending with \"${violation.value}\" but${actualValueStr} was passed.`;\n\n case 'includes':\n return `expected a string containing \"${violation.value}\" but${actualValueStr} was passed.`;\n\n case 'uppercase':\n return `expected an uppercase string but${actualValueStr} was passed.`;\n\n case 'lowercase':\n return `expected a lowercase string but${actualValueStr} was passed.`;\n\n case 'regex':\n return `expected a string matching /${violation.value}/ but${actualValueStr} was passed.`;\n }\n};\n\nconst numericConstraintToMessage = (\n numericType: 'bigint' | 'number',\n violation: NumericConstraintViolation,\n actualValueStr: string,\n): string => {\n switch (violation.constraint) {\n case 'finite':\n return `expected a finite number but${actualValueStr} was passed.`;\n\n case 'int':\n return `expected an integer but${actualValueStr} was passed.`;\n\n case 'safeInteger':\n return `expected a safe integer but${actualValueStr} was passed.`;\n\n case 'nonZero':\n return `expected a non-zero ${numericType} but${actualValueStr} was passed.`;\n\n case 'negative':\n return `expected a negative ${numericType} but${actualValueStr} was passed.`;\n\n case 'nonNegative':\n return `expected a non-negative ${numericType} but${actualValueStr} was passed.`;\n\n case 'positive':\n return `expected a positive ${numericType} but${actualValueStr} was passed.`;\n\n case 'nonPositive':\n return `expected a non-positive ${numericType} but${actualValueStr} was passed.`;\n\n case 'gt':\n return `expected a ${numericType} greater than ${violation.value} but${actualValueStr} was passed.`;\n\n case 'gte':\n case 'min':\n return `expected a ${numericType} greater than or equal to ${violation.value} but${actualValueStr} was passed.`;\n\n case 'lt':\n return `expected a ${numericType} less than ${violation.value} but${actualValueStr} was passed.`;\n\n case 'lte':\n case 'max':\n return `expected a ${numericType} less than or equal to ${violation.value} but${actualValueStr} was passed.`;\n\n case 'multipleOf':\n case 'step':\n return `expected a ${numericType} to be a multiple of ${violation.value} but${actualValueStr} was passed.`;\n }\n};\n\n/**\n * Converts an array of validation errors to an array of string messages\n * (for backward compatibility)\n */\nexport const validationErrorsToMessages = (\n errors: readonly ValidationError[],\n maxLengthToPrintActualValue: number = 20,\n): readonly string[] =>\n errors.map((e) => validationErrorToMessage(e, maxLengthToPrintActualValue));\n\n/**\n * Prepends a path segment to all validation errors\n */\nexport const prependPathToValidationErrors = (\n errors: readonly ValidationError[],\n pathSegment: string,\n): readonly ValidationError[] =>\n errors.map((error) => ({\n ...error,\n path: [pathSegment, ...error.path],\n }));\n\n/**\n * Prepends an array index to all validation errors\n */\nexport const prependIndexToValidationErrors = (\n errors: readonly ValidationError[],\n index: number,\n): readonly ValidationError[] =>\n prependPathToValidationErrors(errors, index.toString());\n\n/**\n * Creates a basic validation error for primitive type validation\n */\nexport const createPrimitiveValidationError = ({\n actualValue,\n expectedType,\n typeName,\n details,\n}: Readonly<{\n actualValue: unknown;\n expectedType: string;\n typeName: string;\n details: ValidationErrorDetails | undefined;\n}>): ValidationError =>\n ({\n path: [],\n actualValue,\n expectedType,\n typeName,\n details,\n }) as const;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation-error.mjs","sources":["../../src/utils/validation-error.mts"],"sourcesContent":["import { Arr, isString, match, pipe, unknownToString } from 'ts-data-forge';\n\nexport type ValidationErrorDetails = Readonly<\n | {\n kind: 'custom';\n message: string;\n }\n | {\n kind: 'template-literal';\n }\n | {\n kind: 'enum';\n values: readonly unknown[];\n }\n | {\n kind: 'integer-range';\n start: number;\n endExclusive: number;\n }\n | {\n kind: 'tuple-length';\n expectedLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-length';\n expectedLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-min-length';\n minLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-max-length';\n maxLength: number;\n actualLength: number;\n }\n | {\n kind: 'array-range-length';\n minLength: number;\n maxLength: number;\n actualLength: number;\n }\n | {\n kind: 'non-empty-array';\n }\n | {\n kind: 'missing-key';\n key: string;\n }\n | {\n kind: 'excess-key';\n key: string;\n }\n | {\n kind: 'intersection';\n typeNames: readonly string[];\n }\n | {\n kind: 'union';\n typeNames: readonly string[];\n }\n | {\n kind: 'record-entry';\n entry: 'key' | 'value';\n expectedType: string;\n }\n | {\n kind: 'map-entry';\n entry: 'key' | 'value';\n expectedType: string;\n }\n | {\n kind: 'set-element';\n expectedType: string;\n }\n | {\n kind: 'brand';\n description: string;\n }\n | {\n kind: 'string-constraint';\n violation: StringConstraintViolation;\n }\n | {\n kind: 'numeric-constraint';\n numericType: 'bigint' | 'number';\n violation: NumericConstraintViolation;\n }\n>;\n\n/**\n * Describes which `string` constraint (see the `string` codec) a value failed,\n * together with the constraint's configured value. `value` doubles as the\n * value shown in the constructor-time \"defaultValue ... does not satisfy the\n * constraint ...\" message, so it mirrors the raw constraint input (the flag\n * constraints carry `true`, `regex` carries its `source`).\n */\nexport type StringConstraintViolation = Readonly<\n | {\n constraint: 'nonempty' | 'lowercase' | 'uppercase';\n value: true;\n }\n | {\n constraint: 'minLength' | 'maxLength';\n value: number;\n }\n | {\n constraint: 'startsWith' | 'endsWith' | 'includes';\n value: string;\n }\n | {\n constraint: 'regex';\n value: string;\n }\n>;\n\n/**\n * Describes which numeric constraint (see the `number` / `bigint` codecs) a\n * value failed. Range bounds are stringified so a single type can describe both\n * `number` and `bigint` violations; `value` doubles as the value shown in the\n * constructor-time \"defaultValue ... does not satisfy the constraint ...\"\n * message.\n */\nexport type NumericConstraintViolation = Readonly<\n | {\n constraint:\n | 'finite'\n | 'int'\n | 'safeInteger'\n | 'nonZero'\n | 'negative'\n | 'nonNegative'\n | 'positive'\n | 'nonPositive';\n value: true;\n }\n | {\n constraint:\n 'gt' | 'gte' | 'min' | 'lt' | 'lte' | 'max' | 'multipleOf' | 'step';\n value: string;\n }\n>;\n\n/**\n * Represents a validation error with structured information\n */\nexport type ValidationError = Readonly<{\n /** The path to the field that failed validation (e.g., 'user.address.street') */\n path: readonly string[];\n /** The actual value that failed validation */\n actualValue: unknown;\n /** The expected type or constraint */\n expectedType: string;\n /** The name of the type that was being validated */\n typeName: string;\n /** Optional structured information used to construct a descriptive message */\n details?: ValidationErrorDetails | undefined;\n}>;\n\n/**\n * Converts a validation error to a human-readable string message\n */\nexport const validationErrorToMessage = (\n error: ValidationError,\n maxLengthToPrintActualValue: number = 20,\n): string => {\n const pathPrefix = Arr.isNonEmpty(error.path)\n ? (`Error at ${error.path.join('.')}: ` as const)\n : 'Error: ';\n\n const detailsMessage = createDetailsMessage(\n error,\n maxLengthToPrintActualValue,\n );\n\n if (detailsMessage !== undefined) {\n return `${pathPrefix}${detailsMessage}`;\n }\n\n const actualTypeStr = typeof error.actualValue;\n\n const actualValueStr: string = isString(error.actualValue)\n ? error.actualValue.length <= maxLengthToPrintActualValue\n ? (` \"${error.actualValue}\"` as const)\n : ''\n : pipe(unknownToString(error.actualValue)).map((s) =>\n s.length <= maxLengthToPrintActualValue ? ` \\`${s}\\`` : '',\n ).value;\n\n return `${pathPrefix}expected <${error.expectedType}> type but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n};\n\nconst createDetailsMessage = (\n error: ValidationError,\n maxLengthToPrintActualValue: number,\n): string | undefined => {\n const actualTypeStr = typeof error.actualValue;\n\n const actualValueStr: string = isString(error.actualValue)\n ? error.actualValue.length <= maxLengthToPrintActualValue\n ? (` \"${error.actualValue}\"` as const)\n : ''\n : pipe(unknownToString(error.actualValue)).map((s) =>\n s.length <= maxLengthToPrintActualValue ? ` \\`${s}\\`` : '',\n ).value;\n\n switch (error.details?.kind) {\n case undefined:\n return undefined;\n\n case 'custom':\n return error.details.message;\n\n case 'template-literal':\n return `expected <${error.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'integer-range':\n return `expected an integer between ${error.details.start} and ${error.details.endExclusive - 1} but${actualValueStr} was passed.`;\n\n case 'tuple-length':\n return `expected tuple of length ${error.details.expectedLength} but length ${error.details.actualLength} was passed.`;\n\n case 'array-length':\n return `expected array of length ${error.details.expectedLength} but length ${error.details.actualLength} was passed.`;\n\n case 'array-min-length':\n return `expected array of length ${error.details.minLength} or more but length ${error.details.actualLength} was passed.`;\n\n case 'array-max-length':\n return `expected array of length ${error.details.maxLength} or less but length ${error.details.actualLength} was passed.`;\n\n case 'array-range-length':\n return `expected array of length between ${error.details.minLength} and ${error.details.maxLength} but length ${error.details.actualLength} was passed.`;\n\n case 'non-empty-array':\n return 'expected non-empty array but empty array was passed.';\n\n case 'missing-key':\n return `missing required key \"${error.details.key}\".`;\n\n case 'excess-key':\n return `excess property \"${error.details.key}\" is not allowed.`;\n\n case 'intersection':\n return `expected value to match all types of <${error.details.typeNames.join('>, <')}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'enum':\n return `expected one of { ${error.details.values\n .map(String)\n .join(', ')} } but${actualValueStr} was passed.`;\n\n case 'union':\n return `expected one of <${error.details.typeNames.join('>, <')}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'record-entry':\n return match(error.details.entry, {\n key: `expected record key type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n value: `expected record value type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n });\n\n case 'map-entry':\n return match(error.details.entry, {\n key: `expected Map key type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n value: `expected Map value type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`,\n });\n\n case 'set-element':\n return `expected Set element type to be <${error.details.expectedType}> but <${actualTypeStr}> type value${actualValueStr} was passed.`;\n\n case 'brand':\n return `expected value to satisfy constraint: ${error.details.description}.`;\n\n case 'string-constraint':\n return stringConstraintToMessage(\n error.details.violation,\n error.actualValue,\n actualValueStr,\n );\n\n case 'numeric-constraint':\n return numericConstraintToMessage(\n error.details.numericType,\n error.details.violation,\n actualValueStr,\n );\n }\n};\n\nconst stringConstraintToMessage = (\n violation: StringConstraintViolation,\n actualValue: unknown,\n actualValueStr: string,\n): string => {\n const actualLength = isString(actualValue) ? actualValue.length : 0;\n\n switch (violation.constraint) {\n case 'nonempty':\n return 'expected a non-empty string but an empty string was passed.';\n\n case 'minLength':\n return `expected a string of length ${violation.value} or more but a string of length ${actualLength}${actualValueStr} was passed.`;\n\n case 'maxLength':\n return `expected a string of length ${violation.value} or less but a string of length ${actualLength}${actualValueStr} was passed.`;\n\n case 'startsWith':\n return `expected a string starting with \"${violation.value}\" but${actualValueStr} was passed.`;\n\n case 'endsWith':\n return `expected a string ending with \"${violation.value}\" but${actualValueStr} was passed.`;\n\n case 'includes':\n return `expected a string containing \"${violation.value}\" but${actualValueStr} was passed.`;\n\n case 'uppercase':\n return `expected an uppercase string but${actualValueStr} was passed.`;\n\n case 'lowercase':\n return `expected a lowercase string but${actualValueStr} was passed.`;\n\n case 'regex':\n return `expected a string matching /${violation.value}/ but${actualValueStr} was passed.`;\n }\n};\n\nconst numericConstraintToMessage = (\n numericType: 'bigint' | 'number',\n violation: NumericConstraintViolation,\n actualValueStr: string,\n): string => {\n switch (violation.constraint) {\n case 'finite':\n return `expected a finite number but${actualValueStr} was passed.`;\n\n case 'int':\n return `expected an integer but${actualValueStr} was passed.`;\n\n case 'safeInteger':\n return `expected a safe integer but${actualValueStr} was passed.`;\n\n case 'nonZero':\n return `expected a non-zero ${numericType} but${actualValueStr} was passed.`;\n\n case 'negative':\n return `expected a negative ${numericType} but${actualValueStr} was passed.`;\n\n case 'nonNegative':\n return `expected a non-negative ${numericType} but${actualValueStr} was passed.`;\n\n case 'positive':\n return `expected a positive ${numericType} but${actualValueStr} was passed.`;\n\n case 'nonPositive':\n return `expected a non-positive ${numericType} but${actualValueStr} was passed.`;\n\n case 'gt':\n return `expected a ${numericType} greater than ${violation.value} but${actualValueStr} was passed.`;\n\n case 'gte':\n case 'min':\n return `expected a ${numericType} greater than or equal to ${violation.value} but${actualValueStr} was passed.`;\n\n case 'lt':\n return `expected a ${numericType} less than ${violation.value} but${actualValueStr} was passed.`;\n\n case 'lte':\n case 'max':\n return `expected a ${numericType} less than or equal to ${violation.value} but${actualValueStr} was passed.`;\n\n case 'multipleOf':\n case 'step':\n return `expected a ${numericType} to be a multiple of ${violation.value} but${actualValueStr} was passed.`;\n }\n};\n\n/**\n * Converts an array of validation errors to an array of string messages\n * (for backward compatibility)\n */\nexport const validationErrorsToMessages = (\n errors: readonly ValidationError[],\n maxLengthToPrintActualValue: number = 20,\n): readonly string[] =>\n errors.map((e) => validationErrorToMessage(e, maxLengthToPrintActualValue));\n\n/**\n * Prepends a path segment to all validation errors\n */\nexport const prependPathToValidationErrors = (\n errors: readonly ValidationError[],\n pathSegment: string,\n): readonly ValidationError[] =>\n errors.map((error) => ({\n ...error,\n path: Arr.toUnshifted(pathSegment)(error.path),\n }));\n\n/**\n * Prepends an array index to all validation errors\n */\nexport const prependIndexToValidationErrors = (\n errors: readonly ValidationError[],\n index: number,\n): readonly ValidationError[] =>\n prependPathToValidationErrors(errors, index.toString());\n\n/**\n * Creates a basic validation error for primitive type validation\n */\nexport const createPrimitiveValidationError = ({\n actualValue,\n expectedType,\n typeName,\n details,\n}: Readonly<{\n actualValue: unknown;\n expectedType: string;\n typeName: string;\n details: ValidationErrorDetails | undefined;\n}>): ValidationError =>\n ({\n path: [],\n actualValue,\n expectedType,\n typeName,\n details,\n }) as const;\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-fortress",
|
|
3
|
-
"version": "11.0.
|
|
3
|
+
"version": "11.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript"
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
"z:vitest:node": "pnpm run z:vitest --project='Node.js'"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@sindresorhus/is": "
|
|
88
|
-
"ts-data-forge": "
|
|
89
|
-
"ts-type-forge": "
|
|
87
|
+
"@sindresorhus/is": "8.1.x",
|
|
88
|
+
"ts-data-forge": "12.x",
|
|
89
|
+
"ts-type-forge": "7.x"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@rollup/plugin-replace": "6.0.3",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@semantic-release/github": "12.0.9",
|
|
99
99
|
"@semantic-release/npm": "13.1.5",
|
|
100
100
|
"@semantic-release/release-notes-generator": "14.1.1",
|
|
101
|
-
"@types/node": "26.1.
|
|
101
|
+
"@types/node": "26.1.1",
|
|
102
102
|
"@vitest/browser-playwright": "4.1.10",
|
|
103
103
|
"@vitest/coverage-v8": "4.1.10",
|
|
104
104
|
"@vitest/ui": "4.1.10",
|
|
@@ -106,14 +106,15 @@
|
|
|
106
106
|
"cspell": "10.0.1",
|
|
107
107
|
"esbuild": "0.28.1",
|
|
108
108
|
"eslint": "9.39.4",
|
|
109
|
-
"eslint-config-typed": "5.
|
|
109
|
+
"eslint-config-typed": "5.8.0",
|
|
110
|
+
"eslint-plugin-ts-data-forge": "0.1.6",
|
|
110
111
|
"fast-glob": "3.3.3",
|
|
111
112
|
"fp-ts": "2.16.11",
|
|
112
113
|
"github-settings-as-code": "1.2.9",
|
|
113
114
|
"io-ts": "2.2.22",
|
|
114
115
|
"jiti": "2.7.0",
|
|
115
|
-
"markdownlint": "0.41.
|
|
116
|
-
"markdownlint-cli2": "0.23.
|
|
116
|
+
"markdownlint": "0.41.1",
|
|
117
|
+
"markdownlint-cli2": "0.23.1",
|
|
117
118
|
"npm-run-all2": "9.0.2",
|
|
118
119
|
"playwright": "1.61.1",
|
|
119
120
|
"prettier": "3.9.5",
|
|
@@ -121,19 +122,19 @@
|
|
|
121
122
|
"prettier-plugin-packagejson": "3.0.2",
|
|
122
123
|
"rollup": "4.62.2",
|
|
123
124
|
"rollup-plugin-esbuild": "6.2.1",
|
|
124
|
-
"semantic-release": "25.0.
|
|
125
|
-
"ts-codemod-lib": "2.2.
|
|
126
|
-
"ts-repo-utils": "10.1.
|
|
127
|
-
"tsx": "4.
|
|
128
|
-
"typedoc": "0.28.
|
|
125
|
+
"semantic-release": "25.0.7",
|
|
126
|
+
"ts-codemod-lib": "2.2.2",
|
|
127
|
+
"ts-repo-utils": "10.1.3",
|
|
128
|
+
"tsx": "4.23.1",
|
|
129
|
+
"typedoc": "0.28.20",
|
|
129
130
|
"typedoc-github-theme": "0.4.0",
|
|
130
131
|
"typescript": "6.0.3",
|
|
131
|
-
"typescript-native": "npm:typescript@7.0.
|
|
132
|
-
"vite": "8.1.
|
|
132
|
+
"typescript-native": "npm:typescript@7.0.2",
|
|
133
|
+
"vite": "8.1.5",
|
|
133
134
|
"vitest": "4.1.10",
|
|
134
135
|
"zod": "4.4.3"
|
|
135
136
|
},
|
|
136
|
-
"packageManager": "pnpm@11.
|
|
137
|
+
"packageManager": "pnpm@11.17.0",
|
|
137
138
|
"engines": {
|
|
138
139
|
"node": ">=22.22.2",
|
|
139
140
|
"pnpm": ">=9.0.0"
|
package/src/record/at.mts
CHANGED
|
@@ -101,7 +101,7 @@ export function at(
|
|
|
101
101
|
const hasOptionalMember = memberTypes.some(isOptionalProperty);
|
|
102
102
|
|
|
103
103
|
const collected: readonly Type<unknown>[] = hasOptionalMember
|
|
104
|
-
? (
|
|
104
|
+
? Arr.toPushed(memberTypes, undefinedType)
|
|
105
105
|
: memberTypes;
|
|
106
106
|
|
|
107
107
|
if (Arr.isMinLengthTuple(collected, 2)) {
|
|
@@ -249,7 +249,7 @@ const createDetailsMessage = (
|
|
|
249
249
|
|
|
250
250
|
case 'enum':
|
|
251
251
|
return `expected one of { ${error.details.values
|
|
252
|
-
.map(
|
|
252
|
+
.map(String)
|
|
253
253
|
.join(', ')} } but${actualValueStr} was passed.`;
|
|
254
254
|
|
|
255
255
|
case 'union':
|
|
@@ -395,7 +395,7 @@ export const prependPathToValidationErrors = (
|
|
|
395
395
|
): readonly ValidationError[] =>
|
|
396
396
|
errors.map((error) => ({
|
|
397
397
|
...error,
|
|
398
|
-
path:
|
|
398
|
+
path: Arr.toUnshifted(pathSegment)(error.path),
|
|
399
399
|
}));
|
|
400
400
|
|
|
401
401
|
/**
|