@ds-sfdc/sfparty 1.5.2 โ†’ 1.5.4

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.
@@ -9,8 +9,12 @@ on:
9
9
  jobs:
10
10
  build:
11
11
  runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ node: [18, 20]
12
15
  env:
13
16
  working-directory: ./
17
+ HUSKY: 0 # Disable Husky during the CI/CD process
14
18
  steps:
15
19
  - run: echo "๐ŸŽ‰ The job was automatically triggered by a ${{ github.event_name }} event."
16
20
  - run: echo "๐Ÿง This job is now running on a ${{ runner.os }} server hosted by GitHub!"
@@ -20,7 +24,7 @@ jobs:
20
24
  - name: Setup node ${{ matrix.node }}
21
25
  uses: actions/setup-node@v3
22
26
  with:
23
- node-version: 19
27
+ node-version: ${{ matrix.node }}
24
28
  cache: 'npm'
25
29
  cache-dependency-path: '**/package-lock.json'
26
30
  - run: npm ci
@@ -35,4 +39,4 @@ jobs:
35
39
  - run: echo "๐Ÿงช Running tests ${{ job.status }}."
36
40
  - run: npm test
37
41
  working-directory: ${{env.working-directory}}
38
- - run: echo "๐Ÿ This job's status is ${{ job.status }}."
42
+ - run: echo "๐Ÿ This job's status is ${{ job.status }}."
@@ -0,0 +1,5 @@
1
+ {
2
+ "editor.formatOnPaste": true,
3
+ "editor.formatOnSave": true,
4
+ "editor.formatOnType": true
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ds-sfdc/sfparty",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "Salesforce metadata XML splitter for CI/CD",
5
5
  "type": "module",
6
6
  "repository": {
@@ -12,7 +12,8 @@
12
12
  },
13
13
  "main": "src/index.js",
14
14
  "scripts": {
15
- "test": "jest"
15
+ "test": "jest --no-cache",
16
+ "prepare": "husky || true"
16
17
  },
17
18
  "keywords": [
18
19
  "salesforce,metadata,xml,split,yaml,json"
@@ -20,30 +21,33 @@
20
21
  "author": "Tim Paulaskas",
21
22
  "license": "BSD-3-Clause",
22
23
  "dependencies": {
23
- "axios": "^1.2.2",
24
- "cli-color": "^2.0.3",
25
- "cli-spinners": "^2.7.0",
24
+ "axios": "^1.6.8",
25
+ "cli-color": "^2.0.4",
26
+ "cli-spinners": "^2.9.2",
26
27
  "convert-hrtime": "^5.0.0",
27
28
  "js-yaml": "^4.1.0",
28
- "log-update": "^5.0.1",
29
- "marked": "^4.2.12",
30
- "marked-terminal": "^5.1.1",
31
- "pretty-quick": "^3.1.3",
32
- "semver": "^7.3.8",
33
- "util": "^0.10.3",
34
- "winston": "^3.8.2",
29
+ "log-update": "^6.0.0",
30
+ "marked": "^12.0.1",
31
+ "marked-terminal": "^7.0.0",
32
+ "pretty-quick": "^4.0.0",
33
+ "semver": "^7.6.0",
34
+ "util": "^0.12.5",
35
+ "winston": "^3.13.0",
35
36
  "xml2js": "^0.6.2",
36
- "yargs": "^17.6.2"
37
+ "yargs": "^17.7.2"
37
38
  },
38
39
  "devDependencies": {
39
- "@babel/core": "^7.20.12",
40
- "@babel/preset-env": "^7.20.2",
41
- "@commitlint/cli": "^17.4.0",
42
- "@commitlint/config-conventional": "^17.4.0",
43
- "babel-jest": "^29.3.1",
44
- "jest": "^29.3.1",
45
- "nodemon": "^3.0.3",
46
- "prettier": "^2.8.3"
40
+ "@babel/core": "^7.24.4",
41
+ "@babel/preset-env": "^7.24.4",
42
+ "@commitlint/cli": "^19.2.2",
43
+ "@commitlint/config-conventional": "^19.2.2",
44
+ "babel-jest": "^29.7.0",
45
+ "eslint": "^9.0.0",
46
+ "husky": "^9.0.11",
47
+ "jest": "^29.7.0",
48
+ "lint-staged": "^15.2.2",
49
+ "nodemon": "^3.1.0",
50
+ "prettier": "^3.2.5"
47
51
  },
48
52
  "engines": {
49
53
  "node": ">=0.11"
@@ -55,5 +59,11 @@
55
59
  "directories": {
56
60
  "lib": "lib",
57
61
  "test": "tests"
62
+ },
63
+ "lint-staged": {
64
+ "*.js": [
65
+ "eslint --fix",
66
+ "prettier --write"
67
+ ]
58
68
  }
59
69
  }
package/src/index.js CHANGED
@@ -104,7 +104,7 @@ global.metaTypes = {
104
104
  let types = []
105
105
  const packageDir = getRootPath()
106
106
 
107
- let errorMessage = clc.red(
107
+ const errorMessage = clc.red(
108
108
  'Please specify the action of ' +
109
109
  clc.whiteBright.bgRedBright('split') +
110
110
  ' or ' +
@@ -193,7 +193,7 @@ yargs(hideBin(process.argv))
193
193
  global.format = argv.format
194
194
  const startProm = new Promise((resolve, reject) => {
195
195
  if (argv.git !== undefined) {
196
- let gitRef = argv.git.trim()
196
+ const gitRef = argv.git.trim()
197
197
  global.git.append = argv.append || global.git.append
198
198
  global.git.delta = argv.delta || global.git.delta
199
199
  if (argv.git === '') {
@@ -259,9 +259,9 @@ yargs(hideBin(process.argv))
259
259
  global.git.enabled = result
260
260
 
261
261
  if (global.git.enabled) {
262
- let addManifest =
262
+ const addManifest =
263
263
  argv.package || 'manifest/package-party.xml'
264
- let desManifest =
264
+ const desManifest =
265
265
  argv.destructive ||
266
266
  'manifest/destructiveChanges-party.xml'
267
267
 
@@ -413,13 +413,13 @@ function yargCheck(argv, options) {
413
413
  function displayMessageAndDuration(startTime, message) {
414
414
  const diff = process.hrtime.bigint() - BigInt(startTime)
415
415
  let durationMessage
416
- let executionTime = convertHrtime(diff)
417
- let minutes = Math.floor(
416
+ const executionTime = convertHrtime(diff)
417
+ const minutes = Math.floor(
418
418
  (executionTime.seconds +
419
419
  Math.round(executionTime.milliseconds / 100000)) /
420
420
  60,
421
421
  )
422
- let seconds = Math.round(
422
+ const seconds = Math.round(
423
423
  (executionTime.seconds +
424
424
  Math.round(executionTime.milliseconds / 100000)) %
425
425
  60,
@@ -453,7 +453,7 @@ function splitHandler(argv, startTime) {
453
453
  splitHandler(argv, startTime)
454
454
  } else {
455
455
  if (argv.type === undefined || argv.type.split(',').length > 1) {
456
- let message = `Split completed in `
456
+ const message = `Split completed in `
457
457
  displayMessageAndDuration(startTime, message)
458
458
  }
459
459
  checkVersion({
@@ -488,7 +488,7 @@ function processSplit(typeItem, argv) {
488
488
  let sourceDir = argv.source || ''
489
489
  let targetDir = argv.target || ''
490
490
  let name = argv.name
491
- let all =
491
+ const all =
492
492
  argv.type === undefined || name === undefined ? true : argv.all
493
493
 
494
494
  if (type == global.metaTypes.label.type) {
@@ -517,7 +517,7 @@ function processSplit(typeItem, argv) {
517
517
  typeObj.definition.directory,
518
518
  )
519
519
  }
520
- let metaDirPath = sourceDir
520
+ const metaDirPath = sourceDir
521
521
 
522
522
  if (!all) {
523
523
  let metaFilePath = path.join(metaDirPath, name)
@@ -570,15 +570,15 @@ function processSplit(typeItem, argv) {
570
570
  })
571
571
  })
572
572
  Promise.allSettled(promList).then((results) => {
573
- let message = `Split ${clc.bgBlackBright(
573
+ const message = `Split ${clc.bgBlackBright(
574
574
  processed.current > promList.length
575
575
  ? promList.length
576
576
  : processed.current,
577
577
  )} file(s) ${
578
578
  processed.errors > 0
579
579
  ? 'with ' +
580
- clc.bgBlackBright.red(processed.errors) +
581
- ' error(s) '
580
+ clc.bgBlackBright.red(processed.errors) +
581
+ ' error(s) '
582
582
  : ''
583
583
  }in `
584
584
  displayMessageAndDuration(startTime, message)
@@ -590,6 +590,12 @@ function processSplit(typeItem, argv) {
590
590
  function combineHandler(argv, startTime) {
591
591
  const combine = processCombine(types[0], argv)
592
592
  combine.then((resolve) => {
593
+ if (resolve == false) {
594
+ global.logger.error(
595
+ 'Will not continue due to YAML format issues. Please correct and try again.',
596
+ )
597
+ process.exit(1)
598
+ }
593
599
  types.shift() // remove first item from array
594
600
  if (types.length > 0) {
595
601
  console.log()
@@ -608,7 +614,7 @@ function combineHandler(argv, startTime) {
608
614
  desPkg.savePackage(xml2js, fileUtils)
609
615
  }
610
616
  if (argv.type === undefined || argv.type.split(',').length > 1) {
611
- let message = `Combine completed in `
617
+ const message = `Combine completed in `
612
618
  displayMessageAndDuration(startTime, message)
613
619
  }
614
620
  checkVersion({
@@ -644,8 +650,8 @@ function processCombine(typeItem, argv) {
644
650
 
645
651
  let sourceDir = argv.source || ''
646
652
  let targetDir = argv.target || ''
647
- let name = argv.name
648
- let all =
653
+ const name = argv.name
654
+ const all =
649
655
  argv.type === undefined || name === undefined ? true : argv.all
650
656
 
651
657
  sourceDir = path.join(
@@ -685,7 +691,7 @@ function processCombine(typeItem, argv) {
685
691
  processList.push(global.metaTypes.label.definition.root)
686
692
  }
687
693
  } else if (!all) {
688
- let metaDirPath = path.join(sourceDir, name)
694
+ const metaDirPath = path.join(sourceDir, name)
689
695
  if (!fileUtils.directoryExists({ dirPath: metaDirPath, fs })) {
690
696
  global.logger.error('Directory not found: ' + metaDirPath)
691
697
  process.exit(1)
@@ -747,17 +753,24 @@ function processCombine(typeItem, argv) {
747
753
  results.forEach((result) => {
748
754
  if (result.value == true) {
749
755
  successes++
750
- } else if (result.value == false) {
756
+ } else if (
757
+ result.value == false ||
758
+ result.status == 'rejected'
759
+ ) {
751
760
  errors++
752
761
  }
753
762
  })
754
- let message = `Combined ${clc.bgBlackBright(successes)} file(s) ${
763
+ const message = `Combined ${clc.bgBlackBright(successes)} file(s) ${
755
764
  errors > 0
756
- ? 'with ' + clc.bgBlackBright(errors) + 'error(s) '
765
+ ? 'with ' + clc.bgBlackBright(errors) + ' error(s) '
757
766
  : ''
758
767
  }in `
759
768
  displayMessageAndDuration(startTime, message)
760
- resolve(true)
769
+ if (successes == 0 && errors > 0) {
770
+ resolve(false)
771
+ } else {
772
+ resolve(true)
773
+ }
761
774
  })
762
775
  })
763
776
  }
@@ -839,7 +852,7 @@ function displayHeader() {
839
852
  horizontal: 'โ”€',
840
853
  vertical: 'โ”‚',
841
854
  }
842
- let versionString = `sfparty v${pkgObj.version}${
855
+ const versionString = `sfparty v${pkgObj.version}${
843
856
  process.stdout.columns > pkgObj.description.length + 15
844
857
  ? ' - ' + pkgObj.description
845
858
  : ''
@@ -876,7 +889,7 @@ function displayHeader() {
876
889
  }
877
890
 
878
891
  function getRootPath(packageDir) {
879
- let rootPath = fileUtils.find('sfdx-project.json')
892
+ const rootPath = fileUtils.find('sfdx-project.json')
880
893
  let defaultDir
881
894
  if (rootPath) {
882
895
  global.__basedir = fileUtils.fileInfo(rootPath).dirname
@@ -126,11 +126,11 @@ export function saveFile(
126
126
  fileName = fileName.replaceSpecialChars()
127
127
  switch (format) {
128
128
  case 'json':
129
- let jsonString = JSON.stringify(json, null, '\t')
129
+ const jsonString = JSON.stringify(json, null, '\t')
130
130
  fsTmp.writeFileSync(fileName, jsonString)
131
131
  break
132
132
  case 'yaml':
133
- let doc = yaml.dump(json)
133
+ const doc = yaml.dump(json)
134
134
  fsTmp.writeFileSync(fileName, doc)
135
135
  break
136
136
  }
@@ -151,7 +151,11 @@ export function readFile(filePath, convert = true, fsTmp = fs) {
151
151
  flag: 'r',
152
152
  })
153
153
  if (convert && filePath.indexOf('.yaml') != -1) {
154
- result = yaml.load(data)
154
+ result = yaml.load(data, {
155
+ onWarning: (warning) => {
156
+ throw new Error(`YAML parsing warning: ${warning}`)
157
+ },
158
+ })
155
159
  } else if (convert && filePath.indexOf('.json') != -1) {
156
160
  result = JSON.parse(data)
157
161
  } else if (convert && filePath.indexOf('.xml') != -1) {
@@ -173,7 +177,7 @@ export function readFile(filePath, convert = true, fsTmp = fs) {
173
177
  async function convertXML(data) {
174
178
  return new Promise((resolve, reject) => {
175
179
  try {
176
- let parser = new Parser()
180
+ const parser = new Parser()
177
181
  parser.parseString(data, function (err, result) {
178
182
  if (err) throw err
179
183
  resolve(result)
@@ -89,7 +89,7 @@ export class Combine {
89
89
 
90
90
  if (!fileUtils.directoryExists({ dirPath: that.sourceDir, fs }))
91
91
  reject(`Path does not exist: ${that.sourceDir}`)
92
- let types = ['directories', 'singleFiles', 'main']
92
+ const types = ['directories', 'singleFiles', 'main']
93
93
  types.forEach((type) => {
94
94
  if (that.metadataDefinition[type] !== undefined) {
95
95
  that.#types = that.#types.concat(
@@ -120,9 +120,7 @@ export class Combine {
120
120
  that.#delta = that.metadataDefinition.delta && global.git.delta
121
121
 
122
122
  if (that.#delta) {
123
- const pathMatch = `/${that.metadataDefinition.directory}/${
124
- that.#fileName.shortName
125
- }/`
123
+ const pathMatch = `/${that.metadataDefinition.directory}/${that.#fileName.shortName}/`
126
124
 
127
125
  // get a list of all the added files
128
126
  that.#addedFiles = global.metaTypes[
@@ -148,10 +146,10 @@ export class Combine {
148
146
  )
149
147
  }
150
148
 
151
- let success = processParts(that)
149
+ const success = processParts(that)
152
150
  // Ensure we only match existing metadata type directory and item
153
151
 
154
- if (success) {
152
+ if (success === true) {
155
153
  if (
156
154
  !that.metadataDefinition.packageTypeIsDirectory &&
157
155
  global.git.enabled
@@ -173,6 +171,12 @@ export class Combine {
173
171
  }
174
172
  saveXML(that)
175
173
  return true
174
+ } else if (
175
+ success &&
176
+ success.name &&
177
+ success.name == 'YAMLException'
178
+ ) {
179
+ throw error
176
180
  } else {
177
181
  logUpdate(
178
182
  that.#spinnerMessage
@@ -253,7 +257,7 @@ export class Combine {
253
257
  `main.${global.format}`,
254
258
  ),
255
259
  }
256
- let success = processFile(that, key, fileObj, 'main')
260
+ const success = processFile(that, key, fileObj, 'main')
257
261
  if (!success) {
258
262
  throw new Error('delete XML')
259
263
  }
@@ -281,6 +285,8 @@ export class Combine {
281
285
  } catch (error) {
282
286
  if (error.message == 'delete XML') {
283
287
  return false
288
+ } else if (error.name == 'YAMLException') {
289
+ throw error
284
290
  } else {
285
291
  return true
286
292
  }
@@ -471,7 +477,12 @@ export class Combine {
471
477
  ) {
472
478
  return true
473
479
  }
474
- let result = fileUtils.readFile(fileObj.fullName)
480
+ let result
481
+ try {
482
+ result = fileUtils.readFile(fileObj.fullName)
483
+ } catch (error) {
484
+ throw error
485
+ }
475
486
  if (
476
487
  fileObj.fullName ==
477
488
  path.join(
@@ -559,7 +570,7 @@ export class Combine {
559
570
 
560
571
  function hydrateObject(that, json, key, fileObj) {
561
572
  const sortKey = that.metadataDefinition.sortKeys[key]
562
- let object = json.object
573
+ const object = json.object
563
574
 
564
575
  try {
565
576
  json[key].forEach((arrItem) => {
@@ -631,9 +642,9 @@ export class Combine {
631
642
  }
632
643
 
633
644
  function finishMessage(that) {
634
- let executionTime = getTimeDiff(BigInt(that.#startTime))
635
- let durationMessage = `${executionTime.seconds}.${executionTime.milliseconds}s`
636
- let stateIcon =
645
+ const executionTime = getTimeDiff(BigInt(that.#startTime))
646
+ const durationMessage = `${executionTime.seconds}.${executionTime.milliseconds}s`
647
+ const stateIcon =
637
648
  that.#errorMessage == ''
638
649
  ? global.icons.success
639
650
  : global.icons.fail
@@ -746,7 +757,7 @@ function arrangeKeys(that, json, key = undefined) {
746
757
 
747
758
  function getTimeDiff(startTime, endTime = process.hrtime.bigint()) {
748
759
  const diff = BigInt(endTime) - BigInt(startTime)
749
- let executionTime = convertHrtime(diff)
760
+ const executionTime = convertHrtime(diff)
750
761
  executionTime.seconds = Math.round(executionTime.seconds)
751
762
  executionTime.milliseconds = Math.round(executionTime.milliseconds / 1000)
752
763
  if (executionTime.milliseconds == 0 && executionTime.nanoseconds > 0)