@soulcraft/sdk 1.6.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/client/create-client-sdk.d.ts +16 -2
  2. package/dist/client/create-client-sdk.d.ts.map +1 -1
  3. package/dist/client/create-client-sdk.js +2 -7
  4. package/dist/client/create-client-sdk.js.map +1 -1
  5. package/dist/client/index.d.ts +48 -37
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +61 -42
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/client/namespace-proxy.d.ts +108 -0
  10. package/dist/client/namespace-proxy.d.ts.map +1 -0
  11. package/dist/client/namespace-proxy.js +151 -0
  12. package/dist/client/namespace-proxy.js.map +1 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/modules/app-context/index.d.ts +214 -0
  17. package/dist/modules/app-context/index.d.ts.map +1 -0
  18. package/dist/modules/app-context/index.js +569 -0
  19. package/dist/modules/app-context/index.js.map +1 -0
  20. package/dist/modules/auth/products.d.ts +208 -0
  21. package/dist/modules/auth/products.d.ts.map +1 -0
  22. package/dist/modules/auth/products.js +165 -0
  23. package/dist/modules/auth/products.js.map +1 -0
  24. package/dist/namespaces.d.ts +2942 -0
  25. package/dist/namespaces.d.ts.map +1 -0
  26. package/dist/namespaces.js +37 -0
  27. package/dist/namespaces.js.map +1 -0
  28. package/dist/rpc.d.ts +156 -0
  29. package/dist/rpc.d.ts.map +1 -0
  30. package/dist/rpc.js +26 -0
  31. package/dist/rpc.js.map +1 -0
  32. package/dist/server/create-sdk.d.ts.map +1 -1
  33. package/dist/server/create-sdk.js +3 -13
  34. package/dist/server/create-sdk.js.map +1 -1
  35. package/dist/server/handlers/annotations.d.ts +52 -0
  36. package/dist/server/handlers/annotations.d.ts.map +1 -0
  37. package/dist/server/handlers/annotations.js +204 -0
  38. package/dist/server/handlers/annotations.js.map +1 -0
  39. package/dist/server/handlers/auth.d.ts +53 -0
  40. package/dist/server/handlers/auth.d.ts.map +1 -0
  41. package/dist/server/handlers/auth.js +66 -0
  42. package/dist/server/handlers/auth.js.map +1 -0
  43. package/dist/server/handlers/certification.d.ts +32 -0
  44. package/dist/server/handlers/certification.d.ts.map +1 -0
  45. package/dist/server/handlers/certification.js +253 -0
  46. package/dist/server/handlers/certification.js.map +1 -0
  47. package/dist/server/handlers/chat/conversations.d.ts +91 -0
  48. package/dist/server/handlers/chat/conversations.d.ts.map +1 -0
  49. package/dist/server/handlers/chat/conversations.js +314 -0
  50. package/dist/server/handlers/chat/conversations.js.map +1 -0
  51. package/dist/server/handlers/chat/delegator.d.ts +144 -0
  52. package/dist/server/handlers/chat/delegator.d.ts.map +1 -0
  53. package/dist/server/handlers/chat/delegator.js +431 -0
  54. package/dist/server/handlers/chat/delegator.js.map +1 -0
  55. package/dist/server/handlers/chat/engine.d.ts +81 -0
  56. package/dist/server/handlers/chat/engine.d.ts.map +1 -0
  57. package/dist/server/handlers/chat/engine.js +442 -0
  58. package/dist/server/handlers/chat/engine.js.map +1 -0
  59. package/dist/server/handlers/chat/executor.d.ts +65 -0
  60. package/dist/server/handlers/chat/executor.d.ts.map +1 -0
  61. package/dist/server/handlers/chat/executor.js +375 -0
  62. package/dist/server/handlers/chat/executor.js.map +1 -0
  63. package/dist/server/handlers/chat/index.d.ts +62 -0
  64. package/dist/server/handlers/chat/index.d.ts.map +1 -0
  65. package/dist/server/handlers/chat/index.js +182 -0
  66. package/dist/server/handlers/chat/index.js.map +1 -0
  67. package/dist/server/handlers/chat/memory.d.ts +91 -0
  68. package/dist/server/handlers/chat/memory.d.ts.map +1 -0
  69. package/dist/server/handlers/chat/memory.js +293 -0
  70. package/dist/server/handlers/chat/memory.js.map +1 -0
  71. package/dist/server/handlers/chat/models.d.ts +180 -0
  72. package/dist/server/handlers/chat/models.d.ts.map +1 -0
  73. package/dist/server/handlers/chat/models.js +304 -0
  74. package/dist/server/handlers/chat/models.js.map +1 -0
  75. package/dist/server/handlers/chat/planner.d.ts +116 -0
  76. package/dist/server/handlers/chat/planner.d.ts.map +1 -0
  77. package/dist/server/handlers/chat/planner.js +344 -0
  78. package/dist/server/handlers/chat/planner.js.map +1 -0
  79. package/dist/server/handlers/chat/types.d.ts +500 -0
  80. package/dist/server/handlers/chat/types.d.ts.map +1 -0
  81. package/dist/server/handlers/chat/types.js +11 -0
  82. package/dist/server/handlers/chat/types.js.map +1 -0
  83. package/dist/server/handlers/collections.d.ts +67 -0
  84. package/dist/server/handlers/collections.d.ts.map +1 -0
  85. package/dist/server/handlers/collections.js +484 -0
  86. package/dist/server/handlers/collections.js.map +1 -0
  87. package/dist/server/handlers/commerce.d.ts +106 -0
  88. package/dist/server/handlers/commerce.d.ts.map +1 -0
  89. package/dist/server/handlers/commerce.js +62 -0
  90. package/dist/server/handlers/commerce.js.map +1 -0
  91. package/dist/server/handlers/config.d.ts +112 -0
  92. package/dist/server/handlers/config.d.ts.map +1 -0
  93. package/dist/server/handlers/config.js +122 -0
  94. package/dist/server/handlers/config.js.map +1 -0
  95. package/dist/server/handlers/export.d.ts +72 -0
  96. package/dist/server/handlers/export.d.ts.map +1 -0
  97. package/dist/server/handlers/export.js +175 -0
  98. package/dist/server/handlers/export.js.map +1 -0
  99. package/dist/server/handlers/formats.d.ts +77 -0
  100. package/dist/server/handlers/formats.d.ts.map +1 -0
  101. package/dist/server/handlers/formats.js +65 -0
  102. package/dist/server/handlers/formats.js.map +1 -0
  103. package/dist/server/handlers/graph.d.ts +31 -0
  104. package/dist/server/handlers/graph.d.ts.map +1 -0
  105. package/dist/server/handlers/graph.js +490 -0
  106. package/dist/server/handlers/graph.js.map +1 -0
  107. package/dist/server/handlers/import.d.ts +96 -0
  108. package/dist/server/handlers/import.d.ts.map +1 -0
  109. package/dist/server/handlers/import.js +108 -0
  110. package/dist/server/handlers/import.js.map +1 -0
  111. package/dist/server/handlers/index.d.ts +68 -0
  112. package/dist/server/handlers/index.d.ts.map +1 -0
  113. package/dist/server/handlers/index.js +71 -0
  114. package/dist/server/handlers/index.js.map +1 -0
  115. package/dist/server/handlers/media.d.ts +76 -0
  116. package/dist/server/handlers/media.d.ts.map +1 -0
  117. package/dist/server/handlers/media.js +53 -0
  118. package/dist/server/handlers/media.js.map +1 -0
  119. package/dist/server/handlers/project.d.ts +45 -0
  120. package/dist/server/handlers/project.d.ts.map +1 -0
  121. package/dist/server/handlers/project.js +181 -0
  122. package/dist/server/handlers/project.js.map +1 -0
  123. package/dist/server/handlers/publish.d.ts +102 -0
  124. package/dist/server/handlers/publish.d.ts.map +1 -0
  125. package/dist/server/handlers/publish.js +130 -0
  126. package/dist/server/handlers/publish.js.map +1 -0
  127. package/dist/server/handlers/pulse.d.ts +39 -0
  128. package/dist/server/handlers/pulse.d.ts.map +1 -0
  129. package/dist/server/handlers/pulse.js +78 -0
  130. package/dist/server/handlers/pulse.js.map +1 -0
  131. package/dist/server/handlers/realtime.d.ts +55 -0
  132. package/dist/server/handlers/realtime.d.ts.map +1 -0
  133. package/dist/server/handlers/realtime.js +49 -0
  134. package/dist/server/handlers/realtime.js.map +1 -0
  135. package/dist/server/handlers/search.d.ts +21 -0
  136. package/dist/server/handlers/search.d.ts.map +1 -0
  137. package/dist/server/handlers/search.js +237 -0
  138. package/dist/server/handlers/search.js.map +1 -0
  139. package/dist/server/handlers/session.d.ts +47 -0
  140. package/dist/server/handlers/session.d.ts.map +1 -0
  141. package/dist/server/handlers/session.js +286 -0
  142. package/dist/server/handlers/session.js.map +1 -0
  143. package/dist/server/handlers/settings.d.ts +97 -0
  144. package/dist/server/handlers/settings.d.ts.map +1 -0
  145. package/dist/server/handlers/settings.js +131 -0
  146. package/dist/server/handlers/settings.js.map +1 -0
  147. package/dist/server/handlers/workspace.d.ts +78 -0
  148. package/dist/server/handlers/workspace.d.ts.map +1 -0
  149. package/dist/server/handlers/workspace.js +270 -0
  150. package/dist/server/handlers/workspace.js.map +1 -0
  151. package/dist/server/hono-router.d.ts +66 -0
  152. package/dist/server/hono-router.d.ts.map +1 -0
  153. package/dist/server/hono-router.js +203 -0
  154. package/dist/server/hono-router.js.map +1 -0
  155. package/dist/server/index.d.ts +29 -19
  156. package/dist/server/index.d.ts.map +1 -1
  157. package/dist/server/index.js +33 -19
  158. package/dist/server/index.js.map +1 -1
  159. package/dist/server/namespace-router.d.ts +204 -0
  160. package/dist/server/namespace-router.d.ts.map +1 -0
  161. package/dist/server/namespace-router.js +262 -0
  162. package/dist/server/namespace-router.js.map +1 -0
  163. package/dist/transports/http-namespace.d.ts +210 -0
  164. package/dist/transports/http-namespace.d.ts.map +1 -0
  165. package/dist/transports/http-namespace.js +514 -0
  166. package/dist/transports/http-namespace.js.map +1 -0
  167. package/dist/transports/workshop.d.ts +173 -0
  168. package/dist/transports/workshop.d.ts.map +1 -0
  169. package/dist/transports/workshop.js +307 -0
  170. package/dist/transports/workshop.js.map +1 -0
  171. package/dist/types.d.ts +65 -67
  172. package/dist/types.d.ts.map +1 -1
  173. package/dist/types.js +7 -3
  174. package/dist/types.js.map +1 -1
  175. package/docs/ADR-004-product-registry.md +108 -0
  176. package/package.json +1 -1
@@ -0,0 +1,208 @@
1
+ /**
2
+ * @module modules/auth/products
3
+ * @description Centralized registry of all Soulcraft platform products and their
4
+ * auth configuration. This is the single source of truth for:
5
+ *
6
+ * - Which products exist on the platform
7
+ * - Their production domains and local dev ports
8
+ * - Their OIDC client IDs and redirect callback paths
9
+ * - Whether they require backchannel logout support
10
+ * - Which env var holds their OIDC client secret
11
+ *
12
+ * The auth server (`auth.soulcraft.com`) consumes this registry to derive all
13
+ * its registration arrays — trusted origins, CORS, OIDC trusted clients, and
14
+ * backchannel logout recipients — instead of maintaining five parallel hardcoded lists.
15
+ *
16
+ * ## Adding a new product
17
+ *
18
+ * 1. Add an entry to `SOULCRAFT_PRODUCTS` below (TypeScript enforces completeness).
19
+ * 2. Add `{PRODUCT}_OIDC_CLIENT_SECRET` (or equivalent) to the auth server's
20
+ * `.env.production`. Generate with: `openssl rand -hex 32`
21
+ * 3. Publish a new version of `@soulcraft/sdk`.
22
+ * 4. Deploy the auth server — it will pick up the new product automatically.
23
+ * 5. Set `SOULCRAFT_IDP_URL` in the product's own `.env.production`.
24
+ *
25
+ * @see ADR-002-product-registry.md for design rationale.
26
+ */
27
+ /**
28
+ * Full auth configuration for a single Soulcraft platform product.
29
+ *
30
+ * Consumed by the auth server to derive trusted origins, CORS origins, OIDC
31
+ * client registrations, and backchannel logout recipients.
32
+ */
33
+ export interface ProductRegistration {
34
+ /** Human-readable display name, e.g. `"Soulcraft Workshop"`. */
35
+ name: string;
36
+ /**
37
+ * Production domain without scheme or trailing slash.
38
+ * e.g. `"workshop.soulcraft.com"`, `"soulcraft.com"`
39
+ */
40
+ domain: string;
41
+ /** Local development port. Used to derive `http://localhost:{devPort}` origins. */
42
+ devPort: number;
43
+ /**
44
+ * OIDC client ID registered on the auth server.
45
+ * Must be unique across all products. e.g. `"workshop"`.
46
+ */
47
+ clientId: string;
48
+ /**
49
+ * Name of the environment variable that holds this product's OIDC client secret
50
+ * (or backchannel secret for cookie-proxy products). e.g. `"WORKSHOP_OIDC_CLIENT_SECRET"`.
51
+ */
52
+ secretEnvVar: string;
53
+ /**
54
+ * How this product authenticates users:
55
+ * - `'oidc-redirect'` — full OIDC authorization code flow with redirect callbacks
56
+ * - `'cookie-proxy'` — validates the shared `.soulcraft.com` session cookie directly
57
+ * against `GET /api/auth/get-session`; no OIDC redirect involved
58
+ */
59
+ authMode: 'oidc-redirect' | 'cookie-proxy';
60
+ /**
61
+ * Paths on this product's origin that the auth server should register as OIDC
62
+ * redirect URIs. Empty array for cookie-proxy products. Both production and dev
63
+ * variants are derived automatically via `deriveRedirectUrls`.
64
+ */
65
+ callbackPaths: string[];
66
+ /**
67
+ * Additional paths to include as OIDC redirect URIs beyond the callback paths.
68
+ * Typically the homepage (`"/"`) which is used as `post_logout_redirect_uri`.
69
+ * Defaults to `["/"]` when omitted.
70
+ */
71
+ extraRedirectPaths?: string[];
72
+ /**
73
+ * When `true`, the auth server includes this product in its OIDC backchannel
74
+ * logout registry. The product's `{domain}/api/auth/backchannel-logout` endpoint
75
+ * will be notified on every sign-out so it can terminate local sessions immediately.
76
+ *
77
+ * Set to `false` only for products that do not implement a backchannel endpoint
78
+ * (e.g. read-only dashboards, analytics tools).
79
+ */
80
+ backchannelRequired: boolean;
81
+ }
82
+ /**
83
+ * Central registry of all Soulcraft platform products.
84
+ *
85
+ * `as const satisfies Record<string, ProductRegistration>` provides two guarantees:
86
+ * - TypeScript enforces that every entry has all required `ProductRegistration` fields
87
+ * - Literal types are preserved so `keyof typeof SOULCRAFT_PRODUCTS` yields
88
+ * `'workshop' | 'venue' | 'portal' | 'academy' | 'pulse'` (not just `string`)
89
+ *
90
+ * Adding a product here automatically:
91
+ * - Extends the `SoulcraftProduct` union type
92
+ * - Includes the product in all auth server derivations (origins, CORS, OIDC clients)
93
+ */
94
+ export declare const SOULCRAFT_PRODUCTS: {
95
+ readonly workshop: {
96
+ readonly name: "Soulcraft Workshop";
97
+ readonly domain: "workshop.soulcraft.com";
98
+ readonly devPort: 5001;
99
+ readonly clientId: "workshop";
100
+ readonly secretEnvVar: "WORKSHOP_OIDC_CLIENT_SECRET";
101
+ readonly authMode: "oidc-redirect";
102
+ readonly callbackPaths: ["/api/auth/oauth2/callback/soulcraft-idp", "/api/auth/callback/soulcraft-idp"];
103
+ readonly extraRedirectPaths: ["/"];
104
+ readonly backchannelRequired: true;
105
+ };
106
+ readonly venue: {
107
+ readonly name: "Soulcraft Venue";
108
+ readonly domain: "venue.soulcraft.com";
109
+ readonly devPort: 5174;
110
+ readonly clientId: "venue";
111
+ readonly secretEnvVar: "VENUE_OIDC_CLIENT_SECRET";
112
+ readonly authMode: "oidc-redirect";
113
+ readonly callbackPaths: ["/api/auth/callback/soulcraft-idp"];
114
+ readonly extraRedirectPaths: ["/"];
115
+ readonly backchannelRequired: true;
116
+ };
117
+ readonly portal: {
118
+ readonly name: "Soulcraft Portal";
119
+ readonly domain: "soulcraft.com";
120
+ readonly devPort: 8080;
121
+ readonly clientId: "portal";
122
+ readonly secretEnvVar: "PORTAL_OIDC_CLIENT_SECRET";
123
+ readonly authMode: "oidc-redirect";
124
+ readonly callbackPaths: ["/api/auth/callback/soulcraft-idp", "/auth/callback"];
125
+ readonly extraRedirectPaths: ["/"];
126
+ readonly backchannelRequired: true;
127
+ };
128
+ readonly academy: {
129
+ readonly name: "Soulcraft Academy";
130
+ readonly domain: "academy.soulcraft.com";
131
+ readonly devPort: 5002;
132
+ readonly clientId: "academy";
133
+ readonly secretEnvVar: "ACADEMY_OIDC_CLIENT_SECRET";
134
+ readonly authMode: "oidc-redirect";
135
+ readonly callbackPaths: ["/api/auth/callback/soulcraft-idp"];
136
+ readonly extraRedirectPaths: ["/"];
137
+ readonly backchannelRequired: true;
138
+ };
139
+ readonly pulse: {
140
+ readonly name: "Soulcraft Pulse";
141
+ readonly domain: "pulse.soulcraft.com";
142
+ readonly devPort: 5004;
143
+ readonly clientId: "pulse";
144
+ readonly secretEnvVar: "PULSE_BACKCHANNEL_SECRET";
145
+ readonly authMode: "cookie-proxy";
146
+ readonly callbackPaths: [];
147
+ readonly extraRedirectPaths: ["/"];
148
+ readonly backchannelRequired: false;
149
+ };
150
+ };
151
+ /**
152
+ * Union of all registered Soulcraft product keys.
153
+ *
154
+ * Automatically derived from `SOULCRAFT_PRODUCTS` — adding a product to the
155
+ * registry extends this type without any manual update.
156
+ *
157
+ * @example
158
+ * function validateProduct(p: string): p is SoulcraftProduct {
159
+ * return p in SOULCRAFT_PRODUCTS
160
+ * }
161
+ */
162
+ export type SoulcraftProduct = keyof typeof SOULCRAFT_PRODUCTS;
163
+ /**
164
+ * Derive the full list of trusted origins for all registered products.
165
+ *
166
+ * Returns both the production HTTPS origin and the `http://localhost:{devPort}`
167
+ * development origin for every product in `SOULCRAFT_PRODUCTS`.
168
+ *
169
+ * Used by the auth server for:
170
+ * - `betterAuth({ trustedOrigins: deriveOrigins() })` — callback URL validation
171
+ * - `cors({ origin: deriveOrigins() })` — CORS preflight on the Hono layer
172
+ *
173
+ * @returns Deduplicated list of origin strings (scheme + host, no trailing slash).
174
+ *
175
+ * @example
176
+ * deriveOrigins()
177
+ * // → [
178
+ * // 'https://workshop.soulcraft.com', 'http://localhost:5001',
179
+ * // 'https://venue.soulcraft.com', 'http://localhost:5174',
180
+ * // 'https://soulcraft.com', 'http://localhost:8080',
181
+ * // 'https://academy.soulcraft.com', 'http://localhost:5002',
182
+ * // 'https://pulse.soulcraft.com', 'http://localhost:5004',
183
+ * // ]
184
+ */
185
+ export declare function deriveOrigins(): string[];
186
+ /**
187
+ * Derive all OIDC redirect URIs for a single product registration.
188
+ *
189
+ * Combines callback paths and extra redirect paths, generating both production
190
+ * and local development variants for each. Results are ordered: production paths
191
+ * first (all), then dev paths (all), matching the ordering in the auth server.
192
+ *
193
+ * @param p - A `ProductRegistration` from `SOULCRAFT_PRODUCTS`.
194
+ * @returns List of fully-qualified redirect URI strings.
195
+ *
196
+ * @example
197
+ * deriveRedirectUrls(SOULCRAFT_PRODUCTS.workshop)
198
+ * // → [
199
+ * // 'https://workshop.soulcraft.com/api/auth/oauth2/callback/soulcraft-idp',
200
+ * // 'https://workshop.soulcraft.com/api/auth/callback/soulcraft-idp',
201
+ * // 'https://workshop.soulcraft.com/',
202
+ * // 'http://localhost:5001/api/auth/oauth2/callback/soulcraft-idp',
203
+ * // 'http://localhost:5001/api/auth/callback/soulcraft-idp',
204
+ * // 'http://localhost:5001/',
205
+ * // ]
206
+ */
207
+ export declare function deriveRedirectUrls(p: ProductRegistration): string[];
208
+ //# sourceMappingURL=products.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"products.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/products.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,QAAQ,EAAE,eAAe,GAAG,cAAc,CAAA;IAC1C;;;;OAIG;IACH,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B;;;;;;;OAOG;IACH,mBAAmB,EAAE,OAAO,CAAA;CAC7B;AAMD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+DyB,CAAA;AAExD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,kBAAkB,CAAA;AAM9D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAKxC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAQnE"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * @module modules/auth/products
3
+ * @description Centralized registry of all Soulcraft platform products and their
4
+ * auth configuration. This is the single source of truth for:
5
+ *
6
+ * - Which products exist on the platform
7
+ * - Their production domains and local dev ports
8
+ * - Their OIDC client IDs and redirect callback paths
9
+ * - Whether they require backchannel logout support
10
+ * - Which env var holds their OIDC client secret
11
+ *
12
+ * The auth server (`auth.soulcraft.com`) consumes this registry to derive all
13
+ * its registration arrays — trusted origins, CORS, OIDC trusted clients, and
14
+ * backchannel logout recipients — instead of maintaining five parallel hardcoded lists.
15
+ *
16
+ * ## Adding a new product
17
+ *
18
+ * 1. Add an entry to `SOULCRAFT_PRODUCTS` below (TypeScript enforces completeness).
19
+ * 2. Add `{PRODUCT}_OIDC_CLIENT_SECRET` (or equivalent) to the auth server's
20
+ * `.env.production`. Generate with: `openssl rand -hex 32`
21
+ * 3. Publish a new version of `@soulcraft/sdk`.
22
+ * 4. Deploy the auth server — it will pick up the new product automatically.
23
+ * 5. Set `SOULCRAFT_IDP_URL` in the product's own `.env.production`.
24
+ *
25
+ * @see ADR-002-product-registry.md for design rationale.
26
+ */
27
+ // ─────────────────────────────────────────────────────────────────────────────
28
+ // Registry
29
+ // ─────────────────────────────────────────────────────────────────────────────
30
+ /**
31
+ * Central registry of all Soulcraft platform products.
32
+ *
33
+ * `as const satisfies Record<string, ProductRegistration>` provides two guarantees:
34
+ * - TypeScript enforces that every entry has all required `ProductRegistration` fields
35
+ * - Literal types are preserved so `keyof typeof SOULCRAFT_PRODUCTS` yields
36
+ * `'workshop' | 'venue' | 'portal' | 'academy' | 'pulse'` (not just `string`)
37
+ *
38
+ * Adding a product here automatically:
39
+ * - Extends the `SoulcraftProduct` union type
40
+ * - Includes the product in all auth server derivations (origins, CORS, OIDC clients)
41
+ */
42
+ export const SOULCRAFT_PRODUCTS = {
43
+ workshop: {
44
+ name: 'Soulcraft Workshop',
45
+ domain: 'workshop.soulcraft.com',
46
+ devPort: 5001,
47
+ clientId: 'workshop',
48
+ secretEnvVar: 'WORKSHOP_OIDC_CLIENT_SECRET',
49
+ authMode: 'oidc-redirect',
50
+ callbackPaths: [
51
+ '/api/auth/oauth2/callback/soulcraft-idp',
52
+ // Legacy path kept for in-flight sessions during transitions
53
+ '/api/auth/callback/soulcraft-idp',
54
+ ],
55
+ extraRedirectPaths: ['/'],
56
+ backchannelRequired: true,
57
+ },
58
+ venue: {
59
+ name: 'Soulcraft Venue',
60
+ domain: 'venue.soulcraft.com',
61
+ devPort: 5174,
62
+ clientId: 'venue',
63
+ secretEnvVar: 'VENUE_OIDC_CLIENT_SECRET',
64
+ authMode: 'oidc-redirect',
65
+ callbackPaths: ['/api/auth/callback/soulcraft-idp'],
66
+ extraRedirectPaths: ['/'],
67
+ backchannelRequired: true,
68
+ },
69
+ portal: {
70
+ name: 'Soulcraft Portal',
71
+ domain: 'soulcraft.com',
72
+ devPort: 8080,
73
+ clientId: 'portal',
74
+ secretEnvVar: 'PORTAL_OIDC_CLIENT_SECRET',
75
+ authMode: 'oidc-redirect',
76
+ callbackPaths: ['/api/auth/callback/soulcraft-idp', '/auth/callback'],
77
+ extraRedirectPaths: ['/'],
78
+ backchannelRequired: true,
79
+ },
80
+ academy: {
81
+ name: 'Soulcraft Academy',
82
+ domain: 'academy.soulcraft.com',
83
+ devPort: 5002,
84
+ clientId: 'academy',
85
+ secretEnvVar: 'ACADEMY_OIDC_CLIENT_SECRET',
86
+ authMode: 'oidc-redirect',
87
+ callbackPaths: ['/api/auth/callback/soulcraft-idp'],
88
+ extraRedirectPaths: ['/'],
89
+ backchannelRequired: true,
90
+ },
91
+ pulse: {
92
+ name: 'Soulcraft Pulse',
93
+ domain: 'pulse.soulcraft.com',
94
+ devPort: 5004,
95
+ clientId: 'pulse',
96
+ // Pulse uses cookie-proxy; PULSE_BACKCHANNEL_SECRET doubles as the OIDC client
97
+ // secret for the minimal OIDC client entry that registers the homepage as a valid
98
+ // post_logout_redirect_uri. Backchannel is best-effort; no startup failure if absent.
99
+ secretEnvVar: 'PULSE_BACKCHANNEL_SECRET',
100
+ authMode: 'cookie-proxy',
101
+ callbackPaths: [],
102
+ extraRedirectPaths: ['/'],
103
+ backchannelRequired: false,
104
+ },
105
+ };
106
+ // ─────────────────────────────────────────────────────────────────────────────
107
+ // Derivation helpers
108
+ // ─────────────────────────────────────────────────────────────────────────────
109
+ /**
110
+ * Derive the full list of trusted origins for all registered products.
111
+ *
112
+ * Returns both the production HTTPS origin and the `http://localhost:{devPort}`
113
+ * development origin for every product in `SOULCRAFT_PRODUCTS`.
114
+ *
115
+ * Used by the auth server for:
116
+ * - `betterAuth({ trustedOrigins: deriveOrigins() })` — callback URL validation
117
+ * - `cors({ origin: deriveOrigins() })` — CORS preflight on the Hono layer
118
+ *
119
+ * @returns Deduplicated list of origin strings (scheme + host, no trailing slash).
120
+ *
121
+ * @example
122
+ * deriveOrigins()
123
+ * // → [
124
+ * // 'https://workshop.soulcraft.com', 'http://localhost:5001',
125
+ * // 'https://venue.soulcraft.com', 'http://localhost:5174',
126
+ * // 'https://soulcraft.com', 'http://localhost:8080',
127
+ * // 'https://academy.soulcraft.com', 'http://localhost:5002',
128
+ * // 'https://pulse.soulcraft.com', 'http://localhost:5004',
129
+ * // ]
130
+ */
131
+ export function deriveOrigins() {
132
+ return Object.values(SOULCRAFT_PRODUCTS).flatMap((p) => [
133
+ `https://${p.domain}`,
134
+ `http://localhost:${p.devPort}`,
135
+ ]);
136
+ }
137
+ /**
138
+ * Derive all OIDC redirect URIs for a single product registration.
139
+ *
140
+ * Combines callback paths and extra redirect paths, generating both production
141
+ * and local development variants for each. Results are ordered: production paths
142
+ * first (all), then dev paths (all), matching the ordering in the auth server.
143
+ *
144
+ * @param p - A `ProductRegistration` from `SOULCRAFT_PRODUCTS`.
145
+ * @returns List of fully-qualified redirect URI strings.
146
+ *
147
+ * @example
148
+ * deriveRedirectUrls(SOULCRAFT_PRODUCTS.workshop)
149
+ * // → [
150
+ * // 'https://workshop.soulcraft.com/api/auth/oauth2/callback/soulcraft-idp',
151
+ * // 'https://workshop.soulcraft.com/api/auth/callback/soulcraft-idp',
152
+ * // 'https://workshop.soulcraft.com/',
153
+ * // 'http://localhost:5001/api/auth/oauth2/callback/soulcraft-idp',
154
+ * // 'http://localhost:5001/api/auth/callback/soulcraft-idp',
155
+ * // 'http://localhost:5001/',
156
+ * // ]
157
+ */
158
+ export function deriveRedirectUrls(p) {
159
+ const extraPaths = p.extraRedirectPaths ?? ['/'];
160
+ const allPaths = [...p.callbackPaths, ...extraPaths];
161
+ const prod = allPaths.map((path) => `https://${p.domain}${path}`);
162
+ const dev = allPaths.map((path) => `http://localhost:${p.devPort}${path}`);
163
+ return [...prod, ...dev];
164
+ }
165
+ //# sourceMappingURL=products.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"products.js","sourceRoot":"","sources":["../../../src/modules/auth/products.ts"],"names":[],"mappings":"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"}