sonamu 0.4.14 → 0.5.1
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 +19 -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 +84 -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/bin/build-config.d.ts +9 -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 +48 -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/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 +48 -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 +23 -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/stream/index.d.ts +2 -0
- package/dist/stream/index.d.ts.map +1 -0
- package/dist/stream/index.js +2 -0
- package/dist/stream/index.js.map +1 -0
- package/dist/stream/sse.d.ts +13 -0
- package/dist/stream/sse.d.ts.map +1 -0
- package/dist/stream/sse.js +2 -0
- package/dist/stream/sse.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 +611 -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 +32 -45
- 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 +15 -3
- package/src/api/decorators.ts +144 -20
- package/src/api/index.ts +2 -0
- package/src/api/sonamu.ts +408 -165
- package/src/bin/build-config.ts +10 -0
- package/src/bin/cli-wrapper.ts +35 -32
- package/src/bin/cli.ts +141 -204
- package/src/database/_batch_update.ts +10 -15
- package/src/database/base-model.ts +326 -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 +131 -0
- package/src/file-storage/file-storage.ts +100 -0
- package/src/index.ts +15 -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/stream/index.ts +1 -0
- package/src/stream/sse.ts +49 -0
- 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 +108 -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 +6 -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/dist/base-model-CEB0H0aO.d.mts +0 -43
- package/dist/base-model-CrqDMYhI.d.ts +0 -43
- package/dist/bin/cli-wrapper.d.mts +0 -1
- package/dist/bin/cli-wrapper.mjs +0 -43
- package/dist/bin/cli-wrapper.mjs.map +0 -1
- package/dist/bin/cli.d.mts +0 -2
- package/dist/bin/cli.mjs +0 -907
- package/dist/bin/cli.mjs.map +0 -1
- package/dist/chunk-2WAC2GER.js +0 -7625
- package/dist/chunk-2WAC2GER.js.map +0 -1
- package/dist/chunk-C3IPIF6O.mjs +0 -1581
- package/dist/chunk-C3IPIF6O.mjs.map +0 -1
- package/dist/chunk-EXHKSVTE.js +0 -280
- package/dist/chunk-EXHKSVTE.js.map +0 -1
- package/dist/chunk-FCERKIIF.mjs +0 -7623
- package/dist/chunk-FCERKIIF.mjs.map +0 -1
- package/dist/chunk-HGIBJYOU.mjs +0 -231
- package/dist/chunk-HGIBJYOU.mjs.map +0 -1
- package/dist/chunk-JKSOJRQA.mjs +0 -280
- package/dist/chunk-JKSOJRQA.mjs.map +0 -1
- package/dist/chunk-OTKKFP3Y.js +0 -1581
- package/dist/chunk-OTKKFP3Y.js.map +0 -1
- package/dist/chunk-PTFDTOJU.mjs +0 -19
- package/dist/chunk-PTFDTOJU.mjs.map +0 -1
- package/dist/chunk-UZ2IY5VE.js +0 -231
- package/dist/chunk-UZ2IY5VE.js.map +0 -1
- package/dist/database/drivers/knex/base-model.d.mts +0 -16
- package/dist/database/drivers/knex/base-model.d.ts +0 -16
- package/dist/database/drivers/knex/base-model.js +0 -55
- package/dist/database/drivers/knex/base-model.js.map +0 -1
- package/dist/database/drivers/knex/base-model.mjs +0 -56
- package/dist/database/drivers/knex/base-model.mjs.map +0 -1
- package/dist/database/drivers/kysely/base-model.d.mts +0 -22
- package/dist/database/drivers/kysely/base-model.d.ts +0 -22
- package/dist/database/drivers/kysely/base-model.js +0 -64
- package/dist/database/drivers/kysely/base-model.js.map +0 -1
- package/dist/database/drivers/kysely/base-model.mjs +0 -65
- package/dist/database/drivers/kysely/base-model.mjs.map +0 -1
- package/dist/index.d.mts +0 -813
- package/dist/index.mjs +0 -435
- package/dist/index.mjs.map +0 -1
- package/dist/model-aFgomcdc.d.mts +0 -1112
- package/dist/model-aFgomcdc.d.ts +0 -1112
- 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
package/src/syncer/syncer.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import path, { dirname } from "path";
|
|
2
2
|
import { globAsync, importMultiple } from "../utils/utils";
|
|
3
|
-
import
|
|
3
|
+
import { createReadStream } from "fs";
|
|
4
|
+
import { mkdir, readFile, rm, writeFile } from "fs/promises";
|
|
5
|
+
import { exists } from "../utils/fs-utils";
|
|
4
6
|
import crypto from "crypto";
|
|
5
7
|
import equal from "fast-deep-equal";
|
|
6
|
-
import _ from "lodash";
|
|
8
|
+
import _, { chunk } from "lodash";
|
|
7
9
|
import inflection from "inflection";
|
|
8
10
|
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
9
11
|
import ts from "typescript";
|
|
10
12
|
import {
|
|
11
13
|
ApiParam,
|
|
12
14
|
ApiParamType,
|
|
15
|
+
EntityProp,
|
|
16
|
+
EntityPropNode,
|
|
13
17
|
isBelongsToOneRelationProp,
|
|
14
18
|
isBigIntegerProp,
|
|
15
19
|
isBooleanProp,
|
|
@@ -29,9 +33,6 @@ import {
|
|
|
29
33
|
isTimestampProp,
|
|
30
34
|
isUuidProp,
|
|
31
35
|
isVirtualProp,
|
|
32
|
-
EntityProp,
|
|
33
|
-
EntityPropNode,
|
|
34
|
-
SQLDateTimeString,
|
|
35
36
|
} from "../types/types";
|
|
36
37
|
import {
|
|
37
38
|
ApiDecoratorOptions,
|
|
@@ -73,11 +74,17 @@ import { Template__view_search_input } from "../templates/view_search_input.temp
|
|
|
73
74
|
import { Template__view_list_columns } from "../templates/view_list_columns.template";
|
|
74
75
|
import { Template__generated_http } from "../templates/generated_http.template";
|
|
75
76
|
import { Sonamu } from "../api/sonamu";
|
|
76
|
-
import { execSync } from "child_process";
|
|
77
77
|
import { Template__generated_sso } from "../templates/generated_sso.template";
|
|
78
|
-
import { Template__kysely_interface } from "../templates/kysely_types.template";
|
|
79
|
-
import { DB } from "../database/db";
|
|
80
78
|
import { setTimeout as setTimeoutPromises } from "timers/promises";
|
|
79
|
+
import assert from "assert";
|
|
80
|
+
import * as swc from "@swc/core";
|
|
81
|
+
import { minimatch } from "minimatch";
|
|
82
|
+
import {
|
|
83
|
+
everyAsync,
|
|
84
|
+
filterAsync,
|
|
85
|
+
mapAsync,
|
|
86
|
+
reduceAsync,
|
|
87
|
+
} from "../utils/async-utils";
|
|
81
88
|
|
|
82
89
|
type FileType =
|
|
83
90
|
| "model"
|
|
@@ -122,8 +129,19 @@ export class Syncer {
|
|
|
122
129
|
models: { [modelName: string]: unknown } = {};
|
|
123
130
|
isSyncing: boolean = false;
|
|
124
131
|
|
|
132
|
+
public checksumPatternGroup: GlobPattern = {
|
|
133
|
+
/* 원본 체크 */
|
|
134
|
+
entity: Sonamu.apiRootPath + "/src/application/**/*.entity.json",
|
|
135
|
+
types: Sonamu.apiRootPath + "/src/application/**/*.types.ts",
|
|
136
|
+
generated: Sonamu.apiRootPath + "/src/application/sonamu.generated.ts",
|
|
137
|
+
functions: Sonamu.apiRootPath + "/src/application/**/*.functions.ts",
|
|
138
|
+
/* compiled-JS 체크 */
|
|
139
|
+
model: Sonamu.apiRootPath + "/dist/application/**/*.model.js",
|
|
140
|
+
frame: Sonamu.apiRootPath + "/dist/application/**/*.frame.js",
|
|
141
|
+
};
|
|
142
|
+
|
|
125
143
|
get checksumsPath(): string {
|
|
126
|
-
return path.join(Sonamu.apiRootPath, "
|
|
144
|
+
return path.join(Sonamu.apiRootPath, "/sonamu.lock");
|
|
127
145
|
}
|
|
128
146
|
public constructor() {}
|
|
129
147
|
|
|
@@ -141,7 +159,7 @@ export class Syncer {
|
|
|
141
159
|
const srcCodePath = path
|
|
142
160
|
.join(currentDirname, `../shared/${target}.shared.ts.txt`)
|
|
143
161
|
.replace("/dist/", "/src/");
|
|
144
|
-
if (!
|
|
162
|
+
if (!(await exists(srcCodePath))) {
|
|
145
163
|
return;
|
|
146
164
|
}
|
|
147
165
|
|
|
@@ -153,7 +171,7 @@ export class Syncer {
|
|
|
153
171
|
|
|
154
172
|
const srcChecksum = await this.getChecksumOfFile(srcCodePath);
|
|
155
173
|
const dstChecksum = await (async () => {
|
|
156
|
-
if (
|
|
174
|
+
if (!(await exists(dstCodePath))) {
|
|
157
175
|
return "";
|
|
158
176
|
}
|
|
159
177
|
return this.getChecksumOfFile(dstCodePath);
|
|
@@ -162,7 +180,7 @@ export class Syncer {
|
|
|
162
180
|
if (srcChecksum === dstChecksum) {
|
|
163
181
|
return;
|
|
164
182
|
}
|
|
165
|
-
|
|
183
|
+
await writeFile(dstCodePath, await readFile(srcCodePath));
|
|
166
184
|
console.log(chalk.blue("shared.ts is synced"));
|
|
167
185
|
})
|
|
168
186
|
);
|
|
@@ -175,7 +193,7 @@ export class Syncer {
|
|
|
175
193
|
// 비교
|
|
176
194
|
const isSame = equal(currentChecksums, previousChecksums);
|
|
177
195
|
if (isSame) {
|
|
178
|
-
const msg = "
|
|
196
|
+
const msg = "All files are synced!";
|
|
179
197
|
const margin = (process.stdout.columns - msg.length) / 2;
|
|
180
198
|
console.log(
|
|
181
199
|
chalk.black.bgGreen(" ".repeat(margin) + msg + " ".repeat(margin))
|
|
@@ -209,12 +227,35 @@ export class Syncer {
|
|
|
209
227
|
const diffFiles = diff.map((r) => r.path);
|
|
210
228
|
console.log("Changed Files: ", diffFiles);
|
|
211
229
|
|
|
230
|
+
const { changedChecksums } = await this.doSyncActions(
|
|
231
|
+
diffFiles,
|
|
232
|
+
currentChecksums
|
|
233
|
+
);
|
|
234
|
+
// checksum 오버라이드 (액션 실행 과정 중간에 체크섬이 바뀐 경우)
|
|
235
|
+
currentChecksums = changedChecksums ?? currentChecksums;
|
|
236
|
+
|
|
237
|
+
// 저장
|
|
238
|
+
await this.saveChecksums(currentChecksums);
|
|
239
|
+
|
|
240
|
+
// 싱크 종료
|
|
241
|
+
this.isSyncing = false;
|
|
242
|
+
abc.abort();
|
|
243
|
+
process.off("SIGUSR2", onSIGUSR2);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async doSyncActions(
|
|
247
|
+
diffFiles: string[],
|
|
248
|
+
currentChecksums?: PathAndChecksum[]
|
|
249
|
+
): Promise<{
|
|
250
|
+
diffTypes: string[];
|
|
251
|
+
changedChecksums?: PathAndChecksum[];
|
|
252
|
+
}> {
|
|
212
253
|
// 다른 부분 찾아 액션
|
|
213
254
|
const diffGroups = _.groupBy(diffFiles, (r) => {
|
|
214
255
|
const matched = r.match(
|
|
215
256
|
/\.(model|types|functions|entity|generated|frame)\.[tj]s/
|
|
216
257
|
);
|
|
217
|
-
return matched
|
|
258
|
+
return matched?.[1] ?? "unknown";
|
|
218
259
|
}) as unknown as DiffGroups;
|
|
219
260
|
|
|
220
261
|
// 변경된 파일들을 타입별로 분리하여 각 타입별 액션 처리
|
|
@@ -223,19 +264,24 @@ export class Syncer {
|
|
|
223
264
|
// 트리거: entity, types
|
|
224
265
|
// 액션: 스키마 생성
|
|
225
266
|
if (diffTypes.includes("entity") || diffTypes.includes("types")) {
|
|
226
|
-
|
|
267
|
+
await EntityManager.reload();
|
|
268
|
+
|
|
227
269
|
await this.actionGenerateSchemas();
|
|
228
270
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
271
|
+
// types 생성(entity 새로 추가된 경우)
|
|
272
|
+
// parentId가 없고, types가 없는 경우에만 생성
|
|
273
|
+
const entityId = this.getEntityIdFromPath([
|
|
274
|
+
...(diffGroups["entity"] ?? []),
|
|
275
|
+
])[0];
|
|
276
|
+
if (entityId) {
|
|
277
|
+
const entity = EntityManager.get(entityId);
|
|
278
|
+
const typeFilePath = path.join(
|
|
279
|
+
Sonamu.apiRootPath,
|
|
280
|
+
`src/application/${entity.names.fs}/${entity.names.fs}.types.ts`
|
|
238
281
|
);
|
|
282
|
+
if (entity.parentId === undefined && !(await exists(typeFilePath))) {
|
|
283
|
+
await this.generateTemplate("init_types", { entityId });
|
|
284
|
+
}
|
|
239
285
|
}
|
|
240
286
|
|
|
241
287
|
// generated 싱크까지 동시에 처리 후 체크섬 갱신
|
|
@@ -244,7 +290,11 @@ export class Syncer {
|
|
|
244
290
|
"/src/application/sonamu.generated.ts",
|
|
245
291
|
]);
|
|
246
292
|
diffTypes.push("generated");
|
|
247
|
-
|
|
293
|
+
|
|
294
|
+
// fullSync인 경우만 실행
|
|
295
|
+
if (currentChecksums) {
|
|
296
|
+
currentChecksums = await this.getCurrentChecksums();
|
|
297
|
+
}
|
|
248
298
|
}
|
|
249
299
|
|
|
250
300
|
// 트리거: types, enums, generated 변경시
|
|
@@ -254,8 +304,6 @@ export class Syncer {
|
|
|
254
304
|
diffTypes.includes("functions") ||
|
|
255
305
|
diffTypes.includes("generated")
|
|
256
306
|
) {
|
|
257
|
-
console.log("// 액션: 파일 싱크 types / functions / generated");
|
|
258
|
-
|
|
259
307
|
const tsPaths = _.uniq(
|
|
260
308
|
[
|
|
261
309
|
...(diffGroups["types"] ?? []),
|
|
@@ -268,15 +316,22 @@ export class Syncer {
|
|
|
268
316
|
|
|
269
317
|
// 트리거: model
|
|
270
318
|
if (diffTypes.includes("model") || diffTypes.includes("frame")) {
|
|
271
|
-
console.log("// 액션: 서비스 생성");
|
|
272
319
|
const mergedGroup = [
|
|
273
320
|
...(diffGroups["model"] ?? []),
|
|
274
321
|
...(diffGroups["frame"] ?? []),
|
|
275
322
|
];
|
|
323
|
+
|
|
324
|
+
// registeredApis 초기화
|
|
325
|
+
await this.autoloadModels();
|
|
326
|
+
|
|
327
|
+
// Syncer.apis 초기화
|
|
328
|
+
await this.autoloadApis();
|
|
329
|
+
|
|
276
330
|
const params: { namesRecord: EntityNamesRecord; modelTsPath: string }[] =
|
|
277
331
|
mergedGroup.map((modelPath) => {
|
|
278
332
|
if (modelPath.endsWith(".model.js")) {
|
|
279
333
|
const entityId = this.getEntityIdFromPath([modelPath])[0];
|
|
334
|
+
assert(entityId);
|
|
280
335
|
return {
|
|
281
336
|
namesRecord: EntityManager.getNamesFromId(entityId),
|
|
282
337
|
modelTsPath: path.join(
|
|
@@ -289,6 +344,7 @@ export class Syncer {
|
|
|
289
344
|
}
|
|
290
345
|
if (modelPath.endsWith("frame.js")) {
|
|
291
346
|
const [, frameName] = modelPath.match(/.+\/(.+)\.frame.js$/) ?? [];
|
|
347
|
+
assert(frameName);
|
|
292
348
|
return {
|
|
293
349
|
namesRecord: EntityManager.getNamesFromId(frameName),
|
|
294
350
|
modelTsPath: path.join(
|
|
@@ -303,24 +359,122 @@ export class Syncer {
|
|
|
303
359
|
});
|
|
304
360
|
await this.actionGenerateServices(params);
|
|
305
361
|
|
|
306
|
-
console.log("// 액션: HTTP파일 생성");
|
|
307
362
|
await this.actionGenerateHttps();
|
|
308
363
|
}
|
|
309
364
|
|
|
310
|
-
|
|
311
|
-
|
|
365
|
+
return {
|
|
366
|
+
diffTypes,
|
|
367
|
+
changedChecksums: currentChecksums,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
312
370
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
371
|
+
async syncFromWatcher(diffFiles: string[]): Promise<void> {
|
|
372
|
+
const tsFiles = diffFiles.filter((file) => file.endsWith(".ts"));
|
|
373
|
+
const jsonFiles = diffFiles.filter((file) => file.endsWith(".json"));
|
|
374
|
+
|
|
375
|
+
// transpile (성능 이슈를 고려하여 5개 동시 실행)
|
|
376
|
+
const chunks = chunk(tsFiles, 5);
|
|
377
|
+
let transpiledFilePaths: string[] = [];
|
|
378
|
+
for (const chunk of chunks) {
|
|
379
|
+
const _transpiledFilePaths = await Promise.all(
|
|
380
|
+
chunk.map(async (diffFile) => {
|
|
381
|
+
const { code, map } = await swc.transformFile(diffFile, {
|
|
382
|
+
module: {
|
|
383
|
+
type: "commonjs",
|
|
384
|
+
},
|
|
385
|
+
jsc: {
|
|
386
|
+
parser: {
|
|
387
|
+
syntax: "typescript",
|
|
388
|
+
decorators: true,
|
|
389
|
+
},
|
|
390
|
+
target: "es5",
|
|
391
|
+
},
|
|
392
|
+
sourceMaps: true,
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
const jsPath = diffFile
|
|
396
|
+
.replace("/src/", "/dist/")
|
|
397
|
+
.replace(".ts", ".js");
|
|
398
|
+
await mkdir(path.dirname(jsPath), { recursive: true }); // 파일 새로 추가된 경우 디렉토리 생성
|
|
399
|
+
await writeFile(jsPath, code);
|
|
400
|
+
|
|
401
|
+
if (map) {
|
|
402
|
+
const mapPath = jsPath + ".map";
|
|
403
|
+
await mkdir(path.dirname(mapPath), { recursive: true });
|
|
404
|
+
await writeFile(mapPath, map);
|
|
405
|
+
|
|
406
|
+
const sourceMapComment =
|
|
407
|
+
"\n//# sourceMappingURL=" + path.basename(mapPath);
|
|
408
|
+
await writeFile(jsPath, sourceMapComment, {
|
|
409
|
+
flag: "a" /*파일 끝에 붙이기만 해요*/,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
console.log(
|
|
414
|
+
chalk.bold("Transpiled: ") +
|
|
415
|
+
chalk.blue(`${jsPath.replace(Sonamu.apiRootPath, "api")}`)
|
|
416
|
+
);
|
|
417
|
+
return jsPath;
|
|
418
|
+
})
|
|
419
|
+
);
|
|
420
|
+
transpiledFilePaths.push(..._transpiledFilePaths);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// module reload - doSyncActions 전에 캐시 삭제
|
|
424
|
+
function clearModuleAndDependents(filePath: string) {
|
|
425
|
+
const resolved = require.resolve(filePath);
|
|
426
|
+
const toDelete = new Set([resolved]);
|
|
427
|
+
|
|
428
|
+
// 이 파일을 children으로 가진 모듈 찾기
|
|
429
|
+
Object.keys(require.cache).forEach((key) => {
|
|
430
|
+
const mod = require.cache[key];
|
|
431
|
+
if (mod?.children?.some((child) => child.id === resolved)) {
|
|
432
|
+
toDelete.add(key);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
toDelete.forEach((key) => {
|
|
437
|
+
if (key.includes("dist/index.js")) {
|
|
438
|
+
process.kill(process.pid, "SIGUSR2");
|
|
439
|
+
}
|
|
440
|
+
delete require.cache[key];
|
|
441
|
+
// console.debug(
|
|
442
|
+
// chalk.bold("ModuleCleared: ") +
|
|
443
|
+
// chalk.blue(`${key.replace(Sonamu.apiRootPath, "api")}`)
|
|
444
|
+
// );
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
transpiledFilePaths.map((filePath) => {
|
|
448
|
+
clearModuleAndDependents(filePath);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// doSyncActions
|
|
452
|
+
const allFilePaths = [...tsFiles, ...transpiledFilePaths, ...jsonFiles];
|
|
453
|
+
const targetFilePaths = allFilePaths
|
|
454
|
+
.filter((filePath) => {
|
|
455
|
+
return Object.values(this.checksumPatternGroup).some((pattern) =>
|
|
456
|
+
minimatch(filePath, pattern)
|
|
457
|
+
);
|
|
458
|
+
})
|
|
459
|
+
.map((filePath) => "/" + path.relative(Sonamu.apiRootPath, filePath));
|
|
460
|
+
await this.doSyncActions(targetFilePaths);
|
|
461
|
+
|
|
462
|
+
this.apis = [];
|
|
463
|
+
this.types = {};
|
|
464
|
+
this.models = {};
|
|
465
|
+
await this.autoloadTypes();
|
|
466
|
+
await this.autoloadModels();
|
|
467
|
+
await this.autoloadApis();
|
|
468
|
+
|
|
469
|
+
this.syncUI();
|
|
317
470
|
}
|
|
318
471
|
|
|
319
472
|
getEntityIdFromPath(filePaths: string[]): string[] {
|
|
320
473
|
return _.uniq(
|
|
321
474
|
filePaths.map((p) => {
|
|
322
475
|
const matched = p.match(/application\/(.+)\//);
|
|
323
|
-
|
|
476
|
+
assert(matched && matched[1]);
|
|
477
|
+
return inflection.camelize(matched[1].replace(/\-/g, "_"));
|
|
324
478
|
})
|
|
325
479
|
);
|
|
326
480
|
}
|
|
@@ -361,15 +515,16 @@ export class Syncer {
|
|
|
361
515
|
{},
|
|
362
516
|
{ overwrite: true }
|
|
363
517
|
);
|
|
518
|
+
assert(res);
|
|
364
519
|
return res;
|
|
365
520
|
}
|
|
366
521
|
|
|
367
522
|
async copyFileWithReplaceCoreToShared(fromPath: string, toPath: string) {
|
|
368
|
-
if (!
|
|
523
|
+
if (!(await exists(fromPath))) {
|
|
369
524
|
return;
|
|
370
525
|
}
|
|
371
526
|
|
|
372
|
-
const oldFileContent =
|
|
527
|
+
const oldFileContent = (await readFile(fromPath)).toString();
|
|
373
528
|
|
|
374
529
|
const newFileContent = (() => {
|
|
375
530
|
const nfc = oldFileContent.replace(
|
|
@@ -383,13 +538,12 @@ export class Syncer {
|
|
|
383
538
|
return nfc;
|
|
384
539
|
}
|
|
385
540
|
})();
|
|
386
|
-
return
|
|
541
|
+
return writeFile(toPath, newFileContent);
|
|
387
542
|
}
|
|
388
543
|
|
|
389
544
|
async actionSyncFilesToTargets(tsPaths: string[]): Promise<string[]> {
|
|
390
545
|
const { targets } = Sonamu.config.sync;
|
|
391
546
|
const { dir: apiDir } = Sonamu.config.api;
|
|
392
|
-
const { appRootPath } = Sonamu;
|
|
393
547
|
|
|
394
548
|
return (
|
|
395
549
|
await Promise.all(
|
|
@@ -401,12 +555,14 @@ export class Syncer {
|
|
|
401
555
|
.replace(`/${apiDir}/`, `/${target}/`)
|
|
402
556
|
.replace("/application/", "/services/");
|
|
403
557
|
const dir = dirname(dst);
|
|
404
|
-
if (!
|
|
405
|
-
|
|
558
|
+
if (!(await exists(dir))) {
|
|
559
|
+
await mkdir(dir, { recursive: true });
|
|
406
560
|
}
|
|
407
561
|
console.log(
|
|
408
|
-
"
|
|
409
|
-
|
|
562
|
+
chalk.bold("Copied: ") +
|
|
563
|
+
chalk.blue(
|
|
564
|
+
`Copied: ${dst.replace(Sonamu.appRootPath + "/", "")}`
|
|
565
|
+
)
|
|
410
566
|
);
|
|
411
567
|
await this.copyFileWithReplaceCoreToShared(realSrc, dst);
|
|
412
568
|
return dst;
|
|
@@ -418,22 +574,13 @@ export class Syncer {
|
|
|
418
574
|
}
|
|
419
575
|
|
|
420
576
|
async getCurrentChecksums(): Promise<PathAndChecksum[]> {
|
|
421
|
-
const PatternGroup: GlobPattern = {
|
|
422
|
-
/* 원본 체크 */
|
|
423
|
-
entity: Sonamu.apiRootPath + "/src/application/**/*.entity.json",
|
|
424
|
-
types: Sonamu.apiRootPath + "/src/application/**/*.types.ts",
|
|
425
|
-
generated: Sonamu.apiRootPath + "/src/application/sonamu.generated.ts",
|
|
426
|
-
functions: Sonamu.apiRootPath + "/src/application/**/*.functions.ts",
|
|
427
|
-
/* compiled-JS 체크 */
|
|
428
|
-
model: Sonamu.apiRootPath + "/dist/application/**/*.model.js",
|
|
429
|
-
frame: Sonamu.apiRootPath + "/dist/application/**/*.frame.js",
|
|
430
|
-
};
|
|
431
|
-
|
|
432
577
|
const filePaths = (
|
|
433
578
|
await Promise.all(
|
|
434
|
-
Object.entries(
|
|
435
|
-
|
|
436
|
-
|
|
579
|
+
Object.entries(this.checksumPatternGroup).map(
|
|
580
|
+
async ([_fileType, pattern]) => {
|
|
581
|
+
return globAsync(pattern);
|
|
582
|
+
}
|
|
583
|
+
)
|
|
437
584
|
)
|
|
438
585
|
)
|
|
439
586
|
.flat()
|
|
@@ -454,27 +601,29 @@ export class Syncer {
|
|
|
454
601
|
}
|
|
455
602
|
|
|
456
603
|
async getPreviousChecksums(): Promise<PathAndChecksum[]> {
|
|
457
|
-
if (
|
|
604
|
+
if (!(await exists(this.checksumsPath))) {
|
|
458
605
|
return [];
|
|
459
606
|
}
|
|
460
607
|
|
|
461
|
-
const previousChecksums =
|
|
462
|
-
this.checksumsPath
|
|
463
|
-
)
|
|
608
|
+
const previousChecksums = JSON.parse(
|
|
609
|
+
(await readFile(this.checksumsPath, "utf-8"))
|
|
610
|
+
) as PathAndChecksum[];
|
|
464
611
|
return previousChecksums;
|
|
465
612
|
}
|
|
466
613
|
|
|
467
614
|
async saveChecksums(checksums: PathAndChecksum[]): Promise<void> {
|
|
468
|
-
await
|
|
469
|
-
|
|
470
|
-
|
|
615
|
+
await writeFile(
|
|
616
|
+
this.checksumsPath,
|
|
617
|
+
JSON.stringify(checksums, null, 2),
|
|
618
|
+
"utf-8"
|
|
619
|
+
);
|
|
471
620
|
console.log("checksum saved", this.checksumsPath);
|
|
472
621
|
}
|
|
473
622
|
|
|
474
623
|
async getChecksumOfFile(filePath: string): Promise<string> {
|
|
475
624
|
return new Promise<string>((resolve, reject) => {
|
|
476
625
|
const hash = crypto.createHash("sha1");
|
|
477
|
-
const input =
|
|
626
|
+
const input = createReadStream(filePath);
|
|
478
627
|
input.on("error", reject);
|
|
479
628
|
input.on("data", function (chunk: any) {
|
|
480
629
|
hash.update(chunk);
|
|
@@ -488,7 +637,7 @@ export class Syncer {
|
|
|
488
637
|
async readApisFromFile(filePath: string) {
|
|
489
638
|
const sourceFile = ts.createSourceFile(
|
|
490
639
|
filePath,
|
|
491
|
-
|
|
640
|
+
(await readFile(filePath)).toString(),
|
|
492
641
|
ts.ScriptTarget.Latest
|
|
493
642
|
);
|
|
494
643
|
|
|
@@ -647,6 +796,7 @@ export class Syncer {
|
|
|
647
796
|
t: "object",
|
|
648
797
|
props: literalNode.members.map((member) => {
|
|
649
798
|
if (ts.isIndexSignatureDeclaration(member)) {
|
|
799
|
+
assert(member.parameters[0]);
|
|
650
800
|
const res = this.resolveParamDec({
|
|
651
801
|
name: member.parameters[0].name as ts.Identifier,
|
|
652
802
|
type: member.parameters[0].type as ts.TypeNode,
|
|
@@ -791,12 +941,15 @@ export class Syncer {
|
|
|
791
941
|
);
|
|
792
942
|
// console.debug(chalk.yellow(`autoload:models @ ${pathPattern}`));
|
|
793
943
|
|
|
794
|
-
const filePaths =
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
944
|
+
const filePaths = await filterAsync(
|
|
945
|
+
await globAsync(pathPattern),
|
|
946
|
+
async (path) => {
|
|
947
|
+
// src 디렉터리 내에 있는 해당 파일이 존재할 경우에만 로드
|
|
948
|
+
// 삭제된 파일이지만 dist에 남아있는 경우 BaseSchema undefined 에러 방지
|
|
949
|
+
const srcPath = path.replace("/dist/", "/src/").replace(".js", ".ts");
|
|
950
|
+
return await exists(srcPath);
|
|
951
|
+
}
|
|
952
|
+
);
|
|
800
953
|
const modules = await importMultiple(filePaths);
|
|
801
954
|
const functions = modules
|
|
802
955
|
.map(({ imported }) => Object.entries(imported))
|
|
@@ -822,16 +975,15 @@ export class Syncer {
|
|
|
822
975
|
];
|
|
823
976
|
// console.debug(chalk.magenta(`autoload:types @ ${pathPatterns.join("\n")}`));
|
|
824
977
|
|
|
825
|
-
const filePaths = (
|
|
826
|
-
await
|
|
827
|
-
|
|
828
|
-
.flat()
|
|
829
|
-
.filter((path) => {
|
|
978
|
+
const filePaths = await filterAsync(
|
|
979
|
+
(await mapAsync(pathPatterns, globAsync)).flat(),
|
|
980
|
+
async (path) => {
|
|
830
981
|
// src 디렉터리 내에 있는 해당 파일이 존재할 경우에만 로드
|
|
831
982
|
// 삭제된 파일이지만 dist에 남아있는 경우 BaseSchema undefined 에러 방지
|
|
832
983
|
const srcPath = path.replace("/dist/", "/src/").replace(".js", ".ts");
|
|
833
|
-
return
|
|
834
|
-
}
|
|
984
|
+
return await exists(srcPath);
|
|
985
|
+
}
|
|
986
|
+
);
|
|
835
987
|
const modules = await importMultiple(filePaths, doRefresh);
|
|
836
988
|
const functions = modules
|
|
837
989
|
.map(({ imported }) => Object.entries(imported))
|
|
@@ -877,8 +1029,6 @@ export class Syncer {
|
|
|
877
1029
|
return new Template__view_enums_dropdown();
|
|
878
1030
|
} else if (key === "view_enums_buttonset") {
|
|
879
1031
|
return new Template__view_enums_buttonset();
|
|
880
|
-
} else if (key === "kysely_interface") {
|
|
881
|
-
return new Template__kysely_interface();
|
|
882
1032
|
} else {
|
|
883
1033
|
throw new BadRequestException(`잘못된 템플릿 키 ${key}`);
|
|
884
1034
|
}
|
|
@@ -1012,13 +1162,13 @@ export class Syncer {
|
|
|
1012
1162
|
return await Promise.all(
|
|
1013
1163
|
dstFilePaths.map(async (dstFilePath) => {
|
|
1014
1164
|
const dir = path.dirname(dstFilePath);
|
|
1015
|
-
if (
|
|
1016
|
-
|
|
1165
|
+
if (!(await exists(dir))) {
|
|
1166
|
+
await mkdir(dir, { recursive: true });
|
|
1017
1167
|
}
|
|
1018
|
-
|
|
1168
|
+
await writeFile(dstFilePath, pathAndCode.code);
|
|
1019
1169
|
console.log(
|
|
1020
|
-
"
|
|
1021
|
-
|
|
1170
|
+
chalk.bold("Generated: ") +
|
|
1171
|
+
chalk.blue(`${dstFilePath.replace(appRootPath + "/", "")}`)
|
|
1022
1172
|
);
|
|
1023
1173
|
return dstFilePath;
|
|
1024
1174
|
})
|
|
@@ -1047,18 +1197,19 @@ export class Syncer {
|
|
|
1047
1197
|
)
|
|
1048
1198
|
).flat();
|
|
1049
1199
|
|
|
1050
|
-
const filteredPathAndCodes: PathAndCode[] = (() => {
|
|
1200
|
+
const filteredPathAndCodes: PathAndCode[] = await (async () => {
|
|
1051
1201
|
if (generateOptions.overwrite === true) {
|
|
1052
1202
|
return pathAndCodes;
|
|
1053
1203
|
} else {
|
|
1054
|
-
return pathAndCodes
|
|
1204
|
+
return await filterAsync(pathAndCodes, async (pathAndCode) => {
|
|
1055
1205
|
const { targets } = Sonamu.config.sync;
|
|
1056
1206
|
const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}`;
|
|
1057
1207
|
const dstFilePaths = targets.map((target) =>
|
|
1058
1208
|
filePath.replace("/:target/", `/${target}/`)
|
|
1059
1209
|
);
|
|
1060
|
-
return
|
|
1061
|
-
|
|
1210
|
+
return await everyAsync(
|
|
1211
|
+
dstFilePaths,
|
|
1212
|
+
async (dstPath) => !(await exists(dstPath))
|
|
1062
1213
|
);
|
|
1063
1214
|
});
|
|
1064
1215
|
}
|
|
@@ -1076,11 +1227,11 @@ export class Syncer {
|
|
|
1076
1227
|
);
|
|
1077
1228
|
}
|
|
1078
1229
|
|
|
1079
|
-
checkExistsGenCode(
|
|
1230
|
+
async checkExistsGenCode(
|
|
1080
1231
|
entityId: string,
|
|
1081
1232
|
templateKey: TemplateKey,
|
|
1082
1233
|
enumId?: string
|
|
1083
|
-
): { subPath: string; fullPath: string; isExists: boolean } {
|
|
1234
|
+
): Promise<{ subPath: string; fullPath: string; isExists: boolean }> {
|
|
1084
1235
|
const { target, path: genPath } = this.getTemplate(
|
|
1085
1236
|
templateKey
|
|
1086
1237
|
).getTargetAndPath(EntityManager.getNamesFromId(entityId), enumId);
|
|
@@ -1090,32 +1241,33 @@ export class Syncer {
|
|
|
1090
1241
|
return {
|
|
1091
1242
|
subPath,
|
|
1092
1243
|
fullPath,
|
|
1093
|
-
isExists:
|
|
1244
|
+
isExists: await exists(fullPath),
|
|
1094
1245
|
};
|
|
1095
1246
|
}
|
|
1096
1247
|
|
|
1097
|
-
checkExists(
|
|
1248
|
+
async checkExists(
|
|
1098
1249
|
entityId: string,
|
|
1099
1250
|
enums: {
|
|
1100
1251
|
[name: string]: z.ZodEnum<any>;
|
|
1101
1252
|
}
|
|
1102
|
-
): Record<`${TemplateKey}${string}`, boolean
|
|
1253
|
+
): Promise<Record<`${TemplateKey}${string}`, boolean>> {
|
|
1103
1254
|
const keys: TemplateKey[] = TemplateKey.options;
|
|
1104
1255
|
const names = EntityManager.getNamesFromId(entityId);
|
|
1105
1256
|
const enumsKeys = Object.keys(enums).filter(
|
|
1106
1257
|
(name) => name !== names.constant
|
|
1107
1258
|
);
|
|
1108
1259
|
|
|
1109
|
-
return
|
|
1110
|
-
|
|
1260
|
+
return await reduceAsync(
|
|
1261
|
+
keys,
|
|
1262
|
+
async (result, key) => {
|
|
1111
1263
|
const tpl = this.getTemplate(key);
|
|
1112
1264
|
if (key.startsWith("view_enums")) {
|
|
1113
|
-
enumsKeys
|
|
1265
|
+
await mapAsync(enumsKeys, async (componentId) => {
|
|
1114
1266
|
const { target, path: p } = tpl.getTargetAndPath(
|
|
1115
1267
|
names,
|
|
1116
1268
|
componentId
|
|
1117
1269
|
);
|
|
1118
|
-
result[`${key}__${componentId}`] =
|
|
1270
|
+
result[`${key}__${componentId}`] = await exists(
|
|
1119
1271
|
path.join(Sonamu.appRootPath, target, p)
|
|
1120
1272
|
);
|
|
1121
1273
|
});
|
|
@@ -1125,13 +1277,13 @@ export class Syncer {
|
|
|
1125
1277
|
const { target, path: p } = tpl.getTargetAndPath(names);
|
|
1126
1278
|
const { targets } = Sonamu.config.sync;
|
|
1127
1279
|
if (target.includes(":target")) {
|
|
1128
|
-
targets
|
|
1129
|
-
result[`${key}__${t}`] =
|
|
1280
|
+
await mapAsync(targets, async (t) => {
|
|
1281
|
+
result[`${key}__${t}`] = await exists(
|
|
1130
1282
|
path.join(Sonamu.appRootPath, target.replace(":target", t), p)
|
|
1131
1283
|
);
|
|
1132
1284
|
});
|
|
1133
1285
|
} else {
|
|
1134
|
-
result[key] =
|
|
1286
|
+
result[key] = await exists(path.join(Sonamu.appRootPath, target, p));
|
|
1135
1287
|
}
|
|
1136
1288
|
|
|
1137
1289
|
return result;
|
|
@@ -1221,13 +1373,13 @@ export class Syncer {
|
|
|
1221
1373
|
} else if (isTimeProp(prop)) {
|
|
1222
1374
|
zodType = z.string().length(8);
|
|
1223
1375
|
} else if (isDateTimeProp(prop)) {
|
|
1224
|
-
zodType =
|
|
1376
|
+
zodType = z.date();
|
|
1225
1377
|
} else if (isTimestampProp(prop)) {
|
|
1226
|
-
zodType =
|
|
1378
|
+
zodType = z.date();
|
|
1227
1379
|
} else if (isJsonProp(prop)) {
|
|
1228
1380
|
zodType = await this.getZodTypeById(prop.id);
|
|
1229
1381
|
} else if (isUuidProp(prop)) {
|
|
1230
|
-
zodType = z.
|
|
1382
|
+
zodType = z.uuid();
|
|
1231
1383
|
} else if (isVirtualProp(prop)) {
|
|
1232
1384
|
zodType = await this.getZodTypeById(prop.id);
|
|
1233
1385
|
} else if (isRelationProp(prop)) {
|
|
@@ -1255,7 +1407,9 @@ export class Syncer {
|
|
|
1255
1407
|
key: string,
|
|
1256
1408
|
zodType: z.ZodTypeAny
|
|
1257
1409
|
): RenderingNode["renderType"] {
|
|
1258
|
-
if (zodType instanceof z.
|
|
1410
|
+
if (zodType instanceof z.ZodDate) {
|
|
1411
|
+
return "datetime";
|
|
1412
|
+
} else if (zodType instanceof z.ZodString) {
|
|
1259
1413
|
if (key.includes("img") || key.includes("image")) {
|
|
1260
1414
|
return "string-image";
|
|
1261
1415
|
} else if (zodType.description === "SQLDateTimeString") {
|
|
@@ -1286,11 +1440,12 @@ export class Syncer {
|
|
|
1286
1440
|
} else if (zodType instanceof z.ZodLiteral) {
|
|
1287
1441
|
return "string-plain";
|
|
1288
1442
|
} else {
|
|
1289
|
-
throw new Error(`타입 파싱 불가 ${key} ${zodType.
|
|
1443
|
+
throw new Error(`타입 파싱 불가 ${key} ${zodType.def.type}`);
|
|
1290
1444
|
}
|
|
1291
1445
|
}
|
|
1446
|
+
|
|
1292
1447
|
zodTypeToRenderingNode(
|
|
1293
|
-
zodType: z.
|
|
1448
|
+
zodType: z.ZodType<any>,
|
|
1294
1449
|
baseKey: string = "root"
|
|
1295
1450
|
): RenderingNode {
|
|
1296
1451
|
const def = {
|
|
@@ -1310,7 +1465,7 @@ export class Syncer {
|
|
|
1310
1465
|
children,
|
|
1311
1466
|
};
|
|
1312
1467
|
} else if (zodType instanceof z.ZodArray) {
|
|
1313
|
-
const innerType = zodType.
|
|
1468
|
+
const innerType = (zodType as z.ZodArray<z.ZodType<any>>).def.element;
|
|
1314
1469
|
if (innerType instanceof z.ZodString && baseKey.includes("images")) {
|
|
1315
1470
|
return {
|
|
1316
1471
|
...def,
|
|
@@ -1323,19 +1478,19 @@ export class Syncer {
|
|
|
1323
1478
|
element: this.zodTypeToRenderingNode(innerType, baseKey),
|
|
1324
1479
|
};
|
|
1325
1480
|
} else if (zodType instanceof z.ZodUnion) {
|
|
1326
|
-
const optionNodes = zodType.
|
|
1481
|
+
const optionNodes = (zodType as z.ZodUnion<z.ZodType[]>).def.options.map((opt) =>
|
|
1327
1482
|
this.zodTypeToRenderingNode(opt, baseKey)
|
|
1328
1483
|
);
|
|
1329
1484
|
// TODO: ZodUnion이 들어있는 경우 핸들링
|
|
1330
1485
|
return optionNodes[0];
|
|
1331
1486
|
} else if (zodType instanceof z.ZodOptional) {
|
|
1332
1487
|
return {
|
|
1333
|
-
...this.zodTypeToRenderingNode(zodType.
|
|
1488
|
+
...this.zodTypeToRenderingNode((zodType as z.ZodOptional<z.ZodType>).def.innerType, baseKey),
|
|
1334
1489
|
optional: true,
|
|
1335
1490
|
};
|
|
1336
1491
|
} else if (zodType instanceof z.ZodNullable) {
|
|
1337
1492
|
return {
|
|
1338
|
-
...this.zodTypeToRenderingNode(zodType.
|
|
1493
|
+
...this.zodTypeToRenderingNode((zodType as z.ZodNullable<z.ZodType>).def.innerType, baseKey),
|
|
1339
1494
|
nullable: true,
|
|
1340
1495
|
};
|
|
1341
1496
|
} else {
|
|
@@ -1350,7 +1505,7 @@ export class Syncer {
|
|
|
1350
1505
|
entityId: string,
|
|
1351
1506
|
subsetKey: string
|
|
1352
1507
|
): Promise<RenderingNode> {
|
|
1353
|
-
const entity =
|
|
1508
|
+
const entity = EntityManager.get(entityId);
|
|
1354
1509
|
const subsetA = entity.subsets[subsetKey];
|
|
1355
1510
|
if (subsetA === undefined) {
|
|
1356
1511
|
throw new ServiceUnavailableException("SubsetA 가 없습니다.");
|
|
@@ -1423,17 +1578,19 @@ export class Syncer {
|
|
|
1423
1578
|
// reload entities
|
|
1424
1579
|
await EntityManager.reload();
|
|
1425
1580
|
|
|
1426
|
-
//
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
]
|
|
1581
|
+
// syncFromWatcher에서 처리하므로 주석처리
|
|
1582
|
+
// this.actionGenerateSchemas();
|
|
1583
|
+
|
|
1584
|
+
// // generate schemas, types
|
|
1585
|
+
// await Promise.all([
|
|
1586
|
+
// ...(form.parentId === undefined
|
|
1587
|
+
// ? [
|
|
1588
|
+
// this.generateTemplate("init_types", {
|
|
1589
|
+
// entityId: form.entityId,
|
|
1590
|
+
// }),
|
|
1591
|
+
// ]
|
|
1592
|
+
// : []),
|
|
1593
|
+
// ]);
|
|
1437
1594
|
}
|
|
1438
1595
|
|
|
1439
1596
|
async delEntity(entityId: string): Promise<{ delPaths: string[] }> {
|
|
@@ -1458,9 +1615,9 @@ export class Syncer {
|
|
|
1458
1615
|
})(); // iife
|
|
1459
1616
|
|
|
1460
1617
|
for await (const delPath of delPaths) {
|
|
1461
|
-
if (
|
|
1618
|
+
if (await exists(delPath)) {
|
|
1462
1619
|
console.log(chalk.red(`DELETE ${delPath}`));
|
|
1463
|
-
|
|
1620
|
+
await rm(delPath, { recursive: true, force: true });
|
|
1464
1621
|
} else {
|
|
1465
1622
|
console.log(chalk.yellow(`NOT_EXISTS ${delPath}`));
|
|
1466
1623
|
}
|
|
@@ -1471,4 +1628,14 @@ export class Syncer {
|
|
|
1471
1628
|
|
|
1472
1629
|
return { delPaths };
|
|
1473
1630
|
}
|
|
1631
|
+
|
|
1632
|
+
syncUI() {
|
|
1633
|
+
const uiPort = Sonamu.config.ui?.port ?? 57000;
|
|
1634
|
+
|
|
1635
|
+
fetch(`http://127.0.0.1:${uiPort}/api/reload`, {
|
|
1636
|
+
method: "GET",
|
|
1637
|
+
}).catch((e) =>
|
|
1638
|
+
console.log(chalk.dim(`Failed to reload Sonamu UI: ${e.message}`))
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1474
1641
|
}
|