@rebasepro/types 0.10.0 → 0.10.1-canary.0a881d4
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/dist/call_context.d.ts +51 -0
- package/dist/controllers/auth_state.d.ts +23 -0
- package/dist/controllers/client.d.ts +3 -1
- package/dist/controllers/collection_registry.d.ts +5 -1
- package/dist/controllers/data_driver.d.ts +31 -2
- package/dist/controllers/index.d.ts +1 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +374 -1
- package/dist/index.es.js.map +1 -1
- package/dist/types/admin_block.d.ts +34 -0
- package/dist/types/backend.d.ts +30 -1
- package/dist/types/channel_bus.d.ts +192 -0
- package/dist/types/collection_contract.d.ts +43 -0
- package/dist/types/collections.d.ts +17 -789
- package/dist/types/component_ref.d.ts +39 -6
- package/dist/types/entity_callbacks.d.ts +1 -1
- package/dist/types/index.d.ts +7 -15
- package/dist/types/project_manifest.d.ts +336 -0
- package/dist/types/properties.d.ts +12 -157
- package/dist/types/schema_version.d.ts +18 -0
- package/dist/types/security_rules.d.ts +320 -0
- package/dist/types/storage_authorize.d.ts +74 -0
- package/package.json +3 -6
- package/src/call_context.ts +56 -0
- package/src/controllers/auth_state.ts +24 -0
- package/src/controllers/client.ts +3 -2
- package/src/controllers/collection_registry.ts +5 -1
- package/src/controllers/data_driver.ts +58 -2
- package/src/controllers/index.ts +1 -10
- package/src/index.ts +1 -1
- package/src/types/admin_block.ts +75 -0
- package/src/types/backend.ts +33 -1
- package/src/types/channel_bus.ts +202 -0
- package/src/types/collection_contract.ts +278 -0
- package/src/types/collections.ts +25 -848
- package/src/types/component_ref.ts +40 -6
- package/src/types/entity_callbacks.ts +1 -1
- package/src/types/index.ts +7 -15
- package/src/types/policy.ts +25 -11
- package/src/types/project_manifest.ts +362 -0
- package/src/types/properties.ts +11 -169
- package/src/types/schema_version.ts +112 -0
- package/src/types/security_rules.ts +344 -0
- package/src/types/storage_authorize.ts +77 -0
- package/dist/controllers/analytics_controller.d.ts +0 -7
- package/dist/controllers/auth.d.ts +0 -110
- package/dist/controllers/customization_controller.d.ts +0 -61
- package/dist/controllers/dialogs_controller.d.ts +0 -36
- package/dist/controllers/local_config_persistence.d.ts +0 -20
- package/dist/controllers/navigation.d.ts +0 -225
- package/dist/controllers/registry.d.ts +0 -80
- package/dist/controllers/side_dialogs_controller.d.ts +0 -67
- package/dist/controllers/side_panel_controller.d.ts +0 -97
- package/dist/controllers/snackbar.d.ts +0 -24
- package/dist/rebase_context.d.ts +0 -110
- package/dist/types/breadcrumbs.d.ts +0 -26
- package/dist/types/builders.d.ts +0 -15
- package/dist/types/component_overrides.d.ts +0 -196
- package/dist/types/entity_actions.d.ts +0 -104
- package/dist/types/entity_link_builder.d.ts +0 -7
- package/dist/types/entity_views.d.ts +0 -95
- package/dist/types/export_import.d.ts +0 -21
- package/dist/types/formex.d.ts +0 -40
- package/dist/types/locales.d.ts +0 -4
- package/dist/types/modify_collections.d.ts +0 -5
- package/dist/types/plugins.d.ts +0 -277
- package/dist/types/property_config.d.ts +0 -74
- package/dist/types/slots.d.ts +0 -262
- package/dist/types/translations.d.ts +0 -915
- package/dist/types/user_management_delegate.d.ts +0 -22
- package/src/controllers/analytics_controller.tsx +0 -57
- package/src/controllers/auth.tsx +0 -121
- package/src/controllers/customization_controller.tsx +0 -72
- package/src/controllers/dialogs_controller.tsx +0 -37
- package/src/controllers/local_config_persistence.tsx +0 -22
- package/src/controllers/navigation.ts +0 -267
- package/src/controllers/registry.ts +0 -95
- package/src/controllers/side_dialogs_controller.tsx +0 -82
- package/src/controllers/side_panel_controller.tsx +0 -112
- package/src/controllers/snackbar.ts +0 -29
- package/src/rebase_context.tsx +0 -130
- package/src/types/breadcrumbs.ts +0 -27
- package/src/types/builders.ts +0 -17
- package/src/types/component_overrides.ts +0 -244
- package/src/types/entity_actions.tsx +0 -125
- package/src/types/entity_link_builder.ts +0 -8
- package/src/types/entity_views.tsx +0 -114
- package/src/types/export_import.ts +0 -26
- package/src/types/formex.ts +0 -45
- package/src/types/locales.ts +0 -81
- package/src/types/modify_collections.tsx +0 -6
- package/src/types/plugins.tsx +0 -346
- package/src/types/property_config.tsx +0 -95
- package/src/types/slots.tsx +0 -307
- package/src/types/translations.ts +0 -1026
- package/src/types/user_management_delegate.ts +0 -23
package/src/types/properties.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { Entity, EntityReference, EntityRelation, EntityValues, GeoPoint, V
|
|
|
4
4
|
import type { JoinStep, OnAction, Relation } from "./relations";
|
|
5
5
|
import type { CollectionConfig, FilterValues, WhereFilterOp } from "./collections";
|
|
6
6
|
import type { ColorKey, ColorScheme } from "./chips";
|
|
7
|
-
import type {
|
|
7
|
+
import type { AuthState } from "../controllers/auth_state";
|
|
8
8
|
import type { AfterReadProps, BeforeSaveProps } from "./entity_callbacks";
|
|
9
9
|
import type { User } from "../users";
|
|
10
10
|
|
|
@@ -151,50 +151,7 @@ export type InferEntityType<P extends Properties> = {
|
|
|
151
151
|
-readonly [K in OptionalPropertyKeys<P>]?: InferPropertyType<P[K]>;
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
-
/**
|
|
155
|
-
* Interface including all common properties of a CMS property.
|
|
156
|
-
* @group Entity properties
|
|
157
|
-
*/
|
|
158
|
-
export interface BaseUIConfig<CustomProps = unknown> {
|
|
159
|
-
columnWidth?: number;
|
|
160
|
-
hideFromCollection?: boolean;
|
|
161
|
-
readOnly?: boolean;
|
|
162
|
-
disabled?: boolean | PropertyDisabledConfig;
|
|
163
|
-
widthPercentage?: number;
|
|
164
|
-
customProps?: CustomProps;
|
|
165
|
-
Field?: ComponentRef<any>;
|
|
166
|
-
Preview?: ComponentRef<any>;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Narrow the filter operators offered for this property in collection
|
|
170
|
-
* filter UIs (table header filters and the Filters dialog).
|
|
171
|
-
*
|
|
172
|
-
* The final offered set is the **intersection** of the engine's
|
|
173
|
-
* capabilities, the property-type defaults, and this list — you can only
|
|
174
|
-
* *restrict*, never enable an operator the underlying engine cannot run.
|
|
175
|
-
*
|
|
176
|
-
* Pass an empty array to disable filtering on this property entirely.
|
|
177
|
-
*
|
|
178
|
-
* @example
|
|
179
|
-
* // Email column: exact match, contains, and null check only
|
|
180
|
-
* ui: { filterOperators: ["==", "ilike", "is-null"] }
|
|
181
|
-
*/
|
|
182
|
-
filterOperators?: readonly WhereFilterOp[];
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Replace the filter field rendered for this property in collection
|
|
186
|
-
* filter UIs. The component receives `FilterFieldBindingProps`
|
|
187
|
-
* (property, resolved `operators`, `value`, `setValue`, …).
|
|
188
|
-
*
|
|
189
|
-
* Takes precedence over the collection-level
|
|
190
|
-
* `components["Collection.FilterField"]` override and the built-in
|
|
191
|
-
* per-type filter fields.
|
|
192
|
-
*/
|
|
193
|
-
Filter?: ComponentRef<any>;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
154
|
export interface BaseProperty<CustomProps = unknown> {
|
|
197
|
-
ui?: BaseUIConfig<CustomProps>;
|
|
198
155
|
/**
|
|
199
156
|
* Property name (e.g. Product)
|
|
200
157
|
*/
|
|
@@ -285,36 +242,7 @@ export interface BaseProperty<CustomProps = unknown> {
|
|
|
285
242
|
|
|
286
243
|
}
|
|
287
244
|
|
|
288
|
-
/**
|
|
289
|
-
* @group Entity properties
|
|
290
|
-
*/
|
|
291
|
-
export interface StringUIConfig extends BaseUIConfig {
|
|
292
|
-
/**
|
|
293
|
-
* Is this string property long enough so it should be displayed in
|
|
294
|
-
* a multiple line field. Defaults to false. If set to true,
|
|
295
|
-
* the number of lines adapts to the content
|
|
296
|
-
*/
|
|
297
|
-
multiline?: boolean;
|
|
298
|
-
/**
|
|
299
|
-
* Should this string property be displayed as a markdown field. If true,
|
|
300
|
-
* the field is rendered as a text editor that supports markdown highlight
|
|
301
|
-
* syntax. It also includes a preview of the result.
|
|
302
|
-
*/
|
|
303
|
-
markdown?: boolean;
|
|
304
|
-
/**
|
|
305
|
-
* Should this string be rendered as a tag instead of just text.
|
|
306
|
-
*/
|
|
307
|
-
previewAsTag?: boolean;
|
|
308
|
-
clearable?: boolean;
|
|
309
|
-
/**
|
|
310
|
-
* If the value of this property is a URL, you can set this flag to true
|
|
311
|
-
* to add a link, or one of the supported media types to render a preview
|
|
312
|
-
*/
|
|
313
|
-
url?: boolean | PreviewType;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
245
|
export interface StringProperty extends BaseProperty {
|
|
317
|
-
ui?: StringUIConfig;
|
|
318
246
|
type: "string";
|
|
319
247
|
/**
|
|
320
248
|
* Default value for new entities. Must be a string.
|
|
@@ -374,17 +302,19 @@ export interface StringProperty extends BaseProperty {
|
|
|
374
302
|
* Does this field include an email
|
|
375
303
|
*/
|
|
376
304
|
email?: boolean;
|
|
377
|
-
}
|
|
378
305
|
|
|
379
|
-
/**
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
306
|
+
/**
|
|
307
|
+
* Does this string hold a URL?
|
|
308
|
+
*
|
|
309
|
+
* A statement about the *data*, which is why it sits here beside `email`
|
|
310
|
+
* rather than in the admin block: the OpenAPI generator turns it into
|
|
311
|
+
* `format: "uri"`, so it is part of the published API contract. How the panel
|
|
312
|
+
* renders it — as a link, an image, a video — is `admin.urlPreview`.
|
|
313
|
+
*/
|
|
314
|
+
url?: boolean;
|
|
384
315
|
}
|
|
385
316
|
|
|
386
317
|
export interface NumberProperty extends BaseProperty {
|
|
387
|
-
ui?: NumberUIConfig;
|
|
388
318
|
type: "number";
|
|
389
319
|
/**
|
|
390
320
|
* Default value for new entities. Must be a number.
|
|
@@ -423,7 +353,6 @@ export interface NumberProperty extends BaseProperty {
|
|
|
423
353
|
* @group Entity properties
|
|
424
354
|
*/
|
|
425
355
|
export interface BooleanProperty extends BaseProperty {
|
|
426
|
-
ui?: BaseUIConfig;
|
|
427
356
|
type: "boolean";
|
|
428
357
|
/**
|
|
429
358
|
* Default value for new entities. Must be a boolean.
|
|
@@ -435,15 +364,7 @@ export interface BooleanProperty extends BaseProperty {
|
|
|
435
364
|
validation?: PropertyValidationSchema;
|
|
436
365
|
}
|
|
437
366
|
|
|
438
|
-
/**
|
|
439
|
-
* @group Entity properties
|
|
440
|
-
*/
|
|
441
|
-
export interface VectorUIConfig extends BaseUIConfig {
|
|
442
|
-
clearable?: boolean;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
367
|
export interface VectorProperty extends BaseProperty {
|
|
446
|
-
ui?: VectorUIConfig;
|
|
447
368
|
type: "vector";
|
|
448
369
|
/**
|
|
449
370
|
* Default value for new entities.
|
|
@@ -465,18 +386,7 @@ export interface BinaryProperty extends BaseProperty {
|
|
|
465
386
|
validation?: PropertyValidationSchema;
|
|
466
387
|
}
|
|
467
388
|
|
|
468
|
-
/**
|
|
469
|
-
* @group Entity properties
|
|
470
|
-
*/
|
|
471
|
-
export interface DateUIConfig extends BaseUIConfig {
|
|
472
|
-
/**
|
|
473
|
-
* Add an icon to clear the value and set it to `null`. Defaults to `false`
|
|
474
|
-
*/
|
|
475
|
-
clearable?: boolean;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
389
|
export interface DateProperty extends BaseProperty {
|
|
479
|
-
ui?: DateUIConfig;
|
|
480
390
|
type: "date";
|
|
481
391
|
/**
|
|
482
392
|
* Default value for new entities. Must be a Date.
|
|
@@ -513,7 +423,6 @@ export interface DateProperty extends BaseProperty {
|
|
|
513
423
|
* @group Entity properties
|
|
514
424
|
*/
|
|
515
425
|
export interface GeopointProperty extends BaseProperty {
|
|
516
|
-
ui?: BaseUIConfig;
|
|
517
426
|
type: "geopoint";
|
|
518
427
|
/**
|
|
519
428
|
* Default value for new entities. Must be a GeoPoint.
|
|
@@ -525,13 +434,6 @@ export interface GeopointProperty extends BaseProperty {
|
|
|
525
434
|
validation?: PropertyValidationSchema;
|
|
526
435
|
}
|
|
527
436
|
|
|
528
|
-
/**
|
|
529
|
-
* @group Entity properties
|
|
530
|
-
*/
|
|
531
|
-
export interface ReferenceUIConfig extends BaseUIConfig {
|
|
532
|
-
previewProperties?: string[];
|
|
533
|
-
}
|
|
534
|
-
|
|
535
437
|
/**
|
|
536
438
|
* A pointer to a entity, stored **as a value** on the row (id + path, and
|
|
537
439
|
* optionally a `driver`/`databaseId` for cross-datasource pointers).
|
|
@@ -549,7 +451,6 @@ export interface ReferenceUIConfig extends BaseUIConfig {
|
|
|
549
451
|
* @group Entity properties
|
|
550
452
|
*/
|
|
551
453
|
export interface ReferenceProperty extends BaseProperty {
|
|
552
|
-
ui?: ReferenceUIConfig;
|
|
553
454
|
type: "reference";
|
|
554
455
|
/**
|
|
555
456
|
* Default value for new entities. Must be a EntityReference.
|
|
@@ -588,14 +489,6 @@ export interface ReferenceProperty extends BaseProperty {
|
|
|
588
489
|
includeEntityLink?: boolean;
|
|
589
490
|
}
|
|
590
491
|
|
|
591
|
-
/**
|
|
592
|
-
* @group Entity properties
|
|
593
|
-
*/
|
|
594
|
-
export interface RelationUIConfig extends BaseUIConfig {
|
|
595
|
-
previewProperties?: string[];
|
|
596
|
-
widget?: "select" | "dialog";
|
|
597
|
-
}
|
|
598
|
-
|
|
599
492
|
/**
|
|
600
493
|
* A schema-level relationship between collections **within a single
|
|
601
494
|
* datasource** — backed by a foreign key, junction table, or explicit join
|
|
@@ -613,7 +506,6 @@ export interface RelationUIConfig extends BaseUIConfig {
|
|
|
613
506
|
* @group Entity properties
|
|
614
507
|
*/
|
|
615
508
|
export interface RelationProperty extends BaseProperty {
|
|
616
|
-
ui?: RelationUIConfig;
|
|
617
509
|
type: "relation";
|
|
618
510
|
/**
|
|
619
511
|
* Default value for new entities. Must be a EntityRelation or array of EntityRelation.
|
|
@@ -747,16 +639,7 @@ export interface RelationProperty extends BaseProperty {
|
|
|
747
639
|
widget?: "select" | "dialog";
|
|
748
640
|
}
|
|
749
641
|
|
|
750
|
-
/**
|
|
751
|
-
* @group Entity properties
|
|
752
|
-
*/
|
|
753
|
-
export interface ArrayUIConfig extends BaseUIConfig {
|
|
754
|
-
expanded?: boolean;
|
|
755
|
-
minimalistView?: boolean;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
642
|
export interface ArrayProperty extends BaseProperty {
|
|
759
|
-
ui?: ArrayUIConfig;
|
|
760
643
|
type: "array";
|
|
761
644
|
/**
|
|
762
645
|
* Default value for new entities. Must be an array.
|
|
@@ -830,17 +713,7 @@ export interface ArrayProperty extends BaseProperty {
|
|
|
830
713
|
canAddElements?: boolean;
|
|
831
714
|
}
|
|
832
715
|
|
|
833
|
-
/**
|
|
834
|
-
* @group Entity properties
|
|
835
|
-
*/
|
|
836
|
-
export interface MapUIConfig extends BaseUIConfig {
|
|
837
|
-
expanded?: boolean;
|
|
838
|
-
minimalistView?: boolean;
|
|
839
|
-
spreadChildren?: boolean;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
716
|
export interface MapProperty extends BaseProperty {
|
|
843
|
-
ui?: MapUIConfig;
|
|
844
717
|
type: "map";
|
|
845
718
|
/**
|
|
846
719
|
* Default value for new entities. Must be a record/object.
|
|
@@ -887,34 +760,9 @@ export type PropertyBuilderProps<M extends Record<string, unknown> = Record<stri
|
|
|
887
760
|
index?: number;
|
|
888
761
|
path: string;
|
|
889
762
|
entityId?: string | number;
|
|
890
|
-
authController:
|
|
763
|
+
authController: AuthState;
|
|
891
764
|
};
|
|
892
765
|
|
|
893
|
-
/**
|
|
894
|
-
* @group Entity properties
|
|
895
|
-
*/
|
|
896
|
-
export interface PropertyDisabledConfig {
|
|
897
|
-
/**
|
|
898
|
-
* Enable this flag if you would like to clear the value of the field
|
|
899
|
-
* when the corresponding property gets disabled.
|
|
900
|
-
*
|
|
901
|
-
* This is useful for keeping data consistency when you have conditional
|
|
902
|
-
* properties.
|
|
903
|
-
*/
|
|
904
|
-
clearOnDisabled?: boolean;
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* Explanation of why this property is disabled (e.g. a different field
|
|
908
|
-
* needs to be enabled)
|
|
909
|
-
*/
|
|
910
|
-
disabledMessage?: string;
|
|
911
|
-
|
|
912
|
-
/**
|
|
913
|
-
* Set this flag to true if you want to hide this field when disabled
|
|
914
|
-
*/
|
|
915
|
-
hidden?: boolean;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
766
|
/**
|
|
919
767
|
* We use this type to define mapping between string or number values in
|
|
920
768
|
* the data source to a label (such in a select dropdown).
|
|
@@ -1195,12 +1043,6 @@ export interface UploadedFileContext {
|
|
|
1195
1043
|
storage: StorageConfig;
|
|
1196
1044
|
}
|
|
1197
1045
|
|
|
1198
|
-
/**
|
|
1199
|
-
* Used for previewing urls if the download file is known
|
|
1200
|
-
* @group Entity properties
|
|
1201
|
-
*/
|
|
1202
|
-
export type PreviewType = "image" | "video" | "audio" | "file";
|
|
1203
|
-
|
|
1204
1046
|
/**
|
|
1205
1047
|
* MIME types for storage fields
|
|
1206
1048
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { CollectionConfig } from "./collections";
|
|
2
|
+
import { serializeCollections } from "./collection_contract";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The schema version stamp.
|
|
6
|
+
*
|
|
7
|
+
* One function, used in three places that must agree or the whole drift-detection
|
|
8
|
+
* story is noise: `rebase build` writes it into a bundle manifest, the runtime
|
|
9
|
+
* serves it from the contract endpoint, and a generated SDK records the value it
|
|
10
|
+
* was built from. If any two of those computed it differently, every client would
|
|
11
|
+
* look permanently out of date.
|
|
12
|
+
*
|
|
13
|
+
* It covers **collections only** — the client's contract is the shape of the
|
|
14
|
+
* data, so editing a hook or a server function must not invalidate every SDK in
|
|
15
|
+
* every repository. That is a deliberate narrowing, not an oversight.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Stable stringify: object keys sorted at every level, so key order cannot alter the hash. */
|
|
19
|
+
function canonicalize(value: unknown): string {
|
|
20
|
+
if (value === null || typeof value !== "object") {
|
|
21
|
+
return JSON.stringify(value) ?? "null";
|
|
22
|
+
}
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
return `[${value.map(canonicalize).join(",")}]`;
|
|
25
|
+
}
|
|
26
|
+
const entries = Object.entries(value as Record<string, unknown>)
|
|
27
|
+
.filter(([, v]) => v !== undefined)
|
|
28
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
29
|
+
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalize(v)}`).join(",")}}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Reduce a collection to the parts a generated client is actually built from.
|
|
34
|
+
*
|
|
35
|
+
* The version answers one question — "is this SDK stale?" — so it must change
|
|
36
|
+
* exactly when the generated types could change, and never otherwise. Hashing a
|
|
37
|
+
* whole collection fails both halves of that:
|
|
38
|
+
*
|
|
39
|
+
* - Security rules, callbacks, icons, groups and UI settings do not appear in a
|
|
40
|
+
* generated client, so including them reports perfectly current SDKs as stale.
|
|
41
|
+
* - Worse, they are not stable *inputs*. The runtime applies default security
|
|
42
|
+
* rules when it loads collections, so the same source hashed before and after
|
|
43
|
+
* loading produced two different answers — a build-time stamp that could never
|
|
44
|
+
* match the server that served it.
|
|
45
|
+
*
|
|
46
|
+
* Codegen reads the slug (for the `Database` key and type names), the properties,
|
|
47
|
+
* and the relations. That is the projection.
|
|
48
|
+
*/
|
|
49
|
+
function projectForCodegen(collection: CollectionConfig): Record<string, unknown> {
|
|
50
|
+
const source = collection as CollectionConfig & {
|
|
51
|
+
relations?: unknown;
|
|
52
|
+
subcollections?: CollectionConfig[];
|
|
53
|
+
path?: string;
|
|
54
|
+
engine?: unknown;
|
|
55
|
+
dataSource?: unknown;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
slug: collection.slug ?? source.path,
|
|
60
|
+
properties: collection.properties,
|
|
61
|
+
relations: source.relations,
|
|
62
|
+
// The engine decides whether relations are resolved at all: codegen asks
|
|
63
|
+
// `getDataSourceCapabilities(collection.engine).supportsRelations`, and an
|
|
64
|
+
// engine that answers no drops every foreign-key column from the
|
|
65
|
+
// generated Row/Insert/Update types. Moving a collection to such an
|
|
66
|
+
// engine is a real change to the generated types, so it has to move the
|
|
67
|
+
// version. `dataSource` is what resolves to `engine`, so it counts too.
|
|
68
|
+
engine: source.engine,
|
|
69
|
+
dataSource: source.dataSource,
|
|
70
|
+
subcollections: source.subcollections?.map(projectForCodegen)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Compute the canonical string a schema version hashes.
|
|
76
|
+
*
|
|
77
|
+
* Exposed separately so the hashing itself can differ by environment: Node has
|
|
78
|
+
* `crypto`, and callers without it can still compare canonical forms directly.
|
|
79
|
+
*/
|
|
80
|
+
export function canonicalSchemaPayload(collections: CollectionConfig[]): string {
|
|
81
|
+
const projected = serializeCollections(collections)
|
|
82
|
+
.map(collection => projectForCodegen(collection as CollectionConfig));
|
|
83
|
+
return canonicalize(projected);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A short, non-cryptographic digest of the canonical payload.
|
|
88
|
+
*
|
|
89
|
+
* FNV-1a style, 64 bits, as two 32-bit halves. This is an identity, not a
|
|
90
|
+
* security boundary: nothing trusts a schema version to prove anything, it only
|
|
91
|
+
* answers "is this the same schema as before". A hand-rolled hash keeps this
|
|
92
|
+
* module free of `node:crypto`, so the identical function runs in the browser,
|
|
93
|
+
* in the CLI, and in the runtime — which is the property that actually matters.
|
|
94
|
+
*/
|
|
95
|
+
export function computeSchemaVersion(collections: CollectionConfig[]): string {
|
|
96
|
+
const payload = canonicalSchemaPayload(collections);
|
|
97
|
+
|
|
98
|
+
let h1 = 0x811c9dc5;
|
|
99
|
+
let h2 = 0x01000193;
|
|
100
|
+
|
|
101
|
+
for (let i = 0; i < payload.length; i++) {
|
|
102
|
+
const code = payload.charCodeAt(i);
|
|
103
|
+
h1 ^= code;
|
|
104
|
+
// Multiply by the FNV prime using shifts to stay in 32-bit integer math.
|
|
105
|
+
h1 = (h1 + ((h1 << 1) + (h1 << 4) + (h1 << 7) + (h1 << 8) + (h1 << 24))) >>> 0;
|
|
106
|
+
h2 ^= code + i;
|
|
107
|
+
h2 = (h2 + ((h2 << 1) + (h2 << 5) + (h2 << 9) + (h2 << 15) + (h2 << 24))) >>> 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const hex = (n: number): string => n.toString(16).padStart(8, "0");
|
|
111
|
+
return `v1:${hex(h1)}${hex(h2)}`;
|
|
112
|
+
}
|