@cimplify/cli 0.12.2 → 0.13.1
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/{add-5ODVFWVR.mjs → add-F7GKDXAD.mjs} +4 -3
- package/dist/agent-UTARR75F.mjs +25 -0
- package/dist/{assets-4D7VXRUE.mjs → assets-Y4JE6MSG.mjs} +4 -3
- package/dist/{auth-step-up-NOSM4PUR.mjs → auth-step-up-EHL5PM2L.mjs} +5 -4
- package/dist/{cancel-PPNH6K67.mjs → cancel-QSZE2XC2.mjs} +4 -3
- package/dist/{chunk-7P2OGMZ4.mjs → chunk-2VK4UABO.mjs} +5 -5
- package/dist/{chunk-ITAFAORS.mjs → chunk-4YIFBYBV.mjs} +2 -1
- package/dist/{chunk-DBZ3UOQ2.mjs → chunk-5U5OXOPN.mjs} +1 -1
- package/dist/{chunk-PVHB2MHV.mjs → chunk-AMREB4KE.mjs} +2 -2
- package/dist/{chunk-F4S5KETY.mjs → chunk-JPXK5BLA.mjs} +1 -1
- package/dist/{chunk-K5464A3L.mjs → chunk-OVHZV57L.mjs} +1 -1
- package/dist/{chunk-UBAI443T.mjs → chunk-QA36VSLX.mjs} +1 -1
- package/dist/{chunk-6C2QY3ZP.mjs → chunk-RR4NOZGY.mjs} +5 -4
- package/dist/{chunk-W3WLADJP.mjs → chunk-SVJPU4K7.mjs} +8 -8
- package/dist/{chunk-GLXONXS3.mjs → chunk-UP7N53C4.mjs} +1 -1
- package/dist/{chunk-VTR5R5NQ.mjs → chunk-VJJDGHZC.mjs} +2 -1
- package/dist/{chunk-E2T2SBP5.mjs → chunk-YPC4VU65.mjs} +1 -73
- package/dist/chunk-ZPVN6UXL.mjs +74 -0
- package/dist/{dev-5MB2BJ6L.mjs → chunk-ZX5ZEOEU.mjs} +78 -216
- package/dist/{deploy-H7245HMP.mjs → deploy-UTAYLZOM.mjs} +8 -7
- package/dist/dev-WSX75ELC.mjs +169 -0
- package/dist/dispatcher.mjs +30 -28
- package/dist/{doctor-6Z6YR37N.mjs → doctor-QFCEYEEZ.mjs} +8 -7
- package/dist/{domains-H3K2WW55.mjs → domains-OS3DXSDN.mjs} +5 -4
- package/dist/{env-3HY7HFVT.mjs → env-UVO4OIEO.mjs} +6 -5
- package/dist/{explain-2FLJFJP3.mjs → explain-BZPONVN3.mjs} +3 -2
- package/dist/{inspect-CGYX4DDF.mjs → inspect-ULWQHT7J.mjs} +3 -2
- package/dist/introspect-HGX4I3XQ.mjs +9 -0
- package/dist/{link-O4WAUWWE.mjs → link-VQN2WPZO.mjs} +4 -3
- package/dist/{list-27TS2L47.mjs → list-DZTPWNU3.mjs} +3 -2
- package/dist/{login-SCWIIEGR.mjs → login-UZ5Y7GIO.mjs} +5 -4
- package/dist/{logout-3RLBZ33M.mjs → logout-XYWZR6QJ.mjs} +3 -2
- package/dist/{logs-2ECJQ3MU.mjs → logs-YNXDXAF7.mjs} +4 -3
- package/dist/{mock-TSUKCLWU.mjs → mock-HFVAAYK2.mjs} +2 -1
- package/dist/{projects-2BITX2YE.mjs → projects-RJ44DJKZ.mjs} +4 -3
- package/dist/repo-OK6CVG3G.mjs +9 -0
- package/dist/{rollback-4YLTZRXP.mjs → rollback-Z2PRL7FS.mjs} +5 -4
- package/dist/{status-IA7PJ4TV.mjs → status-RR3GGTVU.mjs} +4 -3
- package/dist/{unlink-RFK74SFP.mjs → unlink-JBVZYOA3.mjs} +3 -2
- package/dist/{update-VIDP5OKO.mjs → update-2FSGAVDH.mjs} +4 -3
- package/dist/{whoami-6GFMOY2M.mjs → whoami-5G32NNEP.mjs} +4 -3
- package/package.json +3 -3
- package/templates/storefront-auto/package.json +1 -1
- package/templates/storefront-bakery/package.json +1 -1
- package/templates/storefront-fashion/package.json +1 -1
- package/templates/storefront-grocery/package.json +1 -1
- package/templates/storefront-pharmacy/package.json +1 -1
- package/templates/storefront-restaurant/package.json +1 -1
- package/templates/storefront-retail/package.json +1 -1
- package/templates/storefront-services/package.json +1 -1
- package/dist/introspect-YBDCOO3I.mjs +0 -8
- package/dist/repo-WSUAHXWO.mjs +0 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { CliError, CLI_ERROR_CODE } from './chunk-
|
|
2
|
+
import { CliError, CLI_ERROR_CODE } from './chunk-YPC4VU65.mjs';
|
|
3
3
|
import { randomBytes, createHash } from 'crypto';
|
|
4
4
|
import { createServer } from 'http';
|
|
5
5
|
import { spawn } from 'child_process';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { TERMINAL_DEPLOYMENT_STATUSES, DEPLOYMENT_STATUS } from './chunk-MXYUAJEW.mjs';
|
|
3
|
-
import {
|
|
3
|
+
import { CliError, CLI_ERROR_CODE } from './chunk-YPC4VU65.mjs';
|
|
4
|
+
import { dim, failure, success, isJsonMode } from './chunk-ZPVN6UXL.mjs';
|
|
4
5
|
|
|
5
6
|
// src/progress.ts
|
|
6
7
|
var POLL_INTERVAL_MS = 1e3;
|
|
@@ -73,76 +73,4 @@ function isCliError(err) {
|
|
|
73
73
|
return err instanceof CliError || typeof err === "object" && err !== null && err.name === "CliError" && typeof err.code === "string" && typeof err.exitCode === "number";
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
var RESET = "\x1B[0m";
|
|
78
|
-
var BOLD_OPEN = "\x1B[1m";
|
|
79
|
-
var DIM_OPEN = "\x1B[2m";
|
|
80
|
-
var RED_OPEN = "\x1B[31m";
|
|
81
|
-
var GREEN_OPEN = "\x1B[32m";
|
|
82
|
-
var YELLOW_OPEN = "\x1B[33m";
|
|
83
|
-
var CYAN_OPEN = "\x1B[36m";
|
|
84
|
-
var PREFIX_STEP = "\u25B8";
|
|
85
|
-
var PREFIX_SUCCESS = "\u2713";
|
|
86
|
-
var PREFIX_FAILURE = "\u2717";
|
|
87
|
-
var ENV_JSON = "CIMPLIFY_JSON";
|
|
88
|
-
var ENV_YES = "CIMPLIFY_YES";
|
|
89
|
-
function envFlag(name) {
|
|
90
|
-
const v = process.env[name];
|
|
91
|
-
return v === "1" || v === "true";
|
|
92
|
-
}
|
|
93
|
-
function isJsonMode() {
|
|
94
|
-
return envFlag(ENV_JSON);
|
|
95
|
-
}
|
|
96
|
-
function isAutoYes() {
|
|
97
|
-
return envFlag(ENV_YES);
|
|
98
|
-
}
|
|
99
|
-
function isInteractive() {
|
|
100
|
-
return Boolean(process.stdout.isTTY) && Boolean(process.stdin.isTTY);
|
|
101
|
-
}
|
|
102
|
-
function wrap(open, value) {
|
|
103
|
-
return `${open}${value}${RESET}`;
|
|
104
|
-
}
|
|
105
|
-
function bold(value) {
|
|
106
|
-
return isJsonMode() ? value : wrap(BOLD_OPEN, value);
|
|
107
|
-
}
|
|
108
|
-
function dim(value) {
|
|
109
|
-
return isJsonMode() ? value : wrap(DIM_OPEN, value);
|
|
110
|
-
}
|
|
111
|
-
function red(value) {
|
|
112
|
-
return isJsonMode() ? value : wrap(RED_OPEN, value);
|
|
113
|
-
}
|
|
114
|
-
function green(value) {
|
|
115
|
-
return isJsonMode() ? value : wrap(GREEN_OPEN, value);
|
|
116
|
-
}
|
|
117
|
-
function yellow(value) {
|
|
118
|
-
return isJsonMode() ? value : wrap(YELLOW_OPEN, value);
|
|
119
|
-
}
|
|
120
|
-
function cyan(value) {
|
|
121
|
-
return isJsonMode() ? value : wrap(CYAN_OPEN, value);
|
|
122
|
-
}
|
|
123
|
-
function step(message) {
|
|
124
|
-
if (isJsonMode()) return;
|
|
125
|
-
console.log(`${cyan(PREFIX_STEP)} ${message}`);
|
|
126
|
-
}
|
|
127
|
-
function success(message) {
|
|
128
|
-
if (isJsonMode()) return;
|
|
129
|
-
console.log(`${green(PREFIX_SUCCESS)} ${message}`);
|
|
130
|
-
}
|
|
131
|
-
function failure(message) {
|
|
132
|
-
if (isJsonMode()) return;
|
|
133
|
-
console.error(`${red(PREFIX_FAILURE)} ${message}`);
|
|
134
|
-
}
|
|
135
|
-
function info(message) {
|
|
136
|
-
if (isJsonMode()) return;
|
|
137
|
-
console.log(message);
|
|
138
|
-
}
|
|
139
|
-
var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
|
|
140
|
-
function result(data) {
|
|
141
|
-
if (!isJsonMode()) return;
|
|
142
|
-
if (process.env[ENV_EMITTED] === "1") return;
|
|
143
|
-
process.env[ENV_EMITTED] = "1";
|
|
144
|
-
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
145
|
-
`);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export { CLI_ERROR_CODE, CliError, EXIT_CODE, bold, dim, failure, green, info, isAutoYes, isCliError, isInteractive, isJsonMode, red, result, step, success, yellow };
|
|
76
|
+
export { CLI_ERROR_CODE, CliError, EXIT_CODE, isCliError };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// src/output.ts
|
|
3
|
+
var RESET = "\x1B[0m";
|
|
4
|
+
var BOLD_OPEN = "\x1B[1m";
|
|
5
|
+
var DIM_OPEN = "\x1B[2m";
|
|
6
|
+
var RED_OPEN = "\x1B[31m";
|
|
7
|
+
var GREEN_OPEN = "\x1B[32m";
|
|
8
|
+
var YELLOW_OPEN = "\x1B[33m";
|
|
9
|
+
var CYAN_OPEN = "\x1B[36m";
|
|
10
|
+
var PREFIX_STEP = "\u25B8";
|
|
11
|
+
var PREFIX_SUCCESS = "\u2713";
|
|
12
|
+
var PREFIX_FAILURE = "\u2717";
|
|
13
|
+
var ENV_JSON = "CIMPLIFY_JSON";
|
|
14
|
+
var ENV_YES = "CIMPLIFY_YES";
|
|
15
|
+
function envFlag(name) {
|
|
16
|
+
const v = process.env[name];
|
|
17
|
+
return v === "1" || v === "true";
|
|
18
|
+
}
|
|
19
|
+
function isJsonMode() {
|
|
20
|
+
return envFlag(ENV_JSON);
|
|
21
|
+
}
|
|
22
|
+
function isAutoYes() {
|
|
23
|
+
return envFlag(ENV_YES);
|
|
24
|
+
}
|
|
25
|
+
function isInteractive() {
|
|
26
|
+
return Boolean(process.stdout.isTTY) && Boolean(process.stdin.isTTY);
|
|
27
|
+
}
|
|
28
|
+
function wrap(open, value) {
|
|
29
|
+
return `${open}${value}${RESET}`;
|
|
30
|
+
}
|
|
31
|
+
function bold(value) {
|
|
32
|
+
return isJsonMode() ? value : wrap(BOLD_OPEN, value);
|
|
33
|
+
}
|
|
34
|
+
function dim(value) {
|
|
35
|
+
return isJsonMode() ? value : wrap(DIM_OPEN, value);
|
|
36
|
+
}
|
|
37
|
+
function red(value) {
|
|
38
|
+
return isJsonMode() ? value : wrap(RED_OPEN, value);
|
|
39
|
+
}
|
|
40
|
+
function green(value) {
|
|
41
|
+
return isJsonMode() ? value : wrap(GREEN_OPEN, value);
|
|
42
|
+
}
|
|
43
|
+
function yellow(value) {
|
|
44
|
+
return isJsonMode() ? value : wrap(YELLOW_OPEN, value);
|
|
45
|
+
}
|
|
46
|
+
function cyan(value) {
|
|
47
|
+
return isJsonMode() ? value : wrap(CYAN_OPEN, value);
|
|
48
|
+
}
|
|
49
|
+
function step(message) {
|
|
50
|
+
if (isJsonMode()) return;
|
|
51
|
+
console.log(`${cyan(PREFIX_STEP)} ${message}`);
|
|
52
|
+
}
|
|
53
|
+
function success(message) {
|
|
54
|
+
if (isJsonMode()) return;
|
|
55
|
+
console.log(`${green(PREFIX_SUCCESS)} ${message}`);
|
|
56
|
+
}
|
|
57
|
+
function failure(message) {
|
|
58
|
+
if (isJsonMode()) return;
|
|
59
|
+
console.error(`${red(PREFIX_FAILURE)} ${message}`);
|
|
60
|
+
}
|
|
61
|
+
function info(message) {
|
|
62
|
+
if (isJsonMode()) return;
|
|
63
|
+
console.log(message);
|
|
64
|
+
}
|
|
65
|
+
var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
|
|
66
|
+
function result(data) {
|
|
67
|
+
if (!isJsonMode()) return;
|
|
68
|
+
if (process.env[ENV_EMITTED] === "1") return;
|
|
69
|
+
process.env[ENV_EMITTED] = "1";
|
|
70
|
+
process.stdout.write(`${JSON.stringify({ ok: true, data })}
|
|
71
|
+
`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { bold, dim, failure, green, info, isAutoYes, isInteractive, isJsonMode, red, result, step, success, yellow };
|
|
@@ -1,14 +1,60 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { ENV_SCOPE, PUBLIC_ENV_PREFIX } from './chunk-MXYUAJEW.mjs';
|
|
4
|
-
import { parseArgs, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
5
|
-
import { ApiClient } from './chunk-F4S5KETY.mjs';
|
|
6
|
-
import { readAuth, readProjectLink } from './chunk-UBAI443T.mjs';
|
|
7
|
-
import { info, CliError, CLI_ERROR_CODE, dim } from './chunk-E2T2SBP5.mjs';
|
|
8
|
-
import { spawn } from 'child_process';
|
|
2
|
+
import { info, dim } from './chunk-ZPVN6UXL.mjs';
|
|
9
3
|
import { promises, watch } from 'fs';
|
|
10
|
-
import
|
|
4
|
+
import path2 from 'path';
|
|
11
5
|
import http from 'http';
|
|
6
|
+
import { spawn } from 'child_process';
|
|
7
|
+
|
|
8
|
+
var TUNNEL_URL_ENV = "CIMPLIFY_TUNNEL_URL";
|
|
9
|
+
var TUNNEL_TOKEN_ENV = "CIMPLIFY_TUNNEL_TOKEN";
|
|
10
|
+
var TUNNEL_LOCAL_PORT_ENV = "CIMPLIFY_TUNNEL_LOCAL_PORT";
|
|
11
|
+
var TUNNEL_CONFIG_DIR = ".cimplify";
|
|
12
|
+
var TUNNEL_CONFIG_FILE = "tunnel.json";
|
|
13
|
+
var DEFAULT_DEV_SERVER_PORT = 3e3;
|
|
14
|
+
function tunnelConfigPath(cwd) {
|
|
15
|
+
return path2.join(cwd, TUNNEL_CONFIG_DIR, TUNNEL_CONFIG_FILE);
|
|
16
|
+
}
|
|
17
|
+
async function readTunnelConfig(cwd, env = process.env) {
|
|
18
|
+
const url = env[TUNNEL_URL_ENV];
|
|
19
|
+
const token = env[TUNNEL_TOKEN_ENV];
|
|
20
|
+
if (url && token) {
|
|
21
|
+
return { url, token, localPort: envPort(env) ?? DEFAULT_DEV_SERVER_PORT };
|
|
22
|
+
}
|
|
23
|
+
return readTunnelConfigFile(cwd);
|
|
24
|
+
}
|
|
25
|
+
function envPort(env) {
|
|
26
|
+
const raw = env[TUNNEL_LOCAL_PORT_ENV];
|
|
27
|
+
if (!raw) return null;
|
|
28
|
+
const port = Number.parseInt(raw, 10);
|
|
29
|
+
return Number.isInteger(port) && port > 0 && port < 65536 ? port : null;
|
|
30
|
+
}
|
|
31
|
+
async function readTunnelConfigFile(cwd) {
|
|
32
|
+
let raw;
|
|
33
|
+
try {
|
|
34
|
+
raw = await promises.readFile(tunnelConfigPath(cwd), "utf8");
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(raw);
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
45
|
+
const record = parsed;
|
|
46
|
+
if (typeof record.url !== "string" || record.url.length === 0) return null;
|
|
47
|
+
if (typeof record.token !== "string" || record.token.length === 0) return null;
|
|
48
|
+
const localPort = typeof record.port === "number" && Number.isInteger(record.port) && record.port > 0 ? record.port : DEFAULT_DEV_SERVER_PORT;
|
|
49
|
+
return { url: record.url, token: record.token, localPort };
|
|
50
|
+
}
|
|
51
|
+
function sameTunnelConfig(a, b) {
|
|
52
|
+
if (a === null || b === null) return a === b;
|
|
53
|
+
return a.url === b.url && a.token === b.token && a.localPort === b.localPort;
|
|
54
|
+
}
|
|
55
|
+
function sameTunnelEndpoint(a, b) {
|
|
56
|
+
return a.url === b.url && a.localPort === b.localPort;
|
|
57
|
+
}
|
|
12
58
|
|
|
13
59
|
// src/tunnel/v2/codec.ts
|
|
14
60
|
var HEADER_LEN = 9;
|
|
@@ -610,8 +656,8 @@ function execCommand(request) {
|
|
|
610
656
|
throw new ControlFsError(CONTROL_ERROR.INVALID_PATH, "exec requires a command");
|
|
611
657
|
}
|
|
612
658
|
function resolveInRoot(root, rel) {
|
|
613
|
-
const resolved =
|
|
614
|
-
const rootWithSep = root.endsWith(
|
|
659
|
+
const resolved = path2.resolve(root, rel);
|
|
660
|
+
const rootWithSep = root.endsWith(path2.sep) ? root : root + path2.sep;
|
|
615
661
|
if (resolved !== root && !resolved.startsWith(rootWithSep)) {
|
|
616
662
|
throw new ControlFsError(CONTROL_ERROR.INVALID_PATH, `path escapes workspace: ${rel}`);
|
|
617
663
|
}
|
|
@@ -633,7 +679,7 @@ var NodeControlFs = class {
|
|
|
633
679
|
}
|
|
634
680
|
async write(rel, content, encoding) {
|
|
635
681
|
const abs = resolveInRoot(this.root, rel);
|
|
636
|
-
await promises.mkdir(
|
|
682
|
+
await promises.mkdir(path2.dirname(abs), { recursive: true });
|
|
637
683
|
const bytes = encoding === ENCODING.BASE64 ? Buffer.from(content, "base64") : Buffer.from(content, "utf8");
|
|
638
684
|
await promises.writeFile(abs, bytes).catch(rethrow(rel));
|
|
639
685
|
}
|
|
@@ -649,7 +695,7 @@ var NodeControlFs = class {
|
|
|
649
695
|
async listTree() {
|
|
650
696
|
const out = [];
|
|
651
697
|
const walk = async (dir) => {
|
|
652
|
-
const dirents = await promises.readdir(
|
|
698
|
+
const dirents = await promises.readdir(path2.join(this.root, dir), { withFileTypes: true });
|
|
653
699
|
for (const dirent of dirents) {
|
|
654
700
|
if (DEFAULT_IGNORED.has(dirent.name)) continue;
|
|
655
701
|
const rel = dir ? `${dir}/${dirent.name}` : dirent.name;
|
|
@@ -675,7 +721,7 @@ var NodeControlFs = class {
|
|
|
675
721
|
async rename(from, to) {
|
|
676
722
|
const absFrom = resolveInRoot(this.root, from);
|
|
677
723
|
const absTo = resolveInRoot(this.root, to);
|
|
678
|
-
await promises.mkdir(
|
|
724
|
+
await promises.mkdir(path2.dirname(absTo), { recursive: true });
|
|
679
725
|
await promises.rename(absFrom, absTo).catch(rethrow(from));
|
|
680
726
|
}
|
|
681
727
|
};
|
|
@@ -690,7 +736,7 @@ var NodeControlWatcher = class {
|
|
|
690
736
|
const pending = /* @__PURE__ */ new Map();
|
|
691
737
|
const flush = (rel) => {
|
|
692
738
|
pending.delete(rel);
|
|
693
|
-
promises.stat(
|
|
739
|
+
promises.stat(path2.join(this.root, rel)).then(
|
|
694
740
|
(stat) => onEvent(stat.isDirectory() ? WATCH_EVENT.ADD : WATCH_EVENT.CHANGE, [rel]),
|
|
695
741
|
() => onEvent(WATCH_EVENT.REMOVE, [rel])
|
|
696
742
|
);
|
|
@@ -701,7 +747,7 @@ var NodeControlWatcher = class {
|
|
|
701
747
|
onResync();
|
|
702
748
|
return;
|
|
703
749
|
}
|
|
704
|
-
const rel = filename.toString().split(
|
|
750
|
+
const rel = filename.toString().split(path2.sep).join("/");
|
|
705
751
|
if (isIgnored(rel)) return;
|
|
706
752
|
const existing = pending.get(rel);
|
|
707
753
|
if (existing) clearTimeout(existing);
|
|
@@ -1344,6 +1390,10 @@ var SessionV2 = class {
|
|
|
1344
1390
|
const now = Date.now();
|
|
1345
1391
|
const tickGap = now - this.lastTickAt;
|
|
1346
1392
|
this.lastTickAt = now;
|
|
1393
|
+
if (tickGap < 0 || now < this.lastInboundAt) {
|
|
1394
|
+
this.lastInboundAt = now;
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1347
1397
|
if (tickGap > FROZEN_TICK_GAP_MS) {
|
|
1348
1398
|
this.abort(`process froze ${Math.round(tickGap / 1e3)}s (suspend/resume); redialing`);
|
|
1349
1399
|
return;
|
|
@@ -1851,61 +1901,12 @@ function makeAgentContext(localPort, hello, createLocalSocket) {
|
|
|
1851
1901
|
createLocalSocket: (url, protocols) => createLocalSocket(url, protocols)
|
|
1852
1902
|
};
|
|
1853
1903
|
}
|
|
1854
|
-
var TUNNEL_URL_ENV = "CIMPLIFY_TUNNEL_URL";
|
|
1855
|
-
var TUNNEL_TOKEN_ENV = "CIMPLIFY_TUNNEL_TOKEN";
|
|
1856
|
-
var TUNNEL_LOCAL_PORT_ENV = "CIMPLIFY_TUNNEL_LOCAL_PORT";
|
|
1857
|
-
var TUNNEL_CONFIG_DIR = ".cimplify";
|
|
1858
|
-
var TUNNEL_CONFIG_FILE = "tunnel.json";
|
|
1859
|
-
var DEFAULT_DEV_SERVER_PORT = 3e3;
|
|
1860
|
-
function tunnelConfigPath(cwd) {
|
|
1861
|
-
return path.join(cwd, TUNNEL_CONFIG_DIR, TUNNEL_CONFIG_FILE);
|
|
1862
|
-
}
|
|
1863
|
-
async function readTunnelConfig(cwd, env = process.env) {
|
|
1864
|
-
const url = env[TUNNEL_URL_ENV];
|
|
1865
|
-
const token = env[TUNNEL_TOKEN_ENV];
|
|
1866
|
-
if (url && token) {
|
|
1867
|
-
return { url, token, localPort: envPort(env) ?? DEFAULT_DEV_SERVER_PORT };
|
|
1868
|
-
}
|
|
1869
|
-
return readTunnelConfigFile(cwd);
|
|
1870
|
-
}
|
|
1871
|
-
function envPort(env) {
|
|
1872
|
-
const raw = env[TUNNEL_LOCAL_PORT_ENV];
|
|
1873
|
-
if (!raw) return null;
|
|
1874
|
-
const port = Number.parseInt(raw, 10);
|
|
1875
|
-
return Number.isInteger(port) && port > 0 && port < 65536 ? port : null;
|
|
1876
|
-
}
|
|
1877
|
-
async function readTunnelConfigFile(cwd) {
|
|
1878
|
-
let raw;
|
|
1879
|
-
try {
|
|
1880
|
-
raw = await promises.readFile(tunnelConfigPath(cwd), "utf8");
|
|
1881
|
-
} catch {
|
|
1882
|
-
return null;
|
|
1883
|
-
}
|
|
1884
|
-
let parsed;
|
|
1885
|
-
try {
|
|
1886
|
-
parsed = JSON.parse(raw);
|
|
1887
|
-
} catch {
|
|
1888
|
-
return null;
|
|
1889
|
-
}
|
|
1890
|
-
if (typeof parsed !== "object" || parsed === null) return null;
|
|
1891
|
-
const record = parsed;
|
|
1892
|
-
if (typeof record.url !== "string" || record.url.length === 0) return null;
|
|
1893
|
-
if (typeof record.token !== "string" || record.token.length === 0) return null;
|
|
1894
|
-
const localPort = typeof record.port === "number" && Number.isInteger(record.port) && record.port > 0 ? record.port : DEFAULT_DEV_SERVER_PORT;
|
|
1895
|
-
return { url: record.url, token: record.token, localPort };
|
|
1896
|
-
}
|
|
1897
|
-
function sameTunnelConfig(a, b) {
|
|
1898
|
-
if (a === null || b === null) return a === b;
|
|
1899
|
-
return a.url === b.url && a.token === b.token && a.localPort === b.localPort;
|
|
1900
|
-
}
|
|
1901
|
-
function sameTunnelEndpoint(a, b) {
|
|
1902
|
-
return a.url === b.url && a.localPort === b.localPort;
|
|
1903
|
-
}
|
|
1904
1904
|
|
|
1905
1905
|
// src/tunnel/manager.ts
|
|
1906
1906
|
var CONFIG_POLL_MS = 2e3;
|
|
1907
1907
|
var RECONNECT_MIN_MS = 1e3;
|
|
1908
1908
|
var RECONNECT_MAX_MS = 3e4;
|
|
1909
|
+
var STAND_DOWN_RETRY_MS = 5 * 6e4;
|
|
1909
1910
|
var CLOSE_CODE_REPLACED = 4e3;
|
|
1910
1911
|
function makeDefaultCreateClient(workspaceRoot) {
|
|
1911
1912
|
return (config, events) => new NegotiatingAgentClient({
|
|
@@ -1935,6 +1936,7 @@ function startTunnelRuntime(cwd, options = {}) {
|
|
|
1935
1936
|
reconnectTimer = null;
|
|
1936
1937
|
}
|
|
1937
1938
|
};
|
|
1939
|
+
let backoffResetTimer = null;
|
|
1938
1940
|
const startClient = (config) => {
|
|
1939
1941
|
generation += 1;
|
|
1940
1942
|
standDown = false;
|
|
@@ -1943,7 +1945,14 @@ function startTunnelRuntime(cwd, options = {}) {
|
|
|
1943
1945
|
onConnected: () => {
|
|
1944
1946
|
if (stopped || myGeneration !== generation) return;
|
|
1945
1947
|
connected = true;
|
|
1946
|
-
|
|
1948
|
+
if (backoffResetTimer) clearTimeout(backoffResetTimer);
|
|
1949
|
+
backoffResetTimer = setTimeout(() => {
|
|
1950
|
+
backoffResetTimer = null;
|
|
1951
|
+
if (!stopped && connected && myGeneration === generation) {
|
|
1952
|
+
reconnectDelay = RECONNECT_MIN_MS;
|
|
1953
|
+
}
|
|
1954
|
+
}, 1e4);
|
|
1955
|
+
backoffResetTimer.unref?.();
|
|
1947
1956
|
onStatus("(preview tunnel: connected)");
|
|
1948
1957
|
},
|
|
1949
1958
|
onClosed: (reason, closeCode) => {
|
|
@@ -1952,6 +1961,8 @@ function startTunnelRuntime(cwd, options = {}) {
|
|
|
1952
1961
|
if (closeCode === CLOSE_CODE_REPLACED) {
|
|
1953
1962
|
standDown = true;
|
|
1954
1963
|
onStatus("(preview tunnel: replaced by a newer agent; standing down)");
|
|
1964
|
+
reconnectDelay = STAND_DOWN_RETRY_MS;
|
|
1965
|
+
scheduleReconnect();
|
|
1955
1966
|
return;
|
|
1956
1967
|
}
|
|
1957
1968
|
onStatus(`(preview tunnel: disconnected \u2014 ${reason})`);
|
|
@@ -2019,153 +2030,4 @@ function startTunnelRuntime(cwd, options = {}) {
|
|
|
2019
2030
|
};
|
|
2020
2031
|
}
|
|
2021
2032
|
|
|
2022
|
-
|
|
2023
|
-
var FLAG_REMOTE = "remote";
|
|
2024
|
-
var PACKAGE_JSON = "package.json";
|
|
2025
|
-
var ENV_LOCAL_FILE = ".env.local";
|
|
2026
|
-
var PUBLIC_API_URL_KEY = "NEXT_PUBLIC_CIMPLIFY_API_URL";
|
|
2027
|
-
var SCRIPT_DEV = "dev";
|
|
2028
|
-
var PREVIEW_ORIGIN_ENV = "CIMPLIFY_PREVIEW_ORIGIN";
|
|
2029
|
-
async function applyPreviewOrigin(cwd, originList) {
|
|
2030
|
-
const { ensurePreviewOrigin } = await import('./preview-config-344CUZLO.mjs');
|
|
2031
|
-
const origins = originList.split(",").map((origin) => origin.trim()).filter((origin) => origin.length > 0);
|
|
2032
|
-
if (origins.length === 0) return;
|
|
2033
|
-
try {
|
|
2034
|
-
const result = await ensurePreviewOrigin(cwd, origins);
|
|
2035
|
-
if (result.status === "unrecognized") {
|
|
2036
|
-
info(
|
|
2037
|
-
dim(
|
|
2038
|
-
`(preview: could not resolve ${result.file} config shape; hot-reload may be limited)`
|
|
2039
|
-
)
|
|
2040
|
-
);
|
|
2041
|
-
}
|
|
2042
|
-
} catch (err) {
|
|
2043
|
-
info(dim(`(preview: dev-origin setup skipped: ${err.message})`));
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
var PM_BUN = "bun";
|
|
2047
|
-
var PM_PNPM = "pnpm";
|
|
2048
|
-
var PM_YARN = "yarn";
|
|
2049
|
-
var PM_NPM = "npm";
|
|
2050
|
-
var LOCKFILE_BUN = "bun.lock";
|
|
2051
|
-
var LOCKFILE_BUN_BINARY = "bun.lockb";
|
|
2052
|
-
var LOCKFILE_PNPM = "pnpm-lock.yaml";
|
|
2053
|
-
var LOCKFILE_YARN = "yarn.lock";
|
|
2054
|
-
var BUNFIG = "bunfig.toml";
|
|
2055
|
-
function envEndpoint(businessId, projectId) {
|
|
2056
|
-
return `/v1/businesses/${encodeURIComponent(businessId)}/projects/${encodeURIComponent(projectId)}/env-vars`;
|
|
2057
|
-
}
|
|
2058
|
-
async function detectPackageManager(cwd) {
|
|
2059
|
-
if (await pathExists(path.join(cwd, LOCKFILE_BUN))) return PM_BUN;
|
|
2060
|
-
if (await pathExists(path.join(cwd, LOCKFILE_BUN_BINARY))) return PM_BUN;
|
|
2061
|
-
if (await pathExists(path.join(cwd, BUNFIG))) return PM_BUN;
|
|
2062
|
-
if (await pathExists(path.join(cwd, LOCKFILE_PNPM))) return PM_PNPM;
|
|
2063
|
-
if (await pathExists(path.join(cwd, LOCKFILE_YARN))) return PM_YARN;
|
|
2064
|
-
return PM_NPM;
|
|
2065
|
-
}
|
|
2066
|
-
async function pathExists(target) {
|
|
2067
|
-
try {
|
|
2068
|
-
await promises.stat(target);
|
|
2069
|
-
return true;
|
|
2070
|
-
} catch (err) {
|
|
2071
|
-
if (err.code === "ENOENT") return false;
|
|
2072
|
-
throw err;
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
async function readPackageJson(cwd) {
|
|
2076
|
-
const pkgPath = path.join(cwd, PACKAGE_JSON);
|
|
2077
|
-
let raw;
|
|
2078
|
-
try {
|
|
2079
|
-
raw = await promises.readFile(pkgPath, "utf8");
|
|
2080
|
-
} catch (err) {
|
|
2081
|
-
if (err.code === "ENOENT") {
|
|
2082
|
-
throw new CliError(
|
|
2083
|
-
CLI_ERROR_CODE.INVALID_INPUT,
|
|
2084
|
-
`No package.json in ${cwd}. \`cimplify dev\` runs your project's dev script.`
|
|
2085
|
-
);
|
|
2086
|
-
}
|
|
2087
|
-
throw err;
|
|
2088
|
-
}
|
|
2089
|
-
return JSON.parse(raw);
|
|
2090
|
-
}
|
|
2091
|
-
function mergeEnvEntries(existing, incoming) {
|
|
2092
|
-
const seen = new Set(existing.map((e) => e.key));
|
|
2093
|
-
const merged = [...existing];
|
|
2094
|
-
for (const entry of incoming) {
|
|
2095
|
-
if (seen.has(entry.key)) continue;
|
|
2096
|
-
merged.push(entry);
|
|
2097
|
-
seen.add(entry.key);
|
|
2098
|
-
}
|
|
2099
|
-
return merged;
|
|
2100
|
-
}
|
|
2101
|
-
async function applyRemoteEnv(client, businessId, projectId, apiBaseUrl, cwd) {
|
|
2102
|
-
const records = await client.get(envEndpoint(businessId, projectId), {
|
|
2103
|
-
query: { scope: ENV_SCOPE.PRODUCTION }
|
|
2104
|
-
});
|
|
2105
|
-
const incoming = records.filter((r) => r.value !== null && !r.is_secret).map((r) => ({ key: r.key, value: r.value }));
|
|
2106
|
-
incoming.push({ key: PUBLIC_API_URL_KEY, value: apiBaseUrl });
|
|
2107
|
-
const envPath = path.join(cwd, ENV_LOCAL_FILE);
|
|
2108
|
-
let existing = [];
|
|
2109
|
-
try {
|
|
2110
|
-
const raw = await promises.readFile(envPath, "utf8");
|
|
2111
|
-
existing = parseEnvFile(raw);
|
|
2112
|
-
} catch (err) {
|
|
2113
|
-
if (err.code !== "ENOENT") throw err;
|
|
2114
|
-
}
|
|
2115
|
-
const merged = mergeEnvEntries(existing, incoming);
|
|
2116
|
-
await promises.writeFile(envPath, formatEnvFile(merged), "utf8");
|
|
2117
|
-
const publicCount = incoming.filter((e) => e.key.startsWith(PUBLIC_ENV_PREFIX)).length;
|
|
2118
|
-
return publicCount;
|
|
2119
|
-
}
|
|
2120
|
-
async function run(argv) {
|
|
2121
|
-
const args = parseArgs(argv);
|
|
2122
|
-
const remote = flagBool(args, FLAG_REMOTE);
|
|
2123
|
-
const cwd = process.cwd();
|
|
2124
|
-
const previewOrigin = process.env[PREVIEW_ORIGIN_ENV];
|
|
2125
|
-
if (remote) {
|
|
2126
|
-
const auth = await readAuth();
|
|
2127
|
-
const link = await readProjectLink();
|
|
2128
|
-
const client = ApiClient.fromAuth(auth);
|
|
2129
|
-
const publicCount = await applyRemoteEnv(
|
|
2130
|
-
client,
|
|
2131
|
-
link.businessId,
|
|
2132
|
-
link.projectId,
|
|
2133
|
-
auth.apiBaseUrl,
|
|
2134
|
-
cwd
|
|
2135
|
-
);
|
|
2136
|
-
const label = link.businessHandle ?? auth.businessHandle ?? auth.businessId;
|
|
2137
|
-
info(`Dev mode: connected to ${label} production data (${publicCount} public var${publicCount === 1 ? "" : "s"} merged)`);
|
|
2138
|
-
} else if (previewOrigin) {
|
|
2139
|
-
info("Dev mode: hosted preview");
|
|
2140
|
-
} else {
|
|
2141
|
-
info("Dev mode: using local mock (`cimplify mock`)");
|
|
2142
|
-
}
|
|
2143
|
-
const pkg = await readPackageJson(cwd);
|
|
2144
|
-
if (!pkg.scripts || !pkg.scripts[SCRIPT_DEV]) {
|
|
2145
|
-
throw new CliError(
|
|
2146
|
-
CLI_ERROR_CODE.INVALID_INPUT,
|
|
2147
|
-
`No "${SCRIPT_DEV}" script in package.json. Add one (e.g. "next dev") and re-run.`
|
|
2148
|
-
);
|
|
2149
|
-
}
|
|
2150
|
-
let stopTunnel = null;
|
|
2151
|
-
if (previewOrigin) {
|
|
2152
|
-
await applyPreviewOrigin(cwd, previewOrigin);
|
|
2153
|
-
stopTunnel = startTunnelRuntime(cwd);
|
|
2154
|
-
}
|
|
2155
|
-
const pm = await detectPackageManager(cwd);
|
|
2156
|
-
info(dim(`(running: ${pm} run ${SCRIPT_DEV})`));
|
|
2157
|
-
const child = spawn(pm, ["run", SCRIPT_DEV], { cwd, stdio: "inherit" });
|
|
2158
|
-
try {
|
|
2159
|
-
await new Promise((resolve, reject) => {
|
|
2160
|
-
child.on("error", (err) => reject(new CliError(CLI_ERROR_CODE.INVALID_INPUT, `Failed to spawn ${pm}: ${err.message}`)));
|
|
2161
|
-
child.on("close", (code) => {
|
|
2162
|
-
process.exitCode = code ?? 0;
|
|
2163
|
-
resolve();
|
|
2164
|
-
});
|
|
2165
|
-
});
|
|
2166
|
-
} finally {
|
|
2167
|
-
stopTunnel?.();
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
|
|
2171
|
-
export { run as default, detectPackageManager, mergeEnvEntries };
|
|
2033
|
+
export { TUNNEL_URL_ENV, startTunnelRuntime };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { isFreestyleRemote, gitDetectRoot, gitStatusPorcelain, gitCurrentBranch, gitCurrentSha, gitGetRemoteUrl, gitPushToUrl, gitPush } from './chunk-
|
|
3
|
-
import { pollDeployment } from './chunk-
|
|
4
|
-
import { fetchRepoRecord, fetchCloneToken } from './chunk-
|
|
5
|
-
import { promptYesNo } from './chunk-
|
|
2
|
+
import { isFreestyleRemote, gitDetectRoot, gitStatusPorcelain, gitCurrentBranch, gitCurrentSha, gitGetRemoteUrl, gitPushToUrl, gitPush } from './chunk-OVHZV57L.mjs';
|
|
3
|
+
import { pollDeployment } from './chunk-VJJDGHZC.mjs';
|
|
4
|
+
import { fetchRepoRecord, fetchCloneToken } from './chunk-RR4NOZGY.mjs';
|
|
5
|
+
import { promptYesNo } from './chunk-4YIFBYBV.mjs';
|
|
6
6
|
import { REPO_PROVIDER, ENV_SCOPE, DEPLOY_TRIGGER, DEPLOYMENT_STATUS, TOKEN_PURPOSE } from './chunk-MXYUAJEW.mjs';
|
|
7
7
|
import { parseArgs, flagBool, flagString } from './chunk-C4M3DXKC.mjs';
|
|
8
|
-
import { ApiClient } from './chunk-
|
|
9
|
-
import { readAuth, readProjectLink, writeProjectState } from './chunk-
|
|
10
|
-
import { CliError, CLI_ERROR_CODE,
|
|
8
|
+
import { ApiClient } from './chunk-JPXK5BLA.mjs';
|
|
9
|
+
import { readAuth, readProjectLink, writeProjectState } from './chunk-QA36VSLX.mjs';
|
|
10
|
+
import { CliError, CLI_ERROR_CODE, EXIT_CODE } from './chunk-YPC4VU65.mjs';
|
|
11
|
+
import { info, dim, step, success, result } from './chunk-ZPVN6UXL.mjs';
|
|
11
12
|
|
|
12
13
|
// src/commands/deploy.ts
|
|
13
14
|
var FLAG_PROD = "prod";
|