@tryarcanist/cli 0.1.63 → 0.1.65
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/dist/index.js +90 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2070,6 +2070,85 @@ async function stopCommand(sessionId, options = {}, command) {
|
|
|
2070
2070
|
);
|
|
2071
2071
|
}
|
|
2072
2072
|
|
|
2073
|
+
// src/commands/test-creds.ts
|
|
2074
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
2075
|
+
function parseRepoArg(repo) {
|
|
2076
|
+
const trimmed = repo.trim();
|
|
2077
|
+
const slashIndex = trimmed.indexOf("/");
|
|
2078
|
+
if (slashIndex <= 0 || slashIndex === trimmed.length - 1) {
|
|
2079
|
+
throw new CliError("user", `repo must be in the form 'owner/name' (got: '${repo}')`);
|
|
2080
|
+
}
|
|
2081
|
+
return { owner: trimmed.slice(0, slashIndex), name: trimmed.slice(slashIndex + 1) };
|
|
2082
|
+
}
|
|
2083
|
+
function basePath(businessId, repo) {
|
|
2084
|
+
return `/api/businesses/${encodeURIComponent(businessId)}/repos/${encodeURIComponent(repo.owner)}/${encodeURIComponent(repo.name)}/test-credentials`;
|
|
2085
|
+
}
|
|
2086
|
+
function readValue(options) {
|
|
2087
|
+
const sources = [options.value, options.valueFile, options.valueStdin].filter((v) => v !== void 0 && v !== false);
|
|
2088
|
+
if (sources.length !== 1) {
|
|
2089
|
+
throw new CliError("user", "Provide exactly one of --value, --value-file, or --value-stdin.");
|
|
2090
|
+
}
|
|
2091
|
+
if (options.value !== void 0) return options.value;
|
|
2092
|
+
const raw = options.valueFile ? readFileSync2(options.valueFile, "utf8") : readFileSync2(0, "utf8");
|
|
2093
|
+
return raw.replace(/\r?\n$/, "");
|
|
2094
|
+
}
|
|
2095
|
+
async function listTestCredentialsCommand(repo, options, command) {
|
|
2096
|
+
const runtime = getRuntimeOptions(command, options);
|
|
2097
|
+
const config = requireConfig(runtime);
|
|
2098
|
+
const repoArg = parseRepoArg(repo);
|
|
2099
|
+
const payload = await apiFetch(config, basePath(options.business, repoArg));
|
|
2100
|
+
if (isJson(command, options)) {
|
|
2101
|
+
writeJson(payload);
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
if (payload.credentials.length === 0) {
|
|
2105
|
+
console.log(`No test credentials configured for ${repoArg.owner}/${repoArg.name}.`);
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
for (const cred of payload.credentials) {
|
|
2109
|
+
const ts = new Date(cred.updatedAt).toISOString();
|
|
2110
|
+
console.log(`${cred.name} ${ts} ${cred.rotatedByUserId ?? "-"}`);
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
async function setTestCredentialCommand(repo, name, options, command) {
|
|
2114
|
+
const runtime = getRuntimeOptions(command, options);
|
|
2115
|
+
const config = requireConfig(runtime);
|
|
2116
|
+
const repoArg = parseRepoArg(repo);
|
|
2117
|
+
const value = readValue(options);
|
|
2118
|
+
const payload = await apiFetch(
|
|
2119
|
+
config,
|
|
2120
|
+
`${basePath(options.business, repoArg)}/${encodeURIComponent(name)}`,
|
|
2121
|
+
{ method: "PUT", body: JSON.stringify({ value }) }
|
|
2122
|
+
);
|
|
2123
|
+
if (isJson(command, options)) {
|
|
2124
|
+
writeJson(payload);
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
console.log(`Set test credential '${name}' for ${repoArg.owner}/${repoArg.name}.`);
|
|
2128
|
+
}
|
|
2129
|
+
async function deleteTestCredentialCommand(repo, name, options, command) {
|
|
2130
|
+
if (isJson(command, options) && options.yes !== true) {
|
|
2131
|
+
throw new CliError("user", "`test-creds delete --json` requires --yes.");
|
|
2132
|
+
}
|
|
2133
|
+
if (options.yes !== true) {
|
|
2134
|
+
const repoArg2 = parseRepoArg(repo);
|
|
2135
|
+
await confirmOrThrow(`Delete test credential '${name}' for ${repoArg2.owner}/${repoArg2.name}?`);
|
|
2136
|
+
}
|
|
2137
|
+
const runtime = getRuntimeOptions(command, options);
|
|
2138
|
+
const config = requireConfig(runtime);
|
|
2139
|
+
const repoArg = parseRepoArg(repo);
|
|
2140
|
+
const payload = await apiFetch(
|
|
2141
|
+
config,
|
|
2142
|
+
`${basePath(options.business, repoArg)}/${encodeURIComponent(name)}`,
|
|
2143
|
+
{ method: "DELETE" }
|
|
2144
|
+
);
|
|
2145
|
+
if (isJson(command, options)) {
|
|
2146
|
+
writeJson(payload);
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
console.log(`Deleted test credential '${name}' for ${repoArg.owner}/${repoArg.name}.`);
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2073
2152
|
// src/commands/tokens.ts
|
|
2074
2153
|
async function listTokensCommand(options, command) {
|
|
2075
2154
|
const runtime = getRuntimeOptions(command, options);
|
|
@@ -2318,6 +2397,17 @@ Examples:
|
|
|
2318
2397
|
arcanist tokens revoke 42 --yes --json
|
|
2319
2398
|
`
|
|
2320
2399
|
).action((id, options, command) => revokeTokenCommand(id, options, command));
|
|
2400
|
+
var testCreds = program.command("test-creds").description("Manage repo-scoped test credentials referenced by appRuntime.e2e.credentials in .arcanist.json");
|
|
2401
|
+
testCreds.command("list").description("List test credentials configured for a repo").argument("<repo>", "Repository in 'owner/name' form").requiredOption("--business <id>", "Business ID that owns the repo").action((repo, options, command) => listTestCredentialsCommand(repo, options, command));
|
|
2402
|
+
testCreds.command("set").description("Set or rotate a test credential value").argument("<repo>", "Repository in 'owner/name' form").argument("<name>", "Credential name (must match credentials[].name in .arcanist.json)").requiredOption("--business <id>", "Business ID that owns the repo").option("--value <value>", "Credential value (insecure on shared shells; prefer --value-stdin)").option("--value-file <path>", "Read value from a file").option("--value-stdin", "Read value from stdin").addHelpText(
|
|
2403
|
+
"after",
|
|
2404
|
+
`
|
|
2405
|
+
Examples:
|
|
2406
|
+
echo "$E2E_PASS" | arcanist test-creds set tryarcanist/arcanist test_user_password --business biz-1 --value-stdin
|
|
2407
|
+
arcanist test-creds set tryarcanist/arcanist test_user_email --business biz-1 --value-file ./email.txt
|
|
2408
|
+
`
|
|
2409
|
+
).action((repo, name, options, command) => setTestCredentialCommand(repo, name, options, command));
|
|
2410
|
+
testCreds.command("delete").description("Delete a test credential").argument("<repo>", "Repository in 'owner/name' form").argument("<name>", "Credential name").requiredOption("--business <id>", "Business ID that owns the repo").option("--yes", "Confirm deletion without prompting").action((repo, name, options, command) => deleteTestCredentialCommand(repo, name, options, command));
|
|
2321
2411
|
program.command("login").description("Authenticate with a personal access token").option("--token-stdin", "Read token from stdin instead of interactive prompt").option("--api-url <url>", "Set custom API URL").action((options, command) => {
|
|
2322
2412
|
printDeprecatedAlias("login", "auth login", command);
|
|
2323
2413
|
return loginCommand(options, command);
|