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
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ProviderOptions, Schema, Tool } from "@ai-sdk/provider-utils";
|
|
2
|
+
import type { LanguageModel, StopCondition, ToolSet } from "ai";
|
|
3
|
+
|
|
4
|
+
export type ToolChoiceLimited = "auto" | "none" | "required";
|
|
5
|
+
|
|
6
|
+
export interface ToolDecoratorSchema<INPUT, OUTPUT = unknown> {
|
|
7
|
+
input: Schema<INPUT>;
|
|
8
|
+
output?: Schema<OUTPUT>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ToolDecoratorOptions<INPUT, OUTPUT = unknown> {
|
|
12
|
+
name?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
schema: ToolDecoratorSchema<INPUT, OUTPUT>;
|
|
15
|
+
needsApproval?: Tool<INPUT, OUTPUT>["needsApproval"];
|
|
16
|
+
toModelOutput?: Tool<INPUT, OUTPUT>["toModelOutput"];
|
|
17
|
+
providerOptions?: ProviderOptions;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type RegisteredToolDefinition = {
|
|
21
|
+
name: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
schema: ToolDecoratorSchema<unknown, unknown>;
|
|
24
|
+
needsApproval?: Tool["needsApproval"];
|
|
25
|
+
toModelOutput?: Tool["toModelOutput"];
|
|
26
|
+
providerOptions?: ProviderOptions;
|
|
27
|
+
method: (...args: unknown[]) => unknown;
|
|
28
|
+
from: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface AgentConfig {
|
|
32
|
+
model: LanguageModel;
|
|
33
|
+
instructions?: string;
|
|
34
|
+
toolChoice?: ToolChoiceLimited;
|
|
35
|
+
providerOptions?: ProviderOptions;
|
|
36
|
+
stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;
|
|
37
|
+
activeTools?: Array<string>;
|
|
38
|
+
maxOutputTokens?: number;
|
|
39
|
+
temperature?: number;
|
|
40
|
+
topP?: number;
|
|
41
|
+
topK?: number;
|
|
42
|
+
presencePenalty?: number;
|
|
43
|
+
frequencyPenalty?: number;
|
|
44
|
+
stopSequences?: string[];
|
|
45
|
+
seed?: number;
|
|
46
|
+
headers?: Record<string, string | undefined>;
|
|
47
|
+
}
|
package/src/ai/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./agents";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const rtzrAuthResponseSchema = z.object({
|
|
5
|
+
access_token: z.string(),
|
|
6
|
+
expire_at: z.number(),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const rtzrTranscriptionResponseSchema = lazySchema(() =>
|
|
10
|
+
zodSchema(
|
|
11
|
+
z.object({
|
|
12
|
+
id: z.string(),
|
|
13
|
+
}),
|
|
14
|
+
),
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export const rtzrTranscriptionResultResponseSchema = lazySchema(() =>
|
|
18
|
+
zodSchema(
|
|
19
|
+
z.object({
|
|
20
|
+
id: z.string(),
|
|
21
|
+
status: z.enum(["transcribing", "completed", "failed"]),
|
|
22
|
+
results: z
|
|
23
|
+
.object({
|
|
24
|
+
utterances: z.array(
|
|
25
|
+
z.object({
|
|
26
|
+
start_at: z.number(),
|
|
27
|
+
duration: z.number(),
|
|
28
|
+
msg: z.string(),
|
|
29
|
+
spk: z.number(),
|
|
30
|
+
lang: z.string().optional(),
|
|
31
|
+
}),
|
|
32
|
+
),
|
|
33
|
+
})
|
|
34
|
+
.nullish(),
|
|
35
|
+
}),
|
|
36
|
+
),
|
|
37
|
+
);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AISDKError } from "@ai-sdk/provider";
|
|
2
|
+
import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
export const rtzrErrorDataSchema = z.object({
|
|
6
|
+
error: z.object({
|
|
7
|
+
msg: z.string(),
|
|
8
|
+
type: z.string().nullish(),
|
|
9
|
+
param: z.any().nullish(),
|
|
10
|
+
code: z.union([z.string(), z.number()]).nullish(),
|
|
11
|
+
}),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type RtzrErrorData = z.infer<typeof rtzrErrorDataSchema>;
|
|
15
|
+
|
|
16
|
+
export const rtzrFailedResponseHandler = createJsonErrorResponseHandler({
|
|
17
|
+
errorSchema: rtzrErrorDataSchema,
|
|
18
|
+
errorToMessage: (data) => data.error.msg,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export class RtzrClientError extends AISDKError {
|
|
22
|
+
constructor(
|
|
23
|
+
message: string,
|
|
24
|
+
options?: {
|
|
25
|
+
cause?: Error;
|
|
26
|
+
},
|
|
27
|
+
) {
|
|
28
|
+
super({
|
|
29
|
+
name: "RtzrClientError",
|
|
30
|
+
message,
|
|
31
|
+
cause: options?.cause,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SharedV3Warning,
|
|
3
|
+
TranscriptionModelV3,
|
|
4
|
+
TranscriptionModelV3CallOptions,
|
|
5
|
+
} from "@ai-sdk/provider";
|
|
6
|
+
import {
|
|
7
|
+
combineHeaders,
|
|
8
|
+
convertBase64ToUint8Array,
|
|
9
|
+
createJsonResponseHandler,
|
|
10
|
+
type FetchFunction,
|
|
11
|
+
getFromApi,
|
|
12
|
+
mediaTypeToExtension,
|
|
13
|
+
parseProviderOptions,
|
|
14
|
+
postFormDataToApi,
|
|
15
|
+
} from "@ai-sdk/provider-utils";
|
|
16
|
+
import { isEmpty } from "radashi";
|
|
17
|
+
import {
|
|
18
|
+
rtzrAuthResponseSchema,
|
|
19
|
+
rtzrTranscriptionResponseSchema,
|
|
20
|
+
rtzrTranscriptionResultResponseSchema,
|
|
21
|
+
} from "./api";
|
|
22
|
+
import { RtzrClientError, rtzrFailedResponseHandler } from "./error";
|
|
23
|
+
import {
|
|
24
|
+
type RtzrTranscriptionModelId,
|
|
25
|
+
type RtzrTranscriptionProviderOptions,
|
|
26
|
+
rtzrTranscriptionProviderOptions,
|
|
27
|
+
} from "./options";
|
|
28
|
+
|
|
29
|
+
export type RtzrTranscriptionCallOptions = Omit<
|
|
30
|
+
TranscriptionModelV3CallOptions,
|
|
31
|
+
"providerOptions"
|
|
32
|
+
> & {
|
|
33
|
+
providerOptions?: {
|
|
34
|
+
rtzr?: RtzrTranscriptionProviderOptions;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
interface RtzrTranscriptionModelConfig {
|
|
39
|
+
_internal?: {
|
|
40
|
+
currentDate?: () => Date;
|
|
41
|
+
};
|
|
42
|
+
provider: string;
|
|
43
|
+
auth: {
|
|
44
|
+
clientId: string;
|
|
45
|
+
clientSecret: string;
|
|
46
|
+
};
|
|
47
|
+
url: (options: { path: string }) => string;
|
|
48
|
+
headers: () => Record<string, string | undefined>;
|
|
49
|
+
fetch?: FetchFunction;
|
|
50
|
+
generateId?: () => string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class RtzrTranscriptionModel implements TranscriptionModelV3 {
|
|
54
|
+
readonly specificationVersion = "v3";
|
|
55
|
+
|
|
56
|
+
get provider(): string {
|
|
57
|
+
return this.config.provider;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
constructor(
|
|
61
|
+
readonly modelId: RtzrTranscriptionModelId,
|
|
62
|
+
private readonly config: RtzrTranscriptionModelConfig,
|
|
63
|
+
) {}
|
|
64
|
+
|
|
65
|
+
private async authorize() {
|
|
66
|
+
const fetchApi = this.config.fetch ?? fetch;
|
|
67
|
+
const response = await fetchApi(
|
|
68
|
+
this.config.url({
|
|
69
|
+
path: "/authenticate",
|
|
70
|
+
}),
|
|
71
|
+
{
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
75
|
+
},
|
|
76
|
+
body: new URLSearchParams({
|
|
77
|
+
client_id: this.config.auth.clientId,
|
|
78
|
+
client_secret: this.config.auth.clientSecret,
|
|
79
|
+
}),
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new RtzrClientError(`Failed to authorize: ${response.status}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const data = await response.json();
|
|
88
|
+
const parsedData = rtzrAuthResponseSchema.safeParse(data);
|
|
89
|
+
if (!parsedData.success) {
|
|
90
|
+
throw new RtzrClientError(`Validation failed: ${parsedData.error.message}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return parsedData.data.access_token;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private async getArgs({ audio, mediaType, providerOptions }: RtzrTranscriptionCallOptions) {
|
|
97
|
+
const warnings: SharedV3Warning[] = [];
|
|
98
|
+
const rtzrOptions = await parseProviderOptions({
|
|
99
|
+
provider: "rtzr",
|
|
100
|
+
providerOptions,
|
|
101
|
+
schema: rtzrTranscriptionProviderOptions,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const blob =
|
|
105
|
+
audio instanceof Uint8Array
|
|
106
|
+
? new Blob([new Uint8Array(audio)])
|
|
107
|
+
: new Blob([convertBase64ToUint8Array(audio)]);
|
|
108
|
+
|
|
109
|
+
const formData = new FormData();
|
|
110
|
+
const fileExtension = mediaTypeToExtension(mediaType);
|
|
111
|
+
formData.append(
|
|
112
|
+
"file",
|
|
113
|
+
new File([blob], "audio", { type: mediaType }),
|
|
114
|
+
`audio.${fileExtension}`,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const config = { model_name: this.modelId, ...rtzrOptions };
|
|
118
|
+
formData.append("config", JSON.stringify(config));
|
|
119
|
+
|
|
120
|
+
return { formData, warnings };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async doGenerate(options: RtzrTranscriptionCallOptions) {
|
|
124
|
+
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
125
|
+
|
|
126
|
+
const accessToken = await this.authorize();
|
|
127
|
+
const headers = {
|
|
128
|
+
Authorization: `Bearer ${accessToken}`,
|
|
129
|
+
...options.headers,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const { formData, warnings } = await this.getArgs(options);
|
|
133
|
+
const {
|
|
134
|
+
value: { id: transcriptionId },
|
|
135
|
+
responseHeaders,
|
|
136
|
+
} = await postFormDataToApi({
|
|
137
|
+
url: this.config.url({
|
|
138
|
+
path: "/transcribe",
|
|
139
|
+
}),
|
|
140
|
+
headers: combineHeaders(this.config.headers(), headers),
|
|
141
|
+
formData,
|
|
142
|
+
failedResponseHandler: rtzrFailedResponseHandler,
|
|
143
|
+
successfulResponseHandler: createJsonResponseHandler(rtzrTranscriptionResponseSchema),
|
|
144
|
+
abortSignal: options.abortSignal,
|
|
145
|
+
fetch: this.config.fetch,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const { value: response, rawValue } = await (async () => {
|
|
149
|
+
// transcription이 끝날 떄까지 0.5초마다 체크.
|
|
150
|
+
// timeout을 따로 지정하지 않는 이유는 애초에 AbortSignal을 사용하고 있음.
|
|
151
|
+
while (true) {
|
|
152
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
153
|
+
const data = await getFromApi({
|
|
154
|
+
url: this.config.url({
|
|
155
|
+
path: `/transcribe/${transcriptionId}`,
|
|
156
|
+
}),
|
|
157
|
+
headers: combineHeaders(this.config.headers(), headers),
|
|
158
|
+
failedResponseHandler: rtzrFailedResponseHandler,
|
|
159
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
160
|
+
rtzrTranscriptionResultResponseSchema,
|
|
161
|
+
),
|
|
162
|
+
abortSignal: options.abortSignal,
|
|
163
|
+
fetch: this.config.fetch,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (data.value.status !== "transcribing") {
|
|
167
|
+
return data;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
})();
|
|
171
|
+
|
|
172
|
+
const segments = response.results?.utterances ?? [];
|
|
173
|
+
|
|
174
|
+
const languages = new Set(segments.map((item) => item.lang).filter((item) => !isEmpty(item)));
|
|
175
|
+
const language = (() => {
|
|
176
|
+
if (languages.size > 1) {
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return languages.values().next().value;
|
|
181
|
+
})();
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
text: segments.map((item) => item.msg).join("\n"),
|
|
185
|
+
segments: segments.map((segment) => ({
|
|
186
|
+
text: segment.msg,
|
|
187
|
+
startSecond: Math.trunc(segment.start_at / 1000),
|
|
188
|
+
endSecond: Math.trunc((segment.start_at + segment.duration) / 1000),
|
|
189
|
+
})),
|
|
190
|
+
language,
|
|
191
|
+
warnings,
|
|
192
|
+
durationInSeconds: segments.reduce((acc, segment) => acc + segment.duration, 0) ?? undefined,
|
|
193
|
+
response: {
|
|
194
|
+
timestamp: currentDate,
|
|
195
|
+
modelId: this.modelId,
|
|
196
|
+
headers: responseHeaders,
|
|
197
|
+
body: rawValue,
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type InferSchema, lazySchema, zodSchema } from "@ai-sdk/provider-utils";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export type RtzrTranscriptionModelId = "whisper" | "sommers" | (string & {});
|
|
5
|
+
|
|
6
|
+
const rtzrOptionsShape = {
|
|
7
|
+
domain: z.enum(["CALL", "GENERAL"]).default("GENERAL"),
|
|
8
|
+
language: z.string(),
|
|
9
|
+
languageCandidates: z.array(z.string()).optional(),
|
|
10
|
+
keywords: z.union([z.string(), z.array(z.string())]).optional(),
|
|
11
|
+
paragraphSplitterMax: z.number().optional(),
|
|
12
|
+
diarization: z.boolean().optional(),
|
|
13
|
+
itn: z.boolean().optional(),
|
|
14
|
+
diarizationSpkCount: z.number().optional(),
|
|
15
|
+
disfluencyFilter: z.boolean().optional(),
|
|
16
|
+
paragraphSplitter: z.boolean().optional(),
|
|
17
|
+
profanityFilter: z.boolean().optional(),
|
|
18
|
+
wordTimestamp: z.boolean().optional(),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const rtzrOptionsMap: Record<keyof typeof rtzrOptionsShape, string> = {
|
|
22
|
+
domain: "domain",
|
|
23
|
+
language: "language",
|
|
24
|
+
languageCandidates: "language_candidates",
|
|
25
|
+
keywords: "keywords",
|
|
26
|
+
paragraphSplitterMax: "paragraph_splitter.max",
|
|
27
|
+
diarization: "use_diarization",
|
|
28
|
+
itn: "use_itn",
|
|
29
|
+
diarizationSpkCount: "diarization.spk_count",
|
|
30
|
+
disfluencyFilter: "use_disfluency_filter",
|
|
31
|
+
paragraphSplitter: "use_paragraph_splitter",
|
|
32
|
+
profanityFilter: "use_profanity_filter",
|
|
33
|
+
wordTimestamp: "use_word_timestamp",
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// https://developers.rtzr.ai/docs/stt-file/
|
|
37
|
+
export const rtzrTranscriptionProviderOptions = lazySchema(() =>
|
|
38
|
+
zodSchema(
|
|
39
|
+
z.object(rtzrOptionsShape).transform((item) => {
|
|
40
|
+
return Object.fromEntries(
|
|
41
|
+
Object.entries(item).map(([key, value]) => {
|
|
42
|
+
return [rtzrOptionsMap[key as keyof typeof rtzrOptionsShape], value];
|
|
43
|
+
}),
|
|
44
|
+
);
|
|
45
|
+
}),
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export type RtzrTranscriptionProviderOptions = InferSchema<typeof rtzrTranscriptionProviderOptions>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { NoSuchModelError, type ProviderV3, type TranscriptionModelV3 } from "@ai-sdk/provider";
|
|
2
|
+
import {
|
|
3
|
+
type FetchFunction,
|
|
4
|
+
loadApiKey,
|
|
5
|
+
loadOptionalSetting,
|
|
6
|
+
withoutTrailingSlash,
|
|
7
|
+
withUserAgentSuffix,
|
|
8
|
+
} from "@ai-sdk/provider-utils";
|
|
9
|
+
import { RtzrTranscriptionModel } from "./model";
|
|
10
|
+
import type { RtzrTranscriptionModelId } from "./options";
|
|
11
|
+
|
|
12
|
+
export interface RtzrProvider extends ProviderV3 {
|
|
13
|
+
(modelId: RtzrTranscriptionModelId): TranscriptionModelV3;
|
|
14
|
+
transcription(modelId: RtzrTranscriptionModelId): TranscriptionModelV3;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface RtzrProviderSettings {
|
|
18
|
+
baseURL?: string;
|
|
19
|
+
clientId?: string;
|
|
20
|
+
clientSecret?: string;
|
|
21
|
+
headers?: Record<string, string>;
|
|
22
|
+
name?: string;
|
|
23
|
+
fetch?: FetchFunction;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function createRtzr(options: RtzrProviderSettings = {}): RtzrProvider {
|
|
27
|
+
const baseURL =
|
|
28
|
+
withoutTrailingSlash(
|
|
29
|
+
loadOptionalSetting({
|
|
30
|
+
settingValue: options.baseURL,
|
|
31
|
+
environmentVariableName: "RTZR_BASE_URL",
|
|
32
|
+
}),
|
|
33
|
+
) ?? "https://openapi.vito.ai/v1";
|
|
34
|
+
|
|
35
|
+
const providerName = options.name ?? "rtzr";
|
|
36
|
+
|
|
37
|
+
const getHeaders = () =>
|
|
38
|
+
withUserAgentSuffix(
|
|
39
|
+
{
|
|
40
|
+
...options.headers,
|
|
41
|
+
},
|
|
42
|
+
`cartanova-ai/rtzr-api-provider`,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const createTranscriptionModel = (modelId: RtzrTranscriptionModelId) => {
|
|
46
|
+
const clientId = loadApiKey({
|
|
47
|
+
apiKey: options.clientId,
|
|
48
|
+
environmentVariableName: "RTZR_CLIENT_ID",
|
|
49
|
+
description: "RTZR",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const clientSecret = loadApiKey({
|
|
53
|
+
apiKey: options.clientSecret,
|
|
54
|
+
environmentVariableName: "RTZR_CLIENT_SECRET",
|
|
55
|
+
description: "RTZR",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return new RtzrTranscriptionModel(modelId, {
|
|
59
|
+
provider: `${providerName}.transcription`,
|
|
60
|
+
auth: {
|
|
61
|
+
clientId,
|
|
62
|
+
clientSecret,
|
|
63
|
+
},
|
|
64
|
+
url: ({ path }) => `${baseURL}${path}`,
|
|
65
|
+
headers: getHeaders,
|
|
66
|
+
fetch: options.fetch,
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const provider = (modelId: RtzrTranscriptionModelId) => createTranscriptionModel(modelId);
|
|
71
|
+
|
|
72
|
+
provider.specificationVersion = "v3" as const;
|
|
73
|
+
provider.transcription = createTranscriptionModel;
|
|
74
|
+
provider.transcriptionModel = createTranscriptionModel;
|
|
75
|
+
|
|
76
|
+
const handleUnsupportedTypes = (modelType: "languageModel" | "embeddingModel" | "imageModel") => {
|
|
77
|
+
return (modelId: string) => {
|
|
78
|
+
throw new NoSuchModelError({
|
|
79
|
+
modelId,
|
|
80
|
+
modelType,
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
provider.languageModel = handleUnsupportedTypes("languageModel");
|
|
86
|
+
provider.embeddingModel = handleUnsupportedTypes("embeddingModel");
|
|
87
|
+
provider.imageModel = handleUnsupportedTypes("imageModel");
|
|
88
|
+
return provider as RtzrProvider;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const rtzr = createRtzr();
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { APICallError } from "@ai-sdk/provider";
|
|
2
|
+
import {
|
|
3
|
+
extractResponseHeaders,
|
|
4
|
+
type FetchFunction,
|
|
5
|
+
isAbortError,
|
|
6
|
+
type ResponseHandler,
|
|
7
|
+
withUserAgentSuffix,
|
|
8
|
+
} from "@ai-sdk/provider-utils";
|
|
9
|
+
|
|
10
|
+
const FETCH_FAILED_ERROR_MESSAGES = ["fetch failed", "failed to fetch"];
|
|
11
|
+
|
|
12
|
+
export function handleFetchError({
|
|
13
|
+
error,
|
|
14
|
+
url,
|
|
15
|
+
requestBodyValues,
|
|
16
|
+
}: {
|
|
17
|
+
error: unknown;
|
|
18
|
+
url: string;
|
|
19
|
+
requestBodyValues: unknown;
|
|
20
|
+
}) {
|
|
21
|
+
if (isAbortError(error)) {
|
|
22
|
+
return error;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (
|
|
26
|
+
error instanceof TypeError &&
|
|
27
|
+
FETCH_FAILED_ERROR_MESSAGES.includes(error.message.toLowerCase())
|
|
28
|
+
) {
|
|
29
|
+
const cause = (error as { cause?: Error }).cause;
|
|
30
|
+
|
|
31
|
+
if (cause != null) {
|
|
32
|
+
return new APICallError({
|
|
33
|
+
message: `Cannot connect to API: ${cause.message}`,
|
|
34
|
+
cause,
|
|
35
|
+
url,
|
|
36
|
+
requestBodyValues,
|
|
37
|
+
isRetryable: true, // retry when network error
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return error;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// use function to allow for mocking in tests:
|
|
46
|
+
const getOriginalFetch = () => globalThis.fetch;
|
|
47
|
+
|
|
48
|
+
export const getFromApi = async <T>({
|
|
49
|
+
url,
|
|
50
|
+
headers = {},
|
|
51
|
+
successfulResponseHandler,
|
|
52
|
+
failedResponseHandler,
|
|
53
|
+
abortSignal,
|
|
54
|
+
fetch = getOriginalFetch(),
|
|
55
|
+
}: {
|
|
56
|
+
url: string;
|
|
57
|
+
headers?: Record<string, string | undefined>;
|
|
58
|
+
failedResponseHandler: ResponseHandler<Error>;
|
|
59
|
+
successfulResponseHandler: ResponseHandler<T>;
|
|
60
|
+
abortSignal?: AbortSignal;
|
|
61
|
+
fetch?: FetchFunction;
|
|
62
|
+
}) => {
|
|
63
|
+
try {
|
|
64
|
+
const response = await fetch(url, {
|
|
65
|
+
method: "GET",
|
|
66
|
+
headers: withUserAgentSuffix(headers, `cartanova-ai/rtzr-api-provider`),
|
|
67
|
+
signal: abortSignal,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const responseHeaders = extractResponseHeaders(response);
|
|
71
|
+
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
let errorInformation: {
|
|
74
|
+
value: Error;
|
|
75
|
+
responseHeaders?: Record<string, string> | undefined;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
errorInformation = await failedResponseHandler({
|
|
80
|
+
response,
|
|
81
|
+
url,
|
|
82
|
+
requestBodyValues: {},
|
|
83
|
+
});
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (isAbortError(error) || APICallError.isInstance(error)) {
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
throw new APICallError({
|
|
90
|
+
message: "Failed to process error response",
|
|
91
|
+
cause: error,
|
|
92
|
+
statusCode: response.status,
|
|
93
|
+
url,
|
|
94
|
+
responseHeaders,
|
|
95
|
+
requestBodyValues: {},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
throw errorInformation.value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
return await successfulResponseHandler({
|
|
104
|
+
response,
|
|
105
|
+
url,
|
|
106
|
+
requestBodyValues: {},
|
|
107
|
+
});
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (error instanceof Error) {
|
|
110
|
+
if (isAbortError(error) || APICallError.isInstance(error)) {
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
throw new APICallError({
|
|
116
|
+
message: "Failed to process successful response",
|
|
117
|
+
cause: error,
|
|
118
|
+
statusCode: response.status,
|
|
119
|
+
url,
|
|
120
|
+
responseHeaders,
|
|
121
|
+
requestBodyValues: {},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
throw handleFetchError({ error, url, requestBodyValues: {} });
|
|
126
|
+
}
|
|
127
|
+
};
|
package/src/api/base-frame.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { Knex } from "knex";
|
|
2
|
-
import {
|
|
1
|
+
import type { Knex } from "knex";
|
|
2
|
+
import type { DBPreset } from "../database/db";
|
|
3
|
+
// Static imports kept for non-async functions (getDB, getUpsertBuilder)
|
|
4
|
+
import { DB } from "../database/db";
|
|
3
5
|
import { UpsertBuilder } from "../database/upsert-builder";
|
|
4
6
|
|
|
5
7
|
export abstract class BaseFrameClass {
|
package/src/api/caster.ts
CHANGED
|
@@ -25,6 +25,7 @@ function isZodNumberAnyway(zodType: $ZodType) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// ZodType을 이용해 raw를 Type Coercing
|
|
28
|
+
// biome-ignore lint/suspicious/noExplicitAny: 캐스팅에는 any가 필요함.
|
|
28
29
|
export function caster(zodType: $ZodType, raw: any): any {
|
|
29
30
|
if (isZodNumberAnyway(zodType) && typeof raw === "string") {
|
|
30
31
|
// number
|
|
@@ -35,45 +36,36 @@ export function caster(zodType: $ZodType, raw: any): any {
|
|
|
35
36
|
) {
|
|
36
37
|
// zArrayable Number 케이스 처리
|
|
37
38
|
if (Array.isArray(raw)) {
|
|
38
|
-
const numType = zodType.options.find(opt => isNumberType(opt));
|
|
39
|
+
const numType = zodType.options.find((opt) => isNumberType(opt));
|
|
39
40
|
assert(numType !== undefined);
|
|
41
|
+
// biome-ignore lint/suspicious/noExplicitAny: 캐스팅에는 any가 필요함.
|
|
40
42
|
return raw.map((elem: any) => caster(numType, elem));
|
|
41
43
|
} else {
|
|
42
44
|
return Number(raw);
|
|
43
45
|
}
|
|
44
|
-
} else if (
|
|
45
|
-
zodType instanceof z.ZodBoolean &&
|
|
46
|
-
(raw === "true" || raw === "false")
|
|
47
|
-
) {
|
|
46
|
+
} else if (zodType instanceof z.ZodBoolean && (raw === "true" || raw === "false")) {
|
|
48
47
|
// boolean
|
|
49
48
|
return raw === "true";
|
|
50
|
-
} else if (
|
|
51
|
-
raw !== null &&
|
|
52
|
-
Array.isArray(raw) &&
|
|
53
|
-
zodType instanceof z.ZodArray
|
|
54
|
-
) {
|
|
49
|
+
} else if (raw !== null && Array.isArray(raw) && zodType instanceof z.ZodArray) {
|
|
55
50
|
// array
|
|
51
|
+
// biome-ignore lint/suspicious/noExplicitAny: 캐스팅에는 any가 필요함.
|
|
56
52
|
return raw.map((elem: any) => caster(zodType.element, elem));
|
|
57
|
-
} else if (
|
|
58
|
-
zodType instanceof z.ZodObject &&
|
|
59
|
-
typeof raw === "object" &&
|
|
60
|
-
raw !== null
|
|
61
|
-
) {
|
|
53
|
+
} else if (zodType instanceof z.ZodObject && typeof raw === "object" && raw !== null) {
|
|
62
54
|
// object
|
|
63
|
-
return Object.keys(raw).reduce(
|
|
64
|
-
r
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
return Object.keys(raw).reduce(
|
|
56
|
+
(r, rawKey) => {
|
|
57
|
+
r[rawKey] = caster(zodType.shape[rawKey], raw[rawKey]);
|
|
58
|
+
return r;
|
|
59
|
+
},
|
|
60
|
+
{} as Record<string, unknown>,
|
|
61
|
+
);
|
|
67
62
|
} else if (zodType instanceof z.ZodOptional) {
|
|
68
63
|
// optional
|
|
69
64
|
return caster(zodType.def.innerType, raw);
|
|
70
65
|
} else if (zodType instanceof z.ZodNullable) {
|
|
71
66
|
// nullable
|
|
72
67
|
return caster(zodType.def.innerType, raw);
|
|
73
|
-
} else if (
|
|
74
|
-
zodType instanceof z.ZodDate &&
|
|
75
|
-
new Date(raw).toString() !== "Invalid Date"
|
|
76
|
-
) {
|
|
68
|
+
} else if (zodType instanceof z.ZodDate && new Date(raw).toString() !== "Invalid Date") {
|
|
77
69
|
// date
|
|
78
70
|
return new Date(raw);
|
|
79
71
|
} else {
|
|
@@ -82,7 +74,9 @@ export function caster(zodType: $ZodType, raw: any): any {
|
|
|
82
74
|
}
|
|
83
75
|
}
|
|
84
76
|
|
|
77
|
+
// biome-ignore lint/suspicious/noExplicitAny: 캐스팅에는 any가 필요함.
|
|
85
78
|
export function fastifyCaster(schema: z.ZodObject<any>) {
|
|
79
|
+
// biome-ignore lint/suspicious/noExplicitAny: 캐스팅에는 any가 필요함.
|
|
86
80
|
return z.preprocess((raw: any) => {
|
|
87
81
|
return caster(schema, raw);
|
|
88
82
|
}, schema);
|