@adep/cli 0.1.9 → 0.1.11

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.
Files changed (4) hide show
  1. package/README.md +2 -0
  2. package/dist/index.js +3189 -2422
  3. package/dist/vite.js +378 -49
  4. package/package.json +4 -3
package/dist/vite.js CHANGED
@@ -1138,6 +1138,7 @@ function stripQuotes(raw) {
1138
1138
  const t = raw.trim();
1139
1139
  if (/^'.*'$/.test(t)) return t.slice(1, -1);
1140
1140
  if (/^".*"$/.test(t)) return t.slice(1, -1);
1141
+ if (/^NULL$/i.test(t)) return null;
1141
1142
  return t;
1142
1143
  }
1143
1144
  function parseCreateTable(ddl) {
@@ -1158,50 +1159,109 @@ function parseCreateTable(ddl) {
1158
1159
  }
1159
1160
  return { name, columns };
1160
1161
  }
1161
- function parseWhereClauses(whereRaw, cursor) {
1162
- const clauses = [];
1163
- for (const part of whereRaw.split(/\s+AND\s+/i)) {
1164
- const t = part.trim();
1165
- if (t.length === 0) continue;
1166
- if (/\bIS\s+NULL\b/i.test(t)) {
1167
- const col2 = ident(t.split(/\s+IS\s+NULL\b/i)[0] ?? "");
1168
- clauses.push({ column: col2, operator: "IS NULL", value: null, list: false });
1169
- continue;
1170
- }
1171
- if (/\bIS\s+NOT\s+NULL\b/i.test(t)) {
1172
- const col2 = ident(t.split(/\s+IS\s+NOT\s+NULL\b/i)[0] ?? "");
1173
- clauses.push({ column: col2, operator: "IS NOT NULL", value: null, list: false });
1174
- continue;
1175
- }
1176
- const opMatch = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))\s*(=|!=|>=|<=|>|<|like|in|not\s+in)\s*(.+)$/i.exec(
1177
- t
1178
- );
1179
- if (opMatch === null) continue;
1180
- const col = ident(opMatch[1] ?? "");
1181
- const op = (opMatch[3] ?? opMatch[2] ?? "").toLowerCase();
1182
- const rhs = (opMatch[4] ?? "").trim();
1183
- if (op === "in" || op === "not in") {
1184
- const inner = rhs.replace(/^\(|\)$/g, "");
1185
- const items = splitListItems(inner);
1186
- const list = items.map((item) => {
1187
- if (item.trim() === "?") return cursor.take();
1188
- return stripQuotes(item);
1189
- });
1190
- clauses.push({ column: col, operator: op, value: list, list: true });
1162
+ function splitTopLevel(raw, token) {
1163
+ const parts = [];
1164
+ let depth = 0;
1165
+ let inQuote = false;
1166
+ let buffer = "";
1167
+ const n = raw.length;
1168
+ const isTokenAt = (i) => {
1169
+ const word = raw.slice(i, i + token.length);
1170
+ if (word.toUpperCase() !== token) return false;
1171
+ const before = i === 0 ? "" : raw[i - 1] ?? "";
1172
+ const after = raw[i + token.length] ?? "";
1173
+ return !/[A-Za-z0-9_.]/.test(before) && !/[A-Za-z0-9_.]/.test(after);
1174
+ };
1175
+ for (let i = 0; i < n; i += 1) {
1176
+ const ch = raw[i] ?? "";
1177
+ if (ch === "'") {
1178
+ if (inQuote && raw[i + 1] === "'") {
1179
+ buffer += ch + (raw[i + 1] ?? "");
1180
+ i += 1;
1181
+ continue;
1182
+ }
1183
+ inQuote = !inQuote;
1184
+ buffer += ch;
1191
1185
  continue;
1192
1186
  }
1193
- let value;
1194
- if (rhs === "?") {
1195
- value = cursor.take();
1187
+ if (!inQuote && ch === "(") depth += 1;
1188
+ else if (!inQuote && ch === ")") depth -= 1;
1189
+ if (!inQuote && depth === 0 && isTokenAt(i)) {
1190
+ parts.push(buffer);
1191
+ buffer = "";
1192
+ i += token.length - 1;
1196
1193
  } else {
1197
- value = stripQuotes(rhs);
1194
+ buffer += ch;
1198
1195
  }
1199
- clauses.push({ column: col, operator: op, value, list: false });
1200
1196
  }
1201
- return clauses;
1197
+ parts.push(buffer);
1198
+ return parts;
1202
1199
  }
1203
- function matchWhere(clauses, row) {
1204
- return clauses.every((c) => matchValue(row[c.column], c));
1200
+ function unqualifyColumn(raw) {
1201
+ const t = raw.trim();
1202
+ const dot = t.lastIndexOf(".");
1203
+ if (dot > 0 && /^[A-Za-z_][A-Za-z0-9_]*\./.test(t)) return t.slice(dot + 1);
1204
+ return t;
1205
+ }
1206
+ function parseLeftJoins(tail) {
1207
+ const joins = [];
1208
+ const re = /LEFT\s+JOIN\s+((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))\s+([A-Za-z_][A-Za-z0-9_]*)\s+ON\s+([A-Za-z_][A-Za-z0-9_.]*)\s*=\s*([A-Za-z_][A-Za-z0-9_.]*)/gi;
1209
+ let m;
1210
+ while ((m = re.exec(tail)) !== null) {
1211
+ joins.push({
1212
+ table: ident(m[1] ?? ""),
1213
+ alias: m[3] ?? "",
1214
+ leftCol: unqualifyColumn(m[4] ?? ""),
1215
+ rightCol: unqualifyColumn(m[5] ?? "")
1216
+ });
1217
+ }
1218
+ return joins;
1219
+ }
1220
+ function parseWhereClauses(whereRaw, cursor) {
1221
+ const parseAndGroup = (andRaw) => {
1222
+ const clauses = [];
1223
+ for (const part of splitTopLevel(andRaw, "AND")) {
1224
+ const t = part.trim();
1225
+ if (t.length === 0) continue;
1226
+ if (/\bIS\s+NULL\b/i.test(t)) {
1227
+ clauses.push({ column: unqualifyColumn(ident(t.split(/\s+IS\s+NULL\b/i)[0] ?? "")), operator: "IS NULL", value: null, list: false });
1228
+ continue;
1229
+ }
1230
+ if (/\bIS\s+NOT\s+NULL\b/i.test(t)) {
1231
+ clauses.push({ column: unqualifyColumn(ident(t.split(/\s+IS\s+NOT\s+NULL\b/i)[0] ?? "")), operator: "IS NOT NULL", value: null, list: false });
1232
+ continue;
1233
+ }
1234
+ const opMatch = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_.]*))\s*(=|!=|>=|<=|>|<|like|in|not\s+in)\s*(.+)$/i.exec(
1235
+ t
1236
+ );
1237
+ if (opMatch === null) continue;
1238
+ const col = unqualifyColumn(ident(opMatch[1] ?? ""));
1239
+ const op = (opMatch[3] ?? opMatch[2] ?? "").toLowerCase();
1240
+ const rhs = (opMatch[4] ?? "").trim();
1241
+ if (op === "in" || op === "not in") {
1242
+ const inner = rhs.replace(/^\(|\)$/g, "");
1243
+ const items = splitListItems(inner);
1244
+ const list = items.map((item) => {
1245
+ if (item.trim() === "?") return cursor.take();
1246
+ return stripQuotes(item);
1247
+ });
1248
+ clauses.push({ column: col, operator: op, value: list, list: true });
1249
+ continue;
1250
+ }
1251
+ let value;
1252
+ if (rhs === "?") {
1253
+ value = cursor.take();
1254
+ } else {
1255
+ value = stripQuotes(rhs);
1256
+ }
1257
+ clauses.push({ column: col, operator: op, value, list: false });
1258
+ }
1259
+ return clauses;
1260
+ };
1261
+ return splitTopLevel(whereRaw, "OR").map((group) => group.trim()).filter((group) => group.length > 0).map(parseAndGroup);
1262
+ }
1263
+ function matchWhere(groups, row) {
1264
+ return groups.some((clauses) => clauses.every((c) => matchValue(row[c.column], c)));
1205
1265
  }
1206
1266
  function splitListItems(inner) {
1207
1267
  const items = [];
@@ -1221,6 +1281,168 @@ function splitListItems(inner) {
1221
1281
  items.push(buffer);
1222
1282
  return items;
1223
1283
  }
1284
+ var ExcludedRef = class {
1285
+ constructor(column) {
1286
+ this.column = column;
1287
+ }
1288
+ };
1289
+ var ColumnRef = class {
1290
+ constructor(column) {
1291
+ this.column = column;
1292
+ }
1293
+ };
1294
+ var ExprRef = class {
1295
+ constructor(source) {
1296
+ this.source = source;
1297
+ }
1298
+ };
1299
+ function resolveSetValue(value, existing, row) {
1300
+ if (value instanceof ExcludedRef) return row[value.column];
1301
+ if (value instanceof ColumnRef) return existing[value.column];
1302
+ if (value instanceof ExprRef) return evalArithmetic(value.source, existing, row);
1303
+ return value;
1304
+ }
1305
+ function evalArithmetic(src, existing, row) {
1306
+ const num = (v) => {
1307
+ const n2 = Number(v);
1308
+ return Number.isFinite(n2) ? n2 : 0;
1309
+ };
1310
+ let i = 0;
1311
+ const n = src.length;
1312
+ const skip = () => {
1313
+ while (i < n && /\s/.test(src[i] ?? "")) i += 1;
1314
+ };
1315
+ const peek = () => {
1316
+ skip();
1317
+ return i < n ? src[i] ?? "" : null;
1318
+ };
1319
+ const parseIdent = () => {
1320
+ skip();
1321
+ const m = /^([A-Za-z_][A-Za-z0-9_]*)/.exec(src.slice(i));
1322
+ if (m === null) return null;
1323
+ i += (m[1] ?? "").length;
1324
+ skip();
1325
+ let col = ident(m[1] ?? "");
1326
+ let excluded = false;
1327
+ if (src[i] === ".") {
1328
+ const m2 = /^\.([A-Za-z_][A-Za-z0-9_]*)/.exec(src.slice(i));
1329
+ if (m2 !== null) {
1330
+ i += (m2[0] ?? "").length;
1331
+ if (col.toLowerCase() === "excluded") excluded = true;
1332
+ col = ident(m2[1] ?? "");
1333
+ }
1334
+ }
1335
+ return { col, excluded };
1336
+ };
1337
+ const parseFactor = () => {
1338
+ const ch = peek();
1339
+ if (ch === "(") {
1340
+ i += 1;
1341
+ const v = parseExpr();
1342
+ skip();
1343
+ if (src[i] === ")") i += 1;
1344
+ return v;
1345
+ }
1346
+ const numMatch = /^(\d+(?:\.\d+)?)/.exec(src.slice(i));
1347
+ if (numMatch !== null) {
1348
+ i += (numMatch[1] ?? "").length;
1349
+ return Number(numMatch[1]);
1350
+ }
1351
+ const id = parseIdent();
1352
+ if (id !== null) {
1353
+ const v = id.excluded ? row[id.col] : existing[id.col];
1354
+ return num(v);
1355
+ }
1356
+ return 0;
1357
+ };
1358
+ const parseTerm = () => {
1359
+ let v = parseFactor();
1360
+ for (; ; ) {
1361
+ const ch = peek();
1362
+ if (ch !== "*" && ch !== "/") return v;
1363
+ i += 1;
1364
+ const rhs = parseFactor();
1365
+ v = ch === "*" ? v * rhs : rhs === 0 ? v : v / rhs;
1366
+ }
1367
+ };
1368
+ const parseExpr = () => {
1369
+ let v = parseTerm();
1370
+ for (; ; ) {
1371
+ const ch = peek();
1372
+ if (ch !== "+" && ch !== "-") return v;
1373
+ i += 1;
1374
+ const rhs = parseTerm();
1375
+ v = ch === "+" ? v + rhs : v - rhs;
1376
+ }
1377
+ };
1378
+ return parseExpr();
1379
+ }
1380
+ function splitInsertTuples(body) {
1381
+ const tuples = [];
1382
+ let i = 0;
1383
+ const n = body.length;
1384
+ while (i < n) {
1385
+ while (i < n && (body[i] === " " || body[i] === " " || body[i] === "\n" || body[i] === "\r" || body[i] === ",")) {
1386
+ i += 1;
1387
+ }
1388
+ if (i >= n) break;
1389
+ if (body[i] !== "(") {
1390
+ return { tuples, conflict: body.slice(i).trim() };
1391
+ }
1392
+ let depth = 0;
1393
+ let j = i;
1394
+ for (; j < n; j += 1) {
1395
+ if (body[j] === "(") depth += 1;
1396
+ else if (body[j] === ")") {
1397
+ depth -= 1;
1398
+ if (depth === 0) break;
1399
+ }
1400
+ }
1401
+ if (j >= n) return { tuples, conflict: null };
1402
+ tuples.push(body.slice(i + 1, j));
1403
+ i = j + 1;
1404
+ }
1405
+ return { tuples, conflict: null };
1406
+ }
1407
+ function parseConflictClause(clause, cursor, fallbackCols) {
1408
+ const m = /^ON\s+CONFLICT(?:\s*\(([^)]*)\))?\s+DO\s+(UPDATE\s+SET\s+([\s\S]+)|NOTHING\s*)$/i.exec(
1409
+ clause.trim()
1410
+ );
1411
+ if (m === null) {
1412
+ throw new SimDbError("DB_UNSAFE_OP", `\u65E0\u6CD5\u89E3\u6790 ON CONFLICT \u5B50\u53E5\uFF1A${clause.trim().slice(0, 60)}\u2026`);
1413
+ }
1414
+ const colsRaw = m[1];
1415
+ const cols = colsRaw === void 0 ? fallbackCols : colsRaw.split(",").map(ident);
1416
+ if (cols.length === 0) throw new SimDbError("DB_UNSAFE_OP", "ON CONFLICT \u51B2\u7A81\u5217\u4E3A\u7A7A");
1417
+ const action = m[2] ?? "";
1418
+ if (/^NOTHING/i.test(action)) return { cols, sets: [] };
1419
+ const setRaw = m[3] ?? "";
1420
+ const sets = splitListItems(setRaw).map((part) => {
1421
+ const eq = /^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*([\s\S]+)$/i.exec(part.trim());
1422
+ if (eq === null) {
1423
+ throw new SimDbError("DB_UNSAFE_OP", `\u65E0\u6CD5\u89E3\u6790 SET \u8D4B\u503C\uFF1A${part.trim().slice(0, 60)}\u2026`);
1424
+ }
1425
+ const col = ident(eq[1] ?? "");
1426
+ const rhs = (eq[2] ?? "").trim();
1427
+ let value;
1428
+ if (rhs === "?") {
1429
+ value = cursor.take();
1430
+ } else {
1431
+ const ex = /^excluded\.([A-Za-z_][A-Za-z0-9_]*)$/i.exec(rhs);
1432
+ if (ex !== null) {
1433
+ value = new ExcludedRef(ident(ex[1] ?? ""));
1434
+ } else if (/^([A-Za-z_][A-Za-z0-9_]*)$/.test(rhs) && !/^NULL$/i.test(rhs)) {
1435
+ value = new ColumnRef(ident(rhs));
1436
+ } else if (/^'.*'$/.test(rhs) || /^".*"$/.test(rhs) || /^NULL$/i.test(rhs)) {
1437
+ value = stripQuotes(rhs);
1438
+ } else {
1439
+ value = new ExprRef(rhs);
1440
+ }
1441
+ }
1442
+ return { col, value };
1443
+ });
1444
+ return { cols, sets };
1445
+ }
1224
1446
  function matchValue(value, clause) {
1225
1447
  const op = clause.operator;
1226
1448
  if (op === "IS NULL") return value === null || value === void 0;
@@ -1374,16 +1596,36 @@ var SimSqlEngine = class {
1374
1596
  const valueBody = match[4].trim();
1375
1597
  const cursor = new ParamCursor(params);
1376
1598
  const table = this.ensureTable(tableName);
1599
+ const { tuples, conflict } = splitInsertTuples(valueBody);
1600
+ if (tuples.length === 0) throw new SimDbError("DB_UNSAFE_OP", "INSERT \u7F3A\u5C11 VALUES \u5143\u7EC4");
1601
+ const conflictSpec = conflict === null ? null : parseConflictClause(
1602
+ conflict,
1603
+ cursor,
1604
+ table.columns.filter((c) => c.primaryKey).map((c) => c.name)
1605
+ );
1377
1606
  let inserted = 0;
1378
- for (const group of splitListItems(valueBody)) {
1379
- const inner = group.trim().replace(/^\(|\)$/g, "");
1380
- const values = splitListItems(inner).map(
1607
+ for (const tuple of tuples) {
1608
+ const values = splitListItems(tuple).map(
1381
1609
  (item) => item.trim() === "?" ? cursor.take() : stripQuotes(item)
1382
1610
  );
1383
1611
  const row = {};
1384
1612
  cols.forEach((col, i) => {
1385
1613
  row[col] = values[i] ?? null;
1386
1614
  });
1615
+ if (conflictSpec !== null) {
1616
+ const existing = table.rows.find(
1617
+ (r) => conflictSpec.cols.every((c) => r[c] === row[c])
1618
+ );
1619
+ if (existing !== void 0) {
1620
+ const oldRow = { ...existing };
1621
+ for (const set of conflictSpec.sets) {
1622
+ existing[set.col] = resolveSetValue(set.value, oldRow, row);
1623
+ }
1624
+ inserted += 1;
1625
+ void this.persist();
1626
+ continue;
1627
+ }
1628
+ }
1387
1629
  this.applyAutoincrement(table, row);
1388
1630
  table.rows.push(row);
1389
1631
  inserted += 1;
@@ -1452,6 +1694,20 @@ var SimSqlEngine = class {
1452
1694
  return project(this.catalog(), selectRaw);
1453
1695
  }
1454
1696
  const table = this.ensureTable(tableName);
1697
+ let rows = table.rows;
1698
+ const joins = parseLeftJoins(tail);
1699
+ if (joins.length > 0) {
1700
+ rows = table.rows.map((row) => {
1701
+ const merged = { ...row };
1702
+ for (const j of joins) {
1703
+ const joined = this.tables[j.table]?.rows.find((jr) => jr[j.leftCol] === merged[j.rightCol]);
1704
+ if (joined !== void 0) {
1705
+ for (const [k, v] of Object.entries(joined)) merged[`${j.alias}.${k}`] = v;
1706
+ }
1707
+ }
1708
+ return merged;
1709
+ });
1710
+ }
1455
1711
  const whereMatch = /\bWHERE\b/i.exec(tail);
1456
1712
  const orderMatch = /\bORDER\s+BY\b/i.exec(tail);
1457
1713
  const limitMatch = /\bLIMIT\b/i.exec(tail);
@@ -1460,7 +1716,6 @@ var SimSqlEngine = class {
1460
1716
  whereMatch.index + whereMatch[0].length,
1461
1717
  indexAfter(whereMatch.index, [orderMatch, limitMatch, offsetMatch], tail)
1462
1718
  );
1463
- let rows = table.rows;
1464
1719
  if (whereRaw.trim().length > 0) {
1465
1720
  const clauses = parseWhereClauses(whereRaw, cursor);
1466
1721
  rows = rows.filter((row) => matchWhere(clauses, row));
@@ -1470,9 +1725,9 @@ var SimSqlEngine = class {
1470
1725
  orderMatch.index + orderMatch[0].length,
1471
1726
  indexAfter(orderMatch.index, [limitMatch, offsetMatch], tail)
1472
1727
  );
1473
- const oc = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))\s+(asc|desc)/i.exec(orderRaw);
1728
+ const oc = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_.]*))\s+(asc|desc)/i.exec(orderRaw);
1474
1729
  if (oc !== null) {
1475
- const col = ident(oc[1]);
1730
+ const col = unqualifyColumn(ident(oc[1]));
1476
1731
  const dir = oc[3].toLowerCase();
1477
1732
  rows = [...rows].toSorted((a, b) => {
1478
1733
  const av = a[col];
@@ -1517,6 +1772,15 @@ function indexAfter(start, matches, tail) {
1517
1772
  const end = candidates.length === 0 ? -1 : Math.min(...candidates);
1518
1773
  return end === -1 ? tail.length : end;
1519
1774
  }
1775
+ function parseSelectItem(raw) {
1776
+ const t = raw.trim();
1777
+ const as = /\s+AS\s+([A-Za-z_][A-Za-z0-9_]*)$/i.exec(t);
1778
+ let name = as === null ? t : t.slice(0, as.index).trim();
1779
+ if (unqualifyColumn(name) === "*") return { name: "", qualified: "", alias: "", star: true };
1780
+ const qualified = /^[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*$/.test(name) ? ident(name) : "";
1781
+ const plain = unqualifyColumn(ident(name));
1782
+ return { name: plain, qualified, alias: as === null ? plain : ident(as[1] ?? ""), star: false };
1783
+ }
1520
1784
  function project(rows, selectRaw) {
1521
1785
  if (/^count\s*\(\s*\*/i.test(selectRaw) || /^count\s*\(\s*1\)/i.test(selectRaw)) {
1522
1786
  const alias = selectRaw.match(/\bAS\s+([A-Za-z_][A-Za-z0-9_]*)/i)?.[1] ?? "n";
@@ -1527,10 +1791,21 @@ function project(rows, selectRaw) {
1527
1791
  return [{ [constMatch[2]]: Number(constMatch[1]) }];
1528
1792
  }
1529
1793
  if (selectRaw.trim() === "*") return rows;
1530
- const cols = selectRaw.split(",").map((s) => ident(s.trim()));
1794
+ const items = selectRaw.split(",").map(parseSelectItem);
1795
+ const valueOf = (row, item) => item.qualified !== "" && row[item.qualified] !== void 0 ? row[item.qualified] : row[item.name];
1796
+ if (items.some((item) => item.star)) {
1797
+ return rows.map((row) => {
1798
+ const out = { ...row };
1799
+ for (const item of items) {
1800
+ if (item.star) continue;
1801
+ out[item.alias] = valueOf(row, item);
1802
+ }
1803
+ return out;
1804
+ });
1805
+ }
1531
1806
  return rows.map((row) => {
1532
1807
  const out = {};
1533
- for (const col of cols) out[col] = row[col];
1808
+ for (const item of items) out[item.alias] = valueOf(row, item);
1534
1809
  return out;
1535
1810
  });
1536
1811
  }
@@ -2389,6 +2664,18 @@ function resolveFunctionEntry(files, fnName) {
2389
2664
  if (files[directory] !== void 0) return directory;
2390
2665
  return void 0;
2391
2666
  }
2667
+ function listFunctionNames(files) {
2668
+ const names = /* @__PURE__ */ new Set();
2669
+ for (const key of Object.keys(files)) {
2670
+ const parts = key.split("/");
2671
+ if (parts.length === 1 && parts[0] !== void 0 && parts[0].endsWith(".ts")) {
2672
+ names.add(parts[0].slice(0, -3));
2673
+ } else if (parts.length === 2 && parts[1] === "index.ts" && parts[0] !== void 0) {
2674
+ names.add(parts[0]);
2675
+ }
2676
+ }
2677
+ return [...names];
2678
+ }
2392
2679
  function createSimInvokeHandler(options) {
2393
2680
  return async (method, args) => {
2394
2681
  if (method !== "invoke") {
@@ -3681,6 +3968,27 @@ if (workerPort !== null && workerData !== void 0) {
3681
3968
  // packages/cli/src/dev-shared.ts
3682
3969
  import { readdir as readdir2, readFile as readFile5 } from "node:fs/promises";
3683
3970
  import { join as join8 } from "node:path";
3971
+
3972
+ // packages/runtime/src/shared/function-source.ts
3973
+ var SHARED_SOURCE_ROOT = "functions/_shared/";
3974
+ var FUNCTION_SHARED_DIR = "_shared/";
3975
+ function mergeSharedSource(files, shared) {
3976
+ const merged = { ...files };
3977
+ for (const file of shared) {
3978
+ if (!file.path.startsWith(SHARED_SOURCE_ROOT)) continue;
3979
+ const rel = file.path.slice(SHARED_SOURCE_ROOT.length);
3980
+ if (rel === "") continue;
3981
+ merged[`${FUNCTION_SHARED_DIR}${rel}`] = file.content;
3982
+ }
3983
+ return merged;
3984
+ }
3985
+
3986
+ // shared/shared-source.ts
3987
+ var FUNCTION_SHARED_DIR2 = "_shared";
3988
+ var SHARED_SOURCE_ROOT2 = `functions/${FUNCTION_SHARED_DIR2}/`;
3989
+ var FUNCTION_SHARED_MAX_TOTAL_BYTES = 256 * 1024;
3990
+
3991
+ // packages/cli/src/dev-shared.ts
3684
3992
  var BEARER_TOKEN_RE = /^Bearer\s+(.+)$/i;
3685
3993
  function bearerUserResolverFromEnv() {
3686
3994
  const raw = process.env.ADEP_AUTH_ISSUER;
@@ -3708,6 +4016,9 @@ function createBearerUserResolver(issuer) {
3708
4016
  }
3709
4017
  };
3710
4018
  }
4019
+ function isRuntimeSource(name) {
4020
+ return (name.endsWith(".ts") || name.endsWith(".js")) && !name.endsWith(".d.ts") && !name.endsWith(".test.ts");
4021
+ }
3711
4022
  async function collectFunctions(dir) {
3712
4023
  const files = {};
3713
4024
  const walk = async (sub, prefix) => {
@@ -3722,7 +4033,7 @@ async function collectFunctions(dir) {
3722
4033
  const full = join8(sub, entry.name);
3723
4034
  if (entry.isDirectory()) {
3724
4035
  await walk(full, rel);
3725
- } else if (entry.isFile() && entry.name.endsWith(".ts")) {
4036
+ } else if (entry.isFile() && isRuntimeSource(entry.name)) {
3726
4037
  files[rel] = await readFile5(full, "utf8");
3727
4038
  }
3728
4039
  }
@@ -3730,6 +4041,24 @@ async function collectFunctions(dir) {
3730
4041
  await walk(dir, "");
3731
4042
  return files;
3732
4043
  }
4044
+ function mergeSharedIntoFunctions(files) {
4045
+ const shared = [];
4046
+ for (const [path, content] of Object.entries(files)) {
4047
+ if (!path.startsWith(`${FUNCTION_SHARED_DIR2}/`)) continue;
4048
+ shared.push({
4049
+ path: `${SHARED_SOURCE_ROOT2}${path.slice(FUNCTION_SHARED_DIR2.length + 1)}`,
4050
+ content
4051
+ });
4052
+ }
4053
+ if (shared.length === 0) return files;
4054
+ const inFunction = mergeSharedSource({}, shared);
4055
+ const out = { ...files };
4056
+ for (const name of listFunctionNames(files)) {
4057
+ if (name.startsWith("_") || files[`${name}/index.ts`] === void 0) continue;
4058
+ for (const [rel, content] of Object.entries(inFunction)) out[`${name}/${rel}`] = content;
4059
+ }
4060
+ return out;
4061
+ }
3733
4062
  function bodyOf(req) {
3734
4063
  return new Promise((resolveBody, rejectBody) => {
3735
4064
  const chunks = [];
@@ -3847,7 +4176,7 @@ async function startDevServer(options) {
3847
4176
  log
3848
4177
  });
3849
4178
  await ensureGitignore(cwd);
3850
- let files = await collectFunctions(functionsDir);
4179
+ let files = mergeSharedIntoFunctions(await collectFunctions(functionsDir));
3851
4180
  let env = {
3852
4181
  ...config.environment,
3853
4182
  ...await loadSimEnv(cwd).catch(() => ({}))
@@ -3925,7 +4254,7 @@ async function startDevServer(options) {
3925
4254
  };
3926
4255
  const reload = async () => {
3927
4256
  const [nextFiles, envText2] = await Promise.all([
3928
- collectFunctions(functionsDir),
4257
+ collectFunctions(functionsDir).then(mergeSharedIntoFunctions),
3929
4258
  readFile6(join9(cwd, ".env.local"), "utf8").catch(() => "")
3930
4259
  ]);
3931
4260
  files = nextFiles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adep/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "description": "`adep` 命令行工具包位:登录 / 初始化 / 本地调试 / 部署 / 数据库维护 / 云存储 / 静态托管 / 微前端组件(widget),实现见任务单 CLI-001 ~ CLI-003 与 FE-002;子路径 `@adep/cli/vite` 提供云函数 vite 插件(CLI-014)",
6
6
  "bin": {
@@ -21,15 +21,16 @@
21
21
  "commander": "14.0.2",
22
22
  "esbuild": "0.25.12",
23
23
  "@adep/cf-compat": "0.1.1",
24
- "@adep/vite-plugin": "0.1.3"
24
+ "@adep/vite-plugin": "0.1.5"
25
25
  },
26
26
  "devDependencies": {
27
- "@adep/runtime": "0.2.3",
27
+ "@adep/runtime": "0.2.5",
28
28
  "@adep/types": "0.2.3"
29
29
  },
30
30
  "scripts": {
31
31
  "test": "vitest run",
32
32
  "init": "bun run src/index.ts init --template fullstack example1",
33
+ "gen:templates": "bun run scripts/build-templates.mjs",
33
34
  "build": "bun run ../../scripts/build-package.ts cli"
34
35
  }
35
36
  }