@tailor-platform/sdk 1.67.1 → 1.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +98 -1
  2. package/dist/application-Br48NXBD.mjs +4 -0
  3. package/dist/application-Cr-limKC.mjs +6192 -0
  4. package/dist/application-Cr-limKC.mjs.map +1 -0
  5. package/dist/cli/index.mjs +147 -34
  6. package/dist/cli/index.mjs.map +1 -1
  7. package/dist/cli/lib.d.mts +297 -157
  8. package/dist/cli/lib.mjs +4 -4
  9. package/dist/cli/lib.mjs.map +1 -1
  10. package/dist/cli/skills.mjs +1 -1
  11. package/dist/completion/zsh-worker.zsh +127 -48
  12. package/dist/configure/index.d.mts +2 -2
  13. package/dist/configure/index.mjs +4 -0
  14. package/dist/configure/index.mjs.map +1 -1
  15. package/dist/{crashreport-u9y2npiy.mjs → crashreport-BqyvFk-_.mjs} +2 -2
  16. package/dist/{crashreport-u9y2npiy.mjs.map → crashreport-BqyvFk-_.mjs.map} +1 -1
  17. package/dist/{crashreport-6jpCceOF.mjs → crashreport-BwF8cHF0.mjs} +1 -1
  18. package/dist/enum-constants-C7DaWeQo.mjs.map +1 -1
  19. package/dist/field-C4zdJLW5.mjs.map +1 -1
  20. package/dist/file-utils-BHPxPXmn.mjs.map +1 -1
  21. package/dist/{idp-BlBPtXJ-.d.mts → idp-BmYwCXnJ.d.mts} +30 -3
  22. package/dist/{idp-BZPqpcYY.mjs → idp-ynUfzwpz.mjs} +9 -1
  23. package/dist/idp-ynUfzwpz.mjs.map +1 -0
  24. package/dist/{index-DvEUb3pX.d.mts → index-B7VbJm0_.d.mts} +25 -16
  25. package/dist/{index-DRhMpdnA.d.mts → index-dKNk8hjo.d.mts} +2 -2
  26. package/dist/job-BpsFXPbi.mjs.map +1 -1
  27. package/dist/{kysely-type-D1e0Vwkd.mjs → kysely-type-CSoZxVKN.mjs} +2 -2
  28. package/dist/{kysely-type-D1e0Vwkd.mjs.map → kysely-type-CSoZxVKN.mjs.map} +1 -1
  29. package/dist/{logger-DpJyJvNz.mjs → logger-DKF-JsAK.mjs} +3 -3
  30. package/dist/{logger-DpJyJvNz.mjs.map → logger-DKF-JsAK.mjs.map} +1 -1
  31. package/dist/{mock-DMgIygjE.mjs → mock-wf5qeZLi.mjs} +19 -9
  32. package/dist/mock-wf5qeZLi.mjs.map +1 -0
  33. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  34. package/dist/plugin/index.mjs.map +1 -1
  35. package/dist/registry-D0uB0OrK.mjs.map +1 -1
  36. package/dist/{repl-editor-CJG3sz7A.mjs → repl-editor-DD5YP5mt.mjs} +4 -4
  37. package/dist/{repl-editor-CJG3sz7A.mjs.map → repl-editor-DD5YP5mt.mjs.map} +1 -1
  38. package/dist/runtime/globals.d.mts +3 -2
  39. package/dist/runtime/idp.d.mts +2 -2
  40. package/dist/runtime/idp.mjs +1 -1
  41. package/dist/runtime/index.d.mts +2 -2
  42. package/dist/runtime/index.mjs +1 -1
  43. package/dist/{runtime-BU6KtCvk.mjs → runtime-jowoN6qC.mjs} +803 -226
  44. package/dist/runtime-jowoN6qC.mjs.map +1 -0
  45. package/dist/schema-1msIhXwA.mjs.map +1 -1
  46. package/dist/seed-YAbtMy65.mjs.map +1 -1
  47. package/dist/{service-wI3Hvrgx.mjs → service-B2Jd9CxS.mjs} +2 -2
  48. package/dist/service-B2Jd9CxS.mjs.map +1 -0
  49. package/dist/service-CRaa4Joe.mjs +4 -0
  50. package/dist/{service-DMohAx8a.mjs → service-DDWgZL_L2.mjs} +2 -2
  51. package/dist/service-DDWgZL_L2.mjs.map +1 -0
  52. package/dist/service_pb-DGSmn-aF.mjs +4 -0
  53. package/dist/{application-WpWwTyk9.mjs → service_pb-DSNjrcbW.mjs} +22 -6176
  54. package/dist/service_pb-DSNjrcbW.mjs.map +1 -0
  55. package/dist/telemetry-BQbbVo2t.mjs.map +1 -1
  56. package/dist/types-CmzfQP_m.mjs.map +1 -1
  57. package/dist/utils/test/index.d.mts +2 -2
  58. package/dist/utils/test/index.mjs.map +1 -1
  59. package/dist/vitest/environment.mjs +1 -1
  60. package/dist/vitest/environment.mjs.map +1 -1
  61. package/dist/vitest/index.mjs +4 -4
  62. package/dist/vitest/index.mjs.map +1 -1
  63. package/dist/vitest/setup.mjs +1 -1
  64. package/dist/{workflow.generated-1S50BhEb.d.mts → workflow.generated-Br9bmLdX.d.mts} +98 -3
  65. package/docs/cli/application.md +5 -202
  66. package/docs/cli/auth.md +12 -256
  67. package/docs/cli/completion.md +0 -24
  68. package/docs/cli/crashreport.md +0 -58
  69. package/docs/cli/executor.md +53 -164
  70. package/docs/cli/function.md +2 -118
  71. package/docs/cli/organization.md +1 -211
  72. package/docs/cli/query.md +0 -20
  73. package/docs/cli/secret.md +70 -250
  74. package/docs/cli/setup.md +21 -59
  75. package/docs/cli/skills.md +0 -39
  76. package/docs/cli/staticwebsite.md +24 -172
  77. package/docs/cli/tailordb.md +5 -255
  78. package/docs/cli/upgrade.md +0 -20
  79. package/docs/cli/user.md +32 -247
  80. package/docs/cli/workflow.md +139 -161
  81. package/docs/cli/workspace.md +158 -537
  82. package/docs/cli-reference.md +59 -40
  83. package/docs/configuration.md +7 -1
  84. package/docs/github-actions.md +27 -14
  85. package/docs/services/idp.md +55 -2
  86. package/docs/services/staticwebsite.md +7 -1
  87. package/package.json +23 -18
  88. package/dist/application-Djeezk3m.mjs +0 -4
  89. package/dist/application-WpWwTyk9.mjs.map +0 -1
  90. package/dist/idp-BZPqpcYY.mjs.map +0 -1
  91. package/dist/mock-DMgIygjE.mjs.map +0 -1
  92. package/dist/runtime-BU6KtCvk.mjs.map +0 -1
  93. package/dist/service-BHQIerYh.mjs +0 -4
  94. package/dist/service-DMohAx8a.mjs.map +0 -1
  95. package/dist/service-wI3Hvrgx.mjs.map +0 -1
@@ -1,9 +1,10 @@
1
1
 
2
2
  import { t as db } from "./schema-1msIhXwA.mjs";
3
- import { $ as WorkflowJobExecution_Status, $t as AuthHookPoint, A as loadMachineUserName, At as ExecutorJobStatus, Bt as CreateAuthServiceRequestSchema, Ct as IdPLang, Et as FunctionExecution_Status, F as writePlatformConfig, Ft as CreateAuthIDPConfigRequestSchema, G as resolveStaticWebsiteUrls, Gt as UpdateAuthMachineUserRequestSchema, Ht as CreateUserProfileConfigRequestSchema, It as CreateAuthMachineUserRequestSchema, J as WorkspacePlatformUserRole, Jt as UpdateAuthSCIMResourceRequestSchema, K as byName, Kt as UpdateAuthOAuth2ClientRequestSchema, L as fetchAll, Lt as CreateAuthOAuth2ClientRequestSchema, M as readPlatformConfig, Mt as ExecutorTriggerType, Nt as CreateAuthConnectionRequestSchema, O as loadAccessToken, Ot as CreateExecutorExecutorRequestSchema, Pt as CreateAuthHookRequestSchema, Q as WorkflowExecution_Status, Qt as AuthConnection_Type, R as fetchMachineUserToken, Rt as CreateAuthSCIMConfigRequestSchema, S as getDistDir, St as UpdateIdPServiceRequestSchema, T as loadConfig, Tt as IdPPermissionPermit, U as initOperatorClient, Ut as UpdateAuthHookRequestSchema, Vt as CreateTenantConfigRequestSchema, W as platformBaseUrl, Wt as UpdateAuthIDPConfigRequestSchema, X as CreateWorkflowRequestSchema, Xt as UpdateTenantConfigRequestSchema, Y as CreateWorkflowJobFunctionRequestSchema, Yt as UpdateAuthServiceRequestSchema, Z as UpdateWorkflowRequestSchema, Zt as UpdateUserProfileConfigRequestSchema, _n as Condition_Operator, _t as CreatePipelineServiceRequestSchema, an as AuthSCIMAttribute_Type, at as TailorDBGQLPermission_Permit, b as hasGenerationHooks, bt as PipelineResolver_OperationType, ct as TailorDBType_PermitAction, d as assertUniqueLocalTailorDBTypeNames, dn as CreateApplicationRequestSchema, dt as UpdateStaticWebsiteRequestSchema, en as AuthIDPConfig_AuthType, et as CreateTailorDBServiceRequestSchema, f as assertUniqueTailorDBTypeNamesWithExternal, fn as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, gn as ConditionSchema, gt as CreatePipelineResolverRequestSchema, h as platformBundleDefinePlugin, hn as Subgraph_ServiceType, ht as UpdateSecretManagerSecretRequestSchema, in as AuthSCIMAttribute_Mutability, it as TailorDBGQLPermission_Operator, j as loadWorkspaceId, jt as ExecutorTargetType, k as loadConfigPath, kt as UpdateExecutorExecutorRequestSchema, l as buildExecutorArgsExpr, ln as TenantProviderConfig_TenantProviderType, lt as AddCustomDomainRequestSchema, m as stringifyFunction, mn as ApplicationSchemaUpdateAttemptStatus, mt as CreateSecretManagerVaultRequestSchema, n as generatePluginFilesIfNeeded, nn as AuthOAuth2Client_ClientType, nt as UpdateTailorDBTypeRequestSchema, on as AuthSCIMAttribute_Uniqueness, ot as TailorDBType_Permission_Operator, p as TailorDBTypeSchema, pn as UpdateApplicationRequestSchema, pt as CreateSecretManagerSecretRequestSchema, q as OperatorService, qt as UpdateAuthSCIMConfigRequestSchema, r as loadApplication, rn as AuthOAuth2Client_GrantType, rt as TailorDBGQLPermission_Action, s as HTTP_METHODS, sn as AuthSCIMConfig_AuthorizationType, st as TailorDBType_Permission_Permit, t as defineApplication, tn as AuthInvokerSchema, tt as CreateTailorDBTypeRequestSchema, u as buildResolverOperationHookExpr, un as UserProfileProviderConfig_UserProfileProviderType, ut as CreateStaticWebsiteRequestSchema, vn as FilterSchema, vt as UpdatePipelineResolverRequestSchema, w as hashFile, wt as IdPPermissionOperator, x as createBundleCache, xt as CreateIdPServiceRequestSchema, y as getPluginGenerationDependencies, yn as PageDirection, yt as UpdatePipelineServiceRequestSchema, z as fetchPaged, zt as CreateAuthSCIMResourceRequestSchema } from "./application-WpWwTyk9.mjs";
3
+ import { $ as CreateUserProfileConfigRequestSchema, A as UpdatePipelineServiceRequestSchema, At as PageDirection, B as UpdateExecutorExecutorRequestSchema, Ct as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, D as CreatePipelineResolverRequestSchema, Dt as ConditionSchema, E as UpdateSecretManagerSecretRequestSchema, Et as Subgraph_ServiceType, F as IdPPermissionOperator, G as CreateAuthHookRequestSchema, H as ExecutorTargetType, I as IdPPermissionPermit, J as CreateAuthOAuth2ClientRequestSchema, K as CreateAuthIDPConfigRequestSchema, L as FunctionExecution_Status, M as CreateIdPServiceRequestSchema, N as UpdateIdPServiceRequestSchema, O as CreatePipelineServiceRequestSchema, Ot as Condition_Operator, P as IdPLang, Q as CreateTenantConfigRequestSchema, S as UpdateStaticWebsiteRequestSchema, St as CreateApplicationRequestSchema, T as CreateSecretManagerVaultRequestSchema, Tt as ApplicationSchemaUpdateAttemptStatus, U as ExecutorTriggerType, V as ExecutorJobStatus, W as CreateAuthConnectionRequestSchema, X as CreateAuthSCIMResourceRequestSchema, Y as CreateAuthSCIMConfigRequestSchema, Z as CreateAuthServiceRequestSchema, _ as TailorDBType_Permission_Operator, _t as AuthSCIMAttribute_Uniqueness, a as WorkspacePlatformUserRole, at as UpdateAuthSCIMResourceRequestSchema, b as AddCustomDomainRequestSchema, bt as TenantProviderConfig_TenantProviderType, c as UpdateWorkflowRequestSchema, ct as UpdateUserProfileConfigRequestSchema, d as CreateTailorDBServiceRequestSchema, dt as AuthIDPConfig_AuthType, et as UpdateAuthHookRequestSchema, f as CreateTailorDBTypeRequestSchema, ft as AuthInvokerSchema, g as TailorDBGQLPermission_Permit, gt as AuthSCIMAttribute_Type, h as TailorDBGQLPermission_Operator, ht as AuthSCIMAttribute_Mutability, it as UpdateAuthSCIMConfigRequestSchema, j as PipelineResolver_OperationType, k as UpdatePipelineResolverRequestSchema, kt as FilterSchema, l as WorkflowExecution_Status, lt as AuthConnection_Type, m as TailorDBGQLPermission_Action, mt as AuthOAuth2Client_GrantType, nt as UpdateAuthMachineUserRequestSchema, o as CreateWorkflowJobFunctionRequestSchema, ot as UpdateAuthServiceRequestSchema, p as UpdateTailorDBTypeRequestSchema, pt as AuthOAuth2Client_ClientType, q as CreateAuthMachineUserRequestSchema, rt as UpdateAuthOAuth2ClientRequestSchema, s as CreateWorkflowRequestSchema, st as UpdateTenantConfigRequestSchema, t as OperatorService, tt as UpdateAuthIDPConfigRequestSchema, u as WorkflowJobExecution_Status, ut as AuthHookPoint, v as TailorDBType_Permission_Permit, vt as AuthSCIMConfig_AuthorizationType, w as CreateSecretManagerSecretRequestSchema, wt as UpdateApplicationRequestSchema, x as CreateStaticWebsiteRequestSchema, xt as UserProfileProviderConfig_UserProfileProviderType, y as TailorDBType_PermitAction, z as CreateExecutorExecutorRequestSchema } from "./service_pb-DSNjrcbW.mjs";
4
4
  import { t as assertDefined } from "./assert-CKfwrmCV.mjs";
5
- import { a as parseBoolean, i as symbols, n as logger, r as styles, t as CIPromptError } from "./logger-DpJyJvNz.mjs";
6
- import { o as loadFilesWithIgnores, t as createExecutorService } from "./service-wI3Hvrgx.mjs";
5
+ import { a as parseBoolean, i as symbols, n as logger, r as styles, t as CIPromptError } from "./logger-DKF-JsAK.mjs";
6
+ import { A as loadMachineUserName, F as writePlatformConfig, G as resolveStaticWebsiteUrls, K as byName, L as fetchAll, M as readPlatformConfig, O as loadAccessToken, R as fetchMachineUserToken, S as getDistDir, T as loadConfig, U as initOperatorClient, W as platformBaseUrl, b as hasGenerationHooks, d as assertUniqueLocalTailorDBTypeNames, f as assertUniqueTailorDBTypeNamesWithExternal, h as platformBundleDefinePlugin, j as loadWorkspaceId, k as loadConfigPath, l as buildExecutorArgsExpr, m as stringifyFunction, n as generatePluginFilesIfNeeded, p as TailorDBTypeSchema, r as loadApplication, s as HTTP_METHODS, t as defineApplication, u as buildResolverOperationHookExpr, w as hashFile, x as createBundleCache, y as getPluginGenerationDependencies, z as fetchPaged } from "./application-Cr-limKC.mjs";
7
+ import { o as loadFilesWithIgnores, t as createExecutorService } from "./service-B2Jd9CxS.mjs";
7
8
  import { t as multiline } from "./multiline-Cf9ODpr1.mjs";
8
9
  import { t as readPackageJson } from "./package-json-DcQApfPQ.mjs";
9
10
  import { i as userAgent } from "./secret-file-eB3R3Fil.mjs";
@@ -39,6 +40,7 @@ import * as inflection from "inflection";
39
40
  import { pathToString } from "@bufbuild/protobuf/reflect";
40
41
  import { createValidator } from "@bufbuild/protovalidate";
41
42
  import { setTimeout as setTimeout$1 } from "timers/promises";
43
+ import { setTimeout as setTimeout$2 } from "node:timers/promises";
42
44
  import { spawn } from "node:child_process";
43
45
  import { watch } from "chokidar";
44
46
  import * as madgeModule from "madge";
@@ -384,7 +386,7 @@ function nestedMessage(field) {
384
386
  function isWellKnownType(message) {
385
387
  return message.typeName.startsWith("google.protobuf.");
386
388
  }
387
- const UNREPRESENTABLE_WELL_KNOWN_TYPES = new Set([
389
+ const UNREPRESENTABLE_WELL_KNOWN_TYPES = /* @__PURE__ */ new Set([
388
390
  "google.protobuf.Struct",
389
391
  "google.protobuf.Value",
390
392
  "google.protobuf.ListValue",
@@ -567,7 +569,7 @@ function fieldToJson(field, visited) {
567
569
  return json;
568
570
  }
569
571
  function renderInspectJson(method) {
570
- const visited = new Set([method.input]);
572
+ const visited = /* @__PURE__ */ new Set([method.input]);
571
573
  return {
572
574
  method: method.name,
573
575
  input: {
@@ -598,7 +600,7 @@ function renderInspectText(method) {
598
600
  const lines = [];
599
601
  lines.push(`${method.name}`);
600
602
  lines.push(` request: ${method.input.typeName}`);
601
- const visited = new Set([method.input]);
603
+ const visited = /* @__PURE__ */ new Set([method.input]);
602
604
  for (const f of method.input.fields) lines.push(...renderFieldText(f, " ", visited));
603
605
  lines.push(` response: ${method.output.typeName}`);
604
606
  return lines.join("\n");
@@ -749,7 +751,7 @@ function normalizeBodyFieldKeys(body, fields) {
749
751
  }
750
752
  return changed;
751
753
  }
752
- const FORBIDDEN_SEGMENTS = new Set([
754
+ const FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set([
753
755
  "__proto__",
754
756
  "constructor",
755
757
  "prototype"
@@ -3161,7 +3163,8 @@ function normalizeIdPPermission(permission) {
3161
3163
  read: permission.read.map((p) => normalizeIdPActionPermission(p)),
3162
3164
  update: permission.update.map((p) => normalizeIdPActionPermission(p)),
3163
3165
  delete: permission.delete.map((p) => normalizeIdPActionPermission(p)),
3164
- sendPasswordResetEmail: permission.sendPasswordResetEmail.map((p) => normalizeIdPActionPermission(p))
3166
+ sendPasswordResetEmail: (permission.sendPasswordResetEmail ?? []).map((p) => normalizeIdPActionPermission(p)),
3167
+ unenrollMfa: (permission.unenrollMfa ?? []).map((p) => normalizeIdPActionPermission(p))
3165
3168
  };
3166
3169
  }
3167
3170
  /**
@@ -3187,7 +3190,7 @@ function parseIdPPermission(rawPermission) {
3187
3190
  function findOmittedPermitRules(permission) {
3188
3191
  if (!permission) return [];
3189
3192
  const locations = [];
3190
- for (const action of Object.keys(permission)) permission[action].forEach((rule, index) => {
3193
+ for (const action of Object.keys(permission)) permission[action]?.forEach((rule, index) => {
3191
3194
  if (isObjectFormat(rule) && rule.permit === void 0) locations.push(`${String(action)}[${index}]`);
3192
3195
  });
3193
3196
  return locations;
@@ -3195,6 +3198,14 @@ function findOmittedPermitRules(permission) {
3195
3198
 
3196
3199
  //#endregion
3197
3200
  //#region src/cli/commands/deploy/idp.ts
3201
+ async function resolveServiceReturnOrigins(client, request) {
3202
+ const policy = request.userAuthPolicy;
3203
+ const originals = policy?.allowedReturnOrigins;
3204
+ if (!policy || !originals?.length) return;
3205
+ const resolved = await resolveStaticWebsiteUrls(client, assertDefined(request.workspaceId, "request missing workspaceId"), originals, `IdP service "${request.namespaceName ?? ""}" allowedReturnOrigins`);
3206
+ if (resolved.length !== originals.length) throw new Error(`IdP service "${request.namespaceName ?? ""}" allowedReturnOrigins: ${originals.length - resolved.length} of ${originals.length} entries could not be resolved. Check that each "<name>:url" entry refers to a deployed static website.`);
3207
+ policy.allowedReturnOrigins = resolved;
3208
+ }
3198
3209
  /**
3199
3210
  * Build the vault name for an IdP client.
3200
3211
  * @param namespaceName - IdP namespace name
@@ -3224,9 +3235,11 @@ async function applyIdP(client, result, phase = "create-update") {
3224
3235
  const { changeSet } = result;
3225
3236
  if (phase === "create-update") {
3226
3237
  await Promise.all([...changeSet.service.creates.map(async (create) => {
3238
+ await resolveServiceReturnOrigins(client, create.request);
3227
3239
  await client.createIdPService(create.request);
3228
3240
  await client.setMetadata(create.metaRequest);
3229
3241
  }), ...changeSet.service.updates.map(async (update) => {
3242
+ await resolveServiceReturnOrigins(client, update.request);
3230
3243
  await client.updateIdPService(update.request);
3231
3244
  await client.setMetadata(update.metaRequest);
3232
3245
  })]);
@@ -3285,7 +3298,8 @@ async function applyIdP(client, result, phase = "create-update") {
3285
3298
  async function planIdP(context) {
3286
3299
  const { client, workspaceId, application, forRemoval, forceApplyAll = false, idpUserTriggerTargets } = context;
3287
3300
  const idps = forRemoval ? [] : application.idpServices;
3288
- const { changeSet: serviceChangeSet, conflicts, unmanaged, resourceOwners } = await planServices$3(client, workspaceId, application.name, application.id, idps, idpUserTriggerTargets ?? /* @__PURE__ */ new Set());
3301
+ const expectedLocalWebsites = new Set(application.staticWebsiteServices.map((website) => website.name));
3302
+ const { changeSet: serviceChangeSet, conflicts, unmanaged, resourceOwners } = await planServices$3(client, workspaceId, application.name, application.id, idps, idpUserTriggerTargets ?? /* @__PURE__ */ new Set(), expectedLocalWebsites);
3289
3303
  return {
3290
3304
  changeSet: {
3291
3305
  service: serviceChangeSet,
@@ -3309,7 +3323,11 @@ function normalizeComparableUserAuthPolicy(policy) {
3309
3323
  allowedEmailDomains: (policy?.allowedEmailDomains ?? []).toSorted(),
3310
3324
  allowGoogleOauth: policy?.allowGoogleOauth ?? false,
3311
3325
  disablePasswordAuth: policy?.disablePasswordAuth ?? false,
3312
- allowMicrosoftOauth: policy?.allowMicrosoftOauth ?? false
3326
+ allowMicrosoftOauth: policy?.allowMicrosoftOauth ?? false,
3327
+ enableMfa: policy?.enableMfa ?? false,
3328
+ requireMfa: policy?.requireMfa ?? false,
3329
+ allowedReturnOrigins: (policy?.allowedReturnOrigins ?? []).toSorted(),
3330
+ mfaIssuer: policy?.mfaIssuer ?? ""
3313
3331
  };
3314
3332
  }
3315
3333
  function normalizeComparableDisableGqlOperations(value) {
@@ -3318,7 +3336,9 @@ function normalizeComparableDisableGqlOperations(value) {
3318
3336
  update: value?.update ?? false,
3319
3337
  delete: value?.delete ?? false,
3320
3338
  read: value?.read ?? false,
3321
- sendPasswordResetEmail: value?.sendPasswordResetEmail ?? false
3339
+ sendPasswordResetEmail: value?.sendPasswordResetEmail ?? false,
3340
+ requestMfaSettingsUrl: value?.requestMfaSettingsUrl ?? false,
3341
+ unenrollMfa: value?.unenrollMfa ?? false
3322
3342
  };
3323
3343
  }
3324
3344
  function normalizeComparableEmailConfig(value) {
@@ -3340,7 +3360,7 @@ function normalizeComparableIdPService(input) {
3340
3360
  }
3341
3361
  function normalizeComparablePermission(permission) {
3342
3362
  if (!permission) return;
3343
- if (permission.create.length === 0 && permission.read.length === 0 && permission.update.length === 0 && permission.delete.length === 0 && permission.sendPasswordResetEmail.length === 0) return;
3363
+ if (permission.create.length === 0 && permission.read.length === 0 && permission.update.length === 0 && permission.delete.length === 0 && permission.sendPasswordResetEmail.length === 0 && permission.unenrollMfa.length === 0) return;
3344
3364
  const normalizePolicy = (policy) => ({
3345
3365
  conditions: policy.conditions.map((c) => ({
3346
3366
  left: c.left ? { kind: c.left.kind } : void 0,
@@ -3355,7 +3375,8 @@ function normalizeComparablePermission(permission) {
3355
3375
  read: permission.read.map(normalizePolicy),
3356
3376
  update: permission.update.map(normalizePolicy),
3357
3377
  delete: permission.delete.map(normalizePolicy),
3358
- sendPasswordResetEmail: permission.sendPasswordResetEmail.map(normalizePolicy)
3378
+ sendPasswordResetEmail: permission.sendPasswordResetEmail.map(normalizePolicy),
3379
+ unenrollMfa: permission.unenrollMfa.map(normalizePolicy)
3359
3380
  };
3360
3381
  }
3361
3382
  function areIdPServicesEqual(existing, desired) {
@@ -3369,7 +3390,7 @@ function areIdPServicesEqual(existing, desired) {
3369
3390
  permission: normalizeComparablePermission(existing.permission)
3370
3391
  }), desired);
3371
3392
  }
3372
- async function planServices$3(client, workspaceId, appName, appId, idps, idpUserTriggerTargets) {
3393
+ async function planServices$3(client, workspaceId, appName, appId, idps, idpUserTriggerTargets, expectedLocalWebsites) {
3373
3394
  const changeSet = createChangeSet("IdP services");
3374
3395
  const conflicts = [];
3375
3396
  const unmanaged = [];
@@ -3431,10 +3452,15 @@ async function planServices$3(client, workspaceId, appName, appId, idps, idpUser
3431
3452
  if (omittedPermitLocations.length > 0) logger.warn(`IdP service "${namespaceName}" has permission rule(s) ${omittedPermitLocations.join(", ")} in object form without an explicit "permit"; they default to "deny". Set permit: true (allow) or permit: false (deny) to silence this warning.`);
3432
3453
  const parsedPermission = parseIdPPermission(idp.permission);
3433
3454
  const protoPermission = parsedPermission ? protoIdPPermission(parsedPermission) : void 0;
3455
+ const resolvedReturnOrigins = await resolveStaticWebsiteUrls(client, workspaceId, userAuthPolicy?.allowedReturnOrigins ? [...userAuthPolicy.allowedReturnOrigins] : [], `IdP service "${namespaceName}" allowedReturnOrigins`, { expectedLocalNames: expectedLocalWebsites });
3456
+ const userAuthPolicyForCompare = userAuthPolicy ? {
3457
+ ...userAuthPolicy,
3458
+ allowedReturnOrigins: resolvedReturnOrigins
3459
+ } : userAuthPolicy;
3434
3460
  const desired = normalizeComparableIdPService({
3435
3461
  authorization,
3436
3462
  lang,
3437
- userAuthPolicy: normalizeComparableUserAuthPolicy(userAuthPolicy),
3463
+ userAuthPolicy: normalizeComparableUserAuthPolicy(userAuthPolicyForCompare),
3438
3464
  publishUserEvents,
3439
3465
  disableGqlOperations: normalizeComparableDisableGqlOperations(convertGqlOperationsToDisable(idp.gqlOperations)),
3440
3466
  emailConfig: normalizeComparableEmailConfig(emailConfig),
@@ -3576,7 +3602,9 @@ function convertGqlOperationsToDisable(gqlOperations) {
3576
3602
  update: gqlOperations.update === false,
3577
3603
  delete: gqlOperations.delete === false,
3578
3604
  read: gqlOperations.read === false,
3579
- sendPasswordResetEmail: gqlOperations.sendPasswordResetEmail === false
3605
+ sendPasswordResetEmail: gqlOperations.sendPasswordResetEmail === false,
3606
+ requestMfaSettingsUrl: gqlOperations.requestMfaSettingsUrl === false,
3607
+ unenrollMfa: gqlOperations.unenrollMfa === false
3580
3608
  };
3581
3609
  }
3582
3610
  function protoIdPPermission(permission) {
@@ -3585,7 +3613,8 @@ function protoIdPPermission(permission) {
3585
3613
  read: permission.read.map((p) => protoIdPPolicy(p)),
3586
3614
  update: permission.update.map((p) => protoIdPPolicy(p)),
3587
3615
  delete: permission.delete.map((p) => protoIdPPolicy(p)),
3588
- sendPasswordResetEmail: permission.sendPasswordResetEmail.map((p) => protoIdPPolicy(p))
3616
+ sendPasswordResetEmail: permission.sendPasswordResetEmail.map((p) => protoIdPPolicy(p)),
3617
+ unenrollMfa: permission.unenrollMfa.map((p) => protoIdPPolicy(p))
3589
3618
  };
3590
3619
  }
3591
3620
  function protoIdPPolicy(policy) {
@@ -3756,7 +3785,7 @@ async function planAuth(context) {
3756
3785
  },
3757
3786
  conflicts: [...conflicts, ...connectionResult.conflicts],
3758
3787
  unmanaged: [...unmanaged, ...connectionResult.unmanaged],
3759
- resourceOwners: new Set([...resourceOwners, ...connectionResult.resourceOwners])
3788
+ resourceOwners: /* @__PURE__ */ new Set([...resourceOwners, ...connectionResult.resourceOwners])
3760
3789
  };
3761
3790
  }
3762
3791
  async function planServices$2(client, workspaceId, appName, appId, auths, forceApplyAll = false) {
@@ -4891,7 +4920,7 @@ async function readConfigId(configPath) {
4891
4920
  async function assertConfigIdInCI(configPath) {
4892
4921
  const result = await readConfigId(configPath);
4893
4922
  if (result === null) return;
4894
- if (!result.id) throw new Error("tailor.config.ts is missing an 'id'. CI does not auto-generate one (each run would be treated as a separate app and break resource ownership). Run 'tailor-sdk setup github' or 'tailor-sdk apply' locally and commit the injected id.");
4923
+ if (!result.id) throw new Error("tailor.config.ts is missing an 'id'. CI does not auto-generate one (each run would be treated as a separate app and break resource ownership). Run 'tailor-sdk setup' or 'tailor-sdk apply' locally and commit the injected id.");
4895
4924
  if (!uuidRegex.test(result.id)) throw new Error(`'id' in ${configPath} must be a UUID. To use this config for a separate app, delete it.`);
4896
4925
  }
4897
4926
  /**
@@ -6975,7 +7004,7 @@ function createSnapshotFieldConfig(field) {
6975
7004
  }
6976
7005
  /**
6977
7006
  * Create a snapshot field config from an OperatorFieldConfig (for nested fields)
6978
- * @param {import("@/parser/service/tailordb/types").OperatorFieldConfig} fieldConfig - Field configuration
7007
+ * @param {import("#/parser/service/tailordb/types").OperatorFieldConfig} fieldConfig - Field configuration
6979
7008
  * @returns {SnapshotFieldConfig} Snapshot field configuration
6980
7009
  */
6981
7010
  function createSnapshotFieldConfigFromOperatorConfig(fieldConfig) {
@@ -7825,7 +7854,7 @@ function validateMigrationFiles(migrationsDir) {
7825
7854
  message: `Schema file found at migration ${formatMigrationNumber(num)}, but schema should only exist at ${formatMigrationNumber(0)}`,
7826
7855
  migrationNumber: num
7827
7856
  });
7828
- const allNumbers = [...new Set([...schemaFiles, ...diffFiles])].toSorted((a, b) => a - b);
7857
+ const allNumbers = [.../* @__PURE__ */ new Set([...schemaFiles, ...diffFiles])].toSorted((a, b) => a - b);
7829
7858
  if (allNumbers.length === 0) return errors;
7830
7859
  for (const num of schemaFiles) if (num !== 0 && diffFiles.includes(num)) errors.push({
7831
7860
  type: "duplicate",
@@ -7957,7 +7986,7 @@ function compareFields(typeName, fieldName, remoteField, snapshotField) {
7957
7986
  /**
7958
7987
  * System fields that are auto-generated and should be excluded from comparison
7959
7988
  */
7960
- const SYSTEM_FIELDS = new Set(["id"]);
7989
+ const SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id"]);
7961
7990
  /**
7962
7991
  * Compare remote TailorDB types with a local snapshot
7963
7992
  * @param {ProtoTailorDBType[]} remoteTypes - Remote types from listParsedTailorDBTypes API
@@ -8485,7 +8514,7 @@ function protoGqlOperand(operand) {
8485
8514
  /**
8486
8515
  * Diff change kinds that require pre-migration schema adjustments.
8487
8516
  */
8488
- const PRE_MIGRATION_FIELD_KINDS = new Set([
8517
+ const PRE_MIGRATION_FIELD_KINDS = /* @__PURE__ */ new Set([
8489
8518
  "field_added",
8490
8519
  "field_modified",
8491
8520
  "field_removed"
@@ -8700,7 +8729,7 @@ const DEFAULT_POLL_INTERVAL = 1e3;
8700
8729
  * @returns {Promise<ExecutionWaitResult>} Execution result
8701
8730
  * @throws {Error} If execution is not found
8702
8731
  */
8703
- async function waitForExecution$1(client, workspaceId, executionId, pollInterval = DEFAULT_POLL_INTERVAL) {
8732
+ async function waitForExecution(client, workspaceId, executionId, pollInterval = DEFAULT_POLL_INTERVAL) {
8704
8733
  while (true) {
8705
8734
  const { execution } = await client.getFunctionExecution({
8706
8735
  workspaceId,
@@ -8735,7 +8764,7 @@ async function executeScript(options) {
8735
8764
  invoker
8736
8765
  });
8737
8766
  const executionId = response.executionId;
8738
- const result = await waitForExecution$1(client, workspaceId, executionId, pollInterval);
8767
+ const result = await waitForExecution(client, workspaceId, executionId, pollInterval);
8739
8768
  if (result.status === FunctionExecution_Status.SUCCESS) return {
8740
8769
  success: true,
8741
8770
  logs: result.logs,
@@ -9628,7 +9657,7 @@ async function rollbackSingleMigrationPrePhase(client, changeSet, migration, wor
9628
9657
  const name = update.request.tailordbType?.name;
9629
9658
  if (update.request.namespaceName === migration.namespace && name) namespaceTypes.add(name);
9630
9659
  }
9631
- const applied = new Set([...processedTypes.created, ...processedTypes.updated]);
9660
+ const applied = /* @__PURE__ */ new Set([...processedTypes.created, ...processedTypes.updated]);
9632
9661
  const rollbackTypes = new Set([...namespaceTypes].filter((name) => applied.has(name)));
9633
9662
  if (rollbackTypes.size === 0) return;
9634
9663
  const priorSnapshot = reconstructSnapshotFromMigrations(migration.migrationsDir, migration.number - 1);
@@ -9949,7 +9978,7 @@ const tailordbCompareKnownDefaults = {
9949
9978
  * Proto bigint-backed values can round-trip as numbers locally and strings remotely.
9950
9979
  * Canonicalize them to strings at compare time.
9951
9980
  */
9952
- numericStringPaths: new Set([
9981
+ numericStringPaths: /* @__PURE__ */ new Set([
9953
9982
  "schema.fields.*.serial.start",
9954
9983
  "schema.fields.*.serial.maxValue",
9955
9984
  "schema.settings.defaultQueryLimitSize",
@@ -10529,8 +10558,13 @@ function validateItems(params) {
10529
10558
  *
10530
10559
  * Collections not validated: idp client, tailorDB gqlPermission, functionRegistry — no
10531
10560
  * buf.validate annotations.
10532
- * Application cors is excluded: static-website URL placeholders are resolved at apply time
10533
- * and a bare cors array carries no constraint that would false-positive when omitted.
10561
+ * Application cors and IdP userAuthPolicy.allowedReturnOrigins receive special
10562
+ * handling: static-website URL placeholders are resolved at apply time, so the
10563
+ * relevant origin/URL constraints would false-positive on `<name>:url` entries
10564
+ * here. Application cors is dropped entirely (no other constraint to lose); IdP
10565
+ * `allowedReturnOrigins` substitutes placeholder entries with a dummy origin so
10566
+ * the per-item regex and the cross-field `enable_mfa requires ≥1 origin` rule
10567
+ * still get exercised on the rest of the payload.
10534
10568
  * Workflow jobFunctions map excluded: versions are registered at apply time (registerJobFunctions)
10535
10569
  * and the map field carries no min_items constraint. Job names are validated separately via
10536
10570
  * CreateWorkflowJobFunctionRequestSchema using usedJobNames from the workflow change set.
@@ -10582,8 +10616,25 @@ async function validatePlan(input) {
10582
10616
  creates(CreateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.creates);
10583
10617
  updates(UpdateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.updates);
10584
10618
  creates(AddCustomDomainRequestSchema, "StaticWebsite custom domain", staticWebsite.customDomainChangeSet.creates);
10585
- creates(CreateIdPServiceRequestSchema, "IdP service", idp.changeSet.service.creates);
10586
- updates(UpdateIdPServiceRequestSchema, "IdP service", idp.changeSet.service.updates);
10619
+ const placeholderOriginReplacement = "https://placeholder.invalid";
10620
+ const substituteIdpReturnOrigins = (item) => {
10621
+ const request = item.request;
10622
+ const origins = request.userAuthPolicy?.allowedReturnOrigins;
10623
+ if (!Array.isArray(origins) || origins.length === 0) return item;
10624
+ const substituted = origins.map((origin) => typeof origin === "string" && /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]:url$/.test(origin) ? placeholderOriginReplacement : origin);
10625
+ return {
10626
+ ...item,
10627
+ request: {
10628
+ ...request,
10629
+ userAuthPolicy: {
10630
+ ...request.userAuthPolicy,
10631
+ allowedReturnOrigins: substituted
10632
+ }
10633
+ }
10634
+ };
10635
+ };
10636
+ creates(CreateIdPServiceRequestSchema, "IdP service", idp.changeSet.service.creates.map(substituteIdpReturnOrigins));
10637
+ updates(UpdateIdPServiceRequestSchema, "IdP service", idp.changeSet.service.updates.map(substituteIdpReturnOrigins));
10587
10638
  const idpClientVaultItems = [...idp.changeSet.client.creates.map((c) => ({
10588
10639
  clientName: c.request.client?.name ?? "",
10589
10640
  namespaceName: c.request.namespaceName ?? "",
@@ -11064,7 +11115,7 @@ async function deploy(options) {
11064
11115
  await confirmImportantResourceDeletion(importantDeletions, yes);
11065
11116
  const emptyApps = computeRenamedAppDeletions({
11066
11117
  conflicts: allConflicts,
11067
- resourceOwners: new Set([
11118
+ resourceOwners: /* @__PURE__ */ new Set([
11068
11119
  ...functionRegistry.resourceOwners,
11069
11120
  ...tailorDB.resourceOwners,
11070
11121
  ...staticWebsite.resourceOwners,
@@ -11178,7 +11229,42 @@ function colorizeExecutorJobStatus(status) {
11178
11229
  * @returns True if status is terminal
11179
11230
  */
11180
11231
  function isExecutorJobTerminalStatus(status) {
11181
- return status === ExecutorJobStatus.SUCCESS || status === ExecutorJobStatus.FAILED || status === ExecutorJobStatus.CANCELED;
11232
+ return isExecutorJobSuccessStatus(status) || isExecutorJobFailureStatus(status);
11233
+ }
11234
+ /**
11235
+ * Check if executor job status is successful.
11236
+ * @param status - Executor job status enum value
11237
+ * @returns True if status is success
11238
+ */
11239
+ function isExecutorJobSuccessStatus(status) {
11240
+ return status === ExecutorJobStatus.SUCCESS;
11241
+ }
11242
+ /**
11243
+ * Check if executor job status is a terminal failure.
11244
+ * @param status - Executor job status enum value
11245
+ * @returns True if status is failure
11246
+ */
11247
+ function isExecutorJobFailureStatus(status) {
11248
+ return status === ExecutorJobStatus.FAILED || status === ExecutorJobStatus.CANCELED;
11249
+ }
11250
+ /**
11251
+ * Check if executor job status can still progress.
11252
+ * @param status - Executor job status enum value
11253
+ * @returns True if status is transient
11254
+ */
11255
+ function isExecutorJobTransientStatus(status) {
11256
+ return status === ExecutorJobStatus.UNSPECIFIED || status === ExecutorJobStatus.PENDING || status === ExecutorJobStatus.RUNNING;
11257
+ }
11258
+ /**
11259
+ * Classify executor job status for waiter decisions.
11260
+ * @param status - Executor job status enum value
11261
+ * @returns Classified executor job status
11262
+ */
11263
+ function classifyExecutorJobStatus(status) {
11264
+ if (isExecutorJobSuccessStatus(status)) return "success";
11265
+ if (isExecutorJobTerminalStatus(status)) return "failure";
11266
+ if (isExecutorJobTransientStatus(status)) return "transient";
11267
+ return "transient";
11182
11268
  }
11183
11269
  /**
11184
11270
  * Parse executor job status string to enum.
@@ -11570,36 +11656,158 @@ function functionExecutionStatusToString(status) {
11570
11656
  }
11571
11657
  }
11572
11658
 
11659
+ //#endregion
11660
+ //#region src/cli/shared/wait-error.ts
11661
+ /**
11662
+ * Format a caught error into a string for diagnostics.
11663
+ * @param error - Error to format
11664
+ * @returns Error message string
11665
+ */
11666
+ function formatWaitError(error) {
11667
+ return error instanceof Error ? error.message : String(error);
11668
+ }
11669
+ /**
11670
+ * Check whether a polling error is retryable (transient platform errors).
11671
+ * @param error - Error to check
11672
+ * @returns True if the error should be retried
11673
+ */
11674
+ function isRetryableWaitError(error) {
11675
+ if (!(error instanceof ConnectError)) return false;
11676
+ return error.code === Code.Aborted || error.code === Code.ResourceExhausted || error.code === Code.Unavailable;
11677
+ }
11678
+
11573
11679
  //#endregion
11574
11680
  //#region src/cli/commands/workflow/args.ts
11681
+ const workflowWaitUntilArg = z.enum([
11682
+ "success",
11683
+ "suspended",
11684
+ "terminal"
11685
+ ]);
11575
11686
  const nameArgs = { name: arg(z.string(), {
11576
11687
  positional: true,
11577
11688
  description: "Workflow name"
11578
11689
  }) };
11579
- const waitArgs = {
11580
- wait: arg(z.boolean().default(false), {
11581
- alias: "W",
11582
- description: "Wait for execution to complete"
11583
- }),
11690
+ const workflowWaitControlArgs = {
11584
11691
  interval: arg(durationArg.default("3s"), {
11585
11692
  alias: "i",
11586
- description: "Polling interval when using --wait (e.g., '3s', '500ms', '1m')"
11693
+ description: "Polling interval when waiting (e.g., '3s', '500ms', '1m')"
11694
+ }),
11695
+ timeout: arg(durationArg.default("10m"), {
11696
+ alias: "t",
11697
+ description: "Maximum time to wait (e.g., '30s', '10m')"
11698
+ }),
11699
+ until: arg(workflowWaitUntilArg.default("terminal"), {
11700
+ alias: "u",
11701
+ description: "Wait target (success, suspended, terminal)"
11587
11702
  }),
11588
11703
  logs: arg(z.boolean().default(false), {
11589
11704
  alias: "l",
11590
- description: "Display job execution logs after completion (requires --wait)"
11705
+ description: "Display job execution logs after completion"
11591
11706
  })
11592
11707
  };
11708
+ const waitArgs = {
11709
+ wait: arg(z.boolean().default(false), {
11710
+ alias: "W",
11711
+ description: "Wait for execution to complete"
11712
+ }),
11713
+ ...workflowWaitControlArgs
11714
+ };
11593
11715
 
11594
11716
  //#endregion
11595
11717
  //#region src/cli/commands/workflow/status.ts
11596
11718
  /**
11719
+ * Check if workflow execution status is successful.
11720
+ * @param status - Workflow execution status enum value
11721
+ * @returns True if status is success
11722
+ */
11723
+ function isWorkflowExecutionSuccessStatus(status) {
11724
+ return status === WorkflowExecution_Status.SUCCESS;
11725
+ }
11726
+ /**
11727
+ * Check if workflow job execution status is suspended or waiting.
11728
+ * @param status - Workflow job execution status enum value
11729
+ * @returns True if status represents a wait point
11730
+ */
11731
+ function isWorkflowJobExecutionSuspendedStatus(status) {
11732
+ return status === WorkflowJobExecution_Status.SUSPEND || status === WorkflowJobExecution_Status.WAITING;
11733
+ }
11734
+ /**
11735
+ * Check if workflow execution status is suspended or waiting.
11736
+ * @param status - Workflow execution status enum value
11737
+ * @returns True if status represents a suspended execution
11738
+ */
11739
+ function isWorkflowExecutionSuspendedStatus(status) {
11740
+ return status === WorkflowExecution_Status.PENDING_RESUME || status === WorkflowExecution_Status.WAITING;
11741
+ }
11742
+ /**
11743
+ * Check if workflow execution status is a terminal failure.
11744
+ * @param status - Workflow execution status enum value
11745
+ * @returns True if status represents failure
11746
+ */
11747
+ function isWorkflowExecutionFailureStatus(status) {
11748
+ return status === WorkflowExecution_Status.FAILED;
11749
+ }
11750
+ /**
11751
+ * Check if workflow execution status can still progress without user action.
11752
+ * @param status - Workflow execution status enum value
11753
+ * @returns True if status is transient
11754
+ */
11755
+ function isWorkflowExecutionTransientStatus(status) {
11756
+ return status === WorkflowExecution_Status.UNSPECIFIED || status === WorkflowExecution_Status.PENDING || status === WorkflowExecution_Status.RUNNING || status === WorkflowExecution_Status.PENDING_RETRY;
11757
+ }
11758
+ /**
11597
11759
  * Check if workflow execution status is terminal.
11598
11760
  * @param status - Workflow execution status enum value
11599
11761
  * @returns True if status is terminal
11600
11762
  */
11601
11763
  function isWorkflowExecutionTerminalStatus(status) {
11602
- return status === WorkflowExecution_Status.SUCCESS || status === WorkflowExecution_Status.FAILED || status === WorkflowExecution_Status.PENDING_RESUME;
11764
+ return isWorkflowExecutionSuccessStatus(status) || isWorkflowExecutionFailureStatus(status) || isWorkflowExecutionSuspendedStatus(status);
11765
+ }
11766
+ /**
11767
+ * Classify workflow execution status for waiter decisions.
11768
+ * @param execution - Workflow execution to classify
11769
+ * @returns Classified workflow execution status
11770
+ */
11771
+ function classifyWorkflowExecutionStatus(execution) {
11772
+ if (isWorkflowExecutionTerminalStatus(execution.status)) {
11773
+ if (isWorkflowExecutionSuccessStatus(execution.status)) return {
11774
+ statusClass: "success",
11775
+ status: execution.status
11776
+ };
11777
+ if (isWorkflowExecutionFailureStatus(execution.status)) return {
11778
+ statusClass: "failure",
11779
+ status: execution.status
11780
+ };
11781
+ return {
11782
+ statusClass: "suspended",
11783
+ status: execution.status
11784
+ };
11785
+ }
11786
+ if (execution.jobExecutions.some((job) => isWorkflowJobExecutionSuspendedStatus(job.status))) return {
11787
+ statusClass: "suspended",
11788
+ status: execution.status
11789
+ };
11790
+ if (isWorkflowExecutionTransientStatus(execution.status)) return {
11791
+ statusClass: "transient",
11792
+ status: execution.status
11793
+ };
11794
+ return {
11795
+ statusClass: "transient",
11796
+ status: execution.status
11797
+ };
11798
+ }
11799
+ /**
11800
+ * Check if a classified workflow execution has reached the requested waiter target.
11801
+ * @param classification - Workflow execution status classification
11802
+ * @param until - Requested wait target
11803
+ * @returns True if the wait target is reached
11804
+ */
11805
+ function hasReachedWorkflowWaitTarget(classification, until) {
11806
+ switch (until) {
11807
+ case "success": return classification.statusClass === "success";
11808
+ case "suspended": return classification.statusClass === "suspended";
11809
+ case "terminal": return classification.statusClass === "success" || classification.statusClass === "failure" || classification.statusClass === "suspended";
11810
+ }
11603
11811
  }
11604
11812
 
11605
11813
  //#endregion
@@ -11616,6 +11824,8 @@ function workflowExecutionStatusToString(status) {
11616
11824
  case WorkflowExecution_Status.RUNNING: return "RUNNING";
11617
11825
  case WorkflowExecution_Status.SUCCESS: return "SUCCESS";
11618
11826
  case WorkflowExecution_Status.FAILED: return "FAILED";
11827
+ case WorkflowExecution_Status.PENDING_RETRY: return "PENDING_RETRY";
11828
+ case WorkflowExecution_Status.WAITING: return "WAITING";
11619
11829
  default: return "UNSPECIFIED";
11620
11830
  }
11621
11831
  }
@@ -11630,6 +11840,7 @@ function workflowJobExecutionStatusToString(status) {
11630
11840
  case WorkflowJobExecution_Status.SUSPEND: return "SUSPEND";
11631
11841
  case WorkflowJobExecution_Status.SUCCESS: return "SUCCESS";
11632
11842
  case WorkflowJobExecution_Status.FAILED: return "FAILED";
11843
+ case WorkflowJobExecution_Status.WAITING: return "WAITING";
11633
11844
  default: return "UNSPECIFIED";
11634
11845
  }
11635
11846
  }
@@ -11695,24 +11906,200 @@ function toWorkflowExecutionInfo(execution) {
11695
11906
  }
11696
11907
 
11697
11908
  //#endregion
11698
- //#region src/cli/commands/workflow/executions.ts
11699
- function sleep$1(ms) {
11700
- return new Promise((resolve) => setTimeout(resolve, ms));
11701
- }
11702
- function formatTime$2(date) {
11909
+ //#region src/cli/commands/workflow/waiter.ts
11910
+ const DEFAULT_WORKFLOW_WAIT_INTERVAL_MS = 3e3;
11911
+ function formatTime$1(date) {
11703
11912
  return date.toLocaleTimeString("en-US", { hour12: false });
11704
11913
  }
11705
- function colorizeStatus$1(status) {
11914
+ function colorizeStatus(status) {
11706
11915
  const statusText = WorkflowExecution_Status[status];
11707
11916
  switch (status) {
11708
- case WorkflowExecution_Status.PENDING: return styles.dim(statusText);
11709
- case WorkflowExecution_Status.PENDING_RESUME: return styles.warning(statusText);
11917
+ case WorkflowExecution_Status.PENDING:
11918
+ case WorkflowExecution_Status.UNSPECIFIED: return styles.dim(statusText);
11919
+ case WorkflowExecution_Status.PENDING_RESUME:
11920
+ case WorkflowExecution_Status.PENDING_RETRY:
11921
+ case WorkflowExecution_Status.WAITING: return styles.warning(statusText);
11710
11922
  case WorkflowExecution_Status.RUNNING: return styles.info(statusText);
11711
11923
  case WorkflowExecution_Status.SUCCESS: return styles.success(statusText);
11712
11924
  case WorkflowExecution_Status.FAILED: return styles.error(statusText);
11713
11925
  default: return statusText;
11714
11926
  }
11715
11927
  }
11928
+ function getActiveJobs(execution) {
11929
+ return execution.jobExecutions.filter((job) => job.status === WorkflowJobExecution_Status.RUNNING || job.status === WorkflowJobExecution_Status.SUSPEND || job.status === WorkflowJobExecution_Status.WAITING).map((job) => job.stackedJobName).join(", ");
11930
+ }
11931
+ function createWorkflowWaitResult(options) {
11932
+ const elapsedMs = Date.now() - options.startedAt;
11933
+ if (options.execution) {
11934
+ const classification = classifyWorkflowExecutionStatus(options.execution);
11935
+ return {
11936
+ ...toWorkflowExecutionInfo(options.execution),
11937
+ statusClass: classification.statusClass,
11938
+ elapsedMs,
11939
+ attempts: options.attempts,
11940
+ timedOut: options.timedOut,
11941
+ lastError: options.lastError
11942
+ };
11943
+ }
11944
+ return {
11945
+ id: options.executionId,
11946
+ workflowName: "",
11947
+ status: "UNKNOWN",
11948
+ statusClass: "unknown",
11949
+ jobExecutions: 0,
11950
+ startedAt: null,
11951
+ finishedAt: null,
11952
+ elapsedMs,
11953
+ attempts: options.attempts,
11954
+ timedOut: options.timedOut,
11955
+ lastError: options.lastError
11956
+ };
11957
+ }
11958
+ /**
11959
+ * Wait for a workflow execution to reach the requested state.
11960
+ * @param options - Workflow waiter options
11961
+ * @returns Final or timed-out workflow wait result
11962
+ */
11963
+ async function waitForWorkflowExecution(options) {
11964
+ const interval = options.interval ?? 3e3;
11965
+ const until = options.until ?? "terminal";
11966
+ const startedAt = Date.now();
11967
+ const sp = options.showProgress ? spinner({ indent: 2 }).start("Waiting for workflow to complete...") : null;
11968
+ let attempts = 0;
11969
+ let lastExecution;
11970
+ let lastError = null;
11971
+ let lastStatus;
11972
+ let lastActiveJobs;
11973
+ try {
11974
+ while (true) {
11975
+ const elapsedMs = Date.now() - startedAt;
11976
+ const remainingMs = options.timeout === void 0 ? void 0 : options.timeout - elapsedMs;
11977
+ if (remainingMs !== void 0 && remainingMs <= 0) {
11978
+ sp?.fail("Workflow wait timed out.");
11979
+ return createWorkflowWaitResult({
11980
+ executionId: options.executionId,
11981
+ execution: lastExecution,
11982
+ startedAt,
11983
+ attempts,
11984
+ timedOut: true,
11985
+ lastError
11986
+ });
11987
+ }
11988
+ try {
11989
+ attempts += 1;
11990
+ const { execution } = await options.client.getWorkflowExecution({
11991
+ workspaceId: options.workspaceId,
11992
+ executionId: options.executionId
11993
+ });
11994
+ if (!execution) {
11995
+ sp?.fail(`Execution '${options.executionId}' not found.`);
11996
+ throw new Error(`Execution '${options.executionId}' not found.`);
11997
+ }
11998
+ lastExecution = execution;
11999
+ lastError = null;
12000
+ const classification = classifyWorkflowExecutionStatus(execution);
12001
+ const coloredStatus = colorizeStatus(execution.status);
12002
+ if (execution.status !== lastStatus) {
12003
+ if (options.showProgress) {
12004
+ sp?.stop();
12005
+ logger.info(`Status: ${coloredStatus}`, {
12006
+ mode: "stream",
12007
+ indent: 2
12008
+ });
12009
+ sp?.start("Waiting for workflow to complete...");
12010
+ }
12011
+ lastStatus = execution.status;
12012
+ }
12013
+ if (options.trackJobs) {
12014
+ const activeJobs = getActiveJobs(execution);
12015
+ if (activeJobs && activeJobs !== lastActiveJobs) {
12016
+ if (options.showProgress) {
12017
+ sp?.stop();
12018
+ logger.info(`Job | ${activeJobs}: ${coloredStatus}`, {
12019
+ mode: "stream",
12020
+ indent: 2
12021
+ });
12022
+ sp?.start("Waiting for workflow to complete...");
12023
+ }
12024
+ lastActiveJobs = activeJobs;
12025
+ }
12026
+ }
12027
+ if (sp) sp.text = `Waiting for workflow to complete... (${formatTime$1(/* @__PURE__ */ new Date())})`;
12028
+ if (hasReachedWorkflowWaitTarget(classification, until) || classification.statusClass === "failure" || until === "suspended" && classification.statusClass === "success") {
12029
+ if (execution.status === WorkflowExecution_Status.SUCCESS) sp?.succeed(`Completed: ${coloredStatus}`);
12030
+ else if (isWorkflowExecutionFailureStatus(execution.status)) sp?.fail(`Completed: ${coloredStatus}`);
12031
+ else if (isWorkflowExecutionSuspendedStatus(execution.status)) sp?.warn(`Completed: ${coloredStatus}`);
12032
+ else sp?.succeed(`Completed: ${coloredStatus}`);
12033
+ return createWorkflowWaitResult({
12034
+ executionId: options.executionId,
12035
+ execution,
12036
+ startedAt,
12037
+ attempts,
12038
+ timedOut: false,
12039
+ lastError
12040
+ });
12041
+ }
12042
+ } catch (error) {
12043
+ if (!isRetryableWaitError(error)) throw error;
12044
+ lastError = formatWaitError(error);
12045
+ if (options.showProgress) {
12046
+ if (sp) sp.text = `Retrying workflow status poll... (${formatTime$1(/* @__PURE__ */ new Date())})`;
12047
+ }
12048
+ }
12049
+ const nextElapsedMs = Date.now() - startedAt;
12050
+ const nextRemainingMs = options.timeout === void 0 ? void 0 : options.timeout - nextElapsedMs;
12051
+ if (nextRemainingMs !== void 0 && nextRemainingMs <= 0) {
12052
+ sp?.fail("Workflow wait timed out.");
12053
+ return createWorkflowWaitResult({
12054
+ executionId: options.executionId,
12055
+ execution: lastExecution,
12056
+ startedAt,
12057
+ attempts,
12058
+ timedOut: true,
12059
+ lastError
12060
+ });
12061
+ }
12062
+ await setTimeout$2(nextRemainingMs === void 0 ? interval : Math.min(interval, nextRemainingMs));
12063
+ }
12064
+ } finally {
12065
+ sp?.stop();
12066
+ }
12067
+ }
12068
+ /**
12069
+ * Wait for an existing workflow execution by ID.
12070
+ * @param options - Workflow execution wait options
12071
+ * @returns Workflow wait result
12072
+ */
12073
+ async function waitForWorkflowExecutionById(options) {
12074
+ return await waitForWorkflowExecution({
12075
+ client: await initOperatorClient(await loadAccessToken({ profile: options.profile })),
12076
+ workspaceId: await loadWorkspaceId({
12077
+ workspaceId: options.workspaceId,
12078
+ profile: options.profile
12079
+ }),
12080
+ executionId: options.executionId,
12081
+ interval: options.interval,
12082
+ timeout: options.timeout,
12083
+ until: options.until,
12084
+ showProgress: options.showProgress,
12085
+ trackJobs: options.trackJobs
12086
+ });
12087
+ }
12088
+ /**
12089
+ * Build a user-facing failure message for a workflow wait result.
12090
+ * @param result - Workflow wait result
12091
+ * @param until - Requested wait target
12092
+ * @returns Failure message, or undefined when the wait succeeded
12093
+ */
12094
+ function getWorkflowWaitFailureMessage(result, until) {
12095
+ if (result.timedOut) return `Timed out waiting for workflow execution '${result.id}' to reach ${until}. Last status: ${result.status}.`;
12096
+ if (result.status === "FAILED") return `Workflow execution '${result.id}' failed.`;
12097
+ if (until === "success" && result.statusClass !== "success") return `Workflow execution '${result.id}' reached ${result.status} before success.`;
12098
+ if (until === "suspended" && result.statusClass !== "suspended") return `Workflow execution '${result.id}' reached ${result.status} before suspension.`;
12099
+ }
12100
+
12101
+ //#endregion
12102
+ //#region src/cli/commands/workflow/executions.ts
11716
12103
  function parseStatus(status) {
11717
12104
  switch (status.toUpperCase()) {
11718
12105
  case "PENDING": return WorkflowExecution_Status.PENDING;
@@ -11720,7 +12107,10 @@ function parseStatus(status) {
11720
12107
  case "RUNNING": return WorkflowExecution_Status.RUNNING;
11721
12108
  case "SUCCESS": return WorkflowExecution_Status.SUCCESS;
11722
12109
  case "FAILED": return WorkflowExecution_Status.FAILED;
11723
- default: throw new Error(`Invalid status: ${status}. Valid values: PENDING, PENDING_RESUME, RUNNING, SUCCESS, FAILED`);
12110
+ case "PENDING_RETRY": return WorkflowExecution_Status.PENDING_RETRY;
12111
+ case "WAITING": return WorkflowExecution_Status.WAITING;
12112
+ case "UNSPECIFIED": return WorkflowExecution_Status.UNSPECIFIED;
12113
+ default: throw new Error(`Invalid status: ${status}. Valid values: UNSPECIFIED, PENDING, PENDING_RESUME, RUNNING, SUCCESS, FAILED, PENDING_RETRY, WAITING`);
11724
12114
  }
11725
12115
  }
11726
12116
  async function listWorkflowExecutions(options) {
@@ -11809,37 +12199,28 @@ async function getWorkflowExecution(options) {
11809
12199
  }
11810
12200
  async function waitForCompletion() {
11811
12201
  const interval = options.interval ?? 3e3;
11812
- while (true) {
11813
- const { execution } = await client.getWorkflowExecution({
11814
- workspaceId,
11815
- executionId: options.executionId
11816
- });
11817
- if (!execution) throw new Error(`Execution '${options.executionId}' not found.`);
11818
- if (isWorkflowExecutionTerminalStatus(execution.status)) return await fetchExecutionWithLogs(options.executionId, options.logs ?? false);
11819
- await sleep$1(interval);
11820
- }
12202
+ const waitResult = await waitForWorkflowExecution({
12203
+ client,
12204
+ workspaceId,
12205
+ executionId: options.executionId,
12206
+ interval,
12207
+ timeout: options.timeout,
12208
+ until: options.until ?? "terminal"
12209
+ });
12210
+ return {
12211
+ ...await fetchExecutionWithLogs(options.executionId, options.logs ?? false),
12212
+ statusClass: waitResult.statusClass,
12213
+ elapsedMs: waitResult.elapsedMs,
12214
+ attempts: waitResult.attempts,
12215
+ timedOut: waitResult.timedOut,
12216
+ lastError: waitResult.lastError
12217
+ };
11821
12218
  }
11822
12219
  return {
11823
12220
  execution: await fetchExecutionWithLogs(options.executionId, options.logs ?? false),
11824
12221
  wait: waitForCompletion
11825
12222
  };
11826
12223
  }
11827
- async function waitWithSpinner(waitFn, interval, json) {
11828
- const sp = !json ? spinner().start("Waiting for workflow to complete...") : null;
11829
- const updateInterval = setInterval(() => {
11830
- if (sp) sp.text = `Waiting for workflow to complete... (${formatTime$2(/* @__PURE__ */ new Date())})`;
11831
- }, interval);
11832
- try {
11833
- const result = await waitFn();
11834
- const coloredStatus = colorizeStatus$1(WorkflowExecution_Status[result.status]);
11835
- if (result.status === "SUCCESS") sp?.succeed(`Completed: ${coloredStatus}`);
11836
- else sp?.fail(`Completed: ${coloredStatus}`);
11837
- return result;
11838
- } finally {
11839
- clearInterval(updateInterval);
11840
- sp?.stop();
11841
- }
11842
- }
11843
12224
  /**
11844
12225
  * Print a workflow execution and its logs in a human-readable format.
11845
12226
  * @param execution - Workflow execution detail info
@@ -11901,19 +12282,55 @@ const executionsCommand = defineAppCommand({
11901
12282
  logs: arg(z.boolean().default(false), { description: "Display job execution logs (detail mode only)" })
11902
12283
  }).strict(),
11903
12284
  run: async (args) => {
12285
+ const jsonOutput = logger.jsonMode || args.json;
11904
12286
  if (args.executionId) {
11905
12287
  const interval = parseDuration(args.interval);
11906
- const { execution, wait } = await getWorkflowExecution({
12288
+ if (!jsonOutput) logger.info(`Execution ID: ${args.executionId}`, { mode: "stream" });
12289
+ if (args.wait) {
12290
+ const result = await waitForWorkflowExecutionById({
12291
+ executionId: args.executionId,
12292
+ workspaceId: args["workspace-id"],
12293
+ profile: args.profile,
12294
+ interval,
12295
+ timeout: parseDuration(args.timeout),
12296
+ until: args.until,
12297
+ showProgress: !jsonOutput,
12298
+ trackJobs: true
12299
+ });
12300
+ if (args.logs && !jsonOutput) {
12301
+ const { execution } = await getWorkflowExecution({
12302
+ executionId: args.executionId,
12303
+ workspaceId: args["workspace-id"],
12304
+ profile: args.profile,
12305
+ logs: true
12306
+ });
12307
+ printExecutionWithLogs(execution);
12308
+ } else if (args.logs) {
12309
+ const { execution } = await getWorkflowExecution({
12310
+ executionId: args.executionId,
12311
+ workspaceId: args["workspace-id"],
12312
+ profile: args.profile,
12313
+ logs: true
12314
+ });
12315
+ const output = {
12316
+ ...result,
12317
+ jobDetails: execution.jobDetails
12318
+ };
12319
+ logger.out(output);
12320
+ } else logger.out(result);
12321
+ const failureMessage = getWorkflowWaitFailureMessage(result, args.until);
12322
+ if (failureMessage) throw new Error(failureMessage);
12323
+ return;
12324
+ }
12325
+ const { execution } = await getWorkflowExecution({
11907
12326
  executionId: args.executionId,
11908
12327
  workspaceId: args["workspace-id"],
11909
12328
  profile: args.profile,
11910
12329
  interval,
11911
12330
  logs: args.logs
11912
12331
  });
11913
- if (!args.json) logger.info(`Execution ID: ${execution.id}`, { mode: "stream" });
11914
- const result = args.wait ? await waitWithSpinner(wait, interval, args.json) : execution;
11915
- if (args.logs && !args.json) printExecutionWithLogs(result);
11916
- else logger.out(result);
12332
+ if (args.logs && !jsonOutput) printExecutionWithLogs(execution);
12333
+ else logger.out(execution);
11917
12334
  } else {
11918
12335
  const executions = await listWorkflowExecutions({
11919
12336
  workspaceId: args["workspace-id"],
@@ -11978,90 +12395,6 @@ const getCommand$5 = defineAppCommand({
11978
12395
 
11979
12396
  //#endregion
11980
12397
  //#region src/cli/commands/workflow/start.ts
11981
- function sleep(ms) {
11982
- return new Promise((resolve) => setTimeout(resolve, ms));
11983
- }
11984
- function formatTime$1(date) {
11985
- return date.toLocaleTimeString("en-US", { hour12: false });
11986
- }
11987
- function colorizeStatus(status) {
11988
- const statusText = WorkflowExecution_Status[status];
11989
- switch (status) {
11990
- case WorkflowExecution_Status.PENDING: return styles.dim(statusText);
11991
- case WorkflowExecution_Status.PENDING_RESUME: return styles.warning(statusText);
11992
- case WorkflowExecution_Status.RUNNING: return styles.info(statusText);
11993
- case WorkflowExecution_Status.SUCCESS: return styles.success(statusText);
11994
- case WorkflowExecution_Status.FAILED: return styles.error(statusText);
11995
- default: return statusText;
11996
- }
11997
- }
11998
- /**
11999
- * Wait for a workflow execution to reach a terminal state, optionally showing progress.
12000
- * @param options - Wait options
12001
- * @returns Final workflow execution info
12002
- */
12003
- async function waitForExecution(options) {
12004
- const { client, workspaceId, executionId, interval, showProgress, trackJobs } = options;
12005
- let lastStatus;
12006
- let lastRunningJobs;
12007
- const sp = showProgress ? spinner({ indent: 2 }).start("Waiting for workflow to complete...") : null;
12008
- try {
12009
- while (true) {
12010
- const { execution } = await client.getWorkflowExecution({
12011
- workspaceId,
12012
- executionId
12013
- });
12014
- if (!execution) {
12015
- sp?.fail(`Execution '${executionId}' not found.`);
12016
- throw new Error(`Execution '${executionId}' not found.`);
12017
- }
12018
- const now = formatTime$1(/* @__PURE__ */ new Date());
12019
- const coloredStatus = colorizeStatus(execution.status);
12020
- if (execution.status !== lastStatus) {
12021
- if (showProgress) {
12022
- sp?.stop();
12023
- logger.info(`Status: ${coloredStatus}`, {
12024
- mode: "stream",
12025
- indent: 2
12026
- });
12027
- sp?.start(`Waiting for workflow to complete...`);
12028
- }
12029
- lastStatus = execution.status;
12030
- }
12031
- if (trackJobs && execution.status === WorkflowExecution_Status.RUNNING) {
12032
- const runningJobs = getRunningJobs(execution);
12033
- if (runningJobs && runningJobs !== lastRunningJobs) {
12034
- if (showProgress) {
12035
- sp?.stop();
12036
- logger.info(`Job | ${runningJobs}: ${coloredStatus}`, {
12037
- mode: "stream",
12038
- indent: 2
12039
- });
12040
- sp?.start(`Waiting for workflow to complete...`);
12041
- }
12042
- lastRunningJobs = runningJobs;
12043
- }
12044
- }
12045
- if (sp) sp.text = `Waiting for workflow to complete... (${now})`;
12046
- if (isTerminalStatus(execution.status)) {
12047
- if (execution.status === WorkflowExecution_Status.SUCCESS) sp?.succeed(`Completed: ${coloredStatus}`);
12048
- else if (execution.status === WorkflowExecution_Status.FAILED) sp?.fail(`Completed: ${coloredStatus}`);
12049
- else sp?.warn(`Completed: ${coloredStatus}`);
12050
- return toWorkflowExecutionInfo(execution);
12051
- }
12052
- await sleep(interval);
12053
- }
12054
- } catch (error) {
12055
- sp?.stop();
12056
- throw error;
12057
- }
12058
- }
12059
- function getRunningJobs(execution) {
12060
- return execution.jobExecutions.filter((job) => job.status === WorkflowJobExecution_Status.RUNNING).map((job) => job.stackedJobName).join(", ");
12061
- }
12062
- function isTerminalStatus(status) {
12063
- return status === WorkflowExecution_Status.SUCCESS || status === WorkflowExecution_Status.FAILED || status === WorkflowExecution_Status.PENDING_RESUME;
12064
- }
12065
12398
  async function startWorkflowCore(options) {
12066
12399
  const { client, workspaceId, workflowName } = options;
12067
12400
  try {
@@ -12076,11 +12409,13 @@ async function startWorkflowCore(options) {
12076
12409
  });
12077
12410
  return {
12078
12411
  executionId,
12079
- wait: (waitOptions) => waitForExecution({
12412
+ wait: (waitOptions) => waitForWorkflowExecution({
12080
12413
  client,
12081
12414
  workspaceId,
12082
12415
  executionId,
12083
12416
  interval: options.interval ?? 3e3,
12417
+ timeout: waitOptions?.timeout,
12418
+ until: waitOptions?.until,
12084
12419
  showProgress: waitOptions?.showProgress,
12085
12420
  trackJobs: true
12086
12421
  })
@@ -12164,7 +12499,11 @@ const startCommand = defineAppCommand({
12164
12499
  const jsonOutput = logger.jsonMode;
12165
12500
  logger.info(`Execution ID: ${executionId}`, { mode: "stream" });
12166
12501
  if (args.wait) {
12167
- const result = await wait({ showProgress: !jsonOutput });
12502
+ const result = await wait({
12503
+ showProgress: !jsonOutput,
12504
+ timeout: parseDuration(args.timeout),
12505
+ until: args.until
12506
+ });
12168
12507
  if (args.logs && !jsonOutput) {
12169
12508
  const { execution } = await getWorkflowExecution({
12170
12509
  executionId,
@@ -12173,7 +12512,20 @@ const startCommand = defineAppCommand({
12173
12512
  logs: true
12174
12513
  });
12175
12514
  printExecutionWithLogs(execution);
12515
+ } else if (args.logs) {
12516
+ const { execution } = await getWorkflowExecution({
12517
+ executionId,
12518
+ workspaceId: args["workspace-id"],
12519
+ profile: args.profile,
12520
+ logs: true
12521
+ });
12522
+ logger.out({
12523
+ ...result,
12524
+ jobDetails: execution.jobDetails
12525
+ });
12176
12526
  } else logger.out(result);
12527
+ const failureMessage = getWorkflowWaitFailureMessage(result, args.until);
12528
+ if (failureMessage) throw new Error(failureMessage);
12177
12529
  } else logger.out({ executionId });
12178
12530
  }
12179
12531
  });
@@ -12183,6 +12535,16 @@ const startCommand = defineAppCommand({
12183
12535
  function formatTime(date) {
12184
12536
  return date.toLocaleTimeString("en-US", { hour12: false });
12185
12537
  }
12538
+ function createUnknownExecutorJob(executorName, jobId) {
12539
+ return {
12540
+ id: jobId,
12541
+ executorName,
12542
+ status: "UNKNOWN",
12543
+ scheduledAt: "N/A",
12544
+ createdAt: "N/A",
12545
+ updatedAt: "N/A"
12546
+ };
12547
+ }
12186
12548
  async function listExecutorJobs(options) {
12187
12549
  const executorName = "executorName" in options ? options.executorName : options.executor.name;
12188
12550
  const client = await initOperatorClient(await loadAccessToken({ profile: options.profile }));
@@ -12266,7 +12628,27 @@ async function watchExecutorJob(options) {
12266
12628
  profile: options.profile
12267
12629
  });
12268
12630
  const interval = options.interval ?? 3e3;
12269
- const sp = spinner().start("Waiting for executor job to complete...");
12631
+ const timeout = options.timeout;
12632
+ const showProgress = options.showProgress ?? !logger.jsonMode;
12633
+ const startedAt = Date.now();
12634
+ const sp = showProgress ? spinner().start("Waiting for executor job to complete...") : null;
12635
+ let attempts = 0;
12636
+ let lastError = null;
12637
+ const remainingTimeout = () => {
12638
+ if (timeout === void 0) return;
12639
+ return timeout - (Date.now() - startedAt);
12640
+ };
12641
+ const withWaitMetadata = (result, timedOut) => ({
12642
+ ...result,
12643
+ elapsedMs: Date.now() - startedAt,
12644
+ attempts,
12645
+ timedOut,
12646
+ lastError
12647
+ });
12648
+ const timeoutResult = (targetType, job) => withWaitMetadata({
12649
+ job: job ? toExecutorJobInfo(job) : createUnknownExecutorJob(executorName, options.jobId),
12650
+ targetType
12651
+ }, true);
12270
12652
  try {
12271
12653
  const { executor } = await client.getExecutorExecutor({
12272
12654
  workspaceId,
@@ -12277,29 +12659,47 @@ async function watchExecutorJob(options) {
12277
12659
  const targetTypeStr = executorTargetTypeToString(targetType);
12278
12660
  let job;
12279
12661
  while (true) {
12280
- job = (await client.getExecutorJob({
12281
- workspaceId,
12282
- executorName,
12283
- jobId: options.jobId
12284
- })).job;
12285
- if (!job) throw new Error(`Job '${options.jobId}' not found.`);
12286
- if (isExecutorJobTerminalStatus(job.status)) break;
12287
- sp.text = `Waiting for executor job... (${formatTime(/* @__PURE__ */ new Date())})`;
12288
- await setTimeout$1(interval);
12662
+ const remainingMs = remainingTimeout();
12663
+ if (remainingMs !== void 0 && remainingMs <= 0) {
12664
+ sp?.fail("Executor job wait timed out.");
12665
+ return timeoutResult(targetTypeStr, job);
12666
+ }
12667
+ try {
12668
+ attempts += 1;
12669
+ job = (await client.getExecutorJob({
12670
+ workspaceId,
12671
+ executorName,
12672
+ jobId: options.jobId
12673
+ })).job;
12674
+ if (!job) throw new Error(`Job '${options.jobId}' not found.`);
12675
+ lastError = null;
12676
+ if (classifyExecutorJobStatus(job.status) !== "transient") break;
12677
+ } catch (error) {
12678
+ if (!isRetryableWaitError(error)) throw error;
12679
+ lastError = formatWaitError(error);
12680
+ if (sp) sp.text = `Retrying executor job poll... (${formatTime(/* @__PURE__ */ new Date())})`;
12681
+ }
12682
+ const nextRemainingMs = remainingTimeout();
12683
+ if (nextRemainingMs !== void 0 && nextRemainingMs <= 0) {
12684
+ sp?.fail("Executor job wait timed out.");
12685
+ return timeoutResult(targetTypeStr, job);
12686
+ }
12687
+ if (sp) sp.text = `Waiting for executor job... (${formatTime(/* @__PURE__ */ new Date())})`;
12688
+ await setTimeout$1(nextRemainingMs === void 0 ? interval : Math.min(interval, nextRemainingMs));
12289
12689
  }
12290
12690
  const jobInfo = toExecutorJobInfo(job);
12291
12691
  const coloredStatus = colorizeExecutorJobStatus(jobInfo.status);
12292
- if (job.status === ExecutorJobStatus.SUCCESS) sp.succeed(`Executor job completed: ${coloredStatus}`);
12293
- else sp.fail(`Executor job completed: ${coloredStatus}`);
12692
+ if (job.status === ExecutorJobStatus.SUCCESS) sp?.succeed(`Executor job completed: ${coloredStatus}`);
12693
+ else sp?.fail(`Executor job completed: ${coloredStatus}`);
12294
12694
  const attemptInfos = (await fetchAll(async (pageToken, maxPageSize) => {
12295
- const { attempts, nextPageToken } = await client.listExecutorJobAttempts({
12695
+ const { attempts: jobAttempts, nextPageToken } = await client.listExecutorJobAttempts({
12296
12696
  workspaceId,
12297
12697
  jobId: options.jobId,
12298
12698
  pageToken,
12299
12699
  pageSize: maxPageSize,
12300
12700
  pageDirection: PageDirection.DESC
12301
12701
  });
12302
- return [attempts, nextPageToken];
12702
+ return [jobAttempts, nextPageToken];
12303
12703
  })).map(toExecutorJobAttemptInfo);
12304
12704
  const jobDetail = {
12305
12705
  ...jobInfo,
@@ -12308,18 +12708,27 @@ async function watchExecutorJob(options) {
12308
12708
  const operationReference = attemptInfos[0]?.operationReference;
12309
12709
  if (operationReference) switch (targetType) {
12310
12710
  case ExecutorTargetType.WORKFLOW:
12311
- sp.stop();
12711
+ sp?.stop();
12312
12712
  try {
12313
- const executionResult = await waitForExecution({
12713
+ const workflowTimeout = remainingTimeout();
12714
+ if (workflowTimeout !== void 0 && workflowTimeout <= 0) return withWaitMetadata({
12715
+ job: jobDetail,
12716
+ targetType: targetTypeStr,
12717
+ workflowExecutionId: operationReference
12718
+ }, true);
12719
+ const executionResult = await waitForWorkflowExecution({
12314
12720
  client,
12315
12721
  workspaceId,
12316
12722
  executionId: operationReference,
12317
12723
  interval,
12318
- showProgress: true,
12724
+ timeout: workflowTimeout,
12725
+ showProgress,
12319
12726
  trackJobs: true
12320
12727
  });
12728
+ attempts += executionResult.attempts;
12729
+ lastError = executionResult.lastError;
12321
12730
  let workflowJobLogs;
12322
- if (options.logs) {
12731
+ if (options.logs) try {
12323
12732
  const { execution: execWithLogs } = await getWorkflowExecution({
12324
12733
  executionId: operationReference,
12325
12734
  workspaceId: options.workspaceId,
@@ -12331,67 +12740,109 @@ async function watchExecutorJob(options) {
12331
12740
  logs: job.logs,
12332
12741
  result: job.result
12333
12742
  }));
12743
+ } catch (error) {
12744
+ logger.warn(`Could not fetch workflow execution logs: ${error instanceof Error ? error.message : error}`);
12334
12745
  }
12335
- return {
12746
+ return withWaitMetadata({
12336
12747
  job: jobDetail,
12337
12748
  targetType: targetTypeStr,
12338
12749
  workflowExecutionId: operationReference,
12339
12750
  workflowStatus: executionResult.status,
12340
12751
  workflowJobLogs
12341
- };
12752
+ }, executionResult.timedOut);
12342
12753
  } catch (error) {
12343
12754
  logger.warn(`Could not track workflow execution: ${error instanceof Error ? error.message : error}`);
12344
- return {
12755
+ return withWaitMetadata({
12345
12756
  job: jobDetail,
12346
12757
  targetType: targetTypeStr,
12347
12758
  workflowExecutionId: operationReference
12348
- };
12759
+ }, false);
12349
12760
  }
12350
12761
  case ExecutorTargetType.FUNCTION:
12351
12762
  case ExecutorTargetType.JOB_FUNCTION:
12352
- sp.start(`Waiting for function execution ${operationReference}...`);
12763
+ sp?.start(`Waiting for function execution ${operationReference}...`);
12353
12764
  try {
12765
+ let functionStatus;
12354
12766
  while (true) {
12355
- const { execution } = await client.getFunctionExecution({
12356
- workspaceId,
12357
- executionId: operationReference
12358
- });
12359
- if (!execution) throw new Error(`Function execution '${operationReference}' not found.`);
12360
- if (isFunctionExecutionTerminalStatus(execution.status)) {
12361
- const statusStr = functionExecutionStatusToString(execution.status);
12362
- const coloredFnStatus = colorizeFunctionExecutionStatus(statusStr);
12363
- if (execution.status === FunctionExecution_Status.SUCCESS) sp.succeed(`Function execution completed: ${coloredFnStatus}`);
12364
- else sp.fail(`Function execution completed: ${coloredFnStatus}`);
12365
- return {
12767
+ const functionTimeout = remainingTimeout();
12768
+ if (functionTimeout !== void 0 && functionTimeout <= 0) {
12769
+ sp?.fail("Function execution wait timed out.");
12770
+ return withWaitMetadata({
12366
12771
  job: jobDetail,
12367
12772
  targetType: targetTypeStr,
12368
12773
  functionExecutionId: operationReference,
12369
- functionStatus: statusStr,
12370
- functionLogs: options.logs ? execution.logs || void 0 : void 0
12371
- };
12774
+ functionStatus
12775
+ }, true);
12372
12776
  }
12373
- sp.text = `Waiting for function execution... (${formatTime(/* @__PURE__ */ new Date())})`;
12374
- await setTimeout$1(interval);
12777
+ try {
12778
+ attempts += 1;
12779
+ const { execution } = await client.getFunctionExecution({
12780
+ workspaceId,
12781
+ executionId: operationReference
12782
+ });
12783
+ if (!execution) throw new Error(`Function execution '${operationReference}' not found.`);
12784
+ lastError = null;
12785
+ functionStatus = functionExecutionStatusToString(execution.status);
12786
+ if (isFunctionExecutionTerminalStatus(execution.status)) {
12787
+ const coloredFnStatus = colorizeFunctionExecutionStatus(functionStatus);
12788
+ if (execution.status === FunctionExecution_Status.SUCCESS) sp?.succeed(`Function execution completed: ${coloredFnStatus}`);
12789
+ else sp?.fail(`Function execution completed: ${coloredFnStatus}`);
12790
+ return withWaitMetadata({
12791
+ job: jobDetail,
12792
+ targetType: targetTypeStr,
12793
+ functionExecutionId: operationReference,
12794
+ functionStatus,
12795
+ functionLogs: options.logs ? execution.logs || void 0 : void 0
12796
+ }, false);
12797
+ }
12798
+ } catch (error) {
12799
+ if (!isRetryableWaitError(error)) throw error;
12800
+ lastError = formatWaitError(error);
12801
+ if (sp) sp.text = `Retrying function execution poll... (${formatTime(/* @__PURE__ */ new Date())})`;
12802
+ }
12803
+ const nextFunctionTimeout = remainingTimeout();
12804
+ if (nextFunctionTimeout !== void 0 && nextFunctionTimeout <= 0) {
12805
+ sp?.fail("Function execution wait timed out.");
12806
+ return withWaitMetadata({
12807
+ job: jobDetail,
12808
+ targetType: targetTypeStr,
12809
+ functionExecutionId: operationReference,
12810
+ functionStatus
12811
+ }, true);
12812
+ }
12813
+ if (sp) sp.text = `Waiting for function execution... (${formatTime(/* @__PURE__ */ new Date())})`;
12814
+ await setTimeout$1(nextFunctionTimeout === void 0 ? interval : Math.min(interval, nextFunctionTimeout));
12375
12815
  }
12376
12816
  } catch (error) {
12377
- sp.warn(`Could not track function execution: ${error instanceof Error ? error.message : error}`);
12378
- return {
12817
+ sp?.warn(`Could not track function execution: ${error instanceof Error ? error.message : error}`);
12818
+ return withWaitMetadata({
12379
12819
  job: jobDetail,
12380
12820
  targetType: targetTypeStr,
12381
12821
  functionExecutionId: operationReference
12382
- };
12822
+ }, false);
12383
12823
  }
12384
12824
  break;
12385
12825
  default: break;
12386
12826
  }
12387
- return {
12827
+ return withWaitMetadata({
12388
12828
  job: jobDetail,
12389
12829
  targetType: targetTypeStr
12390
- };
12830
+ }, false);
12391
12831
  } finally {
12392
- sp.stop();
12832
+ sp?.stop();
12393
12833
  }
12394
12834
  }
12835
+ /**
12836
+ * Build a user-facing failure message for an executor job wait result.
12837
+ * @param result - Executor job wait result
12838
+ * @returns Failure message, or undefined when the wait succeeded
12839
+ */
12840
+ function getExecutorWaitFailureMessage(result) {
12841
+ if (result.timedOut) return `Timed out waiting for executor job '${result.job.id}'. Last status: ${result.job.status}.`;
12842
+ if (result.job.status === "FAILED" || result.job.status === "CANCELED") return `Executor job '${result.job.id}' completed with status ${result.job.status}.`;
12843
+ if (result.workflowStatus === "FAILED") return `Workflow execution '${result.workflowExecutionId}' failed.`;
12844
+ if (result.functionStatus === "FAILED") return `Function execution '${result.functionExecutionId}' failed.`;
12845
+ }
12395
12846
  function printJobWithAttempts(job) {
12396
12847
  const summaryData = [
12397
12848
  ["id", job.id],
@@ -12473,6 +12924,10 @@ const jobsCommand = defineAppCommand({
12473
12924
  alias: "i",
12474
12925
  description: "Polling interval when using --wait (e.g., '3s', '500ms', '1m')"
12475
12926
  }),
12927
+ timeout: arg(durationArg.default("5m"), {
12928
+ alias: "t",
12929
+ description: "Maximum time to wait when using --wait (e.g., '30s', '5m')"
12930
+ }),
12476
12931
  ...pagedLogArgs,
12477
12932
  limit: arg(nonNegativeIntArg.default(50), { description: "Maximum number of jobs to list (0: unlimited, default: 50) (list mode only)" }),
12478
12933
  logs: arg(z.boolean().default(false), {
@@ -12481,6 +12936,7 @@ const jobsCommand = defineAppCommand({
12481
12936
  })
12482
12937
  }).strict(),
12483
12938
  run: async (args) => {
12939
+ const jsonOutput = logger.jsonMode || args.json;
12484
12940
  if (args.jobId) {
12485
12941
  if (args.wait) {
12486
12942
  const result = await watchExecutorJob({
@@ -12489,9 +12945,11 @@ const jobsCommand = defineAppCommand({
12489
12945
  workspaceId: args["workspace-id"],
12490
12946
  profile: args.profile,
12491
12947
  interval: parseDuration(args.interval),
12492
- logs: args.logs
12948
+ timeout: parseDuration(args.timeout),
12949
+ logs: args.logs,
12950
+ showProgress: !jsonOutput
12493
12951
  });
12494
- if (!args.json) {
12952
+ if (!jsonOutput) {
12495
12953
  logger.log(styles.bold(`Target Type: ${result.targetType}\n`));
12496
12954
  printJobWithAttempts(result.job);
12497
12955
  if (result.workflowExecutionId) {
@@ -12526,6 +12984,8 @@ const jobsCommand = defineAppCommand({
12526
12984
  }
12527
12985
  }
12528
12986
  } else logger.out(result);
12987
+ const failureMessage = getExecutorWaitFailureMessage(result);
12988
+ if (failureMessage) throw new Error(failureMessage);
12529
12989
  return;
12530
12990
  }
12531
12991
  const job = await getExecutorJob({
@@ -12535,7 +12995,7 @@ const jobsCommand = defineAppCommand({
12535
12995
  workspaceId: args["workspace-id"],
12536
12996
  profile: args.profile
12537
12997
  });
12538
- if (args.attempts && !args.json) printJobWithAttempts(job);
12998
+ if (args.attempts && !jsonOutput) printJobWithAttempts(job);
12539
12999
  else logger.out(job);
12540
13000
  } else {
12541
13001
  if (args.wait) logger.warn("--wait flag is ignored in list mode. Specify a job ID to wait.");
@@ -12722,12 +13182,17 @@ The \`--logs\` option displays logs from the downstream execution when available
12722
13182
  alias: "i",
12723
13183
  description: "Polling interval when using --wait (e.g., '3s', '500ms', '1m')"
12724
13184
  }),
13185
+ timeout: arg(durationArg.default("5m"), {
13186
+ alias: "t",
13187
+ description: "Maximum time to wait when using --wait (e.g., '30s', '5m')"
13188
+ }),
12725
13189
  logs: arg(z.boolean().default(false), {
12726
13190
  alias: "l",
12727
13191
  description: "Display function execution logs after completion (requires --wait)"
12728
13192
  })
12729
13193
  }).strict(),
12730
13194
  run: async (args) => {
13195
+ const jsonOutput = logger.jsonMode || args.json;
12731
13196
  await assertWritable({ profile: args.profile });
12732
13197
  const client = await initOperatorClient(await loadAccessToken({ profile: args.profile }));
12733
13198
  const workspaceId = await loadWorkspaceId({
@@ -12768,9 +13233,11 @@ The \`--logs\` option displays logs from the downstream execution when available
12768
13233
  workspaceId: args["workspace-id"],
12769
13234
  profile: args.profile,
12770
13235
  interval: parseDuration(args.interval),
12771
- logs: args.logs
13236
+ timeout: parseDuration(args.timeout),
13237
+ logs: args.logs,
13238
+ showProgress: !jsonOutput
12772
13239
  });
12773
- if (!args.json) {
13240
+ if (!jsonOutput) {
12774
13241
  logger.log(styles.bold(`\nTarget Type: ${watchResult.targetType}`));
12775
13242
  logger.log(`Job Status: ${watchResult.job.status}`);
12776
13243
  if (watchResult.workflowExecutionId) {
@@ -12805,6 +13272,8 @@ The \`--logs\` option displays logs from the downstream execution when available
12805
13272
  }
12806
13273
  }
12807
13274
  } else logger.out(watchResult);
13275
+ const failureMessage = getExecutorWaitFailureMessage(watchResult);
13276
+ if (failureMessage) throw new Error(failureMessage);
12808
13277
  }
12809
13278
  }
12810
13279
  });
@@ -15182,7 +15651,7 @@ function formatEnumUnion(values) {
15182
15651
  return values.map((v) => `"${v}"`).join(" | ");
15183
15652
  }
15184
15653
  function generateEnumChangeColumnType(enumValueChange, config) {
15185
- const selectType = formatEnumUnion([...new Set([...enumValueChange.beforeValues, ...enumValueChange.afterValues])]);
15654
+ const selectType = formatEnumUnion([.../* @__PURE__ */ new Set([...enumValueChange.beforeValues, ...enumValueChange.afterValues])]);
15186
15655
  const afterType = formatEnumUnion(enumValueChange.afterValues);
15187
15656
  if (config.array && !config.required) return `ColumnType<(${selectType})[] | null, (${afterType})[] | null, (${afterType})[] | null>`;
15188
15657
  if (config.array) return `ColumnType<(${selectType})[], (${afterType})[], (${afterType})[]>`;
@@ -15509,7 +15978,7 @@ async function generate(options) {
15509
15978
  if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
15510
15979
  let pluginManager;
15511
15980
  if (plugins.length > 0) pluginManager = new PluginManager(plugins);
15512
- const { defineApplication } = await import("./application-Djeezk3m.mjs");
15981
+ const { defineApplication } = await import("./application-Br48NXBD.mjs");
15513
15982
  const application = defineApplication({
15514
15983
  config,
15515
15984
  pluginManager
@@ -15942,11 +16411,13 @@ async function resumeWorkflow(options) {
15942
16411
  });
15943
16412
  return {
15944
16413
  executionId,
15945
- wait: (waitOptions) => waitForExecution({
16414
+ wait: (waitOptions) => waitForWorkflowExecution({
15946
16415
  client,
15947
16416
  workspaceId,
15948
16417
  executionId,
15949
16418
  interval: options.interval ?? 3e3,
16419
+ timeout: waitOptions?.timeout,
16420
+ until: waitOptions?.until,
15950
16421
  showProgress: waitOptions?.showProgress
15951
16422
  })
15952
16423
  };
@@ -15970,16 +16441,21 @@ const resumeCommand = defineAppCommand({
15970
16441
  ...waitArgs
15971
16442
  }).strict(),
15972
16443
  run: async (args) => {
16444
+ const jsonOutput = logger.jsonMode || args.json;
15973
16445
  const { executionId, wait } = await resumeWorkflow({
15974
16446
  executionId: args.executionId,
15975
16447
  workspaceId: args["workspace-id"],
15976
16448
  profile: args.profile,
15977
16449
  interval: parseDuration(args.interval)
15978
16450
  });
15979
- if (!args.json) logger.info(`Execution ID: ${executionId}`, { mode: "stream" });
16451
+ if (!jsonOutput) logger.info(`Execution ID: ${executionId}`, { mode: "stream" });
15980
16452
  if (args.wait) {
15981
- const result = await wait({ showProgress: !args.json });
15982
- if (args.logs && !args.json) {
16453
+ const result = await wait({
16454
+ showProgress: !jsonOutput,
16455
+ timeout: parseDuration(args.timeout),
16456
+ until: args.until
16457
+ });
16458
+ if (args.logs && !jsonOutput) {
15983
16459
  const { execution } = await getWorkflowExecution({
15984
16460
  executionId,
15985
16461
  workspaceId: args["workspace-id"],
@@ -15987,11 +16463,112 @@ const resumeCommand = defineAppCommand({
15987
16463
  logs: true
15988
16464
  });
15989
16465
  printExecutionWithLogs(execution);
16466
+ } else if (args.logs) {
16467
+ const { execution } = await getWorkflowExecution({
16468
+ executionId,
16469
+ workspaceId: args["workspace-id"],
16470
+ profile: args.profile,
16471
+ logs: true
16472
+ });
16473
+ logger.out({
16474
+ ...result,
16475
+ jobDetails: execution.jobDetails
16476
+ });
15990
16477
  } else logger.out(result);
16478
+ const failureMessage = getWorkflowWaitFailureMessage(result, args.until);
16479
+ if (failureMessage) throw new Error(failureMessage);
15991
16480
  } else logger.out({ executionId });
15992
16481
  }
15993
16482
  });
15994
16483
 
16484
+ //#endregion
16485
+ //#region src/cli/commands/workflow/wait.ts
16486
+ /**
16487
+ * Wait for an existing workflow execution by ID.
16488
+ * @param options - Workflow wait options
16489
+ * @returns Workflow wait result
16490
+ */
16491
+ async function waitWorkflowExecution(options) {
16492
+ return await waitForWorkflowExecutionById({
16493
+ ...options,
16494
+ showProgress: options.showProgress ?? !logger.jsonMode,
16495
+ trackJobs: options.trackJobs ?? true
16496
+ });
16497
+ }
16498
+ /**
16499
+ * Attach workflow job logs to a wait result when requested.
16500
+ * @param result - Workflow wait result
16501
+ * @param options - Workflow wait options
16502
+ * @returns Workflow wait result with optional job details
16503
+ */
16504
+ async function addWorkflowLogsToWaitResult(result, options) {
16505
+ const { execution } = await getWorkflowExecution({
16506
+ executionId: options.executionId,
16507
+ workspaceId: options.workspaceId,
16508
+ profile: options.profile,
16509
+ logs: true
16510
+ });
16511
+ return {
16512
+ ...result,
16513
+ jobDetails: execution.jobDetails
16514
+ };
16515
+ }
16516
+ const waitCommand = defineAppCommand({
16517
+ name: "wait",
16518
+ description: "Wait for a workflow execution.",
16519
+ examples: [
16520
+ {
16521
+ cmd: "execution-id --until success --timeout 10m --json",
16522
+ desc: "Wait for workflow success"
16523
+ },
16524
+ {
16525
+ cmd: "execution-id --until suspended --timeout 6m --logs --json",
16526
+ desc: "Wait for a workflow wait point"
16527
+ },
16528
+ {
16529
+ cmd: "execution-id --until terminal",
16530
+ desc: "Wait for success, failure, or suspension"
16531
+ }
16532
+ ],
16533
+ args: z.object({
16534
+ ...workspaceArgs,
16535
+ "execution-id": arg(z.string(), {
16536
+ positional: true,
16537
+ description: "Execution ID"
16538
+ }),
16539
+ ...workflowWaitControlArgs
16540
+ }).strict(),
16541
+ run: async (args) => {
16542
+ const jsonOutput = logger.jsonMode || args.json;
16543
+ const result = await waitWorkflowExecution({
16544
+ executionId: args.executionId,
16545
+ workspaceId: args["workspace-id"],
16546
+ profile: args.profile,
16547
+ interval: parseDuration(args.interval),
16548
+ timeout: parseDuration(args.timeout),
16549
+ until: args.until,
16550
+ showProgress: !jsonOutput
16551
+ });
16552
+ const output = args.logs ? await addWorkflowLogsToWaitResult(result, {
16553
+ executionId: args.executionId,
16554
+ workspaceId: args["workspace-id"],
16555
+ profile: args.profile
16556
+ }) : result;
16557
+ if (!jsonOutput && output.jobDetails) printExecutionWithLogs({
16558
+ id: output.id,
16559
+ workflowName: output.workflowName,
16560
+ status: output.status,
16561
+ jobExecutions: output.jobExecutions,
16562
+ startedAt: output.startedAt,
16563
+ finishedAt: output.finishedAt,
16564
+ jobDetails: output.jobDetails
16565
+ });
16566
+ else logger.out(output);
16567
+ const failureMessage = getWorkflowWaitFailureMessage(result, args.until);
16568
+ if (failureMessage) throw new Error(failureMessage);
16569
+ }
16570
+ });
16571
+
15995
16572
  //#endregion
15996
16573
  //#region src/cli/commands/workspace/app/transform.ts
15997
16574
  const statusToString = (status) => {
@@ -17335,7 +17912,7 @@ async function runRepl(options) {
17335
17912
  const execute = await prepareQueryExecutor(options);
17336
17913
  const historyPath = getReplHistoryPath(options.engine, options.profile, options.workspaceId);
17337
17914
  const validate = createReplValidator(options.engine);
17338
- const { highlightSqlLine, highlightGraphqlLine, replTransform } = await import("./repl-editor-CJG3sz7A.mjs");
17915
+ const { highlightSqlLine, highlightGraphqlLine, replTransform } = await import("./repl-editor-DD5YP5mt.mjs");
17339
17916
  const highlight = options.engine === "sql" ? highlightSqlLine : highlightGraphqlLine;
17340
17917
  const prompt = createPrompt({
17341
17918
  prefix: "",
@@ -17669,5 +18246,5 @@ function isDeno() {
17669
18246
  }
17670
18247
 
17671
18248
  //#endregion
17672
- export { listCommand$5 as $, INITIAL_SCHEMA_NUMBER as $t, truncate as A, commonArgs as An, startCommand as At, logBetaWarning as B, getExecutor as Bt, listCommand$2 as C, PluginManager as Cn, triggerExecutor as Ct, resumeWorkflow as D, apiCall as Dn, jobsCommand as Dt, resumeCommand as E, apiCommand as En, getExecutorJob as Et, writeDbTypesFile as F, pagedLogArgs as Fn, getWorkflowExecution as Ft, organizationTree as G, MIGRATION_LABEL_KEY as Gt, removeCommand$1 as H, executeScript as Ht, getConfiguredEditorCommand as I, paginationArgs as In, listWorkflowExecutions as It, listOrganizations as J, compareSnapshotWithRemote as Jt, treeCommand as K, handleOptionalToRequiredError as Kt, openInConfiguredEditor as L, toPageDirection as Ln, functionExecutionStatusToString as Lt, generate as M, confirmationArgs as Mn, getCommand$5 as Mt, generateCommand as N, deploymentArgs as Nn, getWorkflow as Nt, listCommand$3 as O, assertWritable as On, listExecutorJobs as Ot, generateMigrationScript as P, isVerbose as Pn, executionsCommand as Pt, updateFolder as Q, DIFF_FILE_NAME as Qt, show as R, workspaceArgs as Rn, formatKeyValueTable as Rt, listApps as S, sdkNameLabelKey as Sn, triggerCommand as St, healthCommand as T, prompt as Tn, listExecutors as Tt, updateCommand$1 as U, waitForExecution$1 as Ut, remove as V, deploy as Vt, updateOrganization as W, bundleMigrationScript as Wt, getOrganization as X, protoGqlPermission as Xt, getCommand$1 as Y, generateAllTypeManifestsFromSnapshot as Yt, updateCommand$2 as Z, DB_TYPES_FILE_NAME as Zt, getWorkspace as _, formatMigrationDiff as _n, listFunctionRegistries as _t, updateUser as a, createSnapshotFromLocalTypes as an, createCommand$1 as at, createCommand as b, ensureConfigId as bn, listWebhookExecutors as bt, listCommand as c, getMigrationFilePath as cn, listOAuth2Clients as ct, inviteUser as d, isValidMigrationNumber as dn, getMachineUserToken as dt, MIGRATE_FILE_NAME as en, listFolders as et, restoreCommand as f, loadDiff as fn, tokenCommand as ft, getCommand as g, formatDiffSummary as gn, listCommand$8 as gt, listWorkspaces as h, parseMigrationNumberArg as hn, generate$1 as ht, updateCommand as i, compareSnapshots as in, deleteFolder as it, truncateCommand as j, configArg as jn, startWorkflow as jt, listWorkflows as k, defineAppCommand as kn, watchExecutorJob as kt, listUsers as l, getMigrationFiles as ln, getCommand$3 as lt, listCommand$1 as m, formatMigrationNumber as mn, listMachineUsers as mt, query as n, assertValidMigrationFiles as nn, getFolder as nt, removeCommand as o, getLatestMigrationNumber as on, createFolder as ot, restoreWorkspace as p, reconstructSnapshotFromMigrations as pn, listCommand$7 as pt, listCommand$4 as q, parseMigrationLabelNumber as qt, queryCommand as r, compareLocalTypesWithSnapshot as rn, deleteCommand$1 as rt, removeUser as s, getMigrationDirPath as sn, listCommand$6 as st, isNativeTypeScriptRuntime as t, SCHEMA_FILE_NAME as tn, getCommand$2 as tt, inviteCommand as u, getNextMigrationNumber as un, getOAuth2Client as ut, deleteCommand as v, hasChanges as vn, getCommand$4 as vt, getAppHealth as w, generateUserTypes as wn, listCommand$9 as wt, createWorkspace as x, resourceTrn as xn, webhookCommand as xt, deleteWorkspace as y, getNamespacesWithMigrations as yn, getFunctionRegistry as yt, showCommand as z, getCommand$6 as zt };
17673
- //# sourceMappingURL=runtime-BU6KtCvk.mjs.map
18249
+ export { updateCommand$2 as $, protoGqlPermission as $t, listCommand$3 as A, apiCall as An, jobsCommand as At, show as B, toPageDirection as Bn, functionExecutionStatusToString as Bt, listCommand$2 as C, ensureConfigId as Cn, webhookCommand as Ct, waitWorkflowExecution as D, generateUserTypes as Dn, listExecutors as Dt, waitCommand as E, PluginManager as En, listCommand$9 as Et, generateCommand as F, confirmationArgs as Fn, getCommand$5 as Ft, updateCommand$1 as G, executeScript as Gt, logBetaWarning as H, getCommand$6 as Ht, generateMigrationScript as I, deploymentArgs as In, getWorkflow as It, treeCommand as J, MIGRATION_LABEL_KEY as Jt, updateOrganization as K, waitForExecution as Kt, writeDbTypesFile as L, isVerbose as Ln, executionsCommand as Lt, truncate as M, defineAppCommand as Mn, watchExecutorJob as Mt, truncateCommand as N, commonArgs as Nn, startCommand as Nt, resumeCommand as O, prompt as On, getExecutorJob as Ot, generate as P, configArg as Pn, startWorkflow as Pt, getOrganization as Q, generateAllTypeManifestsFromSnapshot as Qt, getConfiguredEditorCommand as R, pagedLogArgs as Rn, getWorkflowExecution as Rt, listApps as S, getNamespacesWithMigrations as Sn, listWebhookExecutors as St, healthCommand as T, sdkNameLabelKey as Tn, triggerExecutor as Tt, remove as U, getExecutor as Ut, showCommand as V, workspaceArgs as Vn, formatKeyValueTable as Vt, removeCommand$1 as W, deploy as Wt, listOrganizations as X, parseMigrationLabelNumber as Xt, listCommand$4 as Y, handleOptionalToRequiredError as Yt, getCommand$1 as Z, compareSnapshotWithRemote as Zt, getWorkspace as _, formatMigrationNumber as _n, generate$1 as _t, updateUser as a, assertValidMigrationFiles as an, deleteCommand$1 as at, createCommand as b, formatMigrationDiff as bn, getCommand$4 as bt, listCommand as c, createSnapshotFromLocalTypes as cn, createFolder as ct, inviteUser as d, getMigrationFilePath as dn, getCommand$3 as dt, DB_TYPES_FILE_NAME as en, updateFolder as et, restoreCommand as f, getMigrationFiles as fn, getOAuth2Client as ft, getCommand as g, reconstructSnapshotFromMigrations as gn, listMachineUsers as gt, listWorkspaces as h, loadDiff as hn, listCommand$7 as ht, updateCommand as i, SCHEMA_FILE_NAME as in, getFolder as it, listWorkflows as j, assertWritable as jn, listExecutorJobs as jt, resumeWorkflow as k, apiCommand as kn, getExecutorWaitFailureMessage as kt, listUsers as l, getLatestMigrationNumber as ln, listCommand$6 as lt, listCommand$1 as m, isValidMigrationNumber as mn, tokenCommand as mt, query as n, INITIAL_SCHEMA_NUMBER as nn, listFolders as nt, removeCommand as o, compareLocalTypesWithSnapshot as on, deleteFolder as ot, restoreWorkspace as p, getNextMigrationNumber as pn, getMachineUserToken as pt, organizationTree as q, bundleMigrationScript as qt, queryCommand as r, MIGRATE_FILE_NAME as rn, getCommand$2 as rt, removeUser as s, compareSnapshots as sn, createCommand$1 as st, isNativeTypeScriptRuntime as t, DIFF_FILE_NAME as tn, listCommand$5 as tt, inviteCommand as u, getMigrationDirPath as un, listOAuth2Clients as ut, deleteCommand as v, parseMigrationNumberArg as vn, listCommand$8 as vt, getAppHealth as w, resourceTrn as wn, triggerCommand as wt, createWorkspace as x, hasChanges as xn, getFunctionRegistry as xt, deleteWorkspace as y, formatDiffSummary as yn, listFunctionRegistries as yt, openInConfiguredEditor as z, paginationArgs as zn, listWorkflowExecutions as zt };
18250
+ //# sourceMappingURL=runtime-jowoN6qC.mjs.map