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/ui/cdd-service.ts
CHANGED
|
@@ -4,6 +4,7 @@ import os from "os";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
|
|
6
6
|
import { Sonamu } from "../api/sonamu";
|
|
7
|
+
import { isStringValue } from "../utils/runtime-value";
|
|
7
8
|
import {
|
|
8
9
|
type CddAcEntry,
|
|
9
10
|
type CddAcFile,
|
|
@@ -17,6 +18,22 @@ import {
|
|
|
17
18
|
type CddTreeNode,
|
|
18
19
|
} from "./cdd-types";
|
|
19
20
|
|
|
21
|
+
interface CddTreeResult {
|
|
22
|
+
exists: boolean;
|
|
23
|
+
tree: CddTreeNode[];
|
|
24
|
+
}
|
|
25
|
+
interface EditorCliConfig {
|
|
26
|
+
cli: string;
|
|
27
|
+
waitFlag: string;
|
|
28
|
+
}
|
|
29
|
+
interface EditorCliResolution {
|
|
30
|
+
bin: string;
|
|
31
|
+
args: string[];
|
|
32
|
+
}
|
|
33
|
+
interface CddRulesResult {
|
|
34
|
+
rules: CddRuleSummary[];
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
export type {
|
|
21
38
|
CddAcEntry,
|
|
22
39
|
CddAcFile,
|
|
@@ -93,7 +110,7 @@ function scanDirectory(dirPath: string, relativeTo: string): CddTreeNode[] {
|
|
|
93
110
|
}
|
|
94
111
|
|
|
95
112
|
/** contract/ 디렉터리의 트리 구조를 반환 */
|
|
96
|
-
export function getCddTree():
|
|
113
|
+
export function getCddTree(): CddTreeResult {
|
|
97
114
|
const contractDir = getContractDir();
|
|
98
115
|
if (!fs.existsSync(contractDir)) {
|
|
99
116
|
return { exists: false, tree: [] };
|
|
@@ -142,17 +159,17 @@ export async function editContent(
|
|
|
142
159
|
}
|
|
143
160
|
|
|
144
161
|
/** 에디터별 앱 번들 내 CLI 경로 + --wait 플래그 매핑 */
|
|
145
|
-
const EDITOR_CLI_MAP
|
|
162
|
+
const EDITOR_CLI_MAP = {
|
|
146
163
|
"Visual Studio Code": { cli: "Contents/Resources/app/bin/code", waitFlag: "--wait" },
|
|
147
164
|
Zed: { cli: "Contents/MacOS/cli", waitFlag: "--wait" },
|
|
148
165
|
Cursor: { cli: "Contents/Resources/app/bin/cursor", waitFlag: "--wait" },
|
|
149
|
-
}
|
|
166
|
+
} satisfies Record<string, EditorCliConfig>;
|
|
150
167
|
|
|
151
168
|
/** 앱 번들 CLI 경로를 resolve. wait=false이면 --wait 플래그를 생략 */
|
|
152
|
-
function resolveEditorCli(options?: { wait?: boolean }):
|
|
169
|
+
function resolveEditorCli(options?: { wait?: boolean }): EditorCliResolution {
|
|
153
170
|
const wait = options?.wait ?? true;
|
|
154
171
|
const appName = Sonamu.config.externalEditor ?? "Visual Studio Code";
|
|
155
|
-
const mapping = EDITOR_CLI_MAP[appName];
|
|
172
|
+
const mapping = Object.entries(EDITOR_CLI_MAP).find(([name]) => name === appName)?.[1];
|
|
156
173
|
if (!mapping) {
|
|
157
174
|
throw new Error(
|
|
158
175
|
`지원되지 않는 에디터입니다: ${appName} (지원: ${Object.keys(EDITOR_CLI_MAP).join(", ")})`,
|
|
@@ -218,7 +235,7 @@ export function openSourceFile(filePath: string): void {
|
|
|
218
235
|
* ======================================================================== */
|
|
219
236
|
|
|
220
237
|
/** contract/rules/ 디렉터리 내 .rules.json 파일 목록 반환 */
|
|
221
|
-
export function listRules():
|
|
238
|
+
export function listRules(): CddRulesResult {
|
|
222
239
|
const contractDir = getContractDir();
|
|
223
240
|
const rulesDir = path.join(contractDir, "rules");
|
|
224
241
|
if (!fs.existsSync(rulesDir)) return { rules: [] };
|
|
@@ -235,11 +252,13 @@ export function listRules(): { rules: CddRuleSummary[] } {
|
|
|
235
252
|
|
|
236
253
|
try {
|
|
237
254
|
const raw = fs.readFileSync(absPath, "utf-8");
|
|
238
|
-
const doc =
|
|
255
|
+
const doc = /* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ JSON.parse(
|
|
256
|
+
raw,
|
|
257
|
+
) as { description?: string; rules?: unknown[] };
|
|
239
258
|
rules.push({
|
|
240
259
|
key,
|
|
241
260
|
path: relPath,
|
|
242
|
-
description:
|
|
261
|
+
description: isStringValue(doc.description) ? doc.description : "",
|
|
243
262
|
ruleCount: Array.isArray(doc.rules) ? doc.rules.length : 0,
|
|
244
263
|
});
|
|
245
264
|
} catch (err) {
|
|
@@ -266,12 +285,14 @@ export function readRule(ruleKey: string): CddRuleDetail {
|
|
|
266
285
|
}
|
|
267
286
|
|
|
268
287
|
const raw = fs.readFileSync(absPath, "utf-8");
|
|
269
|
-
const doc =
|
|
288
|
+
const doc = /* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ JSON.parse(
|
|
289
|
+
raw,
|
|
290
|
+
) as { description?: string; rules?: CddRuleEntry[] };
|
|
270
291
|
|
|
271
292
|
return {
|
|
272
293
|
key: ruleKey,
|
|
273
294
|
path: `rules/${ruleKey}.rules.json`,
|
|
274
|
-
description:
|
|
295
|
+
description: isStringValue(doc.description) ? doc.description : "",
|
|
275
296
|
rules: Array.isArray(doc.rules) ? doc.rules : [],
|
|
276
297
|
};
|
|
277
298
|
}
|
|
@@ -287,7 +308,9 @@ export function addRule(req: CddAddRuleRequest): CddRuleDetail {
|
|
|
287
308
|
}
|
|
288
309
|
|
|
289
310
|
const raw = fs.readFileSync(absPath, "utf-8");
|
|
290
|
-
const doc =
|
|
311
|
+
const doc = /* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ JSON.parse(
|
|
312
|
+
raw,
|
|
313
|
+
) as { description?: string; rules?: CddRuleEntry[] };
|
|
291
314
|
const rules: CddRuleEntry[] = Array.isArray(doc.rules) ? doc.rules : [];
|
|
292
315
|
|
|
293
316
|
const nextId = generateNextRuleId(rules);
|
|
@@ -308,7 +331,7 @@ export function addRule(req: CddAddRuleRequest): CddRuleDetail {
|
|
|
308
331
|
return {
|
|
309
332
|
key: req.ruleKey,
|
|
310
333
|
path: `rules/${req.ruleKey}.rules.json`,
|
|
311
|
-
description:
|
|
334
|
+
description: isStringValue(doc.description) ? doc.description : "",
|
|
312
335
|
rules,
|
|
313
336
|
};
|
|
314
337
|
}
|
package/src/ui/migrations-api.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type MigrationStreamEvent,
|
|
21
21
|
type MigrationTarget,
|
|
22
22
|
} from "../migration/types";
|
|
23
|
+
import { forwardAsyncErrors } from "./async-route";
|
|
23
24
|
|
|
24
25
|
type ApprovalReady = { type: "ready" };
|
|
25
26
|
type ApprovalResult = ApprovalReady | SlackConfirmPendingResult;
|
|
@@ -39,7 +40,8 @@ function assertTargets(migrator: Migrator, targets: MigrationTarget[]): void {
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
function targetRequiresApproval(slack: SlackConfirm, target: MigrationTarget): boolean {
|
|
42
|
-
const connection =
|
|
43
|
+
const connection = /* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ Sonamu
|
|
44
|
+
.dbConfig[target]?.connection as { host?: string } | undefined;
|
|
43
45
|
const remote = !LOCAL_HOSTS.has((connection?.host ?? "localhost").toLowerCase());
|
|
44
46
|
return remote && slack.isTargetRequiresApproval(target);
|
|
45
47
|
}
|
|
@@ -251,58 +253,65 @@ export async function registerMigrationsApi(server: FastifyInstance) {
|
|
|
251
253
|
connections: migrator.getConnections(),
|
|
252
254
|
}));
|
|
253
255
|
server.get("/api/migrations/codes", async () => ({ codes: await migrator.getMigrationCodes() }));
|
|
254
|
-
server.get<{ Querystring: { codeName: string } }>("/api/migrations/code",
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
256
|
+
server.get<{ Querystring: { codeName: string } }>("/api/migrations/code", (request) =>
|
|
257
|
+
forwardAsyncErrors(async () => {
|
|
258
|
+
const migrationCode = (await migrator.getMigrationCodes()).find(
|
|
259
|
+
({ name }) => name === request.query.codeName,
|
|
260
|
+
);
|
|
261
|
+
if (migrationCode === undefined) {
|
|
262
|
+
throw new BadRequestException(SD("error.badRequest"));
|
|
263
|
+
}
|
|
264
|
+
return { code: await readFile(migrationCode.path, "utf8") };
|
|
265
|
+
}),
|
|
266
|
+
);
|
|
267
|
+
server.get<{ Querystring: { connKey?: MigrationTarget } }>("/api/migrations/status", (request) =>
|
|
268
|
+
forwardAsyncErrors(async () => {
|
|
266
269
|
if (request.query.connKey === undefined) {
|
|
267
270
|
return { status: await migrator.getStatus() };
|
|
268
271
|
}
|
|
269
272
|
return { status: await migrator.getConnectionStatus(request.query.connKey) };
|
|
270
|
-
},
|
|
273
|
+
}),
|
|
271
274
|
);
|
|
272
275
|
server.get<{ Querystring: { compareConnKey: MigrationTarget } }>(
|
|
273
276
|
"/api/migrations/prepared-codes",
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
+
(request) =>
|
|
278
|
+
forwardAsyncErrors(async () => ({
|
|
279
|
+
preparedCodes: await migrator.getPreparedCodes(request.query.compareConnKey),
|
|
280
|
+
})),
|
|
277
281
|
);
|
|
278
282
|
|
|
279
|
-
server.post<{ Body: ApplyBody }>("/api/migrations/request-approval",
|
|
280
|
-
|
|
281
|
-
|
|
283
|
+
server.post<{ Body: ApplyBody }>("/api/migrations/request-approval", (request) =>
|
|
284
|
+
forwardAsyncErrors(async () => {
|
|
285
|
+
return requestApproval(migrator, request.body.targets, request.body.requestor);
|
|
286
|
+
}),
|
|
287
|
+
);
|
|
282
288
|
server.post<{ Body: { channel: string; ts: string } }>(
|
|
283
289
|
"/api/migrations/checkApproval",
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
+
(request) =>
|
|
291
|
+
forwardAsyncErrors(async () => {
|
|
292
|
+
const slack = new SlackConfirm();
|
|
293
|
+
return slack.isConfigured()
|
|
294
|
+
? slack.checkApproval(request.body.channel, request.body.ts)
|
|
295
|
+
: { approved: true, rejected: false };
|
|
296
|
+
}),
|
|
290
297
|
);
|
|
291
298
|
server.post<{
|
|
292
299
|
Body: { channel: string; ts: string; reason: string; requestor?: string };
|
|
293
|
-
}>("/api/migrations/forceApproval",
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
300
|
+
}>("/api/migrations/forceApproval", (request) =>
|
|
301
|
+
forwardAsyncErrors(async () => {
|
|
302
|
+
const slack = new SlackConfirm();
|
|
303
|
+
if (!slack.isConfigured()) {
|
|
304
|
+
throw new BadRequestException(SD("sonamu.error.slackConfirmNotConfigured"));
|
|
305
|
+
}
|
|
306
|
+
await slack.forceApproval(
|
|
307
|
+
request.body.channel,
|
|
308
|
+
request.body.ts,
|
|
309
|
+
request.body.reason,
|
|
310
|
+
request.body.requestor,
|
|
311
|
+
);
|
|
312
|
+
return { success: true };
|
|
313
|
+
}),
|
|
314
|
+
);
|
|
306
315
|
|
|
307
316
|
server.post("/api/migrations/shadow", async (_request, reply) => {
|
|
308
317
|
return sendMigrationStream(reply, "shadow", [], (onProgress) => {
|
|
@@ -343,7 +352,8 @@ export async function registerMigrationsApi(server: FastifyInstance) {
|
|
|
343
352
|
|
|
344
353
|
server.post<{ Body: { compareConnKey?: MigrationTarget } }>(
|
|
345
354
|
"/api/migrations/generatePreparedCodes",
|
|
346
|
-
|
|
355
|
+
(request) =>
|
|
356
|
+
forwardAsyncErrors(async () => migrator.generatePreparedCodes(request.body.compareConnKey)),
|
|
347
357
|
);
|
|
348
358
|
|
|
349
359
|
// 이전 UI 번들과 외부 스크립트가 새 서버에서도 한 릴리스 동안 동작하도록 유지합니다.
|
|
@@ -355,15 +365,17 @@ export async function registerMigrationsApi(server: FastifyInstance) {
|
|
|
355
365
|
forceReason?: string;
|
|
356
366
|
requestor?: string;
|
|
357
367
|
};
|
|
358
|
-
}>("/api/migrations/runAction",
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
368
|
+
}>("/api/migrations/runAction", (request) =>
|
|
369
|
+
forwardAsyncErrors(async () => {
|
|
370
|
+
if (request.body.action === "shadow") {
|
|
371
|
+
return migrator.runShadowTest();
|
|
372
|
+
}
|
|
373
|
+
if (request.body.action === "apply") {
|
|
374
|
+
return runLegacyApply(migrator, request.body);
|
|
375
|
+
}
|
|
376
|
+
assertTargets(migrator, request.body.targets);
|
|
377
|
+
await getAvailableTargetStatuses(migrator, request.body.targets);
|
|
378
|
+
return migrator.rollback(request.body.targets);
|
|
379
|
+
}),
|
|
380
|
+
);
|
|
369
381
|
}
|
package/src/utils/formatter.ts
CHANGED
|
@@ -10,8 +10,9 @@ import { format, type FormatConfig } from "oxfmt";
|
|
|
10
10
|
import { cached } from "./async-utils";
|
|
11
11
|
import { isTest } from "./controller";
|
|
12
12
|
import { execute } from "./process-utils";
|
|
13
|
+
import { isNumberValue } from "./runtime-value";
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* 코드를 프로젝트의 oxfmt + oxlint 설정에 맞춰 포매팅한 문자열을 반환합니다.
|
|
@@ -75,9 +76,11 @@ async function loadOxfmtConfig(): Promise<FormatConfig> {
|
|
|
75
76
|
while (true) {
|
|
76
77
|
const candidate = join(dir, ".oxfmtrc.json");
|
|
77
78
|
try {
|
|
79
|
+
// SAFETY: 선행 분기와 함수 계약이 이 타입을 보장합니다.
|
|
78
80
|
cachedOxfmtConfig = JSON.parse(await readFile(candidate, "utf-8")) as FormatConfig;
|
|
79
81
|
return cachedOxfmtConfig;
|
|
80
82
|
} catch (e) {
|
|
83
|
+
// SAFETY: 선행 분기와 함수 계약이 이 타입을 보장합니다.
|
|
81
84
|
if ((e as NodeJS.ErrnoException).code !== "ENOENT") {
|
|
82
85
|
!isTest() && console.error(`Failed to load ${candidate}:`, e);
|
|
83
86
|
break;
|
|
@@ -121,7 +124,8 @@ async function runOxlint(code: string): Promise<string> {
|
|
|
121
124
|
});
|
|
122
125
|
} catch (e) {
|
|
123
126
|
// lint 위반 시 exit code != 0이지만 --fix는 적용됨. exec 자체 실패만 throw.
|
|
124
|
-
|
|
127
|
+
// SAFETY: 선행 분기와 함수 계약이 이 타입을 보장합니다.
|
|
128
|
+
if (!isNumberValue((e as Error & { code?: number }).code)) {
|
|
125
129
|
throw e;
|
|
126
130
|
}
|
|
127
131
|
}
|
|
@@ -138,7 +142,7 @@ async function runOxlint(code: string): Promise<string> {
|
|
|
138
142
|
|
|
139
143
|
function resolveOxlintBin(): string {
|
|
140
144
|
try {
|
|
141
|
-
return
|
|
145
|
+
return requireFromHere.resolve("oxlint/bin/oxlint");
|
|
142
146
|
} catch {
|
|
143
147
|
return "oxlint";
|
|
144
148
|
}
|
package/src/utils/fs-utils.ts
CHANGED
|
@@ -8,12 +8,12 @@ import { formatCode } from "./formatter";
|
|
|
8
8
|
/**
|
|
9
9
|
* fs/promises에는 exists가 없어요. 대신 access가 있습니다.
|
|
10
10
|
* 근데 얘는 인터페이스가 쓰기 불편해요. 그래서 감싸주었습니다.
|
|
11
|
-
* @param
|
|
11
|
+
* @param targetPath
|
|
12
12
|
* @returns
|
|
13
13
|
*/
|
|
14
|
-
export async function exists(
|
|
14
|
+
export async function exists(targetPath: PathLike): Promise<boolean> {
|
|
15
15
|
try {
|
|
16
|
-
await access(
|
|
16
|
+
await access(targetPath, constants.F_OK);
|
|
17
17
|
return true;
|
|
18
18
|
} catch {
|
|
19
19
|
return false;
|
|
@@ -21,9 +21,9 @@ export async function exists(path: PathLike): Promise<boolean> {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// 디렉토리가 아니라 파일만 존재하는지 확인합니다.
|
|
24
|
-
export async function fileExists(
|
|
24
|
+
export async function fileExists(targetPath: PathLike): Promise<boolean> {
|
|
25
25
|
try {
|
|
26
|
-
const stats = await stat(
|
|
26
|
+
const stats = await stat(targetPath);
|
|
27
27
|
return stats.isFile();
|
|
28
28
|
} catch {
|
|
29
29
|
return false;
|
package/src/utils/model.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { type SonamuQueryMode } from "../types/types";
|
|
1
|
+
import { type SonamuQueryMode, type SonamuSemanticParams } from "../types/types";
|
|
2
2
|
|
|
3
3
|
// semanticQuery가 있으면 similarity를 추가하는 조건부 타입
|
|
4
|
-
type WithSimilarity<LP, T> =
|
|
5
|
-
? T & { similarity: number }
|
|
6
|
-
: T;
|
|
4
|
+
type WithSimilarity<LP, T> = "semanticQuery" extends keyof LP ? T & { similarity: number } : T;
|
|
7
5
|
|
|
8
6
|
export type ListResult<
|
|
9
7
|
LP extends { queryMode?: SonamuQueryMode },
|
|
@@ -20,6 +18,7 @@ export function asArray<T>(param: T | T[]): T[] {
|
|
|
20
18
|
if (Array.isArray(param)) {
|
|
21
19
|
return param;
|
|
22
20
|
} else {
|
|
21
|
+
// SAFETY: 선행 분기와 함수 계약이 이 타입을 보장합니다.
|
|
23
22
|
return [param] as T[];
|
|
24
23
|
}
|
|
25
24
|
}
|
|
@@ -39,5 +38,5 @@ export interface BaseListParams {
|
|
|
39
38
|
page?: number;
|
|
40
39
|
keyword?: string;
|
|
41
40
|
queryMode?: "list" | "count" | "both";
|
|
42
|
-
semanticQuery?:
|
|
41
|
+
semanticQuery?: SonamuSemanticParams["semanticQuery"];
|
|
43
42
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isBigIntValue,
|
|
3
|
+
isFunctionValue,
|
|
4
|
+
isNumberValue,
|
|
5
|
+
isObjectValue,
|
|
6
|
+
isStringValue,
|
|
7
|
+
isSymbolValue,
|
|
8
|
+
} from "./runtime-value";
|
|
9
|
+
|
|
1
10
|
type Primitive = string | number | boolean | null | undefined;
|
|
2
11
|
|
|
3
12
|
type TypedArray =
|
|
@@ -84,8 +93,8 @@ export interface SerializableCheckResult {
|
|
|
84
93
|
* isSerializable({ fn: () => {} }) // { valid: false, reason: "Function at fn" }
|
|
85
94
|
* isSerializable({ deep: { nested: Promise.resolve() } }) // { valid: false, reason: "Promise at deep.nested" }
|
|
86
95
|
*/
|
|
87
|
-
export function isSerializable(
|
|
88
|
-
value:
|
|
96
|
+
export function isSerializable<Value>(
|
|
97
|
+
value: Value,
|
|
89
98
|
path: string[] = [],
|
|
90
99
|
seen: WeakSet<object> = new WeakSet(),
|
|
91
100
|
): SerializableCheckResult {
|
|
@@ -94,23 +103,26 @@ export function isSerializable(
|
|
|
94
103
|
return { valid: true };
|
|
95
104
|
}
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
if (
|
|
107
|
+
isStringValue(value) ||
|
|
108
|
+
isNumberValue(value) ||
|
|
109
|
+
value === true ||
|
|
110
|
+
value === false ||
|
|
111
|
+
value === undefined ||
|
|
112
|
+
isBigIntValue(value)
|
|
113
|
+
) {
|
|
102
114
|
return { valid: true };
|
|
103
115
|
}
|
|
104
116
|
|
|
105
|
-
if (
|
|
117
|
+
if (isFunctionValue(value)) {
|
|
106
118
|
return { valid: false, reason: `Function at ${formatPath(path)}` };
|
|
107
119
|
}
|
|
108
|
-
if (
|
|
120
|
+
if (isSymbolValue(value)) {
|
|
109
121
|
return { valid: false, reason: `Symbol at ${formatPath(path)}` };
|
|
110
122
|
}
|
|
111
123
|
|
|
112
|
-
if (
|
|
113
|
-
const obj = value
|
|
124
|
+
if (isObjectValue(value)) {
|
|
125
|
+
const obj = value;
|
|
114
126
|
|
|
115
127
|
if (obj instanceof Promise) {
|
|
116
128
|
return { valid: false, reason: `Promise at ${formatPath(path)}` };
|
|
@@ -126,7 +138,7 @@ export function isSerializable(
|
|
|
126
138
|
if (obj instanceof WeakSet) {
|
|
127
139
|
return { valid: false, reason: `WeakSet at ${formatPath(path)}` };
|
|
128
140
|
}
|
|
129
|
-
if (
|
|
141
|
+
if ("WeakRef" in globalThis && obj instanceof WeakRef) {
|
|
130
142
|
return { valid: false, reason: `WeakRef at ${formatPath(path)}` };
|
|
131
143
|
}
|
|
132
144
|
|
|
@@ -179,13 +191,11 @@ export function isSerializable(
|
|
|
179
191
|
|
|
180
192
|
// Vitest는 Error를 허용하지만 속성은 직렬화 필요
|
|
181
193
|
if (obj instanceof Error) {
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
seen,
|
|
188
|
-
);
|
|
194
|
+
const errorEntries = Object.entries(obj).filter(
|
|
195
|
+
([key]) => !["name", "message", "stack"].includes(key),
|
|
196
|
+
);
|
|
197
|
+
for (const [key, nestedValue] of errorEntries) {
|
|
198
|
+
const result = isSerializable(nestedValue, [...path, key], seen);
|
|
189
199
|
if (!result.valid) return result;
|
|
190
200
|
}
|
|
191
201
|
return { valid: true };
|
|
@@ -201,14 +211,14 @@ export function isSerializable(
|
|
|
201
211
|
};
|
|
202
212
|
}
|
|
203
213
|
|
|
204
|
-
for (const key of Object.
|
|
205
|
-
const result = isSerializable(
|
|
214
|
+
for (const [key, nestedValue] of Object.entries(obj)) {
|
|
215
|
+
const result = isSerializable(nestedValue, [...path, key], seen);
|
|
206
216
|
if (!result.valid) return result;
|
|
207
217
|
}
|
|
208
218
|
return { valid: true };
|
|
209
219
|
}
|
|
210
220
|
|
|
211
|
-
return { valid: false, reason: `Unknown
|
|
221
|
+
return { valid: false, reason: `Unknown value at ${formatPath(path)}` };
|
|
212
222
|
}
|
|
213
223
|
|
|
214
224
|
function formatPath(path: string[]): string {
|
|
@@ -4,6 +4,8 @@ import { promisify } from "util";
|
|
|
4
4
|
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
|
|
7
|
+
import { isStringValue } from "./runtime-value";
|
|
8
|
+
|
|
7
9
|
const execFileAsync = promisify(execFile);
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -16,7 +18,7 @@ export async function execute(
|
|
|
16
18
|
options?: ExecFileOptions,
|
|
17
19
|
): Promise<string> {
|
|
18
20
|
const { stdout } = await execFileAsync(bin, args, options);
|
|
19
|
-
return
|
|
21
|
+
return isStringValue(stdout) ? stdout : stdout.toString();
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
/**
|
|
@@ -37,6 +39,7 @@ export async function runWithGracefulShutdown(
|
|
|
37
39
|
waitForUpTo: 20000,
|
|
38
40
|
},
|
|
39
41
|
): Promise<void> {
|
|
42
|
+
// SAFETY: 선행 분기와 함수 계약이 이 타입을 보장합니다.
|
|
40
43
|
let isRunning = true as boolean;
|
|
41
44
|
|
|
42
45
|
const abortController = new AbortController();
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function hasPrimitiveTag<Value>(value: Value, tag: string): boolean {
|
|
2
|
+
return Object.prototype.toString.call(value) === tag && Object(value) !== value;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/** 런타임 값이 원시 문자열인지 판별합니다. */
|
|
6
|
+
export function isStringValue<Value>(value: Value): value is Value & string {
|
|
7
|
+
return hasPrimitiveTag(value, "[object String]");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** 런타임 값이 원시 숫자인지 판별합니다. */
|
|
11
|
+
export function isNumberValue<Value>(value: Value): value is Value & number {
|
|
12
|
+
return hasPrimitiveTag(value, "[object Number]");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** 런타임 값이 원시 심벌인지 판별합니다. */
|
|
16
|
+
export function isSymbolValue<Value>(value: Value): value is Value & symbol {
|
|
17
|
+
return hasPrimitiveTag(value, "[object Symbol]");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** 런타임 값이 원시 bigint인지 판별합니다. */
|
|
21
|
+
export function isBigIntValue<Value>(value: Value): value is Value & bigint {
|
|
22
|
+
return hasPrimitiveTag(value, "[object BigInt]");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 런타임 값이 함수인지 판별합니다. */
|
|
26
|
+
export function isFunctionValue<Value>(value: Value): value is Value & CallableFunction {
|
|
27
|
+
try {
|
|
28
|
+
const tag = Object.prototype.toString.call(value);
|
|
29
|
+
return (
|
|
30
|
+
tag === "[object Function]" ||
|
|
31
|
+
tag === "[object AsyncFunction]" ||
|
|
32
|
+
tag === "[object GeneratorFunction]" ||
|
|
33
|
+
tag === "[object AsyncGeneratorFunction]"
|
|
34
|
+
);
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** null과 함수를 제외한 객체 표현인지 판별합니다. */
|
|
41
|
+
export function isObjectValue<Value>(value: Value): value is Value & object {
|
|
42
|
+
return value !== null && Object(value) === value && !isFunctionValue(value);
|
|
43
|
+
}
|
package/src/utils/sql-parser.ts
CHANGED
|
@@ -9,15 +9,21 @@ import {
|
|
|
9
9
|
} from "node-sql-parser";
|
|
10
10
|
import { unique } from "radashi";
|
|
11
11
|
|
|
12
|
+
import { isObjectValue, isStringValue } from "./runtime-value";
|
|
12
13
|
import { nonNullable } from "./utils";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
type ParserColumnRef = Omit<ColumnRef, "table"> & {
|
|
16
|
+
table?: string | { type: string; value: string } | null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function getTableName(expr: ParserColumnRef) {
|
|
20
|
+
const table = expr.table;
|
|
21
|
+
if (isStringValue(table)) {
|
|
22
|
+
return table;
|
|
19
23
|
}
|
|
20
|
-
return
|
|
24
|
+
return isObjectValue(table) && "value" in table && isStringValue(table.value)
|
|
25
|
+
? table.value
|
|
26
|
+
: null;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
// where 조건에 사용된 테이블명을 추출
|
|
@@ -29,6 +35,7 @@ export function getTableNamesFromWhere(ast: AST | AST[]): string[] {
|
|
|
29
35
|
|
|
30
36
|
const extractTableName = (expr: Expr | ExpressionValue): string[] => {
|
|
31
37
|
if (expr.type === "column_ref") {
|
|
38
|
+
// SAFETY: 선행 분기와 함수 계약이 이 타입을 보장합니다.
|
|
32
39
|
const table = getTableName(expr as ColumnRef);
|
|
33
40
|
return table ? [table] : [];
|
|
34
41
|
} else if (expr.type === "binary_expr" && "left" in expr) {
|
package/src/utils/type-utils.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isObjectValue } from "./runtime-value";
|
|
1
2
|
// 타입을 펼쳐서 보여주는 유틸리티 (객체에만 사용해야 함)
|
|
2
3
|
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
|
|
3
4
|
|
|
@@ -32,9 +33,9 @@ export function withProp<T extends object, P extends string, V>(
|
|
|
32
33
|
const result = structuredClone(obj);
|
|
33
34
|
|
|
34
35
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- 범용 배열 요소 타입
|
|
35
|
-
const setDeep = (current: any,
|
|
36
|
-
if (
|
|
37
|
-
const [key, ...rest] =
|
|
36
|
+
const setDeep = (current: any, pathKeys: string[]): void => {
|
|
37
|
+
if (pathKeys.length === 0) return;
|
|
38
|
+
const [key, ...rest] = pathKeys;
|
|
38
39
|
|
|
39
40
|
if (rest.length === 0) {
|
|
40
41
|
if (Array.isArray(current)) {
|
|
@@ -45,21 +46,22 @@ export function withProp<T extends object, P extends string, V>(
|
|
|
45
46
|
current[key] = value;
|
|
46
47
|
}
|
|
47
48
|
} else {
|
|
48
|
-
if (!(key in current) ||
|
|
49
|
+
if (!(key in current) || !isObjectValue(current[key])) {
|
|
49
50
|
current[key] = {};
|
|
50
51
|
}
|
|
51
52
|
if (Array.isArray(current[key])) {
|
|
52
53
|
// oxlint-disable-next-line @typescript-eslint/no-explicit-any -- 범용 배열 요소 타입
|
|
53
54
|
current[key].forEach((item: any) => {
|
|
54
|
-
setDeep(item, rest
|
|
55
|
+
setDeep(item, rest);
|
|
55
56
|
});
|
|
56
57
|
} else {
|
|
57
|
-
setDeep(current[key], rest
|
|
58
|
+
setDeep(current[key], rest);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
};
|
|
61
62
|
|
|
62
|
-
setDeep(result, keys
|
|
63
|
+
setDeep(result, keys);
|
|
64
|
+
// SAFETY: 선행 분기와 함수 계약이 이 타입을 보장합니다.
|
|
63
65
|
return result as SetPath<T, P, V>;
|
|
64
66
|
}
|
|
65
67
|
|