@tailor-platform/sdk 2.0.0-next.0 → 2.0.0-next.10
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 +972 -0
- 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-DArFTTJ9.mjs +3 -0
- package/dist/{application-76hhIhnJ.mjs → application-miwiXtB4.mjs} +1963 -1953
- package/dist/application-miwiXtB4.mjs.map +1 -0
- package/dist/{assert-CKfwrmCV.mjs → assert-DBxo8jPo.mjs} +1 -2
- package/dist/{assert-CKfwrmCV.mjs.map → assert-DBxo8jPo.mjs.map} +1 -1
- package/dist/authconnection-CZvi9ANm.mjs +9 -0
- package/dist/authconnection-CZvi9ANm.mjs.map +1 -0
- package/dist/{brand-DlnJ375c.mjs → brand-Eo4pLXPJ.mjs} +1 -2
- package/dist/brand-Eo4pLXPJ.mjs.map +1 -0
- 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 +34 -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 +7 -0
- package/dist/cli/commands/deploy/idp.d.mts +5 -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 +9 -0
- package/dist/cli/commands/deploy/types.d.mts +3 -0
- package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +3 -0
- package/dist/cli/commands/deploy/workflow.d.mts +4 -0
- package/dist/cli/commands/executor/get.d.mts +28 -0
- package/dist/cli/commands/executor/jobs.d.mts +122 -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 +40 -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 +26 -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/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 +74 -0
- package/dist/cli/commands/workflow/get.d.mts +30 -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 +60 -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 -5534
- package/dist/cli/lib.d.mts +90 -21180
- package/dist/cli/lib.mjs +157 -16
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.d.mts +23 -0
- package/dist/cli/main.mjs +6583 -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 +3 -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 +2 -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 +1273 -0
- package/dist/cli/shared/config-loader.d.mts +25 -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/type-generator.d.mts +19 -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 +4223 -0
- package/dist/configure/config/index.d.mts +20 -0
- package/dist/configure/config/types.d.mts +111 -0
- package/dist/configure/index.d.mts +135 -7
- package/dist/configure/index.mjs +409 -56
- 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 +271 -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 +4 -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 +83 -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 +56 -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-s0lxhu8_.mjs → context-DYQVYWqZ.mjs} +4 -6
- package/dist/context-DYQVYWqZ.mjs.map +1 -0
- package/dist/{crashreport-BhD0y14F.mjs → crashreport-B5LqCTfF.mjs} +25 -17
- package/dist/{crashreport-BhD0y14F.mjs.map → crashreport-B5LqCTfF.mjs.map} +1 -1
- package/dist/{crashreport-D1wKBJ8N.mjs → crashreport-eI7ty7ok.mjs} +1 -2
- package/dist/{enum-constants-C7DaWeQo.mjs → enum-constants-j9QBF0cB.mjs} +1 -2
- package/dist/enum-constants-j9QBF0cB.mjs.map +1 -0
- package/dist/{errors-EsY4XO6O.mjs → errors-D7583Zz7.mjs} +18 -3
- package/dist/errors-D7583Zz7.mjs.map +1 -0
- package/dist/{file-B58Dm-2P.mjs → file-BUcmVIH2.mjs} +12 -23
- package/dist/file-BUcmVIH2.mjs.map +1 -0
- package/dist/{file-utils-BHPxPXmn.mjs → file-utils-yEiIS4nJ.mjs} +7 -8
- package/dist/file-utils-yEiIS4nJ.mjs.map +1 -0
- package/dist/{globals-ByrCoDip.mjs → globals-DQotNuwK.mjs} +32 -6
- package/dist/globals-DQotNuwK.mjs.map +1 -0
- package/dist/iconv-QWaZh0TT.mjs +38 -0
- package/dist/iconv-QWaZh0TT.mjs.map +1 -0
- package/dist/{idp-Ch95ag8h.mjs → idp-RA_swu-h.mjs} +12 -6
- package/dist/idp-RA_swu-h.mjs.map +1 -0
- package/dist/{interceptor-DOqRkCya.mjs → interceptor-e33JtsC-.mjs} +2 -3
- package/dist/interceptor-e33JtsC-.mjs.map +1 -0
- package/dist/kysely/index.d.mts +5 -7
- package/dist/kysely/index.mjs +0 -1
- package/dist/kysely/index.mjs.map +1 -1
- package/dist/{kysely-type-D1e0Vwkd.mjs → kysely-type-DqIRgDYR.mjs} +6 -6
- package/dist/kysely-type-DqIRgDYR.mjs.map +1 -0
- 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/{multiline-Cf9ODpr1.mjs → multiline-sfHpTZZK.mjs} +1 -2
- package/dist/{multiline-Cf9ODpr1.mjs.map → multiline-sfHpTZZK.mjs.map} +1 -1
- package/dist/{package-json-DcQApfPQ.mjs → package-json-8b0O9TlX.mjs} +1 -2
- package/dist/{package-json-DcQApfPQ.mjs.map → package-json-8b0O9TlX.mjs.map} +1 -1
- package/dist/package-json-Cv2Z-TqQ.mjs +3 -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 +1 -2
- package/dist/plugin/builtin/file-utils/index.d.mts +15 -1
- package/dist/plugin/builtin/file-utils/index.mjs +1 -2
- package/dist/plugin/builtin/kysely-type/index.d.mts +15 -1
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -2
- package/dist/plugin/builtin/seed/index.d.mts +46 -2
- package/dist/plugin/builtin/seed/index.mjs +1 -2
- package/dist/plugin/builtin/seed/seed-type-processor.d.mts +19 -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 -119
- package/dist/plugin/index.mjs +1 -2
- 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-C7qTBDD2.mjs → register-ts-hook-BAHMwxfG.mjs} +12374 -8672
- package/dist/register-ts-hook-BAHMwxfG.mjs.map +1 -0
- package/dist/registry-BIGVUrMB.mjs +54 -0
- package/dist/registry-BIGVUrMB.mjs.map +1 -0
- package/dist/{repl-editor-CJG3sz7A.mjs → repl-editor-BCozyiNq.mjs} +7 -7
- package/dist/{repl-editor-CJG3sz7A.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 -3
- package/dist/runtime/context.d.mts +54 -2
- package/dist/runtime/context.mjs +2 -3
- package/dist/runtime/field-parse.d.mts +10 -0
- package/dist/runtime/file.d.mts +170 -2
- package/dist/runtime/file.mjs +2 -3
- package/dist/runtime/globals.d.mts +38 -53
- package/dist/runtime/globals.mjs +0 -1
- package/dist/runtime/iconv.d.mts +73 -2
- package/dist/runtime/iconv.mjs +2 -3
- package/dist/runtime/idp.d.mts +129 -2
- package/dist/runtime/idp.mjs +2 -3
- package/dist/runtime/index.d.mts +48 -9
- package/dist/runtime/index.mjs +10 -9
- 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 -3
- package/dist/runtime/types.d.mts +25 -0
- package/dist/runtime/workflow.d.mts +124 -2
- package/dist/runtime/workflow.mjs +2 -3
- package/dist/{schema-1msIhXwA.mjs → schema--xYWRGfe.mjs} +289 -231
- package/dist/schema--xYWRGfe.mjs.map +1 -0
- package/dist/{secret-file-CWzF8rry.mjs → secret-file-C3J4Gy8r.mjs} +2 -3
- package/dist/{secret-file-CWzF8rry.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/index.mjs +0 -1
- package/dist/seed/index.mjs.map +1 -1
- package/dist/seed-LUVr7jHL.mjs +444 -0
- package/dist/seed-LUVr7jHL.mjs.map +1 -0
- package/dist/{service-DMohAx8a2.mjs → service-B5WynBHQ.mjs} +3 -4
- package/dist/service-B5WynBHQ.mjs.map +1 -0
- package/dist/service-BNtPsK9Q.mjs +837 -0
- package/dist/service-BNtPsK9Q.mjs.map +1 -0
- package/dist/service-D5jn05ZI.mjs +3 -0
- package/dist/service_pb-BwZRiNug.mjs +167 -0
- package/dist/service_pb-BwZRiNug.mjs.map +1 -0
- package/dist/service_pb-wRkxUta6.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 +315 -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 +563 -0
- package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +144 -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 +3575 -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 +182 -0
- package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +861 -0
- package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +309 -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-BQbbVo2t.mjs → telemetry-BRVdwh14.mjs} +4 -5
- 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/type-source-DH_LH20p.mjs +13 -0
- package/dist/type-source-DH_LH20p.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 +209 -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 +6 -99
- package/dist/utils/test/index.mjs +60 -40
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/utils/test/mock.d.mts +86 -0
- package/dist/vitest/environment.d.mts +1 -2
- package/dist/vitest/environment.mjs +2 -3
- package/dist/vitest/environment.mjs.map +1 -1
- package/dist/vitest/index.d.mts +15 -392
- package/dist/vitest/index.mjs +1347 -9
- 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 +157 -0
- package/dist/vitest/setup.d.mts +1 -2
- package/dist/vitest/setup.mjs +2 -3
- package/dist/vitest/setup.mjs.map +1 -1
- package/dist/vitest/workflow-local.d.mts +41 -0
- package/dist/workflow-CsaQ9qK-.mjs +42 -0
- package/dist/workflow-CsaQ9qK-.mjs.map +1 -0
- package/dist/{client-CobIRHl-.mjs → workspace_resource_pb-UGK1SSn_.mjs} +55 -616
- package/dist/workspace_resource_pb-UGK1SSn_.mjs.map +1 -0
- package/docs/cli/application.md +150 -252
- package/docs/cli/auth.md +51 -295
- package/docs/cli/completion.md +4 -25
- package/docs/cli/crashreport.md +3 -63
- package/docs/cli/executor.md +72 -183
- package/docs/cli/function.md +17 -133
- 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 +71 -427
- 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 +213 -96
- package/docs/configuration.md +40 -8
- package/docs/github-actions.md +72 -24
- package/docs/migration/v2.md +1316 -0
- package/docs/multi-environment.md +29 -7
- package/docs/plugin/custom.md +6 -6
- package/docs/plugin/index.md +9 -9
- package/docs/quickstart.md +8 -7
- package/docs/runtime.md +21 -12
- package/docs/services/aigateway.md +115 -0
- package/docs/services/auth.md +70 -61
- package/docs/services/executor.md +8 -5
- package/docs/services/http-adapter.md +16 -1
- package/docs/services/idp.md +55 -2
- package/docs/services/resolver.md +63 -11
- package/docs/services/secret.md +11 -11
- package/docs/services/staticwebsite.md +8 -2
- package/docs/services/tailordb-migration.md +43 -28
- package/docs/services/tailordb.md +200 -99
- package/docs/services/workflow.md +135 -59
- package/docs/testing.md +253 -145
- package/package.json +61 -47
- package/postinstall.mjs +4 -6
- package/dist/actor-J2gJ0eK5.d.mts +0 -24
- package/dist/application-76hhIhnJ.mjs.map +0 -1
- package/dist/application-av2raLs6.mjs +0 -4
- package/dist/authconnection-BIYzEh2p.d.mts +0 -39
- package/dist/authconnection-D8SJGMpj.mjs +0 -16
- package/dist/authconnection-D8SJGMpj.mjs.map +0 -1
- package/dist/brand-DlnJ375c.mjs.map +0 -1
- package/dist/chunk-BkoGK1jX.mjs +0 -21
- 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/cli/skills.d.mts +0 -1
- package/dist/cli/skills.mjs +0 -22
- package/dist/cli/skills.mjs.map +0 -1
- package/dist/client-C68VWo4g.mjs +0 -4
- package/dist/client-CobIRHl-.mjs.map +0 -1
- package/dist/context-CUBwSBq4.d.mts +0 -68
- package/dist/context-s0lxhu8_.mjs.map +0 -1
- package/dist/enum-constants-C7DaWeQo.mjs.map +0 -1
- package/dist/env-B-g-qgE4.d.mts +0 -7
- package/dist/errors-EsY4XO6O.mjs.map +0 -1
- package/dist/field-C4zdJLW5.mjs +0 -23
- package/dist/field-C4zdJLW5.mjs.map +0 -1
- package/dist/file-B58Dm-2P.mjs.map +0 -1
- package/dist/file-BzK8z3X-.d.mts +0 -250
- package/dist/file-utils-BHPxPXmn.mjs.map +0 -1
- package/dist/globals-ByrCoDip.mjs.map +0 -1
- package/dist/iconv-DreIffeM.mjs +0 -64
- package/dist/iconv-DreIffeM.mjs.map +0 -1
- package/dist/iconv-kwrmd1U_.d.mts +0 -122
- package/dist/idp-BlBPtXJ-.d.mts +0 -160
- package/dist/idp-Ch95ag8h.mjs.map +0 -1
- package/dist/index-CLxubakC.d.mts +0 -1225
- package/dist/index-CPRnOjjt.d.mts +0 -18
- package/dist/index-CQZVJ5SX.d.mts +0 -18
- package/dist/index-CfRFkXIO.d.mts +0 -47
- package/dist/index-DRhMpdnA.d.mts +0 -46
- package/dist/index-DUupuPhZ.d.mts +0 -18
- package/dist/interceptor-DOqRkCya.mjs.map +0 -1
- package/dist/job-BpsFXPbi.mjs +0 -54
- package/dist/job-BpsFXPbi.mjs.map +0 -1
- package/dist/kysely-type-D1e0Vwkd.mjs.map +0 -1
- package/dist/logger-DpJyJvNz.mjs +0 -221
- package/dist/logger-DpJyJvNz.mjs.map +0 -1
- package/dist/mock-DMgIygjE.mjs +0 -806
- package/dist/mock-DMgIygjE.mjs.map +0 -1
- package/dist/package-json-wzO6nV9O.mjs +0 -4
- package/dist/plugin-C_FyVSdl.d.mts +0 -634
- package/dist/registry-D0uB0OrK.mjs +0 -178
- package/dist/registry-D0uB0OrK.mjs.map +0 -1
- package/dist/runtime-C7qTBDD2.mjs.map +0 -1
- package/dist/schema-1msIhXwA.mjs.map +0 -1
- package/dist/secretmanager-B9h-U_8U.mjs +0 -25
- package/dist/secretmanager-B9h-U_8U.mjs.map +0 -1
- package/dist/secretmanager-CKLB3wAQ.d.mts +0 -55
- package/dist/seed-BH2FbrPV.mjs +0 -1171
- package/dist/seed-BH2FbrPV.mjs.map +0 -1
- package/dist/service-BHQIerYh.mjs +0 -4
- package/dist/service-DMohAx8a2.mjs.map +0 -1
- package/dist/service-wI3Hvrgx.mjs +0 -460
- package/dist/service-wI3Hvrgx.mjs.map +0 -1
- package/dist/tailordb-BlBGmQK-.d.mts +0 -863
- package/dist/telemetry-BQbbVo2t.mjs.map +0 -1
- package/dist/telemetry-w92bvGdC.mjs +0 -4
- package/dist/types-2Be3wSMc.mjs +0 -5
- package/dist/types-CmzfQP_m.mjs +0 -372
- package/dist/types-CmzfQP_m.mjs.map +0 -1
- package/dist/workflow--aPbA8Uq.mjs +0 -39
- package/dist/workflow--aPbA8Uq.mjs.map +0 -1
- package/dist/workflow-CMamswkK.d.mts +0 -96
- package/dist/workflow.generated-Bf1tWylx.d.mts +0 -1416
- package/docs/generator/builtin.md +0 -257
- package/docs/generator/custom.md +0 -147
- package/docs/generator/index.md +0 -66
package/docs/testing.md
CHANGED
|
@@ -11,19 +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 })`
|
|
16
|
-
- `
|
|
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
|
+
- `runWorkflowLocally(workflow, args)` — run a workflow chain locally with real job bodies
|
|
18
|
+
- `executor.operation.body({ ...args, invoker })` — invoke a function-kind executor
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
For anonymous direct calls:
|
|
19
21
|
|
|
20
|
-
- `
|
|
22
|
+
- Pass `null` for anonymous `caller` / `invoker` context in direct unit tests.
|
|
21
23
|
|
|
22
24
|
Platform API mocks under `@tailor-platform/sdk/vitest` (for use with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta) below):
|
|
23
25
|
|
|
24
26
|
- `mockTailordb` — TailorDB query stubs and call recording
|
|
25
27
|
- `mockWorkflow` — `tailor.workflow` job / wait / resolve mocks
|
|
26
|
-
- `
|
|
28
|
+
- `runWorkflowLocally` — local full-chain workflow runner
|
|
29
|
+
- `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway`, `mockLogger` — corresponding platform API mocks
|
|
27
30
|
|
|
28
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.
|
|
29
32
|
|
|
@@ -60,25 +63,30 @@ export default defineConfig({
|
|
|
60
63
|
|
|
61
64
|
### Acquiring mocks with `using`
|
|
62
65
|
|
|
63
|
-
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())`:
|
|
64
67
|
|
|
65
68
|
```typescript
|
|
66
69
|
import { mockTailordb } from "@tailor-platform/sdk/vitest";
|
|
67
70
|
|
|
68
71
|
test("...", () => {
|
|
69
72
|
using db = mockTailordb();
|
|
70
|
-
db.
|
|
73
|
+
db.onQuery(/SELECT age/).returnsRows([{ age: 30 }]);
|
|
71
74
|
// …
|
|
72
75
|
}); // reset automatically here
|
|
73
76
|
```
|
|
74
77
|
|
|
75
|
-
|
|
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.
|
|
76
84
|
|
|
77
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).
|
|
78
86
|
>
|
|
79
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.
|
|
80
88
|
>
|
|
81
|
-
> **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.
|
|
82
90
|
|
|
83
91
|
### TailorDB Mock
|
|
84
92
|
|
|
@@ -89,14 +97,19 @@ import { mockTailordb } from "@tailor-platform/sdk/vitest";
|
|
|
89
97
|
|
|
90
98
|
test("resolver queries the database", async () => {
|
|
91
99
|
using db = mockTailordb();
|
|
92
|
-
//
|
|
93
|
-
db.
|
|
100
|
+
// Use an explicit queue when transaction order is part of the test.
|
|
101
|
+
db.enqueueRows(
|
|
94
102
|
[], // BEGIN (empty result)
|
|
95
103
|
[{ age: 30 }], // SELECT (one row)
|
|
96
104
|
[], // COMMIT
|
|
97
105
|
);
|
|
98
106
|
|
|
99
|
-
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
|
+
});
|
|
100
113
|
|
|
101
114
|
expect(result).toEqual({ oldAge: 30, newAge: 31 });
|
|
102
115
|
expect(db.executedQueries).toHaveLength(3);
|
|
@@ -104,75 +117,85 @@ test("resolver queries the database", async () => {
|
|
|
104
117
|
});
|
|
105
118
|
```
|
|
106
119
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- **`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.
|
|
110
|
-
- **`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.
|
|
111
|
-
- **`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:
|
|
112
121
|
|
|
113
122
|
```typescript
|
|
114
123
|
test("content-based mock", async () => {
|
|
115
124
|
using db = mockTailordb();
|
|
116
|
-
db.
|
|
117
|
-
|
|
118
|
-
|
|
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: {},
|
|
119
135
|
});
|
|
120
136
|
|
|
121
|
-
const result = await resolver.body({ input: { userId: "1" } });
|
|
122
|
-
|
|
123
137
|
expect(db.executedQueries[0].query).toContain("SELECT");
|
|
124
138
|
});
|
|
125
139
|
```
|
|
126
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
|
+
|
|
127
147
|
### Workflow Mock
|
|
128
148
|
|
|
129
|
-
`.
|
|
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:
|
|
130
150
|
|
|
131
151
|
```typescript
|
|
132
152
|
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
153
|
+
import { processPayment, validateOrder } from "./jobs";
|
|
133
154
|
|
|
134
|
-
test("workflow
|
|
155
|
+
test("workflow starts jobs", async () => {
|
|
135
156
|
using wf = mockWorkflow();
|
|
136
|
-
wf.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
});
|
|
157
|
+
const validate = wf.job(validateOrder);
|
|
158
|
+
const payment = wf.job(processPayment);
|
|
159
|
+
validate.mockResolvedValue({ valid: true });
|
|
160
|
+
payment.mockResolvedValue({ txnId: "txn-1" });
|
|
141
161
|
|
|
142
162
|
const result = await main({ input: { orderId: "o-1" } });
|
|
143
163
|
|
|
144
|
-
expect(
|
|
145
|
-
|
|
146
|
-
{ jobName: "process-payment", args: { orderId: "o-1" } },
|
|
147
|
-
]);
|
|
164
|
+
expect(validate).toHaveBeenCalledWith({ orderId: "o-1" });
|
|
165
|
+
expect(payment).toHaveBeenCalledWith({ orderId: "o-1" });
|
|
148
166
|
});
|
|
149
167
|
```
|
|
150
168
|
|
|
151
|
-
`
|
|
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:
|
|
152
172
|
|
|
153
173
|
```typescript
|
|
154
174
|
using wf = mockWorkflow();
|
|
175
|
+
const approvalMock = wf.waitPoint(approvalWaitPoint);
|
|
155
176
|
|
|
156
|
-
|
|
157
|
-
|
|
177
|
+
approvalMock.wait.mockResolvedValue({ approved: true });
|
|
178
|
+
await approvalWaitPoint.wait({ message: "Please approve" });
|
|
158
179
|
|
|
159
|
-
|
|
160
|
-
wf.enqueueResults({ valid: true }, { txnId: "txn-1" });
|
|
180
|
+
expect(approvalMock.wait).toHaveBeenCalledWith({ message: "Please approve" });
|
|
161
181
|
```
|
|
162
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
|
+
|
|
163
185
|
### SecretManager Mock
|
|
164
186
|
|
|
165
187
|
```typescript
|
|
166
188
|
import { mockSecretmanager } from "@tailor-platform/sdk/vitest";
|
|
167
189
|
|
|
168
190
|
test("reads secrets from vault", async () => {
|
|
169
|
-
using sm = mockSecretmanager(
|
|
170
|
-
|
|
171
|
-
"my-vault": { API_KEY: "sk-123", DB_PASS: "secret" },
|
|
191
|
+
using sm = mockSecretmanager({
|
|
192
|
+
secrets: { "my-vault": { API_KEY: "sk-123" } },
|
|
172
193
|
});
|
|
194
|
+
sm.setSecret("my-vault", "API_KEY", "override");
|
|
195
|
+
sm.mergeSecrets("my-vault", { DB_PASS: "secret" });
|
|
173
196
|
|
|
174
197
|
const key = await tailor.secretmanager.getSecret("my-vault", "API_KEY");
|
|
175
|
-
expect(key).toBe("
|
|
198
|
+
expect(key).toBe("override");
|
|
176
199
|
expect(sm.calls).toEqual([{ method: "getSecret", vault: "my-vault", name: "API_KEY" }]);
|
|
177
200
|
});
|
|
178
201
|
```
|
|
@@ -183,65 +206,65 @@ test("reads secrets from vault", async () => {
|
|
|
183
206
|
import { mockAuthconnection } from "@tailor-platform/sdk/vitest";
|
|
184
207
|
|
|
185
208
|
test("returns configured token", async () => {
|
|
186
|
-
using ac = mockAuthconnection(
|
|
187
|
-
|
|
188
|
-
|
|
209
|
+
using ac = mockAuthconnection({
|
|
210
|
+
tokens: { google: { access_token: "ya29.xxx" } },
|
|
211
|
+
onUnhandled: "error",
|
|
189
212
|
});
|
|
213
|
+
ac.setToken("google", { access_token: "replacement" });
|
|
190
214
|
|
|
191
215
|
const token = await tailor.authconnection.getConnectionToken("google");
|
|
192
|
-
expect(token.access_token).toBe("
|
|
216
|
+
expect(token.access_token).toBe("replacement");
|
|
193
217
|
});
|
|
194
218
|
```
|
|
195
219
|
|
|
196
|
-
|
|
220
|
+
By default, an unconfigured connection returns `{ access_token: "mock-token" }`. Pass `onUnhandled: "error"` to fail instead.
|
|
197
221
|
|
|
198
222
|
### IDP Mock
|
|
199
223
|
|
|
200
224
|
```typescript
|
|
201
225
|
import { mockIdp } from "@tailor-platform/sdk/vitest";
|
|
202
226
|
|
|
203
|
-
test("
|
|
204
|
-
using idp = mockIdp();
|
|
205
|
-
idp.
|
|
206
|
-
|
|
207
|
-
|
|
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: [],
|
|
208
236
|
});
|
|
209
237
|
|
|
210
238
|
const client = new tailor.idp.Client({ namespace: "my-ns" });
|
|
211
239
|
const user = await client.user("u-1");
|
|
212
240
|
expect(user.name).toBe("alice");
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
test("queue-based", async () => {
|
|
216
|
-
using idp = mockIdp();
|
|
217
|
-
idp.enqueueResult({ id: "u-1", name: "alice", disabled: false });
|
|
218
|
-
|
|
219
|
-
const client = new tailor.idp.Client({ namespace: "my-ns" });
|
|
220
|
-
const user = await client.user("u-1");
|
|
221
|
-
expect(user.name).toBe("alice");
|
|
222
|
-
expect(idp.calls).toMatchObject([{ method: "user", namespace: "my-ns" }]);
|
|
241
|
+
expect(customerIdp.user).toHaveBeenCalledWith("u-1");
|
|
223
242
|
});
|
|
224
243
|
```
|
|
225
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
|
+
|
|
226
247
|
### File Mock
|
|
227
248
|
|
|
228
249
|
```typescript
|
|
229
250
|
import { mockFile } from "@tailor-platform/sdk/vitest";
|
|
230
251
|
|
|
231
252
|
test("mock file download", async () => {
|
|
232
|
-
using file = mockFile();
|
|
233
|
-
file.
|
|
253
|
+
using file = mockFile({ onUnhandled: "error" });
|
|
254
|
+
file.download.mockResolvedValue({
|
|
234
255
|
data: new Uint8Array([1, 2, 3]),
|
|
235
256
|
metadata: { contentType: "image/png", fileSize: 3, sha256sum: "abc", lastUploadedAt: "" },
|
|
236
257
|
});
|
|
237
258
|
|
|
238
259
|
const result = await tailordb.file.download("ns", "Doc", "attachment", "r-1");
|
|
239
260
|
expect(result.data).toEqual(new Uint8Array([1, 2, 3]));
|
|
240
|
-
expect(file.
|
|
261
|
+
expect(file.download).toHaveBeenCalledWith("ns", "Doc", "attachment", "r-1");
|
|
241
262
|
});
|
|
242
263
|
```
|
|
243
264
|
|
|
244
|
-
|
|
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:
|
|
245
268
|
|
|
246
269
|
```typescript
|
|
247
270
|
test("mock file download stream", async () => {
|
|
@@ -252,7 +275,7 @@ test("mock file download stream", async () => {
|
|
|
252
275
|
controller.close();
|
|
253
276
|
},
|
|
254
277
|
});
|
|
255
|
-
file.
|
|
278
|
+
file.downloadStream.mockResolvedValue({
|
|
256
279
|
body,
|
|
257
280
|
metadata: { contentType: "image/png", fileSize: 3, sha256sum: "abc", lastUploadedAt: "" },
|
|
258
281
|
});
|
|
@@ -262,28 +285,6 @@ test("mock file download stream", async () => {
|
|
|
262
285
|
});
|
|
263
286
|
```
|
|
264
287
|
|
|
265
|
-
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.
|
|
266
|
-
|
|
267
|
-
```typescript
|
|
268
|
-
test("mock file download stream (deprecated openDownloadStream)", async () => {
|
|
269
|
-
using file = mockFile();
|
|
270
|
-
file.enqueueResult([
|
|
271
|
-
{
|
|
272
|
-
type: "metadata",
|
|
273
|
-
metadata: { contentType: "image/png", fileSize: 3, sha256sum: "abc" },
|
|
274
|
-
},
|
|
275
|
-
{ type: "chunk", data: new Uint8Array([1, 2]), position: 0 },
|
|
276
|
-
{ type: "chunk", data: new Uint8Array([3]), position: 2 },
|
|
277
|
-
{ type: "complete" },
|
|
278
|
-
]);
|
|
279
|
-
|
|
280
|
-
const stream = await tailordb.file.openDownloadStream("ns", "Doc", "attachment", "r-1");
|
|
281
|
-
const items = [];
|
|
282
|
-
for await (const item of stream) items.push(item);
|
|
283
|
-
expect(items).toHaveLength(4);
|
|
284
|
-
});
|
|
285
|
-
```
|
|
286
|
-
|
|
287
288
|
### Iconv Mock
|
|
288
289
|
|
|
289
290
|
```typescript
|
|
@@ -291,10 +292,7 @@ import { mockIconv } from "@tailor-platform/sdk/vitest";
|
|
|
291
292
|
|
|
292
293
|
test("mock encoding conversion", () => {
|
|
293
294
|
using iconv = mockIconv();
|
|
294
|
-
iconv.
|
|
295
|
-
if (method === "decode") return "decoded-text";
|
|
296
|
-
return null; // falls back to default empty string
|
|
297
|
-
});
|
|
295
|
+
iconv.decode.mockReturnValue("decoded-text");
|
|
298
296
|
|
|
299
297
|
const result = tailor.iconv.decode(new Uint8Array([0x48, 0x69]), "UTF-8");
|
|
300
298
|
expect(result).toBe("decoded-text");
|
|
@@ -302,6 +300,48 @@ test("mock encoding conversion", () => {
|
|
|
302
300
|
});
|
|
303
301
|
```
|
|
304
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
|
+
|
|
305
345
|
### Loading Secrets from Config
|
|
306
346
|
|
|
307
347
|
Pass a config path to load `defineSecretManager()` values into the mock:
|
|
@@ -313,7 +353,7 @@ export default defineConfig({
|
|
|
313
353
|
});
|
|
314
354
|
```
|
|
315
355
|
|
|
316
|
-
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.
|
|
317
357
|
|
|
318
358
|
### Per-Project Configuration
|
|
319
359
|
|
|
@@ -355,7 +395,7 @@ export default defineConfig({
|
|
|
355
395
|
|
|
356
396
|
## Unit Tests
|
|
357
397
|
|
|
358
|
-
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.
|
|
359
399
|
|
|
360
400
|
### Testing Resolvers
|
|
361
401
|
|
|
@@ -364,7 +404,6 @@ Unit tests call `.body()` (or `.trigger()`) directly on a resolver, workflow job
|
|
|
364
404
|
For pure logic with no external dependencies, invoke `.body()` directly:
|
|
365
405
|
|
|
366
406
|
```typescript
|
|
367
|
-
import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
|
|
368
407
|
import { describe, expect, test } from "vitest";
|
|
369
408
|
import resolver from "../src/resolver/add";
|
|
370
409
|
|
|
@@ -372,7 +411,8 @@ describe("add resolver", () => {
|
|
|
372
411
|
test("adds two numbers", async () => {
|
|
373
412
|
const result = await resolver.body({
|
|
374
413
|
input: { left: 1, right: 2 },
|
|
375
|
-
|
|
414
|
+
caller: null,
|
|
415
|
+
invoker: null,
|
|
376
416
|
env: {},
|
|
377
417
|
});
|
|
378
418
|
expect(result).toBe(3);
|
|
@@ -388,15 +428,16 @@ Stub the global `tailordb.Client` and queue raw query results in order. Best for
|
|
|
388
428
|
|
|
389
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()`.
|
|
390
430
|
|
|
431
|
+
> The example below uses `aroundAll` / `aroundEach`, which require Vitest ≥ 4.1.
|
|
432
|
+
|
|
391
433
|
```typescript
|
|
392
|
-
import {
|
|
393
|
-
import { afterAll, afterEach, beforeAll, describe, expect, test, vi } from "vitest";
|
|
434
|
+
import { aroundAll, aroundEach, describe, expect, test, vi } from "vitest";
|
|
394
435
|
import resolver from "../src/resolver/incrementUserAge";
|
|
395
436
|
|
|
396
437
|
describe("incrementUserAge resolver", () => {
|
|
397
438
|
const mockQueryObject = vi.fn();
|
|
398
439
|
|
|
399
|
-
|
|
440
|
+
aroundAll(async (runSuite) => {
|
|
400
441
|
vi.stubGlobal("tailordb", {
|
|
401
442
|
Client: vi.fn(
|
|
402
443
|
class {
|
|
@@ -406,9 +447,13 @@ describe("incrementUserAge resolver", () => {
|
|
|
406
447
|
},
|
|
407
448
|
),
|
|
408
449
|
});
|
|
450
|
+
await runSuite();
|
|
451
|
+
vi.unstubAllGlobals();
|
|
452
|
+
});
|
|
453
|
+
aroundEach(async (runTest) => {
|
|
454
|
+
await runTest();
|
|
455
|
+
mockQueryObject.mockReset();
|
|
409
456
|
});
|
|
410
|
-
afterAll(() => vi.unstubAllGlobals());
|
|
411
|
-
afterEach(() => mockQueryObject.mockReset());
|
|
412
457
|
|
|
413
458
|
test("increments age inside a transaction", async () => {
|
|
414
459
|
// BEGIN → SELECT → UPDATE → COMMIT
|
|
@@ -419,7 +464,8 @@ describe("incrementUserAge resolver", () => {
|
|
|
419
464
|
|
|
420
465
|
const result = await resolver.body({
|
|
421
466
|
input: { email: "test@example.com" },
|
|
422
|
-
|
|
467
|
+
caller: null,
|
|
468
|
+
invoker: null,
|
|
423
469
|
env: {},
|
|
424
470
|
});
|
|
425
471
|
|
|
@@ -490,7 +536,6 @@ describe("decrementUserAge", () => {
|
|
|
490
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:
|
|
491
537
|
|
|
492
538
|
```typescript
|
|
493
|
-
import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
|
|
494
539
|
import { createKyselyMock } from "@tailor-platform/sdk/vitest";
|
|
495
540
|
import { describe, expect, test, vi } from "vitest";
|
|
496
541
|
import { getDB, type Namespace } from "../generated/db";
|
|
@@ -522,7 +567,8 @@ describe("upsertUsers resolver", () => {
|
|
|
522
567
|
{ name: "Existing", email: "exists@example.com", age: 41 },
|
|
523
568
|
],
|
|
524
569
|
},
|
|
525
|
-
|
|
570
|
+
caller: null,
|
|
571
|
+
invoker: null,
|
|
526
572
|
env: { appName: "Resolver Template", version: 1 },
|
|
527
573
|
});
|
|
528
574
|
|
|
@@ -538,39 +584,70 @@ Reach for [`mockTailordb`](#mocking-the-tailordb-client) instead when you want t
|
|
|
538
584
|
|
|
539
585
|
#### Resolvers that resume a workflow
|
|
540
586
|
|
|
541
|
-
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:
|
|
542
588
|
|
|
543
589
|
```typescript
|
|
544
|
-
import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
|
|
545
590
|
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
546
591
|
import { describe, expect, test } from "vitest";
|
|
592
|
+
import { approval } from "../workflow/approval";
|
|
547
593
|
import resolver from "./resolveApproval";
|
|
548
594
|
|
|
549
595
|
describe("resolveApproval resolver", () => {
|
|
550
596
|
test("resolves approval with approved=true", async () => {
|
|
551
597
|
using wf = mockWorkflow();
|
|
552
|
-
wf.
|
|
553
|
-
|
|
554
|
-
|
|
598
|
+
const approvalMock = wf.waitPoint(approval);
|
|
599
|
+
approvalMock.setResolvePayload({
|
|
600
|
+
message: "Please approve order order-1",
|
|
601
|
+
orderId: "order-1",
|
|
555
602
|
});
|
|
556
603
|
|
|
557
604
|
const result = await resolver.body({
|
|
558
605
|
input: { executionId: "exec-1", approved: true },
|
|
559
|
-
|
|
606
|
+
caller: null,
|
|
607
|
+
invoker: null,
|
|
560
608
|
env: {},
|
|
561
609
|
});
|
|
562
610
|
|
|
563
611
|
expect(result).toEqual({ resolved: true });
|
|
564
|
-
expect(
|
|
612
|
+
expect(approvalMock.resolve).toHaveBeenCalledWith("exec-1", expect.any(Function));
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
```
|
|
616
|
+
|
|
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"]]);
|
|
565
642
|
});
|
|
566
643
|
});
|
|
567
644
|
```
|
|
568
645
|
|
|
569
|
-
`
|
|
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`.
|
|
570
647
|
|
|
571
648
|
### Testing Executors
|
|
572
649
|
|
|
573
|
-
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.
|
|
574
651
|
|
|
575
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:
|
|
576
653
|
|
|
@@ -587,6 +664,14 @@ describe("onUserCreated executor", () => {
|
|
|
587
664
|
throw new Error("expected function operation");
|
|
588
665
|
}
|
|
589
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",
|
|
590
675
|
newRecord: {
|
|
591
676
|
id: "user-1",
|
|
592
677
|
name: "Alice",
|
|
@@ -611,11 +696,11 @@ To exercise the full chain (executor → helper → TailorDB), drop the spy and
|
|
|
611
696
|
|
|
612
697
|
### Testing Workflow Jobs
|
|
613
698
|
|
|
614
|
-
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.
|
|
615
700
|
|
|
616
701
|
#### Simple job
|
|
617
702
|
|
|
618
|
-
Call `.body()` with the input and a stub `{ env: {} }`:
|
|
703
|
+
Call `.body()` with the input and a stub `{ env: {}, invoker: null }`:
|
|
619
704
|
|
|
620
705
|
```typescript
|
|
621
706
|
import { describe, expect, test } from "vitest";
|
|
@@ -623,46 +708,54 @@ import { validateOrder } from "./order-fulfillment";
|
|
|
623
708
|
|
|
624
709
|
describe("validateOrder", () => {
|
|
625
710
|
test("accepts a valid order", () => {
|
|
626
|
-
const result = validateOrder.body(
|
|
711
|
+
const result = validateOrder.body(
|
|
712
|
+
{ orderId: "order-1", amount: 100 },
|
|
713
|
+
{ env: {}, invoker: null },
|
|
714
|
+
);
|
|
627
715
|
expect(result).toEqual({ valid: true, orderId: "order-1" });
|
|
628
716
|
});
|
|
629
717
|
|
|
630
718
|
test("rejects a non-positive amount", () => {
|
|
631
|
-
expect(() =>
|
|
632
|
-
"
|
|
633
|
-
);
|
|
719
|
+
expect(() =>
|
|
720
|
+
validateOrder.body({ orderId: "order-1", amount: 0 }, { env: {}, invoker: null }),
|
|
721
|
+
).toThrow("Order amount must be positive");
|
|
634
722
|
});
|
|
635
723
|
});
|
|
636
724
|
```
|
|
637
725
|
|
|
638
|
-
#### Jobs that
|
|
726
|
+
#### Jobs that start other jobs
|
|
639
727
|
|
|
640
|
-
|
|
728
|
+
Use `mockWorkflow().job(definition)` to replace dependent jobs with deterministic results:
|
|
641
729
|
|
|
642
730
|
```typescript
|
|
643
|
-
import {
|
|
731
|
+
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
732
|
+
import { describe, expect, test } from "vitest";
|
|
644
733
|
import { fulfillOrder, processPayment, sendConfirmation, validateOrder } from "./order-fulfillment";
|
|
645
734
|
|
|
646
735
|
describe("fulfillOrder", () => {
|
|
647
736
|
test("chains validate → pay → confirm", async () => {
|
|
648
|
-
using
|
|
737
|
+
using wf = mockWorkflow();
|
|
738
|
+
const validate = wf.job(validateOrder).mockResolvedValue({
|
|
649
739
|
valid: true,
|
|
650
740
|
orderId: "order-1",
|
|
651
741
|
});
|
|
652
|
-
|
|
742
|
+
wf.job(processPayment).mockResolvedValue({
|
|
653
743
|
transactionId: "txn-order-1",
|
|
654
744
|
amount: 100,
|
|
655
745
|
status: "completed",
|
|
656
746
|
});
|
|
657
|
-
|
|
747
|
+
wf.job(sendConfirmation).mockResolvedValue({
|
|
658
748
|
orderId: "order-1",
|
|
659
749
|
transactionId: "txn-order-1",
|
|
660
750
|
confirmed: true,
|
|
661
751
|
});
|
|
662
752
|
|
|
663
|
-
const result = await fulfillOrder.body(
|
|
753
|
+
const result = await fulfillOrder.body(
|
|
754
|
+
{ orderId: "order-1", amount: 100 },
|
|
755
|
+
{ env: {}, invoker: null },
|
|
756
|
+
);
|
|
664
757
|
|
|
665
|
-
expect(
|
|
758
|
+
expect(validate).toHaveBeenCalledWith({ orderId: "order-1", amount: 100 });
|
|
666
759
|
expect(result).toMatchObject({ confirmed: true, paymentStatus: "completed" });
|
|
667
760
|
});
|
|
668
761
|
});
|
|
@@ -672,58 +765,74 @@ describe("fulfillOrder", () => {
|
|
|
672
765
|
|
|
673
766
|
#### Jobs that wait on approval
|
|
674
767
|
|
|
675
|
-
`.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:
|
|
676
769
|
|
|
677
770
|
```typescript
|
|
678
771
|
import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
679
772
|
import { describe, expect, test } from "vitest";
|
|
680
|
-
import { processWithApproval } from "./approval";
|
|
773
|
+
import { approval, processWithApproval } from "./approval";
|
|
681
774
|
|
|
682
775
|
describe("processWithApproval", () => {
|
|
683
776
|
test("returns approved status when .wait() resolves positively", async () => {
|
|
684
777
|
using wf = mockWorkflow();
|
|
685
|
-
wf.
|
|
778
|
+
const approvalMock = wf.waitPoint(approval);
|
|
779
|
+
approvalMock.wait.mockResolvedValue({ approved: true });
|
|
686
780
|
|
|
687
|
-
const result = await processWithApproval.body(
|
|
781
|
+
const result = await processWithApproval.body(
|
|
782
|
+
{ orderId: "order-1" },
|
|
783
|
+
{ env: {}, invoker: null },
|
|
784
|
+
);
|
|
688
785
|
|
|
689
786
|
expect(result).toEqual({ orderId: "order-1", status: "approved" });
|
|
690
|
-
expect(
|
|
691
|
-
|
|
692
|
-
|
|
787
|
+
expect(approvalMock.wait).toHaveBeenCalledWith({
|
|
788
|
+
message: "Please approve order order-1",
|
|
789
|
+
orderId: "order-1",
|
|
693
790
|
});
|
|
694
791
|
});
|
|
695
792
|
|
|
696
793
|
test("returns rejected status when .wait() resolves negatively", async () => {
|
|
697
794
|
using wf = mockWorkflow();
|
|
698
|
-
wf.
|
|
795
|
+
wf.waitPoint(approval).wait.mockResolvedValue({ approved: false });
|
|
699
796
|
|
|
700
|
-
const result = await processWithApproval.body(
|
|
797
|
+
const result = await processWithApproval.body(
|
|
798
|
+
{ orderId: "order-2" },
|
|
799
|
+
{ env: {}, invoker: null },
|
|
800
|
+
);
|
|
701
801
|
|
|
702
802
|
expect(result.status).toBe("rejected");
|
|
703
803
|
});
|
|
704
804
|
});
|
|
705
805
|
```
|
|
706
806
|
|
|
707
|
-
`setWaitHandler`
|
|
807
|
+
The lower-level `setWaitHandler` and `waitCalls` APIs remain available when one handler must cover several wait points.
|
|
708
808
|
|
|
709
809
|
#### Running a full workflow locally
|
|
710
810
|
|
|
711
|
-
To exercise the full chain with real job bodies,
|
|
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:
|
|
712
812
|
|
|
713
813
|
```typescript
|
|
814
|
+
import { runWorkflowLocally } from "@tailor-platform/sdk/vitest";
|
|
714
815
|
import { describe, expect, test } from "vitest";
|
|
715
816
|
import workflow from "./order-fulfillment";
|
|
716
817
|
|
|
717
818
|
describe("order-fulfillment workflow", () => {
|
|
718
|
-
test("
|
|
719
|
-
const result = await workflow
|
|
819
|
+
test("runWorkflowLocally() executes all jobs", async () => {
|
|
820
|
+
const result = await runWorkflowLocally(workflow, { orderId: "order-3", amount: 300 });
|
|
720
821
|
|
|
721
822
|
expect(result).toMatchObject({ confirmed: true, paymentStatus: "completed" });
|
|
722
823
|
});
|
|
723
824
|
});
|
|
724
825
|
```
|
|
725
826
|
|
|
726
|
-
Acquire `mockWorkflow()` only when you need to override a dependent
|
|
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
|
+
|
|
829
|
+
Pass `{ env }` as the third argument when job bodies need configuration values during the local run.
|
|
830
|
+
|
|
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.
|
|
834
|
+
|
|
835
|
+
This helper is still a local runner. Use E2E tests when you need to verify deployed workflow scheduling, suspension, or replay behavior.
|
|
727
836
|
|
|
728
837
|
**Use when:** you want to verify orchestration end to end without the cost of a real deployment.
|
|
729
838
|
|
|
@@ -823,14 +932,13 @@ Use `startWorkflow` from the CLI helpers. It starts the workflow on the deployed
|
|
|
823
932
|
import { randomUUID } from "node:crypto";
|
|
824
933
|
import { startWorkflow } from "@tailor-platform/sdk/cli";
|
|
825
934
|
import { describe, expect, test } from "vitest";
|
|
826
|
-
import config from "../tailor.config";
|
|
827
935
|
import userProfileSync from "../src/workflow/sync-profile";
|
|
828
936
|
|
|
829
937
|
describe("user-profile-sync workflow", () => {
|
|
830
938
|
test("executes end to end", { timeout: 180_000 }, async () => {
|
|
831
939
|
const { executionId, wait } = await startWorkflow({
|
|
832
940
|
workflow: userProfileSync,
|
|
833
|
-
|
|
941
|
+
invoker: "admin",
|
|
834
942
|
arg: {
|
|
835
943
|
name: "workflow-test",
|
|
836
944
|
email: `wf-${randomUUID()}@example.com`,
|