deepspace 0.19.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/cli.js +492 -259
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +11 -6
- package/dist/server.js +63 -19
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +8 -1
- package/dist/worker.js +63 -19
- package/dist/worker.js.map +1 -1
- package/features/admin-page/src/AdminPage.tsx +4 -4
- package/features/documents/feature.json +2 -1
- package/features/documents/src/DocumentsEditorPage.tsx +31 -10
- package/features/documents/src/DocumentsListPage.tsx +59 -26
- package/features/documents/src/InviteDialog.tsx +49 -14
- package/features/documents/src/LibrarySidebar.tsx +92 -84
- package/features/documents/src/__tests__/documents-presence-access.test.ts +15 -2
- package/features/documents/src/documents-library-types.ts +6 -0
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
renderUsage
|
|
9
9
|
} from "citty";
|
|
10
10
|
import { sync as spawnSync8 } from "cross-spawn";
|
|
11
|
-
import { readFileSync as readFileSync28, existsSync as
|
|
12
|
-
import { dirname as
|
|
11
|
+
import { readFileSync as readFileSync28, existsSync as existsSync26 } from "fs";
|
|
12
|
+
import { dirname as dirname12, join as join24 } from "path";
|
|
13
13
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
14
14
|
|
|
15
15
|
// src/cli/lib/spinner.ts
|
|
@@ -205,6 +205,13 @@ var InputError = class extends Error {
|
|
|
205
205
|
this.code = code;
|
|
206
206
|
}
|
|
207
207
|
};
|
|
208
|
+
var CliExit = class extends Error {
|
|
209
|
+
constructor(exitCode) {
|
|
210
|
+
super(`exit ${exitCode}`);
|
|
211
|
+
this.exitCode = exitCode;
|
|
212
|
+
this.name = "CliExit";
|
|
213
|
+
}
|
|
214
|
+
};
|
|
208
215
|
function errorCode(err) {
|
|
209
216
|
if (err instanceof ApiError || err instanceof InputError) return err.code;
|
|
210
217
|
if (err instanceof Error && err.name === "GitError") return err.code ?? "git_error";
|
|
@@ -230,12 +237,17 @@ function formatCliError(err) {
|
|
|
230
237
|
${hint}` : message;
|
|
231
238
|
}
|
|
232
239
|
function renderCliError(err) {
|
|
240
|
+
if (err instanceof CliExit) {
|
|
241
|
+
process.exitCode = err.exitCode;
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
233
244
|
stopActiveSpinner();
|
|
234
245
|
const message = formatCliError(err);
|
|
235
246
|
const slug = errorCode(err);
|
|
236
247
|
if (process.argv.includes("--json")) {
|
|
237
248
|
console.log(JSON.stringify({ ok: false, ...slug ? { code: slug } : {}, error: message }));
|
|
238
|
-
process.
|
|
249
|
+
process.exitCode = 1;
|
|
250
|
+
return;
|
|
239
251
|
}
|
|
240
252
|
console.error(slug ? withSlug(message, slug) : message);
|
|
241
253
|
if (process.env.DEBUG) {
|
|
@@ -244,7 +256,7 @@ function renderCliError(err) {
|
|
|
244
256
|
API ${apiPath}${status3 ? ` (${status3})` : ""}`);
|
|
245
257
|
if (err instanceof Error && err.stack) console.error("\n" + err.stack);
|
|
246
258
|
}
|
|
247
|
-
process.
|
|
259
|
+
process.exitCode = 1;
|
|
248
260
|
}
|
|
249
261
|
function wrapCommandErrors(cmd) {
|
|
250
262
|
const run2 = cmd.run;
|
|
@@ -301,10 +313,9 @@ function withoutReservedKeys(payload) {
|
|
|
301
313
|
)
|
|
302
314
|
);
|
|
303
315
|
}
|
|
304
|
-
function
|
|
305
|
-
|
|
306
|
-
process.
|
|
307
|
-
return void 0;
|
|
316
|
+
function finishCommand(code) {
|
|
317
|
+
stopActiveSpinner();
|
|
318
|
+
process.exitCode = code;
|
|
308
319
|
}
|
|
309
320
|
function nameVariants(name) {
|
|
310
321
|
return [
|
|
@@ -398,9 +409,9 @@ function defineDeepspaceCommand(def) {
|
|
|
398
409
|
else p3.log.error(line);
|
|
399
410
|
if (refusal?.action) printAction(refusal.action);
|
|
400
411
|
}
|
|
401
|
-
|
|
412
|
+
finishCommand(refusal?.actionRequired ? 2 : 1);
|
|
402
413
|
}
|
|
403
|
-
if (succeeded)
|
|
414
|
+
if (succeeded) finishCommand(0);
|
|
404
415
|
}
|
|
405
416
|
});
|
|
406
417
|
}
|
|
@@ -515,7 +526,7 @@ function effectivePlatformUrls(env = process.env) {
|
|
|
515
526
|
var DASHBOARD_URL = DEEPSPACE_ENV === "production" ? "https://dashboard.deep.space" : DEEPSPACE_ENV === "staging" ? "https://dashboard.deepspacesites.com" : "http://127.0.0.1:9";
|
|
516
527
|
|
|
517
528
|
// src/cli/auth.ts
|
|
518
|
-
import { readFileSync as readFileSync2,
|
|
529
|
+
import { readFileSync as readFileSync2, existsSync, mkdirSync } from "fs";
|
|
519
530
|
import { join } from "path";
|
|
520
531
|
import { homedir } from "os";
|
|
521
532
|
|
|
@@ -543,6 +554,16 @@ async function exchangeSession(authUrl, sessionToken) {
|
|
|
543
554
|
return data.token ?? null;
|
|
544
555
|
}
|
|
545
556
|
|
|
557
|
+
// src/cli/lib/secure-file.ts
|
|
558
|
+
import { chmodSync, writeFileSync } from "fs";
|
|
559
|
+
function writeSecretFileSync(path, content) {
|
|
560
|
+
writeFileSync(path, content, { mode: 384 });
|
|
561
|
+
try {
|
|
562
|
+
chmodSync(path, 384);
|
|
563
|
+
} catch {
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
546
567
|
// src/cli/auth.ts
|
|
547
568
|
var AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth;
|
|
548
569
|
var PROD_AUTH_URL = "https://auth.deep.space";
|
|
@@ -585,7 +606,7 @@ async function ensureToken() {
|
|
|
585
606
|
);
|
|
586
607
|
}
|
|
587
608
|
mkdirSync(DIR, { recursive: true, mode: 448 });
|
|
588
|
-
|
|
609
|
+
writeSecretFileSync(TOKEN_PATH, token);
|
|
589
610
|
return token;
|
|
590
611
|
}
|
|
591
612
|
function isTokenValid(jwt) {
|
|
@@ -603,7 +624,7 @@ registerAuthRefresh(async () => {
|
|
|
603
624
|
const token = await exchangeSession(AUTH_URL, sessionToken);
|
|
604
625
|
if (!token) return null;
|
|
605
626
|
mkdirSync(DIR, { recursive: true, mode: 448 });
|
|
606
|
-
|
|
627
|
+
writeSecretFileSync(TOKEN_PATH, token);
|
|
607
628
|
return token;
|
|
608
629
|
} catch {
|
|
609
630
|
return null;
|
|
@@ -611,19 +632,18 @@ registerAuthRefresh(async () => {
|
|
|
611
632
|
});
|
|
612
633
|
|
|
613
634
|
// src/cli/commands/login.ts
|
|
614
|
-
import {
|
|
615
|
-
import {
|
|
616
|
-
import { homedir as homedir2 } from "os";
|
|
635
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3 } from "fs";
|
|
636
|
+
import { dirname as dirname2 } from "path";
|
|
617
637
|
import { randomBytes, createHash } from "crypto";
|
|
618
638
|
import * as p4 from "@clack/prompts";
|
|
619
639
|
|
|
620
640
|
// src/cli/lib/open-browser.ts
|
|
621
|
-
import {
|
|
641
|
+
import { spawn } from "child_process";
|
|
622
642
|
function openBrowser(url) {
|
|
623
643
|
const quoted = JSON.stringify(url);
|
|
624
644
|
const cmd = process.platform === "darwin" ? `open ${quoted}` : process.platform === "win32" ? `start "" ${quoted}` : `xdg-open ${quoted}`;
|
|
625
|
-
|
|
626
|
-
});
|
|
645
|
+
spawn(cmd, { shell: true, detached: true, stdio: "ignore", windowsHide: true }).on("error", () => {
|
|
646
|
+
}).unref();
|
|
627
647
|
}
|
|
628
648
|
|
|
629
649
|
// src/cli/commands/login.ts
|
|
@@ -716,9 +736,13 @@ var login_default = defineDeepspaceCommand({
|
|
|
716
736
|
if (!json) s.start("Waiting for authentication...");
|
|
717
737
|
const result = await pollForCompletion(sessionId, codeVerifier);
|
|
718
738
|
if (!result) {
|
|
719
|
-
throw new Refusal(
|
|
720
|
-
|
|
721
|
-
|
|
739
|
+
throw new Refusal(
|
|
740
|
+
"Login timed out. Run `deepspace auth login` to try again.",
|
|
741
|
+
"login_timeout",
|
|
742
|
+
{
|
|
743
|
+
action: cliAction("deepspace", "auth", "login")
|
|
744
|
+
}
|
|
745
|
+
);
|
|
722
746
|
}
|
|
723
747
|
storeCredentials(result.sessionToken, result.jwt);
|
|
724
748
|
await provisionProfile(result.jwt);
|
|
@@ -798,11 +822,10 @@ async function pollForCompletion(sessionId, codeVerifier) {
|
|
|
798
822
|
return null;
|
|
799
823
|
}
|
|
800
824
|
function storeCredentials(sessionToken, jwt) {
|
|
801
|
-
const dir = join2(homedir2(), ".deepspace");
|
|
802
|
-
mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
803
825
|
const { sessionPath, tokenPath } = credentialPaths(AUTH_URL2);
|
|
804
|
-
|
|
805
|
-
|
|
826
|
+
mkdirSync2(dirname2(sessionPath), { recursive: true, mode: 448 });
|
|
827
|
+
writeSecretFileSync(sessionPath, sessionToken);
|
|
828
|
+
writeSecretFileSync(tokenPath, jwt);
|
|
806
829
|
}
|
|
807
830
|
async function provisionProfile(jwt) {
|
|
808
831
|
try {
|
|
@@ -883,8 +906,8 @@ var logout_default = defineDeepspaceCommand({
|
|
|
883
906
|
});
|
|
884
907
|
|
|
885
908
|
// src/cli/lib/app-identity.ts
|
|
886
|
-
import { existsSync as existsSync3, readFileSync as readFileSync5, writeFileSync as
|
|
887
|
-
import { join as
|
|
909
|
+
import { existsSync as existsSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
910
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
888
911
|
import { parse as parseToml } from "smol-toml";
|
|
889
912
|
|
|
890
913
|
// src/server/utils/registry-client.ts
|
|
@@ -919,7 +942,7 @@ function mintAppId(now = Date.now()) {
|
|
|
919
942
|
return `app_${mintUlid(now)}`;
|
|
920
943
|
}
|
|
921
944
|
function readWranglerIdentityConfig(cwd) {
|
|
922
|
-
const wranglerPath =
|
|
945
|
+
const wranglerPath = join2(resolve2(cwd), "wrangler.toml");
|
|
923
946
|
if (!existsSync3(wranglerPath)) return null;
|
|
924
947
|
try {
|
|
925
948
|
return parseToml(readFileSync5(wranglerPath, "utf-8"));
|
|
@@ -938,7 +961,7 @@ function readAppId(cwd = process.cwd(), wranglerEnv) {
|
|
|
938
961
|
return typeof id === "string" && APP_ID_RE.test(id) ? id : null;
|
|
939
962
|
}
|
|
940
963
|
function writeAppId(cwd, appId, opts = {}) {
|
|
941
|
-
const wranglerPath =
|
|
964
|
+
const wranglerPath = join2(resolve2(cwd), "wrangler.toml");
|
|
942
965
|
if (!existsSync3(wranglerPath)) {
|
|
943
966
|
throw new Error(`No wrangler.toml in ${resolve2(cwd)}`);
|
|
944
967
|
}
|
|
@@ -971,19 +994,19 @@ ${header}
|
|
|
971
994
|
${line}
|
|
972
995
|
`;
|
|
973
996
|
}
|
|
974
|
-
|
|
997
|
+
writeFileSync2(wranglerPath, src);
|
|
975
998
|
}
|
|
976
999
|
|
|
977
1000
|
// src/cli/commands/dev.ts
|
|
978
|
-
import { resolve as resolve8, basename as basename2, join as
|
|
979
|
-
import
|
|
1001
|
+
import { resolve as resolve8, basename as basename2, join as join11 } from "path";
|
|
1002
|
+
import spawn2 from "cross-spawn";
|
|
980
1003
|
|
|
981
1004
|
// src/cli/lib/app-context.ts
|
|
982
1005
|
import { existsSync as existsSync4, readFileSync as readFileSync6, readdirSync } from "fs";
|
|
983
|
-
import { dirname as
|
|
1006
|
+
import { dirname as dirname3, join as join3, resolve as resolve3 } from "path";
|
|
984
1007
|
import { parse as parseToml2 } from "smol-toml";
|
|
985
1008
|
function detectAppName(cwd = process.cwd()) {
|
|
986
|
-
const wranglerPath =
|
|
1009
|
+
const wranglerPath = join3(resolve3(cwd), "wrangler.toml");
|
|
987
1010
|
if (!existsSync4(wranglerPath)) return null;
|
|
988
1011
|
try {
|
|
989
1012
|
const config = parseToml2(readFileSync6(wranglerPath, "utf-8"));
|
|
@@ -998,15 +1021,15 @@ function detectAppName(cwd = process.cwd()) {
|
|
|
998
1021
|
function findAppDir(start = process.cwd()) {
|
|
999
1022
|
let dir = resolve3(start);
|
|
1000
1023
|
for (; ; ) {
|
|
1001
|
-
if (existsSync4(
|
|
1002
|
-
const parent =
|
|
1024
|
+
if (existsSync4(join3(dir, "wrangler.toml"))) return dir;
|
|
1025
|
+
const parent = dirname3(dir);
|
|
1003
1026
|
if (parent === dir) return null;
|
|
1004
1027
|
dir = parent;
|
|
1005
1028
|
}
|
|
1006
1029
|
}
|
|
1007
1030
|
function findChildApps(dir) {
|
|
1008
1031
|
try {
|
|
1009
|
-
return readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync4(
|
|
1032
|
+
return readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync4(join3(dir, entry.name, "wrangler.toml"))).map((entry) => entry.name).sort();
|
|
1010
1033
|
} catch {
|
|
1011
1034
|
return [];
|
|
1012
1035
|
}
|
|
@@ -1017,16 +1040,16 @@ import {
|
|
|
1017
1040
|
existsSync as existsSync5,
|
|
1018
1041
|
readFileSync as readFileSync8,
|
|
1019
1042
|
realpathSync as realpathSync2,
|
|
1020
|
-
writeFileSync as
|
|
1043
|
+
writeFileSync as writeFileSync3,
|
|
1021
1044
|
mkdirSync as mkdirSync4,
|
|
1022
1045
|
renameSync,
|
|
1023
1046
|
unlinkSync
|
|
1024
1047
|
} from "fs";
|
|
1025
|
-
import { join as
|
|
1048
|
+
import { join as join5, resolve as resolve5, dirname as dirname5, basename, isAbsolute as isAbsolute2, sep } from "path";
|
|
1026
1049
|
|
|
1027
1050
|
// src/cli/lib/git/repository.ts
|
|
1028
1051
|
import { appendFileSync, mkdirSync as mkdirSync3, readFileSync as readFileSync7 } from "fs";
|
|
1029
|
-
import { dirname as
|
|
1052
|
+
import { dirname as dirname4, join as join4, resolve as resolve4 } from "path";
|
|
1030
1053
|
|
|
1031
1054
|
// src/cli/lib/git/process.ts
|
|
1032
1055
|
import { sync as spawnSync } from "cross-spawn";
|
|
@@ -1230,7 +1253,7 @@ function listWorktrees(cwd) {
|
|
|
1230
1253
|
}
|
|
1231
1254
|
function ensureLocalExclude(cwd, pattern) {
|
|
1232
1255
|
const commonDir = resolve4(cwd, gitLine(cwd, ["rev-parse", "--git-common-dir"]));
|
|
1233
|
-
const excludePath =
|
|
1256
|
+
const excludePath = join4(commonDir, "info", "exclude");
|
|
1234
1257
|
let current = "";
|
|
1235
1258
|
try {
|
|
1236
1259
|
current = readFileSync7(excludePath, "utf-8");
|
|
@@ -1238,7 +1261,7 @@ function ensureLocalExclude(cwd, pattern) {
|
|
|
1238
1261
|
}
|
|
1239
1262
|
if (current.split("\n").some((line) => line.trim() === pattern)) return;
|
|
1240
1263
|
try {
|
|
1241
|
-
mkdirSync3(
|
|
1264
|
+
mkdirSync3(dirname4(excludePath), { recursive: true });
|
|
1242
1265
|
appendFileSync(
|
|
1243
1266
|
excludePath,
|
|
1244
1267
|
`${current.endsWith("\n") || current === "" ? "" : "\n"}${pattern}
|
|
@@ -1250,9 +1273,9 @@ function ensureLocalExclude(cwd, pattern) {
|
|
|
1250
1273
|
|
|
1251
1274
|
// src/cli/lib/launch-config.ts
|
|
1252
1275
|
function writeLaunchFile(launchPath, config) {
|
|
1253
|
-
mkdirSync4(
|
|
1276
|
+
mkdirSync4(dirname5(launchPath), { recursive: true });
|
|
1254
1277
|
const tmpPath = `${launchPath}.${process.pid}.tmp`;
|
|
1255
|
-
|
|
1278
|
+
writeFileSync3(tmpPath, JSON.stringify(config, null, 2) + "\n");
|
|
1256
1279
|
try {
|
|
1257
1280
|
renameSync(tmpPath, launchPath);
|
|
1258
1281
|
} catch (err) {
|
|
@@ -1273,7 +1296,7 @@ function readLaunchFile(launchPath) {
|
|
|
1273
1296
|
return parsed;
|
|
1274
1297
|
}
|
|
1275
1298
|
function writeLaunchConfigIfMissing(appDir, appName, port, opts = {}) {
|
|
1276
|
-
const launchPath =
|
|
1299
|
+
const launchPath = join5(appDir, ".claude", "launch.json");
|
|
1277
1300
|
try {
|
|
1278
1301
|
const config = readLaunchFile(launchPath);
|
|
1279
1302
|
if (!config) return;
|
|
@@ -1314,7 +1337,7 @@ function writeLaunchConfigIfMissing(appDir, appName, port, opts = {}) {
|
|
|
1314
1337
|
}
|
|
1315
1338
|
function resolveAppLaunchPort(appDir) {
|
|
1316
1339
|
try {
|
|
1317
|
-
const config = readLaunchFile(
|
|
1340
|
+
const config = readLaunchFile(join5(appDir, ".claude", "launch.json"));
|
|
1318
1341
|
if (!config) return null;
|
|
1319
1342
|
const appName = detectAppName(appDir) ?? basename(appDir);
|
|
1320
1343
|
const entry = config.configurations.find((c) => c?.name === appName) ?? (config.configurations.length === 1 ? config.configurations[0] : void 0);
|
|
@@ -1331,10 +1354,10 @@ function detectClaudeWorktree(appDir) {
|
|
|
1331
1354
|
listWorktrees(appDir).map((worktree) => canonicalPath(worktree.path))
|
|
1332
1355
|
);
|
|
1333
1356
|
if (!registered.has(worktreeRoot)) return null;
|
|
1334
|
-
const worktreesDir =
|
|
1335
|
-
const claudeDir =
|
|
1357
|
+
const worktreesDir = dirname5(worktreeRoot);
|
|
1358
|
+
const claudeDir = dirname5(worktreesDir);
|
|
1336
1359
|
if (basename(worktreesDir) !== "worktrees" || basename(claudeDir) !== ".claude") return null;
|
|
1337
|
-
const ownerRoot = canonicalPath(
|
|
1360
|
+
const ownerRoot = canonicalPath(dirname5(claudeDir));
|
|
1338
1361
|
if (!registered.has(ownerRoot)) return null;
|
|
1339
1362
|
return { mainRepoRoot: ownerRoot, worktreeName: basename(worktreeRoot) };
|
|
1340
1363
|
} catch {
|
|
@@ -1368,12 +1391,12 @@ function deriveWorktreePort(worktreeKey) {
|
|
|
1368
1391
|
return WORKTREE_PORT_MIN + hash % WORKTREE_PORT_RANGE;
|
|
1369
1392
|
}
|
|
1370
1393
|
function upsertWorktreeLaunchConfig(mainRepoRoot, worktreeName, appDir, opts) {
|
|
1371
|
-
const launchPath =
|
|
1394
|
+
const launchPath = join5(mainRepoRoot, ".claude", "launch.json");
|
|
1372
1395
|
const entryName = WORKTREE_ENTRY_PREFIX + worktreeName;
|
|
1373
1396
|
try {
|
|
1374
1397
|
const config = readLaunchFile(launchPath);
|
|
1375
1398
|
if (!config) return null;
|
|
1376
|
-
const worktreesRoot =
|
|
1399
|
+
const worktreesRoot = join5(mainRepoRoot, ".claude", "worktrees") + sep;
|
|
1377
1400
|
config.configurations = config.configurations.filter((c) => {
|
|
1378
1401
|
if (c?.name === entryName) return false;
|
|
1379
1402
|
const isStaleWorktreeEntry = typeof c?.name === "string" && c.name.startsWith(WORKTREE_ENTRY_PREFIX) && typeof c.cwd === "string" && isAbsolute2(c.cwd) && c.cwd.startsWith(worktreesRoot) && !existsSync5(c.cwd);
|
|
@@ -1411,7 +1434,7 @@ function resolveWorktreePort(appDir) {
|
|
|
1411
1434
|
const claude = detectClaudeWorktree(appDir);
|
|
1412
1435
|
if (claude) {
|
|
1413
1436
|
try {
|
|
1414
|
-
const config = readLaunchFile(
|
|
1437
|
+
const config = readLaunchFile(join5(claude.mainRepoRoot, ".claude", "launch.json"));
|
|
1415
1438
|
const entry = config?.configurations.find(
|
|
1416
1439
|
(c) => c?.name === WORKTREE_ENTRY_PREFIX + claude.worktreeName
|
|
1417
1440
|
);
|
|
@@ -1472,19 +1495,9 @@ async function fetchAppIdentityToken(deployUrl, callerJwt, appId) {
|
|
|
1472
1495
|
return body.token;
|
|
1473
1496
|
}
|
|
1474
1497
|
|
|
1475
|
-
// src/cli/lib/secure-file.ts
|
|
1476
|
-
import { chmodSync, writeFileSync as writeFileSync5 } from "fs";
|
|
1477
|
-
function writeSecretFileSync(path, content) {
|
|
1478
|
-
writeFileSync5(path, content, { mode: 384 });
|
|
1479
|
-
try {
|
|
1480
|
-
chmodSync(path, 384);
|
|
1481
|
-
} catch {
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
1498
|
// src/cli/lib/wrangler-env.ts
|
|
1486
|
-
import { existsSync as existsSync6, readFileSync as readFileSync9, rmSync as rmSync2, writeFileSync as
|
|
1487
|
-
import { join as
|
|
1499
|
+
import { existsSync as existsSync6, readFileSync as readFileSync9, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
1500
|
+
import { join as join6 } from "path";
|
|
1488
1501
|
import { parse as parseToml3, stringify as stringifyToml } from "smol-toml";
|
|
1489
1502
|
|
|
1490
1503
|
// src/server/rooms/app-name.ts
|
|
@@ -1585,7 +1598,7 @@ function resolveAppNameForEnv(config, envName) {
|
|
|
1585
1598
|
return resolveAppName(envBlock.name);
|
|
1586
1599
|
}
|
|
1587
1600
|
function devVarsPathFor(appDir) {
|
|
1588
|
-
return
|
|
1601
|
+
return join6(appDir, ".dev.vars");
|
|
1589
1602
|
}
|
|
1590
1603
|
function prepareWranglerEnvConfig(appDir, envName) {
|
|
1591
1604
|
if (!envName) return { cleanup() {
|
|
@@ -1594,11 +1607,11 @@ function prepareWranglerEnvConfig(appDir, envName) {
|
|
|
1594
1607
|
const resolved = resolveAppNameForEnv(config, envName);
|
|
1595
1608
|
if (!resolved.ok) throw new Error(resolved.reason);
|
|
1596
1609
|
const flattened = flattenWranglerEnvConfig(config, envName);
|
|
1597
|
-
const configPath =
|
|
1610
|
+
const configPath = join6(
|
|
1598
1611
|
appDir,
|
|
1599
1612
|
`.wrangler.deepspace.${safeGeneratedConfigSegment(envName)}.${process.pid}.${++generatedConfigSeq}.toml`
|
|
1600
1613
|
);
|
|
1601
|
-
|
|
1614
|
+
writeFileSync4(
|
|
1602
1615
|
configPath,
|
|
1603
1616
|
[
|
|
1604
1617
|
"# Generated by DeepSpace for this CLI run.",
|
|
@@ -1660,7 +1673,7 @@ var WranglerConfigError = class extends Error {
|
|
|
1660
1673
|
}
|
|
1661
1674
|
};
|
|
1662
1675
|
function readWranglerConfig(appDir) {
|
|
1663
|
-
const path =
|
|
1676
|
+
const path = join6(appDir, "wrangler.toml");
|
|
1664
1677
|
const raw = readFileSync9(path, "utf-8");
|
|
1665
1678
|
try {
|
|
1666
1679
|
return parseToml3(raw);
|
|
@@ -1669,7 +1682,7 @@ function readWranglerConfig(appDir) {
|
|
|
1669
1682
|
}
|
|
1670
1683
|
}
|
|
1671
1684
|
function hasWranglerConfig(appDir) {
|
|
1672
|
-
return existsSync6(
|
|
1685
|
+
return existsSync6(join6(appDir, "wrangler.toml"));
|
|
1673
1686
|
}
|
|
1674
1687
|
|
|
1675
1688
|
// src/cli/lib/dev-vars.ts
|
|
@@ -1712,21 +1725,21 @@ async function writeDevVars(appDir, ownerId, callerJwt, wranglerEnv, opts = {})
|
|
|
1712
1725
|
|
|
1713
1726
|
// src/cli/lib/install-status.ts
|
|
1714
1727
|
import { existsSync as existsSync8, readFileSync as readFileSync11, realpathSync as realpathSync3 } from "fs";
|
|
1715
|
-
import { dirname as
|
|
1728
|
+
import { dirname as dirname6, join as join8, resolve as resolve6 } from "path";
|
|
1716
1729
|
|
|
1717
1730
|
// src/cli/lib/package-manager.ts
|
|
1718
1731
|
import { existsSync as existsSync7, readFileSync as readFileSync10 } from "fs";
|
|
1719
|
-
import { join as
|
|
1732
|
+
import { join as join7 } from "path";
|
|
1720
1733
|
function detectPackageManager(appDir) {
|
|
1721
1734
|
try {
|
|
1722
|
-
const pkg2 = JSON.parse(readFileSync10(
|
|
1735
|
+
const pkg2 = JSON.parse(readFileSync10(join7(appDir, "package.json"), "utf-8"));
|
|
1723
1736
|
const name = typeof pkg2.packageManager === "string" ? pkg2.packageManager.split("@")[0] : "";
|
|
1724
1737
|
if (name === "npm" || name === "pnpm" || name === "yarn" || name === "bun") return name;
|
|
1725
1738
|
} catch {
|
|
1726
1739
|
}
|
|
1727
|
-
if (existsSync7(
|
|
1728
|
-
if (existsSync7(
|
|
1729
|
-
if (existsSync7(
|
|
1740
|
+
if (existsSync7(join7(appDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
1741
|
+
if (existsSync7(join7(appDir, "yarn.lock"))) return "yarn";
|
|
1742
|
+
if (existsSync7(join7(appDir, "bun.lock")) || existsSync7(join7(appDir, "bun.lockb"))) return "bun";
|
|
1730
1743
|
return "npm";
|
|
1731
1744
|
}
|
|
1732
1745
|
function installCommand(appDir) {
|
|
@@ -1736,10 +1749,10 @@ function installCommand(appDir) {
|
|
|
1736
1749
|
// src/cli/lib/install-status.ts
|
|
1737
1750
|
function installState(appDir) {
|
|
1738
1751
|
if (resolvesDeepspace(appDir)) return "ready";
|
|
1739
|
-
const sentinelDir =
|
|
1740
|
-
if (existsSync8(
|
|
1741
|
-
if (existsSync8(
|
|
1742
|
-
if (!existsSync8(
|
|
1752
|
+
const sentinelDir = join8(appDir, ".deepspace");
|
|
1753
|
+
if (existsSync8(join8(sentinelDir, "install.err"))) return "failed";
|
|
1754
|
+
if (existsSync8(join8(sentinelDir, "install.started"))) {
|
|
1755
|
+
if (!existsSync8(join8(sentinelDir, "install.done")) && installWorkerAlive(sentinelDir)) {
|
|
1743
1756
|
return "installing";
|
|
1744
1757
|
}
|
|
1745
1758
|
return "failed";
|
|
@@ -1751,11 +1764,11 @@ function tailHint(logPath, platform = process.platform) {
|
|
|
1751
1764
|
}
|
|
1752
1765
|
function ensureInstallReady(appDir) {
|
|
1753
1766
|
if (resolvesDeepspace(appDir)) return;
|
|
1754
|
-
const sentinelDir =
|
|
1755
|
-
const errPath =
|
|
1756
|
-
const startedPath =
|
|
1757
|
-
const donePath =
|
|
1758
|
-
const logPath =
|
|
1767
|
+
const sentinelDir = join8(appDir, ".deepspace");
|
|
1768
|
+
const errPath = join8(sentinelDir, "install.err");
|
|
1769
|
+
const startedPath = join8(sentinelDir, "install.started");
|
|
1770
|
+
const donePath = join8(sentinelDir, "install.done");
|
|
1771
|
+
const logPath = join8(sentinelDir, "install.log");
|
|
1759
1772
|
if (existsSync8(errPath)) {
|
|
1760
1773
|
const detail = readFileSync11(errPath, "utf-8").trimEnd();
|
|
1761
1774
|
const log29 = existsSync8(logPath) ? ` Full log: ${logPath}.` : "";
|
|
@@ -1796,9 +1809,9 @@ function resolvesDeepspace(fromDir) {
|
|
|
1796
1809
|
} catch {
|
|
1797
1810
|
}
|
|
1798
1811
|
for (; ; ) {
|
|
1799
|
-
if (existsSync8(
|
|
1812
|
+
if (existsSync8(join8(dir, "node_modules", "deepspace", "package.json"))) return true;
|
|
1800
1813
|
if (dir === checkoutRoot) return false;
|
|
1801
|
-
const parent =
|
|
1814
|
+
const parent = dirname6(dir);
|
|
1802
1815
|
if (parent === dir) return false;
|
|
1803
1816
|
dir = parent;
|
|
1804
1817
|
}
|
|
@@ -1811,7 +1824,7 @@ function canonicalPath2(path) {
|
|
|
1811
1824
|
}
|
|
1812
1825
|
}
|
|
1813
1826
|
function installWorkerAlive(sentinelDir) {
|
|
1814
|
-
const pidPath =
|
|
1827
|
+
const pidPath = join8(sentinelDir, "install.pid");
|
|
1815
1828
|
if (!existsSync8(pidPath)) return false;
|
|
1816
1829
|
const pid = Number(readFileSync11(pidPath, "utf-8").trim());
|
|
1817
1830
|
if (!Number.isSafeInteger(pid) || pid <= 0) return false;
|
|
@@ -1864,7 +1877,7 @@ function preflightWindowsWorkerd(appDir) {
|
|
|
1864
1877
|
|
|
1865
1878
|
// src/cli/lib/macos-junk.ts
|
|
1866
1879
|
import { readdirSync as readdirSync2, rmSync as rmSync3 } from "fs";
|
|
1867
|
-
import { join as
|
|
1880
|
+
import { join as join9 } from "path";
|
|
1868
1881
|
var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", ".wrangler", ".vite"]);
|
|
1869
1882
|
function removeMacosJunk(dir) {
|
|
1870
1883
|
let removed = 0;
|
|
@@ -1875,7 +1888,7 @@ function removeMacosJunk(dir) {
|
|
|
1875
1888
|
return removed;
|
|
1876
1889
|
}
|
|
1877
1890
|
for (const entry of entries) {
|
|
1878
|
-
const path =
|
|
1891
|
+
const path = join9(dir, entry.name);
|
|
1879
1892
|
if (entry.isDirectory()) {
|
|
1880
1893
|
if (!SKIP_DIRS.has(entry.name)) removed += removeMacosJunk(path);
|
|
1881
1894
|
continue;
|
|
@@ -2373,7 +2386,7 @@ async function refreshSecretsCache(deployUrl, token, appId, wranglerEnv, selecte
|
|
|
2373
2386
|
|
|
2374
2387
|
// src/cli/lib/schema-lint.ts
|
|
2375
2388
|
import { existsSync as existsSync10 } from "fs";
|
|
2376
|
-
import { join as
|
|
2389
|
+
import { join as join10 } from "path";
|
|
2377
2390
|
import { pathToFileURL } from "url";
|
|
2378
2391
|
|
|
2379
2392
|
// src/server/schemas/registry.ts
|
|
@@ -2432,12 +2445,12 @@ function lintSchema(schema) {
|
|
|
2432
2445
|
|
|
2433
2446
|
// src/cli/lib/schema-lint.ts
|
|
2434
2447
|
async function lintProjectSchemas(appDir) {
|
|
2435
|
-
const schemasPath =
|
|
2448
|
+
const schemasPath = join10(appDir, "src", "schemas.ts");
|
|
2436
2449
|
if (!existsSync10(schemasPath)) return null;
|
|
2437
2450
|
let schemas;
|
|
2438
2451
|
try {
|
|
2439
2452
|
const esbuild = await import("esbuild");
|
|
2440
|
-
const outFile =
|
|
2453
|
+
const outFile = join10(appDir, ".wrangler", "deploy", "schemas.lint.bundle.mjs");
|
|
2441
2454
|
await esbuild.build({
|
|
2442
2455
|
entryPoints: [schemasPath],
|
|
2443
2456
|
bundle: true,
|
|
@@ -2498,9 +2511,9 @@ function isPortListening(port, host, timeoutMs = 500) {
|
|
|
2498
2511
|
socket.connect(port, target2);
|
|
2499
2512
|
});
|
|
2500
2513
|
}
|
|
2501
|
-
async function waitForPortListening(port, host, timeoutMs) {
|
|
2514
|
+
async function waitForPortListening(port, host, timeoutMs, signal) {
|
|
2502
2515
|
const deadline = Date.now() + timeoutMs;
|
|
2503
|
-
while (Date.now() < deadline) {
|
|
2516
|
+
while (Date.now() < deadline && !signal?.aborted) {
|
|
2504
2517
|
if (await isPortListening(port, host)) return true;
|
|
2505
2518
|
await new Promise((resolve21) => setTimeout(resolve21, 250));
|
|
2506
2519
|
}
|
|
@@ -2598,7 +2611,7 @@ var dev_default = defineDeepspaceCommand({
|
|
|
2598
2611
|
);
|
|
2599
2612
|
} else if (!args.json) {
|
|
2600
2613
|
console.warn(
|
|
2601
|
-
`Warning: could not update ${
|
|
2614
|
+
`Warning: could not update ${join11(worktree.mainRepoRoot, ".claude", "launch.json")} (malformed or unwritable) \u2014 the Claude preview tool may serve the main repo's code instead of this worktree.`
|
|
2602
2615
|
);
|
|
2603
2616
|
}
|
|
2604
2617
|
}
|
|
@@ -2664,13 +2677,15 @@ Free it with \`${killCmd}\`, or start on another port: \`deepspace dev start --p
|
|
|
2664
2677
|
}
|
|
2665
2678
|
const url = `http://${host === DEFAULT_DEV_HOST ? "localhost" : host}:${port}`;
|
|
2666
2679
|
say("Starting dev server...\n");
|
|
2667
|
-
const vite =
|
|
2680
|
+
const vite = spawn2("npx", ["vite", "--port", String(port), "--strictPort", "--host", host], {
|
|
2668
2681
|
cwd: appDir,
|
|
2669
2682
|
stdio: "inherit",
|
|
2670
2683
|
env: wranglerViteEnv(process.env, wranglerConfig, { DEEPSPACE_PORT: String(port) })
|
|
2671
2684
|
});
|
|
2685
|
+
const readiness = new AbortController();
|
|
2672
2686
|
if (args.json) {
|
|
2673
|
-
void waitForPortListening(port, host, READINESS_TIMEOUT_MS).then((ready) => {
|
|
2687
|
+
void waitForPortListening(port, host, READINESS_TIMEOUT_MS, readiness.signal).then((ready) => {
|
|
2688
|
+
if (readiness.signal.aborted) return;
|
|
2674
2689
|
console.log(
|
|
2675
2690
|
JSON.stringify(
|
|
2676
2691
|
ready ? { ok: true, ready: true, url, port, host, appDir } : {
|
|
@@ -2702,6 +2717,7 @@ Free it with \`${killCmd}\`, or start on another port: \`deepspace dev start --p
|
|
|
2702
2717
|
});
|
|
2703
2718
|
process.off("SIGINT", stop);
|
|
2704
2719
|
process.off("SIGTERM", stop);
|
|
2720
|
+
readiness.abort();
|
|
2705
2721
|
if (!devExitSucceeded(code, stopping)) {
|
|
2706
2722
|
throw new Refusal(`Dev server exited with code ${code}.`, "dev_server_failed", {
|
|
2707
2723
|
extra: { port, appDir, exitCode: code }
|
|
@@ -2817,12 +2833,12 @@ var kill_default = defineDeepspaceCommand({
|
|
|
2817
2833
|
}
|
|
2818
2834
|
});
|
|
2819
2835
|
function noTargetsMessage(opts) {
|
|
2820
|
-
const { enumerated, swept, all, port } = opts;
|
|
2836
|
+
const { enumerated, swept, all, port, platform = process.platform } = opts;
|
|
2821
2837
|
const couldObserve = enumerated || all && swept;
|
|
2822
2838
|
if (!couldObserve) {
|
|
2823
2839
|
return {
|
|
2824
2840
|
ok: false,
|
|
2825
|
-
message: `Couldn't determine what's running on :${port}: no lsof/pgrep and /proc is unavailable, so nothing was inspected or killed. Install lsof (or procps for pgrep), or find and kill the process manually.`
|
|
2841
|
+
message: platform === "win32" ? `Couldn't determine what's running on :${port}: the PowerShell port query could not be run, so nothing was inspected or killed. Either powershell.exe (or pwsh) is not on PATH, or Get-NetTCPConnection is unavailable on this Windows edition. Find the process manually with \`netstat -ano | findstr :${port}\`.` : `Couldn't determine what's running on :${port}: no lsof/pgrep and /proc is unavailable, so nothing was inspected or killed. Install lsof (or procps for pgrep), or find and kill the process manually.`
|
|
2826
2842
|
};
|
|
2827
2843
|
}
|
|
2828
2844
|
return {
|
|
@@ -2917,7 +2933,7 @@ function sweepByName(names) {
|
|
|
2917
2933
|
const all = /* @__PURE__ */ new Set();
|
|
2918
2934
|
if (IS_WIN) {
|
|
2919
2935
|
const orClauses = names.map((n) => `($_.Name -like '*${n}*') -or ($_.CommandLine -like '*${n}*')`).join(" -or ");
|
|
2920
|
-
const script = `Get-CimInstance Win32_Process | Where-Object { ${orClauses} } | Select-Object -ExpandProperty ProcessId`;
|
|
2936
|
+
const script = `Get-CimInstance Win32_Process | Where-Object { $_.ProcessId -ne $PID -and (${orClauses}) } | Select-Object -ExpandProperty ProcessId`;
|
|
2921
2937
|
const r = runPowershellChecked(script);
|
|
2922
2938
|
for (const pid of r.pids) if (pid !== process.pid) all.add(pid);
|
|
2923
2939
|
return { pids: [...all], swept: r.ran };
|
|
@@ -2954,14 +2970,22 @@ function run(cmd) {
|
|
|
2954
2970
|
function runPowershell(script) {
|
|
2955
2971
|
return runPowershellChecked(script).pids;
|
|
2956
2972
|
}
|
|
2973
|
+
var PS_SENTINEL = "__deepspace_ps_ok__";
|
|
2974
|
+
function withSentinel(script) {
|
|
2975
|
+
return `$ErrorActionPreference='Stop'; try { ${script}; '${PS_SENTINEL}' } catch { }`;
|
|
2976
|
+
}
|
|
2977
|
+
function readPowershellPids(stdout) {
|
|
2978
|
+
if (!stdout.includes(PS_SENTINEL)) return { pids: [], ran: false };
|
|
2979
|
+
return { pids: parsePidLines(stdout.replace(PS_SENTINEL, "")), ran: true };
|
|
2980
|
+
}
|
|
2957
2981
|
function runPowershellChecked(script) {
|
|
2958
2982
|
const exe = pwshOrPowershell();
|
|
2959
2983
|
try {
|
|
2960
|
-
const r = spawnSync2(exe, ["-NoProfile", "-NonInteractive", "-Command", script], {
|
|
2984
|
+
const r = spawnSync2(exe, ["-NoProfile", "-NonInteractive", "-Command", withSentinel(script)], {
|
|
2961
2985
|
encoding: "utf-8"
|
|
2962
2986
|
});
|
|
2963
2987
|
if (r.error) return { pids: [], ran: false };
|
|
2964
|
-
return
|
|
2988
|
+
return readPowershellPids(r.stdout ?? "");
|
|
2965
2989
|
} catch {
|
|
2966
2990
|
return { pids: [], ran: false };
|
|
2967
2991
|
}
|
|
@@ -3026,10 +3050,10 @@ function ensurePlaywright(appDir) {
|
|
|
3026
3050
|
import { readFileSync as readFileSync14 } from "fs";
|
|
3027
3051
|
|
|
3028
3052
|
// src/testing/accounts.ts
|
|
3029
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as
|
|
3030
|
-
import { homedir as
|
|
3031
|
-
import { join as
|
|
3032
|
-
var TEST_ACCOUNTS_PATH =
|
|
3053
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync5 } from "fs";
|
|
3054
|
+
import { homedir as homedir2 } from "os";
|
|
3055
|
+
import { join as join12 } from "path";
|
|
3056
|
+
var TEST_ACCOUNTS_PATH = join12(homedir2(), ".deepspace", "test-accounts.json");
|
|
3033
3057
|
var PRODUCTION_AUTH_ORIGIN = "https://auth.deep.space";
|
|
3034
3058
|
var STAGING_AUTH_ORIGIN = "https://auth.deepspacesites.com";
|
|
3035
3059
|
function currentTestAccountScope(env = process.env) {
|
|
@@ -3115,8 +3139,8 @@ function validTestAccounts(value) {
|
|
|
3115
3139
|
);
|
|
3116
3140
|
}
|
|
3117
3141
|
function saveTestAccountStore(store) {
|
|
3118
|
-
mkdirSync5(
|
|
3119
|
-
|
|
3142
|
+
mkdirSync5(join12(homedir2(), ".deepspace"), { recursive: true });
|
|
3143
|
+
writeFileSync5(TEST_ACCOUNTS_PATH, JSON.stringify(store, null, 2), { mode: 384 });
|
|
3120
3144
|
}
|
|
3121
3145
|
|
|
3122
3146
|
// src/cli/lib/test-account-service.ts
|
|
@@ -3616,7 +3640,7 @@ var clear = defineDeepspaceCommand({
|
|
|
3616
3640
|
return { data: { deleted: 0, requested: 0, failures: [] } };
|
|
3617
3641
|
}
|
|
3618
3642
|
if (!args.yes) {
|
|
3619
|
-
if (args.json) {
|
|
3643
|
+
if (!process.stdin.isTTY || args.json) {
|
|
3620
3644
|
throw new Refusal(
|
|
3621
3645
|
"Deleting test accounts needs confirmation. Pass --yes to confirm non-interactively.",
|
|
3622
3646
|
"confirmation_required"
|
|
@@ -3845,15 +3869,15 @@ function describeFilesFailure(status3, body) {
|
|
|
3845
3869
|
import * as p6 from "@clack/prompts";
|
|
3846
3870
|
import { execSync as execSync2 } from "child_process";
|
|
3847
3871
|
import { createHash as createHash2 } from "crypto";
|
|
3848
|
-
import {
|
|
3849
|
-
import { dirname as
|
|
3872
|
+
import { existsSync as existsSync14, readFileSync as readFileSync17, readdirSync as readdirSync4 } from "fs";
|
|
3873
|
+
import { dirname as dirname7, join as join15, resolve as resolve11 } from "path";
|
|
3850
3874
|
|
|
3851
3875
|
// src/documentation/deploy.ts
|
|
3852
3876
|
import { existsSync as existsSync12, readFileSync as readFileSync15 } from "fs";
|
|
3853
|
-
import { join as
|
|
3877
|
+
import { join as join13 } from "path";
|
|
3854
3878
|
function readDocumentationDeployManifest(appDir, clientDir) {
|
|
3855
|
-
if (!existsSync12(
|
|
3856
|
-
const manifestPath =
|
|
3879
|
+
if (!existsSync12(join13(appDir, "documentation.json"))) return void 0;
|
|
3880
|
+
const manifestPath = join13(clientDir, "_documentation", "manifest.json");
|
|
3857
3881
|
if (!existsSync12(manifestPath)) {
|
|
3858
3882
|
throw new Error(
|
|
3859
3883
|
"documentation.json exists but the build produced no documentation manifest. Ensure vite.config.ts includes deepSpaceDocumentation() from deepspace/documentation."
|
|
@@ -3874,7 +3898,7 @@ import {
|
|
|
3874
3898
|
readFileSync as readFileSync16,
|
|
3875
3899
|
writeSync
|
|
3876
3900
|
} from "fs";
|
|
3877
|
-
import { join as
|
|
3901
|
+
import { join as join14 } from "path";
|
|
3878
3902
|
|
|
3879
3903
|
// src/shared/protocol/app-migrations.ts
|
|
3880
3904
|
var APP_MIGRATION_ID_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/;
|
|
@@ -3926,7 +3950,7 @@ var APP_MIGRATION_DEFINITIONS = SOURCE_MIGRATIONS.map(
|
|
|
3926
3950
|
({ id, description }) => ({ id, description })
|
|
3927
3951
|
);
|
|
3928
3952
|
function readAppliedAppMigrations(appDir) {
|
|
3929
|
-
const path =
|
|
3953
|
+
const path = join14(appDir, APP_MIGRATIONS_MANIFEST);
|
|
3930
3954
|
if (!existsSync13(path)) return [];
|
|
3931
3955
|
const source = readRegularFile(path);
|
|
3932
3956
|
let parsed;
|
|
@@ -3953,7 +3977,7 @@ function planAppMigrations(appDir) {
|
|
|
3953
3977
|
const edits = [];
|
|
3954
3978
|
for (const repoPath of tracked) {
|
|
3955
3979
|
if (!isSourcePath(repoPath, appPrefix)) continue;
|
|
3956
|
-
const absolutePath =
|
|
3980
|
+
const absolutePath = join14(repo, repoPath);
|
|
3957
3981
|
let stat;
|
|
3958
3982
|
try {
|
|
3959
3983
|
stat = lstatSync(absolutePath);
|
|
@@ -3961,7 +3985,8 @@ function planAppMigrations(appDir) {
|
|
|
3961
3985
|
continue;
|
|
3962
3986
|
}
|
|
3963
3987
|
if (!stat.isFile() || stat.isSymbolicLink()) continue;
|
|
3964
|
-
const
|
|
3988
|
+
const checkout = readRegularFile(absolutePath);
|
|
3989
|
+
const before = normalizeEol(checkout);
|
|
3965
3990
|
let after = before;
|
|
3966
3991
|
for (const migration of pendingMigrations) {
|
|
3967
3992
|
const result = migration.transform(after, repoPath);
|
|
@@ -3979,7 +4004,9 @@ function planAppMigrations(appDir) {
|
|
|
3979
4004
|
}
|
|
3980
4005
|
blockers.push(...migration.findBlockers(after, repoPath));
|
|
3981
4006
|
}
|
|
3982
|
-
if (after !== before)
|
|
4007
|
+
if (after !== before) {
|
|
4008
|
+
edits.push({ path: repoPath, before: checkout, after: restoreEol(after, checkout) });
|
|
4009
|
+
}
|
|
3983
4010
|
}
|
|
3984
4011
|
const pending = pendingMigrations.map((migration) => {
|
|
3985
4012
|
const planned = perMigration.get(migration.id);
|
|
@@ -3987,7 +4014,7 @@ function planAppMigrations(appDir) {
|
|
|
3987
4014
|
});
|
|
3988
4015
|
if (pending.length > 0 && blockers.length === 0) {
|
|
3989
4016
|
const manifestPath = `${appPrefix}${APP_MIGRATIONS_MANIFEST}`;
|
|
3990
|
-
const absoluteManifestPath =
|
|
4017
|
+
const absoluteManifestPath = join14(repo, manifestPath);
|
|
3991
4018
|
const before = existsSync13(absoluteManifestPath) ? readRegularFile(absoluteManifestPath) : null;
|
|
3992
4019
|
const after = `${JSON.stringify([...appliedIds, ...pending.map(({ id }) => id)], null, 2)}
|
|
3993
4020
|
`;
|
|
@@ -4003,13 +4030,19 @@ function planAppMigrations(appDir) {
|
|
|
4003
4030
|
function applyAppMigrationPlan(appDir, plan) {
|
|
4004
4031
|
const repo = repoToplevel(appDir);
|
|
4005
4032
|
for (const edit of plan.edits) {
|
|
4006
|
-
const absolutePath =
|
|
4033
|
+
const absolutePath = join14(repo, edit.path);
|
|
4007
4034
|
const current = existsSync13(absolutePath) ? readRegularFile(absolutePath) : null;
|
|
4008
4035
|
if (current !== edit.before) {
|
|
4009
4036
|
throw new Error(`Migration input changed after planning: ${edit.path}`);
|
|
4010
4037
|
}
|
|
4011
4038
|
}
|
|
4012
|
-
for (const edit of plan.edits) writeRegularFile(
|
|
4039
|
+
for (const edit of plan.edits) writeRegularFile(join14(repo, edit.path), edit.before, edit.after);
|
|
4040
|
+
}
|
|
4041
|
+
function normalizeEol(source) {
|
|
4042
|
+
return source.replaceAll("\r\n", "\n");
|
|
4043
|
+
}
|
|
4044
|
+
function restoreEol(source, checkout) {
|
|
4045
|
+
return checkout.includes("\r\n") ? source.replaceAll("\n", "\r\n") : source;
|
|
4013
4046
|
}
|
|
4014
4047
|
function readRegularFile(path) {
|
|
4015
4048
|
const before = lstatSync(path);
|
|
@@ -4161,6 +4194,7 @@ ${SECURE_JOB_ROOM_CONSTRUCTOR}`
|
|
|
4161
4194
|
]
|
|
4162
4195
|
];
|
|
4163
4196
|
var HTTP_ROLE_IMPORT = `import { resolveAppRole } from 'deepspace/worker'`;
|
|
4197
|
+
var HTTP_ROLE_IMPORT_PATTERN = /\bimport\s*\{[^}]*\bresolveAppRole\b[^}]*\}\s*from\s*(['"])deepspace\/worker\1/;
|
|
4164
4198
|
var HTTP_ROLE_IMPORT_SEAM = `import type { AppContext, Env } from '../../worker.js'`;
|
|
4165
4199
|
var DEBUG_ROUTE_SEAM = ` app.all('/api/debug/*', async (c) => {
|
|
4166
4200
|
if (c.env.ALLOW_DEBUG_ROUTES !== 'true') {
|
|
@@ -4199,8 +4233,11 @@ function secureDebugRouteOccurrences(source) {
|
|
|
4199
4233
|
0
|
|
4200
4234
|
);
|
|
4201
4235
|
}
|
|
4236
|
+
function httpRoleImportOccurrences(source) {
|
|
4237
|
+
return source.match(new RegExp(HTTP_ROLE_IMPORT_PATTERN.source, "g"))?.length ?? 0;
|
|
4238
|
+
}
|
|
4202
4239
|
function hasSecureDebugRoute(source) {
|
|
4203
|
-
return debugRouteOccurrences(source) === 1 && secureDebugRouteOccurrences(source) === 1 &&
|
|
4240
|
+
return debugRouteOccurrences(source) === 1 && secureDebugRouteOccurrences(source) === 1 && httpRoleImportOccurrences(source) === 1;
|
|
4204
4241
|
}
|
|
4205
4242
|
function migrateSecureRoomBoundaries(source, file) {
|
|
4206
4243
|
if (file.endsWith("src/server/realtime-routes.ts")) {
|
|
@@ -4243,7 +4280,7 @@ function migrateDebugRouteAuthorization(source) {
|
|
|
4243
4280
|
const matchingRoutes = DEBUG_ROUTE_REPLACEMENTS.filter(
|
|
4244
4281
|
([before2]) => occurrences(source, before2) === 1
|
|
4245
4282
|
);
|
|
4246
|
-
if (debugRouteOccurrences(source) !== 1 || matchingRoutes.length !== 1 ||
|
|
4283
|
+
if (debugRouteOccurrences(source) !== 1 || matchingRoutes.length !== 1 || httpRoleImportOccurrences(source) !== 0 || occurrences(source, HTTP_ROLE_IMPORT_SEAM) !== 1) {
|
|
4247
4284
|
return { source, replacements: 0 };
|
|
4248
4285
|
}
|
|
4249
4286
|
const [before, after] = matchingRoutes[0];
|
|
@@ -4357,7 +4394,9 @@ function findWorkerOwnedNotFoundBlockers(source, file) {
|
|
|
4357
4394
|
const blockers = [];
|
|
4358
4395
|
const lines = source.split("\n");
|
|
4359
4396
|
for (const [index, line] of lines.entries()) {
|
|
4360
|
-
if (!/['"`]\/index\.html/.test(line))
|
|
4397
|
+
if (!/(?:\burl\.pathname\s*=\s*|\bnew\s+URL\s*\(\s*)['"`]\/index\.html/.test(line)) {
|
|
4398
|
+
continue;
|
|
4399
|
+
}
|
|
4361
4400
|
blockers.push({
|
|
4362
4401
|
migrationId: WORKER_OWNED_NOT_FOUND_MIGRATION_ID,
|
|
4363
4402
|
file,
|
|
@@ -4370,16 +4409,6 @@ function findWorkerOwnedNotFoundBlockers(source, file) {
|
|
|
4370
4409
|
|
|
4371
4410
|
// src/cli/commands/deploy/build.ts
|
|
4372
4411
|
var RESERVED_RUN_WORKER_FIRST2 = new Set(RESERVED_RUN_WORKER_FIRST);
|
|
4373
|
-
function secureBuildDevVars(workerDir) {
|
|
4374
|
-
const path = join16(workerDir, ".dev.vars");
|
|
4375
|
-
if (!existsSync14(path)) return false;
|
|
4376
|
-
const stat = lstatSync2(path);
|
|
4377
|
-
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4378
|
-
throw new Error(`Refusing unsafe build secret path: ${path}`);
|
|
4379
|
-
}
|
|
4380
|
-
chmodSync2(path, 384);
|
|
4381
|
-
return true;
|
|
4382
|
-
}
|
|
4383
4412
|
function declaredCompatibilityDate(config) {
|
|
4384
4413
|
const declared = config.compatibility_date;
|
|
4385
4414
|
return typeof declared === "string" && /^\d{4}-\d{2}-\d{2}$/.test(declared) ? declared : null;
|
|
@@ -4415,7 +4444,7 @@ async function buildDeployBundle(options) {
|
|
|
4415
4444
|
preparedWranglerConfig?.cleanup();
|
|
4416
4445
|
}
|
|
4417
4446
|
spinner2.stop("Built");
|
|
4418
|
-
const deployConfigPath =
|
|
4447
|
+
const deployConfigPath = join15(appDir, ".wrangler", "deploy", "config.json");
|
|
4419
4448
|
if (!existsSync14(deployConfigPath)) {
|
|
4420
4449
|
output.die(
|
|
4421
4450
|
"Build output config not found at .wrangler/deploy/config.json",
|
|
@@ -4423,7 +4452,7 @@ async function buildDeployBundle(options) {
|
|
|
4423
4452
|
);
|
|
4424
4453
|
}
|
|
4425
4454
|
const deployConfig = JSON.parse(readFileSync17(deployConfigPath, "utf-8"));
|
|
4426
|
-
const outputWranglerPath = resolve11(
|
|
4455
|
+
const outputWranglerPath = resolve11(dirname7(deployConfigPath), deployConfig.configPath);
|
|
4427
4456
|
if (!existsSync14(outputWranglerPath)) {
|
|
4428
4457
|
output.die(`Output wrangler.json not found at ${outputWranglerPath}`, "build_output_missing");
|
|
4429
4458
|
}
|
|
@@ -4435,13 +4464,8 @@ async function buildDeployBundle(options) {
|
|
|
4435
4464
|
"build_output_mismatch"
|
|
4436
4465
|
);
|
|
4437
4466
|
}
|
|
4438
|
-
const workerDir =
|
|
4439
|
-
|
|
4440
|
-
secureBuildDevVars(workerDir);
|
|
4441
|
-
} catch (error) {
|
|
4442
|
-
output.die(errorMessage(error), "build_output_unsafe");
|
|
4443
|
-
}
|
|
4444
|
-
const workerBundlePath = join16(workerDir, outputConfig.main);
|
|
4467
|
+
const workerDir = dirname7(outputWranglerPath);
|
|
4468
|
+
const workerBundlePath = join15(workerDir, outputConfig.main);
|
|
4445
4469
|
const clientDir = outputConfig.assets?.directory ? resolve11(workerDir, outputConfig.assets.directory) : null;
|
|
4446
4470
|
if (!existsSync14(workerBundlePath)) {
|
|
4447
4471
|
output.die(`Worker bundle not found at ${workerBundlePath}`, "build_output_missing");
|
|
@@ -4533,7 +4557,7 @@ function collectAssets(dir) {
|
|
|
4533
4557
|
const walk = (currentDir, prefix) => {
|
|
4534
4558
|
for (const entry of readdirSync4(currentDir, { withFileTypes: true })) {
|
|
4535
4559
|
if (isDeployAssetControlFile(entry.name)) continue;
|
|
4536
|
-
const fullPath =
|
|
4560
|
+
const fullPath = join15(currentDir, entry.name);
|
|
4537
4561
|
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
4538
4562
|
if (entry.isDirectory()) {
|
|
4539
4563
|
walk(fullPath, relativePath);
|
|
@@ -4557,7 +4581,7 @@ function readDeployAssetConfig(clientDir) {
|
|
|
4557
4581
|
["_headers", "_headers"],
|
|
4558
4582
|
["_redirects", "_redirects"]
|
|
4559
4583
|
]) {
|
|
4560
|
-
const filePath =
|
|
4584
|
+
const filePath = join15(clientDir, file);
|
|
4561
4585
|
if (!existsSync14(filePath)) continue;
|
|
4562
4586
|
const content = readFileSync17(filePath, "utf8");
|
|
4563
4587
|
if (content.trim()) config[key] = content;
|
|
@@ -4574,17 +4598,17 @@ function errorMessage(error) {
|
|
|
4574
4598
|
// src/cli/commands/deploy/commerce.ts
|
|
4575
4599
|
import * as p7 from "@clack/prompts";
|
|
4576
4600
|
import { existsSync as existsSync15 } from "fs";
|
|
4577
|
-
import { join as
|
|
4601
|
+
import { join as join16 } from "path";
|
|
4578
4602
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
4579
4603
|
var API_URL2 = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api;
|
|
4580
4604
|
function errorMessage2(error) {
|
|
4581
4605
|
return error instanceof Error ? error.message : String(error);
|
|
4582
4606
|
}
|
|
4583
4607
|
async function loadDeclaration(appDir, sourceFile, outputFile, exportName) {
|
|
4584
|
-
const sourcePath =
|
|
4608
|
+
const sourcePath = join16(appDir, "src", sourceFile);
|
|
4585
4609
|
if (!existsSync15(sourcePath)) return void 0;
|
|
4586
4610
|
const esbuild = await import("esbuild");
|
|
4587
|
-
const outputPath =
|
|
4611
|
+
const outputPath = join16(appDir, ".wrangler", "deploy", outputFile);
|
|
4588
4612
|
await esbuild.build({
|
|
4589
4613
|
entryPoints: [sourcePath],
|
|
4590
4614
|
bundle: true,
|
|
@@ -4677,7 +4701,7 @@ Stripe will keep charging them until you cancel. Cancel at the end of their curr
|
|
|
4677
4701
|
}
|
|
4678
4702
|
}
|
|
4679
4703
|
async function syncSubscriptionPlans(appDir, appName, token, nonInteractive) {
|
|
4680
|
-
if (!existsSync15(
|
|
4704
|
+
if (!existsSync15(join16(appDir, "src", "subscriptions.ts"))) return;
|
|
4681
4705
|
let plans;
|
|
4682
4706
|
try {
|
|
4683
4707
|
plans = await loadDeclaration(
|
|
@@ -4732,7 +4756,7 @@ async function syncSubscriptionPlans(appDir, appName, token, nonInteractive) {
|
|
|
4732
4756
|
}
|
|
4733
4757
|
}
|
|
4734
4758
|
async function syncOneTimeProducts(appDir, appName, token) {
|
|
4735
|
-
if (!existsSync15(
|
|
4759
|
+
if (!existsSync15(join16(appDir, "src", "products.ts"))) return;
|
|
4736
4760
|
let products;
|
|
4737
4761
|
try {
|
|
4738
4762
|
products = await loadDeclaration(
|
|
@@ -4827,7 +4851,7 @@ function createDeployOutput(json) {
|
|
|
4827
4851
|
else console.error(withSlug(message, code));
|
|
4828
4852
|
if (action) printAction(action);
|
|
4829
4853
|
}
|
|
4830
|
-
|
|
4854
|
+
throw new CliExit(opts.actionRequired ? 2 : 1);
|
|
4831
4855
|
}
|
|
4832
4856
|
};
|
|
4833
4857
|
}
|
|
@@ -5556,6 +5580,7 @@ async function syncDeployRepository(options) {
|
|
|
5556
5580
|
sourceRevision = claimed.revision;
|
|
5557
5581
|
}
|
|
5558
5582
|
} catch (error) {
|
|
5583
|
+
if (error instanceof CliExit) throw error;
|
|
5559
5584
|
const failure = deployRepositoryFailure(error, appDir);
|
|
5560
5585
|
output.die(failure.error, failure.code);
|
|
5561
5586
|
}
|
|
@@ -5672,7 +5697,7 @@ async function deployBuiltBundle(options) {
|
|
|
5672
5697
|
...action ? { action } : {}
|
|
5673
5698
|
});
|
|
5674
5699
|
}
|
|
5675
|
-
|
|
5700
|
+
throw new CliExit(actionRequired ? 2 : 1);
|
|
5676
5701
|
};
|
|
5677
5702
|
const makeForm = () => {
|
|
5678
5703
|
const form = new FormData();
|
|
@@ -6583,6 +6608,7 @@ var apps_default = defineDeepspaceCommand({
|
|
|
6583
6608
|
|
|
6584
6609
|
// src/cli/commands/logs.ts
|
|
6585
6610
|
import { defineCommand as defineCommand4 } from "citty";
|
|
6611
|
+
import { setTimeout as delay } from "timers/promises";
|
|
6586
6612
|
|
|
6587
6613
|
// src/shared/log-events.ts
|
|
6588
6614
|
var LOG_LEVELS = ["debug", "log", "info", "warn", "error"];
|
|
@@ -6693,7 +6719,7 @@ function formatEvent(e, color, now = Date.now()) {
|
|
|
6693
6719
|
const client = e.source === "client" ? paint("35", "CLIENT", color) + " " : "";
|
|
6694
6720
|
return `${time} ${client}${tag} ${body}`;
|
|
6695
6721
|
}
|
|
6696
|
-
var sleep3 = (ms) =>
|
|
6722
|
+
var sleep3 = (ms, signal) => delay(ms, void 0, { signal });
|
|
6697
6723
|
var logs_default = defineCommand4({
|
|
6698
6724
|
meta: {
|
|
6699
6725
|
name: "logs",
|
|
@@ -6769,12 +6795,17 @@ var logs_default = defineCommand4({
|
|
|
6769
6795
|
const windowLabel = args.since?.trim() || "15m";
|
|
6770
6796
|
const MAX_LIMIT = 500;
|
|
6771
6797
|
const followLimit = followInitialLimit(limit, MAX_LIMIT);
|
|
6772
|
-
const fetchPage = async (since, pageLimit, token2) => {
|
|
6798
|
+
const fetchPage = async (since, pageLimit, token2, signal) => {
|
|
6773
6799
|
const params = new URLSearchParams({ since: String(since) });
|
|
6774
6800
|
if (pageLimit !== void 0) params.set("limit", String(pageLimit));
|
|
6775
6801
|
if (args.level) params.set("level", args.level);
|
|
6776
6802
|
if (args.search) params.set("search", args.search);
|
|
6777
|
-
return apiFetch(
|
|
6803
|
+
return apiFetch(
|
|
6804
|
+
DEPLOY_URL6,
|
|
6805
|
+
token2,
|
|
6806
|
+
`/api/apps/${appId}/logs?${params}`,
|
|
6807
|
+
signal ? { signal } : void 0
|
|
6808
|
+
);
|
|
6778
6809
|
};
|
|
6779
6810
|
const print = (events) => {
|
|
6780
6811
|
for (const e of events) {
|
|
@@ -6810,7 +6841,8 @@ var logs_default = defineCommand4({
|
|
|
6810
6841
|
}
|
|
6811
6842
|
return;
|
|
6812
6843
|
}
|
|
6813
|
-
|
|
6844
|
+
const tail = new AbortController();
|
|
6845
|
+
process.once("SIGINT", () => tail.abort());
|
|
6814
6846
|
if (!args.json) {
|
|
6815
6847
|
console.error(`Tailing logs for ${appId} \u2014 Ctrl+C to stop.`);
|
|
6816
6848
|
}
|
|
@@ -6835,12 +6867,23 @@ var logs_default = defineCommand4({
|
|
|
6835
6867
|
}
|
|
6836
6868
|
}
|
|
6837
6869
|
for (; ; ) {
|
|
6838
|
-
|
|
6870
|
+
try {
|
|
6871
|
+
await sleep3(backoff || interval, tail.signal);
|
|
6872
|
+
} catch {
|
|
6873
|
+
return;
|
|
6874
|
+
}
|
|
6839
6875
|
const freshToken = await ensureToken();
|
|
6876
|
+
if (tail.signal.aborted) return;
|
|
6840
6877
|
let page;
|
|
6841
6878
|
try {
|
|
6842
|
-
page = await fetchPage(
|
|
6879
|
+
page = await fetchPage(
|
|
6880
|
+
nextPollSince(cursor, initialSince),
|
|
6881
|
+
followLimit,
|
|
6882
|
+
freshToken,
|
|
6883
|
+
tail.signal
|
|
6884
|
+
);
|
|
6843
6885
|
} catch (err) {
|
|
6886
|
+
if (tail.signal.aborted) return;
|
|
6844
6887
|
if (err instanceof ApiError && [401, 403, 404].includes(err.status)) throw err;
|
|
6845
6888
|
backoff = Math.min(backoff ? backoff * 2 : MIN_POLL_MS, 3e4);
|
|
6846
6889
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -6946,7 +6989,7 @@ var usage_default = defineDeepspaceCommand({
|
|
|
6946
6989
|
|
|
6947
6990
|
// src/cli/commands/add.ts
|
|
6948
6991
|
import { existsSync as existsSync18, readFileSync as readFileSync20, realpathSync as realpathSync4 } from "fs";
|
|
6949
|
-
import { dirname as
|
|
6992
|
+
import { dirname as dirname9, join as join18, resolve as resolve15 } from "path";
|
|
6950
6993
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
6951
6994
|
|
|
6952
6995
|
// src/cli/commands/feature-installer.ts
|
|
@@ -6962,17 +7005,17 @@ import {
|
|
|
6962
7005
|
readSync,
|
|
6963
7006
|
readdirSync as readdirSync5,
|
|
6964
7007
|
rmSync as rmSync4,
|
|
6965
|
-
writeFileSync as
|
|
7008
|
+
writeFileSync as writeFileSync6
|
|
6966
7009
|
} from "fs";
|
|
6967
7010
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
6968
7011
|
import { tmpdir as tmpdir2 } from "os";
|
|
6969
|
-
import { dirname as
|
|
7012
|
+
import { dirname as dirname8, isAbsolute as isAbsolute4, join as join17, resolve as resolve14 } from "path";
|
|
6970
7013
|
import { fileURLToPath } from "url";
|
|
6971
7014
|
var NAV_MARKER = "// \u2500\u2500 Features add nav items below this line \u2500\u2500";
|
|
6972
7015
|
function featurePackageRoot(moduleUrl = import.meta.url) {
|
|
6973
|
-
let dir =
|
|
7016
|
+
let dir = dirname8(fileURLToPath(moduleUrl));
|
|
6974
7017
|
for (; ; ) {
|
|
6975
|
-
const packagePath =
|
|
7018
|
+
const packagePath = join17(dir, "package.json");
|
|
6976
7019
|
if (existsSync17(packagePath)) {
|
|
6977
7020
|
try {
|
|
6978
7021
|
const pkg2 = JSON.parse(readFileSync19(packagePath, "utf-8"));
|
|
@@ -6980,16 +7023,16 @@ function featurePackageRoot(moduleUrl = import.meta.url) {
|
|
|
6980
7023
|
} catch {
|
|
6981
7024
|
}
|
|
6982
7025
|
}
|
|
6983
|
-
const parent =
|
|
7026
|
+
const parent = dirname8(dir);
|
|
6984
7027
|
if (parent === dir) throw new Error("Could not locate the deepspace package root");
|
|
6985
7028
|
dir = parent;
|
|
6986
7029
|
}
|
|
6987
7030
|
}
|
|
6988
7031
|
function hasFeatureCatalog(packageRoot = featurePackageRoot()) {
|
|
6989
|
-
return existsSync17(
|
|
7032
|
+
return existsSync17(join17(packageRoot, "features"));
|
|
6990
7033
|
}
|
|
6991
7034
|
function readFeatureConfig(id, packageRoot = featurePackageRoot()) {
|
|
6992
|
-
const configPath =
|
|
7035
|
+
const configPath = join17(packageRoot, "features", id, "feature.json");
|
|
6993
7036
|
if (!existsSync17(configPath)) return null;
|
|
6994
7037
|
try {
|
|
6995
7038
|
const config = JSON.parse(readFileSync19(configPath, "utf-8"));
|
|
@@ -7002,7 +7045,7 @@ function readFeatureConfig(id, packageRoot = featurePackageRoot()) {
|
|
|
7002
7045
|
}
|
|
7003
7046
|
}
|
|
7004
7047
|
function listFeatureConfigs(packageRoot = featurePackageRoot()) {
|
|
7005
|
-
const featuresDir =
|
|
7048
|
+
const featuresDir = join17(packageRoot, "features");
|
|
7006
7049
|
if (!existsSync17(featuresDir)) return [];
|
|
7007
7050
|
return readdirSync5(featuresDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => readFeatureConfig(entry.name, packageRoot)).filter((config) => config !== null && !config.internal).sort((a, b) => a.id.localeCompare(b.id));
|
|
7008
7051
|
}
|
|
@@ -7051,17 +7094,17 @@ function resolveFeatureDestPath(fileDest, route) {
|
|
|
7051
7094
|
return route?.protected === false ? `${appPages}${rest}` : `${appPages}(protected)/${rest}`;
|
|
7052
7095
|
}
|
|
7053
7096
|
function copyFile(src, dest) {
|
|
7054
|
-
mkdirSync6(
|
|
7097
|
+
mkdirSync6(dirname8(dest), { recursive: true });
|
|
7055
7098
|
copyFileSync(src, dest);
|
|
7056
7099
|
}
|
|
7057
7100
|
function copyFileWithImportShift(src, dest, levels) {
|
|
7058
|
-
mkdirSync6(
|
|
7101
|
+
mkdirSync6(dirname8(dest), { recursive: true });
|
|
7059
7102
|
const prefix = "../".repeat(levels);
|
|
7060
7103
|
const shifted = readFileSync19(src, "utf-8").replace(
|
|
7061
7104
|
/(from\s+|import\s+|import\()(['"])(\.\.\/)/g,
|
|
7062
7105
|
`$1$2${prefix}$3`
|
|
7063
7106
|
);
|
|
7064
|
-
|
|
7107
|
+
writeFileSync6(dest, shifted);
|
|
7065
7108
|
}
|
|
7066
7109
|
function installFiles(packageRoot, config, targetDir, emit) {
|
|
7067
7110
|
let copied = 0;
|
|
@@ -7070,9 +7113,9 @@ function installFiles(packageRoot, config, targetDir, emit) {
|
|
|
7070
7113
|
const preexisting = [];
|
|
7071
7114
|
const missing = [];
|
|
7072
7115
|
for (const file of config.files) {
|
|
7073
|
-
const srcPath =
|
|
7116
|
+
const srcPath = join17(packageRoot, "features", config.id, file.src);
|
|
7074
7117
|
const resolvedDest = resolveFeatureDestPath(file.dest, config.route);
|
|
7075
|
-
const destPath =
|
|
7118
|
+
const destPath = join17(targetDir, resolvedDest);
|
|
7076
7119
|
const existed = existsSync17(destPath);
|
|
7077
7120
|
if (existed) preexisting.push(resolvedDest);
|
|
7078
7121
|
if (!existsSync17(srcPath)) {
|
|
@@ -7112,7 +7155,7 @@ function unresolvedSchema(schema, reason, emit) {
|
|
|
7112
7155
|
}
|
|
7113
7156
|
function integrateSchema(config, targetDir, emit) {
|
|
7114
7157
|
if (!config.schema) return [];
|
|
7115
|
-
const schemasPath =
|
|
7158
|
+
const schemasPath = join17(targetDir, "src", "schemas.ts");
|
|
7116
7159
|
if (!existsSync17(schemasPath)) {
|
|
7117
7160
|
return [unresolvedSchema(config.schema, "src/schemas.ts was not found.", emit)];
|
|
7118
7161
|
}
|
|
@@ -7147,7 +7190,7 @@ export const schemas`
|
|
|
7147
7190
|
return [unresolvedSchema(config.schema, reason, emit)];
|
|
7148
7191
|
}
|
|
7149
7192
|
content = withEntry;
|
|
7150
|
-
|
|
7193
|
+
writeFileSync6(schemasPath, content);
|
|
7151
7194
|
emit(` Schema integrated: ${exportName} -> schemas.ts`);
|
|
7152
7195
|
return [];
|
|
7153
7196
|
}
|
|
@@ -7169,7 +7212,7 @@ function unresolvedActions(actions, reason, emit) {
|
|
|
7169
7212
|
}
|
|
7170
7213
|
function integrateActions(config, targetDir, emit) {
|
|
7171
7214
|
if (!config.actions?.length) return [];
|
|
7172
|
-
const actionsPath =
|
|
7215
|
+
const actionsPath = join17(targetDir, "src", "actions", "index.ts");
|
|
7173
7216
|
if (!existsSync17(actionsPath)) {
|
|
7174
7217
|
return [unresolvedActions(config.actions, "src/actions/index.ts was not found.", emit)];
|
|
7175
7218
|
}
|
|
@@ -7213,13 +7256,13 @@ ${registryEntry}`);
|
|
|
7213
7256
|
integrated++;
|
|
7214
7257
|
emit(` Action integrated: ${action.registerAs} (${action.exportName})`);
|
|
7215
7258
|
}
|
|
7216
|
-
if (integrated > 0)
|
|
7259
|
+
if (integrated > 0) writeFileSync6(actionsPath, content);
|
|
7217
7260
|
return unresolved;
|
|
7218
7261
|
}
|
|
7219
7262
|
function integrateCode(config, targetDir, emit) {
|
|
7220
7263
|
const unresolved = [];
|
|
7221
7264
|
for (const insertion of config.code ?? []) {
|
|
7222
|
-
const targetPath =
|
|
7265
|
+
const targetPath = join17(targetDir, insertion.file);
|
|
7223
7266
|
if (!existsSync17(targetPath)) {
|
|
7224
7267
|
unresolved.push({
|
|
7225
7268
|
area: "code",
|
|
@@ -7256,27 +7299,27 @@ ${content.slice(importIndex < 0 ? 0 : importIndex)}`;
|
|
|
7256
7299
|
const prefix = insertion.placement === "before" ? "" : "\n";
|
|
7257
7300
|
const suffix = insertion.placement === "before" ? "\n" : "";
|
|
7258
7301
|
content = `${content.slice(0, insertAt)}${prefix}${insertion.insert}${suffix}${content.slice(insertAt)}`;
|
|
7259
|
-
|
|
7302
|
+
writeFileSync6(targetPath, content);
|
|
7260
7303
|
emit(` Integrated: ${insertion.file}`);
|
|
7261
7304
|
}
|
|
7262
7305
|
return unresolved;
|
|
7263
7306
|
}
|
|
7264
7307
|
function integrateIgnore(config, targetDir) {
|
|
7265
7308
|
if (!config.ignore?.length) return;
|
|
7266
|
-
const targetPath =
|
|
7309
|
+
const targetPath = join17(targetDir, ".gitignore");
|
|
7267
7310
|
const current = existsSync17(targetPath) ? readFileSync19(targetPath, "utf-8") : "";
|
|
7268
7311
|
const present = new Set(current.split(/\r?\n/).map((line) => line.trim()));
|
|
7269
7312
|
const missing = config.ignore.filter((pattern) => !present.has(pattern));
|
|
7270
7313
|
if (missing.length === 0) return;
|
|
7271
7314
|
const separator = current === "" || current.endsWith("\n") ? "" : "\n";
|
|
7272
|
-
|
|
7315
|
+
writeFileSync6(targetPath, `${current}${separator}${missing.join("\n")}
|
|
7273
7316
|
`);
|
|
7274
7317
|
}
|
|
7275
7318
|
function integrateWrangler(config, targetDir, emit) {
|
|
7276
7319
|
const runWorkerFirst = config.wrangler?.runWorkerFirst === true;
|
|
7277
7320
|
const rateLimits = config.wrangler?.rateLimits ?? [];
|
|
7278
7321
|
if (!runWorkerFirst && rateLimits.length === 0) return [];
|
|
7279
|
-
const targetPath =
|
|
7322
|
+
const targetPath = join17(targetDir, "wrangler.toml");
|
|
7280
7323
|
const steps = [
|
|
7281
7324
|
...runWorkerFirst ? ["Set assets.run_worker_first = true in wrangler.toml."] : [],
|
|
7282
7325
|
...rateLimits.map((binding) => `Add the ${binding.name} rate-limit binding to wrangler.toml.`)
|
|
@@ -7306,7 +7349,7 @@ ${rateLimitBindingBlock(scope, binding)}
|
|
|
7306
7349
|
}
|
|
7307
7350
|
}
|
|
7308
7351
|
if (changed) {
|
|
7309
|
-
|
|
7352
|
+
writeFileSync6(targetPath, source);
|
|
7310
7353
|
emit(" Integrated: wrangler.toml");
|
|
7311
7354
|
} else emit(" Integration already present: wrangler.toml");
|
|
7312
7355
|
return [];
|
|
@@ -7360,7 +7403,7 @@ function rateLimitBindingBlock(scope, binding) {
|
|
|
7360
7403
|
}
|
|
7361
7404
|
function integrateCss(packageRoot, config, targetDir, emit) {
|
|
7362
7405
|
if (!config.css?.length) return [];
|
|
7363
|
-
const stylesPath =
|
|
7406
|
+
const stylesPath = join17(targetDir, "src", "styles.css");
|
|
7364
7407
|
if (!existsSync17(stylesPath)) {
|
|
7365
7408
|
emit(" Warning: Cannot integrate CSS \u2014 src/styles.css not found");
|
|
7366
7409
|
return [
|
|
@@ -7377,7 +7420,7 @@ function integrateCss(packageRoot, config, targetDir, emit) {
|
|
|
7377
7420
|
let integrated = 0;
|
|
7378
7421
|
const unresolved = [];
|
|
7379
7422
|
for (const cssFile of config.css) {
|
|
7380
|
-
const srcPath =
|
|
7423
|
+
const srcPath = join17(packageRoot, "features", config.id, cssFile);
|
|
7381
7424
|
if (!existsSync17(srcPath)) {
|
|
7382
7425
|
emit(` Warning: CSS source not found: ${cssFile}`, "stderr");
|
|
7383
7426
|
unresolved.push({
|
|
@@ -7399,7 +7442,7 @@ ${css}`;
|
|
|
7399
7442
|
integrated++;
|
|
7400
7443
|
emit(` CSS integrated: ${cssFile} -> styles.css`);
|
|
7401
7444
|
}
|
|
7402
|
-
if (integrated > 0)
|
|
7445
|
+
if (integrated > 0) writeFileSync6(stylesPath, styles);
|
|
7403
7446
|
return unresolved;
|
|
7404
7447
|
}
|
|
7405
7448
|
function unresolvedRoute(route, config, reason, emit) {
|
|
@@ -7414,7 +7457,7 @@ function unresolvedRoute(route, config, reason, emit) {
|
|
|
7414
7457
|
}
|
|
7415
7458
|
function integrateRoute(config, targetDir, emit) {
|
|
7416
7459
|
if (!config.route) return [];
|
|
7417
|
-
const navPath =
|
|
7460
|
+
const navPath = join17(targetDir, "src", "nav.ts");
|
|
7418
7461
|
if (!existsSync17(navPath)) {
|
|
7419
7462
|
return [unresolvedRoute(config.route, config, "src/nav.ts was not found.", emit)];
|
|
7420
7463
|
}
|
|
@@ -7439,7 +7482,7 @@ function integrateRoute(config, targetDir, emit) {
|
|
|
7439
7482
|
const entry = ` { path: '${routePath}', label: '${config.name}'${roles} },`;
|
|
7440
7483
|
content = content.replace(NAV_MARKER, `${NAV_MARKER}
|
|
7441
7484
|
${entry}`);
|
|
7442
|
-
|
|
7485
|
+
writeFileSync6(navPath, content);
|
|
7443
7486
|
emit(` Nav wired: ${routePath} (${config.name})`);
|
|
7444
7487
|
emit(" Route: automatic (file-based routing via src/pages/)");
|
|
7445
7488
|
return [];
|
|
@@ -7465,10 +7508,10 @@ function runPackageInstall(packageManager, targetDir, outputVisible) {
|
|
|
7465
7508
|
const child = spawnSync6(packageManager, ["install"], { ...options, stdio: "inherit" });
|
|
7466
7509
|
return { error: child.error, status: child.status };
|
|
7467
7510
|
}
|
|
7468
|
-
const captureDir = mkdtempSync(
|
|
7511
|
+
const captureDir = mkdtempSync(join17(tmpdir2(), "deepspace-add-install-"));
|
|
7469
7512
|
let outputFd;
|
|
7470
7513
|
try {
|
|
7471
|
-
outputFd = openSync2(
|
|
7514
|
+
outputFd = openSync2(join17(captureDir, "output.log"), "w+");
|
|
7472
7515
|
const child = spawnSync6(packageManager, ["install"], {
|
|
7473
7516
|
...options,
|
|
7474
7517
|
stdio: ["ignore", outputFd, outputFd]
|
|
@@ -7492,7 +7535,7 @@ function integrateDependencies(config, targetDir, runInstall, outputVisible, emi
|
|
|
7492
7535
|
if (declarations.every(({ values }) => !values || Object.keys(values).length === 0)) {
|
|
7493
7536
|
return { added: [], installRan: false, packageManager };
|
|
7494
7537
|
}
|
|
7495
|
-
const packagePath =
|
|
7538
|
+
const packagePath = join17(targetDir, "package.json");
|
|
7496
7539
|
if (!existsSync17(packagePath)) {
|
|
7497
7540
|
emit(" Could not patch package.json (file not found)");
|
|
7498
7541
|
return { added: [], installRan: false, packageManager };
|
|
@@ -7523,7 +7566,7 @@ function integrateDependencies(config, targetDir, runInstall, outputVisible, emi
|
|
|
7523
7566
|
if (added.length === 0) {
|
|
7524
7567
|
emit(" Dependencies already present");
|
|
7525
7568
|
} else {
|
|
7526
|
-
|
|
7569
|
+
writeFileSync6(packagePath, `${JSON.stringify(pkg2, null, 2)}
|
|
7527
7570
|
`, "utf-8");
|
|
7528
7571
|
emit(` Added to package.json: ${added.map(({ name }) => name).join(", ")}`);
|
|
7529
7572
|
if (skipped.length) emit(` Already present (kept your version): ${skipped.join(", ")}`);
|
|
@@ -7559,7 +7602,7 @@ ${child.diagnosticTail}` : "";
|
|
|
7559
7602
|
}
|
|
7560
7603
|
function dependencySnapshot(targetDir) {
|
|
7561
7604
|
try {
|
|
7562
|
-
const pkg2 = JSON.parse(readFileSync19(
|
|
7605
|
+
const pkg2 = JSON.parse(readFileSync19(join17(targetDir, "package.json"), "utf-8"));
|
|
7563
7606
|
return {
|
|
7564
7607
|
dependencies: pkg2.dependencies ?? {},
|
|
7565
7608
|
devDependencies: pkg2.devDependencies ?? {}
|
|
@@ -7571,7 +7614,7 @@ function dependencySnapshot(targetDir) {
|
|
|
7571
7614
|
function installedNavFeatures(packageRoot, targetDir) {
|
|
7572
7615
|
return listFeatureConfigs(packageRoot).filter((feature) => feature.category === "nav" && feature.files.length > 0).filter((feature) => {
|
|
7573
7616
|
const signature = resolveFeatureDestPath(feature.files[0].dest, feature.route);
|
|
7574
|
-
return existsSync17(
|
|
7617
|
+
return existsSync17(join17(targetDir, signature));
|
|
7575
7618
|
}).map((feature) => feature.id);
|
|
7576
7619
|
}
|
|
7577
7620
|
function warnNavConflicts(packageRoot, config, targetDir, emit) {
|
|
@@ -7804,8 +7847,8 @@ function renderFeatureInfo(config) {
|
|
|
7804
7847
|
return lines.join("\n");
|
|
7805
7848
|
}
|
|
7806
7849
|
function isDeepSpaceApp(dir) {
|
|
7807
|
-
if (existsSync18(
|
|
7808
|
-
const packagePath =
|
|
7850
|
+
if (existsSync18(join18(dir, "wrangler.toml"))) return true;
|
|
7851
|
+
const packagePath = join18(dir, "package.json");
|
|
7809
7852
|
if (!existsSync18(packagePath)) return false;
|
|
7810
7853
|
try {
|
|
7811
7854
|
const pkg2 = JSON.parse(readFileSync20(packagePath, "utf-8"));
|
|
@@ -7817,9 +7860,9 @@ function isDeepSpaceApp(dir) {
|
|
|
7817
7860
|
function installedPackageRoot(fromDir) {
|
|
7818
7861
|
let dir = fromDir;
|
|
7819
7862
|
for (; ; ) {
|
|
7820
|
-
const candidate =
|
|
7821
|
-
if (existsSync18(
|
|
7822
|
-
const parent =
|
|
7863
|
+
const candidate = join18(dir, "node_modules", "deepspace");
|
|
7864
|
+
if (existsSync18(join18(candidate, "package.json"))) return candidate;
|
|
7865
|
+
const parent = dirname9(dir);
|
|
7823
7866
|
if (parent === dir) return null;
|
|
7824
7867
|
dir = parent;
|
|
7825
7868
|
}
|
|
@@ -7835,8 +7878,8 @@ async function targetInstaller(appDir) {
|
|
|
7835
7878
|
if (realpathSync4(installedRoot) === realpathSync4(featurePackageRoot())) {
|
|
7836
7879
|
return { installFeature };
|
|
7837
7880
|
}
|
|
7838
|
-
const entry =
|
|
7839
|
-
const catalog =
|
|
7881
|
+
const entry = join18(installedRoot, "dist", "feature-installer.js");
|
|
7882
|
+
const catalog = join18(installedRoot, "features");
|
|
7840
7883
|
if (!existsSync18(entry) || !existsSync18(catalog)) {
|
|
7841
7884
|
throw new Refusal(
|
|
7842
7885
|
`The app's installed deepspace package does not contain the typed feature installer.
|
|
@@ -8011,13 +8054,12 @@ function fmtDate(iso) {
|
|
|
8011
8054
|
}
|
|
8012
8055
|
async function confirm4(message) {
|
|
8013
8056
|
process.stdout.write(`${message} [y/N] `);
|
|
8014
|
-
|
|
8057
|
+
const answer = await new Promise((resolve21) => {
|
|
8015
8058
|
process.stdin.setEncoding("utf-8");
|
|
8016
|
-
process.stdin.once("data", (data) =>
|
|
8017
|
-
const answer = data.toString().trim().toLowerCase();
|
|
8018
|
-
resolve21(answer === "y" || answer === "yes");
|
|
8019
|
-
});
|
|
8059
|
+
process.stdin.once("data", (data) => resolve21(data.toString().trim().toLowerCase()));
|
|
8020
8060
|
});
|
|
8061
|
+
process.stdin.pause();
|
|
8062
|
+
return answer === "y" || answer === "yes";
|
|
8021
8063
|
}
|
|
8022
8064
|
var cannotPrompt = (json) => json || !process.stdin.isTTY;
|
|
8023
8065
|
var search = defineDeepspaceCommand({
|
|
@@ -9368,7 +9410,7 @@ var integrations_default = defineCommand9({
|
|
|
9368
9410
|
// src/cli/commands/feedback.ts
|
|
9369
9411
|
import * as p16 from "@clack/prompts";
|
|
9370
9412
|
import { existsSync as existsSync20, readFileSync as readFileSync22 } from "fs";
|
|
9371
|
-
import { dirname as
|
|
9413
|
+
import { dirname as dirname10, join as join19 } from "path";
|
|
9372
9414
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9373
9415
|
import { release } from "os";
|
|
9374
9416
|
var API_URL8 = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api;
|
|
@@ -9389,10 +9431,10 @@ function normalizeType(raw) {
|
|
|
9389
9431
|
}
|
|
9390
9432
|
function readCliVersion() {
|
|
9391
9433
|
try {
|
|
9392
|
-
const here =
|
|
9434
|
+
const here = dirname10(fileURLToPath2(import.meta.url));
|
|
9393
9435
|
const candidates = [
|
|
9394
|
-
|
|
9395
|
-
|
|
9436
|
+
join19(here, "..", "package.json"),
|
|
9437
|
+
join19(here, "..", "..", "..", "package.json")
|
|
9396
9438
|
];
|
|
9397
9439
|
for (const path of candidates) {
|
|
9398
9440
|
if (!existsSync20(path)) continue;
|
|
@@ -9793,7 +9835,7 @@ var get2 = defineCommand10({
|
|
|
9793
9835
|
const { secrets } = await listSecrets(DEPLOY_URL11, t.token, t.appId, t.configName);
|
|
9794
9836
|
const item = secrets.find((s) => s.key === key);
|
|
9795
9837
|
if (!item)
|
|
9796
|
-
|
|
9838
|
+
throw new InputError(`Secret "${key}" not found in ${t.configName}`, "secret_not_found");
|
|
9797
9839
|
ok(
|
|
9798
9840
|
args.json === true,
|
|
9799
9841
|
{
|
|
@@ -9865,7 +9907,7 @@ var upload = defineCommand10({
|
|
|
9865
9907
|
const content = args.file === "-" ? readFileSync23(0, "utf-8") : readFileSync23(args.file, "utf-8");
|
|
9866
9908
|
const secrets = parseSecretsUpload(content);
|
|
9867
9909
|
if (Object.keys(secrets).length === 0)
|
|
9868
|
-
|
|
9910
|
+
throw new InputError("No secrets found in the input.", "empty_input");
|
|
9869
9911
|
await uploadSecrets(DEPLOY_URL11, t.token, t.appId, t.configName, secrets, args.replace);
|
|
9870
9912
|
const uploaded = Object.keys(secrets);
|
|
9871
9913
|
ok(
|
|
@@ -9896,11 +9938,9 @@ var download = defineCommand10({
|
|
|
9896
9938
|
const t = await resolveTarget(args);
|
|
9897
9939
|
const format = args.format;
|
|
9898
9940
|
if (!["dotenv", "json", "shell"].includes(format)) {
|
|
9899
|
-
|
|
9900
|
-
|
|
9901
|
-
|
|
9902
|
-
"invalid_format"
|
|
9903
|
-
)
|
|
9941
|
+
throw new InputError(
|
|
9942
|
+
`Unknown format "${args.format}" \u2014 use dotenv, json, or shell.`,
|
|
9943
|
+
"invalid_format"
|
|
9904
9944
|
);
|
|
9905
9945
|
}
|
|
9906
9946
|
const { secrets } = await fetchSecretsValues(DEPLOY_URL11, t.token, t.appId, t.configName);
|
|
@@ -9918,11 +9958,9 @@ var pull = defineCommand10({
|
|
|
9918
9958
|
const wranglerEnv = args.env?.trim() || void 0;
|
|
9919
9959
|
const appDir = findAppDir();
|
|
9920
9960
|
if (!appDir)
|
|
9921
|
-
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
"not_in_app_repo"
|
|
9925
|
-
)
|
|
9961
|
+
throw new InputError(
|
|
9962
|
+
"Run from a DeepSpace app directory (one containing wrangler.toml).",
|
|
9963
|
+
"not_in_app_repo"
|
|
9926
9964
|
);
|
|
9927
9965
|
const t = await resolveTarget(args);
|
|
9928
9966
|
const ownerId = decodeJwtPayload(t.token).sub;
|
|
@@ -9986,11 +10024,9 @@ var configsCreate = defineCommand10({
|
|
|
9986
10024
|
const { configs: configs2 } = await listConfigs(DEPLOY_URL11, t.token, t.appId);
|
|
9987
10025
|
if (configs2.some((c) => c.name === name)) {
|
|
9988
10026
|
if (copyFrom) {
|
|
9989
|
-
|
|
9990
|
-
new
|
|
9991
|
-
|
|
9992
|
-
"config_exists"
|
|
9993
|
-
)
|
|
10027
|
+
throw new InputError(
|
|
10028
|
+
`Config "${name}" already exists \u2014 refusing to copy "${copyFrom}" over it. Delete it first, or pick a new name.`,
|
|
10029
|
+
"config_exists"
|
|
9994
10030
|
);
|
|
9995
10031
|
}
|
|
9996
10032
|
ok(
|
|
@@ -10890,7 +10926,7 @@ var pull_default = defineDeepspaceCommand({
|
|
|
10890
10926
|
// src/cli/commands/clone.ts
|
|
10891
10927
|
import * as p20 from "@clack/prompts";
|
|
10892
10928
|
import { existsSync as existsSync22, readdirSync as readdirSync6, rmSync as rmSync5 } from "fs";
|
|
10893
|
-
import { resolve as resolve17, basename as basename5, join as
|
|
10929
|
+
import { resolve as resolve17, basename as basename5, join as join20 } from "path";
|
|
10894
10930
|
function cleanFailedCloneDir(dir) {
|
|
10895
10931
|
let entries;
|
|
10896
10932
|
try {
|
|
@@ -10900,7 +10936,7 @@ function cleanFailedCloneDir(dir) {
|
|
|
10900
10936
|
}
|
|
10901
10937
|
if (entries.length === 1 && entries[0] === ".git") {
|
|
10902
10938
|
try {
|
|
10903
|
-
rmSync5(
|
|
10939
|
+
rmSync5(join20(dir, ".git"), { recursive: true, force: true });
|
|
10904
10940
|
return [];
|
|
10905
10941
|
} catch {
|
|
10906
10942
|
return entries;
|
|
@@ -11385,8 +11421,16 @@ function printOverlaps(overlaps, json) {
|
|
|
11385
11421
|
|
|
11386
11422
|
// src/cli/commands/workspace/local.ts
|
|
11387
11423
|
import * as p24 from "@clack/prompts";
|
|
11388
|
-
import {
|
|
11389
|
-
|
|
11424
|
+
import {
|
|
11425
|
+
existsSync as existsSync23,
|
|
11426
|
+
mkdirSync as mkdirSync7,
|
|
11427
|
+
readFileSync as readFileSync25,
|
|
11428
|
+
realpathSync as realpathSync6,
|
|
11429
|
+
renameSync as renameSync2,
|
|
11430
|
+
statSync as statSync3,
|
|
11431
|
+
writeFileSync as writeFileSync7
|
|
11432
|
+
} from "fs";
|
|
11433
|
+
import { dirname as dirname11, isAbsolute as isAbsolute5, join as join21, relative as relative2, sep as sep2 } from "path";
|
|
11390
11434
|
var WORKSPACE_MARKER = "deepspace-workspace.json";
|
|
11391
11435
|
function excludeWorktreeDir(appDir, dir) {
|
|
11392
11436
|
try {
|
|
@@ -11407,7 +11451,7 @@ function worktreeMarkerPath(worktreeRoot) {
|
|
|
11407
11451
|
const result = runGit(worktreeRoot, ["rev-parse", "--absolute-git-dir"], { allowFail: true });
|
|
11408
11452
|
if (result.status !== 0) return null;
|
|
11409
11453
|
const gitDir = result.stdout.toString("utf-8").trim();
|
|
11410
|
-
return isAbsolute5(gitDir) ?
|
|
11454
|
+
return isAbsolute5(gitDir) ? join21(gitDir, WORKSPACE_MARKER) : null;
|
|
11411
11455
|
} catch {
|
|
11412
11456
|
return null;
|
|
11413
11457
|
}
|
|
@@ -11418,8 +11462,8 @@ function markManagedWorkspace(worktreeRoot, workspaceId) {
|
|
|
11418
11462
|
const marker = { version: 1, workspaceId, mode: "managed-linked" };
|
|
11419
11463
|
const tempPath = `${markerPath}.${process.pid}.tmp`;
|
|
11420
11464
|
try {
|
|
11421
|
-
mkdirSync7(
|
|
11422
|
-
|
|
11465
|
+
mkdirSync7(dirname11(markerPath), { recursive: true });
|
|
11466
|
+
writeFileSync7(tempPath, JSON.stringify(marker) + "\n");
|
|
11423
11467
|
renameSync2(tempPath, markerPath);
|
|
11424
11468
|
return true;
|
|
11425
11469
|
} catch {
|
|
@@ -11452,11 +11496,11 @@ function isManagedWorkspaceWorktree(worktreeRoot, workspaceId) {
|
|
|
11452
11496
|
function defaultWorkspaceRoot(appDir, workspaceId) {
|
|
11453
11497
|
const primary = listWorktrees(appDir)[0];
|
|
11454
11498
|
if (!primary) throw new Error("Git did not report a primary worktree");
|
|
11455
|
-
return
|
|
11499
|
+
return join21(primary.path, ".deepspace", "ws", workspaceId.slice(3).toLowerCase());
|
|
11456
11500
|
}
|
|
11457
11501
|
function appDirInWorktree(appDir, worktreeRoot) {
|
|
11458
11502
|
const appRelative = relative2(realpathSync6(repoToplevel(appDir)), realpathSync6(appDir));
|
|
11459
|
-
return appRelative ?
|
|
11503
|
+
return appRelative ? join21(worktreeRoot, appRelative) : worktreeRoot;
|
|
11460
11504
|
}
|
|
11461
11505
|
function primaryAppDir(appDir) {
|
|
11462
11506
|
const primary = listWorktrees(appDir)[0];
|
|
@@ -11491,7 +11535,7 @@ function rematerializeWorkspaceWorktree(appDir, worktreeRoot, branch, workspaceI
|
|
|
11491
11535
|
function inOwnLinkedWorktree(appDir, id) {
|
|
11492
11536
|
if (workspaceIdFromBranch(currentBranch(appDir)) !== id) return false;
|
|
11493
11537
|
try {
|
|
11494
|
-
return statSync3(
|
|
11538
|
+
return statSync3(join21(repoToplevel(appDir), ".git")).isFile();
|
|
11495
11539
|
} catch {
|
|
11496
11540
|
return false;
|
|
11497
11541
|
}
|
|
@@ -11532,6 +11576,7 @@ function cleanupJson(outcome) {
|
|
|
11532
11576
|
worktreeRetained: outcome.worktreeRetained,
|
|
11533
11577
|
branchDeleted: outcome.branchDeleted,
|
|
11534
11578
|
...outcome.mainDir ? { mainDir: outcome.mainDir } : {},
|
|
11579
|
+
...outcome.leftoverDir ? { leftoverDir: outcome.leftoverDir } : {},
|
|
11535
11580
|
...outcome.error ? { error: outcome.error } : {}
|
|
11536
11581
|
};
|
|
11537
11582
|
}
|
|
@@ -11606,7 +11651,23 @@ function cleanupWorkspaceLocal(appDir, id, trunkBranch, options = {}) {
|
|
|
11606
11651
|
}
|
|
11607
11652
|
const remove2 = runGit(mainDir, ["worktree", "remove", linked.path], { allowFail: true });
|
|
11608
11653
|
if (remove2.status !== 0) {
|
|
11609
|
-
|
|
11654
|
+
const reason = remove2.stderr.toString("utf-8").trim() || "unknown git error";
|
|
11655
|
+
const registered = listWorktrees(mainDir);
|
|
11656
|
+
const stillRegistered = registered.length === 0 || registered.some((worktree, index) => index > 0 && worktree.path === linked.path);
|
|
11657
|
+
if (stillRegistered) {
|
|
11658
|
+
out.error = `git worktree remove ${linked.path} failed: ${reason}`;
|
|
11659
|
+
return out;
|
|
11660
|
+
}
|
|
11661
|
+
runGit(mainDir, ["worktree", "prune"], { allowFail: true });
|
|
11662
|
+
out.worktreeDir = null;
|
|
11663
|
+
const leftover = existsSync23(linked.path);
|
|
11664
|
+
if (leftover) out.leftoverDir = linked.path;
|
|
11665
|
+
else out.worktreeRemoved = linked.path;
|
|
11666
|
+
deleteWsBranch(mainDir, branch, expectedBranchOid, out);
|
|
11667
|
+
if (leftover) {
|
|
11668
|
+
const branchProblem = out.error;
|
|
11669
|
+
out.error = `git removed the worktree but could not delete its files (${reason})` + (branchProblem ? `. Also: ${branchProblem}` : "");
|
|
11670
|
+
}
|
|
11610
11671
|
return out;
|
|
11611
11672
|
}
|
|
11612
11673
|
out.worktreeRemoved = linked.path;
|
|
@@ -11628,12 +11689,20 @@ function cleanupWorkspaceLocal(appDir, id, trunkBranch, options = {}) {
|
|
|
11628
11689
|
function cleanupRefusalMessage(outcome) {
|
|
11629
11690
|
if (outcome.worktreeDir) {
|
|
11630
11691
|
const dir = shQuote(outcome.worktreeDir);
|
|
11631
|
-
|
|
11692
|
+
if (outcome.error.includes("contains modified or untracked files")) {
|
|
11693
|
+
return `Cleanup incomplete: ${outcome.error}. The worktree at ${dir} still holds uncommitted or untracked work \u2014 that's why the plain removal refused. Inspect it (\`git -C ${dir} status\`) and commit anything worth keeping to the workspace branch. Once it's clean, remove it from the main checkout: \`git worktree remove ${dir}\`.`;
|
|
11694
|
+
}
|
|
11695
|
+
return `Cleanup incomplete: ${outcome.error}. The worktree at ${dir} is still registered; git refused the plain removal for the reason above. Inspect it (\`git -C ${dir} status\`), resolve that, then remove it from the main checkout: \`git worktree remove ${dir}\`.`;
|
|
11696
|
+
}
|
|
11697
|
+
if (outcome.leftoverDir) {
|
|
11698
|
+
return `Cleanup incomplete: ${outcome.error}. Close anything using that folder \u2014 a dev server, an editor, or a shell inside it \u2014 then delete: ${shQuote(outcome.leftoverDir)}`;
|
|
11632
11699
|
}
|
|
11633
11700
|
return `Cleanup incomplete: ${outcome.error}. Finish it from the main checkout once ${shQuote(outcome.branch)} is safe to delete.`;
|
|
11634
11701
|
}
|
|
11635
11702
|
function cleanupAction(outcome) {
|
|
11636
|
-
|
|
11703
|
+
if (outcome.worktreeDir) return { cwd: outcome.worktreeDir, argv: ["git", "status"] };
|
|
11704
|
+
if (outcome.leftoverDir) return { cwd: process.cwd(), argv: ["git", "worktree", "list"] };
|
|
11705
|
+
return { cwd: process.cwd(), argv: ["git", "branch", "--list", outcome.branch] };
|
|
11637
11706
|
}
|
|
11638
11707
|
function reportCleanupHuman(outcome) {
|
|
11639
11708
|
if (outcome.error) {
|
|
@@ -11641,6 +11710,7 @@ function reportCleanupHuman(outcome) {
|
|
|
11641
11710
|
cleanupRefusalMessage({
|
|
11642
11711
|
error: outcome.error,
|
|
11643
11712
|
worktreeDir: outcome.worktreeDir,
|
|
11713
|
+
leftoverDir: outcome.leftoverDir,
|
|
11644
11714
|
branch: outcome.branch
|
|
11645
11715
|
})
|
|
11646
11716
|
);
|
|
@@ -11888,7 +11958,7 @@ var newWorkspaceCommand = defineDeepspaceCommand({
|
|
|
11888
11958
|
|
|
11889
11959
|
// src/cli/commands/workspace/attach.ts
|
|
11890
11960
|
import * as p26 from "@clack/prompts";
|
|
11891
|
-
import { existsSync as
|
|
11961
|
+
import { existsSync as existsSync24, readdirSync as readdirSync7, realpathSync as realpathSync7, rmSync as rmSync6 } from "fs";
|
|
11892
11962
|
import { isAbsolute as isAbsolute7, resolve as resolve19 } from "path";
|
|
11893
11963
|
function samePath(a, b) {
|
|
11894
11964
|
const real = (p35) => {
|
|
@@ -11908,7 +11978,7 @@ function finishedWorkspaceMessage(id, view) {
|
|
|
11908
11978
|
return `Workspace ${id} is ${workspace.status} \u2014 its ref is retained briefly (fetch ${workspace.ref} to inspect), but attach only works on active workspaces.`;
|
|
11909
11979
|
}
|
|
11910
11980
|
function cleanFailedFreshAttachDir(dir) {
|
|
11911
|
-
if (!
|
|
11981
|
+
if (!existsSync24(dir)) return [];
|
|
11912
11982
|
let entries;
|
|
11913
11983
|
try {
|
|
11914
11984
|
entries = readdirSync7(dir);
|
|
@@ -11990,7 +12060,7 @@ var attachWorkspaceCommand = defineDeepspaceCommand({
|
|
|
11990
12060
|
const localTip = resolveCommit(appDir, `refs/heads/${branch}`);
|
|
11991
12061
|
if (localTip) {
|
|
11992
12062
|
let existing = resolveWorkspaceWorktree(listWorktrees(appDir), id);
|
|
11993
|
-
if (existing && !
|
|
12063
|
+
if (existing && !existsSync24(existing)) {
|
|
11994
12064
|
runGit(appDir, ["worktree", "prune"], { allowFail: true });
|
|
11995
12065
|
existing = null;
|
|
11996
12066
|
}
|
|
@@ -12108,7 +12178,7 @@ var attachWorkspaceCommand = defineDeepspaceCommand({
|
|
|
12108
12178
|
process.cwd(),
|
|
12109
12179
|
(typeof args.dir === "string" ? args.dir.trim() : "") || `ws-${id.slice(3).toLowerCase()}`
|
|
12110
12180
|
);
|
|
12111
|
-
if (
|
|
12181
|
+
if (existsSync24(dir)) {
|
|
12112
12182
|
spinner2?.stop("Target exists.");
|
|
12113
12183
|
throw new Refusal(`${dir} already exists \u2014 pass a different directory.`, "dir_exists");
|
|
12114
12184
|
}
|
|
@@ -12446,12 +12516,12 @@ import * as p30 from "@clack/prompts";
|
|
|
12446
12516
|
// src/cli/lib/validation.ts
|
|
12447
12517
|
import { sync as spawnSync7 } from "cross-spawn";
|
|
12448
12518
|
import { readFileSync as readFileSync26 } from "fs";
|
|
12449
|
-
import { join as
|
|
12519
|
+
import { join as join22 } from "path";
|
|
12450
12520
|
var MAX_SUMMARY_CHARS = 4e3;
|
|
12451
12521
|
var MAX_OUTPUT_BUFFER = 64 * 1024 * 1024;
|
|
12452
12522
|
function configuredCommand(appDir) {
|
|
12453
12523
|
try {
|
|
12454
|
-
const pkg2 = JSON.parse(readFileSync26(
|
|
12524
|
+
const pkg2 = JSON.parse(readFileSync26(join22(appDir, "package.json"), "utf-8"));
|
|
12455
12525
|
if (pkg2.scripts?.validate) return `${detectPackageManager(appDir)} run --silent validate`;
|
|
12456
12526
|
} catch {
|
|
12457
12527
|
}
|
|
@@ -12792,12 +12862,14 @@ var landWorkspaceCommand = defineDeepspaceCommand({
|
|
|
12792
12862
|
if (cleanup?.error) {
|
|
12793
12863
|
const action2 = cleanupAction({
|
|
12794
12864
|
worktreeDir: cleanup.worktreeDir,
|
|
12865
|
+
leftoverDir: cleanup.leftoverDir,
|
|
12795
12866
|
branch: cleanup.branch
|
|
12796
12867
|
});
|
|
12797
12868
|
throw new Refusal(
|
|
12798
12869
|
cleanupRefusalMessage({
|
|
12799
12870
|
error: cleanup.error,
|
|
12800
12871
|
worktreeDir: cleanup.worktreeDir,
|
|
12872
|
+
leftoverDir: cleanup.leftoverDir,
|
|
12801
12873
|
branch: cleanup.branch
|
|
12802
12874
|
}),
|
|
12803
12875
|
"cleanup_incomplete",
|
|
@@ -12963,12 +13035,14 @@ var dropWorkspaceCommand = defineDeepspaceCommand({
|
|
|
12963
13035
|
if (cleanup?.error) {
|
|
12964
13036
|
const action = cleanupAction({
|
|
12965
13037
|
worktreeDir: cleanup.worktreeDir,
|
|
13038
|
+
leftoverDir: cleanup.leftoverDir,
|
|
12966
13039
|
branch: cleanup.branch
|
|
12967
13040
|
});
|
|
12968
13041
|
throw new Refusal(
|
|
12969
13042
|
cleanupRefusalMessage({
|
|
12970
13043
|
error: cleanup.error,
|
|
12971
13044
|
worktreeDir: cleanup.worktreeDir,
|
|
13045
|
+
leftoverDir: cleanup.leftoverDir,
|
|
12972
13046
|
branch: cleanup.branch
|
|
12973
13047
|
}),
|
|
12974
13048
|
"cleanup_incomplete",
|
|
@@ -13523,10 +13597,165 @@ function sameRefs(left, right) {
|
|
|
13523
13597
|
|
|
13524
13598
|
// src/cli/commands/update.ts
|
|
13525
13599
|
import * as p34 from "@clack/prompts";
|
|
13526
|
-
import { existsSync as
|
|
13527
|
-
import { join as
|
|
13600
|
+
import { existsSync as existsSync25, readFileSync as readFileSync27, writeFileSync as writeFileSync8 } from "fs";
|
|
13601
|
+
import { join as join23, resolve as resolve20 } from "path";
|
|
13602
|
+
|
|
13603
|
+
// package.json
|
|
13604
|
+
var package_default = {
|
|
13605
|
+
name: "deepspace",
|
|
13606
|
+
version: "0.19.1",
|
|
13607
|
+
engines: {
|
|
13608
|
+
node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
|
|
13609
|
+
},
|
|
13610
|
+
description: "DeepSpace SDK \u2014 build real-time collaborative apps on Cloudflare Workers",
|
|
13611
|
+
type: "module",
|
|
13612
|
+
sideEffects: false,
|
|
13613
|
+
main: "./dist/index.js",
|
|
13614
|
+
types: "./dist/index.d.ts",
|
|
13615
|
+
bin: {
|
|
13616
|
+
deepspace: "dist/cli.js"
|
|
13617
|
+
},
|
|
13618
|
+
exports: {
|
|
13619
|
+
".": {
|
|
13620
|
+
types: "./dist/index.d.ts",
|
|
13621
|
+
import: "./dist/index.js"
|
|
13622
|
+
},
|
|
13623
|
+
"./schema": {
|
|
13624
|
+
types: "./dist/schema.d.ts",
|
|
13625
|
+
import: "./dist/schema.js"
|
|
13626
|
+
},
|
|
13627
|
+
"./worker": {
|
|
13628
|
+
types: "./dist/worker.d.ts",
|
|
13629
|
+
import: "./dist/worker.js"
|
|
13630
|
+
},
|
|
13631
|
+
"./server": {
|
|
13632
|
+
types: "./dist/server.d.ts",
|
|
13633
|
+
import: "./dist/server.js"
|
|
13634
|
+
},
|
|
13635
|
+
"./testing": {
|
|
13636
|
+
types: "./dist/testing.d.ts",
|
|
13637
|
+
import: "./dist/testing.js"
|
|
13638
|
+
},
|
|
13639
|
+
"./documentation": {
|
|
13640
|
+
types: "./dist/documentation.d.ts",
|
|
13641
|
+
import: "./dist/documentation.js"
|
|
13642
|
+
},
|
|
13643
|
+
"./documentation/react": {
|
|
13644
|
+
types: "./dist/documentation-react.d.ts",
|
|
13645
|
+
import: "./dist/documentation-react.js"
|
|
13646
|
+
}
|
|
13647
|
+
},
|
|
13648
|
+
files: [
|
|
13649
|
+
"dist",
|
|
13650
|
+
"features",
|
|
13651
|
+
"CHANGELOG.md"
|
|
13652
|
+
],
|
|
13653
|
+
scripts: {
|
|
13654
|
+
build: "node ../../scripts/clean-artifacts.mjs dist --tsbuildinfo && tsup",
|
|
13655
|
+
"type-check": "tsc --noEmit",
|
|
13656
|
+
test: "vitest run",
|
|
13657
|
+
"test:documentation-browser": "playwright test --config src/documentation/runtime/__browser__/playwright.config.ts",
|
|
13658
|
+
clean: "node ../../scripts/clean-artifacts.mjs dist --tsbuildinfo",
|
|
13659
|
+
prepublishOnly: "pnpm build"
|
|
13660
|
+
},
|
|
13661
|
+
dependencies: {
|
|
13662
|
+
"@ai-sdk/anthropic": "2.0.91",
|
|
13663
|
+
"@ai-sdk/openai": "2.0.116",
|
|
13664
|
+
"@ai-sdk/openai-compatible": "1.0.46",
|
|
13665
|
+
"@clack/prompts": "^1.2.0",
|
|
13666
|
+
"@mdx-js/mdx": "^3.1.1",
|
|
13667
|
+
acorn: "^8.16.0",
|
|
13668
|
+
ai: "5.0.222",
|
|
13669
|
+
"better-auth": "1.6.23",
|
|
13670
|
+
citty: "^0.2.0",
|
|
13671
|
+
"cross-spawn": "^7.0.6",
|
|
13672
|
+
esbuild: "^0.27.0",
|
|
13673
|
+
"highlight.js": "^11.11.1",
|
|
13674
|
+
hono: "^4.6.0",
|
|
13675
|
+
jose: "^6.1.0",
|
|
13676
|
+
marked: "^18.0.7",
|
|
13677
|
+
"mdast-util-gfm": "^3.1.0",
|
|
13678
|
+
"mdast-util-to-markdown": "^2.1.2",
|
|
13679
|
+
"rehype-highlight": "^7.0.2",
|
|
13680
|
+
"remark-frontmatter": "^5.0.0",
|
|
13681
|
+
"remark-gfm": "^4.0.1",
|
|
13682
|
+
"sanitize-html": "^2.17.6",
|
|
13683
|
+
"smol-toml": "^1.6.1",
|
|
13684
|
+
yaml: "^2.9.0",
|
|
13685
|
+
yjs: "^13.6.0",
|
|
13686
|
+
zod: "^4.3.6"
|
|
13687
|
+
},
|
|
13688
|
+
peerDependencies: {
|
|
13689
|
+
"@playwright/test": ">=1.40.0",
|
|
13690
|
+
clsx: ">=2.0.0",
|
|
13691
|
+
"lucide-react": ">=0.400.0",
|
|
13692
|
+
react: "^18.0.0 || ^19.0.0",
|
|
13693
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
13694
|
+
"tailwind-merge": ">=2.0.0"
|
|
13695
|
+
},
|
|
13696
|
+
peerDependenciesMeta: {
|
|
13697
|
+
"@playwright/test": {
|
|
13698
|
+
optional: true
|
|
13699
|
+
},
|
|
13700
|
+
react: {
|
|
13701
|
+
optional: true
|
|
13702
|
+
},
|
|
13703
|
+
"react-dom": {
|
|
13704
|
+
optional: true
|
|
13705
|
+
},
|
|
13706
|
+
clsx: {
|
|
13707
|
+
optional: true
|
|
13708
|
+
},
|
|
13709
|
+
"tailwind-merge": {
|
|
13710
|
+
optional: true
|
|
13711
|
+
},
|
|
13712
|
+
"lucide-react": {
|
|
13713
|
+
optional: true
|
|
13714
|
+
}
|
|
13715
|
+
},
|
|
13716
|
+
devDependencies: {
|
|
13717
|
+
"@cloudflare/workers-types": "^4.20241205.0",
|
|
13718
|
+
"@playwright/test": "^1.59.1",
|
|
13719
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
13720
|
+
"@types/cross-spawn": "^6.0.6",
|
|
13721
|
+
"@types/react": "^19.0.0",
|
|
13722
|
+
"@types/react-dom": "^19.0.0",
|
|
13723
|
+
"@types/sanitize-html": "^2.16.1",
|
|
13724
|
+
"better-sqlite3": "^12.0.0",
|
|
13725
|
+
clsx: "^2.1.1",
|
|
13726
|
+
"framer-motion": "^12.38.0",
|
|
13727
|
+
jsdom: "^29.1.1",
|
|
13728
|
+
"lucide-react": "^1.7.0",
|
|
13729
|
+
"react-router-dom": "^7.1.0",
|
|
13730
|
+
"tailwind-merge": "^3.5.0",
|
|
13731
|
+
tsup: "^8.3.0",
|
|
13732
|
+
typescript: "^5.7.0",
|
|
13733
|
+
vitest: "^4.1.0"
|
|
13734
|
+
},
|
|
13735
|
+
keywords: [
|
|
13736
|
+
"deepspace",
|
|
13737
|
+
"cloudflare-workers",
|
|
13738
|
+
"durable-objects",
|
|
13739
|
+
"real-time",
|
|
13740
|
+
"collaborative",
|
|
13741
|
+
"sdk"
|
|
13742
|
+
],
|
|
13743
|
+
license: "Apache-2.0",
|
|
13744
|
+
homepage: "https://deep.space",
|
|
13745
|
+
repository: {
|
|
13746
|
+
type: "git",
|
|
13747
|
+
url: "git+https://github.com/deepdotspace/deepspace.git",
|
|
13748
|
+
directory: "packages/deepspace"
|
|
13749
|
+
},
|
|
13750
|
+
bugs: {
|
|
13751
|
+
url: "https://github.com/deepdotspace/deepspace/issues"
|
|
13752
|
+
}
|
|
13753
|
+
};
|
|
13754
|
+
|
|
13755
|
+
// src/cli/commands/update.ts
|
|
13528
13756
|
var REGISTRY = "https://registry.npmjs.org/deepspace/latest";
|
|
13529
13757
|
var DOCS_URL = "https://documentation.deep.space/cli-reference/commands";
|
|
13758
|
+
var COMPATIBLE_AI_VERSION = package_default.dependencies.ai;
|
|
13530
13759
|
var OLDEST_SUPPORTED_MINOR = 12;
|
|
13531
13760
|
function parseVersion(raw) {
|
|
13532
13761
|
const match = /^(\d+)\.(\d+)\.(\d+)/.exec(raw.trim().replace(/^[\^~]/, ""));
|
|
@@ -13538,25 +13767,29 @@ function gapIsTooWide(from, to) {
|
|
|
13538
13767
|
return from.major === 0 && from.minor < OLDEST_SUPPORTED_MINOR;
|
|
13539
13768
|
}
|
|
13540
13769
|
function readAppSdkVersion(appDir) {
|
|
13541
|
-
const installed =
|
|
13542
|
-
if (
|
|
13770
|
+
const installed = join23(appDir, "node_modules", "deepspace", "package.json");
|
|
13771
|
+
if (existsSync25(installed)) {
|
|
13543
13772
|
const parsed2 = JSON.parse(readFileSync27(installed, "utf8"));
|
|
13544
13773
|
if (typeof parsed2.version === "string") return parsed2.version;
|
|
13545
13774
|
}
|
|
13546
|
-
const manifest =
|
|
13547
|
-
if (!
|
|
13775
|
+
const manifest = join23(appDir, "package.json");
|
|
13776
|
+
if (!existsSync25(manifest)) return null;
|
|
13548
13777
|
const parsed = JSON.parse(readFileSync27(manifest, "utf8"));
|
|
13549
13778
|
return parsed.dependencies?.deepspace ?? null;
|
|
13550
13779
|
}
|
|
13551
13780
|
function pinSdkVersion(appDir, version) {
|
|
13552
|
-
const path =
|
|
13781
|
+
const path = join23(appDir, "package.json");
|
|
13553
13782
|
const source = readFileSync27(path, "utf8");
|
|
13554
|
-
|
|
13783
|
+
let updated = source.replace(
|
|
13555
13784
|
/("deepspace"\s*:\s*")[^"]+(")/,
|
|
13556
13785
|
(_match, head, tail) => `${head}^${version}${tail}`
|
|
13557
13786
|
);
|
|
13787
|
+
updated = updated.replace(
|
|
13788
|
+
/("ai"\s*:\s*")[^"]+(")/,
|
|
13789
|
+
(_match, head, tail) => `${head}${COMPATIBLE_AI_VERSION}${tail}`
|
|
13790
|
+
);
|
|
13558
13791
|
if (updated === source) return false;
|
|
13559
|
-
|
|
13792
|
+
writeFileSync8(path, updated);
|
|
13560
13793
|
return true;
|
|
13561
13794
|
}
|
|
13562
13795
|
async function latestPublishedVersion() {
|
|
@@ -13695,9 +13928,9 @@ var update_default = defineDeepspaceCommand({
|
|
|
13695
13928
|
});
|
|
13696
13929
|
|
|
13697
13930
|
// src/cli/cli.ts
|
|
13698
|
-
var __dirname =
|
|
13699
|
-
var pkg = JSON.parse(readFileSync28(
|
|
13700
|
-
if (process.platform === "linux" && !process.env.SSL_CERT_FILE &&
|
|
13931
|
+
var __dirname = dirname12(fileURLToPath3(import.meta.url));
|
|
13932
|
+
var pkg = JSON.parse(readFileSync28(join24(__dirname, "..", "package.json"), "utf-8"));
|
|
13933
|
+
if (process.platform === "linux" && !process.env.SSL_CERT_FILE && existsSync26("/etc/ssl/certs/ca-certificates.crt")) {
|
|
13701
13934
|
process.env.SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt";
|
|
13702
13935
|
}
|
|
13703
13936
|
var create2 = defineCommand14({
|