@verdaccio/e2e-cli 2.6.0 → 2.8.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 (56) hide show
  1. package/build/adapters/bun.d.ts +2 -0
  2. package/build/adapters/deno.d.ts +2 -0
  3. package/build/adapters/index.d.ts +2 -0
  4. package/build/cjs/adapters/bun.cjs +63 -0
  5. package/build/cjs/adapters/bun.cjs.map +1 -0
  6. package/build/cjs/adapters/deno.cjs +58 -0
  7. package/build/cjs/adapters/deno.cjs.map +1 -0
  8. package/build/cjs/adapters/index.cjs +2 -0
  9. package/build/cjs/index.cjs +16 -6
  10. package/build/cjs/index.cjs.map +1 -1
  11. package/build/cjs/scenarios/index.cjs +6 -0
  12. package/build/cjs/scenarios/index.cjs.map +1 -0
  13. package/build/cjs/scenarios/install-multiple-deps.cjs +116 -0
  14. package/build/cjs/scenarios/install-multiple-deps.cjs.map +1 -0
  15. package/build/cjs/tests/audit.cjs +24 -4
  16. package/build/cjs/tests/audit.cjs.map +1 -1
  17. package/build/cjs/tests/ci.cjs +83 -0
  18. package/build/cjs/tests/ci.cjs.map +1 -0
  19. package/build/cjs/tests/index.cjs +6 -1
  20. package/build/cjs/tests/index.cjs.map +1 -1
  21. package/build/cjs/tests/info.cjs +3 -0
  22. package/build/cjs/tests/info.cjs.map +1 -1
  23. package/build/cjs/tests/install.cjs +0 -1
  24. package/build/cjs/tests/install.cjs.map +1 -1
  25. package/build/cjs/tests/publish.cjs +1 -0
  26. package/build/cjs/tests/publish.cjs.map +1 -1
  27. package/build/esm/adapters/bun.js +61 -0
  28. package/build/esm/adapters/bun.js.map +1 -0
  29. package/build/esm/adapters/deno.js +56 -0
  30. package/build/esm/adapters/deno.js.map +1 -0
  31. package/build/esm/adapters/index.js +2 -0
  32. package/build/esm/index.js +11 -4
  33. package/build/esm/index.js.map +1 -1
  34. package/build/esm/scenarios/index.js +7 -0
  35. package/build/esm/scenarios/index.js.map +1 -0
  36. package/build/esm/scenarios/install-multiple-deps.js +113 -0
  37. package/build/esm/scenarios/install-multiple-deps.js.map +1 -0
  38. package/build/esm/tests/audit.js +23 -4
  39. package/build/esm/tests/audit.js.map +1 -1
  40. package/build/esm/tests/ci.js +80 -0
  41. package/build/esm/tests/ci.js.map +1 -0
  42. package/build/esm/tests/index.js +6 -1
  43. package/build/esm/tests/index.js.map +1 -1
  44. package/build/esm/tests/info.js +3 -0
  45. package/build/esm/tests/info.js.map +1 -1
  46. package/build/esm/tests/install.js +0 -1
  47. package/build/esm/tests/install.js.map +1 -1
  48. package/build/esm/tests/publish.js +1 -0
  49. package/build/esm/tests/publish.js.map +1 -1
  50. package/build/index.d.ts +2 -1
  51. package/build/scenarios/index.d.ts +4 -0
  52. package/build/scenarios/install-multiple-deps.d.ts +2 -0
  53. package/build/tests/ci.d.ts +2 -0
  54. package/build/tests/index.d.ts +3 -1
  55. package/build/types.d.ts +2 -2
  56. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ import { PackageManagerAdapter } from '../types';
2
+ export declare function createBunAdapter(binPath?: string, _version?: string): PackageManagerAdapter;
@@ -0,0 +1,2 @@
1
+ import { PackageManagerAdapter } from '../types';
2
+ export declare function createDenoAdapter(binPath?: string, _version?: string): PackageManagerAdapter;
@@ -1,3 +1,5 @@
1
+ export { createBunAdapter } from './bun';
2
+ export { createDenoAdapter } from './deno';
1
3
  export { createNpmAdapter } from './npm';
2
4
  export { createPnpmAdapter } from './pnpm';
3
5
  export { createYarnClassicAdapter } from './yarn-classic';
@@ -0,0 +1,63 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_process = require("../utils/process.cjs");
3
+ const require_project = require("../utils/project.cjs");
4
+ let debug = require("debug");
5
+ debug = require_runtime.__toESM(debug);
6
+ let child_process = require("child_process");
7
+ //#region src/adapters/bun.ts
8
+ var debug$1 = (0, debug.default)("verdaccio:e2e-cli:bun");
9
+ var BUN_SUPPORTED_COMMANDS = new Set([
10
+ "publish",
11
+ "install",
12
+ "info",
13
+ "audit"
14
+ ]);
15
+ function detectVersion(bin) {
16
+ try {
17
+ return (0, child_process.execSync)(`${bin} --version`, {
18
+ encoding: "utf8",
19
+ timeout: 5e3
20
+ }).trim();
21
+ } catch {
22
+ return "unknown";
23
+ }
24
+ }
25
+ function resolveBunBin(binPath) {
26
+ if (binPath) return binPath;
27
+ return "bun";
28
+ }
29
+ function createBunAdapter(binPath, _version) {
30
+ const bin = resolveBunBin(binPath);
31
+ const resolved = detectVersion(bin);
32
+ debug$1("creating bun adapter with bin: %s (%s)", bin, resolved);
33
+ return {
34
+ name: `bun@${resolved}`,
35
+ type: "bun",
36
+ bin,
37
+ supports: BUN_SUPPORTED_COMMANDS,
38
+ registryArg(url) {
39
+ return ["--registry", url];
40
+ },
41
+ prefixArg(folder) {
42
+ return ["--cwd", folder];
43
+ },
44
+ exec(options, ...args) {
45
+ if (args[0] === "info") {
46
+ const pkgName = args[1];
47
+ return require_process.exec(options, bin, [
48
+ "info",
49
+ pkgName,
50
+ ...args.slice(2).filter((a) => a !== "--registry").filter((a) => !a.startsWith("http"))
51
+ ]);
52
+ }
53
+ return require_process.exec(options, bin, args);
54
+ },
55
+ async prepareProject(packageName, version, registryUrl, port, token, dependencies = {}, devDependencies = {}) {
56
+ return require_project.prepareGenericEmptyProject(packageName, version, port, token, registryUrl, dependencies, devDependencies);
57
+ }
58
+ };
59
+ }
60
+ //#endregion
61
+ exports.createBunAdapter = createBunAdapter;
62
+
63
+ //# sourceMappingURL=bun.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun.cjs","names":[],"sources":["../../../src/adapters/bun.ts"],"sourcesContent":["import { SpawnOptions, execSync } from 'child_process';\nimport buildDebug from 'debug';\n\nimport { ExecOutput, PackageManagerAdapter } from '../types';\nimport { exec } from '../utils/process';\nimport { prepareGenericEmptyProject } from '../utils/project';\n\nconst debug = buildDebug('verdaccio:e2e-cli:bun');\n\nconst BUN_SUPPORTED_COMMANDS = new Set([\n 'publish',\n 'install',\n 'info',\n 'audit',\n]);\n\nfunction detectVersion(bin: string): string {\n try {\n return execSync(`${bin} --version`, { encoding: 'utf8', timeout: 5000 }).trim();\n } catch {\n return 'unknown';\n }\n}\n\nfunction resolveBunBin(binPath?: string): string {\n if (binPath) return binPath;\n return 'bun';\n}\n\nexport function createBunAdapter(binPath?: string, _version?: string): PackageManagerAdapter {\n const bin = resolveBunBin(binPath);\n const resolved = detectVersion(bin);\n debug('creating bun adapter with bin: %s (%s)', bin, resolved);\n\n const adapter: PackageManagerAdapter = {\n name: `bun@${resolved}`,\n type: 'bun',\n bin,\n supports: BUN_SUPPORTED_COMMANDS,\n\n registryArg(url: string): string[] {\n return ['--registry', url];\n },\n\n prefixArg(folder: string): string[] {\n return ['--cwd', folder];\n },\n\n exec(options: SpawnOptions, ...args: string[]): Promise<ExecOutput> {\n const cmd = args[0];\n\n if (cmd === 'info') {\n // bun info <pkg> reads registry from .npmrc, strip --registry <url>\n const pkgName = args[1];\n const filteredArgs = args.slice(2).filter((a) => a !== '--registry');\n // also remove the URL that follows --registry\n const cleaned = filteredArgs.filter((a) => !a.startsWith('http'));\n return exec(options, bin, ['info', pkgName, ...cleaned]);\n }\n\n return exec(options, bin, args);\n },\n\n async prepareProject(\n packageName: string,\n version: string,\n registryUrl: string,\n port: number,\n token: string,\n dependencies: Record<string, string> = {},\n devDependencies: Record<string, string> = {}\n ): Promise<{ tempFolder: string }> {\n return prepareGenericEmptyProject(\n packageName,\n version,\n port,\n token,\n registryUrl,\n dependencies,\n devDependencies\n );\n },\n };\n\n return adapter;\n}\n"],"mappings":";;;;;;;AAOA,IAAM,WAAA,GAAA,MAAA,SAAmB,wBAAwB;AAEjD,IAAM,yBAAyB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,cAAc,KAAqB;AAC1C,KAAI;AACF,UAAA,GAAA,cAAA,UAAgB,GAAG,IAAI,aAAa;GAAE,UAAU;GAAQ,SAAS;GAAM,CAAC,CAAC,MAAM;SACzE;AACN,SAAO;;;AAIX,SAAS,cAAc,SAA0B;AAC/C,KAAI,QAAS,QAAO;AACpB,QAAO;;AAGT,SAAgB,iBAAiB,SAAkB,UAA0C;CAC3F,MAAM,MAAM,cAAc,QAAQ;CAClC,MAAM,WAAW,cAAc,IAAI;AACnC,SAAM,0CAA0C,KAAK,SAAS;AAoD9D,QAlDuC;EACrC,MAAM,OAAO;EACb,MAAM;EACN;EACA,UAAU;EAEV,YAAY,KAAuB;AACjC,UAAO,CAAC,cAAc,IAAI;;EAG5B,UAAU,QAA0B;AAClC,UAAO,CAAC,SAAS,OAAO;;EAG1B,KAAK,SAAuB,GAAG,MAAqC;AAGlE,OAFY,KAAK,OAEL,QAAQ;IAElB,MAAM,UAAU,KAAK;AAIrB,WAAO,gBAAA,KAAK,SAAS,KAAK;KAAC;KAAQ;KAAS,GAHvB,KAAK,MAAM,EAAE,CAAC,QAAQ,MAAM,MAAM,aAAa,CAEvC,QAAQ,MAAM,CAAC,EAAE,WAAW,OAAO,CAAC;KACV,CAAC;;AAG1D,UAAO,gBAAA,KAAK,SAAS,KAAK,KAAK;;EAGjC,MAAM,eACJ,aACA,SACA,aACA,MACA,OACA,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACX;AACjC,UAAO,gBAAA,2BACL,aACA,SACA,MACA,OACA,aACA,cACA,gBACD;;EAEJ"}
@@ -0,0 +1,58 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_process = require("../utils/process.cjs");
3
+ const require_project = require("../utils/project.cjs");
4
+ let debug = require("debug");
5
+ debug = require_runtime.__toESM(debug);
6
+ let child_process = require("child_process");
7
+ //#region src/adapters/deno.ts
8
+ var debug$1 = (0, debug.default)("verdaccio:e2e-cli:deno");
9
+ var DENO_SUPPORTED_COMMANDS = new Set(["install", "info"]);
10
+ function detectVersion(bin) {
11
+ try {
12
+ const match = (0, child_process.execSync)(`${bin} --version`, {
13
+ encoding: "utf8",
14
+ timeout: 5e3
15
+ }).match(/deno (\S+)/);
16
+ return match ? match[1] : "unknown";
17
+ } catch {
18
+ return "unknown";
19
+ }
20
+ }
21
+ function resolveDenoBin(binPath) {
22
+ if (binPath) return binPath;
23
+ return "deno";
24
+ }
25
+ function createDenoAdapter(binPath, _version) {
26
+ const bin = resolveDenoBin(binPath);
27
+ const resolved = detectVersion(bin);
28
+ debug$1("creating deno adapter with bin: %s (%s)", bin, resolved);
29
+ return {
30
+ name: `deno@${resolved}`,
31
+ type: "deno",
32
+ bin,
33
+ supports: DENO_SUPPORTED_COMMANDS,
34
+ registryArg(_url) {
35
+ return [];
36
+ },
37
+ prefixArg(folder) {
38
+ return ["--root", folder];
39
+ },
40
+ exec(options, ...args) {
41
+ const cmd = args[0];
42
+ if (cmd === "info") return require_process.exec(options, bin, [
43
+ "info",
44
+ `npm:${args[1]}`,
45
+ "--node-modules-dir=auto"
46
+ ].concat(args.slice(2).filter((a) => a !== "--json")));
47
+ if (cmd === "install") return require_process.exec(options, bin, ["install"]);
48
+ return require_process.exec(options, bin, args);
49
+ },
50
+ async prepareProject(packageName, version, registryUrl, port, token, dependencies = {}, devDependencies = {}) {
51
+ return require_project.prepareGenericEmptyProject(packageName, version, port, token, registryUrl, dependencies, devDependencies);
52
+ }
53
+ };
54
+ }
55
+ //#endregion
56
+ exports.createDenoAdapter = createDenoAdapter;
57
+
58
+ //# sourceMappingURL=deno.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno.cjs","names":[],"sources":["../../../src/adapters/deno.ts"],"sourcesContent":["import { SpawnOptions, execSync } from 'child_process';\nimport buildDebug from 'debug';\n\nimport { ExecOutput, PackageManagerAdapter } from '../types';\nimport { exec } from '../utils/process';\nimport { prepareGenericEmptyProject } from '../utils/project';\n\nconst debug = buildDebug('verdaccio:e2e-cli:deno');\n\nconst DENO_SUPPORTED_COMMANDS = new Set(['install', 'info']);\n\nfunction detectVersion(bin: string): string {\n try {\n const output = execSync(`${bin} --version`, { encoding: 'utf8', timeout: 5000 });\n const match = output.match(/deno (\\S+)/);\n return match ? match[1] : 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nfunction resolveDenoBin(binPath?: string): string {\n if (binPath) return binPath;\n return 'deno';\n}\n\nexport function createDenoAdapter(binPath?: string, _version?: string): PackageManagerAdapter {\n const bin = resolveDenoBin(binPath);\n const resolved = detectVersion(bin);\n debug('creating deno adapter with bin: %s (%s)', bin, resolved);\n\n const adapter: PackageManagerAdapter = {\n name: `deno@${resolved}`,\n type: 'deno',\n bin,\n supports: DENO_SUPPORTED_COMMANDS,\n\n registryArg(_url: string): string[] {\n // deno reads the registry from .npmrc (written by prepareProject), no CLI flag needed\n return [];\n },\n\n prefixArg(folder: string): string[] {\n return ['--root', folder];\n },\n\n exec(options: SpawnOptions, ...args: string[]): Promise<ExecOutput> {\n const cmd = args[0];\n\n if (cmd === 'info') {\n // deno info npm:<pkg> --node-modules-dir=auto\n const pkgName = args[1];\n const filteredArgs = ['info', `npm:${pkgName}`, '--node-modules-dir=auto'].concat(\n args.slice(2).filter((a) => a !== '--json')\n );\n return exec(options, bin, filteredArgs);\n }\n\n if (cmd === 'install') {\n // deno install — reads registry from .npmrc, no extra flags needed\n return exec(options, bin, ['install']);\n }\n\n return exec(options, bin, args);\n },\n\n async prepareProject(\n packageName: string,\n version: string,\n registryUrl: string,\n port: number,\n token: string,\n dependencies: Record<string, string> = {},\n devDependencies: Record<string, string> = {}\n ): Promise<{ tempFolder: string }> {\n return prepareGenericEmptyProject(\n packageName,\n version,\n port,\n token,\n registryUrl,\n dependencies,\n devDependencies\n );\n },\n };\n\n return adapter;\n}\n"],"mappings":";;;;;;;AAOA,IAAM,WAAA,GAAA,MAAA,SAAmB,yBAAyB;AAElD,IAAM,0BAA0B,IAAI,IAAI,CAAC,WAAW,OAAO,CAAC;AAE5D,SAAS,cAAc,KAAqB;AAC1C,KAAI;EAEF,MAAM,SAAA,GAAA,cAAA,UADkB,GAAG,IAAI,aAAa;GAAE,UAAU;GAAQ,SAAS;GAAM,CAAC,CAC3D,MAAM,aAAa;AACxC,SAAO,QAAQ,MAAM,KAAK;SACpB;AACN,SAAO;;;AAIX,SAAS,eAAe,SAA0B;AAChD,KAAI,QAAS,QAAO;AACpB,QAAO;;AAGT,SAAgB,kBAAkB,SAAkB,UAA0C;CAC5F,MAAM,MAAM,eAAe,QAAQ;CACnC,MAAM,WAAW,cAAc,IAAI;AACnC,SAAM,2CAA2C,KAAK,SAAS;AA0D/D,QAxDuC;EACrC,MAAM,QAAQ;EACd,MAAM;EACN;EACA,UAAU;EAEV,YAAY,MAAwB;AAElC,UAAO,EAAE;;EAGX,UAAU,QAA0B;AAClC,UAAO,CAAC,UAAU,OAAO;;EAG3B,KAAK,SAAuB,GAAG,MAAqC;GAClE,MAAM,MAAM,KAAK;AAEjB,OAAI,QAAQ,OAMV,QAAO,gBAAA,KAAK,SAAS,KAHA;IAAC;IAAQ,OADd,KAAK;IAC2B;IAA0B,CAAC,OACzE,KAAK,MAAM,EAAE,CAAC,QAAQ,MAAM,MAAM,SAAS,CAC5C,CACsC;AAGzC,OAAI,QAAQ,UAEV,QAAO,gBAAA,KAAK,SAAS,KAAK,CAAC,UAAU,CAAC;AAGxC,UAAO,gBAAA,KAAK,SAAS,KAAK,KAAK;;EAGjC,MAAM,eACJ,aACA,SACA,aACA,MACA,OACA,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACX;AACjC,UAAO,gBAAA,2BACL,aACA,SACA,MACA,OACA,aACA,cACA,gBACD;;EAEJ"}
@@ -1,3 +1,5 @@
1
+ require("./bun.cjs");
2
+ require("./deno.cjs");
1
3
  require("./npm.cjs");
2
4
  require("./pnpm.cjs");
3
5
  require("./yarn-classic.cjs");
@@ -1,11 +1,14 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
3
+ const require_bun = require("./adapters/bun.cjs");
4
+ const require_deno = require("./adapters/deno.cjs");
3
5
  const require_npm = require("./adapters/npm.cjs");
4
6
  const require_pnpm = require("./adapters/pnpm.cjs");
5
7
  const require_yarn_classic = require("./adapters/yarn-classic.cjs");
6
8
  const require_yarn_modern = require("./adapters/yarn-modern.cjs");
7
9
  require("./adapters/index.cjs");
8
- const require_index$1 = require("./tests/index.cjs");
10
+ const require_index$1 = require("./scenarios/index.cjs");
11
+ const require_index$2 = require("./tests/index.cjs");
9
12
  const require_registry_client = require("./utils/registry-client.cjs");
10
13
  const require_runner = require("./runner.cjs");
11
14
  let debug = require("debug");
@@ -34,7 +37,9 @@ function parseAdapters(pmFilters) {
34
37
  else if (name === "pnpm") adapters.push(require_pnpm.createPnpmAdapter(binPath, version));
35
38
  else if (name === "yarn-classic" || name === "yarn1") adapters.push(require_yarn_classic.createYarnClassicAdapter(binPath, version));
36
39
  else if (name === "yarn-modern" || name === "yarn") adapters.push(require_yarn_modern.createYarnModernAdapter(binPath, version));
37
- else throw new Error(`Unknown package manager: "${name}". Supported: npm, pnpm, yarn-classic, yarn-modern[@version]`);
40
+ else if (name === "bun") adapters.push(require_bun.createBunAdapter(binPath, version));
41
+ else if (name === "deno") adapters.push(require_deno.createDenoAdapter(binPath, version));
42
+ else throw new Error(`Unknown package manager: "${name}". Supported: npm, pnpm, yarn-classic, yarn-modern, bun, deno`);
38
43
  }
39
44
  return adapters;
40
45
  }
@@ -84,18 +89,20 @@ function printHelp() {
84
89
 
85
90
  Options:
86
91
  --pm <name[@version]> Package manager to test (can be repeated)
87
- Supported: npm, pnpm, yarn-classic, yarn-modern (or yarn)
92
+ Supported: npm, pnpm, yarn-classic, yarn-modern (or yarn), bun, deno
88
93
  Examples: --pm npm@10 --pm pnpm@9
89
94
  --pm yarn-modern@4
90
95
  --pm yarn-modern@3
91
96
  --pm yarn-classic
97
+ --pm bun
92
98
  --pm npm --pm pnpm (uses system version)
93
99
  Auto-installs the requested yarn version if needed
94
100
  Default: npm
95
101
 
96
102
  -t, --test <name> Filter tests by name (can be repeated)
97
- Available: publish, install, audit, info, deprecate,
103
+ Available: publish, install, ci, audit, info, deprecate,
98
104
  dist-tags, ping, search, star, unpublish
105
+ Scenarios: scenario:install-multiple-deps
99
106
  Default: all supported by the PM
100
107
 
101
108
  --token <token> Auth token (skips user creation)
@@ -133,7 +140,7 @@ async function main(argv = process.argv) {
133
140
  }
134
141
  const adapters = parseAdapters(options.pm);
135
142
  console.log(`Adapters: ${adapters.map((a) => a.name).join(", ")}`);
136
- const tests = options.test && options.test.length > 0 ? require_index$1.allTests.filter((t) => options.test.includes(t.name)) : require_index$1.allTests;
143
+ const tests = options.test && options.test.length > 0 ? require_index$2.allTests.filter((t) => options.test.includes(t.name)) : require_index$2.allTests;
137
144
  console.log(`Tests: ${tests.map((t) => t.name).join(", ")}`);
138
145
  const { exitCode } = await require_runner.runAll(adapters, tests, options.registry, token, {
139
146
  timeout: options.timeout,
@@ -143,7 +150,10 @@ async function main(argv = process.argv) {
143
150
  process.exit(exitCode);
144
151
  }
145
152
  //#endregion
146
- exports.allTests = require_index$1.allTests;
153
+ exports.allScenarios = require_index$1.allScenarios;
154
+ exports.allTests = require_index$2.allTests;
155
+ exports.createBunAdapter = require_bun.createBunAdapter;
156
+ exports.createDenoAdapter = require_deno.createDenoAdapter;
147
157
  exports.createNpmAdapter = require_npm.createNpmAdapter;
148
158
  exports.createPnpmAdapter = require_pnpm.createPnpmAdapter;
149
159
  exports.createYarnClassicAdapter = require_yarn_classic.createYarnClassicAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport {\n createNpmAdapter,\n createPnpmAdapter,\n createYarnClassicAdapter,\n createYarnModernAdapter,\n} from './adapters';\nimport { allTests } from './tests';\nimport { CliOptions, PackageManagerAdapter } from './types';\nimport { createUser, pingRegistry } from './utils/registry-client';\nimport { runAll } from './runner';\n\nconst debug = buildDebug('verdaccio:e2e-cli');\n\nfunction parsePmSpec(filter: string): { name: string; version?: string; binPath?: string } {\n // --pm yarn-modern@3, --pm yarn-classic@1.22.22, --pm npm=/path/to/bin\n const eqIdx = filter.indexOf('=');\n if (eqIdx !== -1) {\n return { name: filter.slice(0, eqIdx).toLowerCase(), binPath: filter.slice(eqIdx + 1) };\n }\n const atIdx = filter.indexOf('@');\n if (atIdx !== -1) {\n return { name: filter.slice(0, atIdx).toLowerCase(), version: filter.slice(atIdx + 1) };\n }\n return { name: filter.toLowerCase() };\n}\n\nfunction parseAdapters(pmFilters?: string[]): PackageManagerAdapter[] {\n if (!pmFilters || pmFilters.length === 0) {\n return [createNpmAdapter()];\n }\n\n const adapters: PackageManagerAdapter[] = [];\n\n for (const filter of pmFilters) {\n const { name, version, binPath } = parsePmSpec(filter);\n\n if (name === 'npm') {\n adapters.push(createNpmAdapter(binPath, version));\n } else if (name === 'pnpm') {\n adapters.push(createPnpmAdapter(binPath, version));\n } else if (name === 'yarn-classic' || name === 'yarn1') {\n adapters.push(createYarnClassicAdapter(binPath, version));\n } else if (name === 'yarn-modern' || name === 'yarn') {\n adapters.push(createYarnModernAdapter(binPath, version));\n } else {\n throw new Error(\n `Unknown package manager: \"${name}\". Supported: npm, pnpm, yarn-classic, yarn-modern[@version]`\n );\n }\n }\n\n return adapters;\n}\n\nfunction parseArgs(argv: string[]): CliOptions {\n const options: CliOptions = {\n registry: '',\n pm: [],\n test: [],\n concurrency: 1,\n timeout: 50000,\n verbose: false,\n };\n\n for (let i = 2; i < argv.length; i++) {\n const arg = argv[i];\n\n if (arg === '--registry' || arg === '-r') {\n options.registry = argv[++i];\n } else if (arg === '--pm') {\n options.pm!.push(argv[++i]);\n } else if (arg === '--test' || arg === '-t') {\n options.test!.push(argv[++i]);\n } else if (arg === '--concurrency' || arg === '-c') {\n options.concurrency = parseInt(argv[++i], 10);\n } else if (arg === '--timeout') {\n options.timeout = parseInt(argv[++i], 10);\n } else if (arg === '--token') {\n options.token = argv[++i];\n } else if (arg === '--verbose' || arg === '-v') {\n options.verbose = true;\n } else if (arg === '--help' || arg === '-h') {\n printHelp();\n process.exit(0);\n } else if (arg.startsWith('--registry=')) {\n options.registry = arg.split('=')[1];\n } else if (arg.startsWith('--pm=')) {\n options.pm!.push(arg.split('=')[1]);\n } else if (arg.startsWith('--test=')) {\n options.test!.push(arg.split('=')[1]);\n } else if (arg.startsWith('--token=')) {\n options.token = arg.split('=')[1];\n } else if (arg.startsWith('--timeout=')) {\n options.timeout = parseInt(arg.split('=')[1], 10);\n } else {\n console.error(`Unknown argument: ${arg}`);\n printHelp();\n process.exit(1);\n }\n }\n\n return options;\n}\n\nfunction printHelp(): void {\n console.log(`\n @verdaccio/e2e-cli - Run Verdaccio e2e tests against any running registry\n\n Usage:\n verdaccio-e2e --registry <url> [options]\n\n Required:\n -r, --registry <url> Verdaccio registry URL (e.g. http://localhost:4873)\n\n Options:\n --pm <name[@version]> Package manager to test (can be repeated)\n Supported: npm, pnpm, yarn-classic, yarn-modern (or yarn)\n Examples: --pm npm@10 --pm pnpm@9\n --pm yarn-modern@4\n --pm yarn-modern@3\n --pm yarn-classic\n --pm npm --pm pnpm (uses system version)\n Auto-installs the requested yarn version if needed\n Default: npm\n\n -t, --test <name> Filter tests by name (can be repeated)\n Available: publish, install, audit, info, deprecate,\n dist-tags, ping, search, star, unpublish\n Default: all supported by the PM\n\n --token <token> Auth token (skips user creation)\n --timeout <ms> Per-test timeout (default: 50000)\n -v, --verbose Enable debug output\n -h, --help Show this help\n `);\n}\n\nexport async function main(argv: string[] = process.argv): Promise<void> {\n const options = parseArgs(argv);\n\n if (!options.registry) {\n console.error('Error: --registry is required\\n');\n printHelp();\n process.exit(1);\n }\n\n // Run from a temp dir to isolate from the host project's packageManager, .yarnrc.yml, etc.\n const { createTempFolder } = await import('./utils/project');\n const runDir = await createTempFolder('e2e-run');\n process.chdir(runDir);\n\n if (options.verbose) {\n const { setVerbose } = await import('./utils/process');\n setVerbose(true);\n }\n\n // Ensure registry is reachable\n console.log(`Checking registry at ${options.registry}...`);\n const alive = await pingRegistry(options.registry);\n if (!alive) {\n console.error(`Error: Registry at ${options.registry} is not reachable`);\n process.exit(1);\n }\n console.log(`Registry is alive.`);\n\n // Get auth token\n let token = options.token;\n if (!token) {\n console.log('Creating test user...');\n const auth = await createUser(options.registry);\n token = auth.token;\n console.log(`User \"${auth.user}\" created.`);\n }\n\n // Build adapter list\n const adapters = parseAdapters(options.pm);\n console.log(`Adapters: ${adapters.map((a) => a.name).join(', ')}`);\n\n // Filter tests\n const tests = options.test && options.test.length > 0\n ? allTests.filter((t) => options.test!.includes(t.name))\n : allTests;\n\n console.log(`Tests: ${tests.map((t) => t.name).join(', ')}`);\n\n // Run\n const { exitCode } = await runAll(adapters, tests, options.registry, token, {\n timeout: options.timeout,\n concurrency: options.concurrency,\n testFilter: options.test,\n });\n\n process.exit(exitCode);\n}\n\n// Re-export for programmatic usage\nexport { allTests } from './tests';\nexport { createNpmAdapter, createPnpmAdapter, createYarnClassicAdapter, createYarnModernAdapter } from './adapters';\nexport { runAll, runSuite } from './runner';\nexport type { PackageManagerAdapter, TestDefinition, TestContext, CliOptions } from './types';\n"],"mappings":";;;;;;;;;;;;;mBAayB,oBAAoB;AAE7C,SAAS,YAAY,QAAsE;CAEzF,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACjC,KAAI,UAAU,GACZ,QAAO;EAAE,MAAM,OAAO,MAAM,GAAG,MAAM,CAAC,aAAa;EAAE,SAAS,OAAO,MAAM,QAAQ,EAAE;EAAE;CAEzF,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACjC,KAAI,UAAU,GACZ,QAAO;EAAE,MAAM,OAAO,MAAM,GAAG,MAAM,CAAC,aAAa;EAAE,SAAS,OAAO,MAAM,QAAQ,EAAE;EAAE;AAEzF,QAAO,EAAE,MAAM,OAAO,aAAa,EAAE;;AAGvC,SAAS,cAAc,WAA+C;AACpE,KAAI,CAAC,aAAa,UAAU,WAAW,EACrC,QAAO,CAAC,YAAA,kBAAkB,CAAC;CAG7B,MAAM,WAAoC,EAAE;AAE5C,MAAK,MAAM,UAAU,WAAW;EAC9B,MAAM,EAAE,MAAM,SAAS,YAAY,YAAY,OAAO;AAEtD,MAAI,SAAS,MACX,UAAS,KAAK,YAAA,iBAAiB,SAAS,QAAQ,CAAC;WACxC,SAAS,OAClB,UAAS,KAAK,aAAA,kBAAkB,SAAS,QAAQ,CAAC;WACzC,SAAS,kBAAkB,SAAS,QAC7C,UAAS,KAAK,qBAAA,yBAAyB,SAAS,QAAQ,CAAC;WAChD,SAAS,iBAAiB,SAAS,OAC5C,UAAS,KAAK,oBAAA,wBAAwB,SAAS,QAAQ,CAAC;MAExD,OAAM,IAAI,MACR,6BAA6B,KAAK,8DACnC;;AAIL,QAAO;;AAGT,SAAS,UAAU,MAA4B;CAC7C,MAAM,UAAsB;EAC1B,UAAU;EACV,IAAI,EAAE;EACN,MAAM,EAAE;EACR,aAAa;EACb,SAAS;EACT,SAAS;EACV;AAED,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,MAAM,KAAK;AAEjB,MAAI,QAAQ,gBAAgB,QAAQ,KAClC,SAAQ,WAAW,KAAK,EAAE;WACjB,QAAQ,OACjB,SAAQ,GAAI,KAAK,KAAK,EAAE,GAAG;WAClB,QAAQ,YAAY,QAAQ,KACrC,SAAQ,KAAM,KAAK,KAAK,EAAE,GAAG;WACpB,QAAQ,mBAAmB,QAAQ,KAC5C,SAAQ,cAAc,SAAS,KAAK,EAAE,IAAI,GAAG;WACpC,QAAQ,YACjB,SAAQ,UAAU,SAAS,KAAK,EAAE,IAAI,GAAG;WAChC,QAAQ,UACjB,SAAQ,QAAQ,KAAK,EAAE;WACd,QAAQ,eAAe,QAAQ,KACxC,SAAQ,UAAU;WACT,QAAQ,YAAY,QAAQ,MAAM;AAC3C,cAAW;AACX,WAAQ,KAAK,EAAE;aACN,IAAI,WAAW,cAAc,CACtC,SAAQ,WAAW,IAAI,MAAM,IAAI,CAAC;WACzB,IAAI,WAAW,QAAQ,CAChC,SAAQ,GAAI,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG;WAC1B,IAAI,WAAW,UAAU,CAClC,SAAQ,KAAM,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG;WAC5B,IAAI,WAAW,WAAW,CACnC,SAAQ,QAAQ,IAAI,MAAM,IAAI,CAAC;WACtB,IAAI,WAAW,aAAa,CACrC,SAAQ,UAAU,SAAS,IAAI,MAAM,IAAI,CAAC,IAAI,GAAG;OAC5C;AACL,WAAQ,MAAM,qBAAqB,MAAM;AACzC,cAAW;AACX,WAAQ,KAAK,EAAE;;;AAInB,QAAO;;AAGT,SAAS,YAAkB;AACzB,SAAQ,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6BV;;AAGJ,eAAsB,KAAK,OAAiB,QAAQ,MAAqB;CACvE,MAAM,UAAU,UAAU,KAAK;AAE/B,KAAI,CAAC,QAAQ,UAAU;AACrB,UAAQ,MAAM,kCAAkC;AAChD,aAAW;AACX,UAAQ,KAAK,EAAE;;CAIjB,MAAM,EAAE,qBAAqB,MAAA,QAAA,SAAA,CAAA,WAAA,QAAM,sBAAA,CAAA;CACnC,MAAM,SAAS,MAAM,iBAAiB,UAAU;AAChD,SAAQ,MAAM,OAAO;AAErB,KAAI,QAAQ,SAAS;EACnB,MAAM,EAAE,eAAe,MAAA,QAAA,SAAA,CAAA,WAAA,QAAM,sBAAA,CAAA;AAC7B,aAAW,KAAK;;AAIlB,SAAQ,IAAI,wBAAwB,QAAQ,SAAS,KAAK;AAE1D,KAAI,CADU,MAAM,wBAAA,aAAa,QAAQ,SAAS,EACtC;AACV,UAAQ,MAAM,sBAAsB,QAAQ,SAAS,mBAAmB;AACxE,UAAQ,KAAK,EAAE;;AAEjB,SAAQ,IAAI,qBAAqB;CAGjC,IAAI,QAAQ,QAAQ;AACpB,KAAI,CAAC,OAAO;AACV,UAAQ,IAAI,wBAAwB;EACpC,MAAM,OAAO,MAAM,wBAAA,WAAW,QAAQ,SAAS;AAC/C,UAAQ,KAAK;AACb,UAAQ,IAAI,SAAS,KAAK,KAAK,YAAY;;CAI7C,MAAM,WAAW,cAAc,QAAQ,GAAG;AAC1C,SAAQ,IAAI,aAAa,SAAS,KAAK,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG;CAGlE,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,KAAK,SAAS,IAChD,gBAAA,SAAS,QAAQ,MAAM,QAAQ,KAAM,SAAS,EAAE,KAAK,CAAC,GACtD,gBAAA;AAEJ,SAAQ,IAAI,UAAU,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG;CAG5D,MAAM,EAAE,aAAa,MAAM,eAAA,OAAO,UAAU,OAAO,QAAQ,UAAU,OAAO;EAC1E,SAAS,QAAQ;EACjB,aAAa,QAAQ;EACrB,YAAY,QAAQ;EACrB,CAAC;AAEF,SAAQ,KAAK,SAAS"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport {\n createBunAdapter,\n createDenoAdapter,\n createNpmAdapter,\n createPnpmAdapter,\n createYarnClassicAdapter,\n createYarnModernAdapter,\n} from './adapters';\nimport { allTests } from './tests';\nimport { CliOptions, PackageManagerAdapter } from './types';\nimport { createUser, pingRegistry } from './utils/registry-client';\nimport { runAll } from './runner';\n\nconst debug = buildDebug('verdaccio:e2e-cli');\n\nfunction parsePmSpec(filter: string): { name: string; version?: string; binPath?: string } {\n // --pm yarn-modern@3, --pm yarn-classic@1.22.22, --pm npm=/path/to/bin\n const eqIdx = filter.indexOf('=');\n if (eqIdx !== -1) {\n return { name: filter.slice(0, eqIdx).toLowerCase(), binPath: filter.slice(eqIdx + 1) };\n }\n const atIdx = filter.indexOf('@');\n if (atIdx !== -1) {\n return { name: filter.slice(0, atIdx).toLowerCase(), version: filter.slice(atIdx + 1) };\n }\n return { name: filter.toLowerCase() };\n}\n\nfunction parseAdapters(pmFilters?: string[]): PackageManagerAdapter[] {\n if (!pmFilters || pmFilters.length === 0) {\n return [createNpmAdapter()];\n }\n\n const adapters: PackageManagerAdapter[] = [];\n\n for (const filter of pmFilters) {\n const { name, version, binPath } = parsePmSpec(filter);\n\n if (name === 'npm') {\n adapters.push(createNpmAdapter(binPath, version));\n } else if (name === 'pnpm') {\n adapters.push(createPnpmAdapter(binPath, version));\n } else if (name === 'yarn-classic' || name === 'yarn1') {\n adapters.push(createYarnClassicAdapter(binPath, version));\n } else if (name === 'yarn-modern' || name === 'yarn') {\n adapters.push(createYarnModernAdapter(binPath, version));\n } else if (name === 'bun') {\n adapters.push(createBunAdapter(binPath, version));\n } else if (name === 'deno') {\n adapters.push(createDenoAdapter(binPath, version));\n } else {\n throw new Error(\n `Unknown package manager: \"${name}\". Supported: npm, pnpm, yarn-classic, yarn-modern, bun, deno`\n );\n }\n }\n\n return adapters;\n}\n\nfunction parseArgs(argv: string[]): CliOptions {\n const options: CliOptions = {\n registry: '',\n pm: [],\n test: [],\n concurrency: 1,\n timeout: 50000,\n verbose: false,\n };\n\n for (let i = 2; i < argv.length; i++) {\n const arg = argv[i];\n\n if (arg === '--registry' || arg === '-r') {\n options.registry = argv[++i];\n } else if (arg === '--pm') {\n options.pm!.push(argv[++i]);\n } else if (arg === '--test' || arg === '-t') {\n options.test!.push(argv[++i]);\n } else if (arg === '--concurrency' || arg === '-c') {\n options.concurrency = parseInt(argv[++i], 10);\n } else if (arg === '--timeout') {\n options.timeout = parseInt(argv[++i], 10);\n } else if (arg === '--token') {\n options.token = argv[++i];\n } else if (arg === '--verbose' || arg === '-v') {\n options.verbose = true;\n } else if (arg === '--help' || arg === '-h') {\n printHelp();\n process.exit(0);\n } else if (arg.startsWith('--registry=')) {\n options.registry = arg.split('=')[1];\n } else if (arg.startsWith('--pm=')) {\n options.pm!.push(arg.split('=')[1]);\n } else if (arg.startsWith('--test=')) {\n options.test!.push(arg.split('=')[1]);\n } else if (arg.startsWith('--token=')) {\n options.token = arg.split('=')[1];\n } else if (arg.startsWith('--timeout=')) {\n options.timeout = parseInt(arg.split('=')[1], 10);\n } else {\n console.error(`Unknown argument: ${arg}`);\n printHelp();\n process.exit(1);\n }\n }\n\n return options;\n}\n\nfunction printHelp(): void {\n console.log(`\n @verdaccio/e2e-cli - Run Verdaccio e2e tests against any running registry\n\n Usage:\n verdaccio-e2e --registry <url> [options]\n\n Required:\n -r, --registry <url> Verdaccio registry URL (e.g. http://localhost:4873)\n\n Options:\n --pm <name[@version]> Package manager to test (can be repeated)\n Supported: npm, pnpm, yarn-classic, yarn-modern (or yarn), bun, deno\n Examples: --pm npm@10 --pm pnpm@9\n --pm yarn-modern@4\n --pm yarn-modern@3\n --pm yarn-classic\n --pm bun\n --pm npm --pm pnpm (uses system version)\n Auto-installs the requested yarn version if needed\n Default: npm\n\n -t, --test <name> Filter tests by name (can be repeated)\n Available: publish, install, ci, audit, info, deprecate,\n dist-tags, ping, search, star, unpublish\n Scenarios: scenario:install-multiple-deps\n Default: all supported by the PM\n\n --token <token> Auth token (skips user creation)\n --timeout <ms> Per-test timeout (default: 50000)\n -v, --verbose Enable debug output\n -h, --help Show this help\n `);\n}\n\nexport async function main(argv: string[] = process.argv): Promise<void> {\n const options = parseArgs(argv);\n\n if (!options.registry) {\n console.error('Error: --registry is required\\n');\n printHelp();\n process.exit(1);\n }\n\n // Run from a temp dir to isolate from the host project's packageManager, .yarnrc.yml, etc.\n const { createTempFolder } = await import('./utils/project');\n const runDir = await createTempFolder('e2e-run');\n process.chdir(runDir);\n\n if (options.verbose) {\n const { setVerbose } = await import('./utils/process');\n setVerbose(true);\n }\n\n // Ensure registry is reachable\n console.log(`Checking registry at ${options.registry}...`);\n const alive = await pingRegistry(options.registry);\n if (!alive) {\n console.error(`Error: Registry at ${options.registry} is not reachable`);\n process.exit(1);\n }\n console.log(`Registry is alive.`);\n\n // Get auth token\n let token = options.token;\n if (!token) {\n console.log('Creating test user...');\n const auth = await createUser(options.registry);\n token = auth.token;\n console.log(`User \"${auth.user}\" created.`);\n }\n\n // Build adapter list\n const adapters = parseAdapters(options.pm);\n console.log(`Adapters: ${adapters.map((a) => a.name).join(', ')}`);\n\n // Filter tests\n const tests = options.test && options.test.length > 0\n ? allTests.filter((t) => options.test!.includes(t.name))\n : allTests;\n\n console.log(`Tests: ${tests.map((t) => t.name).join(', ')}`);\n\n // Run\n const { exitCode } = await runAll(adapters, tests, options.registry, token, {\n timeout: options.timeout,\n concurrency: options.concurrency,\n testFilter: options.test,\n });\n\n process.exit(exitCode);\n}\n\n// Re-export for programmatic usage\nexport { allTests } from './tests';\nexport { allScenarios } from './scenarios';\nexport { createBunAdapter, createDenoAdapter, createNpmAdapter, createPnpmAdapter, createYarnClassicAdapter, createYarnModernAdapter } from './adapters';\nexport { runAll, runSuite } from './runner';\nexport type { PackageManagerAdapter, TestDefinition, TestContext, CliOptions } from './types';\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ //#region src/scenarios/index.ts
2
+ var allScenarios = [require("./install-multiple-deps.cjs").installMultipleDepsScenario];
3
+ //#endregion
4
+ exports.allScenarios = allScenarios;
5
+
6
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/scenarios/index.ts"],"sourcesContent":["import { TestDefinition } from '../types';\n\nimport { installMultipleDepsScenario } from './install-multiple-deps';\n\nexport const allScenarios: TestDefinition[] = [installMultipleDepsScenario];\n\nexport { installMultipleDepsScenario };\n"],"mappings":";AAIA,IAAa,eAAiC,wCAAC,4BAA4B"}
@@ -0,0 +1,116 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ let debug = require("debug");
3
+ debug = require_runtime.__toESM(debug);
4
+ let assert = require("assert");
5
+ assert = require_runtime.__toESM(assert);
6
+ //#region src/scenarios/install-multiple-deps.ts
7
+ var debug$1 = (0, debug.default)("verdaccio:e2e-cli:scenario:install-multiple-deps");
8
+ /**
9
+ * Scenario: install-multiple-deps
10
+ *
11
+ * Publishes several packages to the registry (some scoped, some unscoped,
12
+ * some with inter-dependencies), then creates a consumer project that
13
+ * depends on all of them and runs `install`.
14
+ *
15
+ * This exercises the registry under realistic load:
16
+ * - many parallel tarball downloads
17
+ * - metadata resolution for multiple packages
18
+ * - scoped-package authentication
19
+ * - transitive dependency resolution
20
+ */
21
+ var SEED_PACKAGES_COUNT = 5;
22
+ /**
23
+ * Parse `info --json` output across all adapters.
24
+ * Yarn classic wraps the result in NDJSON lines with `{ type: "inspect", data: { ... } }`.
25
+ */
26
+ function parseInfoOutput(stdout, adapterType) {
27
+ if (adapterType === "yarn-classic") {
28
+ const lines = stdout.split("\n").filter(Boolean);
29
+ for (const line of lines) try {
30
+ const obj = JSON.parse(line);
31
+ if (obj.type === "inspect" && obj.data) return obj.data;
32
+ } catch {}
33
+ return JSON.parse(stdout);
34
+ }
35
+ return JSON.parse(stdout);
36
+ }
37
+ async function publishSeedPackage(ctx, pkgName, version, dependencies = {}) {
38
+ debug$1("publishing seed package %s@%s", pkgName, version);
39
+ const { tempFolder } = await ctx.adapter.prepareProject(pkgName, version, ctx.registryUrl, ctx.port, ctx.token, dependencies);
40
+ if (ctx.adapter.type === "yarn-modern") await ctx.adapter.exec({ cwd: tempFolder }, "install");
41
+ await ctx.adapter.exec({ cwd: tempFolder }, "publish", ...ctx.adapter.registryArg(ctx.registryUrl));
42
+ debug$1("published %s@%s", pkgName, version);
43
+ }
44
+ async function testInstallMultipleDeps(ctx) {
45
+ const id = ctx.runId;
46
+ let projectCwd = "";
47
+ await ctx.subTest("publish seed packages", async () => {
48
+ for (let i = 1; i <= SEED_PACKAGES_COUNT; i++) await publishSeedPackage(ctx, `@verdaccio/seed-${id}-${i}`, "1.0.0");
49
+ const sharedPkg = `@verdaccio/seed-shared-${id}`;
50
+ await publishSeedPackage(ctx, sharedPkg, "1.0.0");
51
+ await publishSeedPackage(ctx, `@verdaccio/seed-mid-${id}`, "1.0.0", {
52
+ [`@verdaccio/seed-${id}-1`]: "1.0.0",
53
+ [`@verdaccio/seed-${id}-2`]: "1.0.0",
54
+ [sharedPkg]: "1.0.0"
55
+ });
56
+ debug$1("all seed packages published");
57
+ });
58
+ await ctx.subTest("install all dependencies in consumer project", async () => {
59
+ const consumerDeps = {};
60
+ for (let i = 1; i <= SEED_PACKAGES_COUNT; i++) consumerDeps[`@verdaccio/seed-${id}-${i}`] = "1.0.0";
61
+ consumerDeps[`@verdaccio/seed-mid-${id}`] = "1.0.0";
62
+ consumerDeps[`@verdaccio/seed-shared-${id}`] = "1.0.0";
63
+ const consumerName = `@verdaccio/consumer-${id}`;
64
+ const { tempFolder } = await ctx.adapter.prepareProject(consumerName, "1.0.0", ctx.registryUrl, ctx.port, ctx.token, consumerDeps);
65
+ projectCwd = tempFolder;
66
+ debug$1("installing %d dependencies in consumer project", Object.keys(consumerDeps).length);
67
+ const args = ["install", ...ctx.adapter.registryArg(ctx.registryUrl)];
68
+ await ctx.adapter.exec({ cwd: tempFolder }, ...args);
69
+ debug$1("install completed for consumer project");
70
+ });
71
+ await ctx.subTest("verify installed packages", async () => {
72
+ for (let i = 1; i <= SEED_PACKAGES_COUNT; i++) {
73
+ const name = `@verdaccio/seed-${id}-${i}`;
74
+ const info = parseInfoOutput((await ctx.adapter.exec({ cwd: projectCwd }, "info", name, "--json", ...ctx.adapter.registryArg(ctx.registryUrl))).stdout, ctx.adapter.type);
75
+ assert.default.strictEqual(info.name, name, `Expected package name "${name}"`);
76
+ assert.default.strictEqual(info.version, "1.0.0", `Expected version 1.0.0 for ${name}`);
77
+ }
78
+ const midName = `@verdaccio/seed-mid-${id}`;
79
+ const midInfo = parseInfoOutput((await ctx.adapter.exec({ cwd: projectCwd }, "info", midName, "--json", ...ctx.adapter.registryArg(ctx.registryUrl))).stdout, ctx.adapter.type);
80
+ assert.default.strictEqual(midInfo.name, midName);
81
+ const deps = midInfo.dependencies || {};
82
+ assert.default.strictEqual(deps[`@verdaccio/seed-${id}-1`], "1.0.0", "Intermediate should depend on seed-1");
83
+ assert.default.strictEqual(deps[`@verdaccio/seed-${id}-2`], "1.0.0", "Intermediate should depend on seed-2");
84
+ assert.default.strictEqual(deps[`@verdaccio/seed-shared-${id}`], "1.0.0", "Intermediate should depend on shared");
85
+ debug$1("all packages verified");
86
+ });
87
+ await ctx.subTest("update and re-install", async () => {
88
+ const leafName = `@verdaccio/seed-${id}-1`;
89
+ await publishSeedPackage(ctx, leafName, "2.0.0");
90
+ const sharedName = `@verdaccio/seed-shared-${id}`;
91
+ await publishSeedPackage(ctx, sharedName, "2.0.0");
92
+ const consumerDeps = {
93
+ [leafName]: "^1.0.0",
94
+ [sharedName]: "^1.0.0"
95
+ };
96
+ const consumerName = `@verdaccio/consumer-update-${id}`;
97
+ const { tempFolder } = await ctx.adapter.prepareProject(consumerName, "1.0.0", ctx.registryUrl, ctx.port, ctx.token, consumerDeps);
98
+ await ctx.adapter.exec({ cwd: tempFolder }, "install", ...ctx.adapter.registryArg(ctx.registryUrl));
99
+ const leafInfo = parseInfoOutput((await ctx.adapter.exec({ cwd: tempFolder }, "info", leafName, "--json", ...ctx.adapter.registryArg(ctx.registryUrl))).stdout, ctx.adapter.type);
100
+ assert.default.strictEqual(leafInfo["dist-tags"]?.latest ?? leafInfo.version, "2.0.0", `Expected latest version of ${leafName} to be 2.0.0`);
101
+ debug$1("update and re-install verified");
102
+ });
103
+ }
104
+ var installMultipleDepsScenario = {
105
+ name: "scenario:install-multiple-deps",
106
+ requires: [
107
+ "publish",
108
+ "install",
109
+ "info"
110
+ ],
111
+ run: testInstallMultipleDeps
112
+ };
113
+ //#endregion
114
+ exports.installMultipleDepsScenario = installMultipleDepsScenario;
115
+
116
+ //# sourceMappingURL=install-multiple-deps.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-multiple-deps.cjs","names":[],"sources":["../../../src/scenarios/install-multiple-deps.ts"],"sourcesContent":["import assert from 'assert';\nimport buildDebug from 'debug';\n\nimport { TestContext, TestDefinition } from '../types';\n\nconst debug = buildDebug('verdaccio:e2e-cli:scenario:install-multiple-deps');\n\n/**\n * Scenario: install-multiple-deps\n *\n * Publishes several packages to the registry (some scoped, some unscoped,\n * some with inter-dependencies), then creates a consumer project that\n * depends on all of them and runs `install`.\n *\n * This exercises the registry under realistic load:\n * - many parallel tarball downloads\n * - metadata resolution for multiple packages\n * - scoped-package authentication\n * - transitive dependency resolution\n */\n\nconst SEED_PACKAGES_COUNT = 5;\n\n/**\n * Parse `info --json` output across all adapters.\n * Yarn classic wraps the result in NDJSON lines with `{ type: \"inspect\", data: { ... } }`.\n */\nfunction parseInfoOutput(stdout: string, adapterType: string): any {\n if (adapterType === 'yarn-classic') {\n // Yarn classic outputs NDJSON — find the \"inspect\" line that holds package data\n const lines = stdout.split('\\n').filter(Boolean);\n for (const line of lines) {\n try {\n const obj = JSON.parse(line);\n if (obj.type === 'inspect' && obj.data) {\n return obj.data;\n }\n } catch {\n // skip non-JSON lines\n }\n }\n // Fallback: try parsing the whole output\n return JSON.parse(stdout);\n }\n return JSON.parse(stdout);\n}\n\nasync function publishSeedPackage(\n ctx: TestContext,\n pkgName: string,\n version: string,\n dependencies: Record<string, string> = {}\n): Promise<void> {\n debug('publishing seed package %s@%s', pkgName, version);\n const { tempFolder } = await ctx.adapter.prepareProject(\n pkgName,\n version,\n ctx.registryUrl,\n ctx.port,\n ctx.token,\n dependencies\n );\n\n if (ctx.adapter.type === 'yarn-modern') {\n await ctx.adapter.exec({ cwd: tempFolder }, 'install');\n }\n\n await ctx.adapter.exec(\n { cwd: tempFolder },\n 'publish',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n debug('published %s@%s', pkgName, version);\n}\n\nasync function testInstallMultipleDeps(ctx: TestContext): Promise<void> {\n const id = ctx.runId;\n\n // Shared project folder used as cwd for info commands across subtests.\n // Yarn modern requires a project context (package.json + .yarnrc.yml) for `yarn npm info`.\n let projectCwd = '';\n\n // --- Phase 1: Publish a tree of seed packages ---\n await ctx.subTest('publish seed packages', async () => {\n // Leaf packages (no dependencies of their own)\n for (let i = 1; i <= SEED_PACKAGES_COUNT; i++) {\n const name = `@verdaccio/seed-${id}-${i}`;\n await publishSeedPackage(ctx, name, '1.0.0');\n }\n\n // A \"shared\" package that multiple consumers will pull in\n const sharedPkg = `@verdaccio/seed-shared-${id}`;\n await publishSeedPackage(ctx, sharedPkg, '1.0.0');\n\n // An intermediate package that depends on some leaf packages + shared\n const intermediatePkg = `@verdaccio/seed-mid-${id}`;\n await publishSeedPackage(ctx, intermediatePkg, '1.0.0', {\n [`@verdaccio/seed-${id}-1`]: '1.0.0',\n [`@verdaccio/seed-${id}-2`]: '1.0.0',\n [sharedPkg]: '1.0.0',\n });\n\n debug('all seed packages published');\n });\n\n // --- Phase 2: Create a consumer project that depends on everything ---\n await ctx.subTest('install all dependencies in consumer project', async () => {\n const consumerDeps: Record<string, string> = {};\n\n // Direct deps on all leaf packages\n for (let i = 1; i <= SEED_PACKAGES_COUNT; i++) {\n consumerDeps[`@verdaccio/seed-${id}-${i}`] = '1.0.0';\n }\n\n // Also depend on the intermediate (pulls in transitive deps)\n consumerDeps[`@verdaccio/seed-mid-${id}`] = '1.0.0';\n\n // And the shared package directly (already a transitive dep of mid)\n consumerDeps[`@verdaccio/seed-shared-${id}`] = '1.0.0';\n\n const consumerName = `@verdaccio/consumer-${id}`;\n const { tempFolder } = await ctx.adapter.prepareProject(\n consumerName,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token,\n consumerDeps\n );\n\n projectCwd = tempFolder;\n\n debug('installing %d dependencies in consumer project', Object.keys(consumerDeps).length);\n\n const args = ['install', ...ctx.adapter.registryArg(ctx.registryUrl)];\n await ctx.adapter.exec({ cwd: tempFolder }, ...args);\n\n debug('install completed for consumer project');\n });\n\n // --- Phase 3: Verify all packages resolved correctly ---\n await ctx.subTest('verify installed packages', async () => {\n // Check that each seed package is retrievable via `info`\n for (let i = 1; i <= SEED_PACKAGES_COUNT; i++) {\n const name = `@verdaccio/seed-${id}-${i}`;\n const resp = await ctx.adapter.exec(\n { cwd: projectCwd },\n 'info',\n name,\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n const info = parseInfoOutput(resp.stdout, ctx.adapter.type);\n assert.strictEqual(info.name, name, `Expected package name \"${name}\"`);\n assert.strictEqual(info.version, '1.0.0', `Expected version 1.0.0 for ${name}`);\n }\n\n // Verify intermediate package has correct dependencies in registry metadata\n const midName = `@verdaccio/seed-mid-${id}`;\n const resp = await ctx.adapter.exec(\n { cwd: projectCwd },\n 'info',\n midName,\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n const midInfo = parseInfoOutput(resp.stdout, ctx.adapter.type);\n assert.strictEqual(midInfo.name, midName);\n\n const deps = midInfo.dependencies || {};\n assert.strictEqual(\n deps[`@verdaccio/seed-${id}-1`],\n '1.0.0',\n 'Intermediate should depend on seed-1'\n );\n assert.strictEqual(\n deps[`@verdaccio/seed-${id}-2`],\n '1.0.0',\n 'Intermediate should depend on seed-2'\n );\n assert.strictEqual(\n deps[`@verdaccio/seed-shared-${id}`],\n '1.0.0',\n 'Intermediate should depend on shared'\n );\n\n debug('all packages verified');\n });\n\n // --- Phase 4: Publish updated versions and re-install ---\n await ctx.subTest('update and re-install', async () => {\n // Publish v2 of a leaf and the shared package\n const leafName = `@verdaccio/seed-${id}-1`;\n await publishSeedPackage(ctx, leafName, '2.0.0');\n\n const sharedName = `@verdaccio/seed-shared-${id}`;\n await publishSeedPackage(ctx, sharedName, '2.0.0');\n\n // Create a new consumer that uses ^ ranges — should pick up 2.0.0\n const consumerDeps: Record<string, string> = {\n [leafName]: '^1.0.0',\n [sharedName]: '^1.0.0',\n };\n\n const consumerName = `@verdaccio/consumer-update-${id}`;\n const { tempFolder } = await ctx.adapter.prepareProject(\n consumerName,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token,\n consumerDeps\n );\n\n await ctx.adapter.exec({ cwd: tempFolder }, 'install', ...ctx.adapter.registryArg(ctx.registryUrl));\n\n // Verify that the registry now serves both versions\n const leafResp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'info',\n leafName,\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n const leafInfo = parseInfoOutput(leafResp.stdout, ctx.adapter.type);\n\n // dist-tags.latest should be 2.0.0\n assert.strictEqual(\n leafInfo['dist-tags']?.latest ?? leafInfo.version,\n '2.0.0',\n `Expected latest version of ${leafName} to be 2.0.0`\n );\n\n debug('update and re-install verified');\n });\n}\n\nexport const installMultipleDepsScenario: TestDefinition = {\n name: 'scenario:install-multiple-deps',\n requires: ['publish', 'install', 'info'],\n run: testInstallMultipleDeps,\n};\n"],"mappings":"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"}
@@ -1,19 +1,39 @@
1
1
  const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ let debug = require("debug");
3
+ debug = require_runtime.__toESM(debug);
2
4
  let assert = require("assert");
3
5
  assert = require_runtime.__toESM(assert);
4
6
  //#region src/tests/audit.ts
7
+ var debug$1 = (0, debug.default)("verdaccio:e2e-cli:test:audit");
5
8
  async function testAudit(ctx) {
9
+ if (ctx.adapter.type !== "npm" && ctx.adapter.type !== "bun") {
10
+ debug$1("skipping audit test for %s (npm/bun only)", ctx.adapter.type);
11
+ return;
12
+ }
6
13
  const packages = [`verdaccio-audit-${ctx.runId}`, `@verdaccio/audit-${ctx.runId}`];
7
14
  for (const pkgName of packages) {
8
15
  const { tempFolder } = await ctx.adapter.prepareProject(pkgName, "1.0.0", ctx.registryUrl, ctx.port, ctx.token, { jquery: "3.6.1" });
9
16
  await ctx.adapter.exec({ cwd: tempFolder }, "install", ...ctx.adapter.registryArg(ctx.registryUrl));
17
+ try {
18
+ if ((await fetch(`${ctx.registryUrl}/-/npm/v1/security/audits/quick`, {
19
+ method: "POST",
20
+ headers: { "Content-Type": "application/json" },
21
+ body: "{}"
22
+ })).status === 404) {
23
+ debug$1("audit endpoint not supported by this registry (404), skipping");
24
+ return;
25
+ }
26
+ } catch {
27
+ debug$1("audit endpoint probe failed, skipping");
28
+ return;
29
+ }
10
30
  const resp = await ctx.adapter.exec({ cwd: tempFolder }, "audit", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
11
- const parsedBody = JSON.parse(resp.stdout);
12
- if (ctx.adapter.type === "npm") {
13
- assert.default.ok(parsedBody.metadata !== void 0, "Expected \"metadata\" in audit response");
31
+ if (ctx.adapter.type === "bun") assert.default.ok(resp.stdout.length > 0 || resp.stderr.length > 0, "Expected audit output");
32
+ else {
33
+ const parsedBody = JSON.parse(resp.stdout);
14
34
  assert.default.ok(parsedBody.auditReportVersion !== void 0, "Expected \"auditReportVersion\" in audit response");
15
35
  assert.default.ok(parsedBody.vulnerabilities !== void 0, "Expected \"vulnerabilities\" in audit response");
16
- } else assert.default.ok(parsedBody !== void 0, "Expected audit JSON response");
36
+ }
17
37
  }
18
38
  }
19
39
  var auditTest = {
@@ -1 +1 @@
1
- {"version":3,"file":"audit.cjs","names":[],"sources":["../../../src/tests/audit.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testAudit(ctx: TestContext): Promise<void> {\n const packages = [`verdaccio-audit-${ctx.runId}`, `@verdaccio/audit-${ctx.runId}`];\n\n for (const pkgName of packages) {\n const { tempFolder } = await ctx.adapter.prepareProject(\n pkgName,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token,\n { jquery: '3.6.1' }\n );\n\n // install is required to create package lock file\n await ctx.adapter.exec(\n { cwd: tempFolder },\n 'install',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n const resp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'audit',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n const parsedBody = JSON.parse(resp.stdout);\n\n if (ctx.adapter.type === 'npm') {\n assert.ok(parsedBody.metadata !== undefined, 'Expected \"metadata\" in audit response');\n assert.ok(\n parsedBody.auditReportVersion !== undefined,\n 'Expected \"auditReportVersion\" in audit response'\n );\n assert.ok(\n parsedBody.vulnerabilities !== undefined,\n 'Expected \"vulnerabilities\" in audit response'\n );\n } else {\n // pnpm audit --json returns advisories-based format\n assert.ok(parsedBody !== undefined, 'Expected audit JSON response');\n }\n }\n}\n\nexport const auditTest: TestDefinition = {\n name: 'audit',\n requires: ['audit'],\n run: testAudit,\n};\n"],"mappings":";;;;AAIA,eAAe,UAAU,KAAiC;CACxD,MAAM,WAAW,CAAC,mBAAmB,IAAI,SAAS,oBAAoB,IAAI,QAAQ;AAElF,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,SACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,OACJ,EAAE,QAAQ,SAAS,CACpB;AAGD,QAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,YAAY,EACnB,WACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;EAED,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,YAAY,EACnB,SACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;EAED,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;AAE1C,MAAI,IAAI,QAAQ,SAAS,OAAO;AAC9B,UAAA,QAAO,GAAG,WAAW,aAAa,KAAA,GAAW,0CAAwC;AACrF,UAAA,QAAO,GACL,WAAW,uBAAuB,KAAA,GAClC,oDACD;AACD,UAAA,QAAO,GACL,WAAW,oBAAoB,KAAA,GAC/B,iDACD;QAGD,QAAA,QAAO,GAAG,eAAe,KAAA,GAAW,+BAA+B;;;AAKzE,IAAa,YAA4B;CACvC,MAAM;CACN,UAAU,CAAC,QAAQ;CACnB,KAAK;CACN"}
1
+ {"version":3,"file":"audit.cjs","names":[],"sources":["../../../src/tests/audit.ts"],"sourcesContent":["import assert from 'assert';\nimport buildDebug from 'debug';\n\nimport { TestContext, TestDefinition } from '../types';\n\nconst debug = buildDebug('verdaccio:e2e-cli:test:audit');\n\nasync function testAudit(ctx: TestContext): Promise<void> {\n // Audit is only reliable with npm and bun — pnpm/yarn audit output varies too much\n if (ctx.adapter.type !== 'npm' && ctx.adapter.type !== 'bun') {\n debug('skipping audit test for %s (npm/bun only)', ctx.adapter.type);\n return;\n }\n\n const packages = [`verdaccio-audit-${ctx.runId}`, `@verdaccio/audit-${ctx.runId}`];\n\n for (const pkgName of packages) {\n const { tempFolder } = await ctx.adapter.prepareProject(\n pkgName,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token,\n { jquery: '3.6.1' }\n );\n\n // install is required to create package lock file\n await ctx.adapter.exec(\n { cwd: tempFolder },\n 'install',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n // npm audit exits with code 1 both when vulnerabilities are found AND when\n // the endpoint is unavailable. We need to distinguish between the two.\n // Probe the audit endpoint first to avoid false failures on registries\n // that don't support it (e.g. verdaccio next-7+).\n try {\n const probe = await fetch(`${ctx.registryUrl}/-/npm/v1/security/audits/quick`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: '{}',\n });\n if (probe.status === 404) {\n debug('audit endpoint not supported by this registry (404), skipping');\n return;\n }\n } catch {\n debug('audit endpoint probe failed, skipping');\n return;\n }\n\n const resp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'audit',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n if (ctx.adapter.type === 'bun') {\n // bun audit output may differ — exit code 0 is sufficient for basic validation\n assert.ok(resp.stdout.length > 0 || resp.stderr.length > 0, 'Expected audit output');\n } else {\n const parsedBody = JSON.parse(resp.stdout);\n assert.ok(parsedBody.auditReportVersion !== undefined, 'Expected \"auditReportVersion\" in audit response');\n assert.ok(parsedBody.vulnerabilities !== undefined, 'Expected \"vulnerabilities\" in audit response');\n }\n }\n}\n\nexport const auditTest: TestDefinition = {\n name: 'audit',\n requires: ['audit'],\n run: testAudit,\n};\n"],"mappings":";;;;;;AAKA,IAAM,WAAA,GAAA,MAAA,SAAmB,+BAA+B;AAExD,eAAe,UAAU,KAAiC;AAExD,KAAI,IAAI,QAAQ,SAAS,SAAS,IAAI,QAAQ,SAAS,OAAO;AAC5D,UAAM,6CAA6C,IAAI,QAAQ,KAAK;AACpE;;CAGF,MAAM,WAAW,CAAC,mBAAmB,IAAI,SAAS,oBAAoB,IAAI,QAAQ;AAElF,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,SACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,OACJ,EAAE,QAAQ,SAAS,CACpB;AAGD,QAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,YAAY,EACnB,WACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AAMD,MAAI;AAMF,QALc,MAAM,MAAM,GAAG,IAAI,YAAY,kCAAkC;IAC7E,QAAQ;IACR,SAAS,EAAE,gBAAgB,oBAAoB;IAC/C,MAAM;IACP,CAAC,EACQ,WAAW,KAAK;AACxB,YAAM,gEAAgE;AACtE;;UAEI;AACN,WAAM,wCAAwC;AAC9C;;EAGF,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,YAAY,EACnB,SACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AAED,MAAI,IAAI,QAAQ,SAAS,MAEvB,QAAA,QAAO,GAAG,KAAK,OAAO,SAAS,KAAK,KAAK,OAAO,SAAS,GAAG,wBAAwB;OAC/E;GACL,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;AAC1C,UAAA,QAAO,GAAG,WAAW,uBAAuB,KAAA,GAAW,oDAAkD;AACzG,UAAA,QAAO,GAAG,WAAW,oBAAoB,KAAA,GAAW,iDAA+C;;;;AAKzG,IAAa,YAA4B;CACvC,MAAM;CACN,UAAU,CAAC,QAAQ;CACnB,KAAK;CACN"}
@@ -0,0 +1,83 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ let debug = require("debug");
3
+ debug = require_runtime.__toESM(debug);
4
+ let path = require("path");
5
+ let fs_promises = require("fs/promises");
6
+ let assert = require("assert");
7
+ assert = require_runtime.__toESM(assert);
8
+ //#region src/tests/ci.ts
9
+ var debug$1 = (0, debug.default)("verdaccio:e2e-cli:test:ci");
10
+ /**
11
+ * Test: ci
12
+ *
13
+ * Verifies that lockfile-based install works correctly.
14
+ * Unlike `install`, CI commands skip metadata fetches and resolve
15
+ * tarballs directly from the URLs stored in the lockfile.
16
+ *
17
+ * Flow:
18
+ * 1. Prepare a project with dependencies
19
+ * 2. Run `install` to generate the lockfile
20
+ * 3. Remove node_modules
21
+ * 4. Run the CI-equivalent command (npm ci / pnpm install --frozen-lockfile / yarn --frozen-lockfile / yarn --immutable)
22
+ * 5. Verify it completes successfully
23
+ */
24
+ function getCiArgs(ctx) {
25
+ switch (ctx.adapter.type) {
26
+ case "npm": return ["ci", ...ctx.adapter.registryArg(ctx.registryUrl)];
27
+ case "pnpm": return [
28
+ "install",
29
+ "--frozen-lockfile",
30
+ ...ctx.adapter.registryArg(ctx.registryUrl)
31
+ ];
32
+ case "yarn-classic": return [
33
+ "install",
34
+ "--frozen-lockfile",
35
+ ...ctx.adapter.registryArg(ctx.registryUrl)
36
+ ];
37
+ case "yarn-modern": return ["install", "--immutable"];
38
+ case "bun": return [
39
+ "install",
40
+ "--frozen-lockfile",
41
+ ...ctx.adapter.registryArg(ctx.registryUrl)
42
+ ];
43
+ default: return ["ci", ...ctx.adapter.registryArg(ctx.registryUrl)];
44
+ }
45
+ }
46
+ async function testCi(ctx) {
47
+ if (ctx.adapter.type === "deno") {
48
+ debug$1("skipping ci test for deno (no ci command)");
49
+ return;
50
+ }
51
+ const { tempFolder } = await ctx.adapter.prepareProject(`ci-test-${ctx.runId}`, "1.0.0", ctx.registryUrl, ctx.port, ctx.token, { "is-odd": "1.0.0" });
52
+ debug$1("running initial install to generate lockfile in %s", tempFolder);
53
+ await ctx.adapter.exec({ cwd: tempFolder }, "install", ...ctx.adapter.registryArg(ctx.registryUrl));
54
+ debug$1("lockfile generated, removing node_modules");
55
+ await (0, fs_promises.rm)((0, path.join)(tempFolder, "node_modules"), {
56
+ recursive: true,
57
+ force: true
58
+ });
59
+ await (0, fs_promises.rm)((0, path.join)(tempFolder, ".pnpm-store"), {
60
+ recursive: true,
61
+ force: true
62
+ });
63
+ debug$1("node_modules removed, running ci command");
64
+ const ciArgs = getCiArgs(ctx);
65
+ debug$1("ci args: %o", ciArgs);
66
+ const resp = await ctx.adapter.exec({ cwd: tempFolder }, ...ciArgs);
67
+ if (ctx.adapter.type === "npm") {
68
+ debug$1("npm ci output: %s", resp.stdout + resp.stderr);
69
+ assert.default.ok(true, "npm ci completed successfully");
70
+ } else {
71
+ debug$1("ci completed successfully for %s", ctx.adapter.type);
72
+ assert.default.ok(true, `CI install completed successfully for ${ctx.adapter.type}`);
73
+ }
74
+ }
75
+ var ciTest = {
76
+ name: "ci",
77
+ requires: ["install"],
78
+ run: testCi
79
+ };
80
+ //#endregion
81
+ exports.ciTest = ciTest;
82
+
83
+ //# sourceMappingURL=ci.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci.cjs","names":[],"sources":["../../../src/tests/ci.ts"],"sourcesContent":["import assert from 'assert';\nimport buildDebug from 'debug';\nimport { rm } from 'fs/promises';\nimport { join } from 'path';\n\nimport { TestContext, TestDefinition } from '../types';\n\nconst debug = buildDebug('verdaccio:e2e-cli:test:ci');\n\n/**\n * Test: ci\n *\n * Verifies that lockfile-based install works correctly.\n * Unlike `install`, CI commands skip metadata fetches and resolve\n * tarballs directly from the URLs stored in the lockfile.\n *\n * Flow:\n * 1. Prepare a project with dependencies\n * 2. Run `install` to generate the lockfile\n * 3. Remove node_modules\n * 4. Run the CI-equivalent command (npm ci / pnpm install --frozen-lockfile / yarn --frozen-lockfile / yarn --immutable)\n * 5. Verify it completes successfully\n */\n\nfunction getCiArgs(ctx: TestContext): string[] {\n switch (ctx.adapter.type) {\n case 'npm':\n // `npm ci` — separate command, reads package-lock.json\n return ['ci', ...ctx.adapter.registryArg(ctx.registryUrl)];\n case 'pnpm':\n // `pnpm install --frozen-lockfile` — same command, strict mode\n return ['install', '--frozen-lockfile', ...ctx.adapter.registryArg(ctx.registryUrl)];\n case 'yarn-classic':\n // `yarn install --frozen-lockfile`\n return ['install', '--frozen-lockfile', ...ctx.adapter.registryArg(ctx.registryUrl)];\n case 'yarn-modern':\n // `yarn install --immutable`\n return ['install', '--immutable'];\n case 'bun':\n // `bun install --frozen-lockfile`\n return ['install', '--frozen-lockfile', ...ctx.adapter.registryArg(ctx.registryUrl)];\n default:\n return ['ci', ...ctx.adapter.registryArg(ctx.registryUrl)];\n }\n}\n\nasync function testCi(ctx: TestContext): Promise<void> {\n // deno doesn't have a CI/frozen-lockfile equivalent\n if (ctx.adapter.type === 'deno') {\n debug('skipping ci test for deno (no ci command)');\n return;\n }\n\n const { tempFolder } = await ctx.adapter.prepareProject(\n `ci-test-${ctx.runId}`,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token,\n { 'is-odd': '1.0.0' }\n );\n\n debug('running initial install to generate lockfile in %s', tempFolder);\n\n // Step 1: Run install to generate the lockfile\n await ctx.adapter.exec(\n { cwd: tempFolder },\n 'install',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n debug('lockfile generated, removing node_modules');\n\n // Step 2: Remove node_modules to force a clean install from lockfile\n const nodeModulesPath = join(tempFolder, 'node_modules');\n await rm(nodeModulesPath, { recursive: true, force: true });\n\n // For pnpm, also clean the virtual store\n const pnpmStorePath = join(tempFolder, '.pnpm-store');\n await rm(pnpmStorePath, { recursive: true, force: true });\n\n debug('node_modules removed, running ci command');\n\n // Step 3: Run CI-equivalent command (tarball-only, no metadata fetches)\n const ciArgs = getCiArgs(ctx);\n debug('ci args: %o', ciArgs);\n const resp = await ctx.adapter.exec({ cwd: tempFolder }, ...ciArgs);\n\n // Step 4: Verify success\n if (ctx.adapter.type === 'npm') {\n // npm ci with --json is not reliable, just check exit code 0\n // and verify output mentions added packages\n const output = resp.stdout + resp.stderr;\n debug('npm ci output: %s', output);\n assert.ok(true, 'npm ci completed successfully');\n } else {\n debug('ci completed successfully for %s', ctx.adapter.type);\n assert.ok(true, `CI install completed successfully for ${ctx.adapter.type}`);\n }\n}\n\nexport const ciTest: TestDefinition = {\n name: 'ci',\n requires: ['install'],\n run: testCi,\n};\n"],"mappings":";;;;;;;;AAOA,IAAM,WAAA,GAAA,MAAA,SAAmB,4BAA4B;;;;;;;;;;;;;;;AAiBrD,SAAS,UAAU,KAA4B;AAC7C,SAAQ,IAAI,QAAQ,MAApB;EACE,KAAK,MAEH,QAAO,CAAC,MAAM,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAAC;EAC5D,KAAK,OAEH,QAAO;GAAC;GAAW;GAAqB,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY;GAAC;EACtF,KAAK,eAEH,QAAO;GAAC;GAAW;GAAqB,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY;GAAC;EACtF,KAAK,cAEH,QAAO,CAAC,WAAW,cAAc;EACnC,KAAK,MAEH,QAAO;GAAC;GAAW;GAAqB,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY;GAAC;EACtF,QACE,QAAO,CAAC,MAAM,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAAC;;;AAIhE,eAAe,OAAO,KAAiC;AAErD,KAAI,IAAI,QAAQ,SAAS,QAAQ;AAC/B,UAAM,4CAA4C;AAClD;;CAGF,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,WAAW,IAAI,SACf,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,OACJ,EAAE,UAAU,SAAS,CACtB;AAED,SAAM,sDAAsD,WAAW;AAGvE,OAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,YAAY,EACnB,WACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AAED,SAAM,4CAA4C;AAIlD,QAAA,GAAA,YAAA,KAAA,GAAA,KAAA,MAD6B,YAAY,eAAe,EAC9B;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;AAI3D,QAAA,GAAA,YAAA,KAAA,GAAA,KAAA,MAD2B,YAAY,cAAc,EAC7B;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;AAEzD,SAAM,2CAA2C;CAGjD,MAAM,SAAS,UAAU,IAAI;AAC7B,SAAM,eAAe,OAAO;CAC5B,MAAM,OAAO,MAAM,IAAI,QAAQ,KAAK,EAAE,KAAK,YAAY,EAAE,GAAG,OAAO;AAGnE,KAAI,IAAI,QAAQ,SAAS,OAAO;AAI9B,UAAM,qBADS,KAAK,SAAS,KAAK,OACA;AAClC,SAAA,QAAO,GAAG,MAAM,gCAAgC;QAC3C;AACL,UAAM,oCAAoC,IAAI,QAAQ,KAAK;AAC3D,SAAA,QAAO,GAAG,MAAM,yCAAyC,IAAI,QAAQ,OAAO;;;AAIhF,IAAa,SAAyB;CACpC,MAAM;CACN,UAAU,CAAC,UAAU;CACrB,KAAK;CACN"}
@@ -1,4 +1,7 @@
1
+ require("../scenarios/install-multiple-deps.cjs");
2
+ const require_index = require("../scenarios/index.cjs");
1
3
  const require_audit = require("./audit.cjs");
4
+ const require_ci = require("./ci.cjs");
2
5
  const require_deprecate = require("./deprecate.cjs");
3
6
  const require_dist_tags = require("./dist-tags.cjs");
4
7
  const require_info = require("./info.cjs");
@@ -13,6 +16,7 @@ const require_unpublish = require("./unpublish.cjs");
13
16
  var allTests = [
14
17
  require_publish.publishTest,
15
18
  require_install.installTest,
19
+ require_ci.ciTest,
16
20
  require_audit.auditTest,
17
21
  require_info.infoTest,
18
22
  require_deprecate.deprecateTest,
@@ -21,7 +25,8 @@ var allTests = [
21
25
  require_ping.pingTest,
22
26
  require_search.searchTest,
23
27
  require_star.starTest,
24
- require_unpublish.unpublishTest
28
+ require_unpublish.unpublishTest,
29
+ ...require_index.allScenarios
25
30
  ];
26
31
  //#endregion
27
32
  exports.allTests = allTests;