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
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { type ExtendedApi } from "../../api/decorators";
|
|
2
|
+
import {
|
|
3
|
+
getHttpValidatorFingerprint,
|
|
4
|
+
getHttpValidatorRouteIdentifier,
|
|
5
|
+
getHttpValidatorRouteKey,
|
|
6
|
+
} from "../../api/http-validator";
|
|
7
|
+
import { Sonamu } from "../../api/sonamu";
|
|
8
|
+
import { type ApiParamType } from "../../types/types";
|
|
9
|
+
import { isObjectValue, isStringValue } from "../../utils/runtime-value";
|
|
10
|
+
import { Template } from "../template";
|
|
11
|
+
|
|
12
|
+
function collectReferencedTypes(type: ApiParamType, result: Set<string>): void {
|
|
13
|
+
if (isStringValue(type)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
switch (type.t) {
|
|
17
|
+
case "ref":
|
|
18
|
+
result.add(type.id);
|
|
19
|
+
for (const argument of type.args ?? []) {
|
|
20
|
+
collectReferencedTypes(argument, result);
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
case "array":
|
|
24
|
+
collectReferencedTypes(type.elementsType, result);
|
|
25
|
+
return;
|
|
26
|
+
case "object":
|
|
27
|
+
for (const prop of type.props) {
|
|
28
|
+
collectReferencedTypes(prop.type, result);
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
case "union":
|
|
32
|
+
case "intersection":
|
|
33
|
+
for (const member of type.types) {
|
|
34
|
+
collectReferencedTypes(member, result);
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
case "tuple-type":
|
|
38
|
+
for (const element of type.elements) {
|
|
39
|
+
collectReferencedTypes(element, result);
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
case "indexed-access":
|
|
43
|
+
collectReferencedTypes(type.object, result);
|
|
44
|
+
collectReferencedTypes(type.index, result);
|
|
45
|
+
return;
|
|
46
|
+
case "type-param":
|
|
47
|
+
if (type.constraint !== undefined) {
|
|
48
|
+
collectReferencedTypes(type.constraint, result);
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
case "function":
|
|
52
|
+
for (const parameter of type.parameters) {
|
|
53
|
+
collectReferencedTypes(parameter.type, result);
|
|
54
|
+
}
|
|
55
|
+
collectReferencedTypes(type.returnType, result);
|
|
56
|
+
return;
|
|
57
|
+
case "string-literal":
|
|
58
|
+
case "numeric-literal":
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class Template__http_validators extends Template {
|
|
64
|
+
constructor() {
|
|
65
|
+
super("http_validators");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
getTargetAndPath() {
|
|
69
|
+
return {
|
|
70
|
+
target: `${Sonamu.config.api.dir}/src/application`,
|
|
71
|
+
path: "sonamu.validators.generated.ts",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
render() {
|
|
76
|
+
const apis = [...Sonamu.syncer.apis]
|
|
77
|
+
.filter((api) => api.websocketOptions === undefined)
|
|
78
|
+
.toSorted((left, right) =>
|
|
79
|
+
getHttpValidatorRouteKey(left).localeCompare(getHttpValidatorRouteKey(right)),
|
|
80
|
+
);
|
|
81
|
+
const routeKeys = apis.map(getHttpValidatorRouteKey);
|
|
82
|
+
const duplicateKey = routeKeys.find((key, index) => routeKeys.indexOf(key) !== index);
|
|
83
|
+
if (duplicateKey !== undefined) {
|
|
84
|
+
throw new Error(`중복된 HTTP validator route key: ${duplicateKey}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const fingerprint = getHttpValidatorFingerprint(apis);
|
|
88
|
+
const policy = Sonamu.config.validation?.zodCompiler;
|
|
89
|
+
const isAot = isObjectValue(policy) && policy !== null && policy.api === "aot";
|
|
90
|
+
const hasAotValidators = isAot && apis.length > 0;
|
|
91
|
+
const referencedTypes = new Set<string>();
|
|
92
|
+
for (const api of apis) {
|
|
93
|
+
for (const typeParameter of api.typeParameters) {
|
|
94
|
+
collectReferencedTypes(typeParameter, referencedTypes);
|
|
95
|
+
}
|
|
96
|
+
for (const parameter of api.parameters) {
|
|
97
|
+
collectReferencedTypes(parameter.type, referencedTypes);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const importKeys = [...referencedTypes]
|
|
101
|
+
.filter((typeName) => Sonamu.syncer.types[typeName] !== undefined)
|
|
102
|
+
.toSorted();
|
|
103
|
+
const body = isAot
|
|
104
|
+
? this.renderAotRegistry(apis, fingerprint, importKeys)
|
|
105
|
+
: this.renderPlainStub(apis, fingerprint);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
...this.getTargetAndPath(),
|
|
109
|
+
body,
|
|
110
|
+
importKeys,
|
|
111
|
+
customHeaders: [
|
|
112
|
+
"/**",
|
|
113
|
+
" * @generated",
|
|
114
|
+
" * 직접 수정하지 마세요.",
|
|
115
|
+
" */",
|
|
116
|
+
"",
|
|
117
|
+
"/* oxlint-disable */",
|
|
118
|
+
"",
|
|
119
|
+
...(hasAotValidators
|
|
120
|
+
? [
|
|
121
|
+
`import { compile } from "zod-compiler";`,
|
|
122
|
+
`import { fastifyCaster, getZodObjectFromApi } from "sonamu";`,
|
|
123
|
+
]
|
|
124
|
+
: []),
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private renderAotRegistry(
|
|
130
|
+
apis: ExtendedApi[],
|
|
131
|
+
fingerprint: string,
|
|
132
|
+
importKeys: string[],
|
|
133
|
+
): string {
|
|
134
|
+
const declarations = apis.map((api) => {
|
|
135
|
+
const identifier = `validator_${getHttpValidatorRouteIdentifier(api)}`;
|
|
136
|
+
const schemaApi = {
|
|
137
|
+
modelName: api.modelName,
|
|
138
|
+
methodName: api.methodName,
|
|
139
|
+
path: api.path,
|
|
140
|
+
options: { httpMethod: api.options.httpMethod ?? "GET" },
|
|
141
|
+
typeParameters: api.typeParameters,
|
|
142
|
+
parameters: api.parameters,
|
|
143
|
+
returnType: "unknown",
|
|
144
|
+
} satisfies ExtendedApi;
|
|
145
|
+
return `export const ${identifier} = compile(fastifyCaster(getZodObjectFromApi(${JSON.stringify(schemaApi)}, { ...types })));`;
|
|
146
|
+
});
|
|
147
|
+
const routeIds = Object.fromEntries(
|
|
148
|
+
apis.map((api) => [getHttpValidatorRouteKey(api), getHttpValidatorRouteIdentifier(api)]),
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
return [
|
|
152
|
+
`export const fingerprint = ${JSON.stringify(fingerprint)};`,
|
|
153
|
+
`export const routeIds = ${JSON.stringify(routeIds)};`,
|
|
154
|
+
`const types = { ${importKeys.join(", ")} };`,
|
|
155
|
+
...declarations,
|
|
156
|
+
`export const validators = new Map([`,
|
|
157
|
+
...apis.map((api) => {
|
|
158
|
+
const routeKey = getHttpValidatorRouteKey(api);
|
|
159
|
+
return ` [${JSON.stringify(routeKey)}, validator_${getHttpValidatorRouteIdentifier(api)}],`;
|
|
160
|
+
}),
|
|
161
|
+
`]);`,
|
|
162
|
+
].join("\n");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private renderPlainStub(apis: ExtendedApi[], fingerprint: string): string {
|
|
166
|
+
const routeIds = Object.fromEntries(
|
|
167
|
+
apis.map((api) => [getHttpValidatorRouteKey(api), getHttpValidatorRouteIdentifier(api)]),
|
|
168
|
+
);
|
|
169
|
+
return [
|
|
170
|
+
`export const fingerprint = ${JSON.stringify(fingerprint)};`,
|
|
171
|
+
`export const routeIds = ${JSON.stringify(routeIds)};`,
|
|
172
|
+
`export const validators = new Map();`,
|
|
173
|
+
].join("\n");
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -33,7 +33,9 @@ export class Template__model extends Template {
|
|
|
33
33
|
const listParamsNode = zodTypeToRenderingNode(listParamsZodType);
|
|
34
34
|
|
|
35
35
|
const subsetKeyZodType = await getZodTypeById(`${entityId}SubsetKey`);
|
|
36
|
-
const subsetKeys =
|
|
36
|
+
const subsetKeys =
|
|
37
|
+
/* SAFETY: 생성된 *SubsetKey 타입은 enum 스키마로 등록된다. */ (subsetKeyZodType as z.ZodEnum)
|
|
38
|
+
.enum;
|
|
37
39
|
|
|
38
40
|
const names = EntityManager.getNamesFromId(entityId);
|
|
39
41
|
const entity = EntityManager.get(entityId);
|
|
@@ -52,8 +52,9 @@ const SUPPORTED_LOCALES = ${JSON.stringify(supportedLocales)} as const;
|
|
|
52
52
|
function getCurrentLocale(): (typeof SUPPORTED_LOCALES)[number] {
|
|
53
53
|
try {
|
|
54
54
|
const ctx = Sonamu.getContext();
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
const locale = ctx.locale;
|
|
56
|
+
return SUPPORTED_LOCALES.find((supportedLocale) => supportedLocale === locale) ?? DEFAULT_LOCALE;
|
|
57
|
+
} catch {
|
|
57
58
|
return DEFAULT_LOCALE;
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -61,14 +62,14 @@ function getCurrentLocale(): (typeof SUPPORTED_LOCALES)[number] {
|
|
|
61
62
|
: `
|
|
62
63
|
const DEFAULT_LOCALE = "${defaultLocale}" as const;
|
|
63
64
|
export const SUPPORTED_LOCALES = ${JSON.stringify(supportedLocales)} as const;
|
|
64
|
-
let
|
|
65
|
+
let currentLocale: (typeof SUPPORTED_LOCALES)[number] = DEFAULT_LOCALE;
|
|
65
66
|
|
|
66
67
|
export function setLocale(locale: (typeof SUPPORTED_LOCALES)[number]) {
|
|
67
|
-
|
|
68
|
+
currentLocale = locale;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
export function getCurrentLocale(): (typeof SUPPORTED_LOCALES)[number] {
|
|
71
|
-
return
|
|
72
|
+
return currentLocale;
|
|
72
73
|
}
|
|
73
74
|
`.trim();
|
|
74
75
|
|
|
@@ -126,7 +127,10 @@ export function defineLocale(dict: Partial<MergedDictionary>) {
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
// 각 locale별로 rc-keys + entity labels + 프로젝트 dict 합침
|
|
129
|
-
|
|
130
|
+
type DictionaryRegistry = {
|
|
131
|
+
[L in (typeof SUPPORTED_LOCALES)[number]]: Partial<MergedDictionary>;
|
|
132
|
+
};
|
|
133
|
+
const dictionaries: DictionaryRegistry = {
|
|
130
134
|
${defaultLocale}: { ...${getRCKeysVarName(defaultLocale)}, ...entityLabels, ...${defaultLocale} },
|
|
131
135
|
${supportedLocales
|
|
132
136
|
.filter((locale) => locale !== defaultLocale)
|
|
@@ -138,29 +142,33 @@ type SDReturnType<K extends DictKey> = MergedDictionary[K] extends (...args: inf
|
|
|
138
142
|
? (...args: P) => LocalizedString
|
|
139
143
|
: LocalizedString;
|
|
140
144
|
|
|
141
|
-
function getDictValue<K extends DictKey>(key: K, locale:
|
|
145
|
+
function getDictValue<K extends DictKey>(key: K, locale: (typeof SUPPORTED_LOCALES)[number]): SDReturnType<K> {
|
|
142
146
|
// 1. 지정된 locale에서 조회
|
|
143
147
|
const dict = dictionaries[locale];
|
|
144
148
|
if (dict?.[key] !== undefined) {
|
|
145
|
-
|
|
149
|
+
// SAFETY: 요청 locale의 같은 키는 MergedDictionary가 정한 반환 종류를 유지합니다.
|
|
150
|
+
return dict[key] as SDReturnType<K>;
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
// 2. default locale에서 조회
|
|
149
154
|
if (locale !== DEFAULT_LOCALE && dictionaries[DEFAULT_LOCALE]?.[key] !== undefined) {
|
|
150
|
-
|
|
155
|
+
// SAFETY: 기본 locale의 같은 키는 MergedDictionary가 정한 반환 종류를 유지합니다.
|
|
156
|
+
return dictionaries[DEFAULT_LOCALE][key] as SDReturnType<K>;
|
|
151
157
|
}
|
|
152
158
|
|
|
153
159
|
// 3. supported locales 순회
|
|
154
160
|
for (const supportedLocale of SUPPORTED_LOCALES) {
|
|
155
161
|
if (supportedLocale !== locale && supportedLocale !== DEFAULT_LOCALE) {
|
|
156
162
|
if (dictionaries[supportedLocale]?.[key] !== undefined) {
|
|
157
|
-
|
|
163
|
+
// SAFETY: 대체 locale의 같은 키는 MergedDictionary가 정한 반환 종류를 유지합니다.
|
|
164
|
+
return dictionaries[supportedLocale][key] as SDReturnType<K>;
|
|
158
165
|
}
|
|
159
166
|
}
|
|
160
167
|
}
|
|
161
168
|
|
|
162
|
-
//
|
|
163
|
-
|
|
169
|
+
// 모든 locale에 값이 없으면 동적으로 조합된 키를 그대로 노출합니다.
|
|
170
|
+
// SAFETY: 누락된 사전 키의 문자열 표현은 LocalizedString fallback 규약을 따릅니다.
|
|
171
|
+
return String(key) as SDReturnType<K>;
|
|
164
172
|
}
|
|
165
173
|
|
|
166
174
|
/**
|
|
@@ -226,58 +234,85 @@ type LocalizedColumnCandidate<T, K extends string> =
|
|
|
226
234
|
type LocalizedColumnReturn<T, K extends string> =
|
|
227
235
|
| LocalizedColumnValueFrom<LocalizedColumnCandidate<T, K>>
|
|
228
236
|
| undefined;
|
|
229
|
-
type LocaleValueMap =
|
|
237
|
+
type LocaleValueMap = {
|
|
238
|
+
[L in (typeof SUPPORTED_LOCALES)[number]]?: LocalizedColumnValue;
|
|
239
|
+
};
|
|
240
|
+
function isString<V>(value: V): value is V & string {
|
|
241
|
+
return Object.prototype.toString.call(value) === "[object String]";
|
|
242
|
+
}
|
|
230
243
|
|
|
231
|
-
function isLocalizedColumnValue(value:
|
|
232
|
-
return
|
|
244
|
+
function isLocalizedColumnValue<V>(value: V): value is V & LocalizedColumnValue {
|
|
245
|
+
return isString(value) || (Array.isArray(value) && value.every(isString));
|
|
233
246
|
}
|
|
234
247
|
|
|
235
|
-
function isLocalizedColumnScalarValue(value:
|
|
236
|
-
return ["
|
|
248
|
+
function isLocalizedColumnScalarValue<V>(value: V): value is V & LocalizedColumnScalarValue {
|
|
249
|
+
return ["[object String]", "[object Number]", "[object Boolean]", "[object BigInt]"].includes(
|
|
250
|
+
Object.prototype.toString.call(value),
|
|
251
|
+
);
|
|
237
252
|
}
|
|
238
253
|
|
|
239
|
-
function isEmptyLocalizedColumnValue(value:
|
|
254
|
+
function isEmptyLocalizedColumnValue<V>(value: V): value is V & (null | undefined | "") {
|
|
240
255
|
return value === null || value === undefined || value === "";
|
|
241
256
|
}
|
|
242
257
|
|
|
243
|
-
|
|
258
|
+
type PropertyValue<T, K extends PropertyKey> = K extends keyof T ? T[K] : undefined;
|
|
259
|
+
|
|
260
|
+
function getProperty<T extends object, K extends PropertyKey>(row: T, key: K): PropertyValue<T, K> {
|
|
261
|
+
if (!(key in row)) {
|
|
262
|
+
// SAFETY: 존재하지 않는 후보 키는 조건부 속성 타입에서도 undefined입니다.
|
|
263
|
+
return undefined as PropertyValue<T, K>;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// SAFETY: own/inherited 키 존재를 확인했으므로 해당 키의 조건부 속성 타입으로 좁힐 수 있습니다.
|
|
267
|
+
return (row as T & Record<K, PropertyValue<T, K>>)[key];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function getNestedLocaleValue<T extends object, K extends LocalizedBaseColumn<T>>(
|
|
244
271
|
row: T,
|
|
245
272
|
column: K,
|
|
246
273
|
locale: (typeof SUPPORTED_LOCALES)[number],
|
|
247
|
-
):
|
|
248
|
-
const columnValue = row
|
|
249
|
-
if (columnValue === null ||
|
|
274
|
+
): LocalizedColumnValue | undefined {
|
|
275
|
+
const columnValue = getProperty(row, column);
|
|
276
|
+
if (columnValue === null || Object.prototype.toString.call(columnValue) !== "[object Object]") {
|
|
250
277
|
return undefined;
|
|
251
278
|
}
|
|
252
279
|
|
|
280
|
+
// SAFETY: 일반 객체 검사를 통과한 값만 locale별 값 맵으로 조회합니다.
|
|
253
281
|
return (columnValue as LocaleValueMap)[locale];
|
|
254
282
|
}
|
|
255
283
|
|
|
256
|
-
|
|
284
|
+
function localizedKey<K extends string>(columnName: K, localeName: (typeof SUPPORTED_LOCALES)[number]) {
|
|
285
|
+
return \`\${columnName}_\${localeName}\`;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function localizedColumn<T extends object, K extends LocalizedBaseColumn<T>>(
|
|
257
289
|
row: T,
|
|
258
290
|
column: K,
|
|
259
291
|
): LocalizedColumnReturn<T, K> {
|
|
260
|
-
const
|
|
261
|
-
const locale = SUPPORTED_LOCALES.includes(
|
|
262
|
-
const otherLocales = SUPPORTED_LOCALES.filter(
|
|
263
|
-
|
|
292
|
+
const requestedLocale = getCurrentLocale();
|
|
293
|
+
const locale = SUPPORTED_LOCALES.includes(requestedLocale) ? requestedLocale : DEFAULT_LOCALE;
|
|
294
|
+
const otherLocales = SUPPORTED_LOCALES.filter(
|
|
295
|
+
(candidateLocale) => candidateLocale !== locale && candidateLocale !== DEFAULT_LOCALE,
|
|
296
|
+
);
|
|
264
297
|
const values = [
|
|
265
|
-
{ value: row
|
|
298
|
+
{ value: getProperty(row, localizedKey(column, locale)), source: "direct" },
|
|
266
299
|
{ value: getNestedLocaleValue(row, column, locale), source: "nested" },
|
|
267
|
-
{ value: row
|
|
268
|
-
{ value: row
|
|
300
|
+
{ value: getProperty(row, column), source: "direct" },
|
|
301
|
+
{ value: getProperty(row, localizedKey(column, DEFAULT_LOCALE)), source: "direct" },
|
|
269
302
|
{ value: getNestedLocaleValue(row, column, DEFAULT_LOCALE), source: "nested" },
|
|
270
303
|
...otherLocales.flatMap((l) => [
|
|
271
|
-
{ value: row
|
|
304
|
+
{ value: getProperty(row, localizedKey(column, l)), source: "direct" },
|
|
272
305
|
{ value: getNestedLocaleValue(row, column, l), source: "nested" },
|
|
273
306
|
]),
|
|
274
307
|
];
|
|
275
308
|
|
|
276
309
|
for (const { value, source } of values) {
|
|
277
310
|
if (!isEmptyLocalizedColumnValue(value) && isLocalizedColumnValue(value)) {
|
|
311
|
+
// SAFETY: 값 가드가 선택한 컬럼의 문자열 또는 문자열 배열임을 확인했습니다.
|
|
278
312
|
return value as LocalizedColumnReturn<T, K>;
|
|
279
313
|
}
|
|
280
314
|
if (source === "direct" && !isEmptyLocalizedColumnValue(value) && isLocalizedColumnScalarValue(value)) {
|
|
315
|
+
// SAFETY: 직접 컬럼의 스칼라 값은 문자열로 변환해 지역화 반환 타입을 충족합니다.
|
|
281
316
|
return String(value) as LocalizedColumnReturn<T, K>;
|
|
282
317
|
}
|
|
283
318
|
}
|
|
@@ -292,14 +327,19 @@ export function localizedColumn<T extends Record<string, unknown>, K extends Loc
|
|
|
292
327
|
* @example
|
|
293
328
|
* SD.enumLabels("TagOrderBy")[key] // → 현재 locale의 라벨
|
|
294
329
|
*/
|
|
295
|
-
|
|
296
|
-
|
|
330
|
+
interface EnumLabels {
|
|
331
|
+
[key: string]: LocalizedString;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
SD.enumLabels = (enumName: string): EnumLabels => {
|
|
335
|
+
return new Proxy<EnumLabels>({}, {
|
|
297
336
|
get(_, key: string | symbol) {
|
|
298
|
-
if (
|
|
337
|
+
if (Object.prototype.toString.call(key) === "[object Symbol]") {
|
|
299
338
|
return undefined;
|
|
300
339
|
}
|
|
301
340
|
|
|
302
|
-
|
|
341
|
+
// SAFETY: 생성된 enum 이름과 값의 조합은 enum 사전 키 형식을 따릅니다.
|
|
342
|
+
const dictKey = \`enum.\${enumName}.\${String(key)}\` as DictKey;
|
|
303
343
|
return getDictValue(dictKey, getCurrentLocale());
|
|
304
344
|
}
|
|
305
345
|
});
|
|
@@ -318,16 +358,16 @@ SD.enumLabels = (enumName: string): Record<string, LocalizedString> => {
|
|
|
318
358
|
* react-components의 rc-keys를 추출합
|
|
319
359
|
* sonamu/src/dict/rc-keys.ts 파일의 소스 코드를 직접 읽어서 반환
|
|
320
360
|
*/
|
|
321
|
-
private extractRCKeysSourceCode()
|
|
361
|
+
private extractRCKeysSourceCode() {
|
|
322
362
|
try {
|
|
323
363
|
// rc-keys.ts 파일 경로
|
|
324
|
-
const
|
|
325
|
-
const
|
|
364
|
+
const currentFilename = fileURLToPath(import.meta.url);
|
|
365
|
+
const currentDirectory = path.dirname(currentFilename);
|
|
326
366
|
|
|
327
367
|
// dist에서 실행될 때는 src로 경로 변경
|
|
328
|
-
const basePath =
|
|
329
|
-
?
|
|
330
|
-
:
|
|
368
|
+
const basePath = currentDirectory.includes("/dist/")
|
|
369
|
+
? currentDirectory.replace("/dist/", "/src/")
|
|
370
|
+
: currentDirectory;
|
|
331
371
|
|
|
332
372
|
const rcKeysPath = path.join(basePath, "../../dict/rc-keys.ts");
|
|
333
373
|
|
|
@@ -11,6 +11,7 @@ import { Sonamu } from "../../api/sonamu";
|
|
|
11
11
|
import { EntityManager } from "../../entity/entity-manager";
|
|
12
12
|
import { type TemplateOptions } from "../../types/types";
|
|
13
13
|
import { ApiParamType } from "../../types/types";
|
|
14
|
+
import { isStringValue } from "../../utils/runtime-value";
|
|
14
15
|
import { assertDefined } from "../../utils/utils";
|
|
15
16
|
import { Template } from "../template";
|
|
16
17
|
import { BUILT_IN_TYPES, zodTypeToTsTypeDef } from "../zod-converter";
|
|
@@ -197,8 +198,7 @@ export function ${methodNameWebSocketCamelized}(
|
|
|
197
198
|
.map((param) => {
|
|
198
199
|
// primitive 타입인지 체크
|
|
199
200
|
const isPrimitive =
|
|
200
|
-
|
|
201
|
-
["string", "number", "boolean"].includes(param.type);
|
|
201
|
+
isStringValue(param.type) && ["string", "number", "boolean"].includes(param.type);
|
|
202
202
|
|
|
203
203
|
if (isPrimitive) {
|
|
204
204
|
// primitive: 직접 formData.append
|
|
@@ -11,6 +11,18 @@ import {
|
|
|
11
11
|
} from "../helpers";
|
|
12
12
|
import { Template } from "../template";
|
|
13
13
|
|
|
14
|
+
type FormDefaultValue =
|
|
15
|
+
| null
|
|
16
|
+
| undefined
|
|
17
|
+
| boolean
|
|
18
|
+
| number
|
|
19
|
+
| string
|
|
20
|
+
| never[]
|
|
21
|
+
| Record<string, never>;
|
|
22
|
+
interface FormDefaults {
|
|
23
|
+
[columnName: string]: FormDefaultValue;
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
export class Template__view_form extends Template {
|
|
15
27
|
constructor() {
|
|
16
28
|
super("view_form");
|
|
@@ -149,41 +161,38 @@ export class Template__view_form extends Template {
|
|
|
149
161
|
}
|
|
150
162
|
}
|
|
151
163
|
|
|
152
|
-
resolveDefaultValue(columns: RenderingNode[]):
|
|
153
|
-
return columns.reduce(
|
|
154
|
-
(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
164
|
+
resolveDefaultValue(columns: RenderingNode[]): FormDefaults {
|
|
165
|
+
return columns.reduce<FormDefaults>((result, col) => {
|
|
166
|
+
if (col.optional) {
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
158
169
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
} else if (col.zodType instanceof z.ZodArray) {
|
|
177
|
-
value = [];
|
|
178
|
-
} else if (col.zodType instanceof z.ZodObject) {
|
|
179
|
-
value = {};
|
|
170
|
+
let value: FormDefaultValue;
|
|
171
|
+
if (col.nullable === true) {
|
|
172
|
+
value = null;
|
|
173
|
+
} else if (col.zodType instanceof z.ZodNumber) {
|
|
174
|
+
value = 0;
|
|
175
|
+
} else if (col.zodType instanceof z.ZodEnum) {
|
|
176
|
+
value = Object.keys(col.zodType.enum)[0];
|
|
177
|
+
} else if (col.zodType instanceof z.ZodBoolean) {
|
|
178
|
+
value = false;
|
|
179
|
+
} else if (col.zodType instanceof z.core.$ZodString) {
|
|
180
|
+
// NOTE: z.ZodString으로 비교하면 z.url(), z.email() 등의 타입에서 문제가 생기므로 z.core.$ZodString으로 비교함
|
|
181
|
+
// FIXME: email이나 url 타입 등에 대한 처리가 필요함
|
|
182
|
+
if (col.renderType === "string-datetime") {
|
|
183
|
+
value = "now()";
|
|
184
|
+
} else {
|
|
185
|
+
value = "";
|
|
180
186
|
}
|
|
187
|
+
} else if (col.zodType instanceof z.ZodArray) {
|
|
188
|
+
value = [];
|
|
189
|
+
} else if (col.zodType instanceof z.ZodObject) {
|
|
190
|
+
value = {};
|
|
191
|
+
}
|
|
181
192
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
{} as { [key: string]: unknown },
|
|
186
|
-
);
|
|
193
|
+
result[col.name] = value;
|
|
194
|
+
return result;
|
|
195
|
+
}, {});
|
|
187
196
|
}
|
|
188
197
|
|
|
189
198
|
async render({ entityId }: TemplateOptions["view_form"]) {
|
|
@@ -228,12 +237,16 @@ export class Template__view_form extends Template {
|
|
|
228
237
|
try {
|
|
229
238
|
const { id } = getEnumInfoFromColName(entityId, col.name);
|
|
230
239
|
enumImports.add(id);
|
|
231
|
-
} catch {
|
|
240
|
+
} catch {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
232
243
|
} else if (col.renderType === "number-fk_id" || col.renderType === "string-fk_id") {
|
|
233
244
|
try {
|
|
234
245
|
const relProp = getRelationPropFromColName(entityId, col.name.replace("_id", ""));
|
|
235
246
|
fkConfigImports.add(relProp.with);
|
|
236
|
-
} catch {
|
|
247
|
+
} catch {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
237
250
|
} else if (
|
|
238
251
|
col.renderType === "string-plain" &&
|
|
239
252
|
col.name.endsWith("_id") &&
|
|
@@ -243,14 +256,18 @@ export class Template__view_form extends Template {
|
|
|
243
256
|
try {
|
|
244
257
|
const relProp = getRelationPropFromColName(entityId, col.name.replace("_id", ""));
|
|
245
258
|
fkConfigImports.add(relProp.with);
|
|
246
|
-
} catch {
|
|
259
|
+
} catch {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
247
262
|
} else if (col.renderType === "array" && col.name.endsWith("_ids")) {
|
|
248
263
|
// ManyToMany relation의 FK 배열
|
|
249
264
|
try {
|
|
250
265
|
const baseName = col.name.replace(/_ids$/, "");
|
|
251
266
|
const relProp = getRelationPropFromColName(entityId, baseName);
|
|
252
267
|
fkConfigImports.add(relProp.with);
|
|
253
|
-
} catch {
|
|
268
|
+
} catch {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
254
271
|
}
|
|
255
272
|
});
|
|
256
273
|
|
|
@@ -295,7 +312,7 @@ import { defaultCatch } from "@/services/sonamu.shared";
|
|
|
295
312
|
import { ${names.capital}SaveParams } from "@/services/${names.fs}/${names.fs}.types";${
|
|
296
313
|
fkConfigImports.size > 0
|
|
297
314
|
? `\nimport { ${Array.from(fkConfigImports)
|
|
298
|
-
.map((
|
|
315
|
+
.map((relatedEntityId) => `${relatedEntityId}AsyncIdConfig`)
|
|
299
316
|
.join(", ")} } from "@/services/services.generated";`
|
|
300
317
|
: ""
|
|
301
318
|
}
|
|
@@ -487,8 +504,8 @@ ${columns
|
|
|
487
504
|
const label = (() => {
|
|
488
505
|
if (col.label.endsWith("Id")) {
|
|
489
506
|
try {
|
|
490
|
-
const
|
|
491
|
-
return
|
|
507
|
+
const relatedEntity = EntityManager.get(col.label.replace("Id", ""));
|
|
508
|
+
return relatedEntity.title ?? col.label;
|
|
492
509
|
} catch {
|
|
493
510
|
return col.label;
|
|
494
511
|
}
|