@aotter/mantle 0.2.0-alpha.6 → 0.2.0-alpha.8

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 (946) hide show
  1. package/README.md +157 -45
  2. package/dist/auth/adapter.d.ts +32 -0
  3. package/dist/auth/adapter.js +285 -0
  4. package/dist/auth/admin.d.ts +3 -0
  5. package/dist/auth/admin.js +21 -0
  6. package/dist/auth/caller.d.ts +86 -0
  7. package/dist/auth/caller.js +155 -0
  8. package/dist/auth/hardening.d.ts +24 -0
  9. package/dist/auth/hardening.js +40 -0
  10. package/dist/auth/identity.d.ts +121 -0
  11. package/dist/auth/identity.js +203 -0
  12. package/dist/auth/oauth.d.ts +63 -0
  13. package/dist/auth/oauth.js +217 -0
  14. package/dist/auth/resource-seeds.js +10 -0
  15. package/dist/auth/routes.d.ts +32 -0
  16. package/dist/auth/routes.js +225 -0
  17. package/dist/build/compiler.d.ts +712 -0
  18. package/dist/build/compiler.js +6896 -0
  19. package/dist/{spec → build/spec}/domain/model/ManifestGrammar.d.ts +30 -47
  20. package/dist/{spec → build/spec}/domain/model/RuntimePlan.d.ts +77 -3
  21. package/dist/{spec → build/spec}/domain/model/SqlIr.d.ts +37 -6
  22. package/dist/build/spec/domain/model/UserFields.d.ts +20 -0
  23. package/dist/{spec → build/spec}/domain/service/PlanFingerprint.d.ts +4 -1
  24. package/dist/{spec → build/spec}/kernel/diagnostic.d.ts +1 -30
  25. package/dist/bun/assets.d.ts +2 -0
  26. package/dist/bun/assets.js +24 -0
  27. package/dist/domain/adminOrder.js +24 -0
  28. package/dist/domain/columns.js +55 -0
  29. package/dist/domain/describe/chunk-ZVXBGP7Y.js +424 -0
  30. package/dist/domain/describe/index.d.ts +58 -0
  31. package/dist/domain/describe/index.js +115 -0
  32. package/dist/domain/describe/target-hash.d.ts +8 -0
  33. package/dist/domain/describe/target-hash.js +12 -0
  34. package/dist/domain/describe/targets.d.ts +40 -0
  35. package/dist/domain/entry.js +33 -0
  36. package/dist/domain/generated-tools.js +19 -0
  37. package/dist/domain/generation.d.ts +16 -0
  38. package/dist/domain/generation.js +1 -0
  39. package/dist/domain/input.js +17 -0
  40. package/dist/domain/model.js +1 -0
  41. package/dist/domain/paging.js +230 -0
  42. package/dist/domain/recipes.js +19 -0
  43. package/dist/domain/userReferences.js +5 -0
  44. package/dist/domain/wireScalars.js +47 -0
  45. package/dist/infrastructure/adminEntries.js +153 -0
  46. package/dist/infrastructure/adminPaging.js +72 -0
  47. package/dist/infrastructure/artifacts.js +71 -0
  48. package/dist/infrastructure/authSchema.js +83 -0
  49. package/dist/infrastructure/bundle.js +174 -0
  50. package/dist/infrastructure/cli.js +97 -0
  51. package/dist/infrastructure/generate.d.ts +12 -0
  52. package/dist/infrastructure/generate.js +174 -0
  53. package/dist/infrastructure/generateAuth.d.ts +8 -0
  54. package/dist/infrastructure/generateAuth.js +23 -0
  55. package/dist/infrastructure/inputs.js +41 -0
  56. package/dist/infrastructure/wrangler.js +94 -0
  57. package/dist/kernel/authorization.d.ts +4 -0
  58. package/dist/kernel/authorization.js +16 -0
  59. package/dist/kernel/binds.d.ts +51 -0
  60. package/dist/kernel/binds.js +45 -0
  61. package/dist/kernel/caller-identity.d.ts +24 -0
  62. package/dist/kernel/caller-identity.js +22 -0
  63. package/dist/kernel/contract-error.d.ts +12 -0
  64. package/dist/kernel/contract-error.js +14 -0
  65. package/dist/kernel/contracts.d.ts +139 -0
  66. package/dist/kernel/contracts.js +92 -0
  67. package/dist/{spec/domain/service/CloudflareCron.d.ts → kernel/cron.d.ts} +0 -1
  68. package/dist/{spec/domain/service/CloudflareCron.js → kernel/cron.js} +1 -6
  69. package/dist/kernel/dialect/common.d.ts +39 -0
  70. package/dist/kernel/dialect/common.js +6 -0
  71. package/dist/kernel/dialect/postgres.d.ts +16 -0
  72. package/dist/kernel/dialect/postgres.js +18 -0
  73. package/dist/kernel/dialect/sqlite.d.ts +20 -0
  74. package/dist/kernel/dialect/sqlite.js +34 -0
  75. package/dist/kernel/drain.d.ts +5 -0
  76. package/dist/kernel/drain.js +35 -0
  77. package/dist/kernel/driver/bun-sqlite.d.ts +19 -0
  78. package/dist/kernel/driver/bun-sqlite.js +77 -0
  79. package/dist/kernel/driver/d1.d.ts +24 -0
  80. package/dist/kernel/driver/d1.js +22 -0
  81. package/dist/kernel/driver/postgres.d.ts +25 -0
  82. package/dist/kernel/driver/postgres.js +98 -0
  83. package/dist/kernel/driver/transaction-context.d.ts +10 -0
  84. package/dist/kernel/driver/transaction-context.js +29 -0
  85. package/dist/kernel/email.d.ts +28 -0
  86. package/dist/{auth/emailTemplates.js → kernel/email.js} +13 -2
  87. package/dist/kernel/host-access.d.ts +10 -0
  88. package/dist/kernel/host-access.js +65 -0
  89. package/dist/kernel/host-caller.d.ts +39 -0
  90. package/dist/kernel/host-caller.js +56 -0
  91. package/dist/kernel/json-body.d.ts +4 -0
  92. package/dist/kernel/json-body.js +44 -0
  93. package/dist/kernel/mcp-apps.d.ts +69 -0
  94. package/dist/kernel/mcp-apps.js +40 -0
  95. package/dist/kernel/mcp-call.d.ts +5 -0
  96. package/dist/kernel/mcp-call.js +25 -0
  97. package/dist/kernel/mcp-handler.js +371 -0
  98. package/dist/kernel/mcp.d.ts +106 -0
  99. package/dist/kernel/mcp.js +49 -0
  100. package/dist/kernel/media.d.ts +27 -0
  101. package/dist/kernel/media.js +216 -0
  102. package/dist/kernel/paging.d.ts +55 -0
  103. package/dist/kernel/paging.js +95 -0
  104. package/dist/kernel/publishing.d.ts +4 -0
  105. package/dist/kernel/publishing.js +16 -0
  106. package/dist/{cloudflare/r2Media.d.ts → kernel/r2-media.d.ts} +4 -5
  107. package/dist/kernel/r2-media.js +78 -0
  108. package/dist/kernel/rest-dispatch.js +38 -0
  109. package/dist/kernel/rest-router.js +64 -0
  110. package/dist/kernel/rest.d.ts +58 -0
  111. package/dist/kernel/rest.js +41 -0
  112. package/dist/kernel/scalars.d.ts +6 -0
  113. package/dist/kernel/scalars.js +43 -0
  114. package/dist/kernel/search.js +5 -0
  115. package/dist/{core/site.d.ts → kernel/site-types.d.ts} +38 -9
  116. package/dist/kernel/site-types.js +1 -0
  117. package/dist/kernel/site.d.ts +39 -0
  118. package/dist/kernel/site.js +32 -0
  119. package/dist/kernel/store.d.ts +165 -0
  120. package/dist/kernel/store.js +257 -0
  121. package/dist/kernel/surface.d.ts +10 -0
  122. package/dist/kernel/surface.js +19 -0
  123. package/dist/kernel/sweep.d.ts +17 -0
  124. package/dist/kernel/sweep.js +27 -0
  125. package/dist/kernel/translations.d.ts +1 -0
  126. package/dist/kernel/translations.js +13 -0
  127. package/dist/kernel/user-caller.d.ts +31 -0
  128. package/dist/kernel/user-caller.js +67 -0
  129. package/dist/kernel/user-field-name.js +3 -0
  130. package/dist/kernel/user-fields.d.ts +34 -0
  131. package/dist/kernel/user-fields.js +71 -0
  132. package/dist/kernel/validation.d.ts +15 -0
  133. package/dist/kernel/validation.js +54 -0
  134. package/dist/kernel/web-gateway.js +68 -0
  135. package/dist/kernel/web-head.js +15 -0
  136. package/dist/kernel/web-response.js +8 -0
  137. package/dist/kernel/web.d.ts +77 -0
  138. package/dist/kernel/web.js +158 -0
  139. package/dist/kernel/where.js +27 -0
  140. package/dist/testing/index.d.ts +1 -37
  141. package/dist/testing/index.js +1 -43
  142. package/dist/usecase/adminBindings.js +141 -0
  143. package/dist/usecase/adminClient.js +87 -0
  144. package/dist/usecase/adminDescriptors.js +107 -0
  145. package/dist/usecase/generate.js +165 -0
  146. package/dist/usecase/handlers.js +21 -0
  147. package/dist/usecase/mcp-media.js +17 -0
  148. package/dist/usecase/mcp.js +100 -0
  149. package/dist/usecase/paging.js +71 -0
  150. package/dist/usecase/publishing.js +63 -0
  151. package/dist/usecase/refusals.js +27 -0
  152. package/dist/usecase/rest.js +54 -0
  153. package/dist/usecase/search.js +7 -0
  154. package/dist/usecase/site.js +40 -0
  155. package/dist/usecase/stores.js +62 -0
  156. package/dist/usecase/tool-version.js +9 -0
  157. package/dist/usecase/translations.js +78 -0
  158. package/dist/usecase/ttl.js +20 -0
  159. package/dist/usecase/validation.js +233 -0
  160. package/dist/usecase/web.js +23 -0
  161. package/docs/examples/README.md +31 -16
  162. package/docs/examples/app-shell/README.md +86 -0
  163. package/docs/examples/app-shell/package.json +42 -0
  164. package/docs/examples/app-shell/pnpm-workspace.yaml +8 -0
  165. package/docs/examples/app-shell/smoke-kit.mjs +154 -0
  166. package/docs/examples/app-shell/src/auth.ts +57 -0
  167. package/docs/examples/app-shell/src/handlers.ts +5 -0
  168. package/docs/examples/app-shell/src/index.ts +4 -0
  169. package/docs/examples/app-shell/src/routes.ts +13 -0
  170. package/docs/examples/app-shell/src/schedule.ts +8 -0
  171. package/docs/examples/app-shell/src/service.ts +70 -0
  172. package/docs/examples/app-shell/src/sign-in.ts +41 -0
  173. package/docs/examples/app-shell/src/signup.ts +8 -0
  174. package/docs/examples/{reference-service → app-shell}/tsconfig.json +6 -2
  175. package/docs/examples/app-shell/worker-configuration.d.ts +22 -0
  176. package/docs/examples/app-shell/wrangler.jsonc +62 -0
  177. package/docs/examples/club-events/README.md +60 -0
  178. package/docs/examples/club-events/manifests/club-events.yaml +225 -0
  179. package/docs/examples/club-events/smoke.mjs +121 -0
  180. package/docs/examples/club-events/src/handlers.ts +25 -0
  181. package/docs/examples/club-events/src/signup.ts +9 -0
  182. package/docs/examples/generated-web/README.md +78 -0
  183. package/docs/examples/generated-web/posts.yaml +38 -0
  184. package/docs/examples/generated-web/seed.sql +6 -0
  185. package/docs/examples/generated-web/src/worker.ts +43 -0
  186. package/docs/examples/generated-web/tsconfig.json +8 -0
  187. package/docs/examples/generated-web/wrangler.jsonc +8 -0
  188. package/docs/examples/purchasing/.dev.vars.example +6 -0
  189. package/docs/examples/purchasing/README.md +90 -0
  190. package/docs/examples/purchasing/manifests/purchasing.yaml +341 -0
  191. package/docs/examples/purchasing/seed.sql +4 -0
  192. package/docs/examples/purchasing/smoke.mjs +177 -0
  193. package/docs/examples/purchasing/src/admin.tsx +13 -0
  194. package/docs/examples/purchasing/src/handlers.ts +33 -0
  195. package/docs/examples/purchasing/src/notify.ts +29 -0
  196. package/docs/examples/purchasing/src/requests-page.ts +57 -0
  197. package/docs/examples/purchasing/src/routes.ts +53 -0
  198. package/docs/examples/purchasing/src/schedule.ts +31 -0
  199. package/docs/examples/purchasing/src/signup.ts +5 -0
  200. package/docs/examples/purchasing/src/supplier.ts +32 -0
  201. package/docs/examples/purchasing/wrangler.jsonc +69 -0
  202. package/docs/examples/recipes/README.md +58 -0
  203. package/docs/examples/recipes/manifests/recipes.yaml +75 -0
  204. package/docs/examples/recipes/smoke.mjs +102 -0
  205. package/docs/examples/recipes/src/media.ts +13 -0
  206. package/docs/examples/recipes/src/pages.ts +99 -0
  207. package/docs/examples/recipes/src/routes.ts +71 -0
  208. package/docs/examples/recipes/src/site-config.ts +12 -0
  209. package/docs/examples/recipes/wrangler.jsonc +74 -0
  210. package/docs/handbook/cloudflare/authentication.md +164 -214
  211. package/docs/handbook/cloudflare/chatgpt-sites.md +4 -113
  212. package/docs/handbook/cloudflare/deploy-and-operate.md +38 -103
  213. package/docs/handbook/cloudflare/media-r2.md +62 -133
  214. package/docs/handbook/cloudflare/service-entry.md +210 -119
  215. package/docs/handbook/concepts/authorization.md +10 -123
  216. package/docs/handbook/concepts/four-atoms.md +9 -92
  217. package/docs/handbook/concepts/lifecycle-and-locales.md +9 -80
  218. package/docs/handbook/concepts/mcp-and-agents.md +24 -136
  219. package/docs/handbook/concepts/procedures-and-triggers.md +5 -162
  220. package/docs/handbook/concepts/runtime-and-adapters.md +15 -224
  221. package/docs/handbook/concepts/views.md +10 -109
  222. package/docs/handbook/examples/hub.md +2 -18
  223. package/docs/handbook/guides/adapter-guide.md +11 -0
  224. package/docs/handbook/guides/admin-ui.md +111 -164
  225. package/docs/handbook/guides/agent-setup.md +32 -27
  226. package/docs/handbook/guides/email.md +86 -0
  227. package/docs/handbook/guides/mcp-apps.md +483 -0
  228. package/docs/handbook/guides/native-admin.md +543 -0
  229. package/docs/handbook/guides/native-execution.md +132 -0
  230. package/docs/handbook/guides/oauth.md +161 -0
  231. package/docs/handbook/guides/postgres-adapters.md +56 -0
  232. package/docs/handbook/guides/public-pages.md +53 -0
  233. package/docs/handbook/guides/size-and-startup.md +9 -0
  234. package/docs/handbook/guides/typed-queries.md +39 -102
  235. package/docs/handbook/navigation.json +160 -31
  236. package/docs/handbook/reference/admin-descriptors.md +53 -0
  237. package/docs/handbook/reference/authorization.md +44 -52
  238. package/docs/handbook/reference/describe.md +56 -0
  239. package/docs/handbook/reference/diagnostics.md +15 -79
  240. package/docs/handbook/reference/features.md +45 -53
  241. package/docs/handbook/reference/manifest.md +6 -69
  242. package/docs/handbook/reference/procedure.md +11 -116
  243. package/docs/handbook/reference/schema.md +85 -185
  244. package/docs/handbook/reference/site-config.md +5 -65
  245. package/docs/handbook/reference/surface.md +389 -97
  246. package/docs/handbook/reference/trigger.md +54 -90
  247. package/docs/handbook/reference/view.md +32 -160
  248. package/docs/handbook/releases/index.md +120 -13
  249. package/docs/handbook/start/overview.md +9 -56
  250. package/docs/handbook/start/project-and-cli.md +40 -149
  251. package/docs/handbook/start/quickstart-worker.md +38 -116
  252. package/docs/skills/develop/SKILL.md +35 -123
  253. package/docs/skills/develop/mcp-app.md +37 -77
  254. package/docs/skills/integrate/SKILL.md +42 -84
  255. package/docs/skills/media-gc/SKILL.md +21 -8
  256. package/docs/skills/provision/SKILL.md +28 -91
  257. package/docs/skills/update/SKILL.md +19 -43
  258. package/docs/source/scripts/postgres-adapter.ts +101 -0
  259. package/docs/upgrade-0.1-to-0.2.md +25 -9
  260. package/package.json +97 -112
  261. package/skills/.keep +0 -0
  262. package/skills/README.md +67 -0
  263. package/skills/mantle/SKILL.md +135 -0
  264. package/skills/mantle/references/local-testing.md +15 -0
  265. package/skills/mantle/references/web.md +41 -0
  266. package/skills/mantle/references/website.md +49 -0
  267. package/dist/admin/consent.d.ts +0 -17
  268. package/dist/admin/consent.d.ts.map +0 -1
  269. package/dist/admin/consent.js +0 -17
  270. package/dist/admin/consent.js.map +0 -1
  271. package/dist/admin/createAdminSurface.d.ts +0 -25
  272. package/dist/admin/createAdminSurface.d.ts.map +0 -1
  273. package/dist/admin/createAdminSurface.js +0 -635
  274. package/dist/admin/createAdminSurface.js.map +0 -1
  275. package/dist/admin/design.d.ts +0 -7
  276. package/dist/admin/design.d.ts.map +0 -1
  277. package/dist/admin/design.js +0 -18
  278. package/dist/admin/design.js.map +0 -1
  279. package/dist/admin/developerConsole.d.ts +0 -267
  280. package/dist/admin/developerConsole.d.ts.map +0 -1
  281. package/dist/admin/developerConsole.js +0 -136
  282. package/dist/admin/developerConsole.js.map +0 -1
  283. package/dist/admin/extensions.d.ts +0 -290
  284. package/dist/admin/extensions.d.ts.map +0 -1
  285. package/dist/admin/extensions.js +0 -532
  286. package/dist/admin/extensions.js.map +0 -1
  287. package/dist/admin/identity.d.ts +0 -62
  288. package/dist/admin/identity.d.ts.map +0 -1
  289. package/dist/admin/identity.js +0 -7
  290. package/dist/admin/identity.js.map +0 -1
  291. package/dist/admin/index.d.ts +0 -7
  292. package/dist/admin/index.d.ts.map +0 -1
  293. package/dist/admin/index.js +0 -7
  294. package/dist/admin/index.js.map +0 -1
  295. package/dist/admin/procedureFlow.d.ts +0 -38
  296. package/dist/admin/procedureFlow.d.ts.map +0 -1
  297. package/dist/admin/procedureFlow.js +0 -188
  298. package/dist/admin/procedureFlow.js.map +0 -1
  299. package/dist/auth/ConsoleEmailSender.d.ts +0 -15
  300. package/dist/auth/ConsoleEmailSender.d.ts.map +0 -1
  301. package/dist/auth/ConsoleEmailSender.js +0 -19
  302. package/dist/auth/ConsoleEmailSender.js.map +0 -1
  303. package/dist/auth/appleClientSecret.d.ts +0 -75
  304. package/dist/auth/appleClientSecret.d.ts.map +0 -1
  305. package/dist/auth/appleClientSecret.js +0 -116
  306. package/dist/auth/appleClientSecret.js.map +0 -1
  307. package/dist/auth/buildAuth.d.ts +0 -4568
  308. package/dist/auth/buildAuth.d.ts.map +0 -1
  309. package/dist/auth/buildAuth.js +0 -312
  310. package/dist/auth/buildAuth.js.map +0 -1
  311. package/dist/auth/callerResolver.d.ts +0 -52
  312. package/dist/auth/callerResolver.d.ts.map +0 -1
  313. package/dist/auth/callerResolver.js +0 -52
  314. package/dist/auth/callerResolver.js.map +0 -1
  315. package/dist/auth/createAuthRoutes.d.ts +0 -22
  316. package/dist/auth/createAuthRoutes.d.ts.map +0 -1
  317. package/dist/auth/createAuthRoutes.js +0 -129
  318. package/dist/auth/createAuthRoutes.js.map +0 -1
  319. package/dist/auth/createMantleAuth.d.ts +0 -3
  320. package/dist/auth/createMantleAuth.d.ts.map +0 -1
  321. package/dist/auth/createMantleAuth.js +0 -504
  322. package/dist/auth/createMantleAuth.js.map +0 -1
  323. package/dist/auth/db.d.ts +0 -18
  324. package/dist/auth/db.d.ts.map +0 -1
  325. package/dist/auth/db.js +0 -27
  326. package/dist/auth/db.js.map +0 -1
  327. package/dist/auth/emailTemplates.d.ts +0 -7
  328. package/dist/auth/emailTemplates.d.ts.map +0 -1
  329. package/dist/auth/emailTemplates.js.map +0 -1
  330. package/dist/auth/index.d.ts +0 -9
  331. package/dist/auth/index.d.ts.map +0 -1
  332. package/dist/auth/index.js +0 -7
  333. package/dist/auth/index.js.map +0 -1
  334. package/dist/auth/methods.d.ts +0 -717
  335. package/dist/auth/methods.d.ts.map +0 -1
  336. package/dist/auth/methods.js +0 -321
  337. package/dist/auth/methods.js.map +0 -1
  338. package/dist/auth/oauthTokens.d.ts +0 -24
  339. package/dist/auth/oauthTokens.d.ts.map +0 -1
  340. package/dist/auth/oauthTokens.js +0 -146
  341. package/dist/auth/oauthTokens.js.map +0 -1
  342. package/dist/auth/setupIncomplete.d.ts +0 -16
  343. package/dist/auth/setupIncomplete.d.ts.map +0 -1
  344. package/dist/auth/setupIncomplete.js +0 -50
  345. package/dist/auth/setupIncomplete.js.map +0 -1
  346. package/dist/auth/types.d.ts +0 -440
  347. package/dist/auth/types.d.ts.map +0 -1
  348. package/dist/auth/types.js +0 -10
  349. package/dist/auth/types.js.map +0 -1
  350. package/dist/bun/index.d.ts +0 -21
  351. package/dist/bun/index.d.ts.map +0 -1
  352. package/dist/bun/index.js +0 -46
  353. package/dist/bun/index.js.map +0 -1
  354. package/dist/cli/emitModule.d.ts +0 -7
  355. package/dist/cli/emitModule.d.ts.map +0 -1
  356. package/dist/cli/emitModule.js +0 -127
  357. package/dist/cli/emitModule.js.map +0 -1
  358. package/dist/cli/generate.d.ts +0 -8
  359. package/dist/cli/generate.d.ts.map +0 -1
  360. package/dist/cli/generate.js +0 -391
  361. package/dist/cli/generate.js.map +0 -1
  362. package/dist/cli/main.d.ts +0 -3
  363. package/dist/cli/main.d.ts.map +0 -1
  364. package/dist/cli/main.js +0 -21
  365. package/dist/cli/main.js.map +0 -1
  366. package/dist/cli/preset.d.ts +0 -18
  367. package/dist/cli/preset.d.ts.map +0 -1
  368. package/dist/cli/preset.js +0 -405
  369. package/dist/cli/preset.js.map +0 -1
  370. package/dist/cloudflare/index.d.ts +0 -25
  371. package/dist/cloudflare/index.d.ts.map +0 -1
  372. package/dist/cloudflare/index.js +0 -16
  373. package/dist/cloudflare/index.js.map +0 -1
  374. package/dist/cloudflare/r2Media.d.ts.map +0 -1
  375. package/dist/cloudflare/r2Media.js +0 -69
  376. package/dist/cloudflare/r2Media.js.map +0 -1
  377. package/dist/core/caller.d.ts +0 -35
  378. package/dist/core/caller.d.ts.map +0 -1
  379. package/dist/core/caller.js +0 -3
  380. package/dist/core/caller.js.map +0 -1
  381. package/dist/core/createMantle.d.ts +0 -22
  382. package/dist/core/createMantle.d.ts.map +0 -1
  383. package/dist/core/createMantle.js +0 -117
  384. package/dist/core/createMantle.js.map +0 -1
  385. package/dist/core/dialect.d.ts +0 -53
  386. package/dist/core/dialect.d.ts.map +0 -1
  387. package/dist/core/dialect.js +0 -7
  388. package/dist/core/dialect.js.map +0 -1
  389. package/dist/core/driver.d.ts +0 -24
  390. package/dist/core/driver.d.ts.map +0 -1
  391. package/dist/core/driver.js +0 -2
  392. package/dist/core/driver.js.map +0 -1
  393. package/dist/core/email.d.ts +0 -17
  394. package/dist/core/email.d.ts.map +0 -1
  395. package/dist/core/email.js +0 -2
  396. package/dist/core/email.js.map +0 -1
  397. package/dist/core/index.d.ts +0 -16
  398. package/dist/core/index.d.ts.map +0 -1
  399. package/dist/core/index.js +0 -16
  400. package/dist/core/index.js.map +0 -1
  401. package/dist/core/invocation.d.ts +0 -66
  402. package/dist/core/invocation.d.ts.map +0 -1
  403. package/dist/core/invocation.js +0 -3
  404. package/dist/core/invocation.js.map +0 -1
  405. package/dist/core/observation.d.ts +0 -3
  406. package/dist/core/observation.d.ts.map +0 -1
  407. package/dist/core/observation.js +0 -10
  408. package/dist/core/observation.js.map +0 -1
  409. package/dist/core/runtime/auth.d.ts +0 -9
  410. package/dist/core/runtime/auth.d.ts.map +0 -1
  411. package/dist/core/runtime/auth.js +0 -39
  412. package/dist/core/runtime/auth.js.map +0 -1
  413. package/dist/core/runtime/createRuntime.d.ts +0 -23
  414. package/dist/core/runtime/createRuntime.d.ts.map +0 -1
  415. package/dist/core/runtime/createRuntime.js +0 -214
  416. package/dist/core/runtime/createRuntime.js.map +0 -1
  417. package/dist/core/runtime/verifyPlan.d.ts +0 -34
  418. package/dist/core/runtime/verifyPlan.d.ts.map +0 -1
  419. package/dist/core/runtime/verifyPlan.js +0 -301
  420. package/dist/core/runtime/verifyPlan.js.map +0 -1
  421. package/dist/core/service.d.ts +0 -45
  422. package/dist/core/service.d.ts.map +0 -1
  423. package/dist/core/service.js +0 -2
  424. package/dist/core/service.js.map +0 -1
  425. package/dist/core/sessionUser.d.ts +0 -14
  426. package/dist/core/sessionUser.d.ts.map +0 -1
  427. package/dist/core/sessionUser.js +0 -4
  428. package/dist/core/sessionUser.js.map +0 -1
  429. package/dist/core/site.d.ts.map +0 -1
  430. package/dist/core/site.js +0 -2
  431. package/dist/core/site.js.map +0 -1
  432. package/dist/core/siteConfig.d.ts +0 -5
  433. package/dist/core/siteConfig.d.ts.map +0 -1
  434. package/dist/core/siteConfig.js +0 -24
  435. package/dist/core/siteConfig.js.map +0 -1
  436. package/dist/core/sql/allowlist.d.ts +0 -67
  437. package/dist/core/sql/allowlist.d.ts.map +0 -1
  438. package/dist/core/sql/allowlist.js +0 -737
  439. package/dist/core/sql/allowlist.js.map +0 -1
  440. package/dist/core/sql/ast.d.ts +0 -24
  441. package/dist/core/sql/ast.d.ts.map +0 -1
  442. package/dist/core/sql/ast.js +0 -32
  443. package/dist/core/sql/ast.js.map +0 -1
  444. package/dist/core/sql/compile.d.ts +0 -50
  445. package/dist/core/sql/compile.d.ts.map +0 -1
  446. package/dist/core/sql/compile.js +0 -48
  447. package/dist/core/sql/compile.js.map +0 -1
  448. package/dist/core/sql/policy.d.ts +0 -123
  449. package/dist/core/sql/policy.d.ts.map +0 -1
  450. package/dist/core/sql/policy.js +0 -398
  451. package/dist/core/sql/policy.js.map +0 -1
  452. package/dist/core/sql/positions.d.ts +0 -30
  453. package/dist/core/sql/positions.d.ts.map +0 -1
  454. package/dist/core/sql/positions.js +0 -22
  455. package/dist/core/sql/positions.js.map +0 -1
  456. package/dist/core/sql/run.d.ts +0 -68
  457. package/dist/core/sql/run.d.ts.map +0 -1
  458. package/dist/core/sql/run.js +0 -384
  459. package/dist/core/sql/run.js.map +0 -1
  460. package/dist/core/store/createStore.d.ts +0 -49
  461. package/dist/core/store/createStore.d.ts.map +0 -1
  462. package/dist/core/store/createStore.js +0 -227
  463. package/dist/core/store/createStore.js.map +0 -1
  464. package/dist/core/store/cursor.d.ts +0 -4
  465. package/dist/core/store/cursor.d.ts.map +0 -1
  466. package/dist/core/store/cursor.js +0 -22
  467. package/dist/core/store/cursor.js.map +0 -1
  468. package/dist/core/store/json.d.ts +0 -80
  469. package/dist/core/store/json.d.ts.map +0 -1
  470. package/dist/core/store/json.js +0 -342
  471. package/dist/core/store/json.js.map +0 -1
  472. package/dist/core/store.d.ts +0 -160
  473. package/dist/core/store.d.ts.map +0 -1
  474. package/dist/core/store.js +0 -2
  475. package/dist/core/store.js.map +0 -1
  476. package/dist/core/wire.d.ts +0 -20
  477. package/dist/core/wire.d.ts.map +0 -1
  478. package/dist/core/wire.js +0 -84
  479. package/dist/core/wire.js.map +0 -1
  480. package/dist/core/withCaller.d.ts +0 -24
  481. package/dist/core/withCaller.d.ts.map +0 -1
  482. package/dist/core/withCaller.js +0 -35
  483. package/dist/core/withCaller.js.map +0 -1
  484. package/dist/d1/adapter.d.ts +0 -12
  485. package/dist/d1/adapter.d.ts.map +0 -1
  486. package/dist/d1/adapter.js +0 -23
  487. package/dist/d1/adapter.js.map +0 -1
  488. package/dist/d1/codec.d.ts +0 -14
  489. package/dist/d1/codec.d.ts.map +0 -1
  490. package/dist/d1/codec.js +0 -136
  491. package/dist/d1/codec.js.map +0 -1
  492. package/dist/d1/compile/index.d.ts +0 -9
  493. package/dist/d1/compile/index.d.ts.map +0 -1
  494. package/dist/d1/compile/index.js +0 -9
  495. package/dist/d1/compile/index.js.map +0 -1
  496. package/dist/d1/dialect.d.ts +0 -4
  497. package/dist/d1/dialect.d.ts.map +0 -1
  498. package/dist/d1/dialect.js +0 -13
  499. package/dist/d1/dialect.js.map +0 -1
  500. package/dist/d1/executor.d.ts +0 -15
  501. package/dist/d1/executor.d.ts.map +0 -1
  502. package/dist/d1/executor.js +0 -96
  503. package/dist/d1/executor.js.map +0 -1
  504. package/dist/d1/index.d.ts +0 -6
  505. package/dist/d1/index.d.ts.map +0 -1
  506. package/dist/d1/index.js +0 -6
  507. package/dist/d1/index.js.map +0 -1
  508. package/dist/d1/lower.d.ts +0 -8
  509. package/dist/d1/lower.d.ts.map +0 -1
  510. package/dist/d1/lower.js +0 -167
  511. package/dist/d1/lower.js.map +0 -1
  512. package/dist/d1/media.d.ts +0 -5
  513. package/dist/d1/media.d.ts.map +0 -1
  514. package/dist/d1/media.js +0 -157
  515. package/dist/d1/media.js.map +0 -1
  516. package/dist/d1/migrations.d.ts +0 -12
  517. package/dist/d1/migrations.d.ts.map +0 -1
  518. package/dist/d1/migrations.js +0 -111
  519. package/dist/d1/migrations.js.map +0 -1
  520. package/dist/d1/print.d.ts +0 -28
  521. package/dist/d1/print.d.ts.map +0 -1
  522. package/dist/d1/print.js +0 -54
  523. package/dist/d1/print.js.map +0 -1
  524. package/dist/d1/site.d.ts +0 -17
  525. package/dist/d1/site.d.ts.map +0 -1
  526. package/dist/d1/site.js +0 -63
  527. package/dist/d1/site.js.map +0 -1
  528. package/dist/d1/storage.d.ts +0 -34
  529. package/dist/d1/storage.d.ts.map +0 -1
  530. package/dist/d1/storage.js +0 -288
  531. package/dist/d1/storage.js.map +0 -1
  532. package/dist/d1/tz.d.ts +0 -21
  533. package/dist/d1/tz.d.ts.map +0 -1
  534. package/dist/d1/tz.js +0 -54
  535. package/dist/d1/tz.js.map +0 -1
  536. package/dist/d1/validator.d.ts +0 -10
  537. package/dist/d1/validator.d.ts.map +0 -1
  538. package/dist/d1/validator.js +0 -33
  539. package/dist/d1/validator.js.map +0 -1
  540. package/dist/mcp/apps.d.ts +0 -43
  541. package/dist/mcp/apps.d.ts.map +0 -1
  542. package/dist/mcp/apps.js +0 -57
  543. package/dist/mcp/apps.js.map +0 -1
  544. package/dist/mcp/catalog.d.ts +0 -55
  545. package/dist/mcp/catalog.d.ts.map +0 -1
  546. package/dist/mcp/catalog.js +0 -81
  547. package/dist/mcp/catalog.js.map +0 -1
  548. package/dist/mcp/createMcpSurface.d.ts +0 -60
  549. package/dist/mcp/createMcpSurface.d.ts.map +0 -1
  550. package/dist/mcp/createMcpSurface.js +0 -182
  551. package/dist/mcp/createMcpSurface.js.map +0 -1
  552. package/dist/mcp/index.d.ts +0 -4
  553. package/dist/mcp/index.d.ts.map +0 -1
  554. package/dist/mcp/index.js +0 -4
  555. package/dist/mcp/index.js.map +0 -1
  556. package/dist/mcp/media.d.ts +0 -9
  557. package/dist/mcp/media.d.ts.map +0 -1
  558. package/dist/mcp/media.js +0 -33
  559. package/dist/mcp/media.js.map +0 -1
  560. package/dist/postgres/adapter.d.ts +0 -23
  561. package/dist/postgres/adapter.d.ts.map +0 -1
  562. package/dist/postgres/adapter.js +0 -50
  563. package/dist/postgres/adapter.js.map +0 -1
  564. package/dist/postgres/codec.d.ts +0 -13
  565. package/dist/postgres/codec.d.ts.map +0 -1
  566. package/dist/postgres/codec.js +0 -110
  567. package/dist/postgres/codec.js.map +0 -1
  568. package/dist/postgres/compile/index.d.ts +0 -9
  569. package/dist/postgres/compile/index.d.ts.map +0 -1
  570. package/dist/postgres/compile/index.js +0 -9
  571. package/dist/postgres/compile/index.js.map +0 -1
  572. package/dist/postgres/driver.d.ts +0 -109
  573. package/dist/postgres/driver.d.ts.map +0 -1
  574. package/dist/postgres/driver.js +0 -186
  575. package/dist/postgres/driver.js.map +0 -1
  576. package/dist/postgres/executor.d.ts +0 -28
  577. package/dist/postgres/executor.d.ts.map +0 -1
  578. package/dist/postgres/executor.js +0 -96
  579. package/dist/postgres/executor.js.map +0 -1
  580. package/dist/postgres/index.d.ts +0 -8
  581. package/dist/postgres/index.d.ts.map +0 -1
  582. package/dist/postgres/index.js +0 -8
  583. package/dist/postgres/index.js.map +0 -1
  584. package/dist/postgres/lower.d.ts +0 -6
  585. package/dist/postgres/lower.d.ts.map +0 -1
  586. package/dist/postgres/lower.js +0 -152
  587. package/dist/postgres/lower.js.map +0 -1
  588. package/dist/postgres/print.d.ts +0 -11
  589. package/dist/postgres/print.d.ts.map +0 -1
  590. package/dist/postgres/print.js +0 -108
  591. package/dist/postgres/print.js.map +0 -1
  592. package/dist/postgres/session.d.ts +0 -9
  593. package/dist/postgres/session.d.ts.map +0 -1
  594. package/dist/postgres/session.js +0 -111
  595. package/dist/postgres/session.js.map +0 -1
  596. package/dist/postgres/storage.d.ts +0 -32
  597. package/dist/postgres/storage.d.ts.map +0 -1
  598. package/dist/postgres/storage.js +0 -283
  599. package/dist/postgres/storage.js.map +0 -1
  600. package/dist/postgres/validator.d.ts +0 -13
  601. package/dist/postgres/validator.d.ts.map +0 -1
  602. package/dist/postgres/validator.js +0 -53
  603. package/dist/postgres/validator.js.map +0 -1
  604. package/dist/spec/domain/index.d.ts +0 -3
  605. package/dist/spec/domain/index.d.ts.map +0 -1
  606. package/dist/spec/domain/index.js +0 -3
  607. package/dist/spec/domain/index.js.map +0 -1
  608. package/dist/spec/domain/model/ContentState.d.ts +0 -8
  609. package/dist/spec/domain/model/ContentState.d.ts.map +0 -1
  610. package/dist/spec/domain/model/ContentState.js +0 -7
  611. package/dist/spec/domain/model/ContentState.js.map +0 -1
  612. package/dist/spec/domain/model/Entry.d.ts +0 -29
  613. package/dist/spec/domain/model/Entry.d.ts.map +0 -1
  614. package/dist/spec/domain/model/Entry.js +0 -16
  615. package/dist/spec/domain/model/Entry.js.map +0 -1
  616. package/dist/spec/domain/model/Locale.d.ts +0 -30
  617. package/dist/spec/domain/model/Locale.d.ts.map +0 -1
  618. package/dist/spec/domain/model/Locale.js +0 -33
  619. package/dist/spec/domain/model/Locale.js.map +0 -1
  620. package/dist/spec/domain/model/ManifestGrammar.d.ts.map +0 -1
  621. package/dist/spec/domain/model/ManifestGrammar.js +0 -153
  622. package/dist/spec/domain/model/ManifestGrammar.js.map +0 -1
  623. package/dist/spec/domain/model/MediaMimeAccept.d.ts +0 -55
  624. package/dist/spec/domain/model/MediaMimeAccept.d.ts.map +0 -1
  625. package/dist/spec/domain/model/MediaMimeAccept.js +0 -90
  626. package/dist/spec/domain/model/MediaMimeAccept.js.map +0 -1
  627. package/dist/spec/domain/model/RuntimePlan.d.ts.map +0 -1
  628. package/dist/spec/domain/model/RuntimePlan.js +0 -4
  629. package/dist/spec/domain/model/RuntimePlan.js.map +0 -1
  630. package/dist/spec/domain/model/SiteConfig.d.ts +0 -173
  631. package/dist/spec/domain/model/SiteConfig.d.ts.map +0 -1
  632. package/dist/spec/domain/model/SiteConfig.js +0 -13
  633. package/dist/spec/domain/model/SiteConfig.js.map +0 -1
  634. package/dist/spec/domain/model/SqlIr.d.ts.map +0 -1
  635. package/dist/spec/domain/model/SqlIr.js +0 -95
  636. package/dist/spec/domain/model/SqlIr.js.map +0 -1
  637. package/dist/spec/domain/model/index.d.ts +0 -14
  638. package/dist/spec/domain/model/index.d.ts.map +0 -1
  639. package/dist/spec/domain/model/index.js +0 -14
  640. package/dist/spec/domain/model/index.js.map +0 -1
  641. package/dist/spec/domain/service/CloudflareCron.d.ts.map +0 -1
  642. package/dist/spec/domain/service/CloudflareCron.js.map +0 -1
  643. package/dist/spec/domain/service/CrossSchemaChecker.d.ts +0 -34
  644. package/dist/spec/domain/service/CrossSchemaChecker.d.ts.map +0 -1
  645. package/dist/spec/domain/service/CrossSchemaChecker.js +0 -114
  646. package/dist/spec/domain/service/CrossSchemaChecker.js.map +0 -1
  647. package/dist/spec/domain/service/EntryDataValidator.d.ts +0 -56
  648. package/dist/spec/domain/service/EntryDataValidator.d.ts.map +0 -1
  649. package/dist/spec/domain/service/EntryDataValidator.js +0 -88
  650. package/dist/spec/domain/service/EntryDataValidator.js.map +0 -1
  651. package/dist/spec/domain/service/JsonSchemaToZod.d.ts +0 -29
  652. package/dist/spec/domain/service/JsonSchemaToZod.d.ts.map +0 -1
  653. package/dist/spec/domain/service/JsonSchemaToZod.js +0 -156
  654. package/dist/spec/domain/service/JsonSchemaToZod.js.map +0 -1
  655. package/dist/spec/domain/service/LifecycleStateMachine.d.ts +0 -75
  656. package/dist/spec/domain/service/LifecycleStateMachine.d.ts.map +0 -1
  657. package/dist/spec/domain/service/LifecycleStateMachine.js +0 -76
  658. package/dist/spec/domain/service/LifecycleStateMachine.js.map +0 -1
  659. package/dist/spec/domain/service/LocaleCanonicalizer.d.ts +0 -29
  660. package/dist/spec/domain/service/LocaleCanonicalizer.d.ts.map +0 -1
  661. package/dist/spec/domain/service/LocaleCanonicalizer.js +0 -96
  662. package/dist/spec/domain/service/LocaleCanonicalizer.js.map +0 -1
  663. package/dist/spec/domain/service/ManifestFieldChecks.d.ts +0 -60
  664. package/dist/spec/domain/service/ManifestFieldChecks.d.ts.map +0 -1
  665. package/dist/spec/domain/service/ManifestFieldChecks.js +0 -116
  666. package/dist/spec/domain/service/ManifestFieldChecks.js.map +0 -1
  667. package/dist/spec/domain/service/ManifestGraphValidator.d.ts +0 -15
  668. package/dist/spec/domain/service/ManifestGraphValidator.d.ts.map +0 -1
  669. package/dist/spec/domain/service/ManifestGraphValidator.js +0 -225
  670. package/dist/spec/domain/service/ManifestGraphValidator.js.map +0 -1
  671. package/dist/spec/domain/service/ManifestLinker.d.ts +0 -45
  672. package/dist/spec/domain/service/ManifestLinker.d.ts.map +0 -1
  673. package/dist/spec/domain/service/ManifestLinker.js +0 -92
  674. package/dist/spec/domain/service/ManifestLinker.js.map +0 -1
  675. package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts +0 -16
  676. package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts.map +0 -1
  677. package/dist/spec/domain/service/ManifestLocaleTrimmer.js +0 -76
  678. package/dist/spec/domain/service/ManifestLocaleTrimmer.js.map +0 -1
  679. package/dist/spec/domain/service/ManifestParser.d.ts +0 -49
  680. package/dist/spec/domain/service/ManifestParser.d.ts.map +0 -1
  681. package/dist/spec/domain/service/ManifestParser.js +0 -203
  682. package/dist/spec/domain/service/ManifestParser.js.map +0 -1
  683. package/dist/spec/domain/service/ManifestPartition.d.ts +0 -9
  684. package/dist/spec/domain/service/ManifestPartition.d.ts.map +0 -1
  685. package/dist/spec/domain/service/ManifestPartition.js +0 -19
  686. package/dist/spec/domain/service/ManifestPartition.js.map +0 -1
  687. package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts +0 -33
  688. package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts.map +0 -1
  689. package/dist/spec/domain/service/ManifestPathDiagnoser.js +0 -43
  690. package/dist/spec/domain/service/ManifestPathDiagnoser.js.map +0 -1
  691. package/dist/spec/domain/service/ManifestSourceSpans.d.ts +0 -10
  692. package/dist/spec/domain/service/ManifestSourceSpans.d.ts.map +0 -1
  693. package/dist/spec/domain/service/ManifestSourceSpans.js +0 -76
  694. package/dist/spec/domain/service/ManifestSourceSpans.js.map +0 -1
  695. package/dist/spec/domain/service/McpToolNaming.d.ts +0 -25
  696. package/dist/spec/domain/service/McpToolNaming.d.ts.map +0 -1
  697. package/dist/spec/domain/service/McpToolNaming.js +0 -50
  698. package/dist/spec/domain/service/McpToolNaming.js.map +0 -1
  699. package/dist/spec/domain/service/PlanFingerprint.d.ts.map +0 -1
  700. package/dist/spec/domain/service/PlanFingerprint.js +0 -14
  701. package/dist/spec/domain/service/PlanFingerprint.js.map +0 -1
  702. package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts +0 -4
  703. package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts.map +0 -1
  704. package/dist/spec/domain/service/ProcedureViewSpecChecks.js +0 -211
  705. package/dist/spec/domain/service/ProcedureViewSpecChecks.js.map +0 -1
  706. package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts +0 -44
  707. package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts.map +0 -1
  708. package/dist/spec/domain/service/SchemaAdminUiChecker.js +0 -333
  709. package/dist/spec/domain/service/SchemaAdminUiChecker.js.map +0 -1
  710. package/dist/spec/domain/service/SchemaIndexChecker.d.ts +0 -33
  711. package/dist/spec/domain/service/SchemaIndexChecker.d.ts.map +0 -1
  712. package/dist/spec/domain/service/SchemaIndexChecker.js +0 -256
  713. package/dist/spec/domain/service/SchemaIndexChecker.js.map +0 -1
  714. package/dist/spec/domain/service/SchemaSearchChecker.d.ts +0 -11
  715. package/dist/spec/domain/service/SchemaSearchChecker.d.ts.map +0 -1
  716. package/dist/spec/domain/service/SchemaSearchChecker.js +0 -78
  717. package/dist/spec/domain/service/SchemaSearchChecker.js.map +0 -1
  718. package/dist/spec/domain/service/SchemaSpecChecks.d.ts +0 -31
  719. package/dist/spec/domain/service/SchemaSpecChecks.d.ts.map +0 -1
  720. package/dist/spec/domain/service/SchemaSpecChecks.js +0 -445
  721. package/dist/spec/domain/service/SchemaSpecChecks.js.map +0 -1
  722. package/dist/spec/domain/service/SiteDefaultsValidator.d.ts +0 -39
  723. package/dist/spec/domain/service/SiteDefaultsValidator.d.ts.map +0 -1
  724. package/dist/spec/domain/service/SiteDefaultsValidator.js +0 -194
  725. package/dist/spec/domain/service/SiteDefaultsValidator.js.map +0 -1
  726. package/dist/spec/domain/service/SqlClassify.d.ts +0 -19
  727. package/dist/spec/domain/service/SqlClassify.d.ts.map +0 -1
  728. package/dist/spec/domain/service/SqlClassify.js +0 -42
  729. package/dist/spec/domain/service/SqlClassify.js.map +0 -1
  730. package/dist/spec/domain/service/SqlRefusal.d.ts +0 -16
  731. package/dist/spec/domain/service/SqlRefusal.d.ts.map +0 -1
  732. package/dist/spec/domain/service/SqlRefusal.js +0 -20
  733. package/dist/spec/domain/service/SqlRefusal.js.map +0 -1
  734. package/dist/spec/domain/service/SqlTypes.d.ts +0 -40
  735. package/dist/spec/domain/service/SqlTypes.d.ts.map +0 -1
  736. package/dist/spec/domain/service/SqlTypes.js +0 -110
  737. package/dist/spec/domain/service/SqlTypes.js.map +0 -1
  738. package/dist/spec/domain/service/StaffRoleHierarchy.d.ts +0 -3
  739. package/dist/spec/domain/service/StaffRoleHierarchy.d.ts.map +0 -1
  740. package/dist/spec/domain/service/StaffRoleHierarchy.js +0 -19
  741. package/dist/spec/domain/service/StaffRoleHierarchy.js.map +0 -1
  742. package/dist/spec/domain/service/TriggerGraphChecks.d.ts +0 -16
  743. package/dist/spec/domain/service/TriggerGraphChecks.d.ts.map +0 -1
  744. package/dist/spec/domain/service/TriggerGraphChecks.js +0 -337
  745. package/dist/spec/domain/service/TriggerGraphChecks.js.map +0 -1
  746. package/dist/spec/domain/service/TriggerSpecChecks.d.ts +0 -4
  747. package/dist/spec/domain/service/TriggerSpecChecks.d.ts.map +0 -1
  748. package/dist/spec/domain/service/TriggerSpecChecks.js +0 -89
  749. package/dist/spec/domain/service/TriggerSpecChecks.js.map +0 -1
  750. package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts +0 -11
  751. package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts.map +0 -1
  752. package/dist/spec/domain/service/ValidatedAdminUiProjection.js +0 -26
  753. package/dist/spec/domain/service/ValidatedAdminUiProjection.js.map +0 -1
  754. package/dist/spec/domain/service/ViewAdminUiChecker.d.ts +0 -14
  755. package/dist/spec/domain/service/ViewAdminUiChecker.d.ts.map +0 -1
  756. package/dist/spec/domain/service/ViewAdminUiChecker.js +0 -58
  757. package/dist/spec/domain/service/ViewAdminUiChecker.js.map +0 -1
  758. package/dist/spec/domain/service/index.d.ts +0 -24
  759. package/dist/spec/domain/service/index.d.ts.map +0 -1
  760. package/dist/spec/domain/service/index.js +0 -24
  761. package/dist/spec/domain/service/index.js.map +0 -1
  762. package/dist/spec/index.d.ts +0 -10
  763. package/dist/spec/index.d.ts.map +0 -1
  764. package/dist/spec/index.js +0 -12
  765. package/dist/spec/index.js.map +0 -1
  766. package/dist/spec/infrastructure/cli/parseArgsError.d.ts +0 -16
  767. package/dist/spec/infrastructure/cli/parseArgsError.d.ts.map +0 -1
  768. package/dist/spec/infrastructure/cli/parseArgsError.js +0 -34
  769. package/dist/spec/infrastructure/cli/parseArgsError.js.map +0 -1
  770. package/dist/spec/infrastructure/index.d.ts +0 -2
  771. package/dist/spec/infrastructure/index.d.ts.map +0 -1
  772. package/dist/spec/infrastructure/index.js +0 -2
  773. package/dist/spec/infrastructure/index.js.map +0 -1
  774. package/dist/spec/infrastructure/sql/PgQueryParser.d.ts +0 -18
  775. package/dist/spec/infrastructure/sql/PgQueryParser.d.ts.map +0 -1
  776. package/dist/spec/infrastructure/sql/PgQueryParser.js +0 -17
  777. package/dist/spec/infrastructure/sql/PgQueryParser.js.map +0 -1
  778. package/dist/spec/infrastructure/sql/compilePlan.d.ts +0 -37
  779. package/dist/spec/infrastructure/sql/compilePlan.d.ts.map +0 -1
  780. package/dist/spec/infrastructure/sql/compilePlan.js +0 -287
  781. package/dist/spec/infrastructure/sql/compilePlan.js.map +0 -1
  782. package/dist/spec/infrastructure/sql/compileSql.d.ts +0 -35
  783. package/dist/spec/infrastructure/sql/compileSql.d.ts.map +0 -1
  784. package/dist/spec/infrastructure/sql/compileSql.js +0 -92
  785. package/dist/spec/infrastructure/sql/compileSql.js.map +0 -1
  786. package/dist/spec/infrastructure/sql/frontEnd.d.ts +0 -8
  787. package/dist/spec/infrastructure/sql/frontEnd.d.ts.map +0 -1
  788. package/dist/spec/infrastructure/sql/frontEnd.js +0 -100
  789. package/dist/spec/infrastructure/sql/frontEnd.js.map +0 -1
  790. package/dist/spec/infrastructure/sql/index.d.ts +0 -4
  791. package/dist/spec/infrastructure/sql/index.d.ts.map +0 -1
  792. package/dist/spec/infrastructure/sql/index.js +0 -4
  793. package/dist/spec/infrastructure/sql/index.js.map +0 -1
  794. package/dist/spec/kernel/diagnostic.d.ts.map +0 -1
  795. package/dist/spec/kernel/diagnostic.js +0 -301
  796. package/dist/spec/kernel/diagnostic.js.map +0 -1
  797. package/dist/spec/kernel/index.d.ts +0 -8
  798. package/dist/spec/kernel/index.d.ts.map +0 -1
  799. package/dist/spec/kernel/index.js +0 -8
  800. package/dist/spec/kernel/index.js.map +0 -1
  801. package/dist/spec/usecase/EmitTypes.d.ts +0 -22
  802. package/dist/spec/usecase/EmitTypes.d.ts.map +0 -1
  803. package/dist/spec/usecase/EmitTypes.js +0 -182
  804. package/dist/spec/usecase/EmitTypes.js.map +0 -1
  805. package/dist/spec/usecase/ValidateManifestsUseCase.d.ts +0 -8
  806. package/dist/spec/usecase/ValidateManifestsUseCase.d.ts.map +0 -1
  807. package/dist/spec/usecase/ValidateManifestsUseCase.js +0 -101
  808. package/dist/spec/usecase/ValidateManifestsUseCase.js.map +0 -1
  809. package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts +0 -27
  810. package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts.map +0 -1
  811. package/dist/spec/usecase/dto/ValidateManifestsRequest.js +0 -2
  812. package/dist/spec/usecase/dto/ValidateManifestsRequest.js.map +0 -1
  813. package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts +0 -14
  814. package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts.map +0 -1
  815. package/dist/spec/usecase/dto/ValidateManifestsResponse.js +0 -2
  816. package/dist/spec/usecase/dto/ValidateManifestsResponse.js.map +0 -1
  817. package/dist/spec/usecase/dto/index.d.ts +0 -3
  818. package/dist/spec/usecase/dto/index.d.ts.map +0 -1
  819. package/dist/spec/usecase/dto/index.js +0 -3
  820. package/dist/spec/usecase/dto/index.js.map +0 -1
  821. package/dist/spec/usecase/index.d.ts +0 -10
  822. package/dist/spec/usecase/index.d.ts.map +0 -1
  823. package/dist/spec/usecase/index.js +0 -10
  824. package/dist/spec/usecase/index.js.map +0 -1
  825. package/dist/testing/cases/before-hook.d.ts +0 -4
  826. package/dist/testing/cases/before-hook.d.ts.map +0 -1
  827. package/dist/testing/cases/before-hook.js +0 -71
  828. package/dist/testing/cases/before-hook.js.map +0 -1
  829. package/dist/testing/cases/corpus.d.ts +0 -14
  830. package/dist/testing/cases/corpus.d.ts.map +0 -1
  831. package/dist/testing/cases/corpus.js +0 -93
  832. package/dist/testing/cases/corpus.js.map +0 -1
  833. package/dist/testing/cases/policy.d.ts +0 -87
  834. package/dist/testing/cases/policy.d.ts.map +0 -1
  835. package/dist/testing/cases/policy.js +0 -143
  836. package/dist/testing/cases/policy.js.map +0 -1
  837. package/dist/testing/cases/printer.d.ts +0 -4
  838. package/dist/testing/cases/printer.d.ts.map +0 -1
  839. package/dist/testing/cases/printer.js +0 -34
  840. package/dist/testing/cases/printer.js.map +0 -1
  841. package/dist/testing/cases/report-view.d.ts +0 -5
  842. package/dist/testing/cases/report-view.d.ts.map +0 -1
  843. package/dist/testing/cases/report-view.js +0 -51
  844. package/dist/testing/cases/report-view.js.map +0 -1
  845. package/dist/testing/cases/requisition.d.ts +0 -4
  846. package/dist/testing/cases/requisition.d.ts.map +0 -1
  847. package/dist/testing/cases/requisition.js +0 -38
  848. package/dist/testing/cases/requisition.js.map +0 -1
  849. package/dist/testing/cases/search-places.d.ts +0 -4
  850. package/dist/testing/cases/search-places.d.ts.map +0 -1
  851. package/dist/testing/cases/search-places.js +0 -60
  852. package/dist/testing/cases/search-places.js.map +0 -1
  853. package/dist/testing/cases/stock.d.ts +0 -4
  854. package/dist/testing/cases/stock.d.ts.map +0 -1
  855. package/dist/testing/cases/stock.js +0 -35
  856. package/dist/testing/cases/stock.js.map +0 -1
  857. package/dist/testing/cases/store.d.ts +0 -4
  858. package/dist/testing/cases/store.d.ts.map +0 -1
  859. package/dist/testing/cases/store.js +0 -100
  860. package/dist/testing/cases/store.js.map +0 -1
  861. package/dist/testing/harness.d.ts +0 -94
  862. package/dist/testing/harness.d.ts.map +0 -1
  863. package/dist/testing/harness.js +0 -168
  864. package/dist/testing/harness.js.map +0 -1
  865. package/dist/testing/index.d.ts.map +0 -1
  866. package/dist/testing/index.js.map +0 -1
  867. package/dist/testing/report.d.ts +0 -15
  868. package/dist/testing/report.d.ts.map +0 -1
  869. package/dist/testing/report.js +0 -22
  870. package/dist/testing/report.js.map +0 -1
  871. package/dist/web/createRestSurface.d.ts +0 -7
  872. package/dist/web/createRestSurface.d.ts.map +0 -1
  873. package/dist/web/createRestSurface.js +0 -41
  874. package/dist/web/createRestSurface.js.map +0 -1
  875. package/dist/web/index.d.ts +0 -2
  876. package/dist/web/index.d.ts.map +0 -1
  877. package/dist/web/index.js +0 -2
  878. package/dist/web/index.js.map +0 -1
  879. package/docs/adr/0001-four-atom-manifest-model.md +0 -440
  880. package/docs/adr/0002-closed-enums-for-bindings.md +0 -253
  881. package/docs/adr/0007-ai-as-primary-author.md +0 -473
  882. package/docs/adr/0008-structured-diagnostic-shape.md +0 -338
  883. package/docs/adr/0009-consumer-supplied-manifests.md +0 -149
  884. package/docs/adr/0010-locale-and-translates.md +0 -453
  885. package/docs/adr/0011-adapter-port-spec.md +0 -281
  886. package/docs/adr/0012-views-as-public-rest.md +0 -161
  887. package/docs/adr/0013-agent-provisioned-consumer-projects.md +0 -154
  888. package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +0 -939
  889. package/docs/adr/0016-site-semantic-layer.md +0 -70
  890. package/docs/adr/0017-media-multi-variant-agent-side-optimization.md +0 -181
  891. package/docs/adr/0018-core-starters-repository-boundary.md +0 -179
  892. package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +0 -244
  893. package/docs/adr/0020-builtin-handler-contracts-and-matched-upsert.md +0 -199
  894. package/docs/adr/0021-retire-starter-scaffolding.md +0 -30
  895. package/docs/adr/0022-caller-observed-version-occ.md +0 -212
  896. package/docs/adr/0023-port-failure-contract.md +0 -69
  897. package/docs/adr/0024-manifest-native-schema-tables.md +0 -264
  898. package/docs/adr/0025-reserved-native-columns-and-published-only-public-views.md +0 -105
  899. package/docs/adr/0026-progressive-generate.md +0 -36
  900. package/docs/adr/0027-scheduled-procedure-triggers.md +0 -31
  901. package/docs/adr/0028-schema-ttl-expiry.md +0 -33
  902. package/docs/adr/0029-mcp-apps-interaction-contracts.md +0 -324
  903. package/docs/adr/0030-store.md +0 -40
  904. package/docs/adr/0031-host-cloud-core-contract.md +0 -102
  905. package/docs/adr/0032-store-centric-core-and-service-contract.md +0 -384
  906. package/docs/adr/0033-storage-converges-to-the-plan.md +0 -92
  907. package/docs/adr/0034-store-is-authored-as-sql.md +0 -192
  908. package/docs/adr/0035-sql-dialects.md +0 -154
  909. package/docs/adr/0036-host-and-dialect.md +0 -65
  910. package/docs/adr/0037-postgresql-is-the-reference-dialect.md +0 -125
  911. package/docs/adr/0038-bun-native-host.md +0 -63
  912. package/docs/adr/0039-postgresql-is-native.md +0 -130
  913. package/docs/adr/README.md +0 -98
  914. package/docs/adr/adr-lite-1376-admin-extensions.md +0 -330
  915. package/docs/adr/adr-lite-803-request-diagnostics.md +0 -38
  916. package/docs/adr/adr-lite-808-route-readiness.md +0 -47
  917. package/docs/adr/adr-lite-809-bounded-public-content.md +0 -71
  918. package/docs/adr/adr-lite-812-native-parity.md +0 -150
  919. package/docs/adr/adr-lite-823-home-statistics.md +0 -64
  920. package/docs/adr/adr-lite-842-mcp-authoring.md +0 -30
  921. package/docs/adr/adr-lite-845-frontend-client.md +0 -38
  922. package/docs/adr/adr-lite-861-admin-webmcp.md +0 -48
  923. package/docs/adr/adr-lite-909-admin-ui-kit.md +0 -37
  924. package/docs/examples/commerce-inventory.md +0 -498
  925. package/docs/examples/commerce.md +0 -254
  926. package/docs/examples/guarded-api.md +0 -238
  927. package/docs/examples/intake-hooks.md +0 -237
  928. package/docs/examples/intake.md +0 -127
  929. package/docs/examples/legal-documents.md +0 -218
  930. package/docs/examples/procurement.md +0 -226
  931. package/docs/examples/publication.md +0 -211
  932. package/docs/examples/reference-service/.mantle/generated/mantle.ts +0 -174
  933. package/docs/examples/reference-service/.mantle/generated/plan.json +0 -1936
  934. package/docs/examples/reference-service/README.md +0 -33
  935. package/docs/examples/reference-service/manifests/catalog.yaml +0 -103
  936. package/docs/examples/reference-service/manifests/orders.yaml +0 -120
  937. package/docs/examples/reference-service/mantle.config.json +0 -1
  938. package/docs/examples/reference-service/package.json +0 -27
  939. package/docs/examples/reference-service/smoke.mjs +0 -160
  940. package/docs/examples/reference-service/src/handlers.ts +0 -36
  941. package/docs/examples/reference-service/src/index.ts +0 -33
  942. package/docs/examples/reference-service/src/service.ts +0 -78
  943. package/docs/examples/reference-service/wrangler.jsonc +0 -26
  944. package/docs/examples/reservation.md +0 -142
  945. package/docs/handbook/guides/admin-extensions.md +0 -191
  946. /package/docs/examples/{reference-service → app-shell}/.dev.vars.example +0 -0
@@ -0,0 +1,233 @@
1
+ /** Compile boundary checks into each operation; no schema enters the request bundle. */
2
+ import { INPUT_RULE_KEYWORDS, lookupLocalRef as lookup, rootRefChain } from "../build/compiler.js";
3
+ import { literal, q } from "../domain/entry.js";
4
+ import { publishingInput } from "./publishing.js";
5
+ import { equal } from "../kernel/validation.js";
6
+ const pointer = (key) => key.replace(/~/g, "~0").replace(/\//g, "~1");
7
+ const supported = new Set([..."$defs $ref $schema $id type nullable properties required additionalProperties items enum const format pattern minLength maxLength minimum maximum exclusiveMinimum exclusiveMaximum multipleOf minItems maxItems title description default readOnly writeOnly examples deprecated x-mantle-ref x-mcp-hint".split(" "), ...INPUT_RULE_KEYWORDS]);
8
+ const shapes = "see docs/handbook/reference/surface.md";
9
+ // YAML .inf and .nan parse to numbers that JSON writes as null.
10
+ const finite = (value) => typeof value === "number" ? Number.isFinite(value) : !!value && typeof value === "object" ? Object.values(value).every(finite) : true;
11
+ const has = (key) => `Object.hasOwn(object,${q(key)})`;
12
+ const exactly = (value, keys) => !!value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).sort().join(" ") === keys;
13
+ /**
14
+ * An object schema's rules, each failing `when` (JavaScript on `object`) with its sentence at the missing field `key`, or the
15
+ * reason a rule has an unsupported shape.
16
+ */
17
+ function rules(schema) {
18
+ const declared = (names) => Array.isArray(names) && names.length > 0 && names.every(name => typeof name === "string" && Object.hasOwn(schema.properties ?? {}, name));
19
+ const list = (names) => names.map(name => `'${name}'`).join(" and ");
20
+ const found = [], { dependentRequired: dependent, anyOf, if: condition, then, else: otherwise } = schema;
21
+ if (dependent !== undefined) {
22
+ if (!dependent || typeof dependent !== "object" || Array.isArray(dependent) || !declared(Object.keys(dependent)) || !Object.values(dependent).every(declared))
23
+ return `dependentRequired maps declared properties to lists of declared properties; ${shapes}.`;
24
+ for (const [key, names] of Object.entries(dependent))
25
+ for (const name of names)
26
+ found.push({ when: `${has(key)} && !${has(name)}`, key: name, message: `'${name}' is required when '${key}' is present.` });
27
+ }
28
+ if (anyOf !== undefined) {
29
+ if (!Array.isArray(anyOf) || !anyOf.length || !anyOf.every(branch => exactly(branch, "required") && declared(branch.required)))
30
+ return `anyOf is supported only as branches of exactly { required: [declared properties] }; ${shapes}.`;
31
+ const branches = anyOf.map(branch => branch.required);
32
+ found.push({ when: `!(${branches.map(names => names.map(has).join(" && ")).join(" || ")})`, message: `At least one of ${branches.map(names => names.length > 1 ? `(${list(names)})` : list(names)).join(", ")} is required.` });
33
+ }
34
+ if (condition !== undefined || then !== undefined || otherwise !== undefined) {
35
+ const [key] = exactly(condition, "properties required") ? Object.keys(condition.properties) : [];
36
+ const value = key === undefined ? undefined : condition.properties[key];
37
+ // Without required: [key], an absent key satisfies `if`.
38
+ if (key === undefined || !exactly(condition.properties, key) || !exactly(value, "const") || !(["string", "boolean"].includes(typeof value.const) || Number.isFinite(value.const) || value.const === null) || q(condition.required) !== q([key]) || !declared([key]))
39
+ return `if is supported only as exactly { properties: { <field>: { const: <string, finite number, boolean or null> } }, required: [<field>] }, so an absent field does not satisfy it; ${shapes}.`;
40
+ if (then === undefined && otherwise === undefined || [then, otherwise].some(branch => branch !== undefined && !(exactly(branch, "required") && declared(branch.required))))
41
+ return `then and else are supported only as exactly { required: [declared properties] } after an if; ${shapes}.`;
42
+ const met = `${has(key)} && object[${q(key)}] === ${q(value.const)}`;
43
+ for (const name of then?.required ?? [])
44
+ found.push({ when: `${met} && !${has(name)}`, key: name, message: `'${name}' is required when '${key}' is ${q(value.const)}.` });
45
+ for (const name of otherwise?.required ?? [])
46
+ found.push({ when: `!(${met}) && !${has(name)}`, key: name, message: `'${name}' is required unless '${key}' is ${q(value.const)}.` });
47
+ }
48
+ return found;
49
+ }
50
+ /** Whether an input schema accepts `{}`: a list View is read with no input, so web indexes need this. */
51
+ export function acceptsEmpty(input) {
52
+ if (input === undefined)
53
+ return true;
54
+ // Validation applies a root `$ref`'s target too, so each schema along the chain must accept `{}`; an unresolved or cyclic chain does not.
55
+ // dependentRequired needs a present key; an if needs its field, so `{}` meets only an else. An enum or const must admit `{}`.
56
+ return rootRefChain(input)?.every(schema => !schema.required?.length && schema.anyOf === undefined && !schema.else?.required?.length
57
+ && (schema.enum === undefined || schema.enum.some(option => equal({}, option))) && (schema.const === undefined || equal({}, schema.const)) && (schema.type === undefined || [schema.type].flat().includes("object"))) ?? false;
58
+ }
59
+ /**
60
+ * An input schema as an AI tool catalogue advertises it: some model APIs refuse rules (a root `anyOf`, `if`), so each rule leaves
61
+ * the schema and becomes a sentence of the description.
62
+ */
63
+ export function advertised(input, description) {
64
+ if (!input)
65
+ return { inputSchema: input, description };
66
+ const sentences = [], copy = JSON.parse(q(input));
67
+ const strip = (node, at) => {
68
+ if (!node || typeof node !== "object")
69
+ return;
70
+ const schema = node;
71
+ // An MCP View tool keeps each rule set of its root `$ref` chain as an `allOf` branch over the merged properties.
72
+ const branches = Array.isArray(schema.allOf) ? schema.allOf : [];
73
+ for (const branch of [schema, ...branches.map(branch => ({ ...branch, properties: schema.properties }))]) {
74
+ const found = rules(branch);
75
+ if (typeof found !== "string")
76
+ for (const rule of found)
77
+ sentences.push(at ? `In '${at}': ${rule.message}` : rule.message);
78
+ }
79
+ if (branches.length && branches.every(branch => Object.keys(branch).every(key => INPUT_RULE_KEYWORDS.includes(key))))
80
+ delete schema.allOf;
81
+ for (const keyword of INPUT_RULE_KEYWORDS)
82
+ delete schema[keyword];
83
+ for (const [key, child] of Object.entries((schema.properties ?? {})))
84
+ strip(child, `${at}/${key}`);
85
+ for (const [key, child] of Object.entries((schema.$defs ?? {})))
86
+ strip(child, `#/$defs/${key}`);
87
+ strip(schema.items, `${at}/*`);
88
+ strip(schema.additionalProperties, `${at}/*`);
89
+ };
90
+ strip(copy, "");
91
+ if (!sentences.length)
92
+ return { inputSchema: input, description };
93
+ const text = sentences.join(" ");
94
+ return { inputSchema: copy, description: typeof description === "string" ? `${description} ${text}` : Object.fromEntries(Object.entries(description).map(([locale, value]) => [locale, `${value} ${text}`])) };
95
+ }
96
+ const bounds = [
97
+ ["string", "[...value].length", { minLength: "<", maxLength: ">" }],
98
+ ["number", "value", { minimum: "<", maximum: ">", exclusiveMinimum: "<=", exclusiveMaximum: ">=" }],
99
+ ["array", "value.length", { minItems: "<", maxItems: ">" }],
100
+ ];
101
+ const condition = (type) => ({ null: "value === null", array: "Array.isArray(value)", object: 'typeof value === "object" && value !== null && !Array.isArray(value)', integer: 'typeof value === "number" && Number.isSafeInteger(value)', number: 'typeof value === "number" && Number.isFinite(value)' })[type] ?? `typeof value === ${q(type)}`;
102
+ const typeCheck = (types) => `if (!(${types.map(type => `(${condition(type)})`).join(" || ")})) fail(path, ${q(`Expected ${types.join(" or ")}.`)});`;
103
+ export function emitValidation(plan, refuse = (path, message) => { throw Error(`${path}: ${message}`); }) {
104
+ const files = {};
105
+ for (const [kind, operations] of [["views", plan.views], ["procedures", plan.procedures]])
106
+ for (const [name, operation] of Object.entries(operations)) {
107
+ const root = operation.input ?? { type: "object", additionalProperties: false };
108
+ const base = `${kind}/${name}/input`, file = `validation/${kind}/${encodeURIComponent(name)}.ts`;
109
+ const json = q(root);
110
+ if (kind === "procedures" && json === q(publishingInput)) {
111
+ files[file] = `import { transition } from "@aotter/mantle/validation";\nexport const validate = (raw: unknown) => transition(${q(base)}, raw);\n`;
112
+ continue;
113
+ }
114
+ // Only a local `$ref`, or more than 100 nested objects and arrays, can reach the nesting limit: only then is `depth` passed.
115
+ const recursive = json.includes('"$ref"') || json.split(/[[{]/).length > 101, depth = recursive ? ",depth+1" : "";
116
+ // Identical bodies share one function.
117
+ const nodes = new Map(), bodies = new Map(), functions = [], formats = new Set(), patterns = new Map();
118
+ let equality = false;
119
+ const resolve = (ref) => {
120
+ const found = lookup(root, ref);
121
+ if (!found)
122
+ refuse(base, "Input ref must be a valid local JSON pointer.");
123
+ return found ?? {};
124
+ };
125
+ const emit = (schema) => {
126
+ if (nodes.has(schema))
127
+ return nodes.get(schema);
128
+ const named = `check${nodes.size}`;
129
+ nodes.set(schema, named);
130
+ for (const key of Object.keys(schema))
131
+ if (!supported.has(key))
132
+ refuse(base, `Generated input validation does not support '${key}'.`);
133
+ const lines = recursive ? ['if (depth > 100) fail(path, "Input nesting exceeds 100 levels.");'] : [];
134
+ const check = (invalid, message) => lines.push(`if (${invalid}) fail(path, ${q(message)});`);
135
+ if (schema.nullable)
136
+ lines.push("if (value === null) return;");
137
+ if (schema.$ref !== undefined)
138
+ lines.push(`${emit(resolve(schema.$ref))}(value,path${depth});`);
139
+ const types = [schema.type].flat().filter((type) => !!type);
140
+ for (const type of types)
141
+ if (!"null array object integer number string boolean".split(" ").includes(type))
142
+ refuse(base, `Unsupported input type '${type}'.`);
143
+ if (types.length)
144
+ lines.push(typeCheck(types));
145
+ // After a single type check `fail` (never) has narrowed `value`: that type's guard is implied.
146
+ const only = types.length === 1 ? types[0] : undefined;
147
+ const guard = (type, test = `(${condition(type)})`) => only === type || type === "number" && only === "integer" ? "" : test + " && ";
148
+ if (schema.enum) {
149
+ if (!finite(schema.enum))
150
+ refuse(base, "Input enum numbers must be finite; JSON has no Infinity or NaN.");
151
+ equality = true;
152
+ check(`!${literal(schema.enum)}.some(option=>equal(value,option))`, "Value is not in enum.");
153
+ }
154
+ if (schema.const !== undefined) {
155
+ if (!finite(schema.const))
156
+ refuse(base, "Input const numbers must be finite; JSON has no Infinity or NaN.");
157
+ equality = true;
158
+ check(`!equal(value,${literal(schema.const)})`, "Value violates const.");
159
+ }
160
+ for (const [type, measure, keywords] of bounds)
161
+ for (const [key, operator] of Object.entries(keywords))
162
+ if (schema[key] !== undefined)
163
+ check(`${guard(type)}${measure} ${operator} ${schema[key]}`, `Value violates ${key}.`);
164
+ if (schema.multipleOf !== undefined)
165
+ check(`${guard("number", 'typeof value === "number"')}!(Math.abs(value / ${schema.multipleOf} - Math.round(value / ${schema.multipleOf})) < 1e-9)`, "Number violates multipleOf.");
166
+ if (schema.pattern !== undefined) {
167
+ try {
168
+ new RegExp(schema.pattern);
169
+ }
170
+ catch {
171
+ refuse(base, "Input pattern is not a valid regular expression.");
172
+ }
173
+ if (!patterns.has(schema.pattern))
174
+ patterns.set(schema.pattern, `pattern${patterns.size}`);
175
+ check(`${guard("string", 'typeof value === "string"')}!${patterns.get(schema.pattern)}.test(value)`, "String does not match pattern.");
176
+ }
177
+ if (schema.format) {
178
+ if (schema.format === "email")
179
+ check(`${guard("string", 'typeof value === "string"')}!/^[^\\s@]+@[^\\s@]+$/u.test(value)`, "Expected an email with one @, non-empty local and domain parts, and no whitespace.");
180
+ else if (schema.format === "uri")
181
+ lines.push(`${only === "string" ? "" : 'if (typeof value === "string") '}{ let url: URL | undefined; try { url = new URL(value); } catch {} if (url?.protocol !== "http:" && url?.protocol !== "https:") fail(path, "Expected an absolute http or https URL."); }`);
182
+ else if (!["date", "date-time"].includes(schema.format))
183
+ refuse(base, `Generated input validation does not support format '${schema.format}'; ${shapes} for the supported formats.`);
184
+ else {
185
+ const scalar = schema.format === "date" ? "encodeDate" : "encodeTimestamptz";
186
+ formats.add(scalar);
187
+ lines.push(`${only === "string" ? "" : 'if (typeof value === "string") '}try { ${scalar}(value); } catch { fail(path, ${q(`Expected a valid ${schema.format}.`)}); }`);
188
+ }
189
+ }
190
+ if (schema.items)
191
+ lines.push(`${only === "array" ? "" : "if (Array.isArray(value)) "}for (let i=0;i<value.length;i++) ${emit(schema.items)}(value[i],path+"/"+i${depth});`);
192
+ // Several keys that need no JSON-pointer escaping are checked by one loop, in the same order.
193
+ const required = schema.required ?? [], checks = Object.entries(schema.properties ?? {}).map(([key, child]) => [key, emit(child)]);
194
+ const loop = (keys) => keys.length > 1 && keys.every(key => pointer(key) === key);
195
+ const object = loop(required) ? [`for (const key of ${q(required)}) if (!Object.hasOwn(object,key)) fail(path+"/"+key,"Required field is missing.");`] : required.map(key => `if (!Object.hasOwn(object,${q(key)})) fail(path+${q("/" + pointer(key))},"Required field is missing.");`);
196
+ if (loop(checks.map(([key]) => key)))
197
+ object.push(`for (const [key,check] of [${checks.map(([key, fn]) => `[${q(key)},${fn}]`)}] as const) if (Object.hasOwn(object,key)) check(object[key],path+"/"+key${depth});`);
198
+ else
199
+ for (const [key, fn] of checks)
200
+ object.push(`if (Object.hasOwn(object,${q(key)})) ${fn}(object[${q(key)}],path+${q("/" + pointer(key))}${depth});`);
201
+ if (schema.additionalProperties === false || typeof schema.additionalProperties === "object")
202
+ object.push(`for (const key of Object.keys(object)) if (!(${q(Object.keys(schema.properties ?? {}))} as readonly string[]).includes(key)) { const childPath = path+"/"+key.replace(/~/g,"~0").replace(/\\//g,"~1"); ${schema.additionalProperties === false ? 'fail(childPath,"Unknown field.");' : `${emit(schema.additionalProperties)}(object[key],childPath${depth});`} }`);
203
+ const checked = rules(schema);
204
+ if (typeof checked === "string")
205
+ refuse(base, checked);
206
+ else
207
+ for (const rule of checked)
208
+ object.push(`if (${rule.when}) fail(path${rule.key === undefined ? "" : `+${q("/" + pointer(rule.key))}`}, ${q(rule.message)});`);
209
+ if (object.length)
210
+ lines.push(`${only === "object" ? "" : `if (${condition("object")}) `}{ const object = value as Record<string,unknown>;\n${object.join("\n")}\n}`);
211
+ const body = lines.join("\n");
212
+ // Without recursion nothing calls a check before its body is complete, so an identical body's function serves it.
213
+ const fn = recursive ? named : bodies.get(body) ?? named;
214
+ if (fn === named) {
215
+ bodies.set(body, fn);
216
+ functions.push(`function ${fn}(value:unknown,path:string${recursive ? ",depth:number" : ""}):void {\n${body}\n}`);
217
+ }
218
+ nodes.set(schema, fn);
219
+ return fn;
220
+ };
221
+ const validate = emit(root);
222
+ const fields = kind === "views" ? Object.entries(root.properties ?? {}).map(([key, schema]) => {
223
+ const type = [schema.type].flat().find(type => type && type !== "null");
224
+ return type === "boolean" || type === "integer" || type === "number" ? [key, type] : [key];
225
+ }) : undefined;
226
+ const helpers = [...(functions.length ? ["fail"] : []), ...(equality ? ["equal"] : []), ...(fields ? ["query as read"] : [])];
227
+ const code = `${helpers.length ? `import { ${helpers.join(", ")} } from "@aotter/mantle/validation";\n` : ""}${formats.size ? `import { ${[...formats].join(", ")} } from "@aotter/mantle/scalars";\n` : ""}${[...patterns].map(([pattern, name]) => `const ${name} = new RegExp(${q(pattern)});\n`).join("")}${functions.join("\n")}
228
+ export function validate(raw:unknown):Record<string,unknown> { ${validate}(raw,${q(base)}${recursive ? ",0" : ""}); return raw as Record<string,unknown>; }
229
+ ${fields ? `export const query = (params:URLSearchParams) => read(params, validate, ${q(`${kind}/${name}`)}, ${q(fields)});\n` : ""}`;
230
+ files[file] = code;
231
+ }
232
+ return files;
233
+ }
@@ -0,0 +1,23 @@
1
+ import { databaseImport, q } from "../domain/entry.js";
2
+ import { authLines, conversions } from "../domain/input.js";
3
+ import { acceptsEmpty } from "./validation.js";
4
+ export function emitWeb(plan, lowered, target) {
5
+ const views = Object.entries(plan.views).filter(([, v]) => v.surface === "public");
6
+ const table = views.map(([name, v], i) => {
7
+ const binds = lowered.views[name]?.public?.binds ?? [], convert = conversions(v.input?.properties, binds, target);
8
+ const booleans = Object.keys(v.input?.properties ?? {}).filter(field => binds.some(b => b.k === "input" && String(b.name).toLowerCase() === field.toLowerCase() && String(b.type) === "bool"));
9
+ const check = authLines(v.requires, `views/${name}`, binds, !target.endsWith("postgres"));
10
+ return `[${q(name)}, { ${check.length ? `check: (caller) => {${check.join("")}}, ` : ""}${acceptsEmpty(v.input) ? "" : "unlisted: true, "}query: input${i}, page: async (db, caller, input, paging) => (await import("./paged/views/${encodeURIComponent(name)}.js")).default(db, caller, input, paging)${convert ? `, convert: ${convert}` : ""}${booleans.length ? `, booleans: ${q(booleans)}` : ""} }]`;
11
+ });
12
+ return { "web.ts": [
13
+ ...(plan.access ? ['import { userBinds } from "@aotter/mantle/user-fields";'] : []),
14
+ ...([...Object.values(plan.views)].some(v => v.requires?.auth?.all.length) ? ['import { deny, isAdmin, isUser } from "@aotter/mantle/contracts";'] : []),
15
+ ...views.flatMap(([n], i) => [`import { query as input${i} } from "./validation/views/${encodeURIComponent(n)}.js";`, `import type { Row as Row${i} } from "./views/${encodeURIComponent(n)}.js";`]),
16
+ 'import { web as site, type Options, type Page } from "@aotter/mantle/web";',
17
+ databaseImport(target),
18
+ `type App = { Rows: {${views.map(([n], i) => `${q(n)}:Row${i}`).join(";")}}; Inputs: {${views.map(([n, v]) => `${q(n)}:${Object.keys(v.input?.properties ?? {}).map(k => q(k)).join(" | ") || "never"}`).join(";")}}; List: ${views.filter(([, v]) => acceptsEmpty(v.input)).map(([n]) => q(n)).join(" | ") || "never"} };`,
19
+ "export function web<const P extends Record<string, Page<App>>, E = unknown>(options: Options<App, Database, P, E>) {",
20
+ ` return site<Database, E>(${plan.access ? `{...options, fields: ${q(plan.access.userFields)}, accessTargets: () => import("./access-targets.js").then(m => m.targets)}` : '{...options, accessTargets: () => import("./access-targets.js").then(m => m.targets)}'}, [${table.join(", ")}]);`,
21
+ "}"
22
+ ].join("\n") + "\n" };
23
+ }
@@ -1,20 +1,35 @@
1
- # Examples hub
1
+ # Examples
2
2
 
3
- Every page is a whole service in the 0.2.0 grammar: its manifests compile with
4
- `mantle generate` (the SDK repository compiles each one in its checks). Copy the shape you need into
5
- your project's `manifests/`; none is a template to copy wholesale.
3
+ Start from the **app shell**, then copy the example closest to your app on top of it. Each example shows a few
4
+ capabilities the others do not; combine them for anything else.
6
5
 
7
- | Example | What it shows | Handler code |
8
- |---|---|---|
9
- | [`reference-service/`](./reference-service/README.md) | A runnable service with its smoke test: scoped orders, SQL Views and Procedures, hooks, a cron, REST, both MCP surfaces, Admin's API and console email-OTP sign-in. The release gate runs it. | yes |
10
- | [Intake form](./intake.md) | An anonymous form: one SQL `INSERT` and a staff View. | none |
11
- | [Intake with bot check and notification](./intake-hooks.md) | A Turnstile check as the Procedure's guard, an email from an after hook. | 2 handlers |
12
- | [Reservation requests](./reservation.md) | A request queue with a Schema `check`. | none |
13
- | [Publication](./publication.md) | Localized posts with a parent identity, per-locale lists and `mantle.search`. | none |
14
- | [Legal documents and consent](./legal-documents.md) | Immutable revisions, and an acceptance written only for a published revision. | none |
15
- | [Procurement approvals](./procurement.md) | Members see their own rows through `auth.uid()`; staff review with an optimistic lock. | none |
16
- | [Commerce catalog and orders](./commerce.md) | A published catalog, guest orders and a locked staff review. | none |
17
- | [Commerce inventory](./commerce-inventory.md) | Server-side pricing, atomic stock reservation with `checks` and locks, a scheduled expiry and a verified payment callback. | 3 handlers |
18
- | [Guarded API access](./guarded-api.md) | API keys through a custom `CallerResolver`, scopes and a live entitlement guard. | 2 handlers |
6
+ | Example | Shows |
7
+ |---|---|
8
+ | [App shell](./app-shell/README.md) | Better Auth (email OTP, `admin` + `user`), one Worker fetch, Admin, MCP, REST, local acceptance kit. No business manifests. |
9
+ | [Recipes](./recipes/README.md) | Publishing (draft → publish), translations, visitor pages with SEO, JSON-LD, `llms.txt`, Markdown and hreflang alternates, R2 media. |
10
+ | [Club events](./club-events/README.md) | Members who see and change only their own rows, no duplicates, capacity that never oversells, a handler that checks before writing, a member MCP tool, members-only sign-up. |
11
+ | [Purchasing](./purchasing/README.md) | An internal workflow: guarded status transitions, admin-only approval (Admin and admin MCP), optimistic concurrency, several writes in one transaction, an external API with a signed callback, email and cron. |
12
+ | [Generated website](./generated-web/README.md) | The smallest public site: list and detail pages, REST, `llms.txt`, sitemap, Markdown alternates. |
19
13
 
14
+ ## Combining
15
+
16
+ | You need | Take |
17
+ |---|---|
18
+ | Stock that never oversells (orders, tickets, bookings) | club-events' capacity: a Schema `checks` constraint plus the decrement in the same program |
19
+ | Employees or customers who see only their own records | club-events' `restrict: { <schema>: "author_id = auth.uid()" }` |
20
+ | An approval step, or any state machine | purchasing's guarded `UPDATE ... WHERE requestStatus = ...` Procedures |
21
+ | A third-party API that answers later (webhooks, callbacks) | purchasing's `src/routes.ts`: verify the raw request, then call a Procedure |
22
+ | Public, multilingual, search- and AI-friendly pages | recipes' `src/routes.ts` |
23
+ | Invite-only or members-only sign-up | club-events' `members` allowlist + `src/signup.ts` |
24
+ | Notifications and reminders | purchasing's `EmailSender` call and `src/schedule.ts` |
25
+
26
+ When you copy an example only for one of its patterns, delete what your app does not need. Copying club-events, for
27
+ example, also brings its `members` allowlist and `src/signup.ts` (members-only sign-up); remove both, or restore the
28
+ shell's allow-all `src/signup.ts`, unless sign-up should be invite-only. Purchasing brings its supplier callback
29
+ (`src/routes.ts`, `src/supplier.ts`), email (`src/notify.ts`), cron (`src/schedule.ts` and `triggers.crons`) and its
30
+ `wrangler.jsonc` secrets. `pnpm generate` and `tsc` point at leftovers that reference removed Schemas.
31
+
32
+ Every example uses two roles: `admin` (the admin layer) and `user`.
33
+
34
+ [Reference service](https://github.com/aotter/mantle/tree/v0.2.0-alpha.8/docs/examples/reference-service) is the release smoke test for packed packages, not a starting point. Its source lives in the tagged repository; it is not included in the npm docs.
20
35
  Projects on 0.1.x move with [the upgrade guide](../upgrade-0.1-to-0.2.md).
@@ -0,0 +1,86 @@
1
+ # App shell
2
+
3
+ The wiring every Mantle Cloudflare app needs, ready to copy: Better Auth (email OTP, admin + user roles),
4
+ one Worker fetch (auth routes → your routes → Admin → MCP → generated REST), the Admin console assets, and a
5
+ local acceptance kit. It has no business manifests: add your own, or copy one of the examples on top of it.
6
+
7
+ ## Start an app
8
+
9
+ ```sh
10
+ cp -R node_modules/@aotter/mantle/docs/examples/app-shell/. my-app/ # or from this repository
11
+ cp -R node_modules/@aotter/mantle/docs/examples/club-events/. my-app/ # optional: an example on top
12
+ cd my-app
13
+ # package.json: pin the exact installed Mantle version for @aotter/mantle, -admin and -ui
14
+ pnpm install
15
+ pnpm generate # writes generated/ and lists any `handler: { ref }` to implement in src/handlers.ts
16
+ pnpm types && pnpm check
17
+ cp .dev.vars.example .dev.vars
18
+ pnpm db:init && pnpm db:seed # db:seed only when the example has seed.sql
19
+ pnpm dev # one-time codes print to this log
20
+ pnpm smoke # when the copied example has smoke.mjs
21
+ ```
22
+
23
+ npm works too (`npm install`, `npm run …`). `package.json` pins `@better-auth/core` and `@better-auth/utils` even though
24
+ the shell does not import them: they are the exact versions the SDK's Better Auth peers require, and without them a fresh
25
+ install resolves newer ones (npm ERESOLVE, or a second Better Auth type tree under pnpm). Keep every Better Auth package
26
+ on one version.
27
+
28
+ ## Files you edit
29
+
30
+ | File | What it is for |
31
+ |---|---|
32
+ | `manifests/*.yaml` | Your Schemas, Views, Procedures and Triggers. `pnpm generate` compiles every file here. |
33
+ | `src/handlers.ts` | Code for each `handler: { ref }` Procedure. The Store it receives is bound to the same caller. |
34
+ | `src/routes.ts` | App-owned routes: visitor pages, SEO files, webhooks and callbacks. |
35
+ | `src/admin.tsx` | Optional, not shipped: the Admin entry (`defineAdmin(admin, { nav, pages, home, components, plugins, mcp })`) `mantle bundle` builds instead of the built-in one. Add it to group the sidebar or replace Admin regions; see docs/handbook/guides/native-admin.md. |
36
+ | `src/sign-in.ts` | Member sign-in page at `/sign-in` (email code, then back to `?return=`) and `signInRedirect(request)` for pages that need a signed-in visitor. Unstyled; delete it if the app has no member pages. |
37
+ | `src/schedule.ts` | Cron work. Add the cron to `wrangler.jsonc` `triggers.crons`. |
38
+ | `src/signup.ts` | `allowSignUp(env, email)`: who may create an account (allow-all by default). `auth.ts` calls it before Better Auth creates a user; `ADMIN_EMAIL` is always allowed. |
39
+ | `src/auth.ts` | Better Auth options. Two roles only: `admin` (the admin layer) and `user`. Replace the console OTP sender before deploying. |
40
+ | `smoke.mjs` | Your acceptance steps on `smoke-kit.mjs` (fresh local D1, OTP sign-in per user, REST/MCP/Admin calls). |
41
+
42
+ `src/service.ts` and `src/index.ts` rarely change. Delete the blocks marked `MCP / OAuth (optional)` in `auth.ts`
43
+ and `service.ts` if the app has no MCP.
44
+
45
+ Search for `AGENT:` to find what an app must fill in.
46
+
47
+ ## Local testing notes
48
+
49
+ - Better Auth allows 3 OTP requests per minute per client IP. `smoke-kit.mjs` gives each user its own
50
+ `cf-connecting-ip`; when testing by hand, wait a minute or vary that header.
51
+ - `ADMIN_EMAIL`'s first verified sign-in becomes `admin` while no admin exists. The sign-in response may still show
52
+ the previous role; `/admin/api/me` shows the current one.
53
+ - Admin HTTP routes are listed in `docs/handbook/guides/native-admin.md`.
54
+
55
+ ### MCP acceptance
56
+
57
+ Generation declares tools; the app owns whether and where a remote endpoint is mounted.
58
+ In your `smoke.mjs`, reuse the generated static tool names rather than maintaining a second list:
59
+
60
+ ```js
61
+ import assert from "node:assert/strict";
62
+ import { assertMcpDiscovery, smoke } from "./smoke-kit.mjs";
63
+ import { developerConsole } from "./generated/admin-descriptors.ts";
64
+
65
+ await smoke(async ({ origin, owner, signIn, mcp }) => {
66
+ const cookie = await signIn(owner);
67
+ const tools = developerConsole.interfaces.callable.filter(tool => tool.surface === "admin");
68
+ await assertMcpDiscovery(`${origin}/mcp/admin`, { tools, headers: { cookie, origin } });
69
+ // Denial is a separate assertion, not successful discovery.
70
+ assert.equal((await mcp("/mcp/admin")).status, 401);
71
+ });
72
+ ```
73
+
74
+ Node 22.22+ can read this pure static
75
+ TypeScript descriptor directly; no generated request handlers are executed to derive expected names.
76
+ A TypeScript smoke scenario can instead import `tools` from generated `mcp.ts`.
77
+ Explicitly select the permitted subset if the app narrows authorization, and include any app-composed tools.
78
+ The assertion initializes MCP, forwards supplied identity/session headers, reads all tools/list pages,
79
+ and compares exact names without calling business tools. JSON/SSE protocol failures, missing routes,
80
+ unexpected/missing tools and repeated/excessive pagination fail; it never obtains credentials or mounts routes.
81
+
82
+ This local cookie test does not prove OAuth Bearer or an external client's connection. Test those separately
83
+ with supplied credentials and record their results. For each declared interface, the existing handoff/README/test
84
+ report must say verified (command, identity and result), intentionally not exposed, or deferred/unverified with a
85
+ reason. WebMCP-only applications remain valid; an interrupted preview must retain the remote acceptance item
86
+ as deferred rather than silently claiming completion.
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "mantle-app",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "generate": "mantle generate cloudflare-d1 generated manifests/*.yaml --auth src/auth.ts --entry src/index.ts --admin",
7
+ "types": "wrangler types --include-runtime=false",
8
+ "db:init": "wrangler d1 execute mantle-app --local --file generated/schema.sql",
9
+ "db:seed": "wrangler d1 execute mantle-app --local --file seed.sql",
10
+ "build": "mantle bundle src/index.ts dist",
11
+ "test": "node --test generated/admin-mcp-app.check.mjs",
12
+ "dev": "wrangler dev --local --ip 127.0.0.1 --port 8787",
13
+ "check": "mantle generate cloudflare-d1 generated manifests/*.yaml --auth src/auth.ts --entry src/index.ts --admin --check && wrangler types --include-runtime=false --check && tsc --noEmit",
14
+ "smoke": "node smoke.mjs"
15
+ },
16
+ "dependencies": {
17
+ "@aotter/mantle": "0.2.0-alpha.8",
18
+ "@aotter/mantle-ui": "0.2.0-alpha.8",
19
+ "@better-auth/cimd": "1.7.7",
20
+ "@better-auth/core": "1.7.7",
21
+ "@better-auth/mcp": "1.7.7",
22
+ "@better-auth/oauth-provider": "1.7.7",
23
+ "@better-auth/utils": "0.4.2",
24
+ "@modelcontextprotocol/ext-apps": "2.0.0",
25
+ "@modelcontextprotocol/server": "2.2.0",
26
+ "better-auth": "1.7.7",
27
+ "@aotter/mantle-admin": "0.2.0-alpha.8",
28
+ "react": "19.3.0",
29
+ "react-dom": "19.3.0"
30
+ },
31
+ "devDependencies": {
32
+ "@cloudflare/workers-types": "5.20260904.1",
33
+ "@types/node": "^26",
34
+ "@types/react": "^19.3.0",
35
+ "playwright-core": "1.62.1",
36
+ "typescript": "^6.0.3",
37
+ "wrangler": "4.129.0"
38
+ },
39
+ "engines": {
40
+ "node": ">=22.22"
41
+ }
42
+ }
@@ -0,0 +1,8 @@
1
+ # pnpm 10+ blocks dependency build scripts by default; wrangler needs these two. `packages` keeps pnpm 9 happy.
2
+ packages: ["."]
3
+ allowBuilds:
4
+ esbuild: true
5
+ workerd: true
6
+ onlyBuiltDependencies:
7
+ - esbuild
8
+ - workerd
@@ -0,0 +1,154 @@
1
+ // Local acceptance kit: runs the app under `wrangler dev --local` on a fresh D1 and drives it over HTTP like a browser or agent.
2
+ // Usage in smoke.mjs:
3
+ // import { smoke } from "./smoke-kit.mjs";
4
+ // await smoke(async ({ call, mcp, signIn, owner, step }) => { const admin = await signIn(owner); ... step("..."); });
5
+ // Extra Worker variables: await smoke(scenario, { vars: { SUPPLIER_API_URL: "http://127.0.0.1:9999" } });
6
+ import assert from "node:assert/strict";
7
+ import { execFile, spawn, spawnSync } from "node:child_process";
8
+ import { existsSync, mkdtempSync, rmSync } from "node:fs";
9
+ import { tmpdir } from "node:os";
10
+ import { join } from "node:path";
11
+ import { promisify } from "node:util";
12
+
13
+ /** Read-only remote acceptance. Pass generated tools filtered for this surface and the supplied test identity. */
14
+ export async function assertMcpDiscovery(endpoint, { tools, headers = {} }) {
15
+ const expected = tools.map(tool => tool.name).sort();
16
+ assert.equal(new Set(expected).size, expected.length, "expected tools contain duplicate names");
17
+ const requestHeaders = new Headers(headers);
18
+ requestHeaders.set("content-type", "application/json");
19
+ requestHeaders.set("accept", "application/json, text/event-stream");
20
+ let id = 0;
21
+ const rpc = async (method, params, notification = false) => {
22
+ const message = { jsonrpc: "2.0", ...(notification ? {} : { id: ++id }), method, ...(params === undefined ? {} : { params }) };
23
+ const response = await fetch(endpoint, { method: "POST", headers: requestHeaders, redirect: "error", signal: AbortSignal.timeout(10_000), body: JSON.stringify(message) });
24
+ assert.equal(response.status, notification ? 202 : 200, `MCP ${method}: HTTP ${response.status}`);
25
+ if (notification) { await response.body?.cancel(); return; }
26
+ const text = await response.text(), type = response.headers.get("content-type") ?? "";
27
+ let replies;
28
+ if (type.includes("text/event-stream")) {
29
+ replies = text.replace(/\r\n/g, "\n").split("\n\n").map(event => event.split("\n").filter(line => line.startsWith("data:")).map(line => line.slice(5).trimStart()).join("\n")).filter(Boolean).map(data => JSON.parse(data));
30
+ } else {
31
+ assert.ok(type.includes("application/json"), `MCP ${method}: expected JSON or SSE`);
32
+ replies = [JSON.parse(text)];
33
+ }
34
+ const matches = replies.filter(reply => reply?.id === message.id);
35
+ assert.equal(matches.length, 1, `MCP ${method}: expected one response with the request id`);
36
+ const reply = matches[0];
37
+ assert.equal(reply.jsonrpc, "2.0", `MCP ${method}: invalid JSON-RPC version`);
38
+ assert.ok(!Object.hasOwn(reply, "error"), `MCP ${method}: returned a JSON-RPC error`);
39
+ assert.ok(reply.result && typeof reply.result === "object" && !Array.isArray(reply.result), `MCP ${method}: missing result object`);
40
+ const session = response.headers.get("mcp-session-id");
41
+ if (session) requestHeaders.set("mcp-session-id", session);
42
+ return reply.result;
43
+ };
44
+ const initialized = await rpc("initialize", { protocolVersion: "2025-11-25", capabilities: {}, clientInfo: { name: "mantle-smoke", version: "1" } });
45
+ assert.equal(initialized.protocolVersion, "2025-11-25", "MCP initialize: unsupported protocol version");
46
+ assert.ok(initialized.capabilities?.tools && typeof initialized.capabilities.tools === "object" && !Array.isArray(initialized.capabilities.tools), "MCP initialize: no tools capability");
47
+ assert.ok(typeof initialized.serverInfo?.name === "string" && typeof initialized.serverInfo?.version === "string", "MCP initialize: invalid serverInfo");
48
+ requestHeaders.set("mcp-protocol-version", initialized.protocolVersion);
49
+ await rpc("notifications/initialized", undefined, true);
50
+ const names = [], cursors = new Set();
51
+ let cursor;
52
+ do {
53
+ assert.ok(cursors.size < 100, "MCP tools/list: exceeded 100 pages");
54
+ const page = await rpc("tools/list", cursor === undefined ? {} : { cursor });
55
+ assert.ok(Array.isArray(page.tools) && page.tools.every(tool => tool && typeof tool.name === "string" && tool.name.length > 0 && tool.inputSchema && typeof tool.inputSchema === "object" && !Array.isArray(tool.inputSchema) && tool.inputSchema.type === "object"), "MCP tools/list: invalid tools");
56
+ names.push(...page.tools.map(tool => tool.name));
57
+ cursor = page.nextCursor;
58
+ if (cursor !== undefined) {
59
+ assert.ok(typeof cursor === "string" && cursor.length > 0 && !cursors.has(cursor), "MCP tools/list: invalid or repeated cursor");
60
+ cursors.add(cursor);
61
+ }
62
+ } while (cursor !== undefined);
63
+ assert.deepEqual(names.sort(), expected, "MCP tools/list: discovered tools differ from the expected permitted tools");
64
+ return names;
65
+ }
66
+
67
+ const database = "mantle-app"; // wrangler.jsonc d1_databases[0].database_name
68
+ const env = { ...process.env, WRANGLER_SEND_METRICS: "false" };
69
+
70
+ export async function smoke(scenario, { vars = {} } = {}) {
71
+ const port = 18000 + Math.floor(Math.random() * 1000), origin = `http://127.0.0.1:${port}`, owner = "owner@example.test";
72
+ const state = mkdtempSync(join(tmpdir(), "mantle-smoke-"));
73
+ // Deployment DDL is explicit: nothing at runtime creates tables.
74
+ for (const file of ["generated/schema.sql", ...(existsSync("seed.sql") ? ["seed.sql"] : [])]) {
75
+ const applied = spawnSync("pnpm", ["exec", "wrangler", "d1", "execute", database, "--local", "--persist-to", state, "--file", file], { encoding: "utf8", env });
76
+ assert.equal(applied.status, 0, applied.stdout + applied.stderr);
77
+ }
78
+ const wrangler = spawn("pnpm", ["exec", "wrangler", "dev", "--local", "--ip", "127.0.0.1", "--port", String(port), "--inspector-port", "0", "--persist-to", state, "--test-scheduled",
79
+ "--var", `PUBLIC_ORIGIN:${origin}`, "--var", `ADMIN_EMAIL:${owner}`, "--var", "BETTER_AUTH_SECRET:local-smoke-secret-0123456789abcdef", ...Object.entries(vars).flatMap(([name, value]) => ["--var", `${name}:${value}`])],
80
+ // its own process group: pnpm does not pass a signal on to wrangler and workerd
81
+ { env: { ...env, CI: "1" }, stdio: ["ignore", "pipe", "pipe"], detached: true });
82
+ let logs = "";
83
+ wrangler.stdout.on("data", chunk => { logs += chunk; });
84
+ wrangler.stderr.on("data", chunk => { logs += chunk; });
85
+
86
+ // Better Auth limits OTP requests to 3 per minute per IP: each signed-in user gets its own client IP.
87
+ const ips = new Map();
88
+ const ipOf = email => ips.get(email) ?? (ips.set(email, `203.0.113.${ips.size + 1}`), ips.get(email));
89
+ /** method, path, { cookie, body, ip, headers } -> { status, body, headers } */
90
+ const call = async (method, path, { cookie, body, ip, headers = {} } = {}) => {
91
+ const response = await fetch(`${origin}${path}`, { method, headers: { "content-type": "application/json", origin, ...(cookie ? { cookie } : {}), ...(ip ? { "cf-connecting-ip": ip } : {}), ...headers },
92
+ ...(body === undefined ? {} : { body: typeof body === "string" ? body : JSON.stringify(body) }) });
93
+ const text = await response.text();
94
+ let parsed; try { parsed = text ? JSON.parse(text) : null; } catch { parsed = text; }
95
+ return { status: response.status, body: parsed, headers: response.headers };
96
+ };
97
+ /** MCP tools/list (no name) or tools/call on /mcp or /mcp/admin. */
98
+ const mcp = async (path, cookie, name, args) => {
99
+ const response = await fetch(`${origin}${path}`, { method: "POST", headers: { "content-type": "application/json", origin, accept: "application/json, text/event-stream", ...(cookie ? { cookie } : {}) },
100
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: name ? "tools/call" : "tools/list", params: name ? { name, arguments: args } : {} }) });
101
+ const text = await response.text(), data = text.split("\n").find(line => line.startsWith("data:"));
102
+ return { status: response.status, body: data ? JSON.parse(data.slice(5)) : text ? JSON.parse(text) : null };
103
+ };
104
+ /** Console email OTP: request a code, read it from the wrangler log, sign in; returns the cookie header. */
105
+ const signIn = async email => {
106
+ const before = logs.length, ip = ipOf(email);
107
+ assert.equal((await call("POST", "/api/auth/email-otp/send-verification-otp", { body: { email, type: "sign-in" }, ip })).status, 200);
108
+ let code;
109
+ for (let i = 0; i < 40 && !code; i++) {
110
+ code = new RegExp(`${email.replace(/[.+]/g, "\\$&")}[\\s\\S]*?one-time code is (\\d{6})`).exec(logs.slice(before))?.[1];
111
+ if (!code) await new Promise(resolve => setTimeout(resolve, 100));
112
+ }
113
+ assert.ok(code, `no one-time code for ${email} in the log`);
114
+ const signed = await call("POST", "/api/auth/sign-in/email-otp", { body: { email, otp: code }, ip });
115
+ assert.equal(signed.status, 200, JSON.stringify(signed.body));
116
+ return signed.headers.getSetCookie().map(c => c.split(";")[0]).join("; ");
117
+ };
118
+ /** Run SQL against the local D1 (inspect state or inject a failure). Async, so the server's sockets stay serviced. */
119
+ const sql = async command => {
120
+ const { stdout } = await promisify(execFile)("pnpm", ["exec", "wrangler", "d1", "execute", database, "--local", "--persist-to", state, "--command", command, "--json"], { encoding: "utf8", env });
121
+ return JSON.parse(stdout)[0].results;
122
+ };
123
+ /** Fire the Worker's scheduled() handler (wrangler dev --test-scheduled). */
124
+ const cron = async expression => (await fetch(`${origin}/cdn-cgi/local/scheduled?cron=${encodeURIComponent(expression)}`)).status;
125
+ /** Wait until the wrangler log (console.log from the Worker, e.g. ConsoleEmailSender) matches. */
126
+ const waitForLog = async pattern => {
127
+ for (let i = 0; i < 40; i++) { if (pattern.test(logs)) return; await new Promise(resolve => setTimeout(resolve, 100)); }
128
+ assert.fail(`no log line matching ${pattern}`);
129
+ };
130
+ const step = name => console.log(`ok - ${name}`);
131
+ try {
132
+ for (let attempt = 0; ; attempt++) {
133
+ if (wrangler.exitCode !== null) throw new Error(`wrangler exited ${wrangler.exitCode}`);
134
+ try { await fetch(`${origin}/api/auth/ok`); break; } catch { /* starting */ }
135
+ if (attempt > 240) throw new Error("the Worker did not start");
136
+ await new Promise(resolve => setTimeout(resolve, 250));
137
+ }
138
+ await scenario({ origin, owner, call, mcp, signIn, sql, cron, waitForLog, step, logs: () => logs });
139
+ console.log("smoke passed");
140
+ } catch (error) {
141
+ console.error(logs.slice(-4000));
142
+ throw error;
143
+ } finally {
144
+ const stop = signal => { try { process.kill(-wrangler.pid, signal); } catch { /* already gone */ } };
145
+ stop("SIGTERM");
146
+ await new Promise(resolve => {
147
+ if (wrangler.exitCode !== null) return resolve();
148
+ const timer = setTimeout(() => { stop("SIGKILL"); resolve(); }, 5_000);
149
+ wrangler.once("exit", () => { clearTimeout(timer); resolve(); });
150
+ });
151
+ stop("SIGKILL");
152
+ rmSync(state, { recursive: true, force: true });
153
+ }
154
+ }