@tailor-platform/sdk 1.82.0 → 1.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/dist/application-5FOWIxFQ.mjs +3 -0
- package/dist/{application-CVeA53ok.mjs → application-CnCljDwk.mjs} +15 -10
- package/dist/application-CnCljDwk.mjs.map +1 -0
- package/dist/cli/commands/deploy/tailordb/index.d.mts +1 -0
- package/dist/cli/commands/generate/service.d.mts +1 -1
- package/dist/cli/commands/generate/types.d.mts +1 -1
- package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +11 -1
- package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -1
- package/dist/cli/index.mjs +65 -10
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +1 -1
- package/dist/cli/lib.mjs +2 -2
- package/dist/cli/shared/client.d.mts +28 -3
- package/dist/cli/skills.d.mts +1 -1
- package/dist/completion/zsh-worker.zsh +35 -22
- package/dist/configure/index.d.mts +2 -2
- package/dist/configure/index.mjs +173 -5
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/executor/index.d.mts +2 -2
- package/dist/configure/services/executor/trigger/event.d.mts +245 -2
- package/dist/configure/services/executor/trigger/index.d.mts +3 -3
- package/dist/configure/services/index.d.mts +2 -2
- package/dist/configure/services/tailordb/index.d.mts +0 -1
- package/dist/configure/services/workflow/execution-policy.d.mts +2 -2
- package/dist/configure/services/workflow/job.d.mts +9 -0
- package/dist/configure/services/workflow/workflow.d.mts +10 -0
- package/dist/{globals-DUqEetIh.mjs → globals-DraXTdqg.mjs} +6 -5
- package/dist/globals-DraXTdqg.mjs.map +1 -0
- package/dist/{register-typescript-runtime-O7zQNif0.mjs → register-typescript-runtime-BCvWR3HC.mjs} +518 -123
- package/dist/register-typescript-runtime-BCvWR3HC.mjs.map +1 -0
- package/dist/{registry-CXi7rJq7.mjs → registry-Ct0Wgxp1.mjs} +3 -3
- package/dist/registry-Ct0Wgxp1.mjs.map +1 -0
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/workflow.d.mts +39 -21
- package/dist/runtime/workflow.mjs +2 -2
- package/dist/{service-B0MaodSg.mjs → service-CPJWhTLn.mjs} +29 -2
- package/dist/service-CPJWhTLn.mjs.map +1 -0
- package/dist/service-Cigg_U-v.mjs +3 -0
- package/dist/{service_pb-BwZRiNug.mjs → service_pb-D5--My_M.mjs} +5 -5
- package/dist/service_pb-D5--My_M.mjs.map +1 -0
- package/dist/{service_pb-wRkxUta6.mjs → service_pb-i8CmnQP4.mjs} +1 -1
- package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +106 -1
- package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +24 -1
- package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +49 -1
- package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +89 -6
- package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +26 -1
- package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +101 -1
- package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +22 -1
- package/dist/types/executor.generated.d.mts +23 -3
- package/dist/utils/test/index.mjs +18 -12
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/utils/test/mock.d.mts +2 -2
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/index.mjs +30 -24
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mocks/file.d.mts +1 -1
- package/dist/vitest/mocks/workflow.d.mts +20 -15
- package/dist/vitest/setup.mjs +1 -1
- package/dist/{workflow-CkIDJpdg.mjs → workflow-B2mwc7aT.mjs} +17 -9
- package/dist/workflow-B2mwc7aT.mjs.map +1 -0
- package/dist/{workspace_resource_pb-UGK1SSn_.mjs → workspace_resource_pb-DXnO2AT-.mjs} +7 -7
- package/dist/workspace_resource_pb-DXnO2AT-.mjs.map +1 -0
- package/docs/cli/tailordb.md +14 -12
- package/docs/cli-reference.md +15 -15
- package/docs/runtime.md +1 -1
- package/docs/services/executor.md +83 -3
- package/docs/services/idp.md +3 -3
- package/docs/services/tailordb-migration.md +18 -5
- package/docs/services/workflow.md +28 -2
- package/docs/testing.md +1 -1
- package/package.json +16 -16
- package/dist/application-CP0W2sQo.mjs +0 -3
- package/dist/application-CVeA53ok.mjs.map +0 -1
- package/dist/globals-DUqEetIh.mjs.map +0 -1
- package/dist/register-typescript-runtime-O7zQNif0.mjs.map +0 -1
- package/dist/registry-CXi7rJq7.mjs.map +0 -1
- package/dist/service-B0MaodSg.mjs.map +0 -1
- package/dist/service-KnAiVofD.mjs +0 -3
- package/dist/service_pb-BwZRiNug.mjs.map +0 -1
- package/dist/workflow-CkIDJpdg.mjs.map +0 -1
- package/dist/workspace_resource_pb-UGK1SSn_.mjs.map +0 -1
package/dist/{register-typescript-runtime-O7zQNif0.mjs → register-typescript-runtime-BCvWR3HC.mjs}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as db } from "./schema-CYrle8JZ.mjs";
|
|
2
|
-
import { $ as CreateAuthHookRequestSchema, B as IdPLang, Bt as Subgraph_ServiceType, C as CreateStaticWebsiteRequestSchema, Ct as AuthInvokerSchema, D as CreateSecretManagerSecretRequestSchema, Dt as AuthSCIMAttribute_Type, Et as AuthSCIMAttribute_Mutability, Ft as CreateApplicationRequestSchema, H as IdPPermissionPermit, Ht as UpdateAIGatewayRequestSchema, I as PipelineResolver_OperationType, It as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, Jt as FilterSchema, K as CreateExecutorExecutorRequestSchema, Kt as ConditionSchema, L as CreateIdPServiceRequestSchema, Lt as UpdateApplicationRequestSchema, M as CreatePipelineServiceRequestSchema, Mt as UserProfileProviderConfig_UserProfileProviderType, N as UpdatePipelineResolverRequestSchema, O as CreateSecretManagerVaultRequestSchema, Ot as AuthSCIMAttribute_Uniqueness, P as UpdatePipelineServiceRequestSchema, Q as CreateAuthConnectionRequestSchema, R as UpdateIdPServiceRequestSchema, S as AddCustomDomainRequestSchema, St as AuthIDPConfig_AuthType, Tt as AuthOAuth2Client_GrantType, U as FunctionExecution_Status, V as IdPPermissionOperator, Vt as CreateAIGatewayRequestSchema, X as ExecutorTargetType, Y as ExecutorJobStatus, Yt as PageDirection, Z as ExecutorTriggerType, _ as TailorDBGQLPermission_Permit, _t as UpdateUserProfileConfigRequestSchema, a as CreateWorkflowRequestSchema, at as CreateAuthServiceRequestSchema, b as TailorDBType_Permission_Permit, bt as AuthConnection_Type, ct as UpdateAuthConnectionRequestSchema, d as CreateTailorDBServiceRequestSchema, dt as UpdateAuthMachineUserRequestSchema, et as CreateAuthIDPConfigRequestSchema, f as CreateTailorDBTypeRequestSchema, ft as UpdateAuthOAuth2ClientRequestSchema, g as TailorDBGQLPermission_Operator, gt as UpdateTenantConfigRequestSchema, h as TailorDBGQLPermission_Action, ht as UpdateAuthServiceRequestSchema, i as CreateWorkflowJobFunctionRequestSchema, it as CreateAuthSCIMResourceRequestSchema, j as CreatePipelineResolverRequestSchema, jt as TenantProviderConfig_TenantProviderType, k as UpdateSecretManagerSecretRequestSchema, kt as AuthSCIMConfig_AuthorizationType, l as WorkflowExecution_Status, lt as UpdateAuthHookRequestSchema, mt as UpdateAuthSCIMResourceRequestSchema, nt as CreateAuthOAuth2ClientRequestSchema, o as UpdateWorkflowJobFunctionExecutionPolicyRequestSchema, ot as CreateTenantConfigRequestSchema, p as UpdateTailorDBTypeRequestSchema, pt as UpdateAuthSCIMConfigRequestSchema, q as UpdateExecutorExecutorRequestSchema, qt as Condition_Operator, r as CreateWorkflowJobFunctionExecutionPolicyRequestSchema, rt as CreateAuthSCIMConfigRequestSchema, s as UpdateWorkflowRequestSchema, st as CreateUserProfileConfigRequestSchema, t as WorkspacePlatformUserRole, tt as CreateAuthMachineUserRequestSchema, u as WorkflowJobExecution_Status, ut as UpdateAuthIDPConfigRequestSchema, v as TailorDBTypeSchema, w as UpdateStaticWebsiteRequestSchema, wt as AuthOAuth2Client_ClientType, x as TailorDBType_PermitAction, xt as AuthHookPoint, y as TailorDBType_Permission_Operator, yt as AuthConnection_Status, zt as ApplicationSchemaUpdateAttemptStatus } from "./workspace_resource_pb-
|
|
2
|
+
import { $ as CreateAuthHookRequestSchema, B as IdPLang, Bt as Subgraph_ServiceType, C as CreateStaticWebsiteRequestSchema, Ct as AuthInvokerSchema, D as CreateSecretManagerSecretRequestSchema, Dt as AuthSCIMAttribute_Type, Et as AuthSCIMAttribute_Mutability, Ft as CreateApplicationRequestSchema, H as IdPPermissionPermit, Ht as UpdateAIGatewayRequestSchema, I as PipelineResolver_OperationType, It as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, Jt as FilterSchema, K as CreateExecutorExecutorRequestSchema, Kt as ConditionSchema, L as CreateIdPServiceRequestSchema, Lt as UpdateApplicationRequestSchema, M as CreatePipelineServiceRequestSchema, Mt as UserProfileProviderConfig_UserProfileProviderType, N as UpdatePipelineResolverRequestSchema, O as CreateSecretManagerVaultRequestSchema, Ot as AuthSCIMAttribute_Uniqueness, P as UpdatePipelineServiceRequestSchema, Q as CreateAuthConnectionRequestSchema, R as UpdateIdPServiceRequestSchema, S as AddCustomDomainRequestSchema, St as AuthIDPConfig_AuthType, Tt as AuthOAuth2Client_GrantType, U as FunctionExecution_Status, V as IdPPermissionOperator, Vt as CreateAIGatewayRequestSchema, X as ExecutorTargetType, Y as ExecutorJobStatus, Yt as PageDirection, Z as ExecutorTriggerType, _ as TailorDBGQLPermission_Permit, _t as UpdateUserProfileConfigRequestSchema, a as CreateWorkflowRequestSchema, at as CreateAuthServiceRequestSchema, b as TailorDBType_Permission_Permit, bt as AuthConnection_Type, ct as UpdateAuthConnectionRequestSchema, d as CreateTailorDBServiceRequestSchema, dt as UpdateAuthMachineUserRequestSchema, et as CreateAuthIDPConfigRequestSchema, f as CreateTailorDBTypeRequestSchema, ft as UpdateAuthOAuth2ClientRequestSchema, g as TailorDBGQLPermission_Operator, gt as UpdateTenantConfigRequestSchema, h as TailorDBGQLPermission_Action, ht as UpdateAuthServiceRequestSchema, i as CreateWorkflowJobFunctionRequestSchema, it as CreateAuthSCIMResourceRequestSchema, j as CreatePipelineResolverRequestSchema, jt as TenantProviderConfig_TenantProviderType, k as UpdateSecretManagerSecretRequestSchema, kt as AuthSCIMConfig_AuthorizationType, l as WorkflowExecution_Status, lt as UpdateAuthHookRequestSchema, mt as UpdateAuthSCIMResourceRequestSchema, nt as CreateAuthOAuth2ClientRequestSchema, o as UpdateWorkflowJobFunctionExecutionPolicyRequestSchema, ot as CreateTenantConfigRequestSchema, p as UpdateTailorDBTypeRequestSchema, pt as UpdateAuthSCIMConfigRequestSchema, q as UpdateExecutorExecutorRequestSchema, qt as Condition_Operator, r as CreateWorkflowJobFunctionExecutionPolicyRequestSchema, rt as CreateAuthSCIMConfigRequestSchema, s as UpdateWorkflowRequestSchema, st as CreateUserProfileConfigRequestSchema, t as WorkspacePlatformUserRole, tt as CreateAuthMachineUserRequestSchema, u as WorkflowJobExecution_Status, ut as UpdateAuthIDPConfigRequestSchema, v as TailorDBTypeSchema, w as UpdateStaticWebsiteRequestSchema, wt as AuthOAuth2Client_ClientType, x as TailorDBType_PermitAction, xt as AuthHookPoint, y as TailorDBType_Permission_Operator, yt as AuthConnection_Status, zt as ApplicationSchemaUpdateAttemptStatus } from "./workspace_resource_pb-DXnO2AT-.mjs";
|
|
3
3
|
import { t as assertDefined } from "./assert-DBxo8jPo.mjs";
|
|
4
4
|
import { a as parseBoolean, i as symbols, n as logger, o as renderTable, r as styles, t as CIPromptError } from "./logger-CXQq9YIp.mjs";
|
|
5
|
-
import { A as defaultPlatformBaseUrl, B as getPlatformBaseUrl, C as getPluginGenerationDependencies, D as hashContent, E as getDistDir, G as
|
|
6
|
-
import { o as loadFilesWithIgnores, s as functionSchema, t as createExecutorService } from "./service-
|
|
5
|
+
import { A as defaultPlatformBaseUrl, B as getPlatformBaseUrl, C as getPluginGenerationDependencies, D as hashContent, E as getDistDir, G as normalizeBaseUrl, H as initOperatorClient, J as byName, K as rememberPlatformConfigForToken, L as getConsoleBaseUrl, M as fetchAllTolerant, N as fetchMachineUserToken, O as hashFile, P as fetchPaged, R as getOAuth2ClientId, T as createBundleCache, U as isDefaultPlatform, V as initOAuth2Client, W as isNotFoundError, X as LOG_LEVELS, Y as createApplyLimiter, _ as stringifyFunction, d as buildExecutorArgsExpr, f as buildResolverOperationHookExpr, g as TailorDBTypeSchema$1, h as assertUniqueTailorDBTypeNamesWithExternal, i as resolverBundleKey, j as fetchAll, l as HTTP_METHODS, m as assertUniqueLocalTailorDBTypeNames, n as generatePluginFilesIfNeeded, o as WorkflowJobFunctionExecutionPolicySchema, q as resolveStaticWebsiteUrls, r as loadApplication, t as defineApplication, v as resolveTSConfigWithFallback, w as hasGenerationHooks, y as platformBundleDefinePlugin, z as getOrNull } from "./application-CnCljDwk.mjs";
|
|
6
|
+
import { o as loadFilesWithIgnores, s as functionSchema, t as createExecutorService } from "./service-CPJWhTLn.mjs";
|
|
7
7
|
import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "./enum-constants-j9QBF0cB.mjs";
|
|
8
8
|
import { t as multiline } from "./multiline-sfHpTZZK.mjs";
|
|
9
9
|
import { n as fileUtilsPlugin, t as FileUtilsGeneratorID } from "./file-utils-DcyIPFQh.mjs";
|
|
@@ -5926,6 +5926,18 @@ function protoExecutor(context, executor) {
|
|
|
5926
5926
|
}
|
|
5927
5927
|
});
|
|
5928
5928
|
break;
|
|
5929
|
+
case "workflowExecution":
|
|
5930
|
+
case "workflowJobExecution":
|
|
5931
|
+
triggerType = ExecutorTriggerType.EVENT;
|
|
5932
|
+
triggerConfig = typedEventTrigger({
|
|
5933
|
+
case: "workflow",
|
|
5934
|
+
value: {
|
|
5935
|
+
eventTypes: trigger.events,
|
|
5936
|
+
workflowName: trigger.workflowName,
|
|
5937
|
+
...trigger.condition ? { condition: { expr: `(${stringifyFunction(trigger.condition)})(${argsExpr})` } } : {}
|
|
5938
|
+
}
|
|
5939
|
+
});
|
|
5940
|
+
break;
|
|
5929
5941
|
default: throw new Error(`Unknown trigger: ${trigger}`);
|
|
5930
5942
|
}
|
|
5931
5943
|
const target = executor.operation;
|
|
@@ -7200,6 +7212,10 @@ const warningChangeInfoSchema = z.looseObject({
|
|
|
7200
7212
|
fieldName: z.string().optional(),
|
|
7201
7213
|
reason: z.string()
|
|
7202
7214
|
});
|
|
7215
|
+
const scriptSkippedInfoSchema = z.looseObject({
|
|
7216
|
+
reason: z.string().trim().min(1),
|
|
7217
|
+
acknowledgedAt: z.string()
|
|
7218
|
+
});
|
|
7203
7219
|
const migrationDiffSchema = z.looseObject({
|
|
7204
7220
|
version: z.number(),
|
|
7205
7221
|
namespace: z.string(),
|
|
@@ -7210,7 +7226,8 @@ const migrationDiffSchema = z.looseObject({
|
|
|
7210
7226
|
breakingChanges: z.array(breakingChangeInfoSchema),
|
|
7211
7227
|
hasWarnings: z.boolean().optional(),
|
|
7212
7228
|
warnings: z.array(warningChangeInfoSchema).optional(),
|
|
7213
|
-
requiresMigrationScript: z.boolean()
|
|
7229
|
+
requiresMigrationScript: z.boolean(),
|
|
7230
|
+
scriptSkipped: scriptSkippedInfoSchema.optional()
|
|
7214
7231
|
});
|
|
7215
7232
|
|
|
7216
7233
|
//#endregion
|
|
@@ -7852,75 +7869,81 @@ function areFieldsDifferent(oldField, newField) {
|
|
|
7852
7869
|
return false;
|
|
7853
7870
|
}
|
|
7854
7871
|
/**
|
|
7855
|
-
*
|
|
7872
|
+
* Collect breaking changes for a field change
|
|
7856
7873
|
* @param {string} typeName - Name of the type containing the field
|
|
7857
7874
|
* @param {string} fieldName - Name of the field being changed
|
|
7858
7875
|
* @param {SnapshotFieldConfig | undefined} oldField - Old field configuration
|
|
7859
7876
|
* @param {SnapshotFieldConfig | undefined} newField - New field configuration
|
|
7860
|
-
* @returns {BreakingChangeInfo
|
|
7877
|
+
* @returns {BreakingChangeInfo[]} Breaking change information
|
|
7861
7878
|
*/
|
|
7862
|
-
function
|
|
7863
|
-
|
|
7879
|
+
function getBreakingFieldChanges(typeName, fieldName, oldField, newField) {
|
|
7880
|
+
const breakingChanges = [];
|
|
7881
|
+
if (!oldField && newField && newField.required) breakingChanges.push({
|
|
7864
7882
|
typeName,
|
|
7865
7883
|
fieldName,
|
|
7866
7884
|
reason: "Required field added"
|
|
7867
|
-
};
|
|
7868
|
-
if (oldField && newField && oldField.type !== newField.type)
|
|
7885
|
+
});
|
|
7886
|
+
if (oldField && newField && oldField.type !== newField.type) breakingChanges.push({
|
|
7869
7887
|
typeName,
|
|
7870
7888
|
fieldName,
|
|
7871
7889
|
reason: `Field type changed from ${oldField.type} to ${newField.type}`,
|
|
7872
7890
|
unsupported: true,
|
|
7873
7891
|
showThreeStepHint: true
|
|
7874
|
-
};
|
|
7875
|
-
if (oldField && newField && !oldField.required && newField.required)
|
|
7892
|
+
});
|
|
7893
|
+
if (oldField && newField && !oldField.required && newField.required) breakingChanges.push({
|
|
7876
7894
|
typeName,
|
|
7877
7895
|
fieldName,
|
|
7878
7896
|
reason: "Field changed from optional to required"
|
|
7879
|
-
};
|
|
7897
|
+
});
|
|
7880
7898
|
if (oldField && newField && (oldField.array ?? false) !== (newField.array ?? false)) {
|
|
7881
7899
|
const [fromType, toType] = oldField.array ? ["array", "single value"] : ["single value", "array"];
|
|
7882
|
-
|
|
7900
|
+
breakingChanges.push({
|
|
7883
7901
|
typeName,
|
|
7884
7902
|
fieldName,
|
|
7885
7903
|
reason: `Field changed from ${fromType} to ${toType}`,
|
|
7886
7904
|
unsupported: true,
|
|
7887
7905
|
showThreeStepHint: true
|
|
7888
|
-
};
|
|
7906
|
+
});
|
|
7889
7907
|
}
|
|
7890
7908
|
if (oldField && newField) {
|
|
7891
7909
|
const oldForeignKeyType = oldField.foreignKeyType;
|
|
7892
7910
|
const newForeignKeyType = newField.foreignKeyType;
|
|
7893
|
-
if (oldForeignKeyType && newForeignKeyType && oldForeignKeyType !== newForeignKeyType)
|
|
7911
|
+
if (oldForeignKeyType && newForeignKeyType && oldForeignKeyType !== newForeignKeyType) breakingChanges.push({
|
|
7894
7912
|
typeName,
|
|
7895
7913
|
fieldName,
|
|
7896
7914
|
reason: `Foreign key target type changed from ${oldForeignKeyType} to ${newForeignKeyType}`
|
|
7897
|
-
};
|
|
7915
|
+
});
|
|
7898
7916
|
}
|
|
7899
|
-
if (oldField && newField && !(oldField.unique ?? false) && (newField.unique ?? false))
|
|
7917
|
+
if (oldField && newField && !(oldField.unique ?? false) && (newField.unique ?? false)) breakingChanges.push({
|
|
7900
7918
|
typeName,
|
|
7901
7919
|
fieldName,
|
|
7902
7920
|
reason: "Unique constraint added to field"
|
|
7903
|
-
};
|
|
7921
|
+
});
|
|
7922
|
+
if (oldField?.type === "decimal" && newField?.type === "decimal" && oldField.scale !== newField.scale) breakingChanges.push({
|
|
7923
|
+
typeName,
|
|
7924
|
+
fieldName,
|
|
7925
|
+
reason: `Decimal scale changed from ${oldField.scale} to ${newField.scale}`
|
|
7926
|
+
});
|
|
7904
7927
|
if (oldField && newField && oldField.type === "enum" && newField.type === "enum") {
|
|
7905
7928
|
const oldAllowed = oldField.allowedValues ?? [];
|
|
7906
7929
|
const newAllowed = newField.allowedValues ?? [];
|
|
7907
7930
|
const oldValues = oldAllowed.map((v) => v.value);
|
|
7908
7931
|
const newValuesSet = new Set(newAllowed.map((v) => v.value));
|
|
7909
7932
|
const removedValues = oldValues.filter((v) => !newValuesSet.has(v));
|
|
7910
|
-
if (removedValues.length > 0)
|
|
7933
|
+
if (removedValues.length > 0) breakingChanges.push({
|
|
7911
7934
|
typeName,
|
|
7912
7935
|
fieldName,
|
|
7913
7936
|
reason: `Enum values removed: ${removedValues.join(", ")}`
|
|
7914
|
-
};
|
|
7937
|
+
});
|
|
7915
7938
|
}
|
|
7916
|
-
return
|
|
7939
|
+
return breakingChanges;
|
|
7917
7940
|
}
|
|
7918
7941
|
function addChange(ctx, change, oldField, newField) {
|
|
7919
7942
|
ctx.changes.push(change);
|
|
7920
7943
|
if (!change.fieldName) return;
|
|
7921
|
-
const
|
|
7922
|
-
if (
|
|
7923
|
-
ctx.breakingChanges.push(
|
|
7944
|
+
const breakingChanges = getBreakingFieldChanges(change.typeName, change.fieldName, oldField, newField);
|
|
7945
|
+
if (breakingChanges.length > 0) {
|
|
7946
|
+
ctx.breakingChanges.push(...breakingChanges);
|
|
7924
7947
|
return;
|
|
7925
7948
|
}
|
|
7926
7949
|
if (change.kind === "field_removed") ctx.warnings.push({
|
|
@@ -7964,6 +7987,29 @@ function compareTypeFields(ctx, typeName, prevType, currType) {
|
|
|
7964
7987
|
}
|
|
7965
7988
|
}
|
|
7966
7989
|
/**
|
|
7990
|
+
* Determine if a type-level index change is breaking. Mirrors the field-level
|
|
7991
|
+
* unique reasoning: enforcing a unique constraint over existing rows can fail
|
|
7992
|
+
* on duplicates, so both adding a unique index and re-pointing an existing
|
|
7993
|
+
* unique index at a different field set require a data migration.
|
|
7994
|
+
* @param {string} typeName - Name of the type containing the index
|
|
7995
|
+
* @param {string} indexName - Name of the index being changed
|
|
7996
|
+
* @param {SnapshotIndexConfig | undefined} oldIndex - Old index configuration
|
|
7997
|
+
* @param {SnapshotIndexConfig | undefined} newIndex - New index configuration
|
|
7998
|
+
* @returns {BreakingChangeInfo | null} Breaking change info or null if not breaking
|
|
7999
|
+
*/
|
|
8000
|
+
function isBreakingIndexChange(typeName, indexName, oldIndex, newIndex) {
|
|
8001
|
+
if (!newIndex || !(newIndex.unique ?? false)) return null;
|
|
8002
|
+
if (!oldIndex || !(oldIndex.unique ?? false)) return {
|
|
8003
|
+
typeName,
|
|
8004
|
+
reason: `Unique constraint added to index "${indexName}"`
|
|
8005
|
+
};
|
|
8006
|
+
if (JSON.stringify(oldIndex.fields.toSorted()) !== JSON.stringify(newIndex.fields.toSorted())) return {
|
|
8007
|
+
typeName,
|
|
8008
|
+
reason: `Unique index fields changed on index "${indexName}"`
|
|
8009
|
+
};
|
|
8010
|
+
return null;
|
|
8011
|
+
}
|
|
8012
|
+
/**
|
|
7967
8013
|
* Compare type-level indexes
|
|
7968
8014
|
* @param {DiffContext} ctx - Diff context
|
|
7969
8015
|
* @param {string} typeName - Type name
|
|
@@ -7974,12 +8020,16 @@ function compareTypeFields(ctx, typeName, prevType, currType) {
|
|
|
7974
8020
|
function compareIndexes(ctx, typeName, oldIndexes, newIndexes) {
|
|
7975
8021
|
const oldKeys = new Set(Object.keys(oldIndexes || {}));
|
|
7976
8022
|
const newKeys = new Set(Object.keys(newIndexes || {}));
|
|
7977
|
-
for (const [indexName, indexConfig] of Object.entries(newIndexes ?? {})) if (!oldKeys.has(indexName))
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
8023
|
+
for (const [indexName, indexConfig] of Object.entries(newIndexes ?? {})) if (!oldKeys.has(indexName)) {
|
|
8024
|
+
ctx.changes.push({
|
|
8025
|
+
kind: "index_added",
|
|
8026
|
+
typeName,
|
|
8027
|
+
indexName,
|
|
8028
|
+
after: indexConfig
|
|
8029
|
+
});
|
|
8030
|
+
const breaking = isBreakingIndexChange(typeName, indexName, void 0, indexConfig);
|
|
8031
|
+
if (breaking) ctx.breakingChanges.push(breaking);
|
|
8032
|
+
}
|
|
7983
8033
|
for (const [indexName, indexConfig] of Object.entries(oldIndexes ?? {})) if (!newKeys.has(indexName)) ctx.changes.push({
|
|
7984
8034
|
kind: "index_removed",
|
|
7985
8035
|
typeName,
|
|
@@ -8002,6 +8052,8 @@ function compareIndexes(ctx, typeName, oldIndexes, newIndexes) {
|
|
|
8002
8052
|
before: oldIndex,
|
|
8003
8053
|
after: newIndex
|
|
8004
8054
|
});
|
|
8055
|
+
const breaking = isBreakingIndexChange(typeName, indexName, oldIndex, newIndex);
|
|
8056
|
+
if (breaking) ctx.breakingChanges.push(breaking);
|
|
8005
8057
|
}
|
|
8006
8058
|
}
|
|
8007
8059
|
}
|
|
@@ -9326,6 +9378,12 @@ function protoGqlOperand(operand) {
|
|
|
9326
9378
|
* - `field_modified` optional→required, unique constraint added, enum
|
|
9327
9379
|
* value removed: keep the looser side until Post-phase.
|
|
9328
9380
|
*
|
|
9381
|
+
* and the type-level index adjustments:
|
|
9382
|
+
*
|
|
9383
|
+
* - `index_added` with `unique: true`: withhold the index until Post-phase.
|
|
9384
|
+
* - `index_modified` that gains a unique constraint or re-points a unique
|
|
9385
|
+
* index at different fields: keep the previous definition until Post-phase.
|
|
9386
|
+
*
|
|
9329
9387
|
* Type-level deletions (`type_removed`) are handled by the deploy flow,
|
|
9330
9388
|
* which retains the type until Post-phase rather than via this module.
|
|
9331
9389
|
*
|
|
@@ -9407,6 +9465,45 @@ function applyPreMigrationFieldAdjustments(fields, typeChanges) {
|
|
|
9407
9465
|
}
|
|
9408
9466
|
}
|
|
9409
9467
|
}
|
|
9468
|
+
/**
|
|
9469
|
+
* Build a map of type-level index changes that require pre-migration schema
|
|
9470
|
+
* adjustment (the breaking ones — see {@link isBreakingIndexChange}).
|
|
9471
|
+
* @param {PendingMigration[]} pendingMigrations - Pending migrations to scan
|
|
9472
|
+
* @returns {PreMigrationIndexChangesMap} Map of changes keyed by typeName/indexName
|
|
9473
|
+
*/
|
|
9474
|
+
function buildPreMigrationIndexChangesMap(pendingMigrations) {
|
|
9475
|
+
const map = /* @__PURE__ */ new Map();
|
|
9476
|
+
for (const migration of pendingMigrations) for (const change of migration.diff.changes) {
|
|
9477
|
+
if (change.kind !== "index_added" && change.kind !== "index_modified") continue;
|
|
9478
|
+
const before = change.kind === "index_modified" ? change.before : void 0;
|
|
9479
|
+
if (!isBreakingIndexChange(change.typeName, change.indexName, before, change.after)) continue;
|
|
9480
|
+
const perType = map.get(change.typeName) ?? /* @__PURE__ */ new Map();
|
|
9481
|
+
perType.set(change.indexName, change);
|
|
9482
|
+
map.set(change.typeName, perType);
|
|
9483
|
+
}
|
|
9484
|
+
return map;
|
|
9485
|
+
}
|
|
9486
|
+
/**
|
|
9487
|
+
* Apply pre-migration schema adjustments to a type's index map in place.
|
|
9488
|
+
*
|
|
9489
|
+
* The indexes map is the proto-shape `TailorDBType.schema.indexes` that will
|
|
9490
|
+
* be sent in the Pre-phase. We mutate it so that:
|
|
9491
|
+
*
|
|
9492
|
+
* - Newly added unique indexes are withheld until Post-phase.
|
|
9493
|
+
* - Modified indexes keep their previous definition until Post-phase.
|
|
9494
|
+
*
|
|
9495
|
+
* @param {Record<string, MessageInitShape<typeof TailorDBType_IndexSchema>>} indexes - Index map to adjust (mutated in place)
|
|
9496
|
+
* @param {Map<string, IndexDiffChange>} typeIndexChanges - Changes for this type, keyed by indexName
|
|
9497
|
+
*/
|
|
9498
|
+
function applyPreMigrationIndexAdjustments(indexes, typeIndexChanges) {
|
|
9499
|
+
for (const [indexName, change] of typeIndexChanges) {
|
|
9500
|
+
if (change.kind === "index_added") {
|
|
9501
|
+
delete indexes[indexName];
|
|
9502
|
+
continue;
|
|
9503
|
+
}
|
|
9504
|
+
if (change.kind === "index_modified") indexes[indexName] = convertIndexToProto(change.before);
|
|
9505
|
+
}
|
|
9506
|
+
}
|
|
9410
9507
|
|
|
9411
9508
|
//#endregion
|
|
9412
9509
|
//#region src/cli/commands/tailordb/migrate/types.ts
|
|
@@ -9781,8 +9878,9 @@ async function getCurrentMigrationNumber(client, workspaceId, namespace) {
|
|
|
9781
9878
|
const label = metadata?.labels[MIGRATION_LABEL_KEY];
|
|
9782
9879
|
if (!label) return 0;
|
|
9783
9880
|
return parseMigrationLabelNumber(label) ?? 0;
|
|
9784
|
-
} catch {
|
|
9785
|
-
return 0;
|
|
9881
|
+
} catch (error) {
|
|
9882
|
+
if (isNotFoundError(error)) return 0;
|
|
9883
|
+
throw error;
|
|
9786
9884
|
}
|
|
9787
9885
|
}
|
|
9788
9886
|
/**
|
|
@@ -9790,9 +9888,10 @@ async function getCurrentMigrationNumber(client, workspaceId, namespace) {
|
|
|
9790
9888
|
* @param {OperatorClient} client - Operator client instance
|
|
9791
9889
|
* @param {string} workspaceId - Workspace ID
|
|
9792
9890
|
* @param {NamespaceWithMigrations[]} namespacesWithMigrations - Namespaces with migrations config
|
|
9891
|
+
* @param {string} [configPath] - Config file path, included in remediation guidance when provided
|
|
9793
9892
|
* @returns {Promise<PendingMigration[]>} List of pending migrations
|
|
9794
9893
|
*/
|
|
9795
|
-
async function detectPendingMigrations(client, workspaceId, namespacesWithMigrations) {
|
|
9894
|
+
async function detectPendingMigrations(client, workspaceId, namespacesWithMigrations, configPath) {
|
|
9796
9895
|
const pendingMigrations = [];
|
|
9797
9896
|
for (const { namespace, migrationsDir } of namespacesWithMigrations) {
|
|
9798
9897
|
const currentMigration = await getCurrentMigrationNumber(client, workspaceId, namespace);
|
|
@@ -9804,9 +9903,15 @@ async function detectPendingMigrations(client, workspaceId, namespacesWithMigrat
|
|
|
9804
9903
|
const diff = loadDiff(diffPath);
|
|
9805
9904
|
const scriptPath = getMigrationFilePath(migrationsDir, file.number, "migrate");
|
|
9806
9905
|
const hasScript = fs$1.existsSync(scriptPath);
|
|
9807
|
-
if (diff.requiresMigrationScript && !hasScript) {
|
|
9808
|
-
|
|
9809
|
-
|
|
9906
|
+
if (diff.requiresMigrationScript && !hasScript && !diff.scriptSkipped) {
|
|
9907
|
+
const configArg = configPath ? ` --config "${path.relative(process.cwd(), configPath) || configPath}"` : "";
|
|
9908
|
+
const scriptCmd = `tailor-sdk tailordb migration script ${file.number} --namespace ${namespace}${configArg}`;
|
|
9909
|
+
throw new Error(`Migration ${namespace}/${formatMigrationNumber(file.number)} requires a migration script but migrate.ts was not found.\nTo resolve, either:\n - Add a script: ${scriptCmd}\n - Or record that no script is needed: ${scriptCmd} --no-script --reason "<why no data migration is needed>"`);
|
|
9910
|
+
}
|
|
9911
|
+
if (diff.scriptSkipped) {
|
|
9912
|
+
const migrationLabel = `${namespace}/${formatMigrationNumber(file.number)}`;
|
|
9913
|
+
if (hasScript) logger.warn(`Migration ${migrationLabel} has both a skip acknowledgment and migrate.ts; executing migrate.ts.`);
|
|
9914
|
+
else logger.info(`Migration ${migrationLabel} runs without a script (skip acknowledged at ${diff.scriptSkipped.acknowledgedAt}: ${diff.scriptSkipped.reason})`);
|
|
9810
9915
|
}
|
|
9811
9916
|
pendingMigrations.push({
|
|
9812
9917
|
number: file.number,
|
|
@@ -10103,6 +10208,38 @@ function formatRemoteVerificationResults(results) {
|
|
|
10103
10208
|
}
|
|
10104
10209
|
return lines.join("\n");
|
|
10105
10210
|
}
|
|
10211
|
+
const MIGRATION_FILE_KINDS = [
|
|
10212
|
+
"schema",
|
|
10213
|
+
"diff",
|
|
10214
|
+
"migrate",
|
|
10215
|
+
"db"
|
|
10216
|
+
];
|
|
10217
|
+
/**
|
|
10218
|
+
* Capture the migration files that a deployment plan depends on.
|
|
10219
|
+
* @param namespacesWithMigrations - Configured migration directories by namespace
|
|
10220
|
+
* @returns SHA-256 digest by namespace
|
|
10221
|
+
*/
|
|
10222
|
+
function captureMigrationFileState(namespacesWithMigrations) {
|
|
10223
|
+
const state = {};
|
|
10224
|
+
for (const { namespace, migrationsDir } of namespacesWithMigrations.toSorted((a, b) => a.namespace.localeCompare(b.namespace))) {
|
|
10225
|
+
const hash = createHash("sha256");
|
|
10226
|
+
const migrationNumbers = [...new Set(getMigrationFiles(migrationsDir).map(({ number }) => number))].toSorted((a, b) => a - b);
|
|
10227
|
+
for (const migrationNumber of migrationNumbers) for (const kind of MIGRATION_FILE_KINDS) {
|
|
10228
|
+
const filePath = getMigrationFilePath(migrationsDir, migrationNumber, kind);
|
|
10229
|
+
hash.update(`${formatMigrationNumber(migrationNumber)}/${kind}\0`);
|
|
10230
|
+
if (fs$1.existsSync(filePath)) hash.update(fs$1.readFileSync(filePath));
|
|
10231
|
+
else hash.update("<missing>");
|
|
10232
|
+
hash.update("\0");
|
|
10233
|
+
}
|
|
10234
|
+
state[namespace] = hash.digest("hex");
|
|
10235
|
+
}
|
|
10236
|
+
return state;
|
|
10237
|
+
}
|
|
10238
|
+
function migrationFileStatesEqual(planned, current) {
|
|
10239
|
+
const plannedNamespaces = Object.keys(planned).toSorted();
|
|
10240
|
+
const currentNamespaces = Object.keys(current).toSorted();
|
|
10241
|
+
return plannedNamespaces.length === currentNamespaces.length && plannedNamespaces.every((namespace, index) => namespace === currentNamespaces[index] && planned[namespace] === current[namespace]);
|
|
10242
|
+
}
|
|
10106
10243
|
/**
|
|
10107
10244
|
* Validate migration files and detect pending migrations
|
|
10108
10245
|
* @param {OperatorClient} client - Operator client instance
|
|
@@ -10148,19 +10285,20 @@ async function validateAndDetectMigrations(client, workspaceId, typesByNamespace
|
|
|
10148
10285
|
throw new Error("Remote schema verification failed");
|
|
10149
10286
|
}
|
|
10150
10287
|
}
|
|
10151
|
-
pendingMigrations = await detectPendingMigrations(client, workspaceId, namespacesWithMigrations);
|
|
10288
|
+
pendingMigrations = await detectPendingMigrations(client, workspaceId, namespacesWithMigrations, config.path);
|
|
10152
10289
|
if (pendingMigrations.length > 0) {
|
|
10153
10290
|
logger.newline();
|
|
10154
10291
|
const withScripts = pendingMigrations.filter((m) => m.hasScript);
|
|
10155
10292
|
const withoutScripts = pendingMigrations.filter((m) => !m.hasScript);
|
|
10156
|
-
logger.info(
|
|
10293
|
+
logger.info(`${pendingMigrations.length} pending migration(s) will be applied:`);
|
|
10157
10294
|
if (withoutScripts.length > 0) logger.info(` • ${withoutScripts.length} schema change(s) (applied automatically with schema deployment)`, { mode: "plain" });
|
|
10158
10295
|
if (withScripts.length > 0) logger.info(` • ${withScripts.length} data migration(s) (requires migration script execution)`, { mode: "plain" });
|
|
10159
10296
|
}
|
|
10160
10297
|
}
|
|
10161
10298
|
return {
|
|
10162
10299
|
pendingMigrations,
|
|
10163
|
-
namespacesWithMigrations
|
|
10300
|
+
namespacesWithMigrations,
|
|
10301
|
+
migrationFileState: captureMigrationFileState(namespacesWithMigrations)
|
|
10164
10302
|
};
|
|
10165
10303
|
}
|
|
10166
10304
|
/**
|
|
@@ -10208,6 +10346,22 @@ function buildMigrationContextForScripts(client, migrationContext, migrationsReq
|
|
|
10208
10346
|
configDir: path.dirname(migrationContext.config.path)
|
|
10209
10347
|
};
|
|
10210
10348
|
}
|
|
10349
|
+
async function validateTailorDBMigrationState(client, result) {
|
|
10350
|
+
const { context } = result;
|
|
10351
|
+
const typesByNamespace = /* @__PURE__ */ new Map();
|
|
10352
|
+
for (const tailordb of context.tailorDBInputs) typesByNamespace.set(tailordb.namespace, tailordb.types);
|
|
10353
|
+
const validation = await validateAndDetectMigrations(client, context.workspaceId, typesByNamespace, context.config, context.noSchemaCheck, context.tailorDBInputs);
|
|
10354
|
+
if (!migrationFileStatesEqual(context.migrationFileState, validation.migrationFileState)) throw new Error("Migration files changed after deployment planning. Run the deployment again to create a fresh plan.");
|
|
10355
|
+
return validation;
|
|
10356
|
+
}
|
|
10357
|
+
/**
|
|
10358
|
+
* Revalidate migration state before the deployment enters any mutation phase.
|
|
10359
|
+
* @param client - Operator client instance
|
|
10360
|
+
* @param result - Planned TailorDB changes
|
|
10361
|
+
*/
|
|
10362
|
+
async function preflightTailorDB(client, result) {
|
|
10363
|
+
await validateTailorDBMigrationState(client, result);
|
|
10364
|
+
}
|
|
10211
10365
|
/**
|
|
10212
10366
|
* Apply TailorDB-related changes for the given phase.
|
|
10213
10367
|
* @param client - Operator client instance
|
|
@@ -10217,9 +10371,7 @@ function buildMigrationContextForScripts(client, migrationContext, migrationsReq
|
|
|
10217
10371
|
async function applyTailorDB(client, result, phase = "create-update") {
|
|
10218
10372
|
const { changeSet, context: migrationContext } = result;
|
|
10219
10373
|
if (phase === "create-update") {
|
|
10220
|
-
const
|
|
10221
|
-
for (const tailordb of migrationContext.tailorDBInputs) typesByNamespace.set(tailordb.namespace, tailordb.types);
|
|
10222
|
-
const { pendingMigrations, namespacesWithMigrations } = await validateAndDetectMigrations(client, migrationContext.workspaceId, typesByNamespace, migrationContext.config, migrationContext.noSchemaCheck, migrationContext.tailorDBInputs);
|
|
10374
|
+
const { pendingMigrations, namespacesWithMigrations } = await validateTailorDBMigrationState(client, result);
|
|
10223
10375
|
if (pendingMigrations.length > 0) {
|
|
10224
10376
|
processedTypes.reset();
|
|
10225
10377
|
deletedResources.reset();
|
|
@@ -10401,6 +10553,7 @@ async function awaitAllSettledOrThrow(promises) {
|
|
|
10401
10553
|
*/
|
|
10402
10554
|
async function executeSingleMigrationPrePhase(client, changeSet, migration, tailorDBInputs, executorUsedTypes) {
|
|
10403
10555
|
const preMigrationChanges = buildPreMigrationChangesMap([migration]);
|
|
10556
|
+
const preMigrationIndexChanges = buildPreMigrationIndexChangesMap([migration]);
|
|
10404
10557
|
const affectedTypes = getAffectedTypeNames(migration);
|
|
10405
10558
|
const createdBeforeMigration = new Set(processedTypes.created);
|
|
10406
10559
|
for (const create of changeSet.type.creates) {
|
|
@@ -10412,6 +10565,8 @@ async function executeSingleMigrationPrePhase(client, changeSet, migration, tail
|
|
|
10412
10565
|
clonedRequest.tailordbType = snapshotType;
|
|
10413
10566
|
const typeChanges = preMigrationChanges.get(typeName);
|
|
10414
10567
|
if (typeChanges && typeChanges.size > 0 && clonedRequest.tailordbType.schema?.fields) applyPreMigrationFieldAdjustments(clonedRequest.tailordbType.schema.fields, typeChanges);
|
|
10568
|
+
const indexChanges = preMigrationIndexChanges.get(typeName);
|
|
10569
|
+
if (indexChanges && indexChanges.size > 0 && clonedRequest.tailordbType.schema?.indexes) applyPreMigrationIndexAdjustments(clonedRequest.tailordbType.schema.indexes, indexChanges);
|
|
10415
10570
|
processedTypes.created.add(typeName);
|
|
10416
10571
|
await client.createTailorDBType(clonedRequest);
|
|
10417
10572
|
}
|
|
@@ -10423,6 +10578,8 @@ async function executeSingleMigrationPrePhase(client, changeSet, migration, tail
|
|
|
10423
10578
|
const clonedTypeRequest = structuredClone(snapshotType);
|
|
10424
10579
|
const typeChanges = preMigrationChanges.get(typeName);
|
|
10425
10580
|
if (typeChanges && typeChanges.size > 0 && clonedTypeRequest.schema?.fields) applyPreMigrationFieldAdjustments(clonedTypeRequest.schema.fields, typeChanges);
|
|
10581
|
+
const indexChanges = preMigrationIndexChanges.get(typeName);
|
|
10582
|
+
if (indexChanges && indexChanges.size > 0 && clonedTypeRequest.schema?.indexes) applyPreMigrationIndexAdjustments(clonedTypeRequest.schema.indexes, indexChanges);
|
|
10426
10583
|
processedTypes.updated.add(typeName);
|
|
10427
10584
|
await client.updateTailorDBType({
|
|
10428
10585
|
workspaceId: create.request.workspaceId,
|
|
@@ -10439,6 +10596,8 @@ async function executeSingleMigrationPrePhase(client, changeSet, migration, tail
|
|
|
10439
10596
|
clonedRequest.tailordbType = snapshotType;
|
|
10440
10597
|
const typeChanges = preMigrationChanges.get(typeName);
|
|
10441
10598
|
if (typeChanges && typeChanges.size > 0 && clonedRequest.tailordbType.schema?.fields) applyPreMigrationFieldAdjustments(clonedRequest.tailordbType.schema.fields, typeChanges);
|
|
10599
|
+
const indexChanges = preMigrationIndexChanges.get(typeName);
|
|
10600
|
+
if (indexChanges && indexChanges.size > 0 && clonedRequest.tailordbType.schema?.indexes) applyPreMigrationIndexAdjustments(clonedRequest.tailordbType.schema.indexes, indexChanges);
|
|
10442
10601
|
processedTypes.updated.add(typeName);
|
|
10443
10602
|
await client.updateTailorDBType(clonedRequest);
|
|
10444
10603
|
}
|
|
@@ -10481,12 +10640,14 @@ const deletedResources = {
|
|
|
10481
10640
|
*/
|
|
10482
10641
|
async function executeSingleMigrationPostPhase(client, changeSet, migration, tailorDBInputs, executorUsedTypes) {
|
|
10483
10642
|
const preMigrationChanges = buildPreMigrationChangesMap([migration]);
|
|
10643
|
+
const preMigrationIndexChanges = buildPreMigrationIndexChangesMap([migration]);
|
|
10644
|
+
const adjustedTypes = /* @__PURE__ */ new Set([...preMigrationChanges.keys(), ...preMigrationIndexChanges.keys()]);
|
|
10484
10645
|
const affectedTypes = getAffectedTypeNames(migration);
|
|
10485
10646
|
const deletedTypeNames = getDeletedTypeNames(migration);
|
|
10486
10647
|
try {
|
|
10487
10648
|
for (const create of changeSet.type.creates) {
|
|
10488
10649
|
const typeName = create.request.tailordbType?.name;
|
|
10489
|
-
if (!typeName || !affectedTypes.has(typeName) || !
|
|
10650
|
+
if (!typeName || !affectedTypes.has(typeName) || !adjustedTypes.has(typeName)) continue;
|
|
10490
10651
|
const snapshotType = buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes);
|
|
10491
10652
|
if (!snapshotType) continue;
|
|
10492
10653
|
await client.updateTailorDBType({
|
|
@@ -10497,7 +10658,7 @@ async function executeSingleMigrationPostPhase(client, changeSet, migration, tai
|
|
|
10497
10658
|
}
|
|
10498
10659
|
for (const update of changeSet.type.updates) {
|
|
10499
10660
|
const typeName = update.request.tailordbType?.name;
|
|
10500
|
-
if (!typeName || !affectedTypes.has(typeName) || !
|
|
10661
|
+
if (!typeName || !affectedTypes.has(typeName) || !adjustedTypes.has(typeName)) continue;
|
|
10501
10662
|
const snapshotType = buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes);
|
|
10502
10663
|
if (!snapshotType) continue;
|
|
10503
10664
|
await client.updateTailorDBType({
|
|
@@ -10618,6 +10779,12 @@ async function planTailorDB(context) {
|
|
|
10618
10779
|
const executors = forRemoval ? [] : Object.values(await application.executorService?.loadExecutors() ?? {});
|
|
10619
10780
|
const executorUsedTypes = new Set(context.executorUsedTailorDBTypes ?? []);
|
|
10620
10781
|
for (const executor of executors) if (executor.trigger.kind === "tailordb") executorUsedTypes.add(executor.trigger.typeName);
|
|
10782
|
+
const typesByNamespace = /* @__PURE__ */ new Map();
|
|
10783
|
+
for (const tailordb of tailordbs) typesByNamespace.set(tailordb.namespace, tailordb.types);
|
|
10784
|
+
const { namespacesWithMigrations, migrationFileState } = forRemoval ? {
|
|
10785
|
+
namespacesWithMigrations: [],
|
|
10786
|
+
migrationFileState: {}
|
|
10787
|
+
} : await validateAndDetectMigrations(client, workspaceId, typesByNamespace, config, noSchemaCheck ?? false, tailordbs);
|
|
10621
10788
|
const { changeSet: serviceChangeSet, conflicts, unmanaged, resourceOwners } = await planServices(client, workspaceId, application.name, application.id, tailordbs);
|
|
10622
10789
|
const deletedServices = serviceChangeSet.deletes.map((del) => del.name);
|
|
10623
10790
|
const [typeChangeSet, gqlPermissionChangeSet] = await Promise.all([planTypes(client, workspaceId, tailordbs, executorUsedTypes, deletedServices, void 0, forceApplyAll), planGqlPermissions(client, workspaceId, tailordbs, deletedServices, forceApplyAll)]);
|
|
@@ -10639,7 +10806,9 @@ async function planTailorDB(context) {
|
|
|
10639
10806
|
tailorDBInputs: tailordbs,
|
|
10640
10807
|
executorUsedTypes,
|
|
10641
10808
|
config,
|
|
10642
|
-
noSchemaCheck: noSchemaCheck ?? false
|
|
10809
|
+
noSchemaCheck: noSchemaCheck ?? false,
|
|
10810
|
+
namespacesWithMigrations,
|
|
10811
|
+
migrationFileState
|
|
10643
10812
|
}
|
|
10644
10813
|
};
|
|
10645
10814
|
}
|
|
@@ -11051,7 +11220,7 @@ function formatMigrationCheckResults(results) {
|
|
|
11051
11220
|
async function applyWorkflow(client, result, phase = "create-update") {
|
|
11052
11221
|
const { changeSet, appName, appId } = result;
|
|
11053
11222
|
if (phase === "create-update") {
|
|
11054
|
-
const jobFunctionVersions = await registerJobFunctions(client, changeSet, appName, appId, result.unchangedWorkflowJobNames);
|
|
11223
|
+
const jobFunctionVersions = await registerJobFunctions(client, changeSet, appName, appId, result.unchangedWorkflowJobNames, result.jobFunctionPublishEvents);
|
|
11055
11224
|
await Promise.all([...changeSet.creates.map(async (create) => {
|
|
11056
11225
|
const filteredVersions = filterJobFunctionVersions(jobFunctionVersions, create.usedJobNames);
|
|
11057
11226
|
const shape = buildWorkflowValidationShape(create.workspaceId, create.workflow);
|
|
@@ -11061,7 +11230,8 @@ async function applyWorkflow(client, result, phase = "create-update") {
|
|
|
11061
11230
|
mainJobFunctionName: shape.mainJobFunctionName,
|
|
11062
11231
|
retryPolicy: shape.retryPolicy,
|
|
11063
11232
|
concurrencyPolicy: shape.concurrencyPolicy,
|
|
11064
|
-
jobFunctions: filteredVersions
|
|
11233
|
+
jobFunctions: filteredVersions,
|
|
11234
|
+
publishExecutionEvents: shape.publishExecutionEvents
|
|
11065
11235
|
});
|
|
11066
11236
|
await client.setMetadata(create.metaRequest);
|
|
11067
11237
|
}), ...changeSet.updates.map(async (update) => {
|
|
@@ -11073,7 +11243,8 @@ async function applyWorkflow(client, result, phase = "create-update") {
|
|
|
11073
11243
|
mainJobFunctionName: shape.mainJobFunctionName,
|
|
11074
11244
|
retryPolicy: shape.retryPolicy,
|
|
11075
11245
|
concurrencyPolicy: shape.concurrencyPolicy,
|
|
11076
|
-
jobFunctions: filteredVersions
|
|
11246
|
+
jobFunctions: filteredVersions,
|
|
11247
|
+
publishExecutionEvents: shape.publishExecutionEvents
|
|
11077
11248
|
});
|
|
11078
11249
|
await client.setMetadata(update.metaRequest);
|
|
11079
11250
|
})]);
|
|
@@ -11134,9 +11305,10 @@ function filterJobFunctionVersions(allVersions, usedJobNames) {
|
|
|
11134
11305
|
* @param appName - Application name
|
|
11135
11306
|
* @param appId - Application ID used for job function metadata when available
|
|
11136
11307
|
* @param unchangedWorkflowJobNames - Job function names used by unchanged workflows
|
|
11308
|
+
* @param jobFunctionPublishEvents - Resolved `publishExecutionEvents` keyed by job function name
|
|
11137
11309
|
* @returns Map of job function names to versions
|
|
11138
11310
|
*/
|
|
11139
|
-
async function registerJobFunctions(client, changeSet, appName, appId, unchangedWorkflowJobNames = /* @__PURE__ */ new Set()) {
|
|
11311
|
+
async function registerJobFunctions(client, changeSet, appName, appId, unchangedWorkflowJobNames = /* @__PURE__ */ new Set(), jobFunctionPublishEvents = /* @__PURE__ */ new Map()) {
|
|
11140
11312
|
const jobFunctionVersions = {};
|
|
11141
11313
|
const firstWorkflow = changeSet.creates[0] || changeSet.updates[0] || changeSet.deletes[0];
|
|
11142
11314
|
if (!firstWorkflow) return jobFunctionVersions;
|
|
@@ -11155,15 +11327,14 @@ async function registerJobFunctions(client, changeSet, appName, appId, unchanged
|
|
|
11155
11327
|
const existingJobNamesSet = new Set(existingJobFunctions);
|
|
11156
11328
|
if (changeSet.creates.length > 0 || changeSet.updates.length > 0) {
|
|
11157
11329
|
const results = await Promise.all(Array.from(allUsedJobNames).map(async (jobName) => {
|
|
11158
|
-
const
|
|
11159
|
-
|
|
11160
|
-
jobFunctionName: jobName,
|
|
11161
|
-
scriptRef: workflowJobFunctionName(jobName)
|
|
11162
|
-
}) : await client.createWorkflowJobFunction({
|
|
11330
|
+
const isExisting = existingJobNamesSet.has(jobName);
|
|
11331
|
+
const request = {
|
|
11163
11332
|
workspaceId,
|
|
11164
11333
|
jobFunctionName: jobName,
|
|
11165
|
-
scriptRef: workflowJobFunctionName(jobName)
|
|
11166
|
-
|
|
11334
|
+
scriptRef: workflowJobFunctionName(jobName),
|
|
11335
|
+
publishExecutionEvents: jobFunctionPublishEvents.get(jobName) ?? false
|
|
11336
|
+
};
|
|
11337
|
+
const response = isExisting ? await client.updateWorkflowJobFunction(request) : await client.createWorkflowJobFunction(request);
|
|
11167
11338
|
await client.setMetadata(await buildMetaRequest({
|
|
11168
11339
|
trn: resourceTrn(workspaceId, "workflow_job_function", jobName),
|
|
11169
11340
|
appName,
|
|
@@ -11210,9 +11381,64 @@ function buildWorkflowValidationShape(workspaceId, workflow) {
|
|
|
11210
11381
|
workflowName: workflow.name,
|
|
11211
11382
|
mainJobFunctionName: workflow.mainJob.name,
|
|
11212
11383
|
...workflow.retryPolicy && { retryPolicy: toRetryPolicy(workflow.retryPolicy) },
|
|
11213
|
-
...workflow.concurrencyPolicy && { concurrencyPolicy: toConcurrencyPolicy(workflow.concurrencyPolicy) }
|
|
11384
|
+
...workflow.concurrencyPolicy && { concurrencyPolicy: toConcurrencyPolicy(workflow.concurrencyPolicy) },
|
|
11385
|
+
publishExecutionEvents: workflow.publishEvents ?? false
|
|
11214
11386
|
};
|
|
11215
11387
|
}
|
|
11388
|
+
const NO_EVENT_SUBSCRIBERS = { workflowNames: /* @__PURE__ */ new Set() };
|
|
11389
|
+
function isSubscribed(subscribers, workflowName) {
|
|
11390
|
+
return subscribers.workflowNames.has(workflowName);
|
|
11391
|
+
}
|
|
11392
|
+
function resolvePublishEvents(params) {
|
|
11393
|
+
const { explicit, subscribed, remote, conflictError } = params;
|
|
11394
|
+
if (explicit === false && subscribed) throw new Error(conflictError);
|
|
11395
|
+
if (explicit !== void 0) return explicit;
|
|
11396
|
+
return subscribed || (remote ?? false);
|
|
11397
|
+
}
|
|
11398
|
+
/**
|
|
11399
|
+
* Resolve `publishExecutionEvents` for every job function used by a workflow.
|
|
11400
|
+
*
|
|
11401
|
+
* A job execution trigger names a workflow rather than a job, so a subscription
|
|
11402
|
+
* opts in every job that workflow runs.
|
|
11403
|
+
* @param params - Workflows, their job dependencies, subscribers, explicit job flags, and existing job functions
|
|
11404
|
+
* @returns Resolved flags keyed by job function name
|
|
11405
|
+
*/
|
|
11406
|
+
function resolveJobPublishEvents(params) {
|
|
11407
|
+
const { workflows, mainJobDeps, subscribers, explicit, existing } = params;
|
|
11408
|
+
const usedJobNames = /* @__PURE__ */ new Set();
|
|
11409
|
+
const subscribedJobNames = /* @__PURE__ */ new Set();
|
|
11410
|
+
for (const workflow of Object.values(workflows)) {
|
|
11411
|
+
const jobNames = mainJobDeps[workflow.mainJob.name];
|
|
11412
|
+
if (!jobNames) continue;
|
|
11413
|
+
const subscribed = isSubscribed(subscribers, workflow.name);
|
|
11414
|
+
for (const jobName of jobNames) {
|
|
11415
|
+
usedJobNames.add(jobName);
|
|
11416
|
+
if (subscribed) subscribedJobNames.add(jobName);
|
|
11417
|
+
}
|
|
11418
|
+
}
|
|
11419
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
11420
|
+
for (const jobName of usedJobNames) resolved.set(jobName, resolvePublishEvents({
|
|
11421
|
+
explicit: explicit.get(jobName),
|
|
11422
|
+
subscribed: subscribedJobNames.has(jobName),
|
|
11423
|
+
remote: existing.get(jobName)?.publishExecutionEvents,
|
|
11424
|
+
conflictError: `Job "${jobName}" has "publishEvents: false", but executors with a workflowJobExecution trigger subscribe to a workflow that runs it. Either remove "publishEvents: false" or remove the matching executor triggers.`
|
|
11425
|
+
}));
|
|
11426
|
+
return resolved;
|
|
11427
|
+
}
|
|
11428
|
+
/**
|
|
11429
|
+
* Collect job functions whose remote publishing flag no longer matches the plan.
|
|
11430
|
+
* @param existing - Existing job functions keyed by name
|
|
11431
|
+
* @param resolved - Resolved `publishExecutionEvents` keyed by job function name
|
|
11432
|
+
* @returns Job function names needing re-registration
|
|
11433
|
+
*/
|
|
11434
|
+
function collectStaleJobFunctionNames(existing, resolved) {
|
|
11435
|
+
const stale = /* @__PURE__ */ new Set();
|
|
11436
|
+
for (const [jobName, publishEvents] of resolved) {
|
|
11437
|
+
const remote = existing.get(jobName);
|
|
11438
|
+
if (remote && remote.publishExecutionEvents !== publishEvents) stale.add(jobName);
|
|
11439
|
+
}
|
|
11440
|
+
return stale;
|
|
11441
|
+
}
|
|
11216
11442
|
/**
|
|
11217
11443
|
* Plan workflow changes and job functions based on current and desired state.
|
|
11218
11444
|
* @param client - Operator client instance
|
|
@@ -11222,15 +11448,26 @@ function buildWorkflowValidationShape(workspaceId, workflow) {
|
|
|
11222
11448
|
* @param workflows - Parsed workflows
|
|
11223
11449
|
* @param mainJobDeps - Main job dependencies by workflow
|
|
11224
11450
|
* @param unchangedJobFunctions - Job functions already proven unchanged by function registry plan
|
|
11451
|
+
* @param eventPublishing - Executor subscriptions and explicit job flags driving execution event publishing
|
|
11225
11452
|
* @returns Planned workflow changes
|
|
11226
11453
|
*/
|
|
11227
|
-
async function planWorkflow(client, workspaceId, appName, appId, workflows, mainJobDeps, unchangedJobFunctions = /* @__PURE__ */ new Set()) {
|
|
11454
|
+
async function planWorkflow(client, workspaceId, appName, appId, workflows, mainJobDeps, unchangedJobFunctions = /* @__PURE__ */ new Set(), eventPublishing = {}) {
|
|
11228
11455
|
const changeSet = createChangeSet("Workflows");
|
|
11229
11456
|
const conflicts = [];
|
|
11230
11457
|
const unmanaged = [];
|
|
11231
11458
|
const resourceOwners = /* @__PURE__ */ new Set();
|
|
11232
11459
|
const unchangedWorkflowJobNames = /* @__PURE__ */ new Set();
|
|
11233
11460
|
const retainedWorkflowJobNames = /* @__PURE__ */ new Set();
|
|
11461
|
+
const executionSubscribers = eventPublishing.execution ?? NO_EVENT_SUBSCRIBERS;
|
|
11462
|
+
const existingJobFunctions = await fetchExistingJobFunctions(client, workspaceId);
|
|
11463
|
+
const jobFunctionPublishEvents = resolveJobPublishEvents({
|
|
11464
|
+
workflows,
|
|
11465
|
+
mainJobDeps,
|
|
11466
|
+
subscribers: eventPublishing.jobExecution ?? NO_EVENT_SUBSCRIBERS,
|
|
11467
|
+
explicit: eventPublishing.jobPublishEvents ?? /* @__PURE__ */ new Map(),
|
|
11468
|
+
existing: existingJobFunctions
|
|
11469
|
+
});
|
|
11470
|
+
const staleJobFunctionNames = collectStaleJobFunctionNames(existingJobFunctions, jobFunctionPublishEvents);
|
|
11234
11471
|
const existingWorkflows = await fetchExistingResourcesWithLabels({
|
|
11235
11472
|
client,
|
|
11236
11473
|
fetchPage: async (pageToken, pageSize) => {
|
|
@@ -11254,6 +11491,15 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
|
|
|
11254
11491
|
const usedJobNames = mainJobDeps[workflow.mainJob.name];
|
|
11255
11492
|
if (!usedJobNames) throw new Error(`Job "${workflow.mainJob.name}" (mainJob of workflow "${workflow.name}") was not found.\n\nPossible causes:\n - The job is not exported as a named export\n - The file containing the job is not included in workflow.files glob pattern\n\nSolution:\n export const ${workflow.mainJob.name} = createWorkflowJob({ name: "${workflow.mainJob.name}", ... })`);
|
|
11256
11493
|
usedJobNames.forEach((jobName) => retainedWorkflowJobNames.add(jobName));
|
|
11494
|
+
const desiredWorkflow = {
|
|
11495
|
+
...workflow,
|
|
11496
|
+
publishEvents: resolvePublishEvents({
|
|
11497
|
+
explicit: workflow.publishEvents,
|
|
11498
|
+
subscribed: isSubscribed(executionSubscribers, workflow.name),
|
|
11499
|
+
remote: existing?.resource.publishExecutionEvents,
|
|
11500
|
+
conflictError: `Workflow "${workflow.name}" has "publishEvents: false", but executors with a workflowExecution trigger subscribe to it. Either remove "publishEvents: false" or remove the matching executor triggers.`
|
|
11501
|
+
})
|
|
11502
|
+
};
|
|
11257
11503
|
if (existing) {
|
|
11258
11504
|
if (trackDesiredResourceOwnership({
|
|
11259
11505
|
labels: existing.allLabels,
|
|
@@ -11264,13 +11510,19 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
|
|
|
11264
11510
|
resourceName: workflow.name,
|
|
11265
11511
|
conflicts,
|
|
11266
11512
|
unmanaged
|
|
11267
|
-
}) && hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) && canTreatWorkflowAsUnchanged(
|
|
11513
|
+
}) && hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) && canTreatWorkflowAsUnchanged({
|
|
11514
|
+
existing: existing.resource,
|
|
11515
|
+
workflow: desiredWorkflow,
|
|
11516
|
+
usedJobNames,
|
|
11517
|
+
unchangedJobFunctions,
|
|
11518
|
+
staleJobFunctionNames
|
|
11519
|
+
})) {
|
|
11268
11520
|
changeSet.unchanged.push({ name: workflow.name });
|
|
11269
11521
|
for (const jobName of usedJobNames) unchangedWorkflowJobNames.add(jobName);
|
|
11270
11522
|
} else changeSet.updates.push({
|
|
11271
11523
|
name: workflow.name,
|
|
11272
11524
|
workspaceId,
|
|
11273
|
-
workflow,
|
|
11525
|
+
workflow: desiredWorkflow,
|
|
11274
11526
|
usedJobNames,
|
|
11275
11527
|
metaRequest
|
|
11276
11528
|
});
|
|
@@ -11278,7 +11530,7 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
|
|
|
11278
11530
|
} else changeSet.creates.push({
|
|
11279
11531
|
name: workflow.name,
|
|
11280
11532
|
workspaceId,
|
|
11281
|
-
workflow,
|
|
11533
|
+
workflow: desiredWorkflow,
|
|
11282
11534
|
usedJobNames,
|
|
11283
11535
|
metaRequest
|
|
11284
11536
|
});
|
|
@@ -11308,6 +11560,7 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
|
|
|
11308
11560
|
workspaceId,
|
|
11309
11561
|
appName,
|
|
11310
11562
|
appId,
|
|
11563
|
+
existingJobFunctionNames: [...existingJobFunctions.keys()],
|
|
11311
11564
|
retainedWorkflowJobNames
|
|
11312
11565
|
});
|
|
11313
11566
|
const deletableJobNames = new Set(jobFunctionDeletes.map((del) => del.jobFunctionName));
|
|
@@ -11323,20 +11576,24 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
|
|
|
11323
11576
|
appName,
|
|
11324
11577
|
appId,
|
|
11325
11578
|
unchangedWorkflowJobNames,
|
|
11326
|
-
jobFunctionDeletes
|
|
11579
|
+
jobFunctionDeletes,
|
|
11580
|
+
jobFunctionPublishEvents
|
|
11327
11581
|
};
|
|
11328
11582
|
}
|
|
11329
|
-
async function
|
|
11330
|
-
const
|
|
11331
|
-
const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
|
|
11583
|
+
async function fetchExistingJobFunctions(client, workspaceId) {
|
|
11584
|
+
const jobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
|
|
11332
11585
|
const response = await client.listWorkflowJobFunctions({
|
|
11333
11586
|
workspaceId,
|
|
11334
11587
|
pageToken,
|
|
11335
11588
|
pageSize: maxPageSize
|
|
11336
11589
|
});
|
|
11337
|
-
return [response.jobFunctions
|
|
11590
|
+
return [response.jobFunctions, response.nextPageToken];
|
|
11338
11591
|
});
|
|
11339
|
-
|
|
11592
|
+
return new Map(jobFunctions.map((jobFunction) => [jobFunction.name, jobFunction]));
|
|
11593
|
+
}
|
|
11594
|
+
async function planWorkflowJobFunctionDeletes(params) {
|
|
11595
|
+
const { client, workspaceId, appName, appId, existingJobFunctionNames, retainedWorkflowJobNames } = params;
|
|
11596
|
+
const candidates = existingJobFunctionNames.filter((jobName) => !retainedWorkflowJobNames.has(jobName));
|
|
11340
11597
|
return (await Promise.all(candidates.map(async (jobFunctionName) => {
|
|
11341
11598
|
const { metadata } = await client.getMetadata({ trn: resourceTrn(workspaceId, "workflow_job_function", jobFunctionName) });
|
|
11342
11599
|
return isOwnedByApp(metadata?.labels, appName, appId) ? {
|
|
@@ -11354,12 +11611,14 @@ async function planWorkflowJobFunctionDeletes(params) {
|
|
|
11354
11611
|
function formatWorkflowChangeEntries(changeSet, workflowJobFunctionChanges) {
|
|
11355
11612
|
return formatChangeEntriesWithFunctionRegistry("workflow", changeSet, workflowJobFunctionChanges, (item) => "usedJobNames" in item ? item.usedJobNames.map((jobName) => workflowJobFunctionName(jobName)) : []);
|
|
11356
11613
|
}
|
|
11357
|
-
function canTreatWorkflowAsUnchanged(
|
|
11614
|
+
function canTreatWorkflowAsUnchanged(params) {
|
|
11615
|
+
const { existing, workflow, usedJobNames, unchangedJobFunctions, staleJobFunctionNames } = params;
|
|
11358
11616
|
if (!usedJobNames.every((jobName) => unchangedJobFunctions.has(jobName))) return false;
|
|
11617
|
+
if (usedJobNames.some((jobName) => staleJobFunctionNames.has(jobName))) return false;
|
|
11359
11618
|
return areWorkflowsEqual(existing, workflow, usedJobNames);
|
|
11360
11619
|
}
|
|
11361
11620
|
function areWorkflowsEqual(existing, workflow, usedJobNames) {
|
|
11362
|
-
return existing.mainJobFunctionName === workflow.mainJob.name && areNormalizedEqual(normalizeComparableExistingWorkflowRetryPolicy(existing.retryPolicy), normalizeComparableWorkflowRetryPolicy(workflow.retryPolicy)) && areNormalizedEqual(normalizeComparableConcurrencyPolicy(existing.concurrencyPolicy), normalizeComparableConcurrencyPolicy(workflow.concurrencyPolicy)) && areNormalizedEqual(normalizeComparableWorkflowJobNames(existing.jobFunctions), normalizeComparableWorkflowJobNames(usedJobNames));
|
|
11621
|
+
return existing.mainJobFunctionName === workflow.mainJob.name && (existing.publishExecutionEvents ?? false) === (workflow.publishEvents ?? false) && areNormalizedEqual(normalizeComparableExistingWorkflowRetryPolicy(existing.retryPolicy), normalizeComparableWorkflowRetryPolicy(workflow.retryPolicy)) && areNormalizedEqual(normalizeComparableConcurrencyPolicy(existing.concurrencyPolicy), normalizeComparableConcurrencyPolicy(workflow.concurrencyPolicy)) && areNormalizedEqual(normalizeComparableWorkflowJobNames(existing.jobFunctions), normalizeComparableWorkflowJobNames(usedJobNames));
|
|
11363
11622
|
}
|
|
11364
11623
|
function normalizeComparableExistingWorkflowRetryPolicy(policy) {
|
|
11365
11624
|
if (!policy) return;
|
|
@@ -11616,6 +11875,9 @@ async function applyDeploymentPlans(client, workspaceId, deployments) {
|
|
|
11616
11875
|
const forEachDeployment = async (apply) => {
|
|
11617
11876
|
for (const deployment of deployments) await apply(deployment);
|
|
11618
11877
|
};
|
|
11878
|
+
await withSpan("apply.preflight", async () => {
|
|
11879
|
+
await forEachDeployment((d) => preflightTailorDB(client, d.tailorDB));
|
|
11880
|
+
});
|
|
11619
11881
|
await withSpan("apply.createUpdateServices", async () => {
|
|
11620
11882
|
await forEachDeployment((d) => applySecretManager(client, d.secretManager, "create-update", d.application));
|
|
11621
11883
|
await forEachDeployment((d) => applyFunctionRegistry(client, workspaceId, d.functionRegistry, "create-update"));
|
|
@@ -13054,6 +13316,39 @@ function collectExecutorUsedResolvers(owner, targets) {
|
|
|
13054
13316
|
}
|
|
13055
13317
|
return usedResolvers;
|
|
13056
13318
|
}
|
|
13319
|
+
/**
|
|
13320
|
+
* Resolve which workflows this target's executors subscribe to, per event
|
|
13321
|
+
* granularity level.
|
|
13322
|
+
*
|
|
13323
|
+
* Scoped to the owning target: unlike TailorDB, Auth and IdP, a workflow has no
|
|
13324
|
+
* `external` declaration, so no supported configuration shares a workflow and a
|
|
13325
|
+
* subscribing executor across configs.
|
|
13326
|
+
* @param target - Deployment target being planned
|
|
13327
|
+
* @returns Subscribers keyed by event granularity level
|
|
13328
|
+
*/
|
|
13329
|
+
function collectWorkflowEventSubscribers(target) {
|
|
13330
|
+
const execution = { workflowNames: /* @__PURE__ */ new Set() };
|
|
13331
|
+
const jobExecution = { workflowNames: /* @__PURE__ */ new Set() };
|
|
13332
|
+
for (const executor of Object.values(target.application.executorService?.executors ?? {})) {
|
|
13333
|
+
const { trigger } = executor;
|
|
13334
|
+
if (trigger.kind !== "workflowExecution" && trigger.kind !== "workflowJobExecution") continue;
|
|
13335
|
+
(trigger.kind === "workflowExecution" ? execution : jobExecution).workflowNames.add(trigger.workflowName);
|
|
13336
|
+
}
|
|
13337
|
+
return {
|
|
13338
|
+
execution,
|
|
13339
|
+
jobExecution
|
|
13340
|
+
};
|
|
13341
|
+
}
|
|
13342
|
+
/**
|
|
13343
|
+
* Collect explicit `publishEvents` values declared on this target's workflow jobs.
|
|
13344
|
+
* @param target - Deployment target being planned
|
|
13345
|
+
* @returns Explicit flags keyed by job name
|
|
13346
|
+
*/
|
|
13347
|
+
function collectWorkflowJobPublishEvents(target) {
|
|
13348
|
+
const jobPublishEvents = /* @__PURE__ */ new Map();
|
|
13349
|
+
for (const job of target.application.workflowService?.jobs ?? []) if (job.publishEvents !== void 0) jobPublishEvents.set(job.name, job.publishEvents);
|
|
13350
|
+
return jobPublishEvents;
|
|
13351
|
+
}
|
|
13057
13352
|
function collectExpectedLocalStaticWebsiteNames(targets) {
|
|
13058
13353
|
const websiteNames = /* @__PURE__ */ new Set();
|
|
13059
13354
|
for (const target of targets) for (const website of target.application.staticWebsiteServices) websiteNames.add(website.name);
|
|
@@ -13655,7 +13950,10 @@ async function planDeploymentTarget(params) {
|
|
|
13655
13950
|
withSpan("plan.pipeline", () => planPipeline(ctx)),
|
|
13656
13951
|
withSpan("plan.application", () => planApplication(ctx, httpAdapterBuildResult)),
|
|
13657
13952
|
withSpan("plan.executor", () => planExecutor(ctx)),
|
|
13658
|
-
withSpan("plan.workflow", () => planWorkflow(client, workspaceId, application.name, application.id, workflowService?.workflows ?? {}, workflowBuildResult?.mainJobDeps ?? {}, unchangedWorkflowJobs
|
|
13953
|
+
withSpan("plan.workflow", () => planWorkflow(client, workspaceId, application.name, application.id, workflowService?.workflows ?? {}, workflowBuildResult?.mainJobDeps ?? {}, unchangedWorkflowJobs, {
|
|
13954
|
+
...collectWorkflowEventSubscribers(target),
|
|
13955
|
+
jobPublishEvents: collectWorkflowJobPublishEvents(target)
|
|
13956
|
+
})),
|
|
13659
13957
|
withSpan("plan.workflowExecutionPolicy", () => planWorkflowJobFunctionExecutionPolicy(client, workspaceId, application.name, application.id, config.workflow?.executionPolicies ?? {})),
|
|
13660
13958
|
withSpan("plan.secretManager", () => planSecretManager(ctx))
|
|
13661
13959
|
]);
|
|
@@ -14470,6 +14768,12 @@ function formatEventTriggerConfig(config) {
|
|
|
14470
14768
|
eventType: config.eventType,
|
|
14471
14769
|
condition: config.condition?.expr || ""
|
|
14472
14770
|
};
|
|
14771
|
+
if (typedConfig.case === "workflow") return {
|
|
14772
|
+
kind: typedConfig.case,
|
|
14773
|
+
eventTypes: typedConfig.value.eventTypes,
|
|
14774
|
+
condition: typedConfig.value.condition?.expr || "",
|
|
14775
|
+
...typedConfig.value.workflowName && { workflowName: typedConfig.value.workflowName }
|
|
14776
|
+
};
|
|
14473
14777
|
const base = {
|
|
14474
14778
|
kind: typedConfig.case,
|
|
14475
14779
|
eventTypes: typedConfig.value.eventTypes,
|
|
@@ -18777,8 +19081,13 @@ async function generateDiffFiles(diff, migrationsDir, migrationNumber, previousS
|
|
|
18777
19081
|
function generateMigrationScript(diff) {
|
|
18778
19082
|
const updates = [];
|
|
18779
19083
|
for (const change of diff.changes) {
|
|
18780
|
-
const
|
|
18781
|
-
|
|
19084
|
+
const decimalScaleScript = generateDecimalScaleChangeScript(change);
|
|
19085
|
+
updates.push(...generateChangeScripts(change, decimalScaleScript !== null));
|
|
19086
|
+
if (decimalScaleScript) {
|
|
19087
|
+
updates.push(decimalScaleScript);
|
|
19088
|
+
const uniqueConstraintScript = generateUniqueConstraintScript(change);
|
|
19089
|
+
if (uniqueConstraintScript) updates.push(uniqueConstraintScript);
|
|
19090
|
+
}
|
|
18782
19091
|
}
|
|
18783
19092
|
if (updates.length === 0) updates.push(` // No data migration needed for this schema change
|
|
18784
19093
|
// Add custom data transformations if required`);
|
|
@@ -18803,84 +19112,170 @@ ${updates.join("\n\n")}
|
|
|
18803
19112
|
`;
|
|
18804
19113
|
}
|
|
18805
19114
|
/**
|
|
18806
|
-
* Generate
|
|
19115
|
+
* Generate scripts for a single change
|
|
18807
19116
|
* @param {DiffChange} change - Diff change to generate script for
|
|
18808
|
-
* @
|
|
18809
|
-
|
|
18810
|
-
|
|
19117
|
+
* @param {boolean} deferUniqueConstraint - Generate the unique check after decimal re-serialization
|
|
19118
|
+
* @returns {string[]} Script contents, or an empty array if no script is needed
|
|
19119
|
+
*/
|
|
19120
|
+
function generateChangeScripts(change, deferUniqueConstraint = false) {
|
|
19121
|
+
if (change.kind === "index_added" || change.kind === "index_modified") {
|
|
19122
|
+
const before = change.kind === "index_modified" ? change.before : void 0;
|
|
19123
|
+
if (!isBreakingIndexChange(change.typeName, change.indexName, before, change.after)) return [];
|
|
19124
|
+
const fields = change.after.fields;
|
|
19125
|
+
const fieldList = fields.map((f) => `"${f}"`).join(", ");
|
|
19126
|
+
const whereClauses = fields.map((f) => `.where("${f}", "=", dup.${f})`).join("\n ");
|
|
19127
|
+
return [` // Resolve duplicate (${fields.join(", ")}) combinations before unique index "${change.indexName}" is enforced
|
|
19128
|
+
{
|
|
19129
|
+
const duplicates = await trx
|
|
19130
|
+
.selectFrom("${change.typeName}")
|
|
19131
|
+
.select([${fieldList}])
|
|
19132
|
+
.groupBy([${fieldList}])
|
|
19133
|
+
.having((eb) => eb.fn.count("id"), ">", 1)
|
|
19134
|
+
.execute();
|
|
19135
|
+
for (const dup of duplicates) {
|
|
19136
|
+
const records = await trx
|
|
19137
|
+
.selectFrom("${change.typeName}")
|
|
19138
|
+
.select(["id"])
|
|
19139
|
+
${whereClauses}
|
|
19140
|
+
.execute();
|
|
19141
|
+
// Keep the first record; update or delete the others so the combination becomes unique
|
|
19142
|
+
for (let i = 1; i < records.length; i++) {
|
|
19143
|
+
await trx
|
|
19144
|
+
.updateTable("${change.typeName}")
|
|
19145
|
+
.set({ ${fields[0]}: null }) // TODO: Set appropriate unique value
|
|
19146
|
+
.where("id", "=", records[i].id)
|
|
19147
|
+
.execute();
|
|
19148
|
+
}
|
|
19149
|
+
}
|
|
19150
|
+
}`];
|
|
19151
|
+
}
|
|
18811
19152
|
if (change.kind === "field_added") {
|
|
18812
|
-
if (change.after.required) return ` // Populate ${change.fieldName} for existing ${change.typeName} records
|
|
19153
|
+
if (change.after.required) return [` // Populate ${change.fieldName} for existing ${change.typeName} records
|
|
18813
19154
|
await trx
|
|
18814
19155
|
.updateTable("${change.typeName}")
|
|
18815
19156
|
.set({
|
|
18816
19157
|
${change.fieldName}: null, // TODO: Set appropriate default value
|
|
18817
19158
|
})
|
|
18818
|
-
.execute()
|
|
18819
|
-
return
|
|
19159
|
+
.execute();`];
|
|
19160
|
+
return [];
|
|
18820
19161
|
}
|
|
18821
|
-
if (change.kind !== "field_modified") return
|
|
19162
|
+
if (change.kind !== "field_modified") return [];
|
|
18822
19163
|
const { before, after } = change;
|
|
18823
|
-
|
|
19164
|
+
const scripts = [];
|
|
19165
|
+
if (!before.required && after.required) scripts.push(` // Set ${change.fieldName} for ${change.typeName} records where it is null
|
|
18824
19166
|
await trx
|
|
18825
19167
|
.updateTable("${change.typeName}")
|
|
18826
19168
|
.set({
|
|
18827
19169
|
${change.fieldName}: null, // TODO: Set appropriate default value
|
|
18828
19170
|
})
|
|
18829
19171
|
.where("${change.fieldName}", "is", null)
|
|
18830
|
-
.execute()
|
|
18831
|
-
if (!
|
|
18832
|
-
|
|
18833
|
-
|
|
18834
|
-
|
|
18835
|
-
.groupBy("${change.fieldName}")
|
|
18836
|
-
.having((eb) => eb.fn.count("id"), ">", 1)
|
|
18837
|
-
.execute();
|
|
18838
|
-
for (const dup of duplicates) {
|
|
18839
|
-
// Keep first record, add suffix to others
|
|
18840
|
-
const records = await trx
|
|
18841
|
-
.selectFrom("${change.typeName}")
|
|
18842
|
-
.select(["id", "${change.fieldName}"])
|
|
18843
|
-
.where("${change.fieldName}", "=", dup.${change.fieldName})
|
|
18844
|
-
.execute();
|
|
18845
|
-
for (let i = 1; i < records.length; i++) {
|
|
18846
|
-
await trx
|
|
18847
|
-
.updateTable("${change.typeName}")
|
|
18848
|
-
.set({ ${change.fieldName}: \`\${records[i].${change.fieldName}}_\${i}\` }) // TODO: Set appropriate unique value
|
|
18849
|
-
.where("id", "=", records[i].id)
|
|
18850
|
-
.execute();
|
|
18851
|
-
}
|
|
18852
|
-
}`;
|
|
19172
|
+
.execute();`);
|
|
19173
|
+
if (!deferUniqueConstraint) {
|
|
19174
|
+
const uniqueConstraintScript = generateUniqueConstraintScript(change);
|
|
19175
|
+
if (uniqueConstraintScript) scripts.push(uniqueConstraintScript);
|
|
19176
|
+
}
|
|
18853
19177
|
if (before.type === "enum" && after.type === "enum") {
|
|
18854
19178
|
const beforeValues = (before.allowedValues ?? []).map((v) => v.value);
|
|
18855
19179
|
const afterValues = (after.allowedValues ?? []).map((v) => v.value);
|
|
18856
19180
|
const removedValues = beforeValues.filter((v) => !afterValues.includes(v));
|
|
18857
19181
|
if (removedValues.length > 0) {
|
|
18858
19182
|
const defaultValue = afterValues[0] ?? "NEW_VALUE";
|
|
18859
|
-
|
|
19183
|
+
scripts.push(` // Migrate records with removed enum values: ${removedValues.join(", ")}
|
|
18860
19184
|
await trx
|
|
18861
19185
|
.updateTable("${change.typeName}")
|
|
18862
19186
|
.set({ ${change.fieldName}: "${defaultValue}" }) // TODO: Set appropriate value
|
|
18863
19187
|
.where("${change.fieldName}", "in", [${removedValues.map((v) => `"${v}"`).join(", ")}])
|
|
18864
|
-
.execute()
|
|
19188
|
+
.execute();`);
|
|
18865
19189
|
}
|
|
18866
19190
|
}
|
|
18867
|
-
if (before.foreignKeyType && after.foreignKeyType && before.foreignKeyType !== after.foreignKeyType)
|
|
19191
|
+
if (before.foreignKeyType && after.foreignKeyType && before.foreignKeyType !== after.foreignKeyType) scripts.push(` // Migrate ${change.fieldName} references from ${before.foreignKeyType} to ${after.foreignKeyType}
|
|
18868
19192
|
// Find records that don't have a valid reference in the new target table
|
|
18869
|
-
|
|
18870
|
-
|
|
18871
|
-
|
|
18872
|
-
|
|
18873
|
-
|
|
18874
|
-
|
|
18875
|
-
|
|
18876
|
-
for (const record of orphanedRecords) {
|
|
18877
|
-
await trx
|
|
18878
|
-
.updateTable("${change.typeName}")
|
|
18879
|
-
.set({ ${change.fieldName}: null }) // TODO: Set appropriate new reference
|
|
18880
|
-
.where("id", "=", record.id)
|
|
19193
|
+
{
|
|
19194
|
+
const orphanedRecords = await trx
|
|
19195
|
+
.selectFrom("${change.typeName}")
|
|
19196
|
+
.leftJoin("${after.foreignKeyType}", "${change.typeName}.${change.fieldName}", "${after.foreignKeyType}.id")
|
|
19197
|
+
.select(["${change.typeName}.id", "${change.typeName}.${change.fieldName}"])
|
|
19198
|
+
.where("${after.foreignKeyType}.id", "is", null)
|
|
19199
|
+
.where("${change.typeName}.${change.fieldName}", "is not", null)
|
|
18881
19200
|
.execute();
|
|
19201
|
+
for (const record of orphanedRecords) {
|
|
19202
|
+
await trx
|
|
19203
|
+
.updateTable("${change.typeName}")
|
|
19204
|
+
.set({ ${change.fieldName}: null }) // TODO: Set appropriate new reference
|
|
19205
|
+
.where("id", "=", record.id)
|
|
19206
|
+
.execute();
|
|
19207
|
+
}
|
|
19208
|
+
}`);
|
|
19209
|
+
return scripts;
|
|
19210
|
+
}
|
|
19211
|
+
function generateUniqueConstraintScript(change) {
|
|
19212
|
+
if (change.kind !== "field_modified") return null;
|
|
19213
|
+
const { before, after } = change;
|
|
19214
|
+
if ((before.unique ?? false) || !(after.unique ?? false)) return null;
|
|
19215
|
+
return ` // Ensure ${change.fieldName} values are unique before adding constraint
|
|
19216
|
+
{
|
|
19217
|
+
const duplicates = await trx
|
|
19218
|
+
.selectFrom("${change.typeName}")
|
|
19219
|
+
.select(["${change.fieldName}"])
|
|
19220
|
+
.groupBy("${change.fieldName}")
|
|
19221
|
+
.having((eb) => eb.fn.count("id"), ">", 1)
|
|
19222
|
+
.execute();
|
|
19223
|
+
for (const dup of duplicates) {
|
|
19224
|
+
// Keep first record, add suffix to others
|
|
19225
|
+
const records = await trx
|
|
19226
|
+
.selectFrom("${change.typeName}")
|
|
19227
|
+
.select(["id", "${change.fieldName}"])
|
|
19228
|
+
.where("${change.fieldName}", "=", dup.${change.fieldName})
|
|
19229
|
+
.execute();
|
|
19230
|
+
for (let i = 1; i < records.length; i++) {
|
|
19231
|
+
await trx
|
|
19232
|
+
.updateTable("${change.typeName}")
|
|
19233
|
+
.set({ ${change.fieldName}: \`\${records[i].${change.fieldName}}_\${i}\` }) // TODO: Set appropriate unique value
|
|
19234
|
+
.where("id", "=", records[i].id)
|
|
19235
|
+
.execute();
|
|
19236
|
+
}
|
|
19237
|
+
}
|
|
19238
|
+
}`;
|
|
19239
|
+
}
|
|
19240
|
+
function generateDecimalScaleChangeScript(change) {
|
|
19241
|
+
if (change.kind !== "field_modified") return null;
|
|
19242
|
+
const { before, after } = change;
|
|
19243
|
+
if (before.type !== "decimal" || after.type !== "decimal" || before.scale === after.scale) return null;
|
|
19244
|
+
const valueExpression = !before.required && after.required ? `row.${change.fieldName}!` : `row.${change.fieldName}`;
|
|
19245
|
+
const beforeScale = before.scale ?? 6;
|
|
19246
|
+
const roundingWarning = (after.scale ?? 6) < beforeScale ? `
|
|
19247
|
+
// Values that exceed the new scale may be rounded half-up, so review the
|
|
19248
|
+
// resulting precision before deploying.` : "";
|
|
19249
|
+
return ` // Re-save existing ${change.typeName} rows so ${change.fieldName} is stored under the new scale.
|
|
19250
|
+
// This is a workaround for a platform-side gap where rows written under the
|
|
19251
|
+
// previous scale could fail on later updates until re-saved. Keep it unless
|
|
19252
|
+
// your platform is confirmed to handle stored values across scale changes.${roundingWarning}
|
|
19253
|
+
{
|
|
19254
|
+
let lastId: string | undefined;
|
|
19255
|
+
while (true) {
|
|
19256
|
+
let query = trx
|
|
19257
|
+
.selectFrom("${change.typeName}")
|
|
19258
|
+
.select(["id", "${change.fieldName}"])
|
|
19259
|
+
.where("${change.fieldName}", "is not", null)
|
|
19260
|
+
.orderBy("id", "asc")
|
|
19261
|
+
.limit(100);
|
|
19262
|
+
if (lastId) {
|
|
19263
|
+
query = query.where("id", ">", lastId);
|
|
19264
|
+
}
|
|
19265
|
+
const rows = await query.execute();
|
|
19266
|
+
if (rows.length === 0) break;
|
|
19267
|
+
|
|
19268
|
+
for (const row of rows) {
|
|
19269
|
+
await trx
|
|
19270
|
+
.updateTable("${change.typeName}")
|
|
19271
|
+
.set({ ${change.fieldName}: ${valueExpression} })
|
|
19272
|
+
.where("id", "=", row.id)
|
|
19273
|
+
.where("${change.fieldName}", "=", ${valueExpression})
|
|
19274
|
+
.execute();
|
|
19275
|
+
}
|
|
19276
|
+
lastId = rows[rows.length - 1]!.id;
|
|
19277
|
+
}
|
|
18882
19278
|
}`;
|
|
18883
|
-
return null;
|
|
18884
19279
|
}
|
|
18885
19280
|
|
|
18886
19281
|
//#endregion
|
|
@@ -18949,7 +19344,7 @@ async function generate(options) {
|
|
|
18949
19344
|
if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
|
|
18950
19345
|
let pluginManager;
|
|
18951
19346
|
if (plugins.length > 0) pluginManager = new PluginManager(plugins);
|
|
18952
|
-
const { defineApplication } = await import("./application-
|
|
19347
|
+
const { defineApplication } = await import("./application-5FOWIxFQ.mjs");
|
|
18953
19348
|
const application = defineApplication({
|
|
18954
19349
|
config,
|
|
18955
19350
|
pluginManager
|
|
@@ -21078,4 +21473,4 @@ async function registerTypeScriptRuntime(hookUrl) {
|
|
|
21078
21473
|
|
|
21079
21474
|
//#endregion
|
|
21080
21475
|
export { listFolders as $, deploymentArgs as $n, handleOptionalToRequiredError as $t, generate as A, generateUserTypes as An, startCommand as At, remove as B, loadConsoleBaseUrl as Bn, deploy as Bt, waitWorkflowExecution as C, formatDiffSummary as Cn, listCommand$8 as Ct, listWorkflows as D, resourceTrn as Dn, jobsCommand as Dt, listCommand$2 as E, getNamespacesWithMigrations as En, getExecutorWaitFailureMessage as Et, openInConfiguredEditor as F, deleteUserTokens as Fn, getWorkflowExecution as Ft, treeCommand as G, readPlatformConfig as Gn, createWorkspace$1 as Gt, updateCommand$1 as H, loadStoredUserTokens as Hn, listCommand$9 as Ht, show as I, fetchLatestToken as In, listWorkflowExecutions as It, getCommand$1 as J, writePlatformConfig as Jn, ensureConfigId as Jt, listCommand$3 as K, resolveUserTokenKey as Kn, formatKeyValueTable as Kt, showCommand as L, hasAnyUserTokenEntry as Ln, functionExecutionStatusToString as Lt, generateMigrationScript as M, apiCall as Mn, getCommand$5 as Mt, writeDbTypesFile as N, assertWritable as Nn, getWorkflow as Nt, truncate as O, sdkNameLabelKey as On, listExecutorJobs as Ot, getConfiguredEditorCommand as P, loadConfig as Pn, executionsCommand as Pt, listCommand$4 as Q, confirmationArgs as Qn, MIGRATION_LABEL_KEY as Qt, extractOwnedNamespaces as R, hasUserTokenEntry as Rn, getCommand$6 as Rt, waitCommand as S, parseMigrationNumberArg as Sn, triggerExecutor as St, resumeWorkflow as T, hasChanges as Tn, getExecutorJob as Tt, updateOrganization as U, loadWorkspaceId as Un, listWorkspaces as Ut, removeCommand$1 as V, loadMachineUserName as Vn, deployFromCLI as Vt, organizationTree as W, platformConfigFromProfile as Wn, createCommand$1 as Wt, updateCommand$2 as X, commonArgs as Xn, waitForExecution as Xt, getOrganization as Y, defineAppCommand as Yn, executeScript as Yt, updateFolder as Z, configArg as Zn, bundleMigrationScript as Zt, deleteWorkspace as _, getNextMigrationNumber as _n, getCommand$4 as _t, updateUser as a, DIFF_FILE_NAME as an, toPageDirection as ar, createFolder as at, getAppHealth as b, reconstructSnapshotFromMigrations as bn, webhookCommand as bt, listCommand as c, SCHEMA_FILE_NAME as cn, getCommand$3 as ct, inviteUser as d, compareSnapshots as dn, tokenCommand as dt, parseMigrationLabelNumber as en, isVerbose as er, getCommand$2 as et, restoreCommand as f, createSnapshotFromLocalTypes as fn, listCommand$6 as ft, deleteCommand as g, getMigrationFiles as gn, listFunctionRegistries as gt, getWorkspace as h, getMigrationFilePath as hn, listCommand$7 as ht, updateCommand as i, DB_TYPES_FILE_NAME as in, resolveMachineUserInputSource as ir, createCommand as it, generateCommand as j, prompt as jn, startWorkflow as jt, truncateCommand as k, PluginManager as kn, watchExecutorJob as kt, listUsers as l, assertValidMigrationFiles as ln, getOAuth2Client as lt, getCommand as m, getMigrationDirPath as mn, generate$1 as mt, query as n, generateAllTypeManifestsFromSnapshot as nn, pagedLogArgs as nr, deleteCommand$1 as nt, removeCommand as o, INITIAL_SCHEMA_NUMBER as on, workspaceArgs as or, listCommand$5 as ot, restoreWorkspace as p, getLatestMigrationNumber as pn, listMachineUsers as pt, listOrganizations as q, saveUserTokens as qn, workspaceNameSchema as qt, queryCommand as r, protoGqlPermission as rn, paginationArgs as rr, deleteFolder as rt, removeUser as s, MIGRATE_FILE_NAME as sn, listOAuth2Clients as st, registerTypeScriptRuntime as t, compareSnapshotWithRemote as tn, multiConfigArg as tr, getFolder as tt, inviteCommand as u, compareLocalTypesWithSnapshot as un, getMachineUserToken as ut, listApps as v, isValidMigrationNumber as vn, getFunctionRegistry as vt, resumeCommand as w, formatMigrationDiff as wn, listExecutors as wt, healthCommand as x, formatMigrationNumber as xn, triggerCommand as xt, listCommand$1 as y, loadDiff as yn, listWebhookExecutors as yt, logBetaWarning as z, loadAccessToken as zn, getExecutor as zt };
|
|
21081
|
-
//# sourceMappingURL=register-typescript-runtime-
|
|
21476
|
+
//# sourceMappingURL=register-typescript-runtime-BCvWR3HC.mjs.map
|