@stigmer/server 3.23.1-dev.20260923075205 → 3.25.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 (226) 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 +88 -5
  18. package/dist/boot/compose.js.map +1 -1
  19. package/dist/boot/route-shadowing.d.ts +25 -0
  20. package/dist/boot/route-shadowing.d.ts.map +1 -0
  21. package/dist/boot/route-shadowing.js +17 -0
  22. package/dist/boot/route-shadowing.js.map +1 -0
  23. package/dist/domain/iampolicy/membership.d.ts +6 -1
  24. package/dist/domain/iampolicy/membership.d.ts.map +1 -1
  25. package/dist/domain/iampolicy/membership.js +8 -2
  26. package/dist/domain/iampolicy/membership.js.map +1 -1
  27. package/dist/domain/identityaccount/constants.d.ts +13 -0
  28. package/dist/domain/identityaccount/constants.d.ts.map +1 -1
  29. package/dist/domain/identityaccount/constants.js +17 -0
  30. package/dist/domain/identityaccount/constants.js.map +1 -1
  31. package/dist/domain/identityaccount/controller.d.ts +3 -1
  32. package/dist/domain/identityaccount/controller.d.ts.map +1 -1
  33. package/dist/domain/identityaccount/controller.js +15 -6
  34. package/dist/domain/identityaccount/controller.js.map +1 -1
  35. package/dist/domain/identityaccount/operator.d.ts.map +1 -1
  36. package/dist/domain/identityaccount/operator.js +1 -0
  37. package/dist/domain/identityaccount/operator.js.map +1 -1
  38. package/dist/domain/identityaccount/provisioning.d.ts +18 -0
  39. package/dist/domain/identityaccount/provisioning.d.ts.map +1 -1
  40. package/dist/domain/identityaccount/provisioning.js +1 -0
  41. package/dist/domain/identityaccount/provisioning.js.map +1 -1
  42. package/dist/domain/identityaccount/resource-store.js +9 -5
  43. package/dist/domain/identityaccount/resource-store.js.map +1 -1
  44. package/dist/domain/identityaccount/steps.d.ts +11 -2
  45. package/dist/domain/identityaccount/steps.d.ts.map +1 -1
  46. package/dist/domain/identityaccount/steps.js +42 -4
  47. package/dist/domain/identityaccount/steps.js.map +1 -1
  48. package/dist/domain/identityaccount/store-contract.d.ts.map +1 -1
  49. package/dist/domain/identityaccount/store-contract.js +33 -0
  50. package/dist/domain/identityaccount/store-contract.js.map +1 -1
  51. package/dist/domain/identityaccount/store.d.ts +7 -5
  52. package/dist/domain/identityaccount/store.d.ts.map +1 -1
  53. package/dist/domain/identityaccount/store.js.map +1 -1
  54. package/dist/domain/platform/controller.d.ts +10 -0
  55. package/dist/domain/platform/controller.d.ts.map +1 -1
  56. package/dist/domain/platform/controller.js +2 -1
  57. package/dist/domain/platform/controller.js.map +1 -1
  58. package/dist/domain/platformclient/constants.d.ts +60 -0
  59. package/dist/domain/platformclient/constants.d.ts.map +1 -0
  60. package/dist/domain/platformclient/constants.js +78 -0
  61. package/dist/domain/platformclient/constants.js.map +1 -0
  62. package/dist/domain/platformclient/controller.d.ts +59 -0
  63. package/dist/domain/platformclient/controller.d.ts.map +1 -0
  64. package/dist/domain/platformclient/controller.js +191 -0
  65. package/dist/domain/platformclient/controller.js.map +1 -0
  66. package/dist/domain/platformclient/credentials.d.ts +13 -0
  67. package/dist/domain/platformclient/credentials.d.ts.map +1 -0
  68. package/dist/domain/platformclient/credentials.js +56 -0
  69. package/dist/domain/platformclient/credentials.js.map +1 -0
  70. package/dist/domain/platformclient/mint.d.ts +23 -0
  71. package/dist/domain/platformclient/mint.d.ts.map +1 -0
  72. package/dist/domain/platformclient/mint.js +254 -0
  73. package/dist/domain/platformclient/mint.js.map +1 -0
  74. package/dist/domain/platformclient/origin-guard.d.ts +9 -0
  75. package/dist/domain/platformclient/origin-guard.d.ts.map +1 -0
  76. package/dist/domain/platformclient/origin-guard.js +81 -0
  77. package/dist/domain/platformclient/origin-guard.js.map +1 -0
  78. package/dist/domain/platformclient/resource-store.d.ts +4 -0
  79. package/dist/domain/platformclient/resource-store.d.ts.map +1 -0
  80. package/dist/domain/platformclient/resource-store.js +117 -0
  81. package/dist/domain/platformclient/resource-store.js.map +1 -0
  82. package/dist/domain/platformclient/steps.d.ts +51 -0
  83. package/dist/domain/platformclient/steps.d.ts.map +1 -0
  84. package/dist/domain/platformclient/steps.js +339 -0
  85. package/dist/domain/platformclient/steps.js.map +1 -0
  86. package/dist/domain/platformclient/store-contract.d.ts +8 -0
  87. package/dist/domain/platformclient/store-contract.d.ts.map +1 -0
  88. package/dist/domain/platformclient/store-contract.js +208 -0
  89. package/dist/domain/platformclient/store-contract.js.map +1 -0
  90. package/dist/domain/platformclient/store.d.ts +58 -0
  91. package/dist/domain/platformclient/store.d.ts.map +1 -0
  92. package/dist/domain/platformclient/store.js +13 -0
  93. package/dist/domain/platformclient/store.js.map +1 -0
  94. package/dist/domain/platformclient/system-managed.d.ts +18 -0
  95. package/dist/domain/platformclient/system-managed.d.ts.map +1 -0
  96. package/dist/domain/platformclient/system-managed.js +80 -0
  97. package/dist/domain/platformclient/system-managed.js.map +1 -0
  98. package/dist/domain/platformclient/token-controller.d.ts +11 -0
  99. package/dist/domain/platformclient/token-controller.d.ts.map +1 -0
  100. package/dist/domain/platformclient/token-controller.js +32 -0
  101. package/dist/domain/platformclient/token-controller.js.map +1 -0
  102. package/dist/domain/platformclient/verifier.d.ts +10 -0
  103. package/dist/domain/platformclient/verifier.d.ts.map +1 -0
  104. package/dist/domain/platformclient/verifier.js +76 -0
  105. package/dist/domain/platformclient/verifier.js.map +1 -0
  106. package/dist/domain/workflow/agent-call-references.d.ts +60 -33
  107. package/dist/domain/workflow/agent-call-references.d.ts.map +1 -1
  108. package/dist/domain/workflow/agent-call-references.js +43 -23
  109. package/dist/domain/workflow/agent-call-references.js.map +1 -1
  110. package/dist/domain/workflow/registry/data/task-kind-registry.json +2 -2
  111. package/dist/encryption/key-manager.d.ts +20 -3
  112. package/dist/encryption/key-manager.d.ts.map +1 -1
  113. package/dist/encryption/key-manager.js +64 -42
  114. package/dist/encryption/key-manager.js.map +1 -1
  115. package/dist/extensions/caller-guards.d.ts +8 -3
  116. package/dist/extensions/caller-guards.d.ts.map +1 -1
  117. package/dist/extensions/drivers.d.ts +37 -0
  118. package/dist/extensions/drivers.d.ts.map +1 -1
  119. package/dist/extensions/guest-token-minting.d.ts +26 -0
  120. package/dist/extensions/guest-token-minting.d.ts.map +1 -0
  121. package/dist/extensions/guest-token-minting.js +2 -0
  122. package/dist/extensions/guest-token-minting.js.map +1 -0
  123. package/dist/extensions/identity.d.ts +6 -4
  124. package/dist/extensions/identity.d.ts.map +1 -1
  125. package/dist/extensions/identity.js.map +1 -1
  126. package/dist/extensions/registry.d.ts +30 -1
  127. package/dist/extensions/registry.d.ts.map +1 -1
  128. package/dist/extensions/registry.js +34 -1
  129. package/dist/extensions/registry.js.map +1 -1
  130. package/dist/index.d.ts +13 -1
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +6 -0
  133. package/dist/index.js.map +1 -1
  134. package/dist/pipeline/apiresource-labels.d.ts +10 -9
  135. package/dist/pipeline/apiresource-labels.d.ts.map +1 -1
  136. package/dist/pipeline/apiresource-labels.js +10 -9
  137. package/dist/pipeline/apiresource-labels.js.map +1 -1
  138. package/dist/pipeline/interceptors/auth.d.ts +14 -0
  139. package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
  140. package/dist/pipeline/interceptors/auth.js +24 -0
  141. package/dist/pipeline/interceptors/auth.js.map +1 -1
  142. package/dist/pipeline/steps/build-update-state.d.ts +11 -1
  143. package/dist/pipeline/steps/build-update-state.d.ts.map +1 -1
  144. package/dist/pipeline/steps/build-update-state.js +5 -2
  145. package/dist/pipeline/steps/build-update-state.js.map +1 -1
  146. package/dist/pipeline/steps/references.d.ts +30 -4
  147. package/dist/pipeline/steps/references.d.ts.map +1 -1
  148. package/dist/pipeline/steps/references.js +13 -1
  149. package/dist/pipeline/steps/references.js.map +1 -1
  150. package/dist/platformtoken/envelope.d.ts +100 -0
  151. package/dist/platformtoken/envelope.d.ts.map +1 -0
  152. package/dist/platformtoken/envelope.js +184 -0
  153. package/dist/platformtoken/envelope.js.map +1 -0
  154. package/dist/platformtoken/key-ring.d.ts +85 -0
  155. package/dist/platformtoken/key-ring.d.ts.map +1 -0
  156. package/dist/platformtoken/key-ring.js +164 -0
  157. package/dist/platformtoken/key-ring.js.map +1 -0
  158. package/package.json +6 -6
  159. package/src/authorization/README.md +1 -1
  160. package/src/authorization/__tests__/authorizer.test.ts +6 -2
  161. package/src/authorization/__tests__/wire-permissions.test.ts +1 -0
  162. package/src/authorization/authorizer.ts +11 -4
  163. package/src/authorization/model/__tests__/registry.test.ts +8 -1
  164. package/src/authorization/model/index.ts +6 -4
  165. package/src/authorization/model/oauth_app.ts +3 -2
  166. package/src/authorization/model/platform_client.ts +43 -0
  167. package/src/boot/__tests__/auth-enabled-composition.test.ts +2 -1
  168. package/src/boot/__tests__/route-shadowing.test.ts +67 -0
  169. package/src/boot/compose.ts +90 -5
  170. package/src/boot/route-shadowing.ts +47 -0
  171. package/src/domain/iampolicy/__tests__/membership.test.ts +7 -0
  172. package/src/domain/iampolicy/membership.ts +8 -2
  173. package/src/domain/identityaccount/__tests__/platform-client-accounts.test.ts +124 -0
  174. package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -0
  175. package/src/domain/identityaccount/constants.ts +20 -0
  176. package/src/domain/identityaccount/controller.ts +16 -4
  177. package/src/domain/identityaccount/operator.ts +1 -0
  178. package/src/domain/identityaccount/provisioning.ts +17 -0
  179. package/src/domain/identityaccount/resource-store.ts +9 -5
  180. package/src/domain/identityaccount/steps.ts +58 -3
  181. package/src/domain/identityaccount/store-contract.ts +51 -0
  182. package/src/domain/identityaccount/store.ts +7 -5
  183. package/src/domain/platform/__tests__/platform.test.ts +7 -1
  184. package/src/domain/platform/controller.ts +12 -1
  185. package/src/domain/platformclient/__tests__/controller.test.ts +397 -0
  186. package/src/domain/platformclient/__tests__/credentials.test.ts +46 -0
  187. package/src/domain/platformclient/__tests__/mint.test.ts +415 -0
  188. package/src/domain/platformclient/__tests__/resource-store.test.ts +140 -0
  189. package/src/domain/platformclient/__tests__/system-managed.test.ts +101 -0
  190. package/src/domain/platformclient/__tests__/verifier-and-guard.test.ts +207 -0
  191. package/src/domain/platformclient/constants.ts +120 -0
  192. package/src/domain/platformclient/controller.ts +449 -0
  193. package/src/domain/platformclient/credentials.ts +68 -0
  194. package/src/domain/platformclient/mint.ts +412 -0
  195. package/src/domain/platformclient/origin-guard.ts +117 -0
  196. package/src/domain/platformclient/resource-store.ts +150 -0
  197. package/src/domain/platformclient/steps.ts +472 -0
  198. package/src/domain/platformclient/store-contract.ts +318 -0
  199. package/src/domain/platformclient/store.ts +63 -0
  200. package/src/domain/platformclient/system-managed.ts +115 -0
  201. package/src/domain/platformclient/token-controller.ts +49 -0
  202. package/src/domain/platformclient/verifier.ts +106 -0
  203. package/src/domain/workflow/__tests__/agent-call-references.test.ts +178 -27
  204. package/src/domain/workflow/agent-call-references.ts +95 -48
  205. package/src/domain/workflow/registry/data/task-kind-registry.json +2 -2
  206. package/src/encryption/key-manager.ts +87 -44
  207. package/src/extensions/__tests__/extension-composition.test.ts +3 -2
  208. package/src/extensions/__tests__/platform-client-composed.test.ts +288 -0
  209. package/src/extensions/__tests__/registry.test.ts +4 -1
  210. package/src/extensions/__tests__/tier-truthfulness.test.ts +8 -0
  211. package/src/extensions/caller-guards.ts +8 -3
  212. package/src/extensions/drivers.ts +37 -0
  213. package/src/extensions/guest-token-minting.ts +32 -0
  214. package/src/extensions/identity.ts +6 -4
  215. package/src/extensions/registry.ts +77 -3
  216. package/src/index.ts +55 -0
  217. package/src/pipeline/apiresource-labels.ts +10 -9
  218. package/src/pipeline/interceptors/auth.ts +27 -0
  219. package/src/pipeline/steps/__tests__/references.test.ts +37 -1
  220. package/src/pipeline/steps/build-update-state.ts +5 -2
  221. package/src/pipeline/steps/references.ts +49 -5
  222. package/src/platformtoken/__tests__/envelope.test.ts +277 -0
  223. package/src/platformtoken/__tests__/key-ring.test.ts +205 -0
  224. package/src/platformtoken/envelope.ts +276 -0
  225. package/src/platformtoken/key-ring.ts +266 -0
  226. package/src/runnerauth/__tests__/runner-subject-composed.test.ts +9 -3
@@ -0,0 +1,51 @@
1
+ import type { DescMessage } from "@bufbuild/protobuf";
2
+ import type { ApiResourceReferenceSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
3
+ import type { PlatformClient } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
4
+ import { PlatformClientSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
5
+ import type { PipelineStep } from "../../pipeline/pipeline.js";
6
+ import type { RequestContext } from "../../pipeline/request-context.js";
7
+ import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
8
+ import { TARGET_RESOURCE_KEY } from "../../pipeline/steps/load-target.js";
9
+ import type { SystemManagedMutation } from "./constants.js";
10
+ import type { PlatformClientStore } from "./store.js";
11
+ type ClientStep = PipelineStep<typeof PlatformClientSchema>;
12
+ /** Context key for the plaintext secret the create and rotate responses show once. */
13
+ export declare const CLIENT_SECRET_PLAINTEXT_KEY = "platformClientSecretPlaintext";
14
+ /** Clears the stored hash in place and answers the client — every response goes through it. */
15
+ export declare function redactPlatformClient(client: PlatformClient): PlatformClient;
16
+ /** The plaintext secret a credential step parked, or an ordering fault. */
17
+ export declare function parkedClientSecret<Desc extends DescMessage>(ctx: RequestContext<Desc>): string;
18
+ export declare function newRefuseReservedSlugStep(): ClientStep;
19
+ /** Rejects a create whose slug the organization already holds. */
20
+ export declare function newCheckDuplicateStep(clients: PlatformClientStore): ClientStep;
21
+ /** Generates the credential fields after BuildNewState, parking the plaintext for the response. */
22
+ export declare function newGenerateClientCredentialsStep(): ClientStep;
23
+ /** Saves the new client through the port; a held slug or client_id is ALREADY_EXISTS. */
24
+ export declare function newPersistNewClientStep(clients: PlatformClientStore): ClientStep;
25
+ /** Loads the client by id, else by org-scoped slug (the id written back), into EXISTING_RESOURCE_KEY. */
26
+ export declare function newLoadExistingClientStep(clients: PlatformClientStore): ClientStep;
27
+ /** Restores the credential fields from the stored row after BuildUpdateState. */
28
+ export declare function newPreserveClientCredentialsStep(): ClientStep;
29
+ /** Replaces the row through the port. */
30
+ export declare function newPersistUpdatedClientStep(clients: PlatformClientStore): ClientStep;
31
+ /** Refuses a mutation of a client carrying the system-managed label, read from `key`. */
32
+ export declare function newRefuseSystemManagedStep<Desc extends DescMessage>(verb: SystemManagedMutation, key: typeof EXISTING_RESOURCE_KEY | typeof TARGET_RESOURCE_KEY): PipelineStep<Desc>;
33
+ /** Loads the client named by an ID-wrapper input into TARGET_RESOURCE_KEY. */
34
+ export declare function newLoadTargetClientStep<InputDesc extends DescMessage>(clients: PlatformClientStore): PipelineStep<InputDesc>;
35
+ /** Loads the client an org/slug reference names into TARGET_RESOURCE_KEY, with the cloud's copy. */
36
+ export declare function newLoadClientByReferenceStep(clients: PlatformClientStore): PipelineStep<typeof ApiResourceReferenceSchema>;
37
+ /**
38
+ * Replaces the loaded client's secret in place (the client_id is
39
+ * permanent), stamps the update audit as the caller, and parks the
40
+ * plaintext for the response. The expiry is left as it is: rotating a
41
+ * secret does not extend a client the owner set to expire.
42
+ */
43
+ export declare function newRotateClientCredentialsStep<InputDesc extends DescMessage>(): PipelineStep<InputDesc>;
44
+ /** Writes the rotated TARGET_RESOURCE_KEY client through the port. */
45
+ export declare function newPersistTargetClientStep<InputDesc extends DescMessage>(clients: PlatformClientStore): PipelineStep<InputDesc>;
46
+ export declare function newLoadExistingClientForDeleteStep<InputDesc extends DescMessage>(clients: PlatformClientStore): PipelineStep<InputDesc>;
47
+ export declare function newDeleteClientStep<InputDesc extends DescMessage>(clients: PlatformClientStore): PipelineStep<InputDesc>;
48
+ /** The client a load step stashed under `key`, or an ordering fault. */
49
+ export declare function storedClientOf<Desc extends DescMessage>(ctx: RequestContext<Desc>, key: string): PlatformClient;
50
+ export {};
51
+ //# sourceMappingURL=steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../../src/domain/platformclient/steps.ts"],"names":[],"mappings":"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"}
@@ -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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"}