sonamu 0.10.12 → 0.10.13
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/dist/ai/agents/agent.d.ts +1 -1
- package/dist/ai/agents/agent.d.ts.map +1 -1
- package/dist/ai/agents/agent.js +5 -6
- package/dist/ai/agents/types.d.ts +1 -1
- package/dist/ai/agents/types.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/api.js +18 -18
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/error.js +17 -15
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/model.js +3 -2
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/options.js +16 -16
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/provider.js +9 -9
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/utils.js +1 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +17 -17
- package/dist/api/code-converters.d.ts +4 -2
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +100 -19
- package/dist/api/config.d.ts +16 -1
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +28 -21
- package/dist/api/context.d.ts +2 -2
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +18 -11
- package/dist/api/http-validator.d.ts +36 -0
- package/dist/api/http-validator.d.ts.map +1 -0
- package/dist/api/http-validator.js +72 -0
- package/dist/api/index.js +6 -4
- package/dist/api/sonamu.d.ts +59 -20
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +250 -106
- package/dist/api/websocket-helpers.d.ts +7 -5
- package/dist/api/websocket-helpers.d.ts.map +1 -1
- package/dist/api/websocket-helpers.js +6 -6
- package/dist/auth/audit-log/builders.d.ts.map +1 -1
- package/dist/auth/audit-log/builders.js +1 -1
- package/dist/auth/audit-log/client-ip.d.ts +1 -1
- package/dist/auth/audit-log/client-ip.d.ts.map +1 -1
- package/dist/auth/audit-log/client-ip.js +4 -2
- package/dist/auth/audit-log/events.d.ts +5 -1
- package/dist/auth/audit-log/events.d.ts.map +1 -1
- package/dist/auth/audit-log/events.js +1 -1
- package/dist/auth/audit-log/plugin.d.ts +0 -8
- package/dist/auth/audit-log/plugin.d.ts.map +1 -1
- package/dist/auth/audit-log/plugin.js +48 -52
- package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
- package/dist/auth/audit-log-ingestor.js +16 -12
- package/dist/auth/auth-generator.d.ts.map +1 -1
- package/dist/auth/auth-generator.js +1 -1
- package/dist/auth/better-auth-request.d.ts.map +1 -1
- package/dist/auth/better-auth-request.js +6 -5
- package/dist/auth/knex-adapter.js +1 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts +13 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/index.js +1 -1
- package/dist/auth/plugins/wrappers/admin.d.ts +1 -1
- package/dist/bin/build-config.d.ts +25 -0
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +105 -2
- package/dist/bin/cli.js +131 -27
- package/dist/bin/compiler-policy.d.ts +3 -0
- package/dist/bin/compiler-policy.d.ts.map +1 -0
- package/dist/bin/compiler-policy.js +24 -0
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +5 -3
- package/dist/bin/test-command.d.ts +22 -1
- package/dist/bin/test-command.d.ts.map +1 -1
- package/dist/bin/test-command.js +18 -10
- package/dist/bin/ts-loader-registration.d.ts +7 -1
- package/dist/bin/ts-loader-registration.d.ts.map +1 -1
- package/dist/bin/ts-loader-registration.js +13 -4
- package/dist/cache/decorator.d.ts.map +1 -1
- package/dist/cache/decorator.js +11 -4
- package/dist/compress/compress.d.ts.map +1 -1
- package/dist/compress/compress.js +1 -1
- package/dist/cone/cone-generator.d.ts +14 -1
- package/dist/cone/cone-generator.d.ts.map +1 -1
- package/dist/cone/cone-generator.js +13 -9
- package/dist/database/_batch_update.js +1 -1
- package/dist/database/base-model.d.ts +22 -10
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +26 -16
- package/dist/database/base-model.types.d.ts +15 -3
- package/dist/database/base-model.types.d.ts.map +1 -1
- package/dist/database/db.d.ts +12 -2
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +10 -7
- package/dist/database/knex.d.ts.map +1 -1
- package/dist/database/knex.js +17 -14
- package/dist/database/puri.d.ts +11 -9
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +93 -79
- package/dist/database/puri.types.d.ts +21 -21
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +1 -1
- package/dist/database/upsert-builder.d.ts +12 -10
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +20 -12
- package/dist/dict/sd.d.ts.map +1 -1
- package/dist/dict/sd.js +1 -1
- package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
- package/dist/dict/sonamu-dictionary.js +1 -1
- package/dist/dict/utils.d.ts.map +1 -1
- package/dist/dict/utils.js +7 -2
- package/dist/entity/entity-manager.d.ts +13 -4
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +19 -11
- package/dist/entity/entity-template-cone.d.ts +73 -5
- package/dist/entity/entity-template-cone.d.ts.map +1 -1
- package/dist/entity/entity-template-cone.js +4 -2
- package/dist/entity/entity.d.ts +6 -2
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +30 -28
- package/dist/env.d.ts +3 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +7 -2
- package/dist/exceptions/so-exceptions.d.ts +24 -20
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +4 -2
- package/dist/filter/utils.d.ts +7 -2
- package/dist/filter/utils.d.ts.map +1 -1
- package/dist/filter/utils.js +8 -6
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -6
- package/dist/logger/configure.d.ts.map +1 -1
- package/dist/logger/configure.js +10 -10
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +50 -46
- package/dist/migration/index-where-predicate.d.ts.map +1 -1
- package/dist/migration/index-where-predicate.js +22 -8
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +1 -1
- package/dist/migration/migrator.d.ts +3 -2
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +27 -21
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/postgresql-schema-reader.js +51 -36
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/migration/slack-confirm.js +1 -1
- package/dist/naite/naite-reporter.js +2 -2
- package/dist/naite/naite.d.ts +74 -15
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +5 -19
- package/dist/runtime-type.d.ts +6 -0
- package/dist/runtime-type.d.ts.map +1 -0
- package/dist/runtime-type.js +26 -0
- package/dist/ssr/hmr-opt-out.d.ts +26 -0
- package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
- package/dist/ssr/hmr-opt-out.js +59 -0
- package/dist/ssr/renderer.d.ts.map +1 -1
- package/dist/ssr/renderer.js +4 -1
- package/dist/storage/base-file.js +14 -14
- package/dist/storage/buffered-file.d.ts +2 -2
- package/dist/storage/buffered-file.d.ts.map +1 -1
- package/dist/storage/buffered-file.js +12 -12
- package/dist/storage/s3-driver.d.ts.map +1 -1
- package/dist/storage/s3-driver.js +1 -1
- package/dist/storage/uploaded-file.d.ts +2 -2
- package/dist/storage/uploaded-file.d.ts.map +1 -1
- package/dist/storage/uploaded-file.js +8 -8
- package/dist/stream/sse.js +11 -11
- package/dist/stream/ws-core.d.ts +1 -1
- package/dist/stream/ws-core.d.ts.map +1 -1
- package/dist/stream/ws-delivery.d.ts +1 -1
- package/dist/stream/ws-delivery.d.ts.map +1 -1
- package/dist/stream/ws-delivery.js +6 -4
- package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
- package/dist/stream/ws-local-connection-store.js +4 -2
- package/dist/stream/ws-presence-store.js +1 -1
- package/dist/stream/ws-registry.d.ts +4 -4
- package/dist/stream/ws-registry.d.ts.map +1 -1
- package/dist/stream/ws-registry.js +4 -2
- package/dist/stream/ws-telemetry.d.ts +16 -12
- package/dist/stream/ws-telemetry.d.ts.map +1 -1
- package/dist/stream/ws-telemetry.js +22 -18
- package/dist/stream/ws.d.ts +18 -12
- package/dist/stream/ws.d.ts.map +1 -1
- package/dist/stream/ws.js +26 -22
- package/dist/syncer/api-parser.js +1 -1
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +7 -8
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +13 -14
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +5 -6
- package/dist/syncer/file-copy.d.ts +5 -0
- package/dist/syncer/file-copy.d.ts.map +1 -0
- package/dist/syncer/file-copy.js +36 -0
- package/dist/syncer/file-patterns.d.ts +1 -0
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +5 -2
- package/dist/syncer/file-tracking.d.ts.map +1 -1
- package/dist/syncer/file-tracking.js +5 -4
- package/dist/syncer/filesystem-dependencies.d.ts +15 -0
- package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
- package/dist/syncer/filesystem-dependencies.js +53 -0
- package/dist/syncer/module-loader.d.ts +1 -1
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +6 -4
- package/dist/syncer/syncer-actions.d.ts +4 -0
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +34 -17
- package/dist/syncer/syncer.d.ts +17 -6
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +71 -29
- package/dist/syncer/watcher.d.ts.map +1 -1
- package/dist/syncer/watcher.js +3 -3
- package/dist/tasks/decorator.d.ts +6 -6
- package/dist/tasks/decorator.d.ts.map +1 -1
- package/dist/tasks/decorator.js +4 -4
- package/dist/tasks/step-wrapper.d.ts +6 -4
- package/dist/tasks/step-wrapper.d.ts.map +1 -1
- package/dist/tasks/step-wrapper.js +5 -5
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +13 -7
- package/dist/template/entity-converter.d.ts +1 -1
- package/dist/template/entity-converter.d.ts.map +1 -1
- package/dist/template/entity-converter.js +2 -2
- package/dist/template/helpers.d.ts +8 -6
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +1 -1
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +4 -4
- package/dist/template/implementations/generated_http.template.d.ts +7 -4
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +21 -21
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +6 -3
- package/dist/template/implementations/http_validators.template.d.ts +18 -0
- package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
- package/dist/template/implementations/http_validators.template.js +127 -0
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +1 -1
- package/dist/template/implementations/queries.template.js +1 -1
- package/dist/template/implementations/sd.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.js +79 -39
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +6 -4
- package/dist/template/implementations/view_form.template.d.ts +6 -1
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +23 -15
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +11 -6
- package/dist/template/template-manager.d.ts.map +1 -1
- package/dist/template/template-manager.js +9 -7
- package/dist/template/template-types.d.ts +12 -5
- package/dist/template/template-types.d.ts.map +1 -1
- package/dist/template/template-types.js +1 -1
- package/dist/template/template.d.ts +2 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +6 -4
- package/dist/template/zod-converter.d.ts +0 -19
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +100 -84
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +2 -1
- package/dist/testing/bootstrap.d.ts.map +1 -1
- package/dist/testing/bootstrap.js +9 -6
- package/dist/testing/data-explorer.d.ts +32 -7
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/data-explorer.js +77 -31
- package/dist/testing/dev-test-routes.d.ts +8 -1
- package/dist/testing/dev-test-routes.d.ts.map +1 -1
- package/dist/testing/dev-test-routes.js +125 -108
- package/dist/testing/dev-vitest-manager.d.ts +54 -8
- package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
- package/dist/testing/dev-vitest-manager.js +24 -9
- package/dist/testing/faker-mappings.d.ts +412 -1
- package/dist/testing/faker-mappings.d.ts.map +1 -1
- package/dist/testing/faker-mappings.js +1 -1
- package/dist/testing/filesystem.d.ts +2 -0
- package/dist/testing/filesystem.d.ts.map +1 -0
- package/dist/testing/filesystem.js +7 -0
- package/dist/testing/fixture-generator.d.ts +25 -8
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +132 -73
- package/dist/testing/fixture-loader.d.ts +3 -1
- package/dist/testing/fixture-loader.d.ts.map +1 -1
- package/dist/testing/fixture-loader.js +1 -20
- package/dist/testing/fixture-manager.d.ts +8 -7
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +91 -59
- package/dist/testing/global-setup.d.ts.map +1 -1
- package/dist/testing/global-setup.js +5 -2
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +6 -3
- package/dist/types/types.d.ts +101 -99
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +234 -225
- package/dist/ui/ai-api.d.ts.map +1 -1
- package/dist/ui/ai-api.js +1 -1
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/ui/ai-client.js +28 -18
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +135 -128
- package/dist/ui/async-route.d.ts +3 -0
- package/dist/ui/async-route.d.ts.map +1 -0
- package/dist/ui/async-route.js +12 -0
- package/dist/ui/cdd-service.d.ts +9 -7
- package/dist/ui/cdd-service.d.ts.map +1 -1
- package/dist/ui/cdd-service.js +7 -5
- package/dist/ui/migrations-api.d.ts.map +1 -1
- package/dist/ui/migrations-api.js +17 -15
- package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
- package/dist/ui-web/index.html +1 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +7 -5
- package/dist/utils/fs-utils.d.ts +3 -3
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +6 -6
- package/dist/utils/model.d.ts +3 -5
- package/dist/utils/model.d.ts.map +1 -1
- package/dist/utils/model.js +1 -1
- package/dist/utils/object-utils.d.ts +1 -1
- package/dist/utils/object-utils.d.ts.map +1 -1
- package/dist/utils/object-utils.js +17 -16
- package/dist/utils/process-utils.d.ts.map +1 -1
- package/dist/utils/process-utils.js +4 -2
- package/dist/utils/runtime-value.d.ts +13 -0
- package/dist/utils/runtime-value.d.ts.map +1 -0
- package/dist/utils/runtime-value.js +40 -0
- package/dist/utils/sql-parser.d.ts +8 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +6 -3
- package/dist/utils/type-utils.d.ts.map +1 -1
- package/dist/utils/type-utils.js +10 -8
- package/dist/utils/utils.d.ts +2 -2
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +11 -8
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +7 -4
- package/dist/vector/chunking.d.ts.map +1 -1
- package/dist/vector/chunking.js +1 -1
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +1 -1
- package/dist/vector/types.d.ts +3 -2
- package/dist/vector/types.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/ai/agents/agent.ts +5 -5
- package/src/ai/agents/types.ts +1 -1
- package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
- package/src/ai/providers/rtzr/error.ts +5 -3
- package/src/ai/providers/rtzr/model.ts +3 -2
- package/src/ai/providers/rtzr/options.ts +10 -5
- package/src/ai/providers/rtzr/provider.ts +10 -10
- package/src/ai/providers/rtzr/utils.ts +3 -1
- package/src/api/__tests__/config.test.ts +11 -21
- package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
- package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
- package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
- package/src/api/caster.ts +6 -8
- package/src/api/code-converters.ts +136 -36
- package/src/api/config.ts +62 -4
- package/src/api/context.ts +3 -3
- package/src/api/decorators.ts +28 -17
- package/src/api/http-validator.ts +149 -0
- package/src/api/sonamu.ts +459 -152
- package/src/api/websocket-helpers.ts +24 -17
- package/src/auth/audit-log/builders.ts +3 -2
- package/src/auth/audit-log/client-ip.ts +4 -2
- package/src/auth/audit-log/events.ts +15 -1
- package/src/auth/audit-log/plugin.ts +129 -200
- package/src/auth/audit-log-ingestor.ts +19 -15
- package/src/auth/auth-generator.ts +10 -5
- package/src/auth/better-auth-request.ts +4 -3
- package/src/auth/knex-adapter.ts +8 -2
- package/src/auth/plugins/entity-definitions/index.ts +6 -5
- package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
- package/src/bin/__tests__/test-command.test.ts +9 -15
- package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
- package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
- package/src/bin/build-config.ts +167 -0
- package/src/bin/cli.ts +153 -36
- package/src/bin/compiler-policy.ts +35 -0
- package/src/bin/fixture.ts +14 -3
- package/src/bin/test-command.ts +74 -29
- package/src/bin/ts-loader-registration.ts +22 -4
- package/src/cache/decorator.ts +10 -3
- package/src/compress/compress.ts +17 -4
- package/src/cone/cone-generator.ts +34 -6
- package/src/database/__tests__/db.test.ts +1 -0
- package/src/database/__tests__/puri.test.ts +16 -15
- package/src/database/__tests__/transaction-scope.test.ts +5 -0
- package/src/database/_batch_update.ts +1 -0
- package/src/database/base-model.ts +81 -50
- package/src/database/base-model.types.ts +6 -6
- package/src/database/db.ts +29 -19
- package/src/database/knex.ts +30 -17
- package/src/database/puri-subset.test-d.ts +17 -0
- package/src/database/puri.ts +181 -143
- package/src/database/puri.types.test-d.ts +31 -1
- package/src/database/puri.types.ts +23 -21
- package/src/database/upsert-builder.ts +75 -53
- package/src/dict/sd.ts +15 -5
- package/src/dict/sonamu-dictionary.ts +6 -6
- package/src/dict/utils.ts +9 -1
- package/src/entity/entity-manager.ts +26 -9
- package/src/entity/entity-template-cone.ts +5 -10
- package/src/entity/entity.ts +50 -34
- package/src/env.ts +7 -3
- package/src/exceptions/error-handler.ts +17 -2
- package/src/exceptions/so-exceptions.ts +26 -20
- package/src/filter/utils.ts +21 -11
- package/src/index.ts +3 -0
- package/src/logger/configure.ts +26 -18
- package/src/migration/__tests__/migrator.test.ts +50 -57
- package/src/migration/code-generation.ts +132 -104
- package/src/migration/index-where-predicate.ts +51 -24
- package/src/migration/migration-set.ts +11 -5
- package/src/migration/migrator.ts +68 -41
- package/src/migration/postgresql-schema-reader.ts +52 -47
- package/src/migration/slack-confirm.ts +17 -15
- package/src/naite/naite-reporter.ts +1 -1
- package/src/naite/naite.ts +97 -24
- package/src/runtime-type.ts +34 -0
- package/src/ssr/hmr-opt-out.ts +78 -0
- package/src/ssr/renderer.ts +6 -0
- package/src/storage/base-file.ts +13 -13
- package/src/storage/buffered-file.ts +11 -11
- package/src/storage/s3-driver.ts +4 -1
- package/src/storage/uploaded-file.ts +8 -8
- package/src/stream/__tests__/ws-contracts.test.ts +4 -2
- package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
- package/src/stream/__tests__/ws.test.ts +30 -6
- package/src/stream/sse.ts +12 -11
- package/src/stream/ws-core.ts +1 -1
- package/src/stream/ws-delivery.ts +16 -7
- package/src/stream/ws-local-connection-store.ts +2 -3
- package/src/stream/ws-presence-store.ts +6 -1
- package/src/stream/ws-registry.ts +16 -7
- package/src/stream/ws-telemetry.ts +66 -43
- package/src/stream/ws.ts +73 -39
- package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
- package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
- package/src/syncer/api-parser.ts +67 -27
- package/src/syncer/checksum.ts +17 -11
- package/src/syncer/code-generator.ts +25 -17
- package/src/syncer/entity-operations.ts +3 -5
- package/src/syncer/file-copy.ts +46 -0
- package/src/syncer/file-patterns.ts +11 -8
- package/src/syncer/file-tracking.ts +3 -4
- package/src/syncer/filesystem-dependencies.ts +73 -0
- package/src/syncer/module-loader.ts +8 -4
- package/src/syncer/syncer-actions.ts +56 -18
- package/src/syncer/syncer.ts +116 -43
- package/src/syncer/watcher.ts +8 -4
- package/src/tasks/decorator.ts +20 -12
- package/src/tasks/step-wrapper.ts +19 -9
- package/src/tasks/workflow-manager.ts +15 -9
- package/src/template/__tests__/http_validators.template.test.ts +160 -0
- package/src/template/__tests__/services.template.mutation.test.ts +24 -23
- package/src/template/__tests__/services.template.websocket.test.ts +21 -25
- package/src/template/entity-converter.ts +5 -2
- package/src/template/helpers.ts +8 -9
- package/src/template/implementations/generated.template.ts +5 -4
- package/src/template/implementations/generated_http.template.ts +61 -15
- package/src/template/implementations/generated_sso.template.ts +15 -4
- package/src/template/implementations/http_validators.template.ts +175 -0
- package/src/template/implementations/model.template.ts +3 -1
- package/src/template/implementations/sd.template.ts +81 -41
- package/src/template/implementations/services.template.ts +2 -2
- package/src/template/implementations/view_form.template.ts +56 -39
- package/src/template/implementations/view_list.template.ts +31 -23
- package/src/template/template-manager.ts +15 -13
- package/src/template/template-types.ts +13 -5
- package/src/template/template.ts +4 -3
- package/src/template/zod-converter.ts +206 -91
- package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
- package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
- package/src/testing/_relation-graph.ts +4 -1
- package/src/testing/bootstrap.ts +12 -5
- package/src/testing/data-explorer.ts +102 -53
- package/src/testing/dev-test-routes.ts +87 -50
- package/src/testing/dev-vitest-manager.ts +88 -32
- package/src/testing/faker-mappings.ts +2 -2
- package/src/testing/filesystem.ts +1 -0
- package/src/testing/fixture-generator.ts +191 -131
- package/src/testing/fixture-loader.ts +5 -1
- package/src/testing/fixture-manager.ts +129 -90
- package/src/testing/global-setup.ts +7 -3
- package/src/testing/index.ts +5 -0
- package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
- package/src/types/types.ts +184 -158
- package/src/ui/ai-api.ts +9 -7
- package/src/ui/ai-client.ts +61 -56
- package/src/ui/api.ts +727 -616
- package/src/ui/async-route.ts +4 -0
- package/src/ui/cdd-service.ts +35 -12
- package/src/ui/migrations-api.ts +63 -51
- package/src/utils/formatter.ts +7 -3
- package/src/utils/fs-utils.ts +5 -5
- package/src/utils/model.ts +4 -5
- package/src/utils/object-utils.ts +32 -22
- package/src/utils/process-utils.ts +4 -1
- package/src/utils/runtime-value.ts +43 -0
- package/src/utils/sql-parser.ts +13 -6
- package/src/utils/type-utils.ts +9 -7
- package/src/utils/utils.ts +19 -21
- package/src/utils/zod-error.ts +4 -2
- package/src/vector/chunking.ts +6 -1
- package/src/vector/embedding.ts +2 -1
- package/src/vector/types.ts +4 -2
- package/tsdown.api.config.ts +5 -2
- package/dist/ui-web/assets/index-C0m1pk6K.js +0 -177
|
@@ -3,17 +3,29 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
3
3
|
import { type WebSocket } from "ws";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
type AnyWebSocketConnection,
|
|
8
|
+
type WebSocketConnection,
|
|
9
|
+
WebSocketRuntime,
|
|
10
|
+
} from "../../stream/ws";
|
|
7
11
|
import { type WebSocketTelemetryConnectionContext } from "../../stream/ws-telemetry";
|
|
8
|
-
import { type SonamuFastifyConfig } from "
|
|
12
|
+
import { type SonamuFastifyConfig } from "../../types/types";
|
|
9
13
|
import { type WebSocketContext } from "../context";
|
|
10
14
|
import { type ExtendedApi } from "../decorators";
|
|
11
15
|
import { Sonamu } from "../sonamu";
|
|
12
16
|
|
|
17
|
+
interface TestWebSocketMessage {
|
|
18
|
+
roomId?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface TestWebSocketEvents {
|
|
22
|
+
joinRoom: TestWebSocketMessage;
|
|
23
|
+
}
|
|
24
|
+
|
|
13
25
|
describe("Sonamu websocket context scoping", () => {
|
|
14
26
|
it("웹소켓 컨텍스트를 생성한 뒤 해당 컨텍스트 안에서 guard를 실행한다", async () => {
|
|
15
27
|
const executionOrder: string[] = [];
|
|
16
|
-
const rawWs = {
|
|
28
|
+
const rawWs: AnyWebSocketConnection = {
|
|
17
29
|
id: "ws-guard",
|
|
18
30
|
namespace: "chat",
|
|
19
31
|
transport: "ws" as const,
|
|
@@ -30,12 +42,12 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
30
42
|
leave() {},
|
|
31
43
|
setUserId() {},
|
|
32
44
|
clearUserId() {},
|
|
33
|
-
}
|
|
45
|
+
};
|
|
34
46
|
const runtime = new WebSocketRuntime({ nodeId: "websocket-guard-test" });
|
|
35
|
-
const
|
|
36
|
-
const originalSyncer = Reflect.get(Sonamu, "_syncer");
|
|
47
|
+
const originalState = Sonamu.captureTestingSnapshot();
|
|
37
48
|
let contextCreated: WebSocketContext | null = null;
|
|
38
49
|
let guardContext: WebSocketContext | null = null;
|
|
50
|
+
let guardTransport: WebSocketContext["transport"] | null = null;
|
|
39
51
|
|
|
40
52
|
vi.spyOn(runtime, "registerConnection").mockReturnValue(rawWs);
|
|
41
53
|
vi.spyOn(runtime, "activateConnection").mockImplementation(() => {
|
|
@@ -43,7 +55,7 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
43
55
|
});
|
|
44
56
|
vi.spyOn(Sonamu, "createWebSocketContext").mockImplementation(async (_config, request, ws) => {
|
|
45
57
|
executionOrder.push("context");
|
|
46
|
-
|
|
58
|
+
const context: WebSocketContext = {
|
|
47
59
|
transport: "ws",
|
|
48
60
|
request,
|
|
49
61
|
headers: request.headers,
|
|
@@ -53,16 +65,21 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
53
65
|
user: null,
|
|
54
66
|
session: null,
|
|
55
67
|
};
|
|
56
|
-
|
|
68
|
+
contextCreated = context;
|
|
69
|
+
return context;
|
|
57
70
|
});
|
|
58
71
|
vi.spyOn(Sonamu, "invokeModelMethod").mockImplementation(async () => {
|
|
59
72
|
executionOrder.push("handler");
|
|
60
73
|
});
|
|
61
74
|
|
|
62
|
-
const config = {
|
|
75
|
+
const config = /* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ {
|
|
63
76
|
guardHandler() {
|
|
64
77
|
executionOrder.push("guard");
|
|
65
78
|
guardContext = Sonamu.getContext<WebSocketContext>();
|
|
79
|
+
guardTransport = guardContext.transport;
|
|
80
|
+
},
|
|
81
|
+
contextProvider(defaultContext) {
|
|
82
|
+
return defaultContext;
|
|
66
83
|
},
|
|
67
84
|
} as SonamuFastifyConfig;
|
|
68
85
|
const api: ExtendedApi = {
|
|
@@ -78,28 +95,27 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
78
95
|
parameters: [],
|
|
79
96
|
returnType: "void",
|
|
80
97
|
};
|
|
81
|
-
const request = {
|
|
98
|
+
const request = /* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ {
|
|
82
99
|
headers: {},
|
|
83
100
|
query: {},
|
|
84
101
|
} as FastifyRequest;
|
|
85
|
-
const createWebSocketHandler: (
|
|
86
|
-
api: ExtendedApi,
|
|
87
|
-
config: SonamuFastifyConfig,
|
|
88
|
-
) => (connection: { socket: WebSocket }, request: FastifyRequest) => Promise<void> =
|
|
89
|
-
Reflect.get(Sonamu, "createWebSocketHandler");
|
|
90
|
-
|
|
91
102
|
try {
|
|
92
103
|
Sonamu.websocketRuntime = runtime;
|
|
93
|
-
Reflect.set(Sonamu, "
|
|
104
|
+
Reflect.set(Sonamu, "syncerValue", { types: {} });
|
|
94
105
|
|
|
95
|
-
await
|
|
106
|
+
await Sonamu.createWebSocketHandlerForTesting(api, config)(
|
|
107
|
+
{
|
|
108
|
+
socket:
|
|
109
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ {} as WebSocket,
|
|
110
|
+
},
|
|
111
|
+
request,
|
|
112
|
+
);
|
|
96
113
|
|
|
97
114
|
expect(executionOrder).toEqual(["context", "guard", "activate", "handler"]);
|
|
98
115
|
expect(guardContext).toBe(contextCreated);
|
|
99
|
-
expect(
|
|
116
|
+
expect(guardTransport).toBe("ws");
|
|
100
117
|
} finally {
|
|
101
|
-
|
|
102
|
-
Reflect.set(Sonamu, "_syncer", originalSyncer);
|
|
118
|
+
Sonamu.restoreTestingSnapshot(originalState);
|
|
103
119
|
vi.restoreAllMocks();
|
|
104
120
|
}
|
|
105
121
|
});
|
|
@@ -108,12 +124,12 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
108
124
|
const messageHandlers = new Map<
|
|
109
125
|
string,
|
|
110
126
|
(
|
|
111
|
-
data:
|
|
127
|
+
data: TestWebSocketMessage,
|
|
112
128
|
telemetryContext?: WebSocketTelemetryConnectionContext,
|
|
113
129
|
) => void | Promise<void>
|
|
114
130
|
>();
|
|
115
131
|
|
|
116
|
-
const rawWs = {
|
|
132
|
+
const rawWs: WebSocketConnection<TestWebSocketEvents, TestWebSocketEvents> = {
|
|
117
133
|
id: "ws-1",
|
|
118
134
|
namespace: "chat",
|
|
119
135
|
transport: "ws" as const,
|
|
@@ -132,18 +148,15 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
132
148
|
leave() {},
|
|
133
149
|
setUserId() {},
|
|
134
150
|
clearUserId() {},
|
|
135
|
-
}
|
|
151
|
+
};
|
|
136
152
|
|
|
137
|
-
let context: WebSocketContext | null = null;
|
|
138
|
-
const
|
|
139
|
-
ws: AnyWebSocketConnection,
|
|
140
|
-
getContext: () => WebSocketContext | null,
|
|
141
|
-
) => AnyWebSocketConnection = Reflect.get(Sonamu, "createScopedWebSocketConnection");
|
|
142
|
-
const scopedWs = createScopedWebSocketConnection.call(Sonamu, rawWs, () => context);
|
|
153
|
+
let context: WebSocketContext<TestWebSocketEvents, TestWebSocketEvents> | null = null;
|
|
154
|
+
const scopedWs = Sonamu.createScopedWebSocketConnectionForTesting(rawWs, () => context);
|
|
143
155
|
|
|
144
156
|
context = {
|
|
145
157
|
transport: "ws",
|
|
146
|
-
request:
|
|
158
|
+
request:
|
|
159
|
+
/* SAFETY: 테스트는 request 속성을 읽지 않고 websocket 컨텍스트 복원만 검증합니다. */ {} as WebSocketContext["request"],
|
|
147
160
|
headers: {},
|
|
148
161
|
ws: scopedWs,
|
|
149
162
|
naiteStore: new Map(),
|
|
@@ -168,12 +181,12 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
168
181
|
const messageHandlers = new Map<
|
|
169
182
|
string,
|
|
170
183
|
(
|
|
171
|
-
data:
|
|
184
|
+
data: TestWebSocketMessage,
|
|
172
185
|
telemetryContext?: WebSocketTelemetryConnectionContext,
|
|
173
186
|
) => void | Promise<void>
|
|
174
187
|
>();
|
|
175
188
|
|
|
176
|
-
const rawWs = {
|
|
189
|
+
const rawWs: WebSocketConnection<TestWebSocketEvents, TestWebSocketEvents> = {
|
|
177
190
|
id: "ws-1",
|
|
178
191
|
namespace: "chat",
|
|
179
192
|
transport: "ws" as const,
|
|
@@ -192,18 +205,15 @@ describe("Sonamu websocket context scoping", () => {
|
|
|
192
205
|
leave() {},
|
|
193
206
|
setUserId() {},
|
|
194
207
|
clearUserId() {},
|
|
195
|
-
}
|
|
208
|
+
};
|
|
196
209
|
|
|
197
|
-
let context: WebSocketContext | null = null;
|
|
198
|
-
const
|
|
199
|
-
ws: AnyWebSocketConnection,
|
|
200
|
-
getContext: () => WebSocketContext | null,
|
|
201
|
-
) => AnyWebSocketConnection = Reflect.get(Sonamu, "createScopedWebSocketConnection");
|
|
202
|
-
const scopedWs = createScopedWebSocketConnection.call(Sonamu, rawWs, () => context);
|
|
210
|
+
let context: WebSocketContext<TestWebSocketEvents, TestWebSocketEvents> | null = null;
|
|
211
|
+
const scopedWs = Sonamu.createScopedWebSocketConnectionForTesting(rawWs, () => context);
|
|
203
212
|
|
|
204
213
|
context = {
|
|
205
214
|
transport: "ws",
|
|
206
|
-
request:
|
|
215
|
+
request:
|
|
216
|
+
/* SAFETY: 테스트는 request 속성을 읽지 않고 websocket 컨텍스트 복원만 검증합니다. */ {} as WebSocketContext["request"],
|
|
207
217
|
headers: {},
|
|
208
218
|
ws: scopedWs,
|
|
209
219
|
naiteStore: new Map(),
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
|
|
7
|
+
import { DB } from "../../database/db";
|
|
8
|
+
import { normalizeZodCompilerPolicy } from "../config";
|
|
9
|
+
import { Sonamu } from "../sonamu";
|
|
10
|
+
|
|
11
|
+
describe("zod-compiler 정책 정규화", () => {
|
|
12
|
+
it.each([undefined, false] as const)(
|
|
13
|
+
"미설정 또는 false를 opt-out 정책으로 정규화한다",
|
|
14
|
+
(policy) => {
|
|
15
|
+
expect(normalizeZodCompilerPolicy(policy, ["web", "app"])).toEqual({
|
|
16
|
+
api: false,
|
|
17
|
+
targets: {},
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
it("API JIT 정책을 target registry 없이 정규화한다", () => {
|
|
23
|
+
expect(normalizeZodCompilerPolicy({ api: "jit" }, ["web"])).toEqual({
|
|
24
|
+
api: "jit",
|
|
25
|
+
targets: {},
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("API AOT 정책을 target registry 없이 정규화한다", () => {
|
|
30
|
+
expect(normalizeZodCompilerPolicy({ api: "aot" }, ["web"])).toEqual({
|
|
31
|
+
api: "aot",
|
|
32
|
+
targets: {},
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("지원하지 않는 target opt-in을 targets 설정 경로에서 거부한다", () => {
|
|
37
|
+
expect(() =>
|
|
38
|
+
normalizeZodCompilerPolicy(
|
|
39
|
+
{
|
|
40
|
+
api: "aot",
|
|
41
|
+
targets: {
|
|
42
|
+
web: "aot",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
["web"],
|
|
46
|
+
),
|
|
47
|
+
).toThrowError(/validation\.zodCompiler\.targets/);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("zod-compiler 빌드 전용 정책 로딩", () => {
|
|
52
|
+
const tempRoots: string[] = [];
|
|
53
|
+
|
|
54
|
+
afterEach(async () => {
|
|
55
|
+
vi.restoreAllMocks();
|
|
56
|
+
vi.resetModules();
|
|
57
|
+
await Promise.all(
|
|
58
|
+
tempRoots.splice(0).map((rootPath) => rm(rootPath, { recursive: true, force: true })),
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("Sonamu와 DB를 초기화하지 않고 source config의 compiler 정책만 읽는다", async () => {
|
|
63
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-compiler-policy-test-"));
|
|
64
|
+
tempRoots.push(rootPath);
|
|
65
|
+
await mkdir(path.join(rootPath, "src"), { recursive: true });
|
|
66
|
+
await writeFile(path.join(rootPath, ".env"), "SONAMU_DB_HOST=localhost\n");
|
|
67
|
+
await writeFile(
|
|
68
|
+
path.join(rootPath, "src", "sonamu.config.ts"),
|
|
69
|
+
`
|
|
70
|
+
export default {
|
|
71
|
+
sync: { targets: ["web"] },
|
|
72
|
+
validation: {
|
|
73
|
+
zodCompiler: {
|
|
74
|
+
api: "aot",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
`,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const sonamuInit = vi.spyOn(Sonamu, "init");
|
|
82
|
+
const generateDBConfig = vi.spyOn(DB, "generateDBConfig");
|
|
83
|
+
const setDBConfig = vi.spyOn(DB, "setConfig");
|
|
84
|
+
|
|
85
|
+
const { loadBuildCompilerPolicy } = await import("../../bin/compiler-policy");
|
|
86
|
+
|
|
87
|
+
await expect(loadBuildCompilerPolicy(rootPath)).resolves.toEqual({
|
|
88
|
+
api: "aot",
|
|
89
|
+
targets: {},
|
|
90
|
+
});
|
|
91
|
+
expect(sonamuInit).not.toHaveBeenCalled();
|
|
92
|
+
expect(generateDBConfig).not.toHaveBeenCalled();
|
|
93
|
+
expect(setDBConfig).not.toHaveBeenCalled();
|
|
94
|
+
});
|
|
95
|
+
});
|
package/src/api/caster.ts
CHANGED
|
@@ -3,6 +3,8 @@ import assert from "assert";
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { type $ZodType } from "zod/v4/core";
|
|
5
5
|
|
|
6
|
+
import { isObjectValue, isStringValue } from "../utils/runtime-value";
|
|
7
|
+
|
|
6
8
|
function isNumberType(zodType: $ZodType): zodType is z.ZodNumber {
|
|
7
9
|
return zodType instanceof z.ZodNumber;
|
|
8
10
|
}
|
|
@@ -28,7 +30,7 @@ function isZodNumberAnyway(zodType: $ZodType) {
|
|
|
28
30
|
// ZodType을 이용해 raw를 Type Coercing
|
|
29
31
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- 캐스팅에는 any가 필요함.
|
|
30
32
|
export function caster(zodType: $ZodType, raw: any): any {
|
|
31
|
-
if (isZodNumberAnyway(zodType) &&
|
|
33
|
+
if (isZodNumberAnyway(zodType) && isStringValue(raw)) {
|
|
32
34
|
// number
|
|
33
35
|
return Number(raw);
|
|
34
36
|
} else if (
|
|
@@ -51,14 +53,10 @@ export function caster(zodType: $ZodType, raw: any): any {
|
|
|
51
53
|
// array
|
|
52
54
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- 캐스팅에는 any가 필요함.
|
|
53
55
|
return raw.map((elem: any) => caster(zodType.element, elem));
|
|
54
|
-
} else if (zodType instanceof z.ZodObject &&
|
|
56
|
+
} else if (zodType instanceof z.ZodObject && isObjectValue(raw) && raw !== null) {
|
|
55
57
|
// object
|
|
56
|
-
return Object.
|
|
57
|
-
(
|
|
58
|
-
r[rawKey] = caster(zodType.shape[rawKey], raw[rawKey]);
|
|
59
|
-
return r;
|
|
60
|
-
},
|
|
61
|
-
{} as Record<string, unknown>,
|
|
58
|
+
return Object.fromEntries(
|
|
59
|
+
Object.keys(raw).map((rawKey) => [rawKey, caster(zodType["shape"][rawKey], raw[rawKey])]),
|
|
62
60
|
);
|
|
63
61
|
} else if (zodType instanceof z.ZodOptional) {
|
|
64
62
|
// optional
|
|
@@ -28,6 +28,76 @@ import { type ExtendedApi } from "./decorators";
|
|
|
28
28
|
type AnyZodObject = z.ZodObject;
|
|
29
29
|
type AnyZodLiteral = z.ZodLiteral;
|
|
30
30
|
|
|
31
|
+
const ApiParamTypeSchema: z.ZodType<ApiParamType> = z.lazy(() =>
|
|
32
|
+
z.union([
|
|
33
|
+
z.enum([
|
|
34
|
+
"string",
|
|
35
|
+
"number",
|
|
36
|
+
"boolean",
|
|
37
|
+
"null",
|
|
38
|
+
"undefined",
|
|
39
|
+
"void",
|
|
40
|
+
"any",
|
|
41
|
+
"unknown",
|
|
42
|
+
"true",
|
|
43
|
+
"false",
|
|
44
|
+
]),
|
|
45
|
+
z.object({ t: z.literal("string-literal"), value: z.string() }),
|
|
46
|
+
z.object({ t: z.literal("numeric-literal"), value: z.number() }),
|
|
47
|
+
z.object({
|
|
48
|
+
t: z.literal("object"),
|
|
49
|
+
props: z.array(
|
|
50
|
+
z.object({
|
|
51
|
+
name: z.string(),
|
|
52
|
+
type: ApiParamTypeSchema,
|
|
53
|
+
optional: z.boolean(),
|
|
54
|
+
defaultDef: z.string().optional(),
|
|
55
|
+
}),
|
|
56
|
+
),
|
|
57
|
+
}),
|
|
58
|
+
z.object({ t: z.literal("union"), types: z.array(ApiParamTypeSchema) }),
|
|
59
|
+
z.object({ t: z.literal("intersection"), types: z.array(ApiParamTypeSchema) }),
|
|
60
|
+
z.object({ t: z.literal("array"), elementsType: ApiParamTypeSchema }),
|
|
61
|
+
z.object({
|
|
62
|
+
t: z.literal("ref"),
|
|
63
|
+
id: z.string(),
|
|
64
|
+
args: z.array(ApiParamTypeSchema).optional(),
|
|
65
|
+
}),
|
|
66
|
+
z.object({
|
|
67
|
+
t: z.literal("indexed-access"),
|
|
68
|
+
object: ApiParamTypeSchema,
|
|
69
|
+
index: ApiParamTypeSchema,
|
|
70
|
+
}),
|
|
71
|
+
z.object({
|
|
72
|
+
t: z.literal("type-param"),
|
|
73
|
+
id: z.string(),
|
|
74
|
+
constraint: ApiParamTypeSchema.optional(),
|
|
75
|
+
}),
|
|
76
|
+
z.object({ t: z.literal("tuple-type"), elements: z.array(ApiParamTypeSchema) }),
|
|
77
|
+
z.object({
|
|
78
|
+
t: z.literal("function"),
|
|
79
|
+
parameters: z.array(
|
|
80
|
+
z.object({
|
|
81
|
+
name: z.string(),
|
|
82
|
+
type: ApiParamTypeSchema,
|
|
83
|
+
optional: z.boolean(),
|
|
84
|
+
defaultDef: z.string().optional(),
|
|
85
|
+
}),
|
|
86
|
+
),
|
|
87
|
+
returnType: ApiParamTypeSchema,
|
|
88
|
+
}),
|
|
89
|
+
]),
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
/** 신뢰할 수 없는 값을 ApiParamType 경계에서 검증합니다. */
|
|
93
|
+
export function parseApiParamType<Input>(input: Input): ApiParamType {
|
|
94
|
+
const result = ApiParamTypeSchema.safeParse(input);
|
|
95
|
+
if (!result.success) {
|
|
96
|
+
throw new Error(`resolve 불가 ApiParamType: ${z.prettifyError(result.error)}`);
|
|
97
|
+
}
|
|
98
|
+
return result.data;
|
|
99
|
+
}
|
|
100
|
+
|
|
31
101
|
/**
|
|
32
102
|
* Promise 타입을 한 번 언래핑하여 내부 타입을 반환합니다.
|
|
33
103
|
* Promise가 아닌 경우 원본 타입을 그대로 반환합니다.
|
|
@@ -49,12 +119,13 @@ export function unwrapPromiseOnce(paramType: ApiParamType) {
|
|
|
49
119
|
* string, number, array, union 등 모든 ApiParamType을 처리하며,
|
|
50
120
|
* 순환참조가 발생하는 경우 z.unknown()으로 fallback합니다.
|
|
51
121
|
*/
|
|
52
|
-
export function getZodTypeFromApiParamType(
|
|
53
|
-
|
|
122
|
+
export function getZodTypeFromApiParamType<Input>(
|
|
123
|
+
input: Input,
|
|
54
124
|
references: {
|
|
55
125
|
[id: string]: z.ZodType;
|
|
56
126
|
},
|
|
57
127
|
): z.ZodType {
|
|
128
|
+
const paramType = parseApiParamType(input);
|
|
58
129
|
switch (paramType) {
|
|
59
130
|
case "string":
|
|
60
131
|
return z.string();
|
|
@@ -63,28 +134,38 @@ export function getZodTypeFromApiParamType(
|
|
|
63
134
|
case "boolean":
|
|
64
135
|
return z.boolean();
|
|
65
136
|
default: {
|
|
66
|
-
const advType =
|
|
137
|
+
const advType =
|
|
138
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as {
|
|
139
|
+
t: string;
|
|
140
|
+
value?: string | number;
|
|
141
|
+
};
|
|
67
142
|
switch (advType.t) {
|
|
68
143
|
case "string-literal":
|
|
69
144
|
case "numeric-literal":
|
|
70
145
|
return z.literal(advType.value);
|
|
71
146
|
case "object": {
|
|
72
|
-
const objType =
|
|
147
|
+
const objType =
|
|
148
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as {
|
|
149
|
+
t: string;
|
|
150
|
+
props: ApiParam[];
|
|
151
|
+
};
|
|
73
152
|
return getZodObjectFromApiParams(objType.props);
|
|
74
153
|
}
|
|
75
154
|
case "array": {
|
|
76
|
-
const arrType =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
155
|
+
const arrType =
|
|
156
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as {
|
|
157
|
+
t: string;
|
|
158
|
+
elementsType: ApiParamType;
|
|
159
|
+
};
|
|
80
160
|
return z.array(getZodTypeFromApiParamType(arrType.elementsType, references));
|
|
81
161
|
}
|
|
82
162
|
case "ref": {
|
|
83
|
-
const refType =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
163
|
+
const refType =
|
|
164
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as {
|
|
165
|
+
t: string;
|
|
166
|
+
id: string;
|
|
167
|
+
args?: ApiParamType[];
|
|
168
|
+
};
|
|
88
169
|
// Date 타입 처리
|
|
89
170
|
if (refType.id === "Date") {
|
|
90
171
|
return z.date();
|
|
@@ -94,10 +175,10 @@ export function getZodTypeFromApiParamType(
|
|
|
94
175
|
if (refType.args?.length !== 2) {
|
|
95
176
|
throw new Error(`잘못된 ${refType.id}`);
|
|
96
177
|
}
|
|
97
|
-
const [obj, literalOrUnion] =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
178
|
+
const [obj, literalOrUnion] =
|
|
179
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ refType.args.map(
|
|
180
|
+
(arg) => getZodTypeFromApiParamType(arg, references),
|
|
181
|
+
) as [AnyZodObject, z.ZodUnion<any> | AnyZodLiteral];
|
|
101
182
|
|
|
102
183
|
let keys: string[] = [];
|
|
103
184
|
if (literalOrUnion instanceof z.ZodUnion) {
|
|
@@ -105,18 +186,25 @@ export function getZodTypeFromApiParamType(
|
|
|
105
186
|
(option: { def: { values: string[] } }) => option.def.values[0],
|
|
106
187
|
);
|
|
107
188
|
} else {
|
|
108
|
-
keys =
|
|
189
|
+
keys =
|
|
190
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ (
|
|
191
|
+
literalOrUnion as z.ZodLiteral<string>
|
|
192
|
+
).def.values;
|
|
109
193
|
}
|
|
110
194
|
const keyRecord = Object.fromEntries(keys.map((key) => [key, true as const]));
|
|
111
195
|
if (refType.id === "Pick") {
|
|
112
196
|
if (obj.pick) {
|
|
113
197
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- Zod 4.3.6 pick 타입 호환성
|
|
114
|
-
return obj.pick(
|
|
198
|
+
return obj.pick(
|
|
199
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ keyRecord as any,
|
|
200
|
+
);
|
|
115
201
|
}
|
|
116
202
|
} else {
|
|
117
203
|
if (obj.omit) {
|
|
118
204
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- Zod 4.3.6 omit 타입 호환성
|
|
119
|
-
return obj.omit(
|
|
205
|
+
return obj.omit(
|
|
206
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ keyRecord as any,
|
|
207
|
+
);
|
|
120
208
|
}
|
|
121
209
|
}
|
|
122
210
|
}
|
|
@@ -126,7 +214,9 @@ export function getZodTypeFromApiParamType(
|
|
|
126
214
|
}
|
|
127
215
|
const obj = getZodTypeFromApiParamType(refType.args[0], references);
|
|
128
216
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- Partial 인수 타입 캐스팅
|
|
129
|
-
return
|
|
217
|
+
return /* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ (
|
|
218
|
+
obj as z.ZodObject<any>
|
|
219
|
+
).partial();
|
|
130
220
|
}
|
|
131
221
|
const reference = references[refType.id];
|
|
132
222
|
if (reference === undefined) {
|
|
@@ -136,10 +226,11 @@ export function getZodTypeFromApiParamType(
|
|
|
136
226
|
return reference;
|
|
137
227
|
}
|
|
138
228
|
case "union": {
|
|
139
|
-
const unionType =
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
229
|
+
const unionType =
|
|
230
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as {
|
|
231
|
+
t: string;
|
|
232
|
+
types: ApiParamType[];
|
|
233
|
+
};
|
|
143
234
|
// nullable 유니온
|
|
144
235
|
if (unionType.types.length === 2 && unionType.types.some((type) => type === "null")) {
|
|
145
236
|
if (unionType.types[0] === "null") {
|
|
@@ -154,10 +245,11 @@ export function getZodTypeFromApiParamType(
|
|
|
154
245
|
);
|
|
155
246
|
}
|
|
156
247
|
case "intersection": {
|
|
157
|
-
const intersectionType =
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
248
|
+
const intersectionType =
|
|
249
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as {
|
|
250
|
+
t: string;
|
|
251
|
+
types: ApiParamType[];
|
|
252
|
+
};
|
|
161
253
|
return intersectionType.types.reduce((result, type, index) => {
|
|
162
254
|
const resolvedType = getZodTypeFromApiParamType(type, references);
|
|
163
255
|
if (index === 0) {
|
|
@@ -165,13 +257,16 @@ export function getZodTypeFromApiParamType(
|
|
|
165
257
|
} else {
|
|
166
258
|
return z.intersection(result, resolvedType);
|
|
167
259
|
}
|
|
168
|
-
}, z.unknown() as z.ZodType);
|
|
260
|
+
}, /* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ z.unknown() as z.ZodType);
|
|
169
261
|
}
|
|
170
262
|
case "tuple-type": {
|
|
171
|
-
const tupleType =
|
|
263
|
+
const tupleType =
|
|
264
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as ApiParamType.TupleType;
|
|
172
265
|
return z.tuple(
|
|
173
266
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- 생성되는 ZodTuple의 타입을 추적하기 어려움
|
|
174
|
-
tupleType.elements.map(
|
|
267
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ tupleType.elements.map(
|
|
268
|
+
(elem) => getZodTypeFromApiParamType(elem, references),
|
|
269
|
+
) as any,
|
|
175
270
|
);
|
|
176
271
|
}
|
|
177
272
|
}
|
|
@@ -221,7 +316,9 @@ export function getZodObjectFromApi(
|
|
|
221
316
|
|
|
222
317
|
// FIXME: references는 글로벌 오브젝트로, typeParam.id("T" 등)를 key로 이렇게 덮어씌워버리면 loadedTypes가 오염됨.
|
|
223
318
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- 레퍼런스 타입 캐스팅
|
|
224
|
-
|
|
319
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ (references[
|
|
320
|
+
typeParam.id
|
|
321
|
+
] as z.ZodType<any>) = zodType;
|
|
225
322
|
}
|
|
226
323
|
}
|
|
227
324
|
}
|
|
@@ -247,7 +344,8 @@ export function getZodObjectFromApi(
|
|
|
247
344
|
* union, intersection, array, ref 등 모든 타입을 TS 문법으로 표현하며,
|
|
248
345
|
* import가 필요한 타입 ID는 injectImportKeys에 수집합니다.
|
|
249
346
|
*/
|
|
250
|
-
export function apiParamTypeToTsType(
|
|
347
|
+
export function apiParamTypeToTsType<Input>(input: Input, injectImportKeys: string[]): string {
|
|
348
|
+
const paramType = parseApiParamType(input);
|
|
251
349
|
if (
|
|
252
350
|
[
|
|
253
351
|
"string",
|
|
@@ -260,9 +358,11 @@ export function apiParamTypeToTsType(paramType: ApiParamType, injectImportKeys:
|
|
|
260
358
|
"void",
|
|
261
359
|
"any",
|
|
262
360
|
"unknown",
|
|
263
|
-
].includes(
|
|
361
|
+
].includes(
|
|
362
|
+
/* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as string,
|
|
363
|
+
)
|
|
264
364
|
) {
|
|
265
|
-
return paramType as string;
|
|
365
|
+
return /* SAFETY: API 데코레이터와 Zod 검증기 등록 계약이 이 값의 타입을 보장한다. */ paramType as string;
|
|
266
366
|
} else if (ApiParamType.isObject(paramType)) {
|
|
267
367
|
return `{ ${apiParamToTsCode(paramType.props, injectImportKeys)} }`;
|
|
268
368
|
} else if (ApiParamType.isStringLiteral(paramType)) {
|