@ds-sfdc/sfparty 1.3.8 → 1.3.9

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
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict'
3
- import { exec, spawnSync } from 'child_process'
3
+ import { spawnSync } from 'child_process'
4
4
  import { readFileSync } from 'fs'
5
5
  import path from 'path'
6
6
  import yargs from 'yargs'
@@ -26,654 +26,818 @@ import * as git from './lib/gitUtils.js'
26
26
  const processStartTime = process.hrtime.bigint()
27
27
 
28
28
  marked.setOptions({
29
- // Define custom renderer
30
- renderer: new markedTerminal
29
+ // Define custom renderer
30
+ renderer: new markedTerminal(),
31
31
  })
32
32
 
33
33
  global.__basedir = undefined
34
34
 
35
35
  global.logger = winston.createLogger({
36
- levels: {
37
- error: 0,
38
- warn: 1,
39
- info: 2,
40
- http: 3,
41
- verbose: 4,
42
- debug: 5,
43
- silly: 6
44
- },
45
- format: winston.format.cli(),
46
- defaultMeta: { service: 'sfparty' },
47
- transports: [
48
- new winston.transports.Console(),
49
- ],
36
+ levels: {
37
+ error: 0,
38
+ warn: 1,
39
+ info: 2,
40
+ http: 3,
41
+ verbose: 4,
42
+ debug: 5,
43
+ silly: 6,
44
+ },
45
+ format: winston.format.cli(),
46
+ defaultMeta: { service: 'sfparty' },
47
+ transports: [new winston.transports.Console()],
50
48
  })
51
49
 
52
50
  global.icons = {
53
- "warn": '🔕',
54
- "success": clc.greenBright('✔'),
55
- "fail": '❗',
56
- "working": '⏳',
57
- "party": '🎉',
58
- "delete": '❌💀❌',
51
+ warn: '🔕',
52
+ success: clc.greenBright('✔'),
53
+ fail: '❗',
54
+ working: '⏳',
55
+ party: '🎉',
56
+ delete: '❌💀❌',
59
57
  }
60
58
 
61
59
  global.displayError = (error, quit = false) => {
62
- global.logger.error(error)
63
- console.info(error)
64
- if (quit) process.exit(1)
60
+ global.logger.error(error)
61
+ console.info(error)
62
+ if (quit) process.exit(1)
65
63
  }
66
64
 
67
- const typeArray = [
68
- 'label',
69
- 'profile',
70
- 'permset',
71
- 'workflow',
72
- ]
65
+ const typeArray = ['label', 'profile', 'permset', 'workflow']
73
66
 
74
67
  global.git = {
75
- enabled: false,
76
- last: undefined,
77
- latest: undefined,
78
- append: false,
79
- delta: false,
68
+ enabled: false,
69
+ last: undefined,
70
+ latest: undefined,
71
+ append: false,
72
+ delta: false,
80
73
  }
81
74
 
82
75
  global.metaTypes = {
83
- label: {
84
- type: labelDefinition.metadataDefinition.filetype,
85
- definition: labelDefinition.metadataDefinition,
86
- add: { files: [], directories: [] },
87
- remove: { files: [], directories: [] },
88
- },
89
- profile: {
90
- type: profileDefinition.metadataDefinition.filetype,
91
- definition: profileDefinition.metadataDefinition,
92
- add: { files: [], directories: [] },
93
- remove: { files: [], directories: [] },
94
- },
95
- permset: {
96
- type: permsetDefinition.metadataDefinition.filetype,
97
- definition: permsetDefinition.metadataDefinition,
98
- add: { files: [], directories: [] },
99
- remove: { files: [], directories: [] },
100
- },
101
- workflow: {
102
- type: workflowDefinition.metadataDefinition.filetype,
103
- definition: workflowDefinition.metadataDefinition,
104
- add: { files: [], directories: [] },
105
- remove: { files: [], directories: [] },
106
- },
76
+ label: {
77
+ type: labelDefinition.metadataDefinition.filetype,
78
+ definition: labelDefinition.metadataDefinition,
79
+ add: { files: [], directories: [] },
80
+ remove: { files: [], directories: [] },
81
+ },
82
+ profile: {
83
+ type: profileDefinition.metadataDefinition.filetype,
84
+ definition: profileDefinition.metadataDefinition,
85
+ add: { files: [], directories: [] },
86
+ remove: { files: [], directories: [] },
87
+ },
88
+ permset: {
89
+ type: permsetDefinition.metadataDefinition.filetype,
90
+ definition: permsetDefinition.metadataDefinition,
91
+ add: { files: [], directories: [] },
92
+ remove: { files: [], directories: [] },
93
+ },
94
+ workflow: {
95
+ type: workflowDefinition.metadataDefinition.filetype,
96
+ definition: workflowDefinition.metadataDefinition,
97
+ add: { files: [], directories: [] },
98
+ remove: { files: [], directories: [] },
99
+ },
107
100
  }
108
101
 
109
-
110
102
  let types = []
111
103
  const packageDir = getRootPath()
112
104
 
113
- let errorMessage = clc.red('Please specify the action of ' + clc.whiteBright.bgRedBright('split') + ' or ' + clc.whiteBright.bgRedBright('combine') + '.')
105
+ let errorMessage = clc.red(
106
+ 'Please specify the action of ' +
107
+ clc.whiteBright.bgRedBright('split') +
108
+ ' or ' +
109
+ clc.whiteBright.bgRedBright('combine') +
110
+ '.',
111
+ )
114
112
 
115
113
  displayHeader() // display header mast
116
114
 
117
115
  yargs(hideBin(process.argv))
118
- .command({
119
- command: 'help',
120
- alias: 'h',
121
- handler: (argv) => {
122
- const data = readFileSync(path.join(process.cwd(), 'README.md'), "utf8")
123
- console.log(marked(data))
124
- }
125
- })
126
- .command({
127
- command: '[test]',
128
- alias: 'test',
129
- handler: (argv) => {
130
- // THIS IS A PLACE TO TEST NEW CODE
131
- global.logger.info(clc.magentaBright(`${global.icons.party} TEST ${global.icons.party}`))
132
- }
133
- })
134
- .command({
135
- command: '[update]',
136
- alias: 'update',
137
- builder: (yargs) => {
138
- yargs
139
- .check(yargCheck)
140
- },
141
- handler: (argv) => {
142
- checkVersion({axios, spawnSync, currentVersion: pkgObj.version, update: true})
143
- }
144
- })
145
- .command({
146
- command: '[version]',
147
- alias: 'version',
148
- builder: (yargs) => {
149
- yargs
150
- .check(yargCheck)
151
- },
152
- })
153
- .command({
154
- command: '[split]',
155
- alias: 'split',
156
- description: 'splits metadata xml to yaml/json files',
157
- builder: (yargs) => {
158
- yargs
159
- .example(yargOptions.splitExamples)
160
- .options(yargOptions.splitOptions)
161
- .choices('format', ['json', 'yaml'])
162
- .check(yargCheck)
163
- },
164
- handler: (argv) => {
165
- global.format = argv.format
166
- splitHandler(argv, processStartTime)
167
- }
168
- })
169
- .command({
170
- command: '[combine]',
171
- alias: 'combine',
172
- description: 'combines yaml/json files into metadata xml',
173
- builder: (yargs) => {
174
- yargs
175
- .example(yargOptions.combineExamples)
176
- .options(yargOptions.combineOptions)
177
- .choices('format', ['json', 'yaml'])
178
- .check(yargCheck)
179
- },
180
- handler: (argv) => {
181
- global.format = argv.format
182
- const startProm = new Promise((resolve, reject) => {
183
- if (argv.git !== undefined) {
184
- let gitRef = argv.git.trim()
185
- global.git.append = argv.append || global.git.append
186
- global.git.delta = argv.delta || global.git.delta
187
- if (argv.git === '') {
188
- const commit = git.lastCommit(global.__basedir, "-1")
189
- commit
190
- .then((data, error) => {
191
- global.git.latest = data.latestCommit
192
- global.git.last = data.lastCommit
193
- if (data.last === undefined) {
194
- gitMode({status: 'not active'})
195
- resolve(false)
196
- } else {
197
- gitMode({status: 'active', lastCommit: data.lastCommit, latestCommit: data.latestCommit})
198
- const diff = git.diff(global.__basedir, `${data.lastCommit}..${data.latestCommit}`)
199
- diff
200
- .then((data, error) => {
201
- gitFiles(data)
202
- resolve(true)
203
- })
204
- .catch((error) => {
205
- global.logger.error(error)
206
- reject(error)
207
- })
208
- }
209
- })
210
- .catch((error) => {
211
- global.logger.error(error)
212
- throw error
213
- })
214
- } else {
215
- gitMode({status: 'active', gitRef})
216
- const diff = git.diff(global.__basedir, gitRef)
217
- diff
218
- .then((data, error) => {
219
- gitFiles(data)
220
- resolve(true)
221
- })
222
- .catch((error) => {
223
- global.logger.error(error)
224
- reject(error)
225
- })
226
- }
227
- } else {
228
- resolve(false)
229
- }
230
- })
231
- startProm.then((result) => {
232
- global.git.enabled = result
233
- combineHandler(argv, processStartTime)
234
- })
235
- startProm.catch((error) => {
236
- global.displayError(error, true)
237
- })
238
- }
239
- })
240
- .demandCommand(1, errorMessage)
241
- .example([
242
- ['$0 split --type=profile --all'],
243
- ['$0 split --type=profile --name="Profile Name"'],
244
- ['$0 combine --type=permset --all'],
245
- ['$0 combine --type=permset --name="Permission Set Name"'],
246
- ])
247
- .help(false)
248
- .argv
249
- .parse
116
+ .command({
117
+ command: 'help',
118
+ alias: 'h',
119
+ handler: (argv) => {
120
+ const data = readFileSync(
121
+ path.join(process.cwd(), 'README.md'),
122
+ 'utf8',
123
+ )
124
+ console.log(marked(data))
125
+ },
126
+ })
127
+ .command({
128
+ command: '[test]',
129
+ alias: 'test',
130
+ handler: (argv) => {
131
+ // THIS IS A PLACE TO TEST NEW CODE
132
+ global.logger.info(
133
+ clc.magentaBright(
134
+ `${global.icons.party} TEST ${global.icons.party}`,
135
+ ),
136
+ )
137
+ },
138
+ })
139
+ .command({
140
+ command: '[update]',
141
+ alias: 'update',
142
+ builder: (yargs) => {
143
+ yargs.check(yargCheck)
144
+ },
145
+ handler: (argv) => {
146
+ checkVersion({
147
+ axios,
148
+ spawnSync,
149
+ currentVersion: pkgObj.version,
150
+ update: true,
151
+ })
152
+ },
153
+ })
154
+ .command({
155
+ command: '[version]',
156
+ alias: 'version',
157
+ builder: (yargs) => {
158
+ yargs.check(yargCheck)
159
+ },
160
+ })
161
+ .command({
162
+ command: '[split]',
163
+ alias: 'split',
164
+ description: 'splits metadata xml to yaml/json files',
165
+ builder: (yargs) => {
166
+ yargs
167
+ .example(yargOptions.splitExamples)
168
+ .options(yargOptions.splitOptions)
169
+ .choices('format', ['json', 'yaml'])
170
+ .check(yargCheck)
171
+ },
172
+ handler: (argv) => {
173
+ global.format = argv.format
174
+ splitHandler(argv, processStartTime)
175
+ },
176
+ })
177
+ .command({
178
+ command: '[combine]',
179
+ alias: 'combine',
180
+ description: 'combines yaml/json files into metadata xml',
181
+ builder: (yargs) => {
182
+ yargs
183
+ .example(yargOptions.combineExamples)
184
+ .options(yargOptions.combineOptions)
185
+ .choices('format', ['json', 'yaml'])
186
+ .check(yargCheck)
187
+ },
188
+ handler: (argv) => {
189
+ global.format = argv.format
190
+ const startProm = new Promise((resolve, reject) => {
191
+ if (argv.git !== undefined) {
192
+ let gitRef = argv.git.trim()
193
+ global.git.append = argv.append || global.git.append
194
+ global.git.delta = argv.delta || global.git.delta
195
+ if (argv.git === '') {
196
+ const commit = git.lastCommit(global.__basedir, '-1')
197
+ commit
198
+ .then((data, error) => {
199
+ global.git.latest = data.latestCommit
200
+ global.git.last = data.lastCommit
201
+ if (data.last === undefined) {
202
+ gitMode({ status: 'not active' })
203
+ resolve(false)
204
+ } else {
205
+ gitMode({
206
+ status: 'active',
207
+ lastCommit: data.lastCommit,
208
+ latestCommit: data.latestCommit,
209
+ })
210
+ const diff = git.diff(
211
+ global.__basedir,
212
+ `${data.lastCommit}..${data.latestCommit}`,
213
+ )
214
+ diff.then((data, error) => {
215
+ gitFiles(data)
216
+ resolve(true)
217
+ }).catch((error) => {
218
+ global.logger.error(error)
219
+ reject(error)
220
+ })
221
+ }
222
+ })
223
+ .catch((error) => {
224
+ global.logger.error(error)
225
+ throw error
226
+ })
227
+ } else {
228
+ gitMode({ status: 'active', gitRef })
229
+ const diff = git.diff(global.__basedir, gitRef)
230
+ diff.then((data, error) => {
231
+ gitFiles(data)
232
+ resolve(true)
233
+ }).catch((error) => {
234
+ global.logger.error(error)
235
+ reject(error)
236
+ })
237
+ }
238
+ } else {
239
+ resolve(false)
240
+ }
241
+ })
242
+ startProm.then((result) => {
243
+ global.git.enabled = result
244
+ combineHandler(argv, processStartTime)
245
+ })
246
+ startProm.catch((error) => {
247
+ global.displayError(error, true)
248
+ })
249
+ },
250
+ })
251
+ .demandCommand(1, errorMessage)
252
+ .example([
253
+ ['$0 split --type=profile --all'],
254
+ ['$0 split --type=profile --name="Profile Name"'],
255
+ ['$0 combine --type=permset --all'],
256
+ ['$0 combine --type=permset --name="Permission Set Name"'],
257
+ ])
258
+ .help(false).argv.parse
250
259
 
251
260
  function gitMode({ status, gitRef, lastCommit, latestCommit }) {
252
- let statusMessage
253
- let displayMessage
254
- if (status == 'not active') {
255
- statusMessage = clc.bgMagentaBright('not active:')
256
- displayMessage = `no prior commit - processing all`
257
- } else {
258
- statusMessage = clc.magentaBright('active:')
259
- if (gitRef === undefined) {
260
- displayMessage = `${clc.bgBlackBright(data.lastCommit) + '..' + clc.bgBlackBright(data.latestCommit)}`
261
- console.log(`${clc.yellowBright('git mode')} ${clc.magentaBright('active:')} ${clc.bgBlackBright(data.lastCommit) + '..' + clc.bgBlackBright(data.latestCommit)}`)
262
- } else {
263
- displayMessage = `${clc.magentaBright('active:')} ${clc.bgBlackBright(gitRef)}`
264
- console.log(`${clc.yellowBright('git mode')} ${clc.magentaBright('active:')} ${clc.bgBlackBright(gitRef)}`)
265
- }
266
- }
267
- console.log(`${clc.yellowBright('git mode')} ${status}:)} ${displayMessage}`)
268
- console.log()
261
+ let statusMessage
262
+ let displayMessage
263
+ if (status == 'not active') {
264
+ statusMessage = clc.bgMagentaBright('not active:')
265
+ displayMessage = `no prior commit - processing all`
266
+ } else {
267
+ statusMessage = clc.magentaBright('active:')
268
+ if (gitRef === undefined) {
269
+ displayMessage = `${clc.bgBlackBright(lastCommit) +
270
+ '..' +
271
+ clc.bgBlackBright(latestCommit)
272
+ }`
273
+ } else {
274
+ let delimiter = '..'
275
+
276
+ if (/\s/.test(gitRef)) {
277
+ delimiter = ' '
278
+ }
279
+
280
+ const refArray = gitRef.split(delimiter)
281
+ const updatedArray = refArray.map((item) => clc.bgBlackBright(item))
282
+ displayMessage = updatedArray.join(delimiter)
283
+ }
284
+ }
285
+ console.log(
286
+ `${clc.yellowBright('git mode')} ${statusMessage} ${displayMessage}`,
287
+ )
288
+ console.log()
269
289
  }
270
290
 
271
291
  function yargCheck(argv, options) {
272
- const argvKeys = Object.keys(argv)
273
- const invalidKeys = argvKeys.filter(key =>
274
- !['_', '$0'].includes(key) &&
275
- !options.string.includes(key) &&
276
- !options.boolean.includes(key) &&
277
- !options.array.includes(key)
278
- )
279
-
280
- if (!argv._.includes('update')) {
281
- checkVersion({axios, spawnSync, currentVersion: pkgObj.version, update: false})
282
- }
283
-
284
- if (invalidKeys.length > 0) {
285
- const invalidKeysWithColor = invalidKeys.map(key => clc.redBright(key))
286
- throw new Error(`Invalid options specified: ${invalidKeysWithColor.join(', ')}`)
287
- }
288
-
289
- const name = argv.name
290
- types = (argv.type !== undefined) ? argv.type.split(',') : typeArray
291
- types.forEach(type => {
292
- type = type.trim()
293
- if (!typeArray.includes(type)) {
294
- throw new Error(`Invalid type: ${type}`)
295
- }
296
- })
297
-
298
- if (types.length > 1) {
299
- // if using multiple types you cannot specify name
300
- if ((typeof name != 'undefined' && name != '')) {
301
- throw new Error(clc.redBright('You cannot specify ' + clc.whiteBright.bgRedBright('--name') + ' when using multiple types.'))
302
- }
303
- } else {
304
- switch (argv.type) {
305
- case 'label':
306
- if ((typeof name != 'undefined' && name != '')) {
307
- throw new Error(clc.redBright('You cannot specify ' + clc.whiteBright.bgRedBright('--name') + ' when using label.'))
308
- }
309
- break
310
- }
311
- }
312
- return true
292
+ const argvKeys = Object.keys(argv)
293
+ const invalidKeys = argvKeys.filter(
294
+ (key) =>
295
+ !['_', '$0'].includes(key) &&
296
+ !options.string.includes(key) &&
297
+ !options.boolean.includes(key) &&
298
+ !options.array.includes(key),
299
+ )
300
+
301
+ if (!argv._.includes('update')) {
302
+ checkVersion({
303
+ axios,
304
+ spawnSync,
305
+ currentVersion: pkgObj.version,
306
+ update: false,
307
+ })
308
+ }
309
+
310
+ if (invalidKeys.length > 0) {
311
+ const invalidKeysWithColor = invalidKeys.map((key) =>
312
+ clc.redBright(key),
313
+ )
314
+ throw new Error(
315
+ `Invalid options specified: ${invalidKeysWithColor.join(', ')}`,
316
+ )
317
+ }
318
+
319
+ const name = argv.name
320
+ types = argv.type !== undefined ? argv.type.split(',') : typeArray
321
+ types.forEach((type) => {
322
+ type = type.trim()
323
+ if (!typeArray.includes(type)) {
324
+ throw new Error(`Invalid type: ${type}`)
325
+ }
326
+ })
327
+
328
+ if (types.length > 1) {
329
+ // if using multiple types you cannot specify name
330
+ if (typeof name != 'undefined' && name != '') {
331
+ throw new Error(
332
+ clc.redBright(
333
+ 'You cannot specify ' +
334
+ clc.whiteBright.bgRedBright('--name') +
335
+ ' when using multiple types.',
336
+ ),
337
+ )
338
+ }
339
+ } else {
340
+ switch (argv.type) {
341
+ case 'label':
342
+ if (typeof name != 'undefined' && name != '') {
343
+ throw new Error(
344
+ clc.redBright(
345
+ 'You cannot specify ' +
346
+ clc.whiteBright.bgRedBright('--name') +
347
+ ' when using label.',
348
+ ),
349
+ )
350
+ }
351
+ break
352
+ }
353
+ }
354
+ return true
313
355
  }
314
356
 
315
357
  function displayMessageAndDuration(startTime, message) {
316
- const diff = process.hrtime.bigint() - BigInt(startTime)
317
- let durationMessage
318
- let executionTime = convertHrtime(diff)
319
- let minutes = Math.floor((executionTime.seconds + Math.round(executionTime.milliseconds / 100000)) / 60)
320
- let seconds = Math.round((executionTime.seconds + Math.round(executionTime.milliseconds / 100000)) % 60)
321
- if (minutes == 0 && seconds == 0) {
322
- durationMessage = message + clc.magentaBright(`<1s`)
323
- } else if (minutes > 0) {
324
- durationMessage = message + clc.magentaBright(`${minutes}m ${seconds}s`)
325
- } else {
326
- durationMessage = message + clc.magentaBright(`${seconds}s`)
327
- }
328
- console.log('\n' + durationMessage)
358
+ const diff = process.hrtime.bigint() - BigInt(startTime)
359
+ let durationMessage
360
+ let executionTime = convertHrtime(diff)
361
+ let minutes = Math.floor(
362
+ (executionTime.seconds +
363
+ Math.round(executionTime.milliseconds / 100000)) /
364
+ 60,
365
+ )
366
+ let seconds = Math.round(
367
+ (executionTime.seconds +
368
+ Math.round(executionTime.milliseconds / 100000)) %
369
+ 60,
370
+ )
371
+ if (minutes == 0 && seconds == 0) {
372
+ durationMessage = message + clc.magentaBright(`<1s`)
373
+ } else if (minutes > 0) {
374
+ durationMessage = message + clc.magentaBright(`${minutes}m ${seconds}s`)
375
+ } else {
376
+ durationMessage = message + clc.magentaBright(`${seconds}s`)
377
+ }
378
+ console.log('\n' + durationMessage)
329
379
  }
330
380
 
331
381
  let callAmount = 0
332
382
  process.on('SIGINT', function () {
333
- if (callAmount < 1) {
334
- console.log(`✅ Received abort command`)
335
- process.exit(1)
336
- }
383
+ if (callAmount < 1) {
384
+ console.log(`✅ Received abort command`)
385
+ process.exit(1)
386
+ }
337
387
 
338
- callAmount++
388
+ callAmount++
339
389
  })
340
390
 
341
391
  function splitHandler(argv, startTime) {
342
- const split = processSplit(types[0], argv)
343
- split.then((resolve) => {
344
- types.shift() // remove first item from array
345
- if (types.length > 0) {
346
- console.log()
347
- splitHandler(argv, startTime)
348
- } else {
349
- if (argv.type === undefined || argv.type.split(',').length > 1) {
350
- let message = `Split completed in `
351
- displayMessageAndDuration(startTime, message)
352
- }
353
- }
354
- })
392
+ const split = processSplit(types[0], argv)
393
+ split.then((resolve) => {
394
+ types.shift() // remove first item from array
395
+ if (types.length > 0) {
396
+ console.log()
397
+ splitHandler(argv, startTime)
398
+ } else {
399
+ if (argv.type === undefined || argv.type.split(',').length > 1) {
400
+ let message = `Split completed in `
401
+ displayMessageAndDuration(startTime, message)
402
+ }
403
+ }
404
+ })
355
405
  }
356
406
 
357
407
  function processSplit(typeItem, argv) {
358
- return new Promise((resolve, reject) => {
359
- const processed = {
360
- total: 0,
361
- errors: 0,
362
- current: 1,
363
- }
364
- const startTime = process.hrtime.bigint()
365
-
366
- if (!typeArray.includes(typeItem)) {
367
- global.logger.error('Metadata type not supported: ' + typeItem)
368
- process.exit(1)
369
- }
370
-
371
- const fileList = []
372
- const typeObj = global.metaTypes[typeItem]
373
- const type = typeObj.type
374
- const metaExtension = `.${type}-meta.xml`
375
-
376
- let sourceDir = argv.source || ''
377
- let targetDir = argv.target || ''
378
- let name = argv.name
379
- let all = (argv.type === undefined || argv.type.split(',').length > 1) ? true : argv.all
380
-
381
- if (type == global.metaTypes.label.type) {
382
- name = global.metaTypes.label.definition.root
383
- }
384
- sourceDir = path.join(global.__basedir, packageDir, 'main', 'default', typeObj.definition.directory)
385
- if (targetDir == '') {
386
- targetDir = path.join(global.__basedir, packageDir + '-party', 'main', 'default', typeObj.definition.directory)
387
- } else {
388
- targetDir = path.join(targetDir, 'main', 'default', typeObj.definition.directory)
389
- }
390
- let metaDirPath = sourceDir
391
-
392
- if (!all) {
393
- let metaFilePath = path.join(metaDirPath, name)
394
- if (!fileUtils.fileExists(metaFilePath)) {
395
- name += metaExtension
396
- metaFilePath = path.join(metaDirPath, name)
397
- if (!fileUtils.fileExists(metaFilePath)) {
398
- global.logger.error('File not found: ' + metaFilePath)
399
- process.exit(1)
400
- }
401
- }
402
- fileList.push(name)
403
- } else {
404
- if (fileUtils.directoryExists(sourceDir)) {
405
- fileUtils.getFiles(sourceDir, metaExtension).forEach(file => {
406
- fileList.push(file)
407
- })
408
- }
409
- }
410
-
411
- processed.total = fileList.length
412
-
413
- if (processed.total == 0) resolve(true)
414
-
415
- console.log(`${clc.bgBlackBright('Source path:')} ${sourceDir}`)
416
- console.log(`${clc.bgBlackBright('Target path:')} ${targetDir}`)
417
- console.log()
418
- console.log(`Splitting a total of ${processed.total} file(s)`)
419
- console.log()
420
-
421
- const promList = []
422
- fileList.forEach(metaFile => {
423
- const metadataItem = new metadataSplit.Split({
424
- metadataDefinition: typeObj.definition,
425
- sourceDir: sourceDir,
426
- targetDir: targetDir,
427
- metaFilePath: path.join(sourceDir, metaFile),
428
- sequence: promList.length + 1,
429
- total: processed.total,
430
- })
431
- const metadataItemProm = metadataItem.split()
432
- promList.push(metadataItemProm)
433
- metadataItemProm.then((resolve, reject) => {
434
- if (resolve == false) {
435
- processed.errors++
436
- processed.current--
437
- } else {
438
- processed.current++
439
- }
440
- })
441
- })
442
- Promise.allSettled(promList).then((results) => {
443
- let message = `Split ${clc.bgBlackBright((processed.current > promList.length) ? promList.length : processed.current)} file(s) ${(processed.errors > 0) ? 'with ' + clc.bgBlackBright.red(processed.errors) + ' error(s) ' : ''}in `
444
- displayMessageAndDuration(startTime, message)
445
- resolve(true)
446
- })
447
- })
408
+ return new Promise((resolve, reject) => {
409
+ const processed = {
410
+ total: 0,
411
+ errors: 0,
412
+ current: 1,
413
+ }
414
+ const startTime = process.hrtime.bigint()
415
+
416
+ if (!typeArray.includes(typeItem)) {
417
+ global.logger.error('Metadata type not supported: ' + typeItem)
418
+ process.exit(1)
419
+ }
420
+
421
+ const fileList = []
422
+ const typeObj = global.metaTypes[typeItem]
423
+ const type = typeObj.type
424
+ const metaExtension = `.${type}-meta.xml`
425
+
426
+ let sourceDir = argv.source || ''
427
+ let targetDir = argv.target || ''
428
+ let name = argv.name
429
+ let all =
430
+ argv.type === undefined || name === undefined ? true : argv.all
431
+
432
+ if (type == global.metaTypes.label.type) {
433
+ name = global.metaTypes.label.definition.root
434
+ }
435
+ sourceDir = path.join(
436
+ global.__basedir,
437
+ packageDir,
438
+ 'main',
439
+ 'default',
440
+ typeObj.definition.directory,
441
+ )
442
+ if (targetDir == '') {
443
+ targetDir = path.join(
444
+ global.__basedir,
445
+ packageDir + '-party',
446
+ 'main',
447
+ 'default',
448
+ typeObj.definition.directory,
449
+ )
450
+ } else {
451
+ targetDir = path.join(
452
+ targetDir,
453
+ 'main',
454
+ 'default',
455
+ typeObj.definition.directory,
456
+ )
457
+ }
458
+ let metaDirPath = sourceDir
459
+
460
+ if (!all) {
461
+ let metaFilePath = path.join(metaDirPath, name)
462
+ if (!fileUtils.fileExists(metaFilePath)) {
463
+ name += metaExtension
464
+ metaFilePath = path.join(metaDirPath, name)
465
+ if (!fileUtils.fileExists(metaFilePath)) {
466
+ global.logger.error('File not found: ' + metaFilePath)
467
+ process.exit(1)
468
+ }
469
+ }
470
+ fileList.push(name)
471
+ } else {
472
+ if (fileUtils.directoryExists(sourceDir)) {
473
+ fileUtils.getFiles(sourceDir, metaExtension).forEach((file) => {
474
+ fileList.push(file)
475
+ })
476
+ }
477
+ }
478
+
479
+ processed.total = fileList.length
480
+
481
+ if (processed.total == 0) resolve(true)
482
+
483
+ console.log(`${clc.bgBlackBright('Source path:')} ${sourceDir}`)
484
+ console.log(`${clc.bgBlackBright('Target path:')} ${targetDir}`)
485
+ console.log()
486
+ console.log(`Splitting a total of ${processed.total} file(s)`)
487
+ console.log()
488
+
489
+ const promList = []
490
+ fileList.forEach((metaFile) => {
491
+ const metadataItem = new metadataSplit.Split({
492
+ metadataDefinition: typeObj.definition,
493
+ sourceDir: sourceDir,
494
+ targetDir: targetDir,
495
+ metaFilePath: path.join(sourceDir, metaFile),
496
+ sequence: promList.length + 1,
497
+ total: processed.total,
498
+ })
499
+ const metadataItemProm = metadataItem.split()
500
+ promList.push(metadataItemProm)
501
+ metadataItemProm.then((resolve, reject) => {
502
+ if (resolve == false) {
503
+ processed.errors++
504
+ processed.current--
505
+ } else {
506
+ processed.current++
507
+ }
508
+ })
509
+ })
510
+ Promise.allSettled(promList).then((results) => {
511
+ let message = `Split ${clc.bgBlackBright(
512
+ processed.current > promList.length
513
+ ? promList.length
514
+ : processed.current,
515
+ )} file(s) ${processed.errors > 0
516
+ ? 'with ' +
517
+ clc.bgBlackBright.red(processed.errors) +
518
+ ' error(s) '
519
+ : ''
520
+ }in `
521
+ displayMessageAndDuration(startTime, message)
522
+ resolve(true)
523
+ })
524
+ })
448
525
  }
449
526
 
450
527
  function combineHandler(argv, startTime) {
451
- const combine = processCombine(types[0], argv)
452
- combine.then((resolve) => {
453
- types.shift() // remove first item from array
454
- if (types.length > 0) {
455
- console.log()
456
- combineHandler(argv, startTime)
457
- } else {
458
- if (global.git.latest !== undefined) {
459
- git.updateLastCommit(global.__basedir, global.git.latest)
460
- }
461
- if (argv.type === undefined || argv.type.split(',').length > 1) {
462
- let message = `Split completed in `
463
- displayMessageAndDuration(startTime, message)
464
- }
465
- }
466
- })
467
- combine.catch((error) => {
468
- throw error
469
- })
470
-
528
+ const combine = processCombine(types[0], argv)
529
+ combine.then((resolve) => {
530
+ types.shift() // remove first item from array
531
+ if (types.length > 0) {
532
+ console.log()
533
+ combineHandler(argv, startTime)
534
+ } else {
535
+ if (global.git.latest !== undefined) {
536
+ git.updateLastCommit(global.__basedir, global.git.latest)
537
+ }
538
+ if (argv.type === undefined || argv.type.split(',').length > 1) {
539
+ let message = `Split completed in `
540
+ displayMessageAndDuration(startTime, message)
541
+ }
542
+ }
543
+ })
544
+ combine.catch((error) => {
545
+ throw error
546
+ })
471
547
  }
472
548
 
473
549
  function processCombine(typeItem, argv) {
474
- return new Promise((resolve, reject) => {
475
- const processed = {
476
- total: 0,
477
- errors: 0,
478
- current: 1,
479
- }
480
- const startTime = process.hrtime.bigint()
481
-
482
- if (!typeArray.includes(typeItem)) {
483
- global.logger.error('Metadata type not supported: ' + typeItem)
484
- process.exit(1)
485
- }
486
-
487
- let processList = []
488
- const typeObj = global.metaTypes[typeItem]
489
- const type = typeObj.type
490
-
491
- let sourceDir = argv.source || ''
492
- let targetDir = argv.target || ''
493
- let name = argv.name
494
- let all = (argv.type === undefined || argv.type.split(',').length > 1) ? true : argv.all
495
- let addManifest = argv.package
496
- let desManifest = argv.destructive
497
-
498
- sourceDir = path.join(global.__basedir, packageDir + '-party', 'main', 'default', typeObj.definition.directory)
499
- if (targetDir == '') {
500
- targetDir = path.join(global.__basedir, packageDir, 'main', 'default', typeObj.definition.directory)
501
- } else {
502
- targetDir = path.join(targetDir, 'main', 'default', typeObj.definition.directory)
503
- }
504
-
505
-
506
-
507
- if (type == global.metaTypes.label.type) {
508
- if (!global.git.enabled || [...new Set([...global.metaTypes[typeItem].add.directories, ...global.metaTypes[typeItem].remove.directories])].includes(global.metaTypes[typeItem].definition.root)) {
509
- processList.push(global.metaTypes.label.definition.root)
510
- }
511
- } else if (!all) {
512
- let metaDirPath = path.join(sourceDir, name)
513
- if (!fileUtils.directoryExists(metaDirPath)) {
514
- global.logger.error('Directory not found: ' + metaDirPath)
515
- process.exit(1)
516
- }
517
- processList.push(name)
518
- } else {
519
- if (global.git.enabled) {
520
- processList = [...new Set([...global.metaTypes[typeItem].add.directories, ...global.metaTypes[typeItem].remove.directories])]
521
- } else {
522
- processList = fileUtils.getDirectories(sourceDir)
523
- }
524
- }
525
-
526
- processed.total = processList.length
527
- console.log(`${clc.bgBlackBright(processed.total)} ${typeItem} file(s) to process`)
528
-
529
- // Abort if there are no files to process
530
- if (processed.total == 0) {
531
- resolve(true)
532
- return
533
- }
534
-
535
- console.log()
536
- console.log(`${clc.bgBlackBright('Source path:')} ${sourceDir}`)
537
- console.log(`${clc.bgBlackBright('Target path:')} ${targetDir}`)
538
- console.log()
539
-
540
- const promList = []
541
- processList.forEach(metaDir => {
542
- const metadataItem = new metadataCombine.Combine({
543
- metadataDefinition: typeObj.definition,
544
- sourceDir: sourceDir,
545
- targetDir: targetDir,
546
- metaDir: metaDir,
547
- sequence: promList.length + 1,
548
- total: processed.total,
549
- addManifest: addManifest,
550
- desManifest: desManifest,
551
- })
552
- const metadataItemProm = metadataItem.combine()
553
- promList.push(metadataItemProm)
554
- metadataItemProm.then((resolve, reject) => {
555
- processed.current++
556
- })
557
- })
558
-
559
- Promise.allSettled(promList).then((results) => {
560
- let successes = 0
561
- let errors = processed.errors++
562
- results.forEach(result => {
563
- if (result.value == true) {
564
- successes++
565
- } else if (result.value == false) {
566
- errors++
567
- }
568
- })
569
- let message = `Combined ${clc.bgBlackBright(successes)} file(s) ${(errors > 0) ? 'with ' + clc.bgBlackBright(errors) + 'error(s) ' : ''}in `
570
- displayMessageAndDuration(startTime, message)
571
- resolve(true)
572
- })
573
- })
550
+ return new Promise((resolve, reject) => {
551
+ const processed = {
552
+ total: 0,
553
+ errors: 0,
554
+ current: 1,
555
+ }
556
+ const startTime = process.hrtime.bigint()
557
+
558
+ if (!typeArray.includes(typeItem)) {
559
+ global.logger.error('Metadata type not supported: ' + typeItem)
560
+ process.exit(1)
561
+ }
562
+
563
+ let processList = []
564
+ const typeObj = global.metaTypes[typeItem]
565
+ const type = typeObj.type
566
+
567
+ let sourceDir = argv.source || ''
568
+ let targetDir = argv.target || ''
569
+ let name = argv.name
570
+ let all =
571
+ argv.type === undefined || name === undefined ? true : argv.all
572
+ let addManifest = argv.package
573
+ let desManifest = argv.destructive
574
+
575
+ sourceDir = path.join(
576
+ global.__basedir,
577
+ packageDir + '-party',
578
+ 'main',
579
+ 'default',
580
+ typeObj.definition.directory,
581
+ )
582
+ if (targetDir == '') {
583
+ targetDir = path.join(
584
+ global.__basedir,
585
+ packageDir,
586
+ 'main',
587
+ 'default',
588
+ typeObj.definition.directory,
589
+ )
590
+ } else {
591
+ targetDir = path.join(
592
+ targetDir,
593
+ 'main',
594
+ 'default',
595
+ typeObj.definition.directory,
596
+ )
597
+ }
598
+
599
+ if (type == global.metaTypes.label.type) {
600
+ if (
601
+ !global.git.enabled ||
602
+ [
603
+ ...new Set([
604
+ ...global.metaTypes[typeItem].add.directories,
605
+ ...global.metaTypes[typeItem].remove.directories,
606
+ ]),
607
+ ].includes(global.metaTypes[typeItem].definition.root)
608
+ ) {
609
+ processList.push(global.metaTypes.label.definition.root)
610
+ }
611
+ } else if (!all) {
612
+ let metaDirPath = path.join(sourceDir, name)
613
+ if (!fileUtils.directoryExists(metaDirPath)) {
614
+ global.logger.error('Directory not found: ' + metaDirPath)
615
+ process.exit(1)
616
+ }
617
+ processList.push(name)
618
+ } else {
619
+ if (global.git.enabled) {
620
+ processList = [
621
+ ...new Set([
622
+ ...global.metaTypes[typeItem].add.directories,
623
+ ...global.metaTypes[typeItem].remove.directories,
624
+ ]),
625
+ ]
626
+ } else {
627
+ processList = fileUtils.getDirectories(sourceDir)
628
+ }
629
+ }
630
+
631
+ processed.total = processList.length
632
+ console.log(
633
+ `${clc.bgBlackBright(
634
+ processed.total,
635
+ )} ${typeItem} file(s) to process`,
636
+ )
637
+
638
+ // Abort if there are no files to process
639
+ if (processed.total == 0) {
640
+ resolve(true)
641
+ return
642
+ }
643
+
644
+ console.log()
645
+ console.log(`${clc.bgBlackBright('Source path:')} ${sourceDir}`)
646
+ console.log(`${clc.bgBlackBright('Target path:')} ${targetDir}`)
647
+ console.log()
648
+
649
+ const promList = []
650
+ processList.forEach((metaDir) => {
651
+ const metadataItem = new metadataCombine.Combine({
652
+ metadataDefinition: typeObj.definition,
653
+ sourceDir: sourceDir,
654
+ targetDir: targetDir,
655
+ metaDir: metaDir,
656
+ sequence: promList.length + 1,
657
+ total: processed.total,
658
+ addManifest: addManifest,
659
+ desManifest: desManifest,
660
+ })
661
+ const metadataItemProm = metadataItem.combine()
662
+ promList.push(metadataItemProm)
663
+ metadataItemProm.then((resolve, reject) => {
664
+ processed.current++
665
+ })
666
+ })
667
+
668
+ Promise.allSettled(promList).then((results) => {
669
+ let successes = 0
670
+ let errors = processed.errors++
671
+ results.forEach((result) => {
672
+ if (result.value == true) {
673
+ successes++
674
+ } else if (result.value == false) {
675
+ errors++
676
+ }
677
+ })
678
+ let message = `Combined ${clc.bgBlackBright(successes)} file(s) ${errors > 0
679
+ ? 'with ' + clc.bgBlackBright(errors) + 'error(s) '
680
+ : ''
681
+ }in `
682
+ displayMessageAndDuration(startTime, message)
683
+ resolve(true)
684
+ })
685
+ })
574
686
  }
575
687
 
576
688
  function gitFiles(data) {
577
- data.forEach(item => {
578
- if (item.path.indexOf(packageDir + '-party/') == 0) {
579
- const pathArray = item.path.split('/')
580
- if (pathArray.length > 3) {
581
- if (getDirectories().includes(pathArray[3])) {
582
- switch (item.action) {
583
- case 'add':
584
- global.metaTypes[getKey(pathArray[3])].add.files.push(path.join(global.__basedir, item.path))
585
- if (!global.metaTypes[getKey(pathArray[3])].add.directories.includes(pathArray[4])) {
586
- global.metaTypes[getKey(pathArray[3])].add.directories.push(pathArray[4])
587
- }
588
- break
589
- case 'delete':
590
- global.metaTypes[getKey(pathArray[3])].remove.files.push(path.join(global.__basedir, item.path))
591
- if (!global.metaTypes[getKey(pathArray[3])].remove.directories.includes(pathArray[4])) {
592
- global.metaTypes[getKey(pathArray[3])].remove.directories.push(pathArray[4])
593
- }
594
- break
595
- }
596
- }
597
- }
598
- }
599
- })
689
+ data.forEach((item) => {
690
+ if (item.path.indexOf(packageDir + '-party/') == 0) {
691
+ const pathArray = item.path.split('/')
692
+ if (pathArray.length > 3) {
693
+ if (getDirectories().includes(pathArray[3])) {
694
+ switch (item.action) {
695
+ case 'add':
696
+ global.metaTypes[
697
+ getKey(pathArray[3])
698
+ ].add.files.push(
699
+ path.join(global.__basedir, item.path),
700
+ )
701
+ if (
702
+ !global.metaTypes[
703
+ getKey(pathArray[3])
704
+ ].add.directories.includes(pathArray[4])
705
+ ) {
706
+ global.metaTypes[
707
+ getKey(pathArray[3])
708
+ ].add.directories.push(pathArray[4])
709
+ }
710
+ break
711
+ case 'delete':
712
+ global.metaTypes[
713
+ getKey(pathArray[3])
714
+ ].remove.files.push(
715
+ path.join(global.__basedir, item.path),
716
+ )
717
+ if (
718
+ !global.metaTypes[
719
+ getKey(pathArray[3])
720
+ ].remove.directories.includes(pathArray[4])
721
+ ) {
722
+ global.metaTypes[
723
+ getKey(pathArray[3])
724
+ ].remove.directories.push(pathArray[4])
725
+ }
726
+ break
727
+ }
728
+ }
729
+ }
730
+ }
731
+ })
600
732
  }
601
733
 
602
734
  function getKey(directory) {
603
- let key = undefined
604
- Object.keys(global.metaTypes).forEach(type => {
605
- if (global.metaTypes[type].definition.directory == directory) {
606
- key = type
607
- }
608
- })
609
- return key
735
+ let key = undefined
736
+ Object.keys(global.metaTypes).forEach((type) => {
737
+ if (global.metaTypes[type].definition.directory == directory) {
738
+ key = type
739
+ }
740
+ })
741
+ return key
610
742
  }
611
743
 
612
744
  function getDirectories() {
613
- const types = []
614
- Object.keys(global.metaTypes).forEach(type => {
615
- try {
616
- types.push(global.metaTypes[type].definition.directory)
617
- } catch (error) {
618
- throw error
619
- }
620
- })
621
- return types
745
+ const types = []
746
+ Object.keys(global.metaTypes).forEach((type) => {
747
+ try {
748
+ types.push(global.metaTypes[type].definition.directory)
749
+ } catch (error) {
750
+ throw error
751
+ }
752
+ })
753
+ return types
622
754
  }
623
755
 
624
756
  function displayHeader() {
625
- const box = {
626
- topLeft: '╭',
627
- topRight: '╮',
628
- bottomLeft: '╰',
629
- bottomRight: '╯',
630
- horizontal: '─',
631
- vertical: '│',
632
- }
633
- let versionString = `sfparty v${pkgObj.version}${(process.stdout.columns > pkgObj.description.length + 15) ? ' - ' + pkgObj.description : ''}`
634
- let titleMessage = `${global.icons.party} ${clc.yellowBright(versionString)} ${global.icons.party}`
635
- titleMessage = titleMessage.padEnd((process.stdout.columns / 2) + versionString.length / 1.65)
636
- titleMessage = titleMessage.padStart(process.stdout.columns)
637
- titleMessage = clc.blackBright(box.vertical) + ' ' + titleMessage + ' ' + clc.blackBright(box.vertical)
638
- console.log(`${clc.blackBright(box.topLeft + box.horizontal.repeat(process.stdout.columns - 2) + box.topRight)}`)
639
- console.log(titleMessage)
640
- console.log(`${clc.blackBright(box.bottomLeft + box.horizontal.repeat(process.stdout.columns - 2) + box.bottomRight)}`)
641
- console.log()
757
+ const box = {
758
+ topLeft: '╭',
759
+ topRight: '╮',
760
+ bottomLeft: '╰',
761
+ bottomRight: '╯',
762
+ horizontal: '─',
763
+ vertical: '│',
764
+ }
765
+ let versionString = `sfparty v${pkgObj.version}${process.stdout.columns > pkgObj.description.length + 15
766
+ ? ' - ' + pkgObj.description
767
+ : ''
768
+ }`
769
+ let titleMessage = `${global.icons.party} ${clc.yellowBright(
770
+ versionString,
771
+ )} ${global.icons.party}`
772
+ titleMessage = titleMessage.padEnd(
773
+ process.stdout.columns / 2 + versionString.length / 1.65,
774
+ )
775
+ titleMessage = titleMessage.padStart(process.stdout.columns)
776
+ titleMessage =
777
+ clc.blackBright(box.vertical) +
778
+ ' ' +
779
+ titleMessage +
780
+ ' ' +
781
+ clc.blackBright(box.vertical)
782
+ console.log(
783
+ `${clc.blackBright(
784
+ box.topLeft +
785
+ box.horizontal.repeat(process.stdout.columns - 2) +
786
+ box.topRight,
787
+ )}`,
788
+ )
789
+ console.log(titleMessage)
790
+ console.log(
791
+ `${clc.blackBright(
792
+ box.bottomLeft +
793
+ box.horizontal.repeat(process.stdout.columns - 2) +
794
+ box.bottomRight,
795
+ )}`,
796
+ )
797
+ console.log()
642
798
  }
643
799
 
644
800
  function getRootPath(packageDir) {
645
- let rootPath = fileUtils.find('sfdx-project.json')
646
- let defaultDir
647
- if (rootPath) {
648
- global.__basedir = fileUtils.fileInfo(rootPath).dirname
649
- let packageJSON
650
- try {
651
- packageJSON = JSON.parse(readFileSync(rootPath))
652
- } catch (error) {
653
- if (error.message.indexOf('JSON at position') > 0) {
654
- global.displayError('sfdx-project.json has invalid JSON', true)
655
- } else {
656
- global.displayError(error, true)
657
- }
658
- }
659
- if (Array.isArray(packageJSON.packageDirectories)) {
660
- packageJSON.packageDirectories.every(directory => {
661
- if (directory.default || packageJSON.packageDirectories.length == 1) defaultDir = directory.path
662
- if (directory == packageDir) {
663
- defaultDir = directory
664
- return false
665
- }
666
- return true
667
- })
668
- }
669
- } else {
670
- global.logger.error('Could not determine base path of Salesforce source directory. No sfdx-project.json found. Please specify a source path or execute from Salesforce project directory.')
671
- process.exit(1)
672
- }
673
- if (packageDir && packageDir != defaultDir) {
674
- global.logger.error('Could not find directory in sfdx-project.json. Please specify a package directory path from the sfdx-project.json file.')
675
- process.exit(1)
676
- }
677
-
678
- return defaultDir
801
+ let rootPath = fileUtils.find('sfdx-project.json')
802
+ let defaultDir
803
+ if (rootPath) {
804
+ global.__basedir = fileUtils.fileInfo(rootPath).dirname
805
+ let packageJSON
806
+ try {
807
+ packageJSON = JSON.parse(readFileSync(rootPath))
808
+ } catch (error) {
809
+ if (error.message.indexOf('JSON at position') > 0) {
810
+ global.displayError('sfdx-project.json has invalid JSON', true)
811
+ } else {
812
+ global.displayError(error, true)
813
+ }
814
+ }
815
+ if (Array.isArray(packageJSON.packageDirectories)) {
816
+ packageJSON.packageDirectories.every((directory) => {
817
+ if (
818
+ directory.default ||
819
+ packageJSON.packageDirectories.length == 1
820
+ )
821
+ defaultDir = directory.path
822
+ if (directory == packageDir) {
823
+ defaultDir = directory
824
+ return false
825
+ }
826
+ return true
827
+ })
828
+ }
829
+ } else {
830
+ global.logger.error(
831
+ 'Could not determine base path of Salesforce source directory. No sfdx-project.json found. Please specify a source path or execute from Salesforce project directory.',
832
+ )
833
+ process.exit(1)
834
+ }
835
+ if (packageDir && packageDir != defaultDir) {
836
+ global.logger.error(
837
+ 'Could not find directory in sfdx-project.json. Please specify a package directory path from the sfdx-project.json file.',
838
+ )
839
+ process.exit(1)
840
+ }
841
+
842
+ return defaultDir
679
843
  }