sonamu 0.5.7 → 0.7.0
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/.swcrc.project-default +18 -0
- package/bin/cli.js +24 -0
- package/dist/ai/agents/agent.d.ts +11 -0
- package/dist/ai/agents/agent.d.ts.map +1 -0
- package/dist/ai/agents/agent.js +65 -0
- package/dist/ai/agents/index.d.ts +3 -0
- package/dist/ai/agents/index.d.ts.map +1 -0
- package/dist/ai/agents/index.js +4 -0
- package/dist/ai/agents/types.d.ts +43 -0
- package/dist/ai/agents/types.d.ts.map +1 -0
- package/dist/ai/agents/types.js +3 -0
- package/dist/ai/index.d.ts +2 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +3 -0
- package/dist/ai/providers/rtzr/api.d.ts +22 -0
- package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/api.js +28 -0
- package/dist/ai/providers/rtzr/error.d.ts +18 -0
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/error.js +29 -0
- package/dist/ai/providers/rtzr/index.d.ts +5 -0
- package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/index.js +6 -0
- package/dist/ai/providers/rtzr/model.d.ts +52 -0
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/model.js +137 -0
- package/dist/ai/providers/rtzr/options.d.ts +7 -0
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/options.js +47 -0
- package/dist/ai/providers/rtzr/provider.d.ts +18 -0
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/provider.js +54 -0
- package/dist/ai/providers/rtzr/utils.d.ts +19 -0
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/utils.js +88 -0
- package/dist/api/base-frame.d.ts +2 -2
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/base-frame.js +13 -2
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +71 -2
- package/dist/api/code-converters.d.ts +58 -14
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +258 -2
- package/dist/api/config.d.ts +90 -0
- package/dist/api/config.d.ts.map +1 -0
- package/dist/api/config.js +25 -0
- package/dist/api/context.d.ts +4 -2
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +3 -2
- package/dist/api/decorators.d.ts +20 -6
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +235 -2
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +9 -2
- package/dist/api/sonamu.d.ts +10 -24
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +514 -2
- package/dist/api/validator.d.ts +6 -0
- package/dist/api/validator.d.ts.map +1 -0
- package/dist/api/validator.js +81 -0
- package/dist/bin/build-config.d.ts +6 -1
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +15 -2
- package/dist/bin/cli.js +519 -2
- package/dist/bin/hot-hook-register.d.ts +11 -0
- package/dist/bin/hot-hook-register.d.ts.map +1 -0
- package/dist/bin/hot-hook-register.js +21 -0
- package/dist/bin/loader-register.d.ts +2 -0
- package/dist/bin/loader-register.d.ts.map +1 -0
- package/dist/bin/loader-register.js +34 -0
- package/dist/database/_batch_update.d.ts +5 -3
- package/dist/database/_batch_update.d.ts.map +1 -1
- package/dist/database/_batch_update.js +95 -2
- package/dist/database/base-model.d.ts +96 -10
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +390 -2
- package/dist/database/base-model.types.d.ts +93 -0
- package/dist/database/base-model.types.d.ts.map +1 -0
- package/dist/database/base-model.types.js +10 -0
- package/dist/database/code-generator.d.ts +1 -1
- package/dist/database/code-generator.d.ts.map +1 -1
- package/dist/database/code-generator.js +54 -2
- package/dist/database/db.d.ts +6 -21
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +129 -2
- package/dist/database/puri-subset.test-d.js +81 -0
- package/dist/database/puri-subset.types.d.ts +123 -0
- package/dist/database/puri-subset.types.d.ts.map +1 -0
- package/dist/database/puri-subset.types.js +16 -0
- package/dist/database/puri-wrapper.d.ts +13 -11
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +109 -2
- package/dist/database/puri.d.ts +41 -23
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +601 -2
- package/dist/database/puri.types.d.ts +25 -6
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +6 -2
- package/dist/database/transaction-context.d.ts +1 -1
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js +14 -2
- package/dist/database/upsert-builder.d.ts +9 -3
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +365 -2
- package/dist/entity/entity-manager.d.ts +167 -2
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +130 -2
- package/dist/entity/entity.d.ts +5 -3
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +750 -2
- package/dist/exceptions/error-handler.d.ts +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +29 -2
- package/dist/exceptions/so-exceptions.d.ts +1 -1
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +85 -2
- package/dist/file-storage/driver.d.ts +1 -1
- package/dist/file-storage/driver.d.ts.map +1 -1
- package/dist/file-storage/driver.js +79 -2
- package/dist/file-storage/file-storage.js +75 -2
- package/dist/index.d.ts +18 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -2
- package/dist/migration/code-generation.d.ts +1 -1
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +614 -2
- package/dist/migration/migration-set.d.ts +2 -10
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +213 -2
- package/dist/migration/migrator.d.ts +24 -82
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +330 -2
- package/dist/migration/postgresql-schema-reader.d.ts +51 -0
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
- package/dist/migration/postgresql-schema-reader.js +245 -0
- package/dist/migration/types.d.ts +6 -38
- package/dist/migration/types.d.ts.map +1 -1
- package/dist/migration/types.js +3 -2
- package/dist/naite/messaging-types.d.ts +43 -0
- package/dist/naite/messaging-types.d.ts.map +1 -0
- package/dist/naite/messaging-types.js +7 -0
- package/dist/naite/naite-reporter.d.ts +41 -0
- package/dist/naite/naite-reporter.d.ts.map +1 -0
- package/dist/naite/naite-reporter.js +102 -0
- package/dist/naite/naite.d.ts +95 -0
- package/dist/naite/naite.d.ts.map +1 -0
- package/dist/naite/naite.js +316 -0
- package/dist/stream/index.js +3 -2
- package/dist/stream/sse.d.ts +2 -2
- package/dist/stream/sse.d.ts.map +1 -1
- package/dist/stream/sse.js +38 -2
- package/dist/syncer/api-parser.d.ts +10 -0
- package/dist/syncer/api-parser.d.ts.map +1 -0
- package/dist/syncer/api-parser.js +240 -0
- package/dist/syncer/checksum.d.ts +21 -0
- package/dist/syncer/checksum.d.ts.map +1 -0
- package/dist/syncer/checksum.js +98 -0
- package/dist/syncer/code-generator.d.ts +20 -0
- package/dist/syncer/code-generator.d.ts.map +1 -0
- package/dist/syncer/code-generator.js +161 -0
- package/dist/syncer/entity-operations.d.ts +17 -0
- package/dist/syncer/entity-operations.d.ts.map +1 -0
- package/dist/syncer/entity-operations.js +59 -0
- package/dist/syncer/file-patterns.d.ts +29 -0
- package/dist/syncer/file-patterns.d.ts.map +1 -0
- package/dist/syncer/file-patterns.js +38 -0
- package/dist/syncer/index.d.ts +6 -0
- package/dist/syncer/index.d.ts.map +1 -1
- package/dist/syncer/index.js +9 -2
- package/dist/syncer/module-loader.d.ts +35 -0
- package/dist/syncer/module-loader.d.ts.map +1 -0
- package/dist/syncer/module-loader.js +87 -0
- package/dist/syncer/syncer.d.ts +98 -106
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +422 -2
- package/dist/template/entity-converter.d.ts +14 -0
- package/dist/template/entity-converter.d.ts.map +1 -0
- package/dist/template/entity-converter.js +108 -0
- package/dist/template/helpers.d.ts +23 -0
- package/dist/template/helpers.d.ts.map +1 -0
- package/dist/template/helpers.js +64 -0
- package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
- package/dist/template/implementations/entity.template.d.ts.map +1 -0
- package/dist/template/implementations/entity.template.js +86 -0
- package/dist/{templates → template/implementations}/generated.template.d.ts +3 -4
- package/dist/template/implementations/generated.template.d.ts.map +1 -0
- package/dist/template/implementations/generated.template.js +249 -0
- package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -4
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
- package/dist/template/implementations/generated_http.template.js +131 -0
- package/dist/{templates → template/implementations}/generated_sso.template.d.ts +4 -5
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
- package/dist/template/implementations/generated_sso.template.js +134 -0
- package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
- package/dist/template/implementations/init_types.template.d.ts.map +1 -0
- package/dist/template/implementations/init_types.template.js +38 -0
- package/dist/template/implementations/model.template.d.ts +17 -0
- package/dist/template/implementations/model.template.d.ts.map +1 -0
- package/dist/template/implementations/model.template.js +181 -0
- package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
- package/dist/template/implementations/model_test.template.d.ts.map +1 -0
- package/dist/template/implementations/model_test.template.js +35 -0
- package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
- package/dist/template/implementations/service.template.d.ts.map +1 -0
- package/dist/template/implementations/service.template.js +201 -0
- package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
- package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
- package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
- package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
- package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
- package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
- package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
- package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
- package/dist/template/implementations/view_enums_select.template.js +55 -0
- package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
- package/dist/template/implementations/view_form.template.d.ts.map +1 -0
- package/dist/template/implementations/view_form.template.js +337 -0
- package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
- package/dist/template/implementations/view_id_all_select.template.js +31 -0
- package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
- package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
- package/dist/template/implementations/view_id_async_select.template.js +105 -0
- package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
- package/dist/template/implementations/view_list.template.d.ts.map +1 -0
- package/dist/template/implementations/view_list.template.js +475 -0
- package/dist/template/implementations/view_list_columns.template.d.ts +17 -0
- package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
- package/dist/template/implementations/view_list_columns.template.js +49 -0
- package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
- package/dist/template/implementations/view_search_input.template.js +64 -0
- package/dist/template/index.d.ts +7 -0
- package/dist/template/index.d.ts.map +1 -0
- package/dist/template/index.js +8 -0
- package/dist/template/template-manager.d.ts +56 -0
- package/dist/template/template-manager.d.ts.map +1 -0
- package/dist/template/template-manager.js +125 -0
- package/dist/template/template-types.d.ts +16 -0
- package/dist/template/template-types.d.ts.map +1 -0
- package/dist/template/template-types.js +7 -0
- package/dist/template/template.d.ts +49 -0
- package/dist/template/template.d.ts.map +1 -0
- package/dist/template/template.js +60 -0
- package/dist/template/zod-converter.d.ts +51 -0
- package/dist/template/zod-converter.d.ts.map +1 -0
- package/dist/template/zod-converter.js +449 -0
- package/dist/testing/_relation-graph.d.ts +1 -1
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +89 -2
- package/dist/testing/fixture-manager.d.ts +42 -11
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +623 -2
- package/dist/types/types.d.ts +747 -143
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +546 -2
- package/dist/typings/knex.d.js +3 -2
- package/dist/utils/async-utils.d.ts +7 -0
- package/dist/utils/async-utils.d.ts.map +1 -1
- package/dist/utils/async-utils.js +57 -2
- package/dist/utils/console-util.d.ts +2 -0
- package/dist/utils/console-util.d.ts.map +1 -0
- package/dist/utils/console-util.js +6 -0
- package/dist/utils/controller.d.ts +1 -0
- package/dist/utils/controller.d.ts.map +1 -1
- package/dist/utils/controller.js +29 -2
- package/dist/utils/esm-utils.d.ts +39 -0
- package/dist/utils/esm-utils.d.ts.map +1 -0
- package/dist/utils/esm-utils.js +49 -0
- package/dist/utils/formatter.d.ts +3 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +110 -0
- package/dist/utils/fs-utils.d.ts +1 -1
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +17 -2
- package/dist/utils/lodash-able.d.ts.map +1 -1
- package/dist/utils/lodash-able.js +6 -2
- package/dist/utils/model.js +22 -2
- package/dist/utils/object-utils.d.ts +44 -0
- package/dist/utils/object-utils.d.ts.map +1 -0
- package/dist/utils/object-utils.js +191 -0
- package/dist/utils/path-utils.d.ts +89 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +60 -0
- package/dist/utils/process-utils.d.ts +13 -0
- package/dist/utils/process-utils.d.ts.map +1 -0
- package/dist/utils/process-utils.js +36 -0
- package/dist/utils/sql-parser.d.ts +5 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +46 -2
- package/dist/utils/type-utils.d.ts +23 -0
- package/dist/utils/type-utils.d.ts.map +1 -0
- package/dist/utils/type-utils.js +45 -0
- package/dist/utils/utils.d.ts +10 -7
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +72 -2
- package/dist/utils/zod-error.d.ts +1 -1
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +19 -2
- package/package.json +65 -27
- package/src/ai/agents/agent.ts +87 -0
- package/src/ai/agents/index.ts +2 -0
- package/src/ai/agents/types.ts +47 -0
- package/src/ai/index.ts +1 -0
- package/src/ai/providers/rtzr/api.ts +37 -0
- package/src/ai/providers/rtzr/error.ts +34 -0
- package/src/ai/providers/rtzr/index.ts +4 -0
- package/src/ai/providers/rtzr/model.ts +201 -0
- package/src/ai/providers/rtzr/options.ts +49 -0
- package/src/ai/providers/rtzr/provider.ts +91 -0
- package/src/ai/providers/rtzr/utils.ts +127 -0
- package/src/api/base-frame.ts +4 -2
- package/src/api/caster.ts +17 -23
- package/src/api/code-converters.ts +178 -535
- package/src/api/config.ts +125 -0
- package/src/api/context.ts +7 -17
- package/src/api/decorators.ts +176 -46
- package/src/api/index.ts +2 -2
- package/src/api/sonamu.ts +190 -167
- package/src/api/validator.ts +83 -0
- package/src/bin/build-config.ts +8 -1
- package/src/bin/cli.ts +258 -124
- package/src/bin/hot-hook-register.ts +22 -0
- package/src/bin/loader-register.ts +38 -0
- package/src/database/_batch_update.ts +46 -31
- package/src/database/base-model.ts +390 -182
- package/src/database/base-model.types.ts +155 -0
- package/src/database/code-generator.ts +13 -32
- package/src/database/db.ts +40 -96
- package/src/database/puri-subset.test-d.ts +471 -0
- package/src/database/puri-subset.types.ts +195 -0
- package/src/database/puri-wrapper.ts +58 -67
- package/src/database/puri.ts +229 -148
- package/src/database/puri.types.ts +76 -30
- package/src/database/transaction-context.ts +1 -1
- package/src/database/upsert-builder.ts +262 -132
- package/src/entity/entity-manager.ts +48 -36
- package/src/entity/entity.ts +330 -248
- package/src/exceptions/error-handler.ts +3 -3
- package/src/exceptions/so-exceptions.ts +11 -11
- package/src/file-storage/driver.ts +5 -5
- package/src/file-storage/file-storage.ts +2 -2
- package/src/index.ts +18 -10
- package/src/migration/code-generation.ts +185 -172
- package/src/migration/migration-set.ts +80 -293
- package/src/migration/migrator.ts +199 -571
- package/src/migration/mysql-schema-reader.ts.txt +272 -0
- package/src/migration/postgresql-schema-reader.ts +310 -0
- package/src/migration/types.ts +6 -39
- package/src/naite/messaging-types.ts +51 -0
- package/src/naite/naite-reporter.ts +128 -0
- package/src/naite/naite.ts +415 -0
- package/src/shared/web.shared.ts.txt +20 -24
- package/src/stream/sse.ts +5 -5
- package/src/syncer/api-parser.ts +282 -0
- package/src/syncer/checksum.ts +140 -0
- package/src/syncer/code-generator.ts +198 -0
- package/src/syncer/entity-operations.ts +65 -0
- package/src/syncer/file-patterns.ts +56 -0
- package/src/syncer/index.ts +6 -0
- package/src/syncer/module-loader.ts +128 -0
- package/src/syncer/syncer.ts +389 -1453
- package/src/template/entity-converter.ts +114 -0
- package/src/template/helpers.ts +81 -0
- package/src/{templates → template/implementations}/entity.template.ts +7 -7
- package/src/{templates → template/implementations}/generated.template.ts +101 -101
- package/src/{templates → template/implementations}/generated_http.template.ts +27 -57
- package/src/template/implementations/generated_sso.template.ts +151 -0
- package/src/{templates → template/implementations}/init_types.template.ts +5 -7
- package/src/{templates → template/implementations}/model.template.ts +52 -43
- package/src/{templates → template/implementations}/model_test.template.ts +5 -5
- package/src/{templates → template/implementations}/service.template.ts +66 -82
- package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
- package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +4 -20
- package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
- package/src/{templates → template/implementations}/view_form.template.ts +40 -83
- package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
- package/src/{templates → template/implementations}/view_id_async_select.template.ts +10 -24
- package/src/{templates → template/implementations}/view_list.template.ts +60 -152
- package/src/{templates → template/implementations}/view_list_columns.template.ts +5 -11
- package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
- package/src/template/index.ts +6 -0
- package/src/template/template-manager.ts +166 -0
- package/src/template/template-types.ts +16 -0
- package/src/template/template.ts +105 -0
- package/src/template/zod-converter.ts +525 -0
- package/src/testing/_relation-graph.ts +18 -11
- package/src/testing/fixture-manager.ts +472 -359
- package/src/types/types.ts +553 -308
- package/src/typings/knex.d.ts +7 -9
- package/src/utils/async-utils.ts +23 -10
- package/src/utils/console-util.ts +4 -0
- package/src/utils/controller.ts +3 -0
- package/src/utils/esm-utils.ts +59 -0
- package/src/utils/formatter.ts +109 -0
- package/src/utils/fs-utils.ts +1 -1
- package/src/utils/lodash-able.ts +1 -4
- package/src/utils/object-utils.ts +217 -0
- package/src/utils/path-utils.ts +99 -0
- package/src/utils/process-utils.ts +46 -0
- package/src/utils/sql-parser.ts +23 -5
- package/src/utils/type-utils.ts +83 -0
- package/src/utils/utils.ts +66 -43
- package/src/utils/zod-error.ts +3 -4
- package/dist/api/base-frame.js.map +0 -1
- package/dist/api/caster.js.map +0 -1
- package/dist/api/code-converters.js.map +0 -1
- package/dist/api/context.js.map +0 -1
- package/dist/api/decorators.js.map +0 -1
- package/dist/api/index.js.map +0 -1
- package/dist/api/sonamu.js.map +0 -1
- package/dist/bin/build-config.js.map +0 -1
- package/dist/bin/cli-wrapper.d.ts +0 -3
- package/dist/bin/cli-wrapper.d.ts.map +0 -1
- package/dist/bin/cli-wrapper.js +0 -3
- package/dist/bin/cli-wrapper.js.map +0 -1
- package/dist/bin/cli.js.map +0 -1
- package/dist/database/_batch_update.js.map +0 -1
- package/dist/database/base-model.js.map +0 -1
- package/dist/database/code-generator.js.map +0 -1
- package/dist/database/db.js.map +0 -1
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
- package/dist/database/puri-wrapper.js.map +0 -1
- package/dist/database/puri.js.map +0 -1
- package/dist/database/puri.types.js.map +0 -1
- package/dist/database/transaction-context.js.map +0 -1
- package/dist/database/upsert-builder.js.map +0 -1
- package/dist/entity/entity-manager.js.map +0 -1
- package/dist/entity/entity-utils.d.ts +0 -61
- package/dist/entity/entity-utils.d.ts.map +0 -1
- package/dist/entity/entity-utils.js +0 -2
- package/dist/entity/entity-utils.js.map +0 -1
- package/dist/entity/entity.js.map +0 -1
- package/dist/exceptions/error-handler.js.map +0 -1
- package/dist/exceptions/so-exceptions.js.map +0 -1
- package/dist/file-storage/driver.js.map +0 -1
- package/dist/file-storage/file-storage.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/migration/code-generation.js.map +0 -1
- package/dist/migration/migration-set.js.map +0 -1
- package/dist/migration/migrator.js.map +0 -1
- package/dist/migration/types.js.map +0 -1
- package/dist/stream/index.js.map +0 -1
- package/dist/stream/sse.js.map +0 -1
- package/dist/syncer/index.js.map +0 -1
- package/dist/syncer/syncer.js.map +0 -1
- package/dist/templates/base-template.d.ts +0 -13
- package/dist/templates/base-template.d.ts.map +0 -1
- package/dist/templates/base-template.js +0 -2
- package/dist/templates/base-template.js.map +0 -1
- package/dist/templates/entity.template.d.ts.map +0 -1
- package/dist/templates/entity.template.js +0 -2
- package/dist/templates/entity.template.js.map +0 -1
- package/dist/templates/generated.template.d.ts.map +0 -1
- package/dist/templates/generated.template.js +0 -2
- package/dist/templates/generated.template.js.map +0 -1
- package/dist/templates/generated_http.template.d.ts.map +0 -1
- package/dist/templates/generated_http.template.js +0 -2
- package/dist/templates/generated_http.template.js.map +0 -1
- package/dist/templates/generated_sso.template.d.ts.map +0 -1
- package/dist/templates/generated_sso.template.js +0 -2
- package/dist/templates/generated_sso.template.js.map +0 -1
- package/dist/templates/index.d.ts +0 -2
- package/dist/templates/index.d.ts.map +0 -1
- package/dist/templates/index.js +0 -2
- package/dist/templates/index.js.map +0 -1
- package/dist/templates/init_types.template.d.ts.map +0 -1
- package/dist/templates/init_types.template.js +0 -2
- package/dist/templates/init_types.template.js.map +0 -1
- package/dist/templates/model.template.d.ts +0 -17
- package/dist/templates/model.template.d.ts.map +0 -1
- package/dist/templates/model.template.js +0 -2
- package/dist/templates/model.template.js.map +0 -1
- package/dist/templates/model_test.template.d.ts.map +0 -1
- package/dist/templates/model_test.template.js +0 -2
- package/dist/templates/model_test.template.js.map +0 -1
- package/dist/templates/service.template.d.ts.map +0 -1
- package/dist/templates/service.template.js +0 -2
- package/dist/templates/service.template.js.map +0 -1
- package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
- package/dist/templates/view_enums_buttonset.template.js +0 -2
- package/dist/templates/view_enums_buttonset.template.js.map +0 -1
- package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
- package/dist/templates/view_enums_dropdown.template.js +0 -2
- package/dist/templates/view_enums_dropdown.template.js.map +0 -1
- package/dist/templates/view_enums_select.template.d.ts.map +0 -1
- package/dist/templates/view_enums_select.template.js +0 -2
- package/dist/templates/view_enums_select.template.js.map +0 -1
- package/dist/templates/view_form.template.d.ts.map +0 -1
- package/dist/templates/view_form.template.js +0 -2
- package/dist/templates/view_form.template.js.map +0 -1
- package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
- package/dist/templates/view_id_all_select.template.js +0 -2
- package/dist/templates/view_id_all_select.template.js.map +0 -1
- package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
- package/dist/templates/view_id_async_select.template.js +0 -2
- package/dist/templates/view_id_async_select.template.js.map +0 -1
- package/dist/templates/view_list.template.d.ts.map +0 -1
- package/dist/templates/view_list.template.js +0 -2
- package/dist/templates/view_list.template.js.map +0 -1
- package/dist/templates/view_list_columns.template.d.ts +0 -17
- package/dist/templates/view_list_columns.template.d.ts.map +0 -1
- package/dist/templates/view_list_columns.template.js +0 -2
- package/dist/templates/view_list_columns.template.js.map +0 -1
- package/dist/templates/view_search_input.template.d.ts.map +0 -1
- package/dist/templates/view_search_input.template.js +0 -2
- package/dist/templates/view_search_input.template.js.map +0 -1
- package/dist/testing/_relation-graph.js.map +0 -1
- package/dist/testing/fixture-manager.js.map +0 -1
- package/dist/types/types.js.map +0 -1
- package/dist/typings/knex.d.js.map +0 -1
- package/dist/utils/async-utils.js.map +0 -1
- package/dist/utils/controller.js.map +0 -1
- package/dist/utils/fs-utils.js.map +0 -1
- package/dist/utils/lodash-able.js.map +0 -1
- package/dist/utils/model.js.map +0 -1
- package/dist/utils/sql-parser.js.map +0 -1
- package/dist/utils/utils.js.map +0 -1
- package/dist/utils/zod-error.js.map +0 -1
- package/src/bin/cli-wrapper.ts +0 -75
- package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
- package/src/entity/entity-utils.ts +0 -291
- package/src/templates/base-template.ts +0 -19
- package/src/templates/generated_sso.template.ts +0 -138
- package/src/templates/index.ts +0 -1
|
@@ -1,23 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: Puri.types.ts는 다양한 타입을 사용하고 있습니다. */
|
|
2
|
+
|
|
3
|
+
import type { QueryResult } from "pg";
|
|
4
|
+
import type { DatabaseSchemaExtend } from "../types/types";
|
|
5
|
+
import type { Puri } from "./puri";
|
|
6
|
+
import type { PuriWrapper } from "./puri-wrapper";
|
|
7
|
+
|
|
8
|
+
// 메타데이터 컬럼 유틸
|
|
9
|
+
type MetadataColumns = "__fulltext__" | "__virtual__";
|
|
10
|
+
|
|
11
|
+
// virtual 컬럼 타입 추출
|
|
12
|
+
type VirtualKeys<T> = T extends { __virtual__: readonly (infer V)[] } ? V & string : never;
|
|
13
|
+
|
|
14
|
+
// virtual 컬럼 제거
|
|
15
|
+
type StripVirtual<T> = Omit<T, VirtualKeys<T>>;
|
|
16
|
+
|
|
17
|
+
// 메타데이터 필드 제외한 실제 엔티티 컬럼
|
|
18
|
+
export type ColumnKeys<T> = Exclude<keyof StripVirtual<T>, MetadataColumns> & string;
|
|
19
|
+
|
|
20
|
+
// virtual 컬럼 제거 후 __fulltext__ 메타데이터 유지
|
|
21
|
+
export type PuriTable<T> = Omit<StripVirtual<T>, "__virtual__">;
|
|
22
|
+
|
|
23
|
+
// 메타데이터 컬럼 제외 타입 정의
|
|
24
|
+
export type OmitMetadataColumns<T> = Omit<T, MetadataColumns>;
|
|
7
25
|
|
|
8
26
|
// TTables의 모든 테이블에서 사용 가능한 컬럼 경로
|
|
9
27
|
export type AvailableColumns<TTables extends Record<string, any>> =
|
|
10
28
|
| {
|
|
11
|
-
[TAlias in keyof TTables]: `${TAlias & string}.${
|
|
29
|
+
[TAlias in keyof TTables]: `${TAlias & string}.${ColumnKeys<TTables[TAlias]>}`;
|
|
12
30
|
}[keyof TTables]
|
|
13
31
|
| (IsSingleKey<TTables> extends true
|
|
14
|
-
?
|
|
32
|
+
? ColumnKeys<TTables[keyof TTables]> // 단일 테이블이면 컬럼명만도 허용
|
|
15
33
|
: never);
|
|
34
|
+
|
|
16
35
|
// Group By, Order By, Having 등에서 선택 가능한 컬럼
|
|
17
|
-
export type ResultAvailableColumns<
|
|
18
|
-
|
|
19
|
-
TResult
|
|
20
|
-
> = AvailableColumns<TTables> | `${keyof TResult & string}`;
|
|
36
|
+
export type ResultAvailableColumns<TTables extends Record<string, any>, TResult = any> =
|
|
37
|
+
| AvailableColumns<TTables>
|
|
38
|
+
| `${keyof TResult & string}`;
|
|
21
39
|
|
|
22
40
|
// Select 값 타입 확장
|
|
23
41
|
export type SelectValue<TTables extends Record<string, any>> =
|
|
@@ -84,12 +102,11 @@ export type FulltextColumns<TTables extends Record<string, any>> = {
|
|
|
84
102
|
export type ComparisonOperator = "=" | ">" | ">=" | "<" | "<=" | "<>" | "!=";
|
|
85
103
|
|
|
86
104
|
// SQL Expression 타입 정의
|
|
87
|
-
export type SqlExpression<T extends "string" | "number" | "boolean" | "date"> =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
};
|
|
105
|
+
export type SqlExpression<T extends "string" | "number" | "boolean" | "date"> = {
|
|
106
|
+
_type: "sql_expression"; // 또는 "computed_value"
|
|
107
|
+
_return: T;
|
|
108
|
+
_sql: string;
|
|
109
|
+
};
|
|
93
110
|
|
|
94
111
|
// 결과 타입 가독성을 위한 타입 확장
|
|
95
112
|
export type Expand<T> = T extends any[]
|
|
@@ -98,29 +115,58 @@ export type Expand<T> = T extends any[]
|
|
|
98
115
|
? { [K in keyof T]: T[K] }
|
|
99
116
|
: T;
|
|
100
117
|
|
|
101
|
-
type IsSingleKey<TTables extends Record<string, any>> =
|
|
102
|
-
|
|
103
|
-
?
|
|
104
|
-
?
|
|
105
|
-
? true
|
|
106
|
-
: false
|
|
118
|
+
type IsSingleKey<TTables extends Record<string, any>> = keyof TTables extends infer K
|
|
119
|
+
? K extends keyof TTables
|
|
120
|
+
? keyof TTables extends K // 역방향 체크로 단일 키 확인
|
|
121
|
+
? true
|
|
107
122
|
: false
|
|
108
|
-
: false
|
|
123
|
+
: false
|
|
124
|
+
: false;
|
|
109
125
|
|
|
110
126
|
export type SingleTableValue<TTables extends Record<string, any>> =
|
|
111
127
|
IsSingleKey<TTables> extends true ? TTables[keyof TTables] : never;
|
|
112
128
|
|
|
113
129
|
// Nullable을 Optional로 변환
|
|
114
130
|
type NullableToOptional<T> = {
|
|
115
|
-
[K in keyof T as T[K] extends null | undefined ? K : never]?: Exclude<
|
|
116
|
-
T[K],
|
|
117
|
-
null | undefined
|
|
118
|
-
>;
|
|
131
|
+
[K in keyof T as T[K] extends null | undefined ? K : never]?: Exclude<T[K], null | undefined>;
|
|
119
132
|
} & Partial<{
|
|
120
133
|
[K in keyof T as T[K] extends null | undefined ? never : K]: T[K];
|
|
121
134
|
}>;
|
|
122
135
|
|
|
123
136
|
// Insert 타입: id, created_at 제외
|
|
124
137
|
export type InsertData<T> = NullableToOptional<
|
|
125
|
-
Omit<T
|
|
138
|
+
Omit<PuriTable<T>, "id" | "created_at" | MetadataColumns>
|
|
126
139
|
>;
|
|
140
|
+
|
|
141
|
+
// Insert Result 타입
|
|
142
|
+
export type InsertResult = Pick<QueryResult<any>, "command" | "rowCount" | "rows" | "oid">;
|
|
143
|
+
|
|
144
|
+
// SubsetQuery를 위한 타입 유틸리티
|
|
145
|
+
type ExtractTTables<T extends Puri<any, any, any>> = T extends Puri<any, infer TTables, any>
|
|
146
|
+
? TTables
|
|
147
|
+
: never;
|
|
148
|
+
export type UnionExtractedTTables<
|
|
149
|
+
SubsetKey extends string,
|
|
150
|
+
SubsetQueries extends Record<
|
|
151
|
+
SubsetKey,
|
|
152
|
+
(qbWrapper: PuriWrapper<DatabaseSchemaExtend>) => Puri<any, any, any>
|
|
153
|
+
>,
|
|
154
|
+
> = {
|
|
155
|
+
[K in SubsetKey]: ExtractTTables<ReturnType<SubsetQueries[K]>>;
|
|
156
|
+
}[SubsetKey];
|
|
157
|
+
|
|
158
|
+
// ON CONFLICT 대상 타입
|
|
159
|
+
// - 단일 컬럼: "email"
|
|
160
|
+
// - 복수 컬럼: ["user_id", "product_id"]
|
|
161
|
+
export type OnConflictTarget = string | string[];
|
|
162
|
+
|
|
163
|
+
// ON CONFLICT 액션 타입
|
|
164
|
+
// - "nothing": DO NOTHING
|
|
165
|
+
// - { update: [...] }: DO UPDATE
|
|
166
|
+
export type OnConflictAction<TTables extends Record<string, unknown>> =
|
|
167
|
+
| "nothing"
|
|
168
|
+
| {
|
|
169
|
+
update:
|
|
170
|
+
| AvailableColumns<TTables>[] // 배열 형태 - ["name", "email"]
|
|
171
|
+
| WhereCondition<TTables>; // 객체 형태 - { name: "John", count: Puri.rawNumber(...) }
|
|
172
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PuriTransactionWrapper } from "./puri-wrapper";
|
|
2
1
|
import type { DBPreset } from "./db";
|
|
2
|
+
import type { PuriTransactionWrapper } from "./puri-wrapper";
|
|
3
3
|
|
|
4
4
|
export class TransactionContext {
|
|
5
5
|
private transactions: Map<DBPreset, PuriTransactionWrapper> = new Map();
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { randomUUID } from "crypto";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import type { Knex } from "knex";
|
|
3
|
+
import { unique } from "radashi";
|
|
4
4
|
import { EntityManager } from "../entity/entity-manager";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { Naite } from "../naite/naite";
|
|
6
|
+
import { assertDefined, chunk, nonNullable } from "../utils/utils";
|
|
7
|
+
import { batchUpdate, type RowWithId } from "./_batch_update";
|
|
7
8
|
|
|
8
9
|
type TableData = {
|
|
9
10
|
references: Set<string>;
|
|
10
|
-
rows:
|
|
11
|
+
rows: Record<string, unknown>[];
|
|
11
12
|
uniqueIndexes: { name?: string; columns: string[] }[];
|
|
12
13
|
uniquesMap: Map<string, string>;
|
|
13
14
|
};
|
|
@@ -16,12 +17,12 @@ export type UBRef = {
|
|
|
16
17
|
of: string;
|
|
17
18
|
use?: string;
|
|
18
19
|
};
|
|
19
|
-
export function isRefField(field:
|
|
20
|
+
export function isRefField(field: unknown): field is UBRef {
|
|
20
21
|
return (
|
|
21
22
|
field !== undefined &&
|
|
22
23
|
field !== null &&
|
|
23
|
-
field
|
|
24
|
-
field
|
|
24
|
+
(field as UBRef)?.of !== undefined &&
|
|
25
|
+
(field as UBRef)?.uuid !== undefined
|
|
25
26
|
);
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -33,24 +34,26 @@ export class UpsertBuilder {
|
|
|
33
34
|
|
|
34
35
|
getTable(tableName: string): TableData {
|
|
35
36
|
const table = this.tables.get(tableName);
|
|
36
|
-
if (table
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
return EntityManager.getTableSpec(tableName);
|
|
40
|
-
} catch {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
})();
|
|
44
|
-
|
|
45
|
-
this.tables.set(tableName, {
|
|
46
|
-
references: new Set(),
|
|
47
|
-
rows: [],
|
|
48
|
-
uniqueIndexes: tableSpec?.uniqueIndexes ?? [],
|
|
49
|
-
uniquesMap: new Map<string, string>(),
|
|
50
|
-
});
|
|
37
|
+
if (table) {
|
|
38
|
+
return table;
|
|
51
39
|
}
|
|
52
40
|
|
|
53
|
-
|
|
41
|
+
const tableSpec = (() => {
|
|
42
|
+
try {
|
|
43
|
+
return EntityManager.getTableSpec(tableName);
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
})();
|
|
48
|
+
|
|
49
|
+
const tableData = {
|
|
50
|
+
references: new Set<string>(),
|
|
51
|
+
rows: [],
|
|
52
|
+
uniqueIndexes: tableSpec?.uniqueIndexes ?? [],
|
|
53
|
+
uniquesMap: new Map<string, string>(),
|
|
54
|
+
};
|
|
55
|
+
this.tables.set(tableName, tableData);
|
|
56
|
+
return tableData;
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
hasTable(tableName: string): boolean {
|
|
@@ -60,16 +63,8 @@ export class UpsertBuilder {
|
|
|
60
63
|
register<T extends string>(
|
|
61
64
|
tableName: string,
|
|
62
65
|
row: {
|
|
63
|
-
[key in T]?:
|
|
64
|
-
|
|
65
|
-
| string
|
|
66
|
-
| number
|
|
67
|
-
| boolean
|
|
68
|
-
| bigint
|
|
69
|
-
| null
|
|
70
|
-
| object
|
|
71
|
-
| unknown;
|
|
72
|
-
}
|
|
66
|
+
[key in T]?: UBRef | string | number | boolean | bigint | null | object | unknown;
|
|
67
|
+
},
|
|
73
68
|
): UBRef {
|
|
74
69
|
const table = this.getTable(tableName);
|
|
75
70
|
|
|
@@ -94,18 +89,21 @@ export class UpsertBuilder {
|
|
|
94
89
|
.filter(nonNullable);
|
|
95
90
|
|
|
96
91
|
// uuid 생성 로직
|
|
97
|
-
const uuid
|
|
92
|
+
const { uuid, isReused } = (() => {
|
|
98
93
|
// 키를 순회하여 이미 존재하는 키가 있는지 확인
|
|
99
94
|
if (uniqueKeys.length > 0) {
|
|
100
95
|
for (const uniqueKey of uniqueKeys) {
|
|
101
96
|
if (table.uniquesMap.has(uniqueKey)) {
|
|
102
|
-
return
|
|
97
|
+
return {
|
|
98
|
+
uuid: assertDefined(table.uniquesMap.get(uniqueKey), "Unique key not found"),
|
|
99
|
+
isReused: true,
|
|
100
|
+
};
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
// 찾을 수 없는 경우 생성
|
|
108
|
-
return randomUUID();
|
|
106
|
+
return { uuid: randomUUID(), isReused: false };
|
|
109
107
|
})();
|
|
110
108
|
|
|
111
109
|
// 모든 유니크키에 대해 유니크맵에 uuid 저장
|
|
@@ -117,45 +115,45 @@ export class UpsertBuilder {
|
|
|
117
115
|
|
|
118
116
|
// 이 테이블에 사용된 RefField를 순회하여, 현재 테이블 정보에 어떤 필드를 참조하는지 추가
|
|
119
117
|
// 이 정보를 나중에 치환할 때 사용
|
|
120
|
-
row = Object.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
}, {} as any);
|
|
118
|
+
row = Object.fromEntries(
|
|
119
|
+
Object.entries(row).map(([rowKey, rowValue]) => {
|
|
120
|
+
if (isRefField(rowValue)) {
|
|
121
|
+
rowValue.use ??= "id";
|
|
122
|
+
table.references.add(`${rowValue.of}.${rowValue.use}`);
|
|
123
|
+
return [rowKey, rowValue];
|
|
124
|
+
} else if (typeof rowValue === "object" && !(rowValue instanceof Date)) {
|
|
125
|
+
// object인 경우 JSON으로 변환
|
|
126
|
+
return [rowKey, rowValue === null ? null : JSON.stringify(rowValue)];
|
|
127
|
+
} else {
|
|
128
|
+
return [rowKey, rowValue];
|
|
129
|
+
}
|
|
130
|
+
}),
|
|
131
|
+
) as { [key in T]?: unknown };
|
|
135
132
|
|
|
136
133
|
table.rows.push({
|
|
137
134
|
uuid,
|
|
138
135
|
...row,
|
|
139
136
|
});
|
|
140
137
|
|
|
141
|
-
|
|
138
|
+
const result: UBRef = {
|
|
142
139
|
of: tableName,
|
|
143
140
|
uuid: (row as { uuid?: string }).uuid ?? uuid,
|
|
144
141
|
};
|
|
142
|
+
|
|
143
|
+
Naite.t("puri:ub-register", {
|
|
144
|
+
tableName,
|
|
145
|
+
uuid: result.uuid,
|
|
146
|
+
isUuidReused: isReused,
|
|
147
|
+
row,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return result;
|
|
145
151
|
}
|
|
146
152
|
|
|
147
|
-
async upsert(
|
|
148
|
-
wdb: Knex,
|
|
149
|
-
tableName: string,
|
|
150
|
-
chunkSize?: number
|
|
151
|
-
): Promise<number[]> {
|
|
153
|
+
async upsert(wdb: Knex, tableName: string, chunkSize?: number): Promise<number[]> {
|
|
152
154
|
return this.upsertOrInsert(wdb, tableName, "upsert", chunkSize);
|
|
153
155
|
}
|
|
154
|
-
async insertOnly(
|
|
155
|
-
wdb: Knex,
|
|
156
|
-
tableName: string,
|
|
157
|
-
chunkSize?: number
|
|
158
|
-
): Promise<number[]> {
|
|
156
|
+
async insertOnly(wdb: Knex, tableName: string, chunkSize?: number): Promise<number[]> {
|
|
159
157
|
return this.upsertOrInsert(wdb, tableName, "insert", chunkSize);
|
|
160
158
|
}
|
|
161
159
|
|
|
@@ -163,7 +161,7 @@ export class UpsertBuilder {
|
|
|
163
161
|
wdb: Knex,
|
|
164
162
|
tableName: string,
|
|
165
163
|
mode: "upsert" | "insert",
|
|
166
|
-
chunkSize?: number
|
|
164
|
+
chunkSize?: number,
|
|
167
165
|
): Promise<number[]> {
|
|
168
166
|
if (this.hasTable(tableName) === false) {
|
|
169
167
|
return [];
|
|
@@ -178,9 +176,7 @@ export class UpsertBuilder {
|
|
|
178
176
|
|
|
179
177
|
if (
|
|
180
178
|
table.rows.some((row) =>
|
|
181
|
-
Object.entries(row).some(
|
|
182
|
-
([, value]) => isRefField(value) && value.of !== tableName
|
|
183
|
-
)
|
|
179
|
+
Object.entries(row).some(([, value]) => isRefField(value) && value.of !== tableName),
|
|
184
180
|
)
|
|
185
181
|
) {
|
|
186
182
|
throw new Error(`${tableName} 해결되지 않은 참조가 있습니다.`);
|
|
@@ -190,7 +186,7 @@ export class UpsertBuilder {
|
|
|
190
186
|
const { references, refTables } = Array.from(this.tables).reduce(
|
|
191
187
|
(r, [, table]) => {
|
|
192
188
|
const reference = Array.from(table.references.values()).find((ref) =>
|
|
193
|
-
ref.includes(tableName
|
|
189
|
+
ref.includes(`${tableName}.`),
|
|
194
190
|
);
|
|
195
191
|
if (reference) {
|
|
196
192
|
r.references.push(reference);
|
|
@@ -202,77 +198,132 @@ export class UpsertBuilder {
|
|
|
202
198
|
{
|
|
203
199
|
references: [] as string[],
|
|
204
200
|
refTables: [] as TableData[],
|
|
205
|
-
}
|
|
206
|
-
);
|
|
207
|
-
const extractFields = _.uniq(references).map(
|
|
208
|
-
(reference) => reference.split(".")[1]
|
|
201
|
+
},
|
|
209
202
|
);
|
|
203
|
+
const extractFields = unique(references)
|
|
204
|
+
.map((reference) => reference.split(".")[1])
|
|
205
|
+
.filter((field): field is string => field !== undefined);
|
|
210
206
|
|
|
211
|
-
//
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (mode === "insert") {
|
|
226
|
-
await q;
|
|
227
|
-
} else if (mode === "upsert") {
|
|
228
|
-
await q.onDuplicateUpdate.apply(q, Object.keys(normalRows[0]));
|
|
229
|
-
}
|
|
207
|
+
// 의존성 순서에 따라 레벨별 그룹화 (자기 참조가 없으면 Level 0 하나)
|
|
208
|
+
const { levels, hasCircular } = this.buildInsertLevels(table.rows, tableName);
|
|
209
|
+
|
|
210
|
+
if (hasCircular) {
|
|
211
|
+
throw new Error(`${tableName}에 순환 자기 참조가 있습니다.`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// upsert 모드일 때 유니크 인덱스가 없으면 에러
|
|
215
|
+
if (mode === "upsert" && table.uniqueIndexes.length === 0) {
|
|
216
|
+
throw new Error(`${tableName}에 unique index가 정의되지 않아 upsert를 할 수 없습니다.`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const uuidMap = new Map<string, unknown>();
|
|
220
|
+
const allIds: number[] = [];
|
|
230
221
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
222
|
+
// 레벨별로 순차 처리
|
|
223
|
+
for (const levelRows of levels) {
|
|
224
|
+
// 이전 레벨에서 얻은 ID로 자기 참조 해결
|
|
225
|
+
const resolvedRows = levelRows.map((row) => {
|
|
226
|
+
const resolved = { ...row };
|
|
227
|
+
for (const [key, value] of Object.entries(row)) {
|
|
228
|
+
if (isRefField(value) && value.of === tableName) {
|
|
229
|
+
const parent = uuidMap.get(value.uuid);
|
|
230
|
+
|
|
231
|
+
if (!parent) throw new Error(`존재하지 않는 uuid ${value.uuid} -- in ${tableName}`);
|
|
232
|
+
|
|
233
|
+
resolved[key] = (parent as Record<string, unknown>)[value.use ?? "id"];
|
|
234
|
+
|
|
235
|
+
Naite.t("puri:ub-ref-resolved", {
|
|
236
|
+
tableName,
|
|
237
|
+
field: key,
|
|
238
|
+
from: { of: value.of, uuid: value.uuid, use: value.use ?? "id" },
|
|
239
|
+
to: resolved[key],
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return resolved;
|
|
238
244
|
});
|
|
245
|
+
|
|
246
|
+
// 현재 레벨 upsert
|
|
247
|
+
const levelChunks = chunkSize ? chunk(resolvedRows, chunkSize) : [resolvedRows];
|
|
248
|
+
const selectFields = unique(["uuid", "id", ...extractFields]);
|
|
249
|
+
|
|
250
|
+
for (const dataChunk of levelChunks) {
|
|
251
|
+
if (dataChunk.length === 0) continue;
|
|
252
|
+
|
|
253
|
+
let resultRows: { uuid: string; id: number; [key: string]: unknown }[];
|
|
254
|
+
|
|
255
|
+
if (mode === "insert") {
|
|
256
|
+
// INSERT 모드
|
|
257
|
+
await wdb.insert(dataChunk).into(tableName);
|
|
258
|
+
|
|
259
|
+
const uuids = dataChunk.map((r) => r.uuid);
|
|
260
|
+
resultRows = await wdb(tableName)
|
|
261
|
+
.select(selectFields)
|
|
262
|
+
.whereIn("uuid", uuids as readonly string[]);
|
|
263
|
+
} else {
|
|
264
|
+
// UPSERT 모드 (uniqueIndexes 이미 체크됨)
|
|
265
|
+
const conflictColumns = table.uniqueIndexes[0].columns;
|
|
266
|
+
const updateColumns = Object.keys(dataChunk[0]).filter(
|
|
267
|
+
(col) => col !== "uuid" && !conflictColumns.includes(col),
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
// RETURNING으로 결과 받기
|
|
271
|
+
const query = wdb.insert(dataChunk).into(tableName).onConflict(conflictColumns);
|
|
272
|
+
|
|
273
|
+
// updateColumns가 비어있으면 ignore(), 아니면 merge()
|
|
274
|
+
if (updateColumns.length === 0) {
|
|
275
|
+
resultRows = await query.ignore().returning(selectFields);
|
|
276
|
+
} else {
|
|
277
|
+
resultRows = await query.merge(updateColumns).returning(selectFields);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// 양쪽 모드 공통 처리
|
|
282
|
+
for (const row of resultRows) {
|
|
283
|
+
uuidMap.set(row.uuid, row);
|
|
284
|
+
allIds.push(row.id);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
239
287
|
}
|
|
240
288
|
|
|
241
289
|
// 해당 테이블 참조를 실제 밸류로 변경
|
|
242
|
-
|
|
290
|
+
for (const table of refTables) {
|
|
243
291
|
table.rows = table.rows.map((row) => {
|
|
244
|
-
Object.keys(row)
|
|
292
|
+
for (const key of Object.keys(row)) {
|
|
245
293
|
const prop = row[key];
|
|
246
294
|
if (isRefField(prop) && prop.of === tableName) {
|
|
247
295
|
const parent = uuidMap.get(prop.uuid);
|
|
248
|
-
if (parent
|
|
296
|
+
if (!parent) {
|
|
249
297
|
console.error(prop);
|
|
250
|
-
throw new Error(
|
|
251
|
-
`존재하지 않는 uuid ${prop.uuid} -- in ${tableName}`
|
|
252
|
-
);
|
|
298
|
+
throw new Error(`존재하지 않는 uuid ${prop.uuid} -- in ${tableName}`);
|
|
253
299
|
}
|
|
254
|
-
|
|
300
|
+
const resolvedValue = (parent as Record<string, unknown>)[prop.use ?? "id"];
|
|
301
|
+
row[key] = resolvedValue;
|
|
302
|
+
|
|
303
|
+
Naite.t("puri:ub-ref-resolved", {
|
|
304
|
+
tableName,
|
|
305
|
+
field: key,
|
|
306
|
+
from: { of: prop.of, uuid: prop.uuid, use: prop.use ?? "id" },
|
|
307
|
+
to: resolvedValue,
|
|
308
|
+
});
|
|
255
309
|
}
|
|
256
|
-
}
|
|
310
|
+
}
|
|
257
311
|
return row;
|
|
258
312
|
});
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
const allIds = Array.from(uuidMap.values()).map((row) => row.id);
|
|
262
|
-
|
|
263
|
-
// 자기 참조가 있는 경우 재귀적으로 upsert
|
|
264
|
-
if (selfRefRows.length > 0) {
|
|
265
|
-
// 처리된 데이터를 제외하고 다시 upsert
|
|
266
|
-
table.rows = selfRefRows;
|
|
267
|
-
const selfRefIds = await this.upsert(wdb, tableName, chunkSize);
|
|
268
|
-
allIds.push(...selfRefIds);
|
|
269
|
-
} else {
|
|
270
|
-
// 자기 참조가 없으면 해당 테이블의 데이터 초기화
|
|
271
|
-
table.rows = [];
|
|
272
|
-
table.references.clear();
|
|
273
|
-
table.uniquesMap.clear();
|
|
274
313
|
}
|
|
275
314
|
|
|
315
|
+
// 해당 테이블의 데이터 초기화
|
|
316
|
+
table.rows = [];
|
|
317
|
+
table.references.clear();
|
|
318
|
+
table.uniquesMap.clear();
|
|
319
|
+
|
|
320
|
+
Naite.t("puri:ub-upserted", {
|
|
321
|
+
tableName,
|
|
322
|
+
mode,
|
|
323
|
+
rowCount: allIds.length,
|
|
324
|
+
returnedIds: allIds,
|
|
325
|
+
});
|
|
326
|
+
|
|
276
327
|
return allIds;
|
|
277
328
|
}
|
|
278
329
|
|
|
@@ -282,34 +333,113 @@ export class UpsertBuilder {
|
|
|
282
333
|
options?: {
|
|
283
334
|
chunkSize?: number;
|
|
284
335
|
where?: string | string[];
|
|
285
|
-
}
|
|
336
|
+
},
|
|
286
337
|
): Promise<void> {
|
|
287
|
-
options =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
338
|
+
options = {
|
|
339
|
+
...options,
|
|
340
|
+
chunkSize: options?.chunkSize ?? 500,
|
|
341
|
+
where: options?.where ?? "id",
|
|
342
|
+
};
|
|
291
343
|
|
|
292
344
|
if (this.hasTable(tableName) === false) {
|
|
293
345
|
return;
|
|
294
346
|
}
|
|
295
|
-
const table = this.tables.get(tableName)
|
|
296
|
-
if (table
|
|
347
|
+
const table = this.tables.get(tableName);
|
|
348
|
+
if (!table) {
|
|
349
|
+
throw new Error(`등록되지 않은 테이블 ${tableName}에 updateBatch 요청`);
|
|
350
|
+
} else if (table.rows.length === 0) {
|
|
297
351
|
return;
|
|
298
352
|
}
|
|
299
353
|
|
|
300
|
-
const whereColumns = Array.isArray(options.where)
|
|
301
|
-
? options.where
|
|
302
|
-
: [options.where ?? "id"];
|
|
354
|
+
const whereColumns = Array.isArray(options.where) ? options.where : [options.where ?? "id"];
|
|
303
355
|
const rows = table.rows.map((_row) => {
|
|
304
|
-
const { uuid, ...row } = _row;
|
|
356
|
+
const { uuid: _, ...row } = _row; // uuid 제외
|
|
305
357
|
return row as RowWithId<string>;
|
|
306
358
|
});
|
|
307
359
|
|
|
308
360
|
await batchUpdate(wdb, tableName, whereColumns, rows, options.chunkSize);
|
|
309
361
|
|
|
362
|
+
Naite.t("puri:ub-batch-updated", {
|
|
363
|
+
tableName,
|
|
364
|
+
rowCount: rows.length,
|
|
365
|
+
whereColumns,
|
|
366
|
+
});
|
|
367
|
+
|
|
310
368
|
// updateBatch 완료 후 처리된 데이터 제거
|
|
311
369
|
table.rows = [];
|
|
312
370
|
table.references.clear();
|
|
313
371
|
table.uniquesMap.clear();
|
|
314
372
|
}
|
|
373
|
+
|
|
374
|
+
// ============================================================================
|
|
375
|
+
// Private Helpers
|
|
376
|
+
// ============================================================================
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* rows를 의존성 순서에 따라 레벨별로 그룹화
|
|
380
|
+
* - 자기 참조 없는 경우 : 모든 rows가 Level 0
|
|
381
|
+
* - 자기 참조 있는 경우 : 자기 참조 관계를 위상 정렬하여 레벨별로 그룹화
|
|
382
|
+
*/
|
|
383
|
+
private buildInsertLevels(
|
|
384
|
+
rows: Record<string, unknown>[],
|
|
385
|
+
tableName: string,
|
|
386
|
+
): { levels: Record<string, unknown>[][]; hasCircular: boolean } {
|
|
387
|
+
// 1. 자기 참조가 없으면 한 레벨로 처리
|
|
388
|
+
const hasSelfRef = rows
|
|
389
|
+
.flatMap((row) => Object.values(row))
|
|
390
|
+
.some((value) => isRefField(value) && value.of === tableName);
|
|
391
|
+
if (!hasSelfRef) return { levels: [rows], hasCircular: false };
|
|
392
|
+
|
|
393
|
+
// 2. uuid → row 매핑 (중복 uuid 방지)
|
|
394
|
+
const rowByUuid = new Map<string, Record<string, unknown>>();
|
|
395
|
+
for (const row of rows) {
|
|
396
|
+
const uuid = row.uuid as string | undefined;
|
|
397
|
+
if (!uuid) throw new Error(`buildInsertLevels: uuid가 없는 row -- in ${tableName}`);
|
|
398
|
+
rowByUuid.set(uuid, row);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
let pending = Array.from(rowByUuid.values());
|
|
402
|
+
const levels: Record<string, unknown>[][] = [];
|
|
403
|
+
const inserted = new Set<string>();
|
|
404
|
+
|
|
405
|
+
// 3. 레벨별 분류
|
|
406
|
+
while (pending.length > 0) {
|
|
407
|
+
const currentLevel: Record<string, unknown>[] = [];
|
|
408
|
+
const nextPending: Record<string, unknown>[] = [];
|
|
409
|
+
|
|
410
|
+
for (const row of pending) {
|
|
411
|
+
// 이 row가 참조하는 자기 참조들
|
|
412
|
+
const selfRefs = Object.values(row).filter(
|
|
413
|
+
(value) => isRefField(value) && value.of === tableName,
|
|
414
|
+
) as UBRef[];
|
|
415
|
+
|
|
416
|
+
// 참조하는 모든 uuid가 이미 inserted에 있어야 이번 레벨에 포함
|
|
417
|
+
const canInsert = selfRefs.every((ref) => {
|
|
418
|
+
if (!rowByUuid.has(ref.uuid)) {
|
|
419
|
+
throw new Error(`존재하지 않는 uuid ${ref.uuid} -- in ${tableName}`);
|
|
420
|
+
}
|
|
421
|
+
return inserted.has(ref.uuid);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
if (canInsert) {
|
|
425
|
+
currentLevel.push(row);
|
|
426
|
+
} else {
|
|
427
|
+
nextPending.push(row);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// 순환 참조 감지
|
|
432
|
+
if (currentLevel.length === 0) return { levels: [], hasCircular: true };
|
|
433
|
+
|
|
434
|
+
// 레벨 확정 + inserted 갱신
|
|
435
|
+
levels.push(currentLevel);
|
|
436
|
+
for (const row of currentLevel) {
|
|
437
|
+
inserted.add(row.uuid as string);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
pending = nextPending;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return { levels, hasCircular: false };
|
|
444
|
+
}
|
|
315
445
|
}
|