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
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
type DatabaseSchemaExtend,
|
|
12
12
|
type EntityIndex,
|
|
13
13
|
} from "../types/types";
|
|
14
|
+
import { asArray } from "../utils/model";
|
|
15
|
+
import { isNumberValue, isObjectValue, isStringValue } from "../utils/runtime-value";
|
|
14
16
|
import { assertDefined, nonNullable } from "../utils/utils";
|
|
15
17
|
import { batchUpdate } from "./_batch_update";
|
|
16
18
|
import { type RowWithId } from "./_batch_update";
|
|
@@ -27,22 +29,36 @@ export type { DatabaseForeignKeys };
|
|
|
27
29
|
type InheritableColumns<TTable extends TableName<DatabaseSchemaExtend>> =
|
|
28
30
|
TTable extends keyof DatabaseSchemaExtend ? ColumnKeys<DatabaseSchemaExtend[TTable]> : never;
|
|
29
31
|
|
|
32
|
+
// 참조 필드 타입
|
|
33
|
+
export type UBRef = {
|
|
34
|
+
uuid: string;
|
|
35
|
+
of: string;
|
|
36
|
+
use?: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
type UpsertValue =
|
|
40
|
+
| string
|
|
41
|
+
| number
|
|
42
|
+
| boolean
|
|
43
|
+
| bigint
|
|
44
|
+
| Date
|
|
45
|
+
| Buffer
|
|
46
|
+
| Knex.Raw
|
|
47
|
+
| UBRef
|
|
48
|
+
| null
|
|
49
|
+
| UpsertValue[]
|
|
50
|
+
| { [key: string]: UpsertValue | undefined };
|
|
51
|
+
type UpsertRow = Record<string, UpsertValue | undefined>;
|
|
52
|
+
|
|
30
53
|
// 테이블 데이터 타입
|
|
31
54
|
type TableData = {
|
|
32
55
|
references: Set<string>;
|
|
33
|
-
rows:
|
|
56
|
+
rows: UpsertRow[];
|
|
34
57
|
uniqueIndexes: EntityIndex[];
|
|
35
58
|
uniquesMap: Map<string, string>;
|
|
36
59
|
jsonColumns: string[];
|
|
37
60
|
};
|
|
38
61
|
|
|
39
|
-
// 참조 필드 타입
|
|
40
|
-
export type UBRef = {
|
|
41
|
-
uuid: string;
|
|
42
|
-
of: string;
|
|
43
|
-
use?: string;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
62
|
// upsert 옵션
|
|
47
63
|
export type UpsertOptions<TTable extends TableName<DatabaseSchemaExtend>> = {
|
|
48
64
|
chunkSize?: number;
|
|
@@ -55,13 +71,8 @@ export type InsertOnlyOptions = {
|
|
|
55
71
|
chunkSize?: number;
|
|
56
72
|
};
|
|
57
73
|
|
|
58
|
-
export function isRefField(field:
|
|
59
|
-
return (
|
|
60
|
-
field !== undefined &&
|
|
61
|
-
field !== null &&
|
|
62
|
-
(field as UBRef)?.of !== undefined &&
|
|
63
|
-
(field as UBRef)?.uuid !== undefined
|
|
64
|
-
);
|
|
74
|
+
export function isRefField<Value>(field: Value): field is Value & UBRef {
|
|
75
|
+
return isObjectValue(field) && "of" in field && "uuid" in field;
|
|
65
76
|
}
|
|
66
77
|
|
|
67
78
|
export class UpsertBuilder {
|
|
@@ -99,22 +110,19 @@ export class UpsertBuilder {
|
|
|
99
110
|
return this.tables.has(tableName);
|
|
100
111
|
}
|
|
101
112
|
|
|
102
|
-
register<
|
|
103
|
-
tableName: string,
|
|
104
|
-
row: {
|
|
105
|
-
[key in T]?: UBRef | string | number | boolean | bigint | null | object | unknown;
|
|
106
|
-
},
|
|
107
|
-
): UBRef {
|
|
113
|
+
register<Row extends object>(tableName: string, row: Row): UBRef {
|
|
108
114
|
const table = this.getTable(tableName);
|
|
109
115
|
|
|
110
116
|
// 해당 테이블의 unique 인덱스를 순회하며 키 생성
|
|
111
117
|
const uniqueKeys = table.uniqueIndexes
|
|
112
118
|
.map((unqIndex) => {
|
|
113
119
|
const uniqueKeyArray = unqIndex.columns.map((unqCol) => {
|
|
120
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
114
121
|
const val = row[unqCol.name as keyof typeof row];
|
|
115
122
|
if (isRefField(val)) {
|
|
116
123
|
return val.uuid;
|
|
117
124
|
} else {
|
|
125
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
118
126
|
return row[unqCol.name as keyof typeof row] ?? randomUUID(); // nullable인 경우 uuid로 랜덤값 삽입
|
|
119
127
|
}
|
|
120
128
|
});
|
|
@@ -154,32 +162,33 @@ export class UpsertBuilder {
|
|
|
154
162
|
|
|
155
163
|
// 이 테이블에 사용된 RefField를 순회하여, 현재 테이블 정보에 어떤 필드를 참조하는지 추가
|
|
156
164
|
// 이 정보를 나중에 치환할 때 사용
|
|
157
|
-
|
|
165
|
+
const normalizedRow = Object.fromEntries(
|
|
158
166
|
Object.entries(row).map(([rowKey, rowValue]) => {
|
|
159
167
|
if (isRefField(rowValue)) {
|
|
160
168
|
rowValue.use ??= "id";
|
|
161
169
|
table.references.add(`${rowValue.of}.${rowValue.use}`);
|
|
162
|
-
return [rowKey, rowValue];
|
|
170
|
+
return [rowKey, rowValue] as const;
|
|
163
171
|
} else if (table.jsonColumns.includes(rowKey) && rowValue !== null) {
|
|
164
172
|
// JSON 컬럼인 경우 JSON.stringify 처리 (Knex는 JSON 타입을 지원하지 않음)
|
|
165
|
-
return [rowKey, JSON.stringify(rowValue)];
|
|
173
|
+
return [rowKey, JSON.stringify(rowValue)] as const;
|
|
166
174
|
} else if (isArray(rowValue)) {
|
|
167
175
|
// 배열은 그대로 저장
|
|
168
|
-
return [rowKey, rowValue];
|
|
176
|
+
return [rowKey, rowValue] as const;
|
|
169
177
|
} else {
|
|
170
|
-
return [rowKey, rowValue];
|
|
178
|
+
return [rowKey, rowValue] as const;
|
|
171
179
|
}
|
|
172
180
|
}),
|
|
173
|
-
)
|
|
181
|
+
);
|
|
174
182
|
|
|
175
183
|
table.rows.push({
|
|
176
184
|
uuid,
|
|
177
|
-
...
|
|
185
|
+
...normalizedRow,
|
|
178
186
|
});
|
|
179
187
|
|
|
180
188
|
const result: UBRef = {
|
|
181
189
|
of: tableName,
|
|
182
|
-
|
|
190
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
191
|
+
uuid: isStringValue(normalizedRow.uuid) ? normalizedRow.uuid : uuid,
|
|
183
192
|
};
|
|
184
193
|
|
|
185
194
|
Naite.t("puri:ub-register", {
|
|
@@ -235,19 +244,21 @@ export class UpsertBuilder {
|
|
|
235
244
|
|
|
236
245
|
// 전체 테이블 순회하여 현재 테이블 참조하는 모든 테이블 추출
|
|
237
246
|
const { references, refTables } = Array.from(this.tables).reduce(
|
|
238
|
-
(r, [,
|
|
239
|
-
const reference = Array.from(
|
|
247
|
+
(r, [, candidateTable]) => {
|
|
248
|
+
const reference = Array.from(candidateTable.references.values()).find((ref) =>
|
|
240
249
|
ref.includes(`${tableName}.`),
|
|
241
250
|
);
|
|
242
251
|
if (reference) {
|
|
243
252
|
r.references.push(reference);
|
|
244
|
-
r.refTables.push(
|
|
253
|
+
r.refTables.push(candidateTable);
|
|
245
254
|
}
|
|
246
255
|
|
|
247
256
|
return r;
|
|
248
257
|
},
|
|
249
258
|
{
|
|
259
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
250
260
|
references: [] as string[],
|
|
261
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
251
262
|
refTables: [] as TableData[],
|
|
252
263
|
},
|
|
253
264
|
);
|
|
@@ -262,7 +273,7 @@ export class UpsertBuilder {
|
|
|
262
273
|
throw new Error(`${tableName}에 순환 자기 참조가 있습니다.`);
|
|
263
274
|
}
|
|
264
275
|
|
|
265
|
-
const uuidMap = new Map<string,
|
|
276
|
+
const uuidMap = new Map<string, UpsertRow & { id: number | string }>();
|
|
266
277
|
const allIds: (number | string)[] = [];
|
|
267
278
|
|
|
268
279
|
// 레벨별로 순차 처리
|
|
@@ -282,7 +293,8 @@ export class UpsertBuilder {
|
|
|
282
293
|
|
|
283
294
|
if (!parent) throw new Error(`존재하지 않는 uuid ${value.uuid} -- in ${tableName}`);
|
|
284
295
|
|
|
285
|
-
|
|
296
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
297
|
+
resolved[key] = (parent as UpsertRow)[value.use ?? "id"];
|
|
286
298
|
|
|
287
299
|
Naite.t("puri:ub-ref-resolved", {
|
|
288
300
|
tableName,
|
|
@@ -309,10 +321,15 @@ export class UpsertBuilder {
|
|
|
309
321
|
});
|
|
310
322
|
|
|
311
323
|
// uuid를 별도로 보관하고, DB에 저장할 데이터에서 제거
|
|
324
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
312
325
|
const originalUuids = dataChunk.map((r) => r.uuid as string);
|
|
313
|
-
const dataForDb = dataChunk.map((
|
|
326
|
+
const dataForDb = dataChunk.map((row) => {
|
|
327
|
+
const rest = { ...row };
|
|
328
|
+
delete rest.uuid;
|
|
329
|
+
return rest;
|
|
330
|
+
});
|
|
314
331
|
|
|
315
|
-
let resultRows: { id: number | string
|
|
332
|
+
let resultRows: (UpsertRow & { id: number | string })[];
|
|
316
333
|
|
|
317
334
|
if (mode === "insert") {
|
|
318
335
|
// INSERT 모드 - RETURNING 사용
|
|
@@ -339,9 +356,11 @@ export class UpsertBuilder {
|
|
|
339
356
|
if (conditions.length === 0) continue;
|
|
340
357
|
|
|
341
358
|
// 배치 SELECT
|
|
359
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
342
360
|
const existingRows = (await wdb(tableName)
|
|
343
|
-
|
|
344
|
-
.
|
|
361
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
362
|
+
.whereIn(columns, conditions as UpsertRow[][])
|
|
363
|
+
.select("id", ...columns)) as UpsertRow[];
|
|
345
364
|
|
|
346
365
|
// Map 생성: unique 컬럼 조합 → id
|
|
347
366
|
const existingMap = new Map<string, number | string>();
|
|
@@ -350,7 +369,7 @@ export class UpsertBuilder {
|
|
|
350
369
|
.map((col) => String(existing[col] ?? ""))
|
|
351
370
|
.join("---delimiter---");
|
|
352
371
|
const id = existing.id;
|
|
353
|
-
if (
|
|
372
|
+
if (isNumberValue(id) || isStringValue(id)) {
|
|
354
373
|
existingMap.set(key, id);
|
|
355
374
|
}
|
|
356
375
|
}
|
|
@@ -377,6 +396,7 @@ export class UpsertBuilder {
|
|
|
377
396
|
|
|
378
397
|
// inherit 옵션 처리 - inherit 컬럼은 update 대상에서 제외
|
|
379
398
|
if (options?.inherit?.length) {
|
|
399
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
380
400
|
const inheritColumns = options.inherit as string[];
|
|
381
401
|
|
|
382
402
|
const excludedFromUpdate = updateColumns.filter((c) => inheritColumns.includes(c));
|
|
@@ -415,8 +435,8 @@ export class UpsertBuilder {
|
|
|
415
435
|
}
|
|
416
436
|
|
|
417
437
|
// 해당 테이블 참조를 실제 밸류로 변경
|
|
418
|
-
for (const
|
|
419
|
-
|
|
438
|
+
for (const referencingTable of refTables) {
|
|
439
|
+
referencingTable.rows = referencingTable.rows.map((row) => {
|
|
420
440
|
for (const key of Object.keys(row)) {
|
|
421
441
|
const prop = row[key];
|
|
422
442
|
if (isRefField(prop) && prop.of === tableName) {
|
|
@@ -425,7 +445,8 @@ export class UpsertBuilder {
|
|
|
425
445
|
console.error(prop);
|
|
426
446
|
throw new Error(`존재하지 않는 uuid ${prop.uuid} -- in ${tableName}`);
|
|
427
447
|
}
|
|
428
|
-
|
|
448
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
449
|
+
const resolvedValue = parent[prop.use ?? "id"];
|
|
429
450
|
row[key] = resolvedValue;
|
|
430
451
|
|
|
431
452
|
Naite.t("puri:ub-ref-resolved", {
|
|
@@ -442,9 +463,7 @@ export class UpsertBuilder {
|
|
|
442
463
|
|
|
443
464
|
if (options?.cleanOrphans) {
|
|
444
465
|
const cleanOrphans = options.cleanOrphans;
|
|
445
|
-
const fkColumns =
|
|
446
|
-
? (cleanOrphans as ForeignKeyColumns<TTable>[])
|
|
447
|
-
: [cleanOrphans as ForeignKeyColumns<TTable>];
|
|
466
|
+
const fkColumns = asArray(cleanOrphans);
|
|
448
467
|
|
|
449
468
|
// 현재 register된 레코드들의 FK 값들 추출
|
|
450
469
|
const fkConditions = fkColumns.map((fkCol) => {
|
|
@@ -458,6 +477,7 @@ export class UpsertBuilder {
|
|
|
458
477
|
|
|
459
478
|
// 각 FK 컬럼에 대한 WHERE IN 조건 추가
|
|
460
479
|
for (const { column, values } of fkConditions) {
|
|
480
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
461
481
|
deleteQuery = deleteQuery.whereIn(column, values as Knex.Value[]);
|
|
462
482
|
}
|
|
463
483
|
|
|
@@ -486,6 +506,7 @@ export class UpsertBuilder {
|
|
|
486
506
|
returnedIds: allIds,
|
|
487
507
|
});
|
|
488
508
|
|
|
509
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
489
510
|
return allIds as IdType<DatabaseSchemaExtend, TTable>[];
|
|
490
511
|
}
|
|
491
512
|
|
|
@@ -516,6 +537,7 @@ export class UpsertBuilder {
|
|
|
516
537
|
const whereColumns = Array.isArray(options.where) ? options.where : [options.where ?? "id"];
|
|
517
538
|
const rows = table.rows.map((_row) => {
|
|
518
539
|
const { uuid: _, ...row } = _row; // uuid 제외
|
|
540
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
519
541
|
return row as RowWithId<string>;
|
|
520
542
|
});
|
|
521
543
|
|
|
@@ -542,10 +564,7 @@ export class UpsertBuilder {
|
|
|
542
564
|
* - 자기 참조 없는 경우 : 모든 rows가 Level 0
|
|
543
565
|
* - 자기 참조 있는 경우 : 자기 참조 관계를 위상 정렬하여 레벨별로 그룹화
|
|
544
566
|
*/
|
|
545
|
-
private buildInsertLevels(
|
|
546
|
-
rows: Record<string, unknown>[],
|
|
547
|
-
tableName: string,
|
|
548
|
-
): { levels: Record<string, unknown>[][]; hasCircular: boolean } {
|
|
567
|
+
private buildInsertLevels(rows: UpsertRow[], tableName: string) {
|
|
549
568
|
// 1. 자기 참조가 없으면 한 레벨로 처리
|
|
550
569
|
const hasSelfRef = rows
|
|
551
570
|
.flatMap((row) => Object.values(row))
|
|
@@ -553,24 +572,26 @@ export class UpsertBuilder {
|
|
|
553
572
|
if (!hasSelfRef) return { levels: [rows], hasCircular: false };
|
|
554
573
|
|
|
555
574
|
// 2. uuid → row 매핑 (중복 uuid 방지)
|
|
556
|
-
const rowByUuid = new Map<string,
|
|
575
|
+
const rowByUuid = new Map<string, UpsertRow>();
|
|
557
576
|
for (const row of rows) {
|
|
577
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
558
578
|
const uuid = row.uuid as string | undefined;
|
|
559
579
|
if (!uuid) throw new Error(`buildInsertLevels: uuid가 없는 row -- in ${tableName}`);
|
|
560
580
|
rowByUuid.set(uuid, row);
|
|
561
581
|
}
|
|
562
582
|
|
|
563
583
|
let pending = Array.from(rowByUuid.values());
|
|
564
|
-
const levels:
|
|
584
|
+
const levels: UpsertRow[][] = [];
|
|
565
585
|
const inserted = new Set<string>();
|
|
566
586
|
|
|
567
587
|
// 3. 레벨별 분류
|
|
568
588
|
while (pending.length > 0) {
|
|
569
|
-
const currentLevel:
|
|
570
|
-
const nextPending:
|
|
589
|
+
const currentLevel: UpsertRow[] = [];
|
|
590
|
+
const nextPending: UpsertRow[] = [];
|
|
571
591
|
|
|
572
592
|
for (const row of pending) {
|
|
573
593
|
// 이 row가 참조하는 자기 참조들
|
|
594
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
574
595
|
const selfRefs = Object.values(row).filter(
|
|
575
596
|
(value) => isRefField(value) && value.of === tableName,
|
|
576
597
|
) as UBRef[];
|
|
@@ -596,6 +617,7 @@ export class UpsertBuilder {
|
|
|
596
617
|
// 레벨 확정 + inserted 갱신
|
|
597
618
|
levels.push(currentLevel);
|
|
598
619
|
for (const row of currentLevel) {
|
|
620
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
599
621
|
inserted.add(row.uuid as string);
|
|
600
622
|
}
|
|
601
623
|
|
package/src/dict/sd.ts
CHANGED
|
@@ -16,7 +16,10 @@ type MergedDictionary = {
|
|
|
16
16
|
? (...args: P) => string
|
|
17
17
|
: string;
|
|
18
18
|
};
|
|
19
|
-
|
|
19
|
+
interface DictionariesByLocale {
|
|
20
|
+
[locale: string]: MergedDictionary;
|
|
21
|
+
}
|
|
22
|
+
const dictionaries: DictionariesByLocale = {
|
|
20
23
|
ko,
|
|
21
24
|
en,
|
|
22
25
|
};
|
|
@@ -44,25 +47,32 @@ function getDictValue<K extends DictKey>(key: K, locale: string): SDReturnType<K
|
|
|
44
47
|
// 1. 지정된 locale에서 조회
|
|
45
48
|
const dict = dictionaries[locale];
|
|
46
49
|
if (dict?.[key] !== undefined) {
|
|
47
|
-
return
|
|
50
|
+
return /* SAFETY: 동기화된 사전 계약에서 문자열 브랜드만 추가한다. */ dict[
|
|
51
|
+
key
|
|
52
|
+
] as SDReturnType<K>;
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
// 2. default locale에서 조회
|
|
51
56
|
if (locale !== defaultLocale && dictionaries[defaultLocale]?.[key] !== undefined) {
|
|
52
|
-
return
|
|
57
|
+
return /* SAFETY: 동기화된 사전 계약에서 문자열 브랜드만 추가한다. */ dictionaries[
|
|
58
|
+
defaultLocale
|
|
59
|
+
][key] as SDReturnType<K>;
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
// 3. supported locales 순회
|
|
56
63
|
for (const supportedLocale of supportedLocales) {
|
|
57
64
|
if (supportedLocale !== locale && supportedLocale !== defaultLocale) {
|
|
58
65
|
if (dictionaries[supportedLocale]?.[key] !== undefined) {
|
|
59
|
-
return
|
|
66
|
+
return /* SAFETY: 동기화된 사전 계약에서 문자열 브랜드만 추가한다. */ dictionaries[
|
|
67
|
+
supportedLocale
|
|
68
|
+
][key] as SDReturnType<K>;
|
|
60
69
|
}
|
|
61
70
|
}
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
// 4. 모두 실패 시 key 반환
|
|
65
|
-
|
|
74
|
+
const missingValue: MergedDictionary[DictKey] = key;
|
|
75
|
+
return /* SAFETY: 누락 키 문자열에 LocalizedString 브랜드만 추가한다. */ missingValue as SDReturnType<K>;
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
/**
|
|
@@ -303,10 +303,7 @@ export class SonamuDictionary {
|
|
|
303
303
|
/**
|
|
304
304
|
* 함수 값들에서 사용되는 헬퍼 함수를 감지합니다.
|
|
305
305
|
*/
|
|
306
|
-
private detectUsedHelpers(entries: DictEntry[])
|
|
307
|
-
helpers: string[];
|
|
308
|
-
usesFormat: boolean;
|
|
309
|
-
} {
|
|
306
|
+
private detectUsedHelpers(entries: DictEntry[]) {
|
|
310
307
|
const functionEntries = entries.filter((e) => e.isFunction);
|
|
311
308
|
const helpers: string[] = [];
|
|
312
309
|
|
|
@@ -547,7 +544,7 @@ export class SonamuDictionary {
|
|
|
547
544
|
/**
|
|
548
545
|
* Project dict 파일([locale].ts)에서 딕셔너리 로드
|
|
549
546
|
*/
|
|
550
|
-
loadProjectDict(locale: string)
|
|
547
|
+
loadProjectDict(locale: string) {
|
|
551
548
|
const dictPath = path.join(Sonamu.apiRootPath, "src", "i18n", `${locale}.ts`);
|
|
552
549
|
if (!fs.existsSync(dictPath)) {
|
|
553
550
|
return { entries: [] };
|
|
@@ -795,7 +792,10 @@ export class SonamuDictionary {
|
|
|
795
792
|
}
|
|
796
793
|
|
|
797
794
|
const key = rowValues.key;
|
|
798
|
-
const source =
|
|
795
|
+
const source =
|
|
796
|
+
/* SAFETY: 동기화된 사전 키와 값 계약이 이 값의 타입을 보장한다. */ rowValues.source as
|
|
797
|
+
| "entity"
|
|
798
|
+
| "project";
|
|
799
799
|
|
|
800
800
|
if (!key || !source) continue;
|
|
801
801
|
|
package/src/dict/utils.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
import { isFunctionValue } from "../utils/runtime-value";
|
|
2
|
+
|
|
1
3
|
export type PluralForms = {
|
|
2
4
|
zero?: string | ((n: number) => string);
|
|
3
5
|
one?: string | ((n: number) => string);
|
|
4
6
|
other?: string | ((n: number) => string);
|
|
5
7
|
};
|
|
6
8
|
|
|
9
|
+
type PluralResolver = (n: number) => string;
|
|
10
|
+
|
|
11
|
+
function isPluralResolver(form: PluralForms[keyof PluralForms]): form is PluralResolver {
|
|
12
|
+
return isFunctionValue(form);
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
export function plural(n: number, forms: PluralForms): string {
|
|
8
16
|
const form = (n === 0 && forms.zero) || (n === 1 && forms.one) || forms.other;
|
|
9
|
-
return
|
|
17
|
+
return isPluralResolver(form) ? form(n) : (form ?? n.toString());
|
|
10
18
|
}
|
|
11
19
|
|
|
12
20
|
export function createFormat(locale: string) {
|
|
@@ -30,6 +30,19 @@ export type TableSpec = {
|
|
|
30
30
|
uniqueIndexes: EntityIndex[];
|
|
31
31
|
jsonColumns: string[];
|
|
32
32
|
};
|
|
33
|
+
|
|
34
|
+
function parseEntityJson(source: string) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(source);
|
|
37
|
+
} catch (cause) {
|
|
38
|
+
// JSON 파서 계약 밖의 오류는 구문 오류로 정규화하고 원인을 보존합니다.
|
|
39
|
+
if (!(cause instanceof SyntaxError)) {
|
|
40
|
+
throw new SyntaxError("entity.json 파싱 중 예기치 않은 오류가 발생했습니다.", { cause });
|
|
41
|
+
}
|
|
42
|
+
throw cause;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
class EntityManagerClass {
|
|
34
47
|
private entities: Map<string, Entity> = new Map();
|
|
35
48
|
public modulePaths: Map<string, string> = new Map();
|
|
@@ -37,23 +50,25 @@ class EntityManagerClass {
|
|
|
37
50
|
public isAutoloaded: boolean = false;
|
|
38
51
|
|
|
39
52
|
// 경로 전달받아 모든 entity.json 파일 로드
|
|
40
|
-
async autoload(
|
|
53
|
+
async autoload(doSilent: boolean = false) {
|
|
41
54
|
if (this.isAutoloaded) {
|
|
42
55
|
return;
|
|
43
56
|
}
|
|
44
57
|
const pathPattern = path.join(Sonamu.apiRootPath, "/src/application/**/*.entity.json");
|
|
45
58
|
|
|
46
59
|
for await (const file of glob(path.resolve(pathPattern))) {
|
|
47
|
-
const json =
|
|
60
|
+
const json = parseEntityJson((await readFile(file)).toString());
|
|
48
61
|
|
|
49
62
|
// entity.json 스키마 검증
|
|
50
63
|
const error = this.schemaValidate(json);
|
|
51
64
|
if (error) {
|
|
52
65
|
const relativePath = path.relative(Sonamu.apiRootPath, file);
|
|
53
66
|
const errorMessage = prettifyError(error);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
67
|
+
if (!doSilent) {
|
|
68
|
+
console.error(
|
|
69
|
+
chalk.red(`Invalid entity.json schema: ${relativePath}\n${chalk.yellow(errorMessage)}`),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
57
72
|
}
|
|
58
73
|
|
|
59
74
|
await this.register(json, { deferSearchTextJsonSourceValidation: true });
|
|
@@ -65,7 +80,7 @@ class EntityManagerClass {
|
|
|
65
80
|
this.isAutoloaded = true;
|
|
66
81
|
}
|
|
67
82
|
|
|
68
|
-
schemaValidate(json:
|
|
83
|
+
schemaValidate<Value>(json: Value) {
|
|
69
84
|
const result = EntityJsonSchema.safeParse(json);
|
|
70
85
|
return result.success ? null : result.error;
|
|
71
86
|
}
|
|
@@ -180,7 +195,9 @@ class EntityManagerClass {
|
|
|
180
195
|
}
|
|
181
196
|
|
|
182
197
|
getByTable(table: string): Entity {
|
|
183
|
-
const entity = Array.from(this.entities.values()).find(
|
|
198
|
+
const entity = Array.from(this.entities.values()).find(
|
|
199
|
+
(candidate) => candidate.table === table,
|
|
200
|
+
);
|
|
184
201
|
if (entity === undefined) {
|
|
185
202
|
throw new Error(`존재하지 않는 Entity 요청 ${table}`);
|
|
186
203
|
}
|
|
@@ -242,7 +259,7 @@ class EntityManagerClass {
|
|
|
242
259
|
return tableSpec;
|
|
243
260
|
}
|
|
244
261
|
|
|
245
|
-
getNamesFromId(entityId: string)
|
|
262
|
+
getNamesFromId(entityId: string) {
|
|
246
263
|
// entityId가 단복수 동형 단어인 경우 List 붙여서 생성
|
|
247
264
|
const pluralized =
|
|
248
265
|
inflection.pluralize(entityId) === entityId
|
|
@@ -258,7 +275,7 @@ class EntityManagerClass {
|
|
|
258
275
|
capitalPlural: pluralized,
|
|
259
276
|
upper: entityId.toUpperCase(),
|
|
260
277
|
constant: inflection.underscore(entityId).toUpperCase(),
|
|
261
|
-
};
|
|
278
|
+
} satisfies EntityNamesRecord;
|
|
262
279
|
}
|
|
263
280
|
|
|
264
281
|
/**
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
isRelationProp,
|
|
15
15
|
isSubsetDefWithCone,
|
|
16
16
|
} from "../types/types";
|
|
17
|
+
import { isStringValue } from "../utils/runtime-value";
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Entity의 템플릿 cone을 생성합니다.
|
|
@@ -21,15 +22,7 @@ import {
|
|
|
21
22
|
* LLM을 사용하지 않고 faker-mappings.ts를 활용하여 기본 cone을 생성합니다.
|
|
22
23
|
* stub entity 생성 시 자동으로 호출되어 최소한의 cone 메타데이터를 제공합니다.
|
|
23
24
|
*/
|
|
24
|
-
export function generateTemplateCones(
|
|
25
|
-
entity: EntityJson,
|
|
26
|
-
locale: "ko" | "en" | "ja" = "ko",
|
|
27
|
-
): {
|
|
28
|
-
entityCone?: Cone;
|
|
29
|
-
propCones: Record<string, Cone>;
|
|
30
|
-
subsetCones: Record<string, Cone>;
|
|
31
|
-
enumCones: Record<string, Cone>;
|
|
32
|
-
} {
|
|
25
|
+
export function generateTemplateCones(entity: EntityJson, locale: "ko" | "en" | "ja" = "ko") {
|
|
33
26
|
const mapping = fakerMappings[locale];
|
|
34
27
|
|
|
35
28
|
if (!mapping) {
|
|
@@ -77,6 +70,7 @@ export function generateTemplateCones(
|
|
|
77
70
|
};
|
|
78
71
|
return acc;
|
|
79
72
|
},
|
|
73
|
+
// SAFETY: 스키마 검증과 메타데이터 계약이 이 타입을 보장합니다.
|
|
80
74
|
{} as Record<string, { note: string }>,
|
|
81
75
|
),
|
|
82
76
|
};
|
|
@@ -188,6 +182,7 @@ function shouldHaveDataSource(prop: EntityProp): boolean {
|
|
|
188
182
|
|
|
189
183
|
// OneToOne은 hasJoinColumn: true인 경우에만 dataSource 필요
|
|
190
184
|
if (isOneToOneRelationProp(prop)) {
|
|
185
|
+
// SAFETY: 스키마 검증과 메타데이터 계약이 이 타입을 보장합니다.
|
|
191
186
|
return (prop as OneToOneRelationProp).hasJoinColumn;
|
|
192
187
|
}
|
|
193
188
|
|
|
@@ -199,7 +194,7 @@ function shouldHaveDataSource(prop: EntityProp): boolean {
|
|
|
199
194
|
*/
|
|
200
195
|
function getSubsetScale(key: string, subset: SubsetDef, locale: "ko" | "en" | "ja"): string {
|
|
201
196
|
const fields = isSubsetDefWithCone(subset) ? subset.fields : subset;
|
|
202
|
-
const fieldNames = fields.map((f) => (
|
|
197
|
+
const fieldNames = fields.map((f) => (isStringValue(f) ? f : f.field)).join(", ");
|
|
203
198
|
|
|
204
199
|
const templates = {
|
|
205
200
|
ko: `${key} 서브셋. 포함된 필드: ${fieldNames}`,
|