@opendatalabs/personal-server-ts-core 1.33.8 → 1.34.1
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/additions/budget.d.ts +28 -0
- package/dist/additions/budget.d.ts.map +1 -0
- package/dist/additions/budget.js +119 -0
- package/dist/additions/budget.js.map +1 -0
- package/dist/additions/durable.d.ts +64 -0
- package/dist/additions/durable.d.ts.map +1 -0
- package/dist/additions/durable.js +591 -0
- package/dist/additions/durable.js.map +1 -0
- package/dist/additions/first-added.d.ts +32 -48
- package/dist/additions/first-added.d.ts.map +1 -1
- package/dist/additions/first-added.js +68 -123
- package/dist/additions/first-added.js.map +1 -1
- package/dist/additions/index.d.ts +3 -0
- package/dist/additions/index.d.ts.map +1 -1
- package/dist/additions/index.js +3 -0
- package/dist/additions/index.js.map +1 -1
- package/dist/additions/ledger-store.js +1 -1
- package/dist/additions/record-rules.d.ts.map +1 -1
- package/dist/additions/record-rules.js +7 -0
- package/dist/additions/record-rules.js.map +1 -1
- package/dist/additions/summary.d.ts +88 -1
- package/dist/additions/summary.d.ts.map +1 -1
- package/dist/additions/summary.js +173 -8
- package/dist/additions/summary.js.map +1 -1
- package/dist/additions/version-inventory.d.ts +80 -0
- package/dist/additions/version-inventory.d.ts.map +1 -0
- package/dist/additions/version-inventory.js +232 -0
- package/dist/additions/version-inventory.js.map +1 -0
- package/dist/api/index.d.ts +70 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +506 -79
- package/dist/api/index.js.map +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/request.d.ts +6 -0
- package/dist/auth/request.d.ts.map +1 -1
- package/dist/auth/request.js +66 -4
- package/dist/auth/request.js.map +1 -1
- package/dist/contracts/data.d.ts +54 -8
- package/dist/contracts/data.d.ts.map +1 -1
- package/dist/contracts/data.js +178 -35
- package/dist/contracts/data.js.map +1 -1
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/derivatives/registration.d.ts +0 -5
- package/dist/derivatives/registration.d.ts.map +1 -1
- package/dist/derivatives/registration.js +2 -1
- package/dist/derivatives/registration.js.map +1 -1
- package/dist/errors/pdpp-catalog.d.ts +36 -0
- package/dist/errors/pdpp-catalog.d.ts.map +1 -0
- package/dist/errors/pdpp-catalog.js +86 -0
- package/dist/errors/pdpp-catalog.js.map +1 -0
- package/dist/grants/index.d.ts +2 -0
- package/dist/grants/index.d.ts.map +1 -1
- package/dist/grants/index.js +4 -0
- package/dist/grants/index.js.map +1 -1
- package/dist/grants/pdpp-binding-store.d.ts +89 -0
- package/dist/grants/pdpp-binding-store.d.ts.map +1 -0
- package/dist/grants/pdpp-binding-store.js +112 -0
- package/dist/grants/pdpp-binding-store.js.map +1 -0
- package/dist/grants/pdpp-binding.d.ts +169 -0
- package/dist/grants/pdpp-binding.d.ts.map +1 -0
- package/dist/grants/pdpp-binding.js +236 -0
- package/dist/grants/pdpp-binding.js.map +1 -0
- package/dist/legacy-projection/bindings.d.ts +28 -1
- package/dist/legacy-projection/bindings.d.ts.map +1 -1
- package/dist/legacy-projection/bindings.js +622 -189
- package/dist/legacy-projection/bindings.js.map +1 -1
- package/dist/legacy-projection/claude-source-record.d.ts +22 -0
- package/dist/legacy-projection/claude-source-record.d.ts.map +1 -0
- package/dist/legacy-projection/claude-source-record.js +360 -0
- package/dist/legacy-projection/claude-source-record.js.map +1 -0
- package/dist/legacy-projection/declared-text.d.ts +41 -0
- package/dist/legacy-projection/declared-text.d.ts.map +1 -0
- package/dist/legacy-projection/declared-text.js +199 -0
- package/dist/legacy-projection/declared-text.js.map +1 -0
- package/dist/legacy-projection/github-browser-bindings.d.ts.map +1 -1
- package/dist/legacy-projection/github-browser-bindings.js +89 -5
- package/dist/legacy-projection/github-browser-bindings.js.map +1 -1
- package/dist/legacy-projection/github-legacy-fields.d.ts +6 -0
- package/dist/legacy-projection/github-legacy-fields.d.ts.map +1 -0
- package/dist/legacy-projection/github-legacy-fields.js +202 -0
- package/dist/legacy-projection/github-legacy-fields.js.map +1 -0
- package/dist/legacy-projection/index.d.ts +5 -1
- package/dist/legacy-projection/index.d.ts.map +1 -1
- package/dist/legacy-projection/index.js +55 -1
- package/dist/legacy-projection/index.js.map +1 -1
- package/dist/legacy-projection/oura-browser-bindings.d.ts.map +1 -1
- package/dist/legacy-projection/oura-browser-bindings.js +43 -41
- package/dist/legacy-projection/oura-browser-bindings.js.map +1 -1
- package/dist/legacy-projection/types.d.ts +38 -2
- package/dist/legacy-projection/types.d.ts.map +1 -1
- package/dist/mcp/read-client.d.ts.map +1 -1
- package/dist/mcp/read-client.js +10 -1
- package/dist/mcp/read-client.js.map +1 -1
- package/dist/mcp/resources.d.ts.map +1 -1
- package/dist/mcp/resources.js +3 -0
- package/dist/mcp/resources.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +11 -2
- package/dist/mcp/tools.js.map +1 -1
- package/dist/pdpp/approval.d.ts +271 -0
- package/dist/pdpp/approval.d.ts.map +1 -0
- package/dist/pdpp/approval.js +467 -0
- package/dist/pdpp/approval.js.map +1 -0
- package/dist/pdpp/client-identity.d.ts +88 -0
- package/dist/pdpp/client-identity.d.ts.map +1 -0
- package/dist/pdpp/client-identity.js +196 -0
- package/dist/pdpp/client-identity.js.map +1 -0
- package/dist/pdpp/client-metadata.d.ts +95 -0
- package/dist/pdpp/client-metadata.d.ts.map +1 -0
- package/dist/pdpp/client-metadata.js +96 -0
- package/dist/pdpp/client-metadata.js.map +1 -0
- package/dist/pdpp/commitments.d.ts +75 -0
- package/dist/pdpp/commitments.d.ts.map +1 -0
- package/dist/pdpp/commitments.js +113 -0
- package/dist/pdpp/commitments.js.map +1 -0
- package/dist/pdpp/declaration.d.ts +118 -0
- package/dist/pdpp/declaration.d.ts.map +1 -0
- package/dist/pdpp/declaration.js +836 -0
- package/dist/pdpp/declaration.js.map +1 -0
- package/dist/pdpp/index.d.ts +37 -0
- package/dist/pdpp/index.d.ts.map +1 -0
- package/dist/pdpp/index.js +23 -0
- package/dist/pdpp/index.js.map +1 -0
- package/dist/pdpp/issuance.d.ts +126 -0
- package/dist/pdpp/issuance.d.ts.map +1 -0
- package/dist/pdpp/issuance.js +180 -0
- package/dist/pdpp/issuance.js.map +1 -0
- package/dist/pdpp/pkce.d.ts +53 -0
- package/dist/pdpp/pkce.d.ts.map +1 -0
- package/dist/pdpp/pkce.js +109 -0
- package/dist/pdpp/pkce.js.map +1 -0
- package/dist/pdpp/redirect.d.ts +60 -0
- package/dist/pdpp/redirect.d.ts.map +1 -0
- package/dist/pdpp/redirect.js +125 -0
- package/dist/pdpp/redirect.js.map +1 -0
- package/dist/pdpp/resolve.d.ts +109 -0
- package/dist/pdpp/resolve.d.ts.map +1 -0
- package/dist/pdpp/resolve.js +393 -0
- package/dist/pdpp/resolve.js.map +1 -0
- package/dist/pdpp/review.d.ts +280 -0
- package/dist/pdpp/review.d.ts.map +1 -0
- package/dist/pdpp/review.js +205 -0
- package/dist/pdpp/review.js.map +1 -0
- package/dist/pdpp/selection.d.ts +50 -0
- package/dist/pdpp/selection.d.ts.map +1 -0
- package/dist/pdpp/selection.js +442 -0
- package/dist/pdpp/selection.js.map +1 -0
- package/dist/pdpp/store.d.ts +228 -0
- package/dist/pdpp/store.d.ts.map +1 -0
- package/dist/pdpp/store.js +542 -0
- package/dist/pdpp/store.js.map +1 -0
- package/dist/pdpp/tokens.d.ts +181 -0
- package/dist/pdpp/tokens.d.ts.map +1 -0
- package/dist/pdpp/tokens.js +419 -0
- package/dist/pdpp/tokens.js.map +1 -0
- package/dist/pdpp/types.d.ts +441 -0
- package/dist/pdpp/types.d.ts.map +1 -0
- package/dist/pdpp/types.js +61 -0
- package/dist/pdpp/types.js.map +1 -0
- package/dist/pdpp-version.d.ts +28 -0
- package/dist/pdpp-version.d.ts.map +1 -0
- package/dist/pdpp-version.js +28 -0
- package/dist/pdpp-version.js.map +1 -0
- package/dist/policy/data-read.d.ts +24 -0
- package/dist/policy/data-read.d.ts.map +1 -1
- package/dist/policy/data-read.js +60 -3
- package/dist/policy/data-read.js.map +1 -1
- package/dist/policy/data-write.d.ts.map +1 -1
- package/dist/policy/data-write.js +3 -0
- package/dist/policy/data-write.js.map +1 -1
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.d.ts.map +1 -1
- package/dist/policy/index.js +1 -0
- package/dist/policy/index.js.map +1 -1
- package/dist/policy/reserved-scopes.d.ts +3 -0
- package/dist/policy/reserved-scopes.d.ts.map +1 -0
- package/dist/policy/reserved-scopes.js +5 -0
- package/dist/policy/reserved-scopes.js.map +1 -0
- package/dist/ports/index.d.ts +63 -0
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/pdpp-auth.d.ts +129 -0
- package/dist/ports/pdpp-auth.d.ts.map +1 -0
- package/dist/ports/pdpp-auth.js +60 -0
- package/dist/ports/pdpp-auth.js.map +1 -0
- package/dist/ports/pdpp-auth.test-utils.d.ts +9 -0
- package/dist/ports/pdpp-auth.test-utils.d.ts.map +1 -0
- package/dist/ports/pdpp-auth.test-utils.js +18 -0
- package/dist/ports/pdpp-auth.test-utils.js.map +1 -0
- package/dist/schemas/server-config.d.ts +44 -0
- package/dist/schemas/server-config.d.ts.map +1 -1
- package/dist/schemas/server-config.js +91 -0
- package/dist/schemas/server-config.js.map +1 -1
- package/dist/signing/request-signer.d.ts +2 -0
- package/dist/signing/request-signer.d.ts.map +1 -1
- package/dist/signing/request-signer.js +1 -0
- package/dist/signing/request-signer.js.map +1 -1
- package/dist/storage/adapters/interface.d.ts +3 -0
- package/dist/storage/adapters/interface.d.ts.map +1 -1
- package/dist/storage/adapters/vana-audience.d.ts +12 -0
- package/dist/storage/adapters/vana-audience.d.ts.map +1 -0
- package/dist/storage/adapters/vana-audience.js +72 -0
- package/dist/storage/adapters/vana-audience.js.map +1 -0
- package/dist/storage/adapters/vana.d.ts +2 -0
- package/dist/storage/adapters/vana.d.ts.map +1 -1
- package/dist/storage/adapters/vana.js +53 -20
- package/dist/storage/adapters/vana.js.map +1 -1
- package/dist/storage/canonical-legacy-projection.d.ts +262 -0
- package/dist/storage/canonical-legacy-projection.d.ts.map +1 -0
- package/dist/storage/canonical-legacy-projection.js +761 -0
- package/dist/storage/canonical-legacy-projection.js.map +1 -0
- package/dist/storage/index/manager.d.ts +29 -2
- package/dist/storage/index/manager.d.ts.map +1 -1
- package/dist/storage/index/schema.d.ts +1 -1
- package/dist/storage/index/schema.js +1 -1
- package/dist/storage/index/types.d.ts +7 -1
- package/dist/storage/index/types.d.ts.map +1 -1
- package/dist/storage/legacy-projection.d.ts +13 -10
- package/dist/storage/legacy-projection.d.ts.map +1 -1
- package/dist/storage/legacy-projection.js +269 -74
- package/dist/storage/legacy-projection.js.map +1 -1
- package/dist/storage/legacy-scope-coverage-exceptions.d.ts +8 -0
- package/dist/storage/legacy-scope-coverage-exceptions.d.ts.map +1 -0
- package/dist/storage/legacy-scope-coverage-exceptions.js +10 -0
- package/dist/storage/legacy-scope-coverage-exceptions.js.map +1 -0
- package/dist/storage/legacy-scope-coverage.d.ts +53 -0
- package/dist/storage/legacy-scope-coverage.d.ts.map +1 -0
- package/dist/storage/legacy-scope-coverage.js +403 -0
- package/dist/storage/legacy-scope-coverage.js.map +1 -0
- package/dist/storage/legacy-scope-entity-keys.d.ts +4 -0
- package/dist/storage/legacy-scope-entity-keys.d.ts.map +1 -0
- package/dist/storage/legacy-scope-entity-keys.js +92 -0
- package/dist/storage/legacy-scope-entity-keys.js.map +1 -0
- package/dist/storage/legacy-scope-view.d.ts +154 -0
- package/dist/storage/legacy-scope-view.d.ts.map +1 -0
- package/dist/storage/legacy-scope-view.js +735 -0
- package/dist/storage/legacy-scope-view.js.map +1 -0
- package/dist/storage/pdpp-records/completion.d.ts +91 -0
- package/dist/storage/pdpp-records/completion.d.ts.map +1 -0
- package/dist/storage/pdpp-records/completion.js +170 -0
- package/dist/storage/pdpp-records/completion.js.map +1 -0
- package/dist/storage/pdpp-records/cursor.d.ts +41 -0
- package/dist/storage/pdpp-records/cursor.d.ts.map +1 -0
- package/dist/storage/pdpp-records/cursor.js +49 -0
- package/dist/storage/pdpp-records/cursor.js.map +1 -0
- package/dist/storage/pdpp-records/declaration-witness.d.ts +58 -0
- package/dist/storage/pdpp-records/declaration-witness.d.ts.map +1 -0
- package/dist/storage/pdpp-records/declaration-witness.js +230 -0
- package/dist/storage/pdpp-records/declaration-witness.js.map +1 -0
- package/dist/storage/pdpp-records/enforcement.d.ts +52 -0
- package/dist/storage/pdpp-records/enforcement.d.ts.map +1 -0
- package/dist/storage/pdpp-records/enforcement.js +116 -0
- package/dist/storage/pdpp-records/enforcement.js.map +1 -0
- package/dist/storage/pdpp-records/index.d.ts +5 -0
- package/dist/storage/pdpp-records/index.d.ts.map +1 -0
- package/dist/storage/pdpp-records/index.js +5 -0
- package/dist/storage/pdpp-records/index.js.map +1 -0
- package/dist/storage/pdpp-records/ingest-plan.d.ts +39 -0
- package/dist/storage/pdpp-records/ingest-plan.d.ts.map +1 -0
- package/dist/storage/pdpp-records/ingest-plan.js +103 -0
- package/dist/storage/pdpp-records/ingest-plan.js.map +1 -0
- package/dist/storage/pdpp-records/interface.d.ts +104 -0
- package/dist/storage/pdpp-records/interface.d.ts.map +1 -0
- package/dist/storage/pdpp-records/interface.js +2 -0
- package/dist/storage/pdpp-records/interface.js.map +1 -0
- package/dist/storage/pdpp-records/memory-store.d.ts +9 -0
- package/dist/storage/pdpp-records/memory-store.d.ts.map +1 -0
- package/dist/storage/pdpp-records/memory-store.js +466 -0
- package/dist/storage/pdpp-records/memory-store.js.map +1 -0
- package/dist/storage/pdpp-records/portable.d.ts +9 -0
- package/dist/storage/pdpp-records/portable.d.ts.map +1 -0
- package/dist/storage/pdpp-records/portable.js +8 -0
- package/dist/storage/pdpp-records/portable.js.map +1 -0
- package/dist/storage/pdpp-records/read-port.d.ts +44 -0
- package/dist/storage/pdpp-records/read-port.d.ts.map +1 -0
- package/dist/storage/pdpp-records/read-port.js +22 -0
- package/dist/storage/pdpp-records/read-port.js.map +1 -0
- package/dist/storage/pdpp-records/record-key.d.ts +52 -0
- package/dist/storage/pdpp-records/record-key.d.ts.map +1 -0
- package/dist/storage/pdpp-records/record-key.js +97 -0
- package/dist/storage/pdpp-records/record-key.js.map +1 -0
- package/dist/storage/pdpp-records/schema.d.ts +41 -0
- package/dist/storage/pdpp-records/schema.d.ts.map +1 -0
- package/dist/storage/pdpp-records/schema.js +153 -0
- package/dist/storage/pdpp-records/schema.js.map +1 -0
- package/dist/storage/pdpp-records/stream-declaration.d.ts +88 -0
- package/dist/storage/pdpp-records/stream-declaration.d.ts.map +1 -0
- package/dist/storage/pdpp-records/stream-declaration.js +57 -0
- package/dist/storage/pdpp-records/stream-declaration.js.map +1 -0
- package/dist/storage/pdpp-records/types.d.ts +138 -0
- package/dist/storage/pdpp-records/types.d.ts.map +1 -0
- package/dist/storage/pdpp-records/types.js +38 -0
- package/dist/storage/pdpp-records/types.js.map +1 -0
- package/dist/sync/data-point-feed.d.ts +3 -0
- package/dist/sync/data-point-feed.d.ts.map +1 -1
- package/dist/sync/data-point-feed.js +17 -1
- package/dist/sync/data-point-feed.js.map +1 -1
- package/dist/sync/delete-data-port.d.ts +2 -0
- package/dist/sync/delete-data-port.d.ts.map +1 -1
- package/dist/sync/delete-data-port.js +1 -1
- package/dist/sync/delete-data-port.js.map +1 -1
- package/dist/sync/engine/sync-manager.d.ts.map +1 -1
- package/dist/sync/engine/sync-manager.js +5 -2
- package/dist/sync/engine/sync-manager.js.map +1 -1
- package/dist/sync/index.d.ts +3 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +4 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/pdpp-import.d.ts +192 -0
- package/dist/sync/pdpp-import.d.ts.map +1 -0
- package/dist/sync/pdpp-import.js +441 -0
- package/dist/sync/pdpp-import.js.map +1 -0
- package/dist/sync/scope-deletions.d.ts +10 -0
- package/dist/sync/scope-deletions.d.ts.map +1 -1
- package/dist/sync/scope-deletions.js +40 -7
- package/dist/sync/scope-deletions.js.map +1 -1
- package/dist/sync/workers/download.d.ts +14 -0
- package/dist/sync/workers/download.d.ts.map +1 -1
- package/dist/sync/workers/download.js +149 -13
- package/dist/sync/workers/download.js.map +1 -1
- package/dist/sync/workers/upload.d.ts +2 -0
- package/dist/sync/workers/upload.d.ts.map +1 -1
- package/dist/sync/workers/upload.js +7 -0
- package/dist/sync/workers/upload.js.map +1 -1
- package/dist/test-utils/memory-storage.d.ts +1 -1
- package/dist/test-utils/memory-storage.d.ts.map +1 -1
- package/dist/test-utils/memory-storage.js +11 -5
- package/dist/test-utils/memory-storage.js.map +1 -1
- package/package.json +54 -4
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PdppRecordStore } from "./interface.js";
|
|
2
|
+
import type { StreamDeclaration, StreamDeclarationRegistry } from "./stream-declaration.js";
|
|
3
|
+
import type { ListRecordsOptions, ListRecordsPage, PdppStoredRecord, StreamListing } from "./types.js";
|
|
4
|
+
/** Async read boundary for synchronous and native-bridge record stores. */
|
|
5
|
+
export interface PdppRecordReadPort {
|
|
6
|
+
/**
|
|
7
|
+
* Reads a keyset page using the synchronous store's cursor contract.
|
|
8
|
+
*
|
|
9
|
+
* In cursor.ts, tokens are base64url JSON containing kind "list", stream,
|
|
10
|
+
* store epoch, order, the last row's sortValue and recordKey, and optionally
|
|
11
|
+
* a write-clock horizon. Clients must treat tokens as opaque: never parse,
|
|
12
|
+
* construct, or re-encode them.
|
|
13
|
+
*
|
|
14
|
+
* The SQLite store (server pdpp-records-sqlite-store.ts) and memory-store.ts
|
|
15
|
+
* order by (emitted_at, record_key), both reversed for descending order.
|
|
16
|
+
* Continuations select tuples strictly beyond the cursor in that direction.
|
|
17
|
+
* There is no instance tiebreaker: equal tuples in different instances can
|
|
18
|
+
* straddle a page boundary and be skipped. Stream/epoch mismatch expires
|
|
19
|
+
* the cursor; an order mismatch is invalid.
|
|
20
|
+
*
|
|
21
|
+
* Each call reads current non-deleted rows; the SQLite horizon only fences
|
|
22
|
+
* instance resets, it does not filter rows. A walk is not a snapshot: a
|
|
23
|
+
* record unchanged for the whole walk is returned exactly once (subject to
|
|
24
|
+
* the instance tie above), inserts beyond the cursor may appear, inserts
|
|
25
|
+
* behind it are missed, an update that changes emitted_at may repeat or
|
|
26
|
+
* skip that record, and deletes remove unread records.
|
|
27
|
+
*
|
|
28
|
+
* Implementations must return byte-identical pages to the synchronous store
|
|
29
|
+
* for the same data, request, and cursor context (including epoch/horizon),
|
|
30
|
+
* preserving row order, projections, cursor bytes, and terminal-page shape.
|
|
31
|
+
*/
|
|
32
|
+
listRecords(stream: string, options: ListRecordsOptions): Promise<ListRecordsPage>;
|
|
33
|
+
getRecord(instance: string, stream: string, recordKey: string): Promise<PdppStoredRecord | undefined>;
|
|
34
|
+
listStreams(instanceIds: string[]): Promise<StreamListing[]>;
|
|
35
|
+
/** Uses the existing registry lookup with its instance/stream order reversed. */
|
|
36
|
+
getStreamDeclaration(stream: string, instance: string): Promise<StreamDeclaration | undefined>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Adapts sync reads without changing their values, cursors, or error objects.
|
|
40
|
+
* Supply the existing registry's forInstance lookup alongside the store reads.
|
|
41
|
+
* Async method bodies turn synchronous throws into rejected promises.
|
|
42
|
+
*/
|
|
43
|
+
export declare function fromSyncRecordStore(store: Pick<PdppRecordStore, "listRecords" | "getRecord" | "listStreams"> & Pick<StreamDeclarationRegistry, "forInstance">): PdppRecordReadPort;
|
|
44
|
+
//# sourceMappingURL=read-port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-port.d.ts","sourceRoot":"","sources":["../../../src/storage/pdpp-records/read-port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EACV,iBAAiB,EACjB,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,WAAW,CACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,eAAe,CAAC,CAAC;IAE5B,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IAEzC,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAE7D,iFAAiF;IACjF,oBAAoB,CAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;CAC3C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,GAAG,WAAW,GAAG,aAAa,CAAC,GACvE,IAAI,CAAC,yBAAyB,EAAE,aAAa,CAAC,GAC/C,kBAAkB,CAepB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapts sync reads without changing their values, cursors, or error objects.
|
|
3
|
+
* Supply the existing registry's forInstance lookup alongside the store reads.
|
|
4
|
+
* Async method bodies turn synchronous throws into rejected promises.
|
|
5
|
+
*/
|
|
6
|
+
export function fromSyncRecordStore(store) {
|
|
7
|
+
return {
|
|
8
|
+
async listRecords(stream, options) {
|
|
9
|
+
return store.listRecords(stream, options);
|
|
10
|
+
},
|
|
11
|
+
async getRecord(instance, stream, recordKey) {
|
|
12
|
+
return store.getRecord(instance, stream, recordKey);
|
|
13
|
+
},
|
|
14
|
+
async listStreams(instanceIds) {
|
|
15
|
+
return store.listStreams(instanceIds);
|
|
16
|
+
},
|
|
17
|
+
async getStreamDeclaration(stream, instance) {
|
|
18
|
+
return store.forInstance(instance, stream);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=read-port.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-port.js","sourceRoot":"","sources":["../../../src/storage/pdpp-records/read-port.ts"],"names":[],"mappings":"AA4DA;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,KACgD;IAEhD,OAAO;QACL,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO;YAC/B,OAAO,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS;YACzC,OAAO,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,WAAW;YAC3B,OAAO,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QACD,KAAK,CAAC,oBAAoB,CAAC,MAAM,EAAE,QAAQ;YACzC,OAAO,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical record-key encoding, spec-core.md Section 4 "Compound key encoding".
|
|
3
|
+
*
|
|
4
|
+
* Single-field primary keys: the key is the string form of that value.
|
|
5
|
+
* Multi-field (compound) primary keys: the key is the minified JSON array of
|
|
6
|
+
* string-converted key values, in the order declared by the SourceDeclaration
|
|
7
|
+
* `primary_key`. Every component is converted to a string before encoding,
|
|
8
|
+
* even when the source value is a number, boolean, or date.
|
|
9
|
+
*
|
|
10
|
+
* Known encoding ambiguity (reviewed, not fixed — INFO, not exploitable):
|
|
11
|
+
* a single-field key whose literal string value happens to look like a
|
|
12
|
+
* minified JSON array, e.g. `'["a","b"]'`, encodes identically to the
|
|
13
|
+
* compound key `["a", "b"]`. Evaluated against how this collides in
|
|
14
|
+
* practice: `PdppRecordStore` keys every row by `(instance, stream,
|
|
15
|
+
* record_key)`, and a stream's declared `primary_key` arity is fixed at
|
|
16
|
+
* declaration time — a stream cannot be single-key for one record and
|
|
17
|
+
* compound-key for another. The ambiguous pair above can therefore only
|
|
18
|
+
* ever arise across two DIFFERENT streams (one single-key, one compound),
|
|
19
|
+
* which are different storage-key namespaces and never compared against
|
|
20
|
+
* each other. It cannot happen within one stream. It also does not widen a
|
|
21
|
+
* grant: `resources` matching is exact string `includes()`, never a prefix
|
|
22
|
+
* or substring match (`enforcement.ts`), so an aliased key string cannot be
|
|
23
|
+
* used to smuggle access to a record the grant didn't name. Not fixed here:
|
|
24
|
+
* changing the wire encoding (e.g. a type-tagged prefix) would need
|
|
25
|
+
* coordination with every existing reader of these keys (list/get/delete/
|
|
26
|
+
* blob routes here, and any client already parsing record IDs), which this
|
|
27
|
+
* lane should not do unilaterally for a risk that is bounded to data
|
|
28
|
+
* integrity within a single (currently impossible) same-stream collision.
|
|
29
|
+
*/
|
|
30
|
+
import type { EnvelopeKey } from "./types.js";
|
|
31
|
+
export declare class RecordKeyError extends Error {
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Encodes an envelope `key` (string or string[]) into the canonical record-key
|
|
35
|
+
* string used for storage, URLs, and `resources[]` grant entries.
|
|
36
|
+
*/
|
|
37
|
+
export declare function encodeRecordKey(key: EnvelopeKey): string;
|
|
38
|
+
/**
|
|
39
|
+
* Computes the canonical record key from a record's `data` object and the
|
|
40
|
+
* stream's declared `primary_key` field list, independent of the envelope's
|
|
41
|
+
* `key` field. Used to validate `key` <-> `data` agreement (spec §4 "Record
|
|
42
|
+
* identity").
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeRecordKeyFromData(data: Record<string, unknown>, primaryKeyFields: string[]): string;
|
|
45
|
+
/**
|
|
46
|
+
* Validates that the envelope `key` field encodes to the same canonical
|
|
47
|
+
* string as the record's `data`, per spec §4 "Record identity": "the values
|
|
48
|
+
* of the `data` fields named by the stream's `primary_key` MUST match the
|
|
49
|
+
* values in the `key` envelope field (in order)."
|
|
50
|
+
*/
|
|
51
|
+
export declare function keyMatchesData(envelopeKey: EnvelopeKey, data: Record<string, unknown>, primaryKeyFields: string[]): boolean;
|
|
52
|
+
//# sourceMappingURL=record-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-key.d.ts","sourceRoot":"","sources":["../../../src/storage/pdpp-records/record-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAoB9C,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CASxD;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,CAkBR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,gBAAgB,EAAE,MAAM,EAAE,GACzB,OAAO,CAIT"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical record-key encoding, spec-core.md Section 4 "Compound key encoding".
|
|
3
|
+
*
|
|
4
|
+
* Single-field primary keys: the key is the string form of that value.
|
|
5
|
+
* Multi-field (compound) primary keys: the key is the minified JSON array of
|
|
6
|
+
* string-converted key values, in the order declared by the SourceDeclaration
|
|
7
|
+
* `primary_key`. Every component is converted to a string before encoding,
|
|
8
|
+
* even when the source value is a number, boolean, or date.
|
|
9
|
+
*
|
|
10
|
+
* Known encoding ambiguity (reviewed, not fixed — INFO, not exploitable):
|
|
11
|
+
* a single-field key whose literal string value happens to look like a
|
|
12
|
+
* minified JSON array, e.g. `'["a","b"]'`, encodes identically to the
|
|
13
|
+
* compound key `["a", "b"]`. Evaluated against how this collides in
|
|
14
|
+
* practice: `PdppRecordStore` keys every row by `(instance, stream,
|
|
15
|
+
* record_key)`, and a stream's declared `primary_key` arity is fixed at
|
|
16
|
+
* declaration time — a stream cannot be single-key for one record and
|
|
17
|
+
* compound-key for another. The ambiguous pair above can therefore only
|
|
18
|
+
* ever arise across two DIFFERENT streams (one single-key, one compound),
|
|
19
|
+
* which are different storage-key namespaces and never compared against
|
|
20
|
+
* each other. It cannot happen within one stream. It also does not widen a
|
|
21
|
+
* grant: `resources` matching is exact string `includes()`, never a prefix
|
|
22
|
+
* or substring match (`enforcement.ts`), so an aliased key string cannot be
|
|
23
|
+
* used to smuggle access to a record the grant didn't name. Not fixed here:
|
|
24
|
+
* changing the wire encoding (e.g. a type-tagged prefix) would need
|
|
25
|
+
* coordination with every existing reader of these keys (list/get/delete/
|
|
26
|
+
* blob routes here, and any client already parsing record IDs), which this
|
|
27
|
+
* lane should not do unilaterally for a risk that is bounded to data
|
|
28
|
+
* integrity within a single (currently impossible) same-stream collision.
|
|
29
|
+
*/
|
|
30
|
+
/** Converts a single primary-key field value to its canonical string form. */
|
|
31
|
+
function toKeyComponentString(value) {
|
|
32
|
+
if (typeof value === "string")
|
|
33
|
+
return value;
|
|
34
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
35
|
+
return String(value);
|
|
36
|
+
}
|
|
37
|
+
if (value instanceof Date)
|
|
38
|
+
return value.toISOString();
|
|
39
|
+
if (value === null || value === undefined) {
|
|
40
|
+
throw new RecordKeyError("Primary key component cannot be null or undefined");
|
|
41
|
+
}
|
|
42
|
+
// Objects/arrays are not valid primary-key component types.
|
|
43
|
+
throw new RecordKeyError(`Primary key component has unsupported type: ${typeof value}`);
|
|
44
|
+
}
|
|
45
|
+
export class RecordKeyError extends Error {
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Encodes an envelope `key` (string or string[]) into the canonical record-key
|
|
49
|
+
* string used for storage, URLs, and `resources[]` grant entries.
|
|
50
|
+
*/
|
|
51
|
+
export function encodeRecordKey(key) {
|
|
52
|
+
if (Array.isArray(key)) {
|
|
53
|
+
if (key.length === 0) {
|
|
54
|
+
throw new RecordKeyError("Compound key array must not be empty");
|
|
55
|
+
}
|
|
56
|
+
const components = key.map(toKeyComponentString);
|
|
57
|
+
return JSON.stringify(components);
|
|
58
|
+
}
|
|
59
|
+
return toKeyComponentString(key);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Computes the canonical record key from a record's `data` object and the
|
|
63
|
+
* stream's declared `primary_key` field list, independent of the envelope's
|
|
64
|
+
* `key` field. Used to validate `key` <-> `data` agreement (spec §4 "Record
|
|
65
|
+
* identity").
|
|
66
|
+
*/
|
|
67
|
+
export function computeRecordKeyFromData(data, primaryKeyFields) {
|
|
68
|
+
if (primaryKeyFields.length === 0) {
|
|
69
|
+
throw new RecordKeyError("Stream has no declared primary_key fields");
|
|
70
|
+
}
|
|
71
|
+
if (primaryKeyFields.length === 1) {
|
|
72
|
+
const [field] = primaryKeyFields;
|
|
73
|
+
if (!(field in data)) {
|
|
74
|
+
throw new RecordKeyError(`data is missing primary key field "${field}"`);
|
|
75
|
+
}
|
|
76
|
+
return toKeyComponentString(data[field]);
|
|
77
|
+
}
|
|
78
|
+
const components = primaryKeyFields.map((field) => {
|
|
79
|
+
if (!(field in data)) {
|
|
80
|
+
throw new RecordKeyError(`data is missing primary key field "${field}"`);
|
|
81
|
+
}
|
|
82
|
+
return toKeyComponentString(data[field]);
|
|
83
|
+
});
|
|
84
|
+
return JSON.stringify(components);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Validates that the envelope `key` field encodes to the same canonical
|
|
88
|
+
* string as the record's `data`, per spec §4 "Record identity": "the values
|
|
89
|
+
* of the `data` fields named by the stream's `primary_key` MUST match the
|
|
90
|
+
* values in the `key` envelope field (in order)."
|
|
91
|
+
*/
|
|
92
|
+
export function keyMatchesData(envelopeKey, data, primaryKeyFields) {
|
|
93
|
+
const fromEnvelope = encodeRecordKey(envelopeKey);
|
|
94
|
+
const fromData = computeRecordKeyFromData(data, primaryKeyFields);
|
|
95
|
+
return fromEnvelope === fromData;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=record-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-key.js","sourceRoot":"","sources":["../../../src/storage/pdpp-records/record-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,8EAA8E;AAC9E,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,IAAI,cAAc,CACtB,mDAAmD,CACpD,CAAC;IACJ,CAAC;IACD,4DAA4D;IAC5D,MAAM,IAAI,cAAc,CACtB,+CAA+C,OAAO,KAAK,EAAE,CAC9D,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAgB;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,cAAc,CAAC,sCAAsC,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAA6B,EAC7B,gBAA0B;IAE1B,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,cAAc,CAAC,2CAA2C,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC;QACjC,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,cAAc,CAAC,sCAAsC,KAAK,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAChD,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,cAAc,CAAC,sCAAsC,KAAK,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAwB,EACxB,IAA6B,EAC7B,gBAA0B;IAE1B,MAAM,YAAY,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAClE,OAAO,YAAY,KAAK,QAAQ,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* P5: validate canonical record `data` against the stream schema of the
|
|
3
|
+
* configured, digest-verified declaration.
|
|
4
|
+
*
|
|
5
|
+
* The schema is the one the registry already serves in §8 stream metadata,
|
|
6
|
+
* resolved by `(instance, stream)`, so writes are checked against the same
|
|
7
|
+
* document the owner consented against. There is no second catalog.
|
|
8
|
+
*
|
|
9
|
+
* §5 fixes the dialect at JSON Schema 2020-12, and `parseDeclaration` refuses
|
|
10
|
+
* any other `$schema` and any remote `$ref` before a declaration is retained.
|
|
11
|
+
* So every schema that reaches this module is compiled as 2020-12. `format`
|
|
12
|
+
* stays an annotation (the 2020-12 default), and an unknown keyword is an
|
|
13
|
+
* annotation too, so validation does not depend on which formats or
|
|
14
|
+
* extensions this build happens to know.
|
|
15
|
+
*/
|
|
16
|
+
import { type ValidateFunction } from "ajv2020/dist/2020.js";
|
|
17
|
+
import type { RecordDataValidator, StreamDeclarationRegistry } from "./portable.js";
|
|
18
|
+
/** Shared 2020-12 compiler for writes and declaration-upgrade witnesses. */
|
|
19
|
+
export declare function compileRecordSchema(schema: Record<string, unknown>): ValidateFunction;
|
|
20
|
+
/**
|
|
21
|
+
* A validator for every stream the registry declares.
|
|
22
|
+
*
|
|
23
|
+
* A stream whose declaration carries no schema is not checked: a
|
|
24
|
+
* private-shape declaration states no shape to check against. A schema this
|
|
25
|
+
* build cannot compile prevents the resource server from mounting, because
|
|
26
|
+
* an unchecked write would store data the declaration may not permit.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createRecordDataValidator(declarations: StreamDeclarationRegistry): RecordDataValidator;
|
|
29
|
+
/**
|
|
30
|
+
* The failing instance path, with every segment the schema does not name
|
|
31
|
+
* replaced by `*`.
|
|
32
|
+
*
|
|
33
|
+
* Under `additionalProperties` or `patternProperties` a path segment is a key
|
|
34
|
+
* taken from the record data, such as an email address, and reasons reach
|
|
35
|
+
* logs. So a segment is shown only when it is a key of `properties` at that
|
|
36
|
+
* point in the schema, or an index into an array schema. Once the walk cannot
|
|
37
|
+
* follow the schema (a combinator, a non-local `$ref`), every later segment
|
|
38
|
+
* is redacted. The instance root is shown as `(root)`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function redactedPath(schema: Record<string, unknown>, instancePath: string, data: unknown): string;
|
|
41
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/storage/pdpp-records/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EACV,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,eAAe,CAAC;AAEvB,4EAA4E;AAC5E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,gBAAgB,CASlB;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,yBAAyB,GACtC,mBAAmB,CAwCrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,OAAO,UA4Cd"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* P5: validate canonical record `data` against the stream schema of the
|
|
3
|
+
* configured, digest-verified declaration.
|
|
4
|
+
*
|
|
5
|
+
* The schema is the one the registry already serves in §8 stream metadata,
|
|
6
|
+
* resolved by `(instance, stream)`, so writes are checked against the same
|
|
7
|
+
* document the owner consented against. There is no second catalog.
|
|
8
|
+
*
|
|
9
|
+
* §5 fixes the dialect at JSON Schema 2020-12, and `parseDeclaration` refuses
|
|
10
|
+
* any other `$schema` and any remote `$ref` before a declaration is retained.
|
|
11
|
+
* So every schema that reaches this module is compiled as 2020-12. `format`
|
|
12
|
+
* stays an annotation (the 2020-12 default), and an unknown keyword is an
|
|
13
|
+
* annotation too, so validation does not depend on which formats or
|
|
14
|
+
* extensions this build happens to know.
|
|
15
|
+
*/
|
|
16
|
+
// The npm alias keeps this dialect separate from legacy validators using Ajv 6.
|
|
17
|
+
import { Ajv2020 } from "ajv2020/dist/2020.js";
|
|
18
|
+
/** Shared 2020-12 compiler for writes and declaration-upgrade witnesses. */
|
|
19
|
+
export function compileRecordSchema(schema) {
|
|
20
|
+
// A fresh Ajv instance allows separate sources to reuse the same `$id`
|
|
21
|
+
// and lets root references (`$ref: "#"`) resolve normally.
|
|
22
|
+
const ajv = new Ajv2020({
|
|
23
|
+
allErrors: false,
|
|
24
|
+
strict: false,
|
|
25
|
+
validateFormats: false,
|
|
26
|
+
});
|
|
27
|
+
return ajv.compile(schema);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A validator for every stream the registry declares.
|
|
31
|
+
*
|
|
32
|
+
* A stream whose declaration carries no schema is not checked: a
|
|
33
|
+
* private-shape declaration states no shape to check against. A schema this
|
|
34
|
+
* build cannot compile prevents the resource server from mounting, because
|
|
35
|
+
* an unchecked write would store data the declaration may not permit.
|
|
36
|
+
*/
|
|
37
|
+
export function createRecordDataValidator(declarations) {
|
|
38
|
+
const compiled = new WeakMap();
|
|
39
|
+
function validatorFor(schema) {
|
|
40
|
+
let validate = compiled.get(schema);
|
|
41
|
+
if (!validate) {
|
|
42
|
+
validate = compileRecordSchema(schema);
|
|
43
|
+
compiled.set(schema, validate);
|
|
44
|
+
}
|
|
45
|
+
return validate;
|
|
46
|
+
}
|
|
47
|
+
// Compilation is a boot-time declaration gate. A declaration is not
|
|
48
|
+
// retained for serving if its advertised schema cannot be enforced.
|
|
49
|
+
for (const declaration of declarations.list()) {
|
|
50
|
+
if (declaration.schema) {
|
|
51
|
+
try {
|
|
52
|
+
validatorFor(declaration.schema);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
throw new Error(`PDPP stream '${declaration.name}' schema cannot compile: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return (stream, instance, data) => {
|
|
60
|
+
const schema = declarations.forInstance(instance, stream)?.schema;
|
|
61
|
+
if (!schema)
|
|
62
|
+
return null;
|
|
63
|
+
const validate = validatorFor(schema);
|
|
64
|
+
if (validate(data))
|
|
65
|
+
return null;
|
|
66
|
+
// `allErrors: false` stops at the first failing keyword, so the reason
|
|
67
|
+
// is the same for the same data and schema on every call.
|
|
68
|
+
const [error] = validate.errors ?? [];
|
|
69
|
+
const path = error
|
|
70
|
+
? redactedPath(schema, error.instancePath, data)
|
|
71
|
+
: "(root)";
|
|
72
|
+
return `schema_violation: ${path} ${error?.message ?? "does not match the declared schema"}`;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The failing instance path, with every segment the schema does not name
|
|
77
|
+
* replaced by `*`.
|
|
78
|
+
*
|
|
79
|
+
* Under `additionalProperties` or `patternProperties` a path segment is a key
|
|
80
|
+
* taken from the record data, such as an email address, and reasons reach
|
|
81
|
+
* logs. So a segment is shown only when it is a key of `properties` at that
|
|
82
|
+
* point in the schema, or an index into an array schema. Once the walk cannot
|
|
83
|
+
* follow the schema (a combinator, a non-local `$ref`), every later segment
|
|
84
|
+
* is redacted. The instance root is shown as `(root)`.
|
|
85
|
+
*/
|
|
86
|
+
export function redactedPath(schema, instancePath, data) {
|
|
87
|
+
if (instancePath === "")
|
|
88
|
+
return "(root)";
|
|
89
|
+
const segments = instancePath
|
|
90
|
+
.slice(1)
|
|
91
|
+
.split("/")
|
|
92
|
+
.map((s) => s.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
93
|
+
let node = schema;
|
|
94
|
+
let value = data;
|
|
95
|
+
const shown = [];
|
|
96
|
+
for (const segment of segments) {
|
|
97
|
+
const current = resolveLocalRef(schema, node);
|
|
98
|
+
const properties = current?.properties;
|
|
99
|
+
const arrayValue = Array.isArray(value) ? value : undefined;
|
|
100
|
+
const numericIndex = /^(0|[1-9][0-9]*)$/.test(segment);
|
|
101
|
+
if (arrayValue && numericIndex) {
|
|
102
|
+
shown.push(segment.replace(/~/g, "~0").replace(/\//g, "~1"));
|
|
103
|
+
const prefix = current?.prefixItems;
|
|
104
|
+
const index = Number(segment);
|
|
105
|
+
node = prefix && index < prefix.length ? prefix[index] : current?.items;
|
|
106
|
+
value = arrayValue[index];
|
|
107
|
+
}
|
|
108
|
+
else if (properties && Object.hasOwn(properties, segment)) {
|
|
109
|
+
shown.push(segment.replace(/~/g, "~0").replace(/\//g, "~1"));
|
|
110
|
+
node = properties[segment];
|
|
111
|
+
value =
|
|
112
|
+
value && typeof value === "object"
|
|
113
|
+
? value[segment]
|
|
114
|
+
: undefined;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
shown.push("*");
|
|
118
|
+
// A data key under `additionalProperties` still has a known schema,
|
|
119
|
+
// unless a `patternProperties` entry could apply instead.
|
|
120
|
+
node =
|
|
121
|
+
current && !("patternProperties" in current)
|
|
122
|
+
? current.additionalProperties
|
|
123
|
+
: undefined;
|
|
124
|
+
value =
|
|
125
|
+
value && typeof value === "object"
|
|
126
|
+
? value[segment]
|
|
127
|
+
: undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return `/${shown.join("/")}`;
|
|
131
|
+
}
|
|
132
|
+
function resolveLocalRef(root, node) {
|
|
133
|
+
for (let depth = 0; depth < 32; depth++) {
|
|
134
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
const ref = node.$ref;
|
|
138
|
+
if (typeof ref !== "string")
|
|
139
|
+
return node;
|
|
140
|
+
if (!ref.startsWith("#"))
|
|
141
|
+
return undefined;
|
|
142
|
+
node = ref
|
|
143
|
+
.slice(1)
|
|
144
|
+
.split("/")
|
|
145
|
+
.filter((s) => s !== "")
|
|
146
|
+
.map((s) => decodeURIComponent(s).replace(/~1/g, "/").replace(/~0/g, "~"))
|
|
147
|
+
.reduce((at, key) => at && typeof at === "object"
|
|
148
|
+
? at[key]
|
|
149
|
+
: undefined, root);
|
|
150
|
+
}
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/storage/pdpp-records/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { StreamSemantics } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The minimal per-stream declaration this lane needs from spec-core.md
|
|
4
|
+
* Section 5 "Source Declaration" — NOT a full Source Declaration model (that
|
|
5
|
+
* is Collection Profile / Lane D territory, out of scope here). This lane
|
|
6
|
+
* only needs enough to validate ingest and serve §8 reads: semantics,
|
|
7
|
+
* primary key, the field used for stable list ordering / incremental sync,
|
|
8
|
+
* and which fields are schema-required (always included in a sparse
|
|
9
|
+
* projection per spec §8 "fields" parameter).
|
|
10
|
+
*/
|
|
11
|
+
export interface StreamDeclaration {
|
|
12
|
+
name: string;
|
|
13
|
+
semantics: StreamSemantics;
|
|
14
|
+
primaryKey: string[];
|
|
15
|
+
cursorField: string;
|
|
16
|
+
/** Fields declared as consent_time_field candidates for time_constraint enforcement. */
|
|
17
|
+
consentTimeField?: string;
|
|
18
|
+
/** Always included in a sparse `fields` projection, even if not requested. */
|
|
19
|
+
requiredFields: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Every top-level member the retained declaration declares for this stream.
|
|
22
|
+
*
|
|
23
|
+
* This is the RS's only authority for what a record of this stream MEANS. A
|
|
24
|
+
* v0.2 grant naming a member that is not here cannot be served: the RS
|
|
25
|
+
* cannot tell whether the member is absent from every record, was renamed,
|
|
26
|
+
* or is something the record happens to carry under that key — and each
|
|
27
|
+
* possible answer discloses a different, unverified thing. That read is
|
|
28
|
+
* refused with `disclosure_unavailable` rather than quietly resolved.
|
|
29
|
+
*
|
|
30
|
+
* Optional because a v0.1 deployment may boot from a declaration shape that
|
|
31
|
+
* carries no field list, and a v0.1 grant has no approved projection to
|
|
32
|
+
* check against. Absent means "no check", never "no fields".
|
|
33
|
+
*/
|
|
34
|
+
declaredFields?: string[];
|
|
35
|
+
/**
|
|
36
|
+
* The stream's JSON Schema from the retained declaration (§5).
|
|
37
|
+
*
|
|
38
|
+
* §8 stream metadata carries this so a client can understand record shape
|
|
39
|
+
* without a second lookup. Optional because a deployment may boot from a
|
|
40
|
+
* private-shape declaration that has no schema to carry; the route then
|
|
41
|
+
* falls back to a field-name projection rather than fabricating one.
|
|
42
|
+
*/
|
|
43
|
+
schema?: Record<string, unknown>;
|
|
44
|
+
/**
|
|
45
|
+
* The stream's declared selection capabilities (§5), e.g.
|
|
46
|
+
* `{ fields: true, resources: false }`. §8 metadata reports what the source
|
|
47
|
+
* supports so a client knows which selections are even expressible.
|
|
48
|
+
*/
|
|
49
|
+
selection?: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Stream declarations, keyed by source and stream name.
|
|
53
|
+
*
|
|
54
|
+
* Stream names are only unique within one source: two sources may both
|
|
55
|
+
* declare `profile` with different keys and schemas. Every lookup that
|
|
56
|
+
* decides how to validate or disclose a record therefore names the source,
|
|
57
|
+
* directly or through the instance that holds the record.
|
|
58
|
+
*/
|
|
59
|
+
export interface StreamDeclarationRegistry {
|
|
60
|
+
/**
|
|
61
|
+
* The declaration for `stream`. With `sourceId`, that source's own
|
|
62
|
+
* declaration. Without it, the declaration only when exactly one source
|
|
63
|
+
* declares the name; `undefined` when none or several do.
|
|
64
|
+
*/
|
|
65
|
+
get(stream: string, sourceId?: string): StreamDeclaration | undefined;
|
|
66
|
+
/** The declaration that governs `stream` records held in `instance`. */
|
|
67
|
+
forInstance(instance: string, stream: string): StreamDeclaration | undefined;
|
|
68
|
+
/** True when at least one source declares `stream`. */
|
|
69
|
+
declares(stream: string): boolean;
|
|
70
|
+
list(): StreamDeclaration[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A registry for a deployment that serves one source, or a test that does
|
|
74
|
+
* not care which source a stream belongs to. Every instance and source
|
|
75
|
+
* resolves to the same declaration for a name.
|
|
76
|
+
*/
|
|
77
|
+
export declare function createStreamDeclarationRegistry(declarations: StreamDeclaration[]): StreamDeclarationRegistry;
|
|
78
|
+
export interface SourceStreamDeclarations {
|
|
79
|
+
sourceId: string;
|
|
80
|
+
/** Optional legacy handle for callers that still use source-derived IDs. */
|
|
81
|
+
instance?: string;
|
|
82
|
+
streams: StreamDeclaration[];
|
|
83
|
+
}
|
|
84
|
+
/** A registry for several sources, keyed by `(source.id, stream)`. */
|
|
85
|
+
export declare function createSourceStreamDeclarationRegistry(sources: SourceStreamDeclarations[]): StreamDeclarationRegistry;
|
|
86
|
+
/** Schema-required fields are always included, even under a sparse `fields` request. */
|
|
87
|
+
export declare function withRequiredFields(requested: string[] | undefined, required: string[]): string[] | undefined;
|
|
88
|
+
//# sourceMappingURL=stream-declaration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-declaration.d.ts","sourceRoot":"","sources":["../../../src/storage/pdpp-records/stream-declaration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,eAAe,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACtE,wEAAwE;IACxE,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;IAC7E,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,IAAI,IAAI,iBAAiB,EAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,YAAY,EAAE,iBAAiB,EAAE,GAChC,yBAAyB,CAQ3B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,sEAAsE;AACtE,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,wBAAwB,EAAE,GAClC,yBAAyB,CAiC3B;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,EAC/B,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,EAAE,GAAG,SAAS,CAKtB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A registry for a deployment that serves one source, or a test that does
|
|
3
|
+
* not care which source a stream belongs to. Every instance and source
|
|
4
|
+
* resolves to the same declaration for a name.
|
|
5
|
+
*/
|
|
6
|
+
export function createStreamDeclarationRegistry(declarations) {
|
|
7
|
+
const byName = new Map(declarations.map((d) => [d.name, d]));
|
|
8
|
+
return {
|
|
9
|
+
get: (stream) => byName.get(stream),
|
|
10
|
+
forInstance: (_instance, stream) => byName.get(stream),
|
|
11
|
+
declares: (stream) => byName.has(stream),
|
|
12
|
+
list: () => declarations,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** A registry for several sources, keyed by `(source.id, stream)`. */
|
|
16
|
+
export function createSourceStreamDeclarationRegistry(sources) {
|
|
17
|
+
const bySource = new Map();
|
|
18
|
+
const sourceByInstance = new Map();
|
|
19
|
+
const declaringSources = new Map();
|
|
20
|
+
for (const source of sources) {
|
|
21
|
+
bySource.set(source.sourceId, new Map(source.streams.map((d) => [d.name, d])));
|
|
22
|
+
if (source.instance !== undefined) {
|
|
23
|
+
sourceByInstance.set(source.instance, source.sourceId);
|
|
24
|
+
}
|
|
25
|
+
for (const stream of source.streams) {
|
|
26
|
+
const list = declaringSources.get(stream.name) ?? [];
|
|
27
|
+
list.push(stream);
|
|
28
|
+
declaringSources.set(stream.name, list);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
get(stream, sourceId) {
|
|
33
|
+
if (sourceId !== undefined)
|
|
34
|
+
return bySource.get(sourceId)?.get(stream);
|
|
35
|
+
const candidates = declaringSources.get(stream) ?? [];
|
|
36
|
+
return candidates.length === 1 ? candidates[0] : undefined;
|
|
37
|
+
},
|
|
38
|
+
forInstance(instance, stream) {
|
|
39
|
+
const sourceId = sourceByInstance.get(instance);
|
|
40
|
+
return sourceId === undefined
|
|
41
|
+
? undefined
|
|
42
|
+
: bySource.get(sourceId)?.get(stream);
|
|
43
|
+
},
|
|
44
|
+
declares: (stream) => declaringSources.has(stream),
|
|
45
|
+
list: () => sources.flatMap((source) => source.streams),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Schema-required fields are always included, even under a sparse `fields` request. */
|
|
49
|
+
export function withRequiredFields(requested, required) {
|
|
50
|
+
if (!requested)
|
|
51
|
+
return undefined;
|
|
52
|
+
const merged = new Set(requested);
|
|
53
|
+
for (const field of required)
|
|
54
|
+
merged.add(field);
|
|
55
|
+
return Array.from(merged);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=stream-declaration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-declaration.js","sourceRoot":"","sources":["../../../src/storage/pdpp-records/stream-declaration.ts"],"names":[],"mappings":"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"}
|