@npmcli/arborist 6.0.0 → 6.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.
Files changed (2) hide show
  1. package/lib/yarn-lock.js +41 -13
  2. package/package.json +1 -1
package/lib/yarn-lock.js CHANGED
@@ -7,9 +7,8 @@
7
7
  // <key> <value>
8
8
  //
9
9
  // Assume that any key or value might be quoted, though that's only done
10
- // in practice if certain chars are in the string. Quoting unnecessarily
11
- // does not cause problems for yarn, so that's what we do when we write
12
- // it back.
10
+ // in practice if certain chars are in the string. When writing back, we follow
11
+ // Yarn's rules for quoting, to cause minimal friction.
13
12
  //
14
13
  // The data format would support nested objects, but at this time, it
15
14
  // appears that yarn does not use that for anything, so in the interest
@@ -33,10 +32,44 @@ const consistentResolve = require('./consistent-resolve.js')
33
32
  const { dirname } = require('path')
34
33
  const { breadth } = require('treeverse')
35
34
 
35
+ // Sort Yarn entries respecting the yarn.lock sort order
36
+ const yarnEntryPriorities = {
37
+ name: 1,
38
+ version: 2,
39
+ uid: 3,
40
+ resolved: 4,
41
+ integrity: 5,
42
+ registry: 6,
43
+ dependencies: 7,
44
+ }
45
+
46
+ const priorityThenLocaleCompare = (a, b) => {
47
+ if (!yarnEntryPriorities[a] && !yarnEntryPriorities[b]) {
48
+ return localeCompare(a, b)
49
+ }
50
+ /* istanbul ignore next */
51
+ return (yarnEntryPriorities[a] || 100) > (yarnEntryPriorities[b] || 100) ? 1 : -1
52
+ }
53
+
54
+ const quoteIfNeeded = val => {
55
+ if (
56
+ typeof val === 'boolean' ||
57
+ typeof val === 'number' ||
58
+ val.startsWith('true') ||
59
+ val.startsWith('false') ||
60
+ /[:\s\n\\",[\]]/g.test(val) ||
61
+ !/^[a-zA-Z]/g.test(val)
62
+ ) {
63
+ return JSON.stringify(val)
64
+ }
65
+
66
+ return val
67
+ }
68
+
36
69
  // sort a key/value object into a string of JSON stringified keys and vals
37
70
  const sortKV = obj => Object.keys(obj)
38
71
  .sort(localeCompare)
39
- .map(k => ` ${JSON.stringify(k)} ${JSON.stringify(obj[k])}`)
72
+ .map(k => ` ${quoteIfNeeded(k)} ${quoteIfNeeded(obj[k])}`)
40
73
  .join('\n')
41
74
 
42
75
  // for checking against previous entries
@@ -171,7 +204,7 @@ class YarnLock {
171
204
  toString () {
172
205
  return prefix + [...new Set([...this.entries.values()])]
173
206
  .map(e => e.toString())
174
- .sort(localeCompare).join('\n\n') + '\n'
207
+ .sort((a, b) => localeCompare(a.replace(/"/g, ''), b.replace(/"/g, ''))).join('\n\n') + '\n'
175
208
  }
176
209
 
177
210
  fromTree (tree) {
@@ -323,19 +356,14 @@ class YarnLockEntry {
323
356
  // sort objects to the bottom, then alphabetical
324
357
  return ([...this[_specs]]
325
358
  .sort(localeCompare)
326
- .map(JSON.stringify).join(', ') +
359
+ .map(quoteIfNeeded).join(', ') +
327
360
  ':\n' +
328
361
  Object.getOwnPropertyNames(this)
329
362
  .filter(prop => this[prop] !== null)
330
- .sort(
331
- (a, b) =>
332
- /* istanbul ignore next - sort call order is unpredictable */
333
- (typeof this[a] === 'object') === (typeof this[b] === 'object')
334
- ? localeCompare(a, b)
335
- : typeof this[a] === 'object' ? 1 : -1)
363
+ .sort(priorityThenLocaleCompare)
336
364
  .map(prop =>
337
365
  typeof this[prop] !== 'object'
338
- ? ` ${JSON.stringify(prop)} ${JSON.stringify(this[prop])}\n`
366
+ ? ` ${prop} ${prop === 'integrity' ? this[prop] : JSON.stringify(this[prop])}\n`
339
367
  : Object.keys(this[prop]).length === 0 ? ''
340
368
  : ` ${prop}:\n` + sortKV(this[prop]) + '\n')
341
369
  .join('')).trim()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/arborist",
3
- "version": "6.0.0",
3
+ "version": "6.1.0",
4
4
  "description": "Manage node_modules trees",
5
5
  "dependencies": {
6
6
  "@isaacs/string-locale-compare": "^1.1.0",