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/api.ts
CHANGED
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
ServiceUnavailableException,
|
|
21
21
|
} from "../exceptions/so-exceptions";
|
|
22
22
|
import { TemplateManager } from "../template/template-manager";
|
|
23
|
-
import { DataExplorer } from "../testing/data-explorer";
|
|
24
|
-
import { FixtureGenerator } from "../testing/fixture-generator";
|
|
23
|
+
import { DataExplorer, type DataExplorerOptions } from "../testing/data-explorer";
|
|
24
|
+
import { FixtureGenerator, type FixtureGenerationSpec } from "../testing/fixture-generator";
|
|
25
25
|
import { FixtureManager } from "../testing/fixture-manager";
|
|
26
26
|
import { type DuplicateCheckOptions } from "../testing/fixture-manager";
|
|
27
27
|
import { BUILT_IN_TYPE_IDS, TemplateKey } from "../types/types";
|
|
@@ -35,8 +35,10 @@ import {
|
|
|
35
35
|
type FlattenSubsetRow,
|
|
36
36
|
type PathAndCode,
|
|
37
37
|
} from "../types/types";
|
|
38
|
+
import { isObjectValue } from "../utils/runtime-value";
|
|
38
39
|
import { nonNullable } from "../utils/utils";
|
|
39
40
|
import { setAiApi } from "./ai-api";
|
|
41
|
+
import { forwardAsyncErrors } from "./async-route";
|
|
40
42
|
import { type CddAddRuleRequest } from "./cdd-service";
|
|
41
43
|
import {
|
|
42
44
|
addRule,
|
|
@@ -50,30 +52,41 @@ import {
|
|
|
50
52
|
} from "./cdd-service";
|
|
51
53
|
import { registerMigrationsApi } from "./migrations-api";
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
async function waitForHMRCompleted<T>(fn: () => Promise<T>): Promise<T> {
|
|
58
|
-
const waitPromise = new Promise<void>((resolve) => {
|
|
59
|
-
const handler = () => {
|
|
60
|
-
clearTimeout(timeout);
|
|
61
|
-
resolve();
|
|
62
|
-
};
|
|
55
|
+
interface EntityTemplateInput {
|
|
56
|
+
entityId: string;
|
|
57
|
+
enumId?: string;
|
|
58
|
+
}
|
|
63
59
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
async function waitForHMRCompleted<T>(fn: () => Promise<T>): Promise<T> {
|
|
61
|
+
const waitPromise = new Promise<void>((resolve) => {
|
|
62
|
+
const handler = () => {
|
|
63
|
+
clearTimeout(timeout);
|
|
64
|
+
resolve();
|
|
65
|
+
};
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
const timeout = setTimeout(() => {
|
|
68
|
+
Sonamu.syncer.eventEmitter.off("onHMRCompleted", handler);
|
|
69
|
+
resolve();
|
|
70
|
+
}, 1500);
|
|
71
|
+
|
|
72
|
+
Sonamu.syncer.eventEmitter.once("onHMRCompleted", handler);
|
|
73
|
+
});
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
const result = await fn();
|
|
76
|
+
await waitPromise;
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
76
79
|
|
|
80
|
+
function flattenSubsetRows(subsetRows: EntitySubsetRow[]): FlattenSubsetRow[] {
|
|
81
|
+
return subsetRows.flatMap((subsetRow) => {
|
|
82
|
+
const { children, ...sRow } = subsetRow;
|
|
83
|
+
return [sRow, ...flattenSubsetRows(children)];
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
88
|
+
fastify.register(
|
|
89
|
+
async (server) => {
|
|
77
90
|
await setAiApi(server);
|
|
78
91
|
await registerMigrationsApi(server);
|
|
79
92
|
|
|
@@ -87,185 +100,188 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
87
100
|
preset?: "types" | "entity.json" | "generated";
|
|
88
101
|
absPath?: string;
|
|
89
102
|
};
|
|
90
|
-
}>("/api/tools/openVscode",
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
}>("/api/tools/openVscode", (request) =>
|
|
104
|
+
forwardAsyncErrors(async () => {
|
|
105
|
+
const { entityId, preset, absPath } = request.query;
|
|
106
|
+
|
|
107
|
+
const targetPath = (() => {
|
|
108
|
+
if (entityId && preset) {
|
|
109
|
+
const entity = EntityManager.get(entityId);
|
|
110
|
+
const { names } = entity;
|
|
111
|
+
|
|
112
|
+
const { apiRootPath } = Sonamu;
|
|
113
|
+
const filename = (() => {
|
|
114
|
+
switch (preset) {
|
|
115
|
+
case "types":
|
|
116
|
+
return `${names.fs}.types.ts`;
|
|
117
|
+
case "entity.json":
|
|
118
|
+
return `${names.fs}.entity.json`;
|
|
119
|
+
case "generated":
|
|
120
|
+
return `${names.fs}.generated.ts`;
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
})();
|
|
124
|
+
return `${apiRootPath}/src/application/${entity.names.parentFs}/${filename}`;
|
|
125
|
+
} else {
|
|
126
|
+
if (!absPath) {
|
|
127
|
+
throw new BadRequestException(SD("sonamu.error.presetOrAbsPathRequired"));
|
|
107
128
|
}
|
|
108
|
-
|
|
109
|
-
return `${apiRootPath}/src/application/${entity.names.parentFs}/${filename}`;
|
|
110
|
-
} else {
|
|
111
|
-
if (!absPath) {
|
|
112
|
-
throw new BadRequestException(SD("sonamu.error.presetOrAbsPathRequired"));
|
|
129
|
+
return absPath;
|
|
113
130
|
}
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
});
|
|
131
|
+
})();
|
|
132
|
+
execSync(`code ${targetPath}`);
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
119
135
|
|
|
120
136
|
server.get<{
|
|
121
137
|
Querystring: {
|
|
122
138
|
editor: "vscode" | "cursor" | "zed";
|
|
123
139
|
absPath: string;
|
|
124
140
|
};
|
|
125
|
-
}>("/api/tools/openEditor",
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
141
|
+
}>("/api/tools/openEditor", (request) =>
|
|
142
|
+
forwardAsyncErrors(async () => {
|
|
143
|
+
const commands = {
|
|
144
|
+
vscode: "code",
|
|
145
|
+
cursor: "cursor",
|
|
146
|
+
zed: "zed",
|
|
147
|
+
} as const;
|
|
148
|
+
const command = commands[request.query.editor];
|
|
149
|
+
if (command === undefined) {
|
|
150
|
+
throw new BadRequestException(SD("error.badRequest"));
|
|
151
|
+
}
|
|
135
152
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
153
|
+
// 셸을 거치지 않아 파일 경로가 명령으로 해석되지 않도록 합니다.
|
|
154
|
+
execFileSync(command, [request.query.absPath]);
|
|
155
|
+
}),
|
|
156
|
+
);
|
|
139
157
|
|
|
140
158
|
server.get<{
|
|
141
159
|
Querystring: {
|
|
142
160
|
origin: string;
|
|
143
161
|
entityId?: string;
|
|
144
162
|
};
|
|
145
|
-
}>("/api/tools/getSuggestion",
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
entity.props.forEach((prop) => {
|
|
209
|
-
if (glossary.has(prop.name)) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if (prop.desc) {
|
|
213
|
-
glossary.set(prop.name, prop.desc.replace(entity.title ?? "", "{EntityID}"));
|
|
163
|
+
}>("/api/tools/getSuggestion", (request) =>
|
|
164
|
+
forwardAsyncErrors(async () => {
|
|
165
|
+
const { origin, entityId } = request.query;
|
|
166
|
+
|
|
167
|
+
// 치환 용어집
|
|
168
|
+
const glossary = new Map<string, string>([
|
|
169
|
+
["status", "상태"],
|
|
170
|
+
["type", "타입"],
|
|
171
|
+
["image", "이미지"],
|
|
172
|
+
["images", "이미지리스트"],
|
|
173
|
+
["url", "URL"],
|
|
174
|
+
["id", "ID"],
|
|
175
|
+
["name", `{EntityID}명`],
|
|
176
|
+
["title", "{EntityID}명"],
|
|
177
|
+
["parent", "상위{EntityID}"],
|
|
178
|
+
["desc", "설명"],
|
|
179
|
+
["at", "일시"],
|
|
180
|
+
["created", "등록"],
|
|
181
|
+
["updated", "수정"],
|
|
182
|
+
["deleted", "삭제"],
|
|
183
|
+
["by", "유저"],
|
|
184
|
+
["date", "일자"],
|
|
185
|
+
["time", "시간"],
|
|
186
|
+
["ko", "(한글)"],
|
|
187
|
+
["en", "(영문)"],
|
|
188
|
+
["krw", "(원)"],
|
|
189
|
+
["usd", "(USD)"],
|
|
190
|
+
["color", "컬러"],
|
|
191
|
+
["code", "코드"],
|
|
192
|
+
["x", "X좌표"],
|
|
193
|
+
["y", "Y좌표"],
|
|
194
|
+
["current", "현재"],
|
|
195
|
+
["stock", "재고"],
|
|
196
|
+
["total", "총"],
|
|
197
|
+
["admin", "관리자"],
|
|
198
|
+
["group", "그룹"],
|
|
199
|
+
["item", "아이템"],
|
|
200
|
+
["cnt", "수량"],
|
|
201
|
+
["price", "가격"],
|
|
202
|
+
["preset", "프리셋"],
|
|
203
|
+
["acct", "계좌"],
|
|
204
|
+
["tel", "전화번호"],
|
|
205
|
+
["no", "번호"],
|
|
206
|
+
["body", "내용"],
|
|
207
|
+
["content", "내용"],
|
|
208
|
+
["orderno", "정렬순서"],
|
|
209
|
+
["priority", "우선순위"],
|
|
210
|
+
["text", "텍스트"],
|
|
211
|
+
["key", "키"],
|
|
212
|
+
["sum", "합산"],
|
|
213
|
+
["expected", "예상"],
|
|
214
|
+
["actual", "실제"],
|
|
215
|
+
]);
|
|
216
|
+
// 전체 엔티티 순회하며, 엔티티 타이틀과 프롭 설명을 치환 용어집에 추가
|
|
217
|
+
for (const glossaryEntityId of EntityManager.getAllIds()) {
|
|
218
|
+
const glossaryEntity = EntityManager.get(glossaryEntityId);
|
|
219
|
+
if ((glossaryEntity.title ?? "") !== "") {
|
|
220
|
+
glossary.set(inflection.underscore(glossaryEntity.id), glossaryEntity.title);
|
|
221
|
+
glossary.set(
|
|
222
|
+
inflection.underscore(inflection.pluralize(glossaryEntity.id)),
|
|
223
|
+
`${glossaryEntity.title}리스트`,
|
|
224
|
+
);
|
|
214
225
|
}
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
226
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
];
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// 조합을 순회하며, 치환 용어집에 있는 단어가 포함된 경우, 치환 용어로 치환
|
|
233
|
-
const REPLACED_PREFIX = "#REPLACED//"; // 치환된 단어를 join 이후에도 식별하기 위해 prefix 추가
|
|
234
|
-
let remainArr: string[] = [...words];
|
|
235
|
-
for (const comb of combinations) {
|
|
236
|
-
const remainStr = remainArr.join("_");
|
|
237
|
-
if (remainStr.includes(comb.w) && glossary.has(comb.w)) {
|
|
238
|
-
remainArr = remainStr
|
|
239
|
-
.replace(comb.w, REPLACED_PREFIX + glossary.get(comb.w))
|
|
240
|
-
.split("_");
|
|
241
|
-
}
|
|
227
|
+
glossaryEntity.props.forEach((prop) => {
|
|
228
|
+
if (glossary.has(prop.name)) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (prop.desc) {
|
|
232
|
+
glossary.set(
|
|
233
|
+
prop.name,
|
|
234
|
+
prop.desc.replace(glossaryEntity.title ?? "", "{EntityID}"),
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
242
238
|
}
|
|
243
239
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
240
|
+
const suggested = (() => {
|
|
241
|
+
// 단어 분리, 가능한 조합 생성
|
|
242
|
+
const words = origin.split("_");
|
|
243
|
+
const combinations = [...range(words.length, 0, -1)].flatMap((len) => {
|
|
244
|
+
return [
|
|
245
|
+
...range(0, words.length - len + 1, (idx) => {
|
|
246
|
+
return {
|
|
247
|
+
len,
|
|
248
|
+
w: words.slice(idx, idx + len).join("_"),
|
|
249
|
+
};
|
|
250
|
+
}),
|
|
251
|
+
];
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// 조합을 순회하며, 치환 용어집에 있는 단어가 포함된 경우, 치환 용어로 치환
|
|
255
|
+
const REPLACED_PREFIX = "#REPLACED//"; // 치환된 단어를 join 이후에도 식별하기 위해 prefix 추가
|
|
256
|
+
let remainArr: string[] = [...words];
|
|
257
|
+
for (const comb of combinations) {
|
|
258
|
+
const remainStr = remainArr.join("_");
|
|
259
|
+
if (remainStr.includes(comb.w) && glossary.has(comb.w)) {
|
|
260
|
+
remainArr = remainStr
|
|
261
|
+
.replace(comb.w, REPLACED_PREFIX + glossary.get(comb.w))
|
|
262
|
+
.split("_");
|
|
250
263
|
}
|
|
251
|
-
}
|
|
252
|
-
.join("")
|
|
253
|
-
.replace(/{EntityID}/g, entityId ? EntityManager.get(entityId).title : "");
|
|
254
|
-
})();
|
|
264
|
+
}
|
|
255
265
|
|
|
256
|
-
|
|
257
|
-
|
|
266
|
+
return remainArr
|
|
267
|
+
.map((r) => {
|
|
268
|
+
if (r.startsWith(REPLACED_PREFIX)) {
|
|
269
|
+
return r.replace(REPLACED_PREFIX, "");
|
|
270
|
+
} else {
|
|
271
|
+
return r.toUpperCase();
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
.join("")
|
|
275
|
+
.replace(/{EntityID}/g, entityId ? EntityManager.get(entityId).title : "");
|
|
276
|
+
})();
|
|
277
|
+
|
|
278
|
+
return { suggested };
|
|
279
|
+
}),
|
|
280
|
+
);
|
|
258
281
|
|
|
259
282
|
server.get("/api/entity/findMany", async () => {
|
|
260
283
|
const entityIds = EntityManager.getAllIds();
|
|
261
284
|
|
|
262
|
-
function flattenSubsetRows(subsetRows: EntitySubsetRow[]): FlattenSubsetRow[] {
|
|
263
|
-
return subsetRows.flatMap((subsetRow) => {
|
|
264
|
-
const { children, ...sRow } = subsetRow;
|
|
265
|
-
return [sRow, ...flattenSubsetRows(children)];
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
285
|
const entities = await Promise.all(
|
|
270
286
|
entityIds.map((entityId) => {
|
|
271
287
|
const entity = EntityManager.get(entityId);
|
|
@@ -307,45 +323,55 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
307
323
|
filter?: "enums" | "types";
|
|
308
324
|
reload?: "1";
|
|
309
325
|
};
|
|
310
|
-
}>(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const projectTypeIds = Object.entries(Sonamu.syncer.types)
|
|
320
|
-
.filter(([_typeId, zodType]) => (zodType._zod.def.type as string) !== "enum")
|
|
321
|
-
.map(([typeId, _zodType]) => typeId);
|
|
322
|
-
|
|
323
|
-
// 내장 타입들 (sonamu 코어에서 제공)
|
|
324
|
-
const builtInTypeIds = [...BUILT_IN_TYPE_IDS];
|
|
325
|
-
|
|
326
|
-
// 모든 타입 병합
|
|
327
|
-
const allTypeIds = [...builtInTypeIds, ...projectTypeIds];
|
|
326
|
+
}>(
|
|
327
|
+
"/api/entity/typeIds",
|
|
328
|
+
(request): Promise<{ typeIds: string[] }> =>
|
|
329
|
+
forwardAsyncErrors(async () => {
|
|
330
|
+
const { filter, reload } = request.query;
|
|
331
|
+
|
|
332
|
+
if (reload === "1") {
|
|
333
|
+
await Sonamu.syncer.autoloadTypes();
|
|
334
|
+
}
|
|
328
335
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
336
|
+
const typeIds = (() => {
|
|
337
|
+
// 프로젝트에서 정의한 타입들
|
|
338
|
+
const projectTypeIds = Object.entries(Sonamu.syncer.types)
|
|
339
|
+
.filter(([_typeId, zodType]) => {
|
|
340
|
+
const { _zod: zodMetadata } = zodType;
|
|
341
|
+
return (
|
|
342
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ (zodMetadata
|
|
343
|
+
.def.type as string) !== "enum"
|
|
344
|
+
);
|
|
345
|
+
})
|
|
346
|
+
.map(([typeId, _zodType]) => typeId);
|
|
347
|
+
|
|
348
|
+
// 내장 타입들 (sonamu 코어에서 제공)
|
|
349
|
+
const builtInTypeIds = [...BUILT_IN_TYPE_IDS];
|
|
350
|
+
|
|
351
|
+
// 모든 타입 병합
|
|
352
|
+
const allTypeIds = [...builtInTypeIds, ...projectTypeIds];
|
|
353
|
+
|
|
354
|
+
if (filter === "types") {
|
|
355
|
+
return allTypeIds;
|
|
356
|
+
}
|
|
332
357
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
358
|
+
const enumIds = EntityManager.getAllIds().flatMap((entityId) => {
|
|
359
|
+
const entity = EntityManager.get(entityId);
|
|
360
|
+
return Object.keys(entity.enumLabels);
|
|
361
|
+
});
|
|
337
362
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
363
|
+
if (filter === "enums") {
|
|
364
|
+
return enumIds;
|
|
365
|
+
} else {
|
|
366
|
+
return [...allTypeIds, ...enumIds];
|
|
367
|
+
}
|
|
368
|
+
})();
|
|
344
369
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
370
|
+
return {
|
|
371
|
+
typeIds,
|
|
372
|
+
};
|
|
373
|
+
}),
|
|
374
|
+
);
|
|
349
375
|
|
|
350
376
|
server.post<{
|
|
351
377
|
Body: {
|
|
@@ -356,25 +382,29 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
356
382
|
parentId?: string;
|
|
357
383
|
};
|
|
358
384
|
};
|
|
359
|
-
}>("/api/entity/create",
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
385
|
+
}>("/api/entity/create", (request) =>
|
|
386
|
+
forwardAsyncErrors(async () => {
|
|
387
|
+
return await waitForHMRCompleted(async () => {
|
|
388
|
+
const { form } = request.body;
|
|
389
|
+
await Sonamu.syncer.createEntity({ ...form, entityId: form.id });
|
|
363
390
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
391
|
+
return 1;
|
|
392
|
+
});
|
|
393
|
+
}),
|
|
394
|
+
);
|
|
367
395
|
|
|
368
396
|
server.post<{
|
|
369
397
|
Body: {
|
|
370
398
|
entityId: string;
|
|
371
399
|
};
|
|
372
|
-
}>("/api/entity/del",
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
400
|
+
}>("/api/entity/del", (request) =>
|
|
401
|
+
forwardAsyncErrors(async () => {
|
|
402
|
+
return await waitForHMRCompleted(async () => {
|
|
403
|
+
const { entityId } = request.body;
|
|
404
|
+
return await Sonamu.syncer.delEntity(entityId);
|
|
405
|
+
});
|
|
406
|
+
}),
|
|
407
|
+
);
|
|
378
408
|
|
|
379
409
|
server.post<{
|
|
380
410
|
Body: {
|
|
@@ -385,18 +415,20 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
385
415
|
parentId?: string;
|
|
386
416
|
};
|
|
387
417
|
};
|
|
388
|
-
}>("/api/entity/modifyEntityBase",
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
418
|
+
}>("/api/entity/modifyEntityBase", (request) =>
|
|
419
|
+
forwardAsyncErrors(async () => {
|
|
420
|
+
return await waitForHMRCompleted(async () => {
|
|
421
|
+
const { entityId, newValues } = request.body;
|
|
422
|
+
const entity = EntityManager.get(entityId);
|
|
423
|
+
entity.title = newValues.title;
|
|
424
|
+
entity.table = newValues.table;
|
|
425
|
+
entity.parentId = newValues.parentId;
|
|
426
|
+
await entity.save();
|
|
396
427
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
428
|
+
return 1;
|
|
429
|
+
});
|
|
430
|
+
}),
|
|
431
|
+
);
|
|
400
432
|
|
|
401
433
|
server.post<{
|
|
402
434
|
Body: {
|
|
@@ -405,40 +437,44 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
405
437
|
fields: string[];
|
|
406
438
|
fieldsInternal?: string[];
|
|
407
439
|
};
|
|
408
|
-
}>("/api/entity/modifySubset",
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if (fieldsInternal
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
440
|
+
}>("/api/entity/modifySubset", (request) =>
|
|
441
|
+
forwardAsyncErrors(async () => {
|
|
442
|
+
return await waitForHMRCompleted(async () => {
|
|
443
|
+
const { entityId, subsetKey, fields, fieldsInternal } = request.body;
|
|
444
|
+
const entity = EntityManager.get(entityId);
|
|
445
|
+
entity.subsets[subsetKey] = fields;
|
|
446
|
+
if (fieldsInternal !== undefined) {
|
|
447
|
+
if (fieldsInternal.length > 0) {
|
|
448
|
+
entity.subsetsInternal[subsetKey] = fieldsInternal;
|
|
449
|
+
} else {
|
|
450
|
+
delete entity.subsetsInternal[subsetKey];
|
|
451
|
+
}
|
|
418
452
|
}
|
|
419
|
-
|
|
420
|
-
await entity.save();
|
|
453
|
+
await entity.save();
|
|
421
454
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
455
|
+
return { updated: fields, updatedInternal: fieldsInternal };
|
|
456
|
+
});
|
|
457
|
+
}),
|
|
458
|
+
);
|
|
425
459
|
|
|
426
460
|
server.post<{
|
|
427
461
|
Body: {
|
|
428
462
|
entityId: string;
|
|
429
463
|
subsetKey: string;
|
|
430
464
|
};
|
|
431
|
-
}>("/api/entity/delSubset",
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
465
|
+
}>("/api/entity/delSubset", (request) =>
|
|
466
|
+
forwardAsyncErrors(async () => {
|
|
467
|
+
return await waitForHMRCompleted(async () => {
|
|
468
|
+
const { entityId, subsetKey } = request.body;
|
|
469
|
+
const entity = EntityManager.get(entityId);
|
|
470
|
+
delete entity.subsets[subsetKey];
|
|
471
|
+
delete entity.subsetsInternal[subsetKey];
|
|
472
|
+
await entity.save();
|
|
438
473
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
474
|
+
return 1;
|
|
475
|
+
});
|
|
476
|
+
}),
|
|
477
|
+
);
|
|
442
478
|
|
|
443
479
|
server.post<{
|
|
444
480
|
Body: {
|
|
@@ -446,14 +482,16 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
446
482
|
newProp: EntityProp;
|
|
447
483
|
at?: number;
|
|
448
484
|
};
|
|
449
|
-
}>("/api/entity/createProp",
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
485
|
+
}>("/api/entity/createProp", (request) =>
|
|
486
|
+
forwardAsyncErrors(async () => {
|
|
487
|
+
return await waitForHMRCompleted(async () => {
|
|
488
|
+
const { entityId, at, newProp } = request.body;
|
|
489
|
+
const entity = EntityManager.get(entityId);
|
|
490
|
+
await entity.createProp(newProp, at);
|
|
491
|
+
return true;
|
|
492
|
+
});
|
|
493
|
+
}),
|
|
494
|
+
);
|
|
457
495
|
|
|
458
496
|
server.post<{
|
|
459
497
|
Body: {
|
|
@@ -461,31 +499,35 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
461
499
|
newProp: EntityProp;
|
|
462
500
|
at: number;
|
|
463
501
|
};
|
|
464
|
-
}>("/api/entity/modifyProp",
|
|
465
|
-
|
|
466
|
-
|
|
502
|
+
}>("/api/entity/modifyProp", (request) =>
|
|
503
|
+
forwardAsyncErrors(async () => {
|
|
504
|
+
return await waitForHMRCompleted(async () => {
|
|
505
|
+
const { entityId, at, newProp } = request.body;
|
|
467
506
|
|
|
468
|
-
|
|
469
|
-
|
|
507
|
+
const entity = EntityManager.get(entityId);
|
|
508
|
+
entity.modifyProp(newProp, at);
|
|
470
509
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
510
|
+
return true;
|
|
511
|
+
});
|
|
512
|
+
}),
|
|
513
|
+
);
|
|
474
514
|
|
|
475
515
|
server.post<{
|
|
476
516
|
Body: {
|
|
477
517
|
entityId: string;
|
|
478
518
|
at: number;
|
|
479
519
|
};
|
|
480
|
-
}>("/api/entity/delProp",
|
|
481
|
-
|
|
482
|
-
|
|
520
|
+
}>("/api/entity/delProp", (request) =>
|
|
521
|
+
forwardAsyncErrors(async () => {
|
|
522
|
+
return await waitForHMRCompleted(async () => {
|
|
523
|
+
const { entityId, at } = request.body;
|
|
483
524
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
525
|
+
const entity = EntityManager.get(entityId);
|
|
526
|
+
entity.delProp(at);
|
|
527
|
+
return true;
|
|
528
|
+
});
|
|
529
|
+
}),
|
|
530
|
+
);
|
|
489
531
|
|
|
490
532
|
server.post<{
|
|
491
533
|
Body: {
|
|
@@ -493,76 +535,84 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
493
535
|
at: number;
|
|
494
536
|
to: number;
|
|
495
537
|
};
|
|
496
|
-
}>("/api/entity/moveProp",
|
|
497
|
-
|
|
498
|
-
|
|
538
|
+
}>("/api/entity/moveProp", (request) =>
|
|
539
|
+
forwardAsyncErrors(async () => {
|
|
540
|
+
return await waitForHMRCompleted(async () => {
|
|
541
|
+
const { entityId, at, to } = request.body;
|
|
499
542
|
|
|
500
|
-
|
|
501
|
-
|
|
543
|
+
const entity = EntityManager.get(entityId);
|
|
544
|
+
entity.moveProp(at, to);
|
|
502
545
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
546
|
+
return true;
|
|
547
|
+
});
|
|
548
|
+
}),
|
|
549
|
+
);
|
|
506
550
|
|
|
507
551
|
server.post<{
|
|
508
552
|
Body: {
|
|
509
553
|
entityId: string;
|
|
510
554
|
indexes: EntityIndex[];
|
|
511
555
|
};
|
|
512
|
-
}>("/api/entity/modifyIndexes",
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
556
|
+
}>("/api/entity/modifyIndexes", (request) =>
|
|
557
|
+
forwardAsyncErrors(async () => {
|
|
558
|
+
return await waitForHMRCompleted(async () => {
|
|
559
|
+
const { entityId, indexes } = request.body;
|
|
560
|
+
const entity = EntityManager.get(entityId);
|
|
561
|
+
entity.indexes = indexes;
|
|
562
|
+
await entity.save();
|
|
518
563
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
564
|
+
return { updated: indexes };
|
|
565
|
+
});
|
|
566
|
+
}),
|
|
567
|
+
);
|
|
522
568
|
|
|
523
569
|
server.post<{
|
|
524
570
|
Body: {
|
|
525
571
|
entityId: string;
|
|
526
572
|
enumLabels: Entity["enumLabels"];
|
|
527
573
|
};
|
|
528
|
-
}>("/api/entity/modifyEnumLabels",
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
574
|
+
}>("/api/entity/modifyEnumLabels", (request) =>
|
|
575
|
+
forwardAsyncErrors(async () => {
|
|
576
|
+
return await waitForHMRCompleted(async () => {
|
|
577
|
+
const { entityId, enumLabels } = request.body;
|
|
578
|
+
const entity = EntityManager.get(entityId);
|
|
579
|
+
entity.enumLabels = enumLabels;
|
|
580
|
+
await entity.save();
|
|
534
581
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
582
|
+
return { updated: enumLabels };
|
|
583
|
+
});
|
|
584
|
+
}),
|
|
585
|
+
);
|
|
538
586
|
|
|
539
587
|
server.post<{
|
|
540
588
|
Body: {
|
|
541
589
|
entityId: string;
|
|
542
590
|
newEnumId: string;
|
|
543
591
|
};
|
|
544
|
-
}>("/api/entity/createEnumId",
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
592
|
+
}>("/api/entity/createEnumId", (request) =>
|
|
593
|
+
forwardAsyncErrors(async () => {
|
|
594
|
+
return await waitForHMRCompleted(async () => {
|
|
595
|
+
const { entityId, newEnumId } = request.body;
|
|
596
|
+
const entity = EntityManager.get(entityId);
|
|
548
597
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
598
|
+
if (entity.enumLabels[newEnumId]) {
|
|
599
|
+
throw new Error(`이미 존재하는 enumId입니다: ${newEnumId}`);
|
|
600
|
+
}
|
|
552
601
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
602
|
+
entity.enumLabels[newEnumId] = newEnumId.endsWith("Status")
|
|
603
|
+
? {
|
|
604
|
+
active: "노출",
|
|
605
|
+
hidden: "숨김",
|
|
606
|
+
}
|
|
607
|
+
: {
|
|
608
|
+
"": "",
|
|
609
|
+
};
|
|
610
|
+
await entity.save();
|
|
562
611
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
612
|
+
return 1;
|
|
613
|
+
});
|
|
614
|
+
}),
|
|
615
|
+
);
|
|
566
616
|
|
|
567
617
|
server.post<{
|
|
568
618
|
Body: {
|
|
@@ -572,58 +622,62 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
572
622
|
after: string;
|
|
573
623
|
};
|
|
574
624
|
};
|
|
575
|
-
}>("/api/entity/modifyEnumId",
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
625
|
+
}>("/api/entity/modifyEnumId", (request) =>
|
|
626
|
+
forwardAsyncErrors(async () => {
|
|
627
|
+
return await waitForHMRCompleted(async () => {
|
|
628
|
+
const { entityId, enumId } = request.body;
|
|
629
|
+
const entityIds = EntityManager.getAllIds();
|
|
630
|
+
const isExists = entityIds.some((candidateEntityId) => {
|
|
631
|
+
const candidateEntity = EntityManager.get(candidateEntityId);
|
|
632
|
+
return Object.keys(candidateEntity.enumLabels).includes(enumId.after);
|
|
633
|
+
});
|
|
634
|
+
if (isExists) {
|
|
635
|
+
throw new Error(`이미 존재하는 EnumId입니다: ${enumId.after}`);
|
|
636
|
+
}
|
|
586
637
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
638
|
+
const entity = EntityManager.get(entityId);
|
|
639
|
+
entity.enumLabels[enumId.after] = entity.enumLabels[enumId.before];
|
|
640
|
+
delete entity.enumLabels[enumId.before];
|
|
590
641
|
|
|
591
|
-
|
|
642
|
+
await entity.save();
|
|
592
643
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
644
|
+
for (const relatedEntityId of entityIds) {
|
|
645
|
+
const relatedEntity = EntityManager.get(relatedEntityId);
|
|
646
|
+
for (const prop of relatedEntity.props) {
|
|
647
|
+
if (prop.type === "enum" && prop.id === enumId.before) {
|
|
648
|
+
prop.id = enumId.after;
|
|
649
|
+
}
|
|
598
650
|
}
|
|
651
|
+
await relatedEntity.save();
|
|
599
652
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
});
|
|
653
|
+
});
|
|
654
|
+
}),
|
|
655
|
+
);
|
|
604
656
|
|
|
605
657
|
server.post<{
|
|
606
658
|
Body: {
|
|
607
659
|
entityId: string;
|
|
608
660
|
enumId: string;
|
|
609
661
|
};
|
|
610
|
-
}>("/api/entity/deleteEnumId",
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
662
|
+
}>("/api/entity/deleteEnumId", (request) =>
|
|
663
|
+
forwardAsyncErrors(async () => {
|
|
664
|
+
return await waitForHMRCompleted(async () => {
|
|
665
|
+
const { entityId, enumId } = request.body;
|
|
666
|
+
|
|
667
|
+
const entityIds = EntityManager.getAllIds();
|
|
668
|
+
const isReferenced = entityIds
|
|
669
|
+
.flatMap((referencingEntityId) => EntityManager.get(referencingEntityId).props)
|
|
670
|
+
.some((prop) => prop.type === "enum" && prop.id === enumId);
|
|
671
|
+
if (isReferenced) {
|
|
672
|
+
throw new Error(`${enumId}를 참조하는 프로퍼티가 존재합니다.`);
|
|
673
|
+
}
|
|
621
674
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
675
|
+
const entity = EntityManager.get(entityId);
|
|
676
|
+
delete entity.enumLabels[enumId];
|
|
677
|
+
await entity.save();
|
|
678
|
+
});
|
|
679
|
+
}),
|
|
680
|
+
);
|
|
627
681
|
|
|
628
682
|
server.post<{
|
|
629
683
|
Body: {
|
|
@@ -634,28 +688,32 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
634
688
|
subsetKey?: string;
|
|
635
689
|
cone: Cone;
|
|
636
690
|
};
|
|
637
|
-
}>("/api/entity/updateCone",
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
691
|
+
}>("/api/entity/updateCone", (request) =>
|
|
692
|
+
forwardAsyncErrors(async () => {
|
|
693
|
+
return await waitForHMRCompleted(async () => {
|
|
694
|
+
const { entityId, target, propName, enumId, subsetKey, cone } = request.body;
|
|
695
|
+
const entity = EntityManager.get(entityId);
|
|
641
696
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
697
|
+
if (target === "entity") {
|
|
698
|
+
entity.cone = cone;
|
|
699
|
+
} else if (target === "prop" && propName) {
|
|
700
|
+
const prop = entity.props.find((p) => p.name === propName);
|
|
701
|
+
if (prop) {
|
|
702
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ (
|
|
703
|
+
prop as { cone?: Cone }
|
|
704
|
+
).cone = cone;
|
|
705
|
+
}
|
|
706
|
+
} else if (target === "enum" && enumId) {
|
|
707
|
+
entity.enumCones[enumId] = cone;
|
|
708
|
+
} else if (target === "subset" && subsetKey) {
|
|
709
|
+
entity.subsetCones[subsetKey] = cone;
|
|
648
710
|
}
|
|
649
|
-
} else if (target === "enum" && enumId) {
|
|
650
|
-
entity.enumCones[enumId] = cone;
|
|
651
|
-
} else if (target === "subset" && subsetKey) {
|
|
652
|
-
entity.subsetCones[subsetKey] = cone;
|
|
653
|
-
}
|
|
654
711
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
712
|
+
await entity.save();
|
|
713
|
+
return true;
|
|
714
|
+
});
|
|
715
|
+
}),
|
|
716
|
+
);
|
|
659
717
|
|
|
660
718
|
server.post<{
|
|
661
719
|
Body: {
|
|
@@ -673,6 +731,7 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
673
731
|
const entity = EntityManager.get(entityId);
|
|
674
732
|
|
|
675
733
|
// locale 기본값: Sonamu.config.i18n.defaultLocale 사용
|
|
734
|
+
// SAFETY: i18n 구성 스키마가 지원 locale을 ko/en/ja로 제한한다.
|
|
676
735
|
const effectiveLocale =
|
|
677
736
|
locale ?? (Sonamu.config.i18n.defaultLocale as "ko" | "en" | "ja");
|
|
678
737
|
|
|
@@ -728,51 +787,55 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
728
787
|
Querystring: {
|
|
729
788
|
entityId: string;
|
|
730
789
|
};
|
|
731
|
-
}>("/api/entity/getTableColumns",
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
790
|
+
}>("/api/entity/getTableColumns", (request) =>
|
|
791
|
+
forwardAsyncErrors(async () => {
|
|
792
|
+
const { entityId } = request.query;
|
|
793
|
+
const entity = EntityManager.get(entityId);
|
|
794
|
+
const columns = entity.getTableColumns();
|
|
795
|
+
return { columns };
|
|
796
|
+
}),
|
|
797
|
+
);
|
|
737
798
|
|
|
738
799
|
server.post<{
|
|
739
800
|
Body: {
|
|
740
801
|
entityIds: string[];
|
|
741
802
|
templateKeys: string[];
|
|
742
803
|
};
|
|
743
|
-
}>("/api/scaffolding/getStatus",
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
804
|
+
}>("/api/scaffolding/getStatus", (request) =>
|
|
805
|
+
forwardAsyncErrors(async () => {
|
|
806
|
+
const { entityIds, templateKeys: _templateKeys } = request.body;
|
|
807
|
+
if ((entityIds ?? []).length === 0) {
|
|
808
|
+
throw new BadRequestException(SD("sonamu.error.entityIdsRequired"));
|
|
809
|
+
} else if ((_templateKeys ?? []).length === 0) {
|
|
810
|
+
throw new BadRequestException(SD("sonamu.error.templateKeysRequired"));
|
|
811
|
+
}
|
|
750
812
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
813
|
+
// sorting
|
|
814
|
+
entityIds.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
815
|
+
const templateKeys = TemplateKey.options.filter((tk) => _templateKeys.includes(tk));
|
|
754
816
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
817
|
+
const combinations = entityIds.flatMap((entityId) => {
|
|
818
|
+
return templateKeys.map((templateKey) => [entityId, templateKey]);
|
|
819
|
+
});
|
|
758
820
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
821
|
+
const statuses = await Promise.all(
|
|
822
|
+
combinations.map(async ([entityId, templateKey]) => {
|
|
823
|
+
const { subPath, fullPath, isExists } = await Sonamu.syncer.checkExistsGenCode(
|
|
824
|
+
entityId,
|
|
825
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ templateKey as TemplateKey,
|
|
826
|
+
);
|
|
827
|
+
return {
|
|
828
|
+
entityId,
|
|
829
|
+
templateKey,
|
|
830
|
+
subPath,
|
|
831
|
+
fullPath,
|
|
832
|
+
isExists,
|
|
833
|
+
};
|
|
834
|
+
}),
|
|
835
|
+
);
|
|
836
|
+
return { statuses };
|
|
837
|
+
}),
|
|
838
|
+
);
|
|
776
839
|
|
|
777
840
|
server.post<{
|
|
778
841
|
Body: {
|
|
@@ -783,54 +846,53 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
783
846
|
overwrite?: boolean;
|
|
784
847
|
}[];
|
|
785
848
|
};
|
|
786
|
-
}>("/api/scaffolding/generate",
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
// 1. 모든 템플릿에서 필요한 dict 키를 수집
|
|
793
|
-
const keys = options.flatMap(({ templateKey }) => {
|
|
794
|
-
const template = TemplateManager.get(templateKey);
|
|
795
|
-
return template.getRequiredDictKeys() ?? [];
|
|
796
|
-
});
|
|
849
|
+
}>("/api/scaffolding/generate", (request) =>
|
|
850
|
+
forwardAsyncErrors(async () => {
|
|
851
|
+
const { options } = request.body;
|
|
852
|
+
if (options.length === 0) {
|
|
853
|
+
throw new BadRequestException(SD("sonamu.error.optionsRequired"));
|
|
854
|
+
}
|
|
797
855
|
|
|
798
|
-
|
|
799
|
-
|
|
856
|
+
// 1. 모든 템플릿에서 필요한 dict 키를 수집
|
|
857
|
+
const keys = options.flatMap(({ templateKey }) => {
|
|
858
|
+
const template = TemplateManager.get(templateKey);
|
|
859
|
+
return template.getRequiredDictKeys() ?? [];
|
|
860
|
+
});
|
|
800
861
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
862
|
+
// 2. target별로 ensureDictKeys 호출 (순차 처리)
|
|
863
|
+
await sonamuDictionary.ensureDictKeys([...new Set(keys)]);
|
|
864
|
+
|
|
865
|
+
// 3. 템플릿 생성 (병렬 처리)
|
|
866
|
+
const result = await Promise.all(
|
|
867
|
+
options.map(async ({ entityId, templateKey, enumId, overwrite }) => {
|
|
868
|
+
try {
|
|
869
|
+
return await Sonamu.syncer.generateTemplate(
|
|
870
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ templateKey as TemplateKey,
|
|
871
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 Entity 템플릿 옵션을 보장한다. */ {
|
|
872
|
+
entityId,
|
|
873
|
+
enumId,
|
|
874
|
+
} as EntityTemplateInput,
|
|
875
|
+
{
|
|
876
|
+
overwrite,
|
|
877
|
+
},
|
|
878
|
+
);
|
|
879
|
+
} catch (e) {
|
|
880
|
+
if (isSoException(e) && e.statusCode === 541) {
|
|
881
|
+
return null;
|
|
882
|
+
} else {
|
|
883
|
+
console.error(e);
|
|
884
|
+
throw e;
|
|
885
|
+
}
|
|
824
886
|
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
);
|
|
887
|
+
}),
|
|
888
|
+
);
|
|
828
889
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
890
|
+
if (result.filter(nonNullable).length === 0) {
|
|
891
|
+
throw new ServiceUnavailableException(SD("sonamu.error.allFilesGenerated"));
|
|
892
|
+
}
|
|
893
|
+
return result;
|
|
894
|
+
}),
|
|
895
|
+
);
|
|
834
896
|
|
|
835
897
|
server.post<{
|
|
836
898
|
Body: {
|
|
@@ -840,48 +902,63 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
840
902
|
enumId?: string;
|
|
841
903
|
};
|
|
842
904
|
};
|
|
843
|
-
}>(
|
|
844
|
-
|
|
905
|
+
}>(
|
|
906
|
+
"/api/scaffolding/preview",
|
|
907
|
+
(request): Promise<{ pathAndCodes: PathAndCode[] }> =>
|
|
908
|
+
forwardAsyncErrors(async () => {
|
|
909
|
+
const { option } = request.body;
|
|
845
910
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
return { pathAndCodes };
|
|
854
|
-
} catch (e) {
|
|
855
|
-
console.error(e);
|
|
856
|
-
throw e;
|
|
857
|
-
}
|
|
858
|
-
});
|
|
911
|
+
try {
|
|
912
|
+
const { templateKey, ...templateOptions } = option;
|
|
913
|
+
const pathAndCodes = await Sonamu.syncer.renderTemplate(
|
|
914
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ templateKey as TemplateKey,
|
|
915
|
+
templateOptions,
|
|
916
|
+
);
|
|
859
917
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
918
|
+
return { pathAndCodes };
|
|
919
|
+
} catch (e) {
|
|
920
|
+
console.error(e);
|
|
921
|
+
throw e;
|
|
922
|
+
}
|
|
923
|
+
}),
|
|
924
|
+
);
|
|
925
|
+
|
|
926
|
+
server.post("/api/fixture", (request) =>
|
|
927
|
+
forwardAsyncErrors(async () => {
|
|
928
|
+
const { sourceDB, targetDB, search, duplicateCheck } =
|
|
929
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ request.body as {
|
|
930
|
+
sourceDB: keyof SonamuDBConfig;
|
|
931
|
+
targetDB: keyof SonamuDBConfig;
|
|
932
|
+
search: FixtureSearchOptions;
|
|
933
|
+
duplicateCheck?: DuplicateCheckOptions;
|
|
934
|
+
};
|
|
867
935
|
|
|
868
|
-
|
|
869
|
-
|
|
936
|
+
return FixtureManager.getFixtures(sourceDB, targetDB, search, duplicateCheck);
|
|
937
|
+
}),
|
|
938
|
+
);
|
|
870
939
|
|
|
871
|
-
server.post("/api/fixture/import",
|
|
872
|
-
|
|
873
|
-
db
|
|
874
|
-
|
|
875
|
-
|
|
940
|
+
server.post("/api/fixture/import", (request) =>
|
|
941
|
+
forwardAsyncErrors(async () => {
|
|
942
|
+
const { db, fixtures } =
|
|
943
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ request.body as {
|
|
944
|
+
db: keyof SonamuDBConfig;
|
|
945
|
+
fixtures: FixtureRecord[];
|
|
946
|
+
};
|
|
876
947
|
|
|
877
|
-
|
|
878
|
-
|
|
948
|
+
return FixtureManager.insertFixtures(db, fixtures);
|
|
949
|
+
}),
|
|
950
|
+
);
|
|
879
951
|
|
|
880
|
-
server.post("/api/fixture/addFixtureLoader",
|
|
881
|
-
|
|
952
|
+
server.post("/api/fixture/addFixtureLoader", (request) =>
|
|
953
|
+
forwardAsyncErrors(async () => {
|
|
954
|
+
const { code } =
|
|
955
|
+
/* SAFETY: UI 도구의 Zod 입력 스키마가 이 값의 타입을 보장한다. */ request.body as {
|
|
956
|
+
code: string;
|
|
957
|
+
};
|
|
882
958
|
|
|
883
|
-
|
|
884
|
-
|
|
959
|
+
return FixtureManager.addFixtureLoader(code);
|
|
960
|
+
}),
|
|
961
|
+
);
|
|
885
962
|
|
|
886
963
|
server.get("/api/i18n/dictionary", async () => {
|
|
887
964
|
return sonamuDictionary.getDictionary();
|
|
@@ -898,14 +975,16 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
898
975
|
.send(buffer);
|
|
899
976
|
});
|
|
900
977
|
|
|
901
|
-
server.post("/api/i18n/import",
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
978
|
+
server.post("/api/i18n/import", (request) =>
|
|
979
|
+
forwardAsyncErrors(async () => {
|
|
980
|
+
const data = await request.file();
|
|
981
|
+
if (!data) {
|
|
982
|
+
throw new BadRequestException(SD("sonamu.error.fileNotUploaded"));
|
|
983
|
+
}
|
|
984
|
+
const buffer = await data.toBuffer();
|
|
985
|
+
return sonamuDictionary.importFromExcel(buffer);
|
|
986
|
+
}),
|
|
987
|
+
);
|
|
909
988
|
|
|
910
989
|
server.post<{
|
|
911
990
|
Body: {
|
|
@@ -914,33 +993,41 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
914
993
|
source: "entity" | "project" | "sonamu";
|
|
915
994
|
values: Record<string, string>;
|
|
916
995
|
};
|
|
917
|
-
}>("/api/i18n/update",
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
996
|
+
}>("/api/i18n/update", (request) =>
|
|
997
|
+
forwardAsyncErrors(async () => {
|
|
998
|
+
await sonamuDictionary.updateEntry(request.body);
|
|
999
|
+
return { success: true };
|
|
1000
|
+
}),
|
|
1001
|
+
);
|
|
921
1002
|
|
|
922
1003
|
server.post<{
|
|
923
1004
|
Body: {
|
|
924
1005
|
key: string;
|
|
925
1006
|
values: Record<string, string>;
|
|
926
1007
|
};
|
|
927
|
-
}>("/api/i18n/create",
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1008
|
+
}>("/api/i18n/create", (request) =>
|
|
1009
|
+
forwardAsyncErrors(async () => {
|
|
1010
|
+
await sonamuDictionary.createEntry(request.body);
|
|
1011
|
+
return { success: true };
|
|
1012
|
+
}),
|
|
1013
|
+
);
|
|
931
1014
|
|
|
932
1015
|
server.post<{
|
|
933
1016
|
Body: {
|
|
934
1017
|
key: string;
|
|
935
1018
|
};
|
|
936
|
-
}>("/api/i18n/delete",
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
})
|
|
1019
|
+
}>("/api/i18n/delete", (request) =>
|
|
1020
|
+
forwardAsyncErrors(async () => {
|
|
1021
|
+
await sonamuDictionary.deleteEntry(request.body.key);
|
|
1022
|
+
return { success: true };
|
|
1023
|
+
}),
|
|
1024
|
+
);
|
|
1025
|
+
|
|
1026
|
+
server.post<{ Body: { keys: string[] } }>("/api/i18n/checkUsage", (request) =>
|
|
1027
|
+
forwardAsyncErrors(async () => {
|
|
1028
|
+
return sonamuDictionary.checkUsage(request.body.keys);
|
|
1029
|
+
}),
|
|
1030
|
+
);
|
|
944
1031
|
|
|
945
1032
|
// Tasks API
|
|
946
1033
|
server.get("/api/tasks/status", async () => {
|
|
@@ -968,61 +1055,71 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
968
1055
|
createdAfter?: string;
|
|
969
1056
|
createdBefore?: string;
|
|
970
1057
|
};
|
|
971
|
-
}>("/api/tasks/workflowRuns",
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1058
|
+
}>("/api/tasks/workflowRuns", (request) =>
|
|
1059
|
+
forwardAsyncErrors(async () => {
|
|
1060
|
+
const backend = Sonamu.workflows.backend;
|
|
1061
|
+
const { limit, after, before, order, status, workflowName, createdAfter, createdBefore } =
|
|
1062
|
+
request.query;
|
|
1063
|
+
return backend.listWorkflowRuns({
|
|
1064
|
+
limit: limit ? Number.parseInt(limit, 10) : undefined,
|
|
1065
|
+
after,
|
|
1066
|
+
before,
|
|
1067
|
+
order,
|
|
1068
|
+
status: status ? status.split(",") : undefined,
|
|
1069
|
+
workflowName: workflowName || undefined,
|
|
1070
|
+
createdAfter: createdAfter ? new Date(createdAfter) : undefined,
|
|
1071
|
+
createdBefore: createdBefore ? new Date(createdBefore) : undefined,
|
|
1072
|
+
});
|
|
1073
|
+
}),
|
|
1074
|
+
);
|
|
986
1075
|
|
|
987
1076
|
server.get<{
|
|
988
1077
|
Params: { id: string };
|
|
989
|
-
}>("/api/tasks/workflowRuns/:id",
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1078
|
+
}>("/api/tasks/workflowRuns/:id", (request) =>
|
|
1079
|
+
forwardAsyncErrors(async () => {
|
|
1080
|
+
const backend = Sonamu.workflows.backend;
|
|
1081
|
+
const workflowRun = await backend.getWorkflowRun({
|
|
1082
|
+
workflowRunId: request.params.id,
|
|
1083
|
+
});
|
|
1084
|
+
if (!workflowRun) {
|
|
1085
|
+
throw new Error(`Workflow run not found: ${request.params.id}`);
|
|
1086
|
+
}
|
|
1087
|
+
return workflowRun;
|
|
1088
|
+
}),
|
|
1089
|
+
);
|
|
999
1090
|
|
|
1000
1091
|
server.post<{
|
|
1001
1092
|
Params: { id: string };
|
|
1002
|
-
}>("/api/tasks/workflowRuns/:id/cancel",
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1093
|
+
}>("/api/tasks/workflowRuns/:id/cancel", (request) =>
|
|
1094
|
+
forwardAsyncErrors(async () => {
|
|
1095
|
+
const backend = Sonamu.workflows.backend;
|
|
1096
|
+
return backend.cancelWorkflowRun({
|
|
1097
|
+
workflowRunId: request.params.id,
|
|
1098
|
+
});
|
|
1099
|
+
}),
|
|
1100
|
+
);
|
|
1008
1101
|
|
|
1009
1102
|
server.post<{
|
|
1010
1103
|
Params: { id: string };
|
|
1011
|
-
}>("/api/tasks/workflowRuns/:id/pause",
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1104
|
+
}>("/api/tasks/workflowRuns/:id/pause", (request) =>
|
|
1105
|
+
forwardAsyncErrors(async () => {
|
|
1106
|
+
const backend = Sonamu.workflows.backend;
|
|
1107
|
+
return backend.pauseWorkflowRun({
|
|
1108
|
+
workflowRunId: request.params.id,
|
|
1109
|
+
});
|
|
1110
|
+
}),
|
|
1111
|
+
);
|
|
1017
1112
|
|
|
1018
1113
|
server.post<{
|
|
1019
1114
|
Params: { id: string };
|
|
1020
|
-
}>("/api/tasks/workflowRuns/:id/resume",
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1115
|
+
}>("/api/tasks/workflowRuns/:id/resume", (request) =>
|
|
1116
|
+
forwardAsyncErrors(async () => {
|
|
1117
|
+
const backend = Sonamu.workflows.backend;
|
|
1118
|
+
return backend.resumeWorkflowRun({
|
|
1119
|
+
workflowRunId: request.params.id,
|
|
1120
|
+
});
|
|
1121
|
+
}),
|
|
1122
|
+
);
|
|
1026
1123
|
|
|
1027
1124
|
server.get<{
|
|
1028
1125
|
Params: { id: string };
|
|
@@ -1031,32 +1128,36 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
1031
1128
|
after?: string;
|
|
1032
1129
|
before?: string;
|
|
1033
1130
|
};
|
|
1034
|
-
}>("/api/tasks/workflowRuns/:id/steps",
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1131
|
+
}>("/api/tasks/workflowRuns/:id/steps", (request) =>
|
|
1132
|
+
forwardAsyncErrors(async () => {
|
|
1133
|
+
const backend = Sonamu.workflows.backend;
|
|
1134
|
+
const { limit, after, before } = request.query;
|
|
1135
|
+
return backend.listStepAttempts({
|
|
1136
|
+
workflowRunId: request.params.id,
|
|
1137
|
+
limit: limit ? Number.parseInt(limit, 10) : undefined,
|
|
1138
|
+
after,
|
|
1139
|
+
before,
|
|
1140
|
+
});
|
|
1141
|
+
}),
|
|
1142
|
+
);
|
|
1044
1143
|
|
|
1045
1144
|
/**
|
|
1046
1145
|
* Health Check API
|
|
1047
1146
|
* MCP 도구가 Sonamu 서버를 자동 감지하기 위한 엔드포인트
|
|
1048
1147
|
*/
|
|
1049
|
-
server.get("/api/sonamu/health",
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1148
|
+
server.get("/api/sonamu/health", (request) =>
|
|
1149
|
+
forwardAsyncErrors(async () => {
|
|
1150
|
+
const address = request.server.server.address();
|
|
1151
|
+
const port = address && isObjectValue(address) ? address.port : 0;
|
|
1152
|
+
|
|
1153
|
+
return {
|
|
1154
|
+
ok: true,
|
|
1155
|
+
project: process.cwd().split("/").pop() || "unknown",
|
|
1156
|
+
port,
|
|
1157
|
+
timestamp: new Date().toISOString(),
|
|
1158
|
+
};
|
|
1159
|
+
}),
|
|
1160
|
+
);
|
|
1060
1161
|
|
|
1061
1162
|
/**
|
|
1062
1163
|
* Fixture 생성 API
|
|
@@ -1065,7 +1166,7 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
1065
1166
|
Body: {
|
|
1066
1167
|
entity: string;
|
|
1067
1168
|
count?: number;
|
|
1068
|
-
overrides?:
|
|
1169
|
+
overrides?: FixtureGenerationSpec["overrides"];
|
|
1069
1170
|
targetDb?: "fixture" | "test";
|
|
1070
1171
|
};
|
|
1071
1172
|
}>("/api/sonamu/fixture/generate", async (request, reply) => {
|
|
@@ -1116,7 +1217,7 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
1116
1217
|
entity: string;
|
|
1117
1218
|
strategy: "sample" | "recent" | "random" | "query";
|
|
1118
1219
|
limit?: number;
|
|
1119
|
-
where?:
|
|
1220
|
+
where?: DataExplorerOptions["where"];
|
|
1120
1221
|
};
|
|
1121
1222
|
}>("/api/sonamu/fixture/explore", async (request, reply) => {
|
|
1122
1223
|
const { entity, strategy, limit = 10, where } = request.body;
|
|
@@ -1265,35 +1366,45 @@ export async function sonamuUIApiPlugin(fastify: FastifyInstance) {
|
|
|
1265
1366
|
return getCddTree();
|
|
1266
1367
|
});
|
|
1267
1368
|
|
|
1268
|
-
server.post<{ Body: { filePath: string } }>("/api/cdd/readContent",
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
})
|
|
1369
|
+
server.post<{ Body: { filePath: string } }>("/api/cdd/readContent", (request) =>
|
|
1370
|
+
forwardAsyncErrors(async () => {
|
|
1371
|
+
const { filePath } = request.body;
|
|
1372
|
+
return readContent(filePath);
|
|
1373
|
+
}),
|
|
1374
|
+
);
|
|
1375
|
+
|
|
1376
|
+
server.post<{ Body: { filePath: string } }>("/api/cdd/editContent", (request) =>
|
|
1377
|
+
forwardAsyncErrors(async () => {
|
|
1378
|
+
const { filePath } = request.body;
|
|
1379
|
+
return editContent(filePath);
|
|
1380
|
+
}),
|
|
1381
|
+
);
|
|
1382
|
+
|
|
1383
|
+
server.post<{ Body: { filePath: string } }>("/api/cdd/openSource", (request) =>
|
|
1384
|
+
forwardAsyncErrors(async () => {
|
|
1385
|
+
const { filePath } = request.body;
|
|
1386
|
+
openSourceFile(filePath);
|
|
1387
|
+
return { success: true };
|
|
1388
|
+
}),
|
|
1389
|
+
);
|
|
1283
1390
|
|
|
1284
1391
|
// CDD Rules API
|
|
1285
1392
|
server.get("/api/cdd/rules", async () => {
|
|
1286
1393
|
return listRules();
|
|
1287
1394
|
});
|
|
1288
1395
|
|
|
1289
|
-
server.post<{ Body: { ruleKey: string } }>("/api/cdd/readRule",
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
})
|
|
1396
|
+
server.post<{ Body: { ruleKey: string } }>("/api/cdd/readRule", (request) =>
|
|
1397
|
+
forwardAsyncErrors(async () => {
|
|
1398
|
+
const { ruleKey } = request.body;
|
|
1399
|
+
return readRule(ruleKey);
|
|
1400
|
+
}),
|
|
1401
|
+
);
|
|
1402
|
+
|
|
1403
|
+
server.post<{ Body: CddAddRuleRequest }>("/api/cdd/addRule", (request) =>
|
|
1404
|
+
forwardAsyncErrors(async () => {
|
|
1405
|
+
return addRule(request.body);
|
|
1406
|
+
}),
|
|
1407
|
+
);
|
|
1297
1408
|
|
|
1298
1409
|
// CDD AC API
|
|
1299
1410
|
server.get("/api/cdd/ac", async () => {
|