@effected/lockfiles 0.1.10 → 0.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.
- package/ImporterDependency.js +15 -5
- package/index.d.ts +15 -5
- package/internal/pnpm.js +2 -3
- package/internal/shared.js +34 -2
- package/package.json +3 -3
package/ImporterDependency.js
CHANGED
|
@@ -12,11 +12,20 @@ import { DependencyField, DependencySpecifier } from "@effected/npm";
|
|
|
12
12
|
* `ClassifiedSpecifier` (`catalog:` / `workspace:` / range / dist-tag / raw),
|
|
13
13
|
* while encoding round-trips the **exact original string byte-for-byte** — the
|
|
14
14
|
* guarantee a before/after lockfile diff relies on.
|
|
15
|
-
* - `version` — the concrete resolved version, **populated by pnpm only
|
|
16
|
-
* records `{ specifier, version }`
|
|
17
|
-
*
|
|
18
|
-
* `version` is
|
|
19
|
-
* `
|
|
15
|
+
* - `version` — the concrete resolved version, **populated by pnpm only**:
|
|
16
|
+
* comparable across refs and printable. pnpm records `{ specifier, version }`
|
|
17
|
+
* per importer dependency, and the parser splits pnpm's peer-disambiguation
|
|
18
|
+
* suffix off into `peerSuffix`, so `version` is always the plain version — or
|
|
19
|
+
* a non-registry resolution (`link:../utils`, `file:...`), passed through
|
|
20
|
+
* verbatim. bun and npm record resolved versions on their package entries
|
|
21
|
+
* instead, so for those formats `version` is absent and a consumer joins by
|
|
22
|
+
* `name` against `Lockfile.packages`.
|
|
23
|
+
* - `peerSuffix` — pnpm's peer-disambiguation context: the raw parenthesized
|
|
24
|
+
* chain the lockfile recorded after the version, e.g.
|
|
25
|
+
* `(effect@4.0.0-beta.101)(ioredis@5.11.1(supports-color@8.1.1))`. Present
|
|
26
|
+
* only when the lockfile recorded one — never for suffix-free pnpm entries,
|
|
27
|
+
* and never for the other formats, which do not record peer context per
|
|
28
|
+
* importer dependency.
|
|
20
29
|
* - `depType` — which dependency map declared it, spelled with `@effected/npm`'s
|
|
21
30
|
* kit-wide `DependencyField` vocabulary.
|
|
22
31
|
*
|
|
@@ -26,6 +35,7 @@ var ImporterDependency = class extends Schema.Class("ImporterDependency")({
|
|
|
26
35
|
name: Schema.NonEmptyString,
|
|
27
36
|
specifier: DependencySpecifier.FromString,
|
|
28
37
|
version: Schema.optionalKey(Schema.String),
|
|
38
|
+
peerSuffix: Schema.optionalKey(Schema.String),
|
|
29
39
|
depType: DependencyField
|
|
30
40
|
}) {};
|
|
31
41
|
|
package/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ declare const ImporterDependency_base: Schema.Class<ImporterDependency, Schema.S
|
|
|
26
26
|
readonly name: Schema.NonEmptyString;
|
|
27
27
|
readonly specifier: Schema.Codec<import("@effected/npm").ClassifiedSpecifier, string, never, never>;
|
|
28
28
|
readonly version: Schema.optionalKey<Schema.String>;
|
|
29
|
+
readonly peerSuffix: Schema.optionalKey<Schema.String>;
|
|
29
30
|
readonly depType: Schema.Literals<readonly ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]>;
|
|
30
31
|
}>, {}>;
|
|
31
32
|
/**
|
|
@@ -38,11 +39,20 @@ declare const ImporterDependency_base: Schema.Class<ImporterDependency, Schema.S
|
|
|
38
39
|
* `ClassifiedSpecifier` (`catalog:` / `workspace:` / range / dist-tag / raw),
|
|
39
40
|
* while encoding round-trips the **exact original string byte-for-byte** — the
|
|
40
41
|
* guarantee a before/after lockfile diff relies on.
|
|
41
|
-
* - `version` — the concrete resolved version, **populated by pnpm only
|
|
42
|
-
* records `{ specifier, version }`
|
|
43
|
-
*
|
|
44
|
-
* `version` is
|
|
45
|
-
* `
|
|
42
|
+
* - `version` — the concrete resolved version, **populated by pnpm only**:
|
|
43
|
+
* comparable across refs and printable. pnpm records `{ specifier, version }`
|
|
44
|
+
* per importer dependency, and the parser splits pnpm's peer-disambiguation
|
|
45
|
+
* suffix off into `peerSuffix`, so `version` is always the plain version — or
|
|
46
|
+
* a non-registry resolution (`link:../utils`, `file:...`), passed through
|
|
47
|
+
* verbatim. bun and npm record resolved versions on their package entries
|
|
48
|
+
* instead, so for those formats `version` is absent and a consumer joins by
|
|
49
|
+
* `name` against `Lockfile.packages`.
|
|
50
|
+
* - `peerSuffix` — pnpm's peer-disambiguation context: the raw parenthesized
|
|
51
|
+
* chain the lockfile recorded after the version, e.g.
|
|
52
|
+
* `(effect@4.0.0-beta.101)(ioredis@5.11.1(supports-color@8.1.1))`. Present
|
|
53
|
+
* only when the lockfile recorded one — never for suffix-free pnpm entries,
|
|
54
|
+
* and never for the other formats, which do not record peer context per
|
|
55
|
+
* importer dependency.
|
|
46
56
|
* - `depType` — which dependency map declared it, spelled with `@effected/npm`'s
|
|
47
57
|
* kit-wide `DependencyField` vocabulary.
|
|
48
58
|
*
|
package/internal/pnpm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LockfileImporter } from "../LockfileImporter.js";
|
|
2
2
|
import { ResolvedPackage } from "../ResolvedPackage.js";
|
|
3
|
-
import { extractWorkspaceDeps, framingFailure, importerDependencies, toIntegrityHash, validationFailure } from "./shared.js";
|
|
3
|
+
import { extractWorkspaceDeps, framingFailure, importerDependencies, splitPeerSuffix, toIntegrityHash, validationFailure } from "./shared.js";
|
|
4
4
|
import { PnpmExtension } from "../PnpmExtension.js";
|
|
5
5
|
import { selectPnpmDocument } from "./documents.js";
|
|
6
6
|
import { Effect, Schema } from "effect";
|
|
@@ -102,8 +102,7 @@ const toFields = (raw) => Effect.gen(function* () {
|
|
|
102
102
|
}));
|
|
103
103
|
}
|
|
104
104
|
if (raw.packages) for (const [key, pkg] of Object.entries(raw.packages)) {
|
|
105
|
-
const
|
|
106
|
-
const bare = parenIndex === -1 ? key : key.slice(0, parenIndex);
|
|
105
|
+
const { plain: bare } = splitPeerSuffix(key);
|
|
107
106
|
const atIndex = bare.lastIndexOf("@");
|
|
108
107
|
if (atIndex <= 0) continue;
|
|
109
108
|
const name = bare.slice(0, atIndex);
|
package/internal/shared.js
CHANGED
|
@@ -42,22 +42,54 @@ const toIntegrityHash = (raw) => {
|
|
|
42
42
|
};
|
|
43
43
|
const decodeSpecifier = Schema.decodeUnknownExit(DependencySpecifier.FromString);
|
|
44
44
|
/**
|
|
45
|
+
* Split pnpm's peer-disambiguation suffix off a recorded string: everything
|
|
46
|
+
* from the first `(` on is suffix, since package names and versions never
|
|
47
|
+
* contain `(`. Handles both shapes pnpm records — a bare version
|
|
48
|
+
* (`"1.0.0(effect@4.0.0)"`, importer entries) and a `name@version` snapshot key
|
|
49
|
+
* (`"fdir@6.5.0(picomatch@4.0.4)"`). A string with no `(` — including
|
|
50
|
+
* `link:...` / `file:...` resolutions — passes through untouched. So does a
|
|
51
|
+
* protocol-bearing string (a `:` ahead of the first `(`), where a parenthesis
|
|
52
|
+
* is path or URL text rather than a peer suffix: pnpm attaches suffixes to
|
|
53
|
+
* registry versions only. This is the single stripping implementation — do not
|
|
54
|
+
* hand-roll an `indexOf("(")` split elsewhere.
|
|
55
|
+
*
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
const splitPeerSuffix = (raw) => {
|
|
59
|
+
const parenIndex = raw.indexOf("(");
|
|
60
|
+
if (parenIndex === -1) return { plain: raw };
|
|
61
|
+
if (raw.lastIndexOf(":", parenIndex) !== -1) return { plain: raw };
|
|
62
|
+
return {
|
|
63
|
+
plain: raw.slice(0, parenIndex),
|
|
64
|
+
peerSuffix: raw.slice(parenIndex)
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
45
68
|
* Build one {@link ImporterDependency}, decoding the raw specifier string into
|
|
46
69
|
* the `@effected/npm` `ClassifiedSpecifier` tagged union. Returns `undefined`
|
|
47
70
|
* — a skip, never a throw — when the name is empty or the specifier does not
|
|
48
71
|
* classify (e.g. an empty specifier), per the total-string-surgery discipline.
|
|
49
72
|
*
|
|
73
|
+
* A pnpm-recorded version is normalized through {@link splitPeerSuffix}: the
|
|
74
|
+
* `version` field carries the plain version and the split-off peer chain lands
|
|
75
|
+
* in `peerSuffix`. A version that is *only* a peer chain (empty plain part) is
|
|
76
|
+
* treated as no concrete version — a skip of both fields, never a throw.
|
|
77
|
+
*
|
|
50
78
|
* @internal
|
|
51
79
|
*/
|
|
52
80
|
const buildImporterDependency = (name, specifier, depType, version) => {
|
|
53
81
|
if (name === "") return void 0;
|
|
54
82
|
const exit = decodeSpecifier(specifier);
|
|
55
83
|
if (Exit.isFailure(exit)) return void 0;
|
|
84
|
+
const resolved = version !== void 0 && version !== "" ? splitPeerSuffix(version) : void 0;
|
|
56
85
|
return ImporterDependency.make({
|
|
57
86
|
name,
|
|
58
87
|
specifier: exit.value,
|
|
59
88
|
depType,
|
|
60
|
-
...
|
|
89
|
+
...resolved !== void 0 && resolved.plain !== "" ? {
|
|
90
|
+
version: resolved.plain,
|
|
91
|
+
...resolved.peerSuffix !== void 0 ? { peerSuffix: resolved.peerSuffix } : {}
|
|
92
|
+
} : {}
|
|
61
93
|
});
|
|
62
94
|
};
|
|
63
95
|
/**
|
|
@@ -130,4 +162,4 @@ const extractWorkspaceDeps = (workspaces, workspaceNames) => {
|
|
|
130
162
|
};
|
|
131
163
|
|
|
132
164
|
//#endregion
|
|
133
|
-
export { DEP_TYPES, extractWorkspaceDeps, framingFailure, importerDependencies, isWorkspaceSpecifier, syntaxFailure, toIntegrityHash, validationFailure };
|
|
165
|
+
export { DEP_TYPES, extractWorkspaceDeps, framingFailure, importerDependencies, isWorkspaceSpecifier, splitPeerSuffix, syntaxFailure, toIntegrityHash, validationFailure };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/lockfiles",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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": [
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@effected/jsonc": "~0.5.1",
|
|
44
|
-
"@effected/npm": "~0.
|
|
44
|
+
"@effected/npm": "~0.4.0",
|
|
45
45
|
"@effected/semver": "~0.2.1",
|
|
46
|
-
"@effected/yaml": "~0.
|
|
46
|
+
"@effected/yaml": "~0.6.0",
|
|
47
47
|
"effect": "4.0.0-beta.101"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|