@haverstack/core 0.40.0 → 0.42.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/README.md +121 -59
- package/dist/access.d.ts +34 -36
- package/dist/access.d.ts.map +1 -1
- package/dist/access.js +65 -42
- package/dist/access.js.map +1 -1
- package/dist/{combine.d.ts → adapter/combine.d.ts} +8 -1
- package/dist/adapter/combine.d.ts.map +1 -0
- package/dist/{combine.js → adapter/combine.js} +7 -0
- package/dist/adapter/combine.js.map +1 -0
- package/dist/{adapter-entry.d.ts → adapter/index.d.ts} +6 -5
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/{adapter-entry.js → adapter/index.js} +5 -4
- package/dist/adapter/index.js.map +1 -0
- package/dist/{sort.d.ts → adapter/sort.d.ts} +20 -20
- package/dist/adapter/sort.d.ts.map +1 -0
- package/dist/{sort.js → adapter/sort.js} +37 -27
- package/dist/adapter/sort.js.map +1 -0
- package/dist/associations/identity.d.ts +93 -0
- package/dist/associations/identity.d.ts.map +1 -0
- package/dist/associations/identity.js +198 -0
- package/dist/associations/identity.js.map +1 -0
- package/dist/associations/validation.d.ts +90 -0
- package/dist/associations/validation.d.ts.map +1 -0
- package/dist/associations/validation.js +339 -0
- package/dist/associations/validation.js.map +1 -0
- package/dist/attachment-records.d.ts +48 -0
- package/dist/attachment-records.d.ts.map +1 -0
- package/dist/attachment-records.js +52 -0
- package/dist/attachment-records.js.map +1 -0
- package/dist/collection.d.ts +182 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +407 -0
- package/dist/collection.js.map +1 -0
- package/dist/content-match.d.ts +25 -0
- package/dist/content-match.d.ts.map +1 -0
- package/dist/content-match.js +51 -0
- package/dist/content-match.js.map +1 -0
- package/dist/content-translation.d.ts +42 -0
- package/dist/content-translation.d.ts.map +1 -0
- package/dist/content-translation.js +108 -0
- package/dist/content-translation.js.map +1 -0
- package/dist/did/did.d.ts.map +1 -0
- package/dist/{did.js → did/did.js} +3 -4
- package/dist/did/did.js.map +1 -0
- package/dist/{did-entry.d.ts → did/index.d.ts} +1 -1
- package/dist/did/index.d.ts.map +1 -0
- package/dist/{did-entry.js → did/index.js} +3 -3
- package/dist/did/index.js.map +1 -0
- package/dist/errors.d.ts +36 -63
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +35 -58
- package/dist/errors.js.map +1 -1
- package/dist/grants.d.ts +20 -43
- package/dist/grants.d.ts.map +1 -1
- package/dist/grants.js +71 -134
- package/dist/grants.js.map +1 -1
- package/dist/id.d.ts +13 -31
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +13 -31
- package/dist/id.js.map +1 -1
- package/dist/index.d.ts +14 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +141 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +219 -0
- package/dist/install.js.map +1 -0
- package/dist/merge.d.ts.map +1 -1
- package/dist/merge.js +5 -11
- package/dist/merge.js.map +1 -1
- package/dist/migration-steps.d.ts +102 -0
- package/dist/migration-steps.d.ts.map +1 -0
- package/dist/migration-steps.js +293 -0
- package/dist/migration-steps.js.map +1 -0
- package/dist/query-validation.d.ts +28 -94
- package/dist/query-validation.d.ts.map +1 -1
- package/dist/query-validation.js +156 -336
- package/dist/query-validation.js.map +1 -1
- package/dist/record-changes.d.ts +2 -117
- package/dist/record-changes.d.ts.map +1 -1
- package/dist/record-changes.js +10 -212
- package/dist/record-changes.js.map +1 -1
- package/dist/schema.d.ts +18 -7
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +59 -30
- package/dist/schema.js.map +1 -1
- package/dist/scoped-stack/authority.d.ts +156 -0
- package/dist/scoped-stack/authority.d.ts.map +1 -0
- package/dist/scoped-stack/authority.js +384 -0
- package/dist/scoped-stack/authority.js.map +1 -0
- package/dist/scoped-stack/scoped-stack.d.ts +338 -0
- package/dist/scoped-stack/scoped-stack.d.ts.map +1 -0
- package/dist/scoped-stack/scoped-stack.js +776 -0
- package/dist/scoped-stack/scoped-stack.js.map +1 -0
- package/dist/scoped-stack/subscription.d.ts +55 -0
- package/dist/scoped-stack/subscription.d.ts.map +1 -0
- package/dist/scoped-stack/subscription.js +110 -0
- package/dist/scoped-stack/subscription.js.map +1 -0
- package/dist/stack/attachments.d.ts +24 -0
- package/dist/stack/attachments.d.ts.map +1 -0
- package/dist/stack/attachments.js +113 -0
- package/dist/stack/attachments.js.map +1 -0
- package/dist/{changes.d.ts → stack/changes.d.ts} +29 -65
- package/dist/stack/changes.d.ts.map +1 -0
- package/dist/{changes.js → stack/changes.js} +32 -66
- package/dist/stack/changes.js.map +1 -0
- package/dist/stack/client.d.ts +271 -0
- package/dist/stack/client.d.ts.map +1 -0
- package/dist/stack/client.js +9 -0
- package/dist/stack/client.js.map +1 -0
- package/dist/stack/identity-bindings.d.ts.map +1 -0
- package/dist/{identity-bindings.js → stack/identity-bindings.js} +8 -14
- package/dist/stack/identity-bindings.js.map +1 -0
- package/dist/stack/install-app.d.ts +22 -0
- package/dist/stack/install-app.d.ts.map +1 -0
- package/dist/stack/install-app.js +260 -0
- package/dist/stack/install-app.js.map +1 -0
- package/dist/stack/integrity.d.ts +94 -0
- package/dist/stack/integrity.d.ts.map +1 -0
- package/dist/stack/integrity.js +268 -0
- package/dist/stack/integrity.js.map +1 -0
- package/dist/{limits.d.ts → stack/limits.d.ts} +2 -5
- package/dist/stack/limits.d.ts.map +1 -0
- package/dist/{limits.js → stack/limits.js} +3 -6
- package/dist/stack/limits.js.map +1 -0
- package/dist/stack/migrations.d.ts +59 -0
- package/dist/stack/migrations.d.ts.map +1 -0
- package/dist/stack/migrations.js +141 -0
- package/dist/stack/migrations.js.map +1 -0
- package/dist/{stack-reads.d.ts → stack/reads.d.ts} +33 -6
- package/dist/stack/reads.d.ts.map +1 -0
- package/dist/{stack-reads.js → stack/reads.js} +49 -7
- package/dist/stack/reads.js.map +1 -0
- package/dist/stack/record-id.d.ts +35 -0
- package/dist/stack/record-id.d.ts.map +1 -0
- package/dist/stack/record-id.js +82 -0
- package/dist/stack/record-id.js.map +1 -0
- package/dist/stack/stack.d.ts +438 -0
- package/dist/stack/stack.d.ts.map +1 -0
- package/dist/stack/stack.js +1366 -0
- package/dist/stack/stack.js.map +1 -0
- package/dist/stack/system-types.d.ts +16 -0
- package/dist/stack/system-types.d.ts.map +1 -0
- package/dist/stack/system-types.js +111 -0
- package/dist/stack/system-types.js.map +1 -0
- package/dist/stack/type-grants.d.ts +20 -0
- package/dist/stack/type-grants.d.ts.map +1 -0
- package/dist/stack/type-grants.js +69 -0
- package/dist/stack/type-grants.js.map +1 -0
- package/dist/stack/write-expectation.d.ts +78 -0
- package/dist/stack/write-expectation.d.ts.map +1 -0
- package/dist/stack/write-expectation.js +71 -0
- package/dist/stack/write-expectation.js.map +1 -0
- package/dist/testing.d.ts +21 -26
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +50 -70
- package/dist/testing.js.map +1 -1
- package/dist/type-handle.d.ts +67 -78
- package/dist/type-handle.d.ts.map +1 -1
- package/dist/type-handle.js +44 -111
- package/dist/type-handle.js.map +1 -1
- package/dist/types/adapter.d.ts +223 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/adapter.js +5 -0
- package/dist/types/adapter.js.map +1 -0
- package/dist/types/associations.d.ts +156 -0
- package/dist/types/associations.d.ts.map +1 -0
- package/dist/types/associations.js +13 -0
- package/dist/types/associations.js.map +1 -0
- package/dist/types/capabilities.d.ts +89 -0
- package/dist/types/capabilities.d.ts.map +1 -0
- package/dist/types/capabilities.js +5 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/events.d.ts +155 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +5 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/ids.d.ts +43 -0
- package/dist/types/ids.d.ts.map +1 -0
- package/dist/types/ids.js +5 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +19 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/journal.d.ts +47 -0
- package/dist/types/journal.d.ts.map +1 -0
- package/dist/types/journal.js +5 -0
- package/dist/types/journal.js.map +1 -0
- package/dist/types/query.d.ts +185 -0
- package/dist/types/query.d.ts.map +1 -0
- package/dist/types/query.js +10 -0
- package/dist/types/query.js.map +1 -0
- package/dist/types/records.d.ts +76 -0
- package/dist/types/records.d.ts.map +1 -0
- package/dist/types/records.js +5 -0
- package/dist/types/records.js.map +1 -0
- package/dist/types/schema.d.ts +74 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +5 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/types/system.d.ts +161 -0
- package/dist/types/system.d.ts.map +1 -0
- package/dist/types/system.js +32 -0
- package/dist/types/system.js.map +1 -0
- package/dist/types/tokens.d.ts +39 -0
- package/dist/types/tokens.d.ts.map +1 -0
- package/dist/types/tokens.js +5 -0
- package/dist/types/tokens.js.map +1 -0
- package/dist/validate.d.ts +29 -70
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +65 -97
- package/dist/validate.js.map +1 -1
- package/dist/{attachment-download.d.ts → wire/attachment-download.d.ts} +0 -57
- package/dist/wire/attachment-download.d.ts.map +1 -0
- package/dist/{attachment-download.js → wire/attachment-download.js} +0 -61
- package/dist/wire/attachment-download.js.map +1 -0
- package/dist/{auth.d.ts → wire/auth.d.ts} +5 -8
- package/dist/wire/auth.d.ts.map +1 -0
- package/dist/{auth.js → wire/auth.js} +5 -8
- package/dist/wire/auth.js.map +1 -0
- package/dist/{wire-body.d.ts → wire/body.d.ts} +13 -5
- package/dist/wire/body.d.ts.map +1 -0
- package/dist/{wire-body.js → wire/body.js} +65 -7
- package/dist/wire/body.js.map +1 -0
- package/dist/{wire-entry.d.ts → wire/index.d.ts} +12 -12
- package/dist/wire/index.d.ts.map +1 -0
- package/dist/{wire-entry.js → wire/index.js} +13 -17
- package/dist/wire/index.js.map +1 -0
- package/dist/{wire-record.d.ts → wire/record.d.ts} +10 -22
- package/dist/wire/record.d.ts.map +1 -0
- package/dist/{wire-record.js → wire/record.js} +12 -24
- package/dist/wire/record.js.map +1 -0
- package/dist/{wire-request.d.ts → wire/request.d.ts} +20 -37
- package/dist/wire/request.d.ts.map +1 -0
- package/dist/{wire-request.js → wire/request.js} +79 -54
- package/dist/wire/request.js.map +1 -0
- package/package.json +7 -7
- package/dist/adapter-entry.d.ts.map +0 -1
- package/dist/adapter-entry.js.map +0 -1
- package/dist/attachment-download.d.ts.map +0 -1
- package/dist/attachment-download.js.map +0 -1
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js.map +0 -1
- package/dist/changes.d.ts.map +0 -1
- package/dist/changes.js.map +0 -1
- package/dist/combine.d.ts.map +0 -1
- package/dist/combine.js.map +0 -1
- package/dist/did-entry.d.ts.map +0 -1
- package/dist/did-entry.js.map +0 -1
- package/dist/did.d.ts.map +0 -1
- package/dist/did.js.map +0 -1
- package/dist/identity-bindings.d.ts.map +0 -1
- package/dist/identity-bindings.js.map +0 -1
- package/dist/limits.d.ts.map +0 -1
- package/dist/limits.js.map +0 -1
- package/dist/record-id.d.ts +0 -70
- package/dist/record-id.d.ts.map +0 -1
- package/dist/record-id.js +0 -127
- package/dist/record-id.js.map +0 -1
- package/dist/scoped-stack.d.ts +0 -532
- package/dist/scoped-stack.d.ts.map +0 -1
- package/dist/scoped-stack.js +0 -1219
- package/dist/scoped-stack.js.map +0 -1
- package/dist/sort.d.ts.map +0 -1
- package/dist/sort.js.map +0 -1
- package/dist/stack-reads.d.ts.map +0 -1
- package/dist/stack-reads.js.map +0 -1
- package/dist/stack.d.ts +0 -971
- package/dist/stack.d.ts.map +0 -1
- package/dist/stack.js +0 -2012
- package/dist/stack.js.map +0 -1
- package/dist/types.d.ts +0 -1250
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -49
- package/dist/types.js.map +0 -1
- package/dist/wire-body.d.ts.map +0 -1
- package/dist/wire-body.js.map +0 -1
- package/dist/wire-entry.d.ts.map +0 -1
- package/dist/wire-entry.js.map +0 -1
- package/dist/wire-record.d.ts.map +0 -1
- package/dist/wire-record.js.map +0 -1
- package/dist/wire-request.d.ts.map +0 -1
- package/dist/wire-request.js.map +0 -1
- /package/dist/{did.d.ts → did/did.d.ts} +0 -0
- /package/dist/{identity-bindings.d.ts → stack/identity-bindings.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../../src/stack/integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,11 +13,8 @@
|
|
|
13
13
|
export declare function assertAttachmentSize(byteLength: number, attachmentBytes: number | null): void;
|
|
14
14
|
/**
|
|
15
15
|
* The content half of the same pre-check, on Stack.create() and
|
|
16
|
-
* Stack.mutate().
|
|
17
|
-
*
|
|
18
|
-
* own request-size limit stays authoritative — this just spares an app the
|
|
19
|
-
* round trip and gives it a typed failure instead of a 413 it has to
|
|
20
|
-
* interpret. See docs/spec/wire-format.md § Request size limits.
|
|
16
|
+
* Stack.mutate(). A `null` ceiling — every local adapter's — skips the
|
|
17
|
+
* serialization entirely.
|
|
21
18
|
*/
|
|
22
19
|
export declare function assertContentSize(content: Record<string, unknown>, contentBytes: number | null, what: 'Content' | 'Patch'): void;
|
|
23
20
|
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/stack/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAM7F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,IAAI,EAAE,SAAS,GAAG,OAAO,GACxB,IAAI,CAQN"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* See docs/spec/wire-format.md § Request size limits.
|
|
11
11
|
*/
|
|
12
|
-
import { StackPayloadTooLargeError } from '
|
|
12
|
+
import { StackPayloadTooLargeError } from '../errors.js';
|
|
13
13
|
/** Shared by Stack.putAttachment() and ScopedStack.putAttachment(). */
|
|
14
14
|
export function assertAttachmentSize(byteLength, attachmentBytes) {
|
|
15
15
|
if (attachmentBytes !== null && byteLength > attachmentBytes) {
|
|
@@ -18,11 +18,8 @@ export function assertAttachmentSize(byteLength, attachmentBytes) {
|
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* The content half of the same pre-check, on Stack.create() and
|
|
21
|
-
* Stack.mutate().
|
|
22
|
-
*
|
|
23
|
-
* own request-size limit stays authoritative — this just spares an app the
|
|
24
|
-
* round trip and gives it a typed failure instead of a 413 it has to
|
|
25
|
-
* interpret. See docs/spec/wire-format.md § Request size limits.
|
|
21
|
+
* Stack.mutate(). A `null` ceiling — every local adapter's — skips the
|
|
22
|
+
* serialization entirely.
|
|
26
23
|
*/
|
|
27
24
|
export function assertContentSize(content, contentBytes, what) {
|
|
28
25
|
if (contentBytes === null)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/stack/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,eAA8B;IACrF,IAAI,eAAe,KAAK,IAAI,IAAI,UAAU,GAAG,eAAe,EAAE,CAAC;QAC7D,MAAM,IAAI,yBAAyB,CACjC,eAAe,UAAU,uBAAuB,eAAe,cAAc,CAC9E,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAgC,EAChC,YAA2B,EAC3B,IAAyB;IAEzB,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO;IAClC,MAAM,UAAU,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5E,IAAI,UAAU,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,IAAI,yBAAyB,CACjC,GAAG,IAAI,KAAK,UAAU,uBAAuB,YAAY,cAAc,CACxE,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration registry
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* The migrations a Stack was opened with, and what this app process
|
|
5
|
+
* understands of each type family. Answers two questions for the Stack:
|
|
6
|
+
* which chain carries a record from one TypeId to another (for
|
|
7
|
+
* migrateAll() and a collection's in-memory reads), and how a stored
|
|
8
|
+
* record reads at `presentAt: 'latest'` — never written back. See
|
|
9
|
+
* docs/spec/data-model.md § Type migrations.
|
|
10
|
+
*/
|
|
11
|
+
import type { StackRecord, TypeId } from '../types/index.js';
|
|
12
|
+
import type { Migration } from '../type-handle.js';
|
|
13
|
+
import type { FieldOrigins } from '../migration-steps.js';
|
|
14
|
+
export declare class MigrationRegistry {
|
|
15
|
+
private readonly steps;
|
|
16
|
+
/**
|
|
17
|
+
* Highest version this instance has defineType()'d, per baseId — what
|
|
18
|
+
* this app process understands, as distinct from what exists in shared
|
|
19
|
+
* storage. Used to detect the stale-writer case in presentAtLatest().
|
|
20
|
+
*/
|
|
21
|
+
private readonly maxDefinedVersion;
|
|
22
|
+
/**
|
|
23
|
+
* Refuses anything the walkers below could not follow. Each TypeId has at
|
|
24
|
+
* most one step out, so the graph is a set of chains, and a walk that
|
|
25
|
+
* comes back to a TypeId it already passed is a cycle.
|
|
26
|
+
*/
|
|
27
|
+
constructor(migrations: readonly Migration[]);
|
|
28
|
+
/**
|
|
29
|
+
* Record that this instance has defined `version` of `baseId` — on the
|
|
30
|
+
* idempotent-no-op path too, since presentAtLatest()'s stale-writer
|
|
31
|
+
* detection depends on it.
|
|
32
|
+
*/
|
|
33
|
+
noteDefined(baseId: string, version: number): void;
|
|
34
|
+
/**
|
|
35
|
+
* Find and compose a migration path from one TypeId to another.
|
|
36
|
+
* Returns null if no path exists.
|
|
37
|
+
*/
|
|
38
|
+
path(fromId: TypeId, toId: TypeId): Migration['migrate'] | null;
|
|
39
|
+
/**
|
|
40
|
+
* What each of `toId`'s top-level fields is in terms of `fromId`'s,
|
|
41
|
+
* composed along the path between them. Null when there is no path, or
|
|
42
|
+
* when a step on it was not built by `migration()` and so declares
|
|
43
|
+
* nothing. See docs/spec/data-model.md § Content queries across versions.
|
|
44
|
+
*/
|
|
45
|
+
origins(fromId: TypeId, toId: TypeId): FieldOrigins | null;
|
|
46
|
+
/**
|
|
47
|
+
* Find the latest registered version of a type family.
|
|
48
|
+
* Follows the migration chain from the given typeId to the end.
|
|
49
|
+
*/
|
|
50
|
+
latest(fromId: TypeId): TypeId;
|
|
51
|
+
/**
|
|
52
|
+
* Apply the registered migration chain in memory, for presentAt:
|
|
53
|
+
* 'latest'. Never writes back. Throws StackMigrationError when the
|
|
54
|
+
* record's version can't be reconciled with what this instance has
|
|
55
|
+
* registered — the stale-writer case.
|
|
56
|
+
*/
|
|
57
|
+
presentAtLatest(record: StackRecord): StackRecord;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/stack/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA6B;IAE/D;;;;OAIG;gBACS,UAAU,EAAE,SAAS,SAAS,EAAE;IAiC5C;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAKlD;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,IAAI;IAgB/D;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAY1D;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQ9B;;;;;OAKG;IACH,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;CA2BlD"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration registry
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* The migrations a Stack was opened with, and what this app process
|
|
5
|
+
* understands of each type family. Answers two questions for the Stack:
|
|
6
|
+
* which chain carries a record from one TypeId to another (for
|
|
7
|
+
* migrateAll() and a collection's in-memory reads), and how a stored
|
|
8
|
+
* record reads at `presentAt: 'latest'` — never written back. See
|
|
9
|
+
* docs/spec/data-model.md § Type migrations.
|
|
10
|
+
*/
|
|
11
|
+
import { parseTypeId } from '../schema.js';
|
|
12
|
+
import { StackMigrationError } from '../errors.js';
|
|
13
|
+
import { composeOrigins, originsOf } from '../migration-steps.js';
|
|
14
|
+
export class MigrationRegistry {
|
|
15
|
+
steps = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* Highest version this instance has defineType()'d, per baseId — what
|
|
18
|
+
* this app process understands, as distinct from what exists in shared
|
|
19
|
+
* storage. Used to detect the stale-writer case in presentAtLatest().
|
|
20
|
+
*/
|
|
21
|
+
maxDefinedVersion = new Map();
|
|
22
|
+
/**
|
|
23
|
+
* Refuses anything the walkers below could not follow. Each TypeId has at
|
|
24
|
+
* most one step out, so the graph is a set of chains, and a walk that
|
|
25
|
+
* comes back to a TypeId it already passed is a cycle.
|
|
26
|
+
*/
|
|
27
|
+
constructor(migrations) {
|
|
28
|
+
for (const m of migrations) {
|
|
29
|
+
const from = parseTypeId(m.from);
|
|
30
|
+
const to = parseTypeId(m.to);
|
|
31
|
+
if (!from || !to) {
|
|
32
|
+
throw new StackMigrationError(`Migration "${m.from}" → "${m.to}" must name two versioned TypeIds.`);
|
|
33
|
+
}
|
|
34
|
+
if (from.baseId === to.baseId && to.version <= from.version) {
|
|
35
|
+
throw new StackMigrationError(`Migration "${m.from}" → "${m.to}" must go to a later version of its family.`);
|
|
36
|
+
}
|
|
37
|
+
if (this.steps.has(m.from)) {
|
|
38
|
+
throw new StackMigrationError(`More than one migration from "${m.from}" was passed.`);
|
|
39
|
+
}
|
|
40
|
+
this.steps.set(m.from, m);
|
|
41
|
+
}
|
|
42
|
+
const acyclic = new Set();
|
|
43
|
+
for (const start of this.steps.keys()) {
|
|
44
|
+
const walked = new Set();
|
|
45
|
+
for (let at = start; at && !acyclic.has(at);) {
|
|
46
|
+
if (walked.has(at)) {
|
|
47
|
+
throw new StackMigrationError(`The migrations passed form a cycle through "${at}".`);
|
|
48
|
+
}
|
|
49
|
+
walked.add(at);
|
|
50
|
+
at = this.steps.get(at)?.to;
|
|
51
|
+
}
|
|
52
|
+
for (const id of walked)
|
|
53
|
+
acyclic.add(id);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Record that this instance has defined `version` of `baseId` — on the
|
|
58
|
+
* idempotent-no-op path too, since presentAtLatest()'s stale-writer
|
|
59
|
+
* detection depends on it.
|
|
60
|
+
*/
|
|
61
|
+
noteDefined(baseId, version) {
|
|
62
|
+
const priorMax = this.maxDefinedVersion.get(baseId) ?? 0;
|
|
63
|
+
if (version > priorMax)
|
|
64
|
+
this.maxDefinedVersion.set(baseId, version);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Find and compose a migration path from one TypeId to another.
|
|
68
|
+
* Returns null if no path exists.
|
|
69
|
+
*/
|
|
70
|
+
path(fromId, toId) {
|
|
71
|
+
if (fromId === toId)
|
|
72
|
+
return (content) => content;
|
|
73
|
+
const steps = [];
|
|
74
|
+
let current = fromId;
|
|
75
|
+
while (current !== toId) {
|
|
76
|
+
const step = this.steps.get(current);
|
|
77
|
+
if (!step)
|
|
78
|
+
return null;
|
|
79
|
+
steps.push(step);
|
|
80
|
+
current = step.to;
|
|
81
|
+
}
|
|
82
|
+
return (content) => steps.reduce((c, step) => step.migrate(c), content);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* What each of `toId`'s top-level fields is in terms of `fromId`'s,
|
|
86
|
+
* composed along the path between them. Null when there is no path, or
|
|
87
|
+
* when a step on it was not built by `migration()` and so declares
|
|
88
|
+
* nothing. See docs/spec/data-model.md § Content queries across versions.
|
|
89
|
+
*/
|
|
90
|
+
origins(fromId, toId) {
|
|
91
|
+
let composed = null;
|
|
92
|
+
for (let current = fromId; current !== toId;) {
|
|
93
|
+
const step = this.steps.get(current);
|
|
94
|
+
const origins = step && originsOf(step);
|
|
95
|
+
if (!origins)
|
|
96
|
+
return null;
|
|
97
|
+
composed = composed ? composeOrigins(composed, origins) : origins;
|
|
98
|
+
current = step.to;
|
|
99
|
+
}
|
|
100
|
+
return composed;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Find the latest registered version of a type family.
|
|
104
|
+
* Follows the migration chain from the given typeId to the end.
|
|
105
|
+
*/
|
|
106
|
+
latest(fromId) {
|
|
107
|
+
let current = fromId;
|
|
108
|
+
for (let step = this.steps.get(current); step; step = this.steps.get(current)) {
|
|
109
|
+
current = step.to;
|
|
110
|
+
}
|
|
111
|
+
return current;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Apply the registered migration chain in memory, for presentAt:
|
|
115
|
+
* 'latest'. Never writes back. Throws StackMigrationError when the
|
|
116
|
+
* record's version can't be reconciled with what this instance has
|
|
117
|
+
* registered — the stale-writer case.
|
|
118
|
+
*/
|
|
119
|
+
presentAtLatest(record) {
|
|
120
|
+
const latestId = this.latest(record.typeId);
|
|
121
|
+
if (latestId !== record.typeId) {
|
|
122
|
+
// latest() found this by walking the same migration graph path()
|
|
123
|
+
// walks, from the same starting point, so a path is always
|
|
124
|
+
// resolvable here.
|
|
125
|
+
const migrateFn = this.path(record.typeId, latestId);
|
|
126
|
+
return { ...record, typeId: latestId, content: migrateFn(record.content) };
|
|
127
|
+
}
|
|
128
|
+
const parsed = parseTypeId(record.typeId);
|
|
129
|
+
const knownMax = parsed ? this.maxDefinedVersion.get(parsed.baseId) : undefined;
|
|
130
|
+
if (parsed && knownMax !== undefined && parsed.version !== knownMax) {
|
|
131
|
+
const direction = parsed.version > knownMax
|
|
132
|
+
? `the record is newer than this app instance understands — update the app, or pass it the missing migrations`
|
|
133
|
+
: `no migration passed to Stack.open() bridges the gap`;
|
|
134
|
+
throw new StackMigrationError(`Record "${record.id}" is at "${record.typeId}", but this app instance has defined ` +
|
|
135
|
+
`up to "${parsed.baseId}@${knownMax}": ${direction}. Omit presentAt: "latest" to ` +
|
|
136
|
+
`read the record as stored.`);
|
|
137
|
+
}
|
|
138
|
+
return record;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/stack/migrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
* Canned reads over a stack
|
|
3
3
|
* -------------------------------------------------------
|
|
4
4
|
* The internal call sites that need every match rather than a page —
|
|
5
|
-
* grant checks, attachment cleanup, DID resolution — expressed once.
|
|
6
|
-
*
|
|
5
|
+
* grant checks, attachment cleanup, DID resolution — expressed once. Most
|
|
6
|
+
* take the query function to run against, so the same read serves an
|
|
7
7
|
* unscoped `Stack` and a permission-filtered `ScopedStack` without either
|
|
8
|
-
* knowing which it got
|
|
8
|
+
* knowing which it got; the `_app` and `_install` reads must see past
|
|
9
|
+
* deletion and listing, so they take the unscoped `Stack` itself. Also the
|
|
10
|
+
* page-size bounds both classes' query() applies.
|
|
9
11
|
*
|
|
10
12
|
* None of these is a public API.
|
|
11
13
|
*/
|
|
12
|
-
import type {
|
|
13
|
-
|
|
14
|
+
import type { Stack } from './stack.js';
|
|
15
|
+
import type { EntityId, GrantContent, InstallContent, QueryResult, StackQuery, StackRecord } from '../types/index.js';
|
|
16
|
+
/** The page size query() answers with when the caller names none. */
|
|
14
17
|
export declare const DEFAULT_QUERY_LIMIT = 50;
|
|
18
|
+
/** The largest page query() returns, whatever the caller asks for. */
|
|
15
19
|
export declare const MAX_QUERY_LIMIT = 1000;
|
|
16
20
|
/**
|
|
17
21
|
* Walks `cursor` to exhaustion for the internal call sites that need every
|
|
@@ -35,4 +39,27 @@ export declare function findFirstMatch(run: (query: StackQuery) => Promise<Query
|
|
|
35
39
|
* having query() throw.
|
|
36
40
|
*/
|
|
37
41
|
export declare function lookupEntityByDid(run: (query: StackQuery) => Promise<QueryResult>, did: EntityId, canFilterContent: boolean, includeUnlisted: boolean): Promise<StackRecord | null>;
|
|
38
|
-
|
|
42
|
+
/**
|
|
43
|
+
* The `_app` card claiming `did`, deleted and unlisted included — the
|
|
44
|
+
* binding rules make it single-valued. Takes the unscoped Stack, since no
|
|
45
|
+
* scoped view may read past deletion and listing for everyone.
|
|
46
|
+
* See docs/spec/identity.md § DID bindings.
|
|
47
|
+
*/
|
|
48
|
+
export declare function findAppCardByDid(stack: Stack, did: EntityId): Promise<StackRecord | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Every `_install` Record, deleted and unlisted included — a deleted
|
|
51
|
+
* install keeps its claims. Takes the unscoped Stack, as findAppCardByDid().
|
|
52
|
+
*/
|
|
53
|
+
export declare function loadInstallRecords(stack: Stack): Promise<(StackRecord & {
|
|
54
|
+
content: InstallContent;
|
|
55
|
+
})[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Every `_grant` Record, cursor-walked through an unscoped query: a grant
|
|
58
|
+
* decides who may read, so it can't sit behind a read check. Unlisted ones
|
|
59
|
+
* count, as listing decides nothing about what a grant confers; deleted
|
|
60
|
+
* ones don't, as soft-deleting is revoking. See docs/spec/unlisted.md.
|
|
61
|
+
*/
|
|
62
|
+
export declare function loadGrantRecords(run: (query: StackQuery) => Promise<QueryResult>): Promise<(StackRecord & {
|
|
63
|
+
content: GrantContent;
|
|
64
|
+
})[]>;
|
|
65
|
+
//# sourceMappingURL=reads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reads.d.ts","sourceRoot":"","sources":["../../src/stack/reads.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAGV,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,WAAW,EACX,UAAU,EACV,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAE3B,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,sEAAsE;AACtE,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,EAChD,KAAK,EAAE,UAAU,EACjB,GAAG,SAAgB,GAClB,OAAO,CAAC,WAAW,EAAE,CAAC,CAcxB;AAKD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,EAChD,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EAC9D,GAAG,SAAgB,GAClB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAiBlC;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,EAChD,GAAG,EAAE,QAAQ,EACb,gBAAgB,EAAE,OAAO,EACzB,eAAe,EAAE,OAAO,GACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAc7B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAa9F;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,CAAC,WAAW,GAAG;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC,EAAE,CAAC,CAKxD;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,GAC/C,OAAO,CAAC,CAAC,WAAW,GAAG;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,EAAE,CAAC,CAKtD"}
|
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
* Canned reads over a stack
|
|
3
3
|
* -------------------------------------------------------
|
|
4
4
|
* The internal call sites that need every match rather than a page —
|
|
5
|
-
* grant checks, attachment cleanup, DID resolution — expressed once.
|
|
6
|
-
*
|
|
5
|
+
* grant checks, attachment cleanup, DID resolution — expressed once. Most
|
|
6
|
+
* take the query function to run against, so the same read serves an
|
|
7
7
|
* unscoped `Stack` and a permission-filtered `ScopedStack` without either
|
|
8
|
-
* knowing which it got
|
|
8
|
+
* knowing which it got; the `_app` and `_install` reads must see past
|
|
9
|
+
* deletion and listing, so they take the unscoped `Stack` itself. Also the
|
|
10
|
+
* page-size bounds both classes' query() applies.
|
|
9
11
|
*
|
|
10
12
|
* None of these is a public API.
|
|
11
13
|
*/
|
|
12
|
-
import { StackBadRequestError } from '
|
|
13
|
-
import {
|
|
14
|
-
|
|
14
|
+
import { StackBadRequestError } from '../errors.js';
|
|
15
|
+
import { filtersContent } from '../query-validation.js';
|
|
16
|
+
import { SYSTEM_TYPES } from '../types/index.js';
|
|
17
|
+
/** The page size query() answers with when the caller names none. */
|
|
15
18
|
export const DEFAULT_QUERY_LIMIT = 50;
|
|
19
|
+
/** The largest page query() returns, whatever the caller asks for. */
|
|
16
20
|
export const MAX_QUERY_LIMIT = 1000;
|
|
17
21
|
/**
|
|
18
22
|
* Walks `cursor` to exhaustion for the internal call sites that need every
|
|
@@ -76,4 +80,42 @@ export async function lookupEntityByDid(run, did, canFilterContent, includeUnlis
|
|
|
76
80
|
}, (r) => r.content.did === did);
|
|
77
81
|
return record ?? null;
|
|
78
82
|
}
|
|
79
|
-
|
|
83
|
+
/**
|
|
84
|
+
* The `_app` card claiming `did`, deleted and unlisted included — the
|
|
85
|
+
* binding rules make it single-valued. Takes the unscoped Stack, since no
|
|
86
|
+
* scoped view may read past deletion and listing for everyone.
|
|
87
|
+
* See docs/spec/identity.md § DID bindings.
|
|
88
|
+
*/
|
|
89
|
+
export function findAppCardByDid(stack, did) {
|
|
90
|
+
return findFirstMatch((q) => stack.query(q), {
|
|
91
|
+
filter: {
|
|
92
|
+
baseId: SYSTEM_TYPES.APP,
|
|
93
|
+
includeDeleted: true,
|
|
94
|
+
includeUnlisted: true,
|
|
95
|
+
...(filtersContent(stack.capabilities) && { content: { did } }),
|
|
96
|
+
},
|
|
97
|
+
}, (r) => r.content.did === did);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Every `_install` Record, deleted and unlisted included — a deleted
|
|
101
|
+
* install keeps its claims. Takes the unscoped Stack, as findAppCardByDid().
|
|
102
|
+
*/
|
|
103
|
+
export async function loadInstallRecords(stack) {
|
|
104
|
+
const records = await queryAllPages((q) => stack.query(q), {
|
|
105
|
+
filter: { baseId: SYSTEM_TYPES.INSTALL, includeDeleted: true, includeUnlisted: true },
|
|
106
|
+
});
|
|
107
|
+
return records;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Every `_grant` Record, cursor-walked through an unscoped query: a grant
|
|
111
|
+
* decides who may read, so it can't sit behind a read check. Unlisted ones
|
|
112
|
+
* count, as listing decides nothing about what a grant confers; deleted
|
|
113
|
+
* ones don't, as soft-deleting is revoking. See docs/spec/unlisted.md.
|
|
114
|
+
*/
|
|
115
|
+
export async function loadGrantRecords(run) {
|
|
116
|
+
const records = await queryAllPages(run, {
|
|
117
|
+
filter: { typeId: `${SYSTEM_TYPES.GRANT}@1`, includeUnlisted: true },
|
|
118
|
+
});
|
|
119
|
+
return records;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=reads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reads.js","sourceRoot":"","sources":["../../src/stack/reads.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record ID and clock-field validation
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* The rules a caller-supplied `id`, `parentId`, `createdAt` or `updatedAt`
|
|
5
|
+
* is held to before any of them reaches storage. A client may mint its own
|
|
6
|
+
* id and backdate a record's clock, so both are untrusted input here even
|
|
7
|
+
* when the types say otherwise.
|
|
8
|
+
*
|
|
9
|
+
* See docs/spec/data-model.md § Record IDs.
|
|
10
|
+
*/
|
|
11
|
+
import type { ValidationError } from '../validate.js';
|
|
12
|
+
export declare const DEFAULT_ID_TIMESTAMP_SKEW_MS: number;
|
|
13
|
+
/**
|
|
14
|
+
* Format and reserved-prefix checks for a caller-supplied id, reported
|
|
15
|
+
* under `field` — `parentId` when the id names a destination rather than
|
|
16
|
+
* the record being written. The prefix is asked first so "_config" gets a
|
|
17
|
+
* specific refusal. StackBadRequestError, not StackValidationError: a
|
|
18
|
+
* malformed id never reaches schema validation.
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateRecordId(id: string, field?: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Validity and range check for a backdated `createdAt`/`updatedAt`. An
|
|
23
|
+
* Invalid Date would switch the ordering and skew checks off rather than
|
|
24
|
+
* fail them, and one outside an id's encodable range has no id to agree
|
|
25
|
+
* with. See docs/spec/data-model.md § Backdating on import.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateClockField(value: Date | undefined, path: string): ValidationError[];
|
|
28
|
+
/**
|
|
29
|
+
* Whether an id's embedded timestamp is within `skewMs` of `reference`:
|
|
30
|
+
* the current time for a live scoped create, where it stops a grantee
|
|
31
|
+
* forging a sort position, or an explicit `createdAt`, which the id must
|
|
32
|
+
* agree with. Pass null to disable. See docs/spec/data-model.md § Record IDs.
|
|
33
|
+
*/
|
|
34
|
+
export declare function validateIdTimestampSkew(id: string, toleranceMs: number | null, referenceMs: number, referenceLabel: string): void;
|
|
35
|
+
//# sourceMappingURL=record-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-id.d.ts","sourceRoot":"","sources":["../../src/stack/record-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAOtD,eAAO,MAAM,4BAA4B,QAAsB,CAAC;AAEhE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,SAAO,GAAG,IAAI,CAW/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE,CAuB3F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,IAAI,CAcN"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record ID and clock-field validation
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* The rules a caller-supplied `id`, `parentId`, `createdAt` or `updatedAt`
|
|
5
|
+
* is held to before any of them reaches storage. A client may mint its own
|
|
6
|
+
* id and backdate a record's clock, so both are untrusted input here even
|
|
7
|
+
* when the types say otherwise.
|
|
8
|
+
*
|
|
9
|
+
* See docs/spec/data-model.md § Record IDs.
|
|
10
|
+
*/
|
|
11
|
+
import { isValidIdFormat, idTimestamp, MAX_ID_TIMESTAMP } from '../id.js';
|
|
12
|
+
import { ARGUMENTS_INVALID, StackBadRequestError, StackValidationError } from '../errors.js';
|
|
13
|
+
// -------------------------------------------------------
|
|
14
|
+
// Record ID validation
|
|
15
|
+
// -------------------------------------------------------
|
|
16
|
+
const RESERVED_ID_PREFIX = '_';
|
|
17
|
+
export const DEFAULT_ID_TIMESTAMP_SKEW_MS = 24 * 60 * 60 * 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Format and reserved-prefix checks for a caller-supplied id, reported
|
|
20
|
+
* under `field` — `parentId` when the id names a destination rather than
|
|
21
|
+
* the record being written. The prefix is asked first so "_config" gets a
|
|
22
|
+
* specific refusal. StackBadRequestError, not StackValidationError: a
|
|
23
|
+
* malformed id never reaches schema validation.
|
|
24
|
+
*/
|
|
25
|
+
export function validateRecordId(id, field = 'ID') {
|
|
26
|
+
if (id.startsWith(RESERVED_ID_PREFIX)) {
|
|
27
|
+
throw new StackBadRequestError(`Invalid ${field} "${id}": uses the reserved "${RESERVED_ID_PREFIX}" prefix.`);
|
|
28
|
+
}
|
|
29
|
+
if (!isValidIdFormat(id)) {
|
|
30
|
+
throw new StackBadRequestError(`Invalid ${field} "${id}": expected 12 lowercase Crockford base-32 characters.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Validity and range check for a backdated `createdAt`/`updatedAt`. An
|
|
35
|
+
* Invalid Date would switch the ordering and skew checks off rather than
|
|
36
|
+
* fail them, and one outside an id's encodable range has no id to agree
|
|
37
|
+
* with. See docs/spec/data-model.md § Backdating on import.
|
|
38
|
+
*/
|
|
39
|
+
export function validateClockField(value, path) {
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
return [];
|
|
42
|
+
// Reachable from the wire, where JSON has no Date: a forwarded request
|
|
43
|
+
// body hands over an ISO string, which must be a 400 naming the field
|
|
44
|
+
// rather than a TypeError from the getTime() below.
|
|
45
|
+
if (!(value instanceof Date)) {
|
|
46
|
+
return [{ path, message: `${path} must be a Date.` }];
|
|
47
|
+
}
|
|
48
|
+
const ms = value.getTime();
|
|
49
|
+
if (Number.isNaN(ms)) {
|
|
50
|
+
return [{ path, message: `${path} is not a valid Date.` }];
|
|
51
|
+
}
|
|
52
|
+
if (ms < 0 || ms > MAX_ID_TIMESTAMP) {
|
|
53
|
+
return [
|
|
54
|
+
{
|
|
55
|
+
path,
|
|
56
|
+
message: `${path} is outside the representable range ` +
|
|
57
|
+
`(1970-01-01T00:00:00.000Z…${new Date(MAX_ID_TIMESTAMP).toISOString()}).`,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Whether an id's embedded timestamp is within `skewMs` of `reference`:
|
|
65
|
+
* the current time for a live scoped create, where it stops a grantee
|
|
66
|
+
* forging a sort position, or an explicit `createdAt`, which the id must
|
|
67
|
+
* agree with. Pass null to disable. See docs/spec/data-model.md § Record IDs.
|
|
68
|
+
*/
|
|
69
|
+
export function validateIdTimestampSkew(id, toleranceMs, referenceMs, referenceLabel) {
|
|
70
|
+
if (toleranceMs === null)
|
|
71
|
+
return;
|
|
72
|
+
const skew = Math.abs(referenceMs - idTimestamp(id));
|
|
73
|
+
if (skew > toleranceMs) {
|
|
74
|
+
throw new StackValidationError([
|
|
75
|
+
{
|
|
76
|
+
path: 'id',
|
|
77
|
+
message: `ID "${id}" timestamp disagrees with ${referenceLabel} by more than the allowed clock-skew tolerance (${toleranceMs}ms).`,
|
|
78
|
+
},
|
|
79
|
+
], ARGUMENTS_INVALID);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=record-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-id.js","sourceRoot":"","sources":["../../src/stack/record-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAG7F,0DAA0D;AAC1D,uBAAuB;AACvB,0DAA0D;AAE1D,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAU,EAAE,KAAK,GAAG,IAAI;IACvD,IAAI,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,oBAAoB,CAC5B,WAAW,KAAK,KAAK,EAAE,yBAAyB,kBAAkB,WAAW,CAC9E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,oBAAoB,CAC5B,WAAW,KAAK,KAAK,EAAE,wDAAwD,CAChF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAuB,EAAE,IAAY;IACtE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,uEAAuE;IACvE,sEAAsE;IACtE,oDAAoD;IACpD,IAAI,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,kBAAkB,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,uBAAuB,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,gBAAgB,EAAE,CAAC;QACpC,OAAO;YACL;gBACE,IAAI;gBACJ,OAAO,EACL,GAAG,IAAI,sCAAsC;oBAC7C,6BAA6B,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE,IAAI;aAC5E;SACF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,EAAU,EACV,WAA0B,EAC1B,WAAmB,EACnB,cAAsB;IAEtB,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,IAAI,IAAI,GAAG,WAAW,EAAE,CAAC;QACvB,MAAM,IAAI,oBAAoB,CAC5B;YACE;gBACE,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,OAAO,EAAE,8BAA8B,cAAc,mDAAmD,WAAW,MAAM;aACnI;SACF,EACD,iBAAiB,CAClB,CAAC;IACJ,CAAC;AACH,CAAC"}
|