@openpkg-ts/sdk 0.51.0 → 0.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/index.d.ts +163 -49
- package/dist/index.js +1069 -203
- package/package.json +8 -4
package/dist/index.js
CHANGED
|
@@ -83,9 +83,70 @@ function mergeConfig(fileConfig, cliOptions) {
|
|
|
83
83
|
...hasExternals ? { externals } : {},
|
|
84
84
|
followExternal: cliOptions.followExternal ?? fileConfig.followExternal,
|
|
85
85
|
only: cliOptions.only ?? fileConfig.only,
|
|
86
|
-
ignore: cliOptions.ignore ?? fileConfig.ignore
|
|
86
|
+
ignore: cliOptions.ignore ?? fileConfig.ignore,
|
|
87
|
+
decisions: cliOptions.decisions ?? fileConfig.decisions
|
|
87
88
|
};
|
|
88
89
|
}
|
|
90
|
+
// src/core/decisions.ts
|
|
91
|
+
var JEV_MODEL = "typesafe-ai/jev";
|
|
92
|
+
var JEV_CONFIDENCE = 0.5;
|
|
93
|
+
var MAX_JEV_QUESTIONS = 50;
|
|
94
|
+
async function loadEvaluate() {
|
|
95
|
+
try {
|
|
96
|
+
const specifier = "ai";
|
|
97
|
+
const mod = await import(specifier);
|
|
98
|
+
if (typeof mod.experimental_evaluate !== "function") {
|
|
99
|
+
throw new Error("ai.experimental_evaluate is not a function");
|
|
100
|
+
}
|
|
101
|
+
return (request) => mod.experimental_evaluate({
|
|
102
|
+
...request,
|
|
103
|
+
providerOptions: {
|
|
104
|
+
gateway: { zeroDataRetention: true },
|
|
105
|
+
...request.providerOptions
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
} catch (err) {
|
|
109
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
110
|
+
throw new Error(`--jev requires the ai package (AI SDK ≥7.0.105): bun add ai
|
|
111
|
+
${msg}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function namedConfidence(result, id) {
|
|
115
|
+
const named = result.providerMetadata?.typesafe?.confidence?.[id];
|
|
116
|
+
return typeof named === "number" ? named : undefined;
|
|
117
|
+
}
|
|
118
|
+
function choiceConfidence(result, id, choice) {
|
|
119
|
+
const named = namedConfidence(result, id);
|
|
120
|
+
if (named !== undefined)
|
|
121
|
+
return named;
|
|
122
|
+
const p = result.answers[id]?.probabilities?.[choice];
|
|
123
|
+
return typeof p === "number" ? p : 0;
|
|
124
|
+
}
|
|
125
|
+
async function jevEvaluate(evaluate, state, questions) {
|
|
126
|
+
return evaluate({
|
|
127
|
+
model: JEV_MODEL,
|
|
128
|
+
state: JSON.parse(JSON.stringify(state)),
|
|
129
|
+
questions,
|
|
130
|
+
providerOptions: { gateway: { zeroDataRetention: true } }
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async function jevChoice(args) {
|
|
134
|
+
const keys = Object.keys(args.criteria);
|
|
135
|
+
if (keys.length < 2)
|
|
136
|
+
return null;
|
|
137
|
+
const id = args.id ?? "choice";
|
|
138
|
+
const result = await jevEvaluate(args.evaluate, args.state, {
|
|
139
|
+
[id]: {
|
|
140
|
+
type: "choice",
|
|
141
|
+
instructions: args.instructions,
|
|
142
|
+
criteria: args.criteria
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
const choice = result.answers[id]?.choice;
|
|
146
|
+
if (!choice || !(choice in args.criteria))
|
|
147
|
+
return null;
|
|
148
|
+
return { choice, confidence: choiceConfidence(result, id, choice) };
|
|
149
|
+
}
|
|
89
150
|
// src/core/loader.ts
|
|
90
151
|
import * as fs2 from "node:fs";
|
|
91
152
|
import { validateSpec } from "@openpkg-ts/spec";
|
|
@@ -1200,6 +1261,584 @@ function extractModuleName(exp) {
|
|
|
1200
1261
|
}
|
|
1201
1262
|
return;
|
|
1202
1263
|
}
|
|
1264
|
+
// src/core/resolve-target.ts
|
|
1265
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
1266
|
+
import * as fs3 from "node:fs";
|
|
1267
|
+
import * as os from "node:os";
|
|
1268
|
+
import * as path2 from "node:path";
|
|
1269
|
+
var SKIP_DIRS = new Set(["node_modules", "dist", ".git", "target", "coverage", ".next", "out"]);
|
|
1270
|
+
var CONV = ["src/index.ts", "src/index.tsx", "src/index.mts", "index.ts", "index.tsx"];
|
|
1271
|
+
var ENTRY_EXT = /\.(c|m)?[tj]sx?$/;
|
|
1272
|
+
var MAX_PACKAGES = 200;
|
|
1273
|
+
function isRemoteInput(input) {
|
|
1274
|
+
return /^(https?:\/\/|git@|github\.com\/)/i.test(input);
|
|
1275
|
+
}
|
|
1276
|
+
function isEntryFilePath(input) {
|
|
1277
|
+
return ENTRY_EXT.test(input) || /\.d\.(ts|mts|cts)$/.test(input);
|
|
1278
|
+
}
|
|
1279
|
+
function parseGithubRepo(input) {
|
|
1280
|
+
const trimmed = input.trim().replace(/\.git$/, "");
|
|
1281
|
+
const https = trimmed.match(/github\.com[/:]([^/]+)\/([^/#?]+)/i);
|
|
1282
|
+
if (!https)
|
|
1283
|
+
return null;
|
|
1284
|
+
return { owner: https[1], repo: https[2] };
|
|
1285
|
+
}
|
|
1286
|
+
function runCmd(cmd, args) {
|
|
1287
|
+
return new Promise((resolve2, reject) => {
|
|
1288
|
+
const child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
1289
|
+
let stderr = "";
|
|
1290
|
+
child.stderr.on("data", (chunk) => {
|
|
1291
|
+
stderr += String(chunk);
|
|
1292
|
+
});
|
|
1293
|
+
child.on("error", reject);
|
|
1294
|
+
child.on("close", (code) => {
|
|
1295
|
+
if (code === 0)
|
|
1296
|
+
resolve2();
|
|
1297
|
+
else
|
|
1298
|
+
reject(new Error(`${cmd} ${args.join(" ")} failed: ${stderr.trim() || code}`));
|
|
1299
|
+
});
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
function whichCmd(cmd) {
|
|
1303
|
+
const checker = process.platform === "win32" ? "where" : "which";
|
|
1304
|
+
return spawnSync(checker, [cmd], { stdio: "ignore" }).status === 0;
|
|
1305
|
+
}
|
|
1306
|
+
async function cloneRemote(input) {
|
|
1307
|
+
const dest = fs3.mkdtempSync(path2.join(os.tmpdir(), "openpkg-"));
|
|
1308
|
+
const github = parseGithubRepo(input);
|
|
1309
|
+
try {
|
|
1310
|
+
if (github && whichCmd("gh")) {
|
|
1311
|
+
await runCmd("gh", [
|
|
1312
|
+
"repo",
|
|
1313
|
+
"clone",
|
|
1314
|
+
`${github.owner}/${github.repo}`,
|
|
1315
|
+
dest,
|
|
1316
|
+
"--",
|
|
1317
|
+
"--depth",
|
|
1318
|
+
"1"
|
|
1319
|
+
]);
|
|
1320
|
+
} else {
|
|
1321
|
+
const url = input.startsWith("github.com/") ? `https://${input}` : input;
|
|
1322
|
+
await runCmd("git", ["clone", "--depth", "1", url, dest]);
|
|
1323
|
+
}
|
|
1324
|
+
} catch (err) {
|
|
1325
|
+
fs3.rmSync(dest, { recursive: true, force: true });
|
|
1326
|
+
throw err;
|
|
1327
|
+
}
|
|
1328
|
+
return dest;
|
|
1329
|
+
}
|
|
1330
|
+
function existsFile(p) {
|
|
1331
|
+
try {
|
|
1332
|
+
return fs3.existsSync(p) && fs3.statSync(p).isFile();
|
|
1333
|
+
} catch {
|
|
1334
|
+
return false;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
function existsDir(p) {
|
|
1338
|
+
try {
|
|
1339
|
+
return fs3.existsSync(p) && fs3.statSync(p).isDirectory();
|
|
1340
|
+
} catch {
|
|
1341
|
+
return false;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
function readJson(file) {
|
|
1345
|
+
try {
|
|
1346
|
+
return JSON.parse(fs3.readFileSync(file, "utf-8"));
|
|
1347
|
+
} catch {
|
|
1348
|
+
return null;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
function parsePnpmWorkspace(yaml) {
|
|
1352
|
+
const globs = [];
|
|
1353
|
+
const lines = yaml.split(`
|
|
1354
|
+
`);
|
|
1355
|
+
let inPackages = false;
|
|
1356
|
+
for (const line of lines) {
|
|
1357
|
+
const trimmed = line.trim();
|
|
1358
|
+
if (trimmed === "packages:") {
|
|
1359
|
+
inPackages = true;
|
|
1360
|
+
continue;
|
|
1361
|
+
}
|
|
1362
|
+
if (inPackages) {
|
|
1363
|
+
if (!line.startsWith(" ") && !line.startsWith("\t") && !line.startsWith("-") && trimmed) {
|
|
1364
|
+
break;
|
|
1365
|
+
}
|
|
1366
|
+
const match = trimmed.match(/^-\s*['"]?([^'"]+)['"]?$/);
|
|
1367
|
+
if (match)
|
|
1368
|
+
globs.push(match[1]);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return globs;
|
|
1372
|
+
}
|
|
1373
|
+
function expandGlob(root, pattern) {
|
|
1374
|
+
const parts = pattern.split("/").filter(Boolean);
|
|
1375
|
+
const out = [];
|
|
1376
|
+
const walk = (dir, i) => {
|
|
1377
|
+
if (out.length >= MAX_PACKAGES)
|
|
1378
|
+
return;
|
|
1379
|
+
if (i === parts.length) {
|
|
1380
|
+
if (existsFile(path2.join(dir, "package.json")))
|
|
1381
|
+
out.push(dir);
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
const part = parts[i];
|
|
1385
|
+
if (!existsDir(dir))
|
|
1386
|
+
return;
|
|
1387
|
+
if (part === "**") {
|
|
1388
|
+
walk(dir, i + 1);
|
|
1389
|
+
let entries = [];
|
|
1390
|
+
try {
|
|
1391
|
+
entries = fs3.readdirSync(dir, { withFileTypes: true });
|
|
1392
|
+
} catch {
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1395
|
+
for (const ent of entries) {
|
|
1396
|
+
if (!ent.isDirectory() || SKIP_DIRS.has(ent.name))
|
|
1397
|
+
continue;
|
|
1398
|
+
walk(path2.join(dir, ent.name), i);
|
|
1399
|
+
}
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
if (part === "*") {
|
|
1403
|
+
let entries = [];
|
|
1404
|
+
try {
|
|
1405
|
+
entries = fs3.readdirSync(dir, { withFileTypes: true });
|
|
1406
|
+
} catch {
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
for (const ent of entries) {
|
|
1410
|
+
if (!ent.isDirectory() || SKIP_DIRS.has(ent.name))
|
|
1411
|
+
continue;
|
|
1412
|
+
walk(path2.join(dir, ent.name), i + 1);
|
|
1413
|
+
}
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
walk(path2.join(dir, part), i + 1);
|
|
1417
|
+
};
|
|
1418
|
+
walk(root, 0);
|
|
1419
|
+
return out;
|
|
1420
|
+
}
|
|
1421
|
+
function workspaceGlobs(dir) {
|
|
1422
|
+
const pnpm = path2.join(dir, "pnpm-workspace.yaml");
|
|
1423
|
+
if (existsFile(pnpm)) {
|
|
1424
|
+
const globs = parsePnpmWorkspace(fs3.readFileSync(pnpm, "utf-8"));
|
|
1425
|
+
if (globs.length)
|
|
1426
|
+
return globs;
|
|
1427
|
+
}
|
|
1428
|
+
const pkg = readJson(path2.join(dir, "package.json"));
|
|
1429
|
+
if (!pkg)
|
|
1430
|
+
return null;
|
|
1431
|
+
const ws = pkg.workspaces;
|
|
1432
|
+
if (Array.isArray(ws) && ws.every((x) => typeof x === "string"))
|
|
1433
|
+
return ws;
|
|
1434
|
+
if (ws && typeof ws === "object" && Array.isArray(ws.packages)) {
|
|
1435
|
+
return (ws.packages ?? []).filter((x) => typeof x === "string");
|
|
1436
|
+
}
|
|
1437
|
+
return null;
|
|
1438
|
+
}
|
|
1439
|
+
function findWorkspaceRoot(start) {
|
|
1440
|
+
let dir = path2.resolve(start);
|
|
1441
|
+
for (let i = 0;i < 12; i++) {
|
|
1442
|
+
const globs = workspaceGlobs(dir);
|
|
1443
|
+
if (globs?.length)
|
|
1444
|
+
return dir;
|
|
1445
|
+
const parent = path2.dirname(dir);
|
|
1446
|
+
if (parent === dir)
|
|
1447
|
+
break;
|
|
1448
|
+
dir = parent;
|
|
1449
|
+
}
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
function toRecord(dir) {
|
|
1453
|
+
const pkg = readJson(path2.join(dir, "package.json"));
|
|
1454
|
+
if (!pkg)
|
|
1455
|
+
return null;
|
|
1456
|
+
const name = typeof pkg.name === "string" ? pkg.name : path2.basename(dir);
|
|
1457
|
+
const scripts = pkg.scripts && typeof pkg.scripts === "object" ? Object.keys(pkg.scripts) : [];
|
|
1458
|
+
return {
|
|
1459
|
+
name,
|
|
1460
|
+
dir,
|
|
1461
|
+
private: pkg.private === true,
|
|
1462
|
+
...typeof pkg.description === "string" ? { description: pkg.description } : {},
|
|
1463
|
+
...typeof pkg.types === "string" ? { types: pkg.types } : {},
|
|
1464
|
+
...typeof pkg.typings === "string" ? { typings: pkg.typings } : {},
|
|
1465
|
+
...typeof pkg.main === "string" ? { main: pkg.main } : {},
|
|
1466
|
+
...typeof pkg.module === "string" ? { module: pkg.module } : {},
|
|
1467
|
+
hasSrc: CONV.some((c) => existsFile(path2.join(dir, c))),
|
|
1468
|
+
hasDist: existsDir(path2.join(dir, "dist")),
|
|
1469
|
+
scripts
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
function catalogPackages(start) {
|
|
1473
|
+
const abs = path2.resolve(start);
|
|
1474
|
+
const root = findWorkspaceRoot(abs) ?? abs;
|
|
1475
|
+
const seen = new Set;
|
|
1476
|
+
const out = [];
|
|
1477
|
+
const add = (dir2) => {
|
|
1478
|
+
const resolved = path2.resolve(dir2);
|
|
1479
|
+
if (seen.has(resolved) || out.length >= MAX_PACKAGES)
|
|
1480
|
+
return;
|
|
1481
|
+
const rec = toRecord(resolved);
|
|
1482
|
+
if (!rec)
|
|
1483
|
+
return;
|
|
1484
|
+
seen.add(resolved);
|
|
1485
|
+
out.push(rec);
|
|
1486
|
+
};
|
|
1487
|
+
const globs = workspaceGlobs(root);
|
|
1488
|
+
if (globs?.length) {
|
|
1489
|
+
for (const glob of globs) {
|
|
1490
|
+
for (const dir2 of expandGlob(root, glob))
|
|
1491
|
+
add(dir2);
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
let dir = abs;
|
|
1495
|
+
for (let i = 0;i < 8; i++) {
|
|
1496
|
+
if (existsFile(path2.join(dir, "package.json"))) {
|
|
1497
|
+
add(dir);
|
|
1498
|
+
break;
|
|
1499
|
+
}
|
|
1500
|
+
const parent = path2.dirname(dir);
|
|
1501
|
+
if (parent === dir)
|
|
1502
|
+
break;
|
|
1503
|
+
dir = parent;
|
|
1504
|
+
}
|
|
1505
|
+
return out;
|
|
1506
|
+
}
|
|
1507
|
+
function collectFromExports(value, out, depth = 0) {
|
|
1508
|
+
if (depth > 4 || value == null)
|
|
1509
|
+
return;
|
|
1510
|
+
if (typeof value === "string") {
|
|
1511
|
+
out.push(value);
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
if (Array.isArray(value)) {
|
|
1515
|
+
for (const v of value)
|
|
1516
|
+
collectFromExports(v, out, depth + 1);
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
if (typeof value === "object") {
|
|
1520
|
+
const obj = value;
|
|
1521
|
+
for (const key of ["types", "import", "default", "require", "node", "browser", "module"]) {
|
|
1522
|
+
if (key in obj)
|
|
1523
|
+
collectFromExports(obj[key], out, depth + 1);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
function collectCandidates(pkgDir, pkg) {
|
|
1528
|
+
const seen = new Map;
|
|
1529
|
+
const add = (rel, source) => {
|
|
1530
|
+
const abs = path2.resolve(pkgDir, rel);
|
|
1531
|
+
if (!existsFile(abs))
|
|
1532
|
+
return;
|
|
1533
|
+
const norm = path2.relative(pkgDir, abs).split(path2.sep).join("/");
|
|
1534
|
+
const prev = seen.get(norm);
|
|
1535
|
+
if (!prev)
|
|
1536
|
+
seen.set(norm, { rel: norm, abs, source });
|
|
1537
|
+
else if (!prev.source.includes(source))
|
|
1538
|
+
prev.source += `, ${source}`;
|
|
1539
|
+
};
|
|
1540
|
+
if (typeof pkg.types === "string")
|
|
1541
|
+
add(pkg.types, "types");
|
|
1542
|
+
if (typeof pkg.typings === "string")
|
|
1543
|
+
add(pkg.typings, "typings");
|
|
1544
|
+
if (pkg.exports && typeof pkg.exports === "object") {
|
|
1545
|
+
const exp = pkg.exports;
|
|
1546
|
+
const root = "." in exp ? exp["."] : exp;
|
|
1547
|
+
const paths = [];
|
|
1548
|
+
collectFromExports(root, paths);
|
|
1549
|
+
for (const p of paths)
|
|
1550
|
+
add(p, "exports");
|
|
1551
|
+
}
|
|
1552
|
+
if (typeof pkg.module === "string")
|
|
1553
|
+
add(pkg.module, "module");
|
|
1554
|
+
if (typeof pkg.main === "string")
|
|
1555
|
+
add(pkg.main, "main");
|
|
1556
|
+
for (const c of CONV)
|
|
1557
|
+
add(c, "convention");
|
|
1558
|
+
return [...seen.values()];
|
|
1559
|
+
}
|
|
1560
|
+
function scoreCandidate(c) {
|
|
1561
|
+
const ts = /\.(ts|tsx|mts)$/.test(c.rel) && !/\.d\.(ts|mts|cts)$/.test(c.rel);
|
|
1562
|
+
const dts = /\.d\.(ts|mts|cts)$/.test(c.rel);
|
|
1563
|
+
const src = c.rel.startsWith("src/");
|
|
1564
|
+
let n = 0;
|
|
1565
|
+
if (ts)
|
|
1566
|
+
n += 40;
|
|
1567
|
+
if (src && ts)
|
|
1568
|
+
n += 20;
|
|
1569
|
+
if (c.source.includes("types") || c.source.includes("typings"))
|
|
1570
|
+
n += dts ? 5 : 10;
|
|
1571
|
+
if (c.source.includes("exports"))
|
|
1572
|
+
n += 8;
|
|
1573
|
+
if (c.source.includes("convention"))
|
|
1574
|
+
n += ts ? 15 : 2;
|
|
1575
|
+
if (c.source.includes("module"))
|
|
1576
|
+
n += 4;
|
|
1577
|
+
if (c.source.includes("main"))
|
|
1578
|
+
n += 2;
|
|
1579
|
+
if (dts)
|
|
1580
|
+
n -= 15;
|
|
1581
|
+
if (/\.(js|mjs|cjs)$/.test(c.rel))
|
|
1582
|
+
n -= 20;
|
|
1583
|
+
return n;
|
|
1584
|
+
}
|
|
1585
|
+
function methodFor(c) {
|
|
1586
|
+
if (c.source.includes("convention") && /\.(ts|tsx|mts)$/.test(c.rel) && !c.rel.includes(".d.")) {
|
|
1587
|
+
return "fallback";
|
|
1588
|
+
}
|
|
1589
|
+
if (c.source.includes("types") || c.source.includes("typings"))
|
|
1590
|
+
return "types";
|
|
1591
|
+
if (c.source.includes("exports"))
|
|
1592
|
+
return "exports";
|
|
1593
|
+
if (c.source.includes("module"))
|
|
1594
|
+
return "module";
|
|
1595
|
+
if (c.source.includes("main"))
|
|
1596
|
+
return "main";
|
|
1597
|
+
return "fallback";
|
|
1598
|
+
}
|
|
1599
|
+
function pickEntry(pkgDir) {
|
|
1600
|
+
const pkg = readJson(path2.join(pkgDir, "package.json")) ?? {};
|
|
1601
|
+
const cands = collectCandidates(pkgDir, pkg);
|
|
1602
|
+
if (!cands.length)
|
|
1603
|
+
return null;
|
|
1604
|
+
const best = [...cands].sort((a, b) => scoreCandidate(b) - scoreCandidate(a))[0];
|
|
1605
|
+
return { entryFile: best.abs, entryPointSource: methodFor(best) };
|
|
1606
|
+
}
|
|
1607
|
+
function listEntryCandidates(pkgDir) {
|
|
1608
|
+
const pkg = readJson(path2.join(pkgDir, "package.json")) ?? {};
|
|
1609
|
+
return collectCandidates(pkgDir, pkg);
|
|
1610
|
+
}
|
|
1611
|
+
function isIgnoredPath(dir) {
|
|
1612
|
+
const norm = dir.split(path2.sep).join("/");
|
|
1613
|
+
return /\/(examples|fixtures|__tests__|test-fixtures)(\/|$)/.test(norm);
|
|
1614
|
+
}
|
|
1615
|
+
function isExtractable(pkg) {
|
|
1616
|
+
if (pkg.private)
|
|
1617
|
+
return false;
|
|
1618
|
+
if (isIgnoredPath(pkg.dir))
|
|
1619
|
+
return false;
|
|
1620
|
+
return pkg.hasSrc || Boolean(pkg.types || pkg.typings);
|
|
1621
|
+
}
|
|
1622
|
+
function intentScore(pkg, intent) {
|
|
1623
|
+
const q = intent.toLowerCase().trim();
|
|
1624
|
+
if (!q)
|
|
1625
|
+
return 0;
|
|
1626
|
+
const words = q.split(/\s+/).filter(Boolean);
|
|
1627
|
+
const name = pkg.name.toLowerCase();
|
|
1628
|
+
const desc = (pkg.description ?? "").toLowerCase();
|
|
1629
|
+
const dir = pkg.dir.split(path2.sep).join("/").toLowerCase();
|
|
1630
|
+
let n = 0;
|
|
1631
|
+
if (name === q || name.endsWith(`/${q}`) || name.split("/").pop() === q)
|
|
1632
|
+
n += 20;
|
|
1633
|
+
for (const w of words) {
|
|
1634
|
+
if (name.includes(w))
|
|
1635
|
+
n += 8;
|
|
1636
|
+
if (desc.includes(w))
|
|
1637
|
+
n += 3;
|
|
1638
|
+
if (dir.includes(w))
|
|
1639
|
+
n += 2;
|
|
1640
|
+
}
|
|
1641
|
+
return n;
|
|
1642
|
+
}
|
|
1643
|
+
function enclosingPackage(inputDir, catalog) {
|
|
1644
|
+
const abs = path2.resolve(inputDir);
|
|
1645
|
+
let best;
|
|
1646
|
+
for (const pkg of catalog) {
|
|
1647
|
+
if (abs === pkg.dir || abs.startsWith(pkg.dir + path2.sep)) {
|
|
1648
|
+
if (!best || pkg.dir.length > best.dir.length)
|
|
1649
|
+
best = pkg;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
return best;
|
|
1653
|
+
}
|
|
1654
|
+
function buildCommand(pkg) {
|
|
1655
|
+
if (pkg.scripts.includes("build:sdk-wasm"))
|
|
1656
|
+
return "pnpm run build:sdk-wasm";
|
|
1657
|
+
if (pkg.scripts.includes("build"))
|
|
1658
|
+
return "bun run build";
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
function head(abs, maxChars = 1200) {
|
|
1662
|
+
try {
|
|
1663
|
+
return fs3.readFileSync(abs, "utf8").slice(0, maxChars);
|
|
1664
|
+
} catch {
|
|
1665
|
+
return "";
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
async function jevPickPackage(candidates, ctx) {
|
|
1669
|
+
if (!ctx.evaluate || candidates.length < 2)
|
|
1670
|
+
return null;
|
|
1671
|
+
const criteria = {};
|
|
1672
|
+
const byId = new Map;
|
|
1673
|
+
for (const [i, pkg] of candidates.entries()) {
|
|
1674
|
+
const id = `p${i}`;
|
|
1675
|
+
byId.set(id, pkg);
|
|
1676
|
+
criteria[id] = `${pkg.name} — ${pkg.description ?? pkg.dir}${pkg.hasSrc ? " (src)" : ""}`;
|
|
1677
|
+
}
|
|
1678
|
+
const picked = await jevChoice({
|
|
1679
|
+
evaluate: ctx.evaluate,
|
|
1680
|
+
instructions: "Which package is the public TypeScript SDK to extract? Prefer the named product, not examples, wasm glue, or private packages.",
|
|
1681
|
+
criteria,
|
|
1682
|
+
state: {
|
|
1683
|
+
intent: ctx.intent ?? null,
|
|
1684
|
+
catalog: candidates.map((p, i) => ({
|
|
1685
|
+
id: `p${i}`,
|
|
1686
|
+
name: p.name,
|
|
1687
|
+
description: p.description ?? null,
|
|
1688
|
+
hasSrc: p.hasSrc,
|
|
1689
|
+
hasDist: p.hasDist,
|
|
1690
|
+
types: p.types ?? p.typings ?? null,
|
|
1691
|
+
private: p.private
|
|
1692
|
+
}))
|
|
1693
|
+
},
|
|
1694
|
+
id: "package"
|
|
1695
|
+
});
|
|
1696
|
+
if (!picked || picked.confidence < JEV_CONFIDENCE)
|
|
1697
|
+
return null;
|
|
1698
|
+
return byId.get(picked.choice) ?? null;
|
|
1699
|
+
}
|
|
1700
|
+
async function jevPickEntry(cands, ctx) {
|
|
1701
|
+
if (!ctx.evaluate || cands.length < 2)
|
|
1702
|
+
return null;
|
|
1703
|
+
const criteria = {};
|
|
1704
|
+
const byId = new Map;
|
|
1705
|
+
for (const [i, c] of cands.entries()) {
|
|
1706
|
+
const id = `c${i}`;
|
|
1707
|
+
byId.set(id, c);
|
|
1708
|
+
criteria[id] = `${c.rel} (${c.source})`;
|
|
1709
|
+
}
|
|
1710
|
+
const picked = await jevChoice({
|
|
1711
|
+
evaluate: ctx.evaluate,
|
|
1712
|
+
instructions: "Which file is the best OpenPkg entry point? Prefer TypeScript source over .d.ts/.js. Prefer the package root public API.",
|
|
1713
|
+
criteria,
|
|
1714
|
+
state: {
|
|
1715
|
+
candidates: cands.map((c, i) => ({
|
|
1716
|
+
id: `c${i}`,
|
|
1717
|
+
path: c.rel,
|
|
1718
|
+
source: c.source,
|
|
1719
|
+
head: head(c.abs)
|
|
1720
|
+
}))
|
|
1721
|
+
},
|
|
1722
|
+
id: "entry"
|
|
1723
|
+
});
|
|
1724
|
+
if (!picked || picked.confidence < JEV_CONFIDENCE)
|
|
1725
|
+
return null;
|
|
1726
|
+
return byId.get(picked.choice) ?? null;
|
|
1727
|
+
}
|
|
1728
|
+
async function finishPackage(pkg, ctx) {
|
|
1729
|
+
const cands = listEntryCandidates(pkg.dir);
|
|
1730
|
+
if (!cands.length) {
|
|
1731
|
+
return {
|
|
1732
|
+
kind: "needs-build",
|
|
1733
|
+
package: pkg,
|
|
1734
|
+
reason: `no TypeScript entry found in ${pkg.name}`,
|
|
1735
|
+
...buildCommand(pkg) ? { command: buildCommand(pkg) } : {}
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
const heuristic = [...cands].sort((a, b) => scoreCandidate(b) - scoreCandidate(a))[0];
|
|
1739
|
+
let chosen = heuristic;
|
|
1740
|
+
let source = methodFor(heuristic);
|
|
1741
|
+
if (ctx.decisions === "jev" && cands.length >= 2) {
|
|
1742
|
+
const jev = await jevPickEntry(cands, ctx);
|
|
1743
|
+
if (jev) {
|
|
1744
|
+
chosen = jev;
|
|
1745
|
+
source = "llm";
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
return {
|
|
1749
|
+
kind: "ok",
|
|
1750
|
+
package: pkg,
|
|
1751
|
+
entryFile: chosen.abs,
|
|
1752
|
+
entryPointSource: source
|
|
1753
|
+
};
|
|
1754
|
+
}
|
|
1755
|
+
async function resolveLocal(abs, startDir, ctx) {
|
|
1756
|
+
const catalog = catalogPackages(startDir);
|
|
1757
|
+
if (!catalog.length) {
|
|
1758
|
+
return { kind: "empty", reason: "no JS/TS packages found" };
|
|
1759
|
+
}
|
|
1760
|
+
const root = findWorkspaceRoot(startDir);
|
|
1761
|
+
const pointed = catalog.find((p) => p.dir === abs);
|
|
1762
|
+
if (pointed && (isExtractable(pointed) || pointed.dir !== root)) {
|
|
1763
|
+
return finishPackage(pointed, ctx);
|
|
1764
|
+
}
|
|
1765
|
+
const intent = ctx.intent;
|
|
1766
|
+
if (intent) {
|
|
1767
|
+
const scored = catalog.map((p) => ({ p, n: intentScore(p, intent) })).filter((x) => x.n > 0).sort((a, b) => b.n - a.n);
|
|
1768
|
+
if (!scored.length) {
|
|
1769
|
+
return { kind: "empty", reason: `no package matched intent "${intent}"` };
|
|
1770
|
+
}
|
|
1771
|
+
const top = scored.filter((x) => x.n === scored[0].n).map((x) => x.p);
|
|
1772
|
+
if (top.length === 1)
|
|
1773
|
+
return finishPackage(top[0], ctx);
|
|
1774
|
+
if (ctx.decisions === "jev") {
|
|
1775
|
+
const jev = await jevPickPackage(top, ctx);
|
|
1776
|
+
if (jev)
|
|
1777
|
+
return finishPackage(jev, ctx);
|
|
1778
|
+
}
|
|
1779
|
+
return { kind: "ambiguous", candidates: top };
|
|
1780
|
+
}
|
|
1781
|
+
const enclosed = enclosingPackage(startDir, catalog);
|
|
1782
|
+
if (enclosed && enclosed.dir !== root)
|
|
1783
|
+
return finishPackage(enclosed, ctx);
|
|
1784
|
+
const extractable = catalog.filter(isExtractable);
|
|
1785
|
+
if (extractable.length === 1)
|
|
1786
|
+
return finishPackage(extractable[0], ctx);
|
|
1787
|
+
if (extractable.length > 1) {
|
|
1788
|
+
if (ctx.decisions === "jev") {
|
|
1789
|
+
const jev = await jevPickPackage(extractable, ctx);
|
|
1790
|
+
if (jev)
|
|
1791
|
+
return finishPackage(jev, ctx);
|
|
1792
|
+
}
|
|
1793
|
+
return { kind: "ambiguous", candidates: extractable };
|
|
1794
|
+
}
|
|
1795
|
+
if (catalog.length === 1)
|
|
1796
|
+
return finishPackage(catalog[0], ctx);
|
|
1797
|
+
return { kind: "empty", reason: "no extractable JS/TS packages found" };
|
|
1798
|
+
}
|
|
1799
|
+
async function resolveTarget(options = {}) {
|
|
1800
|
+
const cwd = path2.resolve(options.cwd ?? process.cwd());
|
|
1801
|
+
const raw = options.input?.trim() || cwd;
|
|
1802
|
+
const decisions = options.decisions ?? "heuristic";
|
|
1803
|
+
const ctx = {
|
|
1804
|
+
decisions,
|
|
1805
|
+
evaluate: options.evaluate,
|
|
1806
|
+
intent: options.intent?.trim() || undefined
|
|
1807
|
+
};
|
|
1808
|
+
if (decisions === "jev" && !ctx.evaluate) {
|
|
1809
|
+
if (!process.env.AI_GATEWAY_API_KEY) {
|
|
1810
|
+
return {
|
|
1811
|
+
kind: "unavailable",
|
|
1812
|
+
reason: `--jev requires AI_GATEWAY_API_KEY
|
|
1813
|
+
https://vercel.com/docs/ai-gateway
|
|
1814
|
+
omit --jev to stay local`
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
try {
|
|
1818
|
+
ctx.evaluate = await loadEvaluate();
|
|
1819
|
+
} catch (err) {
|
|
1820
|
+
return { kind: "unavailable", reason: err instanceof Error ? err.message : String(err) };
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
if (isRemoteInput(raw)) {
|
|
1824
|
+
try {
|
|
1825
|
+
const cloned = await (options.clone ?? cloneRemote)(raw);
|
|
1826
|
+
const startDir2 = cloned;
|
|
1827
|
+
return resolveLocal(startDir2, startDir2, ctx);
|
|
1828
|
+
} catch (err) {
|
|
1829
|
+
return {
|
|
1830
|
+
kind: "empty",
|
|
1831
|
+
reason: `failed to clone ${raw}: ${err instanceof Error ? err.message : String(err)}`
|
|
1832
|
+
};
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
const abs = path2.resolve(cwd, raw);
|
|
1836
|
+
if (existsFile(abs) && isEntryFilePath(abs)) {
|
|
1837
|
+
return { kind: "explicit", entryFile: abs, entryPointSource: "explicit" };
|
|
1838
|
+
}
|
|
1839
|
+
const startDir = existsDir(abs) ? abs : cwd;
|
|
1840
|
+
return resolveLocal(abs, startDir, ctx);
|
|
1841
|
+
}
|
|
1203
1842
|
// src/primitives/filter.ts
|
|
1204
1843
|
function matchesExport(exp, criteria) {
|
|
1205
1844
|
if (criteria.kinds && criteria.kinds.length > 0) {
|
|
@@ -1304,10 +1943,10 @@ function filterSpec(spec, criteria) {
|
|
|
1304
1943
|
};
|
|
1305
1944
|
}
|
|
1306
1945
|
// src/primitives/get.ts
|
|
1307
|
-
import
|
|
1946
|
+
import ts13 from "typescript";
|
|
1308
1947
|
|
|
1309
1948
|
// src/ast/utils.ts
|
|
1310
|
-
import * as
|
|
1949
|
+
import * as path3 from "node:path";
|
|
1311
1950
|
import ts from "typescript";
|
|
1312
1951
|
var INLINE_TAG_RE = /(^|[^\\])\{@([a-zA-Z][a-zA-Z0-9]*)((?:[^}\\]|\\.)*)\}/g;
|
|
1313
1952
|
function parseInlineTags(...texts) {
|
|
@@ -1493,8 +2132,8 @@ function getJSDocComment(node, symbol, checker) {
|
|
|
1493
2132
|
}
|
|
1494
2133
|
function getSourceLocation(node, sourceFile) {
|
|
1495
2134
|
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
1496
|
-
const
|
|
1497
|
-
const file =
|
|
2135
|
+
const relative3 = path3.relative(process.cwd(), sourceFile.fileName);
|
|
2136
|
+
const file = relative3.startsWith("..") ? sourceFile.fileName : relative3;
|
|
1498
2137
|
return {
|
|
1499
2138
|
file,
|
|
1500
2139
|
line: line + 1
|
|
@@ -1666,8 +2305,8 @@ function getExportKind(declaration, type) {
|
|
|
1666
2305
|
}
|
|
1667
2306
|
|
|
1668
2307
|
// src/compiler/program.ts
|
|
1669
|
-
import * as
|
|
1670
|
-
import * as
|
|
2308
|
+
import * as fs4 from "node:fs";
|
|
2309
|
+
import * as path4 from "node:path";
|
|
1671
2310
|
import ts2 from "typescript";
|
|
1672
2311
|
function isJsFile(file) {
|
|
1673
2312
|
return /\.(js|mjs|cjs|jsx)$/.test(file);
|
|
@@ -1683,48 +2322,48 @@ function getScriptKind(file) {
|
|
|
1683
2322
|
}
|
|
1684
2323
|
var DEFAULT_COMPILER_OPTIONS = {
|
|
1685
2324
|
target: ts2.ScriptTarget.Latest,
|
|
1686
|
-
module: ts2.ModuleKind.
|
|
2325
|
+
module: ts2.ModuleKind.NodeNext,
|
|
1687
2326
|
lib: ["lib.es2021.d.ts"],
|
|
1688
2327
|
declaration: true,
|
|
1689
|
-
moduleResolution: ts2.ModuleResolutionKind.
|
|
2328
|
+
moduleResolution: ts2.ModuleResolutionKind.NodeNext,
|
|
1690
2329
|
strict: true
|
|
1691
2330
|
};
|
|
1692
2331
|
function resolveWorkspaceEntry(pkgDir) {
|
|
1693
2332
|
const candidates = [
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
2333
|
+
path4.join(pkgDir, "src", "index.ts"),
|
|
2334
|
+
path4.join(pkgDir, "src", "index.tsx"),
|
|
2335
|
+
path4.join(pkgDir, "index.ts")
|
|
1697
2336
|
];
|
|
1698
2337
|
try {
|
|
1699
|
-
const pkg = JSON.parse(
|
|
2338
|
+
const pkg = JSON.parse(fs4.readFileSync(path4.join(pkgDir, "package.json"), "utf-8"));
|
|
1700
2339
|
for (const field of [pkg.types, pkg.typings]) {
|
|
1701
2340
|
if (typeof field === "string") {
|
|
1702
|
-
candidates.push(
|
|
2341
|
+
candidates.push(path4.resolve(pkgDir, field));
|
|
1703
2342
|
}
|
|
1704
2343
|
}
|
|
1705
2344
|
} catch {}
|
|
1706
|
-
return candidates.find((c) =>
|
|
2345
|
+
return candidates.find((c) => fs4.existsSync(c));
|
|
1707
2346
|
}
|
|
1708
2347
|
function resolveProjectReferences(configPath, parsedConfig) {
|
|
1709
2348
|
const additionalFiles = [];
|
|
1710
2349
|
if (!parsedConfig.projectReferences?.length) {
|
|
1711
2350
|
return additionalFiles;
|
|
1712
2351
|
}
|
|
1713
|
-
const configDir =
|
|
2352
|
+
const configDir = path4.dirname(configPath);
|
|
1714
2353
|
for (const ref of parsedConfig.projectReferences) {
|
|
1715
|
-
const refPath =
|
|
1716
|
-
const refConfigPath =
|
|
1717
|
-
if (!
|
|
2354
|
+
const refPath = path4.resolve(configDir, ref.path);
|
|
2355
|
+
const refConfigPath = fs4.existsSync(path4.join(refPath, "tsconfig.json")) ? path4.join(refPath, "tsconfig.json") : refPath;
|
|
2356
|
+
if (!fs4.existsSync(refConfigPath))
|
|
1718
2357
|
continue;
|
|
1719
2358
|
const refConfigFile = ts2.readConfigFile(refConfigPath, ts2.sys.readFile);
|
|
1720
2359
|
if (refConfigFile.error)
|
|
1721
2360
|
continue;
|
|
1722
|
-
const refParsed = ts2.parseJsonConfigFileContent(refConfigFile.config, ts2.sys,
|
|
2361
|
+
const refParsed = ts2.parseJsonConfigFileContent(refConfigFile.config, ts2.sys, path4.dirname(refConfigPath));
|
|
1723
2362
|
additionalFiles.push(...refParsed.fileNames);
|
|
1724
2363
|
}
|
|
1725
2364
|
return additionalFiles;
|
|
1726
2365
|
}
|
|
1727
|
-
function
|
|
2366
|
+
function parsePnpmWorkspace2(yamlContent) {
|
|
1728
2367
|
const globs = [];
|
|
1729
2368
|
const lines = yamlContent.split(`
|
|
1730
2369
|
`);
|
|
@@ -1750,52 +2389,52 @@ function parsePnpmWorkspace(yamlContent) {
|
|
|
1750
2389
|
function buildWorkspaceMap(baseDir) {
|
|
1751
2390
|
let currentDir = baseDir;
|
|
1752
2391
|
let rootDir;
|
|
1753
|
-
let
|
|
2392
|
+
let workspaceGlobs2 = [];
|
|
1754
2393
|
for (let i = 0;i < 10; i++) {
|
|
1755
|
-
const pnpmPath =
|
|
1756
|
-
if (
|
|
2394
|
+
const pnpmPath = path4.join(currentDir, "pnpm-workspace.yaml");
|
|
2395
|
+
if (fs4.existsSync(pnpmPath)) {
|
|
1757
2396
|
try {
|
|
1758
|
-
const yamlContent =
|
|
1759
|
-
|
|
1760
|
-
if (
|
|
2397
|
+
const yamlContent = fs4.readFileSync(pnpmPath, "utf-8");
|
|
2398
|
+
workspaceGlobs2 = parsePnpmWorkspace2(yamlContent);
|
|
2399
|
+
if (workspaceGlobs2.length > 0) {
|
|
1761
2400
|
rootDir = currentDir;
|
|
1762
2401
|
break;
|
|
1763
2402
|
}
|
|
1764
2403
|
} catch {}
|
|
1765
2404
|
}
|
|
1766
|
-
const pkgPath =
|
|
1767
|
-
if (
|
|
2405
|
+
const pkgPath = path4.join(currentDir, "package.json");
|
|
2406
|
+
if (fs4.existsSync(pkgPath)) {
|
|
1768
2407
|
try {
|
|
1769
|
-
const pkg = JSON.parse(
|
|
2408
|
+
const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
1770
2409
|
if (pkg.workspaces) {
|
|
1771
2410
|
rootDir = currentDir;
|
|
1772
|
-
|
|
2411
|
+
workspaceGlobs2 = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces?.packages || [];
|
|
1773
2412
|
break;
|
|
1774
2413
|
}
|
|
1775
2414
|
} catch {}
|
|
1776
2415
|
}
|
|
1777
|
-
const parent =
|
|
2416
|
+
const parent = path4.dirname(currentDir);
|
|
1778
2417
|
if (parent === currentDir)
|
|
1779
2418
|
break;
|
|
1780
2419
|
currentDir = parent;
|
|
1781
2420
|
}
|
|
1782
|
-
if (!rootDir ||
|
|
2421
|
+
if (!rootDir || workspaceGlobs2.length === 0)
|
|
1783
2422
|
return;
|
|
1784
2423
|
const packages = new Map;
|
|
1785
|
-
for (const glob of
|
|
1786
|
-
const globDir =
|
|
1787
|
-
if (!
|
|
2424
|
+
for (const glob of workspaceGlobs2) {
|
|
2425
|
+
const globDir = path4.join(rootDir, glob.replace(/\/\*$/, ""));
|
|
2426
|
+
if (!fs4.existsSync(globDir) || !fs4.statSync(globDir).isDirectory())
|
|
1788
2427
|
continue;
|
|
1789
|
-
const entries =
|
|
2428
|
+
const entries = fs4.readdirSync(globDir, { withFileTypes: true });
|
|
1790
2429
|
for (const entry of entries) {
|
|
1791
2430
|
if (!entry.isDirectory())
|
|
1792
2431
|
continue;
|
|
1793
|
-
const pkgDir =
|
|
1794
|
-
const pkgJsonPath =
|
|
1795
|
-
if (!
|
|
2432
|
+
const pkgDir = path4.join(globDir, entry.name);
|
|
2433
|
+
const pkgJsonPath = path4.join(pkgDir, "package.json");
|
|
2434
|
+
if (!fs4.existsSync(pkgJsonPath))
|
|
1796
2435
|
continue;
|
|
1797
2436
|
try {
|
|
1798
|
-
const pkg = JSON.parse(
|
|
2437
|
+
const pkg = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
|
|
1799
2438
|
if (pkg.name) {
|
|
1800
2439
|
packages.set(pkg.name, pkgDir);
|
|
1801
2440
|
}
|
|
@@ -1804,10 +2443,35 @@ function buildWorkspaceMap(baseDir) {
|
|
|
1804
2443
|
}
|
|
1805
2444
|
return packages.size > 0 ? { packages, rootDir } : undefined;
|
|
1806
2445
|
}
|
|
2446
|
+
function discoverAmbientTypePackages(baseDir) {
|
|
2447
|
+
const found = [];
|
|
2448
|
+
const seen = new Set;
|
|
2449
|
+
let currentDir = baseDir;
|
|
2450
|
+
for (let i = 0;i < 10; i++) {
|
|
2451
|
+
const typesDir = path4.join(currentDir, "node_modules", "@types");
|
|
2452
|
+
try {
|
|
2453
|
+
if (fs4.existsSync(typesDir) && fs4.statSync(typesDir).isDirectory()) {
|
|
2454
|
+
for (const entry of fs4.readdirSync(typesDir, { withFileTypes: true })) {
|
|
2455
|
+
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
2456
|
+
continue;
|
|
2457
|
+
if (seen.has(entry.name))
|
|
2458
|
+
continue;
|
|
2459
|
+
seen.add(entry.name);
|
|
2460
|
+
found.push(entry.name);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
} catch {}
|
|
2464
|
+
const parent = path4.dirname(currentDir);
|
|
2465
|
+
if (parent === currentDir)
|
|
2466
|
+
break;
|
|
2467
|
+
currentDir = parent;
|
|
2468
|
+
}
|
|
2469
|
+
return found;
|
|
2470
|
+
}
|
|
1807
2471
|
function createProgram(options) {
|
|
1808
2472
|
const { content } = options;
|
|
1809
|
-
const entryFile =
|
|
1810
|
-
const baseDir =
|
|
2473
|
+
const entryFile = path4.resolve(options.entryFile);
|
|
2474
|
+
const baseDir = path4.resolve(options.baseDir ?? path4.dirname(entryFile));
|
|
1811
2475
|
let configPath = ts2.findConfigFile(baseDir, ts2.sys.fileExists, "tsconfig.json");
|
|
1812
2476
|
if (!configPath) {
|
|
1813
2477
|
configPath = ts2.findConfigFile(baseDir, ts2.sys.fileExists, "jsconfig.json");
|
|
@@ -1816,14 +2480,14 @@ function createProgram(options) {
|
|
|
1816
2480
|
let additionalRootFiles = [];
|
|
1817
2481
|
if (configPath) {
|
|
1818
2482
|
const configFile = ts2.readConfigFile(configPath, ts2.sys.readFile);
|
|
1819
|
-
const parsedConfig = ts2.parseJsonConfigFileContent(configFile.config, ts2.sys,
|
|
2483
|
+
const parsedConfig = ts2.parseJsonConfigFileContent(configFile.config, ts2.sys, path4.dirname(configPath));
|
|
1820
2484
|
compilerOptions = { ...compilerOptions, ...parsedConfig.options };
|
|
1821
2485
|
additionalRootFiles = resolveProjectReferences(configPath, parsedConfig);
|
|
1822
2486
|
let sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
|
|
1823
2487
|
if (/\.d\.[cm]?ts$/.test(entryFile)) {
|
|
1824
2488
|
sourceFiles = sourceFiles.filter((f) => {
|
|
1825
2489
|
try {
|
|
1826
|
-
return !ts2.getOutputFileNames(parsedConfig, f, !ts2.sys.useCaseSensitiveFileNames).some((out) =>
|
|
2490
|
+
return !ts2.getOutputFileNames(parsedConfig, f, !ts2.sys.useCaseSensitiveFileNames).some((out) => path4.resolve(out) === entryFile);
|
|
1827
2491
|
} catch {
|
|
1828
2492
|
return true;
|
|
1829
2493
|
}
|
|
@@ -1844,6 +2508,12 @@ function createProgram(options) {
|
|
|
1844
2508
|
compilerOptions = { ...compilerOptions, allowJs: false, checkJs: false };
|
|
1845
2509
|
}
|
|
1846
2510
|
}
|
|
2511
|
+
if (compilerOptions.types === undefined && compilerOptions.typeRoots === undefined) {
|
|
2512
|
+
const ambientTypes = discoverAmbientTypePackages(baseDir);
|
|
2513
|
+
if (ambientTypes.length > 0) {
|
|
2514
|
+
compilerOptions = { ...compilerOptions, types: ambientTypes };
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
1847
2517
|
const workspaceMap = buildWorkspaceMap(baseDir);
|
|
1848
2518
|
const compilerHost = ts2.createCompilerHost(compilerOptions, true);
|
|
1849
2519
|
let inMemorySource;
|
|
@@ -1900,7 +2570,7 @@ import ts5 from "typescript";
|
|
|
1900
2570
|
import ts4 from "typescript";
|
|
1901
2571
|
|
|
1902
2572
|
// src/ast/type-identity.ts
|
|
1903
|
-
import * as
|
|
2573
|
+
import * as path5 from "node:path";
|
|
1904
2574
|
import ts3 from "typescript";
|
|
1905
2575
|
var NODE_MODULES_PKG = /node_modules\/(@[^/]+\/[^/]+|[^/]+)/;
|
|
1906
2576
|
function packageLabel(fileName, workspacePackages) {
|
|
@@ -1908,7 +2578,7 @@ function packageLabel(fileName, workspacePackages) {
|
|
|
1908
2578
|
let pkg = match?.[1];
|
|
1909
2579
|
if (!pkg) {
|
|
1910
2580
|
for (const [name, dir] of workspacePackages) {
|
|
1911
|
-
if (fileName.startsWith(`${
|
|
2581
|
+
if (fileName.startsWith(`${path5.resolve(dir)}${path5.sep}`)) {
|
|
1912
2582
|
pkg = name;
|
|
1913
2583
|
break;
|
|
1914
2584
|
}
|
|
@@ -2316,6 +2986,14 @@ function isAnonymous(type) {
|
|
|
2316
2986
|
const name = symbol.getName();
|
|
2317
2987
|
return name.startsWith("__") || name === "";
|
|
2318
2988
|
}
|
|
2989
|
+
function isFluentThisType(type) {
|
|
2990
|
+
if (!(type.flags & ts4.TypeFlags.TypeParameter))
|
|
2991
|
+
return false;
|
|
2992
|
+
const declarations = type.getSymbol()?.declarations;
|
|
2993
|
+
if (!declarations || declarations.length === 0)
|
|
2994
|
+
return false;
|
|
2995
|
+
return declarations.some((decl) => ts4.isClassDeclaration(decl) || ts4.isClassExpression(decl) || ts4.isInterfaceDeclaration(decl));
|
|
2996
|
+
}
|
|
2319
2997
|
function withDepth(ctx, fn) {
|
|
2320
2998
|
ctx.currentDepth++;
|
|
2321
2999
|
try {
|
|
@@ -2351,7 +3029,7 @@ function buildSchema(type, checker, ctx) {
|
|
|
2351
3029
|
return ensureNonEmptySchema(schema, type, checker);
|
|
2352
3030
|
}
|
|
2353
3031
|
function buildMaxDepthSchema(type, checker) {
|
|
2354
|
-
if (type.flags & ts4.TypeFlags.TypeParameter && type
|
|
3032
|
+
if (type.flags & ts4.TypeFlags.TypeParameter && !isFluentThisType(type)) {
|
|
2355
3033
|
return { "x-ts-type": checker.typeToString(type) };
|
|
2356
3034
|
}
|
|
2357
3035
|
const symbol = type.getSymbol() || type.aliasSymbol;
|
|
@@ -2439,7 +3117,7 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
2439
3117
|
return { type: "bigint" };
|
|
2440
3118
|
if (type.flags & ts4.TypeFlags.ESSymbol)
|
|
2441
3119
|
return { type: "symbol" };
|
|
2442
|
-
if (type
|
|
3120
|
+
if (isFluentThisType(type)) {
|
|
2443
3121
|
const constraint = type.getConstraint?.();
|
|
2444
3122
|
const symbol2 = constraint?.getSymbol() ?? type.getSymbol();
|
|
2445
3123
|
if (symbol2 && !isAnonymous(type)) {
|
|
@@ -4500,12 +5178,13 @@ function serializeResolvedMembers(type, node, ctx) {
|
|
|
4500
5178
|
}
|
|
4501
5179
|
|
|
4502
5180
|
// src/schema/registry.ts
|
|
5181
|
+
import ts12 from "typescript";
|
|
4503
5182
|
function isTypeReference(type) {
|
|
4504
|
-
return !!(type.flags &
|
|
5183
|
+
return !!(type.flags & ts12.TypeFlags.Object && type.objectFlags && type.objectFlags & ts12.ObjectFlags.Reference);
|
|
4505
5184
|
}
|
|
4506
5185
|
function getNonNullableType(type) {
|
|
4507
5186
|
if (type.isUnion()) {
|
|
4508
|
-
const nonNullable = type.types.filter((t) => !(t.flags &
|
|
5187
|
+
const nonNullable = type.types.filter((t) => !(t.flags & ts12.TypeFlags.Undefined) && !(t.flags & ts12.TypeFlags.Null));
|
|
4509
5188
|
if (nonNullable.length === 1) {
|
|
4510
5189
|
return nonNullable[0];
|
|
4511
5190
|
}
|
|
@@ -5261,7 +5940,7 @@ async function getExport(options) {
|
|
|
5261
5940
|
ctx.exportedIds = exportedIds;
|
|
5262
5941
|
try {
|
|
5263
5942
|
const originalDecls = targetSymbol.declarations ?? [];
|
|
5264
|
-
const isNamespaceExportDecl = originalDecls.some((d) =>
|
|
5943
|
+
const isNamespaceExportDecl = originalDecls.some((d) => ts13.isNamespaceExport(d) || ts13.isNamespaceImport(d));
|
|
5265
5944
|
if (isNamespaceExportDecl) {
|
|
5266
5945
|
const spec2 = serializeNamespaceForGet(targetSymbol, exportName, ctx);
|
|
5267
5946
|
const types2 = ctx.typeRegistry.getAll().map((t) => normalizeType(t));
|
|
@@ -5312,42 +5991,42 @@ function resolveExportTarget(symbol, checker) {
|
|
|
5312
5991
|
let isTypeOnly = false;
|
|
5313
5992
|
const declarations = symbol.declarations ?? [];
|
|
5314
5993
|
for (const decl of declarations) {
|
|
5315
|
-
if (
|
|
5994
|
+
if (ts13.isExportSpecifier(decl)) {
|
|
5316
5995
|
if (decl.isTypeOnly)
|
|
5317
5996
|
isTypeOnly = true;
|
|
5318
5997
|
const exportDecl = decl.parent?.parent;
|
|
5319
|
-
if (exportDecl &&
|
|
5998
|
+
if (exportDecl && ts13.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly) {
|
|
5320
5999
|
isTypeOnly = true;
|
|
5321
6000
|
}
|
|
5322
6001
|
}
|
|
5323
6002
|
}
|
|
5324
|
-
if (symbol.flags &
|
|
6003
|
+
if (symbol.flags & ts13.SymbolFlags.Alias) {
|
|
5325
6004
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
5326
6005
|
if (aliased && aliased !== symbol) {
|
|
5327
6006
|
resolvedSymbol = aliased;
|
|
5328
6007
|
}
|
|
5329
6008
|
}
|
|
5330
6009
|
const targetDeclarations = resolvedSymbol.declarations ?? [];
|
|
5331
|
-
const declaration = resolvedSymbol.valueDeclaration || targetDeclarations.find((d) => d.kind !==
|
|
6010
|
+
const declaration = resolvedSymbol.valueDeclaration || targetDeclarations.find((d) => d.kind !== ts13.SyntaxKind.ExportSpecifier) || targetDeclarations[0];
|
|
5332
6011
|
return { declaration, resolvedSymbol, isTypeOnly };
|
|
5333
6012
|
}
|
|
5334
6013
|
function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportName, ctx, isTypeOnly) {
|
|
5335
6014
|
let result = null;
|
|
5336
|
-
if (
|
|
6015
|
+
if (ts13.isFunctionDeclaration(declaration)) {
|
|
5337
6016
|
result = serializeFunctionExport(declaration, ctx);
|
|
5338
|
-
} else if (
|
|
6017
|
+
} else if (ts13.isClassDeclaration(declaration)) {
|
|
5339
6018
|
result = serializeClass(declaration, ctx);
|
|
5340
|
-
} else if (
|
|
6019
|
+
} else if (ts13.isInterfaceDeclaration(declaration)) {
|
|
5341
6020
|
result = serializeInterface(declaration, ctx);
|
|
5342
|
-
} else if (
|
|
6021
|
+
} else if (ts13.isTypeAliasDeclaration(declaration)) {
|
|
5343
6022
|
result = serializeTypeAlias(declaration, ctx);
|
|
5344
|
-
} else if (
|
|
6023
|
+
} else if (ts13.isEnumDeclaration(declaration)) {
|
|
5345
6024
|
result = serializeEnum(declaration, ctx);
|
|
5346
|
-
} else if (
|
|
6025
|
+
} else if (ts13.isVariableDeclaration(declaration)) {
|
|
5347
6026
|
const varStatement = declaration.parent?.parent;
|
|
5348
|
-
if (varStatement &&
|
|
5349
|
-
if (declaration.initializer && (
|
|
5350
|
-
const varName =
|
|
6027
|
+
if (varStatement && ts13.isVariableStatement(varStatement)) {
|
|
6028
|
+
if (declaration.initializer && (ts13.isArrowFunction(declaration.initializer) || ts13.isFunctionExpression(declaration.initializer))) {
|
|
6029
|
+
const varName = ts13.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
|
|
5351
6030
|
result = serializeFunctionExport(declaration.initializer, ctx, varName);
|
|
5352
6031
|
} else {
|
|
5353
6032
|
const checker = ctx.program.getTypeChecker();
|
|
@@ -5361,7 +6040,7 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
|
|
|
5361
6040
|
}
|
|
5362
6041
|
}
|
|
5363
6042
|
}
|
|
5364
|
-
} else if (
|
|
6043
|
+
} else if (ts13.isNamespaceExport(declaration) || ts13.isModuleDeclaration(declaration) || ts13.isNamespaceImport(declaration) || ts13.isSourceFile(declaration)) {
|
|
5365
6044
|
result = serializeNamespaceForGet(_exportSymbol, exportName, ctx);
|
|
5366
6045
|
}
|
|
5367
6046
|
if (result) {
|
|
@@ -5377,7 +6056,7 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
|
|
|
5377
6056
|
function serializeNamespaceForGet(symbol, exportName, ctx) {
|
|
5378
6057
|
const checker = ctx.program.getTypeChecker();
|
|
5379
6058
|
let targetSymbol = symbol;
|
|
5380
|
-
if (symbol.flags &
|
|
6059
|
+
if (symbol.flags & ts13.SymbolFlags.Alias) {
|
|
5381
6060
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
5382
6061
|
if (aliased && aliased !== symbol) {
|
|
5383
6062
|
targetSymbol = aliased;
|
|
@@ -5407,7 +6086,7 @@ function serializeNamespaceForGet(symbol, exportName, ctx) {
|
|
|
5407
6086
|
}
|
|
5408
6087
|
function detectExternalPackage(symbol, checker) {
|
|
5409
6088
|
let targetSymbol = symbol;
|
|
5410
|
-
if (symbol.flags &
|
|
6089
|
+
if (symbol.flags & ts13.SymbolFlags.Alias) {
|
|
5411
6090
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
5412
6091
|
if (aliased && aliased !== symbol) {
|
|
5413
6092
|
targetSymbol = aliased;
|
|
@@ -5421,9 +6100,9 @@ function detectExternalPackage(symbol, checker) {
|
|
|
5421
6100
|
if (match)
|
|
5422
6101
|
return match[1];
|
|
5423
6102
|
}
|
|
5424
|
-
if (
|
|
6103
|
+
if (ts13.isExportSpecifier(decl)) {
|
|
5425
6104
|
const exportDecl = decl.parent?.parent;
|
|
5426
|
-
if (exportDecl &&
|
|
6105
|
+
if (exportDecl && ts13.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
|
|
5427
6106
|
const moduleText = exportDecl.moduleSpecifier.text;
|
|
5428
6107
|
if (!moduleText.startsWith(".") && !moduleText.startsWith("/")) {
|
|
5429
6108
|
return moduleText;
|
|
@@ -5434,8 +6113,8 @@ function detectExternalPackage(symbol, checker) {
|
|
|
5434
6113
|
return;
|
|
5435
6114
|
}
|
|
5436
6115
|
// src/primitives/list.ts
|
|
5437
|
-
import * as
|
|
5438
|
-
import
|
|
6116
|
+
import * as path6 from "node:path";
|
|
6117
|
+
import ts14 from "typescript";
|
|
5439
6118
|
async function listExports(options) {
|
|
5440
6119
|
const { entryFile, baseDir, content } = options;
|
|
5441
6120
|
const errors = [];
|
|
@@ -5478,16 +6157,16 @@ async function listExports(options) {
|
|
|
5478
6157
|
}
|
|
5479
6158
|
function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
|
|
5480
6159
|
const name = symbol.getName();
|
|
5481
|
-
const isReexport = !!(symbol.flags &
|
|
6160
|
+
const isReexport = !!(symbol.flags & ts14.SymbolFlags.Alias);
|
|
5482
6161
|
let targetSymbol = symbol;
|
|
5483
|
-
if (symbol.flags &
|
|
6162
|
+
if (symbol.flags & ts14.SymbolFlags.Alias) {
|
|
5484
6163
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
5485
6164
|
if (aliased && aliased !== symbol) {
|
|
5486
6165
|
targetSymbol = aliased;
|
|
5487
6166
|
}
|
|
5488
6167
|
}
|
|
5489
6168
|
const declarations = targetSymbol.declarations ?? [];
|
|
5490
|
-
const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !==
|
|
6169
|
+
const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts14.SyntaxKind.ExportSpecifier) || declarations[0];
|
|
5491
6170
|
if (!declaration) {
|
|
5492
6171
|
return {
|
|
5493
6172
|
name,
|
|
@@ -5497,11 +6176,11 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
|
|
|
5497
6176
|
reexport: true
|
|
5498
6177
|
};
|
|
5499
6178
|
}
|
|
5500
|
-
if (
|
|
6179
|
+
if (ts14.isSourceFile(declaration)) {
|
|
5501
6180
|
return {
|
|
5502
6181
|
name,
|
|
5503
6182
|
kind: "namespace",
|
|
5504
|
-
file:
|
|
6183
|
+
file: path6.relative(path6.dirname(entryFile), declaration.fileName),
|
|
5505
6184
|
line: 1,
|
|
5506
6185
|
reexport: true
|
|
5507
6186
|
};
|
|
@@ -5515,7 +6194,7 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
|
|
|
5515
6194
|
return {
|
|
5516
6195
|
name,
|
|
5517
6196
|
kind,
|
|
5518
|
-
file:
|
|
6197
|
+
file: path6.relative(path6.dirname(entryFile), sourceFile.fileName),
|
|
5519
6198
|
line: line + 1,
|
|
5520
6199
|
...description ? { description } : {},
|
|
5521
6200
|
...deprecated ? { deprecated: true } : {},
|
|
@@ -5536,21 +6215,21 @@ function getDescriptionPreview(symbol, checker) {
|
|
|
5536
6215
|
return `${firstLine.slice(0, 77)}...`;
|
|
5537
6216
|
}
|
|
5538
6217
|
// src/builder/spec-builder.ts
|
|
5539
|
-
import * as
|
|
5540
|
-
import * as
|
|
6218
|
+
import * as fs7 from "node:fs";
|
|
6219
|
+
import * as path10 from "node:path";
|
|
5541
6220
|
import { SCHEMA_URL, SCHEMA_VERSION } from "@openpkg-ts/spec";
|
|
5542
|
-
import
|
|
6221
|
+
import ts19 from "typescript";
|
|
5543
6222
|
|
|
5544
6223
|
// src/ast/resolve.ts
|
|
5545
|
-
import
|
|
6224
|
+
import ts15 from "typescript";
|
|
5546
6225
|
function isTypeOnlyExport(symbol) {
|
|
5547
6226
|
const declarations = symbol.declarations ?? [];
|
|
5548
6227
|
for (const decl of declarations) {
|
|
5549
|
-
if (
|
|
6228
|
+
if (ts15.isExportSpecifier(decl)) {
|
|
5550
6229
|
if (decl.isTypeOnly)
|
|
5551
6230
|
return true;
|
|
5552
6231
|
const exportDecl = decl.parent?.parent;
|
|
5553
|
-
if (exportDecl &&
|
|
6232
|
+
if (exportDecl && ts15.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly) {
|
|
5554
6233
|
return true;
|
|
5555
6234
|
}
|
|
5556
6235
|
}
|
|
@@ -5560,22 +6239,22 @@ function isTypeOnlyExport(symbol) {
|
|
|
5560
6239
|
function resolveExportTarget2(symbol, checker) {
|
|
5561
6240
|
let targetSymbol = symbol;
|
|
5562
6241
|
const isTypeOnly = isTypeOnlyExport(symbol);
|
|
5563
|
-
if (symbol.flags &
|
|
6242
|
+
if (symbol.flags & ts15.SymbolFlags.Alias) {
|
|
5564
6243
|
const aliasTarget = checker.getAliasedSymbol(symbol);
|
|
5565
6244
|
if (aliasTarget && aliasTarget !== symbol) {
|
|
5566
6245
|
targetSymbol = aliasTarget;
|
|
5567
6246
|
}
|
|
5568
6247
|
}
|
|
5569
6248
|
const declarations = targetSymbol.declarations ?? [];
|
|
5570
|
-
const declaration = targetSymbol.valueDeclaration || declarations.find((decl) => decl.kind !==
|
|
6249
|
+
const declaration = targetSymbol.valueDeclaration || declarations.find((decl) => decl.kind !== ts15.SyntaxKind.ExportSpecifier) || declarations[0];
|
|
5571
6250
|
return { declaration, targetSymbol, isTypeOnly };
|
|
5572
6251
|
}
|
|
5573
6252
|
|
|
5574
6253
|
// src/schema/standard-schema.ts
|
|
5575
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
5576
|
-
import * as
|
|
5577
|
-
import * as
|
|
5578
|
-
import * as
|
|
6254
|
+
import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
|
|
6255
|
+
import * as fs5 from "node:fs";
|
|
6256
|
+
import * as os2 from "node:os";
|
|
6257
|
+
import * as path7 from "node:path";
|
|
5579
6258
|
var MAX_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
5580
6259
|
function isStandardJSONSchema(obj) {
|
|
5581
6260
|
if (typeof obj !== "object" || obj === null)
|
|
@@ -5597,7 +6276,7 @@ function isStandardJSONSchema(obj) {
|
|
|
5597
6276
|
var cachedRuntime;
|
|
5598
6277
|
function commandExists(cmd) {
|
|
5599
6278
|
try {
|
|
5600
|
-
const result =
|
|
6279
|
+
const result = spawnSync2(process.platform === "win32" ? "where" : "which", [cmd], {
|
|
5601
6280
|
stdio: "ignore"
|
|
5602
6281
|
});
|
|
5603
6282
|
return result.status === 0;
|
|
@@ -5829,21 +6508,21 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
|
|
|
5829
6508
|
result.errors.push("No TypeScript runtime available. Install bun, tsx, or ts-node, or use Node 22+.");
|
|
5830
6509
|
return result;
|
|
5831
6510
|
}
|
|
5832
|
-
if (!
|
|
6511
|
+
if (!fs5.existsSync(tsFilePath)) {
|
|
5833
6512
|
result.errors.push(`TypeScript file not found: ${tsFilePath}`);
|
|
5834
6513
|
return result;
|
|
5835
6514
|
}
|
|
5836
|
-
const tempDir =
|
|
5837
|
-
const workerPath =
|
|
6515
|
+
const tempDir = os2.tmpdir();
|
|
6516
|
+
const workerPath = path7.join(tempDir, `openpkg-extract-worker-${Date.now()}.ts`);
|
|
5838
6517
|
try {
|
|
5839
|
-
|
|
6518
|
+
fs5.writeFileSync(workerPath, TS_WORKER_SCRIPT);
|
|
5840
6519
|
const optionsJson = JSON.stringify({ target, libraryOptions });
|
|
5841
6520
|
const args = [...runtime.args, workerPath, tsFilePath, optionsJson];
|
|
5842
|
-
return await new Promise((
|
|
5843
|
-
const child =
|
|
6521
|
+
return await new Promise((resolve4) => {
|
|
6522
|
+
const child = spawn2(runtime.cmd, args, {
|
|
5844
6523
|
timeout,
|
|
5845
6524
|
stdio: ["ignore", "pipe", "pipe"],
|
|
5846
|
-
cwd:
|
|
6525
|
+
cwd: path7.dirname(tsFilePath)
|
|
5847
6526
|
});
|
|
5848
6527
|
let stdout = "";
|
|
5849
6528
|
let stderr = "";
|
|
@@ -5867,7 +6546,7 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
|
|
|
5867
6546
|
});
|
|
5868
6547
|
child.on("close", (code) => {
|
|
5869
6548
|
try {
|
|
5870
|
-
|
|
6549
|
+
fs5.unlinkSync(workerPath);
|
|
5871
6550
|
} catch (cleanupErr) {
|
|
5872
6551
|
if (cleanupErr?.code !== "ENOENT") {
|
|
5873
6552
|
result.warnings.push({ code: "CLEANUP_FAILED", message: String(cleanupErr) });
|
|
@@ -5875,14 +6554,14 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
|
|
|
5875
6554
|
}
|
|
5876
6555
|
if (code !== 0) {
|
|
5877
6556
|
result.errors.push(`Extraction failed (${runtime.name}): ${stderr || `exit code ${code}`}`);
|
|
5878
|
-
|
|
6557
|
+
resolve4(result);
|
|
5879
6558
|
return;
|
|
5880
6559
|
}
|
|
5881
6560
|
try {
|
|
5882
6561
|
const parsed = JSON.parse(stdout);
|
|
5883
6562
|
if (!parsed.success) {
|
|
5884
6563
|
result.errors.push(`Extraction failed: ${parsed.error}`);
|
|
5885
|
-
|
|
6564
|
+
resolve4(result);
|
|
5886
6565
|
return;
|
|
5887
6566
|
}
|
|
5888
6567
|
for (const item of parsed.results) {
|
|
@@ -5917,23 +6596,23 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
|
|
|
5917
6596
|
message: "stderr exceeded 10MB buffer limit"
|
|
5918
6597
|
});
|
|
5919
6598
|
}
|
|
5920
|
-
|
|
6599
|
+
resolve4(result);
|
|
5921
6600
|
});
|
|
5922
6601
|
child.on("error", (err) => {
|
|
5923
6602
|
try {
|
|
5924
|
-
|
|
6603
|
+
fs5.unlinkSync(workerPath);
|
|
5925
6604
|
} catch (cleanupErr) {
|
|
5926
6605
|
if (cleanupErr?.code !== "ENOENT") {
|
|
5927
6606
|
result.warnings.push({ code: "CLEANUP_FAILED", message: String(cleanupErr) });
|
|
5928
6607
|
}
|
|
5929
6608
|
}
|
|
5930
6609
|
result.errors.push(`Subprocess error: ${err.message}`);
|
|
5931
|
-
|
|
6610
|
+
resolve4(result);
|
|
5932
6611
|
});
|
|
5933
6612
|
});
|
|
5934
6613
|
} catch (e) {
|
|
5935
6614
|
try {
|
|
5936
|
-
|
|
6615
|
+
fs5.unlinkSync(workerPath);
|
|
5937
6616
|
} catch (cleanupErr) {
|
|
5938
6617
|
if (cleanupErr?.code !== "ENOENT") {
|
|
5939
6618
|
result.warnings.push({ code: "CLEANUP_FAILED", message: String(cleanupErr) });
|
|
@@ -5944,12 +6623,12 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
|
|
|
5944
6623
|
}
|
|
5945
6624
|
}
|
|
5946
6625
|
function readTsconfigOutDir(baseDir) {
|
|
5947
|
-
const tsconfigPath =
|
|
6626
|
+
const tsconfigPath = path7.join(baseDir, "tsconfig.json");
|
|
5948
6627
|
try {
|
|
5949
|
-
if (!
|
|
6628
|
+
if (!fs5.existsSync(tsconfigPath)) {
|
|
5950
6629
|
return null;
|
|
5951
6630
|
}
|
|
5952
|
-
const content =
|
|
6631
|
+
const content = fs5.readFileSync(tsconfigPath, "utf-8");
|
|
5953
6632
|
const stripped = content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
|
|
5954
6633
|
const tsconfig = JSON.parse(stripped);
|
|
5955
6634
|
if (tsconfig.compilerOptions?.outDir) {
|
|
@@ -5959,7 +6638,7 @@ function readTsconfigOutDir(baseDir) {
|
|
|
5959
6638
|
return null;
|
|
5960
6639
|
}
|
|
5961
6640
|
function resolveCompiledPath(tsPath, baseDir) {
|
|
5962
|
-
const relativePath =
|
|
6641
|
+
const relativePath = path7.relative(baseDir, tsPath);
|
|
5963
6642
|
const withoutExt = relativePath.replace(/\.tsx?$/, "");
|
|
5964
6643
|
const srcPrefix = withoutExt.replace(/^src\//, "");
|
|
5965
6644
|
const tsconfigOutDir = readTsconfigOutDir(baseDir);
|
|
@@ -5967,7 +6646,7 @@ function resolveCompiledPath(tsPath, baseDir) {
|
|
|
5967
6646
|
const candidates = [];
|
|
5968
6647
|
if (tsconfigOutDir) {
|
|
5969
6648
|
for (const ext of extensions) {
|
|
5970
|
-
candidates.push(
|
|
6649
|
+
candidates.push(path7.join(baseDir, tsconfigOutDir, `${srcPrefix}${ext}`));
|
|
5971
6650
|
}
|
|
5972
6651
|
}
|
|
5973
6652
|
const commonOutDirs = ["dist", "build", "lib", "out"];
|
|
@@ -5975,21 +6654,21 @@ function resolveCompiledPath(tsPath, baseDir) {
|
|
|
5975
6654
|
if (outDir === tsconfigOutDir)
|
|
5976
6655
|
continue;
|
|
5977
6656
|
for (const ext of extensions) {
|
|
5978
|
-
candidates.push(
|
|
6657
|
+
candidates.push(path7.join(baseDir, outDir, `${srcPrefix}${ext}`));
|
|
5979
6658
|
}
|
|
5980
6659
|
}
|
|
5981
6660
|
for (const ext of extensions) {
|
|
5982
|
-
candidates.push(
|
|
6661
|
+
candidates.push(path7.join(baseDir, `${withoutExt}${ext}`));
|
|
5983
6662
|
}
|
|
5984
6663
|
const workspaceMatch = baseDir.match(/^(.+\/packages\/[^/]+)$/);
|
|
5985
6664
|
if (workspaceMatch) {
|
|
5986
6665
|
const pkgRoot = workspaceMatch[1];
|
|
5987
6666
|
for (const ext of extensions) {
|
|
5988
|
-
candidates.push(
|
|
6667
|
+
candidates.push(path7.join(pkgRoot, "dist", `${srcPrefix}${ext}`));
|
|
5989
6668
|
}
|
|
5990
6669
|
}
|
|
5991
6670
|
for (const candidate of candidates) {
|
|
5992
|
-
if (
|
|
6671
|
+
if (fs5.existsSync(candidate)) {
|
|
5993
6672
|
return candidate;
|
|
5994
6673
|
}
|
|
5995
6674
|
}
|
|
@@ -6002,13 +6681,13 @@ async function extractStandardSchemas(compiledJsPath, options = {}) {
|
|
|
6002
6681
|
errors: [],
|
|
6003
6682
|
warnings: []
|
|
6004
6683
|
};
|
|
6005
|
-
if (!
|
|
6684
|
+
if (!fs5.existsSync(compiledJsPath)) {
|
|
6006
6685
|
result.errors.push(`Compiled JS not found: ${compiledJsPath}`);
|
|
6007
6686
|
return result;
|
|
6008
6687
|
}
|
|
6009
6688
|
const optionsJson = JSON.stringify({ target, libraryOptions });
|
|
6010
|
-
return new Promise((
|
|
6011
|
-
const child =
|
|
6689
|
+
return new Promise((resolve4) => {
|
|
6690
|
+
const child = spawn2("node", ["-e", WORKER_SCRIPT, compiledJsPath, optionsJson], {
|
|
6012
6691
|
timeout,
|
|
6013
6692
|
stdio: ["ignore", "pipe", "pipe"]
|
|
6014
6693
|
});
|
|
@@ -6035,14 +6714,14 @@ async function extractStandardSchemas(compiledJsPath, options = {}) {
|
|
|
6035
6714
|
child.on("close", (code) => {
|
|
6036
6715
|
if (code !== 0) {
|
|
6037
6716
|
result.errors.push(`Extraction process failed: ${stderr || `exit code ${code}`}`);
|
|
6038
|
-
|
|
6717
|
+
resolve4(result);
|
|
6039
6718
|
return;
|
|
6040
6719
|
}
|
|
6041
6720
|
try {
|
|
6042
6721
|
const parsed = JSON.parse(stdout);
|
|
6043
6722
|
if (!parsed.success) {
|
|
6044
6723
|
result.errors.push(`Extraction failed: ${parsed.error}`);
|
|
6045
|
-
|
|
6724
|
+
resolve4(result);
|
|
6046
6725
|
return;
|
|
6047
6726
|
}
|
|
6048
6727
|
for (const item of parsed.results) {
|
|
@@ -6077,11 +6756,11 @@ async function extractStandardSchemas(compiledJsPath, options = {}) {
|
|
|
6077
6756
|
message: "stderr exceeded 10MB buffer limit"
|
|
6078
6757
|
});
|
|
6079
6758
|
}
|
|
6080
|
-
|
|
6759
|
+
resolve4(result);
|
|
6081
6760
|
});
|
|
6082
6761
|
child.on("error", (err) => {
|
|
6083
6762
|
result.errors.push(`Subprocess error: ${err.message}`);
|
|
6084
|
-
|
|
6763
|
+
resolve4(result);
|
|
6085
6764
|
});
|
|
6086
6765
|
});
|
|
6087
6766
|
}
|
|
@@ -6118,10 +6797,10 @@ async function extractStandardSchemasFromProject(entryFile, baseDir, options = {
|
|
|
6118
6797
|
}
|
|
6119
6798
|
|
|
6120
6799
|
// src/builder/external-resolver.ts
|
|
6121
|
-
import * as
|
|
6122
|
-
import * as
|
|
6800
|
+
import * as fs6 from "node:fs";
|
|
6801
|
+
import * as path8 from "node:path";
|
|
6123
6802
|
import picomatch from "picomatch";
|
|
6124
|
-
import
|
|
6803
|
+
import ts16 from "typescript";
|
|
6125
6804
|
function matchesExternalPattern(packageName, include, exclude) {
|
|
6126
6805
|
if (!include?.length)
|
|
6127
6806
|
return false;
|
|
@@ -6137,7 +6816,7 @@ function matchesExternalPattern(packageName, include, exclude) {
|
|
|
6137
6816
|
return true;
|
|
6138
6817
|
}
|
|
6139
6818
|
function resolveExternalModule(moduleSpecifier, containingFile, compilerOptions) {
|
|
6140
|
-
const resolved =
|
|
6819
|
+
const resolved = ts16.resolveModuleName(moduleSpecifier, containingFile, compilerOptions, ts16.sys);
|
|
6141
6820
|
if (!resolved.resolvedModule) {
|
|
6142
6821
|
return null;
|
|
6143
6822
|
}
|
|
@@ -6153,20 +6832,20 @@ function findPackageJson(resolvedPath, packageName) {
|
|
|
6153
6832
|
const isScoped = packageName.startsWith("@");
|
|
6154
6833
|
const packageParts = isScoped ? packageName.split("/").slice(0, 2) : [packageName.split("/")[0]];
|
|
6155
6834
|
const packageDir = packageParts.join("/");
|
|
6156
|
-
let dir =
|
|
6835
|
+
let dir = path8.dirname(resolvedPath);
|
|
6157
6836
|
const maxDepth = 10;
|
|
6158
6837
|
for (let i = 0;i < maxDepth; i++) {
|
|
6159
6838
|
if (dir.endsWith(`node_modules/${packageDir}`)) {
|
|
6160
|
-
const pkgPath =
|
|
6161
|
-
if (
|
|
6839
|
+
const pkgPath = path8.join(dir, "package.json");
|
|
6840
|
+
if (fs6.existsSync(pkgPath)) {
|
|
6162
6841
|
try {
|
|
6163
|
-
return JSON.parse(
|
|
6842
|
+
return JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
|
|
6164
6843
|
} catch {
|
|
6165
6844
|
return;
|
|
6166
6845
|
}
|
|
6167
6846
|
}
|
|
6168
6847
|
}
|
|
6169
|
-
const parent =
|
|
6848
|
+
const parent = path8.dirname(dir);
|
|
6170
6849
|
if (parent === dir)
|
|
6171
6850
|
break;
|
|
6172
6851
|
dir = parent;
|
|
@@ -6202,7 +6881,7 @@ function extractExternalExport(exportName, resolvedModule, program, ctx, visited
|
|
|
6202
6881
|
return null;
|
|
6203
6882
|
}
|
|
6204
6883
|
let resolvedSymbol = targetExport;
|
|
6205
|
-
if (targetExport.flags &
|
|
6884
|
+
if (targetExport.flags & ts16.SymbolFlags.Alias) {
|
|
6206
6885
|
const aliased = checker.getAliasedSymbol(targetExport);
|
|
6207
6886
|
if (aliased && aliased !== targetExport) {
|
|
6208
6887
|
resolvedSymbol = aliased;
|
|
@@ -6244,6 +6923,80 @@ function extractExternalExport(exportName, resolvedModule, program, ctx, visited
|
|
|
6244
6923
|
return specExport;
|
|
6245
6924
|
}
|
|
6246
6925
|
|
|
6926
|
+
// src/builder/jev-extract.ts
|
|
6927
|
+
var FOLLOW_SCORE_LEVELS = [
|
|
6928
|
+
"opaque — a stub is enough",
|
|
6929
|
+
"useful — expanding helps",
|
|
6930
|
+
"essential — needed to understand the public API"
|
|
6931
|
+
];
|
|
6932
|
+
var AMBIGUOUS_CODES = new Set([
|
|
6933
|
+
"FORGOTTEN_EXPORT",
|
|
6934
|
+
"SERIALIZATION_FAILED",
|
|
6935
|
+
"RUNTIME_SCHEMA_ERROR"
|
|
6936
|
+
]);
|
|
6937
|
+
async function selectFollowExternal(refs, evaluate) {
|
|
6938
|
+
const sliced = refs.slice(0, MAX_JEV_QUESTIONS);
|
|
6939
|
+
if (!sliced.length)
|
|
6940
|
+
return [];
|
|
6941
|
+
const questions = {};
|
|
6942
|
+
for (const [i, ref] of sliced.entries()) {
|
|
6943
|
+
questions[`t${i}`] = {
|
|
6944
|
+
type: "score",
|
|
6945
|
+
instructions: `How load-bearing is ${ref.typeName} from ${ref.package} for understanding this public TypeScript API?`,
|
|
6946
|
+
criteria: FOLLOW_SCORE_LEVELS
|
|
6947
|
+
};
|
|
6948
|
+
}
|
|
6949
|
+
const result = await jevEvaluate(evaluate, {
|
|
6950
|
+
types: sliced,
|
|
6951
|
+
task: "OpenPkg extracts a public TS API. Stub opaque externals; expand load-bearing ones."
|
|
6952
|
+
}, questions);
|
|
6953
|
+
const follow = new Set;
|
|
6954
|
+
for (const [i, ref] of sliced.entries()) {
|
|
6955
|
+
const id = `t${i}`;
|
|
6956
|
+
const score = result.answers[id]?.score;
|
|
6957
|
+
if (typeof score !== "number")
|
|
6958
|
+
continue;
|
|
6959
|
+
const conf = namedConfidence(result, id) ?? (score >= 1.5 || score <= 0.5 ? 1 : 0);
|
|
6960
|
+
if (score >= 1.5 || score >= 1 && conf >= JEV_CONFIDENCE)
|
|
6961
|
+
follow.add(ref.package);
|
|
6962
|
+
}
|
|
6963
|
+
return [...follow];
|
|
6964
|
+
}
|
|
6965
|
+
async function calibrateDiagnostics(diagnostics, evaluate) {
|
|
6966
|
+
const targets = diagnostics.map((d, index) => ({ d, index })).filter(({ d }) => d.code && AMBIGUOUS_CODES.has(d.code)).slice(0, MAX_JEV_QUESTIONS);
|
|
6967
|
+
if (targets.length < 1)
|
|
6968
|
+
return;
|
|
6969
|
+
const questions = {};
|
|
6970
|
+
for (const [i, { d }] of targets.entries()) {
|
|
6971
|
+
questions[`d${i}`] = {
|
|
6972
|
+
type: "choice",
|
|
6973
|
+
instructions: `What severity should this extraction diagnostic have? ${d.message}`,
|
|
6974
|
+
criteria: {
|
|
6975
|
+
error: "Blocks a correct spec",
|
|
6976
|
+
warning: "Likely a real API gap",
|
|
6977
|
+
info: "Informational only"
|
|
6978
|
+
}
|
|
6979
|
+
};
|
|
6980
|
+
}
|
|
6981
|
+
const result = await jevEvaluate(evaluate, {
|
|
6982
|
+
diagnostics: targets.map(({ d }) => ({
|
|
6983
|
+
code: d.code,
|
|
6984
|
+
message: d.message,
|
|
6985
|
+
severity: d.severity
|
|
6986
|
+
}))
|
|
6987
|
+
}, questions);
|
|
6988
|
+
for (const [i, { d }] of targets.entries()) {
|
|
6989
|
+
const id = `d${i}`;
|
|
6990
|
+
const choice = result.answers[id]?.choice;
|
|
6991
|
+
if (choice !== "error" && choice !== "warning" && choice !== "info")
|
|
6992
|
+
continue;
|
|
6993
|
+
const conf = namedConfidence(result, id) ?? result.answers[id]?.probabilities?.[choice] ?? 0;
|
|
6994
|
+
if (conf < JEV_CONFIDENCE)
|
|
6995
|
+
continue;
|
|
6996
|
+
d.severity = choice;
|
|
6997
|
+
}
|
|
6998
|
+
}
|
|
6999
|
+
|
|
6247
7000
|
// src/builder/schema-merger.ts
|
|
6248
7001
|
function mergeRuntimeSchemas(staticExports, runtimeSchemas) {
|
|
6249
7002
|
let merged = 0;
|
|
@@ -6273,7 +7026,7 @@ function mergeRuntimeSchemas(staticExports, runtimeSchemas) {
|
|
|
6273
7026
|
}
|
|
6274
7027
|
|
|
6275
7028
|
// src/builder/type-cache.ts
|
|
6276
|
-
import
|
|
7029
|
+
import ts17 from "typescript";
|
|
6277
7030
|
|
|
6278
7031
|
// src/utils/cache-manager.ts
|
|
6279
7032
|
class CacheManager {
|
|
@@ -6380,10 +7133,10 @@ function findTypeDefinition(typeName, program, sourceFile) {
|
|
|
6380
7133
|
return typeDefinitionCache.getOrCompute(typeName, () => {
|
|
6381
7134
|
const checker = program.getTypeChecker();
|
|
6382
7135
|
const findInNode = (node) => {
|
|
6383
|
-
if ((
|
|
7136
|
+
if ((ts17.isInterfaceDeclaration(node) || ts17.isTypeAliasDeclaration(node) || ts17.isClassDeclaration(node) || ts17.isEnumDeclaration(node)) && node.name?.text === typeName) {
|
|
6384
7137
|
return node.getSourceFile().fileName;
|
|
6385
7138
|
}
|
|
6386
|
-
return
|
|
7139
|
+
return ts17.forEachChild(node, findInNode);
|
|
6387
7140
|
};
|
|
6388
7141
|
const entryResult = findInNode(sourceFile);
|
|
6389
7142
|
if (entryResult)
|
|
@@ -6395,14 +7148,14 @@ function findTypeDefinition(typeName, program, sourceFile) {
|
|
|
6395
7148
|
return result;
|
|
6396
7149
|
}
|
|
6397
7150
|
}
|
|
6398
|
-
const symbol = checker.resolveName(typeName, sourceFile,
|
|
7151
|
+
const symbol = checker.resolveName(typeName, sourceFile, ts17.SymbolFlags.Type, false);
|
|
6399
7152
|
return symbol?.declarations?.[0]?.getSourceFile().fileName;
|
|
6400
7153
|
});
|
|
6401
7154
|
}
|
|
6402
7155
|
function hasInternalTag(typeName, program, sourceFile) {
|
|
6403
7156
|
return internalTagCache.getOrCompute(typeName, () => {
|
|
6404
7157
|
const checker = program.getTypeChecker();
|
|
6405
|
-
const symbol = checker.resolveName(typeName, sourceFile,
|
|
7158
|
+
const symbol = checker.resolveName(typeName, sourceFile, ts17.SymbolFlags.Type, false);
|
|
6406
7159
|
if (!symbol)
|
|
6407
7160
|
return false;
|
|
6408
7161
|
return symbol.getJsDocTags().some((tag) => tag.name === "internal");
|
|
@@ -6410,7 +7163,7 @@ function hasInternalTag(typeName, program, sourceFile) {
|
|
|
6410
7163
|
}
|
|
6411
7164
|
|
|
6412
7165
|
// src/builder/type-expansion.ts
|
|
6413
|
-
import
|
|
7166
|
+
import ts18 from "typescript";
|
|
6414
7167
|
var NODE_MODULES_PKG2 = /node_modules\/(@[^/]+\/[^/]+|[^/]+)/;
|
|
6415
7168
|
function isLibFile(fileName) {
|
|
6416
7169
|
return fileName.includes("/typescript/lib/lib.") || fileName.includes("\\typescript\\lib\\lib.");
|
|
@@ -6427,8 +7180,9 @@ function createExternalExpansionPredicate(opts) {
|
|
|
6427
7180
|
return false;
|
|
6428
7181
|
if (opts.followExternal === true)
|
|
6429
7182
|
return true;
|
|
6430
|
-
if (Array.isArray(opts.followExternal) && opts.followExternal.some((e) => matchesEntry(e, pkg)))
|
|
7183
|
+
if (Array.isArray(opts.followExternal) && opts.followExternal.some((e) => matchesEntry(e, pkg))) {
|
|
6431
7184
|
return true;
|
|
7185
|
+
}
|
|
6432
7186
|
return opts.workspacePackages.has(pkg);
|
|
6433
7187
|
};
|
|
6434
7188
|
return (symbol) => {
|
|
@@ -6444,6 +7198,66 @@ function createExternalExpansionPredicate(opts) {
|
|
|
6444
7198
|
return true;
|
|
6445
7199
|
};
|
|
6446
7200
|
}
|
|
7201
|
+
function collectReferencedExternals(exportedSymbols, checker, workspacePackages) {
|
|
7202
|
+
const out = [];
|
|
7203
|
+
const seen = new Set;
|
|
7204
|
+
const visited = new Set;
|
|
7205
|
+
const consider = (symbol) => {
|
|
7206
|
+
if (!symbol)
|
|
7207
|
+
return;
|
|
7208
|
+
const decl = symbol.declarations?.[0];
|
|
7209
|
+
if (!decl)
|
|
7210
|
+
return;
|
|
7211
|
+
const fileName = decl.getSourceFile().fileName;
|
|
7212
|
+
if (isLibFile(fileName))
|
|
7213
|
+
return;
|
|
7214
|
+
const match = fileName.match(NODE_MODULES_PKG2);
|
|
7215
|
+
if (!match)
|
|
7216
|
+
return;
|
|
7217
|
+
const pkg = match[1];
|
|
7218
|
+
if (pkg === "typescript" || workspacePackages.has(pkg))
|
|
7219
|
+
return;
|
|
7220
|
+
const typeName = symbol.getName();
|
|
7221
|
+
if (typeName.startsWith("__"))
|
|
7222
|
+
return;
|
|
7223
|
+
const key = `${pkg}:${typeName}`;
|
|
7224
|
+
if (seen.has(key))
|
|
7225
|
+
return;
|
|
7226
|
+
seen.add(key);
|
|
7227
|
+
out.push({ typeName, package: pkg });
|
|
7228
|
+
};
|
|
7229
|
+
const visit = (type, depth) => {
|
|
7230
|
+
if (!type || depth > 20 || visited.has(type))
|
|
7231
|
+
return;
|
|
7232
|
+
visited.add(type);
|
|
7233
|
+
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
7234
|
+
consider(symbol);
|
|
7235
|
+
const match = symbol?.declarations?.[0]?.getSourceFile().fileName.match(NODE_MODULES_PKG2);
|
|
7236
|
+
if (match && !workspacePackages.has(match[1]))
|
|
7237
|
+
return;
|
|
7238
|
+
for (const arg of type.aliasTypeArguments ?? [])
|
|
7239
|
+
visit(arg, depth + 1);
|
|
7240
|
+
const typeRef = type;
|
|
7241
|
+
if (typeRef.target) {
|
|
7242
|
+
for (const arg of checker.getTypeArguments(typeRef) ?? [])
|
|
7243
|
+
visit(arg, depth + 1);
|
|
7244
|
+
}
|
|
7245
|
+
if (type.isUnion() || type.isIntersection()) {
|
|
7246
|
+
for (const t of type.types)
|
|
7247
|
+
visit(t, depth + 1);
|
|
7248
|
+
}
|
|
7249
|
+
for (const sig of [...type.getCallSignatures(), ...type.getConstructSignatures()]) {
|
|
7250
|
+
for (const param of sig.getParameters())
|
|
7251
|
+
visit(checker.getTypeOfSymbol(param), depth + 1);
|
|
7252
|
+
visit(sig.getReturnType(), depth + 1);
|
|
7253
|
+
}
|
|
7254
|
+
};
|
|
7255
|
+
for (const symbol of exportedSymbols) {
|
|
7256
|
+
visit(checker.getTypeOfSymbol(symbol), 0);
|
|
7257
|
+
visit(checker.getDeclaredTypeOfSymbol(symbol), 0);
|
|
7258
|
+
}
|
|
7259
|
+
return out;
|
|
7260
|
+
}
|
|
6447
7261
|
function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
6448
7262
|
if (opts.followExternal === false)
|
|
6449
7263
|
return;
|
|
@@ -6479,7 +7293,7 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
6479
7293
|
visit(t, depth + 1);
|
|
6480
7294
|
}
|
|
6481
7295
|
}
|
|
6482
|
-
if (!allowed || !(type.flags &
|
|
7296
|
+
if (!allowed || !(type.flags & ts18.TypeFlags.Object || type.isClassOrInterface())) {
|
|
6483
7297
|
return;
|
|
6484
7298
|
}
|
|
6485
7299
|
if (type.isClassOrInterface()) {
|
|
@@ -6502,19 +7316,19 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
6502
7316
|
visit(info.type, depth + 1);
|
|
6503
7317
|
}
|
|
6504
7318
|
};
|
|
6505
|
-
const TYPE_SYMBOL_FLAGS =
|
|
7319
|
+
const TYPE_SYMBOL_FLAGS = ts18.SymbolFlags.Interface | ts18.SymbolFlags.TypeAlias | ts18.SymbolFlags.Class | ts18.SymbolFlags.RegularEnum | ts18.SymbolFlags.ConstEnum;
|
|
6506
7320
|
const visitedSymbols = new Set;
|
|
6507
7321
|
const symbolKind = (symbol) => {
|
|
6508
|
-
if (symbol.flags &
|
|
7322
|
+
if (symbol.flags & ts18.SymbolFlags.Interface)
|
|
6509
7323
|
return "interface";
|
|
6510
|
-
if (symbol.flags &
|
|
7324
|
+
if (symbol.flags & ts18.SymbolFlags.Class)
|
|
6511
7325
|
return "class";
|
|
6512
|
-
if (symbol.flags & (
|
|
7326
|
+
if (symbol.flags & (ts18.SymbolFlags.RegularEnum | ts18.SymbolFlags.ConstEnum))
|
|
6513
7327
|
return "enum";
|
|
6514
7328
|
return "type";
|
|
6515
7329
|
};
|
|
6516
7330
|
const resolveAlias = (symbol) => {
|
|
6517
|
-
if (symbol.flags &
|
|
7331
|
+
if (symbol.flags & ts18.SymbolFlags.Alias) {
|
|
6518
7332
|
try {
|
|
6519
7333
|
return checker.getAliasedSymbol(symbol);
|
|
6520
7334
|
} catch {
|
|
@@ -6566,7 +7380,7 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
6566
7380
|
const target = symbol && resolveAlias(symbol);
|
|
6567
7381
|
if (!target || visitedSymbols.has(target))
|
|
6568
7382
|
return;
|
|
6569
|
-
if (!(target.flags & (
|
|
7383
|
+
if (!(target.flags & (ts18.SymbolFlags.ValueModule | ts18.SymbolFlags.NamespaceModule)))
|
|
6570
7384
|
return;
|
|
6571
7385
|
if (!symbolAllowed(target))
|
|
6572
7386
|
return;
|
|
@@ -6581,22 +7395,22 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
6581
7395
|
}
|
|
6582
7396
|
};
|
|
6583
7397
|
const walkNode = (node) => {
|
|
6584
|
-
if (
|
|
7398
|
+
if (ts18.isTypeReferenceNode(node)) {
|
|
6585
7399
|
handleRef(node.typeName);
|
|
6586
|
-
if (
|
|
7400
|
+
if (ts18.isQualifiedName(node.typeName)) {
|
|
6587
7401
|
handleNamespaceRef(node.typeName.left);
|
|
6588
7402
|
}
|
|
6589
|
-
} else if (
|
|
7403
|
+
} else if (ts18.isExpressionWithTypeArguments(node)) {
|
|
6590
7404
|
handleRef(node.expression);
|
|
6591
|
-
} else if (
|
|
7405
|
+
} else if (ts18.isTypeQueryNode(node)) {
|
|
6592
7406
|
handleRef(node.exprName);
|
|
6593
|
-
if (
|
|
7407
|
+
if (ts18.isQualifiedName(node.exprName)) {
|
|
6594
7408
|
handleRef(node.exprName.left);
|
|
6595
7409
|
handleNamespaceRef(node.exprName.left);
|
|
6596
7410
|
}
|
|
6597
|
-
} else if (
|
|
7411
|
+
} else if (ts18.isImportTypeNode(node) && node.qualifier) {
|
|
6598
7412
|
handleRef(node.qualifier);
|
|
6599
|
-
if (
|
|
7413
|
+
if (ts18.isQualifiedName(node.qualifier)) {
|
|
6600
7414
|
handleNamespaceRef(node.qualifier.left);
|
|
6601
7415
|
}
|
|
6602
7416
|
}
|
|
@@ -6612,7 +7426,7 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
6612
7426
|
};
|
|
6613
7427
|
for (const exportSymbol of exportedSymbols) {
|
|
6614
7428
|
let target = exportSymbol;
|
|
6615
|
-
if (exportSymbol.flags &
|
|
7429
|
+
if (exportSymbol.flags & ts18.SymbolFlags.Alias) {
|
|
6616
7430
|
try {
|
|
6617
7431
|
target = checker.getAliasedSymbol(exportSymbol);
|
|
6618
7432
|
} catch {
|
|
@@ -6631,7 +7445,7 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
6631
7445
|
}
|
|
6632
7446
|
|
|
6633
7447
|
// src/builder/verification.ts
|
|
6634
|
-
import * as
|
|
7448
|
+
import * as path9 from "node:path";
|
|
6635
7449
|
var BUILTIN_TYPES2 = new Set([
|
|
6636
7450
|
"Array",
|
|
6637
7451
|
"ArrayBuffer",
|
|
@@ -6720,8 +7534,8 @@ function isExternalType2(definedIn, baseDir) {
|
|
|
6720
7534
|
return true;
|
|
6721
7535
|
if (definedIn.includes("node_modules"))
|
|
6722
7536
|
return true;
|
|
6723
|
-
const normalizedDefined =
|
|
6724
|
-
const normalizedBase =
|
|
7537
|
+
const normalizedDefined = path9.resolve(definedIn);
|
|
7538
|
+
const normalizedBase = path9.resolve(baseDir);
|
|
6725
7539
|
return !normalizedDefined.startsWith(normalizedBase);
|
|
6726
7540
|
}
|
|
6727
7541
|
function shouldSkipDanglingRef(name) {
|
|
@@ -6886,7 +7700,7 @@ async function extract(options) {
|
|
|
6886
7700
|
const { program, sourceFile } = result;
|
|
6887
7701
|
if (!sourceFile) {
|
|
6888
7702
|
return {
|
|
6889
|
-
spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
|
|
7703
|
+
spec: createEmptySpec(entryFile, includeSchema, isDtsSource, options.entryPointSource),
|
|
6890
7704
|
diagnostics: [
|
|
6891
7705
|
{
|
|
6892
7706
|
message: `Entry file not found: ${entryFile}. Specify with: drift list src/index.ts`,
|
|
@@ -6899,7 +7713,7 @@ async function extract(options) {
|
|
|
6899
7713
|
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
6900
7714
|
if (!moduleSymbol) {
|
|
6901
7715
|
return {
|
|
6902
|
-
spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
|
|
7716
|
+
spec: createEmptySpec(entryFile, includeSchema, isDtsSource, options.entryPointSource),
|
|
6903
7717
|
diagnostics: [
|
|
6904
7718
|
{
|
|
6905
7719
|
message: `No exports found in ${entryFile}. Is this the right entry point?`,
|
|
@@ -6911,7 +7725,7 @@ async function extract(options) {
|
|
|
6911
7725
|
const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
|
|
6912
7726
|
if (exportedSymbols.length === 0) {
|
|
6913
7727
|
return {
|
|
6914
|
-
spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
|
|
7728
|
+
spec: createEmptySpec(entryFile, includeSchema, isDtsSource, options.entryPointSource),
|
|
6915
7729
|
diagnostics: [
|
|
6916
7730
|
{
|
|
6917
7731
|
message: `No exports found in ${entryFile}. Is this the right entry point?`,
|
|
@@ -6935,6 +7749,36 @@ async function extract(options) {
|
|
|
6935
7749
|
...included ? {} : { skipReason: "filtered" }
|
|
6936
7750
|
});
|
|
6937
7751
|
}
|
|
7752
|
+
let followExternal = options.followExternal;
|
|
7753
|
+
let evaluate = options.evaluate;
|
|
7754
|
+
const wantsJev = options.decisions === "jev" || followExternal === "auto";
|
|
7755
|
+
if (wantsJev && !evaluate) {
|
|
7756
|
+
if (process.env.AI_GATEWAY_API_KEY) {
|
|
7757
|
+
try {
|
|
7758
|
+
evaluate = await loadEvaluate();
|
|
7759
|
+
} catch (err) {
|
|
7760
|
+
diagnostics.push({
|
|
7761
|
+
message: err instanceof Error ? err.message : String(err),
|
|
7762
|
+
severity: "error",
|
|
7763
|
+
code: "JEV_UNAVAILABLE"
|
|
7764
|
+
});
|
|
7765
|
+
}
|
|
7766
|
+
} else if (followExternal === "auto") {
|
|
7767
|
+
diagnostics.push({
|
|
7768
|
+
message: "followExternal auto requires --jev and AI_GATEWAY_API_KEY",
|
|
7769
|
+
severity: "error",
|
|
7770
|
+
code: "JEV_UNAVAILABLE"
|
|
7771
|
+
});
|
|
7772
|
+
}
|
|
7773
|
+
}
|
|
7774
|
+
if (followExternal === "auto") {
|
|
7775
|
+
if (!evaluate) {
|
|
7776
|
+
followExternal = undefined;
|
|
7777
|
+
} else {
|
|
7778
|
+
const refs = collectReferencedExternals(exportedSymbols, typeChecker, result.workspacePackages ?? new Map);
|
|
7779
|
+
followExternal = await selectFollowExternal(refs, evaluate);
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
6938
7782
|
const ctx = createContext(program, sourceFile, {
|
|
6939
7783
|
maxTypeDepth,
|
|
6940
7784
|
maxExternalTypeDepth,
|
|
@@ -6943,7 +7787,7 @@ async function extract(options) {
|
|
|
6943
7787
|
maxProperties,
|
|
6944
7788
|
onTruncation,
|
|
6945
7789
|
shouldExpandExternal: createExternalExpansionPredicate({
|
|
6946
|
-
followExternal
|
|
7790
|
+
followExternal,
|
|
6947
7791
|
workspacePackages: result.workspacePackages ?? new Map
|
|
6948
7792
|
}),
|
|
6949
7793
|
workspacePackages: result.workspacePackages ?? new Map
|
|
@@ -6975,9 +7819,9 @@ async function extract(options) {
|
|
|
6975
7819
|
break;
|
|
6976
7820
|
}
|
|
6977
7821
|
}
|
|
6978
|
-
if (
|
|
7822
|
+
if (ts19.isExportSpecifier(decl)) {
|
|
6979
7823
|
const exportDecl = decl.parent?.parent;
|
|
6980
|
-
if (exportDecl &&
|
|
7824
|
+
if (exportDecl && ts19.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
|
|
6981
7825
|
const moduleText = exportDecl.moduleSpecifier.getText().slice(1, -1);
|
|
6982
7826
|
if (!moduleText.startsWith(".") && !moduleText.startsWith("/")) {
|
|
6983
7827
|
externalPackage = moduleText;
|
|
@@ -7041,12 +7885,12 @@ async function extract(options) {
|
|
|
7041
7885
|
const verification = buildVerificationSummary(exportedSymbols.length, exports.length, exportTracker);
|
|
7042
7886
|
const meta = await getPackageMeta(entryFile, baseDir);
|
|
7043
7887
|
expandReachableTypes(filteredSymbols, ctx, {
|
|
7044
|
-
followExternal
|
|
7888
|
+
followExternal,
|
|
7045
7889
|
workspacePackages: result.workspacePackages ?? new Map,
|
|
7046
7890
|
entryFile
|
|
7047
7891
|
});
|
|
7048
7892
|
{
|
|
7049
|
-
const symFlags =
|
|
7893
|
+
const symFlags = ts19.SymbolFlags.Type | ts19.SymbolFlags.Interface | ts19.SymbolFlags.Class;
|
|
7050
7894
|
const maxPasses = 5;
|
|
7051
7895
|
for (let pass = 0;pass < maxPasses; pass++) {
|
|
7052
7896
|
const allRefs = new Map;
|
|
@@ -7081,7 +7925,7 @@ async function extract(options) {
|
|
|
7081
7925
|
}
|
|
7082
7926
|
}
|
|
7083
7927
|
const types = ctx.typeRegistry.getAll();
|
|
7084
|
-
const projectBaseDir = baseDir ??
|
|
7928
|
+
const projectBaseDir = baseDir ?? path10.dirname(entryFile);
|
|
7085
7929
|
const definedTypes = new Set(types.map((t) => t.id));
|
|
7086
7930
|
const forgottenExports = collectForgottenExports(exports, types, program, sourceFile, exportedIds, projectBaseDir, definedTypes);
|
|
7087
7931
|
for (const forgotten of forgottenExports) {
|
|
@@ -7114,7 +7958,7 @@ async function extract(options) {
|
|
|
7114
7958
|
}
|
|
7115
7959
|
let runtimeMetadata;
|
|
7116
7960
|
if (options.schemaExtraction === "hybrid") {
|
|
7117
|
-
const projectBaseDir2 = baseDir ||
|
|
7961
|
+
const projectBaseDir2 = baseDir || path10.dirname(entryFile);
|
|
7118
7962
|
const runtimeResult = await extractStandardSchemasFromProject(entryFile, projectBaseDir2, {
|
|
7119
7963
|
target: "draft-2020-12",
|
|
7120
7964
|
timeout: 15000
|
|
@@ -7159,6 +8003,7 @@ async function extract(options) {
|
|
|
7159
8003
|
generator: "@openpkg-ts/sdk",
|
|
7160
8004
|
timestamp: new Date().toISOString(),
|
|
7161
8005
|
mode: isDtsSource ? "declaration-only" : "source",
|
|
8006
|
+
...generationEntry(entryFile, options.entryPointSource),
|
|
7162
8007
|
...options.schemaExtraction === "hybrid" ? { schemaExtraction: "hybrid" } : {},
|
|
7163
8008
|
...isDtsSource && {
|
|
7164
8009
|
limitations: ["No JSDoc descriptions", "No @example tags", "No @param descriptions"]
|
|
@@ -7179,6 +8024,9 @@ async function extract(options) {
|
|
|
7179
8024
|
suggestion: "Check serialization errors for these exports"
|
|
7180
8025
|
});
|
|
7181
8026
|
}
|
|
8027
|
+
if (evaluate) {
|
|
8028
|
+
await calibrateDiagnostics(diagnostics, evaluate);
|
|
8029
|
+
}
|
|
7182
8030
|
return {
|
|
7183
8031
|
spec,
|
|
7184
8032
|
diagnostics,
|
|
@@ -7193,21 +8041,21 @@ async function extract(options) {
|
|
|
7193
8041
|
}
|
|
7194
8042
|
function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTypeOnly = false) {
|
|
7195
8043
|
let result = null;
|
|
7196
|
-
if (
|
|
8044
|
+
if (ts19.isFunctionDeclaration(declaration)) {
|
|
7197
8045
|
result = serializeFunctionExport(declaration, ctx);
|
|
7198
|
-
} else if (
|
|
8046
|
+
} else if (ts19.isClassDeclaration(declaration)) {
|
|
7199
8047
|
result = serializeClass(declaration, ctx);
|
|
7200
|
-
} else if (
|
|
8048
|
+
} else if (ts19.isInterfaceDeclaration(declaration)) {
|
|
7201
8049
|
result = serializeInterface(declaration, ctx);
|
|
7202
|
-
} else if (
|
|
8050
|
+
} else if (ts19.isTypeAliasDeclaration(declaration)) {
|
|
7203
8051
|
result = serializeTypeAlias(declaration, ctx);
|
|
7204
|
-
} else if (
|
|
8052
|
+
} else if (ts19.isEnumDeclaration(declaration)) {
|
|
7205
8053
|
result = serializeEnum(declaration, ctx);
|
|
7206
|
-
} else if (
|
|
8054
|
+
} else if (ts19.isVariableDeclaration(declaration)) {
|
|
7207
8055
|
const varStatement = declaration.parent?.parent;
|
|
7208
|
-
if (varStatement &&
|
|
7209
|
-
if (declaration.initializer && (
|
|
7210
|
-
const varName =
|
|
8056
|
+
if (varStatement && ts19.isVariableStatement(varStatement)) {
|
|
8057
|
+
if (declaration.initializer && (ts19.isArrowFunction(declaration.initializer) || ts19.isFunctionExpression(declaration.initializer))) {
|
|
8058
|
+
const varName = ts19.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
|
|
7211
8059
|
result = serializeFunctionExport(declaration.initializer, ctx, varName);
|
|
7212
8060
|
} else {
|
|
7213
8061
|
result = serializeVariable(declaration, varStatement, ctx);
|
|
@@ -7219,7 +8067,7 @@ function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTyp
|
|
|
7219
8067
|
}
|
|
7220
8068
|
}
|
|
7221
8069
|
}
|
|
7222
|
-
} else if (
|
|
8070
|
+
} else if (ts19.isNamespaceExport(declaration) || ts19.isModuleDeclaration(declaration) || ts19.isNamespaceImport(declaration) || ts19.isSourceFile(declaration)) {
|
|
7223
8071
|
try {
|
|
7224
8072
|
result = serializeNamespaceExport(exportSymbol, exportName, ctx);
|
|
7225
8073
|
} catch {
|
|
@@ -7256,7 +8104,7 @@ function serializeNamespaceExport(symbol, exportName, ctx) {
|
|
|
7256
8104
|
const members = [];
|
|
7257
8105
|
const checker = ctx.program.getTypeChecker();
|
|
7258
8106
|
let targetSymbol = symbol;
|
|
7259
|
-
if (symbol.flags &
|
|
8107
|
+
if (symbol.flags & ts19.SymbolFlags.Alias) {
|
|
7260
8108
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
7261
8109
|
if (aliased && aliased !== symbol) {
|
|
7262
8110
|
targetSymbol = aliased;
|
|
@@ -7284,31 +8132,31 @@ function serializeNamespaceExport(symbol, exportName, ctx) {
|
|
|
7284
8132
|
function serializeNamespaceMember(symbol, memberName, ctx) {
|
|
7285
8133
|
const checker = ctx.program.getTypeChecker();
|
|
7286
8134
|
let targetSymbol = symbol;
|
|
7287
|
-
if (symbol.flags &
|
|
8135
|
+
if (symbol.flags & ts19.SymbolFlags.Alias) {
|
|
7288
8136
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
7289
8137
|
if (aliased && aliased !== symbol) {
|
|
7290
8138
|
targetSymbol = aliased;
|
|
7291
8139
|
}
|
|
7292
8140
|
}
|
|
7293
8141
|
const declarations = targetSymbol.declarations ?? [];
|
|
7294
|
-
const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !==
|
|
8142
|
+
const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts19.SyntaxKind.ExportSpecifier) || declarations[0];
|
|
7295
8143
|
if (!declaration)
|
|
7296
8144
|
return null;
|
|
7297
8145
|
const type = checker.getTypeAtLocation(declaration);
|
|
7298
8146
|
const callSignatures = type.getCallSignatures();
|
|
7299
8147
|
const { deprecated } = isSymbolDeprecated(targetSymbol);
|
|
7300
8148
|
let kind = "variable";
|
|
7301
|
-
if (
|
|
8149
|
+
if (ts19.isFunctionDeclaration(declaration) || ts19.isFunctionExpression(declaration)) {
|
|
7302
8150
|
kind = "function";
|
|
7303
|
-
} else if (
|
|
8151
|
+
} else if (ts19.isClassDeclaration(declaration)) {
|
|
7304
8152
|
kind = "class";
|
|
7305
|
-
} else if (
|
|
8153
|
+
} else if (ts19.isInterfaceDeclaration(declaration)) {
|
|
7306
8154
|
kind = "interface";
|
|
7307
|
-
} else if (
|
|
8155
|
+
} else if (ts19.isTypeAliasDeclaration(declaration)) {
|
|
7308
8156
|
kind = "type";
|
|
7309
|
-
} else if (
|
|
8157
|
+
} else if (ts19.isEnumDeclaration(declaration)) {
|
|
7310
8158
|
kind = "enum";
|
|
7311
|
-
} else if (
|
|
8159
|
+
} else if (ts19.isVariableDeclaration(declaration)) {
|
|
7312
8160
|
if (callSignatures.length > 0) {
|
|
7313
8161
|
kind = "function";
|
|
7314
8162
|
}
|
|
@@ -7339,18 +8187,18 @@ function serializeNamespaceMember(symbol, memberName, ctx) {
|
|
|
7339
8187
|
function flattenJSDocComment(comment) {
|
|
7340
8188
|
if (comment === undefined)
|
|
7341
8189
|
return "";
|
|
7342
|
-
return typeof comment === "string" ? comment :
|
|
8190
|
+
return typeof comment === "string" ? comment : ts19.getTextOfJSDocComment(comment) ?? "";
|
|
7343
8191
|
}
|
|
7344
8192
|
function getJSDocFromExportSymbol(symbol) {
|
|
7345
8193
|
const tags = [];
|
|
7346
8194
|
const examples = [];
|
|
7347
8195
|
const decl = symbol.declarations?.[0];
|
|
7348
8196
|
if (decl) {
|
|
7349
|
-
const exportDecl =
|
|
7350
|
-
if (exportDecl &&
|
|
7351
|
-
const jsDocs =
|
|
8197
|
+
const exportDecl = ts19.isNamespaceExport(decl) ? decl.parent : decl;
|
|
8198
|
+
if (exportDecl && ts19.isExportDeclaration(exportDecl)) {
|
|
8199
|
+
const jsDocs = ts19.getJSDocCommentsAndTags(exportDecl);
|
|
7352
8200
|
for (const doc of jsDocs) {
|
|
7353
|
-
if (
|
|
8201
|
+
if (ts19.isJSDoc(doc) && doc.comment) {
|
|
7354
8202
|
const commentText = flattenJSDocComment(doc.comment);
|
|
7355
8203
|
if (commentText) {
|
|
7356
8204
|
return {
|
|
@@ -7409,16 +8257,24 @@ function withExportName(entry, exportName) {
|
|
|
7409
8257
|
name: exportName
|
|
7410
8258
|
};
|
|
7411
8259
|
}
|
|
7412
|
-
function
|
|
8260
|
+
function generationEntry(entryFile, source) {
|
|
8261
|
+
const rel = path10.relative(process.cwd(), entryFile).split(path10.sep).join("/");
|
|
8262
|
+
return {
|
|
8263
|
+
entryPoint: rel || entryFile,
|
|
8264
|
+
entryPointSource: source ?? "explicit"
|
|
8265
|
+
};
|
|
8266
|
+
}
|
|
8267
|
+
function createEmptySpec(entryFile, includeSchema, isDtsSource, entryPointSource) {
|
|
7413
8268
|
return {
|
|
7414
8269
|
...includeSchema ? { $schema: SCHEMA_URL } : {},
|
|
7415
8270
|
openpkg: SCHEMA_VERSION,
|
|
7416
|
-
meta: { name:
|
|
8271
|
+
meta: { name: path10.basename(entryFile, path10.extname(entryFile)) },
|
|
7417
8272
|
exports: [],
|
|
7418
8273
|
generation: {
|
|
7419
8274
|
generator: "@openpkg-ts/sdk",
|
|
7420
8275
|
timestamp: new Date().toISOString(),
|
|
7421
8276
|
mode: isDtsSource ? "declaration-only" : "source",
|
|
8277
|
+
...generationEntry(entryFile, entryPointSource),
|
|
7422
8278
|
...isDtsSource && {
|
|
7423
8279
|
limitations: ["No JSDoc descriptions", "No @example tags", "No @param descriptions"]
|
|
7424
8280
|
}
|
|
@@ -7429,7 +8285,7 @@ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
|
|
|
7429
8285
|
const localSym = checker.resolveName(name, sourceFile, symFlags, false);
|
|
7430
8286
|
if (localSym)
|
|
7431
8287
|
return checker.getDeclaredTypeOfSymbol(localSym);
|
|
7432
|
-
const entryDir =
|
|
8288
|
+
const entryDir = path10.dirname(sourceFile.fileName);
|
|
7433
8289
|
for (const sf of program.getSourceFiles()) {
|
|
7434
8290
|
const fn = sf.fileName;
|
|
7435
8291
|
if (fn.includes("/typescript/lib/lib.") || fn.includes("\\typescript\\lib\\lib."))
|
|
@@ -7445,22 +8301,22 @@ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
|
|
|
7445
8301
|
return;
|
|
7446
8302
|
}
|
|
7447
8303
|
async function getPackageMeta(entryFile, baseDir) {
|
|
7448
|
-
let dir = baseDir ??
|
|
7449
|
-
while (dir !==
|
|
7450
|
-
const pkgPath =
|
|
8304
|
+
let dir = baseDir ?? path10.dirname(entryFile);
|
|
8305
|
+
while (dir !== path10.dirname(dir)) {
|
|
8306
|
+
const pkgPath = path10.join(dir, "package.json");
|
|
7451
8307
|
try {
|
|
7452
|
-
if (
|
|
7453
|
-
const pkg = JSON.parse(
|
|
8308
|
+
if (fs7.existsSync(pkgPath)) {
|
|
8309
|
+
const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
|
|
7454
8310
|
return {
|
|
7455
|
-
name: pkg.name ??
|
|
8311
|
+
name: pkg.name ?? path10.basename(dir),
|
|
7456
8312
|
version: pkg.version,
|
|
7457
8313
|
description: pkg.description
|
|
7458
8314
|
};
|
|
7459
8315
|
}
|
|
7460
8316
|
} catch {}
|
|
7461
|
-
dir =
|
|
8317
|
+
dir = path10.dirname(dir);
|
|
7462
8318
|
}
|
|
7463
|
-
return { name:
|
|
8319
|
+
return { name: path10.basename(baseDir ?? path10.dirname(entryFile)) };
|
|
7464
8320
|
}
|
|
7465
8321
|
|
|
7466
8322
|
// src/primitives/spec.ts
|
|
@@ -7945,12 +8801,12 @@ function toToolSchema(exp, spec, options) {
|
|
|
7945
8801
|
};
|
|
7946
8802
|
}
|
|
7947
8803
|
// src/types/utils.ts
|
|
7948
|
-
import
|
|
8804
|
+
import ts20 from "typescript";
|
|
7949
8805
|
function isExported(node) {
|
|
7950
8806
|
const modifiers = node.modifiers;
|
|
7951
8807
|
if (!modifiers)
|
|
7952
8808
|
return false;
|
|
7953
|
-
return modifiers.some((m) => m.kind ===
|
|
8809
|
+
return modifiers.some((m) => m.kind === ts20.SyntaxKind.ExportKeyword);
|
|
7954
8810
|
}
|
|
7955
8811
|
function getNodeName(node) {
|
|
7956
8812
|
if ("name" in node && node.name) {
|
|
@@ -7994,6 +8850,7 @@ export {
|
|
|
7994
8850
|
schemasAreEqual,
|
|
7995
8851
|
schemaIsAny,
|
|
7996
8852
|
resolveTypeRef,
|
|
8853
|
+
resolveTarget,
|
|
7997
8854
|
resolveExportTarget2 as resolveExportTarget,
|
|
7998
8855
|
resolveCompiledPath,
|
|
7999
8856
|
renderTypeText,
|
|
@@ -8001,6 +8858,8 @@ export {
|
|
|
8001
8858
|
registerAdapter,
|
|
8002
8859
|
recommendSemverBump,
|
|
8003
8860
|
query,
|
|
8861
|
+
pickEntry,
|
|
8862
|
+
parseGithubRepo,
|
|
8004
8863
|
normalizeType,
|
|
8005
8864
|
normalizeSchema,
|
|
8006
8865
|
normalizeMembers,
|
|
@@ -8014,12 +8873,14 @@ export {
|
|
|
8014
8873
|
isSymbolDeprecated,
|
|
8015
8874
|
isStandardJSONSchema,
|
|
8016
8875
|
isSchemaType,
|
|
8876
|
+
isRemoteInput,
|
|
8017
8877
|
isReadonlyPropertySymbol,
|
|
8018
8878
|
isPureRefSchema,
|
|
8019
8879
|
isProperty,
|
|
8020
8880
|
isPrimitiveName,
|
|
8021
8881
|
isMethod,
|
|
8022
8882
|
isExported,
|
|
8883
|
+
isEntryFilePath,
|
|
8023
8884
|
isBuiltinSymbol,
|
|
8024
8885
|
isBuiltinGeneric,
|
|
8025
8886
|
isAnonymous,
|
|
@@ -8047,6 +8908,7 @@ export {
|
|
|
8047
8908
|
formatMappedType,
|
|
8048
8909
|
formatConditionalType,
|
|
8049
8910
|
formatBadges,
|
|
8911
|
+
findWorkspaceRoot,
|
|
8050
8912
|
findMissingParamDocs,
|
|
8051
8913
|
findDiscriminatorProperty,
|
|
8052
8914
|
findAdapter,
|
|
@@ -8070,7 +8932,9 @@ export {
|
|
|
8070
8932
|
declaredTypeNode,
|
|
8071
8933
|
createProgram,
|
|
8072
8934
|
createDocs,
|
|
8935
|
+
cloneRemote,
|
|
8073
8936
|
categorizeBreakingChanges,
|
|
8937
|
+
catalogPackages,
|
|
8074
8938
|
calculateNextVersion,
|
|
8075
8939
|
bundleRefs,
|
|
8076
8940
|
buildSignatureString,
|
|
@@ -8087,6 +8951,8 @@ export {
|
|
|
8087
8951
|
PRIMITIVES,
|
|
8088
8952
|
NUMBER_PROTOTYPE_METHODS,
|
|
8089
8953
|
LATEST_VERSION,
|
|
8954
|
+
JEV_MODEL,
|
|
8955
|
+
JEV_CONFIDENCE,
|
|
8090
8956
|
CacheManager,
|
|
8091
8957
|
CONFIG_FILENAME,
|
|
8092
8958
|
BUILTIN_TYPE_SCHEMAS,
|