@opendatalabs/personal-server-ts-core 1.33.8 → 1.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/dist/additions/budget.d.ts +28 -0
  2. package/dist/additions/budget.d.ts.map +1 -0
  3. package/dist/additions/budget.js +119 -0
  4. package/dist/additions/budget.js.map +1 -0
  5. package/dist/additions/durable.d.ts +64 -0
  6. package/dist/additions/durable.d.ts.map +1 -0
  7. package/dist/additions/durable.js +591 -0
  8. package/dist/additions/durable.js.map +1 -0
  9. package/dist/additions/first-added.d.ts +32 -48
  10. package/dist/additions/first-added.d.ts.map +1 -1
  11. package/dist/additions/first-added.js +68 -123
  12. package/dist/additions/first-added.js.map +1 -1
  13. package/dist/additions/index.d.ts +3 -0
  14. package/dist/additions/index.d.ts.map +1 -1
  15. package/dist/additions/index.js +3 -0
  16. package/dist/additions/index.js.map +1 -1
  17. package/dist/additions/ledger-store.js +1 -1
  18. package/dist/additions/record-rules.d.ts.map +1 -1
  19. package/dist/additions/record-rules.js +7 -0
  20. package/dist/additions/record-rules.js.map +1 -1
  21. package/dist/additions/summary.d.ts +88 -1
  22. package/dist/additions/summary.d.ts.map +1 -1
  23. package/dist/additions/summary.js +173 -8
  24. package/dist/additions/summary.js.map +1 -1
  25. package/dist/additions/version-inventory.d.ts +80 -0
  26. package/dist/additions/version-inventory.d.ts.map +1 -0
  27. package/dist/additions/version-inventory.js +232 -0
  28. package/dist/additions/version-inventory.js.map +1 -0
  29. package/dist/api/index.d.ts +70 -2
  30. package/dist/api/index.d.ts.map +1 -1
  31. package/dist/api/index.js +506 -79
  32. package/dist/api/index.js.map +1 -1
  33. package/dist/auth/index.d.ts +1 -1
  34. package/dist/auth/index.d.ts.map +1 -1
  35. package/dist/auth/index.js +1 -1
  36. package/dist/auth/index.js.map +1 -1
  37. package/dist/auth/request.d.ts +6 -0
  38. package/dist/auth/request.d.ts.map +1 -1
  39. package/dist/auth/request.js +66 -4
  40. package/dist/auth/request.js.map +1 -1
  41. package/dist/contracts/data.d.ts +54 -8
  42. package/dist/contracts/data.d.ts.map +1 -1
  43. package/dist/contracts/data.js +178 -35
  44. package/dist/contracts/data.js.map +1 -1
  45. package/dist/contracts/index.d.ts +1 -1
  46. package/dist/contracts/index.d.ts.map +1 -1
  47. package/dist/derivatives/registration.d.ts +0 -5
  48. package/dist/derivatives/registration.d.ts.map +1 -1
  49. package/dist/derivatives/registration.js +2 -1
  50. package/dist/derivatives/registration.js.map +1 -1
  51. package/dist/errors/pdpp-catalog.d.ts +36 -0
  52. package/dist/errors/pdpp-catalog.d.ts.map +1 -0
  53. package/dist/errors/pdpp-catalog.js +86 -0
  54. package/dist/errors/pdpp-catalog.js.map +1 -0
  55. package/dist/grants/index.d.ts +2 -0
  56. package/dist/grants/index.d.ts.map +1 -1
  57. package/dist/grants/index.js +4 -0
  58. package/dist/grants/index.js.map +1 -1
  59. package/dist/grants/pdpp-binding-store.d.ts +89 -0
  60. package/dist/grants/pdpp-binding-store.d.ts.map +1 -0
  61. package/dist/grants/pdpp-binding-store.js +112 -0
  62. package/dist/grants/pdpp-binding-store.js.map +1 -0
  63. package/dist/grants/pdpp-binding.d.ts +169 -0
  64. package/dist/grants/pdpp-binding.d.ts.map +1 -0
  65. package/dist/grants/pdpp-binding.js +236 -0
  66. package/dist/grants/pdpp-binding.js.map +1 -0
  67. package/dist/legacy-projection/bindings.d.ts +28 -1
  68. package/dist/legacy-projection/bindings.d.ts.map +1 -1
  69. package/dist/legacy-projection/bindings.js +622 -189
  70. package/dist/legacy-projection/bindings.js.map +1 -1
  71. package/dist/legacy-projection/claude-source-record.d.ts +22 -0
  72. package/dist/legacy-projection/claude-source-record.d.ts.map +1 -0
  73. package/dist/legacy-projection/claude-source-record.js +360 -0
  74. package/dist/legacy-projection/claude-source-record.js.map +1 -0
  75. package/dist/legacy-projection/declared-text.d.ts +41 -0
  76. package/dist/legacy-projection/declared-text.d.ts.map +1 -0
  77. package/dist/legacy-projection/declared-text.js +199 -0
  78. package/dist/legacy-projection/declared-text.js.map +1 -0
  79. package/dist/legacy-projection/github-browser-bindings.d.ts.map +1 -1
  80. package/dist/legacy-projection/github-browser-bindings.js +89 -5
  81. package/dist/legacy-projection/github-browser-bindings.js.map +1 -1
  82. package/dist/legacy-projection/github-legacy-fields.d.ts +6 -0
  83. package/dist/legacy-projection/github-legacy-fields.d.ts.map +1 -0
  84. package/dist/legacy-projection/github-legacy-fields.js +202 -0
  85. package/dist/legacy-projection/github-legacy-fields.js.map +1 -0
  86. package/dist/legacy-projection/index.d.ts +3 -1
  87. package/dist/legacy-projection/index.d.ts.map +1 -1
  88. package/dist/legacy-projection/index.js +49 -1
  89. package/dist/legacy-projection/index.js.map +1 -1
  90. package/dist/legacy-projection/oura-browser-bindings.d.ts.map +1 -1
  91. package/dist/legacy-projection/oura-browser-bindings.js +43 -41
  92. package/dist/legacy-projection/oura-browser-bindings.js.map +1 -1
  93. package/dist/legacy-projection/types.d.ts +38 -2
  94. package/dist/legacy-projection/types.d.ts.map +1 -1
  95. package/dist/mcp/resources.d.ts.map +1 -1
  96. package/dist/mcp/resources.js +3 -0
  97. package/dist/mcp/resources.js.map +1 -1
  98. package/dist/mcp/tools.d.ts.map +1 -1
  99. package/dist/mcp/tools.js +11 -2
  100. package/dist/mcp/tools.js.map +1 -1
  101. package/dist/pdpp/approval.d.ts +271 -0
  102. package/dist/pdpp/approval.d.ts.map +1 -0
  103. package/dist/pdpp/approval.js +467 -0
  104. package/dist/pdpp/approval.js.map +1 -0
  105. package/dist/pdpp/client-identity.d.ts +88 -0
  106. package/dist/pdpp/client-identity.d.ts.map +1 -0
  107. package/dist/pdpp/client-identity.js +196 -0
  108. package/dist/pdpp/client-identity.js.map +1 -0
  109. package/dist/pdpp/client-metadata.d.ts +95 -0
  110. package/dist/pdpp/client-metadata.d.ts.map +1 -0
  111. package/dist/pdpp/client-metadata.js +96 -0
  112. package/dist/pdpp/client-metadata.js.map +1 -0
  113. package/dist/pdpp/commitments.d.ts +75 -0
  114. package/dist/pdpp/commitments.d.ts.map +1 -0
  115. package/dist/pdpp/commitments.js +113 -0
  116. package/dist/pdpp/commitments.js.map +1 -0
  117. package/dist/pdpp/declaration.d.ts +118 -0
  118. package/dist/pdpp/declaration.d.ts.map +1 -0
  119. package/dist/pdpp/declaration.js +836 -0
  120. package/dist/pdpp/declaration.js.map +1 -0
  121. package/dist/pdpp/index.d.ts +37 -0
  122. package/dist/pdpp/index.d.ts.map +1 -0
  123. package/dist/pdpp/index.js +23 -0
  124. package/dist/pdpp/index.js.map +1 -0
  125. package/dist/pdpp/issuance.d.ts +126 -0
  126. package/dist/pdpp/issuance.d.ts.map +1 -0
  127. package/dist/pdpp/issuance.js +180 -0
  128. package/dist/pdpp/issuance.js.map +1 -0
  129. package/dist/pdpp/pkce.d.ts +53 -0
  130. package/dist/pdpp/pkce.d.ts.map +1 -0
  131. package/dist/pdpp/pkce.js +109 -0
  132. package/dist/pdpp/pkce.js.map +1 -0
  133. package/dist/pdpp/redirect.d.ts +60 -0
  134. package/dist/pdpp/redirect.d.ts.map +1 -0
  135. package/dist/pdpp/redirect.js +125 -0
  136. package/dist/pdpp/redirect.js.map +1 -0
  137. package/dist/pdpp/resolve.d.ts +109 -0
  138. package/dist/pdpp/resolve.d.ts.map +1 -0
  139. package/dist/pdpp/resolve.js +393 -0
  140. package/dist/pdpp/resolve.js.map +1 -0
  141. package/dist/pdpp/review.d.ts +280 -0
  142. package/dist/pdpp/review.d.ts.map +1 -0
  143. package/dist/pdpp/review.js +205 -0
  144. package/dist/pdpp/review.js.map +1 -0
  145. package/dist/pdpp/selection.d.ts +50 -0
  146. package/dist/pdpp/selection.d.ts.map +1 -0
  147. package/dist/pdpp/selection.js +442 -0
  148. package/dist/pdpp/selection.js.map +1 -0
  149. package/dist/pdpp/store.d.ts +228 -0
  150. package/dist/pdpp/store.d.ts.map +1 -0
  151. package/dist/pdpp/store.js +542 -0
  152. package/dist/pdpp/store.js.map +1 -0
  153. package/dist/pdpp/tokens.d.ts +181 -0
  154. package/dist/pdpp/tokens.d.ts.map +1 -0
  155. package/dist/pdpp/tokens.js +419 -0
  156. package/dist/pdpp/tokens.js.map +1 -0
  157. package/dist/pdpp/types.d.ts +441 -0
  158. package/dist/pdpp/types.d.ts.map +1 -0
  159. package/dist/pdpp/types.js +61 -0
  160. package/dist/pdpp/types.js.map +1 -0
  161. package/dist/pdpp-version.d.ts +28 -0
  162. package/dist/pdpp-version.d.ts.map +1 -0
  163. package/dist/pdpp-version.js +28 -0
  164. package/dist/pdpp-version.js.map +1 -0
  165. package/dist/policy/data-read.d.ts +24 -0
  166. package/dist/policy/data-read.d.ts.map +1 -1
  167. package/dist/policy/data-read.js +60 -3
  168. package/dist/policy/data-read.js.map +1 -1
  169. package/dist/policy/data-write.d.ts.map +1 -1
  170. package/dist/policy/data-write.js +3 -0
  171. package/dist/policy/data-write.js.map +1 -1
  172. package/dist/policy/index.d.ts +1 -0
  173. package/dist/policy/index.d.ts.map +1 -1
  174. package/dist/policy/index.js +1 -0
  175. package/dist/policy/index.js.map +1 -1
  176. package/dist/policy/reserved-scopes.d.ts +3 -0
  177. package/dist/policy/reserved-scopes.d.ts.map +1 -0
  178. package/dist/policy/reserved-scopes.js +5 -0
  179. package/dist/policy/reserved-scopes.js.map +1 -0
  180. package/dist/ports/index.d.ts +63 -0
  181. package/dist/ports/index.d.ts.map +1 -1
  182. package/dist/ports/index.js.map +1 -1
  183. package/dist/ports/pdpp-auth.d.ts +129 -0
  184. package/dist/ports/pdpp-auth.d.ts.map +1 -0
  185. package/dist/ports/pdpp-auth.js +60 -0
  186. package/dist/ports/pdpp-auth.js.map +1 -0
  187. package/dist/ports/pdpp-auth.test-utils.d.ts +9 -0
  188. package/dist/ports/pdpp-auth.test-utils.d.ts.map +1 -0
  189. package/dist/ports/pdpp-auth.test-utils.js +18 -0
  190. package/dist/ports/pdpp-auth.test-utils.js.map +1 -0
  191. package/dist/schemas/server-config.d.ts +44 -0
  192. package/dist/schemas/server-config.d.ts.map +1 -1
  193. package/dist/schemas/server-config.js +91 -0
  194. package/dist/schemas/server-config.js.map +1 -1
  195. package/dist/signing/request-signer.d.ts +2 -0
  196. package/dist/signing/request-signer.d.ts.map +1 -1
  197. package/dist/signing/request-signer.js +1 -0
  198. package/dist/signing/request-signer.js.map +1 -1
  199. package/dist/storage/adapters/interface.d.ts +3 -0
  200. package/dist/storage/adapters/interface.d.ts.map +1 -1
  201. package/dist/storage/adapters/vana-audience.d.ts +12 -0
  202. package/dist/storage/adapters/vana-audience.d.ts.map +1 -0
  203. package/dist/storage/adapters/vana-audience.js +72 -0
  204. package/dist/storage/adapters/vana-audience.js.map +1 -0
  205. package/dist/storage/adapters/vana.d.ts +2 -0
  206. package/dist/storage/adapters/vana.d.ts.map +1 -1
  207. package/dist/storage/adapters/vana.js +53 -20
  208. package/dist/storage/adapters/vana.js.map +1 -1
  209. package/dist/storage/canonical-legacy-projection.d.ts +262 -0
  210. package/dist/storage/canonical-legacy-projection.d.ts.map +1 -0
  211. package/dist/storage/canonical-legacy-projection.js +761 -0
  212. package/dist/storage/canonical-legacy-projection.js.map +1 -0
  213. package/dist/storage/index/manager.d.ts +29 -2
  214. package/dist/storage/index/manager.d.ts.map +1 -1
  215. package/dist/storage/index/schema.d.ts +1 -1
  216. package/dist/storage/index/schema.js +1 -1
  217. package/dist/storage/index/types.d.ts +7 -1
  218. package/dist/storage/index/types.d.ts.map +1 -1
  219. package/dist/storage/legacy-projection.d.ts +4 -3
  220. package/dist/storage/legacy-projection.d.ts.map +1 -1
  221. package/dist/storage/legacy-projection.js +145 -42
  222. package/dist/storage/legacy-projection.js.map +1 -1
  223. package/dist/storage/legacy-scope-coverage-exceptions.d.ts +8 -0
  224. package/dist/storage/legacy-scope-coverage-exceptions.d.ts.map +1 -0
  225. package/dist/storage/legacy-scope-coverage-exceptions.js +10 -0
  226. package/dist/storage/legacy-scope-coverage-exceptions.js.map +1 -0
  227. package/dist/storage/legacy-scope-coverage.d.ts +53 -0
  228. package/dist/storage/legacy-scope-coverage.d.ts.map +1 -0
  229. package/dist/storage/legacy-scope-coverage.js +403 -0
  230. package/dist/storage/legacy-scope-coverage.js.map +1 -0
  231. package/dist/storage/legacy-scope-entity-keys.d.ts +4 -0
  232. package/dist/storage/legacy-scope-entity-keys.d.ts.map +1 -0
  233. package/dist/storage/legacy-scope-entity-keys.js +92 -0
  234. package/dist/storage/legacy-scope-entity-keys.js.map +1 -0
  235. package/dist/storage/legacy-scope-view.d.ts +154 -0
  236. package/dist/storage/legacy-scope-view.d.ts.map +1 -0
  237. package/dist/storage/legacy-scope-view.js +735 -0
  238. package/dist/storage/legacy-scope-view.js.map +1 -0
  239. package/dist/storage/pdpp-records/completion.d.ts +91 -0
  240. package/dist/storage/pdpp-records/completion.d.ts.map +1 -0
  241. package/dist/storage/pdpp-records/completion.js +170 -0
  242. package/dist/storage/pdpp-records/completion.js.map +1 -0
  243. package/dist/storage/pdpp-records/cursor.d.ts +41 -0
  244. package/dist/storage/pdpp-records/cursor.d.ts.map +1 -0
  245. package/dist/storage/pdpp-records/cursor.js +49 -0
  246. package/dist/storage/pdpp-records/cursor.js.map +1 -0
  247. package/dist/storage/pdpp-records/declaration-witness.d.ts +58 -0
  248. package/dist/storage/pdpp-records/declaration-witness.d.ts.map +1 -0
  249. package/dist/storage/pdpp-records/declaration-witness.js +230 -0
  250. package/dist/storage/pdpp-records/declaration-witness.js.map +1 -0
  251. package/dist/storage/pdpp-records/enforcement.d.ts +52 -0
  252. package/dist/storage/pdpp-records/enforcement.d.ts.map +1 -0
  253. package/dist/storage/pdpp-records/enforcement.js +116 -0
  254. package/dist/storage/pdpp-records/enforcement.js.map +1 -0
  255. package/dist/storage/pdpp-records/index.d.ts +5 -0
  256. package/dist/storage/pdpp-records/index.d.ts.map +1 -0
  257. package/dist/storage/pdpp-records/index.js +5 -0
  258. package/dist/storage/pdpp-records/index.js.map +1 -0
  259. package/dist/storage/pdpp-records/ingest-plan.d.ts +39 -0
  260. package/dist/storage/pdpp-records/ingest-plan.d.ts.map +1 -0
  261. package/dist/storage/pdpp-records/ingest-plan.js +103 -0
  262. package/dist/storage/pdpp-records/ingest-plan.js.map +1 -0
  263. package/dist/storage/pdpp-records/interface.d.ts +104 -0
  264. package/dist/storage/pdpp-records/interface.d.ts.map +1 -0
  265. package/dist/storage/pdpp-records/interface.js +2 -0
  266. package/dist/storage/pdpp-records/interface.js.map +1 -0
  267. package/dist/storage/pdpp-records/memory-store.d.ts +9 -0
  268. package/dist/storage/pdpp-records/memory-store.d.ts.map +1 -0
  269. package/dist/storage/pdpp-records/memory-store.js +466 -0
  270. package/dist/storage/pdpp-records/memory-store.js.map +1 -0
  271. package/dist/storage/pdpp-records/portable.d.ts +9 -0
  272. package/dist/storage/pdpp-records/portable.d.ts.map +1 -0
  273. package/dist/storage/pdpp-records/portable.js +8 -0
  274. package/dist/storage/pdpp-records/portable.js.map +1 -0
  275. package/dist/storage/pdpp-records/read-port.d.ts +44 -0
  276. package/dist/storage/pdpp-records/read-port.d.ts.map +1 -0
  277. package/dist/storage/pdpp-records/read-port.js +22 -0
  278. package/dist/storage/pdpp-records/read-port.js.map +1 -0
  279. package/dist/storage/pdpp-records/record-key.d.ts +52 -0
  280. package/dist/storage/pdpp-records/record-key.d.ts.map +1 -0
  281. package/dist/storage/pdpp-records/record-key.js +97 -0
  282. package/dist/storage/pdpp-records/record-key.js.map +1 -0
  283. package/dist/storage/pdpp-records/schema.d.ts +41 -0
  284. package/dist/storage/pdpp-records/schema.d.ts.map +1 -0
  285. package/dist/storage/pdpp-records/schema.js +153 -0
  286. package/dist/storage/pdpp-records/schema.js.map +1 -0
  287. package/dist/storage/pdpp-records/stream-declaration.d.ts +88 -0
  288. package/dist/storage/pdpp-records/stream-declaration.d.ts.map +1 -0
  289. package/dist/storage/pdpp-records/stream-declaration.js +57 -0
  290. package/dist/storage/pdpp-records/stream-declaration.js.map +1 -0
  291. package/dist/storage/pdpp-records/types.d.ts +138 -0
  292. package/dist/storage/pdpp-records/types.d.ts.map +1 -0
  293. package/dist/storage/pdpp-records/types.js +38 -0
  294. package/dist/storage/pdpp-records/types.js.map +1 -0
  295. package/dist/sync/data-point-feed.d.ts +3 -0
  296. package/dist/sync/data-point-feed.d.ts.map +1 -1
  297. package/dist/sync/data-point-feed.js +17 -1
  298. package/dist/sync/data-point-feed.js.map +1 -1
  299. package/dist/sync/delete-data-port.d.ts +2 -0
  300. package/dist/sync/delete-data-port.d.ts.map +1 -1
  301. package/dist/sync/delete-data-port.js +1 -1
  302. package/dist/sync/delete-data-port.js.map +1 -1
  303. package/dist/sync/engine/sync-manager.d.ts.map +1 -1
  304. package/dist/sync/engine/sync-manager.js +5 -2
  305. package/dist/sync/engine/sync-manager.js.map +1 -1
  306. package/dist/sync/index.d.ts +3 -1
  307. package/dist/sync/index.d.ts.map +1 -1
  308. package/dist/sync/index.js +4 -0
  309. package/dist/sync/index.js.map +1 -1
  310. package/dist/sync/pdpp-import.d.ts +192 -0
  311. package/dist/sync/pdpp-import.d.ts.map +1 -0
  312. package/dist/sync/pdpp-import.js +441 -0
  313. package/dist/sync/pdpp-import.js.map +1 -0
  314. package/dist/sync/scope-deletions.d.ts +10 -0
  315. package/dist/sync/scope-deletions.d.ts.map +1 -1
  316. package/dist/sync/scope-deletions.js +40 -7
  317. package/dist/sync/scope-deletions.js.map +1 -1
  318. package/dist/sync/workers/download.d.ts +14 -0
  319. package/dist/sync/workers/download.d.ts.map +1 -1
  320. package/dist/sync/workers/download.js +149 -13
  321. package/dist/sync/workers/download.js.map +1 -1
  322. package/dist/sync/workers/upload.d.ts +2 -0
  323. package/dist/sync/workers/upload.d.ts.map +1 -1
  324. package/dist/sync/workers/upload.js +7 -0
  325. package/dist/sync/workers/upload.js.map +1 -1
  326. package/dist/test-utils/memory-storage.d.ts +1 -1
  327. package/dist/test-utils/memory-storage.d.ts.map +1 -1
  328. package/dist/test-utils/memory-storage.js +11 -5
  329. package/dist/test-utils/memory-storage.js.map +1 -1
  330. 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":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,gFAAgF;AAChF,OAAO,EAAE,OAAO,EAAyB,MAAM,sBAAsB,CAAC;AAMtE,4EAA4E;AAC5E,MAAM,UAAU,mBAAmB,CACjC,MAA+B;IAE/B,uEAAuE;IACvE,2DAA2D;IAC3D,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC;QACtB,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,KAAK;QACb,eAAe,EAAE,KAAK;KACvB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CACvC,YAAuC;IAEvC,MAAM,QAAQ,GAAG,IAAI,OAAO,EAA4B,CAAC;IAEzD,SAAS,YAAY,CAAC,MAA+B;QACnD,IAAI,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YACvC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,oEAAoE;IACpE,oEAAoE;IACpE,KAAK,MAAM,WAAW,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,gBAAgB,WAAW,CAAC,IAAI,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC9G,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAClE,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,uEAAuE;QACvE,0DAA0D;QAC1D,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK;YAChB,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC;YAChD,CAAC,CAAC,QAAQ,CAAC;QACb,OAAO,qBAAqB,IAAI,IAAI,KAAK,EAAE,OAAO,IAAI,oCAAoC,EAAE,CAAC;IAC/F,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,MAA+B,EAC/B,YAAoB,EACpB,IAAa;IAEb,IAAI,YAAY,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IACzC,MAAM,QAAQ,GAAG,YAAY;SAC1B,KAAK,CAAC,CAAC,CAAC;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IACzD,IAAI,IAAI,GAAY,MAAM,CAAC;IAC3B,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,OAAO,EAAE,UACS,CAAC;QACtC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5D,MAAM,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,UAAU,IAAI,YAAY,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,OAAO,EAAE,WAAoC,CAAC;YAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,GAAG,MAAM,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC;YACxE,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;YAC7D,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;YAC3B,KAAK;gBACH,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAChC,CAAC,CAAE,KAAiC,CAAC,OAAO,CAAC;oBAC7C,CAAC,CAAC,SAAS,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,oEAAoE;YACpE,0DAA0D;YAC1D,IAAI;gBACF,OAAO,IAAI,CAAC,CAAC,mBAAmB,IAAI,OAAO,CAAC;oBAC1C,CAAC,CAAC,OAAO,CAAC,oBAAoB;oBAC9B,CAAC,CAAC,SAAS,CAAC;YAChB,KAAK;gBACH,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAChC,CAAC,CAAE,KAAiC,CAAC,OAAO,CAAC;oBAC7C,CAAC,CAAC,SAAS,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,eAAe,CACtB,IAA6B,EAC7B,IAAa;IAEb,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;QACxC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,GAAG,GAAI,IAAgC,CAAC,IAAI,CAAC;QACnD,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAA+B,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,IAAI,GAAG,GAAG;aACP,KAAK,CAAC,CAAC,CAAC;aACR,KAAK,CAAC,GAAG,CAAC;aACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;aACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;aACzE,MAAM,CACL,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CACV,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ;YAC1B,CAAC,CAAE,EAA8B,CAAC,GAAG,CAAC;YACtC,CAAC,CAAC,SAAS,EACf,IAAI,CACL,CAAC;IACN,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -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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"}