-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathversionobsoleteflows.ts
119 lines (90 loc) · 3.2 KB
/
versionobsoleteflows.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import * as os from 'os';
import { flags, SfdxCommand } from '@salesforce/command';
import { Messages, SfError } from '@salesforce/core';
import { AnyJson } from '@salesforce/ts-types';
import { readFileSync, writeFileSync } from 'fs';
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
import { promisify } from 'util';
import { exec } from 'child_process';
const syncExec = promisify(exec);
Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('nakama-plugin-sfdx', 'versionobsoleteflows');
const parseXml = (xmlContent) => {
return new XMLParser({
ignoreDeclaration: true,
attributeNamePrefix: '@_',
ignoreAttributes: false
}).parse(xmlContent);
};
const buildXml = (jsonObject) => {
return new XMLBuilder({
format: true,
attributeNamePrefix: '@_',
ignoreAttributes: false
}).build(jsonObject);
};
const getFlowMembers = (packageTypes) => {
const flowType = packageTypes.filter((type) => type.name === 'Flow')[0];
if (!flowType) {
return; // there is no Flow type in the destructiveChanges.xml
}
let flowMembers = flowType.members;
if (!flowMembers) {
return; // there are no Flow members in the destructiveChanges.xml
}
if (!Array.isArray(flowMembers)) {
flowMembers = [flowMembers];
}
return flowMembers.join("','");
};
const getObsoleteFlowVersions = async (flowMembers) => {
try {
const result = (
await syncExec(
`sfdx force:data:soql:query --query "SELECT Definition.DeveloperName, VersionNumber FROM Flow WHERE Status = 'Obsolete' AND Definition.DeveloperName IN ('${flowMembers}')" --usetoolingapi --json`
)
).stdout;
return JSON.parse(result).result.records;
} catch (e) {
const stdout = JSON.parse(e.stdout);
throw new SfError(stdout.message, stdout.name);
}
};
const replaceFlowMembersWithObsoleteVersions = (obsoleteFlowVersions, packageTypes) => {
const flowsWithVersions = obsoleteFlowVersions.map(
(version) => `${version.Definition.DeveloperName}-${version.VersionNumber}`
);
const index = packageTypes.findIndex((type) => type.name === 'Flow');
packageTypes[index].members = flowsWithVersions;
};
export default class Versionobsoleteflows extends SfdxCommand {
public static description = messages.getMessage('commandDescription');
public static examples = messages.getMessage('examples').split(os.EOL);
public static args = [{ name: 'file' }];
protected static flagsConfig = {
path: flags.filepath({
char: 'p',
description: messages.getMessage('pathToFileFlagDescription'),
required: true
})
};
public async run(): Promise<AnyJson> {
const fileContent = readFileSync(this.flags.path, { encoding: 'utf-8' });
const jsonContent = parseXml(fileContent);
let packageTypes = jsonContent.Package.types;
if (!packageTypes) {
return; // destructiveChanges.xml is empty
}
if (!Array.isArray(packageTypes)) {
packageTypes = [packageTypes];
}
const flowMembers = getFlowMembers(packageTypes);
if (flowMembers) {
const obsoleteFlowVersions = await getObsoleteFlowVersions(flowMembers);
replaceFlowMembersWithObsoleteVersions(obsoleteFlowVersions, packageTypes);
const xmlContent = buildXml(jsonContent);
writeFileSync(this.flags.path, xmlContent);
}
return { success: true };
}
}