@kelpie/server 0.4.1 → 0.5.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 (177) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +14 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/index.d.ts +2 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/appUrl.d.ts +27 -0
  9. package/dist/lib/appUrl.d.ts.map +1 -0
  10. package/dist/lib/appUrl.js +53 -0
  11. package/dist/lib/appUrl.js.map +1 -0
  12. package/dist/lib/clientIp.d.ts +24 -0
  13. package/dist/lib/clientIp.d.ts.map +1 -0
  14. package/dist/lib/clientIp.js +34 -0
  15. package/dist/lib/clientIp.js.map +1 -0
  16. package/dist/lib/config.d.ts +6 -0
  17. package/dist/lib/config.d.ts.map +1 -1
  18. package/dist/lib/config.js +2 -0
  19. package/dist/lib/config.js.map +1 -1
  20. package/dist/lib/egress.d.ts +44 -0
  21. package/dist/lib/egress.d.ts.map +1 -0
  22. package/dist/lib/egress.js +111 -0
  23. package/dist/lib/egress.js.map +1 -0
  24. package/dist/lib/ids.d.ts +2 -0
  25. package/dist/lib/ids.d.ts.map +1 -1
  26. package/dist/lib/ids.js +2 -0
  27. package/dist/lib/ids.js.map +1 -1
  28. package/dist/lib/rateLimit.d.ts +12 -4
  29. package/dist/lib/rateLimit.d.ts.map +1 -1
  30. package/dist/lib/rateLimit.js +6 -0
  31. package/dist/lib/rateLimit.js.map +1 -1
  32. package/dist/modules/agent-tasks/dispatch.d.ts +4 -2
  33. package/dist/modules/agent-tasks/dispatch.d.ts.map +1 -1
  34. package/dist/modules/agent-tasks/dispatch.js +4 -2
  35. package/dist/modules/agent-tasks/dispatch.js.map +1 -1
  36. package/dist/modules/agent-tasks/index.d.ts.map +1 -1
  37. package/dist/modules/agent-tasks/index.js +3 -1
  38. package/dist/modules/agent-tasks/index.js.map +1 -1
  39. package/dist/modules/auth/index.d.ts.map +1 -1
  40. package/dist/modules/auth/index.js +10 -3
  41. package/dist/modules/auth/index.js.map +1 -1
  42. package/dist/modules/auth/repository.d.ts +13 -1
  43. package/dist/modules/auth/repository.d.ts.map +1 -1
  44. package/dist/modules/auth/repository.js +32 -1
  45. package/dist/modules/auth/repository.js.map +1 -1
  46. package/dist/modules/auth/routes.d.ts.map +1 -1
  47. package/dist/modules/auth/routes.js +29 -6
  48. package/dist/modules/auth/routes.js.map +1 -1
  49. package/dist/modules/auth/schema.d.ts +130 -0
  50. package/dist/modules/auth/schema.d.ts.map +1 -1
  51. package/dist/modules/auth/schema.js +16 -0
  52. package/dist/modules/auth/schema.js.map +1 -1
  53. package/dist/modules/auth/service.d.ts +7 -1
  54. package/dist/modules/auth/service.d.ts.map +1 -1
  55. package/dist/modules/auth/service.js +53 -4
  56. package/dist/modules/auth/service.js.map +1 -1
  57. package/dist/modules/deals/repository.d.ts.map +1 -1
  58. package/dist/modules/deals/repository.js +1 -0
  59. package/dist/modules/deals/repository.js.map +1 -1
  60. package/dist/modules/decisions/repository.d.ts.map +1 -1
  61. package/dist/modules/decisions/repository.js +8 -7
  62. package/dist/modules/decisions/repository.js.map +1 -1
  63. package/dist/modules/forms/index.d.ts.map +1 -1
  64. package/dist/modules/forms/index.js +6 -1
  65. package/dist/modules/forms/index.js.map +1 -1
  66. package/dist/modules/forms/publicRoutes.d.ts +3 -0
  67. package/dist/modules/forms/publicRoutes.d.ts.map +1 -1
  68. package/dist/modules/forms/publicRoutes.js +10 -4
  69. package/dist/modules/forms/publicRoutes.js.map +1 -1
  70. package/dist/modules/forms/submission.d.ts +3 -0
  71. package/dist/modules/forms/submission.d.ts.map +1 -1
  72. package/dist/modules/forms/submission.js +6 -0
  73. package/dist/modules/forms/submission.js.map +1 -1
  74. package/dist/modules/opportunities/repository.d.ts.map +1 -1
  75. package/dist/modules/opportunities/repository.js +1 -0
  76. package/dist/modules/opportunities/repository.js.map +1 -1
  77. package/dist/modules/partnerships/repository.d.ts.map +1 -1
  78. package/dist/modules/partnerships/repository.js +1 -0
  79. package/dist/modules/partnerships/repository.js.map +1 -1
  80. package/dist/modules/raises/repository.d.ts.map +1 -1
  81. package/dist/modules/raises/repository.js +1 -0
  82. package/dist/modules/raises/repository.js.map +1 -1
  83. package/dist/modules/rate-limit/middleware.d.ts +4 -4
  84. package/dist/modules/rate-limit/middleware.d.ts.map +1 -1
  85. package/dist/modules/rate-limit/middleware.js +57 -11
  86. package/dist/modules/rate-limit/middleware.js.map +1 -1
  87. package/dist/modules/webhooks/delivery.d.ts +5 -2
  88. package/dist/modules/webhooks/delivery.d.ts.map +1 -1
  89. package/dist/modules/webhooks/delivery.js +5 -2
  90. package/dist/modules/webhooks/delivery.js.map +1 -1
  91. package/dist/modules/webhooks/index.d.ts.map +1 -1
  92. package/dist/modules/webhooks/index.js +3 -1
  93. package/dist/modules/webhooks/index.js.map +1 -1
  94. package/dist/modules/workspace/idempotencyMiddleware.d.ts.map +1 -1
  95. package/dist/modules/workspace/idempotencyMiddleware.js +14 -1
  96. package/dist/modules/workspace/idempotencyMiddleware.js.map +1 -1
  97. package/dist/modules/workspace/index.d.ts.map +1 -1
  98. package/dist/modules/workspace/index.js +3 -0
  99. package/dist/modules/workspace/index.js.map +1 -1
  100. package/dist/modules/workspace/repository.d.ts +1 -1
  101. package/dist/modules/workspace/repository.d.ts.map +1 -1
  102. package/dist/modules/workspace/repository.js +15 -9
  103. package/dist/modules/workspace/repository.js.map +1 -1
  104. package/dist/modules/workspace/routes.d.ts +0 -4
  105. package/dist/modules/workspace/routes.d.ts.map +1 -1
  106. package/dist/modules/workspace/routes.js +2 -7
  107. package/dist/modules/workspace/routes.js.map +1 -1
  108. package/dist/modules/workspace/service.d.ts +4 -2
  109. package/dist/modules/workspace/service.d.ts.map +1 -1
  110. package/dist/modules/workspace/service.js +42 -17
  111. package/dist/modules/workspace/service.js.map +1 -1
  112. package/dist/modules/workspace/tools.d.ts.map +1 -1
  113. package/dist/modules/workspace/tools.js +6 -7
  114. package/dist/modules/workspace/tools.js.map +1 -1
  115. package/dist/operator.d.ts +40 -0
  116. package/dist/operator.d.ts.map +1 -0
  117. package/dist/operator.js +50 -0
  118. package/dist/operator.js.map +1 -0
  119. package/dist/runtime/module.d.ts +25 -1
  120. package/dist/runtime/module.d.ts.map +1 -1
  121. package/dist/runtime/registry.d.ts +16 -1
  122. package/dist/runtime/registry.d.ts.map +1 -1
  123. package/dist/runtime/registry.js +34 -0
  124. package/dist/runtime/registry.js.map +1 -1
  125. package/dist/testing/client.d.ts +3 -1
  126. package/dist/testing/client.d.ts.map +1 -1
  127. package/dist/testing/client.js +19 -2
  128. package/dist/testing/client.js.map +1 -1
  129. package/dist/testing/environment.d.ts +2 -0
  130. package/dist/testing/environment.d.ts.map +1 -1
  131. package/dist/testing/environment.js +3 -0
  132. package/dist/testing/environment.js.map +1 -1
  133. package/dist/webBundle.d.ts +8 -0
  134. package/dist/webBundle.d.ts.map +1 -1
  135. package/dist/webBundle.js +9 -7
  136. package/dist/webBundle.js.map +1 -1
  137. package/migrations/0018_hard_mystique.sql +12 -0
  138. package/migrations/meta/0018_snapshot.json +5113 -0
  139. package/migrations/meta/_journal.json +8 -1
  140. package/package.json +2 -2
  141. package/src/app.ts +16 -0
  142. package/src/index.ts +9 -1
  143. package/src/lib/appUrl.ts +64 -0
  144. package/src/lib/clientIp.ts +41 -0
  145. package/src/lib/config.ts +8 -0
  146. package/src/lib/egress.ts +149 -0
  147. package/src/lib/ids.ts +2 -0
  148. package/src/lib/rateLimit.ts +16 -4
  149. package/src/modules/agent-tasks/dispatch.ts +9 -2
  150. package/src/modules/agent-tasks/index.ts +3 -1
  151. package/src/modules/auth/index.ts +12 -5
  152. package/src/modules/auth/repository.ts +56 -1
  153. package/src/modules/auth/routes.ts +34 -6
  154. package/src/modules/auth/schema.ts +17 -0
  155. package/src/modules/auth/service.ts +78 -5
  156. package/src/modules/deals/repository.ts +1 -0
  157. package/src/modules/decisions/repository.ts +8 -7
  158. package/src/modules/forms/index.ts +6 -1
  159. package/src/modules/forms/publicRoutes.ts +14 -4
  160. package/src/modules/forms/submission.ts +10 -0
  161. package/src/modules/opportunities/repository.ts +1 -0
  162. package/src/modules/partnerships/repository.ts +1 -0
  163. package/src/modules/raises/repository.ts +1 -0
  164. package/src/modules/rate-limit/middleware.ts +74 -11
  165. package/src/modules/webhooks/delivery.ts +10 -2
  166. package/src/modules/webhooks/index.ts +3 -1
  167. package/src/modules/workspace/idempotencyMiddleware.ts +17 -1
  168. package/src/modules/workspace/index.ts +4 -0
  169. package/src/modules/workspace/repository.ts +15 -8
  170. package/src/modules/workspace/routes.ts +0 -8
  171. package/src/modules/workspace/service.ts +53 -20
  172. package/src/modules/workspace/tools.ts +7 -21
  173. package/src/runtime/module.ts +25 -1
  174. package/src/runtime/registry.ts +59 -1
  175. package/src/testing/client.ts +22 -2
  176. package/src/testing/environment.ts +4 -0
  177. package/src/webBundle.ts +21 -7
@@ -1,4 +1,4 @@
1
- import type { Hono } from 'hono';
1
+ import type { Handler, Hono, MiddlewareHandler } from 'hono';
2
2
  import type { ZodType } from 'zod';
3
3
  import type { Actor } from '../lib/actor.ts';
4
4
  import type { Database } from '../lib/database.ts';
@@ -85,6 +85,30 @@ export interface ModuleContext extends ModuleServices {
85
85
  * scope every query to that. There is no other way in.
86
86
  */
87
87
  publicRoutes(mount: (router: Hono) => void): void;
88
+ /**
89
+ * Declares one route at its real, full path on the app itself, outside
90
+ * `/v1`. Core applies the declaration; no router exists between the module
91
+ * and the app.
92
+ *
93
+ * Nothing is put in front of it: no actor resolution, no workspace, no
94
+ * `module.<id>` capability gate, and workspace settings cannot toggle it.
95
+ * A surface declared this way owns its access rules, normally by pairing
96
+ * these with `appMiddleware`. Paths at or under `/v1`, `/mcp`, or
97
+ * `/healthz` are refused at boot: those are core's surfaces, and `routes`
98
+ * is the only way under `/v1`.
99
+ */
100
+ appRoute(method: 'GET' | 'POST' | 'PATCH' | 'DELETE', path: string, handler: Handler): void;
101
+ /**
102
+ * Declares middleware for a path pattern (`/operator/api/*`), the other
103
+ * half of `appRoute`.
104
+ *
105
+ * The app applies every declared middleware before any declared route, in
106
+ * module registration order, so a pattern covers matching routes from
107
+ * every module, later-registered ones included. That is what lets one
108
+ * module guard a surface other modules add routes to. Reserved paths are
109
+ * refused as for `appRoute`.
110
+ */
111
+ appMiddleware(pattern: string, handler: MiddlewareHandler): void;
88
112
  schema(tables: Readonly<Record<string, unknown>>, migrationsDir: string): void;
89
113
  readonly mcp: McpToolRegistry;
90
114
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/runtime/module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/runtime/module.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Hono } from 'hono';
2
- import type { Context } from 'hono';
2
+ import type { Context, Handler, MiddlewareHandler } from 'hono';
3
3
  import type { Actor } from '../lib/actor.ts';
4
4
  import type { Environment } from '../lib/config.ts';
5
5
  import type { Logger } from '../lib/logger.ts';
@@ -15,6 +15,10 @@ export interface ModuleContributions {
15
15
  readonly routers: readonly ModuleRouter[];
16
16
  /** Routers for `/v1/public`: no credentials, CORS open. `architecture.md` boot step 5. */
17
17
  readonly publicRouters: readonly ModuleRouter[];
18
+ /** Middleware declared on the app itself. Applied before every `appRoutes` entry. */
19
+ readonly appMiddleware: readonly AppMiddlewareContribution[];
20
+ /** Routes declared at full paths on the app itself, outside `/v1`. */
21
+ readonly appRoutes: readonly AppRouteContribution[];
18
22
  readonly schemas: readonly SchemaContribution[];
19
23
  readonly mcpTools: readonly McpTool[];
20
24
  /** The bus every module subscribed to. Services publish through it after commit. */
@@ -26,6 +30,17 @@ export interface ModuleRouter {
26
30
  readonly moduleId: string;
27
31
  readonly router: Hono;
28
32
  }
33
+ export interface AppRouteContribution {
34
+ readonly moduleId: string;
35
+ readonly method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
36
+ readonly path: string;
37
+ readonly handler: Handler;
38
+ }
39
+ export interface AppMiddlewareContribution {
40
+ readonly moduleId: string;
41
+ readonly pattern: string;
42
+ readonly handler: MiddlewareHandler;
43
+ }
29
44
  /**
30
45
  * What `registerModules` needs.
31
46
  *
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/runtime/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAE5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EAGP,cAAc,EACd,kBAAkB,EACnB,MAAM,aAAa,CAAA;AAIpB;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IACzC,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IAC/C,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC/C,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;IACrC,oFAAoF;IACpF,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAA;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CACtB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IACzC,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACtC,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAA;IACvD,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;IACrE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAA;CAC3E;AA+GD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuEjG"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/runtime/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAE5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EAGP,cAAc,EACd,kBAAkB,EACnB,MAAM,aAAa,CAAA;AAIpB;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IACzC,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IAC/C,qFAAqF;IACrF,QAAQ,CAAC,aAAa,EAAE,SAAS,yBAAyB,EAAE,CAAA;IAC5D,sEAAsE;IACtE,QAAQ,CAAC,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACnD,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC/C,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;IACrC,oFAAoF;IACpF,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAA;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAA;CACpC;AAwBD;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IACzC,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACtC,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAA;IACvD,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;IACrE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAA;CAC3E;AA8HD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA2EjG"}
@@ -5,6 +5,25 @@ import { createEntitlementRegistry, requireCapability } from './entitlements.js'
5
5
  import { createEventBus } from './events.js';
6
6
  import { createModuleConfigProvider, moduleCapabilityName, validateModuleConfig } from './moduleConfig.js';
7
7
  import { ModuleBootError, orderModules } from './order.js';
8
+ /**
9
+ * Paths `appRoute`/`appMiddleware` may not touch. `/v1` because `routes` with
10
+ * its gates is the only way there, the rest because they are core's own
11
+ * surfaces. `/mcp` mirrors `MCP_ROUTE_PREFIX`, written out because `runtime/`
12
+ * must not import a feature module.
13
+ */
14
+ const RESERVED_APP_PATHS = ['/v1', '/mcp', '/healthz'];
15
+ function assertMountablePath(moduleId, kind, path) {
16
+ if (!path.startsWith('/')) {
17
+ throw new ModuleBootError([`module "${moduleId}" declares ${kind} "${path}", which must start with "/"`]);
18
+ }
19
+ for (const reserved of RESERVED_APP_PATHS) {
20
+ if (path === reserved || path.startsWith(`${reserved}/`)) {
21
+ throw new ModuleBootError([
22
+ `module "${moduleId}" declares ${kind} "${path}" under "${reserved}", which is core's surface`,
23
+ ]);
24
+ }
25
+ }
26
+ }
8
27
  function createModuleContext(module, accumulator, options, events, entitlements, moduleCatalog) {
9
28
  return {
10
29
  ...options.services,
@@ -30,6 +49,17 @@ function createModuleContext(module, accumulator, options, events, entitlements,
30
49
  mount(router);
31
50
  accumulator.publicRouters.push({ moduleId: module.id, router });
32
51
  },
52
+ // No gate on either, unlike `routes`: a surface declared here owns its
53
+ // own access rules, and a per-module `module.<id>` check would hand
54
+ // workspaces a switch over deployment tooling they do not own.
55
+ appRoute(method, path, handler) {
56
+ assertMountablePath(module.id, 'app route', path);
57
+ accumulator.appRoutes.push({ moduleId: module.id, method, path, handler });
58
+ },
59
+ appMiddleware(pattern, handler) {
60
+ assertMountablePath(module.id, 'app middleware', pattern);
61
+ accumulator.appMiddleware.push({ moduleId: module.id, pattern, handler });
62
+ },
33
63
  schema(tables, migrationsDir) {
34
64
  accumulator.schemas.push({ moduleId: module.id, tables, migrationsDir });
35
65
  },
@@ -92,6 +122,8 @@ export async function registerModules(options) {
92
122
  const accumulator = {
93
123
  routers: [],
94
124
  publicRouters: [],
125
+ appMiddleware: [],
126
+ appRoutes: [],
95
127
  schemas: [],
96
128
  mcpTools: [],
97
129
  };
@@ -139,6 +171,8 @@ export async function registerModules(options) {
139
171
  return {
140
172
  routers: accumulator.routers,
141
173
  publicRouters: accumulator.publicRouters,
174
+ appMiddleware: accumulator.appMiddleware,
175
+ appRoutes: accumulator.appRoutes,
142
176
  schemas: accumulator.schemas,
143
177
  mcpTools: accumulator.mcpTools,
144
178
  events,
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/runtime/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAI3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEpG,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAEhF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAU5C,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC1G,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAwE1D,SAAS,mBAAmB,CAC1B,MAAoB,EACpB,WAAwB,EACxB,OAA6B,EAC7B,MAAgB,EAChB,YAAiC,EACjC,aAA4C;IAE5C,OAAO;QACL,GAAG,OAAO,CAAC,QAAQ;QAEnB,MAAM,CAAC,KAAK;YACV,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;YAEzB,uEAAuE;YACvE,oEAAoE;YACpE,wEAAwE;YACxE,uCAAuC;YACvC,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACrE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAA;gBAEhC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;oBACtC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAA;oBAEzC,MAAM,iBAAiB,CAAC,YAAY,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;oBACjG,MAAM,IAAI,EAAE,CAAA;gBACd,CAAC,CAAC,CAAA;YACJ,CAAC;YAED,KAAK,CAAC,MAAM,CAAC,CAAA;YACb,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QAC3D,CAAC;QAED,YAAY,CAAC,KAAK;YAChB,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAA;YACzB,KAAK,CAAC,MAAM,CAAC,CAAA;YACb,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QACjE,CAAC;QAED,MAAM,CAAC,MAAM,EAAE,aAAa;YAC1B,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAA;QAC1E,CAAC;QAED,GAAG,EAAE;YACH,IAAI,CAAC,UAAU;gBACb,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC/E,MAAM,IAAI,eAAe,CAAC,CAAC,WAAW,MAAM,CAAC,EAAE,wBAAwB,UAAU,CAAC,IAAI,SAAS,CAAC,CAAC,CAAA;gBACnG,CAAC;gBAED,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACxB,IAAI,EAAE,UAAU,CAAC,IAAI;oBACrB,WAAW,EAAE,UAAU,CAAC,WAAW;oBACnC,WAAW,EAAE,UAAU,CAAC,WAAW;oBACnC,uEAAuE;oBACvE,yEAAyE;oBACzE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;wBAChC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;wBAEzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;4BACpB,MAAM,QAAQ,CAAC,gBAAgB,CAC7B,+BAA+B,UAAU,CAAC,IAAI,GAAG,EACjD,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CACpC,CAAA;wBACH,CAAC;wBAED,kEAAkE;wBAClE,kEAAkE;wBAClE,8DAA8D;wBAC9D,mBAAmB;wBACnB,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;4BAC/B,MAAM,iBAAiB,CAAC,YAAY,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;wBACnG,CAAC;wBAED,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;oBAC9C,CAAC;iBACF,CAAC,CAAA;YACJ,CAAC;SACF;QAED,MAAM,CAAC,MAAM;YACX,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;YAEpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,eAAe,CACvB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,MAAM,CAAC,EAAE,YAAY,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC,CACrG,CAAA;YACH,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAA;QACpB,CAAC;QAED,MAAM;QACN,YAAY;QAEZ,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QAEhD,aAAa;QACb,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA6B;IACjE,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAE7C,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,oBAAoB,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7D,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC/D,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,yBAAyB,EAAE,CAAA;IACxE,MAAM,WAAW,GAAgB;QAC/B,OAAO,EAAE,EAAE;QACX,aAAa,EAAE,EAAE;QACjB,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE;KACb,CAAA;IACD,MAAM,aAAa,GAAkC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC5E,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,IAAI;KACvC,CAAC,CAAC,CAAA;IAEH,2EAA2E;IAC3E,yEAAyE;IACzE,oCAAoC;IACpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC/B,YAAY,CAAC,OAAO,CAAC;gBACnB,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrC,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,gBAAgB,MAAM,CAAC,EAAE,sCAAsC;aAC7E,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,6EAA6E;IAC7E,yCAAyC;IACzC,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,YAAY,CAAC,OAAO,CAAC,0BAA0B,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IACxE,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,CAAC,CAAA;QAEtG,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAChC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACrC,MAAM,KAAK,CAAA;YACb,CAAC;YAED,MAAM,IAAI,eAAe,CAAC,CAAC,WAAW,MAAM,CAAC,EAAE,yBAAyB,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;gBAChG,KAAK,EAAE,KAAK;aACb,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;IACxC,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;QACxC,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;KACxC,CAAC,CAAA;IAEF,OAAO;QACL,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,aAAa,EAAE,WAAW,CAAC,aAAa;QACxC,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,MAAM;QACN,YAAY;KACb,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/runtime/registry.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { Hono } from 'hono';
2
2
  import type { AppBindings } from '../app.ts';
3
+ import type { Database } from '../lib/database.ts';
3
4
  /**
4
5
  * An HTTP client for integration tests, plus the two setups almost every suite
5
6
  * needs first: an account, and an account that owns a workspace.
@@ -30,5 +31,6 @@ export declare function readRecord(payload: unknown): Record<string, unknown>;
30
31
  export declare function readList(payload: unknown): Record<string, unknown>[];
31
32
  /** Reads `next_cursor`, which is a string or null and never absent. */
32
33
  export declare function readCursor(payload: unknown): string | null;
33
- export declare function createTestClient(app: Hono<AppBindings>): TestClient;
34
+ /** @param db Verifies a fresh signup directly, so almost every suite can start from a working owner. */
35
+ export declare function createTestClient(app: Hono<AppBindings>, db: Database): TestClient;
34
36
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/testing/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAE5C;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAED,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACnF,uDAAuD;IACvD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACtC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;CACzD;AAMD,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMpE;AAED,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAMpE;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAM1D;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,UAAU,CA+CnE"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/testing/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAED,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACnF,uDAAuD;IACvD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACtC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;CACzD;AAMD,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMpE;AAED,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAMpE;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAM1D;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,QAAQ,GAAG,UAAU,CA+DjF"}
@@ -1,3 +1,5 @@
1
+ import { eq } from 'drizzle-orm';
2
+ import { users } from '../modules/auth/schema.js';
1
3
  function isRecord(value) {
2
4
  return typeof value === 'object' && value !== null;
3
5
  }
@@ -28,7 +30,8 @@ export function readCursor(payload) {
28
30
  }
29
31
  return payload.next_cursor;
30
32
  }
31
- export function createTestClient(app) {
33
+ /** @param db Verifies a fresh signup directly, so almost every suite can start from a working owner. */
34
+ export function createTestClient(app, db) {
32
35
  function send(method, path, options = {}) {
33
36
  return Promise.resolve(app.request(path, {
34
37
  method,
@@ -40,13 +43,27 @@ export function createTestClient(app) {
40
43
  ...(options.body === undefined ? {} : { body: JSON.stringify(options.body) }),
41
44
  }));
42
45
  }
46
+ /**
47
+ * Signs up and verifies directly against the database.
48
+ *
49
+ * These suites are about the CRM, not verification: going through the real
50
+ * emailed link for every signup would mean threading the email spy through
51
+ * this client too, for a step almost nothing here is testing. `auth.test.ts`
52
+ * and `workspace.test.ts` cover the real link.
53
+ */
43
54
  async function signUp(email) {
44
55
  const response = await send('POST', '/v1/auth/signup', {
45
- body: { email, name: 'Someone', password: 'correct horse battery staple' },
56
+ body: {
57
+ email,
58
+ name: 'Someone',
59
+ password: 'correct horse battery staple',
60
+ },
46
61
  });
47
62
  if (response.status !== 201) {
48
63
  throw new Error(`Signing up ${email} answered ${String(response.status)}`);
49
64
  }
65
+ const accountId = readString(readRecord(await response.json()).account, 'id');
66
+ await db.update(users).set({ emailVerifiedAt: new Date() }).where(eq(users.id, accountId));
50
67
  // Only the cookie's name=value matters to a later request; the attributes
51
68
  // after the first semicolon are for a browser.
52
69
  return (response.headers.get('Set-Cookie') ?? '').split(';')[0] ?? '';
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/testing/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/testing/client.ts"],"names":[],"mappings":"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"}
@@ -13,5 +13,7 @@ import type { Environment } from '../lib/config.ts';
13
13
  * secret is ever sealed with it.
14
14
  */
15
15
  export declare const TEST_SECRET_ENCRYPTION_KEY = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
16
+ /** The base URL every emailed link is built from in tests. */
17
+ export declare const TEST_APP_BASE_URL = "https://kelpie.test";
16
18
  export declare const TEST_ENVIRONMENT: Environment;
17
19
  //# sourceMappingURL=environment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/testing/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD;;;;;;;GAOG;AAEH;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,iDAAiD,CAAA;AAExF,eAAO,MAAM,gBAAgB,EAAE,WAG9B,CAAA"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/testing/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD;;;;;;;GAOG;AAEH;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,iDAAiD,CAAA;AAExF,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,wBAAwB,CAAA;AAEtD,eAAO,MAAM,gBAAgB,EAAE,WAI9B,CAAA"}
@@ -12,8 +12,11 @@
12
12
  * secret is ever sealed with it.
13
13
  */
14
14
  export const TEST_SECRET_ENCRYPTION_KEY = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
15
+ /** The base URL every emailed link is built from in tests. */
16
+ export const TEST_APP_BASE_URL = 'https://kelpie.test';
15
17
  export const TEST_ENVIRONMENT = {
16
18
  NODE_ENV: 'test',
17
19
  SECRET_ENCRYPTION_KEY: TEST_SECRET_ENCRYPTION_KEY,
20
+ APP_BASE_URL: TEST_APP_BASE_URL,
18
21
  };
19
22
  //# sourceMappingURL=environment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/testing/environment.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,8CAA8C,CAAA;AAExF,MAAM,CAAC,MAAM,gBAAgB,GAAgB;IAC3C,QAAQ,EAAE,MAAM;IAChB,qBAAqB,EAAE,0BAA0B;CAClD,CAAA"}
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/testing/environment.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,8CAA8C,CAAA;AAExF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAA;AAEtD,MAAM,CAAC,MAAM,gBAAgB,GAAgB;IAC3C,QAAQ,EAAE,MAAM;IAChB,qBAAqB,EAAE,0BAA0B;IACjD,YAAY,EAAE,iBAAiB;CAChC,CAAA"}
@@ -17,6 +17,14 @@ import type { AppBindings } from './app.ts';
17
17
  export interface WebBundleOptions {
18
18
  /** Directory holding the built `index.html` and its assets. */
19
19
  readonly directory: string;
20
+ /**
21
+ * Prefixes the assembly's own modules answer on beyond core's, via
22
+ * `appRoute`/`appMiddleware`. An unmatched GET under one stays a JSON
23
+ * error instead of becoming the app shell, the same rule `/v1` gets. The
24
+ * assembly names them here because only it knows which of its declared
25
+ * paths are API rather than pages.
26
+ */
27
+ readonly apiPrefixes?: readonly string[];
20
28
  }
21
29
  /** The bundle directory does not hold a build. Thrown at boot, never per request. */
22
30
  export declare class WebBundleError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"webBundle.d.ts","sourceRoot":"","sources":["../src/webBundle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,MAAM,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,qFAAqF;AACrF,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAuCD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAwBtF"}
1
+ {"version":3,"file":"webBundle.d.ts","sourceRoot":"","sources":["../src/webBundle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,MAAM,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACzC;AAED,qFAAqF;AACrF,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AA2CD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CA0BtF"}
package/dist/webBundle.js CHANGED
@@ -10,14 +10,15 @@ export class WebBundleError extends Error {
10
10
  }
11
11
  }
12
12
  /**
13
- * The prefixes `createApp` answers on.
13
+ * The prefixes `createApp` itself answers on.
14
14
  *
15
15
  * `/v1/public` needs no entry of its own: it sits under `/v1`. `MCP_ROUTE_PREFIX`
16
16
  * is imported rather than written out, so moving the endpoint moves this with it.
17
+ * An assembly's own API prefixes arrive through `WebBundleOptions.apiPrefixes`.
17
18
  */
18
- const API_PREFIXES = ['/v1', MCP_ROUTE_PREFIX, '/healthz'];
19
- function isApiRequest(path) {
20
- return API_PREFIXES.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
19
+ const CORE_API_PREFIXES = ['/v1', MCP_ROUTE_PREFIX, '/healthz'];
20
+ function isApiRequestFor(prefixes) {
21
+ return (path) => prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
21
22
  }
22
23
  /**
23
24
  * Restricts a handler to requests for the web app.
@@ -32,7 +33,7 @@ function isApiRequest(path) {
32
33
  * not a page request, and only a `GET` or a `HEAD` can sensibly be answered with
33
34
  * a document.
34
35
  */
35
- function webRequestsOnly(handler) {
36
+ function webRequestsOnly(isApiRequest, handler) {
36
37
  return async (context, next) => {
37
38
  const isDocumentRequest = context.req.method === 'GET' || context.req.method === 'HEAD';
38
39
  if (!isDocumentRequest || isApiRequest(context.req.path)) {
@@ -58,10 +59,11 @@ export function serveWebBundle(app, options) {
58
59
  if (!existsSync(indexHtml)) {
59
60
  throw new WebBundleError(`No index.html in ${directory}. Point WEB_BUNDLE_DIR at a built web bundle, or run the web build first.`);
60
61
  }
62
+ const isApiRequest = isApiRequestFor([...CORE_API_PREFIXES, ...(options.apiPrefixes ?? [])]);
61
63
  // Two registrations rather than one: `serveStatic` calls `next()` when it
62
64
  // finds no file, which is exactly the signal the fallback needs. A request
63
65
  // for a real asset is answered by the first and never reaches the second.
64
- app.use('*', webRequestsOnly(serveStatic({ root: directory })));
66
+ app.use('*', webRequestsOnly(isApiRequest, serveStatic({ root: directory })));
65
67
  // The single-page fallback. The app decides what to draw from the address, so
66
68
  // a deep link to `/people/per_01J…` has to return the same `index.html` even
67
69
  // though no file sits at that path.
@@ -70,6 +72,6 @@ export function serveWebBundle(app, options) {
70
72
  // does by default. Narrowing this by `Accept` would turn a stale asset
71
73
  // reference into a clean 404, and would also turn `curl /people/per_01J…`
72
74
  // into one, so it is left alone.
73
- app.use('*', webRequestsOnly(serveStatic({ path: indexHtml })));
75
+ app.use('*', webRequestsOnly(isApiRequest, serveStatic({ path: indexHtml })));
74
76
  }
75
77
  //# sourceMappingURL=webBundle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webBundle.js","sourceRoot":"","sources":["../src/webBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAI5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAsBzD,qFAAqF;AACrF,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;IAC9B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,YAAY,GAAsB,CAAC,KAAK,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAA;AAE7E,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAA;AACxF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,eAAe,CAAC,OAA0B;IACjD,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC7B,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAA;QAEvF,IAAI,CAAC,iBAAiB,IAAI,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAC/B,CAAC,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,GAAsB,EAAE,OAAyB;IAC9E,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAE/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,cAAc,CACtB,oBAAoB,SAAS,2EAA2E,CACzG,CAAA;IACH,CAAC;IAED,0EAA0E;IAC1E,2EAA2E;IAC3E,0EAA0E;IAC1E,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;IAE/D,8EAA8E;IAC9E,6EAA6E;IAC7E,oCAAoC;IACpC,EAAE;IACF,4EAA4E;IAC5E,uEAAuE;IACvE,0EAA0E;IAC1E,iCAAiC;IACjC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;AACjE,CAAC"}
1
+ {"version":3,"file":"webBundle.js","sourceRoot":"","sources":["../src/webBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAI5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AA8BzD,qFAAqF;AACrF,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;IAC9B,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAsB,CAAC,KAAK,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAA;AAElF,SAAS,eAAe,CAAC,QAA2B;IAClD,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAA;AAC9F,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,eAAe,CACtB,YAAuC,EACvC,OAA0B;IAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC7B,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAA;QAEvF,IAAI,CAAC,iBAAiB,IAAI,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAC/B,CAAC,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,GAAsB,EAAE,OAAyB;IAC9E,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAE/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,cAAc,CACtB,oBAAoB,SAAS,2EAA2E,CACzG,CAAA;IACH,CAAC;IAED,MAAM,YAAY,GAAG,eAAe,CAAC,CAAC,GAAG,iBAAiB,EAAE,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAE5F,0EAA0E;IAC1E,2EAA2E;IAC3E,0EAA0E;IAC1E,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;IAE7E,8EAA8E;IAC9E,6EAA6E;IAC7E,oCAAoC;IACpC,EAAE;IACF,4EAA4E;IAC5E,uEAAuE;IACvE,0EAA0E;IAC1E,iCAAiC;IACjC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;AAC/E,CAAC"}
@@ -0,0 +1,12 @@
1
+ CREATE TABLE "email_verification_tokens" (
2
+ "id" text PRIMARY KEY NOT NULL,
3
+ "user_id" text NOT NULL,
4
+ "token_hash" text NOT NULL,
5
+ "expires_at" timestamp with time zone NOT NULL,
6
+ "used_at" timestamp with time zone,
7
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
8
+ CONSTRAINT "email_verification_tokens_token_hash_unique" UNIQUE("token_hash")
9
+ );
10
+ --> statement-breakpoint
11
+ ALTER TABLE "users" ADD COLUMN "email_verified_at" timestamp with time zone;--> statement-breakpoint
12
+ ALTER TABLE "email_verification_tokens" ADD CONSTRAINT "email_verification_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;