flatlock 1.1.0 → 1.2.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 (49) hide show
  1. package/README.md +54 -1
  2. package/bin/flatlock-cmp.js +71 -45
  3. package/dist/compare.d.ts +25 -3
  4. package/dist/compare.d.ts.map +1 -1
  5. package/dist/detect.d.ts.map +1 -1
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/parsers/index.d.ts +2 -2
  9. package/dist/parsers/npm.d.ts +64 -37
  10. package/dist/parsers/npm.d.ts.map +1 -1
  11. package/dist/parsers/pnpm/detect.d.ts +136 -0
  12. package/dist/parsers/pnpm/detect.d.ts.map +1 -0
  13. package/dist/parsers/pnpm/index.d.ts +120 -0
  14. package/dist/parsers/pnpm/index.d.ts.map +1 -0
  15. package/dist/parsers/pnpm/internal.d.ts +5 -0
  16. package/dist/parsers/pnpm/internal.d.ts.map +1 -0
  17. package/dist/parsers/pnpm/shrinkwrap.d.ts +129 -0
  18. package/dist/parsers/pnpm/shrinkwrap.d.ts.map +1 -0
  19. package/dist/parsers/pnpm/v5.d.ts +139 -0
  20. package/dist/parsers/pnpm/v5.d.ts.map +1 -0
  21. package/dist/parsers/pnpm/v6plus.d.ts +212 -0
  22. package/dist/parsers/pnpm/v6plus.d.ts.map +1 -0
  23. package/dist/parsers/pnpm.d.ts +1 -59
  24. package/dist/parsers/pnpm.d.ts.map +1 -1
  25. package/dist/parsers/types.d.ts +23 -0
  26. package/dist/parsers/types.d.ts.map +1 -0
  27. package/dist/parsers/yarn-berry.d.ts +141 -52
  28. package/dist/parsers/yarn-berry.d.ts.map +1 -1
  29. package/dist/parsers/yarn-classic.d.ts +79 -33
  30. package/dist/parsers/yarn-classic.d.ts.map +1 -1
  31. package/dist/set.d.ts +189 -0
  32. package/dist/set.d.ts.map +1 -0
  33. package/package.json +7 -5
  34. package/src/compare.js +385 -28
  35. package/src/detect.js +3 -4
  36. package/src/index.js +9 -2
  37. package/src/parsers/index.js +10 -2
  38. package/src/parsers/npm.js +64 -16
  39. package/src/parsers/pnpm/detect.js +198 -0
  40. package/src/parsers/pnpm/index.js +289 -0
  41. package/src/parsers/pnpm/internal.js +41 -0
  42. package/src/parsers/pnpm/shrinkwrap.js +241 -0
  43. package/src/parsers/pnpm/v5.js +225 -0
  44. package/src/parsers/pnpm/v6plus.js +290 -0
  45. package/src/parsers/pnpm.js +11 -89
  46. package/src/parsers/types.js +10 -0
  47. package/src/parsers/yarn-berry.js +183 -36
  48. package/src/parsers/yarn-classic.js +81 -21
  49. package/src/set.js +618 -0
@@ -1,16 +1,19 @@
1
1
  import yarnLockfile from '@yarnpkg/lockfile';
2
2
 
3
- const { parse } = yarnLockfile;
3
+ /** @typedef {import('./types.js').Dependency} Dependency */
4
4
 
5
5
  /**
6
- * @typedef {Object} Dependency
7
- * @property {string} name - Package name
8
- * @property {string} version - Resolved version
9
- * @property {string} [integrity] - Integrity hash
10
- * @property {string} [resolved] - Resolution URL
11
- * @property {boolean} [link] - True if this is a symlink
6
+ * @typedef {Object} YarnClassicParseResult
7
+ * @property {'success' | 'merge' | 'conflict'} type - Parse result type
8
+ * @property {Record<string, any>} object - Parsed lockfile object
12
9
  */
13
10
 
11
+ /**
12
+ * The yarn classic parse function (handles CJS/ESM interop)
13
+ * @type {(content: string) => YarnClassicParseResult}
14
+ */
15
+ export const parseYarnClassic = yarnLockfile.default?.parse || yarnLockfile.parse;
16
+
14
17
  /**
15
18
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16
19
  * !! WARNING: DO NOT MODIFY THIS FUNCTION !!
@@ -27,14 +30,68 @@ const { parse } = yarnLockfile;
27
30
  *
28
31
  * Extract package name from yarn classic key.
29
32
  *
30
- * Examples:
31
- * "lodash@^4.17.21" → "lodash"
32
- * "@babel/core@^7.0.0" → "@babel/core"
33
- * "lodash@^4.17.21, lodash@^4.0.0" → "lodash" (multiple version ranges)
34
- * "@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3" → "@babel/traverse--for-generate-function-map"
35
- *
36
33
  * @param {string} key - Lockfile entry key
37
34
  * @returns {string} Package name
35
+ *
36
+ * @example
37
+ * // Simple unscoped package with semver range
38
+ * parseLockfileKey('lodash@^4.17.21')
39
+ * // => 'lodash'
40
+ *
41
+ * @example
42
+ * // Scoped package
43
+ * parseLockfileKey('@babel/core@^7.0.0')
44
+ * // => '@babel/core'
45
+ *
46
+ * @example
47
+ * // Multiple version ranges (comma-separated) - takes first entry
48
+ * parseLockfileKey('lodash@^4.17.21, lodash@^4.0.0')
49
+ * // => 'lodash'
50
+ *
51
+ * @example
52
+ * // Multiple ranges for scoped package
53
+ * parseLockfileKey('@types/node@^18.0.0, @types/node@^20.0.0')
54
+ * // => '@types/node'
55
+ *
56
+ * @example
57
+ * // npm: alias protocol - returns the ALIAS name
58
+ * parseLockfileKey('@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3')
59
+ * // => '@babel/traverse--for-generate-function-map'
60
+ *
61
+ * @example
62
+ * // Unscoped alias
63
+ * parseLockfileKey('string-width-cjs@npm:string-width@^4.2.0')
64
+ * // => 'string-width-cjs'
65
+ *
66
+ * @example
67
+ * // Exact version
68
+ * parseLockfileKey('typescript@5.3.3')
69
+ * // => 'typescript'
70
+ *
71
+ * @example
72
+ * // Git URL specifier
73
+ * parseLockfileKey('my-lib@github:user/repo#v1.0.0')
74
+ * // => 'my-lib'
75
+ *
76
+ * @example
77
+ * // Tarball URL
78
+ * parseLockfileKey('custom-pkg@https://example.com/pkg.tgz')
79
+ * // => 'custom-pkg'
80
+ *
81
+ * @example
82
+ * // Package with prerelease version
83
+ * parseLockfileKey('@next/env@^14.0.0-canary.0')
84
+ * // => '@next/env'
85
+ *
86
+ * @example
87
+ * // Package without @ (bare name, edge case)
88
+ * parseLockfileKey('lodash')
89
+ * // => 'lodash'
90
+ *
91
+ * @example
92
+ * // Deeply scoped alias pointing to scoped package
93
+ * parseLockfileKey('@myorg/my-alias@npm:@original/package@^1.0.0')
94
+ * // => '@myorg/my-alias'
38
95
  */
39
96
  export function parseLockfileKey(key) {
40
97
  // Keys can have multiple version ranges: "pkg@^1.0.0, pkg@^2.0.0"
@@ -72,19 +129,22 @@ export function parseLockfileKey(key) {
72
129
 
73
130
  /**
74
131
  * Parse yarn.lock v1 (classic)
75
- * @param {string} content - Lockfile content
132
+ * @param {string | object} input - Lockfile content string or pre-parsed object
76
133
  * @param {Object} [_options] - Parser options (unused, reserved for future use)
77
134
  * @returns {Generator<Dependency>}
78
135
  */
79
- export function* fromYarnClassicLock(content, _options = {}) {
80
- const parsed = parse(content);
81
-
82
- if (parsed.type !== 'success') {
83
- throw new Error(`Failed to parse yarn.lock: ${parsed.type}`);
136
+ export function* fromYarnClassicLock(input, _options = {}) {
137
+ let lockfile;
138
+ if (typeof input === 'string') {
139
+ const result = parseYarnClassic(input);
140
+ if (result.type !== 'success' && result.type !== 'merge') {
141
+ throw new Error('Failed to parse yarn.lock');
142
+ }
143
+ lockfile = result.object;
144
+ } else {
145
+ lockfile = input;
84
146
  }
85
147
 
86
- const lockfile = parsed.object;
87
-
88
148
  for (const [key, pkg] of Object.entries(lockfile)) {
89
149
  const name = parseLockfileKey(key);
90
150
  const { version, integrity, resolved } = pkg;