@aotter/mantle 0.2.0-alpha.5 → 0.2.0-alpha.7
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.
- package/README.md +152 -45
- package/dist/auth/adapter.d.ts +32 -0
- package/dist/auth/adapter.js +285 -0
- package/dist/auth/admin.d.ts +3 -0
- package/dist/auth/admin.js +21 -0
- package/dist/auth/caller.d.ts +86 -0
- package/dist/auth/caller.js +154 -0
- package/dist/auth/hardening.d.ts +24 -0
- package/dist/auth/hardening.js +40 -0
- package/dist/auth/identity.d.ts +121 -0
- package/dist/auth/identity.js +203 -0
- package/dist/auth/oauth.d.ts +31 -0
- package/dist/auth/oauth.js +124 -0
- package/dist/auth/resource-seeds.js +10 -0
- package/dist/auth/routes.d.ts +32 -0
- package/dist/auth/{createAuthRoutes.js → routes.js} +130 -35
- package/dist/build/compiler.d.ts +790 -0
- package/dist/build/compiler.js +6971 -0
- package/dist/{spec → build/spec}/domain/model/ManifestGrammar.d.ts +28 -42
- package/dist/{spec → build/spec}/domain/model/RuntimePlan.d.ts +77 -3
- package/dist/{spec → build/spec}/domain/model/SqlIr.d.ts +35 -6
- package/dist/build/spec/domain/model/UserFields.d.ts +20 -0
- package/dist/{spec → build/spec}/domain/service/PlanFingerprint.d.ts +2 -1
- package/dist/{spec → build/spec}/kernel/diagnostic.d.ts +1 -30
- package/dist/bun/assets.d.ts +2 -0
- package/dist/bun/assets.js +24 -0
- package/dist/domain/adminOrder.js +24 -0
- package/dist/domain/columns.js +55 -0
- package/dist/domain/describe/chunk-ZIQVLA7X.js +363 -0
- package/dist/domain/describe/index.d.ts +58 -0
- package/dist/domain/describe/index.js +115 -0
- package/dist/domain/describe/target-hash.d.ts +8 -0
- package/dist/domain/describe/target-hash.js +12 -0
- package/dist/domain/describe/targets.d.ts +40 -0
- package/dist/domain/entry.js +33 -0
- package/dist/domain/generated-tools.js +17 -0
- package/dist/domain/generation.d.ts +16 -0
- package/dist/domain/generation.js +1 -0
- package/dist/domain/input.js +17 -0
- package/dist/domain/model.js +1 -0
- package/dist/domain/paging.js +204 -0
- package/dist/domain/recipes.js +19 -0
- package/dist/domain/userReferences.js +5 -0
- package/dist/domain/wireScalars.js +47 -0
- package/dist/infrastructure/adminEntries.js +153 -0
- package/dist/infrastructure/adminPaging.js +72 -0
- package/dist/infrastructure/artifacts.js +71 -0
- package/dist/infrastructure/authSchema.js +83 -0
- package/dist/infrastructure/bundle.js +84 -0
- package/dist/infrastructure/cli.js +101 -0
- package/dist/infrastructure/generate.d.ts +14 -0
- package/dist/infrastructure/generate.js +174 -0
- package/dist/infrastructure/generateAuth.d.ts +8 -0
- package/dist/infrastructure/generateAuth.js +17 -0
- package/dist/infrastructure/inputs.js +36 -0
- package/dist/infrastructure/wrangler.js +71 -0
- package/dist/kernel/authorization.d.ts +4 -0
- package/dist/kernel/authorization.js +16 -0
- package/dist/kernel/binds.d.ts +51 -0
- package/dist/kernel/binds.js +45 -0
- package/dist/kernel/caller-identity.d.ts +24 -0
- package/dist/kernel/caller-identity.js +22 -0
- package/dist/kernel/contract-error.d.ts +12 -0
- package/dist/kernel/contract-error.js +14 -0
- package/dist/kernel/contracts.d.ts +139 -0
- package/dist/kernel/contracts.js +92 -0
- package/dist/{spec/domain/service/CloudflareCron.d.ts → kernel/cron.d.ts} +0 -1
- package/dist/{spec/domain/service/CloudflareCron.js → kernel/cron.js} +1 -6
- package/dist/kernel/dialect/common.d.ts +39 -0
- package/dist/kernel/dialect/common.js +6 -0
- package/dist/kernel/dialect/postgres.d.ts +16 -0
- package/dist/kernel/dialect/postgres.js +18 -0
- package/dist/kernel/dialect/sqlite.d.ts +20 -0
- package/dist/kernel/dialect/sqlite.js +34 -0
- package/dist/kernel/driver/bun-sqlite.d.ts +19 -0
- package/dist/kernel/driver/bun-sqlite.js +77 -0
- package/dist/kernel/driver/d1.d.ts +24 -0
- package/dist/kernel/driver/d1.js +22 -0
- package/dist/kernel/driver/postgres.d.ts +25 -0
- package/dist/kernel/driver/postgres.js +95 -0
- package/dist/kernel/driver/transaction-context.d.ts +10 -0
- package/dist/kernel/driver/transaction-context.js +29 -0
- package/dist/kernel/email.d.ts +28 -0
- package/dist/{auth/emailTemplates.js → kernel/email.js} +13 -2
- package/dist/kernel/host-access.d.ts +10 -0
- package/dist/kernel/host-access.js +65 -0
- package/dist/kernel/host-caller.d.ts +38 -0
- package/dist/kernel/host-caller.js +55 -0
- package/dist/kernel/json-body.d.ts +4 -0
- package/dist/kernel/json-body.js +44 -0
- package/dist/kernel/mcp-apps.d.ts +49 -0
- package/dist/kernel/mcp-apps.js +40 -0
- package/dist/kernel/mcp-call.d.ts +5 -0
- package/dist/kernel/mcp-call.js +25 -0
- package/dist/kernel/mcp-handler.js +288 -0
- package/dist/kernel/mcp.d.ts +101 -0
- package/dist/kernel/mcp.js +25 -0
- package/dist/kernel/media.d.ts +27 -0
- package/dist/kernel/media.js +216 -0
- package/dist/kernel/paging.d.ts +55 -0
- package/dist/kernel/paging.js +95 -0
- package/dist/kernel/publishing.d.ts +4 -0
- package/dist/kernel/publishing.js +16 -0
- package/dist/{cloudflare/r2Media.d.ts → kernel/r2-media.d.ts} +4 -5
- package/dist/kernel/r2-media.js +78 -0
- package/dist/kernel/rest-dispatch.js +38 -0
- package/dist/kernel/rest-router.js +63 -0
- package/dist/kernel/rest.d.ts +58 -0
- package/dist/kernel/rest.js +41 -0
- package/dist/kernel/scalars.d.ts +6 -0
- package/dist/kernel/scalars.js +43 -0
- package/dist/kernel/search.js +5 -0
- package/dist/{core/site.d.ts → kernel/site-types.d.ts} +38 -9
- package/dist/kernel/site-types.js +1 -0
- package/dist/kernel/site.d.ts +41 -0
- package/dist/kernel/site.js +32 -0
- package/dist/kernel/store.d.ts +165 -0
- package/dist/kernel/store.js +257 -0
- package/dist/kernel/surface.d.ts +10 -0
- package/dist/kernel/surface.js +19 -0
- package/dist/kernel/sweep.d.ts +17 -0
- package/dist/kernel/sweep.js +27 -0
- package/dist/kernel/translations.d.ts +1 -0
- package/dist/kernel/translations.js +13 -0
- package/dist/kernel/user-caller.d.ts +31 -0
- package/dist/kernel/user-caller.js +67 -0
- package/dist/kernel/user-field-name.js +3 -0
- package/dist/kernel/user-fields.d.ts +34 -0
- package/dist/kernel/user-fields.js +71 -0
- package/dist/kernel/validation.d.ts +15 -0
- package/dist/kernel/validation.js +54 -0
- package/dist/kernel/web-gateway.js +68 -0
- package/dist/kernel/web-head.js +15 -0
- package/dist/kernel/web-response.js +8 -0
- package/dist/kernel/web.d.ts +75 -0
- package/dist/kernel/web.js +155 -0
- package/dist/kernel/where.js +27 -0
- package/dist/testing/index.d.ts +1 -37
- package/dist/testing/index.js +1 -43
- package/dist/usecase/adminBindings.js +142 -0
- package/dist/usecase/adminDescriptors.js +153 -0
- package/dist/usecase/generate.js +164 -0
- package/dist/usecase/handlers.js +21 -0
- package/dist/usecase/mcp-media.js +17 -0
- package/dist/usecase/mcp.js +96 -0
- package/dist/usecase/paging.js +72 -0
- package/dist/usecase/publishing.js +63 -0
- package/dist/usecase/refusals.js +27 -0
- package/dist/usecase/rest.js +54 -0
- package/dist/usecase/search.js +7 -0
- package/dist/usecase/site.js +40 -0
- package/dist/usecase/stores.js +62 -0
- package/dist/usecase/translations.js +78 -0
- package/dist/usecase/ttl.js +20 -0
- package/dist/usecase/validation.js +132 -0
- package/dist/usecase/web.js +22 -0
- package/docs/examples/README.md +31 -16
- package/docs/examples/app-shell/README.md +48 -0
- package/docs/examples/app-shell/package.json +34 -0
- package/docs/examples/app-shell/pnpm-workspace.yaml +8 -0
- package/docs/examples/app-shell/smoke-kit.mjs +100 -0
- package/docs/examples/app-shell/src/admin.ts +10 -0
- package/docs/examples/app-shell/src/auth.ts +55 -0
- package/docs/examples/app-shell/src/handlers.ts +5 -0
- package/docs/examples/app-shell/src/index.ts +4 -0
- package/docs/examples/app-shell/src/routes.ts +13 -0
- package/docs/examples/app-shell/src/schedule.ts +8 -0
- package/docs/examples/app-shell/src/service.ts +70 -0
- package/docs/examples/app-shell/src/sign-in.ts +41 -0
- package/docs/examples/app-shell/src/signup.ts +8 -0
- package/docs/examples/{reference-service → app-shell}/tsconfig.json +2 -1
- package/docs/examples/app-shell/worker-configuration.d.ts +22 -0
- package/docs/examples/app-shell/wrangler.jsonc +61 -0
- package/docs/examples/club-events/README.md +60 -0
- package/docs/examples/club-events/manifests/club-events.yaml +225 -0
- package/docs/examples/club-events/smoke.mjs +121 -0
- package/docs/examples/club-events/src/handlers.ts +25 -0
- package/docs/examples/club-events/src/signup.ts +9 -0
- package/docs/examples/generated-web/README.md +74 -0
- package/docs/examples/generated-web/posts.yaml +38 -0
- package/docs/examples/generated-web/seed.sql +6 -0
- package/docs/examples/generated-web/src/worker.ts +43 -0
- package/docs/examples/generated-web/tsconfig.json +8 -0
- package/docs/examples/generated-web/wrangler.jsonc +7 -0
- package/docs/examples/purchasing/.dev.vars.example +6 -0
- package/docs/examples/purchasing/README.md +90 -0
- package/docs/examples/purchasing/manifests/purchasing.yaml +341 -0
- package/docs/examples/purchasing/seed.sql +4 -0
- package/docs/examples/purchasing/smoke.mjs +171 -0
- package/docs/examples/purchasing/src/admin.ts +12 -0
- package/docs/examples/purchasing/src/handlers.ts +33 -0
- package/docs/examples/purchasing/src/notify.ts +29 -0
- package/docs/examples/purchasing/src/requests-page.ts +57 -0
- package/docs/examples/purchasing/src/routes.ts +53 -0
- package/docs/examples/purchasing/src/schedule.ts +31 -0
- package/docs/examples/purchasing/src/signup.ts +5 -0
- package/docs/examples/purchasing/src/supplier.ts +32 -0
- package/docs/examples/purchasing/wrangler.jsonc +68 -0
- package/docs/examples/recipes/README.md +58 -0
- package/docs/examples/recipes/manifests/recipes.yaml +75 -0
- package/docs/examples/recipes/smoke.mjs +102 -0
- package/docs/examples/recipes/src/media.ts +13 -0
- package/docs/examples/recipes/src/pages.ts +99 -0
- package/docs/examples/recipes/src/routes.ts +71 -0
- package/docs/examples/recipes/src/site-config.ts +12 -0
- package/docs/examples/recipes/wrangler.jsonc +73 -0
- package/docs/handbook/cloudflare/authentication.md +142 -212
- package/docs/handbook/cloudflare/chatgpt-sites.md +4 -113
- package/docs/handbook/cloudflare/deploy-and-operate.md +20 -103
- package/docs/handbook/cloudflare/media-r2.md +62 -133
- package/docs/handbook/cloudflare/service-entry.md +180 -116
- package/docs/handbook/concepts/authorization.md +10 -123
- package/docs/handbook/concepts/four-atoms.md +9 -92
- package/docs/handbook/concepts/lifecycle-and-locales.md +9 -80
- package/docs/handbook/concepts/mcp-and-agents.md +10 -141
- package/docs/handbook/concepts/procedures-and-triggers.md +5 -162
- package/docs/handbook/concepts/runtime-and-adapters.md +15 -183
- package/docs/handbook/concepts/views.md +10 -109
- package/docs/handbook/examples/hub.md +2 -18
- package/docs/handbook/guides/adapter-guide.md +11 -0
- package/docs/handbook/guides/admin-extensions.md +20 -0
- package/docs/handbook/guides/admin-ui.md +5 -163
- package/docs/handbook/guides/agent-setup.md +5 -18
- package/docs/handbook/guides/email.md +86 -0
- package/docs/handbook/guides/mcp-apps.md +44 -0
- package/docs/handbook/guides/native-admin.md +298 -0
- package/docs/handbook/guides/native-execution.md +132 -0
- package/docs/handbook/guides/oauth.md +105 -0
- package/docs/handbook/guides/postgres-adapters.md +56 -0
- package/docs/handbook/guides/public-pages.md +53 -0
- package/docs/handbook/guides/size-and-startup.md +9 -0
- package/docs/handbook/guides/typed-queries.md +39 -102
- package/docs/handbook/navigation.json +164 -30
- package/docs/handbook/reference/admin-descriptors.md +88 -0
- package/docs/handbook/reference/authorization.md +44 -52
- package/docs/handbook/reference/describe.md +56 -0
- package/docs/handbook/reference/diagnostics.md +15 -78
- package/docs/handbook/reference/features.md +45 -53
- package/docs/handbook/reference/manifest.md +6 -69
- package/docs/handbook/reference/procedure.md +9 -117
- package/docs/handbook/reference/schema.md +65 -172
- package/docs/handbook/reference/site-config.md +5 -65
- package/docs/handbook/reference/surface.md +279 -93
- package/docs/handbook/reference/trigger.md +24 -93
- package/docs/handbook/reference/view.md +32 -158
- package/docs/handbook/releases/index.md +124 -15
- package/docs/handbook/start/overview.md +9 -56
- package/docs/handbook/start/project-and-cli.md +40 -141
- package/docs/handbook/start/quickstart-worker.md +38 -116
- package/docs/skills/develop/SKILL.md +34 -117
- package/docs/skills/develop/mcp-app.md +37 -77
- package/docs/skills/integrate/SKILL.md +42 -84
- package/docs/skills/media-gc/SKILL.md +14 -3
- package/docs/skills/provision/SKILL.md +25 -88
- package/docs/skills/update/SKILL.md +19 -40
- package/docs/source/scripts/postgres-adapter.ts +101 -0
- package/docs/upgrade-0.1-to-0.2.md +26 -10
- package/package.json +97 -112
- package/skills/.keep +0 -0
- package/skills/README.md +72 -0
- package/skills/mantle/SKILL.md +135 -0
- package/skills/mantle/references/local-testing.md +11 -0
- package/skills/mantle/references/web.md +41 -0
- package/skills/mantle/references/website.md +47 -0
- package/dist/admin/consent.d.ts +0 -17
- package/dist/admin/consent.d.ts.map +0 -1
- package/dist/admin/consent.js +0 -17
- package/dist/admin/consent.js.map +0 -1
- package/dist/admin/createAdminSurface.d.ts +0 -22
- package/dist/admin/createAdminSurface.d.ts.map +0 -1
- package/dist/admin/createAdminSurface.js +0 -592
- package/dist/admin/createAdminSurface.js.map +0 -1
- package/dist/admin/design.d.ts +0 -7
- package/dist/admin/design.d.ts.map +0 -1
- package/dist/admin/design.js +0 -18
- package/dist/admin/design.js.map +0 -1
- package/dist/admin/developerConsole.d.ts +0 -267
- package/dist/admin/developerConsole.d.ts.map +0 -1
- package/dist/admin/developerConsole.js +0 -136
- package/dist/admin/developerConsole.js.map +0 -1
- package/dist/admin/identity.d.ts +0 -62
- package/dist/admin/identity.d.ts.map +0 -1
- package/dist/admin/identity.js +0 -7
- package/dist/admin/identity.js.map +0 -1
- package/dist/admin/index.d.ts +0 -6
- package/dist/admin/index.d.ts.map +0 -1
- package/dist/admin/index.js +0 -6
- package/dist/admin/index.js.map +0 -1
- package/dist/admin/procedureFlow.d.ts +0 -38
- package/dist/admin/procedureFlow.d.ts.map +0 -1
- package/dist/admin/procedureFlow.js +0 -188
- package/dist/admin/procedureFlow.js.map +0 -1
- package/dist/auth/ConsoleEmailSender.d.ts +0 -15
- package/dist/auth/ConsoleEmailSender.d.ts.map +0 -1
- package/dist/auth/ConsoleEmailSender.js +0 -19
- package/dist/auth/ConsoleEmailSender.js.map +0 -1
- package/dist/auth/appleClientSecret.d.ts +0 -75
- package/dist/auth/appleClientSecret.d.ts.map +0 -1
- package/dist/auth/appleClientSecret.js +0 -116
- package/dist/auth/appleClientSecret.js.map +0 -1
- package/dist/auth/buildAuth.d.ts +0 -4566
- package/dist/auth/buildAuth.d.ts.map +0 -1
- package/dist/auth/buildAuth.js +0 -311
- package/dist/auth/buildAuth.js.map +0 -1
- package/dist/auth/callerResolver.d.ts +0 -48
- package/dist/auth/callerResolver.d.ts.map +0 -1
- package/dist/auth/callerResolver.js +0 -49
- package/dist/auth/callerResolver.js.map +0 -1
- package/dist/auth/createAuthRoutes.d.ts +0 -22
- package/dist/auth/createAuthRoutes.d.ts.map +0 -1
- package/dist/auth/createAuthRoutes.js.map +0 -1
- package/dist/auth/createMantleAuth.d.ts +0 -3
- package/dist/auth/createMantleAuth.d.ts.map +0 -1
- package/dist/auth/createMantleAuth.js +0 -503
- package/dist/auth/createMantleAuth.js.map +0 -1
- package/dist/auth/db.d.ts +0 -17
- package/dist/auth/db.d.ts.map +0 -1
- package/dist/auth/db.js +0 -24
- package/dist/auth/db.js.map +0 -1
- package/dist/auth/emailTemplates.d.ts +0 -7
- package/dist/auth/emailTemplates.d.ts.map +0 -1
- package/dist/auth/emailTemplates.js.map +0 -1
- package/dist/auth/index.d.ts +0 -9
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -7
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/methods.d.ts +0 -717
- package/dist/auth/methods.d.ts.map +0 -1
- package/dist/auth/methods.js +0 -321
- package/dist/auth/methods.js.map +0 -1
- package/dist/auth/oauthTokens.d.ts +0 -24
- package/dist/auth/oauthTokens.d.ts.map +0 -1
- package/dist/auth/oauthTokens.js +0 -146
- package/dist/auth/oauthTokens.js.map +0 -1
- package/dist/auth/setupIncomplete.d.ts +0 -16
- package/dist/auth/setupIncomplete.d.ts.map +0 -1
- package/dist/auth/setupIncomplete.js +0 -50
- package/dist/auth/setupIncomplete.js.map +0 -1
- package/dist/auth/types.d.ts +0 -440
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js +0 -10
- package/dist/auth/types.js.map +0 -1
- package/dist/bun/index.d.ts +0 -65
- package/dist/bun/index.d.ts.map +0 -1
- package/dist/bun/index.js +0 -130
- package/dist/bun/index.js.map +0 -1
- package/dist/cli/emitModule.d.ts +0 -7
- package/dist/cli/emitModule.d.ts.map +0 -1
- package/dist/cli/emitModule.js +0 -127
- package/dist/cli/emitModule.js.map +0 -1
- package/dist/cli/generate.d.ts +0 -8
- package/dist/cli/generate.d.ts.map +0 -1
- package/dist/cli/generate.js +0 -391
- package/dist/cli/generate.js.map +0 -1
- package/dist/cli/main.d.ts +0 -3
- package/dist/cli/main.d.ts.map +0 -1
- package/dist/cli/main.js +0 -21
- package/dist/cli/main.js.map +0 -1
- package/dist/cli/preset.d.ts +0 -18
- package/dist/cli/preset.d.ts.map +0 -1
- package/dist/cli/preset.js +0 -353
- package/dist/cli/preset.js.map +0 -1
- package/dist/cloudflare/index.d.ts +0 -21
- package/dist/cloudflare/index.d.ts.map +0 -1
- package/dist/cloudflare/index.js +0 -14
- package/dist/cloudflare/index.js.map +0 -1
- package/dist/cloudflare/r2Media.d.ts.map +0 -1
- package/dist/cloudflare/r2Media.js +0 -69
- package/dist/cloudflare/r2Media.js.map +0 -1
- package/dist/core/caller.d.ts +0 -35
- package/dist/core/caller.d.ts.map +0 -1
- package/dist/core/caller.js +0 -3
- package/dist/core/caller.js.map +0 -1
- package/dist/core/createMantle.d.ts +0 -22
- package/dist/core/createMantle.d.ts.map +0 -1
- package/dist/core/createMantle.js +0 -117
- package/dist/core/createMantle.js.map +0 -1
- package/dist/core/dialect.d.ts +0 -41
- package/dist/core/dialect.d.ts.map +0 -1
- package/dist/core/dialect.js +0 -7
- package/dist/core/dialect.js.map +0 -1
- package/dist/core/driver.d.ts +0 -17
- package/dist/core/driver.d.ts.map +0 -1
- package/dist/core/driver.js +0 -2
- package/dist/core/driver.js.map +0 -1
- package/dist/core/email.d.ts +0 -17
- package/dist/core/email.d.ts.map +0 -1
- package/dist/core/email.js +0 -2
- package/dist/core/email.js.map +0 -1
- package/dist/core/index.d.ts +0 -16
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -16
- package/dist/core/index.js.map +0 -1
- package/dist/core/invocation.d.ts +0 -66
- package/dist/core/invocation.d.ts.map +0 -1
- package/dist/core/invocation.js +0 -3
- package/dist/core/invocation.js.map +0 -1
- package/dist/core/observation.d.ts +0 -3
- package/dist/core/observation.d.ts.map +0 -1
- package/dist/core/observation.js +0 -10
- package/dist/core/observation.js.map +0 -1
- package/dist/core/runtime/auth.d.ts +0 -9
- package/dist/core/runtime/auth.d.ts.map +0 -1
- package/dist/core/runtime/auth.js +0 -39
- package/dist/core/runtime/auth.js.map +0 -1
- package/dist/core/runtime/createRuntime.d.ts +0 -23
- package/dist/core/runtime/createRuntime.d.ts.map +0 -1
- package/dist/core/runtime/createRuntime.js +0 -214
- package/dist/core/runtime/createRuntime.js.map +0 -1
- package/dist/core/runtime/verifyPlan.d.ts +0 -34
- package/dist/core/runtime/verifyPlan.d.ts.map +0 -1
- package/dist/core/runtime/verifyPlan.js +0 -301
- package/dist/core/runtime/verifyPlan.js.map +0 -1
- package/dist/core/service.d.ts +0 -45
- package/dist/core/service.d.ts.map +0 -1
- package/dist/core/service.js +0 -2
- package/dist/core/service.js.map +0 -1
- package/dist/core/site.d.ts.map +0 -1
- package/dist/core/site.js +0 -2
- package/dist/core/site.js.map +0 -1
- package/dist/core/siteConfig.d.ts +0 -5
- package/dist/core/siteConfig.d.ts.map +0 -1
- package/dist/core/siteConfig.js +0 -24
- package/dist/core/siteConfig.js.map +0 -1
- package/dist/core/sql/allowlist.d.ts +0 -65
- package/dist/core/sql/allowlist.d.ts.map +0 -1
- package/dist/core/sql/allowlist.js +0 -705
- package/dist/core/sql/allowlist.js.map +0 -1
- package/dist/core/sql/ast.d.ts +0 -24
- package/dist/core/sql/ast.d.ts.map +0 -1
- package/dist/core/sql/ast.js +0 -32
- package/dist/core/sql/ast.js.map +0 -1
- package/dist/core/sql/compile.d.ts +0 -50
- package/dist/core/sql/compile.d.ts.map +0 -1
- package/dist/core/sql/compile.js +0 -48
- package/dist/core/sql/compile.js.map +0 -1
- package/dist/core/sql/policy.d.ts +0 -121
- package/dist/core/sql/policy.d.ts.map +0 -1
- package/dist/core/sql/policy.js +0 -379
- package/dist/core/sql/policy.js.map +0 -1
- package/dist/core/sql/positions.d.ts +0 -30
- package/dist/core/sql/positions.d.ts.map +0 -1
- package/dist/core/sql/positions.js +0 -22
- package/dist/core/sql/positions.js.map +0 -1
- package/dist/core/sql/run.d.ts +0 -76
- package/dist/core/sql/run.d.ts.map +0 -1
- package/dist/core/sql/run.js +0 -267
- package/dist/core/sql/run.js.map +0 -1
- package/dist/core/store/createStore.d.ts +0 -49
- package/dist/core/store/createStore.d.ts.map +0 -1
- package/dist/core/store/createStore.js +0 -227
- package/dist/core/store/createStore.js.map +0 -1
- package/dist/core/store/cursor.d.ts +0 -4
- package/dist/core/store/cursor.d.ts.map +0 -1
- package/dist/core/store/cursor.js +0 -22
- package/dist/core/store/cursor.js.map +0 -1
- package/dist/core/store/json.d.ts +0 -80
- package/dist/core/store/json.d.ts.map +0 -1
- package/dist/core/store/json.js +0 -342
- package/dist/core/store/json.js.map +0 -1
- package/dist/core/store.d.ts +0 -160
- package/dist/core/store.d.ts.map +0 -1
- package/dist/core/store.js +0 -2
- package/dist/core/store.js.map +0 -1
- package/dist/core/wire.d.ts +0 -20
- package/dist/core/wire.d.ts.map +0 -1
- package/dist/core/wire.js +0 -84
- package/dist/core/wire.js.map +0 -1
- package/dist/core/withCaller.d.ts +0 -24
- package/dist/core/withCaller.d.ts.map +0 -1
- package/dist/core/withCaller.js +0 -35
- package/dist/core/withCaller.js.map +0 -1
- package/dist/d1/adapter.d.ts +0 -12
- package/dist/d1/adapter.d.ts.map +0 -1
- package/dist/d1/adapter.js +0 -23
- package/dist/d1/adapter.js.map +0 -1
- package/dist/d1/codec.d.ts +0 -14
- package/dist/d1/codec.d.ts.map +0 -1
- package/dist/d1/codec.js +0 -136
- package/dist/d1/codec.js.map +0 -1
- package/dist/d1/compile/index.d.ts +0 -9
- package/dist/d1/compile/index.d.ts.map +0 -1
- package/dist/d1/compile/index.js +0 -9
- package/dist/d1/compile/index.js.map +0 -1
- package/dist/d1/dialect.d.ts +0 -4
- package/dist/d1/dialect.d.ts.map +0 -1
- package/dist/d1/dialect.js +0 -13
- package/dist/d1/dialect.js.map +0 -1
- package/dist/d1/executor.d.ts +0 -13
- package/dist/d1/executor.d.ts.map +0 -1
- package/dist/d1/executor.js +0 -91
- package/dist/d1/executor.js.map +0 -1
- package/dist/d1/index.d.ts +0 -6
- package/dist/d1/index.d.ts.map +0 -1
- package/dist/d1/index.js +0 -6
- package/dist/d1/index.js.map +0 -1
- package/dist/d1/lower.d.ts +0 -8
- package/dist/d1/lower.d.ts.map +0 -1
- package/dist/d1/lower.js +0 -167
- package/dist/d1/lower.js.map +0 -1
- package/dist/d1/media.d.ts +0 -5
- package/dist/d1/media.d.ts.map +0 -1
- package/dist/d1/media.js +0 -157
- package/dist/d1/media.js.map +0 -1
- package/dist/d1/migrations.d.ts +0 -12
- package/dist/d1/migrations.d.ts.map +0 -1
- package/dist/d1/migrations.js +0 -111
- package/dist/d1/migrations.js.map +0 -1
- package/dist/d1/print.d.ts +0 -28
- package/dist/d1/print.d.ts.map +0 -1
- package/dist/d1/print.js +0 -54
- package/dist/d1/print.js.map +0 -1
- package/dist/d1/site.d.ts +0 -17
- package/dist/d1/site.d.ts.map +0 -1
- package/dist/d1/site.js +0 -63
- package/dist/d1/site.js.map +0 -1
- package/dist/d1/storage.d.ts +0 -34
- package/dist/d1/storage.d.ts.map +0 -1
- package/dist/d1/storage.js +0 -288
- package/dist/d1/storage.js.map +0 -1
- package/dist/d1/tz.d.ts +0 -21
- package/dist/d1/tz.d.ts.map +0 -1
- package/dist/d1/tz.js +0 -54
- package/dist/d1/tz.js.map +0 -1
- package/dist/d1/validator.d.ts +0 -10
- package/dist/d1/validator.d.ts.map +0 -1
- package/dist/d1/validator.js +0 -33
- package/dist/d1/validator.js.map +0 -1
- package/dist/mcp/apps.d.ts +0 -43
- package/dist/mcp/apps.d.ts.map +0 -1
- package/dist/mcp/apps.js +0 -57
- package/dist/mcp/apps.js.map +0 -1
- package/dist/mcp/catalog.d.ts +0 -55
- package/dist/mcp/catalog.d.ts.map +0 -1
- package/dist/mcp/catalog.js +0 -81
- package/dist/mcp/catalog.js.map +0 -1
- package/dist/mcp/createMcpSurface.d.ts +0 -60
- package/dist/mcp/createMcpSurface.d.ts.map +0 -1
- package/dist/mcp/createMcpSurface.js +0 -182
- package/dist/mcp/createMcpSurface.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js +0 -4
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/media.d.ts +0 -9
- package/dist/mcp/media.d.ts.map +0 -1
- package/dist/mcp/media.js +0 -33
- package/dist/mcp/media.js.map +0 -1
- package/dist/postgres/adapter.d.ts +0 -20
- package/dist/postgres/adapter.d.ts.map +0 -1
- package/dist/postgres/adapter.js +0 -44
- package/dist/postgres/adapter.js.map +0 -1
- package/dist/postgres/codec.d.ts +0 -13
- package/dist/postgres/codec.d.ts.map +0 -1
- package/dist/postgres/codec.js +0 -110
- package/dist/postgres/codec.js.map +0 -1
- package/dist/postgres/compile/index.d.ts +0 -9
- package/dist/postgres/compile/index.d.ts.map +0 -1
- package/dist/postgres/compile/index.js +0 -9
- package/dist/postgres/compile/index.js.map +0 -1
- package/dist/postgres/driver.d.ts +0 -92
- package/dist/postgres/driver.d.ts.map +0 -1
- package/dist/postgres/driver.js +0 -110
- package/dist/postgres/driver.js.map +0 -1
- package/dist/postgres/executor.d.ts +0 -20
- package/dist/postgres/executor.d.ts.map +0 -1
- package/dist/postgres/executor.js +0 -69
- package/dist/postgres/executor.js.map +0 -1
- package/dist/postgres/index.d.ts +0 -7
- package/dist/postgres/index.d.ts.map +0 -1
- package/dist/postgres/index.js +0 -7
- package/dist/postgres/index.js.map +0 -1
- package/dist/postgres/lower.d.ts +0 -6
- package/dist/postgres/lower.d.ts.map +0 -1
- package/dist/postgres/lower.js +0 -157
- package/dist/postgres/lower.js.map +0 -1
- package/dist/postgres/print.d.ts +0 -11
- package/dist/postgres/print.d.ts.map +0 -1
- package/dist/postgres/print.js +0 -121
- package/dist/postgres/print.js.map +0 -1
- package/dist/postgres/storage.d.ts +0 -19
- package/dist/postgres/storage.d.ts.map +0 -1
- package/dist/postgres/storage.js +0 -201
- package/dist/postgres/storage.js.map +0 -1
- package/dist/postgres/textRows.d.ts +0 -10
- package/dist/postgres/textRows.d.ts.map +0 -1
- package/dist/postgres/textRows.js +0 -44
- package/dist/postgres/textRows.js.map +0 -1
- package/dist/postgres/validator.d.ts +0 -12
- package/dist/postgres/validator.d.ts.map +0 -1
- package/dist/postgres/validator.js +0 -46
- package/dist/postgres/validator.js.map +0 -1
- package/dist/spec/domain/index.d.ts +0 -3
- package/dist/spec/domain/index.d.ts.map +0 -1
- package/dist/spec/domain/index.js +0 -3
- package/dist/spec/domain/index.js.map +0 -1
- package/dist/spec/domain/model/ContentState.d.ts +0 -8
- package/dist/spec/domain/model/ContentState.d.ts.map +0 -1
- package/dist/spec/domain/model/ContentState.js +0 -7
- package/dist/spec/domain/model/ContentState.js.map +0 -1
- package/dist/spec/domain/model/Entry.d.ts +0 -29
- package/dist/spec/domain/model/Entry.d.ts.map +0 -1
- package/dist/spec/domain/model/Entry.js +0 -16
- package/dist/spec/domain/model/Entry.js.map +0 -1
- package/dist/spec/domain/model/Locale.d.ts +0 -30
- package/dist/spec/domain/model/Locale.d.ts.map +0 -1
- package/dist/spec/domain/model/Locale.js +0 -33
- package/dist/spec/domain/model/Locale.js.map +0 -1
- package/dist/spec/domain/model/ManifestGrammar.d.ts.map +0 -1
- package/dist/spec/domain/model/ManifestGrammar.js +0 -149
- package/dist/spec/domain/model/ManifestGrammar.js.map +0 -1
- package/dist/spec/domain/model/MediaMimeAccept.d.ts +0 -55
- package/dist/spec/domain/model/MediaMimeAccept.d.ts.map +0 -1
- package/dist/spec/domain/model/MediaMimeAccept.js +0 -90
- package/dist/spec/domain/model/MediaMimeAccept.js.map +0 -1
- package/dist/spec/domain/model/RuntimePlan.d.ts.map +0 -1
- package/dist/spec/domain/model/RuntimePlan.js +0 -4
- package/dist/spec/domain/model/RuntimePlan.js.map +0 -1
- package/dist/spec/domain/model/SiteConfig.d.ts +0 -173
- package/dist/spec/domain/model/SiteConfig.d.ts.map +0 -1
- package/dist/spec/domain/model/SiteConfig.js +0 -13
- package/dist/spec/domain/model/SiteConfig.js.map +0 -1
- package/dist/spec/domain/model/SqlIr.d.ts.map +0 -1
- package/dist/spec/domain/model/SqlIr.js +0 -95
- package/dist/spec/domain/model/SqlIr.js.map +0 -1
- package/dist/spec/domain/model/index.d.ts +0 -14
- package/dist/spec/domain/model/index.d.ts.map +0 -1
- package/dist/spec/domain/model/index.js +0 -14
- package/dist/spec/domain/model/index.js.map +0 -1
- package/dist/spec/domain/service/CloudflareCron.d.ts.map +0 -1
- package/dist/spec/domain/service/CloudflareCron.js.map +0 -1
- package/dist/spec/domain/service/CrossSchemaChecker.d.ts +0 -34
- package/dist/spec/domain/service/CrossSchemaChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/CrossSchemaChecker.js +0 -114
- package/dist/spec/domain/service/CrossSchemaChecker.js.map +0 -1
- package/dist/spec/domain/service/EntryDataValidator.d.ts +0 -56
- package/dist/spec/domain/service/EntryDataValidator.d.ts.map +0 -1
- package/dist/spec/domain/service/EntryDataValidator.js +0 -88
- package/dist/spec/domain/service/EntryDataValidator.js.map +0 -1
- package/dist/spec/domain/service/JsonSchemaToZod.d.ts +0 -29
- package/dist/spec/domain/service/JsonSchemaToZod.d.ts.map +0 -1
- package/dist/spec/domain/service/JsonSchemaToZod.js +0 -156
- package/dist/spec/domain/service/JsonSchemaToZod.js.map +0 -1
- package/dist/spec/domain/service/LifecycleStateMachine.d.ts +0 -75
- package/dist/spec/domain/service/LifecycleStateMachine.d.ts.map +0 -1
- package/dist/spec/domain/service/LifecycleStateMachine.js +0 -76
- package/dist/spec/domain/service/LifecycleStateMachine.js.map +0 -1
- package/dist/spec/domain/service/LocaleCanonicalizer.d.ts +0 -29
- package/dist/spec/domain/service/LocaleCanonicalizer.d.ts.map +0 -1
- package/dist/spec/domain/service/LocaleCanonicalizer.js +0 -96
- package/dist/spec/domain/service/LocaleCanonicalizer.js.map +0 -1
- package/dist/spec/domain/service/ManifestFieldChecks.d.ts +0 -60
- package/dist/spec/domain/service/ManifestFieldChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestFieldChecks.js +0 -116
- package/dist/spec/domain/service/ManifestFieldChecks.js.map +0 -1
- package/dist/spec/domain/service/ManifestGraphValidator.d.ts +0 -15
- package/dist/spec/domain/service/ManifestGraphValidator.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestGraphValidator.js +0 -225
- package/dist/spec/domain/service/ManifestGraphValidator.js.map +0 -1
- package/dist/spec/domain/service/ManifestLinker.d.ts +0 -45
- package/dist/spec/domain/service/ManifestLinker.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestLinker.js +0 -92
- package/dist/spec/domain/service/ManifestLinker.js.map +0 -1
- package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts +0 -16
- package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestLocaleTrimmer.js +0 -76
- package/dist/spec/domain/service/ManifestLocaleTrimmer.js.map +0 -1
- package/dist/spec/domain/service/ManifestParser.d.ts +0 -49
- package/dist/spec/domain/service/ManifestParser.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestParser.js +0 -203
- package/dist/spec/domain/service/ManifestParser.js.map +0 -1
- package/dist/spec/domain/service/ManifestPartition.d.ts +0 -9
- package/dist/spec/domain/service/ManifestPartition.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestPartition.js +0 -19
- package/dist/spec/domain/service/ManifestPartition.js.map +0 -1
- package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts +0 -33
- package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestPathDiagnoser.js +0 -43
- package/dist/spec/domain/service/ManifestPathDiagnoser.js.map +0 -1
- package/dist/spec/domain/service/ManifestSourceSpans.d.ts +0 -10
- package/dist/spec/domain/service/ManifestSourceSpans.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestSourceSpans.js +0 -76
- package/dist/spec/domain/service/ManifestSourceSpans.js.map +0 -1
- package/dist/spec/domain/service/McpToolNaming.d.ts +0 -25
- package/dist/spec/domain/service/McpToolNaming.d.ts.map +0 -1
- package/dist/spec/domain/service/McpToolNaming.js +0 -50
- package/dist/spec/domain/service/McpToolNaming.js.map +0 -1
- package/dist/spec/domain/service/PlanFingerprint.d.ts.map +0 -1
- package/dist/spec/domain/service/PlanFingerprint.js +0 -14
- package/dist/spec/domain/service/PlanFingerprint.js.map +0 -1
- package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts +0 -4
- package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/ProcedureViewSpecChecks.js +0 -211
- package/dist/spec/domain/service/ProcedureViewSpecChecks.js.map +0 -1
- package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts +0 -42
- package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaAdminUiChecker.js +0 -289
- package/dist/spec/domain/service/SchemaAdminUiChecker.js.map +0 -1
- package/dist/spec/domain/service/SchemaIndexChecker.d.ts +0 -33
- package/dist/spec/domain/service/SchemaIndexChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaIndexChecker.js +0 -256
- package/dist/spec/domain/service/SchemaIndexChecker.js.map +0 -1
- package/dist/spec/domain/service/SchemaSearchChecker.d.ts +0 -11
- package/dist/spec/domain/service/SchemaSearchChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaSearchChecker.js +0 -78
- package/dist/spec/domain/service/SchemaSearchChecker.js.map +0 -1
- package/dist/spec/domain/service/SchemaSpecChecks.d.ts +0 -31
- package/dist/spec/domain/service/SchemaSpecChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaSpecChecks.js +0 -445
- package/dist/spec/domain/service/SchemaSpecChecks.js.map +0 -1
- package/dist/spec/domain/service/SiteDefaultsValidator.d.ts +0 -39
- package/dist/spec/domain/service/SiteDefaultsValidator.d.ts.map +0 -1
- package/dist/spec/domain/service/SiteDefaultsValidator.js +0 -194
- package/dist/spec/domain/service/SiteDefaultsValidator.js.map +0 -1
- package/dist/spec/domain/service/SqlClassify.d.ts +0 -19
- package/dist/spec/domain/service/SqlClassify.d.ts.map +0 -1
- package/dist/spec/domain/service/SqlClassify.js +0 -42
- package/dist/spec/domain/service/SqlClassify.js.map +0 -1
- package/dist/spec/domain/service/SqlRefusal.d.ts +0 -16
- package/dist/spec/domain/service/SqlRefusal.d.ts.map +0 -1
- package/dist/spec/domain/service/SqlRefusal.js +0 -20
- package/dist/spec/domain/service/SqlRefusal.js.map +0 -1
- package/dist/spec/domain/service/SqlTypes.d.ts +0 -40
- package/dist/spec/domain/service/SqlTypes.d.ts.map +0 -1
- package/dist/spec/domain/service/SqlTypes.js +0 -110
- package/dist/spec/domain/service/SqlTypes.js.map +0 -1
- package/dist/spec/domain/service/StaffRoleHierarchy.d.ts +0 -3
- package/dist/spec/domain/service/StaffRoleHierarchy.d.ts.map +0 -1
- package/dist/spec/domain/service/StaffRoleHierarchy.js +0 -19
- package/dist/spec/domain/service/StaffRoleHierarchy.js.map +0 -1
- package/dist/spec/domain/service/TriggerGraphChecks.d.ts +0 -16
- package/dist/spec/domain/service/TriggerGraphChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/TriggerGraphChecks.js +0 -337
- package/dist/spec/domain/service/TriggerGraphChecks.js.map +0 -1
- package/dist/spec/domain/service/TriggerSpecChecks.d.ts +0 -4
- package/dist/spec/domain/service/TriggerSpecChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/TriggerSpecChecks.js +0 -89
- package/dist/spec/domain/service/TriggerSpecChecks.js.map +0 -1
- package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts +0 -11
- package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts.map +0 -1
- package/dist/spec/domain/service/ValidatedAdminUiProjection.js +0 -26
- package/dist/spec/domain/service/ValidatedAdminUiProjection.js.map +0 -1
- package/dist/spec/domain/service/ViewAdminUiChecker.d.ts +0 -14
- package/dist/spec/domain/service/ViewAdminUiChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/ViewAdminUiChecker.js +0 -53
- package/dist/spec/domain/service/ViewAdminUiChecker.js.map +0 -1
- package/dist/spec/domain/service/index.d.ts +0 -24
- package/dist/spec/domain/service/index.d.ts.map +0 -1
- package/dist/spec/domain/service/index.js +0 -24
- package/dist/spec/domain/service/index.js.map +0 -1
- package/dist/spec/index.d.ts +0 -10
- package/dist/spec/index.d.ts.map +0 -1
- package/dist/spec/index.js +0 -12
- package/dist/spec/index.js.map +0 -1
- package/dist/spec/infrastructure/cli/parseArgsError.d.ts +0 -16
- package/dist/spec/infrastructure/cli/parseArgsError.d.ts.map +0 -1
- package/dist/spec/infrastructure/cli/parseArgsError.js +0 -34
- package/dist/spec/infrastructure/cli/parseArgsError.js.map +0 -1
- package/dist/spec/infrastructure/index.d.ts +0 -2
- package/dist/spec/infrastructure/index.d.ts.map +0 -1
- package/dist/spec/infrastructure/index.js +0 -2
- package/dist/spec/infrastructure/index.js.map +0 -1
- package/dist/spec/infrastructure/sql/PgQueryParser.d.ts +0 -18
- package/dist/spec/infrastructure/sql/PgQueryParser.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/PgQueryParser.js +0 -17
- package/dist/spec/infrastructure/sql/PgQueryParser.js.map +0 -1
- package/dist/spec/infrastructure/sql/compilePlan.d.ts +0 -37
- package/dist/spec/infrastructure/sql/compilePlan.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/compilePlan.js +0 -282
- package/dist/spec/infrastructure/sql/compilePlan.js.map +0 -1
- package/dist/spec/infrastructure/sql/compileSql.d.ts +0 -35
- package/dist/spec/infrastructure/sql/compileSql.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/compileSql.js +0 -92
- package/dist/spec/infrastructure/sql/compileSql.js.map +0 -1
- package/dist/spec/infrastructure/sql/frontEnd.d.ts +0 -8
- package/dist/spec/infrastructure/sql/frontEnd.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/frontEnd.js +0 -100
- package/dist/spec/infrastructure/sql/frontEnd.js.map +0 -1
- package/dist/spec/infrastructure/sql/index.d.ts +0 -4
- package/dist/spec/infrastructure/sql/index.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/index.js +0 -4
- package/dist/spec/infrastructure/sql/index.js.map +0 -1
- package/dist/spec/kernel/diagnostic.d.ts.map +0 -1
- package/dist/spec/kernel/diagnostic.js +0 -296
- package/dist/spec/kernel/diagnostic.js.map +0 -1
- package/dist/spec/kernel/index.d.ts +0 -8
- package/dist/spec/kernel/index.d.ts.map +0 -1
- package/dist/spec/kernel/index.js +0 -8
- package/dist/spec/kernel/index.js.map +0 -1
- package/dist/spec/usecase/EmitTypes.d.ts +0 -22
- package/dist/spec/usecase/EmitTypes.d.ts.map +0 -1
- package/dist/spec/usecase/EmitTypes.js +0 -182
- package/dist/spec/usecase/EmitTypes.js.map +0 -1
- package/dist/spec/usecase/ValidateManifestsUseCase.d.ts +0 -8
- package/dist/spec/usecase/ValidateManifestsUseCase.d.ts.map +0 -1
- package/dist/spec/usecase/ValidateManifestsUseCase.js +0 -101
- package/dist/spec/usecase/ValidateManifestsUseCase.js.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts +0 -27
- package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsRequest.js +0 -2
- package/dist/spec/usecase/dto/ValidateManifestsRequest.js.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts +0 -14
- package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsResponse.js +0 -2
- package/dist/spec/usecase/dto/ValidateManifestsResponse.js.map +0 -1
- package/dist/spec/usecase/dto/index.d.ts +0 -3
- package/dist/spec/usecase/dto/index.d.ts.map +0 -1
- package/dist/spec/usecase/dto/index.js +0 -3
- package/dist/spec/usecase/dto/index.js.map +0 -1
- package/dist/spec/usecase/index.d.ts +0 -10
- package/dist/spec/usecase/index.d.ts.map +0 -1
- package/dist/spec/usecase/index.js +0 -10
- package/dist/spec/usecase/index.js.map +0 -1
- package/dist/testing/cases/before-hook.d.ts +0 -4
- package/dist/testing/cases/before-hook.d.ts.map +0 -1
- package/dist/testing/cases/before-hook.js +0 -71
- package/dist/testing/cases/before-hook.js.map +0 -1
- package/dist/testing/cases/corpus.d.ts +0 -12
- package/dist/testing/cases/corpus.d.ts.map +0 -1
- package/dist/testing/cases/corpus.js +0 -91
- package/dist/testing/cases/corpus.js.map +0 -1
- package/dist/testing/cases/policy.d.ts +0 -74
- package/dist/testing/cases/policy.d.ts.map +0 -1
- package/dist/testing/cases/policy.js +0 -142
- package/dist/testing/cases/policy.js.map +0 -1
- package/dist/testing/cases/printer.d.ts +0 -4
- package/dist/testing/cases/printer.d.ts.map +0 -1
- package/dist/testing/cases/printer.js +0 -32
- package/dist/testing/cases/printer.js.map +0 -1
- package/dist/testing/cases/report-view.d.ts +0 -5
- package/dist/testing/cases/report-view.d.ts.map +0 -1
- package/dist/testing/cases/report-view.js +0 -33
- package/dist/testing/cases/report-view.js.map +0 -1
- package/dist/testing/cases/requisition.d.ts +0 -4
- package/dist/testing/cases/requisition.d.ts.map +0 -1
- package/dist/testing/cases/requisition.js +0 -38
- package/dist/testing/cases/requisition.js.map +0 -1
- package/dist/testing/cases/search-places.d.ts +0 -4
- package/dist/testing/cases/search-places.d.ts.map +0 -1
- package/dist/testing/cases/search-places.js +0 -60
- package/dist/testing/cases/search-places.js.map +0 -1
- package/dist/testing/cases/stock.d.ts +0 -4
- package/dist/testing/cases/stock.d.ts.map +0 -1
- package/dist/testing/cases/stock.js +0 -35
- package/dist/testing/cases/stock.js.map +0 -1
- package/dist/testing/cases/store.d.ts +0 -4
- package/dist/testing/cases/store.d.ts.map +0 -1
- package/dist/testing/cases/store.js +0 -100
- package/dist/testing/cases/store.js.map +0 -1
- package/dist/testing/harness.d.ts +0 -94
- package/dist/testing/harness.d.ts.map +0 -1
- package/dist/testing/harness.js +0 -168
- package/dist/testing/harness.js.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/testing/report.d.ts +0 -15
- package/dist/testing/report.d.ts.map +0 -1
- package/dist/testing/report.js +0 -22
- package/dist/testing/report.js.map +0 -1
- package/dist/web/createRestSurface.d.ts +0 -7
- package/dist/web/createRestSurface.d.ts.map +0 -1
- package/dist/web/createRestSurface.js +0 -41
- package/dist/web/createRestSurface.js.map +0 -1
- package/dist/web/index.d.ts +0 -2
- package/dist/web/index.d.ts.map +0 -1
- package/dist/web/index.js +0 -2
- package/dist/web/index.js.map +0 -1
- package/docs/adr/0001-four-atom-manifest-model.md +0 -440
- package/docs/adr/0002-closed-enums-for-bindings.md +0 -253
- package/docs/adr/0007-ai-as-primary-author.md +0 -473
- package/docs/adr/0008-structured-diagnostic-shape.md +0 -338
- package/docs/adr/0009-consumer-supplied-manifests.md +0 -149
- package/docs/adr/0010-locale-and-translates.md +0 -453
- package/docs/adr/0011-adapter-port-spec.md +0 -281
- package/docs/adr/0012-views-as-public-rest.md +0 -161
- package/docs/adr/0013-agent-provisioned-consumer-projects.md +0 -154
- package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +0 -939
- package/docs/adr/0016-site-semantic-layer.md +0 -70
- package/docs/adr/0017-media-multi-variant-agent-side-optimization.md +0 -181
- package/docs/adr/0018-core-starters-repository-boundary.md +0 -179
- package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +0 -244
- package/docs/adr/0020-builtin-handler-contracts-and-matched-upsert.md +0 -199
- package/docs/adr/0021-retire-starter-scaffolding.md +0 -30
- package/docs/adr/0022-caller-observed-version-occ.md +0 -212
- package/docs/adr/0023-port-failure-contract.md +0 -69
- package/docs/adr/0024-manifest-native-schema-tables.md +0 -264
- package/docs/adr/0025-reserved-native-columns-and-published-only-public-views.md +0 -105
- package/docs/adr/0026-progressive-generate.md +0 -36
- package/docs/adr/0027-scheduled-procedure-triggers.md +0 -31
- package/docs/adr/0028-schema-ttl-expiry.md +0 -33
- package/docs/adr/0029-mcp-apps-interaction-contracts.md +0 -324
- package/docs/adr/0030-store.md +0 -40
- package/docs/adr/0031-host-cloud-core-contract.md +0 -102
- package/docs/adr/0032-store-centric-core-and-service-contract.md +0 -384
- package/docs/adr/0033-storage-converges-to-the-plan.md +0 -92
- package/docs/adr/0034-store-is-authored-as-sql.md +0 -192
- package/docs/adr/0035-sql-dialects.md +0 -154
- package/docs/adr/0036-host-and-dialect.md +0 -65
- package/docs/adr/0037-postgresql-is-the-reference-dialect.md +0 -124
- package/docs/adr/0038-bun-native-host.md +0 -63
- package/docs/adr/README.md +0 -96
- package/docs/adr/adr-lite-803-request-diagnostics.md +0 -38
- package/docs/adr/adr-lite-808-route-readiness.md +0 -47
- package/docs/adr/adr-lite-809-bounded-public-content.md +0 -71
- package/docs/adr/adr-lite-812-native-parity.md +0 -150
- package/docs/adr/adr-lite-823-home-statistics.md +0 -64
- package/docs/adr/adr-lite-842-mcp-authoring.md +0 -30
- package/docs/adr/adr-lite-845-frontend-client.md +0 -38
- package/docs/adr/adr-lite-861-admin-webmcp.md +0 -48
- package/docs/adr/adr-lite-909-admin-ui-kit.md +0 -37
- package/docs/examples/commerce-inventory.md +0 -481
- package/docs/examples/commerce.md +0 -254
- package/docs/examples/guarded-api.md +0 -238
- package/docs/examples/intake-hooks.md +0 -237
- package/docs/examples/intake.md +0 -127
- package/docs/examples/legal-documents.md +0 -218
- package/docs/examples/procurement.md +0 -226
- package/docs/examples/publication.md +0 -211
- package/docs/examples/reference-service/.mantle/generated/mantle.ts +0 -174
- package/docs/examples/reference-service/.mantle/generated/plan.json +0 -1936
- package/docs/examples/reference-service/README.md +0 -33
- package/docs/examples/reference-service/manifests/catalog.yaml +0 -103
- package/docs/examples/reference-service/manifests/orders.yaml +0 -120
- package/docs/examples/reference-service/mantle.config.json +0 -1
- package/docs/examples/reference-service/package.json +0 -27
- package/docs/examples/reference-service/smoke.mjs +0 -160
- package/docs/examples/reference-service/src/handlers.ts +0 -36
- package/docs/examples/reference-service/src/index.ts +0 -33
- package/docs/examples/reference-service/src/service.ts +0 -78
- package/docs/examples/reference-service/wrangler.jsonc +0 -26
- package/docs/examples/reservation.md +0 -142
- /package/docs/examples/{reference-service → app-shell}/.dev.vars.example +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { viewOutputs } from "../build/compiler.js";
|
|
2
|
+
export function refuseDeclarations({ plan }, diagnostics) {
|
|
3
|
+
const refuse = (path, message) => diagnostics.push({ code: "GENERATE_UNSUPPORTED", path, message });
|
|
4
|
+
for (const [name, trigger] of Object.entries(plan.triggers)) {
|
|
5
|
+
const kind = trigger.source.kind;
|
|
6
|
+
if (kind === "http" || kind === "mcp")
|
|
7
|
+
continue;
|
|
8
|
+
refuse(`triggers/${name}`, kind === "schedule" ? "Schedule Triggers are unsupported. Wire scheduled() yourself." : "Before/after lifecycle hooks are unsupported. Write a custom handler.");
|
|
9
|
+
}
|
|
10
|
+
for (const [name, schema] of Object.entries(plan.schemas)) {
|
|
11
|
+
const parent = schema.translates && plan.schemas[schema.translates.parent.toLowerCase()];
|
|
12
|
+
if (parent?.scope && schema.scope !== parent.scope)
|
|
13
|
+
refuse(`schemas/${name}/translates`, `Scoped translation parent '${schema.translates.parent}' requires the same child scope column '${parent.scope}'. Different or missing child scope columns cannot be correlated safely.`);
|
|
14
|
+
}
|
|
15
|
+
for (const [kind, declarations] of [["views", plan.views], ["procedures", plan.procedures]]) {
|
|
16
|
+
for (const [name, declaration] of Object.entries(declarations)) {
|
|
17
|
+
if (declaration.requires?.guard)
|
|
18
|
+
refuse(`${kind}/${name}/requires/guard`, "Dynamic authorization guards are unsupported. Write a custom handler that checks authorization before executing queries.");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
for (const [name, view] of Object.entries(plan.views)) {
|
|
22
|
+
for (const [key, column] of Object.entries(viewOutputs(view, plan.schemas, new Map(), true).columns))
|
|
23
|
+
if (plan.schemas[column.schema]?.fields[column.field] === "geo") {
|
|
24
|
+
refuse(`views/${name}/columns/${key}`, "Native geo projection is unsupported. Select the latitude and longitude columns explicitly.");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { databaseImport, q, viewImports } from "../domain/entry.js";
|
|
2
|
+
import { authLines, conversions } from "../domain/input.js";
|
|
3
|
+
import { boundaryPage, outputConversions } from "../domain/columns.js";
|
|
4
|
+
export function emitRest(plan, lowered, target, description) {
|
|
5
|
+
const guard = (requires, path, binds = [], trustedOnly = false) => {
|
|
6
|
+
const lines = authLines(requires, path, binds, !target.endsWith("postgres"), trustedOnly);
|
|
7
|
+
return lines.length ? `, check: (caller) => {${lines.join("")}}` : "";
|
|
8
|
+
};
|
|
9
|
+
const userImport = plan.access ? ['import { userBinds } from "@aotter/mantle/user-fields";'] : [];
|
|
10
|
+
const refs = Object.values(plan.procedures).some(p => "ref" in p.handler);
|
|
11
|
+
const imports = [...userImport, 'import { rest as serve, type Options } from "@aotter/mantle/rest";', databaseImport(target), ...(refs ? ['import { store, type Handlers } from "./generated.js";'] : [])];
|
|
12
|
+
if (Object.values(plan.procedures).some(p => p.trustedOnly) || [...Object.values(plan.views), ...Object.values(plan.procedures)].some(p => p.requires?.auth?.all.length))
|
|
13
|
+
imports.push('import { deny, isAdmin, isUser } from "@aotter/mantle/contracts";');
|
|
14
|
+
const views = [], procedures = [];
|
|
15
|
+
let hasWire = false;
|
|
16
|
+
const convert = (code) => code ? `, convert: ${code}` : "";
|
|
17
|
+
// Each segment matches in its encoded form; `{name}` segments capture.
|
|
18
|
+
const route = (method, path) => {
|
|
19
|
+
const keys = [];
|
|
20
|
+
const source = path.split("/").map(segment => segment.startsWith("{") && segment.endsWith("}") ? (keys.push(segment.slice(1, -1)), "([^/]+)") : encodeURIComponent(segment).replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("/");
|
|
21
|
+
return `method: ${q(method)}, pattern: new RegExp(${q("^" + source + "/?$")})${keys.length ? `, keys: ${q(keys)}` : ""}`;
|
|
22
|
+
};
|
|
23
|
+
for (const [name, view] of Object.entries(plan.views)) {
|
|
24
|
+
if (view.surface !== "public")
|
|
25
|
+
continue;
|
|
26
|
+
const id = views.length, encoded = encodeURIComponent(name);
|
|
27
|
+
const wire = outputConversions(plan, name, target);
|
|
28
|
+
imports.push(...viewImports(name, id).map(line => wire.some(([, type]) => type === "int") ? line.replaceAll("./paged/views/", "./paged/wire/views/") : line));
|
|
29
|
+
hasWire ||= wire.length > 0;
|
|
30
|
+
views.push(`{ ${route("GET", `/api/views/${name}`)}, target: ${q({ kind: "view", name })}${guard(view.requires, `views/${name}`, (lowered.views[name]?.public ?? lowered.views[name]?.caller)?.binds)}, query: query${id}, page: ${boundaryPage(`page${id}`, wire)}${convert(conversions(view.input?.properties, (lowered.views[name]?.public ?? lowered.views[name]?.caller)?.binds ?? [], target))} }`);
|
|
31
|
+
}
|
|
32
|
+
const triggers = Object.values(plan.triggers).filter(t => t.source.kind === "http").sort((a, b) => a.source.kind === "http" && b.source.kind === "http" ? (a.source.path.match(/\{/g)?.length ?? 0) - (b.source.path.match(/\{/g)?.length ?? 0) : 0);
|
|
33
|
+
for (const trigger of triggers) {
|
|
34
|
+
if (trigger.source.kind !== "http")
|
|
35
|
+
continue;
|
|
36
|
+
const { method, path } = trigger.source, name = trigger.procedure, procedure = plan.procedures[name], id = procedures.length, ref = "ref" in procedure.handler;
|
|
37
|
+
if (!ref)
|
|
38
|
+
imports.push(`import procedure${id} from "./procedures/${encodeURIComponent(name)}.js";`);
|
|
39
|
+
imports.push(`import { validate as validate${id} } from "./validation/procedures/${encodeURIComponent(name)}.js";`);
|
|
40
|
+
const params = Object.fromEntries([...path.matchAll(/\{([^}]+)\}/g)].flatMap(([, key]) => {
|
|
41
|
+
const type = [procedure.input?.properties?.[key]?.type].flat().find(t => t && t !== "null");
|
|
42
|
+
return type === "integer" || type === "number" ? [[key, "number"]] : type === "boolean" ? [[key, "boolean"]] : [];
|
|
43
|
+
}));
|
|
44
|
+
procedures.push(`{ ${route(method, path)}, id: ${q(`rest:${method} ${path.replace(/\{([^}]+)\}/g, ":$1")}`)}, target: ${q({ kind: "procedure", name })}${description.targets.find(t => t._meta.id === `procedure:${name}`)?._meta.readOnly ? ", readOnly: true" : ""}${guard(procedure.requires, `procedures/${name}`, lowered.procedures[name]?.caller?.flatMap(s => s.binds), procedure.trustedOnly)}${Object.keys(params).length ? `, params: ${q(params)}` : ""}, validate: validate${id}${convert(conversions(procedure.input?.properties, lowered.procedures[name]?.caller?.flatMap(s => s.binds) ?? [], target))}, run: ${ref ? `(db, caller, input, handlers) => store(db, caller, { handlers }).procedures[${q(name)}](input)` : `procedure${id}`} }`);
|
|
45
|
+
}
|
|
46
|
+
if (hasWire)
|
|
47
|
+
imports.push('import { wireRows } from "@aotter/mantle/contracts";');
|
|
48
|
+
const list = (items) => items.length ? `[\n${items.map(item => " " + item + ",\n").join("")} ]` : "[]";
|
|
49
|
+
return { "rest.ts": `${imports.join("\n")}
|
|
50
|
+
export function rest<Env>(options: Options<Env, Database>${refs ? " & { handlers: Handlers }" : ""}): (request: Request, env: Env, ctx?: import("@aotter/mantle/contracts").RequestContext) => Promise<Response | undefined> {
|
|
51
|
+
return serve<Env, Database${refs ? ", Handlers" : ""}>(${list([...views, ...procedures])}, ${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)}'});
|
|
52
|
+
}
|
|
53
|
+
` };
|
|
54
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function searchDiagnostics(warnings) {
|
|
2
|
+
return [...new Set(warnings.filter(message => /mantle\.search|search fields/.test(message)).map(message => message.replace(/^(plan#\/[^ ]+) \([^)]*\): /, "$1: ")))].map(message => ({
|
|
3
|
+
code: "GENERATE_UNSUPPORTED",
|
|
4
|
+
path: /^plan#\/([^: ]+)/.exec(message)?.[1] ?? "views",
|
|
5
|
+
message: `${message}. Declare searchableFields on the source Schema; search_rank needs mantle.search on the same alias in the same query.`,
|
|
6
|
+
}));
|
|
7
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Generate the optional site/media module and deployment DDL, never runtime preparation. */
|
|
2
|
+
import { assertSiteDefaultsCanonical, canonicalizeLocaleList, expandPolicyRequired } from "../build/compiler.js";
|
|
3
|
+
import { driverFor, isSqlite, q } from "../domain/entry.js";
|
|
4
|
+
export function emitSite(target, defaults, refuse, schemaNames) {
|
|
5
|
+
if (!defaults)
|
|
6
|
+
return {};
|
|
7
|
+
try {
|
|
8
|
+
assertSiteDefaultsCanonical(defaults);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
refuse("site", String(error.message));
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
for (const name of schemaNames)
|
|
15
|
+
if (["site_config", "media_assets", "pending_media_uploads"].includes(name.toLowerCase()))
|
|
16
|
+
refuse(`schemas/${name}`, "This table name is reserved by the selected site/media module.");
|
|
17
|
+
if (new Set(defaults.media?.purposes?.map(p => p.name)).size !== (defaults.media?.purposes?.length ?? 0))
|
|
18
|
+
refuse("site/media/purposes", "Media purpose names must be unique.");
|
|
19
|
+
defaults = { ...defaults, ...(defaults.locales ? { locales: canonicalizeLocaleList(defaults.locales).valid } : {}) };
|
|
20
|
+
const pg = !isSqlite(target), driver = driverFor(target);
|
|
21
|
+
const policies = defaults.media?.purposes?.map(p => ({ ...p, required: expandPolicyRequired(p.required).map(slot => slot.join(",")) })) ?? [];
|
|
22
|
+
const seed = ["brand", "title", "description"].filter(key => defaults[key]).map(key => `INSERT INTO site_config (key,value) VALUES ('${key}','${defaults[key].replaceAll("'", "''")}') ON CONFLICT(key) DO NOTHING;`).join("\n");
|
|
23
|
+
const root = "@aotter/mantle";
|
|
24
|
+
return { "site.ts": `import { createSite } from "${root}/site";
|
|
25
|
+
import type { Caller } from "${root}/contracts";
|
|
26
|
+
import type { ${pg ? "Postgres" : "Handle"} as Database } from "${root}/${pg ? "contracts" : `driver/${driver}`}";
|
|
27
|
+
import * as DRIVER from "${root}/driver/${driver}";
|
|
28
|
+
import { param, escapeLike, likeEscape, like } from "${root}/dialect/${pg ? "postgres" : "sqlite"}";
|
|
29
|
+
export const siteDefaults = ${q(defaults)} as const;
|
|
30
|
+
const policies = ${q(policies)} as const;
|
|
31
|
+
export function site(db: Database, caller: Caller) { return createSite({read:(sql,values)=>DRIVER.read(db,sql,values),write:steps=>DRIVER.procedure(db,steps,"site"),definitive:DRIVER.definitive},{param,escapeLike,likeEscape,like},caller,siteDefaults,policies); }
|
|
32
|
+
`, "site-seed.sql": seed + "\n", "site-schema.sql": `CREATE TABLE site_config (key TEXT PRIMARY KEY, value TEXT NOT NULL);
|
|
33
|
+
CREATE TABLE media_assets (id TEXT PRIMARY KEY, created_at ${pg ? "BIGINT" : "INTEGER"} NOT NULL, owner_id TEXT, alt TEXT, caption TEXT, variants TEXT NOT NULL, metadata TEXT);
|
|
34
|
+
CREATE INDEX media_assets_by_created_id ON media_assets (created_at DESC, id DESC);
|
|
35
|
+
CREATE INDEX media_assets_by_owner_created ON media_assets (owner_id, created_at DESC);
|
|
36
|
+
CREATE TABLE pending_media_uploads (id TEXT PRIMARY KEY, record TEXT NOT NULL, expires_at ${pg ? "BIGINT" : "INTEGER"} NOT NULL);
|
|
37
|
+
CREATE INDEX pending_media_uploads_expires_at ON pending_media_uploads (expires_at);
|
|
38
|
+
${seed}
|
|
39
|
+
` };
|
|
40
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One typed collection per Schema, over the generic `createStore`. Core's row rules (`rowPolicy`, `writePolicy`) are evaluated
|
|
3
|
+
* here, at build time, ONCE for a placeholder scope and TTL into the shared `Rules`; a Schema adds only a `Fact` (scope, TTL,
|
|
4
|
+
* publishing, its date-time and date columns). Generation is refused if a Schema's expanded rules differ from Core's own for it
|
|
5
|
+
* (caller and trusted rows, insert fills, update sets and lock, delete lock).
|
|
6
|
+
* Column names, value types, writable columns and `orderBy` are TypeScript types only: nothing at runtime knows them.
|
|
7
|
+
*/
|
|
8
|
+
import { NATIVE_NOT_NULL, notNullColumns, rowPolicy, writePolicy } from "../build/compiler.js";
|
|
9
|
+
import { declaredType, inputType, nativeType } from "../domain/columns.js";
|
|
10
|
+
import { q } from "../domain/entry.js";
|
|
11
|
+
import { expand, SCOPE, TTL } from "../kernel/store.js";
|
|
12
|
+
import { userScopeTerm } from '../build/compiler.js';
|
|
13
|
+
// Types the typed Store compares and writes as plain bind values. Fixed numerics are scaled integers on SQLite; geo is two columns.
|
|
14
|
+
const SCALAR = new Set(["text", "real", "float8", "integer", "int4", "int8", "bool", "timestamptz", "date"]);
|
|
15
|
+
/** Core's own rules for a Schema, in the shape of `Rules` without the id expression (a delete's lock is compared separately). */
|
|
16
|
+
const core = (s, schemas) => {
|
|
17
|
+
const update = writePolicy(s, "update", { lock: true });
|
|
18
|
+
return { caller: rowPolicy(s, "caller", schemas), trusted: rowPolicy(s, "trusted", schemas), fills: writePolicy(s, "insert").fills, sets: update.sets, lock: update.lock };
|
|
19
|
+
};
|
|
20
|
+
const probe = { scope: SCOPE, ttl: TTL, ttlSeconds: 0, publishing: true };
|
|
21
|
+
/** @internal */
|
|
22
|
+
export function emitStores(schemas, isSqlite, newId, refuse, required = false) {
|
|
23
|
+
const all = Object.values(schemas).sort((a, b) => a.name < b.name ? -1 : 1);
|
|
24
|
+
if (!all.length && !required)
|
|
25
|
+
return undefined;
|
|
26
|
+
const rules = { ...core(probe), newId };
|
|
27
|
+
const tables = [], facts = [];
|
|
28
|
+
for (const s of all) {
|
|
29
|
+
const type = (column) => declaredType(s.fields, column) ?? (column === "version" ? "integer" : column === "published_at" ? "timestamptz" : "text");
|
|
30
|
+
const declared = Object.keys(s.fields).filter(f => f !== s.scope && s.fields[f] !== "geo");
|
|
31
|
+
const geo = Object.keys(s.fields).filter(f => s.fields[f] === "geo").flatMap(f => [`${f}_lat`, `${f}_lng`]); // `*` returns a geo field's two columns
|
|
32
|
+
const names = [...["id", "version", "created_at", "updated_at", "author_id", ...(s.publishing ? ["status", "published_at"] : [])], ...declared];
|
|
33
|
+
const required = new Set(s.schema.required ?? []), notNull = notNullColumns(s);
|
|
34
|
+
const nonNull = (column) => NATIVE_NOT_NULL.has(column) || notNull.has(column);
|
|
35
|
+
const ts = [...(s.publishing ? ["published_at"] : []), ...declared.filter(c => s.fields[c] === "timestamptz")], dates = declared.filter(c => s.fields[c] === "date");
|
|
36
|
+
const parent = s.translates && schemas[s.translates.parent.toLowerCase()];
|
|
37
|
+
const inherited = parent ? Object.keys(parent.fields).filter(c => c !== parent.scope && !Object.hasOwn(s.fields, c)).flatMap(c => parent.fields[c] === "geo" ? [`${c}_lat`, `${c}_lng`] : [c]) : [];
|
|
38
|
+
const inheritedType = (c) => parent?.fields[c] ?? "real";
|
|
39
|
+
const fact = {
|
|
40
|
+
...(s.userScopes?.length ? { u: s.userScopes.map(u => userScopeTerm(u, true)) } : {}),
|
|
41
|
+
...(s.scope ? { s: s.scope } : {}), ...(s.ttl ? { ttl: [s.ttl, s.ttlSeconds ?? 0] } : {}), ...(s.publishing ? { pub: 1 } : {}),
|
|
42
|
+
...(ts.length ? { ts } : {}), ...(dates.length ? { d: dates } : {}),
|
|
43
|
+
...(s.search?.length ? { search: s.search } : {}),
|
|
44
|
+
...(parent ? { parent: { on: s.translates.on.toLowerCase(), ...(parent.scope ? { scope: [parent.scope, s.scope] } : {}), table: s.translates.parent.toLowerCase(), visible: rowPolicy(s, "caller", schemas).find(t => t[1] === "parent"), caller: rowPolicy(parent, "caller", schemas), trusted: rowPolicy(parent, "trusted", schemas), fields: inherited, ts: inherited.filter(c => parent.fields[c] === "timestamptz"), d: inherited.filter(c => parent.fields[c] === "date") } } : {}),
|
|
45
|
+
};
|
|
46
|
+
// the shared rules, with this Schema's scope and TTL put in, are Core's rules for it: or the runtime would enforce something else
|
|
47
|
+
const expected = q([core(s, schemas), writePolicy(s, "delete", { lock: true }).lock]), got = q([expand(rules, fact), rules.lock]);
|
|
48
|
+
if (expected !== got)
|
|
49
|
+
refuse(`schemas/${s.name}`, `Core's row rules for this Schema differ from the shared rules (${expected} vs ${got}); the generic Store cannot serve it.`);
|
|
50
|
+
// ORDER BY is allowed where the caller's scoped read can walk an index (its first column, or the one after the scope column) and the column is NOT NULL.
|
|
51
|
+
const indexed = new Set([...(s.publishing ? [[...(s.scope ? [s.scope] : []), "published_at", "id"]] : []), ...(s.indexes ?? []), ...(s.unique ?? [])].map(i => i[0] === s.scope ? i[1] : i[0]).filter((c) => !!c));
|
|
52
|
+
const key = (c) => /^[A-Za-z_]\w*$/.test(c) ? c : q(c);
|
|
53
|
+
const of = (columns, value) => `{ ${columns.map(c => `${key(c)}: ${value(c)};`).join(" ")} }`;
|
|
54
|
+
const union = (columns) => columns.map(c => q(c)).join(" | ") || "never";
|
|
55
|
+
const scalar = (c) => SCALAR.has(type(c));
|
|
56
|
+
const writable = declared.filter(c => !(s.userScopes ?? []).some(u => u.column === c) && (scalar(c) || type(c) === "json"));
|
|
57
|
+
const input = (c) => `${inputType(type(c))}${nonNull(c) ? "" : " | null"}`;
|
|
58
|
+
tables.push(`${key(s.name)}: { row: ${of([...names, ...geo], c => c === "id" ? "string" : nativeType(geo.includes(c) ? "real" : type(c), isSqlite, nonNull(c)))}${inherited.length ? ` & { ${inherited.map(c => `${key(c)}?: ${nativeType(inheritedType(c), isSqlite)};`).join(" ")} }` : ""}; fields: ${of(names.filter(scalar), c => inputType(type(c)))}; set: ${of(writable, input)}${s.userScopes?.length ? `; insert: ${of([...writable, ...s.userScopes.map(u => u.column)], input)}` : ""}; required: ${union(s.publishing ? [] : writable.filter(c => required.has(s.names?.[c] ?? c)))}; order: ${union(["id", ...names.filter(c => c !== "id" && scalar(c) && indexed.has(c) && (nonNull(c) || s.publishing && c === "published_at"))])} }`);
|
|
59
|
+
facts.push(`${q(s.name)}: ${q(fact)}`);
|
|
60
|
+
}
|
|
61
|
+
return { tables: `{ ${tables.join("; ")} }`, rules: q(rules), facts: `{ ${facts.join(", ")} }` };
|
|
62
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { userReferences } from "../domain/userReferences.js";
|
|
2
|
+
/** Translation helpers use generated SQL policy, never a request-time manifest. */
|
|
3
|
+
import { rowPolicy } from "../build/compiler.js";
|
|
4
|
+
import { renderTerm } from "../kernel/store.js";
|
|
5
|
+
import { dialect as SQLITE } from "../kernel/dialect/sqlite.js";
|
|
6
|
+
import { dialect as POSTGRES } from "../kernel/dialect/postgres.js";
|
|
7
|
+
import { declaredType } from "../domain/columns.js";
|
|
8
|
+
import { driverFor, isSqlite, q } from "../domain/entry.js";
|
|
9
|
+
/** The parent is checked by the same atomic UPDATE that publishes the child. */
|
|
10
|
+
export function publishedParent(plan, child, d, recipes, trusted) {
|
|
11
|
+
const tr = child.translates, parent = plan.schemas[tr.parent.toLowerCase()], on = tr.on.toLowerCase();
|
|
12
|
+
const conditions = [`p.${d.ident(on)} = ${d.ident(child.name)}.${d.ident(on)}`];
|
|
13
|
+
if (parent.scope)
|
|
14
|
+
conditions.push(`p.${d.ident(parent.scope)} = ${d.ident(child.name)}.${d.ident(child.scope ?? parent.scope)}`);
|
|
15
|
+
if (parent.publishing)
|
|
16
|
+
conditions.push("p.status = 'published'");
|
|
17
|
+
for (const term of rowPolicy(parent, trusted ? "trusted" : "caller", plan.schemas))
|
|
18
|
+
conditions.push(renderTerm(d, term, "p.", recipe => (recipes.push(recipe), d.param(recipes.length))));
|
|
19
|
+
return `EXISTS (SELECT 1 FROM ${d.ident(parent.name)} p WHERE ${conditions.join(" AND ")})`;
|
|
20
|
+
}
|
|
21
|
+
export function emitTranslations(plan, target) {
|
|
22
|
+
const d = isSqlite(target) ? SQLITE : POSTGRES;
|
|
23
|
+
const user = userReferences(plan, isSqlite(target));
|
|
24
|
+
const children = Object.values(plan.schemas).filter(s => s.translates);
|
|
25
|
+
if (!Object.values(plan.schemas).some(s => s.localized))
|
|
26
|
+
return {};
|
|
27
|
+
if (!children.length)
|
|
28
|
+
return { "translations.ts": 'export {toCanonicalLocale} from "@aotter/mantle/translations";\n' };
|
|
29
|
+
const parents = [...new Set(children.map(s => s.translates.parent.toLowerCase()))], declarations = [], descriptors = [];
|
|
30
|
+
const driver = driverFor(target);
|
|
31
|
+
for (const parent of parents) {
|
|
32
|
+
const schema = plan.schemas[parent], types = children.filter(s => s.translates.parent.toLowerCase() === parent);
|
|
33
|
+
const entries = types.map(child => {
|
|
34
|
+
const on = child.translates.on.toLowerCase(), type = declaredType(child.fields, on);
|
|
35
|
+
const key = "t." + d.ident(on), projection = type === "timestamptz" ? d.wireTimestamp(key).join("") : type === "date" ? d.wireDate(key).join("") : key;
|
|
36
|
+
const lower = (mode) => {
|
|
37
|
+
const terms = rowPolicy(plan.schemas[child.name], mode, plan.schemas), recipes = [];
|
|
38
|
+
const where = terms.map(term => renderTerm(d, term, "t.", recipe => (recipes.push(recipe), d.param(recipes.length)))).join(" AND ");
|
|
39
|
+
return `{where:${q(where)},binds:${q(recipes)}}`;
|
|
40
|
+
};
|
|
41
|
+
return `{on:${q(on)},type:${q(type ?? "text")},sql:${q(`SELECT t.id AS _id, ${projection} AS _key, t.locale FROM ${d.ident(child.name)} t`)},caller:${lower('caller')},trusted:${lower('trusted')}}`;
|
|
42
|
+
});
|
|
43
|
+
const columns = [...new Set(types.map(s => s.translates.on.toLowerCase()))];
|
|
44
|
+
declarations.push(`${q(schema.name)}: Pick<Tables[${q(schema.name)}]["row"],${["id", ...columns.filter(c => c !== schema.scope)].map(value => q(value)).join("|")}>${schema.scope && columns.includes(schema.scope) ? ` & {readonly ${q(schema.scope)}?:string|null}` : ""};`);
|
|
45
|
+
descriptors.push(`${q(schema.name)}:[${entries.join(",")}]`);
|
|
46
|
+
}
|
|
47
|
+
return { "translations.ts": `${user.code ? user.code + "\n" : ""}import {ContractError,type Caller${driver === "postgres" ? ",type Postgres as Database" : ""}} from "@aotter/mantle/contracts";
|
|
48
|
+
${driver !== "postgres" ? `import type {Handle as Database} from "@aotter/mantle/driver/${driver}";` : ""}
|
|
49
|
+
import {read} from "@aotter/mantle/driver/${driver}";
|
|
50
|
+
import {binds,encode} from "@aotter/mantle/binds";
|
|
51
|
+
import {param,ident${driver === "postgres" ? ",cast" : ""},timestamp,date} from "@aotter/mantle/dialect/${driver === "postgres" ? "postgres" : "sqlite"}";
|
|
52
|
+
import type {Tables} from "./generated.js";
|
|
53
|
+
export {toCanonicalLocale} from "@aotter/mantle/translations";
|
|
54
|
+
export interface TranslationParents {${declarations.join("\n")}}
|
|
55
|
+
const descriptors={${descriptors.join(",")}} as const;
|
|
56
|
+
/** Only pass the current parent page (up to 500); reads are bounded to its keys. */
|
|
57
|
+
export async function translationLocales<P extends keyof TranslationParents>(db:Database,caller:Caller,parent:P,parents:readonly TranslationParents[P][]):Promise<Record<string,string[]>> {
|
|
58
|
+
${user.used ? ' USER.modeOf(caller);\n' : ''} if(parents.length>500)throw new ContractError("INPUT_VALIDATION_FAILED","Pass one parent page, at most 500 rows.","translations");
|
|
59
|
+
const out:Record<string,string[]>=Object.fromEntries(parents.map(row=>[row.id,[]]));
|
|
60
|
+
for(const child of descriptors[parent]) {
|
|
61
|
+
const rows=parents as readonly Record<string,unknown>[],keys=[...new Set(rows.map(row=>row[child.on]).filter(value=>value!==null&&value!==undefined&&value!==""))];
|
|
62
|
+
const byKey=new Map<unknown,Set<string>>(),mode=${user.used ? 'USER.modeOf(caller)==="trusted"' : 'caller.kind==="system"'}?child.trusted:child.caller;
|
|
63
|
+
for(let i=0;i<keys.length;i+=50) {
|
|
64
|
+
const base=binds(${user.used ? "USER_VALUES" : "{}"},mode.binds,caller),batch=keys.slice(i,i+50);let after:string|undefined;
|
|
65
|
+
do {
|
|
66
|
+
const values=[...base,...batch.map(value=>encode({timestamp,date},child.type,value))],where=[...(mode.where?[${user.used ? "USER.scoped(mode.where,caller)" : "mode.where"}]:[]),"t."+ident(child.on)+" IN ("+batch.map((_,index)=>${driver === "postgres" ? "cast(param(base.length+index+1),child.type)" : "param(base.length+index+1)"}).join(",")+")"];
|
|
67
|
+
if(after!==undefined){values.push(after);where.push("t.id > "+param(values.length));}
|
|
68
|
+
const translations:Record<string,unknown>[]=await read(db,child.sql+" WHERE "+where.join(" AND ")+" ORDER BY t.id LIMIT 500",values);
|
|
69
|
+
for(const row of translations)if(typeof row.locale==="string")byKey.set(row._key,(byKey.get(row._key)??new Set()).add(row.locale));
|
|
70
|
+
after=translations.length===500?String(translations.at(-1)!._id):undefined;
|
|
71
|
+
}while(after!==undefined);
|
|
72
|
+
}
|
|
73
|
+
for(const row of rows)for(const locale of byKey.get(row[child.on])??[])if(!out[String(row.id)]!.includes(locale))out[String(row.id)]!.push(locale);
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
` };
|
|
78
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { dialect as sqlite } from "../kernel/dialect/sqlite.js";
|
|
2
|
+
import { dialect as postgres } from "../kernel/dialect/postgres.js";
|
|
3
|
+
import { entry, exportName, q } from "../domain/entry.js";
|
|
4
|
+
export function emitTtl(plan, isSqlite, declarations, procedures, entries, refuse) {
|
|
5
|
+
const d = isSqlite ? sqlite : postgres;
|
|
6
|
+
const schemas = Object.values(plan.schemas).filter(s => s.ttl).sort((a, b) => a.name.localeCompare(b.name));
|
|
7
|
+
if (schemas.length)
|
|
8
|
+
declarations.push(`import { sweep as sweepTtl } from "@aotter/mantle/sweep";`, `import { cutoff as ttlCutoff } from "@aotter/mantle/dialect/${isSqlite ? "sqlite" : "postgres"}";`);
|
|
9
|
+
for (const s of schemas) {
|
|
10
|
+
const name = `${s.name}.sweepExpired`, fn = exportName("procedure", name), path = `procedures/${name}`;
|
|
11
|
+
if (plan.procedures[name]) {
|
|
12
|
+
refuse(path, "This name is reserved for generated TTL maintenance.");
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
const pick = `SELECT _rid FROM ${d.ident(s.name)} WHERE ${d.ident(s.ttl)} IS NOT NULL AND ${d.ident(s.ttl)} <= ${d.param(1)} AND _rid > ${d.param(2)} ORDER BY _rid LIMIT ${d.param(3)}`;
|
|
16
|
+
declarations.push(`export type ${fn}Input = import("@aotter/mantle/sweep").SweepInput;`, `export type ${fn}Result = import("@aotter/mantle/sweep").SweepResult;`, `async function ${fn}(db: Database, caller: Caller, input: ${fn}Input = {}): Promise<${fn}Result> { return sweepTtl(db, caller, input, ${q(path)}, ${s.ttlSeconds}, ${q([pick, `DELETE FROM ${d.ident(s.name)} WHERE _rid IN (${pick}) RETURNING _rid`])}, {cutoff: ttlCutoff}, DRIVER.procedure); }`, `export { ${fn} };`);
|
|
17
|
+
procedures.push(`[${q(name)}]: ${fn}`);
|
|
18
|
+
entries[`procedures/${encodeURIComponent(name)}.ts`] = entry("procedure", name, `${fn}Input as Input, ${fn}Result as Output`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { q } from "../domain/entry.js";
|
|
2
|
+
import { publishingInput } from "./publishing.js";
|
|
3
|
+
const pointer = (key) => key.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
4
|
+
const supported = new Set("$defs $ref $schema $id type nullable properties required additionalProperties items enum 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(" "));
|
|
5
|
+
const bounds = [
|
|
6
|
+
["string", "[...value].length", { minLength: "<", maxLength: ">" }],
|
|
7
|
+
["number", "value", { minimum: "<", maximum: ">", exclusiveMinimum: "<=", exclusiveMaximum: ">=" }],
|
|
8
|
+
["array", "value.length", { minItems: "<", maxItems: ">" }],
|
|
9
|
+
];
|
|
10
|
+
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)}`;
|
|
11
|
+
const typeCheck = (types) => `if (!(${types.map(type => `(${condition(type)})`).join(" || ")})) fail(path, ${q(`Expected ${types.join(" or ")}.`)});`;
|
|
12
|
+
export function emitValidation(plan, refuse = (path, message) => { throw Error(`${path}: ${message}`); }) {
|
|
13
|
+
const files = {};
|
|
14
|
+
for (const [kind, operations] of [["views", plan.views], ["procedures", plan.procedures]])
|
|
15
|
+
for (const [name, operation] of Object.entries(operations)) {
|
|
16
|
+
const root = operation.input ?? { type: "object", additionalProperties: false };
|
|
17
|
+
const base = `${kind}/${name}/input`, file = `validation/${kind}/${encodeURIComponent(name)}.ts`;
|
|
18
|
+
const json = q(root);
|
|
19
|
+
if (kind === "procedures" && json === q(publishingInput)) {
|
|
20
|
+
files[file] = `import { transition } from "@aotter/mantle/validation";\nexport const validate = (raw: unknown) => transition(${q(base)}, raw);\n`;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
// Only a local `$ref`, or more than 100 nested objects and arrays, can reach the nesting limit: only then is `depth` passed.
|
|
24
|
+
const recursive = json.includes('"$ref"') || json.split(/[[{]/).length > 101, depth = recursive ? ",depth+1" : "";
|
|
25
|
+
// Identical bodies share one function.
|
|
26
|
+
const nodes = new Map(), bodies = new Map(), functions = [], formats = new Set();
|
|
27
|
+
let equality = false;
|
|
28
|
+
const resolve = (ref) => {
|
|
29
|
+
let value = root;
|
|
30
|
+
try {
|
|
31
|
+
if (typeof ref !== "string" || !ref.startsWith("#/"))
|
|
32
|
+
throw Error();
|
|
33
|
+
for (const key of decodeURIComponent(ref.slice(2)).split("/").map(key => key.replace(/~1/g, "/").replace(/~0/g, "~")))
|
|
34
|
+
value = value && typeof value === "object" && Object.hasOwn(value, key) ? value[key] : undefined;
|
|
35
|
+
if (value && typeof value === "object")
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
refuse(base, "Input ref must be a valid local JSON pointer.");
|
|
40
|
+
return {};
|
|
41
|
+
};
|
|
42
|
+
const emit = (schema) => {
|
|
43
|
+
if (nodes.has(schema))
|
|
44
|
+
return nodes.get(schema);
|
|
45
|
+
const named = `check${nodes.size}`;
|
|
46
|
+
nodes.set(schema, named);
|
|
47
|
+
for (const key of Object.keys(schema))
|
|
48
|
+
if (!supported.has(key))
|
|
49
|
+
refuse(base, `Generated input validation does not support '${key}'.`);
|
|
50
|
+
const lines = recursive ? ['if (depth > 100) fail(path, "Input nesting exceeds 100 levels.");'] : [];
|
|
51
|
+
const check = (invalid, message) => lines.push(`if (${invalid}) fail(path, ${q(message)});`);
|
|
52
|
+
if (schema.nullable)
|
|
53
|
+
lines.push("if (value === null) return;");
|
|
54
|
+
if (schema.$ref !== undefined)
|
|
55
|
+
lines.push(`${emit(resolve(schema.$ref))}(value,path${depth});`);
|
|
56
|
+
const types = [schema.type].flat().filter((type) => !!type);
|
|
57
|
+
for (const type of types)
|
|
58
|
+
if (!"null array object integer number string boolean".split(" ").includes(type))
|
|
59
|
+
refuse(base, `Unsupported input type '${type}'.`);
|
|
60
|
+
if (types.length)
|
|
61
|
+
lines.push(typeCheck(types));
|
|
62
|
+
// After a single type check `fail` (never) has narrowed `value`: that type's guard is implied.
|
|
63
|
+
const only = types.length === 1 ? types[0] : undefined;
|
|
64
|
+
const guard = (type, test = `(${condition(type)})`) => only === type || type === "number" && only === "integer" ? "" : test + " && ";
|
|
65
|
+
if (schema.enum) {
|
|
66
|
+
equality = true;
|
|
67
|
+
check(`!${q(schema.enum)}.some(option=>equal(value,option))`, "Value is not in enum.");
|
|
68
|
+
}
|
|
69
|
+
for (const [type, measure, keywords] of bounds)
|
|
70
|
+
for (const [key, operator] of Object.entries(keywords))
|
|
71
|
+
if (schema[key] !== undefined)
|
|
72
|
+
check(`${guard(type)}${measure} ${operator} ${schema[key]}`, `Value violates ${key}.`);
|
|
73
|
+
if (schema.multipleOf !== undefined)
|
|
74
|
+
check(`${guard("number", 'typeof value === "number"')}!(Math.abs(value / ${schema.multipleOf} - Math.round(value / ${schema.multipleOf})) < 1e-9)`, "Number violates multipleOf.");
|
|
75
|
+
if (schema.pattern !== undefined) {
|
|
76
|
+
try {
|
|
77
|
+
new RegExp(schema.pattern);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
refuse(base, "Input pattern is not a valid regular expression.");
|
|
81
|
+
}
|
|
82
|
+
check(`${guard("string", 'typeof value === "string"')}!new RegExp(${q(schema.pattern)}).test(value)`, "String does not match pattern.");
|
|
83
|
+
}
|
|
84
|
+
if (schema.format) {
|
|
85
|
+
if (schema.format === "email")
|
|
86
|
+
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.");
|
|
87
|
+
else if (!["date", "date-time"].includes(schema.format))
|
|
88
|
+
refuse(base, `Generated input validation does not support format '${schema.format}'.`);
|
|
89
|
+
else {
|
|
90
|
+
const scalar = schema.format === "date" ? "encodeDate" : "encodeTimestamptz";
|
|
91
|
+
formats.add(scalar);
|
|
92
|
+
lines.push(`${only === "string" ? "" : 'if (typeof value === "string") '}try { ${scalar}(value); } catch { fail(path, ${q(`Expected a valid ${schema.format}.`)}); }`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (schema.items)
|
|
96
|
+
lines.push(`${only === "array" ? "" : "if (Array.isArray(value)) "}for (let i=0;i<value.length;i++) ${emit(schema.items)}(value[i],path+"/"+i${depth});`);
|
|
97
|
+
// Several keys that need no JSON-pointer escaping are checked by one loop, in the same order.
|
|
98
|
+
const required = schema.required ?? [], checks = Object.entries(schema.properties ?? {}).map(([key, child]) => [key, emit(child)]);
|
|
99
|
+
const loop = (keys) => keys.length > 1 && keys.every(key => pointer(key) === key);
|
|
100
|
+
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.");`);
|
|
101
|
+
if (loop(checks.map(([key]) => key)))
|
|
102
|
+
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});`);
|
|
103
|
+
else
|
|
104
|
+
for (const [key, fn] of checks)
|
|
105
|
+
object.push(`if (Object.hasOwn(object,${q(key)})) ${fn}(object[${q(key)}],path+${q("/" + pointer(key))}${depth});`);
|
|
106
|
+
if (schema.additionalProperties === false || typeof schema.additionalProperties === "object")
|
|
107
|
+
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});`} }`);
|
|
108
|
+
if (object.length)
|
|
109
|
+
lines.push(`${only === "object" ? "" : `if (${condition("object")}) `}{ const object = value as Record<string,unknown>;\n${object.join("\n")}\n}`);
|
|
110
|
+
const body = lines.join("\n");
|
|
111
|
+
// Without recursion nothing calls a check before its body is complete, so an identical body's function serves it.
|
|
112
|
+
const fn = recursive ? named : bodies.get(body) ?? named;
|
|
113
|
+
if (fn === named) {
|
|
114
|
+
bodies.set(body, fn);
|
|
115
|
+
functions.push(`function ${fn}(value:unknown,path:string${recursive ? ",depth:number" : ""}):void {\n${body}\n}`);
|
|
116
|
+
}
|
|
117
|
+
nodes.set(schema, fn);
|
|
118
|
+
return fn;
|
|
119
|
+
};
|
|
120
|
+
const validate = emit(root);
|
|
121
|
+
const fields = kind === "views" ? Object.entries(root.properties ?? {}).map(([key, schema]) => {
|
|
122
|
+
const type = [schema.type].flat().find(type => type && type !== "null");
|
|
123
|
+
return type === "boolean" || type === "integer" || type === "number" ? [key, type] : [key];
|
|
124
|
+
}) : undefined;
|
|
125
|
+
const helpers = [...(functions.length ? ["fail"] : []), ...(equality ? ["equal"] : []), ...(fields ? ["query as read"] : [])];
|
|
126
|
+
const code = `${helpers.length ? `import { ${helpers.join(", ")} } from "@aotter/mantle/validation";\n` : ""}${formats.size ? `import { ${[...formats].join(", ")} } from "@aotter/mantle/scalars";\n` : ""}${functions.join("\n")}
|
|
127
|
+
export function validate(raw:unknown):Record<string,unknown> { ${validate}(raw,${q(base)}${recursive ? ",0" : ""}); return raw as Record<string,unknown>; }
|
|
128
|
+
${fields ? `export const query = (params:URLSearchParams) => read(params, validate, ${q(`${kind}/${name}`)}, ${q(fields)});\n` : ""}`;
|
|
129
|
+
files[file] = code;
|
|
130
|
+
}
|
|
131
|
+
return files;
|
|
132
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { databaseImport, q } from "../domain/entry.js";
|
|
2
|
+
import { authLines, conversions } from "../domain/input.js";
|
|
3
|
+
export function emitWeb(plan, lowered, target) {
|
|
4
|
+
const views = Object.entries(plan.views).filter(([, v]) => v.surface === "public");
|
|
5
|
+
const table = views.map(([name, v], i) => {
|
|
6
|
+
const binds = lowered.views[name]?.public?.binds ?? [], convert = conversions(v.input?.properties, binds, target);
|
|
7
|
+
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"));
|
|
8
|
+
const check = authLines(v.requires, `views/${name}`, binds, !target.endsWith("postgres"));
|
|
9
|
+
return `[${q(name)}, { ${check.length ? `check: (caller) => {${check.join("")}}, ` : ""}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)}` : ""} }]`;
|
|
10
|
+
});
|
|
11
|
+
return { "web.ts": [
|
|
12
|
+
...(plan.access ? ['import { userBinds } from "@aotter/mantle/user-fields";'] : []),
|
|
13
|
+
...([...Object.values(plan.views)].some(v => v.requires?.auth?.all.length) ? ['import { deny, isAdmin, isUser } from "@aotter/mantle/contracts";'] : []),
|
|
14
|
+
...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";`]),
|
|
15
|
+
'import { web as site, type Options, type Page } from "@aotter/mantle/web";',
|
|
16
|
+
databaseImport(target),
|
|
17
|
+
`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]) => !v.input?.required?.length).map(([n]) => q(n)).join(" | ") || "never"} };`,
|
|
18
|
+
"export function web<const P extends Record<string, Page<App>>, E = unknown>(options: Options<App, Database, P, E>) {",
|
|
19
|
+
` 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(", ")}]);`,
|
|
20
|
+
"}"
|
|
21
|
+
].join("\n") + "\n" };
|
|
22
|
+
}
|
package/docs/examples/README.md
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
|
-
# Examples
|
|
1
|
+
# Examples
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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 |
|
|
8
|
-
|
|
9
|
-
| [
|
|
10
|
-
| [
|
|
11
|
-
| [
|
|
12
|
-
| [
|
|
13
|
-
| [
|
|
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](./reference-service/README.md) is the release smoke test for packed packages, not a starting point.
|
|
20
35
|
Projects on 0.1.x move with [the upgrade guide](../upgrade-0.1-to-0.2.md).
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
## Files you edit
|
|
24
|
+
|
|
25
|
+
| File | What it is for |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `manifests/*.yaml` | Your Schemas, Views, Procedures and Triggers. `pnpm generate` compiles every file here. |
|
|
28
|
+
| `src/handlers.ts` | Code for each `handler: { ref }` Procedure. The Store it receives is bound to the same caller. |
|
|
29
|
+
| `src/routes.ts` | App-owned routes: visitor pages, SEO files, webhooks and callbacks. |
|
|
30
|
+
| `src/admin.ts` | Admin presentation for `--admin-extensions`: `navGroups` (sidebar groups) and `adminExtensions`. Empty by default. |
|
|
31
|
+
| `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. |
|
|
32
|
+
| `src/schedule.ts` | Cron work. Add the cron to `wrangler.jsonc` `triggers.crons`. |
|
|
33
|
+
| `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. |
|
|
34
|
+
| `src/auth.ts` | Better Auth options. Two roles only: `admin` (the admin layer) and `user`. Replace the console OTP sender before deploying. |
|
|
35
|
+
| `smoke.mjs` | Your acceptance steps on `smoke-kit.mjs` (fresh local D1, OTP sign-in per user, REST/MCP/Admin calls). |
|
|
36
|
+
|
|
37
|
+
`src/service.ts` and `src/index.ts` rarely change. Delete the blocks marked `MCP / OAuth (optional)` in `auth.ts`
|
|
38
|
+
and `service.ts` if the app has no MCP.
|
|
39
|
+
|
|
40
|
+
Search for `AGENT:` to find what an app must fill in.
|
|
41
|
+
|
|
42
|
+
## Local testing notes
|
|
43
|
+
|
|
44
|
+
- Better Auth allows 3 OTP requests per minute per client IP. `smoke-kit.mjs` gives each user its own
|
|
45
|
+
`cf-connecting-ip`; when testing by hand, wait a minute or vary that header.
|
|
46
|
+
- `ADMIN_EMAIL`'s first verified sign-in becomes `admin` while no admin exists. The sign-in response may still show
|
|
47
|
+
the previous role; `/admin/api/me` shows the current one.
|
|
48
|
+
- Admin HTTP routes are listed in `docs/handbook/guides/native-admin.md`.
|
|
@@ -0,0 +1,34 @@
|
|
|
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 --admin-extensions src/admin.ts",
|
|
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
|
+
"dev": "wrangler dev --local --ip 127.0.0.1 --port 8787",
|
|
11
|
+
"check": "mantle generate cloudflare-d1 generated manifests/*.yaml --auth src/auth.ts --entry src/index.ts --admin --admin-extensions src/admin.ts --check && wrangler types --include-runtime=false --check && tsc --noEmit",
|
|
12
|
+
"smoke": "node smoke.mjs"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@aotter/mantle": "0.2.0-alpha.7",
|
|
16
|
+
"@aotter/mantle-ui": "0.2.0-alpha.7",
|
|
17
|
+
"@better-auth/cimd": "1.7.7",
|
|
18
|
+
"@better-auth/mcp": "1.7.7",
|
|
19
|
+
"@better-auth/oauth-provider": "1.7.7",
|
|
20
|
+
"@modelcontextprotocol/ext-apps": "2.0.0",
|
|
21
|
+
"@modelcontextprotocol/server": "2.1.0",
|
|
22
|
+
"better-auth": "1.7.7",
|
|
23
|
+
"@aotter/mantle-admin": "0.2.0-alpha.7"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@cloudflare/workers-types": "5.20260904.1",
|
|
27
|
+
"@types/node": "^26",
|
|
28
|
+
"typescript": "^6.0.3",
|
|
29
|
+
"wrangler": "4.129.0"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.22"
|
|
33
|
+
}
|
|
34
|
+
}
|