sonamu 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.swcrc.project-default +18 -0
- package/bin/cli.js +24 -0
- package/dist/ai/agents/agent.d.ts +11 -0
- package/dist/ai/agents/agent.d.ts.map +1 -0
- package/dist/ai/agents/agent.js +65 -0
- package/dist/ai/agents/index.d.ts +3 -0
- package/dist/ai/agents/index.d.ts.map +1 -0
- package/dist/ai/agents/index.js +4 -0
- package/dist/ai/agents/types.d.ts +43 -0
- package/dist/ai/agents/types.d.ts.map +1 -0
- package/dist/ai/agents/types.js +3 -0
- package/dist/ai/index.d.ts +2 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +3 -0
- package/dist/ai/providers/rtzr/api.d.ts +22 -0
- package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/api.js +28 -0
- package/dist/ai/providers/rtzr/error.d.ts +18 -0
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/error.js +29 -0
- package/dist/ai/providers/rtzr/index.d.ts +5 -0
- package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/index.js +6 -0
- package/dist/ai/providers/rtzr/model.d.ts +52 -0
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/model.js +137 -0
- package/dist/ai/providers/rtzr/options.d.ts +7 -0
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/options.js +47 -0
- package/dist/ai/providers/rtzr/provider.d.ts +18 -0
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/provider.js +54 -0
- package/dist/ai/providers/rtzr/utils.d.ts +19 -0
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/utils.js +88 -0
- package/dist/api/base-frame.d.ts +2 -2
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/base-frame.js +2 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +6 -1
- package/dist/api/code-converters.d.ts +58 -14
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +178 -409
- package/dist/api/config.d.ts +27 -13
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +19 -26
- package/dist/api/context.d.ts +4 -3
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts +20 -6
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +111 -18
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +3 -3
- package/dist/api/sonamu.d.ts +7 -7
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +83 -51
- package/dist/api/validator.d.ts +6 -0
- package/dist/api/validator.d.ts.map +1 -0
- package/dist/api/validator.js +81 -0
- package/dist/bin/build-config.d.ts +5 -1
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +5 -2
- package/dist/bin/cli.js +165 -64
- package/dist/bin/loader-register.d.ts +2 -0
- package/dist/bin/loader-register.d.ts.map +1 -0
- package/dist/bin/loader-register.js +34 -0
- package/dist/database/_batch_update.d.ts +5 -3
- package/dist/database/_batch_update.d.ts.map +1 -1
- package/dist/database/_batch_update.js +30 -13
- package/dist/database/base-model.d.ts +96 -10
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +232 -89
- package/dist/database/base-model.types.d.ts +93 -0
- package/dist/database/base-model.types.d.ts.map +1 -0
- package/dist/database/base-model.types.js +10 -0
- package/dist/database/code-generator.d.ts +1 -1
- package/dist/database/code-generator.d.ts.map +1 -1
- package/dist/database/code-generator.js +11 -10
- package/dist/database/db.d.ts +5 -6
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +22 -25
- package/dist/database/puri-subset.test-d.js +81 -0
- package/dist/database/puri-subset.types.d.ts +123 -0
- package/dist/database/puri-subset.types.d.ts.map +1 -0
- package/dist/database/puri-subset.types.js +16 -0
- package/dist/database/puri-wrapper.d.ts +13 -11
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +2 -2
- package/dist/database/puri.d.ts +25 -14
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +83 -21
- package/dist/database/puri.types.d.ts +21 -7
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +4 -1
- package/dist/database/transaction-context.d.ts +1 -1
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js +1 -1
- package/dist/database/upsert-builder.d.ts +9 -3
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +228 -78
- package/dist/entity/entity-manager.d.ts +165 -2
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +26 -10
- package/dist/entity/entity.d.ts +5 -3
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +153 -54
- package/dist/exceptions/error-handler.d.ts +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +1 -1
- package/dist/exceptions/so-exceptions.d.ts +1 -1
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +1 -1
- package/dist/file-storage/driver.d.ts +1 -1
- package/dist/file-storage/driver.d.ts.map +1 -1
- package/dist/file-storage/driver.js +1 -1
- package/dist/file-storage/file-storage.js +2 -2
- package/dist/index.d.ts +18 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -13
- package/dist/migration/code-generation.d.ts +1 -1
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +123 -67
- package/dist/migration/migration-set.d.ts +2 -10
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +67 -218
- package/dist/migration/migrator.d.ts +24 -73
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +121 -301
- package/dist/migration/postgresql-schema-reader.d.ts +51 -0
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
- package/dist/migration/postgresql-schema-reader.js +245 -0
- package/dist/migration/types.d.ts +6 -38
- package/dist/migration/types.d.ts.map +1 -1
- package/dist/migration/types.js +1 -1
- package/dist/naite/messaging-types.d.ts +43 -0
- package/dist/naite/messaging-types.d.ts.map +1 -0
- package/dist/naite/messaging-types.js +7 -0
- package/dist/naite/naite-reporter.d.ts +41 -0
- package/dist/naite/naite-reporter.d.ts.map +1 -0
- package/dist/naite/naite-reporter.js +102 -0
- package/dist/naite/naite.d.ts +91 -8
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +285 -41
- package/dist/stream/sse.d.ts +2 -2
- package/dist/stream/sse.d.ts.map +1 -1
- package/dist/stream/sse.js +1 -1
- package/dist/syncer/api-parser.d.ts +3 -13
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +67 -56
- package/dist/syncer/checksum.d.ts +2 -2
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +11 -11
- package/dist/syncer/code-generator.d.ts +3 -3
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +37 -17
- package/dist/syncer/entity-operations.d.ts +2 -2
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +9 -8
- package/dist/syncer/file-patterns.d.ts +1 -1
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +1 -1
- package/dist/syncer/index.d.ts +4 -4
- package/dist/syncer/index.d.ts.map +1 -1
- package/dist/syncer/index.js +5 -5
- package/dist/syncer/module-loader.d.ts +4 -4
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +17 -12
- package/dist/syncer/syncer.d.ts +31 -24
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +92 -45
- package/dist/template/entity-converter.d.ts +1 -1
- package/dist/template/entity-converter.d.ts.map +1 -1
- package/dist/template/entity-converter.js +15 -8
- package/dist/template/helpers.d.ts +2 -2
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +3 -3
- package/dist/template/implementations/entity.template.d.ts +2 -2
- package/dist/template/implementations/entity.template.d.ts.map +1 -1
- package/dist/template/implementations/entity.template.js +4 -5
- package/dist/template/implementations/generated.template.d.ts +2 -3
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +46 -29
- package/dist/template/implementations/generated_http.template.d.ts +2 -3
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +9 -9
- package/dist/template/implementations/generated_sso.template.d.ts +3 -4
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +54 -25
- package/dist/template/implementations/init_types.template.d.ts +2 -2
- package/dist/template/implementations/init_types.template.d.ts.map +1 -1
- package/dist/template/implementations/init_types.template.js +2 -2
- package/dist/template/implementations/model.template.d.ts +2 -2
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +47 -37
- package/dist/template/implementations/model_test.template.d.ts +2 -2
- package/dist/template/implementations/model_test.template.d.ts.map +1 -1
- package/dist/template/implementations/model_test.template.js +2 -2
- package/dist/template/implementations/service.template.d.ts +4 -4
- package/dist/template/implementations/service.template.d.ts.map +1 -1
- package/dist/template/implementations/service.template.js +24 -16
- package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
- package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
- package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
- package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_select.template.js +2 -2
- package/dist/template/implementations/view_form.template.d.ts +2 -2
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +4 -4
- package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_all_select.template.js +1 -1
- package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
- package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_async_select.template.js +1 -1
- package/dist/template/implementations/view_list.template.d.ts +2 -2
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +29 -19
- package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
- package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list_columns.template.js +1 -1
- package/dist/template/implementations/view_search_input.template.d.ts +2 -2
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.js +1 -1
- package/dist/template/index.d.ts +4 -2
- package/dist/template/index.d.ts.map +1 -1
- package/dist/template/index.js +5 -3
- package/dist/template/template-manager.d.ts +56 -0
- package/dist/template/template-manager.d.ts.map +1 -0
- package/dist/template/template-manager.js +125 -0
- package/dist/template/template-types.d.ts +16 -0
- package/dist/template/template-types.d.ts.map +1 -0
- package/dist/template/template-types.js +7 -0
- package/dist/template/template.d.ts +12 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +19 -6
- package/dist/template/zod-converter.d.ts +40 -7
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +341 -58
- package/dist/testing/_relation-graph.d.ts +1 -1
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +12 -3
- package/dist/testing/fixture-manager.d.ts +42 -11
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +338 -236
- package/dist/types/types.d.ts +709 -104
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +309 -52
- package/dist/typings/knex.d.js +2 -2
- package/dist/utils/async-utils.d.ts.map +1 -1
- package/dist/utils/async-utils.js +3 -3
- package/dist/utils/console-util.js +1 -1
- package/dist/utils/controller.d.ts +1 -0
- package/dist/utils/controller.d.ts.map +1 -1
- package/dist/utils/controller.js +4 -1
- package/dist/utils/esm-utils.d.ts +0 -6
- package/dist/utils/esm-utils.d.ts.map +1 -1
- package/dist/utils/esm-utils.js +2 -9
- package/dist/utils/formatter.d.ts +3 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +110 -0
- package/dist/utils/fs-utils.d.ts +1 -1
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +1 -1
- package/dist/utils/lodash-able.d.ts.map +1 -1
- package/dist/utils/lodash-able.js +1 -1
- package/dist/utils/object-utils.d.ts +44 -0
- package/dist/utils/object-utils.d.ts.map +1 -0
- package/dist/utils/object-utils.js +191 -0
- package/dist/utils/path-utils.d.ts +1 -1
- package/dist/utils/path-utils.d.ts.map +1 -1
- package/dist/utils/path-utils.js +3 -3
- package/dist/utils/process-utils.js +1 -1
- package/dist/utils/sql-parser.d.ts +5 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +14 -3
- package/dist/utils/type-utils.d.ts +23 -0
- package/dist/utils/type-utils.d.ts.map +1 -0
- package/dist/utils/type-utils.js +45 -0
- package/dist/utils/utils.d.ts +7 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +44 -5
- package/dist/utils/zod-error.d.ts +1 -1
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +1 -1
- package/package.json +54 -29
- package/src/ai/agents/agent.ts +87 -0
- package/src/ai/agents/index.ts +2 -0
- package/src/ai/agents/types.ts +47 -0
- package/src/ai/index.ts +1 -0
- package/src/ai/providers/rtzr/api.ts +37 -0
- package/src/ai/providers/rtzr/error.ts +34 -0
- package/src/ai/providers/rtzr/index.ts +4 -0
- package/src/ai/providers/rtzr/model.ts +201 -0
- package/src/ai/providers/rtzr/options.ts +49 -0
- package/src/ai/providers/rtzr/provider.ts +91 -0
- package/src/ai/providers/rtzr/utils.ts +127 -0
- package/src/api/base-frame.ts +4 -2
- package/src/api/caster.ts +17 -23
- package/src/api/code-converters.ts +176 -533
- package/src/api/config.ts +39 -56
- package/src/api/context.ts +7 -18
- package/src/api/decorators.ts +175 -46
- package/src/api/index.ts +2 -2
- package/src/api/sonamu.ts +133 -124
- package/src/api/validator.ts +83 -0
- package/src/bin/build-config.ts +7 -1
- package/src/bin/cli.ts +192 -110
- package/src/bin/loader-register.ts +38 -0
- package/src/database/_batch_update.ts +46 -31
- package/src/database/base-model.ts +390 -182
- package/src/database/base-model.types.ts +155 -0
- package/src/database/code-generator.ts +13 -32
- package/src/database/db.ts +36 -50
- package/src/database/puri-subset.test-d.ts +471 -0
- package/src/database/puri-subset.types.ts +195 -0
- package/src/database/puri-wrapper.ts +58 -67
- package/src/database/puri.ts +182 -126
- package/src/database/puri.types.ts +64 -31
- package/src/database/transaction-context.ts +1 -1
- package/src/database/upsert-builder.ts +262 -132
- package/src/entity/entity-manager.ts +36 -28
- package/src/entity/entity.ts +330 -249
- package/src/exceptions/error-handler.ts +3 -3
- package/src/exceptions/so-exceptions.ts +11 -11
- package/src/file-storage/driver.ts +5 -5
- package/src/file-storage/file-storage.ts +2 -2
- package/src/index.ts +18 -12
- package/src/migration/code-generation.ts +185 -172
- package/src/migration/migration-set.ts +80 -293
- package/src/migration/migrator.ts +182 -425
- package/src/migration/mysql-schema-reader.ts.txt +272 -0
- package/src/migration/postgresql-schema-reader.ts +310 -0
- package/src/migration/types.ts +6 -39
- package/src/naite/messaging-types.ts +51 -0
- package/src/naite/naite-reporter.ts +128 -0
- package/src/naite/naite.ts +378 -33
- package/src/shared/web.shared.ts.txt +20 -24
- package/src/stream/sse.ts +5 -5
- package/src/syncer/api-parser.ts +52 -69
- package/src/syncer/checksum.ts +25 -37
- package/src/syncer/code-generator.ts +58 -62
- package/src/syncer/entity-operations.ts +12 -15
- package/src/syncer/file-patterns.ts +2 -2
- package/src/syncer/index.ts +4 -4
- package/src/syncer/module-loader.ts +28 -25
- package/src/syncer/syncer.ts +155 -162
- package/src/template/entity-converter.ts +18 -27
- package/src/template/helpers.ts +8 -11
- package/src/template/implementations/entity.template.ts +6 -6
- package/src/template/implementations/generated.template.ts +99 -99
- package/src/template/implementations/generated_http.template.ts +21 -54
- package/src/template/implementations/generated_sso.template.ts +78 -65
- package/src/template/implementations/init_types.template.ts +4 -6
- package/src/template/implementations/model.template.ts +47 -38
- package/src/template/implementations/model_test.template.ts +3 -3
- package/src/template/implementations/service.template.ts +56 -80
- package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
- package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
- package/src/template/implementations/view_enums_select.template.ts +3 -3
- package/src/template/implementations/view_form.template.ts +34 -75
- package/src/template/implementations/view_id_all_select.template.ts +2 -2
- package/src/template/implementations/view_id_async_select.template.ts +9 -23
- package/src/template/implementations/view_list.template.ts +54 -95
- package/src/template/implementations/view_list_columns.template.ts +4 -10
- package/src/template/implementations/view_search_input.template.ts +2 -2
- package/src/template/index.ts +4 -2
- package/src/template/template-manager.ts +166 -0
- package/src/template/template-types.ts +16 -0
- package/src/template/template.ts +29 -10
- package/src/template/zod-converter.ts +407 -101
- package/src/testing/_relation-graph.ts +18 -11
- package/src/testing/fixture-manager.ts +468 -362
- package/src/types/types.ts +516 -248
- package/src/typings/knex.d.ts +7 -9
- package/src/utils/async-utils.ts +8 -12
- package/src/utils/console-util.ts +1 -1
- package/src/utils/controller.ts +3 -0
- package/src/utils/esm-utils.ts +8 -18
- package/src/utils/formatter.ts +109 -0
- package/src/utils/fs-utils.ts +1 -1
- package/src/utils/lodash-able.ts +1 -4
- package/src/utils/object-utils.ts +217 -0
- package/src/utils/path-utils.ts +3 -6
- package/src/utils/process-utils.ts +1 -1
- package/src/utils/sql-parser.ts +23 -5
- package/src/utils/type-utils.ts +83 -0
- package/src/utils/utils.ts +58 -9
- package/src/utils/zod-error.ts +3 -3
- package/dist/bin/cli-wrapper.d.ts +0 -3
- package/dist/bin/cli-wrapper.d.ts.map +0 -1
- package/dist/bin/cli-wrapper.js +0 -72
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -39
- package/dist/entity/entity-utils.d.ts +0 -61
- package/dist/entity/entity-utils.d.ts.map +0 -1
- package/dist/entity/entity-utils.js +0 -210
- package/src/bin/cli-wrapper.ts +0 -82
- package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
- package/src/entity/entity-utils.ts +0 -291
package/src/syncer/syncer.ts
CHANGED
|
@@ -1,40 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
3
|
-
import { exists } from "../utils/fs-utils";
|
|
4
|
-
import * as _ from "lodash-es";
|
|
5
|
-
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
6
|
-
import { GenerateOptions } from "../types/types";
|
|
7
|
-
import chalk from "chalk";
|
|
8
|
-
import { TemplateKey, TemplateOptions } from "../types/types";
|
|
9
|
-
import { Sonamu } from "../api/sonamu";
|
|
1
|
+
import { hot } from "@sonamu-kit/hot-hook";
|
|
10
2
|
import assert from "assert";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
11
5
|
import { minimatch } from "minimatch";
|
|
6
|
+
import path, { dirname } from "path";
|
|
7
|
+
import { group, unique } from "radashi";
|
|
8
|
+
import type { z } from "zod";
|
|
9
|
+
import { registeredApis } from "../api/decorators";
|
|
10
|
+
import { Sonamu } from "../api/sonamu";
|
|
11
|
+
import { EntityManager, type EntityNamesRecord } from "../entity/entity-manager";
|
|
12
|
+
import { Naite } from "../naite/naite";
|
|
13
|
+
import { TemplateManager } from "../template/template-manager";
|
|
14
|
+
import type { GenerateOptions, PathAndCode } from "../types/types";
|
|
15
|
+
import { TemplateKey, type TemplateOptions } from "../types/types";
|
|
12
16
|
import { mapAsync, reduceAsync } from "../utils/async-utils";
|
|
13
17
|
import { centerText } from "../utils/console-util";
|
|
18
|
+
import { isTest } from "../utils/controller";
|
|
19
|
+
import { exists } from "../utils/fs-utils";
|
|
20
|
+
import type { AbsolutePath } from "../utils/path-utils";
|
|
14
21
|
import { runWithGracefulShutdown } from "../utils/process-utils";
|
|
15
|
-
import {
|
|
22
|
+
import { areFilesSame, findChangedFilesUsingChecksums, renewChecksums } from "./checksum";
|
|
16
23
|
import { generateTemplate, renderTemplate } from "./code-generator";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
FileType,
|
|
20
|
-
getChecksumPatternGroupInAbsolutePath,
|
|
21
|
-
} from "./file-patterns";
|
|
22
|
-
import {
|
|
23
|
-
findChangedFilesUsingChecksums,
|
|
24
|
-
renewChecksums,
|
|
25
|
-
areFilesSame,
|
|
26
|
-
} from "./checksum";
|
|
24
|
+
import { createEntity, delEntity } from "./entity-operations";
|
|
25
|
+
import { type FileType, getChecksumPatternGroupInAbsolutePath } from "./file-patterns";
|
|
27
26
|
import {
|
|
27
|
+
type LoadedApis,
|
|
28
|
+
type LoadedModels,
|
|
29
|
+
type LoadedTypes,
|
|
28
30
|
loadApis,
|
|
29
31
|
loadModels,
|
|
30
32
|
loadTypes,
|
|
31
|
-
LoadedApis,
|
|
32
|
-
LoadedModels,
|
|
33
|
-
LoadedTypes,
|
|
34
33
|
} from "./module-loader";
|
|
35
|
-
import { createEntity, delEntity } from "./entity-operations";
|
|
36
|
-
import { z } from "zod";
|
|
37
|
-
import { hot } from "@sonamu-kit/hot-hook";
|
|
38
34
|
|
|
39
35
|
type DiffGroups = {
|
|
40
36
|
[key in FileType]: AbsolutePath[];
|
|
@@ -74,7 +70,7 @@ export class Syncer {
|
|
|
74
70
|
// 싱크 액션이 끝나면 항상 체크섬을 다시 갱신합니다.
|
|
75
71
|
await renewChecksums();
|
|
76
72
|
},
|
|
77
|
-
{ whenThisHappens: "SIGUSR2", waitForUpTo: 20000 }
|
|
73
|
+
{ whenThisHappens: "SIGUSR2", waitForUpTo: 20000 },
|
|
78
74
|
);
|
|
79
75
|
}
|
|
80
76
|
|
|
@@ -84,10 +80,7 @@ export class Syncer {
|
|
|
84
80
|
* 체크섬 파일 업데이트는 여기에서 하지 않습니다. 호출자가 합니다.
|
|
85
81
|
* @param diffFilePath - 변경 파일들. 프로젝트 루트부터 "src/" 또는 "dist/"로 시작하는 상대 경로입니다. 예시: "src/application/user/user.model.ts"
|
|
86
82
|
*/
|
|
87
|
-
async syncFromWatcher(
|
|
88
|
-
event: string,
|
|
89
|
-
diffFilePath: AbsolutePath
|
|
90
|
-
): Promise<void> {
|
|
83
|
+
async syncFromWatcher(event: string, diffFilePath: AbsolutePath): Promise<void> {
|
|
91
84
|
if (event !== "change" && event !== "add" && event !== "unlink") {
|
|
92
85
|
return;
|
|
93
86
|
}
|
|
@@ -95,18 +88,33 @@ export class Syncer {
|
|
|
95
88
|
// 일단 변경된 파일과 dependent 파일들을 invalidate 합니다.
|
|
96
89
|
// 한 번 이상 import된 친구들에 대해서만 실제 작업이 일어납니다.
|
|
97
90
|
// 그러니 안심하고 invalidate 해도 됩니다.
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)
|
|
104
|
-
|
|
91
|
+
// 테스트 환경에서는 hot.invalidateFile시 초기 에러가 발생하기 때문에 invalidate 하지 않습니다.
|
|
92
|
+
if (!isTest()) {
|
|
93
|
+
const invalidatedPaths = (await hot.invalidateFile(diffFilePath, event)) as AbsolutePath[];
|
|
94
|
+
|
|
95
|
+
if (invalidatedPaths.length > 0) {
|
|
96
|
+
console.log(chalk.bold(`🔄 Invalidated:`));
|
|
97
|
+
|
|
98
|
+
for (const invalidatedPath of invalidatedPaths) {
|
|
99
|
+
// 만약 model.ts 파일이 변경(invalidate)되었다? 그러면 registeredApis 중에서 이 모델에 해당하는 api들은 지워줘요.
|
|
100
|
+
// registeredApis는 통으로 다 날려버릴 수 없습니다. registeredApis에 올라오는 친구들은 초기 로드시 또는 HMR시에만 등록되기 때문입니다.
|
|
101
|
+
// 따라서 model.ts 파일의 변경으로 다음번 새로운 eval이 예상되는 이 시점에서만, 이 모델에서 나온 registeredApis들을 지워줄 수 있습니다.
|
|
102
|
+
const removedApis = this.removeInvalidatedRegisteredApis(invalidatedPath);
|
|
103
|
+
if (removedApis.length > 0) {
|
|
104
|
+
console.log(
|
|
105
|
+
chalk.blue(`- ${path.relative(Sonamu.apiRootPath, invalidatedPath)}`),
|
|
106
|
+
chalk.gray(`(with ${removedApis.length} APIs)`),
|
|
107
|
+
);
|
|
108
|
+
} else {
|
|
109
|
+
console.log(chalk.blue(`- ${path.relative(Sonamu.apiRootPath, invalidatedPath)}`));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
const isInCheckPatternGroup = Object.values(
|
|
108
|
-
|
|
109
|
-
)
|
|
115
|
+
const isInCheckPatternGroup = Object.values(getChecksumPatternGroupInAbsolutePath()).some(
|
|
116
|
+
(pattern) => minimatch(diffFilePath, pattern),
|
|
117
|
+
);
|
|
110
118
|
|
|
111
119
|
// 할 일(sync)이 있으면 합니다.
|
|
112
120
|
if (isInCheckPatternGroup) {
|
|
@@ -122,25 +130,48 @@ export class Syncer {
|
|
|
122
130
|
this.syncUI();
|
|
123
131
|
}
|
|
124
132
|
|
|
125
|
-
|
|
133
|
+
removeInvalidatedRegisteredApis(
|
|
134
|
+
invalidatedPath: AbsolutePath,
|
|
135
|
+
): (typeof registeredApis)[number][] {
|
|
136
|
+
if (!invalidatedPath.endsWith(".model.ts" /*소스 코드를 다루는 상황이니 .ts 경로로 봅니다.*/)) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const entityId = EntityManager.getEntityIdFromPath(invalidatedPath);
|
|
141
|
+
const toRemove = registeredApis.filter((api) => api.modelName === `${entityId}Model`);
|
|
142
|
+
for (const api of toRemove) {
|
|
143
|
+
registeredApis.splice(registeredApis.indexOf(api), 1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return toRemove;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async copySharedToTargets(targets: string[]): Promise<void> {
|
|
126
150
|
for (const target of targets) {
|
|
127
151
|
// 지금 가져가려는 이 파일은 Sonamu 코드베이스의 일부입니다.
|
|
128
152
|
// 그런데 dist 속 빌드된 소스 코드 파일이 필요한 것이 아니고, src에만 있는 텍스트 파일이 필요합니다.
|
|
129
153
|
// 따라서 /src/에서 찾습니다.
|
|
130
154
|
const srcPath = path.join(
|
|
131
155
|
import.meta.dirname.replace("/dist/", "/src/"),
|
|
132
|
-
`../shared/${target}.shared.ts.txt
|
|
156
|
+
`../shared/${target}.shared.ts.txt`,
|
|
133
157
|
);
|
|
134
158
|
if (!(await exists(srcPath))) {
|
|
135
159
|
return;
|
|
136
160
|
}
|
|
161
|
+
if (!(await exists(path.join(Sonamu.appRootPath, target)))) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`Tried to copy sonamu.shared.ts to target '${target}' but the target directory does not exist. Please check your project directory structure.`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
137
166
|
|
|
138
167
|
// 이건 프로젝트에 .ts 소스 코드 파일을 생성하는 것이므로 src의 .ts 경로로 갑니다.
|
|
139
|
-
const destPath = path.join(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
168
|
+
const destPath = path.join(Sonamu.appRootPath, target, "./sonamu.shared.ts");
|
|
169
|
+
|
|
170
|
+
// 정말 혹시나지만 target 디렉토리는 있어도 src/services 디렉토리는 없을 수 있으므로 미리 생성해줍니다.
|
|
171
|
+
if (!(await exists(path.dirname(destPath)))) {
|
|
172
|
+
await mkdir(path.dirname(destPath), { recursive: true });
|
|
173
|
+
console.warn(`Created directory '${path.dirname(destPath)}' because it did not exist.`);
|
|
174
|
+
}
|
|
144
175
|
|
|
145
176
|
if (await areFilesSame(srcPath, destPath)) {
|
|
146
177
|
return;
|
|
@@ -148,10 +179,10 @@ export class Syncer {
|
|
|
148
179
|
|
|
149
180
|
await writeFile(destPath, await readFile(srcPath));
|
|
150
181
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
chalk.blue(path.relative(Sonamu.appRootPath, destPath))
|
|
154
|
-
|
|
182
|
+
!isTest() &&
|
|
183
|
+
console.log(
|
|
184
|
+
chalk.bold("Copied: ") + chalk.blue(path.relative(Sonamu.appRootPath, destPath)),
|
|
185
|
+
);
|
|
155
186
|
}
|
|
156
187
|
}
|
|
157
188
|
|
|
@@ -173,9 +204,7 @@ export class Syncer {
|
|
|
173
204
|
* @param diffFilePaths - 변경된 파일들의 절대 경로 목록
|
|
174
205
|
* @returns diffTypes - 변경된 파일의 타입 목록 (entity, types, model 등)
|
|
175
206
|
*/
|
|
176
|
-
|
|
177
|
-
diffFilePaths: AbsolutePath[]
|
|
178
|
-
): Promise<{ diffTypes: string[] }> {
|
|
207
|
+
async doSyncActions(diffFilePaths: AbsolutePath[]): Promise<{ diffTypes: string[] }> {
|
|
179
208
|
const diffGroups = this.calculateDiffGroups(diffFilePaths);
|
|
180
209
|
const diffTypes = Object.keys(diffGroups);
|
|
181
210
|
|
|
@@ -210,39 +239,28 @@ export class Syncer {
|
|
|
210
239
|
};
|
|
211
240
|
}
|
|
212
241
|
|
|
213
|
-
|
|
214
|
-
return
|
|
215
|
-
const matched = r.match(
|
|
216
|
-
/\.(model|types|functions|entity|generated|frame|config)\.[tj]s/
|
|
217
|
-
);
|
|
242
|
+
calculateDiffGroups(diffFiles: AbsolutePath[]): DiffGroups {
|
|
243
|
+
return group(diffFiles, (r) => {
|
|
244
|
+
const matched = r.match(/\.(model|types|functions|entity|generated|frame|config)\.[tj]s/);
|
|
218
245
|
return matched?.[1] ?? "unknown";
|
|
219
246
|
}) as unknown as DiffGroups;
|
|
220
247
|
}
|
|
221
248
|
|
|
222
|
-
|
|
223
|
-
diffGroups
|
|
224
|
-
diffTypes: string[]
|
|
225
|
-
): Promise<void> {
|
|
226
|
-
// console.log(
|
|
227
|
-
// chalk.gray(
|
|
228
|
-
// `[Processing] Handling entity changes: ${diffGroups["entity"]?.map((p) => path.relative(Sonamu.apiRootPath, p)).join(", ")}`
|
|
229
|
-
// )
|
|
230
|
-
// );
|
|
249
|
+
async handleEntityChange(diffGroups: DiffGroups, diffTypes: string[]): Promise<void> {
|
|
250
|
+
Naite.t("handleEntityChange", { diffGroups, diffTypes });
|
|
231
251
|
|
|
232
252
|
await EntityManager.reload();
|
|
233
253
|
|
|
234
254
|
// types 생성(entity 새로 추가된 경우)
|
|
235
255
|
// parentId가 없고, types가 없는 경우에만 생성
|
|
236
|
-
const entityId = EntityManager.getEntityIdFromPath(
|
|
237
|
-
diffGroups["entity"]?.[0]
|
|
238
|
-
);
|
|
256
|
+
const entityId = EntityManager.getEntityIdFromPath(diffGroups.entity?.[0]);
|
|
239
257
|
|
|
240
258
|
if (entityId) {
|
|
241
259
|
const entity = EntityManager.get(entityId);
|
|
242
260
|
// 프로젝트에 생성되어야 하는 .ts 파일의 경로입니다.
|
|
243
261
|
const typeFilePath = path.join(
|
|
244
262
|
Sonamu.apiRootPath,
|
|
245
|
-
`src/application/${entity.names.fs}/${entity.names.fs}.types.ts
|
|
263
|
+
`src/application/${entity.names.fs}/${entity.names.fs}.types.ts`,
|
|
246
264
|
);
|
|
247
265
|
if (entity.parentId === undefined && !(await exists(typeFilePath))) {
|
|
248
266
|
await generateTemplate("init_types", { entityId });
|
|
@@ -251,24 +269,20 @@ export class Syncer {
|
|
|
251
269
|
|
|
252
270
|
await this.actionGenerateSchemas();
|
|
253
271
|
|
|
254
|
-
diffGroups
|
|
255
|
-
...(diffGroups
|
|
256
|
-
path.join(
|
|
257
|
-
Sonamu.apiRootPath,
|
|
258
|
-
"src/application/sonamu.generated.ts"
|
|
259
|
-
) as AbsolutePath,
|
|
272
|
+
diffGroups.generated = unique([
|
|
273
|
+
...(diffGroups.generated ?? []),
|
|
274
|
+
path.join(Sonamu.apiRootPath, "src/application/sonamu.generated.ts") as AbsolutePath,
|
|
260
275
|
]);
|
|
261
276
|
diffTypes.push("generated");
|
|
262
277
|
}
|
|
263
278
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
...(diffGroups
|
|
269
|
-
...(diffGroups["functions"] ?? []),
|
|
270
|
-
...(diffGroups["generated"] ?? []),
|
|
279
|
+
async handleTypesOrFunctionsOrGeneratedChange(diffGroups: DiffGroups): Promise<FileType[]> {
|
|
280
|
+
const tsPaths = unique([
|
|
281
|
+
...(diffGroups.types ?? []),
|
|
282
|
+
...(diffGroups.functions ?? []),
|
|
283
|
+
...(diffGroups.generated ?? []),
|
|
271
284
|
]);
|
|
285
|
+
Naite.t("handleTypesOrFunctionsOrGeneratedChange", { diffGroups });
|
|
272
286
|
|
|
273
287
|
// console.log(
|
|
274
288
|
// chalk.gray(
|
|
@@ -281,13 +295,9 @@ export class Syncer {
|
|
|
281
295
|
return [];
|
|
282
296
|
}
|
|
283
297
|
|
|
284
|
-
|
|
285
|
-
diffGroups
|
|
286
|
-
|
|
287
|
-
const mergedGroup = [
|
|
288
|
-
...(diffGroups["model"] ?? []),
|
|
289
|
-
...(diffGroups["frame"] ?? []),
|
|
290
|
-
];
|
|
298
|
+
async handleModelOrFrameChange(diffGroups: DiffGroups): Promise<void> {
|
|
299
|
+
Naite.t("handleModelOrFrameChange", { diffGroups });
|
|
300
|
+
const mergedGroup = [...(diffGroups.model ?? []), ...(diffGroups.frame ?? [])];
|
|
291
301
|
|
|
292
302
|
// console.log(
|
|
293
303
|
// chalk.gray(
|
|
@@ -330,13 +340,11 @@ export class Syncer {
|
|
|
330
340
|
const { host, port } = Sonamu.config.server.listen ?? {};
|
|
331
341
|
const content = `API_HOST=${host ?? "localhost"}\nAPI_PORT=${port ?? 3000}`;
|
|
332
342
|
|
|
343
|
+
Naite.t("actionSyncConfig", { content });
|
|
333
344
|
await Promise.all(
|
|
334
345
|
Sonamu.config.sync.targets.map(async (target) => {
|
|
335
|
-
await writeFile(
|
|
336
|
-
|
|
337
|
-
content
|
|
338
|
-
);
|
|
339
|
-
})
|
|
346
|
+
await writeFile(path.join(Sonamu.appRootPath, target, ".sonamu.env"), content);
|
|
347
|
+
}),
|
|
340
348
|
);
|
|
341
349
|
}
|
|
342
350
|
|
|
@@ -344,7 +352,7 @@ export class Syncer {
|
|
|
344
352
|
* sonamu.generated.ts와 sonamu.generated.sso.ts를 생성합니다.
|
|
345
353
|
* @returns 생성된 파일 경로 배열.
|
|
346
354
|
*/
|
|
347
|
-
|
|
355
|
+
async actionGenerateSchemas(): Promise<AbsolutePath[]> {
|
|
348
356
|
return (
|
|
349
357
|
await Promise.all([
|
|
350
358
|
generateTemplate("generated_sso", {}, { overwrite: true }),
|
|
@@ -360,18 +368,19 @@ export class Syncer {
|
|
|
360
368
|
* @param paramsArray
|
|
361
369
|
* @returns 생성된 파일 경로 배열.
|
|
362
370
|
*/
|
|
363
|
-
|
|
371
|
+
async actionGenerateServices(
|
|
364
372
|
paramsArray: {
|
|
365
373
|
namesRecord: EntityNamesRecord;
|
|
366
|
-
}[]
|
|
374
|
+
}[],
|
|
367
375
|
): Promise<string[]> {
|
|
376
|
+
Naite.t("actionGenerateServices", paramsArray);
|
|
368
377
|
return (
|
|
369
378
|
await Promise.all(
|
|
370
379
|
paramsArray.map(async (params) =>
|
|
371
|
-
generateTemplate("service", params, {
|
|
380
|
+
generateTemplate("service", params as TemplateOptions["service"], {
|
|
372
381
|
overwrite: true,
|
|
373
|
-
})
|
|
374
|
-
)
|
|
382
|
+
}),
|
|
383
|
+
),
|
|
375
384
|
)
|
|
376
385
|
)
|
|
377
386
|
.flat()
|
|
@@ -382,11 +391,11 @@ export class Syncer {
|
|
|
382
391
|
* sonamu.generated.http를 생성합니다.
|
|
383
392
|
* @returns 생성된 파일 경로.
|
|
384
393
|
*/
|
|
385
|
-
|
|
394
|
+
async actionGenerateHttps(): Promise<AbsolutePath> {
|
|
386
395
|
const [res] = await generateTemplate(
|
|
387
396
|
"generated_http",
|
|
388
|
-
{},
|
|
389
|
-
{ overwrite: true }
|
|
397
|
+
{ entityId: "dummy" },
|
|
398
|
+
{ overwrite: true },
|
|
390
399
|
);
|
|
391
400
|
assert(res);
|
|
392
401
|
return res;
|
|
@@ -397,9 +406,7 @@ export class Syncer {
|
|
|
397
406
|
* @param tsPaths
|
|
398
407
|
* @returns 복사된 파일 경로 배열.
|
|
399
408
|
*/
|
|
400
|
-
|
|
401
|
-
tsPaths: AbsolutePath[]
|
|
402
|
-
): Promise<string[]> {
|
|
409
|
+
async actionSyncFilesToTargets(tsPaths: AbsolutePath[]): Promise<string[]> {
|
|
403
410
|
const { targets } = Sonamu.config.sync;
|
|
404
411
|
const { dir: apiDir } = Sonamu.config.api;
|
|
405
412
|
|
|
@@ -415,23 +422,20 @@ export class Syncer {
|
|
|
415
422
|
if (!(await exists(dir))) {
|
|
416
423
|
await mkdir(dir, { recursive: true });
|
|
417
424
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
chalk.blue(dst.replace(Sonamu.appRootPath
|
|
421
|
-
|
|
425
|
+
!isTest() &&
|
|
426
|
+
console.log(
|
|
427
|
+
chalk.bold("Copied: ") + chalk.blue(dst.replace(`${Sonamu.appRootPath}/`, "")),
|
|
428
|
+
);
|
|
422
429
|
await this.copyFileWithReplaceCoreToShared(realSrc, dst);
|
|
423
430
|
return dst;
|
|
424
|
-
})
|
|
425
|
-
)
|
|
426
|
-
)
|
|
431
|
+
}),
|
|
432
|
+
),
|
|
433
|
+
),
|
|
427
434
|
)
|
|
428
435
|
).flat();
|
|
429
436
|
}
|
|
430
437
|
|
|
431
|
-
private async copyFileWithReplaceCoreToShared(
|
|
432
|
-
fromPath: string,
|
|
433
|
-
toPath: string
|
|
434
|
-
) {
|
|
438
|
+
private async copyFileWithReplaceCoreToShared(fromPath: string, toPath: string) {
|
|
435
439
|
if (!(await exists(fromPath))) {
|
|
436
440
|
return;
|
|
437
441
|
}
|
|
@@ -439,16 +443,8 @@ export class Syncer {
|
|
|
439
443
|
const oldFileContent = (await readFile(fromPath)).toString();
|
|
440
444
|
|
|
441
445
|
const newFileContent = (() => {
|
|
442
|
-
const nfc = oldFileContent.replace(
|
|
443
|
-
|
|
444
|
-
`from "src/services/sonamu.shared"`
|
|
445
|
-
);
|
|
446
|
-
|
|
447
|
-
if (toPath.includes("/web/")) {
|
|
448
|
-
return nfc; // .replace(/from "lodash";/g, `from "lodash-es";`); // TODO 흠? 필요없을듯.
|
|
449
|
-
} else {
|
|
450
|
-
return nfc;
|
|
451
|
-
}
|
|
446
|
+
const nfc = oldFileContent.replace(/from "sonamu"/g, `from "./sonamu.shared"`);
|
|
447
|
+
return nfc;
|
|
452
448
|
})();
|
|
453
449
|
return writeFile(toPath, newFileContent);
|
|
454
450
|
}
|
|
@@ -463,11 +459,12 @@ export class Syncer {
|
|
|
463
459
|
async checkExistsGenCode(
|
|
464
460
|
entityId: string,
|
|
465
461
|
templateKey: TemplateKey,
|
|
466
|
-
enumId?: string
|
|
462
|
+
enumId?: string,
|
|
467
463
|
): Promise<{ subPath: string; fullPath: string; isExists: boolean }> {
|
|
468
|
-
const { target, path: genPath } =
|
|
469
|
-
|
|
470
|
-
|
|
464
|
+
const { target, path: genPath } = TemplateManager.get(templateKey).getTargetAndPath(
|
|
465
|
+
EntityManager.getNamesFromId(entityId),
|
|
466
|
+
enumId,
|
|
467
|
+
);
|
|
471
468
|
|
|
472
469
|
const subPath = path.join(target, genPath);
|
|
473
470
|
const fullPath = path.join(Sonamu.appRootPath, subPath);
|
|
@@ -487,27 +484,22 @@ export class Syncer {
|
|
|
487
484
|
async checkExists(
|
|
488
485
|
entityId: string,
|
|
489
486
|
enums: {
|
|
490
|
-
[name: string]: z.ZodEnum<
|
|
491
|
-
}
|
|
487
|
+
[name: string]: z.ZodEnum<Readonly<Record<string, string | number>>>;
|
|
488
|
+
},
|
|
492
489
|
): Promise<Record<`${TemplateKey}${string}`, boolean>> {
|
|
493
490
|
const keys: TemplateKey[] = TemplateKey.options;
|
|
494
491
|
const names = EntityManager.getNamesFromId(entityId);
|
|
495
|
-
const enumsKeys = Object.keys(enums).filter(
|
|
496
|
-
(name) => name !== names.constant
|
|
497
|
-
);
|
|
492
|
+
const enumsKeys = Object.keys(enums).filter((name) => name !== names.constant);
|
|
498
493
|
|
|
499
494
|
return await reduceAsync(
|
|
500
495
|
keys,
|
|
501
496
|
async (result, key) => {
|
|
502
|
-
const tpl =
|
|
497
|
+
const tpl = TemplateManager.get(key);
|
|
503
498
|
if (key.startsWith("view_enums")) {
|
|
504
499
|
await mapAsync(enumsKeys, async (componentId) => {
|
|
505
|
-
const { target, path: p } = tpl.getTargetAndPath(
|
|
506
|
-
names,
|
|
507
|
-
componentId
|
|
508
|
-
);
|
|
500
|
+
const { target, path: p } = tpl.getTargetAndPath(names, componentId);
|
|
509
501
|
result[`${key}__${componentId}`] = await exists(
|
|
510
|
-
path.join(Sonamu.appRootPath, target, p)
|
|
502
|
+
path.join(Sonamu.appRootPath, target, p),
|
|
511
503
|
);
|
|
512
504
|
});
|
|
513
505
|
return result;
|
|
@@ -518,7 +510,7 @@ export class Syncer {
|
|
|
518
510
|
if (target.includes(":target")) {
|
|
519
511
|
await mapAsync(targets, async (t) => {
|
|
520
512
|
result[`${key}__${t}`] = await exists(
|
|
521
|
-
path.join(Sonamu.appRootPath, target.replace(":target", t), p)
|
|
513
|
+
path.join(Sonamu.appRootPath, target.replace(":target", t), p),
|
|
522
514
|
);
|
|
523
515
|
});
|
|
524
516
|
} else {
|
|
@@ -527,26 +519,24 @@ export class Syncer {
|
|
|
527
519
|
|
|
528
520
|
return result;
|
|
529
521
|
},
|
|
530
|
-
{} as Record<`${TemplateKey}${string}`, boolean
|
|
522
|
+
{} as Record<`${TemplateKey}${string}`, boolean>,
|
|
531
523
|
);
|
|
532
524
|
}
|
|
533
525
|
|
|
534
526
|
syncUI() {
|
|
535
527
|
const uiPort = Sonamu.config.ui?.port ?? 57000;
|
|
536
528
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
console.log(chalk.dim(`Failed to reload Sonamu UI: ${e.message}`))
|
|
541
|
-
|
|
529
|
+
if (!isTest()) {
|
|
530
|
+
fetch(`http://127.0.0.1:${uiPort}/api/reload`, {
|
|
531
|
+
method: "GET",
|
|
532
|
+
}).catch((e) => console.log(chalk.dim(`Failed to reload Sonamu UI: ${e.message}`)));
|
|
533
|
+
}
|
|
542
534
|
}
|
|
543
535
|
|
|
544
536
|
/**
|
|
545
537
|
* 하위호환용 프록시 메소드입니다.
|
|
546
538
|
*/
|
|
547
|
-
async createEntity(
|
|
548
|
-
form: Omit<TemplateOptions["entity"], "title"> & { title?: string }
|
|
549
|
-
) {
|
|
539
|
+
async createEntity(form: TemplateOptions["entity"]) {
|
|
550
540
|
return await createEntity(form);
|
|
551
541
|
}
|
|
552
542
|
|
|
@@ -560,18 +550,21 @@ export class Syncer {
|
|
|
560
550
|
/**
|
|
561
551
|
* 하위호환용 프록시 메소드입니다.
|
|
562
552
|
*/
|
|
563
|
-
async generateTemplate(
|
|
564
|
-
key:
|
|
565
|
-
templateOptions:
|
|
566
|
-
_generateOptions?: GenerateOptions
|
|
567
|
-
) {
|
|
553
|
+
async generateTemplate<T extends TemplateKey>(
|
|
554
|
+
key: T,
|
|
555
|
+
templateOptions: TemplateOptions[T],
|
|
556
|
+
_generateOptions?: GenerateOptions,
|
|
557
|
+
): Promise<AbsolutePath[]> {
|
|
568
558
|
return await generateTemplate(key, templateOptions, _generateOptions);
|
|
569
559
|
}
|
|
570
560
|
|
|
571
561
|
/**
|
|
572
562
|
* 하위호환용 프록시 메소드입니다.
|
|
573
563
|
*/
|
|
574
|
-
async renderTemplate
|
|
564
|
+
async renderTemplate<T extends keyof TemplateOptions>(
|
|
565
|
+
key: T,
|
|
566
|
+
templateOptions: TemplateOptions[T],
|
|
567
|
+
): Promise<PathAndCode[]> {
|
|
575
568
|
return await renderTemplate(key, templateOptions);
|
|
576
569
|
}
|
|
577
570
|
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
+
import assert from "assert";
|
|
1
2
|
import z from "zod";
|
|
2
3
|
import { EntityManager } from "../entity/entity-manager";
|
|
3
4
|
import { ServiceUnavailableException } from "../exceptions/so-exceptions";
|
|
4
|
-
import { EntityPropNode, RenderingNode } from "../types/types";
|
|
5
|
-
import {
|
|
5
|
+
import type { EntityPropNode, RenderingNode } from "../types/types";
|
|
6
|
+
import { propToZodType, zodTypeToRenderingNode } from "./zod-converter";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* 엔티티의 특정 subset을 RenderingNode로 변환합니다.
|
|
9
10
|
* subset의 필드들을 Zod 타입으로 변환한 후 UI 렌더링용 노드로 만듭니다.
|
|
10
11
|
* object와 array의 경우 적절한 pick 필드를 자동으로 선택합니다.
|
|
11
12
|
*/
|
|
12
|
-
export async function getColumnsNode(
|
|
13
|
-
entityId: string,
|
|
14
|
-
subsetKey: string
|
|
15
|
-
): Promise<RenderingNode> {
|
|
13
|
+
export async function getColumnsNode(entityId: string, subsetKey: string): Promise<RenderingNode> {
|
|
16
14
|
const entity = EntityManager.get(entityId);
|
|
17
15
|
const subset = entity.subsets[subsetKey];
|
|
18
16
|
if (subset === undefined) {
|
|
@@ -24,16 +22,15 @@ export async function getColumnsNode(
|
|
|
24
22
|
children: propNodes,
|
|
25
23
|
};
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)) as z.ZodObject<any>;
|
|
25
|
+
// biome-ignore lint/suspicious/noExplicitAny: zod 스키마를 로드할 때 사용하는 타입
|
|
26
|
+
const columnsZodType = (await propNodeToZodType(rootPropNode)) as z.ZodObject<any>;
|
|
30
27
|
|
|
31
28
|
const columnsNode = zodTypeToRenderingNode(columnsZodType);
|
|
32
|
-
columnsNode.children
|
|
29
|
+
assert(columnsNode.children !== undefined, "columnsNode.children is undefined");
|
|
30
|
+
columnsNode.children = columnsNode.children.map((child) => {
|
|
33
31
|
if (child.renderType === "object") {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
);
|
|
32
|
+
assert(child.children !== undefined, "child.children is undefined");
|
|
33
|
+
const pickedCol = child.children.find((cc) => ["title", "name"].includes(cc.name));
|
|
37
34
|
if (pickedCol) {
|
|
38
35
|
return {
|
|
39
36
|
...child,
|
|
@@ -50,9 +47,7 @@ export async function getColumnsNode(
|
|
|
50
47
|
child.element &&
|
|
51
48
|
child.element.renderType === "object"
|
|
52
49
|
) {
|
|
53
|
-
const pickedCol = child.element
|
|
54
|
-
["title", "name"].includes(cc.name)
|
|
55
|
-
);
|
|
50
|
+
const pickedCol = child.element?.children?.find((cc) => ["title", "name"].includes(cc.name));
|
|
56
51
|
if (pickedCol) {
|
|
57
52
|
return {
|
|
58
53
|
...child,
|
|
@@ -78,9 +73,7 @@ export async function getColumnsNode(
|
|
|
78
73
|
* EntityPropNode를 Zod 타입으로 변환합니다.
|
|
79
74
|
* plain, array, object 세 가지 nodeType을 재귀적으로 처리합니다.
|
|
80
75
|
*/
|
|
81
|
-
export async function propNodeToZodType(
|
|
82
|
-
propNode: EntityPropNode
|
|
83
|
-
): Promise<z.ZodTypeAny> {
|
|
76
|
+
export async function propNodeToZodType(propNode: EntityPropNode): Promise<z.ZodTypeAny> {
|
|
84
77
|
if (propNode.nodeType === "plain") {
|
|
85
78
|
return propToZodType(propNode.prop);
|
|
86
79
|
} else if (propNode.nodeType === "array") {
|
|
@@ -102,15 +95,13 @@ export async function propNodeToZodType(
|
|
|
102
95
|
}
|
|
103
96
|
}
|
|
104
97
|
} else if (propNode.nodeType === "object") {
|
|
105
|
-
const
|
|
106
|
-
async (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return result;
|
|
111
|
-
},
|
|
112
|
-
{} as any
|
|
98
|
+
const entries = await Promise.all(
|
|
99
|
+
propNode.children.map(async (childPropNode) => {
|
|
100
|
+
assert(childPropNode.prop?.name !== undefined, "childPropNode.prop.name is undefined");
|
|
101
|
+
return [childPropNode.prop.name, await propNodeToZodType(childPropNode)] as const;
|
|
102
|
+
}),
|
|
113
103
|
);
|
|
104
|
+
const obj = Object.fromEntries(entries);
|
|
114
105
|
|
|
115
106
|
if (propNode.prop?.nullable === true) {
|
|
116
107
|
return z.object(obj).nullable();
|