sonamu 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.swcrc.project-default +18 -0
- package/bin/cli.js +24 -0
- package/dist/ai/agents/agent.d.ts +11 -0
- package/dist/ai/agents/agent.d.ts.map +1 -0
- package/dist/ai/agents/agent.js +65 -0
- package/dist/ai/agents/index.d.ts +3 -0
- package/dist/ai/agents/index.d.ts.map +1 -0
- package/dist/ai/agents/index.js +4 -0
- package/dist/ai/agents/types.d.ts +43 -0
- package/dist/ai/agents/types.d.ts.map +1 -0
- package/dist/ai/agents/types.js +3 -0
- package/dist/ai/index.d.ts +2 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +3 -0
- package/dist/ai/providers/rtzr/api.d.ts +22 -0
- package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/api.js +28 -0
- package/dist/ai/providers/rtzr/error.d.ts +18 -0
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/error.js +29 -0
- package/dist/ai/providers/rtzr/index.d.ts +5 -0
- package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/index.js +6 -0
- package/dist/ai/providers/rtzr/model.d.ts +52 -0
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/model.js +137 -0
- package/dist/ai/providers/rtzr/options.d.ts +7 -0
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/options.js +47 -0
- package/dist/ai/providers/rtzr/provider.d.ts +18 -0
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/provider.js +54 -0
- package/dist/ai/providers/rtzr/utils.d.ts +19 -0
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/utils.js +88 -0
- package/dist/api/base-frame.d.ts +2 -2
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/base-frame.js +2 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +6 -1
- package/dist/api/code-converters.d.ts +58 -14
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +178 -409
- package/dist/api/config.d.ts +27 -13
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +19 -26
- package/dist/api/context.d.ts +4 -3
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts +20 -6
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +111 -18
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +3 -3
- package/dist/api/sonamu.d.ts +7 -7
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +83 -51
- package/dist/api/validator.d.ts +6 -0
- package/dist/api/validator.d.ts.map +1 -0
- package/dist/api/validator.js +81 -0
- package/dist/bin/build-config.d.ts +5 -1
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +5 -2
- package/dist/bin/cli.js +165 -64
- package/dist/bin/loader-register.d.ts +2 -0
- package/dist/bin/loader-register.d.ts.map +1 -0
- package/dist/bin/loader-register.js +34 -0
- package/dist/database/_batch_update.d.ts +5 -3
- package/dist/database/_batch_update.d.ts.map +1 -1
- package/dist/database/_batch_update.js +30 -13
- package/dist/database/base-model.d.ts +96 -10
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +232 -89
- package/dist/database/base-model.types.d.ts +93 -0
- package/dist/database/base-model.types.d.ts.map +1 -0
- package/dist/database/base-model.types.js +10 -0
- package/dist/database/code-generator.d.ts +1 -1
- package/dist/database/code-generator.d.ts.map +1 -1
- package/dist/database/code-generator.js +11 -10
- package/dist/database/db.d.ts +5 -6
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +22 -25
- package/dist/database/puri-subset.test-d.js +81 -0
- package/dist/database/puri-subset.types.d.ts +123 -0
- package/dist/database/puri-subset.types.d.ts.map +1 -0
- package/dist/database/puri-subset.types.js +16 -0
- package/dist/database/puri-wrapper.d.ts +13 -11
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +2 -2
- package/dist/database/puri.d.ts +25 -14
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +83 -21
- package/dist/database/puri.types.d.ts +21 -7
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +4 -1
- package/dist/database/transaction-context.d.ts +1 -1
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js +1 -1
- package/dist/database/upsert-builder.d.ts +9 -3
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +228 -78
- package/dist/entity/entity-manager.d.ts +165 -2
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +26 -10
- package/dist/entity/entity.d.ts +5 -3
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +153 -54
- package/dist/exceptions/error-handler.d.ts +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +1 -1
- package/dist/exceptions/so-exceptions.d.ts +1 -1
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +1 -1
- package/dist/file-storage/driver.d.ts +1 -1
- package/dist/file-storage/driver.d.ts.map +1 -1
- package/dist/file-storage/driver.js +1 -1
- package/dist/file-storage/file-storage.js +2 -2
- package/dist/index.d.ts +18 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -13
- package/dist/migration/code-generation.d.ts +1 -1
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +123 -67
- package/dist/migration/migration-set.d.ts +2 -10
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +67 -218
- package/dist/migration/migrator.d.ts +24 -73
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +121 -301
- package/dist/migration/postgresql-schema-reader.d.ts +51 -0
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
- package/dist/migration/postgresql-schema-reader.js +245 -0
- package/dist/migration/types.d.ts +6 -38
- package/dist/migration/types.d.ts.map +1 -1
- package/dist/migration/types.js +1 -1
- package/dist/naite/messaging-types.d.ts +43 -0
- package/dist/naite/messaging-types.d.ts.map +1 -0
- package/dist/naite/messaging-types.js +7 -0
- package/dist/naite/naite-reporter.d.ts +41 -0
- package/dist/naite/naite-reporter.d.ts.map +1 -0
- package/dist/naite/naite-reporter.js +102 -0
- package/dist/naite/naite.d.ts +91 -8
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +285 -41
- package/dist/stream/sse.d.ts +2 -2
- package/dist/stream/sse.d.ts.map +1 -1
- package/dist/stream/sse.js +1 -1
- package/dist/syncer/api-parser.d.ts +3 -13
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +67 -56
- package/dist/syncer/checksum.d.ts +2 -2
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +11 -11
- package/dist/syncer/code-generator.d.ts +3 -3
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +37 -17
- package/dist/syncer/entity-operations.d.ts +2 -2
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +9 -8
- package/dist/syncer/file-patterns.d.ts +1 -1
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +1 -1
- package/dist/syncer/index.d.ts +4 -4
- package/dist/syncer/index.d.ts.map +1 -1
- package/dist/syncer/index.js +5 -5
- package/dist/syncer/module-loader.d.ts +4 -4
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +17 -12
- package/dist/syncer/syncer.d.ts +31 -24
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +92 -45
- package/dist/template/entity-converter.d.ts +1 -1
- package/dist/template/entity-converter.d.ts.map +1 -1
- package/dist/template/entity-converter.js +15 -8
- package/dist/template/helpers.d.ts +2 -2
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +3 -3
- package/dist/template/implementations/entity.template.d.ts +2 -2
- package/dist/template/implementations/entity.template.d.ts.map +1 -1
- package/dist/template/implementations/entity.template.js +4 -5
- package/dist/template/implementations/generated.template.d.ts +2 -3
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +46 -29
- package/dist/template/implementations/generated_http.template.d.ts +2 -3
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +9 -9
- package/dist/template/implementations/generated_sso.template.d.ts +3 -4
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +54 -25
- package/dist/template/implementations/init_types.template.d.ts +2 -2
- package/dist/template/implementations/init_types.template.d.ts.map +1 -1
- package/dist/template/implementations/init_types.template.js +2 -2
- package/dist/template/implementations/model.template.d.ts +2 -2
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +47 -37
- package/dist/template/implementations/model_test.template.d.ts +2 -2
- package/dist/template/implementations/model_test.template.d.ts.map +1 -1
- package/dist/template/implementations/model_test.template.js +2 -2
- package/dist/template/implementations/service.template.d.ts +4 -4
- package/dist/template/implementations/service.template.d.ts.map +1 -1
- package/dist/template/implementations/service.template.js +24 -16
- package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
- package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
- package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_select.template.js +2 -2
- package/dist/template/implementations/view_form.template.d.ts +2 -2
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +4 -4
- package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_all_select.template.js +1 -1
- package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
- package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_async_select.template.js +1 -1
- package/dist/template/implementations/view_list.template.d.ts +2 -2
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +29 -19
- package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
- package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list_columns.template.js +1 -1
- package/dist/template/implementations/view_search_input.template.d.ts +2 -2
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.js +1 -1
- package/dist/template/index.d.ts +4 -2
- package/dist/template/index.d.ts.map +1 -1
- package/dist/template/index.js +5 -3
- package/dist/template/template-manager.d.ts +56 -0
- package/dist/template/template-manager.d.ts.map +1 -0
- package/dist/template/template-manager.js +125 -0
- package/dist/template/template-types.d.ts +16 -0
- package/dist/template/template-types.d.ts.map +1 -0
- package/dist/template/template-types.js +7 -0
- package/dist/template/template.d.ts +12 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +19 -6
- package/dist/template/zod-converter.d.ts +40 -7
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +341 -58
- package/dist/testing/_relation-graph.d.ts +1 -1
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +12 -3
- package/dist/testing/fixture-manager.d.ts +42 -11
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +338 -236
- package/dist/types/types.d.ts +709 -104
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +309 -52
- package/dist/typings/knex.d.js +2 -2
- package/dist/utils/async-utils.d.ts.map +1 -1
- package/dist/utils/async-utils.js +3 -3
- package/dist/utils/console-util.js +1 -1
- package/dist/utils/controller.d.ts +1 -0
- package/dist/utils/controller.d.ts.map +1 -1
- package/dist/utils/controller.js +4 -1
- package/dist/utils/esm-utils.d.ts +0 -6
- package/dist/utils/esm-utils.d.ts.map +1 -1
- package/dist/utils/esm-utils.js +2 -9
- package/dist/utils/formatter.d.ts +3 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +110 -0
- package/dist/utils/fs-utils.d.ts +1 -1
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +1 -1
- package/dist/utils/lodash-able.d.ts.map +1 -1
- package/dist/utils/lodash-able.js +1 -1
- package/dist/utils/object-utils.d.ts +44 -0
- package/dist/utils/object-utils.d.ts.map +1 -0
- package/dist/utils/object-utils.js +191 -0
- package/dist/utils/path-utils.d.ts +1 -1
- package/dist/utils/path-utils.d.ts.map +1 -1
- package/dist/utils/path-utils.js +3 -3
- package/dist/utils/process-utils.js +1 -1
- package/dist/utils/sql-parser.d.ts +5 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +14 -3
- package/dist/utils/type-utils.d.ts +23 -0
- package/dist/utils/type-utils.d.ts.map +1 -0
- package/dist/utils/type-utils.js +45 -0
- package/dist/utils/utils.d.ts +7 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +44 -5
- package/dist/utils/zod-error.d.ts +1 -1
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +1 -1
- package/package.json +54 -29
- package/src/ai/agents/agent.ts +87 -0
- package/src/ai/agents/index.ts +2 -0
- package/src/ai/agents/types.ts +47 -0
- package/src/ai/index.ts +1 -0
- package/src/ai/providers/rtzr/api.ts +37 -0
- package/src/ai/providers/rtzr/error.ts +34 -0
- package/src/ai/providers/rtzr/index.ts +4 -0
- package/src/ai/providers/rtzr/model.ts +201 -0
- package/src/ai/providers/rtzr/options.ts +49 -0
- package/src/ai/providers/rtzr/provider.ts +91 -0
- package/src/ai/providers/rtzr/utils.ts +127 -0
- package/src/api/base-frame.ts +4 -2
- package/src/api/caster.ts +17 -23
- package/src/api/code-converters.ts +176 -533
- package/src/api/config.ts +39 -56
- package/src/api/context.ts +7 -18
- package/src/api/decorators.ts +175 -46
- package/src/api/index.ts +2 -2
- package/src/api/sonamu.ts +133 -124
- package/src/api/validator.ts +83 -0
- package/src/bin/build-config.ts +7 -1
- package/src/bin/cli.ts +192 -110
- package/src/bin/loader-register.ts +38 -0
- package/src/database/_batch_update.ts +46 -31
- package/src/database/base-model.ts +390 -182
- package/src/database/base-model.types.ts +155 -0
- package/src/database/code-generator.ts +13 -32
- package/src/database/db.ts +36 -50
- package/src/database/puri-subset.test-d.ts +471 -0
- package/src/database/puri-subset.types.ts +195 -0
- package/src/database/puri-wrapper.ts +58 -67
- package/src/database/puri.ts +182 -126
- package/src/database/puri.types.ts +64 -31
- package/src/database/transaction-context.ts +1 -1
- package/src/database/upsert-builder.ts +262 -132
- package/src/entity/entity-manager.ts +36 -28
- package/src/entity/entity.ts +330 -249
- package/src/exceptions/error-handler.ts +3 -3
- package/src/exceptions/so-exceptions.ts +11 -11
- package/src/file-storage/driver.ts +5 -5
- package/src/file-storage/file-storage.ts +2 -2
- package/src/index.ts +18 -12
- package/src/migration/code-generation.ts +185 -172
- package/src/migration/migration-set.ts +80 -293
- package/src/migration/migrator.ts +182 -425
- package/src/migration/mysql-schema-reader.ts.txt +272 -0
- package/src/migration/postgresql-schema-reader.ts +310 -0
- package/src/migration/types.ts +6 -39
- package/src/naite/messaging-types.ts +51 -0
- package/src/naite/naite-reporter.ts +128 -0
- package/src/naite/naite.ts +378 -33
- package/src/shared/web.shared.ts.txt +20 -24
- package/src/stream/sse.ts +5 -5
- package/src/syncer/api-parser.ts +52 -69
- package/src/syncer/checksum.ts +25 -37
- package/src/syncer/code-generator.ts +58 -62
- package/src/syncer/entity-operations.ts +12 -15
- package/src/syncer/file-patterns.ts +2 -2
- package/src/syncer/index.ts +4 -4
- package/src/syncer/module-loader.ts +28 -25
- package/src/syncer/syncer.ts +155 -162
- package/src/template/entity-converter.ts +18 -27
- package/src/template/helpers.ts +8 -11
- package/src/template/implementations/entity.template.ts +6 -6
- package/src/template/implementations/generated.template.ts +99 -99
- package/src/template/implementations/generated_http.template.ts +21 -54
- package/src/template/implementations/generated_sso.template.ts +78 -65
- package/src/template/implementations/init_types.template.ts +4 -6
- package/src/template/implementations/model.template.ts +47 -38
- package/src/template/implementations/model_test.template.ts +3 -3
- package/src/template/implementations/service.template.ts +56 -80
- package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
- package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
- package/src/template/implementations/view_enums_select.template.ts +3 -3
- package/src/template/implementations/view_form.template.ts +34 -75
- package/src/template/implementations/view_id_all_select.template.ts +2 -2
- package/src/template/implementations/view_id_async_select.template.ts +9 -23
- package/src/template/implementations/view_list.template.ts +54 -95
- package/src/template/implementations/view_list_columns.template.ts +4 -10
- package/src/template/implementations/view_search_input.template.ts +2 -2
- package/src/template/index.ts +4 -2
- package/src/template/template-manager.ts +166 -0
- package/src/template/template-types.ts +16 -0
- package/src/template/template.ts +29 -10
- package/src/template/zod-converter.ts +407 -101
- package/src/testing/_relation-graph.ts +18 -11
- package/src/testing/fixture-manager.ts +468 -362
- package/src/types/types.ts +516 -248
- package/src/typings/knex.d.ts +7 -9
- package/src/utils/async-utils.ts +8 -12
- package/src/utils/console-util.ts +1 -1
- package/src/utils/controller.ts +3 -0
- package/src/utils/esm-utils.ts +8 -18
- package/src/utils/formatter.ts +109 -0
- package/src/utils/fs-utils.ts +1 -1
- package/src/utils/lodash-able.ts +1 -4
- package/src/utils/object-utils.ts +217 -0
- package/src/utils/path-utils.ts +3 -6
- package/src/utils/process-utils.ts +1 -1
- package/src/utils/sql-parser.ts +23 -5
- package/src/utils/type-utils.ts +83 -0
- package/src/utils/utils.ts +58 -9
- package/src/utils/zod-error.ts +3 -3
- package/dist/bin/cli-wrapper.d.ts +0 -3
- package/dist/bin/cli-wrapper.d.ts.map +0 -1
- package/dist/bin/cli-wrapper.js +0 -72
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -39
- package/dist/entity/entity-utils.d.ts +0 -61
- package/dist/entity/entity-utils.d.ts.map +0 -1
- package/dist/entity/entity-utils.js +0 -210
- package/src/bin/cli-wrapper.ts +0 -82
- package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
- package/src/entity/entity-utils.ts +0 -291
|
@@ -1,23 +1,20 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
1
3
|
import path from "path";
|
|
4
|
+
import { unique } from "radashi";
|
|
2
5
|
import { Sonamu } from "../api/sonamu";
|
|
6
|
+
import { EntityManager } from "../entity/entity-manager";
|
|
3
7
|
import { AlreadyProcessedException } from "../exceptions/so-exceptions";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
TemplateOptions,
|
|
9
|
-
} from "../types/types";
|
|
8
|
+
import { Naite } from "../naite/naite";
|
|
9
|
+
import type { RenderedTemplate } from "../template/template";
|
|
10
|
+
import { TemplateManager } from "../template/template-manager";
|
|
11
|
+
import type { GenerateOptions, PathAndCode, TemplateKey, TemplateOptions } from "../types/types";
|
|
10
12
|
import { everyAsync, filterAsync } from "../utils/async-utils";
|
|
13
|
+
import { isTest } from "../utils/controller";
|
|
14
|
+
import { formatCode } from "../utils/formatter";
|
|
11
15
|
import { exists } from "../utils/fs-utils";
|
|
12
|
-
import chalk from "chalk";
|
|
13
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
14
|
-
import * as _ from "lodash-es";
|
|
15
|
-
import { Template } from "../template/template";
|
|
16
|
-
import { RenderedTemplate } from "../template/template";
|
|
17
|
-
import { EntityManager } from "../entity/entity-manager";
|
|
18
16
|
import { wrapIf } from "../utils/lodash-able";
|
|
19
|
-
import
|
|
20
|
-
import { AbsolutePath } from "../utils/path-utils";
|
|
17
|
+
import type { AbsolutePath } from "../utils/path-utils";
|
|
21
18
|
|
|
22
19
|
/**
|
|
23
20
|
* 템플릿을 렌더링하고 파일로 생성합니다.
|
|
@@ -27,15 +24,16 @@ import { AbsolutePath } from "../utils/path-utils";
|
|
|
27
24
|
* @param _generateOptions - 생성 옵션 (overwrite 여부)
|
|
28
25
|
* @returns 생성된 파일 경로 배열
|
|
29
26
|
*/
|
|
30
|
-
export async function generateTemplate(
|
|
31
|
-
key:
|
|
32
|
-
templateOptions:
|
|
33
|
-
_generateOptions?: GenerateOptions
|
|
27
|
+
export async function generateTemplate<T extends TemplateKey>(
|
|
28
|
+
key: T,
|
|
29
|
+
templateOptions: TemplateOptions[T],
|
|
30
|
+
_generateOptions?: GenerateOptions,
|
|
34
31
|
): Promise<AbsolutePath[]> {
|
|
35
32
|
const generateOptions = {
|
|
36
33
|
overwrite: false,
|
|
37
34
|
..._generateOptions,
|
|
38
35
|
};
|
|
36
|
+
Naite.t("generateTemplate", { key, templateOptions, generateOptions });
|
|
39
37
|
|
|
40
38
|
// 키 children
|
|
41
39
|
const keys: TemplateKey[] = [key];
|
|
@@ -45,7 +43,7 @@ export async function generateTemplate(
|
|
|
45
43
|
await Promise.all(
|
|
46
44
|
keys.map(async (key) => {
|
|
47
45
|
return await renderTemplate(key, templateOptions);
|
|
48
|
-
})
|
|
46
|
+
}),
|
|
49
47
|
)
|
|
50
48
|
).flat();
|
|
51
49
|
|
|
@@ -56,24 +54,21 @@ export async function generateTemplate(
|
|
|
56
54
|
return await filterAsync(pathAndCodes, async (pathAndCode) => {
|
|
57
55
|
const { targets } = Sonamu.config.sync;
|
|
58
56
|
const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}`;
|
|
59
|
-
const dstFilePaths = targets.map((target) =>
|
|
60
|
-
|
|
61
|
-
);
|
|
62
|
-
return await everyAsync(
|
|
63
|
-
dstFilePaths,
|
|
64
|
-
async (dstPath) => !(await exists(dstPath))
|
|
65
|
-
);
|
|
57
|
+
const dstFilePaths = targets.map((target) => filePath.replace("/:target/", `/${target}/`));
|
|
58
|
+
return await everyAsync(dstFilePaths, async (dstPath) => !(await exists(dstPath)));
|
|
66
59
|
});
|
|
67
60
|
}
|
|
68
61
|
})();
|
|
69
|
-
|
|
62
|
+
|
|
70
63
|
if (filteredPathAndCodes.length === 0) {
|
|
71
64
|
throw new AlreadyProcessedException("이미 경로에 모든 파일이 존재합니다.");
|
|
72
65
|
}
|
|
73
66
|
|
|
74
|
-
return (
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
return (
|
|
68
|
+
await Promise.all(
|
|
69
|
+
filteredPathAndCodes.map((pathAndCode) => writeCodeToPathEachTarget(pathAndCode)),
|
|
70
|
+
)
|
|
71
|
+
).flat();
|
|
77
72
|
}
|
|
78
73
|
|
|
79
74
|
/**
|
|
@@ -85,9 +80,11 @@ export async function generateTemplate(
|
|
|
85
80
|
*/
|
|
86
81
|
export async function renderTemplate<T extends keyof TemplateOptions>(
|
|
87
82
|
key: T,
|
|
88
|
-
options: TemplateOptions[T]
|
|
83
|
+
options: TemplateOptions[T],
|
|
89
84
|
): Promise<PathAndCode[]> {
|
|
90
|
-
|
|
85
|
+
Naite.t("renderTemplate", { key, options });
|
|
86
|
+
|
|
87
|
+
const template = TemplateManager.get(key);
|
|
91
88
|
|
|
92
89
|
const rendered = await template.render(options);
|
|
93
90
|
const resolved = await resolveRenderedTemplate(key, rendered);
|
|
@@ -98,7 +95,7 @@ export async function renderTemplate<T extends keyof TemplateOptions>(
|
|
|
98
95
|
await Promise.all(
|
|
99
96
|
rendered.preTemplates.map(({ key, options }) => {
|
|
100
97
|
return renderTemplate(key, options);
|
|
101
|
-
})
|
|
98
|
+
}),
|
|
102
99
|
)
|
|
103
100
|
).flat();
|
|
104
101
|
}
|
|
@@ -108,8 +105,10 @@ export async function renderTemplate<T extends keyof TemplateOptions>(
|
|
|
108
105
|
|
|
109
106
|
async function resolveRenderedTemplate(
|
|
110
107
|
key: TemplateKey,
|
|
111
|
-
result: RenderedTemplate
|
|
108
|
+
result: RenderedTemplate,
|
|
112
109
|
): Promise<PathAndCode> {
|
|
110
|
+
Naite.t(`resolveRenderedTemplate${key}`, { key, result });
|
|
111
|
+
|
|
113
112
|
const { target, path: filePath, body, importKeys, customHeaders } = result;
|
|
114
113
|
|
|
115
114
|
// import 할 대상의 대상 path 추출
|
|
@@ -119,16 +118,16 @@ async function resolveRenderedTemplate(
|
|
|
119
118
|
const modulePath = EntityManager.getModulePath(importKey);
|
|
120
119
|
let importPath = modulePath;
|
|
121
120
|
if (modulePath.includes("/") || modulePath.includes(".")) {
|
|
122
|
-
importPath = wrapIf(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
);
|
|
121
|
+
importPath = wrapIf(path.relative(path.dirname(filePath), modulePath), (p) => [
|
|
122
|
+
p.startsWith(".") === false,
|
|
123
|
+
`./${p}`,
|
|
124
|
+
]);
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
// 같은 파일에서 import 하는 경우 keys 로 나열 처리
|
|
129
128
|
const existsOne = r.find((importDef) => importDef.from === importPath);
|
|
130
129
|
if (existsOne) {
|
|
131
|
-
existsOne.keys =
|
|
130
|
+
existsOne.keys = unique(existsOne.keys.concat(importKey));
|
|
132
131
|
} else {
|
|
133
132
|
r.push({
|
|
134
133
|
keys: [importKey],
|
|
@@ -140,20 +139,16 @@ async function resolveRenderedTemplate(
|
|
|
140
139
|
[] as {
|
|
141
140
|
keys: string[];
|
|
142
141
|
from: string;
|
|
143
|
-
}[]
|
|
142
|
+
}[],
|
|
144
143
|
)
|
|
145
144
|
// 셀프 참조 방지
|
|
146
|
-
.filter(
|
|
147
|
-
(importDef) =>
|
|
148
|
-
filePath.endsWith(importDef.from.replace("./", "") + ".ts") === false
|
|
149
|
-
);
|
|
145
|
+
.filter((importDef) => filePath.endsWith(`${importDef.from.replace("./", "")}.ts`) === false);
|
|
150
146
|
|
|
151
147
|
// 커스텀 헤더 포함하여 헤더 생성
|
|
152
148
|
const header = [
|
|
153
149
|
...(customHeaders ?? []),
|
|
154
150
|
...importDefs.map(
|
|
155
|
-
(importDef) =>
|
|
156
|
-
`import { ${importDef.keys.join(", ")} } from '${importDef.from}'`
|
|
151
|
+
(importDef) => `import { ${importDef.keys.join(", ")} } from '${importDef.from}'`,
|
|
157
152
|
),
|
|
158
153
|
].join("\n");
|
|
159
154
|
|
|
@@ -161,29 +156,30 @@ async function resolveRenderedTemplate(
|
|
|
161
156
|
if (key === "generated_http") {
|
|
162
157
|
return [header, body].join("\n\n");
|
|
163
158
|
} else {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
159
|
+
Naite.t("resolveRenderedTemplate:beforeFormat", { key, header, body });
|
|
160
|
+
const formatted = formatCode(
|
|
161
|
+
[header, body].join("\n\n"),
|
|
162
|
+
key === "entity" ? "json" : "typescript",
|
|
163
|
+
`${Sonamu.appRootPath}/${filePath}`,
|
|
164
|
+
);
|
|
165
|
+
Naite.t(`resolveRenderedTemplate:formatted:${key}`, formatted);
|
|
166
|
+
return formatted;
|
|
167
167
|
}
|
|
168
168
|
})();
|
|
169
169
|
|
|
170
170
|
return {
|
|
171
|
-
path: target
|
|
171
|
+
path: `${target}/${filePath}`,
|
|
172
172
|
code: formatted,
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
async function writeCodeToPathEachTarget(
|
|
177
|
-
pathAndCode: PathAndCode
|
|
178
|
-
): Promise<AbsolutePath[]> {
|
|
176
|
+
async function writeCodeToPathEachTarget(pathAndCode: PathAndCode): Promise<AbsolutePath[]> {
|
|
179
177
|
const { targets } = Sonamu.config.sync;
|
|
180
178
|
const { appRootPath } = Sonamu;
|
|
181
179
|
const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}` as AbsolutePath;
|
|
182
180
|
|
|
183
|
-
const dstFilePaths =
|
|
184
|
-
targets.map((target) =>
|
|
185
|
-
filePath.replace("/:target/", `/${target}/`)
|
|
186
|
-
) as AbsolutePath[]
|
|
181
|
+
const dstFilePaths = unique(
|
|
182
|
+
targets.map((target) => filePath.replace("/:target/", `/${target}/`)) as AbsolutePath[],
|
|
187
183
|
);
|
|
188
184
|
return await Promise.all(
|
|
189
185
|
dstFilePaths.map(async (dstFilePath) => {
|
|
@@ -192,11 +188,11 @@ async function writeCodeToPathEachTarget(
|
|
|
192
188
|
await mkdir(dir, { recursive: true });
|
|
193
189
|
}
|
|
194
190
|
await writeFile(dstFilePath, pathAndCode.code);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
chalk.blue(`${dstFilePath.replace(appRootPath
|
|
198
|
-
|
|
191
|
+
!isTest() &&
|
|
192
|
+
console.log(
|
|
193
|
+
chalk.bold("Generated: ") + chalk.blue(`${dstFilePath.replace(`${appRootPath}/`, "")}`),
|
|
194
|
+
);
|
|
199
195
|
return dstFilePath;
|
|
200
|
-
})
|
|
196
|
+
}),
|
|
201
197
|
);
|
|
202
198
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { rm } from "fs/promises";
|
|
2
|
-
import { exists } from "../utils/fs-utils";
|
|
3
1
|
import chalk from "chalk";
|
|
2
|
+
import { rm } from "fs/promises";
|
|
3
|
+
import { Sonamu } from "../api/sonamu";
|
|
4
4
|
import { EntityManager } from "../entity/entity-manager";
|
|
5
|
-
import { TemplateOptions } from "../types/types";
|
|
6
5
|
import { BadRequestException } from "../exceptions/so-exceptions";
|
|
7
|
-
import {
|
|
6
|
+
import type { TemplateOptions } from "../types/types";
|
|
7
|
+
import { isTest } from "../utils/controller";
|
|
8
|
+
import { exists } from "../utils/fs-utils";
|
|
8
9
|
import { generateTemplate } from "./code-generator";
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -12,7 +13,7 @@ import { generateTemplate } from "./code-generator";
|
|
|
12
13
|
* entityId는 반드시 CamelCase 형식이어야 합니다.
|
|
13
14
|
*/
|
|
14
15
|
export async function createEntity(
|
|
15
|
-
form: Omit<TemplateOptions["entity"], "title"> & { title
|
|
16
|
+
form: Omit<TemplateOptions["entity"], "title"> & { title: string },
|
|
16
17
|
) {
|
|
17
18
|
if (!/^[A-Z][a-zA-Z0-9]*$/.test(form.entityId)) {
|
|
18
19
|
throw new BadRequestException("entityId는 CamelCase 형식이어야 합니다.");
|
|
@@ -29,9 +30,7 @@ export async function createEntity(
|
|
|
29
30
|
* parentId가 있는 서브 엔티티의 경우 entity.json만 삭제하고,
|
|
30
31
|
* 루트 엔티티의 경우 디렉토리 전체와 타겟 디렉토리를 삭제합니다.
|
|
31
32
|
*/
|
|
32
|
-
export async function delEntity(
|
|
33
|
-
entityId: string
|
|
34
|
-
): Promise<{ delPaths: string[] }> {
|
|
33
|
+
export async function delEntity(entityId: string): Promise<{ delPaths: string[] }> {
|
|
35
34
|
const entity = EntityManager.get(entityId);
|
|
36
35
|
|
|
37
36
|
const delPaths = (() => {
|
|
@@ -43,21 +42,19 @@ export async function delEntity(
|
|
|
43
42
|
return [
|
|
44
43
|
`${Sonamu.apiRootPath}/src/application/${entity.names.fs}`,
|
|
45
44
|
`${Sonamu.apiRootPath}/dist/application/${entity.names.fs}`,
|
|
46
|
-
...Sonamu.config.sync.targets
|
|
47
|
-
.
|
|
48
|
-
|
|
49
|
-
])
|
|
50
|
-
.flat(),
|
|
45
|
+
...Sonamu.config.sync.targets.flatMap((target) => [
|
|
46
|
+
`${Sonamu.appRootPath}/${target}/src/services/${entity.names.fs}`,
|
|
47
|
+
]),
|
|
51
48
|
];
|
|
52
49
|
}
|
|
53
50
|
})(); // iife
|
|
54
51
|
|
|
55
52
|
for await (const delPath of delPaths) {
|
|
56
53
|
if (await exists(delPath)) {
|
|
57
|
-
console.log(chalk.red(`DELETE ${delPath}`));
|
|
54
|
+
!isTest() && console.log(chalk.red(`DELETE ${delPath}`));
|
|
58
55
|
await rm(delPath, { recursive: true, force: true });
|
|
59
56
|
} else {
|
|
60
|
-
console.log(chalk.yellow(`NOT_EXISTS ${delPath}`));
|
|
57
|
+
!isTest() && console.log(chalk.yellow(`NOT_EXISTS ${delPath}`));
|
|
61
58
|
}
|
|
62
59
|
}
|
|
63
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { Sonamu } from "../api/sonamu";
|
|
3
|
-
import { AbsolutePath, ApiRelativePath } from "../utils/path-utils";
|
|
3
|
+
import type { AbsolutePath, ApiRelativePath } from "../utils/path-utils";
|
|
4
4
|
|
|
5
5
|
export type FileType =
|
|
6
6
|
| "model"
|
|
@@ -51,6 +51,6 @@ export function getChecksumPatternGroupInAbsolutePath(): GlobPattern<AbsolutePat
|
|
|
51
51
|
Object.entries(checksumPatternGroup).map(([key, value]) => [
|
|
52
52
|
key,
|
|
53
53
|
path.join(Sonamu.apiRootPath, value), // API 상대 경로 → 절대 경로
|
|
54
|
-
])
|
|
54
|
+
]),
|
|
55
55
|
) as GlobPattern<AbsolutePath>;
|
|
56
56
|
}
|
package/src/syncer/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./api-parser";
|
|
2
|
+
export * from "./checksum";
|
|
2
3
|
export * from "./code-generator";
|
|
3
|
-
export * from "./module-loader";
|
|
4
4
|
export * from "./entity-operations";
|
|
5
5
|
export * from "./file-patterns";
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./
|
|
6
|
+
export * from "./module-loader";
|
|
7
|
+
export * from "./syncer";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import { globAsync } from "../utils/async-utils";
|
|
3
|
-
import { importMembers } from "../utils/esm-utils";
|
|
4
2
|
import { z } from "zod";
|
|
3
|
+
import type { BaseFrameClass } from "../api/base-frame";
|
|
4
|
+
import type { ApiDecoratorOptions } from "../api/decorators";
|
|
5
5
|
import { Sonamu } from "../api/sonamu";
|
|
6
|
+
import type { BaseModelClass } from "../database/base-model";
|
|
7
|
+
import type { ApiParam, ApiParamType } from "../types/types";
|
|
8
|
+
import { globAsync } from "../utils/async-utils";
|
|
9
|
+
import { importMembers } from "../utils/esm-utils";
|
|
10
|
+
import { type AbsolutePath, runtimePath } from "../utils/path-utils";
|
|
6
11
|
import { readApisFromFile } from "./api-parser";
|
|
7
|
-
import { BaseFrameClass } from "../api/base-frame";
|
|
8
|
-
import { BaseModelClass } from "../database/base-model";
|
|
9
|
-
import { AbsolutePath, runtimePath } from "../utils/path-utils";
|
|
10
|
-
import { ApiParam, ApiParamType } from "../types/types";
|
|
11
|
-
import { ApiDecoratorOptions } from "../api/decorators";
|
|
12
12
|
|
|
13
13
|
export type LoadedApis = {
|
|
14
14
|
typeParameters: ApiParamType.TypeParam[];
|
|
@@ -20,6 +20,7 @@ export type LoadedApis = {
|
|
|
20
20
|
options: ApiDecoratorOptions;
|
|
21
21
|
}[];
|
|
22
22
|
|
|
23
|
+
// biome-ignore lint/suspicious/noExplicitAny: zod 스키마를 로드할 때 사용하는 타입
|
|
23
24
|
export type LoadedTypes = { [typeName: string]: z.ZodObject<any> };
|
|
24
25
|
|
|
25
26
|
export type LoadedModels = {
|
|
@@ -38,21 +39,29 @@ export async function loadApis(): Promise<LoadedApis> {
|
|
|
38
39
|
// 모델들의 .ts 파일이 있어야 이를 읽어서 라우트를 등록할 수 있어요!
|
|
39
40
|
const modelPathsPattern = path.join(
|
|
40
41
|
Sonamu.apiRootPath,
|
|
41
|
-
"src/application/**/*.{model,frame}.ts" // !! runtimePath 안 씀 주의 !!
|
|
42
|
+
"src/application/**/*.{model,frame}.ts", // !! runtimePath 안 씀 주의 !!
|
|
42
43
|
);
|
|
43
44
|
const modelPaths = (await globAsync(modelPathsPattern)) as AbsolutePath[];
|
|
44
45
|
|
|
45
46
|
const apis: LoadedApis = [];
|
|
46
|
-
let count = 0;
|
|
47
47
|
for (const filePath of modelPaths) {
|
|
48
48
|
const parsedApis = await readApisFromFile(filePath);
|
|
49
49
|
apis.push(...parsedApis);
|
|
50
|
-
count++;
|
|
51
50
|
}
|
|
52
51
|
// console.log(
|
|
53
52
|
// chalk.gray(`[Loading] Loaded APIs from "*.model.ts" files: ${count} files.`)
|
|
54
53
|
// );
|
|
55
54
|
|
|
55
|
+
for (const api of apis) {
|
|
56
|
+
if (api.path === "") {
|
|
57
|
+
// api의 경로(path)가 "텅 비어있음"인 상태입니다.
|
|
58
|
+
// 이는 @api와 함께 사용해야 하는 데코레이터(가령 @upload)가 @api 없이 붙은 상황입니다.
|
|
59
|
+
throw new Error(
|
|
60
|
+
`API ${api.modelName}.${api.methodName} has no path. Please attach @api decorator to the method.`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
return apis;
|
|
57
66
|
}
|
|
58
67
|
|
|
@@ -62,23 +71,21 @@ export async function loadApis(): Promise<LoadedApis> {
|
|
|
62
71
|
export async function loadModels(): Promise<LoadedModels> {
|
|
63
72
|
const modelPathsPattern = path.join(
|
|
64
73
|
Sonamu.apiRootPath,
|
|
65
|
-
runtimePath("src/application/**/*.{model,frame}.ts")
|
|
74
|
+
runtimePath("src/application/**/*.{model,frame}.ts"),
|
|
66
75
|
);
|
|
67
76
|
const modelPaths = await globAsync(modelPathsPattern);
|
|
68
77
|
|
|
69
78
|
const models: LoadedModels = {};
|
|
70
|
-
let
|
|
79
|
+
let _count = 0;
|
|
71
80
|
for (const filePath of modelPaths) {
|
|
72
|
-
const importedMembers = await importMembers<
|
|
73
|
-
BaseModelClass | BaseFrameClass
|
|
74
|
-
>(filePath);
|
|
81
|
+
const importedMembers = await importMembers<BaseModelClass | BaseFrameClass>(filePath);
|
|
75
82
|
|
|
76
83
|
for (const { name, value } of importedMembers) {
|
|
77
84
|
if (name.endsWith("Model") || name.endsWith("Frame")) {
|
|
78
85
|
models[name] = value;
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
|
-
|
|
88
|
+
_count++;
|
|
82
89
|
}
|
|
83
90
|
// console.log(
|
|
84
91
|
// chalk.gray(
|
|
@@ -95,25 +102,21 @@ export async function loadModels(): Promise<LoadedModels> {
|
|
|
95
102
|
export async function loadTypes(): Promise<LoadedTypes> {
|
|
96
103
|
const typePathsPatterns = [
|
|
97
104
|
path.join(Sonamu.apiRootPath, runtimePath("src/application/**/*.types.ts")),
|
|
98
|
-
path.join(
|
|
99
|
-
Sonamu.apiRootPath,
|
|
100
|
-
runtimePath("src/application/**/*.generated.ts")
|
|
101
|
-
),
|
|
105
|
+
path.join(Sonamu.apiRootPath, runtimePath("src/application/**/*.generated.ts")),
|
|
102
106
|
];
|
|
103
|
-
const typePaths = (
|
|
104
|
-
await Promise.all(typePathsPatterns.map(globAsync))
|
|
105
|
-
).flat();
|
|
107
|
+
const typePaths = (await Promise.all(typePathsPatterns.map(globAsync))).flat();
|
|
106
108
|
|
|
107
109
|
const types: LoadedTypes = {};
|
|
108
|
-
let
|
|
110
|
+
let _count = 0;
|
|
109
111
|
for (const filePath of typePaths) {
|
|
112
|
+
// biome-ignore lint/suspicious/noExplicitAny: zod 스키마를 로드할 때 사용하는 타입
|
|
110
113
|
const importedMembers = await importMembers<z.ZodObject<any>>(filePath);
|
|
111
114
|
for (const { name, value } of importedMembers) {
|
|
112
115
|
if (value instanceof z.ZodObject) {
|
|
113
116
|
types[name] = value;
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
|
-
|
|
119
|
+
_count++;
|
|
117
120
|
}
|
|
118
121
|
// console.log(
|
|
119
122
|
// chalk.gray(
|