sonamu 0.5.7 → 0.6.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/dist/api/base-frame.js +12 -2
- package/dist/api/caster.js +66 -2
- package/dist/api/code-converters.js +489 -2
- package/dist/api/config.d.ts +76 -0
- package/dist/api/config.d.ts.map +1 -0
- package/dist/api/config.js +32 -0
- package/dist/api/context.d.ts +1 -0
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +3 -2
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +142 -2
- package/dist/api/index.js +9 -2
- package/dist/api/sonamu.d.ts +8 -22
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +482 -2
- package/dist/bin/build-config.d.ts +2 -1
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +12 -2
- package/dist/bin/cli-wrapper.js +71 -2
- package/dist/bin/cli.js +418 -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/database/_batch_update.js +78 -2
- package/dist/database/base-model.js +247 -2
- package/dist/database/code-generator.js +53 -2
- package/dist/database/db.d.ts +2 -16
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +132 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +39 -2
- package/dist/database/puri-wrapper.js +109 -2
- package/dist/database/puri.d.ts +23 -16
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +539 -2
- package/dist/database/puri.types.d.ts +8 -3
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +3 -2
- package/dist/database/transaction-context.js +14 -2
- package/dist/database/upsert-builder.js +215 -2
- package/dist/entity/entity-manager.d.ts +3 -1
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +114 -2
- package/dist/entity/entity-utils.js +210 -2
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +651 -2
- package/dist/exceptions/error-handler.js +29 -2
- package/dist/exceptions/so-exceptions.js +85 -2
- package/dist/file-storage/driver.js +79 -2
- package/dist/file-storage/file-storage.js +75 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -2
- package/dist/migration/code-generation.js +558 -2
- package/dist/migration/migration-set.js +364 -2
- package/dist/migration/migrator.d.ts +0 -9
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +510 -2
- package/dist/migration/types.js +3 -2
- package/dist/naite/naite.d.ts +12 -0
- package/dist/naite/naite.d.ts.map +1 -0
- package/dist/naite/naite.js +72 -0
- package/dist/stream/index.js +3 -2
- package/dist/stream/sse.js +38 -2
- package/dist/syncer/api-parser.d.ts +20 -0
- package/dist/syncer/api-parser.d.ts.map +1 -0
- package/dist/syncer/api-parser.js +229 -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 +141 -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 +58 -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 +82 -0
- package/dist/syncer/syncer.d.ts +93 -108
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +375 -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 +101 -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 +87 -0
- package/dist/{templates → template/implementations}/generated.template.d.ts +3 -3
- package/dist/template/implementations/generated.template.d.ts.map +1 -0
- package/dist/template/implementations/generated.template.js +232 -0
- package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -3
- 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 +3 -3
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
- package/dist/template/implementations/generated_sso.template.js +105 -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 +171 -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 +193 -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 +465 -0
- package/dist/{templates → template/implementations}/view_list_columns.template.d.ts +3 -3
- 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 +5 -0
- package/dist/template/index.d.ts.map +1 -0
- package/dist/template/index.js +6 -0
- package/dist/template/template.d.ts +39 -0
- package/dist/template/template.d.ts.map +1 -0
- package/dist/template/template.js +47 -0
- package/dist/template/zod-converter.d.ts +18 -0
- package/dist/template/zod-converter.d.ts.map +1 -0
- package/dist/template/zod-converter.js +166 -0
- package/dist/testing/_relation-graph.js +80 -2
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +521 -2
- package/dist/types/types.d.ts +39 -40
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +289 -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.js +26 -2
- package/dist/utils/esm-utils.d.ts +45 -0
- package/dist/utils/esm-utils.d.ts.map +1 -0
- package/dist/utils/esm-utils.js +56 -0
- package/dist/utils/fs-utils.js +17 -2
- package/dist/utils/lodash-able.js +6 -2
- package/dist/utils/model.js +22 -2
- 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.js +35 -2
- package/dist/utils/utils.d.ts +4 -7
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +33 -2
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +19 -2
- package/package.json +21 -8
- package/src/api/code-converters.ts +2 -2
- package/src/api/config.ts +142 -0
- package/src/api/context.ts +1 -0
- package/src/api/decorators.ts +1 -0
- package/src/api/sonamu.ts +81 -67
- package/src/bin/build-config.ts +2 -1
- package/src/bin/cli-wrapper.ts +10 -3
- package/src/bin/cli.ts +108 -56
- package/src/bin/hot-hook-register.ts +22 -0
- package/src/database/base-model.ts +1 -1
- package/src/database/code-generator.ts +1 -1
- package/src/database/db.ts +10 -52
- package/src/database/puri.ts +78 -53
- package/src/database/puri.types.ts +18 -5
- package/src/database/upsert-builder.ts +1 -1
- package/src/entity/entity-manager.ts +19 -15
- package/src/entity/entity.ts +4 -3
- package/src/index.ts +2 -0
- package/src/migration/code-generation.ts +1 -1
- package/src/migration/migration-set.ts +1 -1
- package/src/migration/migrator.ts +23 -152
- package/src/naite/naite.ts +70 -0
- package/src/syncer/api-parser.ts +299 -0
- package/src/syncer/checksum.ts +152 -0
- package/src/syncer/code-generator.ts +202 -0
- package/src/syncer/entity-operations.ts +68 -0
- package/src/syncer/file-patterns.ts +56 -0
- package/src/syncer/index.ts +6 -0
- package/src/syncer/module-loader.ts +125 -0
- package/src/syncer/syncer.ts +363 -1420
- package/src/template/entity-converter.ts +123 -0
- package/src/template/helpers.ts +84 -0
- package/src/{templates → template/implementations}/entity.template.ts +4 -4
- package/src/{templates → template/implementations}/generated.template.ts +9 -9
- package/src/{templates → template/implementations}/generated_http.template.ts +9 -6
- package/src/{templates → template/implementations}/generated_sso.template.ts +7 -7
- package/src/{templates → template/implementations}/init_types.template.ts +4 -4
- package/src/{templates → template/implementations}/model.template.ts +9 -9
- package/src/{templates → template/implementations}/model_test.template.ts +5 -5
- package/src/{templates → template/implementations}/service.template.ts +19 -11
- package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
- package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +5 -21
- package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
- package/src/{templates → template/implementations}/view_form.template.ts +11 -13
- package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
- package/src/{templates → template/implementations}/view_id_async_select.template.ts +3 -3
- package/src/{templates → template/implementations}/view_list.template.ts +13 -64
- package/src/{templates → template/implementations}/view_list_columns.template.ts +3 -3
- package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
- package/src/template/index.ts +4 -0
- package/src/template/template.ts +86 -0
- package/src/template/zod-converter.ts +219 -0
- package/src/testing/fixture-manager.ts +8 -1
- package/src/types/types.ts +38 -61
- package/src/utils/async-utils.ts +17 -0
- package/src/utils/console-util.ts +4 -0
- package/src/utils/esm-utils.ts +69 -0
- package/src/utils/path-utils.ts +102 -0
- package/src/utils/process-utils.ts +46 -0
- package/src/utils/sql-parser.ts +1 -1
- package/src/utils/utils.ts +14 -40
- package/src/utils/zod-error.ts +0 -1
- 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.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.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.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.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/templates/base-template.ts +0 -19
- package/src/templates/index.ts +0 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { setTimeout as setTimeoutPromises } from "timers/promises";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 주어진 작업을 실행합니다.
|
|
6
|
+
* 주어진 프로세스 이벤트(=시그널)가 발생하였을 때에도 최대 한계(delayBeforeShutdown) 동안 작업을 기다린 후 종료합니다.
|
|
7
|
+
* @param {() => Promise<void>} job - 실행할 작업
|
|
8
|
+
* @param {event: NodeJS.Signals; delayBeforeShutdown: number} options - 옵션
|
|
9
|
+
* @param {NodeJS.Signals} options.event - 프로세스 이벤트
|
|
10
|
+
* @param {number} options.delayBeforeShutdown - 최대 한계 시간
|
|
11
|
+
*/
|
|
12
|
+
export async function runWithGracefulShutdown(
|
|
13
|
+
job: () => Promise<void>,
|
|
14
|
+
{
|
|
15
|
+
whenThisHappens: event,
|
|
16
|
+
waitForUpTo: delayBeforeShutdown,
|
|
17
|
+
}: { whenThisHappens: NodeJS.Signals; waitForUpTo: number } = {
|
|
18
|
+
whenThisHappens: "SIGUSR2",
|
|
19
|
+
waitForUpTo: 20000,
|
|
20
|
+
}
|
|
21
|
+
): Promise<void> {
|
|
22
|
+
let isRunning = true as boolean;
|
|
23
|
+
|
|
24
|
+
const abortController = new AbortController();
|
|
25
|
+
const onEvent = async () => {
|
|
26
|
+
if (!isRunning) {
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
console.log(chalk.magentaBright(`wait for syncing done....`));
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await setTimeoutPromises(delayBeforeShutdown, "waiting-sync", {
|
|
33
|
+
signal: abortController.signal,
|
|
34
|
+
});
|
|
35
|
+
} catch {}
|
|
36
|
+
console.log(chalk.magentaBright(`Syncing DONE!`));
|
|
37
|
+
process.exit(0);
|
|
38
|
+
};
|
|
39
|
+
process.on(event, onEvent);
|
|
40
|
+
|
|
41
|
+
await job();
|
|
42
|
+
|
|
43
|
+
isRunning = false;
|
|
44
|
+
abortController.abort();
|
|
45
|
+
process.off(event, onEvent);
|
|
46
|
+
}
|
package/src/utils/sql-parser.ts
CHANGED
package/src/utils/utils.ts
CHANGED
|
@@ -1,60 +1,30 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import { glob } from "fs/promises";
|
|
3
2
|
import fs from "fs";
|
|
3
|
+
import { AbsolutePath } from "./path-utils";
|
|
4
4
|
|
|
5
|
-
export async function
|
|
6
|
-
const files: string[] = [];
|
|
7
|
-
for await (const file of glob(path.resolve(pathPattern))) {
|
|
8
|
-
files.push(file);
|
|
9
|
-
}
|
|
10
|
-
return files;
|
|
11
|
-
}
|
|
12
|
-
export async function importMultiple(
|
|
13
|
-
filePaths: string[],
|
|
14
|
-
doRefresh: boolean = false
|
|
15
|
-
): Promise<{ filePath: string; imported: any }[]> {
|
|
16
|
-
const results: { filePath: string; imported: any }[] = [];
|
|
17
|
-
|
|
18
|
-
for (const filePath of filePaths) {
|
|
19
|
-
let importPath = "./" + path.relative(__dirname, filePath);
|
|
20
|
-
|
|
21
|
-
if (doRefresh) {
|
|
22
|
-
if (require.resolve) {
|
|
23
|
-
delete require.cache[require.resolve(importPath)];
|
|
24
|
-
} else {
|
|
25
|
-
importPath += `?t=${Date.now()}`;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const imported = await import(importPath);
|
|
30
|
-
results.push({
|
|
31
|
-
filePath,
|
|
32
|
-
imported,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return results;
|
|
37
|
-
}
|
|
38
|
-
export async function findAppRootPath() {
|
|
5
|
+
export async function findAppRootPath(): Promise<AbsolutePath> {
|
|
39
6
|
const apiRootPath = findApiRootPath();
|
|
40
|
-
return apiRootPath
|
|
7
|
+
return apiRootPath
|
|
8
|
+
.split(path.sep)
|
|
9
|
+
.slice(0, -1)
|
|
10
|
+
.join(path.sep) as AbsolutePath;
|
|
41
11
|
}
|
|
42
12
|
|
|
43
|
-
export function findApiRootPath() {
|
|
13
|
+
export function findApiRootPath(): AbsolutePath {
|
|
44
14
|
// NOTE: for support npm / yarn workspaces
|
|
45
15
|
const workspacePath = process.env["INIT_CWD"];
|
|
46
16
|
if (workspacePath && workspacePath.length !== 0) {
|
|
47
|
-
return workspacePath;
|
|
17
|
+
return workspacePath as AbsolutePath;
|
|
48
18
|
}
|
|
49
19
|
|
|
50
|
-
const basePath =
|
|
20
|
+
const basePath = import.meta.filename;
|
|
51
21
|
let dir = path.dirname(basePath);
|
|
52
22
|
if (dir.includes("/.yarn/")) {
|
|
53
23
|
dir = dir.split("/.yarn/")[0];
|
|
54
24
|
}
|
|
55
25
|
do {
|
|
56
26
|
if (fs.existsSync(path.join(dir, "/package.json"))) {
|
|
57
|
-
return dir.split(path.sep).join(path.sep);
|
|
27
|
+
return dir.split(path.sep).join(path.sep) as AbsolutePath;
|
|
58
28
|
}
|
|
59
29
|
dir = dir.split(path.sep).slice(0, -1).join(path.sep);
|
|
60
30
|
} while (dir.split(path.sep).length > 1);
|
|
@@ -64,3 +34,7 @@ export function findApiRootPath() {
|
|
|
64
34
|
export function nonNullable<T>(value: T): value is NonNullable<T> {
|
|
65
35
|
return value !== null && value !== undefined;
|
|
66
36
|
}
|
|
37
|
+
|
|
38
|
+
export function exhaustive(_param: never) {
|
|
39
|
+
throw new Error(`exhaustive`);
|
|
40
|
+
}
|
package/src/utils/zod-error.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/base-frame.ts"],"sourcesContent":["import { Knex } from \"knex\";\nimport { DB, DBPreset } from \"../database/db\";\nimport { UpsertBuilder } from \"../database/upsert-builder\";\n\nexport abstract class BaseFrameClass {\n getDB(which: DBPreset): Knex {\n return DB.getDB(which);\n }\n\n getUpsertBuilder() {\n return new UpsertBuilder();\n }\n}\n"],"names":["BaseFrameClass","getDB","which","DB","getUpsertBuilder","UpsertBuilder"],"mappings":"oGAIsBA,wDAAAA,kCAHO,6CACC,qpBAEvB,IAAA,AAAeA,4BAAf,iCAAeA,wCAAAA,8BAAAA,iBACpBC,IAAAA,cAAAA,SAAAA,MAAMC,KAAe,EACnB,OAAOC,MAAE,CAACF,KAAK,CAACC,MAClB,IAEAE,IAAAA,yBAAAA,SAAAA,mBACE,OAAO,IAAIC,4BAAa,AAC1B,YAPoBL"}
|
package/dist/api/caster.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/caster.ts"],"sourcesContent":["import assert from \"assert\";\nimport { z } from \"zod\";\nimport type { $ZodType } from \"zod/v4/core\";\n\nfunction isNumberType(zodType: $ZodType): zodType is z.ZodNumber {\n return zodType instanceof z.ZodNumber;\n}\n\nfunction isNullOrOptional(zodType: $ZodType): zodType is z.ZodNullable | z.ZodOptional {\n return zodType instanceof z.ZodNullable || zodType instanceof z.ZodOptional;\n}\n\n// optional, nullable 무관하게 ZodNumber 체크\nfunction isZodNumberAnyway(zodType: $ZodType) {\n if (isNumberType(zodType)) {\n return true;\n }\n\n // ZodNullable 또는 ZodOptional일 때\n if (isNullOrOptional(zodType) && isNumberType(zodType.def.innerType)) {\n return true;\n }\n\n return false;\n}\n\n// ZodType을 이용해 raw를 Type Coercing\nexport function caster(zodType: $ZodType, raw: any): any {\n if (isZodNumberAnyway(zodType) && typeof raw === \"string\") {\n // number\n return Number(raw);\n } else if (\n zodType instanceof z.ZodUnion &&\n zodType.options.some((opt) => isZodNumberAnyway(opt))\n ) {\n // zArrayable Number 케이스 처리\n if (Array.isArray(raw)) {\n const numType = zodType.options.find(opt => isNumberType(opt));\n assert(numType !== undefined);\n return raw.map((elem: any) => caster(numType, elem));\n } else {\n return Number(raw);\n }\n } else if (\n zodType instanceof z.ZodBoolean &&\n (raw === \"true\" || raw === \"false\")\n ) {\n // boolean\n return raw === \"true\";\n } else if (\n raw !== null &&\n Array.isArray(raw) &&\n zodType instanceof z.ZodArray\n ) {\n // array\n return raw.map((elem: any) => caster(zodType.element, elem));\n } else if (\n zodType instanceof z.ZodObject &&\n typeof raw === \"object\" &&\n raw !== null\n ) {\n // object\n return Object.keys(raw).reduce((r, rawKey) => {\n r[rawKey] = caster(zodType.shape[rawKey], raw[rawKey]);\n return r;\n }, {} as any);\n } else if (zodType instanceof z.ZodOptional) {\n // optional\n return caster(zodType.def.innerType, raw);\n } else if (zodType instanceof z.ZodNullable) {\n // nullable\n return caster(zodType.def.innerType, raw);\n } else if (\n zodType instanceof z.ZodDate &&\n new Date(raw).toString() !== \"Invalid Date\"\n ) {\n // date\n return new Date(raw);\n } else {\n // 나머지는 처리 안함\n return raw;\n }\n}\n\nexport function fastifyCaster(schema: z.ZodObject<any>) {\n return z.preprocess((raw: any) => {\n return caster(schema, raw);\n }, schema);\n}\n"],"names":["caster","fastifyCaster","isNumberType","zodType","z","ZodNumber","isNullOrOptional","ZodNullable","ZodOptional","isZodNumberAnyway","def","innerType","raw","Number","ZodUnion","options","some","opt","Array","isArray","numType","find","assert","undefined","map","elem","ZodBoolean","ZodArray","element","ZodObject","Object","keys","reduce","r","rawKey","shape","ZodDate","Date","toString","schema","preprocess"],"mappings":"mPA2BgBA,gBAAAA,YAyDAC,uBAAAA,2EApFG,4BACD,oZAGlB,SAASC,aAAaC,OAAiB,EACrC,OAAOA,AAAO,YAAPA,QAAmBC,MAAC,CAACC,SAAS,CACvC,CAEA,SAASC,iBAAiBH,OAAiB,EACzC,OAAOA,AAAO,YAAPA,QAAmBC,MAAC,CAACG,WAAW,GAAIJ,AAAO,YAAPA,QAAmBC,MAAC,CAACI,WAAW,CAC7E,CAGA,SAASC,kBAAkBN,OAAiB,EAC1C,GAAID,aAAaC,SAAU,CACzB,OAAO,IACT,CAGA,GAAIG,iBAAiBH,UAAYD,aAAaC,QAAQO,GAAG,CAACC,SAAS,EAAG,CACpE,OAAO,IACT,CAEA,OAAO,KACT,CAGO,SAASX,OAAOG,OAAiB,CAAES,GAAQ,EAChD,GAAIH,kBAAkBN,UAAY,OAAOS,MAAQ,SAAU,CAEzD,OAAOC,OAAOD,IAChB,MAAO,GACLT,AAAO,YAAPA,QAAmBC,MAAC,CAACU,QAAQ,GAC7BX,QAAQY,OAAO,CAACC,IAAI,CAAC,SAACC,YAAQR,kBAAkBQ,OAChD,CAEA,GAAIC,MAAMC,OAAO,CAACP,KAAM,CACtB,IAAMQ,QAAUjB,QAAQY,OAAO,CAACM,IAAI,CAACJ,SAAAA,YAAOf,aAAae,OACzDK,GAAAA,eAAM,EAACF,UAAYG,WACnB,OAAOX,IAAIY,GAAG,CAAC,SAACC,aAAczB,OAAOoB,QAASK,OAChD,KAAO,CACL,OAAOZ,OAAOD,IAChB,CACF,MAAO,GACLT,AAAO,YAAPA,QAAmBC,MAAC,CAACsB,UAAU,GAC9Bd,CAAAA,MAAQ,QAAUA,MAAQ,OAAM,EACjC,CAEA,OAAOA,MAAQ,MACjB,MAAO,GACLA,MAAQ,MACRM,MAAMC,OAAO,CAACP,MACdT,AAAO,YAAPA,QAAmBC,MAAC,CAACuB,QAAQ,EAC7B,CAEA,OAAOf,IAAIY,GAAG,CAAC,SAACC,aAAczB,OAAOG,QAAQyB,OAAO,CAAEH,OACxD,MAAO,GACLtB,AAAO,YAAPA,QAAmBC,MAAC,CAACyB,SAAS,GAC9B,CAAA,OAAOjB,8BAAP,SAAOA,IAAE,IAAM,UACfA,MAAQ,KACR,CAEA,OAAOkB,OAAOC,IAAI,CAACnB,KAAKoB,MAAM,CAAC,SAACC,EAAGC,QACjCD,CAAC,CAACC,OAAO,CAAGlC,OAAOG,QAAQgC,KAAK,CAACD,OAAO,CAAEtB,GAAG,CAACsB,OAAO,EACrD,OAAOD,CACT,EAAG,CAAC,EACN,MAAO,GAAI9B,AAAO,YAAPA,QAAmBC,MAAC,CAACI,WAAW,EAAE,CAE3C,OAAOR,OAAOG,QAAQO,GAAG,CAACC,SAAS,CAAEC,IACvC,MAAO,GAAIT,AAAO,YAAPA,QAAmBC,MAAC,CAACG,WAAW,EAAE,CAE3C,OAAOP,OAAOG,QAAQO,GAAG,CAACC,SAAS,CAAEC,IACvC,MAAO,GACLT,AAAO,YAAPA,QAAmBC,MAAC,CAACgC,OAAO,GAC5B,IAAIC,KAAKzB,KAAK0B,QAAQ,KAAO,eAC7B,CAEA,OAAO,IAAID,KAAKzB,IAClB,KAAO,CAEL,OAAOA,GACT,CACF,CAEO,SAASX,cAAcsC,MAAwB,EACpD,OAAOnC,MAAC,CAACoC,UAAU,CAAC,SAAC5B,KACnB,OAAOZ,OAAOuC,OAAQ3B,IACxB,EAAG2B,OACL"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/code-converters.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { $ZodLooseShape } from \"zod/v4/core\"\nimport {\n ApiParam,\n ApiParamType,\n EntityProp,\n EntityPropNode,\n TextProp,\n isBelongsToOneRelationProp,\n isBigIntegerProp,\n isBooleanProp,\n isDateProp,\n isDateTimeProp,\n isDecimalProp,\n isDoubleProp,\n isEnumProp,\n isFloatProp,\n isIntegerProp,\n isJsonProp,\n isOneToOneRelationProp,\n isRelationProp,\n isStringProp,\n isTextProp,\n isTimeProp,\n isTimestampProp,\n isUuidProp,\n isVirtualProp,\n} from \"../types/types\";\nimport { ExtendedApi } from \"./decorators\";\nimport type { Literal } from \"zod/v4/core/util\";\n\n// <any>를 자제하고, Zod에서 제약하는 기본적인 Generic Type Parameter를 사용함.\ntype AnyZodRecord = z.ZodRecord<z.ZodString | z.ZodNumber | z.ZodSymbol, z.ZodType>;\ntype AnyZodObject = z.ZodObject<$ZodLooseShape>;\ntype AnyZodArray = z.ZodArray<z.ZodType>;\ntype AnyZodNullable = z.ZodNullable<z.ZodType>;\ntype AnyZodOptional = z.ZodOptional<z.ZodType>;\ntype AnyZodDefault = z.ZodDefault<z.ZodType>;\ntype AnyZodLiteral = z.ZodLiteral<Literal>;\ntype AnyZodUnion = z.ZodUnion<z.ZodType[]>;\n\n/*\n ExtendedApi 에서 ZodObject 리턴\n*/\nexport function getZodObjectFromApi(\n api: ExtendedApi,\n references: {\n [id: string]: AnyZodObject;\n } = {}\n) {\n if (api.typeParameters?.length > 0) {\n api.typeParameters.map((typeParam) => {\n if (typeParam.constraint) {\n let zodType = getZodTypeFromApiParamType(\n typeParam.constraint,\n references\n );\n (references[typeParam.id] as any) = zodType;\n }\n });\n }\n\n const ReqType = getZodObjectFromApiParams(\n api.parameters.filter(\n (param) =>\n !ApiParamType.isContext(param.type) &&\n !ApiParamType.isRefKnex(param.type) &&\n !(param.optional === true && param.name.startsWith(\"_\")) // _로 시작하는 파라미터는 제외\n ),\n references\n );\n return ReqType;\n}\n\n/*\n ZodObject를 통해 ApiParam 리턴\n*/\nexport function getZodObjectFromApiParams(\n apiParams: ApiParam[],\n references: {\n [id: string]: AnyZodObject;\n } = {}\n): z.ZodObject {\n return z.object(\n apiParams.reduce((r, param) => {\n let zodType = getZodTypeFromApiParamType(param.type, references);\n if (param.optional) {\n zodType = zodType.optional();\n }\n return {\n ...r,\n [param.name]: zodType,\n };\n }, {})\n );\n}\n\n/*\n ApiParamType으로 ZodType 컨버팅\n*/\nexport function getZodTypeFromApiParamType(\n paramType: ApiParamType,\n references: {\n [id: string]: AnyZodObject;\n }\n): z.ZodType<unknown> {\n switch (paramType) {\n case \"string\":\n return z.string();\n case \"number\":\n return z.number();\n case \"boolean\":\n return z.boolean();\n default:\n const advType = paramType as { t: string };\n switch (advType.t) {\n case \"string-literal\":\n case \"numeric-literal\":\n return z.literal((advType as any).value);\n case \"object\":\n const objType = paramType as { t: string; props: ApiParam[] };\n return getZodObjectFromApiParams(objType.props);\n case \"array\":\n const arrType = paramType as {\n t: string;\n elementsType: ApiParamType;\n };\n return z.array(\n getZodTypeFromApiParamType(arrType.elementsType, references)\n );\n case \"ref\":\n const refType = paramType as {\n t: string;\n id: string;\n args?: ApiParamType[];\n };\n\n // Date 타입 처리\n if (refType.id === \"Date\") {\n return z.date();\n }\n\n // 객체 키 관리 유틸리티\n if ([\"Pick\", \"Omit\"].includes(refType.id)) {\n if (refType.args?.length !== 2) {\n throw new Error(`잘못된 ${refType.id}`);\n }\n const [obj, literalOrUnion] = refType.args!.map((arg) =>\n getZodTypeFromApiParamType(arg, references)\n ) as [AnyZodObject, z.ZodUnion<any> | AnyZodLiteral];\n let keys: string[] = [];\n if (literalOrUnion instanceof z.ZodUnion) {\n keys = literalOrUnion.def.options.map(\n (option: { def: { value: string } }) => option.def.value\n );\n } else {\n keys = (literalOrUnion as z.ZodLiteral<string>).def.values;\n }\n const keyRecord = keys.reduce((result, key) => {\n return {\n ...result,\n [key]: true,\n };\n }, {} as any);\n\n if (refType.id === \"Pick\") {\n if (obj.pick) {\n return obj.pick(keyRecord);\n }\n } else {\n if (obj.omit) {\n return obj.omit(keyRecord);\n }\n }\n }\n if ([\"Partial\"].includes(refType.id)) {\n if (refType.args?.length !== 1) {\n throw new Error(`잘못된 ${refType.id}`);\n }\n const obj = getZodTypeFromApiParamType(refType.args[0], references);\n return (obj as any).partial();\n }\n\n const reference = references[refType.id];\n if (reference === undefined) {\n return z.string();\n // throw new Error(`ref 참조 불가 ${refType.id}`);\n }\n return reference;\n case \"union\":\n const unionType = paramType as {\n t: string;\n types: ApiParamType[];\n };\n // nullable 유니온\n if (\n unionType.types.length === 2 &&\n unionType.types.some((type) => type === \"null\")\n ) {\n if (unionType.types[0] === \"null\") {\n return getZodTypeFromApiParamType(\n unionType.types[1],\n references\n ).nullable();\n } else {\n return getZodTypeFromApiParamType(\n unionType.types[0],\n references\n ).nullable();\n }\n }\n\n // 일반 유니온\n return z.union(\n unionType.types.map((type) =>\n getZodTypeFromApiParamType(type, references)\n ) as any\n );\n case \"intersection\":\n const intersectionType = paramType as {\n t: string;\n types: ApiParamType[];\n };\n return intersectionType.types.reduce((result, type, index) => {\n const resolvedType = getZodTypeFromApiParamType(type, references);\n if (index === 0) {\n return resolvedType;\n } else {\n return z.intersection(result as any, resolvedType);\n }\n }, z.unknown() as any) as any;\n case \"tuple-type\":\n const tupleType = paramType as ApiParamType.TupleType;\n return z.tuple(\n tupleType.elements.map((elem) =>\n getZodTypeFromApiParamType(elem, references)\n ) as any\n );\n }\n return z.unknown();\n }\n}\n\nexport function propNodeToZodTypeDef(\n propNode: EntityPropNode,\n injectImportKeys: string[]\n): string {\n if (propNode.nodeType === \"plain\") {\n return propToZodTypeDef(propNode.prop, injectImportKeys);\n } else if (propNode.nodeType === \"array\") {\n return [\n propNode.prop ? `${propNode.prop.name}: ` : \"\",\n \"z.array(z.object({\",\n propNode.children\n .map((childPropNode) =>\n propNodeToZodTypeDef(childPropNode, injectImportKeys)\n )\n .join(\"\\n\"),\n \"\",\n \"})),\",\n ].join(\"\\n\");\n } else if (propNode.nodeType === \"object\") {\n return [\n propNode.prop ? `${propNode.prop.name}: ` : \"\",\n \"z.object({\",\n propNode.children\n .map((childPropNode) =>\n propNodeToZodTypeDef(childPropNode, injectImportKeys)\n )\n .join(\"\\n\"),\n \"\",\n `})${propNode.prop && propNode.prop.nullable ? \".nullable()\" : \"\"},`,\n ].join(\"\\n\");\n } else {\n throw Error;\n }\n}\n\nexport function getTextTypeLength(textType: TextProp[\"textType\"]): number {\n switch (textType) {\n case \"text\":\n return 1024 * 64 - 1;\n case \"mediumtext\":\n return 1024 * 1024 * 16 - 1;\n case \"longtext\":\n return 1024 * 1024 * 1024 * 4 - 1;\n }\n}\n\nexport function propToZodTypeDef(\n prop: EntityProp,\n injectImportKeys: string[]\n): string {\n let stmt: string;\n if (isIntegerProp(prop)) {\n stmt = `${prop.name}: z.int()`;\n } else if (isBigIntegerProp(prop)) {\n stmt = `${prop.name}: z.bigint()`;\n } else if (isTextProp(prop)) {\n stmt = `${prop.name}: z.string().max(${getTextTypeLength(prop.textType)})`;\n } else if (isEnumProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isStringProp(prop)) {\n stmt = `${prop.name}: z.string().max(${prop.length})`;\n } else if (isDecimalProp(prop)) {\n stmt = `${prop.name}: z.string()`;\n } else if (isFloatProp(prop) || isDoubleProp(prop)) {\n stmt = `${prop.name}: z.number()`;\n } else if (isBooleanProp(prop)) {\n stmt = `${prop.name}: z.boolean()`;\n } else if (isDateProp(prop)) {\n stmt = `${prop.name}: z.string().length(10)`;\n } else if (isTimeProp(prop)) {\n stmt = `${prop.name}: z.string().length(8)`;\n } else if (isDateTimeProp(prop)) {\n stmt = `${prop.name}: z.date()`;\n } else if (isTimestampProp(prop)) {\n stmt = `${prop.name}: z.date()`;\n } else if (isJsonProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isUuidProp(prop)) {\n stmt = `${prop.name}: z.uuid()`;\n } else if (isVirtualProp(prop)) {\n stmt = `${prop.name}: ${prop.id}`;\n injectImportKeys.push(prop.id);\n } else if (isRelationProp(prop)) {\n if (\n isBelongsToOneRelationProp(prop) ||\n (isOneToOneRelationProp(prop) && prop.hasJoinColumn)\n ) {\n stmt = `${prop.name}_id: z.int()`;\n } else {\n // 그외 relation 케이스 제외\n return `// ${prop.name}: ${prop.relationType} ${prop.with}`;\n }\n } else {\n return \"// unable to resolve\";\n }\n\n if ((prop as { unsigned?: boolean }).unsigned) {\n stmt += \".nonnegative()\";\n }\n if (prop.nullable) {\n stmt += \".nullable()\";\n }\n\n return stmt + \",\";\n}\n\n// TODO(Haze, 251031): \"template_literal\", \"file\"에 대한 지원이 필요함.\nexport function zodTypeToZodCode(zt: z.ZodType): string {\n switch (zt.def.type) {\n case \"string\":\n return \"z.string()\";\n case \"number\":\n return \"z.number()\";\n case \"bigint\":\n return \"z.bigint()\";\n case \"boolean\":\n return \"z.boolean()\";\n case \"date\":\n return \"z.date()\";\n case \"null\":\n return \"z.null()\";\n case \"undefined\":\n return \"z.undefined()\";\n case \"any\":\n return \"z.any()\";\n case \"unknown\":\n return \"z.unknown()\";\n case \"never\":\n return \"z.never()\";\n case \"nullable\":\n return zodTypeToZodCode((zt as AnyZodNullable).def.innerType) + \".nullable()\";\n case \"default\":\n const zDefaultDef = (zt as AnyZodDefault).def;\n return (\n zodTypeToZodCode(zDefaultDef.innerType) +\n `.default(${zDefaultDef.defaultValue})`\n );\n case \"record\":\n const zRecordDef = (zt as AnyZodRecord).def;\n return `z.record(${zodTypeToZodCode(zRecordDef.keyType)}, ${zodTypeToZodCode(\n zRecordDef.valueType\n )})`;\n case \"literal\":\n const items = Array.from((zt as z.ZodLiteral<any>).values).map(value => {\n if (typeof value === \"string\") {\n return `\"${value}\"`;\n }\n\n if (value === null) {\n return `null`;\n }\n\n if (value === undefined) {\n return `undefined`;\n }\n\n return `${value}`;\n });\n\n if (items.length === 1) {\n return `z.literal(${items[0]})`;\n }\n return `z.literal([${items.join(\", \")}])`;\n case \"union\":\n return `z.union([${(zt as AnyZodUnion).def.options\n .map((option: z.ZodType) => zodTypeToZodCode(option))\n .join(\",\")}])`;\n case \"enum\":\n // NOTE: z.enum([\"A\", \"B\"])도 z.enum({ A: \"A\", B: \"B\" })로 처리됨.\n return `z.enum({${Object.entries((zt as z.ZodEnum).def.entries)\n .map(([key, val]) =>\n typeof val === \"string\" ? `${key}: \"${val}\"` : `${key}: ${val}`)\n .join(\", \")}})`;\n case \"array\":\n return `z.array(${zodTypeToZodCode((zt as z.ZodArray<z.ZodType>).def.element)})`;\n case \"object\":\n const shape = (zt as any).shape;\n return [\n \"z.object({\",\n ...Object.keys(shape).map(\n (key) => `${key}: ${zodTypeToZodCode(shape[key])},`\n ),\n \"})\",\n ].join(\"\\n\");\n case \"optional\":\n return zodTypeToZodCode((zt as z.ZodOptional<z.ZodType>).def.innerType) + \".optional()\";\n case \"file\":\n return `z.file()`;\n case \"intersection\":\n const zIntersectionDef = (zt as z.ZodIntersection<z.ZodType, z.ZodType>).def;\n return `z.intersection(${zodTypeToZodCode(zIntersectionDef.left)}, ${zodTypeToZodCode(zIntersectionDef.right)})`;\n case \"file\":\n return `z.file()`;\n default:\n throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);\n }\n}\n\nexport function apiParamToTsCode(\n params: ApiParam[],\n injectImportKeys: string[]\n): string {\n return params\n .map((param) => {\n return `${param.name}${\n param.optional && !param.defaultDef ? \"?\" : \"\"\n }: ${apiParamTypeToTsType(param.type, injectImportKeys)}${\n param.defaultDef ? `= ${param.defaultDef}` : \"\"\n }`;\n })\n .join(\", \");\n}\n\nexport function apiParamToTsCodeAsObject(\n params: ApiParam[],\n injectImportKeys: string[]\n): string {\n return `{ ${params\n .map(\n (param) =>\n `${param.name}${param.optional ? \"?\" : \"\"}: ${apiParamTypeToTsType(\n param.type,\n injectImportKeys\n )}${param.defaultDef ? `= ${param.defaultDef}` : \"\"}`\n )\n .join(\", \")} }`;\n}\n\nexport function apiParamTypeToTsType(\n paramType: ApiParamType,\n injectImportKeys: string[]\n): string {\n if (\n [\n \"string\",\n \"number\",\n \"boolean\",\n \"true\",\n \"false\",\n \"null\",\n \"undefined\",\n \"void\",\n \"any\",\n \"unknown\",\n ].includes(paramType as string)\n ) {\n return paramType as string;\n } else if (ApiParamType.isObject(paramType)) {\n return `{ ${apiParamToTsCode(paramType.props, injectImportKeys)} }`;\n } else if (ApiParamType.isStringLiteral(paramType)) {\n return `\"${paramType.value}\"`;\n } else if (ApiParamType.isNumericLiteral(paramType)) {\n return String(paramType.value);\n } else if (ApiParamType.isUnion(paramType)) {\n return paramType.types\n .map((type) => apiParamTypeToTsType(type, injectImportKeys))\n .join(\" | \");\n } else if (ApiParamType.isIntersection(paramType)) {\n return paramType.types\n .map((type) => apiParamTypeToTsType(type, injectImportKeys))\n .join(\" & \");\n } else if (ApiParamType.isArray(paramType)) {\n return (\n apiParamTypeToTsType(paramType.elementsType, injectImportKeys) + \"[]\"\n );\n } else if (ApiParamType.isRef(paramType)) {\n if (\n [\"Pick\", \"Omit\", \"Promise\", \"Partial\", \"Date\"].includes(paramType.id) ===\n false\n ) {\n // importKeys 인젝션\n injectImportKeys.push(paramType.id);\n }\n if (paramType.args === undefined || paramType.args.length === 0) {\n return paramType.id;\n } else {\n return `${paramType.id}<${paramType.args\n .map((arg) => apiParamTypeToTsType(arg, injectImportKeys))\n .join(\",\")}>`;\n }\n } else if (ApiParamType.isIndexedAccess(paramType)) {\n return `${apiParamTypeToTsType(\n paramType.object,\n injectImportKeys\n )}[${apiParamTypeToTsType(paramType.index, injectImportKeys)}]`;\n } else if (ApiParamType.isTupleType(paramType)) {\n return `[ ${paramType.elements.map((elem) =>\n apiParamTypeToTsType(elem, injectImportKeys)\n )} ]`;\n } else if (ApiParamType.isTypeParam(paramType)) {\n return `<${paramType.id}${\n paramType.constraint\n ? ` extends ${apiParamTypeToTsType(\n paramType.constraint,\n injectImportKeys\n )}`\n : \"\"\n }>`;\n } else {\n throw new Error(`resolve 불가 ApiParamType ${paramType}`);\n }\n}\n\nexport function unwrapPromiseOnce(paramType: ApiParamType) {\n if (ApiParamType.isPromise(paramType)) {\n return paramType.args![0];\n } else {\n return paramType;\n }\n}\n\n// TODO(Haze, 251031): \"template_literal\", \"file\"에 대한 지원이 필요함.\nexport function serializeZodType(zt: z.ZodType): any {\n switch (zt.def.type) {\n case \"object\":\n return {\n type: \"object\",\n shape: Object.keys((zt as AnyZodObject).shape).reduce(\n (result, key) => {\n return {\n ...result,\n [key]: serializeZodType((zt as AnyZodObject).shape[key]),\n };\n },\n {}\n ),\n };\n case \"array\":\n return {\n type: \"array\",\n element: serializeZodType((zt as AnyZodArray).def.element),\n };\n case \"enum\":\n return {\n type: \"enum\",\n values: (zt as z.ZodEnum).def.entries,\n };\n case \"string\":\n return {\n type: \"string\",\n checks: zt.def.checks,\n };\n case \"number\":\n return {\n type: \"number\",\n checks: zt.def.checks,\n };\n case \"boolean\":\n return {\n type: \"boolean\",\n };\n case \"nullable\":\n return {\n ...serializeZodType((zt as AnyZodNullable).def.innerType),\n nullable: true,\n };\n case \"optional\":\n return {\n ...serializeZodType((zt as AnyZodOptional).def.innerType),\n optional: true,\n };\n case \"any\":\n return {\n type: \"any\",\n };\n case \"record\":\n return {\n type: \"record\",\n keyType: serializeZodType((zt as AnyZodRecord).def.keyType),\n valueType: serializeZodType((zt as AnyZodRecord).def.valueType),\n };\n case \"union\":\n return {\n type: \"union\",\n options: (zt.def as AnyZodUnion).options.map((option) =>\n serializeZodType(option)\n ),\n };\n default:\n throw new Error(\n `Serialize 로직이 정의되지 않은 ZodType: ${zt.def.type}`\n );\n }\n}\n\n// TODO(Haze, 251031): \"template_literal\", \"file\"에 대한 지원이 필요함.\nexport function zodTypeToTsTypeDef(zt: z.ZodType): string {\n switch (zt.def.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n case \"bigint\":\n case \"date\":\n case \"null\":\n case \"undefined\":\n case \"any\":\n case \"unknown\":\n case \"never\":\n return zt.def.type;\n case \"nullable\":\n return zodTypeToTsTypeDef((zt as AnyZodNullable).def.innerType) + \" | null\";\n case \"default\":\n return zodTypeToTsTypeDef((zt as AnyZodDefault).def.innerType);\n case \"record\":\n const recordType = zt as AnyZodRecord;\n return `{ [ key: ${zodTypeToTsTypeDef(recordType.def.keyType)} ]: ${zodTypeToTsTypeDef(recordType.def.valueType)}}`;\n case \"literal\":\n return Array.from((zt as z.ZodLiteral).values).map(value => {\n if (typeof value === \"string\") {\n return `\"${value}\"`;\n }\n\n if (value === null) {\n return `null`;\n }\n\n if (value === undefined) {\n return `undefined`;\n }\n\n return `${value}`;\n }).join(\" | \")\n case \"union\":\n return `${(zt as AnyZodUnion).options\n .map((option) => zodTypeToTsTypeDef(option))\n .join(\" | \")}`;\n case \"enum\":\n return `${(zt as z.ZodEnum).options.map((val) => `\"${val}\"`).join(\" | \")}`;\n case \"array\":\n return `${zodTypeToTsTypeDef((zt as AnyZodArray).element)}[]`;\n case \"object\":\n const shape = (zt as AnyZodObject).shape;\n return [\n \"{\",\n ...Object.keys(shape).map((key) => {\n if (shape[key].def.type === \"optional\") {\n return `${key}?: ${zodTypeToTsTypeDef(shape[key].def.innerType)},`;\n } else {\n return `${key}: ${zodTypeToTsTypeDef(shape[key])},`;\n }\n }),\n \"}\",\n ].join(\"\\n\");\n case \"optional\":\n return zodTypeToTsTypeDef((zt as AnyZodOptional).def.innerType) + \" | undefined\";\n default:\n throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);\n }\n}\n"],"names":["apiParamToTsCode","apiParamToTsCodeAsObject","apiParamTypeToTsType","getTextTypeLength","getZodObjectFromApi","getZodObjectFromApiParams","getZodTypeFromApiParamType","propNodeToZodTypeDef","propToZodTypeDef","serializeZodType","unwrapPromiseOnce","zodTypeToTsTypeDef","zodTypeToZodCode","api","references","typeParameters","length","map","typeParam","constraint","zodType","id","ReqType","parameters","filter","param","ApiParamType","isContext","type","isRefKnex","optional","name","startsWith","apiParams","z","object","reduce","r","paramType","string","number","boolean","advType","t","literal","value","objType","props","arrType","array","elementsType","refType","date","includes","args","Error","arg","obj","literalOrUnion","keys","ZodUnion","def","options","option","values","keyRecord","result","key","pick","omit","partial","reference","undefined","unionType","types","some","nullable","union","intersectionType","index","resolvedType","intersection","unknown","tupleType","tuple","elements","elem","propNode","injectImportKeys","nodeType","prop","children","childPropNode","join","textType","stmt","isIntegerProp","isBigIntegerProp","isTextProp","isEnumProp","push","isStringProp","isDecimalProp","isFloatProp","isDoubleProp","isBooleanProp","isDateProp","isTimeProp","isDateTimeProp","isTimestampProp","isJsonProp","isUuidProp","isVirtualProp","isRelationProp","isBelongsToOneRelationProp","isOneToOneRelationProp","hasJoinColumn","relationType","with","unsigned","zt","innerType","zDefaultDef","defaultValue","zRecordDef","keyType","valueType","items","Array","from","Object","entries","val","element","shape","zIntersectionDef","left","right","params","defaultDef","isObject","isStringLiteral","isNumericLiteral","String","isUnion","isIntersection","isArray","isRef","isIndexedAccess","isTupleType","isTypeParam","isPromise","checks","recordType"],"mappings":"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"}
|
package/dist/api/context.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/context.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/decorators.ts"],"sourcesContent":["import type { HTTPMethods } from \"fastify\";\nimport inflection from \"inflection\";\nimport type { ApiParam, ApiParamType } from \"../types/types\";\nimport { z } from \"zod\";\nimport {\n PuriTransactionWrapper,\n PuriWrapper,\n TransactionalOptions,\n} from \"../database/puri-wrapper\";\nimport { DB } from \"../database/db\";\nimport { Sonamu } from \"./sonamu\";\nimport type { UploadContext } from \"./context\";\n\nexport interface GuardKeys {\n query: true;\n admin: true;\n user: true;\n}\nexport type GuardKey = keyof GuardKeys;\nexport type ServiceClient =\n | \"axios\"\n | \"axios-multipart\"\n | \"swr\"\n | \"window-fetch\";\nexport type ApiDecoratorOptions = {\n httpMethod?: HTTPMethods;\n contentType?:\n | \"text/plain\"\n | \"text/html\"\n | \"text/xml\"\n | \"application/json\"\n | \"application/octet-stream\";\n clients?: ServiceClient[];\n path?: string;\n resourceName?: string;\n guards?: GuardKey[];\n description?: string;\n timeout?: number;\n};\nexport type StreamDecoratorOptions = {\n type: \"sse\"; // | 'ws\n events: z.ZodObject<any>;\n path?: string;\n resourceName?: string;\n guards?: GuardKey[];\n description?: string;\n};\nexport type UploadDecoratorOptions = {\n mode?: \"single\" | \"multiple\";\n};\nexport const registeredApis: {\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n streamOptions?: StreamDecoratorOptions;\n uploadOptions?: UploadDecoratorOptions;\n}[] = [];\nexport type ExtendedApi = {\n modelName: string;\n methodName: string;\n path: string;\n options: ApiDecoratorOptions;\n streamOptions?: StreamDecoratorOptions;\n uploadOptions?: UploadDecoratorOptions;\n typeParameters: ApiParamType.TypeParam[];\n parameters: ApiParam[];\n returnType: ApiParamType;\n};\n\nexport function api(options: ApiDecoratorOptions = {}) {\n options = {\n httpMethod: \"GET\",\n contentType: \"application/json\",\n clients: [\"axios\"],\n ...options,\n };\n\n return function (target: Object, propertyKey: string) {\n const modelName = target.constructor.name.match(/(.+)Class$/)![1];\n const methodName = propertyKey;\n\n const defaultPath = `/${inflection.camelize(\n modelName.replace(/Model$/, \"\").replace(/Frame$/, \"\"),\n true\n )}/${inflection.camelize(propertyKey, true)}`;\n\n // 기존 동일한 메서드가 있는지 확인 후 있는 경우 override\n const existingApi = registeredApis.find(\n (api) => api.modelName === modelName && api.methodName === methodName\n );\n if (existingApi) {\n existingApi.options = options;\n } else {\n registeredApis.push({\n modelName,\n methodName,\n path: options.path ?? defaultPath,\n options,\n });\n }\n };\n}\n\nexport function stream(options: StreamDecoratorOptions) {\n return function (target: Object, propertyKey: string) {\n const modelName = target.constructor.name.match(/(.+)Class$/)![1];\n const methodName = propertyKey;\n\n const defaultPath = `/${inflection.camelize(\n modelName.replace(/Model$/, \"\").replace(/Frame$/, \"\"),\n true\n )}/${inflection.camelize(propertyKey, true)}`;\n\n const existingApi = registeredApis.find(\n (api) => api.modelName === modelName && api.methodName === methodName\n );\n if (existingApi) {\n existingApi.options = options;\n } else {\n registeredApis.push({\n modelName,\n methodName,\n path: options.path ?? defaultPath,\n options: {\n ...options,\n httpMethod: \"GET\",\n },\n streamOptions: options,\n });\n }\n };\n}\n\nexport function transactional(options: TransactionalOptions = {}) {\n const { isolation, readOnly, dbPreset = \"w\" } = options;\n\n return function (\n _target: Object,\n _propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (this: any, ...args: any[]) {\n const existingContext = DB.transactionStorage.getStore();\n\n // 이미 AsyncLocalStorage 컨텍스트 안에 있는지 확인\n if (existingContext) {\n // 해당 preset의 트랜잭션이 이미 있으면 재사용\n if (existingContext.getTransaction(dbPreset)) {\n return originalMethod.apply(this, args);\n }\n }\n\n // AsyncLocalStorage 컨텍스트 없거나 해당 preset의 트랜잭션이 없으면 새로 시작\n const startTransaction = async () => {\n const puri = this.getPuri(dbPreset) as PuriWrapper;\n\n return puri.knex.transaction(\n async (trx) => {\n const trxWrapper = new PuriTransactionWrapper(\n trx,\n this.getUpsertBuilder()\n );\n // TransactionContext에 트랜잭션 저장\n DB.getTransactionContext().setTransaction(dbPreset, trxWrapper);\n\n try {\n return await originalMethod.apply(this, args);\n } finally {\n // 트랜잭션 제거\n DB.getTransactionContext().deleteTransaction(dbPreset);\n }\n },\n { isolationLevel: isolation, readOnly }\n );\n };\n\n // AsyncLocalStorage 컨텍스트가 없으면 새로 생성\n if (!existingContext) {\n return DB.runWithTransaction(startTransaction);\n } else {\n // 컨텍스트는 있지만 이 preset의 트랜잭션은 없는 경우 (같은 컨텍스트 내에서 실행)\n return startTransaction();\n }\n };\n\n return descriptor;\n };\n}\n\nexport function upload(options: UploadDecoratorOptions = {}) {\n return function (\n _target: Object,\n _propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value;\n const modelName = _target.constructor.name.match(/(.+)Class$/)![1];\n const methodName = _propertyKey;\n\n // registeredApis에서 해당 API 찾아서 uploadOptions 추가\n const existingApi = registeredApis.find(\n (api) => api.modelName === modelName && api.methodName === methodName\n );\n if (existingApi) {\n existingApi.uploadOptions = options;\n }\n\n descriptor.value = async function (this: any, ...args: any[]) {\n const { request } = Sonamu.getContext();\n const uploadContext: UploadContext = {\n file: undefined,\n files: [],\n };\n\n const storage = Sonamu.storage;\n if (!storage) {\n throw new Error(\"Storage가 설정되지 않았습니다.\");\n }\n\n const { FileStorage } = await import(\"../file-storage/file-storage\");\n if (options.mode === \"multiple\") {\n const rawFilesIterator = request.files();\n for await (const rawFile of rawFilesIterator) {\n if (rawFile) {\n uploadContext.files.push(new FileStorage(rawFile, storage));\n }\n }\n } else {\n const rawFile = await request.file();\n if (rawFile) {\n uploadContext.file = new FileStorage(rawFile, storage);\n }\n }\n\n return Sonamu.uploadStorage.run({ uploadContext }, () => {\n return originalMethod.apply(this, args);\n });\n };\n\n return descriptor;\n };\n}\n"],"names":["api","registeredApis","stream","transactional","upload","options","httpMethod","contentType","clients","target","propertyKey","modelName","name","match","methodName","defaultPath","inflection","camelize","replace","existingApi","find","push","path","streamOptions","isolation","readOnly","dbPreset","_target","_propertyKey","descriptor","originalMethod","value","args","existingContext","startTransaction","DB","transactionStorage","getStore","getTransaction","apply","puri","getPuri","knex","transaction","trx","trxWrapper","PuriTransactionWrapper","getUpsertBuilder","getTransactionContext","setTransaction","deleteTransaction","isolationLevel","runWithTransaction","uploadOptions","request","uploadContext","storage","FileStorage","rawFilesIterator","rawFile","Sonamu","getContext","file","undefined","files","Error","mode","uploadStorage","run"],"mappings":"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"}
|
package/dist/api/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/index.ts"],"sourcesContent":["export * from \"./caster\";\nexport * from \"./code-converters\";\nexport * from \"./context\";\nexport * from \"./decorators\";\nexport * from \"../file-storage/driver\";\nexport * from \"../file-storage/file-storage\";\nexport * from \"./sonamu\";\n"],"names":[],"mappings":"2FAAc,0CACA,mDACA,2CACA,8CACA,wDACA,8DACA"}
|
package/dist/api/sonamu.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/sonamu.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\nimport chalk from \"chalk\";\nimport fastify from \"fastify\";\nimport { readFile } from \"fs/promises\";\nimport path from \"path\";\nimport { exists } from \"../utils/fs-utils\";\n\nimport type { FSWatcher } from \"chokidar\";\nimport { formatInTimeZone } from \"date-fns-tz\";\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from \"fastify\";\nimport type { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { ZodError, ZodObject } from \"zod\";\nimport { DB, SonamuDBConfig } from \"../database/db\";\nimport { attachOnDuplicateUpdate } from \"../database/knex-plugins/knex-on-duplicate-update\";\nimport {\n BadRequestException,\n NotFoundException,\n} from \"../exceptions/so-exceptions\";\nimport type { Driver } from \"../file-storage/driver\";\nimport { createSSEFactory } from \"../stream/sse\";\nimport type { Syncer } from \"../syncer/syncer\";\nimport {\n ApiParamType,\n SonamuFastifyConfig,\n SonamuServerOptions,\n} from \"../types/types\";\nimport { isLocal, isTest } from \"../utils/controller\";\nimport { findApiRootPath } from \"../utils/utils\";\nimport { humanizeZodError } from \"../utils/zod-error\";\nimport { fastifyCaster } from \"./caster\";\nimport { getZodObjectFromApi } from \"./code-converters\";\nimport type { AuthContext, Context, UploadContext } from \"./context\";\nimport type { ExtendedApi } from \"./decorators\";\nimport fastifyPassport from \"@fastify/passport\";\n\nexport type SonamuConfig = {\n projectName?: string;\n api: {\n dir: string;\n };\n sync: {\n targets: string[];\n };\n route: {\n prefix: string;\n };\n timezone?: string;\n ui?: {\n port: number;\n };\n};\nexport type SonamuSecrets = {\n [key: string]: string;\n};\nclass SonamuClass {\n public isInitialized: boolean = false;\n public asyncLocalStorage: AsyncLocalStorage<{\n context: Context;\n }> = new AsyncLocalStorage();\n\n public uploadStorage: AsyncLocalStorage<{\n uploadContext: UploadContext;\n }> = new AsyncLocalStorage();\n\n public getContext(): Context {\n const store = this.asyncLocalStorage.getStore();\n if (store?.context) {\n return store.context;\n }\n throw new Error(\"Sonamu cannot find context\");\n }\n\n public getUploadContext(): UploadContext {\n const store = this.uploadStorage.getStore();\n if (store?.uploadContext) {\n return store.uploadContext;\n }\n throw new Error(\n \"Sonamu cannot find upload context. Did you use @upload decorator?\"\n );\n }\n\n private _apiRootPath: string | null = null;\n set apiRootPath(apiRootPath: string) {\n this._apiRootPath = apiRootPath;\n }\n get apiRootPath(): string {\n if (this._apiRootPath === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._apiRootPath!;\n }\n get appRootPath(): string {\n return this.apiRootPath.split(path.sep).slice(0, -1).join(path.sep);\n }\n\n private _dbConfig: SonamuDBConfig | null = null;\n set dbConfig(dbConfig: SonamuDBConfig) {\n this._dbConfig = dbConfig;\n }\n get dbConfig(): SonamuDBConfig {\n if (this._dbConfig === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._dbConfig!;\n }\n\n private _syncer: Syncer | null = null;\n set syncer(syncer: Syncer) {\n this._syncer = syncer;\n }\n get syncer(): Syncer {\n if (this._syncer === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._syncer!;\n }\n\n private _config: SonamuConfig | null = null;\n set config(config: SonamuConfig) {\n this._config = config;\n }\n get config(): SonamuConfig {\n if (this._config === null) {\n throw new Error(\"Sonamu has not been initialized\");\n }\n return this._config;\n }\n\n private _secrets: SonamuSecrets | null = null;\n set secrets(secrets: SonamuSecrets) {\n this._secrets = secrets;\n }\n get secrets(): SonamuSecrets | null {\n return this._secrets;\n }\n\n private _storage: Driver | null = null;\n set storage(storage: Driver) {\n this._storage = storage;\n }\n get storage(): Driver | null {\n return this._storage;\n }\n\n // HMR 처리\n public watcher: FSWatcher | null = null;\n private pendingFiles: string[] = [];\n private hmrStartTime: number = 0;\n\n public server: FastifyInstance | null = null;\n\n async initForTesting() {\n await this.init(true, false, undefined, true);\n }\n\n async init(\n doSilent: boolean = false,\n enableSync: boolean = true,\n apiRootPath?: string,\n forTesting: boolean = false\n ) {\n if (this.isInitialized) {\n return;\n }\n !doSilent &&\n console.time(\n chalk.cyan(`Sonamu.init${forTesting ? \" for testing\" : \"\"}`)\n );\n\n // API 루트 패스\n this.apiRootPath = apiRootPath ?? findApiRootPath();\n const configPath = path.join(this.apiRootPath, \"sonamu.config.json\");\n const secretsPath = path.join(this.apiRootPath, \"sonamu.secrets.json\");\n if (!(await exists(configPath))) {\n throw new Error(`Cannot find sonamu.config.json in ${configPath}`);\n }\n this.config = JSON.parse(\n (await readFile(configPath)).toString()\n ) as SonamuConfig;\n if (await exists(secretsPath)) {\n this.secrets = JSON.parse(\n (await readFile(secretsPath)).toString()\n ) as SonamuSecrets;\n }\n\n // DB 로드\n this.dbConfig = await DB.readKnexfile();\n !doSilent && console.log(chalk.green(\"DB Config Loaded!\"));\n attachOnDuplicateUpdate();\n\n // 테스팅인 경우 엔티티 로드 & 싱크 없이 중단\n if (forTesting) {\n this.isInitialized = true;\n return;\n }\n\n // Entity 로드\n const { EntityManager } = await import(\"../entity/entity-manager\");\n await EntityManager.autoload(doSilent);\n\n // Syncer\n const { Syncer } = await import(\"../syncer/syncer\");\n this.syncer = new Syncer();\n\n // Autoload: Models / Types / APIs\n await this.syncer.autoloadModels();\n await this.syncer.autoloadTypes();\n await this.syncer.autoloadApis();\n\n if (isLocal() && !isTest() && enableSync) {\n await this.syncer.sync();\n\n // FIXME: hmr 설정된 경우만 워처 시작\n this.startWatcher();\n\n this.syncer.syncUI();\n }\n\n this.isInitialized = true;\n !doSilent && console.timeEnd(chalk.cyan(\"Sonamu.init\"));\n }\n\n async createServer(\n options: SonamuServerOptions,\n initOptions?: {\n enableSync?: boolean;\n doSilent?: boolean;\n }\n ) {\n const server = fastify(options.fastify);\n this.server = server;\n\n // Storage 설정 저장\n if (options.storage) {\n this.storage = options.storage;\n }\n\n // 플러그인 등록\n if (options.plugins) {\n this.registerPlugins(server, options.plugins);\n }\n\n if (options.auth) {\n if (!options.plugins?.session) {\n throw new Error(\n \"Auth requires session plugin. Please add plugins.session configuration.\"\n );\n }\n\n this.registerAuth(server, options.auth);\n }\n\n // API 라우팅 설정\n await this.withFastify(server, options.apiConfig, {\n enableSync: initOptions?.enableSync,\n doSilent: initOptions?.doSilent,\n });\n\n // 서버 시작\n await this.boot(server, options);\n\n return server;\n }\n\n async withFastify(\n server: FastifyInstance<Server, IncomingMessage, ServerResponse>,\n config: SonamuFastifyConfig,\n options?: {\n enableSync?: boolean;\n doSilent?: boolean;\n }\n ) {\n if (this.isInitialized === false) {\n await this.init(options?.doSilent, options?.enableSync);\n }\n\n this.server = server;\n\n // timezone 설정\n const timezone = this.config.timezone;\n if (timezone) {\n const DATE_FORMAT = \"yyyy-MM-dd'T'HH:mm:ssXXX\";\n // ISO 8601 날짜 형식 정규식 (예: 2024-01-15T09:30:00.000Z)\n const ISO_DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/;\n\n server.setReplySerializer((payload) => {\n return JSON.stringify(payload, (_key, value) => {\n if (typeof value === \"string\" && ISO_DATE_REGEX.test(value)) {\n return formatInTimeZone(new Date(value), timezone, DATE_FORMAT);\n }\n return value;\n });\n });\n !options?.doSilent &&\n console.log(chalk.green(`Timezone set to ${timezone}`));\n }\n\n // 전체 라우팅 리스트\n server.get(\n `${this.config.route.prefix}/routes`,\n async (_request, _reply): Promise<any> => {\n return this.syncer.apis;\n }\n );\n\n // Healthcheck API\n server.get(\n `${this.config.route.prefix}/healthcheck`,\n async (_request, _reply): Promise<string> => {\n return \"ok\";\n }\n );\n\n // API 라우팅 (로컬HMR 상태와 구분)\n if (isLocal()) {\n server.all(\"*\", (request, reply) => {\n const found = this.syncer.apis.find(\n (api) =>\n this.config.route.prefix + api.path === request.url.split(\"?\")[0] &&\n (api.options.httpMethod ?? \"GET\") === request.method.toUpperCase()\n );\n if (found) {\n return this.getApiHandler(found, config)(request, reply);\n }\n throw new NotFoundException(\"존재하지 않는 API 접근입니다.\");\n });\n } else {\n this.syncer.apis.map((api) => {\n // model\n if (this.syncer.models[api.modelName] === undefined) {\n throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);\n }\n\n // route\n server.route({\n method: api.options.httpMethod!,\n url: this.config.route.prefix + api.path,\n handler: this.getApiHandler(api, config),\n }); // END server.route\n });\n }\n }\n\n getApiHandler(api: ExtendedApi, config: SonamuFastifyConfig) {\n return async (\n request: FastifyRequest,\n reply: FastifyReply\n ): Promise<unknown> => {\n (api.options.guards ?? []).every((guard) =>\n config.guardHandler(guard, request, api)\n );\n\n // 파라미터 정보로 zod 스키마 빌드\n const ReqType = getZodObjectFromApi(api, this.syncer.types);\n\n // request 파싱\n const which = api.options.httpMethod === \"GET\" ? \"query\" : \"body\";\n let reqBody: {\n [key: string]: unknown;\n };\n try {\n reqBody = fastifyCaster(ReqType).parse(request[which] ?? {});\n } catch (e) {\n if (e instanceof ZodError) {\n const messages = humanizeZodError(e)\n .map((issue) => issue.message)\n .join(\" \");\n throw new BadRequestException(messages, {\n zodError: e,\n });\n } else {\n throw e;\n }\n }\n\n // Content-Type\n reply.type(api.options.contentType ?? \"application/json\");\n\n // 캐시\n const { cacheKey, cacheTtl, cachedData } = await (async () => {\n if (config.cache) {\n try {\n const cacheKeyRes = config.cache.resolveKey(api.path, reqBody);\n if (cacheKeyRes.cache === false) {\n return { cacheKey: null, cachedData: null };\n }\n\n const cacheKey = cacheKeyRes.key;\n const cacheTtl = cacheKeyRes.ttl;\n const cachedData = await config.cache.get(cacheKey);\n return { cacheKey, cacheTtl, cachedData };\n } catch (e) {\n console.error(e);\n }\n return { cacheKey: null, cachedData: null };\n }\n return { cacheKey: null, cachedData: null };\n })();\n if (cachedData !== null) {\n return cachedData;\n }\n\n // createSSEFactory 함수에 미리 request의 socket과 reply를 바인딩.\n const createSSE = (<T extends ZodObject>(\n _request: FastifyRequest,\n _reply: FastifyReply,\n _events: T\n ) => createSSEFactory(_request.socket, _reply, _events)).bind(\n null,\n request,\n reply\n );\n\n const context: Context = {\n ...(await Promise.resolve(\n config.contextProvider(\n {\n request,\n reply,\n headers: request.headers,\n createSSE,\n // auth\n user: request.user ?? null,\n passport: {\n login: request.login.bind(\n request\n ) as AuthContext[\"passport\"][\"login\"],\n logout: request.logout.bind(\n request\n ) as AuthContext[\"passport\"][\"logout\"],\n },\n },\n request,\n reply\n )\n )),\n };\n\n const model = this.syncer.models[api.modelName];\n return this.asyncLocalStorage.run({ context }, async () => {\n const result = await (model as any)[api.methodName].apply(\n model,\n api.parameters.map((param) => {\n // Context 인젝션\n if (ApiParamType.isContext(param.type)) {\n return context;\n } else {\n return reqBody[param.name];\n }\n })\n );\n reply.type(api.options.contentType ?? \"application/json\");\n\n // 캐시 키 있는 경우 갱신 후 저장\n if (config.cache && cacheKey) {\n await config.cache.put(cacheKey, result, cacheTtl);\n }\n return result;\n });\n };\n }\n\n startWatcher(): void {\n const watchPath = path.join(this.apiRootPath, \"src\");\n const chokidar = require(\"chokidar\") as typeof import(\"chokidar\");\n this.watcher = chokidar.watch(watchPath, {\n ignored: (path, stats) =>\n (!!stats?.isFile() &&\n !path.endsWith(\".ts\") &&\n !path.endsWith(\".json\")) ||\n path.endsWith(\"src/index.ts\"),\n persistent: true,\n ignoreInitial: true,\n });\n this.watcher.on(\"all\", async (event: string, filePath: string) => {\n if (event !== \"change\" && event !== \"add\") {\n return;\n }\n\n try {\n await this.handleFileChange(event, filePath);\n } catch (e) {\n console.error(e);\n }\n });\n }\n\n /*\n A function that automatically handles init and destroy when using Sonamu via scripts. \n */\n async runScript(fn: () => Promise<void>) {\n await this.init(true, false, undefined, false);\n try {\n await fn();\n } finally {\n await this.destroy();\n }\n }\n\n private registerPlugins(\n server: FastifyInstance,\n plugins: SonamuServerOptions[\"plugins\"]\n ) {\n if (!plugins) {\n return;\n }\n\n const pluginsModules = {\n cors: \"@fastify/cors\",\n formbody: \"@fastify/formbody\",\n multipart: \"@fastify/multipart\",\n qs: \"fastify-qs\",\n sse: \"fastify-sse-v2\",\n static: \"@fastify/static\",\n session: \"@fastify/secure-session\",\n } as const;\n\n const registerPlugin = <K extends keyof NonNullable<typeof plugins>>(\n key: K,\n pluginName: string\n ) => {\n const option = plugins[key];\n if (!option) return;\n\n if (option === true) {\n server.register(import(pluginName));\n } else {\n server.register(import(pluginName), option);\n }\n };\n\n Object.entries(pluginsModules).forEach(([key, pluginName]) => {\n registerPlugin(key as keyof typeof plugins, pluginName);\n });\n\n if (plugins.custom) {\n plugins.custom(server);\n }\n }\n\n private async registerAuth(\n server: FastifyInstance,\n options: NonNullable<SonamuServerOptions[\"auth\"]>\n ) {\n server.register(fastifyPassport.initialize());\n server.register(fastifyPassport.secureSession());\n\n if (typeof options === \"boolean\") {\n fastifyPassport.registerUserSerializer(async (user, _request) => user);\n fastifyPassport.registerUserDeserializer(\n async (serialized, _request) => serialized\n );\n } else {\n fastifyPassport.registerUserSerializer(options.userSerializer);\n fastifyPassport.registerUserDeserializer(options.userDeserializer);\n }\n }\n\n private async boot(server: FastifyInstance, options: SonamuServerOptions) {\n const port = options.listen?.port ?? 3000;\n const host = options.listen?.host ?? \"localhost\";\n\n server.addHook(\"onClose\", async () => {\n await options.lifecycle?.onShutdown?.(server);\n await this.destroy();\n });\n\n const shutdown = async () => {\n try {\n await server.close();\n process.exit(0);\n } catch (err) {\n console.error(\"Error during shutdown:\", err);\n process.exit(1);\n }\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n if (options.lifecycle?.onError) {\n server.setErrorHandler(options.lifecycle?.onError);\n }\n\n server\n .listen({ port, host })\n .then(async () => {\n await options.lifecycle?.onStart?.(server);\n })\n .catch(async (err) => {\n console.error(chalk.red(\"Failed to start server:\", err));\n await shutdown();\n });\n }\n\n private async handleFileChange(\n event: string,\n filePath: string\n ): Promise<void> {\n // 첫 번째 파일이면 HMR 시작 시간 기록\n if (this.pendingFiles.length === 0) {\n this.hmrStartTime = Date.now();\n }\n\n this.pendingFiles.push(filePath);\n\n const relativePath = filePath.replace(this.apiRootPath, \"api\");\n console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)}`));\n\n await this.syncer.syncFromWatcher([filePath]);\n\n // 처리 완료된 파일을 대기 목록에서 제거\n this.pendingFiles = this.pendingFiles.slice(1);\n\n // 모든 파일 처리가 완료되면 최종 메시지 출력\n if (this.pendingFiles.length === 0) {\n await this.finishHMR();\n }\n }\n\n private async finishHMR(): Promise<void> {\n await this.syncer.saveChecksums(await this.syncer.getCurrentChecksums());\n\n const endTime = Date.now();\n const totalTime = endTime - this.hmrStartTime;\n const msg = `HMR Done! ${chalk.bold.white(`${totalTime}ms`)}`;\n const margin = Math.max(0, (process.stdout.columns - msg.length) / 2);\n\n console.log(\n chalk.black.bgGreen(\" \".repeat(margin) + msg + \" \".repeat(margin))\n );\n }\n\n async destroy(): Promise<void> {\n const { BaseModel } = require(\"../database/base-model\");\n await BaseModel.destroy();\n await this.watcher?.close();\n this.storage?.destroy();\n }\n}\nexport const Sonamu = new SonamuClass();\n"],"names":["Sonamu","SonamuClass","isInitialized","asyncLocalStorage","AsyncLocalStorage","uploadStorage","_apiRootPath","_dbConfig","_syncer","_config","_secrets","_storage","watcher","pendingFiles","hmrStartTime","server","getContext","store","getStore","context","Error","getUploadContext","uploadContext","apiRootPath","appRootPath","split","path","sep","slice","join","dbConfig","syncer","config","secrets","storage","initForTesting","init","undefined","doSilent","enableSync","forTesting","configPath","secretsPath","EntityManager","Syncer","console","time","chalk","cyan","findApiRootPath","exists","JSON","parse","readFile","toString","DB","readKnexfile","log","green","attachOnDuplicateUpdate","autoload","autoloadModels","autoloadTypes","autoloadApis","isLocal","isTest","sync","startWatcher","syncUI","timeEnd","createServer","options","initOptions","fastify","plugins","registerPlugins","auth","session","registerAuth","withFastify","apiConfig","boot","timezone","DATE_FORMAT","ISO_DATE_REGEX","setReplySerializer","payload","stringify","_key","value","test","formatInTimeZone","Date","get","route","prefix","_request","_reply","apis","all","request","reply","found","find","api","url","httpMethod","method","toUpperCase","getApiHandler","NotFoundException","map","models","modelName","handler","ReqType","which","reqBody","messages","cacheKey","cacheTtl","cachedData","createSSE","model","guards","every","guard","guardHandler","getZodObjectFromApi","types","fastifyCaster","e","ZodError","humanizeZodError","issue","message","BadRequestException","zodError","type","contentType","cacheKeyRes","cache","resolveKey","key","ttl","error","_events","createSSEFactory","socket","bind","Promise","resolve","contextProvider","headers","user","passport","login","logout","run","result","methodName","apply","parameters","param","ApiParamType","isContext","name","put","watchPath","chokidar","require","watch","ignored","stats","isFile","endsWith","persistent","ignoreInitial","on","event","filePath","handleFileChange","runScript","fn","destroy","pluginsModules","cors","formbody","multipart","qs","sse","static","registerPlugin","pluginName","option","register","Object","entries","forEach","custom","fastifyPassport","initialize","secureSession","registerUserSerializer","registerUserDeserializer","serialized","userSerializer","userDeserializer","port","host","shutdown","listen","addHook","lifecycle","onShutdown","err","close","process","exit","onError","setErrorHandler","then","onStart","catch","red","relativePath","length","now","push","replace","bold","blue","syncFromWatcher","finishHMR","endTime","totalTime","msg","margin","saveChecksums","getCurrentChecksums","white","Math","max","stdout","columns","black","bgGreen","repeat","BaseModel"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/build-config.ts"],"sourcesContent":["/**\n * 빌드 결과물이 담길 디렉토리 경로\n */\nexport const BUILD_DIR = \"dist\";\n\n/**\n * SWC 빌드 명령어\n */\nexport const SWC_BUILD_COMMAND = `swc src -d ${BUILD_DIR} --strip-leading-paths --source-maps -C module.type=commonjs -C jsc.parser.syntax=typescript -C jsc.parser.decorators=true -C jsc.target=es5`;\n\n/**\n * TSC 타입 체크 명령어\n */\nexport const TSC_TYPE_CHECK_COMMAND = `tsc --noEmit`;\n"],"names":["BUILD_DIR","SWC_BUILD_COMMAND","TSC_TYPE_CHECK_COMMAND"],"mappings":"mPAGaA,mBAAAA,eAKAC,2BAAAA,uBAKAC,gCAAAA,0BAVN,IAAMF,UAAY,OAKlB,IAAMC,kBAAoB,AAAC,cAAuB,OAAVD,UAAU,gJAKlD,IAAME,uBAAyB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/cli-wrapper.ts"],"sourcesContent":["#!/usr/bin/env ts-node\n\nimport { spawnSync, execSync } from \"child_process\";\nimport { resolve } from \"path\";\nimport { existsSync, rmSync } from \"fs\";\nimport chalk from \"chalk\";\nimport {\n BUILD_DIR,\n SWC_BUILD_COMMAND,\n TSC_TYPE_CHECK_COMMAND,\n} from \"./build-config\";\n\nconst scriptPath = resolve(__dirname, \"cli.js\");\nconst args = process.argv.slice(2);\n\n// build 명령어는 dist 없이도 실행 가능하도록 cli.ts 외부에서 처리(Sonamu.init에서 dist 필요)\nfunction build() {\n try {\n console.log(chalk.blue(\"Removing build directory...\"));\n if (existsSync(BUILD_DIR)) {\n rmSync(BUILD_DIR, { recursive: true, force: true });\n }\n } catch (error) {\n console.error(chalk.red(\"Remove build directory failed.\"), error);\n process.exit(1);\n }\n\n try {\n console.log(chalk.blue(\"Building with swc...\"));\n execSync(SWC_BUILD_COMMAND, { cwd: process.cwd(), stdio: \"inherit\" });\n } catch (error) {\n console.error(chalk.red(\"Build failed.\"), error);\n process.exit(1);\n }\n}\n\nfunction checkTypes() {\n try {\n console.log(chalk.blue(\"Checking types with tsc...\"));\n execSync(TSC_TYPE_CHECK_COMMAND, {\n cwd: process.cwd(),\n stdio: \"inherit\",\n });\n } catch (error) {\n console.error(chalk.red(\"Type check failed.\"), error);\n process.exit(1);\n }\n}\n\nif (args[0] === \"build\") {\n console.log(chalk.blue(\"Building the project...\"));\n build();\n checkTypes();\n console.log(chalk.green(\"Build completed successfully.\"));\n process.exit(0);\n}\n\nif (args[0] === \"dev:serve\") {\n build();\n}\n\nif (!existsSync(scriptPath)) {\n console.error(`Error: Script not found at ${scriptPath}`);\n process.exit(1);\n}\n\nconst result = spawnSync(\n process.execPath,\n [\"-r\", \"source-map-support/register\", \"--no-warnings\", scriptPath, ...args],\n {\n stdio: \"inherit\",\n }\n);\n\nprocess.exit(result.status ?? 1);\n"],"names":["scriptPath","resolve","__dirname","args","process","argv","slice","build","console","log","chalk","blue","existsSync","BUILD_DIR","rmSync","recursive","force","error","red","exit","execSync","SWC_BUILD_COMMAND","cwd","stdio","checkTypes","TSC_TYPE_CHECK_COMMAND","green","result","spawnSync","execPath","status"],"mappings":";iGAEoC,mCACZ,wBACW,+DACjB,mCAKX,6rCAEP,IAAMA,WAAaC,GAAAA,aAAO,EAACC,UAAW,UACtC,IAAMC,KAAOC,QAAQC,IAAI,CAACC,KAAK,CAAC,GAGhC,SAASC,QACP,GAAI,CACFC,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,gCACvB,GAAIC,GAAAA,cAAU,EAACC,sBAAS,EAAG,CACzBC,GAAAA,UAAM,EAACD,sBAAS,CAAE,CAAEE,UAAW,KAAMC,MAAO,IAAK,EACnD,CACF,CAAE,MAAOC,MAAO,CACdT,QAAQS,KAAK,CAACP,cAAK,CAACQ,GAAG,CAAC,kCAAmCD,OAC3Db,QAAQe,IAAI,CAAC,EACf,CAEA,GAAI,CACFX,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,yBACvBS,GAAAA,uBAAQ,EAACC,8BAAiB,CAAE,CAAEC,IAAKlB,QAAQkB,GAAG,GAAIC,MAAO,SAAU,EACrE,CAAE,MAAON,MAAO,CACdT,QAAQS,KAAK,CAACP,cAAK,CAACQ,GAAG,CAAC,iBAAkBD,OAC1Cb,QAAQe,IAAI,CAAC,EACf,CACF,CAEA,SAASK,aACP,GAAI,CACFhB,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,+BACvBS,GAAAA,uBAAQ,EAACK,mCAAsB,CAAE,CAC/BH,IAAKlB,QAAQkB,GAAG,GAChBC,MAAO,SACT,EACF,CAAE,MAAON,MAAO,CACdT,QAAQS,KAAK,CAACP,cAAK,CAACQ,GAAG,CAAC,sBAAuBD,OAC/Cb,QAAQe,IAAI,CAAC,EACf,CACF,CAEA,GAAIhB,IAAI,CAAC,EAAE,GAAK,QAAS,CACvBK,QAAQC,GAAG,CAACC,cAAK,CAACC,IAAI,CAAC,4BACvBJ,QACAiB,aACAhB,QAAQC,GAAG,CAACC,cAAK,CAACgB,KAAK,CAAC,kCACxBtB,QAAQe,IAAI,CAAC,EACf,CAEA,GAAIhB,IAAI,CAAC,EAAE,GAAK,YAAa,CAC3BI,OACF,CAEA,GAAI,CAACK,GAAAA,cAAU,EAACZ,YAAa,CAC3BQ,QAAQS,KAAK,CAAC,AAAC,8BAAwC,OAAXjB,aAC5CI,QAAQe,IAAI,CAAC,EACf,CAEA,IAAMQ,OAASC,GAAAA,wBAAS,EACtBxB,QAAQyB,QAAQ,CAChB,CAAC,KAAM,8BAA+B,gBAAiB7B,WAAoB,CAA3E,OAAmE,qBAAGG,OACtE,CACEoB,MAAO,SACT,OAGWI,eAAbvB,QAAQe,IAAI,CAACQ,CAAAA,eAAAA,OAAOG,MAAM,UAAbH,wBAAAA,eAAiB"}
|
package/dist/bin/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/cli.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport dotenv from \"dotenv\";\ndotenv.config();\n\nimport path from \"path\";\nimport { tsicli } from \"tsicli\";\nimport { execSync } from \"child_process\";\nimport { mkdir, readdir, readFile, writeFile } from \"fs/promises\";\nimport { exists } from \"../utils/fs-utils\";\nimport process from \"process\";\nimport { Sonamu } from \"../api\";\nimport knex, { Knex } from \"knex\";\nimport { findApiRootPath } from \"../utils/utils\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { Migrator } from \"../migration/migrator\";\nimport { FixtureManager } from \"../testing/fixture-manager\";\n// import { SWC_BUILD_COMMAND } from \"./build-config\";\nimport { NodemonSettings } from \"nodemon\";\n\nlet migrator: Migrator;\n\nasync function bootstrap() {\n // dev:serve 명령어가 아닌 경우에만 Sonamu 초기화\n if (process.argv[2] !== \"dev:serve\") {\n await Sonamu.init(false, false);\n }\n\n await tsicli(process.argv, {\n types: {\n \"#entityId\": {\n type: \"autocomplete\",\n name: \"#entityId\",\n message: \"Please input #entityId\",\n choices: EntityManager.getAllParentIds().map((entityId) => ({\n title: entityId,\n value: entityId,\n })),\n },\n \"#recordIds\": \"number[]\",\n \"#name\": \"string\",\n },\n args: [\n [\"fixture\", \"init\"],\n [\"fixture\", \"import\", \"#entityId\", \"#recordIds\"],\n [\"fixture\", \"sync\"],\n [\"migrate\", \"run\"],\n [\"migrate\", \"check\"],\n [\"migrate\", \"rollback\"],\n [\"migrate\", \"reset\"],\n [\"migrate\", \"clear\"],\n [\"migrate\", \"status\"],\n [\"stub\", \"practice\", \"#name\"],\n [\"stub\", \"entity\", \"#name\"],\n [\"scaffold\", \"model\", \"#entityId\"],\n [\"scaffold\", \"model_test\", \"#entityId\"],\n [\"scaffold\", \"view_list\", \"#entityId\"],\n [\"scaffold\", \"view_form\", \"#entityId\"],\n [\"ui\"],\n [\"dev:serve\"],\n [\"serve\"],\n ],\n runners: {\n migrate_run,\n migrate_check,\n migrate_rollback,\n migrate_clear,\n migrate_reset,\n migrate_status,\n fixture_init,\n fixture_import,\n fixture_sync,\n stub_practice,\n stub_entity,\n scaffold_model,\n scaffold_model_test,\n ui,\n // scaffold_view_list,\n // scaffold_view_form,\n \"dev:serve\": dev_serve,\n serve,\n },\n });\n}\nbootstrap().finally(async () => {\n if (migrator) {\n await migrator.destroy();\n }\n await FixtureManager.destroy();\n});\n\nasync function dev_serve() {\n const nodemon = await import(\"nodemon\");\n\n const nodemonConfig = await (async () => {\n const projectNodemonPath = path.join(findApiRootPath(), \"nodemon.json\");\n const hasProjectNodemon = await exists(projectNodemonPath);\n\n if (hasProjectNodemon) {\n return JSON.parse(await readFile(projectNodemonPath, \"utf8\"));\n }\n\n return {\n watch: [\"src/index.ts\"],\n ignore: [\"dist/**\", \"**/*.js\", \"**/*.d.ts\"],\n exec: [\n // SWC_BUILD_COMMAND,\n \"node --no-warnings -r source-map-support/register -r dotenv/config dist/index.js\",\n ].join(\" && \"),\n } as NodemonSettings;\n })();\n nodemon.default(nodemonConfig);\n\n // 프로세스 종료 처리\n const cleanup = async () => {\n await Sonamu.server?.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n process.on(\"SIGUSR2\", cleanup);\n}\n\nasync function serve() {\n const distIndexPath = path.join(Sonamu.apiRootPath, \"dist\", \"index.js\");\n\n if (!(await exists(distIndexPath))) {\n console.log(\n chalk.red(\"dist/index.js not found. Please build your project first.\")\n );\n console.log(chalk.blue(\"Run: yarn sonamu build\"));\n return;\n }\n\n const { spawn } = await import(\"child_process\");\n const serverProcess = spawn(\n \"node\",\n [\"-r\", \"source-map-support/register\", \"-r\", \"dotenv/config\", distIndexPath],\n {\n cwd: Sonamu.apiRootPath,\n stdio: \"inherit\",\n }\n );\n\n process.on(\"SIGINT\", () => {\n serverProcess.kill(\"SIGTERM\");\n process.exit(0);\n });\n}\n\nasync function setupMigrator() {\n // migrator\n migrator = new Migrator({\n mode: \"dev\",\n });\n}\n\nasync function setupFixtureManager() {\n FixtureManager.init();\n}\n\nasync function migrate_run() {\n await setupMigrator();\n\n await migrator.cleanUpDist();\n await migrator.run();\n}\n\nasync function migrate_check() {\n await setupMigrator();\n\n await migrator.cleanUpDist();\n await migrator.check();\n}\n\nasync function migrate_status() {\n await setupMigrator();\n\n const status = await migrator.getStatus();\n // status;\n console.log(status);\n}\n\nasync function migrate_rollback() {\n await setupMigrator();\n\n await migrator.rollback();\n}\n\nasync function migrate_clear() {\n await setupMigrator();\n\n await migrator.clearPendingList();\n}\n\nasync function migrate_reset() {\n await setupMigrator();\n\n await migrator.resetAll();\n}\n\nasync function fixture_init() {\n const srcConfig = Sonamu.dbConfig.development_master;\n const targets = [\n {\n label: \"(REMOTE) Fixture DB\",\n config: Sonamu.dbConfig.fixture_remote,\n },\n {\n label: \"(LOCAL) Fixture DB\",\n config: Sonamu.dbConfig.fixture_local,\n toSkip: (() => {\n const remoteConn = Sonamu.dbConfig.fixture_remote\n .connection as Knex.ConnectionConfig;\n const localConn = Sonamu.dbConfig.fixture_local\n .connection as Knex.ConnectionConfig;\n return (\n remoteConn.host === localConn.host &&\n remoteConn.database === localConn.database\n );\n })(),\n },\n {\n label: \"(LOCAL) Testing DB\",\n config: Sonamu.dbConfig.test,\n },\n ] as {\n label: string;\n config: Knex.Config;\n toSkip?: boolean;\n }[];\n\n // 1. 기준DB 스키마를 덤프\n console.log(\"DUMP...\");\n const dumpFilename = `/tmp/sonamu-fixture-init-${Date.now()}.sql`;\n const srcConn = srcConfig.connection as Knex.ConnectionConfig;\n const migrationsDump = `/tmp/sonamu-fixture-init-migrations-${Date.now()}.sql`;\n execSync(\n `mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction -d --no-create-db --triggers ${srcConn.database} > ${dumpFilename}`\n );\n const _db = knex(srcConfig);\n const [[migrations]] = await _db.raw(\n \"SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = ? AND table_name = 'knex_migrations'\",\n [srcConn.database]\n );\n if (migrations.count > 0) {\n execSync(\n `mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction --no-create-db --triggers ${srcConn.database} knex_migrations knex_migrations_lock > ${migrationsDump}`\n );\n }\n\n // 2. 대상DB 각각에 대하여 존재여부 확인 후 붓기\n for await (const { label, config, toSkip } of targets) {\n const conn = config.connection as Knex.ConnectionConfig;\n\n if (toSkip === true) {\n console.log(chalk.red(`${label}: Skipped!`));\n continue;\n }\n\n const db = knex({\n ...config,\n connection: {\n ...((config.connection ?? {}) as Knex.ConnectionConfig),\n database: undefined,\n },\n });\n const [[row]] = await db.raw(`SHOW DATABASES LIKE \"${conn.database}\"`);\n if (row) {\n console.log(\n chalk.yellow(`${label}: Database \"${conn.database}\" Already exists`)\n );\n await db.destroy();\n continue;\n }\n\n console.log(`SYNC to ${label}...`);\n const mysqlCmd = `mysql -h${conn.host} -u${conn.user} -p${conn.password}`;\n execSync(`${mysqlCmd} -e 'DROP DATABASE IF EXISTS \\`${conn.database}\\`'`);\n execSync(`${mysqlCmd} -e 'CREATE DATABASE \\`${conn.database}\\`'`);\n execSync(`${mysqlCmd} ${conn.database} < ${dumpFilename}`);\n if (await exists(migrationsDump)) {\n execSync(`${mysqlCmd} ${conn.database} < ${migrationsDump}`);\n }\n\n await db.destroy();\n }\n\n await _db.destroy();\n}\n\nasync function fixture_import(entityId: string, recordIds: number[]) {\n await setupFixtureManager();\n\n await FixtureManager.importFixture(entityId, recordIds);\n await FixtureManager.sync();\n}\n\nasync function fixture_sync() {\n await setupFixtureManager();\n\n await FixtureManager.sync();\n}\n\nasync function stub_practice(name: string) {\n const practiceDir = path.join(Sonamu.apiRootPath, \"src\", \"practices\");\n const fileNames = await readdir(practiceDir);\n\n const maxSeqNo = await (async () => {\n if (!(await exists(practiceDir))) {\n await mkdir(practiceDir, { recursive: true });\n }\n\n const filteredSeqs = fileNames\n .filter(\n (fileName) => fileName.startsWith(\"p\") && fileName.endsWith(\".ts\")\n )\n .map((fileName) => {\n const [, seqNo] = fileName.match(/^p([0-9]+)\\-/) ?? [\"0\", \"0\"];\n return parseInt(seqNo);\n })\n .sort((a, b) => b - a);\n\n if (filteredSeqs.length > 0) {\n return filteredSeqs[0];\n }\n\n return 0;\n })();\n\n const currentSeqNo = maxSeqNo + 1;\n const fileName = `p${currentSeqNo}-${name}.ts`;\n const dstPath = path.join(practiceDir, fileName);\n\n const code = [\n `import { Sonamu } from \"sonamu\";`,\n \"\",\n `console.clear();`,\n `console.log(\"${fileName}\");`,\n \"\",\n `Sonamu.runScript(async () => {`,\n ` // TODO`,\n `});`,\n \"\",\n ].join(\"\\n\");\n await writeFile(dstPath, code);\n\n execSync(`code ${dstPath}`);\n\n const runCode = `yarn node -r dotenv/config -r source-map-support/register dist/practices/${fileName.replace(\n \".ts\",\n \".js\"\n )}`;\n console.log(`${chalk.blue(runCode)} copied to clipboard.`);\n execSync(`echo \"${runCode}\" | pbcopy`);\n}\n\nasync function stub_entity(entityId: string) {\n await Sonamu.syncer.createEntity({ entityId });\n}\n\nasync function scaffold_model(entityId: string) {\n await Sonamu.syncer.generateTemplate(\"model\", {\n entityId,\n });\n}\n\nasync function scaffold_model_test(entityId: string) {\n await Sonamu.syncer.generateTemplate(\"model_test\", {\n entityId,\n });\n}\n\nasync function ui() {\n try {\n type StartServersOptions = {\n projectName: string;\n apiRootPath: string;\n port: number;\n };\n const sonamuUI: {\n startServers: (options: StartServersOptions) => void;\n } = await import(\"@sonamu-kit/ui\" as string);\n sonamuUI.startServers({\n projectName:\n Sonamu.config.projectName ?? path.basename(Sonamu.apiRootPath),\n apiRootPath: Sonamu.apiRootPath,\n port: Sonamu.config.ui?.port ?? 57000,\n });\n } catch (e: unknown) {\n if (e instanceof Error && e.message.includes(\"isn't declared\")) {\n console.log(`You need to install ${chalk.blue(`@sonamu-kit/ui`)} first.`);\n return;\n }\n throw e;\n }\n}\n"],"names":["dotenv","config","migrator","bootstrap","process","argv","Sonamu","init","tsicli","types","type","name","message","choices","EntityManager","getAllParentIds","map","entityId","title","value","args","runners","migrate_run","migrate_check","migrate_rollback","migrate_clear","migrate_reset","migrate_status","fixture_init","fixture_import","fixture_sync","stub_practice","stub_entity","scaffold_model","scaffold_model_test","ui","dev_serve","serve","finally","destroy","FixtureManager","nodemon","nodemonConfig","cleanup","projectNodemonPath","hasProjectNodemon","path","join","findApiRootPath","exists","JSON","parse","readFile","watch","ignore","exec","default","server","close","exit","on","distIndexPath","spawn","serverProcess","apiRootPath","console","log","chalk","red","blue","cwd","stdio","kill","setupMigrator","Migrator","mode","setupFixtureManager","cleanUpDist","run","check","status","getStatus","rollback","clearPendingList","resetAll","srcConfig","targets","dumpFilename","srcConn","migrationsDump","_db","migrations","label","toSkip","conn","db","row","mysqlCmd","dbConfig","development_master","fixture_remote","fixture_local","remoteConn","connection","localConn","host","database","test","Date","now","execSync","user","password","knex","raw","count","undefined","yellow","recordIds","importFixture","sync","practiceDir","fileNames","maxSeqNo","currentSeqNo","fileName","dstPath","code","runCode","readdir","filteredSeqs","mkdir","recursive","filter","startsWith","endsWith","match","seqNo","parseInt","sort","a","b","length","writeFile","replace","syncer","createEntity","generateTemplate","sonamuUI","e","startServers","projectName","basename","port","Error","includes"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/database/_batch_update.ts"],"sourcesContent":["/*\n 아래의 링크에서 참고해서 가져온 소스코드\n https://github.com/knex/knex/issues/5716\n*/\n\nimport { Knex } from \"knex\";\n\nexport type RowWithId<Id extends string> = {\n [key in Id]: any;\n} & Record<string, any>;\n\n/**\n * Batch update rows in a table. Technically its a patch since it only updates the specified columns. Any omitted columns will not be affected\n * @param db\n * @param tableName\n * @param ids\n * @param rows\n * @param chunkSize\n * @param trx\n */\nexport async function batchUpdate<Id extends string>(\n knex: Knex,\n tableName: string,\n ids: Id[],\n rows: RowWithId<Id>[],\n chunkSize = 50,\n trx: Knex.Transaction | null = null\n) {\n const chunks: RowWithId<Id>[][] = [];\n for (let i = 0; i < rows.length; i += chunkSize) {\n chunks.push(rows.slice(i, i + chunkSize));\n }\n\n const executeUpdate = async (\n chunk: RowWithId<Id>[],\n transaction: Knex.Transaction\n ) => {\n const sql = generateBatchUpdateSQL(knex, tableName, chunk, ids);\n return knex.raw(sql).transacting(transaction);\n };\n\n if (trx) {\n for (const chunk of chunks) {\n await executeUpdate(chunk, trx);\n }\n } else {\n await knex.transaction(async (newTrx) => {\n for (const chunk of chunks) {\n await executeUpdate(chunk, newTrx);\n }\n });\n }\n}\n\n/**\n * Generate a set of unique keys in a data array\n *\n * Example:\n * [ { a: 1, b: 2 }, { a: 3, c: 4 } ] => Set([ \"a\", \"b\", \"c\" ])\n * @param data\n */\nfunction generateKeySetFromData(data: Record<string, any>[]) {\n const keySet: Set<string> = new Set();\n for (const row of data) {\n for (const key of Object.keys(row)) {\n keySet.add(key);\n }\n }\n return keySet;\n}\n\nfunction generateBatchUpdateSQL<Id extends string>(\n db: Knex,\n tableName: string,\n data: Record<string, any>[],\n identifiers: Id[]\n) {\n const keySet = generateKeySetFromData(data);\n const bindings = [];\n\n const invalidIdentifiers = identifiers.filter((id) => !keySet.has(id));\n if (invalidIdentifiers.length > 0) {\n throw new Error(\n `Invalid identifiers: ${invalidIdentifiers.join(\", \")}. Identifiers must exist in the data`\n );\n }\n\n const cases = [];\n for (const key of keySet) {\n if (identifiers.includes(key as Id)) continue;\n\n const rows = [];\n for (const row of data) {\n if (Object.hasOwnProperty.call(row, key)) {\n const whereClause = identifiers\n .map((id) => `\\`${id}\\` = ?`)\n .join(\" AND \");\n rows.push(`WHEN (${whereClause}) THEN ?`);\n bindings.push(...identifiers.map((i) => row[i]), row[key]);\n }\n }\n\n const whenThen = rows.join(\" \");\n cases.push(`\\`${key}\\` = CASE ${whenThen} ELSE \\`${key}\\` END`);\n }\n\n const whereInClauses = identifiers\n .map((col) => `${col} IN (${data.map(() => \"?\").join(\", \")})`)\n .join(\" AND \");\n\n const whereInBindings = identifiers.flatMap((col) =>\n data.map((row) => row[col])\n );\n\n const sql = db.raw(\n `UPDATE \\`${tableName}\\` SET ${cases.join(\", \")} WHERE ${whereInClauses}`,\n [...bindings, ...whereInBindings]\n );\n\n return sql.toQuery();\n}\n"],"names":["batchUpdate","knex","tableName","ids","rows","chunkSize","trx","chunks","i","executeUpdate","chunk","length","push","slice","transaction","sql","generateBatchUpdateSQL","raw","transacting","newTrx","generateKeySetFromData","data","keySet","Set","row","Object","keys","key","add","db","identifiers","bindings","invalidIdentifiers","filter","id","has","Error","join","cases","includes","hasOwnProperty","call","whereClause","map","whenThen","whereInClauses","col","whereInBindings","flatMap","toQuery"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/database/base-model.ts"],"sourcesContent":["import { DateTime } from \"luxon\";\nimport { Knex } from \"knex\";\nimport { chunk, groupBy, isObject, omit, set, uniq } from \"lodash\";\nimport { DBPreset, DB } from \"./db\";\nimport { isCustomJoinClause, type SubsetQuery } from \"../types/types\";\nimport type { BaseListParams } from \"../utils/model\";\nimport inflection from \"inflection\";\nimport chalk from \"chalk\";\nimport { UpsertBuilder } from \"./upsert-builder\";\nimport SqlParser from \"node-sql-parser\";\nimport { getTableName, getTableNamesFromWhere } from \"../utils/sql-parser\";\nimport { PuriWrapper } from \"./puri-wrapper\";\n\nexport class BaseModelClass {\n public modelName: string = \"Unknown\";\n\n /* DB 인스턴스 get, destroy */\n getDB(which: DBPreset): Knex {\n return DB.getDB(which);\n }\n\n getPuri(which: DBPreset): PuriWrapper {\n // 트랜잭션 컨텍스트에서 트랜잭션 획득\n const trx = DB.getTransactionContext().getTransaction(which);\n if (trx) {\n return trx;\n }\n\n // 트랜잭션이 없으면 새로운 PuriWrapper 반환\n const db = this.getDB(which);\n return new PuriWrapper(db, this.getUpsertBuilder());\n }\n\n async destroy() {\n return DB.destroy();\n }\n\n myNow(timestamp?: number): string {\n const dt: DateTime =\n timestamp === undefined\n ? DateTime.local()\n : DateTime.fromSeconds(timestamp);\n return dt.toFormat(\"yyyy-MM-dd HH:mm:ss\");\n }\n\n async getInsertedIds(\n wdb: Knex,\n rows: any[],\n tableName: string,\n unqKeyFields: string[],\n chunkSize: number = 500\n ) {\n if (!wdb) {\n wdb = this.getDB(\"w\");\n }\n\n let unqKeys: string[];\n let whereInField: any, selectField: string;\n if (unqKeyFields.length > 1) {\n whereInField = wdb.raw(`CONCAT_WS('_', '${unqKeyFields.join(\",\")}')`);\n selectField = `${whereInField} as tmpUid`;\n unqKeys = rows.map((row) =>\n unqKeyFields.map((field) => row[field]).join(\"_\")\n );\n } else {\n whereInField = unqKeyFields[0];\n selectField = unqKeyFields[0];\n unqKeys = rows.map((row) => row[unqKeyFields[0]]);\n }\n const chunks = chunk(unqKeys, chunkSize);\n\n let resultIds: number[] = [];\n for (let chunk of chunks) {\n const dbRows = await wdb(tableName)\n .select(\"id\", wdb.raw(selectField))\n .whereIn(whereInField, chunk);\n resultIds = resultIds.concat(\n dbRows.map((dbRow: any) => parseInt(dbRow.id))\n );\n }\n\n return resultIds;\n }\n\n async useLoaders(db: Knex, rows: any[], loaders: SubsetQuery[\"loaders\"]) {\n if (loaders.length === 0) {\n return rows;\n }\n\n for (let loader of loaders) {\n let subQ: any;\n let subRows: any[];\n let toCol: string;\n\n const fromIds = rows.map((row) => row[loader.manyJoin.idField]);\n\n if (loader.manyJoin.through === undefined) {\n // HasMany\n const idColumn = `${loader.manyJoin.toTable}.${loader.manyJoin.toCol}`;\n subQ = db(loader.manyJoin.toTable)\n .whereIn(idColumn, fromIds)\n .select([...loader.select, idColumn]);\n\n // HasMany에서 OneJoin이 있는 경우\n loader.oneJoins.map((join) => {\n if (join.join == \"inner\") {\n subQ.innerJoin(\n `${join.table} as ${join.as}`,\n this.getJoinClause(db, join)\n );\n } else if (join.join == \"outer\") {\n subQ.leftOuterJoin(\n `${join.table} as ${join.as}`,\n this.getJoinClause(db, join)\n );\n }\n });\n toCol = loader.manyJoin.toCol;\n } else {\n // ManyToMany\n const idColumn = `${loader.manyJoin.through.table}.${loader.manyJoin.through.fromCol}`;\n subQ = db(loader.manyJoin.through.table)\n .join(\n loader.manyJoin.toTable,\n `${loader.manyJoin.through.table}.${loader.manyJoin.through.toCol}`,\n `${loader.manyJoin.toTable}.${loader.manyJoin.toCol}`\n )\n .whereIn(idColumn, fromIds)\n .select(uniq([...loader.select, idColumn]));\n\n // ManyToMany에서 OneJoin이 있는 경우\n loader.oneJoins.map((join) => {\n if (join.join == \"inner\") {\n subQ.innerJoin(\n `${join.table} as ${join.as}`,\n this.getJoinClause(db, join)\n );\n } else if (join.join == \"outer\") {\n subQ.leftOuterJoin(\n `${join.table} as ${join.as}`,\n this.getJoinClause(db, join)\n );\n }\n });\n toCol = loader.manyJoin.through.fromCol;\n }\n subRows = await subQ;\n\n if (loader.loaders) {\n // 추가 -Many 케이스가 있는 경우 recursion 처리\n subRows = await this.useLoaders(db, subRows, loader.loaders);\n }\n\n // 불러온 row들을 참조ID 기준으로 분류 배치\n const subRowGroups = groupBy(subRows, toCol);\n rows = rows.map((row) => {\n row[loader.as] = (subRowGroups[row[loader.manyJoin.idField]] ?? []).map(\n (r) => omit(r, toCol)\n );\n return row;\n });\n }\n return rows;\n }\n\n hydrate<T>(rows: T[]): T[] {\n return rows.map((row: any) => {\n // nullable relation인 경우 관련된 필드가 전부 null로 생성되는 것 방지하는 코드\n const nestedKeys = Object.keys(row).filter((key) => key.includes(\"__\"));\n const groups = groupBy(nestedKeys, (key) => key.split(\"__\")[0]);\n const nullKeys = Object.keys(groups).filter(\n (key) =>\n groups[key].length > 1 &&\n groups[key].every(\n (field) =>\n row[field] === null ||\n (Array.isArray(row[field]) && row[field].length === 0)\n )\n );\n\n const hydrated = Object.keys(row).reduce((r, field) => {\n if (!field.includes(\"__\")) {\n if (Array.isArray(row[field]) && isObject(row[field][0])) {\n r[field] = this.hydrate(row[field]);\n return r;\n } else {\n r[field] = row[field];\n return r;\n }\n }\n\n const parts = field.split(\"__\");\n const objPath =\n parts[0] +\n parts\n .slice(1)\n .map((part) => `[${part}]`)\n .join(\"\");\n set(\n r,\n objPath,\n row[field] && Array.isArray(row[field]) && isObject(row[field][0])\n ? this.hydrate(row[field])\n : row[field]\n );\n\n return r;\n }, {} as any);\n nullKeys.map((nullKey) => (hydrated[nullKey] = null));\n\n return hydrated;\n });\n }\n\n async runSubsetQuery<T extends BaseListParams, U extends string>({\n params,\n baseTable,\n subset,\n subsetQuery,\n build,\n afterBuild,\n debug,\n db: _db,\n optimizeCountQuery,\n }: {\n subset: U;\n params: T;\n subsetQuery: SubsetQuery;\n build: (buildParams: {\n qb: Knex.QueryBuilder;\n db: Knex;\n select: (string | Knex.Raw)[];\n joins: SubsetQuery[\"joins\"];\n virtual: string[];\n }) => Knex.QueryBuilder;\n afterBuild?: (buildParams: {\n qb: Knex.QueryBuilder;\n db: Knex;\n select: (string | Knex.Raw)[];\n joins: SubsetQuery[\"joins\"];\n virtual: string[];\n }) => Knex.QueryBuilder;\n baseTable?: string;\n debug?: boolean | \"list\" | \"count\";\n db?: Knex;\n optimizeCountQuery?: boolean;\n }): Promise<{\n rows: any[];\n total?: number | undefined;\n subsetQuery: SubsetQuery;\n qb: Knex.QueryBuilder;\n }> {\n const db = _db ?? this.getDB(subset.startsWith(\"A\") ? \"w\" : \"r\");\n baseTable =\n baseTable ?? inflection.pluralize(inflection.underscore(this.modelName));\n const queryMode =\n params.queryMode ?? (params.id !== undefined ? \"list\" : \"both\");\n\n const { select, virtual, joins, loaders } = subsetQuery;\n const qb = build({\n qb: db.from(baseTable),\n db,\n select,\n joins,\n virtual,\n });\n\n const applyJoinClause = (\n qb: Knex.QueryBuilder,\n joins: SubsetQuery[\"joins\"]\n ) => {\n joins.map((join) => {\n if (join.join == \"inner\") {\n qb.innerJoin(\n `${join.table} as ${join.as}`,\n this.getJoinClause(db, join)\n );\n } else if (join.join == \"outer\") {\n qb.leftOuterJoin(\n `${join.table} as ${join.as}`,\n this.getJoinClause(db, join)\n );\n }\n });\n };\n\n // countQuery\n const total = await (async () => {\n if (queryMode === \"list\") {\n return undefined;\n }\n\n const clonedQb = qb.clone().clear(\"order\").clear(\"offset\").clear(\"limit\");\n const parser = new SqlParser.Parser();\n\n // optmizeCountQuery가 true인 경우 다른 clause에 영향을 주지 않는 모든 join을 제외함\n if (optimizeCountQuery) {\n const parsedQuery = parser.astify(clonedQb.toQuery());\n const tables = getTableNamesFromWhere(parsedQuery);\n // where절에 사용되는 테이블의 조인을 위해 사용되는 테이블\n const needToJoin = uniq(\n tables.flatMap((table) =>\n table.split(\"__\").map((t) => inflection.pluralize(t))\n )\n );\n applyJoinClause(\n clonedQb,\n joins.filter((j) => needToJoin.includes(j.table))\n );\n } else {\n applyJoinClause(clonedQb, joins);\n }\n\n const processedQb =\n afterBuild?.({\n qb: clonedQb,\n db,\n select,\n joins,\n virtual,\n }) ?? clonedQb;\n\n const parsedQuery = parser.astify(processedQb.toQuery());\n const q = Array.isArray(parsedQuery) ? parsedQuery[0] : parsedQuery;\n if (q.type !== \"select\") {\n throw new Error(\"Invalid query\");\n }\n\n const countQuery =\n q.distinct !== null\n ? clonedQb\n .clear(\"select\")\n .select(\n db.raw(\n `COUNT(DISTINCT \\`${getTableName(q.columns[0].expr)}\\`.\\`${q.columns[0].expr.column}\\`) as total`\n )\n )\n .first()\n : clonedQb.clear(\"select\").count(\"*\", { as: \"total\" }).first();\n const countRow: { total?: number } = await countQuery;\n\n // debug: countQuery\n if (debug === true || debug === \"count\") {\n console.debug(\n \"DEBUG: count query\",\n chalk.blue(countQuery.toQuery().toString())\n );\n }\n\n return countRow?.total ?? 0;\n })();\n\n // listQuery\n const rows = await (async () => {\n if (queryMode === \"count\") {\n return [];\n }\n\n // limit, offset\n if (params.num !== 0) {\n qb.limit(params.num!);\n qb.offset(params.num! * (params.page! - 1));\n }\n\n // select, rows\n const clonedQb = qb.clone().select(select);\n\n // join\n applyJoinClause(clonedQb, joins);\n\n const listQuery =\n afterBuild?.({\n qb: clonedQb,\n db,\n select,\n joins,\n virtual,\n }) ?? clonedQb;\n\n let rows = await listQuery;\n // debug: listQuery\n if (debug === true || debug === \"list\") {\n console.debug(\n \"DEBUG: list query\",\n chalk.blue(listQuery.toQuery().toString())\n );\n }\n\n rows = await this.useLoaders(db, rows, loaders);\n rows = this.hydrate(rows);\n return rows;\n })();\n\n return { rows, total, subsetQuery, qb };\n }\n\n getJoinClause(\n db: Knex<any, unknown>,\n join: SubsetQuery[\"joins\"][number]\n ): Knex.Raw<any> {\n if (!isCustomJoinClause(join)) {\n return db.raw(`${join.from} = ${join.to}`);\n } else {\n return db.raw(join.custom);\n }\n }\n\n getUpsertBuilder(): UpsertBuilder {\n return new UpsertBuilder();\n }\n}\nexport const BaseModel = new BaseModelClass();\n"],"names":["BaseModel","BaseModelClass","modelName","getDB","which","DB","getPuri","trx","getTransactionContext","getTransaction","db","PuriWrapper","getUpsertBuilder","destroy","myNow","timestamp","dt","undefined","DateTime","local","fromSeconds","toFormat","getInsertedIds","wdb","rows","tableName","unqKeyFields","chunkSize","unqKeys","whereInField","selectField","chunks","resultIds","chunk","dbRows","length","raw","join","map","row","field","select","whereIn","concat","dbRow","parseInt","id","useLoaders","loaders","loader","subQ","subRows","toCol","fromIds","idColumn","subRowGroups","manyJoin","idField","through","toTable","oneJoins","innerJoin","table","as","getJoinClause","leftOuterJoin","fromCol","uniq","groupBy","r","omit","hydrate","nestedKeys","Object","keys","filter","key","includes","groups","split","nullKeys","every","Array","isArray","hydrated","reduce","isObject","parts","objPath","slice","part","set","nullKey","runSubsetQuery","params","baseTable","subset","subsetQuery","build","afterBuild","debug","_db","optimizeCountQuery","queryMode","virtual","joins","qb","applyJoinClause","total","startsWith","inflection","pluralize","underscore","from","clonedQb","parser","parsedQuery","tables","needToJoin","processedQb","q","countQuery","countRow","clone","clear","SqlParser","Parser","astify","toQuery","getTableNamesFromWhere","flatMap","t","j","type","Error","distinct","getTableName","columns","expr","column","first","count","console","chalk","blue","toString","listQuery","num","limit","offset","page","isCustomJoinClause","to","custom","UpsertBuilder"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/database/code-generator.ts"],"sourcesContent":["import _ from \"lodash\";\nimport equal from \"fast-deep-equal\";\nimport { MigrationColumn, MigrationIndex } from \"../types/types\";\n\nexport class CodeGenerator {\n getAlterColumnsTo(\n entityColumns: MigrationColumn[],\n dbColumns: MigrationColumn[]\n ) {\n const columnsTo = {\n add: [] as MigrationColumn[],\n drop: [] as MigrationColumn[],\n alter: [] as MigrationColumn[],\n };\n\n // 컬럼명 기준 비교\n const extraColumns = {\n db: _.differenceBy(dbColumns, entityColumns, (col) => col.name),\n entity: _.differenceBy(entityColumns, dbColumns, (col) => col.name),\n };\n if (extraColumns.entity.length > 0) {\n columnsTo.add = columnsTo.add.concat(extraColumns.entity);\n }\n if (extraColumns.db.length > 0) {\n columnsTo.drop = columnsTo.drop.concat(extraColumns.db);\n }\n\n // 동일 컬럼명의 세부 필드 비교\n const sameDbColumns = _.intersectionBy(\n dbColumns,\n entityColumns,\n (col) => col.name\n );\n const sameMdColumns = _.intersectionBy(\n entityColumns,\n dbColumns,\n (col) => col.name\n );\n columnsTo.alter = _.differenceWith(sameDbColumns, sameMdColumns, (a, b) =>\n equal(a, b)\n );\n\n return columnsTo;\n }\n\n getAlterIndexesTo(\n entityIndexes: MigrationIndex[],\n dbIndexes: MigrationIndex[]\n ) {\n // 인덱스 비교\n let indexesTo = {\n add: [] as MigrationIndex[],\n drop: [] as MigrationIndex[],\n };\n const extraIndexes = {\n db: _.differenceBy(dbIndexes, entityIndexes, (col) =>\n [col.type, col.columns.join(\"-\")].join(\"//\")\n ),\n entity: _.differenceBy(entityIndexes, dbIndexes, (col) =>\n [col.type, col.columns.join(\"-\")].join(\"//\")\n ),\n };\n if (extraIndexes.entity.length > 0) {\n indexesTo.add = indexesTo.add.concat(extraIndexes.entity);\n }\n if (extraIndexes.db.length > 0) {\n indexesTo.drop = indexesTo.drop.concat(extraIndexes.db);\n }\n\n return indexesTo;\n }\n}\n"],"names":["CodeGenerator","getAlterColumnsTo","entityColumns","dbColumns","columnsTo","add","drop","alter","extraColumns","db","_","differenceBy","col","name","entity","length","concat","sameDbColumns","intersectionBy","sameMdColumns","differenceWith","a","b","equal","getAlterIndexesTo","entityIndexes","dbIndexes","indexesTo","extraIndexes","type","columns","join"],"mappings":"oGAIaA,uDAAAA,2EAJC,4EACI,+tBAGX,IAAA,AAAMA,2BAAN,iCAAMA,uCAAAA,6BAAAA,gBACXC,IAAAA,0BAAAA,SAAAA,kBACEC,aAAgC,CAChCC,SAA4B,EAE5B,IAAMC,UAAY,CAChBC,IAAK,EAAE,CACPC,KAAM,EAAE,CACRC,MAAO,EAAE,AACX,EAGA,IAAMC,aAAe,CACnBC,GAAIC,eAAC,CAACC,YAAY,CAACR,UAAWD,cAAe,SAACU,YAAQA,IAAIC,IAAI,GAC9DC,OAAQJ,eAAC,CAACC,YAAY,CAACT,cAAeC,UAAW,SAACS,YAAQA,IAAIC,IAAI,EACpE,EACA,GAAIL,aAAaM,MAAM,CAACC,MAAM,CAAG,EAAG,CAClCX,UAAUC,GAAG,CAAGD,UAAUC,GAAG,CAACW,MAAM,CAACR,aAAaM,MAAM,CAC1D,CACA,GAAIN,aAAaC,EAAE,CAACM,MAAM,CAAG,EAAG,CAC9BX,UAAUE,IAAI,CAAGF,UAAUE,IAAI,CAACU,MAAM,CAACR,aAAaC,EAAE,CACxD,CAGA,IAAMQ,cAAgBP,eAAC,CAACQ,cAAc,CACpCf,UACAD,cACA,SAACU,YAAQA,IAAIC,IAAI,GAEnB,IAAMM,cAAgBT,eAAC,CAACQ,cAAc,CACpChB,cACAC,UACA,SAACS,YAAQA,IAAIC,IAAI,EAEnBT,CAAAA,UAAUG,KAAK,CAAGG,eAAC,CAACU,cAAc,CAACH,cAAeE,cAAe,SAACE,EAAGC,SACnEC,GAAAA,sBAAK,EAACF,EAAGC,KAGX,OAAOlB,SACT,IAEAoB,IAAAA,0BAAAA,SAAAA,kBACEC,aAA+B,CAC/BC,SAA2B,EAG3B,IAAIC,UAAY,CACdtB,IAAK,EAAE,CACPC,KAAM,EAAE,AACV,EACA,IAAMsB,aAAe,CACnBnB,GAAIC,eAAC,CAACC,YAAY,CAACe,UAAWD,cAAe,SAACb,WAC5C,CAACA,IAAIiB,IAAI,CAAEjB,IAAIkB,OAAO,CAACC,IAAI,CAAC,KAAK,CAACA,IAAI,CAAC,QAEzCjB,OAAQJ,eAAC,CAACC,YAAY,CAACc,cAAeC,UAAW,SAACd,WAChD,CAACA,IAAIiB,IAAI,CAAEjB,IAAIkB,OAAO,CAACC,IAAI,CAAC,KAAK,CAACA,IAAI,CAAC,OAE3C,EACA,GAAIH,aAAad,MAAM,CAACC,MAAM,CAAG,EAAG,CAClCY,UAAUtB,GAAG,CAAGsB,UAAUtB,GAAG,CAACW,MAAM,CAACY,aAAad,MAAM,CAC1D,CACA,GAAIc,aAAanB,EAAE,CAACM,MAAM,CAAG,EAAG,CAC9BY,UAAUrB,IAAI,CAAGqB,UAAUrB,IAAI,CAACU,MAAM,CAACY,aAAanB,EAAE,CACxD,CAEA,OAAOkB,SACT,YAlEW3B"}
|
package/dist/database/db.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/database/db.ts"],"sourcesContent":["export type DBPreset = \"w\" | \"r\";\nimport knex, { Knex } from \"knex\";\nimport path from \"path\";\nimport _ from \"lodash\";\nimport { Sonamu } from \"../api\";\nimport { ServiceUnavailableException } from \"../exceptions/so-exceptions\";\nimport { AsyncLocalStorage } from \"async_hooks\";\nimport { TransactionContext } from \"./transaction-context\";\n\ntype MySQLConfig = Omit<Knex.Config, \"connection\"> & {\n connection?: Knex.MySql2ConnectionConfig;\n};\n\nexport type SonamuDBBaseConfig = {\n // 기본 데이터베이스 이름\n database: string;\n\n // 모든 환경에 적용될 기본 Knex 옵션\n defaultOptions?: MySQLConfig;\n\n // 환경별 설정\n environments?: {\n development?: MySQLConfig;\n development_slave?: MySQLConfig;\n production?: MySQLConfig;\n production_slave?: MySQLConfig;\n remote_fixture?: MySQLConfig;\n };\n};\n\nexport type SonamuDBConfig = {\n development_master: Knex.Config;\n development_slave: Knex.Config;\n test: Knex.Config;\n fixture_local: Knex.Config;\n fixture_remote: Knex.Config;\n production_master: Knex.Config;\n production_slave: Knex.Config;\n};\n\nclass DBClass {\n private wdb?: Knex;\n private rdb?: Knex;\n\n public transactionStorage = new AsyncLocalStorage<TransactionContext>();\n\n public runWithTransaction<T>(callback: () => Promise<T>): Promise<T> {\n return this.transactionStorage.run(new TransactionContext(), callback);\n }\n\n public getTransactionContext(): TransactionContext {\n return this.transactionStorage.getStore() ?? new TransactionContext();\n }\n\n async readKnexfile(): Promise<SonamuDBConfig> {\n const dbConfigPath: string = path.join(\n Sonamu.apiRootPath,\n \"/dist/configs/db.js\"\n );\n try {\n const knexfileModule = await import(dbConfigPath);\n const config =\n knexfileModule.default?.default ??\n knexfileModule.default ??\n knexfileModule;\n return this.generateDBConfig(config);\n } catch {}\n\n throw new ServiceUnavailableException(\n `다음 경로에서 DB설정 파일을 찾을 수 없습니다: ${dbConfigPath}. 먼저 빌드(yarn build)를 수행해주세요.`\n );\n }\n\n getDB(which: DBPreset): Knex {\n const dbConfig = Sonamu.dbConfig;\n\n // 테스트 트랜잭션 격리\n if (process.env.NODE_ENV === \"test\") {\n if (this.testTransaction) {\n return this.testTransaction;\n } else if (this.wdb) {\n return this.wdb;\n } else {\n this[\"wdb\"] = knex({\n ...dbConfig[\"test\"],\n // 단일 풀\n pool: {\n min: 1,\n max: 1,\n },\n });\n return this[\"wdb\"];\n }\n }\n\n const instanceName = which === \"w\" ? \"wdb\" : \"rdb\";\n\n if (!this[instanceName]) {\n let config: Knex.Config;\n switch (process.env.NODE_ENV ?? \"development\") {\n case \"development\":\n case \"staging\":\n config =\n which === \"w\"\n ? dbConfig[\"development_master\"]\n : (dbConfig[\"development_slave\"] ??\n dbConfig[\"development_master\"]);\n break;\n case \"production\":\n config =\n which === \"w\"\n ? dbConfig[\"production_master\"]\n : (dbConfig[\"production_slave\"] ?? dbConfig[\"production_master\"]);\n break;\n default:\n throw new Error(\n `현재 ENV ${process.env.NODE_ENV}에는 설정 가능한 DB설정이 없습니다.`\n );\n }\n this[instanceName] = knex(config);\n }\n\n return this[instanceName]!;\n }\n\n async destroy(): Promise<void> {\n if (this.wdb !== undefined) {\n await this.wdb.destroy();\n this.wdb = undefined;\n }\n if (this.rdb !== undefined) {\n await this.rdb.destroy();\n this.rdb = undefined;\n }\n }\n\n private generateDBConfig(config: SonamuDBBaseConfig): SonamuDBConfig {\n const defaultKnexConfig: Partial<MySQLConfig> = _.merge(\n {\n client: \"mysql2\",\n pool: {\n min: 1,\n max: 5,\n },\n migrations: {\n extension: \"js\",\n directory: \"./dist/migrations\",\n },\n connection: {\n database: config.database,\n ...config.defaultOptions?.connection,\n },\n },\n config.defaultOptions\n );\n\n // 로컬 환경 설정\n const test: MySQLConfig = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_test`,\n ...config.defaultOptions?.connection,\n },\n });\n\n const fixture_local = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_fixture_local`,\n ...config.defaultOptions?.connection,\n },\n });\n\n // 개발 환경 설정\n const devMasterOptions = config.environments?.development;\n const devSlaveOptions = config.environments?.development_slave;\n const development_master = _.merge({}, defaultKnexConfig, devMasterOptions);\n const development_slave = _.merge(\n {},\n defaultKnexConfig,\n devMasterOptions,\n devSlaveOptions\n );\n // NOTE: fixture remote는 default connection의 DB를 override해선 안됨.\n const fixture_remote = _.merge(\n {},\n defaultKnexConfig,\n devMasterOptions,\n {\n connection: {\n database: `${config.database}_fixture_remote`,\n },\n },\n config.environments?.remote_fixture\n );\n\n // 프로덕션 환경 설정\n const prodMasterOptions = config.environments?.production ?? {};\n const prodSlaveOptions = config.environments?.production_slave ?? {};\n const production_master = _.merge({}, defaultKnexConfig, prodMasterOptions);\n const production_slave = _.merge(\n {},\n defaultKnexConfig,\n prodMasterOptions,\n prodSlaveOptions\n );\n\n return {\n test,\n fixture_local,\n fixture_remote,\n development_master,\n development_slave,\n production_master,\n production_slave,\n };\n }\n\n // Test 환경에서 트랜잭션 사용\n public testTransaction: Knex.Transaction | null = null;\n async createTestTransaction(): Promise<Knex.Transaction> {\n const db = this.getDB(\"w\");\n this.testTransaction = await db.transaction();\n return this.testTransaction;\n }\n async clearTestTransaction(): Promise<void> {\n await this.testTransaction?.rollback();\n this.testTransaction = null;\n }\n}\nexport const DB = new DBClass();\n"],"names":["DB","DBClass","wdb","rdb","transactionStorage","AsyncLocalStorage","testTransaction","runWithTransaction","callback","run","TransactionContext","getTransactionContext","getStore","readKnexfile","dbConfigPath","knexfileModule","config","path","join","Sonamu","apiRootPath","default","generateDBConfig","ServiceUnavailableException","getDB","which","dbConfig","process","env","NODE_ENV","knex","pool","min","max","instanceName","Error","destroy","undefined","defaultKnexConfig","_","merge","client","migrations","extension","directory","connection","database","defaultOptions","test","fixture_local","devMasterOptions","environments","development","devSlaveOptions","development_slave","development_master","fixture_remote","remote_fixture","prodMasterOptions","production","prodSlaveOptions","production_slave","production_master","createTestTransaction","db","transaction","clearTestTransaction","rollback"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/database/knex-plugins/knex-on-duplicate-update.ts"],"sourcesContent":["import knex from \"knex\";\n\nexport function attachOnDuplicateUpdate() {\n try {\n knex.QueryBuilder.extend(\"onDuplicateUpdate\", function (...columns) {\n if (columns.length === 0) {\n // 업데이트 할 컬럼이 없으면 onDuplicateUpdate 구문 처리 패스\n const { sql: originalSQL, bindings: originalBindings } = this.toSQL();\n return this.client.raw(originalSQL, originalBindings);\n }\n\n const { placeholders, bindings } = columns.reduce(\n (result, column) => {\n if (typeof column === \"string\") {\n result.placeholders.push(`?? = Values(??)`);\n result.bindings.push(column, column);\n } else if (column && typeof column === \"object\") {\n Object.keys(column).forEach((key) => {\n result.placeholders.push(`?? = ?`);\n result.bindings.push(key, column[key]);\n });\n } else {\n throw new Error(\n \"onDuplicateUpdate error: expected column name to be string or object.\"\n );\n }\n\n return result;\n },\n { placeholders: [], bindings: [] }\n );\n\n const { sql: originalSQL, bindings: originalBindings } = this.toSQL();\n\n const newBindings = [...originalBindings, ...bindings];\n\n return this.client.raw(\n `${originalSQL} ON DUPLICATE KEY UPDATE ${placeholders.join(\", \")}`,\n newBindings\n );\n });\n } catch {\n // ignored\n }\n}"],"names":["attachOnDuplicateUpdate","knex","QueryBuilder","extend","columns","length","toSQL","sql","originalSQL","bindings","originalBindings","client","raw","reduce","result","column","placeholders","push","Object","keys","forEach","key","Error","newBindings","join"],"mappings":"oGAEgBA,iEAAAA,mFAFC,yzCAEV,SAASA,0BACd,GAAI,CACFC,aAAI,CAACC,YAAY,CAACC,MAAM,CAAC,oBAAqB,WAAU,IAAA,IAAA,KAAA,UAAA,OAAA,AAAGC,QAAH,UAAA,MAAA,KAAA,EAAA,KAAA,KAAA,QAAGA,QAAH,MAAA,SAAA,CAAA,KAAU,CAChE,GAAIA,QAAQC,MAAM,GAAK,EAAG,CAExB,IAAyD,YAAA,IAAI,CAACC,KAAK,GAA3DC,AAAKC,YAA4C,YAAjDD,IAAkBE,AAAUC,iBAAqB,YAA/BD,SAC1B,OAAO,IAAI,CAACE,MAAM,CAACC,GAAG,CAACJ,YAAaE,iBACtC,CAEA,IAAmCN,gBAAAA,QAAQS,MAAM,CAC/C,SAACC,OAAQC,QACP,GAAI,OAAOA,SAAW,SAAU,CAC9BD,OAAOE,YAAY,CAACC,IAAI,CAAC,mBACzBH,OAAOL,QAAQ,CAACQ,IAAI,CAACF,OAAQA,OAC/B,MAAO,GAAIA,QAAU,CAAA,OAAOA,iCAAP,SAAOA,OAAK,IAAM,SAAU,CAC/CG,OAAOC,IAAI,CAACJ,QAAQK,OAAO,CAAC,SAACC,KAC3BP,OAAOE,YAAY,CAACC,IAAI,CAAC,UACzBH,OAAOL,QAAQ,CAACQ,IAAI,CAACI,IAAKN,MAAM,CAACM,IAAI,CACvC,EACF,KAAO,CACL,MAAM,IAAIC,MACR,wEAEJ,CAEA,OAAOR,MACT,EACA,CAAEE,aAAc,EAAE,CAAEP,SAAU,EAAE,AAAC,GAlB3BO,aAA2BZ,gBAA3BY,aAAcP,SAAaL,gBAAbK,SAqBtB,IAAyD,aAAA,IAAI,CAACH,KAAK,GAA3DC,AAAKC,aAA4C,aAAjDD,IAAkBE,AAAUC,kBAAqB,aAA/BD,SAE1B,IAAMc,YAAc,AAAC,qBAAGb,0BAAkB,qBAAGD,WAE7C,OAAO,IAAI,CAACE,MAAM,CAACC,GAAG,CACpB,AAAC,GAAyCI,OAAvCR,aAAY,6BAAmD,OAAxBQ,aAAaQ,IAAI,CAAC,OAC5DD,YAEJ,EACF,CAAE,QAAM,CAER,CACF"}
|