@tailor-platform/sdk 2.0.0-next.3 → 2.0.0-next.5
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 +142 -0
- package/dist/aigateway-DR4Kwuik.mjs +9 -0
- package/dist/{aigateway-B3oZZE6v.mjs.map → aigateway-DR4Kwuik.mjs.map} +1 -1
- package/dist/{application-eHp9jXld.mjs → application-Bf8wxOi6.mjs} +701 -597
- package/dist/application-Bf8wxOi6.mjs.map +1 -0
- package/dist/application-CUkjzfij.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 -1
- package/dist/cli/cache/store.d.mts +1 -1
- package/dist/cli/commands/api/index.d.mts +1 -0
- package/dist/cli/commands/deploy/aigateway.d.mts +5 -1
- package/dist/cli/commands/deploy/application.d.mts +7 -1
- package/dist/cli/commands/deploy/apply-phases.d.mts +14 -1
- package/dist/cli/commands/deploy/auth.d.mts +5 -1
- package/dist/cli/commands/deploy/deploy.d.mts +5 -0
- package/dist/cli/commands/deploy/executor.d.mts +7 -1
- package/dist/cli/commands/deploy/function-registry.d.mts +5 -0
- package/dist/cli/commands/deploy/idp.d.mts +5 -1
- package/dist/cli/commands/deploy/resolver.d.mts +5 -1
- package/dist/cli/commands/deploy/secret-manager.d.mts +5 -1
- package/dist/cli/commands/deploy/staticwebsite.d.mts +5 -1
- package/dist/cli/commands/deploy/tailordb/index.d.mts +8 -1
- package/dist/cli/commands/deploy/types.d.mts +3 -1
- package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +3 -0
- package/dist/cli/commands/deploy/workflow.d.mts +4 -1
- package/dist/cli/commands/executor/get.d.mts +0 -1
- package/dist/cli/commands/executor/jobs.d.mts +0 -1
- package/dist/cli/commands/executor/list.d.mts +0 -1
- package/dist/cli/commands/executor/transform.d.mts +1 -0
- package/dist/cli/commands/executor/trigger.d.mts +0 -1
- package/dist/cli/commands/executor/webhook.d.mts +0 -1
- package/dist/cli/commands/function/get.d.mts +0 -1
- package/dist/cli/commands/function/list.d.mts +0 -1
- package/dist/cli/commands/function/transform.d.mts +1 -0
- package/dist/cli/commands/generate/service.d.mts +5 -1
- package/dist/cli/commands/machineuser/list.d.mts +0 -1
- package/dist/cli/commands/machineuser/token.d.mts +0 -1
- package/dist/cli/commands/oauth2client/get.d.mts +0 -1
- package/dist/cli/commands/oauth2client/list.d.mts +0 -1
- package/dist/cli/commands/oauth2client/transform.d.mts +1 -0
- package/dist/cli/commands/organization/folder/create.d.mts +0 -1
- package/dist/cli/commands/organization/folder/delete.d.mts +0 -1
- package/dist/cli/commands/organization/folder/get.d.mts +0 -1
- package/dist/cli/commands/organization/folder/list.d.mts +0 -1
- package/dist/cli/commands/organization/folder/update.d.mts +0 -1
- package/dist/cli/commands/organization/get.d.mts +0 -1
- package/dist/cli/commands/organization/list.d.mts +0 -1
- package/dist/cli/commands/organization/transform.d.mts +2 -0
- package/dist/cli/commands/organization/tree.d.mts +0 -1
- package/dist/cli/commands/organization/update.d.mts +0 -1
- package/dist/cli/commands/remove.d.mts +0 -1
- package/dist/cli/commands/show.d.mts +9 -4
- package/dist/cli/commands/tailordb/migrate/config.d.mts +0 -1
- package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +16 -3
- package/dist/cli/commands/tailordb/migrate/generate.d.mts +0 -1
- package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +6 -0
- package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -1
- package/dist/cli/commands/tailordb/truncate.d.mts +0 -1
- package/dist/cli/commands/workflow/executions.d.mts +0 -1
- package/dist/cli/commands/workflow/get.d.mts +2 -1
- package/dist/cli/commands/workflow/list.d.mts +0 -1
- package/dist/cli/commands/workflow/resume.d.mts +0 -1
- package/dist/cli/commands/workflow/start.d.mts +0 -1
- package/dist/cli/commands/workflow/status.d.mts +1 -0
- package/dist/cli/commands/workflow/transform.d.mts +1 -0
- package/dist/cli/commands/workflow/wait.d.mts +0 -1
- package/dist/cli/commands/workflow/waiter.d.mts +1 -1
- package/dist/cli/commands/workspace/app/health.d.mts +0 -1
- package/dist/cli/commands/workspace/app/list.d.mts +0 -1
- package/dist/cli/commands/workspace/app/transform.d.mts +2 -0
- package/dist/cli/commands/workspace/create.d.mts +0 -1
- package/dist/cli/commands/workspace/delete.d.mts +0 -1
- package/dist/cli/commands/workspace/get.d.mts +0 -1
- package/dist/cli/commands/workspace/list.d.mts +0 -1
- package/dist/cli/commands/workspace/restore.d.mts +0 -1
- package/dist/cli/commands/workspace/transform.d.mts +2 -0
- package/dist/cli/commands/workspace/user/invite.d.mts +0 -1
- package/dist/cli/commands/workspace/user/list.d.mts +0 -1
- package/dist/cli/commands/workspace/user/remove.d.mts +0 -1
- package/dist/cli/commands/workspace/user/transform.d.mts +1 -0
- package/dist/cli/commands/workspace/user/update.d.mts +0 -1
- package/dist/cli/index.d.mts +6 -3
- package/dist/cli/index.mjs +273 -104
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +4 -2
- package/dist/cli/lib.mjs +4 -4
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/query/index.d.mts +4 -1
- package/dist/cli/services/application.d.mts +12 -1
- package/dist/cli/services/auth/service.d.mts +2 -0
- package/dist/cli/services/executor/service.d.mts +1 -1
- package/dist/cli/services/http-adapter/bundler.d.mts +3 -1
- package/dist/cli/services/http-adapter/service.d.mts +2 -1
- package/dist/cli/services/resolver/service.d.mts +1 -1
- package/dist/cli/services/tailordb/service.d.mts +3 -1
- package/dist/cli/services/workflow/bundler.d.mts +2 -1
- package/dist/cli/services/workflow/service.d.mts +1 -1
- package/dist/cli/shared/args.d.mts +1 -1
- package/dist/cli/shared/client.d.mts +1 -1
- package/dist/cli/shared/config-loader.d.mts +0 -1
- package/dist/cli/shared/context.d.mts +2 -1
- package/dist/cli/shared/script-executor.d.mts +0 -1
- package/dist/cli/shared/seed-chunker.d.mts +7 -3
- package/dist/cli/shared/type-generator.d.mts +0 -1
- package/dist/cli/ts-hook.mjs +43 -13
- package/dist/completion/zsh-worker.zsh +10 -10
- package/dist/configure/config/index.d.mts +0 -1
- package/dist/configure/config/types.d.mts +3 -1
- package/dist/configure/index.d.mts +17 -5
- package/dist/configure/index.mjs +309 -5
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/aigateway/index.d.mts +0 -1
- package/dist/configure/services/aigateway/types.d.mts +0 -1
- package/dist/configure/services/auth/index.d.mts +0 -1
- package/dist/configure/services/auth/types.d.mts +15 -14
- package/dist/configure/services/executor/executor.d.mts +1 -1
- package/dist/configure/services/executor/index.d.mts +1 -0
- package/dist/configure/services/executor/operation.d.mts +2 -2
- package/dist/configure/services/executor/trigger/event.d.mts +0 -1
- package/dist/configure/services/executor/trigger/index.d.mts +0 -1
- package/dist/configure/services/executor/trigger/schedule.d.mts +0 -1
- package/dist/configure/services/executor/trigger/webhook.d.mts +0 -1
- package/dist/configure/services/http-adapter/http-adapter.d.mts +1 -2
- package/dist/configure/services/idp/index.d.mts +1 -5
- package/dist/configure/services/idp/permission.d.mts +4 -5
- package/dist/configure/services/idp/types.d.mts +0 -1
- package/dist/configure/services/index.d.mts +8 -1
- package/dist/configure/services/resolver/resolver.d.mts +1 -0
- package/dist/configure/services/resolver/types.d.mts +0 -1
- package/dist/configure/services/secrets/index.d.mts +0 -1
- package/dist/configure/services/secrets/types.d.mts +0 -1
- package/dist/configure/services/staticwebsite/index.d.mts +0 -1
- package/dist/configure/services/staticwebsite/types.d.mts +0 -1
- package/dist/configure/services/tailordb/permission.d.mts +4 -5
- package/dist/configure/services/tailordb/schema.d.mts +104 -68
- package/dist/configure/services/tailordb/types.d.mts +66 -17
- 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 +4 -1
- package/dist/configure/services/workflow/job.d.mts +7 -3
- package/dist/configure/services/workflow/wait-point.d.mts +0 -1
- package/dist/configure/services/workflow/workflow.d.mts +1 -1
- package/dist/configure/types/field-runtime.d.mts +0 -1
- package/dist/configure/types/field.d.mts +1 -2
- package/dist/configure/types/field.types.d.mts +6 -45
- package/dist/configure/types/index.d.mts +1 -0
- package/dist/configure/types/type.d.mts +1 -2
- package/dist/{context-Bd266-ru.mjs → context-DYQVYWqZ.mjs} +4 -5
- package/dist/{context-Bd266-ru.mjs.map → context-DYQVYWqZ.mjs.map} +1 -1
- package/dist/{file-BbdFGdMV.mjs → file-BUcmVIH2.mjs} +12 -14
- package/dist/file-BUcmVIH2.mjs.map +1 -0
- package/dist/{file-utils-CYZnO1pX.mjs → file-utils-yEiIS4nJ.mjs} +2 -2
- package/dist/file-utils-yEiIS4nJ.mjs.map +1 -0
- package/dist/{globals-DhwZj0RB.mjs → globals-BjhJJ2dN.mjs} +2 -2
- package/dist/globals-BjhJJ2dN.mjs.map +1 -0
- package/dist/iconv-QWaZh0TT.mjs +38 -0
- package/dist/iconv-QWaZh0TT.mjs.map +1 -0
- package/dist/{idp-Bx25ZBdN.mjs → idp-RA_swu-h.mjs} +4 -5
- package/dist/idp-RA_swu-h.mjs.map +1 -0
- package/dist/kysely/index.d.mts +3 -4
- package/dist/{kysely-type-5eAChaHO.mjs → kysely-type-DqIRgDYR.mjs} +4 -5
- package/dist/kysely-type-DqIRgDYR.mjs.map +1 -0
- package/dist/parser/service/auth/index.d.mts +1 -1
- package/dist/parser/service/auth/schema.d.mts +2 -0
- package/dist/parser/service/http-adapter/index.d.mts +1 -1
- package/dist/parser/service/idp/types.d.mts +1 -0
- package/dist/parser/service/tailordb/types.d.mts +6 -1
- package/dist/plugin/builtin/enum-constants/index.d.mts +0 -1
- package/dist/plugin/builtin/file-utils/index.d.mts +0 -1
- package/dist/plugin/builtin/file-utils/index.mjs +1 -1
- package/dist/plugin/builtin/kysely-type/index.d.mts +0 -1
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/plugin/builtin/seed/index.d.mts +0 -1
- package/dist/plugin/get-generated-type.d.mts +0 -1
- package/dist/plugin/manager.d.mts +2 -1
- package/dist/plugin/types.d.mts +0 -1
- package/dist/plugin/with-context.d.mts +0 -1
- package/dist/{register-ts-hook-ZpBacA07.mjs → register-ts-hook-BhzVkej0.mjs} +799 -446
- package/dist/register-ts-hook-BhzVkej0.mjs.map +1 -0
- package/dist/{registry-DH4m7eYo.mjs → registry-BSbq6SPo.mjs} +4 -3
- package/dist/registry-BSbq6SPo.mjs.map +1 -0
- package/dist/resource_pb-BRv7AMXK.mjs +49 -0
- package/dist/resource_pb-BRv7AMXK.mjs.map +1 -0
- package/dist/runtime/aigateway.d.mts +5 -15
- package/dist/runtime/aigateway.mjs +2 -2
- package/dist/runtime/authconnection.d.mts +5 -15
- package/dist/runtime/authconnection.mjs +2 -2
- package/dist/runtime/context.d.mts +14 -6
- package/dist/runtime/context.mjs +2 -2
- package/dist/runtime/file.d.mts +14 -54
- package/dist/runtime/file.mjs +2 -2
- package/dist/runtime/globals.d.mts +1 -2
- package/dist/runtime/iconv.d.mts +5 -53
- package/dist/runtime/iconv.mjs +2 -2
- package/dist/runtime/idp.d.mts +13 -70
- package/dist/runtime/idp.mjs +2 -2
- package/dist/runtime/index.d.mts +11 -12
- package/dist/runtime/index.mjs +9 -9
- package/dist/runtime/secretmanager.d.mts +7 -20
- package/dist/runtime/secretmanager.mjs +2 -2
- package/dist/runtime/types.d.mts +9 -4
- package/dist/runtime/workflow.d.mts +42 -41
- package/dist/runtime/workflow.mjs +2 -2
- package/dist/{schema-89dYxNC2.mjs → schema-iCd1ugGp.mjs} +257 -54
- package/dist/schema-iCd1ugGp.mjs.map +1 -0
- package/dist/secretmanager-CYlpffsz.mjs +13 -0
- package/dist/secretmanager-CYlpffsz.mjs.map +1 -0
- package/dist/seed/index.d.mts +3 -2
- package/dist/service-BT0GPd01.mjs +3 -0
- package/dist/{service-ufH7sS8o.mjs → service-CzZEVrp9.mjs} +14 -9
- package/dist/service-CzZEVrp9.mjs.map +1 -0
- package/dist/{service_pb-CIrhGwHk.mjs → service_pb-Bk7dL-yT.mjs} +27 -50
- package/dist/service_pb-Bk7dL-yT.mjs.map +1 -0
- package/dist/{service_pb-DjwIn4jO.mjs → service_pb-DZkfjB_6.mjs} +1 -1
- package/dist/tailor-proto/src/tailor/v1/aigateway_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/aigateway_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/application_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/auth_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/events_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/events_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/executor_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/function_registry_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/http_adapter_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/idp_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/idp_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/metadata_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/metadata_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/meter_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/pipeline_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/pipeline_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/secret_manager_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/secret_manager_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +1 -2
- package/dist/tailor-proto/src/tailor/v1/stateflow_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/stateflow_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/tailordb_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/tailordb_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/telemetryrouter_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +29 -10
- package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +35 -2
- package/dist/tailor-proto/src/tailor/v1/workspace_pb.d.mts +0 -1
- package/dist/tailor-proto/src/tailor/v1/workspace_resource_pb.d.mts +0 -1
- package/dist/types/aigateway.generated.d.mts +5 -2
- package/dist/types/auth-connection.generated.d.mts +24 -11
- package/dist/types/auth.generated.d.mts +115 -84
- package/dist/types/executor.generated.d.mts +76 -84
- package/dist/types/helpers.d.mts +7 -6
- package/dist/types/http-adapter.generated.d.mts +11 -5
- package/dist/types/idp.generated.d.mts +536 -524
- package/dist/types/resolver.generated.d.mts +26 -11
- package/dist/types/staticwebsite.generated.d.mts +7 -3
- package/dist/types/tailordb.generated.d.mts +57 -29
- package/dist/types/workflow.generated.d.mts +9 -4
- package/dist/utils/test/index.d.mts +1 -2
- package/dist/utils/test/index.mjs +36 -10
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/utils/test/mock.d.mts +0 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/index.d.mts +1 -1
- package/dist/vitest/index.mjs +11 -11
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mock-kysely.d.mts +0 -1
- package/dist/vitest/mocks/aigateway.d.mts +2 -2
- package/dist/vitest/mocks/authconnection.d.mts +2 -2
- package/dist/vitest/mocks/idp.d.mts +2 -2
- package/dist/vitest/mocks/secretmanager.d.mts +3 -1
- package/dist/vitest/mocks/tailordb.d.mts +6 -3
- package/dist/vitest/mocks/workflow.d.mts +15 -8
- package/dist/vitest/setup.mjs +1 -1
- package/dist/vitest/workflow-local.d.mts +1 -0
- package/dist/workflow-GNuSnsTx.mjs +22 -0
- package/dist/workflow-GNuSnsTx.mjs.map +1 -0
- package/docs/cli/auth.md +3 -3
- package/docs/cli/setup.md +9 -9
- package/docs/cli-reference.md +7 -6
- package/docs/configuration.md +24 -0
- package/docs/migration/v2.md +317 -0
- package/docs/plugin/custom.md +4 -4
- package/docs/plugin/index.md +2 -2
- package/docs/runtime.md +4 -2
- package/docs/services/aigateway.md +2 -0
- package/docs/services/auth.md +2 -2
- package/docs/services/resolver.md +1 -1
- package/docs/services/tailordb-migration.md +1 -1
- package/docs/services/tailordb.md +125 -93
- package/docs/services/workflow.md +78 -0
- package/package.json +22 -22
- package/dist/aigateway-B3oZZE6v.mjs +0 -15
- package/dist/application-D2hSK1ZL.mjs +0 -3
- package/dist/application-eHp9jXld.mjs.map +0 -1
- package/dist/authconnection-BGQM8FZI.mjs +0 -15
- package/dist/authconnection-BGQM8FZI.mjs.map +0 -1
- package/dist/cli/shared/trigger-context.d.mts +0 -1
- package/dist/field-runtime-CAnh_oow.mjs +0 -183
- package/dist/field-runtime-CAnh_oow.mjs.map +0 -1
- package/dist/file-BbdFGdMV.mjs.map +0 -1
- package/dist/file-utils-CYZnO1pX.mjs.map +0 -1
- package/dist/globals-DhwZj0RB.mjs.map +0 -1
- package/dist/iconv-D2vi8G36.mjs +0 -63
- package/dist/iconv-D2vi8G36.mjs.map +0 -1
- package/dist/idp-Bx25ZBdN.mjs.map +0 -1
- package/dist/kysely-type-5eAChaHO.mjs.map +0 -1
- package/dist/register-ts-hook-ZpBacA07.mjs.map +0 -1
- package/dist/registry-DH4m7eYo.mjs.map +0 -1
- package/dist/rolldown-runtime-DXywRVcq.mjs +0 -20
- package/dist/schema-89dYxNC2.mjs.map +0 -1
- package/dist/secretmanager-BVxw3ih_.mjs +0 -24
- package/dist/secretmanager-BVxw3ih_.mjs.map +0 -1
- package/dist/service-CkIwEctX.mjs +0 -3
- package/dist/service-ufH7sS8o.mjs.map +0 -1
- package/dist/service_pb-CIrhGwHk.mjs.map +0 -1
- package/dist/types-C-lQ4se3.mjs +0 -4
- package/dist/types-CXF2OYdR.mjs +0 -199
- package/dist/types-CXF2OYdR.mjs.map +0 -1
- package/dist/workflow-Bo59B75H.mjs +0 -50
- package/dist/workflow-Bo59B75H.mjs.map +0 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { t as db } from "./schema-
|
|
2
|
-
import {
|
|
1
|
+
import { t as db } from "./schema-iCd1ugGp.mjs";
|
|
2
|
+
import { i as PageDirection, n as Condition_Operator, r as FilterSchema, t as ConditionSchema } from "./resource_pb-BRv7AMXK.mjs";
|
|
3
3
|
import { t as assertDefined } from "./assert-DBxo8jPo.mjs";
|
|
4
4
|
import { a as parseBoolean, i as symbols, n as logger, r as styles, t as CIPromptError } from "./logger-BEiZZ3qT.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { c as stripTailorDBTypeBuilderHelpers, h as loadFilesWithIgnores, t as createExecutorService, u as TailorDBTypeSchema } from "./service-
|
|
5
|
+
import { B as readPlatformConfig, C as createBundleCache, Ct as positiveIntArg, D as loadConfig, E as hashFile, Et as workspaceArgs, F as loadMachineUserName, G as writePlatformConfig, H as resolveConfigUser, I as loadPlatformClientConfig, J as fetchAll, M as loadAccessToken, N as loadConfigPath, R as loadWorkspaceId, S as hasGenerationHooks, St as parseDuration, T as hashContent, Tt as toPageDirection, X as fetchMachineUserToken, Y as fetchAllTolerant, Z as fetchPaged, _ as platformBundleDefinePlugin, _t as nonNegativeIntArg, at as initOperatorClient, bt as pagedLogArgs, ct as byName, dt as confirmationArgs, et as getConsoleBaseUrl, f as buildExecutorArgsExpr, ft as deploymentArgs, g as stringifyFunction, h as assertUniqueTailorDBTypeNamesWithExternal, i as resolverBundleKey, m as assertUniqueLocalTailorDBTypeNames, mt as folderArgs, n as generatePluginFilesIfNeeded, nt as getOrNull, o as getApplicationAuthNamespace, ot as isDefaultPlatform, p as buildResolverOperationHookExpr, pt as durationArg, r as loadApplication, rt as getPlatformBaseUrl, s as WorkflowJobFunctionExecutionPolicySchema, st as resolveStaticWebsiteUrls, t as defineApplication, tt as getOAuth2ClientId, u as HTTP_METHODS, ut as configArg, vt as orderArg, w as getDistDir, wt as resolveMachineUserInputSource, x as getPluginGenerationDependencies, xt as paginationArgs, yt as organizationArgs, z as platformConfigFromProfile } from "./application-Bf8wxOi6.mjs";
|
|
6
|
+
import { c as stripTailorDBTypeBuilderHelpers, h as loadFilesWithIgnores, t as createExecutorService, u as TailorDBTypeSchema } from "./service-CzZEVrp9.mjs";
|
|
7
7
|
import { t as multiline } from "./multiline-sfHpTZZK.mjs";
|
|
8
8
|
import { t as readPackageJson } from "./package-json-8b0O9TlX.mjs";
|
|
9
9
|
import { i as userAgent } from "./secret-file-aoNXJmKa.mjs";
|
|
10
10
|
import { n as isCLIError, t as createCLIError } from "./errors-118wUDRr.mjs";
|
|
11
|
+
import { $ as CreateAuthServiceRequestSchema, A as CreatePipelineServiceRequestSchema, At as Subgraph_ServiceType, C as CreateStaticWebsiteRequestSchema, D as CreateSecretManagerVaultRequestSchema, Dt as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, E as CreateSecretManagerSecretRequestSchema, Et as CreateApplicationRequestSchema, F as UpdateIdPServiceRequestSchema, G as ExecutorTriggerType, H as UpdateExecutorExecutorRequestSchema, I as IdPLang, J as CreateAuthIDPConfigRequestSchema, K as CreateAuthConnectionRequestSchema, L as IdPPermissionOperator, M as UpdatePipelineServiceRequestSchema, Mt as UpdateAIGatewayRequestSchema, N as PipelineResolver_OperationType, O as UpdateSecretManagerSecretRequestSchema, Ot as UpdateApplicationRequestSchema, P as CreateIdPServiceRequestSchema, Q as CreateAuthSCIMResourceRequestSchema, R as IdPPermissionPermit, S as AddCustomDomainRequestSchema, St as AuthSCIMConfig_AuthorizationType, Tt as UserProfileProviderConfig_UserProfileProviderType, U as ExecutorJobStatus, V as CreateExecutorExecutorRequestSchema, W as ExecutorTargetType, X as CreateAuthOAuth2ClientRequestSchema, Y as CreateAuthMachineUserRequestSchema, Z as CreateAuthSCIMConfigRequestSchema, _ as TailorDBGQLPermission_Operator, _t as AuthOAuth2Client_ClientType, a as WorkspacePlatformUserRole, at as UpdateAuthMachineUserRequestSchema, b as TailorDBType_Permission_Permit, bt as AuthSCIMAttribute_Type, c as CreateWorkflowRequestSchema, ct as UpdateAuthSCIMResourceRequestSchema, d as WorkflowExecution_Status, dt as UpdateUserProfileConfigRequestSchema, et as CreateTenantConfigRequestSchema, f as WorkflowJobExecution_Status, ft as AuthConnection_Status, g as TailorDBGQLPermission_Action, gt as AuthInvokerSchema, h as UpdateTailorDBTypeRequestSchema, ht as AuthIDPConfig_AuthType, it as UpdateAuthIDPConfigRequestSchema, j as UpdatePipelineResolverRequestSchema, jt as CreateAIGatewayRequestSchema, k as CreatePipelineResolverRequestSchema, kt as ApplicationSchemaUpdateAttemptStatus, l as UpdateWorkflowJobFunctionExecutionPolicyRequestSchema, lt as UpdateAuthServiceRequestSchema, m as CreateTailorDBTypeRequestSchema, mt as AuthHookPoint, nt as UpdateAuthConnectionRequestSchema, o as CreateWorkflowJobFunctionExecutionPolicyRequestSchema, ot as UpdateAuthOAuth2ClientRequestSchema, p as CreateTailorDBServiceRequestSchema, pt as AuthConnection_Type, q as CreateAuthHookRequestSchema, rt as UpdateAuthHookRequestSchema, s as CreateWorkflowJobFunctionRequestSchema, st as UpdateAuthSCIMConfigRequestSchema, t as OperatorService, tt as CreateUserProfileConfigRequestSchema, u as UpdateWorkflowRequestSchema, ut as UpdateTenantConfigRequestSchema, v as TailorDBGQLPermission_Permit, vt as AuthOAuth2Client_GrantType, w as UpdateStaticWebsiteRequestSchema, wt as TenantProviderConfig_TenantProviderType, x as TailorDBType_PermitAction, xt as AuthSCIMAttribute_Uniqueness, y as TailorDBType_Permission_Operator, yt as AuthSCIMAttribute_Mutability, z as FunctionExecution_Status } from "./service_pb-Bk7dL-yT.mjs";
|
|
11
12
|
import { r as withSpan } from "./telemetry-BRVdwh14.mjs";
|
|
12
13
|
import * as mod from "node:module";
|
|
13
14
|
import * as path from "pathe";
|
|
@@ -16,8 +17,7 @@ import { arg, createDefineCommand, defineCommand, runCommand } from "politty";
|
|
|
16
17
|
import { z } from "zod";
|
|
17
18
|
import { ScalarType, create, fromJson, toJson } from "@bufbuild/protobuf";
|
|
18
19
|
import * as fs$1 from "node:fs";
|
|
19
|
-
import {
|
|
20
|
-
import { parseEnv } from "node:util";
|
|
20
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
21
21
|
import { ValueSchema, timestampDate } from "@bufbuild/protobuf/wkt";
|
|
22
22
|
import { formatDistanceToNowStrict } from "date-fns";
|
|
23
23
|
import { getBorderCharacters, table } from "table";
|
|
@@ -48,240 +48,6 @@ import { createPrompt } from "@toiroakr/read-multiline";
|
|
|
48
48
|
import { astVisitor, parse } from "pgsql-ast-parser";
|
|
49
49
|
import { parse as parse$1 } from "@0no-co/graphql.web";
|
|
50
50
|
|
|
51
|
-
//#region src/cli/shared/args.ts
|
|
52
|
-
const unitToMs = {
|
|
53
|
-
ms: 1,
|
|
54
|
-
s: 1e3,
|
|
55
|
-
m: 60 * 1e3
|
|
56
|
-
};
|
|
57
|
-
const durationPattern = /^(\d+)(ms|s|m)$/;
|
|
58
|
-
/**
|
|
59
|
-
* Schema for duration string validation (e.g., "3s", "500ms", "1m")
|
|
60
|
-
* Only validates format; use parseDuration() to convert to milliseconds
|
|
61
|
-
*/
|
|
62
|
-
const durationArg = z.string().refine((val) => durationPattern.test(val), { message: "Invalid duration format. Expected format: '3s', '500ms', '1m'" }).refine((val) => {
|
|
63
|
-
const match = val.match(durationPattern);
|
|
64
|
-
if (!match) return false;
|
|
65
|
-
const digits = match[1];
|
|
66
|
-
return digits !== void 0 && parseInt(digits, 10) > 0;
|
|
67
|
-
}, { message: "Duration must be greater than 0" });
|
|
68
|
-
/**
|
|
69
|
-
* Parse a validated duration string into milliseconds
|
|
70
|
-
* @param duration - Duration string (e.g., "3s", "500ms", "1m")
|
|
71
|
-
* @returns Duration in milliseconds
|
|
72
|
-
*/
|
|
73
|
-
function parseDuration(duration) {
|
|
74
|
-
const match = assertDefined(duration.match(durationPattern), `invalid duration format: ${duration}`);
|
|
75
|
-
const value = parseInt(assertDefined(match[1], "duration digits group missing"), 10);
|
|
76
|
-
const unit = assertDefined(match[2], "duration unit group missing");
|
|
77
|
-
return value * unitToMs[unit];
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Schema for positive integer validation (from string input)
|
|
81
|
-
* Transforms the string to a number
|
|
82
|
-
*/
|
|
83
|
-
const positiveIntArg = z.coerce.number().int().positive();
|
|
84
|
-
/**
|
|
85
|
-
* Schema for non-negative integer validation (from string input).
|
|
86
|
-
* Accepts 0 (used for `--limit 0` to disable the limit).
|
|
87
|
-
*/
|
|
88
|
-
const nonNegativeIntArg = z.coerce.number().int().nonnegative();
|
|
89
|
-
/**
|
|
90
|
-
* Schema for sort order (`asc` or `desc`).
|
|
91
|
-
*/
|
|
92
|
-
const orderArg = z.enum(["asc", "desc"]);
|
|
93
|
-
/**
|
|
94
|
-
* Translate a CLI `--order` value into the proto `PageDirection` enum.
|
|
95
|
-
* Returns `undefined` when the user did not specify an order so that
|
|
96
|
-
* callers can omit the field and fall back to the server default.
|
|
97
|
-
* @param order - Order string from CLI args (`"asc"` | `"desc"` | undefined)
|
|
98
|
-
* @returns PageDirection, or undefined when `order` is undefined
|
|
99
|
-
*/
|
|
100
|
-
function toPageDirection(order) {
|
|
101
|
-
if (order === void 0) return void 0;
|
|
102
|
-
return order === "asc" ? PageDirection.ASC : PageDirection.DESC;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Load env files from parsed arguments.
|
|
106
|
-
* Processes --env-file first, then --env-file-if-exists.
|
|
107
|
-
*
|
|
108
|
-
* Follows Node.js --env-file behavior:
|
|
109
|
-
* - Variables already set in the environment are NOT overwritten
|
|
110
|
-
* - Variables from later files override those from earlier files
|
|
111
|
-
* @param envFiles - Required env file path(s) that must exist
|
|
112
|
-
* @param envFilesIfExists - Optional env file path(s) that are loaded if they exist
|
|
113
|
-
*/
|
|
114
|
-
function loadEnvFiles(envFiles, envFilesIfExists) {
|
|
115
|
-
const originalEnvKeys = new Set(Object.keys(process.env));
|
|
116
|
-
const load = (files, required) => {
|
|
117
|
-
for (const file of [files ?? []].flat()) {
|
|
118
|
-
const envPath = path.resolve(process.cwd(), file);
|
|
119
|
-
if (!fs$1.existsSync(envPath)) {
|
|
120
|
-
if (required) throw new Error(`Environment file not found: ${envPath}`);
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
const parsed = parseEnv(fs$1.readFileSync(envPath, "utf-8"));
|
|
124
|
-
for (const [key, value] of Object.entries(parsed)) {
|
|
125
|
-
if (originalEnvKeys.has(key)) continue;
|
|
126
|
-
process.env[key] = value;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
load(envFiles, true);
|
|
131
|
-
load(envFilesIfExists, false);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Common arguments for all CLI commands
|
|
135
|
-
*
|
|
136
|
-
* NOTE: --env-file and --env-file-if-exists collide with Node.js flags due to a bug
|
|
137
|
-
* (https://github.com/nodejs/node/issues/54232). Node.js parses these even after the
|
|
138
|
-
* script path, causing warnings (twice due to tsx loader).
|
|
139
|
-
*/
|
|
140
|
-
const commonArgs = {
|
|
141
|
-
"env-file": arg(z.string().optional(), {
|
|
142
|
-
alias: "e",
|
|
143
|
-
description: "Path to the environment file (error if not found)",
|
|
144
|
-
completion: {
|
|
145
|
-
type: "file",
|
|
146
|
-
matcher: [".env.*", ".env"]
|
|
147
|
-
}
|
|
148
|
-
}),
|
|
149
|
-
"env-file-if-exists": arg(z.string().optional(), {
|
|
150
|
-
description: "Path to the environment file (ignored if not found)",
|
|
151
|
-
completion: {
|
|
152
|
-
type: "file",
|
|
153
|
-
matcher: [".env.*", ".env"]
|
|
154
|
-
},
|
|
155
|
-
effect: (_value, { args }) => {
|
|
156
|
-
loadEnvFiles(args["env-file"], args["env-file-if-exists"]);
|
|
157
|
-
}
|
|
158
|
-
}),
|
|
159
|
-
verbose: arg(z.boolean().default(false), {
|
|
160
|
-
description: "Enable verbose logging",
|
|
161
|
-
effect: (value) => {
|
|
162
|
-
verboseMode = value;
|
|
163
|
-
}
|
|
164
|
-
}),
|
|
165
|
-
json: arg(z.boolean().default(false), {
|
|
166
|
-
alias: "j",
|
|
167
|
-
description: "Output as JSON",
|
|
168
|
-
effect: (value) => {
|
|
169
|
-
logger.jsonMode = value;
|
|
170
|
-
}
|
|
171
|
-
})
|
|
172
|
-
};
|
|
173
|
-
/**
|
|
174
|
-
* Arguments for commands that require workspace context
|
|
175
|
-
*/
|
|
176
|
-
const workspaceArgs = {
|
|
177
|
-
"workspace-id": arg(z.string().optional(), {
|
|
178
|
-
alias: "w",
|
|
179
|
-
description: "Workspace ID",
|
|
180
|
-
env: "TAILOR_PLATFORM_WORKSPACE_ID",
|
|
181
|
-
completion: { type: "none" }
|
|
182
|
-
}),
|
|
183
|
-
profile: arg(z.string().optional(), {
|
|
184
|
-
alias: "p",
|
|
185
|
-
description: "Workspace profile",
|
|
186
|
-
env: "TAILOR_PLATFORM_PROFILE",
|
|
187
|
-
completion: { type: "none" }
|
|
188
|
-
})
|
|
189
|
-
};
|
|
190
|
-
/**
|
|
191
|
-
* Shared config arg for commands that accept a config file path
|
|
192
|
-
*/
|
|
193
|
-
const configArg = { config: arg(z.string().default("tailor.config.ts"), {
|
|
194
|
-
alias: "c",
|
|
195
|
-
description: "Path to Tailor config file",
|
|
196
|
-
env: "TAILOR_CONFIG_PATH",
|
|
197
|
-
completion: {
|
|
198
|
-
type: "file",
|
|
199
|
-
extensions: ["ts"]
|
|
200
|
-
}
|
|
201
|
-
}) };
|
|
202
|
-
/**
|
|
203
|
-
* Shared config arg for commands that accept one or more comma-separated config file paths
|
|
204
|
-
*/
|
|
205
|
-
const multiConfigArg = { config: arg(z.string().default("tailor.config.ts"), {
|
|
206
|
-
alias: "c",
|
|
207
|
-
description: "Path to SDK config file. Use comma-separated paths to deploy multiple apps together.",
|
|
208
|
-
env: "TAILOR_PLATFORM_SDK_CONFIG_PATH",
|
|
209
|
-
completion: {
|
|
210
|
-
type: "file",
|
|
211
|
-
extensions: ["ts"]
|
|
212
|
-
}
|
|
213
|
-
}) };
|
|
214
|
-
/**
|
|
215
|
-
* Arguments for commands that interact with deployed resources (includes config)
|
|
216
|
-
*/
|
|
217
|
-
const deploymentArgs = {
|
|
218
|
-
...workspaceArgs,
|
|
219
|
-
...configArg
|
|
220
|
-
};
|
|
221
|
-
/**
|
|
222
|
-
* Arguments for commands that require confirmation
|
|
223
|
-
*/
|
|
224
|
-
const confirmationArgs = { yes: arg(z.boolean().default(false), {
|
|
225
|
-
alias: "y",
|
|
226
|
-
description: "Skip confirmation prompts"
|
|
227
|
-
}) };
|
|
228
|
-
/**
|
|
229
|
-
* Arguments for commands that require organization context
|
|
230
|
-
*/
|
|
231
|
-
const organizationArgs = { "organization-id": arg(z.string(), {
|
|
232
|
-
alias: "o",
|
|
233
|
-
description: "Organization ID",
|
|
234
|
-
env: "TAILOR_PLATFORM_ORGANIZATION_ID",
|
|
235
|
-
completion: { type: "none" }
|
|
236
|
-
}) };
|
|
237
|
-
/**
|
|
238
|
-
* Arguments for list commands that accept `--order` / `--limit`. Sort
|
|
239
|
-
* order defaults to `desc` (newest first) because most callers want the
|
|
240
|
-
* latest items; pass `--order asc` to opt in to ascending order. The
|
|
241
|
-
* limit is unbounded by default so existing invocations keep returning
|
|
242
|
-
* every item; pass `--limit N` to cap the result size.
|
|
243
|
-
* @param defaultOrder - Default value for `--order` (defaults to `"desc"`)
|
|
244
|
-
* @returns Argument shape suitable for spreading into a command schema
|
|
245
|
-
*/
|
|
246
|
-
const paginationArgs = (defaultOrder = "desc") => ({
|
|
247
|
-
order: arg(orderArg.default(defaultOrder), { description: "Sort order (asc or desc)" }),
|
|
248
|
-
limit: arg(nonNegativeIntArg.optional(), {
|
|
249
|
-
alias: "l",
|
|
250
|
-
description: "Maximum number of items to return (0 or omit: unlimited)"
|
|
251
|
-
})
|
|
252
|
-
});
|
|
253
|
-
/**
|
|
254
|
-
* Arguments for time-series log list commands. Defaults to newest-first
|
|
255
|
-
* (`desc`) and a 50-item cap so that listing stays responsive on busy
|
|
256
|
-
* workspaces. Pass `--limit 0` to disable the cap and fetch all entries.
|
|
257
|
-
*/
|
|
258
|
-
const pagedLogArgs = {
|
|
259
|
-
order: arg(orderArg.default("desc"), { description: "Sort order (asc or desc)" }),
|
|
260
|
-
limit: arg(nonNegativeIntArg.default(50), {
|
|
261
|
-
alias: "l",
|
|
262
|
-
description: "Maximum number of items to return (0: unlimited)"
|
|
263
|
-
})
|
|
264
|
-
};
|
|
265
|
-
/**
|
|
266
|
-
* Arguments for commands that require folder context
|
|
267
|
-
*/
|
|
268
|
-
const folderArgs = { "folder-id": arg(z.string(), {
|
|
269
|
-
alias: "f",
|
|
270
|
-
description: "Folder ID",
|
|
271
|
-
env: "TAILOR_PLATFORM_FOLDER_ID",
|
|
272
|
-
completion: { type: "none" }
|
|
273
|
-
}) };
|
|
274
|
-
let verboseMode = false;
|
|
275
|
-
/**
|
|
276
|
-
* Returns whether verbose mode is enabled.
|
|
277
|
-
* Used by the global cleanup handler which doesn't have access to parsed args.
|
|
278
|
-
* @returns Whether verbose mode is enabled
|
|
279
|
-
*/
|
|
280
|
-
function isVerbose() {
|
|
281
|
-
return verboseMode;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
//#endregion
|
|
285
51
|
//#region src/cli/shared/command.ts
|
|
286
52
|
/**
|
|
287
53
|
* defineCommand with global args type (CommonArgsType).
|
|
@@ -1601,7 +1367,7 @@ var PluginManager = class {
|
|
|
1601
1367
|
}
|
|
1602
1368
|
/**
|
|
1603
1369
|
* Extend a TailorDB type with new fields.
|
|
1604
|
-
* This method handles the `db.
|
|
1370
|
+
* This method handles the `db.table()` call and metadata copying internally.
|
|
1605
1371
|
* @param params - Parameters for type extension
|
|
1606
1372
|
* @returns The extended TailorDB type
|
|
1607
1373
|
*/
|
|
@@ -1616,7 +1382,7 @@ var PluginManager = class {
|
|
|
1616
1382
|
};
|
|
1617
1383
|
const pluralForm = originalType.metadata.settings?.pluralForm;
|
|
1618
1384
|
const typeName = pluralForm ? [originalType.name, pluralForm] : originalType.name;
|
|
1619
|
-
return copyMetadataToExtendedType(originalType, db.
|
|
1385
|
+
return copyMetadataToExtendedType(originalType, db.table(typeName, fieldsWithoutId));
|
|
1620
1386
|
}
|
|
1621
1387
|
};
|
|
1622
1388
|
/**
|
|
@@ -2531,35 +2297,59 @@ const SecretsStateSchema = z.object({
|
|
|
2531
2297
|
vaults: z.record(z.string(), z.record(z.string(), z.string())),
|
|
2532
2298
|
connections: z.record(z.string(), z.string()).optional()
|
|
2533
2299
|
});
|
|
2300
|
+
const PersistedSecretsStateSchema = z.object({
|
|
2301
|
+
version: z.literal(1),
|
|
2302
|
+
workspaceId: z.string(),
|
|
2303
|
+
applicationKey: z.string(),
|
|
2304
|
+
state: SecretsStateSchema
|
|
2305
|
+
});
|
|
2534
2306
|
/**
|
|
2535
|
-
* Get the file path for
|
|
2536
|
-
* @
|
|
2307
|
+
* Get the file path for one workspace and application's secrets state JSON.
|
|
2308
|
+
* @param scope - Workspace and application identity for the deployment
|
|
2309
|
+
* @returns Absolute path to the scoped state file
|
|
2537
2310
|
*/
|
|
2538
|
-
function getSecretsStatePath() {
|
|
2539
|
-
|
|
2311
|
+
function getSecretsStatePath(scope) {
|
|
2312
|
+
const scopeHash = hashValue(JSON.stringify([scope.workspaceId, applicationStateKey(scope)]));
|
|
2313
|
+
return path.join(getDistDir(), "secrets-state", `${scopeHash}.json`);
|
|
2540
2314
|
}
|
|
2541
|
-
|
|
2542
|
-
* Load secrets hash state from disk.
|
|
2543
|
-
* @returns Persisted state, or empty state if file is missing or corrupted
|
|
2544
|
-
*/
|
|
2545
|
-
function loadSecretsState() {
|
|
2546
|
-
const filePath = getSecretsStatePath();
|
|
2547
|
-
if (!existsSync(filePath)) return { vaults: {} };
|
|
2315
|
+
function loadPersistedSecretsState(scope) {
|
|
2548
2316
|
try {
|
|
2549
|
-
const raw = readFileSync(
|
|
2550
|
-
|
|
2317
|
+
const raw = readFileSync(getSecretsStatePath(scope), "utf-8");
|
|
2318
|
+
const persistedState = PersistedSecretsStateSchema.parse(JSON.parse(raw));
|
|
2319
|
+
if (persistedState.workspaceId !== scope.workspaceId || persistedState.applicationKey !== applicationStateKey(scope)) return;
|
|
2320
|
+
return persistedState;
|
|
2551
2321
|
} catch {
|
|
2552
|
-
return
|
|
2322
|
+
return;
|
|
2553
2323
|
}
|
|
2554
2324
|
}
|
|
2325
|
+
function applicationStateKey(scope) {
|
|
2326
|
+
if (!scope.applicationId) throw new Error(`Application "${scope.applicationName}" has no stable id for secrets state`);
|
|
2327
|
+
return `id:${scope.applicationId}`;
|
|
2328
|
+
}
|
|
2329
|
+
/**
|
|
2330
|
+
* Load secrets hash state for one workspace and application from disk.
|
|
2331
|
+
* @param scope - Workspace and application identity for the deployment
|
|
2332
|
+
* @returns Persisted state, or empty state if the scope is missing or the file is invalid
|
|
2333
|
+
*/
|
|
2334
|
+
function loadSecretsState(scope) {
|
|
2335
|
+
if (!scope.applicationId) return { vaults: {} };
|
|
2336
|
+
return loadPersistedSecretsState(scope)?.state ?? { vaults: {} };
|
|
2337
|
+
}
|
|
2555
2338
|
/**
|
|
2556
|
-
* Save secrets hash state to disk.
|
|
2339
|
+
* Save secrets hash state for one workspace and application to disk.
|
|
2340
|
+
* @param scope - Workspace and application identity for the deployment
|
|
2557
2341
|
* @param state - The secrets state to persist
|
|
2558
2342
|
*/
|
|
2559
|
-
function saveSecretsState(state) {
|
|
2560
|
-
|
|
2343
|
+
function saveSecretsState(scope, state) {
|
|
2344
|
+
if (!scope.applicationId) return;
|
|
2345
|
+
const filePath = getSecretsStatePath(scope);
|
|
2561
2346
|
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
2562
|
-
writeFileSync(filePath, JSON.stringify(
|
|
2347
|
+
writeFileSync(filePath, JSON.stringify({
|
|
2348
|
+
version: 1,
|
|
2349
|
+
workspaceId: scope.workspaceId,
|
|
2350
|
+
applicationKey: applicationStateKey(scope),
|
|
2351
|
+
state
|
|
2352
|
+
}, null, 2), "utf-8");
|
|
2563
2353
|
}
|
|
2564
2354
|
/**
|
|
2565
2355
|
* Compute SHA-256 hex digest of a value.
|
|
@@ -2625,6 +2415,11 @@ function buildUpdateMask(existing, desired, secretChanged) {
|
|
|
2625
2415
|
* @returns Planned changes for auth connections
|
|
2626
2416
|
*/
|
|
2627
2417
|
async function planAuthConnections(client, workspaceId, appName, appId, auths) {
|
|
2418
|
+
const stateScope = {
|
|
2419
|
+
workspaceId,
|
|
2420
|
+
applicationId: appId,
|
|
2421
|
+
applicationName: appName
|
|
2422
|
+
};
|
|
2628
2423
|
const changeSet = createChangeSet("Auth connections");
|
|
2629
2424
|
const conflicts = [];
|
|
2630
2425
|
const unmanaged = [];
|
|
@@ -2648,7 +2443,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
|
|
|
2648
2443
|
allLabels: metadata?.labels
|
|
2649
2444
|
};
|
|
2650
2445
|
}));
|
|
2651
|
-
const state = loadSecretsState();
|
|
2446
|
+
const state = loadSecretsState(stateScope);
|
|
2652
2447
|
for (const [name, config] of Object.entries(desiredConnections)) {
|
|
2653
2448
|
const existing = existingConnections[name];
|
|
2654
2449
|
const metaRequest = await buildMetaRequest({
|
|
@@ -2709,7 +2504,8 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
|
|
|
2709
2504
|
changeSet,
|
|
2710
2505
|
conflicts,
|
|
2711
2506
|
unmanaged,
|
|
2712
|
-
resourceOwners
|
|
2507
|
+
resourceOwners,
|
|
2508
|
+
stateScope
|
|
2713
2509
|
};
|
|
2714
2510
|
}
|
|
2715
2511
|
/**
|
|
@@ -2719,7 +2515,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
|
|
|
2719
2515
|
* @param phase - Apply phase
|
|
2720
2516
|
*/
|
|
2721
2517
|
async function applyAuthConnections(client, result, phase) {
|
|
2722
|
-
const { changeSet } = result;
|
|
2518
|
+
const { changeSet, stateScope } = result;
|
|
2723
2519
|
if (phase === "create-update") {
|
|
2724
2520
|
await Promise.all(changeSet.creates.map(async (create) => {
|
|
2725
2521
|
await client.createAuthConnection(create.request);
|
|
@@ -2733,26 +2529,29 @@ async function applyAuthConnections(client, result, phase) {
|
|
|
2733
2529
|
await Promise.all(changeSet.updates.map(async (update) => {
|
|
2734
2530
|
await client.setMetadata(update.metaRequest);
|
|
2735
2531
|
}));
|
|
2736
|
-
const
|
|
2737
|
-
if (
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2532
|
+
const secretReplaces = changeSet.replaces.filter((replace) => replace.updateRequest.updateMask?.paths?.includes("oauth2.client_secret"));
|
|
2533
|
+
if (changeSet.creates.length > 0 || secretReplaces.length > 0) {
|
|
2534
|
+
const state = loadSecretsState(stateScope);
|
|
2535
|
+
if (!state.connections) state.connections = {};
|
|
2536
|
+
for (const create of changeSet.creates) {
|
|
2537
|
+
const conn = create.request.connection;
|
|
2538
|
+
if (conn?.config?.case === "oauth2") state.connections[create.name] = hashValue(conn.config.value.clientSecret ?? "");
|
|
2539
|
+
}
|
|
2540
|
+
for (const replace of secretReplaces) {
|
|
2541
|
+
const conn = replace.updateRequest.connection;
|
|
2542
|
+
if (conn?.config?.case === "oauth2") state.connections[replace.name] = hashValue(conn.config.value.clientSecret ?? "");
|
|
2543
|
+
}
|
|
2544
|
+
saveSecretsState(stateScope, state);
|
|
2745
2545
|
}
|
|
2746
|
-
saveSecretsState(state);
|
|
2747
2546
|
} else {
|
|
2748
2547
|
await Promise.all(changeSet.deletes.map(async (del) => {
|
|
2749
2548
|
await client.deleteAuthConnection(del.request);
|
|
2750
2549
|
}));
|
|
2751
2550
|
if (changeSet.deletes.length > 0) {
|
|
2752
|
-
const state = loadSecretsState();
|
|
2551
|
+
const state = loadSecretsState(stateScope);
|
|
2753
2552
|
if (state.connections) {
|
|
2754
2553
|
for (const del of changeSet.deletes) delete state.connections[del.name];
|
|
2755
|
-
saveSecretsState(state);
|
|
2554
|
+
saveSecretsState(stateScope, state);
|
|
2756
2555
|
}
|
|
2757
2556
|
}
|
|
2758
2557
|
}
|
|
@@ -3915,7 +3714,10 @@ async function applyAuth(client, result, phase = "create-update") {
|
|
|
3915
3714
|
await Promise.all([...changeSet.machineUser.creates.map((create) => client.createAuthMachineUser(create.request)), ...changeSet.machineUser.updates.map((update) => client.updateAuthMachineUser(update.request))]);
|
|
3916
3715
|
};
|
|
3917
3716
|
const applyCreateUpdateDependents = async () => {
|
|
3918
|
-
await applyAuthConnections(client, {
|
|
3717
|
+
await applyAuthConnections(client, {
|
|
3718
|
+
changeSet: changeSet.connection,
|
|
3719
|
+
stateScope: result.connectionStateScope
|
|
3720
|
+
}, "create-update");
|
|
3919
3721
|
await Promise.all([...changeSet.idpConfig.creates.map(async (create) => {
|
|
3920
3722
|
if (create.idpConfig.kind === "BuiltInIdP") assertDefined(create.request.idpConfig, "request missing idpConfig").config = await protoBuiltinIdPConfig(client, assertDefined(create.request.workspaceId, "request missing workspaceId"), create.idpConfig);
|
|
3921
3723
|
return client.createAuthIDPConfig(create.request);
|
|
@@ -3958,7 +3760,10 @@ async function applyAuth(client, result, phase = "create-update") {
|
|
|
3958
3760
|
await Promise.all(changeSet.tenantConfig.deletes.map((del) => client.deleteTenantConfig(del.request)));
|
|
3959
3761
|
await Promise.all(changeSet.userProfileConfig.deletes.map((del) => client.deleteUserProfileConfig(del.request)));
|
|
3960
3762
|
await Promise.all(changeSet.idpConfig.deletes.map((del) => client.deleteAuthIDPConfig(del.request)));
|
|
3961
|
-
await applyAuthConnections(client, {
|
|
3763
|
+
await applyAuthConnections(client, {
|
|
3764
|
+
changeSet: changeSet.connection,
|
|
3765
|
+
stateScope: result.connectionStateScope
|
|
3766
|
+
}, "delete-resources");
|
|
3962
3767
|
} else if (phase === "delete-services") await Promise.all(changeSet.service.deletes.map((del) => client.deleteAuthService(del.request)));
|
|
3963
3768
|
}
|
|
3964
3769
|
/**
|
|
@@ -4002,7 +3807,8 @@ async function planAuth(context) {
|
|
|
4002
3807
|
},
|
|
4003
3808
|
conflicts: [...conflicts, ...connectionResult.conflicts],
|
|
4004
3809
|
unmanaged: [...unmanaged, ...connectionResult.unmanaged],
|
|
4005
|
-
resourceOwners: /* @__PURE__ */ new Set([...resourceOwners, ...connectionResult.resourceOwners])
|
|
3810
|
+
resourceOwners: /* @__PURE__ */ new Set([...resourceOwners, ...connectionResult.resourceOwners]),
|
|
3811
|
+
connectionStateScope: connectionResult.stateScope
|
|
4006
3812
|
};
|
|
4007
3813
|
}
|
|
4008
3814
|
async function planServices$2(client, workspaceId, appName, appId, auths, forceApplyAll = false) {
|
|
@@ -5878,7 +5684,12 @@ async function planSecretManager(context) {
|
|
|
5878
5684
|
getName: (resource) => resource.name,
|
|
5879
5685
|
getTrn: (name) => resourceTrn(workspaceId, "vault", name)
|
|
5880
5686
|
});
|
|
5881
|
-
const
|
|
5687
|
+
const stateScope = {
|
|
5688
|
+
workspaceId,
|
|
5689
|
+
applicationId: application.id,
|
|
5690
|
+
applicationName: application.name
|
|
5691
|
+
};
|
|
5692
|
+
const state = loadSecretsState(stateScope);
|
|
5882
5693
|
const skippedSecrets = [];
|
|
5883
5694
|
await Promise.all(secretVaults.map(async (vault) => {
|
|
5884
5695
|
const vaultName = vault.vaultName;
|
|
@@ -5987,7 +5798,8 @@ async function planSecretManager(context) {
|
|
|
5987
5798
|
skippedSecrets,
|
|
5988
5799
|
conflicts,
|
|
5989
5800
|
unmanaged,
|
|
5990
|
-
resourceOwners
|
|
5801
|
+
resourceOwners,
|
|
5802
|
+
stateScope
|
|
5991
5803
|
};
|
|
5992
5804
|
}
|
|
5993
5805
|
/**
|
|
@@ -5995,11 +5807,11 @@ async function planSecretManager(context) {
|
|
|
5995
5807
|
* @param client - Operator client instance
|
|
5996
5808
|
* @param result - Planned secret changes
|
|
5997
5809
|
* @param phase - Apply phase
|
|
5998
|
-
* @param application - Application
|
|
5810
|
+
* @param application - Application used for ownership metadata and hash state persistence
|
|
5999
5811
|
* @returns Promise that resolves when secret changes are applied
|
|
6000
5812
|
*/
|
|
6001
5813
|
async function applySecretManager(client, result, phase = "create-update", application) {
|
|
6002
|
-
const { vaultChangeSet, secretChangeSet } = result;
|
|
5814
|
+
const { vaultChangeSet, secretChangeSet, stateScope } = result;
|
|
6003
5815
|
if (phase === "create-update") {
|
|
6004
5816
|
await Promise.all(vaultChangeSet.creates.map(async (create) => {
|
|
6005
5817
|
await client.createSecretManagerVault(vaultCreateRequest(create));
|
|
@@ -6022,13 +5834,14 @@ async function applySecretManager(client, result, phase = "create-update", appli
|
|
|
6022
5834
|
}));
|
|
6023
5835
|
await Promise.all(secretChangeSet.creates.map((create) => client.createSecretManagerSecret(secretCreateRequest(create))));
|
|
6024
5836
|
await Promise.all(secretChangeSet.updates.map((update) => client.updateSecretManagerSecret(secretUpdateRequest(update))));
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
5837
|
+
const secretHashUpdates = [...secretChangeSet.creates, ...secretChangeSet.updates];
|
|
5838
|
+
if (application && secretHashUpdates.length > 0) {
|
|
5839
|
+
const state = loadSecretsState(stateScope);
|
|
5840
|
+
for (const secret of secretHashUpdates) {
|
|
5841
|
+
if (!Object.hasOwn(state.vaults, secret.vaultName)) state.vaults[secret.vaultName] = {};
|
|
5842
|
+
assertDefined(state.vaults[secret.vaultName], "vault state entry missing")[secret.secretName] = hashValue(secret.value);
|
|
6030
5843
|
}
|
|
6031
|
-
saveSecretsState(state);
|
|
5844
|
+
saveSecretsState(stateScope, state);
|
|
6032
5845
|
}
|
|
6033
5846
|
} else {
|
|
6034
5847
|
await Promise.all(secretChangeSet.deletes.map((del) => client.deleteSecretManagerSecret({
|
|
@@ -6041,13 +5854,13 @@ async function applySecretManager(client, result, phase = "create-update", appli
|
|
|
6041
5854
|
secretmanagerVaultName: del.name
|
|
6042
5855
|
})));
|
|
6043
5856
|
if (secretChangeSet.deletes.length > 0 || vaultChangeSet.deletes.length > 0) {
|
|
6044
|
-
const state = loadSecretsState();
|
|
5857
|
+
const state = loadSecretsState(stateScope);
|
|
6045
5858
|
for (const del of secretChangeSet.deletes) if (Object.hasOwn(state.vaults, del.vaultName)) {
|
|
6046
5859
|
delete assertDefined(state.vaults[del.vaultName], "vault state entry missing")[del.secretName];
|
|
6047
5860
|
if (Object.keys(assertDefined(state.vaults[del.vaultName], "vault state entry missing")).length === 0) delete state.vaults[del.vaultName];
|
|
6048
5861
|
}
|
|
6049
5862
|
for (const del of vaultChangeSet.deletes) delete state.vaults[del.name];
|
|
6050
|
-
saveSecretsState(state);
|
|
5863
|
+
saveSecretsState(stateScope, state);
|
|
6051
5864
|
}
|
|
6052
5865
|
}
|
|
6053
5866
|
}
|
|
@@ -6142,6 +5955,7 @@ function formatDiffChange(change) {
|
|
|
6142
5955
|
case "relationship_removed": return ` - [Relationship${change.relationshipType ? ` (${change.relationshipType})` : ""}] ${change.relationshipName}`;
|
|
6143
5956
|
case "relationship_modified": return ` ~ [Relationship${change.relationshipType ? ` (${change.relationshipType})` : ""}] ${change.relationshipName}: ${change.reason ?? "modified"}`;
|
|
6144
5957
|
case "permission_modified": return ` ~ [Permission] ${change.reason ?? "modified"}`;
|
|
5958
|
+
case "type_scripts_modified": return ` ~ [Type Scripts] ${change.typeName}: ${change.reason ?? "type-level hooks/validate changed"}`;
|
|
6145
5959
|
default: {
|
|
6146
5960
|
const unknown = change;
|
|
6147
5961
|
return ` ? ${unknown.typeName}.${unknown.fieldName ?? ""}`;
|
|
@@ -6236,7 +6050,8 @@ const DIFF_CHANGE_LABELS = {
|
|
|
6236
6050
|
relationship_added: "relationship(s) added",
|
|
6237
6051
|
relationship_removed: "relationship(s) removed",
|
|
6238
6052
|
relationship_modified: "relationship(s) modified",
|
|
6239
|
-
permission_modified: "permission(s) modified"
|
|
6053
|
+
permission_modified: "permission(s) modified",
|
|
6054
|
+
type_scripts_modified: "type script(s) modified"
|
|
6240
6055
|
};
|
|
6241
6056
|
/**
|
|
6242
6057
|
* Format a summary of the migration diff
|
|
@@ -6250,6 +6065,181 @@ function formatDiffSummary(diff) {
|
|
|
6250
6065
|
return parts.length > 0 ? parts.join(", ") : "No changes";
|
|
6251
6066
|
}
|
|
6252
6067
|
|
|
6068
|
+
//#endregion
|
|
6069
|
+
//#region src/parser/service/tailordb/type-script.ts
|
|
6070
|
+
const INPUT = "_input";
|
|
6071
|
+
const NEW_RECORD = "_newRecord";
|
|
6072
|
+
const OLD_RECORD = "_oldRecord";
|
|
6073
|
+
const NOW = "_now";
|
|
6074
|
+
const SOURCE_HASH_PREFIX = "// @sdk-source-hash:";
|
|
6075
|
+
const TIME_TYPES = /* @__PURE__ */ new Set([
|
|
6076
|
+
"datetime",
|
|
6077
|
+
"date",
|
|
6078
|
+
"time"
|
|
6079
|
+
]);
|
|
6080
|
+
const key = (name) => JSON.stringify(name);
|
|
6081
|
+
function collectFieldScriptSources(fields) {
|
|
6082
|
+
const entries = [];
|
|
6083
|
+
for (const [name, config] of Object.entries(fields).toSorted(([a], [b]) => a.localeCompare(b))) {
|
|
6084
|
+
const data = {};
|
|
6085
|
+
if (config.hooks?.create?.expr) data.hc = config.hooks.create.expr;
|
|
6086
|
+
if (config.hooks?.update?.expr) data.hu = config.hooks.update.expr;
|
|
6087
|
+
if (config.validate?.some((v) => v.script?.expr)) data.v = config.validate.filter((v) => v.script?.expr).map((v) => [v.script?.expr, v.errorMessage]);
|
|
6088
|
+
if (config.default !== void 0) {
|
|
6089
|
+
data.d = config.default instanceof Date ? config.default.toISOString() : config.default;
|
|
6090
|
+
data.t = config.type;
|
|
6091
|
+
}
|
|
6092
|
+
if (config.fields) {
|
|
6093
|
+
const nested = collectFieldScriptSources(config.fields);
|
|
6094
|
+
if (nested.length > 0) {
|
|
6095
|
+
data.f = nested;
|
|
6096
|
+
data.a = !!config.array;
|
|
6097
|
+
}
|
|
6098
|
+
}
|
|
6099
|
+
if (Object.keys(data).length > 0) entries.push([name, data]);
|
|
6100
|
+
}
|
|
6101
|
+
return entries;
|
|
6102
|
+
}
|
|
6103
|
+
function computeSourceScriptHash(fields, options) {
|
|
6104
|
+
const fieldSources = collectFieldScriptSources(fields);
|
|
6105
|
+
if (!(fieldSources.length > 0 || options?.typeHookExpr?.create || options?.typeHookExpr?.update || options?.typeValidateExpr)) return void 0;
|
|
6106
|
+
const payload = [fieldSources];
|
|
6107
|
+
if (options?.typeHookExpr?.create) payload.push(["thc", options.typeHookExpr.create]);
|
|
6108
|
+
if (options?.typeHookExpr?.update) payload.push(["thu", options.typeHookExpr.update]);
|
|
6109
|
+
if (options?.typeValidateExpr) payload.push(["tve", options.typeValidateExpr]);
|
|
6110
|
+
return createHash("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
6111
|
+
}
|
|
6112
|
+
function extractSourceScriptHash(expr) {
|
|
6113
|
+
return expr.match(/\/\/ @sdk-source-hash:([0-9a-f]+)\s*$/)?.[1];
|
|
6114
|
+
}
|
|
6115
|
+
const isNestedType = (config) => config.type === "nested" && config.fields !== void 0;
|
|
6116
|
+
function serializeDefault(value, fieldType) {
|
|
6117
|
+
if (value === "now" && TIME_TYPES.has(fieldType)) return NOW;
|
|
6118
|
+
if (value instanceof Date) return `new Date(${JSON.stringify(value.toISOString())})`;
|
|
6119
|
+
return JSON.stringify(value);
|
|
6120
|
+
}
|
|
6121
|
+
/**
|
|
6122
|
+
* Build the object literal that reconstructs one record level with hook
|
|
6123
|
+
* overrides and defaults applied. For create, defaults are appended as
|
|
6124
|
+
* `?? defaultValue` after the hook expression (field hook → default).
|
|
6125
|
+
* Returns null when no field under this level has a hook or default for
|
|
6126
|
+
* the operation.
|
|
6127
|
+
* @param {Record<string, ScriptFieldConfig>} fields - Field configurations
|
|
6128
|
+
* @param {string} accessExpr - JS expression to access the parent object
|
|
6129
|
+
* @param {string} oldAccessExpr - JS expression to access the old record parent
|
|
6130
|
+
* @param {HookOperation} operation - Hook operation type
|
|
6131
|
+
* @param {boolean} nested - Whether building inside a nested field (rejects defaults)
|
|
6132
|
+
* @returns {string | null} Object literal expression or null
|
|
6133
|
+
*/
|
|
6134
|
+
function buildHookObject(fields, accessExpr, oldAccessExpr, operation, nested = false) {
|
|
6135
|
+
const parts = [];
|
|
6136
|
+
for (const [name, config] of Object.entries(fields)) {
|
|
6137
|
+
const access = `${accessExpr}[${key(name)}]`;
|
|
6138
|
+
const oldAccess = `${oldAccessExpr}?.[${key(name)}]`;
|
|
6139
|
+
if (isNestedType(config) && config.fields) {
|
|
6140
|
+
if (config.array) {
|
|
6141
|
+
const inner = buildHookObject(config.fields, "__el", "undefined", operation, true);
|
|
6142
|
+
if (inner !== null) parts.push(`${key(name)}: (${access} || []).map((__el) => Object.assign({}, __el, ${inner}))`);
|
|
6143
|
+
} else {
|
|
6144
|
+
const inner = buildHookObject(config.fields, `(${access} || {})`, oldAccess, operation, true);
|
|
6145
|
+
if (inner !== null) parts.push(`${key(name)}: Object.assign({}, ${access}, ${inner})`);
|
|
6146
|
+
}
|
|
6147
|
+
continue;
|
|
6148
|
+
}
|
|
6149
|
+
const hook = config.hooks?.[operation];
|
|
6150
|
+
if (nested && config.default !== void 0) throw new Error(`.default() cannot be used on nested inner field "${name}"`);
|
|
6151
|
+
const hasDefault = operation === "create" && config.default !== void 0;
|
|
6152
|
+
if (hook && hasDefault) parts.push(`${key(name)}: ((_value) => (${hook.expr}))(${access}) ?? ${serializeDefault(config.default, config.type)}`);
|
|
6153
|
+
else if (hook && operation === "create") parts.push(`${key(name)}: ((_value) => (${hook.expr}))(${access})`);
|
|
6154
|
+
else if (hook) parts.push(`${key(name)}: ((_value, _oldValue) => (${hook.expr}))(${access}, ${oldAccess} ?? null)`);
|
|
6155
|
+
else if (hasDefault) parts.push(`${key(name)}: ${access} ?? ${serializeDefault(config.default, config.type)}`);
|
|
6156
|
+
}
|
|
6157
|
+
if (parts.length === 0) return null;
|
|
6158
|
+
return `{ ${parts.join(", ")} }`;
|
|
6159
|
+
}
|
|
6160
|
+
/**
|
|
6161
|
+
* Build validation statements for one record level.
|
|
6162
|
+
* Each leaf field with validators contributes a block that runs every
|
|
6163
|
+
* validator and records all failing messages keyed by dotted field path.
|
|
6164
|
+
* @param {Record<string, ScriptFieldConfig>} fields - Field configurations
|
|
6165
|
+
* @param {string} accessExpr - JS expression to access the parent object
|
|
6166
|
+
* @param {string} keyPrefix - Dotted path prefix for error keys
|
|
6167
|
+
* @returns {string[]} Array of validation statement strings
|
|
6168
|
+
*/
|
|
6169
|
+
function buildValidateStatements(fields, accessExpr, keyPrefix) {
|
|
6170
|
+
const statements = [];
|
|
6171
|
+
for (const [name, config] of Object.entries(fields)) {
|
|
6172
|
+
const access = `${accessExpr}[${key(name)}]`;
|
|
6173
|
+
const fieldPath = keyPrefix ? `${keyPrefix}.${name}` : name;
|
|
6174
|
+
const validators = (config.validate ?? []).filter((v) => v.script?.expr);
|
|
6175
|
+
if (validators.length > 0) {
|
|
6176
|
+
const checks = validators.map((v) => `{ const __r = (${v.script?.expr}); if (typeof __r === "string") { __errs[${key(fieldPath)}] = __r; } }`).join("\n");
|
|
6177
|
+
statements.push(`{ const _value = ${access};\n${checks}\n}`);
|
|
6178
|
+
}
|
|
6179
|
+
if (isNestedType(config) && config.fields) if (config.array) {
|
|
6180
|
+
const innerParts = [];
|
|
6181
|
+
for (const [innerName, innerConfig] of Object.entries(config.fields)) {
|
|
6182
|
+
const innerValidators = (innerConfig.validate ?? []).filter((v) => v.script?.expr);
|
|
6183
|
+
if (innerValidators.length > 0) {
|
|
6184
|
+
const errorKeyExpr = `${JSON.stringify(fieldPath + "[")} + __idx + ${JSON.stringify("]." + innerName)}`;
|
|
6185
|
+
const checks = innerValidators.map((v) => `{ const __r = (${v.script?.expr}); if (typeof __r === "string") { __errs[${errorKeyExpr}] = __r; } }`).join("\n");
|
|
6186
|
+
innerParts.push(`{ const _value = __el[${key(innerName)}];\n${checks}\n}`);
|
|
6187
|
+
}
|
|
6188
|
+
}
|
|
6189
|
+
if (innerParts.length > 0) statements.push(`(${access} || []).forEach((__el, __idx) => {\n${innerParts.join("\n")}\n});`);
|
|
6190
|
+
} else {
|
|
6191
|
+
const nested = buildValidateStatements(config.fields, access, fieldPath);
|
|
6192
|
+
if (nested.length > 0) statements.push(`if (${access} != null) {\n${nested.join("\n")}\n}`);
|
|
6193
|
+
}
|
|
6194
|
+
}
|
|
6195
|
+
return statements;
|
|
6196
|
+
}
|
|
6197
|
+
function wrapHook(objectExpr) {
|
|
6198
|
+
return `((_invoker) => { const ${NOW} = new Date(); return ${objectExpr}; })(typeof _invoker !== "undefined" ? _invoker : undefined)`;
|
|
6199
|
+
}
|
|
6200
|
+
function wrapValidate(statements, typeValidateExpr) {
|
|
6201
|
+
const issuesFn = typeValidateExpr ? " const __issues = (f, m) => { __errs[f] = m; };" : "";
|
|
6202
|
+
const typeValidateStmt = typeValidateExpr ? ` ${typeValidateExpr};` : "";
|
|
6203
|
+
return `((_invoker) => { const __errs = {};${issuesFn}\n${statements.join("\n")}${typeValidateStmt}\nreturn __errs; })(typeof _invoker !== "undefined" ? _invoker : undefined)`;
|
|
6204
|
+
}
|
|
6205
|
+
/**
|
|
6206
|
+
* Aggregate every field's create/update hook, default, and validate into
|
|
6207
|
+
* type-level scripts. Hooks compute a single shared timestamp (`now`) per
|
|
6208
|
+
* operation, so all fields touched in one create/update observe the same
|
|
6209
|
+
* instant. Defaults are applied after hooks on create only. Validators
|
|
6210
|
+
* run with the same rules on create and update.
|
|
6211
|
+
* @param fields - Per-field script configuration
|
|
6212
|
+
* @param options - Optional type-level hook/validate expressions
|
|
6213
|
+
* @returns Aggregated type-level scripts
|
|
6214
|
+
*/
|
|
6215
|
+
function buildTypeScripts(fields, options) {
|
|
6216
|
+
const result = {};
|
|
6217
|
+
const typeHookExpr = options?.typeHookExpr;
|
|
6218
|
+
const typeValidateExpr = options?.typeValidateExpr;
|
|
6219
|
+
const hash = computeSourceScriptHash(fields, options);
|
|
6220
|
+
const hashSuffix = hash ? ` ${SOURCE_HASH_PREFIX}${hash}` : "";
|
|
6221
|
+
const hook = {};
|
|
6222
|
+
for (const operation of ["create", "update"]) {
|
|
6223
|
+
const perFieldExpr = buildHookObject(fields, INPUT, OLD_RECORD, operation);
|
|
6224
|
+
const typeLevelExpr = typeHookExpr?.[operation];
|
|
6225
|
+
let expr;
|
|
6226
|
+
if (perFieldExpr !== null && typeLevelExpr) expr = `((_invoker) => { const ${NOW} = new Date(); const __fl = ${perFieldExpr}; return Object.assign({}, __fl, ((${INPUT}) => ${typeLevelExpr})(Object.assign({}, ${INPUT}, __fl))); })(typeof _invoker !== "undefined" ? _invoker : undefined)`;
|
|
6227
|
+
else if (typeLevelExpr) expr = wrapHook(typeLevelExpr);
|
|
6228
|
+
else if (perFieldExpr !== null) expr = wrapHook(perFieldExpr);
|
|
6229
|
+
if (expr) hook[operation] = { expr: expr + hashSuffix };
|
|
6230
|
+
}
|
|
6231
|
+
if (hook.create || hook.update) result.typeHook = hook;
|
|
6232
|
+
const statements = buildValidateStatements(fields, NEW_RECORD, "");
|
|
6233
|
+
if (statements.length > 0 || typeValidateExpr) {
|
|
6234
|
+
const expr = wrapValidate(statements, typeValidateExpr) + hashSuffix;
|
|
6235
|
+
result.typeValidate = {
|
|
6236
|
+
create: { expr },
|
|
6237
|
+
update: { expr }
|
|
6238
|
+
};
|
|
6239
|
+
}
|
|
6240
|
+
return result;
|
|
6241
|
+
}
|
|
6242
|
+
|
|
6253
6243
|
//#endregion
|
|
6254
6244
|
//#region src/cli/commands/tailordb/migrate/migration-number.ts
|
|
6255
6245
|
/**
|
|
@@ -6341,6 +6331,7 @@ const snapshotFieldConfigSchema = z.looseObject({
|
|
|
6341
6331
|
validate: z.array(snapshotValidationSchema).optional(),
|
|
6342
6332
|
serial: snapshotSerialSchema.optional(),
|
|
6343
6333
|
scale: z.number().optional(),
|
|
6334
|
+
default: z.unknown().optional(),
|
|
6344
6335
|
fields: z.lazy(() => snapshotRecordSchema(snapshotFieldConfigSchema)).optional()
|
|
6345
6336
|
});
|
|
6346
6337
|
const snapshotIndexConfigSchema = z.looseObject({
|
|
@@ -6586,6 +6577,20 @@ const permissionModifiedChangeSchema = z.looseObject({
|
|
|
6586
6577
|
before: snapshotPermissionStateSchema.optional(),
|
|
6587
6578
|
after: snapshotPermissionStateSchema.optional()
|
|
6588
6579
|
});
|
|
6580
|
+
const typeScriptsStateSchema = z.looseObject({
|
|
6581
|
+
typeHookExpr: z.looseObject({
|
|
6582
|
+
create: z.string().optional(),
|
|
6583
|
+
update: z.string().optional()
|
|
6584
|
+
}).optional(),
|
|
6585
|
+
typeValidateExpr: z.string().optional()
|
|
6586
|
+
});
|
|
6587
|
+
const typeScriptsModifiedChangeSchema = z.looseObject({
|
|
6588
|
+
kind: z.literal("type_scripts_modified"),
|
|
6589
|
+
typeName: z.string(),
|
|
6590
|
+
reason: z.string().optional(),
|
|
6591
|
+
before: typeScriptsStateSchema,
|
|
6592
|
+
after: typeScriptsStateSchema
|
|
6593
|
+
});
|
|
6589
6594
|
const diffChangeSchema = z.discriminatedUnion("kind", [
|
|
6590
6595
|
typeAddedChangeSchema,
|
|
6591
6596
|
typeRemovedChangeSchema,
|
|
@@ -6603,7 +6608,8 @@ const diffChangeSchema = z.discriminatedUnion("kind", [
|
|
|
6603
6608
|
relationshipAddedChangeSchema,
|
|
6604
6609
|
relationshipRemovedChangeSchema,
|
|
6605
6610
|
relationshipModifiedChangeSchema,
|
|
6606
|
-
permissionModifiedChangeSchema
|
|
6611
|
+
permissionModifiedChangeSchema,
|
|
6612
|
+
typeScriptsModifiedChangeSchema
|
|
6607
6613
|
]);
|
|
6608
6614
|
const breakingChangeInfoSchema = z.looseObject({
|
|
6609
6615
|
typeName: z.string(),
|
|
@@ -6807,6 +6813,7 @@ function createSnapshotFieldConfigFromOperatorConfig(fieldConfig) {
|
|
|
6807
6813
|
...fieldConfig.serial.format && { format: fieldConfig.serial.format }
|
|
6808
6814
|
};
|
|
6809
6815
|
if (fieldConfig.scale !== void 0) config.scale = fieldConfig.scale;
|
|
6816
|
+
if (fieldConfig.default !== void 0) config.default = fieldConfig.default;
|
|
6810
6817
|
if (fieldConfig.fields && Object.keys(fieldConfig.fields).length > 0) {
|
|
6811
6818
|
config.fields = {};
|
|
6812
6819
|
for (const [nestedName, nestedConfig] of Object.entries(fieldConfig.fields)) config.fields[nestedName] = createSnapshotFieldConfigFromOperatorConfig(nestedConfig);
|
|
@@ -6848,6 +6855,8 @@ function createSnapshotType(type) {
|
|
|
6848
6855
|
};
|
|
6849
6856
|
}
|
|
6850
6857
|
if (type.files && Object.keys(type.files).length > 0) snapshotType.files = { ...type.files };
|
|
6858
|
+
if (type.typeHookExpr) snapshotType.typeHookExpr = type.typeHookExpr;
|
|
6859
|
+
if (type.typeValidateExpr) snapshotType.typeValidateExpr = type.typeValidateExpr;
|
|
6851
6860
|
if (Object.keys(type.forwardRelationships).length > 0) {
|
|
6852
6861
|
snapshotType.forwardRelationships = {};
|
|
6853
6862
|
for (const [relName, rel] of Object.entries(type.forwardRelationships)) snapshotType.forwardRelationships[relName] = {
|
|
@@ -7031,6 +7040,18 @@ function applyDiffToSnapshot(snapshot, diff) {
|
|
|
7031
7040
|
};
|
|
7032
7041
|
break;
|
|
7033
7042
|
}
|
|
7043
|
+
case "type_scripts_modified": {
|
|
7044
|
+
const existing = types[change.typeName];
|
|
7045
|
+
if (existing) {
|
|
7046
|
+
const { typeHookExpr: _, typeValidateExpr: __, ...rest } = existing;
|
|
7047
|
+
types[change.typeName] = {
|
|
7048
|
+
...rest,
|
|
7049
|
+
...change.after.typeHookExpr && { typeHookExpr: change.after.typeHookExpr },
|
|
7050
|
+
...change.after.typeValidateExpr !== void 0 && { typeValidateExpr: change.after.typeValidateExpr }
|
|
7051
|
+
};
|
|
7052
|
+
}
|
|
7053
|
+
break;
|
|
7054
|
+
}
|
|
7034
7055
|
case "field_added":
|
|
7035
7056
|
case "field_modified": {
|
|
7036
7057
|
const existing = types[change.typeName];
|
|
@@ -7255,6 +7276,10 @@ function areFieldsDifferent(oldField, newField) {
|
|
|
7255
7276
|
if ((oldSerial.format ?? "") !== (newSerial.format ?? "")) return true;
|
|
7256
7277
|
}
|
|
7257
7278
|
if (oldField.scale !== newField.scale) return true;
|
|
7279
|
+
if (oldField.default !== newField.default) {
|
|
7280
|
+
if (typeof oldField.default !== typeof newField.default) return true;
|
|
7281
|
+
if (JSON.stringify(oldField.default) !== JSON.stringify(newField.default)) return true;
|
|
7282
|
+
}
|
|
7258
7283
|
const oldFields = oldField.fields ?? {};
|
|
7259
7284
|
const newFields = newField.fields ?? {};
|
|
7260
7285
|
const oldFieldNames = Object.keys(oldFields);
|
|
@@ -7617,6 +7642,24 @@ function compareTypeSettings(ctx, typeName, previous, current) {
|
|
|
7617
7642
|
after: snapshotTypeSettingsState(current)
|
|
7618
7643
|
});
|
|
7619
7644
|
}
|
|
7645
|
+
function typeScriptsState(type) {
|
|
7646
|
+
return {
|
|
7647
|
+
...type.typeHookExpr && { typeHookExpr: type.typeHookExpr },
|
|
7648
|
+
...type.typeValidateExpr !== void 0 && { typeValidateExpr: type.typeValidateExpr }
|
|
7649
|
+
};
|
|
7650
|
+
}
|
|
7651
|
+
function compareTypeScripts(ctx, typeName, previous, current) {
|
|
7652
|
+
const prevState = typeScriptsState(previous);
|
|
7653
|
+
const currState = typeScriptsState(current);
|
|
7654
|
+
if (JSON.stringify(prevState) === JSON.stringify(currState)) return;
|
|
7655
|
+
ctx.changes.push({
|
|
7656
|
+
kind: "type_scripts_modified",
|
|
7657
|
+
typeName,
|
|
7658
|
+
reason: "type-level scripts changed",
|
|
7659
|
+
before: prevState,
|
|
7660
|
+
after: currState
|
|
7661
|
+
});
|
|
7662
|
+
}
|
|
7620
7663
|
/**
|
|
7621
7664
|
* Compare two snapshots and generate a diff
|
|
7622
7665
|
* @param {SchemaSnapshot} previous - Previous schema snapshot
|
|
@@ -7655,6 +7698,7 @@ function compareNormalizedSnapshots(previous, current) {
|
|
|
7655
7698
|
const prevType = assertDefined(previous.types[typeName], `type "${typeName}" missing from previous snapshot`);
|
|
7656
7699
|
const currType = assertDefined(current.types[typeName], `type "${typeName}" missing from current snapshot`);
|
|
7657
7700
|
compareTypeSettings(ctx, typeName, prevType, currType);
|
|
7701
|
+
compareTypeScripts(ctx, typeName, prevType, currType);
|
|
7658
7702
|
compareTypeFields(ctx, typeName, prevType, currType);
|
|
7659
7703
|
compareIndexes(ctx, typeName, prevType.indexes, currType.indexes);
|
|
7660
7704
|
compareFiles(ctx, typeName, prevType.files, currType.files);
|
|
@@ -8144,7 +8188,66 @@ const SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id"]);
|
|
|
8144
8188
|
* @returns {SchemaDrift[]} List of drifts detected
|
|
8145
8189
|
*/
|
|
8146
8190
|
function compareRemoteWithSnapshot(remoteTypes, snapshot, remoteGqlPermissions = []) {
|
|
8147
|
-
|
|
8191
|
+
const structuralDrifts = compareNormalizedRemoteWithSnapshot(createRemoteComparableSnapshot(createSnapshotFromRemoteTypes(remoteTypes, snapshot.namespace, remoteGqlPermissions, snapshot)), createRemoteComparableSnapshot(snapshot));
|
|
8192
|
+
const scriptDrifts = compareScriptHashes(remoteTypes, snapshot);
|
|
8193
|
+
return [...structuralDrifts, ...scriptDrifts];
|
|
8194
|
+
}
|
|
8195
|
+
function extractRemoteScriptHash(remoteType) {
|
|
8196
|
+
const exprs = [
|
|
8197
|
+
remoteType.schema?.typeHook?.create?.expr,
|
|
8198
|
+
remoteType.schema?.typeHook?.update?.expr,
|
|
8199
|
+
remoteType.schema?.typeValidate?.create?.expr,
|
|
8200
|
+
remoteType.schema?.typeValidate?.update?.expr
|
|
8201
|
+
];
|
|
8202
|
+
let found;
|
|
8203
|
+
for (const expr of exprs) if (expr) {
|
|
8204
|
+
const hash = extractSourceScriptHash(expr);
|
|
8205
|
+
if (hash) {
|
|
8206
|
+
if (found && found !== hash) return void 0;
|
|
8207
|
+
found = hash;
|
|
8208
|
+
}
|
|
8209
|
+
}
|
|
8210
|
+
return found;
|
|
8211
|
+
}
|
|
8212
|
+
function remoteHasScripts(remoteType) {
|
|
8213
|
+
return !!(remoteType.schema?.typeHook?.create?.expr || remoteType.schema?.typeHook?.update?.expr || remoteType.schema?.typeValidate?.create?.expr || remoteType.schema?.typeValidate?.update?.expr);
|
|
8214
|
+
}
|
|
8215
|
+
function compareScriptHashes(remoteTypes, snapshot) {
|
|
8216
|
+
const drifts = [];
|
|
8217
|
+
const remoteByName = new Map(remoteTypes.map((t) => [t.name, t]));
|
|
8218
|
+
for (const [typeName, snapshotType] of Object.entries(snapshot.types)) {
|
|
8219
|
+
const localHash = computeSourceScriptHash(snapshotType.fields, {
|
|
8220
|
+
typeHookExpr: snapshotType.typeHookExpr,
|
|
8221
|
+
typeValidateExpr: snapshotType.typeValidateExpr
|
|
8222
|
+
});
|
|
8223
|
+
const remoteType = remoteByName.get(typeName);
|
|
8224
|
+
if (!remoteType) continue;
|
|
8225
|
+
if (localHash) {
|
|
8226
|
+
const remoteHash = extractRemoteScriptHash(remoteType);
|
|
8227
|
+
if (localHash !== remoteHash) drifts.push({
|
|
8228
|
+
typeName,
|
|
8229
|
+
kind: "script_mismatch",
|
|
8230
|
+
details: remoteHash ? `Type '${typeName}' scripts differ between remote and snapshot` : `Type '${typeName}' has no script hash on remote`
|
|
8231
|
+
});
|
|
8232
|
+
} else if (remoteHasScripts(remoteType)) drifts.push({
|
|
8233
|
+
typeName,
|
|
8234
|
+
kind: "script_mismatch",
|
|
8235
|
+
details: `Type '${typeName}' has scripts on remote but not in snapshot`
|
|
8236
|
+
});
|
|
8237
|
+
}
|
|
8238
|
+
return drifts;
|
|
8239
|
+
}
|
|
8240
|
+
function stripFieldScriptProps(field) {
|
|
8241
|
+
const { hooks: _hooks, validate: _validate, default: _default, ...rest } = field;
|
|
8242
|
+
if (rest.fields) {
|
|
8243
|
+
const nested = createSnapshotRecord();
|
|
8244
|
+
for (const [name, f] of Object.entries(rest.fields)) nested[name] = stripFieldScriptProps(f);
|
|
8245
|
+
return {
|
|
8246
|
+
...rest,
|
|
8247
|
+
fields: nested
|
|
8248
|
+
};
|
|
8249
|
+
}
|
|
8250
|
+
return rest;
|
|
8148
8251
|
}
|
|
8149
8252
|
function createRemoteComparableSnapshot(snapshot) {
|
|
8150
8253
|
const types = createSnapshotRecord();
|
|
@@ -8152,10 +8255,11 @@ function createRemoteComparableSnapshot(snapshot) {
|
|
|
8152
8255
|
const fields = createSnapshotRecord();
|
|
8153
8256
|
for (const [fieldName, field] of Object.entries(type.fields)) {
|
|
8154
8257
|
if (SYSTEM_FIELDS.has(fieldName)) continue;
|
|
8155
|
-
fields[fieldName] = field;
|
|
8258
|
+
fields[fieldName] = stripFieldScriptProps(field);
|
|
8156
8259
|
}
|
|
8260
|
+
const { typeHookExpr: _, typeValidateExpr: __, ...typeRest } = type;
|
|
8157
8261
|
types[typeName] = {
|
|
8158
|
-
...
|
|
8262
|
+
...typeRest,
|
|
8159
8263
|
fields
|
|
8160
8264
|
};
|
|
8161
8265
|
}
|
|
@@ -8265,6 +8369,11 @@ function schemaDriftFromDiffChange(change) {
|
|
|
8265
8369
|
kind: "permission_mismatch",
|
|
8266
8370
|
details: change.reason ?? "Permissions differ between remote and snapshot"
|
|
8267
8371
|
};
|
|
8372
|
+
case "type_scripts_modified": return {
|
|
8373
|
+
typeName: change.typeName,
|
|
8374
|
+
kind: "script_mismatch",
|
|
8375
|
+
details: change.reason ?? "Type-level scripts differ between remote and snapshot"
|
|
8376
|
+
};
|
|
8268
8377
|
default: throw new Error("Unsupported diff change");
|
|
8269
8378
|
}
|
|
8270
8379
|
}
|
|
@@ -8349,6 +8458,10 @@ function generateTailorDBTypeManifestFromSnapshot(snapshotType, options = {}) {
|
|
|
8349
8458
|
update: [],
|
|
8350
8459
|
delete: []
|
|
8351
8460
|
};
|
|
8461
|
+
const { typeHook, typeValidate } = buildTypeScripts(snapshotType.fields, {
|
|
8462
|
+
typeHookExpr: snapshotType.typeHookExpr,
|
|
8463
|
+
typeValidateExpr: snapshotType.typeValidateExpr
|
|
8464
|
+
});
|
|
8352
8465
|
return {
|
|
8353
8466
|
name: snapshotType.name,
|
|
8354
8467
|
schema: {
|
|
@@ -8360,10 +8473,15 @@ function generateTailorDBTypeManifestFromSnapshot(snapshotType, options = {}) {
|
|
|
8360
8473
|
directives: [],
|
|
8361
8474
|
indexes,
|
|
8362
8475
|
files,
|
|
8363
|
-
permission
|
|
8476
|
+
permission,
|
|
8477
|
+
...typeHook && { typeHook },
|
|
8478
|
+
...typeValidate && { typeValidate }
|
|
8364
8479
|
}
|
|
8365
8480
|
};
|
|
8366
8481
|
}
|
|
8482
|
+
function optionalOnCreate(config) {
|
|
8483
|
+
return config.hooks?.create || config.default !== void 0 ? { optionalOnCreate: true } : {};
|
|
8484
|
+
}
|
|
8367
8485
|
/**
|
|
8368
8486
|
* Convert a snapshot field config to proto format
|
|
8369
8487
|
* @param {SnapshotFieldConfig} config - Snapshot field config
|
|
@@ -8374,7 +8492,6 @@ function convertFieldConfigToProto(config) {
|
|
|
8374
8492
|
type: config.type,
|
|
8375
8493
|
allowedValues: config.type === "enum" ? config.allowedValues?.map((v) => ({ ...v })) ?? [] : [],
|
|
8376
8494
|
description: config.description || "",
|
|
8377
|
-
validate: toProtoSnapshotFieldValidate(config),
|
|
8378
8495
|
array: config.array ?? false,
|
|
8379
8496
|
index: config.index ?? false,
|
|
8380
8497
|
unique: config.unique ?? false,
|
|
@@ -8383,7 +8500,7 @@ function convertFieldConfigToProto(config) {
|
|
|
8383
8500
|
foreignKeyField: config.foreignKeyField,
|
|
8384
8501
|
required: config.required,
|
|
8385
8502
|
vector: config.vector ?? false,
|
|
8386
|
-
...
|
|
8503
|
+
...optionalOnCreate(config),
|
|
8387
8504
|
...config.serial && { serial: {
|
|
8388
8505
|
start: BigInt(config.serial.start),
|
|
8389
8506
|
...config.serial.maxValue !== void 0 && { maxValue: BigInt(config.serial.maxValue) },
|
|
@@ -8394,20 +8511,6 @@ function convertFieldConfigToProto(config) {
|
|
|
8394
8511
|
if (config.type === "nested" && config.fields) fieldEntry.fields = processNestedFieldsFromSnapshot(config.fields);
|
|
8395
8512
|
return fieldEntry;
|
|
8396
8513
|
}
|
|
8397
|
-
function toProtoSnapshotFieldValidate(config) {
|
|
8398
|
-
return (config.validate ?? []).map((val) => ({
|
|
8399
|
-
action: TailorDBType_PermitAction.DENY,
|
|
8400
|
-
errorMessage: val.errorMessage || "",
|
|
8401
|
-
script: { expr: val.script && val.script.expr ? `!${val.script.expr}` : "" }
|
|
8402
|
-
}));
|
|
8403
|
-
}
|
|
8404
|
-
function toProtoSnapshotFieldHooks(config) {
|
|
8405
|
-
if (!config.hooks) return {};
|
|
8406
|
-
return { hooks: {
|
|
8407
|
-
create: config.hooks.create ? { expr: config.hooks.create.expr || "" } : void 0,
|
|
8408
|
-
update: config.hooks.update ? { expr: config.hooks.update.expr || "" } : void 0
|
|
8409
|
-
} };
|
|
8410
|
-
}
|
|
8411
8514
|
/**
|
|
8412
8515
|
* Process nested fields from snapshot format to proto format
|
|
8413
8516
|
* @param {Record<string, SnapshotFieldConfig>} fields - Nested fields
|
|
@@ -8421,14 +8524,12 @@ function processNestedFieldsFromSnapshot(fields) {
|
|
|
8421
8524
|
type: "nested",
|
|
8422
8525
|
allowedValues: fieldConfig.allowedValues?.map((v) => ({ ...v })) ?? [],
|
|
8423
8526
|
description: fieldConfig.description || "",
|
|
8424
|
-
validate: toProtoSnapshotFieldValidate(fieldConfig),
|
|
8425
8527
|
required: fieldConfig.required,
|
|
8426
8528
|
array: fieldConfig.array ?? false,
|
|
8427
8529
|
index: false,
|
|
8428
8530
|
unique: false,
|
|
8429
8531
|
foreignKey: false,
|
|
8430
8532
|
vector: false,
|
|
8431
|
-
...toProtoSnapshotFieldHooks(fieldConfig),
|
|
8432
8533
|
fields: deepNestedFields,
|
|
8433
8534
|
...fieldConfig.scale !== void 0 && { scale: fieldConfig.scale }
|
|
8434
8535
|
};
|
|
@@ -8436,14 +8537,13 @@ function processNestedFieldsFromSnapshot(fields) {
|
|
|
8436
8537
|
type: fieldConfig.type,
|
|
8437
8538
|
allowedValues: fieldConfig.type === "enum" ? fieldConfig.allowedValues?.map((v) => ({ ...v })) ?? [] : [],
|
|
8438
8539
|
description: fieldConfig.description || "",
|
|
8439
|
-
validate: toProtoSnapshotFieldValidate(fieldConfig),
|
|
8440
8540
|
required: fieldConfig.required,
|
|
8441
8541
|
array: fieldConfig.array ?? false,
|
|
8442
8542
|
index: false,
|
|
8443
8543
|
unique: false,
|
|
8444
8544
|
foreignKey: false,
|
|
8445
8545
|
vector: false,
|
|
8446
|
-
...
|
|
8546
|
+
...optionalOnCreate(fieldConfig),
|
|
8447
8547
|
...fieldConfig.serial && { serial: {
|
|
8448
8548
|
start: BigInt(fieldConfig.serial.start),
|
|
8449
8549
|
...fieldConfig.serial.maxValue !== void 0 && { maxValue: BigInt(fieldConfig.serial.maxValue) },
|
|
@@ -9764,14 +9864,6 @@ const migrationSnapshotCache = {
|
|
|
9764
9864
|
return snapshot;
|
|
9765
9865
|
}
|
|
9766
9866
|
};
|
|
9767
|
-
/**
|
|
9768
|
-
* Build the TailorDBType manifest for `typeName` from migration N's snapshot.
|
|
9769
|
-
* @param migration - The pending migration whose snapshot to consult
|
|
9770
|
-
* @param typeName - The type name to look up in the snapshot
|
|
9771
|
-
* @param tailorDBInputs - Deploy inputs, used to resolve namespace gqlOperations
|
|
9772
|
-
* @param executorUsedTypes - Types used by executors (drives publishRecordEvents default)
|
|
9773
|
-
* @returns The manifest, or undefined if `typeName` is not in that snapshot.
|
|
9774
|
-
*/
|
|
9775
9867
|
function buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes) {
|
|
9776
9868
|
const snapshotType = migrationSnapshotCache.load(migration).types[typeName];
|
|
9777
9869
|
if (!snapshotType) return void 0;
|
|
@@ -10282,18 +10374,28 @@ function normalizeComparableTailorDBType(type) {
|
|
|
10282
10374
|
settings: normalized?.schema?.settings ?? {},
|
|
10283
10375
|
indexes: normalized?.schema?.indexes ?? {},
|
|
10284
10376
|
files: normalized?.schema?.files ?? {},
|
|
10285
|
-
permission: normalized?.schema?.permission ?? {}
|
|
10377
|
+
permission: normalized?.schema?.permission ?? {},
|
|
10378
|
+
typeHook: normalized?.schema?.typeHook ?? {},
|
|
10379
|
+
typeValidate: normalized?.schema?.typeValidate ?? {}
|
|
10286
10380
|
}
|
|
10287
10381
|
}, []);
|
|
10288
10382
|
}
|
|
10289
10383
|
function normalizeTailorDBCompareValue(value, path) {
|
|
10290
10384
|
if (value === void 0 || value === null) return value;
|
|
10385
|
+
if (typeof value === "boolean") {
|
|
10386
|
+
if (path.at(-1) === "optionalOnCreate" && value === false) return;
|
|
10387
|
+
return value;
|
|
10388
|
+
}
|
|
10291
10389
|
if (typeof value === "number" || typeof value === "bigint" || typeof value === "string") {
|
|
10292
10390
|
if (matchesNumericStringPath(path) && isNumericLikeValue(value)) return String(value);
|
|
10293
10391
|
if ((path.at(-1) === "expr" || path.at(-1) === "description") && value === tailordbCompareKnownDefaults.emptyExpression) return;
|
|
10294
10392
|
return value;
|
|
10295
10393
|
}
|
|
10296
|
-
if (Array.isArray(value))
|
|
10394
|
+
if (Array.isArray(value)) {
|
|
10395
|
+
const items = value.map((item, index) => normalizeTailorDBCompareValue(item, [...path, index])).filter((item) => item !== void 0);
|
|
10396
|
+
if (items.length === 0 && path.at(-1) === "validate") return;
|
|
10397
|
+
return items;
|
|
10398
|
+
}
|
|
10297
10399
|
if (!isPlainObject(value)) return value;
|
|
10298
10400
|
const normalizedEntries = Object.entries(value).map(([key, entryValue]) => [key, normalizeTailorDBCompareValue(entryValue, [...path, key])]).filter(([, entryValue]) => entryValue !== void 0);
|
|
10299
10401
|
const normalizedObject = Object.fromEntries(normalizedEntries);
|
|
@@ -10546,11 +10648,11 @@ async function registerJobFunctions(client, changeSet, appName, appId, unchanged
|
|
|
10546
10648
|
const allUsedJobNames = /* @__PURE__ */ new Set();
|
|
10547
10649
|
unchangedWorkflowJobNames.forEach((jobName) => allUsedJobNames.add(jobName));
|
|
10548
10650
|
for (const item of [...changeSet.creates, ...changeSet.updates]) for (const jobName of item.usedJobNames) allUsedJobNames.add(jobName);
|
|
10549
|
-
const existingJobFunctions = await fetchAll(async (pageToken,
|
|
10651
|
+
const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
|
|
10550
10652
|
const response = await client.listWorkflowJobFunctions({
|
|
10551
10653
|
workspaceId,
|
|
10552
10654
|
pageToken,
|
|
10553
|
-
pageSize:
|
|
10655
|
+
pageSize: maxPageSize
|
|
10554
10656
|
});
|
|
10555
10657
|
return [response.jobFunctions.map((j) => j.name), response.nextPageToken];
|
|
10556
10658
|
});
|
|
@@ -10730,11 +10832,11 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
|
|
|
10730
10832
|
}
|
|
10731
10833
|
async function planWorkflowJobFunctionDeletes(params) {
|
|
10732
10834
|
const { client, workspaceId, appName, appId, retainedWorkflowJobNames } = params;
|
|
10733
|
-
const existingJobFunctions = await fetchAll(async (pageToken,
|
|
10835
|
+
const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
|
|
10734
10836
|
const response = await client.listWorkflowJobFunctions({
|
|
10735
10837
|
workspaceId,
|
|
10736
10838
|
pageToken,
|
|
10737
|
-
pageSize:
|
|
10839
|
+
pageSize: maxPageSize
|
|
10738
10840
|
});
|
|
10739
10841
|
return [response.jobFunctions.map((jobFunction) => jobFunction.name), response.nextPageToken];
|
|
10740
10842
|
});
|
|
@@ -10814,6 +10916,198 @@ function normalizeRetryPolicyForCompare(policy) {
|
|
|
10814
10916
|
};
|
|
10815
10917
|
}
|
|
10816
10918
|
|
|
10919
|
+
//#endregion
|
|
10920
|
+
//#region src/cli/commands/deploy/workflow-execution-policy.ts
|
|
10921
|
+
function toConcurrencyPolicyInit(policy) {
|
|
10922
|
+
if (!policy) return void 0;
|
|
10923
|
+
return { maxConcurrentExecutions: policy.maxConcurrentExecutions };
|
|
10924
|
+
}
|
|
10925
|
+
function normalizeComparableConcurrency(policy) {
|
|
10926
|
+
if (!policy || !policy.maxConcurrentExecutions) return void 0;
|
|
10927
|
+
return { maxConcurrentExecutions: policy.maxConcurrentExecutions };
|
|
10928
|
+
}
|
|
10929
|
+
/**
|
|
10930
|
+
* The declared key prefix, regardless of variant. `ExecutionPolicyWildcardInstance`
|
|
10931
|
+
* omits `key` from its public type to force callers through `keyFor()`, but
|
|
10932
|
+
* the underlying value always carries it when produced by
|
|
10933
|
+
* `defineWorkflowExecutionPolicy()` or `defineWorkflowExecutionPolicies()`.
|
|
10934
|
+
* @param policy - Declared policy from the config
|
|
10935
|
+
* @returns The declared key prefix
|
|
10936
|
+
*/
|
|
10937
|
+
function declaredKey(policy) {
|
|
10938
|
+
if (policy.matchType === "exact") return policy.key;
|
|
10939
|
+
const key = policy.key;
|
|
10940
|
+
if (typeof key !== "string") throw new Error(`Invalid workflow execution policy "${policy.name}": prefix policies must be created via defineWorkflowExecutionPolicy() or defineWorkflowExecutionPolicies(), not a hand-constructed object.`);
|
|
10941
|
+
return key;
|
|
10942
|
+
}
|
|
10943
|
+
/**
|
|
10944
|
+
* The literal key the platform registers for a declared policy: `key` with a
|
|
10945
|
+
* trailing `*` appended when `matchType` is `"prefix"`.
|
|
10946
|
+
* @param policy - Declared policy from the config
|
|
10947
|
+
* @returns The platform-facing execution policy key
|
|
10948
|
+
*/
|
|
10949
|
+
function toPlatformExecutionPolicyKey(policy) {
|
|
10950
|
+
const key = declaredKey(policy);
|
|
10951
|
+
return policy.matchType === "prefix" ? `${key}*` : key;
|
|
10952
|
+
}
|
|
10953
|
+
/**
|
|
10954
|
+
* Validate a declared execution policy against the parser schema. Throws with
|
|
10955
|
+
* a descriptive error when `name` or the platform-facing key violates the
|
|
10956
|
+
* platform grammar.
|
|
10957
|
+
* @param policy - Declared policy from the config
|
|
10958
|
+
*/
|
|
10959
|
+
function validatePolicy(policy) {
|
|
10960
|
+
if (declaredKey(policy).endsWith("*")) throw new Error(`Invalid workflow execution policy "${policy.name}": key must not end with '*'; omit the '*' and set matchType: "prefix" for wildcard policies (the SDK appends '*' automatically).`);
|
|
10961
|
+
const parsed = WorkflowJobFunctionExecutionPolicySchema.safeParse({
|
|
10962
|
+
name: policy.name,
|
|
10963
|
+
key: toPlatformExecutionPolicyKey(policy),
|
|
10964
|
+
concurrencyPolicy: policy.concurrencyPolicy
|
|
10965
|
+
});
|
|
10966
|
+
if (!parsed.success) throw new Error(`Invalid workflow execution policy "${policy.name}": ${parsed.error.issues.map((issue) => issue.message).join("; ")}`);
|
|
10967
|
+
}
|
|
10968
|
+
/**
|
|
10969
|
+
* Plan workflow job function execution policy changes based on desired
|
|
10970
|
+
* declarations and current remote state.
|
|
10971
|
+
* @param client - Operator client instance
|
|
10972
|
+
* @param workspaceId - Workspace ID
|
|
10973
|
+
* @param appName - Application name
|
|
10974
|
+
* @param appId - Application ID for ownership metadata
|
|
10975
|
+
* @param declared - Policies declared in the config (property name → instance)
|
|
10976
|
+
* @returns Planned execution policy changes
|
|
10977
|
+
*/
|
|
10978
|
+
async function planWorkflowJobFunctionExecutionPolicy(client, workspaceId, appName, appId, declared) {
|
|
10979
|
+
const changeSet = createChangeSet("Workflow execution policies");
|
|
10980
|
+
const conflicts = [];
|
|
10981
|
+
const unmanaged = [];
|
|
10982
|
+
const resourceOwners = /* @__PURE__ */ new Set();
|
|
10983
|
+
const declaredList = Object.values(declared);
|
|
10984
|
+
for (const policy of declaredList) validatePolicy(policy);
|
|
10985
|
+
const existing = await fetchExistingResourcesWithLabels({
|
|
10986
|
+
client,
|
|
10987
|
+
fetchPage: async (pageToken, pageSize) => {
|
|
10988
|
+
const response = await client.listWorkflowJobFunctionExecutionPolicies({
|
|
10989
|
+
workspaceId,
|
|
10990
|
+
pageToken,
|
|
10991
|
+
pageSize
|
|
10992
|
+
});
|
|
10993
|
+
return [response.policies, response.nextPageToken];
|
|
10994
|
+
},
|
|
10995
|
+
getName: (resource) => resource.name,
|
|
10996
|
+
getTrn: (name) => resourceTrn(workspaceId, "workflow_job_function_execution_policy", name)
|
|
10997
|
+
});
|
|
10998
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
10999
|
+
for (const policy of declaredList) {
|
|
11000
|
+
if (seenNames.has(policy.name)) throw new Error(`Duplicate workflow execution policy name "${policy.name}". Each policy must have a unique name within the workspace.`);
|
|
11001
|
+
seenNames.add(policy.name);
|
|
11002
|
+
const metaRequest = await buildMetaRequest({
|
|
11003
|
+
trn: resourceTrn(workspaceId, "workflow_job_function_execution_policy", policy.name),
|
|
11004
|
+
appName,
|
|
11005
|
+
appId
|
|
11006
|
+
});
|
|
11007
|
+
const found = existing[policy.name];
|
|
11008
|
+
if (found) {
|
|
11009
|
+
const owned = trackDesiredResourceOwnership({
|
|
11010
|
+
labels: found.allLabels,
|
|
11011
|
+
ownerLabel: found.label,
|
|
11012
|
+
appName,
|
|
11013
|
+
appId,
|
|
11014
|
+
resourceType: "Workflow execution policy",
|
|
11015
|
+
resourceName: policy.name,
|
|
11016
|
+
conflicts,
|
|
11017
|
+
unmanaged
|
|
11018
|
+
});
|
|
11019
|
+
const remoteKey = found.resource.executionPolicyKey;
|
|
11020
|
+
const desiredKey = toPlatformExecutionPolicyKey(policy);
|
|
11021
|
+
const remoteConcurrency = normalizeComparableConcurrency(found.resource.concurrencyPolicy);
|
|
11022
|
+
const desiredConcurrency = normalizeComparableConcurrency(policy.concurrencyPolicy);
|
|
11023
|
+
if (owned && hasMatchingSdkVersion(found.allLabels, metaRequest.labels) && remoteKey === desiredKey && areNormalizedEqual(remoteConcurrency, desiredConcurrency)) changeSet.unchanged.push({ name: policy.name });
|
|
11024
|
+
else if (remoteKey !== desiredKey) changeSet.replaces.push({
|
|
11025
|
+
name: policy.name,
|
|
11026
|
+
workspaceId,
|
|
11027
|
+
policy,
|
|
11028
|
+
metaRequest
|
|
11029
|
+
});
|
|
11030
|
+
else changeSet.updates.push({
|
|
11031
|
+
name: policy.name,
|
|
11032
|
+
workspaceId,
|
|
11033
|
+
policy,
|
|
11034
|
+
metaRequest
|
|
11035
|
+
});
|
|
11036
|
+
delete existing[policy.name];
|
|
11037
|
+
} else changeSet.creates.push({
|
|
11038
|
+
name: policy.name,
|
|
11039
|
+
workspaceId,
|
|
11040
|
+
policy,
|
|
11041
|
+
metaRequest
|
|
11042
|
+
});
|
|
11043
|
+
}
|
|
11044
|
+
for (const [name, remaining] of Object.entries(existing)) {
|
|
11045
|
+
if (!remaining) continue;
|
|
11046
|
+
if (trackRemainingResourceOwner({
|
|
11047
|
+
labels: remaining.allLabels,
|
|
11048
|
+
ownerLabel: remaining.label,
|
|
11049
|
+
appName,
|
|
11050
|
+
appId,
|
|
11051
|
+
resourceOwners
|
|
11052
|
+
})) changeSet.deletes.push({
|
|
11053
|
+
name,
|
|
11054
|
+
workspaceId
|
|
11055
|
+
});
|
|
11056
|
+
}
|
|
11057
|
+
return {
|
|
11058
|
+
changeSet,
|
|
11059
|
+
conflicts,
|
|
11060
|
+
unmanaged,
|
|
11061
|
+
resourceOwners
|
|
11062
|
+
};
|
|
11063
|
+
}
|
|
11064
|
+
/**
|
|
11065
|
+
* Apply planned workflow execution policy changes for the given phase.
|
|
11066
|
+
* @param client - Operator client instance
|
|
11067
|
+
* @param plan - Result of `planWorkflowJobFunctionExecutionPolicy`
|
|
11068
|
+
* @param phase - Apply phase
|
|
11069
|
+
* @returns Promise that resolves when policies are applied
|
|
11070
|
+
*/
|
|
11071
|
+
async function applyWorkflowJobFunctionExecutionPolicy(client, plan, phase = "create-update") {
|
|
11072
|
+
const { changeSet } = plan;
|
|
11073
|
+
if (phase === "create-update") await Promise.all([
|
|
11074
|
+
...changeSet.replaces.map(async (replace) => {
|
|
11075
|
+
await client.deleteWorkflowJobFunctionExecutionPolicy({
|
|
11076
|
+
workspaceId: replace.workspaceId,
|
|
11077
|
+
executionPolicyName: replace.name
|
|
11078
|
+
});
|
|
11079
|
+
await client.createWorkflowJobFunctionExecutionPolicy({
|
|
11080
|
+
workspaceId: replace.workspaceId,
|
|
11081
|
+
executionPolicyName: replace.policy.name,
|
|
11082
|
+
executionPolicyKey: toPlatformExecutionPolicyKey(replace.policy),
|
|
11083
|
+
concurrencyPolicy: toConcurrencyPolicyInit(replace.policy.concurrencyPolicy)
|
|
11084
|
+
});
|
|
11085
|
+
await client.setMetadata(replace.metaRequest);
|
|
11086
|
+
}),
|
|
11087
|
+
...changeSet.creates.map(async (create) => {
|
|
11088
|
+
await client.createWorkflowJobFunctionExecutionPolicy({
|
|
11089
|
+
workspaceId: create.workspaceId,
|
|
11090
|
+
executionPolicyName: create.policy.name,
|
|
11091
|
+
executionPolicyKey: toPlatformExecutionPolicyKey(create.policy),
|
|
11092
|
+
concurrencyPolicy: toConcurrencyPolicyInit(create.policy.concurrencyPolicy)
|
|
11093
|
+
});
|
|
11094
|
+
await client.setMetadata(create.metaRequest);
|
|
11095
|
+
}),
|
|
11096
|
+
...changeSet.updates.map(async (update) => {
|
|
11097
|
+
await client.updateWorkflowJobFunctionExecutionPolicy({
|
|
11098
|
+
workspaceId: update.workspaceId,
|
|
11099
|
+
executionPolicyName: update.policy.name,
|
|
11100
|
+
concurrencyPolicy: toConcurrencyPolicyInit(update.policy.concurrencyPolicy)
|
|
11101
|
+
});
|
|
11102
|
+
await client.setMetadata(update.metaRequest);
|
|
11103
|
+
})
|
|
11104
|
+
]);
|
|
11105
|
+
else await Promise.all(changeSet.deletes.map((del) => client.deleteWorkflowJobFunctionExecutionPolicy({
|
|
11106
|
+
workspaceId: del.workspaceId,
|
|
11107
|
+
executionPolicyName: del.name
|
|
11108
|
+
})));
|
|
11109
|
+
}
|
|
11110
|
+
|
|
10817
11111
|
//#endregion
|
|
10818
11112
|
//#region src/cli/commands/deploy/apply-phases.ts
|
|
10819
11113
|
/**
|
|
@@ -10847,10 +11141,12 @@ async function applyDeploymentPlans(client, workspaceId, deployments) {
|
|
|
10847
11141
|
});
|
|
10848
11142
|
await withSpan("apply.createUpdateDependentServices", async () => {
|
|
10849
11143
|
await forEachDeployment((d) => applyExecutor(client, d.executor, "create-update"));
|
|
11144
|
+
await forEachDeployment((d) => applyWorkflowJobFunctionExecutionPolicy(client, d.workflowExecutionPolicy, "create-update"));
|
|
10850
11145
|
await forEachDeployment((d) => applyWorkflow(client, d.workflow, "create-update"));
|
|
10851
11146
|
});
|
|
10852
11147
|
await withSpan("apply.deleteDependentServices", async () => {
|
|
10853
11148
|
await forEachDeployment((d) => applyWorkflow(client, d.workflow, "delete"));
|
|
11149
|
+
await forEachDeployment((d) => applyWorkflowJobFunctionExecutionPolicy(client, d.workflowExecutionPolicy, "delete"));
|
|
10854
11150
|
await forEachDeployment((d) => applyExecutor(client, d.executor, "delete"));
|
|
10855
11151
|
await forEachDeployment((d) => applyStaticWebsite(client, d.staticWebsite, "delete"));
|
|
10856
11152
|
await forEachDeployment((d) => applyAIGateway(client, d.aiGateway, "delete"));
|
|
@@ -11159,13 +11455,14 @@ function validateItems(params) {
|
|
|
11159
11455
|
*
|
|
11160
11456
|
* Collections not validated: idp client, tailorDB gqlPermission, functionRegistry — no
|
|
11161
11457
|
* buf.validate annotations.
|
|
11162
|
-
* Application cors and IdP userAuthPolicy.allowedReturnOrigins receive
|
|
11163
|
-
* handling: static-website URL placeholders are resolved at apply time, so the
|
|
11458
|
+
* Application cors, AIGateway cors, and IdP userAuthPolicy.allowedReturnOrigins receive
|
|
11459
|
+
* special handling: static-website URL placeholders are resolved at apply time, so the
|
|
11164
11460
|
* relevant origin/URL constraints would false-positive on `<name>:url` entries
|
|
11165
|
-
* here. Application cors
|
|
11166
|
-
*
|
|
11167
|
-
*
|
|
11168
|
-
*
|
|
11461
|
+
* here. Application cors and AIGateway cors are dropped entirely, forgoing their
|
|
11462
|
+
* per-item URL/origin constraints for the whole list rather than substituting
|
|
11463
|
+
* placeholders; IdP `allowedReturnOrigins` instead substitutes placeholder entries
|
|
11464
|
+
* with a dummy origin so the per-item regex and the cross-field `enable_mfa requires
|
|
11465
|
+
* ≥1 origin` rule still get exercised on the rest of the payload.
|
|
11169
11466
|
* Workflow jobFunctions map excluded: versions are registered at apply time (registerJobFunctions)
|
|
11170
11467
|
* and the map field carries no min_items constraint. Job names are validated separately via
|
|
11171
11468
|
* CreateWorkflowJobFunctionRequestSchema using usedJobNames from the workflow change set.
|
|
@@ -11175,7 +11472,7 @@ function validateItems(params) {
|
|
|
11175
11472
|
* @param input - Plan results from the plan phase
|
|
11176
11473
|
*/
|
|
11177
11474
|
async function validatePlan(input) {
|
|
11178
|
-
const { tailorDB, staticWebsite, idp, auth, pipeline, app, executor, workflow, secretManager } = input;
|
|
11475
|
+
const { tailorDB, staticWebsite, aiGateway, idp, auth, pipeline, app, executor, workflow, workflowExecutionPolicy, secretManager } = input;
|
|
11179
11476
|
const validator = createValidator();
|
|
11180
11477
|
const violations = [];
|
|
11181
11478
|
function creates(schema, kind, items) {
|
|
@@ -11228,6 +11525,20 @@ async function validatePlan(input) {
|
|
|
11228
11525
|
creates(CreateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.creates);
|
|
11229
11526
|
updates(UpdateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.updates);
|
|
11230
11527
|
creates(AddCustomDomainRequestSchema, "StaticWebsite custom domain", staticWebsite.customDomainChangeSet.creates);
|
|
11528
|
+
creates(CreateAIGatewayRequestSchema, "AIGateway", aiGateway.changeSet.creates.map((item) => ({
|
|
11529
|
+
name: item.name,
|
|
11530
|
+
request: {
|
|
11531
|
+
...item.request,
|
|
11532
|
+
cors: void 0
|
|
11533
|
+
}
|
|
11534
|
+
})));
|
|
11535
|
+
updates(UpdateAIGatewayRequestSchema, "AIGateway", aiGateway.changeSet.updates.map((item) => ({
|
|
11536
|
+
name: item.name,
|
|
11537
|
+
request: {
|
|
11538
|
+
...item.request,
|
|
11539
|
+
cors: void 0
|
|
11540
|
+
}
|
|
11541
|
+
})));
|
|
11231
11542
|
const placeholderOriginReplacement = "https://placeholder.invalid";
|
|
11232
11543
|
const substituteIdpReturnOrigins = (item) => {
|
|
11233
11544
|
const request = item.request;
|
|
@@ -11318,6 +11629,23 @@ async function validatePlan(input) {
|
|
|
11318
11629
|
}
|
|
11319
11630
|
})));
|
|
11320
11631
|
}
|
|
11632
|
+
creates(CreateWorkflowJobFunctionExecutionPolicyRequestSchema, "Workflow execution policy", [...workflowExecutionPolicy.changeSet.creates, ...workflowExecutionPolicy.changeSet.replaces].map((item) => ({
|
|
11633
|
+
name: item.name,
|
|
11634
|
+
request: {
|
|
11635
|
+
workspaceId: item.workspaceId,
|
|
11636
|
+
executionPolicyName: item.policy.name,
|
|
11637
|
+
executionPolicyKey: toPlatformExecutionPolicyKey(item.policy),
|
|
11638
|
+
...item.policy.concurrencyPolicy && { concurrencyPolicy: { maxConcurrentExecutions: item.policy.concurrencyPolicy.maxConcurrentExecutions } }
|
|
11639
|
+
}
|
|
11640
|
+
})));
|
|
11641
|
+
updates(UpdateWorkflowJobFunctionExecutionPolicyRequestSchema, "Workflow execution policy", workflowExecutionPolicy.changeSet.updates.map((item) => ({
|
|
11642
|
+
name: item.name,
|
|
11643
|
+
request: {
|
|
11644
|
+
workspaceId: item.workspaceId,
|
|
11645
|
+
executionPolicyName: item.policy.name,
|
|
11646
|
+
...item.policy.concurrencyPolicy && { concurrencyPolicy: { maxConcurrentExecutions: item.policy.concurrencyPolicy.maxConcurrentExecutions } }
|
|
11647
|
+
}
|
|
11648
|
+
})));
|
|
11321
11649
|
creates(CreateSecretManagerVaultRequestSchema, "Secret Manager vault", secretManager.vaultChangeSet.creates.map((item) => ({
|
|
11322
11650
|
name: item.name,
|
|
11323
11651
|
request: vaultCreateRequest(item)
|
|
@@ -11550,6 +11878,7 @@ function buildPlanReport(results) {
|
|
|
11550
11878
|
const executorEntries = formatExecutorChangeEntries(results.executor.changeSet, buildPlannedExecutorsByName(results.executor.changeSet), results.functionRegistry.executorFunctionChanges);
|
|
11551
11879
|
const resolverEntries = formatResolverChangeEntries(results.pipeline.changeSet.resolver, results.functionRegistry.resolverFunctionChanges);
|
|
11552
11880
|
const workflowEntries = formatWorkflowChangeEntries(results.workflow.changeSet, results.functionRegistry.workflowJobChanges);
|
|
11881
|
+
const workflowExecutionPolicyEntries = formatChangeSetEntries(results.workflowExecutionPolicy.changeSet, ["executionPolicy"]);
|
|
11553
11882
|
const authHookEntries = formatAuthHookChangeEntries(results.auth.changeSet.authHook, results.functionRegistry.authHookFunctionChanges);
|
|
11554
11883
|
const tailorDBEntries = [...formatTailorDBResourceChangeEntries(results.tailorDB.changeSet.type, results.tailorDB.changeSet.gqlPermission)];
|
|
11555
11884
|
const pipelineEntries = [...resolverEntries];
|
|
@@ -11580,6 +11909,7 @@ function buildPlanReport(results) {
|
|
|
11580
11909
|
...pipelineEntries,
|
|
11581
11910
|
...executorEntries,
|
|
11582
11911
|
...workflowEntries,
|
|
11912
|
+
...workflowExecutionPolicyEntries,
|
|
11583
11913
|
...idpEntries,
|
|
11584
11914
|
...authEntries
|
|
11585
11915
|
];
|
|
@@ -11952,7 +12282,7 @@ async function planDeploymentTarget(params) {
|
|
|
11952
12282
|
};
|
|
11953
12283
|
const functionRegistry = await withSpan("plan.functionRegistry", () => planFunctionRegistry(client, workspaceId, application.name, application.id, functionEntries));
|
|
11954
12284
|
const unchangedWorkflowJobs = new Set(functionRegistry.changeSet.unchanged.filter((entry) => entry.name.startsWith(WORKFLOW_PREFIX)).map((entry) => entry.name.slice(WORKFLOW_PREFIX.length)));
|
|
11955
|
-
const [tailorDB, staticWebsite, aiGateway, idp, auth, pipeline, app, executor, workflow, secretManager] = await Promise.all([
|
|
12285
|
+
const [tailorDB, staticWebsite, aiGateway, idp, auth, pipeline, app, executor, workflow, workflowExecutionPolicy, secretManager] = await Promise.all([
|
|
11956
12286
|
withSpan("plan.tailorDB", () => planTailorDB(ctx)),
|
|
11957
12287
|
withSpan("plan.staticWebsite", () => planStaticWebsite(ctx)),
|
|
11958
12288
|
withSpan("plan.aiGateway", () => planAIGateway(ctx)),
|
|
@@ -11962,6 +12292,7 @@ async function planDeploymentTarget(params) {
|
|
|
11962
12292
|
withSpan("plan.application", () => planApplication(ctx, httpAdapterBuildResult)),
|
|
11963
12293
|
withSpan("plan.executor", () => planExecutor(ctx)),
|
|
11964
12294
|
withSpan("plan.workflow", () => planWorkflow(client, workspaceId, application.name, application.id, workflowService?.workflows ?? {}, workflowBuildResult?.mainJobDeps ?? {}, unchangedWorkflowJobs)),
|
|
12295
|
+
withSpan("plan.workflowExecutionPolicy", () => planWorkflowJobFunctionExecutionPolicy(client, workspaceId, application.name, application.id, config.workflow?.executionPolicies ?? {})),
|
|
11965
12296
|
withSpan("plan.secretManager", () => planSecretManager(ctx))
|
|
11966
12297
|
]);
|
|
11967
12298
|
return {
|
|
@@ -11976,6 +12307,7 @@ async function planDeploymentTarget(params) {
|
|
|
11976
12307
|
app,
|
|
11977
12308
|
executor,
|
|
11978
12309
|
workflow,
|
|
12310
|
+
workflowExecutionPolicy,
|
|
11979
12311
|
secretManager
|
|
11980
12312
|
};
|
|
11981
12313
|
});
|
|
@@ -11992,47 +12324,25 @@ function deploymentPlanResults(deployment) {
|
|
|
11992
12324
|
const { application: _application, ...results } = deployment;
|
|
11993
12325
|
return results;
|
|
11994
12326
|
}
|
|
12327
|
+
/**
|
|
12328
|
+
* Every `PlanResults` entry except `app` carries ownership-tracking fields;
|
|
12329
|
+
* deriving the list from `results` itself (instead of naming each key) keeps
|
|
12330
|
+
* these collectors in sync with `PlannedDeployment` as resource types are added.
|
|
12331
|
+
* @param results - Plan results for a single deployment
|
|
12332
|
+
* @returns The ownership-tracking plan entries, `app` excluded
|
|
12333
|
+
*/
|
|
12334
|
+
function ownershipTrackedPlans(results) {
|
|
12335
|
+
const { app: _app, ...rest } = results;
|
|
12336
|
+
return Object.values(rest);
|
|
12337
|
+
}
|
|
11995
12338
|
function collectOwnerConflicts(results) {
|
|
11996
|
-
return
|
|
11997
|
-
...results.functionRegistry.conflicts,
|
|
11998
|
-
...results.tailorDB.conflicts,
|
|
11999
|
-
...results.staticWebsite.conflicts,
|
|
12000
|
-
...results.aiGateway.conflicts,
|
|
12001
|
-
...results.idp.conflicts,
|
|
12002
|
-
...results.auth.conflicts,
|
|
12003
|
-
...results.pipeline.conflicts,
|
|
12004
|
-
...results.executor.conflicts,
|
|
12005
|
-
...results.workflow.conflicts,
|
|
12006
|
-
...results.secretManager.conflicts
|
|
12007
|
-
];
|
|
12339
|
+
return ownershipTrackedPlans(results).flatMap((plan) => plan.conflicts);
|
|
12008
12340
|
}
|
|
12009
12341
|
function collectUnmanagedResources(results) {
|
|
12010
|
-
return
|
|
12011
|
-
...results.functionRegistry.unmanaged,
|
|
12012
|
-
...results.tailorDB.unmanaged,
|
|
12013
|
-
...results.staticWebsite.unmanaged,
|
|
12014
|
-
...results.aiGateway.unmanaged,
|
|
12015
|
-
...results.idp.unmanaged,
|
|
12016
|
-
...results.auth.unmanaged,
|
|
12017
|
-
...results.pipeline.unmanaged,
|
|
12018
|
-
...results.executor.unmanaged,
|
|
12019
|
-
...results.workflow.unmanaged,
|
|
12020
|
-
...results.secretManager.unmanaged
|
|
12021
|
-
];
|
|
12342
|
+
return ownershipTrackedPlans(results).flatMap((plan) => plan.unmanaged);
|
|
12022
12343
|
}
|
|
12023
12344
|
function collectResourceOwners(results) {
|
|
12024
|
-
return
|
|
12025
|
-
...results.functionRegistry.resourceOwners,
|
|
12026
|
-
...results.tailorDB.resourceOwners,
|
|
12027
|
-
...results.staticWebsite.resourceOwners,
|
|
12028
|
-
...results.aiGateway.resourceOwners,
|
|
12029
|
-
...results.idp.resourceOwners,
|
|
12030
|
-
...results.auth.resourceOwners,
|
|
12031
|
-
...results.pipeline.resourceOwners,
|
|
12032
|
-
...results.executor.resourceOwners,
|
|
12033
|
-
...results.workflow.resourceOwners,
|
|
12034
|
-
...results.secretManager.resourceOwners
|
|
12035
|
-
]);
|
|
12345
|
+
return new Set(ownershipTrackedPlans(results).flatMap((plan) => [...plan.resourceOwners]));
|
|
12036
12346
|
}
|
|
12037
12347
|
function collectImportantResourceDeletions(results) {
|
|
12038
12348
|
const importantDeletions = [];
|
|
@@ -12176,6 +12486,12 @@ const DEPLOY_MANAGED_RESOURCE_DEFINITIONS = [
|
|
|
12176
12486
|
namesOf: (target) => Object.values(target.application.workflowService?.workflows ?? {}).map((workflow) => workflow.name),
|
|
12177
12487
|
changeSetOf: (results) => results.workflow.changeSet
|
|
12178
12488
|
},
|
|
12489
|
+
{
|
|
12490
|
+
resourceLabel: "Workflow execution policy",
|
|
12491
|
+
resourceType: "workflow_job_function_execution_policy",
|
|
12492
|
+
namesOf: (target) => Object.values(target.config.workflow?.executionPolicies ?? {}).map((policy) => policy.name),
|
|
12493
|
+
changeSetOf: (results) => results.workflowExecutionPolicy.changeSet
|
|
12494
|
+
},
|
|
12179
12495
|
{
|
|
12180
12496
|
resourceLabel: "Auth connection",
|
|
12181
12497
|
resourceType: "auth.connection",
|
|
@@ -13723,6 +14039,7 @@ async function resolveApplicationAuthNamespace(options) {
|
|
|
13723
14039
|
async function startWorkflowByName(options) {
|
|
13724
14040
|
const machineUser = await loadMachineUserName({
|
|
13725
14041
|
machineUser: options.machineUser,
|
|
14042
|
+
machineUserSource: options.machineUserSource,
|
|
13726
14043
|
profile: options.profile
|
|
13727
14044
|
});
|
|
13728
14045
|
if (!machineUser) throw new Error("Machine user is required. Specify --machine-user, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.");
|
|
@@ -13793,6 +14110,7 @@ const startCommand = defineAppCommand({
|
|
|
13793
14110
|
const { executionId, wait } = await startWorkflowByName({
|
|
13794
14111
|
name: args.name,
|
|
13795
14112
|
machineUser: args["machine-user"],
|
|
14113
|
+
machineUserSource: resolveMachineUserInputSource(args["machine-user"]),
|
|
13796
14114
|
arg: args.arg,
|
|
13797
14115
|
workspaceId: args["workspace-id"],
|
|
13798
14116
|
profile: args.profile,
|
|
@@ -15578,14 +15896,10 @@ const listCommand$7 = defineAppCommand({
|
|
|
15578
15896
|
|
|
15579
15897
|
//#endregion
|
|
15580
15898
|
//#region src/cli/commands/machineuser/token.ts
|
|
15581
|
-
|
|
15582
|
-
* Get a machine user access token for the current application.
|
|
15583
|
-
* @param options - Token retrieval options
|
|
15584
|
-
* @returns Machine user token info
|
|
15585
|
-
*/
|
|
15586
|
-
async function getMachineUserToken(options) {
|
|
15899
|
+
async function getMachineUserTokenInternal(options) {
|
|
15587
15900
|
const name = await loadMachineUserName({
|
|
15588
15901
|
machineUser: options.name,
|
|
15902
|
+
machineUserSource: options.nameSource,
|
|
15589
15903
|
profile: options.profile
|
|
15590
15904
|
});
|
|
15591
15905
|
if (!name) throw new Error("Machine user is required. Provide the NAME positional argument, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.");
|
|
@@ -15615,6 +15929,14 @@ async function getMachineUserToken(options) {
|
|
|
15615
15929
|
expiresAt: expiresAt.toISOString()
|
|
15616
15930
|
};
|
|
15617
15931
|
}
|
|
15932
|
+
/**
|
|
15933
|
+
* Get a machine user access token for the current application.
|
|
15934
|
+
* @param options - Token retrieval options
|
|
15935
|
+
* @returns Machine user token info
|
|
15936
|
+
*/
|
|
15937
|
+
async function getMachineUserToken(options) {
|
|
15938
|
+
return await getMachineUserTokenInternal(options);
|
|
15939
|
+
}
|
|
15618
15940
|
const tokenCommand = defineAppCommand({
|
|
15619
15941
|
name: "token",
|
|
15620
15942
|
description: "Get an access token for a machine user.",
|
|
@@ -15622,13 +15944,13 @@ const tokenCommand = defineAppCommand({
|
|
|
15622
15944
|
...deploymentArgs,
|
|
15623
15945
|
name: arg(z.string().optional(), {
|
|
15624
15946
|
positional: true,
|
|
15625
|
-
description: "Machine user name. Falls back to the active profile's default machine user."
|
|
15626
|
-
env: "TAILOR_PLATFORM_MACHINE_USER_NAME"
|
|
15947
|
+
description: "Machine user name. Falls back to TAILOR_PLATFORM_MACHINE_USER_NAME, then the active profile's default machine user."
|
|
15627
15948
|
})
|
|
15628
15949
|
}),
|
|
15629
15950
|
run: async (args) => {
|
|
15630
|
-
const token = await
|
|
15951
|
+
const token = await getMachineUserTokenInternal({
|
|
15631
15952
|
name: args.name,
|
|
15953
|
+
nameSource: resolveMachineUserInputSource(args.name, process.argv.slice(2), { valueIsExplicit: args.name !== void 0 }),
|
|
15632
15954
|
workspaceId: args["workspace-id"],
|
|
15633
15955
|
profile: args.profile,
|
|
15634
15956
|
configPath: args.config
|
|
@@ -16298,62 +16620,67 @@ async function execRemove(client, workspaceId, application, config, confirm) {
|
|
|
16298
16620
|
forRemoval: true,
|
|
16299
16621
|
config
|
|
16300
16622
|
};
|
|
16301
|
-
const
|
|
16302
|
-
|
|
16303
|
-
|
|
16304
|
-
|
|
16305
|
-
|
|
16306
|
-
|
|
16307
|
-
|
|
16308
|
-
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
|
|
16623
|
+
const plans = {
|
|
16624
|
+
tailorDB: await planTailorDB(ctx),
|
|
16625
|
+
staticWebsite: await planStaticWebsite(ctx),
|
|
16626
|
+
aiGateway: await planAIGateway(ctx),
|
|
16627
|
+
idp: await planIdP(ctx),
|
|
16628
|
+
auth: await planAuth(ctx),
|
|
16629
|
+
pipeline: await planPipeline(ctx),
|
|
16630
|
+
app: await planApplication(ctx),
|
|
16631
|
+
executor: await planExecutor(ctx),
|
|
16632
|
+
workflow: await planWorkflow(client, workspaceId, application.name, application.id, {}, {}),
|
|
16633
|
+
workflowExecutionPolicy: await planWorkflowJobFunctionExecutionPolicy(client, workspaceId, application.name, application.id, {}),
|
|
16634
|
+
functionRegistry: await planFunctionRegistry(client, workspaceId, application.name, application.id, []),
|
|
16635
|
+
secretManager: await planSecretManager(ctx)
|
|
16636
|
+
};
|
|
16312
16637
|
const removeLines = [
|
|
16313
|
-
...functionRegistry.changeSet.lines(),
|
|
16314
|
-
...staticWebsite.changeSet.lines(),
|
|
16315
|
-
...aiGateway.changeSet.lines(),
|
|
16316
|
-
...app.lines(),
|
|
16317
|
-
...tailorDB.changeSet.service.lines(),
|
|
16318
|
-
...tailorDB.changeSet.type.lines(),
|
|
16319
|
-
...tailorDB.changeSet.gqlPermission.lines(),
|
|
16320
|
-
...pipeline.changeSet.service.lines(),
|
|
16321
|
-
...pipeline.changeSet.resolver.lines(),
|
|
16322
|
-
...executor.changeSet.lines(),
|
|
16323
|
-
...workflow.changeSet.lines(),
|
|
16324
|
-
...
|
|
16325
|
-
...idp.changeSet.
|
|
16326
|
-
...
|
|
16327
|
-
...auth.changeSet.
|
|
16328
|
-
...auth.changeSet.
|
|
16329
|
-
...auth.changeSet.
|
|
16330
|
-
...auth.changeSet.
|
|
16331
|
-
...auth.changeSet.
|
|
16332
|
-
...auth.changeSet.
|
|
16333
|
-
...auth.changeSet.
|
|
16334
|
-
...auth.changeSet.
|
|
16335
|
-
...auth.changeSet.
|
|
16336
|
-
...
|
|
16337
|
-
...secretManager.
|
|
16638
|
+
...plans.functionRegistry.changeSet.lines(),
|
|
16639
|
+
...plans.staticWebsite.changeSet.lines(),
|
|
16640
|
+
...plans.aiGateway.changeSet.lines(),
|
|
16641
|
+
...plans.app.lines(),
|
|
16642
|
+
...plans.tailorDB.changeSet.service.lines(),
|
|
16643
|
+
...plans.tailorDB.changeSet.type.lines(),
|
|
16644
|
+
...plans.tailorDB.changeSet.gqlPermission.lines(),
|
|
16645
|
+
...plans.pipeline.changeSet.service.lines(),
|
|
16646
|
+
...plans.pipeline.changeSet.resolver.lines(),
|
|
16647
|
+
...plans.executor.changeSet.lines(),
|
|
16648
|
+
...plans.workflow.changeSet.lines(),
|
|
16649
|
+
...plans.workflowExecutionPolicy.changeSet.lines(),
|
|
16650
|
+
...plans.idp.changeSet.service.lines(),
|
|
16651
|
+
...plans.idp.changeSet.client.lines(),
|
|
16652
|
+
...plans.auth.changeSet.service.lines(),
|
|
16653
|
+
...plans.auth.changeSet.idpConfig.lines(),
|
|
16654
|
+
...plans.auth.changeSet.userProfileConfig.lines(),
|
|
16655
|
+
...plans.auth.changeSet.tenantConfig.lines(),
|
|
16656
|
+
...plans.auth.changeSet.machineUser.lines(),
|
|
16657
|
+
...plans.auth.changeSet.oauth2Client.lines(),
|
|
16658
|
+
...plans.auth.changeSet.authHook.lines(),
|
|
16659
|
+
...plans.auth.changeSet.scim.lines(),
|
|
16660
|
+
...plans.auth.changeSet.scimResource.lines(),
|
|
16661
|
+
...plans.auth.changeSet.connection.lines(),
|
|
16662
|
+
...plans.secretManager.vaultChangeSet.lines(),
|
|
16663
|
+
...plans.secretManager.secretChangeSet.lines()
|
|
16338
16664
|
];
|
|
16339
16665
|
if (removeLines.length > 0) logger.log(removeLines.join("\n"));
|
|
16340
|
-
if (tailorDB.changeSet.service.deletes.length === 0 && staticWebsite.changeSet.deletes.length === 0 && aiGateway.changeSet.deletes.length === 0 && idp.changeSet.service.deletes.length === 0 && auth.changeSet.service.deletes.length === 0 && pipeline.changeSet.service.deletes.length === 0 && app.deletes.length === 0 && executor.changeSet.deletes.length === 0 && workflow.changeSet.deletes.length === 0 && functionRegistry.changeSet.deletes.length === 0 && secretManager.vaultChangeSet.deletes.length === 0 && secretManager.secretChangeSet.deletes.length === 0) return;
|
|
16666
|
+
if (plans.tailorDB.changeSet.service.deletes.length === 0 && plans.staticWebsite.changeSet.deletes.length === 0 && plans.aiGateway.changeSet.deletes.length === 0 && plans.idp.changeSet.service.deletes.length === 0 && plans.auth.changeSet.service.deletes.length === 0 && plans.pipeline.changeSet.service.deletes.length === 0 && plans.app.deletes.length === 0 && plans.executor.changeSet.deletes.length === 0 && plans.workflow.changeSet.deletes.length === 0 && plans.workflowExecutionPolicy.changeSet.deletes.length === 0 && plans.functionRegistry.changeSet.deletes.length === 0 && plans.secretManager.vaultChangeSet.deletes.length === 0 && plans.secretManager.secretChangeSet.deletes.length === 0) return;
|
|
16341
16667
|
if (confirm) await confirm();
|
|
16342
|
-
await applyWorkflow(client, workflow, "delete");
|
|
16343
|
-
await
|
|
16344
|
-
await
|
|
16345
|
-
await
|
|
16346
|
-
await
|
|
16347
|
-
await
|
|
16348
|
-
await applyPipeline(client, pipeline, "delete-
|
|
16349
|
-
await
|
|
16350
|
-
await applyAuth(client, auth, "delete-
|
|
16351
|
-
await
|
|
16352
|
-
await applyIdP(client, idp, "delete-
|
|
16353
|
-
await
|
|
16354
|
-
await applyTailorDB(client, tailorDB, "delete-
|
|
16355
|
-
await
|
|
16356
|
-
await
|
|
16668
|
+
await applyWorkflow(client, plans.workflow, "delete");
|
|
16669
|
+
await applyWorkflowJobFunctionExecutionPolicy(client, plans.workflowExecutionPolicy, "delete");
|
|
16670
|
+
await applyExecutor(client, plans.executor, "delete");
|
|
16671
|
+
await applyStaticWebsite(client, plans.staticWebsite, "delete");
|
|
16672
|
+
await applyAIGateway(client, plans.aiGateway, "delete");
|
|
16673
|
+
await applyApplication(client, plans.app, "delete");
|
|
16674
|
+
await applyPipeline(client, plans.pipeline, "delete-resources");
|
|
16675
|
+
await applyPipeline(client, plans.pipeline, "delete-services");
|
|
16676
|
+
await applyAuth(client, plans.auth, "delete-resources");
|
|
16677
|
+
await applyAuth(client, plans.auth, "delete-services");
|
|
16678
|
+
await applyIdP(client, plans.idp, "delete-resources");
|
|
16679
|
+
await applyIdP(client, plans.idp, "delete-services");
|
|
16680
|
+
await applyTailorDB(client, plans.tailorDB, "delete-resources");
|
|
16681
|
+
await applyTailorDB(client, plans.tailorDB, "delete-services");
|
|
16682
|
+
await applyFunctionRegistry(client, workspaceId, plans.functionRegistry, "delete");
|
|
16683
|
+
await applySecretManager(client, plans.secretManager, "delete");
|
|
16357
16684
|
}
|
|
16358
16685
|
/**
|
|
16359
16686
|
* Remove all resources managed by the current application.
|
|
@@ -16529,10 +16856,27 @@ function applicationInfo(app) {
|
|
|
16529
16856
|
updatedAt: app.updateTime ? timestampDate(app.updateTime) : null
|
|
16530
16857
|
};
|
|
16531
16858
|
}
|
|
16859
|
+
async function fetchAIGateways(client, workspaceId, names) {
|
|
16860
|
+
return (await Promise.all(names.map(async (name) => {
|
|
16861
|
+
try {
|
|
16862
|
+
const { aigateway } = await client.getAIGateway({
|
|
16863
|
+
workspaceId,
|
|
16864
|
+
aigatewayName: name
|
|
16865
|
+
});
|
|
16866
|
+
return aigateway ? {
|
|
16867
|
+
name: aigateway.name,
|
|
16868
|
+
url: aigateway.url
|
|
16869
|
+
} : void 0;
|
|
16870
|
+
} catch (error) {
|
|
16871
|
+
if (error instanceof ConnectError && error.code === Code.NotFound) return;
|
|
16872
|
+
throw error;
|
|
16873
|
+
}
|
|
16874
|
+
}))).filter((gateway) => gateway !== void 0);
|
|
16875
|
+
}
|
|
16532
16876
|
/**
|
|
16533
16877
|
* Show applied application information for the current workspace.
|
|
16534
16878
|
* @param options - Show options
|
|
16535
|
-
* @returns
|
|
16879
|
+
* @returns Deployed application, workspace, and AI Gateway information
|
|
16536
16880
|
*/
|
|
16537
16881
|
async function show(options) {
|
|
16538
16882
|
const client = await initOperatorClient(await loadAccessToken({ profile: options?.profile }));
|
|
@@ -16541,10 +16885,15 @@ async function show(options) {
|
|
|
16541
16885
|
profile: options?.profile
|
|
16542
16886
|
});
|
|
16543
16887
|
const { config } = await loadConfig(options?.configPath);
|
|
16544
|
-
const
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16888
|
+
const aiGatewayNames = config.aiGateways?.length ? [...new Set(config.aiGateways.map((gateway) => gateway.name))] : [];
|
|
16889
|
+
const [workspaceResp, resp, aiGateways] = await Promise.all([
|
|
16890
|
+
client.getWorkspace({ workspaceId }),
|
|
16891
|
+
client.getApplication({
|
|
16892
|
+
workspaceId,
|
|
16893
|
+
applicationName: config.name
|
|
16894
|
+
}),
|
|
16895
|
+
fetchAIGateways(client, workspaceId, aiGatewayNames)
|
|
16896
|
+
]);
|
|
16548
16897
|
const { name, ...appInfo } = applicationInfo(assertDefined(resp.application, `application "${config.name}" not found in workspace`));
|
|
16549
16898
|
const workspace = workspaceResp.workspace;
|
|
16550
16899
|
const workspaceFolderName = workspace ? await resolveWorkspaceFolderName(client, workspace) : "";
|
|
@@ -16554,7 +16903,8 @@ async function show(options) {
|
|
|
16554
16903
|
workspaceName: workspace?.name ?? "",
|
|
16555
16904
|
...workspaceFolderName ? { workspaceFolderName } : {},
|
|
16556
16905
|
workspaceRegion: workspace?.region ?? "",
|
|
16557
|
-
...appInfo
|
|
16906
|
+
...appInfo,
|
|
16907
|
+
aiGateways
|
|
16558
16908
|
};
|
|
16559
16909
|
}
|
|
16560
16910
|
const showWorkspaceNameTransformer = createWorkspaceNameTransformer("workspaceName", "workspaceFolderName");
|
|
@@ -17181,7 +17531,7 @@ async function generate(options) {
|
|
|
17181
17531
|
if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
|
|
17182
17532
|
let pluginManager;
|
|
17183
17533
|
if (plugins.length > 0) pluginManager = new PluginManager(plugins);
|
|
17184
|
-
const { defineApplication } = await import("./application-
|
|
17534
|
+
const { defineApplication } = await import("./application-CUkjzfij.mjs");
|
|
17185
17535
|
const application = defineApplication({
|
|
17186
17536
|
config,
|
|
17187
17537
|
pluginManager
|
|
@@ -18869,7 +19219,8 @@ const queryBaseOptionsSchema = z.object({
|
|
|
18869
19219
|
profile: z.string().optional(),
|
|
18870
19220
|
configPath: z.string().optional(),
|
|
18871
19221
|
engine: queryEngineSchema,
|
|
18872
|
-
machineUser: z.string().optional()
|
|
19222
|
+
machineUser: z.string().optional(),
|
|
19223
|
+
machineUserSource: z.enum(["option", "env"]).optional()
|
|
18873
19224
|
});
|
|
18874
19225
|
const queryOptionsSchema = queryBaseOptionsSchema.extend({ query: z.string() });
|
|
18875
19226
|
async function getNamespaceFromSqlQuery(workspaceId, query, client, namespaces) {
|
|
@@ -18894,6 +19245,7 @@ async function loadOptions(options) {
|
|
|
18894
19245
|
if (!result.success) throw new Error(assertDefined(result.error.issues[0], "validation error missing issues").message);
|
|
18895
19246
|
const machineUser = await loadMachineUserName({
|
|
18896
19247
|
machineUser: result.data.machineUser,
|
|
19248
|
+
machineUserSource: result.data.machineUserSource,
|
|
18897
19249
|
profile: result.data.profile
|
|
18898
19250
|
});
|
|
18899
19251
|
if (!machineUser) throw new Error("Machine user is required. Specify --machine-user, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.");
|
|
@@ -19313,7 +19665,8 @@ const queryCommand = defineAppCommand({
|
|
|
19313
19665
|
profile: args.profile,
|
|
19314
19666
|
configPath: args.config,
|
|
19315
19667
|
engine: args.engine,
|
|
19316
|
-
machineUser: args["machine-user"]
|
|
19668
|
+
machineUser: args["machine-user"],
|
|
19669
|
+
machineUserSource: resolveMachineUserInputSource(args["machine-user"])
|
|
19317
19670
|
};
|
|
19318
19671
|
if (mode.mode === "abort") {
|
|
19319
19672
|
logger.info("Editor closed without a query. Nothing was executed.");
|
|
@@ -19456,5 +19809,5 @@ async function registerTsHook(tsHookUrl) {
|
|
|
19456
19809
|
}
|
|
19457
19810
|
|
|
19458
19811
|
//#endregion
|
|
19459
|
-
export { getOrganization as $, compareSnapshotWithRemote as $t, listCommand$3 as A, apiCommand as An, getExecutorWaitFailureMessage as At, show as B,
|
|
19460
|
-
//# sourceMappingURL=register-ts-hook-
|
|
19812
|
+
export { getOrganization as $, compareSnapshotWithRemote as $t, listCommand$3 as A, apiCommand as An, getExecutorWaitFailureMessage as At, show as B, listWorkflowExecutions as Bt, listCommand$2 as C, hasChanges as Cn, listWebhookExecutors as Ct, waitWorkflowExecution as D, PluginManager as Dn, listCommand$9 as Dt, waitCommand as E, sdkNameLabelKey as En, triggerExecutor as Et, generateCommand as F, startWorkflow as Ft, removeCommand$1 as G, deploy as Gt, extractOwnedNamespaces as H, formatKeyValueTable as Ht, generateMigrationScript as I, getCommand$5 as It, organizationTree as J, waitForExecution as Jt, updateCommand$1 as K, ensureConfigId as Kt, writeDbTypesFile as L, getWorkflow as Lt, truncate as M, assertWritable as Mn, listExecutorJobs as Mt, truncateCommand as N, defineAppCommand as Nn, watchExecutorJob as Nt, resumeCommand as O, generateUserTypes as On, listExecutors as Ot, generate as P, startCommand as Pt, getCommand$1 as Q, parseMigrationLabelNumber as Qt, getConfiguredEditorCommand as R, executionsCommand as Rt, listApps as S, formatMigrationDiff as Sn, getFunctionRegistry as St, healthCommand as T, resourceTrn as Tn, triggerCommand as Tt, logBetaWarning as U, getCommand$6 as Ut, showCommand as V, functionExecutionStatusToString as Vt, remove as W, getExecutor as Wt, listCommand$4 as X, MIGRATION_LABEL_KEY as Xt, treeCommand as Y, bundleMigrationScript as Yt, listOrganizations as Z, handleOptionalToRequiredError as Zt, getWorkspace as _, loadDiff as _n, listMachineUsers as _t, updateUser as a, MIGRATE_FILE_NAME as an, getFolder as at, createCommand as b, parseMigrationNumberArg as bn, listFunctionRegistries as bt, listCommand as c, compareLocalTypesWithSnapshot as cn, createCommand$1 as ct, inviteUser as d, getLatestMigrationNumber as dn, listOAuth2Clients as dt, generateAllTypeManifestsFromSnapshot as en, updateCommand$2 as et, restoreCommand as f, getMigrationDirPath as fn, getCommand$3 as ft, getCommand as g, isValidMigrationNumber as gn, listCommand$7 as gt, listWorkspaces as h, getNextMigrationNumber as hn, tokenCommand as ht, updateCommand as i, INITIAL_SCHEMA_NUMBER as in, getCommand$2 as it, listWorkflows as j, apiCall as jn, jobsCommand as jt, resumeWorkflow as k, prompt as kn, getExecutorJob as kt, listUsers as l, compareSnapshots as ln, createFolder as lt, listCommand$1 as m, getMigrationFiles as mn, getMachineUserToken as mt, query as n, DB_TYPES_FILE_NAME as nn, listCommand$5 as nt, removeCommand as o, SCHEMA_FILE_NAME as on, deleteCommand$1 as ot, restoreWorkspace as p, getMigrationFilePath as pn, getOAuth2Client as pt, updateOrganization as q, executeScript as qt, queryCommand as r, DIFF_FILE_NAME as rn, listFolders as rt, removeUser as s, assertValidMigrationFiles as sn, deleteFolder as st, registerTsHook as t, protoGqlPermission as tn, updateFolder as tt, inviteCommand as u, createSnapshotFromLocalTypes as un, listCommand$6 as ut, deleteCommand as v, reconstructSnapshotFromMigrations as vn, generate$1 as vt, getAppHealth as w, getNamespacesWithMigrations as wn, webhookCommand as wt, createWorkspace as x, formatDiffSummary as xn, getCommand$4 as xt, deleteWorkspace as y, formatMigrationNumber as yn, listCommand$8 as yt, openInConfiguredEditor as z, getWorkflowExecution as zt };
|
|
19813
|
+
//# sourceMappingURL=register-ts-hook-BhzVkej0.mjs.map
|