@verdaccio/e2e-cli 2.10.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1591 -0
- package/Cargo.toml +19 -0
- package/bin/e2e-cli.js +26 -6
- package/build/bin/verdaccio-e2e +0 -0
- package/build/cjs/index.cjs +11 -166
- package/build/esm/index.js +10 -153
- package/build/index.d.ts +15 -6
- package/package.json +14 -16
- package/scripts/build-js-package.mjs +25 -0
- package/src/e2e_tests/audit.rs +51 -0
- package/src/e2e_tests/ci.rs +32 -0
- package/src/e2e_tests/deprecate.rs +64 -0
- package/src/e2e_tests/dist_tags.rs +56 -0
- package/src/e2e_tests/info.rs +43 -0
- package/src/e2e_tests/install.rs +27 -0
- package/src/e2e_tests/login.rs +64 -0
- package/src/e2e_tests/mod.rs +104 -0
- package/src/e2e_tests/ping.rs +33 -0
- package/src/e2e_tests/publish.rs +68 -0
- package/src/e2e_tests/search.rs +14 -0
- package/src/e2e_tests/unpublish.rs +37 -0
- package/src/main.rs +1411 -0
- package/src/scenarios/install_multiple_deps.rs +99 -0
- package/src/scenarios/minimum_release_age.rs +45 -0
- package/src/scenarios/mod.rs +11 -0
- package/build/adapters/adapter.d.ts +0 -1
- package/build/adapters/bun.d.ts +0 -2
- package/build/adapters/deno.d.ts +0 -2
- package/build/adapters/index.d.ts +0 -6
- package/build/adapters/npm.d.ts +0 -2
- package/build/adapters/pnpm.d.ts +0 -2
- package/build/adapters/yarn-classic.d.ts +0 -2
- package/build/adapters/yarn-modern.d.ts +0 -2
- package/build/cjs/_virtual/_rolldown/runtime.cjs +0 -23
- package/build/cjs/adapters/bun.cjs +0 -63
- package/build/cjs/adapters/bun.cjs.map +0 -1
- package/build/cjs/adapters/deno.cjs +0 -58
- package/build/cjs/adapters/deno.cjs.map +0 -1
- package/build/cjs/adapters/index.cjs +0 -6
- package/build/cjs/adapters/npm.cjs +0 -75
- package/build/cjs/adapters/npm.cjs.map +0 -1
- package/build/cjs/adapters/pnpm.cjs +0 -104
- package/build/cjs/adapters/pnpm.cjs.map +0 -1
- package/build/cjs/adapters/yarn-classic.cjs +0 -98
- package/build/cjs/adapters/yarn-classic.cjs.map +0 -1
- package/build/cjs/adapters/yarn-modern.cjs +0 -206
- package/build/cjs/adapters/yarn-modern.cjs.map +0 -1
- package/build/cjs/index.cjs.map +0 -1
- package/build/cjs/reporter.cjs +0 -113
- package/build/cjs/reporter.cjs.map +0 -1
- package/build/cjs/runner.cjs +0 -141
- package/build/cjs/runner.cjs.map +0 -1
- package/build/cjs/scenarios/index.cjs +0 -8
- package/build/cjs/scenarios/index.cjs.map +0 -1
- package/build/cjs/scenarios/install-multiple-deps.cjs +0 -116
- package/build/cjs/scenarios/install-multiple-deps.cjs.map +0 -1
- package/build/cjs/scenarios/minimum-release-age.cjs +0 -112
- package/build/cjs/scenarios/minimum-release-age.cjs.map +0 -1
- package/build/cjs/tests/audit.cjs +0 -47
- package/build/cjs/tests/audit.cjs.map +0 -1
- package/build/cjs/tests/ci.cjs +0 -83
- package/build/cjs/tests/ci.cjs.map +0 -1
- package/build/cjs/tests/deprecate.cjs +0 -107
- package/build/cjs/tests/deprecate.cjs.map +0 -1
- package/build/cjs/tests/dist-tags.cjs +0 -43
- package/build/cjs/tests/dist-tags.cjs.map +0 -1
- package/build/cjs/tests/index.cjs +0 -33
- package/build/cjs/tests/index.cjs.map +0 -1
- package/build/cjs/tests/info.cjs +0 -41
- package/build/cjs/tests/info.cjs.map +0 -1
- package/build/cjs/tests/install.cjs +0 -27
- package/build/cjs/tests/install.cjs.map +0 -1
- package/build/cjs/tests/login.cjs +0 -117
- package/build/cjs/tests/login.cjs.map +0 -1
- package/build/cjs/tests/ping.cjs +0 -30
- package/build/cjs/tests/ping.cjs.map +0 -1
- package/build/cjs/tests/publish.cjs +0 -37
- package/build/cjs/tests/publish.cjs.map +0 -1
- package/build/cjs/tests/search.cjs +0 -19
- package/build/cjs/tests/search.cjs.map +0 -1
- package/build/cjs/tests/unpublish.cjs +0 -40
- package/build/cjs/tests/unpublish.cjs.map +0 -1
- package/build/cjs/utils/process.cjs +0 -85
- package/build/cjs/utils/process.cjs.map +0 -1
- package/build/cjs/utils/project.cjs +0 -55
- package/build/cjs/utils/project.cjs.map +0 -1
- package/build/cjs/utils/registry-client.cjs +0 -56
- package/build/cjs/utils/registry-client.cjs.map +0 -1
- package/build/esm/adapters/bun.js +0 -61
- package/build/esm/adapters/bun.js.map +0 -1
- package/build/esm/adapters/deno.js +0 -56
- package/build/esm/adapters/deno.js.map +0 -1
- package/build/esm/adapters/index.js +0 -7
- package/build/esm/adapters/npm.js +0 -73
- package/build/esm/adapters/npm.js.map +0 -1
- package/build/esm/adapters/pnpm.js +0 -102
- package/build/esm/adapters/pnpm.js.map +0 -1
- package/build/esm/adapters/yarn-classic.js +0 -96
- package/build/esm/adapters/yarn-classic.js.map +0 -1
- package/build/esm/adapters/yarn-modern.js +0 -203
- package/build/esm/adapters/yarn-modern.js.map +0 -1
- package/build/esm/index.js.map +0 -1
- package/build/esm/reporter.js +0 -107
- package/build/esm/reporter.js.map +0 -1
- package/build/esm/runner.js +0 -138
- package/build/esm/runner.js.map +0 -1
- package/build/esm/scenarios/index.js +0 -8
- package/build/esm/scenarios/index.js.map +0 -1
- package/build/esm/scenarios/install-multiple-deps.js +0 -113
- package/build/esm/scenarios/install-multiple-deps.js.map +0 -1
- package/build/esm/scenarios/minimum-release-age.js +0 -109
- package/build/esm/scenarios/minimum-release-age.js.map +0 -1
- package/build/esm/tests/audit.js +0 -44
- package/build/esm/tests/audit.js.map +0 -1
- package/build/esm/tests/ci.js +0 -80
- package/build/esm/tests/ci.js.map +0 -1
- package/build/esm/tests/deprecate.js +0 -104
- package/build/esm/tests/deprecate.js.map +0 -1
- package/build/esm/tests/dist-tags.js +0 -41
- package/build/esm/tests/dist-tags.js.map +0 -1
- package/build/esm/tests/index.js +0 -33
- package/build/esm/tests/index.js.map +0 -1
- package/build/esm/tests/info.js +0 -39
- package/build/esm/tests/info.js.map +0 -1
- package/build/esm/tests/install.js +0 -25
- package/build/esm/tests/install.js.map +0 -1
- package/build/esm/tests/login.js +0 -113
- package/build/esm/tests/login.js.map +0 -1
- package/build/esm/tests/ping.js +0 -28
- package/build/esm/tests/ping.js.map +0 -1
- package/build/esm/tests/publish.js +0 -35
- package/build/esm/tests/publish.js.map +0 -1
- package/build/esm/tests/search.js +0 -17
- package/build/esm/tests/search.js.map +0 -1
- package/build/esm/tests/unpublish.js +0 -38
- package/build/esm/tests/unpublish.js.map +0 -1
- package/build/esm/utils/process.js +0 -82
- package/build/esm/utils/process.js.map +0 -1
- package/build/esm/utils/project.js +0 -50
- package/build/esm/utils/project.js.map +0 -1
- package/build/esm/utils/registry-client.js +0 -53
- package/build/esm/utils/registry-client.js.map +0 -1
- package/build/reporter.d.ts +0 -7
- package/build/runner.d.ts +0 -13
- package/build/scenarios/index.d.ts +0 -5
- package/build/scenarios/install-multiple-deps.d.ts +0 -2
- package/build/scenarios/minimum-release-age.d.ts +0 -11
- package/build/tests/audit.d.ts +0 -2
- package/build/tests/ci.d.ts +0 -2
- package/build/tests/deprecate.d.ts +0 -2
- package/build/tests/dist-tags.d.ts +0 -2
- package/build/tests/index.d.ts +0 -15
- package/build/tests/info.d.ts +0 -2
- package/build/tests/install.d.ts +0 -2
- package/build/tests/login.d.ts +0 -2
- package/build/tests/ping.d.ts +0 -2
- package/build/tests/publish.d.ts +0 -2
- package/build/tests/search.d.ts +0 -2
- package/build/tests/unpublish.d.ts +0 -2
- package/build/types.d.ts +0 -81
- package/build/utils/index.d.ts +0 -3
- package/build/utils/process.d.ts +0 -4
- package/build/utils/project.d.ts +0 -6
- package/build/utils/registry-client.d.ts +0 -15
package/build/esm/tests/info.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { createTempFolder } from "../utils/project.js";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { writeFile } from "fs/promises";
|
|
4
|
-
import assert from "assert";
|
|
5
|
-
//#region src/tests/info.ts
|
|
6
|
-
async function testInfo(ctx) {
|
|
7
|
-
const tempFolder = await createTempFolder("info-test");
|
|
8
|
-
await writeFile(join(tempFolder, "package.json"), JSON.stringify({
|
|
9
|
-
name: "info-test",
|
|
10
|
-
version: "1.0.0"
|
|
11
|
-
}));
|
|
12
|
-
const resp = await ctx.adapter.exec({ cwd: tempFolder }, "info", "verdaccio", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
13
|
-
if (ctx.adapter.type === "yarn-classic") {
|
|
14
|
-
const dataLine = resp.stdout.split("\n").filter(Boolean).find((l) => {
|
|
15
|
-
try {
|
|
16
|
-
return JSON.parse(l).type === "inspect";
|
|
17
|
-
} catch {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
assert.ok(dataLine, "Expected yarn info NDJSON to contain an \"inspect\" entry");
|
|
22
|
-
} else if (ctx.adapter.type === "deno") {
|
|
23
|
-
const output = resp.stdout + resp.stderr;
|
|
24
|
-
assert.ok(output.includes("verdaccio"), "Expected deno info output to reference verdaccio");
|
|
25
|
-
} else {
|
|
26
|
-
const parsedBody = JSON.parse(resp.stdout);
|
|
27
|
-
assert.strictEqual(parsedBody.name, "verdaccio", "Expected package name \"verdaccio\"");
|
|
28
|
-
assert.ok(parsedBody.dependencies !== void 0, "Expected \"dependencies\" to be defined");
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
var infoTest = {
|
|
32
|
-
name: "info",
|
|
33
|
-
requires: ["info"],
|
|
34
|
-
run: testInfo
|
|
35
|
-
};
|
|
36
|
-
//#endregion
|
|
37
|
-
export { infoTest };
|
|
38
|
-
|
|
39
|
-
//# sourceMappingURL=info.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"info.js","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,iBAAiB,YAAY;CACtD,MAAM,UACJ,KAAK,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;CAED,IAAI,IAAI,QAAQ,SAAS,gBAAgB;EAEvC,MAAM,WADQ,KAAK,OAAO,MAAM,KAAK,CAAC,OAAO,QAC5B,CAAM,MAAM,MAAM;GACjC,IAAI;IAEF,OADY,KAAK,MAAM,EAChB,CAAI,SAAS;WACd;IACN,OAAO;;IAET;EACF,OAAO,GAAG,UAAU,4DAA0D;QACzE,IAAI,IAAI,QAAQ,SAAS,QAAQ;EAEtC,MAAM,SAAS,KAAK,SAAS,KAAK;EAClC,OAAO,GAAG,OAAO,SAAS,YAAY,EAAE,mDAAmD;QACtF;EACL,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;EAC1C,OAAO,YAAY,WAAW,MAAM,aAAa,sCAAoC;EACrF,OAAO,GAAG,WAAW,iBAAiB,KAAA,GAAW,0CAAwC;;;AAI7F,IAAa,WAA2B;CACtC,MAAM;CACN,UAAU,CAAC,OAAO;CAClB,KAAK;CACN"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
//#region src/tests/install.ts
|
|
3
|
-
async function testInstall(ctx) {
|
|
4
|
-
const { tempFolder } = await ctx.adapter.prepareProject(`install-test-${ctx.runId}`, "1.0.0", ctx.registryUrl, ctx.port, ctx.token, { react: "18.2.0" });
|
|
5
|
-
const isNpm = ctx.adapter.type === "npm";
|
|
6
|
-
const args = isNpm ? [
|
|
7
|
-
"install",
|
|
8
|
-
"--json",
|
|
9
|
-
...ctx.adapter.registryArg(ctx.registryUrl)
|
|
10
|
-
] : ["install", ...ctx.adapter.registryArg(ctx.registryUrl)];
|
|
11
|
-
const resp = await ctx.adapter.exec({ cwd: tempFolder }, ...args);
|
|
12
|
-
if (isNpm) {
|
|
13
|
-
const parsedBody = JSON.parse(resp.stdout);
|
|
14
|
-
assert.ok(parsedBody.added !== void 0, "Expected \"added\" field in install response");
|
|
15
|
-
} else assert.ok(true, "Install completed successfully");
|
|
16
|
-
}
|
|
17
|
-
var installTest = {
|
|
18
|
-
name: "install",
|
|
19
|
-
requires: ["install"],
|
|
20
|
-
run: testInstall
|
|
21
|
-
};
|
|
22
|
-
//#endregion
|
|
23
|
-
export { installTest };
|
|
24
|
-
|
|
25
|
-
//# sourceMappingURL=install.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","names":[],"sources":["../../../src/tests/install.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testInstall(ctx: TestContext): Promise<void> {\n const { tempFolder } = await ctx.adapter.prepareProject(\n `install-test-${ctx.runId}`,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token,\n { react: '18.2.0' }\n );\n\n const isNpm = ctx.adapter.type === 'npm';\n\n // pnpm doesn't support --json on install\n const args = isNpm\n ? ['install', '--json', ...ctx.adapter.registryArg(ctx.registryUrl)]\n : ['install', ...ctx.adapter.registryArg(ctx.registryUrl)];\n\n const resp = await ctx.adapter.exec({ cwd: tempFolder }, ...args);\n\n if (isNpm) {\n const parsedBody = JSON.parse(resp.stdout);\n assert.ok(parsedBody.added !== undefined, 'Expected \"added\" field in install response');\n } else {\n // for pnpm/yarn just verify it completed without error (exit code 0)\n assert.ok(true, 'Install completed successfully');\n }\n}\n\nexport const installTest: TestDefinition = {\n name: 'install',\n requires: ['install'],\n run: testInstall,\n};\n"],"mappings":";;AAIA,eAAe,YAAY,KAAiC;CAC1D,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,gBAAgB,IAAI,SACpB,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,OACJ,EAAE,OAAO,UAAU,CACpB;CAED,MAAM,QAAQ,IAAI,QAAQ,SAAS;CAGnC,MAAM,OAAO,QACT;EAAC;EAAW;EAAU,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY;EAAC,GAClE,CAAC,WAAW,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAAC;CAE5D,MAAM,OAAO,MAAM,IAAI,QAAQ,KAAK,EAAE,KAAK,YAAY,EAAE,GAAG,KAAK;CAEjE,IAAI,OAAO;EACT,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;EAC1C,OAAO,GAAG,WAAW,UAAU,KAAA,GAAW,+CAA6C;QAGvF,OAAO,GAAG,MAAM,iCAAiC;;AAIrD,IAAa,cAA8B;CACzC,MAAM;CACN,UAAU,CAAC,UAAU;CACrB,KAAK;CACN"}
|
package/build/esm/tests/login.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { createTempFolder, getPackageJSON, getREADME } from "../utils/project.js";
|
|
2
|
-
import buildDebug from "debug";
|
|
3
|
-
import { join } from "path";
|
|
4
|
-
import { writeFile } from "fs/promises";
|
|
5
|
-
import YAML from "js-yaml";
|
|
6
|
-
import assert from "assert";
|
|
7
|
-
//#region src/tests/login.ts
|
|
8
|
-
var debug = buildDebug("verdaccio:e2e-cli:test:login");
|
|
9
|
-
/**
|
|
10
|
-
* Creates a project with registry config but WITHOUT auth token,
|
|
11
|
-
* so whoami will use the token saved by login to ~/.yarnrc.yml.
|
|
12
|
-
*/
|
|
13
|
-
async function prepareLoginProject(ctx, name) {
|
|
14
|
-
debug("preparing project for %s (no auth token)", name);
|
|
15
|
-
const tempFolder = await createTempFolder(name);
|
|
16
|
-
const yamlContent = YAML.dump({
|
|
17
|
-
npmRegistryServer: ctx.registryUrl,
|
|
18
|
-
enableImmutableInstalls: false,
|
|
19
|
-
unsafeHttpWhitelist: ["localhost"]
|
|
20
|
-
});
|
|
21
|
-
await writeFile(join(tempFolder, ".yarnrc.yml"), yamlContent);
|
|
22
|
-
await writeFile(join(tempFolder, "package.json"), JSON.stringify({
|
|
23
|
-
name,
|
|
24
|
-
version: "1.0.0"
|
|
25
|
-
}));
|
|
26
|
-
if (ctx.adapter.importPlugin) {
|
|
27
|
-
debug("importing npm-login plugin into %s", tempFolder);
|
|
28
|
-
await ctx.adapter.importPlugin(tempFolder, "npm-login");
|
|
29
|
-
}
|
|
30
|
-
return tempFolder;
|
|
31
|
-
}
|
|
32
|
-
async function yarnLogin(ctx, cwd, user, password, email) {
|
|
33
|
-
debug("yarn npm login as %s", user);
|
|
34
|
-
return ctx.adapter.exec({ cwd }, "login", "--auth-type=legacy", `--user=${user}`, `--password=${password}`, `--email=${email}`);
|
|
35
|
-
}
|
|
36
|
-
async function yarnWhoami(ctx, cwd) {
|
|
37
|
-
const resp = await ctx.adapter.exec({ cwd }, "whoami");
|
|
38
|
-
debug("yarn npm whoami: %s", resp.stdout);
|
|
39
|
-
return resp.stdout;
|
|
40
|
-
}
|
|
41
|
-
async function testLogin(ctx) {
|
|
42
|
-
const type = ctx.adapter.type;
|
|
43
|
-
const id = ctx.runId;
|
|
44
|
-
if (type !== "yarn-modern") {
|
|
45
|
-
debug("login test only supported for yarn-modern, skipping %s", type);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const user1 = `login-a-${id}`;
|
|
49
|
-
const password1 = "test-password-123";
|
|
50
|
-
const email1 = `${user1}@test.example.com`;
|
|
51
|
-
await ctx.subTest("create new user + whoami", async () => {
|
|
52
|
-
const tf = await prepareLoginProject(ctx, `verdaccio-login1-${id}`);
|
|
53
|
-
const loginResp = await yarnLogin(ctx, tf, user1, password1, email1);
|
|
54
|
-
assert.ok(loginResp.stdout.includes("Logged in") || loginResp.stdout.includes("token saved"), `Expected login success message but got "${loginResp.stdout}"`);
|
|
55
|
-
const who = await yarnWhoami(ctx, tf);
|
|
56
|
-
assert.ok(who.includes(user1), `Expected whoami "${user1}" but got "${who}"`);
|
|
57
|
-
});
|
|
58
|
-
await ctx.subTest("login existing user", async () => {
|
|
59
|
-
const tf = await prepareLoginProject(ctx, `verdaccio-login2-${id}`);
|
|
60
|
-
const loginResp = await yarnLogin(ctx, tf, user1, password1, email1);
|
|
61
|
-
assert.ok(loginResp.stdout.includes("Logged in") || loginResp.stdout.includes("token saved"), `Expected login success for existing user but got "${loginResp.stdout}"`);
|
|
62
|
-
const who = await yarnWhoami(ctx, tf);
|
|
63
|
-
assert.ok(who.includes(user1), `Expected "${user1}" but got "${who}"`);
|
|
64
|
-
});
|
|
65
|
-
await ctx.subTest("wrong password fails", async () => {
|
|
66
|
-
const tf = await prepareLoginProject(ctx, `verdaccio-login3-${id}`);
|
|
67
|
-
let loginFailed = false;
|
|
68
|
-
try {
|
|
69
|
-
await yarnLogin(ctx, tf, user1, "wrong-password", email1);
|
|
70
|
-
} catch {
|
|
71
|
-
loginFailed = true;
|
|
72
|
-
}
|
|
73
|
-
assert.ok(loginFailed, "Login with wrong password should have failed");
|
|
74
|
-
});
|
|
75
|
-
await ctx.subTest("login then publish", async () => {
|
|
76
|
-
const pkgName = `@verdaccio/login-pub-${id}`;
|
|
77
|
-
const tf = await createTempFolder(`login-pub-${id}`);
|
|
78
|
-
const yamlContent = YAML.dump({
|
|
79
|
-
npmRegistryServer: ctx.registryUrl,
|
|
80
|
-
enableImmutableInstalls: false,
|
|
81
|
-
unsafeHttpWhitelist: ["localhost"]
|
|
82
|
-
});
|
|
83
|
-
await writeFile(join(tf, ".yarnrc.yml"), yamlContent);
|
|
84
|
-
await writeFile(join(tf, "package.json"), getPackageJSON(pkgName, "1.0.0"));
|
|
85
|
-
await writeFile(join(tf, "README.md"), getREADME(pkgName));
|
|
86
|
-
if (ctx.adapter.importPlugin) await ctx.adapter.importPlugin(tf, "npm-login");
|
|
87
|
-
await yarnLogin(ctx, tf, user1, password1, email1);
|
|
88
|
-
await ctx.adapter.exec({ cwd: tf }, "install");
|
|
89
|
-
const pubResp = await ctx.adapter.exec({ cwd: tf }, "publish");
|
|
90
|
-
assert.ok(pubResp.stdout.includes("Package archive published"), `Expected publish success but got "${pubResp.stdout}"`);
|
|
91
|
-
});
|
|
92
|
-
await ctx.subTest("switch users", async () => {
|
|
93
|
-
const user2 = `login-b-${id}`;
|
|
94
|
-
const password2 = "other-password-456";
|
|
95
|
-
const email2 = `${user2}@test.example.com`;
|
|
96
|
-
const tf = await prepareLoginProject(ctx, `verdaccio-login5-${id}`);
|
|
97
|
-
await yarnLogin(ctx, tf, user1, password1, email1);
|
|
98
|
-
const who1 = await yarnWhoami(ctx, tf);
|
|
99
|
-
assert.ok(who1.includes(user1), `Expected "${user1}" but got "${who1}"`);
|
|
100
|
-
await yarnLogin(ctx, tf, user2, password2, email2);
|
|
101
|
-
const who2 = await yarnWhoami(ctx, tf);
|
|
102
|
-
assert.ok(who2.includes(user2), `Expected "${user2}" after switch but got "${who2}"`);
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
var loginTest = {
|
|
106
|
-
name: "login",
|
|
107
|
-
requires: ["login"],
|
|
108
|
-
run: testLogin
|
|
109
|
-
};
|
|
110
|
-
//#endregion
|
|
111
|
-
export { loginTest };
|
|
112
|
-
|
|
113
|
-
//# sourceMappingURL=login.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","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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"}
|
package/build/esm/tests/ping.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
//#region src/tests/ping.ts
|
|
3
|
-
async function testPing(ctx) {
|
|
4
|
-
const type = ctx.adapter.type;
|
|
5
|
-
const needsProject = type === "yarn-modern";
|
|
6
|
-
let cwd;
|
|
7
|
-
if (needsProject) {
|
|
8
|
-
const { tempFolder } = await ctx.adapter.prepareProject(`verdaccio-ping-${ctx.runId}`, "1.0.0", ctx.registryUrl, ctx.port, ctx.token);
|
|
9
|
-
cwd = tempFolder;
|
|
10
|
-
if (ctx.adapter.importPlugin) await ctx.adapter.importPlugin(tempFolder, "npm-ping");
|
|
11
|
-
}
|
|
12
|
-
const jsonFlag = type === "yarn-modern" ? [] : ["--json"];
|
|
13
|
-
const resp = await ctx.adapter.exec({ cwd }, "ping", ...jsonFlag, ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
14
|
-
if (type === "yarn-modern") assert.ok(true, "ping succeeded");
|
|
15
|
-
else {
|
|
16
|
-
const parsedBody = JSON.parse(resp.stdout);
|
|
17
|
-
assert.strictEqual(parsedBody.registry, ctx.registryUrl + "/", `Expected registry "${ctx.registryUrl}/" but got "${parsedBody.registry}"`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
var pingTest = {
|
|
21
|
-
name: "ping",
|
|
22
|
-
requires: ["ping"],
|
|
23
|
-
run: testPing
|
|
24
|
-
};
|
|
25
|
-
//#endregion
|
|
26
|
-
export { pingTest };
|
|
27
|
-
|
|
28
|
-
//# sourceMappingURL=ping.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ping.js","names":[],"sources":["../../../src/tests/ping.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testPing(ctx: TestContext): Promise<void> {\n const type = ctx.adapter.type;\n const needsProject = type === 'yarn-modern';\n let cwd: string | undefined;\n\n if (needsProject) {\n const { tempFolder } = await ctx.adapter.prepareProject(\n `verdaccio-ping-${ctx.runId}`,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token\n );\n cwd = tempFolder;\n if (ctx.adapter.importPlugin) {\n await ctx.adapter.importPlugin(tempFolder, 'npm-ping');\n }\n }\n\n const jsonFlag = type === 'yarn-modern' ? [] : ['--json'];\n const resp = await ctx.adapter.exec(\n { cwd },\n 'ping',\n ...jsonFlag,\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n\n if (type === 'yarn-modern') {\n // yarn npm ping succeeding (exit code 0) is sufficient proof the registry is reachable\n assert.ok(true, 'ping succeeded');\n } else {\n const parsedBody = JSON.parse(resp.stdout);\n assert.strictEqual(\n parsedBody.registry,\n ctx.registryUrl + '/',\n `Expected registry \"${ctx.registryUrl}/\" but got \"${parsedBody.registry}\"`\n );\n }\n}\n\nexport const pingTest: TestDefinition = {\n name: 'ping',\n requires: ['ping'],\n run: testPing,\n};\n"],"mappings":";;AAIA,eAAe,SAAS,KAAiC;CACvD,MAAM,OAAO,IAAI,QAAQ;CACzB,MAAM,eAAe,SAAS;CAC9B,IAAI;CAEJ,IAAI,cAAc;EAChB,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,kBAAkB,IAAI,SACtB,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;EACD,MAAM;EACN,IAAI,IAAI,QAAQ,cACd,MAAM,IAAI,QAAQ,aAAa,YAAY,WAAW;;CAI1D,MAAM,WAAW,SAAS,gBAAgB,EAAE,GAAG,CAAC,SAAS;CACzD,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,EACP,QACA,GAAG,UACH,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;CAED,IAAI,SAAS,eAEX,OAAO,GAAG,MAAM,iBAAiB;MAC5B;EACL,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;EAC1C,OAAO,YACL,WAAW,UACX,IAAI,cAAc,KAClB,sBAAsB,IAAI,YAAY,cAAc,WAAW,SAAS,GACzE;;;AAIL,IAAa,WAA2B;CACtC,MAAM;CACN,UAAU,CAAC,OAAO;CAClB,KAAK;CACN"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
//#region src/tests/publish.ts
|
|
3
|
-
async function testPublish(ctx) {
|
|
4
|
-
const packages = [
|
|
5
|
-
`verdaccio-memory-${ctx.runId}`,
|
|
6
|
-
`verdaccio-${ctx.runId}`,
|
|
7
|
-
`@verdaccio/foo-${ctx.runId}`,
|
|
8
|
-
`@verdaccio/some-foo-${ctx.runId}`
|
|
9
|
-
];
|
|
10
|
-
const type = ctx.adapter.type;
|
|
11
|
-
for (const pkgName of packages) {
|
|
12
|
-
const { tempFolder } = await ctx.adapter.prepareProject(pkgName, "1.0.0", ctx.registryUrl, ctx.port, ctx.token);
|
|
13
|
-
if (type === "yarn-modern") await ctx.adapter.exec({ cwd: tempFolder }, "install");
|
|
14
|
-
const resp = await ctx.adapter.exec({ cwd: tempFolder }, "publish", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
15
|
-
if (type === "yarn-modern") assert.ok(resp.stdout.match(/Package archive published/), `Expected "Package archive published" for ${pkgName} but got "${resp.stdout}"`);
|
|
16
|
-
else if (type === "yarn-classic") assert.ok(resp.stdout.length > 0, `Expected publish output for ${pkgName}`);
|
|
17
|
-
else if (type === "bun") assert.ok(true, `Publish succeeded for ${pkgName}`);
|
|
18
|
-
else try {
|
|
19
|
-
const parsedBody = JSON.parse(resp.stdout);
|
|
20
|
-
assert.strictEqual(parsedBody.name, pkgName, `Expected package name "${pkgName}" but got "${parsedBody.name}"`);
|
|
21
|
-
assert.ok(parsedBody.files, `Expected files to be defined for ${pkgName}`);
|
|
22
|
-
} catch {
|
|
23
|
-
assert.ok(true, `Publish succeeded for ${pkgName}`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
var publishTest = {
|
|
28
|
-
name: "publish",
|
|
29
|
-
requires: ["publish"],
|
|
30
|
-
run: testPublish
|
|
31
|
-
};
|
|
32
|
-
//#endregion
|
|
33
|
-
export { publishTest };
|
|
34
|
-
|
|
35
|
-
//# sourceMappingURL=publish.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","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;CAEzB,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,SACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;EAGD,IAAI,SAAS,eACX,MAAM,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;EAED,IAAI,SAAS,eACX,OAAO,GACL,KAAK,OAAO,MAAM,4BAA4B,EAC9C,4CAA4C,QAAQ,YAAY,KAAK,OAAO,GAC7E;OACI,IAAI,SAAS,gBAElB,OAAO,GAAG,KAAK,OAAO,SAAS,GAAG,+BAA+B,UAAU;OACtE,IAAI,SAAS,OAElB,OAAO,GAAG,MAAM,yBAAyB,UAAU;OAGnD,IAAI;GACF,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO;GAC1C,OAAO,YACL,WAAW,MACX,SACA,0BAA0B,QAAQ,aAAa,WAAW,KAAK,GAChE;GACD,OAAO,GAAG,WAAW,OAAO,oCAAoC,UAAU;UACpE;GAEN,OAAO,GAAG,MAAM,yBAAyB,UAAU;;;;AAM3D,IAAa,cAA8B;CACzC,MAAM;CACN,UAAU,CAAC,UAAU;CACrB,KAAK;CACN"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
//#region src/tests/search.ts
|
|
3
|
-
async function testSearch(ctx) {
|
|
4
|
-
const resp = await ctx.adapter.exec({}, "search", "@verdaccio/cli", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
5
|
-
const pkgFind = JSON.parse(resp.stdout).find((item) => item.name === "@verdaccio/cli");
|
|
6
|
-
assert.ok(pkgFind, "Expected to find @verdaccio/cli in search results");
|
|
7
|
-
assert.strictEqual(pkgFind.name, "@verdaccio/cli");
|
|
8
|
-
}
|
|
9
|
-
var searchTest = {
|
|
10
|
-
name: "search",
|
|
11
|
-
requires: ["search"],
|
|
12
|
-
run: testSearch
|
|
13
|
-
};
|
|
14
|
-
//#endregion
|
|
15
|
-
export { searchTest };
|
|
16
|
-
|
|
17
|
-
//# sourceMappingURL=search.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","names":[],"sources":["../../../src/tests/search.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function testSearch(ctx: TestContext): Promise<void> {\n const resp = await ctx.adapter.exec(\n {},\n 'search',\n '@verdaccio/cli',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n const parsedBody = JSON.parse(resp.stdout);\n const pkgFind = parsedBody.find((item: any) => item.name === '@verdaccio/cli');\n assert.ok(pkgFind, 'Expected to find @verdaccio/cli in search results');\n assert.strictEqual(pkgFind.name, '@verdaccio/cli');\n}\n\nexport const searchTest: TestDefinition = {\n name: 'search',\n requires: ['search'],\n run: testSearch,\n};\n"],"mappings":";;AAIA,eAAe,WAAW,KAAiC;CACzD,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,EACF,UACA,kBACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;CAED,MAAM,UADa,KAAK,MAAM,KAAK,OACnB,CAAW,MAAM,SAAc,KAAK,SAAS,iBAAiB;CAC9E,OAAO,GAAG,SAAS,oDAAoD;CACvE,OAAO,YAAY,QAAQ,MAAM,iBAAiB;;AAGpD,IAAa,aAA6B;CACxC,MAAM;CACN,UAAU,CAAC,SAAS;CACpB,KAAK;CACN"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
//#region src/tests/unpublish.ts
|
|
3
|
-
async function publishPkg(ctx, tempFolder) {
|
|
4
|
-
await ctx.adapter.exec({ cwd: tempFolder }, "publish", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
5
|
-
}
|
|
6
|
-
async function bumpVersion(ctx, tempFolder, bump) {
|
|
7
|
-
await ctx.adapter.exec({ cwd: tempFolder }, "version", bump, "--no--git-tag-version", "--loglevel=info", ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
8
|
-
}
|
|
9
|
-
async function testUnpublish(ctx) {
|
|
10
|
-
const id = ctx.runId;
|
|
11
|
-
const pkgName = `@verdaccio/unpub1-${id}`;
|
|
12
|
-
const { tempFolder } = await ctx.adapter.prepareProject(pkgName, "1.0.0", ctx.registryUrl, ctx.port, ctx.token);
|
|
13
|
-
await publishPkg(ctx, tempFolder);
|
|
14
|
-
await bumpVersion(ctx, tempFolder, "minor");
|
|
15
|
-
await publishPkg(ctx, tempFolder);
|
|
16
|
-
await bumpVersion(ctx, tempFolder, "minor");
|
|
17
|
-
await publishPkg(ctx, tempFolder);
|
|
18
|
-
await bumpVersion(ctx, tempFolder, "major");
|
|
19
|
-
await publishPkg(ctx, tempFolder);
|
|
20
|
-
const resp = await ctx.adapter.exec({ cwd: tempFolder }, "unpublish", pkgName, "--force", "--loglevel=info", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
21
|
-
assert.ok(resp.stdout.includes(pkgName), `Expected unpublish output to contain "${pkgName}" but got "${resp.stdout}"`);
|
|
22
|
-
const pkgName2 = `@verdaccio/unpub2-${id}`;
|
|
23
|
-
const { tempFolder: tf2 } = await ctx.adapter.prepareProject(pkgName2, "1.0.0", ctx.registryUrl, ctx.port, ctx.token);
|
|
24
|
-
await publishPkg(ctx, tf2);
|
|
25
|
-
await bumpVersion(ctx, tf2, "minor");
|
|
26
|
-
await publishPkg(ctx, tf2);
|
|
27
|
-
const resp2 = await ctx.adapter.exec({ cwd: tf2 }, "unpublish", `${pkgName2}@1.0.0`, "--force", "--loglevel=info", "--json", ...ctx.adapter.registryArg(ctx.registryUrl));
|
|
28
|
-
assert.ok(resp2.stdout.includes(pkgName2), `Expected unpublish output to contain "${pkgName2}" but got "${resp2.stdout}"`);
|
|
29
|
-
}
|
|
30
|
-
var unpublishTest = {
|
|
31
|
-
name: "unpublish",
|
|
32
|
-
requires: ["unpublish"],
|
|
33
|
-
run: testUnpublish
|
|
34
|
-
};
|
|
35
|
-
//#endregion
|
|
36
|
-
export { unpublishTest };
|
|
37
|
-
|
|
38
|
-
//# sourceMappingURL=unpublish.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"unpublish.js","names":[],"sources":["../../../src/tests/unpublish.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { TestContext, TestDefinition } from '../types';\n\nasync function publishPkg(ctx: TestContext, tempFolder: string) {\n await ctx.adapter.exec(\n { cwd: tempFolder },\n 'publish',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n}\n\nasync function bumpVersion(ctx: TestContext, tempFolder: string, bump: string) {\n await ctx.adapter.exec(\n { cwd: tempFolder },\n 'version',\n bump,\n '--no--git-tag-version',\n '--loglevel=info',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n}\n\nasync function testUnpublish(ctx: TestContext): Promise<void> {\n const id = ctx.runId;\n\n // Test 1: unpublish a full package\n const pkgName = `@verdaccio/unpub1-${id}`;\n const { tempFolder } = await ctx.adapter.prepareProject(\n pkgName,\n '1.0.0',\n ctx.registryUrl,\n ctx.port,\n ctx.token\n );\n await publishPkg(ctx, tempFolder);\n await bumpVersion(ctx, tempFolder, 'minor');\n await publishPkg(ctx, tempFolder);\n await bumpVersion(ctx, tempFolder, 'minor');\n await publishPkg(ctx, tempFolder);\n await bumpVersion(ctx, tempFolder, 'major');\n await publishPkg(ctx, tempFolder);\n\n const resp = await ctx.adapter.exec(\n { cwd: tempFolder },\n 'unpublish',\n pkgName,\n '--force',\n '--loglevel=info',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n assert.ok(\n resp.stdout.includes(pkgName),\n `Expected unpublish output to contain \"${pkgName}\" but got \"${resp.stdout}\"`\n );\n\n // Test 2: unpublish a specific version\n const pkgName2 = `@verdaccio/unpub2-${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 publishPkg(ctx, tf2);\n await bumpVersion(ctx, tf2, 'minor');\n await publishPkg(ctx, tf2);\n\n const resp2 = await ctx.adapter.exec(\n { cwd: tf2 },\n 'unpublish',\n `${pkgName2}@1.0.0`,\n '--force',\n '--loglevel=info',\n '--json',\n ...ctx.adapter.registryArg(ctx.registryUrl)\n );\n assert.ok(\n resp2.stdout.includes(pkgName2),\n `Expected unpublish output to contain \"${pkgName2}\" but got \"${resp2.stdout}\"`\n );\n}\n\nexport const unpublishTest: TestDefinition = {\n name: 'unpublish',\n requires: ['unpublish'],\n run: testUnpublish,\n};\n"],"mappings":";;AAIA,eAAe,WAAW,KAAkB,YAAoB;CAC9D,MAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,YAAY,EACnB,WACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;;AAGH,eAAe,YAAY,KAAkB,YAAoB,MAAc;CAC7E,MAAM,IAAI,QAAQ,KAChB,EAAE,KAAK,YAAY,EACnB,WACA,MACA,yBACA,mBACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;;AAGH,eAAe,cAAc,KAAiC;CAC5D,MAAM,KAAK,IAAI;CAGf,MAAM,UAAU,qBAAqB;CACrC,MAAM,EAAE,eAAe,MAAM,IAAI,QAAQ,eACvC,SACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;CACD,MAAM,WAAW,KAAK,WAAW;CACjC,MAAM,YAAY,KAAK,YAAY,QAAQ;CAC3C,MAAM,WAAW,KAAK,WAAW;CACjC,MAAM,YAAY,KAAK,YAAY,QAAQ;CAC3C,MAAM,WAAW,KAAK,WAAW;CACjC,MAAM,YAAY,KAAK,YAAY,QAAQ;CAC3C,MAAM,WAAW,KAAK,WAAW;CAEjC,MAAM,OAAO,MAAM,IAAI,QAAQ,KAC7B,EAAE,KAAK,YAAY,EACnB,aACA,SACA,WACA,mBACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;CACD,OAAO,GACL,KAAK,OAAO,SAAS,QAAQ,EAC7B,yCAAyC,QAAQ,aAAa,KAAK,OAAO,GAC3E;CAGD,MAAM,WAAW,qBAAqB;CACtC,MAAM,EAAE,YAAY,QAAQ,MAAM,IAAI,QAAQ,eAC5C,UACA,SACA,IAAI,aACJ,IAAI,MACJ,IAAI,MACL;CACD,MAAM,WAAW,KAAK,IAAI;CAC1B,MAAM,YAAY,KAAK,KAAK,QAAQ;CACpC,MAAM,WAAW,KAAK,IAAI;CAE1B,MAAM,QAAQ,MAAM,IAAI,QAAQ,KAC9B,EAAE,KAAK,KAAK,EACZ,aACA,GAAG,SAAS,SACZ,WACA,mBACA,UACA,GAAG,IAAI,QAAQ,YAAY,IAAI,YAAY,CAC5C;CACD,OAAO,GACL,MAAM,OAAO,SAAS,SAAS,EAC/B,yCAAyC,SAAS,aAAa,MAAM,OAAO,GAC7E;;AAGH,IAAa,gBAAgC;CAC3C,MAAM;CACN,UAAU,CAAC,YAAY;CACvB,KAAK;CACN"}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import buildDebug from "debug";
|
|
2
|
-
import { spawn } from "child_process";
|
|
3
|
-
import { basename } from "path";
|
|
4
|
-
import { createInterface } from "readline";
|
|
5
|
-
//#region src/utils/process.ts
|
|
6
|
-
var debug = buildDebug("verdaccio:e2e-cli:process");
|
|
7
|
-
var debugRead = buildDebug("verdaccio:e2e-cli:line");
|
|
8
|
-
var _verbose = false;
|
|
9
|
-
function setVerbose(v) {
|
|
10
|
-
_verbose = v;
|
|
11
|
-
}
|
|
12
|
-
var COLORS = {
|
|
13
|
-
reset: "\x1B[0m",
|
|
14
|
-
dim: "\x1B[2m",
|
|
15
|
-
cyan: "\x1B[36m",
|
|
16
|
-
green: "\x1B[32m",
|
|
17
|
-
red: "\x1B[31m",
|
|
18
|
-
yellow: "\x1B[33m"
|
|
19
|
-
};
|
|
20
|
-
function shortCmd(cmd, args) {
|
|
21
|
-
return `${basename(cmd)} ${args.join(" ")}`;
|
|
22
|
-
}
|
|
23
|
-
async function exec(options, cmd, args) {
|
|
24
|
-
debug("start exec %o %o %o", options, cmd, args ? args.join(" ") : "");
|
|
25
|
-
let stdout = "";
|
|
26
|
-
let stderr = "";
|
|
27
|
-
if (_verbose) {
|
|
28
|
-
const cwd = options.cwd ? ` ${COLORS.dim}(cwd: ${basename(String(options.cwd))})${COLORS.reset}` : "";
|
|
29
|
-
process.stdout.write(` ${COLORS.cyan}$${COLORS.reset} ${shortCmd(cmd, args)}${cwd}\n`);
|
|
30
|
-
}
|
|
31
|
-
const spawnOptions = {
|
|
32
|
-
cwd: options.cwd,
|
|
33
|
-
stdio: options.stdio || "pipe",
|
|
34
|
-
env: options.env || process.env
|
|
35
|
-
};
|
|
36
|
-
if (process.platform.startsWith("win")) {
|
|
37
|
-
args.unshift("/c", cmd);
|
|
38
|
-
cmd = "cmd.exe";
|
|
39
|
-
spawnOptions.stdio = "pipe";
|
|
40
|
-
}
|
|
41
|
-
const start = Date.now();
|
|
42
|
-
const childProcess = spawn(cmd, args, spawnOptions);
|
|
43
|
-
if (childProcess.stdout) {
|
|
44
|
-
childProcess.stdout.on("data", (data) => {
|
|
45
|
-
debugRead("data %o", data.toString());
|
|
46
|
-
});
|
|
47
|
-
createInterface({
|
|
48
|
-
input: childProcess.stdout,
|
|
49
|
-
output: process.stdout,
|
|
50
|
-
terminal: false
|
|
51
|
-
}).on("line", function(line) {
|
|
52
|
-
debugRead("line %o", line);
|
|
53
|
-
stdout += line;
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
if (childProcess.stderr) childProcess.stderr.on("data", (data) => {
|
|
57
|
-
stderr += data.toString();
|
|
58
|
-
});
|
|
59
|
-
const err = /* @__PURE__ */ new Error(`Running "${cmd} ${args.join(" ")}" returned error code `);
|
|
60
|
-
return new Promise((resolve, reject) => {
|
|
61
|
-
childProcess.on("exit", (code) => {
|
|
62
|
-
const duration = Date.now() - start;
|
|
63
|
-
debugRead("exit %o", code);
|
|
64
|
-
if (_verbose) {
|
|
65
|
-
const status = code ? `${COLORS.red}exit ${code}${COLORS.reset}` : `${COLORS.green}ok${COLORS.reset}`;
|
|
66
|
-
process.stdout.write(` ${COLORS.dim} -> ${status} ${COLORS.dim}(${duration}ms)${COLORS.reset}\n`);
|
|
67
|
-
}
|
|
68
|
-
if (!code) resolve({
|
|
69
|
-
stdout,
|
|
70
|
-
stderr
|
|
71
|
-
});
|
|
72
|
-
else {
|
|
73
|
-
err.message += `${code}...\n\nSTDOUT:\n${stdout}\n\nSTDERR:\n${stderr}\n`;
|
|
74
|
-
reject(err);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
//#endregion
|
|
80
|
-
export { exec, setVerbose };
|
|
81
|
-
|
|
82
|
-
//# sourceMappingURL=process.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"process.js","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,QAAQ,WAAW,4BAA4B;AACrD,IAAM,YAAY,WAAW,yBAAyB;AAEtD,IAAI,WAAW;AAEf,SAAgB,WAAW,GAAY;CACrC,WAAW;;AAGb,IAAM,SAAS;CACb,OAAO;CACP,KAAK;CACL,MAAM;CACN,OAAO;CACP,KAAK;CACL,QAAQ;CACT;AAED,SAAS,SAAS,KAAa,MAAwB;CAErD,OAAO,GADK,SAAS,IACX,CAAI,GAAG,KAAK,KAAK,IAAI;;AAGjC,eAAsB,KACpB,SACA,KACA,MACqB;CACrB,MAAM,uBAAuB,SAAS,KAAK,OAAO,KAAK,KAAK,IAAI,GAAG,GAAG;CACtE,IAAI,SAAS;CACb,IAAI,SAAS;CAEb,IAAI,UAAU;EACZ,MAAM,MAAM,QAAQ,MAChB,IAAI,OAAO,IAAI,QAAQ,SAAS,OAAO,QAAQ,IAAI,CAAC,CAAC,GAAG,OAAO,UAC/D;EACJ,QAAQ,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;CAED,IAAI,QAAQ,SAAS,WAAW,MAAM,EAAE;EACtC,KAAK,QAAQ,MAAM,IAAI;EACvB,MAAM;EACN,aAAa,QAAQ;;CAGvB,MAAM,QAAQ,KAAK,KAAK;CACxB,MAAM,eAAe,MAAM,KAAK,MAAM,aAAa;CAEnD,IAAI,aAAa,QAAQ;EACvB,aAAa,OAAO,GAAG,SAAS,SAAS;GACvC,UAAU,WAAW,KAAK,UAAU,CAAC;IACrC;EAOF,gBAN2B;GACzB,OAAO,aAAa;GACpB,QAAQ,QAAQ;GAChB,UAAU;GACX,CAED,CAAG,GAAG,QAAQ,SAAU,MAAM;GAC5B,UAAU,WAAW,KAAK;GAC1B,UAAU;IACV;;CAGJ,IAAI,aAAa,QACf,aAAa,OAAO,GAAG,SAAS,SAAS;EACvC,UAAU,KAAK,UAAU;GACzB;CAGJ,MAAM,sBAAM,IAAI,MAAM,YAAY,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,wBAAwB;CAChF,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,aAAa,GAAG,SAAS,SAAS;GAChC,MAAM,WAAW,KAAK,KAAK,GAAG;GAC9B,UAAU,WAAW,KAAK;GAE1B,IAAI,UAAU;IACZ,MAAM,SAAS,OACX,GAAG,OAAO,IAAI,OAAO,OAAO,OAAO,UACnC,GAAG,OAAO,MAAM,IAAI,OAAO;IAC/B,QAAQ,OAAO,MACb,SAAS,OAAO,IAAI,OAAO,OAAO,GAAG,OAAO,IAAI,GAAG,SAAS,KAAK,OAAO,MAAM,IAC/E;;GAGH,IAAI,CAAC,MACH,QAAQ;IAAE;IAAQ;IAAQ,CAAC;QACtB;IACL,IAAI,WAAW,GAAG,KAAK,kBAAkB,OAAO,eAAe,OAAO;IACtE,OAAO,IAAI;;IAEb;GACF"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import buildDebug from "debug";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { mkdtemp, writeFile } from "fs/promises";
|
|
4
|
-
import { tmpdir } from "os";
|
|
5
|
-
//#region src/utils/project.ts
|
|
6
|
-
var debug = buildDebug("verdaccio:e2e-cli:project");
|
|
7
|
-
async function createTempFolder(prefix) {
|
|
8
|
-
const sanitized = prefix.replace(/[^a-zA-Z0-9-_]/g, "-");
|
|
9
|
-
debug("creating temp folder %o", sanitized);
|
|
10
|
-
return mkdtemp(join(tmpdir(), `verdaccio-e2e-${sanitized}-`));
|
|
11
|
-
}
|
|
12
|
-
function getPackageJSON(packageName, version = "1.0.0", dependencies = {}, devDependencies = {}) {
|
|
13
|
-
debug("creating package.json %o", packageName);
|
|
14
|
-
return JSON.stringify({
|
|
15
|
-
name: packageName,
|
|
16
|
-
version,
|
|
17
|
-
description: "some cool project",
|
|
18
|
-
main: "index.js",
|
|
19
|
-
scripts: { test: "echo exit 1" },
|
|
20
|
-
dependencies,
|
|
21
|
-
devDependencies,
|
|
22
|
-
keywords: ["foo", "bar"],
|
|
23
|
-
author: "Verdaccio E2E <verdaccio@example.org>",
|
|
24
|
-
license: "MIT"
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
function getREADME(packageName) {
|
|
28
|
-
return `
|
|
29
|
-
# My README ${packageName}
|
|
30
|
-
|
|
31
|
-
some text
|
|
32
|
-
|
|
33
|
-
## subtitle
|
|
34
|
-
|
|
35
|
-
more text
|
|
36
|
-
`;
|
|
37
|
-
}
|
|
38
|
-
async function prepareGenericEmptyProject(packageName, version, port, token, registryDomain, dependencies = {}, devDependencies = {}) {
|
|
39
|
-
debug("preparing generic project %o", packageName);
|
|
40
|
-
const getNPMrc = (port, token, registry) => `//localhost:${port}/:_authToken=${token}\nregistry=${registry}`;
|
|
41
|
-
const tempFolder = await createTempFolder("temp-folder");
|
|
42
|
-
await writeFile(join(tempFolder, "package.json"), getPackageJSON(packageName, version, dependencies, devDependencies));
|
|
43
|
-
await writeFile(join(tempFolder, "README.md"), getREADME(packageName));
|
|
44
|
-
await writeFile(join(tempFolder, ".npmrc"), getNPMrc(port, token, registryDomain));
|
|
45
|
-
return { tempFolder };
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { createTempFolder, getPackageJSON, getREADME, prepareGenericEmptyProject };
|
|
49
|
-
|
|
50
|
-
//# sourceMappingURL=project.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","names":[],"sources":["../../../src/utils/project.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { mkdirSync } from 'fs';\nimport { mkdtemp, writeFile } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\n\nconst debug = buildDebug('verdaccio:e2e-cli:project');\n\nexport async function createTempFolder(prefix: string): Promise<string> {\n const sanitized = prefix.replace(/[^a-zA-Z0-9-_]/g, '-');\n debug('creating temp folder %o', sanitized);\n return mkdtemp(join(tmpdir(), `verdaccio-e2e-${sanitized}-`));\n}\n\nexport function getPackageJSON(\n packageName: string,\n version = '1.0.0',\n dependencies: Record<string, string> = {},\n devDependencies: Record<string, string> = {}\n): string {\n debug('creating package.json %o', packageName);\n const json = {\n name: packageName,\n version,\n description: 'some cool project',\n main: 'index.js',\n scripts: {\n test: 'echo exit 1',\n },\n dependencies,\n devDependencies,\n keywords: ['foo', 'bar'],\n author: 'Verdaccio E2E <verdaccio@example.org>',\n license: 'MIT',\n };\n return JSON.stringify(json);\n}\n\nexport function getREADME(packageName: string): string {\n return `\n # My README ${packageName}\n\n some text\n\n ## subtitle\n\n more text\n `;\n}\n\nexport async function prepareGenericEmptyProject(\n packageName: string,\n version: string,\n port: number,\n token: string,\n registryDomain: string,\n dependencies: Record<string, string> = {},\n devDependencies: Record<string, string> = {}\n): Promise<{ tempFolder: string }> {\n debug('preparing generic project %o', packageName);\n const getNPMrc = (port: number, token: string, registry: string) =>\n `//localhost:${port}/:_authToken=${token}\\nregistry=${registry}`;\n const tempFolder = await createTempFolder('temp-folder');\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 await writeFile(join(tempFolder, '.npmrc'), getNPMrc(port, token, registryDomain));\n return { tempFolder };\n}\n"],"mappings":";;;;;AAMA,IAAM,QAAQ,WAAW,4BAA4B;AAErD,eAAsB,iBAAiB,QAAiC;CACtE,MAAM,YAAY,OAAO,QAAQ,mBAAmB,IAAI;CACxD,MAAM,2BAA2B,UAAU;CAC3C,OAAO,QAAQ,KAAK,QAAQ,EAAE,iBAAiB,UAAU,GAAG,CAAC;;AAG/D,SAAgB,eACd,aACA,UAAU,SACV,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACpC;CACR,MAAM,4BAA4B,YAAY;CAe9C,OAAO,KAAK,UAAU;EAbpB,MAAM;EACN;EACA,aAAa;EACb,MAAM;EACN,SAAS,EACP,MAAM,eACP;EACD;EACA;EACA,UAAU,CAAC,OAAO,MAAM;EACxB,QAAQ;EACR,SAAS;EAEW,CAAK;;AAG7B,SAAgB,UAAU,aAA6B;CACrD,OAAO;iBACQ,YAAY;;;;;;;;;AAU7B,eAAsB,2BACpB,aACA,SACA,MACA,OACA,gBACA,eAAuC,EAAE,EACzC,kBAA0C,EAAE,EACX;CACjC,MAAM,gCAAgC,YAAY;CAClD,MAAM,YAAY,MAAc,OAAe,aAC7C,eAAe,KAAK,eAAe,MAAM,aAAa;CACxD,MAAM,aAAa,MAAM,iBAAiB,cAAc;CACxD,MAAM,UACJ,KAAK,YAAY,eAAe,EAChC,eAAe,aAAa,SAAS,cAAc,gBAAgB,CACpE;CACD,MAAM,UAAU,KAAK,YAAY,YAAY,EAAE,UAAU,YAAY,CAAC;CACtE,MAAM,UAAU,KAAK,YAAY,SAAS,EAAE,SAAS,MAAM,OAAO,eAAe,CAAC;CAClF,OAAO,EAAE,YAAY"}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import buildDebug from "debug";
|
|
2
|
-
import { ping } from "@verdaccio/registry-cli";
|
|
3
|
-
//#region src/utils/registry-client.ts
|
|
4
|
-
var debug = buildDebug("verdaccio:e2e-cli:registry-client");
|
|
5
|
-
/**
|
|
6
|
-
* Creates a user on the registry and returns the auth token.
|
|
7
|
-
* Uses a unique username per run to avoid 409 conflicts.
|
|
8
|
-
* Works against any running Verdaccio instance with htpasswd auth.
|
|
9
|
-
*/
|
|
10
|
-
async function createUser(registryUrl, user = `e2e-user-${Date.now()}`, password = "e2e-test-password") {
|
|
11
|
-
debug("creating user %s on %s", user, registryUrl);
|
|
12
|
-
const url = `${registryUrl}/-/user/org.couchdb.user:${encodeURIComponent(user)}`;
|
|
13
|
-
const response = await fetch(url, {
|
|
14
|
-
method: "PUT",
|
|
15
|
-
headers: { "Content-Type": "application/json" },
|
|
16
|
-
body: JSON.stringify({
|
|
17
|
-
name: user,
|
|
18
|
-
password,
|
|
19
|
-
_id: `org.couchdb.user:${user}`,
|
|
20
|
-
type: "user",
|
|
21
|
-
roles: [],
|
|
22
|
-
date: (/* @__PURE__ */ new Date()).toISOString()
|
|
23
|
-
})
|
|
24
|
-
});
|
|
25
|
-
const body = await response.json();
|
|
26
|
-
if (response.status === 201 || response.status === 200 || response.status === 409) {
|
|
27
|
-
const token = body.token;
|
|
28
|
-
if (token) {
|
|
29
|
-
debug("user %s authenticated, token obtained", user);
|
|
30
|
-
return {
|
|
31
|
-
token,
|
|
32
|
-
user
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
throw new Error(`Failed to create/login user "${user}" on ${registryUrl}: ${response.status} ${JSON.stringify(body)}`);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Ping the registry to check it's alive.
|
|
40
|
-
* Uses @verdaccio/registry-cli ping.
|
|
41
|
-
*/
|
|
42
|
-
async function pingRegistry(registryUrl) {
|
|
43
|
-
debug("pinging %s", registryUrl);
|
|
44
|
-
try {
|
|
45
|
-
return (await ping(registryUrl)).ok;
|
|
46
|
-
} catch {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
export { createUser, pingRegistry };
|
|
52
|
-
|
|
53
|
-
//# sourceMappingURL=registry-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry-client.js","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,QAAQ,WAAW,oCAAoC;;;;;;AAY7D,eAAsB,WACpB,aACA,OAAO,YAAY,KAAK,KAAK,IAC7B,WAAW,qBACY;CACvB,MAAM,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;CAEnC,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;EACjF,MAAM,QAAQ,KAAK;EACnB,IAAI,OAAO;GACT,MAAM,yCAAyC,KAAK;GACpD,OAAO;IAAE;IAAO;IAAM;;;CAI1B,MAAM,IAAI,MACR,gCAAgC,KAAK,OAAO,YAAY,IAAI,SAAS,OAAO,GAAG,KAAK,UAAU,KAAK,GACpG;;;;;;AAOH,eAAsB,aAAa,aAAuC;CACxE,MAAM,cAAc,YAAY;CAChC,IAAI;EAEF,QAAO,MADc,KAAK,YAAY,EACxB;SACR;EACN,OAAO"}
|
package/build/reporter.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { SuiteResult, TestResult } from './types';
|
|
2
|
-
export declare function reportTestStart(adapterName: string, testName: string): void;
|
|
3
|
-
export declare function reportTestResult(result: TestResult, hasSubTests?: boolean): void;
|
|
4
|
-
export declare function reportSuiteStart(adapterName: string): void;
|
|
5
|
-
export declare function reportSubTestResult(label: string, passed: boolean, duration?: number): void;
|
|
6
|
-
export declare function reportSkipped(testName: string): void;
|
|
7
|
-
export declare function reportSummary(results: SuiteResult[]): void;
|
package/build/runner.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { PackageManagerAdapter, SuiteResult, TestDefinition } from './types';
|
|
2
|
-
export declare function runSuite(adapter: PackageManagerAdapter, tests: TestDefinition[], registryUrl: string, token: string, options: {
|
|
3
|
-
timeout: number;
|
|
4
|
-
testFilter?: string[];
|
|
5
|
-
}): Promise<SuiteResult>;
|
|
6
|
-
export declare function runAll(adapters: PackageManagerAdapter[], tests: TestDefinition[], registryUrl: string, token: string, options: {
|
|
7
|
-
timeout: number;
|
|
8
|
-
concurrency: number;
|
|
9
|
-
testFilter?: string[];
|
|
10
|
-
}): Promise<{
|
|
11
|
-
results: SuiteResult[];
|
|
12
|
-
exitCode: number;
|
|
13
|
-
}>;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { TestDefinition } from '../types';
|
|
2
|
-
import { installMultipleDepsScenario } from './install-multiple-deps';
|
|
3
|
-
import { minimumReleaseAgeScenario } from './minimum-release-age';
|
|
4
|
-
export declare const allScenarios: TestDefinition[];
|
|
5
|
-
export { installMultipleDepsScenario, minimumReleaseAgeScenario };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { PackageManagerAdapter, TestDefinition } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* True only for pnpm versions that actually enforce minimumReleaseAge.
|
|
4
|
-
*
|
|
5
|
-
* The cooldown is honored in pnpm 11.1.0+, but it is silently ignored in
|
|
6
|
-
* 11.0.0 / 11.0.1 (and the 11.0.0 release candidates) — those versions install
|
|
7
|
-
* brand-new packages regardless of the configured cooldown. We scope this
|
|
8
|
-
* scenario to pnpm 11.1.0 and newer so it doesn't false-fail on that regression.
|
|
9
|
-
*/
|
|
10
|
-
export declare function isPnpm11Plus(adapter: PackageManagerAdapter): boolean;
|
|
11
|
-
export declare const minimumReleaseAgeScenario: TestDefinition;
|