@confect/core 10.2.0 → 10.3.1
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/CHANGELOG.md +20 -0
- package/dist/GroupSpec.d.ts +5 -7
- package/dist/GroupSpec.d.ts.map +1 -1
- package/dist/GroupSpec.js +9 -45
- package/dist/GroupSpec.js.map +1 -1
- package/dist/SchemaToValidator.d.ts +16 -15
- package/dist/SchemaToValidator.d.ts.map +1 -1
- package/dist/SchemaToValidator.js.map +1 -1
- package/dist/Spec.d.ts +1 -4
- package/dist/Spec.d.ts.map +1 -1
- package/dist/Spec.js +4 -14
- package/dist/Spec.js.map +1 -1
- package/dist/SystemFields.js +1 -1
- package/dist/Types.d.ts +13 -2
- package/dist/Types.d.ts.map +1 -1
- package/dist/Types.js.map +1 -1
- package/package.json +6 -6
- package/src/GroupSpec.ts +20 -83
- package/src/SchemaToValidator.ts +108 -97
- package/src/Spec.ts +6 -44
- package/src/Types.ts +40 -13
package/dist/Types.d.ts
CHANGED
|
@@ -22,8 +22,19 @@ export interface TypeDefect<Message extends string, T = never> {
|
|
|
22
22
|
}
|
|
23
23
|
export type IsRecursive<T> = true extends DetectCycle<T> ? true : false;
|
|
24
24
|
type NonRecursiveLeaf = Brand.Brand<any> | GenericId<any> | ArrayBuffer;
|
|
25
|
-
type
|
|
26
|
-
|
|
25
|
+
type IsSame<A, B> = (<G>() => G extends A ? 1 : 2) extends <G>() => (G extends B ? 1 : 2) ? true : false;
|
|
26
|
+
type IsObject<T> = T extends object ? true : false;
|
|
27
|
+
/**
|
|
28
|
+
* Whether `T` is one of the types already on the path, compared by identity.
|
|
29
|
+
* Assignability is not enough: a nested struct is assignable to an ancestor
|
|
30
|
+
* whenever the ancestor's extra fields are optional, and two structs whose
|
|
31
|
+
* fields are all optional can be assignable to each other in both directions.
|
|
32
|
+
* `DetectCycle` asks only once `T` is assignable to some type on the path,
|
|
33
|
+
* which keeps the identity comparisons off the common, non-recursive case.
|
|
34
|
+
*/
|
|
35
|
+
type IsAncestor<T, Ancestors> = Ancestors extends unknown ? IsSame<T, Ancestors> : never;
|
|
36
|
+
type DetectCycle<T, Ancestors = never> = IsAny<T> extends true ? false : [T] extends [any] ? T extends NonRecursiveLeaf ? false : IsObject<T> extends false ? false : (T extends Ancestors ? true extends IsAncestor<T, Ancestors> ? true : false : false) extends true ? true : T extends Array<infer U> ? DetectCycle<U, Ancestors | T> : T extends Map<infer _U, infer V> ? DetectCycle<V, Ancestors | T> : T extends Set<infer U> ? DetectCycle<U, Ancestors | T> : T extends object ? true extends {
|
|
37
|
+
[K in keyof T]: DetectCycle<T[K], Ancestors | T>;
|
|
27
38
|
}[keyof T] ? true : false : false : never;
|
|
28
39
|
export type UnionToTuple<t> = _unionToTuple<t, []> extends infer result ? conform<result, t[]> : never;
|
|
29
40
|
type _unionToTuple<t, result extends unknown[]> = getLastBranch<t> extends infer current ? [t] extends [never] ? result : _unionToTuple<Exclude<t, current>, [current, ...result]> : never;
|
package/dist/Types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../src/Types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../src/Types.ts"],"names":[],"mappings":"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"}
|
package/dist/Types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Types.js","names":[],"sources":["../src/Types.ts"],"sourcesContent":["import type {\n DocumentByName,\n FieldTypeFromFieldPath,\n GenericDatabaseReader,\n GenericDataModel,\n TableNamesInDataModel,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\nimport type { Brand } from \"effect\";\n\nexport type IsOptional<T, K extends keyof T> =\n {} extends Pick<T, K> ? true : false;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\nexport type IsUnion<T, U extends T = T> = T extends unknown\n ? [U] extends [T]\n ? false\n : true\n : never;\n\n// https://stackoverflow.com/a/52806744\nexport type IsValueLiteral<Vl> = [Vl] extends [never]\n ? never\n : IsUnion<Vl> extends true\n ? false\n : [Vl] extends [string | number | bigint | boolean]\n ? [string] extends [Vl]\n ? false\n : [number] extends [Vl]\n ? false\n : [boolean] extends [Vl]\n ? false\n : [bigint] extends [Vl]\n ? false\n : true\n : false;\n\n/**\n * Only checks for records with string keys.\n */\nexport type IsRecord<T> = [T] extends [never]\n ? false\n : IsUnion<T> extends true\n ? false\n : T extends Record<string, infer V>\n ? string extends keyof T\n ? keyof T extends string\n ? T extends Record<string, V>\n ? Record<string, V> extends T\n ? true\n : false\n : false\n : false\n : false\n : false;\n\nexport type DeepMutable<T> =\n IsAny<T> extends true\n ? any\n : T extends NonRecursiveLeaf\n ? T\n : T extends ReadonlyMap<infer K, infer V>\n ? Map<DeepMutable<K>, DeepMutable<V>>\n : T extends ReadonlySet<infer V>\n ? Set<DeepMutable<V>>\n : [keyof T] extends [never]\n ? T\n : {\n -readonly [K in keyof T]: IsOptional<T, K> extends true\n ? DeepMutable<Exclude<T[K], undefined>>\n : DeepMutable<T[K]>;\n };\n\nexport interface TypeError<Message extends string, T = never> {\n readonly \"~@confect/core/Types/TypeError\": Message;\n readonly \"~value\"?: T;\n}\n\nexport interface TypeDefect<Message extends string, T = never> {\n readonly \"~@confect/core/Types/TypeDefect\": Message;\n readonly \"~value\"?: T;\n}\n\nexport type IsRecursive<T> = true extends DetectCycle<T> ? true : false;\n\ntype NonRecursiveLeaf = Brand.Brand<any> | GenericId<any> | ArrayBuffer;\n\ntype DetectCycle<T,
|
|
1
|
+
{"version":3,"file":"Types.js","names":[],"sources":["../src/Types.ts"],"sourcesContent":["import type {\n DocumentByName,\n FieldTypeFromFieldPath,\n GenericDatabaseReader,\n GenericDataModel,\n TableNamesInDataModel,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\nimport type { Brand } from \"effect\";\n\nexport type IsOptional<T, K extends keyof T> =\n {} extends Pick<T, K> ? true : false;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\nexport type IsUnion<T, U extends T = T> = T extends unknown\n ? [U] extends [T]\n ? false\n : true\n : never;\n\n// https://stackoverflow.com/a/52806744\nexport type IsValueLiteral<Vl> = [Vl] extends [never]\n ? never\n : IsUnion<Vl> extends true\n ? false\n : [Vl] extends [string | number | bigint | boolean]\n ? [string] extends [Vl]\n ? false\n : [number] extends [Vl]\n ? false\n : [boolean] extends [Vl]\n ? false\n : [bigint] extends [Vl]\n ? false\n : true\n : false;\n\n/**\n * Only checks for records with string keys.\n */\nexport type IsRecord<T> = [T] extends [never]\n ? false\n : IsUnion<T> extends true\n ? false\n : T extends Record<string, infer V>\n ? string extends keyof T\n ? keyof T extends string\n ? T extends Record<string, V>\n ? Record<string, V> extends T\n ? true\n : false\n : false\n : false\n : false\n : false;\n\nexport type DeepMutable<T> =\n IsAny<T> extends true\n ? any\n : T extends NonRecursiveLeaf\n ? T\n : T extends ReadonlyMap<infer K, infer V>\n ? Map<DeepMutable<K>, DeepMutable<V>>\n : T extends ReadonlySet<infer V>\n ? Set<DeepMutable<V>>\n : [keyof T] extends [never]\n ? T\n : {\n -readonly [K in keyof T]: IsOptional<T, K> extends true\n ? DeepMutable<Exclude<T[K], undefined>>\n : DeepMutable<T[K]>;\n };\n\nexport interface TypeError<Message extends string, T = never> {\n readonly \"~@confect/core/Types/TypeError\": Message;\n readonly \"~value\"?: T;\n}\n\nexport interface TypeDefect<Message extends string, T = never> {\n readonly \"~@confect/core/Types/TypeDefect\": Message;\n readonly \"~value\"?: T;\n}\n\nexport type IsRecursive<T> = true extends DetectCycle<T> ? true : false;\n\ntype NonRecursiveLeaf = Brand.Brand<any> | GenericId<any> | ArrayBuffer;\n\ntype IsSame<A, B> =\n (<G>() => G extends A ? 1 : 2) extends <G>() => G extends B ? 1 : 2\n ? true\n : false;\n\ntype IsObject<T> = T extends object ? true : false;\n\n/**\n * Whether `T` is one of the types already on the path, compared by identity.\n * Assignability is not enough: a nested struct is assignable to an ancestor\n * whenever the ancestor's extra fields are optional, and two structs whose\n * fields are all optional can be assignable to each other in both directions.\n * `DetectCycle` asks only once `T` is assignable to some type on the path,\n * which keeps the identity comparisons off the common, non-recursive case.\n */\ntype IsAncestor<T, Ancestors> = Ancestors extends unknown\n ? IsSame<T, Ancestors>\n : never;\n\ntype DetectCycle<T, Ancestors = never> =\n IsAny<T> extends true\n ? false\n : [T] extends [any]\n ? T extends NonRecursiveLeaf\n ? false\n : IsObject<T> extends false\n ? false\n : (\n T extends Ancestors\n ? true extends IsAncestor<T, Ancestors>\n ? true\n : false\n : false\n ) extends true\n ? true\n : T extends Array<infer U>\n ? DetectCycle<U, Ancestors | T>\n : T extends Map<infer _U, infer V>\n ? DetectCycle<V, Ancestors | T>\n : T extends Set<infer U>\n ? DetectCycle<U, Ancestors | T>\n : T extends object\n ? true extends {\n [K in keyof T]: DetectCycle<T[K], Ancestors | T>;\n }[keyof T]\n ? true\n : false\n : false\n : never;\n\n//////////////////////////////////\n// START: Vendored from Arktype //\n//////////////////////////////////\n\n// https://github.com/arktypeio/arktype/blob/2e911d01a741ccee7a17e31ee144049817fabbb8/ark/util/unionToTuple.ts#L9\n\nexport type UnionToTuple<t> =\n _unionToTuple<t, []> extends infer result ? conform<result, t[]> : never;\n\ntype _unionToTuple<t, result extends unknown[]> =\n getLastBranch<t> extends infer current\n ? [t] extends [never]\n ? result\n : _unionToTuple<Exclude<t, current>, [current, ...result]>\n : never;\n\ntype getLastBranch<t> =\n intersectUnion<t extends unknown ? (x: t) => void : never> extends (\n x: infer branch,\n ) => void\n ? branch\n : never;\n\ntype intersectUnion<t> = (t extends unknown ? (_: t) => void : never) extends (\n _: infer intersection,\n) => void\n ? intersection\n : never;\n\ntype conform<t, base> = t extends base ? t : base;\n\n////////////////////////////////\n// END: Vendored from Arktype //\n////////////////////////////////\n\nexport type IndexFieldTypesForEq<\n ConvexDataModel extends GenericDataModel,\n Table extends TableNamesInDataModel<ConvexDataModel>,\n T extends string[],\n> = T extends readonly [...infer Rest, any]\n ? Rest extends readonly string[]\n ? {\n [K in keyof Rest]: FieldTypeFromFieldPath<\n DocumentByName<ConvexDataModel, Table>,\n Rest[K]\n >;\n }\n : never\n : never;\n\n// Would prefer to use `BaseDatabaseReader` from the `convex` package, but it's not exported.\nexport type BaseDatabaseReader<DataModel extends GenericDataModel> = {\n get: GenericDatabaseReader<DataModel>[\"get\"];\n query: GenericDatabaseReader<DataModel>[\"query\"];\n};\n"],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@confect/core",
|
|
3
3
|
"description": "Shared specs and schemas used by all Confect packages",
|
|
4
|
-
"version": "10.
|
|
4
|
+
"version": "10.3.1",
|
|
5
5
|
"author": "RJ Dellecese",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/rjdellecese/confect/issues"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
|
-
"@effect/vitest": "4.0.
|
|
11
|
-
"@types/node": "26.6.
|
|
10
|
+
"@effect/vitest": "4.0.4",
|
|
11
|
+
"@types/node": "26.6.5",
|
|
12
12
|
"confect-bench-harness": "0.0.0",
|
|
13
|
-
"effect": "4.0.
|
|
14
|
-
"tsdown": "0.23.
|
|
13
|
+
"effect": "4.0.4",
|
|
14
|
+
"tsdown": "0.23.1",
|
|
15
15
|
"tsx": "4.23.15",
|
|
16
16
|
"typescript": "7.0.2",
|
|
17
17
|
"unrun": "0.3.1",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"type": "module",
|
|
62
62
|
"types": "./dist/index.d.ts",
|
|
63
63
|
"scripts": {
|
|
64
|
-
"bench": "tsx test/Refs.bench.ts",
|
|
64
|
+
"bench": "tsx test/Refs.bench.ts && tsx test/Types.bench.ts",
|
|
65
65
|
"clean": "shx rm -rf dist coverage node_modules",
|
|
66
66
|
"dev": "tsdown --watch --no-clean --config-loader unrun",
|
|
67
67
|
"test": "vitest run",
|
package/src/GroupSpec.ts
CHANGED
|
@@ -55,21 +55,6 @@ export interface GroupSpec<
|
|
|
55
55
|
MiddlewareSpecs_
|
|
56
56
|
>;
|
|
57
57
|
|
|
58
|
-
addGroup<Group extends AnyWithProps>(
|
|
59
|
-
group: Group,
|
|
60
|
-
): GroupSpec<Runtime, Name_, Functions_, Groups_ | Group, MiddlewareSpecs_>;
|
|
61
|
-
|
|
62
|
-
addGroupAt<const AtName extends string, Group extends AnyWithProps>(
|
|
63
|
-
name: AtName,
|
|
64
|
-
group: Group,
|
|
65
|
-
): GroupSpec<
|
|
66
|
-
Runtime,
|
|
67
|
-
Name_,
|
|
68
|
-
Functions_,
|
|
69
|
-
Groups_ | NamedAt<Group, AtName>,
|
|
70
|
-
MiddlewareSpecs_
|
|
71
|
-
>;
|
|
72
|
-
|
|
73
58
|
middleware<MiddlewareSpec_ extends MiddlewareSpec.AnyMiddlewareSpec>(
|
|
74
59
|
middlewareSpec: MiddlewareSpec_ &
|
|
75
60
|
MiddlewareSpec.ValidateAttach<
|
|
@@ -99,16 +84,6 @@ export interface AnyWithProps extends GroupSpec<
|
|
|
99
84
|
MiddlewareSpec.AnyMiddlewareSpec
|
|
100
85
|
> {}
|
|
101
86
|
|
|
102
|
-
export interface AnyWithPropsWithRuntime<
|
|
103
|
-
Runtime extends RuntimeAndFunctionType.Runtime,
|
|
104
|
-
> extends GroupSpec<
|
|
105
|
-
Runtime,
|
|
106
|
-
string,
|
|
107
|
-
FunctionSpec.AnyWithPropsWithRuntime<Runtime>,
|
|
108
|
-
AnyWithPropsWithRuntime<Runtime>,
|
|
109
|
-
MiddlewareSpec.AnyMiddlewareSpec
|
|
110
|
-
> {}
|
|
111
|
-
|
|
112
87
|
export type Name<Group extends AnyWithProps> = Group["name"];
|
|
113
88
|
|
|
114
89
|
export type Functions<Group extends AnyWithProps> = Group["~Functions"];
|
|
@@ -146,16 +121,16 @@ export type AddGroups<
|
|
|
146
121
|
> =
|
|
147
122
|
Group extends GroupSpec<
|
|
148
123
|
infer Runtime,
|
|
149
|
-
|
|
124
|
+
string,
|
|
150
125
|
infer Functions_,
|
|
151
126
|
infer Groups_,
|
|
152
127
|
infer MiddlewareSpecs_
|
|
153
128
|
>
|
|
154
129
|
? GroupSpec<
|
|
155
130
|
Runtime,
|
|
156
|
-
|
|
131
|
+
Group["name"],
|
|
157
132
|
Functions_,
|
|
158
|
-
Groups_ | ExtraGroups,
|
|
133
|
+
Exclude<Groups_, { readonly name: Name<ExtraGroups> }> | ExtraGroups,
|
|
159
134
|
MiddlewareSpecs_
|
|
160
135
|
>
|
|
161
136
|
: never;
|
|
@@ -196,32 +171,6 @@ const Proto = {
|
|
|
196
171
|
});
|
|
197
172
|
},
|
|
198
173
|
|
|
199
|
-
addGroup<Group extends Any>(this: Any, group: Group) {
|
|
200
|
-
const this_ = this as AnyWithProps;
|
|
201
|
-
const group_ = group as unknown as AnyWithProps;
|
|
202
|
-
|
|
203
|
-
return makeProto({
|
|
204
|
-
runtime: this_.runtime,
|
|
205
|
-
name: this_.name,
|
|
206
|
-
functions: this_.functions,
|
|
207
|
-
groups: Record.set(this_.groups, group_.name, group_),
|
|
208
|
-
middlewareAttachments: this_.middlewareAttachments,
|
|
209
|
-
});
|
|
210
|
-
},
|
|
211
|
-
|
|
212
|
-
addGroupAt<Group extends Any>(this: Any, name: string, group: Group) {
|
|
213
|
-
const this_ = this as AnyWithProps;
|
|
214
|
-
const group_ = group as unknown as AnyWithProps;
|
|
215
|
-
|
|
216
|
-
return makeProto({
|
|
217
|
-
runtime: this_.runtime,
|
|
218
|
-
name: this_.name,
|
|
219
|
-
functions: this_.functions,
|
|
220
|
-
groups: Record.set(this_.groups, name, withName(name, group_)),
|
|
221
|
-
middlewareAttachments: this_.middlewareAttachments,
|
|
222
|
-
});
|
|
223
|
-
},
|
|
224
|
-
|
|
225
174
|
middleware<MiddlewareSpec_ extends MiddlewareSpec.AnyMiddlewareSpec>(
|
|
226
175
|
this: Any,
|
|
227
176
|
middlewareSpec: MiddlewareSpec_,
|
|
@@ -270,7 +219,7 @@ const makeProto = <
|
|
|
270
219
|
Runtime extends RuntimeAndFunctionType.Runtime,
|
|
271
220
|
Name_ extends string,
|
|
272
221
|
Functions_ extends FunctionSpec.AnyWithPropsWithRuntime<Runtime>,
|
|
273
|
-
Groups_ extends
|
|
222
|
+
Groups_ extends AnyWithProps,
|
|
274
223
|
MiddlewareAttachments_ extends
|
|
275
224
|
ReadonlyArray<MiddlewareAttachment.MiddlewareAttachment>,
|
|
276
225
|
>({
|
|
@@ -315,20 +264,6 @@ export const make = (): GroupSpec<"Convex", ""> =>
|
|
|
315
264
|
middlewareAttachments: [],
|
|
316
265
|
});
|
|
317
266
|
|
|
318
|
-
export const makeAt = <const Name_ extends string>(
|
|
319
|
-
name: Name_,
|
|
320
|
-
): GroupSpec<"Convex", Name_> => {
|
|
321
|
-
validateConfectFunctionIdentifier(name);
|
|
322
|
-
|
|
323
|
-
return makeProto({
|
|
324
|
-
runtime: "Convex",
|
|
325
|
-
name,
|
|
326
|
-
functions: Record.empty(),
|
|
327
|
-
groups: Record.empty(),
|
|
328
|
-
middlewareAttachments: [],
|
|
329
|
-
});
|
|
330
|
-
};
|
|
331
|
-
|
|
332
267
|
export const makeNode = (): GroupSpec<"Node", ""> =>
|
|
333
268
|
makeProto({
|
|
334
269
|
runtime: "Node",
|
|
@@ -338,20 +273,6 @@ export const makeNode = (): GroupSpec<"Node", ""> =>
|
|
|
338
273
|
middlewareAttachments: [],
|
|
339
274
|
});
|
|
340
275
|
|
|
341
|
-
export const makeNodeAt = <const Name_ extends string>(
|
|
342
|
-
name: Name_,
|
|
343
|
-
): GroupSpec<"Node", Name_> => {
|
|
344
|
-
validateConfectFunctionIdentifier(name);
|
|
345
|
-
|
|
346
|
-
return makeProto({
|
|
347
|
-
runtime: "Node",
|
|
348
|
-
name,
|
|
349
|
-
functions: Record.empty(),
|
|
350
|
-
groups: Record.empty(),
|
|
351
|
-
middlewareAttachments: [],
|
|
352
|
-
});
|
|
353
|
-
};
|
|
354
|
-
|
|
355
276
|
export function withName<const Name_ extends string, Group extends Any>(
|
|
356
277
|
name: Name_,
|
|
357
278
|
group: Group,
|
|
@@ -373,6 +294,22 @@ export function withName(name: string, group: Any): AnyWithProps {
|
|
|
373
294
|
});
|
|
374
295
|
}
|
|
375
296
|
|
|
297
|
+
export const addGroupsAt = (
|
|
298
|
+
group: AnyWithProps,
|
|
299
|
+
children: Record.ReadonlyRecord<string, AnyWithProps>,
|
|
300
|
+
): AnyWithProps =>
|
|
301
|
+
makeProto({
|
|
302
|
+
runtime: group.runtime,
|
|
303
|
+
name: group.name,
|
|
304
|
+
functions: group.functions,
|
|
305
|
+
groups: Record.union(
|
|
306
|
+
group.groups,
|
|
307
|
+
Record.map(children, (child, name) => withName(name, child)),
|
|
308
|
+
(_existing, incoming) => incoming,
|
|
309
|
+
),
|
|
310
|
+
middlewareAttachments: group.middlewareAttachments,
|
|
311
|
+
});
|
|
312
|
+
|
|
376
313
|
export const validateMiddleware = (
|
|
377
314
|
group: AnyWithProps,
|
|
378
315
|
): Result.Result<void, MiddlewareAttachment.ValidationError> =>
|
package/src/SchemaToValidator.ts
CHANGED
|
@@ -11,7 +11,6 @@ import type {
|
|
|
11
11
|
VLiteral,
|
|
12
12
|
VNull,
|
|
13
13
|
VObject,
|
|
14
|
-
VOptional,
|
|
15
14
|
VRecord,
|
|
16
15
|
VString,
|
|
17
16
|
VUnion,
|
|
@@ -130,123 +129,135 @@ export type ValueToValidator<Vl> = [Vl] extends [never]
|
|
|
130
129
|
? never
|
|
131
130
|
: IsAny<Vl> extends true
|
|
132
131
|
? VAny
|
|
132
|
+
: [Vl] extends [string | number | bigint | boolean | null | ArrayBuffer]
|
|
133
|
+
? ConvertValueToValidator<Vl>
|
|
134
|
+
: IsRecursive<Vl> extends true
|
|
135
|
+
? VAny
|
|
136
|
+
: [Vl] extends [ReadonlyValue]
|
|
137
|
+
? ConvertValueToValidator<Vl>
|
|
138
|
+
: TypeError<"Provided value is not a valid Convex value", Vl>;
|
|
139
|
+
|
|
140
|
+
type OptionalValue<Vl, Optionality> = Optionality extends "optional"
|
|
141
|
+
? Vl | undefined
|
|
142
|
+
: Vl;
|
|
143
|
+
|
|
144
|
+
type ConvertValueToValidator<
|
|
145
|
+
Vl,
|
|
146
|
+
Optionality extends "required" | "optional" = "required",
|
|
147
|
+
> = [Vl] extends [never]
|
|
148
|
+
? never
|
|
149
|
+
: IsAny<Vl> extends true
|
|
150
|
+
? VAny<any, Optionality>
|
|
133
151
|
: [Vl] extends [null]
|
|
134
|
-
? VNull
|
|
152
|
+
? VNull<OptionalValue<null, Optionality>, Optionality>
|
|
135
153
|
: [Vl] extends [boolean]
|
|
136
154
|
? [boolean] extends [Vl]
|
|
137
|
-
? VBoolean
|
|
138
|
-
: VLiteral<Vl>
|
|
155
|
+
? VBoolean<OptionalValue<boolean, Optionality>, Optionality>
|
|
156
|
+
: VLiteral<OptionalValue<Vl, Optionality>, Optionality>
|
|
139
157
|
: IsUnion<Vl> extends true
|
|
140
|
-
?
|
|
141
|
-
? VAny
|
|
142
|
-
: [Vl] extends [ReadonlyValue]
|
|
143
|
-
? UnionValueToValidator<Vl>
|
|
144
|
-
: TypeError<"Provided value is not a valid Convex value", Vl>
|
|
158
|
+
? UnionValueToValidator<Vl, Optionality>
|
|
145
159
|
: [Vl] extends [number]
|
|
146
160
|
? [number] extends [Vl]
|
|
147
|
-
? VFloat64
|
|
148
|
-
: VLiteral<Vl>
|
|
161
|
+
? VFloat64<OptionalValue<number, Optionality>, Optionality>
|
|
162
|
+
: VLiteral<OptionalValue<Vl, Optionality>, Optionality>
|
|
149
163
|
: [Vl] extends [bigint]
|
|
150
164
|
? [bigint] extends [Vl]
|
|
151
|
-
? VInt64
|
|
152
|
-
: VLiteral<Vl>
|
|
165
|
+
? VInt64<OptionalValue<bigint, Optionality>, Optionality>
|
|
166
|
+
: VLiteral<OptionalValue<Vl, Optionality>, Optionality>
|
|
153
167
|
: [Vl] extends [string]
|
|
154
|
-
? Vl
|
|
155
|
-
__tableName: infer TableName extends string;
|
|
156
|
-
}
|
|
157
|
-
? VId<GenericId.GenericId<TableName>>
|
|
158
|
-
: [string] extends [Vl]
|
|
159
|
-
? VString
|
|
160
|
-
: VLiteral<Vl>
|
|
168
|
+
? StringValueToValidator<Vl, Optionality>
|
|
161
169
|
: [Vl] extends [ArrayBuffer]
|
|
162
|
-
? VBytes
|
|
170
|
+
? VBytes<OptionalValue<ArrayBuffer, Optionality>, Optionality>
|
|
163
171
|
: IsRecursive<Vl> extends true
|
|
164
|
-
? VAny
|
|
165
|
-
:
|
|
166
|
-
?
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
:
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
172
|
+
? VAny<any, Optionality>
|
|
173
|
+
: Vl extends ReadonlyArray<infer El>
|
|
174
|
+
? VArray<
|
|
175
|
+
OptionalValue<MutableValue<El[]>, Optionality>,
|
|
176
|
+
ConvertValueToValidator<El>,
|
|
177
|
+
Optionality
|
|
178
|
+
>
|
|
179
|
+
: Vl extends object
|
|
180
|
+
? ObjectValueToValidator<Vl, Optionality>
|
|
181
|
+
: never;
|
|
182
|
+
|
|
183
|
+
type StringValueToValidator<
|
|
184
|
+
Vl,
|
|
185
|
+
Optionality extends "required" | "optional",
|
|
186
|
+
> = Vl extends { __tableName: infer TableName extends string }
|
|
187
|
+
? VId<OptionalValue<GenericId.GenericId<TableName>, Optionality>, Optionality>
|
|
188
|
+
: [string] extends [Vl]
|
|
189
|
+
? VString<OptionalValue<string, Optionality>, Optionality>
|
|
190
|
+
: VLiteral<OptionalValue<Vl, Optionality>, Optionality>;
|
|
191
|
+
|
|
192
|
+
type ObjectValueToValidator<Vl, Optionality extends "required" | "optional"> =
|
|
193
|
+
IsRecord<MutableValue<Vl>> extends true
|
|
194
|
+
? ValueToValidator<Vl[keyof Vl]> extends infer VdValue extends Validator<
|
|
195
|
+
any,
|
|
196
|
+
"required",
|
|
197
|
+
any
|
|
198
|
+
>
|
|
199
|
+
? VRecord<
|
|
200
|
+
OptionalValue<MutableValue<Vl>, Optionality>,
|
|
201
|
+
VString,
|
|
202
|
+
VdValue,
|
|
203
|
+
Optionality
|
|
204
|
+
>
|
|
180
205
|
: never
|
|
181
|
-
:
|
|
206
|
+
: ObjectFieldsToValidators<Vl> extends infer VdFields extends Record<
|
|
207
|
+
string,
|
|
208
|
+
any
|
|
209
|
+
>
|
|
210
|
+
? VObject<
|
|
211
|
+
OptionalValue<MutableValue<Vl>, Optionality>,
|
|
212
|
+
VdFields,
|
|
213
|
+
Optionality
|
|
214
|
+
>
|
|
215
|
+
: never;
|
|
182
216
|
|
|
183
|
-
type
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
: VObject<VlRecord, VdRecord>
|
|
195
|
-
: never
|
|
196
|
-
: never
|
|
197
|
-
: never;
|
|
217
|
+
type ObjectFieldsToValidators<Vl> = {
|
|
218
|
+
-readonly [K in keyof Vl]-?: IsAny<Vl[K]> extends true
|
|
219
|
+
? IsOptional<Vl, K> extends true
|
|
220
|
+
? VAny<any, "optional">
|
|
221
|
+
: VAny
|
|
222
|
+
: undefined extends Vl[K]
|
|
223
|
+
? OptionalValueToValidator<Vl[K]>
|
|
224
|
+
: [Vl[K]] extends [ReadonlyValue]
|
|
225
|
+
? ConvertValueToValidator<Vl[K]>
|
|
226
|
+
: never;
|
|
227
|
+
};
|
|
198
228
|
|
|
199
229
|
export type UndefinedOrValueToValidator<Vl extends ReadonlyValue | undefined> =
|
|
200
230
|
undefined extends Vl
|
|
201
|
-
?
|
|
202
|
-
? ValueToValidator<Val> extends infer Vd extends Validator<
|
|
203
|
-
any,
|
|
204
|
-
"required",
|
|
205
|
-
any
|
|
206
|
-
>
|
|
207
|
-
? VOptional<Vd>
|
|
208
|
-
: never
|
|
209
|
-
: never
|
|
231
|
+
? OptionalValueToValidator<Vl>
|
|
210
232
|
: [Vl] extends [ReadonlyValue]
|
|
211
233
|
? ValueToValidator<Vl>
|
|
212
234
|
: never;
|
|
213
235
|
|
|
214
|
-
type UnionValueToValidator<Vl extends
|
|
215
|
-
|
|
236
|
+
type UnionValueToValidator<Vl, Optionality extends "required" | "optional"> =
|
|
237
|
+
IsRecursive<Vl> extends true
|
|
238
|
+
? VAny<any, Optionality>
|
|
239
|
+
: VUnion<
|
|
240
|
+
OptionalValue<MutableValue<Vl>, Optionality>,
|
|
241
|
+
ValueTupleToValidatorTuple<UnionToTuple<Vl>>,
|
|
242
|
+
Optionality
|
|
243
|
+
>;
|
|
244
|
+
|
|
245
|
+
type ValueTupleToValidatorTuple<
|
|
246
|
+
VlTuple extends readonly unknown[],
|
|
247
|
+
Acc extends Validator<any, "required", any>[] = [],
|
|
248
|
+
> = VlTuple extends
|
|
249
|
+
| [true, false, ...infer VlRest]
|
|
250
|
+
| [false, true, ...infer VlRest]
|
|
251
|
+
? ValueTupleToValidatorTuple<VlRest, [...Acc, VBoolean]>
|
|
252
|
+
: VlTuple extends [infer Vl, ...infer VlRest]
|
|
253
|
+
? ValueTupleToValidatorTuple<VlRest, [...Acc, ConvertValueToValidator<Vl>]>
|
|
254
|
+
: Acc;
|
|
255
|
+
|
|
256
|
+
type OptionalValueToValidator<Vl> = [Vl] extends [
|
|
257
|
+
(infer Val extends ReadonlyValue) | undefined,
|
|
216
258
|
]
|
|
217
|
-
?
|
|
218
|
-
|
|
219
|
-
ReadonlyArray<ReadonlyValue>
|
|
220
|
-
? ValueTupleToValidatorTuple<VlTuple> extends infer VdTuple extends
|
|
221
|
-
Validator<any, "required", any>[]
|
|
222
|
-
? VUnion<MutableValue<Vl>, VdTuple>
|
|
223
|
-
: TypeError<"Failed to convert value tuple to validator tuple">
|
|
224
|
-
: TypeError<"Failed to convert union to tuple">
|
|
225
|
-
: TypeError<"Expected a union of values, but got a single value instead">
|
|
226
|
-
: TypeError<"Provided value is not a valid Convex value">;
|
|
227
|
-
|
|
228
|
-
type ValueTupleToValidatorTuple<VlTuple extends ReadonlyArray<ReadonlyValue>> =
|
|
229
|
-
VlTuple extends
|
|
230
|
-
| [true, false, ...infer VlRest extends ReadonlyArray<ReadonlyValue>]
|
|
231
|
-
| [false, true, ...infer VlRest extends ReadonlyArray<ReadonlyValue>]
|
|
232
|
-
? ValueTupleToValidatorTuple<VlRest> extends infer VdRest extends Validator<
|
|
233
|
-
any,
|
|
234
|
-
any,
|
|
235
|
-
any
|
|
236
|
-
>[]
|
|
237
|
-
? [VBoolean<boolean>, ...VdRest]
|
|
238
|
-
: never
|
|
239
|
-
: VlTuple extends [
|
|
240
|
-
infer Vl extends ReadonlyValue,
|
|
241
|
-
...infer VlRest extends ReadonlyArray<ReadonlyValue>,
|
|
242
|
-
]
|
|
243
|
-
? ValueToValidator<Vl> extends infer Vd extends Validator<any, any, any>
|
|
244
|
-
? ValueTupleToValidatorTuple<VlRest> extends infer VdRest extends
|
|
245
|
-
Validator<any, "required", any>[]
|
|
246
|
-
? [Vd, ...VdRest]
|
|
247
|
-
: never
|
|
248
|
-
: never
|
|
249
|
-
: [];
|
|
259
|
+
? ConvertValueToValidator<Val, "optional">
|
|
260
|
+
: never;
|
|
250
261
|
|
|
251
262
|
export const compileSchema = <T, E>(
|
|
252
263
|
schema: Schema.Codec<T, E>,
|
package/src/Spec.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as Predicate from "effect/Predicate";
|
|
2
2
|
import * as Record from "effect/Record";
|
|
3
|
-
import * as Struct from "effect/Struct";
|
|
4
3
|
import * as GroupSpec from "./GroupSpec";
|
|
5
4
|
|
|
6
5
|
export const TypeId = "~@confect/core/Spec";
|
|
@@ -20,22 +19,6 @@ export interface Spec<
|
|
|
20
19
|
Groups_ extends Record.ReadonlyRecord<string, GroupSpec.AnyWithProps> = {},
|
|
21
20
|
> {
|
|
22
21
|
readonly [TypeId]: Readonly<Groups_>;
|
|
23
|
-
|
|
24
|
-
add<Group extends GroupSpec.AnyWithProps>(
|
|
25
|
-
group: Group,
|
|
26
|
-
): Spec<
|
|
27
|
-
Struct.Assign<Groups_, Record.ReadonlyRecord<GroupSpec.Name<Group>, Group>>
|
|
28
|
-
>;
|
|
29
|
-
|
|
30
|
-
addAt<const Name extends string, Group extends GroupSpec.AnyWithProps>(
|
|
31
|
-
name: Name,
|
|
32
|
-
group: Group,
|
|
33
|
-
): Spec<
|
|
34
|
-
Struct.Assign<
|
|
35
|
-
Groups_,
|
|
36
|
-
Record.ReadonlyRecord<Name, GroupSpec.NamedAt<Group, Name>>
|
|
37
|
-
>
|
|
38
|
-
>;
|
|
39
22
|
}
|
|
40
23
|
|
|
41
24
|
export interface Any {
|
|
@@ -56,31 +39,10 @@ export const groups = <Spec_ extends AnyWithProps>(
|
|
|
56
39
|
self: Spec_,
|
|
57
40
|
): Spec_[TypeId] => self[TypeId];
|
|
58
41
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
add<Group extends GroupSpec.AnyWithProps>(group: Group) {
|
|
66
|
-
return makeRecord(
|
|
67
|
-
Struct.assign(
|
|
68
|
-
record,
|
|
69
|
-
Record.singleton<GroupSpec.Name<Group>, Group>(group.name, group),
|
|
70
|
-
),
|
|
71
|
-
);
|
|
72
|
-
},
|
|
73
|
-
addAt<const Name extends string, Group extends GroupSpec.AnyWithProps>(
|
|
74
|
-
name: Name,
|
|
75
|
-
group: Group,
|
|
76
|
-
) {
|
|
77
|
-
return makeRecord(
|
|
78
|
-
Struct.assign(
|
|
79
|
-
record,
|
|
80
|
-
Record.singleton(name, GroupSpec.withName(name, group)),
|
|
81
|
-
),
|
|
82
|
-
);
|
|
83
|
-
},
|
|
42
|
+
export const fromGroups = (
|
|
43
|
+
record: Record.ReadonlyRecord<string, GroupSpec.AnyWithProps>,
|
|
44
|
+
): AnyWithProps => ({
|
|
45
|
+
[TypeId]: Record.map(record, (group, name) =>
|
|
46
|
+
GroupSpec.withName(name, group),
|
|
47
|
+
),
|
|
84
48
|
});
|
|
85
|
-
|
|
86
|
-
export const make = (): Spec => makeRecord({});
|
package/src/Types.ts
CHANGED
|
@@ -86,27 +86,54 @@ export type IsRecursive<T> = true extends DetectCycle<T> ? true : false;
|
|
|
86
86
|
|
|
87
87
|
type NonRecursiveLeaf = Brand.Brand<any> | GenericId<any> | ArrayBuffer;
|
|
88
88
|
|
|
89
|
-
type
|
|
89
|
+
type IsSame<A, B> =
|
|
90
|
+
(<G>() => G extends A ? 1 : 2) extends <G>() => G extends B ? 1 : 2
|
|
91
|
+
? true
|
|
92
|
+
: false;
|
|
93
|
+
|
|
94
|
+
type IsObject<T> = T extends object ? true : false;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Whether `T` is one of the types already on the path, compared by identity.
|
|
98
|
+
* Assignability is not enough: a nested struct is assignable to an ancestor
|
|
99
|
+
* whenever the ancestor's extra fields are optional, and two structs whose
|
|
100
|
+
* fields are all optional can be assignable to each other in both directions.
|
|
101
|
+
* `DetectCycle` asks only once `T` is assignable to some type on the path,
|
|
102
|
+
* which keeps the identity comparisons off the common, non-recursive case.
|
|
103
|
+
*/
|
|
104
|
+
type IsAncestor<T, Ancestors> = Ancestors extends unknown
|
|
105
|
+
? IsSame<T, Ancestors>
|
|
106
|
+
: never;
|
|
107
|
+
|
|
108
|
+
type DetectCycle<T, Ancestors = never> =
|
|
90
109
|
IsAny<T> extends true
|
|
91
110
|
? false
|
|
92
111
|
: [T] extends [any]
|
|
93
112
|
? T extends NonRecursiveLeaf
|
|
94
113
|
? false
|
|
95
|
-
: T extends
|
|
96
|
-
?
|
|
97
|
-
:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
? DetectCycle<V, [...Cache, T]>
|
|
101
|
-
: T extends Set<infer U>
|
|
102
|
-
? DetectCycle<U, [...Cache, T]>
|
|
103
|
-
: T extends object
|
|
104
|
-
? true extends {
|
|
105
|
-
[K in keyof T]: DetectCycle<T[K], [...Cache, T]>;
|
|
106
|
-
}[keyof T]
|
|
114
|
+
: IsObject<T> extends false
|
|
115
|
+
? false
|
|
116
|
+
: (
|
|
117
|
+
T extends Ancestors
|
|
118
|
+
? true extends IsAncestor<T, Ancestors>
|
|
107
119
|
? true
|
|
108
120
|
: false
|
|
109
121
|
: false
|
|
122
|
+
) extends true
|
|
123
|
+
? true
|
|
124
|
+
: T extends Array<infer U>
|
|
125
|
+
? DetectCycle<U, Ancestors | T>
|
|
126
|
+
: T extends Map<infer _U, infer V>
|
|
127
|
+
? DetectCycle<V, Ancestors | T>
|
|
128
|
+
: T extends Set<infer U>
|
|
129
|
+
? DetectCycle<U, Ancestors | T>
|
|
130
|
+
: T extends object
|
|
131
|
+
? true extends {
|
|
132
|
+
[K in keyof T]: DetectCycle<T[K], Ancestors | T>;
|
|
133
|
+
}[keyof T]
|
|
134
|
+
? true
|
|
135
|
+
: false
|
|
136
|
+
: false
|
|
110
137
|
: never;
|
|
111
138
|
|
|
112
139
|
//////////////////////////////////
|