@confect/core 10.0.0-next.9 → 10.1.0
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 +964 -47
- package/README.md +3 -1
- package/dist/FunctionProvenance.d.ts +166 -68
- package/dist/FunctionProvenance.d.ts.map +1 -1
- package/dist/FunctionProvenance.js +55 -13
- package/dist/FunctionProvenance.js.map +1 -1
- package/dist/FunctionSpec.d.ts +320 -138
- package/dist/FunctionSpec.d.ts.map +1 -1
- package/dist/FunctionSpec.js +56 -13
- package/dist/FunctionSpec.js.map +1 -1
- package/dist/GenericId.d.ts.map +1 -1
- package/dist/GenericId.js +1 -1
- package/dist/GroupPath.d.ts +6 -10
- package/dist/GroupPath.d.ts.map +1 -1
- package/dist/GroupPath.js.map +1 -1
- package/dist/GroupSpec.d.ts +25 -12
- package/dist/GroupSpec.d.ts.map +1 -1
- package/dist/GroupSpec.js +51 -14
- package/dist/GroupSpec.js.map +1 -1
- package/dist/Identifier.d.ts +6 -5
- package/dist/Identifier.d.ts.map +1 -1
- package/dist/Identifier.js +6 -5
- package/dist/Identifier.js.map +1 -1
- package/dist/Lazy.d.ts +11 -14
- package/dist/Lazy.d.ts.map +1 -1
- package/dist/Lazy.js +11 -14
- package/dist/Lazy.js.map +1 -1
- package/dist/MiddlewareAttachment.d.ts +171 -0
- package/dist/MiddlewareAttachment.d.ts.map +1 -0
- package/dist/MiddlewareAttachment.js +48 -0
- package/dist/MiddlewareAttachment.js.map +1 -0
- package/dist/MiddlewareSpec.d.ts +198 -0
- package/dist/MiddlewareSpec.d.ts.map +1 -0
- package/dist/MiddlewareSpec.js +60 -0
- package/dist/MiddlewareSpec.js.map +1 -0
- package/dist/PaginationError.d.ts +20 -0
- package/dist/PaginationError.d.ts.map +1 -0
- package/dist/PaginationError.js +31 -0
- package/dist/PaginationError.js.map +1 -0
- package/dist/PaginationOptions.d.ts +23 -0
- package/dist/PaginationOptions.d.ts.map +1 -0
- package/dist/PaginationOptions.js +29 -0
- package/dist/PaginationOptions.js.map +1 -0
- package/dist/PaginationResult.d.ts +1 -0
- package/dist/PaginationResult.d.ts.map +1 -1
- package/dist/PaginationResult.js.map +1 -1
- package/dist/Ref.d.ts +135 -47
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js +104 -46
- package/dist/Ref.js.map +1 -1
- package/dist/Refs.d.ts +10 -5
- package/dist/Refs.d.ts.map +1 -1
- package/dist/Refs.js +5 -4
- package/dist/Refs.js.map +1 -1
- package/dist/SchemaToValidator.d.ts +99 -0
- package/dist/SchemaToValidator.d.ts.map +1 -0
- package/dist/SchemaToValidator.js +158 -0
- package/dist/SchemaToValidator.js.map +1 -0
- package/dist/Spec.d.ts +16 -12
- package/dist/Spec.d.ts.map +1 -1
- package/dist/Spec.js +14 -9
- package/dist/Spec.js.map +1 -1
- package/dist/SystemFields.d.ts +20 -19
- package/dist/SystemFields.d.ts.map +1 -1
- package/dist/SystemFields.js +22 -21
- package/dist/SystemFields.js.map +1 -1
- package/dist/Table.d.ts +75 -0
- package/dist/Table.d.ts.map +1 -0
- package/dist/Table.js +77 -0
- package/dist/Table.js.map +1 -0
- package/dist/Types.d.ts +8 -2
- package/dist/Types.d.ts.map +1 -1
- package/dist/Types.js.map +1 -1
- package/dist/UserIdentity.d.ts.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -4
- package/package.json +17 -15
- package/src/FunctionProvenance.ts +197 -34
- package/src/FunctionSpec.ts +332 -86
- package/src/GroupPath.ts +6 -12
- package/src/GroupSpec.ts +184 -25
- package/src/Identifier.ts +6 -5
- package/src/Lazy.ts +11 -14
- package/src/MiddlewareAttachment.ts +106 -0
- package/src/MiddlewareSpec.ts +392 -0
- package/src/PaginationError.ts +78 -0
- package/src/PaginationOptions.ts +23 -0
- package/src/PaginationResult.ts +4 -0
- package/src/Ref.ts +468 -236
- package/src/Refs.ts +43 -18
- package/src/SchemaToValidator.ts +612 -0
- package/src/Spec.ts +50 -39
- package/src/SystemFields.ts +40 -42
- package/src/Table.ts +427 -0
- package/src/Types.ts +9 -3
- package/src/index.ts +6 -1
- package/dist/Registry.d.ts +0 -24
- package/dist/Registry.d.ts.map +0 -1
- package/dist/Registry.js +0 -19
- package/dist/Registry.js.map +0 -1
- package/dist/tsconfig.src.tsbuildinfo +0 -1
- package/src/Registry.ts +0 -30
package/src/Spec.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as Predicate from "effect/Predicate";
|
|
2
2
|
import * as Record from "effect/Record";
|
|
3
|
+
import * as Struct from "effect/Struct";
|
|
3
4
|
import * as GroupSpec from "./GroupSpec";
|
|
4
5
|
|
|
5
|
-
export const TypeId = "
|
|
6
|
+
export const TypeId = "~@confect/core/Spec";
|
|
6
7
|
export type TypeId = typeof TypeId;
|
|
7
8
|
|
|
8
9
|
export const isSpec = (u: unknown): u is AnyWithProps =>
|
|
@@ -10,66 +11,76 @@ export const isSpec = (u: unknown): u is AnyWithProps =>
|
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* A Confect spec: a flat container of function groups. Groups may be of any
|
|
13
|
-
* runtime
|
|
14
|
+
* runtime—a group built with `GroupSpec.makeNode()` (a Node action group) sits
|
|
14
15
|
* alongside `GroupSpec.make()` groups in the same namespace. The runtime of a
|
|
15
16
|
* group lives on the group itself (`GroupSpec.runtime`) and on each function's
|
|
16
17
|
* `RuntimeAndFunctionType`; the spec does not carry a runtime of its own.
|
|
17
18
|
*/
|
|
18
|
-
export interface Spec<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Groups_,
|
|
23
|
-
GroupName
|
|
24
|
-
>;
|
|
25
|
-
};
|
|
19
|
+
export interface Spec<
|
|
20
|
+
Groups_ extends Record.ReadonlyRecord<string, GroupSpec.AnyWithProps> = {},
|
|
21
|
+
> {
|
|
22
|
+
readonly [TypeId]: Readonly<Groups_>;
|
|
26
23
|
|
|
27
24
|
add<Group extends GroupSpec.AnyWithProps>(
|
|
28
25
|
group: Group,
|
|
29
|
-
): Spec<
|
|
26
|
+
): Spec<
|
|
27
|
+
Struct.Assign<Groups_, Record.ReadonlyRecord<GroupSpec.Name<Group>, Group>>
|
|
28
|
+
>;
|
|
30
29
|
|
|
31
30
|
addAt<const Name extends string, Group extends GroupSpec.AnyWithProps>(
|
|
32
31
|
name: Name,
|
|
33
32
|
group: Group,
|
|
34
|
-
): Spec<
|
|
33
|
+
): Spec<
|
|
34
|
+
Struct.Assign<
|
|
35
|
+
Groups_,
|
|
36
|
+
Record.ReadonlyRecord<Name, GroupSpec.NamedAt<Group, Name>>
|
|
37
|
+
>
|
|
38
|
+
>;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
export interface Any {
|
|
38
|
-
readonly [TypeId]:
|
|
42
|
+
readonly [TypeId]: unknown;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
export interface AnyWithProps extends
|
|
45
|
+
export interface AnyWithProps extends Any {
|
|
46
|
+
readonly [TypeId]: Record.ReadonlyRecord<string, GroupSpec.AnyWithProps>;
|
|
47
|
+
}
|
|
42
48
|
|
|
43
49
|
export type Groups<Spec_ extends AnyWithProps> =
|
|
44
|
-
Spec_[
|
|
50
|
+
Spec_[TypeId][keyof Spec_[TypeId]];
|
|
45
51
|
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
/**
|
|
53
|
+
* The group record stored by a spec, with its precise member types.
|
|
54
|
+
*/
|
|
55
|
+
export const groups = <Spec_ extends AnyWithProps>(
|
|
56
|
+
self: Spec_,
|
|
57
|
+
): Spec_[TypeId] => self[TypeId];
|
|
48
58
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
const makeRecord = <
|
|
60
|
+
Groups_ extends Record.ReadonlyRecord<string, GroupSpec.AnyWithProps>,
|
|
61
|
+
>(
|
|
62
|
+
record: Groups_,
|
|
63
|
+
): Spec<Groups_> => ({
|
|
64
|
+
[TypeId]: record,
|
|
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
|
+
);
|
|
53
72
|
},
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
this: AnyWithProps,
|
|
57
|
-
name: string,
|
|
73
|
+
addAt<const Name extends string, Group extends GroupSpec.AnyWithProps>(
|
|
74
|
+
name: Name,
|
|
58
75
|
group: Group,
|
|
59
76
|
) {
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
|
|
77
|
+
return makeRecord(
|
|
78
|
+
Struct.assign(
|
|
79
|
+
record,
|
|
80
|
+
Record.singleton(name, GroupSpec.withName(name, group)),
|
|
81
|
+
),
|
|
82
|
+
);
|
|
63
83
|
},
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const makeProto = <Groups_ extends GroupSpec.AnyWithProps>({
|
|
67
|
-
groups,
|
|
68
|
-
}: {
|
|
69
|
-
groups: Record.ReadonlyRecord<string, Groups_>;
|
|
70
|
-
}): Spec<Groups_> =>
|
|
71
|
-
Object.assign(Object.create(Proto), {
|
|
72
|
-
groups,
|
|
73
|
-
});
|
|
84
|
+
});
|
|
74
85
|
|
|
75
|
-
export const make = (): Spec =>
|
|
86
|
+
export const make = (): Spec => makeRecord({});
|
package/src/SystemFields.ts
CHANGED
|
@@ -13,12 +13,13 @@ import * as Struct from "effect/Struct";
|
|
|
13
13
|
import * as GenericId from "./GenericId";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Produces a schema for Convex system fields. In Confect, system fields include
|
|
16
|
+
* Produces a schema for Convex system fields. In Confect, system fields include
|
|
17
|
+
* `_id`.
|
|
17
18
|
*/
|
|
18
19
|
export const SystemFields = <TableName extends string>(tableName: TableName) =>
|
|
19
20
|
Schema.Struct({
|
|
20
21
|
_id: GenericId.GenericId(tableName),
|
|
21
|
-
_creationTime: Schema.
|
|
22
|
+
_creationTime: Schema.Finite,
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
/**
|
|
@@ -58,23 +59,21 @@ const splitSystemFields = (input: { [key: PropertyKey]: unknown }) => {
|
|
|
58
59
|
* output. Transformations construct fresh objects, so without this the system
|
|
59
60
|
* fields would be dropped at every transformation step.
|
|
60
61
|
*/
|
|
61
|
-
const wrapGetter = (
|
|
62
|
-
getter: SchemaGetter.Getter<any, any,
|
|
63
|
-
): SchemaGetter.Getter<any, any,
|
|
64
|
-
|
|
62
|
+
const wrapGetter = <R>(
|
|
63
|
+
getter: SchemaGetter.Getter<any, any, R>,
|
|
64
|
+
): SchemaGetter.Getter<any, any, R> =>
|
|
65
|
+
SchemaGetter.transformOptionalEffect((input, options) => {
|
|
65
66
|
if (Option.isNone(input) || !Predicate.isObject(input.value)) {
|
|
66
|
-
return
|
|
67
|
+
return SchemaGetter.run(getter, input, options);
|
|
67
68
|
}
|
|
68
69
|
const { system, rest } = splitSystemFields(input.value);
|
|
69
|
-
return getter
|
|
70
|
-
.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Option.map((output) =>
|
|
74
|
-
Predicate.isObject(output) ? Struct.assign(output, system) : output,
|
|
75
|
-
),
|
|
70
|
+
return SchemaGetter.run(getter, Option.some(rest), options).pipe(
|
|
71
|
+
Effect.map(
|
|
72
|
+
Option.map((output) =>
|
|
73
|
+
Predicate.isObject(output) ? Struct.assign(output, system) : output,
|
|
76
74
|
),
|
|
77
|
-
)
|
|
75
|
+
),
|
|
76
|
+
);
|
|
78
77
|
});
|
|
79
78
|
|
|
80
79
|
const wrapTransformation = (
|
|
@@ -93,8 +92,8 @@ const wrapTransformation = (
|
|
|
93
92
|
|
|
94
93
|
/**
|
|
95
94
|
* Builds an AST walker that adds the given system-field property signatures to
|
|
96
|
-
* every object node of a schema's AST
|
|
97
|
-
* chain
|
|
95
|
+
* every object node of a schema's AST—including each step of its encoding
|
|
96
|
+
* chain—wrapping transformations so the fields survive them.
|
|
98
97
|
*/
|
|
99
98
|
const makeExtendAst = (
|
|
100
99
|
systemPropertySignatures: ReadonlyArray<SchemaAST.PropertySignature>,
|
|
@@ -113,7 +112,7 @@ const makeExtendAst = (
|
|
|
113
112
|
if (SchemaAST.isUnion(ast)) {
|
|
114
113
|
return new SchemaAST.Union(
|
|
115
114
|
Array.map(ast.types, extendAst),
|
|
116
|
-
ast.
|
|
115
|
+
ast.options,
|
|
117
116
|
ast.annotations,
|
|
118
117
|
ast.checks,
|
|
119
118
|
ast.encoding === undefined ? undefined : extendEncoding(ast.encoding),
|
|
@@ -154,15 +153,15 @@ const makeExtendAst = (
|
|
|
154
153
|
/**
|
|
155
154
|
* Extend a table schema with Convex system fields.
|
|
156
155
|
*
|
|
157
|
-
* A plain `Struct` gains the fields via `
|
|
158
|
-
*
|
|
159
|
-
* `Struct`/`Union` structure. Any other object-shaped schema
|
|
160
|
-
* `Schema.decodeTo`/`Schema.encodeKeys`, a branded struct, a
|
|
161
|
-
* —
|
|
162
|
-
* gains the system fields, and each transformation is wrapped so
|
|
163
|
-
* bypass the user-defined getters. Schemas that do not resolve to an
|
|
164
|
-
* shape at every step (such as `Schema.Class`, whose decoded values are
|
|
165
|
-
* instances) are rejected with a descriptive error.
|
|
156
|
+
* A plain `Struct` gains the fields via `mapFields` and a `Union` has them
|
|
157
|
+
* distributed across its members via `mapMembers`, preserving the schema's
|
|
158
|
+
* checks and `Struct`/`Union` structure. Any other object-shaped schema—one
|
|
159
|
+
* built with `Schema.decodeTo`/`Schema.encodeKeys`, a branded struct, a
|
|
160
|
+
* suspended schema—is extended at the AST level: every object node in its
|
|
161
|
+
* encoding chain gains the system fields, and each transformation is wrapped so
|
|
162
|
+
* the fields bypass the user-defined getters. Schemas that do not resolve to an
|
|
163
|
+
* object shape at every step (such as `Schema.Class`, whose decoded values are
|
|
164
|
+
* class instances) are rejected with a descriptive error.
|
|
166
165
|
*
|
|
167
166
|
* Note that struct-level checks on an extended schema observe the value with
|
|
168
167
|
* the system fields attached, and encoding an extended schema emits the system
|
|
@@ -193,11 +192,9 @@ export const extendWithSystemFields = <
|
|
|
193
192
|
SchemaAST.isUnion(s.ast) &&
|
|
194
193
|
Array.isArray((s as { readonly members?: unknown }).members)
|
|
195
194
|
) {
|
|
196
|
-
return Schema.Union(
|
|
197
|
-
Array.map(
|
|
198
|
-
|
|
199
|
-
extend,
|
|
200
|
-
),
|
|
195
|
+
return (s as Schema.Union<ReadonlyArray<Schema.Top>>).mapMembers(
|
|
196
|
+
Array.map(extend),
|
|
197
|
+
{ unsafePreserveChecks: true },
|
|
201
198
|
);
|
|
202
199
|
}
|
|
203
200
|
if (
|
|
@@ -205,8 +202,9 @@ export const extendWithSystemFields = <
|
|
|
205
202
|
SchemaAST.isObjects(s.ast) &&
|
|
206
203
|
typeof (s as { readonly mapFields?: unknown }).mapFields === "function"
|
|
207
204
|
) {
|
|
208
|
-
return Schema.
|
|
209
|
-
|
|
205
|
+
return (s as Schema.Struct<Schema.Struct.Fields>).mapFields(
|
|
206
|
+
Struct.assign(system),
|
|
207
|
+
{ unsafePreserveChecks: true },
|
|
210
208
|
);
|
|
211
209
|
}
|
|
212
210
|
return Schema.make(extendAst(s.ast));
|
|
@@ -219,9 +217,9 @@ export const extendWithSystemFields = <
|
|
|
219
217
|
};
|
|
220
218
|
|
|
221
219
|
/**
|
|
222
|
-
* Applies the system fields to a single struct, mirroring
|
|
223
|
-
* Any other (already-extended or opaque) schema falls
|
|
224
|
-
* the system-field document shape.
|
|
220
|
+
* Applies the system fields to a single struct, mirroring
|
|
221
|
+
* `Schema.fieldsAssign`. Any other (already-extended or opaque) schema falls
|
|
222
|
+
* back to a `Codec` carrying the system-field document shape.
|
|
225
223
|
*/
|
|
226
224
|
type ApplySystemFields<TableName extends string, S> =
|
|
227
225
|
S extends Schema.Struct<infer Fields extends Schema.Struct.Fields>
|
|
@@ -241,10 +239,10 @@ type ApplySystemFields<TableName extends string, S> =
|
|
|
241
239
|
* This mirrors the runtime {@link extendWithSystemFields}: a `Struct` gains the
|
|
242
240
|
* system fields directly (matching `Schema.fieldsAssign`), and a `Union` has
|
|
243
241
|
* them distributed across its members (matching
|
|
244
|
-
* `union.mapMembers(Tuple.map(Schema.fieldsAssign(...)))`). The
|
|
245
|
-
* structure is preserved rather than collapsed to a bare
|
|
246
|
-
* schema falls back to a `Codec` carrying the system-field
|
|
247
|
-
* matching the runtime's AST-level extension.
|
|
242
|
+
* `union.mapMembers(Tuple.map(Schema.fieldsAssign(...)))`). The
|
|
243
|
+
* `Struct`/`Union` structure is preserved rather than collapsed to a bare
|
|
244
|
+
* `Codec`; any other schema falls back to a `Codec` carrying the system-field
|
|
245
|
+
* document shape, matching the runtime's AST-level extension.
|
|
248
246
|
*/
|
|
249
247
|
export type ExtendWithSystemFields<
|
|
250
248
|
TableName extends string,
|
|
@@ -264,7 +262,7 @@ export type ExtendWithSystemFields<
|
|
|
264
262
|
|
|
265
263
|
/**
|
|
266
264
|
* The decoded/encoded document shape: a table's fields plus Convex's system
|
|
267
|
-
* fields. Deliberately a bare intersection (no `Expand`/`Simplify`)
|
|
265
|
+
* fields. Deliberately a bare intersection (no `Expand`/`Simplify`)—flattening
|
|
268
266
|
* it with a homomorphic mapped type collapses to `{ [x: string]: any }` when
|
|
269
267
|
* `Document` is still an unresolved generic, which breaks structural
|
|
270
268
|
* comparability in the database reader/writer plumbing.
|