sonamu 0.6.0 → 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 +2 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +6 -1
- 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 +178 -409
- package/dist/api/config.d.ts +27 -13
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +19 -26
- package/dist/api/context.d.ts +4 -3
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts +20 -6
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +111 -18
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +3 -3
- package/dist/api/sonamu.d.ts +7 -7
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +83 -51
- 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 +5 -1
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +5 -2
- package/dist/bin/cli.js +165 -64
- 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 +30 -13
- 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 +232 -89
- 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 +11 -10
- package/dist/database/db.d.ts +5 -6
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +22 -25
- 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 +2 -2
- package/dist/database/puri.d.ts +25 -14
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +83 -21
- package/dist/database/puri.types.d.ts +21 -7
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +4 -1
- 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 +1 -1
- 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 +228 -78
- package/dist/entity/entity-manager.d.ts +165 -2
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +26 -10
- package/dist/entity/entity.d.ts +5 -3
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +153 -54
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/file-storage/file-storage.js +2 -2
- package/dist/index.d.ts +18 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -13
- 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 +123 -67
- 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 +67 -218
- package/dist/migration/migrator.d.ts +24 -73
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +121 -301
- 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 +1 -1
- 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 +91 -8
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +285 -41
- package/dist/stream/sse.d.ts +2 -2
- package/dist/stream/sse.d.ts.map +1 -1
- package/dist/stream/sse.js +1 -1
- package/dist/syncer/api-parser.d.ts +3 -13
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +67 -56
- package/dist/syncer/checksum.d.ts +2 -2
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +11 -11
- package/dist/syncer/code-generator.d.ts +3 -3
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +37 -17
- package/dist/syncer/entity-operations.d.ts +2 -2
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +9 -8
- package/dist/syncer/file-patterns.d.ts +1 -1
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +1 -1
- package/dist/syncer/index.d.ts +4 -4
- package/dist/syncer/index.d.ts.map +1 -1
- package/dist/syncer/index.js +5 -5
- package/dist/syncer/module-loader.d.ts +4 -4
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +17 -12
- package/dist/syncer/syncer.d.ts +31 -24
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +92 -45
- 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 +15 -8
- package/dist/template/helpers.d.ts +2 -2
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +3 -3
- package/dist/template/implementations/entity.template.d.ts +2 -2
- package/dist/template/implementations/entity.template.d.ts.map +1 -1
- package/dist/template/implementations/entity.template.js +4 -5
- package/dist/template/implementations/generated.template.d.ts +2 -3
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +46 -29
- package/dist/template/implementations/generated_http.template.d.ts +2 -3
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +9 -9
- package/dist/template/implementations/generated_sso.template.d.ts +3 -4
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +54 -25
- package/dist/template/implementations/init_types.template.d.ts +2 -2
- package/dist/template/implementations/init_types.template.d.ts.map +1 -1
- package/dist/template/implementations/init_types.template.js +2 -2
- package/dist/template/implementations/model.template.d.ts +2 -2
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +47 -37
- package/dist/template/implementations/model_test.template.d.ts +2 -2
- package/dist/template/implementations/model_test.template.d.ts.map +1 -1
- package/dist/template/implementations/model_test.template.js +2 -2
- package/dist/template/implementations/service.template.d.ts +4 -4
- package/dist/template/implementations/service.template.d.ts.map +1 -1
- package/dist/template/implementations/service.template.js +24 -16
- package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
- package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
- package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_select.template.js +2 -2
- package/dist/template/implementations/view_form.template.d.ts +2 -2
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +4 -4
- package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_all_select.template.js +1 -1
- package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
- package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_async_select.template.js +1 -1
- package/dist/template/implementations/view_list.template.d.ts +2 -2
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +29 -19
- package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
- package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list_columns.template.js +1 -1
- package/dist/template/implementations/view_search_input.template.d.ts +2 -2
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.js +1 -1
- package/dist/template/index.d.ts +4 -2
- package/dist/template/index.d.ts.map +1 -1
- package/dist/template/index.js +5 -3
- 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 +12 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +19 -6
- package/dist/template/zod-converter.d.ts +40 -7
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +341 -58
- 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 +12 -3
- 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 +338 -236
- package/dist/types/types.d.ts +709 -104
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +309 -52
- package/dist/typings/knex.d.js +2 -2
- package/dist/utils/async-utils.d.ts.map +1 -1
- package/dist/utils/async-utils.js +3 -3
- package/dist/utils/console-util.js +1 -1
- package/dist/utils/controller.d.ts +1 -0
- package/dist/utils/controller.d.ts.map +1 -1
- package/dist/utils/controller.js +4 -1
- package/dist/utils/esm-utils.d.ts +0 -6
- package/dist/utils/esm-utils.d.ts.map +1 -1
- package/dist/utils/esm-utils.js +2 -9
- 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 +1 -1
- package/dist/utils/lodash-able.d.ts.map +1 -1
- package/dist/utils/lodash-able.js +1 -1
- 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 +1 -1
- package/dist/utils/path-utils.d.ts.map +1 -1
- package/dist/utils/path-utils.js +3 -3
- package/dist/utils/process-utils.js +1 -1
- 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 +14 -3
- 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 +7 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +44 -5
- 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 +1 -1
- package/package.json +54 -29
- 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 +176 -533
- package/src/api/config.ts +39 -56
- package/src/api/context.ts +7 -18
- package/src/api/decorators.ts +175 -46
- package/src/api/index.ts +2 -2
- package/src/api/sonamu.ts +133 -124
- package/src/api/validator.ts +83 -0
- package/src/bin/build-config.ts +7 -1
- package/src/bin/cli.ts +192 -110
- 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 +36 -50
- 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 +182 -126
- package/src/database/puri.types.ts +64 -31
- package/src/database/transaction-context.ts +1 -1
- package/src/database/upsert-builder.ts +262 -132
- package/src/entity/entity-manager.ts +36 -28
- package/src/entity/entity.ts +330 -249
- 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 -12
- package/src/migration/code-generation.ts +185 -172
- package/src/migration/migration-set.ts +80 -293
- package/src/migration/migrator.ts +182 -425
- 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 +378 -33
- package/src/shared/web.shared.ts.txt +20 -24
- package/src/stream/sse.ts +5 -5
- package/src/syncer/api-parser.ts +52 -69
- package/src/syncer/checksum.ts +25 -37
- package/src/syncer/code-generator.ts +58 -62
- package/src/syncer/entity-operations.ts +12 -15
- package/src/syncer/file-patterns.ts +2 -2
- package/src/syncer/index.ts +4 -4
- package/src/syncer/module-loader.ts +28 -25
- package/src/syncer/syncer.ts +155 -162
- package/src/template/entity-converter.ts +18 -27
- package/src/template/helpers.ts +8 -11
- package/src/template/implementations/entity.template.ts +6 -6
- package/src/template/implementations/generated.template.ts +99 -99
- package/src/template/implementations/generated_http.template.ts +21 -54
- package/src/template/implementations/generated_sso.template.ts +78 -65
- package/src/template/implementations/init_types.template.ts +4 -6
- package/src/template/implementations/model.template.ts +47 -38
- package/src/template/implementations/model_test.template.ts +3 -3
- package/src/template/implementations/service.template.ts +56 -80
- package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
- package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
- package/src/template/implementations/view_enums_select.template.ts +3 -3
- package/src/template/implementations/view_form.template.ts +34 -75
- package/src/template/implementations/view_id_all_select.template.ts +2 -2
- package/src/template/implementations/view_id_async_select.template.ts +9 -23
- package/src/template/implementations/view_list.template.ts +54 -95
- package/src/template/implementations/view_list_columns.template.ts +4 -10
- package/src/template/implementations/view_search_input.template.ts +2 -2
- package/src/template/index.ts +4 -2
- package/src/template/template-manager.ts +166 -0
- package/src/template/template-types.ts +16 -0
- package/src/template/template.ts +29 -10
- package/src/template/zod-converter.ts +407 -101
- package/src/testing/_relation-graph.ts +18 -11
- package/src/testing/fixture-manager.ts +468 -362
- package/src/types/types.ts +516 -248
- package/src/typings/knex.d.ts +7 -9
- package/src/utils/async-utils.ts +8 -12
- package/src/utils/console-util.ts +1 -1
- package/src/utils/controller.ts +3 -0
- package/src/utils/esm-utils.ts +8 -18
- 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 +3 -6
- package/src/utils/process-utils.ts +1 -1
- package/src/utils/sql-parser.ts +23 -5
- package/src/utils/type-utils.ts +83 -0
- package/src/utils/utils.ts +58 -9
- package/src/utils/zod-error.ts +3 -3
- 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 -72
- 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 -39
- 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 -210
- package/src/bin/cli-wrapper.ts +0 -82
- package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
- package/src/entity/entity-utils.ts +0 -291
package/src/database/puri.ts
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noThenProperty: Puri는 thenable 인터페이스를 구현하고 있습니다. */
|
|
2
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: Puri는 다양한 타입을 사용하고 있습니다. */
|
|
3
|
+
|
|
4
|
+
import assert from "assert";
|
|
5
|
+
import chalk from "chalk";
|
|
1
6
|
import type { Knex } from "knex";
|
|
7
|
+
import { Naite } from "../naite/naite";
|
|
2
8
|
import type {
|
|
3
9
|
AvailableColumns,
|
|
4
|
-
|
|
5
|
-
ParseSelectObject,
|
|
6
|
-
WhereCondition,
|
|
10
|
+
ColumnKeys,
|
|
7
11
|
ComparisonOperator,
|
|
8
|
-
ExtractColumnType,
|
|
9
|
-
SqlExpression,
|
|
10
12
|
Expand,
|
|
13
|
+
ExtractColumnType,
|
|
11
14
|
FulltextColumns,
|
|
12
|
-
ResultAvailableColumns,
|
|
13
15
|
InsertData,
|
|
16
|
+
InsertResult,
|
|
17
|
+
OnConflictAction,
|
|
18
|
+
ParseSelectObject,
|
|
19
|
+
ResultAvailableColumns,
|
|
20
|
+
SelectObject,
|
|
14
21
|
SingleTableValue,
|
|
22
|
+
SqlExpression,
|
|
23
|
+
WhereCondition,
|
|
15
24
|
} from "./puri.types";
|
|
16
|
-
import
|
|
17
|
-
import assert from "assert";
|
|
18
|
-
import { Naite } from "../naite/naite";
|
|
25
|
+
import type { ClearStatements } from "./puri-subset.types";
|
|
19
26
|
|
|
20
27
|
export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
21
28
|
private knexQuery: Knex.QueryBuilder;
|
|
22
29
|
|
|
23
30
|
// 생성자 시그니처들
|
|
24
31
|
constructor(knex: Knex, tableName: string);
|
|
25
|
-
constructor(
|
|
26
|
-
knex: Knex,
|
|
27
|
-
tableSpec: Record<string, string | Puri<TSchema, any, any>>
|
|
28
|
-
);
|
|
32
|
+
constructor(knex: Knex, tableSpec: Record<string, string | Puri<TSchema, any, any>>);
|
|
29
33
|
constructor(
|
|
30
34
|
public knex: Knex,
|
|
31
|
-
tableNameOrSpec: any
|
|
35
|
+
tableNameOrSpec: any,
|
|
32
36
|
) {
|
|
33
37
|
if (typeof tableNameOrSpec === "string") {
|
|
34
38
|
// Case: new Puri(knex, "users")
|
|
@@ -58,7 +62,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
58
62
|
return {
|
|
59
63
|
_type: "sql_expression",
|
|
60
64
|
_return: "number",
|
|
61
|
-
_sql: `COUNT(${column})`,
|
|
65
|
+
_sql: `COUNT(${column})::integer`,
|
|
62
66
|
};
|
|
63
67
|
}
|
|
64
68
|
static sum(column: string): SqlExpression<"number"> {
|
|
@@ -127,19 +131,14 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
127
131
|
|
|
128
132
|
// SELECT (overwrite)
|
|
129
133
|
select<TSelect extends SelectObject<TTables>>(
|
|
130
|
-
selectObj: TSelect
|
|
134
|
+
selectObj: TSelect,
|
|
131
135
|
): Puri<TSchema, TTables, ParseSelectObject<TTables, TSelect>> {
|
|
132
136
|
const selectClauses: (string | Knex.Raw)[] = [];
|
|
133
137
|
|
|
134
138
|
for (const [alias, columnOrFunction] of Object.entries(selectObj)) {
|
|
135
|
-
if (
|
|
136
|
-
typeof columnOrFunction === "object" &&
|
|
137
|
-
columnOrFunction._type === "sql_expression"
|
|
138
|
-
) {
|
|
139
|
+
if (typeof columnOrFunction === "object" && columnOrFunction._type === "sql_expression") {
|
|
139
140
|
// SQL 함수인 경우
|
|
140
|
-
selectClauses.push(
|
|
141
|
-
this.knex.raw(`${columnOrFunction._sql} as ${alias}`)
|
|
142
|
-
);
|
|
141
|
+
selectClauses.push(this.knex.raw(`${columnOrFunction._sql} as ${alias}`));
|
|
143
142
|
} else {
|
|
144
143
|
// 일반 컬럼인 경우
|
|
145
144
|
const columnPath = columnOrFunction as string;
|
|
@@ -159,7 +158,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
159
158
|
|
|
160
159
|
// SELECT (select는 overwrite, appendSelect는 append)
|
|
161
160
|
appendSelect<TSelect extends SelectObject<TTables>>(
|
|
162
|
-
selectObj: TSelect
|
|
161
|
+
selectObj: TSelect,
|
|
163
162
|
): Puri<TSchema, TTables, TResult & ParseSelectObject<TTables, TSelect>> {
|
|
164
163
|
return this.select(selectObj) as any;
|
|
165
164
|
}
|
|
@@ -170,11 +169,30 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
170
169
|
return this as any;
|
|
171
170
|
}
|
|
172
171
|
|
|
172
|
+
// CLEAR
|
|
173
|
+
clear(statement: ClearStatements): this {
|
|
174
|
+
this.knexQuery.clear(statement);
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// knex에 없어서 직접 구현함
|
|
179
|
+
clearJoin(alias: string): this {
|
|
180
|
+
(this.knexQuery as any)._statements = (this.knexQuery as any)._statements.filter((s: any) => {
|
|
181
|
+
if ("joinType" in s) {
|
|
182
|
+
const [_alias, _table] = Object.entries(s.table)[0];
|
|
183
|
+
return _alias !== alias;
|
|
184
|
+
} else {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
return this;
|
|
189
|
+
}
|
|
190
|
+
|
|
173
191
|
// JOIN: 서브쿼리 + Alias
|
|
174
192
|
join<TJoinAlias extends string, TSubResult>(
|
|
175
193
|
tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
|
|
176
194
|
left: AvailableColumns<TTables>,
|
|
177
|
-
right: `${TJoinAlias}.${
|
|
195
|
+
right: `${TJoinAlias}.${ColumnKeys<TSubResult>}`,
|
|
178
196
|
): Puri<
|
|
179
197
|
TSchema,
|
|
180
198
|
TTables & Record<TJoinAlias, TSubResult>, // 서브쿼리의 TResult
|
|
@@ -184,7 +202,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
184
202
|
join<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
|
|
185
203
|
tableSpec: { [K in TJoinAlias]: TJoinTable },
|
|
186
204
|
left: AvailableColumns<TTables>,
|
|
187
|
-
right: `${TJoinAlias}.${
|
|
205
|
+
right: `${TJoinAlias}.${ColumnKeys<TSchema[TJoinTable]>}`,
|
|
188
206
|
): Puri<
|
|
189
207
|
TSchema,
|
|
190
208
|
TTables & Record<TJoinAlias, TSchema[TJoinTable]>, // TTables 확장!
|
|
@@ -194,7 +212,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
194
212
|
join<TJoinTable extends keyof TSchema>(
|
|
195
213
|
tableName: TJoinTable,
|
|
196
214
|
left: AvailableColumns<TTables>,
|
|
197
|
-
right: `${TJoinTable & string}.${
|
|
215
|
+
right: `${TJoinTable & string}.${ColumnKeys<TSchema[TJoinTable]>}`,
|
|
198
216
|
): Puri<
|
|
199
217
|
TSchema,
|
|
200
218
|
TTables & Record<TJoinTable, TSchema[TJoinTable]>, // 테이블명이 키
|
|
@@ -203,23 +221,17 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
203
221
|
// JOIN: 서브쿼리 + Alias + 콜백
|
|
204
222
|
join<TJoinAlias extends string, TSubResult>(
|
|
205
223
|
tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
|
|
206
|
-
callback: (
|
|
207
|
-
j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>
|
|
208
|
-
) => void
|
|
224
|
+
callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>) => void,
|
|
209
225
|
): Puri<TSchema, TTables & Record<TJoinAlias, TSubResult>, TResult>;
|
|
210
226
|
// JOIN: 테이블 + Alias + 콜백
|
|
211
227
|
join<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
|
|
212
228
|
tableSpec: { [K in TJoinAlias]: TJoinTable },
|
|
213
|
-
callback: (
|
|
214
|
-
j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>
|
|
215
|
-
) => void
|
|
229
|
+
callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>) => void,
|
|
216
230
|
): Puri<TSchema, TTables & Record<TJoinAlias, TSchema[TJoinTable]>, TResult>;
|
|
217
231
|
// JOIN: 테이블명 + 콜백
|
|
218
232
|
join<TJoinTable extends keyof TSchema>(
|
|
219
233
|
tableName: TJoinTable,
|
|
220
|
-
callback: (
|
|
221
|
-
j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>
|
|
222
|
-
) => void
|
|
234
|
+
callback: (j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>) => void,
|
|
223
235
|
): Puri<TSchema, TTables & Record<TJoinTable, TSchema[TJoinTable]>, TResult>;
|
|
224
236
|
// JOIN 실제 구현
|
|
225
237
|
join(tableNameOrSpec: any, ...args: any[]): any {
|
|
@@ -230,7 +242,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
230
242
|
leftJoin<TJoinAlias extends string, TSubResult>(
|
|
231
243
|
tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
|
|
232
244
|
left: AvailableColumns<TTables>,
|
|
233
|
-
right: `${TJoinAlias}.${
|
|
245
|
+
right: `${TJoinAlias}.${ColumnKeys<TSubResult>}`,
|
|
234
246
|
): Puri<
|
|
235
247
|
TSchema,
|
|
236
248
|
TTables & Record<TJoinAlias, TSubResult>, // 서브쿼리의 TResult
|
|
@@ -240,7 +252,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
240
252
|
leftJoin<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
|
|
241
253
|
tableSpec: { [K in TJoinAlias]: TJoinTable },
|
|
242
254
|
left: AvailableColumns<TTables>,
|
|
243
|
-
right: `${TJoinAlias}.${
|
|
255
|
+
right: `${TJoinAlias}.${ColumnKeys<TSchema[TJoinTable]>}`,
|
|
244
256
|
): Puri<
|
|
245
257
|
TSchema,
|
|
246
258
|
TTables & Record<TJoinAlias, TSchema[TJoinTable]>, // TTables 확장!
|
|
@@ -250,7 +262,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
250
262
|
leftJoin<TJoinTable extends keyof TSchema>(
|
|
251
263
|
tableName: TJoinTable,
|
|
252
264
|
left: AvailableColumns<TTables>,
|
|
253
|
-
right: `${TJoinTable & string}.${
|
|
265
|
+
right: `${TJoinTable & string}.${ColumnKeys<TSchema[TJoinTable]>}`,
|
|
254
266
|
): Puri<
|
|
255
267
|
TSchema,
|
|
256
268
|
TTables & Record<TJoinTable, TSchema[TJoinTable]>, // 테이블명이 키
|
|
@@ -259,34 +271,24 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
259
271
|
// LEFT JOIN: 서브쿼리 + Alias + 콜백
|
|
260
272
|
leftJoin<TJoinAlias extends string, TSubResult>(
|
|
261
273
|
tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
|
|
262
|
-
callback: (
|
|
263
|
-
j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>
|
|
264
|
-
) => void
|
|
274
|
+
callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>) => void,
|
|
265
275
|
): Puri<TSchema, TTables & Record<TJoinAlias, TSubResult>, TResult>;
|
|
266
276
|
// LEFT JOIN: 테이블 + Alias + 콜백
|
|
267
277
|
leftJoin<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
|
|
268
278
|
tableSpec: { [K in TJoinAlias]: TJoinTable },
|
|
269
|
-
callback: (
|
|
270
|
-
j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>
|
|
271
|
-
) => void
|
|
279
|
+
callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>) => void,
|
|
272
280
|
): Puri<TSchema, TTables & Record<TJoinAlias, TSchema[TJoinTable]>, TResult>;
|
|
273
281
|
// LEFT JOIN: 테이블명 + 콜백
|
|
274
282
|
leftJoin<TJoinTable extends keyof TSchema>(
|
|
275
283
|
tableName: TJoinTable,
|
|
276
|
-
callback: (
|
|
277
|
-
j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>
|
|
278
|
-
) => void
|
|
284
|
+
callback: (j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>) => void,
|
|
279
285
|
): Puri<TSchema, TTables & Record<TJoinTable, TSchema[TJoinTable]>, TResult>;
|
|
280
286
|
// LEFT JOIN 실제 구현
|
|
281
287
|
leftJoin(tableNameOrSpec: any, ...args: any[]): any {
|
|
282
288
|
return this.__commonJoin("leftJoin", tableNameOrSpec, ...args);
|
|
283
289
|
}
|
|
284
290
|
|
|
285
|
-
__commonJoin(
|
|
286
|
-
joinType: "join" | "leftJoin",
|
|
287
|
-
tableNameOrSpec: any,
|
|
288
|
-
...args: any[]
|
|
289
|
-
): this {
|
|
291
|
+
__commonJoin(joinType: "join" | "leftJoin", tableNameOrSpec: any, ...args: any[]): this {
|
|
290
292
|
if (typeof tableNameOrSpec === "string") {
|
|
291
293
|
// Case 1: join("posts", ...)
|
|
292
294
|
const tableName = tableNameOrSpec;
|
|
@@ -352,25 +354,26 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
352
354
|
// WHERE: 컬럼 - 사용: .where("u.id", 1)
|
|
353
355
|
where<TColumn extends AvailableColumns<TTables>>(
|
|
354
356
|
column: TColumn,
|
|
355
|
-
value: ExtractColumnType<TTables, TColumn & string
|
|
357
|
+
value: ExtractColumnType<TTables, TColumn & string>,
|
|
356
358
|
): this;
|
|
357
359
|
// WHERE: 컬럼 - 사용: .where("u.id", ">", 10)
|
|
358
360
|
where<TColumn extends AvailableColumns<TTables>>(
|
|
359
361
|
column: TColumn,
|
|
360
362
|
operator: ComparisonOperator | "like" | "not like",
|
|
361
|
-
value: ExtractColumnType<TTables, TColumn & string
|
|
363
|
+
value: ExtractColumnType<TTables, TColumn & string>,
|
|
362
364
|
): this;
|
|
363
365
|
// WHERE: 컬럼 - 사용: .where("u.id", "like", "%test%")
|
|
364
|
-
where(columnOrConditions: any, operatorOrValue?: any, value?: any): this {
|
|
366
|
+
where(...args: [columnOrConditions: any, operatorOrValue?: any, value?: any]): this {
|
|
367
|
+
const [columnOrConditions, operatorOrValue, value] = args;
|
|
365
368
|
if (typeof columnOrConditions === "object") {
|
|
366
369
|
this.knexQuery.where(columnOrConditions);
|
|
367
|
-
} else if (
|
|
370
|
+
} else if (typeof value === "undefined") {
|
|
368
371
|
if (operatorOrValue === null) {
|
|
369
372
|
this.knexQuery.whereNull(columnOrConditions);
|
|
370
373
|
return this;
|
|
371
374
|
}
|
|
372
375
|
this.knexQuery.where(columnOrConditions, operatorOrValue);
|
|
373
|
-
} else if (
|
|
376
|
+
} else if (typeof value !== "undefined") {
|
|
374
377
|
if (value === null) {
|
|
375
378
|
if (operatorOrValue === "!=") {
|
|
376
379
|
this.knexQuery.whereNotNull(columnOrConditions);
|
|
@@ -390,7 +393,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
390
393
|
// WHERE IN
|
|
391
394
|
whereIn<TColumn extends AvailableColumns<TTables>>(
|
|
392
395
|
column: TColumn,
|
|
393
|
-
values: ExtractColumnType<TTables, TColumn & string>[]
|
|
396
|
+
values: ExtractColumnType<TTables, TColumn & string>[],
|
|
394
397
|
): Puri<TSchema, TTables, TResult> {
|
|
395
398
|
this.knexQuery.whereIn(column, values);
|
|
396
399
|
return this as any;
|
|
@@ -399,17 +402,14 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
399
402
|
// WHERE NOT IN
|
|
400
403
|
whereNotIn<TColumn extends AvailableColumns<TTables>>(
|
|
401
404
|
column: TColumn,
|
|
402
|
-
values: ExtractColumnType<TTables, TColumn & string>[]
|
|
405
|
+
values: ExtractColumnType<TTables, TColumn & string>[],
|
|
403
406
|
): Puri<TSchema, TTables, TResult> {
|
|
404
|
-
this.knexQuery.
|
|
407
|
+
this.knexQuery.whereNotIn(column, values);
|
|
405
408
|
return this as any;
|
|
406
409
|
}
|
|
407
410
|
|
|
408
411
|
// WHERE MATCH
|
|
409
|
-
whereMatch<TColumn extends FulltextColumns<TTables>>(
|
|
410
|
-
column: TColumn,
|
|
411
|
-
value: string
|
|
412
|
-
): this {
|
|
412
|
+
whereMatch<TColumn extends FulltextColumns<TTables>>(column: TColumn, value: string): this {
|
|
413
413
|
this.knexQuery.whereRaw(`MATCH (${String(column)}) AGAINST (?)`, [value]);
|
|
414
414
|
return this;
|
|
415
415
|
}
|
|
@@ -433,7 +433,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
433
433
|
// ORDER BY
|
|
434
434
|
orderBy<TColumn extends ResultAvailableColumns<TTables, TResult>>(
|
|
435
435
|
column: TColumn,
|
|
436
|
-
direction: "asc" | "desc"
|
|
436
|
+
direction: "asc" | "desc",
|
|
437
437
|
): this;
|
|
438
438
|
orderBy(column: string, direction: "asc" | "desc" = "asc"): this {
|
|
439
439
|
this.knexQuery.orderBy(column, direction);
|
|
@@ -452,9 +452,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
// GROUP BY
|
|
455
|
-
groupBy<TColumns extends ResultAvailableColumns<TTables, TResult>>(
|
|
456
|
-
...columns: TColumns[]
|
|
457
|
-
): this;
|
|
455
|
+
groupBy<TColumns extends ResultAvailableColumns<TTables, TResult>>(...columns: TColumns[]): this;
|
|
458
456
|
groupBy(...columns: string[]): this {
|
|
459
457
|
this.knexQuery.groupBy(...(columns as string[]));
|
|
460
458
|
return this;
|
|
@@ -465,16 +463,20 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
465
463
|
having<TColumn extends ResultAvailableColumns<TTables, TResult>>(
|
|
466
464
|
column: TColumn,
|
|
467
465
|
operator: ComparisonOperator,
|
|
468
|
-
value: any
|
|
466
|
+
value: any,
|
|
469
467
|
): this;
|
|
470
468
|
// HAVING 구현
|
|
471
469
|
having(...conditions: any[]): this {
|
|
472
470
|
if (conditions.length === 1) {
|
|
473
471
|
// having("COUNT(*) > 10")
|
|
474
|
-
this.knexQuery.having(conditions[0]);
|
|
472
|
+
this.knexQuery.having(this.knex.raw(conditions[0]));
|
|
475
473
|
} else if (conditions.length === 3) {
|
|
476
474
|
// having("count", ">", 10)
|
|
477
|
-
this.knexQuery.having(
|
|
475
|
+
this.knexQuery.having(
|
|
476
|
+
this.knex.raw(conditions[0]),
|
|
477
|
+
conditions[1],
|
|
478
|
+
this.knex.raw(conditions[2]),
|
|
479
|
+
);
|
|
478
480
|
} else {
|
|
479
481
|
throw new Error("Invalid having arguments");
|
|
480
482
|
}
|
|
@@ -483,16 +485,14 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
483
485
|
|
|
484
486
|
// 실행 메서드들 - thenable 구현
|
|
485
487
|
then<TResult1 = Expand<TResult>[], TResult2 = never>(
|
|
486
|
-
onfulfilled?:
|
|
487
|
-
|
|
488
|
-
| null,
|
|
489
|
-
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
|
488
|
+
onfulfilled?: ((value: Expand<TResult>[]) => TResult1 | PromiseLike<TResult1>) | null,
|
|
489
|
+
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
|
|
490
490
|
): Promise<TResult1 | TResult2> {
|
|
491
|
-
Naite.t("puri-query", this.toQuery());
|
|
491
|
+
Naite.t("puri:executed-query", this.toQuery());
|
|
492
492
|
return this.knexQuery.then(onfulfilled as any, onrejected);
|
|
493
493
|
}
|
|
494
494
|
catch<TResult2 = never>(
|
|
495
|
-
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
|
495
|
+
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
|
|
496
496
|
): Promise<TResult | TResult2> {
|
|
497
497
|
return this.knexQuery.catch(onrejected);
|
|
498
498
|
}
|
|
@@ -503,14 +503,12 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
503
503
|
// 하나만 쿼리
|
|
504
504
|
first(): ResolvedPuri<Expand<TResult>, never> {
|
|
505
505
|
this.knexQuery.first();
|
|
506
|
-
return new ResolvedPuri(this.knexQuery);
|
|
506
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
507
507
|
}
|
|
508
508
|
|
|
509
509
|
// 쿼리한 레코드에서 특정 컬럼만 추출한 배열 리턴
|
|
510
|
-
pluck<
|
|
511
|
-
TColumn
|
|
512
|
-
>(
|
|
513
|
-
column: TColumn
|
|
510
|
+
pluck<TColumn extends keyof TResult | ResultAvailableColumns<TTables, TResult>>(
|
|
511
|
+
column: TColumn,
|
|
514
512
|
): ResolvedPuri<
|
|
515
513
|
TColumn extends keyof TResult
|
|
516
514
|
? TResult[TColumn][]
|
|
@@ -518,50 +516,50 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
518
516
|
never
|
|
519
517
|
> {
|
|
520
518
|
this.knexQuery.pluck(column as string);
|
|
521
|
-
return new ResolvedPuri(this.knexQuery);
|
|
519
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
522
520
|
}
|
|
523
521
|
|
|
524
522
|
// INSERT
|
|
525
523
|
insert(
|
|
526
|
-
data: InsertData<SingleTableValue<TTables
|
|
527
|
-
): ResolvedPuri<
|
|
524
|
+
data: InsertData<SingleTableValue<TTables>>,
|
|
525
|
+
): ResolvedPuri<InsertResult, SingleTableValue<TTables>> {
|
|
528
526
|
this.knexQuery.insert(data);
|
|
529
|
-
return new ResolvedPuri(this.knexQuery);
|
|
527
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
530
528
|
}
|
|
531
529
|
|
|
532
530
|
// UPDATE
|
|
533
|
-
update(data: WhereCondition<TTables>): ResolvedPuri<
|
|
531
|
+
update(data: WhereCondition<TTables>): ResolvedPuri<number, SingleTableValue<TTables>> {
|
|
534
532
|
this.knexQuery.update(data);
|
|
535
|
-
return new ResolvedPuri(this.knexQuery);
|
|
533
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
536
534
|
}
|
|
537
535
|
|
|
538
536
|
// Increment
|
|
539
537
|
increment<TColumn extends AvailableColumns<TTables>>(
|
|
540
538
|
column: TColumn,
|
|
541
|
-
value: number
|
|
542
|
-
): ResolvedPuri<number,
|
|
539
|
+
value: number,
|
|
540
|
+
): ResolvedPuri<number, SingleTableValue<TTables>> {
|
|
543
541
|
if (value <= 0) {
|
|
544
542
|
throw new Error("Increment value must be greater than 0");
|
|
545
543
|
}
|
|
546
544
|
this.knexQuery.increment(column, value);
|
|
547
|
-
return new ResolvedPuri(this.knexQuery);
|
|
545
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
548
546
|
}
|
|
549
547
|
// Decrement
|
|
550
548
|
decrement<TColumn extends AvailableColumns<TTables>>(
|
|
551
549
|
column: TColumn,
|
|
552
|
-
value: number
|
|
553
|
-
): ResolvedPuri<number,
|
|
550
|
+
value: number,
|
|
551
|
+
): ResolvedPuri<number, SingleTableValue<TTables>> {
|
|
554
552
|
if (value <= 0) {
|
|
555
553
|
throw new Error("Decrement value must be greater than 0");
|
|
556
554
|
}
|
|
557
555
|
this.knexQuery.decrement(column, value);
|
|
558
|
-
return new ResolvedPuri(this.knexQuery);
|
|
556
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
559
557
|
}
|
|
560
558
|
|
|
561
559
|
// DELETE
|
|
562
|
-
delete(): ResolvedPuri<number,
|
|
560
|
+
delete(): ResolvedPuri<number, SingleTableValue<TTables>> {
|
|
563
561
|
this.knexQuery.delete();
|
|
564
|
-
return new ResolvedPuri(this.knexQuery);
|
|
562
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
565
563
|
}
|
|
566
564
|
|
|
567
565
|
// 확인 쿼리 리턴
|
|
@@ -571,12 +569,17 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
571
569
|
|
|
572
570
|
// 쿼리 디버깅 로그 출력
|
|
573
571
|
debug(): this {
|
|
574
|
-
console.log(
|
|
575
|
-
`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`
|
|
576
|
-
);
|
|
572
|
+
console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
|
|
577
573
|
return this;
|
|
578
574
|
}
|
|
579
575
|
|
|
576
|
+
clone(): Puri<TSchema, TTables, TResult> {
|
|
577
|
+
// 'dual'은 더미 테이블이며, 바로 아래 줄에서 knexQuery가 덮어씌워집니다.
|
|
578
|
+
const newPuri = new Puri<TSchema, TTables, TResult>(this.knex, "dual");
|
|
579
|
+
newPuri.knexQuery = this.knexQuery.clone();
|
|
580
|
+
return newPuri;
|
|
581
|
+
}
|
|
582
|
+
|
|
580
583
|
formatSQL(unformatted: string): string {
|
|
581
584
|
// SQL 예약어 목록
|
|
582
585
|
const keywords = [
|
|
@@ -650,10 +653,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
650
653
|
});
|
|
651
654
|
|
|
652
655
|
// JOIN 절 처리
|
|
653
|
-
formatted = formatted.replace(
|
|
654
|
-
/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi,
|
|
655
|
-
"\n$1JOIN "
|
|
656
|
-
);
|
|
656
|
+
formatted = formatted.replace(/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi, "\n$1JOIN ");
|
|
657
657
|
|
|
658
658
|
// AND, OR 조건 처리
|
|
659
659
|
formatted = formatted.replace(/\s+(AND|OR)\s+/gi, "\n $1 ");
|
|
@@ -663,7 +663,7 @@ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
|
|
|
663
663
|
const indentedLines = [];
|
|
664
664
|
let indentLevel = 0;
|
|
665
665
|
|
|
666
|
-
for (
|
|
666
|
+
for (const line of lines) {
|
|
667
667
|
const trimmedLine = line.trim();
|
|
668
668
|
if (!trimmedLine) continue;
|
|
669
669
|
|
|
@@ -701,12 +701,12 @@ export class WhereGroup<TTables extends Record<string, any>> {
|
|
|
701
701
|
where(conditions: WhereCondition<TTables>): this;
|
|
702
702
|
where<TColumn extends AvailableColumns<TTables>>(
|
|
703
703
|
column: TColumn,
|
|
704
|
-
value: ExtractColumnType<TTables, TColumn & string
|
|
704
|
+
value: ExtractColumnType<TTables, TColumn & string>,
|
|
705
705
|
): this;
|
|
706
706
|
where<TColumn extends AvailableColumns<TTables>>(
|
|
707
707
|
column: TColumn,
|
|
708
708
|
operator: ComparisonOperator,
|
|
709
|
-
value: ExtractColumnType<TTables, TColumn & string
|
|
709
|
+
value: ExtractColumnType<TTables, TColumn & string>,
|
|
710
710
|
): this;
|
|
711
711
|
where(...args: any[]): WhereGroup<TTables> {
|
|
712
712
|
this.builder.where(args[0], ...args.slice(1));
|
|
@@ -717,12 +717,12 @@ export class WhereGroup<TTables extends Record<string, any>> {
|
|
|
717
717
|
orWhere(conditions: WhereCondition<TTables>): this;
|
|
718
718
|
orWhere<TColumn extends AvailableColumns<TTables>>(
|
|
719
719
|
column: TColumn,
|
|
720
|
-
value: ExtractColumnType<TTables, TColumn & string
|
|
720
|
+
value: ExtractColumnType<TTables, TColumn & string>,
|
|
721
721
|
): this;
|
|
722
722
|
orWhere<TColumn extends AvailableColumns<TTables>>(
|
|
723
723
|
column: TColumn,
|
|
724
724
|
operator: ComparisonOperator,
|
|
725
|
-
value: ExtractColumnType<TTables, TColumn & string
|
|
725
|
+
value: ExtractColumnType<TTables, TColumn & string>,
|
|
726
726
|
): this;
|
|
727
727
|
orWhere(...args: any[]): WhereGroup<TTables> {
|
|
728
728
|
this.builder.orWhere(args[0], ...args.slice(1));
|
|
@@ -739,9 +739,7 @@ export class WhereGroup<TTables extends Record<string, any>> {
|
|
|
739
739
|
return this;
|
|
740
740
|
}
|
|
741
741
|
orWhereGroup(callback: (g: WhereGroup<TTables>) => void): this;
|
|
742
|
-
orWhereGroup(
|
|
743
|
-
callback: (g: WhereGroup<TTables>) => void
|
|
744
|
-
): WhereGroup<TTables> {
|
|
742
|
+
orWhereGroup(callback: (g: WhereGroup<TTables>) => void): WhereGroup<TTables> {
|
|
745
743
|
this.builder.orWhere((subBuilder) => {
|
|
746
744
|
const subGroup = new WhereGroup<TTables>(subBuilder);
|
|
747
745
|
callback(subGroup);
|
|
@@ -762,7 +760,7 @@ export class JoinClauseGroup<
|
|
|
762
760
|
on(
|
|
763
761
|
left: AvailableColumns<TLeft>,
|
|
764
762
|
operator: ComparisonOperator,
|
|
765
|
-
right: AvailableColumns<TRight
|
|
763
|
+
right: AvailableColumns<TRight>,
|
|
766
764
|
): this;
|
|
767
765
|
// ON(AND): 콜백
|
|
768
766
|
on(callback: (nested: JoinClauseGroup<TLeft, TRight>) => void): this;
|
|
@@ -778,7 +776,7 @@ export class JoinClauseGroup<
|
|
|
778
776
|
orOn(
|
|
779
777
|
left: AvailableColumns<TLeft>,
|
|
780
778
|
operator: ComparisonOperator,
|
|
781
|
-
right: AvailableColumns<TRight
|
|
779
|
+
right: AvailableColumns<TRight>,
|
|
782
780
|
): this;
|
|
783
781
|
// ON(OR): 콜백
|
|
784
782
|
orOn(callback: (nested: JoinClauseGroup<TLeft, TRight>) => void): this;
|
|
@@ -791,37 +789,95 @@ export class JoinClauseGroup<
|
|
|
791
789
|
|
|
792
790
|
/*
|
|
793
791
|
TResolved: 쿼리 실행 후 반환될 결과 타입
|
|
794
|
-
|
|
792
|
+
TReturning: RETURNING 절에 사용될 타입
|
|
795
793
|
*/
|
|
796
|
-
export class ResolvedPuri<TResolved,
|
|
797
|
-
constructor(
|
|
794
|
+
export class ResolvedPuri<TResolved, TReturning> {
|
|
795
|
+
constructor(
|
|
796
|
+
public knexQuery: Knex.QueryBuilder,
|
|
797
|
+
private knex: Knex,
|
|
798
|
+
) {}
|
|
798
799
|
|
|
799
800
|
toQuery(): string {
|
|
800
801
|
return this.knexQuery.toQuery();
|
|
801
802
|
}
|
|
802
803
|
|
|
803
804
|
debug(): this {
|
|
804
|
-
console.log(
|
|
805
|
-
`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`
|
|
806
|
-
);
|
|
805
|
+
console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
|
|
807
806
|
return this;
|
|
808
807
|
}
|
|
809
808
|
|
|
810
809
|
then<TResult1 = TResolved, TResult2 = never>(
|
|
811
|
-
onfulfilled?:
|
|
812
|
-
|
|
813
|
-
| null,
|
|
814
|
-
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
|
810
|
+
onfulfilled?: ((value: TResolved) => TResult1 | PromiseLike<TResult1>) | null,
|
|
811
|
+
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
|
|
815
812
|
): Promise<TResult1 | TResult2> {
|
|
816
|
-
Naite.t("puri-query", this.toQuery());
|
|
813
|
+
Naite.t("puri:executed-query", this.toQuery());
|
|
817
814
|
return this.knexQuery.then(onfulfilled as any, onrejected);
|
|
818
815
|
}
|
|
819
816
|
catch<TResult2 = never>(
|
|
820
|
-
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
|
817
|
+
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
|
|
821
818
|
): Promise<TResolved | TResult2> {
|
|
822
819
|
return this.knexQuery.catch(onrejected);
|
|
823
820
|
}
|
|
824
821
|
finally(onfinally?: (() => void) | null): Promise<TResolved> {
|
|
825
822
|
return this.knexQuery.finally(onfinally);
|
|
826
823
|
}
|
|
824
|
+
|
|
825
|
+
// ON CONFLICT - 컬럼 기반
|
|
826
|
+
onConflict<TTables extends Record<string, TReturning>>(
|
|
827
|
+
columns: string | string[],
|
|
828
|
+
action?: OnConflictAction<TTables>,
|
|
829
|
+
): this {
|
|
830
|
+
const target = Array.isArray(columns) ? columns : [columns];
|
|
831
|
+
|
|
832
|
+
if (!action || action === "nothing") {
|
|
833
|
+
// DO NOTHING
|
|
834
|
+
this.knexQuery.onConflict(target).ignore();
|
|
835
|
+
} else {
|
|
836
|
+
// DO UPDATE
|
|
837
|
+
const { update } = action;
|
|
838
|
+
|
|
839
|
+
// action.update 배열 형태 : ["name", "email"]
|
|
840
|
+
if (Array.isArray(update)) {
|
|
841
|
+
this.knexQuery.onConflict(target).merge(update);
|
|
842
|
+
} else {
|
|
843
|
+
// action.update 객체 형태: { name: "John", count: raw(...) }
|
|
844
|
+
const mergeObj: Record<string, any> = {};
|
|
845
|
+
|
|
846
|
+
for (const [key, value] of Object.entries(update)) {
|
|
847
|
+
if (
|
|
848
|
+
value &&
|
|
849
|
+
typeof value === "object" &&
|
|
850
|
+
"_type" in value &&
|
|
851
|
+
value._type === "sql_expression"
|
|
852
|
+
) {
|
|
853
|
+
// SqlExpression → knex.raw()로 변환
|
|
854
|
+
mergeObj[key] = this.knex.raw((value as SqlExpression<any>)._sql);
|
|
855
|
+
} else {
|
|
856
|
+
// 일반 값
|
|
857
|
+
mergeObj[key] = value;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
this.knexQuery.onConflict(target).merge(mergeObj);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
return this;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// RETURNING: "*" - 전체 컬럼
|
|
869
|
+
returning(column: "*"): ResolvedPuri<TReturning[], never>;
|
|
870
|
+
// RETURNING: 단일 컬럼
|
|
871
|
+
returning<TColumn extends ColumnKeys<TReturning>>(
|
|
872
|
+
column: TColumn,
|
|
873
|
+
): ResolvedPuri<Pick<TReturning, TColumn>[], never>;
|
|
874
|
+
// RETURNING: 복수 컬럼 (배열)
|
|
875
|
+
returning<TColumn extends ColumnKeys<TReturning>>(
|
|
876
|
+
columns: TColumn[],
|
|
877
|
+
): ResolvedPuri<Pick<TReturning, TColumn>[], never>;
|
|
878
|
+
// RETURNING 구현
|
|
879
|
+
returning(columnOrColumns: string | string[]): ResolvedPuri<any[], never> {
|
|
880
|
+
this.knexQuery.returning(columnOrColumns);
|
|
881
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
882
|
+
}
|
|
827
883
|
}
|