flatlock 1.3.0 → 1.5.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/bin/flatcover.js +322 -58
- package/bin/flatlock-cmp.js +2 -2
- package/dist/compare.d.ts +85 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/detect.d.ts +33 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/parsers/index.d.ts +5 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/npm.d.ts +154 -0
- package/dist/parsers/npm.d.ts.map +1 -0
- package/dist/parsers/pnpm/detect.d.ts +136 -0
- package/dist/parsers/pnpm/detect.d.ts.map +1 -0
- package/dist/parsers/pnpm/index.d.ts +154 -0
- package/dist/parsers/pnpm/index.d.ts.map +1 -0
- package/dist/parsers/pnpm/internal.d.ts +5 -0
- package/dist/parsers/pnpm/internal.d.ts.map +1 -0
- package/dist/parsers/pnpm/shrinkwrap.d.ts +129 -0
- package/dist/parsers/pnpm/shrinkwrap.d.ts.map +1 -0
- package/dist/parsers/pnpm/v5.d.ts +139 -0
- package/dist/parsers/pnpm/v5.d.ts.map +1 -0
- package/dist/parsers/pnpm/v6plus.d.ts +212 -0
- package/dist/parsers/pnpm/v6plus.d.ts.map +1 -0
- package/dist/parsers/pnpm.d.ts +2 -0
- package/dist/parsers/pnpm.d.ts.map +1 -0
- package/dist/parsers/types.d.ts +23 -0
- package/dist/parsers/types.d.ts.map +1 -0
- package/dist/parsers/yarn-berry.d.ts +197 -0
- package/dist/parsers/yarn-berry.d.ts.map +1 -0
- package/dist/parsers/yarn-classic.d.ts +110 -0
- package/dist/parsers/yarn-classic.d.ts.map +1 -0
- package/dist/result.d.ts +12 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/set.d.ts +238 -0
- package/dist/set.d.ts.map +1 -0
- package/package.json +9 -4
- package/src/compare.js +5 -7
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/** @typedef {import('./types.js').Dependency} Dependency */
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {Object} WorkspacePackage
|
|
4
|
+
* @property {string} name
|
|
5
|
+
* @property {string} version
|
|
6
|
+
* @property {Record<string, string>} [dependencies]
|
|
7
|
+
* @property {Record<string, string>} [devDependencies]
|
|
8
|
+
* @property {Record<string, string>} [optionalDependencies]
|
|
9
|
+
* @property {Record<string, string>} [peerDependencies]
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Extract package name from yarn berry resolution field.
|
|
13
|
+
*
|
|
14
|
+
* The resolution field is the CANONICAL identifier and should be used instead of the key.
|
|
15
|
+
* Keys can contain npm aliases (e.g., "string-width-cjs@npm:string-width@^4.2.0") while
|
|
16
|
+
* the resolution always contains the actual package name (e.g., "string-width@npm:4.2.3").
|
|
17
|
+
*
|
|
18
|
+
* @param {string} resolution - Resolution field from lockfile entry
|
|
19
|
+
* @returns {string | null} Package name or null if parsing fails
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Unscoped npm package
|
|
23
|
+
* parseResolution('lodash@npm:4.17.21')
|
|
24
|
+
* // => 'lodash'
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Scoped npm package
|
|
28
|
+
* parseResolution('@babel/core@npm:7.24.0')
|
|
29
|
+
* // => '@babel/core'
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* // Aliased package - resolution shows the REAL package name
|
|
33
|
+
* // (key was "string-width-cjs@npm:string-width@^4.2.0")
|
|
34
|
+
* parseResolution('string-width@npm:4.2.3')
|
|
35
|
+
* // => 'string-width'
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Scoped aliased package - resolution shows the REAL package name
|
|
39
|
+
* // (key was "@babel-baseline/core@npm:@babel/core@7.24.4")
|
|
40
|
+
* parseResolution('@babel/core@npm:7.24.4')
|
|
41
|
+
* // => '@babel/core'
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Patch protocol (nested protocols)
|
|
45
|
+
* parseResolution('pkg@patch:pkg@npm:1.0.0#./patch')
|
|
46
|
+
* // => 'pkg'
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Scoped package with patch protocol
|
|
50
|
+
* parseResolution('@scope/pkg@patch:@scope/pkg@npm:1.0.0#./fix.patch')
|
|
51
|
+
* // => '@scope/pkg'
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Workspace protocol
|
|
55
|
+
* parseResolution('my-pkg@workspace:packages/my-pkg')
|
|
56
|
+
* // => 'my-pkg'
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // Scoped workspace package
|
|
60
|
+
* parseResolution('@myorg/utils@workspace:packages/utils')
|
|
61
|
+
* // => '@myorg/utils'
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Git protocol
|
|
65
|
+
* parseResolution('my-lib@git:github.com/user/repo#commit-hash')
|
|
66
|
+
* // => 'my-lib'
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* // Null/empty input
|
|
70
|
+
* parseResolution(null)
|
|
71
|
+
* // => null
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // Empty string
|
|
75
|
+
* parseResolution('')
|
|
76
|
+
* // => null
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* // Portal protocol (symlink to external package)
|
|
80
|
+
* parseResolution('@scope/external@portal:../external-pkg')
|
|
81
|
+
* // => '@scope/external'
|
|
82
|
+
*/
|
|
83
|
+
export function parseResolution(resolution: string): string | null;
|
|
84
|
+
/**
|
|
85
|
+
* Extract package name from yarn berry key (fallback for when resolution is unavailable).
|
|
86
|
+
*
|
|
87
|
+
* WARNING: Keys can contain npm aliases. Prefer parseResolution() when possible.
|
|
88
|
+
* The key may return an alias name instead of the real package name.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} key - Lockfile entry key
|
|
91
|
+
* @returns {string} Package name (may be alias name, not canonical name)
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* // Simple unscoped package
|
|
95
|
+
* parseLockfileKey('lodash@npm:^4.17.21')
|
|
96
|
+
* // => 'lodash'
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* // Scoped package
|
|
100
|
+
* parseLockfileKey('@babel/core@npm:^7.24.0')
|
|
101
|
+
* // => '@babel/core'
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* // Multiple version ranges (comma-separated) - takes first entry
|
|
105
|
+
* parseLockfileKey('@types/node@npm:^18.0.0, @types/node@npm:^20.0.0')
|
|
106
|
+
* // => '@types/node'
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* // npm alias - returns the ALIAS name (not real package)
|
|
110
|
+
* // Use parseResolution() for the real package name
|
|
111
|
+
* parseLockfileKey('string-width-cjs@npm:string-width@^4.2.0')
|
|
112
|
+
* // => 'string-width-cjs'
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* // Scoped npm alias
|
|
116
|
+
* parseLockfileKey('@babel-baseline/core@npm:@babel/core@7.24.4')
|
|
117
|
+
* // => '@babel-baseline/core'
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* // Workspace protocol
|
|
121
|
+
* parseLockfileKey('my-pkg@workspace:packages/my-pkg')
|
|
122
|
+
* // => 'my-pkg'
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // Scoped workspace package
|
|
126
|
+
* parseLockfileKey('@myorg/utils@workspace:.')
|
|
127
|
+
* // => '@myorg/utils'
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* // Portal protocol
|
|
131
|
+
* parseLockfileKey('external-pkg@portal:../some/path')
|
|
132
|
+
* // => 'external-pkg'
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* // Link protocol
|
|
136
|
+
* parseLockfileKey('linked-pkg@link:./local')
|
|
137
|
+
* // => 'linked-pkg'
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* // Patch protocol (complex nested format)
|
|
141
|
+
* parseLockfileKey('pkg@patch:pkg@npm:1.0.0#./patches/fix.patch')
|
|
142
|
+
* // => 'pkg'
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* // Scoped patch
|
|
146
|
+
* parseLockfileKey('@scope/pkg@patch:@scope/pkg@npm:1.0.0#./fix.patch')
|
|
147
|
+
* // => '@scope/pkg'
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* // File protocol
|
|
151
|
+
* parseLockfileKey('local-pkg@file:../local-package')
|
|
152
|
+
* // => 'local-pkg'
|
|
153
|
+
*/
|
|
154
|
+
export function parseLockfileKey(key: string): string;
|
|
155
|
+
/**
|
|
156
|
+
* Parse yarn.lock v2+ (berry)
|
|
157
|
+
* @param {string | object} input - Lockfile content string or pre-parsed object
|
|
158
|
+
* @param {Object} [_options] - Parser options (unused, reserved for future use)
|
|
159
|
+
* @returns {Generator<Dependency>}
|
|
160
|
+
*/
|
|
161
|
+
export function fromYarnBerryLock(input: string | object, _options?: Object): Generator<Dependency>;
|
|
162
|
+
/**
|
|
163
|
+
* Extract workspace paths from yarn berry lockfile.
|
|
164
|
+
*
|
|
165
|
+
* Yarn berry workspace entries use `@workspace:` protocol in keys.
|
|
166
|
+
* Keys can have multiple comma-separated descriptors.
|
|
167
|
+
*
|
|
168
|
+
* @param {string | object} input - Lockfile content string or pre-parsed object
|
|
169
|
+
* @returns {string[]} Array of workspace paths (e.g., ['packages/foo', 'packages/bar'])
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* extractWorkspacePaths(lockfile)
|
|
173
|
+
* // => ['packages/babel-core', 'packages/babel-parser', ...]
|
|
174
|
+
*/
|
|
175
|
+
export function extractWorkspacePaths(input: string | object): string[];
|
|
176
|
+
/**
|
|
177
|
+
* Build workspace packages map by reading package.json files.
|
|
178
|
+
*
|
|
179
|
+
* @param {string | object} input - Lockfile content string or pre-parsed object
|
|
180
|
+
* @param {string} repoDir - Path to repository root
|
|
181
|
+
* @returns {Promise<Record<string, WorkspacePackage>>} Map of workspace path to package info
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* const workspaces = await buildWorkspacePackages(lockfile, '/path/to/repo');
|
|
185
|
+
* // => { 'packages/foo': { name: '@scope/foo', version: '1.0.0', dependencies: {...} } }
|
|
186
|
+
*/
|
|
187
|
+
export function buildWorkspacePackages(input: string | object, repoDir: string): Promise<Record<string, WorkspacePackage>>;
|
|
188
|
+
export type Dependency = import("./types.js").Dependency;
|
|
189
|
+
export type WorkspacePackage = {
|
|
190
|
+
name: string;
|
|
191
|
+
version: string;
|
|
192
|
+
dependencies?: Record<string, string>;
|
|
193
|
+
devDependencies?: Record<string, string>;
|
|
194
|
+
optionalDependencies?: Record<string, string>;
|
|
195
|
+
peerDependencies?: Record<string, string>;
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=yarn-berry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yarn-berry.d.ts","sourceRoot":"","sources":["../../src/parsers/yarn-berry.js"],"names":[],"mappings":"AAIA,4DAA4D;AAE5D;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,4CAjEW,MAAM,GACJ,MAAM,GAAG,IAAI,CA4FzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,sCAhEW,MAAM,GACJ,MAAM,CAiGlB;AAED;;;;;GAKG;AACH,yCAJW,MAAM,GAAG,MAAM,aACf,MAAM,GACJ,SAAS,CAAC,UAAU,CAAC,CAqCjC;AAED;;;;;;;;;;;;GAYG;AACH,6CAPW,MAAM,GAAG,MAAM,GACb,MAAM,EAAE,CA+BpB;AAED;;;;;;;;;;GAUG;AACH,8CARW,MAAM,GAAG,MAAM,WACf,MAAM,GACJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CA6BrD;yBAjVa,OAAO,YAAY,EAAE,UAAU;;UAI/B,MAAM;aACN,MAAM;mBACN,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;sBACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;2BACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;uBACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
3
|
+
* !! WARNING: DO NOT MODIFY THIS FUNCTION !!
|
|
4
|
+
* !! AI AGENTS (Claude, Copilot, etc.): DO NOT TOUCH THIS CODE !!
|
|
5
|
+
* !! !!
|
|
6
|
+
* !! This is YARN LOCKFILE KEY parsing, NOT npm spec parsing. !!
|
|
7
|
+
* !! Yarn lockfile keys have their own format: !!
|
|
8
|
+
* !! - Multiple comma-separated entries: "pkg@^1.0.0, pkg@^2.0.0" !!
|
|
9
|
+
* !! - npm: aliasing protocol: "alias@npm:actual@^1.0.0" !!
|
|
10
|
+
* !! !!
|
|
11
|
+
* !! npm-package-arg (npa) does NOT understand these formats. !!
|
|
12
|
+
* !! Do not "improve" this with npa. !!
|
|
13
|
+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
14
|
+
*
|
|
15
|
+
* Extract package name from yarn classic key.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} key - Lockfile entry key
|
|
18
|
+
* @returns {string} Package name
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Simple unscoped package with semver range
|
|
22
|
+
* parseLockfileKey('lodash@^4.17.21')
|
|
23
|
+
* // => 'lodash'
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // Scoped package
|
|
27
|
+
* parseLockfileKey('@babel/core@^7.0.0')
|
|
28
|
+
* // => '@babel/core'
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Multiple version ranges (comma-separated) - takes first entry
|
|
32
|
+
* parseLockfileKey('lodash@^4.17.21, lodash@^4.0.0')
|
|
33
|
+
* // => 'lodash'
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Multiple ranges for scoped package
|
|
37
|
+
* parseLockfileKey('@types/node@^18.0.0, @types/node@^20.0.0')
|
|
38
|
+
* // => '@types/node'
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // npm: alias protocol - returns the ALIAS name
|
|
42
|
+
* parseLockfileKey('@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3')
|
|
43
|
+
* // => '@babel/traverse--for-generate-function-map'
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // Unscoped alias
|
|
47
|
+
* parseLockfileKey('string-width-cjs@npm:string-width@^4.2.0')
|
|
48
|
+
* // => 'string-width-cjs'
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Exact version
|
|
52
|
+
* parseLockfileKey('typescript@5.3.3')
|
|
53
|
+
* // => 'typescript'
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // Git URL specifier
|
|
57
|
+
* parseLockfileKey('my-lib@github:user/repo#v1.0.0')
|
|
58
|
+
* // => 'my-lib'
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // Tarball URL
|
|
62
|
+
* parseLockfileKey('custom-pkg@https://example.com/pkg.tgz')
|
|
63
|
+
* // => 'custom-pkg'
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Package with prerelease version
|
|
67
|
+
* parseLockfileKey('@next/env@^14.0.0-canary.0')
|
|
68
|
+
* // => '@next/env'
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* // Package without @ (bare name, edge case)
|
|
72
|
+
* parseLockfileKey('lodash')
|
|
73
|
+
* // => 'lodash'
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // Deeply scoped alias pointing to scoped package
|
|
77
|
+
* parseLockfileKey('@myorg/my-alias@npm:@original/package@^1.0.0')
|
|
78
|
+
* // => '@myorg/my-alias'
|
|
79
|
+
*/
|
|
80
|
+
export function parseLockfileKey(key: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* Parse yarn.lock v1 (classic)
|
|
83
|
+
* @param {string | object} input - Lockfile content string or pre-parsed object
|
|
84
|
+
* @param {Object} [_options] - Parser options (unused, reserved for future use)
|
|
85
|
+
* @returns {Generator<Dependency>}
|
|
86
|
+
*/
|
|
87
|
+
export function fromYarnClassicLock(input: string | object, _options?: Object): Generator<Dependency>;
|
|
88
|
+
/** @typedef {import('./types.js').Dependency} Dependency */
|
|
89
|
+
/**
|
|
90
|
+
* @typedef {Object} YarnClassicParseResult
|
|
91
|
+
* @property {'success' | 'merge' | 'conflict'} type - Parse result type
|
|
92
|
+
* @property {Record<string, any>} object - Parsed lockfile object
|
|
93
|
+
*/
|
|
94
|
+
/**
|
|
95
|
+
* The yarn classic parse function (handles CJS/ESM interop)
|
|
96
|
+
* @type {(content: string) => YarnClassicParseResult}
|
|
97
|
+
*/
|
|
98
|
+
export const parseYarnClassic: (content: string) => YarnClassicParseResult;
|
|
99
|
+
export type Dependency = import("./types.js").Dependency;
|
|
100
|
+
export type YarnClassicParseResult = {
|
|
101
|
+
/**
|
|
102
|
+
* - Parse result type
|
|
103
|
+
*/
|
|
104
|
+
type: "success" | "merge" | "conflict";
|
|
105
|
+
/**
|
|
106
|
+
* - Parsed lockfile object
|
|
107
|
+
*/
|
|
108
|
+
object: Record<string, any>;
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=yarn-classic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yarn-classic.d.ts","sourceRoot":"","sources":["../../src/parsers/yarn-classic.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,sCA/DW,MAAM,GACJ,MAAM,CA8FlB;AAED;;;;;GAKG;AACH,2CAJW,MAAM,GAAG,MAAM,aACf,MAAM,GACJ,SAAS,CAAC,UAAU,CAAC,CAgCjC;AAnKD,4DAA4D;AAE5D;;;;GAIG;AAEH;;;GAGG;AACH,+BAFU,CAAC,OAAO,EAAE,MAAM,KAAK,sBAAsB,CAE6B;yBAZpE,OAAO,YAAY,EAAE,UAAU;;;;;UAI/B,SAAS,GAAG,OAAO,GAAG,UAAU;;;;YAChC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
|
package/dist/result.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function Ok<T>(value: T): OkResult<T>;
|
|
2
|
+
export function Err(error: Error | string): ErrResult;
|
|
3
|
+
export type OkResult<T> = {
|
|
4
|
+
ok: true;
|
|
5
|
+
value: T;
|
|
6
|
+
};
|
|
7
|
+
export type ErrResult = {
|
|
8
|
+
ok: false;
|
|
9
|
+
error: Error;
|
|
10
|
+
};
|
|
11
|
+
export type Result<T> = OkResult<T> | ErrResult;
|
|
12
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.js"],"names":[],"mappings":"AAwBO,mBAJM,CAAC,SACH,CAAC,GACC,QAAQ,CAAC,CAAC,CAAC,CAEwB;AAOzC,2BAHI,KAAK,GAAG,MAAM,GACZ,SAAS,CAKpB;qBAjCW,CAAC;QAEA,IAAI;WACJ,CAAC;;;QAKD,KAAK;WACL,KAAK;;mBAIN,CAAC,IACD,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS"}
|
package/dist/set.d.ts
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Set-like container for lockfile dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Identity is determined by name@version. Two dependencies with the same
|
|
5
|
+
* name and version are considered equal, regardless of integrity or resolved URL.
|
|
6
|
+
*
|
|
7
|
+
* All set operations return new FlatlockSet instances (immutable pattern).
|
|
8
|
+
*
|
|
9
|
+
* NOTE: Set operations (union, intersection, difference) return sets that
|
|
10
|
+
* cannot use dependenciesOf() because they lack lockfile traversal data.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const set = await FlatlockSet.fromPath('./package-lock.json');
|
|
14
|
+
* console.log(set.size); // 1234
|
|
15
|
+
* console.log(set.has('lodash@4.17.21')); // true
|
|
16
|
+
*
|
|
17
|
+
* // Get dependencies for a specific workspace
|
|
18
|
+
* const pkg = JSON.parse(await readFile('./packages/foo/package.json'));
|
|
19
|
+
* const subset = await set.dependenciesOf(pkg, { workspacePath: 'packages/foo', repoDir: '.' });
|
|
20
|
+
*
|
|
21
|
+
* // Set operations
|
|
22
|
+
* const other = await FlatlockSet.fromPath('./other-lock.json');
|
|
23
|
+
* const common = set.intersection(other);
|
|
24
|
+
*/
|
|
25
|
+
export class FlatlockSet {
|
|
26
|
+
/**
|
|
27
|
+
* Create FlatlockSet from lockfile path (auto-detect type)
|
|
28
|
+
* @param {string} path - Path to lockfile
|
|
29
|
+
* @param {FromStringOptions} [options] - Parser options
|
|
30
|
+
* @returns {Promise<FlatlockSet>}
|
|
31
|
+
*/
|
|
32
|
+
static fromPath(path: string, options?: FromStringOptions): Promise<FlatlockSet>;
|
|
33
|
+
/**
|
|
34
|
+
* Create FlatlockSet from lockfile string
|
|
35
|
+
* @param {string} content - Lockfile content
|
|
36
|
+
* @param {FromStringOptions} [options] - Parser options
|
|
37
|
+
* @returns {FlatlockSet}
|
|
38
|
+
*/
|
|
39
|
+
static fromString(content: string, options?: FromStringOptions): FlatlockSet;
|
|
40
|
+
/**
|
|
41
|
+
* Parse lockfile once, returning both processed deps and raw data
|
|
42
|
+
* @param {string} content
|
|
43
|
+
* @param {LockfileType} type
|
|
44
|
+
* @param {FromStringOptions} options
|
|
45
|
+
* @returns {{ deps: Map<string, Dependency>, packages: LockfilePackages, importers: LockfileImporters | null, snapshots: Record<string, any> | null }}
|
|
46
|
+
*/
|
|
47
|
+
static "__#private@#parseAll"(content: string, type: LockfileType, options: FromStringOptions): {
|
|
48
|
+
deps: Map<string, Dependency>;
|
|
49
|
+
packages: LockfilePackages;
|
|
50
|
+
importers: LockfileImporters | null;
|
|
51
|
+
snapshots: Record<string, any> | null;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* @param {symbol} internal - Must be INTERNAL symbol
|
|
55
|
+
* @param {Map<string, Dependency>} deps
|
|
56
|
+
* @param {LockfilePackages | null} packages
|
|
57
|
+
* @param {LockfileImporters | null} importers
|
|
58
|
+
* @param {Record<string, any> | null} snapshots
|
|
59
|
+
* @param {LockfileType | null} type
|
|
60
|
+
*/
|
|
61
|
+
constructor(internal: symbol, deps: Map<string, Dependency>, packages: LockfilePackages | null, importers: LockfileImporters | null, snapshots: Record<string, any> | null, type: LockfileType | null);
|
|
62
|
+
/** @returns {number} */
|
|
63
|
+
get size(): number;
|
|
64
|
+
/** @returns {LockfileType | null} */
|
|
65
|
+
get type(): LockfileType | null;
|
|
66
|
+
/** @returns {boolean} */
|
|
67
|
+
get canTraverse(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Get workspace paths from lockfile.
|
|
70
|
+
* Supports npm, pnpm, and yarn berry lockfiles.
|
|
71
|
+
* @returns {string[]} Array of workspace paths (e.g., ['packages/foo', 'packages/bar'])
|
|
72
|
+
*/
|
|
73
|
+
getWorkspacePaths(): string[];
|
|
74
|
+
/**
|
|
75
|
+
* Check if a dependency exists
|
|
76
|
+
* @param {string} nameAtVersion - e.g., "lodash@4.17.21"
|
|
77
|
+
* @returns {boolean}
|
|
78
|
+
*/
|
|
79
|
+
has(nameAtVersion: string): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Get a dependency by name@version
|
|
82
|
+
* @param {string} nameAtVersion
|
|
83
|
+
* @returns {Dependency | undefined}
|
|
84
|
+
*/
|
|
85
|
+
get(nameAtVersion: string): Dependency | undefined;
|
|
86
|
+
/** @returns {IterableIterator<Dependency>} */
|
|
87
|
+
values(): IterableIterator<Dependency>;
|
|
88
|
+
/** @returns {IterableIterator<string>} */
|
|
89
|
+
keys(): IterableIterator<string>;
|
|
90
|
+
/** @returns {IterableIterator<[string, Dependency]>} */
|
|
91
|
+
entries(): IterableIterator<[string, Dependency]>;
|
|
92
|
+
/**
|
|
93
|
+
* Execute a callback for each dependency
|
|
94
|
+
* @param {(dep: Dependency, key: string, set: FlatlockSet) => void} callback
|
|
95
|
+
* @param {any} [thisArg]
|
|
96
|
+
*/
|
|
97
|
+
forEach(callback: (dep: Dependency, key: string, set: FlatlockSet) => void, thisArg?: any): void;
|
|
98
|
+
/**
|
|
99
|
+
* Union of this set with another
|
|
100
|
+
* @param {FlatlockSet} other
|
|
101
|
+
* @returns {FlatlockSet}
|
|
102
|
+
*/
|
|
103
|
+
union(other: FlatlockSet): FlatlockSet;
|
|
104
|
+
/**
|
|
105
|
+
* Intersection of this set with another
|
|
106
|
+
* @param {FlatlockSet} other
|
|
107
|
+
* @returns {FlatlockSet}
|
|
108
|
+
*/
|
|
109
|
+
intersection(other: FlatlockSet): FlatlockSet;
|
|
110
|
+
/**
|
|
111
|
+
* Difference: elements in this set but not in other
|
|
112
|
+
* @param {FlatlockSet} other
|
|
113
|
+
* @returns {FlatlockSet}
|
|
114
|
+
*/
|
|
115
|
+
difference(other: FlatlockSet): FlatlockSet;
|
|
116
|
+
/**
|
|
117
|
+
* Check if this set is a subset of another
|
|
118
|
+
* @param {FlatlockSet} other
|
|
119
|
+
* @returns {boolean}
|
|
120
|
+
*/
|
|
121
|
+
isSubsetOf(other: FlatlockSet): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Check if this set is a superset of another
|
|
124
|
+
* @param {FlatlockSet} other
|
|
125
|
+
* @returns {boolean}
|
|
126
|
+
*/
|
|
127
|
+
isSupersetOf(other: FlatlockSet): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Check if this set has no elements in common with another
|
|
130
|
+
* @param {FlatlockSet} other
|
|
131
|
+
* @returns {boolean}
|
|
132
|
+
*/
|
|
133
|
+
isDisjointFrom(other: FlatlockSet): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Get transitive dependencies of a package.json
|
|
136
|
+
*
|
|
137
|
+
* For monorepos, provide workspacePath and repoDir to get correct resolution.
|
|
138
|
+
* Without workspacePath, assumes root package (hoisted deps only).
|
|
139
|
+
*
|
|
140
|
+
* NOTE: This method is only available on sets created directly from
|
|
141
|
+
* fromPath/fromString. Sets created via union/intersection/difference
|
|
142
|
+
* cannot use this method (canTraverse will be false).
|
|
143
|
+
*
|
|
144
|
+
* @param {PackageJson} packageJson - Parsed package.json
|
|
145
|
+
* @param {DependenciesOfOptions} [options]
|
|
146
|
+
* @returns {Promise<FlatlockSet>}
|
|
147
|
+
* @throws {Error} If called on a set that cannot traverse
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* // Simple usage with repoDir (recommended)
|
|
151
|
+
* const deps = await lockfile.dependenciesOf(pkg, {
|
|
152
|
+
* workspacePath: 'packages/foo',
|
|
153
|
+
* repoDir: '/path/to/repo'
|
|
154
|
+
* });
|
|
155
|
+
*/
|
|
156
|
+
dependenciesOf(packageJson: PackageJson, options?: DependenciesOfOptions): Promise<FlatlockSet>;
|
|
157
|
+
/**
|
|
158
|
+
* Convert to array
|
|
159
|
+
* @returns {Dependency[]}
|
|
160
|
+
*/
|
|
161
|
+
toArray(): Dependency[];
|
|
162
|
+
/** @returns {IterableIterator<Dependency>} */
|
|
163
|
+
[Symbol.iterator](): IterableIterator<Dependency>;
|
|
164
|
+
#private;
|
|
165
|
+
}
|
|
166
|
+
export type Dependency = import("./parsers/npm.js").Dependency;
|
|
167
|
+
export type LockfileType = import("./detect.js").LockfileType;
|
|
168
|
+
export type WorkspacePackage = {
|
|
169
|
+
/**
|
|
170
|
+
* - Package name (e.g., '@vue/shared')
|
|
171
|
+
*/
|
|
172
|
+
name: string;
|
|
173
|
+
/**
|
|
174
|
+
* - Package version (e.g., '3.5.26')
|
|
175
|
+
*/
|
|
176
|
+
version: string;
|
|
177
|
+
/**
|
|
178
|
+
* - Production dependencies (for yarn berry workspace traversal)
|
|
179
|
+
*/
|
|
180
|
+
dependencies?: Record<string, string>;
|
|
181
|
+
/**
|
|
182
|
+
* - Dev dependencies
|
|
183
|
+
*/
|
|
184
|
+
devDependencies?: Record<string, string>;
|
|
185
|
+
/**
|
|
186
|
+
* - Optional dependencies
|
|
187
|
+
*/
|
|
188
|
+
optionalDependencies?: Record<string, string>;
|
|
189
|
+
/**
|
|
190
|
+
* - Peer dependencies
|
|
191
|
+
*/
|
|
192
|
+
peerDependencies?: Record<string, string>;
|
|
193
|
+
};
|
|
194
|
+
export type DependenciesOfOptions = {
|
|
195
|
+
/**
|
|
196
|
+
* - Path to workspace (e.g., 'packages/foo')
|
|
197
|
+
*/
|
|
198
|
+
workspacePath?: string;
|
|
199
|
+
/**
|
|
200
|
+
* - Path to repository root for reading workspace package.json files
|
|
201
|
+
*/
|
|
202
|
+
repoDir?: string;
|
|
203
|
+
/**
|
|
204
|
+
* - Include devDependencies
|
|
205
|
+
*/
|
|
206
|
+
dev?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* - Include optionalDependencies
|
|
209
|
+
*/
|
|
210
|
+
optional?: boolean;
|
|
211
|
+
/**
|
|
212
|
+
* - Include peerDependencies (default false: peers are provided by consumer)
|
|
213
|
+
*/
|
|
214
|
+
peer?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* - Map of workspace path to package info for resolving workspace links (auto-built if repoDir provided)
|
|
217
|
+
*/
|
|
218
|
+
workspacePackages?: Record<string, WorkspacePackage>;
|
|
219
|
+
};
|
|
220
|
+
export type FromStringOptions = {
|
|
221
|
+
/**
|
|
222
|
+
* - Path hint for type detection
|
|
223
|
+
*/
|
|
224
|
+
path?: string;
|
|
225
|
+
/**
|
|
226
|
+
* - Explicit lockfile type
|
|
227
|
+
*/
|
|
228
|
+
type?: LockfileType;
|
|
229
|
+
};
|
|
230
|
+
export type PackageJson = {
|
|
231
|
+
dependencies?: Record<string, string>;
|
|
232
|
+
devDependencies?: Record<string, string>;
|
|
233
|
+
optionalDependencies?: Record<string, string>;
|
|
234
|
+
peerDependencies?: Record<string, string>;
|
|
235
|
+
};
|
|
236
|
+
export type LockfilePackages = Record<string, any>;
|
|
237
|
+
export type LockfileImporters = Record<string, any>;
|
|
238
|
+
//# sourceMappingURL=set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../src/set.js"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flatlock",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "The Matlock of lockfile parsers - extracts packages without building dependency graphs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lockfile",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
},
|
|
36
36
|
"main": "src/index.js",
|
|
37
37
|
"bin": {
|
|
38
|
-
"flatlock": "
|
|
39
|
-
"flatlock-cmp": "
|
|
40
|
-
"flatcover": "
|
|
38
|
+
"flatlock": "bin/flatlock.js",
|
|
39
|
+
"flatlock-cmp": "bin/flatlock-cmp.js",
|
|
40
|
+
"flatcover": "bin/flatcover.js"
|
|
41
41
|
},
|
|
42
42
|
"files": [
|
|
43
43
|
"src",
|
|
@@ -87,6 +87,11 @@
|
|
|
87
87
|
"@yarnpkg/core": "^4.5.0"
|
|
88
88
|
},
|
|
89
89
|
"packageManager": "pnpm@10.25.0",
|
|
90
|
+
"pnpm": {
|
|
91
|
+
"overrides": {
|
|
92
|
+
"tar": ">=7.5.3"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
90
95
|
"engines": {
|
|
91
96
|
"node": ">=22"
|
|
92
97
|
},
|
package/src/compare.js
CHANGED
|
@@ -6,7 +6,7 @@ import { tmpdir } from 'node:os';
|
|
|
6
6
|
import { dirname, join } from 'node:path';
|
|
7
7
|
import { parseSyml } from '@yarnpkg/parsers';
|
|
8
8
|
import yaml from 'js-yaml';
|
|
9
|
-
import {
|
|
9
|
+
import { collect, detectType, Type } from './index.js';
|
|
10
10
|
import { parseYarnBerryKey, parseYarnClassic, parseYarnClassicKey } from './parsers/index.js';
|
|
11
11
|
import { parseSpec as parsePnpmSpec } from './parsers/pnpm.js';
|
|
12
12
|
|
|
@@ -545,12 +545,10 @@ export async function compare(filepath, options = {}) {
|
|
|
545
545
|
const content = await readFile(filepath, 'utf8');
|
|
546
546
|
const type = detectType({ path: filepath, content });
|
|
547
547
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
553
|
-
}
|
|
548
|
+
console.time(`⏱ collect [...]${filepath.slice(-40)}`);
|
|
549
|
+
const deps = await collect(filepath);
|
|
550
|
+
console.timeEnd(`⏱ collect [...]${filepath.slice(-40)}`);
|
|
551
|
+
const flatlockSet = new Set(deps.map(({ name, version }) => `${name}@${version}`));
|
|
554
552
|
|
|
555
553
|
let comparisonResult;
|
|
556
554
|
switch (type) {
|