Skip to content

Commit fde3605

Browse files
author
naman-contentstack
committed
feat: add publishing rules support
1 parent 4beaeab commit fde3605

13 files changed

Lines changed: 469 additions & 3 deletions

File tree

.talismanrc

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
fileignoreconfig:
2-
- filename: pnpm-lock.yaml
3-
checksum: 97cb862682f7dec430f2079ac686bbfec4fc22c080c8d50cf14c4e2249bb8c8c
2+
- filename: packages/contentstack-import/src/config/index.ts
3+
checksum: 541136c45d6a74010e4999389dd9c06a0e6b7b74bea62087d66c50b17e8e5d11
4+
- filename: packages/contentstack-variants/src/types/export-config.ts
5+
checksum: 5707cf07e6777d31d4730567d861300a94b16b8a97e47fb3d804efb67f214aab
6+
- filename: packages/contentstack-import/src/types/index.ts
7+
checksum: 068079597f11b6460cca4005ca2345d7c2a954dc516a14c51782c631652cd5a3
8+
- filename: packages/contentstack-export/src/config/index.ts
9+
checksum: 2c811d2bd7b6657b567fd120cfaf05306ca751109c070bf7b49c18d06b211764
10+
- filename: packages/contentstack-export/src/types/index.ts
11+
checksum: 173b811f93b12da873d5860275a85438d2f78a1c4e387c77ec5246f1c0231da2
12+
- filename: packages/contentstack-export/src/types/default-config.ts
13+
checksum: 0cc62919207384ec710ea3f8a3445d6e5bd78cc2c5306b9e74aaeec688eb028d
14+
- filename: packages/contentstack-import/src/types/default-config.ts
15+
checksum: 0db51c83ce44e31d51ae881a0f0bfc2cd39cb15bd333fe3b1e9f19292d575d91
16+
- filename: packages/contentstack-import/src/import/modules/publishing-rules.ts
17+
checksum: 429a803bc18e691db93bae3df1714071d0face6441b82cb938a83e8bf94ae14c
418
version: '1.0'

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',
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import omit from 'lodash/omit';
2+
import isEmpty from 'lodash/isEmpty';
3+
import { resolve as pResolve } from 'node:path';
4+
import { handleAndLogError, log } from '@contentstack/cli-utilities';
5+
6+
import BaseClass from './base-class';
7+
import { fsUtil } from '../../utils';
8+
import { PublishingRulesConfig, ModuleClassParams } from '../../types';
9+
10+
export default class ExportPublishingRules extends BaseClass {
11+
private readonly publishingRules: Record<string, Record<string, unknown>> = {};
12+
private readonly publishingRulesConfig: PublishingRulesConfig;
13+
private publishingRulesFolderPath: string;
14+
private readonly qs: { include_count: boolean; skip?: number };
15+
16+
constructor({ exportConfig, stackAPIClient }: ModuleClassParams) {
17+
super({ exportConfig, stackAPIClient });
18+
this.publishingRulesConfig = exportConfig.modules['publishing-rules'];
19+
this.qs = { include_count: true };
20+
this.exportConfig.context.module = 'publishing-rules';
21+
}
22+
23+
async start(): Promise<void> {
24+
this.publishingRulesFolderPath = pResolve(
25+
this.exportConfig.data,
26+
this.exportConfig.branchName || '',
27+
this.publishingRulesConfig.dirName,
28+
);
29+
log.debug(`Publishing rules folder path: ${this.publishingRulesFolderPath}`, this.exportConfig.context);
30+
31+
await fsUtil.makeDirectory(this.publishingRulesFolderPath);
32+
log.debug('Created publishing rules directory', this.exportConfig.context);
33+
34+
await this.fetchAllPublishingRules();
35+
36+
if (isEmpty(this.publishingRules)) {
37+
log.info('No Publishing Rules found', this.exportConfig.context);
38+
return;
39+
}
40+
41+
const outPath = pResolve(this.publishingRulesFolderPath, this.publishingRulesConfig.fileName);
42+
fsUtil.writeFile(outPath, this.publishingRules);
43+
log.success(
44+
`Publishing rules exported successfully! Total count: ${Object.keys(this.publishingRules).length}`,
45+
this.exportConfig.context,
46+
);
47+
}
48+
49+
private async fetchAllPublishingRules(skip = 0): Promise<void> {
50+
try {
51+
if (skip > 0) {
52+
this.qs.skip = skip;
53+
}
54+
55+
const data: { items?: Record<string, unknown>[]; count?: number } = await this.stack
56+
.workflow()
57+
.publishRule()
58+
.fetchAll(this.qs);
59+
60+
const items = data.items ?? [];
61+
const total = data.count ?? items.length;
62+
63+
if (!items.length) {
64+
log.debug('No publishing rules returned for this page', this.exportConfig.context);
65+
return;
66+
}
67+
68+
for (const rule of items) {
69+
const uid = rule.uid as string | undefined;
70+
if (uid) {
71+
this.publishingRules[uid] = omit(rule, this.publishingRulesConfig.invalidKeys) as Record<
72+
string,
73+
unknown
74+
>;
75+
}
76+
}
77+
78+
const nextSkip = skip + items.length;
79+
if (nextSkip < total) {
80+
await this.fetchAllPublishingRules(nextSkip);
81+
}
82+
} catch (error: unknown) {
83+
handleAndLogError(error as Error, { ...this.exportConfig.context });
84+
}
85+
}
86+
}

packages/contentstack-export/src/types/default-config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ export default interface DefaultConfig {
6767
invalidKeys: string[];
6868
dependencies?: Modules[];
6969
};
70+
'publishing-rules': {
71+
dirName: string;
72+
fileName: string;
73+
invalidKeys: string[];
74+
dependencies?: Modules[];
75+
limit?: number;
76+
};
7077
globalfields: {
7178
dirName: string;
7279
fileName: string;

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export type Modules =
4646
| 'content-types'
4747
| 'custom-roles'
4848
| 'workflows'
49+
| 'publishing-rules'
4950
| 'labels'
5051
| 'marketplace-apps'
5152
| 'taxonomies'
@@ -117,6 +118,14 @@ export interface WorkflowConfig {
117118
limit?: number;
118119
}
119120

121+
export interface PublishingRulesConfig {
122+
dirName: string;
123+
fileName: string;
124+
invalidKeys: string[];
125+
dependencies?: Modules[];
126+
limit?: number;
127+
}
128+
120129
export interface CustomRoleConfig {
121130
dirName: string;
122131
fileName: string;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const config: DefaultConfig = {
4141
'personalize',
4242
'custom-roles',
4343
'workflows',
44+
'publishing-rules',
4445
'entries',
4546
'variant-entries',
4647
'labels',
@@ -88,6 +89,11 @@ const config: DefaultConfig = {
8889
fileName: 'workflows.json',
8990
invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'],
9091
},
92+
'publishing-rules': {
93+
dirName: 'workflows',
94+
fileName: 'publishing-rules.json',
95+
invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'],
96+
},
9197
assets: {
9298
dirName: 'assets',
9399
assetBatchLimit: 1,
@@ -455,5 +461,7 @@ const config: DefaultConfig = {
455461
globalModules: ['webhooks'],
456462
entriesPublish: true,
457463
};
464+
export const PUBLISHING_RULES_APPROVERS_SKIP_MSG =
465+
'Skipping import of publish rule approver(s) (roles/users); reconfigure approvers on the target stack.';
458466

459467
export default config;

packages/contentstack-import/src/import/modules/base-class.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ export type ApiModuleType =
5151
| 'delete-entries'
5252
| 'create-taxonomies'
5353
| 'create-terms'
54-
| 'import-taxonomy';
54+
| 'import-taxonomy'
55+
| 'create-publishing-rule';
5556

5657
export type ApiOptions = {
5758
uid?: string;
@@ -374,6 +375,13 @@ export default abstract class BaseClass {
374375
.create({ workflow: apiData as WorkflowData })
375376
.then(onSuccess)
376377
.catch(onReject);
378+
case 'create-publishing-rule':
379+
return this.stack
380+
.workflow()
381+
.publishRule()
382+
.create({ publishing_rule: omit(apiData, ['uid']) as any })
383+
.then(onSuccess)
384+
.catch(onReject);
377385
case 'create-custom-role':
378386
return this.stack
379387
.role()

0 commit comments

Comments
 (0)