@adep/cli 0.4.5 → 0.4.10
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/README.md +44 -3
- package/dist/index.js +1206 -742
- package/dist/vite.js +218 -35
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -12,7 +12,11 @@ var __export = (target, all) => {
|
|
|
12
12
|
// packages/cli/src/config.ts
|
|
13
13
|
function resolvePaths(env = process.env) {
|
|
14
14
|
const home = env["ADEP_HOME"] ?? `${env["HOME"] ?? ""}/.adep`;
|
|
15
|
-
return {
|
|
15
|
+
return {
|
|
16
|
+
home,
|
|
17
|
+
credentialsFile: `${home}/credentials`,
|
|
18
|
+
credentialsDir: `${home}/credentials.d`
|
|
19
|
+
};
|
|
16
20
|
}
|
|
17
21
|
function resolveServer(env = process.env) {
|
|
18
22
|
return (env["ADEP_SERVER"] ?? "https://adep.top").replace(/\/+$/, "");
|
|
@@ -66,29 +70,13 @@ var init_browser = __esm({
|
|
|
66
70
|
});
|
|
67
71
|
|
|
68
72
|
// packages/cli/src/credentials.ts
|
|
69
|
-
import { mkdir, open, readFile, rm, stat } from "node:fs/promises";
|
|
70
|
-
import {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const handle = await open(paths.credentialsFile, "w", 384);
|
|
74
|
-
try {
|
|
75
|
-
await handle.writeFile(JSON.stringify(credentials, null, 2));
|
|
76
|
-
} finally {
|
|
77
|
-
await handle.close();
|
|
78
|
-
}
|
|
79
|
-
await chmodStrict(paths.credentialsFile);
|
|
73
|
+
import { chmod, mkdir, open, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
74
|
+
import { join } from "node:path";
|
|
75
|
+
function slotNameFor(server) {
|
|
76
|
+
return encodeURIComponent(new URL(server).host);
|
|
80
77
|
}
|
|
81
|
-
|
|
82
|
-
const info = await stat(file2);
|
|
83
|
-
const mode = info.mode & 511;
|
|
84
|
-
if (mode !== 384) {
|
|
85
|
-
const { chmod } = await import("node:fs/promises");
|
|
86
|
-
await chmod(file2, 384);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
async function loadCredentials(paths) {
|
|
78
|
+
function parseCredentials(raw) {
|
|
90
79
|
try {
|
|
91
|
-
const raw = await readFile(paths.credentialsFile, "utf8");
|
|
92
80
|
const parsed = JSON.parse(raw);
|
|
93
81
|
if (typeof parsed["server"] !== "string" || typeof parsed["email"] !== "string" || typeof parsed["encodedToken"] !== "string") {
|
|
94
82
|
return null;
|
|
@@ -104,7 +92,84 @@ async function loadCredentials(paths) {
|
|
|
104
92
|
return null;
|
|
105
93
|
}
|
|
106
94
|
}
|
|
95
|
+
async function chmodStrict(file2) {
|
|
96
|
+
const info = await stat(file2);
|
|
97
|
+
const mode = info.mode & 511;
|
|
98
|
+
if (mode !== 384) {
|
|
99
|
+
await chmod(file2, 384);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function writeSlot(paths, credentials, slot) {
|
|
103
|
+
await mkdir(paths.credentialsDir, { recursive: true });
|
|
104
|
+
const file2 = slotFileOf(paths, slot);
|
|
105
|
+
const handle = await open(file2, "w", 384);
|
|
106
|
+
try {
|
|
107
|
+
await handle.writeFile(JSON.stringify(credentials, null, 2));
|
|
108
|
+
} finally {
|
|
109
|
+
await handle.close();
|
|
110
|
+
}
|
|
111
|
+
await chmodStrict(file2);
|
|
112
|
+
}
|
|
113
|
+
async function readSlot(paths, slot) {
|
|
114
|
+
try {
|
|
115
|
+
return parseCredentials(await readFile(slotFileOf(paths, slot), "utf8"));
|
|
116
|
+
} catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function readCurrent(paths) {
|
|
121
|
+
try {
|
|
122
|
+
const raw = (await readFile(currentFileOf(paths), "utf8")).trim();
|
|
123
|
+
return raw === "" ? null : raw;
|
|
124
|
+
} catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function writeCurrent(paths, slot) {
|
|
129
|
+
await mkdir(paths.credentialsDir, { recursive: true });
|
|
130
|
+
await writeFile(currentFileOf(paths), `${slot}
|
|
131
|
+
`, "utf8");
|
|
132
|
+
}
|
|
133
|
+
async function migrateLegacyFile(paths) {
|
|
134
|
+
let raw;
|
|
135
|
+
try {
|
|
136
|
+
raw = await readFile(paths.credentialsFile, "utf8");
|
|
137
|
+
} catch {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const parsed = parseCredentials(raw);
|
|
141
|
+
if (parsed === null) return;
|
|
142
|
+
try {
|
|
143
|
+
const slot = slotNameFor(parsed.server);
|
|
144
|
+
await writeSlot(paths, parsed, slot);
|
|
145
|
+
if (await readCurrent(paths) === null) {
|
|
146
|
+
await writeCurrent(paths, slot);
|
|
147
|
+
}
|
|
148
|
+
} catch {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
await rm(paths.credentialsFile, { force: true });
|
|
152
|
+
}
|
|
153
|
+
async function saveCredentials(paths, credentials) {
|
|
154
|
+
await migrateLegacyFile(paths);
|
|
155
|
+
const slot = slotNameFor(credentials.server);
|
|
156
|
+
const previous = await readSlot(paths, slot);
|
|
157
|
+
await writeSlot(paths, credentials, slot);
|
|
158
|
+
await writeCurrent(paths, slot);
|
|
159
|
+
return { previous };
|
|
160
|
+
}
|
|
161
|
+
async function loadCredentials(paths) {
|
|
162
|
+
await migrateLegacyFile(paths);
|
|
163
|
+
const current = await readCurrent(paths);
|
|
164
|
+
if (current === null) return null;
|
|
165
|
+
return readSlot(paths, current);
|
|
166
|
+
}
|
|
107
167
|
async function clearCredentials(paths) {
|
|
168
|
+
const current = await readCurrent(paths);
|
|
169
|
+
if (current !== null) {
|
|
170
|
+
await rm(slotFileOf(paths, current), { force: true });
|
|
171
|
+
}
|
|
172
|
+
await rm(currentFileOf(paths), { force: true });
|
|
108
173
|
await rm(paths.credentialsFile, { force: true });
|
|
109
174
|
}
|
|
110
175
|
function encodeToken(token) {
|
|
@@ -123,9 +188,12 @@ function authHeaders(credentials) {
|
|
|
123
188
|
}
|
|
124
189
|
return { cookie: sessionCookieHeader(credentials) };
|
|
125
190
|
}
|
|
191
|
+
var slotFileOf, currentFileOf;
|
|
126
192
|
var init_credentials = __esm({
|
|
127
193
|
"packages/cli/src/credentials.ts"() {
|
|
128
194
|
"use strict";
|
|
195
|
+
slotFileOf = (paths, slot) => join(paths.credentialsDir, `${slot}.json`);
|
|
196
|
+
currentFileOf = (paths) => join(paths.credentialsDir, "current");
|
|
129
197
|
}
|
|
130
198
|
});
|
|
131
199
|
|
|
@@ -246,14 +314,18 @@ async function login(paths, input2) {
|
|
|
246
314
|
const eq = cookie.indexOf("=");
|
|
247
315
|
const cookieName = cookie.slice(0, eq);
|
|
248
316
|
const token = cookie.slice(eq + 1);
|
|
249
|
-
await saveCredentials(paths, {
|
|
317
|
+
const { previous } = await saveCredentials(paths, {
|
|
250
318
|
server,
|
|
251
319
|
email: input2.email,
|
|
252
320
|
encodedToken: encodeToken(token),
|
|
253
321
|
cookieName,
|
|
254
322
|
authType: "cookie"
|
|
255
323
|
});
|
|
256
|
-
return {
|
|
324
|
+
return {
|
|
325
|
+
email: input2.email,
|
|
326
|
+
authType: "cookie",
|
|
327
|
+
...previous !== null && previous.email !== input2.email ? { replacedEmail: previous.email } : {}
|
|
328
|
+
};
|
|
257
329
|
}
|
|
258
330
|
async function parseDeviceError(response) {
|
|
259
331
|
let body = null;
|
|
@@ -394,13 +466,17 @@ async function loginWithDevice(paths, input2) {
|
|
|
394
466
|
now: input2.now ?? Date.now
|
|
395
467
|
});
|
|
396
468
|
const email3 = await fetchIdentityWithToken(server, token);
|
|
397
|
-
await saveCredentials(paths, {
|
|
469
|
+
const { previous } = await saveCredentials(paths, {
|
|
398
470
|
server,
|
|
399
471
|
email: email3,
|
|
400
472
|
encodedToken: encodeToken(token),
|
|
401
473
|
authType: "bearer"
|
|
402
474
|
});
|
|
403
|
-
return {
|
|
475
|
+
return {
|
|
476
|
+
email: email3,
|
|
477
|
+
authType: "bearer",
|
|
478
|
+
...previous !== null && previous.email !== email3 ? { replacedEmail: previous.email } : {}
|
|
479
|
+
};
|
|
404
480
|
}
|
|
405
481
|
async function fetchIdentityWithToken(server, token) {
|
|
406
482
|
let response;
|
|
@@ -1001,6 +1077,9 @@ function depsKeyOf(dependencies) {
|
|
|
1001
1077
|
const canonical = Object.entries(dependencies).map(([name, version2]) => `${name}@${version2}`).toSorted().join("\n");
|
|
1002
1078
|
return createHash("sha256").update(canonical).digest("hex").slice(0, 16);
|
|
1003
1079
|
}
|
|
1080
|
+
function parseNameList(value) {
|
|
1081
|
+
return value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
1082
|
+
}
|
|
1004
1083
|
var PACKAGE_NAME_PATTERN, COMPARATOR_PATTERN, MANIFEST_MAX_DEPS;
|
|
1005
1084
|
var init_manifest = __esm({
|
|
1006
1085
|
"packages/runtime/src/functions/deps/manifest.ts"() {
|
|
@@ -1035,22 +1114,22 @@ var init_resolve = __esm({
|
|
|
1035
1114
|
// packages/runtime/src/functions/runtime/worker-executor.ts
|
|
1036
1115
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
1037
1116
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
1038
|
-
import { dirname as
|
|
1117
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
1039
1118
|
import { Worker } from "node:worker_threads";
|
|
1040
1119
|
function resolveWorkerEntry(baseDir = fileURLToPath2(new URL(".", import.meta.url))) {
|
|
1041
1120
|
const candidates = [
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1121
|
+
join4(baseDir, "worker-entry.js"),
|
|
1122
|
+
join4(baseDir, "worker-entry.ts"),
|
|
1123
|
+
join4(baseDir, "domains/functions/runtime/worker-entry.js"),
|
|
1124
|
+
join4(baseDir, "domains/functions/runtime/worker-entry.ts")
|
|
1046
1125
|
];
|
|
1047
1126
|
let current = baseDir;
|
|
1048
1127
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
1049
1128
|
candidates.push(
|
|
1050
|
-
|
|
1051
|
-
|
|
1129
|
+
join4(current, "packages/runtime/src/functions/runtime/worker-entry.js"),
|
|
1130
|
+
join4(current, "packages/runtime/src/functions/runtime/worker-entry.ts")
|
|
1052
1131
|
);
|
|
1053
|
-
const parent =
|
|
1132
|
+
const parent = dirname3(current);
|
|
1054
1133
|
if (parent === current) break;
|
|
1055
1134
|
current = parent;
|
|
1056
1135
|
}
|
|
@@ -1920,6 +1999,20 @@ var init_builder = __esm({
|
|
|
1920
1999
|
|
|
1921
2000
|
// packages/runtime/src/database/sdk/cloud.ts
|
|
1922
2001
|
function errorWithCode(error62) {
|
|
2002
|
+
if (error62 instanceof Error) {
|
|
2003
|
+
const sqlite = /no such table: (\S+)/.exec(error62.message);
|
|
2004
|
+
if (sqlite !== null) {
|
|
2005
|
+
return new Error(
|
|
2006
|
+
`[DB_TABLE_MISSING] \u9879\u76EE\u5E93\u5DF2\u542F\u52A8\u4F46\u7F3A\u8868 "${sqlite[1]}"\uFF1A\u8BF7\u6267\u884C adep db migrate <schema.sql> \u5EFA\u8868\uFF08\u53D1\u5E03\u4E0D\u542B\u5EFA\u8868\uFF09\u3002\u539F\u59CB\u9519\u8BEF\uFF1A${error62.message}`
|
|
2007
|
+
);
|
|
2008
|
+
}
|
|
2009
|
+
const pg = /relation "([^"]+)" does not exist/.exec(error62.message);
|
|
2010
|
+
if (pg !== null) {
|
|
2011
|
+
return new Error(
|
|
2012
|
+
`[DB_TABLE_MISSING] \u9879\u76EE\u5E93\u5DF2\u542F\u52A8\u4F46\u7F3A\u8868\uFF08\u6216\u5173\u7CFB\uFF09"${pg[1]}"\uFF1A\u8BF7\u6267\u884C adep db migrate <schema.sql> \u5EFA\u8868\uFF08\u53D1\u5E03\u4E0D\u542B\u5EFA\u8868\uFF09\u3002\u539F\u59CB\u9519\u8BEF\uFF1A${error62.message}`
|
|
2013
|
+
);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
1923
2016
|
const code = typeof error62 === "object" && error62 !== null && typeof error62.code === "string" ? error62.code : void 0;
|
|
1924
2017
|
if (code !== void 0 && error62 instanceof Error) {
|
|
1925
2018
|
return new Error(`[${code}] ${error62.message}`);
|
|
@@ -3257,13 +3350,13 @@ var init_cloud2 = __esm({
|
|
|
3257
3350
|
});
|
|
3258
3351
|
|
|
3259
3352
|
// packages/runtime/src/storage/driver/local.ts
|
|
3260
|
-
import { mkdir as mkdir3, readFile as readFile2, readdir, rm as rm2, stat as stat3, unlink, writeFile as
|
|
3261
|
-
import { dirname as
|
|
3353
|
+
import { mkdir as mkdir3, readFile as readFile2, readdir, rm as rm2, stat as stat3, unlink, writeFile as writeFile3 } from "node:fs/promises";
|
|
3354
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
3262
3355
|
function createLocalStorageDriver(options) {
|
|
3263
3356
|
const quotaBytes = options.quotaBytes ?? PROJECT_QUOTA_BYTES;
|
|
3264
|
-
const bucketDir = (projectId) =>
|
|
3265
|
-
const objectPath = (projectId, path) =>
|
|
3266
|
-
const metaPath = (projectId, path) =>
|
|
3357
|
+
const bucketDir = (projectId) => join5(options.dir, projectId);
|
|
3358
|
+
const objectPath = (projectId, path) => join5(bucketDir(projectId), path);
|
|
3359
|
+
const metaPath = (projectId, path) => join5(dirname4(objectPath(projectId, path)), `${path.split("/").pop() ?? ""}${META_SUFFIX}`);
|
|
3267
3360
|
const readStoredMeta = async (projectId, path) => {
|
|
3268
3361
|
const raw = await readFile2(metaPath(projectId, path), "utf8");
|
|
3269
3362
|
return JSON.parse(raw);
|
|
@@ -3275,7 +3368,7 @@ function createLocalStorageDriver(options) {
|
|
|
3275
3368
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3276
3369
|
...meta3.contentType === void 0 ? {} : { contentType: meta3.contentType }
|
|
3277
3370
|
};
|
|
3278
|
-
await
|
|
3371
|
+
await writeFile3(metaPath(projectId, path), JSON.stringify(payload), "utf8");
|
|
3279
3372
|
};
|
|
3280
3373
|
const totalSize = async (projectId) => {
|
|
3281
3374
|
const root = bucketDir(projectId);
|
|
@@ -3289,7 +3382,7 @@ function createLocalStorageDriver(options) {
|
|
|
3289
3382
|
}
|
|
3290
3383
|
const tasks = [];
|
|
3291
3384
|
for (const entry of entries) {
|
|
3292
|
-
const full =
|
|
3385
|
+
const full = join5(dir, entry.name);
|
|
3293
3386
|
if (entry.isDirectory()) {
|
|
3294
3387
|
tasks.push(walk(full));
|
|
3295
3388
|
} else if (entry.isFile() && !entry.name.endsWith(META_SUFFIX)) {
|
|
@@ -3333,8 +3426,8 @@ function createLocalStorageDriver(options) {
|
|
|
3333
3426
|
);
|
|
3334
3427
|
}
|
|
3335
3428
|
const dest = objectPath(projectId, path);
|
|
3336
|
-
await mkdir3(
|
|
3337
|
-
await
|
|
3429
|
+
await mkdir3(dirname4(dest), { recursive: true });
|
|
3430
|
+
await writeFile3(dest, data);
|
|
3338
3431
|
await writeStoredMeta(projectId, path, {
|
|
3339
3432
|
visibility: putOptions.visibility,
|
|
3340
3433
|
size: data.byteLength,
|
|
@@ -3412,7 +3505,7 @@ function createLocalStorageDriver(options) {
|
|
|
3412
3505
|
const tasks = [];
|
|
3413
3506
|
for (const entry of entries) {
|
|
3414
3507
|
if (entry.name.endsWith(META_SUFFIX)) continue;
|
|
3415
|
-
const full =
|
|
3508
|
+
const full = join5(dir, entry.name);
|
|
3416
3509
|
const rel = relative10 === "" ? entry.name : `${relative10}/${entry.name}`;
|
|
3417
3510
|
if (entry.isFile()) {
|
|
3418
3511
|
if (prefix !== void 0 && !rel.startsWith(prefix)) continue;
|
|
@@ -3461,9 +3554,9 @@ var init_local = __esm({
|
|
|
3461
3554
|
});
|
|
3462
3555
|
|
|
3463
3556
|
// packages/cli/src/sim/storage.ts
|
|
3464
|
-
import { join as
|
|
3557
|
+
import { join as join6 } from "node:path";
|
|
3465
3558
|
function createSimStorageCapability(options) {
|
|
3466
|
-
const dir =
|
|
3559
|
+
const dir = join6(options.cwd, ".adep", "sim", "storage");
|
|
3467
3560
|
const driver = createLocalStorageDriver({ dir });
|
|
3468
3561
|
const signer = {
|
|
3469
3562
|
secret: options.secret ?? SIM_SIGN_SECRET,
|
|
@@ -3638,13 +3731,13 @@ var init_merge = __esm({
|
|
|
3638
3731
|
});
|
|
3639
3732
|
|
|
3640
3733
|
// packages/cli/src/sim/runtime.ts
|
|
3641
|
-
import { mkdir as mkdir4, readFile as readFile3, writeFile as
|
|
3642
|
-
import { dirname as
|
|
3734
|
+
import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
|
|
3735
|
+
import { dirname as dirname5, join as join7 } from "node:path";
|
|
3643
3736
|
function simDir(cwd) {
|
|
3644
|
-
return
|
|
3737
|
+
return join7(cwd, ".adep", "sim");
|
|
3645
3738
|
}
|
|
3646
3739
|
function jsonStorage(cwd) {
|
|
3647
|
-
const file2 =
|
|
3740
|
+
const file2 = join7(simDir(cwd), "db.json");
|
|
3648
3741
|
return {
|
|
3649
3742
|
async load() {
|
|
3650
3743
|
try {
|
|
@@ -3655,8 +3748,8 @@ function jsonStorage(cwd) {
|
|
|
3655
3748
|
}
|
|
3656
3749
|
},
|
|
3657
3750
|
async save(tables) {
|
|
3658
|
-
await mkdir4(
|
|
3659
|
-
await
|
|
3751
|
+
await mkdir4(dirname5(file2), { recursive: true });
|
|
3752
|
+
await writeFile4(file2, JSON.stringify(tables), "utf8");
|
|
3660
3753
|
}
|
|
3661
3754
|
};
|
|
3662
3755
|
}
|
|
@@ -3811,6 +3904,63 @@ var init_client = __esm({
|
|
|
3811
3904
|
}
|
|
3812
3905
|
});
|
|
3813
3906
|
|
|
3907
|
+
// packages/runtime/src/shared/sql-split.ts
|
|
3908
|
+
function splitSqlStatements(source) {
|
|
3909
|
+
const statements = [];
|
|
3910
|
+
let buffer = "";
|
|
3911
|
+
let inQuote = false;
|
|
3912
|
+
const lines = source.split("\n");
|
|
3913
|
+
for (const rawLine of lines) {
|
|
3914
|
+
const trimmed = rawLine.trim();
|
|
3915
|
+
if (!inQuote && (trimmed.length === 0 || trimmed.startsWith("--"))) continue;
|
|
3916
|
+
const scanLine = inQuote ? rawLine : trimmed;
|
|
3917
|
+
for (let i = 0; i < scanLine.length; i++) {
|
|
3918
|
+
const ch = scanLine[i];
|
|
3919
|
+
if (inQuote) {
|
|
3920
|
+
if (ch === "'") {
|
|
3921
|
+
if (scanLine[i + 1] === "'") {
|
|
3922
|
+
buffer += ch + scanLine[i + 1];
|
|
3923
|
+
i++;
|
|
3924
|
+
continue;
|
|
3925
|
+
}
|
|
3926
|
+
inQuote = false;
|
|
3927
|
+
}
|
|
3928
|
+
buffer += ch;
|
|
3929
|
+
continue;
|
|
3930
|
+
}
|
|
3931
|
+
if (ch === "'") {
|
|
3932
|
+
inQuote = true;
|
|
3933
|
+
buffer += ch;
|
|
3934
|
+
continue;
|
|
3935
|
+
}
|
|
3936
|
+
if (ch === "-" && scanLine[i + 1] === "-") break;
|
|
3937
|
+
if (ch === ";") {
|
|
3938
|
+
const statement = buffer.trim();
|
|
3939
|
+
if (statement.length > 0) statements.push(statement);
|
|
3940
|
+
buffer = "";
|
|
3941
|
+
continue;
|
|
3942
|
+
}
|
|
3943
|
+
buffer += ch;
|
|
3944
|
+
}
|
|
3945
|
+
if (inQuote) {
|
|
3946
|
+
buffer += "\n";
|
|
3947
|
+
} else if (buffer.length > 0 && !/\s$/.test(buffer)) {
|
|
3948
|
+
buffer += " ";
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3951
|
+
if (inQuote) {
|
|
3952
|
+
throw new Error(`SQL \u811A\u672C\u5F15\u53F7\u672A\u95ED\u5408\uFF1A${buffer.trim().slice(0, 80)}\u2026`);
|
|
3953
|
+
}
|
|
3954
|
+
const tail = buffer.trim();
|
|
3955
|
+
if (tail.length > 0) statements.push(tail);
|
|
3956
|
+
return statements;
|
|
3957
|
+
}
|
|
3958
|
+
var init_sql_split = __esm({
|
|
3959
|
+
"packages/runtime/src/shared/sql-split.ts"() {
|
|
3960
|
+
"use strict";
|
|
3961
|
+
}
|
|
3962
|
+
});
|
|
3963
|
+
|
|
3814
3964
|
// packages/cli/src/db.ts
|
|
3815
3965
|
var db_exports = {};
|
|
3816
3966
|
__export(db_exports, {
|
|
@@ -3912,61 +4062,20 @@ async function dbRollback(paths, options) {
|
|
|
3912
4062
|
{ method: "POST", body: { to: options.to } }
|
|
3913
4063
|
);
|
|
3914
4064
|
}
|
|
3915
|
-
function splitSqlStatements(source) {
|
|
3916
|
-
const statements = [];
|
|
3917
|
-
let buffer = "";
|
|
3918
|
-
let inQuote = false;
|
|
3919
|
-
const lines = source.split("\n");
|
|
3920
|
-
for (const rawLine of lines) {
|
|
3921
|
-
const trimmed = rawLine.trim();
|
|
3922
|
-
if (!inQuote && (trimmed.length === 0 || trimmed.startsWith("--"))) continue;
|
|
3923
|
-
for (let i = 0; i < rawLine.length; i++) {
|
|
3924
|
-
const ch = rawLine[i];
|
|
3925
|
-
if (inQuote) {
|
|
3926
|
-
if (ch === "'") {
|
|
3927
|
-
if (rawLine[i + 1] === "'") {
|
|
3928
|
-
buffer += ch + rawLine[i + 1];
|
|
3929
|
-
i++;
|
|
3930
|
-
continue;
|
|
3931
|
-
}
|
|
3932
|
-
inQuote = false;
|
|
3933
|
-
}
|
|
3934
|
-
buffer += ch;
|
|
3935
|
-
continue;
|
|
3936
|
-
}
|
|
3937
|
-
if (ch === "'") {
|
|
3938
|
-
inQuote = true;
|
|
3939
|
-
buffer += ch;
|
|
3940
|
-
continue;
|
|
3941
|
-
}
|
|
3942
|
-
if (ch === "-" && rawLine[i + 1] === "-") break;
|
|
3943
|
-
if (ch === ";") {
|
|
3944
|
-
const statement = buffer.trim();
|
|
3945
|
-
if (statement.length > 0) statements.push(statement);
|
|
3946
|
-
buffer = "";
|
|
3947
|
-
continue;
|
|
3948
|
-
}
|
|
3949
|
-
buffer += ch;
|
|
3950
|
-
}
|
|
3951
|
-
buffer += inQuote ? "\n" : " ";
|
|
3952
|
-
}
|
|
3953
|
-
if (inQuote) {
|
|
3954
|
-
throw new Error(`SQL \u8FC1\u79FB\u6587\u4EF6\u5F15\u53F7\u672A\u95ED\u5408\uFF1A${buffer.trim().slice(0, 80)}\u2026`);
|
|
3955
|
-
}
|
|
3956
|
-
const tail = buffer.trim();
|
|
3957
|
-
if (tail.length > 0) statements.push(tail);
|
|
3958
|
-
return statements;
|
|
3959
|
-
}
|
|
3960
4065
|
async function dbMigrate(paths, options) {
|
|
3961
|
-
const
|
|
3962
|
-
const
|
|
3963
|
-
|
|
3964
|
-
|
|
4066
|
+
const queue = [];
|
|
4067
|
+
for (const file2 of options.files) {
|
|
4068
|
+
const source = await readFile4(resolve3(file2), "utf8");
|
|
4069
|
+
const statements = splitSqlStatements(source);
|
|
4070
|
+
if (statements.length === 0) {
|
|
4071
|
+
throw new Error(`\u8FC1\u79FB\u6587\u4EF6\u6CA1\u6709\u53EF\u6267\u884C\u8BED\u53E5\uFF1A${file2}`);
|
|
4072
|
+
}
|
|
4073
|
+
for (const statement of statements) queue.push({ file: file2, statement });
|
|
3965
4074
|
}
|
|
3966
4075
|
const { project: project2 } = await open2(paths, options);
|
|
3967
4076
|
const applied = [];
|
|
3968
4077
|
const changes = [];
|
|
3969
|
-
for (const statement of
|
|
4078
|
+
for (const { file: file2, statement } of queue) {
|
|
3970
4079
|
try {
|
|
3971
4080
|
const result = await dbExec(paths, {
|
|
3972
4081
|
cwd: options.cwd,
|
|
@@ -3985,7 +4094,7 @@ async function dbMigrate(paths, options) {
|
|
|
3985
4094
|
projectId: project2,
|
|
3986
4095
|
applied,
|
|
3987
4096
|
changes,
|
|
3988
|
-
failed: { statement, code, message }
|
|
4097
|
+
failed: { file: file2, statement, code, message }
|
|
3989
4098
|
};
|
|
3990
4099
|
}
|
|
3991
4100
|
}
|
|
@@ -3996,12 +4105,14 @@ var init_db2 = __esm({
|
|
|
3996
4105
|
"use strict";
|
|
3997
4106
|
init_auth();
|
|
3998
4107
|
init_client();
|
|
4108
|
+
init_sql_split();
|
|
4109
|
+
init_sql_split();
|
|
3999
4110
|
}
|
|
4000
4111
|
});
|
|
4001
4112
|
|
|
4002
4113
|
// packages/cli/src/serve/sqlite-driver.ts
|
|
4003
4114
|
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
4004
|
-
import { dirname as
|
|
4115
|
+
import { dirname as dirname6, resolve as resolve4 } from "node:path";
|
|
4005
4116
|
function isBun(versions) {
|
|
4006
4117
|
return versions["bun"] !== void 0 && versions["bun"] !== "";
|
|
4007
4118
|
}
|
|
@@ -4051,7 +4162,7 @@ async function openSqliteProjectDriver(file2, options = {}) {
|
|
|
4051
4162
|
throw new Error(`${moduleName} \u672A\u5BFC\u51FA ${ctorName}\uFF1A\u5F53\u524D\u8FD0\u884C\u65F6\u7684 SQLite \u5185\u5EFA\u6A21\u5757\u4E0D\u53EF\u7528`);
|
|
4052
4163
|
}
|
|
4053
4164
|
const target = file2 === ":memory:" ? file2 : resolve4(file2);
|
|
4054
|
-
if (target !== ":memory:") await mkdir5(
|
|
4165
|
+
if (target !== ":memory:") await mkdir5(dirname6(target), { recursive: true });
|
|
4055
4166
|
const database = new Ctor(target);
|
|
4056
4167
|
database.exec("PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;");
|
|
4057
4168
|
return {
|
|
@@ -4090,7 +4201,7 @@ var init_sqlite_driver = __esm({
|
|
|
4090
4201
|
|
|
4091
4202
|
// packages/cli/src/serve/db-mode.ts
|
|
4092
4203
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
4093
|
-
import { join as
|
|
4204
|
+
import { join as join8, relative, resolve as resolve5 } from "node:path";
|
|
4094
4205
|
function isServeDbMode(value) {
|
|
4095
4206
|
return SERVE_DB_MODES.includes(value.trim().toLowerCase());
|
|
4096
4207
|
}
|
|
@@ -4125,7 +4236,7 @@ function displayPath(cwd, target) {
|
|
|
4125
4236
|
return rel.startsWith("..") ? target : rel.split(/[\\/]/u).join("/");
|
|
4126
4237
|
}
|
|
4127
4238
|
function simDbTarget(cwd) {
|
|
4128
|
-
return displayPath(cwd,
|
|
4239
|
+
return displayPath(cwd, join8(simDir(cwd), "db.json"));
|
|
4129
4240
|
}
|
|
4130
4241
|
function resolveLocalDbTarget(cwd, options) {
|
|
4131
4242
|
const mode = resolveServeDbMode(options.db);
|
|
@@ -4211,7 +4322,7 @@ var init_db_mode = __esm({
|
|
|
4211
4322
|
|
|
4212
4323
|
// packages/cli/src/sim/env.ts
|
|
4213
4324
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
4214
|
-
import { join as
|
|
4325
|
+
import { join as join9 } from "node:path";
|
|
4215
4326
|
function parseEnv(content) {
|
|
4216
4327
|
const env = {};
|
|
4217
4328
|
for (const raw of content.split(/\r?\n/)) {
|
|
@@ -4226,8 +4337,8 @@ function parseEnv(content) {
|
|
|
4226
4337
|
return env;
|
|
4227
4338
|
}
|
|
4228
4339
|
async function loadSimEnv(cwd, config2 = {}) {
|
|
4229
|
-
const envRoot = await readFile6(
|
|
4230
|
-
const envLocal = await readFile6(
|
|
4340
|
+
const envRoot = await readFile6(join9(cwd, ".env"), "utf8").catch(() => "");
|
|
4341
|
+
const envLocal = await readFile6(join9(cwd, ".env.local"), "utf8").catch(() => "");
|
|
4231
4342
|
const merged = { ...parseEnv(envRoot), ...parseEnv(envLocal) };
|
|
4232
4343
|
for (const secret of config2.secrets ?? []) {
|
|
4233
4344
|
if (merged[secret] !== void 0) continue;
|
|
@@ -4247,6 +4358,32 @@ var init_env = __esm({
|
|
|
4247
4358
|
}
|
|
4248
4359
|
});
|
|
4249
4360
|
|
|
4361
|
+
// packages/cli/src/sim/fetch-config.ts
|
|
4362
|
+
function resolveLocalFetchConfig(simEnv) {
|
|
4363
|
+
const rawAllowlist = simEnv.FUNCTIONS_FETCH_ALLOWLIST;
|
|
4364
|
+
if (rawAllowlist === void 0) return void 0;
|
|
4365
|
+
const rawTimeout = simEnv.FUNCTIONS_FETCH_TIMEOUT_MS;
|
|
4366
|
+
let timeoutMs = LOCAL_FETCH_TIMEOUT_MS_DEFAULT;
|
|
4367
|
+
if (rawTimeout !== void 0 && rawTimeout.trim() !== "") {
|
|
4368
|
+
const parsed = Number(rawTimeout);
|
|
4369
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
4370
|
+
throw new Error(
|
|
4371
|
+
`[adep] FUNCTIONS_FETCH_TIMEOUT_MS \u975E\u6CD5\uFF1A"${rawTimeout}"\uFF08\u987B\u4E3A\u6B63\u6574\u6570\u6BEB\u79D2\u6570\uFF1B\u4E0D\u914D\u5219\u7F3A\u7701 ${LOCAL_FETCH_TIMEOUT_MS_DEFAULT}\uFF09`
|
|
4372
|
+
);
|
|
4373
|
+
}
|
|
4374
|
+
timeoutMs = parsed;
|
|
4375
|
+
}
|
|
4376
|
+
return { allowlist: parseNameList(rawAllowlist), timeoutMs };
|
|
4377
|
+
}
|
|
4378
|
+
var LOCAL_FETCH_TIMEOUT_MS_DEFAULT;
|
|
4379
|
+
var init_fetch_config = __esm({
|
|
4380
|
+
"packages/cli/src/sim/fetch-config.ts"() {
|
|
4381
|
+
"use strict";
|
|
4382
|
+
init_manifest();
|
|
4383
|
+
LOCAL_FETCH_TIMEOUT_MS_DEFAULT = 1e4;
|
|
4384
|
+
}
|
|
4385
|
+
});
|
|
4386
|
+
|
|
4250
4387
|
// packages/cli/src/sim/invoke.ts
|
|
4251
4388
|
function resolveFunctionEntry(files, fnName) {
|
|
4252
4389
|
const flat = `${fnName}.ts`;
|
|
@@ -4376,6 +4513,11 @@ var init_boundary = __esm({
|
|
|
4376
4513
|
kind: "diff",
|
|
4377
4514
|
title: "\u4E0D\u8BA1\u91CF",
|
|
4378
4515
|
detail: "\u672C\u6A21\u62DF\u8FD0\u884C\u65F6\u4E0D\u4EA7\u51FA\u8BA1\u91CF\u4E8B\u4EF6\uFF0C\u4E5F\u4E0D\u5199 billing\uFF1B\u79BB\u7EBF\u5F00\u53D1\u4E0D\u8BA1\u8D39\u3002"
|
|
4516
|
+
},
|
|
4517
|
+
{
|
|
4518
|
+
kind: "diff",
|
|
4519
|
+
title: "\u51FA\u7F51\u7531\u767D\u540D\u5355\u63A7\u5236",
|
|
4520
|
+
detail: "cloud.fetch \u9ED8\u8BA4\u65E0\u7F51\u7EDC\uFF08\u672A\u914D\u7F6E\u65F6\u8C03\u7528\u629B FN_FETCH_DISABLED\uFF09\uFF1B.env \u914D FUNCTIONS_FETCH_ALLOWLIST\uFF08\u9017\u53F7\u5206\u9694\u4E3B\u673A\uFF0C*. \u901A\u914D\uFF1BFUNCTIONS_FETCH_TIMEOUT_MS \u7F3A\u7701 10s\uFF09\u540E\u91CD\u542F\u6CE8\u5165\u53D7\u63A7 fetch\u2014\u2014\u95E8\u7981\u4E0E\u7EBF\u4E0A\u4E00\u81F4\uFF08\u767D\u540D\u5355 / \u8D85\u65F6 / \u91CD\u5B9A\u5411\u9010\u8DF3\u590D\u68C0\uFF09\uFF0C\u4F46\u672C\u5730\u7531\u5F00\u53D1\u673A\u7F51\u7EDC\u6808\u76F4\u8FDE\uFF0C\u65E0\u5E73\u53F0\u51FA\u7F51\u4E2D\u7EE7\u4E0E\u5BA1\u8BA1\u3002"
|
|
4379
4521
|
}
|
|
4380
4522
|
];
|
|
4381
4523
|
}
|
|
@@ -4383,9 +4525,9 @@ var init_boundary = __esm({
|
|
|
4383
4525
|
|
|
4384
4526
|
// packages/cli/src/ts-config.ts
|
|
4385
4527
|
import { stat as stat4, readFile as readFile7 } from "node:fs/promises";
|
|
4386
|
-
import { join as
|
|
4528
|
+
import { join as join10 } from "node:path";
|
|
4387
4529
|
async function loadAdepConfigModule(cwd) {
|
|
4388
|
-
const configPath =
|
|
4530
|
+
const configPath = join10(cwd, "adep.config.ts");
|
|
4389
4531
|
try {
|
|
4390
4532
|
await stat4(configPath);
|
|
4391
4533
|
} catch {
|
|
@@ -5746,7 +5888,7 @@ var init_chain = __esm({
|
|
|
5746
5888
|
// packages/runtime/src/functions/runtime/worker-entry.ts
|
|
5747
5889
|
import { parentPort, workerData } from "node:worker_threads";
|
|
5748
5890
|
import { createRequire } from "node:module";
|
|
5749
|
-
import { join as
|
|
5891
|
+
import { join as join11 } from "node:path";
|
|
5750
5892
|
function errorMessageOf2(error62) {
|
|
5751
5893
|
if (error62 instanceof Error) return error62.message;
|
|
5752
5894
|
if (typeof error62 === "object" && error62 !== null && "message" in error62) {
|
|
@@ -5801,7 +5943,7 @@ function errorMessageWithLocation(error62, files) {
|
|
|
5801
5943
|
}
|
|
5802
5944
|
function createBareResolver(deps) {
|
|
5803
5945
|
const platformRequire = createRequire(import.meta.url);
|
|
5804
|
-
const depsRequire = deps.dir === null ? null : createRequire(
|
|
5946
|
+
const depsRequire = deps.dir === null ? null : createRequire(join11(deps.dir, "__deps__.js"));
|
|
5805
5947
|
return (request) => {
|
|
5806
5948
|
if (deps.builtin.includes(request)) return platformRequire(request);
|
|
5807
5949
|
const root = splitBareSpecifier(request);
|
|
@@ -5994,13 +6136,127 @@ var init_function_source = __esm({
|
|
|
5994
6136
|
}
|
|
5995
6137
|
});
|
|
5996
6138
|
|
|
6139
|
+
// packages/runtime/src/shared/multipart.ts
|
|
6140
|
+
function extractBoundary(contentType) {
|
|
6141
|
+
const match = /boundary\s*=\s*(?:"([^"]+)"|([^;\s]+))/i.exec(contentType);
|
|
6142
|
+
if (match === null) {
|
|
6143
|
+
throw new MultipartParseError("Content-Type \u7F3A\u5C11 boundary \u53C2\u6570\uFF0C\u65E0\u6CD5\u89E3\u6790 multipart \u8BF7\u6C42\u4F53");
|
|
6144
|
+
}
|
|
6145
|
+
const boundary = match[1] ?? match[2];
|
|
6146
|
+
if (boundary === void 0 || boundary.length === 0) {
|
|
6147
|
+
throw new MultipartParseError("Content-Type \u7684 boundary \u4E3A\u7A7A");
|
|
6148
|
+
}
|
|
6149
|
+
return boundary;
|
|
6150
|
+
}
|
|
6151
|
+
function indexOfSequence(haystack, needle, from) {
|
|
6152
|
+
outer: for (let i = from; i + needle.length <= haystack.length; i++) {
|
|
6153
|
+
for (let j = 0; j < needle.length; j++) {
|
|
6154
|
+
if (haystack[i + j] !== needle[j]) continue outer;
|
|
6155
|
+
}
|
|
6156
|
+
return i;
|
|
6157
|
+
}
|
|
6158
|
+
return -1;
|
|
6159
|
+
}
|
|
6160
|
+
function unquote(value) {
|
|
6161
|
+
return value.replace(/\\(.)/g, "$1");
|
|
6162
|
+
}
|
|
6163
|
+
function parseMultipart(contentType, raw) {
|
|
6164
|
+
const boundary = extractBoundary(contentType);
|
|
6165
|
+
const delim = encoder2.encode(`--${boundary}`);
|
|
6166
|
+
const positions = [];
|
|
6167
|
+
scan: for (let i = 0; i + delim.length <= raw.length; i++) {
|
|
6168
|
+
if (raw[i] !== delim[0]) continue;
|
|
6169
|
+
for (let j = 1; j < delim.length; j++) {
|
|
6170
|
+
if (raw[i + j] !== delim[j]) continue scan;
|
|
6171
|
+
}
|
|
6172
|
+
positions.push(i);
|
|
6173
|
+
}
|
|
6174
|
+
if (positions.length === 0) {
|
|
6175
|
+
throw new MultipartParseError(
|
|
6176
|
+
`\u8BF7\u6C42\u4F53\u91CC\u627E\u4E0D\u5230 boundary "${boundary}" \u7684\u5206\u9694\u7B26\u2014\u2014\u53EF\u80FD\u662F\u8BF7\u6C42\u88AB\u622A\u65AD\u6216 Content-Type \u4E0E\u8BF7\u6C42\u4F53\u4E0D\u5339\u914D`
|
|
6177
|
+
);
|
|
6178
|
+
}
|
|
6179
|
+
const lastPos = positions[positions.length - 1];
|
|
6180
|
+
if (raw[lastPos + delim.length] !== 45 || raw[lastPos + delim.length + 1] !== 45) {
|
|
6181
|
+
throw new MultipartParseError("multipart \u6570\u636E\u88AB\u622A\u65AD\uFF1A\u7F3A\u5C11\u7EC8\u7ED3\u5206\u9694\u7B26 --boundary--");
|
|
6182
|
+
}
|
|
6183
|
+
const files = [];
|
|
6184
|
+
const fields = {};
|
|
6185
|
+
let fieldCount = 0;
|
|
6186
|
+
for (let k = 0; k + 1 < positions.length; k++) {
|
|
6187
|
+
const partStart = positions[k] + delim.length + 2;
|
|
6188
|
+
const partEnd = positions[k + 1] - 2;
|
|
6189
|
+
if (raw[partStart - 2] !== 13 || raw[partStart - 1] !== 10) {
|
|
6190
|
+
throw new MultipartParseError("multipart \u5206\u9694\u7B26\u540E\u7F3A\u5C11 CRLF\uFF0C\u8BF7\u6C42\u4F53\u683C\u5F0F\u975E\u6CD5");
|
|
6191
|
+
}
|
|
6192
|
+
if (partEnd < partStart) {
|
|
6193
|
+
throw new MultipartParseError("multipart part \u5185\u5BB9\u4E3A\u7A7A\uFF08header \u4E0E\u6B63\u6587\u90FD\u4E0D\u5B58\u5728\uFF09");
|
|
6194
|
+
}
|
|
6195
|
+
const part = raw.subarray(partStart, partEnd);
|
|
6196
|
+
const headerSep = indexOfSequence(part, HEADER_BODY_SEP, 0);
|
|
6197
|
+
if (headerSep < 0) {
|
|
6198
|
+
throw new MultipartParseError("multipart part \u7F3A\u5C11 header \u4E0E\u6B63\u6587\u4E4B\u95F4\u7684\u7A7A\u884C\u5206\u9694");
|
|
6199
|
+
}
|
|
6200
|
+
const headerLines = decoder2.decode(part.subarray(0, headerSep)).split("\r\n");
|
|
6201
|
+
const data = part.subarray(headerSep + HEADER_BODY_SEP.length);
|
|
6202
|
+
const disposition = headerLines.find(
|
|
6203
|
+
(line) => line.toLowerCase().startsWith("content-disposition:")
|
|
6204
|
+
);
|
|
6205
|
+
if (disposition === void 0) {
|
|
6206
|
+
throw new MultipartParseError("multipart part \u7F3A\u5C11 Content-Disposition \u5934");
|
|
6207
|
+
}
|
|
6208
|
+
const nameMatch = /name="((?:[^"\\]|\\.)*)"/.exec(disposition);
|
|
6209
|
+
if (nameMatch === null) {
|
|
6210
|
+
throw new MultipartParseError("multipart part \u7684 Content-Disposition \u7F3A\u5C11 name \u53C2\u6570");
|
|
6211
|
+
}
|
|
6212
|
+
const fieldName = unquote(nameMatch[1]);
|
|
6213
|
+
const filenameMatch = /filename="((?:[^"\\]|\\.)*)"/.exec(disposition);
|
|
6214
|
+
if (filenameMatch !== null) {
|
|
6215
|
+
const clientName = unquote(filenameMatch[1]);
|
|
6216
|
+
if (clientName === "") continue;
|
|
6217
|
+
const typeLine = headerLines.find((line) => line.toLowerCase().startsWith("content-type:"));
|
|
6218
|
+
const type = typeLine === void 0 ? "application/octet-stream" : typeLine.slice(typeLine.indexOf(":") + 1).trim();
|
|
6219
|
+
files.push({ name: clientName, type, size: data.length, data });
|
|
6220
|
+
} else {
|
|
6221
|
+
const value = decoder2.decode(data);
|
|
6222
|
+
const prev = fields[fieldName];
|
|
6223
|
+
if (prev === void 0) fields[fieldName] = value;
|
|
6224
|
+
else if (typeof prev === "string") fields[fieldName] = [prev, value];
|
|
6225
|
+
else fields[fieldName] = [...prev, value];
|
|
6226
|
+
fieldCount++;
|
|
6227
|
+
}
|
|
6228
|
+
}
|
|
6229
|
+
return { fields: fieldCount > 0 ? fields : void 0, files };
|
|
6230
|
+
}
|
|
6231
|
+
var MultipartParseError, HEADER_BODY_SEP, encoder2, decoder2;
|
|
6232
|
+
var init_multipart = __esm({
|
|
6233
|
+
"packages/runtime/src/shared/multipart.ts"() {
|
|
6234
|
+
"use strict";
|
|
6235
|
+
MultipartParseError = class extends Error {
|
|
6236
|
+
constructor(message) {
|
|
6237
|
+
super(message);
|
|
6238
|
+
this.name = "MultipartParseError";
|
|
6239
|
+
}
|
|
6240
|
+
};
|
|
6241
|
+
HEADER_BODY_SEP = [13, 10, 13, 10];
|
|
6242
|
+
encoder2 = new TextEncoder();
|
|
6243
|
+
decoder2 = new TextDecoder();
|
|
6244
|
+
}
|
|
6245
|
+
});
|
|
6246
|
+
|
|
5997
6247
|
// packages/cli/src/dev-shared.ts
|
|
5998
6248
|
import { readdir as readdir2, readFile as readFile8 } from "node:fs/promises";
|
|
5999
|
-
import { join as
|
|
6000
|
-
function bearerUserResolverFromEnv() {
|
|
6001
|
-
const raw = process.env.ADEP_AUTH_ISSUER;
|
|
6002
|
-
|
|
6003
|
-
|
|
6249
|
+
import { join as join12 } from "node:path";
|
|
6250
|
+
function bearerUserResolverFromEnv(fileEnv = {}) {
|
|
6251
|
+
const raw = firstNonEmpty(process.env.ADEP_AUTH_ISSUER, fileEnv.ADEP_AUTH_ISSUER);
|
|
6252
|
+
return raw === void 0 ? void 0 : createBearerUserResolver(raw);
|
|
6253
|
+
}
|
|
6254
|
+
function firstNonEmpty(...values) {
|
|
6255
|
+
for (const value of values) {
|
|
6256
|
+
const trimmed = value?.trim();
|
|
6257
|
+
if (trimmed !== void 0 && trimmed !== "") return trimmed;
|
|
6258
|
+
}
|
|
6259
|
+
return void 0;
|
|
6004
6260
|
}
|
|
6005
6261
|
function createBearerUserResolver(issuer) {
|
|
6006
6262
|
const userinfoUrl = `${issuer.replace(/\/+$/, "")}/oauth/userinfo`;
|
|
@@ -6037,7 +6293,7 @@ async function collectFunctions(dir, readImpl = (path) => readFile8(path, "utf8"
|
|
|
6037
6293
|
}
|
|
6038
6294
|
for (const entry of entries) {
|
|
6039
6295
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
6040
|
-
const full =
|
|
6296
|
+
const full = join12(sub, entry.name);
|
|
6041
6297
|
if (entry.isDirectory()) {
|
|
6042
6298
|
await walk(full, rel);
|
|
6043
6299
|
} else if (entry.isFile() && isRuntimeSource(entry.name)) {
|
|
@@ -6067,25 +6323,41 @@ function mergeSharedIntoFunctions(files) {
|
|
|
6067
6323
|
}
|
|
6068
6324
|
return out;
|
|
6069
6325
|
}
|
|
6070
|
-
function
|
|
6071
|
-
return new Promise((
|
|
6326
|
+
function readRawBody(req) {
|
|
6327
|
+
return new Promise((resolveRaw, rejectRaw) => {
|
|
6072
6328
|
const chunks = [];
|
|
6073
6329
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
6074
|
-
req.on("end", () =>
|
|
6075
|
-
|
|
6076
|
-
if (raw.length === 0) {
|
|
6077
|
-
resolveBody(void 0);
|
|
6078
|
-
return;
|
|
6079
|
-
}
|
|
6080
|
-
try {
|
|
6081
|
-
resolveBody(JSON.parse(raw));
|
|
6082
|
-
} catch {
|
|
6083
|
-
resolveBody(raw);
|
|
6084
|
-
}
|
|
6085
|
-
});
|
|
6086
|
-
req.on("error", rejectBody);
|
|
6330
|
+
req.on("end", () => resolveRaw(Buffer.concat(chunks)));
|
|
6331
|
+
req.on("error", rejectRaw);
|
|
6087
6332
|
});
|
|
6088
6333
|
}
|
|
6334
|
+
async function bodyOf(req) {
|
|
6335
|
+
const raw = (await readRawBody(req)).toString("utf8");
|
|
6336
|
+
if (raw.length === 0) return void 0;
|
|
6337
|
+
try {
|
|
6338
|
+
return JSON.parse(raw);
|
|
6339
|
+
} catch {
|
|
6340
|
+
return raw;
|
|
6341
|
+
}
|
|
6342
|
+
}
|
|
6343
|
+
async function bodyWithFiles(req) {
|
|
6344
|
+
const contentType = String(req.headers["content-type"] ?? "");
|
|
6345
|
+
if (!contentType.toLowerCase().startsWith("multipart/form-data")) {
|
|
6346
|
+
return { body: await bodyOf(req) };
|
|
6347
|
+
}
|
|
6348
|
+
const bytes = await readRawBody(req);
|
|
6349
|
+
let parsed;
|
|
6350
|
+
try {
|
|
6351
|
+
parsed = parseMultipart(contentType, bytes);
|
|
6352
|
+
} catch (error62) {
|
|
6353
|
+
const message = error62 instanceof MultipartParseError ? error62.message : `multipart \u89E3\u6790\u5931\u8D25\uFF1A${error62 instanceof Error ? error62.message : String(error62)}`;
|
|
6354
|
+
throw new ExecutorError(400, "FN_MULTIPART_INVALID", message);
|
|
6355
|
+
}
|
|
6356
|
+
return {
|
|
6357
|
+
body: parsed.fields,
|
|
6358
|
+
...parsed.files.length > 0 ? { files: [...parsed.files] } : {}
|
|
6359
|
+
};
|
|
6360
|
+
}
|
|
6089
6361
|
function writeJson(res, status, payload) {
|
|
6090
6362
|
res.writeHead(status, { "content-type": "application/json" });
|
|
6091
6363
|
res.end(JSON.stringify(payload));
|
|
@@ -6100,13 +6372,14 @@ async function requestInput(url2, req, readBody) {
|
|
|
6100
6372
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
6101
6373
|
if (typeof value === "string") headers[key] = value;
|
|
6102
6374
|
}
|
|
6103
|
-
const
|
|
6375
|
+
const parsed = req.method === "GET" || req.method === "HEAD" ? void 0 : await readBody(req);
|
|
6104
6376
|
return {
|
|
6105
6377
|
method: req.method ?? "GET",
|
|
6106
6378
|
path: url2.pathname,
|
|
6107
6379
|
query,
|
|
6108
6380
|
headers,
|
|
6109
|
-
...body === void 0 ? {} : { body }
|
|
6381
|
+
...parsed?.body === void 0 ? {} : { body: parsed.body },
|
|
6382
|
+
...parsed?.files === void 0 ? {} : { files: parsed.files }
|
|
6110
6383
|
};
|
|
6111
6384
|
}
|
|
6112
6385
|
var BEARER_TOKEN_RE;
|
|
@@ -6115,6 +6388,8 @@ var init_dev_shared = __esm({
|
|
|
6115
6388
|
"use strict";
|
|
6116
6389
|
init_function_source();
|
|
6117
6390
|
init_shared_source();
|
|
6391
|
+
init_multipart();
|
|
6392
|
+
init_executor_runtime();
|
|
6118
6393
|
init_invoke();
|
|
6119
6394
|
BEARER_TOKEN_RE = /^Bearer\s+(.+)$/i;
|
|
6120
6395
|
}
|
|
@@ -6130,8 +6405,8 @@ __export(dev_exports, {
|
|
|
6130
6405
|
});
|
|
6131
6406
|
import { createServer } from "node:http";
|
|
6132
6407
|
import { watch } from "node:fs";
|
|
6133
|
-
import { mkdir as mkdir6, readFile as readFile9, writeFile as
|
|
6134
|
-
import { basename, join as
|
|
6408
|
+
import { mkdir as mkdir6, readFile as readFile9, writeFile as writeFile5 } from "node:fs/promises";
|
|
6409
|
+
import { basename, join as join13, resolve as resolve6 } from "node:path";
|
|
6135
6410
|
async function loadConfig(cwd) {
|
|
6136
6411
|
const name = basename(resolve6(cwd));
|
|
6137
6412
|
const config2 = await loadAdepConfigModule(cwd);
|
|
@@ -6176,10 +6451,10 @@ function printBoundaries(log) {
|
|
|
6176
6451
|
}
|
|
6177
6452
|
}
|
|
6178
6453
|
async function ensureGitignore(cwd) {
|
|
6179
|
-
const gitignorePath =
|
|
6454
|
+
const gitignorePath = join13(cwd, ".gitignore");
|
|
6180
6455
|
const existing = await readFile9(gitignorePath, "utf8").catch(() => "");
|
|
6181
6456
|
if (existing.split(/\r?\n/).includes(".adep/")) return;
|
|
6182
|
-
await
|
|
6457
|
+
await writeFile5(gitignorePath, `${existing.replace(/\n+$/, "")}
|
|
6183
6458
|
.adep/
|
|
6184
6459
|
`, "utf8");
|
|
6185
6460
|
}
|
|
@@ -6191,16 +6466,25 @@ async function startDevServer(options) {
|
|
|
6191
6466
|
if (options.prefix !== void 0) {
|
|
6192
6467
|
config2.functionsPrefix = options.prefix.replace(/^\/+|\/+$/g, "");
|
|
6193
6468
|
}
|
|
6194
|
-
const functionsDir =
|
|
6469
|
+
const functionsDir = join13(cwd, config2.functionsDir);
|
|
6195
6470
|
const coldStartAt = Date.now();
|
|
6196
6471
|
const dbTarget = resolveLocalDbTarget(cwd, {
|
|
6197
6472
|
...options.db === void 0 ? {} : { db: options.db },
|
|
6198
6473
|
...options.dbFile === void 0 ? {} : { dbFile: options.dbFile }
|
|
6199
6474
|
});
|
|
6200
|
-
const
|
|
6475
|
+
const simEnv = await loadSimEnv(cwd).catch(() => ({}));
|
|
6476
|
+
let bearerUser = bearerUserResolverFromEnv(simEnv);
|
|
6477
|
+
const fetchConfig = resolveLocalFetchConfig(simEnv);
|
|
6201
6478
|
const executor = new WorkerFunctionExecutor({
|
|
6202
|
-
deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS }
|
|
6479
|
+
deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS },
|
|
6480
|
+
// GAME-007 本地接线:配置白名单才注入受控 fetch,语义与线上逐字一致。
|
|
6481
|
+
...fetchConfig === void 0 ? {} : { fetch: fetchConfig }
|
|
6203
6482
|
});
|
|
6483
|
+
if (fetchConfig !== void 0) {
|
|
6484
|
+
log(
|
|
6485
|
+
`[adep] \u53D7\u63A7 fetch \u5DF2\u6CE8\u5165\uFF08FUNCTIONS_FETCH_ALLOWLIST\uFF09\uFF1A\u767D\u540D\u5355 ${fetchConfig.allowlist.length} \u9879\uFF0C\u8D85\u65F6 ${fetchConfig.timeoutMs}ms`
|
|
6486
|
+
);
|
|
6487
|
+
}
|
|
6204
6488
|
await mkdir6(functionsDir, { recursive: true });
|
|
6205
6489
|
const db = await openLocalDbDriver(dbTarget, { cwd, tag: "adep", log });
|
|
6206
6490
|
const runtime = await createSimRuntime({
|
|
@@ -6223,7 +6507,7 @@ async function startDevServer(options) {
|
|
|
6223
6507
|
let files = mergeSharedIntoFunctions(await collectFunctions(functionsDir));
|
|
6224
6508
|
let env = {
|
|
6225
6509
|
...config2.environment,
|
|
6226
|
-
...
|
|
6510
|
+
...simEnv
|
|
6227
6511
|
};
|
|
6228
6512
|
const dbBundle = runtime.bundle;
|
|
6229
6513
|
const invokeHandler = createSimInvokeHandler({ executor, files });
|
|
@@ -6299,12 +6583,13 @@ async function startDevServer(options) {
|
|
|
6299
6583
|
const reload = async () => {
|
|
6300
6584
|
const [nextFiles, envText2] = await Promise.all([
|
|
6301
6585
|
collectFunctions(functionsDir).then(mergeSharedIntoFunctions),
|
|
6302
|
-
readFile9(
|
|
6586
|
+
readFile9(join13(cwd, ".env.local"), "utf8").catch(() => "")
|
|
6303
6587
|
]);
|
|
6304
6588
|
files = nextFiles;
|
|
6305
6589
|
env = { ...config2.environment, ...parseEnvFile(envText2) };
|
|
6590
|
+
bearerUser = bearerUserResolverFromEnv(await loadSimEnv(cwd).catch(() => ({})));
|
|
6306
6591
|
};
|
|
6307
|
-
const envText = await readFile9(
|
|
6592
|
+
const envText = await readFile9(join13(cwd, ".env.local"), "utf8").catch(() => "");
|
|
6308
6593
|
env = { ...config2.environment, ...parseEnvFile(envText) };
|
|
6309
6594
|
let debounceTimer;
|
|
6310
6595
|
let watcher;
|
|
@@ -6320,7 +6605,7 @@ async function startDevServer(options) {
|
|
|
6320
6605
|
}
|
|
6321
6606
|
const buildInput = async (fnName, entry, url2, req) => {
|
|
6322
6607
|
const hasEnv = Object.keys(env).length > 0;
|
|
6323
|
-
const request = await requestInput(url2, req,
|
|
6608
|
+
const request = await requestInput(url2, req, bodyWithFiles);
|
|
6324
6609
|
if (bearerUser !== void 0) request.user = await bearerUser(request.headers);
|
|
6325
6610
|
return {
|
|
6326
6611
|
project: { id: "local", slug: config2.name },
|
|
@@ -6394,9 +6679,9 @@ async function startDevServer(options) {
|
|
|
6394
6679
|
writeJson(res, 404, { error: { code: "FN_NOT_FOUND", message: `\u51FD\u6570 "${fnName}" \u4E0D\u5B58\u5728` } });
|
|
6395
6680
|
return;
|
|
6396
6681
|
}
|
|
6397
|
-
const input2 = await buildInput(fnName, entry, url2, req);
|
|
6398
6682
|
const startedAt = performance.now();
|
|
6399
6683
|
try {
|
|
6684
|
+
const input2 = await buildInput(fnName, entry, url2, req);
|
|
6400
6685
|
const result = await executor.execute(input2);
|
|
6401
6686
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
6402
6687
|
for (const line of result.logs) log(`[adep] ${line}`);
|
|
@@ -6469,7 +6754,9 @@ async function startDevServer(options) {
|
|
|
6469
6754
|
log(`[adep] curl \u793A\u4F8B\uFF1Acurl ${baseUrl}${curlPath}`);
|
|
6470
6755
|
printBoundaries(log);
|
|
6471
6756
|
if (bearerUser !== void 0) {
|
|
6472
|
-
log(
|
|
6757
|
+
log(
|
|
6758
|
+
`[adep] \u767B\u5F55\u5373\u670D\u52A1\uFF1AADEP_AUTH_ISSUER \u5DF2\u914D\u7F6E\uFF0CBearer token \u5C06\u89E3\u6790\u4E3A\u7528\u6237\u8EAB\u4EFD\uFF08userinfo \u7AEF\u70B9\uFF09`
|
|
6759
|
+
);
|
|
6473
6760
|
}
|
|
6474
6761
|
log(`[adep] \u6570\u636E\u5E93\uFF1A${dbLabel} \u2192 ${dbTargetText}`);
|
|
6475
6762
|
startStateAlarmScheduler();
|
|
@@ -6496,6 +6783,7 @@ var init_dev = __esm({
|
|
|
6496
6783
|
init_runtime();
|
|
6497
6784
|
init_db_mode();
|
|
6498
6785
|
init_env();
|
|
6786
|
+
init_fetch_config();
|
|
6499
6787
|
init_invoke();
|
|
6500
6788
|
init_builtin_deps2();
|
|
6501
6789
|
init_boundary();
|
|
@@ -6549,6 +6837,75 @@ var init_prompt = __esm({
|
|
|
6549
6837
|
}
|
|
6550
6838
|
});
|
|
6551
6839
|
|
|
6840
|
+
// packages/cli/src/export/client.ts
|
|
6841
|
+
var client_exports2 = {};
|
|
6842
|
+
__export(client_exports2, {
|
|
6843
|
+
createExportApiClient: () => createExportApiClient
|
|
6844
|
+
});
|
|
6845
|
+
import { writeFile as writeFile8 } from "node:fs/promises";
|
|
6846
|
+
function toExportJob(view) {
|
|
6847
|
+
return {
|
|
6848
|
+
id: view.id,
|
|
6849
|
+
status: view.status,
|
|
6850
|
+
progress: view.progress,
|
|
6851
|
+
createdAt: view.createdAt,
|
|
6852
|
+
...view.stage === void 0 ? {} : { stage: view.stage },
|
|
6853
|
+
...view.error === void 0 ? {} : { error: view.error },
|
|
6854
|
+
...view.downloadUrl === void 0 ? {} : { downloadUrl: view.downloadUrl },
|
|
6855
|
+
...view.bundleSize === void 0 ? {} : { bundleSize: view.bundleSize },
|
|
6856
|
+
...view.completedAt === void 0 ? {} : { completedAt: view.completedAt }
|
|
6857
|
+
};
|
|
6858
|
+
}
|
|
6859
|
+
async function createExportApiClient(paths) {
|
|
6860
|
+
const client = await createClient(paths);
|
|
6861
|
+
return {
|
|
6862
|
+
async triggerExport(projectId, options) {
|
|
6863
|
+
const view = await client.request(
|
|
6864
|
+
`/api/v1/projects/${encodeURIComponent(projectId)}/export`,
|
|
6865
|
+
{
|
|
6866
|
+
method: "POST",
|
|
6867
|
+
body: {
|
|
6868
|
+
withData: options.withData,
|
|
6869
|
+
withSource: options.withSource,
|
|
6870
|
+
...options.withoutSource === true ? { withoutSource: true } : {}
|
|
6871
|
+
}
|
|
6872
|
+
},
|
|
6873
|
+
"EXPORT_TRIGGER_FAILED"
|
|
6874
|
+
);
|
|
6875
|
+
return toExportJob(view);
|
|
6876
|
+
},
|
|
6877
|
+
async getJobStatus(jobId) {
|
|
6878
|
+
const view = await client.request(
|
|
6879
|
+
`/api/v1/exports/${encodeURIComponent(jobId)}`,
|
|
6880
|
+
{},
|
|
6881
|
+
"EXPORT_STATUS_FAILED"
|
|
6882
|
+
);
|
|
6883
|
+
return toExportJob(view);
|
|
6884
|
+
},
|
|
6885
|
+
async downloadBundle(jobId, outputPath) {
|
|
6886
|
+
const download = await client.request(
|
|
6887
|
+
`/api/v1/exports/${encodeURIComponent(jobId)}/download`,
|
|
6888
|
+
{},
|
|
6889
|
+
"EXPORT_DOWNLOAD_FAILED"
|
|
6890
|
+
);
|
|
6891
|
+
if (download.downloadUrl.length === 0) {
|
|
6892
|
+
throw new CliError("EXPORT_BUNDLE_UNAVAILABLE", "\u5BFC\u51FA\u4EA7\u7269\u4E0B\u8F7D URL \u4E3A\u7A7A\uFF0C\u4EA7\u7269\u53EF\u80FD\u5C1A\u4E0D\u53EF\u7528");
|
|
6893
|
+
}
|
|
6894
|
+
const response = await client.download(download.downloadUrl, "EXPORT_DOWNLOAD_FAILED");
|
|
6895
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
6896
|
+
await writeFile8(outputPath, bytes);
|
|
6897
|
+
return { path: outputPath, size: bytes.length };
|
|
6898
|
+
}
|
|
6899
|
+
};
|
|
6900
|
+
}
|
|
6901
|
+
var init_client2 = __esm({
|
|
6902
|
+
"packages/cli/src/export/client.ts"() {
|
|
6903
|
+
"use strict";
|
|
6904
|
+
init_auth();
|
|
6905
|
+
init_client();
|
|
6906
|
+
}
|
|
6907
|
+
});
|
|
6908
|
+
|
|
6552
6909
|
// shared/deploy-bundle/manifest.ts
|
|
6553
6910
|
var CURRENT_SCHEMA_VERSION, BundleContentKind, ALLOWED_CONTENT_KINDS;
|
|
6554
6911
|
var init_manifest2 = __esm({
|
|
@@ -6820,7 +7177,7 @@ function zipRead(buf) {
|
|
|
6820
7177
|
if (eocd < 0) throw new ZipFormatError("\u627E\u4E0D\u5230 EOCD \u7B7E\u540D");
|
|
6821
7178
|
const total = r.u16(eocd + 10);
|
|
6822
7179
|
const centralOffset = r.u32(eocd + 16);
|
|
6823
|
-
const
|
|
7180
|
+
const decoder3 = new TextDecoder();
|
|
6824
7181
|
const out = /* @__PURE__ */ new Map();
|
|
6825
7182
|
let cursor = centralOffset;
|
|
6826
7183
|
for (let i = 0; i < total; i++) {
|
|
@@ -6834,7 +7191,7 @@ function zipRead(buf) {
|
|
|
6834
7191
|
const commentLen = r.u16(cursor + 32);
|
|
6835
7192
|
const localHeaderOffset = r.u32(cursor + 42);
|
|
6836
7193
|
if (localHeaderOffset + 30 > buf.length) throw new ZipFormatError("\u672C\u5730\u5934\u504F\u79FB\u8D8A\u754C");
|
|
6837
|
-
const name =
|
|
7194
|
+
const name = decoder3.decode(r.slice(cursor + 46, nameLen));
|
|
6838
7195
|
const localNameLen = r.u16(localHeaderOffset + 26);
|
|
6839
7196
|
const localExtraLen = r.u16(localHeaderOffset + 28);
|
|
6840
7197
|
const dataStart = localHeaderOffset + 30 + localNameLen + localExtraLen;
|
|
@@ -6892,75 +7249,6 @@ var init_zip = __esm({
|
|
|
6892
7249
|
}
|
|
6893
7250
|
});
|
|
6894
7251
|
|
|
6895
|
-
// packages/cli/src/export/client.ts
|
|
6896
|
-
var client_exports2 = {};
|
|
6897
|
-
__export(client_exports2, {
|
|
6898
|
-
createExportApiClient: () => createExportApiClient
|
|
6899
|
-
});
|
|
6900
|
-
import { writeFile as writeFile7 } from "node:fs/promises";
|
|
6901
|
-
function toExportJob(view) {
|
|
6902
|
-
return {
|
|
6903
|
-
id: view.id,
|
|
6904
|
-
status: view.status,
|
|
6905
|
-
progress: view.progress,
|
|
6906
|
-
createdAt: view.createdAt,
|
|
6907
|
-
...view.stage === void 0 ? {} : { stage: view.stage },
|
|
6908
|
-
...view.error === void 0 ? {} : { error: view.error },
|
|
6909
|
-
...view.downloadUrl === void 0 ? {} : { downloadUrl: view.downloadUrl },
|
|
6910
|
-
...view.bundleSize === void 0 ? {} : { bundleSize: view.bundleSize },
|
|
6911
|
-
...view.completedAt === void 0 ? {} : { completedAt: view.completedAt }
|
|
6912
|
-
};
|
|
6913
|
-
}
|
|
6914
|
-
async function createExportApiClient(paths) {
|
|
6915
|
-
const client = await createClient(paths);
|
|
6916
|
-
return {
|
|
6917
|
-
async triggerExport(projectId, options) {
|
|
6918
|
-
const view = await client.request(
|
|
6919
|
-
`/api/v1/projects/${encodeURIComponent(projectId)}/export`,
|
|
6920
|
-
{
|
|
6921
|
-
method: "POST",
|
|
6922
|
-
body: {
|
|
6923
|
-
withData: options.withData,
|
|
6924
|
-
withSource: options.withSource,
|
|
6925
|
-
...options.withoutSource === true ? { withoutSource: true } : {}
|
|
6926
|
-
}
|
|
6927
|
-
},
|
|
6928
|
-
"EXPORT_TRIGGER_FAILED"
|
|
6929
|
-
);
|
|
6930
|
-
return toExportJob(view);
|
|
6931
|
-
},
|
|
6932
|
-
async getJobStatus(jobId) {
|
|
6933
|
-
const view = await client.request(
|
|
6934
|
-
`/api/v1/exports/${encodeURIComponent(jobId)}`,
|
|
6935
|
-
{},
|
|
6936
|
-
"EXPORT_STATUS_FAILED"
|
|
6937
|
-
);
|
|
6938
|
-
return toExportJob(view);
|
|
6939
|
-
},
|
|
6940
|
-
async downloadBundle(jobId, outputPath) {
|
|
6941
|
-
const download = await client.request(
|
|
6942
|
-
`/api/v1/exports/${encodeURIComponent(jobId)}/download`,
|
|
6943
|
-
{},
|
|
6944
|
-
"EXPORT_DOWNLOAD_FAILED"
|
|
6945
|
-
);
|
|
6946
|
-
if (download.downloadUrl.length === 0) {
|
|
6947
|
-
throw new CliError("EXPORT_BUNDLE_UNAVAILABLE", "\u5BFC\u51FA\u4EA7\u7269\u4E0B\u8F7D URL \u4E3A\u7A7A\uFF0C\u4EA7\u7269\u53EF\u80FD\u5C1A\u4E0D\u53EF\u7528");
|
|
6948
|
-
}
|
|
6949
|
-
const response = await client.download(download.downloadUrl, "EXPORT_DOWNLOAD_FAILED");
|
|
6950
|
-
const bytes = Buffer.from(await response.arrayBuffer());
|
|
6951
|
-
await writeFile7(outputPath, bytes);
|
|
6952
|
-
return { path: outputPath, size: bytes.length };
|
|
6953
|
-
}
|
|
6954
|
-
};
|
|
6955
|
-
}
|
|
6956
|
-
var init_client2 = __esm({
|
|
6957
|
-
"packages/cli/src/export/client.ts"() {
|
|
6958
|
-
"use strict";
|
|
6959
|
-
init_auth();
|
|
6960
|
-
init_client();
|
|
6961
|
-
}
|
|
6962
|
-
});
|
|
6963
|
-
|
|
6964
7252
|
// packages/cli/src/serve/banner.ts
|
|
6965
7253
|
function isLoopback(host) {
|
|
6966
7254
|
return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
|
|
@@ -7029,6 +7317,58 @@ var init_banner = __esm({
|
|
|
7029
7317
|
}
|
|
7030
7318
|
});
|
|
7031
7319
|
|
|
7320
|
+
// packages/cli/src/serve/staleness.ts
|
|
7321
|
+
function diffFunctionFiles(snapshot, current) {
|
|
7322
|
+
const changes = [];
|
|
7323
|
+
for (const path of Object.keys(snapshot)) {
|
|
7324
|
+
const before = snapshot[path];
|
|
7325
|
+
const after = current[path];
|
|
7326
|
+
if (after === void 0) changes.push(`\u5220\u9664 ${path}`);
|
|
7327
|
+
else if (before !== after) changes.push(`\u4FEE\u6539 ${path}`);
|
|
7328
|
+
}
|
|
7329
|
+
for (const path of Object.keys(current)) {
|
|
7330
|
+
if (snapshot[path] === void 0) changes.push(`\u65B0\u589E ${path}`);
|
|
7331
|
+
}
|
|
7332
|
+
return changes.toSorted();
|
|
7333
|
+
}
|
|
7334
|
+
function stalenessWarning(changes) {
|
|
7335
|
+
const shown = changes.slice(0, 3).join("\u3001");
|
|
7336
|
+
const more = changes.length > 3 ? ` \u7B49 ${changes.length} \u5904` : "";
|
|
7337
|
+
return `[serve] \u26A0\uFE0F \u6E90\u7801\u5DF2\u53D8\u66F4\u4F46\u8FDB\u7A0B\u5185\u4ECD\u662F\u65E7\u4EE3\u7801\uFF08${shown}${more}\uFF09\u3002\u8BF7\u91CD\u542F serve \u6216\u6539\u7528 --watch \u70ED\u91CD\u8F7D\u3002`;
|
|
7338
|
+
}
|
|
7339
|
+
function createStalenessGuard(options) {
|
|
7340
|
+
const { loadedFiles, loadFiles, log } = options;
|
|
7341
|
+
const minIntervalMs = options.minIntervalMs ?? 2e3;
|
|
7342
|
+
let lastScanAt = -Infinity;
|
|
7343
|
+
let warned = false;
|
|
7344
|
+
return {
|
|
7345
|
+
check: async () => {
|
|
7346
|
+
const now = Date.now();
|
|
7347
|
+
if (now - lastScanAt < minIntervalMs) return;
|
|
7348
|
+
lastScanAt = now;
|
|
7349
|
+
let current;
|
|
7350
|
+
try {
|
|
7351
|
+
current = await loadFiles();
|
|
7352
|
+
} catch {
|
|
7353
|
+
return;
|
|
7354
|
+
}
|
|
7355
|
+
const changes = diffFunctionFiles(loadedFiles, current);
|
|
7356
|
+
if (changes.length === 0) {
|
|
7357
|
+
warned = false;
|
|
7358
|
+
return;
|
|
7359
|
+
}
|
|
7360
|
+
if (warned) return;
|
|
7361
|
+
warned = true;
|
|
7362
|
+
log(stalenessWarning(changes));
|
|
7363
|
+
}
|
|
7364
|
+
};
|
|
7365
|
+
}
|
|
7366
|
+
var init_staleness = __esm({
|
|
7367
|
+
"packages/cli/src/serve/staleness.ts"() {
|
|
7368
|
+
"use strict";
|
|
7369
|
+
}
|
|
7370
|
+
});
|
|
7371
|
+
|
|
7032
7372
|
// shared/sdk/template-params.ts
|
|
7033
7373
|
function extractTemplateFields(root) {
|
|
7034
7374
|
if (root === null || typeof root !== "object") {
|
|
@@ -7155,8 +7495,8 @@ var init_template_params = __esm({
|
|
|
7155
7495
|
});
|
|
7156
7496
|
|
|
7157
7497
|
// packages/cli/src/serve/template-params.ts
|
|
7158
|
-
import { readFile as
|
|
7159
|
-
import { join as
|
|
7498
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
7499
|
+
import { join as join28 } from "node:path";
|
|
7160
7500
|
import { parse as parse3 } from "yaml";
|
|
7161
7501
|
function mergeTemplateEnvSource(source) {
|
|
7162
7502
|
return { ...source.processEnv, ...source.dotenv, ...source.dotenvLocal };
|
|
@@ -7164,7 +7504,7 @@ function mergeTemplateEnvSource(source) {
|
|
|
7164
7504
|
async function loadTemplateFields(cwd) {
|
|
7165
7505
|
let text;
|
|
7166
7506
|
try {
|
|
7167
|
-
text = await
|
|
7507
|
+
text = await readFile20(join28(cwd, TEMPLATE_PARAMS_FILE), "utf8");
|
|
7168
7508
|
} catch {
|
|
7169
7509
|
return null;
|
|
7170
7510
|
}
|
|
@@ -7180,7 +7520,7 @@ async function loadTemplateFields(cwd) {
|
|
|
7180
7520
|
return extractTemplateFields(root);
|
|
7181
7521
|
}
|
|
7182
7522
|
async function readDotenvFile(cwd, name) {
|
|
7183
|
-
const text = await
|
|
7523
|
+
const text = await readFile20(join28(cwd, name), "utf8").catch(() => "");
|
|
7184
7524
|
if (text === "") return {};
|
|
7185
7525
|
return parseEnvFile(text);
|
|
7186
7526
|
}
|
|
@@ -7235,8 +7575,8 @@ __export(server_exports, {
|
|
|
7235
7575
|
});
|
|
7236
7576
|
import { createServer as createServer2 } from "node:http";
|
|
7237
7577
|
import { watch as watch2 } from "node:fs";
|
|
7238
|
-
import { mkdir as
|
|
7239
|
-
import { extname, join as
|
|
7578
|
+
import { mkdir as mkdir14, readFile as readFile21, stat as stat12 } from "node:fs/promises";
|
|
7579
|
+
import { extname, join as join29, relative as relative4, resolve as resolve12 } from "node:path";
|
|
7240
7580
|
function envNumber(name) {
|
|
7241
7581
|
const raw = process.env[name];
|
|
7242
7582
|
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
@@ -7269,8 +7609,7 @@ async function startServeServer(options) {
|
|
|
7269
7609
|
...options.dbFile === void 0 ? {} : { dbFile: options.dbFile }
|
|
7270
7610
|
});
|
|
7271
7611
|
const config2 = await loadConfig(cwd);
|
|
7272
|
-
const functionsDir =
|
|
7273
|
-
const bearerUser = bearerUserResolverFromEnv();
|
|
7612
|
+
const functionsDir = join29(cwd, config2.functionsDir);
|
|
7274
7613
|
let hasStatic = false;
|
|
7275
7614
|
try {
|
|
7276
7615
|
const publicStat = await stat12(staticDir);
|
|
@@ -7281,9 +7620,10 @@ async function startServeServer(options) {
|
|
|
7281
7620
|
const loadFunctionFiles = async () => mergeSharedIntoFunctions(await collectFunctions(functionsDir));
|
|
7282
7621
|
let files = await loadFunctionFiles();
|
|
7283
7622
|
let functionNames = listFunctionNames(files);
|
|
7284
|
-
const envText = await
|
|
7623
|
+
const envText = await readFile21(join29(cwd, ".env.local"), "utf8").catch(() => "");
|
|
7285
7624
|
let env = parseEnvFile(envText);
|
|
7286
7625
|
let simEnv = await loadSimEnv(cwd).catch(() => ({}));
|
|
7626
|
+
let bearerUser = bearerUserResolverFromEnv(simEnv);
|
|
7287
7627
|
const dotenvFile = await readDotenvFile(cwd, ".env");
|
|
7288
7628
|
let templateEnv;
|
|
7289
7629
|
try {
|
|
@@ -7322,21 +7662,35 @@ async function startServeServer(options) {
|
|
|
7322
7662
|
log
|
|
7323
7663
|
});
|
|
7324
7664
|
}
|
|
7665
|
+
const fetchConfig = resolveLocalFetchConfig(simEnv);
|
|
7325
7666
|
const executor = new WorkerFunctionExecutor({
|
|
7326
|
-
deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS }
|
|
7667
|
+
deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS },
|
|
7668
|
+
...fetchConfig === void 0 ? {} : { fetch: fetchConfig }
|
|
7327
7669
|
});
|
|
7670
|
+
if (fetchConfig !== void 0) {
|
|
7671
|
+
log(
|
|
7672
|
+
`[adep] \u53D7\u63A7 fetch \u5DF2\u6CE8\u5165\uFF08FUNCTIONS_FETCH_ALLOWLIST\uFF09\uFF1A\u767D\u540D\u5355 ${fetchConfig.allowlist.length} \u9879\uFF0C\u8D85\u65F6 ${fetchConfig.timeoutMs}ms`
|
|
7673
|
+
);
|
|
7674
|
+
}
|
|
7328
7675
|
const dbBundle = runtime.bundle;
|
|
7329
7676
|
let invokeHandler = createSimInvokeHandler({ executor, files });
|
|
7677
|
+
const stalenessGuard = options.watch === true ? void 0 : createStalenessGuard({
|
|
7678
|
+
loadedFiles: { ...files },
|
|
7679
|
+
loadFiles: loadFunctionFiles,
|
|
7680
|
+
log,
|
|
7681
|
+
...options.stalenessCheckIntervalMs === void 0 ? {} : { minIntervalMs: options.stalenessCheckIntervalMs }
|
|
7682
|
+
});
|
|
7330
7683
|
let stopWatch;
|
|
7331
7684
|
if (options.watch === true) {
|
|
7332
7685
|
const reload = async () => {
|
|
7333
7686
|
const [nextFiles, envLocalText] = await Promise.all([
|
|
7334
7687
|
loadFunctionFiles(),
|
|
7335
|
-
|
|
7688
|
+
readFile21(join29(cwd, ".env.local"), "utf8").catch(() => "")
|
|
7336
7689
|
]);
|
|
7337
7690
|
files = nextFiles;
|
|
7338
7691
|
env = parseEnvFile(envLocalText);
|
|
7339
7692
|
simEnv = await loadSimEnv(cwd).catch(() => ({}));
|
|
7693
|
+
bearerUser = bearerUserResolverFromEnv(simEnv);
|
|
7340
7694
|
invokeHandler = createSimInvokeHandler({ executor, files });
|
|
7341
7695
|
functionNames = listFunctionNames(files);
|
|
7342
7696
|
log(`[serve] \u70ED\u91CD\u8F7D\uFF1A\u68C0\u6D4B\u5230\u53D8\u66F4\uFF0C\u5DF2\u91CD\u65B0\u52A0\u8F7D ${functionNames.length} \u4E2A\u51FD\u6570`);
|
|
@@ -7349,7 +7703,7 @@ async function startServeServer(options) {
|
|
|
7349
7703
|
void reload();
|
|
7350
7704
|
}, 120);
|
|
7351
7705
|
};
|
|
7352
|
-
await
|
|
7706
|
+
await mkdir14(functionsDir, { recursive: true }).catch(() => void 0);
|
|
7353
7707
|
try {
|
|
7354
7708
|
watchers.push(watch2(functionsDir, { recursive: true }, scheduleReload));
|
|
7355
7709
|
} catch {
|
|
@@ -7367,7 +7721,7 @@ async function startServeServer(options) {
|
|
|
7367
7721
|
const buildInput = async (fnName, entry, url2, req) => {
|
|
7368
7722
|
const hasEnv = Object.keys(env).length > 0 || Object.keys(simEnv).length > 0 || Object.keys(config2.environment ?? {}).length > 0;
|
|
7369
7723
|
const mergedEnv = { ...config2.environment, ...simEnv, ...env };
|
|
7370
|
-
const request = await requestInput(url2, req,
|
|
7724
|
+
const request = await requestInput(url2, req, bodyWithFiles);
|
|
7371
7725
|
if (bearerUser !== void 0) request.user = await bearerUser(request.headers);
|
|
7372
7726
|
return {
|
|
7373
7727
|
project: { id: "local", slug: config2.name },
|
|
@@ -7404,31 +7758,31 @@ async function startServeServer(options) {
|
|
|
7404
7758
|
const serveStatic = async (pathname, res) => {
|
|
7405
7759
|
if (!hasStatic) return false;
|
|
7406
7760
|
const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
|
|
7407
|
-
const filePath =
|
|
7408
|
-
const resolvedPath = safePath === "" || safePath === "/" ?
|
|
7761
|
+
const filePath = join29(staticDir, safePath);
|
|
7762
|
+
const resolvedPath = safePath === "" || safePath === "/" ? join29(filePath, "index.html") : filePath;
|
|
7409
7763
|
try {
|
|
7410
7764
|
const fileStat = await stat12(resolvedPath);
|
|
7411
7765
|
if (fileStat.isDirectory()) {
|
|
7412
|
-
const indexPath =
|
|
7766
|
+
const indexPath = join29(resolvedPath, "index.html");
|
|
7413
7767
|
try {
|
|
7414
7768
|
const indexStat = await stat12(indexPath);
|
|
7415
7769
|
if (indexStat.isFile()) {
|
|
7416
|
-
sendStaticFile(res, indexPath, await
|
|
7770
|
+
sendStaticFile(res, indexPath, await readFile21(indexPath));
|
|
7417
7771
|
return true;
|
|
7418
7772
|
}
|
|
7419
7773
|
} catch {
|
|
7420
7774
|
}
|
|
7421
7775
|
return false;
|
|
7422
7776
|
}
|
|
7423
|
-
sendStaticFile(res, resolvedPath, await
|
|
7777
|
+
sendStaticFile(res, resolvedPath, await readFile21(resolvedPath));
|
|
7424
7778
|
return true;
|
|
7425
7779
|
} catch {
|
|
7426
7780
|
if (options.spaFallback === true) {
|
|
7427
7781
|
const ext = extname(pathname);
|
|
7428
7782
|
if (ext === "" || ext === ".html") {
|
|
7429
7783
|
try {
|
|
7430
|
-
const indexContent = await
|
|
7431
|
-
sendStaticFile(res,
|
|
7784
|
+
const indexContent = await readFile21(join29(staticDir, "index.html"));
|
|
7785
|
+
sendStaticFile(res, join29(staticDir, "index.html"), indexContent);
|
|
7432
7786
|
return true;
|
|
7433
7787
|
} catch {
|
|
7434
7788
|
}
|
|
@@ -7511,15 +7865,16 @@ async function startServeServer(options) {
|
|
|
7511
7865
|
});
|
|
7512
7866
|
return;
|
|
7513
7867
|
}
|
|
7868
|
+
await stalenessGuard?.check();
|
|
7514
7869
|
const entry = resolveFunctionEntry(files, fnName);
|
|
7515
7870
|
if (entry === void 0) {
|
|
7516
7871
|
log(`[serve] ${req.method ?? "GET"} ${pathname} -> 404\uFF08\u51FD\u6570\u4E0D\u5B58\u5728\uFF09`);
|
|
7517
7872
|
writeJson(res, 404, { error: { code: "FN_NOT_FOUND", message: `\u51FD\u6570 "${fnName}" \u4E0D\u5B58\u5728` } });
|
|
7518
7873
|
return;
|
|
7519
7874
|
}
|
|
7520
|
-
const input2 = await buildInput(fnName, entry, url2, req);
|
|
7521
7875
|
const startedAt = performance.now();
|
|
7522
7876
|
try {
|
|
7877
|
+
const input2 = await buildInput(fnName, entry, url2, req);
|
|
7523
7878
|
const result = await executor.execute(input2);
|
|
7524
7879
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
7525
7880
|
if (options.watch === true) {
|
|
@@ -7656,9 +8011,11 @@ var init_server = __esm({
|
|
|
7656
8011
|
init_runtime();
|
|
7657
8012
|
init_storage();
|
|
7658
8013
|
init_env();
|
|
8014
|
+
init_fetch_config();
|
|
7659
8015
|
init_invoke();
|
|
7660
8016
|
init_dev();
|
|
7661
8017
|
init_banner();
|
|
8018
|
+
init_staleness();
|
|
7662
8019
|
init_template_params2();
|
|
7663
8020
|
init_adep_env_inject();
|
|
7664
8021
|
init_template_params();
|
|
@@ -7688,6 +8045,20 @@ var init_server = __esm({
|
|
|
7688
8045
|
}
|
|
7689
8046
|
});
|
|
7690
8047
|
|
|
8048
|
+
// packages/cli/src/hash.ts
|
|
8049
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
8050
|
+
function sha256Hex(content) {
|
|
8051
|
+
return createHash4("sha256").update(content).digest("hex");
|
|
8052
|
+
}
|
|
8053
|
+
function sha256HexOfBytes(bytes) {
|
|
8054
|
+
return createHash4("sha256").update(bytes).digest("hex");
|
|
8055
|
+
}
|
|
8056
|
+
var init_hash = __esm({
|
|
8057
|
+
"packages/cli/src/hash.ts"() {
|
|
8058
|
+
"use strict";
|
|
8059
|
+
}
|
|
8060
|
+
});
|
|
8061
|
+
|
|
7691
8062
|
// packages/cli/src/deploy.ts
|
|
7692
8063
|
var deploy_exports = {};
|
|
7693
8064
|
__export(deploy_exports, {
|
|
@@ -7696,9 +8067,8 @@ __export(deploy_exports, {
|
|
|
7696
8067
|
collectShared: () => collectShared,
|
|
7697
8068
|
deploy: () => deploy
|
|
7698
8069
|
});
|
|
7699
|
-
import {
|
|
7700
|
-
import {
|
|
7701
|
-
import { join as join24, resolve as resolve13, basename as basename4, relative as relative5, sep } from "node:path";
|
|
8070
|
+
import { readdir as readdir9, readFile as readFile22 } from "node:fs/promises";
|
|
8071
|
+
import { join as join30, resolve as resolve13, basename as basename4, relative as relative5, sep } from "node:path";
|
|
7702
8072
|
function functionUrlBase(prefix) {
|
|
7703
8073
|
const raw = (prefix ?? "/api").trim();
|
|
7704
8074
|
const normalized = raw === "/" ? "/" : raw.replace(/\/+$/, "");
|
|
@@ -7710,7 +8080,7 @@ function isRuntimeSource2(name) {
|
|
|
7710
8080
|
async function collectFunctionFiles(functionsDir) {
|
|
7711
8081
|
let dirents;
|
|
7712
8082
|
try {
|
|
7713
|
-
dirents = await
|
|
8083
|
+
dirents = await readdir9(functionsDir, { withFileTypes: true });
|
|
7714
8084
|
} catch {
|
|
7715
8085
|
return {};
|
|
7716
8086
|
}
|
|
@@ -7724,10 +8094,10 @@ async function collectFunctionFiles(functionsDir) {
|
|
|
7724
8094
|
if (conflicting.length > 0) throw new AmbiguousFunctionError(functionsDir, conflicting);
|
|
7725
8095
|
const out = {};
|
|
7726
8096
|
for (const name of flatNames) {
|
|
7727
|
-
out[name] = { [`${name}.ts`]: await
|
|
8097
|
+
out[name] = { [`${name}.ts`]: await readFile22(join30(functionsDir, `${name}.ts`), "utf8") };
|
|
7728
8098
|
}
|
|
7729
8099
|
for (const name of dirNames) {
|
|
7730
|
-
const files = await collectFunctionDir(
|
|
8100
|
+
const files = await collectFunctionDir(join30(functionsDir, name));
|
|
7731
8101
|
if (files["index.ts"] === void 0) continue;
|
|
7732
8102
|
out[name] = files;
|
|
7733
8103
|
}
|
|
@@ -7738,7 +8108,7 @@ async function collectFunctionDir(absDir) {
|
|
|
7738
8108
|
const walk = async (dir, prefix) => {
|
|
7739
8109
|
let entries;
|
|
7740
8110
|
try {
|
|
7741
|
-
entries = await
|
|
8111
|
+
entries = await readdir9(dir, { withFileTypes: true });
|
|
7742
8112
|
} catch {
|
|
7743
8113
|
return;
|
|
7744
8114
|
}
|
|
@@ -7746,39 +8116,36 @@ async function collectFunctionDir(absDir) {
|
|
|
7746
8116
|
const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
7747
8117
|
if (entry.isDirectory()) {
|
|
7748
8118
|
if (entry.name === "__tests__" || IGNORED_DIRS.has(entry.name)) continue;
|
|
7749
|
-
await walk(
|
|
8119
|
+
await walk(join30(dir, entry.name), rel);
|
|
7750
8120
|
continue;
|
|
7751
8121
|
}
|
|
7752
8122
|
if (!isRuntimeSource2(entry.name)) continue;
|
|
7753
|
-
files[rel] = await
|
|
8123
|
+
files[rel] = await readFile22(join30(dir, entry.name), "utf8");
|
|
7754
8124
|
}
|
|
7755
8125
|
};
|
|
7756
8126
|
await walk(absDir, "");
|
|
7757
8127
|
return files;
|
|
7758
8128
|
}
|
|
7759
|
-
function sha256Hex(content) {
|
|
7760
|
-
return createHash4("sha256").update(content).digest("hex");
|
|
7761
|
-
}
|
|
7762
8129
|
async function collectShared(functionsDir) {
|
|
7763
|
-
const sharedDir =
|
|
8130
|
+
const sharedDir = join30(functionsDir, FUNCTION_SHARED_DIR);
|
|
7764
8131
|
const files = {};
|
|
7765
8132
|
const walk = async (dir) => {
|
|
7766
8133
|
let entries;
|
|
7767
8134
|
try {
|
|
7768
|
-
entries = await
|
|
8135
|
+
entries = await readdir9(dir, { withFileTypes: true });
|
|
7769
8136
|
} catch {
|
|
7770
8137
|
return;
|
|
7771
8138
|
}
|
|
7772
8139
|
for (const entry of entries) {
|
|
7773
8140
|
if (entry.isDirectory()) {
|
|
7774
8141
|
if (entry.name === "__tests__" || entry.name === "node_modules") continue;
|
|
7775
|
-
await walk(
|
|
8142
|
+
await walk(join30(dir, entry.name));
|
|
7776
8143
|
continue;
|
|
7777
8144
|
}
|
|
7778
8145
|
if (!isRuntimeSource2(entry.name)) continue;
|
|
7779
|
-
const full =
|
|
8146
|
+
const full = join30(dir, entry.name);
|
|
7780
8147
|
const rel = relative5(sharedDir, full).split(sep).join("/");
|
|
7781
|
-
files[`${SHARED_SOURCE_ROOT}${rel}`] = await
|
|
8148
|
+
files[`${SHARED_SOURCE_ROOT}${rel}`] = await readFile22(full, "utf8");
|
|
7782
8149
|
}
|
|
7783
8150
|
};
|
|
7784
8151
|
await walk(sharedDir);
|
|
@@ -7790,7 +8157,7 @@ async function deploy(paths, options) {
|
|
|
7790
8157
|
const cwd = resolve13(options.cwd);
|
|
7791
8158
|
const config2 = await loadConfig(cwd);
|
|
7792
8159
|
const slug = options.slug ?? config2.name;
|
|
7793
|
-
const functionsDir = options.functionsDir === void 0 ?
|
|
8160
|
+
const functionsDir = options.functionsDir === void 0 ? join30(cwd, config2.functionsDir) : resolve13(cwd, options.functionsDir);
|
|
7794
8161
|
const local = await collectFunctionFiles(functionsDir);
|
|
7795
8162
|
if (Object.keys(local).length === 0) {
|
|
7796
8163
|
throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
|
|
@@ -7894,6 +8261,7 @@ var init_deploy = __esm({
|
|
|
7894
8261
|
init_function_source();
|
|
7895
8262
|
init_auth();
|
|
7896
8263
|
init_client();
|
|
8264
|
+
init_hash();
|
|
7897
8265
|
init_dev();
|
|
7898
8266
|
init_net();
|
|
7899
8267
|
init_shared_source();
|
|
@@ -7921,8 +8289,8 @@ __export(storage_exports, {
|
|
|
7921
8289
|
storageRemove: () => storageRemove,
|
|
7922
8290
|
storageUpload: () => storageUpload
|
|
7923
8291
|
});
|
|
7924
|
-
import { mkdir as
|
|
7925
|
-
import { basename as basename5, dirname as
|
|
8292
|
+
import { mkdir as mkdir15, readFile as readFile23, stat as stat13, writeFile as writeFile15 } from "node:fs/promises";
|
|
8293
|
+
import { basename as basename5, dirname as dirname12, extname as extname2, join as join31, resolve as resolve14 } from "node:path";
|
|
7926
8294
|
function envQuery2(options) {
|
|
7927
8295
|
return options.environment === void 0 ? "" : `?environment=${options.environment}`;
|
|
7928
8296
|
}
|
|
@@ -7967,7 +8335,7 @@ async function storageUpload(paths, options) {
|
|
|
7967
8335
|
throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
|
|
7968
8336
|
}
|
|
7969
8337
|
const visibility = options.visibility ?? "private";
|
|
7970
|
-
const bytes = await
|
|
8338
|
+
const bytes = await readFile23(local);
|
|
7971
8339
|
const form = new FormData();
|
|
7972
8340
|
form.set("path", options.path);
|
|
7973
8341
|
form.set("visibility", visibility);
|
|
@@ -8014,9 +8382,9 @@ async function storageDownload(paths, options) {
|
|
|
8014
8382
|
const url2 = await resolveDownloadUrl(client, project2, options.path, options.environment);
|
|
8015
8383
|
const response = await client.download(url2, "STORAGE_DOWNLOAD_FAILED");
|
|
8016
8384
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
8017
|
-
const output2 = resolve14(options.output ??
|
|
8018
|
-
await
|
|
8019
|
-
await
|
|
8385
|
+
const output2 = resolve14(options.output ?? join31(resolve14(options.cwd), basename5(options.path)));
|
|
8386
|
+
await mkdir15(dirname12(output2), { recursive: true });
|
|
8387
|
+
await writeFile15(output2, bytes);
|
|
8020
8388
|
return { path: options.path, output: output2, size: bytes.length };
|
|
8021
8389
|
}
|
|
8022
8390
|
async function storageRemove(paths, options) {
|
|
@@ -8042,8 +8410,9 @@ __export(hosting_exports, {
|
|
|
8042
8410
|
hostingInfo: () => hostingInfo,
|
|
8043
8411
|
hostingPull: () => hostingPull
|
|
8044
8412
|
});
|
|
8045
|
-
import { readdir as
|
|
8046
|
-
import {
|
|
8413
|
+
import { readdir as readdir10, readFile as readFile24, stat as stat14 } from "node:fs/promises";
|
|
8414
|
+
import { spawnSync } from "node:child_process";
|
|
8415
|
+
import { dirname as dirname13, join as join32, relative as relative6, resolve as resolve15, sep as sep2 } from "node:path";
|
|
8047
8416
|
async function open5(paths, options) {
|
|
8048
8417
|
const client = await createClient(paths);
|
|
8049
8418
|
const project2 = await resolveSlug(resolve15(options.cwd), options.slug);
|
|
@@ -8064,12 +8433,12 @@ async function collectSiteFiles(dir) {
|
|
|
8064
8433
|
const walk = async (sub) => {
|
|
8065
8434
|
let entries;
|
|
8066
8435
|
try {
|
|
8067
|
-
entries = await
|
|
8436
|
+
entries = await readdir10(sub, { withFileTypes: true });
|
|
8068
8437
|
} catch {
|
|
8069
8438
|
return;
|
|
8070
8439
|
}
|
|
8071
8440
|
for (const entry of entries) {
|
|
8072
|
-
const full =
|
|
8441
|
+
const full = join32(sub, entry.name);
|
|
8073
8442
|
if (entry.isDirectory()) {
|
|
8074
8443
|
await walk(full);
|
|
8075
8444
|
} else if (entry.isFile()) {
|
|
@@ -8085,25 +8454,70 @@ async function hostingDeploy(paths, options) {
|
|
|
8085
8454
|
const { client, project: project2 } = await open5(paths, options);
|
|
8086
8455
|
const log = options.log ?? ((line) => process.stdout.write(`${line}
|
|
8087
8456
|
`));
|
|
8457
|
+
if (options.build !== void 0) {
|
|
8458
|
+
log(`[adep] \u6267\u884C\u6784\u5EFA\uFF1A${options.build}`);
|
|
8459
|
+
const runner = spawnSync(options.build, {
|
|
8460
|
+
shell: true,
|
|
8461
|
+
cwd: resolve15(options.cwd),
|
|
8462
|
+
stdio: options.log ? "pipe" : "inherit"
|
|
8463
|
+
});
|
|
8464
|
+
if (runner.status !== 0) {
|
|
8465
|
+
throw new CliError(
|
|
8466
|
+
"BUILD_FAILED",
|
|
8467
|
+
`\u6784\u5EFA\u547D\u4EE4\u5931\u8D25\uFF08exit ${runner.status ?? "\u672A\u77E5"}\uFF09\uFF1A${options.build}`
|
|
8468
|
+
);
|
|
8469
|
+
}
|
|
8470
|
+
}
|
|
8088
8471
|
const files = await collectSiteFiles(options.dir);
|
|
8089
8472
|
if (files.size === 0) {
|
|
8090
8473
|
throw new CliError("NO_SITE_FILES", `\u7AD9\u70B9\u76EE\u5F55\u4E3A\u7A7A\uFF1A${resolve15(options.dir)}`);
|
|
8091
8474
|
}
|
|
8092
|
-
|
|
8475
|
+
let newestMtimeMs = 0;
|
|
8476
|
+
const localEntries = /* @__PURE__ */ new Map();
|
|
8093
8477
|
for (const [rel, full] of files) {
|
|
8478
|
+
const [info2, bytes] = await Promise.all([stat14(full), readFile24(full)]);
|
|
8479
|
+
localEntries.set(rel, { bytes, size: info2.size, hash: sha256HexOfBytes(bytes) });
|
|
8480
|
+
newestMtimeMs = Math.max(newestMtimeMs, info2.mtimeMs);
|
|
8481
|
+
}
|
|
8482
|
+
const builtAt = new Date(newestMtimeMs).toISOString();
|
|
8483
|
+
log(`[adep] \u90E8\u7F72\u5185\u5BB9\u6784\u5EFA\u4E8E ${builtAt}\uFF08\u672C\u5730\u76EE\u5F55\u6700\u65B0\u6587\u4EF6\u4FEE\u6539\u65F6\u95F4\uFF09`);
|
|
8484
|
+
const remote = await client.request(
|
|
8485
|
+
`/api/v1/projects/${project2}/hosting`
|
|
8486
|
+
);
|
|
8487
|
+
const remotePublic = /* @__PURE__ */ new Map();
|
|
8488
|
+
for (const entry of remote.files ?? []) {
|
|
8489
|
+
if (entry.visibility === "public" && entry.path.startsWith("site/") && entry.path !== HOSTING_CONFIG_PATH) {
|
|
8490
|
+
remotePublic.set(entry.path.slice("site/".length), entry);
|
|
8491
|
+
}
|
|
8492
|
+
}
|
|
8493
|
+
const uploaded = [];
|
|
8494
|
+
let reused = 0;
|
|
8495
|
+
for (const [rel, local] of localEntries) {
|
|
8496
|
+
const remoteEntry = remotePublic.get(rel);
|
|
8497
|
+
if (remoteEntry !== void 0 && remoteEntry.size === local.size && remoteEntry.url) {
|
|
8498
|
+
const response = await client.download(remoteEntry.url, "HOSTING_COMPARE_FAILED");
|
|
8499
|
+
const remoteBytes = new Uint8Array(await response.arrayBuffer());
|
|
8500
|
+
if (sha256HexOfBytes(remoteBytes) === local.hash) {
|
|
8501
|
+
reused += 1;
|
|
8502
|
+
continue;
|
|
8503
|
+
}
|
|
8504
|
+
}
|
|
8094
8505
|
log(`[adep] \u4E0A\u4F20 site/${rel}`);
|
|
8095
|
-
const info2 = await stat14(full);
|
|
8096
|
-
const bytes = await readFile21(full);
|
|
8097
8506
|
const form = new FormData();
|
|
8098
8507
|
form.set("path", `site/${rel}`);
|
|
8099
8508
|
form.set("visibility", "public");
|
|
8100
8509
|
form.set(
|
|
8101
8510
|
"file",
|
|
8102
|
-
new Blob([bytes], { type: contentTypeOf(rel) }),
|
|
8511
|
+
new Blob([local.bytes], { type: contentTypeOf(rel) }),
|
|
8103
8512
|
rel.split("/").pop()
|
|
8104
8513
|
);
|
|
8105
8514
|
await client.upload(`/api/v1/projects/${project2}/files`, form, "HOSTING_UPLOAD_FAILED");
|
|
8106
|
-
uploaded.push({ path: `site/${rel}`, size:
|
|
8515
|
+
uploaded.push({ path: `site/${rel}`, size: local.size });
|
|
8516
|
+
}
|
|
8517
|
+
const identical = uploaded.length === 0;
|
|
8518
|
+
if (identical) {
|
|
8519
|
+
log("\u26A0 \u672C\u6B21\u4E0A\u4F20\u5185\u5BB9\u4E0E\u7EBF\u4E0A\u73B0\u6709\u7248\u672C\u5B8C\u5168\u4E00\u81F4\u2014\u2014\u82E5\u521A\u4FEE\u6539\u8FC7\u6E90\u7801\uFF0C\u53EF\u80FD\u5FD8\u4E86\u5148\u6784\u5EFA\u3002");
|
|
8520
|
+
log(" \u5982\u786E\u5C5E\u91CD\u590D\u90E8\u7F72\uFF08\u4F8B\u5982\u91CD\u8BD5\uFF09\uFF0C\u53EF\u5FFD\u7565\u672C\u8B66\u793A\u3002");
|
|
8107
8521
|
}
|
|
8108
8522
|
const config2 = await client.request(
|
|
8109
8523
|
`/api/v1/projects/${project2}/hosting`,
|
|
@@ -8113,7 +8527,7 @@ async function hostingDeploy(paths, options) {
|
|
|
8113
8527
|
}
|
|
8114
8528
|
);
|
|
8115
8529
|
const info = await hostingInfo(paths, options);
|
|
8116
|
-
return { config: config2.config, siteUrl: info.siteUrl, uploaded };
|
|
8530
|
+
return { config: config2.config, siteUrl: info.siteUrl, uploaded, reused, identical, builtAt };
|
|
8117
8531
|
}
|
|
8118
8532
|
async function hostingPull(paths, options) {
|
|
8119
8533
|
const { client } = await open5(paths, options);
|
|
@@ -8121,7 +8535,7 @@ async function hostingPull(paths, options) {
|
|
|
8121
8535
|
`));
|
|
8122
8536
|
const info = await hostingInfo(paths, options);
|
|
8123
8537
|
const outputDir = resolve15(options.output ?? resolve15(options.cwd));
|
|
8124
|
-
const { mkdir:
|
|
8538
|
+
const { mkdir: mkdir17, writeFile: writeFile17 } = await import("node:fs/promises");
|
|
8125
8539
|
const files = [];
|
|
8126
8540
|
for (const entry of info.files) {
|
|
8127
8541
|
if (entry.visibility !== "public" || entry.path === HOSTING_CONFIG_PATH) continue;
|
|
@@ -8131,9 +8545,9 @@ async function hostingPull(paths, options) {
|
|
|
8131
8545
|
const response = await client.download(url2, "HOSTING_DOWNLOAD_FAILED");
|
|
8132
8546
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
8133
8547
|
const rel = entry.path.replace(/^site\//, "");
|
|
8134
|
-
const target =
|
|
8135
|
-
await
|
|
8136
|
-
await
|
|
8548
|
+
const target = join32(outputDir, ...rel.split("/"));
|
|
8549
|
+
await mkdir17(dirname13(target), { recursive: true });
|
|
8550
|
+
await writeFile17(target, bytes);
|
|
8137
8551
|
files.push({ path: entry.path, size: bytes.length });
|
|
8138
8552
|
}
|
|
8139
8553
|
return { siteUrl: info.siteUrl, outputDir, files };
|
|
@@ -8155,6 +8569,7 @@ var init_hosting = __esm({
|
|
|
8155
8569
|
"use strict";
|
|
8156
8570
|
init_client();
|
|
8157
8571
|
init_auth();
|
|
8572
|
+
init_hash();
|
|
8158
8573
|
init_storage2();
|
|
8159
8574
|
HOSTING_CONFIG_PATH = "site/.hosting.json";
|
|
8160
8575
|
}
|
|
@@ -8187,22 +8602,22 @@ __export(frontend_exports, {
|
|
|
8187
8602
|
frontendSync: () => frontendSync,
|
|
8188
8603
|
isStaticFrontendDir: () => isStaticFrontendDir
|
|
8189
8604
|
});
|
|
8190
|
-
import { readdir as
|
|
8191
|
-
import { join as
|
|
8605
|
+
import { readdir as readdir11, readFile as readFile25, stat as stat15 } from "node:fs/promises";
|
|
8606
|
+
import { join as join33, relative as relative7, sep as sep3 } from "node:path";
|
|
8192
8607
|
async function collectFiles(root, dir) {
|
|
8193
8608
|
const files = /* @__PURE__ */ new Map();
|
|
8194
8609
|
const skipped = [];
|
|
8195
|
-
const entries = await
|
|
8610
|
+
const entries = await readdir11(dir, { withFileTypes: true });
|
|
8196
8611
|
for (const entry of entries) {
|
|
8197
8612
|
if (entry.isDirectory()) {
|
|
8198
8613
|
if (IGNORED_DIRS2.has(entry.name)) continue;
|
|
8199
|
-
const nested = await collectFiles(root,
|
|
8614
|
+
const nested = await collectFiles(root, join33(dir, entry.name));
|
|
8200
8615
|
for (const [path, content] of nested.files) files.set(path, content);
|
|
8201
8616
|
skipped.push(...nested.skipped);
|
|
8202
8617
|
continue;
|
|
8203
8618
|
}
|
|
8204
8619
|
if (IGNORED_FILES.has(entry.name)) continue;
|
|
8205
|
-
const full =
|
|
8620
|
+
const full = join33(dir, entry.name);
|
|
8206
8621
|
const rel = relative7(root, full).split(sep3).join("/");
|
|
8207
8622
|
const info = await stat15(full);
|
|
8208
8623
|
if (info.size > 1024 * 1024) {
|
|
@@ -8210,7 +8625,7 @@ async function collectFiles(root, dir) {
|
|
|
8210
8625
|
continue;
|
|
8211
8626
|
}
|
|
8212
8627
|
try {
|
|
8213
|
-
const content = await
|
|
8628
|
+
const content = await readFile25(full, "utf8");
|
|
8214
8629
|
if (content.includes("\0")) {
|
|
8215
8630
|
skipped.push(rel);
|
|
8216
8631
|
continue;
|
|
@@ -8225,7 +8640,7 @@ async function collectFiles(root, dir) {
|
|
|
8225
8640
|
async function frontendSync(paths, options) {
|
|
8226
8641
|
const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
|
|
8227
8642
|
`));
|
|
8228
|
-
const webDir = options.dir ??
|
|
8643
|
+
const webDir = options.dir ?? join33(options.cwd, "web");
|
|
8229
8644
|
const rootStat = await stat15(webDir).catch(() => null);
|
|
8230
8645
|
if (rootStat === null || !rootStat.isDirectory()) {
|
|
8231
8646
|
throw new CliError(
|
|
@@ -8285,14 +8700,14 @@ function declaresBuildScript(pkgJson) {
|
|
|
8285
8700
|
return typeof build === "string" && build.trim().length > 0;
|
|
8286
8701
|
}
|
|
8287
8702
|
async function isStaticFrontendDir(dir) {
|
|
8288
|
-
const pkg = await
|
|
8703
|
+
const pkg = await readFile25(join33(dir, "package.json"), "utf8").catch(() => void 0);
|
|
8289
8704
|
if (declaresBuildScript(pkg)) return false;
|
|
8290
8705
|
const walk = async (sub) => {
|
|
8291
|
-
const entries = await
|
|
8706
|
+
const entries = await readdir11(sub, { withFileTypes: true });
|
|
8292
8707
|
for (const entry of entries) {
|
|
8293
8708
|
if (entry.isDirectory()) {
|
|
8294
8709
|
if (IGNORED_DIRS2.has(entry.name)) continue;
|
|
8295
|
-
if (!await walk(
|
|
8710
|
+
if (!await walk(join33(sub, entry.name))) return false;
|
|
8296
8711
|
continue;
|
|
8297
8712
|
}
|
|
8298
8713
|
if (FRONTEND_TRANSFORM_EXTENSIONS.some((ext) => entry.name.endsWith(ext))) return false;
|
|
@@ -8328,12 +8743,12 @@ var fs_exports = {};
|
|
|
8328
8743
|
__export(fs_exports, {
|
|
8329
8744
|
createExportFileSystem: () => createExportFileSystem
|
|
8330
8745
|
});
|
|
8331
|
-
import { mkdir as
|
|
8332
|
-
import { dirname as
|
|
8746
|
+
import { mkdir as mkdir16, readFile as readFile27, rm as rm5, stat as stat17, writeFile as writeFile16 } from "node:fs/promises";
|
|
8747
|
+
import { dirname as dirname14, join as join36 } from "node:path";
|
|
8333
8748
|
function createExportFileSystem() {
|
|
8334
8749
|
return {
|
|
8335
|
-
readFile: (path) =>
|
|
8336
|
-
writeFile: (path, content) =>
|
|
8750
|
+
readFile: (path) => readFile27(path),
|
|
8751
|
+
writeFile: (path, content) => writeFile16(path, content),
|
|
8337
8752
|
// 同时用于清理解压临时目录(${zip}.tmp 是个目录)——递归强制删除,缺失不报错。
|
|
8338
8753
|
deleteFile: async (path) => {
|
|
8339
8754
|
await rm5(path, { recursive: true, force: true });
|
|
@@ -8347,14 +8762,14 @@ function createExportFileSystem() {
|
|
|
8347
8762
|
}
|
|
8348
8763
|
},
|
|
8349
8764
|
mkdir: async (path) => {
|
|
8350
|
-
await
|
|
8765
|
+
await mkdir16(path, { recursive: true });
|
|
8351
8766
|
},
|
|
8352
8767
|
unzip: async (zipPath, targetDir) => {
|
|
8353
|
-
const entries = zipRead(await
|
|
8768
|
+
const entries = zipRead(await readFile27(zipPath));
|
|
8354
8769
|
for (const [name, data] of entries) {
|
|
8355
|
-
const dest =
|
|
8356
|
-
await
|
|
8357
|
-
await
|
|
8770
|
+
const dest = join36(targetDir, name);
|
|
8771
|
+
await mkdir16(dirname14(dest), { recursive: true });
|
|
8772
|
+
await writeFile16(dest, data);
|
|
8358
8773
|
}
|
|
8359
8774
|
}
|
|
8360
8775
|
};
|
|
@@ -8598,8 +9013,8 @@ ${detail}`);
|
|
|
8598
9013
|
});
|
|
8599
9014
|
|
|
8600
9015
|
// packages/cli/src/sandbox-scan.ts
|
|
8601
|
-
import { readdir as
|
|
8602
|
-
import { join as
|
|
9016
|
+
import { readdir as readdir13, readFile as readFile28 } from "node:fs/promises";
|
|
9017
|
+
import { join as join37, relative as relative9, sep as sep5 } from "node:path";
|
|
8603
9018
|
function extractSpecifiers(line) {
|
|
8604
9019
|
const out = [];
|
|
8605
9020
|
const patterns = [
|
|
@@ -8643,17 +9058,17 @@ function classify(specifier) {
|
|
|
8643
9058
|
return null;
|
|
8644
9059
|
}
|
|
8645
9060
|
async function scanFunctionSources(rootDir, functionsDir) {
|
|
8646
|
-
const base =
|
|
9061
|
+
const base = join37(rootDir, functionsDir);
|
|
8647
9062
|
const findings = [];
|
|
8648
9063
|
async function walk(current) {
|
|
8649
9064
|
let entries;
|
|
8650
9065
|
try {
|
|
8651
|
-
entries = await
|
|
9066
|
+
entries = await readdir13(current, { withFileTypes: true });
|
|
8652
9067
|
} catch {
|
|
8653
9068
|
return;
|
|
8654
9069
|
}
|
|
8655
9070
|
for (const entry of entries) {
|
|
8656
|
-
const abs =
|
|
9071
|
+
const abs = join37(current, entry.name);
|
|
8657
9072
|
if (entry.isDirectory()) {
|
|
8658
9073
|
if (SKIP_DIRS.has(entry.name)) continue;
|
|
8659
9074
|
await walk(abs);
|
|
@@ -8664,7 +9079,7 @@ async function scanFunctionSources(rootDir, functionsDir) {
|
|
|
8664
9079
|
if (entry.name.endsWith(".d.ts")) continue;
|
|
8665
9080
|
let content;
|
|
8666
9081
|
try {
|
|
8667
|
-
content = await
|
|
9082
|
+
content = await readFile28(abs, "utf8");
|
|
8668
9083
|
} catch {
|
|
8669
9084
|
continue;
|
|
8670
9085
|
}
|
|
@@ -8787,6 +9202,7 @@ __export(doctor_exports, {
|
|
|
8787
9202
|
runDoctor: () => runDoctor
|
|
8788
9203
|
});
|
|
8789
9204
|
import { stat as stat18 } from "node:fs/promises";
|
|
9205
|
+
import { join as join38 } from "node:path";
|
|
8790
9206
|
async function probeServer(server) {
|
|
8791
9207
|
const controller = new AbortController();
|
|
8792
9208
|
const timer = setTimeout(() => controller.abort(), SERVER_PROBE_TIMEOUT_MS);
|
|
@@ -8814,14 +9230,15 @@ async function credentialMode(file2) {
|
|
|
8814
9230
|
async function runDoctor(paths, cwd = process.cwd()) {
|
|
8815
9231
|
const credentials = await loadCredentials(paths);
|
|
8816
9232
|
const server = credentials?.server ?? resolveServer();
|
|
8817
|
-
const
|
|
9233
|
+
const credentialsFile = credentials !== null ? join38(paths.credentialsDir, `${slotNameFor(credentials.server)}.json`) : paths.credentialsFile;
|
|
9234
|
+
const mode = await credentialMode(credentialsFile);
|
|
8818
9235
|
const offline = await isOffline();
|
|
8819
9236
|
const health = await probeServer(server);
|
|
8820
9237
|
const sandbox = await scanSandbox(cwd);
|
|
8821
9238
|
const report = {
|
|
8822
9239
|
server,
|
|
8823
9240
|
credentials: {
|
|
8824
|
-
file:
|
|
9241
|
+
file: credentialsFile,
|
|
8825
9242
|
present: credentials !== null,
|
|
8826
9243
|
...mode === void 0 ? {} : { mode }
|
|
8827
9244
|
},
|
|
@@ -8833,7 +9250,7 @@ async function runDoctor(paths, cwd = process.cwd()) {
|
|
|
8833
9250
|
};
|
|
8834
9251
|
if (credentials !== null) report.credentials.email = credentials.email;
|
|
8835
9252
|
if (mode !== void 0 && mode !== "600") {
|
|
8836
|
-
report.credentials.warning = `\u6743\u9650 ${mode} \u5BBD\u4E8E 0600\uFF0C\u5EFA\u8BAE chmod 600 ${
|
|
9253
|
+
report.credentials.warning = `\u6743\u9650 ${mode} \u5BBD\u4E8E 0600\uFF0C\u5EFA\u8BAE chmod 600 ${credentialsFile}`;
|
|
8837
9254
|
}
|
|
8838
9255
|
return report;
|
|
8839
9256
|
}
|
|
@@ -9278,12 +9695,12 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
9278
9695
|
init_auth();
|
|
9279
9696
|
|
|
9280
9697
|
// packages/cli/src/init.ts
|
|
9281
|
-
import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
|
|
9282
|
-
import { dirname as
|
|
9698
|
+
import { mkdir as mkdir2, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
|
|
9699
|
+
import { dirname as dirname2, join as join3, resolve } from "node:path";
|
|
9283
9700
|
|
|
9284
9701
|
// packages/cli/src/templates/registry.ts
|
|
9285
9702
|
import { readFileSync } from "node:fs";
|
|
9286
|
-
import { dirname as
|
|
9703
|
+
import { dirname, join as join2 } from "node:path";
|
|
9287
9704
|
import { fileURLToPath } from "node:url";
|
|
9288
9705
|
|
|
9289
9706
|
// packages/cli/src/templates/generated.ts
|
|
@@ -12668,15 +13085,15 @@ var TEMPLATE_CODES = [
|
|
|
12668
13085
|
];
|
|
12669
13086
|
var TEMPLATE_NAMES = TEMPLATE_CODES;
|
|
12670
13087
|
function findCliPackageJson() {
|
|
12671
|
-
let dir =
|
|
13088
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
12672
13089
|
for (; ; ) {
|
|
12673
|
-
const candidate =
|
|
13090
|
+
const candidate = join2(dir, "package.json");
|
|
12674
13091
|
try {
|
|
12675
13092
|
const pkg = JSON.parse(readFileSync(candidate, "utf8"));
|
|
12676
13093
|
if (pkg.name === "@adep/cli") return candidate;
|
|
12677
13094
|
} catch {
|
|
12678
13095
|
}
|
|
12679
|
-
const parent =
|
|
13096
|
+
const parent = dirname(dir);
|
|
12680
13097
|
if (parent === dir) {
|
|
12681
13098
|
throw new Error("\u627E\u4E0D\u5230 @adep/cli \u7684 package.json\uFF08\u5DF2\u904D\u5386\u5230\u6587\u4EF6\u7CFB\u7EDF\u6839\uFF09");
|
|
12682
13099
|
}
|
|
@@ -12688,10 +13105,10 @@ function cliVersionOf() {
|
|
|
12688
13105
|
return pkg.version;
|
|
12689
13106
|
}
|
|
12690
13107
|
function cliPackageRoot() {
|
|
12691
|
-
return
|
|
13108
|
+
return dirname(findCliPackageJson());
|
|
12692
13109
|
}
|
|
12693
13110
|
function localTemplateDir(code) {
|
|
12694
|
-
return
|
|
13111
|
+
return join2(cliPackageRoot(), "src", "templates", code);
|
|
12695
13112
|
}
|
|
12696
13113
|
function templateFiles(code, name) {
|
|
12697
13114
|
const generated = GENERATED_TEMPLATES[code];
|
|
@@ -12752,9 +13169,9 @@ async function initProject(cwd, name, template, filesOverride) {
|
|
|
12752
13169
|
await mkdir2(projectPath, { recursive: true });
|
|
12753
13170
|
await Promise.all(
|
|
12754
13171
|
files.map(async (file2) => {
|
|
12755
|
-
const target =
|
|
12756
|
-
await mkdir2(
|
|
12757
|
-
await
|
|
13172
|
+
const target = join3(projectPath, file2.path);
|
|
13173
|
+
await mkdir2(dirname2(target), { recursive: true });
|
|
13174
|
+
await writeFile2(target, file2.content);
|
|
12758
13175
|
})
|
|
12759
13176
|
);
|
|
12760
13177
|
return { projectPath, files: files.map((file2) => file2.path) };
|
|
@@ -12945,7 +13362,8 @@ function registerAuth(program2, ctx) {
|
|
|
12945
13362
|
});
|
|
12946
13363
|
command.ok(result2, (data) => {
|
|
12947
13364
|
const d = data;
|
|
12948
|
-
|
|
13365
|
+
const replaced = d.replacedEmail !== void 0 ? `\uFF0C\u5DF2\u66FF\u6362\u539F ${d.replacedEmail} \u7684\u51ED\u636E` : "";
|
|
13366
|
+
return `\u5DF2\u767B\u5F55\uFF1A${d.email}\uFF08\u51ED\u636E\u6309 server \u5206\u69FD\u4FDD\u5B58\u4E8E ${ctx.paths.credentialsDir}/\uFF0C\u6743\u9650 0600${replaced}\uFF09`;
|
|
12949
13367
|
});
|
|
12950
13368
|
return;
|
|
12951
13369
|
}
|
|
@@ -12966,7 +13384,8 @@ function registerAuth(program2, ctx) {
|
|
|
12966
13384
|
});
|
|
12967
13385
|
command.ok(result, (data) => {
|
|
12968
13386
|
const d = data;
|
|
12969
|
-
|
|
13387
|
+
const replaced = d.replacedEmail !== void 0 ? `\uFF0C\u5DF2\u66FF\u6362\u539F ${d.replacedEmail} \u7684\u51ED\u636E` : "";
|
|
13388
|
+
return `\u5DF2\u767B\u5F55\uFF1A${d.email}\uFF08\u6D4F\u89C8\u5668\u7F51\u9875\u6388\u6743\uFF1B\u51ED\u636E\u6309 server \u5206\u69FD\u4FDD\u5B58\u4E8E ${ctx.paths.credentialsDir}/\uFF0C\u6743\u9650 0600${replaced}\uFF09`;
|
|
12970
13389
|
});
|
|
12971
13390
|
});
|
|
12972
13391
|
}
|
|
@@ -13023,17 +13442,17 @@ async function fetchTemplates(server) {
|
|
|
13023
13442
|
// packages/cli/src/template-package.ts
|
|
13024
13443
|
init_auth();
|
|
13025
13444
|
init_credentials();
|
|
13026
|
-
import { mkdir as mkdir7, readFile as readFile10, readdir as readdir3, stat as stat5, writeFile as
|
|
13027
|
-
import { join as
|
|
13445
|
+
import { mkdir as mkdir7, readFile as readFile10, readdir as readdir3, stat as stat5, writeFile as writeFile6 } from "node:fs/promises";
|
|
13446
|
+
import { join as join14 } from "node:path";
|
|
13028
13447
|
function cachedPackagePath(paths, code, version2) {
|
|
13029
|
-
return
|
|
13448
|
+
return join14(paths.home, "templates", `${code}-${version2}.json`);
|
|
13030
13449
|
}
|
|
13031
13450
|
async function collectTemplateDir(dir) {
|
|
13032
13451
|
const files = [];
|
|
13033
13452
|
async function walk(current, prefix) {
|
|
13034
13453
|
const entries = await readdir3(current, { withFileTypes: true });
|
|
13035
13454
|
for (const entry of entries) {
|
|
13036
|
-
const full =
|
|
13455
|
+
const full = join14(current, entry.name);
|
|
13037
13456
|
const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
13038
13457
|
if (entry.isDirectory()) {
|
|
13039
13458
|
await walk(full, rel);
|
|
@@ -13065,8 +13484,8 @@ async function loadCachedPackage(paths, code, version2) {
|
|
|
13065
13484
|
return pkg;
|
|
13066
13485
|
}
|
|
13067
13486
|
async function saveCachedPackage(paths, pkg) {
|
|
13068
|
-
await mkdir7(
|
|
13069
|
-
await
|
|
13487
|
+
await mkdir7(join14(paths.home, "templates"), { recursive: true });
|
|
13488
|
+
await writeFile6(cachedPackagePath(paths, pkg.code, pkg.version), JSON.stringify(pkg), "utf8");
|
|
13070
13489
|
}
|
|
13071
13490
|
async function downloadTemplatePackage(server, code) {
|
|
13072
13491
|
let response;
|
|
@@ -13151,7 +13570,7 @@ function packageManifestEntry(pkg) {
|
|
|
13151
13570
|
async function assertPublishableTemplate(dir, expectedCode) {
|
|
13152
13571
|
let info;
|
|
13153
13572
|
try {
|
|
13154
|
-
info = await stat5(
|
|
13573
|
+
info = await stat5(join14(dir, "template.json"));
|
|
13155
13574
|
} catch {
|
|
13156
13575
|
throw new CliError(
|
|
13157
13576
|
"TEMPLATE_NOT_PUBLISHABLE",
|
|
@@ -13165,7 +13584,7 @@ async function assertPublishableTemplate(dir, expectedCode) {
|
|
|
13165
13584
|
code: expectedCode,
|
|
13166
13585
|
version: "",
|
|
13167
13586
|
manifest: {},
|
|
13168
|
-
files: [{ path: "template.json", content: await readFile10(
|
|
13587
|
+
files: [{ path: "template.json", content: await readFile10(join14(dir, "template.json"), "utf8") }]
|
|
13169
13588
|
});
|
|
13170
13589
|
if (manifest === null) {
|
|
13171
13590
|
throw new CliError("TEMPLATE_NOT_PUBLISHABLE", `\u76EE\u5F55 ${dir}/template.json \u4E0D\u662F\u5408\u6CD5 JSON`);
|
|
@@ -13289,15 +13708,150 @@ function registerTemplates(program2, ctx) {
|
|
|
13289
13708
|
import { resolve as resolve10 } from "node:path";
|
|
13290
13709
|
|
|
13291
13710
|
// packages/cli/src/app-build.ts
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
13295
|
-
|
|
13296
|
-
import {
|
|
13297
|
-
import {
|
|
13298
|
-
|
|
13299
|
-
|
|
13300
|
-
import {
|
|
13711
|
+
import { mkdir as mkdir11, writeFile as writeFile12 } from "node:fs/promises";
|
|
13712
|
+
import { join as join22, resolve as resolve8 } from "node:path";
|
|
13713
|
+
|
|
13714
|
+
// packages/cli/src/app-init.ts
|
|
13715
|
+
import { cp, mkdir as mkdir8, readdir as readdir5, stat as stat7, writeFile as writeFile7 } from "node:fs/promises";
|
|
13716
|
+
import { dirname as dirname8, join as join16, resolve as resolve7 } from "node:path";
|
|
13717
|
+
|
|
13718
|
+
// packages/cli/src/app-template.ts
|
|
13719
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
13720
|
+
import { readdir as readdir4, readFile as readFile11, stat as stat6 } from "node:fs/promises";
|
|
13721
|
+
import { dirname as dirname7, join as join15 } from "node:path";
|
|
13722
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
13723
|
+
var TEMPLATE_VAR_ALLOWLIST = {
|
|
13724
|
+
"app-desktop": /* @__PURE__ */ new Set(["projectSlug", "appName", "appId", "platformUrl"]),
|
|
13725
|
+
"app-mobile": /* @__PURE__ */ new Set([
|
|
13726
|
+
"projectSlug",
|
|
13727
|
+
"appName",
|
|
13728
|
+
"platformUrl",
|
|
13729
|
+
"iosBundleId",
|
|
13730
|
+
"androidPackageId"
|
|
13731
|
+
]),
|
|
13732
|
+
// xtool 只做 iOS ⇒ 没有 androidPackageId。少这一个变量是**刻意的**:
|
|
13733
|
+
// 模板里若写了它,渲染期会 fail loud(而不是渲染出一个没有 Android 目标的空值)。
|
|
13734
|
+
"app-mobile-xtool": /* @__PURE__ */ new Set(["projectSlug", "appName", "platformUrl", "iosBundleId"])
|
|
13735
|
+
};
|
|
13736
|
+
function shellTemplateForPlatform(platform) {
|
|
13737
|
+
return platform === "mobile" ? "app-mobile" : "app-desktop";
|
|
13738
|
+
}
|
|
13739
|
+
function normalizeToolchain(input2) {
|
|
13740
|
+
if (input2 === void 0 || input2.length === 0) return "capacitor";
|
|
13741
|
+
if (input2 === "capacitor" || input2 === "xtool") return input2;
|
|
13742
|
+
throw new InitError(
|
|
13743
|
+
"INVALID_TOOLCHAIN",
|
|
13744
|
+
`--toolchain \u987B\u4E3A capacitor | xtool\uFF0C\u6536\u5230 "${input2}"\uFF08\u7F3A\u7701 capacitor\uFF09`
|
|
13745
|
+
);
|
|
13746
|
+
}
|
|
13747
|
+
function shellTemplateFor(platform, toolchain) {
|
|
13748
|
+
if (toolchain === "xtool") {
|
|
13749
|
+
if (platform !== "mobile") {
|
|
13750
|
+
throw new InitError(
|
|
13751
|
+
"INVALID_TOOLCHAIN",
|
|
13752
|
+
`--toolchain xtool \u53EA\u652F\u6301 --platform mobile\uFF08xtool \u4EA7\u51FA iOS \u539F\u751F app\uFF09\uFF0C\u6536\u5230 --platform ${platform}`
|
|
13753
|
+
);
|
|
13754
|
+
}
|
|
13755
|
+
return "app-mobile-xtool";
|
|
13756
|
+
}
|
|
13757
|
+
return shellTemplateForPlatform(platform);
|
|
13758
|
+
}
|
|
13759
|
+
var XTOOL_SHELL_REUSED_FROM_MOBILE = [
|
|
13760
|
+
{ from: "plugins/adep-bridge", to: "plugins/adep-bridge" },
|
|
13761
|
+
{ from: "web/adep-bridge.js", to: "web/adep-bridge.js" },
|
|
13762
|
+
{ from: "web/offline-runtime.js", to: "web/offline-runtime.js" }
|
|
13763
|
+
];
|
|
13764
|
+
var TEMPLATE_MANIFEST_FILES = /* @__PURE__ */ new Set(["template.json"]);
|
|
13765
|
+
async function collectRelPaths(dir, base) {
|
|
13766
|
+
const entries = await readdir4(dir, { withFileTypes: true });
|
|
13767
|
+
const nested = await Promise.all(
|
|
13768
|
+
entries.filter((entry) => entry.name !== ".DS_Store" && !TEMPLATE_MANIFEST_FILES.has(entry.name)).toSorted((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0).map((entry) => {
|
|
13769
|
+
const abs = join15(dir, entry.name);
|
|
13770
|
+
return entry.isDirectory() ? (
|
|
13771
|
+
// 递归时 base 必须带上子目录前缀,否则深层文件相对路径会丢目录段
|
|
13772
|
+
// (app-mobile 是嵌套目录结构:bridge/gate.mjs、plugins/adep-bridge/...)。
|
|
13773
|
+
collectRelPaths(abs, join15(base, entry.name))
|
|
13774
|
+
) : Promise.resolve([join15(base, entry.name).split("\\").join("/")]);
|
|
13775
|
+
})
|
|
13776
|
+
);
|
|
13777
|
+
return nested.flat();
|
|
13778
|
+
}
|
|
13779
|
+
async function findCliPackageRoot() {
|
|
13780
|
+
let dir = dirname7(fileURLToPath3(import.meta.url));
|
|
13781
|
+
for (; ; ) {
|
|
13782
|
+
let raw;
|
|
13783
|
+
try {
|
|
13784
|
+
raw = readFileSync3(join15(dir, "package.json"), "utf8");
|
|
13785
|
+
} catch {
|
|
13786
|
+
raw = "";
|
|
13787
|
+
}
|
|
13788
|
+
try {
|
|
13789
|
+
const pkg = JSON.parse(raw);
|
|
13790
|
+
if (pkg.name === "@adep/cli") return dir;
|
|
13791
|
+
} catch {
|
|
13792
|
+
}
|
|
13793
|
+
const parent = dirname7(dir);
|
|
13794
|
+
if (parent === dir) {
|
|
13795
|
+
throw new InitError(
|
|
13796
|
+
"SHELL_TEMPLATE_MISSING",
|
|
13797
|
+
"\u627E\u4E0D\u5230 @adep/cli \u7684 package.json\uFF08\u5DF2\u904D\u5386\u5230\u6587\u4EF6\u7CFB\u7EDF\u6839\uFF09"
|
|
13798
|
+
);
|
|
13799
|
+
}
|
|
13800
|
+
dir = parent;
|
|
13801
|
+
}
|
|
13802
|
+
}
|
|
13803
|
+
async function appShellTemplateDir(code = "app-desktop") {
|
|
13804
|
+
const dir = join15(await findCliPackageRoot(), "templates", code);
|
|
13805
|
+
try {
|
|
13806
|
+
await stat6(dir);
|
|
13807
|
+
} catch {
|
|
13808
|
+
throw new InitError(
|
|
13809
|
+
"SHELL_TEMPLATE_MISSING",
|
|
13810
|
+
`\u58F3\u6A21\u677F\u76EE\u5F55\u7F3A\u5931\uFF1A${dir}\uFF08\u5B89\u88C5\u4EA7\u7269\u5E94\u5305\u542B templates/\uFF0C\u68C0\u67E5 package.json \u7684 files \u5B57\u6BB5\uFF09`
|
|
13811
|
+
);
|
|
13812
|
+
}
|
|
13813
|
+
return dir;
|
|
13814
|
+
}
|
|
13815
|
+
async function renderAppShellTemplate(vars, code = "app-desktop") {
|
|
13816
|
+
const templateDir = await appShellTemplateDir(code);
|
|
13817
|
+
const rels = await collectRelPaths(templateDir, ".");
|
|
13818
|
+
const allowed = TEMPLATE_VAR_ALLOWLIST[code];
|
|
13819
|
+
const values = {
|
|
13820
|
+
projectSlug: vars.projectSlug,
|
|
13821
|
+
appName: vars.appName,
|
|
13822
|
+
platformUrl: vars.platformUrl,
|
|
13823
|
+
// ⚠️ 判据是「desktop 与 mobile 族」而不是「是不是 app-mobile」——`app-mobile-xtool`
|
|
13824
|
+
// 同样要 iosBundleId。原来写成 `code === 'app-mobile' ? ... : { appId }` 时,
|
|
13825
|
+
// 新 code 会落进 else 分支:`{{iosBundleId}}` 取到 `undefined → ''`,
|
|
13826
|
+
// 渲染出一个 **bundle id 为空** 的工程(SwiftPM/xtool 都在更晚的环节才报错)。
|
|
13827
|
+
...code === "app-desktop" ? { appId: vars.appId ?? "" } : {
|
|
13828
|
+
iosBundleId: vars.iosBundleId ?? "",
|
|
13829
|
+
androidPackageId: vars.androidPackageId ?? ""
|
|
13830
|
+
}
|
|
13831
|
+
};
|
|
13832
|
+
return Promise.all(
|
|
13833
|
+
rels.map(async (rel) => {
|
|
13834
|
+
const raw = await readFile11(join15(templateDir, rel), "utf8");
|
|
13835
|
+
const content = raw.replace(/\{\{\s*([A-Za-z0-9_-]+)\s*\}\}/g, (whole, name) => {
|
|
13836
|
+
if (!allowed.has(name)) {
|
|
13837
|
+
throw new InitError(
|
|
13838
|
+
"SHELL_TEMPLATE_INVALID",
|
|
13839
|
+
`\u58F3\u6A21\u677F ${code} \u7684\u6587\u4EF6 ${rel} \u4F7F\u7528\u4E86\u672A\u652F\u6301\u53D8\u91CF "${whole}"\uFF1A\u5141\u8BB8 ${[...allowed].join(" | ")}`
|
|
13840
|
+
);
|
|
13841
|
+
}
|
|
13842
|
+
return values[name] ?? "";
|
|
13843
|
+
});
|
|
13844
|
+
const leftover = /\{\{\s*[A-Za-z0-9_-]+\s*\}\}/.exec(content);
|
|
13845
|
+
if (leftover !== null) {
|
|
13846
|
+
throw new InitError(
|
|
13847
|
+
"SHELL_TEMPLATE_INVALID",
|
|
13848
|
+
`\u58F3\u6A21\u677F ${code} \u7684\u6587\u4EF6 ${rel} \u6E32\u67D3\u540E\u4ECD\u6709\u672A\u66FF\u6362\u5360\u4F4D\u7B26 "${leftover[0]}"`
|
|
13849
|
+
);
|
|
13850
|
+
}
|
|
13851
|
+
return { path: rel, content };
|
|
13852
|
+
})
|
|
13853
|
+
);
|
|
13854
|
+
}
|
|
13301
13855
|
|
|
13302
13856
|
// node_modules/.pnpm/zod@4.6.7/node_modules/zod/v4/classic/external.js
|
|
13303
13857
|
var external_exports = {};
|
|
@@ -33050,148 +33604,6 @@ function parseAdepAppConfig(input2) {
|
|
|
33050
33604
|
return parsed.data;
|
|
33051
33605
|
}
|
|
33052
33606
|
|
|
33053
|
-
// packages/cli/src/app-init.ts
|
|
33054
|
-
import { cp, mkdir as mkdir8, readdir as readdir5, stat as stat7, writeFile as writeFile6 } from "node:fs/promises";
|
|
33055
|
-
import { dirname as dirname9, join as join15, resolve as resolve7 } from "node:path";
|
|
33056
|
-
|
|
33057
|
-
// packages/cli/src/app-template.ts
|
|
33058
|
-
import { readFileSync as readFileSync3 } from "node:fs";
|
|
33059
|
-
import { readdir as readdir4, readFile as readFile11, stat as stat6 } from "node:fs/promises";
|
|
33060
|
-
import { dirname as dirname8, join as join14 } from "node:path";
|
|
33061
|
-
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
33062
|
-
var TEMPLATE_VAR_ALLOWLIST = {
|
|
33063
|
-
"app-desktop": /* @__PURE__ */ new Set(["projectSlug", "appName", "appId", "platformUrl"]),
|
|
33064
|
-
"app-mobile": /* @__PURE__ */ new Set([
|
|
33065
|
-
"projectSlug",
|
|
33066
|
-
"appName",
|
|
33067
|
-
"platformUrl",
|
|
33068
|
-
"iosBundleId",
|
|
33069
|
-
"androidPackageId"
|
|
33070
|
-
]),
|
|
33071
|
-
// xtool 只做 iOS ⇒ 没有 androidPackageId。少这一个变量是**刻意的**:
|
|
33072
|
-
// 模板里若写了它,渲染期会 fail loud(而不是渲染出一个没有 Android 目标的空值)。
|
|
33073
|
-
"app-mobile-xtool": /* @__PURE__ */ new Set(["projectSlug", "appName", "platformUrl", "iosBundleId"])
|
|
33074
|
-
};
|
|
33075
|
-
function shellTemplateForPlatform(platform) {
|
|
33076
|
-
return platform === "mobile" ? "app-mobile" : "app-desktop";
|
|
33077
|
-
}
|
|
33078
|
-
function normalizeToolchain(input2) {
|
|
33079
|
-
if (input2 === void 0 || input2.length === 0) return "capacitor";
|
|
33080
|
-
if (input2 === "capacitor" || input2 === "xtool") return input2;
|
|
33081
|
-
throw new InitError(
|
|
33082
|
-
"INVALID_TOOLCHAIN",
|
|
33083
|
-
`--toolchain \u987B\u4E3A capacitor | xtool\uFF0C\u6536\u5230 "${input2}"\uFF08\u7F3A\u7701 capacitor\uFF09`
|
|
33084
|
-
);
|
|
33085
|
-
}
|
|
33086
|
-
function shellTemplateFor(platform, toolchain) {
|
|
33087
|
-
if (toolchain === "xtool") {
|
|
33088
|
-
if (platform !== "mobile") {
|
|
33089
|
-
throw new InitError(
|
|
33090
|
-
"INVALID_TOOLCHAIN",
|
|
33091
|
-
`--toolchain xtool \u53EA\u652F\u6301 --platform mobile\uFF08xtool \u4EA7\u51FA iOS \u539F\u751F app\uFF09\uFF0C\u6536\u5230 --platform ${platform}`
|
|
33092
|
-
);
|
|
33093
|
-
}
|
|
33094
|
-
return "app-mobile-xtool";
|
|
33095
|
-
}
|
|
33096
|
-
return shellTemplateForPlatform(platform);
|
|
33097
|
-
}
|
|
33098
|
-
var XTOOL_SHELL_REUSED_FROM_MOBILE = [
|
|
33099
|
-
{ from: "plugins/adep-bridge", to: "plugins/adep-bridge" },
|
|
33100
|
-
{ from: "web/adep-bridge.js", to: "web/adep-bridge.js" },
|
|
33101
|
-
{ from: "web/offline-runtime.js", to: "web/offline-runtime.js" }
|
|
33102
|
-
];
|
|
33103
|
-
var TEMPLATE_MANIFEST_FILES = /* @__PURE__ */ new Set(["template.json"]);
|
|
33104
|
-
async function collectRelPaths(dir, base) {
|
|
33105
|
-
const entries = await readdir4(dir, { withFileTypes: true });
|
|
33106
|
-
const nested = await Promise.all(
|
|
33107
|
-
entries.filter((entry) => entry.name !== ".DS_Store" && !TEMPLATE_MANIFEST_FILES.has(entry.name)).toSorted((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0).map((entry) => {
|
|
33108
|
-
const abs = join14(dir, entry.name);
|
|
33109
|
-
return entry.isDirectory() ? (
|
|
33110
|
-
// 递归时 base 必须带上子目录前缀,否则深层文件相对路径会丢目录段
|
|
33111
|
-
// (app-mobile 是嵌套目录结构:bridge/gate.mjs、plugins/adep-bridge/...)。
|
|
33112
|
-
collectRelPaths(abs, join14(base, entry.name))
|
|
33113
|
-
) : Promise.resolve([join14(base, entry.name).split("\\").join("/")]);
|
|
33114
|
-
})
|
|
33115
|
-
);
|
|
33116
|
-
return nested.flat();
|
|
33117
|
-
}
|
|
33118
|
-
async function findCliPackageRoot() {
|
|
33119
|
-
let dir = dirname8(fileURLToPath3(import.meta.url));
|
|
33120
|
-
for (; ; ) {
|
|
33121
|
-
let raw;
|
|
33122
|
-
try {
|
|
33123
|
-
raw = readFileSync3(join14(dir, "package.json"), "utf8");
|
|
33124
|
-
} catch {
|
|
33125
|
-
raw = "";
|
|
33126
|
-
}
|
|
33127
|
-
try {
|
|
33128
|
-
const pkg = JSON.parse(raw);
|
|
33129
|
-
if (pkg.name === "@adep/cli") return dir;
|
|
33130
|
-
} catch {
|
|
33131
|
-
}
|
|
33132
|
-
const parent = dirname8(dir);
|
|
33133
|
-
if (parent === dir) {
|
|
33134
|
-
throw new InitError(
|
|
33135
|
-
"SHELL_TEMPLATE_MISSING",
|
|
33136
|
-
"\u627E\u4E0D\u5230 @adep/cli \u7684 package.json\uFF08\u5DF2\u904D\u5386\u5230\u6587\u4EF6\u7CFB\u7EDF\u6839\uFF09"
|
|
33137
|
-
);
|
|
33138
|
-
}
|
|
33139
|
-
dir = parent;
|
|
33140
|
-
}
|
|
33141
|
-
}
|
|
33142
|
-
async function appShellTemplateDir(code = "app-desktop") {
|
|
33143
|
-
const dir = join14(await findCliPackageRoot(), "templates", code);
|
|
33144
|
-
try {
|
|
33145
|
-
await stat6(dir);
|
|
33146
|
-
} catch {
|
|
33147
|
-
throw new InitError(
|
|
33148
|
-
"SHELL_TEMPLATE_MISSING",
|
|
33149
|
-
`\u58F3\u6A21\u677F\u76EE\u5F55\u7F3A\u5931\uFF1A${dir}\uFF08\u5B89\u88C5\u4EA7\u7269\u5E94\u5305\u542B templates/\uFF0C\u68C0\u67E5 package.json \u7684 files \u5B57\u6BB5\uFF09`
|
|
33150
|
-
);
|
|
33151
|
-
}
|
|
33152
|
-
return dir;
|
|
33153
|
-
}
|
|
33154
|
-
async function renderAppShellTemplate(vars, code = "app-desktop") {
|
|
33155
|
-
const templateDir = await appShellTemplateDir(code);
|
|
33156
|
-
const rels = await collectRelPaths(templateDir, ".");
|
|
33157
|
-
const allowed = TEMPLATE_VAR_ALLOWLIST[code];
|
|
33158
|
-
const values = {
|
|
33159
|
-
projectSlug: vars.projectSlug,
|
|
33160
|
-
appName: vars.appName,
|
|
33161
|
-
platformUrl: vars.platformUrl,
|
|
33162
|
-
// ⚠️ 判据是「desktop 与 mobile 族」而不是「是不是 app-mobile」——`app-mobile-xtool`
|
|
33163
|
-
// 同样要 iosBundleId。原来写成 `code === 'app-mobile' ? ... : { appId }` 时,
|
|
33164
|
-
// 新 code 会落进 else 分支:`{{iosBundleId}}` 取到 `undefined → ''`,
|
|
33165
|
-
// 渲染出一个 **bundle id 为空** 的工程(SwiftPM/xtool 都在更晚的环节才报错)。
|
|
33166
|
-
...code === "app-desktop" ? { appId: vars.appId ?? "" } : {
|
|
33167
|
-
iosBundleId: vars.iosBundleId ?? "",
|
|
33168
|
-
androidPackageId: vars.androidPackageId ?? ""
|
|
33169
|
-
}
|
|
33170
|
-
};
|
|
33171
|
-
return Promise.all(
|
|
33172
|
-
rels.map(async (rel) => {
|
|
33173
|
-
const raw = await readFile11(join14(templateDir, rel), "utf8");
|
|
33174
|
-
const content = raw.replace(/\{\{\s*([A-Za-z0-9_-]+)\s*\}\}/g, (whole, name) => {
|
|
33175
|
-
if (!allowed.has(name)) {
|
|
33176
|
-
throw new InitError(
|
|
33177
|
-
"SHELL_TEMPLATE_INVALID",
|
|
33178
|
-
`\u58F3\u6A21\u677F ${code} \u7684\u6587\u4EF6 ${rel} \u4F7F\u7528\u4E86\u672A\u652F\u6301\u53D8\u91CF "${whole}"\uFF1A\u5141\u8BB8 ${[...allowed].join(" | ")}`
|
|
33179
|
-
);
|
|
33180
|
-
}
|
|
33181
|
-
return values[name] ?? "";
|
|
33182
|
-
});
|
|
33183
|
-
const leftover = /\{\{\s*[A-Za-z0-9_-]+\s*\}\}/.exec(content);
|
|
33184
|
-
if (leftover !== null) {
|
|
33185
|
-
throw new InitError(
|
|
33186
|
-
"SHELL_TEMPLATE_INVALID",
|
|
33187
|
-
`\u58F3\u6A21\u677F ${code} \u7684\u6587\u4EF6 ${rel} \u6E32\u67D3\u540E\u4ECD\u6709\u672A\u66FF\u6362\u5360\u4F4D\u7B26 "${leftover[0]}"`
|
|
33188
|
-
);
|
|
33189
|
-
}
|
|
33190
|
-
return { path: rel, content };
|
|
33191
|
-
})
|
|
33192
|
-
);
|
|
33193
|
-
}
|
|
33194
|
-
|
|
33195
33607
|
// packages/cli/src/app-init.ts
|
|
33196
33608
|
function appIdForSlug(slug) {
|
|
33197
33609
|
return `top.adep.${slug}`;
|
|
@@ -33264,16 +33676,16 @@ async function initAppShell(cwd, input2) {
|
|
|
33264
33676
|
await Promise.all(
|
|
33265
33677
|
files.map(async (file2) => {
|
|
33266
33678
|
if (file2.path === "adep.app.json") return;
|
|
33267
|
-
const target =
|
|
33268
|
-
await mkdir8(
|
|
33269
|
-
await
|
|
33679
|
+
const target = join16(appPath, file2.path);
|
|
33680
|
+
await mkdir8(dirname8(target), { recursive: true });
|
|
33681
|
+
await writeFile7(target, file2.content);
|
|
33270
33682
|
})
|
|
33271
33683
|
);
|
|
33272
|
-
await
|
|
33684
|
+
await writeFile7(join16(appPath, "adep.app.json"), configJson);
|
|
33273
33685
|
for (const item of reused) {
|
|
33274
|
-
await cp(item.from,
|
|
33686
|
+
await cp(item.from, join16(appPath, item.to), { recursive: true });
|
|
33275
33687
|
}
|
|
33276
|
-
const reusedFiles = (await Promise.all(reused.map((item) => listFiles(
|
|
33688
|
+
const reusedFiles = (await Promise.all(reused.map((item) => listFiles(join16(appPath, item.to), item.to)))).flat();
|
|
33277
33689
|
const written = files.map((file2) => file2.path).filter((path) => path !== "adep.app.json");
|
|
33278
33690
|
return {
|
|
33279
33691
|
appPath,
|
|
@@ -33285,7 +33697,7 @@ async function resolveXtoolReusedSources() {
|
|
|
33285
33697
|
const mobileDir = await appShellTemplateDir("app-mobile");
|
|
33286
33698
|
const resolved = [];
|
|
33287
33699
|
for (const item of XTOOL_SHELL_REUSED_FROM_MOBILE) {
|
|
33288
|
-
const from =
|
|
33700
|
+
const from = join16(mobileDir, item.from);
|
|
33289
33701
|
try {
|
|
33290
33702
|
await stat7(from);
|
|
33291
33703
|
} catch {
|
|
@@ -33304,7 +33716,7 @@ async function listFiles(path, base) {
|
|
|
33304
33716
|
const nested = await Promise.all(
|
|
33305
33717
|
entries.filter((entry) => entry.name !== ".DS_Store").map((entry) => {
|
|
33306
33718
|
const rel = `${base}/${entry.name}`;
|
|
33307
|
-
return entry.isDirectory() ? listFiles(
|
|
33719
|
+
return entry.isDirectory() ? listFiles(join16(path, entry.name), rel) : Promise.resolve([rel]);
|
|
33308
33720
|
})
|
|
33309
33721
|
);
|
|
33310
33722
|
return nested.flat().toSorted();
|
|
@@ -33312,8 +33724,10 @@ async function listFiles(path, base) {
|
|
|
33312
33724
|
|
|
33313
33725
|
// packages/cli/src/app-build.ts
|
|
33314
33726
|
init_client();
|
|
33315
|
-
init_config();
|
|
33316
33727
|
init_client2();
|
|
33728
|
+
|
|
33729
|
+
// packages/cli/src/app-build/shared.ts
|
|
33730
|
+
import { stat as stat8 } from "node:fs/promises";
|
|
33317
33731
|
var SITE_PREFIX = "site/";
|
|
33318
33732
|
var SHELL_SITE_DIR = "app/site";
|
|
33319
33733
|
var MOBILE_SITE_ASSET_FILES = {
|
|
@@ -33370,30 +33784,15 @@ async function pathExists(path) {
|
|
|
33370
33784
|
return false;
|
|
33371
33785
|
}
|
|
33372
33786
|
}
|
|
33373
|
-
|
|
33374
|
-
|
|
33375
|
-
|
|
33376
|
-
|
|
33377
|
-
|
|
33378
|
-
|
|
33379
|
-
|
|
33380
|
-
|
|
33381
|
-
|
|
33382
|
-
);
|
|
33383
|
-
}
|
|
33384
|
-
let parsed;
|
|
33385
|
-
try {
|
|
33386
|
-
parsed = JSON.parse(text);
|
|
33387
|
-
} catch (error62) {
|
|
33388
|
-
throw new InitError(
|
|
33389
|
-
"APP_CONFIG_INVALID",
|
|
33390
|
-
`adep.app.json \u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${error62 instanceof Error ? error62.message : String(error62)}`
|
|
33391
|
-
);
|
|
33392
|
-
}
|
|
33393
|
-
const config2 = parseAdepAppConfig(parsed);
|
|
33394
|
-
const raw = parsed ?? {};
|
|
33395
|
-
return { raw, config: config2 };
|
|
33396
|
-
}
|
|
33787
|
+
|
|
33788
|
+
// packages/cli/src/app-build/bundle.ts
|
|
33789
|
+
init_shared_source();
|
|
33790
|
+
init_validate();
|
|
33791
|
+
init_zip();
|
|
33792
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
33793
|
+
import { mkdir as mkdir9, mkdtemp, readFile as readFile12, rm as rm3, writeFile as writeFile9 } from "node:fs/promises";
|
|
33794
|
+
import { tmpdir } from "node:os";
|
|
33795
|
+
import { dirname as dirname9, join as join17, posix } from "node:path";
|
|
33397
33796
|
function computeBundleVersion(manifest) {
|
|
33398
33797
|
const siteEntries = manifest.contents.filter((content) => content.path.startsWith(SITE_PREFIX)).toSorted((left, right) => compareByCodeUnit(left.path, right.path));
|
|
33399
33798
|
const fingerprint = createHash2("sha256").update(siteEntries.map((content) => `${content.path}:${content.sha256}`).join("\n")).digest("hex").slice(0, 12);
|
|
@@ -33483,23 +33882,18 @@ function verifySiteContents(manifest, entries) {
|
|
|
33483
33882
|
}
|
|
33484
33883
|
}
|
|
33485
33884
|
async function writeSiteTree(shellDir, site) {
|
|
33486
|
-
const targetRoot =
|
|
33885
|
+
const targetRoot = join17(shellDir, SHELL_SITE_DIR);
|
|
33487
33886
|
await rm3(targetRoot, { recursive: true, force: true });
|
|
33488
33887
|
await mkdir9(targetRoot, { recursive: true });
|
|
33489
33888
|
const written = [];
|
|
33490
33889
|
for (const [rel, bytes] of site) {
|
|
33491
|
-
const dest =
|
|
33492
|
-
await mkdir9(
|
|
33493
|
-
await
|
|
33890
|
+
const dest = join17(targetRoot, ...rel.split("/"));
|
|
33891
|
+
await mkdir9(dirname9(dest), { recursive: true });
|
|
33892
|
+
await writeFile9(dest, bytes);
|
|
33494
33893
|
written.push({ path: `${SHELL_SITE_DIR}/${rel}`, size: bytes.length });
|
|
33495
33894
|
}
|
|
33496
33895
|
return written;
|
|
33497
33896
|
}
|
|
33498
|
-
async function bindVersion(shellDir, raw, binding) {
|
|
33499
|
-
const next = { ...raw, build: binding };
|
|
33500
|
-
await writeFile8(join16(shellDir, "adep.app.json"), `${JSON.stringify(next, null, 2)}
|
|
33501
|
-
`);
|
|
33502
|
-
}
|
|
33503
33897
|
async function waitForExport(api, jobId, pollIntervalMs, maxPollAttempts) {
|
|
33504
33898
|
let attempts = 0;
|
|
33505
33899
|
for (; ; ) {
|
|
@@ -33515,6 +33909,113 @@ async function waitForExport(api, jobId, pollIntervalMs, maxPollAttempts) {
|
|
|
33515
33909
|
await new Promise((resolvePromise) => setTimeout(resolvePromise, pollIntervalMs));
|
|
33516
33910
|
}
|
|
33517
33911
|
}
|
|
33912
|
+
async function fetchAndInjectSite(input2) {
|
|
33913
|
+
const workDir = await mkdtemp(join17(tmpdir(), "adep-app-build-"));
|
|
33914
|
+
try {
|
|
33915
|
+
const zipPath = join17(workDir, "bundle.zip");
|
|
33916
|
+
await input2.api.downloadBundle(input2.jobId, zipPath);
|
|
33917
|
+
const entries = zipRead(await readFile12(zipPath));
|
|
33918
|
+
const manifest = readManifest(entries);
|
|
33919
|
+
verifySiteContents(manifest, entries);
|
|
33920
|
+
const site = collectSiteEntries(entries);
|
|
33921
|
+
if (site.size === 0) {
|
|
33922
|
+
throw new InitError(
|
|
33923
|
+
"APP_NO_PUBLISHED_FRONTEND",
|
|
33924
|
+
`\u9879\u76EE "${input2.projectSlug}" \u6CA1\u6709\u5DF2\u53D1\u5E03\u7684\u9875\u9762\u4EA7\u7269\uFF08\u5BFC\u51FA\u5305\u5185\u6CA1\u6709 ${SITE_PREFIX}\uFF09\uFF1A\u8BF7\u5148\u6267\u884C adep publish --only frontend --project ${input2.projectSlug}`
|
|
33925
|
+
);
|
|
33926
|
+
}
|
|
33927
|
+
return { manifest, written: await writeSiteTree(input2.shellDir, site) };
|
|
33928
|
+
} finally {
|
|
33929
|
+
await rm3(workDir, { recursive: true, force: true });
|
|
33930
|
+
}
|
|
33931
|
+
}
|
|
33932
|
+
|
|
33933
|
+
// packages/cli/src/app-build/shell.ts
|
|
33934
|
+
import { readFile as readFile13, writeFile as writeFile10 } from "node:fs/promises";
|
|
33935
|
+
import { join as join18 } from "node:path";
|
|
33936
|
+
async function readShellConfig(shellDir) {
|
|
33937
|
+
const configPath = join18(shellDir, "adep.app.json");
|
|
33938
|
+
let text;
|
|
33939
|
+
try {
|
|
33940
|
+
text = await readFile13(configPath, "utf8");
|
|
33941
|
+
} catch {
|
|
33942
|
+
throw new InitError(
|
|
33943
|
+
"APP_CONFIG_NOT_FOUND",
|
|
33944
|
+
`\u672A\u627E\u5230 ${configPath}\uFF1A\u8BE5\u76EE\u5F55\u4E0D\u662F\u684C\u9762\u58F3\u5DE5\u7A0B\uFF0C\u6216\u5C1A\u672A\u6267\u884C adep app init --dir ${shellDir}`
|
|
33945
|
+
);
|
|
33946
|
+
}
|
|
33947
|
+
let parsed;
|
|
33948
|
+
try {
|
|
33949
|
+
parsed = JSON.parse(text);
|
|
33950
|
+
} catch (error62) {
|
|
33951
|
+
throw new InitError(
|
|
33952
|
+
"APP_CONFIG_INVALID",
|
|
33953
|
+
`adep.app.json \u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${error62 instanceof Error ? error62.message : String(error62)}`
|
|
33954
|
+
);
|
|
33955
|
+
}
|
|
33956
|
+
const config2 = parseAdepAppConfig(parsed);
|
|
33957
|
+
const raw = parsed ?? {};
|
|
33958
|
+
return { raw, config: config2 };
|
|
33959
|
+
}
|
|
33960
|
+
async function bindVersion(shellDir, raw, binding) {
|
|
33961
|
+
const next = { ...raw, build: binding };
|
|
33962
|
+
await writeFile10(join18(shellDir, "adep.app.json"), `${JSON.stringify(next, null, 2)}
|
|
33963
|
+
`);
|
|
33964
|
+
}
|
|
33965
|
+
|
|
33966
|
+
// packages/cli/src/app-build/site.ts
|
|
33967
|
+
import { copyFile, readFile as readFile14, writeFile as writeFile11 } from "node:fs/promises";
|
|
33968
|
+
import { join as join19 } from "node:path";
|
|
33969
|
+
async function readEntryPage(indexPath) {
|
|
33970
|
+
try {
|
|
33971
|
+
return await readFile14(indexPath, "utf8");
|
|
33972
|
+
} catch (error62) {
|
|
33973
|
+
const code = typeof error62 === "object" && error62 !== null ? error62.code : void 0;
|
|
33974
|
+
if (code === "ENOENT") {
|
|
33975
|
+
throw new InitError(
|
|
33976
|
+
"APP_SITE_MISSING",
|
|
33977
|
+
`\u7AD9\u70B9\u4EA7\u7269\u7F3A\u5165\u53E3\u9875\uFF1A${indexPath} \u4E0D\u5B58\u5728\u3002\u79FB\u52A8\u58F3\u7684 WebView \u6052\u52A0\u8F7D index.html\uFF0C\u7F3A\u4E86\u88C5\u673A\u5C31\u662F\u767D\u5C4F\u2014\u2014\u8BF7\u786E\u8BA4\u7AD9\u70B9\u5DF2\u53D1\u5E03\u4E14\u5165\u53E3\u9875\u662F**\u6839\u7EA7** index.html\uFF08\`adep publish --only frontend\`\uFF09\uFF0C\u518D\u91CD\u8DD1 adep app build`
|
|
33978
|
+
);
|
|
33979
|
+
}
|
|
33980
|
+
throw new InitError(
|
|
33981
|
+
"APP_SITE_UNREADABLE",
|
|
33982
|
+
`\u7AD9\u70B9\u5165\u53E3\u9875\u8BFB\u4E0D\u51FA\u6765\uFF1A${indexPath}\uFF08${error62 instanceof Error ? error62.message : String(error62)}\uFF09`
|
|
33983
|
+
);
|
|
33984
|
+
}
|
|
33985
|
+
}
|
|
33986
|
+
async function injectMobileShellAssets(input2) {
|
|
33987
|
+
const siteRoot = join19(input2.shellDir, SHELL_SITE_DIR);
|
|
33988
|
+
const indexPath = join19(siteRoot, "index.html");
|
|
33989
|
+
const html = await readEntryPage(indexPath);
|
|
33990
|
+
const permissionsJson = `${JSON.stringify(
|
|
33991
|
+
{ schemaVersion: 1, permissions: sortPermissions(input2.permissions) },
|
|
33992
|
+
null,
|
|
33993
|
+
2
|
|
33994
|
+
)}
|
|
33995
|
+
`;
|
|
33996
|
+
await writeFile11(join19(siteRoot, MOBILE_SITE_ASSET_FILES.permissions), permissionsJson);
|
|
33997
|
+
await copyFile(
|
|
33998
|
+
join19(input2.shellDir, "web", "adep-bridge.js"),
|
|
33999
|
+
join19(siteRoot, MOBILE_SITE_ASSET_FILES.bridge)
|
|
34000
|
+
);
|
|
34001
|
+
await copyFile(
|
|
34002
|
+
join19(input2.shellDir, "adep.app.json"),
|
|
34003
|
+
join19(siteRoot, MOBILE_SITE_ASSET_FILES.config)
|
|
34004
|
+
);
|
|
34005
|
+
if (html.includes("adep-bridge.js")) return;
|
|
34006
|
+
const tag = '<script src="/adep-bridge.js"></script>';
|
|
34007
|
+
const next = html.includes("</head>") ? html.replace("</head>", `${tag}
|
|
34008
|
+
</head>`) : `${tag}
|
|
34009
|
+
${html}`;
|
|
34010
|
+
await writeFile11(indexPath, next);
|
|
34011
|
+
}
|
|
34012
|
+
|
|
34013
|
+
// packages/cli/src/app-build/toolchain.ts
|
|
34014
|
+
init_config();
|
|
34015
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
34016
|
+
import { closeSync, openSync } from "node:fs";
|
|
34017
|
+
import { copyFile as copyFile2, mkdir as mkdir10, readdir as readdir6 } from "node:fs/promises";
|
|
34018
|
+
import { basename as basename2, join as join20 } from "node:path";
|
|
33518
34019
|
function platformArgs(platform) {
|
|
33519
34020
|
if (platform === "darwin") return ["--mac"];
|
|
33520
34021
|
if (platform === "win32") return ["--win"];
|
|
@@ -33522,7 +34023,7 @@ function platformArgs(platform) {
|
|
|
33522
34023
|
}
|
|
33523
34024
|
function resolvePackagerBinary(shellDir) {
|
|
33524
34025
|
const name = process.platform === "win32" ? "electron-builder.cmd" : "electron-builder";
|
|
33525
|
-
return
|
|
34026
|
+
return join20(shellDir, "node_modules", ".bin", name);
|
|
33526
34027
|
}
|
|
33527
34028
|
function missingDepsError(shellDir) {
|
|
33528
34029
|
return new InitError(
|
|
@@ -33534,17 +34035,17 @@ function missingMobileDepsError(shellDir, platform) {
|
|
|
33534
34035
|
if (platform === "ios") {
|
|
33535
34036
|
return new InitError(
|
|
33536
34037
|
"APP_SHELL_DEPS_MISSING",
|
|
33537
|
-
`\u672A\u627E\u5230 iOS \u539F\u751F\u5DE5\u7A0B\uFF08${
|
|
34038
|
+
`\u672A\u627E\u5230 iOS \u539F\u751F\u5DE5\u7A0B\uFF08${join20(shellDir, "ios", "App")}\uFF09\uFF1A\u8BF7\u5148\u5728 ${shellDir} \u6267\u884C npx cap add ios && npx cap sync`
|
|
33538
34039
|
);
|
|
33539
34040
|
}
|
|
33540
34041
|
return new InitError(
|
|
33541
34042
|
"APP_SHELL_DEPS_MISSING",
|
|
33542
|
-
`\u672A\u627E\u5230 Android \u539F\u751F\u5DE5\u7A0B\uFF08${
|
|
34043
|
+
`\u672A\u627E\u5230 Android \u539F\u751F\u5DE5\u7A0B\uFF08${join20(shellDir, "android", "gradlew")}\uFF09\uFF1A\u8BF7\u5148\u5728 ${shellDir} \u6267\u884C npx cap add android && npx cap sync`
|
|
33543
34044
|
);
|
|
33544
34045
|
}
|
|
33545
34046
|
function resolveCapBinary(shellDir) {
|
|
33546
34047
|
const name = process.platform === "win32" ? "cap.cmd" : "cap";
|
|
33547
|
-
return
|
|
34048
|
+
return join20(shellDir, "node_modules", ".bin", name);
|
|
33548
34049
|
}
|
|
33549
34050
|
async function syncCapacitorAssets(input2) {
|
|
33550
34051
|
const capBin = resolveCapBinary(input2.shellDir);
|
|
@@ -33567,11 +34068,11 @@ async function assertShellPackagerReady(shellDir, platform, prepareOnly, toolcha
|
|
|
33567
34068
|
return;
|
|
33568
34069
|
}
|
|
33569
34070
|
if (platform === "ios") {
|
|
33570
|
-
if (!await pathExists(
|
|
33571
|
-
if (await pathExists(
|
|
34071
|
+
if (!await pathExists(join20(shellDir, "ios", "App"))) {
|
|
34072
|
+
if (await pathExists(join20(shellDir, "xtool.yml"))) {
|
|
33572
34073
|
throw new InitError(
|
|
33573
34074
|
"APP_SHELL_DEPS_MISSING",
|
|
33574
|
-
`\u672A\u627E\u5230 Capacitor \u7684 iOS \u539F\u751F\u5DE5\u7A0B\uFF08${
|
|
34075
|
+
`\u672A\u627E\u5230 Capacitor \u7684 iOS \u539F\u751F\u5DE5\u7A0B\uFF08${join20(shellDir, "ios", "App")}\uFF09\uFF1B\u4F46\u68C0\u6D4B\u5230\u8BE5\u76EE\u5F55\u662F xtool \u58F3\u5DE5\u7A0B\uFF08\u6709 xtool.yml\uFF09\u2014\u2014\u672C\u6B21\u8BF7\u52A0 --toolchain xtool`
|
|
33575
34076
|
);
|
|
33576
34077
|
}
|
|
33577
34078
|
throw missingMobileDepsError(shellDir, "ios");
|
|
@@ -33587,16 +34088,16 @@ async function assertShellPackagerReady(shellDir, platform, prepareOnly, toolcha
|
|
|
33587
34088
|
if (!await pathExists(resolvePackagerBinary(shellDir))) throw missingDepsError(shellDir);
|
|
33588
34089
|
}
|
|
33589
34090
|
async function assertXtoolShellReady(shellDir) {
|
|
33590
|
-
if (!await pathExists(
|
|
34091
|
+
if (!await pathExists(join20(shellDir, "xtool.yml")) || !await pathExists(join20(shellDir, "Package.swift"))) {
|
|
33591
34092
|
throw new InitError(
|
|
33592
34093
|
"APP_SHELL_DEPS_MISSING",
|
|
33593
|
-
`\u672A\u627E\u5230 xtool \u58F3\u5DE5\u7A0B\uFF08\u9700\u8981 ${
|
|
34094
|
+
`\u672A\u627E\u5230 xtool \u58F3\u5DE5\u7A0B\uFF08\u9700\u8981 ${join20(shellDir, "xtool.yml")} \u4E0E ${join20(shellDir, "Package.swift")}\uFF09\uFF1A\u8BF7\u7528 adep app init --platform mobile --toolchain xtool \u751F\u6210`
|
|
33594
34095
|
);
|
|
33595
34096
|
}
|
|
33596
|
-
if (!await pathExists(
|
|
34097
|
+
if (!await pathExists(join20(shellDir, "plugins", "adep-bridge", "Package.swift"))) {
|
|
33597
34098
|
throw new InitError(
|
|
33598
34099
|
"APP_SHELL_DEPS_MISSING",
|
|
33599
|
-
`xtool \u58F3\u7F3A\u5C11\u539F\u751F\u6865\u63D2\u4EF6\u6E90\u7801\uFF08${
|
|
34100
|
+
`xtool \u58F3\u7F3A\u5C11\u539F\u751F\u6865\u63D2\u4EF6\u6E90\u7801\uFF08${join20(shellDir, "plugins", "adep-bridge", "Package.swift")}\uFF09\uFF1A\u58F3\u7684 Package.swift \u4EE5 .package(path:) \u786C\u4F9D\u8D56\u5B83\uFF0C\u7F3A\u5931\u65F6**\u89E3\u6790\u6E05\u5355\u5373\u5931\u8D25**\uFF08\u4E0D\u662F\u8FD0\u884C\u671F\u5C11\u4E2A\u529F\u80FD\uFF09\u3002\u8BF7\u91CD\u65B0 adep app init --platform mobile --toolchain xtool\uFF0C\u6216\u624B\u5DE5\u8865\u8BE5\u76EE\u5F55`
|
|
33600
34101
|
);
|
|
33601
34102
|
}
|
|
33602
34103
|
}
|
|
@@ -33623,8 +34124,8 @@ function probeCommand(command, args) {
|
|
|
33623
34124
|
});
|
|
33624
34125
|
}
|
|
33625
34126
|
function xcodebuildArgs(shellDir, outDir) {
|
|
33626
|
-
const appDir =
|
|
33627
|
-
const project2 =
|
|
34127
|
+
const appDir = join20(shellDir, "ios", "App");
|
|
34128
|
+
const project2 = join20(appDir, "App.xcodeproj");
|
|
33628
34129
|
const args = [
|
|
33629
34130
|
// 有 workspace(pod install 后)用 workspace;否则退到 xcodeproj(无插件的最小工程)。
|
|
33630
34131
|
"-project",
|
|
@@ -33635,7 +34136,7 @@ function xcodebuildArgs(shellDir, outDir) {
|
|
|
33635
34136
|
"Release",
|
|
33636
34137
|
"archive",
|
|
33637
34138
|
"-archivePath",
|
|
33638
|
-
|
|
34139
|
+
join20(outDir, `${basename2(shellDir)}.xcarchive`),
|
|
33639
34140
|
// unsigned:平台不出具任何签名(PRD §2.11.6「平台不出具签名」)。
|
|
33640
34141
|
// 显式 CODE_SIGNING_ALLOWED=NO——不带任何签名身份(CODE_SIGN_IDENTITY / PROVISIONING_PROFILE)。
|
|
33641
34142
|
"CODE_SIGNING_ALLOWED=NO",
|
|
@@ -33644,8 +34145,8 @@ function xcodebuildArgs(shellDir, outDir) {
|
|
|
33644
34145
|
return args;
|
|
33645
34146
|
}
|
|
33646
34147
|
async function runXcodebuild(input2) {
|
|
33647
|
-
const workspace =
|
|
33648
|
-
const project2 =
|
|
34148
|
+
const workspace = join20(input2.shellDir, "ios", "App", "App.xcworkspace");
|
|
34149
|
+
const project2 = join20(input2.shellDir, "ios", "App", "App.xcodeproj");
|
|
33649
34150
|
if (!await pathExists(workspace) && !await pathExists(project2)) {
|
|
33650
34151
|
throw missingMobileDepsError(input2.shellDir, "ios");
|
|
33651
34152
|
}
|
|
@@ -33662,7 +34163,7 @@ async function assertUnsignedIosArchive(archivePath) {
|
|
|
33662
34163
|
if (!await pathExists(archivePath)) {
|
|
33663
34164
|
throw new InitError("APP_ARCHIVE_INCOMPLETE", `iOS archive \u4E0D\u5B58\u5728\uFF1A${archivePath}`);
|
|
33664
34165
|
}
|
|
33665
|
-
const applicationsDir =
|
|
34166
|
+
const applicationsDir = join20(archivePath, "Products", "Applications");
|
|
33666
34167
|
let hasAppBundle = false;
|
|
33667
34168
|
try {
|
|
33668
34169
|
const entries = await readdir6(applicationsDir, { withFileTypes: true });
|
|
@@ -33692,7 +34193,7 @@ async function assertUnsignedIosArchive(archivePath) {
|
|
|
33692
34193
|
continue;
|
|
33693
34194
|
}
|
|
33694
34195
|
if (entry.isDirectory()) {
|
|
33695
|
-
await walk(
|
|
34196
|
+
await walk(join20(dir, entry.name), childRel, depth + 1);
|
|
33696
34197
|
}
|
|
33697
34198
|
}
|
|
33698
34199
|
};
|
|
@@ -33705,10 +34206,10 @@ async function assertUnsignedIosArchive(archivePath) {
|
|
|
33705
34206
|
}
|
|
33706
34207
|
}
|
|
33707
34208
|
function resolveGradlew(shellDir) {
|
|
33708
|
-
return process.platform === "win32" ?
|
|
34209
|
+
return process.platform === "win32" ? join20(shellDir, "android", "gradlew.bat") : join20(shellDir, "android", "gradlew");
|
|
33709
34210
|
}
|
|
33710
34211
|
async function copyGradleApkToOutDir(shellDir, outDir) {
|
|
33711
|
-
const outputsRoot =
|
|
34212
|
+
const outputsRoot = join20(shellDir, "android", "app", "build", "outputs", "apk");
|
|
33712
34213
|
const copied = [];
|
|
33713
34214
|
const walk = async (dir, depth) => {
|
|
33714
34215
|
if (depth > 2) return;
|
|
@@ -33719,9 +34220,9 @@ async function copyGradleApkToOutDir(shellDir, outDir) {
|
|
|
33719
34220
|
return;
|
|
33720
34221
|
}
|
|
33721
34222
|
for (const entry of entries) {
|
|
33722
|
-
const full =
|
|
34223
|
+
const full = join20(dir, entry.name);
|
|
33723
34224
|
if (entry.isFile() && entry.name.endsWith(".apk")) {
|
|
33724
|
-
await
|
|
34225
|
+
await copyFile2(full, join20(outDir, entry.name));
|
|
33725
34226
|
copied.push(entry.name);
|
|
33726
34227
|
continue;
|
|
33727
34228
|
}
|
|
@@ -33737,7 +34238,7 @@ async function runGradle(input2) {
|
|
|
33737
34238
|
const gradlew = resolveGradlew(input2.shellDir);
|
|
33738
34239
|
if (!await pathExists(gradlew)) throw missingMobileDepsError(input2.shellDir, "android");
|
|
33739
34240
|
if (process.platform === "win32") {
|
|
33740
|
-
await spawnChild(
|
|
34241
|
+
await spawnChild(join20(input2.shellDir, "android"), "cmd.exe", [
|
|
33741
34242
|
"/d",
|
|
33742
34243
|
"/s",
|
|
33743
34244
|
"/c",
|
|
@@ -33745,14 +34246,14 @@ async function runGradle(input2) {
|
|
|
33745
34246
|
"assembleRelease"
|
|
33746
34247
|
]);
|
|
33747
34248
|
} else {
|
|
33748
|
-
await spawnChild(
|
|
34249
|
+
await spawnChild(join20(input2.shellDir, "android"), gradlew, ["assembleRelease"]);
|
|
33749
34250
|
}
|
|
33750
|
-
await
|
|
34251
|
+
await mkdir10(input2.outDir, { recursive: true });
|
|
33751
34252
|
const copied = await copyGradleApkToOutDir(input2.shellDir, input2.outDir);
|
|
33752
34253
|
if (copied.length === 0) {
|
|
33753
34254
|
throw new InitError(
|
|
33754
34255
|
"APP_ARTIFACT_MISSING",
|
|
33755
|
-
`gradle \u5DF2\u6210\u529F\u4F46 ${
|
|
34256
|
+
`gradle \u5DF2\u6210\u529F\u4F46 ${join20(input2.shellDir, "android", "app", "build", "outputs", "apk")} \u4E0B\u6CA1\u6709 .apk\uFF1AassembleRelease \u53EF\u80FD\u88AB\u964D\u7EA7\u6210\u522B\u7684\u53D8\u4F53\uFF0C\u8BF7\u68C0\u67E5 android \u5DE5\u7A0B\u7684\u6784\u5EFA\u53D8\u4F53\u914D\u7F6E`
|
|
33756
34257
|
);
|
|
33757
34258
|
}
|
|
33758
34259
|
}
|
|
@@ -33818,6 +34319,10 @@ async function runElectronBuilder(input2) {
|
|
|
33818
34319
|
}
|
|
33819
34320
|
await spawnChild(input2.shellDir, binary, args, void 0, env);
|
|
33820
34321
|
}
|
|
34322
|
+
|
|
34323
|
+
// packages/cli/src/app-build/artifacts.ts
|
|
34324
|
+
import { readFile as readFile15, readdir as readdir7 } from "node:fs/promises";
|
|
34325
|
+
import { join as join21, relative as relative2 } from "node:path";
|
|
33821
34326
|
function isArtifact(name, isDirectory, platform, toolchain) {
|
|
33822
34327
|
if (toolchain === "xtool") return !isDirectory && name.endsWith(".ipa");
|
|
33823
34328
|
if (platform === "ios") return isDirectory && name.endsWith(".xcarchive");
|
|
@@ -33830,17 +34335,17 @@ function isArtifact(name, isDirectory, platform, toolchain) {
|
|
|
33830
34335
|
}
|
|
33831
34336
|
async function findArtifacts(shellDir, outDir, platform, toolchain = "capacitor") {
|
|
33832
34337
|
const found = [];
|
|
33833
|
-
const scanRoot = toolchain === "xtool" ?
|
|
34338
|
+
const scanRoot = toolchain === "xtool" ? join21(shellDir, XTOOL_ARTIFACT_DIR) : outDir;
|
|
33834
34339
|
const walk = async (dir, depth) => {
|
|
33835
34340
|
if (depth > 3) return;
|
|
33836
34341
|
let entries;
|
|
33837
34342
|
try {
|
|
33838
|
-
entries = await
|
|
34343
|
+
entries = await readdir7(dir, { withFileTypes: true });
|
|
33839
34344
|
} catch {
|
|
33840
34345
|
return;
|
|
33841
34346
|
}
|
|
33842
34347
|
for (const entry of entries) {
|
|
33843
|
-
const full =
|
|
34348
|
+
const full = join21(dir, entry.name);
|
|
33844
34349
|
if (isArtifact(entry.name, entry.isDirectory(), platform, toolchain)) {
|
|
33845
34350
|
found.push(relative2(shellDir, full).split(/[\\/]/u).join("/"));
|
|
33846
34351
|
continue;
|
|
@@ -33891,7 +34396,7 @@ function linuxTargetSkips(declared, artifacts) {
|
|
|
33891
34396
|
}
|
|
33892
34397
|
async function readLinuxDeclaredTargets(shellDir) {
|
|
33893
34398
|
try {
|
|
33894
|
-
const raw = await
|
|
34399
|
+
const raw = await readFile15(join21(shellDir, "package.json"), "utf8");
|
|
33895
34400
|
const parsed = JSON.parse(raw);
|
|
33896
34401
|
const target = parsed.build?.linux?.target;
|
|
33897
34402
|
if (typeof target === "string") return [target];
|
|
@@ -33902,69 +34407,8 @@ async function readLinuxDeclaredTargets(shellDir) {
|
|
|
33902
34407
|
return [];
|
|
33903
34408
|
}
|
|
33904
34409
|
}
|
|
33905
|
-
|
|
33906
|
-
|
|
33907
|
-
try {
|
|
33908
|
-
const zipPath = join16(workDir, "bundle.zip");
|
|
33909
|
-
await input2.api.downloadBundle(input2.jobId, zipPath);
|
|
33910
|
-
const entries = zipRead(await readFile12(zipPath));
|
|
33911
|
-
const manifest = readManifest(entries);
|
|
33912
|
-
verifySiteContents(manifest, entries);
|
|
33913
|
-
const site = collectSiteEntries(entries);
|
|
33914
|
-
if (site.size === 0) {
|
|
33915
|
-
throw new InitError(
|
|
33916
|
-
"APP_NO_PUBLISHED_FRONTEND",
|
|
33917
|
-
`\u9879\u76EE "${input2.projectSlug}" \u6CA1\u6709\u5DF2\u53D1\u5E03\u7684\u9875\u9762\u4EA7\u7269\uFF08\u5BFC\u51FA\u5305\u5185\u6CA1\u6709 ${SITE_PREFIX}\uFF09\uFF1A\u8BF7\u5148\u6267\u884C adep publish --only frontend --project ${input2.projectSlug}`
|
|
33918
|
-
);
|
|
33919
|
-
}
|
|
33920
|
-
return { manifest, written: await writeSiteTree(input2.shellDir, site) };
|
|
33921
|
-
} finally {
|
|
33922
|
-
await rm3(workDir, { recursive: true, force: true });
|
|
33923
|
-
}
|
|
33924
|
-
}
|
|
33925
|
-
async function readEntryPage(indexPath) {
|
|
33926
|
-
try {
|
|
33927
|
-
return await readFile12(indexPath, "utf8");
|
|
33928
|
-
} catch (error62) {
|
|
33929
|
-
const code = typeof error62 === "object" && error62 !== null ? error62.code : void 0;
|
|
33930
|
-
if (code === "ENOENT") {
|
|
33931
|
-
throw new InitError(
|
|
33932
|
-
"APP_SITE_MISSING",
|
|
33933
|
-
`\u7AD9\u70B9\u4EA7\u7269\u7F3A\u5165\u53E3\u9875\uFF1A${indexPath} \u4E0D\u5B58\u5728\u3002\u79FB\u52A8\u58F3\u7684 WebView \u6052\u52A0\u8F7D index.html\uFF0C\u7F3A\u4E86\u88C5\u673A\u5C31\u662F\u767D\u5C4F\u2014\u2014\u8BF7\u786E\u8BA4\u7AD9\u70B9\u5DF2\u53D1\u5E03\u4E14\u5165\u53E3\u9875\u662F**\u6839\u7EA7** index.html\uFF08\`adep publish --only frontend\`\uFF09\uFF0C\u518D\u91CD\u8DD1 adep app build`
|
|
33934
|
-
);
|
|
33935
|
-
}
|
|
33936
|
-
throw new InitError(
|
|
33937
|
-
"APP_SITE_UNREADABLE",
|
|
33938
|
-
`\u7AD9\u70B9\u5165\u53E3\u9875\u8BFB\u4E0D\u51FA\u6765\uFF1A${indexPath}\uFF08${error62 instanceof Error ? error62.message : String(error62)}\uFF09`
|
|
33939
|
-
);
|
|
33940
|
-
}
|
|
33941
|
-
}
|
|
33942
|
-
async function injectMobileShellAssets(input2) {
|
|
33943
|
-
const siteRoot = join16(input2.shellDir, SHELL_SITE_DIR);
|
|
33944
|
-
const indexPath = join16(siteRoot, "index.html");
|
|
33945
|
-
const html = await readEntryPage(indexPath);
|
|
33946
|
-
const permissionsJson = `${JSON.stringify(
|
|
33947
|
-
{ schemaVersion: 1, permissions: sortPermissions(input2.permissions) },
|
|
33948
|
-
null,
|
|
33949
|
-
2
|
|
33950
|
-
)}
|
|
33951
|
-
`;
|
|
33952
|
-
await writeFile8(join16(siteRoot, MOBILE_SITE_ASSET_FILES.permissions), permissionsJson);
|
|
33953
|
-
await copyFile(
|
|
33954
|
-
join16(input2.shellDir, "web", "adep-bridge.js"),
|
|
33955
|
-
join16(siteRoot, MOBILE_SITE_ASSET_FILES.bridge)
|
|
33956
|
-
);
|
|
33957
|
-
await copyFile(
|
|
33958
|
-
join16(input2.shellDir, "adep.app.json"),
|
|
33959
|
-
join16(siteRoot, MOBILE_SITE_ASSET_FILES.config)
|
|
33960
|
-
);
|
|
33961
|
-
if (html.includes("adep-bridge.js")) return;
|
|
33962
|
-
const tag = '<script src="/adep-bridge.js"></script>';
|
|
33963
|
-
const next = html.includes("</head>") ? html.replace("</head>", `${tag}
|
|
33964
|
-
</head>`) : `${tag}
|
|
33965
|
-
${html}`;
|
|
33966
|
-
await writeFile8(indexPath, next);
|
|
33967
|
-
}
|
|
34410
|
+
|
|
34411
|
+
// packages/cli/src/app-build.ts
|
|
33968
34412
|
async function buildDesktopApp(options, deps) {
|
|
33969
34413
|
const shellDir = resolve8(options.dir);
|
|
33970
34414
|
const platform = normalizePlatform(options.platform);
|
|
@@ -33972,7 +34416,7 @@ async function buildDesktopApp(options, deps) {
|
|
|
33972
34416
|
const toolchain = normalizeToolchain(options.toolchain);
|
|
33973
34417
|
const prepareOnly = options.prepareOnly === true;
|
|
33974
34418
|
const now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
33975
|
-
const outDir =
|
|
34419
|
+
const outDir = join22(shellDir, SHELL_OUT_DIR);
|
|
33976
34420
|
if (isMobilePlatform(platform) && target === "dir") {
|
|
33977
34421
|
throw new InitError(
|
|
33978
34422
|
"INVALID_TARGET",
|
|
@@ -34033,7 +34477,7 @@ async function buildDesktopApp(options, deps) {
|
|
|
34033
34477
|
if (toolchain === "capacitor" && (platform === "ios" || platform === "android")) {
|
|
34034
34478
|
await (deps.runCapSync ?? syncCapacitorAssets)({ shellDir, platform });
|
|
34035
34479
|
}
|
|
34036
|
-
await
|
|
34480
|
+
await mkdir11(outDir, { recursive: true });
|
|
34037
34481
|
await (deps.runPackager ?? runPlatformPackager)({
|
|
34038
34482
|
shellDir,
|
|
34039
34483
|
platform,
|
|
@@ -34044,7 +34488,7 @@ async function buildDesktopApp(options, deps) {
|
|
|
34044
34488
|
});
|
|
34045
34489
|
artifacts = await findArtifacts(shellDir, outDir, platform, toolchain);
|
|
34046
34490
|
if (artifacts.length === 0) {
|
|
34047
|
-
const scanned = toolchain === "xtool" ?
|
|
34491
|
+
const scanned = toolchain === "xtool" ? join22(shellDir, XTOOL_ARTIFACT_DIR) : outDir;
|
|
34048
34492
|
const hint = toolchain === "xtool" ? "`xtool dev build --ipa` \u7684\u4EA7\u7269\u5E94\u5728 xtool/<product>.ipa\uFF08\u65E0\u8F93\u51FA\u4F4D\u53C2\u6570\uFF09\uFF1B\u8BF7\u68C0\u67E5 xtool \u662F\u5426\u771F\u7684\u8DD1\u5230\u4E86\u6253\u5305\uFF08\u800C\u4E0D\u662F\u5728\u7F16\u8BD1\u9636\u6BB5\u9000\u51FA\uFF09" : "\u8BF7\u68C0\u67E5\u58F3\u5DE5\u7A0B\u7684\u539F\u751F\u5DE5\u7A0B / build \u914D\u7F6E";
|
|
34049
34493
|
throw new InitError(
|
|
34050
34494
|
"APP_ARTIFACT_MISSING",
|
|
@@ -34053,7 +34497,7 @@ async function buildDesktopApp(options, deps) {
|
|
|
34053
34497
|
}
|
|
34054
34498
|
if (platform === "ios" && toolchain === "capacitor") {
|
|
34055
34499
|
for (const artifact of artifacts) {
|
|
34056
|
-
await assertUnsignedIosArchive(
|
|
34500
|
+
await assertUnsignedIosArchive(join22(shellDir, artifact));
|
|
34057
34501
|
}
|
|
34058
34502
|
}
|
|
34059
34503
|
if (platform === "linux" && target === "installer") {
|
|
@@ -34086,9 +34530,9 @@ async function buildDesktopApp(options, deps) {
|
|
|
34086
34530
|
artifacts,
|
|
34087
34531
|
warnings
|
|
34088
34532
|
};
|
|
34089
|
-
await
|
|
34090
|
-
const reportPath =
|
|
34091
|
-
await
|
|
34533
|
+
await mkdir11(outDir, { recursive: true });
|
|
34534
|
+
const reportPath = join22(outDir, REPORT_FILE);
|
|
34535
|
+
await writeFile12(reportPath, `${JSON.stringify(report, null, 2)}
|
|
34092
34536
|
`);
|
|
34093
34537
|
return {
|
|
34094
34538
|
appPath: shellDir,
|
|
@@ -34132,17 +34576,17 @@ async function createAppBuildApi(paths, cwd) {
|
|
|
34132
34576
|
}
|
|
34133
34577
|
|
|
34134
34578
|
// packages/cli/src/app-doctor.ts
|
|
34135
|
-
import { readFile as
|
|
34136
|
-
import { join as
|
|
34579
|
+
import { readFile as readFile17, stat as stat9 } from "node:fs/promises";
|
|
34580
|
+
import { join as join24 } from "node:path";
|
|
34137
34581
|
|
|
34138
34582
|
// packages/cli/src/app-offline-build.ts
|
|
34139
34583
|
init_zip();
|
|
34140
34584
|
init_auth();
|
|
34141
34585
|
import { createHash as createHash3 } from "node:crypto";
|
|
34142
|
-
import { access, copyFile as
|
|
34586
|
+
import { access, copyFile as copyFile3, mkdir as mkdir12, mkdtemp as mkdtemp2, readFile as readFile16, rm as rm4, writeFile as writeFile13 } from "node:fs/promises";
|
|
34143
34587
|
import { spawn as spawn3 } from "node:child_process";
|
|
34144
34588
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
34145
|
-
import { dirname as
|
|
34589
|
+
import { dirname as dirname10, join as join23, posix as posix2, resolve as resolve9 } from "node:path";
|
|
34146
34590
|
init_client();
|
|
34147
34591
|
var SHELL_OFFLINE_DIR = "app/offline";
|
|
34148
34592
|
var SHELL_SITE_OFFLINE_DIR = "app/site/offline";
|
|
@@ -34184,15 +34628,15 @@ function collectOfflineEntries(entries) {
|
|
|
34184
34628
|
return collected;
|
|
34185
34629
|
}
|
|
34186
34630
|
async function writeOfflineTree(shellDir, collected, targetRel) {
|
|
34187
|
-
const targetRoot =
|
|
34631
|
+
const targetRoot = join23(shellDir, targetRel);
|
|
34188
34632
|
await rm4(targetRoot, { recursive: true, force: true });
|
|
34189
|
-
await
|
|
34633
|
+
await mkdir12(targetRoot, { recursive: true });
|
|
34190
34634
|
const written = [];
|
|
34191
34635
|
for (const [rel, bytes] of collected) {
|
|
34192
34636
|
if (rel.length === 0 || rel.endsWith("/")) continue;
|
|
34193
|
-
const dest =
|
|
34194
|
-
await
|
|
34195
|
-
await
|
|
34637
|
+
const dest = join23(targetRoot, ...rel.split("/"));
|
|
34638
|
+
await mkdir12(dirname10(dest), { recursive: true });
|
|
34639
|
+
await writeFile13(dest, bytes);
|
|
34196
34640
|
written.push({ path: `${targetRel}/${rel}`, size: bytes.length });
|
|
34197
34641
|
}
|
|
34198
34642
|
return written;
|
|
@@ -34286,14 +34730,14 @@ async function buildOfflineApp(options, deps) {
|
|
|
34286
34730
|
);
|
|
34287
34731
|
}
|
|
34288
34732
|
if (mobileOffline) {
|
|
34289
|
-
const entry =
|
|
34733
|
+
const entry = join23(shellDir, "app", "site", "index.html");
|
|
34290
34734
|
if (!await fileExists(entry)) {
|
|
34291
34735
|
throw new InitError(
|
|
34292
34736
|
"APP_SITE_MISSING",
|
|
34293
34737
|
`\u79BB\u7EBF\u5305\u7F3A\u9875\u9762\u4EA7\u7269\uFF1A${entry} \u4E0D\u5B58\u5728\u3002\u8BF7\u5148\u6267\u884C ` + (toolchain === "xtool" ? "`adep app build --platform ios --toolchain xtool`\uFF08\u62C9\u53D6\u9875\u9762\u4EA7\u7269\u5E76\u6CE8\u5165\u9875\u9762\u6865 / \u58F3\u914D\u7F6E\uFF09\uFF0C" : "`adep app build --platform android`\uFF08\u62C9\u53D6\u9875\u9762\u4EA7\u7269\u5E76\u6CE8\u5165\u9875\u9762\u6865 / \u58F3\u914D\u7F6E\uFF09\uFF0C") + "\u518D\u6267\u884C\u79BB\u7EBF\u6784\u5EFA\u2014\u2014\u79BB\u7EBF\u6784\u5EFA\u53EA\u8FFD\u52A0 site/offline/ \u5B50\u6811\uFF0C\u4E0D\u4EA7\u751F\u9875\u9762\u672C\u4F53"
|
|
34294
34738
|
);
|
|
34295
34739
|
}
|
|
34296
|
-
const loaderSource =
|
|
34740
|
+
const loaderSource = join23(shellDir, MOBILE_OFFLINE_LOADER.source);
|
|
34297
34741
|
if (!await fileExists(loaderSource)) {
|
|
34298
34742
|
throw new InitError(
|
|
34299
34743
|
"OFFLINE_LOADER_MISSING",
|
|
@@ -34318,11 +34762,11 @@ ${finished.error ?? "\u670D\u52A1\u7AEF\u672A\u63D0\u4F9B\u539F\u56E0"}
|
|
|
34318
34762
|
\uFF08\u8FD9\u4E9B\u51FD\u6570\u4E0D\u53EF\u79FB\u690D\u5230\u8BBE\u5907\u7AEF\uFF1B\u4ECE\u6253\u5305\u914D\u7F6E\u7684\u79BB\u7EBF\u767D\u540D\u5355\u79FB\u9664\u540E\u91CD\u65B0\u4FDD\u5B58\uFF0C\u5373\u53EF\u7EE7\u7EED\u6784\u5EFA\uFF09`
|
|
34319
34763
|
);
|
|
34320
34764
|
}
|
|
34321
|
-
const workDir = await mkdtemp2(
|
|
34765
|
+
const workDir = await mkdtemp2(join23(tmpdir2(), "adep-app-offline-build-"));
|
|
34322
34766
|
try {
|
|
34323
|
-
const bundlePath =
|
|
34767
|
+
const bundlePath = join23(workDir, "bundle.adepack");
|
|
34324
34768
|
await deps.api.downloadBundle(project2.id, finished.id, bundlePath);
|
|
34325
|
-
const entries = zipRead(await
|
|
34769
|
+
const entries = zipRead(await readFile16(bundlePath));
|
|
34326
34770
|
const manifest = readManifest(entries, { allowOfflinePortZero: true });
|
|
34327
34771
|
const collected = collectOfflineEntries(entries);
|
|
34328
34772
|
const functionEntries = readFunctionsIndex(collected);
|
|
@@ -34331,9 +34775,9 @@ ${finished.error ?? "\u670D\u52A1\u7AEF\u672A\u63D0\u4F9B\u539F\u56E0"}
|
|
|
34331
34775
|
if (mobileOffline) {
|
|
34332
34776
|
const permissions = sortPermissions(await deps.api.getPackagingPermissions(project2.id));
|
|
34333
34777
|
await injectMobileShellAssets({ shellDir, permissions });
|
|
34334
|
-
await
|
|
34335
|
-
|
|
34336
|
-
|
|
34778
|
+
await copyFile3(
|
|
34779
|
+
join23(shellDir, MOBILE_OFFLINE_LOADER.source),
|
|
34780
|
+
join23(shellDir, MOBILE_OFFLINE_LOADER.dest)
|
|
34337
34781
|
);
|
|
34338
34782
|
}
|
|
34339
34783
|
const builtAt = now().toISOString();
|
|
@@ -34349,13 +34793,13 @@ ${finished.error ?? "\u670D\u52A1\u7AEF\u672A\u63D0\u4F9B\u539F\u56E0"}
|
|
|
34349
34793
|
platform: "ios",
|
|
34350
34794
|
target: "installer",
|
|
34351
34795
|
toolchain: "xtool",
|
|
34352
|
-
outDir:
|
|
34796
|
+
outDir: join23(shellDir, "dist")
|
|
34353
34797
|
});
|
|
34354
|
-
artifacts = await findArtifacts(shellDir,
|
|
34798
|
+
artifacts = await findArtifacts(shellDir, join23(shellDir, "dist"), "ios", "xtool");
|
|
34355
34799
|
} else if (androidOffline) {
|
|
34356
34800
|
await (deps.runCapSync ?? syncCapacitorAssets)({ shellDir, platform: "android" });
|
|
34357
|
-
const outDir2 =
|
|
34358
|
-
await
|
|
34801
|
+
const outDir2 = join23(shellDir, "dist");
|
|
34802
|
+
await mkdir12(outDir2, { recursive: true });
|
|
34359
34803
|
await runner({
|
|
34360
34804
|
shellDir,
|
|
34361
34805
|
platform: "android",
|
|
@@ -34366,8 +34810,8 @@ ${finished.error ?? "\u670D\u52A1\u7AEF\u672A\u63D0\u4F9B\u539F\u56E0"}
|
|
|
34366
34810
|
artifacts = await findArtifacts(shellDir, outDir2, "android");
|
|
34367
34811
|
} else {
|
|
34368
34812
|
const platform = resolveOfflinePlatform();
|
|
34369
|
-
const outDir2 =
|
|
34370
|
-
await
|
|
34813
|
+
const outDir2 = join23(shellDir, "dist");
|
|
34814
|
+
await mkdir12(outDir2, { recursive: true });
|
|
34371
34815
|
await runner({
|
|
34372
34816
|
shellDir,
|
|
34373
34817
|
platform,
|
|
@@ -34380,7 +34824,7 @@ ${finished.error ?? "\u670D\u52A1\u7AEF\u672A\u63D0\u4F9B\u539F\u56E0"}
|
|
|
34380
34824
|
if (artifacts.length === 0) {
|
|
34381
34825
|
throw new InitError(
|
|
34382
34826
|
"APP_ARTIFACT_MISSING",
|
|
34383
|
-
toolchain === "xtool" ? `\u6253\u5305\u5668\u5DF2\u6267\u884C\u4F46 ${
|
|
34827
|
+
toolchain === "xtool" ? `\u6253\u5305\u5668\u5DF2\u6267\u884C\u4F46 ${join23(shellDir, "xtool")} \u4E0B\u6CA1\u6709 ios \u4EA7\u7269\uFF1A\`xtool dev build --ipa\` \u7684\u4EA7\u7269\u5E94\u5728 xtool/<product>.ipa\uFF08\u65E0\u8F93\u51FA\u4F4D\u53C2\u6570\uFF09\uFF1B\u8BF7\u68C0\u67E5 xtool \u662F\u5426\u771F\u7684\u8DD1\u5230\u4E86\u6253\u5305\uFF08\u800C\u4E0D\u662F\u5728\u7F16\u8BD1\u9636\u6BB5\u9000\u51FA\uFF09` : androidOffline ? `\u6253\u5305\u5668\u5DF2\u6267\u884C\u4F46 ${join23(shellDir, "dist")} \u4E0B\u6CA1\u6709 android \u4EA7\u7269\uFF1Agradle assembleRelease \u7684 APK \u5E94\u5DF2\u88AB\u590D\u5236\u8FDB dist/\uFF08\u89C1 copyGradleApkToOutDir\uFF09\uFF1B\u8BF7\u68C0\u67E5 android \u5DE5\u7A0B\u7684\u6784\u5EFA\u53D8\u4F53\u914D\u7F6E` : `electron-builder \u5DF2\u6267\u884C\u4F46 ${join23(shellDir, "dist")} \u4E0B\u6CA1\u6709\u4EA7\u7269\uFF1A\u8BF7\u68C0\u67E5\u58F3\u5DE5\u7A0B build \u914D\u7F6E\u7684 target`
|
|
34384
34828
|
);
|
|
34385
34829
|
}
|
|
34386
34830
|
}
|
|
@@ -34408,10 +34852,10 @@ ${finished.error ?? "\u670D\u52A1\u7AEF\u672A\u63D0\u4F9B\u539F\u56E0"}
|
|
|
34408
34852
|
},
|
|
34409
34853
|
artifacts
|
|
34410
34854
|
};
|
|
34411
|
-
const outDir =
|
|
34412
|
-
await
|
|
34413
|
-
const reportPath =
|
|
34414
|
-
await
|
|
34855
|
+
const outDir = join23(shellDir, "dist");
|
|
34856
|
+
await mkdir12(outDir, { recursive: true });
|
|
34857
|
+
const reportPath = join23(outDir, "build-report.json");
|
|
34858
|
+
await writeFile13(reportPath, `${JSON.stringify(report, null, 2)}
|
|
34415
34859
|
`);
|
|
34416
34860
|
return {
|
|
34417
34861
|
appPath: shellDir,
|
|
@@ -34472,7 +34916,7 @@ async function createAppOfflineBuildApi(paths, cwd) {
|
|
|
34472
34916
|
}
|
|
34473
34917
|
const response = await client.download(downloadUrl, "APP_OFFLINE_BUILD_DOWNLOAD_FAILED");
|
|
34474
34918
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
34475
|
-
await
|
|
34919
|
+
await writeFile13(outputPath, bytes);
|
|
34476
34920
|
return { path: outputPath, size: bytes.length };
|
|
34477
34921
|
},
|
|
34478
34922
|
// 与在线构建 `AppBuildDeps.getPackagingPermissions` 同一端点同一读法(app-build.ts 同款)。
|
|
@@ -34510,7 +34954,7 @@ async function pathExists2(path) {
|
|
|
34510
34954
|
}
|
|
34511
34955
|
async function missingEntries(root, rels) {
|
|
34512
34956
|
const probed = await Promise.all(
|
|
34513
|
-
rels.map(async (rel) => ({ rel, exists: await pathExists2(
|
|
34957
|
+
rels.map(async (rel) => ({ rel, exists: await pathExists2(join24(root, ...rel.split("/"))) }))
|
|
34514
34958
|
);
|
|
34515
34959
|
return probed.filter((entry) => !entry.exists).map((entry) => entry.rel);
|
|
34516
34960
|
}
|
|
@@ -34524,10 +34968,10 @@ async function resolveTargets(shellDir, template, platform) {
|
|
|
34524
34968
|
if (template === "app-mobile-xtool") return [{ platform: "ios", toolchain: "xtool" }];
|
|
34525
34969
|
if (template === "app-mobile") {
|
|
34526
34970
|
const targets = [];
|
|
34527
|
-
if (await pathExists2(
|
|
34971
|
+
if (await pathExists2(join24(shellDir, "ios", "App"))) {
|
|
34528
34972
|
targets.push({ platform: "ios", toolchain: "capacitor" });
|
|
34529
34973
|
}
|
|
34530
|
-
if (await pathExists2(
|
|
34974
|
+
if (await pathExists2(join24(shellDir, "android", "gradlew"))) {
|
|
34531
34975
|
targets.push({ platform: "android", toolchain: "capacitor" });
|
|
34532
34976
|
}
|
|
34533
34977
|
return targets;
|
|
@@ -34535,10 +34979,10 @@ async function resolveTargets(shellDir, template, platform) {
|
|
|
34535
34979
|
return [];
|
|
34536
34980
|
}
|
|
34537
34981
|
async function checkConfigDrift(shellDir, config2) {
|
|
34538
|
-
const siteConfigPath =
|
|
34982
|
+
const siteConfigPath = join24(shellDir, SHELL_SITE_DIR, MOBILE_SITE_ASSET_FILES.config);
|
|
34539
34983
|
let text;
|
|
34540
34984
|
try {
|
|
34541
|
-
text = await
|
|
34985
|
+
text = await readFile17(siteConfigPath, "utf8");
|
|
34542
34986
|
} catch {
|
|
34543
34987
|
return {
|
|
34544
34988
|
id: "configDrift",
|
|
@@ -34579,8 +35023,8 @@ async function checkConfigDrift(shellDir, config2) {
|
|
|
34579
35023
|
};
|
|
34580
35024
|
}
|
|
34581
35025
|
async function checkOffline(shellDir) {
|
|
34582
|
-
const desktopRoot =
|
|
34583
|
-
const siteRoot =
|
|
35026
|
+
const desktopRoot = join24(shellDir, SHELL_OFFLINE_DIR);
|
|
35027
|
+
const siteRoot = join24(shellDir, SHELL_SITE_OFFLINE_DIR);
|
|
34584
35028
|
const hasDesktop = await pathExists2(desktopRoot);
|
|
34585
35029
|
const hasSite = await pathExists2(siteRoot);
|
|
34586
35030
|
if (!hasDesktop && !hasSite) {
|
|
@@ -34613,7 +35057,7 @@ async function checkOffline(shellDir) {
|
|
|
34613
35057
|
let functions = [];
|
|
34614
35058
|
try {
|
|
34615
35059
|
const index = JSON.parse(
|
|
34616
|
-
await
|
|
35060
|
+
await readFile17(join24(root, ...OFFLINE_BUNDLE_PATHS.functionsIndex.split("/")), "utf8")
|
|
34617
35061
|
);
|
|
34618
35062
|
functions = index.functions ?? [];
|
|
34619
35063
|
} catch (error62) {
|
|
@@ -34626,7 +35070,7 @@ async function checkOffline(shellDir) {
|
|
|
34626
35070
|
};
|
|
34627
35071
|
}
|
|
34628
35072
|
const missingSources = (await missingEntries(
|
|
34629
|
-
|
|
35073
|
+
join24(root, "functions"),
|
|
34630
35074
|
functions.map((entry) => typeof entry.name === "string" ? entry.name : "").filter((name) => name !== "").map((name) => `${name}.mjs`)
|
|
34631
35075
|
)).map((rel) => rel.slice(0, -".mjs".length));
|
|
34632
35076
|
if (missingSources.length > 0) {
|
|
@@ -34654,10 +35098,10 @@ async function checkIdentity(shellDir, desktopShaped) {
|
|
|
34654
35098
|
detail: "\u79FB\u52A8\u58F3\u5F62\u6001\uFF1A\u8EAB\u4EFD\u5728 Keychain / Keystore\uFF08\u672C\u9879\u53EA\u8BFB\u684C\u9762\u58F3\u7684\u72B6\u6001\u6587\u4EF6\uFF09"
|
|
34655
35099
|
};
|
|
34656
35100
|
}
|
|
34657
|
-
const file2 =
|
|
35101
|
+
const file2 = join24(shellDir, IDENTITY_STATUS_REL);
|
|
34658
35102
|
let text;
|
|
34659
35103
|
try {
|
|
34660
|
-
text = await
|
|
35104
|
+
text = await readFile17(file2, "utf8");
|
|
34661
35105
|
} catch {
|
|
34662
35106
|
return {
|
|
34663
35107
|
id: "identity",
|
|
@@ -34792,7 +35236,7 @@ async function runShellDoctor(shellDir, deps = {}) {
|
|
|
34792
35236
|
}
|
|
34793
35237
|
let html;
|
|
34794
35238
|
try {
|
|
34795
|
-
html = await readEntryPage(
|
|
35239
|
+
html = await readEntryPage(join24(shellDir, SHELL_SITE_DIR, "index.html"));
|
|
34796
35240
|
checks.push({
|
|
34797
35241
|
id: "siteEntry",
|
|
34798
35242
|
status: "ok",
|
|
@@ -34810,7 +35254,7 @@ async function runShellDoctor(shellDir, deps = {}) {
|
|
|
34810
35254
|
}
|
|
34811
35255
|
const desktopShaped = config2.template === "app-desktop";
|
|
34812
35256
|
if (desktopShaped) {
|
|
34813
|
-
if (await pathExists2(
|
|
35257
|
+
if (await pathExists2(join24(shellDir, "preload.cjs"))) {
|
|
34814
35258
|
checks.push({
|
|
34815
35259
|
id: "bridgeTag",
|
|
34816
35260
|
status: "ok",
|
|
@@ -34855,7 +35299,7 @@ async function runShellDoctor(shellDir, deps = {}) {
|
|
|
34855
35299
|
});
|
|
34856
35300
|
} else {
|
|
34857
35301
|
const missingAssets = await missingEntries(
|
|
34858
|
-
|
|
35302
|
+
join24(shellDir, SHELL_SITE_DIR),
|
|
34859
35303
|
Object.values(MOBILE_SITE_ASSET_FILES)
|
|
34860
35304
|
);
|
|
34861
35305
|
if (missingAssets.length === 0) {
|
|
@@ -34924,8 +35368,8 @@ function formatShellDoctorReport(report) {
|
|
|
34924
35368
|
}
|
|
34925
35369
|
|
|
34926
35370
|
// packages/cli/src/app-sync.ts
|
|
34927
|
-
import { readFile as
|
|
34928
|
-
import { join as
|
|
35371
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
35372
|
+
import { join as join25 } from "node:path";
|
|
34929
35373
|
|
|
34930
35374
|
// packages/app-runtime/src/device-sqlite.ts
|
|
34931
35375
|
function createDeviceSqliteDriver(sqlite) {
|
|
@@ -35361,7 +35805,7 @@ var APP_SYNC_CODES = {
|
|
|
35361
35805
|
/** 当前运行时无 SQLite 内建模块(需要 Bun 或 Node ≥ 22.5)。 */
|
|
35362
35806
|
runtimeUnsupported: "APP_SYNC_RUNTIME_UNSUPPORTED"
|
|
35363
35807
|
};
|
|
35364
|
-
var LOCAL_DB_REL =
|
|
35808
|
+
var LOCAL_DB_REL = join25("data", "offline.sqlite");
|
|
35365
35809
|
function resolveOwnerKey(explicit) {
|
|
35366
35810
|
const fromEnv = process.env["ADEP_OWNER_KEY"];
|
|
35367
35811
|
const value = (explicit ?? fromEnv ?? "").trim();
|
|
@@ -35436,9 +35880,9 @@ async function runAppSync(options) {
|
|
|
35436
35880
|
);
|
|
35437
35881
|
}
|
|
35438
35882
|
const ownerKey = resolveOwnerKey(options.ownerKey);
|
|
35439
|
-
const localDb =
|
|
35883
|
+
const localDb = join25(shellDir, LOCAL_DB_REL);
|
|
35440
35884
|
try {
|
|
35441
|
-
await
|
|
35885
|
+
await readFile18(localDb);
|
|
35442
35886
|
} catch (error62) {
|
|
35443
35887
|
const code = error62.code;
|
|
35444
35888
|
if (code === "ENOENT" || code === "EISDIR") {
|
|
@@ -35499,14 +35943,14 @@ function formatAppSyncReport(report) {
|
|
|
35499
35943
|
// packages/cli/src/app-open.ts
|
|
35500
35944
|
import { spawn as spawn4 } from "node:child_process";
|
|
35501
35945
|
import { stat as stat10 } from "node:fs/promises";
|
|
35502
|
-
import { join as
|
|
35946
|
+
import { join as join26 } from "node:path";
|
|
35503
35947
|
var OPEN_UNSUPPORTED_HINT = {
|
|
35504
35948
|
"app-mobile": "\u79FB\u52A8\u58F3\u6CA1\u6709\u5F00\u53D1\u9884\u89C8\u8DEF\u5F84\uFF1A\u4E0B\u4E00\u6B65\u662F npm install && npx cap add ios / android\uFF08\u539F\u751F\u5DE5\u7A0B\u7531 Capacitor \u751F\u6210\uFF09\uFF0C\u968F\u540E\u5728 Xcode / Android Studio \u91CC\u8FD0\u884C",
|
|
35505
35949
|
"app-mobile-xtool": "xtool \u79FB\u52A8\u58F3\u6CA1\u6709\u5F00\u53D1\u9884\u89C8\u8DEF\u5F84\uFF1A\u5728\u8BE5\u76EE\u5F55\u6267\u884C xtool dev\uFF08\u9009\u8BBE\u5907\uFF09\u2014\u2014\u4E0D\u9700\u8981 npm start"
|
|
35506
35950
|
};
|
|
35507
35951
|
function resolveDevBinary(shellDir) {
|
|
35508
35952
|
const name = process.platform === "win32" ? "electron.cmd" : "electron";
|
|
35509
|
-
return
|
|
35953
|
+
return join26(shellDir, "node_modules", ".bin", name);
|
|
35510
35954
|
}
|
|
35511
35955
|
function defaultSpawnDev(command, args, options) {
|
|
35512
35956
|
return spawn4(command, args, { cwd: options.cwd, stdio: "inherit" });
|
|
@@ -35792,8 +36236,8 @@ function registerApp(program2, ctx) {
|
|
|
35792
36236
|
// packages/cli/src/import-cf.ts
|
|
35793
36237
|
init_adep_config();
|
|
35794
36238
|
init_regexp();
|
|
35795
|
-
import { copyFile as
|
|
35796
|
-
import { basename as basename3, dirname as
|
|
36239
|
+
import { copyFile as copyFile4, mkdir as mkdir13, readFile as readFile19, readdir as readdir8, stat as stat11, writeFile as writeFile14 } from "node:fs/promises";
|
|
36240
|
+
import { basename as basename3, dirname as dirname11, join as join27, relative as relative3, resolve as resolve11 } from "node:path";
|
|
35797
36241
|
var TomlSyntaxError = class extends Error {
|
|
35798
36242
|
constructor(message) {
|
|
35799
36243
|
super(message);
|
|
@@ -36047,13 +36491,13 @@ var SKIP_COPY_NAMES = /* @__PURE__ */ new Set([
|
|
|
36047
36491
|
async function copyWorkerDir(sourceDir, targetDir, mainFile) {
|
|
36048
36492
|
const copied = [];
|
|
36049
36493
|
const renamedIndex = [];
|
|
36050
|
-
const entries = await
|
|
36494
|
+
const entries = await readdir8(sourceDir, { withFileTypes: true });
|
|
36051
36495
|
for (const entry of entries) {
|
|
36052
|
-
const from =
|
|
36053
|
-
const to =
|
|
36496
|
+
const from = join27(sourceDir, entry.name);
|
|
36497
|
+
const to = join27(targetDir, entry.name);
|
|
36054
36498
|
if (SKIP_COPY_NAMES.has(entry.name)) continue;
|
|
36055
36499
|
if (entry.isDirectory()) {
|
|
36056
|
-
await
|
|
36500
|
+
await mkdir13(to, { recursive: true });
|
|
36057
36501
|
const sub = await copyWorkerDir(from, to, "");
|
|
36058
36502
|
copied.push(...sub.copied);
|
|
36059
36503
|
renamedIndex.push(...sub.renamedIndex);
|
|
@@ -36061,18 +36505,18 @@ async function copyWorkerDir(sourceDir, targetDir, mainFile) {
|
|
|
36061
36505
|
}
|
|
36062
36506
|
if (from === mainFile) continue;
|
|
36063
36507
|
if (entry.name === "index.ts") {
|
|
36064
|
-
await
|
|
36508
|
+
await copyFile4(from, join27(targetDir, "_index.ts"));
|
|
36065
36509
|
renamedIndex.push("_index.ts");
|
|
36066
36510
|
continue;
|
|
36067
36511
|
}
|
|
36068
|
-
await
|
|
36512
|
+
await copyFile4(from, to);
|
|
36069
36513
|
copied.push(relative3(targetDir, to));
|
|
36070
36514
|
}
|
|
36071
36515
|
return { copied, renamedIndex };
|
|
36072
36516
|
}
|
|
36073
36517
|
async function readDevVars(sourceDir) {
|
|
36074
36518
|
try {
|
|
36075
|
-
const text = await
|
|
36519
|
+
const text = await readFile19(join27(sourceDir, ".dev.vars"), "utf8");
|
|
36076
36520
|
const vars = {};
|
|
36077
36521
|
for (const line of text.split(/\r?\n/)) {
|
|
36078
36522
|
const trimmed = line.trim();
|
|
@@ -36090,19 +36534,19 @@ async function readDevVars(sourceDir) {
|
|
|
36090
36534
|
async function copyAssetsToWeb(sourceDir, assetsDir, outDir) {
|
|
36091
36535
|
const files = [];
|
|
36092
36536
|
const from = resolve11(sourceDir, assetsDir);
|
|
36093
|
-
const target =
|
|
36094
|
-
await
|
|
36095
|
-
const entries = await
|
|
36537
|
+
const target = join27(outDir, "web");
|
|
36538
|
+
await mkdir13(target, { recursive: true });
|
|
36539
|
+
const entries = await readdir8(from, { withFileTypes: true });
|
|
36096
36540
|
for (const entry of entries) {
|
|
36097
|
-
const src =
|
|
36098
|
-
const dst =
|
|
36541
|
+
const src = join27(from, entry.name);
|
|
36542
|
+
const dst = join27(target, entry.name);
|
|
36099
36543
|
if (entry.isDirectory()) {
|
|
36100
|
-
await
|
|
36544
|
+
await mkdir13(dst, { recursive: true });
|
|
36101
36545
|
const sub = await copyAssetsToWeb(src, ".", outDir);
|
|
36102
36546
|
files.push(...sub);
|
|
36103
36547
|
continue;
|
|
36104
36548
|
}
|
|
36105
|
-
await
|
|
36549
|
+
await copyFile4(src, dst);
|
|
36106
36550
|
files.push(relative3(outDir, dst));
|
|
36107
36551
|
}
|
|
36108
36552
|
return files;
|
|
@@ -36351,11 +36795,11 @@ function renderImportPackageJson(name) {
|
|
|
36351
36795
|
async function importCfProject(cwd, sourceDir, options = {}) {
|
|
36352
36796
|
let tomlText;
|
|
36353
36797
|
try {
|
|
36354
|
-
tomlText = await
|
|
36798
|
+
tomlText = await readFile19(join27(sourceDir, "wrangler.toml"), "utf8");
|
|
36355
36799
|
} catch {
|
|
36356
36800
|
throw new ImportCfError(
|
|
36357
36801
|
"NO_WRANGLER",
|
|
36358
|
-
`\u627E\u4E0D\u5230 ${
|
|
36802
|
+
`\u627E\u4E0D\u5230 ${join27(sourceDir, "wrangler.toml")}\uFF1A\u9700\u5728 Cloudflare \u9879\u76EE\u6839\u6267\u884C\u5BFC\u5165`
|
|
36359
36803
|
);
|
|
36360
36804
|
}
|
|
36361
36805
|
let config2;
|
|
@@ -36390,10 +36834,10 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
36390
36834
|
const configText = renderAdepConfig(adepConfig, {
|
|
36391
36835
|
header: "// \u7531 adep import cf \u751F\u6210\uFF08CF-015\uFF09\uFF1A\u7ED1\u5B9A\u58F0\u660E\u4E0E wrangler.toml \u5BF9\u5E94"
|
|
36392
36836
|
});
|
|
36393
|
-
await
|
|
36394
|
-
await
|
|
36837
|
+
await mkdir13(outDir, { recursive: true });
|
|
36838
|
+
await writeFile14(join27(outDir, "adep.config.ts"), configText, "utf8");
|
|
36395
36839
|
files.push("adep.config.ts");
|
|
36396
|
-
await
|
|
36840
|
+
await writeFile14(join27(outDir, "package.json"), renderImportPackageJson(workerName), "utf8");
|
|
36397
36841
|
files.push("package.json");
|
|
36398
36842
|
let mainCopied = false;
|
|
36399
36843
|
if (config2.main !== void 0) {
|
|
@@ -36407,12 +36851,12 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
36407
36851
|
if (!mainStat.isFile()) {
|
|
36408
36852
|
throw new ImportCfError("MAIN_NOT_FILE", `main \u4E0D\u662F\u6587\u4EF6\uFF1A${config2.main}`);
|
|
36409
36853
|
}
|
|
36410
|
-
const fnDir =
|
|
36411
|
-
await
|
|
36412
|
-
await
|
|
36854
|
+
const fnDir = join27(outDir, "functions", workerName);
|
|
36855
|
+
await mkdir13(fnDir, { recursive: true });
|
|
36856
|
+
await copyFile4(mainAbs, join27(fnDir, "worker.ts"));
|
|
36413
36857
|
files.push(`functions/${workerName}/worker.ts`);
|
|
36414
36858
|
mainCopied = true;
|
|
36415
|
-
const mainDir =
|
|
36859
|
+
const mainDir = dirname11(mainAbs);
|
|
36416
36860
|
const { copied, renamedIndex } = await copyWorkerDir(mainDir, fnDir, mainAbs);
|
|
36417
36861
|
if (renamedIndex.length > 0) {
|
|
36418
36862
|
warnings.push(
|
|
@@ -36423,7 +36867,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
36423
36867
|
if (copied.length > 0) {
|
|
36424
36868
|
warnings.push(`\u5DF2\u590D\u5236\u540C\u76EE\u5F55\u4F9D\u8D56\u6A21\u5757 ${copied.length} \u4E2A\uFF08\u4FDD\u6301\u76F8\u5BF9 import\uFF09`);
|
|
36425
36869
|
}
|
|
36426
|
-
await
|
|
36870
|
+
await writeFile14(join27(fnDir, "index.ts"), renderFunctionEntry("worker", cfBindings), "utf8");
|
|
36427
36871
|
files.push(`functions/${workerName}/index.ts`);
|
|
36428
36872
|
}
|
|
36429
36873
|
let dosMigrated = 0;
|
|
@@ -36438,20 +36882,20 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
36438
36882
|
);
|
|
36439
36883
|
}
|
|
36440
36884
|
if (doBindings.length > 0) {
|
|
36441
|
-
const fnDir =
|
|
36442
|
-
const workerPath =
|
|
36443
|
-
const workerText = await
|
|
36885
|
+
const fnDir = join27(outDir, "functions", workerName);
|
|
36886
|
+
const workerPath = join27(fnDir, "worker.ts");
|
|
36887
|
+
const workerText = await readFile19(workerPath, "utf8");
|
|
36444
36888
|
const { text: stripped, removed } = stripDurableObjectClasses(
|
|
36445
36889
|
workerText,
|
|
36446
36890
|
doBindings.map((b) => b.className)
|
|
36447
36891
|
);
|
|
36448
|
-
await
|
|
36892
|
+
await writeFile14(workerPath, stripped, "utf8");
|
|
36449
36893
|
if (removed.length > 0) {
|
|
36450
|
-
await
|
|
36894
|
+
await mkdir13(join27(fnDir, "durable-objects"), { recursive: true });
|
|
36451
36895
|
await Promise.all(
|
|
36452
36896
|
removed.map(async (r) => {
|
|
36453
|
-
await
|
|
36454
|
-
|
|
36897
|
+
await writeFile14(
|
|
36898
|
+
join27(fnDir, "durable-objects", `${r.className}.ts`),
|
|
36455
36899
|
`${r.source}
|
|
36456
36900
|
`,
|
|
36457
36901
|
"utf8"
|
|
@@ -36461,8 +36905,8 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
36461
36905
|
);
|
|
36462
36906
|
}
|
|
36463
36907
|
if (removed.length > 0) {
|
|
36464
|
-
await
|
|
36465
|
-
|
|
36908
|
+
await writeFile14(
|
|
36909
|
+
join27(fnDir, "state-objects.ts"),
|
|
36466
36910
|
renderStateObjectDeclaration(doBindings, removed),
|
|
36467
36911
|
"utf8"
|
|
36468
36912
|
);
|
|
@@ -36507,7 +36951,7 @@ async function importCfProject(cwd, sourceDir, options = {}) {
|
|
|
36507
36951
|
unsupported,
|
|
36508
36952
|
warnings
|
|
36509
36953
|
});
|
|
36510
|
-
await
|
|
36954
|
+
await writeFile14(join27(outDir, "MIGRATION.md"), migration, "utf8");
|
|
36511
36955
|
files.push("MIGRATION.md");
|
|
36512
36956
|
if (!mainCopied) {
|
|
36513
36957
|
warnings.push("wrangler.toml \u672A\u58F0\u660E main\uFF1A\u672A\u751F\u6210\u51FD\u6570\uFF0C\u4EC5\u751F\u6210\u914D\u7F6E\u4E0E\u62A5\u544A");
|
|
@@ -36628,7 +37072,7 @@ init_auth();
|
|
|
36628
37072
|
init_client();
|
|
36629
37073
|
init_deploy();
|
|
36630
37074
|
import { stat as stat16 } from "node:fs/promises";
|
|
36631
|
-
import { join as
|
|
37075
|
+
import { join as join34, resolve as resolve16 } from "node:path";
|
|
36632
37076
|
async function resolveProjectId2(client, cwd, slug) {
|
|
36633
37077
|
const resolvedSlug = await resolveSlug(resolve16(cwd), slug);
|
|
36634
37078
|
const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
|
|
@@ -36675,8 +37119,8 @@ async function publishStaticFrontend(paths, options) {
|
|
|
36675
37119
|
"\u7EAF\u9759\u6001\u7AD9\u6682\u4E0D\u652F\u6301\u53D1\u5230\u5F00\u53D1\u7AD9\u70B9\uFF1A\u8BE5\u901A\u9053\u76F4\u63A5\u4E0A\u4F20 site/\uFF0C\u4F1A\u8986\u76D6\u7EBF\u4E0A\u7AD9\u70B9\u3002\u8BF7\u6539\u7528\u5E73\u53F0\u6784\u5EFA\u901A\u9053\uFF08\u5728 web/ \u58F0\u660E scripts.build\uFF09\uFF0C\u6216\u7528 --only functions \u4E4B\u5916\u7684\u5176\u5B83\u65B9\u5F0F\u9A8C\u8BC1\u3002"
|
|
36676
37120
|
);
|
|
36677
37121
|
}
|
|
36678
|
-
const webDir =
|
|
36679
|
-
const indexStat = await stat16(
|
|
37122
|
+
const webDir = join34(options.cwd, "web");
|
|
37123
|
+
const indexStat = await stat16(join34(webDir, "index.html")).catch(() => null);
|
|
36680
37124
|
if (indexStat === null || !indexStat.isFile()) {
|
|
36681
37125
|
throw new CliError(
|
|
36682
37126
|
"FRONTEND_NO_PAGE",
|
|
@@ -36729,7 +37173,7 @@ async function runPublish(paths, io, cwd, flags) {
|
|
|
36729
37173
|
});
|
|
36730
37174
|
}
|
|
36731
37175
|
if (wantFrontend) {
|
|
36732
|
-
const webDir =
|
|
37176
|
+
const webDir = join34(cwd, "web");
|
|
36733
37177
|
const webStat = await stat16(webDir).catch(() => null);
|
|
36734
37178
|
if (webStat !== null && webStat.isDirectory()) {
|
|
36735
37179
|
const { isStaticFrontendDir: isStaticFrontendDir2 } = await Promise.resolve().then(() => (init_frontend(), frontend_exports));
|
|
@@ -36797,6 +37241,13 @@ function renderPublish(data) {
|
|
|
36797
37241
|
lines.push(`\u2713 frontend built ${status} \xB7 ${fe.siteUrl}`);
|
|
36798
37242
|
}
|
|
36799
37243
|
}
|
|
37244
|
+
if (result.functions !== void 0) {
|
|
37245
|
+
lines.push("");
|
|
37246
|
+
lines.push("\u53D1\u5E03\u540E\u4E09\u6B65\uFF08\u9996\u6B21\u53D1\u5E03\u5FC5\u505A\uFF09\uFF1A");
|
|
37247
|
+
lines.push(" 1. adep db start # \u542F\u52A8\u9879\u76EE\u6570\u636E\u5E93\uFF08\u82E5\u5DF2\u542F\u52A8\u8DF3\u8FC7\uFF09");
|
|
37248
|
+
lines.push(" 2. adep db migrate <schema.sql> # \u5EFA\u8868\uFF08\u53D1\u5E03\u4E0D\u542B\u5EFA\u8868\uFF09");
|
|
37249
|
+
lines.push(" 3. adep db migrate <seed.sql> # \u79CD\u5B50\u6570\u636E\uFF08\u53EF\u9009\uFF09");
|
|
37250
|
+
}
|
|
36800
37251
|
return lines;
|
|
36801
37252
|
}
|
|
36802
37253
|
function registerPublish(program2, ctx) {
|
|
@@ -36830,8 +37281,8 @@ init_auth();
|
|
|
36830
37281
|
// packages/cli/src/deploy-worker.ts
|
|
36831
37282
|
init_auth();
|
|
36832
37283
|
init_client();
|
|
36833
|
-
import { readdir as
|
|
36834
|
-
import { join as
|
|
37284
|
+
import { readdir as readdir12, readFile as readFile26 } from "node:fs/promises";
|
|
37285
|
+
import { join as join35, relative as relative8, resolve as resolve17, sep as sep4 } from "node:path";
|
|
36835
37286
|
async function collectWranglerFiles(dir) {
|
|
36836
37287
|
const root = resolve17(dir);
|
|
36837
37288
|
const out = {};
|
|
@@ -36839,7 +37290,7 @@ async function collectWranglerFiles(dir) {
|
|
|
36839
37290
|
const walk = async (sub) => {
|
|
36840
37291
|
let entries;
|
|
36841
37292
|
try {
|
|
36842
|
-
entries = await
|
|
37293
|
+
entries = await readdir12(sub, { withFileTypes: true });
|
|
36843
37294
|
} catch (error62) {
|
|
36844
37295
|
throw new CliError(
|
|
36845
37296
|
"WORKER_DIR_UNREADABLE",
|
|
@@ -36848,11 +37299,11 @@ async function collectWranglerFiles(dir) {
|
|
|
36848
37299
|
}
|
|
36849
37300
|
for (const entry of entries) {
|
|
36850
37301
|
if (entry.isDirectory() && skip.has(entry.name)) continue;
|
|
36851
|
-
const full =
|
|
37302
|
+
const full = join35(sub, entry.name);
|
|
36852
37303
|
if (entry.isDirectory()) {
|
|
36853
37304
|
await walk(full);
|
|
36854
37305
|
} else if (entry.isFile()) {
|
|
36855
|
-
const buf = await
|
|
37306
|
+
const buf = await readFile26(full).catch(() => null);
|
|
36856
37307
|
if (buf === null) continue;
|
|
36857
37308
|
if (buf.includes(0)) continue;
|
|
36858
37309
|
out[relative8(root, full).split(sep4).join("/")] = buf.toString("utf8");
|
|
@@ -37164,20 +37615,21 @@ function registerDb(program2, ctx) {
|
|
|
37164
37615
|
});
|
|
37165
37616
|
});
|
|
37166
37617
|
db.command("migrate").description(
|
|
37167
|
-
"\u6267\u884C SQL \u8FC1\u79FB\u6587\u4EF6\uFF08
|
|
37168
|
-
).argument("<
|
|
37618
|
+
"\u6267\u884C SQL \u8FC1\u79FB\u6587\u4EF6\uFF08\u53EF\u591A\u4E2A\uFF0C\u6309\u58F0\u660E\u987A\u5E8F\u6267\u884C\u2014\u2014a.sql \u5EFA\u8868\u3001b.sql \u63D2\u6570\u636E\u7684\u4F9D\u8D56\u987A\u5E8F\u5C31\u662F\u58F0\u660E\u987A\u5E8F\uFF1B\u5931\u8D25\u5373\u505C\u5E76\u6307\u5411\u5931\u8D25\u6587\u4EF6\uFF09"
|
|
37619
|
+
).argument("<files...>", "\u8FC1\u79FB SQL \u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u5F53\u524D\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u6309\u58F0\u660E\u987A\u5E8F\u6267\u884C\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (files, flags) => {
|
|
37169
37620
|
const command = ctx.io("db migrate");
|
|
37170
37621
|
await command.run(async () => {
|
|
37171
37622
|
const { environment, source } = await ctx.env();
|
|
37172
37623
|
const { dbMigrate: dbMigrate2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
|
|
37173
37624
|
const result = await dbMigrate2(ctx.paths, {
|
|
37174
37625
|
cwd: ctx.cwd,
|
|
37175
|
-
|
|
37626
|
+
files,
|
|
37176
37627
|
environment,
|
|
37177
37628
|
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
37178
37629
|
});
|
|
37179
37630
|
if (result.failed !== void 0) {
|
|
37180
|
-
|
|
37631
|
+
const f = result.failed;
|
|
37632
|
+
command.fail(f.code, `\u6587\u4EF6 ${f.file} \u4E2D\u7684\u8BED\u53E5\u6267\u884C\u5931\u8D25\uFF1A${f.message}`);
|
|
37181
37633
|
return;
|
|
37182
37634
|
}
|
|
37183
37635
|
command.line(
|
|
@@ -37655,28 +38107,40 @@ function registerHosting(program2, ctx) {
|
|
|
37655
38107
|
});
|
|
37656
38108
|
});
|
|
37657
38109
|
hosting.command("deploy").description(
|
|
37658
|
-
"[deprecated] \u63A8\u8350\u4F7F\u7528 adep publish --only frontend\u3002\u90E8\u7F72\u672C\u5730\u76EE\u5F55\u4E3A\u9759\u6001\u7AD9\u70B9\uFF1A\
|
|
37659
|
-
).argument("<dir>", "\u672C\u5730\u7AD9\u70B9\u76EE\u5F55").option("--spa", "\u6253\u5F00\u6258\u7BA1\u5E76\u542F\u7528 SPA \u56DE\u9000\uFF08\u7F3A\u7701\u4EC5\u6253\u5F00\u6258\u7BA1\uFF09", false).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(
|
|
37660
|
-
|
|
37661
|
-
|
|
37662
|
-
|
|
37663
|
-
|
|
37664
|
-
|
|
37665
|
-
|
|
37666
|
-
|
|
37667
|
-
|
|
37668
|
-
|
|
37669
|
-
|
|
37670
|
-
|
|
37671
|
-
|
|
37672
|
-
|
|
37673
|
-
|
|
37674
|
-
|
|
37675
|
-
|
|
37676
|
-
|
|
38110
|
+
"[deprecated] \u63A8\u8350\u4F7F\u7528 adep publish --only frontend\u3002\u90E8\u7F72\u672C\u5730\u76EE\u5F55\u4E3A\u9759\u6001\u7AD9\u70B9\uFF1A\u589E\u91CF\u6BD4\u5BF9\u53EA\u4F20\u53D8\u66F4\u5E76\u6253\u5F00\u6258\u7BA1"
|
|
38111
|
+
).argument("<dir>", "\u672C\u5730\u7AD9\u70B9\u76EE\u5F55").option("--spa", "\u6253\u5F00\u6258\u7BA1\u5E76\u542F\u7528 SPA \u56DE\u9000\uFF08\u7F3A\u7701\u4EC5\u6253\u5F00\u6258\u7BA1\uFF09", false).option("--build <cmd>", "\u90E8\u7F72\u524D\u6267\u884C\u7684\u6784\u5EFA\u547D\u4EE4\uFF08\u9879\u76EE\u6839\u76EE\u5F55\u8FD0\u884C\uFF0C\u975E\u96F6\u9000\u51FA\u5373\u4E2D\u6B62\u90E8\u7F72\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(
|
|
38112
|
+
async (dir, flags) => {
|
|
38113
|
+
const command = ctx.io("hosting deploy");
|
|
38114
|
+
if (!command.json) {
|
|
38115
|
+
process.stderr.write(
|
|
38116
|
+
"\u63D0\u793A\uFF1Aadep hosting deploy \u5DF2\u5E9F\u5F03\uFF0C\u63A8\u8350\u4F7F\u7528 adep publish --only frontend\uFF08\u5E73\u53F0\u4FA7\u6784\u5EFA web/ \u8349\u7A3F\uFF09\uFF1B\u5982\u786E\u9700\u4E0A\u4F20\u9884\u6784\u5EFA\u76EE\u5F55\uFF0C\u4ECD\u53EF\u7EE7\u7EED\u4F7F\u7528\u672C\u547D\u4EE4\n"
|
|
38117
|
+
);
|
|
38118
|
+
}
|
|
38119
|
+
await command.run(async () => {
|
|
38120
|
+
const { hostingDeploy: hostingDeploy2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
|
|
38121
|
+
const result = await hostingDeploy2(ctx.paths, {
|
|
38122
|
+
cwd: ctx.cwd,
|
|
38123
|
+
dir,
|
|
38124
|
+
...flags.spa === true ? { spa: true } : {},
|
|
38125
|
+
...flags.build === void 0 ? {} : { build: flags.build },
|
|
38126
|
+
...flags.project === void 0 ? {} : { slug: flags.project },
|
|
38127
|
+
// 人读模式逐行输出进度;JSON 模式丢弃(stdout 必须恰好一个 JSON 对象)。
|
|
38128
|
+
log: (line) => command.line(line)
|
|
38129
|
+
});
|
|
38130
|
+
command.ok(result, (data) => {
|
|
38131
|
+
const r = data;
|
|
38132
|
+
const lines = [];
|
|
38133
|
+
if (r.identical) {
|
|
38134
|
+
lines.push("\u26A0 \u672C\u6B21\u4E0A\u4F20\u5185\u5BB9\u4E0E\u7EBF\u4E0A\u73B0\u6709\u7248\u672C\u5B8C\u5168\u4E00\u81F4\u2014\u2014\u82E5\u521A\u4FEE\u6539\u8FC7\u6E90\u7801\uFF0C\u53EF\u80FD\u5FD8\u4E86\u5148\u6784\u5EFA\u3002");
|
|
38135
|
+
}
|
|
38136
|
+
lines.push(
|
|
38137
|
+
`\u7AD9\u70B9\u5DF2\u4E0A\u7EBF\uFF1A${r.siteUrl}\uFF08${r.uploaded.length} \u53D8\u66F4 / ${r.reused} \u590D\u7528\uFF0C\u6784\u5EFA\u4E8E ${r.builtAt}\uFF0CSPA \u56DE\u9000 ${r.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`
|
|
38138
|
+
);
|
|
38139
|
+
return lines;
|
|
38140
|
+
});
|
|
37677
38141
|
});
|
|
37678
|
-
}
|
|
37679
|
-
|
|
38142
|
+
}
|
|
38143
|
+
);
|
|
37680
38144
|
hosting.command("pull").description("\u62C9\u53D6\u7AD9\u70B9\u516C\u5F00\u6587\u4EF6\u5230\u672C\u5730\u76EE\u5F55\uFF08\u8DF3\u8FC7\u6258\u7BA1\u914D\u7F6E\uFF09").option("-o, --output <dir>", "\u672C\u5730\u8F93\u51FA\u76EE\u5F55\uFF08\u7F3A\u7701\u5199\u5230 cwd\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
37681
38145
|
const command = ctx.io("hosting pull");
|
|
37682
38146
|
await command.run(async () => {
|