sonamu 0.4.14 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.swcrc +15 -0
- package/dist/api/base-frame.d.ts +8 -0
- package/dist/api/base-frame.d.ts.map +1 -0
- package/dist/api/base-frame.js +2 -0
- package/dist/api/base-frame.js.map +1 -0
- package/dist/api/caster.d.ts +5 -0
- package/dist/api/caster.d.ts.map +1 -0
- package/dist/api/caster.js +2 -0
- package/dist/api/caster.js.map +1 -0
- package/dist/api/code-converters.d.ts +23 -0
- package/dist/api/code-converters.d.ts.map +1 -0
- package/dist/api/code-converters.js +2 -0
- package/dist/api/code-converters.js.map +1 -0
- package/dist/api/context.d.ts +16 -0
- package/dist/api/context.d.ts.map +1 -0
- package/dist/api/context.js +2 -0
- package/dist/api/context.js.map +1 -0
- package/dist/api/decorators.d.ts +50 -0
- package/dist/api/decorators.d.ts.map +1 -0
- package/dist/api/decorators.js +2 -0
- package/dist/api/decorators.js.map +1 -0
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/sonamu.d.ts +83 -0
- package/dist/api/sonamu.d.ts.map +1 -0
- package/dist/api/sonamu.js +2 -0
- package/dist/api/sonamu.js.map +1 -0
- package/dist/api/sonamu.types.d.ts +30 -0
- package/dist/api/sonamu.types.d.ts.map +1 -0
- package/dist/api/sonamu.types.js +2 -0
- package/dist/api/sonamu.types.js.map +1 -0
- package/dist/bin/build-config.d.ts +5 -0
- package/dist/bin/build-config.d.ts.map +1 -0
- package/dist/bin/build-config.js +2 -0
- package/dist/bin/build-config.js.map +1 -0
- package/dist/bin/cli-wrapper.d.ts +2 -0
- package/dist/bin/cli-wrapper.d.ts.map +1 -0
- package/dist/bin/cli-wrapper.js +1 -38
- package/dist/bin/cli-wrapper.js.map +1 -1
- package/dist/bin/cli.d.ts +2 -2
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +1 -903
- package/dist/bin/cli.js.map +1 -1
- package/dist/database/_batch_update.d.ts +15 -0
- package/dist/database/_batch_update.d.ts.map +1 -0
- package/dist/database/_batch_update.js +2 -0
- package/dist/database/_batch_update.js.map +1 -0
- package/dist/database/base-model.d.ts +41 -0
- package/dist/database/base-model.d.ts.map +1 -0
- package/dist/database/base-model.js +2 -0
- package/dist/database/base-model.js.map +1 -0
- package/dist/database/code-generator.d.ts +13 -0
- package/dist/database/code-generator.d.ts.map +1 -0
- package/dist/database/code-generator.js +2 -0
- package/dist/database/code-generator.js.map +1 -0
- package/dist/database/db.d.ts +40 -0
- package/dist/database/db.d.ts.map +1 -0
- package/dist/database/db.js +2 -0
- package/dist/database/db.js.map +1 -0
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +2 -0
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +1 -0
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +2 -0
- package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +1 -0
- package/dist/database/puri-wrapper.d.ts +34 -0
- package/dist/database/puri-wrapper.d.ts.map +1 -0
- package/dist/database/puri-wrapper.js +2 -0
- package/dist/database/puri-wrapper.js.map +1 -0
- package/dist/database/puri.d.ts +83 -0
- package/dist/database/puri.d.ts.map +1 -0
- package/dist/database/puri.js +2 -0
- package/dist/database/puri.js.map +1 -0
- package/dist/database/puri.types.d.ts +60 -0
- package/dist/database/puri.types.d.ts.map +1 -0
- package/dist/database/puri.types.js +2 -0
- package/dist/database/puri.types.js.map +1 -0
- package/dist/database/transaction-context.d.ts +9 -0
- package/dist/database/transaction-context.d.ts.map +1 -0
- package/dist/database/transaction-context.js +2 -0
- package/dist/database/transaction-context.js.map +1 -0
- package/dist/database/types.d.ts +39 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +2 -0
- package/dist/database/types.js.map +1 -0
- package/dist/database/upsert-builder.d.ts +34 -0
- package/dist/database/upsert-builder.d.ts.map +1 -0
- package/dist/database/upsert-builder.js +2 -0
- package/dist/database/upsert-builder.js.map +1 -0
- package/dist/entity/entity-manager.d.ts +32 -0
- package/dist/entity/entity-manager.d.ts.map +1 -0
- package/dist/entity/entity-manager.js +2 -0
- package/dist/entity/entity-manager.js.map +1 -0
- package/dist/entity/entity-utils.d.ts +61 -0
- package/dist/entity/entity-utils.d.ts.map +1 -0
- package/dist/entity/entity-utils.js +2 -0
- package/dist/entity/entity-utils.js.map +1 -0
- package/dist/entity/entity.d.ts +62 -0
- package/dist/entity/entity.d.ts.map +1 -0
- package/dist/entity/entity.js +2 -0
- package/dist/entity/entity.js.map +1 -0
- package/dist/entity/migrator.d.ts +135 -0
- package/dist/entity/migrator.d.ts.map +1 -0
- package/dist/entity/migrator.js +2 -0
- package/dist/entity/migrator.js.map +1 -0
- package/dist/exceptions/error-handler.d.ts +3 -0
- package/dist/exceptions/error-handler.d.ts.map +1 -0
- package/dist/exceptions/error-handler.js +2 -0
- package/dist/exceptions/error-handler.js.map +1 -0
- package/dist/exceptions/so-exceptions.d.ts +48 -0
- package/dist/exceptions/so-exceptions.d.ts.map +1 -0
- package/dist/exceptions/so-exceptions.js +2 -0
- package/dist/exceptions/so-exceptions.js.map +1 -0
- package/dist/file-storage/driver.d.ts +45 -0
- package/dist/file-storage/driver.d.ts.map +1 -0
- package/dist/file-storage/driver.js +2 -0
- package/dist/file-storage/driver.js.map +1 -0
- package/dist/file-storage/file-storage.d.ts +50 -0
- package/dist/file-storage/file-storage.d.ts.map +1 -0
- package/dist/file-storage/file-storage.js +2 -0
- package/dist/file-storage/file-storage.js.map +1 -0
- package/dist/index.d.ts +22 -813
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -433
- package/dist/index.js.map +1 -1
- package/dist/migration/code-generation.d.ts +15 -0
- package/dist/migration/code-generation.d.ts.map +1 -0
- package/dist/migration/code-generation.js +2 -0
- package/dist/migration/code-generation.js.map +1 -0
- package/dist/migration/migration-set.d.ts +17 -0
- package/dist/migration/migration-set.d.ts.map +1 -0
- package/dist/migration/migration-set.js +2 -0
- package/dist/migration/migration-set.js.map +1 -0
- package/dist/migration/migrator.d.ts +130 -0
- package/dist/migration/migrator.d.ts.map +1 -0
- package/dist/migration/migrator.js +2 -0
- package/dist/migration/migrator.js.map +1 -0
- package/dist/migration/types.d.ts +52 -0
- package/dist/migration/types.d.ts.map +1 -0
- package/dist/migration/types.js +2 -0
- package/dist/migration/types.js.map +1 -0
- package/dist/smd/smd-manager.d.ts +28 -0
- package/dist/smd/smd-manager.d.ts.map +1 -0
- package/dist/smd/smd-manager.js +2 -0
- package/dist/smd/smd-manager.js.map +1 -0
- package/dist/smd/smd.d.ts +40 -0
- package/dist/smd/smd.d.ts.map +1 -0
- package/dist/smd/smd.js +2 -0
- package/dist/smd/smd.js.map +1 -0
- package/dist/syncer/index.d.ts +2 -0
- package/dist/syncer/index.d.ts.map +1 -0
- package/dist/syncer/index.js +2 -0
- package/dist/syncer/index.js.map +1 -0
- package/dist/syncer/syncer.d.ts +127 -0
- package/dist/syncer/syncer.d.ts.map +1 -0
- package/dist/syncer/syncer.js +2 -0
- package/dist/syncer/syncer.js.map +1 -0
- package/dist/templates/base-template.d.ts +13 -0
- package/dist/templates/base-template.d.ts.map +1 -0
- package/dist/templates/base-template.js +2 -0
- package/dist/templates/base-template.js.map +1 -0
- package/dist/templates/entity.template.d.ts +17 -0
- package/dist/templates/entity.template.d.ts.map +1 -0
- package/dist/templates/entity.template.js +2 -0
- package/dist/templates/entity.template.js.map +1 -0
- package/dist/templates/generated.template.d.ts +27 -0
- package/dist/templates/generated.template.d.ts.map +1 -0
- package/dist/templates/generated.template.js +2 -0
- package/dist/templates/generated.template.js.map +1 -0
- package/dist/templates/generated_http.template.d.ts +24 -0
- package/dist/templates/generated_http.template.d.ts.map +1 -0
- package/dist/templates/generated_http.template.js +2 -0
- package/dist/templates/generated_http.template.js.map +1 -0
- package/dist/templates/generated_sso.template.d.ts +20 -0
- package/dist/templates/generated_sso.template.d.ts.map +1 -0
- package/dist/templates/generated_sso.template.js +2 -0
- package/dist/templates/generated_sso.template.js.map +1 -0
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +2 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/init_types.template.d.ts +17 -0
- package/dist/templates/init_types.template.d.ts.map +1 -0
- package/dist/templates/init_types.template.js +2 -0
- package/dist/templates/init_types.template.js.map +1 -0
- package/dist/templates/model.template.d.ts +17 -0
- package/dist/templates/model.template.d.ts.map +1 -0
- package/dist/templates/model.template.js +2 -0
- package/dist/templates/model.template.js.map +1 -0
- package/dist/templates/model_test.template.d.ts +17 -0
- package/dist/templates/model_test.template.d.ts.map +1 -0
- package/dist/templates/model_test.template.js +2 -0
- package/dist/templates/model_test.template.js.map +1 -0
- package/dist/templates/service.template.d.ts +29 -0
- package/dist/templates/service.template.d.ts.map +1 -0
- package/dist/templates/service.template.js +2 -0
- package/dist/templates/service.template.js.map +1 -0
- package/dist/templates/view_enums_buttonset.template.d.ts +17 -0
- package/dist/templates/view_enums_buttonset.template.d.ts.map +1 -0
- package/dist/templates/view_enums_buttonset.template.js +2 -0
- package/dist/templates/view_enums_buttonset.template.js.map +1 -0
- package/dist/templates/view_enums_dropdown.template.d.ts +18 -0
- package/dist/templates/view_enums_dropdown.template.d.ts.map +1 -0
- package/dist/templates/view_enums_dropdown.template.js +2 -0
- package/dist/templates/view_enums_dropdown.template.js.map +1 -0
- package/dist/templates/view_enums_select.template.d.ts +17 -0
- package/dist/templates/view_enums_select.template.d.ts.map +1 -0
- package/dist/templates/view_enums_select.template.js +2 -0
- package/dist/templates/view_enums_select.template.js.map +1 -0
- package/dist/templates/view_form.template.d.ts +26 -0
- package/dist/templates/view_form.template.d.ts.map +1 -0
- package/dist/templates/view_form.template.js +2 -0
- package/dist/templates/view_form.template.js.map +1 -0
- package/dist/templates/view_id_all_select.template.d.ts +17 -0
- package/dist/templates/view_id_all_select.template.d.ts.map +1 -0
- package/dist/templates/view_id_all_select.template.js +2 -0
- package/dist/templates/view_id_all_select.template.js.map +1 -0
- package/dist/templates/view_id_async_select.template.d.ts +17 -0
- package/dist/templates/view_id_async_select.template.d.ts.map +1 -0
- package/dist/templates/view_id_async_select.template.js +2 -0
- package/dist/templates/view_id_async_select.template.js.map +1 -0
- package/dist/templates/view_list.template.d.ts +38 -0
- package/dist/templates/view_list.template.d.ts.map +1 -0
- package/dist/templates/view_list.template.js +2 -0
- package/dist/templates/view_list.template.js.map +1 -0
- package/dist/templates/view_list_columns.template.d.ts +17 -0
- package/dist/templates/view_list_columns.template.d.ts.map +1 -0
- package/dist/templates/view_list_columns.template.js +2 -0
- package/dist/templates/view_list_columns.template.js.map +1 -0
- package/dist/templates/view_search_input.template.d.ts +17 -0
- package/dist/templates/view_search_input.template.d.ts.map +1 -0
- package/dist/templates/view_search_input.template.js +2 -0
- package/dist/templates/view_search_input.template.js.map +1 -0
- package/dist/testing/_relation-graph.d.ts +7 -0
- package/dist/testing/_relation-graph.d.ts.map +1 -0
- package/dist/testing/_relation-graph.js +2 -0
- package/dist/testing/_relation-graph.js.map +1 -0
- package/dist/testing/fixture-manager.d.ts +35 -0
- package/dist/testing/fixture-manager.d.ts.map +1 -0
- package/dist/testing/fixture-manager.js +2 -0
- package/dist/testing/fixture-manager.js.map +1 -0
- package/dist/types/types.d.ts +609 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +2 -0
- package/dist/types/types.js.map +1 -0
- package/dist/typings/knex.d.js +2 -0
- package/dist/typings/knex.d.js.map +1 -0
- package/dist/utils/async-utils.d.ts +25 -0
- package/dist/utils/async-utils.d.ts.map +1 -0
- package/dist/utils/async-utils.js +2 -0
- package/dist/utils/async-utils.js.map +1 -0
- package/dist/utils/controller.d.ts +9 -0
- package/dist/utils/controller.d.ts.map +1 -0
- package/dist/utils/controller.js +2 -0
- package/dist/utils/controller.js.map +1 -0
- package/dist/utils/fs-utils.d.ts +9 -0
- package/dist/utils/fs-utils.d.ts.map +1 -0
- package/dist/utils/fs-utils.js +2 -0
- package/dist/utils/fs-utils.js.map +1 -0
- package/dist/utils/lodash-able.d.ts +2 -0
- package/dist/utils/lodash-able.d.ts.map +1 -0
- package/dist/utils/lodash-able.js +2 -0
- package/dist/utils/lodash-able.js.map +1 -0
- package/dist/utils/model.d.ts +17 -0
- package/dist/utils/model.d.ts.map +1 -0
- package/dist/utils/model.js +2 -0
- package/dist/utils/model.js.map +1 -0
- package/dist/utils/sql-parser.d.ts +4 -0
- package/dist/utils/sql-parser.d.ts.map +1 -0
- package/dist/utils/sql-parser.js +2 -0
- package/dist/utils/sql-parser.js.map +1 -0
- package/dist/utils/utils.d.ts +9 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +2 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/utils/zod-error.d.ts +8 -0
- package/dist/utils/zod-error.d.ts.map +1 -0
- package/dist/utils/zod-error.js +2 -0
- package/dist/utils/zod-error.js.map +1 -0
- package/nodemon.json +6 -0
- package/package.json +29 -44
- package/src/api/base-frame.ts +3 -4
- package/src/api/caster.ts +22 -23
- package/src/api/code-converters.ts +170 -134
- package/src/api/context.ts +13 -6
- package/src/api/decorators.ts +146 -20
- package/src/api/index.ts +2 -0
- package/src/api/sonamu.ts +374 -165
- package/src/bin/build-config.ts +5 -0
- package/src/bin/cli-wrapper.ts +29 -40
- package/src/bin/cli.ts +132 -190
- package/src/database/_batch_update.ts +10 -15
- package/src/database/base-model.ts +300 -216
- package/src/database/db.ts +191 -21
- package/src/database/{drivers/knex/plugins → knex-plugins}/knex-on-duplicate-update.ts +1 -1
- package/src/database/puri-wrapper.ts +129 -0
- package/src/database/puri.ts +808 -0
- package/src/database/puri.types.ts +222 -0
- package/src/database/transaction-context.ts +18 -0
- package/src/database/upsert-builder.ts +32 -35
- package/src/entity/entity-manager.ts +7 -15
- package/src/entity/entity.ts +9 -31
- package/src/entity/migrator-/354/235/264/354/202/254/352/260/224/354/226/264/354/232/224.md +1 -0
- package/src/file-storage/driver.ts +121 -0
- package/src/file-storage/file-storage.ts +100 -0
- package/src/index.ts +14 -11
- package/src/migration/code-generation.ts +777 -0
- package/src/migration/migration-set.ts +453 -0
- package/src/migration/migrator.ts +823 -0
- package/src/migration/types.ts +53 -0
- package/src/shared/web.shared.ts.txt +33 -2
- package/src/syncer/syncer.ts +294 -127
- package/src/templates/generated.template.ts +13 -1
- package/src/templates/generated_http.template.ts +15 -12
- package/src/templates/generated_sso.template.ts +50 -2
- package/src/templates/model.template.ts +138 -2
- package/src/templates/service.template.ts +0 -1
- package/src/templates/view_form.template.ts +11 -7
- package/src/templates/view_list.template.ts +12 -4
- package/src/testing/fixture-manager.ts +229 -174
- package/src/types/types.ts +102 -14
- package/src/utils/async-utils.ts +64 -0
- package/src/utils/fs-utils.ts +17 -0
- package/src/utils/model.ts +0 -2
- package/src/utils/utils.ts +14 -58
- package/src/utils/zod-error.ts +12 -176
- package/tsconfig.json +2 -0
- package/tsup.config.js +4 -2
- package/.pnp.cjs +0 -14363
- package/.pnp.loader.mjs +0 -2047
- package/.vscode/extensions.json +0 -6
- package/.vscode/settings.json +0 -9
- package/.yarnrc.yml +0 -5
- package/src/database/base-model.abstract.ts +0 -97
- package/src/database/db.abstract.ts +0 -75
- package/src/database/drivers/knex/base-model.ts +0 -55
- package/src/database/drivers/knex/client.ts +0 -209
- package/src/database/drivers/knex/db.ts +0 -232
- package/src/database/drivers/knex/generator.ts +0 -659
- package/src/database/drivers/kysely/base-model.ts +0 -89
- package/src/database/drivers/kysely/client.ts +0 -309
- package/src/database/drivers/kysely/db.ts +0 -238
- package/src/database/drivers/kysely/generator.ts +0 -714
- package/src/database/types.ts +0 -118
- package/src/entity/migrator.ts +0 -1400
- package/src/smd/smd-manager.ts +0 -139
- package/src/smd/smd.ts +0 -571
- package/src/templates/kysely_types.template.ts +0 -205
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Knex } from "knex";
|
|
2
|
+
import { Entity } from "../entity/entity";
|
|
3
|
+
import { MigrationSet, MigrationSetAndJoinTable } from "../types/types";
|
|
4
|
+
/**
|
|
5
|
+
* DB에서 테이블 정보를 읽어서 MigrationSet을 만들어옵니다.
|
|
6
|
+
* @param compareDB Knex 인스턴스
|
|
7
|
+
* @param table 테이블 이름
|
|
8
|
+
* @returns MigrationSet 객체
|
|
9
|
+
*/
|
|
10
|
+
export declare function getMigrationSetFromDB(compareDB: Knex, table: string): Promise<MigrationSet | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Entity를 읽어서 MigrationSetAndJoinTable을 만들어옵니다.
|
|
13
|
+
* @param entity Entity 객체
|
|
14
|
+
* @returns MigrationSetAndJoinTable 객체
|
|
15
|
+
*/
|
|
16
|
+
export declare function getMigrationSetFromEntity(entity: Entity): MigrationSetAndJoinTable;
|
|
17
|
+
//# sourceMappingURL=migration-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-set.d.ts","sourceRoot":"","sources":["../../src/migration/migration-set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAEL,YAAY,EAmBZ,wBAAwB,EACzB,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,IAAI,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA2E9B;AAqJD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,GACb,wBAAwB,CAsL1B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});function _export(target,all){for(var name in all)Object.defineProperty(target,name,{enumerable:true,get:Object.getOwnPropertyDescriptor(all,name).get})}_export(exports,{get getMigrationSetFromDB(){return getMigrationSetFromDB},get getMigrationSetFromEntity(){return getMigrationSetFromEntity}});var _lodash=/*#__PURE__*/_interop_require_default(require("lodash"));var _inflection=/*#__PURE__*/_interop_require_default(require("inflection"));var _entitymanager=require("../entity/entity-manager");var _types=require("../types/types");function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};var ownKeys=Object.keys(source);if(typeof Object.getOwnPropertySymbols==="function"){ownKeys=ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym){return Object.getOwnPropertyDescriptor(source,sym).enumerable}))}ownKeys.forEach(function(key){_define_property(target,key,source[key])})}return target}function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);if(enumerableOnly){symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable})}keys.push.apply(keys,symbols)}return keys}function _object_spread_props(target,source){source=source!=null?source:{};if(Object.getOwnPropertyDescriptors){Object.defineProperties(target,Object.getOwnPropertyDescriptors(source))}else{ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key))})}return target}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["return"]=verb(2),typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]<t[3])){_.label=op[1];break}if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break}if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break}if(t[2])_.ops.pop();_.trys.pop();continue}op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0}if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true}}}function getMigrationSetFromDB(compareDB,table){return _async_to_generator(function(){var dbColumns,dbIndexes,dbForeigns,ref,e,columns,dbIndexesGroup,parseIndexType,indexes,foreigns;return _ts_generator(this,function(_state){switch(_state.label){case 0:_state.trys.push([0,2,,3]);return[4,readTable(compareDB,table)];case 1:ref=_sliced_to_array.apply(void 0,[_state.sent(),3]),dbColumns=ref[0],dbIndexes=ref[1],dbForeigns=ref[2],ref;return[3,3];case 2:e=_state.sent();if((0,_types.isKnexError)(e)&&e.code==="ER_NO_SUCH_TABLE"){return[2,null]}console.error(e);return[2,null];case 3:columns=dbColumns.map(function(dbColumn){var dbColType=resolveDBColType(dbColumn.Type,dbColumn.Field);return _object_spread({name:dbColumn.Field,nullable:dbColumn.Null!=="NO"},dbColType,function(){if(dbColumn.Default!==null){return{defaultTo:dbColumn.Default}}return{}}())});dbIndexesGroup=_lodash.default.groupBy(dbIndexes.filter(function(dbIndex){return dbIndex.Key_name!=="PRIMARY"&&!dbForeigns.find(function(dbForeign){return dbForeign.keyName===dbIndex.Key_name})}),function(dbIndex){return dbIndex.Key_name});parseIndexType=function(index){if(index.Index_type==="FULLTEXT"){return"fulltext"}return index.Non_unique===1?"index":"unique"};indexes=Object.keys(dbIndexesGroup).map(function(keyName){var currentIndexes=dbIndexesGroup[keyName];return{type:parseIndexType(currentIndexes[0]),columns:currentIndexes.map(function(currentIndex){return currentIndex.Column_name})}});foreigns=dbForeigns.map(function(dbForeign){return{columns:[dbForeign.from],to:"".concat(dbForeign.referencesTable,".").concat(dbForeign.referencesField),onUpdate:dbForeign.onUpdate,onDelete:dbForeign.onDelete}});return[2,{table:table,columns:columns,indexes:indexes,foreigns:foreigns}]}})})()}function readTable(compareDB,tableName){return _async_to_generator(function(){var _ref,_cols,cols,_ref1,indexes,_ref2,_ref_,row,ddl,matched,foreignKeys,e;return _ts_generator(this,function(_state){switch(_state.label){case 0:_state.trys.push([0,4,,5]);return[4,compareDB.raw("SHOW FIELDS FROM ".concat(tableName))];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),1]),_cols=_ref[0];cols=_cols.map(function(col){return _object_spread({},col,col.Default!==null&&{Default:col.Default.replace(/[0-9]+/g,"").length>0&&col.Extra!=="DEFAULT_GENERATED"?'"'.concat(col.Default,'"'):col.Default})});return[4,compareDB.raw("SHOW INDEX FROM ".concat(tableName))];case 2:_ref1=_sliced_to_array.apply(void 0,[_state.sent(),1]),indexes=_ref1[0];return[4,compareDB.raw("SHOW CREATE TABLE ".concat(tableName))];case 3:_ref2=_sliced_to_array.apply(void 0,[_state.sent(),1]),_ref_=_sliced_to_array(_ref2[0],1),row=_ref_[0];ddl=row["Create Table"];matched=ddl.match(/CONSTRAINT .+/g);foreignKeys=(matched!==null&&matched!==void 0?matched:[]).map(function(line){var _replace_match_,_replace_match;var matched=line.match(/CONSTRAINT `(.+)` FOREIGN KEY \(`(.+)`\) REFERENCES `(.+)` \(`(.+)`\)( ON [A-Z ]+)*/);if(!matched){throw new Error("인식할 수 없는 FOREIGN KEY CONSTRAINT ".concat(line))}var _matched=_sliced_to_array(matched,6),keyName=_matched[1],from=_matched[2],referencesTable=_matched[3],referencesField=_matched[4],onClause=_matched[5];var _match;var _ref=_sliced_to_array((_match=(onClause!==null&&onClause!==void 0?onClause:"").match(/ON UPDATE ([A-Z ]+)$/))!==null&&_match!==void 0?_match:[],2),onUpdateFull=_ref[0],_onUpdate=_ref[1];var onUpdate=_onUpdate!==null&&_onUpdate!==void 0?_onUpdate:"NO ACTION";var _replace_match__trim;var onDelete=(_replace_match__trim=(_replace_match=(onClause!==null&&onClause!==void 0?onClause:"").replace(onUpdateFull!==null&&onUpdateFull!==void 0?onUpdateFull:"","").match(/ON DELETE ([A-Z ]+)/))===null||_replace_match===void 0?void 0:(_replace_match_=_replace_match[1])===null||_replace_match_===void 0?void 0:_replace_match_.trim())!==null&&_replace_match__trim!==void 0?_replace_match__trim:"NO ACTION";return{keyName:keyName,from:from,referencesTable:referencesTable,referencesField:referencesField,onDelete:onDelete,onUpdate:onUpdate}});return[2,[cols,indexes,foreignKeys]];case 4:e=_state.sent();throw e;case 5:return[2]}})})()}function resolveDBColType(colType,colField){var _colType_split=_sliced_to_array(colType.split(" "),2),rawType=_colType_split[0],unsigned=_colType_split[1];var matched=rawType.match(/\(([0-9]+)\)/);var length;if(matched!==null&&matched[1]){rawType=rawType.replace(/\(([0-9]+)\)/,"");length=parseInt(matched[1])}if(rawType==="char"&&colField==="uuid"){return{type:"uuid"}}switch(rawType){case"int":return{type:"integer",unsigned:unsigned==="unsigned"};case"varchar":return _object_spread({type:"string"},length!==undefined&&{length:length});case"text":case"mediumtext":case"longtext":case"timestamp":case"json":case"date":case"time":return{type:rawType};case"datetime":return{type:"datetime"};case"tinyint":return{type:"boolean"};default:if(rawType.startsWith("decimal")){var _rawType_match;var _ref=_sliced_to_array((_rawType_match=rawType.match(/decimal\(([0-9]+),([0-9]+)\)/))!==null&&_rawType_match!==void 0?_rawType_match:[],3),precision=_ref[1],scale=_ref[2];return _object_spread({type:"decimal",precision:parseInt(precision),scale:parseInt(scale)},unsigned==="unsigned"&&{unsigned:true})}else if(rawType.startsWith("float")){var _rawType_match1;var _ref1=_sliced_to_array((_rawType_match1=rawType.match(/float\(([0-9]+),([0-9]+)\)/))!==null&&_rawType_match1!==void 0?_rawType_match1:[],3),precision1=_ref1[1],scale1=_ref1[2];return _object_spread({type:"float",precision:parseInt(precision1),scale:parseInt(scale1)},unsigned==="unsigned"&&{unsigned:true})}throw new Error("resolve 불가능한 DB컬럼 타입 ".concat(colType," ").concat(rawType))}}function getMigrationSetFromEntity(entity){var migrationSet=entity.props.reduce(function(r,prop){if((0,_types.isVirtualProp)(prop)){return r}if((0,_types.isHasManyRelationProp)(prop)){return r}if(!(0,_types.isRelationProp)(prop)){var type;if((0,_types.isTextProp)(prop)){type=prop.textType}else if((0,_types.isEnumProp)(prop)){type="string"}else{type=prop.type}var _prop_precision,_prop_scale;var column=_object_spread(_object_spread_props(_object_spread({name:prop.name,type:type},(0,_types.isIntegerProp)(prop)&&{unsigned:prop.unsigned===true},((0,_types.isStringProp)(prop)||(0,_types.isEnumProp)(prop))&&{length:prop.length}),{nullable:prop.nullable===true}),function(){if(prop.dbDefault!==undefined){return{defaultTo:prop.dbDefault}}return{}}(),((0,_types.isDecimalProp)(prop)||(0,_types.isFloatProp)(prop))&&{precision:(_prop_precision=prop.precision)!==null&&_prop_precision!==void 0?_prop_precision:8,scale:(_prop_scale=prop.scale)!==null&&_prop_scale!==void 0?_prop_scale:2});r.columns.push(column)}if((0,_types.isManyToManyRelationProp)(prop)){var relMd=_entitymanager.EntityManager.get(prop.with);var table1=entity.table;var table2=relMd.table;var join={from:"".concat(entity.table,".id"),through:{from:"".concat(prop.joinTable,".").concat(_inflection.default.singularize(table1),"_id"),to:"".concat(prop.joinTable,".").concat(_inflection.default.singularize(table2),"_id"),onUpdate:prop.onUpdate,onDelete:prop.onDelete},to:"".concat(relMd.table,".id")};var through=join.through;var fields=[through.from,through.to];r.joinTables.push({table:through.from.split(".")[0],indexes:[{type:"unique",columns:["uuid"]}].concat(_to_consumable_array(entity.indexes.filter(function(index){return index.columns.find(function(col){return col.includes(prop.joinTable+".")})}).map(function(index){return _object_spread_props(_object_spread({},index),{columns:index.columns.map(function(col){return col.replace(prop.joinTable+".","")})})}))),columns:[{name:"id",type:"integer",nullable:false,unsigned:true}].concat(_to_consumable_array(fields.map(function(field){return{name:field.split(".")[1],type:"integer",nullable:false,unsigned:true}})),[{name:"uuid",nullable:true,type:"uuid"}]),foreigns:fields.map(function(field){var col=field.split(".")[1];var to=function(){if(_inflection.default.singularize(join.to.split(".")[0])+"_id"===col){return join.to}else{return join.from}}();return{columns:[col],to:to,onUpdate:through.onUpdate,onDelete:through.onDelete}})});return r}else if((0,_types.isBelongsToOneRelationProp)(prop)||(0,_types.isOneToOneRelationProp)(prop)&&prop.hasJoinColumn){var idColumnName=prop.name+"_id";var _prop_nullable;r.columns.push({name:idColumnName,type:"integer",unsigned:true,nullable:(_prop_nullable=prop.nullable)!==null&&_prop_nullable!==void 0?_prop_nullable:false});var _prop_useConstraint;if(((_prop_useConstraint=prop.useConstraint)!==null&&_prop_useConstraint!==void 0?_prop_useConstraint:true)===true){var _prop_onUpdate,_prop_onDelete;r.foreigns.push({columns:[idColumnName],to:"".concat(_inflection.default.underscore(_inflection.default.pluralize(prop.with)).toLowerCase(),".id"),onUpdate:(_prop_onUpdate=prop.onUpdate)!==null&&_prop_onUpdate!==void 0?_prop_onUpdate:"RESTRICT",onDelete:(_prop_onDelete=prop.onDelete)!==null&&_prop_onDelete!==void 0?_prop_onDelete:"RESTRICT"})}}return r},{table:entity.table,columns:[],indexes:[],foreigns:[],joinTables:[]});migrationSet.indexes=entity.indexes.filter(function(index){return index.columns.find(function(col){return col.includes(".")===false})});migrationSet.columns=migrationSet.columns.concat({name:"uuid",nullable:true,type:"uuid"});migrationSet.indexes=migrationSet.indexes.concat({type:"unique",columns:["uuid"]});return migrationSet}
|
|
2
|
+
//# sourceMappingURL=migration-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/migration/migration-set.ts"],"sourcesContent":["import { Knex } from \"knex\";\nimport { DBColumn, DBForeign, DBIndex } from \"./types\";\nimport _ from \"lodash\";\nimport inflection from \"inflection\";\nimport { Entity } from \"../entity/entity\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport {\n isKnexError,\n MigrationSet,\n RelationOn,\n isBelongsToOneRelationProp,\n isDecimalProp,\n isEnumProp,\n isFloatProp,\n isHasManyRelationProp,\n isIntegerProp,\n isManyToManyRelationProp,\n isOneToOneRelationProp,\n isRelationProp,\n isStringProp,\n isTextProp,\n isVirtualProp,\n KnexColumnType,\n MigrationColumn,\n MigrationForeign,\n MigrationIndex,\n MigrationJoinTable,\n MigrationSetAndJoinTable,\n} from \"../types/types\";\n\n/**\n * DB에서 테이블 정보를 읽어서 MigrationSet을 만들어옵니다.\n * @param compareDB Knex 인스턴스\n * @param table 테이블 이름\n * @returns MigrationSet 객체\n */\nexport async function getMigrationSetFromDB(\n compareDB: Knex,\n table: string\n): Promise<MigrationSet | null> {\n let dbColumns: DBColumn[], dbIndexes: DBIndex[], dbForeigns: DBForeign[];\n try {\n [dbColumns, dbIndexes, dbForeigns] = await readTable(compareDB, table);\n } catch (e: unknown) {\n if (isKnexError(e) && e.code === \"ER_NO_SUCH_TABLE\") {\n return null;\n }\n console.error(e);\n return null;\n }\n\n const columns: MigrationColumn[] = dbColumns.map((dbColumn) => {\n const dbColType = resolveDBColType(dbColumn.Type, dbColumn.Field);\n return {\n name: dbColumn.Field,\n nullable: dbColumn.Null !== \"NO\",\n ...dbColType,\n ...(() => {\n if (dbColumn.Default !== null) {\n return {\n defaultTo: dbColumn.Default,\n };\n }\n return {};\n })(),\n };\n });\n\n const dbIndexesGroup = _.groupBy(\n dbIndexes.filter(\n (dbIndex) =>\n dbIndex.Key_name !== \"PRIMARY\" &&\n !dbForeigns.find((dbForeign) => dbForeign.keyName === dbIndex.Key_name)\n ),\n (dbIndex) => dbIndex.Key_name\n );\n\n const parseIndexType = (index: DBIndex) => {\n if (index.Index_type === \"FULLTEXT\") {\n return \"fulltext\";\n }\n return index.Non_unique === 1 ? \"index\" : \"unique\";\n };\n\n // indexes 처리\n const indexes: MigrationIndex[] = Object.keys(dbIndexesGroup).map(\n (keyName) => {\n const currentIndexes = dbIndexesGroup[keyName];\n return {\n type: parseIndexType(currentIndexes[0]),\n columns: currentIndexes.map((currentIndex) => currentIndex.Column_name),\n };\n }\n );\n // console.log(table);\n // console.table(dbIndexes);\n // console.table(dbForeigns);\n\n // foreigns 처리\n const foreigns: MigrationForeign[] = dbForeigns.map((dbForeign) => {\n return {\n columns: [dbForeign.from],\n to: `${dbForeign.referencesTable}.${dbForeign.referencesField}`,\n onUpdate: dbForeign.onUpdate as RelationOn,\n onDelete: dbForeign.onDelete as RelationOn,\n };\n });\n\n return {\n table,\n columns,\n indexes,\n foreigns,\n };\n}\n\n/*\n * 기존 테이블 읽어서 cols, indexes 반환\n */\nasync function readTable(\n compareDB: Knex,\n tableName: string\n): Promise<[DBColumn[], DBIndex[], DBForeign[]]> {\n // 테이블 정보\n try {\n const [_cols] = (await compareDB.raw(`SHOW FIELDS FROM ${tableName}`)) as [\n DBColumn[],\n ];\n const cols = _cols.map((col) => ({\n ...col,\n // Default 값은 숫자나 MySQL Expression이 아닌 경우 \"\"로 감싸줌\n ...(col.Default !== null && {\n Default:\n col.Default.replace(/[0-9]+/g, \"\").length > 0 &&\n col.Extra !== \"DEFAULT_GENERATED\"\n ? `\"${col.Default}\"`\n : col.Default,\n }),\n }));\n\n const [indexes] = await compareDB.raw(`SHOW INDEX FROM ${tableName}`);\n const [[row]] = await compareDB.raw(`SHOW CREATE TABLE ${tableName}`);\n const ddl = row[\"Create Table\"];\n const matched = ddl.match(/CONSTRAINT .+/g);\n const foreignKeys = (matched ?? []).map((line: string) => {\n // 해당 라인을 정규식으로 파싱\n const matched = line.match(\n /CONSTRAINT `(.+)` FOREIGN KEY \\(`(.+)`\\) REFERENCES `(.+)` \\(`(.+)`\\)( ON [A-Z ]+)*/\n );\n if (!matched) {\n throw new Error(`인식할 수 없는 FOREIGN KEY CONSTRAINT ${line}`);\n }\n const [, keyName, from, referencesTable, referencesField, onClause] =\n matched;\n // console.debug({ tableName, line, onClause });\n\n const [onUpdateFull, _onUpdate] =\n (onClause ?? \"\").match(/ON UPDATE ([A-Z ]+)$/) ?? [];\n const onUpdate = _onUpdate ?? \"NO ACTION\";\n\n const onDelete =\n (onClause ?? \"\")\n .replace(onUpdateFull ?? \"\", \"\")\n .match(/ON DELETE ([A-Z ]+)/)?.[1]\n ?.trim() ?? \"NO ACTION\";\n\n return {\n keyName,\n from,\n referencesTable,\n referencesField,\n onDelete,\n onUpdate,\n };\n });\n return [cols, indexes, foreignKeys];\n } catch (e) {\n throw e;\n }\n}\n\nfunction resolveDBColType(\n colType: string,\n colField: string\n): Pick<\n MigrationColumn,\n \"type\" | \"unsigned\" | \"length\" | \"precision\" | \"scale\"\n> {\n let [rawType, unsigned] = colType.split(\" \");\n const matched = rawType.match(/\\(([0-9]+)\\)/);\n let length;\n if (matched !== null && matched[1]) {\n rawType = rawType.replace(/\\(([0-9]+)\\)/, \"\");\n length = parseInt(matched[1]);\n }\n\n if (rawType === \"char\" && colField === \"uuid\") {\n return {\n type: \"uuid\",\n };\n }\n\n switch (rawType) {\n case \"int\":\n return {\n type: \"integer\",\n unsigned: unsigned === \"unsigned\",\n };\n case \"varchar\":\n // case \"char\":\n return {\n type: \"string\",\n ...(length !== undefined && {\n length,\n }),\n };\n case \"text\":\n case \"mediumtext\":\n case \"longtext\":\n case \"timestamp\":\n case \"json\":\n case \"date\":\n case \"time\":\n return {\n type: rawType,\n };\n case \"datetime\":\n return {\n type: \"datetime\",\n };\n case \"tinyint\":\n return {\n type: \"boolean\",\n };\n default:\n // decimal 처리\n if (rawType.startsWith(\"decimal\")) {\n const [, precision, scale] =\n rawType.match(/decimal\\(([0-9]+),([0-9]+)\\)/) ?? [];\n return {\n type: \"decimal\",\n precision: parseInt(precision),\n scale: parseInt(scale),\n ...(unsigned === \"unsigned\" && {\n unsigned: true,\n }),\n };\n } else if (rawType.startsWith(\"float\")) {\n const [, precision, scale] =\n rawType.match(/float\\(([0-9]+),([0-9]+)\\)/) ?? [];\n return {\n type: \"float\",\n precision: parseInt(precision),\n scale: parseInt(scale),\n ...(unsigned === \"unsigned\" && {\n unsigned: true,\n }),\n };\n }\n throw new Error(`resolve 불가능한 DB컬럼 타입 ${colType} ${rawType}`);\n }\n}\n\n/**\n * Entity를 읽어서 MigrationSetAndJoinTable을 만들어옵니다.\n * @param entity Entity 객체\n * @returns MigrationSetAndJoinTable 객체\n */\nexport function getMigrationSetFromEntity(\n entity: Entity\n): MigrationSetAndJoinTable {\n const migrationSet: MigrationSetAndJoinTable = entity.props.reduce(\n (r, prop) => {\n // virtual 필드 제외\n if (isVirtualProp(prop)) {\n return r;\n }\n // HasMany 케이스는 아무 처리도 하지 않음\n if (isHasManyRelationProp(prop)) {\n return r;\n }\n\n // 일반 컬럼\n if (!isRelationProp(prop)) {\n // type resolve\n let type: KnexColumnType;\n if (isTextProp(prop)) {\n type = prop.textType;\n } else if (isEnumProp(prop)) {\n type = \"string\";\n } else {\n type = prop.type as KnexColumnType;\n }\n\n const column = {\n name: prop.name,\n type,\n ...(isIntegerProp(prop) && { unsigned: prop.unsigned === true }),\n ...((isStringProp(prop) || isEnumProp(prop)) && {\n length: prop.length,\n }),\n nullable: prop.nullable === true,\n ...(() => {\n if (prop.dbDefault !== undefined) {\n return {\n defaultTo: prop.dbDefault,\n };\n }\n return {};\n })(),\n // FIXME: float(N, M) deprecated\n // Decimal, Float 타입의 경우 precision, scale 추가\n ...((isDecimalProp(prop) || isFloatProp(prop)) && {\n precision: prop.precision ?? 8,\n scale: prop.scale ?? 2,\n }),\n };\n\n r.columns.push(column);\n }\n\n if (isManyToManyRelationProp(prop)) {\n // ManyToMany 케이스\n const relMd = EntityManager.get(prop.with);\n const table1 = entity.table;\n const table2 = relMd.table;\n const join = {\n from: `${entity.table}.id`,\n through: {\n from: `${prop.joinTable}.${inflection.singularize(table1)}_id`,\n to: `${prop.joinTable}.${inflection.singularize(table2)}_id`,\n onUpdate: prop.onUpdate,\n onDelete: prop.onDelete,\n },\n to: `${relMd.table}.id`,\n };\n const through = join.through;\n const fields = [through.from, through.to];\n r.joinTables.push({\n table: through.from.split(\".\")[0],\n indexes: [\n {\n type: \"unique\",\n columns: [\"uuid\"],\n },\n // 조인 테이블에 걸린 인덱스 찾아와서 연결\n ...entity.indexes\n .filter((index) =>\n index.columns.find((col) => col.includes(prop.joinTable + \".\"))\n )\n .map((index) => ({\n ...index,\n columns: index.columns.map((col) =>\n col.replace(prop.joinTable + \".\", \"\")\n ),\n })),\n ],\n columns: [\n {\n name: \"id\",\n type: \"integer\",\n nullable: false,\n unsigned: true,\n },\n ...fields.map((field) => {\n return {\n name: field.split(\".\")[1],\n type: \"integer\",\n nullable: false,\n unsigned: true,\n } as MigrationColumn;\n }),\n {\n name: \"uuid\",\n nullable: true,\n type: \"uuid\",\n },\n ],\n foreigns: fields.map((field) => {\n // 현재 필드가 어떤 테이블에 속하는지 판단\n const col = field.split(\".\")[1];\n const to = (() => {\n if (\n inflection.singularize(join.to.split(\".\")[0]) + \"_id\" ===\n col\n ) {\n return join.to;\n } else {\n return join.from;\n }\n })();\n return {\n columns: [col],\n to,\n onUpdate: through.onUpdate,\n onDelete: through.onDelete,\n };\n }),\n });\n return r;\n } else if (\n isBelongsToOneRelationProp(prop) ||\n (isOneToOneRelationProp(prop) && prop.hasJoinColumn)\n ) {\n // -OneRelation 케이스\n const idColumnName = prop.name + \"_id\";\n r.columns.push({\n name: idColumnName,\n type: \"integer\",\n unsigned: true,\n nullable: prop.nullable ?? false,\n });\n if ((prop.useConstraint ?? true) === true) {\n r.foreigns.push({\n columns: [idColumnName],\n to: `${inflection\n .underscore(inflection.pluralize(prop.with))\n .toLowerCase()}.id`,\n onUpdate: prop.onUpdate ?? \"RESTRICT\",\n onDelete: prop.onDelete ?? \"RESTRICT\",\n });\n }\n }\n\n return r;\n },\n {\n table: entity.table,\n columns: [] as MigrationColumn[],\n indexes: [] as MigrationIndex[],\n foreigns: [] as MigrationForeign[],\n joinTables: [] as MigrationJoinTable[],\n }\n );\n\n // indexes\n migrationSet.indexes = entity.indexes.filter((index) =>\n index.columns.find((col) => col.includes(\".\") === false)\n );\n\n // uuid\n migrationSet.columns = migrationSet.columns.concat({\n name: \"uuid\",\n nullable: true,\n type: \"uuid\",\n } as MigrationColumn);\n migrationSet.indexes = migrationSet.indexes.concat({\n type: \"unique\",\n columns: [\"uuid\"],\n } as MigrationIndex);\n\n return migrationSet;\n}\n"],"names":["getMigrationSetFromDB","getMigrationSetFromEntity","compareDB","table","dbColumns","dbIndexes","dbForeigns","e","columns","dbIndexesGroup","parseIndexType","indexes","foreigns","readTable","isKnexError","code","console","error","map","dbColumn","dbColType","resolveDBColType","Type","Field","name","nullable","Null","Default","defaultTo","_","groupBy","filter","dbIndex","Key_name","find","dbForeign","keyName","index","Index_type","Non_unique","Object","keys","currentIndexes","type","currentIndex","Column_name","from","to","referencesTable","referencesField","onUpdate","onDelete","tableName","_cols","cols","row","ddl","matched","foreignKeys","raw","col","replace","length","Extra","match","line","Error","onClause","onUpdateFull","_onUpdate","trim","colType","colField","split","rawType","unsigned","parseInt","undefined","startsWith","precision","scale","entity","migrationSet","props","reduce","r","prop","isVirtualProp","isHasManyRelationProp","isRelationProp","isTextProp","textType","isEnumProp","column","isIntegerProp","isStringProp","dbDefault","isDecimalProp","isFloatProp","push","isManyToManyRelationProp","relMd","EntityManager","get","with","table1","table2","join","through","inflection","joinTable","singularize","fields","joinTables","includes","field","isBelongsToOneRelationProp","isOneToOneRelationProp","hasJoinColumn","idColumnName","useConstraint","underscore","pluralize","toLowerCase","concat"],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Knex } from "knex";
|
|
2
|
+
import { SonamuDBConfig } from "../database/db";
|
|
3
|
+
import { MigrationStatus } from "./types";
|
|
4
|
+
type MigratorMode = "dev" | "deploy";
|
|
5
|
+
export type MigratorOptions = {
|
|
6
|
+
readonly mode: MigratorMode;
|
|
7
|
+
};
|
|
8
|
+
export declare class Migrator {
|
|
9
|
+
private readonly options;
|
|
10
|
+
targets: {
|
|
11
|
+
compare?: Knex;
|
|
12
|
+
pending: Knex;
|
|
13
|
+
shadow: Knex;
|
|
14
|
+
apply: Knex[];
|
|
15
|
+
};
|
|
16
|
+
constructor(options: MigratorOptions);
|
|
17
|
+
private getMigrationCodes;
|
|
18
|
+
/**
|
|
19
|
+
* 타겟별 마이그레이션 상태와 코드 생성/준비 상태를 구해옵니다.
|
|
20
|
+
* 실제로 DB에 접근도 하고 마이그레이션 코드 파일도 확인하고,
|
|
21
|
+
* 필요하다면 적용할 수 있는 코드를 생성까지 해옵니다.
|
|
22
|
+
*
|
|
23
|
+
* CLI와 Sonamu UI에서 사용됩니다.
|
|
24
|
+
*
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
getStatus(): Promise<MigrationStatus>;
|
|
28
|
+
/**
|
|
29
|
+
* 마이그레이션을 적용하거나 롤백합니다.
|
|
30
|
+
* Sonamu UI에서 마이그레이션 작업을 수행할 때 사용됩니다.
|
|
31
|
+
*
|
|
32
|
+
* CLI와 Sonamu UI에서 사용됩니다.
|
|
33
|
+
*
|
|
34
|
+
* @param action 작업 유형 (apply/rollback)
|
|
35
|
+
* @param targets 작업 대상 DB 설정 키 (keyof SonamuDBConfig)
|
|
36
|
+
* @returns 작업 결과
|
|
37
|
+
*/
|
|
38
|
+
runAction(action: "apply" | "rollback", targets: (keyof SonamuDBConfig)[]): Promise<{
|
|
39
|
+
connKey: string;
|
|
40
|
+
batchNo: number;
|
|
41
|
+
applied: string[];
|
|
42
|
+
}[]>;
|
|
43
|
+
/**
|
|
44
|
+
* 마이그레이션 코드 파일을 삭제합니다.
|
|
45
|
+
*
|
|
46
|
+
* Sonamu UI에서 사용됩니다.
|
|
47
|
+
*
|
|
48
|
+
* @param codeNames 삭제할 마이그레이션 코드 파일 이름 배열
|
|
49
|
+
* @returns 삭제된 마이그레이션 코드 파일 개수
|
|
50
|
+
*/
|
|
51
|
+
delCodes(codeNames: string[]): Promise<number>;
|
|
52
|
+
/**
|
|
53
|
+
* 마이그레이션 코드 파일을 생성합니다.
|
|
54
|
+
*
|
|
55
|
+
* Sonamu UI에서 사용됩니다.
|
|
56
|
+
*
|
|
57
|
+
* @returns 생성된 마이그레이션 코드 파일 개수
|
|
58
|
+
*/
|
|
59
|
+
generatePreparedCodes(): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* pending 마이그레이션 목록을 삭제합니다.
|
|
62
|
+
*
|
|
63
|
+
* CLI에서 사용됩니다.
|
|
64
|
+
*/
|
|
65
|
+
clearPendingList(): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* 마이그레이션 코드 파일을 확인합니다.
|
|
68
|
+
*
|
|
69
|
+
* CLI에서 사용됩니다.
|
|
70
|
+
*/
|
|
71
|
+
check(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* 마이그레이션을 수행합니다.
|
|
74
|
+
*
|
|
75
|
+
* runAction이 인자로 들어온 타겟들에 대해 주어진 동작(apply/rollback)을 수행한다면,
|
|
76
|
+
* 이 함수는 생성자로 들어온 connection(knex)들에 대해 마이그레이션을 수행합니다.
|
|
77
|
+
*
|
|
78
|
+
* CLI에서 사용됩니다.
|
|
79
|
+
*/
|
|
80
|
+
run(): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* 타겟으로 지정된 DB를 롤백합니다.
|
|
83
|
+
*
|
|
84
|
+
* runAction이 인자로 들어온 타겟들에 대해 주어진 동작(apply/rollback)을 수행한다면,
|
|
85
|
+
* 이 함수는 생성자로 들어온 connection(knex)들에 대해 롤백을 수행합니다.
|
|
86
|
+
*
|
|
87
|
+
* CLI에서 사용됩니다.
|
|
88
|
+
*/
|
|
89
|
+
rollback(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* 빌드된 마이그레이션 파일을 삭제합니다.
|
|
92
|
+
*
|
|
93
|
+
* CLI에서 사용됩니다.
|
|
94
|
+
*
|
|
95
|
+
* @param force 강제 삭제 여부
|
|
96
|
+
* @returns
|
|
97
|
+
*/
|
|
98
|
+
cleanUpDist(force?: boolean): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Shadow DB 테스트를 진행합니다.
|
|
101
|
+
*
|
|
102
|
+
* Sonamu UI에서 사용됩니다.
|
|
103
|
+
*
|
|
104
|
+
* @returns Shadow DB 테스트 결과
|
|
105
|
+
*/
|
|
106
|
+
runShadowTest(): Promise<{
|
|
107
|
+
connKey: string;
|
|
108
|
+
batchNo: number;
|
|
109
|
+
applied: string[];
|
|
110
|
+
}[]>;
|
|
111
|
+
/**
|
|
112
|
+
* 모든 DB를 롤백하고 전체 마이그레이션 파일을 삭제합니다.
|
|
113
|
+
*
|
|
114
|
+
* CLI에서 사용됩니다.
|
|
115
|
+
*
|
|
116
|
+
* @returns
|
|
117
|
+
*/
|
|
118
|
+
resetAll(): Promise<void>;
|
|
119
|
+
private compareMigrations;
|
|
120
|
+
/**
|
|
121
|
+
* 마이그레이션 대상 커넥션을 종료합니다.
|
|
122
|
+
*
|
|
123
|
+
* CLI에서 사용됩니다.
|
|
124
|
+
*
|
|
125
|
+
* @returns {Promise<void>} 종료 결과
|
|
126
|
+
*/
|
|
127
|
+
destroy(): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
export {};
|
|
130
|
+
//# sourceMappingURL=migrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../../src/migration/migrator.ts"],"names":[],"mappings":"AACA,OAAa,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAYlC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,eAAe,EAA6B,MAAM,SAAS,CAAC;AAIrE,KAAK,YAAY,GAAG,KAAK,GAAG,QAAQ,CAAC;AACrC,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,qBAAa,QAAQ;IAQP,OAAO,CAAC,QAAQ,CAAC,OAAO;IAPpC,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,IAAI,CAAC;QACf,OAAO,EAAE,IAAI,CAAC;QACd,MAAM,EAAE,IAAI,CAAC;QACb,KAAK,EAAE,IAAI,EAAE,CAAC;KACf,CAAC;gBAE2B,OAAO,EAAE,eAAe;YA2CvC,iBAAiB;IA2D/B;;;;;;;;OAQG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAgH3C;;;;;;;;;OASG;IACG,SAAS,CACb,MAAM,EAAE,OAAO,GAAG,UAAU,EAC5B,OAAO,EAAE,CAAC,MAAM,cAAc,CAAC,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,EAAE,CACJ;IA6DD;;;;;;;OAOG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAkCpD;;;;;;OAMG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAwB9C;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBvC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B;;;;;;;OAOG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA8E1B;;;;;;;OAOG;IACG,QAAQ;IAYd;;;;;;;OAOG;IACG,WAAW,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA4DxD;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAC5B;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,EAAE,CACJ;IAmED;;;;;;OAMG;IACG,QAAQ;YA4BA,iBAAiB;IAqE/B;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAO/B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"Migrator",{enumerable:true,get:function(){return Migrator}});var _lodash=/*#__PURE__*/_interop_require_default(require("lodash"));var _knex=/*#__PURE__*/_interop_require_default(require("knex"));var _chalk=/*#__PURE__*/_interop_require_default(require("chalk"));var _luxon=require("luxon");var _promises=require("fs/promises");var _fsutils=require("../utils/fs-utils");var _prompts=/*#__PURE__*/_interop_require_default(require("prompts"));var _child_process=require("child_process");var _path=/*#__PURE__*/_interop_require_default(require("path"));var _entitymanager=require("../entity/entity-manager");var _api=require("../api");var _soexceptions=require("../exceptions/so-exceptions");var _codegeneration=require("./code-generation");var _migrationset=require("./migration-set");function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};var ownKeys=Object.keys(source);if(typeof Object.getOwnPropertySymbols==="function"){ownKeys=ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym){return Object.getOwnPropertyDescriptor(source,sym).enumerable}))}ownKeys.forEach(function(key){_define_property(target,key,source[key])})}return target}function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);if(enumerableOnly){symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable})}keys.push.apply(keys,symbols)}return keys}function _object_spread_props(target,source){source=source!=null?source:{};if(Object.getOwnPropertyDescriptors){Object.defineProperties(target,Object.getOwnPropertyDescriptors(source))}else{ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key))})}return target}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["return"]=verb(2),typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]<t[3])){_.label=op[1];break}if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break}if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break}if(t[2])_.ops.pop();_.trys.pop();continue}op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0}if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true}}}var Migrator=/*#__PURE__*/function(){"use strict";function Migrator(options){_class_call_check(this,Migrator);_define_property(this,"options",void 0);_define_property(this,"targets",void 0);this.options=options;var dbConfig=_api.Sonamu.dbConfig;if(this.options.mode==="dev"){var devDB=(0,_knex.default)(dbConfig.development_master);var testDB=(0,_knex.default)(dbConfig.test);var fixtureLocalDB=(0,_knex.default)(dbConfig.fixture_local);var applyDBs=[devDB,testDB,fixtureLocalDB];if(dbConfig.fixture_local.connection.host!==dbConfig.fixture_remote.connection.host||dbConfig.fixture_local.connection.database!==dbConfig.fixture_remote.connection.database){var fixtureRemoteDB=(0,_knex.default)(dbConfig.fixture_remote);applyDBs.push(fixtureRemoteDB)}this.targets={compare:devDB,pending:devDB,shadow:testDB,apply:applyDBs}}else if(this.options.mode==="deploy"){var productionDB=(0,_knex.default)(dbConfig.production_master);var testDB1=(0,_knex.default)(dbConfig.test);this.targets={pending:productionDB,shadow:testDB1,apply:[productionDB]}}else{throw new Error("잘못된 모드 ".concat(this.options.mode," 입력"))}}_create_class(Migrator,[{key:"getMigrationCodes",value:function getMigrationCodes(){return _async_to_generator(function(){var srcMigrationsDir,distMigrationsDir,srcMigrations,distMigrations,normal,onlyTs,onlyJs;return _ts_generator(this,function(_state){switch(_state.label){case 0:srcMigrationsDir="".concat(_api.Sonamu.apiRootPath,"/src/migrations");distMigrationsDir="".concat(_api.Sonamu.apiRootPath,"/dist/migrations");return[4,(0,_fsutils.exists)(srcMigrationsDir)];case 1:if(!!_state.sent())return[3,3];return[4,(0,_promises.mkdir)(srcMigrationsDir,{recursive:true})];case 2:_state.sent();_state.label=3;case 3:return[4,(0,_fsutils.exists)(distMigrationsDir)];case 4:if(!!_state.sent())return[3,6];return[4,(0,_promises.mkdir)(distMigrationsDir,{recursive:true})];case 5:_state.sent();_state.label=6;case 6:return[4,(0,_promises.readdir)(srcMigrationsDir)];case 7:srcMigrations=_state.sent().filter(function(f){return f.endsWith(".ts")}).map(function(f){return f.split(".")[0]});return[4,(0,_promises.readdir)(distMigrationsDir)];case 8:distMigrations=_state.sent().filter(function(f){return f.endsWith(".js")}).map(function(f){return f.split(".")[0]});normal=_lodash.default.intersection(srcMigrations,distMigrations).map(function(filename){return{name:filename,path:_path.default.join(srcMigrationsDir,filename)+".ts"}}).sort(function(a,b){return a>b?1:-1});onlyTs=_lodash.default.difference(srcMigrations,distMigrations).map(function(filename){return{name:filename,path:_path.default.join(srcMigrationsDir,filename)+".ts"}});onlyJs=_lodash.default.difference(distMigrations,srcMigrations).map(function(filename){return{name:filename,path:_path.default.join(distMigrationsDir,filename)+".js"}});return[2,{normal:normal,onlyTs:onlyTs,onlyJs:onlyJs}]}})})()}},{key:"getStatus",value:function getStatus(){return _async_to_generator(function(){var _this,_ref,normal,onlyTs,onlyJs,connKeys,statuses,preparedCodes;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;return[4,this.getMigrationCodes()];case 1:_ref=_state.sent(),normal=_ref.normal,onlyTs=_ref.onlyTs,onlyJs=_ref.onlyJs;if(onlyTs.length>0){console.debug({onlyTs:onlyTs});throw new _soexceptions.ServiceUnavailableException("There are un-compiled TS migration files.\nPlease compile them first. You might want to run a development server with HMR.\n\n".concat(onlyTs.map(function(f){return f.name}).join("\n")))}if(!(onlyJs.length>0))return[3,3];console.debug({onlyJs:onlyJs});return[4,Promise.all(onlyJs.map(function(f){return _async_to_generator(function(){return _ts_generator(this,function(_state){(0,_child_process.execSync)("rm -f ".concat(f.path.replace("/src/","/dist/").replace(".ts",".js")));return[2]})})()}))];case 2:_state.sent();_state.label=3;case 3:connKeys=Object.keys(_api.Sonamu.dbConfig).filter(function(key){return key.endsWith("_slave")===false});return[4,Promise.all(connKeys.map(function(connKey){return _async_to_generator(function(){var knexOptions,tConn,status,pending,currentVersion,connection,_connection_user;return _ts_generator(this,function(_state){switch(_state.label){case 0:knexOptions=_api.Sonamu.dbConfig[connKey];tConn=(0,_knex.default)(knexOptions);return[4,function(){return _async_to_generator(function(){var err;return _ts_generator(this,function(_state){switch(_state.label){case 0:_state.trys.push([0,2,,3]);return[4,tConn.migrate.status()];case 1:return[2,_state.sent()];case 2:err=_state.sent();console.warn(_chalk.default.yellow("".concat(connKey,"의 마이그레이션 상태를 가져오는 데에 실패하였습니다. 데이터베이스가 올바르게 구성되지 않은 것 같습니다. 확인하시고 다시 시도해주세요.\n시도한 연결 설정:\n").concat(JSON.stringify(knexOptions.connection,null,2),"\n발생한 에러:\n").concat(err,"\n")));return[2,"error"];case 3:return[2]}})})()}()];case 1:status=_state.sent();return[4,function(){return _async_to_generator(function(){var _ref,fdList,err;return _ts_generator(this,function(_state){switch(_state.label){case 0:_state.trys.push([0,2,,3]);return[4,tConn.migrate.list()];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),2]),fdList=_ref[1];return[2,fdList.map(function(fd){return fd.file.replace(".js","")})];case 2:err=_state.sent();return[2,[]];case 3:return[2]}})})()}()];case 2:pending=_state.sent();return[4,function(){return _async_to_generator(function(){var err;return _ts_generator(this,function(_state){switch(_state.label){case 0:_state.trys.push([0,2,,3]);return[4,tConn.migrate.currentVersion()];case 1:return[2,_state.sent()];case 2:err=_state.sent();return[2,"error"];case 3:return[2]}})})()}()];case 3:currentVersion=_state.sent();connection=knexOptions.connection;return[4,tConn.destroy()];case 4:_state.sent();return[2,{name:connKey.replace("_master",""),connKey:connKey,connString:"mysql2://".concat((_connection_user=connection.user)!==null&&_connection_user!==void 0?_connection_user:"","@").concat(connection.host,":").concat(connection.port,"/").concat(connection.database),currentVersion:currentVersion,status:status,pending:pending}]}})})()}))];case 4:statuses=_state.sent();return[4,function(){return _async_to_generator(function(){var status0conn,compareDBconn,genCodes;return _ts_generator(this,function(_state){switch(_state.label){case 0:status0conn=statuses.find(function(status){return status.status===0});if(status0conn===undefined){return[2,[]]}compareDBconn=(0,_knex.default)(_api.Sonamu.dbConfig[status0conn.connKey]);return[4,this.compareMigrations(compareDBconn)];case 1:genCodes=_state.sent();return[4,compareDBconn.destroy()];case 2:_state.sent();return[2,genCodes]}})}).call(_this)}()];case 5:preparedCodes=_state.sent();return[2,{conns:statuses,codes:normal,preparedCodes:preparedCodes}]}})}).call(this)}},{key:"runAction",value:function runAction(action,targets){return _async_to_generator(function(){var configs,conns,result;return _ts_generator(this,function(_state){switch(_state.label){case 0:configs=_lodash.default.uniqBy(targets.map(function(target){return{connKey:target,options:_api.Sonamu.dbConfig[target]}}).filter(function(c){return c.options!==undefined}),function(param){var options=param.options;var _options_connection_port;return"".concat(options.connection.host,":").concat((_options_connection_port=options.connection.port)!==null&&_options_connection_port!==void 0?_options_connection_port:3306,"/").concat(options.connection.database)});return[4,Promise.all(configs.map(function(config){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,{connKey:config.connKey,knex:(0,_knex.default)(config.options)}]})})()}))];case 1:conns=_state.sent();return[4,function(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(action){case"apply":return[2,Promise.all(conns.map(function(param){var connKey=param.connKey,knex=param.knex;return _async_to_generator(function(){var _ref,batchNo,applied;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,knex.migrate.latest()];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),2]),batchNo=_ref[0],applied=_ref[1];return[2,{connKey:connKey,batchNo:batchNo,applied:applied}]}})})()}))];case"rollback":return[2,Promise.all(conns.map(function(param){var connKey=param.connKey,knex=param.knex;return _async_to_generator(function(){var _ref,batchNo,applied;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,knex.migrate.rollback()];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),2]),batchNo=_ref[0],applied=_ref[1];return[2,{connKey:connKey,batchNo:batchNo,applied:applied}]}})})()}))]}return[2]})})()}()];case 2:result=_state.sent();return[4,Promise.all(conns.map(function(param){var knex=param.knex;return knex.destroy()}))];case 3:_state.sent();return[2,result]}})})()}},{key:"delCodes",value:function delCodes(codeNames){return _async_to_generator(function(){var conns,delFiles,res;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.getStatus()];case 1:conns=_state.sent().conns;if(conns.some(function(conn){return codeNames.some(function(codeName){return conn.pending.includes(codeName)===false})})){throw new Error("You cannot delete a migration file if there is already applied.")}delFiles=codeNames.map(function(codeName){return["".concat(_api.Sonamu.apiRootPath,"/src/migrations/").concat(codeName,".ts"),"".concat(_api.Sonamu.apiRootPath,"/dist/migrations/").concat(codeName,".js")]}).flat();return[4,Promise.all(delFiles.map(function(delFile){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_fsutils.exists)(delFile)];case 1:if(!_state.sent())return[3,3];console.log(_chalk.default.red("DELETE: ".concat(delFile)));return[4,(0,_promises.unlink)(delFile)];case 2:_state.sent();return[2,delFiles.includes(".ts")?1:0];case 3:return[2,0]}})})()}))];case 2:res=_state.sent();return[2,_lodash.default.sum(res)]}})}).call(this)}},{key:"generatePreparedCodes",value:function generatePreparedCodes(){return _async_to_generator(function(){var preparedCodes,migrationsDir,_iteratorNormalCompletion,_didIteratorError,_iteratorError,_iterator,_step,_step_value,index,pcode,dateTag,filePath,err;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.getStatus()];case 1:preparedCodes=_state.sent().preparedCodes;if(preparedCodes.length===0){console.log(_chalk.default.green("\n현재 모두 싱크된 상태입니다."));return[2,0]}migrationsDir="".concat(_api.Sonamu.apiRootPath,"/src/migrations");_iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;_state.label=2;case 2:_state.trys.push([2,7,8,9]);_iterator=preparedCodes.entries()[Symbol.iterator]();_state.label=3;case 3:if(!!(_iteratorNormalCompletion=(_step=_iterator.next()).done))return[3,6];_step_value=_sliced_to_array(_step.value,2),index=_step_value[0],pcode=_step_value[1];if(!pcode.formatted)return[3,5];dateTag=_luxon.DateTime.local().plus({seconds:index}).toFormat("yyyyMMddHHmmss");filePath="".concat(migrationsDir,"/").concat(dateTag,"_").concat(pcode.title,".ts");return[4,(0,_promises.writeFile)(filePath,pcode.formatted)];case 4:_state.sent();console.log(_chalk.default.green("MIGRTAION CREATED ".concat(filePath)));_state.label=5;case 5:_iteratorNormalCompletion=true;return[3,3];case 6:return[3,9];case 7:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,9];case 8:try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}return[7];case 9:return[2,preparedCodes.length]}})}).call(this)}},{key:"clearPendingList",value:function clearPendingList(){return _async_to_generator(function(){var _ref,pendingList,migrationsDir,delList,_iteratorNormalCompletion,_didIteratorError,_iteratorError,_iterator,_step,p,err;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.targets.pending.migrate.list()];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),2]),pendingList=_ref[1];migrationsDir="".concat(_api.Sonamu.apiRootPath,"/src/migrations");delList=pendingList.map(function(df){return _path.default.join(migrationsDir,df.file).replace(".js",".ts")});_iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;_state.label=2;case 2:_state.trys.push([2,8,9,10]);_iterator=delList[Symbol.iterator]();_state.label=3;case 3:if(!!(_iteratorNormalCompletion=(_step=_iterator.next()).done))return[3,7];p=_step.value;return[4,(0,_fsutils.exists)(p)];case 4:if(!_state.sent())return[3,6];return[4,(0,_promises.unlink)(p)];case 5:_state.sent();_state.label=6;case 6:_iteratorNormalCompletion=true;return[3,3];case 7:return[3,10];case 8:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,10];case 9:try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}return[7];case 10:return[4,this.cleanUpDist(true)];case 11:_state.sent();return[2]}})}).call(this)}},{key:"check",value:function check(){return _async_to_generator(function(){var codes;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.compareMigrations(this.targets.compare)];case 1:codes=_state.sent();if(codes.length===0){console.log(_chalk.default.green("\n현재 모두 싱크된 상태입니다."));return[2]}console.table(codes,["type","title"]);console.log(codes[0]);return[2]}})}).call(this)}},{key:"run",value:function run(){return _async_to_generator(function(){var _ref,pendingList,answer,codes,answer1,migrationsDir,_iteratorNormalCompletion,_didIteratorError,_iteratorError,_iterator,_step,_step_value,index,code,dateTag,filePath,err;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.targets.pending.migrate.list()];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),2]),pendingList=_ref[1];if(!(pendingList.length>0))return[3,5];console.log(_chalk.default.red("pending 된 마이그레이션이 존재합니다."),pendingList.map(function(pending){return pending.file}));return[4,(0,_prompts.default)({type:"confirm",name:"value",message:"Shadow DB 테스트를 진행하시겠습니까?",initial:true})];case 2:answer=_state.sent();if(answer.value===false){return[2]}console.time(_chalk.default.blue("Migrator - runShadowTest"));return[4,this.runShadowTest()];case 3:_state.sent();console.timeEnd(_chalk.default.blue("Migrator - runShadowTest"));return[4,Promise.all(this.targets.apply.map(function(applyDb){return _async_to_generator(function(){var label,_ref;return _ts_generator(this,function(_state){switch(_state.label){case 0:label=_chalk.default.green("APPLIED ".concat(applyDb.client.connectionSettings.host," ").concat(applyDb.client.database()));console.time(label);return[4,applyDb.migrate.latest()];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),1]);console.timeEnd(label);return[2]}})})()}))];case 4:_state.sent();_state.label=5;case 5:return[4,this.compareMigrations(this.targets.compare)];case 6:codes=_state.sent();if(codes.length===0){console.log(_chalk.default.green("\n현재 모두 싱크된 상태입니다."));return[2]}console.table(codes,["type","title"]);return[4,(0,_prompts.default)({type:"confirm",name:"value",message:"마이그레이션 코드를 생성하시겠습니까?",initial:false})];case 7:answer1=_state.sent();if(answer1.value===false){return[2]}migrationsDir="".concat(_api.Sonamu.apiRootPath,"/src/migrations");_iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;_state.label=8;case 8:_state.trys.push([8,13,14,15]);_iterator=codes.entries()[Symbol.iterator]();_state.label=9;case 9:if(!!(_iteratorNormalCompletion=(_step=_iterator.next()).done))return[3,12];_step_value=_sliced_to_array(_step.value,2),index=_step_value[0],code=_step_value[1];if(!code.formatted)return[3,11];dateTag=_luxon.DateTime.local().plus({seconds:index}).toFormat("yyyyMMddHHmmss");filePath="".concat(migrationsDir,"/").concat(dateTag,"_").concat(code.title,".ts");return[4,(0,_promises.writeFile)(filePath,code.formatted)];case 10:_state.sent();console.log(_chalk.default.green("MIGRTAION CREATED ".concat(filePath)));_state.label=11;case 11:_iteratorNormalCompletion=true;return[3,9];case 12:return[3,15];case 13:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,15];case 14:try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}return[7];case 15:return[2]}})}).call(this)}},{key:"rollback",value:function rollback(){return _async_to_generator(function(){var rollbackAllResult;return _ts_generator(this,function(_state){switch(_state.label){case 0:console.time(_chalk.default.red("rollback:"));return[4,Promise.all(this.targets.apply.map(function(db){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,db.migrate.forceFreeMigrationsLock()];case 1:_state.sent();return[2,db.migrate.rollback(undefined,false)]}})})()}))];case 1:rollbackAllResult=_state.sent();console.dir({rollbackAllResult:rollbackAllResult},{depth:null});console.timeEnd(_chalk.default.red("rollback:"));return[2]}})}).call(this)}},{key:"cleanUpDist",value:function cleanUpDist(){var force=arguments.length>0&&arguments[0]!==void 0?arguments[0]:false;return _async_to_generator(function(){var files,_tmp,diffOnSrc,diffOnDist,answer,filesToRm,_iteratorNormalCompletion,_didIteratorError,_iteratorError,_iterator,_step,filePath,err;function getFilesUnder(dir){return _async_to_generator(function(){var migrationPath;return _ts_generator(this,function(_state){switch(_state.label){case 0:migrationPath=_path.default.join(_api.Sonamu.apiRootPath,dir,"migrations");return[4,(0,_fsutils.exists)(migrationPath)];case 1:if(!!_state.sent())return[3,3];return[4,(0,_promises.mkdir)(migrationPath,{recursive:true})];case 2:_state.sent();_state.label=3;case 3:return[4,(0,_promises.readdir)(migrationPath)];case 4:return[2,_state.sent().filter(function(filename){return filename.startsWith(".")===false})]}})})()}return _ts_generator(this,function(_state){switch(_state.label){case 0:_tmp={};return[4,getFilesUnder("src")];case 1:_tmp.src=_state.sent();return[4,getFilesUnder("dist")];case 2:files=(_tmp.dist=_state.sent(),_tmp);diffOnSrc=_lodash.default.differenceBy(files.src,files.dist,function(filename){return filename.split(".")[0]});if(diffOnSrc.length>0){throw new Error("컴파일 되지 않은 파일이 있습니다.\n"+diffOnSrc.join("\n"))}diffOnDist=_lodash.default.differenceBy(files.dist,files.src,function(filename){return filename.split(".")[0]});if(!(diffOnDist.length>0))return[3,13];console.log(_chalk.default.red("원본 ts파일을 찾을 수 없는 js파일이 있습니다."));console.log(diffOnDist);if(!!force)return[3,4];return[4,(0,_prompts.default)({type:"confirm",name:"value",message:"삭제를 진행하시겠습니까?",initial:true})];case 3:answer=_state.sent();if(answer.value===false){return[2]}_state.label=4;case 4:filesToRm=diffOnDist.map(function(filename){return _path.default.join(_api.Sonamu.apiRootPath,"dist","migrations",filename)});_iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;_state.label=5;case 5:_state.trys.push([5,10,11,12]);_iterator=filesToRm[Symbol.iterator]();_state.label=6;case 6:if(!!(_iteratorNormalCompletion=(_step=_iterator.next()).done))return[3,9];filePath=_step.value;return[4,(0,_promises.unlink)(filePath)];case 7:_state.sent();_state.label=8;case 8:_iteratorNormalCompletion=true;return[3,6];case 9:return[3,12];case 10:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,12];case 11:try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}return[7];case 12:console.log(_chalk.default.green("".concat(filesToRm.length,"건 삭제되었습니다!")));_state.label=13;case 13:return[2]}})})()}},{key:"runShadowTest",value:function runShadowTest(){return _async_to_generator(function(){var tdb,tdbConn,shadowDatabase,tmpSqlPath,_tdbConn_port,_tdbConn_port1,sdb,_ref,batchNo,applied,e;return _ts_generator(this,function(_state){switch(_state.label){case 0:tdb=(0,_knex.default)(_api.Sonamu.dbConfig.test);tdbConn=_api.Sonamu.dbConfig.test.connection;shadowDatabase=tdbConn.database+"__migration_shadow";tmpSqlPath="/tmp/".concat(shadowDatabase,".sql");console.log(_chalk.default.magenta("".concat(tdbConn.database,"의 데이터 ").concat(tmpSqlPath,"로 덤프")));(0,_child_process.execSync)("mysqldump -h".concat(tdbConn.host," -P").concat((_tdbConn_port=tdbConn.port)!==null&&_tdbConn_port!==void 0?_tdbConn_port:3306," -u").concat(tdbConn.user," -p'").concat(tdbConn.password,"' ").concat(tdbConn.database," --single-transaction --no-create-db --triggers > ").concat(tmpSqlPath,";"));(0,_child_process.execSync)("sed -i'' -e 's/`".concat(tdbConn.database,"`/`").concat(shadowDatabase,"`/g' ").concat(tmpSqlPath,";"));console.log(_chalk.default.magenta("".concat(shadowDatabase," 리셋")));return[4,tdb.raw("DROP DATABASE IF EXISTS `".concat(shadowDatabase,"`;"))];case 1:_state.sent();return[4,tdb.raw("CREATE DATABASE `".concat(shadowDatabase,"`;"))];case 2:_state.sent();console.log(_chalk.default.magenta("".concat(shadowDatabase," 데이터베이스 생성")));(0,_child_process.execSync)("mysql -h".concat(tdbConn.host," -P").concat((_tdbConn_port1=tdbConn.port)!==null&&_tdbConn_port1!==void 0?_tdbConn_port1:3306," -u").concat(tdbConn.user," -p'").concat(tdbConn.password,"' ").concat(shadowDatabase," < ").concat(tmpSqlPath,";"));sdb=(0,_knex.default)(_object_spread_props(_object_spread({},_api.Sonamu.dbConfig.test),{connection:_object_spread_props(_object_spread({},tdbConn),{database:shadowDatabase,password:tdbConn.password})}));_state.label=3;case 3:_state.trys.push([3,6,7,9]);return[4,sdb.migrate.latest()];case 4:_ref=_sliced_to_array.apply(void 0,[_state.sent(),2]),batchNo=_ref[0],applied=_ref[1];console.log(_chalk.default.green("Shadow DB 테스트에 성공했습니다!"),{batchNo:batchNo,applied:applied});console.log(_chalk.default.magenta("".concat(shadowDatabase," 삭제")));return[4,tdb.raw("DROP DATABASE IF EXISTS `".concat(shadowDatabase,"`;"))];case 5:_state.sent();return[2,[{connKey:"shadow",batchNo:batchNo,applied:applied}]];case 6:e=_state.sent();console.error(e);throw new _soexceptions.ServiceUnavailableException("Shadow DB 테스트 진행 중 에러");case 7:return[4,tdb.destroy()];case 8:_state.sent();return[7];case 9:return[2]}})})()}},{key:"resetAll",value:function resetAll(){return _async_to_generator(function(){var answer,rollbackAllResult,migrationsDir;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_prompts.default)({type:"confirm",name:"value",message:"모든 DB를 롤백하고 전체 마이그레이션 파일을 삭제하시겠습니까?",initial:false})];case 1:answer=_state.sent();if(answer.value===false){return[2]}console.time(_chalk.default.red("rollback-all:"));return[4,Promise.all(this.targets.apply.map(function(db){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,db.migrate.forceFreeMigrationsLock()];case 1:_state.sent();return[2,db.migrate.rollback(undefined,true)]}})})()}))];case 2:rollbackAllResult=_state.sent();console.log({rollbackAllResult:rollbackAllResult});console.timeEnd(_chalk.default.red("rollback-all:"));migrationsDir="".concat(_api.Sonamu.apiRootPath,"/src/migrations");console.time(_chalk.default.red("delete migration files"));(0,_child_process.execSync)("rm -f ".concat(migrationsDir,"/*"));(0,_child_process.execSync)("rm -f ".concat(migrationsDir.replace("/src/","/dist/"),"/*"));console.timeEnd(_chalk.default.red("delete migration files"));return[2]}})}).call(this)}},{key:"compareMigrations",value:function compareMigrations(compareDB){return _async_to_generator(function(){var entityIds,entitySetsWithJoinTable,joinTablesWithDup,joinTables,entitySets,codes;return _ts_generator(this,function(_state){switch(_state.label){case 0:entityIds=_entitymanager.EntityManager.getAllIds();entitySetsWithJoinTable=entityIds.filter(function(entityId){return _entitymanager.EntityManager.get(entityId).props.length>0}).map(function(entityId){return(0,_migrationset.getMigrationSetFromEntity)(_entitymanager.EntityManager.get(entityId))});joinTablesWithDup=entitySetsWithJoinTable.map(function(entitySet){return entitySet.joinTables}).flat();joinTables=Object.values(_lodash.default.groupBy(joinTablesWithDup,function(jt){return jt.table})).map(function(tables){if(tables.length===1){return tables[0]}return _object_spread_props(_object_spread({},tables[0]),{indexes:_lodash.default.uniqBy(tables.flatMap(function(t){return t.indexes}),function(index){return[index.type].concat(_to_consumable_array(index.columns.sort())).join("-")})})});entitySets=_to_consumable_array(entitySetsWithJoinTable).concat(_to_consumable_array(joinTables));return[4,Promise.all(entitySets.map(function(entitySet){return _async_to_generator(function(){var dbSet;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_migrationset.getMigrationSetFromDB)(compareDB,entitySet.table)];case 1:dbSet=_state.sent();if(!(dbSet===null))return[3,3];return[4,(0,_codegeneration.generateCreateCode)(entitySet)];case 2:return[2,_state.sent()];case 3:return[4,(0,_codegeneration.generateAlterCode)(entitySet,dbSet)];case 4:return[2,_state.sent()];case 5:return[2]}})})()}))];case 1:codes=_state.sent().flat();codes.sort(function(codeA,codeB){if(codeA.type==="foreign"&&codeB.type=="normal"){return 1}else if(codeA.type==="normal"&&codeB.type==="foreign"){return-1}else{return 0}});return[2,codes]}})})()}},{key:"destroy",value:function destroy(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,Promise.all(this.targets.apply.map(function(db){return db.destroy()}))];case 1:_state.sent();return[2]}})}).call(this)}}]);return Migrator}();
|
|
2
|
+
//# sourceMappingURL=migrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/migration/migrator.ts"],"sourcesContent":["import _ from \"lodash\";\nimport knex, { Knex } from \"knex\";\nimport chalk from \"chalk\";\nimport { DateTime } from \"luxon\";\nimport { mkdir, readdir, unlink, writeFile } from \"fs/promises\";\nimport { exists } from \"../utils/fs-utils\";\nimport prompts from \"prompts\";\nimport { execSync } from \"child_process\";\nimport path from \"path\";\nimport { GenMigrationCode, MigrationSet } from \"../types/types\";\nimport { EntityManager } from \"../entity/entity-manager\";\nimport { Sonamu } from \"../api\";\nimport { ServiceUnavailableException } from \"../exceptions/so-exceptions\";\nimport { SonamuDBConfig } from \"../database/db\";\nimport { generateCreateCode, generateAlterCode } from \"./code-generation\";\nimport { MigrationStatus, MigrationCode, ConnString } from \"./types\";\nimport { getMigrationSetFromDB } from \"./migration-set\";\nimport { getMigrationSetFromEntity } from \"./migration-set\";\n\ntype MigratorMode = \"dev\" | \"deploy\";\nexport type MigratorOptions = {\n readonly mode: MigratorMode;\n};\n\nexport class Migrator {\n targets: {\n compare?: Knex;\n pending: Knex;\n shadow: Knex;\n apply: Knex[];\n };\n\n constructor(private readonly options: MigratorOptions) {\n const { dbConfig } = Sonamu;\n\n if (this.options.mode === \"dev\") {\n const devDB = knex(dbConfig.development_master);\n const testDB = knex(dbConfig.test);\n const fixtureLocalDB = knex(dbConfig.fixture_local);\n\n const applyDBs = [devDB, testDB, fixtureLocalDB];\n if (\n (dbConfig.fixture_local.connection as Knex.MySql2ConnectionConfig)\n .host !==\n (dbConfig.fixture_remote.connection as Knex.MySql2ConnectionConfig)\n .host ||\n (dbConfig.fixture_local.connection as Knex.MySql2ConnectionConfig)\n .database !==\n (dbConfig.fixture_remote.connection as Knex.MySql2ConnectionConfig)\n .database\n ) {\n const fixtureRemoteDB = knex(dbConfig.fixture_remote);\n applyDBs.push(fixtureRemoteDB);\n }\n\n this.targets = {\n compare: devDB,\n pending: devDB,\n shadow: testDB,\n apply: applyDBs,\n };\n } else if (this.options.mode === \"deploy\") {\n const productionDB = knex(dbConfig.production_master);\n const testDB = knex(dbConfig.test);\n\n this.targets = {\n pending: productionDB,\n shadow: testDB,\n apply: [productionDB],\n };\n } else {\n throw new Error(`잘못된 모드 ${this.options.mode} 입력`);\n }\n }\n\n private async getMigrationCodes(): Promise<{\n normal: MigrationCode[];\n onlyTs: MigrationCode[];\n onlyJs: MigrationCode[];\n }> {\n const srcMigrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n const distMigrationsDir = `${Sonamu.apiRootPath}/dist/migrations`;\n\n if (!(await exists(srcMigrationsDir))) {\n await mkdir(srcMigrationsDir, {\n recursive: true,\n });\n }\n if (!(await exists(distMigrationsDir))) {\n await mkdir(distMigrationsDir, {\n recursive: true,\n });\n }\n const srcMigrations = (await readdir(srcMigrationsDir))\n .filter((f) => f.endsWith(\".ts\"))\n .map((f) => f.split(\".\")[0]);\n const distMigrations = (await readdir(distMigrationsDir))\n .filter((f) => f.endsWith(\".js\"))\n .map((f) => f.split(\".\")[0]);\n\n const normal = _.intersection(srcMigrations, distMigrations)\n .map((filename) => {\n return {\n name: filename,\n path: path.join(srcMigrationsDir, filename) + \".ts\",\n };\n })\n .sort((a, b) => (a > b ? 1 : -1));\n\n const onlyTs = _.difference(srcMigrations, distMigrations).map(\n (filename) => {\n return {\n name: filename,\n path: path.join(srcMigrationsDir, filename) + \".ts\",\n };\n }\n );\n\n const onlyJs = _.difference(distMigrations, srcMigrations).map(\n (filename) => {\n return {\n name: filename,\n path: path.join(distMigrationsDir, filename) + \".js\",\n };\n }\n );\n\n return {\n normal,\n onlyTs,\n onlyJs,\n };\n }\n\n /**\n * 타겟별 마이그레이션 상태와 코드 생성/준비 상태를 구해옵니다.\n * 실제로 DB에 접근도 하고 마이그레이션 코드 파일도 확인하고,\n * 필요하다면 적용할 수 있는 코드를 생성까지 해옵니다.\n *\n * CLI와 Sonamu UI에서 사용됩니다.\n *\n * @returns\n */\n async getStatus(): Promise<MigrationStatus> {\n const { normal, onlyTs, onlyJs } = await this.getMigrationCodes();\n if (onlyTs.length > 0) {\n console.debug({ onlyTs });\n throw new ServiceUnavailableException(\n `There are un-compiled TS migration files.\\nPlease compile them first. You might want to run a development server with HMR.\\n\\n${onlyTs\n .map((f) => f.name)\n .join(\"\\n\")}`\n );\n }\n if (onlyJs.length > 0) {\n console.debug({ onlyJs });\n await Promise.all(\n onlyJs.map(async (f) => {\n execSync(\n `rm -f ${f.path.replace(\"/src/\", \"/dist/\").replace(\".ts\", \".js\")}`\n );\n })\n );\n }\n\n const connKeys = Object.keys(Sonamu.dbConfig).filter(\n (key) => key.endsWith(\"_slave\") === false\n ) as (keyof typeof Sonamu.dbConfig)[];\n\n const statuses = await Promise.all(\n connKeys.map(async (connKey) => {\n const knexOptions = Sonamu.dbConfig[connKey];\n const tConn = knex(knexOptions);\n\n const status = await (async () => {\n try {\n return await tConn.migrate.status();\n } catch (err) {\n console.warn(\n chalk.yellow(\n `${connKey}의 마이그레이션 상태를 가져오는 데에 실패하였습니다. 데이터베이스가 올바르게 구성되지 않은 것 같습니다. 확인하시고 다시 시도해주세요.\\n시도한 연결 설정:\\n${JSON.stringify(knexOptions.connection, null, 2)}\\n발생한 에러:\\n${err}\\n`\n )\n );\n return \"error\" /*클라이언트에서 에러 체크에 사용하는 리터럴입니다.*/;\n }\n })();\n const pending = await (async () => {\n try {\n const [, fdList] = await tConn.migrate.list();\n return fdList.map((fd: { file: string }) =>\n fd.file.replace(\".js\", \"\")\n );\n } catch (err) {\n return [];\n }\n })();\n const currentVersion = await (async () => {\n try {\n return await tConn.migrate.currentVersion();\n } catch (err) {\n return \"error\";\n }\n })();\n\n const connection =\n knexOptions.connection as Knex.MySql2ConnectionConfig;\n\n await tConn.destroy();\n\n return {\n name: connKey.replace(\"_master\", \"\"),\n connKey,\n connString: `mysql2://${connection.user ?? \"\"}@${connection.host}:${\n connection.port\n }/${connection.database}` as ConnString,\n currentVersion,\n status,\n pending,\n };\n })\n );\n\n const preparedCodes: GenMigrationCode[] = await (async () => {\n const status0conn = statuses.find((status) => status.status === 0);\n if (status0conn === undefined) {\n return [];\n }\n\n const compareDBconn = knex(Sonamu.dbConfig[status0conn.connKey]);\n const genCodes = await this.compareMigrations(compareDBconn);\n\n await compareDBconn.destroy();\n\n return genCodes;\n })();\n\n return {\n conns: statuses,\n codes: normal,\n preparedCodes,\n };\n /*\n TS/JS 코드 컴파일 상태 확인\n 1. 원본 파일 없는 JS파일이 존재하는 경우: 삭제\n 2. 컴파일 되지 않은 TS파일이 존재하는 경우: throw 쳐서 데브 서버 오픈 요청\n \n DB 마이그레이션 상태 확인\n 1. 전체 DB설정에 대해서 현재 마이그레이션 상태 확인\n - connKey: string\n - status: number\n - currentVersion: string\n - list: { file: string; directory: string }[]\n \n */\n }\n\n /**\n * 마이그레이션을 적용하거나 롤백합니다.\n * Sonamu UI에서 마이그레이션 작업을 수행할 때 사용됩니다.\n *\n * CLI와 Sonamu UI에서 사용됩니다.\n *\n * @param action 작업 유형 (apply/rollback)\n * @param targets 작업 대상 DB 설정 키 (keyof SonamuDBConfig)\n * @returns 작업 결과\n */\n async runAction(\n action: \"apply\" | \"rollback\",\n targets: (keyof SonamuDBConfig)[]\n ): Promise<\n {\n connKey: string;\n batchNo: number;\n applied: string[];\n }[]\n > {\n // get uniq knex configs\n const configs = _.uniqBy(\n targets\n .map((target) => ({\n connKey: target,\n options: Sonamu.dbConfig[target as keyof typeof Sonamu.dbConfig],\n }))\n .filter((c) => c.options !== undefined),\n ({ options }) =>\n `${(options.connection as Knex.MySql2ConnectionConfig).host}:${\n (options.connection as Knex.MySql2ConnectionConfig).port ?? 3306\n }/${(options.connection as Knex.MySql2ConnectionConfig).database}`\n );\n\n // get connections\n const conns = await Promise.all(\n configs.map(async (config) => ({\n connKey: config.connKey,\n knex: knex(config.options),\n }))\n );\n\n // action\n const result = await (async () => {\n switch (action) {\n case \"apply\":\n return Promise.all(\n conns.map(async ({ connKey, knex }) => {\n const [batchNo, applied] = await knex.migrate.latest();\n return {\n connKey,\n batchNo,\n applied,\n };\n })\n );\n case \"rollback\":\n return Promise.all(\n conns.map(async ({ connKey, knex }) => {\n const [batchNo, applied] = await knex.migrate.rollback();\n return {\n connKey,\n batchNo,\n applied,\n };\n })\n );\n }\n })();\n\n // destroy\n await Promise.all(\n conns.map(({ knex }) => {\n return knex.destroy();\n })\n );\n\n return result;\n }\n\n /**\n * 마이그레이션 코드 파일을 삭제합니다.\n *\n * Sonamu UI에서 사용됩니다.\n *\n * @param codeNames 삭제할 마이그레이션 코드 파일 이름 배열\n * @returns 삭제된 마이그레이션 코드 파일 개수\n */\n async delCodes(codeNames: string[]): Promise<number> {\n const { conns } = await this.getStatus();\n if (\n conns.some((conn) => {\n return codeNames.some(\n (codeName) => conn.pending.includes(codeName) === false\n );\n })\n ) {\n throw new Error(\n \"You cannot delete a migration file if there is already applied.\"\n );\n }\n\n const delFiles = codeNames\n .map((codeName) => [\n `${Sonamu.apiRootPath}/src/migrations/${codeName}.ts`,\n `${Sonamu.apiRootPath}/dist/migrations/${codeName}.js`,\n ])\n .flat();\n\n const res = await Promise.all(\n delFiles.map(async (delFile) => {\n if (await exists(delFile)) {\n console.log(chalk.red(`DELETE: ${delFile}`));\n await unlink(delFile);\n return delFiles.includes(\".ts\") ? 1 : 0;\n }\n return 0;\n })\n );\n return _.sum(res);\n }\n\n /**\n * 마이그레이션 코드 파일을 생성합니다.\n *\n * Sonamu UI에서 사용됩니다.\n *\n * @returns 생성된 마이그레이션 코드 파일 개수\n */\n async generatePreparedCodes(): Promise<number> {\n const { preparedCodes } = await this.getStatus();\n if (preparedCodes.length === 0) {\n console.log(chalk.green(\"\\n현재 모두 싱크된 상태입니다.\"));\n return 0;\n }\n\n // 실제 코드 생성\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n\n for (const [index, pcode] of preparedCodes.entries()) {\n if (pcode.formatted) {\n const dateTag = DateTime.local()\n .plus({ seconds: index })\n .toFormat(\"yyyyMMddHHmmss\");\n const filePath = `${migrationsDir}/${dateTag}_${pcode.title}.ts`;\n await writeFile(filePath, pcode.formatted!);\n console.log(chalk.green(`MIGRTAION CREATED ${filePath}`));\n }\n }\n\n return preparedCodes.length;\n }\n\n /**\n * pending 마이그레이션 목록을 삭제합니다.\n *\n * CLI에서 사용됩니다.\n */\n async clearPendingList(): Promise<void> {\n const [, pendingList] = (await this.targets.pending.migrate.list()) as [\n unknown,\n {\n file: string;\n directory: string;\n }[],\n ];\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n const delList = pendingList.map((df) => {\n return path.join(migrationsDir, df.file).replace(\".js\", \".ts\");\n });\n for (let p of delList) {\n if (await exists(p)) {\n await unlink(p);\n }\n }\n await this.cleanUpDist(true);\n }\n\n /**\n * 마이그레이션 코드 파일을 확인합니다.\n *\n * CLI에서 사용됩니다.\n */\n async check(): Promise<void> {\n const codes = await this.compareMigrations(this.targets.compare!);\n if (codes.length === 0) {\n console.log(chalk.green(\"\\n현재 모두 싱크된 상태입니다.\"));\n return;\n }\n\n // 현재 생성된 코드 표기\n console.table(codes, [\"type\", \"title\"]);\n console.log(codes[0]);\n }\n\n /**\n * 마이그레이션을 수행합니다.\n *\n * runAction이 인자로 들어온 타겟들에 대해 주어진 동작(apply/rollback)을 수행한다면,\n * 이 함수는 생성자로 들어온 connection(knex)들에 대해 마이그레이션을 수행합니다.\n *\n * CLI에서 사용됩니다.\n */\n async run(): Promise<void> {\n // pending 마이그레이션 확인\n const [, pendingList] = await this.targets.pending.migrate.list();\n if (pendingList.length > 0) {\n console.log(\n chalk.red(\"pending 된 마이그레이션이 존재합니다.\"),\n pendingList.map((pending: any) => pending.file)\n );\n\n // pending이 있는 경우 Shadow DB 테스트 진행 여부 컨펌\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"Shadow DB 테스트를 진행하시겠습니까?\",\n initial: true,\n });\n if (answer.value === false) {\n return;\n }\n\n console.time(chalk.blue(\"Migrator - runShadowTest\"));\n await this.runShadowTest();\n console.timeEnd(chalk.blue(\"Migrator - runShadowTest\"));\n await Promise.all(\n this.targets.apply.map(async (applyDb) => {\n const label = chalk.green(\n `APPLIED ${\n applyDb.client.connectionSettings.host\n } ${applyDb.client.database()}`\n );\n console.time(label);\n const [,] = await applyDb.migrate.latest();\n console.timeEnd(label);\n })\n );\n }\n\n // Entity-DB간 비교하여 코드 생성 리턴\n const codes = await this.compareMigrations(this.targets.compare!);\n if (codes.length === 0) {\n console.log(chalk.green(\"\\n현재 모두 싱크된 상태입니다.\"));\n return;\n }\n\n // 현재 생성된 코드 표기\n console.table(codes, [\"type\", \"title\"]);\n\n /* DEBUG: 디버깅용 코드\n codes.map((code) => console.log(code.formatted));\n process.exit();\n */\n\n // 실제 파일 생성 프롬프트\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"마이그레이션 코드를 생성하시겠습니까?\",\n initial: false,\n });\n if (answer.value === false) {\n return;\n }\n\n // 실제 코드 생성\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n\n for (const [index, code] of codes.entries()) {\n if (code.formatted) {\n const dateTag = DateTime.local()\n .plus({ seconds: index })\n .toFormat(\"yyyyMMddHHmmss\");\n const filePath = `${migrationsDir}/${dateTag}_${code.title}.ts`;\n await writeFile(filePath, code.formatted!);\n console.log(chalk.green(`MIGRTAION CREATED ${filePath}`));\n }\n }\n }\n\n /**\n * 타겟으로 지정된 DB를 롤백합니다.\n *\n * runAction이 인자로 들어온 타겟들에 대해 주어진 동작(apply/rollback)을 수행한다면,\n * 이 함수는 생성자로 들어온 connection(knex)들에 대해 롤백을 수행합니다.\n *\n * CLI에서 사용됩니다.\n */\n async rollback() {\n console.time(chalk.red(\"rollback:\"));\n const rollbackAllResult = await Promise.all(\n this.targets.apply.map(async (db) => {\n await db.migrate.forceFreeMigrationsLock();\n return db.migrate.rollback(undefined, false);\n })\n );\n console.dir({ rollbackAllResult }, { depth: null });\n console.timeEnd(chalk.red(\"rollback:\"));\n }\n\n /**\n * 빌드된 마이그레이션 파일을 삭제합니다.\n *\n * CLI에서 사용됩니다.\n *\n * @param force 강제 삭제 여부\n * @returns\n */\n async cleanUpDist(force: boolean = false): Promise<void> {\n async function getFilesUnder(dir: string): Promise<string[]> {\n const migrationPath = path.join(Sonamu.apiRootPath, dir, \"migrations\");\n if (!(await exists(migrationPath))) {\n await mkdir(migrationPath, {\n recursive: true,\n });\n }\n return (await readdir(migrationPath)).filter(\n (filename) => filename.startsWith(\".\") === false\n );\n }\n\n const files = {\n src: await getFilesUnder(\"src\"),\n dist: await getFilesUnder(\"dist\"),\n };\n\n const diffOnSrc = _.differenceBy(\n files.src,\n files.dist,\n (filename) => filename.split(\".\")[0]\n );\n if (diffOnSrc.length > 0) {\n throw new Error(\n \"컴파일 되지 않은 파일이 있습니다.\\n\" + diffOnSrc.join(\"\\n\")\n );\n }\n\n const diffOnDist = _.differenceBy(\n files.dist,\n files.src,\n (filename) => filename.split(\".\")[0]\n );\n if (diffOnDist.length > 0) {\n console.log(chalk.red(\"원본 ts파일을 찾을 수 없는 js파일이 있습니다.\"));\n console.log(diffOnDist);\n\n if (!force) {\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"삭제를 진행하시겠습니까?\",\n initial: true,\n });\n if (answer.value === false) {\n return;\n }\n }\n\n const filesToRm = diffOnDist.map((filename) => {\n return path.join(Sonamu.apiRootPath, \"dist\", \"migrations\", filename);\n });\n for (const filePath of filesToRm) {\n await unlink(filePath);\n }\n console.log(chalk.green(`${filesToRm.length}건 삭제되었습니다!`));\n }\n }\n\n /**\n * Shadow DB 테스트를 진행합니다.\n *\n * Sonamu UI에서 사용됩니다.\n *\n * @returns Shadow DB 테스트 결과\n */\n async runShadowTest(): Promise<\n {\n connKey: string;\n batchNo: number;\n applied: string[];\n }[]\n > {\n // ShadowDB 생성 후 테스트 진행\n const tdb = knex(Sonamu.dbConfig.test);\n const tdbConn = Sonamu.dbConfig.test\n .connection as Knex.MySql2ConnectionConfig;\n const shadowDatabase = tdbConn.database + \"__migration_shadow\";\n const tmpSqlPath = `/tmp/${shadowDatabase}.sql`;\n\n // 테스트DB 덤프 후 Database명 치환\n console.log(\n chalk.magenta(`${tdbConn.database}의 데이터 ${tmpSqlPath}로 덤프`)\n );\n execSync(\n `mysqldump -h${tdbConn.host} -P${tdbConn.port ?? 3306} -u${tdbConn.user} -p'${tdbConn.password}' ${tdbConn.database} --single-transaction --no-create-db --triggers > ${tmpSqlPath};`\n );\n execSync(\n `sed -i'' -e 's/\\`${tdbConn.database}\\`/\\`${shadowDatabase}\\`/g' ${tmpSqlPath};`\n );\n\n // 기존 ShadowDB 리셋\n console.log(chalk.magenta(`${shadowDatabase} 리셋`));\n await tdb.raw(`DROP DATABASE IF EXISTS \\`${shadowDatabase}\\`;`);\n await tdb.raw(`CREATE DATABASE \\`${shadowDatabase}\\`;`);\n\n // ShadowDB 테이블 + 데이터 생성\n console.log(chalk.magenta(`${shadowDatabase} 데이터베이스 생성`));\n execSync(\n `mysql -h${tdbConn.host} -P${tdbConn.port ?? 3306} -u${tdbConn.user} -p'${tdbConn.password}' ${shadowDatabase} < ${tmpSqlPath};`\n );\n\n // shadow db 테스트 진행\n const sdb = knex({\n ...Sonamu.dbConfig.test,\n connection: {\n ...tdbConn,\n database: shadowDatabase,\n password: tdbConn.password,\n },\n });\n\n // shadow db 테스트 진행\n try {\n const [batchNo, applied] = await sdb.migrate.latest();\n console.log(chalk.green(\"Shadow DB 테스트에 성공했습니다!\"), {\n batchNo,\n applied,\n });\n\n // 생성한 Shadow DB 삭제\n console.log(chalk.magenta(`${shadowDatabase} 삭제`));\n await tdb.raw(`DROP DATABASE IF EXISTS \\`${shadowDatabase}\\`;`);\n\n return [\n {\n connKey: \"shadow\",\n batchNo,\n applied,\n },\n ];\n } catch (e) {\n console.error(e);\n throw new ServiceUnavailableException(\"Shadow DB 테스트 진행 중 에러\");\n } finally {\n await tdb.destroy();\n }\n }\n\n /**\n * 모든 DB를 롤백하고 전체 마이그레이션 파일을 삭제합니다.\n *\n * CLI에서 사용됩니다.\n *\n * @returns\n */\n async resetAll() {\n const answer = await prompts({\n type: \"confirm\",\n name: \"value\",\n message: \"모든 DB를 롤백하고 전체 마이그레이션 파일을 삭제하시겠습니까?\",\n initial: false,\n });\n if (answer.value === false) {\n return;\n }\n\n console.time(chalk.red(\"rollback-all:\"));\n const rollbackAllResult = await Promise.all(\n this.targets.apply.map(async (db) => {\n await db.migrate.forceFreeMigrationsLock();\n return db.migrate.rollback(undefined, true);\n })\n );\n console.log({ rollbackAllResult });\n console.timeEnd(chalk.red(\"rollback-all:\"));\n\n const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;\n console.time(chalk.red(\"delete migration files\"));\n execSync(`rm -f ${migrationsDir}/*`);\n execSync(`rm -f ${migrationsDir.replace(\"/src/\", \"/dist/\")}/*`);\n console.timeEnd(chalk.red(\"delete migration files\"));\n }\n\n private async compareMigrations(\n compareDB: Knex\n ): Promise<GenMigrationCode[]> {\n // Entity 순회하여 싱크\n const entityIds = EntityManager.getAllIds();\n\n // 조인테이블 포함하여 Entity에서 MigrationSet 추출\n const entitySetsWithJoinTable = entityIds\n .filter((entityId) => EntityManager.get(entityId).props.length > 0)\n .map((entityId) =>\n getMigrationSetFromEntity(EntityManager.get(entityId))\n );\n\n // 조인테이블만 추출\n const joinTablesWithDup = entitySetsWithJoinTable\n .map((entitySet) => entitySet.joinTables)\n .flat();\n // 중복 제거 (중복인 경우 indexes를 병합)\n const joinTables = Object.values(\n _.groupBy(joinTablesWithDup, (jt) => jt.table)\n ).map((tables) => {\n if (tables.length === 1) {\n return tables[0];\n }\n return {\n ...tables[0],\n indexes: _.uniqBy(\n tables.flatMap((t) => t.indexes),\n (index) => [index.type, ...index.columns.sort()].join(\"-\")\n ),\n };\n });\n\n // 조인테이블 포함하여 MigrationSet 배열\n const entitySets: MigrationSet[] = [\n ...entitySetsWithJoinTable,\n ...joinTables,\n ];\n\n const codes: GenMigrationCode[] = (\n await Promise.all(\n entitySets.map(async (entitySet) => {\n const dbSet = await getMigrationSetFromDB(compareDB, entitySet.table);\n\n if (dbSet === null) {\n // 기존 테이블 없음, 새로 테이블 생성\n return await generateCreateCode(entitySet);\n } else {\n // 기존 테이블 존재하는 케이스\n return await generateAlterCode(entitySet, dbSet);\n }\n })\n )\n ).flat();\n\n // normal 타입이 앞으로, foreign이 뒤로\n codes.sort((codeA, codeB) => {\n if (codeA.type === \"foreign\" && codeB.type == \"normal\") {\n return 1;\n } else if (codeA.type === \"normal\" && codeB.type === \"foreign\") {\n return -1;\n } else {\n return 0;\n }\n });\n\n return codes;\n }\n\n /**\n * 마이그레이션 대상 커넥션을 종료합니다.\n *\n * CLI에서 사용됩니다.\n *\n * @returns {Promise<void>} 종료 결과\n */\n async destroy(): Promise<void> {\n await Promise.all(\n this.targets.apply.map((db) => {\n return db.destroy();\n })\n );\n }\n}\n"],"names":["Migrator","options","targets","dbConfig","Sonamu","mode","devDB","knex","development_master","testDB","test","fixtureLocalDB","fixture_local","applyDBs","connection","host","fixture_remote","database","fixtureRemoteDB","push","compare","pending","shadow","apply","productionDB","production_master","Error","getMigrationCodes","srcMigrationsDir","distMigrationsDir","srcMigrations","distMigrations","normal","onlyTs","onlyJs","apiRootPath","exists","mkdir","recursive","readdir","filter","f","endsWith","map","split","_","intersection","filename","name","path","join","sort","a","b","difference","getStatus","connKeys","statuses","preparedCodes","length","console","debug","ServiceUnavailableException","Promise","all","execSync","replace","Object","keys","key","connKey","knexOptions","tConn","status","currentVersion","err","migrate","warn","chalk","yellow","JSON","stringify","fdList","list","fd","file","destroy","connString","user","port","status0conn","compareDBconn","genCodes","find","undefined","compareMigrations","conns","codes","runAction","action","configs","result","uniqBy","target","c","config","batchNo","applied","latest","rollback","delCodes","codeNames","delFiles","res","some","conn","codeName","includes","flat","delFile","log","red","unlink","sum","generatePreparedCodes","migrationsDir","index","pcode","dateTag","filePath","green","entries","formatted","DateTime","local","plus","seconds","toFormat","title","writeFile","clearPendingList","pendingList","delList","p","df","cleanUpDist","check","table","run","answer","code","prompts","type","message","initial","value","time","blue","runShadowTest","timeEnd","applyDb","label","client","connectionSettings","rollbackAllResult","db","forceFreeMigrationsLock","dir","depth","force","files","diffOnSrc","diffOnDist","filesToRm","getFilesUnder","migrationPath","startsWith","src","dist","differenceBy","tdb","tdbConn","shadowDatabase","tmpSqlPath","sdb","e","magenta","password","raw","error","resetAll","compareDB","entityIds","entitySetsWithJoinTable","joinTablesWithDup","joinTables","entitySets","EntityManager","getAllIds","entityId","get","props","getMigrationSetFromEntity","entitySet","values","groupBy","jt","tables","indexes","flatMap","t","columns","dbSet","getMigrationSetFromDB","generateCreateCode","generateAlterCode","codeA","codeB"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { GenMigrationCode } from "../types/types";
|
|
2
|
+
export type MigrationCode = {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
};
|
|
6
|
+
export type ConnString = `${"mysql2"}://${string}@${string}:${number}/${string}`;
|
|
7
|
+
export type MigrationStatus = {
|
|
8
|
+
codes: MigrationCode[];
|
|
9
|
+
conns: {
|
|
10
|
+
name: string;
|
|
11
|
+
connKey: string;
|
|
12
|
+
connString: ConnString;
|
|
13
|
+
currentVersion: string;
|
|
14
|
+
status: string | number;
|
|
15
|
+
pending: string[];
|
|
16
|
+
}[];
|
|
17
|
+
preparedCodes: GenMigrationCode[];
|
|
18
|
+
};
|
|
19
|
+
export type DBColumn = {
|
|
20
|
+
Field: string;
|
|
21
|
+
Type: string;
|
|
22
|
+
Null: string;
|
|
23
|
+
Key: string;
|
|
24
|
+
Default: string | null;
|
|
25
|
+
Extra: string;
|
|
26
|
+
};
|
|
27
|
+
export type DBIndex = {
|
|
28
|
+
Table: string;
|
|
29
|
+
Non_unique: number;
|
|
30
|
+
Key_name: string;
|
|
31
|
+
Seq_in_index: number;
|
|
32
|
+
Column_name: string;
|
|
33
|
+
Collation: string | null;
|
|
34
|
+
Cardinality: number | null;
|
|
35
|
+
Sub_part: number | null;
|
|
36
|
+
Packed: string | null;
|
|
37
|
+
Null: string;
|
|
38
|
+
Index_type: string;
|
|
39
|
+
Comment: string;
|
|
40
|
+
Index_comment: string;
|
|
41
|
+
Visible: string;
|
|
42
|
+
Expression: string | null;
|
|
43
|
+
};
|
|
44
|
+
export type DBForeign = {
|
|
45
|
+
keyName: string;
|
|
46
|
+
from: string;
|
|
47
|
+
referencesTable: string;
|
|
48
|
+
referencesField: string;
|
|
49
|
+
onDelete: string;
|
|
50
|
+
onUpdate: string;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/migration/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AACF,MAAM,MAAM,UAAU,GACpB,GAAG,QAAQ,MAAM,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,UAAU,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,EAAE,CAAC;IACJ,aAAa,EAAE,gBAAgB,EAAE,CAAC;CACnC,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AACF,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/migration/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SMD } from "./smd";
|
|
2
|
+
import { SMDInput } from "../types/types";
|
|
3
|
+
import { EntityNamesRecord } from "../entity/entity-manager";
|
|
4
|
+
type TableSpec = {
|
|
5
|
+
name: string;
|
|
6
|
+
uniqueColumns: string[];
|
|
7
|
+
};
|
|
8
|
+
declare class SMDManagerClass {
|
|
9
|
+
private SMDs;
|
|
10
|
+
modulePaths: Map<string, string>;
|
|
11
|
+
private tableSpecs;
|
|
12
|
+
isAutoloaded: boolean;
|
|
13
|
+
autoload(doSilent?: boolean): Promise<unknown>;
|
|
14
|
+
register(smdInput: SMDInput<string>): void;
|
|
15
|
+
get(smdId: string): SMD;
|
|
16
|
+
exists(smdId: string): boolean;
|
|
17
|
+
getAllIds(): string[];
|
|
18
|
+
getAllParentIds(): string[];
|
|
19
|
+
getChildrenIds(parentId: string): string[];
|
|
20
|
+
setModulePath(key: string, modulePath: string): void;
|
|
21
|
+
getModulePath(key: string): string;
|
|
22
|
+
setTableSpec(tableSpec: TableSpec): void;
|
|
23
|
+
getTableSpec(key: string): TableSpec;
|
|
24
|
+
getNamesFromId(smdId: string): EntityNamesRecord;
|
|
25
|
+
}
|
|
26
|
+
export declare const SMDManager: SMDManagerClass;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=smd-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smd-manager.d.ts","sourceRoot":"","sources":["../../src/smd/smd-manager.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AACF,cAAM,eAAe;IACnB,OAAO,CAAC,IAAI,CAA+B;IACpC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAa;IACpD,OAAO,CAAC,UAAU,CAAqC;IAChD,YAAY,EAAE,OAAO,CAAS;IAG/B,QAAQ,CAAC,QAAQ,GAAE,OAAe;IA+BxC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI;IAK1C,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG;IASvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAK9B,SAAS,IAAI,MAAM,EAAE;IAIrB,eAAe,IAAI,MAAM,EAAE;IAO3B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAO1C,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAKpD,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IASlC,YAAY,CAAC,SAAS,EAAE,SAAS;IAIjC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IASpC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB;CAoBjD;AAED,eAAO,MAAM,UAAU,iBAAwB,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"SMDManager",{enumerable:true,get:function(){return SMDManager}});var _chalk=/*#__PURE__*/_interop_require_default(require("chalk"));var _glob=/*#__PURE__*/_interop_require_default(require("glob"));var _inflection=/*#__PURE__*/_interop_require_default(require("inflection"));var _path=/*#__PURE__*/_interop_require_default(require("path"));var _smd=require("./smd");var _sonamu=require("../api/sonamu");function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap;var cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interop_require_wildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule){return obj}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj}}var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj)){return cache.get(obj)}var newObj={__proto__:null};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(key!=="default"&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc)}else{newObj[key]=obj[key]}}}newObj.default=obj;if(cache){cache.set(obj,newObj)}return newObj}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["return"]=verb(2),typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]<t[3])){_.label=op[1];break}if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break}if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break}if(t[2])_.ops.pop();_.trys.pop();continue}op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0}if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true}}}var SMDManagerClass=/*#__PURE__*/function(){"use strict";function SMDManagerClass(){_class_call_check(this,SMDManagerClass);_define_property(this,"SMDs",new Map);_define_property(this,"modulePaths",new Map);_define_property(this,"tableSpecs",new Map);_define_property(this,"isAutoloaded",false)}_create_class(SMDManagerClass,[{key:"autoload",value:function autoload(){var doSilent=arguments.length>0&&arguments[0]!==void 0?arguments[0]:false;return _async_to_generator(function(){var _this,pathPattern;return _ts_generator(this,function(_state){_this=this;if(this.isAutoloaded){return[2]}pathPattern=_path.default.join(_sonamu.Sonamu.apiRootPath,"/dist/application/**/*.smd.js");!doSilent&&console.log(_chalk.default.yellow("autoload ".concat(pathPattern)));return[2,new Promise(function(resolve){_glob.default.glob(_path.default.resolve(pathPattern),function(_err,files){var importPaths=files.map(function(filePath){return _path.default.relative(__dirname,filePath)});Promise.all(importPaths.map(function(importPath){return _async_to_generator(function(){var _this,imported;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;return[4,Promise.resolve(importPath).then(function(p){return /*#__PURE__*/_interop_require_wildcard(require(p))})];case 1:imported=_state.sent();Object.values(imported).map(function(smdInput){return _this.register(smdInput)});return[2,imported]}})}).call(_this)})).then(function(){resolve("ok");_this.isAutoloaded=true})})})]})}).call(this)}},{key:"register",value:function register(smdInput){var smd=new _smd.SMD(smdInput);this.SMDs.set(smdInput.id,smd)}},{key:"get",value:function get(smdId){var smd=this.SMDs.get(smdId);if(smd===undefined){throw new Error("존재하지 않는 SMD 요청 ".concat(smdId))}return smd}},{key:"exists",value:function exists(smdId){var smd=this.SMDs.get(smdId);return smd!==undefined}},{key:"getAllIds",value:function getAllIds(){return Array.from(SMDManager.SMDs.keys())}},{key:"getAllParentIds",value:function getAllParentIds(){var _this=this;return this.getAllIds().filter(function(smdId){var smd=_this.get(smdId);return smd.parentId===undefined})}},{key:"getChildrenIds",value:function getChildrenIds(parentId){var _this=this;return this.getAllIds().filter(function(smdId){var smd=_this.get(smdId);return smd.parentId===parentId})}},{key:"setModulePath",value:function setModulePath(key,modulePath){this.modulePaths.set(key,modulePath)}},{key:"getModulePath",value:function getModulePath(key){var modulePath=this.modulePaths.get(key);if(modulePath===undefined){throw new Error("존재하지 않는 모듈 패스 요청 ".concat(key))}return modulePath}},{key:"setTableSpec",value:function setTableSpec(tableSpec){this.tableSpecs.set(tableSpec.name,tableSpec)}},{key:"getTableSpec",value:function getTableSpec(key){var tableSpec=this.tableSpecs.get(key);if(tableSpec===undefined){throw new Error("존재하지 않는 테이블 스펙 요청 ".concat(key))}return tableSpec}},{key:"getNamesFromId",value:function getNamesFromId(smdId){var pluralized=_inflection.default.pluralize(smdId)===smdId?"".concat(smdId,"List"):_inflection.default.pluralize(smdId);return{fs:_inflection.default.dasherize(_inflection.default.underscore(smdId)).toLowerCase(),fsPlural:_inflection.default.dasherize(_inflection.default.underscore(pluralized)).toLowerCase(),camel:_inflection.default.camelize(smdId,true),camelPlural:_inflection.default.camelize(pluralized,true),capital:smdId,capitalPlural:pluralized,upper:smdId.toUpperCase(),constant:_inflection.default.underscore(smdId).toUpperCase()}}}]);return SMDManagerClass}();var SMDManager=new SMDManagerClass;
|
|
2
|
+
//# sourceMappingURL=smd-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/smd/smd-manager.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport glob from \"glob\";\nimport inflection from \"inflection\";\nimport _ from \"lodash\";\nimport path from \"path\";\nimport { SMD } from \"./smd\";\nimport { SMDInput } from \"../types/types\";\nimport { Sonamu } from \"../api/sonamu\";\nimport { EntityNamesRecord } from \"../entity/entity-manager\";\n\ntype TableSpec = {\n name: string;\n uniqueColumns: string[];\n};\nclass SMDManagerClass {\n private SMDs: Map<string, SMD> = new Map();\n public modulePaths: Map<string, string> = new Map();\n private tableSpecs: Map<string, TableSpec> = new Map();\n public isAutoloaded: boolean = false;\n\n // 경로 전달받아 모든 SMD 파일 로드\n async autoload(doSilent: boolean = false) {\n if (this.isAutoloaded) {\n return;\n }\n const pathPattern = path.join(\n Sonamu.apiRootPath,\n \"/dist/application/**/*.smd.js\"\n );\n !doSilent && console.log(chalk.yellow(`autoload ${pathPattern}`));\n\n return new Promise((resolve) => {\n glob.glob(path.resolve(pathPattern!), (_err, files) => {\n const importPaths = files.map((filePath) =>\n path.relative(__dirname, filePath)\n );\n Promise.all(\n importPaths.map(async (importPath) => {\n const imported = await import(importPath);\n Object.values(imported).map((smdInput) =>\n this.register(smdInput as SMDInput<string>)\n );\n return imported;\n })\n ).then(() => {\n resolve(\"ok\");\n this.isAutoloaded = true;\n });\n });\n });\n }\n\n register(smdInput: SMDInput<string>): void {\n const smd = new SMD(smdInput);\n this.SMDs.set(smdInput.id, smd);\n }\n\n get(smdId: string): SMD {\n const smd = this.SMDs.get(smdId);\n if (smd === undefined) {\n throw new Error(`존재하지 않는 SMD 요청 ${smdId}`);\n }\n\n return smd;\n }\n\n exists(smdId: string): boolean {\n const smd = this.SMDs.get(smdId);\n return smd !== undefined;\n }\n\n getAllIds(): string[] {\n return Array.from(SMDManager.SMDs.keys());\n }\n\n getAllParentIds(): string[] {\n return this.getAllIds().filter((smdId) => {\n const smd = this.get(smdId);\n return smd.parentId === undefined;\n });\n }\n\n getChildrenIds(parentId: string): string[] {\n return this.getAllIds().filter((smdId) => {\n const smd = this.get(smdId);\n return smd.parentId === parentId;\n });\n }\n\n setModulePath(key: string, modulePath: string): void {\n // console.debug(chalk.cyan(`setModulePath :: ${key} :: ${modulePath}`));\n this.modulePaths.set(key, modulePath);\n }\n\n getModulePath(key: string): string {\n const modulePath = this.modulePaths.get(key);\n if (modulePath === undefined) {\n throw new Error(`존재하지 않는 모듈 패스 요청 ${key}`);\n }\n\n return modulePath;\n }\n\n setTableSpec(tableSpec: TableSpec) {\n this.tableSpecs.set(tableSpec.name, tableSpec);\n }\n\n getTableSpec(key: string): TableSpec {\n const tableSpec = this.tableSpecs.get(key);\n if (tableSpec === undefined) {\n throw new Error(`존재하지 않는 테이블 스펙 요청 ${key}`);\n }\n\n return tableSpec;\n }\n\n getNamesFromId(smdId: string): EntityNamesRecord {\n // entityId가 단복수 동형 단어인 경우 List 붙여서 생성\n const pluralized =\n inflection.pluralize(smdId) === smdId\n ? `${smdId}List`\n : inflection.pluralize(smdId);\n\n return {\n fs: inflection.dasherize(inflection.underscore(smdId)).toLowerCase(),\n fsPlural: inflection\n .dasherize(inflection.underscore(pluralized))\n .toLowerCase(),\n camel: inflection.camelize(smdId, true),\n camelPlural: inflection.camelize(pluralized, true),\n capital: smdId,\n capitalPlural: pluralized,\n upper: smdId.toUpperCase(),\n constant: inflection.underscore(smdId).toUpperCase(),\n };\n }\n}\n\nexport const SMDManager = new SMDManagerClass();\n"],"names":["SMDManager","SMDManagerClass","SMDs","Map","modulePaths","tableSpecs","isAutoloaded","autoload","doSilent","pathPattern","path","join","Sonamu","apiRootPath","console","log","chalk","yellow","Promise","resolve","glob","_err","files","importPaths","map","filePath","relative","__dirname","all","importPath","imported","Object","values","smdInput","register","then","smd","SMD","set","id","get","smdId","undefined","Error","exists","getAllIds","Array","from","keys","getAllParentIds","filter","parentId","getChildrenIds","setModulePath","key","modulePath","getModulePath","setTableSpec","tableSpec","name","getTableSpec","getNamesFromId","pluralized","inflection","pluralize","fs","dasherize","underscore","toLowerCase","fsPlural","camel","camelize","camelPlural","capital","capitalPlural","upper","toUpperCase","constant"],"mappings":"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"}
|