diff --git a/packages/contentstack-config/src/utils/region-handler.ts b/packages/contentstack-config/src/utils/region-handler.ts index c0fae7d353..4b63978112 100644 --- a/packages/contentstack-config/src/utils/region-handler.ts +++ b/packages/contentstack-config/src/utils/region-handler.ts @@ -24,7 +24,7 @@ const regions = { name: 'NA', 'developerHubUrl': 'https://developerhub-api.contentstack.com', 'launchHubUrl': 'https://launch-api.contentstack.com', - 'personalizeUrl': 'https://personalization-api.contentstack.com', + 'personalizeUrl': 'https://personalize-api.contentstack.com', }, EU: { cma: 'https://eu-api.contentstack.com', @@ -33,7 +33,7 @@ const regions = { name: 'EU', 'developerHubUrl': 'https://eu-developerhub-api.contentstack.com', 'launchHubUrl': 'https://eu-launch-api.contentstack.com', - 'personalizeUrl': 'Not available', + 'personalizeUrl': 'https://eu-personalize-api.contentstack.com', }, 'AZURE-NA': { cma: 'https://azure-na-api.contentstack.com', @@ -42,7 +42,7 @@ const regions = { name: 'AZURE-NA', 'developerHubUrl': 'https://azure-na-developerhub-api.contentstack.com', 'launchHubUrl': 'https://azure-na-launch-api.contentstack.com', - 'personalizeUrl': 'Not available', + 'personalizeUrl': 'https://azure-na-personalize-api.contentstack.com', }, 'AZURE-EU': { cma: 'https://azure-eu-api.contentstack.com', @@ -51,7 +51,7 @@ const regions = { name: 'AZURE-EU', 'developerHubUrl': 'https://azure-eu-developerhub-api.contentstack.com', 'launchHubUrl': 'https://azure-eu-launch-api.contentstack.com', - 'personalizeUrl': 'Not available', + 'personalizeUrl': 'https://azure-eu-personalize-api.contentstack.com', }, 'GCP-NA': { cma: 'https://gcp-na-api.contentstack.com', @@ -60,7 +60,7 @@ const regions = { name: 'GCP-NA', 'developerHubUrl': 'https://gcp-na-developerhub-api.contentstack.com', 'launchHubUrl': 'Not available', - 'personalizeUrl': 'Not available', + 'personalizeUrl': 'https://gcp-na-personalize-api.contentstack.com', }, }; diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 3f03203b27..79568c00bf 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -107,7 +107,7 @@ export default class ExportCommand extends Command { exportConfig.host = this.cmaHost; exportConfig.region = this.region; exportConfig.developerHubBaseUrl = this.developerHubUrl; - exportConfig.modules.personalization.baseURL[exportConfig.region.name] = this.personalizeUrl; + if (this.personalizeUrl) exportConfig.modules.personalize.baseURL[exportConfig.region.name] = this.personalizeUrl; exportDir = exportConfig.cliLogsPath || exportConfig.data || exportConfig.exportDir; const managementAPIClient: ContentstackClient = await managementSDKClient(exportConfig); const moduleExporter = new ModuleExporter(managementAPIClient, exportConfig); diff --git a/packages/contentstack-export/src/config/index.ts b/packages/contentstack-export/src/config/index.ts index ad51bf8437..e83d09215f 100644 --- a/packages/contentstack-export/src/config/index.ts +++ b/packages/contentstack-export/src/config/index.ts @@ -33,7 +33,7 @@ const config: DefaultConfig = { 'content-types', 'custom-roles', 'workflows', - 'personalization', + 'personalize', 'entries', 'labels', 'marketplace-apps', @@ -144,11 +144,11 @@ const config: DefaultConfig = { dependencies: ['locales', 'content-types'], exportVersions: false, }, - personalization: { + personalize: { baseURL: { - NA: 'https://personalization-api.contentstack.com', + NA: 'https://personalize-api.contentstack.com', }, - dirName: 'personalization', + dirName: 'personalize', exportOrder: ['attributes', 'audiences', 'events', 'experiences'], projects: { dirName: 'projects', diff --git a/packages/contentstack-export/src/export/modules/personalization.ts b/packages/contentstack-export/src/export/modules/personalize.ts similarity index 93% rename from packages/contentstack-export/src/export/modules/personalization.ts rename to packages/contentstack-export/src/export/modules/personalize.ts index 6d0673ffb1..1e3bc2856a 100644 --- a/packages/contentstack-export/src/export/modules/personalization.ts +++ b/packages/contentstack-export/src/export/modules/personalize.ts @@ -10,12 +10,12 @@ import { import { log, formatError } from '../../utils'; import { ModuleClassParams, ExportConfig } from '../../types'; -export default class ExportPersonalization { +export default class ExportPersonalize { public exportConfig: ExportConfig; public personalizeConfig: { dirName: string; baseURL: Record } & AnyProperty; constructor({ exportConfig }: ModuleClassParams) { this.exportConfig = exportConfig; - this.personalizeConfig = exportConfig.modules.personalization; + this.personalizeConfig = exportConfig.modules.personalize; } async start(): Promise { @@ -39,7 +39,7 @@ export default class ExportPersonalization { experiences: new ExportExperiences(this.exportConfig), }; - const order: (keyof typeof moduleMapper)[] = this.exportConfig.modules.personalization + const order: (keyof typeof moduleMapper)[] = this.exportConfig.modules.personalize .exportOrder as (keyof typeof moduleMapper)[]; for (const module of order) { diff --git a/packages/contentstack-export/src/types/default-config.ts b/packages/contentstack-export/src/types/default-config.ts index edded90644..eb6c5c0474 100644 --- a/packages/contentstack-export/src/types/default-config.ts +++ b/packages/contentstack-export/src/types/default-config.ts @@ -122,7 +122,7 @@ export default interface DefaultConfig { dependencies?: Modules[]; exportVersions: boolean; }; - personalization: { + personalize: { dirName: string; baseURL: Record; } & AnyProperty; diff --git a/packages/contentstack-export/src/types/index.ts b/packages/contentstack-export/src/types/index.ts index 0616dbe545..0b922c0969 100644 --- a/packages/contentstack-export/src/types/index.ts +++ b/packages/contentstack-export/src/types/index.ts @@ -49,7 +49,7 @@ export type Modules = | 'labels' | 'marketplace-apps' | 'taxonomies' - | 'personalization'; + | 'personalize'; export type ModuleClassParams = { stackAPIClient: ReturnType; diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 64897f4509..19b20877f8 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -136,7 +136,7 @@ export default class ImportCommand extends Command { importConfig.host = this.cmaHost; importConfig.region = this.region; importConfig.developerHubBaseUrl = this.developerHubUrl; - importConfig.modules.personalization.baseURL[importConfig.region.name] = this.personalizeUrl; + if (this.personalizeUrl) importConfig.modules.personalize.baseURL[importConfig.region.name] = this.personalizeUrl; backupDir = importConfig.cliLogsPath || importConfig.backupDir; const managementAPIClient: ContentstackClient = await managementSDKClient(importConfig); diff --git a/packages/contentstack-import/src/config/index.ts b/packages/contentstack-import/src/config/index.ts index 1b1e9965ae..10082f2d39 100644 --- a/packages/contentstack-import/src/config/index.ts +++ b/packages/contentstack-import/src/config/index.ts @@ -33,7 +33,7 @@ const config: DefaultConfig = { 'marketplace-apps', 'global-fields', 'content-types', - 'personalization', + 'personalize', 'custom-roles', 'workflows', 'entries', @@ -151,12 +151,12 @@ const config: DefaultConfig = { dirName: 'taxonomies', fileName: 'taxonomies.json', }, - personalization: { + personalize: { baseURL: { - NA: 'https://personalization-api.contentstack.com', + NA: 'https://personalize-api.contentstack.com', }, importData: true, - dirName: 'personalization', + dirName: 'personalize', importOrder: ['attributes', 'audiences', 'events', 'experiences'], project_id: '', projects: { diff --git a/packages/contentstack-import/src/import/modules/personalization.ts b/packages/contentstack-import/src/import/modules/personalize.ts similarity index 85% rename from packages/contentstack-import/src/import/modules/personalization.ts rename to packages/contentstack-import/src/import/modules/personalize.ts index 71f9f29dbe..f8bf81ab51 100644 --- a/packages/contentstack-import/src/import/modules/personalization.ts +++ b/packages/contentstack-import/src/import/modules/personalize.ts @@ -2,13 +2,13 @@ import { Import, LogType } from '@contentstack/cli-variants'; import { log } from '../../utils'; import { ImportConfig, ModuleClassParams } from '../../types'; -export default class ImportPersonalization { +export default class ImportPersonalize { private config: ImportConfig; - public personalizeConfig: ImportConfig['modules']['personalization']; + public personalizeConfig: ImportConfig['modules']['personalize']; constructor({ importConfig }: ModuleClassParams) { this.config = importConfig; - this.personalizeConfig = importConfig.modules.personalization; + this.personalizeConfig = importConfig.modules.personalize; } /** @@ -45,10 +45,10 @@ export default class ImportPersonalization { } } } catch (error) { - this.personalizeConfig.importData = false; // Stop personalization import if project creation fails + this.personalizeConfig.importData = false; // Stop personalize import if project creation fails log(this.config, error, 'error'); if (!this.personalizeConfig.importData) { - log(this.config, 'Skipping personalization migration...', 'warn'); + log(this.config, 'Skipping personalize migration...', 'warn'); } } } diff --git a/packages/contentstack-import/src/import/modules/variant-entries.ts b/packages/contentstack-import/src/import/modules/variant-entries.ts index 2dd4f99390..c699035e4b 100644 --- a/packages/contentstack-import/src/import/modules/variant-entries.ts +++ b/packages/contentstack-import/src/import/modules/variant-entries.ts @@ -14,16 +14,16 @@ import { export default class ImportVarientEntries { private config: ImportConfig; - public personalization: ImportConfig['modules']['personalization']; + public personalize: ImportConfig['modules']['personalize']; private projectMapperFilePath: string; constructor({ importConfig }: ModuleClassParams) { this.config = importConfig; - this.personalization = importConfig.modules.personalization; + this.personalize = importConfig.modules.personalize; this.projectMapperFilePath = path.resolve( sanitizePath(this.config.data), 'mapper', - sanitizePath(this.personalization.dirName), + sanitizePath(this.personalize.dirName), 'projects', 'projects.json', ); @@ -36,8 +36,8 @@ export default class ImportVarientEntries { async start(): Promise { try { const project = fsUtil.readFile(this.projectMapperFilePath) as ProjectStruct; - if (project && project.uid && this.personalization.importData) { - this.config.modules.personalization.project_id = project.uid; + if (project && project.uid) { + this.config.modules.personalize.project_id = project.uid; const helpers: ImportHelperMethodsConfig = { lookUpTerms, lookupAssets, diff --git a/packages/contentstack-import/src/types/default-config.ts b/packages/contentstack-import/src/types/default-config.ts index 8b5390be37..4a39aff817 100644 --- a/packages/contentstack-import/src/types/default-config.ts +++ b/packages/contentstack-import/src/types/default-config.ts @@ -122,7 +122,7 @@ export default interface DefaultConfig { fileName: string; dependencies?: Modules[]; }; - personalization: { + personalize: { baseURL: Record; dirName: string; importData: boolean; diff --git a/packages/contentstack-import/src/types/index.ts b/packages/contentstack-import/src/types/index.ts index e0a82835f7..dab9d5beda 100644 --- a/packages/contentstack-import/src/types/index.ts +++ b/packages/contentstack-import/src/types/index.ts @@ -49,7 +49,7 @@ export type Modules = | 'labels' | 'marketplace-apps' | 'taxonomies' - | 'personalization' + | 'personalize' | 'variant-entries'; export type ModuleClassParams = { diff --git a/packages/contentstack-variants/.gitignore b/packages/contentstack-variants/.gitignore index a9c2ebe564..e0f971471f 100644 --- a/packages/contentstack-variants/.gitignore +++ b/packages/contentstack-variants/.gitignore @@ -7,4 +7,5 @@ /yarn.lock node_modules .DS_Store -coverage \ No newline at end of file +coverage +/tsconfig.tsbuildinfo \ No newline at end of file diff --git a/packages/contentstack-variants/src/export/attributes.ts b/packages/contentstack-variants/src/export/attributes.ts index 1c1192413b..9fa7643a74 100644 --- a/packages/contentstack-variants/src/export/attributes.ts +++ b/packages/contentstack-variants/src/export/attributes.ts @@ -2,26 +2,26 @@ import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; import { sanitizePath } from '@contentstack/cli-utilities'; import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils'; -import { PersonalizationConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types'; +import { PersonalizeConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types'; export default class ExportAttributes extends PersonalizationAdapter { private attributesConfig: AttributesConfig; private attributesFolderPath: string; private attributes: Record[]; - public personalizationConfig: PersonalizationConfig; + public personalizeConfig: PersonalizeConfig; constructor(readonly exportConfig: ExportConfig) { super({ config: exportConfig, - baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name], + baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name], headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id }, }); - this.personalizationConfig = exportConfig.modules.personalization; + this.personalizeConfig = exportConfig.modules.personalize; this.attributesConfig = exportConfig.modules.attributes; this.attributesFolderPath = pResolve( sanitizePath(exportConfig.data), sanitizePath(exportConfig.branchName || ''), - sanitizePath(this.personalizationConfig.dirName), + sanitizePath(this.personalizeConfig.dirName), sanitizePath(this.attributesConfig.dirName), ); this.attributes = []; diff --git a/packages/contentstack-variants/src/export/audiences.ts b/packages/contentstack-variants/src/export/audiences.ts index f63bf1c981..7530de1546 100644 --- a/packages/contentstack-variants/src/export/audiences.ts +++ b/packages/contentstack-variants/src/export/audiences.ts @@ -2,26 +2,26 @@ import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils'; -import { PersonalizationConfig, ExportConfig, AudienceStruct, AudiencesConfig } from '../types'; +import { PersonalizeConfig, ExportConfig, AudienceStruct, AudiencesConfig } from '../types'; export default class ExportAudiences extends PersonalizationAdapter { private audiencesConfig: AudiencesConfig; private audiencesFolderPath: string; private audiences: Record[]; - public personalizationConfig: PersonalizationConfig; + public personalizeConfig: PersonalizeConfig; constructor(readonly exportConfig: ExportConfig) { super({ config: exportConfig, - baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name], + baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name], headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id }, }); - this.personalizationConfig = exportConfig.modules.personalization; + this.personalizeConfig = exportConfig.modules.personalize; this.audiencesConfig = exportConfig.modules.audiences; this.audiencesFolderPath = pResolve( exportConfig.data, exportConfig.branchName || '', - this.personalizationConfig.dirName, + this.personalizeConfig.dirName, this.audiencesConfig.dirName, ); this.audiences = []; diff --git a/packages/contentstack-variants/src/export/events.ts b/packages/contentstack-variants/src/export/events.ts index f125b0e41f..08bce71fa1 100644 --- a/packages/contentstack-variants/src/export/events.ts +++ b/packages/contentstack-variants/src/export/events.ts @@ -2,26 +2,26 @@ import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils'; -import { PersonalizationConfig, ExportConfig, EventStruct, EventsConfig } from '../types'; +import { PersonalizeConfig, ExportConfig, EventStruct, EventsConfig } from '../types'; export default class ExportEvents extends PersonalizationAdapter { private eventsConfig: EventsConfig; private eventsFolderPath: string; private events: Record[]; - public personalizationConfig: PersonalizationConfig; + public personalizeConfig: PersonalizeConfig; constructor(readonly exportConfig: ExportConfig) { super({ config: exportConfig, - baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name], + baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name], headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id }, }); - this.personalizationConfig = exportConfig.modules.personalization; + this.personalizeConfig = exportConfig.modules.personalize; this.eventsConfig = exportConfig.modules.events; this.eventsFolderPath = pResolve( exportConfig.data, exportConfig.branchName || '', - this.personalizationConfig.dirName, + this.personalizeConfig.dirName, this.eventsConfig.dirName, ); this.events = []; diff --git a/packages/contentstack-variants/src/export/experiences.ts b/packages/contentstack-variants/src/export/experiences.ts index fee1d5ef3c..25d9a8420c 100644 --- a/packages/contentstack-variants/src/export/experiences.ts +++ b/packages/contentstack-variants/src/export/experiences.ts @@ -1,16 +1,16 @@ import * as path from 'path'; import { sanitizePath } from '@contentstack/cli-utilities'; -import { PersonalizationConfig, ExportConfig, ExperienceStruct } from '../types'; +import { PersonalizeConfig, ExportConfig, ExperienceStruct } from '../types'; import { formatError, fsUtil, log, PersonalizationAdapter } from '../utils'; export default class ExportExperiences extends PersonalizationAdapter { private experiencesFolderPath: string; public exportConfig: ExportConfig; - public personalizationConfig: PersonalizationConfig; + public personalizeConfig: PersonalizeConfig; constructor(exportConfig: ExportConfig) { super({ config: exportConfig, - baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name], + baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name], headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id }, cmaConfig: { baseURL: exportConfig.region.cma + `/v3`, @@ -18,11 +18,11 @@ export default class ExportExperiences extends PersonalizationAdapter { private projectFolderPath: string; public exportConfig: ExportConfig; - public personalizationConfig: PersonalizationConfig; + public personalizeConfig: PersonalizeConfig; constructor(exportConfig: ExportConfig) { super({ config: exportConfig, - baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name], + baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name], headers: { authtoken: exportConfig.auth_token, organization_uid: exportConfig.org_uid }, }); this.exportConfig = exportConfig; - this.personalizationConfig = exportConfig.modules.personalization; + this.personalizeConfig = exportConfig.modules.personalize; this.projectFolderPath = path.resolve( sanitizePath(exportConfig.data), sanitizePath(exportConfig.branchName || ''), - sanitizePath(this.personalizationConfig.dirName), + sanitizePath(this.personalizeConfig.dirName), 'projects', ); } diff --git a/packages/contentstack-variants/src/import/attribute.ts b/packages/contentstack-variants/src/import/attribute.ts index 3d1e513bff..fd21548232 100644 --- a/packages/contentstack-variants/src/import/attribute.ts +++ b/packages/contentstack-variants/src/import/attribute.ts @@ -9,19 +9,23 @@ export default class Attribute extends PersonalizationAdapter { private attrMapperDirPath: string; private attributesUidMapperPath: string; private attributesUidMapper: Record; - private personalizationConfig: ImportConfig['modules']['personalization']; - private attributeConfig: ImportConfig['modules']['personalization']['attributes']; + private personalizeConfig: ImportConfig['modules']['personalize']; + private attributeConfig: ImportConfig['modules']['personalize']['attributes']; constructor(public readonly config: ImportConfig, private readonly log: LogType = console.log) { const conf: APIConfig = { config, - baseURL: config.modules.personalization.baseURL[config.region.name], - headers: { 'X-Project-Uid': config.modules.personalization.project_id, authtoken: config.auth_token }, + baseURL: config.modules.personalize.baseURL[config.region.name], + headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token }, }; super(Object.assign(config, conf)); - this.personalizationConfig = this.config.modules.personalization; - this.attributeConfig = this.personalizationConfig.attributes; - this.mapperDirPath = resolve(sanitizePath(this.config.backupDir), 'mapper', sanitizePath(this.personalizationConfig.dirName)); + this.personalizeConfig = this.config.modules.personalize; + this.attributeConfig = this.personalizeConfig.attributes; + this.mapperDirPath = resolve( + sanitizePath(this.config.backupDir), + 'mapper', + sanitizePath(this.personalizeConfig.dirName), + ); this.attrMapperDirPath = resolve(sanitizePath(this.mapperDirPath), sanitizePath(this.attributeConfig.dirName)); this.attributesUidMapperPath = resolve(sanitizePath(this.attrMapperDirPath), 'uid-mapping.json'); this.attributesUidMapper = {}; @@ -35,7 +39,12 @@ export default class Attribute extends PersonalizationAdapter { await fsUtil.makeDirectory(this.attrMapperDirPath); const { dirName, fileName } = this.attributeConfig; - const attributesPath = resolve(sanitizePath(this.config.data), sanitizePath(this.personalizationConfig.dirName), sanitizePath(dirName), sanitizePath(fileName)); + const attributesPath = resolve( + sanitizePath(this.config.data), + sanitizePath(this.personalizeConfig.dirName), + sanitizePath(dirName), + sanitizePath(fileName), + ); if (existsSync(attributesPath)) { try { @@ -43,10 +52,19 @@ export default class Attribute extends PersonalizationAdapter { for (const attribute of attributes) { const { key, name, description, uid } = attribute; - const attributeRes = await this.createAttribute({ key, name, description }); - //map old attribute uid to new attribute uid - //mapper file is used to check whether attribute created or not before creating audience - this.attributesUidMapper[uid] = attributeRes?.uid ?? ''; + // skip creating preset attributes, as they are already present in the system + if (attribute.__type === 'PRESET') { + continue; + } + try { + const attributeRes = await this.createAttribute({ key, name, description }); + //map old attribute uid to new attribute uid + //mapper file is used to check whether attribute created or not before creating audience + this.attributesUidMapper[uid] = attributeRes?.uid ?? ''; + } catch (error) { + this.log(this.config, `Failed to create attribute ${name}!`, 'error'); + this.log(this.config, error, 'error'); + } } fsUtil.writeFile(this.attributesUidMapperPath, this.attributesUidMapper); diff --git a/packages/contentstack-variants/src/import/audiences.ts b/packages/contentstack-variants/src/import/audiences.ts index 5812ad853a..be414a8c25 100644 --- a/packages/contentstack-variants/src/import/audiences.ts +++ b/packages/contentstack-variants/src/import/audiences.ts @@ -10,24 +10,32 @@ export default class Audiences extends PersonalizationAdapter { private attributesMapperPath: string; private audiencesUidMapperPath: string; private audiencesUidMapper: Record; - private personalizationConfig: ImportConfig['modules']['personalization']; - private audienceConfig: ImportConfig['modules']['personalization']['audiences']; - public attributeConfig: ImportConfig['modules']['personalization']['attributes']; + private personalizeConfig: ImportConfig['modules']['personalize']; + private audienceConfig: ImportConfig['modules']['personalize']['audiences']; + public attributeConfig: ImportConfig['modules']['personalize']['attributes']; constructor(public readonly config: ImportConfig, private readonly log: LogType = console.log) { const conf: APIConfig = { config, - baseURL: config.modules.personalization.baseURL[config.region.name], - headers: { 'X-Project-Uid': config.modules.personalization.project_id, authtoken: config.auth_token }, + baseURL: config.modules.personalize.baseURL[config.region.name], + headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token }, }; super(Object.assign(config, conf)); - this.personalizationConfig = this.config.modules.personalization; - this.audienceConfig = this.personalizationConfig.audiences; - this.attributeConfig = this.personalizationConfig.attributes; - this.mapperDirPath = resolve(sanitizePath(this.config.backupDir), 'mapper', sanitizePath(this.personalizationConfig.dirName)); + this.personalizeConfig = this.config.modules.personalize; + this.audienceConfig = this.personalizeConfig.audiences; + this.attributeConfig = this.personalizeConfig.attributes; + this.mapperDirPath = resolve( + sanitizePath(this.config.backupDir), + 'mapper', + sanitizePath(this.personalizeConfig.dirName), + ); this.audienceMapperDirPath = resolve(sanitizePath(this.mapperDirPath), sanitizePath(this.audienceConfig.dirName)); this.audiencesUidMapperPath = resolve(sanitizePath(this.audienceMapperDirPath), 'uid-mapping.json'); - this.attributesMapperPath = resolve(sanitizePath(this.mapperDirPath), sanitizePath(this.attributeConfig.dirName), 'uid-mapping.json'); + this.attributesMapperPath = resolve( + sanitizePath(this.mapperDirPath), + sanitizePath(this.attributeConfig.dirName), + 'uid-mapping.json', + ); this.audiencesUidMapper = {}; } @@ -39,7 +47,12 @@ export default class Audiences extends PersonalizationAdapter { await fsUtil.makeDirectory(this.audienceMapperDirPath); const { dirName, fileName } = this.audienceConfig; - const audiencesPath = resolve(sanitizePath(this.config.data), sanitizePath(this.personalizationConfig.dirName), sanitizePath(dirName), sanitizePath(fileName)); + const audiencesPath = resolve( + sanitizePath(this.config.data), + sanitizePath(this.personalizeConfig.dirName), + sanitizePath(dirName), + sanitizePath(fileName), + ); if (existsSync(audiencesPath)) { try { @@ -48,14 +61,19 @@ export default class Audiences extends PersonalizationAdapter { for (const audience of audiences) { let { name, definition, description, uid } = audience; - //check whether reference attributes exists or not - if (definition.rules?.length) { - definition.rules = lookUpAttributes(definition.rules, attributesUid); + try { + //check whether reference attributes exists or not + if (definition.rules?.length) { + definition.rules = lookUpAttributes(definition.rules, attributesUid); + } + const audienceRes = await this.createAudience({ definition, name, description }); + //map old audience uid to new audience uid + //mapper file is used to check whether audience created or not before creating experience + this.audiencesUidMapper[uid] = audienceRes?.uid ?? ''; + } catch (error) { + this.log(this.config, `Failed to create audience uid: ${uid}, name: ${name}`, 'error'); + this.log(this.config, error, 'error'); } - const audienceRes = await this.createAudience({ definition, name, description }); - //map old audience uid to new audience uid - //mapper file is used to check whether audience created or not before creating experience - this.audiencesUidMapper[uid] = audienceRes?.uid ?? ''; } fsUtil.writeFile(this.audiencesUidMapperPath, this.audiencesUidMapper); diff --git a/packages/contentstack-variants/src/import/events.ts b/packages/contentstack-variants/src/import/events.ts index d87d3b93fd..25d7de178f 100644 --- a/packages/contentstack-variants/src/import/events.ts +++ b/packages/contentstack-variants/src/import/events.ts @@ -9,19 +9,23 @@ export default class Events extends PersonalizationAdapter { private eventMapperDirPath: string; private eventsUidMapperPath: string; private eventsUidMapper: Record; - private personalizationConfig: ImportConfig['modules']['personalization']; - private eventsConfig: ImportConfig['modules']['personalization']['events']; + private personalizeConfig: ImportConfig['modules']['personalize']; + private eventsConfig: ImportConfig['modules']['personalize']['events']; constructor(public readonly config: ImportConfig, private readonly log: LogType = console.log) { const conf: APIConfig = { config, - baseURL: config.modules.personalization.baseURL[config.region.name], - headers: { 'X-Project-Uid': config.modules.personalization.project_id, authtoken: config.auth_token }, + baseURL: config.modules.personalize.baseURL[config.region.name], + headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token }, }; super(Object.assign(config, conf)); - this.personalizationConfig = this.config.modules.personalization; - this.eventsConfig = this.personalizationConfig.events; - this.mapperDirPath = resolve(sanitizePath(this.config.backupDir), 'mapper', sanitizePath(this.personalizationConfig.dirName)); + this.personalizeConfig = this.config.modules.personalize; + this.eventsConfig = this.personalizeConfig.events; + this.mapperDirPath = resolve( + sanitizePath(this.config.backupDir), + 'mapper', + sanitizePath(this.personalizeConfig.dirName), + ); this.eventMapperDirPath = resolve(sanitizePath(this.mapperDirPath), sanitizePath(this.eventsConfig.dirName)); this.eventsUidMapperPath = resolve(sanitizePath(this.eventMapperDirPath), 'uid-mapping.json'); this.eventsUidMapper = {}; @@ -35,7 +39,12 @@ export default class Events extends PersonalizationAdapter { await fsUtil.makeDirectory(this.eventMapperDirPath); const { dirName, fileName } = this.eventsConfig; - const eventsPath = resolve(sanitizePath(this.config.data), sanitizePath(this.personalizationConfig.dirName), sanitizePath(dirName), sanitizePath(fileName)); + const eventsPath = resolve( + sanitizePath(this.config.data), + sanitizePath(this.personalizeConfig.dirName), + sanitizePath(dirName), + sanitizePath(fileName), + ); if (existsSync(eventsPath)) { try { @@ -43,8 +52,13 @@ export default class Events extends PersonalizationAdapter { for (const event of events) { const { key, description, uid } = event; - const eventsResponse = await this.createEvents({ key, description }); - this.eventsUidMapper[uid] = eventsResponse?.uid ?? ''; + try { + const eventsResponse = await this.createEvents({ key, description }); + this.eventsUidMapper[uid] = eventsResponse?.uid ?? ''; + } catch (error) { + this.log(this.config, `failed to create event uid: ${uid}`, 'error'); + this.log(this.config, error, 'error'); + } } fsUtil.writeFile(this.eventsUidMapperPath, this.eventsUidMapper); diff --git a/packages/contentstack-variants/src/import/experiences.ts b/packages/contentstack-variants/src/import/experiences.ts index d30c8911a9..2021f5179b 100644 --- a/packages/contentstack-variants/src/import/experiences.ts +++ b/packages/contentstack-variants/src/import/experiences.ts @@ -37,37 +37,37 @@ export default class Experiences extends PersonalizationAdapter { private pendingVariantAndVariantGrpForExperience: string[]; private audiencesUid: Record; private eventsUid: Record; - private personalizationConfig: ImportConfig['modules']['personalization']; - private audienceConfig: ImportConfig['modules']['personalization']['audiences']; - private experienceConfig: ImportConfig['modules']['personalization']['experiences']; + private personalizeConfig: ImportConfig['modules']['personalize']; + private audienceConfig: ImportConfig['modules']['personalize']['audiences']; + private experienceConfig: ImportConfig['modules']['personalize']['experiences']; constructor(public readonly config: ImportConfig, private readonly log: LogType = console.log) { const conf: APIConfig = { config, - baseURL: config.modules.personalization.baseURL[config.region.name], - headers: { 'X-Project-Uid': config.modules.personalization.project_id, authtoken: config.auth_token }, + baseURL: config.modules.personalize.baseURL[config.region.name], + headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token }, cmaConfig: { baseURL: config.region.cma + `/v3`, headers: { authtoken: config.auth_token, api_key: config.apiKey }, }, }; super(Object.assign(config, conf)); - this.personalizationConfig = this.config.modules.personalization; + this.personalizeConfig = this.config.modules.personalize; this.experiencesDirPath = resolve( sanitizePath(this.config.data), - sanitizePath(this.personalizationConfig.dirName), - sanitizePath(this.personalizationConfig.experiences.dirName), + sanitizePath(this.personalizeConfig.dirName), + sanitizePath(this.personalizeConfig.experiences.dirName), ); this.experiencesPath = join( sanitizePath(this.experiencesDirPath), - sanitizePath(this.personalizationConfig.experiences.fileName), + sanitizePath(this.personalizeConfig.experiences.fileName), ); - this.experienceConfig = this.personalizationConfig.experiences; - this.audienceConfig = this.personalizationConfig.audiences; + this.experienceConfig = this.personalizeConfig.experiences; + this.audienceConfig = this.personalizeConfig.audiences; this.mapperDirPath = resolve( sanitizePath(this.config.backupDir), 'mapper', - sanitizePath(this.personalizationConfig.dirName), + sanitizePath(this.personalizeConfig.dirName), ); this.expMapperDirPath = resolve(sanitizePath(this.mapperDirPath), sanitizePath(this.experienceConfig.dirName)); this.experiencesUidMapperPath = resolve(sanitizePath(this.expMapperDirPath), 'uid-mapping.json'); @@ -84,7 +84,7 @@ export default class Experiences extends PersonalizationAdapter { this.experienceCTsPath = resolve(sanitizePath(this.experiencesDirPath), 'experiences-content-types.json'); this.experienceVariantsIdsPath = resolve( sanitizePath(this.config.data), - sanitizePath(this.personalizationConfig.dirName), + sanitizePath(this.personalizeConfig.dirName), sanitizePath(this.experienceConfig.dirName), 'experiences-variants-ids.json', ); @@ -144,9 +144,10 @@ export default class Experiences extends PersonalizationAdapter { if (jobRes) this.log(this.config, this.$t(this.messages.CREATE_SUCCESS, { module: 'Variant & Variant groups' }), 'info'); - if (this.personalizationConfig.importData) { + if (this.personalizeConfig.importData) { this.log(this.config, this.messages.UPDATING_CT_IN_EXP, 'info'); await this.attachCTsInExperience(); + this.log(this.config, this.messages.UPDATED_CT_IN_EXP, 'info'); } await this.createVariantIdMapper(); @@ -220,9 +221,9 @@ export default class Experiences extends PersonalizationAdapter { } /** - * function to validate if all variant groups and variants have been created using personalization background job - * store the variant groups data in mapper/personalization/experiences/cms-variant-groups.json and the variants data - * in mapper/personalization/experiences/cms-variants.json. If not, invoke validateVariantGroupAndVariantsCreated after some delay. + * function to validate if all variant groups and variants have been created using personalize background job + * store the variant groups data in mapper/personalize/experiences/cms-variant-groups.json and the variants data + * in mapper/personalize/experiences/cms-variants.json. If not, invoke validateVariantGroupAndVariantsCreated after some delay. * @param retryCount Counter to track the number of times the function has been called * @returns */ @@ -249,7 +250,7 @@ export default class Experiences extends PersonalizationAdapter { ); return this.validateVariantGroupAndVariantsCreated(retryCount); } else { - this.log(this.config, this.messages.PERSONALIZATION_JOB_FAILURE, 'error'); + this.log(this.config, this.messages.PERSONALIZE_JOB_FAILURE, 'error'); fsUtil.writeFile(this.failedCmsExpPath, this.pendingVariantAndVariantGrpForExperience); return false; } @@ -274,8 +275,8 @@ export default class Experiences extends PersonalizationAdapter { Object.entries(this.experiencesUidMapper).map(async ([oldExpUid, newExpUid]) => { if (experienceCTsMap[oldExpUid]?.length) { // Filter content types that were created - const updatedContentTypes = experienceCTsMap[oldExpUid].filter((ct: any) => - this.createdCTs.includes(ct?.uid), + const updatedContentTypes = experienceCTsMap[oldExpUid].filter( + (ct: any) => this.createdCTs.includes(ct?.uid) && ct.status === 'linked', ); if (updatedContentTypes?.length) { const { variant_groups: [variantGroup] = [] } = diff --git a/packages/contentstack-variants/src/import/project.ts b/packages/contentstack-variants/src/import/project.ts index 5de48e851f..0741785e49 100644 --- a/packages/contentstack-variants/src/import/project.ts +++ b/packages/contentstack-variants/src/import/project.ts @@ -9,14 +9,14 @@ export default class Project extends PersonalizationAdapter { constructor(public readonly config: ImportConfig, private readonly log: LogType = console.log) { const conf: APIConfig = { config, - baseURL: config.modules.personalization.baseURL[config.region.name], + baseURL: config.modules.personalize.baseURL[config.region.name], headers: { organization_uid: config.org_uid, authtoken: config.auth_token }, }; super(Object.assign(config, conf)); this.projectMapperFolderPath = pResolve( sanitizePath(this.config.backupDir), 'mapper', - sanitizePath(this.config.modules.personalization.dirName), + sanitizePath(this.config.modules.personalize.dirName), 'projects', ); } @@ -26,15 +26,15 @@ export default class Project extends PersonalizationAdapter { * data. */ async import() { - const personalization = this.config.modules.personalization; - const { dirName, fileName } = personalization.projects; - const projectPath = join(sanitizePath(this.config.data), sanitizePath(personalization.dirName), sanitizePath(dirName), sanitizePath(fileName)); + const personalize = this.config.modules.personalize; + const { dirName, fileName } = personalize.projects; + const projectPath = join(sanitizePath(this.config.data), sanitizePath(personalize.dirName), sanitizePath(dirName), sanitizePath(fileName)); if (existsSync(projectPath)) { const projects = JSON.parse(readFileSync(projectPath, 'utf8')) as CreateProjectInput[]; if (!projects || projects.length < 1) { - this.config.modules.personalization.importData = false; // Stop personalization import if stack not connected to any project + this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project this.log(this.config, 'No project found!', 'info'); return; } @@ -46,7 +46,7 @@ export default class Project extends PersonalizationAdapter { description: project.description, connectedStackApiKey: this.config.apiKey, }).catch(async (error) => { - if (error === 'personalization.PROJECTS.DUPLICATE_NAME') { + if (error === 'personalization.PROJECTS.DUPLICATE_NAME' || error === 'personalize.PROJECTS.DUPLICATE_NAME') { const projectName = await askProjectName('Copy Of ' + (newName || project.name)); return await createProject(projectName); } @@ -56,15 +56,15 @@ export default class Project extends PersonalizationAdapter { }; const projectRes = await createProject(this.config.personalizeProjectName); - this.config.modules.personalization.project_id = projectRes.uid; - this.config.modules.personalization.importData = true; + this.config.modules.personalize.project_id = projectRes.uid; + this.config.modules.personalize.importData = true; await fsUtil.makeDirectory(this.projectMapperFolderPath); fsUtil.writeFile(pResolve(sanitizePath(this.projectMapperFolderPath), 'projects.json'), projectRes); this.log(this.config, `Project Created Successfully: ${projectRes.uid}`, 'info'); } } else { - this.config.modules.personalization.importData = false; // Stop personalization import if stack not connected to any project + this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project this.log(this.config, 'No project found!', 'info'); } } diff --git a/packages/contentstack-variants/src/import/variant-entries.ts b/packages/contentstack-variants/src/import/variant-entries.ts index 50e899c4bd..c4f4c75176 100644 --- a/packages/contentstack-variants/src/import/variant-entries.ts +++ b/packages/contentstack-variants/src/import/variant-entries.ts @@ -29,7 +29,7 @@ export default class VariantEntries extends VariantAdapter; - public personalizationConfig: ImportConfig['modules']['personalization']; + public personalizeConfig: ImportConfig['modules']['personalize']; public taxonomies!: Record; public assetUrlMapper!: Record; @@ -51,13 +51,22 @@ export default class VariantEntries extends VariantAdapter; @@ -141,9 +155,22 @@ export default class VariantEntries extends VariantAdapter; } & AnyProperty; @@ -269,7 +269,7 @@ export interface ExportConfig extends DefaultConfig { region: any; } -export interface PersonalizationConfig { +export interface PersonalizeConfig { dirName: string; baseURL: Record; } diff --git a/packages/contentstack-variants/src/types/import-config.ts b/packages/contentstack-variants/src/types/import-config.ts index c534796acc..d46f32f098 100644 --- a/packages/contentstack-variants/src/types/import-config.ts +++ b/packages/contentstack-variants/src/types/import-config.ts @@ -12,7 +12,7 @@ export interface ImportDefaultConfig extends AnyProperty { dirName: string; fileName: string; }; - personalization: { + personalize: { baseURL: Record; dirName: string; importData: boolean; diff --git a/packages/contentstack-variants/src/types/variant-entry.ts b/packages/contentstack-variants/src/types/variant-entry.ts index adf10be0bb..5608cb21e2 100644 --- a/packages/contentstack-variants/src/types/variant-entry.ts +++ b/packages/contentstack-variants/src/types/variant-entry.ts @@ -3,11 +3,11 @@ import { AnyProperty } from './utils'; export type VariantEntryStruct = { uid: string; title: string; - variant_id: string; locale: string; _version: number; _variant: { - uid: string; + _uid: string; + _instance_uid: string; _change_set: string[]; _base_entry_version: number; }; diff --git a/packages/contentstack-variants/src/utils/audiences-helper.ts b/packages/contentstack-variants/src/utils/audiences-helper.ts index 2b6a7d4881..feb2ca0431 100644 --- a/packages/contentstack-variants/src/utils/audiences-helper.ts +++ b/packages/contentstack-variants/src/utils/audiences-helper.ts @@ -40,7 +40,7 @@ export const lookUpAudiences = ( } else if (experience.variants) { for (let index = experience.variants.length - 1; index >= 0; index--) { const expVariations = experience.variants[index]; - if (expVariations['__type'] === 'AudienceBasedVariation' && expVariations?.audiences?.length) { + if (expVariations['__type'] === 'SegmentedVariant' && expVariations?.audiences?.length) { updateAudiences(expVariations.audiences, audiencesUid); if (!expVariations.audiences.length) { experience.variants.splice(index, 1); diff --git a/packages/contentstack-variants/src/utils/error-helper.ts b/packages/contentstack-variants/src/utils/error-helper.ts index 36ceeb08de..58c087fbbc 100644 --- a/packages/contentstack-variants/src/utils/error-helper.ts +++ b/packages/contentstack-variants/src/utils/error-helper.ts @@ -22,5 +22,5 @@ function formatError(error: any): string { if (typeof error === 'object') { return Object.values(error).join(' '); } - return String(error); + return error; } diff --git a/packages/contentstack-variants/src/utils/personalization-api-adapter.ts b/packages/contentstack-variants/src/utils/personalization-api-adapter.ts index 40a24ac73f..81548955e1 100644 --- a/packages/contentstack-variants/src/utils/personalization-api-adapter.ts +++ b/packages/contentstack-variants/src/utils/personalization-api-adapter.ts @@ -208,10 +208,10 @@ export class PersonalizationAdapter extends AdapterHelper impl if (status >= 200 && status < 300) { return data; } - + const errorMsg = data?.errors ? formatErrors(data.errors) - : data?.error_message || data?.message || 'Something went wrong while processing variant entries request!'; + : data?.error || data?.error_message || data?.message || 'Something went wrong while processing variant entries request!'; throw errorMsg; } diff --git a/packages/contentstack-variants/src/utils/variant-api-adapter.ts b/packages/contentstack-variants/src/utils/variant-api-adapter.ts index 89d46c5c7f..9e25299576 100644 --- a/packages/contentstack-variants/src/utils/variant-api-adapter.ts +++ b/packages/contentstack-variants/src/utils/variant-api-adapter.ts @@ -184,6 +184,7 @@ export class VariantHttpClient extends AdapterHelper implement }); try { + this.apiClient.headers({ api_version: undefined }); const res = await this.apiClient.put(endpoint, { entry: input }); const data = this.handleVariantAPIRes(res); @@ -214,8 +215,7 @@ export class VariantHttpClient extends AdapterHelper implement const { entry_uid, content_type_uid } = options; let endpoint = `content_types/${content_type_uid}/entries/${entry_uid}/publish`; - const onSuccess = (response: any) => - resolve({ response, apiData: { entryUid: entry_uid, variantUid }, log }); + const onSuccess = (response: any) => resolve({ response, apiData: { entryUid: entry_uid, variantUid }, log }); const onReject = (error: any) => reject({ error, diff --git a/packages/contentstack-variants/tsconfig.tsbuildinfo b/packages/contentstack-variants/tsconfig.tsbuildinfo new file mode 100644 index 0000000000..d2b5f2c97d --- /dev/null +++ b/packages/contentstack-variants/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"root":["./src/index.ts"],"version":"5.6.2"} \ No newline at end of file