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 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,CACjC;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"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convex-helpers",
3
- "version": "0.1.83",
3
+ "version": "0.1.85",
4
4
  "description": "A collection of useful code to complement the official convex package.",
5
5
  "type": "module",
6
6
  "bin": {
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<import("convex/values").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]>]: import("convex/values").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"]>;
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<import("convex/values").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]>]: import("convex/values").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<import("convex/values").Infer<Key>, Value["type"]>, Key, Value, "required", string>;
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
@@ -1 +1 @@
1
- {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["validators.ts"],"names":[],"mappings":"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"}
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
- for (const k of Object.keys(value)) {
364
- if (validator.fields[k] === undefined) {
365
- if (opts?.throw) {
366
- throw new ValidationError("nothing", typeof value[k], appendPath(opts, k));
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
- for (const k of Object.keys(value)) {
484
- if (validator.fields[k] === undefined) {
485
- if (opts?.throw) {
486
- throw new ValidationError(
487
- "nothing",
488
- typeof (value as any)[k],
489
- appendPath(opts, k),
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
  }