@specific.dev/cli 0.1.142 → 0.1.146
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 +4 -4
- package/dist/admin/__next.!KGRlZmF1bHQp.txt +7 -7
- package/dist/admin/__next._full.txt +16 -16
- package/dist/admin/__next._head.txt +4 -4
- package/dist/admin/__next._index.txt +6 -6
- package/dist/admin/__next._tree.txt +2 -2
- package/dist/admin/_next/static/chunks/4894dd6189acd52e.js +1 -0
- package/dist/admin/_next/static/chunks/48cbaceebda5df57.js +1 -0
- package/dist/admin/_next/static/chunks/48f1de3af928e439.js +1 -0
- package/dist/admin/_next/static/chunks/63473a6cb811ed42.js +5 -0
- package/dist/admin/_next/static/chunks/6d4c1852135da048.js +5 -0
- package/dist/admin/_next/static/chunks/{a308451471d4cb39.js → 7c2bbd09e9922443.js} +1 -1
- package/dist/admin/_next/static/chunks/7e5c5b91b30c68a0.js +7 -0
- package/dist/admin/_next/static/chunks/9835cc4e14c5aee3.js +1 -0
- package/dist/admin/_next/static/chunks/{00ed768604f00dc4.js → 9fe0755b78ed504a.js} +1 -1
- package/dist/admin/_next/static/chunks/b44581875c51fcd8.js +1 -0
- package/dist/admin/_next/static/chunks/b6749b7e46ea7447.css +4 -0
- package/dist/admin/_next/static/chunks/b69f189d24b42cc4.js +1 -0
- package/dist/admin/_next/static/chunks/c52b2ebc474a0535.js +1 -0
- package/dist/admin/_next/static/chunks/c82a52b3c62e7d18.js +1 -0
- package/dist/admin/_next/static/chunks/dc5c264e3262a84a.js +1 -0
- package/dist/admin/_next/static/chunks/turbopack-2830c15bd3d8f58b.js +4 -0
- package/dist/admin/_not-found/__next._full.txt +11 -11
- package/dist/admin/_not-found/__next._head.txt +4 -4
- package/dist/admin/_not-found/__next._index.txt +6 -6
- package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +2 -2
- package/dist/admin/_not-found/__next._not-found.txt +3 -3
- package/dist/admin/_not-found/__next._tree.txt +2 -2
- package/dist/admin/_not-found/index.html +1 -1
- package/dist/admin/_not-found/index.txt +11 -11
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +4 -4
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +3 -3
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +7 -7
- package/dist/admin/databases/__next._full.txt +16 -16
- package/dist/admin/databases/__next._head.txt +4 -4
- package/dist/admin/databases/__next._index.txt +6 -6
- package/dist/admin/databases/__next._tree.txt +2 -2
- package/dist/admin/databases/index.html +1 -1
- package/dist/admin/databases/index.txt +16 -16
- package/dist/admin/fullscreen/__next._full.txt +12 -12
- package/dist/admin/fullscreen/__next._head.txt +4 -4
- package/dist/admin/fullscreen/__next._index.txt +6 -6
- package/dist/admin/fullscreen/__next._tree.txt +2 -2
- package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +4 -4
- package/dist/admin/fullscreen/__next.fullscreen.txt +3 -3
- package/dist/admin/fullscreen/databases/__next._full.txt +12 -12
- package/dist/admin/fullscreen/databases/__next._head.txt +4 -4
- package/dist/admin/fullscreen/databases/__next._index.txt +6 -6
- package/dist/admin/fullscreen/databases/__next._tree.txt +2 -2
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +4 -4
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +3 -3
- package/dist/admin/fullscreen/databases/__next.fullscreen.txt +3 -3
- package/dist/admin/fullscreen/databases/index.html +1 -1
- package/dist/admin/fullscreen/databases/index.txt +12 -12
- package/dist/admin/fullscreen/index.html +1 -1
- package/dist/admin/fullscreen/index.txt +12 -12
- package/dist/admin/index.html +1 -1
- package/dist/admin/index.txt +16 -16
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +4 -4
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +3 -3
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +7 -7
- package/dist/admin/mail/__next._full.txt +16 -16
- package/dist/admin/mail/__next._head.txt +4 -4
- package/dist/admin/mail/__next._index.txt +6 -6
- package/dist/admin/mail/__next._tree.txt +2 -2
- package/dist/admin/mail/index.html +1 -1
- package/dist/admin/mail/index.txt +16 -16
- package/dist/admin/services/__next.!KGRlZmF1bHQp.services.__PAGE__.txt +4 -4
- package/dist/admin/services/__next.!KGRlZmF1bHQp.services.txt +3 -3
- package/dist/admin/services/__next.!KGRlZmF1bHQp.txt +7 -7
- package/dist/admin/services/__next._full.txt +16 -16
- package/dist/admin/services/__next._head.txt +4 -4
- package/dist/admin/services/__next._index.txt +6 -6
- package/dist/admin/services/__next._tree.txt +2 -2
- package/dist/admin/services/index.html +1 -1
- package/dist/admin/services/index.txt +16 -16
- package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.__PAGE__.txt +9 -0
- package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.txt +4 -0
- package/dist/admin/storage/__next.!KGRlZmF1bHQp.txt +8 -0
- package/dist/admin/storage/__next._full.txt +27 -0
- package/dist/admin/storage/__next._head.txt +6 -0
- package/dist/admin/storage/__next._index.txt +7 -0
- package/dist/admin/storage/__next._tree.txt +5 -0
- package/dist/admin/storage/index.html +1 -0
- package/dist/admin/storage/index.txt +27 -0
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +7 -7
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +4 -4
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +3 -3
- package/dist/admin/workflows/__next._full.txt +16 -16
- package/dist/admin/workflows/__next._head.txt +4 -4
- package/dist/admin/workflows/__next._index.txt +6 -6
- package/dist/admin/workflows/__next._tree.txt +2 -2
- package/dist/admin/workflows/index.html +1 -1
- package/dist/admin/workflows/index.txt +16 -16
- package/dist/cli.js +515 -24
- package/dist/docs/redis.md +1 -1
- package/package.json +2 -1
- package/dist/admin/_next/static/chunks/051b91c534cf9f23.js +0 -1
- package/dist/admin/_next/static/chunks/05dca3efccd1ccf3.js +0 -1
- package/dist/admin/_next/static/chunks/1437c65d19a610ec.js +0 -5
- package/dist/admin/_next/static/chunks/16e0c1b704eededd.js +0 -2
- package/dist/admin/_next/static/chunks/4bd3607000957431.js +0 -1
- package/dist/admin/_next/static/chunks/5953d56a33f0b7ea.js +0 -4
- package/dist/admin/_next/static/chunks/65ce370ab86b6df6.js +0 -1
- package/dist/admin/_next/static/chunks/99a055acecd950e9.js +0 -1
- package/dist/admin/_next/static/chunks/a088825647b58cc9.css +0 -4
- package/dist/admin/_next/static/chunks/ab7b22d870fdc67c.js +0 -1
- package/dist/admin/_next/static/chunks/b42765249c4a529a.js +0 -1
- package/dist/admin/_next/static/chunks/db49f609ddd8888b.js +0 -1
- package/dist/admin/_next/static/chunks/turbopack-ea5c59f39d53507e.js +0 -4
- /package/dist/admin/_next/static/{0m_Df0WwF7T1e25BA6Bff → g6SjZi_LuWK7FrmmMr5PE}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{0m_Df0WwF7T1e25BA6Bff → g6SjZi_LuWK7FrmmMr5PE}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{0m_Df0WwF7T1e25BA6Bff → g6SjZi_LuWK7FrmmMr5PE}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -185198,6 +185198,16 @@ import * as http from "http";
|
|
|
185198
185198
|
import * as fs7 from "fs";
|
|
185199
185199
|
import * as path7 from "path";
|
|
185200
185200
|
import { fileURLToPath } from "url";
|
|
185201
|
+
import {
|
|
185202
|
+
CopyObjectCommand,
|
|
185203
|
+
DeleteObjectCommand,
|
|
185204
|
+
DeleteObjectsCommand,
|
|
185205
|
+
GetObjectCommand,
|
|
185206
|
+
HeadObjectCommand,
|
|
185207
|
+
ListObjectsV2Command,
|
|
185208
|
+
PutObjectCommand,
|
|
185209
|
+
S3Client
|
|
185210
|
+
} from "@aws-sdk/client-s3";
|
|
185201
185211
|
import * as net3 from "net";
|
|
185202
185212
|
import * as fs8 from "fs";
|
|
185203
185213
|
import * as path9 from "path";
|
|
@@ -369113,9 +369123,9 @@ var postgresBinary = {
|
|
|
369113
369123
|
};
|
|
369114
369124
|
var redisBinary = {
|
|
369115
369125
|
name: "redis",
|
|
369116
|
-
versions: ["8.
|
|
369126
|
+
versions: ["8.1.7"],
|
|
369117
369127
|
// URL: binaries.specific.dev/{SOFTWARE}/{VERSION}/{ARCH}.tar.gz
|
|
369118
|
-
urlTemplate: "https://binaries.specific.dev/
|
|
369128
|
+
urlTemplate: "https://binaries.specific.dev/valkey/{version}/{arch}.tar.gz",
|
|
369119
369129
|
platformMapping: {
|
|
369120
369130
|
darwin: {
|
|
369121
369131
|
arm64: { platform: "macos", arch: "macos_arm" },
|
|
@@ -369128,8 +369138,7 @@ var redisBinary = {
|
|
|
369128
369138
|
},
|
|
369129
369139
|
// Binaries are at the root of the archive
|
|
369130
369140
|
stripComponents: 0,
|
|
369131
|
-
|
|
369132
|
-
executables: ["redis-server"]
|
|
369141
|
+
executables: ["valkey-server"]
|
|
369133
369142
|
};
|
|
369134
369143
|
var electricBinary = {
|
|
369135
369144
|
name: "electric",
|
|
@@ -369449,16 +369458,35 @@ async function startPostgres(pg, port, dataDir, onProgress) {
|
|
|
369449
369458
|
}
|
|
369450
369459
|
};
|
|
369451
369460
|
}
|
|
369452
|
-
async function startRedis(redis, port, onProgress) {
|
|
369461
|
+
async function startRedis(redis, port, dataDir, onProgress) {
|
|
369453
369462
|
const binary = await ensureBinary(redisBinary, void 0, onProgress);
|
|
369454
369463
|
const host = "127.0.0.1";
|
|
369464
|
+
const redisDataPath = path5.join(process.cwd(), dataDir, "redis", redis.name);
|
|
369465
|
+
fs5.mkdirSync(redisDataPath, { recursive: true });
|
|
369466
|
+
const stalePath = path5.join(redisDataPath, "dump.rdb");
|
|
369467
|
+
if (fs5.existsSync(stalePath)) {
|
|
369468
|
+
fs5.rmSync(stalePath, { force: true });
|
|
369469
|
+
}
|
|
369455
369470
|
if (await isPortInUse(host, port)) {
|
|
369456
369471
|
await reclaimSpecificOrphanOnPort(port);
|
|
369457
369472
|
await waitForPortFree(host, port, 1e3);
|
|
369458
369473
|
}
|
|
369459
369474
|
const redisProc = spawn(
|
|
369460
|
-
binary.executables["
|
|
369461
|
-
[
|
|
369475
|
+
binary.executables["valkey-server"],
|
|
369476
|
+
[
|
|
369477
|
+
"--port",
|
|
369478
|
+
String(port),
|
|
369479
|
+
"--bind",
|
|
369480
|
+
host,
|
|
369481
|
+
"--daemonize",
|
|
369482
|
+
"no",
|
|
369483
|
+
"--dir",
|
|
369484
|
+
redisDataPath,
|
|
369485
|
+
"--save",
|
|
369486
|
+
"",
|
|
369487
|
+
"--appendonly",
|
|
369488
|
+
"no"
|
|
369489
|
+
],
|
|
369462
369490
|
{
|
|
369463
369491
|
stdio: ["ignore", "pipe", "pipe"],
|
|
369464
369492
|
detached: true
|
|
@@ -370448,6 +370476,417 @@ function killTrackedProcess(pid, detached, isProcessRunning) {
|
|
|
370448
370476
|
} catch {
|
|
370449
370477
|
}
|
|
370450
370478
|
}
|
|
370479
|
+
var MAX_KEY_LENGTH = 1024;
|
|
370480
|
+
var PROXY_URL_EXPIRES_IN = 3600;
|
|
370481
|
+
function validateKey(key) {
|
|
370482
|
+
if (!key || key.length > MAX_KEY_LENGTH) return "Invalid key length";
|
|
370483
|
+
if (key.includes("..")) return "Key must not contain '..'";
|
|
370484
|
+
if (key.includes("\0")) return "Key must not contain null bytes";
|
|
370485
|
+
if (key.startsWith("/")) return "Key must not start with '/'";
|
|
370486
|
+
return null;
|
|
370487
|
+
}
|
|
370488
|
+
var clientCache = /* @__PURE__ */ new Map();
|
|
370489
|
+
function getClient(info) {
|
|
370490
|
+
const cacheKey = `${info.host}:${info.port}:${info.accessKey}`;
|
|
370491
|
+
const cached2 = clientCache.get(cacheKey);
|
|
370492
|
+
if (cached2) return cached2;
|
|
370493
|
+
const client2 = new S3Client({
|
|
370494
|
+
endpoint: `http://${info.host}:${info.port}`,
|
|
370495
|
+
region: "us-east-1",
|
|
370496
|
+
credentials: {
|
|
370497
|
+
accessKeyId: info.accessKey,
|
|
370498
|
+
secretAccessKey: info.secretKey
|
|
370499
|
+
},
|
|
370500
|
+
forcePathStyle: true
|
|
370501
|
+
});
|
|
370502
|
+
clientCache.set(cacheKey, client2);
|
|
370503
|
+
return client2;
|
|
370504
|
+
}
|
|
370505
|
+
function sendJson(res, status, body) {
|
|
370506
|
+
res.setHeader("Content-Type", "application/json");
|
|
370507
|
+
res.writeHead(status);
|
|
370508
|
+
res.end(JSON.stringify(body));
|
|
370509
|
+
}
|
|
370510
|
+
function sendError(res, status, message) {
|
|
370511
|
+
sendJson(res, status, { error: message });
|
|
370512
|
+
}
|
|
370513
|
+
async function readJsonBody(req) {
|
|
370514
|
+
const chunks = [];
|
|
370515
|
+
for await (const chunk of req) {
|
|
370516
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
370517
|
+
}
|
|
370518
|
+
const text = Buffer.concat(chunks).toString("utf8");
|
|
370519
|
+
return text.length > 0 ? JSON.parse(text) : {};
|
|
370520
|
+
}
|
|
370521
|
+
async function handleListObjects(client2, bucket, url, res) {
|
|
370522
|
+
const prefix = url.searchParams.get("prefix") ?? "";
|
|
370523
|
+
const cursor = url.searchParams.get("cursor") ?? void 0;
|
|
370524
|
+
const maxKeys = Math.min(
|
|
370525
|
+
Math.max(parseInt(url.searchParams.get("maxKeys") ?? "100", 10) || 100, 1),
|
|
370526
|
+
1e3
|
|
370527
|
+
);
|
|
370528
|
+
const response = await client2.send(
|
|
370529
|
+
new ListObjectsV2Command({
|
|
370530
|
+
Bucket: bucket,
|
|
370531
|
+
Prefix: prefix,
|
|
370532
|
+
Delimiter: "/",
|
|
370533
|
+
MaxKeys: maxKeys,
|
|
370534
|
+
ContinuationToken: cursor || void 0
|
|
370535
|
+
})
|
|
370536
|
+
);
|
|
370537
|
+
sendJson(res, 200, {
|
|
370538
|
+
objects: (response.Contents ?? []).map((obj) => ({
|
|
370539
|
+
key: obj.Key,
|
|
370540
|
+
size: obj.Size ?? 0,
|
|
370541
|
+
lastModified: obj.LastModified?.toISOString() ?? "",
|
|
370542
|
+
etag: obj.ETag
|
|
370543
|
+
})),
|
|
370544
|
+
prefixes: (response.CommonPrefixes ?? []).map((p) => p.Prefix),
|
|
370545
|
+
nextCursor: response.NextContinuationToken ?? null,
|
|
370546
|
+
prefix
|
|
370547
|
+
});
|
|
370548
|
+
}
|
|
370549
|
+
async function handleMetrics(client2, bucket, res) {
|
|
370550
|
+
let totalObjects = 0;
|
|
370551
|
+
let totalSize = 0;
|
|
370552
|
+
let continuationToken;
|
|
370553
|
+
let pages = 0;
|
|
370554
|
+
const MAX_PAGES = 100;
|
|
370555
|
+
do {
|
|
370556
|
+
const response = await client2.send(
|
|
370557
|
+
new ListObjectsV2Command({
|
|
370558
|
+
Bucket: bucket,
|
|
370559
|
+
ContinuationToken: continuationToken
|
|
370560
|
+
})
|
|
370561
|
+
);
|
|
370562
|
+
totalObjects += response.KeyCount ?? 0;
|
|
370563
|
+
for (const obj of response.Contents ?? []) {
|
|
370564
|
+
totalSize += obj.Size ?? 0;
|
|
370565
|
+
}
|
|
370566
|
+
continuationToken = response.NextContinuationToken;
|
|
370567
|
+
pages++;
|
|
370568
|
+
} while (continuationToken && pages < MAX_PAGES);
|
|
370569
|
+
sendJson(res, 200, {
|
|
370570
|
+
totalObjects,
|
|
370571
|
+
totalSize,
|
|
370572
|
+
bucketName: bucket,
|
|
370573
|
+
...pages >= MAX_PAGES ? { truncated: true } : {}
|
|
370574
|
+
});
|
|
370575
|
+
}
|
|
370576
|
+
async function handleGetObject(client2, bucket, key, res) {
|
|
370577
|
+
try {
|
|
370578
|
+
const response = await client2.send(
|
|
370579
|
+
new HeadObjectCommand({ Bucket: bucket, Key: key })
|
|
370580
|
+
);
|
|
370581
|
+
sendJson(res, 200, {
|
|
370582
|
+
key,
|
|
370583
|
+
size: response.ContentLength ?? 0,
|
|
370584
|
+
lastModified: response.LastModified?.toISOString(),
|
|
370585
|
+
contentType: response.ContentType,
|
|
370586
|
+
etag: response.ETag,
|
|
370587
|
+
metadata: response.Metadata
|
|
370588
|
+
});
|
|
370589
|
+
} catch (error) {
|
|
370590
|
+
const name = error.name;
|
|
370591
|
+
if (name === "NotFound" || name === "NoSuchKey") {
|
|
370592
|
+
sendError(res, 404, `Object '${key}' not found`);
|
|
370593
|
+
return;
|
|
370594
|
+
}
|
|
370595
|
+
throw error;
|
|
370596
|
+
}
|
|
370597
|
+
}
|
|
370598
|
+
async function handleDeleteObject(client2, bucket, key, res) {
|
|
370599
|
+
if (key.endsWith("/")) {
|
|
370600
|
+
const allKeys = [];
|
|
370601
|
+
let continuationToken;
|
|
370602
|
+
do {
|
|
370603
|
+
const listResponse = await client2.send(
|
|
370604
|
+
new ListObjectsV2Command({
|
|
370605
|
+
Bucket: bucket,
|
|
370606
|
+
Prefix: key,
|
|
370607
|
+
ContinuationToken: continuationToken
|
|
370608
|
+
})
|
|
370609
|
+
);
|
|
370610
|
+
for (const obj of listResponse.Contents ?? []) {
|
|
370611
|
+
if (obj.Key) allKeys.push(obj.Key);
|
|
370612
|
+
}
|
|
370613
|
+
continuationToken = listResponse.NextContinuationToken;
|
|
370614
|
+
} while (continuationToken);
|
|
370615
|
+
const batches = [];
|
|
370616
|
+
for (let i = 0; i < allKeys.length; i += 1e3) {
|
|
370617
|
+
batches.push(
|
|
370618
|
+
client2.send(
|
|
370619
|
+
new DeleteObjectsCommand({
|
|
370620
|
+
Bucket: bucket,
|
|
370621
|
+
Delete: {
|
|
370622
|
+
Objects: allKeys.slice(i, i + 1e3).map((k) => ({ Key: k })),
|
|
370623
|
+
Quiet: true
|
|
370624
|
+
}
|
|
370625
|
+
})
|
|
370626
|
+
)
|
|
370627
|
+
);
|
|
370628
|
+
}
|
|
370629
|
+
await Promise.all(batches);
|
|
370630
|
+
} else {
|
|
370631
|
+
await client2.send(new DeleteObjectCommand({ Bucket: bucket, Key: key }));
|
|
370632
|
+
}
|
|
370633
|
+
sendJson(res, 200, { success: true });
|
|
370634
|
+
}
|
|
370635
|
+
async function handleCreateFolder(client2, bucket, body, res) {
|
|
370636
|
+
const path172 = body.path;
|
|
370637
|
+
if (typeof path172 !== "string") {
|
|
370638
|
+
sendError(res, 400, "Missing path");
|
|
370639
|
+
return;
|
|
370640
|
+
}
|
|
370641
|
+
const folderKey = path172.endsWith("/") ? path172 : `${path172}/`;
|
|
370642
|
+
const keyError = validateKey(folderKey);
|
|
370643
|
+
if (keyError) {
|
|
370644
|
+
sendError(res, 400, keyError);
|
|
370645
|
+
return;
|
|
370646
|
+
}
|
|
370647
|
+
await client2.send(
|
|
370648
|
+
new PutObjectCommand({ Bucket: bucket, Key: folderKey, Body: "" })
|
|
370649
|
+
);
|
|
370650
|
+
sendJson(res, 200, { key: folderKey });
|
|
370651
|
+
}
|
|
370652
|
+
async function handleRename(client2, bucket, body, res) {
|
|
370653
|
+
const { sourceKey, destinationKey } = body;
|
|
370654
|
+
if (typeof sourceKey !== "string" || typeof destinationKey !== "string") {
|
|
370655
|
+
sendError(res, 400, "Missing sourceKey or destinationKey");
|
|
370656
|
+
return;
|
|
370657
|
+
}
|
|
370658
|
+
for (const k of [sourceKey, destinationKey]) {
|
|
370659
|
+
const err = validateKey(k);
|
|
370660
|
+
if (err) {
|
|
370661
|
+
sendError(res, 400, err);
|
|
370662
|
+
return;
|
|
370663
|
+
}
|
|
370664
|
+
}
|
|
370665
|
+
if (sourceKey.endsWith("/")) {
|
|
370666
|
+
const allKeys = [];
|
|
370667
|
+
let continuationToken;
|
|
370668
|
+
do {
|
|
370669
|
+
const listResponse = await client2.send(
|
|
370670
|
+
new ListObjectsV2Command({
|
|
370671
|
+
Bucket: bucket,
|
|
370672
|
+
Prefix: sourceKey,
|
|
370673
|
+
ContinuationToken: continuationToken
|
|
370674
|
+
})
|
|
370675
|
+
);
|
|
370676
|
+
for (const obj of listResponse.Contents ?? []) {
|
|
370677
|
+
if (obj.Key) allKeys.push(obj.Key);
|
|
370678
|
+
}
|
|
370679
|
+
continuationToken = listResponse.NextContinuationToken;
|
|
370680
|
+
} while (continuationToken);
|
|
370681
|
+
if (allKeys.length === 0) {
|
|
370682
|
+
sendError(res, 404, "Folder is empty or does not exist");
|
|
370683
|
+
return;
|
|
370684
|
+
}
|
|
370685
|
+
await Promise.all(
|
|
370686
|
+
allKeys.map(
|
|
370687
|
+
(k) => client2.send(
|
|
370688
|
+
new CopyObjectCommand({
|
|
370689
|
+
Bucket: bucket,
|
|
370690
|
+
CopySource: `${bucket}/${encodeURI(k)}`,
|
|
370691
|
+
Key: destinationKey + k.slice(sourceKey.length)
|
|
370692
|
+
})
|
|
370693
|
+
)
|
|
370694
|
+
)
|
|
370695
|
+
);
|
|
370696
|
+
const deleteBatches = [];
|
|
370697
|
+
for (let i = 0; i < allKeys.length; i += 1e3) {
|
|
370698
|
+
deleteBatches.push(
|
|
370699
|
+
client2.send(
|
|
370700
|
+
new DeleteObjectsCommand({
|
|
370701
|
+
Bucket: bucket,
|
|
370702
|
+
Delete: {
|
|
370703
|
+
Objects: allKeys.slice(i, i + 1e3).map((k) => ({ Key: k })),
|
|
370704
|
+
Quiet: true
|
|
370705
|
+
}
|
|
370706
|
+
})
|
|
370707
|
+
)
|
|
370708
|
+
);
|
|
370709
|
+
}
|
|
370710
|
+
await Promise.all(deleteBatches);
|
|
370711
|
+
} else {
|
|
370712
|
+
await client2.send(
|
|
370713
|
+
new CopyObjectCommand({
|
|
370714
|
+
Bucket: bucket,
|
|
370715
|
+
CopySource: `${bucket}/${encodeURI(sourceKey)}`,
|
|
370716
|
+
Key: destinationKey
|
|
370717
|
+
})
|
|
370718
|
+
);
|
|
370719
|
+
await client2.send(
|
|
370720
|
+
new DeleteObjectCommand({ Bucket: bucket, Key: sourceKey })
|
|
370721
|
+
);
|
|
370722
|
+
}
|
|
370723
|
+
sendJson(res, 200, { key: destinationKey });
|
|
370724
|
+
}
|
|
370725
|
+
async function handleUploadData(client2, bucket, key, req, res) {
|
|
370726
|
+
const chunks = [];
|
|
370727
|
+
for await (const chunk of req) {
|
|
370728
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
370729
|
+
}
|
|
370730
|
+
const body = Buffer.concat(chunks);
|
|
370731
|
+
const contentType = req.headers["content-type"];
|
|
370732
|
+
await client2.send(
|
|
370733
|
+
new PutObjectCommand({
|
|
370734
|
+
Bucket: bucket,
|
|
370735
|
+
Key: key,
|
|
370736
|
+
Body: body,
|
|
370737
|
+
ContentType: typeof contentType === "string" ? contentType : void 0
|
|
370738
|
+
})
|
|
370739
|
+
);
|
|
370740
|
+
res.writeHead(200);
|
|
370741
|
+
res.end();
|
|
370742
|
+
}
|
|
370743
|
+
async function handleDownloadData(client2, bucket, key, res) {
|
|
370744
|
+
try {
|
|
370745
|
+
const response = await client2.send(
|
|
370746
|
+
new GetObjectCommand({ Bucket: bucket, Key: key })
|
|
370747
|
+
);
|
|
370748
|
+
if (response.ContentType) {
|
|
370749
|
+
res.setHeader("Content-Type", response.ContentType);
|
|
370750
|
+
}
|
|
370751
|
+
if (response.ContentLength !== void 0) {
|
|
370752
|
+
res.setHeader("Content-Length", String(response.ContentLength));
|
|
370753
|
+
}
|
|
370754
|
+
res.writeHead(200);
|
|
370755
|
+
const body = response.Body;
|
|
370756
|
+
if (!body) {
|
|
370757
|
+
res.end();
|
|
370758
|
+
return;
|
|
370759
|
+
}
|
|
370760
|
+
if (typeof body.pipe === "function") {
|
|
370761
|
+
body.pipe(res);
|
|
370762
|
+
} else {
|
|
370763
|
+
const stream = body.transformToWebStream();
|
|
370764
|
+
const reader = stream.getReader();
|
|
370765
|
+
while (true) {
|
|
370766
|
+
const { done, value } = await reader.read();
|
|
370767
|
+
if (done) break;
|
|
370768
|
+
if (value) res.write(Buffer.from(value));
|
|
370769
|
+
}
|
|
370770
|
+
res.end();
|
|
370771
|
+
}
|
|
370772
|
+
} catch (error) {
|
|
370773
|
+
const name = error.name;
|
|
370774
|
+
if (name === "NotFound" || name === "NoSuchKey") {
|
|
370775
|
+
if (!res.headersSent) {
|
|
370776
|
+
sendError(res, 404, `Object '${key}' not found`);
|
|
370777
|
+
} else {
|
|
370778
|
+
res.end();
|
|
370779
|
+
}
|
|
370780
|
+
return;
|
|
370781
|
+
}
|
|
370782
|
+
throw error;
|
|
370783
|
+
}
|
|
370784
|
+
}
|
|
370785
|
+
function handlePresigned(storageName, body, res) {
|
|
370786
|
+
const { key, action, expiresIn } = body;
|
|
370787
|
+
if (typeof key !== "string" || action !== "upload" && action !== "download") {
|
|
370788
|
+
sendError(res, 400, "Missing key or invalid action");
|
|
370789
|
+
return;
|
|
370790
|
+
}
|
|
370791
|
+
const keyError = validateKey(key);
|
|
370792
|
+
if (keyError) {
|
|
370793
|
+
sendError(res, 400, keyError);
|
|
370794
|
+
return;
|
|
370795
|
+
}
|
|
370796
|
+
const url = `/api/storage/${encodeURIComponent(storageName)}/data?key=${encodeURIComponent(key)}`;
|
|
370797
|
+
sendJson(res, 200, {
|
|
370798
|
+
url,
|
|
370799
|
+
expiresIn: typeof expiresIn === "number" ? expiresIn : PROXY_URL_EXPIRES_IN
|
|
370800
|
+
});
|
|
370801
|
+
}
|
|
370802
|
+
async function handleStorageRequest(req, res, pathname, url, getStorageInstance) {
|
|
370803
|
+
const match = /^\/api\/storage\/([^/]+)(\/.*)?$/.exec(pathname);
|
|
370804
|
+
if (!match) return false;
|
|
370805
|
+
const storageName = decodeURIComponent(match[1]);
|
|
370806
|
+
const sub = match[2] ?? "";
|
|
370807
|
+
const info = getStorageInstance(storageName);
|
|
370808
|
+
if (!info) {
|
|
370809
|
+
sendError(res, 404, `Storage '${storageName}' not found`);
|
|
370810
|
+
return true;
|
|
370811
|
+
}
|
|
370812
|
+
const client2 = getClient(info);
|
|
370813
|
+
const bucket = info.bucket;
|
|
370814
|
+
try {
|
|
370815
|
+
if (sub === "/objects" && req.method === "GET") {
|
|
370816
|
+
await handleListObjects(client2, bucket, url, res);
|
|
370817
|
+
return true;
|
|
370818
|
+
}
|
|
370819
|
+
if (sub === "/metrics" && req.method === "GET") {
|
|
370820
|
+
await handleMetrics(client2, bucket, res);
|
|
370821
|
+
return true;
|
|
370822
|
+
}
|
|
370823
|
+
if (sub === "/object") {
|
|
370824
|
+
const key = url.searchParams.get("key");
|
|
370825
|
+
if (!key) {
|
|
370826
|
+
sendError(res, 400, "Missing key");
|
|
370827
|
+
return true;
|
|
370828
|
+
}
|
|
370829
|
+
const keyError = validateKey(key);
|
|
370830
|
+
if (keyError) {
|
|
370831
|
+
sendError(res, 400, keyError);
|
|
370832
|
+
return true;
|
|
370833
|
+
}
|
|
370834
|
+
if (req.method === "GET") {
|
|
370835
|
+
await handleGetObject(client2, bucket, key, res);
|
|
370836
|
+
return true;
|
|
370837
|
+
}
|
|
370838
|
+
if (req.method === "DELETE") {
|
|
370839
|
+
await handleDeleteObject(client2, bucket, key, res);
|
|
370840
|
+
return true;
|
|
370841
|
+
}
|
|
370842
|
+
}
|
|
370843
|
+
if (sub === "/data") {
|
|
370844
|
+
const key = url.searchParams.get("key");
|
|
370845
|
+
if (!key) {
|
|
370846
|
+
sendError(res, 400, "Missing key");
|
|
370847
|
+
return true;
|
|
370848
|
+
}
|
|
370849
|
+
const keyError = validateKey(key);
|
|
370850
|
+
if (keyError) {
|
|
370851
|
+
sendError(res, 400, keyError);
|
|
370852
|
+
return true;
|
|
370853
|
+
}
|
|
370854
|
+
if (req.method === "PUT") {
|
|
370855
|
+
await handleUploadData(client2, bucket, key, req, res);
|
|
370856
|
+
return true;
|
|
370857
|
+
}
|
|
370858
|
+
if (req.method === "GET") {
|
|
370859
|
+
await handleDownloadData(client2, bucket, key, res);
|
|
370860
|
+
return true;
|
|
370861
|
+
}
|
|
370862
|
+
}
|
|
370863
|
+
if (sub === "/folder" && req.method === "POST") {
|
|
370864
|
+
const body = await readJsonBody(req);
|
|
370865
|
+
await handleCreateFolder(client2, bucket, body, res);
|
|
370866
|
+
return true;
|
|
370867
|
+
}
|
|
370868
|
+
if (sub === "/rename" && req.method === "POST") {
|
|
370869
|
+
const body = await readJsonBody(req);
|
|
370870
|
+
await handleRename(client2, bucket, body, res);
|
|
370871
|
+
return true;
|
|
370872
|
+
}
|
|
370873
|
+
if (sub === "/presigned" && req.method === "POST") {
|
|
370874
|
+
const body = await readJsonBody(req);
|
|
370875
|
+
handlePresigned(storageName, body, res);
|
|
370876
|
+
return true;
|
|
370877
|
+
}
|
|
370878
|
+
sendError(res, 404, "Not found");
|
|
370879
|
+
return true;
|
|
370880
|
+
} catch (error) {
|
|
370881
|
+
writeLog("admin:storage", `Storage handler error: ${error}`);
|
|
370882
|
+
if (!res.headersSent) {
|
|
370883
|
+
sendError(res, 500, error instanceof Error ? error.message : "Internal error");
|
|
370884
|
+
} else {
|
|
370885
|
+
res.end();
|
|
370886
|
+
}
|
|
370887
|
+
return true;
|
|
370888
|
+
}
|
|
370889
|
+
}
|
|
370451
370890
|
var __dirname = path7.dirname(fileURLToPath(import.meta.url));
|
|
370452
370891
|
var adminDir = path7.join(__dirname, "admin");
|
|
370453
370892
|
var _embeddedAdmin = null;
|
|
@@ -370515,6 +370954,19 @@ function serveEmbeddedFile(res, pathname) {
|
|
|
370515
370954
|
res.end(content);
|
|
370516
370955
|
return;
|
|
370517
370956
|
}
|
|
370957
|
+
if (!path7.extname(relativePath)) {
|
|
370958
|
+
const parts = relativePath.split("/").filter(Boolean);
|
|
370959
|
+
while (parts.length > 0) {
|
|
370960
|
+
parts.pop();
|
|
370961
|
+
const candidate = parts.length === 0 ? "index.html" : parts.join("/") + "/index.html";
|
|
370962
|
+
const fallback = _embeddedAdmin.get(candidate);
|
|
370963
|
+
if (fallback) {
|
|
370964
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
370965
|
+
res.end(fallback);
|
|
370966
|
+
return;
|
|
370967
|
+
}
|
|
370968
|
+
}
|
|
370969
|
+
}
|
|
370518
370970
|
const notFound = _embeddedAdmin.get("404.html");
|
|
370519
370971
|
if (notFound) {
|
|
370520
370972
|
res.writeHead(404, { "Content-Type": "text/html" });
|
|
@@ -370556,6 +371008,20 @@ function serveFilesystemFile(res, pathname) {
|
|
|
370556
371008
|
if (fs7.existsSync(indexPath)) {
|
|
370557
371009
|
return serveFile(res, indexPath);
|
|
370558
371010
|
}
|
|
371011
|
+
if (!path7.extname(relativePath)) {
|
|
371012
|
+
let dir = path7.dirname(resolvedPath);
|
|
371013
|
+
while (dir.startsWith(resolvedAdminDir) && dir !== resolvedAdminDir) {
|
|
371014
|
+
const fallback = path7.join(dir, "index.html");
|
|
371015
|
+
if (fs7.existsSync(fallback)) {
|
|
371016
|
+
return serveFile(res, fallback);
|
|
371017
|
+
}
|
|
371018
|
+
dir = path7.dirname(dir);
|
|
371019
|
+
}
|
|
371020
|
+
const rootIndex = path7.join(resolvedAdminDir, "index.html");
|
|
371021
|
+
if (fs7.existsSync(rootIndex)) {
|
|
371022
|
+
return serveFile(res, rootIndex);
|
|
371023
|
+
}
|
|
371024
|
+
}
|
|
370559
371025
|
const notFoundPath = path7.join(adminDir, "404.html");
|
|
370560
371026
|
if (fs7.existsSync(notFoundPath)) {
|
|
370561
371027
|
return serveFileContent(res, notFoundPath, "text/html", 404);
|
|
@@ -370609,12 +371075,15 @@ function proxyRequest(req, res, targetPort) {
|
|
|
370609
371075
|
});
|
|
370610
371076
|
req.pipe(proxyReq, { end: true });
|
|
370611
371077
|
}
|
|
370612
|
-
async function startAdminServer(getState, listenPort = 0, getLogsDir = () => null) {
|
|
371078
|
+
async function startAdminServer(getState, listenPort = 0, getLogsDir = () => null, getStorageInstance = () => void 0) {
|
|
370613
371079
|
return new Promise((resolve62, reject) => {
|
|
370614
371080
|
const server = http.createServer((req, res) => {
|
|
370615
371081
|
const url = new URL(req.url || "/", "http://localhost");
|
|
370616
371082
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
370617
|
-
res.setHeader(
|
|
371083
|
+
res.setHeader(
|
|
371084
|
+
"Access-Control-Allow-Methods",
|
|
371085
|
+
"GET, POST, PUT, DELETE, OPTIONS"
|
|
371086
|
+
);
|
|
370618
371087
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
370619
371088
|
if (req.method === "OPTIONS") {
|
|
370620
371089
|
res.writeHead(204);
|
|
@@ -370688,6 +371157,10 @@ async function startAdminServer(getState, listenPort = 0, getLogsDir = () => nul
|
|
|
370688
371157
|
res.end(JSON.stringify(body));
|
|
370689
371158
|
return;
|
|
370690
371159
|
}
|
|
371160
|
+
if (pathname.startsWith("/api/storage/")) {
|
|
371161
|
+
void handleStorageRequest(req, res, pathname, url, getStorageInstance);
|
|
371162
|
+
return;
|
|
371163
|
+
}
|
|
370691
371164
|
if (pathname.startsWith("/temporal-ui")) {
|
|
370692
371165
|
const state = getState();
|
|
370693
371166
|
if (state.temporalUiPort) {
|
|
@@ -371686,7 +372159,7 @@ async function startResources(options2) {
|
|
|
371686
372159
|
const port = portAllocator.allocate(`redis:${redis.name}`);
|
|
371687
372160
|
log(`Starting redis "${redis.name}" on port ${port}`);
|
|
371688
372161
|
callbacks.onResourceStarting?.(redis.name, "redis");
|
|
371689
|
-
const instance = await startRedis(redis, port, (progress) => {
|
|
372162
|
+
const instance = await startRedis(redis, port, dataDir, (progress) => {
|
|
371690
372163
|
callbacks.onResourceProgress?.(redis.name, progress);
|
|
371691
372164
|
});
|
|
371692
372165
|
resources.set(redis.name, instance);
|
|
@@ -373315,7 +373788,20 @@ Add them to the config block in specific.local`
|
|
|
373315
373788
|
const adminServer = await startAdminServer(
|
|
373316
373789
|
getState,
|
|
373317
373790
|
adminPort,
|
|
373318
|
-
() => this.serviceLogFiles?.logsDir ?? null
|
|
373791
|
+
() => this.serviceLogFiles?.logsDir ?? null,
|
|
373792
|
+
(name) => {
|
|
373793
|
+
const r = this.resources.get(name);
|
|
373794
|
+
if (!r || r.type !== "storage" || !r.bucket || !r.accessKey || !r.secretKey) {
|
|
373795
|
+
return void 0;
|
|
373796
|
+
}
|
|
373797
|
+
return {
|
|
373798
|
+
host: r.host,
|
|
373799
|
+
port: r.port,
|
|
373800
|
+
bucket: r.bucket,
|
|
373801
|
+
accessKey: r.accessKey,
|
|
373802
|
+
secretKey: r.secretKey
|
|
373803
|
+
};
|
|
373804
|
+
}
|
|
373319
373805
|
);
|
|
373320
373806
|
this.adminServer = adminServer;
|
|
373321
373807
|
this.systemLog(
|
|
@@ -373905,7 +374391,7 @@ function getProjectId() {
|
|
|
373905
374391
|
}
|
|
373906
374392
|
return void 0;
|
|
373907
374393
|
}
|
|
373908
|
-
function
|
|
374394
|
+
function getClient2() {
|
|
373909
374395
|
if (!isEnabled()) return null;
|
|
373910
374396
|
if (!client) {
|
|
373911
374397
|
client = new PostHog("phc_qNQCEUXh6ErdciQRRmeG2xlVvwFjkcW6A5bnOFJ8vXZ", {
|
|
@@ -373918,7 +374404,7 @@ function getClient() {
|
|
|
373918
374404
|
return client;
|
|
373919
374405
|
}
|
|
373920
374406
|
function trackEvent(event, properties) {
|
|
373921
|
-
const ph =
|
|
374407
|
+
const ph = getClient2();
|
|
373922
374408
|
if (!ph) return;
|
|
373923
374409
|
const userId = getUserId();
|
|
373924
374410
|
if (userId && !identified) {
|
|
@@ -373939,7 +374425,7 @@ function trackEvent(event, properties) {
|
|
|
373939
374425
|
event,
|
|
373940
374426
|
properties: {
|
|
373941
374427
|
...properties,
|
|
373942
|
-
cli_version: "0.1.
|
|
374428
|
+
cli_version: "0.1.146",
|
|
373943
374429
|
platform: process.platform,
|
|
373944
374430
|
node_version: process.version,
|
|
373945
374431
|
project_id: getProjectId()
|
|
@@ -376182,6 +376668,7 @@ function DeployUI({ envFlag, preview, config }) {
|
|
|
376182
376668
|
setState((s) => ({
|
|
376183
376669
|
...s,
|
|
376184
376670
|
phase: "creating-tarball",
|
|
376671
|
+
environmentId: match.id,
|
|
376185
376672
|
environmentName: match.name,
|
|
376186
376673
|
environments
|
|
376187
376674
|
}));
|
|
@@ -376195,6 +376682,7 @@ function DeployUI({ envFlag, preview, config }) {
|
|
|
376195
376682
|
setState((s) => ({
|
|
376196
376683
|
...s,
|
|
376197
376684
|
phase: "creating-tarball",
|
|
376685
|
+
environmentId: match.id,
|
|
376198
376686
|
environmentName: match.name,
|
|
376199
376687
|
environments
|
|
376200
376688
|
}));
|
|
@@ -376206,6 +376694,7 @@ function DeployUI({ envFlag, preview, config }) {
|
|
|
376206
376694
|
setState((s) => ({
|
|
376207
376695
|
...s,
|
|
376208
376696
|
phase: "creating-tarball",
|
|
376697
|
+
environmentId: environments[0].id,
|
|
376209
376698
|
environmentName: environments[0].name,
|
|
376210
376699
|
environments
|
|
376211
376700
|
}));
|
|
@@ -376254,6 +376743,7 @@ function DeployUI({ envFlag, preview, config }) {
|
|
|
376254
376743
|
setState((s) => ({
|
|
376255
376744
|
...s,
|
|
376256
376745
|
phase: "creating-tarball",
|
|
376746
|
+
environmentId: previewEnv.id,
|
|
376257
376747
|
environmentName: previewEnv.name
|
|
376258
376748
|
}));
|
|
376259
376749
|
} catch (err) {
|
|
@@ -376275,6 +376765,7 @@ function DeployUI({ envFlag, preview, config }) {
|
|
|
376275
376765
|
setState((s) => ({
|
|
376276
376766
|
...s,
|
|
376277
376767
|
phase: "creating-tarball",
|
|
376768
|
+
environmentId: env2.id,
|
|
376278
376769
|
environmentName: env2.name
|
|
376279
376770
|
}));
|
|
376280
376771
|
},
|
|
@@ -376426,7 +376917,7 @@ function DeployUI({ envFlag, preview, config }) {
|
|
|
376426
376917
|
}, [state]);
|
|
376427
376918
|
const environment = state.environmentName || "prod";
|
|
376428
376919
|
useEffect6(() => {
|
|
376429
|
-
if (state.phase !== "creating-tarball" || !state.projectId || !state.environmentName) return;
|
|
376920
|
+
if (state.phase !== "creating-tarball" || !state.projectId || !state.environmentId || !state.environmentName) return;
|
|
376430
376921
|
let cancelled = false;
|
|
376431
376922
|
async function runDeploy() {
|
|
376432
376923
|
const projectDir = process.cwd();
|
|
@@ -376462,7 +376953,7 @@ function DeployUI({ envFlag, preview, config }) {
|
|
|
376462
376953
|
try {
|
|
376463
376954
|
writeLog("deploy", `Creating deployment for project ${state.projectId}`);
|
|
376464
376955
|
const gitInfo = getGitInfo(projectDir);
|
|
376465
|
-
deployment2 = await client2.createDeployment(state.projectId, state.
|
|
376956
|
+
deployment2 = await client2.createDeployment(state.projectId, state.environmentId, {
|
|
376466
376957
|
triggeredBy: "cli",
|
|
376467
376958
|
...gitInfo && {
|
|
376468
376959
|
gitCommitSha: gitInfo.commitSha,
|
|
@@ -376927,7 +377418,7 @@ async function runDeployPipeline(options2) {
|
|
|
376927
377418
|
const projects = await client2.listProjects();
|
|
376928
377419
|
const project = projects.find((p) => p.id === projectId);
|
|
376929
377420
|
const environments = project?.environments ?? [];
|
|
376930
|
-
let
|
|
377421
|
+
let environmentId;
|
|
376931
377422
|
if (options2.environment) {
|
|
376932
377423
|
const match = findEnvironmentByNameOrId(environments, options2.environment);
|
|
376933
377424
|
if (!match) {
|
|
@@ -376937,15 +377428,15 @@ async function runDeployPipeline(options2) {
|
|
|
376937
377428
|
);
|
|
376938
377429
|
process.exit(1);
|
|
376939
377430
|
}
|
|
376940
|
-
|
|
377431
|
+
environmentId = match.id;
|
|
376941
377432
|
writeEnvironmentId(match.id);
|
|
376942
377433
|
} else if (hasEnvironmentId(projectDir)) {
|
|
376943
377434
|
const savedEnvId = readEnvironmentId(projectDir);
|
|
376944
377435
|
const env2 = environments.find((e) => e.id === savedEnvId);
|
|
376945
377436
|
if (env2) {
|
|
376946
|
-
|
|
377437
|
+
environmentId = env2.id;
|
|
376947
377438
|
} else if (environments.length === 1) {
|
|
376948
|
-
|
|
377439
|
+
environmentId = environments[0].id;
|
|
376949
377440
|
writeEnvironmentId(environments[0].id);
|
|
376950
377441
|
} else if (environments.length === 0) {
|
|
376951
377442
|
console.error("Error: No environments found for this project");
|
|
@@ -376960,7 +377451,7 @@ async function runDeployPipeline(options2) {
|
|
|
376960
377451
|
}
|
|
376961
377452
|
} else {
|
|
376962
377453
|
if (environments.length === 1) {
|
|
376963
|
-
|
|
377454
|
+
environmentId = environments[0].id;
|
|
376964
377455
|
writeEnvironmentId(environments[0].id);
|
|
376965
377456
|
} else if (environments.length === 0) {
|
|
376966
377457
|
console.error("Error: No environments found for this project");
|
|
@@ -377007,7 +377498,7 @@ async function runDeployPipeline(options2) {
|
|
|
377007
377498
|
let deployment;
|
|
377008
377499
|
try {
|
|
377009
377500
|
const gitInfo = getGitInfo(projectDir);
|
|
377010
|
-
deployment = await client2.createDeployment(projectId,
|
|
377501
|
+
deployment = await client2.createDeployment(projectId, environmentId, {
|
|
377011
377502
|
triggeredBy: "cli",
|
|
377012
377503
|
...gitInfo && {
|
|
377013
377504
|
gitCommitSha: gitInfo.commitSha,
|
|
@@ -378050,7 +378541,7 @@ function compareVersions(a, b) {
|
|
|
378050
378541
|
return 0;
|
|
378051
378542
|
}
|
|
378052
378543
|
async function checkForUpdate() {
|
|
378053
|
-
const currentVersion = "0.1.
|
|
378544
|
+
const currentVersion = "0.1.146";
|
|
378054
378545
|
const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
|
|
378055
378546
|
if (!response.ok) {
|
|
378056
378547
|
throw new Error(`Failed to check for updates: HTTP ${response.status}`);
|
|
@@ -378565,7 +379056,7 @@ function friendlyErrorMessage(raw) {
|
|
|
378565
379056
|
var program = new Command();
|
|
378566
379057
|
var env = "production";
|
|
378567
379058
|
var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
|
|
378568
|
-
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.
|
|
379059
|
+
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.146").enablePositionalOptions();
|
|
378569
379060
|
program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
|
|
378570
379061
|
Examples:
|
|
378571
379062
|
$ specific init
|