Rework types for logic function (#18074)
## Summary - **Consolidate logic function services**: Remove `LogicFunctionMetadataService` and consolidate all logic function CRUD operations into `LogicFunctionFromSourceService`, with a new `LogicFunctionFromSourceHelperService` for shared validation/migration logic - **Introduce typed conversion utils following the skill pattern**: Add `fromCreateLogicFunctionFromSourceInputToUniversalFlatLogicFunctionToCreate` and `fromUpdateLogicFunctionFromSourceInputToFlatLogicFunctionToUpdate` that convert DTO inputs directly to flat entities (`UniversalFlatLogicFunction` / `FlatLogicFunction`), replacing the previous intermediate `UpdateLogicFunctionMetadataParams` indirection - **Simplify `CodeStepBuildService`**: Remove ~100 lines of manual duplication logic by delegating to `LogicFunctionFromSourceService.duplicateOneWithSource` - **Remove completed 1-17 migration**: Delete `MigrateWorkflowCodeStepsCommand` and associated utils that migrated workflow code steps from serverless functions to logic functions
This commit is contained in:
-301
@@ -1,301 +0,0 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import crypto from 'crypto';
|
||||
|
||||
import { Command } from 'nest-commander';
|
||||
import { FileFolder, type Sources } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
|
||||
import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner';
|
||||
import {
|
||||
type CodeStepMigrationTarget,
|
||||
collectCodeStepMigrationTargets,
|
||||
migrateWorkflowCodeStepsWithMapping,
|
||||
type ServerlessToLogicFunctionMapping,
|
||||
} from 'src/database/commands/upgrade-version-command/1-17/utils/migrate-workflow-code-step.util';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/services/application.service';
|
||||
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
|
||||
import { LogicFunctionMetadataService } from 'src/engine/metadata-modules/logic-function/services/logic-function-metadata.service';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { WorkflowVersionStatus } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
|
||||
const OLD_BUILT_FOLDER = 'built-function';
|
||||
const OLD_SOURCE_FOLDER = 'serverless-function';
|
||||
const NEW_WORKFLOW_RESOURCE_PREFIX = 'workflow';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade:1-17:migrate-workflow-code-steps',
|
||||
description:
|
||||
'Migrate workflow code steps from v1.16 (serverless) to v1.17 (logic function): create new logic function per (serverlessFunctionId, version), move files, update steps, delete old logic function.',
|
||||
})
|
||||
export class MigrateWorkflowCodeStepsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
|
||||
protected readonly logger = new Logger(MigrateWorkflowCodeStepsCommand.name);
|
||||
|
||||
constructor(
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
protected readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
@InjectRepository(LogicFunctionEntity)
|
||||
private readonly logicFunctionRepository: Repository<LogicFunctionEntity>,
|
||||
protected readonly globalWorkspaceOrmManager: GlobalWorkspaceOrmManager,
|
||||
protected readonly dataSourceService: DataSourceService,
|
||||
private readonly fileStorageService: FileStorageService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly logicFunctionMetadataService: LogicFunctionMetadataService,
|
||||
) {
|
||||
super(workspaceRepository, globalWorkspaceOrmManager, dataSourceService);
|
||||
}
|
||||
|
||||
override async runOnWorkspace({
|
||||
workspaceId,
|
||||
options,
|
||||
}: RunOnWorkspaceArgs): Promise<void> {
|
||||
const isDryRun = options.dryRun ?? false;
|
||||
|
||||
this.logger.log(
|
||||
`Running MigrateWorkflowCodeStepsCommand for workspace ${workspaceId}`,
|
||||
);
|
||||
|
||||
const workflowVersionRepository =
|
||||
await this.globalWorkspaceOrmManager.getRepository(
|
||||
workspaceId,
|
||||
'workflowVersion',
|
||||
{ shouldBypassPermissionChecks: true },
|
||||
);
|
||||
|
||||
const workflowVersions = await workflowVersionRepository.find({
|
||||
select: ['id', 'steps', 'status'],
|
||||
where: {
|
||||
status: In([WorkflowVersionStatus.DRAFT, WorkflowVersionStatus.ACTIVE]),
|
||||
},
|
||||
});
|
||||
|
||||
const allTargets = new Map<string, CodeStepMigrationTarget>();
|
||||
|
||||
for (const version of workflowVersions) {
|
||||
const targets = collectCodeStepMigrationTargets(version.steps);
|
||||
|
||||
for (const target of targets) {
|
||||
const key = `${target.serverlessFunctionId}:${target.serverlessFunctionVersion}`;
|
||||
|
||||
if (!allTargets.has(key)) {
|
||||
allTargets.set(key, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const targetsList = Array.from(allTargets.values());
|
||||
|
||||
if (targetsList.length === 0) {
|
||||
this.logger.log(`No code steps to migrate in workspace ${workspaceId}`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const mapping = new Map<string, string>();
|
||||
|
||||
if (!isDryRun) {
|
||||
for (const target of targetsList) {
|
||||
const newLogicFunctionId =
|
||||
await this.createLogicFunctionAndMigrateFiles(workspaceId, target);
|
||||
|
||||
if (isDefined(newLogicFunctionId)) {
|
||||
const key = `${target.serverlessFunctionId}:${target.serverlessFunctionVersion}`;
|
||||
|
||||
mapping.set(key, newLogicFunctionId);
|
||||
}
|
||||
}
|
||||
|
||||
const serverlessToLogicMapping: ServerlessToLogicFunctionMapping = (
|
||||
serverlessFunctionId,
|
||||
serverlessFunctionVersion,
|
||||
) => {
|
||||
const key = `${serverlessFunctionId}:${serverlessFunctionVersion}`;
|
||||
const newId = mapping.get(key);
|
||||
|
||||
if (!isDefined(newId)) {
|
||||
throw new Error(
|
||||
`Missing mapping for ${serverlessFunctionId}:${serverlessFunctionVersion}`,
|
||||
);
|
||||
}
|
||||
|
||||
return newId;
|
||||
};
|
||||
|
||||
for (const version of workflowVersions) {
|
||||
const { migratedSteps, hasChanges } =
|
||||
migrateWorkflowCodeStepsWithMapping(
|
||||
version.steps,
|
||||
serverlessToLogicMapping,
|
||||
);
|
||||
|
||||
if (!hasChanges) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await workflowVersionRepository.update(
|
||||
{ id: version.id },
|
||||
{ steps: migratedSteps },
|
||||
);
|
||||
|
||||
this.logger.log(
|
||||
`Migrated workflow version ${version.id} in workspace ${workspaceId}`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.logger.log(
|
||||
`[DRY RUN] Would create ${targetsList.length} new logic function(s), migrate files, update workflow steps, and delete ${new Set(targetsList.map((t) => t.serverlessFunctionId)).size} old logic function(s) in workspace ${workspaceId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async getApplicationUniversalIdentifier(
|
||||
applicationId: string,
|
||||
): Promise<string | null> {
|
||||
const application = await this.applicationService.findById(applicationId);
|
||||
|
||||
return application?.universalIdentifier ?? null;
|
||||
}
|
||||
|
||||
private async createLogicFunctionAndMigrateFiles(
|
||||
workspaceId: string,
|
||||
target: CodeStepMigrationTarget,
|
||||
): Promise<string | null> {
|
||||
const { serverlessFunctionId, serverlessFunctionVersion } = target;
|
||||
const version = serverlessFunctionVersion ?? 'draft';
|
||||
|
||||
const oldLogicFunction = await this.logicFunctionRepository.findOne({
|
||||
where: { id: serverlessFunctionId, workspaceId },
|
||||
});
|
||||
|
||||
if (!isDefined(oldLogicFunction)) {
|
||||
this.logger.warn(
|
||||
`Logic function ${serverlessFunctionId} not found in workspace ${workspaceId}, skipping`,
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const newLogicFunctionId = v4();
|
||||
const applicationUniversalIdentifier =
|
||||
await this.getApplicationUniversalIdentifier(
|
||||
oldLogicFunction.applicationId,
|
||||
);
|
||||
|
||||
const { builtContent, sourceContent } = await this.readOldFunctionFiles(
|
||||
workspaceId,
|
||||
serverlessFunctionId,
|
||||
version,
|
||||
);
|
||||
|
||||
const checksum = crypto
|
||||
.createHash('md5')
|
||||
.update(builtContent)
|
||||
.digest('hex');
|
||||
|
||||
if (isDefined(applicationUniversalIdentifier)) {
|
||||
await this.uploadFunctionFiles(
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
newLogicFunctionId,
|
||||
{ builtContent, sourceContent },
|
||||
);
|
||||
}
|
||||
|
||||
await this.logicFunctionMetadataService.createOne({
|
||||
input: {
|
||||
id: newLogicFunctionId,
|
||||
name: oldLogicFunction.name,
|
||||
description: oldLogicFunction.description ?? undefined,
|
||||
timeoutSeconds: oldLogicFunction.timeoutSeconds ?? 300,
|
||||
toolInputSchema: oldLogicFunction.toolInputSchema ?? {},
|
||||
isTool: oldLogicFunction.isTool ?? false,
|
||||
handlerName: oldLogicFunction.handlerName,
|
||||
sourceHandlerPath: `${NEW_WORKFLOW_RESOURCE_PREFIX}/${newLogicFunctionId}/src/index.ts`,
|
||||
builtHandlerPath: `${NEW_WORKFLOW_RESOURCE_PREFIX}/${newLogicFunctionId}/src/index.mjs`,
|
||||
checksum,
|
||||
isBuildUpToDate: true,
|
||||
},
|
||||
workspaceId,
|
||||
ownerFlatApplication: oldLogicFunction.application,
|
||||
});
|
||||
|
||||
this.logger.log(
|
||||
`Created logic function ${newLogicFunctionId} (from ${serverlessFunctionId}/${version}) and migrated files in workspace ${workspaceId}`,
|
||||
);
|
||||
|
||||
return newLogicFunctionId;
|
||||
}
|
||||
|
||||
private async readOldFunctionFiles(
|
||||
workspaceId: string,
|
||||
serverlessFunctionId: string,
|
||||
version: string,
|
||||
): Promise<{ builtContent: string; sourceContent: string }> {
|
||||
const workspacePrefix = `workspace-${workspaceId}`;
|
||||
|
||||
const builtSources = await this.fileStorageService.readFolderLegacy(
|
||||
`${workspacePrefix}/${OLD_BUILT_FOLDER}/${serverlessFunctionId}/${version}`,
|
||||
);
|
||||
|
||||
const sourceSources = await this.fileStorageService.readFolderLegacy(
|
||||
`${workspacePrefix}/${OLD_SOURCE_FOLDER}/${serverlessFunctionId}/${version}`,
|
||||
);
|
||||
|
||||
// Old source layout may nest files under a `src/` key
|
||||
const sourceRoot =
|
||||
(sourceSources.src as Sources) ?? (sourceSources as Sources);
|
||||
|
||||
const builtContent = builtSources['index.mjs'] as string;
|
||||
const sourceContent = sourceRoot['index.ts'] as string;
|
||||
|
||||
if (!isDefined(builtContent) || !isDefined(sourceContent)) {
|
||||
throw new Error(
|
||||
`Missing index.mjs or index.ts for serverless function ${serverlessFunctionId}/${version} in workspace ${workspaceId}`,
|
||||
);
|
||||
}
|
||||
|
||||
return { builtContent, sourceContent };
|
||||
}
|
||||
|
||||
private async uploadFunctionFiles(
|
||||
workspaceId: string,
|
||||
applicationUniversalIdentifier: string,
|
||||
newLogicFunctionId: string,
|
||||
files: { builtContent: string; sourceContent: string },
|
||||
): Promise<void> {
|
||||
const resourcePath = `${NEW_WORKFLOW_RESOURCE_PREFIX}/${newLogicFunctionId}/src`;
|
||||
|
||||
await this.fileStorageService.writeFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.BuiltLogicFunction,
|
||||
resourcePath: `${resourcePath}/index.mjs`,
|
||||
sourceFile: Buffer.from(files.builtContent),
|
||||
mimeType: 'application/javascript',
|
||||
settings: {
|
||||
isTemporaryFile: false,
|
||||
toDelete: false,
|
||||
},
|
||||
});
|
||||
|
||||
await this.fileStorageService.writeFile({
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder: FileFolder.Source,
|
||||
resourcePath: `${resourcePath}/index.ts`,
|
||||
sourceFile: Buffer.from(files.sourceContent),
|
||||
mimeType: 'application/typescript',
|
||||
settings: {
|
||||
isTemporaryFile: false,
|
||||
toDelete: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
-5
@@ -11,7 +11,6 @@ import { MigrateDateTimeIsFilterValuesCommand } from 'src/database/commands/upgr
|
||||
import { MigrateNoteTargetToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-note-target-to-morph-relations.command';
|
||||
import { MigrateSendEmailRecipientsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-send-email-recipients.command';
|
||||
import { MigrateTaskTargetToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-task-target-to-morph-relations.command';
|
||||
import { MigrateWorkflowCodeStepsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-workflow-code-steps.command';
|
||||
import { SeedWorkflowV1_16Command } from 'src/database/commands/upgrade-version-command/1-17/1-17-seed-workflow-v1-16.command';
|
||||
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
|
||||
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||
@@ -25,7 +24,6 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module';
|
||||
import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
|
||||
import { LogicFunctionModule } from 'src/engine/metadata-modules/logic-function/logic-function.module';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
|
||||
@@ -65,7 +63,6 @@ import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/tas
|
||||
ApplicationModule,
|
||||
UserWorkspaceModule,
|
||||
WorkspaceMigrationModule,
|
||||
LogicFunctionModule,
|
||||
RecordPositionModule,
|
||||
GlobalWorkspaceDataSourceModule,
|
||||
],
|
||||
@@ -79,7 +76,6 @@ import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/tas
|
||||
DeleteFileRecordsAndUpdateTableCommand,
|
||||
MigrateSendEmailRecipientsCommand,
|
||||
MigrateDateTimeIsFilterValuesCommand,
|
||||
MigrateWorkflowCodeStepsCommand,
|
||||
SeedWorkflowV1_16Command,
|
||||
BackfillApplicationPackageFilesCommand,
|
||||
],
|
||||
@@ -93,7 +89,6 @@ import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/tas
|
||||
MigrateSendEmailRecipientsCommand,
|
||||
MigrateDateTimeIsFilterValuesCommand,
|
||||
DeleteFileRecordsAndUpdateTableCommand,
|
||||
MigrateWorkflowCodeStepsCommand,
|
||||
SeedWorkflowV1_16Command,
|
||||
BackfillApplicationPackageFilesCommand,
|
||||
],
|
||||
|
||||
-125
@@ -1,125 +0,0 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||
|
||||
type LegacyCodeStepInput = {
|
||||
serverlessFunctionId: string;
|
||||
serverlessFunctionVersion?: string;
|
||||
serverlessFunctionInput?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
type MigratedCodeStepInput = {
|
||||
logicFunctionId: string;
|
||||
logicFunctionInput?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
type WorkflowStep = {
|
||||
id: string;
|
||||
type: string;
|
||||
settings: {
|
||||
input: LegacyCodeStepInput | MigratedCodeStepInput;
|
||||
outputSchema?: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
export const needsCodeStepMigration = (
|
||||
input: LegacyCodeStepInput | MigratedCodeStepInput,
|
||||
): input is LegacyCodeStepInput => {
|
||||
return (
|
||||
'serverlessFunctionId' in input && isDefined(input.serverlessFunctionId)
|
||||
);
|
||||
};
|
||||
|
||||
export type CodeStepMigrationTarget = {
|
||||
serverlessFunctionId: string;
|
||||
serverlessFunctionVersion: string;
|
||||
};
|
||||
|
||||
export type ServerlessToLogicFunctionMapping = (
|
||||
serverlessFunctionId: string,
|
||||
serverlessFunctionVersion: string,
|
||||
) => string;
|
||||
|
||||
export const collectCodeStepMigrationTargets = (
|
||||
steps: unknown,
|
||||
): CodeStepMigrationTarget[] => {
|
||||
if (!isDefined(steps) || !Array.isArray(steps) || steps.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const typedSteps = steps as WorkflowStep[];
|
||||
const seen = new Set<string>();
|
||||
|
||||
const targets: CodeStepMigrationTarget[] = [];
|
||||
|
||||
for (const step of typedSteps) {
|
||||
if (step.type !== WorkflowActionType.CODE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const input = step.settings.input as
|
||||
| LegacyCodeStepInput
|
||||
| MigratedCodeStepInput;
|
||||
|
||||
if (!needsCodeStepMigration(input)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const version = input.serverlessFunctionVersion ?? 'draft';
|
||||
const key = `${input.serverlessFunctionId}:${version}`;
|
||||
|
||||
if (seen.has(key)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(key);
|
||||
targets.push({
|
||||
serverlessFunctionId: input.serverlessFunctionId,
|
||||
serverlessFunctionVersion: version,
|
||||
});
|
||||
}
|
||||
|
||||
return targets;
|
||||
};
|
||||
|
||||
export const migrateWorkflowCodeStepsWithMapping = (
|
||||
steps: unknown,
|
||||
mapping: ServerlessToLogicFunctionMapping,
|
||||
): { migratedSteps: WorkflowStep[]; hasChanges: boolean } => {
|
||||
if (!isDefined(steps) || !Array.isArray(steps) || steps.length === 0) {
|
||||
return { migratedSteps: [], hasChanges: false };
|
||||
}
|
||||
|
||||
const typedSteps = steps as WorkflowStep[];
|
||||
let hasChanges = false;
|
||||
|
||||
const migratedSteps = typedSteps.map((step) => {
|
||||
if (step.type !== WorkflowActionType.CODE) {
|
||||
return step;
|
||||
}
|
||||
|
||||
const input = step.settings.input as
|
||||
| LegacyCodeStepInput
|
||||
| MigratedCodeStepInput;
|
||||
|
||||
if (!needsCodeStepMigration(input)) {
|
||||
return step;
|
||||
}
|
||||
|
||||
hasChanges = true;
|
||||
const version = input.serverlessFunctionVersion ?? 'draft';
|
||||
const newLogicFunctionId = mapping(input.serverlessFunctionId, version);
|
||||
|
||||
return {
|
||||
...step,
|
||||
settings: {
|
||||
...step.settings,
|
||||
input: {
|
||||
logicFunctionId: newLogicFunctionId,
|
||||
logicFunctionInput: input.serverlessFunctionInput ?? {},
|
||||
} as MigratedCodeStepInput,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return { migratedSteps, hasChanges };
|
||||
};
|
||||
-3
@@ -17,7 +17,6 @@ import { MakeWebhookUniversalIdentifierAndApplicationIdNotNullableMigrationComma
|
||||
import { MigrateAttachmentToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-attachment-to-morph-relations.command';
|
||||
import { MigrateNoteTargetToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-note-target-to-morph-relations.command';
|
||||
import { MigrateTaskTargetToMorphRelationsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-task-target-to-morph-relations.command';
|
||||
import { MigrateWorkflowCodeStepsCommand } from 'src/database/commands/upgrade-version-command/1-17/1-17-migrate-workflow-code-steps.command';
|
||||
import { BackfillFileSizeAndMimeTypeCommand } from 'src/database/commands/upgrade-version-command/1-18/1-18-backfill-file-size-and-mime-type.command';
|
||||
import { BackfillMessageChannelThrottleRetryAfterCommand } from 'src/database/commands/upgrade-version-command/1-18/1-18-backfill-message-channel-throttle-retry-after.command';
|
||||
import { BackfillStandardViewsAndFieldMetadataCommand } from 'src/database/commands/upgrade-version-command/1-18/1-18-backfill-standard-views-and-field-metadata.command';
|
||||
@@ -57,7 +56,6 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
||||
protected readonly migrateTaskTargetToMorphRelationsCommand: MigrateTaskTargetToMorphRelationsCommand,
|
||||
protected readonly identifyWebhookMetadataCommand: IdentifyWebhookMetadataCommand,
|
||||
protected readonly makeWebhookUniversalIdentifierAndApplicationIdNotNullableMigrationCommand: MakeWebhookUniversalIdentifierAndApplicationIdNotNullableMigrationCommand,
|
||||
protected readonly migrateWorkflowCodeStepsCommand: MigrateWorkflowCodeStepsCommand,
|
||||
protected readonly fixMorphRelationFieldNamesCommand: FixMorphRelationFieldNamesCommand,
|
||||
|
||||
// 1.18 Commands
|
||||
@@ -94,7 +92,6 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
||||
this
|
||||
.makeWebhookUniversalIdentifierAndApplicationIdNotNullableMigrationCommand,
|
||||
this.deleteFileRecordsAndUpdateTableCommand,
|
||||
this.migrateWorkflowCodeStepsCommand,
|
||||
this.backfillApplicationPackageFilesCommand,
|
||||
this.fixMorphRelationFieldNamesCommand,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user