@forge-cms/runtime 0.4.0 → 0.6.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.
Files changed (73) hide show
  1. package/dist/auth-managed.d.ts +19 -0
  2. package/dist/auth-managed.d.ts.map +1 -0
  3. package/dist/auth-managed.js +24 -0
  4. package/dist/auth-managed.js.map +1 -0
  5. package/dist/concurrency.d.ts +8 -0
  6. package/dist/concurrency.d.ts.map +1 -0
  7. package/dist/concurrency.js +15 -0
  8. package/dist/concurrency.js.map +1 -0
  9. package/dist/context.d.ts +5 -0
  10. package/dist/context.d.ts.map +1 -1
  11. package/dist/errors.d.ts +29 -1
  12. package/dist/errors.d.ts.map +1 -1
  13. package/dist/errors.js +38 -0
  14. package/dist/errors.js.map +1 -1
  15. package/dist/files.d.ts +15 -1
  16. package/dist/files.d.ts.map +1 -1
  17. package/dist/files.js +55 -14
  18. package/dist/files.js.map +1 -1
  19. package/dist/globals.d.ts +21 -3
  20. package/dist/globals.d.ts.map +1 -1
  21. package/dist/globals.js +240 -31
  22. package/dist/globals.js.map +1 -1
  23. package/dist/handlers.d.ts +16 -9
  24. package/dist/handlers.d.ts.map +1 -1
  25. package/dist/handlers.js +63 -99
  26. package/dist/handlers.js.map +1 -1
  27. package/dist/index.d.ts +6 -4
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +8 -4
  30. package/dist/index.js.map +1 -1
  31. package/dist/localization.d.ts +17 -0
  32. package/dist/localization.d.ts.map +1 -1
  33. package/dist/localization.js +56 -0
  34. package/dist/localization.js.map +1 -1
  35. package/dist/operations.d.ts +89 -0
  36. package/dist/operations.d.ts.map +1 -1
  37. package/dist/operations.js +824 -116
  38. package/dist/operations.js.map +1 -1
  39. package/dist/populate.d.ts +23 -3
  40. package/dist/populate.d.ts.map +1 -1
  41. package/dist/populate.js +40 -8
  42. package/dist/populate.js.map +1 -1
  43. package/dist/read-policy.d.ts +35 -0
  44. package/dist/read-policy.d.ts.map +1 -0
  45. package/dist/read-policy.js +59 -0
  46. package/dist/read-policy.js.map +1 -0
  47. package/dist/relation-integrity.d.ts +90 -11
  48. package/dist/relation-integrity.d.ts.map +1 -1
  49. package/dist/relation-integrity.js +145 -60
  50. package/dist/relation-integrity.js.map +1 -1
  51. package/dist/relation-lifecycle.d.ts +95 -0
  52. package/dist/relation-lifecycle.d.ts.map +1 -0
  53. package/dist/relation-lifecycle.js +424 -0
  54. package/dist/relation-lifecycle.js.map +1 -0
  55. package/dist/runtime.d.ts +26 -2
  56. package/dist/runtime.d.ts.map +1 -1
  57. package/dist/runtime.js +120 -49
  58. package/dist/runtime.js.map +1 -1
  59. package/dist/storage-intents.d.ts +96 -0
  60. package/dist/storage-intents.d.ts.map +1 -0
  61. package/dist/storage-intents.js +217 -0
  62. package/dist/storage-intents.js.map +1 -0
  63. package/dist/system-fields.d.ts +27 -0
  64. package/dist/system-fields.d.ts.map +1 -0
  65. package/dist/system-fields.js +74 -0
  66. package/dist/system-fields.js.map +1 -0
  67. package/dist/typed-api.d.ts +2 -2
  68. package/dist/typed-api.d.ts.map +1 -1
  69. package/dist/versions.d.ts +76 -6
  70. package/dist/versions.d.ts.map +1 -1
  71. package/dist/versions.js +258 -44
  72. package/dist/versions.js.map +1 -1
  73. package/package.json +9 -7
@@ -0,0 +1,74 @@
1
+ import { InvalidInputError } from './errors.js';
2
+ /**
3
+ * Forge-owned document metadata (spec 063): never content, never written through the CMS mutation
4
+ * pipeline by a caller or a hook. `_status` is deliberately absent — on a `drafts: true` collection it
5
+ * is lifecycle input and stays writable. Raw `DatabaseAdapter` writes are outside this boundary.
6
+ */
7
+ export const FORGE_OWNED_KEYS = [
8
+ 'id',
9
+ 'created_at',
10
+ 'updated_at',
11
+ '_storageKey'
12
+ ];
13
+ /** `null` and absent are the same stored value — echoing a missing key back as `null` is a no-op. */
14
+ function sameValue(a, b) {
15
+ return (a ?? null) === (b ?? null);
16
+ }
17
+ /**
18
+ * Returns `data` without the Forge-owned keys that merely echo `stored` (the document as it is — `{}`
19
+ * for a document that does not exist yet), calling `reject(key)` for any other value. An echo is a
20
+ * no-op, so a client round-tripping the document it read keeps working; a changed value is a write
21
+ * attempt and is refused rather than silently stripped.
22
+ */
23
+ function screen(data, stored, reject) {
24
+ let screened = data;
25
+ for (const key of FORGE_OWNED_KEYS) {
26
+ if (!Object.hasOwn(data, key))
27
+ continue;
28
+ if (!sameValue(data[key], stored[key]))
29
+ throw reject(key);
30
+ if (screened === data)
31
+ screened = { ...data };
32
+ delete screened[key];
33
+ }
34
+ return screened;
35
+ }
36
+ function callerRejection(key) {
37
+ return new InvalidInputError(`Field '${key}' is managed by Forge and cannot be written`);
38
+ }
39
+ /**
40
+ * The caller-input screen for an update (or an update-mode preview / an existing global): echoes of
41
+ * `existing` are dropped, any other Forge-owned value is a `400`.
42
+ */
43
+ export function screenUpdateInput(data, existing) {
44
+ return screen(data, existing, callerRejection);
45
+ }
46
+ /**
47
+ * The caller-input screen for a create. A trusted caller (`overrideAccess` not `false`) may choose the
48
+ * new document's `id` — a non-empty string, returned separately so hooks never see or change it; every
49
+ * other Forge-owned key (and an untrusted caller's `id`) is a `400`.
50
+ */
51
+ export function screenCreateInput(data, trusted) {
52
+ const { id, ...rest } = data;
53
+ if (id !== undefined && id !== null) {
54
+ if (!trusted)
55
+ throw callerRejection('id');
56
+ if (typeof id !== 'string' || id === '') {
57
+ throw new InvalidInputError(`Field 'id' must be a non-empty string`);
58
+ }
59
+ }
60
+ return {
61
+ content: screen(rest, {}, callerRejection),
62
+ id: typeof id === 'string' ? id : undefined
63
+ };
64
+ }
65
+ /**
66
+ * Screens what a hook stage returned: hooks may change content and `_status`, never Forge-owned
67
+ * metadata. Echoes of `stored` (e.g. a hook returning `{ ...previousData, ...data }`) are dropped; any
68
+ * other value is a server-code bug, reported as a plain `Error` (500) rather than the caller's `400`.
69
+ */
70
+ export function screenHookOutput(data, stored, stage, target) {
71
+ return screen(data, stored, (key) => new Error(`${stage} hook on '${target}' set the Forge-owned field '${key}'; hooks may only change ` +
72
+ `content fields and _status (spec 063)`));
73
+ }
74
+ //# sourceMappingURL=system-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-fields.js","sourceRoot":"","sources":["../src/system-fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAsB;IACjD,IAAI;IACJ,YAAY;IACZ,YAAY;IACZ,aAAa;CACd,CAAC;AAEF,qGAAqG;AACrG,SAAS,SAAS,CAAC,CAAU,EAAE,CAAU;IACvC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,SAAS,MAAM,CACb,IAA6B,EAC7B,MAA+B,EAC/B,MAA8B;IAE9B,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC;YAAE,SAAS;QACxC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAAE,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,QAAQ,KAAK,IAAI;YAAE,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QAC9C,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,OAAO,IAAI,iBAAiB,CAAC,UAAU,GAAG,6CAA6C,CAAC,CAAC;AAC3F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAA6B,EAC7B,QAAiC;IAEjC,OAAO,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAA6B,EAC7B,OAAgB;IAEhB,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,OAAO;YAAE,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,iBAAiB,CAAC,uCAAuC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,eAAe,CAAC;QAC1C,EAAE,EAAE,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;KAC5C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAA6B,EAC7B,MAA+B,EAC/B,KAAa,EACb,MAAc;IAEd,OAAO,MAAM,CACX,IAAI,EACJ,MAAM,EACN,CAAC,GAAG,EAAE,EAAE,CACN,IAAI,KAAK,CACP,GAAG,KAAK,aAAa,MAAM,gCAAgC,GAAG,2BAA2B;QACvF,uCAAuC,CAC1C,CACJ,CAAC;AACJ,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { CollectionBySlug, CollectionDefinition, CollectionDocument, CollectionInput, CollectionRegistry, CollectionSlug } from '@forge-cms/core';
2
2
  import type { WhereCondition } from '@forge-cms/db';
3
- import type { CountArgs, CreateArgs, DeleteArgs, FindArgs, FindByIDArgs, FindOneArgs, PaginatedDocs, UpdateArgs } from './operations.js';
3
+ import type { BaseOperationArgs, CountArgs, CreateArgs, DeleteArgs, FindArgs, FindByIDArgs, FindOneArgs, PaginatedDocs, UpdateArgs } from './operations.js';
4
4
  /**
5
5
  * The Local API generic arg/result wiring for the typed collection surface (`runtime.ts`). Kept in
6
6
  * one file, isolated from `operations.ts` (untyped, unchanged) and from the method bodies in
@@ -51,7 +51,7 @@ export type TypedUpdateArgs<TCollections extends CollectionRegistry, TSlug exten
51
51
  export type TypedDeleteArgs<TCollections extends CollectionRegistry, TSlug extends CollectionSlug<TCollections>> = Omit<DeleteArgs, 'collection'> & {
52
52
  collection: TSlug;
53
53
  };
54
- export type TypedPreviewArgs<TCollections extends CollectionRegistry, TSlug extends CollectionSlug<TCollections>> = {
54
+ export type TypedPreviewArgs<TCollections extends CollectionRegistry, TSlug extends CollectionSlug<TCollections>> = Omit<BaseOperationArgs, 'collection' | 'depth' | 'locale'> & {
55
55
  collection: TSlug;
56
56
  data: CollectionInput<CollectionBySlug<TCollections, TSlug>>;
57
57
  id?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"typed-api.d.ts","sourceRoot":"","sources":["../src/typed-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typed-api.d.ts","sourceRoot":"","sources":["../src/typed-api.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { CmsUser, CollectionDefinition, Version } from '@forge-cms/core';
2
- import type { DatabaseRecord } from '@forge-cms/db';
2
+ import type { DatabaseAdapter, DatabaseRecord } from '@forge-cms/db';
3
3
  import type { OperationContext } from './context.js';
4
4
  export interface ListVersionsArgs {
5
5
  collection: string;
@@ -30,22 +30,92 @@ export interface CreateVersionArgs {
30
30
  label?: string;
31
31
  }
32
32
  declare function versionsEnabled(collection: CollectionDefinition): boolean;
33
+ /**
34
+ * Whether `versions: { autosave: true }` is set. Nothing in the runtime acts on it today (spec 062 §11):
35
+ * automatic snapshots are always `autosave: false`; only a manual `createVersion({ autosave: true })`
36
+ * sets the flag.
37
+ */
33
38
  declare function autosaveEnabled(collection: CollectionDefinition): boolean;
34
39
  /**
35
40
  * Lists all versions of a document, newest first.
36
41
  */
37
42
  export declare function listVersions(ctx: OperationContext, args: ListVersionsArgs): Promise<Version[]>;
38
43
  /**
39
- * Gets a specific version by id.
44
+ * Gets a specific version by id. `overrideAccess: true` (the default, matching every other Local API
45
+ * method) returns the raw, unfiltered snapshot with no owner-visibility check — used internally by
46
+ * {@link import('./operations.js').restoreVersion}, where the authoritative access gate is the
47
+ * subsequent `update()` call, not this read.
40
48
  */
41
49
  export declare function getVersion(ctx: OperationContext, args: GetVersionArgs): Promise<Version>;
42
50
  /**
43
- * Restores a document to a specific version. Creates a new version with the restored data.
51
+ * Creates a version of a document by hand (trusted Local API only — there is no HTTP route). Stores
52
+ * `data` verbatim: no hooks, no access check, no check that the owner document still exists, and — since
53
+ * nothing guarantees the caller passed full content — the row is not marked as a full snapshot, so a
54
+ * restore of it only applies the fields it contains (spec 062 §7).
55
+ *
56
+ * The version number is `latest + 1`, made safe by the unique `(documentId, versionNumber)` index: when
57
+ * another writer takes that number first, the latest is re-read and the insert retried, at most
58
+ * {@link MAX_MANUAL_VERSION_ATTEMPTS} times in total, then {@link ConcurrentModificationError}. Retrying
59
+ * is safe here — and only here — because nothing but the number changes between attempts: no document
60
+ * write, no consumer code. Automatic snapshots are not created through this function; see
61
+ * `operations.ts`, which writes them in the same atomic batch as the document.
44
62
  */
45
- export declare function restoreVersion(ctx: OperationContext, args: RestoreVersionArgs): Promise<DatabaseRecord>;
63
+ export declare function createVersion(ctx: OperationContext, args: CreateVersionArgs): Promise<Version>;
64
+ export declare function versionsCollectionSlug(collectionSlug: string): string;
46
65
  /**
47
- * Creates a new version of a document. Called automatically on updates when versions are enabled.
66
+ * The internal collection that stores a versioned collection's history. The compound unique
67
+ * `(documentId, versionNumber)` index is the version-identity invariant every automatic write relies
68
+ * on for serialization (spec 062 §1/§3); `snapshotFormat` tells a full snapshot from a pre-062 patch.
48
69
  */
49
- export declare function createVersion(ctx: OperationContext, args: CreateVersionArgs): Promise<Version>;
70
+ export declare function versionCollectionDefinition(collectionSlug: string): CollectionDefinition;
71
+ /** Whether `err` is the version table's `(documentId, versionNumber)` unique index rejecting a write. */
72
+ export declare function isVersionIdentityConflict(err: unknown, collection: CollectionDefinition): boolean;
73
+ /** The highest committed version number of a document, `0` when it has none. */
74
+ export declare function readLatestVersionNumber(database: DatabaseAdapter, collection: CollectionDefinition, documentId: string): Promise<number>;
75
+ /**
76
+ * The restorable content of a document (spec 062 §5): every field the collection declares — `null`
77
+ * when unset, so restoring can clear it — plus `_status` on a drafts collection. Never `id`,
78
+ * timestamps, `_storageKey` or undeclared keys.
79
+ */
80
+ export declare function buildSnapshot(collection: CollectionDefinition, content: Record<string, unknown>): Record<string, unknown>;
81
+ export declare function buildVersionRecord(input: {
82
+ documentId: string;
83
+ versionNumber: number;
84
+ data: Record<string, unknown>;
85
+ user: CmsUser | null;
86
+ /** `true` for automatic snapshots built with {@link buildSnapshot}. */
87
+ full: boolean;
88
+ autosave?: boolean;
89
+ label?: string;
90
+ }): DatabaseRecord;
91
+ /** A version as restore needs it: the public shape plus whether its data is a full snapshot. */
92
+ export interface RestorableVersion {
93
+ version: Version;
94
+ full: boolean;
95
+ }
96
+ /** Raw (trusted, unfiltered) version read for restore — `getVersion` does not expose the format marker. */
97
+ export declare function readVersionForRestore(ctx: OperationContext, collection: CollectionDefinition, versionId: string): Promise<RestorableVersion>;
98
+ /**
99
+ * What a restore sets (spec 062 §6). A full snapshot sets every *currently* declared field — a field the
100
+ * snapshot lacks did not exist then, so it becomes `null` (and fails current validation if it is now
101
+ * required). A legacy/manual snapshot may be a patch, so only the declared fields it contains are set.
102
+ * System metadata and undeclared keys are dropped either way.
103
+ */
104
+ export declare function restoreTarget(collection: CollectionDefinition, restorable: RestorableVersion): Record<string, unknown>;
105
+ /** Only the target fields whose value differs from the current document. */
106
+ export declare function diffAgainst(target: Record<string, unknown>, current: Record<string, unknown>): Record<string, unknown>;
107
+ /** One duplicated version identity found by {@link findDuplicateVersionIdentities}. */
108
+ export interface DuplicateVersionIdentity {
109
+ documentId: string;
110
+ versionNumber: number;
111
+ rows: number;
112
+ }
113
+ /**
114
+ * Scans a version table for `(documentId, versionNumber)` pairs held by more than one row — history the
115
+ * pre-062 read-then-insert race could produce, and which blocks the unique index (spec 062 §8). Reads
116
+ * only; never repairs. Pages through the table in identity order with the ordinary adapter API, so it
117
+ * works on every adapter (an upgrade/diagnostic path, not a hot path).
118
+ */
119
+ export declare function findDuplicateVersionIdentities(database: DatabaseAdapter, versionsCollection: string): Promise<DuplicateVersionIdentity[]>;
50
120
  export { versionsEnabled, autosaveEnabled };
51
121
  //# sourceMappingURL=versions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../src/versions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD,iBAAS,eAAe,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAKlE;AAED,iBAAS,eAAe,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAKlE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,OAAO,EAAE,CAAC,CAiBpB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAW9F;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,CAAC,CA8BzB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,OAAO,CAAC,CAiClB;AAiBD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../src/versions.ts"],"names":[],"mappings":"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"}
package/dist/versions.js CHANGED
@@ -1,4 +1,10 @@
1
- import { NotFoundError } from './errors.js';
1
+ import { defineField } from '@forge-cms/core';
2
+ import { isUniqueConstraintError as isDbUniqueConstraintError } from '@forge-cms/db';
3
+ import { ConcurrentModificationError, NotFoundError } from './errors.js';
4
+ import { documentMatches } from './access.js';
5
+ import { checkAccess, statusConstraint } from './read-policy.js';
6
+ import { filterReadableFields } from './field-access.js';
7
+ import { FORGE_OWNED_KEYS } from './system-fields.js';
2
8
  function getCollectionOrThrow(ctx, slug) {
3
9
  const collection = ctx.getCollection(slug);
4
10
  if (!collection)
@@ -9,12 +15,47 @@ function versionsEnabled(collection) {
9
15
  return (collection.versions === true ||
10
16
  (typeof collection.versions === 'object' && collection.versions !== null));
11
17
  }
18
+ /**
19
+ * Whether `versions: { autosave: true }` is set. Nothing in the runtime acts on it today (spec 062 §11):
20
+ * automatic snapshots are always `autosave: false`; only a manual `createVersion({ autosave: true })`
21
+ * sets the flag.
22
+ */
12
23
  function autosaveEnabled(collection) {
13
24
  if (typeof collection.versions === 'object' && collection.versions !== null) {
14
25
  return collection.versions.autosave === true;
15
26
  }
16
27
  return false;
17
28
  }
29
+ /**
30
+ * A version's history must not tell an untrusted caller anything about its owning document that the
31
+ * document's own read policy wouldn't already tell them (spec 058 §2 / maintainer brief §2). This
32
+ * mirrors `findByID`'s own owner-lookup: collection-level denial surfaces as `403` (matching a normal
33
+ * denied read), a missing owner or a row/draft mismatch surfaces as `404` (never confirms whether a
34
+ * hidden document exists), exactly like `findByID` already behaves for a single document by id.
35
+ *
36
+ * Only called when `overrideAccess === false` — a trusted Local API call skips this entirely, same as
37
+ * every other operation's `overrideAccess: true` default.
38
+ */
39
+ async function assertOwnerReadable(ctx, collection, documentId, user) {
40
+ const owner = await ctx.adapters.database.findById(collection.slug, documentId);
41
+ if (!owner)
42
+ throw new NotFoundError(`Document '${documentId}' not found`);
43
+ const decision = await checkAccess(collection, 'read', {
44
+ user,
45
+ overrideAccess: false,
46
+ id: documentId,
47
+ doc: owner
48
+ });
49
+ if (decision.where && !documentMatches(owner, decision.where)) {
50
+ throw new NotFoundError(`Document '${documentId}' not found`);
51
+ }
52
+ // Matches `findByID`'s own default: a single document known by id is visible to any authenticated
53
+ // caller regardless of draft status; anonymous callers only ever see published documents.
54
+ const status = statusConstraint(collection, undefined, user, false, 'all');
55
+ if (status && !documentMatches(owner, status)) {
56
+ throw new NotFoundError(`Document '${documentId}' not found`);
57
+ }
58
+ }
18
59
  /**
19
60
  * Lists all versions of a document, newest first.
20
61
  */
@@ -23,6 +64,11 @@ export async function listVersions(ctx, args) {
23
64
  if (!versionsEnabled(collection)) {
24
65
  throw new Error(`Collection '${args.collection}' does not have versions enabled`);
25
66
  }
67
+ const user = args.user ?? null;
68
+ const overrideAccess = args.overrideAccess !== false;
69
+ if (!overrideAccess) {
70
+ await assertOwnerReadable(ctx, collection, args.documentId, user);
71
+ }
26
72
  const versionsCollection = `_versions_${args.collection}`;
27
73
  const records = await ctx.adapters.database.findMany({
28
74
  collection: versionsCollection,
@@ -32,10 +78,19 @@ export async function listVersions(ctx, args) {
32
78
  ...(args.limit !== undefined && { limit: args.limit }),
33
79
  ...(args.offset !== undefined && { offset: args.offset })
34
80
  });
35
- return records.map(toVersion);
81
+ const versions = records.map(toVersion);
82
+ if (overrideAccess)
83
+ return versions;
84
+ return Promise.all(versions.map(async (version) => ({
85
+ ...version,
86
+ data: await filterReadableFields(version.data, collection, user)
87
+ })));
36
88
  }
37
89
  /**
38
- * Gets a specific version by id.
90
+ * Gets a specific version by id. `overrideAccess: true` (the default, matching every other Local API
91
+ * method) returns the raw, unfiltered snapshot with no owner-visibility check — used internally by
92
+ * {@link import('./operations.js').restoreVersion}, where the authoritative access gate is the
93
+ * subsequent `update()` call, not this read.
39
94
  */
40
95
  export async function getVersion(ctx, args) {
41
96
  const collection = getCollectionOrThrow(ctx, args.collection);
@@ -46,64 +101,223 @@ export async function getVersion(ctx, args) {
46
101
  const record = await ctx.adapters.database.findById(versionsCollection, args.versionId);
47
102
  if (!record)
48
103
  throw new NotFoundError(`Version '${args.versionId}' not found`);
49
- return toVersion(record);
104
+ const version = toVersion(record);
105
+ const user = args.user ?? null;
106
+ const overrideAccess = args.overrideAccess !== false;
107
+ if (overrideAccess)
108
+ return version;
109
+ await assertOwnerReadable(ctx, collection, version.documentId, user);
110
+ return { ...version, data: await filterReadableFields(version.data, collection, user) };
50
111
  }
112
+ /** Attempts (in total) manual {@link createVersion} makes to allocate a version number under contention. */
113
+ const MAX_MANUAL_VERSION_ATTEMPTS = 3;
51
114
  /**
52
- * Restores a document to a specific version. Creates a new version with the restored data.
115
+ * Creates a version of a document by hand (trusted Local API only — there is no HTTP route). Stores
116
+ * `data` verbatim: no hooks, no access check, no check that the owner document still exists, and — since
117
+ * nothing guarantees the caller passed full content — the row is not marked as a full snapshot, so a
118
+ * restore of it only applies the fields it contains (spec 062 §7).
119
+ *
120
+ * The version number is `latest + 1`, made safe by the unique `(documentId, versionNumber)` index: when
121
+ * another writer takes that number first, the latest is re-read and the insert retried, at most
122
+ * {@link MAX_MANUAL_VERSION_ATTEMPTS} times in total, then {@link ConcurrentModificationError}. Retrying
123
+ * is safe here — and only here — because nothing but the number changes between attempts: no document
124
+ * write, no consumer code. Automatic snapshots are not created through this function; see
125
+ * `operations.ts`, which writes them in the same atomic batch as the document.
53
126
  */
54
- export async function restoreVersion(ctx, args) {
127
+ export async function createVersion(ctx, args) {
55
128
  const collection = getCollectionOrThrow(ctx, args.collection);
56
129
  if (!versionsEnabled(collection)) {
57
130
  throw new Error(`Collection '${args.collection}' does not have versions enabled`);
58
131
  }
59
- const version = await getVersion(ctx, {
60
- collection: args.collection,
61
- versionId: args.versionId,
62
- ...(args.user !== undefined && { user: args.user }),
63
- ...(args.overrideAccess !== undefined && { overrideAccess: args.overrideAccess })
64
- });
65
- // Update the document with the version data
66
- const record = await ctx.adapters.database.update(args.collection, version.documentId, version.data);
67
- // Create a new version for the restore
68
- await createVersion(ctx, {
69
- collection: args.collection,
70
- documentId: version.documentId,
71
- data: version.data,
72
- ...(args.user !== undefined && { user: args.user }),
73
- label: `Restored from version ${version.versionNumber}`
74
- });
75
- return record;
132
+ for (let attempt = 1;; attempt++) {
133
+ const latest = await readLatestVersionNumber(ctx.adapters.database, collection, args.documentId);
134
+ const record = buildVersionRecord({
135
+ documentId: args.documentId,
136
+ versionNumber: latest + 1,
137
+ data: args.data,
138
+ user: args.user ?? null,
139
+ full: false,
140
+ ...(args.autosave !== undefined && { autosave: args.autosave }),
141
+ ...(args.label !== undefined && { label: args.label })
142
+ });
143
+ try {
144
+ const created = await ctx.adapters.database.create(versionsCollectionSlug(collection.slug), record);
145
+ return toVersion(created);
146
+ }
147
+ catch (err) {
148
+ if (!isVersionIdentityConflict(err, collection))
149
+ throw err;
150
+ if (attempt >= MAX_MANUAL_VERSION_ATTEMPTS) {
151
+ throw new ConcurrentModificationError(collection.slug, args.documentId);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ // --- spec 062: version table, full snapshots, restore diff ---------------------------------------
157
+ /** Marker stored in `snapshotFormat` on every automatic snapshot written since spec 062. */
158
+ const FULL_SNAPSHOT = 'full';
159
+ export function versionsCollectionSlug(collectionSlug) {
160
+ return `_versions_${collectionSlug}`;
76
161
  }
77
162
  /**
78
- * Creates a new version of a document. Called automatically on updates when versions are enabled.
163
+ * The internal collection that stores a versioned collection's history. The compound unique
164
+ * `(documentId, versionNumber)` index is the version-identity invariant every automatic write relies
165
+ * on for serialization (spec 062 §1/§3); `snapshotFormat` tells a full snapshot from a pre-062 patch.
79
166
  */
80
- export async function createVersion(ctx, args) {
81
- const collection = getCollectionOrThrow(ctx, args.collection);
82
- if (!versionsEnabled(collection)) {
83
- throw new Error(`Collection '${args.collection}' does not have versions enabled`);
84
- }
85
- const versionsCollection = `_versions_${args.collection}`;
86
- // Get the latest version number for this document
87
- const existingVersions = await ctx.adapters.database.findMany({
88
- collection: versionsCollection,
89
- where: { documentId: args.documentId },
167
+ export function versionCollectionDefinition(collectionSlug) {
168
+ const fields = {
169
+ documentId: defineField.text({ required: true }),
170
+ versionNumber: defineField.number({ required: true }),
171
+ data: defineField.json({ required: true }),
172
+ createdAt: defineField.date({ required: true }),
173
+ createdBy: defineField.text(),
174
+ autosave: defineField.boolean(),
175
+ label: defineField.text(),
176
+ snapshotFormat: defineField.text()
177
+ };
178
+ return {
179
+ slug: versionsCollectionSlug(collectionSlug),
180
+ fields,
181
+ indexes: [{ fields: ['documentId', 'versionNumber'], unique: true }]
182
+ };
183
+ }
184
+ /** Whether `err` is the version table's `(documentId, versionNumber)` unique index rejecting a write. */
185
+ export function isVersionIdentityConflict(err, collection) {
186
+ return (isDbUniqueConstraintError(err) && err.collection === versionsCollectionSlug(collection.slug));
187
+ }
188
+ /** The highest committed version number of a document, `0` when it has none. */
189
+ export async function readLatestVersionNumber(database, collection, documentId) {
190
+ const [latest] = await database.findMany({
191
+ collection: versionsCollectionSlug(collection.slug),
192
+ where: { documentId },
90
193
  sort: 'versionNumber',
91
194
  order: 'desc',
92
195
  limit: 1
93
196
  });
94
- const lastVersionNumber = existingVersions.length > 0 ? (existingVersions[0]?.versionNumber ?? 0) : 0;
95
- const versionRecord = {
197
+ const value = latest?.versionNumber;
198
+ return typeof value === 'number' ? value : 0;
199
+ }
200
+ /**
201
+ * The restorable content of a document (spec 062 §5): every field the collection declares — `null`
202
+ * when unset, so restoring can clear it — plus `_status` on a drafts collection. Never `id`,
203
+ * timestamps, `_storageKey` or undeclared keys.
204
+ */
205
+ export function buildSnapshot(collection, content) {
206
+ const snapshot = {};
207
+ for (const name of Object.keys(collection.fields)) {
208
+ snapshot[name] = content[name] ?? null;
209
+ }
210
+ if (collection.drafts === true && content._status !== undefined) {
211
+ snapshot._status = content._status;
212
+ }
213
+ return snapshot;
214
+ }
215
+ export function buildVersionRecord(input) {
216
+ return {
96
217
  id: crypto.randomUUID(),
97
- documentId: args.documentId,
98
- versionNumber: lastVersionNumber + 1,
99
- data: JSON.stringify(args.data),
218
+ documentId: input.documentId,
219
+ versionNumber: input.versionNumber,
220
+ data: JSON.stringify(input.data),
100
221
  createdAt: new Date().toISOString(),
101
- createdBy: args.user?.id ?? null,
102
- autosave: args.autosave ?? false,
103
- ...(args.label !== undefined && { label: args.label })
222
+ createdBy: input.user?.id ?? null,
223
+ autosave: input.autosave ?? false,
224
+ ...(input.full && { snapshotFormat: FULL_SNAPSHOT }),
225
+ ...(input.label !== undefined && { label: input.label })
104
226
  };
105
- const created = await ctx.adapters.database.create(versionsCollection, versionRecord);
106
- return toVersion(created);
227
+ }
228
+ /** Raw (trusted, unfiltered) version read for restore — `getVersion` does not expose the format marker. */
229
+ export async function readVersionForRestore(ctx, collection, versionId) {
230
+ const record = await ctx.adapters.database.findById(versionsCollectionSlug(collection.slug), versionId);
231
+ if (!record)
232
+ throw new NotFoundError(`Version '${versionId}' not found`);
233
+ return { version: toVersion(record), full: record.snapshotFormat === FULL_SNAPSHOT };
234
+ }
235
+ /**
236
+ * What a restore sets (spec 062 §6). A full snapshot sets every *currently* declared field — a field the
237
+ * snapshot lacks did not exist then, so it becomes `null` (and fails current validation if it is now
238
+ * required). A legacy/manual snapshot may be a patch, so only the declared fields it contains are set.
239
+ * System metadata and undeclared keys are dropped either way.
240
+ */
241
+ export function restoreTarget(collection, restorable) {
242
+ const data = restorable.version.data;
243
+ const target = {};
244
+ for (const name of Object.keys(collection.fields)) {
245
+ if (name in data)
246
+ target[name] = data[name];
247
+ else if (restorable.full)
248
+ target[name] = null;
249
+ }
250
+ if (collection.drafts === true && data._status !== undefined)
251
+ target._status = data._status;
252
+ // Adapter/system metadata is never restorable content (spec 062 §5, spec 063).
253
+ for (const key of FORGE_OWNED_KEYS)
254
+ delete target[key];
255
+ return target;
256
+ }
257
+ /** Only the target fields whose value differs from the current document. */
258
+ export function diffAgainst(target, current) {
259
+ const patch = {};
260
+ for (const [key, value] of Object.entries(target)) {
261
+ if (!sameValue(value, current[key]))
262
+ patch[key] = value;
263
+ }
264
+ return patch;
265
+ }
266
+ function comparable(value) {
267
+ if (value === undefined || value === null)
268
+ return null;
269
+ if (value instanceof Date)
270
+ return value.toISOString();
271
+ if (Array.isArray(value))
272
+ return value.map(comparable);
273
+ if (typeof value === 'object') {
274
+ return Object.fromEntries(Object.keys(value)
275
+ .sort()
276
+ .map((key) => [key, comparable(value[key])]));
277
+ }
278
+ return value;
279
+ }
280
+ function sameValue(a, b) {
281
+ return JSON.stringify(comparable(a)) === JSON.stringify(comparable(b));
282
+ }
283
+ const DUPLICATE_SCAN_PAGE = 500;
284
+ /**
285
+ * Scans a version table for `(documentId, versionNumber)` pairs held by more than one row — history the
286
+ * pre-062 read-then-insert race could produce, and which blocks the unique index (spec 062 §8). Reads
287
+ * only; never repairs. Pages through the table in identity order with the ordinary adapter API, so it
288
+ * works on every adapter (an upgrade/diagnostic path, not a hot path).
289
+ */
290
+ export async function findDuplicateVersionIdentities(database, versionsCollection) {
291
+ const duplicates = [];
292
+ let previous;
293
+ for (let offset = 0;; offset += DUPLICATE_SCAN_PAGE) {
294
+ const page = await database.findMany({
295
+ collection: versionsCollection,
296
+ sort: [
297
+ { field: 'documentId', order: 'asc' },
298
+ { field: 'versionNumber', order: 'asc' },
299
+ { field: 'id', order: 'asc' }
300
+ ],
301
+ limit: DUPLICATE_SCAN_PAGE,
302
+ offset
303
+ });
304
+ for (const row of page) {
305
+ const documentId = String(row.documentId);
306
+ const versionNumber = Number(row.versionNumber);
307
+ if (previous &&
308
+ previous.documentId === documentId &&
309
+ previous.versionNumber === versionNumber) {
310
+ previous.rows++;
311
+ if (previous.rows === 2)
312
+ duplicates.push(previous);
313
+ }
314
+ else {
315
+ previous = { documentId, versionNumber, rows: 1 };
316
+ }
317
+ }
318
+ if (page.length < DUPLICATE_SCAN_PAGE)
319
+ return duplicates;
320
+ }
107
321
  }
108
322
  function toVersion(record) {
109
323
  const data = typeof record.data === 'string' ? JSON.parse(record.data) : record.data;
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","sourceRoot":"","sources":["../src/versions.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAkC5C,SAAS,oBAAoB,CAAC,GAAqB,EAAE,IAAY;IAC/D,MAAM,UAAU,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,aAAa,CAAC,eAAe,IAAI,aAAa,CAAC,CAAC;IAC3E,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,eAAe,CAAC,UAAgC;IACvD,OAAO,CACL,UAAU,CAAC,QAAQ,KAAK,IAAI;QAC5B,CAAC,OAAO,UAAU,CAAC,QAAQ,KAAK,QAAQ,IAAI,UAAU,CAAC,QAAQ,KAAK,IAAI,CAAC,CAC1E,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,UAAgC;IACvD,IAAI,OAAO,UAAU,CAAC,QAAQ,KAAK,QAAQ,IAAI,UAAU,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC5E,OAAO,UAAU,CAAC,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAqB,EACrB,IAAsB;IAEtB,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,UAAU,kCAAkC,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,kBAAkB,GAAG,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACnD,UAAU,EAAE,kBAAkB;QAC9B,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;QACtC,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,MAAM;QACb,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QACtD,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;KAC1D,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAqB,EAAE,IAAoB;IAC1E,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,UAAU,kCAAkC,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,kBAAkB,GAAG,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACxF,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,aAAa,CAAC,YAAY,IAAI,CAAC,SAAS,aAAa,CAAC,CAAC;IAE9E,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAqB,EACrB,IAAwB;IAExB,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,UAAU,kCAAkC,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE;QACpC,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACnD,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;KAClF,CAAC,CAAC;IAEH,4CAA4C;IAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAC/C,IAAI,CAAC,UAAU,EACf,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,IAAI,CACb,CAAC;IAEF,uCAAuC;IACvC,MAAM,aAAa,CAAC,GAAG,EAAE;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACnD,KAAK,EAAE,yBAAyB,OAAO,CAAC,aAAa,EAAE;KACxD,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAqB,EACrB,IAAuB;IAEvB,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,UAAU,kCAAkC,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,kBAAkB,GAAG,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;IAE1D,kDAAkD;IAClD,MAAM,gBAAgB,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5D,UAAU,EAAE,kBAAkB;QAC9B,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;QACtC,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,CAAC;KACT,CAAC,CAAC;IAEH,MAAM,iBAAiB,GACrB,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,aAAwB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1F,MAAM,aAAa,GAAmB;QACpC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,aAAa,EAAE,iBAAiB,GAAG,CAAC;QACpC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI;QAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;QAChC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;KACvD,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;IACtF,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,SAAS,CAAC,MAAsB;IACvC,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAErF,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAY;QACvB,UAAU,EAAE,MAAM,CAAC,UAAoB;QACvC,aAAa,EAAE,MAAM,CAAC,aAAuB;QAC7C,IAAI,EAAE,IAA+B;QACrC,SAAS,EAAE,MAAM,CAAC,SAAmB;QACrC,SAAS,EAAG,MAAM,CAAC,SAAoB,IAAI,IAAI;QAC/C,QAAQ,EAAG,MAAM,CAAC,QAAoB,IAAI,KAAK;QAC/C,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAe,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../src/versions.ts"],"names":[],"mappings":"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"}