@ait-co/console-cli 0.1.20 → 0.1.21
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/cli.mjs +306 -61
- package/dist/cli.mjs.map +1 -1
- package/package.json +4 -3
package/dist/cli.mjs
CHANGED
|
@@ -340,6 +340,33 @@ async function fetchCerts(workspaceId, miniAppId, cookies, opts = {}) {
|
|
|
340
340
|
return c;
|
|
341
341
|
});
|
|
342
342
|
}
|
|
343
|
+
async function issueCert(workspaceId, miniAppId, name, cookies, opts = {}) {
|
|
344
|
+
const raw = await requestConsoleApi({
|
|
345
|
+
url: `${BASE$4}/workspaces/${workspaceId}/mini-app/${miniAppId}/cert/issue`,
|
|
346
|
+
method: "POST",
|
|
347
|
+
body: { name },
|
|
348
|
+
cookies,
|
|
349
|
+
...opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}
|
|
350
|
+
});
|
|
351
|
+
if (raw === null || typeof raw !== "object") throw new Error(`Unexpected issue-cert shape for app=${miniAppId}: not an object`);
|
|
352
|
+
const rec = raw;
|
|
353
|
+
const privateKey = typeof rec.privateKey === "string" ? rec.privateKey : null;
|
|
354
|
+
const publicKey = typeof rec.publicKey === "string" ? rec.publicKey : null;
|
|
355
|
+
if (privateKey === null || publicKey === null) throw new Error(`Unexpected issue-cert shape for app=${miniAppId}: missing privateKey/publicKey`);
|
|
356
|
+
return {
|
|
357
|
+
privateKey,
|
|
358
|
+
publicKey
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
async function revokeCert(workspaceId, miniAppId, certId, cookies, opts = {}) {
|
|
362
|
+
await requestConsoleApi({
|
|
363
|
+
url: `${BASE$4}/workspaces/${workspaceId}/mini-app/${miniAppId}/certs/${encodeURIComponent(certId)}/disable`,
|
|
364
|
+
method: "POST",
|
|
365
|
+
body: {},
|
|
366
|
+
cookies,
|
|
367
|
+
...opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
343
370
|
async function fetchShareRewards(params, cookies, opts = {}) {
|
|
344
371
|
const qs = new URLSearchParams();
|
|
345
372
|
qs.set("search", params.search ?? "");
|
|
@@ -1579,7 +1606,26 @@ const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))
|
|
|
1579
1606
|
function isValidEmail(v) {
|
|
1580
1607
|
return EMAIL_REGEX.test(v.toLowerCase());
|
|
1581
1608
|
}
|
|
1582
|
-
const
|
|
1609
|
+
const TITLE_KO_REGEX = /^[가-힣A-Za-z0-9 :·?]+$/;
|
|
1610
|
+
const TITLE_EN_REGEX = /^[A-Za-z0-9 :·?]+$/;
|
|
1611
|
+
const TITLE_KO_MAX_CODEPOINTS_NO_SPACE = 10;
|
|
1612
|
+
const TITLE_EN_MAX_CODEPOINTS_NO_SPACE = 15;
|
|
1613
|
+
function codePointsExcludingSpaces(v) {
|
|
1614
|
+
return [...v].filter((ch) => ch !== " ").length;
|
|
1615
|
+
}
|
|
1616
|
+
function isTitleCaseWord(word) {
|
|
1617
|
+
const chars = [...word];
|
|
1618
|
+
const firstLetterIdx = chars.findIndex((ch) => /[A-Za-z]/.test(ch));
|
|
1619
|
+
if (firstLetterIdx === -1) return true;
|
|
1620
|
+
for (let i = 0; i < chars.length; i++) {
|
|
1621
|
+
const ch = chars[i];
|
|
1622
|
+
if (ch === void 0 || !/[A-Za-z]/.test(ch)) continue;
|
|
1623
|
+
const expectUpper = i === firstLetterIdx;
|
|
1624
|
+
if (expectUpper && ch !== ch.toUpperCase()) return false;
|
|
1625
|
+
if (!expectUpper && ch !== ch.toLowerCase()) return false;
|
|
1626
|
+
}
|
|
1627
|
+
return true;
|
|
1628
|
+
}
|
|
1583
1629
|
const DETAIL_DESCRIPTION_MAX_CODEPOINTS = 500;
|
|
1584
1630
|
function isValidHttpUrl(v) {
|
|
1585
1631
|
try {
|
|
@@ -1591,8 +1637,17 @@ function isValidHttpUrl(v) {
|
|
|
1591
1637
|
}
|
|
1592
1638
|
function validateManifest(raw, configDir) {
|
|
1593
1639
|
const titleKo = requireString(raw, "titleKo");
|
|
1640
|
+
if (!TITLE_KO_REGEX.test(titleKo)) throw new ManifestError("invalid-config", `titleKo may only contain Korean/English letters, digits, spaces, and ":·?" (got "${titleKo}"; server-side rule, errorCode: miniApp.InvalidTitle)`, "titleKo");
|
|
1641
|
+
const titleKoLen = codePointsExcludingSpaces(titleKo);
|
|
1642
|
+
if (titleKoLen > TITLE_KO_MAX_CODEPOINTS_NO_SPACE) throw new ManifestError("invalid-config", `titleKo must be ${TITLE_KO_MAX_CODEPOINTS_NO_SPACE} characters or fewer excluding spaces (got ${titleKoLen}; server-side rule, errorCode: miniApp.InvalidTitle)`, "titleKo");
|
|
1594
1643
|
const titleEn = requireString(raw, "titleEn");
|
|
1595
|
-
if (!TITLE_EN_REGEX.test(titleEn)) throw new ManifestError("invalid-config", `titleEn may only contain English letters, digits, spaces, and
|
|
1644
|
+
if (!TITLE_EN_REGEX.test(titleEn)) throw new ManifestError("invalid-config", `titleEn may only contain English letters, digits, spaces, and ":·?" (got "${titleEn}"; server-side rule, errorCode: miniApp.InvalidTitleEn)`, "titleEn");
|
|
1645
|
+
const titleEnLen = codePointsExcludingSpaces(titleEn);
|
|
1646
|
+
if (titleEnLen > TITLE_EN_MAX_CODEPOINTS_NO_SPACE) throw new ManifestError("invalid-config", `titleEn must be ${TITLE_EN_MAX_CODEPOINTS_NO_SPACE} characters or fewer excluding spaces (got ${titleEnLen}; server-side rule, errorCode: miniApp.InvalidTitleEn)`, "titleEn");
|
|
1647
|
+
for (const word of titleEn.split(" ")) {
|
|
1648
|
+
if (word.length === 0) continue;
|
|
1649
|
+
if (!isTitleCaseWord(word)) throw new ManifestError("invalid-config", `titleEn word "${word}" must be title-case (first letter uppercase, rest lowercase); server-side rule, errorCode: miniApp.InvalidTitleEn`, "titleEn");
|
|
1650
|
+
}
|
|
1596
1651
|
const appName = requireString(raw, "appName");
|
|
1597
1652
|
const csEmail = requireString(raw, "csEmail");
|
|
1598
1653
|
if (!isValidEmail(csEmail)) throw new ManifestError("invalid-config", `csEmail is not a valid email address (got ${csEmail})`, "csEmail");
|
|
@@ -1927,14 +1982,22 @@ function emitDryRun(json, workspaceId, payload) {
|
|
|
1927
1982
|
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
1928
1983
|
}
|
|
1929
1984
|
}
|
|
1985
|
+
function consoleUrlFor(workspaceId, appId) {
|
|
1986
|
+
return `https://apps-in-toss.toss.im/console/workspace/${workspaceId}/mini-app/${appId}`;
|
|
1987
|
+
}
|
|
1930
1988
|
function emitSuccess(json, workspaceId, result) {
|
|
1989
|
+
const consoleUrl = result.miniAppId !== void 0 ? consoleUrlFor(workspaceId, result.miniAppId) : null;
|
|
1931
1990
|
if (json) emitJson({
|
|
1932
1991
|
ok: true,
|
|
1933
1992
|
workspaceId,
|
|
1934
1993
|
appId: result.miniAppId ?? null,
|
|
1935
|
-
reviewState: result.reviewState ?? null
|
|
1994
|
+
reviewState: result.reviewState ?? null,
|
|
1995
|
+
consoleUrl
|
|
1936
1996
|
});
|
|
1937
|
-
else
|
|
1997
|
+
else {
|
|
1998
|
+
process.stdout.write(`Registered mini-app ${result.miniAppId ?? "(id unknown)"} in workspace ${workspaceId} (reviewState=${result.reviewState ?? "unknown"}).\n`);
|
|
1999
|
+
if (consoleUrl !== null) process.stdout.write(`🔗 console: ${consoleUrl}\n`);
|
|
2000
|
+
}
|
|
1938
2001
|
}
|
|
1939
2002
|
async function emitFailureAndExit(json, err) {
|
|
1940
2003
|
return emitFailureFromError(json, err);
|
|
@@ -3175,75 +3238,257 @@ const bundlesCommand = defineCommand({
|
|
|
3175
3238
|
})
|
|
3176
3239
|
}
|
|
3177
3240
|
});
|
|
3241
|
+
const certsLsCommand = defineCommand({
|
|
3242
|
+
meta: {
|
|
3243
|
+
name: "ls",
|
|
3244
|
+
description: "List mTLS certificates issued for a mini-app."
|
|
3245
|
+
},
|
|
3246
|
+
args: {
|
|
3247
|
+
id: {
|
|
3248
|
+
type: "positional",
|
|
3249
|
+
description: "Mini-app ID.",
|
|
3250
|
+
required: true
|
|
3251
|
+
},
|
|
3252
|
+
workspace: {
|
|
3253
|
+
type: "string",
|
|
3254
|
+
description: "Workspace ID. Defaults to the selected workspace."
|
|
3255
|
+
},
|
|
3256
|
+
json: {
|
|
3257
|
+
type: "boolean",
|
|
3258
|
+
description: "Emit machine-readable JSON.",
|
|
3259
|
+
default: false
|
|
3260
|
+
}
|
|
3261
|
+
},
|
|
3262
|
+
async run({ args }) {
|
|
3263
|
+
const appId = parseAppId(args.id);
|
|
3264
|
+
if (appId === null) {
|
|
3265
|
+
if (args.json) emitJson({
|
|
3266
|
+
ok: false,
|
|
3267
|
+
reason: "invalid-id",
|
|
3268
|
+
message: `app id must be a positive integer (got ${JSON.stringify(args.id)})`
|
|
3269
|
+
});
|
|
3270
|
+
else process.stderr.write(`app certs ls: invalid id ${JSON.stringify(args.id)}\n`);
|
|
3271
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
3272
|
+
}
|
|
3273
|
+
const ctx = await resolveWorkspaceContext(args);
|
|
3274
|
+
if (!ctx) return;
|
|
3275
|
+
const { session, workspaceId } = ctx;
|
|
3276
|
+
try {
|
|
3277
|
+
const certs = await fetchCerts(workspaceId, appId, session.cookies);
|
|
3278
|
+
if (args.json) {
|
|
3279
|
+
emitJson({
|
|
3280
|
+
ok: true,
|
|
3281
|
+
workspaceId,
|
|
3282
|
+
appId,
|
|
3283
|
+
certs
|
|
3284
|
+
});
|
|
3285
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
3286
|
+
}
|
|
3287
|
+
if (certs.length === 0) {
|
|
3288
|
+
process.stdout.write(`App ${appId} (ws ${workspaceId}): no mTLS certs\n`);
|
|
3289
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
3290
|
+
}
|
|
3291
|
+
process.stdout.write(`App ${appId} (ws ${workspaceId}): ${certs.length} cert(s)\n`);
|
|
3292
|
+
for (const c of certs) {
|
|
3293
|
+
const id = typeof c.id === "string" || typeof c.id === "number" ? c.id : typeof c.certId === "string" || typeof c.certId === "number" ? c.certId : "-";
|
|
3294
|
+
const cn = typeof c.commonName === "string" ? c.commonName : "-";
|
|
3295
|
+
const createdAt = typeof c.createdAt === "string" ? c.createdAt : "";
|
|
3296
|
+
const expiresAt = typeof c.expiresAt === "string" ? c.expiresAt : typeof c.validUntil === "string" ? c.validUntil : "";
|
|
3297
|
+
process.stdout.write(`${id}\t${cn}\t${createdAt}\t${expiresAt}\n`);
|
|
3298
|
+
}
|
|
3299
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
3300
|
+
} catch (err) {
|
|
3301
|
+
return emitFailureFromError(args.json, err);
|
|
3302
|
+
}
|
|
3303
|
+
}
|
|
3304
|
+
});
|
|
3305
|
+
const CERT_NAME_RE = /^[A-Za-z0-9_-]+$/;
|
|
3306
|
+
function parseCertName(raw) {
|
|
3307
|
+
if (typeof raw !== "string" || raw.length === 0) return { error: "--name is required (cert display name)" };
|
|
3308
|
+
if (!CERT_NAME_RE.test(raw)) return { error: "--name must contain only ASCII letters, digits, `-`, or `_` (no spaces, no Korean, no special chars)" };
|
|
3309
|
+
return { value: raw };
|
|
3310
|
+
}
|
|
3178
3311
|
const certsCommand = defineCommand({
|
|
3179
3312
|
meta: {
|
|
3180
3313
|
name: "certs",
|
|
3181
3314
|
description: "Inspect mTLS certificates for a mini-app."
|
|
3182
3315
|
},
|
|
3183
|
-
subCommands: {
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
id: {
|
|
3190
|
-
type: "positional",
|
|
3191
|
-
description: "Mini-app ID.",
|
|
3192
|
-
required: true
|
|
3316
|
+
subCommands: {
|
|
3317
|
+
ls: certsLsCommand,
|
|
3318
|
+
issue: defineCommand({
|
|
3319
|
+
meta: {
|
|
3320
|
+
name: "issue",
|
|
3321
|
+
description: "Issue a new mTLS certificate for a mini-app."
|
|
3193
3322
|
},
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3323
|
+
args: {
|
|
3324
|
+
id: {
|
|
3325
|
+
type: "positional",
|
|
3326
|
+
description: "Mini-app ID.",
|
|
3327
|
+
required: true
|
|
3328
|
+
},
|
|
3329
|
+
workspace: {
|
|
3330
|
+
type: "string",
|
|
3331
|
+
description: "Workspace ID. Defaults to the selected workspace."
|
|
3332
|
+
},
|
|
3333
|
+
name: {
|
|
3334
|
+
type: "string",
|
|
3335
|
+
description: "Cert display name. ASCII letters/digits/`-`/`_` only."
|
|
3336
|
+
},
|
|
3337
|
+
out: {
|
|
3338
|
+
type: "string",
|
|
3339
|
+
description: "Directory to write `<name>.crt` and `<name>.key` (mode 0600)."
|
|
3340
|
+
},
|
|
3341
|
+
"print-key": {
|
|
3342
|
+
type: "boolean",
|
|
3343
|
+
description: "Include the private key in the response (default: cert only).",
|
|
3344
|
+
default: false
|
|
3345
|
+
},
|
|
3346
|
+
json: {
|
|
3347
|
+
type: "boolean",
|
|
3348
|
+
description: "Emit machine-readable JSON.",
|
|
3349
|
+
default: false
|
|
3350
|
+
}
|
|
3197
3351
|
},
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
const appId = parseAppId(args.id);
|
|
3206
|
-
if (appId === null) {
|
|
3207
|
-
if (args.json) emitJson({
|
|
3208
|
-
ok: false,
|
|
3209
|
-
reason: "invalid-id",
|
|
3210
|
-
message: `app id must be a positive integer (got ${JSON.stringify(args.id)})`
|
|
3211
|
-
});
|
|
3212
|
-
else process.stderr.write(`app certs ls: invalid id ${JSON.stringify(args.id)}\n`);
|
|
3213
|
-
return exitAfterFlush(ExitCode.Usage);
|
|
3214
|
-
}
|
|
3215
|
-
const ctx = await resolveWorkspaceContext(args);
|
|
3216
|
-
if (!ctx) return;
|
|
3217
|
-
const { session, workspaceId } = ctx;
|
|
3218
|
-
try {
|
|
3219
|
-
const certs = await fetchCerts(workspaceId, appId, session.cookies);
|
|
3220
|
-
if (args.json) {
|
|
3221
|
-
emitJson({
|
|
3222
|
-
ok: true,
|
|
3223
|
-
workspaceId,
|
|
3224
|
-
appId,
|
|
3225
|
-
certs
|
|
3352
|
+
async run({ args }) {
|
|
3353
|
+
const appId = parseAppId(args.id);
|
|
3354
|
+
if (appId === null) {
|
|
3355
|
+
if (args.json) emitJson({
|
|
3356
|
+
ok: false,
|
|
3357
|
+
reason: "invalid-id",
|
|
3358
|
+
message: `app id must be a positive integer (got ${JSON.stringify(args.id)})`
|
|
3226
3359
|
});
|
|
3227
|
-
|
|
3360
|
+
else process.stderr.write(`app certs issue: invalid id ${JSON.stringify(args.id)}\n`);
|
|
3361
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
3362
|
+
}
|
|
3363
|
+
const nameResult = parseCertName(args.name);
|
|
3364
|
+
if ("error" in nameResult) {
|
|
3365
|
+
if (args.json) emitJson({
|
|
3366
|
+
ok: false,
|
|
3367
|
+
reason: "invalid-name",
|
|
3368
|
+
message: nameResult.error
|
|
3369
|
+
});
|
|
3370
|
+
else process.stderr.write(`app certs issue: ${nameResult.error}\n`);
|
|
3371
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
3228
3372
|
}
|
|
3229
|
-
|
|
3230
|
-
|
|
3373
|
+
const name = nameResult.value;
|
|
3374
|
+
const ctx = await resolveWorkspaceContext(args);
|
|
3375
|
+
if (!ctx) return;
|
|
3376
|
+
const { session, workspaceId } = ctx;
|
|
3377
|
+
try {
|
|
3378
|
+
const result = await issueCert(workspaceId, appId, name, session.cookies);
|
|
3379
|
+
let savedTo;
|
|
3380
|
+
if (typeof args.out === "string" && args.out.length > 0) {
|
|
3381
|
+
const dir = resolve(args.out);
|
|
3382
|
+
try {
|
|
3383
|
+
await mkdir(dir, { recursive: true });
|
|
3384
|
+
} catch (err) {
|
|
3385
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3386
|
+
if (args.json) emitJson({
|
|
3387
|
+
ok: false,
|
|
3388
|
+
reason: "invalid-out-dir",
|
|
3389
|
+
message: `--out: cannot create ${JSON.stringify(args.out)}: ${message}`
|
|
3390
|
+
});
|
|
3391
|
+
else process.stderr.write(`app certs issue: cannot create --out directory ${JSON.stringify(args.out)}: ${message}\n`);
|
|
3392
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
3393
|
+
}
|
|
3394
|
+
const certPath = resolve(dir, `${name}.crt`);
|
|
3395
|
+
const keyPath = resolve(dir, `${name}.key`);
|
|
3396
|
+
await writeFile(certPath, result.publicKey, { mode: 384 });
|
|
3397
|
+
await writeFile(keyPath, result.privateKey, { mode: 384 });
|
|
3398
|
+
savedTo = {
|
|
3399
|
+
publicKey: certPath,
|
|
3400
|
+
privateKey: keyPath
|
|
3401
|
+
};
|
|
3402
|
+
}
|
|
3403
|
+
if (args.json) {
|
|
3404
|
+
const includeKey = args["print-key"] === true || savedTo === void 0;
|
|
3405
|
+
emitJson({
|
|
3406
|
+
ok: true,
|
|
3407
|
+
workspaceId,
|
|
3408
|
+
appId,
|
|
3409
|
+
name,
|
|
3410
|
+
publicKey: result.publicKey,
|
|
3411
|
+
...includeKey ? { privateKey: result.privateKey } : {},
|
|
3412
|
+
...savedTo ? { savedTo } : {}
|
|
3413
|
+
});
|
|
3414
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
3415
|
+
}
|
|
3416
|
+
if (savedTo) process.stdout.write(`App ${appId} (ws ${workspaceId}): issued cert "${name}"\n cert: ${savedTo.publicKey}\n key: ${savedTo.privateKey}\n`);
|
|
3417
|
+
else process.stdout.write(`App ${appId} (ws ${workspaceId}): issued cert "${name}"\n${result.publicKey}` + (result.publicKey.endsWith("\n") ? "" : "\n") + "Private key not shown. Re-run with --out <dir> or --json --print-key to capture it.\n");
|
|
3231
3418
|
return exitAfterFlush(ExitCode.Ok);
|
|
3419
|
+
} catch (err) {
|
|
3420
|
+
return emitFailureFromError(args.json, err);
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
}),
|
|
3424
|
+
revoke: defineCommand({
|
|
3425
|
+
meta: {
|
|
3426
|
+
name: "revoke",
|
|
3427
|
+
description: "Revoke (disable) an mTLS certificate."
|
|
3428
|
+
},
|
|
3429
|
+
args: {
|
|
3430
|
+
certId: {
|
|
3431
|
+
type: "positional",
|
|
3432
|
+
description: "Cert ID (from `app certs ls`).",
|
|
3433
|
+
required: true
|
|
3434
|
+
},
|
|
3435
|
+
app: {
|
|
3436
|
+
type: "string",
|
|
3437
|
+
description: "Mini-app ID the cert belongs to."
|
|
3438
|
+
},
|
|
3439
|
+
workspace: {
|
|
3440
|
+
type: "string",
|
|
3441
|
+
description: "Workspace ID. Defaults to the selected workspace."
|
|
3442
|
+
},
|
|
3443
|
+
json: {
|
|
3444
|
+
type: "boolean",
|
|
3445
|
+
description: "Emit machine-readable JSON.",
|
|
3446
|
+
default: false
|
|
3232
3447
|
}
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3448
|
+
},
|
|
3449
|
+
async run({ args }) {
|
|
3450
|
+
const certId = typeof args.certId === "string" ? args.certId.trim() : "";
|
|
3451
|
+
if (certId.length === 0) {
|
|
3452
|
+
if (args.json) emitJson({
|
|
3453
|
+
ok: false,
|
|
3454
|
+
reason: "missing-cert-id",
|
|
3455
|
+
message: "certId positional is required"
|
|
3456
|
+
});
|
|
3457
|
+
else process.stderr.write("app certs revoke: certId is required\n");
|
|
3458
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
3459
|
+
}
|
|
3460
|
+
const appId = parseAppId(args.app);
|
|
3461
|
+
if (appId === null) {
|
|
3462
|
+
if (args.json) emitJson({
|
|
3463
|
+
ok: false,
|
|
3464
|
+
reason: "invalid-id",
|
|
3465
|
+
message: `--app must be a positive integer (got ${JSON.stringify(args.app)})`
|
|
3466
|
+
});
|
|
3467
|
+
else process.stderr.write(`app certs revoke: invalid --app ${JSON.stringify(args.app)}\n`);
|
|
3468
|
+
return exitAfterFlush(ExitCode.Usage);
|
|
3469
|
+
}
|
|
3470
|
+
const ctx = await resolveWorkspaceContext(args);
|
|
3471
|
+
if (!ctx) return;
|
|
3472
|
+
const { session, workspaceId } = ctx;
|
|
3473
|
+
try {
|
|
3474
|
+
await revokeCert(workspaceId, appId, certId, session.cookies);
|
|
3475
|
+
if (args.json) {
|
|
3476
|
+
emitJson({
|
|
3477
|
+
ok: true,
|
|
3478
|
+
workspaceId,
|
|
3479
|
+
appId,
|
|
3480
|
+
certId
|
|
3481
|
+
});
|
|
3482
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
3483
|
+
}
|
|
3484
|
+
process.stdout.write(`App ${appId} (ws ${workspaceId}): revoked cert ${certId}\n`);
|
|
3485
|
+
return exitAfterFlush(ExitCode.Ok);
|
|
3486
|
+
} catch (err) {
|
|
3487
|
+
return emitFailureFromError(args.json, err);
|
|
3240
3488
|
}
|
|
3241
|
-
return exitAfterFlush(ExitCode.Ok);
|
|
3242
|
-
} catch (err) {
|
|
3243
|
-
return emitFailureFromError(args.json, err);
|
|
3244
3489
|
}
|
|
3245
|
-
}
|
|
3246
|
-
}
|
|
3490
|
+
})
|
|
3491
|
+
}
|
|
3247
3492
|
});
|
|
3248
3493
|
const VALID_TIME_UNITS = [
|
|
3249
3494
|
"DAY",
|
|
@@ -5561,7 +5806,7 @@ function resolveVersion() {
|
|
|
5561
5806
|
if (typeof injected === "string" && injected.length > 0) return injected;
|
|
5562
5807
|
} catch {}
|
|
5563
5808
|
try {
|
|
5564
|
-
return "0.1.
|
|
5809
|
+
return "0.1.21";
|
|
5565
5810
|
} catch {}
|
|
5566
5811
|
return "0.0.0-dev";
|
|
5567
5812
|
}
|