@specific.dev/cli 0.1.72 → 0.1.74
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/admin/404/index.html +1 -1
- package/dist/admin/404.html +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +2 -2
- package/dist/admin/__next.!KGRlZmF1bHQp.txt +5 -5
- package/dist/admin/__next._full.txt +8 -8
- package/dist/admin/__next._head.txt +1 -1
- package/dist/admin/__next._index.txt +3 -3
- package/dist/admin/__next._tree.txt +1 -1
- package/dist/admin/_next/static/chunks/4bd160f783f6ccf1.js +1 -0
- package/dist/admin/_not-found/__next._full.txt +3 -3
- package/dist/admin/_not-found/__next._head.txt +1 -1
- package/dist/admin/_not-found/__next._index.txt +3 -3
- package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.txt +1 -1
- package/dist/admin/_not-found/__next._tree.txt +1 -1
- package/dist/admin/_not-found/index.html +1 -1
- package/dist/admin/_not-found/index.txt +3 -3
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +2 -2
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +5 -5
- package/dist/admin/databases/__next._full.txt +8 -8
- package/dist/admin/databases/__next._head.txt +1 -1
- package/dist/admin/databases/__next._index.txt +3 -3
- package/dist/admin/databases/__next._tree.txt +1 -1
- package/dist/admin/databases/index.html +1 -1
- package/dist/admin/databases/index.txt +8 -8
- package/dist/admin/fullscreen/__next._full.txt +4 -4
- package/dist/admin/fullscreen/__next._head.txt +1 -1
- package/dist/admin/fullscreen/__next._index.txt +3 -3
- package/dist/admin/fullscreen/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +2 -2
- package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._full.txt +4 -4
- package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._index.txt +3 -3
- package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +2 -2
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/index.html +1 -1
- package/dist/admin/fullscreen/databases/index.txt +4 -4
- package/dist/admin/fullscreen/index.html +1 -1
- package/dist/admin/fullscreen/index.txt +4 -4
- package/dist/admin/index.html +1 -1
- package/dist/admin/index.txt +8 -8
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +2 -2
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +5 -5
- package/dist/admin/mail/__next._full.txt +8 -8
- package/dist/admin/mail/__next._head.txt +1 -1
- package/dist/admin/mail/__next._index.txt +3 -3
- package/dist/admin/mail/__next._tree.txt +1 -1
- package/dist/admin/mail/index.html +1 -1
- package/dist/admin/mail/index.txt +8 -8
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +5 -5
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +2 -2
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
- package/dist/admin/workflows/__next._full.txt +8 -8
- package/dist/admin/workflows/__next._head.txt +1 -1
- package/dist/admin/workflows/__next._index.txt +3 -3
- package/dist/admin/workflows/__next._tree.txt +1 -1
- package/dist/admin/workflows/index.html +1 -1
- package/dist/admin/workflows/index.txt +8 -8
- package/dist/cli.js +137 -341
- package/dist/postinstall.js +1 -1
- package/package.json +1 -1
- package/dist/admin/_next/static/chunks/47a5dab862795de7.js +0 -1
- /package/dist/admin/_next/static/{EdA1eXzy3MBFAW53uuebn → rlz8iRhM93pN2MuVf1ScD}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{EdA1eXzy3MBFAW53uuebn → rlz8iRhM93pN2MuVf1ScD}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{EdA1eXzy3MBFAW53uuebn → rlz8iRhM93pN2MuVf1ScD}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -637,19 +637,19 @@ var init_open = __esm({
|
|
|
637
637
|
}
|
|
638
638
|
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
639
639
|
if (options2.wait) {
|
|
640
|
-
return new Promise((
|
|
640
|
+
return new Promise((resolve9, reject) => {
|
|
641
641
|
subprocess.once("error", reject);
|
|
642
642
|
subprocess.once("close", (exitCode) => {
|
|
643
643
|
if (!options2.allowNonzeroExitCode && exitCode !== 0) {
|
|
644
644
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
645
645
|
return;
|
|
646
646
|
}
|
|
647
|
-
|
|
647
|
+
resolve9(subprocess);
|
|
648
648
|
});
|
|
649
649
|
});
|
|
650
650
|
}
|
|
651
651
|
if (isFallbackAttempt) {
|
|
652
|
-
return new Promise((
|
|
652
|
+
return new Promise((resolve9, reject) => {
|
|
653
653
|
subprocess.once("error", reject);
|
|
654
654
|
subprocess.once("spawn", () => {
|
|
655
655
|
subprocess.once("close", (exitCode) => {
|
|
@@ -659,17 +659,17 @@ var init_open = __esm({
|
|
|
659
659
|
return;
|
|
660
660
|
}
|
|
661
661
|
subprocess.unref();
|
|
662
|
-
|
|
662
|
+
resolve9(subprocess);
|
|
663
663
|
});
|
|
664
664
|
});
|
|
665
665
|
});
|
|
666
666
|
}
|
|
667
667
|
subprocess.unref();
|
|
668
|
-
return new Promise((
|
|
668
|
+
return new Promise((resolve9, reject) => {
|
|
669
669
|
subprocess.once("error", reject);
|
|
670
670
|
subprocess.once("spawn", () => {
|
|
671
671
|
subprocess.off("error", reject);
|
|
672
|
-
|
|
672
|
+
resolve9(subprocess);
|
|
673
673
|
});
|
|
674
674
|
});
|
|
675
675
|
};
|
|
@@ -183448,9 +183448,25 @@ import { execSync } from "child_process";
|
|
|
183448
183448
|
function getCADir() {
|
|
183449
183449
|
return path.join(os.homedir(), ".specific", "root_ca");
|
|
183450
183450
|
}
|
|
183451
|
+
var EXPECTED_DOMAIN = "spcf.localhost";
|
|
183451
183452
|
function caFilesExist() {
|
|
183452
183453
|
const caDir = getCADir();
|
|
183453
|
-
|
|
183454
|
+
const keyPath = path.join(caDir, "ca.key");
|
|
183455
|
+
const certPath = path.join(caDir, "ca.crt");
|
|
183456
|
+
if (!fs.existsSync(keyPath) || !fs.existsSync(certPath)) {
|
|
183457
|
+
return false;
|
|
183458
|
+
}
|
|
183459
|
+
try {
|
|
183460
|
+
const certPem = fs.readFileSync(certPath, "utf-8");
|
|
183461
|
+
const cert = forge.pki.certificateFromPem(certPem);
|
|
183462
|
+
const nameConstraints = cert.getExtension("nameConstraints");
|
|
183463
|
+
if (!nameConstraints) {
|
|
183464
|
+
return false;
|
|
183465
|
+
}
|
|
183466
|
+
return nameConstraints.value.includes(EXPECTED_DOMAIN);
|
|
183467
|
+
} catch {
|
|
183468
|
+
return false;
|
|
183469
|
+
}
|
|
183454
183470
|
}
|
|
183455
183471
|
function caInstalledInTrustStore() {
|
|
183456
183472
|
if (!caFilesExist()) {
|
|
@@ -183539,8 +183555,8 @@ function generateRootCA() {
|
|
|
183539
183555
|
cert.setSubject(attrs);
|
|
183540
183556
|
cert.setIssuer(attrs);
|
|
183541
183557
|
const nameConstraintsExt = createNameConstraintsExtension([
|
|
183542
|
-
".
|
|
183543
|
-
"
|
|
183558
|
+
".spcf.localhost",
|
|
183559
|
+
"spcf.localhost"
|
|
183544
183560
|
]);
|
|
183545
183561
|
cert.setExtensions([
|
|
183546
183562
|
{ name: "basicConstraints", cA: true, critical: true },
|
|
@@ -183638,7 +183654,8 @@ function generateCertificate(domain, keys = []) {
|
|
|
183638
183654
|
// src/lib/dev/resolver-config.ts
|
|
183639
183655
|
import * as fs2 from "fs";
|
|
183640
183656
|
import * as os2 from "os";
|
|
183641
|
-
var RESOLVER_FILE_MACOS = "/etc/resolver/
|
|
183657
|
+
var RESOLVER_FILE_MACOS = "/etc/resolver/spcf.localhost";
|
|
183658
|
+
var OLD_RESOLVER_FILE_MACOS = "/etc/resolver/local.spcf.app";
|
|
183642
183659
|
var RESOLVER_FILE_LINUX = "/etc/systemd/resolved.conf.d/specific-local.conf";
|
|
183643
183660
|
function resolverConfigExists() {
|
|
183644
183661
|
const platform6 = os2.platform();
|
|
@@ -183654,13 +183671,14 @@ function getResolverInstallCommands(port) {
|
|
|
183654
183671
|
if (platform6 === "darwin") {
|
|
183655
183672
|
return [
|
|
183656
183673
|
"mkdir -p /etc/resolver",
|
|
183674
|
+
`rm -f ${OLD_RESOLVER_FILE_MACOS}`,
|
|
183657
183675
|
`printf "nameserver 127.0.0.1\\nport ${port}\\n" > ${RESOLVER_FILE_MACOS}`
|
|
183658
183676
|
];
|
|
183659
183677
|
} else if (platform6 === "linux") {
|
|
183660
183678
|
if (fs2.existsSync("/etc/systemd/resolved.conf.d") || fs2.existsSync("/etc/systemd")) {
|
|
183661
183679
|
return [
|
|
183662
183680
|
"mkdir -p /etc/systemd/resolved.conf.d",
|
|
183663
|
-
`printf "[Resolve]\\nDNS=127.0.0.1:${port}\\nDomains=~
|
|
183681
|
+
`printf "[Resolve]\\nDNS=127.0.0.1:${port}\\nDomains=~spcf.localhost\\n" > ${RESOLVER_FILE_LINUX}`,
|
|
183664
183682
|
"systemctl restart systemd-resolved"
|
|
183665
183683
|
];
|
|
183666
183684
|
}
|
|
@@ -184028,7 +184046,7 @@ async function pollUntilToken(deviceAuth, isCancelled) {
|
|
|
184028
184046
|
return null;
|
|
184029
184047
|
}
|
|
184030
184048
|
function sleep(ms) {
|
|
184031
|
-
return new Promise((
|
|
184049
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
184032
184050
|
}
|
|
184033
184051
|
|
|
184034
184052
|
// src/lib/auth/login.tsx
|
|
@@ -184045,7 +184063,7 @@ function LoginUI({
|
|
|
184045
184063
|
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, isReauthentication && /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "Session expired. Please log in again."), /* @__PURE__ */ React.createElement(Text, { bold: true }, "Log in to Specific"), state.phase === "waiting-for-browser" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, "Your authentication code:", " ", /* @__PURE__ */ React.createElement(Text, { color: "cyan", bold: true }, state.userCode))), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "blue" }, /* @__PURE__ */ React.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React.createElement(Text, null, " Waiting for authentication in browser...")), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "If the browser didn't open, visit: ", state.verificationUri)) : /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "blue" }, /* @__PURE__ */ React.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React.createElement(Text, null, " Initiating login...")));
|
|
184046
184064
|
}
|
|
184047
184065
|
function performLogin(options2 = {}) {
|
|
184048
|
-
return new Promise((
|
|
184066
|
+
return new Promise((resolve9) => {
|
|
184049
184067
|
let currentState = { phase: "initiating" };
|
|
184050
184068
|
let flowHandle;
|
|
184051
184069
|
const instance = render(
|
|
@@ -184085,14 +184103,14 @@ function performLogin(options2 = {}) {
|
|
|
184085
184103
|
process.off("SIGINT", handleExit);
|
|
184086
184104
|
process.off("SIGTERM", handleExit);
|
|
184087
184105
|
instance.unmount();
|
|
184088
|
-
|
|
184106
|
+
resolve9({ success: true, userEmail: newState.email });
|
|
184089
184107
|
}, 100);
|
|
184090
184108
|
} else if (newState.phase === "error") {
|
|
184091
184109
|
setTimeout(() => {
|
|
184092
184110
|
process.off("SIGINT", handleExit);
|
|
184093
184111
|
process.off("SIGTERM", handleExit);
|
|
184094
184112
|
instance.unmount();
|
|
184095
|
-
|
|
184113
|
+
resolve9({ success: false, error: new Error(newState.message) });
|
|
184096
184114
|
}, 100);
|
|
184097
184115
|
}
|
|
184098
184116
|
}
|
|
@@ -184569,7 +184587,7 @@ function trackEvent(event, properties) {
|
|
|
184569
184587
|
event,
|
|
184570
184588
|
properties: {
|
|
184571
184589
|
...properties,
|
|
184572
|
-
cli_version: "0.1.
|
|
184590
|
+
cli_version: "0.1.74",
|
|
184573
184591
|
platform: process.platform,
|
|
184574
184592
|
node_version: process.version,
|
|
184575
184593
|
project_id: getProjectId()
|
|
@@ -184832,7 +184850,7 @@ function InitUI() {
|
|
|
184832
184850
|
}, [phase, exit]);
|
|
184833
184851
|
if (phase === "installing-ca") {
|
|
184834
184852
|
if (caInstallPhase === "prompt") {
|
|
184835
|
-
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, "Configure development environment"), /* @__PURE__ */ React2.createElement(Text2, null, " "), /* @__PURE__ */ React2.createElement(Text2, null, "We need to do a one-time setup for all your Specific projects."), /* @__PURE__ */ React2.createElement(Text2, null, "This is so we can run your apps locally with secure URLs:"), /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "green" }, "https://your-app.
|
|
184853
|
+
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, "Configure development environment"), /* @__PURE__ */ React2.createElement(Text2, null, " "), /* @__PURE__ */ React2.createElement(Text2, null, "We need to do a one-time setup for all your Specific projects."), /* @__PURE__ */ React2.createElement(Text2, null, "This is so we can run your apps locally with secure URLs:"), /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "green" }, "https://your-app.spcf.localhost"), /* @__PURE__ */ React2.createElement(Text2, null, " "), /* @__PURE__ */ React2.createElement(Text2, null, "You will be prompted to authorize with your password."), /* @__PURE__ */ React2.createElement(Text2, null, " "), /* @__PURE__ */ React2.createElement(Text2, null, "Press ", /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, "Enter"), " to authorize."));
|
|
184836
184854
|
}
|
|
184837
184855
|
if (caInstallPhase === "installing") {
|
|
184838
184856
|
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, "Configure development environment"), /* @__PURE__ */ React2.createElement(Text2, null, " "), /* @__PURE__ */ React2.createElement(Text2, null, "Awaiting authorization\u2026"));
|
|
@@ -186030,10 +186048,10 @@ async function downloadFile(url, destPath, onProgress) {
|
|
|
186030
186048
|
});
|
|
186031
186049
|
}
|
|
186032
186050
|
}
|
|
186033
|
-
await new Promise((
|
|
186051
|
+
await new Promise((resolve9, reject) => {
|
|
186034
186052
|
fileStream.end((err) => {
|
|
186035
186053
|
if (err) reject(err);
|
|
186036
|
-
else
|
|
186054
|
+
else resolve9();
|
|
186037
186055
|
});
|
|
186038
186056
|
});
|
|
186039
186057
|
fs13.renameSync(partPath, destPath);
|
|
@@ -186259,13 +186277,13 @@ async function runReshapeCheck(migrationsDir) {
|
|
|
186259
186277
|
try {
|
|
186260
186278
|
const binary = await ensureBinary(reshapeBinary);
|
|
186261
186279
|
const reshapePath = binary.executables["reshape"];
|
|
186262
|
-
return new Promise((
|
|
186280
|
+
return new Promise((resolve9) => {
|
|
186263
186281
|
execFile7(reshapePath, ["check", "--dirs", migrationsDir], (err, _stdout, stderr) => {
|
|
186264
186282
|
if (err) {
|
|
186265
186283
|
const errorMsg = stderr.trim() || err.message;
|
|
186266
|
-
|
|
186284
|
+
resolve9({ success: false, error: errorMsg });
|
|
186267
186285
|
} else {
|
|
186268
|
-
|
|
186286
|
+
resolve9({ success: true });
|
|
186269
186287
|
}
|
|
186270
186288
|
});
|
|
186271
186289
|
});
|
|
@@ -187234,7 +187252,7 @@ var NodeFsHandler = class {
|
|
|
187234
187252
|
this._addToNodeFs(path30, initialAdd, wh, depth + 1);
|
|
187235
187253
|
}
|
|
187236
187254
|
}).on(EV.ERROR, this._boundHandleError);
|
|
187237
|
-
return new Promise((
|
|
187255
|
+
return new Promise((resolve9, reject) => {
|
|
187238
187256
|
if (!stream)
|
|
187239
187257
|
return reject();
|
|
187240
187258
|
stream.once(STR_END, () => {
|
|
@@ -187243,7 +187261,7 @@ var NodeFsHandler = class {
|
|
|
187243
187261
|
return;
|
|
187244
187262
|
}
|
|
187245
187263
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
187246
|
-
|
|
187264
|
+
resolve9(void 0);
|
|
187247
187265
|
previous.getChildren().filter((item) => {
|
|
187248
187266
|
return item !== directory && !current.has(item);
|
|
187249
187267
|
}).forEach((item) => {
|
|
@@ -188307,7 +188325,7 @@ async function startStorage(storage, port, dataDir) {
|
|
|
188307
188325
|
};
|
|
188308
188326
|
}
|
|
188309
188327
|
async function runCommand(command, args, env2) {
|
|
188310
|
-
return new Promise((
|
|
188328
|
+
return new Promise((resolve9, reject) => {
|
|
188311
188329
|
const proc = spawn(command, args, {
|
|
188312
188330
|
stdio: ["ignore", "pipe", "pipe"],
|
|
188313
188331
|
env: env2
|
|
@@ -188318,7 +188336,7 @@ async function runCommand(command, args, env2) {
|
|
|
188318
188336
|
});
|
|
188319
188337
|
proc.on("close", (code) => {
|
|
188320
188338
|
if (code === 0) {
|
|
188321
|
-
|
|
188339
|
+
resolve9();
|
|
188322
188340
|
} else {
|
|
188323
188341
|
reject(new Error(`Command failed with code ${code}: ${stderr}`));
|
|
188324
188342
|
}
|
|
@@ -188327,7 +188345,7 @@ async function runCommand(command, args, env2) {
|
|
|
188327
188345
|
});
|
|
188328
188346
|
}
|
|
188329
188347
|
async function createPostgresDatabase(postgresPath, dataDir, dbName, env2) {
|
|
188330
|
-
return new Promise((
|
|
188348
|
+
return new Promise((resolve9, reject) => {
|
|
188331
188349
|
const proc = spawn(
|
|
188332
188350
|
postgresPath,
|
|
188333
188351
|
["--single", "-D", dataDir, "postgres"],
|
|
@@ -188341,7 +188359,7 @@ async function createPostgresDatabase(postgresPath, dataDir, dbName, env2) {
|
|
|
188341
188359
|
stderr += data.toString();
|
|
188342
188360
|
});
|
|
188343
188361
|
proc.on("close", (code) => {
|
|
188344
|
-
|
|
188362
|
+
resolve9();
|
|
188345
188363
|
});
|
|
188346
188364
|
proc.on("error", reject);
|
|
188347
188365
|
proc.stdin?.write(`CREATE DATABASE "${dbName}";
|
|
@@ -188361,33 +188379,33 @@ async function waitForTcpPort(host, port, timeoutMs = 3e4) {
|
|
|
188361
188379
|
throw new Error(`Port ${port} did not become available within timeout`);
|
|
188362
188380
|
}
|
|
188363
188381
|
function checkTcpPort(host, port) {
|
|
188364
|
-
return new Promise((
|
|
188382
|
+
return new Promise((resolve9) => {
|
|
188365
188383
|
const socket = new net.Socket();
|
|
188366
188384
|
socket.setTimeout(1e3);
|
|
188367
188385
|
socket.on("connect", () => {
|
|
188368
188386
|
socket.destroy();
|
|
188369
|
-
|
|
188387
|
+
resolve9(true);
|
|
188370
188388
|
});
|
|
188371
188389
|
socket.on("timeout", () => {
|
|
188372
188390
|
socket.destroy();
|
|
188373
|
-
|
|
188391
|
+
resolve9(false);
|
|
188374
188392
|
});
|
|
188375
188393
|
socket.on("error", () => {
|
|
188376
188394
|
socket.destroy();
|
|
188377
|
-
|
|
188395
|
+
resolve9(false);
|
|
188378
188396
|
});
|
|
188379
188397
|
socket.connect(port, host);
|
|
188380
188398
|
});
|
|
188381
188399
|
}
|
|
188382
188400
|
async function stopProcess(proc) {
|
|
188383
|
-
return new Promise((
|
|
188401
|
+
return new Promise((resolve9) => {
|
|
188384
188402
|
if (proc.killed || proc.exitCode !== null) {
|
|
188385
|
-
|
|
188403
|
+
resolve9();
|
|
188386
188404
|
return;
|
|
188387
188405
|
}
|
|
188388
188406
|
proc.once("exit", () => {
|
|
188389
188407
|
clearTimeout(forceKillTimeout);
|
|
188390
|
-
|
|
188408
|
+
resolve9();
|
|
188391
188409
|
});
|
|
188392
188410
|
proc.kill("SIGTERM");
|
|
188393
188411
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -188398,7 +188416,7 @@ async function stopProcess(proc) {
|
|
|
188398
188416
|
});
|
|
188399
188417
|
}
|
|
188400
188418
|
function sleep2(ms) {
|
|
188401
|
-
return new Promise((
|
|
188419
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
188402
188420
|
}
|
|
188403
188421
|
|
|
188404
188422
|
// src/lib/dev/service-runner.ts
|
|
@@ -188882,14 +188900,14 @@ function startService(service, resources, secrets, configs, endpointPorts, servi
|
|
|
188882
188900
|
ports: endpointPorts,
|
|
188883
188901
|
process: child,
|
|
188884
188902
|
async stop() {
|
|
188885
|
-
return new Promise((
|
|
188903
|
+
return new Promise((resolve9) => {
|
|
188886
188904
|
if (child.killed || child.exitCode !== null) {
|
|
188887
|
-
|
|
188905
|
+
resolve9();
|
|
188888
188906
|
return;
|
|
188889
188907
|
}
|
|
188890
188908
|
child.once("exit", () => {
|
|
188891
188909
|
clearTimeout(forceKillTimeout);
|
|
188892
|
-
|
|
188910
|
+
resolve9();
|
|
188893
188911
|
});
|
|
188894
188912
|
const pid = child.pid;
|
|
188895
188913
|
if (pid) {
|
|
@@ -188983,7 +189001,7 @@ var InstanceStateManager = class {
|
|
|
188983
189001
|
}
|
|
188984
189002
|
continue;
|
|
188985
189003
|
}
|
|
188986
|
-
await new Promise((
|
|
189004
|
+
await new Promise((resolve9) => setTimeout(resolve9, 100));
|
|
188987
189005
|
} else {
|
|
188988
189006
|
throw e;
|
|
188989
189007
|
}
|
|
@@ -189138,8 +189156,8 @@ var adminDir = path13.join(__dirname3, "admin");
|
|
|
189138
189156
|
var _embeddedAdmin = null;
|
|
189139
189157
|
var HTTP_PORT = 80;
|
|
189140
189158
|
var HTTPS_PORT = 443;
|
|
189141
|
-
var DOMAIN_SUFFIX = ".
|
|
189142
|
-
var ADMIN_DOMAIN = "
|
|
189159
|
+
var DOMAIN_SUFFIX = ".spcf.localhost";
|
|
189160
|
+
var ADMIN_DOMAIN = "spcf.localhost";
|
|
189143
189161
|
var DRIZZLE_GATEWAY_PREFIX = "__drizzle_gateway";
|
|
189144
189162
|
var TEMPORAL_UI_PREFIX = "__temporal";
|
|
189145
189163
|
var MIME_TYPES = {
|
|
@@ -189316,7 +189334,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
189316
189334
|
handleRequest
|
|
189317
189335
|
);
|
|
189318
189336
|
httpsServer.on("upgrade", handleUpgrade);
|
|
189319
|
-
return new Promise((
|
|
189337
|
+
return new Promise((resolve9, reject) => {
|
|
189320
189338
|
let httpStarted = false;
|
|
189321
189339
|
let httpsStarted = false;
|
|
189322
189340
|
let failed = false;
|
|
@@ -189327,7 +189345,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
189327
189345
|
"proxy",
|
|
189328
189346
|
`HTTP/HTTPS proxy started on ports ${HTTP_PORT}/${HTTPS_PORT}`
|
|
189329
189347
|
);
|
|
189330
|
-
|
|
189348
|
+
resolve9({
|
|
189331
189349
|
httpPort: HTTP_PORT,
|
|
189332
189350
|
httpsPort: HTTPS_PORT,
|
|
189333
189351
|
updateServices,
|
|
@@ -189339,13 +189357,13 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
189339
189357
|
writeLog("proxy", "Certificate updated");
|
|
189340
189358
|
},
|
|
189341
189359
|
async stop() {
|
|
189342
|
-
return new Promise((
|
|
189360
|
+
return new Promise((resolve10) => {
|
|
189343
189361
|
let closed = 0;
|
|
189344
189362
|
const onClose = () => {
|
|
189345
189363
|
closed++;
|
|
189346
189364
|
if (closed === 2) {
|
|
189347
189365
|
clearTimeout(forceCloseTimeout);
|
|
189348
|
-
|
|
189366
|
+
resolve10();
|
|
189349
189367
|
}
|
|
189350
189368
|
};
|
|
189351
189369
|
httpServer.close(onClose);
|
|
@@ -189353,7 +189371,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
189353
189371
|
const forceCloseTimeout = setTimeout(() => {
|
|
189354
189372
|
httpServer.closeAllConnections?.();
|
|
189355
189373
|
httpsServer.closeAllConnections?.();
|
|
189356
|
-
|
|
189374
|
+
resolve10();
|
|
189357
189375
|
}, 2e3);
|
|
189358
189376
|
});
|
|
189359
189377
|
}
|
|
@@ -189463,9 +189481,9 @@ function sendNotFound(res, requestedService, serviceMap) {
|
|
|
189463
189481
|
const serviceList = Array.from(serviceMap.keys()).map((key) => {
|
|
189464
189482
|
const parts = key.split(".");
|
|
189465
189483
|
if (parts.length === 1) {
|
|
189466
|
-
return `<li>${parts[0]}.
|
|
189484
|
+
return `<li>${parts[0]}.spcf.localhost</li>`;
|
|
189467
189485
|
} else {
|
|
189468
|
-
return `<li>${key}.
|
|
189486
|
+
return `<li>${key}.spcf.localhost</li>`;
|
|
189469
189487
|
}
|
|
189470
189488
|
}).join("\n");
|
|
189471
189489
|
const message = requestedService ? `No service named "${requestedService}" is running.` : "Invalid host header.";
|
|
@@ -189581,7 +189599,7 @@ function serveFileContent(res, filePath, contentType, statusCode = 200) {
|
|
|
189581
189599
|
}
|
|
189582
189600
|
}
|
|
189583
189601
|
async function startAdminServer(getState) {
|
|
189584
|
-
return new Promise((
|
|
189602
|
+
return new Promise((resolve9, reject) => {
|
|
189585
189603
|
const server = http.createServer((req, res) => {
|
|
189586
189604
|
const url = new URL(req.url || "/", "http://localhost");
|
|
189587
189605
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
@@ -189613,7 +189631,7 @@ async function startAdminServer(getState) {
|
|
|
189613
189631
|
}
|
|
189614
189632
|
const port = addr.port;
|
|
189615
189633
|
writeLog("admin", `Admin API server started on port ${port}`);
|
|
189616
|
-
|
|
189634
|
+
resolve9({
|
|
189617
189635
|
port,
|
|
189618
189636
|
stop: () => new Promise((res, rej) => {
|
|
189619
189637
|
server.close((err) => err ? rej(err) : res());
|
|
@@ -189774,33 +189792,33 @@ async function waitForTcpPort2(host, port, timeoutMs = 3e4) {
|
|
|
189774
189792
|
throw new Error(`Electric port ${port} did not become available within timeout`);
|
|
189775
189793
|
}
|
|
189776
189794
|
function checkTcpPort2(host, port) {
|
|
189777
|
-
return new Promise((
|
|
189795
|
+
return new Promise((resolve9) => {
|
|
189778
189796
|
const socket = new net2.Socket();
|
|
189779
189797
|
socket.setTimeout(1e3);
|
|
189780
189798
|
socket.on("connect", () => {
|
|
189781
189799
|
socket.destroy();
|
|
189782
|
-
|
|
189800
|
+
resolve9(true);
|
|
189783
189801
|
});
|
|
189784
189802
|
socket.on("timeout", () => {
|
|
189785
189803
|
socket.destroy();
|
|
189786
|
-
|
|
189804
|
+
resolve9(false);
|
|
189787
189805
|
});
|
|
189788
189806
|
socket.on("error", () => {
|
|
189789
189807
|
socket.destroy();
|
|
189790
|
-
|
|
189808
|
+
resolve9(false);
|
|
189791
189809
|
});
|
|
189792
189810
|
socket.connect(port, host);
|
|
189793
189811
|
});
|
|
189794
189812
|
}
|
|
189795
189813
|
async function stopProcess2(proc) {
|
|
189796
|
-
return new Promise((
|
|
189814
|
+
return new Promise((resolve9) => {
|
|
189797
189815
|
if (proc.killed || proc.exitCode !== null) {
|
|
189798
|
-
|
|
189816
|
+
resolve9();
|
|
189799
189817
|
return;
|
|
189800
189818
|
}
|
|
189801
189819
|
proc.once("exit", () => {
|
|
189802
189820
|
clearTimeout(forceKillTimeout);
|
|
189803
|
-
|
|
189821
|
+
resolve9();
|
|
189804
189822
|
});
|
|
189805
189823
|
proc.kill("SIGTERM");
|
|
189806
189824
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -189811,7 +189829,7 @@ async function stopProcess2(proc) {
|
|
|
189811
189829
|
});
|
|
189812
189830
|
}
|
|
189813
189831
|
function sleep3(ms) {
|
|
189814
|
-
return new Promise((
|
|
189832
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
189815
189833
|
}
|
|
189816
189834
|
|
|
189817
189835
|
// src/lib/dev/mail-manager.ts
|
|
@@ -189906,20 +189924,20 @@ async function startMailServer(mail, smtpPort, apiPort) {
|
|
|
189906
189924
|
res.writeHead(404);
|
|
189907
189925
|
res.end();
|
|
189908
189926
|
});
|
|
189909
|
-
await new Promise((
|
|
189910
|
-
smtpServer.listen(smtpPort, "127.0.0.1", () =>
|
|
189927
|
+
await new Promise((resolve9, reject) => {
|
|
189928
|
+
smtpServer.listen(smtpPort, "127.0.0.1", () => resolve9());
|
|
189911
189929
|
smtpServer.on("error", reject);
|
|
189912
189930
|
});
|
|
189913
|
-
await new Promise((
|
|
189914
|
-
httpServer.listen(apiPort, "127.0.0.1", () =>
|
|
189931
|
+
await new Promise((resolve9, reject) => {
|
|
189932
|
+
httpServer.listen(apiPort, "127.0.0.1", () => resolve9());
|
|
189915
189933
|
httpServer.on("error", reject);
|
|
189916
189934
|
});
|
|
189917
189935
|
const stop = async () => {
|
|
189918
|
-
await new Promise((
|
|
189919
|
-
smtpServer.close(() =>
|
|
189936
|
+
await new Promise((resolve9) => {
|
|
189937
|
+
smtpServer.close(() => resolve9());
|
|
189920
189938
|
});
|
|
189921
|
-
await new Promise((
|
|
189922
|
-
httpServer.close(() =>
|
|
189939
|
+
await new Promise((resolve9) => {
|
|
189940
|
+
httpServer.close(() => resolve9());
|
|
189923
189941
|
});
|
|
189924
189942
|
};
|
|
189925
189943
|
const resource = {
|
|
@@ -190023,33 +190041,33 @@ async function waitForTcpPort3(host, port, timeoutMs = 3e4) {
|
|
|
190023
190041
|
);
|
|
190024
190042
|
}
|
|
190025
190043
|
function checkTcpPort3(host, port) {
|
|
190026
|
-
return new Promise((
|
|
190044
|
+
return new Promise((resolve9) => {
|
|
190027
190045
|
const socket = new net3.Socket();
|
|
190028
190046
|
socket.setTimeout(1e3);
|
|
190029
190047
|
socket.on("connect", () => {
|
|
190030
190048
|
socket.destroy();
|
|
190031
|
-
|
|
190049
|
+
resolve9(true);
|
|
190032
190050
|
});
|
|
190033
190051
|
socket.on("timeout", () => {
|
|
190034
190052
|
socket.destroy();
|
|
190035
|
-
|
|
190053
|
+
resolve9(false);
|
|
190036
190054
|
});
|
|
190037
190055
|
socket.on("error", () => {
|
|
190038
190056
|
socket.destroy();
|
|
190039
|
-
|
|
190057
|
+
resolve9(false);
|
|
190040
190058
|
});
|
|
190041
190059
|
socket.connect(port, host);
|
|
190042
190060
|
});
|
|
190043
190061
|
}
|
|
190044
190062
|
async function stopProcess3(proc) {
|
|
190045
|
-
return new Promise((
|
|
190063
|
+
return new Promise((resolve9) => {
|
|
190046
190064
|
if (proc.killed || proc.exitCode !== null) {
|
|
190047
|
-
|
|
190065
|
+
resolve9();
|
|
190048
190066
|
return;
|
|
190049
190067
|
}
|
|
190050
190068
|
proc.once("exit", () => {
|
|
190051
190069
|
clearTimeout(forceKillTimeout);
|
|
190052
|
-
|
|
190070
|
+
resolve9();
|
|
190053
190071
|
});
|
|
190054
190072
|
proc.kill("SIGTERM");
|
|
190055
190073
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -190060,7 +190078,7 @@ async function stopProcess3(proc) {
|
|
|
190060
190078
|
});
|
|
190061
190079
|
}
|
|
190062
190080
|
function sleep4(ms) {
|
|
190063
|
-
return new Promise((
|
|
190081
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
190064
190082
|
}
|
|
190065
190083
|
|
|
190066
190084
|
// src/lib/dev/sync-detector.ts
|
|
@@ -190425,38 +190443,38 @@ async function waitForTcpPort4(host, port, timeoutMs = 3e4) {
|
|
|
190425
190443
|
if (isOpen) {
|
|
190426
190444
|
return;
|
|
190427
190445
|
}
|
|
190428
|
-
await new Promise((
|
|
190446
|
+
await new Promise((resolve9) => setTimeout(resolve9, 100));
|
|
190429
190447
|
}
|
|
190430
190448
|
throw new Error(`Temporal port ${port} did not become available within timeout`);
|
|
190431
190449
|
}
|
|
190432
190450
|
function checkTcpPort4(host, port) {
|
|
190433
|
-
return new Promise((
|
|
190451
|
+
return new Promise((resolve9) => {
|
|
190434
190452
|
const socket = new net4.Socket();
|
|
190435
190453
|
socket.setTimeout(1e3);
|
|
190436
190454
|
socket.on("connect", () => {
|
|
190437
190455
|
socket.destroy();
|
|
190438
|
-
|
|
190456
|
+
resolve9(true);
|
|
190439
190457
|
});
|
|
190440
190458
|
socket.on("timeout", () => {
|
|
190441
190459
|
socket.destroy();
|
|
190442
|
-
|
|
190460
|
+
resolve9(false);
|
|
190443
190461
|
});
|
|
190444
190462
|
socket.on("error", () => {
|
|
190445
190463
|
socket.destroy();
|
|
190446
|
-
|
|
190464
|
+
resolve9(false);
|
|
190447
190465
|
});
|
|
190448
190466
|
socket.connect(port, host);
|
|
190449
190467
|
});
|
|
190450
190468
|
}
|
|
190451
190469
|
async function stopProcess4(proc) {
|
|
190452
|
-
return new Promise((
|
|
190470
|
+
return new Promise((resolve9) => {
|
|
190453
190471
|
if (proc.killed || proc.exitCode !== null) {
|
|
190454
|
-
|
|
190472
|
+
resolve9();
|
|
190455
190473
|
return;
|
|
190456
190474
|
}
|
|
190457
190475
|
proc.once("exit", () => {
|
|
190458
190476
|
clearTimeout(forceKillTimeout);
|
|
190459
|
-
|
|
190477
|
+
resolve9();
|
|
190460
190478
|
});
|
|
190461
190479
|
proc.kill("SIGTERM");
|
|
190462
190480
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -190931,7 +190949,7 @@ var ProxyRegistryManager = class {
|
|
|
190931
190949
|
* This catches cases where the owner process is alive but the proxy has crashed.
|
|
190932
190950
|
*/
|
|
190933
190951
|
isProxyListening(port, timeoutMs = 1e3) {
|
|
190934
|
-
return new Promise((
|
|
190952
|
+
return new Promise((resolve9) => {
|
|
190935
190953
|
const socket = new net6.Socket();
|
|
190936
190954
|
let resolved = false;
|
|
190937
190955
|
const cleanup = () => {
|
|
@@ -190943,15 +190961,15 @@ var ProxyRegistryManager = class {
|
|
|
190943
190961
|
socket.setTimeout(timeoutMs);
|
|
190944
190962
|
socket.on("connect", () => {
|
|
190945
190963
|
cleanup();
|
|
190946
|
-
|
|
190964
|
+
resolve9(true);
|
|
190947
190965
|
});
|
|
190948
190966
|
socket.on("timeout", () => {
|
|
190949
190967
|
cleanup();
|
|
190950
|
-
|
|
190968
|
+
resolve9(false);
|
|
190951
190969
|
});
|
|
190952
190970
|
socket.on("error", () => {
|
|
190953
190971
|
cleanup();
|
|
190954
|
-
|
|
190972
|
+
resolve9(false);
|
|
190955
190973
|
});
|
|
190956
190974
|
socket.connect(port, "127.0.0.1");
|
|
190957
190975
|
});
|
|
@@ -191002,7 +191020,7 @@ var ProxyRegistryManager = class {
|
|
|
191002
191020
|
}
|
|
191003
191021
|
continue;
|
|
191004
191022
|
}
|
|
191005
|
-
await new Promise((
|
|
191023
|
+
await new Promise((resolve9) => setTimeout(resolve9, 100));
|
|
191006
191024
|
} else {
|
|
191007
191025
|
throw e;
|
|
191008
191026
|
}
|
|
@@ -192018,7 +192036,7 @@ Add them to the config block in specific.local`);
|
|
|
192018
192036
|
} else {
|
|
192019
192037
|
const keySuffix = instanceKey === "default" ? "" : `.${instanceKey}`;
|
|
192020
192038
|
for (const svc of exposedServices) {
|
|
192021
|
-
publicUrls.set(svc.name, `${svc.name}${keySuffix}.
|
|
192039
|
+
publicUrls.set(svc.name, `${svc.name}${keySuffix}.spcf.localhost`);
|
|
192022
192040
|
}
|
|
192023
192041
|
}
|
|
192024
192042
|
const services2 = [];
|
|
@@ -192251,7 +192269,7 @@ Add them to the config block in specific.local`);
|
|
|
192251
192269
|
dnsServerRef.current = dnsServer;
|
|
192252
192270
|
const currentServices = await proxyRegistry.getAllServices();
|
|
192253
192271
|
const registeredKeys = [...new Set(currentServices.map((s) => s.key))];
|
|
192254
|
-
const certificate = generateCertificate("
|
|
192272
|
+
const certificate = generateCertificate("spcf.localhost", registeredKeys);
|
|
192255
192273
|
const proxy2 = await startHttpProxy(
|
|
192256
192274
|
exposedServices,
|
|
192257
192275
|
certificate,
|
|
@@ -192272,7 +192290,7 @@ Add them to the config block in specific.local`);
|
|
|
192272
192290
|
knownKeys.add(key);
|
|
192273
192291
|
}
|
|
192274
192292
|
const allKeys = [...knownKeys];
|
|
192275
|
-
const newCertificate = generateCertificate("
|
|
192293
|
+
const newCertificate = generateCertificate("spcf.localhost", allKeys);
|
|
192276
192294
|
proxy2.updateCertificate(newCertificate);
|
|
192277
192295
|
}
|
|
192278
192296
|
});
|
|
@@ -192324,7 +192342,7 @@ Add them to the config block in specific.local`);
|
|
|
192324
192342
|
const electionServices = await proxyRegistry.getAllServices();
|
|
192325
192343
|
const electionKeyRegistrations = await proxyRegistry.getAllKeyRegistrations();
|
|
192326
192344
|
const electionKeyNames = Object.keys(electionKeyRegistrations);
|
|
192327
|
-
const certificate = generateCertificate("
|
|
192345
|
+
const certificate = generateCertificate("spcf.localhost", electionKeyNames);
|
|
192328
192346
|
const proxy2 = await startHttpProxy(
|
|
192329
192347
|
exposedServices,
|
|
192330
192348
|
certificate,
|
|
@@ -192400,7 +192418,7 @@ Add them to the config block in specific.local`);
|
|
|
192400
192418
|
}, [reloadTrigger, readyToStart, instanceKey]);
|
|
192401
192419
|
if (state.status === "installing-ca") {
|
|
192402
192420
|
if (state.caInstallPhase === "prompt") {
|
|
192403
|
-
return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "cyan" }, "Configure development environment"), /* @__PURE__ */ React6.createElement(Text6, null, " "), /* @__PURE__ */ React6.createElement(Text6, null, "We need to do a one-time setup for all your Specific projects."), /* @__PURE__ */ React6.createElement(Text6, null, "This is so we can run your apps locally with secure URLs:"), /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "green" }, "https://your-app.
|
|
192421
|
+
return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "cyan" }, "Configure development environment"), /* @__PURE__ */ React6.createElement(Text6, null, " "), /* @__PURE__ */ React6.createElement(Text6, null, "We need to do a one-time setup for all your Specific projects."), /* @__PURE__ */ React6.createElement(Text6, null, "This is so we can run your apps locally with secure URLs:"), /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "green" }, "https://your-app.spcf.localhost"), /* @__PURE__ */ React6.createElement(Text6, null, " "), /* @__PURE__ */ React6.createElement(Text6, null, "You will be prompted to authorize with your password."), /* @__PURE__ */ React6.createElement(Text6, null, " "), /* @__PURE__ */ React6.createElement(Text6, null, "Press ", /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "cyan" }, "Enter"), " to authorize."));
|
|
192404
192422
|
}
|
|
192405
192423
|
if (state.caInstallPhase === "installing") {
|
|
192406
192424
|
return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "cyan" }, "Configure development environment"), /* @__PURE__ */ React6.createElement(Text6, null, " "), /* @__PURE__ */ React6.createElement(Text6, null, "Awaiting authorization\u2026"));
|
|
@@ -192525,7 +192543,7 @@ Add them to the config block in specific.local`);
|
|
|
192525
192543
|
...!tunnelEnabled ? [
|
|
192526
192544
|
{
|
|
192527
192545
|
key: "admin",
|
|
192528
|
-
content: /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "Admin:"), /* @__PURE__ */ React6.createElement(Text6, null, " "), /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "https://", instanceKey === "default" ? "" : `${instanceKey}.`, "
|
|
192546
|
+
content: /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "Admin:"), /* @__PURE__ */ React6.createElement(Text6, null, " "), /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "https://", instanceKey === "default" ? "" : `${instanceKey}.`, "spcf.localhost"))
|
|
192529
192547
|
},
|
|
192530
192548
|
{ key: "admin-space", content: /* @__PURE__ */ React6.createElement(Text6, null, " ") }
|
|
192531
192549
|
] : [],
|
|
@@ -192563,7 +192581,7 @@ Add them to the config block in specific.local`);
|
|
|
192563
192581
|
const proxyName = endpoint.name === "default" ? svc.name : `${svc.name}-${endpoint.name}`;
|
|
192564
192582
|
return {
|
|
192565
192583
|
key: `svc-${svc.name}-${endpoint.name}`,
|
|
192566
|
-
content: /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { color: "green" }, " \u25CF "), /* @__PURE__ */ React6.createElement(Text6, null, displayName), port ? endpoint.public ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, null, " \u2192 "), /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "https://", proxyName, instanceKey === "default" ? "" : `.${instanceKey}`, ".
|
|
192584
|
+
content: /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { color: "green" }, " \u25CF "), /* @__PURE__ */ React6.createElement(Text6, null, displayName), port ? endpoint.public ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, null, " \u2192 "), /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "https://", proxyName, instanceKey === "default" ? "" : `.${instanceKey}`, ".spcf.localhost"), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " (localhost:", port, ")")) : /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " (localhost:", port, ")") : null)
|
|
192567
192585
|
};
|
|
192568
192586
|
});
|
|
192569
192587
|
}),
|
|
@@ -192679,186 +192697,6 @@ import Spinner5 from "ink-spinner";
|
|
|
192679
192697
|
import * as fs26 from "fs";
|
|
192680
192698
|
import * as path23 from "path";
|
|
192681
192699
|
|
|
192682
|
-
// src/lib/deploy/build-tester.ts
|
|
192683
|
-
import { spawn as spawn6 } from "child_process";
|
|
192684
|
-
import { existsSync as existsSync22 } from "fs";
|
|
192685
|
-
import { join as join23, resolve as resolve7 } from "path";
|
|
192686
|
-
function getDependencyInstallCommand(build, projectDir) {
|
|
192687
|
-
if (!build.base) return null;
|
|
192688
|
-
switch (build.base) {
|
|
192689
|
-
case "node":
|
|
192690
|
-
if (existsSync22(join23(projectDir, "pnpm-lock.yaml"))) {
|
|
192691
|
-
return "pnpm install --frozen-lockfile";
|
|
192692
|
-
} else if (existsSync22(join23(projectDir, "yarn.lock"))) {
|
|
192693
|
-
return "yarn install --frozen-lockfile";
|
|
192694
|
-
} else if (existsSync22(join23(projectDir, "package-lock.json"))) {
|
|
192695
|
-
return "npm ci";
|
|
192696
|
-
} else if (existsSync22(join23(projectDir, "package.json"))) {
|
|
192697
|
-
return "npm install";
|
|
192698
|
-
}
|
|
192699
|
-
return null;
|
|
192700
|
-
case "python":
|
|
192701
|
-
if (existsSync22(join23(projectDir, "poetry.lock"))) {
|
|
192702
|
-
return "poetry install --no-interaction";
|
|
192703
|
-
} else if (existsSync22(join23(projectDir, "Pipfile.lock"))) {
|
|
192704
|
-
return "pipenv install --deploy";
|
|
192705
|
-
} else if (existsSync22(join23(projectDir, "Pipfile"))) {
|
|
192706
|
-
return "pipenv install";
|
|
192707
|
-
} else if (existsSync22(join23(projectDir, "pyproject.toml"))) {
|
|
192708
|
-
return "pip install .";
|
|
192709
|
-
} else if (existsSync22(join23(projectDir, "requirements.txt"))) {
|
|
192710
|
-
return "pip install -r requirements.txt";
|
|
192711
|
-
}
|
|
192712
|
-
return null;
|
|
192713
|
-
case "go":
|
|
192714
|
-
return "go mod download";
|
|
192715
|
-
case "rust":
|
|
192716
|
-
case "java":
|
|
192717
|
-
return null;
|
|
192718
|
-
default:
|
|
192719
|
-
return null;
|
|
192720
|
-
}
|
|
192721
|
-
}
|
|
192722
|
-
function runCommand2(command, projectDir, buildName) {
|
|
192723
|
-
return new Promise((resolve10) => {
|
|
192724
|
-
const stdout = [];
|
|
192725
|
-
const stderr = [];
|
|
192726
|
-
writeLog("build-test", `[${buildName}] Running: ${command}`);
|
|
192727
|
-
const child = spawn6(command, {
|
|
192728
|
-
shell: true,
|
|
192729
|
-
cwd: projectDir,
|
|
192730
|
-
env: { ...process.env },
|
|
192731
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
192732
|
-
});
|
|
192733
|
-
child.stdout?.on("data", (data) => {
|
|
192734
|
-
const text = data.toString();
|
|
192735
|
-
stdout.push(text);
|
|
192736
|
-
for (const line of text.split("\n")) {
|
|
192737
|
-
if (line.trim()) {
|
|
192738
|
-
writeLog(`build-test:${buildName}`, line);
|
|
192739
|
-
}
|
|
192740
|
-
}
|
|
192741
|
-
});
|
|
192742
|
-
child.stderr?.on("data", (data) => {
|
|
192743
|
-
const text = data.toString();
|
|
192744
|
-
stderr.push(text);
|
|
192745
|
-
for (const line of text.split("\n")) {
|
|
192746
|
-
if (line.trim()) {
|
|
192747
|
-
writeLog(`build-test:${buildName}`, line);
|
|
192748
|
-
}
|
|
192749
|
-
}
|
|
192750
|
-
});
|
|
192751
|
-
child.on("error", (err) => {
|
|
192752
|
-
writeLog("build-test:error", `[${buildName}] Failed to start: ${err.message}`);
|
|
192753
|
-
resolve10({
|
|
192754
|
-
success: false,
|
|
192755
|
-
output: `Failed to start command: ${err.message}`
|
|
192756
|
-
});
|
|
192757
|
-
});
|
|
192758
|
-
child.on("exit", (code) => {
|
|
192759
|
-
const output = [...stdout, ...stderr].join("");
|
|
192760
|
-
if (code === 0) {
|
|
192761
|
-
writeLog("build-test", `[${buildName}] Command succeeded (exit code 0)`);
|
|
192762
|
-
resolve10({ success: true, output });
|
|
192763
|
-
} else {
|
|
192764
|
-
writeLog("build-test:error", `[${buildName}] Command failed with exit code ${code}`);
|
|
192765
|
-
resolve10({
|
|
192766
|
-
success: false,
|
|
192767
|
-
output: output || `Exit code: ${code}`
|
|
192768
|
-
});
|
|
192769
|
-
}
|
|
192770
|
-
});
|
|
192771
|
-
});
|
|
192772
|
-
}
|
|
192773
|
-
async function testBuild(build, projectDir) {
|
|
192774
|
-
const startTime = Date.now();
|
|
192775
|
-
if (build.dockerfile) {
|
|
192776
|
-
writeLog("build-test", `Skipping test for build "${build.name}" (custom Dockerfile)`);
|
|
192777
|
-
return {
|
|
192778
|
-
buildName: build.name,
|
|
192779
|
-
success: true,
|
|
192780
|
-
output: "Skipped: custom Dockerfile build",
|
|
192781
|
-
durationMs: Date.now() - startTime
|
|
192782
|
-
};
|
|
192783
|
-
}
|
|
192784
|
-
const outputs = [];
|
|
192785
|
-
const workDir = build.root ? resolve7(projectDir, build.root) : projectDir;
|
|
192786
|
-
writeLog("build-test", `Starting test for build "${build.name}" (base: ${build.base}, workDir: ${workDir})`);
|
|
192787
|
-
const depsCommand = getDependencyInstallCommand(build, workDir);
|
|
192788
|
-
if (depsCommand) {
|
|
192789
|
-
writeLog("build-test", `[${build.name}] Installing dependencies...`);
|
|
192790
|
-
const depsResult = await runCommand2(depsCommand, workDir, build.name);
|
|
192791
|
-
outputs.push(`[${depsCommand}]
|
|
192792
|
-
${depsResult.output}`);
|
|
192793
|
-
if (!depsResult.success) {
|
|
192794
|
-
const duration2 = Date.now() - startTime;
|
|
192795
|
-
writeLog("build-test:error", `[${build.name}] Dependency installation failed after ${duration2}ms`);
|
|
192796
|
-
return {
|
|
192797
|
-
buildName: build.name,
|
|
192798
|
-
success: false,
|
|
192799
|
-
output: outputs.join("\n\n"),
|
|
192800
|
-
durationMs: duration2
|
|
192801
|
-
};
|
|
192802
|
-
}
|
|
192803
|
-
writeLog("build-test", `[${build.name}] Dependencies installed successfully`);
|
|
192804
|
-
} else {
|
|
192805
|
-
writeLog("build-test", `[${build.name}] No dependency installation needed for base "${build.base}"`);
|
|
192806
|
-
}
|
|
192807
|
-
if (build.command) {
|
|
192808
|
-
writeLog("build-test", `[${build.name}] Running build command...`);
|
|
192809
|
-
const buildResult = await runCommand2(build.command, workDir, build.name);
|
|
192810
|
-
outputs.push(`[${build.command}]
|
|
192811
|
-
${buildResult.output}`);
|
|
192812
|
-
if (!buildResult.success) {
|
|
192813
|
-
const duration2 = Date.now() - startTime;
|
|
192814
|
-
writeLog("build-test:error", `[${build.name}] Build command failed after ${duration2}ms`);
|
|
192815
|
-
return {
|
|
192816
|
-
buildName: build.name,
|
|
192817
|
-
success: false,
|
|
192818
|
-
output: outputs.join("\n\n"),
|
|
192819
|
-
durationMs: duration2
|
|
192820
|
-
};
|
|
192821
|
-
}
|
|
192822
|
-
writeLog("build-test", `[${build.name}] Build command completed successfully`);
|
|
192823
|
-
} else {
|
|
192824
|
-
writeLog("build-test", `[${build.name}] No build command defined, skipping`);
|
|
192825
|
-
}
|
|
192826
|
-
const duration = Date.now() - startTime;
|
|
192827
|
-
writeLog("build-test", `[${build.name}] Build test passed in ${duration}ms`);
|
|
192828
|
-
return {
|
|
192829
|
-
buildName: build.name,
|
|
192830
|
-
success: true,
|
|
192831
|
-
output: outputs.join("\n\n"),
|
|
192832
|
-
durationMs: duration
|
|
192833
|
-
};
|
|
192834
|
-
}
|
|
192835
|
-
async function testAllBuilds(builds, projectDir) {
|
|
192836
|
-
if (builds.length === 0) {
|
|
192837
|
-
writeLog("build-test", "No builds to test");
|
|
192838
|
-
return { results: [], allPassed: true };
|
|
192839
|
-
}
|
|
192840
|
-
writeLog("build-test", `Testing ${builds.length} build(s) in parallel: ${builds.map((b) => b.name).join(", ")}`);
|
|
192841
|
-
writeLog("build-test", `Project directory: ${projectDir}`);
|
|
192842
|
-
const results = await Promise.all(
|
|
192843
|
-
builds.map((build) => testBuild(build, projectDir))
|
|
192844
|
-
);
|
|
192845
|
-
const passed = results.filter((r) => r.success).length;
|
|
192846
|
-
const failed = results.filter((r) => !r.success).length;
|
|
192847
|
-
const totalDuration = results.reduce((sum, r) => sum + r.durationMs, 0);
|
|
192848
|
-
if (failed > 0) {
|
|
192849
|
-
writeLog("build-test:error", `Build tests completed: ${passed} passed, ${failed} failed`);
|
|
192850
|
-
for (const result of results.filter((r) => !r.success)) {
|
|
192851
|
-
writeLog("build-test:error", `Failed build: ${result.buildName}`);
|
|
192852
|
-
}
|
|
192853
|
-
} else {
|
|
192854
|
-
writeLog("build-test", `All ${passed} build(s) passed (total: ${totalDuration}ms)`);
|
|
192855
|
-
}
|
|
192856
|
-
return {
|
|
192857
|
-
results,
|
|
192858
|
-
allPassed: results.every((r) => r.success)
|
|
192859
|
-
};
|
|
192860
|
-
}
|
|
192861
|
-
|
|
192862
192700
|
// src/lib/tarball/create.ts
|
|
192863
192701
|
import { execSync as execSync4 } from "child_process";
|
|
192864
192702
|
import * as fs25 from "fs";
|
|
@@ -192999,7 +192837,6 @@ function PhaseIndicator({
|
|
|
192999
192837
|
showSpinner = true
|
|
193000
192838
|
}) {
|
|
193001
192839
|
const phases = [
|
|
193002
|
-
"testing-builds",
|
|
193003
192840
|
"creating-tarball",
|
|
193004
192841
|
"creating-deployment",
|
|
193005
192842
|
"uploading",
|
|
@@ -193111,7 +192948,7 @@ function formatErrorCode(code) {
|
|
|
193111
192948
|
function StructuredError({ error }) {
|
|
193112
192949
|
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text7, { color: "red", bold: true }, formatErrorCode(error.code), ": ", error.message), error.resource && /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, "Resource: ", error.resource), error.output && /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text7, { bold: true }, "Output:"), /* @__PURE__ */ React7.createElement(Text7, null, error.output)));
|
|
193113
192950
|
}
|
|
193114
|
-
function DeployUI({ environment, config
|
|
192951
|
+
function DeployUI({ environment, config }) {
|
|
193115
192952
|
const { exit } = useApp3();
|
|
193116
192953
|
const [state, setState] = useState6({ phase: "checking-auth" });
|
|
193117
192954
|
const clientRef = React7.useRef(null);
|
|
@@ -193122,7 +192959,7 @@ function DeployUI({ environment, config, skipBuildTest }) {
|
|
|
193122
192959
|
const projectId = readProjectId(projectDir);
|
|
193123
192960
|
if (isLoggedIn()) {
|
|
193124
192961
|
setState({
|
|
193125
|
-
phase: "
|
|
192962
|
+
phase: "creating-tarball",
|
|
193126
192963
|
projectId
|
|
193127
192964
|
});
|
|
193128
192965
|
} else {
|
|
@@ -193179,7 +193016,7 @@ function DeployUI({ environment, config, skipBuildTest }) {
|
|
|
193179
193016
|
const successResponse = response;
|
|
193180
193017
|
await saveCredentialsFromToken(successResponse);
|
|
193181
193018
|
setState(
|
|
193182
|
-
(s) => s.projectId ? { phase: "
|
|
193019
|
+
(s) => s.projectId ? { phase: "creating-tarball", projectId: s.projectId } : { phase: "loading-projects" }
|
|
193183
193020
|
);
|
|
193184
193021
|
}
|
|
193185
193022
|
};
|
|
@@ -193230,7 +193067,7 @@ function DeployUI({ environment, config, skipBuildTest }) {
|
|
|
193230
193067
|
} else {
|
|
193231
193068
|
writeProjectId(project.id);
|
|
193232
193069
|
setState({
|
|
193233
|
-
phase: "
|
|
193070
|
+
phase: "creating-tarball",
|
|
193234
193071
|
projectId: project.id
|
|
193235
193072
|
});
|
|
193236
193073
|
}
|
|
@@ -193253,7 +193090,7 @@ function DeployUI({ environment, config, skipBuildTest }) {
|
|
|
193253
193090
|
if (cancelled) return;
|
|
193254
193091
|
writeProjectId(project.id);
|
|
193255
193092
|
setState({
|
|
193256
|
-
phase: "
|
|
193093
|
+
phase: "creating-tarball",
|
|
193257
193094
|
projectId: project.id
|
|
193258
193095
|
});
|
|
193259
193096
|
} catch (err) {
|
|
@@ -193414,43 +193251,11 @@ function DeployUI({ environment, config, skipBuildTest }) {
|
|
|
193414
193251
|
})();
|
|
193415
193252
|
}, [state]);
|
|
193416
193253
|
useEffect4(() => {
|
|
193417
|
-
if (state.phase !== "
|
|
193254
|
+
if (state.phase !== "creating-tarball" || !state.projectId) return;
|
|
193418
193255
|
let cancelled = false;
|
|
193419
|
-
async function
|
|
193256
|
+
async function runDeploy() {
|
|
193420
193257
|
const projectDir = process.cwd();
|
|
193421
193258
|
const builds = config.builds || [];
|
|
193422
|
-
if (!skipBuildTest && builds.length > 0) {
|
|
193423
|
-
writeLog("deploy", `Testing ${builds.length} build(s) locally`);
|
|
193424
|
-
try {
|
|
193425
|
-
const results = await testAllBuilds(builds, projectDir);
|
|
193426
|
-
if (cancelled) return;
|
|
193427
|
-
if (!results.allPassed) {
|
|
193428
|
-
const failures = results.results.filter((r) => !r.success);
|
|
193429
|
-
const errorMsg = failures.map((f) => `Build "${f.buildName}" failed:
|
|
193430
|
-
${f.output}`).join("\n\n");
|
|
193431
|
-
writeLog("deploy:error", errorMsg);
|
|
193432
|
-
setState({
|
|
193433
|
-
phase: "error",
|
|
193434
|
-
error: `Build test failed:
|
|
193435
|
-
${errorMsg}`
|
|
193436
|
-
});
|
|
193437
|
-
return;
|
|
193438
|
-
}
|
|
193439
|
-
writeLog("deploy", "All builds passed local testing");
|
|
193440
|
-
} catch (err) {
|
|
193441
|
-
if (cancelled) return;
|
|
193442
|
-
const errorMsg = `Build test failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
193443
|
-
writeLog("deploy:error", errorMsg);
|
|
193444
|
-
setState({
|
|
193445
|
-
phase: "error",
|
|
193446
|
-
error: errorMsg
|
|
193447
|
-
});
|
|
193448
|
-
return;
|
|
193449
|
-
}
|
|
193450
|
-
} else {
|
|
193451
|
-
writeLog("deploy", skipBuildTest ? "Skipping build tests (--skip-build-test)" : "No builds to test");
|
|
193452
|
-
}
|
|
193453
|
-
setState((s) => ({ ...s, phase: "creating-tarball" }));
|
|
193454
193259
|
writeLog("deploy", `Starting deployment to "${environment}"`);
|
|
193455
193260
|
writeLog("deploy", `Project directory: ${projectDir}`);
|
|
193456
193261
|
const client2 = new ApiClient();
|
|
@@ -193516,11 +193321,11 @@ ${errorMsg}`
|
|
|
193516
193321
|
writeLog("deploy", "Deployment in pending state, waiting for builds to complete");
|
|
193517
193322
|
setState((s) => ({ ...s, phase: "pending", deployment: deployment2 }));
|
|
193518
193323
|
}
|
|
193519
|
-
|
|
193324
|
+
runDeploy();
|
|
193520
193325
|
return () => {
|
|
193521
193326
|
cancelled = true;
|
|
193522
193327
|
};
|
|
193523
|
-
}, [state.projectId, environment, config.builds
|
|
193328
|
+
}, [state.projectId, environment, config.builds]);
|
|
193524
193329
|
useEffect4(() => {
|
|
193525
193330
|
if (state.phase !== "pending" || !state.deployment) return;
|
|
193526
193331
|
let pollInterval;
|
|
@@ -193714,7 +193519,7 @@ ${errorMsg}`
|
|
|
193714
193519
|
};
|
|
193715
193520
|
}, [state.phase, state.deployment?.id]);
|
|
193716
193521
|
useEffect4(() => {
|
|
193717
|
-
if (state.phase === "
|
|
193522
|
+
if (state.phase === "creating-tarball") {
|
|
193718
193523
|
trackEvent("deploy_started", { environment });
|
|
193719
193524
|
}
|
|
193720
193525
|
}, [state.phase, environment]);
|
|
@@ -193809,13 +193614,6 @@ ${errorMsg}`
|
|
|
193809
193614
|
return "Preparing";
|
|
193810
193615
|
};
|
|
193811
193616
|
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React7.createElement(Text7, null, /* @__PURE__ */ React7.createElement(Text7, { bold: true, color: "cyan" }, "Deploying to ", environment), deployment && /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, " (", deployment.id, ")")), /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column" }, /* @__PURE__ */ React7.createElement(
|
|
193812
|
-
PhaseIndicator,
|
|
193813
|
-
{
|
|
193814
|
-
phase: "testing-builds",
|
|
193815
|
-
currentPhase: displayPhase,
|
|
193816
|
-
label: "Testing builds locally"
|
|
193817
|
-
}
|
|
193818
|
-
), /* @__PURE__ */ React7.createElement(
|
|
193819
193617
|
PhaseIndicator,
|
|
193820
193618
|
{
|
|
193821
193619
|
phase: "creating-tarball",
|
|
@@ -193869,7 +193667,7 @@ ${errorMsg}`
|
|
|
193869
193667
|
}
|
|
193870
193668
|
), phase === "error" && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, deployment?.error ? /* @__PURE__ */ React7.createElement(StructuredError, { error: deployment.error }) : /* @__PURE__ */ React7.createElement(Text7, { color: "red", bold: true }, error), buildOutput && /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text7, { bold: true }, "Build output:"), /* @__PURE__ */ React7.createElement(Text7, null, buildOutput))), phase === "success" && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text7, { color: "green" }, "Deployment successful!"), deployment?.publicUrls && Object.keys(deployment.publicUrls).length > 0 && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text7, { bold: true }, "Public URLs:"), Object.entries(deployment.publicUrls).map(([name, url]) => /* @__PURE__ */ React7.createElement(Text7, { key: name }, " ", name, ": ", /* @__PURE__ */ React7.createElement(Text7, { color: "cyan" }, url))))));
|
|
193871
193669
|
}
|
|
193872
|
-
async function deployCommand(environment
|
|
193670
|
+
async function deployCommand(environment) {
|
|
193873
193671
|
const configPath = path23.join(process.cwd(), "specific.hcl");
|
|
193874
193672
|
if (!fs26.existsSync(configPath)) {
|
|
193875
193673
|
console.error("Error: No specific.hcl found in current directory");
|
|
@@ -193884,21 +193682,19 @@ async function deployCommand(environment, options2) {
|
|
|
193884
193682
|
process.exit(1);
|
|
193885
193683
|
}
|
|
193886
193684
|
const env2 = environment || "prod";
|
|
193887
|
-
const skipBuildTest = options2?.skipBuildTest ?? false;
|
|
193888
193685
|
render5(
|
|
193889
193686
|
/* @__PURE__ */ React7.createElement(
|
|
193890
193687
|
DeployUI,
|
|
193891
193688
|
{
|
|
193892
193689
|
environment: env2,
|
|
193893
|
-
config
|
|
193894
|
-
skipBuildTest
|
|
193690
|
+
config
|
|
193895
193691
|
}
|
|
193896
193692
|
)
|
|
193897
193693
|
);
|
|
193898
193694
|
}
|
|
193899
193695
|
|
|
193900
193696
|
// src/commands/exec.tsx
|
|
193901
|
-
import { spawn as
|
|
193697
|
+
import { spawn as spawn6 } from "child_process";
|
|
193902
193698
|
import * as fs27 from "fs";
|
|
193903
193699
|
import * as path24 from "path";
|
|
193904
193700
|
async function execCommand(serviceName, command, instanceKey = "default") {
|
|
@@ -194059,7 +193855,7 @@ async function execCommand(serviceName, command, instanceKey = "default") {
|
|
|
194059
193855
|
effectiveCwd = path24.resolve(process.cwd(), build.root);
|
|
194060
193856
|
}
|
|
194061
193857
|
}
|
|
194062
|
-
child =
|
|
193858
|
+
child = spawn6(command[0], command.slice(1), {
|
|
194063
193859
|
cwd: effectiveCwd,
|
|
194064
193860
|
env: {
|
|
194065
193861
|
...process.env,
|
|
@@ -194083,7 +193879,7 @@ async function execCommand(serviceName, command, instanceKey = "default") {
|
|
|
194083
193879
|
}
|
|
194084
193880
|
|
|
194085
193881
|
// src/commands/psql.tsx
|
|
194086
|
-
import { spawn as
|
|
193882
|
+
import { spawn as spawn7 } from "child_process";
|
|
194087
193883
|
import * as fs28 from "fs";
|
|
194088
193884
|
import * as path25 from "path";
|
|
194089
193885
|
async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []) {
|
|
@@ -194206,7 +194002,7 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
|
|
|
194206
194002
|
};
|
|
194207
194003
|
process.on("SIGINT", () => handleSignal("SIGINT"));
|
|
194208
194004
|
process.on("SIGTERM", () => handleSignal("SIGTERM"));
|
|
194209
|
-
child =
|
|
194005
|
+
child = spawn7(psqlPath, ["-h", dbState.host, "-p", String(dbState.port), "-U", dbState.user, "-d", dbState.dbName, ...extraArgs], {
|
|
194210
194006
|
cwd: process.cwd(),
|
|
194211
194007
|
env: {
|
|
194212
194008
|
...process.env,
|
|
@@ -194231,7 +194027,7 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
|
|
|
194231
194027
|
}
|
|
194232
194028
|
|
|
194233
194029
|
// src/commands/reshape.tsx
|
|
194234
|
-
import { spawn as
|
|
194030
|
+
import { spawn as spawn8 } from "child_process";
|
|
194235
194031
|
import * as fs29 from "fs";
|
|
194236
194032
|
import * as path26 from "path";
|
|
194237
194033
|
var VALID_ACTIONS = ["start", "complete", "status", "abort", "check"];
|
|
@@ -194409,7 +194205,7 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
|
|
|
194409
194205
|
};
|
|
194410
194206
|
process.on("SIGINT", () => handleSignal("SIGINT"));
|
|
194411
194207
|
process.on("SIGTERM", () => handleSignal("SIGTERM"));
|
|
194412
|
-
child =
|
|
194208
|
+
child = spawn8(reshapePath, reshapeArgs, {
|
|
194413
194209
|
cwd: process.cwd(),
|
|
194414
194210
|
env: {
|
|
194415
194211
|
...process.env,
|
|
@@ -194686,7 +194482,7 @@ function compareVersions(a, b) {
|
|
|
194686
194482
|
return 0;
|
|
194687
194483
|
}
|
|
194688
194484
|
async function checkForUpdate() {
|
|
194689
|
-
const currentVersion = "0.1.
|
|
194485
|
+
const currentVersion = "0.1.74";
|
|
194690
194486
|
const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
|
|
194691
194487
|
if (!response.ok) {
|
|
194692
194488
|
throw new Error(`Failed to check for updates: HTTP ${response.status}`);
|
|
@@ -194736,7 +194532,7 @@ async function performUpdate(version, onProgress) {
|
|
|
194736
194532
|
}
|
|
194737
194533
|
|
|
194738
194534
|
// src/lib/background-update.ts
|
|
194739
|
-
import { spawn as
|
|
194535
|
+
import { spawn as spawn9 } from "child_process";
|
|
194740
194536
|
import * as fs32 from "fs";
|
|
194741
194537
|
import * as path29 from "path";
|
|
194742
194538
|
import * as os10 from "os";
|
|
@@ -194765,7 +194561,7 @@ function maybeStartBackgroundUpdate() {
|
|
|
194765
194561
|
if (process.env.SPECIFIC_BACKGROUND_UPDATE === "1") return;
|
|
194766
194562
|
if (isRateLimited()) return;
|
|
194767
194563
|
if (!isBinaryWritable()) return;
|
|
194768
|
-
const child =
|
|
194564
|
+
const child = spawn9(process.execPath, [], {
|
|
194769
194565
|
detached: true,
|
|
194770
194566
|
stdio: "ignore",
|
|
194771
194567
|
env: {
|
|
@@ -194885,7 +194681,7 @@ function updateCommand() {
|
|
|
194885
194681
|
var program = new Command();
|
|
194886
194682
|
var env = "production";
|
|
194887
194683
|
var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
|
|
194888
|
-
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.
|
|
194684
|
+
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.74").enablePositionalOptions();
|
|
194889
194685
|
program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").action((options2) => initCommand(options2));
|
|
194890
194686
|
program.command("docs [topic]").description("Fetch LLM-optimized documentation").action(docsCommand);
|
|
194891
194687
|
program.command("check").description("Validate specific.hcl configuration").action(checkCommand);
|
|
@@ -194893,8 +194689,8 @@ program.command("dev").description("Start local development environment").option
|
|
|
194893
194689
|
const key = options2.key ?? getDefaultKey();
|
|
194894
194690
|
devCommand(key, options2.tunnel ?? false);
|
|
194895
194691
|
});
|
|
194896
|
-
program.command("deploy [environment]").description("Deploy to Specific infrastructure").
|
|
194897
|
-
deployCommand(environment
|
|
194692
|
+
program.command("deploy [environment]").description("Deploy to Specific infrastructure").action((environment) => {
|
|
194693
|
+
deployCommand(environment);
|
|
194898
194694
|
});
|
|
194899
194695
|
program.command("exec <service> [args...]").description("Run a one-off command with service environment").option("-k, --key <key>", "Dev environment namespace (auto-detected from git worktree if not specified)").passThroughOptions().action(async (service, args, options2) => {
|
|
194900
194696
|
const filteredArgs = args[0] === "--" ? args.slice(1) : args;
|