@stigmer/server 3.24.0 → 3.26.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 (341) hide show
  1. package/dist/authorization/authorizer.d.ts +10 -4
  2. package/dist/authorization/authorizer.d.ts.map +1 -1
  3. package/dist/authorization/authorizer.js +11 -4
  4. package/dist/authorization/authorizer.js.map +1 -1
  5. package/dist/authorization/model/index.d.ts +4 -4
  6. package/dist/authorization/model/index.d.ts.map +1 -1
  7. package/dist/authorization/model/index.js +2 -0
  8. package/dist/authorization/model/index.js.map +1 -1
  9. package/dist/authorization/model/oauth_app.d.ts.map +1 -1
  10. package/dist/authorization/model/oauth_app.js +3 -2
  11. package/dist/authorization/model/oauth_app.js.map +1 -1
  12. package/dist/authorization/model/platform_client.d.ts +2 -0
  13. package/dist/authorization/model/platform_client.d.ts.map +1 -0
  14. package/dist/authorization/model/platform_client.js +31 -0
  15. package/dist/authorization/model/platform_client.js.map +1 -0
  16. package/dist/boot/compose.d.ts.map +1 -1
  17. package/dist/boot/compose.js +99 -13
  18. package/dist/boot/compose.js.map +1 -1
  19. package/dist/boot/list-indexes.d.ts +3 -0
  20. package/dist/boot/list-indexes.d.ts.map +1 -0
  21. package/dist/boot/list-indexes.js +24 -0
  22. package/dist/boot/list-indexes.js.map +1 -0
  23. package/dist/boot/route-shadowing.d.ts +25 -0
  24. package/dist/boot/route-shadowing.d.ts.map +1 -0
  25. package/dist/boot/route-shadowing.js +17 -0
  26. package/dist/boot/route-shadowing.js.map +1 -0
  27. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  28. package/dist/domain/agentexecution/controller.js +6 -8
  29. package/dist/domain/agentexecution/controller.js.map +1 -1
  30. package/dist/domain/agentexecution/list-index.d.ts +2 -0
  31. package/dist/domain/agentexecution/list-index.d.ts.map +1 -0
  32. package/dist/domain/agentexecution/list-index.js +23 -0
  33. package/dist/domain/agentexecution/list-index.js.map +1 -0
  34. package/dist/domain/agentexecution/steps.d.ts +17 -33
  35. package/dist/domain/agentexecution/steps.d.ts.map +1 -1
  36. package/dist/domain/agentexecution/steps.js +94 -95
  37. package/dist/domain/agentexecution/steps.js.map +1 -1
  38. package/dist/domain/agentexecution/usage.d.ts.map +1 -1
  39. package/dist/domain/agentexecution/usage.js +37 -14
  40. package/dist/domain/agentexecution/usage.js.map +1 -1
  41. package/dist/domain/artifact/controller.d.ts.map +1 -1
  42. package/dist/domain/artifact/controller.js +27 -15
  43. package/dist/domain/artifact/controller.js.map +1 -1
  44. package/dist/domain/artifact/list-index.d.ts +2 -0
  45. package/dist/domain/artifact/list-index.d.ts.map +1 -0
  46. package/dist/domain/artifact/list-index.js +21 -0
  47. package/dist/domain/artifact/list-index.js.map +1 -0
  48. package/dist/domain/iampolicy/membership.d.ts +6 -1
  49. package/dist/domain/iampolicy/membership.d.ts.map +1 -1
  50. package/dist/domain/iampolicy/membership.js +8 -2
  51. package/dist/domain/iampolicy/membership.js.map +1 -1
  52. package/dist/domain/identityaccount/constants.d.ts +13 -0
  53. package/dist/domain/identityaccount/constants.d.ts.map +1 -1
  54. package/dist/domain/identityaccount/constants.js +17 -0
  55. package/dist/domain/identityaccount/constants.js.map +1 -1
  56. package/dist/domain/identityaccount/controller.d.ts +3 -1
  57. package/dist/domain/identityaccount/controller.d.ts.map +1 -1
  58. package/dist/domain/identityaccount/controller.js +15 -6
  59. package/dist/domain/identityaccount/controller.js.map +1 -1
  60. package/dist/domain/identityaccount/operator.d.ts.map +1 -1
  61. package/dist/domain/identityaccount/operator.js +1 -0
  62. package/dist/domain/identityaccount/operator.js.map +1 -1
  63. package/dist/domain/identityaccount/provisioning.d.ts +18 -0
  64. package/dist/domain/identityaccount/provisioning.d.ts.map +1 -1
  65. package/dist/domain/identityaccount/provisioning.js +1 -0
  66. package/dist/domain/identityaccount/provisioning.js.map +1 -1
  67. package/dist/domain/identityaccount/resource-store.js +9 -5
  68. package/dist/domain/identityaccount/resource-store.js.map +1 -1
  69. package/dist/domain/identityaccount/steps.d.ts +11 -2
  70. package/dist/domain/identityaccount/steps.d.ts.map +1 -1
  71. package/dist/domain/identityaccount/steps.js +42 -4
  72. package/dist/domain/identityaccount/steps.js.map +1 -1
  73. package/dist/domain/identityaccount/store-contract.d.ts.map +1 -1
  74. package/dist/domain/identityaccount/store-contract.js +33 -0
  75. package/dist/domain/identityaccount/store-contract.js.map +1 -1
  76. package/dist/domain/identityaccount/store.d.ts +7 -5
  77. package/dist/domain/identityaccount/store.d.ts.map +1 -1
  78. package/dist/domain/identityaccount/store.js.map +1 -1
  79. package/dist/domain/platform/controller.d.ts +10 -0
  80. package/dist/domain/platform/controller.d.ts.map +1 -1
  81. package/dist/domain/platform/controller.js +2 -1
  82. package/dist/domain/platform/controller.js.map +1 -1
  83. package/dist/domain/platformclient/constants.d.ts +60 -0
  84. package/dist/domain/platformclient/constants.d.ts.map +1 -0
  85. package/dist/domain/platformclient/constants.js +78 -0
  86. package/dist/domain/platformclient/constants.js.map +1 -0
  87. package/dist/domain/platformclient/controller.d.ts +59 -0
  88. package/dist/domain/platformclient/controller.d.ts.map +1 -0
  89. package/dist/domain/platformclient/controller.js +191 -0
  90. package/dist/domain/platformclient/controller.js.map +1 -0
  91. package/dist/domain/platformclient/credentials.d.ts +13 -0
  92. package/dist/domain/platformclient/credentials.d.ts.map +1 -0
  93. package/dist/domain/platformclient/credentials.js +56 -0
  94. package/dist/domain/platformclient/credentials.js.map +1 -0
  95. package/dist/domain/platformclient/mint.d.ts +23 -0
  96. package/dist/domain/platformclient/mint.d.ts.map +1 -0
  97. package/dist/domain/platformclient/mint.js +254 -0
  98. package/dist/domain/platformclient/mint.js.map +1 -0
  99. package/dist/domain/platformclient/origin-guard.d.ts +9 -0
  100. package/dist/domain/platformclient/origin-guard.d.ts.map +1 -0
  101. package/dist/domain/platformclient/origin-guard.js +81 -0
  102. package/dist/domain/platformclient/origin-guard.js.map +1 -0
  103. package/dist/domain/platformclient/resource-store.d.ts +4 -0
  104. package/dist/domain/platformclient/resource-store.d.ts.map +1 -0
  105. package/dist/domain/platformclient/resource-store.js +117 -0
  106. package/dist/domain/platformclient/resource-store.js.map +1 -0
  107. package/dist/domain/platformclient/steps.d.ts +51 -0
  108. package/dist/domain/platformclient/steps.d.ts.map +1 -0
  109. package/dist/domain/platformclient/steps.js +339 -0
  110. package/dist/domain/platformclient/steps.js.map +1 -0
  111. package/dist/domain/platformclient/store-contract.d.ts +8 -0
  112. package/dist/domain/platformclient/store-contract.d.ts.map +1 -0
  113. package/dist/domain/platformclient/store-contract.js +208 -0
  114. package/dist/domain/platformclient/store-contract.js.map +1 -0
  115. package/dist/domain/platformclient/store.d.ts +58 -0
  116. package/dist/domain/platformclient/store.d.ts.map +1 -0
  117. package/dist/domain/platformclient/store.js +13 -0
  118. package/dist/domain/platformclient/store.js.map +1 -0
  119. package/dist/domain/platformclient/system-managed.d.ts +18 -0
  120. package/dist/domain/platformclient/system-managed.d.ts.map +1 -0
  121. package/dist/domain/platformclient/system-managed.js +80 -0
  122. package/dist/domain/platformclient/system-managed.js.map +1 -0
  123. package/dist/domain/platformclient/token-controller.d.ts +11 -0
  124. package/dist/domain/platformclient/token-controller.d.ts.map +1 -0
  125. package/dist/domain/platformclient/token-controller.js +32 -0
  126. package/dist/domain/platformclient/token-controller.js.map +1 -0
  127. package/dist/domain/platformclient/verifier.d.ts +10 -0
  128. package/dist/domain/platformclient/verifier.d.ts.map +1 -0
  129. package/dist/domain/platformclient/verifier.js +76 -0
  130. package/dist/domain/platformclient/verifier.js.map +1 -0
  131. package/dist/domain/session/list-index.d.ts +4 -0
  132. package/dist/domain/session/list-index.d.ts.map +1 -0
  133. package/dist/domain/session/list-index.js +26 -0
  134. package/dist/domain/session/list-index.js.map +1 -0
  135. package/dist/domain/session/steps.d.ts +7 -8
  136. package/dist/domain/session/steps.d.ts.map +1 -1
  137. package/dist/domain/session/steps.js +76 -78
  138. package/dist/domain/session/steps.js.map +1 -1
  139. package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
  140. package/dist/domain/workflowexecution/controller.js +53 -55
  141. package/dist/domain/workflowexecution/controller.js.map +1 -1
  142. package/dist/domain/workflowexecution/execution-filter.d.ts +4 -0
  143. package/dist/domain/workflowexecution/execution-filter.d.ts.map +1 -1
  144. package/dist/domain/workflowexecution/execution-filter.js +11 -5
  145. package/dist/domain/workflowexecution/execution-filter.js.map +1 -1
  146. package/dist/domain/workflowexecution/get-execution-summary.d.ts.map +1 -1
  147. package/dist/domain/workflowexecution/get-execution-summary.js +23 -17
  148. package/dist/domain/workflowexecution/get-execution-summary.js.map +1 -1
  149. package/dist/domain/workflowexecution/list-index.d.ts +2 -0
  150. package/dist/domain/workflowexecution/list-index.d.ts.map +1 -0
  151. package/dist/domain/workflowexecution/list-index.js +21 -0
  152. package/dist/domain/workflowexecution/list-index.js.map +1 -0
  153. package/dist/domain/workflowexecution/list-pending-approvals.d.ts.map +1 -1
  154. package/dist/domain/workflowexecution/list-pending-approvals.js +69 -32
  155. package/dist/domain/workflowexecution/list-pending-approvals.js.map +1 -1
  156. package/dist/domain/workflowexecution/queries.d.ts +30 -4
  157. package/dist/domain/workflowexecution/queries.d.ts.map +1 -1
  158. package/dist/domain/workflowexecution/queries.js +76 -22
  159. package/dist/domain/workflowexecution/queries.js.map +1 -1
  160. package/dist/encryption/key-manager.d.ts +20 -3
  161. package/dist/encryption/key-manager.d.ts.map +1 -1
  162. package/dist/encryption/key-manager.js +64 -42
  163. package/dist/encryption/key-manager.js.map +1 -1
  164. package/dist/extensions/caller-guards.d.ts +8 -3
  165. package/dist/extensions/caller-guards.d.ts.map +1 -1
  166. package/dist/extensions/drivers.d.ts +37 -0
  167. package/dist/extensions/drivers.d.ts.map +1 -1
  168. package/dist/extensions/guest-token-minting.d.ts +26 -0
  169. package/dist/extensions/guest-token-minting.d.ts.map +1 -0
  170. package/dist/extensions/guest-token-minting.js +2 -0
  171. package/dist/extensions/guest-token-minting.js.map +1 -0
  172. package/dist/extensions/identity.d.ts +6 -4
  173. package/dist/extensions/identity.d.ts.map +1 -1
  174. package/dist/extensions/identity.js.map +1 -1
  175. package/dist/extensions/list-read-scope.d.ts +9 -12
  176. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  177. package/dist/extensions/list-read-scope.js.map +1 -1
  178. package/dist/extensions/registry.d.ts +30 -1
  179. package/dist/extensions/registry.d.ts.map +1 -1
  180. package/dist/extensions/registry.js +34 -1
  181. package/dist/extensions/registry.js.map +1 -1
  182. package/dist/index.d.ts +15 -2
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.js +6 -0
  185. package/dist/index.js.map +1 -1
  186. package/dist/pipeline/interceptors/auth.d.ts +14 -0
  187. package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
  188. package/dist/pipeline/interceptors/auth.js +24 -0
  189. package/dist/pipeline/interceptors/auth.js.map +1 -1
  190. package/dist/pipeline/steps/build-update-state.d.ts +11 -1
  191. package/dist/pipeline/steps/build-update-state.d.ts.map +1 -1
  192. package/dist/pipeline/steps/build-update-state.js +5 -2
  193. package/dist/pipeline/steps/build-update-state.js.map +1 -1
  194. package/dist/pipeline/steps/list-page.d.ts +63 -0
  195. package/dist/pipeline/steps/list-page.d.ts.map +1 -0
  196. package/dist/pipeline/steps/list-page.js +187 -0
  197. package/dist/pipeline/steps/list-page.js.map +1 -0
  198. package/dist/platformtoken/envelope.d.ts +100 -0
  199. package/dist/platformtoken/envelope.d.ts.map +1 -0
  200. package/dist/platformtoken/envelope.js +184 -0
  201. package/dist/platformtoken/envelope.js.map +1 -0
  202. package/dist/platformtoken/key-ring.d.ts +85 -0
  203. package/dist/platformtoken/key-ring.d.ts.map +1 -0
  204. package/dist/platformtoken/key-ring.js +164 -0
  205. package/dist/platformtoken/key-ring.js.map +1 -0
  206. package/dist/query/activity/handler.d.ts +6 -7
  207. package/dist/query/activity/handler.d.ts.map +1 -1
  208. package/dist/query/activity/handler.js +42 -59
  209. package/dist/query/activity/handler.js.map +1 -1
  210. package/dist/store/interface.d.ts +29 -0
  211. package/dist/store/interface.d.ts.map +1 -1
  212. package/dist/store/interface.js.map +1 -1
  213. package/dist/store/list-index.d.ts +123 -0
  214. package/dist/store/list-index.d.ts.map +1 -0
  215. package/dist/store/list-index.js +277 -0
  216. package/dist/store/list-index.js.map +1 -0
  217. package/dist/store/logger.d.ts +3 -0
  218. package/dist/store/logger.d.ts.map +1 -1
  219. package/dist/store/logger.js +5 -1
  220. package/dist/store/logger.js.map +1 -1
  221. package/dist/store/postgres/migrations.d.ts +10 -6
  222. package/dist/store/postgres/migrations.d.ts.map +1 -1
  223. package/dist/store/postgres/migrations.js +64 -6
  224. package/dist/store/postgres/migrations.js.map +1 -1
  225. package/dist/store/postgres/store.d.ts +26 -5
  226. package/dist/store/postgres/store.d.ts.map +1 -1
  227. package/dist/store/postgres/store.js +377 -22
  228. package/dist/store/postgres/store.js.map +1 -1
  229. package/dist/store/sqlite/migrations.d.ts +11 -5
  230. package/dist/store/sqlite/migrations.d.ts.map +1 -1
  231. package/dist/store/sqlite/migrations.js +50 -4
  232. package/dist/store/sqlite/migrations.js.map +1 -1
  233. package/dist/store/sqlite/store.d.ts +18 -3
  234. package/dist/store/sqlite/store.d.ts.map +1 -1
  235. package/dist/store/sqlite/store.js +321 -15
  236. package/dist/store/sqlite/store.js.map +1 -1
  237. package/package.json +6 -6
  238. package/src/authorization/README.md +1 -1
  239. package/src/authorization/__tests__/authorizer.test.ts +6 -2
  240. package/src/authorization/__tests__/drivers.ts +6 -1
  241. package/src/authorization/__tests__/wire-permissions.test.ts +1 -0
  242. package/src/authorization/authorizer.ts +11 -4
  243. package/src/authorization/model/__tests__/registry.test.ts +8 -1
  244. package/src/authorization/model/index.ts +6 -4
  245. package/src/authorization/model/oauth_app.ts +3 -2
  246. package/src/authorization/model/platform_client.ts +43 -0
  247. package/src/boot/__tests__/auth-enabled-composition.test.ts +2 -1
  248. package/src/boot/__tests__/list-indexes.test.ts +65 -0
  249. package/src/boot/__tests__/route-shadowing.test.ts +67 -0
  250. package/src/boot/compose.ts +113 -18
  251. package/src/boot/list-indexes.ts +25 -0
  252. package/src/boot/route-shadowing.ts +47 -0
  253. package/src/domain/agentexecution/__tests__/agentexecution.test.ts +85 -3
  254. package/src/domain/agentexecution/controller.ts +8 -10
  255. package/src/domain/agentexecution/list-index.ts +24 -0
  256. package/src/domain/agentexecution/steps.ts +118 -115
  257. package/src/domain/agentexecution/usage.ts +38 -17
  258. package/src/domain/artifact/controller.ts +28 -18
  259. package/src/domain/artifact/list-index.ts +22 -0
  260. package/src/domain/iampolicy/__tests__/membership.test.ts +7 -0
  261. package/src/domain/iampolicy/membership.ts +8 -2
  262. package/src/domain/identityaccount/__tests__/platform-client-accounts.test.ts +124 -0
  263. package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -0
  264. package/src/domain/identityaccount/constants.ts +20 -0
  265. package/src/domain/identityaccount/controller.ts +16 -4
  266. package/src/domain/identityaccount/operator.ts +1 -0
  267. package/src/domain/identityaccount/provisioning.ts +17 -0
  268. package/src/domain/identityaccount/resource-store.ts +9 -5
  269. package/src/domain/identityaccount/steps.ts +58 -3
  270. package/src/domain/identityaccount/store-contract.ts +51 -0
  271. package/src/domain/identityaccount/store.ts +7 -5
  272. package/src/domain/platform/__tests__/platform.test.ts +7 -1
  273. package/src/domain/platform/controller.ts +12 -1
  274. package/src/domain/platformclient/__tests__/controller.test.ts +397 -0
  275. package/src/domain/platformclient/__tests__/credentials.test.ts +46 -0
  276. package/src/domain/platformclient/__tests__/mint.test.ts +415 -0
  277. package/src/domain/platformclient/__tests__/resource-store.test.ts +140 -0
  278. package/src/domain/platformclient/__tests__/system-managed.test.ts +101 -0
  279. package/src/domain/platformclient/__tests__/verifier-and-guard.test.ts +207 -0
  280. package/src/domain/platformclient/constants.ts +120 -0
  281. package/src/domain/platformclient/controller.ts +449 -0
  282. package/src/domain/platformclient/credentials.ts +68 -0
  283. package/src/domain/platformclient/mint.ts +412 -0
  284. package/src/domain/platformclient/origin-guard.ts +117 -0
  285. package/src/domain/platformclient/resource-store.ts +150 -0
  286. package/src/domain/platformclient/steps.ts +472 -0
  287. package/src/domain/platformclient/store-contract.ts +318 -0
  288. package/src/domain/platformclient/store.ts +63 -0
  289. package/src/domain/platformclient/system-managed.ts +115 -0
  290. package/src/domain/platformclient/token-controller.ts +49 -0
  291. package/src/domain/platformclient/verifier.ts +106 -0
  292. package/src/domain/session/list-index.ts +28 -0
  293. package/src/domain/session/steps.ts +108 -123
  294. package/src/domain/workflowexecution/__tests__/list-read-scope-summaries.test.ts +155 -99
  295. package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +193 -31
  296. package/src/domain/workflowexecution/controller.ts +54 -82
  297. package/src/domain/workflowexecution/execution-filter.ts +20 -7
  298. package/src/domain/workflowexecution/get-execution-summary.ts +31 -24
  299. package/src/domain/workflowexecution/list-index.ts +22 -0
  300. package/src/domain/workflowexecution/list-pending-approvals.ts +82 -25
  301. package/src/domain/workflowexecution/queries.ts +134 -23
  302. package/src/encryption/key-manager.ts +87 -44
  303. package/src/extensions/__tests__/extension-composition.test.ts +3 -2
  304. package/src/extensions/__tests__/platform-client-composed.test.ts +288 -0
  305. package/src/extensions/__tests__/registry.test.ts +4 -1
  306. package/src/extensions/__tests__/tier-truthfulness.test.ts +8 -0
  307. package/src/extensions/caller-guards.ts +8 -3
  308. package/src/extensions/drivers.ts +37 -0
  309. package/src/extensions/guest-token-minting.ts +32 -0
  310. package/src/extensions/identity.ts +6 -4
  311. package/src/extensions/list-read-scope.ts +9 -12
  312. package/src/extensions/registry.ts +77 -3
  313. package/src/index.ts +65 -1
  314. package/src/pipeline/interceptors/auth.ts +27 -0
  315. package/src/pipeline/steps/__tests__/list-page.test.ts +186 -0
  316. package/src/pipeline/steps/__tests__/references.test.ts +2 -0
  317. package/src/pipeline/steps/build-update-state.ts +5 -2
  318. package/src/pipeline/steps/list-page.ts +284 -0
  319. package/src/platformtoken/__tests__/envelope.test.ts +277 -0
  320. package/src/platformtoken/__tests__/key-ring.test.ts +205 -0
  321. package/src/platformtoken/envelope.ts +276 -0
  322. package/src/platformtoken/key-ring.ts +266 -0
  323. package/src/query/activity/handler.ts +57 -78
  324. package/src/runnerauth/__tests__/runner-subject-composed.test.ts +9 -3
  325. package/src/store/README.md +51 -32
  326. package/src/store/__tests__/list-index.measure.test.ts +293 -0
  327. package/src/store/__tests__/list-index.test.ts +328 -0
  328. package/src/store/__tests__/store-contract.ts +346 -3
  329. package/src/store/interface.ts +39 -0
  330. package/src/store/list-index.ts +465 -0
  331. package/src/store/logger.ts +8 -1
  332. package/src/store/postgres/__tests__/list-index-repair.test.ts +133 -0
  333. package/src/store/postgres/__tests__/migrations.test.ts +27 -19
  334. package/src/store/postgres/__tests__/store-contract.test.ts +50 -3
  335. package/src/store/postgres/migrations.ts +69 -7
  336. package/src/store/postgres/store.ts +485 -29
  337. package/src/store/sqlite/__tests__/migrations.test.ts +51 -7
  338. package/src/store/sqlite/__tests__/store-contract.test.ts +70 -16
  339. package/src/store/sqlite/__tests__/support.ts +12 -3
  340. package/src/store/sqlite/migrations.ts +57 -6
  341. package/src/store/sqlite/store.ts +462 -21
@@ -0,0 +1,339 @@
1
+ /**
2
+ * Platform-client domain steps.
3
+ *
4
+ * The domain's persistence is a PORT (store.ts), so the shared steps that
5
+ * touch storage (CheckDuplicate, LoadExisting, LoadTarget, LoadByReference,
6
+ * Persist, the delete pair) come here under the SAME names over the port —
7
+ * the identity-account domain's "own step, same name" precedent — and every
8
+ * storage-free shared step is reused as it is. The shared context keys are
9
+ * reused too, so BuildUpdateState finds EXISTING_RESOURCE_KEY and the
10
+ * reference read's AuthorizeResolvedTarget finds TARGET_RESOURCE_KEY where
11
+ * they expect them.
12
+ *
13
+ * The domain's own rules:
14
+ * - RefuseReservedSlug: `system-share-client` is the platform's (the
15
+ * cloud keeps each organization's system-managed share client under
16
+ * it, created through its driver, never through this chain), refused
17
+ * after ResolveSlug so a derived slug is refused too.
18
+ * - RefuseSystemManaged: a client carrying the reserved
19
+ * `stigmer.ai/system-managed` label is the platform's; update, delete
20
+ * and rotate refuse it FAILED_PRECONDITION with the cloud's copy.
21
+ * - GenerateClientCredentials, PreserveClientCredentials and
22
+ * RotateClientCredentials: the credential fields are the server's
23
+ * alone — generated on create (whatever the request carried), kept
24
+ * from the stored row on update, replaced (secret only; the client_id
25
+ * is permanent) on rotate. The plaintext secret is parked in the
26
+ * context for the one response that shows it, never persisted.
27
+ * - redactPlatformClient: the stored hash leaves on no response. It is
28
+ * cleared rather than marked (OAuthApp's `***REDACTED***` marker exists
29
+ * because its secret round-trips on update; this hash never does —
30
+ * PreserveClientCredentials restores it from the row).
31
+ *
32
+ * Not-found answers use the shared `notFoundError`, which renders exactly
33
+ * the cloud's `PlatformClient not found: <id>`; the reference read keeps
34
+ * the cloud's own sentence (constants.ts).
35
+ */
36
+ import { Code, ConnectError } from "@connectrpc/connect";
37
+ import { create } from "@bufbuild/protobuf";
38
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
39
+ import { PlatformClientSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
40
+ import { PlatformClientSpecSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/spec_pb";
41
+ import { RESERVED_LABEL_TRUE, SYSTEM_MANAGED_LABEL, } from "../../pipeline/apiresource-labels.js";
42
+ import { alreadyExistsError, failedPreconditionError, internalError, invalidArgumentError, notFoundError, } from "../../pipeline/errors.js";
43
+ import { updateAuditFields } from "../../pipeline/steps/build-update-state.js";
44
+ import { RESOURCE_ID_KEY } from "../../pipeline/steps/delete.js";
45
+ import { requireOrgForReference } from "../../pipeline/steps/helpers.js";
46
+ import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
47
+ import { TARGET_RESOURCE_KEY } from "../../pipeline/steps/load-target.js";
48
+ import { idValueOf, metadataOf } from "../../pipeline/steps/shapes.js";
49
+ import { PLATFORM_CLIENT_KIND_NAME, RESERVED_PLATFORM_CLIENT_SLUGS, referenceNotFoundMessage, reservedSlugMessage, systemManagedMessage, } from "./constants.js";
50
+ import { generateClientId, generateClientSecret, hashClientSecret, secretFingerprint, } from "./credentials.js";
51
+ import { DuplicatePlatformClientError } from "./store.js";
52
+ /** Context key for the plaintext secret the create and rotate responses show once. */
53
+ export const CLIENT_SECRET_PLAINTEXT_KEY = "platformClientSecretPlaintext";
54
+ /** Clears the stored hash in place and answers the client — every response goes through it. */
55
+ export function redactPlatformClient(client) {
56
+ if (client.spec !== undefined) {
57
+ client.spec.clientSecretHash = "";
58
+ }
59
+ return client;
60
+ }
61
+ /** The plaintext secret a credential step parked, or an ordering fault. */
62
+ export function parkedClientSecret(ctx) {
63
+ const secret = ctx.get(CLIENT_SECRET_PLAINTEXT_KEY);
64
+ if (typeof secret !== "string" || secret === "") {
65
+ throw internalError(new Error("no client secret parked — a credential step must run first"), "platform client credentials");
66
+ }
67
+ return secret;
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Create
71
+ // ---------------------------------------------------------------------------
72
+ export function newRefuseReservedSlugStep() {
73
+ return {
74
+ name: "RefuseReservedSlug",
75
+ execute(ctx) {
76
+ const slug = metadataOf(ctx.newState)?.slug ?? "";
77
+ if (RESERVED_PLATFORM_CLIENT_SLUGS.has(slug)) {
78
+ throw invalidArgumentError(reservedSlugMessage(slug));
79
+ }
80
+ },
81
+ };
82
+ }
83
+ /** Rejects a create whose slug the organization already holds. */
84
+ export function newCheckDuplicateStep(clients) {
85
+ return {
86
+ name: "CheckDuplicate",
87
+ async execute(ctx) {
88
+ const metadata = requireMetadata(ctx, "duplicate check");
89
+ const existing = await clients.findByOrgAndSlug(metadata.org, metadata.slug);
90
+ if (existing !== undefined) {
91
+ throw alreadyExistsError(PLATFORM_CLIENT_KIND_NAME, `slug '${metadata.slug}' in org '${metadata.org}' (id: ${existing.metadata?.id ?? ""})`);
92
+ }
93
+ },
94
+ };
95
+ }
96
+ /** Generates the credential fields after BuildNewState, parking the plaintext for the response. */
97
+ export function newGenerateClientCredentialsStep() {
98
+ return {
99
+ name: "GenerateClientCredentials",
100
+ execute(ctx) {
101
+ const spec = specOf(ctx.newState);
102
+ const secret = generateClientSecret();
103
+ spec.clientId = generateClientId();
104
+ spec.clientSecretHash = hashClientSecret(secret);
105
+ spec.secretFingerprint = secretFingerprint(secret);
106
+ ctx.set(CLIENT_SECRET_PLAINTEXT_KEY, secret);
107
+ },
108
+ };
109
+ }
110
+ /** Saves the new client through the port; a held slug or client_id is ALREADY_EXISTS. */
111
+ export function newPersistNewClientStep(clients) {
112
+ return {
113
+ name: "Persist",
114
+ async execute(ctx) {
115
+ try {
116
+ await clients.save(ctx.newState);
117
+ }
118
+ catch (error) {
119
+ if (error instanceof DuplicatePlatformClientError) {
120
+ // The race the duplicate check could not see.
121
+ const metadata = requireMetadata(ctx, "persist");
122
+ throw alreadyExistsError(PLATFORM_CLIENT_KIND_NAME, `slug '${metadata.slug}' in org '${metadata.org}'`);
123
+ }
124
+ throw internalError(error, "failed to save platform client");
125
+ }
126
+ },
127
+ };
128
+ }
129
+ // ---------------------------------------------------------------------------
130
+ // Update
131
+ // ---------------------------------------------------------------------------
132
+ /** Loads the client by id, else by org-scoped slug (the id written back), into EXISTING_RESOURCE_KEY. */
133
+ export function newLoadExistingClientStep(clients) {
134
+ return {
135
+ name: "LoadExisting",
136
+ async execute(ctx) {
137
+ const metadata = requireMetadata(ctx, "load existing");
138
+ let existing;
139
+ if (metadata.id !== "") {
140
+ existing = await clients.findById(metadata.id);
141
+ if (existing === undefined) {
142
+ throw notFoundError(PLATFORM_CLIENT_KIND_NAME, metadata.id);
143
+ }
144
+ }
145
+ else if (metadata.slug !== "") {
146
+ existing = await clients.findByOrgAndSlug(metadata.org, metadata.slug);
147
+ if (existing === undefined) {
148
+ throw notFoundError(PLATFORM_CLIENT_KIND_NAME, metadata.slug);
149
+ }
150
+ metadata.id = existing.metadata?.id ?? "";
151
+ }
152
+ else {
153
+ throw invalidArgumentError("resource id or slug is required for update");
154
+ }
155
+ ctx.set(EXISTING_RESOURCE_KEY, existing);
156
+ },
157
+ };
158
+ }
159
+ /** Restores the credential fields from the stored row after BuildUpdateState. */
160
+ export function newPreserveClientCredentialsStep() {
161
+ return {
162
+ name: "PreserveClientCredentials",
163
+ execute(ctx) {
164
+ const existing = storedClientOf(ctx, EXISTING_RESOURCE_KEY);
165
+ const spec = specOf(ctx.newState);
166
+ spec.clientId = existing.spec?.clientId ?? "";
167
+ spec.clientSecretHash = existing.spec?.clientSecretHash ?? "";
168
+ spec.secretFingerprint = existing.spec?.secretFingerprint ?? "";
169
+ },
170
+ };
171
+ }
172
+ /** Replaces the row through the port. */
173
+ export function newPersistUpdatedClientStep(clients) {
174
+ return {
175
+ name: "Persist",
176
+ async execute(ctx) {
177
+ try {
178
+ await clients.update(ctx.newState);
179
+ }
180
+ catch (error) {
181
+ throw internalError(error, "failed to save platform client");
182
+ }
183
+ },
184
+ };
185
+ }
186
+ // ---------------------------------------------------------------------------
187
+ // Update, delete and rotate: the platform's own clients
188
+ // ---------------------------------------------------------------------------
189
+ /** Refuses a mutation of a client carrying the system-managed label, read from `key`. */
190
+ export function newRefuseSystemManagedStep(verb, key) {
191
+ return {
192
+ name: "RefuseSystemManaged",
193
+ execute(ctx) {
194
+ const client = storedClientOf(ctx, key);
195
+ if (client.metadata?.labels[SYSTEM_MANAGED_LABEL] === RESERVED_LABEL_TRUE) {
196
+ throw failedPreconditionError(systemManagedMessage(verb));
197
+ }
198
+ },
199
+ };
200
+ }
201
+ // ---------------------------------------------------------------------------
202
+ // Get, getByReference, rotate
203
+ // ---------------------------------------------------------------------------
204
+ /** Loads the client named by an ID-wrapper input into TARGET_RESOURCE_KEY. */
205
+ export function newLoadTargetClientStep(clients) {
206
+ return {
207
+ name: "LoadTarget",
208
+ async execute(ctx) {
209
+ const id = idValueOf(ctx.input);
210
+ if (id === "") {
211
+ throw invalidArgumentError("resource id is required");
212
+ }
213
+ ctx.set(TARGET_RESOURCE_KEY, await readClient(clients, id));
214
+ },
215
+ };
216
+ }
217
+ /** Loads the client an org/slug reference names into TARGET_RESOURCE_KEY, with the cloud's copy. */
218
+ export function newLoadClientByReferenceStep(clients) {
219
+ return {
220
+ name: "LoadByReference",
221
+ async execute(ctx) {
222
+ const ref = ctx.input;
223
+ if (ref.slug === "") {
224
+ throw invalidArgumentError("slug is required in reference");
225
+ }
226
+ if (ref.kind !== ApiResourceKind.api_resource_kind_unknown &&
227
+ ref.kind !== ApiResourceKind.platform_client) {
228
+ throw invalidArgumentError(`kind mismatch: expected platform_client, got ${ApiResourceKind[ref.kind] ?? String(ref.kind)}`);
229
+ }
230
+ requireOrgForReference(ApiResourceKind.platform_client, ref.org);
231
+ const client = await clients.findByOrgAndSlug(ref.org, ref.slug);
232
+ if (client === undefined) {
233
+ throw new ConnectError(referenceNotFoundMessage(ref.org, ref.slug), Code.NotFound);
234
+ }
235
+ ctx.set(TARGET_RESOURCE_KEY, client);
236
+ },
237
+ };
238
+ }
239
+ /**
240
+ * Replaces the loaded client's secret in place (the client_id is
241
+ * permanent), stamps the update audit as the caller, and parks the
242
+ * plaintext for the response. The expiry is left as it is: rotating a
243
+ * secret does not extend a client the owner set to expire.
244
+ */
245
+ export function newRotateClientCredentialsStep() {
246
+ return {
247
+ name: "RotateClientCredentials",
248
+ execute(ctx) {
249
+ const client = storedClientOf(ctx, TARGET_RESOURCE_KEY);
250
+ const spec = specOf(client);
251
+ const secret = generateClientSecret();
252
+ spec.clientSecretHash = hashClientSecret(secret);
253
+ spec.secretFingerprint = secretFingerprint(secret);
254
+ // The row is its own "existing": the creation stamp is read before
255
+ // the fresh audit block replaces it.
256
+ updateAuditFields(PlatformClientSchema, client, client, ctx.callerIdentity);
257
+ ctx.set(CLIENT_SECRET_PLAINTEXT_KEY, secret);
258
+ },
259
+ };
260
+ }
261
+ /** Writes the rotated TARGET_RESOURCE_KEY client through the port. */
262
+ export function newPersistTargetClientStep(clients) {
263
+ return {
264
+ name: "Persist",
265
+ async execute(ctx) {
266
+ try {
267
+ await clients.update(storedClientOf(ctx, TARGET_RESOURCE_KEY));
268
+ }
269
+ catch (error) {
270
+ throw internalError(error, "failed to save platform client");
271
+ }
272
+ },
273
+ };
274
+ }
275
+ // ---------------------------------------------------------------------------
276
+ // Delete (ApiResourceDeleteInput; the handler sets RESOURCE_ID_KEY)
277
+ // ---------------------------------------------------------------------------
278
+ export function newLoadExistingClientForDeleteStep(clients) {
279
+ return {
280
+ name: "LoadExistingForDelete",
281
+ async execute(ctx) {
282
+ ctx.set(EXISTING_RESOURCE_KEY, await readClient(clients, requireResourceId(ctx)));
283
+ },
284
+ };
285
+ }
286
+ export function newDeleteClientStep(clients) {
287
+ return {
288
+ name: "DeleteResource",
289
+ async execute(ctx) {
290
+ try {
291
+ await clients.deleteById(requireResourceId(ctx));
292
+ }
293
+ catch (error) {
294
+ throw internalError(error, "failed to delete platform client");
295
+ }
296
+ },
297
+ };
298
+ }
299
+ // ---------------------------------------------------------------------------
300
+ // Shared readers
301
+ // ---------------------------------------------------------------------------
302
+ /** The client by id, or the shared NOT_FOUND; any other fault propagates. */
303
+ async function readClient(clients, id) {
304
+ const client = await clients.findById(id);
305
+ if (client === undefined) {
306
+ throw notFoundError(PLATFORM_CLIENT_KIND_NAME, id);
307
+ }
308
+ return client;
309
+ }
310
+ /** The client a load step stashed under `key`, or an ordering fault. */
311
+ export function storedClientOf(ctx, key) {
312
+ const client = ctx.get(key);
313
+ if (client === undefined) {
314
+ throw internalError(new Error(`no platform client under '${key}' — its load step must run first`), "platform client chain ordering");
315
+ }
316
+ return client;
317
+ }
318
+ function requireMetadata(ctx, operation) {
319
+ const metadata = metadataOf(ctx.newState);
320
+ if (metadata === undefined) {
321
+ throw internalError(new Error("platform client metadata is nil"), operation);
322
+ }
323
+ return metadata;
324
+ }
325
+ /** The client's spec, created in place when the caller omitted it (every field defaults). */
326
+ function specOf(client) {
327
+ if (client.spec === undefined) {
328
+ client.spec = create(PlatformClientSpecSchema);
329
+ }
330
+ return client.spec;
331
+ }
332
+ function requireResourceId(ctx) {
333
+ const id = ctx.get(RESOURCE_ID_KEY);
334
+ if (typeof id !== "string" || id === "") {
335
+ throw internalError(new Error("resource id not found in context (the delete handler sets it)"), "platform client delete ordering");
336
+ }
337
+ return id;
338
+ }
339
+ //# sourceMappingURL=steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../../src/domain/platformclient/steps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { PortContractCase, PortContractFixture } from "../../store/port-contract.js";
2
+ import type { PlatformClientStore } from "./store.js";
3
+ /** The runner's fixture over this port — the name a driver's test and the barrel know it by. */
4
+ export type PlatformClientStoreContractFixture = PortContractFixture<PlatformClientStore>;
5
+ export type PlatformClientStoreContractCase = PortContractCase;
6
+ /** The port's cases over `makeFixture`, one fresh fixture per case. */
7
+ export declare function platformClientStoreContract(makeFixture: () => Promise<PlatformClientStoreContractFixture>): ReadonlyArray<PlatformClientStoreContractCase>;
8
+ //# sourceMappingURL=store-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-contract.d.ts","sourceRoot":"","sources":["../../../src/domain/platformclient/store-contract.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EACV,gBAAgB,EAEhB,mBAAmB,EACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,gGAAgG;AAChG,MAAM,MAAM,kCAAkC,GAC5C,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;AAE3C,MAAM,MAAM,+BAA+B,GAAG,gBAAgB,CAAC;AA2Q/D,uEAAuE;AACvE,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,OAAO,CAAC,kCAAkC,CAAC,GAC7D,aAAa,CAAC,+BAA+B,CAAC,CAEhD"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * The PlatformClientStore PORT-CONTRACT KIT: every behavior an
3
+ * implementation of store.ts must satisfy identically, as cases a driver's
4
+ * test iterates. Open source runs them over its own adapter
5
+ * (resource-store.ts) on sqlite and Postgres in
6
+ * __tests__/resource-store.test.ts; a composition runs the SAME cases over
7
+ * the store it registers as `drivers.platformClientStore` (the cloud's
8
+ * `cloud.iam_platform_client` store), so "the port holds" is one statement
9
+ * proven per driver, never restated per repository.
10
+ *
11
+ * Shape: declarations over the port-contract runner (store/port-contract.ts),
12
+ * which owns the fresh fixture per case, the cleanup, and the reason the
13
+ * kit returns cases instead of calling vitest's `describe`. The
14
+ * disconnected-store case matters most here: the verifier reads this port
15
+ * on every request a minted token bears, so an outage that read as "no
16
+ * client" would revoke every live token instead of failing loudly.
17
+ *
18
+ * The duplicate arms check `instanceof DuplicatePlatformClientError` on the
19
+ * exported class, because that is how the create chain's Persist step
20
+ * catches it: a driver throwing a lookalike fails here for the reason it
21
+ * would fail a create.
22
+ *
23
+ * Case names are the contract lines, in the port's words. The OSS test pins
24
+ * the full list, so a case cannot drop out of the kit unnoticed.
25
+ */
26
+ import assert from "node:assert/strict";
27
+ import { create, equals } from "@bufbuild/protobuf";
28
+ import { PlatformClientSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
29
+ import { portContractCases } from "../../store/port-contract.js";
30
+ import { DuplicatePlatformClientError } from "./store.js";
31
+ /** A client as the domain writes it; each fixture names its own id, org, slug and client_id. */
32
+ function platformClient(fields) {
33
+ return create(PlatformClientSchema, {
34
+ apiVersion: "iam.stigmer.ai/v1",
35
+ kind: "PlatformClient",
36
+ metadata: {
37
+ id: fields.id,
38
+ name: fields.slug,
39
+ slug: fields.slug,
40
+ org: fields.org,
41
+ },
42
+ spec: {
43
+ clientId: fields.clientId,
44
+ clientSecretHash: `hash-of-${fields.clientId}`,
45
+ secretFingerprint: "abcdef",
46
+ autoProvisionAccounts: true,
47
+ allowedOrigins: fields.allowedOrigins ?? [],
48
+ },
49
+ });
50
+ }
51
+ function assertSameClient(actual, expected, message) {
52
+ assert.ok(actual !== undefined, `${message}: no client was answered`);
53
+ assert.ok(equals(PlatformClientSchema, actual, expected), message);
54
+ }
55
+ async function assertDuplicate(write, message) {
56
+ await assert.rejects(write, (error) => error instanceof DuplicatePlatformClientError, message);
57
+ }
58
+ const ACME_DASHBOARD = platformClient({
59
+ id: "pcl_contract_acme_dashboard",
60
+ org: "acme",
61
+ slug: "dashboard",
62
+ clientId: "stgm_cid_contract_acme_dashboard",
63
+ });
64
+ const CASES = [
65
+ [
66
+ "save then findById, findByClientId and findByOrgAndSlug answer the saved client",
67
+ async ({ store }) => {
68
+ await store.save(ACME_DASHBOARD);
69
+ assertSameClient(await store.findById("pcl_contract_acme_dashboard"), ACME_DASHBOARD, "findById must answer the saved row");
70
+ assertSameClient(await store.findByClientId("stgm_cid_contract_acme_dashboard"), ACME_DASHBOARD, "findByClientId must answer the saved row");
71
+ assertSameClient(await store.findByOrgAndSlug("acme", "dashboard"), ACME_DASHBOARD, "findByOrgAndSlug must answer the saved row");
72
+ },
73
+ ],
74
+ [
75
+ "lookups of a client that is not held answer undefined",
76
+ async ({ store }) => {
77
+ await store.save(ACME_DASHBOARD);
78
+ assert.equal(await store.findById("pcl_contract_nobody"), undefined);
79
+ assert.equal(await store.findByClientId("stgm_cid_contract_nobody"), undefined);
80
+ assert.equal(await store.findByOrgAndSlug("acme", "nobody"), undefined);
81
+ assert.equal(await store.findByOrgAndSlug("globex", "dashboard"), undefined, "a slug is scoped to its organization: another org's lookup must miss");
82
+ },
83
+ ],
84
+ [
85
+ "save under a held id raises DuplicatePlatformClientError",
86
+ async ({ store }) => {
87
+ await store.save(ACME_DASHBOARD);
88
+ await assertDuplicate(store.save(platformClient({
89
+ id: "pcl_contract_acme_dashboard",
90
+ org: "acme",
91
+ slug: "other",
92
+ clientId: "stgm_cid_contract_other",
93
+ })), "a held id must be refused, never overwritten");
94
+ },
95
+ ],
96
+ [
97
+ "save under a held (org, slug) raises DuplicatePlatformClientError",
98
+ async ({ store }) => {
99
+ await store.save(ACME_DASHBOARD);
100
+ await assertDuplicate(store.save(platformClient({
101
+ id: "pcl_contract_acme_second",
102
+ org: "acme",
103
+ slug: "dashboard",
104
+ clientId: "stgm_cid_contract_acme_second",
105
+ })), "a held (org, slug) must be refused");
106
+ },
107
+ ],
108
+ [
109
+ "save under a held client_id raises DuplicatePlatformClientError",
110
+ async ({ store }) => {
111
+ await store.save(ACME_DASHBOARD);
112
+ await assertDuplicate(store.save(platformClient({
113
+ id: "pcl_contract_acme_third",
114
+ org: "acme",
115
+ slug: "third",
116
+ clientId: "stgm_cid_contract_acme_dashboard",
117
+ })), "a held client_id must be refused: the mint resolves a client by it");
118
+ },
119
+ ],
120
+ [
121
+ "the same slug in another organization is a different client",
122
+ async ({ store }) => {
123
+ await store.save(ACME_DASHBOARD);
124
+ const globex = platformClient({
125
+ id: "pcl_contract_globex_dashboard",
126
+ org: "globex",
127
+ slug: "dashboard",
128
+ clientId: "stgm_cid_contract_globex_dashboard",
129
+ });
130
+ await store.save(globex);
131
+ assertSameClient(await store.findByOrgAndSlug("globex", "dashboard"), globex, "each organization answers its own client for the shared slug");
132
+ },
133
+ ],
134
+ [
135
+ "update replaces the row in place",
136
+ async ({ store }) => {
137
+ await store.save(ACME_DASHBOARD);
138
+ const edited = platformClient({
139
+ id: "pcl_contract_acme_dashboard",
140
+ org: "acme",
141
+ slug: "dashboard",
142
+ clientId: "stgm_cid_contract_acme_dashboard",
143
+ allowedOrigins: ["https://app.acme.example"],
144
+ });
145
+ await store.update(edited);
146
+ assertSameClient(await store.findById("pcl_contract_acme_dashboard"), edited, "findById must answer the replaced row");
147
+ assertSameClient(await store.findByClientId("stgm_cid_contract_acme_dashboard"), edited, "findByClientId must answer the replaced row");
148
+ },
149
+ ],
150
+ [
151
+ "update of an unknown id writes nothing",
152
+ async ({ store }) => {
153
+ await store.update(ACME_DASHBOARD);
154
+ assert.equal(await store.findById("pcl_contract_acme_dashboard"), undefined, "update must replace, never create");
155
+ },
156
+ ],
157
+ [
158
+ "deleteById frees the id, the client_id and the slug; deleting an unknown id resolves",
159
+ async ({ store }) => {
160
+ await store.save(ACME_DASHBOARD);
161
+ await store.deleteById("pcl_contract_acme_dashboard");
162
+ assert.equal(await store.findById("pcl_contract_acme_dashboard"), undefined);
163
+ assert.equal(await store.findByClientId("stgm_cid_contract_acme_dashboard"), undefined, "a deleted client's client_id must stop resolving: the mint and the verifier read it");
164
+ assert.equal(await store.findByOrgAndSlug("acme", "dashboard"), undefined);
165
+ await store.save(ACME_DASHBOARD);
166
+ await store.deleteById("pcl_contract_nobody");
167
+ },
168
+ ],
169
+ [
170
+ "findByOrg answers every client of the organization and no other",
171
+ async ({ store }) => {
172
+ await store.save(ACME_DASHBOARD);
173
+ await store.save(platformClient({
174
+ id: "pcl_contract_acme_mobile",
175
+ org: "acme",
176
+ slug: "mobile",
177
+ clientId: "stgm_cid_contract_acme_mobile",
178
+ }));
179
+ await store.save(platformClient({
180
+ id: "pcl_contract_globex_dashboard",
181
+ org: "globex",
182
+ slug: "dashboard",
183
+ clientId: "stgm_cid_contract_globex_dashboard",
184
+ }));
185
+ const ids = (await store.findByOrg("acme"))
186
+ .map((client) => client.metadata?.id ?? "")
187
+ .sort();
188
+ assert.deepEqual(ids, [
189
+ "pcl_contract_acme_dashboard",
190
+ "pcl_contract_acme_mobile",
191
+ ]);
192
+ assert.deepEqual(await store.findByOrg("initech"), []);
193
+ },
194
+ ],
195
+ [
196
+ "a disconnected store is an infrastructure fault, never 'not found'",
197
+ async (fixture) => {
198
+ await fixture.disconnect();
199
+ await assert.rejects(fixture.store.findById("pcl_contract_acme_dashboard"), "an id read on a disconnected store must reject: on the verifier's path 'not found' revokes every token");
200
+ await assert.rejects(fixture.store.findByClientId("stgm_cid_contract_acme_dashboard"), "a client_id read on a disconnected store must reject, never read as undefined");
201
+ },
202
+ ],
203
+ ];
204
+ /** The port's cases over `makeFixture`, one fresh fixture per case. */
205
+ export function platformClientStoreContract(makeFixture) {
206
+ return portContractCases(CASES, makeFixture);
207
+ }
208
+ //# sourceMappingURL=store-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-contract.js","sourceRoot":"","sources":["../../../src/domain/platformclient/store-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The PlatformClientStore PORT: the storage contract the platform-client
3
+ * domain writes and reads through, so the cloud serves the same chains
4
+ * over its own `cloud.iam_platform_client` table by registering an
5
+ * implementation as `drivers.platformClientStore` (the identity-account
6
+ * and IamPolicy precedent: a port for an IAM kind whose rows an edition
7
+ * keeps in its own table). Open source's implementation is
8
+ * resource-store.ts over the generic Store.
9
+ *
10
+ * The methods are exactly the lookups the domain asks: by id (every
11
+ * chain, and the verifier's liveness read), by client_id (the mint), by
12
+ * org-scoped slug (getByReference, update addressed by slug, the
13
+ * duplicate check), by organization (listByOrg). A port carries nothing
14
+ * only one edition calls.
15
+ *
16
+ * Contract every implementation must satisfy — proven by the port-contract
17
+ * kit (store-contract.ts, exported), which the OSS adapter's test iterates
18
+ * on both drivers and a composition's driver test iterates too:
19
+ * - `save` is create-only in effect: a held id, a held (org, slug) or a
20
+ * held client_id raises DuplicatePlatformClientError, never a silent
21
+ * overwrite;
22
+ * - `update` replaces by id and never creates: an unknown id writes
23
+ * nothing;
24
+ * - `deleteById` of an unknown id resolves;
25
+ * - `findByOrg` answers every client of the organization and no other,
26
+ * in no promised order (the chain sorts);
27
+ * - a typed not-found reads as `undefined`; any other storage failure
28
+ * propagates as the infrastructure fault it is (the ratified
29
+ * store-fault mapping — an outage must never read as "no client", which
30
+ * on the verifier's path would revoke every live token).
31
+ */
32
+ import type { PlatformClient } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
33
+ /**
34
+ * Raised by `save` when the id, the (org, slug) pair or the client_id is
35
+ * already held, so the create chain answers ALREADY_EXISTS. `cause`
36
+ * carries a driver's own error (the cloud's SQLSTATE 23505) for the logs;
37
+ * the message is the port's.
38
+ */
39
+ export declare class DuplicatePlatformClientError extends Error {
40
+ constructor(message: string, options?: {
41
+ cause?: unknown;
42
+ });
43
+ }
44
+ export interface PlatformClientStore {
45
+ /** Insert; a held id, (org, slug) or client_id raises DuplicatePlatformClientError. */
46
+ save(client: PlatformClient): Promise<void>;
47
+ /** Full-row replace by id; an unknown id writes nothing. */
48
+ update(client: PlatformClient): Promise<void>;
49
+ /** Removes the row; no error when it does not exist. */
50
+ deleteById(id: string): Promise<void>;
51
+ findById(id: string): Promise<PlatformClient | undefined>;
52
+ /** The client holding this public identifier — the mint's lookup. */
53
+ findByClientId(clientId: string): Promise<PlatformClient | undefined>;
54
+ findByOrgAndSlug(org: string, slug: string): Promise<PlatformClient | undefined>;
55
+ /** Every client of the organization, in no promised order. */
56
+ findByOrg(org: string): Promise<ReadonlyArray<PlatformClient>>;
57
+ }
58
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/domain/platformclient/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yDAAyD,CAAC;AAE9F;;;;;GAKG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,MAAM,WAAW,mBAAmB;IAClC,uFAAuF;IACvF,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,4DAA4D;IAC5D,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC1D,qEAAqE;IACrE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACtE,gBAAgB,CACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACvC,8DAA8D;IAC9D,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;CAChE"}