@mandujs/core 0.54.32 → 0.55.0-beta.1
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 +654 -654
- package/package.json +106 -210
- package/scripts/postinstall-lock.ts +153 -153
- package/src/a11y/__tests__/run-audit.test.ts +333 -333
- package/src/a11y/fix-hints.ts +76 -76
- package/src/a11y/index.ts +18 -18
- package/src/a11y/run-audit.ts +15 -15
- package/src/a11y/types.ts +125 -125
- package/src/agent/__tests__/apply.test.ts +224 -0
- package/src/agent/__tests__/context.test.ts +97 -98
- package/src/agent/apply.ts +1031 -0
- package/src/agent/context.ts +552 -552
- package/src/agent/index.ts +4 -3
- package/src/agent/plan.ts +161 -243
- package/src/agent/repair.ts +239 -162
- package/src/agent/sync.ts +197 -198
- package/src/agent/types.ts +242 -94
- package/src/agent/verify.ts +55 -55
- package/src/auth/__tests__/login.test.ts +1 -1
- package/src/auth/__tests__/password.test.ts +15 -5
- package/src/auth/__tests__/reset.test.ts +2 -2
- package/src/auth/__tests__/tokens.test.ts +274 -274
- package/src/auth/__tests__/verification.test.ts +274 -274
- package/src/auth/index.ts +76 -76
- package/src/auth/login.ts +225 -225
- package/src/auth/password.ts +14 -2
- package/src/auth/reset.ts +243 -243
- package/src/auth/tokens.ts +612 -612
- package/src/auth/verification.ts +253 -253
- package/src/brain/__tests__/redactor.test.ts +94 -94
- package/src/brain/adapters/__tests__/_helpers.ts +83 -83
- package/src/brain/adapters/__tests__/anthropic-oauth.test.ts +196 -196
- package/src/brain/adapters/__tests__/chatgpt-auth.test.ts +193 -193
- package/src/brain/adapters/__tests__/openai-oauth.test.ts +209 -209
- package/src/brain/adapters/__tests__/resolver.test.ts +143 -143
- package/src/brain/adapters/anthropic-oauth.ts +1 -1
- package/src/brain/adapters/chatgpt-auth.ts +300 -300
- package/src/brain/adapters/index.ts +319 -319
- package/src/brain/adapters/oauth-flow.ts +439 -439
- package/src/brain/consent.ts +240 -240
- package/src/brain/credentials.ts +396 -396
- package/src/brain/doctor/analyzer.ts +7 -7
- package/src/bundler/__snapshots__/build.test.ts.snap +5 -5
- package/src/bundler/__tests__/build-runner.ts +166 -166
- package/src/bundler/__tests__/client-boundary-transform.test.ts +524 -524
- package/src/bundler/__tests__/cold-start.test.ts +60 -60
- package/src/bundler/__tests__/css.test.ts +49 -20
- package/src/bundler/__tests__/dev-reliability.test.ts +619 -619
- package/src/bundler/__tests__/extended-watch.test.ts +711 -711
- package/src/bundler/__tests__/fast-refresh.test.ts +24 -24
- package/src/bundler/__tests__/generation.test.ts +447 -0
- package/src/bundler/__tests__/hdr.test.ts +24 -18
- package/src/bundler/__tests__/hmr-client.test.ts +62 -24
- package/src/bundler/__tests__/jsx-runtime-shim.test.ts +179 -140
- package/src/bundler/__tests__/manifest-schema.test.ts +305 -266
- package/src/bundler/__tests__/prod-smoke.test.ts +138 -138
- package/src/bundler/__tests__/reverse-import-graph.test.ts +42 -42
- package/src/bundler/__tests__/slot-dispatch.test.ts +573 -573
- package/src/bundler/__tests__/url-cap-and-slot-regex.test.ts +286 -286
- package/src/bundler/__tests__/vendor-cache.test.ts +455 -455
- package/src/bundler/analyzer.ts +15 -15
- package/src/bundler/budget.ts +404 -404
- package/src/bundler/build.test.ts +898 -915
- package/src/bundler/build.ts +113 -24
- package/src/bundler/client-boundary-transform.ts +977 -977
- package/src/bundler/css.ts +65 -44
- package/src/bundler/dev.ts +105 -73
- package/src/bundler/fast-refresh-preamble.ts +47 -47
- package/src/bundler/generation.ts +602 -0
- package/src/bundler/index.ts +3 -3
- package/src/bundler/manifest-schema.ts +55 -40
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +13 -13
- package/src/bundler/plugins/__tests__/react-compiler-config.test.ts +83 -83
- package/src/bundler/plugins/__tests__/react-compiler-lint.test.ts +110 -110
- package/src/bundler/plugins/block-generated-imports.ts +16 -15
- package/src/bundler/plugins/index.ts +83 -83
- package/src/bundler/plugins/react-compiler-config.ts +108 -108
- package/src/bundler/plugins/react-compiler-lint.ts +253 -253
- package/src/bundler/plugins/react-compiler.ts +162 -162
- package/src/bundler/prerender.ts +29 -9
- package/src/bundler/reverse-import-graph.ts +339 -339
- package/src/bundler/safe-build.test.ts +1 -1
- package/src/bundler/safe-build.ts +103 -103
- package/src/bundler/scenario-matrix.ts +229 -229
- package/src/bundler/types.ts +58 -56
- package/src/bundler/vendor-cache-types.ts +130 -130
- package/src/bundler/vendor-cache.ts +526 -526
- package/src/change/snapshot.ts +18 -18
- package/src/client/Form.tsx +105 -105
- package/src/client/Link.tsx +9 -9
- package/src/client/__tests__/props-serialization.test.ts +37 -37
- package/src/client/__tests__/use-sse.test.ts +153 -153
- package/src/client/globals.ts +1 -1
- package/src/client/hooks.ts +362 -362
- package/src/client/hydrate.ts +2 -2
- package/src/client/index.ts +1 -1
- package/src/client/island.ts +79 -79
- package/src/client/prefetch-helper.ts +55 -55
- package/src/client/props-serialization.ts +233 -233
- package/src/client/runtime-entry.ts +598 -598
- package/src/client/runtime.ts +1 -1
- package/src/client/serialize.ts +50 -50
- package/src/client/use-fetch.ts +6 -6
- package/src/client/use-head.ts +197 -197
- package/src/client/use-sse.ts +378 -378
- package/src/client/window-state.ts +101 -101
- package/src/components/Image-compat.ts +3 -0
- package/src/components/Image.tsx +162 -162
- package/src/config/validate.ts +1 -1
- package/src/config/watcher.ts +311 -311
- package/src/constants.ts +40 -40
- package/src/content/collection.ts +9 -9
- package/src/content/content-layer.ts +7 -7
- package/src/content/data-store.ts +245 -245
- package/src/content/frontmatter.ts +189 -189
- package/src/content/generate-types.ts +1 -1
- package/src/content/index.ts +2 -2
- package/src/content/loader-context.ts +171 -171
- package/src/content/loaders/api.ts +216 -216
- package/src/content/loaders/file.ts +172 -172
- package/src/content/loaders/glob.ts +253 -253
- package/src/content/loaders/index.ts +34 -34
- package/src/content/loaders/types.ts +137 -137
- package/src/content/meta-store.ts +209 -209
- package/src/content/prebuild.test.ts +571 -571
- package/src/content/prebuild.ts +636 -636
- package/src/content/schema.ts +20 -20
- package/src/content/sidebar.ts +630 -630
- package/src/content/slug.ts +110 -110
- package/src/content/types.ts +282 -282
- package/src/content/watcher.ts +135 -135
- package/src/contract/client-safe.test.ts +42 -42
- package/src/contract/client-safe.ts +114 -114
- package/src/contract/define.ts +11 -11
- package/src/contract/index.ts +1 -1
- package/src/contract/normalize.test.ts +276 -276
- package/src/contract/normalize.ts +410 -410
- package/src/contract/registry.test.ts +206 -206
- package/src/contract/route-helpers.ts +1 -1
- package/src/contract/rpc.ts +443 -443
- package/src/contract/types.ts +58 -58
- package/src/db/__tests__/db.test.ts +9 -9
- package/src/db/index.ts +2 -2
- package/src/db/migrations/history-table.ts +345 -345
- package/src/db/migrations/index.ts +3 -3
- package/src/db/migrations/lock.ts +324 -324
- package/src/db/migrations/runner.ts +650 -650
- package/src/deploy/cache.ts +140 -140
- package/src/deploy/compile/vercel.ts +344 -344
- package/src/deploy/index.ts +87 -87
- package/src/deploy/inference/brain.ts +268 -268
- package/src/deploy/inference/context.ts +82 -82
- package/src/deploy/inference/filling-extract.ts +245 -245
- package/src/deploy/inference/heuristic.ts +182 -182
- package/src/deploy/intent.ts +173 -173
- package/src/deploy/plan.ts +178 -178
- package/src/design/__tests__/agents-link.test.ts +109 -109
- package/src/design/__tests__/extract-patch-diff.test.ts +265 -265
- package/src/design/__tests__/lint.test.ts +110 -110
- package/src/design/__tests__/parser.test.ts +195 -195
- package/src/design/__tests__/tailwind-theme.test.ts +229 -229
- package/src/design/agents-link.ts +165 -165
- package/src/design/diff.ts +138 -138
- package/src/design/extract.ts +285 -285
- package/src/design/index.ts +102 -102
- package/src/design/lint.ts +209 -209
- package/src/design/parser.ts +555 -555
- package/src/design/patch.ts +241 -241
- package/src/design/scaffold.ts +147 -147
- package/src/design/tailwind-theme.ts +441 -441
- package/src/design/types.ts +210 -210
- package/src/desktop/__tests__/smoke.test.ts +2 -2
- package/src/desktop/__tests__/webview-fallback.test.ts +12 -32
- package/src/desktop/__tests__/window.test.ts +20 -99
- package/src/desktop/__tests__/worker.test.ts +266 -266
- package/src/desktop/index.ts +43 -43
- package/src/desktop/types.ts +158 -158
- package/src/desktop/webview-fallback.ts +17 -4
- package/src/desktop/window.ts +17 -8
- package/src/desktop/worker.ts +180 -180
- package/src/dev-error-overlay/__tests__/overlay-injector.test.ts +241 -241
- package/src/dev-error-overlay/index.ts +30 -30
- package/src/dev-error-overlay/overlay-injector.ts +243 -243
- package/src/dev-error-overlay/overlay-styles.ts +52 -52
- package/src/dev-error-overlay/types.ts +66 -66
- package/src/devtools/ai/context-builder.ts +375 -375
- package/src/devtools/ai/index.ts +25 -25
- package/src/devtools/ai/mcp-connector.ts +25 -25
- package/src/devtools/client/catchers/error-catcher.ts +344 -344
- package/src/devtools/client/catchers/index.ts +18 -18
- package/src/devtools/client/components/index.ts +39 -39
- package/src/devtools/client/components/mandu-character.tsx +331 -331
- package/src/devtools/client/components/panel/errors-panel.tsx +259 -259
- package/src/devtools/client/components/panel/guard-panel.tsx +30 -30
- package/src/devtools/client/components/panel/islands-panel.tsx +16 -16
- package/src/devtools/client/components/panel/network-panel.tsx +291 -291
- package/src/devtools/client/components/panel/panel-container.tsx +1 -1
- package/src/devtools/client/components/panel/preview-panel.tsx +46 -46
- package/src/devtools/client/filters/context-filters.ts +282 -282
- package/src/devtools/client/filters/index.ts +16 -16
- package/src/devtools/client/index.ts +63 -63
- package/src/devtools/hook/create-hook.ts +207 -207
- package/src/devtools/hook/index.ts +13 -13
- package/src/devtools/index.ts +439 -439
- package/src/devtools/init.ts +265 -265
- package/src/devtools/protocol.ts +237 -237
- package/src/devtools/server/index.ts +17 -17
- package/src/devtools/types.ts +35 -35
- package/src/devtools/worker/index.ts +25 -25
- package/src/devtools/worker/redaction-worker.ts +233 -233
- package/src/diagnose/__tests__/checks.test.ts +136 -136
- package/src/diagnose/checks.ts +185 -185
- package/src/diagnose/index.ts +17 -17
- package/src/diagnose/run.ts +10 -10
- package/src/diagnose/types.ts +53 -53
- package/src/email/__tests__/email.test.ts +355 -355
- package/src/email/index.ts +282 -282
- package/src/email/smtp.ts +64 -64
- package/src/error/domains.ts +265 -265
- package/src/error/types.ts +6 -6
- package/src/errors/extractor.ts +409 -409
- package/src/errors/index.ts +19 -19
- package/src/filling/__tests__/session-sqlite.test.ts +5 -1
- package/src/filling/auth.ts +308 -308
- package/src/filling/body-parse.test.ts +60 -60
- package/src/filling/cookie-codec.ts +5 -3
- package/src/filling/deps.ts +265 -265
- package/src/filling/head-method.test.ts +154 -154
- package/src/filling/session-sqlite.ts +617 -617
- package/src/filling/sse.ts +5 -5
- package/src/filling/ws.ts +78 -78
- package/src/generator/generate.ts +30 -30
- package/src/generator/index.ts +3 -3
- package/src/generator/templates.test.ts +48 -48
- package/src/generator/templates.ts +219 -219
- package/src/guard/__tests__/design-inline-class.test.ts +219 -219
- package/src/guard/__tests__/tsgolint-bridge.test.ts +347 -347
- package/src/guard/analyzer.ts +360 -360
- package/src/guard/auto-correct.ts +1 -1
- package/src/guard/check.ts +39 -24
- package/src/guard/config-guard.ts +13 -13
- package/src/guard/contract-guard.ts +9 -9
- package/src/guard/define-rule.ts +243 -243
- package/src/guard/design-inline-class.ts +393 -393
- package/src/guard/file-type.test.ts +24 -24
- package/src/guard/fs-routes-policy.ts +51 -51
- package/src/guard/graph.ts +1 -1
- package/src/guard/healing.ts +36 -36
- package/src/guard/index.ts +11 -11
- package/src/guard/presets/atomic.ts +70 -70
- package/src/guard/presets/clean.ts +77 -77
- package/src/guard/presets/fsd.ts +79 -79
- package/src/guard/presets/hexagonal.ts +68 -68
- package/src/guard/reporter.ts +442 -442
- package/src/guard/rule-presets.ts +379 -379
- package/src/guard/semantic-slots.ts +1 -1
- package/src/guard/suggestions.ts +358 -358
- package/src/guard/tsgolint-bridge.ts +512 -512
- package/src/guard/types.ts +348 -348
- package/src/guard/watcher.ts +405 -405
- package/src/i18n/define.ts +126 -126
- package/src/i18n/index.ts +52 -52
- package/src/i18n/message-registry.ts +173 -173
- package/src/i18n/types.ts +112 -112
- package/src/id/__tests__/id.test.ts +3 -3
- package/src/id/index.ts +105 -105
- package/src/index.ts +9 -48
- package/src/internal/client-boundary.ts +266 -266
- package/src/internal/index.ts +2 -2
- package/src/kitchen/api/agent-devtools-api.ts +779 -779
- package/src/kitchen/api/bundle-inspector.ts +179 -0
- package/src/kitchen/api/errors-grouping.ts +126 -126
- package/src/kitchen/api/file-api.ts +11 -11
- package/src/kitchen/kitchen-handler.ts +36 -0
- package/src/kitchen/kitchen-ui.ts +456 -0
- package/src/logging/index.ts +22 -22
- package/src/logging/transports.ts +365 -365
- package/src/middleware/bridge.ts +147 -147
- package/src/middleware/compose.ts +134 -134
- package/src/middleware/compress.ts +62 -62
- package/src/middleware/cors.ts +47 -47
- package/src/middleware/csrf.ts +328 -328
- package/src/middleware/define.ts +132 -132
- package/src/middleware/jwt.ts +134 -134
- package/src/middleware/logger.ts +58 -58
- package/src/middleware/oauth/__tests__/oauth.test.ts +1 -1
- package/src/middleware/oauth/index.ts +505 -505
- package/src/middleware/oauth/providers.ts +115 -115
- package/src/middleware/rate-limit/index.ts +522 -522
- package/src/middleware/rate-limit/sqlite-store.ts +382 -382
- package/src/middleware/scheduler-cron.ts +96 -96
- package/src/middleware/secure/__tests__/secure.test.ts +360 -360
- package/src/middleware/secure/csp.ts +193 -193
- package/src/middleware/session.ts +174 -174
- package/src/middleware/timeout.ts +55 -55
- package/src/observability/logger-adapter.ts +36 -36
- package/src/observability/sqlite-store.ts +254 -254
- package/src/openapi/generator.ts +1 -1
- package/src/openapi/openapi.test.ts +43 -43
- package/src/perf/__tests__/user-marks.test.ts +354 -354
- package/src/perf/index.ts +133 -133
- package/src/perf/user-marks.ts +1 -1
- package/src/plugins/__tests__/lifecycle-integration.test.ts +272 -272
- package/src/plugins/__tests__/runner.test.ts +409 -409
- package/src/plugins/define.ts +124 -124
- package/src/plugins/examples/dep-check-plugin.ts +80 -80
- package/src/plugins/examples/prerender-cache-plugin.ts +111 -111
- package/src/plugins/examples/sitemap-plugin.ts +65 -65
- package/src/plugins/runner.ts +361 -361
- package/src/plugins/types.ts +368 -368
- package/src/report/index.ts +1 -1
- package/src/resource/__tests__/generator.test.ts +7 -7
- package/src/resource/__tests__/schema.test.ts +14 -14
- package/src/resource/ddl/__tests__/diff.test.ts +639 -639
- package/src/resource/ddl/__tests__/emit.test.ts +165 -165
- package/src/resource/ddl/__tests__/snapshot.test.ts +499 -499
- package/src/resource/ddl/emit.ts +146 -146
- package/src/resource/ddl/persistence-types.ts +218 -218
- package/src/resource/ddl/type-map.ts +223 -223
- package/src/resource/ddl/types.ts +232 -232
- package/src/resource/generator-repo.ts +630 -630
- package/src/resource/generator-schema.ts +11 -11
- package/src/resource/generators/slot.ts +72 -72
- package/src/resource/schema.ts +21 -21
- package/src/router/client-entry.test.ts +227 -227
- package/src/router/client-entry.ts +218 -218
- package/src/router/fs-patterns.test.ts +96 -96
- package/src/router/fs-routes.test.ts +532 -532
- package/src/router/fs-routes.ts +53 -53
- package/src/router/fs-scanner.ts +216 -216
- package/src/router/fs-types.ts +19 -19
- package/src/router/route-source-analyzer.ts +521 -521
- package/src/routes/index.ts +74 -74
- package/src/routes/metadata-routes.ts +427 -427
- package/src/routes/types.ts +341 -341
- package/src/runtime/__tests__/devtools-adapter.test.ts +68 -68
- package/src/runtime/__tests__/error-boundary-redaction.test.ts +141 -141
- package/src/runtime/__tests__/hdr-client.test.ts +223 -223
- package/src/runtime/__tests__/http-errors.test.ts +117 -117
- package/src/runtime/__tests__/inline-client-hydration.test.ts +237 -237
- package/src/runtime/__tests__/not-found.test.ts +152 -152
- package/src/runtime/__tests__/observability-lifecycle.test.ts +103 -103
- package/src/runtime/__tests__/page-render-response.test.ts +517 -517
- package/src/runtime/__tests__/request-middleware.test.ts +70 -70
- package/src/runtime/__tests__/searchparams-page-props.test.ts +81 -81
- package/src/runtime/adapter.ts +47 -47
- package/src/runtime/boundary.tsx +252 -252
- package/src/runtime/cache.ts +494 -494
- package/src/runtime/compose.ts +222 -222
- package/src/runtime/devtools-adapter.ts +68 -68
- package/src/runtime/escape.ts +34 -34
- package/src/runtime/fast-refresh-runtime.ts +322 -322
- package/src/runtime/fast-refresh-types.ts +1 -1
- package/src/runtime/handler.ts +65 -65
- package/src/runtime/handlers.ts +30 -11
- package/src/runtime/http-errors.ts +113 -113
- package/src/runtime/image-handler.ts +1 -1
- package/src/runtime/lifecycle.ts +381 -381
- package/src/runtime/logger.test.ts +345 -345
- package/src/runtime/middleware.ts +264 -264
- package/src/runtime/not-found.ts +93 -93
- package/src/runtime/observability-lifecycle.ts +290 -290
- package/src/runtime/openapi-endpoint.ts +236 -236
- package/src/runtime/page-render-response.ts +287 -274
- package/src/runtime/ppr.ts +74 -74
- package/src/runtime/rate-limit.ts +1 -1
- package/src/runtime/redirect.ts +1 -1
- package/src/runtime/registry.ts +171 -171
- package/src/runtime/request-middleware.ts +31 -31
- package/src/runtime/router.test.ts +4 -4
- package/src/runtime/router.ts +10 -10
- package/src/runtime/server.ts +127 -211
- package/src/runtime/shims.ts +48 -48
- package/src/runtime/ssr.ts +43 -17
- package/src/runtime/static-files.ts +369 -289
- package/src/runtime/streaming-ssr.ts +219 -180
- package/src/runtime/trace.ts +144 -144
- package/src/scheduler/__tests__/scheduler.test.ts +12 -11
- package/src/scheduler/index.ts +11 -5
- package/src/scheduler/validate.ts +169 -169
- package/src/seo/index.ts +219 -219
- package/src/seo/integration/ssr.ts +306 -306
- package/src/seo/render/basic.ts +435 -435
- package/src/seo/render/index.ts +143 -143
- package/src/seo/render/jsonld.ts +539 -539
- package/src/seo/render/opengraph.ts +197 -197
- package/src/seo/render/robots.ts +116 -116
- package/src/seo/render/sitemap.ts +137 -137
- package/src/seo/render/twitter.ts +127 -127
- package/src/seo/resolve/opengraph.ts +143 -143
- package/src/seo/resolve/robots.ts +73 -73
- package/src/seo/resolve/title.ts +94 -94
- package/src/seo/resolve/twitter.ts +73 -73
- package/src/seo/resolve/url.ts +104 -104
- package/src/seo/routes/index.ts +290 -290
- package/src/seo/types.ts +588 -588
- package/src/slot/validator.ts +39 -39
- package/src/spec/schema.ts +35 -35
- package/src/storage/s3/__tests__/s3.test.ts +479 -479
- package/src/storage/s3/index.ts +412 -412
- package/src/testing/__tests__/assertions.test.ts +632 -632
- package/src/testing/__tests__/reporter.test.ts +454 -454
- package/src/testing/assertions.ts +986 -986
- package/src/testing/db.ts +157 -157
- package/src/testing/index.ts +9 -3
- package/src/testing/lcov.ts +192 -0
- package/src/testing/mocks.ts +203 -203
- package/src/testing/session.ts +190 -190
- package/src/types/branded.ts +56 -56
- package/src/types/index.ts +1 -1
- package/src/utils/safe-io.ts +188 -188
- package/src/utils/string-safe.ts +298 -298
- package/src/watcher/__tests__/watcher.test.ts +59 -59
- package/src/watcher/watcher.ts +61 -61
package/src/resource/ddl/emit.ts
CHANGED
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
* 4. Value literals in `DEFAULT` clauses flow through `resolveDefault`
|
|
16
16
|
* which handles quote escaping. `kind: "sql"` is the explicit
|
|
17
17
|
* escape hatch — caller's responsibility.
|
|
18
|
-
* 5. Unsupported changes (v1 scope — `alter-column-type`, and some
|
|
19
|
-
* dialect-specific ALTER gaps) emit a `-- TODO:` comment block plus
|
|
20
|
-
* a deliberate failing sentinel statement. The generated migration
|
|
21
|
-
* is reviewable/editable, but `mandu db apply` will not record it
|
|
22
|
-
* until the operator replaces the TODO with real SQL.
|
|
18
|
+
* 5. Unsupported changes (v1 scope — `alter-column-type`, and some
|
|
19
|
+
* dialect-specific ALTER gaps) emit a `-- TODO:` comment block plus
|
|
20
|
+
* a deliberate failing sentinel statement. The generated migration
|
|
21
|
+
* is reviewable/editable, but `mandu db apply` will not record it
|
|
22
|
+
* until the operator replaces the TODO with real SQL.
|
|
23
23
|
*
|
|
24
24
|
* Determinism:
|
|
25
25
|
* - `emitCreateTable` emits columns in `DdlFieldDef` array order — the
|
|
@@ -339,16 +339,16 @@ export function emitChange(change: Change, provider: SqlProvider): string {
|
|
|
339
339
|
// Change emitters (internal — called only via emitChange dispatch).
|
|
340
340
|
// =====================================================================
|
|
341
341
|
|
|
342
|
-
function emitAddColumn(
|
|
343
|
-
resourceName: string,
|
|
344
|
-
field: DdlFieldDef,
|
|
345
|
-
provider: SqlProvider,
|
|
346
|
-
): string {
|
|
347
|
-
validateAddColumn(resourceName, field, provider);
|
|
348
|
-
const table = quoteIdent(resourceName, provider);
|
|
349
|
-
const columnDef = emitColumnDef(field, provider);
|
|
350
|
-
const addColumn = `ALTER TABLE ${table} ADD COLUMN ${columnDef};`;
|
|
351
|
-
if (!field.indexed || field.unique || field.primary) return addColumn;
|
|
342
|
+
function emitAddColumn(
|
|
343
|
+
resourceName: string,
|
|
344
|
+
field: DdlFieldDef,
|
|
345
|
+
provider: SqlProvider,
|
|
346
|
+
): string {
|
|
347
|
+
validateAddColumn(resourceName, field, provider);
|
|
348
|
+
const table = quoteIdent(resourceName, provider);
|
|
349
|
+
const columnDef = emitColumnDef(field, provider);
|
|
350
|
+
const addColumn = `ALTER TABLE ${table} ADD COLUMN ${columnDef};`;
|
|
351
|
+
if (!field.indexed || field.unique || field.primary) return addColumn;
|
|
352
352
|
return [
|
|
353
353
|
addColumn,
|
|
354
354
|
emitCreateIndex(
|
|
@@ -358,85 +358,85 @@ function emitAddColumn(
|
|
|
358
358
|
false,
|
|
359
359
|
provider,
|
|
360
360
|
),
|
|
361
|
-
].join("\n");
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
function validateAddColumn(
|
|
365
|
-
resourceName: string,
|
|
366
|
-
field: DdlFieldDef,
|
|
367
|
-
provider: SqlProvider,
|
|
368
|
-
): void {
|
|
369
|
-
if (provider !== "sqlite") return;
|
|
370
|
-
|
|
371
|
-
if (field.primary) {
|
|
372
|
-
throw new Error(
|
|
373
|
-
`SQLite cannot add PRIMARY KEY column "${field.name}" to existing table "${resourceName}" via ALTER TABLE. ` +
|
|
374
|
-
`Create a manual table-rebuild migration instead.`,
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (field.unique) {
|
|
379
|
-
throw new Error(
|
|
380
|
-
`SQLite cannot add UNIQUE column "${field.name}" to existing table "${resourceName}" via ALTER TABLE. ` +
|
|
381
|
-
`Add a nullable/non-unique column first, backfill it, then create a unique index manually.`,
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
const defaultIssue = sqliteAddColumnDefaultIssue(field);
|
|
386
|
-
if (defaultIssue) {
|
|
387
|
-
throw new Error(
|
|
388
|
-
`SQLite cannot add column "${field.name}" to existing table "${resourceName}" with this DEFAULT: ` +
|
|
389
|
-
`${defaultIssue} Use a scalar literal default or write a manual backfill migration.`,
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
if (field.nullable) return;
|
|
394
|
-
if (field.default !== undefined && !isSqliteNullDefault(field.default)) return;
|
|
395
|
-
|
|
396
|
-
throw new Error(
|
|
397
|
-
`SQLite cannot add required column "${field.name}" to existing table "${resourceName}" without a non-NULL constant DEFAULT. ` +
|
|
398
|
-
`Add a scalar default, set required:false, or write a manual backfill migration.`,
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
function sqliteAddColumnDefaultIssue(field: DdlFieldDef): string | null {
|
|
403
|
-
const def = field.default;
|
|
404
|
-
if (!def) return null;
|
|
405
|
-
if (def.kind === "now") {
|
|
406
|
-
return `default "now" maps to CURRENT_TIMESTAMP, which SQLite rejects in ADD COLUMN.`;
|
|
407
|
-
}
|
|
408
|
-
if (def.kind !== "sql") return null;
|
|
409
|
-
|
|
410
|
-
const expr = def.expr.trim();
|
|
411
|
-
if (/^CURRENT_(?:TIME|DATE|TIMESTAMP)\b/i.test(expr)) {
|
|
412
|
-
return `SQLite rejects CURRENT_TIME/CURRENT_DATE/CURRENT_TIMESTAMP in ADD COLUMN.`;
|
|
413
|
-
}
|
|
414
|
-
if (/\b[A-Za-z_][A-Za-z0-9_]*\s*\(/.test(expr)) {
|
|
415
|
-
return `SQLite rejects non-constant function defaults in ADD COLUMN.`;
|
|
416
|
-
}
|
|
417
|
-
if (!isSqliteAddColumnConstantSqlDefault(expr)) {
|
|
418
|
-
return `SQLite ADD COLUMN only accepts literal constant defaults; raw SQL expression ${JSON.stringify(expr)} is not safe to emit automatically.`;
|
|
419
|
-
}
|
|
420
|
-
return null;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
function isSqliteNullDefault(def: NonNullable<DdlFieldDef["default"]>): boolean {
|
|
424
|
-
return def.kind === "null" || (def.kind === "sql" && /^NULL$/i.test(def.expr.trim()));
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
function isSqliteAddColumnConstantSqlDefault(expr: string): boolean {
|
|
428
|
-
let value = expr.trim();
|
|
429
|
-
while (value.startsWith("(") && value.endsWith(")")) {
|
|
430
|
-
value = value.slice(1, -1).trim();
|
|
431
|
-
}
|
|
432
|
-
return (
|
|
433
|
-
/^NULL$/i.test(value) ||
|
|
434
|
-
/^(?:TRUE|FALSE)$/i.test(value) ||
|
|
435
|
-
/^[+-]?(?:\d+|\d+\.\d+|\.\d+)(?:e[+-]?\d+)?$/i.test(value) ||
|
|
436
|
-
/^'(?:''|[^'])*'$/.test(value) ||
|
|
437
|
-
/^X'(?:[0-9a-f]{2})*'$/i.test(value)
|
|
438
|
-
);
|
|
439
|
-
}
|
|
361
|
+
].join("\n");
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function validateAddColumn(
|
|
365
|
+
resourceName: string,
|
|
366
|
+
field: DdlFieldDef,
|
|
367
|
+
provider: SqlProvider,
|
|
368
|
+
): void {
|
|
369
|
+
if (provider !== "sqlite") return;
|
|
370
|
+
|
|
371
|
+
if (field.primary) {
|
|
372
|
+
throw new Error(
|
|
373
|
+
`SQLite cannot add PRIMARY KEY column "${field.name}" to existing table "${resourceName}" via ALTER TABLE. ` +
|
|
374
|
+
`Create a manual table-rebuild migration instead.`,
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (field.unique) {
|
|
379
|
+
throw new Error(
|
|
380
|
+
`SQLite cannot add UNIQUE column "${field.name}" to existing table "${resourceName}" via ALTER TABLE. ` +
|
|
381
|
+
`Add a nullable/non-unique column first, backfill it, then create a unique index manually.`,
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const defaultIssue = sqliteAddColumnDefaultIssue(field);
|
|
386
|
+
if (defaultIssue) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
`SQLite cannot add column "${field.name}" to existing table "${resourceName}" with this DEFAULT: ` +
|
|
389
|
+
`${defaultIssue} Use a scalar literal default or write a manual backfill migration.`,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (field.nullable) return;
|
|
394
|
+
if (field.default !== undefined && !isSqliteNullDefault(field.default)) return;
|
|
395
|
+
|
|
396
|
+
throw new Error(
|
|
397
|
+
`SQLite cannot add required column "${field.name}" to existing table "${resourceName}" without a non-NULL constant DEFAULT. ` +
|
|
398
|
+
`Add a scalar default, set required:false, or write a manual backfill migration.`,
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function sqliteAddColumnDefaultIssue(field: DdlFieldDef): string | null {
|
|
403
|
+
const def = field.default;
|
|
404
|
+
if (!def) return null;
|
|
405
|
+
if (def.kind === "now") {
|
|
406
|
+
return `default "now" maps to CURRENT_TIMESTAMP, which SQLite rejects in ADD COLUMN.`;
|
|
407
|
+
}
|
|
408
|
+
if (def.kind !== "sql") return null;
|
|
409
|
+
|
|
410
|
+
const expr = def.expr.trim();
|
|
411
|
+
if (/^CURRENT_(?:TIME|DATE|TIMESTAMP)\b/i.test(expr)) {
|
|
412
|
+
return `SQLite rejects CURRENT_TIME/CURRENT_DATE/CURRENT_TIMESTAMP in ADD COLUMN.`;
|
|
413
|
+
}
|
|
414
|
+
if (/\b[A-Za-z_][A-Za-z0-9_]*\s*\(/.test(expr)) {
|
|
415
|
+
return `SQLite rejects non-constant function defaults in ADD COLUMN.`;
|
|
416
|
+
}
|
|
417
|
+
if (!isSqliteAddColumnConstantSqlDefault(expr)) {
|
|
418
|
+
return `SQLite ADD COLUMN only accepts literal constant defaults; raw SQL expression ${JSON.stringify(expr)} is not safe to emit automatically.`;
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function isSqliteNullDefault(def: NonNullable<DdlFieldDef["default"]>): boolean {
|
|
424
|
+
return def.kind === "null" || (def.kind === "sql" && /^NULL$/i.test(def.expr.trim()));
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function isSqliteAddColumnConstantSqlDefault(expr: string): boolean {
|
|
428
|
+
let value = expr.trim();
|
|
429
|
+
while (value.startsWith("(") && value.endsWith(")")) {
|
|
430
|
+
value = value.slice(1, -1).trim();
|
|
431
|
+
}
|
|
432
|
+
return (
|
|
433
|
+
/^NULL$/i.test(value) ||
|
|
434
|
+
/^(?:TRUE|FALSE)$/i.test(value) ||
|
|
435
|
+
/^[+-]?(?:\d+|\d+\.\d+|\.\d+)(?:e[+-]?\d+)?$/i.test(value) ||
|
|
436
|
+
/^'(?:''|[^'])*'$/.test(value) ||
|
|
437
|
+
/^X'(?:[0-9a-f]{2})*'$/i.test(value)
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
440
|
|
|
441
441
|
/**
|
|
442
442
|
* DROP COLUMN.
|
|
@@ -462,8 +462,8 @@ function emitDropColumn(
|
|
|
462
462
|
*
|
|
463
463
|
* Output: a multi-line SQL comment block naming the resource + field +
|
|
464
464
|
* fromType → toType, followed by the literal TODO message and a no-op
|
|
465
|
-
* a deliberate failing sentinel so the migration runner refuses to mark
|
|
466
|
-
* this TODO as applied until the operator edits the migration manually.
|
|
465
|
+
* a deliberate failing sentinel so the migration runner refuses to mark
|
|
466
|
+
* this TODO as applied until the operator edits the migration manually.
|
|
467
467
|
*/
|
|
468
468
|
function emitAlterColumnTypeStub(
|
|
469
469
|
resourceName: string,
|
|
@@ -477,13 +477,13 @@ function emitAlterColumnTypeStub(
|
|
|
477
477
|
`-- from: ${fromType}`,
|
|
478
478
|
`-- to: ${toType}`,
|
|
479
479
|
`-- TODO: Mandu does not auto-generate ALTER COLUMN TYPE in v1.`,
|
|
480
|
-
`-- Please write the migration manually, then re-run \`mandu db apply\`.`,
|
|
481
|
-
`-- ================================================================`,
|
|
482
|
-
manualMigrationRequiredStatement(
|
|
483
|
-
`Mandu cannot auto-generate ALTER COLUMN TYPE for ${resourceName}.${fieldName}`,
|
|
484
|
-
),
|
|
485
|
-
].join("\n");
|
|
486
|
-
}
|
|
480
|
+
`-- Please write the migration manually, then re-run \`mandu db apply\`.`,
|
|
481
|
+
`-- ================================================================`,
|
|
482
|
+
manualMigrationRequiredStatement(
|
|
483
|
+
`Mandu cannot auto-generate ALTER COLUMN TYPE for ${resourceName}.${fieldName}`,
|
|
484
|
+
),
|
|
485
|
+
].join("\n");
|
|
486
|
+
}
|
|
487
487
|
|
|
488
488
|
function emitAlterColumnNullable(
|
|
489
489
|
resourceName: string,
|
|
@@ -500,34 +500,34 @@ function emitAlterColumnNullable(
|
|
|
500
500
|
: `ALTER TABLE ${table} ALTER COLUMN ${col} SET NOT NULL;`;
|
|
501
501
|
}
|
|
502
502
|
if (provider === "sqlite") {
|
|
503
|
-
// SQLite cannot toggle NOT NULL on an existing column without a full
|
|
504
|
-
// table recreate. Emit a failing stub so the user handles it manually.
|
|
505
|
-
return [
|
|
506
|
-
`-- ================================================================`,
|
|
507
|
-
`-- Nullability change: ${resourceName}.${fieldName} → ${nullable ? "NULL" : "NOT NULL"}`,
|
|
508
|
-
`-- TODO: SQLite cannot toggle NOT NULL in place. Recreate the table`,
|
|
509
|
-
`-- manually (CREATE new, INSERT SELECT, DROP old, RENAME) and re-run.`,
|
|
510
|
-
`-- ================================================================`,
|
|
511
|
-
manualMigrationRequiredStatement(
|
|
512
|
-
`SQLite nullability change requires manual table rebuild for ${resourceName}.${fieldName}`,
|
|
513
|
-
),
|
|
514
|
-
].join("\n");
|
|
515
|
-
}
|
|
503
|
+
// SQLite cannot toggle NOT NULL on an existing column without a full
|
|
504
|
+
// table recreate. Emit a failing stub so the user handles it manually.
|
|
505
|
+
return [
|
|
506
|
+
`-- ================================================================`,
|
|
507
|
+
`-- Nullability change: ${resourceName}.${fieldName} → ${nullable ? "NULL" : "NOT NULL"}`,
|
|
508
|
+
`-- TODO: SQLite cannot toggle NOT NULL in place. Recreate the table`,
|
|
509
|
+
`-- manually (CREATE new, INSERT SELECT, DROP old, RENAME) and re-run.`,
|
|
510
|
+
`-- ================================================================`,
|
|
511
|
+
manualMigrationRequiredStatement(
|
|
512
|
+
`SQLite nullability change requires manual table rebuild for ${resourceName}.${fieldName}`,
|
|
513
|
+
),
|
|
514
|
+
].join("\n");
|
|
515
|
+
}
|
|
516
516
|
// MySQL requires the full column spec; we cannot reconstruct it here.
|
|
517
517
|
// Emit a stub — Agent B's diff emits `alter-column-nullable` only when
|
|
518
518
|
// everything else matches, so this is narrow-scope.
|
|
519
519
|
return [
|
|
520
520
|
`-- ================================================================`,
|
|
521
521
|
`-- Nullability change: ${resourceName}.${fieldName} → ${nullable ? "NULL" : "NOT NULL"}`,
|
|
522
|
-
`-- TODO: MySQL MODIFY COLUMN requires the full column type; Mandu v1`,
|
|
523
|
-
`-- cannot emit this automatically. Please edit this migration to use`,
|
|
524
|
-
`-- \`ALTER TABLE ${resourceName} MODIFY COLUMN ${fieldName} <TYPE> ${nullable ? "NULL" : "NOT NULL"}\``,
|
|
525
|
-
`-- ================================================================`,
|
|
526
|
-
manualMigrationRequiredStatement(
|
|
527
|
-
`MySQL nullability change requires manual MODIFY COLUMN for ${resourceName}.${fieldName}`,
|
|
528
|
-
),
|
|
529
|
-
].join("\n");
|
|
530
|
-
}
|
|
522
|
+
`-- TODO: MySQL MODIFY COLUMN requires the full column type; Mandu v1`,
|
|
523
|
+
`-- cannot emit this automatically. Please edit this migration to use`,
|
|
524
|
+
`-- \`ALTER TABLE ${resourceName} MODIFY COLUMN ${fieldName} <TYPE> ${nullable ? "NULL" : "NOT NULL"}\``,
|
|
525
|
+
`-- ================================================================`,
|
|
526
|
+
manualMigrationRequiredStatement(
|
|
527
|
+
`MySQL nullability change requires manual MODIFY COLUMN for ${resourceName}.${fieldName}`,
|
|
528
|
+
),
|
|
529
|
+
].join("\n");
|
|
530
|
+
}
|
|
531
531
|
|
|
532
532
|
function emitAlterColumnDefault(
|
|
533
533
|
resourceName: string,
|
|
@@ -543,17 +543,17 @@ function emitAlterColumnDefault(
|
|
|
543
543
|
: `ALTER TABLE ${table} ALTER COLUMN ${col} DROP DEFAULT;`;
|
|
544
544
|
}
|
|
545
545
|
if (provider === "sqlite") {
|
|
546
|
-
// Same constraint as nullability — SQLite needs a table recreate.
|
|
547
|
-
return [
|
|
548
|
-
`-- ================================================================`,
|
|
549
|
-
`-- Default change: ${resourceName}.${fieldName}`,
|
|
550
|
-
`-- TODO: SQLite cannot ALTER DEFAULT in place. Recreate the table.`,
|
|
551
|
-
`-- ================================================================`,
|
|
552
|
-
manualMigrationRequiredStatement(
|
|
553
|
-
`SQLite default change requires manual table rebuild for ${resourceName}.${fieldName}`,
|
|
554
|
-
),
|
|
555
|
-
].join("\n");
|
|
556
|
-
}
|
|
546
|
+
// Same constraint as nullability — SQLite needs a table recreate.
|
|
547
|
+
return [
|
|
548
|
+
`-- ================================================================`,
|
|
549
|
+
`-- Default change: ${resourceName}.${fieldName}`,
|
|
550
|
+
`-- TODO: SQLite cannot ALTER DEFAULT in place. Recreate the table.`,
|
|
551
|
+
`-- ================================================================`,
|
|
552
|
+
manualMigrationRequiredStatement(
|
|
553
|
+
`SQLite default change requires manual table rebuild for ${resourceName}.${fieldName}`,
|
|
554
|
+
),
|
|
555
|
+
].join("\n");
|
|
556
|
+
}
|
|
557
557
|
// MySQL — ALTER COLUMN ... SET DEFAULT / DROP DEFAULT is actually supported.
|
|
558
558
|
return def
|
|
559
559
|
? `ALTER TABLE ${table} ALTER COLUMN ${col} SET DEFAULT ${resolveDefault(def, provider)};`
|
|
@@ -597,7 +597,7 @@ function emitRenameTable(
|
|
|
597
597
|
return `ALTER TABLE ${from} RENAME TO ${to};`;
|
|
598
598
|
}
|
|
599
599
|
|
|
600
|
-
function emitRenameColumn(
|
|
600
|
+
function emitRenameColumn(
|
|
601
601
|
resourceName: string,
|
|
602
602
|
oldName: string,
|
|
603
603
|
newName: string,
|
|
@@ -609,15 +609,15 @@ function emitRenameColumn(
|
|
|
609
609
|
// All three dialects use `ALTER TABLE ... RENAME COLUMN ... TO ...` in
|
|
610
610
|
// their modern versions (PG >=9.2, MySQL >=8.0.3, SQLite >=3.25).
|
|
611
611
|
return `ALTER TABLE ${table} RENAME COLUMN ${from} TO ${to};`;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
function manualMigrationRequiredStatement(message: string): string {
|
|
615
|
-
return `SELECT mandu_manual_migration_required(${sqlStringLiteral(message)});`;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
function sqlStringLiteral(value: string): string {
|
|
619
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
620
|
-
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
function manualMigrationRequiredStatement(message: string): string {
|
|
615
|
+
return `SELECT mandu_manual_migration_required(${sqlStringLiteral(message)});`;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function sqlStringLiteral(value: string): string {
|
|
619
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
620
|
+
}
|
|
621
621
|
|
|
622
622
|
// =====================================================================
|
|
623
623
|
// Validation helpers.
|