sonamu 0.6.0 → 0.7.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.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 +227 -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 +386 -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 +55 -30
- 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 +261 -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 +459 -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/dist/naite/naite.d.ts
CHANGED
|
@@ -1,12 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: Naite는 expect와 호응하도록 any를 허용함 */
|
|
2
|
+
import type { ComparisonOperator } from "../database/puri.types";
|
|
3
|
+
interface StackFrame {
|
|
4
|
+
functionName: string | null;
|
|
5
|
+
filePath: string;
|
|
6
|
+
lineNumber: number;
|
|
7
|
+
}
|
|
8
|
+
interface NaiteTrace {
|
|
9
|
+
key: string;
|
|
10
|
+
data: any;
|
|
11
|
+
stack: StackFrame[];
|
|
12
|
+
at: Date;
|
|
13
|
+
}
|
|
14
|
+
export type NaiteStore = Map<string, NaiteTrace[]>;
|
|
15
|
+
/**
|
|
16
|
+
* NaiteQuery 클래스
|
|
17
|
+
* 체이닝을 통한 trace 필터링 및 조회
|
|
18
|
+
*/
|
|
19
|
+
export declare class NaiteQuery {
|
|
20
|
+
private traces;
|
|
21
|
+
constructor(traces: NaiteTrace[]);
|
|
22
|
+
/**
|
|
23
|
+
* 파일명으로 필터링
|
|
24
|
+
* @param fileName 파일명 (예: "syncer.test.ts")
|
|
25
|
+
*/
|
|
26
|
+
fromFile(fileName: string): NaiteQuery;
|
|
27
|
+
/**
|
|
28
|
+
* 함수명으로 필터링
|
|
29
|
+
* @param funcName 함수명 (includes 체크)
|
|
30
|
+
* @param options.from 'direct' = 직접 호출만, 'indirect' = 간접 호출만, 'both' = 모두
|
|
31
|
+
*/
|
|
32
|
+
fromFunction(funcName: string, options?: {
|
|
33
|
+
from: "direct" | "indirect" | "both";
|
|
34
|
+
}): NaiteQuery;
|
|
35
|
+
/**
|
|
36
|
+
* 데이터 경로 기반 필터링
|
|
37
|
+
* @param path radash get 경로 (예: "data.userId")
|
|
38
|
+
* @param operator 비교 연산자
|
|
39
|
+
* @param value 비교값
|
|
40
|
+
*/
|
|
41
|
+
where(path: string, operator: ComparisonOperator | "includes", value: any): NaiteQuery;
|
|
42
|
+
/**
|
|
43
|
+
* 전체 데이터 배열 반환
|
|
44
|
+
*/
|
|
45
|
+
result(): any[];
|
|
46
|
+
/**
|
|
47
|
+
* 첫 번째 데이터 반환
|
|
48
|
+
*/
|
|
49
|
+
first(): any | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* 마지막 데이터 반환
|
|
52
|
+
*/
|
|
53
|
+
last(): any | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* n번째 데이터 반환
|
|
56
|
+
*/
|
|
57
|
+
at(index: number): any | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* 원본 trace 배열 반환 (디버깅/NaiteViewer용)
|
|
60
|
+
*/
|
|
61
|
+
getTraces(): NaiteTrace[];
|
|
62
|
+
}
|
|
63
|
+
export declare class NaiteClass {
|
|
64
|
+
t(name: string, value: any): void;
|
|
65
|
+
/**
|
|
66
|
+
* key 또는 wildcard 패턴으로 trace 조회
|
|
67
|
+
* 항상 NaiteQuery 반환하여 체이닝 가능
|
|
68
|
+
*/
|
|
69
|
+
get(keyPattern: string): NaiteQuery;
|
|
70
|
+
getAll(): {
|
|
5
71
|
[key: string]: any;
|
|
6
72
|
};
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
73
|
+
/**
|
|
74
|
+
* 스토어에 들어있던 트레이스를 고대로 꺼내옵니다.
|
|
75
|
+
* 이때 값들은 모두 직렬화 가능한 상태로 나가게 됩니다.
|
|
76
|
+
* 테스트 정보와 함께 extensions에 보낼 용도로 만들었습니다.
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
getAllTraces(): {
|
|
80
|
+
key: string;
|
|
81
|
+
value: any;
|
|
82
|
+
filePath: string;
|
|
83
|
+
lineNumber: number;
|
|
84
|
+
at: string;
|
|
85
|
+
}[];
|
|
86
|
+
del(key: string): void;
|
|
87
|
+
createStore(): NaiteStore;
|
|
88
|
+
d(_message: string): void;
|
|
89
|
+
i(_message: string): void;
|
|
90
|
+
w(_message: string): void;
|
|
91
|
+
e(_message: string): void;
|
|
11
92
|
}
|
|
93
|
+
export declare const Naite: NaiteClass;
|
|
94
|
+
export {};
|
|
12
95
|
//# sourceMappingURL=naite.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"naite.d.ts","sourceRoot":"","sources":["../../src/naite/naite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"naite.d.ts","sourceRoot":"","sources":["../../src/naite/naite.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAIpF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAIjE,UAAU,UAAU;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,EAAE,EAAE,IAAI,CAAC;CACV;AAGD,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AAsGnD;;;GAGG;AACH,qBAAa,UAAU;IACT,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU,EAAE;IAExC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;IAOtC;;;;OAIG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAA;KAAqB,GACnE,UAAU;IAgBb;;;;;OAKG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,GAAG,UAAU,EAAE,KAAK,EAAE,GAAG,GAAG,UAAU;IA0BtF;;OAEG;IACH,MAAM,IAAI,GAAG,EAAE;IAIf;;OAEG;IACH,KAAK,IAAI,GAAG,GAAG,SAAS;IAIxB;;OAEG;IACH,IAAI,IAAI,GAAG,GAAG,SAAS;IAIvB;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAIlC;;OAEG;IACH,SAAS,IAAI,UAAU,EAAE;CAG1B;AAGD,qBAAa,UAAU;IAErB,CAAC,CACC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG;IAmCZ;;;OAGG;IACH,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;IA0BnC,MAAM,IAAI;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE;IAmBhC;;;;;OAKG;IACH,YAAY,IAAI;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,GAAG,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;KACZ,EAAE;IA+CH,GAAG,CAAC,GAAG,EAAE,MAAM;IAQf,WAAW,IAAI,UAAU;IAKzB,CAAC,CAAC,QAAQ,EAAE,MAAM;IAIlB,CAAC,CAAC,QAAQ,EAAE,MAAM;IAIlB,CAAC,CAAC,QAAQ,EAAE,MAAM;IAIlB,CAAC,CAAC,QAAQ,EAAE,MAAM;CAInB;AAED,eAAO,MAAM,KAAK,YAAmB,CAAC"}
|
package/dist/naite/naite.js
CHANGED
|
@@ -1,72 +1,316 @@
|
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: Naite는 expect와 호응하도록 any를 허용함 */ import { get } from "radashi";
|
|
1
2
|
import { Sonamu } from "../api/sonamu.js";
|
|
2
|
-
|
|
3
|
+
import { isSerializable } from "../utils/object-utils.js";
|
|
4
|
+
/**
|
|
5
|
+
* 콜스택을 파싱하여 StackFrame 배열로 반환
|
|
6
|
+
* - extractCallStack 자신과 Naite.t는 제외
|
|
7
|
+
* - runWithContext/runWithMockContext 발견 시 거기서 종료
|
|
8
|
+
* - node: 내부 경로는 포함하되, lineNumber는 path에 : 포함 시 붙이지 않음
|
|
9
|
+
*/ function extractCallStack() {
|
|
10
|
+
const stack = new Error().stack;
|
|
11
|
+
if (!stack) return [];
|
|
12
|
+
const lines = stack.split("\n");
|
|
13
|
+
// 콜스택 구조:
|
|
14
|
+
// [0]: "Error"
|
|
15
|
+
// [1]: "at extractCallStack"
|
|
16
|
+
// [2]: "at Naite.t"
|
|
17
|
+
// [3]: 실제 호출 위치부터 시작
|
|
18
|
+
const frames = lines.slice(3).map(parseStackFrame).filter((frame)=>frame !== null);
|
|
19
|
+
// runWithContext 계열 함수 발견 시 거기서 자르기
|
|
20
|
+
const contextIndex = frames.findIndex((f)=>f.functionName?.includes("runWithContext") || f.functionName?.includes("runWithMockContext"));
|
|
21
|
+
return contextIndex >= 0 ? frames.slice(0, contextIndex + 1) : frames;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 콜스택 한 줄을 파싱
|
|
25
|
+
* 형식1: "at FunctionName (filePath:lineNumber:columnNumber)"
|
|
26
|
+
* 형식2: "at filePath:lineNumber:columnNumber" (익명 함수/모듈 레벨)
|
|
27
|
+
*/ function parseStackFrame(line) {
|
|
28
|
+
// 패턴1: "at FunctionName (filePath:lineNumber:columnNumber)"
|
|
29
|
+
const matchWithFunc = line.match(/at\s+(.+?)\s+\((.+?):(\d+):\d+\)/);
|
|
30
|
+
if (matchWithFunc) {
|
|
31
|
+
const functionName = matchWithFunc[1];
|
|
32
|
+
const filePath = matchWithFunc[2];
|
|
33
|
+
const lineNumberStr = matchWithFunc[3];
|
|
34
|
+
// filePath에 이미 :가 포함되어 있으면 (예: "node:internal/...")
|
|
35
|
+
if (filePath.includes(":")) {
|
|
36
|
+
return {
|
|
37
|
+
functionName,
|
|
38
|
+
filePath,
|
|
39
|
+
lineNumber: 0
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
functionName,
|
|
44
|
+
filePath,
|
|
45
|
+
lineNumber: Number.parseInt(lineNumberStr, 10)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// 패턴2: "at filePath:lineNumber:columnNumber" (함수명 없음)
|
|
49
|
+
const matchNoFunc = line.match(/at\s+(.+?):(\d+):\d+$/);
|
|
50
|
+
if (matchNoFunc) {
|
|
51
|
+
const filePath = matchNoFunc[1];
|
|
52
|
+
const lineNumberStr = matchNoFunc[2];
|
|
53
|
+
return {
|
|
54
|
+
functionName: null,
|
|
55
|
+
filePath,
|
|
56
|
+
lineNumber: Number.parseInt(lineNumberStr, 10)
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* wildcard 패턴 매칭
|
|
63
|
+
* 예시:
|
|
64
|
+
* - "syncer:*" → "syncer:a", "syncer:a:b" 모두 매칭
|
|
65
|
+
* - "syncer:*:user" → "syncer:renderTemplate:user" 매칭
|
|
66
|
+
* - "syncer:renderTemplate:*" → "syncer:renderTemplate:service" 매칭
|
|
67
|
+
*/ function matchesPattern(key, pattern) {
|
|
68
|
+
const keyParts = key.split(":");
|
|
69
|
+
const patternParts = pattern.split(":");
|
|
70
|
+
// 마지막이 * → prefix 매칭 (길이 무관)
|
|
71
|
+
// 예: "syncer:*"는 "syncer:a", "syncer:a:b" 모두 매칭
|
|
72
|
+
if (patternParts[patternParts.length - 1] === "*") {
|
|
73
|
+
const prefixParts = patternParts.slice(0, -1);
|
|
74
|
+
// prefix가 모두 일치하는지 확인
|
|
75
|
+
return prefixParts.every((part, i)=>part === keyParts[i]);
|
|
76
|
+
}
|
|
77
|
+
// 길이가 같아야 함
|
|
78
|
+
if (patternParts.length !== keyParts.length) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
// 각 파트가 * 또는 정확히 일치
|
|
82
|
+
return patternParts.every((part, i)=>part === "*" || part === keyParts[i]);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* NaiteQuery 클래스
|
|
86
|
+
* 체이닝을 통한 trace 필터링 및 조회
|
|
87
|
+
*/ export class NaiteQuery {
|
|
88
|
+
traces;
|
|
89
|
+
constructor(traces){
|
|
90
|
+
this.traces = traces;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 파일명으로 필터링
|
|
94
|
+
* @param fileName 파일명 (예: "syncer.test.ts")
|
|
95
|
+
*/ fromFile(fileName) {
|
|
96
|
+
const filtered = this.traces.filter((t)=>t.stack.some((frame)=>frame.filePath.endsWith(`/${fileName}`)));
|
|
97
|
+
return new NaiteQuery(filtered);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 함수명으로 필터링
|
|
101
|
+
* @param funcName 함수명 (includes 체크)
|
|
102
|
+
* @param options.from 'direct' = 직접 호출만, 'indirect' = 간접 호출만, 'both' = 모두
|
|
103
|
+
*/ fromFunction(funcName, options = {
|
|
104
|
+
from: "both"
|
|
105
|
+
}) {
|
|
106
|
+
const filtered = this.traces.filter((t)=>{
|
|
107
|
+
if (options.from === "direct") {
|
|
108
|
+
// stack[0]만 확인 (직접 호출)
|
|
109
|
+
return t.stack[0]?.functionName?.includes(funcName);
|
|
110
|
+
}
|
|
111
|
+
if (options.from === "indirect") {
|
|
112
|
+
// stack[1+]에서 확인 (간접 호출)
|
|
113
|
+
return t.stack.slice(1).some((f)=>f.functionName?.includes(funcName));
|
|
114
|
+
}
|
|
115
|
+
// 전체 스택에서 확인
|
|
116
|
+
return t.stack.some((f)=>f.functionName?.includes(funcName));
|
|
117
|
+
});
|
|
118
|
+
return new NaiteQuery(filtered);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 데이터 경로 기반 필터링
|
|
122
|
+
* @param path radash get 경로 (예: "data.userId")
|
|
123
|
+
* @param operator 비교 연산자
|
|
124
|
+
* @param value 비교값
|
|
125
|
+
*/ where(path, operator, value) {
|
|
126
|
+
const filtered = this.traces.filter((trace)=>{
|
|
127
|
+
const actual = get(trace, path);
|
|
128
|
+
switch(operator){
|
|
129
|
+
case ">":
|
|
130
|
+
return actual > value;
|
|
131
|
+
case "<":
|
|
132
|
+
return actual < value;
|
|
133
|
+
case ">=":
|
|
134
|
+
return actual >= value;
|
|
135
|
+
case "<=":
|
|
136
|
+
return actual <= value;
|
|
137
|
+
case "=":
|
|
138
|
+
return actual === value;
|
|
139
|
+
case "!=":
|
|
140
|
+
return actual !== value;
|
|
141
|
+
case "includes":
|
|
142
|
+
return typeof actual === "string" && actual.includes(value);
|
|
143
|
+
default:
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return new NaiteQuery(filtered);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 전체 데이터 배열 반환
|
|
151
|
+
*/ result() {
|
|
152
|
+
return this.traces.map((t)=>t.data);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 첫 번째 데이터 반환
|
|
156
|
+
*/ first() {
|
|
157
|
+
return this.traces[0]?.data;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 마지막 데이터 반환
|
|
161
|
+
*/ last() {
|
|
162
|
+
return this.traces[this.traces.length - 1]?.data;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* n번째 데이터 반환
|
|
166
|
+
*/ at(index) {
|
|
167
|
+
return this.traces[index]?.data;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 원본 trace 배열 반환 (디버깅/NaiteViewer용)
|
|
171
|
+
*/ getTraces() {
|
|
172
|
+
return this.traces;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Naite 싱글턴 객체 (추후 logger 연결 등의 상태 관리 필요성 고려)
|
|
176
|
+
export class NaiteClass {
|
|
3
177
|
// 테스트 로그 기록
|
|
4
|
-
|
|
178
|
+
t(name, value/*이렇게 받은 값이 NaiteTrace로 저장되어 있다가 추후에 vitest에게 meta를 통해 넘겨져 프로세스간 통신을 통해 직렬화되어야 하는 점을 고려하였을 때 여기에 Serializable을 써서 제한을 둘 수도 있지만, 사용상의 편의를 생각하여 any로 받습니다.*/ ) {
|
|
179
|
+
// 이 t 함수는 테스트 환경에서만 작동해야 합니다.
|
|
180
|
+
// 그리고 테스트 환경 판단에 왜 isTest() 함수를 사용하지 않았냐면요,,
|
|
181
|
+
// 이렇게 하는게 유틸 함수 불러와서 사용하는 것보다 조금이나마 빠를 것 같았기 때문입니다.
|
|
182
|
+
if (process.env.NODE_ENV !== "test") {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
const context = Sonamu.getContext();
|
|
187
|
+
const store = context?.naiteStore;
|
|
188
|
+
if (!store) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
// 콜스택 수집
|
|
192
|
+
const stack = extractCallStack();
|
|
193
|
+
const trace = {
|
|
194
|
+
key: name,
|
|
195
|
+
data: value,
|
|
196
|
+
stack,
|
|
197
|
+
at: new Date()
|
|
198
|
+
};
|
|
199
|
+
// 항상 배열로 관리
|
|
200
|
+
const existing = store.get(name) ?? [];
|
|
201
|
+
store.set(name, [
|
|
202
|
+
...existing,
|
|
203
|
+
trace
|
|
204
|
+
]);
|
|
205
|
+
} catch {
|
|
206
|
+
// Context 없는 상황에서 Naite.t 호출
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* key 또는 wildcard 패턴으로 trace 조회
|
|
211
|
+
* 항상 NaiteQuery 반환하여 체이닝 가능
|
|
212
|
+
*/ get(keyPattern) {
|
|
5
213
|
const context = Sonamu.getContext();
|
|
6
214
|
const store = context?.naiteStore;
|
|
7
215
|
if (!store) {
|
|
8
|
-
return;
|
|
216
|
+
return new NaiteQuery([]);
|
|
217
|
+
}
|
|
218
|
+
// wildcard 없으면 exact match
|
|
219
|
+
if (!keyPattern.includes("*")) {
|
|
220
|
+
const traces = store.get(keyPattern) ?? [];
|
|
221
|
+
return new NaiteQuery(traces);
|
|
222
|
+
}
|
|
223
|
+
// wildcard 패턴 매칭
|
|
224
|
+
const allTraces = [];
|
|
225
|
+
for (const [key, traces] of store.entries()){
|
|
226
|
+
if (matchesPattern(key, keyPattern)) {
|
|
227
|
+
allTraces.push(...traces);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return new NaiteQuery(allTraces);
|
|
231
|
+
}
|
|
232
|
+
// 전체 리스트 가져오기
|
|
233
|
+
getAll() {
|
|
234
|
+
const context = Sonamu.getContext();
|
|
235
|
+
if (!context?.naiteStore) {
|
|
236
|
+
return {};
|
|
9
237
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
value
|
|
17
|
-
]);
|
|
238
|
+
// NaiteTrace 배열을 data만 추출하여 반환
|
|
239
|
+
const result = {};
|
|
240
|
+
for (const [key, traces] of context.naiteStore.entries()){
|
|
241
|
+
if (key.startsWith("mock:")) {
|
|
242
|
+
// Mock 설정은 그대로 반환
|
|
243
|
+
result[key] = traces;
|
|
18
244
|
} else {
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
store.get(name),
|
|
22
|
-
value
|
|
23
|
-
]);
|
|
245
|
+
// NaiteTrace 배열은 data만 추출
|
|
246
|
+
result[key] = traces.map((t)=>t.data);
|
|
24
247
|
}
|
|
25
|
-
} else {
|
|
26
|
-
// 값이 없는 경우 추가
|
|
27
|
-
store.set(name, value);
|
|
28
248
|
}
|
|
249
|
+
return result;
|
|
29
250
|
}
|
|
30
|
-
|
|
31
|
-
|
|
251
|
+
/**
|
|
252
|
+
* 스토어에 들어있던 트레이스를 고대로 꺼내옵니다.
|
|
253
|
+
* 이때 값들은 모두 직렬화 가능한 상태로 나가게 됩니다.
|
|
254
|
+
* 테스트 정보와 함께 extensions에 보낼 용도로 만들었습니다.
|
|
255
|
+
* @returns
|
|
256
|
+
*/ getAllTraces() {
|
|
32
257
|
const context = Sonamu.getContext();
|
|
33
|
-
if (!context?.naiteStore
|
|
34
|
-
|
|
258
|
+
if (!context?.naiteStore) {
|
|
259
|
+
return [];
|
|
260
|
+
}
|
|
261
|
+
const traces = Array.from(context.naiteStore.values()).flat();
|
|
262
|
+
// 직렬화 불가능한 값이 존재한다면 이를 대문짝만하게 알려줍니다! 그치만 알리기만 하고 그냥 지나갑니다 ㅎㅎ
|
|
263
|
+
// 왜 직렬화가 중요한가? 이(getAllTraces) 호출의 결과는 외부로 나가게 되는데,
|
|
264
|
+
// 이때 주 용도가 vitest의 task.meta 필드를 통해 afterEach에서 Sonamu extension으로 전달하는 것입니다.
|
|
265
|
+
// 여기서 meta 필드에 담긴 내용은 프로세스간 통신(process.send) 또는 스레드간 통신(message port)을 통해 전달되어야 하는데,
|
|
266
|
+
// 이로 인해 "직렬화 가능한 값들만 허용"하는 제약이 생깁니다.
|
|
267
|
+
//
|
|
268
|
+
// 이 제약을 의식하여 Naite.t에 직렬화 가능한 값만 넘기게 할 수도 있었지만, 그렇게 하면 불편해질 것 같아서 하지 않았습니다.
|
|
269
|
+
// 따라서 현재 Naite.t는 모든 값을 받을 수 있게 되어 있습니다.
|
|
270
|
+
// 대신 이렇게(getAllTraces) 그 값들을 빼낼 때 JSON.stringify를 사용하여 강제로 직렬화 가능하게 만들었습니다,,
|
|
271
|
+
for (const trace of traces){
|
|
272
|
+
const check = isSerializable(trace.data);
|
|
273
|
+
if (!check.valid) {
|
|
274
|
+
console.warn("\n" + "╔════════════════════════════════════════════════════════════════╗\n" + "║ [Naite] Non-serializable value detected! ║\n" + "╠════════════════════════════════════════════════════════════════╣\n" + `║ Key: ${trace.key.padEnd(57)}║\n` + `║ Reason: ${(check.reason ?? "unknown").slice(0, 54).padEnd(54)}║\n` + `║ Location: ${(trace.stack[0]?.filePath ?? "unknown").slice(-51).padEnd(52)}║\n` + `║ Line: ${String(trace.stack[0]?.lineNumber ?? 0).padEnd(56)}║\n` + "╠════════════════════════════════════════════════════════════════╣\n" + "║ Naite.t() accepts any type of value. However, values will ║\n" + "║ be serialized to JSON when exported via Naite.getAllTraces(). ║\n" + "╚════════════════════════════════════════════════════════════════╝\n");
|
|
275
|
+
}
|
|
35
276
|
}
|
|
36
|
-
return
|
|
277
|
+
return traces.map((trace)=>({
|
|
278
|
+
key: trace.key,
|
|
279
|
+
value: JSON.parse(JSON.stringify(trace.data ?? "")),
|
|
280
|
+
filePath: trace.stack[0]?.filePath ?? "",
|
|
281
|
+
lineNumber: trace.stack[0]?.lineNumber ?? 0,
|
|
282
|
+
at: trace.at.toISOString()
|
|
283
|
+
}));
|
|
37
284
|
}
|
|
38
|
-
//
|
|
39
|
-
|
|
285
|
+
// 특정 키 삭제하기
|
|
286
|
+
del(key) {
|
|
40
287
|
const context = Sonamu.getContext();
|
|
41
288
|
if (!context?.naiteStore) {
|
|
42
|
-
return
|
|
289
|
+
return;
|
|
43
290
|
}
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
// throw new Error("Vitest is not initialized");
|
|
50
|
-
// }
|
|
51
|
-
// return this.vitestExpect(this.get(name));
|
|
52
|
-
// }
|
|
291
|
+
context.naiteStore.delete(key);
|
|
292
|
+
}
|
|
293
|
+
createStore() {
|
|
294
|
+
return new Map();
|
|
295
|
+
}
|
|
53
296
|
// 일반 로그 레벨
|
|
54
|
-
|
|
297
|
+
d(_message) {
|
|
55
298
|
// TODO: Logger 연결
|
|
56
299
|
console.log(`[DEBUG] ${_message}`);
|
|
57
300
|
}
|
|
58
|
-
|
|
301
|
+
i(_message) {
|
|
59
302
|
// TODO: Logger 연결
|
|
60
303
|
console.log(`[INFO] ${_message}`);
|
|
61
304
|
}
|
|
62
|
-
|
|
305
|
+
w(_message) {
|
|
63
306
|
// TODO: Logger 연결
|
|
64
307
|
console.log(`[WARN] ${_message}`);
|
|
65
308
|
}
|
|
66
|
-
|
|
309
|
+
e(_message) {
|
|
67
310
|
// TODO: Logger 연결
|
|
68
311
|
console.log(`[ERROR] ${_message}`);
|
|
69
312
|
}
|
|
70
313
|
}
|
|
314
|
+
export const Naite = new NaiteClass();
|
|
71
315
|
|
|
72
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uYWl0ZS9uYWl0ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuXG5leHBvcnQgY2xhc3MgTmFpdGUge1xuICAvLyDthYzsiqTtirgg66Gc6re4IOq4sOuhnVxuICBzdGF0aWMgdChuYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgICBjb25zdCBjb250ZXh0ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBjb25zdCBzdG9yZSA9IGNvbnRleHQ/Lm5haXRlU3RvcmU7XG5cbiAgICBpZiAoIXN0b3JlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzdG9yZS5oYXMobmFtZSkpIHtcbiAgICAgIC8vIOydtOuvuCDqsJLsnbQg7J6I64qUIOqyveyasFxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc3RvcmUuZ2V0KG5hbWUpKSkge1xuICAgICAgICAvLyDrsLDsl7Tsl5Ag7LaU6rCAXG4gICAgICAgIHN0b3JlLnNldChuYW1lLCBbLi4uc3RvcmUuZ2V0KG5hbWUpLCB2YWx1ZV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g67Cw7Je07J20IOyVhOuLjCDqsr3smrAg67Cw7Je066GcIOuzgO2ZmFxuICAgICAgICBzdG9yZS5zZXQobmFtZSwgW3N0b3JlLmdldChuYW1lKSwgdmFsdWVdKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8g6rCS7J20IOyXhuuKlCDqsr3smrAg7LaU6rCAXG4gICAgICBzdG9yZS5zZXQobmFtZSwgdmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIO2FjOyKpO2KuOyXkOyEnCDqsJIg6rCA7KC47Jik6riwXG4gIHN0YXRpYyBnZXQobmFtZTogc3RyaW5nKTogYW55IHtcbiAgICBjb25zdCBjb250ZXh0ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBpZiAoIWNvbnRleHQ/Lm5haXRlU3RvcmUgfHwgIWNvbnRleHQubmFpdGVTdG9yZS5oYXMobmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTmFpdGUuZ2V0OiBcXGAke25hbWV9XFxgIG5vdCBmb3VuZGApO1xuICAgIH1cbiAgICByZXR1cm4gY29udGV4dD8ubmFpdGVTdG9yZT8uZ2V0KG5hbWUpO1xuICB9XG5cbiAgLy8g7KCE7LK0IOumrOyKpO2KuCDqsIDsoLjsmKTquLBcbiAgc3RhdGljIGdldEFsbCgpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgICBjb25zdCBjb250ZXh0ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBpZiAoIWNvbnRleHQ/Lm5haXRlU3RvcmUpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhjb250ZXh0Lm5haXRlU3RvcmUuZW50cmllcygpKTtcbiAgfVxuXG4gIC8vIGV4cGVjdCDrnpjtjbwgKENKUy1FU00g7J207IqI66GcIO2YhOyerCDsgqzsmqnrtojqsIApXG4gIC8vIHN0YXRpYyBleHBlY3QobmFtZTogc3RyaW5nKSB7XG4gIC8vICAgaWYgKCF0aGlzLnZpdGVzdEV4cGVjdCkge1xuICAvLyAgICAgdGhyb3cgbmV3IEVycm9yKFwiVml0ZXN0IGlzIG5vdCBpbml0aWFsaXplZFwiKTtcbiAgLy8gICB9XG4gIC8vICAgcmV0dXJuIHRoaXMudml0ZXN0RXhwZWN0KHRoaXMuZ2V0KG5hbWUpKTtcbiAgLy8gfVxuXG4gIC8vIOydvOuwmCDroZzqt7gg66CI67KoXG4gIHN0YXRpYyBkKF9tZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAvLyBUT0RPOiBMb2dnZXIg7Jew6rKwXG4gICAgY29uc29sZS5sb2coYFtERUJVR10gJHtfbWVzc2FnZX1gKTtcbiAgfVxuICBzdGF0aWMgaShfbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgLy8gVE9ETzogTG9nZ2VyIOyXsOqysFxuICAgIGNvbnNvbGUubG9nKGBbSU5GT10gJHtfbWVzc2FnZX1gKTtcbiAgfVxuICBzdGF0aWMgdyhfbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgLy8gVE9ETzogTG9nZ2VyIOyXsOqysFxuICAgIGNvbnNvbGUubG9nKGBbV0FSTl0gJHtfbWVzc2FnZX1gKTtcbiAgfVxuICBzdGF0aWMgZShfbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgLy8gVE9ETzogTG9nZ2VyIOyXsOqysFxuICAgIGNvbnNvbGUubG9nKGBbRVJST1JdICR7X21lc3NhZ2V9YCk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJTb25hbXUiLCJOYWl0ZSIsInQiLCJuYW1lIiwidmFsdWUiLCJjb250ZXh0IiwiZ2V0Q29udGV4dCIsInN0b3JlIiwibmFpdGVTdG9yZSIsImhhcyIsIkFycmF5IiwiaXNBcnJheSIsImdldCIsInNldCIsIkVycm9yIiwiZ2V0QWxsIiwiT2JqZWN0IiwiZnJvbUVudHJpZXMiLCJlbnRyaWVzIiwiZCIsIl9tZXNzYWdlIiwiY29uc29sZSIsImxvZyIsImkiLCJ3IiwiZSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFBTSxRQUFRLG1CQUFnQjtBQUV2QyxPQUFPLE1BQU1DO0lBQ1gsWUFBWTtJQUNaLE9BQU9DLEVBQUVDLElBQVksRUFBRUMsS0FBVSxFQUFFO1FBQ2pDLE1BQU1DLFVBQVVMLE9BQU9NLFVBQVU7UUFDakMsTUFBTUMsUUFBUUYsU0FBU0c7UUFFdkIsSUFBSSxDQUFDRCxPQUFPO1lBQ1Y7UUFDRjtRQUNBLElBQUlBLE1BQU1FLEdBQUcsQ0FBQ04sT0FBTztZQUNuQixjQUFjO1lBQ2QsSUFBSU8sTUFBTUMsT0FBTyxDQUFDSixNQUFNSyxHQUFHLENBQUNULFFBQVE7Z0JBQ2xDLFNBQVM7Z0JBQ1RJLE1BQU1NLEdBQUcsQ0FBQ1YsTUFBTTt1QkFBSUksTUFBTUssR0FBRyxDQUFDVDtvQkFBT0M7aUJBQU07WUFDN0MsT0FBTztnQkFDTCxtQkFBbUI7Z0JBQ25CRyxNQUFNTSxHQUFHLENBQUNWLE1BQU07b0JBQUNJLE1BQU1LLEdBQUcsQ0FBQ1Q7b0JBQU9DO2lCQUFNO1lBQzFDO1FBQ0YsT0FBTztZQUNMLGNBQWM7WUFDZEcsTUFBTU0sR0FBRyxDQUFDVixNQUFNQztRQUNsQjtJQUNGO0lBRUEsZUFBZTtJQUNmLE9BQU9RLElBQUlULElBQVksRUFBTztRQUM1QixNQUFNRSxVQUFVTCxPQUFPTSxVQUFVO1FBQ2pDLElBQUksQ0FBQ0QsU0FBU0csY0FBYyxDQUFDSCxRQUFRRyxVQUFVLENBQUNDLEdBQUcsQ0FBQ04sT0FBTztZQUN6RCxNQUFNLElBQUlXLE1BQU0sQ0FBQyxhQUFhLEVBQUVYLEtBQUssWUFBWSxDQUFDO1FBQ3BEO1FBQ0EsT0FBT0UsU0FBU0csWUFBWUksSUFBSVQ7SUFDbEM7SUFFQSxjQUFjO0lBQ2QsT0FBT1ksU0FBaUM7UUFDdEMsTUFBTVYsVUFBVUwsT0FBT00sVUFBVTtRQUNqQyxJQUFJLENBQUNELFNBQVNHLFlBQVk7WUFDeEIsT0FBTyxDQUFDO1FBQ1Y7UUFDQSxPQUFPUSxPQUFPQyxXQUFXLENBQUNaLFFBQVFHLFVBQVUsQ0FBQ1UsT0FBTztJQUN0RDtJQUVBLGtDQUFrQztJQUNsQyxnQ0FBZ0M7SUFDaEMsOEJBQThCO0lBQzlCLG9EQUFvRDtJQUNwRCxNQUFNO0lBQ04sOENBQThDO0lBQzlDLElBQUk7SUFFSixXQUFXO0lBQ1gsT0FBT0MsRUFBRUMsUUFBZ0IsRUFBRTtRQUN6QixrQkFBa0I7UUFDbEJDLFFBQVFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRUYsVUFBVTtJQUNuQztJQUNBLE9BQU9HLEVBQUVILFFBQWdCLEVBQUU7UUFDekIsa0JBQWtCO1FBQ2xCQyxRQUFRQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUVGLFVBQVU7SUFDbEM7SUFDQSxPQUFPSSxFQUFFSixRQUFnQixFQUFFO1FBQ3pCLGtCQUFrQjtRQUNsQkMsUUFBUUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFRixVQUFVO0lBQ2xDO0lBQ0EsT0FBT0ssRUFBRUwsUUFBZ0IsRUFBRTtRQUN6QixrQkFBa0I7UUFDbEJDLFFBQVFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRUYsVUFBVTtJQUNuQztBQUNGIn0=
|
|
316
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uYWl0ZS9uYWl0ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogYmlvbWUtaWdub3JlLWFsbCBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTmFpdGXripQgZXhwZWN07JmAIO2YuOydke2VmOuPhOuhnSBhbnnrpbwg7ZeI7Jqp7ZWoICovXG5cbmltcG9ydCB7IGdldCB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHR5cGUgeyBDb21wYXJpc29uT3BlcmF0b3IgfSBmcm9tIFwiLi4vZGF0YWJhc2UvcHVyaS50eXBlc1wiO1xuaW1wb3J0IHsgaXNTZXJpYWxpemFibGUgfSBmcm9tIFwiLi4vdXRpbHMvb2JqZWN0LXV0aWxzXCI7XG5cbi8vIFN0YWNrRnJhbWUg7YOA7J6FXG5pbnRlcmZhY2UgU3RhY2tGcmFtZSB7XG4gIGZ1bmN0aW9uTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgZmlsZVBhdGg6IHN0cmluZzsgLy8gXCIvVXNlcnMvLi4uL3N5bmNlci50c1wiIOuYkOuKlCBcIm5vZGU6aW50ZXJuYWwvLi4uXCJcbiAgbGluZU51bWJlcjogbnVtYmVyOyAvLyBUUyDtjIzsnbwg6riw7KSAIOudvOyduCDrsojtmLhcbn1cblxuLy8gTmFpdGVUcmFjZSDtg4DsnoVcbmludGVyZmFjZSBOYWl0ZVRyYWNlIHtcbiAga2V5OiBzdHJpbmc7XG4gIGRhdGE6IGFueTtcbiAgc3RhY2s6IFN0YWNrRnJhbWVbXTsgLy8g7L2c7Iqk7YOdIOygleuztFxuICBhdDogRGF0ZTtcbn1cblxuLy8gTmFpdGUudOqwgCDsoIDsnqXrkJjripQg7YOA7J6FICjtla3sg4Eg67Cw7Je066GcIO2GteydvClcbmV4cG9ydCB0eXBlIE5haXRlU3RvcmUgPSBNYXA8c3RyaW5nLCBOYWl0ZVRyYWNlW10+O1xuXG4vKipcbiAqIOy9nOyKpO2DneydhCDtjIzsi7HtlZjsl6wgU3RhY2tGcmFtZSDrsLDsl7TroZwg67CY7ZmYXG4gKiAtIGV4dHJhY3RDYWxsU3RhY2sg7J6Q7Iug6rO8IE5haXRlLnTripQg7KCc7Jm4XG4gKiAtIHJ1bldpdGhDb250ZXh0L3J1bldpdGhNb2NrQ29udGV4dCDrsJzqsqwg7IucIOqxsOq4sOyEnCDsooXro4xcbiAqIC0gbm9kZTog64K067aAIOqyveuhnOuKlCDtj6ztlajtlZjrkJgsIGxpbmVOdW1iZXLripQgcGF0aOyXkCA6IO2PrO2VqCDsi5wg67aZ7J207KeAIOyViuydjFxuICovXG5mdW5jdGlvbiBleHRyYWN0Q2FsbFN0YWNrKCk6IFN0YWNrRnJhbWVbXSB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s7XG4gIGlmICghc3RhY2spIHJldHVybiBbXTtcblxuICBjb25zdCBsaW5lcyA9IHN0YWNrLnNwbGl0KFwiXFxuXCIpO1xuXG4gIC8vIOy9nOyKpO2DnSDqtazsobA6XG4gIC8vIFswXTogXCJFcnJvclwiXG4gIC8vIFsxXTogXCJhdCBleHRyYWN0Q2FsbFN0YWNrXCJcbiAgLy8gWzJdOiBcImF0IE5haXRlLnRcIlxuICAvLyBbM106IOyLpOygnCDtmLjstpwg7JyE7LmY67aA7YSwIOyLnOyekVxuICBjb25zdCBmcmFtZXMgPSBsaW5lc1xuICAgIC5zbGljZSgzKVxuICAgIC5tYXAocGFyc2VTdGFja0ZyYW1lKVxuICAgIC5maWx0ZXIoKGZyYW1lKTogZnJhbWUgaXMgU3RhY2tGcmFtZSA9PiBmcmFtZSAhPT0gbnVsbCk7XG5cbiAgLy8gcnVuV2l0aENvbnRleHQg6rOE7Je0IO2VqOyImCDrsJzqsqwg7IucIOqxsOq4sOyEnCDsnpDrpbTquLBcbiAgY29uc3QgY29udGV4dEluZGV4ID0gZnJhbWVzLmZpbmRJbmRleChcbiAgICAoZikgPT5cbiAgICAgIGYuZnVuY3Rpb25OYW1lPy5pbmNsdWRlcyhcInJ1bldpdGhDb250ZXh0XCIpIHx8IGYuZnVuY3Rpb25OYW1lPy5pbmNsdWRlcyhcInJ1bldpdGhNb2NrQ29udGV4dFwiKSxcbiAgKTtcblxuICByZXR1cm4gY29udGV4dEluZGV4ID49IDAgPyBmcmFtZXMuc2xpY2UoMCwgY29udGV4dEluZGV4ICsgMSkgOiBmcmFtZXM7XG59XG5cbi8qKlxuICog7L2c7Iqk7YOdIO2VnCDspITsnYQg7YyM7IuxXG4gKiDtmJXsi50xOiBcImF0IEZ1bmN0aW9uTmFtZSAoZmlsZVBhdGg6bGluZU51bWJlcjpjb2x1bW5OdW1iZXIpXCJcbiAqIO2YleyLnTI6IFwiYXQgZmlsZVBhdGg6bGluZU51bWJlcjpjb2x1bW5OdW1iZXJcIiAo7J2166qFIO2VqOyImC/rqqjrk4gg66CI67KoKVxuICovXG5mdW5jdGlvbiBwYXJzZVN0YWNrRnJhbWUobGluZTogc3RyaW5nKTogU3RhY2tGcmFtZSB8IG51bGwge1xuICAvLyDtjKjthLQxOiBcImF0IEZ1bmN0aW9uTmFtZSAoZmlsZVBhdGg6bGluZU51bWJlcjpjb2x1bW5OdW1iZXIpXCJcbiAgY29uc3QgbWF0Y2hXaXRoRnVuYyA9IGxpbmUubWF0Y2goL2F0XFxzKyguKz8pXFxzK1xcKCguKz8pOihcXGQrKTpcXGQrXFwpLyk7XG4gIGlmIChtYXRjaFdpdGhGdW5jKSB7XG4gICAgY29uc3QgZnVuY3Rpb25OYW1lID0gbWF0Y2hXaXRoRnVuY1sxXTtcbiAgICBjb25zdCBmaWxlUGF0aCA9IG1hdGNoV2l0aEZ1bmNbMl07XG4gICAgY29uc3QgbGluZU51bWJlclN0ciA9IG1hdGNoV2l0aEZ1bmNbM107XG5cbiAgICAvLyBmaWxlUGF0aOyXkCDsnbTrr7ggOuqwgCDtj6ztlajrkJjslrQg7J6I7Jy866m0ICjsmIg6IFwibm9kZTppbnRlcm5hbC8uLi5cIilcbiAgICBpZiAoZmlsZVBhdGguaW5jbHVkZXMoXCI6XCIpKSB7XG4gICAgICByZXR1cm4geyBmdW5jdGlvbk5hbWUsIGZpbGVQYXRoLCBsaW5lTnVtYmVyOiAwIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgIGZpbGVQYXRoLFxuICAgICAgbGluZU51bWJlcjogTnVtYmVyLnBhcnNlSW50KGxpbmVOdW1iZXJTdHIsIDEwKSxcbiAgICB9O1xuICB9XG5cbiAgLy8g7Yyo7YS0MjogXCJhdCBmaWxlUGF0aDpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiICjtlajsiJjrqoUg7JeG7J2MKVxuICBjb25zdCBtYXRjaE5vRnVuYyA9IGxpbmUubWF0Y2goL2F0XFxzKyguKz8pOihcXGQrKTpcXGQrJC8pO1xuICBpZiAobWF0Y2hOb0Z1bmMpIHtcbiAgICBjb25zdCBmaWxlUGF0aCA9IG1hdGNoTm9GdW5jWzFdO1xuICAgIGNvbnN0IGxpbmVOdW1iZXJTdHIgPSBtYXRjaE5vRnVuY1syXTtcblxuICAgIHJldHVybiB7XG4gICAgICBmdW5jdGlvbk5hbWU6IG51bGwsXG4gICAgICBmaWxlUGF0aCxcbiAgICAgIGxpbmVOdW1iZXI6IE51bWJlci5wYXJzZUludChsaW5lTnVtYmVyU3RyLCAxMCksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIHdpbGRjYXJkIO2MqO2EtCDrp6Tsua1cbiAqIOyYiOyLnDpcbiAqIC0gXCJzeW5jZXI6KlwiIOKGkiBcInN5bmNlcjphXCIsIFwic3luY2VyOmE6YlwiIOuqqOuRkCDrp6Tsua1cbiAqIC0gXCJzeW5jZXI6Kjp1c2VyXCIg4oaSIFwic3luY2VyOnJlbmRlclRlbXBsYXRlOnVzZXJcIiDrp6Tsua1cbiAqIC0gXCJzeW5jZXI6cmVuZGVyVGVtcGxhdGU6KlwiIOKGkiBcInN5bmNlcjpyZW5kZXJUZW1wbGF0ZTpzZXJ2aWNlXCIg66ek7LmtXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNQYXR0ZXJuKGtleTogc3RyaW5nLCBwYXR0ZXJuOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qga2V5UGFydHMgPSBrZXkuc3BsaXQoXCI6XCIpO1xuICBjb25zdCBwYXR0ZXJuUGFydHMgPSBwYXR0ZXJuLnNwbGl0KFwiOlwiKTtcblxuICAvLyDrp4jsp4Drp4nsnbQgKiDihpIgcHJlZml4IOunpOy5rSAo6ri47J20IOustOq0gClcbiAgLy8g7JiIOiBcInN5bmNlcjoqXCLripQgXCJzeW5jZXI6YVwiLCBcInN5bmNlcjphOmJcIiDrqqjrkZAg66ek7LmtXG4gIGlmIChwYXR0ZXJuUGFydHNbcGF0dGVyblBhcnRzLmxlbmd0aCAtIDFdID09PSBcIipcIikge1xuICAgIGNvbnN0IHByZWZpeFBhcnRzID0gcGF0dGVyblBhcnRzLnNsaWNlKDAsIC0xKTtcbiAgICAvLyBwcmVmaXjqsIAg66qo65GQIOydvOy5mO2VmOuKlOyngCDtmZXsnbhcbiAgICByZXR1cm4gcHJlZml4UGFydHMuZXZlcnkoKHBhcnQsIGkpID0+IHBhcnQgPT09IGtleVBhcnRzW2ldKTtcbiAgfVxuXG4gIC8vIOq4uOydtOqwgCDqsJnslYTslbwg7ZWoXG4gIGlmIChwYXR0ZXJuUGFydHMubGVuZ3RoICE9PSBrZXlQYXJ0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyDqsIEg7YyM7Yq46rCAICog65iQ64qUIOygle2Zle2eiCDsnbzsuZhcbiAgcmV0dXJuIHBhdHRlcm5QYXJ0cy5ldmVyeSgocGFydCwgaSkgPT4gcGFydCA9PT0gXCIqXCIgfHwgcGFydCA9PT0ga2V5UGFydHNbaV0pO1xufVxuXG4vKipcbiAqIE5haXRlUXVlcnkg7YG0656Y7IqkXG4gKiDssrTsnbTri53snYQg7Ya17ZWcIHRyYWNlIO2VhO2EsOungSDrsI8g7KGw7ZqMXG4gKi9cbmV4cG9ydCBjbGFzcyBOYWl0ZVF1ZXJ5IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0cmFjZXM6IE5haXRlVHJhY2VbXSkge31cblxuICAvKipcbiAgICog7YyM7J2866qF7Jy866GcIO2VhO2EsOungVxuICAgKiBAcGFyYW0gZmlsZU5hbWUg7YyM7J2866qFICjsmIg6IFwic3luY2VyLnRlc3QudHNcIilcbiAgICovXG4gIGZyb21GaWxlKGZpbGVOYW1lOiBzdHJpbmcpOiBOYWl0ZVF1ZXJ5IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMudHJhY2VzLmZpbHRlcigodCkgPT5cbiAgICAgIHQuc3RhY2suc29tZSgoZnJhbWUpID0+IGZyYW1lLmZpbGVQYXRoLmVuZHNXaXRoKGAvJHtmaWxlTmFtZX1gKSksXG4gICAgKTtcbiAgICByZXR1cm4gbmV3IE5haXRlUXVlcnkoZmlsdGVyZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VqOyImOuqheycvOuhnCDtlYTthLDrp4FcbiAgICogQHBhcmFtIGZ1bmNOYW1lIO2VqOyImOuqhSAoaW5jbHVkZXMg7LK07YGsKVxuICAgKiBAcGFyYW0gb3B0aW9ucy5mcm9tICdkaXJlY3QnID0g7KeB7KCRIO2YuOy2nOunjCwgJ2luZGlyZWN0JyA9IOqwhOygkSDtmLjstpzrp4wsICdib3RoJyA9IOuqqOuRkFxuICAgKi9cbiAgZnJvbUZ1bmN0aW9uKFxuICAgIGZ1bmNOYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczogeyBmcm9tOiBcImRpcmVjdFwiIHwgXCJpbmRpcmVjdFwiIHwgXCJib3RoXCIgfSA9IHsgZnJvbTogXCJib3RoXCIgfSxcbiAgKTogTmFpdGVRdWVyeSB7XG4gICAgY29uc3QgZmlsdGVyZWQgPSB0aGlzLnRyYWNlcy5maWx0ZXIoKHQpID0+IHtcbiAgICAgIGlmIChvcHRpb25zLmZyb20gPT09IFwiZGlyZWN0XCIpIHtcbiAgICAgICAgLy8gc3RhY2tbMF3rp4wg7ZmV7J24ICjsp4HsoJEg7Zi47LacKVxuICAgICAgICByZXR1cm4gdC5zdGFja1swXT8uZnVuY3Rpb25OYW1lPy5pbmNsdWRlcyhmdW5jTmFtZSk7XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5mcm9tID09PSBcImluZGlyZWN0XCIpIHtcbiAgICAgICAgLy8gc3RhY2tbMStd7JeQ7IScIO2ZleyduCAo6rCE7KCRIO2YuOy2nClcbiAgICAgICAgcmV0dXJuIHQuc3RhY2suc2xpY2UoMSkuc29tZSgoZikgPT4gZi5mdW5jdGlvbk5hbWU/LmluY2x1ZGVzKGZ1bmNOYW1lKSk7XG4gICAgICB9XG4gICAgICAvLyDsoITssrQg7Iqk7YOd7JeQ7IScIO2ZleyduFxuICAgICAgcmV0dXJuIHQuc3RhY2suc29tZSgoZikgPT4gZi5mdW5jdGlvbk5hbWU/LmluY2x1ZGVzKGZ1bmNOYW1lKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBOYWl0ZVF1ZXJ5KGZpbHRlcmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrjbDsnbTthLAg6rK966GcIOq4sOuwmCDtlYTthLDrp4FcbiAgICogQHBhcmFtIHBhdGggcmFkYXNoIGdldCDqsr3roZwgKOyYiDogXCJkYXRhLnVzZXJJZFwiKVxuICAgKiBAcGFyYW0gb3BlcmF0b3Ig67mE6rWQIOyXsOyCsOyekFxuICAgKiBAcGFyYW0gdmFsdWUg67mE6rWQ6rCSXG4gICAqL1xuICB3aGVyZShwYXRoOiBzdHJpbmcsIG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IgfCBcImluY2x1ZGVzXCIsIHZhbHVlOiBhbnkpOiBOYWl0ZVF1ZXJ5IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMudHJhY2VzLmZpbHRlcigodHJhY2UpID0+IHtcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGdldCh0cmFjZSwgcGF0aCkgYXMgYW55O1xuXG4gICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgXCI+XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCA+IHZhbHVlO1xuICAgICAgICBjYXNlIFwiPFwiOlxuICAgICAgICAgIHJldHVybiBhY3R1YWwgPCB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIj49XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCA+PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIjw9XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCA8PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIj1cIjpcbiAgICAgICAgICByZXR1cm4gYWN0dWFsID09PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIiE9XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCAhPT0gdmFsdWU7XG4gICAgICAgIGNhc2UgXCJpbmNsdWRlc1wiOlxuICAgICAgICAgIHJldHVybiB0eXBlb2YgYWN0dWFsID09PSBcInN0cmluZ1wiICYmIGFjdHVhbC5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBuZXcgTmFpdGVRdWVyeShmaWx0ZXJlZCk7XG4gIH1cblxuICAvKipcbiAgICog7KCE7LK0IOuNsOydtO2EsCDrsLDsl7Qg67CY7ZmYXG4gICAqL1xuICByZXN1bHQoKTogYW55W10ge1xuICAgIHJldHVybiB0aGlzLnRyYWNlcy5tYXAoKHQpID0+IHQuZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICog7LKrIOuyiOynuCDrjbDsnbTthLAg67CY7ZmYXG4gICAqL1xuICBmaXJzdCgpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1swXT8uZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrp4jsp4Drp4kg642w7J207YSwIOuwmO2ZmFxuICAgKi9cbiAgbGFzdCgpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1t0aGlzLnRyYWNlcy5sZW5ndGggLSAxXT8uZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBu67KI7Ke4IOuNsOydtO2EsCDrsJjtmZhcbiAgICovXG4gIGF0KGluZGV4OiBudW1iZXIpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1tpbmRleF0/LmRhdGE7XG4gIH1cblxuICAvKipcbiAgICog7JuQ67O4IHRyYWNlIOuwsOyXtCDrsJjtmZggKOuUlOuyhOq5hS9OYWl0ZVZpZXdlcuyaqSlcbiAgICovXG4gIGdldFRyYWNlcygpOiBOYWl0ZVRyYWNlW10ge1xuICAgIHJldHVybiB0aGlzLnRyYWNlcztcbiAgfVxufVxuXG4vLyBOYWl0ZSDsi7HquIDthLQg6rCd7LK0ICjstpTtm4QgbG9nZ2VyIOyXsOqysCDrk7HsnZgg7IOB7YOcIOq0gOumrCDtlYTsmpTshLEg6rOg66CkKVxuZXhwb3J0IGNsYXNzIE5haXRlQ2xhc3Mge1xuICAvLyDthYzsiqTtirgg66Gc6re4IOq4sOuhnVxuICB0KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZTogYW55IC8q7J2066CH6rKMIOuwm+ydgCDqsJLsnbQgTmFpdGVUcmFjZeuhnCDsoIDsnqXrkJjslrQg7J6I64uk6rCAIOy2lO2bhOyXkCB2aXRlc3Tsl5DqsowgbWV0YeulvCDthrXtlbQg64SY6rKo7KC4IO2UhOuhnOyEuOyKpOqwhCDthrXsi6DsnYQg7Ya17ZW0IOyngeugrO2ZlOuQmOyWtOyVvCDtlZjripQg7KCQ7J2EIOqzoOugpO2VmOyYgOydhCDrlYwg7Jes6riw7JeQIFNlcmlhbGl6YWJsZeydhCDsjajshJwg7KCc7ZWc7J2EIOuRmCDsiJjrj4Qg7J6I7KeA66eMLCDsgqzsmqnsg4HsnZgg7Y647J2Y66W8IOyDneqwge2VmOyXrCBhbnnroZwg67Cb7Iq164uI64ukLiovLFxuICApIHtcbiAgICAvLyDsnbQgdCDtlajsiJjripQg7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnOunjCDsnpHrj5ntlbTslbwg7ZWp64uI64ukLlxuICAgIC8vIOq3uOumrOqzoCDthYzsiqTtirgg7ZmY6rK9IO2MkOuLqOyXkCDsmZwgaXNUZXN0KCkg7ZWo7IiY66W8IOyCrOyaqe2VmOyngCDslYrslZjrg5DrqbTsmpQsLFxuICAgIC8vIOydtOugh+qyjCDtlZjripTqsowg7Jyg7Yu4IO2VqOyImCDrtojrn6zsmYDshJwg7IKs7Jqp7ZWY64qUIOqyg+uztOuLpCDsobDquIjsnbTrgpjrp4gg67mg66W8IOqygyDqsJnslZjquLAg65WM66y47J6F64uI64ukLlxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJ0ZXN0XCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgICBjb25zdCBzdG9yZSA9IGNvbnRleHQ/Lm5haXRlU3RvcmU7XG5cbiAgICAgIGlmICghc3RvcmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyDsvZzsiqTtg50g7IiY7KeRXG4gICAgICBjb25zdCBzdGFjayA9IGV4dHJhY3RDYWxsU3RhY2soKTtcblxuICAgICAgY29uc3QgdHJhY2U6IE5haXRlVHJhY2UgPSB7XG4gICAgICAgIGtleTogbmFtZSxcbiAgICAgICAgZGF0YTogdmFsdWUsXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBhdDogbmV3IERhdGUoKSxcbiAgICAgIH07XG5cbiAgICAgIC8vIO2VreyDgSDrsLDsl7TroZwg6rSA66asXG4gICAgICBjb25zdCBleGlzdGluZyA9IHN0b3JlLmdldChuYW1lKSA/PyBbXTtcbiAgICAgIHN0b3JlLnNldChuYW1lLCBbLi4uZXhpc3RpbmcsIHRyYWNlXSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDb250ZXh0IOyXhuuKlCDsg4Htmansl5DshJwgTmFpdGUudCDtmLjstpxcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICoga2V5IOuYkOuKlCB3aWxkY2FyZCDtjKjthLTsnLzroZwgdHJhY2Ug7KGw7ZqMXG4gICAqIO2VreyDgSBOYWl0ZVF1ZXJ5IOuwmO2ZmO2VmOyXrCDssrTsnbTri50g6rCA64qlXG4gICAqL1xuICBnZXQoa2V5UGF0dGVybjogc3RyaW5nKTogTmFpdGVRdWVyeSB7XG4gICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgY29uc3Qgc3RvcmUgPSBjb250ZXh0Py5uYWl0ZVN0b3JlO1xuXG4gICAgaWYgKCFzdG9yZSkge1xuICAgICAgcmV0dXJuIG5ldyBOYWl0ZVF1ZXJ5KFtdKTtcbiAgICB9XG5cbiAgICAvLyB3aWxkY2FyZCDsl4bsnLzrqbQgZXhhY3QgbWF0Y2hcbiAgICBpZiAoIWtleVBhdHRlcm4uaW5jbHVkZXMoXCIqXCIpKSB7XG4gICAgICBjb25zdCB0cmFjZXMgPSBzdG9yZS5nZXQoa2V5UGF0dGVybikgPz8gW107XG4gICAgICByZXR1cm4gbmV3IE5haXRlUXVlcnkodHJhY2VzKTtcbiAgICB9XG5cbiAgICAvLyB3aWxkY2FyZCDtjKjthLQg66ek7LmtXG4gICAgY29uc3QgYWxsVHJhY2VzOiBOYWl0ZVRyYWNlW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHRyYWNlc10gb2Ygc3RvcmUuZW50cmllcygpKSB7XG4gICAgICBpZiAobWF0Y2hlc1BhdHRlcm4oa2V5LCBrZXlQYXR0ZXJuKSkge1xuICAgICAgICBhbGxUcmFjZXMucHVzaCguLi50cmFjZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgTmFpdGVRdWVyeShhbGxUcmFjZXMpO1xuICB9XG5cbiAgLy8g7KCE7LK0IOumrOyKpO2KuCDqsIDsoLjsmKTquLBcbiAgZ2V0QWxsKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0ge1xuICAgIGNvbnN0IGNvbnRleHQgPSBTb25hbXUuZ2V0Q29udGV4dCgpO1xuICAgIGlmICghY29udGV4dD8ubmFpdGVTdG9yZSkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICAvLyBOYWl0ZVRyYWNlIOuwsOyXtOydhCBkYXRh66eMIOy2lOy2nO2VmOyXrCDrsJjtmZhcbiAgICBjb25zdCByZXN1bHQ6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHRyYWNlc10gb2YgY29udGV4dC5uYWl0ZVN0b3JlLmVudHJpZXMoKSkge1xuICAgICAgaWYgKGtleS5zdGFydHNXaXRoKFwibW9jazpcIikpIHtcbiAgICAgICAgLy8gTW9jayDshKTsoJXsnYAg6re464yA66GcIOuwmO2ZmFxuICAgICAgICByZXN1bHRba2V5XSA9IHRyYWNlcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5haXRlVHJhY2Ug67Cw7Je07J2AIGRhdGHrp4wg7LaU7LacXG4gICAgICAgIHJlc3VsdFtrZXldID0gdHJhY2VzLm1hcCgodDogTmFpdGVUcmFjZSkgPT4gdC5kYXRhKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiDsiqTthqDslrTsl5Ag65Ok7Ja07J6I642YIO2KuOugiOydtOyKpOulvCDqs6DrjIDroZwg6rq864K07Ji164uI64ukLlxuICAgKiDsnbTrlYwg6rCS65Ok7J2AIOuqqOuRkCDsp4HroKztmZQg6rCA64ql7ZWcIOyDge2DnOuhnCDrgpjqsIDqsowg65Cp64uI64ukLlxuICAgKiDthYzsiqTtirgg7KCV67O07JmAIO2VqOq7mCBleHRlbnNpb25z7JeQIOuztOuCvCDsmqnrj4TroZwg66eM65Ok7JeI7Iq164uI64ukLlxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgZ2V0QWxsVHJhY2VzKCk6IHtcbiAgICBrZXk6IHN0cmluZztcbiAgICB2YWx1ZTogYW55O1xuICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgbGluZU51bWJlcjogbnVtYmVyO1xuICAgIGF0OiBzdHJpbmc7XG4gIH1bXSB7XG4gICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgaWYgKCFjb250ZXh0Py5uYWl0ZVN0b3JlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2VzID0gQXJyYXkuZnJvbShjb250ZXh0Lm5haXRlU3RvcmUudmFsdWVzKCkpLmZsYXQoKTtcblxuICAgIC8vIOyngeugrO2ZlCDrtojqsIDriqXtlZwg6rCS7J20IOyhtOyerO2VnOuLpOuptCDsnbTrpbwg64yA66y47Ked66eM7ZWY6rKMIOyVjOugpOykjeuLiOuLpCEg6re47LmY66eMIOyVjOumrOq4sOunjCDtlZjqs6Ag6re464OlIOyngOuCmOqwkeuLiOuLpCDjhY7jhY5cbiAgICAvLyDsmZwg7KeB66Cs7ZmU6rCAIOykkeyalO2VnOqwgD8g7J20KGdldEFsbFRyYWNlcykg7Zi47Lac7J2YIOqysOqzvOuKlCDsmbjrtoDroZwg64KY6rCA6rKMIOuQmOuKlOuNsCxcbiAgICAvLyDsnbTrlYwg7KO8IOyaqeuPhOqwgCB2aXRlc3TsnZggdGFzay5tZXRhIO2VhOuTnOulvCDthrXtlbQgYWZ0ZXJFYWNo7JeQ7IScIFNvbmFtdSBleHRlbnNpb27snLzroZwg7KCE64us7ZWY64qUIOqyg+yeheuLiOuLpC5cbiAgICAvLyDsl6zquLDshJwgbWV0YSDtlYTrk5zsl5Ag64u06ri0IOuCtOyaqeydgCDtlITroZzshLjsiqTqsIQg7Ya17IugKHByb2Nlc3Muc2VuZCkg65iQ64qUIOyKpOugiOuTnOqwhCDthrXsi6AobWVzc2FnZSBwb3J0KeydhCDthrXtlbQg7KCE64us65CY7Ja07JW8IO2VmOuKlOuNsCxcbiAgICAvLyDsnbTroZwg7J247ZW0IFwi7KeB66Cs7ZmUIOqwgOuKpe2VnCDqsJLrk6Trp4wg7ZeI7JqpXCLtlZjripQg7KCc7JW97J20IOyDneq5geuLiOuLpC5cbiAgICAvL1xuICAgIC8vIOydtCDsoJzslb3snYQg7J2Y7Iud7ZWY7JesIE5haXRlLnTsl5Ag7KeB66Cs7ZmUIOqwgOuKpe2VnCDqsJLrp4wg64SY6riw6rKMIO2VoCDsiJjrj4Qg7J6I7JeI7KeA66eMLCDqt7jroIfqsowg7ZWY66m0IOu2iO2OuO2VtOyniCDqsoMg6rCZ7JWE7IScIO2VmOyngCDslYrslZjsirXri4jri6QuXG4gICAgLy8g65Sw65287IScIO2YhOyerCBOYWl0ZS5064qUIOuqqOuToCDqsJLsnYQg67Cb7J2EIOyImCDsnojqsowg65CY7Ja0IOyeiOyKteuLiOuLpC4gXG4gICAgLy8g64yA7IugIOydtOugh+qyjChnZXRBbGxUcmFjZXMpIOq3uCDqsJLrk6TsnYQg67m864K8IOuVjCBKU09OLnN0cmluZ2lmeeulvCDsgqzsmqntlZjsl6wg6rCV7KCc66GcIOyngeugrO2ZlCDqsIDriqXtlZjqsowg66eM65Ok7JeI7Iq164uI64ukLCxcbiAgICBmb3IgKGNvbnN0IHRyYWNlIG9mIHRyYWNlcykge1xuICAgICAgY29uc3QgY2hlY2sgPSBpc1NlcmlhbGl6YWJsZSh0cmFjZS5kYXRhKTtcbiAgICAgIGlmICghY2hlY2sudmFsaWQpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIFwiXFxuXCIgK1xuICAgICAgICAgICAgXCLilZTilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZdcXG5cIiArXG4gICAgICAgICAgICBcIuKVkSAgW05haXRlXSBOb24tc2VyaWFsaXphYmxlIHZhbHVlIGRldGVjdGVkISAgICAgICAgICAgICAgICAgICAgICDilZFcXG5cIiArXG4gICAgICAgICAgICBcIuKVoOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVo1xcblwiICtcbiAgICAgICAgICAgIGDilZEgIEtleTogJHt0cmFjZS5rZXkucGFkRW5kKDU3KX3ilZFcXG5gICtcbiAgICAgICAgICAgIGDilZEgIFJlYXNvbjogJHsoY2hlY2sucmVhc29uID8/IFwidW5rbm93blwiKS5zbGljZSgwLCA1NCkucGFkRW5kKDU0KX3ilZFcXG5gICtcbiAgICAgICAgICAgIGDilZEgIExvY2F0aW9uOiAkeyh0cmFjZS5zdGFja1swXT8uZmlsZVBhdGggPz8gXCJ1bmtub3duXCIpLnNsaWNlKC01MSkucGFkRW5kKDUyKX3ilZFcXG5gICtcbiAgICAgICAgICAgIGDilZEgIExpbmU6ICR7U3RyaW5nKHRyYWNlLnN0YWNrWzBdPy5saW5lTnVtYmVyID8/IDApLnBhZEVuZCg1Nil94pWRXFxuYCArXG4gICAgICAgICAgICBcIuKVoOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVo1xcblwiICtcbiAgICAgICAgICAgIFwi4pWRICBOYWl0ZS50KCkgYWNjZXB0cyBhbnkgdHlwZSBvZiB2YWx1ZS4gSG93ZXZlciwgdmFsdWVzIHdpbGwgICAgIOKVkVxcblwiICtcbiAgICAgICAgICAgIFwi4pWRICBiZSBzZXJpYWxpemVkIHRvIEpTT04gd2hlbiBleHBvcnRlZCB2aWEgTmFpdGUuZ2V0QWxsVHJhY2VzKCkuIOKVkVxcblwiICtcbiAgICAgICAgICAgIFwi4pWa4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWdXFxuXCIsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYWNlcy5tYXAoKHRyYWNlKSA9PiAoe1xuICAgICAga2V5OiB0cmFjZS5rZXksXG4gICAgICB2YWx1ZTogSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0cmFjZS5kYXRhID8/IFwiXCIpKSwgLy8g7KeB66Cs7ZmUIOqwgOuKpe2VnCDqsoPrp4wg64Ko6riw66Ck64qUIOuIiOusvOqyqOyatCDrhbjroKUsLCDslYjqt7jrn6zrqbQgdGFzay5tZXRh7JeQIOuTpOyWtOqwgOyEnCDtlITroZzshLjsiqTqsIQg7Ya17IugIO2VoCDrlYwg66y47KCcIOyDneq4sOqxsOuToOyalCwsXG4gICAgICBmaWxlUGF0aDogdHJhY2Uuc3RhY2tbMF0/LmZpbGVQYXRoID8/IFwiXCIsXG4gICAgICBsaW5lTnVtYmVyOiB0cmFjZS5zdGFja1swXT8ubGluZU51bWJlciA/PyAwLFxuICAgICAgYXQ6IHRyYWNlLmF0LnRvSVNPU3RyaW5nKCksXG4gICAgfSkpO1xuICB9XG5cbiAgLy8g7Yq57KCVIO2CpCDsgq3soJztlZjquLBcbiAgZGVsKGtleTogc3RyaW5nKSB7XG4gICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgaWYgKCFjb250ZXh0Py5uYWl0ZVN0b3JlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnRleHQubmFpdGVTdG9yZS5kZWxldGUoa2V5KTtcbiAgfVxuXG4gIGNyZWF0ZVN0b3JlKCk6IE5haXRlU3RvcmUge1xuICAgIHJldHVybiBuZXcgTWFwPHN0cmluZywgTmFpdGVUcmFjZVtdPigpO1xuICB9XG5cbiAgLy8g7J2867CYIOuhnOq3uCDroIjrsqhcbiAgZChfbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgLy8gVE9ETzogTG9nZ2VyIOyXsOqysFxuICAgIGNvbnNvbGUubG9nKGBbREVCVUddICR7X21lc3NhZ2V9YCk7XG4gIH1cbiAgaShfbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgLy8gVE9ETzogTG9nZ2VyIOyXsOqysFxuICAgIGNvbnNvbGUubG9nKGBbSU5GT10gJHtfbWVzc2FnZX1gKTtcbiAgfVxuICB3KF9tZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAvLyBUT0RPOiBMb2dnZXIg7Jew6rKwXG4gICAgY29uc29sZS5sb2coYFtXQVJOXSAke19tZXNzYWdlfWApO1xuICB9XG4gIGUoX21lc3NhZ2U6IHN0cmluZykge1xuICAgIC8vIFRPRE86IExvZ2dlciDsl7DqsrBcbiAgICBjb25zb2xlLmxvZyhgW0VSUk9SXSAke19tZXNzYWdlfWApO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBOYWl0ZSA9IG5ldyBOYWl0ZUNsYXNzKCk7XG4iXSwibmFtZXMiOlsiZ2V0IiwiU29uYW11IiwiaXNTZXJpYWxpemFibGUiLCJleHRyYWN0Q2FsbFN0YWNrIiwic3RhY2siLCJFcnJvciIsImxpbmVzIiwic3BsaXQiLCJmcmFtZXMiLCJzbGljZSIsIm1hcCIsInBhcnNlU3RhY2tGcmFtZSIsImZpbHRlciIsImZyYW1lIiwiY29udGV4dEluZGV4IiwiZmluZEluZGV4IiwiZiIsImZ1bmN0aW9uTmFtZSIsImluY2x1ZGVzIiwibGluZSIsIm1hdGNoV2l0aEZ1bmMiLCJtYXRjaCIsImZpbGVQYXRoIiwibGluZU51bWJlclN0ciIsImxpbmVOdW1iZXIiLCJOdW1iZXIiLCJwYXJzZUludCIsIm1hdGNoTm9GdW5jIiwibWF0Y2hlc1BhdHRlcm4iLCJrZXkiLCJwYXR0ZXJuIiwia2V5UGFydHMiLCJwYXR0ZXJuUGFydHMiLCJsZW5ndGgiLCJwcmVmaXhQYXJ0cyIsImV2ZXJ5IiwicGFydCIsImkiLCJOYWl0ZVF1ZXJ5IiwidHJhY2VzIiwiZnJvbUZpbGUiLCJmaWxlTmFtZSIsImZpbHRlcmVkIiwidCIsInNvbWUiLCJlbmRzV2l0aCIsImZyb21GdW5jdGlvbiIsImZ1bmNOYW1lIiwib3B0aW9ucyIsImZyb20iLCJ3aGVyZSIsInBhdGgiLCJvcGVyYXRvciIsInZhbHVlIiwidHJhY2UiLCJhY3R1YWwiLCJyZXN1bHQiLCJkYXRhIiwiZmlyc3QiLCJsYXN0IiwiYXQiLCJpbmRleCIsImdldFRyYWNlcyIsIk5haXRlQ2xhc3MiLCJuYW1lIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwiY29udGV4dCIsImdldENvbnRleHQiLCJzdG9yZSIsIm5haXRlU3RvcmUiLCJEYXRlIiwiZXhpc3RpbmciLCJzZXQiLCJrZXlQYXR0ZXJuIiwiYWxsVHJhY2VzIiwiZW50cmllcyIsInB1c2giLCJnZXRBbGwiLCJzdGFydHNXaXRoIiwiZ2V0QWxsVHJhY2VzIiwiQXJyYXkiLCJ2YWx1ZXMiLCJmbGF0IiwiY2hlY2siLCJ2YWxpZCIsImNvbnNvbGUiLCJ3YXJuIiwicGFkRW5kIiwicmVhc29uIiwiU3RyaW5nIiwiSlNPTiIsInBhcnNlIiwic3RyaW5naWZ5IiwidG9JU09TdHJpbmciLCJkZWwiLCJkZWxldGUiLCJjcmVhdGVTdG9yZSIsIk1hcCIsImQiLCJfbWVzc2FnZSIsImxvZyIsInciLCJlIiwiTmFpdGUiXSwibWFwcGluZ3MiOiJBQUFBLGtGQUFrRixHQUVsRixTQUFTQSxHQUFHLFFBQVEsVUFBVTtBQUM5QixTQUFTQyxNQUFNLFFBQVEsbUJBQWdCO0FBRXZDLFNBQVNDLGNBQWMsUUFBUSwyQkFBd0I7QUFvQnZEOzs7OztDQUtDLEdBQ0QsU0FBU0M7SUFDUCxNQUFNQyxRQUFRLElBQUlDLFFBQVFELEtBQUs7SUFDL0IsSUFBSSxDQUFDQSxPQUFPLE9BQU8sRUFBRTtJQUVyQixNQUFNRSxRQUFRRixNQUFNRyxLQUFLLENBQUM7SUFFMUIsVUFBVTtJQUNWLGVBQWU7SUFDZiw2QkFBNkI7SUFDN0Isb0JBQW9CO0lBQ3BCLHFCQUFxQjtJQUNyQixNQUFNQyxTQUFTRixNQUNaRyxLQUFLLENBQUMsR0FDTkMsR0FBRyxDQUFDQyxpQkFDSkMsTUFBTSxDQUFDLENBQUNDLFFBQStCQSxVQUFVO0lBRXBELG9DQUFvQztJQUNwQyxNQUFNQyxlQUFlTixPQUFPTyxTQUFTLENBQ25DLENBQUNDLElBQ0NBLEVBQUVDLFlBQVksRUFBRUMsU0FBUyxxQkFBcUJGLEVBQUVDLFlBQVksRUFBRUMsU0FBUztJQUczRSxPQUFPSixnQkFBZ0IsSUFBSU4sT0FBT0MsS0FBSyxDQUFDLEdBQUdLLGVBQWUsS0FBS047QUFDakU7QUFFQTs7OztDQUlDLEdBQ0QsU0FBU0csZ0JBQWdCUSxJQUFZO0lBQ25DLDREQUE0RDtJQUM1RCxNQUFNQyxnQkFBZ0JELEtBQUtFLEtBQUssQ0FBQztJQUNqQyxJQUFJRCxlQUFlO1FBQ2pCLE1BQU1ILGVBQWVHLGFBQWEs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
|
package/dist/stream/sse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
1
|
+
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
2
|
+
import type { z } from "zod";
|
|
3
3
|
export declare function createSSEFactory<T extends z.ZodObject>(socket: FastifyRequest["socket"], reply: FastifyReply, _events: T): SSEConnection<T>;
|
|
4
4
|
declare class SSEConnection<T extends z.ZodObject> {
|
|
5
5
|
private readonly socket;
|
package/dist/stream/sse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/stream/sse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/stream/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EACpD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,EAChC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,CAAC,oBAGX;AAED,cAAM,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;IAIrC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,OAAO,CAAS;gBAGL,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,EAChC,KAAK,EAAE,YAAY;IAOtC,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAWlE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAa3B"}
|
package/dist/stream/sse.js
CHANGED
|
@@ -35,4 +35,4 @@ class SSEConnection {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
38
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdHJlYW0vc3NlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRmFzdGlmeVJlcGx5LCBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgdHlwZSB7IHogfSBmcm9tIFwiem9kXCI7XG5cbi8vIE5PVEUoSGF6ZSwgMjUxMTA2KTogY29udGV4dCBwcm92aWRlcuyXkOyEnCDsnbjsnpDrpbwg7LGE7JuM7KO866m0IGNyZWF0ZVNTRShldmVudHMp66eM7Jy866GcIOyCrOyaqSDqsIDriqVcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTU0VGYWN0b3J5PFQgZXh0ZW5kcyB6LlpvZE9iamVjdD4oXG4gIHNvY2tldDogRmFzdGlmeVJlcXVlc3RbXCJzb2NrZXRcIl0sXG4gIHJlcGx5OiBGYXN0aWZ5UmVwbHksXG4gIF9ldmVudHM6IFQsXG4pIHtcbiAgcmV0dXJuIG5ldyBTU0VDb25uZWN0aW9uPFQ+KHNvY2tldCwgcmVwbHkpO1xufVxuXG5jbGFzcyBTU0VDb25uZWN0aW9uPFQgZXh0ZW5kcyB6LlpvZE9iamVjdD4ge1xuICBwcml2YXRlIF9jbG9zZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNvY2tldDogRmFzdGlmeVJlcXVlc3RbXCJzb2NrZXRcIl0sXG4gICAgcHJpdmF0ZSByZWFkb25seSByZXBseTogRmFzdGlmeVJlcGx5LFxuICApIHtcbiAgICB0aGlzLnNvY2tldC5vbihcImNsb3NlXCIsICgpID0+IHtcbiAgICAgIHRoaXMuX2Nsb3NlZCA9IHRydWU7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaXNoPEsgZXh0ZW5kcyBrZXlvZiB6LmluZmVyPFQ+PihldmVudDogSywgZGF0YTogei5pbmZlcjxUPltLXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9jbG9zZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJlcGx5LnNzZSh7XG4gICAgICBldmVudDogZXZlbnQgYXMgc3RyaW5nLFxuICAgICAgZGF0YTogSlNPTi5zdHJpbmdpZnkoZGF0YSksXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBlbmQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuX2Nsb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucmVwbHkuc3NlKHtcbiAgICAgIGV2ZW50OiBcImVuZFwiLFxuICAgICAgZGF0YTogXCJFTkRcIixcbiAgICB9KTtcblxuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDIwMCkpO1xuICAgIHRoaXMucmVwbHkucmF3LmVuZCgpO1xuICB9XG59XG4iXSwibmFtZXMiOlsiY3JlYXRlU1NFRmFjdG9yeSIsInNvY2tldCIsInJlcGx5IiwiX2V2ZW50cyIsIlNTRUNvbm5lY3Rpb24iLCJfY2xvc2VkIiwib24iLCJwdWJsaXNoIiwiZXZlbnQiLCJkYXRhIiwic3NlIiwiSlNPTiIsInN0cmluZ2lmeSIsImVuZCIsIlByb21pc2UiLCJyZXNvbHZlIiwic2V0VGltZW91dCIsInJhdyJdLCJtYXBwaW5ncyI6IkFBR0EsNkVBQTZFO0FBQzdFLE9BQU8sU0FBU0EsaUJBQ2RDLE1BQWdDLEVBQ2hDQyxLQUFtQixFQUNuQkMsT0FBVTtJQUVWLE9BQU8sSUFBSUMsY0FBaUJILFFBQVFDO0FBQ3RDO0FBRUEsTUFBTUU7OztJQUNJQyxVQUFVLE1BQU07SUFFeEIsWUFDRSxBQUFpQkosTUFBZ0MsRUFDakQsQUFBaUJDLEtBQW1CLENBQ3BDO2FBRmlCRCxTQUFBQTthQUNBQyxRQUFBQTtRQUVqQixJQUFJLENBQUNELE1BQU0sQ0FBQ0ssRUFBRSxDQUFDLFNBQVM7WUFDdEIsSUFBSSxDQUFDRCxPQUFPLEdBQUc7UUFDakI7SUFDRjtJQUVBRSxRQUFvQ0MsS0FBUSxFQUFFQyxJQUFtQixFQUFRO1FBQ3ZFLElBQUksSUFBSSxDQUFDSixPQUFPLEVBQUU7WUFDaEI7UUFDRjtRQUVBLElBQUksQ0FBQ0gsS0FBSyxDQUFDUSxHQUFHLENBQUM7WUFDYkYsT0FBT0E7WUFDUEMsTUFBTUUsS0FBS0MsU0FBUyxDQUFDSDtRQUN2QjtJQUNGO0lBRUEsTUFBTUksTUFBcUI7UUFDekIsSUFBSSxJQUFJLENBQUNSLE9BQU8sRUFBRTtZQUNoQjtRQUNGO1FBRUEsSUFBSSxDQUFDSCxLQUFLLENBQUNRLEdBQUcsQ0FBQztZQUNiRixPQUFPO1lBQ1BDLE1BQU07UUFDUjtRQUVBLE1BQU0sSUFBSUssUUFBUSxDQUFDQyxVQUFZQyxXQUFXRCxTQUFTO1FBQ25ELElBQUksQ0FBQ2IsS0FBSyxDQUFDZSxHQUFHLENBQUNKLEdBQUc7SUFDcEI7QUFDRiJ9
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { AbsolutePath } from "../utils/path-utils";
|
|
1
|
+
import { type ExtendedApi } from "../api/decorators";
|
|
2
|
+
import type { AbsolutePath } from "../utils/path-utils";
|
|
3
3
|
/**
|
|
4
4
|
* TypeScript 파일을 파싱하여 API 메소드 정보를 추출합니다.
|
|
5
5
|
* @api 데코레이터가 붙은 메소드들의 타입 정보를 분석합니다.
|
|
6
6
|
* @param filePath - 파싱할 TypeScript 파일의 절대 경로
|
|
7
7
|
* @returns API 메소드 정보 배열 (타입 파라미터, 파라미터, 리턴 타입 등)
|
|
8
8
|
*/
|
|
9
|
-
export declare function readApisFromFile(filePath: AbsolutePath): Promise<
|
|
10
|
-
typeParameters: ApiParamType.TypeParam[];
|
|
11
|
-
parameters: ApiParam[];
|
|
12
|
-
returnType: ApiParamType;
|
|
13
|
-
modelName: string;
|
|
14
|
-
methodName: string;
|
|
15
|
-
path: string;
|
|
16
|
-
options: import("..").ApiDecoratorOptions;
|
|
17
|
-
streamOptions?: import("..").StreamDecoratorOptions;
|
|
18
|
-
uploadOptions?: import("..").UploadDecoratorOptions;
|
|
19
|
-
}[]>;
|
|
9
|
+
export declare function readApisFromFile(filePath: AbsolutePath): Promise<ExtendedApi[]>;
|
|
20
10
|
//# sourceMappingURL=api-parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-parser.d.ts","sourceRoot":"","sources":["../../src/syncer/api-parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api-parser.d.ts","sourceRoot":"","sources":["../../src/syncer/api-parser.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAGrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAwGrF"}
|