@gaganref/confect-core 10.3.1-fork.8 → 10.3.1-fork.81

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.
Files changed (89) hide show
  1. package/dist/ActionCall.d.ts +18 -0
  2. package/dist/ActionCall.d.ts.map +1 -0
  3. package/dist/ActionCall.js +21 -0
  4. package/dist/ActionCall.js.map +1 -0
  5. package/dist/App.d.ts +30 -93
  6. package/dist/App.d.ts.map +1 -1
  7. package/dist/App.js +24 -38
  8. package/dist/App.js.map +1 -1
  9. package/dist/Auth.d.ts +33 -9
  10. package/dist/Auth.d.ts.map +1 -1
  11. package/dist/Auth.js +17 -2
  12. package/dist/Auth.js.map +1 -1
  13. package/dist/Callback.d.ts +7 -2
  14. package/dist/Callback.d.ts.map +1 -1
  15. package/dist/Callback.js +11 -6
  16. package/dist/Callback.js.map +1 -1
  17. package/dist/Component.d.ts +98 -2
  18. package/dist/Component.d.ts.map +1 -1
  19. package/dist/Component.js +44 -18
  20. package/dist/Component.js.map +1 -1
  21. package/dist/FunctionSpec.d.ts +365 -2
  22. package/dist/FunctionSpec.d.ts.map +1 -1
  23. package/dist/FunctionSpec.js +66 -3
  24. package/dist/FunctionSpec.js.map +1 -1
  25. package/dist/GenericId.js +2 -2
  26. package/dist/GroupSpec.js +1 -1
  27. package/dist/Http.d.ts +4 -8
  28. package/dist/Http.d.ts.map +1 -1
  29. package/dist/Http.js +15 -22
  30. package/dist/Http.js.map +1 -1
  31. package/dist/ManifestSection.d.ts +70 -0
  32. package/dist/ManifestSection.d.ts.map +1 -0
  33. package/dist/ManifestSection.js +7 -0
  34. package/dist/ManifestSection.js.map +1 -0
  35. package/dist/Mount.d.ts +200 -0
  36. package/dist/Mount.d.ts.map +1 -0
  37. package/dist/Mount.js +116 -0
  38. package/dist/Mount.js.map +1 -0
  39. package/dist/PaginationError.js +1 -1
  40. package/dist/Profile.d.ts +95 -0
  41. package/dist/Profile.d.ts.map +1 -0
  42. package/dist/Profile.js +15 -0
  43. package/dist/Profile.js.map +1 -0
  44. package/dist/Ref.d.ts +4 -3
  45. package/dist/Ref.d.ts.map +1 -1
  46. package/dist/Ref.js +13 -19
  47. package/dist/Ref.js.map +1 -1
  48. package/dist/RefInternal.d.ts +3 -0
  49. package/dist/RefInternal.d.ts.map +1 -0
  50. package/dist/RefInternal.js +16 -0
  51. package/dist/RefInternal.js.map +1 -0
  52. package/dist/SchemaToValidator.d.ts +11 -2
  53. package/dist/SchemaToValidator.d.ts.map +1 -1
  54. package/dist/SchemaToValidator.js +43 -14
  55. package/dist/SchemaToValidator.js.map +1 -1
  56. package/dist/SystemFields.js +3 -3
  57. package/dist/Table.d.ts +48 -9
  58. package/dist/Table.d.ts.map +1 -1
  59. package/dist/Table.js +41 -13
  60. package/dist/Table.js.map +1 -1
  61. package/dist/index.d.ts +4 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +10 -6
  64. package/dist/internal/annotations.d.ts +2 -0
  65. package/dist/internal/annotations.d.ts.map +1 -0
  66. package/dist/internal/annotations.js +6 -0
  67. package/dist/internal/annotations.js.map +1 -0
  68. package/dist/internal/scalarDocs.d.ts +5 -0
  69. package/dist/internal/scalarDocs.d.ts.map +1 -0
  70. package/dist/internal/scalarDocs.js +43 -0
  71. package/dist/internal/scalarDocs.js.map +1 -0
  72. package/package.json +3 -3
  73. package/src/ActionCall.ts +25 -0
  74. package/src/App.ts +36 -136
  75. package/src/Auth.ts +54 -11
  76. package/src/Callback.ts +17 -4
  77. package/src/Component.ts +196 -11
  78. package/src/FunctionSpec.ts +566 -5
  79. package/src/Http.ts +15 -37
  80. package/src/ManifestSection.ts +78 -0
  81. package/src/Mount.ts +401 -0
  82. package/src/Profile.ts +141 -0
  83. package/src/Ref.ts +19 -26
  84. package/src/RefInternal.ts +26 -0
  85. package/src/SchemaToValidator.ts +47 -5
  86. package/src/Table.ts +157 -23
  87. package/src/index.ts +4 -0
  88. package/src/internal/annotations.ts +1 -0
  89. package/src/internal/scalarDocs.ts +72 -0
package/src/Table.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as GenericId from "./GenericId.js";
1
2
  import * as IdScope from "./IdScope.js";
2
3
  import * as Lazy from "./Lazy.js";
3
4
  import * as SystemFields from "./SystemFields.js";
@@ -12,7 +13,13 @@ import type {
12
13
  SearchIndexConfig,
13
14
  VectorIndexConfig,
14
15
  } from "convex/server";
15
- import type { GenericValidator, Validator } from "convex/values";
16
+ import type {
17
+ GenericId as ConvexGenericId,
18
+ GenericValidator,
19
+ Validator,
20
+ } from "convex/values";
21
+ import * as Data from "effect/Data";
22
+ import * as Option from "effect/Option";
16
23
  import * as Predicate from "effect/Predicate";
17
24
  import type * as Schema from "effect/Schema";
18
25
 
@@ -36,6 +43,97 @@ export const isTable = (u: unknown): u is Any =>
36
43
  export const isUnnamedTable = (u: unknown): u is UnnamedAny =>
37
44
  Predicate.hasProperty(u, TypeId) && !Predicate.hasProperty(u, "tableName");
38
45
 
46
+ // -----------------------------------------------------------------------------
47
+ // Group
48
+ // -----------------------------------------------------------------------------
49
+ //
50
+ // A table is grouped by one of its required id fields, and the id's table owns
51
+ // its rows. `table` and `scope` come from the id's schema on first read, so
52
+ // binding a table never builds its `Fields`.
53
+
54
+ export interface Group<
55
+ Key extends string = string,
56
+ Table_ extends string = string,
57
+ Scope_ extends IdScope.IdScope = IdScope.IdScope,
58
+ > {
59
+ readonly key: Key;
60
+ readonly table: Table_;
61
+ readonly scope: Scope_;
62
+ }
63
+
64
+ export class GroupFieldError extends Data.TaggedError("GroupFieldError")<{
65
+ readonly tableName: string;
66
+ readonly key: string;
67
+ }> {
68
+ override get message(): string {
69
+ return `Table '${this.tableName}' cannot be grouped by '${this.key}': it is not a field holding an id.`;
70
+ }
71
+ }
72
+
73
+ type FieldsOf<TableSchema_> = TableSchema_ extends {
74
+ readonly fields: infer StructFields extends Schema.Struct.Fields;
75
+ }
76
+ ? StructFields
77
+ : never;
78
+
79
+ type GroupKeys<TableSchema_> = {
80
+ [
81
+ Key in keyof FieldsOf<TableSchema_> & string
82
+ ]: FieldsOf<TableSchema_>[Key] extends {
83
+ readonly Type: ConvexGenericId<string>;
84
+ }
85
+ ? [FieldsOf<TableSchema_>[Key]["~type.optionality"]] extends ["optional"]
86
+ ? never
87
+ : Key
88
+ : never;
89
+ }[keyof FieldsOf<TableSchema_> & string];
90
+
91
+ type IdTableName<Id> = Id extends {
92
+ readonly "~@confect/core/ScopedId": {
93
+ readonly table: infer TableName extends string;
94
+ };
95
+ }
96
+ ? TableName
97
+ : Id extends ConvexGenericId<infer TableName>
98
+ ? TableName
99
+ : never;
100
+
101
+ type IdScopeOf<Id> = Id extends {
102
+ readonly "~@confect/core/ScopedId": {
103
+ readonly scope: infer Scope_ extends IdScope.IdScope;
104
+ };
105
+ }
106
+ ? Scope_
107
+ : IdScope.App;
108
+
109
+ type GroupOf<TableSchema_, Key extends string> = Group<
110
+ Key,
111
+ IdTableName<
112
+ FieldsOf<TableSchema_>[Key & keyof FieldsOf<TableSchema_>]["Type"]
113
+ >,
114
+ IdScopeOf<FieldsOf<TableSchema_>[Key & keyof FieldsOf<TableSchema_>]["Type"]>
115
+ >;
116
+
117
+ const makeGroup = (
118
+ tableName: string,
119
+ key: string,
120
+ fields: () => Schema.Codec<any, any>,
121
+ ): Group => {
122
+ const idField = () => {
123
+ const ast = (fields() as { readonly fields?: Schema.Struct.Fields })
124
+ .fields?.[key]?.ast;
125
+ const table =
126
+ ast === undefined ? Option.none() : GenericId.tableName<string>(ast);
127
+ if (ast === undefined || Option.isNone(table))
128
+ throw new GroupFieldError({ tableName, key });
129
+ return { table: table.value, scope: GenericId.scope(ast) };
130
+ };
131
+ const group = { key };
132
+ Lazy.defineProperty(group, "table", () => idField().table);
133
+ Lazy.defineProperty(group, "scope", () => idField().scope);
134
+ return group as Group;
135
+ };
136
+
39
137
  // -----------------------------------------------------------------------------
40
138
  // Bound Table
41
139
  // -----------------------------------------------------------------------------
@@ -54,10 +152,12 @@ export interface Table<
54
152
  SearchIndexes_ extends GenericTableSearchIndexes = {},
55
153
  VectorIndexes_ extends GenericTableVectorIndexes = {},
56
154
  Scope_ extends IdScope.IdScope = IdScope.App,
155
+ Group_ extends Group | undefined = undefined,
57
156
  > {
58
157
  readonly [TypeId]: TypeId;
59
158
  readonly tableName: Name_;
60
159
  readonly scope: Scope_;
160
+ readonly group: Group_;
61
161
  readonly Fields: TableSchema_;
62
162
  readonly Doc: SystemFields.ExtendWithSystemFields<
63
163
  Name_,
@@ -82,7 +182,8 @@ export type AnyWithProps = Table<
82
182
  GenericTableIndexes,
83
183
  GenericTableSearchIndexes,
84
184
  GenericTableVectorIndexes,
85
- IdScope.IdScope
185
+ IdScope.IdScope,
186
+ Group | undefined
86
187
  >;
87
188
 
88
189
  // -----------------------------------------------------------------------------
@@ -105,6 +206,7 @@ export interface UnnamedTable<
105
206
  Indexes_ extends GenericTableIndexes = {},
106
207
  SearchIndexes_ extends GenericTableSearchIndexes = {},
107
208
  VectorIndexes_ extends GenericTableVectorIndexes = {},
209
+ Group_ extends Group | undefined = undefined,
108
210
  > {
109
211
  <
110
212
  const Name_ extends string,
@@ -119,7 +221,8 @@ export interface UnnamedTable<
119
221
  Indexes_,
120
222
  SearchIndexes_,
121
223
  VectorIndexes_,
122
- Scope_
224
+ Scope_,
225
+ Group_
123
226
  >;
124
227
 
125
228
  readonly [TypeId]: TypeId;
@@ -146,7 +249,8 @@ export interface UnnamedTable<
146
249
  >
147
250
  >,
148
251
  SearchIndexes_,
149
- VectorIndexes_
252
+ VectorIndexes_,
253
+ Group_
150
254
  >;
151
255
 
152
256
  searchIndex<
@@ -170,7 +274,8 @@ export interface UnnamedTable<
170
274
  }
171
275
  >
172
276
  >,
173
- VectorIndexes_
277
+ VectorIndexes_,
278
+ Group_
174
279
  >;
175
280
 
176
281
  vectorIndex<
@@ -195,7 +300,23 @@ export interface UnnamedTable<
195
300
  filterFields: FilterFields;
196
301
  }
197
302
  >
198
- >
303
+ >,
304
+ Group_
305
+ >;
306
+
307
+ /**
308
+ * Name the required id field that groups this table's rows. The field's table
309
+ * is the one whose rows own these rows.
310
+ */
311
+ group<const Key extends GroupKeys<TableSchema_>>(
312
+ key: Key,
313
+ ): UnnamedTable<
314
+ TableSchema_,
315
+ TableValidator_,
316
+ Indexes_,
317
+ SearchIndexes_,
318
+ VectorIndexes_,
319
+ GroupOf<TableSchema_, Key>
199
320
  >;
200
321
  }
201
322
 
@@ -208,7 +329,8 @@ export type UnnamedAnyWithProps = UnnamedTable<
208
329
  GenericValidator,
209
330
  GenericTableIndexes,
210
331
  GenericTableSearchIndexes,
211
- GenericTableVectorIndexes
332
+ GenericTableVectorIndexes,
333
+ Group | undefined
212
334
  >;
213
335
 
214
336
  // -----------------------------------------------------------------------------
@@ -266,6 +388,7 @@ interface UnnamedState<
266
388
  VectorIndexes_ extends GenericTableVectorIndexes,
267
389
  > {
268
390
  readonly lazyFields: () => TableSchema_;
391
+ readonly groupKey: string | undefined;
269
392
  readonly indexes: Indexes_;
270
393
  readonly searchIndexes: SearchIndexes_;
271
394
  readonly vectorIndexes: VectorIndexes_;
@@ -279,6 +402,7 @@ const makeBound = <
279
402
  SearchIndexes_ extends GenericTableSearchIndexes,
280
403
  VectorIndexes_ extends GenericTableVectorIndexes,
281
404
  Scope_ extends IdScope.IdScope,
405
+ Group_ extends Group | undefined,
282
406
  >(
283
407
  tableName: Name_,
284
408
  state: UnnamedState<TableSchema_, Indexes_, SearchIndexes_, VectorIndexes_>,
@@ -290,12 +414,17 @@ const makeBound = <
290
414
  Indexes_,
291
415
  SearchIndexes_,
292
416
  VectorIndexes_,
293
- Scope_
417
+ Scope_,
418
+ Group_
294
419
  > => {
295
420
  const bound = {
296
421
  [TypeId]: TypeId as TypeId,
297
422
  tableName,
298
423
  scope,
424
+ group:
425
+ state.groupKey === undefined
426
+ ? undefined
427
+ : makeGroup(tableName, state.groupKey, () => bound.Fields),
299
428
  indexes: state.indexes,
300
429
  searchIndexes: state.searchIndexes,
301
430
  vectorIndexes: state.vectorIndexes,
@@ -306,7 +435,8 @@ const makeBound = <
306
435
  Indexes_,
307
436
  SearchIndexes_,
308
437
  VectorIndexes_,
309
- Scope_
438
+ Scope_,
439
+ Group_
310
440
  >;
311
441
 
312
442
  Lazy.defineProperty(bound, "Fields", () => state.lazyFields());
@@ -328,6 +458,7 @@ const makeUnnamed = <
328
458
  Indexes_ extends GenericTableIndexes,
329
459
  SearchIndexes_ extends GenericTableSearchIndexes,
330
460
  VectorIndexes_ extends GenericTableVectorIndexes,
461
+ Group_ extends Group | undefined,
331
462
  >(
332
463
  state: UnnamedState<TableSchema_, Indexes_, SearchIndexes_, VectorIndexes_>,
333
464
  ): UnnamedTable<
@@ -335,14 +466,16 @@ const makeUnnamed = <
335
466
  TableValidator_,
336
467
  Indexes_,
337
468
  SearchIndexes_,
338
- VectorIndexes_
469
+ VectorIndexes_,
470
+ Group_
339
471
  > => {
340
472
  type UnnamedTable_ = UnnamedTable<
341
473
  TableSchema_,
342
474
  TableValidator_,
343
475
  Indexes_,
344
476
  SearchIndexes_,
345
- VectorIndexes_
477
+ VectorIndexes_,
478
+ Group_
346
479
  >;
347
480
 
348
481
  type UnnamedTableFunction<FunctionName extends keyof UnnamedTable_> =
@@ -361,7 +494,8 @@ const makeUnnamed = <
361
494
  Indexes_,
362
495
  SearchIndexes_,
363
496
  VectorIndexes_,
364
- Scope_
497
+ Scope_,
498
+ Group_
365
499
  > =>
366
500
  makeBound<
367
501
  Name_,
@@ -370,18 +504,17 @@ const makeUnnamed = <
370
504
  Indexes_,
371
505
  SearchIndexes_,
372
506
  VectorIndexes_,
373
- Scope_
507
+ Scope_,
508
+ Group_
374
509
  >(tableName, state, (scope ?? IdScope.app) as Scope_);
375
510
 
376
511
  const index: UnnamedTableFunction<"index"> = (name, fields) =>
377
512
  makeUnnamed({
378
- lazyFields: state.lazyFields,
513
+ ...state,
379
514
  indexes: {
380
515
  ...state.indexes,
381
516
  [name]: fields,
382
517
  } as any,
383
- searchIndexes: state.searchIndexes,
384
- vectorIndexes: state.vectorIndexes,
385
518
  });
386
519
 
387
520
  const searchIndex: UnnamedTableFunction<"searchIndex"> = (
@@ -389,13 +522,11 @@ const makeUnnamed = <
389
522
  indexConfig,
390
523
  ) =>
391
524
  makeUnnamed({
392
- lazyFields: state.lazyFields,
393
- indexes: state.indexes,
525
+ ...state,
394
526
  searchIndexes: {
395
527
  ...state.searchIndexes,
396
528
  [name]: indexConfig,
397
529
  } as any,
398
- vectorIndexes: state.vectorIndexes,
399
530
  });
400
531
 
401
532
  const vectorIndex: UnnamedTableFunction<"vectorIndex"> = (
@@ -403,15 +534,16 @@ const makeUnnamed = <
403
534
  indexConfig,
404
535
  ) =>
405
536
  makeUnnamed({
406
- lazyFields: state.lazyFields,
407
- indexes: state.indexes,
408
- searchIndexes: state.searchIndexes,
537
+ ...state,
409
538
  vectorIndexes: {
410
539
  ...state.vectorIndexes,
411
540
  [name]: indexConfig,
412
541
  } as any,
413
542
  });
414
543
 
544
+ const group: UnnamedTableFunction<"group"> = (key) =>
545
+ makeUnnamed({ ...state, groupKey: key });
546
+
415
547
  return Object.assign(bind, {
416
548
  [TypeId]: TypeId as TypeId,
417
549
  indexes: state.indexes,
@@ -420,6 +552,7 @@ const makeUnnamed = <
420
552
  index,
421
553
  searchIndex,
422
554
  vectorIndex,
555
+ group,
423
556
  }) as UnnamedTable_;
424
557
  };
425
558
 
@@ -429,8 +562,9 @@ export const make = <const TableSchema_ extends Schema.Codec<any, any>>(
429
562
  type TableValidator_ = TableSchemaToTableValidator<TableSchema_>;
430
563
  type UnnamedTable_ = UnnamedTable<TableSchema_, TableValidator_>;
431
564
 
432
- return makeUnnamed<TableSchema_, TableValidator_, {}, {}, {}>({
565
+ return makeUnnamed<TableSchema_, TableValidator_, {}, {}, {}, undefined>({
433
566
  lazyFields,
567
+ groupKey: undefined,
434
568
  indexes: {},
435
569
  searchIndexes: {},
436
570
  vectorIndexes: {},
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * as ActionCall from "./ActionCall.js";
1
2
  export * as Callback from "./Callback.js";
2
3
  export * as FunctionProvenance from "./FunctionProvenance.js";
3
4
  export * as FunctionSpec from "./FunctionSpec.js";
@@ -13,11 +14,14 @@ export * as GroupSpec from "./GroupSpec.js";
13
14
  export * as Identifier from "./Identifier.js";
14
15
  export * as Lazy from "./Lazy.js";
15
16
  export * as Manifest from "./Manifest.js";
17
+ export * as ManifestSection from "./ManifestSection.js";
18
+ export * as Mount from "./Mount.js";
16
19
  export * as MiddlewareAttachment from "./MiddlewareAttachment.js";
17
20
  export * as MiddlewareSpec from "./MiddlewareSpec.js";
18
21
  export * as PaginationError from "./PaginationError.js";
19
22
  export * as PaginationOptions from "./PaginationOptions.js";
20
23
  export * as PaginationResult from "./PaginationResult.js";
24
+ export * as Profile from "./Profile.js";
21
25
  export * as Ref from "./Ref.js";
22
26
  export * as Refs from "./Refs.js";
23
27
  export * as RuntimeAndFunctionType from "./RuntimeAndFunctionType.js";
@@ -0,0 +1 @@
1
+ export const CallbackContract = "~@confect/core/Callback/Contract";
@@ -0,0 +1,72 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as HttpRouter from "effect/http/HttpRouter";
3
+ import * as HttpServerResponse from "effect/http/HttpServerResponse";
4
+ import type * as HttpApi from "effect/http-api/HttpApi";
5
+ import type * as HttpApiGroup from "effect/http-api/HttpApiGroup";
6
+ import * as OpenApi from "effect/http-api/OpenApi";
7
+
8
+ const escape = (value: string) =>
9
+ value
10
+ .replaceAll("&", "&amp;")
11
+ .replaceAll("<", "&lt;")
12
+ .replaceAll(">", "&gt;");
13
+
14
+ const escapeAttribute = (value: string) =>
15
+ escape(value).replaceAll('"', "&quot;").replaceAll("'", "&#39;");
16
+
17
+ const escapeJson = (value: unknown) =>
18
+ JSON.stringify(value)
19
+ .replaceAll("<", "\\u003c")
20
+ .replaceAll("\u2028", "\\u2028")
21
+ .replaceAll("\u2029", "\\u2029");
22
+
23
+ // WORKAROUND: Effect 4.0.6's HttpApiScalar module imports its inline Scalar
24
+ // script dynamically, and Convex's bundler then splits a schema that reaches it
25
+ // into an imported chunk, which Convex refuses. This copies `layerCdn`'s page
26
+ // byte for byte. Remove when `checkSchemaBundle.mjs` passes with
27
+ // `HttpApiScalar.layerCdn` restored.
28
+ export const scalarDocs = <
29
+ Id extends string,
30
+ Groups extends HttpApiGroup.Constraint,
31
+ >(
32
+ api: HttpApi.HttpApi<Id, Groups>,
33
+ path: `/${string}`,
34
+ ) =>
35
+ HttpRouter.use((router) => {
36
+ let response: HttpServerResponse.HttpServerResponse | undefined;
37
+ return router.add(
38
+ "GET",
39
+ path,
40
+ Effect.sync(() => {
41
+ if (response !== undefined) return response;
42
+ const spec = OpenApi.fromApi(api);
43
+ const description = (tag: string) =>
44
+ !spec.info.description
45
+ ? ""
46
+ : `<meta name="${tag}" content="${escapeAttribute(spec.info.description)}"/>`;
47
+ response = HttpServerResponse.html(`<!doctype html>
48
+ <html>
49
+ <head>
50
+ <meta charset="utf-8" />
51
+ <title>${escape(spec.info.title)}</title>
52
+ ${description("description")}
53
+ ${description("og:description")}
54
+ <meta
55
+ name="viewport"
56
+ content="width=device-width, initial-scale=1" />
57
+ </head>
58
+ <body>
59
+ <div id="api-reference-container"></div>
60
+ <script src="${escapeAttribute("https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest/dist/browser/standalone.min.js")}" crossorigin></script>
61
+ <script>
62
+ window.Scalar.createApiReference(document.getElementById('api-reference-container'), {
63
+ ...${escapeJson({ _integration: "html" })},
64
+ content: ${escapeJson(spec)}
65
+ })
66
+ </script>
67
+ </body>
68
+ </html>`);
69
+ return response;
70
+ }),
71
+ );
72
+ });