@cimplify/sdk 0.44.32 → 0.44.34
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/commands/deploy.mjs +160 -12
- package/dist/cli/commands/dev.mjs +49 -4
- package/dist/cli/commands/domains.mjs +128 -12
- package/dist/cli/commands/env.mjs +102 -7
- package/dist/cli/commands/link.mjs +58 -5
- package/dist/cli/commands/login.mjs +76 -7
- package/dist/cli/commands/logout.mjs +22 -1
- package/dist/cli/commands/logs.mjs +86 -12
- package/dist/cli/commands/projects.mjs +157 -11
- package/dist/cli/commands/repo.mjs +584 -0
- package/dist/cli/commands/rollback.mjs +83 -7
- package/dist/cli/commands/status.mjs +75 -5
- package/dist/cli/commands/unlink.mjs +22 -1
- package/dist/cli/commands/whoami.mjs +56 -5
- package/dist/dispatcher.mjs +83 -9
- package/package.json +1 -1
- package/templates/storefront-bakery/package.json +2 -3
- package/templates/storefront-fashion/package.json +2 -3
- package/templates/storefront-grocery/package.json +2 -3
- package/templates/storefront-restaurant/package.json +2 -3
- package/templates/storefront-retail/package.json +2 -3
- package/templates/storefront-services/package.json +2 -3
|
@@ -15,15 +15,47 @@ var CLI_ERROR_CODE = {
|
|
|
15
15
|
INVALID_INPUT: "INVALID_INPUT",
|
|
16
16
|
ALREADY_LINKED: "ALREADY_LINKED",
|
|
17
17
|
SERVER_ERROR: "SERVER_ERROR",
|
|
18
|
-
ABORTED: "ABORTED"
|
|
18
|
+
ABORTED: "ABORTED",
|
|
19
|
+
/** Operation needs interactive confirmation and the shell is non-interactive. */
|
|
20
|
+
INTERACTIVE_REQUIRED: "INTERACTIVE_REQUIRED"
|
|
21
|
+
};
|
|
19
22
|
var EXIT_CODE = {
|
|
20
|
-
|
|
23
|
+
ABORTED: 3,
|
|
24
|
+
NOT_LINKED: 4,
|
|
25
|
+
ALREADY_LINKED: 5,
|
|
26
|
+
GIT_ERROR: 6,
|
|
27
|
+
INTERACTIVE_REQUIRED: 7,
|
|
28
|
+
PROJECT_NOT_FOUND: 8,
|
|
29
|
+
NETWORK_ERROR: 10,
|
|
30
|
+
SERVER_ERROR: 11,
|
|
31
|
+
TIMEOUT: 12,
|
|
32
|
+
NOT_LOGGED_IN: 20,
|
|
33
|
+
AUTH_FAILED: 21,
|
|
34
|
+
UNAUTHORIZED: 22,
|
|
35
|
+
INVALID_INPUT: 30
|
|
36
|
+
};
|
|
37
|
+
var EXIT_CODE_FOR = {
|
|
38
|
+
NOT_LOGGED_IN: EXIT_CODE.NOT_LOGGED_IN,
|
|
39
|
+
NOT_LINKED: EXIT_CODE.NOT_LINKED,
|
|
40
|
+
NETWORK_ERROR: EXIT_CODE.NETWORK_ERROR,
|
|
41
|
+
AUTH_FAILED: EXIT_CODE.AUTH_FAILED,
|
|
42
|
+
PROJECT_NOT_FOUND: EXIT_CODE.PROJECT_NOT_FOUND,
|
|
43
|
+
GIT_ERROR: EXIT_CODE.GIT_ERROR,
|
|
44
|
+
INVALID_INPUT: EXIT_CODE.INVALID_INPUT,
|
|
45
|
+
ALREADY_LINKED: EXIT_CODE.ALREADY_LINKED,
|
|
46
|
+
SERVER_ERROR: EXIT_CODE.SERVER_ERROR,
|
|
47
|
+
ABORTED: EXIT_CODE.ABORTED,
|
|
48
|
+
UNAUTHORIZED: EXIT_CODE.UNAUTHORIZED,
|
|
49
|
+
TIMEOUT: EXIT_CODE.TIMEOUT,
|
|
50
|
+
INTERACTIVE_REQUIRED: EXIT_CODE.INTERACTIVE_REQUIRED
|
|
51
|
+
};
|
|
21
52
|
var CliError = class extends Error {
|
|
22
|
-
constructor(code, message,
|
|
53
|
+
constructor(code, message, options = {}) {
|
|
23
54
|
super(message);
|
|
24
55
|
this.name = "CliError";
|
|
25
56
|
this.code = code;
|
|
26
|
-
this.exitCode = exitCode;
|
|
57
|
+
this.exitCode = options.exitCode ?? EXIT_CODE_FOR[code];
|
|
58
|
+
this.remediation = options.remediation;
|
|
27
59
|
}
|
|
28
60
|
};
|
|
29
61
|
|
|
@@ -321,25 +353,57 @@ var BOLD_OPEN = "\x1B[1m";
|
|
|
321
353
|
var DIM_OPEN = "\x1B[2m";
|
|
322
354
|
var GREEN_OPEN = "\x1B[32m";
|
|
323
355
|
var PREFIX_SUCCESS = "\u2713";
|
|
356
|
+
var ENV_JSON = "CIMPLIFY_JSON";
|
|
357
|
+
var ENV_YES = "CIMPLIFY_YES";
|
|
358
|
+
function envFlag(name) {
|
|
359
|
+
const v = process.env[name];
|
|
360
|
+
return v === "1" || v === "true";
|
|
361
|
+
}
|
|
362
|
+
function isJsonMode() {
|
|
363
|
+
return envFlag(ENV_JSON);
|
|
364
|
+
}
|
|
365
|
+
function isAutoYes() {
|
|
366
|
+
return envFlag(ENV_YES);
|
|
367
|
+
}
|
|
368
|
+
function isInteractive() {
|
|
369
|
+
return Boolean(process.stdout.isTTY) && Boolean(process.stdin.isTTY);
|
|
370
|
+
}
|
|
324
371
|
function wrap(open, value) {
|
|
325
372
|
return `${open}${value}${RESET}`;
|
|
326
373
|
}
|
|
327
374
|
function bold(value) {
|
|
328
|
-
return wrap(BOLD_OPEN, value);
|
|
375
|
+
return isJsonMode() ? value : wrap(BOLD_OPEN, value);
|
|
329
376
|
}
|
|
330
377
|
function dim(value) {
|
|
331
|
-
return wrap(DIM_OPEN, value);
|
|
378
|
+
return isJsonMode() ? value : wrap(DIM_OPEN, value);
|
|
332
379
|
}
|
|
333
380
|
function green(value) {
|
|
334
|
-
return wrap(GREEN_OPEN, value);
|
|
381
|
+
return isJsonMode() ? value : wrap(GREEN_OPEN, value);
|
|
335
382
|
}
|
|
336
383
|
function success(message) {
|
|
384
|
+
if (isJsonMode()) return;
|
|
337
385
|
console.log(`${green(PREFIX_SUCCESS)} ${message}`);
|
|
338
386
|
}
|
|
339
387
|
function info(message) {
|
|
388
|
+
if (isJsonMode()) return;
|
|
340
389
|
console.log(message);
|
|
341
390
|
}
|
|
391
|
+
var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
|
|
392
|
+
function result(data) {
|
|
393
|
+
if (!isJsonMode()) return;
|
|
394
|
+
if (process.env[ENV_EMITTED] === "1") return;
|
|
395
|
+
process.env[ENV_EMITTED] = "1";
|
|
396
|
+
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
397
|
+
`);
|
|
398
|
+
}
|
|
342
399
|
async function promptLine(question) {
|
|
400
|
+
if (!isInteractive()) {
|
|
401
|
+
throw new CliError(
|
|
402
|
+
CLI_ERROR_CODE.INTERACTIVE_REQUIRED,
|
|
403
|
+
"this operation needs interactive input but stdin is not a TTY",
|
|
404
|
+
{ remediation: "run interactively, or supply the value via a flag" }
|
|
405
|
+
);
|
|
406
|
+
}
|
|
343
407
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
344
408
|
try {
|
|
345
409
|
return await new Promise((resolve) => {
|
|
@@ -350,6 +414,14 @@ async function promptLine(question) {
|
|
|
350
414
|
}
|
|
351
415
|
}
|
|
352
416
|
async function promptYesNo(question, defaultNo = true) {
|
|
417
|
+
if (isAutoYes()) return true;
|
|
418
|
+
if (!isInteractive()) {
|
|
419
|
+
throw new CliError(
|
|
420
|
+
CLI_ERROR_CODE.INTERACTIVE_REQUIRED,
|
|
421
|
+
`this operation needs confirmation: ${question}`,
|
|
422
|
+
{ remediation: "re-run with --yes to accept, or run interactively" }
|
|
423
|
+
);
|
|
424
|
+
}
|
|
353
425
|
const suffix = defaultNo ? " [y/N] " : " [Y/n] ";
|
|
354
426
|
const answer = (await promptLine(`${question}${suffix}`)).trim().toLowerCase();
|
|
355
427
|
if (answer === "") return !defaultNo;
|
|
@@ -365,6 +437,13 @@ var ENV_SCOPE = {
|
|
|
365
437
|
};
|
|
366
438
|
var SECRET_MASK = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
367
439
|
var PUBLIC_ENV_PREFIX = "NEXT_PUBLIC_";
|
|
440
|
+
var REPO_PROVIDER = {
|
|
441
|
+
FREESTYLE: "freestyle",
|
|
442
|
+
GITHUB: "github",
|
|
443
|
+
GITEA: "gitea",
|
|
444
|
+
EXTERNAL: "external"
|
|
445
|
+
};
|
|
446
|
+
new Set(Object.values(REPO_PROVIDER));
|
|
368
447
|
|
|
369
448
|
// src/cli/commands/env.ts
|
|
370
449
|
var SUB_LS = "ls";
|
|
@@ -462,6 +541,7 @@ async function listEnv(client, businessId, projectId, args) {
|
|
|
462
541
|
});
|
|
463
542
|
if (records.length === 0) {
|
|
464
543
|
info(dim(`No env vars in scope "${scope}". Add one: cimplify env add KEY=VALUE`));
|
|
544
|
+
result({ scope, vars: [] });
|
|
465
545
|
return;
|
|
466
546
|
}
|
|
467
547
|
const keyWidth = Math.max(COL_KEY.length, ...records.map((r) => r.key.length));
|
|
@@ -488,6 +568,15 @@ async function listEnv(client, businessId, projectId, args) {
|
|
|
488
568
|
].join(COL_GAP)
|
|
489
569
|
);
|
|
490
570
|
}
|
|
571
|
+
result({
|
|
572
|
+
scope,
|
|
573
|
+
vars: records.map((r) => ({
|
|
574
|
+
key: r.key,
|
|
575
|
+
scope: r.scope,
|
|
576
|
+
is_secret: r.is_secret,
|
|
577
|
+
value: r.is_secret ? null : r.value ?? null
|
|
578
|
+
}))
|
|
579
|
+
});
|
|
491
580
|
}
|
|
492
581
|
function renderValue(r, show) {
|
|
493
582
|
if (r.is_secret) return SECRET_MASK;
|
|
@@ -514,6 +603,7 @@ Secrets are never returned in plaintext to the CLI; use the dashboard to copy th
|
|
|
514
603
|
await promises.mkdir(path.dirname(outPath), { recursive: true });
|
|
515
604
|
await promises.writeFile(outPath, formatEnvFile(entries), "utf8");
|
|
516
605
|
success(`Pulled ${entries.length} var${entries.length === 1 ? "" : "s"} to ${path.relative(process.cwd(), outPath) || outPath}`);
|
|
606
|
+
result({ scope, count: entries.length, file: outPath });
|
|
517
607
|
}
|
|
518
608
|
async function backupIfExists(target) {
|
|
519
609
|
try {
|
|
@@ -559,6 +649,7 @@ Use --file to point at a different path.`
|
|
|
559
649
|
};
|
|
560
650
|
await client.post(bulkSetEndpoint(businessId, projectId), body);
|
|
561
651
|
success(`Pushed ${entries.length} var${entries.length === 1 ? "" : "s"} to ${scope}${overwrite ? " (overwrite)" : ""}`);
|
|
652
|
+
result({ scope, count: entries.length, overwrite });
|
|
562
653
|
}
|
|
563
654
|
async function addEnv(client, businessId, projectId, args) {
|
|
564
655
|
const positional = args.positional[1];
|
|
@@ -577,6 +668,9 @@ async function addEnv(client, businessId, projectId, args) {
|
|
|
577
668
|
const body = { key, value, scope, is_secret: isSecret };
|
|
578
669
|
const created = await client.post(envEndpoint(businessId, projectId), body);
|
|
579
670
|
success(`Added ${created.key} (${scope}, ${isSecret ? "secret" : "public"})`);
|
|
671
|
+
result({
|
|
672
|
+
var: { key: created.key, scope: created.scope, is_secret: created.is_secret }
|
|
673
|
+
});
|
|
580
674
|
}
|
|
581
675
|
async function removeEnv(client, businessId, projectId, args) {
|
|
582
676
|
const key = args.positional[1];
|
|
@@ -605,6 +699,7 @@ async function removeEnv(client, businessId, projectId, args) {
|
|
|
605
699
|
}
|
|
606
700
|
await client.delete(envItemEndpoint(businessId, projectId, target.id));
|
|
607
701
|
success(`Removed ${key} from ${scope}`);
|
|
702
|
+
result({ removed: true, key, scope });
|
|
608
703
|
}
|
|
609
704
|
|
|
610
705
|
export { classifyIsSecret, run as default };
|
|
@@ -12,13 +12,42 @@ var CLI_ERROR_CODE = {
|
|
|
12
12
|
ALREADY_LINKED: "ALREADY_LINKED",
|
|
13
13
|
SERVER_ERROR: "SERVER_ERROR"};
|
|
14
14
|
var EXIT_CODE = {
|
|
15
|
-
|
|
15
|
+
ABORTED: 3,
|
|
16
|
+
NOT_LINKED: 4,
|
|
17
|
+
ALREADY_LINKED: 5,
|
|
18
|
+
GIT_ERROR: 6,
|
|
19
|
+
INTERACTIVE_REQUIRED: 7,
|
|
20
|
+
PROJECT_NOT_FOUND: 8,
|
|
21
|
+
NETWORK_ERROR: 10,
|
|
22
|
+
SERVER_ERROR: 11,
|
|
23
|
+
TIMEOUT: 12,
|
|
24
|
+
NOT_LOGGED_IN: 20,
|
|
25
|
+
AUTH_FAILED: 21,
|
|
26
|
+
UNAUTHORIZED: 22,
|
|
27
|
+
INVALID_INPUT: 30
|
|
28
|
+
};
|
|
29
|
+
var EXIT_CODE_FOR = {
|
|
30
|
+
NOT_LOGGED_IN: EXIT_CODE.NOT_LOGGED_IN,
|
|
31
|
+
NOT_LINKED: EXIT_CODE.NOT_LINKED,
|
|
32
|
+
NETWORK_ERROR: EXIT_CODE.NETWORK_ERROR,
|
|
33
|
+
AUTH_FAILED: EXIT_CODE.AUTH_FAILED,
|
|
34
|
+
PROJECT_NOT_FOUND: EXIT_CODE.PROJECT_NOT_FOUND,
|
|
35
|
+
GIT_ERROR: EXIT_CODE.GIT_ERROR,
|
|
36
|
+
INVALID_INPUT: EXIT_CODE.INVALID_INPUT,
|
|
37
|
+
ALREADY_LINKED: EXIT_CODE.ALREADY_LINKED,
|
|
38
|
+
SERVER_ERROR: EXIT_CODE.SERVER_ERROR,
|
|
39
|
+
ABORTED: EXIT_CODE.ABORTED,
|
|
40
|
+
UNAUTHORIZED: EXIT_CODE.UNAUTHORIZED,
|
|
41
|
+
TIMEOUT: EXIT_CODE.TIMEOUT,
|
|
42
|
+
INTERACTIVE_REQUIRED: EXIT_CODE.INTERACTIVE_REQUIRED
|
|
43
|
+
};
|
|
16
44
|
var CliError = class extends Error {
|
|
17
|
-
constructor(code, message,
|
|
45
|
+
constructor(code, message, options = {}) {
|
|
18
46
|
super(message);
|
|
19
47
|
this.name = "CliError";
|
|
20
48
|
this.code = code;
|
|
21
|
-
this.exitCode = exitCode;
|
|
49
|
+
this.exitCode = options.exitCode ?? EXIT_CODE_FOR[code];
|
|
50
|
+
this.remediation = options.remediation;
|
|
22
51
|
}
|
|
23
52
|
};
|
|
24
53
|
|
|
@@ -274,21 +303,39 @@ var RESET = "\x1B[0m";
|
|
|
274
303
|
var DIM_OPEN = "\x1B[2m";
|
|
275
304
|
var GREEN_OPEN = "\x1B[32m";
|
|
276
305
|
var PREFIX_SUCCESS = "\u2713";
|
|
306
|
+
var ENV_JSON = "CIMPLIFY_JSON";
|
|
307
|
+
function envFlag(name) {
|
|
308
|
+
const v = process.env[name];
|
|
309
|
+
return v === "1" || v === "true";
|
|
310
|
+
}
|
|
311
|
+
function isJsonMode() {
|
|
312
|
+
return envFlag(ENV_JSON);
|
|
313
|
+
}
|
|
277
314
|
function wrap(open, value) {
|
|
278
315
|
return `${open}${value}${RESET}`;
|
|
279
316
|
}
|
|
280
317
|
function dim(value) {
|
|
281
|
-
return wrap(DIM_OPEN, value);
|
|
318
|
+
return isJsonMode() ? value : wrap(DIM_OPEN, value);
|
|
282
319
|
}
|
|
283
320
|
function green(value) {
|
|
284
|
-
return wrap(GREEN_OPEN, value);
|
|
321
|
+
return isJsonMode() ? value : wrap(GREEN_OPEN, value);
|
|
285
322
|
}
|
|
286
323
|
function success(message) {
|
|
324
|
+
if (isJsonMode()) return;
|
|
287
325
|
console.log(`${green(PREFIX_SUCCESS)} ${message}`);
|
|
288
326
|
}
|
|
289
327
|
function info(message) {
|
|
328
|
+
if (isJsonMode()) return;
|
|
290
329
|
console.log(message);
|
|
291
330
|
}
|
|
331
|
+
var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
|
|
332
|
+
function result(data) {
|
|
333
|
+
if (!isJsonMode()) return;
|
|
334
|
+
if (process.env[ENV_EMITTED] === "1") return;
|
|
335
|
+
process.env[ENV_EMITTED] = "1";
|
|
336
|
+
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
337
|
+
`);
|
|
338
|
+
}
|
|
292
339
|
|
|
293
340
|
// src/cli/commands/link.ts
|
|
294
341
|
function projectEndpoint(businessId, projectId) {
|
|
@@ -320,6 +367,12 @@ async function run(argv) {
|
|
|
320
367
|
await writeProjectLink(link);
|
|
321
368
|
success(`Linked to ${project.name} (${project.id})`);
|
|
322
369
|
if (link.remoteUrl) info(dim(`remote: ${link.remoteUrl}`));
|
|
370
|
+
result({
|
|
371
|
+
project: { id: project.id, name: project.name },
|
|
372
|
+
business: { id: project.business_id },
|
|
373
|
+
remote_url: link.remoteUrl ?? null,
|
|
374
|
+
default_branch: link.defaultBranch ?? null
|
|
375
|
+
});
|
|
323
376
|
}
|
|
324
377
|
|
|
325
378
|
export { run as default };
|
|
@@ -16,16 +16,47 @@ var CLI_ERROR_CODE = {
|
|
|
16
16
|
ALREADY_LINKED: "ALREADY_LINKED",
|
|
17
17
|
SERVER_ERROR: "SERVER_ERROR",
|
|
18
18
|
UNAUTHORIZED: "UNAUTHORIZED",
|
|
19
|
-
TIMEOUT: "TIMEOUT"
|
|
19
|
+
TIMEOUT: "TIMEOUT",
|
|
20
|
+
/** Operation needs interactive confirmation and the shell is non-interactive. */
|
|
21
|
+
INTERACTIVE_REQUIRED: "INTERACTIVE_REQUIRED"
|
|
20
22
|
};
|
|
21
23
|
var EXIT_CODE = {
|
|
22
|
-
|
|
24
|
+
ABORTED: 3,
|
|
25
|
+
NOT_LINKED: 4,
|
|
26
|
+
ALREADY_LINKED: 5,
|
|
27
|
+
GIT_ERROR: 6,
|
|
28
|
+
INTERACTIVE_REQUIRED: 7,
|
|
29
|
+
PROJECT_NOT_FOUND: 8,
|
|
30
|
+
NETWORK_ERROR: 10,
|
|
31
|
+
SERVER_ERROR: 11,
|
|
32
|
+
TIMEOUT: 12,
|
|
33
|
+
NOT_LOGGED_IN: 20,
|
|
34
|
+
AUTH_FAILED: 21,
|
|
35
|
+
UNAUTHORIZED: 22,
|
|
36
|
+
INVALID_INPUT: 30
|
|
37
|
+
};
|
|
38
|
+
var EXIT_CODE_FOR = {
|
|
39
|
+
NOT_LOGGED_IN: EXIT_CODE.NOT_LOGGED_IN,
|
|
40
|
+
NOT_LINKED: EXIT_CODE.NOT_LINKED,
|
|
41
|
+
NETWORK_ERROR: EXIT_CODE.NETWORK_ERROR,
|
|
42
|
+
AUTH_FAILED: EXIT_CODE.AUTH_FAILED,
|
|
43
|
+
PROJECT_NOT_FOUND: EXIT_CODE.PROJECT_NOT_FOUND,
|
|
44
|
+
GIT_ERROR: EXIT_CODE.GIT_ERROR,
|
|
45
|
+
INVALID_INPUT: EXIT_CODE.INVALID_INPUT,
|
|
46
|
+
ALREADY_LINKED: EXIT_CODE.ALREADY_LINKED,
|
|
47
|
+
SERVER_ERROR: EXIT_CODE.SERVER_ERROR,
|
|
48
|
+
ABORTED: EXIT_CODE.ABORTED,
|
|
49
|
+
UNAUTHORIZED: EXIT_CODE.UNAUTHORIZED,
|
|
50
|
+
TIMEOUT: EXIT_CODE.TIMEOUT,
|
|
51
|
+
INTERACTIVE_REQUIRED: EXIT_CODE.INTERACTIVE_REQUIRED
|
|
52
|
+
};
|
|
23
53
|
var CliError = class extends Error {
|
|
24
|
-
constructor(code, message,
|
|
54
|
+
constructor(code, message, options = {}) {
|
|
25
55
|
super(message);
|
|
26
56
|
this.name = "CliError";
|
|
27
57
|
this.code = code;
|
|
28
|
-
this.exitCode = exitCode;
|
|
58
|
+
this.exitCode = options.exitCode ?? EXIT_CODE_FOR[code];
|
|
59
|
+
this.remediation = options.remediation;
|
|
29
60
|
}
|
|
30
61
|
};
|
|
31
62
|
|
|
@@ -386,27 +417,46 @@ var GREEN_OPEN = "\x1B[32m";
|
|
|
386
417
|
var CYAN_OPEN = "\x1B[36m";
|
|
387
418
|
var PREFIX_STEP = "\u25B8";
|
|
388
419
|
var PREFIX_SUCCESS = "\u2713";
|
|
420
|
+
var ENV_JSON = "CIMPLIFY_JSON";
|
|
421
|
+
function envFlag(name) {
|
|
422
|
+
const v = process.env[name];
|
|
423
|
+
return v === "1" || v === "true";
|
|
424
|
+
}
|
|
425
|
+
function isJsonMode() {
|
|
426
|
+
return envFlag(ENV_JSON);
|
|
427
|
+
}
|
|
389
428
|
function wrap(open, value) {
|
|
390
429
|
return `${open}${value}${RESET}`;
|
|
391
430
|
}
|
|
392
431
|
function dim(value) {
|
|
393
|
-
return wrap(DIM_OPEN, value);
|
|
432
|
+
return isJsonMode() ? value : wrap(DIM_OPEN, value);
|
|
394
433
|
}
|
|
395
434
|
function green(value) {
|
|
396
|
-
return wrap(GREEN_OPEN, value);
|
|
435
|
+
return isJsonMode() ? value : wrap(GREEN_OPEN, value);
|
|
397
436
|
}
|
|
398
437
|
function cyan(value) {
|
|
399
|
-
return wrap(CYAN_OPEN, value);
|
|
438
|
+
return isJsonMode() ? value : wrap(CYAN_OPEN, value);
|
|
400
439
|
}
|
|
401
440
|
function step(message) {
|
|
441
|
+
if (isJsonMode()) return;
|
|
402
442
|
console.log(`${cyan(PREFIX_STEP)} ${message}`);
|
|
403
443
|
}
|
|
404
444
|
function success(message) {
|
|
445
|
+
if (isJsonMode()) return;
|
|
405
446
|
console.log(`${green(PREFIX_SUCCESS)} ${message}`);
|
|
406
447
|
}
|
|
407
448
|
function info(message) {
|
|
449
|
+
if (isJsonMode()) return;
|
|
408
450
|
console.log(message);
|
|
409
451
|
}
|
|
452
|
+
var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
|
|
453
|
+
function result(data) {
|
|
454
|
+
if (!isJsonMode()) return;
|
|
455
|
+
if (process.env[ENV_EMITTED] === "1") return;
|
|
456
|
+
process.env[ENV_EMITTED] = "1";
|
|
457
|
+
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
458
|
+
`);
|
|
459
|
+
}
|
|
410
460
|
|
|
411
461
|
// src/cli/commands/login.ts
|
|
412
462
|
var FLAG_API_KEY = "api-key";
|
|
@@ -447,8 +497,21 @@ async function loginWithKey(baseUrl, apiKey) {
|
|
|
447
497
|
savedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
448
498
|
});
|
|
449
499
|
success(`Logged in as ${me.email ?? me.name ?? me.id} (business ${me.business_id})`);
|
|
500
|
+
result({
|
|
501
|
+
logged_in: true,
|
|
502
|
+
account: { id: me.id, email: me.email ?? null, name: me.name ?? null },
|
|
503
|
+
business: { id: me.business_id },
|
|
504
|
+
method: "api_key"
|
|
505
|
+
});
|
|
450
506
|
}
|
|
451
507
|
async function loginWithBrowser(baseUrl, noBrowser) {
|
|
508
|
+
if (isJsonMode()) {
|
|
509
|
+
throw new CliError(
|
|
510
|
+
CLI_ERROR_CODE.INTERACTIVE_REQUIRED,
|
|
511
|
+
"browser login is not supported in --json mode",
|
|
512
|
+
{ remediation: "pass --api-key dk_\u2026 (create one in the dashboard or via `cimplify auth keys create`)" }
|
|
513
|
+
);
|
|
514
|
+
}
|
|
452
515
|
const pkce = generatePkcePair();
|
|
453
516
|
const state = generateState();
|
|
454
517
|
const loopback = await startLoopbackServer(baseUrl);
|
|
@@ -510,6 +573,12 @@ async function loginWithBrowser(baseUrl, noBrowser) {
|
|
|
510
573
|
success(
|
|
511
574
|
`Logged in as ${me.email ?? me.name ?? me.id} (business ${me.business_id})`
|
|
512
575
|
);
|
|
576
|
+
result({
|
|
577
|
+
logged_in: true,
|
|
578
|
+
account: { id: me.id, email: me.email ?? null, name: me.name ?? null },
|
|
579
|
+
business: { id: me.business_id },
|
|
580
|
+
method: "oauth_pkce"
|
|
581
|
+
});
|
|
513
582
|
}
|
|
514
583
|
|
|
515
584
|
export { run as default };
|
|
@@ -2,6 +2,8 @@ import { promises } from 'fs';
|
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
|
|
5
|
+
// src/cli/config.ts
|
|
6
|
+
|
|
5
7
|
// src/cli/config.ts
|
|
6
8
|
var AUTH_FILE_NAME = "auth.json";
|
|
7
9
|
var ENV_XDG_CONFIG_HOME = "XDG_CONFIG_HOME";
|
|
@@ -28,18 +30,36 @@ async function clearAuth() {
|
|
|
28
30
|
var RESET = "\x1B[0m";
|
|
29
31
|
var GREEN_OPEN = "\x1B[32m";
|
|
30
32
|
var PREFIX_SUCCESS = "\u2713";
|
|
33
|
+
var ENV_JSON = "CIMPLIFY_JSON";
|
|
34
|
+
function envFlag(name) {
|
|
35
|
+
const v = process.env[name];
|
|
36
|
+
return v === "1" || v === "true";
|
|
37
|
+
}
|
|
38
|
+
function isJsonMode() {
|
|
39
|
+
return envFlag(ENV_JSON);
|
|
40
|
+
}
|
|
31
41
|
function wrap(open, value) {
|
|
32
42
|
return `${open}${value}${RESET}`;
|
|
33
43
|
}
|
|
34
44
|
function green(value) {
|
|
35
|
-
return wrap(GREEN_OPEN, value);
|
|
45
|
+
return isJsonMode() ? value : wrap(GREEN_OPEN, value);
|
|
36
46
|
}
|
|
37
47
|
function success(message) {
|
|
48
|
+
if (isJsonMode()) return;
|
|
38
49
|
console.log(`${green(PREFIX_SUCCESS)} ${message}`);
|
|
39
50
|
}
|
|
40
51
|
function info(message) {
|
|
52
|
+
if (isJsonMode()) return;
|
|
41
53
|
console.log(message);
|
|
42
54
|
}
|
|
55
|
+
var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
|
|
56
|
+
function result(data) {
|
|
57
|
+
if (!isJsonMode()) return;
|
|
58
|
+
if (process.env[ENV_EMITTED] === "1") return;
|
|
59
|
+
process.env[ENV_EMITTED] = "1";
|
|
60
|
+
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
61
|
+
`);
|
|
62
|
+
}
|
|
43
63
|
|
|
44
64
|
// src/cli/commands/logout.ts
|
|
45
65
|
async function run(_argv) {
|
|
@@ -49,6 +69,7 @@ async function run(_argv) {
|
|
|
49
69
|
} else {
|
|
50
70
|
info("Not logged in.");
|
|
51
71
|
}
|
|
72
|
+
result({ logged_out: removed });
|
|
52
73
|
}
|
|
53
74
|
|
|
54
75
|
export { run as default };
|
|
@@ -13,13 +13,42 @@ var CLI_ERROR_CODE = {
|
|
|
13
13
|
ALREADY_LINKED: "ALREADY_LINKED",
|
|
14
14
|
SERVER_ERROR: "SERVER_ERROR"};
|
|
15
15
|
var EXIT_CODE = {
|
|
16
|
-
|
|
16
|
+
ABORTED: 3,
|
|
17
|
+
NOT_LINKED: 4,
|
|
18
|
+
ALREADY_LINKED: 5,
|
|
19
|
+
GIT_ERROR: 6,
|
|
20
|
+
INTERACTIVE_REQUIRED: 7,
|
|
21
|
+
PROJECT_NOT_FOUND: 8,
|
|
22
|
+
NETWORK_ERROR: 10,
|
|
23
|
+
SERVER_ERROR: 11,
|
|
24
|
+
TIMEOUT: 12,
|
|
25
|
+
NOT_LOGGED_IN: 20,
|
|
26
|
+
AUTH_FAILED: 21,
|
|
27
|
+
UNAUTHORIZED: 22,
|
|
28
|
+
INVALID_INPUT: 30
|
|
29
|
+
};
|
|
30
|
+
var EXIT_CODE_FOR = {
|
|
31
|
+
NOT_LOGGED_IN: EXIT_CODE.NOT_LOGGED_IN,
|
|
32
|
+
NOT_LINKED: EXIT_CODE.NOT_LINKED,
|
|
33
|
+
NETWORK_ERROR: EXIT_CODE.NETWORK_ERROR,
|
|
34
|
+
AUTH_FAILED: EXIT_CODE.AUTH_FAILED,
|
|
35
|
+
PROJECT_NOT_FOUND: EXIT_CODE.PROJECT_NOT_FOUND,
|
|
36
|
+
GIT_ERROR: EXIT_CODE.GIT_ERROR,
|
|
37
|
+
INVALID_INPUT: EXIT_CODE.INVALID_INPUT,
|
|
38
|
+
ALREADY_LINKED: EXIT_CODE.ALREADY_LINKED,
|
|
39
|
+
SERVER_ERROR: EXIT_CODE.SERVER_ERROR,
|
|
40
|
+
ABORTED: EXIT_CODE.ABORTED,
|
|
41
|
+
UNAUTHORIZED: EXIT_CODE.UNAUTHORIZED,
|
|
42
|
+
TIMEOUT: EXIT_CODE.TIMEOUT,
|
|
43
|
+
INTERACTIVE_REQUIRED: EXIT_CODE.INTERACTIVE_REQUIRED
|
|
44
|
+
};
|
|
17
45
|
var CliError = class extends Error {
|
|
18
|
-
constructor(code, message,
|
|
46
|
+
constructor(code, message, options = {}) {
|
|
19
47
|
super(message);
|
|
20
48
|
this.name = "CliError";
|
|
21
49
|
this.code = code;
|
|
22
|
-
this.exitCode = exitCode;
|
|
50
|
+
this.exitCode = options.exitCode ?? EXIT_CODE_FOR[code];
|
|
51
|
+
this.remediation = options.remediation;
|
|
23
52
|
}
|
|
24
53
|
};
|
|
25
54
|
|
|
@@ -265,15 +294,32 @@ async function readProjectState(cwd = process.cwd()) {
|
|
|
265
294
|
var RESET = "\x1B[0m";
|
|
266
295
|
var RED_OPEN = "\x1B[31m";
|
|
267
296
|
var PREFIX_FAILURE = "\u2717";
|
|
297
|
+
var ENV_JSON = "CIMPLIFY_JSON";
|
|
298
|
+
function envFlag(name) {
|
|
299
|
+
const v = process.env[name];
|
|
300
|
+
return v === "1" || v === "true";
|
|
301
|
+
}
|
|
302
|
+
function isJsonMode() {
|
|
303
|
+
return envFlag(ENV_JSON);
|
|
304
|
+
}
|
|
268
305
|
function wrap(open, value) {
|
|
269
306
|
return `${open}${value}${RESET}`;
|
|
270
307
|
}
|
|
271
308
|
function red(value) {
|
|
272
|
-
return wrap(RED_OPEN, value);
|
|
309
|
+
return isJsonMode() ? value : wrap(RED_OPEN, value);
|
|
273
310
|
}
|
|
274
311
|
function failure(message) {
|
|
312
|
+
if (isJsonMode()) return;
|
|
275
313
|
console.error(`${red(PREFIX_FAILURE)} ${message}`);
|
|
276
314
|
}
|
|
315
|
+
var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
|
|
316
|
+
function result(data) {
|
|
317
|
+
if (!isJsonMode()) return;
|
|
318
|
+
if (process.env[ENV_EMITTED] === "1") return;
|
|
319
|
+
process.env[ENV_EMITTED] = "1";
|
|
320
|
+
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
321
|
+
`);
|
|
322
|
+
}
|
|
277
323
|
|
|
278
324
|
// src/cli/types.ts
|
|
279
325
|
var DEPLOYMENT_STATUS = {
|
|
@@ -288,6 +334,13 @@ var TERMINAL_DEPLOYMENT_STATUSES = /* @__PURE__ */ new Set([
|
|
|
288
334
|
DEPLOYMENT_STATUS.CANCELLED,
|
|
289
335
|
DEPLOYMENT_STATUS.SUPERSEDED
|
|
290
336
|
]);
|
|
337
|
+
var REPO_PROVIDER = {
|
|
338
|
+
FREESTYLE: "freestyle",
|
|
339
|
+
GITHUB: "github",
|
|
340
|
+
GITEA: "gitea",
|
|
341
|
+
EXTERNAL: "external"
|
|
342
|
+
};
|
|
343
|
+
new Set(Object.values(REPO_PROVIDER));
|
|
291
344
|
|
|
292
345
|
// src/cli/commands/logs.ts
|
|
293
346
|
var FLAG_DEPLOYMENT = "deployment";
|
|
@@ -325,26 +378,41 @@ async function run(argv) {
|
|
|
325
378
|
}
|
|
326
379
|
const endpoint = progressEndpoint(link.businessId, link.projectId, deploymentId);
|
|
327
380
|
const follow = flagBool(args, FLAG_FOLLOW);
|
|
381
|
+
const json = isJsonMode();
|
|
328
382
|
if (!follow) {
|
|
329
383
|
const progress = await client.get(endpoint);
|
|
330
|
-
if (
|
|
331
|
-
|
|
384
|
+
if (!json) {
|
|
385
|
+
if (progress.build_logs) process.stdout.write(progress.build_logs);
|
|
386
|
+
if (progress.error_message) failure(progress.error_message);
|
|
387
|
+
}
|
|
388
|
+
result({
|
|
389
|
+
deployment_id: deploymentId,
|
|
390
|
+
status: progress.status,
|
|
391
|
+
build_logs: progress.build_logs ?? null,
|
|
392
|
+
error_message: progress.error_message ?? null
|
|
393
|
+
});
|
|
332
394
|
return;
|
|
333
395
|
}
|
|
334
396
|
const cursor = { printed: 0 };
|
|
335
397
|
const startedAt = Date.now();
|
|
336
398
|
let lastErrorMessage;
|
|
399
|
+
let finalProgress = null;
|
|
337
400
|
while (true) {
|
|
338
401
|
const progress = await client.get(endpoint);
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
402
|
+
if (!json) {
|
|
403
|
+
const chunk = nextChunk(cursor, progress.build_logs);
|
|
404
|
+
if (chunk.length > 0) process.stdout.write(chunk);
|
|
405
|
+
if (progress.error_message && progress.error_message !== lastErrorMessage) {
|
|
406
|
+
process.stdout.write(`
|
|
343
407
|
${red(progress.error_message)}
|
|
344
408
|
`);
|
|
345
|
-
|
|
409
|
+
lastErrorMessage = progress.error_message;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (TERMINAL_DEPLOYMENT_STATUSES.has(progress.status)) {
|
|
413
|
+
finalProgress = progress;
|
|
414
|
+
break;
|
|
346
415
|
}
|
|
347
|
-
if (TERMINAL_DEPLOYMENT_STATUSES.has(progress.status)) return;
|
|
348
416
|
if (Date.now() - startedAt > POLL_MAX_MS) {
|
|
349
417
|
throw new CliError(
|
|
350
418
|
CLI_ERROR_CODE.NETWORK_ERROR,
|
|
@@ -353,6 +421,12 @@ ${red(progress.error_message)}
|
|
|
353
421
|
}
|
|
354
422
|
await sleep(POLL_INTERVAL_MS);
|
|
355
423
|
}
|
|
424
|
+
result({
|
|
425
|
+
deployment_id: deploymentId,
|
|
426
|
+
status: finalProgress.status,
|
|
427
|
+
build_logs: finalProgress.build_logs ?? null,
|
|
428
|
+
error_message: finalProgress.error_message ?? null
|
|
429
|
+
});
|
|
356
430
|
}
|
|
357
431
|
|
|
358
432
|
export { run as default, nextChunk };
|