@tailor-platform/sdk 2.0.0-next.1 → 2.0.0-next.11
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/CHANGELOG.md +1056 -24
- package/README.md +9 -9
- package/agent-skills/{tailor-sdk → tailor}/SKILL.md +3 -1
- package/dist/aigateway-DR4Kwuik.mjs +9 -0
- package/dist/aigateway-DR4Kwuik.mjs.map +1 -0
- package/dist/{application-DqS1yBg3.mjs → application-CM6hKnSK.mjs} +2155 -2008
- package/dist/application-CM6hKnSK.mjs.map +1 -0
- package/dist/application-CXNaUNhv.mjs +3 -0
- package/dist/authconnection-CZvi9ANm.mjs +9 -0
- package/dist/authconnection-CZvi9ANm.mjs.map +1 -0
- package/dist/brand-Eo4pLXPJ.mjs.map +1 -1
- package/dist/cli/cache/bundle-cache.d.mts +2 -0
- package/dist/cli/cache/store.d.mts +1 -0
- package/dist/cli/cache/types.d.mts +1 -0
- package/dist/cli/commands/api/api-call.d.mts +19 -0
- package/dist/cli/commands/api/index.d.mts +4 -0
- package/dist/cli/commands/deploy/aigateway.d.mts +5 -0
- package/dist/cli/commands/deploy/application.d.mts +7 -0
- package/dist/cli/commands/deploy/apply-phases.d.mts +14 -0
- package/dist/cli/commands/deploy/auth.d.mts +5 -0
- package/dist/cli/commands/deploy/deploy.d.mts +35 -0
- package/dist/cli/commands/deploy/executor.d.mts +7 -0
- package/dist/cli/commands/deploy/function-registry-types.d.mts +12 -0
- package/dist/cli/commands/deploy/function-registry.d.mts +6 -0
- package/dist/cli/commands/deploy/idp.d.mts +5 -0
- package/dist/cli/commands/deploy/label.d.mts +2 -0
- package/dist/cli/commands/deploy/resolver.d.mts +5 -0
- package/dist/cli/commands/deploy/secret-manager.d.mts +5 -0
- package/dist/cli/commands/deploy/staticwebsite.d.mts +5 -0
- package/dist/cli/commands/deploy/tailordb/index.d.mts +10 -0
- package/dist/cli/commands/deploy/types.d.mts +4 -0
- package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +2 -0
- package/dist/cli/commands/deploy/workflow.d.mts +4 -0
- package/dist/cli/commands/executor/get.d.mts +19 -0
- package/dist/cli/commands/executor/jobs.d.mts +85 -0
- package/dist/cli/commands/executor/list.d.mts +18 -0
- package/dist/cli/commands/executor/transform.d.mts +42 -0
- package/dist/cli/commands/executor/trigger.d.mts +30 -0
- package/dist/cli/commands/executor/webhook.d.mts +21 -0
- package/dist/cli/commands/function/get.d.mts +17 -0
- package/dist/cli/commands/function/list.d.mts +21 -0
- package/dist/cli/commands/function/transform.d.mts +12 -0
- package/dist/cli/commands/generate/options.d.mts +6 -0
- package/dist/cli/commands/generate/seed/bundler.d.mts +27 -0
- package/dist/cli/commands/generate/service.d.mts +15 -0
- package/dist/cli/commands/machineuser/list.d.mts +26 -0
- package/dist/cli/commands/machineuser/token.d.mts +21 -0
- package/dist/cli/commands/oauth2client/get.d.mts +17 -0
- package/dist/cli/commands/oauth2client/list.d.mts +19 -0
- package/dist/cli/commands/oauth2client/transform.d.mts +21 -0
- package/dist/cli/commands/organization/folder/create.d.mts +17 -0
- package/dist/cli/commands/organization/folder/delete.d.mts +15 -0
- package/dist/cli/commands/organization/folder/get.d.mts +16 -0
- package/dist/cli/commands/organization/folder/list.d.mts +21 -0
- package/dist/cli/commands/organization/folder/update.d.mts +17 -0
- package/dist/cli/commands/organization/get.d.mts +15 -0
- package/dist/cli/commands/organization/list.d.mts +14 -0
- package/dist/cli/commands/organization/transform.d.mts +29 -0
- package/dist/cli/commands/organization/tree.d.mts +24 -0
- package/dist/cli/commands/organization/update.d.mts +16 -0
- package/dist/cli/commands/remove.d.mts +15 -0
- package/dist/cli/commands/show.d.mts +39 -0
- package/dist/cli/commands/staticwebsite/deploy.d.mts +19 -0
- package/dist/cli/commands/tailordb/migrate/bundler.d.mts +29 -0
- package/dist/cli/commands/tailordb/migrate/config.d.mts +18 -0
- package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +246 -0
- package/dist/cli/commands/tailordb/migrate/generate.d.mts +16 -0
- package/dist/cli/commands/tailordb/migrate/schema-checks.d.mts +5 -0
- package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +208 -0
- package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +98 -0
- package/dist/cli/commands/tailordb/migrate/types.d.mts +7 -0
- package/dist/cli/commands/tailordb/truncate.d.mts +18 -0
- package/dist/cli/commands/workflow/executions.d.mts +62 -0
- package/dist/cli/commands/workflow/get.d.mts +21 -0
- package/dist/cli/commands/workflow/list.d.mts +18 -0
- package/dist/cli/commands/workflow/resume.d.mts +22 -0
- package/dist/cli/commands/workflow/start.d.mts +48 -0
- package/dist/cli/commands/workflow/status.d.mts +6 -0
- package/dist/cli/commands/workflow/transform.d.mts +34 -0
- package/dist/cli/commands/workflow/wait.d.mts +15 -0
- package/dist/cli/commands/workflow/waiter.d.mts +23 -0
- package/dist/cli/commands/workspace/app/health.d.mts +17 -0
- package/dist/cli/commands/workspace/app/list.d.mts +21 -0
- package/dist/cli/commands/workspace/app/transform.d.mts +20 -0
- package/dist/cli/commands/workspace/create.d.mts +27 -0
- package/dist/cli/commands/workspace/delete.d.mts +14 -0
- package/dist/cli/commands/workspace/get.d.mts +16 -0
- package/dist/cli/commands/workspace/list.d.mts +17 -0
- package/dist/cli/commands/workspace/restore.d.mts +14 -0
- package/dist/cli/commands/workspace/transform.d.mts +20 -0
- package/dist/cli/commands/workspace/user/invite.d.mts +21 -0
- package/dist/cli/commands/workspace/user/list.d.mts +21 -0
- package/dist/cli/commands/workspace/user/remove.d.mts +16 -0
- package/dist/cli/commands/workspace/user/transform.d.mts +9 -0
- package/dist/cli/commands/workspace/user/update.d.mts +21 -0
- package/dist/cli/index.mjs +12 -5481
- package/dist/cli/lib.d.mts +86 -21048
- package/dist/cli/lib.mjs +245 -46
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.d.mts +23 -0
- package/dist/cli/main.mjs +6777 -0
- package/dist/cli/main.mjs.map +1 -0
- package/dist/cli/query/index.d.mts +38 -0
- package/dist/cli/services/application.d.mts +12 -0
- package/dist/cli/services/auth/service.d.mts +3 -0
- package/dist/cli/services/executor/service.d.mts +1 -0
- package/dist/cli/services/http-adapter/bundler.d.mts +4 -0
- package/dist/cli/services/http-adapter/service.d.mts +2 -0
- package/dist/cli/services/resolver/service.d.mts +1 -0
- package/dist/cli/services/tailordb/service.d.mts +3 -0
- package/dist/cli/services/workflow/bundler.d.mts +3 -0
- package/dist/cli/services/workflow/service.d.mts +1 -0
- package/dist/cli/shared/args.d.mts +13 -0
- package/dist/cli/shared/client.d.mts +1298 -0
- package/dist/cli/shared/config-loader.d.mts +32 -0
- package/dist/cli/shared/context.d.mts +29 -0
- package/dist/cli/shared/error-json.d.mts +23 -0
- package/dist/cli/shared/readonly-guard.d.mts +25 -0
- package/dist/cli/shared/script-executor.d.mts +77 -0
- package/dist/cli/shared/seed-chunker.d.mts +45 -0
- package/dist/cli/shared/seed-context.d.mts +49 -0
- package/dist/cli/shared/tailordb-namespaces.d.mts +40 -0
- package/dist/cli/shared/tsconfig-paths-plugin.d.mts +2 -0
- package/dist/cli/shared/type-generator.d.mts +20 -0
- package/dist/cli/shared/workspace-name.d.mts +1 -0
- package/dist/cli/ts-hook.d.mts +4 -0
- package/dist/cli/ts-hook.mjs +333 -0
- package/dist/completion/zsh-worker.zsh +1471 -1217
- package/dist/configure/config/index.d.mts +20 -0
- package/dist/configure/config/types.d.mts +134 -0
- package/dist/configure/index.d.mts +135 -8
- package/dist/configure/index.mjs +558 -36
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/aigateway/index.d.mts +16 -0
- package/dist/configure/services/aigateway/types.d.mts +10 -0
- package/dist/configure/services/auth/index.d.mts +33 -0
- package/dist/configure/services/auth/types.d.mts +168 -0
- package/dist/configure/services/executor/executor.d.mts +70 -0
- package/dist/configure/services/executor/index.d.mts +9 -0
- package/dist/configure/services/executor/operation.d.mts +50 -0
- package/dist/configure/services/executor/trigger/event.d.mts +514 -0
- package/dist/configure/services/executor/trigger/index.d.mts +7 -0
- package/dist/configure/services/executor/trigger/schedule.d.mts +24 -0
- package/dist/configure/services/executor/trigger/webhook.d.mts +43 -0
- package/dist/configure/services/executor/types.d.mts +2 -0
- package/dist/configure/services/http-adapter/http-adapter.d.mts +124 -0
- package/dist/configure/services/http-adapter/index.d.mts +2 -0
- package/dist/configure/services/idp/index.d.mts +60 -0
- package/dist/configure/services/idp/permission.d.mts +64 -0
- package/dist/configure/services/idp/types.d.mts +23 -0
- package/dist/configure/services/index.d.mts +40 -0
- package/dist/configure/services/resolver/index.d.mts +6 -0
- package/dist/configure/services/resolver/permission.d.mts +64 -0
- package/dist/configure/services/resolver/resolver.d.mts +88 -0
- package/dist/configure/services/resolver/types.d.mts +5 -0
- package/dist/configure/services/secrets/index.d.mts +37 -0
- package/dist/configure/services/secrets/types.d.mts +10 -0
- package/dist/configure/services/staticwebsite/index.d.mts +18 -0
- package/dist/configure/services/staticwebsite/types.d.mts +10 -0
- package/dist/configure/services/tailordb/index.d.mts +3 -0
- package/dist/configure/services/tailordb/permission.d.mts +103 -0
- package/dist/configure/services/tailordb/schema.d.mts +486 -0
- package/dist/configure/services/tailordb/types.d.mts +198 -0
- package/dist/configure/services/workflow/execution-policy.d.mts +70 -0
- package/dist/configure/services/workflow/execution-policy.types.d.mts +103 -0
- package/dist/configure/services/workflow/index.d.mts +9 -0
- package/dist/configure/services/workflow/job.d.mts +92 -0
- package/dist/configure/services/workflow/types.d.mts +2 -0
- package/dist/configure/services/workflow/wait-point.d.mts +72 -0
- package/dist/configure/services/workflow/workflow.d.mts +66 -0
- package/dist/configure/types/aigateway-name.d.mts +12 -0
- package/dist/configure/types/connection-name.d.mts +12 -0
- package/dist/configure/types/field.d.mts +8 -0
- package/dist/configure/types/field.types.d.mts +70 -0
- package/dist/configure/types/idp-name.d.mts +12 -0
- package/dist/configure/types/index.d.mts +5 -0
- package/dist/configure/types/machine-user.d.mts +2 -0
- package/dist/configure/types/permission-operand.types.d.mts +20 -0
- package/dist/configure/types/type.d.mts +73 -0
- package/dist/{context-Bd266-ru.mjs → context-DYQVYWqZ.mjs} +4 -5
- package/dist/context-DYQVYWqZ.mjs.map +1 -0
- package/dist/{crashreport-BsjAkFWw.mjs → crashreport-B5LqCTfF.mjs} +10 -11
- package/dist/{crashreport-BsjAkFWw.mjs.map → crashreport-B5LqCTfF.mjs.map} +1 -1
- package/dist/{crashreport-pr6Rhvza.mjs → crashreport-eI7ty7ok.mjs} +1 -1
- package/dist/{errors-Dtf2WPaW.mjs → errors-D7583Zz7.mjs} +18 -2
- package/dist/errors-D7583Zz7.mjs.map +1 -0
- package/dist/{file-_oUZo76X.mjs → file-BUcmVIH2.mjs} +12 -22
- package/dist/file-BUcmVIH2.mjs.map +1 -0
- package/dist/{globals-Crz8o65k.mjs → globals-TfAVItuK.mjs} +32 -55
- package/dist/globals-TfAVItuK.mjs.map +1 -0
- package/dist/iconv-QWaZh0TT.mjs +38 -0
- package/dist/iconv-QWaZh0TT.mjs.map +1 -0
- package/dist/{idp-BDbK5gjm.mjs → idp-RA_swu-h.mjs} +12 -5
- package/dist/idp-RA_swu-h.mjs.map +1 -0
- package/dist/{interceptor-D-q1rvRl.mjs → interceptor-e33JtsC-.mjs} +2 -2
- package/dist/interceptor-e33JtsC-.mjs.map +1 -0
- package/dist/kysely/index.d.mts +5 -7
- package/dist/logger-BtX0suGY.mjs +48 -0
- package/dist/logger-BtX0suGY.mjs.map +1 -0
- package/dist/logger-CXQq9YIp.mjs +317 -0
- package/dist/logger-CXQq9YIp.mjs.map +1 -0
- package/dist/node-builtins-CmaL2Cbq.mjs +36 -0
- package/dist/node-builtins-CmaL2Cbq.mjs.map +1 -0
- package/dist/parser/service/auth/index.d.mts +1 -0
- package/dist/parser/service/auth/schema.d.mts +3 -0
- package/dist/parser/service/http-adapter/index.d.mts +1 -0
- package/dist/parser/service/http-adapter/schema.d.mts +1 -0
- package/dist/parser/service/idp/types.d.mts +5 -0
- package/dist/parser/service/tailordb/type-source.d.mts +10 -0
- package/dist/parser/service/tailordb/types.d.mts +131 -0
- package/dist/platform-serialize-RoRtBS0v.mjs +46 -0
- package/dist/platform-serialize-RoRtBS0v.mjs.map +1 -0
- package/dist/plugin/builtin/enum-constants/index.d.mts +15 -1
- package/dist/plugin/builtin/enum-constants/index.mjs +115 -2
- package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -0
- package/dist/plugin/builtin/file-utils/index.d.mts +15 -1
- package/dist/plugin/builtin/file-utils/index.mjs +149 -2
- package/dist/plugin/builtin/file-utils/index.mjs.map +1 -0
- package/dist/plugin/builtin/kysely-type/index.d.mts +15 -1
- package/dist/plugin/builtin/kysely-type/index.mjs +274 -2
- package/dist/plugin/builtin/kysely-type/index.mjs.map +1 -0
- package/dist/plugin/builtin/seed/index.d.mts +46 -2
- package/dist/plugin/builtin/seed/index.mjs +1 -1
- package/dist/plugin/builtin/seed/seed-type-processor.d.mts +21 -0
- package/dist/plugin/builtin/seed/types.d.mts +2 -0
- package/dist/plugin/get-generated-type.d.mts +16 -0
- package/dist/plugin/index.d.mts +3 -117
- package/dist/plugin/index.mjs +1 -1
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/plugin/manager.d.mts +2 -0
- package/dist/plugin/types.d.mts +242 -0
- package/dist/plugin/with-context.d.mts +101 -0
- package/dist/{runtime-n9NCkjee.mjs → register-ts-hook-LYV7zH-e.mjs} +9652 -4479
- package/dist/register-ts-hook-LYV7zH-e.mjs.map +1 -0
- package/dist/{registry-DdsYlL_P.mjs → registry-BIGVUrMB.mjs} +12 -9
- package/dist/registry-BIGVUrMB.mjs.map +1 -0
- package/dist/{repl-editor-DmGr9zMw.mjs → repl-editor-BCozyiNq.mjs} +6 -5
- package/dist/{repl-editor-DmGr9zMw.mjs.map → repl-editor-BCozyiNq.mjs.map} +1 -1
- package/dist/runtime/aigateway.d.mts +25 -0
- package/dist/runtime/aigateway.mjs +3 -0
- package/dist/runtime/authconnection.d.mts +21 -2
- package/dist/runtime/authconnection.mjs +2 -2
- package/dist/runtime/context.d.mts +54 -2
- package/dist/runtime/context.mjs +2 -2
- package/dist/runtime/field-parse.d.mts +10 -0
- package/dist/runtime/file.d.mts +170 -2
- package/dist/runtime/file.mjs +2 -2
- package/dist/runtime/globals.d.mts +38 -20
- package/dist/runtime/iconv.d.mts +73 -2
- package/dist/runtime/iconv.mjs +2 -2
- package/dist/runtime/idp.d.mts +129 -2
- package/dist/runtime/idp.mjs +2 -2
- package/dist/runtime/index.d.mts +48 -9
- package/dist/runtime/index.mjs +10 -8
- package/dist/runtime/logger.d.mts +98 -0
- package/dist/runtime/logger.mjs +3 -0
- package/dist/runtime/secretmanager.d.mts +41 -2
- package/dist/runtime/secretmanager.mjs +2 -2
- package/dist/runtime/types.d.mts +25 -0
- package/dist/runtime/workflow.d.mts +106 -2
- package/dist/runtime/workflow.mjs +2 -2
- package/dist/{schema-BhkpP5Hw.mjs → schema--xYWRGfe.mjs} +288 -229
- package/dist/schema--xYWRGfe.mjs.map +1 -0
- package/dist/{secret-file-DBqZhjFQ.mjs → secret-file-C3J4Gy8r.mjs} +2 -2
- package/dist/{secret-file-DBqZhjFQ.mjs.map → secret-file-C3J4Gy8r.mjs.map} +1 -1
- package/dist/secretmanager-CYlpffsz.mjs +13 -0
- package/dist/secretmanager-CYlpffsz.mjs.map +1 -0
- package/dist/secretmanager-IY4UvinW.mjs +131 -0
- package/dist/secretmanager-IY4UvinW.mjs.map +1 -0
- package/dist/seed/index.d.mts +4 -4
- package/dist/seed-B-yckgQY.mjs +483 -0
- package/dist/seed-B-yckgQY.mjs.map +1 -0
- package/dist/{service-DU1mVzri.mjs → service-B5WynBHQ.mjs} +3 -3
- package/dist/{service-DU1mVzri.mjs.map → service-B5WynBHQ.mjs.map} +1 -1
- package/dist/service-M7OYziQP.mjs +3 -0
- package/dist/service-k1xy_A5G.mjs +864 -0
- package/dist/service-k1xy_A5G.mjs.map +1 -0
- package/dist/service_pb-D5--My_M.mjs +167 -0
- package/dist/service_pb-D5--My_M.mjs.map +1 -0
- package/dist/service_pb-i8CmnQP4.mjs +3 -0
- package/dist/tailor-proto/src/tailor/v1/aigateway_pb.d.mts +203 -0
- package/dist/tailor-proto/src/tailor/v1/aigateway_resource_pb.d.mts +57 -0
- package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +420 -0
- package/dist/tailor-proto/src/tailor/v1/application_resource_pb.d.mts +160 -0
- package/dist/tailor-proto/src/tailor/v1/auth_pb.d.mts +2069 -0
- package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +865 -0
- package/dist/tailor-proto/src/tailor/v1/events_pb.d.mts +111 -0
- package/dist/tailor-proto/src/tailor/v1/events_resource_pb.d.mts +68 -0
- package/dist/tailor-proto/src/tailor/v1/executor_pb.d.mts +438 -0
- package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +586 -0
- package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +192 -0
- package/dist/tailor-proto/src/tailor/v1/function_registry_pb.d.mts +450 -0
- package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +191 -0
- package/dist/tailor-proto/src/tailor/v1/http_adapter_resource_pb.d.mts +49 -0
- package/dist/tailor-proto/src/tailor/v1/idp_pb.d.mts +406 -0
- package/dist/tailor-proto/src/tailor/v1/idp_resource_pb.d.mts +429 -0
- package/dist/tailor-proto/src/tailor/v1/metadata_pb.d.mts +72 -0
- package/dist/tailor-proto/src/tailor/v1/metadata_resource_pb.d.mts +16 -0
- package/dist/tailor-proto/src/tailor/v1/meter_pb.d.mts +308 -0
- package/dist/tailor-proto/src/tailor/v1/pipeline_pb.d.mts +590 -0
- package/dist/tailor-proto/src/tailor/v1/pipeline_resource_pb.d.mts +329 -0
- package/dist/tailor-proto/src/tailor/v1/resource_pb.d.mts +112 -0
- package/dist/tailor-proto/src/tailor/v1/secret_manager_pb.d.mts +345 -0
- package/dist/tailor-proto/src/tailor/v1/secret_manager_resource_pb.d.mts +53 -0
- package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +3658 -0
- package/dist/tailor-proto/src/tailor/v1/stateflow_pb.d.mts +186 -0
- package/dist/tailor-proto/src/tailor/v1/stateflow_resource_pb.d.mts +28 -0
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_pb.d.mts +428 -0
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_resource_pb.d.mts +89 -0
- package/dist/tailor-proto/src/tailor/v1/tailordb_pb.d.mts +683 -0
- package/dist/tailor-proto/src/tailor/v1/tailordb_resource_pb.d.mts +796 -0
- package/dist/tailor-proto/src/tailor/v1/telemetryrouter_pb.d.mts +329 -0
- package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +207 -0
- package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +961 -0
- package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +330 -0
- package/dist/tailor-proto/src/tailor/v1/workspace_pb.d.mts +2014 -0
- package/dist/tailor-proto/src/tailor/v1/workspace_resource_pb.d.mts +482 -0
- package/dist/{telemetry-CdqJEzkj.mjs → telemetry-BRVdwh14.mjs} +3 -3
- package/dist/telemetry-BRVdwh14.mjs.map +1 -0
- package/dist/telemetry-CkbkeJxl.mjs +3 -0
- package/dist/test-env-key-D7UkZp99.mjs +75 -0
- package/dist/test-env-key-D7UkZp99.mjs.map +1 -0
- package/dist/types/aigateway.generated.d.mts +12 -0
- package/dist/types/app-config.generated.d.mts +4 -0
- package/dist/types/auth-connection.generated.d.mts +33 -0
- package/dist/types/auth.generated.d.mts +188 -0
- package/dist/types/executor.generated.d.mts +229 -0
- package/dist/types/helpers.d.mts +40 -0
- package/dist/types/http-adapter.generated.d.mts +28 -0
- package/dist/types/idp.generated.d.mts +626 -0
- package/dist/types/resolver.generated.d.mts +82 -0
- package/dist/types/secrets.generated.d.mts +14 -0
- package/dist/types/staticwebsite.generated.d.mts +14 -0
- package/dist/types/tailordb.generated.d.mts +468 -0
- package/dist/types/workflow.generated.d.mts +17 -0
- package/dist/user-agent-Bgsszb5I.mjs +28 -0
- package/dist/user-agent-Bgsszb5I.mjs.map +1 -0
- package/dist/utils/test/index.d.mts +5 -100
- package/dist/utils/test/index.mjs +38 -189
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/environment.d.mts +1 -2
- package/dist/vitest/environment.mjs +2 -2
- package/dist/vitest/environment.mjs.map +1 -1
- package/dist/vitest/index.d.mts +17 -431
- package/dist/vitest/index.mjs +1234 -67
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mock-kysely.d.mts +61 -0
- package/dist/vitest/mock.d.mts +10 -0
- package/dist/vitest/mocks/aigateway.d.mts +40 -0
- package/dist/vitest/mocks/authconnection.d.mts +38 -0
- package/dist/vitest/mocks/file.d.mts +58 -0
- package/dist/vitest/mocks/iconv.d.mts +51 -0
- package/dist/vitest/mocks/idp.d.mts +60 -0
- package/dist/vitest/mocks/logger.d.mts +45 -0
- package/dist/vitest/mocks/secretmanager.d.mts +44 -0
- package/dist/vitest/mocks/tailordb.d.mts +115 -0
- package/dist/vitest/mocks/workflow.d.mts +148 -0
- package/dist/vitest/setup.d.mts +1 -2
- package/dist/vitest/setup.mjs +2 -2
- package/dist/vitest/workflow-local.d.mts +41 -0
- package/dist/workflow-Bamae_Yc.mjs +34 -0
- package/dist/workflow-Bamae_Yc.mjs.map +1 -0
- package/dist/{client-z_oHGVNy.mjs → workspace_resource_pb-DXnO2AT-.mjs} +57 -621
- package/dist/workspace_resource_pb-DXnO2AT-.mjs.map +1 -0
- package/docs/cli/application.md +150 -250
- package/docs/cli/auth.md +51 -295
- package/docs/cli/completion.md +1 -25
- package/docs/cli/crashreport.md +3 -61
- package/docs/cli/executor.md +72 -183
- package/docs/cli/function.md +16 -132
- package/docs/cli/organization.md +11 -221
- package/docs/cli/plugin.md +29 -0
- package/docs/cli/query.md +2 -22
- package/docs/cli/secret.md +71 -251
- package/docs/cli/setup.md +138 -40
- package/docs/cli/skills.md +50 -39
- package/docs/cli/staticwebsite.md +32 -180
- package/docs/cli/tailordb.md +89 -413
- package/docs/cli/upgrade.md +2 -22
- package/docs/cli/user.md +78 -247
- package/docs/cli/workflow.md +150 -172
- package/docs/cli/workspace.md +167 -538
- package/docs/cli-reference.md +214 -96
- package/docs/configuration.md +90 -6
- package/docs/github-actions.md +72 -24
- package/docs/migration/v2.md +1613 -0
- package/docs/multi-environment.md +29 -7
- package/docs/plugin/custom.md +4 -4
- package/docs/plugin/index.md +8 -8
- package/docs/quickstart.md +8 -7
- package/docs/runtime.md +18 -9
- package/docs/services/aigateway.md +20 -2
- package/docs/services/auth.md +51 -59
- package/docs/services/executor.md +91 -6
- package/docs/services/http-adapter.md +16 -1
- package/docs/services/idp.md +62 -7
- package/docs/services/resolver.md +67 -11
- package/docs/services/secret.md +11 -11
- package/docs/services/staticwebsite.md +8 -2
- package/docs/services/tailordb-migration.md +55 -29
- package/docs/services/tailordb.md +205 -102
- package/docs/services/workflow.md +163 -55
- package/docs/testing.md +244 -143
- package/package.json +61 -46
- package/postinstall.mjs +4 -6
- package/dist/application-DB2r36Et.mjs +0 -3
- package/dist/application-DqS1yBg3.mjs.map +0 -1
- package/dist/authconnection-D2MhtTN5.mjs +0 -15
- package/dist/authconnection-D2MhtTN5.mjs.map +0 -1
- package/dist/authconnection-DvUQAjQS.d.mts +0 -39
- package/dist/cli/erd-viewer-assets/app.js +0 -1181
- package/dist/cli/erd-viewer-assets/index.html +0 -73
- package/dist/cli/erd-viewer-assets/serve.json +0 -13
- package/dist/cli/erd-viewer-assets/styles.css +0 -789
- package/dist/cli/index.d.mts +0 -5
- package/dist/cli/index.mjs.map +0 -1
- package/dist/client-Dbohmtkv.mjs +0 -3
- package/dist/client-z_oHGVNy.mjs.map +0 -1
- package/dist/context-Bd266-ru.mjs.map +0 -1
- package/dist/context-BuuIb8CC.d.mts +0 -68
- package/dist/enum-constants-j9QBF0cB.mjs +0 -116
- package/dist/enum-constants-j9QBF0cB.mjs.map +0 -1
- package/dist/errors-Dtf2WPaW.mjs.map +0 -1
- package/dist/field-DOsJCPFa.mjs +0 -22
- package/dist/field-DOsJCPFa.mjs.map +0 -1
- package/dist/file-BB8Vs9O_.d.mts +0 -250
- package/dist/file-_oUZo76X.mjs.map +0 -1
- package/dist/file-utils-DcyIPFQh.mjs +0 -150
- package/dist/file-utils-DcyIPFQh.mjs.map +0 -1
- package/dist/globals-Crz8o65k.mjs.map +0 -1
- package/dist/http-adapter.generated-WgMnb7Sb.d.mts +0 -580
- package/dist/iconv-Co-TOPuH.d.mts +0 -122
- package/dist/iconv-D2vi8G36.mjs +0 -63
- package/dist/iconv-D2vi8G36.mjs.map +0 -1
- package/dist/idp-BDbK5gjm.mjs.map +0 -1
- package/dist/idp-DrhVrLmV.d.mts +0 -160
- package/dist/index-5vPyRu1y.d.mts +0 -18
- package/dist/index-B7AKc18V.d.mts +0 -47
- package/dist/index-BlpzXncY.d.mts +0 -1016
- package/dist/index-CK7u9isy.d.mts +0 -46
- package/dist/index-CNYe5lnW.d.mts +0 -18
- package/dist/index-DjUdWlzf.d.mts +0 -18
- package/dist/index-ZePLwxw7.d.mts +0 -208
- package/dist/interceptor-D-q1rvRl.mjs.map +0 -1
- package/dist/job-fuc3j1Ma.mjs +0 -53
- package/dist/job-fuc3j1Ma.mjs.map +0 -1
- package/dist/kysely-type-DR8uzZTA.mjs +0 -274
- package/dist/kysely-type-DR8uzZTA.mjs.map +0 -1
- package/dist/logger-CxF-Ex5d.mjs +0 -220
- package/dist/logger-CxF-Ex5d.mjs.map +0 -1
- package/dist/mock-BjFj5o1I.mjs +0 -804
- package/dist/mock-BjFj5o1I.mjs.map +0 -1
- package/dist/registry-DdsYlL_P.mjs.map +0 -1
- package/dist/rolldown-runtime-DXywRVcq.mjs +0 -20
- package/dist/runtime-n9NCkjee.mjs.map +0 -1
- package/dist/schema-BhkpP5Hw.mjs.map +0 -1
- package/dist/secretmanager-B3n4KHfm.d.mts +0 -55
- package/dist/secretmanager-BVxw3ih_.mjs +0 -24
- package/dist/secretmanager-BVxw3ih_.mjs.map +0 -1
- package/dist/seed-jf3008-h.mjs +0 -1160
- package/dist/seed-jf3008-h.mjs.map +0 -1
- package/dist/service-CCL8ruDf.mjs +0 -459
- package/dist/service-CCL8ruDf.mjs.map +0 -1
- package/dist/service-D6yonf2I.mjs +0 -3
- package/dist/telemetry-CdqJEzkj.mjs.map +0 -1
- package/dist/telemetry-ClwW5ohF.mjs +0 -3
- package/dist/test-env-key-D9kM6ETE.mjs +0 -49
- package/dist/test-env-key-D9kM6ETE.mjs.map +0 -1
- package/dist/types-B2RpYyA_.mjs +0 -371
- package/dist/types-B2RpYyA_.mjs.map +0 -1
- package/dist/types-ClhIrW_C.mjs +0 -4
- package/dist/types-DCUhgpyI.d.mts +0 -784
- package/dist/types-DhO_VEZd.d.mts +0 -574
- package/dist/types-DwDgacni.d.mts +0 -338
- package/dist/workflow-BbKvGLQg.d.mts +0 -96
- package/dist/workflow-DgemCAz3.mjs +0 -38
- package/dist/workflow-DgemCAz3.mjs.map +0 -1
- package/dist/workflow.generated-DtQwEo-x.d.mts +0 -671
package/docs/testing.md
CHANGED
|
@@ -11,22 +11,22 @@ Lean on unit tests for the day-to-day feedback loop — they run fast and exerci
|
|
|
11
11
|
|
|
12
12
|
Unit-test entrypoints exposed by the SDK:
|
|
13
13
|
|
|
14
|
-
- `resolver.body({ input,
|
|
15
|
-
- `workflowJob.body(input, { env })` — invoke a workflow job body directly
|
|
16
|
-
- `workflowJob.
|
|
14
|
+
- `resolver.body({ input, caller, invoker, env })` — invoke a resolver
|
|
15
|
+
- `workflowJob.body(input, { env, invoker })` — invoke a workflow job body directly
|
|
16
|
+
- `workflowJob.start(input)` — chain a workflow job through the workflow runtime
|
|
17
17
|
- `runWorkflowLocally(workflow, args)` — run a workflow chain locally with real job bodies
|
|
18
|
-
- `executor.operation.body(args)` — invoke a function-kind executor
|
|
18
|
+
- `executor.operation.body({ ...args, invoker })` — invoke a function-kind executor
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
For anonymous direct calls:
|
|
21
21
|
|
|
22
|
-
- `
|
|
22
|
+
- Pass `null` for anonymous `caller` / `invoker` context in direct unit tests.
|
|
23
23
|
|
|
24
24
|
Platform API mocks under `@tailor-platform/sdk/vitest` (for use with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta) below):
|
|
25
25
|
|
|
26
26
|
- `mockTailordb` — TailorDB query stubs and call recording
|
|
27
27
|
- `mockWorkflow` — `tailor.workflow` job / wait / resolve mocks
|
|
28
28
|
- `runWorkflowLocally` — local full-chain workflow runner
|
|
29
|
-
- `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv` — corresponding platform API mocks
|
|
29
|
+
- `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway`, `mockLogger` — corresponding platform API mocks
|
|
30
30
|
|
|
31
31
|
For tighter alignment with the production runtime — Node.js module blocking, Web-only globals, and platform API mocks — pair the resolver helpers with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta) below.
|
|
32
32
|
|
|
@@ -63,25 +63,30 @@ export default defineConfig({
|
|
|
63
63
|
|
|
64
64
|
### Acquiring mocks with `using`
|
|
65
65
|
|
|
66
|
-
Each mock controller (`mockTailordb`, `mockWorkflow`, `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`) is a **factory function**. Acquire it inside a test with a [`using` declaration](https://github.com/tc39/proposal-explicit-resource-management) — its state is reset automatically when the test scope exits, so you no longer need `beforeEach(() => mock.reset())`:
|
|
66
|
+
Each mock controller (`mockTailordb`, `mockWorkflow`, `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway`, `mockLogger`) is a **factory function**. Acquire it inside a test with a [`using` declaration](https://github.com/tc39/proposal-explicit-resource-management) — its state is reset automatically when the test scope exits, so you no longer need `beforeEach(() => mock.reset())`:
|
|
67
67
|
|
|
68
68
|
```typescript
|
|
69
69
|
import { mockTailordb } from "@tailor-platform/sdk/vitest";
|
|
70
70
|
|
|
71
71
|
test("...", () => {
|
|
72
72
|
using db = mockTailordb();
|
|
73
|
-
db.
|
|
73
|
+
db.onQuery(/SELECT age/).returnsRows([{ age: 30 }]);
|
|
74
74
|
// …
|
|
75
75
|
}); // reset automatically here
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
Runtime operations are exposed as typed Vitest mocks wherever the platform API has a stable operation shape. For example, use `file.download.mockResolvedValue(...)`, `iconv.decode.mockReturnValue(...)`, or `wf.job(myJob).mockResolvedValue(...)`, then assert with native Vitest matchers. Service-specific helpers cover stateful fixtures and query matching.
|
|
79
|
+
|
|
80
|
+
Every controller provides two lifecycle methods when manual reuse is useful:
|
|
81
|
+
|
|
82
|
+
- `clear()` removes call history but preserves configured behavior.
|
|
83
|
+
- `reset()` removes call history and configured behavior, restoring the controller's default behavior.
|
|
79
84
|
|
|
80
85
|
> **Requirements:** `using` requires TypeScript ≥ 5.2 and a runtime that provides `Symbol.dispose` (Node ≥ 20.4 — the SDK already targets Node ≥ 22, and Vitest's transformer downlevels the syntax for you).
|
|
81
86
|
>
|
|
82
87
|
> **Acquire what you use:** a namespace is only mocked while you hold it with `using`, so code under test that calls a platform API (e.g. `tailor.workflow`, `tailordb.Client`) must run inside a test that has acquired the matching `mockX()`. The error classes and `tailor.context` are always present.
|
|
83
88
|
>
|
|
84
|
-
> **Seeded secrets survive:** secrets seeded from `tailor.config.ts` stay available across tests;
|
|
89
|
+
> **Seeded secrets survive:** secrets seeded from `tailor.config.ts` stay available across tests; per-test fixtures passed to `mockSecretmanager({ secrets: ... })` apply only within that test.
|
|
85
90
|
|
|
86
91
|
### TailorDB Mock
|
|
87
92
|
|
|
@@ -92,14 +97,19 @@ import { mockTailordb } from "@tailor-platform/sdk/vitest";
|
|
|
92
97
|
|
|
93
98
|
test("resolver queries the database", async () => {
|
|
94
99
|
using db = mockTailordb();
|
|
95
|
-
//
|
|
96
|
-
db.
|
|
100
|
+
// Use an explicit queue when transaction order is part of the test.
|
|
101
|
+
db.enqueueRows(
|
|
97
102
|
[], // BEGIN (empty result)
|
|
98
103
|
[{ age: 30 }], // SELECT (one row)
|
|
99
104
|
[], // COMMIT
|
|
100
105
|
);
|
|
101
106
|
|
|
102
|
-
const result = await resolver.body({
|
|
107
|
+
const result = await resolver.body({
|
|
108
|
+
input: { email: "test@example.com" },
|
|
109
|
+
caller: null,
|
|
110
|
+
invoker: null,
|
|
111
|
+
env: {},
|
|
112
|
+
});
|
|
103
113
|
|
|
104
114
|
expect(result).toEqual({ oldAge: 30, newAge: 31 });
|
|
105
115
|
expect(db.executedQueries).toHaveLength(3);
|
|
@@ -107,75 +117,85 @@ test("resolver queries the database", async () => {
|
|
|
107
117
|
});
|
|
108
118
|
```
|
|
109
119
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
- **`enqueueResult(...rows)`** — Order-based, single query. Arguments are the row objects returned by the next `queryObject` call (`enqueueResult()` for empty, `enqueueResult({ id: "1" })` for one row, `enqueueResult({ a: 1 }, { a: 2 })` for multiple rows). Consumed in FIFO order.
|
|
113
|
-
- **`enqueueResults(...rowsArrays)`** — Order-based, multiple queries. Each argument is a rows array for one upcoming query. Equivalent to calling `enqueueResult` for each entry but easier to read for transactional sequences.
|
|
114
|
-
- **`setQueryResolver((query, params) => rows)`** — Content-based fallback. Called when the queue is empty.
|
|
120
|
+
Match queries by SQL text, a regular expression, SQL plus parameters, or a predicate. The most recently registered matcher wins:
|
|
115
121
|
|
|
116
122
|
```typescript
|
|
117
123
|
test("content-based mock", async () => {
|
|
118
124
|
using db = mockTailordb();
|
|
119
|
-
db.
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
db.onQuery({ sql: /FROM users/i, params: ["1"] }).returnsRows([{ id: "1", name: "test" }]);
|
|
126
|
+
db.onQuery(/FROM audit_logs/i)
|
|
127
|
+
.returnsRowsOnce([{ id: "first" }])
|
|
128
|
+
.returnsRows([{ id: "later" }]);
|
|
129
|
+
|
|
130
|
+
const result = await resolver.body({
|
|
131
|
+
input: { userId: "1" },
|
|
132
|
+
caller: null,
|
|
133
|
+
invoker: null,
|
|
134
|
+
env: {},
|
|
122
135
|
});
|
|
123
136
|
|
|
124
|
-
const result = await resolver.body({ input: { userId: "1" } });
|
|
125
|
-
|
|
126
137
|
expect(db.executedQueries[0].query).toContain("SELECT");
|
|
127
138
|
});
|
|
128
139
|
```
|
|
129
140
|
|
|
141
|
+
Within one `mockTailordb()` instance, use either `onQuery()` matchers or a direct `queryObject.mockImplementation()` override. A direct override replaces matcher-based behavior, so do not combine the two styles.
|
|
142
|
+
|
|
143
|
+
`returnsRowsOnce` and `rejectsOnce` configure one-time responses before the persistent `returnsRows` or `rejects` response. `enqueueRows(...rowArrays)` remains available for transaction sequences whose exact call order is under test. The existing `enqueueResult`, `enqueueResults`, and `setQueryResolver` helpers remain supported for compatibility.
|
|
144
|
+
|
|
145
|
+
Pass `{ onUnhandled: "error" }` to make an unmatched query fail instead of returning an empty result.
|
|
146
|
+
|
|
130
147
|
### Workflow Mock
|
|
131
148
|
|
|
132
|
-
Workflow job `.
|
|
149
|
+
Workflow job `.start()` calls use the platform workflow runtime. Acquire `mockWorkflow()` when you want to provide start responses with `setJobHandler` / `enqueueResult` or assert on `startedJobs`. If no response is configured, the mock throws so missing job mocks fail loudly. Use `job(definition)` or `workflow(definition)` to get a stable, fully typed Vitest mock for one definition:
|
|
133
150
|
|
|
134
151
|
```typescript
|
|
135
152
|
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
153
|
+
import { processPayment, validateOrder } from "./jobs";
|
|
136
154
|
|
|
137
|
-
test("workflow
|
|
155
|
+
test("workflow starts jobs", async () => {
|
|
138
156
|
using wf = mockWorkflow();
|
|
139
|
-
wf.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
});
|
|
157
|
+
const validate = wf.job(validateOrder);
|
|
158
|
+
const payment = wf.job(processPayment);
|
|
159
|
+
validate.mockResolvedValue({ valid: true });
|
|
160
|
+
payment.mockResolvedValue({ txnId: "txn-1" });
|
|
144
161
|
|
|
145
162
|
const result = await main({ input: { orderId: "o-1" } });
|
|
146
163
|
|
|
147
|
-
expect(
|
|
148
|
-
|
|
149
|
-
{ jobName: "process-payment", args: { orderId: "o-1" } },
|
|
150
|
-
]);
|
|
164
|
+
expect(validate).toHaveBeenCalledWith({ orderId: "o-1" });
|
|
165
|
+
expect(payment).toHaveBeenCalledWith({ orderId: "o-1" });
|
|
151
166
|
});
|
|
152
167
|
```
|
|
153
168
|
|
|
154
|
-
`
|
|
169
|
+
Unconfigured definition mocks continue to run their real implementations. The lower-level `execJobFunction`, `startWorkflow`, `resumeWorkflowExecution`, `wait`, and `resolve` mocks and the existing `setJobHandler`, `enqueueResult`, `enqueueResults`, and call-record helpers remain available.
|
|
170
|
+
|
|
171
|
+
Use `waitPoint(definition)` for typed wait-point control:
|
|
155
172
|
|
|
156
173
|
```typescript
|
|
157
174
|
using wf = mockWorkflow();
|
|
175
|
+
const approvalMock = wf.waitPoint(approvalWaitPoint);
|
|
158
176
|
|
|
159
|
-
|
|
160
|
-
|
|
177
|
+
approvalMock.wait.mockResolvedValue({ approved: true });
|
|
178
|
+
await approvalWaitPoint.wait({ message: "Please approve" });
|
|
161
179
|
|
|
162
|
-
|
|
163
|
-
wf.enqueueResults({ valid: true }, { txnId: "txn-1" });
|
|
180
|
+
expect(approvalMock.wait).toHaveBeenCalledWith({ message: "Please approve" });
|
|
164
181
|
```
|
|
165
182
|
|
|
183
|
+
Use `wf.setEnv(...)` when locally-run workflow job bodies need configuration values. Per-run `runWorkflowLocally(..., { env })` options take precedence over the mock's env.
|
|
184
|
+
|
|
166
185
|
### SecretManager Mock
|
|
167
186
|
|
|
168
187
|
```typescript
|
|
169
188
|
import { mockSecretmanager } from "@tailor-platform/sdk/vitest";
|
|
170
189
|
|
|
171
190
|
test("reads secrets from vault", async () => {
|
|
172
|
-
using sm = mockSecretmanager(
|
|
173
|
-
|
|
174
|
-
"my-vault": { API_KEY: "sk-123", DB_PASS: "secret" },
|
|
191
|
+
using sm = mockSecretmanager({
|
|
192
|
+
secrets: { "my-vault": { API_KEY: "sk-123" } },
|
|
175
193
|
});
|
|
194
|
+
sm.setSecret("my-vault", "API_KEY", "override");
|
|
195
|
+
sm.mergeSecrets("my-vault", { DB_PASS: "secret" });
|
|
176
196
|
|
|
177
197
|
const key = await tailor.secretmanager.getSecret("my-vault", "API_KEY");
|
|
178
|
-
expect(key).toBe("
|
|
198
|
+
expect(key).toBe("override");
|
|
179
199
|
expect(sm.calls).toEqual([{ method: "getSecret", vault: "my-vault", name: "API_KEY" }]);
|
|
180
200
|
});
|
|
181
201
|
```
|
|
@@ -186,65 +206,65 @@ test("reads secrets from vault", async () => {
|
|
|
186
206
|
import { mockAuthconnection } from "@tailor-platform/sdk/vitest";
|
|
187
207
|
|
|
188
208
|
test("returns configured token", async () => {
|
|
189
|
-
using ac = mockAuthconnection(
|
|
190
|
-
|
|
191
|
-
|
|
209
|
+
using ac = mockAuthconnection({
|
|
210
|
+
tokens: { google: { access_token: "ya29.xxx" } },
|
|
211
|
+
onUnhandled: "error",
|
|
192
212
|
});
|
|
213
|
+
ac.setToken("google", { access_token: "replacement" });
|
|
193
214
|
|
|
194
215
|
const token = await tailor.authconnection.getConnectionToken("google");
|
|
195
|
-
expect(token.access_token).toBe("
|
|
216
|
+
expect(token.access_token).toBe("replacement");
|
|
196
217
|
});
|
|
197
218
|
```
|
|
198
219
|
|
|
199
|
-
|
|
220
|
+
By default, an unconfigured connection returns `{ access_token: "mock-token" }`. Pass `onUnhandled: "error"` to fail instead.
|
|
200
221
|
|
|
201
222
|
### IDP Mock
|
|
202
223
|
|
|
203
224
|
```typescript
|
|
204
225
|
import { mockIdp } from "@tailor-platform/sdk/vitest";
|
|
205
226
|
|
|
206
|
-
test("
|
|
207
|
-
using idp = mockIdp();
|
|
208
|
-
idp.
|
|
209
|
-
|
|
210
|
-
|
|
227
|
+
test("namespace-specific mock", async () => {
|
|
228
|
+
using idp = mockIdp({ onUnhandled: "error" });
|
|
229
|
+
const customerIdp = idp.namespace("my-ns");
|
|
230
|
+
customerIdp.user.mockResolvedValue({
|
|
231
|
+
id: "u-1",
|
|
232
|
+
name: "alice",
|
|
233
|
+
disabled: false,
|
|
234
|
+
mfaEnrolled: false,
|
|
235
|
+
mfaFactorIds: [],
|
|
211
236
|
});
|
|
212
237
|
|
|
213
238
|
const client = new tailor.idp.Client({ namespace: "my-ns" });
|
|
214
239
|
const user = await client.user("u-1");
|
|
215
240
|
expect(user.name).toBe("alice");
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
test("queue-based", async () => {
|
|
219
|
-
using idp = mockIdp();
|
|
220
|
-
idp.enqueueResult({ id: "u-1", name: "alice", disabled: false });
|
|
221
|
-
|
|
222
|
-
const client = new tailor.idp.Client({ namespace: "my-ns" });
|
|
223
|
-
const user = await client.user("u-1");
|
|
224
|
-
expect(user.name).toBe("alice");
|
|
225
|
-
expect(idp.calls).toMatchObject([{ method: "user", namespace: "my-ns" }]);
|
|
241
|
+
expect(customerIdp.user).toHaveBeenCalledWith("u-1");
|
|
226
242
|
});
|
|
227
243
|
```
|
|
228
244
|
|
|
245
|
+
Each namespace exposes typed mocks for `users`, `user`, `userByName`, `createUser`, `updateUser`, `deleteUser`, `sendPasswordResetEmail`, and `unenrollMfa`. The existing resolver, queue, and aggregate `calls` APIs remain supported.
|
|
246
|
+
|
|
229
247
|
### File Mock
|
|
230
248
|
|
|
231
249
|
```typescript
|
|
232
250
|
import { mockFile } from "@tailor-platform/sdk/vitest";
|
|
233
251
|
|
|
234
252
|
test("mock file download", async () => {
|
|
235
|
-
using file = mockFile();
|
|
236
|
-
file.
|
|
253
|
+
using file = mockFile({ onUnhandled: "error" });
|
|
254
|
+
file.download.mockResolvedValue({
|
|
237
255
|
data: new Uint8Array([1, 2, 3]),
|
|
238
256
|
metadata: { contentType: "image/png", fileSize: 3, sha256sum: "abc", lastUploadedAt: "" },
|
|
239
257
|
});
|
|
240
258
|
|
|
241
259
|
const result = await tailordb.file.download("ns", "Doc", "attachment", "r-1");
|
|
242
260
|
expect(result.data).toEqual(new Uint8Array([1, 2, 3]));
|
|
243
|
-
expect(file.
|
|
261
|
+
expect(file.download).toHaveBeenCalledWith("ns", "Doc", "attachment", "r-1");
|
|
244
262
|
});
|
|
245
263
|
```
|
|
246
264
|
|
|
247
|
-
|
|
265
|
+
All File operations are typed Vitest mocks: `upload`, `download`, `downloadAsBase64`, `delete`, `getMetadata`, `downloadStream`, and `uploadStream`. Use native methods such as `mockResolvedValueOnce` and `mockRejectedValueOnce` to model success and failure. The existing resolver, queue, and aggregate `calls` APIs remain supported.
|
|
266
|
+
|
|
267
|
+
For `downloadStream`, configure a `FileDownloadStreamResponse` object with a `ReadableStream` body and metadata:
|
|
248
268
|
|
|
249
269
|
```typescript
|
|
250
270
|
test("mock file download stream", async () => {
|
|
@@ -255,7 +275,7 @@ test("mock file download stream", async () => {
|
|
|
255
275
|
controller.close();
|
|
256
276
|
},
|
|
257
277
|
});
|
|
258
|
-
file.
|
|
278
|
+
file.downloadStream.mockResolvedValue({
|
|
259
279
|
body,
|
|
260
280
|
metadata: { contentType: "image/png", fileSize: 3, sha256sum: "abc", lastUploadedAt: "" },
|
|
261
281
|
});
|
|
@@ -265,28 +285,6 @@ test("mock file download stream", async () => {
|
|
|
265
285
|
});
|
|
266
286
|
```
|
|
267
287
|
|
|
268
|
-
For the deprecated `openDownloadStream`, enqueue an iterable of `StreamValue` items — `metadata`, one or more `chunk` items, and a terminal `complete`. Raw `Uint8Array` / `ArrayBuffer` chunks are rejected so tests stay aligned with the platform's structured stream contract.
|
|
269
|
-
|
|
270
|
-
```typescript
|
|
271
|
-
test("mock file download stream (deprecated openDownloadStream)", async () => {
|
|
272
|
-
using file = mockFile();
|
|
273
|
-
file.enqueueResult([
|
|
274
|
-
{
|
|
275
|
-
type: "metadata",
|
|
276
|
-
metadata: { contentType: "image/png", fileSize: 3, sha256sum: "abc" },
|
|
277
|
-
},
|
|
278
|
-
{ type: "chunk", data: new Uint8Array([1, 2]), position: 0 },
|
|
279
|
-
{ type: "chunk", data: new Uint8Array([3]), position: 2 },
|
|
280
|
-
{ type: "complete" },
|
|
281
|
-
]);
|
|
282
|
-
|
|
283
|
-
const stream = await tailordb.file.openDownloadStream("ns", "Doc", "attachment", "r-1");
|
|
284
|
-
const items = [];
|
|
285
|
-
for await (const item of stream) items.push(item);
|
|
286
|
-
expect(items).toHaveLength(4);
|
|
287
|
-
});
|
|
288
|
-
```
|
|
289
|
-
|
|
290
288
|
### Iconv Mock
|
|
291
289
|
|
|
292
290
|
```typescript
|
|
@@ -294,10 +292,7 @@ import { mockIconv } from "@tailor-platform/sdk/vitest";
|
|
|
294
292
|
|
|
295
293
|
test("mock encoding conversion", () => {
|
|
296
294
|
using iconv = mockIconv();
|
|
297
|
-
iconv.
|
|
298
|
-
if (method === "decode") return "decoded-text";
|
|
299
|
-
return null; // falls back to default empty string
|
|
300
|
-
});
|
|
295
|
+
iconv.decode.mockReturnValue("decoded-text");
|
|
301
296
|
|
|
302
297
|
const result = tailor.iconv.decode(new Uint8Array([0x48, 0x69]), "UTF-8");
|
|
303
298
|
expect(result).toBe("decoded-text");
|
|
@@ -305,6 +300,48 @@ test("mock encoding conversion", () => {
|
|
|
305
300
|
});
|
|
306
301
|
```
|
|
307
302
|
|
|
303
|
+
`convert`, `convertBuffer`, `decode`, `encode`, and `encodings` are all typed Vitest mocks. Pass `{ onUnhandled: "error" }` to fail calls without a configured implementation. The existing resolver and aggregate `calls` APIs remain supported.
|
|
304
|
+
|
|
305
|
+
### AI Gateway Mock
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import { mockAigateway } from "@tailor-platform/sdk/vitest";
|
|
309
|
+
|
|
310
|
+
test("resolves an AI Gateway URL", async () => {
|
|
311
|
+
using aigateway = mockAigateway({
|
|
312
|
+
urls: { "my-aigateway": "https://my-aigateway.example.com" },
|
|
313
|
+
});
|
|
314
|
+
aigateway.setUrl("my-aigateway", "https://replacement.example.com");
|
|
315
|
+
|
|
316
|
+
const { url } = await tailor.aigateway.get("my-aigateway");
|
|
317
|
+
expect(url).toBe("https://replacement.example.com");
|
|
318
|
+
expect(aigateway.calls).toEqual([{ name: "my-aigateway" }]);
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Calling `get` for a name that has not been registered throws. `setUrls` remains available when replacing the complete URL fixture.
|
|
323
|
+
|
|
324
|
+
### Logger Mock
|
|
325
|
+
|
|
326
|
+
Each method is a `vi.fn`, so assert on it directly. `calls` returns the emitted `debug`/`info`/`warn`/`error` entries in order.
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
import { mockLogger } from "@tailor-platform/sdk/vitest";
|
|
330
|
+
|
|
331
|
+
test("logs the processed order", () => {
|
|
332
|
+
using logger = mockLogger();
|
|
333
|
+
|
|
334
|
+
tailor.logger.info("order processed", { orderId: "o-1" });
|
|
335
|
+
|
|
336
|
+
expect(logger.info).toHaveBeenCalledWith("order processed", { orderId: "o-1" });
|
|
337
|
+
expect(logger.calls).toEqual([
|
|
338
|
+
{ severity: "info", message: "order processed", attributes: { orderId: "o-1" } },
|
|
339
|
+
]);
|
|
340
|
+
});
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Without an explicit `mockLogger()`, `tailor.logger.*` calls are no-ops in the `tailor-runtime` environment (they neither throw nor record).
|
|
344
|
+
|
|
308
345
|
### Loading Secrets from Config
|
|
309
346
|
|
|
310
347
|
Pass a config path to load `defineSecretManager()` values into the mock:
|
|
@@ -316,7 +353,7 @@ export default defineConfig({
|
|
|
316
353
|
});
|
|
317
354
|
```
|
|
318
355
|
|
|
319
|
-
This makes `tailor.secretmanager.getSecret("vault", "key")` return the values defined in your config. You can still override with `
|
|
356
|
+
This makes `tailor.secretmanager.getSecret("vault", "key")` return the values defined in your config. You can still override with `mockSecretmanager({ secrets: ... })` in individual tests: a per-test overlay applies only within that test, and the config-loaded secrets remain available to every other test.
|
|
320
357
|
|
|
321
358
|
### Per-Project Configuration
|
|
322
359
|
|
|
@@ -358,7 +395,7 @@ export default defineConfig({
|
|
|
358
395
|
|
|
359
396
|
## Unit Tests
|
|
360
397
|
|
|
361
|
-
Unit tests call `.body()` (or `.
|
|
398
|
+
Unit tests call `.body()` (or `.start()`) directly on a resolver, workflow job, or executor and stub any platform-provided globals they touch.
|
|
362
399
|
|
|
363
400
|
### Testing Resolvers
|
|
364
401
|
|
|
@@ -367,7 +404,6 @@ Unit tests call `.body()` (or `.trigger()`) directly on a resolver, workflow job
|
|
|
367
404
|
For pure logic with no external dependencies, invoke `.body()` directly:
|
|
368
405
|
|
|
369
406
|
```typescript
|
|
370
|
-
import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
|
|
371
407
|
import { describe, expect, test } from "vitest";
|
|
372
408
|
import resolver from "../src/resolver/add";
|
|
373
409
|
|
|
@@ -375,7 +411,8 @@ describe("add resolver", () => {
|
|
|
375
411
|
test("adds two numbers", async () => {
|
|
376
412
|
const result = await resolver.body({
|
|
377
413
|
input: { left: 1, right: 2 },
|
|
378
|
-
|
|
414
|
+
caller: null,
|
|
415
|
+
invoker: null,
|
|
379
416
|
env: {},
|
|
380
417
|
});
|
|
381
418
|
expect(result).toBe(3);
|
|
@@ -391,15 +428,16 @@ Stub the global `tailordb.Client` and queue raw query results in order. Best for
|
|
|
391
428
|
|
|
392
429
|
> If you are running with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta), acquire `using db = mockTailordb()` to install and drive the mock `tailordb.Client` instead of `vi.stubGlobal()`.
|
|
393
430
|
|
|
431
|
+
> The example below uses `aroundAll` / `aroundEach`, which require Vitest ≥ 4.1.
|
|
432
|
+
|
|
394
433
|
```typescript
|
|
395
|
-
import {
|
|
396
|
-
import { afterAll, afterEach, beforeAll, describe, expect, test, vi } from "vitest";
|
|
434
|
+
import { aroundAll, aroundEach, describe, expect, test, vi } from "vitest";
|
|
397
435
|
import resolver from "../src/resolver/incrementUserAge";
|
|
398
436
|
|
|
399
437
|
describe("incrementUserAge resolver", () => {
|
|
400
438
|
const mockQueryObject = vi.fn();
|
|
401
439
|
|
|
402
|
-
|
|
440
|
+
aroundAll(async (runSuite) => {
|
|
403
441
|
vi.stubGlobal("tailordb", {
|
|
404
442
|
Client: vi.fn(
|
|
405
443
|
class {
|
|
@@ -409,9 +447,13 @@ describe("incrementUserAge resolver", () => {
|
|
|
409
447
|
},
|
|
410
448
|
),
|
|
411
449
|
});
|
|
450
|
+
await runSuite();
|
|
451
|
+
vi.unstubAllGlobals();
|
|
452
|
+
});
|
|
453
|
+
aroundEach(async (runTest) => {
|
|
454
|
+
await runTest();
|
|
455
|
+
mockQueryObject.mockReset();
|
|
412
456
|
});
|
|
413
|
-
afterAll(() => vi.unstubAllGlobals());
|
|
414
|
-
afterEach(() => mockQueryObject.mockReset());
|
|
415
457
|
|
|
416
458
|
test("increments age inside a transaction", async () => {
|
|
417
459
|
// BEGIN → SELECT → UPDATE → COMMIT
|
|
@@ -422,7 +464,8 @@ describe("incrementUserAge resolver", () => {
|
|
|
422
464
|
|
|
423
465
|
const result = await resolver.body({
|
|
424
466
|
input: { email: "test@example.com" },
|
|
425
|
-
|
|
467
|
+
caller: null,
|
|
468
|
+
invoker: null,
|
|
426
469
|
env: {},
|
|
427
470
|
});
|
|
428
471
|
|
|
@@ -493,7 +536,6 @@ describe("decrementUserAge", () => {
|
|
|
493
536
|
Pass `mock.db` to functions that take a Kysely instance. When a resolver or executor calls `getDB()` internally there is no such seam, so spy the generated `getDB` and point it at the mock:
|
|
494
537
|
|
|
495
538
|
```typescript
|
|
496
|
-
import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
|
|
497
539
|
import { createKyselyMock } from "@tailor-platform/sdk/vitest";
|
|
498
540
|
import { describe, expect, test, vi } from "vitest";
|
|
499
541
|
import { getDB, type Namespace } from "../generated/db";
|
|
@@ -525,7 +567,8 @@ describe("upsertUsers resolver", () => {
|
|
|
525
567
|
{ name: "Existing", email: "exists@example.com", age: 41 },
|
|
526
568
|
],
|
|
527
569
|
},
|
|
528
|
-
|
|
570
|
+
caller: null,
|
|
571
|
+
invoker: null,
|
|
529
572
|
env: { appName: "Resolver Template", version: 1 },
|
|
530
573
|
});
|
|
531
574
|
|
|
@@ -541,39 +584,70 @@ Reach for [`mockTailordb`](#mocking-the-tailordb-client) instead when you want t
|
|
|
541
584
|
|
|
542
585
|
#### Resolvers that resume a workflow
|
|
543
586
|
|
|
544
|
-
Resolvers that call `waitPoint.resolve(...)` delegate to `tailor.workflow.resolve` at runtime. With the `tailor-runtime` environment active, use `mockWorkflow().
|
|
587
|
+
Resolvers that call `waitPoint.resolve(...)` delegate to `tailor.workflow.resolve` at runtime. With the `tailor-runtime` environment active, use `mockWorkflow().waitPoint(definition)` to invoke the callback with the payload that originally suspended the job:
|
|
545
588
|
|
|
546
589
|
```typescript
|
|
547
|
-
import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
|
|
548
590
|
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
549
591
|
import { describe, expect, test } from "vitest";
|
|
592
|
+
import { approval } from "../workflow/approval";
|
|
550
593
|
import resolver from "./resolveApproval";
|
|
551
594
|
|
|
552
595
|
describe("resolveApproval resolver", () => {
|
|
553
596
|
test("resolves approval with approved=true", async () => {
|
|
554
597
|
using wf = mockWorkflow();
|
|
555
|
-
wf.
|
|
556
|
-
|
|
557
|
-
|
|
598
|
+
const approvalMock = wf.waitPoint(approval);
|
|
599
|
+
approvalMock.setResolvePayload({
|
|
600
|
+
message: "Please approve order order-1",
|
|
601
|
+
orderId: "order-1",
|
|
558
602
|
});
|
|
559
603
|
|
|
560
604
|
const result = await resolver.body({
|
|
561
605
|
input: { executionId: "exec-1", approved: true },
|
|
562
|
-
|
|
606
|
+
caller: null,
|
|
607
|
+
invoker: null,
|
|
563
608
|
env: {},
|
|
564
609
|
});
|
|
565
610
|
|
|
566
611
|
expect(result).toEqual({ resolved: true });
|
|
567
|
-
expect(
|
|
612
|
+
expect(approvalMock.resolve).toHaveBeenCalledWith("exec-1", expect.any(Function));
|
|
568
613
|
});
|
|
569
614
|
});
|
|
570
615
|
```
|
|
571
616
|
|
|
572
|
-
`
|
|
617
|
+
`setResolvePayload` is typed from the wait-point definition. The lower-level `setResolveHandler` and `resolveCalls` APIs remain available when a test must control several wait points together.
|
|
618
|
+
|
|
619
|
+
#### Resolvers that resume failed workflows
|
|
620
|
+
|
|
621
|
+
Resolvers or executors that call `workflow.resumeWorkflowExecution(executionId)` delegate to `tailor.workflow.resumeWorkflowExecution` at runtime. With the `tailor-runtime` environment active, use `mockWorkflow().setResumeHandler` to control the returned execution ID and inspect `resumeWorkflowExecution.mock.calls`:
|
|
622
|
+
|
|
623
|
+
```typescript
|
|
624
|
+
import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
|
|
625
|
+
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
626
|
+
import { describe, expect, test } from "vitest";
|
|
627
|
+
import resolver from "./retryFailedWorkflow";
|
|
628
|
+
|
|
629
|
+
describe("retryFailedWorkflow resolver", () => {
|
|
630
|
+
test("resumes a failed workflow execution", async () => {
|
|
631
|
+
using wf = mockWorkflow();
|
|
632
|
+
wf.setResumeHandler("exec-resumed-123");
|
|
633
|
+
|
|
634
|
+
const result = await resolver.body({
|
|
635
|
+
input: { executionId: "exec-failed-456" },
|
|
636
|
+
user: unauthenticatedTailorUser,
|
|
637
|
+
env: {},
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
expect(result).toEqual({ resumedExecutionId: "exec-resumed-123" });
|
|
641
|
+
expect(wf.resumeWorkflowExecution.mock.calls).toEqual([["exec-failed-456"]]);
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
`setResumeHandler` accepts a static string (same execution ID for every call) or a function `(executionId) => string` that computes one per call. By default the mock echoes the input `executionId`.
|
|
573
647
|
|
|
574
648
|
### Testing Executors
|
|
575
649
|
|
|
576
|
-
Function-kind executors expose their handler as `executor.operation.body(args)`. The shape of `args` is determined by the trigger — for example, `recordCreatedTrigger({ type: user })` produces `{ newRecord }` typed against the type's output
|
|
650
|
+
Function-kind executors expose their handler as `executor.operation.body(args)`. The shape of `args` is determined by the trigger — for example, `recordCreatedTrigger({ type: user })` produces `{ newRecord }` typed against the type's output, plus runtime fields such as `env`, `actor`, and `invoker`. GraphQL, webhook, and workflow operation kinds are declarative and don't expose a user-authored body to test.
|
|
577
651
|
|
|
578
652
|
The `executor` template extracts shared DB access into a helper (`shared.ts`) and tests the helper directly against a mocked `tailordb.Client` (same TailorDB-mocking pattern as the resolver section). Executor handlers themselves stay thin and can be tested by spying on the helper:
|
|
579
653
|
|
|
@@ -590,6 +664,14 @@ describe("onUserCreated executor", () => {
|
|
|
590
664
|
throw new Error("expected function operation");
|
|
591
665
|
}
|
|
592
666
|
await onUserCreated.operation.body({
|
|
667
|
+
workspaceId: "workspace-1",
|
|
668
|
+
appNamespace: "app",
|
|
669
|
+
env: {},
|
|
670
|
+
actor: null,
|
|
671
|
+
invoker: null,
|
|
672
|
+
event: "created",
|
|
673
|
+
rawEvent: "tailordb.type_record.created",
|
|
674
|
+
typeName: "User",
|
|
593
675
|
newRecord: {
|
|
594
676
|
id: "user-1",
|
|
595
677
|
name: "Alice",
|
|
@@ -614,11 +696,11 @@ To exercise the full chain (executor → helper → TailorDB), drop the spy and
|
|
|
614
696
|
|
|
615
697
|
### Testing Workflow Jobs
|
|
616
698
|
|
|
617
|
-
Workflow jobs expose the same `.body()` entrypoint as resolvers, plus `.
|
|
699
|
+
Workflow jobs expose the same `.body()` entrypoint as resolvers, plus `.start()` for calling them from another job or a test.
|
|
618
700
|
|
|
619
701
|
#### Simple job
|
|
620
702
|
|
|
621
|
-
Call `.body()` with the input and a stub `{ env: {} }`:
|
|
703
|
+
Call `.body()` with the input and a stub `{ env: {}, invoker: null }`:
|
|
622
704
|
|
|
623
705
|
```typescript
|
|
624
706
|
import { describe, expect, test } from "vitest";
|
|
@@ -626,46 +708,54 @@ import { validateOrder } from "./order-fulfillment";
|
|
|
626
708
|
|
|
627
709
|
describe("validateOrder", () => {
|
|
628
710
|
test("accepts a valid order", () => {
|
|
629
|
-
const result = validateOrder.body(
|
|
711
|
+
const result = validateOrder.body(
|
|
712
|
+
{ orderId: "order-1", amount: 100 },
|
|
713
|
+
{ env: {}, invoker: null },
|
|
714
|
+
);
|
|
630
715
|
expect(result).toEqual({ valid: true, orderId: "order-1" });
|
|
631
716
|
});
|
|
632
717
|
|
|
633
718
|
test("rejects a non-positive amount", () => {
|
|
634
|
-
expect(() =>
|
|
635
|
-
"
|
|
636
|
-
);
|
|
719
|
+
expect(() =>
|
|
720
|
+
validateOrder.body({ orderId: "order-1", amount: 0 }, { env: {}, invoker: null }),
|
|
721
|
+
).toThrow("Order amount must be positive");
|
|
637
722
|
});
|
|
638
723
|
});
|
|
639
724
|
```
|
|
640
725
|
|
|
641
|
-
#### Jobs that
|
|
726
|
+
#### Jobs that start other jobs
|
|
642
727
|
|
|
643
|
-
|
|
728
|
+
Use `mockWorkflow().job(definition)` to replace dependent jobs with deterministic results:
|
|
644
729
|
|
|
645
730
|
```typescript
|
|
646
|
-
import {
|
|
731
|
+
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
732
|
+
import { describe, expect, test } from "vitest";
|
|
647
733
|
import { fulfillOrder, processPayment, sendConfirmation, validateOrder } from "./order-fulfillment";
|
|
648
734
|
|
|
649
735
|
describe("fulfillOrder", () => {
|
|
650
736
|
test("chains validate → pay → confirm", async () => {
|
|
651
|
-
using
|
|
737
|
+
using wf = mockWorkflow();
|
|
738
|
+
const validate = wf.job(validateOrder).mockResolvedValue({
|
|
652
739
|
valid: true,
|
|
653
740
|
orderId: "order-1",
|
|
654
741
|
});
|
|
655
|
-
|
|
742
|
+
wf.job(processPayment).mockResolvedValue({
|
|
656
743
|
transactionId: "txn-order-1",
|
|
657
744
|
amount: 100,
|
|
658
745
|
status: "completed",
|
|
659
746
|
});
|
|
660
|
-
|
|
747
|
+
wf.job(sendConfirmation).mockResolvedValue({
|
|
661
748
|
orderId: "order-1",
|
|
662
749
|
transactionId: "txn-order-1",
|
|
663
750
|
confirmed: true,
|
|
664
751
|
});
|
|
665
752
|
|
|
666
|
-
const result = await fulfillOrder.body(
|
|
753
|
+
const result = await fulfillOrder.body(
|
|
754
|
+
{ orderId: "order-1", amount: 100 },
|
|
755
|
+
{ env: {}, invoker: null },
|
|
756
|
+
);
|
|
667
757
|
|
|
668
|
-
expect(
|
|
758
|
+
expect(validate).toHaveBeenCalledWith({ orderId: "order-1", amount: 100 });
|
|
669
759
|
expect(result).toMatchObject({ confirmed: true, paymentStatus: "completed" });
|
|
670
760
|
});
|
|
671
761
|
});
|
|
@@ -675,43 +765,50 @@ describe("fulfillOrder", () => {
|
|
|
675
765
|
|
|
676
766
|
#### Jobs that wait on approval
|
|
677
767
|
|
|
678
|
-
`.wait()` calls delegate to `tailor.workflow.wait`. With the `tailor-runtime` environment active, use `mockWorkflow().
|
|
768
|
+
`.wait()` calls delegate to `tailor.workflow.wait`. With the `tailor-runtime` environment active, use `mockWorkflow().waitPoint(definition)` to drive each branch with a typed mock:
|
|
679
769
|
|
|
680
770
|
```typescript
|
|
681
771
|
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
682
772
|
import { describe, expect, test } from "vitest";
|
|
683
|
-
import { processWithApproval } from "./approval";
|
|
773
|
+
import { approval, processWithApproval } from "./approval";
|
|
684
774
|
|
|
685
775
|
describe("processWithApproval", () => {
|
|
686
776
|
test("returns approved status when .wait() resolves positively", async () => {
|
|
687
777
|
using wf = mockWorkflow();
|
|
688
|
-
wf.
|
|
778
|
+
const approvalMock = wf.waitPoint(approval);
|
|
779
|
+
approvalMock.wait.mockResolvedValue({ approved: true });
|
|
689
780
|
|
|
690
|
-
const result = await processWithApproval.body(
|
|
781
|
+
const result = await processWithApproval.body(
|
|
782
|
+
{ orderId: "order-1" },
|
|
783
|
+
{ env: {}, invoker: null },
|
|
784
|
+
);
|
|
691
785
|
|
|
692
786
|
expect(result).toEqual({ orderId: "order-1", status: "approved" });
|
|
693
|
-
expect(
|
|
694
|
-
|
|
695
|
-
|
|
787
|
+
expect(approvalMock.wait).toHaveBeenCalledWith({
|
|
788
|
+
message: "Please approve order order-1",
|
|
789
|
+
orderId: "order-1",
|
|
696
790
|
});
|
|
697
791
|
});
|
|
698
792
|
|
|
699
793
|
test("returns rejected status when .wait() resolves negatively", async () => {
|
|
700
794
|
using wf = mockWorkflow();
|
|
701
|
-
wf.
|
|
795
|
+
wf.waitPoint(approval).wait.mockResolvedValue({ approved: false });
|
|
702
796
|
|
|
703
|
-
const result = await processWithApproval.body(
|
|
797
|
+
const result = await processWithApproval.body(
|
|
798
|
+
{ orderId: "order-2" },
|
|
799
|
+
{ env: {}, invoker: null },
|
|
800
|
+
);
|
|
704
801
|
|
|
705
802
|
expect(result.status).toBe("rejected");
|
|
706
803
|
});
|
|
707
804
|
});
|
|
708
805
|
```
|
|
709
806
|
|
|
710
|
-
`setWaitHandler`
|
|
807
|
+
The lower-level `setWaitHandler` and `waitCalls` APIs remain available when one handler must cover several wait points.
|
|
711
808
|
|
|
712
809
|
#### Running a full workflow locally
|
|
713
810
|
|
|
714
|
-
To exercise the full chain with real job bodies, call `runWorkflowLocally(workflow, args)`. Dependent jobs run their real `.body()` functions, and
|
|
811
|
+
To exercise the full chain with real job bodies, call `runWorkflowLocally(workflow, args)`. Dependent jobs run their real `.body()` functions, and start args/results cross the same JSON boundary as the platform, so a non-serializable payload fails the test exactly as it would in production:
|
|
715
812
|
|
|
716
813
|
```typescript
|
|
717
814
|
import { runWorkflowLocally } from "@tailor-platform/sdk/vitest";
|
|
@@ -727,9 +824,13 @@ describe("order-fulfillment workflow", () => {
|
|
|
727
824
|
});
|
|
728
825
|
```
|
|
729
826
|
|
|
827
|
+
Acquire `mockWorkflow()` only when you need to override a dependent definition with `wf.job(...)` / `wf.workflow(...)` (the rest still run their real bodies), control the env via `wf.setEnv(...)`, or assert on calls.
|
|
828
|
+
|
|
730
829
|
Pass `{ env }` as the third argument when job bodies need configuration values during the local run.
|
|
731
830
|
|
|
732
|
-
|
|
831
|
+
If you already acquired `mockWorkflow()`, you can also call `wf.setEnv(...)` to reuse the same env across local workflow runs.
|
|
832
|
+
|
|
833
|
+
Like the platform runtime, the local runner re-runs the orchestrator body once per `.start()` call (N starts means N+1 passes), so any side effects outside the start results fire on every pass. Keep the body deterministic and move repeatable side effects into the started jobs.
|
|
733
834
|
|
|
734
835
|
This helper is still a local runner. Use E2E tests when you need to verify deployed workflow scheduling, suspension, or replay behavior.
|
|
735
836
|
|
|
@@ -837,7 +938,7 @@ describe("user-profile-sync workflow", () => {
|
|
|
837
938
|
test("executes end to end", { timeout: 180_000 }, async () => {
|
|
838
939
|
const { executionId, wait } = await startWorkflow({
|
|
839
940
|
workflow: userProfileSync,
|
|
840
|
-
|
|
941
|
+
invoker: "admin",
|
|
841
942
|
arg: {
|
|
842
943
|
name: "workflow-test",
|
|
843
944
|
email: `wf-${randomUUID()}@example.com`,
|