Skip to content

Commit c6c700e

Browse files
authored
Merge pull request #2284 from contentstack/feat/DX-3809
skip composition type and compositions if studio project failed to import
2 parents 9fd8c6f + efd318d commit c6c700e

File tree

12 files changed

+155
-42
lines changed

12 files changed

+155
-42
lines changed

.talismanrc

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
fileignoreconfig:
22
- filename: package-lock.json
3-
checksum: ad5cedb62e915203b1a3561b231889f945452d48da12dbdca13c346f93258a7a
3+
checksum: 25bcbb12c701b53f222c599fa8ce53f347853a1d96257cee79b5cf5878e50015
44
- filename: pnpm-lock.yaml
5-
checksum: afa28e14d5080f836632e31930ed3a950bfefb4c874acd163eb6849139b2034e
5+
checksum: 448638c016e13e936e2dfa8297076162b0662de198908d994665579bab8f4b36
66
- filename: packages/contentstack-import-setup/test/unit/backup-handler.test.ts
77
checksum: 0582d62b88834554cf12951c8690a73ef3ddbb78b82d2804d994cf4148e1ef93
88
- filename: packages/contentstack-import-setup/test/config.json
@@ -66,7 +66,7 @@ fileignoreconfig:
6666
- filename: packages/contentstack-bulk-publish/src/producer/publish-unpublished-env.js
6767
checksum: 44dbc966df086f835fdca11cb305d0a5f448ca0be811c14b894e0024f9491385
6868
- filename: packages/contentstack-import/src/import/modules/entries.ts
69-
checksum: 0fa92065747da2ea3b02c666da5a0c6d3e74552c804a15578d9da0bfeb082615
69+
checksum: 290730774c61220645ec211b85b9e218cdbd8addc2d8fd8f061dfa5ede5b5c75
7070
- filename: packages/contentstack-utilities/src/logger/logger.ts
7171
checksum: 76429bc87e279624b386f00e7eb3f4ec25621ace7056289f812b9a076d6e184e
7272
- filename: packages/contentstack-bootstrap/src/bootstrap/utils.ts
@@ -109,8 +109,6 @@ fileignoreconfig:
109109
checksum: b0fa8088fcbb17510fa275bd0dde3f6f4246f2525741c30426f07dd62fe497b0
110110
- filename: packages/contentstack-audit/src/modules/content-types.ts
111111
checksum: ddf7b08e6a80af09c6a7019a637c26089fb76572c7c3d079a8af244b02985f16
112-
- filename: packages/contentstack-import/test/unit/commands/cm/stacks/import.test.ts
113-
checksum: b11e57f1b824d405f86438e9e7c59183f8c59b66b42d8d16dbeaf76195a30548
114112
- filename: packages/contentstack-import/test/unit/utils/asset-helper.test.ts
115113
checksum: 8e83200ac8028f9289ff1bd3a50d191b35c8e28f1854141c90fa1b0134d6bf8a
116114
- filename: packages/contentstack-import/test/unit/import/modules/marketplace-apps.test.ts
@@ -199,8 +197,6 @@ fileignoreconfig:
199197
checksum: 49dd8e754a0d3635585a74e943ab097593f061089a7cddc22683ec6caddbb3c5
200198
- filename: packages/contentstack-export/test/unit/export/modules/personalize.test.ts
201199
checksum: 83cf034fabee00b42b4243a8c0b8ba280ab7c1e68ffd741c49c31aaee8ca0315
202-
- filename: packages/contentstack-utilities/test/unit/logger.test.ts
203-
checksum: 11778d0252202c18a1ca6a38883d6e12fc324ff86ad0fe058bc2505f9cd66ba3
204200
- filename: packages/contentstack-audit/test/unit/audit-base-command.test.ts
205201
checksum: 17a16b4457c820494442f335d94d0949961e68e8ca72ca0f1fa9d4d0eeb0c17a
206202
- filename: packages/contentstack-import/src/import/modules/taxonomies.ts

package-lock.json

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/contentstack-bootstrap/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@contentstack/cli-cm-bootstrap",
33
"description": "Bootstrap contentstack apps",
4-
"version": "1.17.2",
4+
"version": "1.18.0",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"scripts": {
@@ -16,7 +16,7 @@
1616
"test:report": "nyc --reporter=lcov mocha \"test/**/*.test.js\""
1717
},
1818
"dependencies": {
19-
"@contentstack/cli-cm-seed": "~1.13.2",
19+
"@contentstack/cli-cm-seed": "~1.14.0",
2020
"@contentstack/cli-command": "~1.7.1",
2121
"@contentstack/cli-utilities": "~1.16.0",
2222
"@oclif/core": "^4.3.0",

packages/contentstack-clone/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "@contentstack/cli-cm-clone",
33
"description": "Contentstack stack clone plugin",
4-
"version": "1.18.1",
4+
"version": "1.19.0",
55
"author": "Contentstack",
66
"bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
77
"dependencies": {
88
"@colors/colors": "^1.6.0",
99
"@contentstack/cli-cm-export": "~1.22.2",
10-
"@contentstack/cli-cm-import": "~1.30.2",
10+
"@contentstack/cli-cm-import": "~1.31.0",
1111
"@contentstack/cli-command": "~1.7.1",
1212
"@contentstack/cli-utilities": "~1.16.0",
1313
"@oclif/core": "^4.3.0",

packages/contentstack-import/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@contentstack/cli-cm-import",
33
"description": "Contentstack CLI plugin to import content into stack",
4-
"version": "1.30.2",
4+
"version": "1.31.0",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {

packages/contentstack-import/src/config/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const config: DefaultConfig = {
3333
'stack',
3434
'assets',
3535
'taxonomies',
36+
'composable-studio',
3637
'extensions',
3738
'marketplace-apps',
3839
'global-fields',
@@ -44,7 +45,6 @@ const config: DefaultConfig = {
4445
'variant-entries',
4546
'labels',
4647
'webhooks',
47-
'composable-studio',
4848
],
4949
locales: {
5050
dirName: 'locales',

packages/contentstack-import/src/import/modules/composable-studio.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export default class ImportComposableStudio {
2020
private apiClient: HttpClient;
2121
private envUidMapperPath: string;
2222
private envUidMapper: Record<string, string>;
23+
private projectMapperPath: string;
2324

2425
constructor({ importConfig }: ModuleClassParams) {
2526
this.importConfig = importConfig;
@@ -28,6 +29,7 @@ export default class ImportComposableStudio {
2829

2930
// Setup paths
3031
this.composableStudioPath = join(this.importConfig.backupDir, this.composableStudioConfig.dirName);
32+
this.projectMapperPath = join(this.importConfig.backupDir, 'mapper', this.composableStudioConfig.dirName);
3133
this.composableStudioFilePath = join(this.composableStudioPath, this.composableStudioConfig.fileName);
3234
this.envUidMapperPath = join(this.importConfig.backupDir, 'mapper', 'environments', 'uid-mapping.json');
3335
this.envUidMapper = {};
@@ -244,6 +246,14 @@ export default class ImportComposableStudio {
244246
if (response.status >= 200 && response.status < 300) {
245247
projectCreated = true;
246248
log.debug(`Project created successfully with UID: ${response.data?.uid}`, this.importConfig.context);
249+
250+
// Create mapper directory if it doesn't exist
251+
await fsUtil.makeDirectory(this.projectMapperPath);
252+
253+
// write the project to file
254+
const projectFileSuccessPath = join(this.projectMapperPath, this.composableStudioConfig.fileName);
255+
fsUtil.writeFile(projectFileSuccessPath, response.data as unknown as Record<string, unknown>);
256+
log.debug(`Project written to: ${projectFileSuccessPath}`, this.importConfig.context);
247257
} else {
248258
throw new Error(`API call failed with status ${response.status}: ${JSON.stringify(response.data)}`);
249259
}

packages/contentstack-import/src/import/modules/content-types.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import * as path from 'path';
99
import { isEmpty, find, cloneDeep, map } from 'lodash';
1010
import { sanitizePath, log, handleAndLogError } from '@contentstack/cli-utilities';
11-
import { fsUtil, schemaTemplate, lookupExtension, lookUpTaxonomy } from '../../utils';
11+
import { fsUtil, schemaTemplate, lookupExtension, lookUpTaxonomy, fileHelper } from '../../utils';
1212
import { ImportConfig, ModuleClassParams } from '../../types';
1313
import BaseClass, { ApiOptions } from './base-class';
1414
import { updateFieldRules } from '../../utils/content-type-helper';
@@ -54,6 +54,8 @@ export default class ContentTypesImport extends BaseClass {
5454
public taxonomies: Record<string, unknown>;
5555
private extPendingPath: string;
5656
private isExtensionsUpdate = false;
57+
private composableStudioSuccessPath: string;
58+
private composableStudioExportPath: string;
5759

5860
constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
5961
super({ importConfig, stackAPIClient });
@@ -84,6 +86,26 @@ export default class ContentTypesImport extends BaseClass {
8486
['schema.json', 'true'],
8587
['.DS_Store', 'true'],
8688
]);
89+
90+
// Initialize composable studio paths if config exists
91+
if (this.importConfig.modules['composable-studio']) {
92+
this.composableStudioSuccessPath = path.join(
93+
sanitizePath(this.importConfig.data),
94+
'mapper',
95+
this.importConfig.modules['composable-studio'].dirName,
96+
this.importConfig.modules['composable-studio'].fileName,
97+
);
98+
99+
this.composableStudioExportPath = path.join(
100+
sanitizePath(this.importConfig.data),
101+
this.importConfig.modules['composable-studio'].dirName,
102+
this.importConfig.modules['composable-studio'].fileName,
103+
);
104+
} else {
105+
this.composableStudioSuccessPath = '';
106+
this.composableStudioExportPath = '';
107+
}
108+
87109
this.cTs = [];
88110
this.createdCTs = [];
89111
this.titleToUIdMap = new Map();
@@ -110,6 +132,38 @@ export default class ContentTypesImport extends BaseClass {
110132
}
111133
log.debug(`Found ${this.cTs.length} content types to import`, this.importConfig.context);
112134

135+
// If success file doesn't exist but export file does, skip the composition content type
136+
// Only check if composable studio paths are configured
137+
if (
138+
this.composableStudioSuccessPath &&
139+
this.composableStudioExportPath &&
140+
!fileHelper.fileExistsSync(this.composableStudioSuccessPath) &&
141+
fileHelper.fileExistsSync(this.composableStudioExportPath)
142+
) {
143+
const exportedProject = fileHelper.readFileSync(this.composableStudioExportPath) as {
144+
contentTypeUid: string;
145+
};
146+
147+
if (exportedProject?.contentTypeUid) {
148+
const originalCount = this.cTs.length;
149+
this.cTs = this.cTs.filter((ct: Record<string, unknown>) => {
150+
const shouldSkip = ct.uid === exportedProject.contentTypeUid;
151+
if (shouldSkip) {
152+
log.info(
153+
`Skipping content type '${ct.uid}' as Composable Studio project was not created successfully`,
154+
this.importConfig.context,
155+
);
156+
}
157+
return !shouldSkip;
158+
});
159+
160+
const skippedCount = originalCount - this.cTs.length;
161+
if (skippedCount > 0) {
162+
log.debug(`Filtered out ${skippedCount} composition content type(s) from import`, this.importConfig.context);
163+
}
164+
}
165+
}
166+
113167
await fsUtil.makeDirectory(this.cTsMapperPath);
114168
log.debug('Created content types mapper directory.', this.importConfig.context);
115169

packages/contentstack-import/src/import/modules/entries.ts

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ export default class EntriesImport extends BaseClass {
5757
public rteCTs: any;
5858
public rteCTsWithRef: any;
5959
public entriesForVariant: Array<{ content_type: string; locale: string; entry_uid: string }> = [];
60+
private composableStudioSuccessPath: string;
61+
private composableStudioExportPath: string;
6062

6163
constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
6264
super({ importConfig, stackAPIClient });
@@ -92,6 +94,26 @@ export default class EntriesImport extends BaseClass {
9294
sanitizePath(importConfig.modules.locales.dirName),
9395
sanitizePath(importConfig.modules.locales.fileName),
9496
);
97+
98+
// Initialize composable studio paths if config exists
99+
if (this.importConfig.modules['composable-studio']) {
100+
this.composableStudioSuccessPath = path.join(
101+
sanitizePath(this.importConfig.data),
102+
'mapper',
103+
this.importConfig.modules['composable-studio'].dirName,
104+
this.importConfig.modules['composable-studio'].fileName,
105+
);
106+
107+
this.composableStudioExportPath = path.join(
108+
sanitizePath(this.importConfig.data),
109+
this.importConfig.modules['composable-studio'].dirName,
110+
this.importConfig.modules['composable-studio'].fileName,
111+
);
112+
} else {
113+
this.composableStudioSuccessPath = '';
114+
this.composableStudioExportPath = '';
115+
}
116+
95117
this.importConcurrency = this.entriesConfig.importConcurrency || importConfig.importConcurrency;
96118
this.entriesUidMapper = {};
97119
this.modifiedCTs = [];
@@ -116,6 +138,40 @@ export default class EntriesImport extends BaseClass {
116138
return;
117139
}
118140
log.debug(`Found ${this.cTs.length} content types for entry import`, this.importConfig.context);
141+
// If success file doesn't exist but export file does, skip the composition entries
142+
// Only check if composable studio paths are configured
143+
if (
144+
this.composableStudioSuccessPath &&
145+
this.composableStudioExportPath &&
146+
!fileHelper.fileExistsSync(this.composableStudioSuccessPath) &&
147+
fileHelper.fileExistsSync(this.composableStudioExportPath)
148+
) {
149+
const exportedProject = fileHelper.readFileSync(this.composableStudioExportPath) as {
150+
contentTypeUid: string;
151+
};
152+
153+
if (exportedProject?.contentTypeUid) {
154+
const originalCount = this.cTs.length;
155+
this.cTs = this.cTs.filter((ct: Record<string, unknown>) => {
156+
const shouldSkip = ct.uid === exportedProject.contentTypeUid;
157+
if (shouldSkip) {
158+
log.info(
159+
`Skipping entries for content type '${ct.uid}' as Composable Studio project was not created successfully`,
160+
this.importConfig.context,
161+
);
162+
}
163+
return !shouldSkip;
164+
});
165+
166+
const skippedCount = originalCount - this.cTs.length;
167+
if (skippedCount > 0) {
168+
log.debug(
169+
`Filtered out ${skippedCount} composition content type(s) from entry import`,
170+
this.importConfig.context,
171+
);
172+
}
173+
}
174+
}
119175

120176
this.installedExtensions = (
121177
(fsUtil.readFile(this.marketplaceAppMapperPath) as any) || { extension_uid: {} }
@@ -124,10 +180,7 @@ export default class EntriesImport extends BaseClass {
124180

125181
this.assetUidMapper = (fsUtil.readFile(this.assetUidMapperPath) as Record<string, any>) || {};
126182
this.assetUrlMapper = (fsUtil.readFile(this.assetUrlMapperPath) as Record<string, any>) || {};
127-
log.debug(
128-
`Loaded asset mappings – UIDs: ${Object.keys(this.assetUidMapper).length}`,
129-
this.importConfig.context,
130-
);
183+
log.debug(`Loaded asset mappings – UIDs: ${Object.keys(this.assetUidMapper).length}`, this.importConfig.context);
131184

132185
this.taxonomies = (fsUtil.readFile(this.taxonomiesPath) || {}) as Record<string, any>;
133186
log.debug('Loaded taxonomy data for entry processing.', this.importConfig.context);

packages/contentstack-seed/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"name": "@contentstack/cli-cm-seed",
33
"description": "create a Stack from existing content types, entries, assets, etc.",
4-
"version": "1.13.2",
4+
"version": "1.14.0",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {
8-
"@contentstack/cli-cm-import": "1.30.2",
8+
"@contentstack/cli-cm-import": "~1.31.0",
99
"@contentstack/cli-command": "~1.7.1",
1010
"@contentstack/cli-utilities": "~1.16.0",
1111
"@contentstack/management": "~1.22.0",

0 commit comments

Comments
 (0)