@verdaccio/e2e-cli 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/e2e-cli.js +6 -26
- package/build/adapters/adapter.d.ts +1 -0
- package/build/adapters/bun.d.ts +2 -0
- package/build/adapters/deno.d.ts +2 -0
- package/build/adapters/index.d.ts +5 -0
- package/build/adapters/npm.d.ts +2 -0
- package/build/adapters/pnpm.d.ts +2 -0
- package/build/adapters/yarn-modern.d.ts +2 -0
- package/build/cjs/_virtual/_rolldown/runtime.cjs +23 -0
- package/build/cjs/adapters/bun.cjs +64 -0
- package/build/cjs/adapters/bun.cjs.map +1 -0
- package/build/cjs/adapters/deno.cjs +61 -0
- package/build/cjs/adapters/deno.cjs.map +1 -0
- package/build/cjs/adapters/index.cjs +10 -0
- package/build/cjs/adapters/npm.cjs +85 -0
- package/build/cjs/adapters/npm.cjs.map +1 -0
- package/build/cjs/adapters/pnpm.cjs +114 -0
- package/build/cjs/adapters/pnpm.cjs.map +1 -0
- package/build/cjs/adapters/yarn-modern.cjs +207 -0
- package/build/cjs/adapters/yarn-modern.cjs.map +1 -0
- package/build/cjs/index.cjs +186 -11
- package/build/cjs/index.cjs.map +1 -0
- package/build/cjs/reporter.cjs +113 -0
- package/build/cjs/reporter.cjs.map +1 -0
- package/build/cjs/runner.cjs +141 -0
- package/build/cjs/runner.cjs.map +1 -0
- package/build/cjs/scenarios/index.cjs +25 -0
- package/build/cjs/scenarios/index.cjs.map +1 -0
- package/build/cjs/scenarios/install-multiple-deps.cjs +119 -0
- package/build/cjs/scenarios/install-multiple-deps.cjs.map +1 -0
- package/build/cjs/scenarios/metadata.cjs +121 -0
- package/build/cjs/scenarios/metadata.cjs.map +1 -0
- package/build/cjs/scenarios/minimum-release-age.cjs +111 -0
- package/build/cjs/scenarios/minimum-release-age.cjs.map +1 -0
- package/build/cjs/scenarios/search.cjs +136 -0
- package/build/cjs/scenarios/search.cjs.map +1 -0
- package/build/cjs/scenarios/tarballs.cjs +147 -0
- package/build/cjs/scenarios/tarballs.cjs.map +1 -0
- package/build/cjs/scenarios/uplink-failure.cjs +141 -0
- package/build/cjs/scenarios/uplink-failure.cjs.map +1 -0
- package/build/cjs/tests/audit.cjs +60 -0
- package/build/cjs/tests/audit.cjs.map +1 -0
- package/build/cjs/tests/ci.cjs +83 -0
- package/build/cjs/tests/ci.cjs.map +1 -0
- package/build/cjs/tests/deprecate.cjs +108 -0
- package/build/cjs/tests/deprecate.cjs.map +1 -0
- package/build/cjs/tests/dist-tags.cjs +43 -0
- package/build/cjs/tests/dist-tags.cjs.map +1 -0
- package/build/cjs/tests/index.cjs +49 -0
- package/build/cjs/tests/index.cjs.map +1 -0
- package/build/cjs/tests/info.cjs +31 -0
- package/build/cjs/tests/info.cjs.map +1 -0
- package/build/cjs/tests/install.cjs +30 -0
- package/build/cjs/tests/install.cjs.map +1 -0
- package/build/cjs/tests/login.cjs +126 -0
- package/build/cjs/tests/login.cjs.map +1 -0
- package/build/cjs/tests/ping.cjs +26 -0
- package/build/cjs/tests/ping.cjs.map +1 -0
- package/build/cjs/tests/publish.cjs +36 -0
- package/build/cjs/tests/publish.cjs.map +1 -0
- package/build/cjs/tests/search.cjs +23 -0
- package/build/cjs/tests/search.cjs.map +1 -0
- package/build/cjs/tests/unpublish.cjs +40 -0
- package/build/cjs/tests/unpublish.cjs.map +1 -0
- package/build/cjs/utils/e2e-config.cjs +59 -0
- package/build/cjs/utils/e2e-config.cjs.map +1 -0
- package/build/cjs/utils/http-client.cjs +111 -0
- package/build/cjs/utils/http-client.cjs.map +1 -0
- package/build/cjs/utils/info.cjs +25 -0
- package/build/cjs/utils/info.cjs.map +1 -0
- package/build/cjs/utils/mock-uplink.cjs +196 -0
- package/build/cjs/utils/mock-uplink.cjs.map +1 -0
- package/build/cjs/utils/process.cjs +96 -0
- package/build/cjs/utils/process.cjs.map +1 -0
- package/build/cjs/utils/project.cjs +55 -0
- package/build/cjs/utils/project.cjs.map +1 -0
- package/build/cjs/utils/publish.cjs +117 -0
- package/build/cjs/utils/publish.cjs.map +1 -0
- package/build/cjs/utils/registry-client.cjs +56 -0
- package/build/cjs/utils/registry-client.cjs.map +1 -0
- package/build/esm/adapters/bun.js +62 -0
- package/build/esm/adapters/bun.js.map +1 -0
- package/build/esm/adapters/deno.js +59 -0
- package/build/esm/adapters/deno.js.map +1 -0
- package/build/esm/adapters/index.js +6 -0
- package/build/esm/adapters/npm.js +83 -0
- package/build/esm/adapters/npm.js.map +1 -0
- package/build/esm/adapters/pnpm.js +112 -0
- package/build/esm/adapters/pnpm.js.map +1 -0
- package/build/esm/adapters/yarn-modern.js +204 -0
- package/build/esm/adapters/yarn-modern.js.map +1 -0
- package/build/esm/index.js +174 -10
- package/build/esm/index.js.map +1 -0
- package/build/esm/reporter.js +108 -0
- package/build/esm/reporter.js.map +1 -0
- package/build/esm/runner.js +138 -0
- package/build/esm/runner.js.map +1 -0
- package/build/esm/scenarios/index.js +19 -0
- package/build/esm/scenarios/index.js.map +1 -0
- package/build/esm/scenarios/install-multiple-deps.js +117 -0
- package/build/esm/scenarios/install-multiple-deps.js.map +1 -0
- package/build/esm/scenarios/metadata.js +119 -0
- package/build/esm/scenarios/metadata.js.map +1 -0
- package/build/esm/scenarios/minimum-release-age.js +108 -0
- package/build/esm/scenarios/minimum-release-age.js.map +1 -0
- package/build/esm/scenarios/search.js +134 -0
- package/build/esm/scenarios/search.js.map +1 -0
- package/build/esm/scenarios/tarballs.js +145 -0
- package/build/esm/scenarios/tarballs.js.map +1 -0
- package/build/esm/scenarios/uplink-failure.js +139 -0
- package/build/esm/scenarios/uplink-failure.js.map +1 -0
- package/build/esm/tests/audit.js +57 -0
- package/build/esm/tests/audit.js.map +1 -0
- package/build/esm/tests/ci.js +80 -0
- package/build/esm/tests/ci.js.map +1 -0
- package/build/esm/tests/deprecate.js +105 -0
- package/build/esm/tests/deprecate.js.map +1 -0
- package/build/esm/tests/dist-tags.js +41 -0
- package/build/esm/tests/dist-tags.js.map +1 -0
- package/build/esm/tests/index.js +37 -0
- package/build/esm/tests/index.js.map +1 -0
- package/build/esm/tests/info.js +29 -0
- package/build/esm/tests/info.js.map +1 -0
- package/build/esm/tests/install.js +28 -0
- package/build/esm/tests/install.js.map +1 -0
- package/build/esm/tests/login.js +122 -0
- package/build/esm/tests/login.js.map +1 -0
- package/build/esm/tests/ping.js +24 -0
- package/build/esm/tests/ping.js.map +1 -0
- package/build/esm/tests/publish.js +34 -0
- package/build/esm/tests/publish.js.map +1 -0
- package/build/esm/tests/search.js +21 -0
- package/build/esm/tests/search.js.map +1 -0
- package/build/esm/tests/unpublish.js +38 -0
- package/build/esm/tests/unpublish.js.map +1 -0
- package/build/esm/utils/e2e-config.js +58 -0
- package/build/esm/utils/e2e-config.js.map +1 -0
- package/build/esm/utils/http-client.js +105 -0
- package/build/esm/utils/http-client.js.map +1 -0
- package/build/esm/utils/info.js +24 -0
- package/build/esm/utils/info.js.map +1 -0
- package/build/esm/utils/mock-uplink.js +194 -0
- package/build/esm/utils/mock-uplink.js.map +1 -0
- package/build/esm/utils/process.js +92 -0
- package/build/esm/utils/process.js.map +1 -0
- package/build/esm/utils/project.js +50 -0
- package/build/esm/utils/project.js.map +1 -0
- package/build/esm/utils/publish.js +113 -0
- package/build/esm/utils/publish.js.map +1 -0
- package/build/esm/utils/registry-client.js +53 -0
- package/build/esm/utils/registry-client.js.map +1 -0
- package/build/index.d.ts +6 -15
- package/build/reporter.d.ts +7 -0
- package/build/runner.d.ts +13 -0
- package/build/scenarios/index.d.ts +9 -0
- package/build/scenarios/install-multiple-deps.d.ts +2 -0
- package/build/scenarios/metadata.d.ts +2 -0
- package/build/scenarios/minimum-release-age.d.ts +11 -0
- package/build/scenarios/search.d.ts +2 -0
- package/build/scenarios/tarballs.d.ts +2 -0
- package/build/scenarios/uplink-failure.d.ts +2 -0
- package/build/tests/audit.d.ts +2 -0
- package/build/tests/ci.d.ts +2 -0
- package/build/tests/deprecate.d.ts +2 -0
- package/build/tests/dist-tags.d.ts +2 -0
- package/build/tests/index.d.ts +15 -0
- package/build/tests/info.d.ts +2 -0
- package/build/tests/install.d.ts +2 -0
- package/build/tests/login.d.ts +2 -0
- package/build/tests/ping.d.ts +2 -0
- package/build/tests/publish.d.ts +2 -0
- package/build/tests/search.d.ts +2 -0
- package/build/tests/unpublish.d.ts +2 -0
- package/build/types.d.ts +91 -0
- package/build/utils/e2e-config.d.ts +21 -0
- package/build/utils/http-client.d.ts +49 -0
- package/build/utils/index.d.ts +4 -0
- package/build/utils/info.d.ts +14 -0
- package/build/utils/mock-uplink.d.ts +47 -0
- package/build/utils/process.d.ts +11 -0
- package/build/utils/project.d.ts +6 -0
- package/build/utils/publish.d.ts +17 -0
- package/build/utils/registry-client.d.ts +15 -0
- package/package.json +16 -14
- package/Cargo.lock +0 -1591
- package/Cargo.toml +0 -19
- package/build/bin/verdaccio-e2e +0 -0
- package/scripts/build-js-package.mjs +0 -25
- package/src/e2e_tests/audit.rs +0 -51
- package/src/e2e_tests/ci.rs +0 -32
- package/src/e2e_tests/deprecate.rs +0 -64
- package/src/e2e_tests/dist_tags.rs +0 -56
- package/src/e2e_tests/info.rs +0 -43
- package/src/e2e_tests/install.rs +0 -27
- package/src/e2e_tests/login.rs +0 -64
- package/src/e2e_tests/mod.rs +0 -104
- package/src/e2e_tests/ping.rs +0 -33
- package/src/e2e_tests/publish.rs +0 -68
- package/src/e2e_tests/search.rs +0 -14
- package/src/e2e_tests/unpublish.rs +0 -37
- package/src/main.rs +0 -1411
- package/src/scenarios/install_multiple_deps.rs +0 -99
- package/src/scenarios/minimum_release_age.rs +0 -45
- package/src/scenarios/mod.rs +0 -11
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_process = require("../utils/process.cjs");
|
|
3
|
+
const require_project = require("../utils/project.cjs");
|
|
4
|
+
let debug = require("debug");
|
|
5
|
+
debug = require_runtime.__toESM(debug, 1);
|
|
6
|
+
let child_process = require("child_process");
|
|
7
|
+
let path = require("path");
|
|
8
|
+
let fs_promises = require("fs/promises");
|
|
9
|
+
let js_yaml = require("js-yaml");
|
|
10
|
+
js_yaml = require_runtime.__toESM(js_yaml, 1);
|
|
11
|
+
let url = require("url");
|
|
12
|
+
//#region src/adapters/yarn-modern.ts
|
|
13
|
+
var debug$1 = (0, debug.default)("verdaccio:e2e-cli:yarn-modern");
|
|
14
|
+
var YARN_MODERN_SUPPORTED_COMMANDS = /* @__PURE__ */ new Set([
|
|
15
|
+
"publish",
|
|
16
|
+
"install",
|
|
17
|
+
"info",
|
|
18
|
+
"ping",
|
|
19
|
+
"deprecate",
|
|
20
|
+
"login"
|
|
21
|
+
]);
|
|
22
|
+
var YARN_ENV = {
|
|
23
|
+
COREPACK_ENABLE_STRICT: "0",
|
|
24
|
+
YARN_IGNORE_PATH: "1"
|
|
25
|
+
};
|
|
26
|
+
var YARN_BERRY_4_ENV = {
|
|
27
|
+
YARN_ENABLE_HARDENED_MODE: "0",
|
|
28
|
+
YARN_NPM_MINIMAL_AGE_GATE: "0"
|
|
29
|
+
};
|
|
30
|
+
function parseMajor(version) {
|
|
31
|
+
const major = parseInt(version.split(".")[0], 10);
|
|
32
|
+
return Number.isFinite(major) ? major : 0;
|
|
33
|
+
}
|
|
34
|
+
function getYarnEnv(major) {
|
|
35
|
+
return major >= 4 ? {
|
|
36
|
+
...YARN_ENV,
|
|
37
|
+
...YARN_BERRY_4_ENV
|
|
38
|
+
} : { ...YARN_ENV };
|
|
39
|
+
}
|
|
40
|
+
function detectVersion(bin) {
|
|
41
|
+
try {
|
|
42
|
+
return (0, child_process.execSync)(`${bin} --version`, {
|
|
43
|
+
env: {
|
|
44
|
+
...process.env,
|
|
45
|
+
...YARN_ENV
|
|
46
|
+
},
|
|
47
|
+
encoding: "utf8",
|
|
48
|
+
timeout: 5e3
|
|
49
|
+
}).trim();
|
|
50
|
+
} catch {
|
|
51
|
+
return "unknown";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function installYarnModern(version = "4") {
|
|
55
|
+
const pkg = `@yarnpkg/cli-dist@${version}`;
|
|
56
|
+
debug$1("installing %s into temp dir", pkg);
|
|
57
|
+
const tmpDir = (0, child_process.execSync)("mktemp -d", { encoding: "utf8" }).trim();
|
|
58
|
+
(0, child_process.execSync)(`npm install --prefix "${tmpDir}" ${pkg} --loglevel=error`, {
|
|
59
|
+
encoding: "utf8",
|
|
60
|
+
timeout: 3e4
|
|
61
|
+
});
|
|
62
|
+
const bin = `${tmpDir}/node_modules/@yarnpkg/cli-dist/bin/yarn.js`;
|
|
63
|
+
const installed = detectVersion(bin);
|
|
64
|
+
debug$1("installed yarn modern %s at %s", installed, bin);
|
|
65
|
+
console.log(` Auto-installed yarn modern ${installed}`);
|
|
66
|
+
return bin;
|
|
67
|
+
}
|
|
68
|
+
function resolveYarnBin(binPath, version) {
|
|
69
|
+
if (binPath) return binPath;
|
|
70
|
+
if (version) return installYarnModern(version);
|
|
71
|
+
try {
|
|
72
|
+
const systemYarn = (0, child_process.execSync)("which yarn", {
|
|
73
|
+
encoding: "utf8",
|
|
74
|
+
timeout: 5e3
|
|
75
|
+
}).trim();
|
|
76
|
+
const sysVersion = detectVersion(systemYarn);
|
|
77
|
+
if (parseInt(sysVersion.split(".")[0], 10) >= 2) {
|
|
78
|
+
debug$1("using system yarn Berry %s", sysVersion);
|
|
79
|
+
return systemYarn;
|
|
80
|
+
}
|
|
81
|
+
debug$1("system yarn is Classic %s, auto-installing Berry", sysVersion);
|
|
82
|
+
} catch {
|
|
83
|
+
debug$1("no system yarn found, auto-installing Berry");
|
|
84
|
+
}
|
|
85
|
+
return installYarnModern();
|
|
86
|
+
}
|
|
87
|
+
function createYamlConfig(registry, token, major) {
|
|
88
|
+
const defaultYaml = {
|
|
89
|
+
npmRegistryServer: registry,
|
|
90
|
+
enableImmutableInstalls: false,
|
|
91
|
+
unsafeHttpWhitelist: ["localhost"]
|
|
92
|
+
};
|
|
93
|
+
if (major >= 4) {
|
|
94
|
+
defaultYaml.enableHardenedMode = false;
|
|
95
|
+
defaultYaml.npmMinimalAgeGate = 0;
|
|
96
|
+
}
|
|
97
|
+
if (typeof token === "string") {
|
|
98
|
+
new url.URL(registry);
|
|
99
|
+
defaultYaml.npmRegistries = { [registry]: {
|
|
100
|
+
npmAlwaysAuth: true,
|
|
101
|
+
npmAuthToken: token
|
|
102
|
+
} };
|
|
103
|
+
}
|
|
104
|
+
return js_yaml.dump(defaultYaml);
|
|
105
|
+
}
|
|
106
|
+
function createYarnModernAdapter(binPath, version) {
|
|
107
|
+
const bin = resolveYarnBin(binPath, version);
|
|
108
|
+
const resolved = detectVersion(bin);
|
|
109
|
+
const major = parseMajor(resolved);
|
|
110
|
+
const yarnEnv = getYarnEnv(major);
|
|
111
|
+
debug$1("creating yarn modern adapter with bin: %s (%s)", bin, resolved);
|
|
112
|
+
return {
|
|
113
|
+
name: `yarn-modern@${resolved}`,
|
|
114
|
+
type: "yarn-modern",
|
|
115
|
+
bin,
|
|
116
|
+
supports: YARN_MODERN_SUPPORTED_COMMANDS,
|
|
117
|
+
registryArg(_url) {
|
|
118
|
+
return [];
|
|
119
|
+
},
|
|
120
|
+
prefixArg(_folder) {
|
|
121
|
+
return [];
|
|
122
|
+
},
|
|
123
|
+
exec(options, ...args) {
|
|
124
|
+
const env = {
|
|
125
|
+
...process.env,
|
|
126
|
+
...options.env,
|
|
127
|
+
...yarnEnv
|
|
128
|
+
};
|
|
129
|
+
const cmd = args[0];
|
|
130
|
+
let yarnArgs;
|
|
131
|
+
if (cmd === "publish") yarnArgs = [
|
|
132
|
+
"npm",
|
|
133
|
+
"publish",
|
|
134
|
+
...args.slice(1).filter((a) => a !== "--json" && !a.startsWith("--registry"))
|
|
135
|
+
];
|
|
136
|
+
else if (cmd === "info") yarnArgs = [
|
|
137
|
+
"npm",
|
|
138
|
+
"info",
|
|
139
|
+
...args.slice(1).filter((a) => !a.startsWith("--registry"))
|
|
140
|
+
];
|
|
141
|
+
else if (cmd === "ping") yarnArgs = [
|
|
142
|
+
"npm",
|
|
143
|
+
"ping",
|
|
144
|
+
...args.slice(1).filter((a) => !a.startsWith("--registry"))
|
|
145
|
+
];
|
|
146
|
+
else if (cmd === "deprecate") yarnArgs = [
|
|
147
|
+
"npm",
|
|
148
|
+
"deprecate",
|
|
149
|
+
...args.slice(1).filter((a) => !a.startsWith("--registry"))
|
|
150
|
+
];
|
|
151
|
+
else if (cmd === "login") yarnArgs = [
|
|
152
|
+
"npm",
|
|
153
|
+
"login",
|
|
154
|
+
...args.slice(1).filter((a) => !a.startsWith("--registry"))
|
|
155
|
+
];
|
|
156
|
+
else if (cmd === "whoami") yarnArgs = [
|
|
157
|
+
"npm",
|
|
158
|
+
"whoami",
|
|
159
|
+
...args.slice(1).filter((a) => !a.startsWith("--registry"))
|
|
160
|
+
];
|
|
161
|
+
else yarnArgs = args.filter((a) => !a.startsWith("--registry"));
|
|
162
|
+
return require_process.exec({
|
|
163
|
+
...options,
|
|
164
|
+
env
|
|
165
|
+
}, bin, yarnArgs);
|
|
166
|
+
},
|
|
167
|
+
async prepareProject(packageName, version, registryUrl, _port, token, dependencies = {}, devDependencies = {}) {
|
|
168
|
+
const tempFolder = await require_project.createTempFolder(packageName);
|
|
169
|
+
const yamlContent = createYamlConfig(registryUrl, token, major);
|
|
170
|
+
await (0, fs_promises.writeFile)((0, path.join)(tempFolder, ".yarnrc.yml"), yamlContent);
|
|
171
|
+
await (0, fs_promises.writeFile)((0, path.join)(tempFolder, "package.json"), require_project.getPackageJSON(packageName, version, dependencies, devDependencies));
|
|
172
|
+
await (0, fs_promises.writeFile)((0, path.join)(tempFolder, "README.md"), require_project.getREADME(packageName));
|
|
173
|
+
return { tempFolder };
|
|
174
|
+
},
|
|
175
|
+
async importPlugin(cwd, pluginName) {
|
|
176
|
+
debug$1("downloading %s plugin bundle", pluginName);
|
|
177
|
+
const tmpDir = (0, child_process.execSync)("mktemp -d", { encoding: "utf8" }).trim();
|
|
178
|
+
const pkg = `@verdaccio/yarn-plugin-${pluginName}`;
|
|
179
|
+
(0, child_process.execSync)(`npm pack ${pkg} --pack-destination "${tmpDir}"`, {
|
|
180
|
+
encoding: "utf8",
|
|
181
|
+
timeout: 3e4,
|
|
182
|
+
stdio: "pipe"
|
|
183
|
+
});
|
|
184
|
+
(0, child_process.execSync)(`tar xzf "${tmpDir}"/*.tgz -C "${tmpDir}"`, {
|
|
185
|
+
encoding: "utf8",
|
|
186
|
+
stdio: "pipe"
|
|
187
|
+
});
|
|
188
|
+
const bundlePath = (0, path.join)(tmpDir, `package/bundles/@yarnpkg/plugin-${pluginName}.js`);
|
|
189
|
+
debug$1("importing plugin from %s into %s", bundlePath, cwd);
|
|
190
|
+
await require_process.exec({
|
|
191
|
+
cwd,
|
|
192
|
+
env: {
|
|
193
|
+
...process.env,
|
|
194
|
+
...yarnEnv
|
|
195
|
+
}
|
|
196
|
+
}, bin, [
|
|
197
|
+
"plugin",
|
|
198
|
+
"import",
|
|
199
|
+
bundlePath
|
|
200
|
+
]);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
exports.createYarnModernAdapter = createYarnModernAdapter;
|
|
206
|
+
|
|
207
|
+
//# sourceMappingURL=yarn-modern.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yarn-modern.cjs","names":[],"sources":["../../../src/adapters/yarn-modern.ts"],"sourcesContent":["import { SpawnOptions, execSync } from 'child_process';\nimport buildDebug from 'debug';\nimport { writeFile } from 'fs/promises';\nimport * as 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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"}
|
package/build/cjs/index.cjs
CHANGED
|
@@ -1,11 +1,186 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_bun = require("./adapters/bun.cjs");
|
|
4
|
+
const require_deno = require("./adapters/deno.cjs");
|
|
5
|
+
const require_npm = require("./adapters/npm.cjs");
|
|
6
|
+
const require_pnpm = require("./adapters/pnpm.cjs");
|
|
7
|
+
const require_yarn_modern = require("./adapters/yarn-modern.cjs");
|
|
8
|
+
require("./adapters/index.cjs");
|
|
9
|
+
const require_runner = require("./runner.cjs");
|
|
10
|
+
const require_index$1 = require("./scenarios/index.cjs");
|
|
11
|
+
const require_index$2 = require("./tests/index.cjs");
|
|
12
|
+
const require_registry_client = require("./utils/registry-client.cjs");
|
|
13
|
+
let debug = require("debug");
|
|
14
|
+
debug = require_runtime.__toESM(debug, 1);
|
|
15
|
+
//#region src/index.ts
|
|
16
|
+
(0, debug.default)("verdaccio:e2e-cli");
|
|
17
|
+
function parsePmSpec(filter) {
|
|
18
|
+
const eqIdx = filter.indexOf("=");
|
|
19
|
+
if (eqIdx !== -1) return {
|
|
20
|
+
name: filter.slice(0, eqIdx).toLowerCase(),
|
|
21
|
+
binPath: filter.slice(eqIdx + 1)
|
|
22
|
+
};
|
|
23
|
+
const atIdx = filter.indexOf("@");
|
|
24
|
+
if (atIdx !== -1) return {
|
|
25
|
+
name: filter.slice(0, atIdx).toLowerCase(),
|
|
26
|
+
version: filter.slice(atIdx + 1)
|
|
27
|
+
};
|
|
28
|
+
return { name: filter.toLowerCase() };
|
|
29
|
+
}
|
|
30
|
+
function parseAdapters(pmFilters) {
|
|
31
|
+
if (!pmFilters || pmFilters.length === 0) return [require_npm.createNpmAdapter()];
|
|
32
|
+
const adapters = [];
|
|
33
|
+
for (const filter of pmFilters) {
|
|
34
|
+
const { name, version, binPath } = parsePmSpec(filter);
|
|
35
|
+
if (name === "npm") adapters.push(require_npm.createNpmAdapter(binPath, version));
|
|
36
|
+
else if (name === "pnpm") adapters.push(require_pnpm.createPnpmAdapter(binPath, version));
|
|
37
|
+
else if (name === "yarn-classic" || name === "yarn1") throw new Error("yarn classic (v1) is no longer supported. Use yarn-modern (Yarn 3+) instead.");
|
|
38
|
+
else if (name === "yarn-modern" || name === "yarn") adapters.push(require_yarn_modern.createYarnModernAdapter(binPath, version));
|
|
39
|
+
else if (name === "bun") adapters.push(require_bun.createBunAdapter(binPath, version));
|
|
40
|
+
else if (name === "deno") adapters.push(require_deno.createDenoAdapter(binPath, version));
|
|
41
|
+
else throw new Error(`Unknown package manager: "${name}". Supported: npm, pnpm, yarn-modern, bun, deno`);
|
|
42
|
+
}
|
|
43
|
+
return adapters;
|
|
44
|
+
}
|
|
45
|
+
function parseArgs(argv) {
|
|
46
|
+
const options = {
|
|
47
|
+
registry: "",
|
|
48
|
+
pm: [],
|
|
49
|
+
test: [],
|
|
50
|
+
concurrency: 1,
|
|
51
|
+
timeout: 5e4,
|
|
52
|
+
verbose: false
|
|
53
|
+
};
|
|
54
|
+
for (let i = 2; i < argv.length; i++) {
|
|
55
|
+
const arg = argv[i];
|
|
56
|
+
if (arg === "--registry" || arg === "-r") options.registry = argv[++i];
|
|
57
|
+
else if (arg === "--pm") options.pm.push(argv[++i]);
|
|
58
|
+
else if (arg === "--test" || arg === "-t") options.test.push(argv[++i]);
|
|
59
|
+
else if (arg === "--concurrency" || arg === "-c") options.concurrency = parseInt(argv[++i], 10);
|
|
60
|
+
else if (arg === "--timeout") options.timeout = parseInt(argv[++i], 10);
|
|
61
|
+
else if (arg === "--token") options.token = argv[++i];
|
|
62
|
+
else if (arg === "--uplink-port") options.uplinkPort = parseInt(argv[++i], 10);
|
|
63
|
+
else if (arg === "--print-config") options.printConfig = true;
|
|
64
|
+
else if (arg === "--verbose" || arg === "-v") options.verbose = true;
|
|
65
|
+
else if (arg === "--help" || arg === "-h") {
|
|
66
|
+
printHelp();
|
|
67
|
+
process.exit(0);
|
|
68
|
+
} else if (arg.startsWith("--registry=")) options.registry = arg.split("=")[1];
|
|
69
|
+
else if (arg.startsWith("--pm=")) options.pm.push(arg.split("=")[1]);
|
|
70
|
+
else if (arg.startsWith("--test=")) options.test.push(arg.split("=")[1]);
|
|
71
|
+
else if (arg.startsWith("--token=")) options.token = arg.split("=")[1];
|
|
72
|
+
else if (arg.startsWith("--timeout=")) options.timeout = parseInt(arg.split("=")[1], 10);
|
|
73
|
+
else if (arg.startsWith("--uplink-port=")) options.uplinkPort = parseInt(arg.split("=")[1], 10);
|
|
74
|
+
else {
|
|
75
|
+
console.error(`Unknown argument: ${arg}`);
|
|
76
|
+
printHelp();
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return options;
|
|
81
|
+
}
|
|
82
|
+
function printHelp() {
|
|
83
|
+
console.log(`
|
|
84
|
+
@verdaccio/e2e-cli - Run Verdaccio e2e tests against any running registry
|
|
85
|
+
|
|
86
|
+
Usage:
|
|
87
|
+
verdaccio-e2e --registry <url> [options]
|
|
88
|
+
|
|
89
|
+
Required:
|
|
90
|
+
-r, --registry <url> Verdaccio registry URL (e.g. http://localhost:4873)
|
|
91
|
+
|
|
92
|
+
Options:
|
|
93
|
+
--pm <name[@version]> Package manager to test (can be repeated)
|
|
94
|
+
Supported: npm (10-12), pnpm (10+),
|
|
95
|
+
yarn-modern (or yarn, Yarn 3+), bun, deno
|
|
96
|
+
Examples: --pm npm@10 --pm pnpm@11
|
|
97
|
+
--pm yarn-modern@4
|
|
98
|
+
--pm yarn-modern@3
|
|
99
|
+
--pm bun
|
|
100
|
+
--pm npm --pm pnpm (uses system version)
|
|
101
|
+
Auto-installs the requested yarn version if needed
|
|
102
|
+
Default: npm
|
|
103
|
+
|
|
104
|
+
-t, --test <name> Filter tests by name (can be repeated)
|
|
105
|
+
Available: publish, install, ci, audit, info, deprecate,
|
|
106
|
+
dist-tags, ping, search, unpublish
|
|
107
|
+
Scenarios: scenario:install-multiple-deps,
|
|
108
|
+
scenario:minimum-release-age (pnpm 11.1+),
|
|
109
|
+
scenario:tarballs (npm adapter),
|
|
110
|
+
scenario:metadata (npm adapter),
|
|
111
|
+
scenario:search (npm adapter; the
|
|
112
|
+
uplink sub-tests also need
|
|
113
|
+
--uplink-port / E2E_UPLINK_PORT),
|
|
114
|
+
scenario:uplink-failure (npm adapter,
|
|
115
|
+
needs --uplink-port / E2E_UPLINK_PORT
|
|
116
|
+
and a registry started with the config
|
|
117
|
+
from --print-config)
|
|
118
|
+
Default: all supported by the PM
|
|
119
|
+
|
|
120
|
+
--token <token> Auth token (skips user creation)
|
|
121
|
+
--timeout <ms> Per-test timeout (default: 50000)
|
|
122
|
+
--uplink-port <port> Port for the mock uplink used by
|
|
123
|
+
scenario:uplink-failure (default: $E2E_UPLINK_PORT)
|
|
124
|
+
--print-config Print the recommended Verdaccio config for the full
|
|
125
|
+
battery (max_body_size, mock uplink) and exit
|
|
126
|
+
-v, --verbose Enable debug output
|
|
127
|
+
-h, --help Show this help
|
|
128
|
+
`);
|
|
129
|
+
}
|
|
130
|
+
async function main(argv = process.argv) {
|
|
131
|
+
const options = parseArgs(argv);
|
|
132
|
+
if (options.printConfig) {
|
|
133
|
+
const { buildE2EConfig, DEFAULT_UPLINK_PORT } = await Promise.resolve().then(() => require("./utils/e2e-config.cjs"));
|
|
134
|
+
process.stdout.write(buildE2EConfig(options.uplinkPort ?? DEFAULT_UPLINK_PORT));
|
|
135
|
+
process.exit(0);
|
|
136
|
+
}
|
|
137
|
+
if (options.uplinkPort) process.env.E2E_UPLINK_PORT = String(options.uplinkPort);
|
|
138
|
+
if (!options.registry) {
|
|
139
|
+
console.error("Error: --registry is required\n");
|
|
140
|
+
printHelp();
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
const { createTempFolder } = await Promise.resolve().then(() => require("./utils/project.cjs"));
|
|
144
|
+
const runDir = await createTempFolder("e2e-run");
|
|
145
|
+
process.chdir(runDir);
|
|
146
|
+
if (options.verbose) {
|
|
147
|
+
const { setVerbose } = await Promise.resolve().then(() => require("./utils/process.cjs"));
|
|
148
|
+
setVerbose(true);
|
|
149
|
+
}
|
|
150
|
+
console.log(`Checking registry at ${options.registry}...`);
|
|
151
|
+
if (!await require_registry_client.pingRegistry(options.registry)) {
|
|
152
|
+
console.error(`Error: Registry at ${options.registry} is not reachable`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
console.log(`Registry is alive.`);
|
|
156
|
+
let token = options.token;
|
|
157
|
+
if (!token) {
|
|
158
|
+
console.log("Creating test user...");
|
|
159
|
+
const auth = await require_registry_client.createUser(options.registry);
|
|
160
|
+
token = auth.token;
|
|
161
|
+
console.log(`User "${auth.user}" created.`);
|
|
162
|
+
}
|
|
163
|
+
const adapters = parseAdapters(options.pm);
|
|
164
|
+
console.log(`Adapters: ${adapters.map((a) => a.name).join(", ")}`);
|
|
165
|
+
const tests = options.test && options.test.length > 0 ? require_index$2.allTests.filter((t) => options.test.includes(t.name)) : require_index$2.allTests;
|
|
166
|
+
console.log(`Tests: ${tests.map((t) => t.name).join(", ")}`);
|
|
167
|
+
const { exitCode } = await require_runner.runAll(adapters, tests, options.registry, token, {
|
|
168
|
+
timeout: options.timeout,
|
|
169
|
+
concurrency: options.concurrency,
|
|
170
|
+
testFilter: options.test
|
|
171
|
+
});
|
|
172
|
+
process.exit(exitCode);
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
exports.allScenarios = require_index$1.allScenarios;
|
|
176
|
+
exports.allTests = require_index$2.allTests;
|
|
177
|
+
exports.createBunAdapter = require_bun.createBunAdapter;
|
|
178
|
+
exports.createDenoAdapter = require_deno.createDenoAdapter;
|
|
179
|
+
exports.createNpmAdapter = require_npm.createNpmAdapter;
|
|
180
|
+
exports.createPnpmAdapter = require_pnpm.createPnpmAdapter;
|
|
181
|
+
exports.createYarnModernAdapter = require_yarn_modern.createYarnModernAdapter;
|
|
182
|
+
exports.main = main;
|
|
183
|
+
exports.runAll = require_runner.runAll;
|
|
184
|
+
exports.runSuite = require_runner.runSuite;
|
|
185
|
+
|
|
186
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport {\n createBunAdapter,\n createDenoAdapter,\n createNpmAdapter,\n createPnpmAdapter,\n createYarnModernAdapter,\n} from './adapters';\nimport { runAll } from './runner';\nimport { allTests } from './tests';\nimport { CliOptions, PackageManagerAdapter } from './types';\nimport { createUser, pingRegistry } from './utils/registry-client';\n\nconst debug = buildDebug('verdaccio:e2e-cli');\n\nfunction parsePmSpec(filter: string): { name: string; version?: string; binPath?: string } {\n // --pm yarn-modern@3, --pm npm@10, --pm npm=/path/to/bin\n const eqIdx = filter.indexOf('=');\n if (eqIdx !== -1) {\n return { name: filter.slice(0, eqIdx).toLowerCase(), binPath: filter.slice(eqIdx + 1) };\n }\n const atIdx = filter.indexOf('@');\n if (atIdx !== -1) {\n return { name: filter.slice(0, atIdx).toLowerCase(), version: filter.slice(atIdx + 1) };\n }\n return { name: filter.toLowerCase() };\n}\n\nfunction parseAdapters(pmFilters?: string[]): PackageManagerAdapter[] {\n if (!pmFilters || pmFilters.length === 0) {\n return [createNpmAdapter()];\n }\n\n const adapters: PackageManagerAdapter[] = [];\n\n for (const filter of pmFilters) {\n const { name, version, binPath } = parsePmSpec(filter);\n\n if (name === 'npm') {\n adapters.push(createNpmAdapter(binPath, version));\n } else if (name === 'pnpm') {\n adapters.push(createPnpmAdapter(binPath, version));\n } else if (name === 'yarn-classic' || name === 'yarn1') {\n throw new Error(\n 'yarn classic (v1) is no longer supported. Use yarn-modern (Yarn 3+) instead.'\n );\n } else if (name === 'yarn-modern' || name === 'yarn') {\n adapters.push(createYarnModernAdapter(binPath, version));\n } else if (name === 'bun') {\n adapters.push(createBunAdapter(binPath, version));\n } else if (name === 'deno') {\n adapters.push(createDenoAdapter(binPath, version));\n } else {\n throw new Error(\n `Unknown package manager: \"${name}\". Supported: npm, pnpm, yarn-modern, bun, deno`\n );\n }\n }\n\n return adapters;\n}\n\nfunction parseArgs(argv: string[]): CliOptions {\n const options: CliOptions = {\n registry: '',\n pm: [],\n test: [],\n concurrency: 1,\n timeout: 50000,\n verbose: false,\n };\n\n for (let i = 2; i < argv.length; i++) {\n const arg = argv[i];\n\n if (arg === '--registry' || arg === '-r') {\n options.registry = argv[++i];\n } else if (arg === '--pm') {\n options.pm!.push(argv[++i]);\n } else if (arg === '--test' || arg === '-t') {\n options.test!.push(argv[++i]);\n } else if (arg === '--concurrency' || arg === '-c') {\n options.concurrency = parseInt(argv[++i], 10);\n } else if (arg === '--timeout') {\n options.timeout = parseInt(argv[++i], 10);\n } else if (arg === '--token') {\n options.token = argv[++i];\n } else if (arg === '--uplink-port') {\n options.uplinkPort = parseInt(argv[++i], 10);\n } else if (arg === '--print-config') {\n options.printConfig = true;\n } else if (arg === '--verbose' || arg === '-v') {\n options.verbose = true;\n } else if (arg === '--help' || arg === '-h') {\n printHelp();\n process.exit(0);\n } else if (arg.startsWith('--registry=')) {\n options.registry = arg.split('=')[1];\n } else if (arg.startsWith('--pm=')) {\n options.pm!.push(arg.split('=')[1]);\n } else if (arg.startsWith('--test=')) {\n options.test!.push(arg.split('=')[1]);\n } else if (arg.startsWith('--token=')) {\n options.token = arg.split('=')[1];\n } else if (arg.startsWith('--timeout=')) {\n options.timeout = parseInt(arg.split('=')[1], 10);\n } else if (arg.startsWith('--uplink-port=')) {\n options.uplinkPort = parseInt(arg.split('=')[1], 10);\n } else {\n console.error(`Unknown argument: ${arg}`);\n printHelp();\n process.exit(1);\n }\n }\n\n return options;\n}\n\nfunction printHelp(): void {\n console.log(`\n @verdaccio/e2e-cli - Run Verdaccio e2e tests against any running registry\n\n Usage:\n verdaccio-e2e --registry <url> [options]\n\n Required:\n -r, --registry <url> Verdaccio registry URL (e.g. http://localhost:4873)\n\n Options:\n --pm <name[@version]> Package manager to test (can be repeated)\n Supported: npm (10-12), pnpm (10+),\n yarn-modern (or yarn, Yarn 3+), bun, deno\n Examples: --pm npm@10 --pm pnpm@11\n --pm yarn-modern@4\n --pm yarn-modern@3\n --pm bun\n --pm npm --pm pnpm (uses system version)\n Auto-installs the requested yarn version if needed\n Default: npm\n\n -t, --test <name> Filter tests by name (can be repeated)\n Available: publish, install, ci, audit, info, deprecate,\n dist-tags, ping, search, unpublish\n Scenarios: scenario:install-multiple-deps,\n scenario:minimum-release-age (pnpm 11.1+),\n scenario:tarballs (npm adapter),\n scenario:metadata (npm adapter),\n scenario:search (npm adapter; the\n uplink sub-tests also need\n --uplink-port / E2E_UPLINK_PORT),\n scenario:uplink-failure (npm adapter,\n needs --uplink-port / E2E_UPLINK_PORT\n and a registry started with the config\n from --print-config)\n Default: all supported by the PM\n\n --token <token> Auth token (skips user creation)\n --timeout <ms> Per-test timeout (default: 50000)\n --uplink-port <port> Port for the mock uplink used by\n scenario:uplink-failure (default: $E2E_UPLINK_PORT)\n --print-config Print the recommended Verdaccio config for the full\n battery (max_body_size, mock uplink) and exit\n -v, --verbose Enable debug output\n -h, --help Show this help\n `);\n}\n\nexport async function main(argv: string[] = process.argv): Promise<void> {\n const options = parseArgs(argv);\n\n if (options.printConfig) {\n const { buildE2EConfig, DEFAULT_UPLINK_PORT } = await import('./utils/e2e-config');\n process.stdout.write(buildE2EConfig(options.uplinkPort ?? DEFAULT_UPLINK_PORT));\n process.exit(0);\n }\n\n // Expose the mock uplink port to scenarios (scenario:uplink-failure gates on it).\n if (options.uplinkPort) {\n process.env.E2E_UPLINK_PORT = String(options.uplinkPort);\n }\n\n if (!options.registry) {\n console.error('Error: --registry is required\\n');\n printHelp();\n process.exit(1);\n }\n\n // Run from a temp dir to isolate from the host project's packageManager, .yarnrc.yml, etc.\n const { createTempFolder } = await import('./utils/project');\n const runDir = await createTempFolder('e2e-run');\n process.chdir(runDir);\n\n if (options.verbose) {\n const { setVerbose } = await import('./utils/process');\n setVerbose(true);\n }\n\n // Ensure registry is reachable\n console.log(`Checking registry at ${options.registry}...`);\n const alive = await pingRegistry(options.registry);\n if (!alive) {\n console.error(`Error: Registry at ${options.registry} is not reachable`);\n process.exit(1);\n }\n console.log(`Registry is alive.`);\n\n // Get auth token\n let token = options.token;\n if (!token) {\n console.log('Creating test user...');\n const auth = await createUser(options.registry);\n token = auth.token;\n console.log(`User \"${auth.user}\" created.`);\n }\n\n // Build adapter list\n const adapters = parseAdapters(options.pm);\n console.log(`Adapters: ${adapters.map((a) => a.name).join(', ')}`);\n\n // Filter tests\n const tests =\n options.test && options.test.length > 0\n ? allTests.filter((t) => options.test!.includes(t.name))\n : allTests;\n\n console.log(`Tests: ${tests.map((t) => t.name).join(', ')}`);\n\n // Run\n const { exitCode } = await runAll(adapters, tests, options.registry, token, {\n timeout: options.timeout,\n concurrency: options.concurrency,\n testFilter: options.test,\n });\n\n process.exit(exitCode);\n}\n\n// Re-export for programmatic usage\nexport { allTests } from './tests';\nexport { allScenarios } from './scenarios';\nexport {\n createBunAdapter,\n createDenoAdapter,\n createNpmAdapter,\n createPnpmAdapter,\n createYarnModernAdapter,\n} from './adapters';\nexport { runAll, runSuite } from './runner';\nexport type { PackageManagerAdapter, TestDefinition, TestContext, CliOptions } from './types';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
let fs = require("fs");
|
|
2
|
+
//#region src/reporter.ts
|
|
3
|
+
var COLORS = {
|
|
4
|
+
reset: "\x1B[0m",
|
|
5
|
+
red: "\x1B[31m",
|
|
6
|
+
green: "\x1B[32m",
|
|
7
|
+
yellow: "\x1B[33m",
|
|
8
|
+
cyan: "\x1B[36m",
|
|
9
|
+
dim: "\x1B[2m",
|
|
10
|
+
bold: "\x1B[1m"
|
|
11
|
+
};
|
|
12
|
+
function formatDuration(ms) {
|
|
13
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
14
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
15
|
+
}
|
|
16
|
+
function reportTestStart(adapterName, testName) {
|
|
17
|
+
process.stdout.write(` ${COLORS.dim}running${COLORS.reset} ${adapterName} > ${testName}...\n`);
|
|
18
|
+
}
|
|
19
|
+
function reportTestResult(result, hasSubTests = false) {
|
|
20
|
+
if (result.passed) {
|
|
21
|
+
if (!hasSubTests) process.stdout.write(` ${COLORS.green}✓${COLORS.reset} ${result.name} ${COLORS.dim}${formatDuration(result.duration)}${COLORS.reset}\n`);
|
|
22
|
+
else process.stdout.write(` ${COLORS.green}PASS${COLORS.reset} ${result.name} ${COLORS.dim}${formatDuration(result.duration)}${COLORS.reset}\n`);
|
|
23
|
+
} else {
|
|
24
|
+
process.stdout.write(` ${COLORS.red}FAIL${COLORS.reset} ${result.name} ${COLORS.dim}${formatDuration(result.duration)}${COLORS.reset}\n`);
|
|
25
|
+
if (result.error) {
|
|
26
|
+
const lines = result.error.split("\n");
|
|
27
|
+
for (const line of lines) console.log(` ${COLORS.red}${line}${COLORS.reset}`);
|
|
28
|
+
if (process.env.GITHUB_ACTIONS) {
|
|
29
|
+
const msg = result.error.split("\n")[0];
|
|
30
|
+
console.log(`::error title=E2E ${result.name}::${msg}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function reportSuiteStart(adapterName) {
|
|
36
|
+
console.log(`\n${COLORS.bold}${COLORS.cyan}${adapterName}${COLORS.reset}`);
|
|
37
|
+
}
|
|
38
|
+
function reportSubTestResult(label, passed, duration) {
|
|
39
|
+
const icon = passed ? `${COLORS.bold}${COLORS.green}✓${COLORS.reset}` : `${COLORS.bold}${COLORS.red}✗${COLORS.reset}`;
|
|
40
|
+
const dur = duration !== void 0 ? ` ${COLORS.dim}${formatDuration(duration)}${COLORS.reset}` : "";
|
|
41
|
+
process.stdout.write(`\n ${icon} ${COLORS.bold}${label}${COLORS.reset}${dur}\n\n`);
|
|
42
|
+
}
|
|
43
|
+
function reportSkipped(testName) {
|
|
44
|
+
console.log(` ${COLORS.yellow}SKIP${COLORS.reset} ${testName}`);
|
|
45
|
+
}
|
|
46
|
+
function reportSummary(results) {
|
|
47
|
+
console.log(`\n${COLORS.bold}${"=".repeat(50)}${COLORS.reset}`);
|
|
48
|
+
console.log(`${COLORS.bold}Summary${COLORS.reset}\n`);
|
|
49
|
+
let totalPassed = 0;
|
|
50
|
+
let totalFailed = 0;
|
|
51
|
+
let totalSkipped = 0;
|
|
52
|
+
let totalDuration = 0;
|
|
53
|
+
for (const suite of results) {
|
|
54
|
+
const status = suite.failed > 0 ? COLORS.red : COLORS.green;
|
|
55
|
+
const icon = suite.failed > 0 ? "x" : "v";
|
|
56
|
+
console.log(` ${status}${icon}${COLORS.reset} ${suite.adapter}: ${COLORS.green}${suite.passed} passed${COLORS.reset}, ${COLORS.red}${suite.failed} failed${COLORS.reset}, ${COLORS.yellow}${suite.skipped} skipped${COLORS.reset} ${COLORS.dim}(${formatDuration(suite.duration)})${COLORS.reset}`);
|
|
57
|
+
totalPassed += suite.passed;
|
|
58
|
+
totalFailed += suite.failed;
|
|
59
|
+
totalSkipped += suite.skipped;
|
|
60
|
+
totalDuration += suite.duration;
|
|
61
|
+
}
|
|
62
|
+
console.log(`\n Total: ${COLORS.green}${totalPassed} passed${COLORS.reset}, ${COLORS.red}${totalFailed} failed${COLORS.reset}, ${COLORS.yellow}${totalSkipped} skipped${COLORS.reset} ${COLORS.dim}(${formatDuration(totalDuration)})${COLORS.reset}`);
|
|
63
|
+
console.log(`${COLORS.bold}${"=".repeat(50)}${COLORS.reset}\n`);
|
|
64
|
+
const summaryFile = process.env.GITHUB_STEP_SUMMARY;
|
|
65
|
+
if (summaryFile) writeGitHubSummary(summaryFile, results);
|
|
66
|
+
}
|
|
67
|
+
function writeGitHubSummary(summaryFile, results) {
|
|
68
|
+
const lines = [];
|
|
69
|
+
lines.push("## E2E Test Results\n");
|
|
70
|
+
for (const suite of results) {
|
|
71
|
+
const status = suite.failed > 0 ? "❌" : "✅";
|
|
72
|
+
lines.push(`### ${status} ${suite.adapter}\n`);
|
|
73
|
+
lines.push("| Test | Status | Duration |");
|
|
74
|
+
lines.push("|------|--------|----------|");
|
|
75
|
+
for (const test of suite.tests) {
|
|
76
|
+
const icon = test.passed ? "✅" : "❌";
|
|
77
|
+
const dur = formatDuration(test.duration);
|
|
78
|
+
if (test.subTests && test.subTests.length > 0) {
|
|
79
|
+
lines.push(`| **${test.name}** | ${icon} | ${dur} |`);
|
|
80
|
+
for (const sub of test.subTests) {
|
|
81
|
+
const subIcon = sub.passed ? "✅" : "❌";
|
|
82
|
+
const subDur = formatDuration(sub.duration);
|
|
83
|
+
const label = sub.passed ? sub.label : `${sub.label}: ${sub.error?.split("\n")[0] ?? ""}`;
|
|
84
|
+
lines.push(`| ${label} | ${subIcon} | ${subDur} |`);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
const label = test.passed ? test.name : `${test.name}: ${test.error?.split("\n")[0] ?? ""}`;
|
|
88
|
+
lines.push(`| ${label} | ${icon} | ${dur} |`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
lines.push("");
|
|
92
|
+
}
|
|
93
|
+
let totalPassed = 0;
|
|
94
|
+
let totalFailed = 0;
|
|
95
|
+
let totalSkipped = 0;
|
|
96
|
+
for (const suite of results) {
|
|
97
|
+
totalPassed += suite.passed;
|
|
98
|
+
totalFailed += suite.failed;
|
|
99
|
+
totalSkipped += suite.skipped;
|
|
100
|
+
}
|
|
101
|
+
const emoji = totalFailed > 0 ? "❌" : "✅";
|
|
102
|
+
lines.push(`${emoji} **${totalPassed} passed**, **${totalFailed} failed**, **${totalSkipped} skipped**\n`);
|
|
103
|
+
(0, fs.appendFileSync)(summaryFile, lines.join("\n"));
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
exports.reportSkipped = reportSkipped;
|
|
107
|
+
exports.reportSubTestResult = reportSubTestResult;
|
|
108
|
+
exports.reportSuiteStart = reportSuiteStart;
|
|
109
|
+
exports.reportSummary = reportSummary;
|
|
110
|
+
exports.reportTestResult = reportTestResult;
|
|
111
|
+
exports.reportTestStart = reportTestStart;
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=reporter.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.cjs","names":[],"sources":["../../src/reporter.ts"],"sourcesContent":["import { appendFileSync } from 'fs';\n\nimport { SuiteResult, TestResult } from './types';\n\nconst COLORS = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n};\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nexport function reportTestStart(adapterName: string, testName: string): void {\n process.stdout.write(` ${COLORS.dim}running${COLORS.reset} ${adapterName} > ${testName}...\\n`);\n}\n\nexport function reportTestResult(result: TestResult, hasSubTests = false): void {\n if (result.passed) {\n if (!hasSubTests) {\n process.stdout.write(\n ` ${COLORS.green}✓${COLORS.reset} ${result.name} ${COLORS.dim}${formatDuration(result.duration)}${COLORS.reset}\\n`\n );\n } else {\n process.stdout.write(\n ` ${COLORS.green}PASS${COLORS.reset} ${result.name} ${COLORS.dim}${formatDuration(result.duration)}${COLORS.reset}\\n`\n );\n }\n } else {\n process.stdout.write(\n ` ${COLORS.red}FAIL${COLORS.reset} ${result.name} ${COLORS.dim}${formatDuration(result.duration)}${COLORS.reset}\\n`\n );\n if (result.error) {\n const lines = result.error.split('\\n');\n for (const line of lines) {\n console.log(` ${COLORS.red}${line}${COLORS.reset}`);\n }\n // GitHub Actions annotation\n if (process.env.GITHUB_ACTIONS) {\n const msg = result.error.split('\\n')[0];\n console.log(`::error title=E2E ${result.name}::${msg}`);\n }\n }\n }\n}\n\nexport function reportSuiteStart(adapterName: string): void {\n console.log(`\\n${COLORS.bold}${COLORS.cyan}${adapterName}${COLORS.reset}`);\n}\n\nexport function reportSubTestResult(label: string, passed: boolean, duration?: number): void {\n const icon = passed\n ? `${COLORS.bold}${COLORS.green}✓${COLORS.reset}`\n : `${COLORS.bold}${COLORS.red}✗${COLORS.reset}`;\n const dur =\n duration !== undefined ? ` ${COLORS.dim}${formatDuration(duration)}${COLORS.reset}` : '';\n process.stdout.write(`\\n ${icon} ${COLORS.bold}${label}${COLORS.reset}${dur}\\n\\n`);\n}\n\nexport function reportSkipped(testName: string): void {\n console.log(` ${COLORS.yellow}SKIP${COLORS.reset} ${testName}`);\n}\n\nexport function reportSummary(results: SuiteResult[]): void {\n console.log(`\\n${COLORS.bold}${'='.repeat(50)}${COLORS.reset}`);\n console.log(`${COLORS.bold}Summary${COLORS.reset}\\n`);\n\n let totalPassed = 0;\n let totalFailed = 0;\n let totalSkipped = 0;\n let totalDuration = 0;\n\n for (const suite of results) {\n const status = suite.failed > 0 ? COLORS.red : COLORS.green;\n const icon = suite.failed > 0 ? 'x' : 'v';\n console.log(\n ` ${status}${icon}${COLORS.reset} ${suite.adapter}: ` +\n `${COLORS.green}${suite.passed} passed${COLORS.reset}, ` +\n `${COLORS.red}${suite.failed} failed${COLORS.reset}, ` +\n `${COLORS.yellow}${suite.skipped} skipped${COLORS.reset} ` +\n `${COLORS.dim}(${formatDuration(suite.duration)})${COLORS.reset}`\n );\n totalPassed += suite.passed;\n totalFailed += suite.failed;\n totalSkipped += suite.skipped;\n totalDuration += suite.duration;\n }\n\n console.log(\n `\\n Total: ${COLORS.green}${totalPassed} passed${COLORS.reset}, ` +\n `${COLORS.red}${totalFailed} failed${COLORS.reset}, ` +\n `${COLORS.yellow}${totalSkipped} skipped${COLORS.reset} ` +\n `${COLORS.dim}(${formatDuration(totalDuration)})${COLORS.reset}`\n );\n console.log(`${COLORS.bold}${'='.repeat(50)}${COLORS.reset}\\n`);\n\n // GitHub Actions Job Summary\n const summaryFile = process.env.GITHUB_STEP_SUMMARY;\n if (summaryFile) {\n writeGitHubSummary(summaryFile, results);\n }\n}\n\nfunction writeGitHubSummary(summaryFile: string, results: SuiteResult[]): void {\n const lines: string[] = [];\n\n lines.push('## E2E Test Results\\n');\n\n for (const suite of results) {\n const status = suite.failed > 0 ? '❌' : '✅';\n lines.push(`### ${status} ${suite.adapter}\\n`);\n lines.push('| Test | Status | Duration |');\n lines.push('|------|--------|----------|');\n\n for (const test of suite.tests) {\n const icon = test.passed ? '✅' : '❌';\n const dur = formatDuration(test.duration);\n\n if (test.subTests && test.subTests.length > 0) {\n // Parent row\n lines.push(`| **${test.name}** | ${icon} | ${dur} |`);\n // Sub-test rows\n for (const sub of test.subTests) {\n const subIcon = sub.passed ? '✅' : '❌';\n const subDur = formatDuration(sub.duration);\n const label = sub.passed ? sub.label : `${sub.label}: ${sub.error?.split('\\n')[0] ?? ''}`;\n lines.push(`| ${label} | ${subIcon} | ${subDur} |`);\n }\n } else {\n const label = test.passed ? test.name : `${test.name}: ${test.error?.split('\\n')[0] ?? ''}`;\n lines.push(`| ${label} | ${icon} | ${dur} |`);\n }\n }\n\n lines.push('');\n }\n\n let totalPassed = 0;\n let totalFailed = 0;\n let totalSkipped = 0;\n for (const suite of results) {\n totalPassed += suite.passed;\n totalFailed += suite.failed;\n totalSkipped += suite.skipped;\n }\n\n const emoji = totalFailed > 0 ? '❌' : '✅';\n lines.push(\n `${emoji} **${totalPassed} passed**, **${totalFailed} failed**, **${totalSkipped} skipped**\\n`\n );\n\n appendFileSync(summaryFile, lines.join('\\n'));\n}\n"],"mappings":"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"}
|