@learncard/network-brain-service 3.19.0 → 4.0.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 (507) hide show
  1. package/.env.example +47 -82
  2. package/AGENTS.md +52 -0
  3. package/CHANGELOG.md +147 -0
  4. package/README.md +51 -2
  5. package/bootstrapLambda.test.ts +72 -0
  6. package/config/config.dev.json +29 -0
  7. package/config/config.example.json +29 -0
  8. package/config/config.json +1 -0
  9. package/config/config.production.json +29 -0
  10. package/config/config.scouts.dev.json +24 -0
  11. package/config/config.scouts.production.json +24 -0
  12. package/contractEventsLambda.ts +18 -0
  13. package/contractEventsLambdaApp.ts +19 -0
  14. package/didWebLambda.ts +13 -18
  15. package/didWebLambdaApp.ts +22 -0
  16. package/dist/accesslayer/app-manifest-version/create.d.ts +10 -0
  17. package/dist/accesslayer/app-manifest-version/create.d.ts.map +1 -0
  18. package/dist/accesslayer/app-manifest-version/read.d.ts +11 -0
  19. package/dist/accesslayer/app-manifest-version/read.d.ts.map +1 -0
  20. package/dist/accesslayer/app-manifest-version/update.d.ts +7 -0
  21. package/dist/accesslayer/app-manifest-version/update.d.ts.map +1 -0
  22. package/dist/accesslayer/app-store-listing/read.d.ts +2 -1
  23. package/dist/accesslayer/app-store-listing/read.d.ts.map +1 -1
  24. package/dist/accesslayer/app-store-listing/relationships/create.d.ts +1 -0
  25. package/dist/accesslayer/app-store-listing/relationships/create.d.ts.map +1 -1
  26. package/dist/accesslayer/app-store-listing/relationships/read.d.ts +2 -0
  27. package/dist/accesslayer/app-store-listing/relationships/read.d.ts.map +1 -1
  28. package/dist/accesslayer/app-store-listing/update.d.ts +1 -0
  29. package/dist/accesslayer/app-store-listing/update.d.ts.map +1 -1
  30. package/dist/accesslayer/boost/relationships/create.d.ts +2 -1
  31. package/dist/accesslayer/boost/relationships/create.d.ts.map +1 -1
  32. package/dist/accesslayer/consentflowcontract/create.d.ts +9 -1
  33. package/dist/accesslayer/consentflowcontract/create.d.ts.map +1 -1
  34. package/dist/accesslayer/consentflowcontract/read.d.ts +34 -3
  35. package/dist/accesslayer/consentflowcontract/read.d.ts.map +1 -1
  36. package/dist/accesslayer/consentflowcontract/relationships/create.d.ts +4 -1
  37. package/dist/accesslayer/consentflowcontract/relationships/create.d.ts.map +1 -1
  38. package/dist/accesslayer/consentflowcontract/relationships/delete.d.ts.map +1 -1
  39. package/dist/accesslayer/consentflowcontract/relationships/read.d.ts +3 -2
  40. package/dist/accesslayer/consentflowcontract/relationships/read.d.ts.map +1 -1
  41. package/dist/accesslayer/consentflowcontract/relationships/recipients.d.ts +12 -0
  42. package/dist/accesslayer/consentflowcontract/relationships/recipients.d.ts.map +1 -0
  43. package/dist/accesslayer/consentflowcontract/relationships/smartResume.d.ts +12 -0
  44. package/dist/accesslayer/consentflowcontract/relationships/smartResume.d.ts.map +1 -0
  45. package/dist/accesslayer/consentflowcontract/relationships/update.d.ts +8 -5
  46. package/dist/accesslayer/consentflowcontract/relationships/update.d.ts.map +1 -1
  47. package/dist/accesslayer/credential/create.d.ts +2 -1
  48. package/dist/accesslayer/credential/create.d.ts.map +1 -1
  49. package/dist/accesslayer/credential/relationships/create.d.ts +4 -3
  50. package/dist/accesslayer/credential/relationships/create.d.ts.map +1 -1
  51. package/dist/accesslayer/inbox-credential/relationships/create.d.ts +2 -1
  52. package/dist/accesslayer/inbox-credential/relationships/create.d.ts.map +1 -1
  53. package/dist/accesslayer/inbox-credential/update.d.ts +2 -1
  54. package/dist/accesslayer/inbox-credential/update.d.ts.map +1 -1
  55. package/dist/accesslayer/presentation/read.d.ts.map +1 -1
  56. package/dist/accesslayer/presentation/relationships/create.d.ts +2 -2
  57. package/dist/accesslayer/presentation/relationships/create.d.ts.map +1 -1
  58. package/dist/accesslayer/presentation/relationships/read.d.ts.map +1 -1
  59. package/dist/accesslayer/share-link/abandon.d.ts +3 -0
  60. package/dist/accesslayer/share-link/abandon.d.ts.map +1 -0
  61. package/dist/accesslayer/share-link/attachment.d.ts +37 -0
  62. package/dist/accesslayer/share-link/attachment.d.ts.map +1 -0
  63. package/dist/accesslayer/share-link/cleanup.d.ts +6 -0
  64. package/dist/accesslayer/share-link/cleanup.d.ts.map +1 -0
  65. package/dist/accesslayer/share-link/errors.d.ts +8 -0
  66. package/dist/accesslayer/share-link/errors.d.ts.map +1 -0
  67. package/dist/accesslayer/share-link/finalize.d.ts +3 -0
  68. package/dist/accesslayer/share-link/finalize.d.ts.map +1 -0
  69. package/dist/accesslayer/share-link/helpers.d.ts +59 -0
  70. package/dist/accesslayer/share-link/helpers.d.ts.map +1 -0
  71. package/dist/accesslayer/share-link/index.d.ts +12 -0
  72. package/dist/accesslayer/share-link/index.d.ts.map +1 -0
  73. package/dist/accesslayer/share-link/list.d.ts +5 -0
  74. package/dist/accesslayer/share-link/list.d.ts.map +1 -0
  75. package/dist/accesslayer/share-link/read.d.ts +5 -0
  76. package/dist/accesslayer/share-link/read.d.ts.map +1 -0
  77. package/dist/accesslayer/share-link/receipt.d.ts +11 -0
  78. package/dist/accesslayer/share-link/receipt.d.ts.map +1 -0
  79. package/dist/accesslayer/share-link/recovery.d.ts +6 -0
  80. package/dist/accesslayer/share-link/recovery.d.ts.map +1 -0
  81. package/dist/accesslayer/share-link/reserve.d.ts +4 -0
  82. package/dist/accesslayer/share-link/reserve.d.ts.map +1 -0
  83. package/dist/accesslayer/share-link/revoke.d.ts +3 -0
  84. package/dist/accesslayer/share-link/revoke.d.ts.map +1 -0
  85. package/dist/accesslayer/share-link/transaction-execution.d.ts +18 -0
  86. package/dist/accesslayer/share-link/transaction-execution.d.ts.map +1 -0
  87. package/dist/accesslayer/share-link/transaction.d.ts +15 -0
  88. package/dist/accesslayer/share-link/transaction.d.ts.map +1 -0
  89. package/dist/accesslayer/share-link/types.d.ts +375 -0
  90. package/dist/accesslayer/share-link/types.d.ts.map +1 -0
  91. package/dist/app.d.ts +4 -0
  92. package/dist/app.d.ts.map +1 -1
  93. package/dist/cache/app-store.caches.d.ts +49 -0
  94. package/dist/cache/app-store.caches.d.ts.map +1 -1
  95. package/dist/config/applyDockerStageConfig.d.ts +2 -0
  96. package/dist/config/applyDockerStageConfig.d.ts.map +1 -0
  97. package/dist/config/environment.d.ts +14 -0
  98. package/dist/config/environment.d.ts.map +1 -1
  99. package/dist/config/serverlessFunctionEnv.test.d.ts +2 -0
  100. package/dist/config/serverlessFunctionEnv.test.d.ts.map +1 -0
  101. package/dist/config/stageConfig.d.ts +112 -0
  102. package/dist/config/stageConfig.d.ts.map +1 -0
  103. package/dist/config/stageConfig.test.d.ts +2 -0
  104. package/dist/config/stageConfig.test.d.ts.map +1 -0
  105. package/dist/constants/auth-grant.d.ts +2 -0
  106. package/dist/constants/auth-grant.d.ts.map +1 -1
  107. package/dist/didkit_wasm_bg.wasm +0 -0
  108. package/dist/docker-entry.d.ts +1 -1
  109. package/dist/docker-entry.d.ts.map +1 -1
  110. package/dist/helpers/app-manifest.helpers.d.ts +5 -0
  111. package/dist/helpers/app-manifest.helpers.d.ts.map +1 -0
  112. package/dist/helpers/boost.helpers.d.ts.map +1 -1
  113. package/dist/helpers/claim-hooks.helpers.d.ts +2 -1
  114. package/dist/helpers/claim-hooks.helpers.d.ts.map +1 -1
  115. package/dist/helpers/consent-referral.helpers.d.ts +2 -0
  116. package/dist/helpers/consent-referral.helpers.d.ts.map +1 -0
  117. package/dist/helpers/consent-scopes.helpers.d.ts +7 -0
  118. package/dist/helpers/consent-scopes.helpers.d.ts.map +1 -0
  119. package/dist/helpers/contract-event-maintenance.helpers.d.ts +3 -0
  120. package/dist/helpers/contract-event-maintenance.helpers.d.ts.map +1 -0
  121. package/dist/helpers/contract-events.helpers.d.ts +25 -0
  122. package/dist/helpers/contract-events.helpers.d.ts.map +1 -0
  123. package/dist/helpers/contract-requests.helpers.d.ts +19 -0
  124. package/dist/helpers/contract-requests.helpers.d.ts.map +1 -0
  125. package/dist/helpers/credentialSubject.helpers.d.ts +3 -0
  126. package/dist/helpers/credentialSubject.helpers.d.ts.map +1 -0
  127. package/dist/helpers/credentialSubject.helpers.test.d.ts +2 -0
  128. package/dist/helpers/credentialSubject.helpers.test.d.ts.map +1 -0
  129. package/dist/helpers/finalize-inbox.helpers.d.ts +3 -3
  130. package/dist/helpers/finalize-inbox.helpers.d.ts.map +1 -1
  131. package/dist/helpers/inbox.helpers.d.ts.map +1 -1
  132. package/dist/helpers/inline-template.helpers.d.ts +45 -0
  133. package/dist/helpers/inline-template.helpers.d.ts.map +1 -0
  134. package/dist/helpers/notificationMessages.d.ts +1 -1
  135. package/dist/helpers/notificationMessages.d.ts.map +1 -1
  136. package/dist/helpers/notificationQueue.helpers.d.ts.map +1 -1
  137. package/dist/helpers/notifications.helpers.d.ts +6 -0
  138. package/dist/helpers/notifications.helpers.d.ts.map +1 -1
  139. package/dist/helpers/presentation-metadata.d.ts +4 -0
  140. package/dist/helpers/presentation-metadata.d.ts.map +1 -0
  141. package/dist/helpers/presentation.helpers.d.ts +1 -1
  142. package/dist/helpers/presentation.helpers.d.ts.map +1 -1
  143. package/dist/helpers/profile.helpers.d.ts +2 -0
  144. package/dist/helpers/profile.helpers.d.ts.map +1 -1
  145. package/dist/helpers/share-content-client/adapters.d.ts +10 -0
  146. package/dist/helpers/share-content-client/adapters.d.ts.map +1 -0
  147. package/dist/helpers/share-content-client/canonical.d.ts +7 -0
  148. package/dist/helpers/share-content-client/canonical.d.ts.map +1 -0
  149. package/dist/helpers/share-content-client/client.d.ts +5 -0
  150. package/dist/helpers/share-content-client/client.d.ts.map +1 -0
  151. package/dist/helpers/share-content-client/config.d.ts +11 -0
  152. package/dist/helpers/share-content-client/config.d.ts.map +1 -0
  153. package/dist/helpers/share-content-client/index.d.ts +6 -0
  154. package/dist/helpers/share-content-client/index.d.ts.map +1 -0
  155. package/dist/helpers/share-content-client/responses.d.ts +16 -0
  156. package/dist/helpers/share-content-client/responses.d.ts.map +1 -0
  157. package/dist/helpers/share-content-client/types.d.ts +145 -0
  158. package/dist/helpers/share-content-client/types.d.ts.map +1 -0
  159. package/dist/helpers/share-link-attachment-access.d.ts +4 -0
  160. package/dist/helpers/share-link-attachment-access.d.ts.map +1 -0
  161. package/dist/helpers/share-link-attachment.d.ts +18 -0
  162. package/dist/helpers/share-link-attachment.d.ts.map +1 -0
  163. package/dist/helpers/share-link-coordinator/attachment-stat.d.ts +5 -0
  164. package/dist/helpers/share-link-coordinator/attachment-stat.d.ts.map +1 -0
  165. package/dist/helpers/share-link-coordinator/budget-helpers.d.ts +5 -0
  166. package/dist/helpers/share-link-coordinator/budget-helpers.d.ts.map +1 -0
  167. package/dist/helpers/share-link-coordinator/cleanup-runner.d.ts +3 -0
  168. package/dist/helpers/share-link-coordinator/cleanup-runner.d.ts.map +1 -0
  169. package/dist/helpers/share-link-coordinator/coordinator.d.ts +4 -0
  170. package/dist/helpers/share-link-coordinator/coordinator.d.ts.map +1 -0
  171. package/dist/helpers/share-link-coordinator/index.d.ts +5 -0
  172. package/dist/helpers/share-link-coordinator/index.d.ts.map +1 -0
  173. package/dist/helpers/share-link-coordinator/recovery-runner.d.ts +9 -0
  174. package/dist/helpers/share-link-coordinator/recovery-runner.d.ts.map +1 -0
  175. package/dist/helpers/share-link-coordinator/runtime.d.ts +11 -0
  176. package/dist/helpers/share-link-coordinator/runtime.d.ts.map +1 -0
  177. package/dist/helpers/share-link-coordinator/stat.d.ts +4 -0
  178. package/dist/helpers/share-link-coordinator/stat.d.ts.map +1 -0
  179. package/dist/helpers/share-link-coordinator/types.d.ts +160 -0
  180. package/dist/helpers/share-link-coordinator/types.d.ts.map +1 -0
  181. package/dist/helpers/share-link-lifecycle/index.d.ts +5 -0
  182. package/dist/helpers/share-link-lifecycle/index.d.ts.map +1 -0
  183. package/dist/helpers/share-link-lifecycle/lease.helpers.d.ts +4 -0
  184. package/dist/helpers/share-link-lifecycle/lease.helpers.d.ts.map +1 -0
  185. package/dist/helpers/share-link-lifecycle/recovery.helpers.d.ts +21 -0
  186. package/dist/helpers/share-link-lifecycle/recovery.helpers.d.ts.map +1 -0
  187. package/dist/helpers/share-link-lifecycle/request-hash.helpers.d.ts +9 -0
  188. package/dist/helpers/share-link-lifecycle/request-hash.helpers.d.ts.map +1 -0
  189. package/dist/helpers/share-link-lifecycle/types.d.ts +14 -0
  190. package/dist/helpers/share-link-lifecycle/types.d.ts.map +1 -0
  191. package/dist/helpers/share-link-maintenance/budget.d.ts +12 -0
  192. package/dist/helpers/share-link-maintenance/budget.d.ts.map +1 -0
  193. package/dist/helpers/share-link-maintenance/config.d.ts +48 -0
  194. package/dist/helpers/share-link-maintenance/config.d.ts.map +1 -0
  195. package/dist/helpers/share-link-maintenance/index.d.ts +8 -0
  196. package/dist/helpers/share-link-maintenance/index.d.ts.map +1 -0
  197. package/dist/helpers/share-link-maintenance/runner.d.ts +20 -0
  198. package/dist/helpers/share-link-maintenance/runner.d.ts.map +1 -0
  199. package/dist/helpers/share-link-maintenance/runtime.d.ts +38 -0
  200. package/dist/helpers/share-link-maintenance/runtime.d.ts.map +1 -0
  201. package/dist/helpers/share-link-maintenance/scheduler.d.ts +18 -0
  202. package/dist/helpers/share-link-maintenance/scheduler.d.ts.map +1 -0
  203. package/dist/helpers/share-link-maintenance/telemetry.d.ts +5 -0
  204. package/dist/helpers/share-link-maintenance/telemetry.d.ts.map +1 -0
  205. package/dist/helpers/share-link-maintenance/types.d.ts +56 -0
  206. package/dist/helpers/share-link-maintenance/types.d.ts.map +1 -0
  207. package/dist/helpers/share-link-owner/config.d.ts +16 -0
  208. package/dist/helpers/share-link-owner/config.d.ts.map +1 -0
  209. package/dist/helpers/share-link-owner/diagnostics.d.ts +26 -0
  210. package/dist/helpers/share-link-owner/diagnostics.d.ts.map +1 -0
  211. package/dist/helpers/share-link-owner/lazy-initializer.d.ts +2 -0
  212. package/dist/helpers/share-link-owner/lazy-initializer.d.ts.map +1 -0
  213. package/dist/helpers/share-link-owner-projection.d.ts +4 -0
  214. package/dist/helpers/share-link-owner-projection.d.ts.map +1 -0
  215. package/dist/helpers/share-link-passcode-abuse.d.ts +2 -0
  216. package/dist/helpers/share-link-passcode-abuse.d.ts.map +1 -0
  217. package/dist/helpers/share-link-passcode.d.ts +6 -0
  218. package/dist/helpers/share-link-passcode.d.ts.map +1 -0
  219. package/dist/helpers/share-link-policy/index.d.ts +4 -0
  220. package/dist/helpers/share-link-policy/index.d.ts.map +1 -0
  221. package/dist/helpers/share-link-policy/production.d.ts +11 -0
  222. package/dist/helpers/share-link-policy/production.d.ts.map +1 -0
  223. package/dist/helpers/share-link-policy/resolver.d.ts +6 -0
  224. package/dist/helpers/share-link-policy/resolver.d.ts.map +1 -0
  225. package/dist/helpers/share-link-policy/types.d.ts +22 -0
  226. package/dist/helpers/share-link-policy/types.d.ts.map +1 -0
  227. package/dist/helpers/share-link-public/config.d.ts +13 -0
  228. package/dist/helpers/share-link-public/config.d.ts.map +1 -0
  229. package/dist/helpers/share-link-view-notification.d.ts +2 -0
  230. package/dist/helpers/share-link-view-notification.d.ts.map +1 -0
  231. package/dist/helpers/signingAuthority.helpers.d.ts.map +1 -1
  232. package/dist/helpers/smartResume.helpers.d.ts +3 -0
  233. package/dist/helpers/smartResume.helpers.d.ts.map +1 -0
  234. package/dist/index.js +2 -2
  235. package/dist/models/AppManifestVersion.d.ts +20 -0
  236. package/dist/models/AppManifestVersion.d.ts.map +1 -0
  237. package/dist/models/AppStoreListing.d.ts +13 -0
  238. package/dist/models/AppStoreListing.d.ts.map +1 -1
  239. package/dist/models/ConsentFlowContract.d.ts +13 -2
  240. package/dist/models/ConsentFlowContract.d.ts.map +1 -1
  241. package/dist/models/ConsentFlowTerms.d.ts.map +1 -1
  242. package/dist/models/ConsentFlowTransaction.d.ts.map +1 -1
  243. package/dist/models/Integration.d.ts +2 -0
  244. package/dist/models/Integration.d.ts.map +1 -1
  245. package/dist/models/Presentation.d.ts +2 -0
  246. package/dist/models/Presentation.d.ts.map +1 -1
  247. package/dist/models/Profile.d.ts +2 -0
  248. package/dist/models/Profile.d.ts.map +1 -1
  249. package/dist/models/ShareLink.d.ts +46 -0
  250. package/dist/models/ShareLink.d.ts.map +1 -0
  251. package/dist/models/ShareViewReceipt.d.ts +22 -0
  252. package/dist/models/ShareViewReceipt.d.ts.map +1 -0
  253. package/dist/models/index.d.ts +2 -0
  254. package/dist/models/index.d.ts.map +1 -1
  255. package/dist/models/share-link-constraints.d.ts +3 -0
  256. package/dist/models/share-link-constraints.d.ts.map +1 -0
  257. package/dist/openapi.d.ts +1 -1
  258. package/dist/openapi.d.ts.map +1 -1
  259. package/dist/public-share-link-http.d.ts +4 -0
  260. package/dist/public-share-link-http.d.ts.map +1 -0
  261. package/dist/routes/app-store.d.ts +619 -0
  262. package/dist/routes/app-store.d.ts.map +1 -1
  263. package/dist/routes/boosts.d.ts +2 -2
  264. package/dist/routes/boosts.d.ts.map +1 -1
  265. package/dist/routes/contracts.d.ts +148 -5
  266. package/dist/routes/contracts.d.ts.map +1 -1
  267. package/dist/routes/credentials.d.ts +35 -1
  268. package/dist/routes/credentials.d.ts.map +1 -1
  269. package/dist/routes/inbox.d.ts +52 -2
  270. package/dist/routes/inbox.d.ts.map +1 -1
  271. package/dist/routes/index.d.ts +153 -0
  272. package/dist/routes/index.d.ts.map +1 -1
  273. package/dist/routes/presentations.d.ts +1 -0
  274. package/dist/routes/presentations.d.ts.map +1 -1
  275. package/dist/routes/profile-manager.d.ts.map +1 -1
  276. package/dist/routes/profiles.d.ts.map +1 -1
  277. package/dist/routes/public-share-links.d.ts +285 -0
  278. package/dist/routes/public-share-links.d.ts.map +1 -0
  279. package/dist/routes/share-links.d.ts +1005 -0
  280. package/dist/routes/share-links.d.ts.map +1 -0
  281. package/dist/routes/test.d.ts +5 -0
  282. package/dist/routes/test.d.ts.map +1 -1
  283. package/dist/routes/workflows.d.ts.map +1 -1
  284. package/dist/services/delivery/adapters/postmark.adapter.d.ts.map +1 -1
  285. package/dist/types/app-manifest.d.ts +339 -0
  286. package/dist/types/app-manifest.d.ts.map +1 -0
  287. package/dist/types/app-store-listing.d.ts +34 -0
  288. package/dist/types/app-store-listing.d.ts.map +1 -1
  289. package/dist/types/consentflowcontract.d.ts +31 -4
  290. package/dist/types/consentflowcontract.d.ts.map +1 -1
  291. package/dist/types/credential-refresh.d.ts +1 -1
  292. package/esbuildPlugins.cjs +1 -0
  293. package/lambda.ts +49 -192
  294. package/lambdaApp.ts +203 -0
  295. package/package.json +25 -17
  296. package/scripts/export-openapi.ts +20 -0
  297. package/scripts/offline-schema-environment.ts +18 -0
  298. package/scripts/seed-demo-persona.ts +425 -0
  299. package/scripts/verify-python-contracts.ts +72 -0
  300. package/serverless-local.yml +3 -6
  301. package/serverless.function-env.cjs +50 -0
  302. package/serverless.local.yml +0 -1
  303. package/serverless.yml +44 -55
  304. package/shareLinkMaintenanceLambda.ts +18 -0
  305. package/shareLinkMaintenanceLambdaApp.ts +50 -0
  306. package/src/accesslayer/app-manifest-version/create.ts +57 -0
  307. package/src/accesslayer/app-manifest-version/read.ts +129 -0
  308. package/src/accesslayer/app-manifest-version/update.ts +61 -0
  309. package/src/accesslayer/app-store-listing/read.ts +6 -0
  310. package/src/accesslayer/app-store-listing/relationships/create.ts +20 -0
  311. package/src/accesslayer/app-store-listing/relationships/read.ts +24 -1
  312. package/src/accesslayer/app-store-listing/update.ts +15 -0
  313. package/src/accesslayer/boost/relationships/create.ts +8 -2
  314. package/src/accesslayer/consentflowcontract/create.ts +81 -8
  315. package/src/accesslayer/consentflowcontract/read.ts +84 -10
  316. package/src/accesslayer/consentflowcontract/relationships/create.ts +125 -109
  317. package/src/accesslayer/consentflowcontract/relationships/delete.ts +1 -0
  318. package/src/accesslayer/consentflowcontract/relationships/read.ts +184 -108
  319. package/src/accesslayer/consentflowcontract/relationships/recipients.ts +125 -0
  320. package/src/accesslayer/consentflowcontract/relationships/smartResume.ts +125 -0
  321. package/src/accesslayer/consentflowcontract/relationships/update.ts +255 -217
  322. package/src/accesslayer/credential/create.test.ts +2 -115
  323. package/src/accesslayer/credential/create.ts +11 -6
  324. package/src/accesslayer/credential/relationships/create.ts +17 -10
  325. package/src/accesslayer/inbox-credential/relationships/create.ts +70 -48
  326. package/src/accesslayer/inbox-credential/update.ts +4 -2
  327. package/src/accesslayer/presentation/read.ts +57 -25
  328. package/src/accesslayer/presentation/relationships/create.ts +54 -11
  329. package/src/accesslayer/presentation/relationships/read.ts +21 -6
  330. package/src/accesslayer/share-link/abandon.ts +120 -0
  331. package/src/accesslayer/share-link/attachment.ts +360 -0
  332. package/src/accesslayer/share-link/cleanup.ts +271 -0
  333. package/src/accesslayer/share-link/errors.ts +32 -0
  334. package/src/accesslayer/share-link/finalize.ts +313 -0
  335. package/src/accesslayer/share-link/helpers.ts +450 -0
  336. package/src/accesslayer/share-link/index.ts +11 -0
  337. package/src/accesslayer/share-link/list.ts +162 -0
  338. package/src/accesslayer/share-link/read.ts +107 -0
  339. package/src/accesslayer/share-link/receipt.ts +548 -0
  340. package/src/accesslayer/share-link/recovery.ts +565 -0
  341. package/src/accesslayer/share-link/reserve.ts +763 -0
  342. package/src/accesslayer/share-link/revoke.ts +232 -0
  343. package/src/accesslayer/share-link/transaction-execution.ts +72 -0
  344. package/src/accesslayer/share-link/transaction.ts +126 -0
  345. package/src/accesslayer/share-link/types.ts +606 -0
  346. package/src/app.ts +6 -0
  347. package/src/cache/app-store.caches.ts +35 -0
  348. package/src/config/applyDockerStageConfig.ts +6 -0
  349. package/src/config/environment.test.ts +17 -12
  350. package/src/config/environment.ts +15 -0
  351. package/src/config/serverlessFunctionEnv.test.ts +105 -0
  352. package/src/config/stageConfig.test.ts +25 -0
  353. package/src/config/stageConfig.ts +24 -0
  354. package/src/constants/auth-grant.ts +5 -0
  355. package/src/docker-entry.ts +81 -0
  356. package/src/helpers/app-manifest.helpers.ts +185 -0
  357. package/src/helpers/boost.helpers.ts +4 -31
  358. package/src/helpers/claim-hooks.helpers.ts +20 -7
  359. package/src/helpers/consent-referral.helpers.ts +6 -0
  360. package/src/helpers/consent-scopes.helpers.ts +58 -0
  361. package/src/helpers/contract-event-maintenance.helpers.ts +43 -0
  362. package/src/helpers/contract-events.helpers.ts +540 -0
  363. package/src/helpers/contract-requests.helpers.ts +211 -0
  364. package/src/helpers/credentialSubject.helpers.test.ts +114 -0
  365. package/src/helpers/credentialSubject.helpers.ts +40 -0
  366. package/src/helpers/finalize-inbox.helpers.ts +163 -44
  367. package/src/helpers/inbox.helpers.ts +58 -70
  368. package/src/helpers/inline-template.helpers.ts +560 -0
  369. package/src/helpers/notificationMessages.ts +77 -1
  370. package/src/helpers/notificationQueue.helpers.ts +23 -5
  371. package/src/helpers/notifications.helpers.ts +25 -1
  372. package/src/helpers/presentation-metadata.ts +41 -0
  373. package/src/helpers/presentation.helpers.ts +27 -20
  374. package/src/helpers/profile.helpers.ts +13 -0
  375. package/src/helpers/share-content-client/adapters.ts +55 -0
  376. package/src/helpers/share-content-client/canonical.ts +25 -0
  377. package/src/helpers/share-content-client/client.ts +440 -0
  378. package/src/helpers/share-content-client/config.ts +189 -0
  379. package/src/helpers/share-content-client/index.ts +27 -0
  380. package/src/helpers/share-content-client/responses.ts +273 -0
  381. package/src/helpers/share-content-client/types.ts +253 -0
  382. package/src/helpers/share-link-attachment-access.ts +87 -0
  383. package/src/helpers/share-link-attachment.ts +115 -0
  384. package/src/helpers/share-link-coordinator/attachment-stat.ts +41 -0
  385. package/src/helpers/share-link-coordinator/budget-helpers.ts +53 -0
  386. package/src/helpers/share-link-coordinator/cleanup-runner.ts +286 -0
  387. package/src/helpers/share-link-coordinator/coordinator.ts +727 -0
  388. package/src/helpers/share-link-coordinator/index.ts +8 -0
  389. package/src/helpers/share-link-coordinator/recovery-runner.ts +443 -0
  390. package/src/helpers/share-link-coordinator/runtime.ts +88 -0
  391. package/src/helpers/share-link-coordinator/stat.ts +30 -0
  392. package/src/helpers/share-link-coordinator/types.ts +353 -0
  393. package/src/helpers/share-link-lifecycle/index.ts +4 -0
  394. package/src/helpers/share-link-lifecycle/lease.helpers.ts +35 -0
  395. package/src/helpers/share-link-lifecycle/recovery.helpers.ts +173 -0
  396. package/src/helpers/share-link-lifecycle/request-hash.helpers.ts +130 -0
  397. package/src/helpers/share-link-lifecycle/types.ts +58 -0
  398. package/src/helpers/share-link-maintenance/budget.ts +63 -0
  399. package/src/helpers/share-link-maintenance/config.ts +312 -0
  400. package/src/helpers/share-link-maintenance/index.ts +24 -0
  401. package/src/helpers/share-link-maintenance/runner.ts +251 -0
  402. package/src/helpers/share-link-maintenance/runtime.ts +340 -0
  403. package/src/helpers/share-link-maintenance/scheduler.ts +126 -0
  404. package/src/helpers/share-link-maintenance/telemetry.ts +73 -0
  405. package/src/helpers/share-link-maintenance/types.ts +91 -0
  406. package/src/helpers/share-link-owner/config.ts +48 -0
  407. package/src/helpers/share-link-owner/diagnostics.ts +89 -0
  408. package/src/helpers/share-link-owner/lazy-initializer.ts +29 -0
  409. package/src/helpers/share-link-owner-projection.ts +54 -0
  410. package/src/helpers/share-link-passcode-abuse.ts +36 -0
  411. package/src/helpers/share-link-passcode.ts +47 -0
  412. package/src/helpers/share-link-policy/index.ts +7 -0
  413. package/src/helpers/share-link-policy/production.ts +108 -0
  414. package/src/helpers/share-link-policy/resolver.ts +113 -0
  415. package/src/helpers/share-link-policy/types.ts +56 -0
  416. package/src/helpers/share-link-public/config.ts +41 -0
  417. package/src/helpers/share-link-view-notification.ts +18 -0
  418. package/src/helpers/signingAuthority.helpers.ts +23 -14
  419. package/src/helpers/smartResume.helpers.ts +123 -0
  420. package/src/models/AppManifestVersion.ts +43 -0
  421. package/src/models/AppStoreListing.ts +32 -0
  422. package/src/models/ConsentFlowContract.ts +34 -3
  423. package/src/models/ConsentFlowTerms.ts +10 -0
  424. package/src/models/ConsentFlowTransaction.ts +3 -0
  425. package/src/models/Integration.ts +2 -0
  426. package/src/models/Presentation.ts +2 -2
  427. package/src/models/Profile.ts +3 -2
  428. package/src/models/ShareLink.ts +134 -0
  429. package/src/models/ShareViewReceipt.ts +69 -0
  430. package/src/models/index.ts +25 -0
  431. package/src/models/share-link-constraints.ts +98 -0
  432. package/src/openapi.ts +44 -8
  433. package/src/public-share-link-http.ts +49 -0
  434. package/src/routes/app-store.ts +1056 -38
  435. package/src/routes/boosts.ts +14 -25
  436. package/src/routes/contracts.ts +384 -273
  437. package/src/routes/inbox.ts +4 -2
  438. package/src/routes/index.ts +142 -44
  439. package/src/routes/presentations.ts +19 -3
  440. package/src/routes/profile-manager.ts +29 -2
  441. package/src/routes/profiles.ts +29 -6
  442. package/src/routes/public-share-links.ts +983 -0
  443. package/src/routes/share-links.ts +709 -0
  444. package/src/routes/workflows.ts +3 -2
  445. package/src/services/delivery/adapters/postmark.adapter.ts +4 -1
  446. package/src/types/app-manifest.ts +28 -0
  447. package/src/types/app-store-listing.ts +13 -0
  448. package/src/types/consentflowcontract.ts +25 -4
  449. package/test/app-manifest.helpers.spec.ts +170 -0
  450. package/test/app-manifest.routes.spec.ts +299 -0
  451. package/test/app-store-listing-updates.spec.ts +236 -0
  452. package/test/app-store-listing.spec.ts +65 -3
  453. package/test/consent-data-boundaries.spec.ts +352 -0
  454. package/test/consent-recipients.spec.ts +513 -0
  455. package/test/consent-scopes.helpers.spec.ts +67 -0
  456. package/test/consentflow.spec.ts +63 -2
  457. package/test/contract-requests.spec.ts +1588 -0
  458. package/test/credential-storage.neo4j.spec.ts +122 -0
  459. package/test/dids.spec.ts +10 -1
  460. package/test/guardian-gated-routes.spec.ts +49 -0
  461. package/test/helpers/share-link-fixtures.ts +94 -0
  462. package/test/inbox-security.e2e.ts +26 -10
  463. package/test/inbox.spec.ts +184 -8
  464. package/test/inline-template.helpers.spec.ts +49 -0
  465. package/test/managed-recipient-inbox.spec.ts +152 -0
  466. package/test/notificationMessages.spec.ts +13 -0
  467. package/test/openapi.spec.ts +14 -53
  468. package/test/presentations.spec.ts +54 -6
  469. package/test/profiles.spec.ts +97 -1
  470. package/test/share-content-client.contract.spec.ts +365 -0
  471. package/test/share-content-client.unit.spec.ts +462 -0
  472. package/test/share-link-abuse.unit.spec.ts +65 -0
  473. package/test/share-link-attachment.neo4j.spec.ts +262 -0
  474. package/test/share-link-attachment.unit.spec.ts +244 -0
  475. package/test/share-link-coordinator.neo4j.spec.ts +684 -0
  476. package/test/share-link-coordinator.unit.spec.ts +990 -0
  477. package/test/share-link-dependency-diagnostics.unit.spec.ts +127 -0
  478. package/test/share-link-lifecycle.neo4j.spec.ts +1411 -0
  479. package/test/share-link-lifecycle.unit.spec.ts +205 -0
  480. package/test/share-link-list-cursor.unit.spec.ts +86 -0
  481. package/test/share-link-list.neo4j.spec.ts +324 -0
  482. package/test/share-link-maintenance.neo4j.spec.ts +355 -0
  483. package/test/share-link-maintenance.unit.spec.ts +1140 -0
  484. package/test/share-link-owner-policy.unit.spec.ts +210 -0
  485. package/test/share-link-owner-route.unit.spec.ts +820 -0
  486. package/test/share-link-owner-runtime.unit.spec.ts +102 -0
  487. package/test/share-link-passcode.unit.spec.ts +29 -0
  488. package/test/share-link-policy.unit.spec.ts +149 -0
  489. package/test/share-link-presentation-metadata.unit.spec.ts +49 -0
  490. package/test/share-link-production-policy.unit.spec.ts +126 -0
  491. package/test/share-link-public-config.unit.spec.ts +64 -0
  492. package/test/share-link-public-http-adapter.unit.spec.ts +315 -0
  493. package/test/share-link-public-route.unit.spec.ts +1079 -0
  494. package/test/share-link-receipt.neo4j.spec.ts +943 -0
  495. package/test/share-link-recovery.neo4j.spec.ts +935 -0
  496. package/test/share-link-recovery.unit.spec.ts +726 -0
  497. package/test/share-link-service-policy.neo4j.spec.ts +403 -0
  498. package/test/signing-authority-encryption.spec.ts +75 -0
  499. package/test/smart-resume-consent.spec.ts +233 -0
  500. package/test/smart-resume-upload.spec.ts +65 -0
  501. package/tsconfig.build.json +1 -1
  502. package/tsconfig.json +1 -0
  503. package/vitest.config.ts +14 -0
  504. package/vitest.inbox-e2e.config.ts +2 -0
  505. package/vitest.share-links-neo4j.config.ts +19 -0
  506. package/vitest.share-links-unit.config.ts +28 -0
  507. package/workerLambda.test.ts +100 -0
@@ -0,0 +1,58 @@
1
+ /**
2
+ * LC-2187 share-link lifecycle constants and literals.
3
+ *
4
+ * This module is intentionally storage- and transport-agnostic: routes, the
5
+ * LearnCloud client and the reconciliation worker all derive their bounds from
6
+ * here so the Brain repository and the tests agree on one set of numbers.
7
+ */
8
+
9
+ /** Operation kinds that are bound to an idempotency record. */
10
+ export type ShareLinkOperationKind = 'create' | 'update' | 'revoke';
11
+
12
+ export const SHARE_LINK_OPERATION_KINDS: readonly ShareLinkOperationKind[] = [
13
+ 'create',
14
+ 'update',
15
+ 'revoke',
16
+ ];
17
+
18
+ /**
19
+ * Default bounded lease for one in-flight share content operation. A worker that
20
+ * cannot finish staging + finalize within the lease loses its fence and must not
21
+ * commit; a later reservation supersedes it with a higher generation.
22
+ */
23
+ export const SHARE_LINK_DEFAULT_LEASE_MS = 2 * 60 * 1000;
24
+
25
+ /**
26
+ * Retain completed operation records for 30 days.
27
+ *
28
+ * Pruning is an explicit operator action, not an automatic replay path. After a
29
+ * record is pruned, object-reference uniqueness, the share version compare-and-set
30
+ * and the `stopped` terminal state still prevent a replay from overwriting newer
31
+ * content.
32
+ */
33
+ export const SHARE_LINK_OPERATION_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
34
+
35
+ /** Cleanup retry backoff bounds (exponential, capped). */
36
+ export const SHARE_LINK_CLEANUP_BASE_BACKOFF_MS = 30 * 1000;
37
+ export const SHARE_LINK_CLEANUP_MAX_BACKOFF_MS = 24 * 60 * 60 * 1000;
38
+
39
+ /** Default cap on cleanup jobs claimed in one bounded batch. */
40
+ export const SHARE_LINK_CLEANUP_DEFAULT_BATCH = 25;
41
+ export const SHARE_LINK_CLEANUP_MAX_BATCH = 100;
42
+
43
+ /** Default lease for a claimed cleanup job. */
44
+ export const SHARE_LINK_CLEANUP_DEFAULT_CLAIM_MS = 5 * 60 * 1000;
45
+
46
+ /**
47
+ * Hard bounds for a caller-supplied cleanup claim lease. A configured
48
+ * maintenance lease is clamped into this window so a bad deployment cannot hold
49
+ * (or instantly drop) work; the repository default is unchanged.
50
+ */
51
+ export const SHARE_LINK_CLEANUP_MIN_CLAIM_MS = 1_000;
52
+ export const SHARE_LINK_CLEANUP_MAX_CLAIM_MS = 30 * 60 * 1000;
53
+
54
+ /** Reasons a durable cleanup job can be created. */
55
+ export type ShareContentCleanupReason = 'superseded' | 'abandoned' | 'stopped';
56
+
57
+ /** Lifecycle status of a durable cleanup job. */
58
+ export type ShareContentCleanupStatus = 'queued' | 'claimed' | 'completed';
@@ -0,0 +1,63 @@
1
+ import type { MaintenanceBudget } from '../share-link-coordinator';
2
+
3
+ /**
4
+ * Monotonic wall-clock budget for one maintenance pass.
5
+ *
6
+ * The runner checks `exhausted()` before each claim; once the remaining time is
7
+ * at or below `finalizeReserveMs` it must stop starting new graph/remote work so
8
+ * the pass can still log and return a summary. This is a cooperative deadline,
9
+ * not a hard kill: it never uses `Promise.race`, which would leave an untracked
10
+ * mutation running after the pass returned.
11
+ */
12
+ export type MaintenancePassBudget = MaintenanceBudget & {
13
+ elapsedMs: () => number;
14
+ configuredMs: number;
15
+ };
16
+
17
+ const defaultMonotonicNow = (): number =>
18
+ typeof performance !== 'undefined' && typeof performance.now === 'function'
19
+ ? performance.now()
20
+ : Date.now();
21
+
22
+ /**
23
+ * Resolve the pass budget from a Lambda remaining-time value.
24
+ *
25
+ * `undefined` means "no Lambda signal" and keeps the configured budget. Any
26
+ * other value failing the finite/positive check — NaN, Infinity, negative or
27
+ * zero — fails closed to a zero budget so the pass does no work.
28
+ */
29
+ export const resolveMaintenanceBudgetMs = (
30
+ configuredBudgetMs: number,
31
+ remainingTimeMs: number | undefined
32
+ ): number => {
33
+ if (remainingTimeMs === undefined) return configuredBudgetMs;
34
+ if (!Number.isFinite(remainingTimeMs) || remainingTimeMs <= 0) return 0;
35
+
36
+ return Math.min(configuredBudgetMs, Math.trunc(remainingTimeMs));
37
+ };
38
+
39
+ export const createMaintenancePassBudget = (input: {
40
+ budgetMs: number;
41
+ finalizeReserveMs: number;
42
+ monotonicNow?: () => number;
43
+ }): MaintenancePassBudget => {
44
+ const monotonicNow = input.monotonicNow ?? defaultMonotonicNow;
45
+ const configuredMs = Number.isFinite(input.budgetMs)
46
+ ? Math.max(0, Math.trunc(input.budgetMs))
47
+ : 0;
48
+ const reserveMs = Number.isFinite(input.finalizeReserveMs)
49
+ ? Math.max(0, Math.trunc(input.finalizeReserveMs))
50
+ : 0;
51
+ const startedAt = monotonicNow();
52
+ const deadline = startedAt + configuredMs;
53
+
54
+ const remainingMs = (): number => deadline - monotonicNow();
55
+
56
+ return {
57
+ configuredMs,
58
+ elapsedMs: () => monotonicNow() - startedAt,
59
+ remainingMs,
60
+ reserveMs: () => reserveMs,
61
+ exhausted: () => remainingMs() <= reserveMs,
62
+ };
63
+ };
@@ -0,0 +1,312 @@
1
+ import {
2
+ SHARE_LINK_CLEANUP_DEFAULT_BATCH,
3
+ SHARE_LINK_CLEANUP_DEFAULT_CLAIM_MS,
4
+ SHARE_LINK_CLEANUP_MAX_BATCH,
5
+ SHARE_LINK_CLEANUP_MAX_CLAIM_MS,
6
+ SHARE_LINK_CLEANUP_MIN_CLAIM_MS,
7
+ SHARE_LINK_DEFAULT_LEASE_MS,
8
+ } from '../share-link-lifecycle';
9
+ import {
10
+ SHARE_LINK_RECOVERY_DEFAULT_BATCH,
11
+ SHARE_LINK_RECOVERY_MAX_BATCH,
12
+ } from '../share-link-lifecycle/recovery.helpers';
13
+ import { validateShareContentOrigin } from '../share-content-client/config';
14
+ import type { ShareLinkMaintenanceConfig, ShareLinkMaintenanceConfigResolution } from './types';
15
+
16
+ /**
17
+ * Operator-facing configuration for the automatic share-link maintenance pass.
18
+ *
19
+ * Every value is read and validated here rather than in the global environment
20
+ * schema so malformed maintenance settings fail closed to a fixed category
21
+ * instead of preventing the whole Brain service from booting. Absent or
22
+ * invalid configuration must perform no graph or remote I/O and must not
23
+ * initialize a signer.
24
+ */
25
+
26
+ export const SHARE_LINK_MAINTENANCE_ENV = {
27
+ NAMESPACE: 'SHARE_LINK_MAINTENANCE_NAMESPACE',
28
+ ORIGIN: 'SHARE_LINK_MAINTENANCE_ORIGIN',
29
+ AUDIENCE: 'SHARE_LINK_MAINTENANCE_AUDIENCE',
30
+ ALLOW_INSECURE_LOOPBACK: 'SHARE_LINK_MAINTENANCE_ALLOW_INSECURE_LOOPBACK',
31
+ CLAIMANT: 'SHARE_LINK_MAINTENANCE_CLAIMANT',
32
+ RECOVERY_LIMIT: 'SHARE_LINK_MAINTENANCE_RECOVERY_LIMIT',
33
+ CLEANUP_LIMIT: 'SHARE_LINK_MAINTENANCE_CLEANUP_LIMIT',
34
+ RECEIPT_PRUNE_LIMIT: 'SHARE_LINK_MAINTENANCE_RECEIPT_PRUNE_LIMIT',
35
+ LEASE_MS: 'SHARE_LINK_MAINTENANCE_LEASE_MS',
36
+ CLAIM_MS: 'SHARE_LINK_MAINTENANCE_CLAIM_MS',
37
+ BUDGET_MS: 'SHARE_LINK_MAINTENANCE_BUDGET_MS',
38
+ INTERVAL_MS: 'SHARE_LINK_MAINTENANCE_INTERVAL_MS',
39
+ REQUEST_TIMEOUT_MS: 'SHARE_LINK_MAINTENANCE_REQUEST_TIMEOUT_MS',
40
+ FINALIZE_RESERVE_MS: 'SHARE_LINK_MAINTENANCE_FINALIZE_RESERVE_MS',
41
+ GRAPH_TIMEOUT_MS: 'SHARE_LINK_MAINTENANCE_GRAPH_TIMEOUT_MS',
42
+ } as const;
43
+
44
+ export const SHARE_LINK_MAINTENANCE_DEFAULTS = Object.freeze({
45
+ claimant: 'brain-share-link-maintenance',
46
+ recoveryLimit: SHARE_LINK_RECOVERY_DEFAULT_BATCH,
47
+ cleanupLimit: SHARE_LINK_CLEANUP_DEFAULT_BATCH,
48
+ receiptPruneLimit: 200,
49
+ leaseMs: SHARE_LINK_DEFAULT_LEASE_MS,
50
+ claimMs: SHARE_LINK_CLEANUP_DEFAULT_CLAIM_MS,
51
+ budgetMs: 60_000,
52
+ intervalMs: 300_000,
53
+ requestTimeoutMs: 10_000,
54
+ finalizeReserveMs: 5_000,
55
+ graphTimeoutMs: 15_000,
56
+ });
57
+
58
+ export const SHARE_LINK_MAINTENANCE_INVALID_CATEGORY =
59
+ 'share_link_maintenance_configuration_invalid' as const;
60
+
61
+ /**
62
+ * Transport/service-client portion of the share-content configuration.
63
+ *
64
+ * Owner/public APIs and maintenance use the same validated namespace, origin,
65
+ * and audience. No backend rollout flag is required.
66
+ */
67
+ export type ShareLinkServiceTransportConfig = {
68
+ namespace: string;
69
+ origin: string;
70
+ audience: string;
71
+ allowInsecureLoopback: boolean;
72
+ };
73
+
74
+ export type ShareLinkServiceTransportConfigResolution =
75
+ { status: 'enabled'; config: ShareLinkServiceTransportConfig } | { status: 'invalid' };
76
+
77
+ /** Whether any required service wiring has been supplied (empty deployment defaults are absent). */
78
+ export const hasShareLinkServiceTransportConfig = (source: Record<string, unknown>): boolean =>
79
+ [
80
+ SHARE_LINK_MAINTENANCE_ENV.NAMESPACE,
81
+ SHARE_LINK_MAINTENANCE_ENV.ORIGIN,
82
+ SHARE_LINK_MAINTENANCE_ENV.AUDIENCE,
83
+ ].some(key => source[key] !== undefined && source[key] !== null && source[key] !== '');
84
+
85
+ /**
86
+ * Validate service-client transport fields without echoing values or exceptions.
87
+ */
88
+ export const resolveShareLinkServiceTransportConfig = (
89
+ raw: unknown
90
+ ): ShareLinkServiceTransportConfigResolution => {
91
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
92
+ return { status: 'invalid' };
93
+ }
94
+
95
+ const source = raw as Record<string, unknown>;
96
+ const allowInsecureLoopback = parseDeliberateBoolean(
97
+ source[SHARE_LINK_MAINTENANCE_ENV.ALLOW_INSECURE_LOOPBACK]
98
+ );
99
+ if (allowInsecureLoopback === null) return { status: 'invalid' };
100
+ const insecureLoopbackAllowed = allowInsecureLoopback === true;
101
+
102
+ const origin = validateShareContentOrigin(
103
+ source[SHARE_LINK_MAINTENANCE_ENV.ORIGIN],
104
+ insecureLoopbackAllowed
105
+ );
106
+ if (!origin.ok) return { status: 'invalid' };
107
+
108
+ const namespace = source[SHARE_LINK_MAINTENANCE_ENV.NAMESPACE];
109
+ if (!isOpaqueIdentifier(namespace)) return { status: 'invalid' };
110
+
111
+ const audience = source[SHARE_LINK_MAINTENANCE_ENV.AUDIENCE];
112
+ if (typeof audience !== 'string' || !audience.startsWith('did:')) {
113
+ return { status: 'invalid' };
114
+ }
115
+
116
+ return {
117
+ status: 'enabled',
118
+ config: {
119
+ namespace,
120
+ origin: origin.origin,
121
+ audience,
122
+ allowInsecureLoopback: insecureLoopbackAllowed,
123
+ },
124
+ };
125
+ };
126
+
127
+ const OPAQUE_IDENTIFIER_RE = /^[A-Za-z0-9._~-]+$/;
128
+
129
+ const isOpaqueIdentifier = (value: unknown, maxLength = 128): value is string =>
130
+ typeof value === 'string' &&
131
+ value.length >= 1 &&
132
+ value.length <= maxLength &&
133
+ OPAQUE_IDENTIFIER_RE.test(value);
134
+
135
+ const MISSING = Symbol('missing');
136
+
137
+ /** Deliberate boolean parse: only booleans and the exact strings true/false. */
138
+ const parseDeliberateBoolean = (value: unknown): boolean | typeof MISSING | null => {
139
+ if (value === undefined || value === null || value === '') return MISSING;
140
+ if (typeof value === 'boolean') return value;
141
+ if (typeof value === 'string') {
142
+ const normalized = value.trim().toLowerCase();
143
+ if (normalized === 'true') return true;
144
+ if (normalized === 'false') return false;
145
+ }
146
+
147
+ return null;
148
+ };
149
+
150
+ type BoundedIntegerOptions = { minimum: number; maximum: number; fallback: number };
151
+
152
+ const parseBoundedInteger = (
153
+ value: unknown,
154
+ options: BoundedIntegerOptions
155
+ ): number | typeof MISSING | null => {
156
+ if (value === undefined || value === null || value === '') return MISSING;
157
+
158
+ let parsed: number;
159
+ if (typeof value === 'number') parsed = value;
160
+ else if (typeof value === 'string' && /^[0-9]+$/.test(value.trim()))
161
+ parsed = Number(value.trim());
162
+ else return null;
163
+
164
+ if (!Number.isSafeInteger(parsed) || parsed < options.minimum || parsed > options.maximum)
165
+ return null;
166
+
167
+ return parsed;
168
+ };
169
+
170
+ const invalid = (): ShareLinkMaintenanceConfigResolution => ({
171
+ status: 'invalid',
172
+ category: SHARE_LINK_MAINTENANCE_INVALID_CATEGORY,
173
+ });
174
+
175
+ /**
176
+ * Resolve maintenance configuration from a raw record (typically `process.env`).
177
+ * Never throws and never echoes a value.
178
+ */
179
+ export const resolveShareLinkMaintenanceConfig = (
180
+ raw: unknown
181
+ ): ShareLinkMaintenanceConfigResolution => {
182
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return invalid();
183
+
184
+ const source = raw as Record<string, unknown>;
185
+ if (!hasShareLinkServiceTransportConfig(source)) return { status: 'disabled' };
186
+
187
+ const transport = resolveShareLinkServiceTransportConfig(source);
188
+ if (transport.status !== 'enabled') return invalid();
189
+
190
+ const { namespace, origin, audience, allowInsecureLoopback } = transport.config;
191
+
192
+ const claimantValue = source[SHARE_LINK_MAINTENANCE_ENV.CLAIMANT];
193
+ const claimant =
194
+ claimantValue === undefined || claimantValue === ''
195
+ ? SHARE_LINK_MAINTENANCE_DEFAULTS.claimant
196
+ : claimantValue;
197
+ if (!isOpaqueIdentifier(claimant)) return invalid();
198
+
199
+ const numericFields: Array<[string, BoundedIntegerOptions]> = [
200
+ [
201
+ SHARE_LINK_MAINTENANCE_ENV.RECOVERY_LIMIT,
202
+ {
203
+ minimum: 1,
204
+ maximum: SHARE_LINK_RECOVERY_MAX_BATCH,
205
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.recoveryLimit,
206
+ },
207
+ ],
208
+ [
209
+ SHARE_LINK_MAINTENANCE_ENV.CLEANUP_LIMIT,
210
+ {
211
+ minimum: 1,
212
+ maximum: SHARE_LINK_CLEANUP_MAX_BATCH,
213
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.cleanupLimit,
214
+ },
215
+ ],
216
+ [
217
+ SHARE_LINK_MAINTENANCE_ENV.RECEIPT_PRUNE_LIMIT,
218
+ {
219
+ minimum: 1,
220
+ maximum: 1_000,
221
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.receiptPruneLimit,
222
+ },
223
+ ],
224
+ [
225
+ SHARE_LINK_MAINTENANCE_ENV.LEASE_MS,
226
+ {
227
+ minimum: 1_000,
228
+ maximum: 30 * 60 * 1000,
229
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.leaseMs,
230
+ },
231
+ ],
232
+ [
233
+ SHARE_LINK_MAINTENANCE_ENV.CLAIM_MS,
234
+ {
235
+ minimum: SHARE_LINK_CLEANUP_MIN_CLAIM_MS,
236
+ maximum: SHARE_LINK_CLEANUP_MAX_CLAIM_MS,
237
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.claimMs,
238
+ },
239
+ ],
240
+ [
241
+ SHARE_LINK_MAINTENANCE_ENV.BUDGET_MS,
242
+ {
243
+ minimum: 1_000,
244
+ maximum: 240_000,
245
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.budgetMs,
246
+ },
247
+ ],
248
+ [
249
+ SHARE_LINK_MAINTENANCE_ENV.INTERVAL_MS,
250
+ {
251
+ minimum: 1_000,
252
+ maximum: 60 * 60 * 1000,
253
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.intervalMs,
254
+ },
255
+ ],
256
+ [
257
+ SHARE_LINK_MAINTENANCE_ENV.REQUEST_TIMEOUT_MS,
258
+ {
259
+ minimum: 100,
260
+ maximum: 30_000,
261
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.requestTimeoutMs,
262
+ },
263
+ ],
264
+ [
265
+ SHARE_LINK_MAINTENANCE_ENV.FINALIZE_RESERVE_MS,
266
+ {
267
+ minimum: 100,
268
+ maximum: 120_000,
269
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.finalizeReserveMs,
270
+ },
271
+ ],
272
+ [
273
+ SHARE_LINK_MAINTENANCE_ENV.GRAPH_TIMEOUT_MS,
274
+ {
275
+ minimum: 100,
276
+ maximum: 120_000,
277
+ fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.graphTimeoutMs,
278
+ },
279
+ ],
280
+ ];
281
+
282
+ const resolved: Record<string, number> = {};
283
+ for (const [key, options] of numericFields) {
284
+ const parsed = parseBoundedInteger(source[key], options);
285
+ if (parsed === null) return invalid();
286
+ resolved[key] = parsed === MISSING ? options.fallback : parsed;
287
+ }
288
+
289
+ const budgetMs = resolved[SHARE_LINK_MAINTENANCE_ENV.BUDGET_MS] as number;
290
+ const finalizeReserveMs = resolved[SHARE_LINK_MAINTENANCE_ENV.FINALIZE_RESERVE_MS] as number;
291
+ if (finalizeReserveMs >= budgetMs) return invalid();
292
+
293
+ const config: ShareLinkMaintenanceConfig = {
294
+ namespace,
295
+ origin,
296
+ audience,
297
+ allowInsecureLoopback,
298
+ claimant,
299
+ recoveryLimit: resolved[SHARE_LINK_MAINTENANCE_ENV.RECOVERY_LIMIT] as number,
300
+ cleanupLimit: resolved[SHARE_LINK_MAINTENANCE_ENV.CLEANUP_LIMIT] as number,
301
+ receiptPruneLimit: resolved[SHARE_LINK_MAINTENANCE_ENV.RECEIPT_PRUNE_LIMIT] as number,
302
+ leaseMs: resolved[SHARE_LINK_MAINTENANCE_ENV.LEASE_MS] as number,
303
+ claimMs: resolved[SHARE_LINK_MAINTENANCE_ENV.CLAIM_MS] as number,
304
+ budgetMs,
305
+ intervalMs: resolved[SHARE_LINK_MAINTENANCE_ENV.INTERVAL_MS] as number,
306
+ requestTimeoutMs: resolved[SHARE_LINK_MAINTENANCE_ENV.REQUEST_TIMEOUT_MS] as number,
307
+ finalizeReserveMs,
308
+ graphTimeoutMs: resolved[SHARE_LINK_MAINTENANCE_ENV.GRAPH_TIMEOUT_MS] as number,
309
+ };
310
+
311
+ return { status: 'enabled', config };
312
+ };
@@ -0,0 +1,24 @@
1
+ export * from './types';
2
+ export {
3
+ SHARE_LINK_MAINTENANCE_DEFAULTS,
4
+ SHARE_LINK_MAINTENANCE_ENV,
5
+ SHARE_LINK_MAINTENANCE_INVALID_CATEGORY,
6
+ resolveShareLinkMaintenanceConfig,
7
+ } from './config';
8
+ export { createMaintenancePassBudget, type MaintenancePassBudget } from './budget';
9
+ export {
10
+ createConsoleMaintenanceLogger,
11
+ safeLogMaintenance,
12
+ toMaintenanceLogEvent,
13
+ } from './telemetry';
14
+ export { runShareLinkMaintenancePass, type ShareLinkMaintenanceRunnerDependencies } from './runner';
15
+ export {
16
+ createShareLinkMaintenanceScheduler,
17
+ type ShareLinkMaintenanceScheduler,
18
+ type ShareLinkMaintenanceSchedulerDependencies,
19
+ } from './scheduler';
20
+ export {
21
+ createShareLinkMaintenanceRuntime,
22
+ type CreateShareLinkMaintenanceRuntimeOptions,
23
+ type ShareLinkMaintenanceRuntime,
24
+ } from './runtime';