@effected/lockfiles 0.6.0 → 0.6.1
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/internal/pnpm.js +43 -3
- package/package.json +1 -1
package/internal/pnpm.js
CHANGED
|
@@ -135,6 +135,31 @@ const resolveLinkTarget = (importerPath, target) => {
|
|
|
135
135
|
}
|
|
136
136
|
return segments.length === 0 ? void 0 : segments.join("/");
|
|
137
137
|
};
|
|
138
|
+
/** The specifier protocol pnpm resolves through the workspace itself. @internal */
|
|
139
|
+
const WORKSPACE_PREFIX = "workspace:";
|
|
140
|
+
/**
|
|
141
|
+
* The importer a `link:` target lands INSIDE, longest path first.
|
|
142
|
+
*
|
|
143
|
+
* pnpm's `publishConfig.linkDirectory` makes a workspace link point at the
|
|
144
|
+
* package's publish directory rather than its root — `link:../bundler/dist/dev/pkg`
|
|
145
|
+
* where `packages/bundler` is the importer — so the target itself is a build
|
|
146
|
+
* output that is no importer and never will be. The owning importer is the
|
|
147
|
+
* longest ancestor of the target that IS one; longest-first so a nested importer
|
|
148
|
+
* beats its parent.
|
|
149
|
+
*
|
|
150
|
+
* The root importer (`"."`) is deliberately unreachable here: it is an ancestor
|
|
151
|
+
* of every path in the workspace, so admitting it would resolve every stray link
|
|
152
|
+
* to the root rather than leaving it unnamed.
|
|
153
|
+
*
|
|
154
|
+
* @internal
|
|
155
|
+
*/
|
|
156
|
+
const owningImporter = (target, importerPaths) => {
|
|
157
|
+
const segments = target.split("/");
|
|
158
|
+
for (let end = segments.length - 1; end > 0; end--) {
|
|
159
|
+
const candidate = segments.slice(0, end).join("/");
|
|
160
|
+
if (importerPaths.has(candidate)) return candidate;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
138
163
|
/**
|
|
139
164
|
* Resolve one importer's outgoing edges. pnpm records `{ specifier, version }`
|
|
140
165
|
* per importer dependency, where the version is either a registry version (the
|
|
@@ -142,9 +167,22 @@ const resolveLinkTarget = (importerPath, target) => {
|
|
|
142
167
|
* naming another importer — normalized against this importer's own path. Both
|
|
143
168
|
* are checked against the lockfile's instance ids before being emitted.
|
|
144
169
|
*
|
|
170
|
+
* A `link:` target that is no importer gets one further chance, and only under
|
|
171
|
+
* a `workspace:` SPECIFIER: pnpm resolved that edge through the workspace, so
|
|
172
|
+
* the target directory is known to belong to a workspace package, and
|
|
173
|
+
* {@link owningImporter} names it. The specifier is what makes this a
|
|
174
|
+
* resolution rather than a guess — a hand-written `link:../vendor/stub`
|
|
175
|
+
* specifier names a directory pnpm never claimed was a workspace package, and
|
|
176
|
+
* attributing it to whichever importer happens to contain it would answer with
|
|
177
|
+
* the wrong package's peers instead of admitting it could not name the edge.
|
|
178
|
+
*
|
|
179
|
+
* The snapshot path ({@link resolveEdges}) deliberately does NOT do this: a
|
|
180
|
+
* snapshot body records `name: link:<path>` with no specifier beside it, so the
|
|
181
|
+
* evidence this rule turns on is not available there.
|
|
182
|
+
*
|
|
145
183
|
* @internal
|
|
146
184
|
*/
|
|
147
|
-
const resolveImporterEdges = (importer, importerPath, instanceIds) => {
|
|
185
|
+
const resolveImporterEdges = (importer, importerPath, instanceIds, importerPaths) => {
|
|
148
186
|
const edges = /* @__PURE__ */ new Map();
|
|
149
187
|
const unnameable = /* @__PURE__ */ new Set();
|
|
150
188
|
for (const group of importerDepGroups(importer)) {
|
|
@@ -153,7 +191,8 @@ const resolveImporterEdges = (importer, importerPath, instanceIds) => {
|
|
|
153
191
|
if (name === "") continue;
|
|
154
192
|
if (info.version.startsWith(LINK_PREFIX)) {
|
|
155
193
|
const target = resolveLinkTarget(importerPath, info.version.slice(5));
|
|
156
|
-
|
|
194
|
+
const owner = target === void 0 ? void 0 : instanceIds.has(target) ? target : info.specifier.startsWith(WORKSPACE_PREFIX) ? owningImporter(target, importerPaths) : void 0;
|
|
195
|
+
if (owner !== void 0) edges.set(name, owner);
|
|
157
196
|
else unnameable.add(name);
|
|
158
197
|
continue;
|
|
159
198
|
}
|
|
@@ -213,6 +252,7 @@ const toFields = (raw) => Effect.gen(function* () {
|
|
|
213
252
|
...raw.packages ? Object.keys(raw.packages) : [],
|
|
214
253
|
...Object.keys(raw.importers)
|
|
215
254
|
]);
|
|
255
|
+
const importerPaths = new Set(Object.keys(raw.importers).filter((path) => path !== "." && path !== ""));
|
|
216
256
|
const emitted = /* @__PURE__ */ new Set();
|
|
217
257
|
for (const [importerPath, importer] of Object.entries(raw.importers)) {
|
|
218
258
|
if (importerPath === "." || importerPath === "") continue;
|
|
@@ -222,7 +262,7 @@ const toFields = (raw) => Effect.gen(function* () {
|
|
|
222
262
|
instanceId: importerPath,
|
|
223
263
|
isWorkspace: true,
|
|
224
264
|
relativePath: importerPath,
|
|
225
|
-
...resolveImporterEdges(importer, importerPath, instanceIds)
|
|
265
|
+
...resolveImporterEdges(importer, importerPath, instanceIds, importerPaths)
|
|
226
266
|
}));
|
|
227
267
|
}
|
|
228
268
|
const emit = (instanceId, meta, edges) => Effect.gen(function* () {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/lockfiles",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Pure lockfile parsing for bun, npm, pnpm and yarn Berry into one unified Effect schema model, with pure integrity checking against workspace manifests.",
|
|
6
6
|
"keywords": [
|