From b0595e452af1fc29d2fcceed963f70828d13a780 Mon Sep 17 00:00:00 2001 From: Weiko Date: Tue, 10 Dec 2024 15:32:13 +0100 Subject: [PATCH] Fix add-subdomain-to-workspace command (#9005) ## Context Fix add-subdomain-to-workspace command not included in global module also fixing the command regex logic that was not generating subdomain properly --- .../commands/database-command.module.ts | 2 + .../0-34/0-34-generate-subdomain.command.ts | 46 +++++++++++++------ .../0-34/0-34-upgrade-version.module.ts | 7 +-- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/packages/twenty-server/src/database/commands/database-command.module.ts b/packages/twenty-server/src/database/commands/database-command.module.ts index 38af84b8a..75bbce194 100644 --- a/packages/twenty-server/src/database/commands/database-command.module.ts +++ b/packages/twenty-server/src/database/commands/database-command.module.ts @@ -9,6 +9,7 @@ import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-wo import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question'; import { UpgradeTo0_32CommandModule } from 'src/database/commands/upgrade-version/0-32/0-32-upgrade-version.module'; import { UpgradeTo0_33CommandModule } from 'src/database/commands/upgrade-version/0-33/0-33-upgrade-version.module'; +import { UpgradeTo0_34CommandModule } from 'src/database/commands/upgrade-version/0-34/0-34-upgrade-version.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; @@ -49,6 +50,7 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp WorkspaceMetadataVersionModule, UpgradeTo0_32CommandModule, UpgradeTo0_33CommandModule, + UpgradeTo0_34CommandModule, FeatureFlagModule, ], providers: [ diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-generate-subdomain.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-generate-subdomain.command.ts index d7b6d386f..4656de25b 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-generate-subdomain.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-generate-subdomain.command.ts @@ -1,11 +1,11 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Command } from 'nest-commander'; -import { Repository, In } from 'typeorm'; +import { In, Repository } from 'typeorm'; import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { BaseCommandOptions } from 'src/database/commands/base.command'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; // For DX only type WorkspaceId = string; @@ -41,19 +41,25 @@ export class GenerateDefaultSubdomainCommand extends ActiveWorkspacesCommandRunn } if (!domainName && displayName) { - const displayNameWords = displayName.match(/(\w| |\d)+/); - - if (displayNameWords) { - result.subdomain = displayNameWords - .join('-') - .replace(/ /g, '') - .toLowerCase(); - } + result.subdomain = this.sanitizeForSubdomain(displayName); } return result; } + private sanitizeForSubdomain(input: string) { + const normalized = input.normalize('NFKD').replace(/[\u0300-\u036f]/g, ''); + + const hyphenated = normalized + .replace(/[^a-zA-Z0-9]/g, '-') + .replace(/-+/g, '-') + .replace(/^-+|-+$/g, '') + .toLowerCase(); + + // DNS subdomain limit is 63, but we want to be conservative for duplicates + return hyphenated.substring(0, 60); + } + private groupBySubdomainName( acc: Record>, workspace: Workspace, @@ -70,16 +76,23 @@ export class GenerateDefaultSubdomainCommand extends ActiveWorkspacesCommandRunn private async deduplicateAndSave( subdomain: Subdomain, workspaceIds: Array, + existingSubdomains: Set, options: BaseCommandOptions, ) { for (const [index, workspaceId] of workspaceIds.entries()) { const subdomainDeduplicated = - index === 0 ? subdomain : `${subdomain}-${index}`; + index === 0 + ? existingSubdomains.has(subdomain) + ? `${subdomain}-${index}` + : subdomain + : `${subdomain}-${index}`; this.logger.log( `Updating workspace ${workspaceId} with subdomain ${subdomainDeduplicated}`, ); + existingSubdomains.add(subdomainDeduplicated); + if (!options.dryRun) { await this.workspaceRepository.update(workspaceId, { subdomain: subdomainDeduplicated, @@ -89,7 +102,7 @@ export class GenerateDefaultSubdomainCommand extends ActiveWorkspacesCommandRunn } async executeActiveWorkspacesCommand( - passedParam: string[], + _passedParam: string[], options: BaseCommandOptions, activeWorkspaceIds: string[], ): Promise { @@ -116,8 +129,15 @@ export class GenerateDefaultSubdomainCommand extends ActiveWorkspacesCommandRunn ), ); + const existingSubdomains: Set = new Set(); + for (const [subdomain, workspaceIds] of workspaceBySubdomain) { - await this.deduplicateAndSave(subdomain, workspaceIds, options); + await this.deduplicateAndSave( + subdomain, + workspaceIds, + existingSubdomains, + options, + ); } } } diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-upgrade-version.module.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-upgrade-version.module.ts index e6f1af41a..2e532cc64 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-upgrade-version.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-34/0-34-upgrade-version.module.ts @@ -1,13 +1,14 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { GenerateDefaultSubdomainCommand } from 'src/database/commands/upgrade-version/0-34/0-34-generate-subdomain.command'; +import { UpgradeTo0_34Command } from 'src/database/commands/upgrade-version/0-34/0-34-upgrade-version.command'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { SearchModule } from 'src/engine/metadata-modules/search/search.module'; import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; import { WorkspaceSyncMetadataCommandsModule } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module'; -import { UpgradeTo0_34Command } from 'src/database/commands/upgrade-version/0-34/0-34-upgrade-version.command'; @Module({ imports: [ @@ -20,6 +21,6 @@ import { UpgradeTo0_34Command } from 'src/database/commands/upgrade-version/0-34 SearchModule, WorkspaceMigrationRunnerModule, ], - providers: [UpgradeTo0_34Command], + providers: [UpgradeTo0_34Command, GenerateDefaultSubdomainCommand], }) -export class UpgradeTo0_33CommandModule {} +export class UpgradeTo0_34CommandModule {}