Skip to content

Commit 00cf33c

Browse files
Merge pull request #49 from contentstack/feat/DX-3618
feat: add publishing rules support
2 parents a7d3c56 + 756877b commit 00cf33c

45 files changed

Lines changed: 1406 additions & 319 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
fileignoreconfig:
22
- filename: pnpm-lock.yaml
3-
checksum: ce5abaaafcfa33bb71e4af691eb1f5786b7851bfb7f936712374251cbffe2a32
3+
checksum: 48a1b9aca69c8decfed0f5333c8f4a8fa4689f1cb9c00a91dd18532418ea910f
44
version: '1.0'

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.19.1",
4+
"version": "1.19.2",
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.15.1",
19+
"@contentstack/cli-cm-seed": "~1.15.2",
2020
"@contentstack/cli-command": "~1.8.1",
2121
"@contentstack/cli-config": "~1.20.2",
2222
"@contentstack/cli-utilities": "~1.18.2",

packages/contentstack-clone/package.json

Lines changed: 3 additions & 3 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.21.2",
4+
"version": "1.21.3",
55
"author": "Contentstack",
66
"bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
77
"dependencies": {
88
"@colors/colors": "^1.6.0",
9-
"@contentstack/cli-cm-export": "~1.24.2",
10-
"@contentstack/cli-cm-import": "~1.32.2",
9+
"@contentstack/cli-cm-export": "~1.25.0",
10+
"@contentstack/cli-cm-import": "~1.33.0",
1111
"@contentstack/cli-command": "~1.8.1",
1212
"@contentstack/cli-utilities": "~1.18.2",
1313
"@oclif/core": "^4.10.5",

packages/contentstack-export/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-export",
33
"description": "Contentstack CLI plugin to export content from stack",
4-
"version": "1.24.2",
4+
"version": "1.25.0",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {

packages/contentstack-export/src/commands/cm/stacks/export.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,14 @@ export default class ExportCommand extends Command {
121121
try {
122122
const { flags } = await this.parse(ExportCommand);
123123
const exportConfig = await setupExportConfig(flags);
124-
124+
125125
// Store apiKey in configHandler for session.json (return value not needed)
126126
createLogContext(
127127
this.context?.info?.command || 'cm:stacks:export',
128128
exportConfig.apiKey,
129-
exportConfig.authenticationMethod
129+
exportConfig.authenticationMethod,
130130
);
131-
131+
132132
// For log entries, only pass module (other fields are in session.json)
133133
exportConfig.context = { module: '' };
134134
//log.info(`Using Cli Version: ${this.context?.cliVersion}`, exportConfig.context);
@@ -143,9 +143,7 @@ export default class ExportCommand extends Command {
143143
if (!exportConfig.branches?.length) {
144144
writeExportMetaFile(exportConfig);
145145
}
146-
log.success(
147-
`The content of the stack ${exportConfig.apiKey} has been exported successfully!`,
148-
);
146+
log.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`);
149147
log.info(`The exported content has been stored at '${exportDir}'.`, exportConfig.context);
150148
log.success(`The log has been stored at '${getLogPath()}'.`, exportConfig.context);
151149
} catch (error) {
@@ -154,7 +152,6 @@ export default class ExportCommand extends Command {
154152
}
155153
}
156154

157-
158155
// Assign values to exportConfig
159156
private assignExportConfig(exportConfig: ExportConfig): void {
160157
// Note setting host to create cma client

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const config: DefaultConfig = {
3636
'content-types',
3737
'custom-roles',
3838
'workflows',
39+
'publishing-rules',
3940
'personalize',
4041
'entries',
4142
'labels',
@@ -86,6 +87,11 @@ const config: DefaultConfig = {
8687
fileName: 'workflows.json',
8788
invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'],
8889
},
90+
'publishing-rules': {
91+
dirName: 'workflows',
92+
fileName: 'publishing-rules.json',
93+
invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'],
94+
},
8995
globalfields: {
9096
dirName: 'global_fields',
9197
fileName: 'globalfields.json',

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
import * as path from 'path';
2-
import {
3-
ContentstackClient,
4-
handleAndLogError,
5-
messageHandler,
6-
log,
7-
sanitizePath,
8-
} from '@contentstack/cli-utilities';
2+
import { ContentstackClient, handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities';
93

104
import BaseClass from './base-class';
115
import { fsUtil, executeTask } from '../../utils';
@@ -86,7 +80,9 @@ export default class ContentTypesExport extends BaseClass {
8680
const contentTypeSearchResponse = await this.stackAPIClient.contentType().query(this.qs).find();
8781

8882
log.debug(
89-
`Fetched ${contentTypeSearchResponse.items?.length || 0} content types out of total ${contentTypeSearchResponse.count}`,
83+
`Fetched ${contentTypeSearchResponse.items?.length || 0} content types out of total ${
84+
contentTypeSearchResponse.count
85+
}`,
9086
this.exportConfig.context,
9187
);
9288

packages/contentstack-export/src/export/modules/custom-roles.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,26 @@ export default class ExportCustomRoles extends BaseClass {
3737
this.customRolesConfig.dirName,
3838
);
3939
log.debug(`Custom roles folder path is: ${this.rolesFolderPath}`, this.exportConfig.context);
40-
40+
4141
await fsUtil.makeDirectory(this.rolesFolderPath);
4242
log.debug('Custom roles directory created.', this.exportConfig.context);
43-
43+
4444
this.customRolesLocalesFilepath = pResolve(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName);
4545
log.debug(`Custom roles locales file path is: ${this.customRolesLocalesFilepath}`, this.exportConfig.context);
46-
46+
4747
await this.getCustomRoles();
4848
await this.getLocales();
4949
await this.getCustomRolesLocales();
50-
51-
log.debug(`Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles).length}`, this.exportConfig.context);
50+
51+
log.debug(
52+
`Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles).length}`,
53+
this.exportConfig.context,
54+
);
5255
}
5356

5457
async getCustomRoles(): Promise<void> {
5558
log.debug('Fetching all roles from the stack...', this.exportConfig.context);
56-
59+
5760
const roles = await this.stack
5861
.role()
5962
.fetchAll({ include_rules: true, include_permissions: true })
@@ -65,9 +68,12 @@ export default class ExportCustomRoles extends BaseClass {
6568
log.debug('An error occurred while fetching roles.', this.exportConfig.context);
6669
return handleAndLogError(err, { ...this.exportConfig.context });
6770
});
68-
71+
6972
const customRoles = roles.items.filter((role: any) => !this.existingRoles[role.name]);
70-
log.debug(`Found ${customRoles.length} custom roles from ${roles.items?.length || 0} total roles.`, this.exportConfig.context);
73+
log.debug(
74+
`Found ${customRoles.length} custom roles from ${roles.items?.length || 0} total roles.`,
75+
this.exportConfig.context,
76+
);
7177

7278
if (!customRoles.length) {
7379
log.info(messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context);
@@ -79,15 +85,15 @@ export default class ExportCustomRoles extends BaseClass {
7985
log.info(messageHandler.parse('ROLES_EXPORTING_ROLE', role?.name), this.exportConfig.context);
8086
this.customRoles[role.uid] = role;
8187
});
82-
88+
8389
const customRolesFilePath = pResolve(this.rolesFolderPath, this.customRolesConfig.fileName);
8490
log.debug(`Writing custom roles to: ${customRolesFilePath}.`, this.exportConfig.context);
8591
fsUtil.writeFile(customRolesFilePath, this.customRoles);
8692
}
8793

8894
async getLocales() {
8995
log.debug('Fetching locales for custom roles mapping...', this.exportConfig.context);
90-
96+
9197
const locales = await this.stack
9298
.locale()
9399
.query({})
@@ -100,25 +106,28 @@ export default class ExportCustomRoles extends BaseClass {
100106
log.debug('An error occurred while fetching locales.', this.exportConfig.context);
101107
return handleAndLogError(err, { ...this.exportConfig.context });
102108
});
103-
109+
104110
for (const locale of locales.items) {
105111
log.debug(`Mapping locale: ${locale?.name} (${locale?.uid})`, this.exportConfig.context);
106112
this.sourceLocalesMap[locale.uid] = locale;
107113
}
108-
114+
109115
log.debug(`Mapped ${Object.keys(this.sourceLocalesMap).length} source locales.`, this.exportConfig.context);
110116
}
111117

112118
async getCustomRolesLocales() {
113119
log.debug('Processing custom roles locales mapping...', this.exportConfig.context);
114-
120+
115121
for (const role of values(this.customRoles)) {
116122
const customRole = role as Record<string, any>;
117123
log.debug(`Processing locales for custom role: ${customRole?.name}`, this.exportConfig.context);
118-
124+
119125
const rulesLocales = find(customRole.rules, (rule: any) => rule.module === 'locale');
120126
if (rulesLocales?.locales?.length) {
121-
log.debug(`Found ${rulesLocales.locales.length} locales for the role: ${customRole?.name}.`, this.exportConfig.context);
127+
log.debug(
128+
`Found ${rulesLocales.locales.length} locales for the role: ${customRole?.name}.`,
129+
this.exportConfig.context,
130+
);
122131
forEach(rulesLocales.locales, (locale: any) => {
123132
log.debug(`Adding locale ${locale} to the custom roles mapping.`, this.exportConfig.context);
124133
this.localesMap[locale] = 1;
@@ -128,7 +137,7 @@ export default class ExportCustomRoles extends BaseClass {
128137

129138
if (keys(this.localesMap)?.length) {
130139
log.debug(`Processing ${Object.keys(this.localesMap).length} mapped locales.`, this.exportConfig.context);
131-
140+
132141
for (const locale in this.localesMap) {
133142
if (this.sourceLocalesMap[locale] !== undefined) {
134143
const sourceLocale = this.sourceLocalesMap[locale] as Record<string, any>;
@@ -137,7 +146,7 @@ export default class ExportCustomRoles extends BaseClass {
137146
}
138147
this.localesMap[locale] = this.sourceLocalesMap[locale];
139148
}
140-
149+
141150
log.debug(`Writing custom roles locales to: ${this.customRolesLocalesFilepath}.`, this.exportConfig.context);
142151
fsUtil.writeFile(this.customRolesLocalesFilepath, this.localesMap);
143152
} else {

packages/contentstack-export/src/export/modules/environments.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default class ExportEnvironments extends BaseClass {
3535

3636
await fsUtil.makeDirectory(this.environmentsFolderPath);
3737
log.debug('Environments directory created.', this.exportConfig.context);
38-
38+
3939
await this.getEnvironments();
4040
log.debug(`Retrieved ${Object.keys(this.environments).length} environments.`, this.exportConfig.context);
4141

@@ -59,17 +59,17 @@ export default class ExportEnvironments extends BaseClass {
5959
} else {
6060
log.debug('Fetching environments with initial query...', this.exportConfig.context);
6161
}
62-
62+
6363
log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context);
64-
64+
6565
await this.stack
6666
.environment()
6767
.query(this.qs)
6868
.find()
6969
.then(async (data: any) => {
7070
const { items, count } = data;
7171
log.debug(`Fetched ${items?.length || 0} environments out of ${count} total.`, this.exportConfig.context);
72-
72+
7373
if (items?.length) {
7474
log.debug(`Processing ${items.length} environments.`, this.exportConfig.context);
7575
this.sanitizeAttribs(items);
@@ -92,16 +92,19 @@ export default class ExportEnvironments extends BaseClass {
9292

9393
sanitizeAttribs(environments: Record<string, string>[]) {
9494
log.debug(`Sanitizing ${environments.length} environments...`, this.exportConfig.context);
95-
95+
9696
for (let index = 0; index < environments?.length; index++) {
9797
const extUid = environments[index].uid;
9898
const envName = environments[index]?.name;
9999
log.debug(`Processing environment: ${envName} (${extUid})`, this.exportConfig.context);
100-
100+
101101
this.environments[extUid] = omit(environments[index], ['ACL']);
102-
log.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName ), this.exportConfig.context);
102+
log.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName), this.exportConfig.context);
103103
}
104-
105-
log.debug(`Sanitization complete. Total environments processed: ${Object.keys(this.environments).length}`, this.exportConfig.context);
104+
105+
log.debug(
106+
`Sanitization complete. Total environments processed: ${Object.keys(this.environments).length}`,
107+
this.exportConfig.context,
108+
);
106109
}
107110
}

packages/contentstack-export/src/export/modules/extensions.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default class ExportExtensions extends BaseClass {
2727

2828
async start(): Promise<void> {
2929
log.debug('Starting extensions export process...', this.exportConfig.context);
30-
30+
3131
this.extensionsFolderPath = pResolve(
3232
this.exportConfig.data,
3333
this.exportConfig.branchName || '',
@@ -37,7 +37,7 @@ export default class ExportExtensions extends BaseClass {
3737

3838
await fsUtil.makeDirectory(this.extensionsFolderPath);
3939
log.debug('Extensions directory created.', this.exportConfig.context);
40-
40+
4141
await this.getExtensions();
4242
log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions.`, this.exportConfig.context);
4343

@@ -48,7 +48,7 @@ export default class ExportExtensions extends BaseClass {
4848
log.debug(`Writing extensions to: ${extensionsFilePath}.`, this.exportConfig.context);
4949
fsUtil.writeFile(extensionsFilePath, this.extensions);
5050
log.success(
51-
messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length ),
51+
messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length),
5252
this.exportConfig.context,
5353
);
5454
}
@@ -61,17 +61,17 @@ export default class ExportExtensions extends BaseClass {
6161
} else {
6262
log.debug('Fetching extensions with initial query...', this.exportConfig.context);
6363
}
64-
64+
6565
log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context);
66-
66+
6767
await this.stack
6868
.extension()
6969
.query(this.qs)
7070
.find()
7171
.then(async (data: any) => {
7272
const { items, count } = data;
7373
log.debug(`Fetched ${items?.length || 0} extensions out of ${count}.`, this.exportConfig.context);
74-
74+
7575
if (items?.length) {
7676
log.debug(`Processing ${items.length} extensions...`, this.exportConfig.context);
7777
this.sanitizeAttribs(items);
@@ -94,16 +94,19 @@ export default class ExportExtensions extends BaseClass {
9494

9595
sanitizeAttribs(extensions: Record<string, string>[]) {
9696
log.debug(`Sanitizing ${extensions.length} extensions...`, this.exportConfig.context);
97-
97+
9898
for (let index = 0; index < extensions?.length; index++) {
9999
const extUid = extensions[index].uid;
100100
const extTitle = extensions[index]?.title;
101101
log.debug(`Processing extension: '${extTitle}' (UID: ${extUid})...`, this.exportConfig.context);
102-
102+
103103
this.extensions[extUid] = omit(extensions[index], ['SYS_ACL']);
104104
log.info(messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context);
105105
}
106-
107-
log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}.`, this.exportConfig.context);
106+
107+
log.debug(
108+
`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}.`,
109+
this.exportConfig.context,
110+
);
108111
}
109112
}

0 commit comments

Comments
 (0)