@mawesome/npm-vm 0.0.0-alpha.0 → 0.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 (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -1
  3. package/dist/cli.js +4157 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/index-B071ZJDk.d.cts +164 -0
  6. package/dist/index-B071ZJDk.d.ts +164 -0
  7. package/dist/index.cjs +7 -0
  8. package/dist/index.d.cts +2 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +2 -0
  11. package/dist/internal.cjs +2709 -0
  12. package/dist/internal.cjs.map +1 -0
  13. package/dist/internal.d.cts +139 -0
  14. package/dist/internal.d.ts +139 -0
  15. package/dist/internal.js +2706 -0
  16. package/dist/internal.js.map +1 -0
  17. package/dist/provenance--sOYCeF2.js +322 -0
  18. package/dist/provenance--sOYCeF2.js.map +1 -0
  19. package/dist/provenance-DDegWCyS.js +2 -0
  20. package/dist/runtime/atomic-C3shKdH9.cjs +88 -0
  21. package/dist/runtime/bootstrap.cjs +271 -0
  22. package/dist/runtime/commonjs-AANzyd21.cjs +7393 -0
  23. package/dist/runtime/dispatch-B9OSfqsn.cjs +25156 -0
  24. package/dist/runtime/dist-CXwBT6rE.cjs +30766 -0
  25. package/dist/runtime/home-BaoZZSBy.cjs +91 -0
  26. package/dist/runtime/install-C_M5WK98.cjs +13598 -0
  27. package/dist/runtime/journal-_bs-eJRJ.cjs +282 -0
  28. package/dist/runtime/launchers/cmd.tmpl +2 -0
  29. package/dist/runtime/launchers/ps1.tmpl +5 -0
  30. package/dist/runtime/launchers/sh.tmpl +3 -0
  31. package/dist/runtime/lease-HBD4CmBx.cjs +224 -0
  32. package/dist/runtime/lock-DBeYN-Zg.cjs +141 -0
  33. package/dist/runtime/messages-vUDkl1-0.cjs +174 -0
  34. package/dist/runtime/p-map-b8pXdaFZ.cjs +105 -0
  35. package/dist/runtime/proc-hB8N9WjN.cjs +127 -0
  36. package/dist/runtime/provenance-B4bajGXQ.cjs +2 -0
  37. package/dist/runtime/rolldown-runtime-BGT596CS.cjs +64 -0
  38. package/dist/runtime/runtime.cjs +143 -0
  39. package/dist/runtime/src-SpeGbMJx.cjs +314 -0
  40. package/dist/src-Bc9nN1Kl.cjs +2125 -0
  41. package/dist/src-Bc9nN1Kl.cjs.map +1 -0
  42. package/dist/src-NhNG2mnQ.js +1798 -0
  43. package/dist/src-NhNG2mnQ.js.map +1 -0
  44. package/package.json +87 -17
  45. package/index.js +0 -3
@@ -0,0 +1,314 @@
1
+ const require_messages = require("./messages-vUDkl1-0.cjs");
2
+ const require_install = require("./install-C_M5WK98.cjs");
3
+ let node_path = require("node:path");
4
+ let node_fs = require("node:fs");
5
+ //#region src/project.ts
6
+ const BOOLEANS = /* @__PURE__ */ new Set(["global", "workspaces"]);
7
+ const SHORTHANDS = {
8
+ C: "prefix",
9
+ g: "global",
10
+ L: "location",
11
+ ws: "workspaces"
12
+ };
13
+ /**
14
+ * The subset of nopt that decides the prefix: `--flag value`, `--flag=value`, `--no-flag`, `--flag true|false` for booleans, npm's shorthands and `--`.
15
+ * Later flags win, as in nopt.
16
+ */
17
+ function parsePrefixFlags(argv, cwd) {
18
+ const flags = {
19
+ prefix: null,
20
+ global: null,
21
+ location: null,
22
+ workspaces: null
23
+ };
24
+ for (let i = 0; i < argv.length; i += 1) {
25
+ const arg = argv[i];
26
+ if (arg === "--") break;
27
+ let name;
28
+ let value = null;
29
+ if (arg.startsWith("--")) {
30
+ const eq = arg.indexOf("=");
31
+ name = eq === -1 ? arg.slice(2) : arg.slice(2, eq);
32
+ value = eq === -1 ? null : arg.slice(eq + 1);
33
+ name = SHORTHANDS[name] ?? name;
34
+ } else if (arg.startsWith("-") && arg.length > 1 && SHORTHANDS[arg.slice(1)] !== void 0) name = SHORTHANDS[arg.slice(1)];
35
+ else continue;
36
+ let negated = false;
37
+ if (name.startsWith("no-") && BOOLEANS.has(name.slice(3))) {
38
+ negated = true;
39
+ name = name.slice(3);
40
+ }
41
+ if (BOOLEANS.has(name)) {
42
+ let bool = !negated;
43
+ if (value !== null) bool = value !== "false";
44
+ else if (!negated && (argv[i + 1] === "true" || argv[i + 1] === "false")) {
45
+ bool = argv[i + 1] === "true";
46
+ i += 1;
47
+ }
48
+ if (name === "global") flags.global = bool;
49
+ else flags.workspaces = bool;
50
+ continue;
51
+ }
52
+ if (name !== "prefix" && name !== "location") continue;
53
+ if (value === null) {
54
+ if (i + 1 >= argv.length) continue;
55
+ value = argv[i + 1];
56
+ i += 1;
57
+ }
58
+ if (name === "prefix") flags.prefix = (0, node_path.resolve)(cwd, value);
59
+ else flags.location = value;
60
+ }
61
+ return flags;
62
+ }
63
+ /** Global mode from the command line and the npm env, CLI winning (spec RES-3). */
64
+ function isGlobalMode(flags, env) {
65
+ const fromEnv = env["npm_config_global"];
66
+ const global = flags.global ?? (fromEnv === void 0 || fromEnv === "" ? null : ![
67
+ "false",
68
+ "0",
69
+ "null"
70
+ ].includes(fromEnv));
71
+ const location = flags.location ?? env["npm_config_location"] ?? null;
72
+ return global === true || location === "global";
73
+ }
74
+ function hasPackageJson(dir) {
75
+ try {
76
+ return (0, node_fs.statSync)((0, node_path.join)(dir, "package.json")).isFile();
77
+ } catch {
78
+ return false;
79
+ }
80
+ }
81
+ function hasNodeModules(dir) {
82
+ try {
83
+ return (0, node_fs.statSync)((0, node_path.join)(dir, "node_modules")).isDirectory();
84
+ } catch {
85
+ return false;
86
+ }
87
+ }
88
+ function* walkUp(start) {
89
+ let dir = (0, node_path.resolve)(start);
90
+ for (;;) {
91
+ yield dir;
92
+ const parent = (0, node_path.dirname)(dir);
93
+ if (parent === dir) return;
94
+ dir = parent;
95
+ }
96
+ }
97
+ /** The `workspaces` patterns of a manifest: the array form or `{ packages: [] }`, else none. */
98
+ function workspacePatterns(pkg) {
99
+ if (typeof pkg !== "object" || pkg === null) return [];
100
+ let raw = pkg.workspaces;
101
+ if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) raw = raw.packages;
102
+ if (!Array.isArray(raw)) return [];
103
+ return raw.filter((entry) => typeof entry === "string");
104
+ }
105
+ /**
106
+ * Whether `candidate` is one of the workspaces `root` declares, matched like `@npmcli/map-workspaces`.
107
+ * A pattern selects directories holding a `package.json`, `!pattern` removes matches, and `node_modules` never matches.
108
+ */
109
+ function isWorkspaceOf(root, candidate, patterns) {
110
+ const rel = (0, node_path.relative)(root, candidate);
111
+ if (rel === "" || rel.startsWith("..") || (0, node_path.isAbsolute)(rel) || !hasPackageJson(candidate)) return false;
112
+ if (rel.split(node_path.sep).includes("node_modules")) return false;
113
+ const posix = rel.split(node_path.sep).join("/");
114
+ const { positive, negative } = splitPatterns(patterns);
115
+ return positive.some((pattern) => (0, node_path.matchesGlob)(posix, pattern)) && !negative.some((pattern) => (0, node_path.matchesGlob)(posix, pattern));
116
+ }
117
+ function splitPatterns(patterns) {
118
+ const positive = [];
119
+ const negative = [];
120
+ for (const raw of patterns) {
121
+ const bangs = /^!+/.exec(raw)?.[0].length ?? 0;
122
+ const pattern = normalizePattern(raw.slice(bangs));
123
+ if (bangs % 2 === 1) {
124
+ negative.push(pattern);
125
+ continue;
126
+ }
127
+ for (let i = negative.length - 1; i >= 0; i -= 1) if ((0, node_path.matchesGlob)(pattern, negative[i])) negative.splice(i, 1);
128
+ positive.push(pattern);
129
+ }
130
+ return {
131
+ positive,
132
+ negative
133
+ };
134
+ }
135
+ function normalizePattern(pattern) {
136
+ return pattern.replace(/\\/g, "/").replace(/^\.?\/+/, "").replace(/\/+$/, "");
137
+ }
138
+ function readManifest(dir) {
139
+ try {
140
+ return JSON.parse((0, node_fs.readFileSync)((0, node_path.join)(dir, "package.json"), "utf8"));
141
+ } catch {
142
+ return null;
143
+ }
144
+ }
145
+ /**
146
+ * Mirrors `@npmcli/config` `loadLocalPrefix` (spec RES-2): a CLI prefix is final.
147
+ * Otherwise the nearest ancestor with `package.json` or `node_modules` wins, promoted to a parent whose `workspaces` include it unless `--no-workspaces` or global mode.
148
+ */
149
+ function findProject(argv, cwd, env = process.env) {
150
+ const flags = parsePrefixFlags(argv, cwd);
151
+ const global = isGlobalMode(flags, env);
152
+ if (flags.prefix !== null) return {
153
+ root: flags.prefix,
154
+ global,
155
+ cliPrefix: flags.prefix
156
+ };
157
+ let localPrefix = null;
158
+ for (const dir of walkUp(cwd)) {
159
+ const manifest = hasPackageJson(dir);
160
+ if (localPrefix === null) {
161
+ if (manifest || hasNodeModules(dir)) {
162
+ localPrefix = dir;
163
+ if (flags.workspaces === false || global) break;
164
+ }
165
+ continue;
166
+ }
167
+ if (!manifest) continue;
168
+ const pkg = readManifest(dir);
169
+ if (pkg !== null && isWorkspaceOf(dir, localPrefix, workspacePatterns(pkg))) {
170
+ localPrefix = dir;
171
+ break;
172
+ }
173
+ }
174
+ return {
175
+ root: localPrefix ?? (0, node_path.resolve)(cwd),
176
+ global,
177
+ cliPrefix: null
178
+ };
179
+ }
180
+ //#endregion
181
+ //#region src/index.ts
182
+ /** Resolves the npm to run for `argv` in `cwd` (spec section 5); writes only under the cache, spawns npm only as the transport. */
183
+ function resolveNpm(argv, cwd, options = {}) {
184
+ const env = options.env ?? process.env;
185
+ return resolveNpmWith(argv, cwd, options, require_install.createInstaller(require_install.createContext(env, options.home)));
186
+ }
187
+ async function resolveNpmWith(argv, cwd, options, providers) {
188
+ const env = options.env ?? process.env;
189
+ const own = providers.ownNpm();
190
+ const ownResult = (projectRoot, source, warning) => {
191
+ if (own === null) throw new require_messages.NpmVmError("M-TRANSPORT", require_messages.EXIT.transport, "No npm found beside the active Node; reinstall Node.");
192
+ return {
193
+ kind: "own",
194
+ version: own.version,
195
+ cliPath: own.cliPath,
196
+ source,
197
+ projectRoot,
198
+ selection: null,
199
+ specs: null,
200
+ warning
201
+ };
202
+ };
203
+ if (nonEmpty(env["NPM_VM_DISABLE"])) return ownResult(null, null, null);
204
+ const project = findProject(argv, cwd, env);
205
+ if (project.global) return ownResult(project.root, null, null);
206
+ let parsed;
207
+ let source;
208
+ if (nonEmpty(env["NPM_VM_VERSION"])) {
209
+ parsed = {
210
+ specs: [require_install.parseVersionSpec(env["NPM_VM_VERSION"], "NPM_VM_VERSION")],
211
+ onFail: "error",
212
+ field: "devEngines"
213
+ };
214
+ source = {
215
+ file: "NPM_VM_VERSION",
216
+ field: "env"
217
+ };
218
+ } else {
219
+ const file = (0, node_path.join)(project.root, "package.json");
220
+ let read;
221
+ try {
222
+ read = readSpecs(file);
223
+ } catch (error) {
224
+ if (!(error instanceof require_install.SpecError)) throw error;
225
+ const message = `${file}: ${error.message}`;
226
+ const failure = new require_messages.NpmVmError("M-NOMATCH", require_messages.EXIT.resolution, message);
227
+ return applyPolicy(error.onFail, failure, () => ownResult(project.root, null, message));
228
+ }
229
+ if (read === null) return ownResult(project.root, null, null);
230
+ parsed = read;
231
+ source = {
232
+ file,
233
+ field: read.field
234
+ };
235
+ }
236
+ if (own !== null && require_install.ownNpmSatisfies(own.version, parsed.specs)) return ownResult(project.root, source, null);
237
+ const cached = await providers.cached(parsed.specs);
238
+ let result = require_install.selectCandidate(parsed.specs, cached, providers.nodeVersion);
239
+ if (result.kind === "failed" && !options.offline && !nonEmpty(env["NPM_VM_OFFLINE"])) {
240
+ let fromRegistry;
241
+ try {
242
+ fromRegistry = await providers.registry(parsed.specs);
243
+ } catch (error) {
244
+ if (!(error instanceof require_messages.NpmVmError) || error.id !== "M-TRANSPORT") throw error;
245
+ return applyPolicy(parsed.onFail, error, () => ownResult(project.root, source, error.message));
246
+ }
247
+ result = require_install.selectCandidate(parsed.specs, fromRegistry, providers.nodeVersion);
248
+ }
249
+ if (result.kind === "selected") {
250
+ const { candidate } = result.selection;
251
+ const entry = candidate.entryPath ?? providers.entryPathFor(candidate);
252
+ return {
253
+ kind: candidate.entryPath === null ? "download" : "cached",
254
+ version: candidate.version,
255
+ cliPath: (0, node_path.join)(entry, "bin", "npm-cli.js"),
256
+ source,
257
+ projectRoot: project.root,
258
+ selection: result.selection,
259
+ specs: parsed.specs,
260
+ warning: null
261
+ };
262
+ }
263
+ const message = result.failure.kind === "engine" ? require_messages.engineMessage(result.failure.version, result.failure.enginesNode, providers.nodeVersion) : require_messages.noMatchMessage(parsed.specs, source.file, result.failure.reason);
264
+ const id = result.failure.kind === "engine" ? "M-ENGINE" : "M-NOMATCH";
265
+ const failure = new require_messages.NpmVmError(id, require_messages.EXIT.resolution, message);
266
+ return applyPolicy(parsed.onFail, failure, () => ownResult(project.root, source, message));
267
+ }
268
+ /** `onFail` makes a failed resolution fatal, a warning before Node's own npm, or silent (spec RES-7). */
269
+ function applyPolicy(onFail, failure, fallback) {
270
+ if (onFail === "ignore") return {
271
+ ...fallback(),
272
+ warning: null
273
+ };
274
+ if (onFail === "warn") return fallback();
275
+ throw failure;
276
+ }
277
+ /** Reads and validates the project's specs; a broken file or range follows its own `onFail` when readable, else errors. */
278
+ function readSpecs(file) {
279
+ let text;
280
+ try {
281
+ text = (0, node_fs.readFileSync)(file, "utf8");
282
+ } catch {
283
+ return null;
284
+ }
285
+ let pkg;
286
+ try {
287
+ pkg = JSON.parse(text);
288
+ } catch (error) {
289
+ throw new require_messages.NpmVmError("M-NOMATCH", require_messages.EXIT.resolution, `${file} is not valid JSON: ${error.message}`);
290
+ }
291
+ return require_install.parseSpecs(pkg);
292
+ }
293
+ function nonEmpty(value) {
294
+ return value !== void 0 && value !== "";
295
+ }
296
+ //#endregion
297
+ Object.defineProperty(exports, "findProject", {
298
+ enumerable: true,
299
+ get: function() {
300
+ return findProject;
301
+ }
302
+ });
303
+ Object.defineProperty(exports, "resolveNpm", {
304
+ enumerable: true,
305
+ get: function() {
306
+ return resolveNpm;
307
+ }
308
+ });
309
+ Object.defineProperty(exports, "resolveNpmWith", {
310
+ enumerable: true,
311
+ get: function() {
312
+ return resolveNpmWith;
313
+ }
314
+ });