@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/src/index.js CHANGED
@@ -9,6 +9,7 @@ import chalk from 'chalk'
9
9
  import convertHrtime from 'convert-hrtime'
10
10
  import * as fileUtils from './lib/fileUtils.js'
11
11
  import * as pkgObj from '../package.json' assert { type: "json" }
12
+ import * as yargOptions from './meta/yargs.js'
12
13
  import * as metadataSplit from './party/split.js'
13
14
  import * as metadataCombine from './party/combine.js'
14
15
  import * as labelDefinition from './meta/CustomLabels.js'
@@ -16,8 +17,7 @@ import * as profileDefinition from './meta/Profiles.js'
16
17
  import * as permsetDefinition from './meta/PermissionSets.js'
17
18
  import * as workflowDefinition from './meta/Workflows.js'
18
19
 
19
- const startTime = process.hrtime.bigint()
20
-
20
+ const processStartTime = process.hrtime.bigint()
21
21
 
22
22
  global.logger = winston.createLogger({
23
23
  levels: winston.config.syslog.levels,
@@ -28,12 +28,6 @@ global.logger = winston.createLogger({
28
28
  ],
29
29
  });
30
30
 
31
- global.processed = {
32
- total: 0,
33
- errors: 0,
34
- current: 1,
35
- }
36
-
37
31
  global.icons = {
38
32
  "warn": '🔕',
39
33
  "success": chalk.greenBright('✔'),
@@ -68,6 +62,8 @@ const metaTypes = {
68
62
  },
69
63
  }
70
64
 
65
+ let types = []
66
+
71
67
  function getRootPath(packageDir) {
72
68
  let rootPath = fileUtils.find('sfdx-project.json')
73
69
  let defaultDir
@@ -100,7 +96,7 @@ let errorMessage = chalk.red('Please specify the action of ' + chalk.whiteBright
100
96
  displayHeader() // display header mast
101
97
 
102
98
  function displayHeader() {
103
- const table = {
99
+ const box = {
104
100
  topLeft: '╭',
105
101
  topRight: '╮',
106
102
  bottomLeft: '╰',
@@ -112,10 +108,10 @@ function displayHeader() {
112
108
  let titleMessage = `${global.icons.party} ${chalk.yellowBright(versionString)} ${global.icons.party}`
113
109
  titleMessage = titleMessage.padEnd((process.stdout.columns / 2) + versionString.length / 1.65)
114
110
  titleMessage = titleMessage.padStart(process.stdout.columns)
115
- titleMessage = chalk.blackBright(table.vertical) + ' ' + titleMessage + ' ' + chalk.blackBright(table.vertical)
116
- console.log(`${chalk.blackBright(table.topLeft + table.horizontal.repeat(process.stdout.columns - 2) + table.topRight)}`)
111
+ titleMessage = chalk.blackBright(box.vertical) + ' ' + titleMessage + ' ' + chalk.blackBright(box.vertical)
112
+ console.log(`${chalk.blackBright(box.topLeft + box.horizontal.repeat(process.stdout.columns - 2) + box.topRight)}`)
117
113
  console.log(titleMessage)
118
- console.log(`${chalk.blackBright(table.bottomLeft + table.horizontal.repeat(process.stdout.columns - 2) + table.bottomRight)}`)
114
+ console.log(`${chalk.blackBright(box.bottomLeft + box.horizontal.repeat(process.stdout.columns - 2) + box.bottomRight)}`)
119
115
  console.log()
120
116
  }
121
117
 
@@ -124,316 +120,33 @@ yargs(hideBin(process.argv))
124
120
  .command({
125
121
  command: '[split]',
126
122
  alias: 'split',
127
- description: 'splits metadata xml to json files',
123
+ description: 'splits metadata xml to yaml/json files',
128
124
  builder: (yargs) => {
129
125
  yargs
130
- .example([
131
- ['$0 split --type=profile --all'],
132
- ['$0 split --type=permset --name="Permission Set Name"'],
133
- ['--source=packageDir --target=dir/dir'],
134
- ['name portion of file: [name].profile-meta.xml'],
135
- ['Example: --name="Admin" for Admin.profile-meta.xml'],
136
- ['\nCommands not supporting name or all parameters:'],
137
- ['$0 split --type=label'],
138
- ])
139
- .options({
140
- type: {
141
- demand: true,
142
- alias: 'type',
143
- description: 'type of metadata to split',
144
- demandOption: true,
145
- type: 'string',
146
- },
147
- format: {
148
- demand: true,
149
- alias: 'format',
150
- default: 'yaml',
151
- description: 'type of output',
152
- demandOption: true,
153
- type: 'string',
154
- },
155
- name: {
156
- alias: 'n',
157
- description: 'name of metadata file to split',
158
- demandOption: false,
159
- type: 'string',
160
- },
161
- all: {
162
- alias: 'a',
163
- description: 'all metadata files of type will be split',
164
- demandOption: false,
165
- type: 'boolean',
166
- },
167
- source: {
168
- demand: false,
169
- alias: 's',
170
- description: 'package directory path specified in sfdx-project.json',
171
- type: 'string',
172
- },
173
- target: {
174
- demand: false,
175
- alias: 't',
176
- description: 'target path to directory to create json files',
177
- type: 'string',
178
- }
179
- })
180
- .choices('type', typeArray)
126
+ .example(yargOptions.splitExamples)
127
+ .options(yargOptions.splitOptions)
181
128
  .choices('format', ['json', 'yaml'])
182
- .check((argv, options) => {
183
- const name = argv.name
184
- const all = argv.all
185
-
186
- switch (argv.type) {
187
- case 'profile':
188
- case 'permset':
189
- case 'workflow':
190
- if ((typeof name != 'undefined' || name == '') && (typeof all != 'undefined' && all)) {
191
- throw new Error(chalk.redBright('You cannot specify ' + chalk.whiteBright.bgRedBright('--name') + ' and ' + chalk.whiteBright.bgRedBright('--all') + ' at the same time.'))
192
- } else if (typeof name == 'undefined' && (typeof all == 'undefined' || !all)) {
193
- throw new Error(chalk.redBright('You must specify the ' + chalk.whiteBright.bgRedBright('--name') + ' parameter or use the ' + chalk.whiteBright.bgRedBright('--all') + ' switch.'))
194
- } else {
195
- return true // tell Yargs that the arguments passed the check
196
- }
197
- case 'label':
198
- if ((typeof name != 'undefined' && name != '') || (typeof all != 'undefined' && all)) {
199
- throw new Error(chalk.redBright('You cannot specify ' + chalk.whiteBright.bgRedBright('--name') + ' or ' + chalk.whiteBright.bgRedBright('--all') + ' when using label.'))
200
- }
201
- return true
202
- }
203
- })
129
+ .check(yargCheck)
204
130
  },
205
131
  handler: (argv) => {
206
- if (!typeArray.includes(argv.type)) {
207
- global.logger.error('Metadata type not supported: ' + type)
208
- process.exit(1)
209
- }
210
- const fileList = []
211
- const typeObj = metaTypes[argv.type]
212
- const type = typeObj.type
213
- const metaExtension = `.${type}-meta.xml`
214
132
  global.format = argv.format
215
-
216
- let sourceDir = argv.source || ''
217
- let targetDir = argv.target || ''
218
- let name = argv.name
219
- let all = argv.all
220
- let packageDir = getRootPath(sourceDir)
221
-
222
- if (type == metaTypes.label.type) {
223
- name = metaTypes.label.definition.root
224
- }
225
- sourceDir = path.join(global.__basedir, packageDir, 'main', 'default', typeObj.definition.directory)
226
- if (targetDir == '') {
227
- targetDir = path.join(global.__basedir, packageDir + '-party', 'main', 'default', typeObj.definition.directory)
228
- } else {
229
- targetDir = path.join(targetDir, 'main', 'default', typeObj.definition.directory)
230
- }
231
- let metaDirPath = sourceDir
232
- console.log(`${chalk.bgBlackBright('Source path:')} ${sourceDir}`)
233
- console.log(`${chalk.bgBlackBright('Target path:')} ${targetDir}`)
234
- console.log()
235
-
236
- if (!all) {
237
- let metaFilePath = path.join(metaDirPath, name)
238
- if (!fileUtils.fileExists(metaFilePath)) {
239
- name += metaExtension
240
- metaFilePath = path.join(metaDirPath, name)
241
- if (!fileUtils.fileExists(metaFilePath)) {
242
- global.logger.error('File not found: ' + metaFilePath)
243
- process.exit(1)
244
- }
245
- }
246
- fileList.push(name)
247
- } else {
248
- if (fileUtils.directoryExists(sourceDir)) {
249
- fileUtils.getFiles(sourceDir, metaExtension).forEach(file => {
250
- fileList.push(file)
251
- })
252
- }
253
- }
254
-
255
- global.processed.total = fileList.length
256
- console.log(`Splitting a total of ${fileList.length} file(s)`)
257
- console.log()
258
- const promList = []
259
- fileList.forEach(metaFile => {
260
- const metadataItem = new metadataSplit.Split({
261
- metadataDefinition: typeObj.definition,
262
- sourceDir: sourceDir,
263
- targetDir: targetDir,
264
- metaFilePath: path.join(sourceDir, metaFile),
265
- sequence: promList.length + 1,
266
- })
267
- const metadataItemProm = metadataItem.split()
268
- promList.push(metadataItemProm)
269
- metadataItemProm.then((resolve, reject) => {
270
- if (resolve == false) {
271
- global.processed.errors++
272
- global.processed.current--
273
- } else {
274
- global.processed.current++
275
- }
276
- })
277
- })
278
- Promise.allSettled(promList).then((results) => {
279
- let message = `Split ${chalk.bgBlackBright((global.processed.current > promList.length) ? promList.length : global.processed.current)} file(s) ${(global.processed.errors > 0) ? 'with ' + chalk.bgBlackBright.red(global.processed.errors) + ' error(s) ' : ''}in `
280
- displayMessageAndDuration(startTime, message)
281
- })
133
+ splitHandler(argv, processStartTime)
282
134
  }
283
135
  })
284
136
  .command({
285
137
  command: '[combine]',
286
138
  alias: 'combine',
287
- description: 'combines json files into metadata xml',
139
+ description: 'combines yaml/json files into metadata xml',
288
140
  builder: (yargs) => {
289
141
  yargs
290
- .example([
291
- ['$0 combine --type=profile --all'],
292
- ['$0 combine --type=permset --name="Permission Set Name"'],
293
- ['--source=packageDir --target=dir/dir'],
294
- ['name portion of file: [name].profile-meta.xml'],
295
- ['Example: --name="Admin" for Admin.profile-meta.xml'],
296
- ['\nCommands not supporting name or all parameters:'],
297
- ['$0 combine --type=label'],])
298
- .options({
299
- type: {
300
- demand: true,
301
- alias: 'type',
302
- description: 'type of metadata to combine',
303
- demandOption: true,
304
- type: 'string',
305
- },
306
- format: {
307
- demand: true,
308
- alias: 'format',
309
- default: 'yaml',
310
- description: 'type of output',
311
- demandOption: true,
312
- type: 'string',
313
- },
314
- name: {
315
- alias: 'n',
316
- description: 'name of metadata file to combine',
317
- demandOption: false,
318
- type: 'string',
319
- },
320
- all: {
321
- alias: 'a',
322
- description: 'all json files of type will be combined',
323
- demandOption: false,
324
- type: 'boolean',
325
- },
326
- source: {
327
- demand: false,
328
- alias: 's',
329
- description: 'package directory path specified in sfdx-project.json',
330
- type: 'string',
331
- },
332
- target: {
333
- demand: false,
334
- alias: 't',
335
- description: 'target path to directory to create xml files',
336
- type: 'string',
337
- }
338
- })
339
- .choices('type', typeArray)
142
+ .example(yargOptions.combineExamples)
143
+ .options(yargOptions.combineOptions)
340
144
  .choices('format', ['json', 'yaml'])
341
- .check((argv, options) => {
342
- const name = argv.name
343
- const all = argv.all
344
-
345
- switch (argv.type) {
346
- case 'profile':
347
- case 'permset':
348
- case 'workflow':
349
- if ((typeof name != 'undefined' || name == '') && (typeof all != 'undefined' && all)) {
350
- throw new Error(chalk.redBright('You cannot specify ' + chalk.whiteBright.bgRedBright('--name') + ' and ' + chalk.whiteBright.bgRedBright('--all') + ' at the same time.'))
351
- } else if (typeof name == 'undefined' && (typeof all == 'undefined' || !all)) {
352
- throw new Error(chalk.redBright('You must specify the ' + chalk.whiteBright.bgRedBright('--name') + ' parameter or use the ' + chalk.whiteBright.bgRedBright('--all') + ' switch.'))
353
- } else {
354
- return true // tell Yargs that the arguments passed the check
355
- }
356
- case 'label':
357
- if ((typeof name != 'undefined' && name != '') || (typeof all != 'undefined' && all)) {
358
- throw new Error(chalk.redBright('You cannot specify ' + chalk.whiteBright.bgRedBright('--name') + ' or ' + chalk.whiteBright.bgRedBright('--all') + ' when using label.'))
359
- }
360
- return true
361
- }
362
- })
145
+ .check(yargCheck)
363
146
  },
364
147
  handler: (argv) => {
365
- if (!typeArray.includes(argv.type)) {
366
- global.logger.error('Metadata type not supported: ' + type)
367
- process.exit(1)
368
- }
369
- let processList = []
370
148
  global.format = argv.format
371
- const typeObj = metaTypes[argv.type]
372
- const type = typeObj.type
373
-
374
- let sourceDir = argv.source || ''
375
- let targetDir = argv.target || ''
376
- let name = argv.name
377
- let all = argv.all
378
- let packageDir = getRootPath(sourceDir)
379
-
380
- sourceDir = path.join(global.__basedir, packageDir + '-party', 'main', 'default', typeObj.definition.directory)
381
- if (targetDir == '') {
382
- targetDir = path.join(global.__basedir, packageDir, 'main', 'default', typeObj.definition.directory)
383
- } else {
384
- targetDir = path.join(targetDir, 'main', 'default', typeObj.definition.directory)
385
- }
386
-
387
- console.log(`${chalk.bgBlackBright('Source path:')} ${sourceDir}`)
388
- console.log(`${chalk.bgBlackBright('Target path:')} ${targetDir}`)
389
- console.log()
390
-
391
- if (type == metaTypes.label.type) {
392
- processList.push(metaTypes.label.definition.root)
393
- } else if (!all) {
394
- let metaDirPath = path.join(sourceDir, name)
395
- if (!fileUtils.directoryExists(metaDirPath)) {
396
- global.logger.error('Directory not found: ' + metaDirPath)
397
- process.exit(1)
398
- }
399
- processList.push(name)
400
- } else {
401
- processList = fileUtils.getDirectories(sourceDir)
402
- }
403
-
404
- global.processed.total = processList.length
405
- console.log(`Combining a total of ${global.processed.total} file(s)`)
406
- console.log()
407
-
408
- const promList = []
409
- processList.forEach(metaDir => {
410
- const metadataItem = new metadataCombine.Combine({
411
- metadataDefinition: typeObj.definition,
412
- sourceDir: sourceDir,
413
- targetDir: targetDir,
414
- metaDir: metaDir,
415
- sequence: promList.length + 1,
416
- })
417
- const metadataItemProm = metadataItem.combine()
418
- promList.push(metadataItemProm)
419
- metadataItemProm.then((resolve, reject) => {
420
- global.processed.current++
421
- })
422
- })
423
-
424
- Promise.allSettled(promList).then((results) => {
425
- let successes = 0
426
- let errors = 0
427
- results.forEach(result => {
428
- if (result.value == true) {
429
- successes++
430
- } else if (result.value == false) {
431
- errors++
432
- }
433
- })
434
- let message = `Combined ${chalk.bgBlackBright(successes)} file(s) ${(errors > 0) ? 'with ' + chalk.bgBlackBright(errors) + 'error(s) ' : ''}in `
435
- displayMessageAndDuration(startTime, message)
436
- })
149
+ combineHandler(argv, processStartTime)
437
150
  }
438
151
  })
439
152
  .demandCommand(1, errorMessage)
@@ -447,6 +160,35 @@ yargs(hideBin(process.argv))
447
160
  .argv
448
161
  .parse
449
162
 
163
+ function yargCheck(argv, options) {
164
+ const name = argv.name
165
+ types = (argv.type !== undefined) ? argv.type.split(',') : typeArray
166
+ types.forEach(type => {
167
+ type = type.trim()
168
+ if (!typeArray.includes(type)) {
169
+ throw new Error(`Invalid type: ${type}`)
170
+ }
171
+ })
172
+
173
+ if (types.length > 1) {
174
+ // if using multiple types you cannot specify name
175
+ if ((typeof name != 'undefined' && name != '')) {
176
+ throw new Error(chalk.redBright('You cannot specify ' + chalk.whiteBright.bgRedBright('--name') + ' when using multiple types.'))
177
+ }
178
+ return true
179
+ } else {
180
+ switch (argv.type) {
181
+ case 'label':
182
+ if ((typeof name != 'undefined' && name != '')) {
183
+ throw new Error(chalk.redBright('You cannot specify ' + chalk.whiteBright.bgRedBright('--name') + ' when using label.'))
184
+ }
185
+ break
186
+ default:
187
+ return true
188
+ }
189
+ }
190
+ }
191
+
450
192
  function displayMessageAndDuration(startTime, message) {
451
193
  const diff = process.hrtime.bigint() - BigInt(startTime)
452
194
  let durationMessage
@@ -471,4 +213,215 @@ process.on('SIGINT', function () {
471
213
  }
472
214
 
473
215
  callAmount++;
474
- })
216
+ })
217
+
218
+ function splitHandler(argv) {
219
+ const split = processSplit(types[0], argv)
220
+ split.then((resolve) => {
221
+ types.shift() // remove first item from array
222
+ if (types.length > 0) {
223
+ console.log()
224
+ splitHandler(argv)
225
+ } else {
226
+ if (argv.type === undefined || argv.type.split(',').length > 1) {
227
+ let message = `Split completed in `
228
+ displayMessageAndDuration(startTime, message)
229
+ }
230
+ }
231
+ })
232
+ }
233
+
234
+ function processSplit(typeItem, argv) {
235
+ return new Promise((resolve, reject) => {
236
+ const processed = {
237
+ total: 0,
238
+ errors: 0,
239
+ current: 1,
240
+ }
241
+ const startTime = process.hrtime.bigint()
242
+
243
+ if (!typeArray.includes(typeItem)) {
244
+ global.logger.error('Metadata type not supported: ' + typeItem)
245
+ process.exit(1)
246
+ }
247
+
248
+ const fileList = []
249
+ const typeObj = metaTypes[typeItem]
250
+ const type = typeObj.type
251
+ const metaExtension = `.${type}-meta.xml`
252
+
253
+ let sourceDir = argv.source || ''
254
+ let targetDir = argv.target || ''
255
+ let name = argv.name
256
+ let all = (argv.type === undefined || argv.type.split(',').length > 1) ? true : argv.all
257
+ let packageDir = getRootPath(sourceDir)
258
+
259
+ if (type == metaTypes.label.type) {
260
+ name = metaTypes.label.definition.root
261
+ }
262
+ sourceDir = path.join(global.__basedir, packageDir, 'main', 'default', typeObj.definition.directory)
263
+ if (targetDir == '') {
264
+ targetDir = path.join(global.__basedir, packageDir + '-party', 'main', 'default', typeObj.definition.directory)
265
+ } else {
266
+ targetDir = path.join(targetDir, 'main', 'default', typeObj.definition.directory)
267
+ }
268
+ let metaDirPath = sourceDir
269
+
270
+ if (!all) {
271
+ let metaFilePath = path.join(metaDirPath, name)
272
+ if (!fileUtils.fileExists(metaFilePath)) {
273
+ name += metaExtension
274
+ metaFilePath = path.join(metaDirPath, name)
275
+ if (!fileUtils.fileExists(metaFilePath)) {
276
+ global.logger.error('File not found: ' + metaFilePath)
277
+ process.exit(1)
278
+ }
279
+ }
280
+ fileList.push(name)
281
+ } else {
282
+ if (fileUtils.directoryExists(sourceDir)) {
283
+ fileUtils.getFiles(sourceDir, metaExtension).forEach(file => {
284
+ fileList.push(file)
285
+ })
286
+ }
287
+ }
288
+
289
+ processed.total = fileList.length
290
+
291
+ console.log(`${chalk.bgBlackBright('Source path:')} ${sourceDir}`)
292
+ console.log(`${chalk.bgBlackBright('Target path:')} ${targetDir}`)
293
+ console.log()
294
+ console.log(`Splitting a total of ${processed.total} file(s)`)
295
+ console.log()
296
+
297
+ const promList = []
298
+ fileList.forEach(metaFile => {
299
+ const metadataItem = new metadataSplit.Split({
300
+ metadataDefinition: typeObj.definition,
301
+ sourceDir: sourceDir,
302
+ targetDir: targetDir,
303
+ metaFilePath: path.join(sourceDir, metaFile),
304
+ sequence: promList.length + 1,
305
+ total: processed.total,
306
+ })
307
+ const metadataItemProm = metadataItem.split()
308
+ promList.push(metadataItemProm)
309
+ metadataItemProm.then((resolve, reject) => {
310
+ if (resolve == false) {
311
+ processed.errors++
312
+ processed.current--
313
+ } else {
314
+ processed.current++
315
+ }
316
+ })
317
+ })
318
+ Promise.allSettled(promList).then((results) => {
319
+ let message = `Split ${chalk.bgBlackBright((processed.current > promList.length) ? promList.length : processed.current)} file(s) ${(processed.errors > 0) ? 'with ' + chalk.bgBlackBright.red(processed.errors) + ' error(s) ' : ''}in `
320
+ displayMessageAndDuration(startTime, message)
321
+ resolve(true)
322
+ })
323
+ })
324
+ }
325
+
326
+ function combineHandler(argv, startTime) {
327
+ const combine = processCombine(types[0], argv)
328
+ combine.then((resolve) => {
329
+ types.shift() // remove first item from array
330
+ if (types.length > 0) {
331
+ console.log()
332
+ combineHandler(argv, startTime)
333
+ } else {
334
+ if (argv.type === undefined || argv.type.split(',').length > 1) {
335
+ let message = `Split completed in `
336
+ displayMessageAndDuration(startTime, message)
337
+ }
338
+ }
339
+ })
340
+
341
+ }
342
+
343
+ function processCombine(typeItem, argv) {
344
+ return new Promise((resolve, reject) => {
345
+ const processed = {
346
+ total: 0,
347
+ errors: 0,
348
+ current: 1,
349
+ }
350
+ const startTime = process.hrtime.bigint()
351
+
352
+ if (!typeArray.includes(typeItem)) {
353
+ global.logger.error('Metadata type not supported: ' + typeItem)
354
+ process.exit(1)
355
+ }
356
+
357
+ let processList = []
358
+ const typeObj = metaTypes[typeItem]
359
+ const type = typeObj.type
360
+
361
+ let sourceDir = argv.source || ''
362
+ let targetDir = argv.target || ''
363
+ let name = argv.name
364
+ let all = (argv.type === undefined || argv.type.split(',').length > 1) ? true : argv.all
365
+ let packageDir = getRootPath(sourceDir)
366
+
367
+ sourceDir = path.join(global.__basedir, packageDir + '-party', 'main', 'default', typeObj.definition.directory)
368
+ if (targetDir == '') {
369
+ targetDir = path.join(global.__basedir, packageDir, 'main', 'default', typeObj.definition.directory)
370
+ } else {
371
+ targetDir = path.join(targetDir, 'main', 'default', typeObj.definition.directory)
372
+ }
373
+
374
+ console.log(`${chalk.bgBlackBright('Source path:')} ${sourceDir}`)
375
+ console.log(`${chalk.bgBlackBright('Target path:')} ${targetDir}`)
376
+ console.log()
377
+
378
+ if (type == metaTypes.label.type) {
379
+ processList.push(metaTypes.label.definition.root)
380
+ } else if (!all) {
381
+ let metaDirPath = path.join(sourceDir, name)
382
+ if (!fileUtils.directoryExists(metaDirPath)) {
383
+ global.logger.error('Directory not found: ' + metaDirPath)
384
+ process.exit(1)
385
+ }
386
+ processList.push(name)
387
+ } else {
388
+ processList = fileUtils.getDirectories(sourceDir)
389
+ }
390
+
391
+ processed.total = processList.length
392
+ console.log(`Combining a total of ${processed.total} file(s)`)
393
+ console.log()
394
+
395
+ const promList = []
396
+ processList.forEach(metaDir => {
397
+ const metadataItem = new metadataCombine.Combine({
398
+ metadataDefinition: typeObj.definition,
399
+ sourceDir: sourceDir,
400
+ targetDir: targetDir,
401
+ metaDir: metaDir,
402
+ sequence: promList.length + 1,
403
+ total: processed.total,
404
+ })
405
+ const metadataItemProm = metadataItem.combine()
406
+ promList.push(metadataItemProm)
407
+ metadataItemProm.then((resolve, reject) => {
408
+ processed.current++
409
+ })
410
+ })
411
+
412
+ Promise.allSettled(promList).then((results) => {
413
+ let successes = 0
414
+ let errors = 0
415
+ results.forEach(result => {
416
+ if (result.value == true) {
417
+ successes++
418
+ } else if (result.value == false) {
419
+ errors++
420
+ }
421
+ })
422
+ let message = `Combined ${chalk.bgBlackBright(successes)} file(s) ${(errors > 0) ? 'with ' + chalk.bgBlackBright(errors) + 'error(s) ' : ''}in `
423
+ displayMessageAndDuration(startTime, message)
424
+ resolve(true)
425
+ })
426
+ })
427
+ }