@verdaccio/e2e-cli 2.7.0 → 2.9.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 (64) 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/adapters/yarn-classic.cjs.map +1 -1
  10. package/build/cjs/adapters/yarn-modern.cjs +24 -4
  11. package/build/cjs/adapters/yarn-modern.cjs.map +1 -1
  12. package/build/cjs/index.cjs +10 -3
  13. package/build/cjs/index.cjs.map +1 -1
  14. package/build/cjs/reporter.cjs.map +1 -1
  15. package/build/cjs/runner.cjs.map +1 -1
  16. package/build/cjs/scenarios/index.cjs.map +1 -1
  17. package/build/cjs/scenarios/install-multiple-deps.cjs.map +1 -1
  18. package/build/cjs/tests/audit.cjs +8 -5
  19. package/build/cjs/tests/audit.cjs.map +1 -1
  20. package/build/cjs/tests/ci.cjs +9 -0
  21. package/build/cjs/tests/ci.cjs.map +1 -1
  22. package/build/cjs/tests/index.cjs.map +1 -1
  23. package/build/cjs/tests/info.cjs +3 -0
  24. package/build/cjs/tests/info.cjs.map +1 -1
  25. package/build/cjs/tests/login.cjs.map +1 -1
  26. package/build/cjs/tests/publish.cjs +1 -0
  27. package/build/cjs/tests/publish.cjs.map +1 -1
  28. package/build/cjs/tests/star.cjs.map +1 -1
  29. package/build/cjs/utils/process.cjs +1 -1
  30. package/build/cjs/utils/process.cjs.map +1 -1
  31. package/build/cjs/utils/registry-client.cjs.map +1 -1
  32. package/build/esm/adapters/bun.js +61 -0
  33. package/build/esm/adapters/bun.js.map +1 -0
  34. package/build/esm/adapters/deno.js +56 -0
  35. package/build/esm/adapters/deno.js.map +1 -0
  36. package/build/esm/adapters/index.js +2 -0
  37. package/build/esm/adapters/yarn-classic.js.map +1 -1
  38. package/build/esm/adapters/yarn-modern.js +24 -4
  39. package/build/esm/adapters/yarn-modern.js.map +1 -1
  40. package/build/esm/index.js +9 -4
  41. package/build/esm/index.js.map +1 -1
  42. package/build/esm/reporter.js.map +1 -1
  43. package/build/esm/runner.js.map +1 -1
  44. package/build/esm/scenarios/index.js.map +1 -1
  45. package/build/esm/scenarios/install-multiple-deps.js.map +1 -1
  46. package/build/esm/tests/audit.js +8 -5
  47. package/build/esm/tests/audit.js.map +1 -1
  48. package/build/esm/tests/ci.js +9 -0
  49. package/build/esm/tests/ci.js.map +1 -1
  50. package/build/esm/tests/index.js.map +1 -1
  51. package/build/esm/tests/info.js +3 -0
  52. package/build/esm/tests/info.js.map +1 -1
  53. package/build/esm/tests/login.js.map +1 -1
  54. package/build/esm/tests/publish.js +1 -0
  55. package/build/esm/tests/publish.js.map +1 -1
  56. package/build/esm/tests/star.js.map +1 -1
  57. package/build/esm/utils/process.js +1 -1
  58. package/build/esm/utils/process.js.map +1 -1
  59. package/build/esm/utils/registry-client.js.map +1 -1
  60. package/build/index.d.ts +1 -1
  61. package/build/tests/index.d.ts +1 -1
  62. package/build/types.d.ts +2 -3
  63. package/build/utils/process.d.ts +0 -1
  64. package/package.json +2 -2
@@ -1 +1 @@
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 — pnpm/yarn audit output varies too much\n if (ctx.adapter.type !== 'npm') {\n debug('skipping audit test for %s (npm 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 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\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,OAAO;AAC9B,UAAM,yCAAyC,IAAI,QAAQ,KAAK;AAChE;;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;EAED,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;AAC1C,SAAA,QAAO,GAAG,WAAW,uBAAuB,KAAA,GAAW,oDAAkD;AACzG,SAAA,QAAO,GAAG,WAAW,oBAAoB,KAAA,GAAW,iDAA+C;;;AAIvG,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(\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 }\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,GACL,WAAW,uBAAuB,KAAA,GAClC,oDACD;AACD,UAAA,QAAO,GACL,WAAW,oBAAoB,KAAA,GAC/B,iDACD;;;;AAKP,IAAa,YAA4B;CACvC,MAAM;CACN,UAAU,CAAC,QAAQ;CACnB,KAAK;CACN"}
@@ -35,10 +35,19 @@ function getCiArgs(ctx) {
35
35
  ...ctx.adapter.registryArg(ctx.registryUrl)
36
36
  ];
37
37
  case "yarn-modern": return ["install", "--immutable"];
38
+ case "bun": return [
39
+ "install",
40
+ "--frozen-lockfile",
41
+ ...ctx.adapter.registryArg(ctx.registryUrl)
42
+ ];
38
43
  default: return ["ci", ...ctx.adapter.registryArg(ctx.registryUrl)];
39
44
  }
40
45
  }
41
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
+ }
42
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" });
43
52
  debug$1("running initial install to generate lockfile in %s", tempFolder);
44
53
  await ctx.adapter.exec({ cwd: tempFolder }, "install", ...ctx.adapter.registryArg(ctx.registryUrl));
@@ -1 +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 default:\n return ['ci', ...ctx.adapter.registryArg(ctx.registryUrl)];\n }\n}\n\nasync function testCi(ctx: TestContext): Promise<void> {\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,QACE,QAAO,CAAC,MAAM,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAAC;;;AAIhE,eAAe,OAAO,KAAiC;CACrD,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
+ {"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 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/tests/index.ts"],"sourcesContent":["import { TestDefinition } from '../types';\n\nimport { allScenarios, installMultipleDepsScenario } from '../scenarios';\nimport { auditTest } from './audit';\nimport { ciTest } from './ci';\nimport { deprecateTest } from './deprecate';\nimport { distTagsTest } from './dist-tags';\nimport { infoTest } from './info';\nimport { installTest } from './install';\nimport { loginTest } from './login';\nimport { pingTest } from './ping';\nimport { publishTest } from './publish';\nimport { searchTest } from './search';\nimport { starTest } from './star';\nimport { unpublishTest } from './unpublish';\n\nexport const allTests: TestDefinition[] = [\n publishTest,\n installTest,\n ciTest,\n auditTest,\n infoTest,\n deprecateTest,\n distTagsTest,\n loginTest,\n pingTest,\n searchTest,\n starTest,\n unpublishTest,\n // Scenarios (complex, multi-step tests)\n ...allScenarios,\n];\n\nexport {\n publishTest,\n installTest,\n ciTest,\n auditTest,\n infoTest,\n deprecateTest,\n distTagsTest,\n loginTest,\n pingTest,\n searchTest,\n starTest,\n unpublishTest,\n // Scenarios\n installMultipleDepsScenario,\n allScenarios,\n};\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,IAAa,WAA6B;CACxC,gBAAA;CACA,gBAAA;CACA,WAAA;CACA,cAAA;CACA,aAAA;CACA,kBAAA;CACA,kBAAA;CACA,cAAA;CACA,aAAA;CACA,eAAA;CACA,aAAA;CACA,kBAAA;CAEA,GAAG,cAAA;CACJ"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/tests/index.ts"],"sourcesContent":["import { allScenarios, installMultipleDepsScenario } from '../scenarios';\nimport { TestDefinition } from '../types';\nimport { auditTest } from './audit';\nimport { ciTest } from './ci';\nimport { deprecateTest } from './deprecate';\nimport { distTagsTest } from './dist-tags';\nimport { infoTest } from './info';\nimport { installTest } from './install';\nimport { loginTest } from './login';\nimport { pingTest } from './ping';\nimport { publishTest } from './publish';\nimport { searchTest } from './search';\nimport { starTest } from './star';\nimport { unpublishTest } from './unpublish';\n\nexport const allTests: TestDefinition[] = [\n publishTest,\n installTest,\n ciTest,\n auditTest,\n infoTest,\n deprecateTest,\n distTagsTest,\n loginTest,\n pingTest,\n searchTest,\n starTest,\n unpublishTest,\n // Scenarios (complex, multi-step tests)\n ...allScenarios,\n];\n\nexport {\n publishTest,\n installTest,\n ciTest,\n auditTest,\n infoTest,\n deprecateTest,\n distTagsTest,\n loginTest,\n pingTest,\n searchTest,\n starTest,\n unpublishTest,\n // Scenarios\n installMultipleDepsScenario,\n allScenarios,\n};\n"],"mappings":";;;;;;;;;;;;;;;AAeA,IAAa,WAA6B;CACxC,gBAAA;CACA,gBAAA;CACA,WAAA;CACA,cAAA;CACA,aAAA;CACA,kBAAA;CACA,kBAAA;CACA,cAAA;CACA,aAAA;CACA,eAAA;CACA,aAAA;CACA,kBAAA;CAEA,GAAG,cAAA;CACJ"}
@@ -21,6 +21,9 @@ async function testInfo(ctx) {
21
21
  }
22
22
  });
23
23
  assert.default.ok(dataLine, "Expected yarn info NDJSON to contain an \"inspect\" entry");
24
+ } else if (ctx.adapter.type === "deno") {
25
+ const output = resp.stdout + resp.stderr;
26
+ assert.default.ok(output.includes("verdaccio"), "Expected deno info output to reference verdaccio");
24
27
  } else {
25
28
  const parsedBody = JSON.parse(resp.stdout);
26
29
  assert.default.strictEqual(parsedBody.name, "verdaccio", "Expected package name \"verdaccio\"");
@@ -1 +1 @@
1
- {"version":3,"file":"info.cjs","names":[],"sources":["../../../src/tests/info.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\nimport { createTempFolder } from '../utils/project';\nimport { writeFile } from 'fs/promises';\nimport { join } from 'path';\n\nasync function testInfo(ctx: TestContext): Promise<void> {\n // Create a minimal temp project so yarn modern has a project context\n // and yarn classic doesn't pick up the repo's packageManager field\n const tempFolder = await createTempFolder('info-test');\n await writeFile(join(tempFolder, 'package.json'), JSON.stringify({ name: 'info-test', version: '1.0.0' }));\n\n const resp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'info',\n 'verdaccio',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n if (ctx.adapter.type === 'yarn-classic') {\n const lines = resp.stdout.split('\\n').filter(Boolean);\n const dataLine = lines.find((l) => {\n try {\n const obj = JSON.parse(l);\n return obj.type === 'inspect';\n } catch {\n return false;\n }\n });\n assert.ok(dataLine, 'Expected yarn info NDJSON to contain an \"inspect\" entry');\n } else {\n const parsedBody = JSON.parse(resp.stdout);\n assert.strictEqual(parsedBody.name, 'verdaccio', 'Expected package name \"verdaccio\"');\n assert.ok(parsedBody.dependencies !== undefined, 'Expected \"dependencies\" to be defined');\n }\n}\n\nexport const infoTest: TestDefinition = {\n name: 'info',\n requires: ['info'],\n run: testInfo,\n};\n"],"mappings":";;;;;;;AAOA,eAAe,SAAS,KAAiC;CAGvD,MAAM,aAAa,MAAM,gBAAA,iBAAiB,YAAY;AACtD,QAAA,GAAA,YAAA,YAAA,GAAA,KAAA,MAAqB,YAAY,eAAe,EAAE,KAAK,UAAU;EAAE,MAAM;EAAa,SAAS;EAAS,CAAC,CAAC;CAE1G,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,YAAY,EACnB,QACA,aACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AAED,KAAI,IAAI,QAAQ,SAAS,gBAAgB;EAEvC,MAAM,WADQ,KAAK,OAAO,MAAM,KAAK,CAAC,OAAO,QAAQ,CAC9B,MAAM,MAAM;AACjC,OAAI;AAEF,WADY,KAAK,MAAM,EAAE,CACd,SAAS;WACd;AACN,WAAO;;IAET;AACF,SAAA,QAAO,GAAG,UAAU,4DAA0D;QACzE;EACL,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;AAC1C,SAAA,QAAO,YAAY,WAAW,MAAM,aAAa,sCAAoC;AACrF,SAAA,QAAO,GAAG,WAAW,iBAAiB,KAAA,GAAW,0CAAwC;;;AAI7F,IAAa,WAA2B;CACtC,MAAM;CACN,UAAU,CAAC,OAAO;CAClB,KAAK;CACN"}
1
+ {"version":3,"file":"info.cjs","names":[],"sources":["../../../src/tests/info.ts"],"sourcesContent":["import assert from 'assert';\nimport { writeFile } from 'fs/promises';\nimport { join } from 'path';\n\nimport { TestContext, TestDefinition } from '../types';\nimport { createTempFolder } from '../utils/project';\n\nasync function testInfo(ctx: TestContext): Promise<void> {\n // Create a minimal temp project so yarn modern has a project context\n // and yarn classic doesn't pick up the repo's packageManager field\n const tempFolder = await createTempFolder('info-test');\n await writeFile(\n join(tempFolder, 'package.json'),\n JSON.stringify({ name: 'info-test', version: '1.0.0' })\n );\n\n const resp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'info',\n 'verdaccio',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n if (ctx.adapter.type === 'yarn-classic') {\n const lines = resp.stdout.split('\\n').filter(Boolean);\n const dataLine = lines.find((l) => {\n try {\n const obj = JSON.parse(l);\n return obj.type === 'inspect';\n } catch {\n return false;\n }\n });\n assert.ok(dataLine, 'Expected yarn info NDJSON to contain an \"inspect\" entry');\n } else if (ctx.adapter.type === 'deno') {\n // deno info npm:<pkg> outputs a text dependency tree\n const output = resp.stdout + resp.stderr;\n assert.ok(output.includes('verdaccio'), 'Expected deno info output to reference verdaccio');\n } else {\n const parsedBody = JSON.parse(resp.stdout);\n assert.strictEqual(parsedBody.name, 'verdaccio', 'Expected package name \"verdaccio\"');\n assert.ok(parsedBody.dependencies !== undefined, 'Expected \"dependencies\" to be defined');\n }\n}\n\nexport const infoTest: TestDefinition = {\n name: 'info',\n requires: ['info'],\n run: testInfo,\n};\n"],"mappings":";;;;;;;AAOA,eAAe,SAAS,KAAiC;CAGvD,MAAM,aAAa,MAAM,gBAAA,iBAAiB,YAAY;AACtD,QAAA,GAAA,YAAA,YAAA,GAAA,KAAA,MACO,YAAY,eAAe,EAChC,KAAK,UAAU;EAAE,MAAM;EAAa,SAAS;EAAS,CAAC,CACxD;CAED,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,YAAY,EACnB,QACA,aACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AAED,KAAI,IAAI,QAAQ,SAAS,gBAAgB;EAEvC,MAAM,WADQ,KAAK,OAAO,MAAM,KAAK,CAAC,OAAO,QAAQ,CAC9B,MAAM,MAAM;AACjC,OAAI;AAEF,WADY,KAAK,MAAM,EAAE,CACd,SAAS;WACd;AACN,WAAO;;IAET;AACF,SAAA,QAAO,GAAG,UAAU,4DAA0D;YACrE,IAAI,QAAQ,SAAS,QAAQ;EAEtC,MAAM,SAAS,KAAK,SAAS,KAAK;AAClC,SAAA,QAAO,GAAG,OAAO,SAAS,YAAY,EAAE,mDAAmD;QACtF;EACL,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;AAC1C,SAAA,QAAO,YAAY,WAAW,MAAM,aAAa,sCAAoC;AACrF,SAAA,QAAO,GAAG,WAAW,iBAAiB,KAAA,GAAW,0CAAwC;;;AAI7F,IAAa,WAA2B;CACtC,MAAM;CACN,UAAU,CAAC,OAAO;CAClB,KAAK;CACN"}
@@ -1 +1 @@
1
- {"version":3,"file":"login.cjs","names":[],"sources":["../../../src/tests/login.ts"],"sourcesContent":["import assert from 'assert';\nimport buildDebug from 'debug';\nimport { writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport YAML from 'js-yaml';\n\nimport { TestContext, TestDefinition } from '../types';\nimport { createTempFolder, getPackageJSON, getREADME } from '../utils/project';\n\nconst debug = buildDebug('verdaccio:e2e-cli:test:login');\n\n/**\n * Creates a project with registry config but WITHOUT auth token,\n * so whoami will use the token saved by login to ~/.yarnrc.yml.\n */\nasync function prepareLoginProject(\n ctx: TestContext,\n name: string\n): Promise<string> {\n debug('preparing project for %s (no auth token)', name);\n const tempFolder = await createTempFolder(name);\n const yamlContent = YAML.dump({\n npmRegistryServer: ctx.registryUrl,\n enableImmutableInstalls: false,\n unsafeHttpWhitelist: ['localhost'],\n });\n await writeFile(join(tempFolder, '.yarnrc.yml'), yamlContent);\n await writeFile(join(tempFolder, 'package.json'), JSON.stringify({ name, version: '1.0.0' }));\n if (ctx.adapter.importPlugin) {\n debug('importing npm-login plugin into %s', tempFolder);\n await ctx.adapter.importPlugin(tempFolder, 'npm-login');\n }\n return tempFolder;\n}\n\nasync function yarnLogin(\n ctx: TestContext,\n cwd: string,\n user: string,\n password: string,\n email: string\n) {\n debug('yarn npm login as %s', user);\n return ctx.adapter.exec(\n { cwd },\n 'login',\n '--auth-type=legacy',\n `--user=${user}`,\n `--password=${password}`,\n `--email=${email}`\n );\n}\n\nasync function yarnWhoami(ctx: TestContext, cwd: string): Promise<string> {\n const resp = await ctx.adapter.exec({ cwd }, 'whoami');\n debug('yarn npm whoami: %s', resp.stdout);\n return resp.stdout;\n}\n\nasync function testLogin(ctx: TestContext): Promise<void> {\n const type = ctx.adapter.type;\n const id = ctx.runId;\n\n if (type !== 'yarn-modern') {\n debug('login test only supported for yarn-modern, skipping %s', type);\n return;\n }\n\n const user1 = `login-a-${id}`;\n const password1 = 'test-password-123';\n const email1 = `${user1}@test.example.com`;\n\n await ctx.subTest('create new user + whoami', async () => {\n const tf = await prepareLoginProject(ctx, `verdaccio-login1-${id}`);\n const loginResp = await yarnLogin(ctx, tf, user1, password1, email1);\n assert.ok(\n loginResp.stdout.includes('Logged in') || loginResp.stdout.includes('token saved'),\n `Expected login success message but got \"${loginResp.stdout}\"`\n );\n const who = await yarnWhoami(ctx, tf);\n assert.ok(who.includes(user1), `Expected whoami \"${user1}\" but got \"${who}\"`);\n });\n\n await ctx.subTest('login existing user', async () => {\n const tf = await prepareLoginProject(ctx, `verdaccio-login2-${id}`);\n const loginResp = await yarnLogin(ctx, tf, user1, password1, email1);\n assert.ok(\n loginResp.stdout.includes('Logged in') || loginResp.stdout.includes('token saved'),\n `Expected login success for existing user but got \"${loginResp.stdout}\"`\n );\n const who = await yarnWhoami(ctx, tf);\n assert.ok(who.includes(user1), `Expected \"${user1}\" but got \"${who}\"`);\n });\n\n await ctx.subTest('wrong password fails', async () => {\n const tf = await prepareLoginProject(ctx, `verdaccio-login3-${id}`);\n let loginFailed = false;\n try {\n await yarnLogin(ctx, tf, user1, 'wrong-password', email1);\n } catch {\n loginFailed = true;\n }\n assert.ok(loginFailed, 'Login with wrong password should have failed');\n });\n\n await ctx.subTest('login then publish', async () => {\n const pkgName = `@verdaccio/login-pub-${id}`;\n const tf = await createTempFolder(`login-pub-${id}`);\n const yamlContent = YAML.dump({\n npmRegistryServer: ctx.registryUrl,\n enableImmutableInstalls: false,\n unsafeHttpWhitelist: ['localhost'],\n });\n await writeFile(join(tf, '.yarnrc.yml'), yamlContent);\n await writeFile(join(tf, 'package.json'), getPackageJSON(pkgName, '1.0.0'));\n await writeFile(join(tf, 'README.md'), getREADME(pkgName));\n if (ctx.adapter.importPlugin) {\n await ctx.adapter.importPlugin(tf, 'npm-login');\n }\n await yarnLogin(ctx, tf, user1, password1, email1);\n await ctx.adapter.exec({ cwd: tf }, 'install');\n const pubResp = await ctx.adapter.exec({ cwd: tf }, 'publish');\n assert.ok(\n pubResp.stdout.includes('Package archive published'),\n `Expected publish success but got \"${pubResp.stdout}\"`\n );\n });\n\n await ctx.subTest('switch users', async () => {\n const user2 = `login-b-${id}`;\n const password2 = 'other-password-456';\n const email2 = `${user2}@test.example.com`;\n const tf = await prepareLoginProject(ctx, `verdaccio-login5-${id}`);\n\n await yarnLogin(ctx, tf, user1, password1, email1);\n const who1 = await yarnWhoami(ctx, tf);\n assert.ok(who1.includes(user1), `Expected \"${user1}\" but got \"${who1}\"`);\n\n await yarnLogin(ctx, tf, user2, password2, email2);\n const who2 = await yarnWhoami(ctx, tf);\n assert.ok(who2.includes(user2), `Expected \"${user2}\" after switch but got \"${who2}\"`);\n });\n}\n\nexport const loginTest: TestDefinition = {\n name: 'login',\n requires: ['login'],\n run: testLogin,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"login.cjs","names":[],"sources":["../../../src/tests/login.ts"],"sourcesContent":["import assert from 'assert';\nimport buildDebug from 'debug';\nimport { writeFile } from 'fs/promises';\nimport YAML from 'js-yaml';\nimport { join } from 'path';\n\nimport { TestContext, TestDefinition } from '../types';\nimport { createTempFolder, getPackageJSON, getREADME } from '../utils/project';\n\nconst debug = buildDebug('verdaccio:e2e-cli:test:login');\n\n/**\n * Creates a project with registry config but WITHOUT auth token,\n * so whoami will use the token saved by login to ~/.yarnrc.yml.\n */\nasync function prepareLoginProject(ctx: TestContext, name: string): Promise<string> {\n debug('preparing project for %s (no auth token)', name);\n const tempFolder = await createTempFolder(name);\n const yamlContent = YAML.dump({\n npmRegistryServer: ctx.registryUrl,\n enableImmutableInstalls: false,\n unsafeHttpWhitelist: ['localhost'],\n });\n await writeFile(join(tempFolder, '.yarnrc.yml'), yamlContent);\n await writeFile(join(tempFolder, 'package.json'), JSON.stringify({ name, version: '1.0.0' }));\n if (ctx.adapter.importPlugin) {\n debug('importing npm-login plugin into %s', tempFolder);\n await ctx.adapter.importPlugin(tempFolder, 'npm-login');\n }\n return tempFolder;\n}\n\nasync function yarnLogin(\n ctx: TestContext,\n cwd: string,\n user: string,\n password: string,\n email: string\n) {\n debug('yarn npm login as %s', user);\n return ctx.adapter.exec(\n { cwd },\n 'login',\n '--auth-type=legacy',\n `--user=${user}`,\n `--password=${password}`,\n `--email=${email}`\n );\n}\n\nasync function yarnWhoami(ctx: TestContext, cwd: string): Promise<string> {\n const resp = await ctx.adapter.exec({ cwd }, 'whoami');\n debug('yarn npm whoami: %s', resp.stdout);\n return resp.stdout;\n}\n\nasync function testLogin(ctx: TestContext): Promise<void> {\n const type = ctx.adapter.type;\n const id = ctx.runId;\n\n if (type !== 'yarn-modern') {\n debug('login test only supported for yarn-modern, skipping %s', type);\n return;\n }\n\n const user1 = `login-a-${id}`;\n const password1 = 'test-password-123';\n const email1 = `${user1}@test.example.com`;\n\n await ctx.subTest('create new user + whoami', async () => {\n const tf = await prepareLoginProject(ctx, `verdaccio-login1-${id}`);\n const loginResp = await yarnLogin(ctx, tf, user1, password1, email1);\n assert.ok(\n loginResp.stdout.includes('Logged in') || loginResp.stdout.includes('token saved'),\n `Expected login success message but got \"${loginResp.stdout}\"`\n );\n const who = await yarnWhoami(ctx, tf);\n assert.ok(who.includes(user1), `Expected whoami \"${user1}\" but got \"${who}\"`);\n });\n\n await ctx.subTest('login existing user', async () => {\n const tf = await prepareLoginProject(ctx, `verdaccio-login2-${id}`);\n const loginResp = await yarnLogin(ctx, tf, user1, password1, email1);\n assert.ok(\n loginResp.stdout.includes('Logged in') || loginResp.stdout.includes('token saved'),\n `Expected login success for existing user but got \"${loginResp.stdout}\"`\n );\n const who = await yarnWhoami(ctx, tf);\n assert.ok(who.includes(user1), `Expected \"${user1}\" but got \"${who}\"`);\n });\n\n await ctx.subTest('wrong password fails', async () => {\n const tf = await prepareLoginProject(ctx, `verdaccio-login3-${id}`);\n let loginFailed = false;\n try {\n await yarnLogin(ctx, tf, user1, 'wrong-password', email1);\n } catch {\n loginFailed = true;\n }\n assert.ok(loginFailed, 'Login with wrong password should have failed');\n });\n\n await ctx.subTest('login then publish', async () => {\n const pkgName = `@verdaccio/login-pub-${id}`;\n const tf = await createTempFolder(`login-pub-${id}`);\n const yamlContent = YAML.dump({\n npmRegistryServer: ctx.registryUrl,\n enableImmutableInstalls: false,\n unsafeHttpWhitelist: ['localhost'],\n });\n await writeFile(join(tf, '.yarnrc.yml'), yamlContent);\n await writeFile(join(tf, 'package.json'), getPackageJSON(pkgName, '1.0.0'));\n await writeFile(join(tf, 'README.md'), getREADME(pkgName));\n if (ctx.adapter.importPlugin) {\n await ctx.adapter.importPlugin(tf, 'npm-login');\n }\n await yarnLogin(ctx, tf, user1, password1, email1);\n await ctx.adapter.exec({ cwd: tf }, 'install');\n const pubResp = await ctx.adapter.exec({ cwd: tf }, 'publish');\n assert.ok(\n pubResp.stdout.includes('Package archive published'),\n `Expected publish success but got \"${pubResp.stdout}\"`\n );\n });\n\n await ctx.subTest('switch users', async () => {\n const user2 = `login-b-${id}`;\n const password2 = 'other-password-456';\n const email2 = `${user2}@test.example.com`;\n const tf = await prepareLoginProject(ctx, `verdaccio-login5-${id}`);\n\n await yarnLogin(ctx, tf, user1, password1, email1);\n const who1 = await yarnWhoami(ctx, tf);\n assert.ok(who1.includes(user1), `Expected \"${user1}\" but got \"${who1}\"`);\n\n await yarnLogin(ctx, tf, user2, password2, email2);\n const who2 = await yarnWhoami(ctx, tf);\n assert.ok(who2.includes(user2), `Expected \"${user2}\" after switch but got \"${who2}\"`);\n });\n}\n\nexport const loginTest: TestDefinition = {\n name: 'login',\n requires: ['login'],\n run: testLogin,\n};\n"],"mappings":"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"}
@@ -16,6 +16,7 @@ async function testPublish(ctx) {
16
16
  const resp = await ctx.adapter.exec({ cwd: tempFolder }, "publish", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
17
17
  if (type === "yarn-modern") assert.default.ok(resp.stdout.match(/Package archive published/), `Expected "Package archive published" for ${pkgName} but got "${resp.stdout}"`);
18
18
  else if (type === "yarn-classic") assert.default.ok(resp.stdout.length > 0, `Expected publish output for ${pkgName}`);
19
+ else if (type === "bun") assert.default.ok(true, `Publish succeeded for ${pkgName}`);
19
20
  else try {
20
21
  const parsedBody = JSON.parse(resp.stdout);
21
22
  assert.default.strictEqual(parsedBody.name, pkgName, `Expected package name "${pkgName}" but got "${parsedBody.name}"`);
@@ -1 +1 @@
1
- {"version":3,"file":"publish.cjs","names":[],"sources":["../../../src/tests/publish.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testPublish(ctx: TestContext): Promise<void> {\n const packages = [\n `verdaccio-memory-${ctx.runId}`,\n `verdaccio-${ctx.runId}`,\n `@verdaccio/foo-${ctx.runId}`,\n `@verdaccio/some-foo-${ctx.runId}`,\n ];\n\n const type = ctx.adapter.type;\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 );\n\n // yarn modern requires install before publish to generate lockfile\n if (type === 'yarn-modern') {\n await ctx.adapter.exec({ cwd: tempFolder }, 'install');\n }\n\n const resp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'publish',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n if (type === 'yarn-modern') {\n assert.ok(\n resp.stdout.match(/Package archive published/),\n `Expected \"Package archive published\" for ${pkgName} but got \"${resp.stdout}\"`\n );\n } else if (type === 'yarn-classic') {\n // yarn classic --json outputs NDJSON — just verify no error exit (exit code 0 is enough)\n assert.ok(resp.stdout.length > 0, `Expected publish output for ${pkgName}`);\n } else {\n // npm / pnpm\n try {\n const parsedBody = JSON.parse(resp.stdout);\n assert.strictEqual(parsedBody.name, pkgName, `Expected package name \"${pkgName}\" but got \"${parsedBody.name}\"`);\n assert.ok(parsedBody.files, `Expected files to be defined for ${pkgName}`);\n } catch {\n // pnpm v11+ native publish doesn't output JSON — exit code 0 is sufficient\n assert.ok(true, `Publish succeeded for ${pkgName}`);\n }\n }\n }\n}\n\nexport const publishTest: TestDefinition = {\n name: 'publish',\n requires: ['publish'],\n run: testPublish,\n};\n"],"mappings":";;;;AAIA,eAAe,YAAY,KAAiC;CAC1D,MAAM,WAAW;EACf,oBAAoB,IAAI;EACxB,aAAa,IAAI;EACjB,kBAAkB,IAAI;EACtB,uBAAuB,IAAI;EAC5B;CAED,MAAM,OAAO,IAAI,QAAQ;AAEzB,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,SACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;AAGD,MAAI,SAAS,cACX,OAAM,IAAI,QAAQ,KAAK,EAAE,KAAK,YAAY,EAAE,UAAU;EAGxD,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,YAAY,EACnB,WACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AAED,MAAI,SAAS,cACX,QAAA,QAAO,GACL,KAAK,OAAO,MAAM,4BAA4B,EAC9C,4CAA4C,QAAQ,YAAY,KAAK,OAAO,GAC7E;WACQ,SAAS,eAElB,QAAA,QAAO,GAAG,KAAK,OAAO,SAAS,GAAG,+BAA+B,UAAU;MAG3E,KAAI;GACF,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;AAC1C,UAAA,QAAO,YAAY,WAAW,MAAM,SAAS,0BAA0B,QAAQ,aAAa,WAAW,KAAK,GAAG;AAC/G,UAAA,QAAO,GAAG,WAAW,OAAO,oCAAoC,UAAU;UACpE;AAEN,UAAA,QAAO,GAAG,MAAM,yBAAyB,UAAU;;;;AAM3D,IAAa,cAA8B;CACzC,MAAM;CACN,UAAU,CAAC,UAAU;CACrB,KAAK;CACN"}
1
+ {"version":3,"file":"publish.cjs","names":[],"sources":["../../../src/tests/publish.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testPublish(ctx: TestContext): Promise<void> {\n const packages = [\n `verdaccio-memory-${ctx.runId}`,\n `verdaccio-${ctx.runId}`,\n `@verdaccio/foo-${ctx.runId}`,\n `@verdaccio/some-foo-${ctx.runId}`,\n ];\n\n const type = ctx.adapter.type;\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 );\n\n // yarn modern requires install before publish to generate lockfile\n if (type === 'yarn-modern') {\n await ctx.adapter.exec({ cwd: tempFolder }, 'install');\n }\n\n const resp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'publish',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n if (type === 'yarn-modern') {\n assert.ok(\n resp.stdout.match(/Package archive published/),\n `Expected \"Package archive published\" for ${pkgName} but got \"${resp.stdout}\"`\n );\n } else if (type === 'yarn-classic') {\n // yarn classic --json outputs NDJSON — just verify no error exit (exit code 0 is enough)\n assert.ok(resp.stdout.length > 0, `Expected publish output for ${pkgName}`);\n } else if (type === 'bun') {\n // bun publish outputs text confirmation — exit code 0 is sufficient\n assert.ok(true, `Publish succeeded for ${pkgName}`);\n } else {\n // npm / pnpm\n try {\n const parsedBody = JSON.parse(resp.stdout);\n assert.strictEqual(\n parsedBody.name,\n pkgName,\n `Expected package name \"${pkgName}\" but got \"${parsedBody.name}\"`\n );\n assert.ok(parsedBody.files, `Expected files to be defined for ${pkgName}`);\n } catch {\n // pnpm v11+ native publish doesn't output JSON — exit code 0 is sufficient\n assert.ok(true, `Publish succeeded for ${pkgName}`);\n }\n }\n }\n}\n\nexport const publishTest: TestDefinition = {\n name: 'publish',\n requires: ['publish'],\n run: testPublish,\n};\n"],"mappings":";;;;AAIA,eAAe,YAAY,KAAiC;CAC1D,MAAM,WAAW;EACf,oBAAoB,IAAI;EACxB,aAAa,IAAI;EACjB,kBAAkB,IAAI;EACtB,uBAAuB,IAAI;EAC5B;CAED,MAAM,OAAO,IAAI,QAAQ;AAEzB,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,SACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;AAGD,MAAI,SAAS,cACX,OAAM,IAAI,QAAQ,KAAK,EAAE,KAAK,YAAY,EAAE,UAAU;EAGxD,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,YAAY,EACnB,WACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AAED,MAAI,SAAS,cACX,QAAA,QAAO,GACL,KAAK,OAAO,MAAM,4BAA4B,EAC9C,4CAA4C,QAAQ,YAAY,KAAK,OAAO,GAC7E;WACQ,SAAS,eAElB,QAAA,QAAO,GAAG,KAAK,OAAO,SAAS,GAAG,+BAA+B,UAAU;WAClE,SAAS,MAElB,QAAA,QAAO,GAAG,MAAM,yBAAyB,UAAU;MAGnD,KAAI;GACF,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;AAC1C,UAAA,QAAO,YACL,WAAW,MACX,SACA,0BAA0B,QAAQ,aAAa,WAAW,KAAK,GAChE;AACD,UAAA,QAAO,GAAG,WAAW,OAAO,oCAAoC,UAAU;UACpE;AAEN,UAAA,QAAO,GAAG,MAAM,yBAAyB,UAAU;;;;AAM3D,IAAa,cAA8B;CACzC,MAAM;CACN,UAAU,CAAC,UAAU;CACrB,KAAK;CACN"}
@@ -1 +1 @@
1
- {"version":3,"file":"star.cjs","names":[],"sources":["../../../src/tests/star.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testStar(ctx: TestContext): Promise<void> {\n const id = ctx.runId;\n\n // Test 1: star a package\n const pkgName1 = `@verdaccio/star1-${id}`;\n const { tempFolder: tf1 } = await ctx.adapter.prepareProject(\n pkgName1,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token\n );\n await ctx.adapter.exec(\n { cwd: tf1 },\n 'publish',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n const resp1 = await ctx.adapter.exec(\n { cwd: tf1 },\n 'star',\n pkgName1,\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n assert.ok(\n resp1.stdout.includes(pkgName1),\n `Expected star output to contain \"${pkgName1}\" but got \"${resp1.stdout}\"`\n );\n\n // Test 2: unstar a package\n const pkgName2 = `@verdaccio/star2-${id}`;\n const { tempFolder: tf2 } = await ctx.adapter.prepareProject(\n pkgName2,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token\n );\n await ctx.adapter.exec(\n { cwd: tf2 },\n 'publish',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n await ctx.adapter.exec(\n { cwd: tf2 },\n 'star',\n pkgName2,\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n const resp2 = await ctx.adapter.exec(\n { cwd: tf2 },\n 'unstar',\n pkgName2,\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n assert.ok(\n resp2.stdout.includes(pkgName2),\n `Expected unstar output to contain \"${pkgName2}\" but got \"${resp2.stdout}\"`\n );\n}\n\nexport const starTest: TestDefinition = {\n name: 'star',\n requires: ['star'],\n run: testStar,\n};\n"],"mappings":";;;;AAIA,eAAe,SAAS,KAAiC;CACvD,MAAM,KAAK,IAAI;CAGf,MAAM,WAAW,oBAAoB;CACrC,MAAM,EAAE,YAAY,QAAQ,MAAM,IAAI,QAAQ,eAC5C,UACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;AACD,OAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,KAAK,EACZ,WACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;CACD,MAAM,QAAQ,MAAM,IAAI,QAAQ,KAC9B,EAAE,KAAK,KAAK,EACZ,QACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AACD,QAAA,QAAO,GACL,MAAM,OAAO,SAAS,SAAS,EAC/B,oCAAoC,SAAS,aAAa,MAAM,OAAO,GACxE;CAGD,MAAM,WAAW,oBAAoB;CACrC,MAAM,EAAE,YAAY,QAAQ,MAAM,IAAI,QAAQ,eAC5C,UACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;AACD,OAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,KAAK,EACZ,WACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AACD,OAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,KAAK,EACZ,QACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;CACD,MAAM,QAAQ,MAAM,IAAI,QAAQ,KAC9B,EAAE,KAAK,KAAK,EACZ,UACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AACD,QAAA,QAAO,GACL,MAAM,OAAO,SAAS,SAAS,EAC/B,sCAAsC,SAAS,aAAa,MAAM,OAAO,GAC1E;;AAGH,IAAa,WAA2B;CACtC,MAAM;CACN,UAAU,CAAC,OAAO;CAClB,KAAK;CACN"}
1
+ {"version":3,"file":"star.cjs","names":[],"sources":["../../../src/tests/star.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testStar(ctx: TestContext): Promise<void> {\n const id = ctx.runId;\n\n // Test 1: star a package\n const pkgName1 = `@verdaccio/star1-${id}`;\n const { tempFolder: tf1 } = await ctx.adapter.prepareProject(\n pkgName1,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token\n );\n await ctx.adapter.exec({ cwd: tf1 }, 'publish', ...ctx.adapter.registryArg(ctx.registryUrl));\n const resp1 = await ctx.adapter.exec(\n { cwd: tf1 },\n 'star',\n pkgName1,\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n assert.ok(\n resp1.stdout.includes(pkgName1),\n `Expected star output to contain \"${pkgName1}\" but got \"${resp1.stdout}\"`\n );\n\n // Test 2: unstar a package\n const pkgName2 = `@verdaccio/star2-${id}`;\n const { tempFolder: tf2 } = await ctx.adapter.prepareProject(\n pkgName2,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token\n );\n await ctx.adapter.exec({ cwd: tf2 }, 'publish', ...ctx.adapter.registryArg(ctx.registryUrl));\n await ctx.adapter.exec(\n { cwd: tf2 },\n 'star',\n pkgName2,\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n const resp2 = await ctx.adapter.exec(\n { cwd: tf2 },\n 'unstar',\n pkgName2,\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n assert.ok(\n resp2.stdout.includes(pkgName2),\n `Expected unstar output to contain \"${pkgName2}\" but got \"${resp2.stdout}\"`\n );\n}\n\nexport const starTest: TestDefinition = {\n name: 'star',\n requires: ['star'],\n run: testStar,\n};\n"],"mappings":";;;;AAIA,eAAe,SAAS,KAAiC;CACvD,MAAM,KAAK,IAAI;CAGf,MAAM,WAAW,oBAAoB;CACrC,MAAM,EAAE,YAAY,QAAQ,MAAM,IAAI,QAAQ,eAC5C,UACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;AACD,OAAM,IAAI,QAAQ,KAAK,EAAE,KAAK,KAAK,EAAE,WAAW,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAAC;CAC5F,MAAM,QAAQ,MAAM,IAAI,QAAQ,KAC9B,EAAE,KAAK,KAAK,EACZ,QACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AACD,QAAA,QAAO,GACL,MAAM,OAAO,SAAS,SAAS,EAC/B,oCAAoC,SAAS,aAAa,MAAM,OAAO,GACxE;CAGD,MAAM,WAAW,oBAAoB;CACrC,MAAM,EAAE,YAAY,QAAQ,MAAM,IAAI,QAAQ,eAC5C,UACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;AACD,OAAM,IAAI,QAAQ,KAAK,EAAE,KAAK,KAAK,EAAE,WAAW,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAAC;AAC5F,OAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,KAAK,EACZ,QACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;CACD,MAAM,QAAQ,MAAM,IAAI,QAAQ,KAC9B,EAAE,KAAK,KAAK,EACZ,UACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;AACD,QAAA,QAAO,GACL,MAAM,OAAO,SAAS,SAAS,EAC/B,sCAAsC,SAAS,aAAa,MAAM,OAAO,GAC1E;;AAGH,IAAa,WAA2B;CACtC,MAAM;CACN,UAAU,CAAC,OAAO;CAClB,KAAK;CACN"}
@@ -2,8 +2,8 @@ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
2
  let debug = require("debug");
3
3
  debug = require_runtime.__toESM(debug);
4
4
  let child_process = require("child_process");
5
- let readline = require("readline");
6
5
  let path = require("path");
6
+ let readline = require("readline");
7
7
  //#region src/utils/process.ts
8
8
  var debug$1 = (0, debug.default)("verdaccio:e2e-cli:process");
9
9
  var debugRead = (0, debug.default)("verdaccio:e2e-cli:line");
@@ -1 +1 @@
1
- {"version":3,"file":"process.cjs","names":[],"sources":["../../../src/utils/process.ts"],"sourcesContent":["import { SpawnOptions, spawn } from 'child_process';\nimport buildDebug from 'debug';\nimport { createInterface } from 'readline';\nimport { basename } from 'path';\n\nimport { ExecOutput } from '../types';\n\nconst debug = buildDebug('verdaccio:e2e-cli:process');\nconst debugRead = buildDebug('verdaccio:e2e-cli:line');\n\nlet _verbose = false;\n\nexport function setVerbose(v: boolean) {\n _verbose = v;\n}\n\nconst COLORS = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n cyan: '\\x1b[36m',\n green: '\\x1b[32m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n};\n\nfunction shortCmd(cmd: string, args: string[]): string {\n const bin = basename(cmd);\n return `${bin} ${args.join(' ')}`;\n}\n\nexport async function exec(options: SpawnOptions, cmd: string, args: string[]): Promise<ExecOutput> {\n debug('start exec %o %o %o', options, cmd, args ? args.join(' ') : '');\n let stdout = '';\n let stderr = '';\n\n if (_verbose) {\n const cwd = options.cwd ? ` ${COLORS.dim}(cwd: ${basename(String(options.cwd))})${COLORS.reset}` : '';\n process.stdout.write(` ${COLORS.cyan}$${COLORS.reset} ${shortCmd(cmd, args)}${cwd}\\n`);\n }\n\n const spawnOptions: SpawnOptions = {\n cwd: options.cwd,\n stdio: options.stdio || 'pipe',\n env: options.env || process.env,\n };\n\n if (process.platform.startsWith('win')) {\n args.unshift('/c', cmd);\n cmd = 'cmd.exe';\n spawnOptions.stdio = 'pipe';\n }\n\n const start = Date.now();\n const childProcess = spawn(cmd, args, spawnOptions);\n\n if (childProcess.stdout) {\n childProcess.stdout.on('data', (data) => {\n debugRead('data %o', data.toString());\n });\n const rl = createInterface({\n input: childProcess.stdout,\n output: process.stdout,\n terminal: false,\n });\n\n rl.on('line', function (line) {\n debugRead('line %o', line);\n stdout += line;\n });\n }\n\n if (childProcess.stderr) {\n childProcess.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n }\n\n const err = new Error(`Running \"${cmd} ${args.join(' ')}\" returned error code `);\n return new Promise((resolve, reject) => {\n childProcess.on('exit', (code) => {\n const duration = Date.now() - start;\n debugRead('exit %o', code);\n\n if (_verbose) {\n const status = code\n ? `${COLORS.red}exit ${code}${COLORS.reset}`\n : `${COLORS.green}ok${COLORS.reset}`;\n process.stdout.write(` ${COLORS.dim} -> ${status} ${COLORS.dim}(${duration}ms)${COLORS.reset}\\n`);\n }\n\n if (!code) {\n resolve({ stdout, stderr });\n } else {\n err.message += `${code}...\\n\\nSTDOUT:\\n${stdout}\\n\\nSTDERR:\\n${stderr}\\n`;\n reject(err);\n }\n });\n });\n}\n"],"mappings":";;;;;;;AAOA,IAAM,WAAA,GAAA,MAAA,SAAmB,4BAA4B;AACrD,IAAM,aAAA,GAAA,MAAA,SAAuB,yBAAyB;AAEtD,IAAI,WAAW;AAEf,SAAgB,WAAW,GAAY;AACrC,YAAW;;AAGb,IAAM,SAAS;CACb,OAAO;CACP,KAAK;CACL,MAAM;CACN,OAAO;CACP,KAAK;CACL,QAAQ;CACT;AAED,SAAS,SAAS,KAAa,MAAwB;AAErD,QAAO,IAAA,GAAA,KAAA,UADc,IAAI,CACX,GAAG,KAAK,KAAK,IAAI;;AAGjC,eAAsB,KAAK,SAAuB,KAAa,MAAqC;AAClG,SAAM,uBAAuB,SAAS,KAAK,OAAO,KAAK,KAAK,IAAI,GAAG,GAAG;CACtE,IAAI,SAAS;CACb,IAAI,SAAS;AAEb,KAAI,UAAU;EACZ,MAAM,MAAM,QAAQ,MAAM,IAAI,OAAO,IAAI,SAAA,GAAA,KAAA,UAAiB,OAAO,QAAQ,IAAI,CAAC,CAAC,GAAG,OAAO,UAAU;AACnG,UAAQ,OAAO,MAAM,SAAS,OAAO,KAAK,GAAG,OAAO,MAAM,GAAG,SAAS,KAAK,KAAK,GAAG,IAAI,IAAI;;CAG7F,MAAM,eAA6B;EACjC,KAAK,QAAQ;EACb,OAAO,QAAQ,SAAS;EACxB,KAAK,QAAQ,OAAO,QAAQ;EAC7B;AAED,KAAI,QAAQ,SAAS,WAAW,MAAM,EAAE;AACtC,OAAK,QAAQ,MAAM,IAAI;AACvB,QAAM;AACN,eAAa,QAAQ;;CAGvB,MAAM,QAAQ,KAAK,KAAK;CACxB,MAAM,gBAAA,GAAA,cAAA,OAAqB,KAAK,MAAM,aAAa;AAEnD,KAAI,aAAa,QAAQ;AACvB,eAAa,OAAO,GAAG,SAAS,SAAS;AACvC,aAAU,WAAW,KAAK,UAAU,CAAC;IACrC;AAOF,GAAA,GAAA,SAAA,iBAN2B;GACzB,OAAO,aAAa;GACpB,QAAQ,QAAQ;GAChB,UAAU;GACX,CAAC,CAEC,GAAG,QAAQ,SAAU,MAAM;AAC5B,aAAU,WAAW,KAAK;AAC1B,aAAU;IACV;;AAGJ,KAAI,aAAa,OACf,cAAa,OAAO,GAAG,SAAS,SAAS;AACvC,YAAU,KAAK,UAAU;GACzB;CAGJ,MAAM,sBAAM,IAAI,MAAM,YAAY,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,wBAAwB;AAChF,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,eAAa,GAAG,SAAS,SAAS;GAChC,MAAM,WAAW,KAAK,KAAK,GAAG;AAC9B,aAAU,WAAW,KAAK;AAE1B,OAAI,UAAU;IACZ,MAAM,SAAS,OACX,GAAG,OAAO,IAAI,OAAO,OAAO,OAAO,UACnC,GAAG,OAAO,MAAM,IAAI,OAAO;AAC/B,YAAQ,OAAO,MAAM,SAAS,OAAO,IAAI,OAAO,OAAO,GAAG,OAAO,IAAI,GAAG,SAAS,KAAK,OAAO,MAAM,IAAI;;AAGzG,OAAI,CAAC,KACH,SAAQ;IAAE;IAAQ;IAAQ,CAAC;QACtB;AACL,QAAI,WAAW,GAAG,KAAK,kBAAkB,OAAO,eAAe,OAAO;AACtE,WAAO,IAAI;;IAEb;GACF"}
1
+ {"version":3,"file":"process.cjs","names":[],"sources":["../../../src/utils/process.ts"],"sourcesContent":["import { SpawnOptions, spawn } from 'child_process';\nimport buildDebug from 'debug';\nimport { basename } from 'path';\nimport { createInterface } from 'readline';\n\nimport { ExecOutput } from '../types';\n\nconst debug = buildDebug('verdaccio:e2e-cli:process');\nconst debugRead = buildDebug('verdaccio:e2e-cli:line');\n\nlet _verbose = false;\n\nexport function setVerbose(v: boolean) {\n _verbose = v;\n}\n\nconst COLORS = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n cyan: '\\x1b[36m',\n green: '\\x1b[32m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n};\n\nfunction shortCmd(cmd: string, args: string[]): string {\n const bin = basename(cmd);\n return `${bin} ${args.join(' ')}`;\n}\n\nexport async function exec(\n options: SpawnOptions,\n cmd: string,\n args: string[]\n): Promise<ExecOutput> {\n debug('start exec %o %o %o', options, cmd, args ? args.join(' ') : '');\n let stdout = '';\n let stderr = '';\n\n if (_verbose) {\n const cwd = options.cwd\n ? ` ${COLORS.dim}(cwd: ${basename(String(options.cwd))})${COLORS.reset}`\n : '';\n process.stdout.write(` ${COLORS.cyan}$${COLORS.reset} ${shortCmd(cmd, args)}${cwd}\\n`);\n }\n\n const spawnOptions: SpawnOptions = {\n cwd: options.cwd,\n stdio: options.stdio || 'pipe',\n env: options.env || process.env,\n };\n\n if (process.platform.startsWith('win')) {\n args.unshift('/c', cmd);\n cmd = 'cmd.exe';\n spawnOptions.stdio = 'pipe';\n }\n\n const start = Date.now();\n const childProcess = spawn(cmd, args, spawnOptions);\n\n if (childProcess.stdout) {\n childProcess.stdout.on('data', (data) => {\n debugRead('data %o', data.toString());\n });\n const rl = createInterface({\n input: childProcess.stdout,\n output: process.stdout,\n terminal: false,\n });\n\n rl.on('line', function (line) {\n debugRead('line %o', line);\n stdout += line;\n });\n }\n\n if (childProcess.stderr) {\n childProcess.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n }\n\n const err = new Error(`Running \"${cmd} ${args.join(' ')}\" returned error code `);\n return new Promise((resolve, reject) => {\n childProcess.on('exit', (code) => {\n const duration = Date.now() - start;\n debugRead('exit %o', code);\n\n if (_verbose) {\n const status = code\n ? `${COLORS.red}exit ${code}${COLORS.reset}`\n : `${COLORS.green}ok${COLORS.reset}`;\n process.stdout.write(\n ` ${COLORS.dim} -> ${status} ${COLORS.dim}(${duration}ms)${COLORS.reset}\\n`\n );\n }\n\n if (!code) {\n resolve({ stdout, stderr });\n } else {\n err.message += `${code}...\\n\\nSTDOUT:\\n${stdout}\\n\\nSTDERR:\\n${stderr}\\n`;\n reject(err);\n }\n });\n });\n}\n"],"mappings":";;;;;;;AAOA,IAAM,WAAA,GAAA,MAAA,SAAmB,4BAA4B;AACrD,IAAM,aAAA,GAAA,MAAA,SAAuB,yBAAyB;AAEtD,IAAI,WAAW;AAEf,SAAgB,WAAW,GAAY;AACrC,YAAW;;AAGb,IAAM,SAAS;CACb,OAAO;CACP,KAAK;CACL,MAAM;CACN,OAAO;CACP,KAAK;CACL,QAAQ;CACT;AAED,SAAS,SAAS,KAAa,MAAwB;AAErD,QAAO,IAAA,GAAA,KAAA,UADc,IAAI,CACX,GAAG,KAAK,KAAK,IAAI;;AAGjC,eAAsB,KACpB,SACA,KACA,MACqB;AACrB,SAAM,uBAAuB,SAAS,KAAK,OAAO,KAAK,KAAK,IAAI,GAAG,GAAG;CACtE,IAAI,SAAS;CACb,IAAI,SAAS;AAEb,KAAI,UAAU;EACZ,MAAM,MAAM,QAAQ,MAChB,IAAI,OAAO,IAAI,SAAA,GAAA,KAAA,UAAiB,OAAO,QAAQ,IAAI,CAAC,CAAC,GAAG,OAAO,UAC/D;AACJ,UAAQ,OAAO,MAAM,SAAS,OAAO,KAAK,GAAG,OAAO,MAAM,GAAG,SAAS,KAAK,KAAK,GAAG,IAAI,IAAI;;CAG7F,MAAM,eAA6B;EACjC,KAAK,QAAQ;EACb,OAAO,QAAQ,SAAS;EACxB,KAAK,QAAQ,OAAO,QAAQ;EAC7B;AAED,KAAI,QAAQ,SAAS,WAAW,MAAM,EAAE;AACtC,OAAK,QAAQ,MAAM,IAAI;AACvB,QAAM;AACN,eAAa,QAAQ;;CAGvB,MAAM,QAAQ,KAAK,KAAK;CACxB,MAAM,gBAAA,GAAA,cAAA,OAAqB,KAAK,MAAM,aAAa;AAEnD,KAAI,aAAa,QAAQ;AACvB,eAAa,OAAO,GAAG,SAAS,SAAS;AACvC,aAAU,WAAW,KAAK,UAAU,CAAC;IACrC;AAOF,GAAA,GAAA,SAAA,iBAN2B;GACzB,OAAO,aAAa;GACpB,QAAQ,QAAQ;GAChB,UAAU;GACX,CAAC,CAEC,GAAG,QAAQ,SAAU,MAAM;AAC5B,aAAU,WAAW,KAAK;AAC1B,aAAU;IACV;;AAGJ,KAAI,aAAa,OACf,cAAa,OAAO,GAAG,SAAS,SAAS;AACvC,YAAU,KAAK,UAAU;GACzB;CAGJ,MAAM,sBAAM,IAAI,MAAM,YAAY,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,wBAAwB;AAChF,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,eAAa,GAAG,SAAS,SAAS;GAChC,MAAM,WAAW,KAAK,KAAK,GAAG;AAC9B,aAAU,WAAW,KAAK;AAE1B,OAAI,UAAU;IACZ,MAAM,SAAS,OACX,GAAG,OAAO,IAAI,OAAO,OAAO,OAAO,UACnC,GAAG,OAAO,MAAM,IAAI,OAAO;AAC/B,YAAQ,OAAO,MACb,SAAS,OAAO,IAAI,OAAO,OAAO,GAAG,OAAO,IAAI,GAAG,SAAS,KAAK,OAAO,MAAM,IAC/E;;AAGH,OAAI,CAAC,KACH,SAAQ;IAAE;IAAQ;IAAQ,CAAC;QACtB;AACL,QAAI,WAAW,GAAG,KAAK,kBAAkB,OAAO,eAAe,OAAO;AACtE,WAAO,IAAI;;IAEb;GACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry-client.cjs","names":[],"sources":["../../../src/utils/registry-client.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { ping } from '@verdaccio/registry-cli';\n\nconst debug = buildDebug('verdaccio:e2e-cli:registry-client');\n\nexport type RegistryAuth = {\n token: string;\n user: string;\n};\n\n/**\n * Creates a user on the registry and returns the auth token.\n * Uses a unique username per run to avoid 409 conflicts.\n * Works against any running Verdaccio instance with htpasswd auth.\n */\nexport async function createUser(\n registryUrl: string,\n user = `e2e-user-${Date.now()}`,\n password = 'e2e-test-password'\n): Promise<RegistryAuth> {\n debug('creating user %s on %s', user, registryUrl);\n const url = `${registryUrl}/-/user/org.couchdb.user:${encodeURIComponent(user)}`;\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name: user,\n password,\n _id: `org.couchdb.user:${user}`,\n type: 'user',\n roles: [],\n date: new Date().toISOString(),\n }),\n });\n\n const body = (await response.json()) as any;\n\n if (response.status === 201 || response.status === 200 || response.status === 409) {\n const token = body.token;\n if (token) {\n debug('user %s authenticated, token obtained', user);\n return { token, user };\n }\n }\n\n throw new Error(\n `Failed to create/login user \"${user}\" on ${registryUrl}: ${response.status} ${JSON.stringify(body)}`\n );\n}\n\n/**\n * Ping the registry to check it's alive.\n * Uses @verdaccio/registry-cli ping.\n */\nexport async function pingRegistry(registryUrl: string): Promise<boolean> {\n debug('pinging %s', registryUrl);\n try {\n const result = await ping(registryUrl);\n return result.ok;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;AAGA,IAAM,WAAA,GAAA,MAAA,SAAmB,oCAAoC;;;;;;AAY7D,eAAsB,WACpB,aACA,OAAO,YAAY,KAAK,KAAK,IAC7B,WAAW,qBACY;AACvB,SAAM,0BAA0B,MAAM,YAAY;CAClD,MAAM,MAAM,GAAG,YAAY,2BAA2B,mBAAmB,KAAK;CAC9E,MAAM,WAAW,MAAM,MAAM,KAAK;EAChC,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAC/C,MAAM,KAAK,UAAU;GACnB,MAAM;GACN;GACA,KAAK,oBAAoB;GACzB,MAAM;GACN,OAAO,EAAE;GACT,uBAAM,IAAI,MAAM,EAAC,aAAa;GAC/B,CAAC;EACH,CAAC;CAEF,MAAM,OAAQ,MAAM,SAAS,MAAM;AAEnC,KAAI,SAAS,WAAW,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;EACjF,MAAM,QAAQ,KAAK;AACnB,MAAI,OAAO;AACT,WAAM,yCAAyC,KAAK;AACpD,UAAO;IAAE;IAAO;IAAM;;;AAI1B,OAAM,IAAI,MACR,gCAAgC,KAAK,OAAO,YAAY,IAAI,SAAS,OAAO,GAAG,KAAK,UAAU,KAAK,GACpG;;;;;;AAOH,eAAsB,aAAa,aAAuC;AACxE,SAAM,cAAc,YAAY;AAChC,KAAI;AAEF,UADe,OAAA,GAAA,wBAAA,MAAW,YAAY,EACxB;SACR;AACN,SAAO"}
1
+ {"version":3,"file":"registry-client.cjs","names":[],"sources":["../../../src/utils/registry-client.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport { ping } from '@verdaccio/registry-cli';\n\nconst debug = buildDebug('verdaccio:e2e-cli:registry-client');\n\nexport type RegistryAuth = {\n token: string;\n user: string;\n};\n\n/**\n * Creates a user on the registry and returns the auth token.\n * Uses a unique username per run to avoid 409 conflicts.\n * Works against any running Verdaccio instance with htpasswd auth.\n */\nexport async function createUser(\n registryUrl: string,\n user = `e2e-user-${Date.now()}`,\n password = 'e2e-test-password'\n): Promise<RegistryAuth> {\n debug('creating user %s on %s', user, registryUrl);\n const url = `${registryUrl}/-/user/org.couchdb.user:${encodeURIComponent(user)}`;\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name: user,\n password,\n _id: `org.couchdb.user:${user}`,\n type: 'user',\n roles: [],\n date: new Date().toISOString(),\n }),\n });\n\n const body = (await response.json()) as any;\n\n if (response.status === 201 || response.status === 200 || response.status === 409) {\n const token = body.token;\n if (token) {\n debug('user %s authenticated, token obtained', user);\n return { token, user };\n }\n }\n\n throw new Error(\n `Failed to create/login user \"${user}\" on ${registryUrl}: ${response.status} ${JSON.stringify(body)}`\n );\n}\n\n/**\n * Ping the registry to check it's alive.\n * Uses @verdaccio/registry-cli ping.\n */\nexport async function pingRegistry(registryUrl: string): Promise<boolean> {\n debug('pinging %s', registryUrl);\n try {\n const result = await ping(registryUrl);\n return result.ok;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;AAIA,IAAM,WAAA,GAAA,MAAA,SAAmB,oCAAoC;;;;;;AAY7D,eAAsB,WACpB,aACA,OAAO,YAAY,KAAK,KAAK,IAC7B,WAAW,qBACY;AACvB,SAAM,0BAA0B,MAAM,YAAY;CAClD,MAAM,MAAM,GAAG,YAAY,2BAA2B,mBAAmB,KAAK;CAC9E,MAAM,WAAW,MAAM,MAAM,KAAK;EAChC,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAC/C,MAAM,KAAK,UAAU;GACnB,MAAM;GACN;GACA,KAAK,oBAAoB;GACzB,MAAM;GACN,OAAO,EAAE;GACT,uBAAM,IAAI,MAAM,EAAC,aAAa;GAC/B,CAAC;EACH,CAAC;CAEF,MAAM,OAAQ,MAAM,SAAS,MAAM;AAEnC,KAAI,SAAS,WAAW,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;EACjF,MAAM,QAAQ,KAAK;AACnB,MAAI,OAAO;AACT,WAAM,yCAAyC,KAAK;AACpD,UAAO;IAAE;IAAO;IAAM;;;AAI1B,OAAM,IAAI,MACR,gCAAgC,KAAK,OAAO,YAAY,IAAI,SAAS,OAAO,GAAG,KAAK,UAAU,KAAK,GACpG;;;;;;AAOH,eAAsB,aAAa,aAAuC;AACxE,SAAM,cAAc,YAAY;AAChC,KAAI;AAEF,UADe,OAAA,GAAA,wBAAA,MAAW,YAAY,EACxB;SACR;AACN,SAAO"}
@@ -0,0 +1,61 @@
1
+ import { exec } from "../utils/process.js";
2
+ import { prepareGenericEmptyProject } from "../utils/project.js";
3
+ import buildDebug from "debug";
4
+ import { execSync } from "child_process";
5
+ //#region src/adapters/bun.ts
6
+ var debug = buildDebug("verdaccio:e2e-cli:bun");
7
+ var BUN_SUPPORTED_COMMANDS = new Set([
8
+ "publish",
9
+ "install",
10
+ "info",
11
+ "audit"
12
+ ]);
13
+ function detectVersion(bin) {
14
+ try {
15
+ return execSync(`${bin} --version`, {
16
+ encoding: "utf8",
17
+ timeout: 5e3
18
+ }).trim();
19
+ } catch {
20
+ return "unknown";
21
+ }
22
+ }
23
+ function resolveBunBin(binPath) {
24
+ if (binPath) return binPath;
25
+ return "bun";
26
+ }
27
+ function createBunAdapter(binPath, _version) {
28
+ const bin = resolveBunBin(binPath);
29
+ const resolved = detectVersion(bin);
30
+ debug("creating bun adapter with bin: %s (%s)", bin, resolved);
31
+ return {
32
+ name: `bun@${resolved}`,
33
+ type: "bun",
34
+ bin,
35
+ supports: BUN_SUPPORTED_COMMANDS,
36
+ registryArg(url) {
37
+ return ["--registry", url];
38
+ },
39
+ prefixArg(folder) {
40
+ return ["--cwd", folder];
41
+ },
42
+ exec(options, ...args) {
43
+ if (args[0] === "info") {
44
+ const pkgName = args[1];
45
+ return exec(options, bin, [
46
+ "info",
47
+ pkgName,
48
+ ...args.slice(2).filter((a) => a !== "--registry").filter((a) => !a.startsWith("http"))
49
+ ]);
50
+ }
51
+ return exec(options, bin, args);
52
+ },
53
+ async prepareProject(packageName, version, registryUrl, port, token, dependencies = {}, devDependencies = {}) {
54
+ return prepareGenericEmptyProject(packageName, version, port, token, registryUrl, dependencies, devDependencies);
55
+ }
56
+ };
57
+ }
58
+ //#endregion
59
+ export { createBunAdapter };
60
+
61
+ //# sourceMappingURL=bun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun.js","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(['publish', 'install', 'info', 'audit']);\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,QAAQ,WAAW,wBAAwB;AAEjD,IAAM,yBAAyB,IAAI,IAAI;CAAC;CAAW;CAAW;CAAQ;CAAQ,CAAC;AAE/E,SAAS,cAAc,KAAqB;AAC1C,KAAI;AACF,SAAO,SAAS,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,OAAM,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,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,KAAK,SAAS,KAAK,KAAK;;EAGjC,MAAM,eACJ,aACA,SACA,aACA,MACA,OACA,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACX;AACjC,UAAO,2BACL,aACA,SACA,MACA,OACA,aACA,cACA,gBACD;;EAEJ"}
@@ -0,0 +1,56 @@
1
+ import { exec } from "../utils/process.js";
2
+ import { prepareGenericEmptyProject } from "../utils/project.js";
3
+ import buildDebug from "debug";
4
+ import { execSync } from "child_process";
5
+ //#region src/adapters/deno.ts
6
+ var debug = buildDebug("verdaccio:e2e-cli:deno");
7
+ var DENO_SUPPORTED_COMMANDS = new Set(["install", "info"]);
8
+ function detectVersion(bin) {
9
+ try {
10
+ const match = execSync(`${bin} --version`, {
11
+ encoding: "utf8",
12
+ timeout: 5e3
13
+ }).match(/deno (\S+)/);
14
+ return match ? match[1] : "unknown";
15
+ } catch {
16
+ return "unknown";
17
+ }
18
+ }
19
+ function resolveDenoBin(binPath) {
20
+ if (binPath) return binPath;
21
+ return "deno";
22
+ }
23
+ function createDenoAdapter(binPath, _version) {
24
+ const bin = resolveDenoBin(binPath);
25
+ const resolved = detectVersion(bin);
26
+ debug("creating deno adapter with bin: %s (%s)", bin, resolved);
27
+ return {
28
+ name: `deno@${resolved}`,
29
+ type: "deno",
30
+ bin,
31
+ supports: DENO_SUPPORTED_COMMANDS,
32
+ registryArg(_url) {
33
+ return [];
34
+ },
35
+ prefixArg(folder) {
36
+ return ["--root", folder];
37
+ },
38
+ exec(options, ...args) {
39
+ const cmd = args[0];
40
+ if (cmd === "info") return exec(options, bin, [
41
+ "info",
42
+ `npm:${args[1]}`,
43
+ "--node-modules-dir=auto"
44
+ ].concat(args.slice(2).filter((a) => a !== "--json")));
45
+ if (cmd === "install") return exec(options, bin, ["install"]);
46
+ return exec(options, bin, args);
47
+ },
48
+ async prepareProject(packageName, version, registryUrl, port, token, dependencies = {}, devDependencies = {}) {
49
+ return prepareGenericEmptyProject(packageName, version, port, token, registryUrl, dependencies, devDependencies);
50
+ }
51
+ };
52
+ }
53
+ //#endregion
54
+ export { createDenoAdapter };
55
+
56
+ //# sourceMappingURL=deno.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno.js","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,QAAQ,WAAW,yBAAyB;AAElD,IAAM,0BAA0B,IAAI,IAAI,CAAC,WAAW,OAAO,CAAC;AAE5D,SAAS,cAAc,KAAqB;AAC1C,KAAI;EAEF,MAAM,QADS,SAAS,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,OAAM,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,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,KAAK,SAAS,KAAK,CAAC,UAAU,CAAC;AAGxC,UAAO,KAAK,SAAS,KAAK,KAAK;;EAGjC,MAAM,eACJ,aACA,SACA,aACA,MACA,OACA,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACX;AACjC,UAAO,2BACL,aACA,SACA,MACA,OACA,aACA,cACA,gBACD;;EAEJ"}
@@ -1,3 +1,5 @@
1
+ import "./bun.js";
2
+ import "./deno.js";
1
3
  import "./npm.js";
2
4
  import "./pnpm.js";
3
5
  import "./yarn-classic.js";
@@ -1 +1 @@
1
- {"version":3,"file":"yarn-classic.js","names":[],"sources":["../../../src/adapters/yarn-classic.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:yarn-classic');\n\nconst YARN_CLASSIC_SUPPORTED_COMMANDS = new Set([\n 'publish',\n 'install',\n 'info',\n 'audit',\n]);\n\nfunction detectYarnVersion(bin: string): string {\n try {\n return execSync(`${bin} --version`, {\n env: { ...process.env, COREPACK_ENABLE_STRICT: '0', YARN_IGNORE_PATH: '1' },\n encoding: 'utf8',\n timeout: 5000,\n }).trim();\n } catch {\n return 'unknown';\n }\n}\n\nfunction installYarnClassic(version = '1'): string {\n const pkg = version.startsWith('1') ? `yarn@${version}` : `yarn@1`;\n debug('installing %s into temp dir', pkg);\n const tmpDir = execSync('mktemp -d', { encoding: 'utf8' }).trim();\n execSync(`npm install --prefix \"${tmpDir}\" ${pkg} --loglevel=error`, {\n encoding: 'utf8',\n timeout: 30000,\n });\n const bin = `${tmpDir}/node_modules/.bin/yarn`;\n const installed = detectYarnVersion(bin);\n debug('installed yarn %s at %s', installed, bin);\n console.log(` Auto-installed yarn classic ${installed}`);\n return bin;\n}\n\nfunction resolveYarnClassicBin(binPath?: string, version?: string): string {\n if (binPath) return binPath;\n\n // Always install the requested version to ensure reproducibility\n if (version) {\n return installYarnClassic(version);\n }\n\n // Check if system yarn is 1.x\n try {\n const systemYarn = execSync('which yarn', { encoding: 'utf8', timeout: 5000 }).trim();\n const sysVersion = detectYarnVersion(systemYarn);\n const major = sysVersion.split('.')[0];\n if (major === '1') {\n debug('using system yarn classic %s', sysVersion);\n return systemYarn;\n }\n debug('system yarn is Berry %s, auto-installing classic', sysVersion);\n } catch {\n debug('no system yarn found, auto-installing classic');\n }\n\n return installYarnClassic();\n}\n\nexport function createYarnClassicAdapter(binPath?: string, version?: string): PackageManagerAdapter {\n const bin = resolveYarnClassicBin(binPath, version);\n const resolved = detectYarnVersion(bin);\n debug('creating yarn classic adapter with bin: %s (%s)', bin, resolved);\n\n const adapter: PackageManagerAdapter = {\n name: `yarn-classic@${resolved}`,\n type: 'yarn-classic',\n bin,\n supports: YARN_CLASSIC_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 env = {\n ...process.env,\n ...options.env,\n COREPACK_ENABLE_STRICT: '0',\n YARN_IGNORE_PATH: '1',\n };\n return exec({ ...options, env }, 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,QAAQ,WAAW,iCAAiC;AAE1D,IAAM,kCAAkC,IAAI,IAAI;CAC9C;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,kBAAkB,KAAqB;AAC9C,KAAI;AACF,SAAO,SAAS,GAAG,IAAI,aAAa;GAClC,KAAK;IAAE,GAAG,QAAQ;IAAK,wBAAwB;IAAK,kBAAkB;IAAK;GAC3E,UAAU;GACV,SAAS;GACV,CAAC,CAAC,MAAM;SACH;AACN,SAAO;;;AAIX,SAAS,mBAAmB,UAAU,KAAa;CACjD,MAAM,MAAM,QAAQ,WAAW,IAAI,GAAG,QAAQ,YAAY;AAC1D,OAAM,+BAA+B,IAAI;CACzC,MAAM,SAAS,SAAS,aAAa,EAAE,UAAU,QAAQ,CAAC,CAAC,MAAM;AACjE,UAAS,yBAAyB,OAAO,IAAI,IAAI,oBAAoB;EACnE,UAAU;EACV,SAAS;EACV,CAAC;CACF,MAAM,MAAM,GAAG,OAAO;CACtB,MAAM,YAAY,kBAAkB,IAAI;AACxC,OAAM,2BAA2B,WAAW,IAAI;AAChD,SAAQ,IAAI,iCAAiC,YAAY;AACzD,QAAO;;AAGT,SAAS,sBAAsB,SAAkB,SAA0B;AACzE,KAAI,QAAS,QAAO;AAGpB,KAAI,QACF,QAAO,mBAAmB,QAAQ;AAIpC,KAAI;EACF,MAAM,aAAa,SAAS,cAAc;GAAE,UAAU;GAAQ,SAAS;GAAM,CAAC,CAAC,MAAM;EACrF,MAAM,aAAa,kBAAkB,WAAW;AAEhD,MADc,WAAW,MAAM,IAAI,CAAC,OACtB,KAAK;AACjB,SAAM,gCAAgC,WAAW;AACjD,UAAO;;AAET,QAAM,oDAAoD,WAAW;SAC/D;AACN,QAAM,gDAAgD;;AAGxD,QAAO,oBAAoB;;AAG7B,SAAgB,yBAAyB,SAAkB,SAAyC;CAClG,MAAM,MAAM,sBAAsB,SAAS,QAAQ;CACnD,MAAM,WAAW,kBAAkB,IAAI;AACvC,OAAM,mDAAmD,KAAK,SAAS;AA+CvE,QA7CuC;EACrC,MAAM,gBAAgB;EACtB,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;GAClE,MAAM,MAAM;IACV,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,wBAAwB;IACxB,kBAAkB;IACnB;AACD,UAAO,KAAK;IAAE,GAAG;IAAS;IAAK,EAAE,KAAK,KAAK;;EAG7C,MAAM,eACJ,aACA,SACA,aACA,MACA,OACA,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACX;AACjC,UAAO,2BACL,aACA,SACA,MACA,OACA,aACA,cACA,gBACD;;EAEJ"}
1
+ {"version":3,"file":"yarn-classic.js","names":[],"sources":["../../../src/adapters/yarn-classic.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:yarn-classic');\n\nconst YARN_CLASSIC_SUPPORTED_COMMANDS = new Set(['publish', 'install', 'info', 'audit']);\n\nfunction detectYarnVersion(bin: string): string {\n try {\n return execSync(`${bin} --version`, {\n env: { ...process.env, COREPACK_ENABLE_STRICT: '0', YARN_IGNORE_PATH: '1' },\n encoding: 'utf8',\n timeout: 5000,\n }).trim();\n } catch {\n return 'unknown';\n }\n}\n\nfunction installYarnClassic(version = '1'): string {\n const pkg = version.startsWith('1') ? `yarn@${version}` : `yarn@1`;\n debug('installing %s into temp dir', pkg);\n const tmpDir = execSync('mktemp -d', { encoding: 'utf8' }).trim();\n execSync(`npm install --prefix \"${tmpDir}\" ${pkg} --loglevel=error`, {\n encoding: 'utf8',\n timeout: 30000,\n });\n const bin = `${tmpDir}/node_modules/.bin/yarn`;\n const installed = detectYarnVersion(bin);\n debug('installed yarn %s at %s', installed, bin);\n console.log(` Auto-installed yarn classic ${installed}`);\n return bin;\n}\n\nfunction resolveYarnClassicBin(binPath?: string, version?: string): string {\n if (binPath) return binPath;\n\n // Always install the requested version to ensure reproducibility\n if (version) {\n return installYarnClassic(version);\n }\n\n // Check if system yarn is 1.x\n try {\n const systemYarn = execSync('which yarn', { encoding: 'utf8', timeout: 5000 }).trim();\n const sysVersion = detectYarnVersion(systemYarn);\n const major = sysVersion.split('.')[0];\n if (major === '1') {\n debug('using system yarn classic %s', sysVersion);\n return systemYarn;\n }\n debug('system yarn is Berry %s, auto-installing classic', sysVersion);\n } catch {\n debug('no system yarn found, auto-installing classic');\n }\n\n return installYarnClassic();\n}\n\nexport function createYarnClassicAdapter(\n binPath?: string,\n version?: string\n): PackageManagerAdapter {\n const bin = resolveYarnClassicBin(binPath, version);\n const resolved = detectYarnVersion(bin);\n debug('creating yarn classic adapter with bin: %s (%s)', bin, resolved);\n\n const adapter: PackageManagerAdapter = {\n name: `yarn-classic@${resolved}`,\n type: 'yarn-classic',\n bin,\n supports: YARN_CLASSIC_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 env = {\n ...process.env,\n ...options.env,\n COREPACK_ENABLE_STRICT: '0',\n YARN_IGNORE_PATH: '1',\n };\n return exec({ ...options, env }, 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,QAAQ,WAAW,iCAAiC;AAE1D,IAAM,kCAAkC,IAAI,IAAI;CAAC;CAAW;CAAW;CAAQ;CAAQ,CAAC;AAExF,SAAS,kBAAkB,KAAqB;AAC9C,KAAI;AACF,SAAO,SAAS,GAAG,IAAI,aAAa;GAClC,KAAK;IAAE,GAAG,QAAQ;IAAK,wBAAwB;IAAK,kBAAkB;IAAK;GAC3E,UAAU;GACV,SAAS;GACV,CAAC,CAAC,MAAM;SACH;AACN,SAAO;;;AAIX,SAAS,mBAAmB,UAAU,KAAa;CACjD,MAAM,MAAM,QAAQ,WAAW,IAAI,GAAG,QAAQ,YAAY;AAC1D,OAAM,+BAA+B,IAAI;CACzC,MAAM,SAAS,SAAS,aAAa,EAAE,UAAU,QAAQ,CAAC,CAAC,MAAM;AACjE,UAAS,yBAAyB,OAAO,IAAI,IAAI,oBAAoB;EACnE,UAAU;EACV,SAAS;EACV,CAAC;CACF,MAAM,MAAM,GAAG,OAAO;CACtB,MAAM,YAAY,kBAAkB,IAAI;AACxC,OAAM,2BAA2B,WAAW,IAAI;AAChD,SAAQ,IAAI,iCAAiC,YAAY;AACzD,QAAO;;AAGT,SAAS,sBAAsB,SAAkB,SAA0B;AACzE,KAAI,QAAS,QAAO;AAGpB,KAAI,QACF,QAAO,mBAAmB,QAAQ;AAIpC,KAAI;EACF,MAAM,aAAa,SAAS,cAAc;GAAE,UAAU;GAAQ,SAAS;GAAM,CAAC,CAAC,MAAM;EACrF,MAAM,aAAa,kBAAkB,WAAW;AAEhD,MADc,WAAW,MAAM,IAAI,CAAC,OACtB,KAAK;AACjB,SAAM,gCAAgC,WAAW;AACjD,UAAO;;AAET,QAAM,oDAAoD,WAAW;SAC/D;AACN,QAAM,gDAAgD;;AAGxD,QAAO,oBAAoB;;AAG7B,SAAgB,yBACd,SACA,SACuB;CACvB,MAAM,MAAM,sBAAsB,SAAS,QAAQ;CACnD,MAAM,WAAW,kBAAkB,IAAI;AACvC,OAAM,mDAAmD,KAAK,SAAS;AA+CvE,QA7CuC;EACrC,MAAM,gBAAgB;EACtB,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;GAClE,MAAM,MAAM;IACV,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,wBAAwB;IACxB,kBAAkB;IACnB;AACD,UAAO,KAAK;IAAE,GAAG;IAAS;IAAK,EAAE,KAAK,KAAK;;EAG7C,MAAM,eACJ,aACA,SACA,aACA,MACA,OACA,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACX;AACjC,UAAO,2BACL,aACA,SACA,MACA,OACA,aACA,cACA,gBACD;;EAEJ"}
@@ -20,6 +20,20 @@ var YARN_ENV = {
20
20
  COREPACK_ENABLE_STRICT: "0",
21
21
  YARN_IGNORE_PATH: "1"
22
22
  };
23
+ var YARN_BERRY_4_ENV = {
24
+ YARN_ENABLE_HARDENED_MODE: "0",
25
+ YARN_NPM_MINIMAL_AGE_GATE: "0"
26
+ };
27
+ function parseMajor(version) {
28
+ const major = parseInt(version.split(".")[0], 10);
29
+ return Number.isFinite(major) ? major : 0;
30
+ }
31
+ function getYarnEnv(major) {
32
+ return major >= 4 ? {
33
+ ...YARN_ENV,
34
+ ...YARN_BERRY_4_ENV
35
+ } : { ...YARN_ENV };
36
+ }
23
37
  function detectVersion(bin) {
24
38
  try {
25
39
  return execSync(`${bin} --version`, {
@@ -67,12 +81,16 @@ function resolveYarnBin(binPath, version) {
67
81
  }
68
82
  return installYarnModern();
69
83
  }
70
- function createYamlConfig(registry, token) {
84
+ function createYamlConfig(registry, token, major) {
71
85
  const defaultYaml = {
72
86
  npmRegistryServer: registry,
73
87
  enableImmutableInstalls: false,
74
88
  unsafeHttpWhitelist: ["localhost"]
75
89
  };
90
+ if (major >= 4) {
91
+ defaultYaml.enableHardenedMode = false;
92
+ defaultYaml.npmMinimalAgeGate = 0;
93
+ }
76
94
  if (typeof token === "string") {
77
95
  new URL(registry);
78
96
  defaultYaml.npmRegistries = { [registry]: {
@@ -85,6 +103,8 @@ function createYamlConfig(registry, token) {
85
103
  function createYarnModernAdapter(binPath, version) {
86
104
  const bin = resolveYarnBin(binPath, version);
87
105
  const resolved = detectVersion(bin);
106
+ const major = parseMajor(resolved);
107
+ const yarnEnv = getYarnEnv(major);
88
108
  debug("creating yarn modern adapter with bin: %s (%s)", bin, resolved);
89
109
  return {
90
110
  name: `yarn-modern@${resolved}`,
@@ -101,7 +121,7 @@ function createYarnModernAdapter(binPath, version) {
101
121
  const env = {
102
122
  ...process.env,
103
123
  ...options.env,
104
- ...YARN_ENV
124
+ ...yarnEnv
105
125
  };
106
126
  const cmd = args[0];
107
127
  let yarnArgs;
@@ -143,7 +163,7 @@ function createYarnModernAdapter(binPath, version) {
143
163
  },
144
164
  async prepareProject(packageName, version, registryUrl, _port, token, dependencies = {}, devDependencies = {}) {
145
165
  const tempFolder = await createTempFolder(packageName);
146
- const yamlContent = createYamlConfig(registryUrl, token);
166
+ const yamlContent = createYamlConfig(registryUrl, token, major);
147
167
  await writeFile(join(tempFolder, ".yarnrc.yml"), yamlContent);
148
168
  await writeFile(join(tempFolder, "package.json"), getPackageJSON(packageName, version, dependencies, devDependencies));
149
169
  await writeFile(join(tempFolder, "README.md"), getREADME(packageName));
@@ -167,7 +187,7 @@ function createYarnModernAdapter(binPath, version) {
167
187
  cwd,
168
188
  env: {
169
189
  ...process.env,
170
- ...YARN_ENV
190
+ ...yarnEnv
171
191
  }
172
192
  }, bin, [
173
193
  "plugin",
@@ -1 +1 @@
1
- {"version":3,"file":"yarn-modern.js","names":[],"sources":["../../../src/adapters/yarn-modern.ts"],"sourcesContent":["import { SpawnOptions, execSync } from 'child_process';\nimport buildDebug from 'debug';\nimport { writeFile } from 'fs/promises';\nimport YAML from 'js-yaml';\nimport { join } from 'path';\nimport { URL } from 'url';\n\nimport { ExecOutput, PackageManagerAdapter } from '../types';\nimport { exec } from '../utils/process';\nimport { createTempFolder, getPackageJSON, getREADME } from '../utils/project';\n\nconst debug = buildDebug('verdaccio:e2e-cli:yarn-modern');\n\nconst YARN_MODERN_SUPPORTED_COMMANDS = new Set(['publish', 'install', 'info', 'ping', 'deprecate', 'login']);\n\nconst YARN_ENV = {\n COREPACK_ENABLE_STRICT: '0',\n YARN_IGNORE_PATH: '1',\n};\n\nfunction detectVersion(bin: string): string {\n try {\n return execSync(`${bin} --version`, {\n env: { ...process.env, ...YARN_ENV },\n encoding: 'utf8',\n timeout: 5000,\n }).trim();\n } catch {\n return 'unknown';\n }\n}\n\nfunction installYarnModern(version = '4'): string {\n const pkg = `@yarnpkg/cli-dist@${version}`;\n debug('installing %s into temp dir', pkg);\n const tmpDir = execSync('mktemp -d', { encoding: 'utf8' }).trim();\n execSync(`npm install --prefix \"${tmpDir}\" ${pkg} --loglevel=error`, {\n encoding: 'utf8',\n timeout: 30000,\n });\n const bin = `${tmpDir}/node_modules/@yarnpkg/cli-dist/bin/yarn.js`;\n const installed = detectVersion(bin);\n debug('installed yarn modern %s at %s', installed, bin);\n console.log(` Auto-installed yarn modern ${installed}`);\n return bin;\n}\n\nfunction resolveYarnBin(binPath?: string, version?: string): string {\n if (binPath) return binPath;\n\n if (version) {\n return installYarnModern(version);\n }\n\n try {\n const systemYarn = execSync('which yarn', { encoding: 'utf8', timeout: 5000 }).trim();\n const sysVersion = detectVersion(systemYarn);\n const major = parseInt(sysVersion.split('.')[0], 10);\n if (major >= 2) {\n debug('using system yarn Berry %s', sysVersion);\n return systemYarn;\n }\n debug('system yarn is Classic %s, auto-installing Berry', sysVersion);\n } catch {\n debug('no system yarn found, auto-installing Berry');\n }\n\n return installYarnModern();\n}\n\nfunction createYamlConfig(registry: string, token?: string) {\n const defaultYaml: any = {\n npmRegistryServer: registry,\n enableImmutableInstalls: false,\n unsafeHttpWhitelist: ['localhost'],\n };\n\n if (typeof token === 'string') {\n const url = new URL(registry);\n defaultYaml.npmRegistries = {\n [registry]: {\n npmAlwaysAuth: true,\n npmAuthToken: token,\n },\n };\n }\n\n return YAML.dump(defaultYaml);\n}\n\nexport function createYarnModernAdapter(binPath?: string, version?: string): PackageManagerAdapter {\n const bin = resolveYarnBin(binPath, version);\n const resolved = detectVersion(bin);\n debug('creating yarn modern adapter with bin: %s (%s)', bin, resolved);\n\n const adapter: PackageManagerAdapter = {\n name: `yarn-modern@${resolved}`,\n type: 'yarn-modern',\n bin,\n supports: YARN_MODERN_SUPPORTED_COMMANDS,\n\n registryArg(_url: string): string[] {\n return [];\n },\n\n prefixArg(_folder: string): string[] {\n return [];\n },\n\n exec(options: SpawnOptions, ...args: string[]): Promise<ExecOutput> {\n const env = { ...process.env, ...options.env, ...YARN_ENV };\n\n const cmd = args[0];\n let yarnArgs: string[];\n if (cmd === 'publish') {\n const filtered = args.slice(1).filter(\n (a) => a !== '--json' && !a.startsWith('--registry')\n );\n yarnArgs = ['npm', 'publish', ...filtered];\n } else if (cmd === 'info') {\n const filtered = args.slice(1).filter((a) => !a.startsWith('--registry'));\n yarnArgs = ['npm', 'info', ...filtered];\n } else if (cmd === 'ping') {\n const filtered = args.slice(1).filter(\n (a) => !a.startsWith('--registry')\n );\n yarnArgs = ['npm', 'ping', ...filtered];\n } else if (cmd === 'deprecate') {\n const filtered = args.slice(1).filter(\n (a) => !a.startsWith('--registry')\n );\n yarnArgs = ['npm', 'deprecate', ...filtered];\n } else if (cmd === 'login') {\n const filtered = args.slice(1).filter(\n (a) => !a.startsWith('--registry')\n );\n yarnArgs = ['npm', 'login', ...filtered];\n } else if (cmd === 'whoami') {\n const filtered = args.slice(1).filter(\n (a) => !a.startsWith('--registry')\n );\n yarnArgs = ['npm', 'whoami', ...filtered];\n } else {\n yarnArgs = args.filter((a) => !a.startsWith('--registry'));\n }\n\n return exec({ ...options, env }, bin, yarnArgs);\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 const tempFolder = await createTempFolder(packageName);\n const yamlContent = createYamlConfig(registryUrl, token);\n await writeFile(join(tempFolder, '.yarnrc.yml'), yamlContent);\n await writeFile(\n join(tempFolder, 'package.json'),\n getPackageJSON(packageName, version, dependencies, devDependencies)\n );\n await writeFile(join(tempFolder, 'README.md'), getREADME(packageName));\n return { tempFolder };\n },\n\n async importPlugin(cwd: string, pluginName: string): Promise<void> {\n debug('downloading %s plugin bundle', pluginName);\n const tmpDir = execSync('mktemp -d', { encoding: 'utf8' }).trim();\n const pkg = `@verdaccio/yarn-plugin-${pluginName}`;\n execSync(`npm pack ${pkg} --pack-destination \"${tmpDir}\"`, {\n encoding: 'utf8',\n timeout: 30000,\n stdio: 'pipe',\n });\n execSync(`tar xzf \"${tmpDir}\"/*.tgz -C \"${tmpDir}\"`, {\n encoding: 'utf8',\n stdio: 'pipe',\n });\n const bundlePath = join(tmpDir, `package/bundles/@yarnpkg/plugin-${pluginName}.js`);\n debug('importing plugin from %s into %s', bundlePath, cwd);\n await exec({ cwd, env: { ...process.env, ...YARN_ENV } }, bin, [\n 'plugin',\n 'import',\n bundlePath,\n ]);\n },\n };\n\n return adapter;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"yarn-modern.js","names":[],"sources":["../../../src/adapters/yarn-modern.ts"],"sourcesContent":["import { SpawnOptions, execSync } from 'child_process';\nimport buildDebug from 'debug';\nimport { writeFile } from 'fs/promises';\nimport YAML from 'js-yaml';\nimport { join } from 'path';\nimport { URL } from 'url';\n\nimport { ExecOutput, PackageManagerAdapter } from '../types';\nimport { exec } from '../utils/process';\nimport { createTempFolder, getPackageJSON, getREADME } from '../utils/project';\n\nconst debug = buildDebug('verdaccio:e2e-cli:yarn-modern');\n\nconst YARN_MODERN_SUPPORTED_COMMANDS = new Set([\n 'publish',\n 'install',\n 'info',\n 'ping',\n 'deprecate',\n 'login',\n]);\n\nconst YARN_ENV = {\n COREPACK_ENABLE_STRICT: '0',\n YARN_IGNORE_PATH: '1',\n};\n\n// Hardened mode and the minimum-age quarantine are yarn-4-only settings.\n// Yarn 3 errors on unknown configuration keys, so these can only be applied\n// when we know we're driving a 4.x binary.\nconst YARN_BERRY_4_ENV = {\n YARN_ENABLE_HARDENED_MODE: '0',\n YARN_NPM_MINIMAL_AGE_GATE: '0',\n};\n\nfunction parseMajor(version: string): number {\n const major = parseInt(version.split('.')[0], 10);\n return Number.isFinite(major) ? major : 0;\n}\n\nfunction getYarnEnv(major: number): Record<string, string> {\n return major >= 4 ? { ...YARN_ENV, ...YARN_BERRY_4_ENV } : { ...YARN_ENV };\n}\n\nfunction detectVersion(bin: string): string {\n try {\n return execSync(`${bin} --version`, {\n env: { ...process.env, ...YARN_ENV },\n encoding: 'utf8',\n timeout: 5000,\n }).trim();\n } catch {\n return 'unknown';\n }\n}\n\nfunction installYarnModern(version = '4'): string {\n const pkg = `@yarnpkg/cli-dist@${version}`;\n debug('installing %s into temp dir', pkg);\n const tmpDir = execSync('mktemp -d', { encoding: 'utf8' }).trim();\n execSync(`npm install --prefix \"${tmpDir}\" ${pkg} --loglevel=error`, {\n encoding: 'utf8',\n timeout: 30000,\n });\n const bin = `${tmpDir}/node_modules/@yarnpkg/cli-dist/bin/yarn.js`;\n const installed = detectVersion(bin);\n debug('installed yarn modern %s at %s', installed, bin);\n console.log(` Auto-installed yarn modern ${installed}`);\n return bin;\n}\n\nfunction resolveYarnBin(binPath?: string, version?: string): string {\n if (binPath) return binPath;\n\n if (version) {\n return installYarnModern(version);\n }\n\n try {\n const systemYarn = execSync('which yarn', { encoding: 'utf8', timeout: 5000 }).trim();\n const sysVersion = detectVersion(systemYarn);\n const major = parseInt(sysVersion.split('.')[0], 10);\n if (major >= 2) {\n debug('using system yarn Berry %s', sysVersion);\n return systemYarn;\n }\n debug('system yarn is Classic %s, auto-installing Berry', sysVersion);\n } catch {\n debug('no system yarn found, auto-installing Berry');\n }\n\n return installYarnModern();\n}\n\nfunction createYamlConfig(registry: string, token: string | undefined, major: number) {\n const defaultYaml: any = {\n npmRegistryServer: registry,\n enableImmutableInstalls: false,\n unsafeHttpWhitelist: ['localhost'],\n };\n\n // Yarn 4 hardened mode (auto-on for GitHub PR runs) quarantines freshly\n // published packages — every seed package an e2e scenario publishes is\n // exactly the shape it's designed to block. The hardened-mode flag alone\n // isn't enough in 4.15+; the underlying npmMinimalAgeGate must also be\n // pinned to 0. Yarn 3 errors on these keys, so gate by major.\n if (major >= 4) {\n defaultYaml.enableHardenedMode = false;\n defaultYaml.npmMinimalAgeGate = 0;\n }\n\n if (typeof token === 'string') {\n const url = new URL(registry);\n defaultYaml.npmRegistries = {\n [registry]: {\n npmAlwaysAuth: true,\n npmAuthToken: token,\n },\n };\n }\n\n return YAML.dump(defaultYaml);\n}\n\nexport function createYarnModernAdapter(binPath?: string, version?: string): PackageManagerAdapter {\n const bin = resolveYarnBin(binPath, version);\n const resolved = detectVersion(bin);\n const major = parseMajor(resolved);\n const yarnEnv = getYarnEnv(major);\n debug('creating yarn modern adapter with bin: %s (%s)', bin, resolved);\n\n const adapter: PackageManagerAdapter = {\n name: `yarn-modern@${resolved}`,\n type: 'yarn-modern',\n bin,\n supports: YARN_MODERN_SUPPORTED_COMMANDS,\n\n registryArg(_url: string): string[] {\n return [];\n },\n\n prefixArg(_folder: string): string[] {\n return [];\n },\n\n exec(options: SpawnOptions, ...args: string[]): Promise<ExecOutput> {\n const env = { ...process.env, ...options.env, ...yarnEnv };\n\n const cmd = args[0];\n let yarnArgs: string[];\n if (cmd === 'publish') {\n const filtered = args.slice(1).filter((a) => a !== '--json' && !a.startsWith('--registry'));\n yarnArgs = ['npm', 'publish', ...filtered];\n } else if (cmd === 'info') {\n const filtered = args.slice(1).filter((a) => !a.startsWith('--registry'));\n yarnArgs = ['npm', 'info', ...filtered];\n } else if (cmd === 'ping') {\n const filtered = args.slice(1).filter((a) => !a.startsWith('--registry'));\n yarnArgs = ['npm', 'ping', ...filtered];\n } else if (cmd === 'deprecate') {\n const filtered = args.slice(1).filter((a) => !a.startsWith('--registry'));\n yarnArgs = ['npm', 'deprecate', ...filtered];\n } else if (cmd === 'login') {\n const filtered = args.slice(1).filter((a) => !a.startsWith('--registry'));\n yarnArgs = ['npm', 'login', ...filtered];\n } else if (cmd === 'whoami') {\n const filtered = args.slice(1).filter((a) => !a.startsWith('--registry'));\n yarnArgs = ['npm', 'whoami', ...filtered];\n } else {\n yarnArgs = args.filter((a) => !a.startsWith('--registry'));\n }\n\n return exec({ ...options, env }, bin, yarnArgs);\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 const tempFolder = await createTempFolder(packageName);\n const yamlContent = createYamlConfig(registryUrl, token, major);\n await writeFile(join(tempFolder, '.yarnrc.yml'), yamlContent);\n await writeFile(\n join(tempFolder, 'package.json'),\n getPackageJSON(packageName, version, dependencies, devDependencies)\n );\n await writeFile(join(tempFolder, 'README.md'), getREADME(packageName));\n return { tempFolder };\n },\n\n async importPlugin(cwd: string, pluginName: string): Promise<void> {\n debug('downloading %s plugin bundle', pluginName);\n const tmpDir = execSync('mktemp -d', { encoding: 'utf8' }).trim();\n const pkg = `@verdaccio/yarn-plugin-${pluginName}`;\n execSync(`npm pack ${pkg} --pack-destination \"${tmpDir}\"`, {\n encoding: 'utf8',\n timeout: 30000,\n stdio: 'pipe',\n });\n execSync(`tar xzf \"${tmpDir}\"/*.tgz -C \"${tmpDir}\"`, {\n encoding: 'utf8',\n stdio: 'pipe',\n });\n const bundlePath = join(tmpDir, `package/bundles/@yarnpkg/plugin-${pluginName}.js`);\n debug('importing plugin from %s into %s', bundlePath, cwd);\n await exec({ cwd, env: { ...process.env, ...yarnEnv } }, bin, [\n 'plugin',\n 'import',\n bundlePath,\n ]);\n },\n };\n\n return adapter;\n}\n"],"mappings":"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"}
@@ -1,12 +1,14 @@
1
+ import { createBunAdapter } from "./adapters/bun.js";
2
+ import { createDenoAdapter } from "./adapters/deno.js";
1
3
  import { createNpmAdapter } from "./adapters/npm.js";
2
4
  import { createPnpmAdapter } from "./adapters/pnpm.js";
3
5
  import { createYarnClassicAdapter } from "./adapters/yarn-classic.js";
4
6
  import { createYarnModernAdapter } from "./adapters/yarn-modern.js";
5
7
  import "./adapters/index.js";
8
+ import { runAll, runSuite } from "./runner.js";
6
9
  import { allScenarios } from "./scenarios/index.js";
7
10
  import { allTests } from "./tests/index.js";
8
11
  import { createUser, pingRegistry } from "./utils/registry-client.js";
9
- import { runAll, runSuite } from "./runner.js";
10
12
  import buildDebug from "debug";
11
13
  //#region src/index.ts
12
14
  buildDebug("verdaccio:e2e-cli");
@@ -32,7 +34,9 @@ function parseAdapters(pmFilters) {
32
34
  else if (name === "pnpm") adapters.push(createPnpmAdapter(binPath, version));
33
35
  else if (name === "yarn-classic" || name === "yarn1") adapters.push(createYarnClassicAdapter(binPath, version));
34
36
  else if (name === "yarn-modern" || name === "yarn") adapters.push(createYarnModernAdapter(binPath, version));
35
- else throw new Error(`Unknown package manager: "${name}". Supported: npm, pnpm, yarn-classic, yarn-modern[@version]`);
37
+ else if (name === "bun") adapters.push(createBunAdapter(binPath, version));
38
+ else if (name === "deno") adapters.push(createDenoAdapter(binPath, version));
39
+ else throw new Error(`Unknown package manager: "${name}". Supported: npm, pnpm, yarn-classic, yarn-modern, bun, deno`);
36
40
  }
37
41
  return adapters;
38
42
  }
@@ -82,11 +86,12 @@ function printHelp() {
82
86
 
83
87
  Options:
84
88
  --pm <name[@version]> Package manager to test (can be repeated)
85
- Supported: npm, pnpm, yarn-classic, yarn-modern (or yarn)
89
+ Supported: npm, pnpm, yarn-classic, yarn-modern (or yarn), bun, deno
86
90
  Examples: --pm npm@10 --pm pnpm@9
87
91
  --pm yarn-modern@4
88
92
  --pm yarn-modern@3
89
93
  --pm yarn-classic
94
+ --pm bun
90
95
  --pm npm --pm pnpm (uses system version)
91
96
  Auto-installs the requested yarn version if needed
92
97
  Default: npm
@@ -142,6 +147,6 @@ async function main(argv = process.argv) {
142
147
  process.exit(exitCode);
143
148
  }
144
149
  //#endregion
145
- export { allScenarios, allTests, createNpmAdapter, createPnpmAdapter, createYarnClassicAdapter, createYarnModernAdapter, main, runAll, runSuite };
150
+ export { allScenarios, allTests, createBunAdapter, createDenoAdapter, createNpmAdapter, createPnpmAdapter, createYarnClassicAdapter, createYarnModernAdapter, main, runAll, runSuite };
146
151
 
147
152
  //# sourceMappingURL=index.js.map