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
package/src/compress/compress.ts
CHANGED
|
@@ -10,22 +10,35 @@ export const CompressPresets = {
|
|
|
10
10
|
/** 기본 설정 (threshold: 1024, br > gzip > deflate) */
|
|
11
11
|
default: {
|
|
12
12
|
threshold: 1024,
|
|
13
|
-
encodings:
|
|
13
|
+
encodings: /* SAFETY: 호출 경계의 선행 검증과 소유 타입 계약이 이 값의 타입을 보장한다. */ [
|
|
14
|
+
"br",
|
|
15
|
+
"gzip",
|
|
16
|
+
"deflate",
|
|
17
|
+
] as ("br" | "gzip" | "deflate")[],
|
|
14
18
|
},
|
|
15
19
|
/** 적극적 압축 (threshold: 256) */
|
|
16
20
|
aggressive: {
|
|
17
21
|
threshold: 256,
|
|
18
|
-
encodings:
|
|
22
|
+
encodings: /* SAFETY: 호출 경계의 선행 검증과 소유 타입 계약이 이 값의 타입을 보장한다. */ [
|
|
23
|
+
"br",
|
|
24
|
+
"gzip",
|
|
25
|
+
"deflate",
|
|
26
|
+
] as ("br" | "gzip" | "deflate")[],
|
|
19
27
|
},
|
|
20
28
|
/** 보수적 압축 (threshold: 4096, gzip만) */
|
|
21
29
|
conservative: {
|
|
22
30
|
threshold: 4096,
|
|
23
|
-
encodings:
|
|
31
|
+
encodings: /* SAFETY: 호출 경계의 선행 검증과 소유 타입 계약이 이 값의 타입을 보장한다. */ [
|
|
32
|
+
"gzip",
|
|
33
|
+
"deflate",
|
|
34
|
+
] as ("gzip" | "deflate")[],
|
|
24
35
|
},
|
|
25
36
|
/** gzip만 사용 */
|
|
26
37
|
gzipOnly: {
|
|
27
38
|
threshold: 1024,
|
|
28
|
-
encodings:
|
|
39
|
+
encodings: /* SAFETY: 호출 경계의 선행 검증과 소유 타입 계약이 이 값의 타입을 보장한다. */ [
|
|
40
|
+
"gzip",
|
|
41
|
+
] as ["gzip"],
|
|
29
42
|
},
|
|
30
43
|
} as const;
|
|
31
44
|
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
|
|
4
|
+
import { type LanguageModel } from "ai";
|
|
5
|
+
|
|
4
6
|
import { type Cone, type EntityJson } from "../types/types";
|
|
7
|
+
import { isObjectValue } from "../utils/runtime-value";
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* Cone 생성 컨텍스트
|
|
@@ -29,16 +32,32 @@ export type ConeGenerationResult = {
|
|
|
29
32
|
tokensUsed: number;
|
|
30
33
|
};
|
|
31
34
|
|
|
35
|
+
export type ConeTextGenerator = (request: {
|
|
36
|
+
model: LanguageModel;
|
|
37
|
+
prompt: string;
|
|
38
|
+
}) => Promise<{ text: string; usage?: { totalTokens?: number } }>;
|
|
39
|
+
|
|
40
|
+
export type ConeGeneratorDependencies = {
|
|
41
|
+
generateText?: ConeTextGenerator;
|
|
42
|
+
};
|
|
43
|
+
|
|
32
44
|
/**
|
|
33
45
|
* LLM을 사용하여 Entity의 cone 메타데이터를 생성합니다.
|
|
34
46
|
*
|
|
35
47
|
* @param context - Entity 정보와 생성 옵션
|
|
36
48
|
* @returns 생성된 cone 메타데이터
|
|
37
49
|
*/
|
|
38
|
-
export async function generateCones(
|
|
50
|
+
export async function generateCones(
|
|
51
|
+
context: ConeGenerationContext,
|
|
52
|
+
dependencies: ConeGeneratorDependencies = {},
|
|
53
|
+
): Promise<ConeGenerationResult> {
|
|
39
54
|
const apiKey = getApiKey();
|
|
40
55
|
const prompt = buildPrompt(context);
|
|
41
|
-
const { text: responseText, tokensUsed } = await callAnthropicAPI(
|
|
56
|
+
const { text: responseText, tokensUsed } = await callAnthropicAPI(
|
|
57
|
+
prompt,
|
|
58
|
+
apiKey,
|
|
59
|
+
dependencies.generateText,
|
|
60
|
+
);
|
|
42
61
|
const result = parseConeResponse(responseText);
|
|
43
62
|
result.tokensUsed = tokensUsed;
|
|
44
63
|
|
|
@@ -269,11 +288,17 @@ IMPORTANT: Return pure JSON only. Do NOT wrap in markdown code blocks.`;
|
|
|
269
288
|
async function callAnthropicAPI(
|
|
270
289
|
prompt: string,
|
|
271
290
|
apiKey: string,
|
|
291
|
+
injectedGenerateText?: ConeTextGenerator,
|
|
272
292
|
): Promise<{ text: string; tokensUsed: number }> {
|
|
273
293
|
try {
|
|
274
294
|
// @ai-sdk/anthropic과 ai 패키지는 optional dependency이므로 동적 import
|
|
275
295
|
const { createAnthropic } = await import("@ai-sdk/anthropic");
|
|
276
|
-
const
|
|
296
|
+
const generateText: ConeTextGenerator =
|
|
297
|
+
injectedGenerateText ??
|
|
298
|
+
(async (request) => {
|
|
299
|
+
const ai = await import("ai");
|
|
300
|
+
return ai.generateText(request);
|
|
301
|
+
});
|
|
277
302
|
|
|
278
303
|
const anthropic = createAnthropic({
|
|
279
304
|
apiKey,
|
|
@@ -291,8 +316,11 @@ async function callAnthropicAPI(
|
|
|
291
316
|
|
|
292
317
|
return { text, tokensUsed };
|
|
293
318
|
} catch (error: unknown) {
|
|
294
|
-
if (error &&
|
|
295
|
-
const statusCode =
|
|
319
|
+
if (error && isObjectValue(error) && "statusCode" in error) {
|
|
320
|
+
const statusCode =
|
|
321
|
+
/* SAFETY: 호출 경계의 선행 검증과 소유 타입 계약이 이 값의 타입을 보장한다. */ (
|
|
322
|
+
error as { statusCode: number }
|
|
323
|
+
).statusCode;
|
|
296
324
|
if (statusCode === 429) {
|
|
297
325
|
throw new Error("Rate limit exceeded. Please try again later.", { cause: error });
|
|
298
326
|
}
|
|
@@ -317,7 +345,7 @@ function parseConeResponse(text: string): ConeGenerationResult {
|
|
|
317
345
|
try {
|
|
318
346
|
const parsed = JSON.parse(jsonText);
|
|
319
347
|
|
|
320
|
-
if (!parsed.propCones ||
|
|
348
|
+
if (!parsed.propCones || !isObjectValue(parsed.propCones)) {
|
|
321
349
|
throw new Error("Invalid response: propCones is required and must be an object");
|
|
322
350
|
}
|
|
323
351
|
|
|
@@ -75,6 +75,7 @@ describe("DBClass.generateDBConfig", () => {
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
it("fails fast when legacy database.name or database.environments keys are present", () => {
|
|
78
|
+
// SAFETY: 테스트 입력은 선언된 타입 검증 시나리오에 맞게 고정됩니다.
|
|
78
79
|
const legacyConfig = {
|
|
79
80
|
database: "pg",
|
|
80
81
|
name: "miomock",
|
|
@@ -37,6 +37,20 @@ function usersQuery(): Puri<TestSchema, { users: TestSchema["users"] }, TestSche
|
|
|
37
37
|
return new Puri(db, "users");
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function withJsonTableSpec<T>(jsonColumns: string[], callback: () => T): T {
|
|
41
|
+
const tableSpecSpy = vi.spyOn(EntityManager, "getTableSpec").mockReturnValue({
|
|
42
|
+
name: "users",
|
|
43
|
+
uniqueIndexes: [],
|
|
44
|
+
jsonColumns,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
return callback();
|
|
49
|
+
} finally {
|
|
50
|
+
tableSpecSpy.mockRestore();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
afterAll(async () => {
|
|
41
55
|
await db.destroy();
|
|
42
56
|
});
|
|
@@ -104,7 +118,8 @@ describe("Puri JSONB containment", () => {
|
|
|
104
118
|
]);
|
|
105
119
|
|
|
106
120
|
const query = usersQuery();
|
|
107
|
-
|
|
121
|
+
// SAFETY: 직렬화 실패 경로를 검증하기 위해 타입 계약 밖의 값을 의도적으로 전달합니다.
|
|
122
|
+
expect(() => query.whereJsonSupersetOf("payload", undefined as never)).toThrow(
|
|
108
123
|
"Puri JSONB containment value must be JSON-serializable; JSON.stringify returned undefined.",
|
|
109
124
|
);
|
|
110
125
|
expect(query.rawQuery().toSQL().sql).toBe('select * from "users"');
|
|
@@ -112,20 +127,6 @@ describe("Puri JSONB containment", () => {
|
|
|
112
127
|
});
|
|
113
128
|
|
|
114
129
|
describe("Puri onConflict JSON 직렬화", () => {
|
|
115
|
-
function withJsonTableSpec<T>(jsonColumns: string[], callback: () => T): T {
|
|
116
|
-
const tableSpecSpy = vi.spyOn(EntityManager, "getTableSpec").mockReturnValue({
|
|
117
|
-
name: "users",
|
|
118
|
-
uniqueIndexes: [],
|
|
119
|
-
jsonColumns,
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
return callback();
|
|
124
|
-
} finally {
|
|
125
|
-
tableSpecSpy.mockRestore();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
130
|
it("객체 update의 배열을 JSON 문자열 binding으로 변환한다", () => {
|
|
130
131
|
const binding = withJsonTableSpec(["tags"], () =>
|
|
131
132
|
usersQuery()
|
|
@@ -14,6 +14,7 @@ type TransactionScopeDB = DBClass & {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
function createTransactionWrapper(): PuriTransactionWrapper {
|
|
17
|
+
// SAFETY: 테스트 입력은 선언된 타입 검증 시나리오에 맞게 고정됩니다.
|
|
17
18
|
return new PuriTransactionWrapper({} as Knex.Transaction, new UpsertBuilder());
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -32,6 +33,7 @@ function expectScopeRunner(db: TransactionScopeDB) {
|
|
|
32
33
|
|
|
33
34
|
describe("DB.runWithTransactionScope", () => {
|
|
34
35
|
it("저장소가 없어도 루트 scope를 설치하고 콜백 결과를 반환한 뒤 정리한다", async () => {
|
|
36
|
+
// SAFETY: 테스트 입력은 선언된 타입 검증 시나리오에 맞게 고정됩니다.
|
|
35
37
|
const db = new DBClass() as TransactionScopeDB;
|
|
36
38
|
const transaction = createTransactionWrapper();
|
|
37
39
|
const runScope = expectScopeRunner(db);
|
|
@@ -53,6 +55,7 @@ describe("DB.runWithTransactionScope", () => {
|
|
|
53
55
|
});
|
|
54
56
|
|
|
55
57
|
it("scope 안에서 생성된 detached descendant가 완료된 자식 트랜잭션을 다시 사용하지 않는다", async () => {
|
|
58
|
+
// SAFETY: 테스트 입력은 선언된 타입 검증 시나리오에 맞게 고정됩니다.
|
|
56
59
|
const db = new DBClass() as TransactionScopeDB;
|
|
57
60
|
const parentTransaction = createTransactionWrapper();
|
|
58
61
|
const childTransaction = createTransactionWrapper();
|
|
@@ -119,6 +122,7 @@ describe("DB.runWithTransactionScope", () => {
|
|
|
119
122
|
});
|
|
120
123
|
|
|
121
124
|
it("같거나 다른 preset의 중첩 범위를 복원하고 같은 오류를 다시 던진다", async () => {
|
|
125
|
+
// SAFETY: 테스트 입력은 선언된 타입 검증 시나리오에 맞게 고정됩니다.
|
|
122
126
|
const db = new DBClass() as TransactionScopeDB;
|
|
123
127
|
const outer = createTransactionWrapper();
|
|
124
128
|
const samePresetInner = createTransactionWrapper();
|
|
@@ -157,6 +161,7 @@ describe("DB.runWithTransactionScope", () => {
|
|
|
157
161
|
});
|
|
158
162
|
|
|
159
163
|
it("겹치는 sibling 범위가 완료 순서와 무관하게 서로의 활성 트랜잭션을 보지 않는다", async () => {
|
|
164
|
+
// SAFETY: 테스트 입력은 선언된 타입 검증 시나리오에 맞게 고정됩니다.
|
|
160
165
|
const db = new DBClass() as TransactionScopeDB;
|
|
161
166
|
const parentTransaction = createTransactionWrapper();
|
|
162
167
|
const firstTransaction = createTransactionWrapper();
|
|
@@ -97,6 +97,7 @@ function generateBatchUpdateSQL<Id extends string>(
|
|
|
97
97
|
const cases: string[] = [];
|
|
98
98
|
|
|
99
99
|
for (const key of keySet) {
|
|
100
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
100
101
|
if (identifiers.includes(key as Id)) continue;
|
|
101
102
|
|
|
102
103
|
const caseBindings: (string | number | boolean | null)[] = [];
|
|
@@ -11,6 +11,7 @@ import { normalizeFilterQuery, validateSonamuFilters } from "../filter/utils";
|
|
|
11
11
|
import { convertDomainToCategory } from "../logger/category";
|
|
12
12
|
import { type DatabaseSchemaExtend, type SonamuQueryMode } from "../types/types";
|
|
13
13
|
import { type ListResult } from "../utils/model";
|
|
14
|
+
import { isObjectValue } from "../utils/runtime-value";
|
|
14
15
|
import { getJoinTables, getTableNamesFromWhere } from "../utils/sql-parser";
|
|
15
16
|
import { type EnhancerMap, type ResolveSubsetIntersection } from "./base-model.types";
|
|
16
17
|
import { type DBPreset } from "./db";
|
|
@@ -25,7 +26,18 @@ import { PuriWrapper } from "./puri-wrapper";
|
|
|
25
26
|
import { type UnionExtractedTTables } from "./puri.types";
|
|
26
27
|
import { UpsertBuilder } from "./upsert-builder";
|
|
27
28
|
|
|
28
|
-
type
|
|
29
|
+
type DatabaseRecordValue =
|
|
30
|
+
| string
|
|
31
|
+
| number
|
|
32
|
+
| boolean
|
|
33
|
+
| bigint
|
|
34
|
+
| Date
|
|
35
|
+
| Buffer
|
|
36
|
+
| Knex.Raw
|
|
37
|
+
| null
|
|
38
|
+
| DatabaseRecordValue[]
|
|
39
|
+
| { [key: string]: DatabaseRecordValue };
|
|
40
|
+
type DatabaseRecord = Record<string, DatabaseRecordValue | undefined>;
|
|
29
41
|
|
|
30
42
|
/**
|
|
31
43
|
* 모든 Model 클래스의 기본 클래스
|
|
@@ -37,7 +49,7 @@ type UnknownDBRecord = Record<string, unknown>;
|
|
|
37
49
|
*/
|
|
38
50
|
export class BaseModelClass<
|
|
39
51
|
TSubsetKey extends string = never,
|
|
40
|
-
TSubsetMapping extends
|
|
52
|
+
TSubsetMapping extends { [K in TSubsetKey]: TSubsetMapping[K] } = never,
|
|
41
53
|
TSubsetQueries extends Record<TSubsetKey, PuriSubsetFn> = never,
|
|
42
54
|
TLoaderQueries extends PuriLoaderQueries<TSubsetKey> = never,
|
|
43
55
|
> {
|
|
@@ -82,7 +94,7 @@ export class BaseModelClass<
|
|
|
82
94
|
|
|
83
95
|
async getInsertedIds(
|
|
84
96
|
wdb: Knex,
|
|
85
|
-
rows:
|
|
97
|
+
rows: DatabaseRecord[],
|
|
86
98
|
tableName: string,
|
|
87
99
|
unqKeyFields: string[],
|
|
88
100
|
chunkSize: number = 500,
|
|
@@ -102,6 +114,7 @@ export class BaseModelClass<
|
|
|
102
114
|
} else {
|
|
103
115
|
whereInField = unqKeyFields[0];
|
|
104
116
|
selectField = unqKeyFields[0];
|
|
117
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
105
118
|
unqKeys = rows.map((row) => row[unqKeyFields[0]] as string);
|
|
106
119
|
}
|
|
107
120
|
|
|
@@ -109,9 +122,14 @@ export class BaseModelClass<
|
|
|
109
122
|
for (const items of cluster(unqKeys, chunkSize)) {
|
|
110
123
|
const dbRows = await wdb(tableName)
|
|
111
124
|
.select("id", wdb.raw(selectField))
|
|
112
|
-
|
|
125
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
126
|
+
.whereIn(
|
|
127
|
+
/* SAFETY: Knex 런타임은 컬럼 위치의 Raw 표현식을 지원하지만 선언 타입에는 누락되어 있습니다. */
|
|
128
|
+
whereInField as string,
|
|
129
|
+
items,
|
|
130
|
+
);
|
|
113
131
|
resultIds = resultIds.concat(
|
|
114
|
-
dbRows.map((dbRow:
|
|
132
|
+
dbRows.map((dbRow: DatabaseRecord) => parseInt(String(dbRow.id))),
|
|
115
133
|
);
|
|
116
134
|
}
|
|
117
135
|
|
|
@@ -137,16 +155,18 @@ export class BaseModelClass<
|
|
|
137
155
|
NonAllowedAsSingleTable: { __fulltext__: true };
|
|
138
156
|
};
|
|
139
157
|
|
|
158
|
+
function onSubset<S extends TSubsetKey>(subset: S): ReturnType<TSubsetQueries[S]>;
|
|
159
|
+
function onSubset<Arr extends readonly TSubsetKey[]>(
|
|
160
|
+
subsets: [...Arr],
|
|
161
|
+
): ResolveSubsetIntersection<Arr, TSubsetQueries>;
|
|
162
|
+
function onSubset(_subset: TSubsetKey | readonly TSubsetKey[]) {
|
|
163
|
+
return qb;
|
|
164
|
+
}
|
|
165
|
+
|
|
140
166
|
return {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
<S extends TSubsetKey>(subset: S): ReturnType<TSubsetQueries[S]>;
|
|
145
|
-
// 키 배열 -> 교집합 반환
|
|
146
|
-
<Arr extends readonly TSubsetKey[]>(
|
|
147
|
-
subsets: [...Arr],
|
|
148
|
-
): ResolveSubsetIntersection<Arr, TSubsetQueries>;
|
|
149
|
-
},
|
|
167
|
+
// SAFETY: 같은 Puri 인스턴스에 단일 테이블 접근 제한용 타입 마커만 추가합니다.
|
|
168
|
+
qb: qb as Puri<DatabaseSchemaExtend, QBTables, {}>,
|
|
169
|
+
onSubset,
|
|
150
170
|
};
|
|
151
171
|
}
|
|
152
172
|
|
|
@@ -177,11 +197,11 @@ export class BaseModelClass<
|
|
|
177
197
|
async executeSubsetQuery<
|
|
178
198
|
T extends TSubsetKey,
|
|
179
199
|
TComputedResults extends InferAllSubsets<TSubsetQueries, TLoaderQueries>,
|
|
200
|
+
TFilter extends object,
|
|
180
201
|
LP extends {
|
|
181
202
|
num?: number;
|
|
182
203
|
page?: number;
|
|
183
204
|
queryMode?: SonamuQueryMode;
|
|
184
|
-
sonamuFilter?: Record<string, unknown>;
|
|
185
205
|
},
|
|
186
206
|
>(
|
|
187
207
|
params: {
|
|
@@ -191,7 +211,7 @@ export class BaseModelClass<
|
|
|
191
211
|
num: number;
|
|
192
212
|
page: number;
|
|
193
213
|
queryMode?: SonamuQueryMode;
|
|
194
|
-
sonamuFilter?:
|
|
214
|
+
sonamuFilter?: TFilter;
|
|
195
215
|
};
|
|
196
216
|
debug?: boolean;
|
|
197
217
|
optimizeCountQuery?: boolean;
|
|
@@ -217,6 +237,7 @@ export class BaseModelClass<
|
|
|
217
237
|
const total = await this.executeCountQuery(qb, queryParams, debug, optimizeCountQuery);
|
|
218
238
|
|
|
219
239
|
if (queryParams?.queryMode === "count") {
|
|
240
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
220
241
|
return { total } as ListResult<LP, TSubsetMapping[T]>;
|
|
221
242
|
}
|
|
222
243
|
|
|
@@ -232,7 +253,9 @@ export class BaseModelClass<
|
|
|
232
253
|
);
|
|
233
254
|
|
|
234
255
|
// Enhancer 적용
|
|
256
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
235
257
|
const enhancer = (params as any).enhancers?.[subset];
|
|
258
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
236
259
|
const enhancedRows = (await Promise.all(
|
|
237
260
|
computedRows.map((row) => enhancer?.(row) ?? row),
|
|
238
261
|
)) as TSubsetMapping[T][];
|
|
@@ -247,9 +270,11 @@ export class BaseModelClass<
|
|
|
247
270
|
|
|
248
271
|
if (queryParams.queryMode === "list") {
|
|
249
272
|
// 리스트만 리턴
|
|
273
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
250
274
|
return { rows } as ListResult<LP, TSubsetMapping[T]>;
|
|
251
275
|
} else {
|
|
252
276
|
// 둘다 리턴
|
|
277
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
253
278
|
return { rows, total } as ListResult<LP, TSubsetMapping[T]>;
|
|
254
279
|
}
|
|
255
280
|
}
|
|
@@ -272,7 +297,7 @@ export class BaseModelClass<
|
|
|
272
297
|
* @param qb Puri QueryBuilder 인스턴스
|
|
273
298
|
* @param filters FilterQuery 객체
|
|
274
299
|
*/
|
|
275
|
-
protected applySonamuFilters<TEntity
|
|
300
|
+
protected applySonamuFilters<TEntity>(
|
|
276
301
|
qb: Puri<any, any, any>,
|
|
277
302
|
filters?: FilterQuery<TEntity>,
|
|
278
303
|
): void {
|
|
@@ -284,6 +309,7 @@ export class BaseModelClass<
|
|
|
284
309
|
validateSonamuFilters(filters, entity);
|
|
285
310
|
|
|
286
311
|
// 2. 검증된 필터 적용
|
|
312
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
287
313
|
const puri = qb as any;
|
|
288
314
|
|
|
289
315
|
for (const [field, condition] of Object.entries(filters)) {
|
|
@@ -293,13 +319,14 @@ export class BaseModelClass<
|
|
|
293
319
|
const fullField = entity.getFullFieldName(field);
|
|
294
320
|
|
|
295
321
|
// 직접 값 (eq와 동일)
|
|
296
|
-
if (
|
|
322
|
+
if (!isObjectValue(condition) || Array.isArray(condition)) {
|
|
297
323
|
puri.where(fullField, condition);
|
|
298
324
|
continue;
|
|
299
325
|
}
|
|
300
326
|
|
|
301
327
|
// 연산자 객체
|
|
302
328
|
for (const [operator, value] of Object.entries(condition)) {
|
|
329
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
303
330
|
this.applyOperator(qb, fullField, operator as FilterOperator, value);
|
|
304
331
|
}
|
|
305
332
|
}
|
|
@@ -308,12 +335,13 @@ export class BaseModelClass<
|
|
|
308
335
|
/**
|
|
309
336
|
* 단일 연산자를 QueryBuilder에 적용
|
|
310
337
|
*/
|
|
311
|
-
private applyOperator(
|
|
338
|
+
private applyOperator<Value>(
|
|
312
339
|
qb: Puri<any, any, any>,
|
|
313
340
|
field: string,
|
|
314
341
|
operator: FilterOperator,
|
|
315
|
-
value:
|
|
342
|
+
value: Value,
|
|
316
343
|
): void {
|
|
344
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
317
345
|
const puri = qb as any;
|
|
318
346
|
|
|
319
347
|
switch (operator) {
|
|
@@ -394,14 +422,14 @@ export class BaseModelClass<
|
|
|
394
422
|
* 중첩 필드 삭제 (배열 내 객체도 처리)
|
|
395
423
|
*/
|
|
396
424
|
deleteField(obj: any, parts: string[]): void {
|
|
397
|
-
if (!obj ||
|
|
425
|
+
if (!obj || !isObjectValue(obj)) {
|
|
398
426
|
return;
|
|
399
427
|
}
|
|
400
428
|
|
|
401
429
|
if (parts.length === 1) {
|
|
402
430
|
if (Array.isArray(obj)) {
|
|
403
431
|
obj.forEach((item) => {
|
|
404
|
-
if (item &&
|
|
432
|
+
if (item && isObjectValue(item)) {
|
|
405
433
|
delete item[parts[0]];
|
|
406
434
|
}
|
|
407
435
|
});
|
|
@@ -416,7 +444,7 @@ export class BaseModelClass<
|
|
|
416
444
|
|
|
417
445
|
if (Array.isArray(next)) {
|
|
418
446
|
next.map((item) => this.deleteField(item, rest));
|
|
419
|
-
} else if (next &&
|
|
447
|
+
} else if (next && isObjectValue(next)) {
|
|
420
448
|
this.deleteField(next, rest);
|
|
421
449
|
}
|
|
422
450
|
}
|
|
@@ -496,6 +524,7 @@ export class BaseModelClass<
|
|
|
496
524
|
}
|
|
497
525
|
|
|
498
526
|
// 로더 처리
|
|
527
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
499
528
|
const loaders = (this.loaderQueries as any)[subset];
|
|
500
529
|
if (loaders && Array.isArray(loaders)) {
|
|
501
530
|
unloadedRows = await this.processLoaders(unloadedRows, loaders, debug, puriWrapper);
|
|
@@ -525,6 +554,7 @@ export class BaseModelClass<
|
|
|
525
554
|
resolveLoaderQb.debug();
|
|
526
555
|
}
|
|
527
556
|
|
|
557
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
528
558
|
let loadedRows = (await resolveLoaderQb) as any[];
|
|
529
559
|
|
|
530
560
|
// 중첩 loaders가 있으면 재귀 처리
|
|
@@ -549,8 +579,10 @@ export class BaseModelClass<
|
|
|
549
579
|
* - `user__name` → `{ user: { name } }`
|
|
550
580
|
* - nullable relation의 경우 id 필드가 null이면 객체 자체를 null로
|
|
551
581
|
*/
|
|
552
|
-
hydrate<T extends
|
|
582
|
+
hydrate<T extends object>(rows: T[]): T[] {
|
|
583
|
+
// SAFETY: 쿼리 빌더의 제네릭 계약과 선행 검증이 이 타입을 보장합니다.
|
|
553
584
|
return rows.map((row: T) => {
|
|
585
|
+
const rowValues = new Map(Object.entries(row));
|
|
554
586
|
// nullable relation 처리: 그룹의 id 필드가 null이면 객체 전체를 null로
|
|
555
587
|
const nestedKeys = Object.keys(row).filter((key) => key.includes("__"));
|
|
556
588
|
const groups = Object.groupBy(nestedKeys, (key) => key.split("__")[0]);
|
|
@@ -564,26 +596,27 @@ export class BaseModelClass<
|
|
|
564
596
|
const idField = `${groupKey}__id`;
|
|
565
597
|
if (idField in row) {
|
|
566
598
|
// id 필드가 null이면 객체 전체가 null
|
|
567
|
-
return
|
|
599
|
+
return rowValues.get(idField) === null;
|
|
568
600
|
}
|
|
569
601
|
|
|
570
602
|
// id 필드가 없으면 기존 로직: 모든 필드가 null인지 확인
|
|
571
|
-
return fields.every(
|
|
572
|
-
(field)
|
|
573
|
-
|
|
574
|
-
);
|
|
603
|
+
return fields.every((field) => {
|
|
604
|
+
const fieldValue = rowValues.get(field);
|
|
605
|
+
return fieldValue === null || (Array.isArray(fieldValue) && fieldValue.length === 0);
|
|
606
|
+
});
|
|
575
607
|
})
|
|
576
608
|
.map(([key]) => key);
|
|
577
609
|
|
|
578
|
-
|
|
610
|
+
let hydrated: DatabaseRecord = Object.fromEntries([]);
|
|
611
|
+
for (const field of Object.keys(row)) {
|
|
612
|
+
const fieldValue = rowValues.get(field);
|
|
579
613
|
if (!field.includes("__")) {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
return r;
|
|
614
|
+
const hydratedValue =
|
|
615
|
+
Array.isArray(fieldValue) && isObject(fieldValue[0])
|
|
616
|
+
? this.hydrate(fieldValue)
|
|
617
|
+
: fieldValue;
|
|
618
|
+
Object.assign(hydrated, { [field]: hydratedValue });
|
|
619
|
+
continue;
|
|
587
620
|
}
|
|
588
621
|
|
|
589
622
|
// 중첩 필드 처리: user__name → user[name]
|
|
@@ -595,20 +628,18 @@ export class BaseModelClass<
|
|
|
595
628
|
.map((part) => `[${part}]`)
|
|
596
629
|
.join("");
|
|
597
630
|
|
|
598
|
-
|
|
599
|
-
|
|
631
|
+
hydrated = set(
|
|
632
|
+
hydrated,
|
|
600
633
|
objPath,
|
|
601
|
-
|
|
602
|
-
? this.hydrate(
|
|
603
|
-
:
|
|
634
|
+
fieldValue && Array.isArray(fieldValue) && isObject(fieldValue[0])
|
|
635
|
+
? this.hydrate(fieldValue)
|
|
636
|
+
: fieldValue,
|
|
604
637
|
);
|
|
605
|
-
|
|
606
|
-
return r;
|
|
607
|
-
}, {} as UnknownDBRecord);
|
|
638
|
+
}
|
|
608
639
|
|
|
609
640
|
// null relation 처리
|
|
610
641
|
nullKeys.forEach((nullKey) => {
|
|
611
|
-
hydrated[nullKey]
|
|
642
|
+
Object.assign(hydrated, { [nullKey]: null });
|
|
612
643
|
});
|
|
613
644
|
|
|
614
645
|
return hydrated;
|
|
@@ -622,8 +653,8 @@ export class BaseModelClass<
|
|
|
622
653
|
*/
|
|
623
654
|
type EnhancerParam<
|
|
624
655
|
TSubsetKey extends string,
|
|
625
|
-
TComputedResults extends
|
|
626
|
-
TSubsetMapping extends
|
|
656
|
+
TComputedResults extends { [K in TSubsetKey]: TComputedResults[K] },
|
|
657
|
+
TSubsetMapping extends { [K in TSubsetKey]: TSubsetMapping[K] },
|
|
627
658
|
TSubsetQueries extends Record<TSubsetKey, PuriSubsetFn>,
|
|
628
659
|
> = [RequiredEnhancerKeys<TSubsetKey, TComputedResults, TSubsetMapping>] extends [never]
|
|
629
660
|
? { enhancers?: EnhancerMap<TSubsetKey, TComputedResults, TSubsetMapping, TSubsetQueries> }
|
|
@@ -631,8 +662,8 @@ type EnhancerParam<
|
|
|
631
662
|
|
|
632
663
|
type RequiredEnhancerKeys<
|
|
633
664
|
TSubsetKey extends string,
|
|
634
|
-
TComputedResults extends
|
|
635
|
-
TSubsetMapping extends
|
|
665
|
+
TComputedResults extends { [K in TSubsetKey]: TComputedResults[K] },
|
|
666
|
+
TSubsetMapping extends { [K in TSubsetKey]: TSubsetMapping[K] },
|
|
636
667
|
> = {
|
|
637
668
|
[K in TSubsetKey]: TComputedResults[K] extends TSubsetMapping[K] ? never : K;
|
|
638
669
|
}[TSubsetKey];
|
|
@@ -77,8 +77,8 @@ type OmitVirtualQueryFromMapping<TMapping, TVirtualQueryKeys> = Omit<
|
|
|
77
77
|
*/
|
|
78
78
|
type IsEnhancerOptional<
|
|
79
79
|
TSubsetKey extends string,
|
|
80
|
-
TComputedResults extends
|
|
81
|
-
TSubsetMapping extends
|
|
80
|
+
TComputedResults extends { [K in TSubsetKey]: TComputedResults[K] },
|
|
81
|
+
TSubsetMapping extends { [K in TSubsetKey]: TSubsetMapping[K] },
|
|
82
82
|
TSubsetQueries extends Record<TSubsetKey, PuriSubsetFn>,
|
|
83
83
|
K extends TSubsetKey,
|
|
84
84
|
> =
|
|
@@ -106,8 +106,8 @@ type EnhancerFnWithVirtualQuery<TComputed, TMapping, TVirtualQueryKeys> = (
|
|
|
106
106
|
*/
|
|
107
107
|
export type RequiredEnhancerKeys<
|
|
108
108
|
TSubsetKey extends string,
|
|
109
|
-
TComputedResults extends
|
|
110
|
-
TSubsetMapping extends
|
|
109
|
+
TComputedResults extends { [K in TSubsetKey]: TComputedResults[K] },
|
|
110
|
+
TSubsetMapping extends { [K in TSubsetKey]: TSubsetMapping[K] },
|
|
111
111
|
TSubsetQueries extends Record<TSubsetKey, PuriSubsetFn>,
|
|
112
112
|
> = {
|
|
113
113
|
[K in TSubsetKey]: IsEnhancerOptional<
|
|
@@ -136,8 +136,8 @@ export type RequiredEnhancerKeys<
|
|
|
136
136
|
*/
|
|
137
137
|
export type EnhancerMap<
|
|
138
138
|
TSubsetKey extends string,
|
|
139
|
-
TComputedResults extends
|
|
140
|
-
TSubsetMapping extends
|
|
139
|
+
TComputedResults extends { [K in TSubsetKey]: TComputedResults[K] },
|
|
140
|
+
TSubsetMapping extends { [K in TSubsetKey]: TSubsetMapping[K] },
|
|
141
141
|
TSubsetQueries extends Record<TSubsetKey, PuriSubsetFn>,
|
|
142
142
|
TRequiredKeys extends TSubsetKey = RequiredEnhancerKeys<
|
|
143
143
|
TSubsetKey,
|