@ds-sfdc/sfparty 1.0.0-0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -2
- package/package.json +1 -1
- package/src/index.js +259 -306
- package/src/meta/yargs.js +75 -0
- package/src/party/combine.js +17 -4
- package/src/party/split.js +18 -6
- package/src/lib/permset/combine.js +0 -286
- package/src/lib/permset/split.js +0 -287
- package/src/lib/profile/combine.js +0 -309
- package/src/lib/profile/split.js +0 -983
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const options = {
|
|
2
|
+
type: {
|
|
3
|
+
demand: false,
|
|
4
|
+
alias: 'type',
|
|
5
|
+
description: 'type of metadata to $1',
|
|
6
|
+
demandOption: false,
|
|
7
|
+
type: 'string',
|
|
8
|
+
},
|
|
9
|
+
format: {
|
|
10
|
+
demand: true,
|
|
11
|
+
alias: 'format',
|
|
12
|
+
default: 'yaml',
|
|
13
|
+
description: 'type of output',
|
|
14
|
+
demandOption: true,
|
|
15
|
+
type: 'string',
|
|
16
|
+
},
|
|
17
|
+
name: {
|
|
18
|
+
alias: 'n',
|
|
19
|
+
description: 'name of metadata file to $1',
|
|
20
|
+
demandOption: false,
|
|
21
|
+
type: 'string',
|
|
22
|
+
},
|
|
23
|
+
source: {
|
|
24
|
+
demand: false,
|
|
25
|
+
alias: 's',
|
|
26
|
+
description: 'package directory path specified in sfdx-project.json',
|
|
27
|
+
type: 'string',
|
|
28
|
+
},
|
|
29
|
+
target: {
|
|
30
|
+
demand: false,
|
|
31
|
+
alias: 't',
|
|
32
|
+
description: 'target path to directory to create yaml/json files',
|
|
33
|
+
type: 'string',
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getOptions(type) {
|
|
38
|
+
let optionObj = {... options}
|
|
39
|
+
Object.keys(optionObj).forEach(key => {
|
|
40
|
+
Object.keys(optionObj[key]).forEach(subKey => {
|
|
41
|
+
if (typeof optionObj[key][subKey] == 'string') {
|
|
42
|
+
optionObj[key][subKey] = optionObj[key][subKey].replaceAll('$1', type)
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return optionObj
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const splitOptions = getOptions('split')
|
|
51
|
+
export const combineOptions = getOptions('combine')
|
|
52
|
+
|
|
53
|
+
const examples = [
|
|
54
|
+
['$0 $1'],
|
|
55
|
+
['$0 $1 --type=profile'],
|
|
56
|
+
['$0 $1 --type="profile,label"'],
|
|
57
|
+
['$0 $1 --type=permset --name="Permission Set Name"'],
|
|
58
|
+
['--source=packageDir --target=dir/dir'],
|
|
59
|
+
['name portion of file: [name].profile-meta.xml'],
|
|
60
|
+
['Example: --name="Admin" for Admin.profile-meta.xml'],
|
|
61
|
+
['\nCommands not supporting name or all parameters:'],
|
|
62
|
+
['$0 $1 --type=label'],
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
function getExamples(type) {
|
|
66
|
+
let exArr = [...examples]
|
|
67
|
+
exArr.forEach(arrItem => {
|
|
68
|
+
arrItem[0] = arrItem[0].replaceAll('$1', type)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return exArr
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const splitExamples = getExamples('split')
|
|
75
|
+
export const combineExamples = getExamples('combine')
|
package/src/party/combine.js
CHANGED
|
@@ -8,6 +8,12 @@ import * as xml2js from 'xml2js'
|
|
|
8
8
|
import * as fileUtils from '../lib/fileUtils.js'
|
|
9
9
|
|
|
10
10
|
const spinner = cliSpinners['dots']
|
|
11
|
+
const processed = {
|
|
12
|
+
total: 0,
|
|
13
|
+
errors: 0,
|
|
14
|
+
current: 0,
|
|
15
|
+
type: undefined,
|
|
16
|
+
}
|
|
11
17
|
|
|
12
18
|
export class Combine {
|
|
13
19
|
#type = undefined
|
|
@@ -33,6 +39,7 @@ export class Combine {
|
|
|
33
39
|
this.targetDir = config.targetDir
|
|
34
40
|
this.metaDir = config.metaDir
|
|
35
41
|
this.sequence = config.sequence
|
|
42
|
+
this.total = config.total
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
get metadataDefinition() {
|
|
@@ -102,13 +109,19 @@ export class Combine {
|
|
|
102
109
|
})
|
|
103
110
|
|
|
104
111
|
function getXML(that) {
|
|
112
|
+
if (processed.type != that.#root) {
|
|
113
|
+
processed.current = 0
|
|
114
|
+
processed.type = that.#root
|
|
115
|
+
}
|
|
116
|
+
processed.current++
|
|
117
|
+
|
|
105
118
|
that.#startTime = process.hrtime.bigint()
|
|
106
|
-
that.#spinnerMessage = `[%1] of ${
|
|
119
|
+
that.#spinnerMessage = `[%1] of ${that.total} - ${that.#root}: [%4]${chalk.yellowBright('[%5]')}[%2][%3]`
|
|
107
120
|
|
|
108
121
|
that.#types.forEach(key => {
|
|
109
122
|
// display message
|
|
110
123
|
logUpdate(that.#spinnerMessage
|
|
111
|
-
.replace('[%1]', that.sequence.toString().padStart(
|
|
124
|
+
.replace('[%1]', that.sequence.toString().padStart(that.total.toString().length, ' '))
|
|
112
125
|
.replace('[%2]', `\n${chalk.magentaBright(nextFrame(that))} ${key}`)
|
|
113
126
|
.replace('[%3]', `${that.#errorMessage}`)
|
|
114
127
|
.replace('[%4]', `${global.icons.working} `)
|
|
@@ -157,7 +170,7 @@ export class Combine {
|
|
|
157
170
|
// iterate over fileList
|
|
158
171
|
fileList.forEach((file, index) => {
|
|
159
172
|
logUpdate(that.#spinnerMessage
|
|
160
|
-
.replace('[%1]', that.sequence.toString().padStart(
|
|
173
|
+
.replace('[%1]', that.sequence.toString().padStart(that.total.toString().length, ' '))
|
|
161
174
|
.replace('[%2]', `\n${chalk.magentaBright(nextFrame(that))} ${key} - ${index + 1} of ${fileList.length} - ${chalk.magentaBright(file)}`)
|
|
162
175
|
.replace('[%3]', `${that.#errorMessage}`)
|
|
163
176
|
.replace('[%4]', `${global.icons.working} `)
|
|
@@ -292,7 +305,7 @@ export class Combine {
|
|
|
292
305
|
let stateIcon = (that.#errorMessage == '') ? global.icons.success : global.icons.fail
|
|
293
306
|
|
|
294
307
|
logUpdate(that.#spinnerMessage
|
|
295
|
-
.replace('[%1]', that.sequence.toString().padStart(
|
|
308
|
+
.replace('[%1]', that.sequence.toString().padStart(that.total.toString().length, ' '))
|
|
296
309
|
.replace('[%2]', `. Processed in ${durationMessage}.`)
|
|
297
310
|
.replace('[%3]', `${that.#errorMessage}`)
|
|
298
311
|
.replace('[%4]', `${stateIcon} `)
|
package/src/party/split.js
CHANGED
|
@@ -12,6 +12,12 @@ import cliSpinners from 'cli-spinners'
|
|
|
12
12
|
import * as fileUtils from '../lib/fileUtils.js'
|
|
13
13
|
|
|
14
14
|
const spinner = cliSpinners['dots']
|
|
15
|
+
const processed = {
|
|
16
|
+
total: 0,
|
|
17
|
+
errors: 0,
|
|
18
|
+
current: 0,
|
|
19
|
+
type: undefined,
|
|
20
|
+
}
|
|
15
21
|
|
|
16
22
|
export class Split {
|
|
17
23
|
#type = undefined
|
|
@@ -33,6 +39,7 @@ export class Split {
|
|
|
33
39
|
this.targetDir = config.targetDir
|
|
34
40
|
this.metaFilePath = config.metaFilePath
|
|
35
41
|
this.sequence = config.sequence
|
|
42
|
+
this.total = config.total
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
get metadataDefinition() {
|
|
@@ -117,13 +124,18 @@ export class Split {
|
|
|
117
124
|
})
|
|
118
125
|
|
|
119
126
|
function processJSON(that, json, baseDir) {
|
|
120
|
-
that.#spinnerMessage = `[%1] of ${
|
|
127
|
+
that.#spinnerMessage = `[%1] of ${that.total} - ${that.#root}: [%4]${chalk.yellowBright(that.#fileName.shortName)}[%2][%3]`
|
|
121
128
|
|
|
122
129
|
let targetDir = baseDir
|
|
130
|
+
if (processed.type != that.#root) {
|
|
131
|
+
processed.current = 0
|
|
132
|
+
processed.type = that.#root
|
|
133
|
+
}
|
|
134
|
+
processed.current++
|
|
123
135
|
Object.keys(json).forEach(key => {
|
|
124
|
-
that.sequence =
|
|
136
|
+
that.sequence = processed.current
|
|
125
137
|
logUpdate(that.#spinnerMessage
|
|
126
|
-
.replace('[%1]', that.sequence.toString().padStart(
|
|
138
|
+
.replace('[%1]', that.sequence.toString().padStart(that.total.toString().length, ' '))
|
|
127
139
|
.replace('[%2]', `\n${chalk.magentaBright(nextFrame(that))} ${key}`)
|
|
128
140
|
.replace('[%3]', `${that.#errorMessage}`)
|
|
129
141
|
.replace('[%4]', `${global.icons.working} `)
|
|
@@ -157,9 +169,9 @@ export class Split {
|
|
|
157
169
|
}
|
|
158
170
|
mainInfo.main.name = that.#fileName.shortName
|
|
159
171
|
that.metadataDefinition.main.forEach(key => {
|
|
160
|
-
that.sequence =
|
|
172
|
+
that.sequence = processed.current
|
|
161
173
|
logUpdate(that.#spinnerMessage
|
|
162
|
-
.replace('[%1]', that.sequence.toString().padStart(
|
|
174
|
+
.replace('[%1]', that.sequence.toString().padStart(that.total.toString().length, ' '))
|
|
163
175
|
.replace('[%2]', `\n${chalk.magentaBright(nextFrame(that))} ${key}`)
|
|
164
176
|
.replace('[%3]', `${that.#errorMessage}`)
|
|
165
177
|
.replace('[%4]', `${global.icons.working} `)
|
|
@@ -182,7 +194,7 @@ export class Split {
|
|
|
182
194
|
let durationMessage = `${executionTime.seconds}.${executionTime.milliseconds}s`
|
|
183
195
|
let stateIcon = (that.#errorMessage == '') ? global.icons.success : global.icons.fail
|
|
184
196
|
logUpdate(that.#spinnerMessage
|
|
185
|
-
.replace('[%1]', that.sequence.toString().padStart(
|
|
197
|
+
.replace('[%1]', that.sequence.toString().padStart(that.total.toString().length, ' '))
|
|
186
198
|
.replace('[%2]', `. Processed in ${durationMessage}.`)
|
|
187
199
|
.replace('[%3]', `${that.#errorMessage}`)
|
|
188
200
|
.replace('[%4]', `${stateIcon} `)
|
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import os from 'os'
|
|
3
|
-
import { readFileSync, writeFileSync, utimesSync } from 'fs'
|
|
4
|
-
import logUpdate from 'log-update'
|
|
5
|
-
import chalk from 'chalk'
|
|
6
|
-
import convertHrtime from 'convert-hrtime'
|
|
7
|
-
import cliSpinners from 'cli-spinners'
|
|
8
|
-
import * as fileUtils from '../fileUtils.js'
|
|
9
|
-
import { permsetDefinition } from '../../meta/PermissionSets.js'
|
|
10
|
-
import * as xml2js from 'xml2js'
|
|
11
|
-
import * as yaml from 'js-yaml'
|
|
12
|
-
|
|
13
|
-
const spinner = cliSpinners['dots']
|
|
14
|
-
|
|
15
|
-
export class Permset {
|
|
16
|
-
#xml = ''
|
|
17
|
-
#types = []
|
|
18
|
-
#spinnerMessage = ''
|
|
19
|
-
#index = 0
|
|
20
|
-
#startTime = 0
|
|
21
|
-
#fileName = ''
|
|
22
|
-
#errorMessage = ''
|
|
23
|
-
#fileStats
|
|
24
|
-
|
|
25
|
-
constructor(config) {
|
|
26
|
-
this.sourceDir = config.sourceDir
|
|
27
|
-
this.targetDir = config.targetDir
|
|
28
|
-
this.metaDir = config.metaDir
|
|
29
|
-
this.sequence = config.sequence
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
combine() {
|
|
33
|
-
return new Promise((resolve, reject) => {
|
|
34
|
-
const that = this
|
|
35
|
-
if (!fileUtils.directoryExists(path.join(that.sourceDir, that.metaDir))) reject(that.metaDir)
|
|
36
|
-
|
|
37
|
-
that.metaDir = fileUtils.getDirectories(that.sourceDir).find(element => element.toLowerCase() == that.metaDir.toLowerCase())
|
|
38
|
-
|
|
39
|
-
that.#xml = `<?xml version="1.0" encoding="UTF-8"?>${os.EOL}`
|
|
40
|
-
that.#xml += `<PermissionSet xmlns="https://soap.sforce.com/2006/04/metadata">${os.EOL}`
|
|
41
|
-
|
|
42
|
-
permsetDefinition.main.forEach(key => { that.#types.push(key) })
|
|
43
|
-
permsetDefinition.singleFiles.forEach(key => { that.#types.push(key) })
|
|
44
|
-
permsetDefinition.directories.forEach(key => { that.#types.push(key) })
|
|
45
|
-
that.#types.sort()
|
|
46
|
-
|
|
47
|
-
setFileName(that)
|
|
48
|
-
processPermSet(that)
|
|
49
|
-
|
|
50
|
-
saveXML(that)
|
|
51
|
-
resolve(that.metaDir)
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
function setFileName(that) {
|
|
55
|
-
const fileName = path.join(that.sourceDir, that.metaDir, `main.${global.format}`)
|
|
56
|
-
if (fileUtils.fileExists(fileName)) {
|
|
57
|
-
const data = readFileSync(fileName, { encoding: 'utf8', flag: 'r' })
|
|
58
|
-
const result = (global.format == 'yaml') ? yaml.load(data) : JSON.parse(data)
|
|
59
|
-
that.#fileStats = fileUtils.fileInfo(fileName).stats
|
|
60
|
-
that.#fileName = path.join(that.targetDir, result.name + '.permissionset-meta.xml')
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function processPermSet(that) {
|
|
65
|
-
that.#startTime = process.hrtime.bigint()
|
|
66
|
-
that.#spinnerMessage = `[%1] of ${global.processed.total} - Permission Set: [%4]${chalk.yellowBright(that.metaDir)}[%2][%3]`
|
|
67
|
-
logUpdate(that.#spinnerMessage
|
|
68
|
-
.replace('[%1]', that.sequence.toString().padStart(global.processed.total.toString().length, ' '))
|
|
69
|
-
.replace('[%2]', '')
|
|
70
|
-
.replace('[%3]', '')
|
|
71
|
-
.replace('[%4]', '')
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
that.#types.forEach(key => {
|
|
75
|
-
let myLocation
|
|
76
|
-
if (permsetDefinition.main.includes(key)) {
|
|
77
|
-
myLocation = 'main'
|
|
78
|
-
} else if (permsetDefinition.directories.includes(key)) {
|
|
79
|
-
myLocation = 'directory'
|
|
80
|
-
} else if (permsetDefinition.singleFiles.includes(key)) {
|
|
81
|
-
myLocation = 'file'
|
|
82
|
-
}
|
|
83
|
-
logUpdate(that.#spinnerMessage
|
|
84
|
-
.replace('[%1]', that.sequence.toString().padStart(global.processed.total.toString().length, ' '))
|
|
85
|
-
.replace('[%2]', `\n${chalk.magentaBright(nextFrame(that))} ${key}`)
|
|
86
|
-
.replace('[%3]', `${that.#errorMessage}`)
|
|
87
|
-
.replace('[%4]', `${global.icons.working} `)
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
switch (myLocation) {
|
|
91
|
-
case 'main':
|
|
92
|
-
processMain(that, key)
|
|
93
|
-
break
|
|
94
|
-
case 'file':
|
|
95
|
-
processFile(that, key)
|
|
96
|
-
break
|
|
97
|
-
case 'directory':
|
|
98
|
-
processDirectory(that, key)
|
|
99
|
-
break
|
|
100
|
-
}
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function processMain(that, key) {
|
|
105
|
-
const fileName = path.join(that.sourceDir, that.metaDir, `main.${global.format}`)
|
|
106
|
-
if (fileUtils.fileExists(fileName)) {
|
|
107
|
-
const data = readFileSync(fileName, { encoding: 'utf8', flag: 'r' })
|
|
108
|
-
const result = (global.format == 'yaml') ? yaml.load(data) : JSON.parse(data)
|
|
109
|
-
if (result[key] !== undefined) that.#xml += `\t<${key}>${result[key]}</${key}>${os.EOL}`
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function processFile(that, key) {
|
|
114
|
-
const fileName = path.join(that.sourceDir, that.metaDir, `${key}.${global.format}`)
|
|
115
|
-
if (fileUtils.fileExists(fileName)) {
|
|
116
|
-
if (permsetDefinition.singleFiles.includes(key)) {
|
|
117
|
-
genericXML(that, key)
|
|
118
|
-
} else {
|
|
119
|
-
that.#errorMessage += `\n${global.icons.warn} Not processed: ${key}`
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function processDirectory(that, key) {
|
|
125
|
-
switch (key) {
|
|
126
|
-
case 'objectPermissions':
|
|
127
|
-
objectPermissions(that, key)
|
|
128
|
-
break
|
|
129
|
-
default:
|
|
130
|
-
if (permsetDefinition.directories.includes(key)) {
|
|
131
|
-
genericDirectoryXML(that, key)
|
|
132
|
-
break
|
|
133
|
-
} else {
|
|
134
|
-
that.#errorMessage += `\n${global.icons.warn} Not processed: ${key}`
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function getTimeDiff(startTime, endTime = process.hrtime.bigint()) {
|
|
141
|
-
const diff = BigInt(endTime) - BigInt(startTime)
|
|
142
|
-
let executionTime = convertHrtime(diff)
|
|
143
|
-
executionTime.seconds = Math.round(executionTime.seconds)
|
|
144
|
-
executionTime.milliseconds = Math.round(executionTime.milliseconds / 1000)
|
|
145
|
-
if (executionTime.milliseconds == 0 && executionTime.nanoseconds > 0) executionTime.milliseconds = 1
|
|
146
|
-
return executionTime
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function saveXML(that) {
|
|
150
|
-
fileUtils.createDirectory(that.targetDir)
|
|
151
|
-
that.#xml += '</PermissionSet>\n'
|
|
152
|
-
writeFileSync(that.#fileName, that.#xml)
|
|
153
|
-
utimesSync(that.#fileName, that.#fileStats.atime, that.#fileStats.mtime)
|
|
154
|
-
|
|
155
|
-
let executionTime = getTimeDiff(BigInt(that.#startTime))
|
|
156
|
-
let durationMessage = `${executionTime.seconds}.${executionTime.milliseconds}s`
|
|
157
|
-
let stateIcon = (that.#errorMessage == '') ? global.icons.success : global.icons.fail
|
|
158
|
-
logUpdate(that.#spinnerMessage
|
|
159
|
-
.replace('[%1]', that.sequence.toString().padStart(global.processed.total.toString().length, ' '))
|
|
160
|
-
.replace('[%2]', `. Processed in ${durationMessage}.`)
|
|
161
|
-
.replace('[%3]', `${that.#errorMessage}`)
|
|
162
|
-
.replace('[%4]', `${stateIcon} `)
|
|
163
|
-
)
|
|
164
|
-
logUpdate.done()
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function nextFrame(that) {
|
|
169
|
-
return spinner.frames[that.#index = ++that.#index % spinner.frames.length]
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function genericXML(that, key) {
|
|
173
|
-
const fileName = path.join(that.sourceDir, that.metaDir, `${key}.${global.format}`)
|
|
174
|
-
const builder = new xml2js.Builder({ cdata: false, headless: true, rootName: key })
|
|
175
|
-
|
|
176
|
-
if (fileUtils.fileExists(fileName)) {
|
|
177
|
-
const data = readFileSync(fileName, { encoding: 'utf8', flag: 'r' })
|
|
178
|
-
const result = (global.format == 'yaml') ? yaml.load(data) : JSON.parse(data)
|
|
179
|
-
result[key] = sortJSONKeys(sortJSON(result[key], permsetDefinition.sortKeys[key]))
|
|
180
|
-
result[key].forEach(element => {
|
|
181
|
-
that.#xml += `\t<${key}>${os.EOL}`
|
|
182
|
-
Object.keys(element).forEach(tag => {
|
|
183
|
-
let xml
|
|
184
|
-
try {
|
|
185
|
-
xml = builder.buildObject(element[tag]).replace(`<${key}>`, '').replace(`</${key}>`, '')
|
|
186
|
-
that.#xml += `\t\t<${tag}>${xml}</${tag}>${os.EOL}`
|
|
187
|
-
} catch (error) {
|
|
188
|
-
global.logger.error(error)
|
|
189
|
-
}
|
|
190
|
-
})
|
|
191
|
-
that.#xml += `\t</${key}>${os.EOL}`
|
|
192
|
-
})
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function genericDirectoryXML(that, key) {
|
|
197
|
-
let dirPath = path.join(that.sourceDir, that.metaDir, key)
|
|
198
|
-
if (!fileUtils.directoryExists(dirPath)) return
|
|
199
|
-
|
|
200
|
-
let fileList = fileUtils.getFiles(dirPath, `.${global.format}`).sort()
|
|
201
|
-
fileList.forEach(fileName => {
|
|
202
|
-
const data = readFileSync(path.join(dirPath, fileName), { encoding: 'utf8', flag: 'r' })
|
|
203
|
-
const result = (global.format == 'yaml') ? yaml.load(data) : JSON.parse(data)
|
|
204
|
-
const object = result.object
|
|
205
|
-
result[key] = sortJSONKeys(sortJSON(result[key], permsetDefinition.sortKeys[key]))
|
|
206
|
-
result[key].forEach(element => {
|
|
207
|
-
that.#xml += `\t<${key}>${os.EOL}`
|
|
208
|
-
Object.keys(element).forEach(tag => {
|
|
209
|
-
if (tag == permsetDefinition.sortKeys[key] && object) {
|
|
210
|
-
that.#xml += `\t\t<${tag}>${object}.${element[tag]}</${tag}>${os.EOL}`
|
|
211
|
-
} else {
|
|
212
|
-
that.#xml += `\t\t<${tag}>${element[tag]}</${tag}>${os.EOL}`
|
|
213
|
-
}
|
|
214
|
-
})
|
|
215
|
-
that.#xml += `\t</${key}>${os.EOL}`
|
|
216
|
-
})
|
|
217
|
-
})
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function objectPermissions(that, key) {
|
|
221
|
-
let dirPath = path.join(that.sourceDir, that.metaDir, key)
|
|
222
|
-
if (!fileUtils.directoryExists(dirPath)) return
|
|
223
|
-
|
|
224
|
-
let fileList = fileUtils.getFiles(dirPath, `.${global.format}`).sort((a, b) => a.localeCompare(b))
|
|
225
|
-
fileList.forEach(fileName => {
|
|
226
|
-
const data = readFileSync(path.join(dirPath, fileName), { encoding: 'utf8', flag: 'r' })
|
|
227
|
-
const result = (global.format == 'yaml') ? yaml.load(data) : JSON.parse(data)
|
|
228
|
-
result[key]['object'] = result.object
|
|
229
|
-
result[key] = sortJSONKeys(result[key])
|
|
230
|
-
that.#xml += `\t<${key}>${os.EOL}`
|
|
231
|
-
Object.keys(result[key]).forEach(element => {
|
|
232
|
-
that.#xml += `\t\t<${element}>${result[key][element]}</${element}>${os.EOL}`
|
|
233
|
-
})
|
|
234
|
-
that.#xml += `\t</${key}>${os.EOL}`
|
|
235
|
-
})
|
|
236
|
-
}
|
|
237
|
-
// end of functions
|
|
238
|
-
// end of combine
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// end of class
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function sortJSON(json, key) {
|
|
245
|
-
if (Array.isArray(json)) {
|
|
246
|
-
json.sort((a, b) => {
|
|
247
|
-
if (a[key] < b[key]) return -1
|
|
248
|
-
if (a[key] > b[key]) return 1
|
|
249
|
-
return 0
|
|
250
|
-
})
|
|
251
|
-
}
|
|
252
|
-
return json
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function sortJSONKeys(json) {
|
|
256
|
-
// sort json keys alphabetically
|
|
257
|
-
if (Array.isArray(json)) {
|
|
258
|
-
json.forEach(function (part, index) {
|
|
259
|
-
this[index] = Object.keys(this[index])
|
|
260
|
-
.sort((a, b) => {
|
|
261
|
-
if (a < b) return -1
|
|
262
|
-
if (a > b) return 1
|
|
263
|
-
return 0
|
|
264
|
-
})
|
|
265
|
-
.reduce((accumulator, key) => {
|
|
266
|
-
accumulator[key] = this[index][key]
|
|
267
|
-
|
|
268
|
-
return accumulator
|
|
269
|
-
}, {})
|
|
270
|
-
}, json)
|
|
271
|
-
|
|
272
|
-
} else {
|
|
273
|
-
json = Object.keys(json)
|
|
274
|
-
.sort((a, b) => {
|
|
275
|
-
if (a < b) return -1
|
|
276
|
-
if (a > b) return 1
|
|
277
|
-
return 0
|
|
278
|
-
})
|
|
279
|
-
.reduce((accumulator, key) => {
|
|
280
|
-
accumulator[key] = json[key]
|
|
281
|
-
|
|
282
|
-
return accumulator
|
|
283
|
-
}, {})
|
|
284
|
-
}
|
|
285
|
-
return json
|
|
286
|
-
}
|