convex-helpers 0.1.83 → 0.1.85
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/index.d.ts +13 -1
- package/index.d.ts.map +1 -1
- package/index.js +14 -0
- package/index.test.ts +41 -0
- package/index.ts +16 -1
- package/package.json +1 -1
- package/validators.d.ts +6 -4
- package/validators.d.ts.map +1 -1
- package/validators.js +53 -6
- package/validators.ts +70 -10
package/index.d.ts
CHANGED
|
@@ -57,7 +57,19 @@ export declare function pick<T extends Record<string, any>, Keys extends (keyof
|
|
|
57
57
|
* @param keys The keys to omit from the object.
|
|
58
58
|
* @returns A new object with the keys you omitted removed.
|
|
59
59
|
*/
|
|
60
|
-
export declare function omit<T extends Record<string, any>, Keys extends (keyof T)[]>(obj: T, keys: Keys): BetterOmit<T, Keys[number]
|
|
60
|
+
export declare function omit<T extends Record<string, any>, Keys extends (keyof T)[]>(obj: T, keys: Keys): Expand<BetterOmit<T, Keys[number]>>;
|
|
61
|
+
/**
|
|
62
|
+
* Removes the _id and _creationTime fields from an object.
|
|
63
|
+
* This enables easily cloning a Convex document like:
|
|
64
|
+
* ```ts
|
|
65
|
+
* const doc = await db.get(id);
|
|
66
|
+
* const clone = withoutSystemFields(doc);
|
|
67
|
+
* await db.insert(table, clone);
|
|
68
|
+
* ```
|
|
69
|
+
* @param obj The object to remove the _id and _creationTime fields from.
|
|
70
|
+
* @returns A new object with the _id and _creationTime fields removed.
|
|
71
|
+
*/
|
|
72
|
+
export declare function withoutSystemFields<T extends Record<string, any>>(obj: T): Expand<BetterOmit<T, "_id" | "_creationTime">>;
|
|
61
73
|
declare const error: unique symbol;
|
|
62
74
|
export type ErrorMessage<Reason extends string> = Reason & {
|
|
63
75
|
__error: typeof error;
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAC7C,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EACtD,cAAc,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACjE,OAAO,CAAC,MAAM,EAAE,CAAC,CASnB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAEpD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAE/C;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAKhE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAC1E,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,IAAI,GAIL,GACF,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAC1B,CACF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAC1E,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,IAAI,GAIL,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAC7C,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EACtD,cAAc,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACjE,OAAO,CAAC,MAAM,EAAE,CAAC,CASnB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAEpD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAE/C;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAKhE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAC1E,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,IAAI,GAIL,GACF,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAC1B,CACF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAC1E,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,IAAI,GAIL,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CACzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,kDAExE;AAGD,QAAA,MAAM,KAAK,eAAW,CAAC;AACvB,MAAM,MAAM,YAAY,CAAC,MAAM,SAAS,MAAM,IAAI,MAAM,GAAG;IACzD,OAAO,EAAE,OAAO,KAAK,CAAC;CACvB,CAAC;AAGF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAChD;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI;KAC5C,QAAQ,IAAI,MAAM,CAAC,IAAI,QAAQ,SAAS,CAAC,GAAG,KAAK,GAAG,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;CAC5E,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAC,UAAU,SAAS,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IACpD,UAAU,SAAS,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAC/B;KACG,GAAG,IAAI,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC;CAC3C,GACD,KAAK,CAAC;AAEZ;;GAEG;AACH;;;;GAIG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IACrB,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAC/D,IAAI,GACJ,KAAK,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAItE"}
|
package/index.js
CHANGED
|
@@ -78,6 +78,20 @@ export function pick(obj, keys) {
|
|
|
78
78
|
export function omit(obj, keys) {
|
|
79
79
|
return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
|
|
80
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Removes the _id and _creationTime fields from an object.
|
|
83
|
+
* This enables easily cloning a Convex document like:
|
|
84
|
+
* ```ts
|
|
85
|
+
* const doc = await db.get(id);
|
|
86
|
+
* const clone = withoutSystemFields(doc);
|
|
87
|
+
* await db.insert(table, clone);
|
|
88
|
+
* ```
|
|
89
|
+
* @param obj The object to remove the _id and _creationTime fields from.
|
|
90
|
+
* @returns A new object with the _id and _creationTime fields removed.
|
|
91
|
+
*/
|
|
92
|
+
export function withoutSystemFields(obj) {
|
|
93
|
+
return omit(obj, ["_id", "_creationTime"]);
|
|
94
|
+
}
|
|
81
95
|
// Type utils:
|
|
82
96
|
const error = Symbol();
|
|
83
97
|
/**
|
package/index.test.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import { withoutSystemFields } from "./index.js";
|
|
3
|
+
import { test, expect, expectTypeOf } from "vitest";
|
|
4
|
+
|
|
5
|
+
test("withoutSystemFields", () => {
|
|
6
|
+
const obj = { _id: "1", _creationTime: 1, a: "a" };
|
|
7
|
+
const without = withoutSystemFields(obj);
|
|
8
|
+
expect(without).toEqual({ a: "a" });
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("withoutSystemFields when fields aren't present", () => {
|
|
12
|
+
const obj = { a: "a" };
|
|
13
|
+
const without = withoutSystemFields(obj);
|
|
14
|
+
expect(without).toEqual({ a: "a" });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("withoutSystemFields type when it's a union", () => {
|
|
18
|
+
const obj = { a: "a" } as
|
|
19
|
+
| { a: string }
|
|
20
|
+
| { _id: string; _creationTime: number };
|
|
21
|
+
const without = withoutSystemFields(obj);
|
|
22
|
+
expect(without).toEqual({ a: "a" });
|
|
23
|
+
expectTypeOf(without).toEqualTypeOf<{ a: string } | {}>();
|
|
24
|
+
const obj2 = { _id: "1", _creationTime: 1, a: "a" } as
|
|
25
|
+
| { _id: string; _creationTime: number; a: string }
|
|
26
|
+
| { _id: string; _creationTime: number; b: string };
|
|
27
|
+
const without2 = withoutSystemFields(obj2);
|
|
28
|
+
expect(without2).toEqual({ a: "a" });
|
|
29
|
+
expectTypeOf(without2).toEqualTypeOf<{ a: string } | { b: string }>();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("withoutSystemFields works on validators too", () => {
|
|
33
|
+
const validator = v.object({
|
|
34
|
+
_id: v.string(),
|
|
35
|
+
_creationTime: v.number(),
|
|
36
|
+
a: v.string(),
|
|
37
|
+
});
|
|
38
|
+
const { _id, _creationTime, ...rest } = validator.fields;
|
|
39
|
+
const without = withoutSystemFields(validator.fields);
|
|
40
|
+
expectTypeOf(without).toEqualTypeOf<typeof rest>();
|
|
41
|
+
});
|
package/index.ts
CHANGED
|
@@ -95,7 +95,22 @@ export function omit<T extends Record<string, any>, Keys extends (keyof T)[]>(
|
|
|
95
95
|
) {
|
|
96
96
|
return Object.fromEntries(
|
|
97
97
|
Object.entries(obj).filter(([k]) => !keys.includes(k as Keys[number])),
|
|
98
|
-
) as BetterOmit<T, Keys[number]
|
|
98
|
+
) as Expand<BetterOmit<T, Keys[number]>>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Removes the _id and _creationTime fields from an object.
|
|
103
|
+
* This enables easily cloning a Convex document like:
|
|
104
|
+
* ```ts
|
|
105
|
+
* const doc = await db.get(id);
|
|
106
|
+
* const clone = withoutSystemFields(doc);
|
|
107
|
+
* await db.insert(table, clone);
|
|
108
|
+
* ```
|
|
109
|
+
* @param obj The object to remove the _id and _creationTime fields from.
|
|
110
|
+
* @returns A new object with the _id and _creationTime fields removed.
|
|
111
|
+
*/
|
|
112
|
+
export function withoutSystemFields<T extends Record<string, any>>(obj: T) {
|
|
113
|
+
return omit(obj, ["_id", "_creationTime"]);
|
|
99
114
|
}
|
|
100
115
|
|
|
101
116
|
// Type utils:
|
package/package.json
CHANGED
package/validators.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GenericValidator, ObjectType, PropertyValidators, VObject, VOptional, VString, VUnion, Validator } from "convex/values";
|
|
1
|
+
import type { GenericValidator, Infer, ObjectType, PropertyValidators, VObject, VOptional, VString, VUnion, Validator } from "convex/values";
|
|
2
2
|
import type { Expand } from "./index.js";
|
|
3
3
|
import type { DataModelFromSchemaDefinition, GenericDatabaseReader, GenericDataModel, SchemaDefinition, TableNamesInDataModel } from "convex/server";
|
|
4
4
|
/**
|
|
@@ -53,7 +53,7 @@ export declare const any: import("convex/values").VAny<any, "required", string>;
|
|
|
53
53
|
/** Null value. Underscore is so it doesn't shadow the null builtin */
|
|
54
54
|
export declare const null_: import("convex/values").VNull<null, "required">;
|
|
55
55
|
/** Re-export values from v without having to do v.* */
|
|
56
|
-
export declare const id: <TableName extends string>(tableName: TableName) => import("convex/values").VId<import("convex/values").GenericId<TableName>, "required">, object: <T_2 extends PropertyValidators>(fields: T_2) => VObject<import("convex/server").Expand<{ [Property in { [Property_1 in keyof T_2]: T_2[Property_1]["isOptional"] extends "optional" ? Property_1 : never; }[keyof T_2]]?: Exclude<
|
|
56
|
+
export declare const id: <TableName extends string>(tableName: TableName) => import("convex/values").VId<import("convex/values").GenericId<TableName>, "required">, object: <T_2 extends PropertyValidators>(fields: T_2) => VObject<import("convex/server").Expand<{ [Property in { [Property_1 in keyof T_2]: T_2[Property_1]["isOptional"] extends "optional" ? Property_1 : never; }[keyof T_2]]?: Exclude<Infer<T_2[Property]>, undefined> | undefined; } & { [Property_1 in Exclude<keyof T_2, { [Property in keyof T_2]: T_2[Property]["isOptional"] extends "optional" ? Property : never; }[keyof T_2]>]: Infer<T_2[Property_1]>; }>, T_2, "required", { [Property_2 in keyof T_2]: Property_2 | `${Property_2 & string}.${T_2[Property_2]["fieldPaths"]}`; }[keyof T_2] & string>, array: <T_1 extends Validator<any, "required", any>>(element: T_1) => import("convex/values").VArray<T_1["type"][], T_1, "required">, bytes: () => import("convex/values").VBytes<ArrayBuffer, "required">, literal: <T extends string | number | bigint | boolean>(literal: T) => import("convex/values").VLiteral<T, "required">, optional: <T_4 extends GenericValidator>(value: T_4) => VOptional<T_4>, union: <T_3 extends Validator<any, "required", any>[]>(...members: T_3) => VUnion<T_3[number]["type"], T_3, "required", T_3[number]["fieldPaths"]>;
|
|
57
57
|
/** ArrayBuffer validator. */
|
|
58
58
|
export declare const arrayBuffer: import("convex/values").VBytes<ArrayBuffer, "required">;
|
|
59
59
|
/**
|
|
@@ -131,8 +131,8 @@ export declare function typedV<Schema extends SchemaDefinition<any, boolean>>(sc
|
|
|
131
131
|
bytes: () => import("convex/values").VBytes<ArrayBuffer, "required">;
|
|
132
132
|
literal: <T extends string | number | bigint | boolean>(literal: T) => import("convex/values").VLiteral<T, "required">;
|
|
133
133
|
array: <T_1 extends Validator<any, "required", any>>(element: T_1) => import("convex/values").VArray<T_1["type"][], T_1, "required">;
|
|
134
|
-
object: <T_2 extends PropertyValidators>(fields: T_2) => VObject<import("convex/server").Expand<{ [Property in { [Property_1 in keyof T_2]: T_2[Property_1]["isOptional"] extends "optional" ? Property_1 : never; }[keyof T_2]]?: Exclude<
|
|
135
|
-
record: <Key extends Validator<string, "required", any>, Value extends Validator<any, "required", any>>(keys: Key, values: Value) => import("convex/values").VRecord<Record<
|
|
134
|
+
object: <T_2 extends PropertyValidators>(fields: T_2) => VObject<import("convex/server").Expand<{ [Property in { [Property_1 in keyof T_2]: T_2[Property_1]["isOptional"] extends "optional" ? Property_1 : never; }[keyof T_2]]?: Exclude<Infer<T_2[Property]>, undefined> | undefined; } & { [Property_1 in Exclude<keyof T_2, { [Property in keyof T_2]: T_2[Property]["isOptional"] extends "optional" ? Property : never; }[keyof T_2]>]: Infer<T_2[Property_1]>; }>, T_2, "required", { [Property_2 in keyof T_2]: Property_2 | `${Property_2 & string}.${T_2[Property_2]["fieldPaths"]}`; }[keyof T_2] & string>;
|
|
135
|
+
record: <Key extends Validator<string, "required", any>, Value extends Validator<any, "required", any>>(keys: Key, values: Value) => import("convex/values").VRecord<Record<Infer<Key>, Value["type"]>, Key, Value, "required", string>;
|
|
136
136
|
union: <T_3 extends Validator<any, "required", any>[]>(...members: T_3) => VUnion<T_3[number]["type"], T_3, "required", T_3[number]["fieldPaths"]>;
|
|
137
137
|
any: () => import("convex/values").VAny<any, "required", string>;
|
|
138
138
|
optional: <T_4 extends GenericValidator>(value: T_4) => VOptional<T_4>;
|
|
@@ -235,6 +235,8 @@ export declare class ValidationError extends Error {
|
|
|
235
235
|
export declare function validate<T extends Validator<any, any, any>>(validator: T, value: unknown, opts?: {
|
|
236
236
|
throw?: boolean;
|
|
237
237
|
db?: GenericDatabaseReader<GenericDataModel>;
|
|
238
|
+
allowUnknownFields?: boolean;
|
|
238
239
|
_pathPrefix?: string;
|
|
239
240
|
}): value is T["type"];
|
|
241
|
+
export declare function parse<T extends Validator<any, any, any>>(validator: T, value: unknown): Infer<T>;
|
|
240
242
|
//# sourceMappingURL=validators.d.ts.map
|
package/validators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["validators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,OAAO,EACP,SAAS,EACT,OAAO,EACP,MAAM,EACN,SAAS,EACV,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EACV,6BAA6B,EAC7B,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,QAAQ,GACnB,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAC5C,CAAC,SAAS,CAAC,EAAE,EAEb,GAAG,MAAM,CAAC,KACT,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAMvB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,iNAClD,CAAC;AAEvB;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,kBAAkB,EAAE,KAAK,CAAC,KAMrD,GACF,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAElC,CAAC;AAIF,wBAAwB;AACxB,eAAO,MAAM,MAAM,6BAAa,CAAC;AACjC,mEAAmE;AACnE,eAAO,MAAM,MAAM,sDAAc,CAAC;AAClC,mEAAmE;AACnE,eAAO,MAAM,OAAO,sDAAc,CAAC;AACnC,+DAA+D;AAC/D,eAAO,MAAM,OAAO,uDAAc,CAAC;AACnC,yDAAyD;AACzD,eAAO,MAAM,MAAM,oDAAY,CAAC;AAChC,yDAAyD;AACzD,eAAO,MAAM,KAAK,oDAAY,CAAC;AAC/B,uBAAuB;AACvB,eAAO,MAAM,GAAG,uDAAU,CAAC;AAC3B,sEAAsE;AACtE,eAAO,MAAM,KAAK,iDAAW,CAAC;AAC9B,uDAAuD;AACvD,eAAO,MAAQ,EAAE,6IAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["validators.ts"],"names":[],"mappings":"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"}
|
package/validators.js
CHANGED
|
@@ -360,13 +360,15 @@ export function validate(validator, value, opts) {
|
|
|
360
360
|
break;
|
|
361
361
|
}
|
|
362
362
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
if (
|
|
366
|
-
|
|
363
|
+
if (!opts?.allowUnknownFields) {
|
|
364
|
+
for (const k of Object.keys(value)) {
|
|
365
|
+
if (validator.fields[k] === undefined) {
|
|
366
|
+
if (opts?.throw) {
|
|
367
|
+
throw new ValidationError("nothing", typeof value[k], appendPath(opts, k));
|
|
368
|
+
}
|
|
369
|
+
valid = false;
|
|
370
|
+
break;
|
|
367
371
|
}
|
|
368
|
-
valid = false;
|
|
369
|
-
break;
|
|
370
372
|
}
|
|
371
373
|
}
|
|
372
374
|
break;
|
|
@@ -413,6 +415,51 @@ export function validate(validator, value, opts) {
|
|
|
413
415
|
}
|
|
414
416
|
return valid;
|
|
415
417
|
}
|
|
418
|
+
export function parse(validator, value) {
|
|
419
|
+
validate(validator, value, { allowUnknownFields: true, throw: true });
|
|
420
|
+
return stripUnknownFields(validator, value);
|
|
421
|
+
}
|
|
422
|
+
function stripUnknownFields(validator, value) {
|
|
423
|
+
switch (validator.kind) {
|
|
424
|
+
case "object": {
|
|
425
|
+
const result = {};
|
|
426
|
+
for (const [k, v] of Object.entries(value)) {
|
|
427
|
+
if (validator.fields[k] !== undefined) {
|
|
428
|
+
result[k] = stripUnknownFields(validator.fields[k], v);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return result;
|
|
432
|
+
}
|
|
433
|
+
case "record": {
|
|
434
|
+
const result = {};
|
|
435
|
+
for (const [k, v] of Object.entries(value)) {
|
|
436
|
+
result[k] = stripUnknownFields(validator.value, v);
|
|
437
|
+
}
|
|
438
|
+
return result;
|
|
439
|
+
}
|
|
440
|
+
case "array": {
|
|
441
|
+
return value.map((e) => stripUnknownFields(validator.element, e));
|
|
442
|
+
}
|
|
443
|
+
case "union": {
|
|
444
|
+
// First try a strict match
|
|
445
|
+
for (const member of validator.members) {
|
|
446
|
+
if (validate(member, value, { allowUnknownFields: false })) {
|
|
447
|
+
return stripUnknownFields(member, value);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// Then try a permissive match
|
|
451
|
+
for (const member of validator.members) {
|
|
452
|
+
if (validate(member, value, { allowUnknownFields: true })) {
|
|
453
|
+
return stripUnknownFields(member, value);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
throw new Error("No matching member in union");
|
|
457
|
+
}
|
|
458
|
+
default: {
|
|
459
|
+
return value;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
416
463
|
function appendPath(opts, path) {
|
|
417
464
|
return opts?._pathPrefix ? `${opts._pathPrefix}.${path}` : path;
|
|
418
465
|
}
|
package/validators.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
GenericValidator,
|
|
3
|
+
Infer,
|
|
3
4
|
ObjectType,
|
|
4
5
|
PropertyValidators,
|
|
5
6
|
VObject,
|
|
@@ -363,6 +364,8 @@ export function validate<T extends Validator<any, any, any>>(
|
|
|
363
364
|
throw?: boolean;
|
|
364
365
|
/* If provided, v.id validation will check that the id is for the table. */
|
|
365
366
|
db?: GenericDatabaseReader<GenericDataModel>;
|
|
367
|
+
/* If true, allow fields that are not in an object validator. */
|
|
368
|
+
allowUnknownFields?: boolean;
|
|
366
369
|
/* A prefix for the path of the value being validated, for error reporting.
|
|
367
370
|
This is used for recursive calls, do not set it manually. */
|
|
368
371
|
_pathPrefix?: string;
|
|
@@ -480,17 +483,19 @@ export function validate<T extends Validator<any, any, any>>(
|
|
|
480
483
|
break;
|
|
481
484
|
}
|
|
482
485
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
if (
|
|
486
|
-
throw
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
486
|
+
if (!opts?.allowUnknownFields) {
|
|
487
|
+
for (const k of Object.keys(value)) {
|
|
488
|
+
if (validator.fields[k] === undefined) {
|
|
489
|
+
if (opts?.throw) {
|
|
490
|
+
throw new ValidationError(
|
|
491
|
+
"nothing",
|
|
492
|
+
typeof (value as any)[k],
|
|
493
|
+
appendPath(opts, k),
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
valid = false;
|
|
497
|
+
break;
|
|
491
498
|
}
|
|
492
|
-
valid = false;
|
|
493
|
-
break;
|
|
494
499
|
}
|
|
495
500
|
}
|
|
496
501
|
break;
|
|
@@ -538,6 +543,61 @@ export function validate<T extends Validator<any, any, any>>(
|
|
|
538
543
|
return valid;
|
|
539
544
|
}
|
|
540
545
|
|
|
546
|
+
export function parse<T extends Validator<any, any, any>>(
|
|
547
|
+
validator: T,
|
|
548
|
+
value: unknown,
|
|
549
|
+
): Infer<T> {
|
|
550
|
+
validate(validator, value, { allowUnknownFields: true, throw: true });
|
|
551
|
+
return stripUnknownFields(validator, value);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
function stripUnknownFields<T extends Validator<any, any, any>>(
|
|
555
|
+
validator: T,
|
|
556
|
+
value: Infer<T>,
|
|
557
|
+
): Infer<T> {
|
|
558
|
+
switch (validator.kind) {
|
|
559
|
+
case "object": {
|
|
560
|
+
const result: Infer<T> = {};
|
|
561
|
+
for (const [k, v] of Object.entries(value)) {
|
|
562
|
+
if (validator.fields[k] !== undefined) {
|
|
563
|
+
result[k] = stripUnknownFields(validator.fields[k], v);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return result;
|
|
567
|
+
}
|
|
568
|
+
case "record": {
|
|
569
|
+
const result: Infer<T> = {};
|
|
570
|
+
for (const [k, v] of Object.entries(value)) {
|
|
571
|
+
result[k] = stripUnknownFields(validator.value, v);
|
|
572
|
+
}
|
|
573
|
+
return result;
|
|
574
|
+
}
|
|
575
|
+
case "array": {
|
|
576
|
+
return (value as any[]).map((e) =>
|
|
577
|
+
stripUnknownFields(validator.element, e),
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
case "union": {
|
|
581
|
+
// First try a strict match
|
|
582
|
+
for (const member of validator.members) {
|
|
583
|
+
if (validate(member, value, { allowUnknownFields: false })) {
|
|
584
|
+
return stripUnknownFields(member, value);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
// Then try a permissive match
|
|
588
|
+
for (const member of validator.members) {
|
|
589
|
+
if (validate(member, value, { allowUnknownFields: true })) {
|
|
590
|
+
return stripUnknownFields(member, value);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
throw new Error("No matching member in union");
|
|
594
|
+
}
|
|
595
|
+
default: {
|
|
596
|
+
return value as Infer<T>;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
541
601
|
function appendPath(opts: { _pathPrefix?: string } | undefined, path: string) {
|
|
542
602
|
return opts?._pathPrefix ? `${opts._pathPrefix}.${path}` : path;
|
|
543
603
|
}
|