@adep/cli 0.4.1 → 0.4.5
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 +140 -11
- package/dist/index.js +34568 -27795
- package/dist/vite.js +279 -19
- package/dist/worker-entry.js +201 -2
- package/package.json +6 -5
- package/templates/app-desktop/README.md +67 -2
- package/templates/app-desktop/identity-store.mjs +309 -0
- package/templates/app-desktop/identity.mjs +517 -0
- package/templates/app-desktop/main.cjs +17 -0
- package/templates/app-desktop/main.mjs +218 -2
- package/templates/app-desktop/offline-runtime.mjs +72 -3
- package/templates/app-desktop/package.json +10 -6
- package/templates/app-desktop/recovery-ui.mjs +300 -0
- package/templates/app-desktop/sync-loop.mjs +137 -0
- package/templates/app-mobile/README.md +47 -9
- package/templates/app-mobile/package.json +2 -1
- package/templates/app-mobile/plugins/adep-bridge/Package.swift +52 -0
- package/templates/app-mobile/plugins/adep-bridge/android/build.gradle +34 -3
- package/templates/app-mobile/plugins/adep-bridge/android/src/main/AndroidManifest.xml +12 -5
- package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepBridge.kt +198 -12
- package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepIdentity.kt +342 -0
- package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepKeystore.kt +56 -2
- package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepSqlite.kt +506 -0
- package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepSqliteLogic.kt +235 -0
- package/templates/app-mobile/plugins/adep-bridge/dist/plugin.js +30 -0
- package/templates/app-mobile/plugins/adep-bridge/ios/AdepBridge.podspec +7 -1
- package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepBridge.swift +221 -9
- package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepIdentity.swift +500 -0
- package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepKeychain.swift +69 -17
- package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepPermissionGate.swift +25 -4
- package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepShellConfig.swift +54 -0
- package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepSqlite.swift +614 -0
- package/templates/app-mobile/plugins/adep-bridge/package.json +10 -0
- package/templates/app-mobile/template.json +12 -3
- package/templates/app-mobile/web/adep-bridge.js +103 -9
- package/templates/app-mobile/web/offline-runtime.js +230 -0
- package/templates/app-mobile-xtool/AdepShell-Info.plist +24 -0
- package/templates/app-mobile-xtool/Package.swift +59 -0
- package/templates/app-mobile-xtool/README.md +81 -0
- package/templates/app-mobile-xtool/Sources/AdepShell/App.swift +36 -0
- package/templates/app-mobile-xtool/Sources/AdepShell/ShellViewController.swift +223 -0
- package/templates/app-mobile-xtool/adep.permissions.json +4 -0
- package/templates/app-mobile-xtool/app/site/.gitkeep +0 -0
- package/templates/app-mobile-xtool/template.json +15 -0
- package/templates/app-mobile-xtool/xtool.yml +35 -0
- package/templates/app-mobile/plugins/adep-bridge/capacitor.plugin.json +0 -10
package/dist/vite.js
CHANGED
|
@@ -15,6 +15,8 @@ var DB_RPC = {
|
|
|
15
15
|
query: "query",
|
|
16
16
|
/** 写路径(CF-013):`(method=writeQuery, args=[sql, params])` → `{ changes }`。 */
|
|
17
17
|
writeQuery: "writeQuery",
|
|
18
|
+
/** 通用执行(BUG-4,2026-10-14):`(method=execute, args=[sql, params?])` → `{ changes }`。 */
|
|
19
|
+
execute: "execute",
|
|
18
20
|
/** 读取 owned 表变更流(DB-006):`(method=changes, args=[table, query])`。 */
|
|
19
21
|
changes: "changes",
|
|
20
22
|
/** 开启事务:`begin → txId`。 */
|
|
@@ -62,6 +64,30 @@ function normalizeHttpStatus(status) {
|
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
// packages/runtime/src/shared/http-envelope.ts
|
|
67
|
+
function coerceAdepHttpEnvelope(value) {
|
|
68
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
69
|
+
if (isAdepHttpEnvelope(value)) return value;
|
|
70
|
+
const keys = Object.keys(value);
|
|
71
|
+
if (keys.length === 0) return null;
|
|
72
|
+
if (!keys.every((key) => key === "status" || key === "body" || key === "headers")) return null;
|
|
73
|
+
const candidate = value;
|
|
74
|
+
const status = candidate.status;
|
|
75
|
+
if (typeof status !== "number" || !Number.isInteger(status) || status < 100 || status > 599) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
if ("headers" in candidate && candidate.headers !== void 0) {
|
|
79
|
+
const headers = candidate.headers;
|
|
80
|
+
if (typeof headers !== "object" || headers === null || Array.isArray(headers)) return null;
|
|
81
|
+
if (!Object.values(headers).every((headerValue2) => typeof headerValue2 === "string")) return null;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
__adepHttp: {
|
|
85
|
+
status,
|
|
86
|
+
...candidate.headers === void 0 ? {} : { headers: candidate.headers },
|
|
87
|
+
body: candidate.body
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
65
91
|
function isAdepHttpEnvelope(value) {
|
|
66
92
|
if (typeof value !== "object" || value === null) return false;
|
|
67
93
|
const envelope = value.__adepHttp;
|
|
@@ -454,6 +480,14 @@ function assertWriteQuery(sql) {
|
|
|
454
480
|
);
|
|
455
481
|
}
|
|
456
482
|
}
|
|
483
|
+
function classifyStatement(sql) {
|
|
484
|
+
const head = sqlHead(stripLiterals(sql));
|
|
485
|
+
if (head.startsWith("SELECT") || head.startsWith("WITH")) return "read";
|
|
486
|
+
if (head.startsWith("INSERT") || head.startsWith("UPDATE") || head.startsWith("DELETE")) {
|
|
487
|
+
return "write";
|
|
488
|
+
}
|
|
489
|
+
return "ddl";
|
|
490
|
+
}
|
|
457
491
|
|
|
458
492
|
// packages/runtime/src/database/builder/owned.ts
|
|
459
493
|
var OWNED_PK = "id";
|
|
@@ -708,10 +742,21 @@ function compileSelect(state, dialect) {
|
|
|
708
742
|
if (state.orderBys.length > 0) {
|
|
709
743
|
sql += ` ORDER BY ${state.orderBys.map((order) => `${dialect.quote(order.column)} ${order.direction.toUpperCase()}`).join(", ")}`;
|
|
710
744
|
}
|
|
711
|
-
if (state.limit !== void 0)
|
|
712
|
-
|
|
745
|
+
if (state.limit !== void 0) {
|
|
746
|
+
assertInlineableInt(state.limit, "limit");
|
|
747
|
+
sql += ` LIMIT ${state.limit}`;
|
|
748
|
+
}
|
|
749
|
+
if (state.offset !== void 0) {
|
|
750
|
+
assertInlineableInt(state.offset, "offset");
|
|
751
|
+
sql += ` OFFSET ${state.offset}`;
|
|
752
|
+
}
|
|
713
753
|
return { sql, params };
|
|
714
754
|
}
|
|
755
|
+
function assertInlineableInt(value, name) {
|
|
756
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
757
|
+
throw unsafeOperation(`${name} \u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570`);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
715
760
|
function compileCount(state, dialect) {
|
|
716
761
|
const params = [];
|
|
717
762
|
let sql = `SELECT count(*) AS n FROM ${dialect.quote(state.table)}`;
|
|
@@ -1006,6 +1051,21 @@ function createCloudDb(driver, options = {}) {
|
|
|
1006
1051
|
assertWriteQuery(sql);
|
|
1007
1052
|
return driver.run(sql, params);
|
|
1008
1053
|
},
|
|
1054
|
+
async execute(sql, params = []) {
|
|
1055
|
+
if (sql.trim() === "") {
|
|
1056
|
+
throw unsafeOperation("execute \u7684 sql \u4E0D\u80FD\u4E3A\u7A7A");
|
|
1057
|
+
}
|
|
1058
|
+
if (!Array.isArray(params)) {
|
|
1059
|
+
throw unsafeOperation("execute \u7684 params \u5FC5\u987B\u662F\u6570\u7EC4\uFF08\u65E0\u53C2\u53EF\u4E0D\u4F20\uFF09");
|
|
1060
|
+
}
|
|
1061
|
+
guardWrite();
|
|
1062
|
+
const kind = classifyStatement(sql);
|
|
1063
|
+
if (kind === "read") {
|
|
1064
|
+
await driver.all(sql, params);
|
|
1065
|
+
return { changes: 0 };
|
|
1066
|
+
}
|
|
1067
|
+
return driver.run(sql, params);
|
|
1068
|
+
},
|
|
1009
1069
|
async changes(table, query = {}) {
|
|
1010
1070
|
return readChanges(driver, table, query);
|
|
1011
1071
|
}
|
|
@@ -1081,6 +1141,10 @@ function createDbCapability(driver, options = {}) {
|
|
|
1081
1141
|
const [sql, params] = args;
|
|
1082
1142
|
return await db.writeQuery(sql, params);
|
|
1083
1143
|
}
|
|
1144
|
+
case DB_RPC.execute: {
|
|
1145
|
+
const [sql, params] = args;
|
|
1146
|
+
return await db.execute(sql, params ?? []);
|
|
1147
|
+
}
|
|
1084
1148
|
case DB_RPC.changes: {
|
|
1085
1149
|
const [table, query] = args;
|
|
1086
1150
|
return await db.changes(table, query);
|
|
@@ -1246,11 +1310,21 @@ function parseWhereClauses(whereRaw, cursor) {
|
|
|
1246
1310
|
const t = part.trim();
|
|
1247
1311
|
if (t.length === 0) continue;
|
|
1248
1312
|
if (/\bIS\s+NULL\b/i.test(t)) {
|
|
1249
|
-
clauses.push({
|
|
1313
|
+
clauses.push({
|
|
1314
|
+
column: unqualifyColumn(ident(t.split(/\s+IS\s+NULL\b/i)[0] ?? "")),
|
|
1315
|
+
operator: "IS NULL",
|
|
1316
|
+
value: null,
|
|
1317
|
+
list: false
|
|
1318
|
+
});
|
|
1250
1319
|
continue;
|
|
1251
1320
|
}
|
|
1252
1321
|
if (/\bIS\s+NOT\s+NULL\b/i.test(t)) {
|
|
1253
|
-
clauses.push({
|
|
1322
|
+
clauses.push({
|
|
1323
|
+
column: unqualifyColumn(ident(t.split(/\s+IS\s+NOT\s+NULL\b/i)[0] ?? "")),
|
|
1324
|
+
operator: "IS NOT NULL",
|
|
1325
|
+
value: null,
|
|
1326
|
+
list: false
|
|
1327
|
+
});
|
|
1254
1328
|
continue;
|
|
1255
1329
|
}
|
|
1256
1330
|
const opMatch = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_.]*))\s*(=|!=|>=|<=|>|<|like|in|not\s+in)\s*(.+)$/i.exec(
|
|
@@ -1427,7 +1501,10 @@ function parseConflictClause(clause, cursor, fallbackCols) {
|
|
|
1427
1501
|
clause.trim()
|
|
1428
1502
|
);
|
|
1429
1503
|
if (m === null) {
|
|
1430
|
-
throw new SimDbError(
|
|
1504
|
+
throw new SimDbError(
|
|
1505
|
+
"DB_UNSAFE_OP",
|
|
1506
|
+
`\u65E0\u6CD5\u89E3\u6790 ON CONFLICT \u5B50\u53E5\uFF1A${clause.trim().slice(0, 60)}\u2026`
|
|
1507
|
+
);
|
|
1431
1508
|
}
|
|
1432
1509
|
const colsRaw = m[1];
|
|
1433
1510
|
const cols = colsRaw === void 0 ? fallbackCols : colsRaw.split(",").map(ident);
|
|
@@ -1631,16 +1708,16 @@ var SimSqlEngine = class {
|
|
|
1631
1708
|
row[col] = values[i] ?? null;
|
|
1632
1709
|
});
|
|
1633
1710
|
if (conflictSpec !== null) {
|
|
1634
|
-
const existing = table.rows.find(
|
|
1635
|
-
(r) => conflictSpec.cols.every((c) => r[c] === row[c])
|
|
1636
|
-
);
|
|
1711
|
+
const existing = table.rows.find((r) => conflictSpec.cols.every((c) => r[c] === row[c]));
|
|
1637
1712
|
if (existing !== void 0) {
|
|
1638
1713
|
const oldRow = { ...existing };
|
|
1639
1714
|
for (const set of conflictSpec.sets) {
|
|
1640
1715
|
existing[set.col] = resolveSetValue(set.value, oldRow, row);
|
|
1641
1716
|
}
|
|
1642
1717
|
inserted += 1;
|
|
1643
|
-
|
|
1718
|
+
this.persist().catch((error) => {
|
|
1719
|
+
console.warn("[sim] \u6301\u4E45\u5316\u5931\u8D25\uFF1A", error);
|
|
1720
|
+
});
|
|
1644
1721
|
continue;
|
|
1645
1722
|
}
|
|
1646
1723
|
}
|
|
@@ -1648,7 +1725,9 @@ var SimSqlEngine = class {
|
|
|
1648
1725
|
table.rows.push(row);
|
|
1649
1726
|
inserted += 1;
|
|
1650
1727
|
}
|
|
1651
|
-
|
|
1728
|
+
this.persist().catch((error) => {
|
|
1729
|
+
console.warn("[sim] \u6301\u4E45\u5316\u5931\u8D25\uFF1A", error);
|
|
1730
|
+
});
|
|
1652
1731
|
return { changes: inserted };
|
|
1653
1732
|
}
|
|
1654
1733
|
execUpdate(sql, params) {
|
|
@@ -1678,7 +1757,9 @@ var SimSqlEngine = class {
|
|
|
1678
1757
|
}
|
|
1679
1758
|
changes += 1;
|
|
1680
1759
|
}
|
|
1681
|
-
|
|
1760
|
+
this.persist().catch((error) => {
|
|
1761
|
+
console.warn("[sim] \u6301\u4E45\u5316\u5931\u8D25\uFF1A", error);
|
|
1762
|
+
});
|
|
1682
1763
|
return { changes };
|
|
1683
1764
|
}
|
|
1684
1765
|
execDelete(sql, params) {
|
|
@@ -1696,7 +1777,9 @@ var SimSqlEngine = class {
|
|
|
1696
1777
|
else changes += 1;
|
|
1697
1778
|
}
|
|
1698
1779
|
table.rows = keep;
|
|
1699
|
-
|
|
1780
|
+
this.persist().catch((error) => {
|
|
1781
|
+
console.warn("[sim] \u6301\u4E45\u5316\u5931\u8D25\uFF1A", error);
|
|
1782
|
+
});
|
|
1700
1783
|
return { changes };
|
|
1701
1784
|
}
|
|
1702
1785
|
select(sql, params) {
|
|
@@ -1718,7 +1801,9 @@ var SimSqlEngine = class {
|
|
|
1718
1801
|
rows = table.rows.map((row) => {
|
|
1719
1802
|
const merged = { ...row };
|
|
1720
1803
|
for (const j of joins) {
|
|
1721
|
-
const joined = this.tables[j.table]?.rows.find(
|
|
1804
|
+
const joined = this.tables[j.table]?.rows.find(
|
|
1805
|
+
(jr) => jr[j.leftCol] === merged[j.rightCol]
|
|
1806
|
+
);
|
|
1722
1807
|
if (joined !== void 0) {
|
|
1723
1808
|
for (const [k, v] of Object.entries(joined)) merged[`${j.alias}.${k}`] = v;
|
|
1724
1809
|
}
|
|
@@ -2819,7 +2904,7 @@ function envDbFile() {
|
|
|
2819
2904
|
function displayPath(cwd, target) {
|
|
2820
2905
|
if (target === ":memory:") return target;
|
|
2821
2906
|
const rel = relative(cwd, target);
|
|
2822
|
-
return rel.startsWith("..") ? target : rel;
|
|
2907
|
+
return rel.startsWith("..") ? target : rel.split(/[\\/]/u).join("/");
|
|
2823
2908
|
}
|
|
2824
2909
|
function simDbTarget(cwd) {
|
|
2825
2910
|
return displayPath(cwd, join5(simDir(cwd), "db.json"));
|
|
@@ -3211,6 +3296,15 @@ function parseAdepConfig(raw) {
|
|
|
3211
3296
|
data.environment = rec;
|
|
3212
3297
|
}
|
|
3213
3298
|
}
|
|
3299
|
+
if (input.db_environment !== void 0) {
|
|
3300
|
+
if (input.db_environment !== "dev" && input.db_environment !== "prod") {
|
|
3301
|
+
errors.push(
|
|
3302
|
+
`db_environment \u53EA\u63A5\u53D7 'dev' \u6216 'prod'\uFF0C\u6536\u5230 ${typeNameOf(input.db_environment)}\uFF08\u6CE8\u610F\u522B\u4E0E environment \u6DF7\u7528\uFF1A\u540E\u8005\u662F\u6CE8\u5165\u51FD\u6570\u8FD0\u884C\u65F6\u7684\u53D8\u91CF\u8868\uFF09`
|
|
3303
|
+
);
|
|
3304
|
+
} else {
|
|
3305
|
+
data.db_environment = input.db_environment;
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3214
3308
|
if (input.runtime !== void 0) {
|
|
3215
3309
|
const rec = asRecord(input.runtime);
|
|
3216
3310
|
if (rec === null) {
|
|
@@ -3598,6 +3692,158 @@ function parseExportClause(clause) {
|
|
|
3598
3692
|
}
|
|
3599
3693
|
return entries;
|
|
3600
3694
|
}
|
|
3695
|
+
var CONTINUES_AFTER = "=+-*/%&|^<>?:,.[(";
|
|
3696
|
+
var CONTINUES_BEFORE = "`([.?:,+-*/%&|^<>=";
|
|
3697
|
+
var REGEX_PRECEDERS = "(,=:[!&|?{};+-*%~^<>";
|
|
3698
|
+
var MATCHING_OPEN = { ")": "(", "]": "[", "}": "{" };
|
|
3699
|
+
function lineNumberAt(code, index) {
|
|
3700
|
+
let line = 1;
|
|
3701
|
+
for (let i = 0; i < index; i += 1) if (code.charCodeAt(i) === 10) line += 1;
|
|
3702
|
+
return line;
|
|
3703
|
+
}
|
|
3704
|
+
function skipQuoted(code, start) {
|
|
3705
|
+
const quote = code.charAt(start);
|
|
3706
|
+
let i = start + 1;
|
|
3707
|
+
while (i < code.length) {
|
|
3708
|
+
const ch = code.charAt(i);
|
|
3709
|
+
if (ch === "\\") {
|
|
3710
|
+
i += 2;
|
|
3711
|
+
continue;
|
|
3712
|
+
}
|
|
3713
|
+
if (ch === quote) return i + 1;
|
|
3714
|
+
if (ch === "\n") return i;
|
|
3715
|
+
i += 1;
|
|
3716
|
+
}
|
|
3717
|
+
return code.length;
|
|
3718
|
+
}
|
|
3719
|
+
function skipRegex(code, start) {
|
|
3720
|
+
let i = start + 1;
|
|
3721
|
+
let inClass = false;
|
|
3722
|
+
while (i < code.length) {
|
|
3723
|
+
const ch = code.charAt(i);
|
|
3724
|
+
if (ch === "\\") {
|
|
3725
|
+
i += 2;
|
|
3726
|
+
continue;
|
|
3727
|
+
}
|
|
3728
|
+
if (ch === "\n") return start + 1;
|
|
3729
|
+
if (ch === "[") inClass = true;
|
|
3730
|
+
else if (ch === "]") inClass = false;
|
|
3731
|
+
else if (ch === "/" && !inClass) return i + 1;
|
|
3732
|
+
i += 1;
|
|
3733
|
+
}
|
|
3734
|
+
return code.length;
|
|
3735
|
+
}
|
|
3736
|
+
function regexCanStart(prev) {
|
|
3737
|
+
return prev === "" || REGEX_PRECEDERS.includes(prev);
|
|
3738
|
+
}
|
|
3739
|
+
function continuesOnto(code, newline, prev) {
|
|
3740
|
+
if (prev !== "" && CONTINUES_AFTER.includes(prev)) return true;
|
|
3741
|
+
let i = newline + 1;
|
|
3742
|
+
while (i < code.length && /\s/.test(code.charAt(i))) i += 1;
|
|
3743
|
+
const next = code.charAt(i);
|
|
3744
|
+
return next !== "" && CONTINUES_BEFORE.includes(next);
|
|
3745
|
+
}
|
|
3746
|
+
function scanDeclaration(code, from) {
|
|
3747
|
+
const commas = [];
|
|
3748
|
+
const stack = [];
|
|
3749
|
+
let prev = "";
|
|
3750
|
+
let i = from;
|
|
3751
|
+
while (i < code.length) {
|
|
3752
|
+
const ch = code.charAt(i);
|
|
3753
|
+
if (stack[stack.length - 1] === "`") {
|
|
3754
|
+
if (ch === "\\") {
|
|
3755
|
+
i += 2;
|
|
3756
|
+
continue;
|
|
3757
|
+
}
|
|
3758
|
+
if (ch === "`") {
|
|
3759
|
+
stack.pop();
|
|
3760
|
+
prev = "`";
|
|
3761
|
+
i += 1;
|
|
3762
|
+
continue;
|
|
3763
|
+
}
|
|
3764
|
+
if (ch === "$" && code.charAt(i + 1) === "{") {
|
|
3765
|
+
stack.push("{");
|
|
3766
|
+
prev = "{";
|
|
3767
|
+
i += 2;
|
|
3768
|
+
continue;
|
|
3769
|
+
}
|
|
3770
|
+
i += 1;
|
|
3771
|
+
continue;
|
|
3772
|
+
}
|
|
3773
|
+
if (ch === "/" && code.charAt(i + 1) === "/") {
|
|
3774
|
+
const newline = code.indexOf("\n", i);
|
|
3775
|
+
i = newline === -1 ? code.length : newline;
|
|
3776
|
+
continue;
|
|
3777
|
+
}
|
|
3778
|
+
if (ch === "/" && code.charAt(i + 1) === "*") {
|
|
3779
|
+
const close = code.indexOf("*/", i + 2);
|
|
3780
|
+
i = close === -1 ? code.length : close + 2;
|
|
3781
|
+
continue;
|
|
3782
|
+
}
|
|
3783
|
+
if (ch === '"' || ch === "'") {
|
|
3784
|
+
i = skipQuoted(code, i);
|
|
3785
|
+
prev = ch;
|
|
3786
|
+
continue;
|
|
3787
|
+
}
|
|
3788
|
+
if (ch === "`") {
|
|
3789
|
+
stack.push("`");
|
|
3790
|
+
i += 1;
|
|
3791
|
+
continue;
|
|
3792
|
+
}
|
|
3793
|
+
if (ch === "/" && regexCanStart(prev)) {
|
|
3794
|
+
i = skipRegex(code, i);
|
|
3795
|
+
prev = "/";
|
|
3796
|
+
continue;
|
|
3797
|
+
}
|
|
3798
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
3799
|
+
stack.push(ch);
|
|
3800
|
+
prev = ch;
|
|
3801
|
+
i += 1;
|
|
3802
|
+
continue;
|
|
3803
|
+
}
|
|
3804
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
3805
|
+
if (stack[stack.length - 1] !== MATCHING_OPEN[ch]) return { commas, end: i };
|
|
3806
|
+
stack.pop();
|
|
3807
|
+
prev = ch;
|
|
3808
|
+
i += 1;
|
|
3809
|
+
continue;
|
|
3810
|
+
}
|
|
3811
|
+
if (stack.length === 0) {
|
|
3812
|
+
if (ch === ";") return { commas, end: i };
|
|
3813
|
+
if (ch === ",") commas.push(i);
|
|
3814
|
+
if (ch === "\n" && !continuesOnto(code, i, prev)) return { commas, end: i };
|
|
3815
|
+
}
|
|
3816
|
+
if (!/\s/.test(ch)) prev = ch;
|
|
3817
|
+
i += 1;
|
|
3818
|
+
}
|
|
3819
|
+
return { commas, end: code.length };
|
|
3820
|
+
}
|
|
3821
|
+
function declaratorName(segment) {
|
|
3822
|
+
const match = /^\s*([A-Za-z_$][\w$]*)\s*(?:=(?![=>])|$)/.exec(segment);
|
|
3823
|
+
return match === null ? null : match[1] ?? null;
|
|
3824
|
+
}
|
|
3825
|
+
function restDeclarators(code, from) {
|
|
3826
|
+
const { commas, end } = scanDeclaration(code, from);
|
|
3827
|
+
if (commas.length === 0) return [];
|
|
3828
|
+
const segments = [];
|
|
3829
|
+
let cursor = from;
|
|
3830
|
+
for (const comma of commas) {
|
|
3831
|
+
segments.push(code.slice(cursor, comma));
|
|
3832
|
+
cursor = comma + 1;
|
|
3833
|
+
}
|
|
3834
|
+
segments.push(code.slice(cursor, end));
|
|
3835
|
+
const names = [];
|
|
3836
|
+
for (const segment of segments.slice(1)) {
|
|
3837
|
+
const name = declaratorName(segment);
|
|
3838
|
+
if (name === null) {
|
|
3839
|
+
throw new Error(
|
|
3840
|
+
`\u4E0D\u652F\u6301\u7684\u5BFC\u51FA\u58F0\u660E\u5F62\u6001\uFF1A"${segment.trim()}"\uFF08\u6C99\u7BB1\u5B50\u96C6\u4EC5\u63A5\u53D7\u9017\u53F7\u5206\u9694\u7684\u7B80\u5355\u6807\u8BC6\u7B26\u58F0\u660E\uFF0C\u5982 \`export const a = 1, b = 2\`\uFF1B\u542B\u89E3\u6784\u6216\u590D\u6742\u521D\u503C\u65F6\u8BF7\u62C6\u6210\u591A\u6761 export\uFF09`
|
|
3841
|
+
);
|
|
3842
|
+
}
|
|
3843
|
+
names.push(name);
|
|
3844
|
+
}
|
|
3845
|
+
return names;
|
|
3846
|
+
}
|
|
3601
3847
|
function transformModule(code) {
|
|
3602
3848
|
let out = code;
|
|
3603
3849
|
const named = [];
|
|
@@ -3660,10 +3906,20 @@ function transformModule(code) {
|
|
|
3660
3906
|
return `${lead}${indent}const ${temp} = require(${source})${pad}`;
|
|
3661
3907
|
}
|
|
3662
3908
|
);
|
|
3909
|
+
const destructured = /(^|\n)[ \t]*export\s+(const|let|var)\s*[{[]/.exec(out);
|
|
3910
|
+
if (destructured !== null) {
|
|
3911
|
+
const offset = destructured.index + (destructured[1] === "\n" ? 1 : 0);
|
|
3912
|
+
throw new Error(
|
|
3913
|
+
`\u4E0D\u652F\u6301\u7684\u5BFC\u51FA\u58F0\u660E\u5F62\u6001\uFF08\u7B2C ${lineNumberAt(out, offset)} \u884C\uFF09\uFF1A\u89E3\u6784\u5BFC\u51FA \`export ${destructured[2] ?? ""} { \u2026 } = \u2026\`\u3002\u6C99\u7BB1\u5B50\u96C6\u4EC5\u63A5\u53D7\u7B80\u5355\u6807\u8BC6\u7B26\u58F0\u660E\uFF1A\u8BF7\u5148\u58F0\u660E\u518D \`export { a, b }\`\uFF0C\u6216\u62C6\u6210\u591A\u6761 \`export const\``
|
|
3914
|
+
);
|
|
3915
|
+
}
|
|
3663
3916
|
out = out.replace(
|
|
3664
3917
|
/export\s+(const|let|var)\s+([A-Za-z_$][\w$]*)/g,
|
|
3665
|
-
(
|
|
3918
|
+
(match, kw, name, offset, source) => {
|
|
3666
3919
|
named.push({ local: name, exported: name });
|
|
3920
|
+
for (const extra of restDeclarators(source, offset + match.length)) {
|
|
3921
|
+
named.push({ local: extra, exported: extra });
|
|
3922
|
+
}
|
|
3667
3923
|
return `${kw} ${name}`;
|
|
3668
3924
|
}
|
|
3669
3925
|
);
|
|
@@ -4340,7 +4596,9 @@ function errorMessageOf2(error) {
|
|
|
4340
4596
|
return String(error);
|
|
4341
4597
|
}
|
|
4342
4598
|
async function normalizeResultBody(value) {
|
|
4343
|
-
if (!(value instanceof Response))
|
|
4599
|
+
if (!(value instanceof Response)) {
|
|
4600
|
+
return coerceAdepHttpEnvelope(value) ?? value;
|
|
4601
|
+
}
|
|
4344
4602
|
const contentType = value.headers.get("content-type") ?? "";
|
|
4345
4603
|
const text = await value.text();
|
|
4346
4604
|
let payload = text;
|
|
@@ -4588,7 +4846,7 @@ function createBearerUserResolver(issuer) {
|
|
|
4588
4846
|
function isRuntimeSource(name) {
|
|
4589
4847
|
return (name.endsWith(".ts") || name.endsWith(".js")) && !name.endsWith(".d.ts") && !name.endsWith(".test.ts");
|
|
4590
4848
|
}
|
|
4591
|
-
async function collectFunctions(dir) {
|
|
4849
|
+
async function collectFunctions(dir, readImpl = (path) => readFile6(path, "utf8")) {
|
|
4592
4850
|
const files = {};
|
|
4593
4851
|
const walk = async (sub, prefix) => {
|
|
4594
4852
|
let entries;
|
|
@@ -4603,7 +4861,8 @@ async function collectFunctions(dir) {
|
|
|
4603
4861
|
if (entry.isDirectory()) {
|
|
4604
4862
|
await walk(full, rel);
|
|
4605
4863
|
} else if (entry.isFile() && isRuntimeSource(entry.name)) {
|
|
4606
|
-
|
|
4864
|
+
const content = await readImpl(full).catch(() => null);
|
|
4865
|
+
if (content !== null) files[rel] = content;
|
|
4607
4866
|
}
|
|
4608
4867
|
}
|
|
4609
4868
|
};
|
|
@@ -4679,7 +4938,8 @@ async function loadConfig(cwd) {
|
|
|
4679
4938
|
name: config?.name ?? name,
|
|
4680
4939
|
functionsDir: config?.functionsDir ?? "functions",
|
|
4681
4940
|
functionsPrefix: config?.functions_prefix ?? "",
|
|
4682
|
-
...config?.environment === void 0 ? {} : { environment: config.environment }
|
|
4941
|
+
...config?.environment === void 0 ? {} : { environment: config.environment },
|
|
4942
|
+
...config?.db_environment === void 0 ? {} : { dbEnvironment: config.db_environment }
|
|
4683
4943
|
};
|
|
4684
4944
|
}
|
|
4685
4945
|
var parseEnvFile = parseEnv;
|
package/dist/worker-entry.js
CHANGED
|
@@ -127,6 +127,158 @@ function parseExportClause(clause) {
|
|
|
127
127
|
}
|
|
128
128
|
return entries;
|
|
129
129
|
}
|
|
130
|
+
var CONTINUES_AFTER = "=+-*/%&|^<>?:,.[(";
|
|
131
|
+
var CONTINUES_BEFORE = "`([.?:,+-*/%&|^<>=";
|
|
132
|
+
var REGEX_PRECEDERS = "(,=:[!&|?{};+-*%~^<>";
|
|
133
|
+
var MATCHING_OPEN = { ")": "(", "]": "[", "}": "{" };
|
|
134
|
+
function lineNumberAt(code, index) {
|
|
135
|
+
let line = 1;
|
|
136
|
+
for (let i = 0; i < index; i += 1) if (code.charCodeAt(i) === 10) line += 1;
|
|
137
|
+
return line;
|
|
138
|
+
}
|
|
139
|
+
function skipQuoted(code, start) {
|
|
140
|
+
const quote = code.charAt(start);
|
|
141
|
+
let i = start + 1;
|
|
142
|
+
while (i < code.length) {
|
|
143
|
+
const ch = code.charAt(i);
|
|
144
|
+
if (ch === "\\") {
|
|
145
|
+
i += 2;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (ch === quote) return i + 1;
|
|
149
|
+
if (ch === "\n") return i;
|
|
150
|
+
i += 1;
|
|
151
|
+
}
|
|
152
|
+
return code.length;
|
|
153
|
+
}
|
|
154
|
+
function skipRegex(code, start) {
|
|
155
|
+
let i = start + 1;
|
|
156
|
+
let inClass = false;
|
|
157
|
+
while (i < code.length) {
|
|
158
|
+
const ch = code.charAt(i);
|
|
159
|
+
if (ch === "\\") {
|
|
160
|
+
i += 2;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (ch === "\n") return start + 1;
|
|
164
|
+
if (ch === "[") inClass = true;
|
|
165
|
+
else if (ch === "]") inClass = false;
|
|
166
|
+
else if (ch === "/" && !inClass) return i + 1;
|
|
167
|
+
i += 1;
|
|
168
|
+
}
|
|
169
|
+
return code.length;
|
|
170
|
+
}
|
|
171
|
+
function regexCanStart(prev) {
|
|
172
|
+
return prev === "" || REGEX_PRECEDERS.includes(prev);
|
|
173
|
+
}
|
|
174
|
+
function continuesOnto(code, newline, prev) {
|
|
175
|
+
if (prev !== "" && CONTINUES_AFTER.includes(prev)) return true;
|
|
176
|
+
let i = newline + 1;
|
|
177
|
+
while (i < code.length && /\s/.test(code.charAt(i))) i += 1;
|
|
178
|
+
const next = code.charAt(i);
|
|
179
|
+
return next !== "" && CONTINUES_BEFORE.includes(next);
|
|
180
|
+
}
|
|
181
|
+
function scanDeclaration(code, from) {
|
|
182
|
+
const commas = [];
|
|
183
|
+
const stack = [];
|
|
184
|
+
let prev = "";
|
|
185
|
+
let i = from;
|
|
186
|
+
while (i < code.length) {
|
|
187
|
+
const ch = code.charAt(i);
|
|
188
|
+
if (stack[stack.length - 1] === "`") {
|
|
189
|
+
if (ch === "\\") {
|
|
190
|
+
i += 2;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (ch === "`") {
|
|
194
|
+
stack.pop();
|
|
195
|
+
prev = "`";
|
|
196
|
+
i += 1;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (ch === "$" && code.charAt(i + 1) === "{") {
|
|
200
|
+
stack.push("{");
|
|
201
|
+
prev = "{";
|
|
202
|
+
i += 2;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
i += 1;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (ch === "/" && code.charAt(i + 1) === "/") {
|
|
209
|
+
const newline = code.indexOf("\n", i);
|
|
210
|
+
i = newline === -1 ? code.length : newline;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (ch === "/" && code.charAt(i + 1) === "*") {
|
|
214
|
+
const close = code.indexOf("*/", i + 2);
|
|
215
|
+
i = close === -1 ? code.length : close + 2;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (ch === '"' || ch === "'") {
|
|
219
|
+
i = skipQuoted(code, i);
|
|
220
|
+
prev = ch;
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (ch === "`") {
|
|
224
|
+
stack.push("`");
|
|
225
|
+
i += 1;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (ch === "/" && regexCanStart(prev)) {
|
|
229
|
+
i = skipRegex(code, i);
|
|
230
|
+
prev = "/";
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
234
|
+
stack.push(ch);
|
|
235
|
+
prev = ch;
|
|
236
|
+
i += 1;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
240
|
+
if (stack[stack.length - 1] !== MATCHING_OPEN[ch]) return { commas, end: i };
|
|
241
|
+
stack.pop();
|
|
242
|
+
prev = ch;
|
|
243
|
+
i += 1;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (stack.length === 0) {
|
|
247
|
+
if (ch === ";") return { commas, end: i };
|
|
248
|
+
if (ch === ",") commas.push(i);
|
|
249
|
+
if (ch === "\n" && !continuesOnto(code, i, prev)) return { commas, end: i };
|
|
250
|
+
}
|
|
251
|
+
if (!/\s/.test(ch)) prev = ch;
|
|
252
|
+
i += 1;
|
|
253
|
+
}
|
|
254
|
+
return { commas, end: code.length };
|
|
255
|
+
}
|
|
256
|
+
function declaratorName(segment) {
|
|
257
|
+
const match = /^\s*([A-Za-z_$][\w$]*)\s*(?:=(?![=>])|$)/.exec(segment);
|
|
258
|
+
return match === null ? null : match[1] ?? null;
|
|
259
|
+
}
|
|
260
|
+
function restDeclarators(code, from) {
|
|
261
|
+
const { commas, end } = scanDeclaration(code, from);
|
|
262
|
+
if (commas.length === 0) return [];
|
|
263
|
+
const segments = [];
|
|
264
|
+
let cursor = from;
|
|
265
|
+
for (const comma of commas) {
|
|
266
|
+
segments.push(code.slice(cursor, comma));
|
|
267
|
+
cursor = comma + 1;
|
|
268
|
+
}
|
|
269
|
+
segments.push(code.slice(cursor, end));
|
|
270
|
+
const names = [];
|
|
271
|
+
for (const segment of segments.slice(1)) {
|
|
272
|
+
const name = declaratorName(segment);
|
|
273
|
+
if (name === null) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
`\u4E0D\u652F\u6301\u7684\u5BFC\u51FA\u58F0\u660E\u5F62\u6001\uFF1A"${segment.trim()}"\uFF08\u6C99\u7BB1\u5B50\u96C6\u4EC5\u63A5\u53D7\u9017\u53F7\u5206\u9694\u7684\u7B80\u5355\u6807\u8BC6\u7B26\u58F0\u660E\uFF0C\u5982 \`export const a = 1, b = 2\`\uFF1B\u542B\u89E3\u6784\u6216\u590D\u6742\u521D\u503C\u65F6\u8BF7\u62C6\u6210\u591A\u6761 export\uFF09`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
names.push(name);
|
|
279
|
+
}
|
|
280
|
+
return names;
|
|
281
|
+
}
|
|
130
282
|
function transformModule(code) {
|
|
131
283
|
let out = code;
|
|
132
284
|
const named = [];
|
|
@@ -189,10 +341,20 @@ function transformModule(code) {
|
|
|
189
341
|
return `${lead}${indent}const ${temp} = require(${source})${pad}`;
|
|
190
342
|
}
|
|
191
343
|
);
|
|
344
|
+
const destructured = /(^|\n)[ \t]*export\s+(const|let|var)\s*[{[]/.exec(out);
|
|
345
|
+
if (destructured !== null) {
|
|
346
|
+
const offset = destructured.index + (destructured[1] === "\n" ? 1 : 0);
|
|
347
|
+
throw new Error(
|
|
348
|
+
`\u4E0D\u652F\u6301\u7684\u5BFC\u51FA\u58F0\u660E\u5F62\u6001\uFF08\u7B2C ${lineNumberAt(out, offset)} \u884C\uFF09\uFF1A\u89E3\u6784\u5BFC\u51FA \`export ${destructured[2] ?? ""} { \u2026 } = \u2026\`\u3002\u6C99\u7BB1\u5B50\u96C6\u4EC5\u63A5\u53D7\u7B80\u5355\u6807\u8BC6\u7B26\u58F0\u660E\uFF1A\u8BF7\u5148\u58F0\u660E\u518D \`export { a, b }\`\uFF0C\u6216\u62C6\u6210\u591A\u6761 \`export const\``
|
|
349
|
+
);
|
|
350
|
+
}
|
|
192
351
|
out = out.replace(
|
|
193
352
|
/export\s+(const|let|var)\s+([A-Za-z_$][\w$]*)/g,
|
|
194
|
-
(
|
|
353
|
+
(match, kw, name, offset, source) => {
|
|
195
354
|
named.push({ local: name, exported: name });
|
|
355
|
+
for (const extra of restDeclarators(source, offset + match.length)) {
|
|
356
|
+
named.push({ local: extra, exported: extra });
|
|
357
|
+
}
|
|
196
358
|
return `${kw} ${name}`;
|
|
197
359
|
}
|
|
198
360
|
);
|
|
@@ -594,6 +756,8 @@ var DB_RPC = {
|
|
|
594
756
|
query: "query",
|
|
595
757
|
/** 写路径(CF-013):`(method=writeQuery, args=[sql, params])` → `{ changes }`。 */
|
|
596
758
|
writeQuery: "writeQuery",
|
|
759
|
+
/** 通用执行(BUG-4,2026-10-14):`(method=execute, args=[sql, params?])` → `{ changes }`。 */
|
|
760
|
+
execute: "execute",
|
|
597
761
|
/** 读取 owned 表变更流(DB-006):`(method=changes, args=[table, query])`。 */
|
|
598
762
|
changes: "changes",
|
|
599
763
|
/** 开启事务:`begin → txId`。 */
|
|
@@ -732,6 +896,39 @@ function createChainClient(capability, port, pending, nextId, spec) {
|
|
|
732
896
|
return makeRoot(void 0);
|
|
733
897
|
}
|
|
734
898
|
|
|
899
|
+
// packages/runtime/src/shared/http-envelope.ts
|
|
900
|
+
function coerceAdepHttpEnvelope(value) {
|
|
901
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
902
|
+
if (isAdepHttpEnvelope(value)) return value;
|
|
903
|
+
const keys = Object.keys(value);
|
|
904
|
+
if (keys.length === 0) return null;
|
|
905
|
+
if (!keys.every((key) => key === "status" || key === "body" || key === "headers")) return null;
|
|
906
|
+
const candidate = value;
|
|
907
|
+
const status = candidate.status;
|
|
908
|
+
if (typeof status !== "number" || !Number.isInteger(status) || status < 100 || status > 599) {
|
|
909
|
+
return null;
|
|
910
|
+
}
|
|
911
|
+
if ("headers" in candidate && candidate.headers !== void 0) {
|
|
912
|
+
const headers = candidate.headers;
|
|
913
|
+
if (typeof headers !== "object" || headers === null || Array.isArray(headers)) return null;
|
|
914
|
+
if (!Object.values(headers).every((headerValue2) => typeof headerValue2 === "string")) return null;
|
|
915
|
+
}
|
|
916
|
+
return {
|
|
917
|
+
__adepHttp: {
|
|
918
|
+
status,
|
|
919
|
+
...candidate.headers === void 0 ? {} : { headers: candidate.headers },
|
|
920
|
+
body: candidate.body
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
function isAdepHttpEnvelope(value) {
|
|
925
|
+
if (typeof value !== "object" || value === null) return false;
|
|
926
|
+
const envelope = value.__adepHttp;
|
|
927
|
+
if (typeof envelope !== "object" || envelope === null) return false;
|
|
928
|
+
const status = envelope.status;
|
|
929
|
+
return typeof status === "number" && Number.isInteger(status) && status >= 100 && status <= 599;
|
|
930
|
+
}
|
|
931
|
+
|
|
735
932
|
// packages/runtime/src/functions/deps/manifest.ts
|
|
736
933
|
function splitBareSpecifier(request) {
|
|
737
934
|
if (request.startsWith("@")) {
|
|
@@ -751,7 +948,9 @@ function errorMessageOf2(error) {
|
|
|
751
948
|
return String(error);
|
|
752
949
|
}
|
|
753
950
|
async function normalizeResultBody(value) {
|
|
754
|
-
if (!(value instanceof Response))
|
|
951
|
+
if (!(value instanceof Response)) {
|
|
952
|
+
return coerceAdepHttpEnvelope(value) ?? value;
|
|
953
|
+
}
|
|
755
954
|
const contentType = value.headers.get("content-type") ?? "";
|
|
756
955
|
const text = await value.text();
|
|
757
956
|
let payload = text;
|