sonamu 0.10.11 → 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 +133 -29
- 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 +13 -7
- 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 +61 -36
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +276 -167
- 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/migration/types.d.ts +54 -0
- package/dist/migration/types.d.ts.map +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 +146 -210
- 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 +3 -0
- package/dist/ui/migrations-api.d.ts.map +1 -0
- package/dist/ui/migrations-api.js +215 -0
- package/dist/ui-web/assets/index-D3QNH-Dv.css +1 -0
- package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
- package/dist/ui-web/index.html +2 -2
- 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 +11 -7
- 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 +155 -38
- 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 +392 -244
- package/src/migration/postgresql-schema-reader.ts +52 -47
- package/src/migration/slack-confirm.ts +17 -15
- package/src/migration/types.ts +57 -0
- 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 +726 -770
- package/src/ui/async-route.ts +4 -0
- package/src/ui/cdd-service.ts +35 -12
- package/src/ui/migrations-api.ts +381 -0
- 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-CJf8uJYf.js +0 -176
- package/dist/ui-web/assets/index-GMMIVGja.css +0 -1
package/src/bin/cli.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "assert";
|
|
2
|
-
import {
|
|
3
|
-
import { mkdir, readdir, writeFile } from "fs/promises";
|
|
2
|
+
import { spawn, spawnSync } from "child_process";
|
|
3
|
+
import { mkdir, open, readFile, readdir, rm, writeFile } from "fs/promises";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import process from "process";
|
|
@@ -31,19 +31,88 @@ import { exists } from "../utils/fs-utils";
|
|
|
31
31
|
import { findApiRootPath, findAppRootPath } from "../utils/utils";
|
|
32
32
|
import { API_ARTIFACTS, WEB_ARTIFACTS } from "./build-config";
|
|
33
33
|
import { type BuildArtifact } from "./build-config";
|
|
34
|
+
import {
|
|
35
|
+
assertApiZodCompilerBuildOutput,
|
|
36
|
+
createApiZodCompilerBuildWrapper,
|
|
37
|
+
HTTP_VALIDATOR_REGISTRY_BUILD_PATH,
|
|
38
|
+
HTTP_VALIDATOR_REGISTRY_SOURCE_PATH,
|
|
39
|
+
} from "./build-config";
|
|
40
|
+
import { loadBuildCompilerPolicy } from "./compiler-policy";
|
|
34
41
|
import { fixtureExploreCommand, fixtureFetchCommand, fixtureGenCommand } from "./fixture";
|
|
35
42
|
import { getMigrateRunTargets } from "./migrate-targets";
|
|
36
43
|
import { testCommand } from "./test-command";
|
|
37
44
|
|
|
38
45
|
let migrator: Migrator;
|
|
39
46
|
|
|
47
|
+
function runMysql(
|
|
48
|
+
args: string[],
|
|
49
|
+
stdio: [number | "ignore", number | "inherit", "inherit"] = ["ignore", "inherit", "inherit"],
|
|
50
|
+
) {
|
|
51
|
+
const result = spawnSync("mysql", args, { stdio });
|
|
52
|
+
if (result.error) {
|
|
53
|
+
throw result.error;
|
|
54
|
+
}
|
|
55
|
+
if (result.status !== 0) {
|
|
56
|
+
throw new Error(`mysql 명령이 종료 코드 ${result.status ?? "unknown"}로 실패했습니다.`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function writeMysqlDump(args: string[], outputPath: string) {
|
|
61
|
+
const output = await open(outputPath, "w");
|
|
62
|
+
try {
|
|
63
|
+
const result = spawnSync("mysqldump", args, { stdio: ["ignore", output.fd, "inherit"] });
|
|
64
|
+
if (result.error) {
|
|
65
|
+
throw result.error;
|
|
66
|
+
}
|
|
67
|
+
if (result.status !== 0) {
|
|
68
|
+
throw new Error(`mysqldump 명령이 종료 코드 ${result.status ?? "unknown"}로 실패했습니다.`);
|
|
69
|
+
}
|
|
70
|
+
} finally {
|
|
71
|
+
await output.close();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function runMysqlWithInput(args: string[], inputPath: string) {
|
|
76
|
+
const input = await open(inputPath, "r");
|
|
77
|
+
try {
|
|
78
|
+
runMysql(args, [input.fd, "inherit", "inherit"]);
|
|
79
|
+
} finally {
|
|
80
|
+
await input.close();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function openInCode(pathToOpen: string) {
|
|
85
|
+
const result = spawnSync("code", [pathToOpen], { stdio: ["ignore", "inherit", "inherit"] });
|
|
86
|
+
if (result.error) {
|
|
87
|
+
throw result.error;
|
|
88
|
+
}
|
|
89
|
+
if (result.status !== 0) {
|
|
90
|
+
throw new Error(`code 명령이 종료 코드 ${result.status ?? "unknown"}로 실패했습니다.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function mysqlConnectionArgs(connection: Knex.ConnectionConfig) {
|
|
95
|
+
return [
|
|
96
|
+
`-h${String(connection.host)}`,
|
|
97
|
+
`-u${String(connection.user)}`,
|
|
98
|
+
`-p${String(connection.password)}`,
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function copyToClipboard(value: string) {
|
|
103
|
+
const result = spawnSync("pbcopy", [], { input: value, stdio: ["pipe", "inherit", "inherit"] });
|
|
104
|
+
if (result.error) {
|
|
105
|
+
throw result.error;
|
|
106
|
+
}
|
|
107
|
+
if (result.status !== 0) {
|
|
108
|
+
throw new Error(`pbcopy 명령이 종료 코드 ${result.status ?? "unknown"}로 실패했습니다.`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
40
112
|
/**
|
|
41
113
|
* CLI 옵션을 파싱하는 헬퍼 함수
|
|
42
114
|
*/
|
|
43
|
-
function parseCliOptions(argv: string[] = process.argv)
|
|
44
|
-
flags: Set<string>; // --regenerate, --ai, --no-cones 등
|
|
45
|
-
options: Record<string, string>; // --locale ko 등
|
|
46
|
-
} {
|
|
115
|
+
function parseCliOptions(argv: string[] = process.argv) {
|
|
47
116
|
const flags = new Set<string>();
|
|
48
117
|
const options: Record<string, string> = {};
|
|
49
118
|
|
|
@@ -388,8 +457,8 @@ async function dev_web() {
|
|
|
388
457
|
* API 빌드 설정 파일 경로를 결정합니다.
|
|
389
458
|
* 프로젝트 루트에 `tsdown.config.ts`가 있으면 그것을, 없으면 sonamu 기본 설정을 사용합니다.
|
|
390
459
|
*/
|
|
391
|
-
async function resolveApiBuildConfigPath(): Promise<string> {
|
|
392
|
-
const localConfigPath = path.join(
|
|
460
|
+
async function resolveApiBuildConfigPath(apiRootPath: string): Promise<string> {
|
|
461
|
+
const localConfigPath = path.join(apiRootPath, "tsdown.config.ts");
|
|
393
462
|
|
|
394
463
|
try {
|
|
395
464
|
if (await exists(localConfigPath)) {
|
|
@@ -421,22 +490,46 @@ async function build_all() {
|
|
|
421
490
|
* Sonamu.init 없이 호출될 것을 상정하여 구현되었습니다.
|
|
422
491
|
*/
|
|
423
492
|
async function build_api() {
|
|
424
|
-
const
|
|
425
|
-
const
|
|
493
|
+
const apiRootPath = findApiRootPath();
|
|
494
|
+
const baseConfigPath = await resolveApiBuildConfigPath(apiRootPath);
|
|
495
|
+
const policy = await loadBuildCompilerPolicy(apiRootPath);
|
|
496
|
+
const registryPath = path.join(apiRootPath, HTTP_VALIDATOR_REGISTRY_SOURCE_PATH);
|
|
497
|
+
const configFilePath = await createApiZodCompilerBuildWrapper({
|
|
498
|
+
apiRootPath,
|
|
499
|
+
baseConfigPath,
|
|
500
|
+
policy,
|
|
501
|
+
registryPath,
|
|
502
|
+
});
|
|
503
|
+
const temporaryConfigPath = configFilePath === baseConfigPath ? undefined : configFilePath;
|
|
426
504
|
|
|
427
505
|
const apiStartedAt = Date.now();
|
|
428
506
|
try {
|
|
429
507
|
for (const artifact of API_ARTIFACTS) {
|
|
430
|
-
const cwd =
|
|
508
|
+
const cwd = apiRootPath;
|
|
431
509
|
printTaskHeader(artifact.name, artifact.description, cwd);
|
|
432
510
|
|
|
433
511
|
await runBuildSteps(artifact, { cwd, buildCommandArgs: { configFilePath } });
|
|
434
512
|
}
|
|
513
|
+
if (policy.api === "aot") {
|
|
514
|
+
const outputPath = path.join(apiRootPath, HTTP_VALIDATOR_REGISTRY_BUILD_PATH);
|
|
515
|
+
if (!(await exists(outputPath))) {
|
|
516
|
+
throw new Error(`Built HTTP validator registry not found: ${outputPath}`);
|
|
517
|
+
}
|
|
518
|
+
assertApiZodCompilerBuildOutput([
|
|
519
|
+
{
|
|
520
|
+
code: await readFile(outputPath, "utf8"),
|
|
521
|
+
path: outputPath,
|
|
522
|
+
},
|
|
523
|
+
]);
|
|
524
|
+
}
|
|
435
525
|
printBuildSummary("API", true, Date.now() - apiStartedAt);
|
|
436
526
|
} catch (e) {
|
|
437
527
|
printBuildSummary("API", false, Date.now() - apiStartedAt);
|
|
438
|
-
|
|
439
|
-
|
|
528
|
+
throw e;
|
|
529
|
+
} finally {
|
|
530
|
+
if (temporaryConfigPath !== undefined) {
|
|
531
|
+
await rm(temporaryConfigPath, { force: true });
|
|
532
|
+
}
|
|
440
533
|
}
|
|
441
534
|
}
|
|
442
535
|
|
|
@@ -527,7 +620,6 @@ async function start() {
|
|
|
527
620
|
return;
|
|
528
621
|
}
|
|
529
622
|
|
|
530
|
-
const { spawn } = await import("child_process");
|
|
531
623
|
const serverProcess = spawn(
|
|
532
624
|
process.execPath,
|
|
533
625
|
["--enable-source-maps", "-r", "dotenv/config", entryPoint],
|
|
@@ -554,12 +646,12 @@ async function setupFixtureManager() {
|
|
|
554
646
|
|
|
555
647
|
async function migrate_apply(targets: (keyof SonamuDBConfig)[]) {
|
|
556
648
|
await setupMigrator();
|
|
557
|
-
await migrator.
|
|
649
|
+
await migrator.apply(targets);
|
|
558
650
|
}
|
|
559
651
|
|
|
560
652
|
async function migrate_run() {
|
|
561
653
|
await setupMigrator();
|
|
562
|
-
await migrator.
|
|
654
|
+
await migrator.apply(getMigrateRunTargets());
|
|
563
655
|
}
|
|
564
656
|
|
|
565
657
|
async function migrate_generate() {
|
|
@@ -597,7 +689,7 @@ async function migrate_status() {
|
|
|
597
689
|
|
|
598
690
|
async function fixture_init() {
|
|
599
691
|
const srcConfig = Sonamu.dbConfig[getSonamuEnvironment()];
|
|
600
|
-
const targets = [
|
|
692
|
+
const targets = /* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ [
|
|
601
693
|
{
|
|
602
694
|
label: "(REMOTE) Fixture DB",
|
|
603
695
|
config: Sonamu.dbConfig.fixture,
|
|
@@ -606,8 +698,12 @@ async function fixture_init() {
|
|
|
606
698
|
label: "(LOCAL) Testing DB",
|
|
607
699
|
config: Sonamu.dbConfig.test,
|
|
608
700
|
toSkip: (() => {
|
|
609
|
-
const remoteConn =
|
|
610
|
-
|
|
701
|
+
const remoteConn =
|
|
702
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ Sonamu.dbConfig
|
|
703
|
+
.fixture.connection as Knex.ConnectionConfig;
|
|
704
|
+
const localConn =
|
|
705
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ Sonamu.dbConfig
|
|
706
|
+
.test.connection as Knex.ConnectionConfig;
|
|
611
707
|
return remoteConn.host === localConn.host && remoteConn.database === localConn.database;
|
|
612
708
|
})(),
|
|
613
709
|
},
|
|
@@ -620,35 +716,56 @@ async function fixture_init() {
|
|
|
620
716
|
// 1. 기준DB 스키마를 덤프
|
|
621
717
|
console.log("DUMP...");
|
|
622
718
|
const dumpFilename = `/tmp/sonamu-fixture-init-${Date.now()}.sql`;
|
|
623
|
-
const srcConn =
|
|
719
|
+
const srcConn =
|
|
720
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ srcConfig.connection as Knex.ConnectionConfig;
|
|
624
721
|
const migrationsDump = `/tmp/sonamu-fixture-init-migrations-${Date.now()}.sql`;
|
|
625
|
-
|
|
626
|
-
|
|
722
|
+
await writeMysqlDump(
|
|
723
|
+
[
|
|
724
|
+
...mysqlConnectionArgs(srcConn),
|
|
725
|
+
"--single-transaction",
|
|
726
|
+
"-d",
|
|
727
|
+
"--no-create-db",
|
|
728
|
+
"--triggers",
|
|
729
|
+
String(srcConn.database),
|
|
730
|
+
],
|
|
731
|
+
dumpFilename,
|
|
627
732
|
);
|
|
628
|
-
const
|
|
629
|
-
const [[migrations]] = await
|
|
733
|
+
const sourceDb = knex(srcConfig);
|
|
734
|
+
const [[migrations]] = await sourceDb.raw(
|
|
630
735
|
"SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = ? AND table_name = 'knex_migrations'",
|
|
631
736
|
[srcConn.database],
|
|
632
737
|
);
|
|
633
738
|
if (migrations.count > 0) {
|
|
634
|
-
|
|
635
|
-
|
|
739
|
+
await writeMysqlDump(
|
|
740
|
+
[
|
|
741
|
+
...mysqlConnectionArgs(srcConn),
|
|
742
|
+
"--single-transaction",
|
|
743
|
+
"--no-create-db",
|
|
744
|
+
"--triggers",
|
|
745
|
+
String(srcConn.database),
|
|
746
|
+
"knex_migrations",
|
|
747
|
+
"knex_migrations_lock",
|
|
748
|
+
],
|
|
749
|
+
migrationsDump,
|
|
636
750
|
);
|
|
637
751
|
}
|
|
638
752
|
|
|
639
753
|
// 2. 대상DB 각각에 대하여 존재여부 확인 후 붓기
|
|
640
754
|
for (const { label, config, toSkip } of targets) {
|
|
641
|
-
const conn =
|
|
755
|
+
const conn =
|
|
756
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ config.connection as Knex.ConnectionConfig;
|
|
642
757
|
|
|
643
758
|
if (toSkip === true) {
|
|
644
759
|
console.log(chalk.red(`${label}: Skipped!`));
|
|
645
760
|
continue;
|
|
646
761
|
}
|
|
647
762
|
|
|
763
|
+
// SAFETY: Sonamu DB 구성은 Knex 연결 구성으로 검증된 뒤 이 명령에 전달된다.
|
|
764
|
+
const databaseConnection = (config.connection ?? {}) as Knex.ConnectionConfig;
|
|
648
765
|
const db = knex({
|
|
649
766
|
...config,
|
|
650
767
|
connection: {
|
|
651
|
-
...
|
|
768
|
+
...databaseConnection,
|
|
652
769
|
database: undefined,
|
|
653
770
|
},
|
|
654
771
|
});
|
|
@@ -660,18 +777,20 @@ async function fixture_init() {
|
|
|
660
777
|
}
|
|
661
778
|
|
|
662
779
|
console.log(`SYNC to ${label}...`);
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
780
|
+
const connectionArgs = mysqlConnectionArgs(conn);
|
|
781
|
+
const database = String(conn.database);
|
|
782
|
+
const escapedDatabase = database.replaceAll("`", "``");
|
|
783
|
+
runMysql([...connectionArgs, "-e", `DROP DATABASE IF EXISTS \`${escapedDatabase}\``]);
|
|
784
|
+
runMysql([...connectionArgs, "-e", `CREATE DATABASE \`${escapedDatabase}\``]);
|
|
785
|
+
await runMysqlWithInput([...connectionArgs, database], dumpFilename);
|
|
667
786
|
if (await exists(migrationsDump)) {
|
|
668
|
-
|
|
787
|
+
await runMysqlWithInput([...connectionArgs, database], migrationsDump);
|
|
669
788
|
}
|
|
670
789
|
|
|
671
790
|
await db.destroy();
|
|
672
791
|
}
|
|
673
792
|
|
|
674
|
-
await
|
|
793
|
+
await sourceDb.destroy();
|
|
675
794
|
}
|
|
676
795
|
|
|
677
796
|
async function fixture_import(entityId: string, recordIds: number[]) {
|
|
@@ -799,14 +918,14 @@ async function stub_practice(name: string) {
|
|
|
799
918
|
].join("\n");
|
|
800
919
|
await writeFile(dstPath, code);
|
|
801
920
|
|
|
802
|
-
|
|
921
|
+
openInCode(dstPath);
|
|
803
922
|
|
|
804
923
|
const runCode = `yarn node -r dotenv/config --enable-source-maps dist/practices/${fileName.replace(
|
|
805
924
|
".ts",
|
|
806
925
|
".js",
|
|
807
926
|
)}`;
|
|
808
927
|
console.log(`${chalk.blue(runCode)} copied to clipboard.`);
|
|
809
|
-
|
|
928
|
+
copyToClipboard(runCode);
|
|
810
929
|
}
|
|
811
930
|
|
|
812
931
|
async function stub_entity(entityId: string) {
|
|
@@ -822,7 +941,6 @@ async function stub_entity(entityId: string) {
|
|
|
822
941
|
return;
|
|
823
942
|
}
|
|
824
943
|
|
|
825
|
-
const { EntityManager } = await import("../entity/entity-manager");
|
|
826
944
|
const entity = EntityManager.get(entityId);
|
|
827
945
|
if (!entity) {
|
|
828
946
|
console.error(`Entity not found: ${entityId}`);
|
|
@@ -879,7 +997,6 @@ async function stub_entity(entityId: string) {
|
|
|
879
997
|
* ANTHROPIC_API_KEY 필요 (sonamu.secret.ts 또는 환경변수)
|
|
880
998
|
*/
|
|
881
999
|
async function cone_gen(entityId: string) {
|
|
882
|
-
const { EntityManager } = await import("../entity/entity-manager");
|
|
883
1000
|
const { flags, options } = parseCliOptions();
|
|
884
1001
|
|
|
885
1002
|
// --all 옵션: 모든 entity cone 생성
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
|
+
|
|
3
|
+
import { normalizeZodCompilerPolicy, type NormalizedZodCompilerPolicy } from "../api/config";
|
|
4
|
+
import { applyCurrentSnapshotToProcessEnv } from "../env";
|
|
5
|
+
import { isFunctionValue, isObjectValue } from "../utils/runtime-value";
|
|
6
|
+
import { ensureTsLoaderRegistered } from "./ts-loader-registration";
|
|
7
|
+
|
|
8
|
+
type BuildSourceConfig = {
|
|
9
|
+
validation?: {
|
|
10
|
+
zodCompiler?: unknown;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export async function loadBuildCompilerPolicy(
|
|
15
|
+
apiRootPath: string,
|
|
16
|
+
): Promise<NormalizedZodCompilerPolicy> {
|
|
17
|
+
applyCurrentSnapshotToProcessEnv(apiRootPath);
|
|
18
|
+
await ensureTsLoaderRegistered(apiRootPath);
|
|
19
|
+
|
|
20
|
+
const configUrl = pathToFileURL(`${apiRootPath}/src/sonamu.config.ts`);
|
|
21
|
+
configUrl.searchParams.set("sonamu-build", `${Date.now()}-${Math.random()}`);
|
|
22
|
+
const imported =
|
|
23
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ (await import(
|
|
24
|
+
configUrl.href
|
|
25
|
+
)) as { default: unknown };
|
|
26
|
+
const configured = isFunctionValue(imported.default)
|
|
27
|
+
? await Promise.resolve(imported.default())
|
|
28
|
+
: await Promise.resolve(imported.default);
|
|
29
|
+
if (!isObjectValue(configured) || configured === null || Array.isArray(configured)) {
|
|
30
|
+
throw new Error("sonamu.config.ts must export a configuration object");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const config: BuildSourceConfig = configured;
|
|
34
|
+
return normalizeZodCompilerPolicy(config.validation?.zodCompiler);
|
|
35
|
+
}
|
package/src/bin/fixture.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import prompts from "prompts";
|
|
3
|
+
import { z } from "zod";
|
|
3
4
|
|
|
4
5
|
import { Sonamu } from "../api/sonamu";
|
|
5
6
|
import { DB } from "../database/db";
|
|
@@ -23,6 +24,16 @@ interface FixtureCommandOptions {
|
|
|
23
24
|
"no-cache"?: boolean;
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
interface SignupBody {
|
|
28
|
+
name: string;
|
|
29
|
+
email: string;
|
|
30
|
+
username: string;
|
|
31
|
+
password: string;
|
|
32
|
+
display_username?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const SignupErrorResponse = z.object({ code: z.string().optional() }).passthrough();
|
|
36
|
+
|
|
26
37
|
/**
|
|
27
38
|
* username을 일반적인 규칙(영문자 시작, 영문자/숫자만, 1-20자)에 맞도록 정규화합니다.
|
|
28
39
|
*/
|
|
@@ -162,7 +173,7 @@ export async function fixtureGenCommand(options: FixtureCommandOptions) {
|
|
|
162
173
|
const displayUsername =
|
|
163
174
|
userData.display_username !== undefined ? String(userData.display_username) : undefined;
|
|
164
175
|
|
|
165
|
-
const body:
|
|
176
|
+
const body: SignupBody = {
|
|
166
177
|
name,
|
|
167
178
|
email,
|
|
168
179
|
username,
|
|
@@ -181,8 +192,8 @@ export async function fixtureGenCommand(options: FixtureCommandOptions) {
|
|
|
181
192
|
const response = await Sonamu.auth.handler(req);
|
|
182
193
|
|
|
183
194
|
if (!response.ok) {
|
|
184
|
-
const responseData = (await response.json())
|
|
185
|
-
const code =
|
|
195
|
+
const responseData = SignupErrorResponse.parse(await response.json());
|
|
196
|
+
const code = responseData.code;
|
|
186
197
|
if (code === "USER_ALREADY_EXISTS") {
|
|
187
198
|
console.log(chalk.yellow(` ⚠️ ${email} 이미 존재 - 건너뜁니다.`));
|
|
188
199
|
continue;
|
package/src/bin/test-command.ts
CHANGED
|
@@ -2,17 +2,58 @@ import path from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
|
|
5
|
-
import { type SonamuConfig } from "../api/config";
|
|
6
5
|
import { loadConfig } from "../api/config";
|
|
7
6
|
import { type RunResult, type TestCaseResult } from "../testing";
|
|
7
|
+
import { isStringValue } from "../utils/runtime-value";
|
|
8
8
|
import { findApiRootPath } from "../utils/utils";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
interface TestServerLocation {
|
|
11
|
+
host: string;
|
|
12
|
+
port: number;
|
|
13
|
+
routePrefix: string;
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface TestRunPayload {
|
|
18
|
+
files?: string[];
|
|
19
|
+
pattern?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type TestCommandConfig = {
|
|
23
|
+
server: {
|
|
24
|
+
listen?: {
|
|
25
|
+
host?: string;
|
|
26
|
+
port?: number;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
test?: {
|
|
30
|
+
devRunner?: {
|
|
31
|
+
enabled?: boolean;
|
|
32
|
+
routePrefix?: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export interface TestCommandDependencies {
|
|
38
|
+
fetch: typeof globalThis.fetch;
|
|
39
|
+
findApiRootPath: typeof findApiRootPath;
|
|
40
|
+
loadConfig: (apiRootPath: string) => Promise<TestCommandConfig>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const testCommandDependencies: TestCommandDependencies = {
|
|
44
|
+
fetch: globalThis.fetch,
|
|
45
|
+
findApiRootPath,
|
|
46
|
+
loadConfig,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
async function loadDevServerConfig(
|
|
50
|
+
dependencies: TestCommandDependencies,
|
|
51
|
+
): Promise<TestCommandConfig> {
|
|
11
52
|
const prevVitest = process.env.VITEST;
|
|
12
53
|
process.env.VITEST = "true";
|
|
13
54
|
try {
|
|
14
|
-
const apiRootPath = findApiRootPath();
|
|
15
|
-
return await loadConfig(apiRootPath);
|
|
55
|
+
const apiRootPath = dependencies.findApiRootPath();
|
|
56
|
+
return await dependencies.loadConfig(apiRootPath);
|
|
16
57
|
} finally {
|
|
17
58
|
if (prevVitest === undefined) {
|
|
18
59
|
delete process.env.VITEST;
|
|
@@ -22,22 +63,19 @@ async function loadDevServerConfig(): Promise<SonamuConfig> {
|
|
|
22
63
|
}
|
|
23
64
|
}
|
|
24
65
|
|
|
25
|
-
function resolveTestBaseUrl(config:
|
|
26
|
-
host: string;
|
|
27
|
-
port: number;
|
|
28
|
-
routePrefix: string;
|
|
29
|
-
baseUrl: string;
|
|
30
|
-
} {
|
|
66
|
+
function resolveTestBaseUrl(config: TestCommandConfig): TestServerLocation {
|
|
31
67
|
const port = config.server.listen?.port ?? 3000;
|
|
32
68
|
const host = config.server.listen?.host ?? "localhost";
|
|
33
69
|
const routePrefix = config.test?.devRunner?.routePrefix ?? "/__test__";
|
|
34
70
|
return { host, port, routePrefix, baseUrl: `http://${host}:${port}${routePrefix}` };
|
|
35
71
|
}
|
|
36
72
|
|
|
37
|
-
export async function testCommand(
|
|
73
|
+
export async function testCommand(
|
|
74
|
+
dependencies: TestCommandDependencies = testCommandDependencies,
|
|
75
|
+
): Promise<void> {
|
|
38
76
|
const args = process.argv.slice(3);
|
|
39
77
|
|
|
40
|
-
const config = await loadDevServerConfig();
|
|
78
|
+
const config = await loadDevServerConfig(dependencies);
|
|
41
79
|
|
|
42
80
|
// process.argv 파싱: sonamu test [file...] --pattern "이름" --traces --status
|
|
43
81
|
const files: string[] = [];
|
|
@@ -59,7 +97,7 @@ export async function testCommand(): Promise<void> {
|
|
|
59
97
|
}
|
|
60
98
|
|
|
61
99
|
if (showStatus) {
|
|
62
|
-
return testStatusCommand(config);
|
|
100
|
+
return testStatusCommand(config, dependencies.fetch);
|
|
63
101
|
}
|
|
64
102
|
|
|
65
103
|
if (!config.test?.devRunner?.enabled) {
|
|
@@ -74,7 +112,7 @@ export async function testCommand(): Promise<void> {
|
|
|
74
112
|
const { baseUrl } = resolveTestBaseUrl(config);
|
|
75
113
|
const url = `${baseUrl}/run`;
|
|
76
114
|
|
|
77
|
-
const payload:
|
|
115
|
+
const payload: TestRunPayload = {};
|
|
78
116
|
if (files.length > 0) {
|
|
79
117
|
payload.files = files;
|
|
80
118
|
}
|
|
@@ -83,7 +121,7 @@ export async function testCommand(): Promise<void> {
|
|
|
83
121
|
}
|
|
84
122
|
|
|
85
123
|
try {
|
|
86
|
-
const response = await fetch(url, {
|
|
124
|
+
const response = await dependencies.fetch(url, {
|
|
87
125
|
method: "POST",
|
|
88
126
|
headers: { "Content-Type": "application/json" },
|
|
89
127
|
body: JSON.stringify(payload),
|
|
@@ -99,7 +137,10 @@ export async function testCommand(): Promise<void> {
|
|
|
99
137
|
}
|
|
100
138
|
|
|
101
139
|
if (response.status === 500) {
|
|
102
|
-
const errorBody =
|
|
140
|
+
const errorBody =
|
|
141
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ (await response.json()) as {
|
|
142
|
+
error?: string;
|
|
143
|
+
};
|
|
103
144
|
console.error(chalk.red("Vitest 인스턴스가 아직 준비되지 않았습니다"));
|
|
104
145
|
if (errorBody.error) {
|
|
105
146
|
console.error(chalk.red(errorBody.error));
|
|
@@ -112,7 +153,8 @@ export async function testCommand(): Promise<void> {
|
|
|
112
153
|
process.exit(1);
|
|
113
154
|
}
|
|
114
155
|
|
|
115
|
-
const result =
|
|
156
|
+
const result =
|
|
157
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ (await response.json()) as RunResult;
|
|
116
158
|
|
|
117
159
|
const { passed, failed: failedCount, total, durationMs } = result.summary;
|
|
118
160
|
const passedStr = chalk.green(`${passed} passed`);
|
|
@@ -141,10 +183,9 @@ export async function testCommand(): Promise<void> {
|
|
|
141
183
|
console.log(` ${chalk.dim(path.basename(file))}`);
|
|
142
184
|
for (const trace of traces) {
|
|
143
185
|
const loc = `${path.basename(trace.filePath)}:${trace.lineNumber}`;
|
|
144
|
-
const valueStr =
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
: (JSON.stringify(trace.value, null, 2) ?? "undefined");
|
|
186
|
+
const valueStr = isStringValue(trace.value)
|
|
187
|
+
? trace.value
|
|
188
|
+
: (JSON.stringify(trace.value, null, 2) ?? "undefined");
|
|
148
189
|
console.log(`\n ${chalk.yellow(`[${trace.key}]`)} ${chalk.dim(loc)}`);
|
|
149
190
|
const indented = valueStr.split("\n").join("\n ");
|
|
150
191
|
console.log(` ${indented}`);
|
|
@@ -195,7 +236,10 @@ function collectTracesFromResults(
|
|
|
195
236
|
return result;
|
|
196
237
|
}
|
|
197
238
|
|
|
198
|
-
async function testStatusCommand(
|
|
239
|
+
async function testStatusCommand(
|
|
240
|
+
config: TestCommandConfig,
|
|
241
|
+
fetchRequest: typeof globalThis.fetch,
|
|
242
|
+
): Promise<void> {
|
|
199
243
|
if (!config.test?.devRunner?.enabled) {
|
|
200
244
|
console.error(
|
|
201
245
|
chalk.red(
|
|
@@ -209,19 +253,20 @@ async function testStatusCommand(config: SonamuConfig): Promise<void> {
|
|
|
209
253
|
const url = `${baseUrl}/status`;
|
|
210
254
|
|
|
211
255
|
try {
|
|
212
|
-
const response = await
|
|
256
|
+
const response = await fetchRequest(url);
|
|
213
257
|
|
|
214
258
|
if (!response.ok) {
|
|
215
259
|
console.error(chalk.red(`예상하지 못한 응답: ${response.status}`));
|
|
216
260
|
process.exit(1);
|
|
217
261
|
}
|
|
218
262
|
|
|
219
|
-
const status =
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
263
|
+
const status =
|
|
264
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ (await response.json()) as {
|
|
265
|
+
ready: boolean;
|
|
266
|
+
running: boolean;
|
|
267
|
+
lastRunAt: string | null;
|
|
268
|
+
sseAvailable: boolean;
|
|
269
|
+
};
|
|
225
270
|
|
|
226
271
|
console.log(chalk.bold("DevRunner 상태:"));
|
|
227
272
|
console.log(` ready: ${status.ready ? chalk.green("true") : chalk.red("false")}`);
|
|
@@ -13,8 +13,23 @@ type GlobalWithTsLoaderRegisterState = typeof globalThis & {
|
|
|
13
13
|
[tsLoaderRegisterStateKey]?: TsLoaderRegisterState;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
export interface TsLoaderRegistrationDependencies {
|
|
17
|
+
registerLoader: (specifier: string, options: { parentURL: string }) => void;
|
|
18
|
+
resolveLoaderPath: () => string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const tsLoaderRegistrationDependencies: TsLoaderRegistrationDependencies = {
|
|
22
|
+
registerLoader(specifier, options) {
|
|
23
|
+
register(specifier, options);
|
|
24
|
+
},
|
|
25
|
+
resolveLoaderPath() {
|
|
26
|
+
return require.resolve("@sonamu-kit/ts-loader/loader");
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
16
30
|
function getTsLoaderRegisterState(): TsLoaderRegisterState {
|
|
17
|
-
const globalState =
|
|
31
|
+
const globalState =
|
|
32
|
+
/* SAFETY: CLI 파서와 빌드 도구 입력 계약이 이 값의 타입을 보장한다. */ globalThis as GlobalWithTsLoaderRegisterState;
|
|
18
33
|
|
|
19
34
|
if (!globalState[tsLoaderRegisterStateKey]) {
|
|
20
35
|
globalState[tsLoaderRegisterStateKey] = { registered: false };
|
|
@@ -23,16 +38,19 @@ function getTsLoaderRegisterState(): TsLoaderRegisterState {
|
|
|
23
38
|
return globalState[tsLoaderRegisterStateKey];
|
|
24
39
|
}
|
|
25
40
|
|
|
26
|
-
export async function ensureTsLoaderRegistered(
|
|
41
|
+
export async function ensureTsLoaderRegistered(
|
|
42
|
+
apiRoot: string,
|
|
43
|
+
dependencies: TsLoaderRegistrationDependencies = tsLoaderRegistrationDependencies,
|
|
44
|
+
): Promise<void> {
|
|
27
45
|
const state = getTsLoaderRegisterState();
|
|
28
46
|
if (state.registered) {
|
|
29
47
|
return;
|
|
30
48
|
}
|
|
31
49
|
|
|
32
50
|
void apiRoot;
|
|
33
|
-
const loaderPath =
|
|
51
|
+
const loaderPath = dependencies.resolveLoaderPath();
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
dependencies.registerLoader(pathToFileURL(loaderPath).href, {
|
|
36
54
|
parentURL: import.meta.url,
|
|
37
55
|
});
|
|
38
56
|
state.registered = true;
|