@wrongstack/tools 0.7.7 → 0.7.8
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/dist/builtin.js +173 -124
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.js +173 -124
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/index.js +173 -124
- package/dist/index.js.map +1 -1
- package/dist/pack.js +173 -124
- package/dist/pack.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as fs2 from 'node:fs/promises';
|
|
2
2
|
import * as path3 from 'node:path';
|
|
3
3
|
import { compileGlob } from '@wrongstack/core';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
4
5
|
import * as fs from 'node:fs';
|
|
5
6
|
import { mkdirSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
6
|
-
import { DatabaseSync } from 'node:sqlite';
|
|
7
7
|
import * as ts from 'typescript';
|
|
8
8
|
import { execSync, spawnSync } from 'node:child_process';
|
|
9
9
|
|
|
@@ -82,12 +82,39 @@ function internalKindToLspKind(k) {
|
|
|
82
82
|
// src/codebase-index/writer.ts
|
|
83
83
|
var INDEX_DIR = ".codebase-index";
|
|
84
84
|
var DB_FILE = "index.db";
|
|
85
|
+
var warningSilenced = false;
|
|
86
|
+
function silenceSqliteExperimentalWarning() {
|
|
87
|
+
if (warningSilenced) return;
|
|
88
|
+
warningSilenced = true;
|
|
89
|
+
const original = process.emitWarning.bind(process);
|
|
90
|
+
process.emitWarning = ((warning, ...rest) => {
|
|
91
|
+
const msg = typeof warning === "string" ? warning : warning?.message ?? "";
|
|
92
|
+
const name = typeof warning === "string" ? String(rest[0] ?? "") : warning?.name ?? "";
|
|
93
|
+
if (/sqlite/i.test(msg) && /experimental/i.test(`${name} ${msg}`)) return;
|
|
94
|
+
original(warning, ...rest);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
var DatabaseSyncCtor;
|
|
98
|
+
function loadDatabaseSync() {
|
|
99
|
+
if (DatabaseSyncCtor) return DatabaseSyncCtor;
|
|
100
|
+
silenceSqliteExperimentalWarning();
|
|
101
|
+
try {
|
|
102
|
+
const req = createRequire(import.meta.url);
|
|
103
|
+
DatabaseSyncCtor = req("node:sqlite").DatabaseSync;
|
|
104
|
+
} catch (err) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`The codebase index needs Node's built-in SQLite (node:sqlite), available since Node 22.5. This runtime doesn't provide it: ${err instanceof Error ? err.message : String(err)}`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return DatabaseSyncCtor;
|
|
110
|
+
}
|
|
85
111
|
var IndexStore = class {
|
|
86
112
|
constructor(projectRoot) {
|
|
87
113
|
this.projectRoot = projectRoot;
|
|
88
114
|
const dir = path3.join(projectRoot, INDEX_DIR);
|
|
89
115
|
fs.mkdirSync(dir, { recursive: true });
|
|
90
|
-
|
|
116
|
+
const Database = loadDatabaseSync();
|
|
117
|
+
this.db = new Database(path3.join(dir, DB_FILE));
|
|
91
118
|
this.initSchema();
|
|
92
119
|
}
|
|
93
120
|
projectRoot;
|
|
@@ -1102,7 +1129,10 @@ function checkNativeParser() {
|
|
|
1102
1129
|
execSync("rustc --version", { stdio: "pipe" });
|
|
1103
1130
|
const toolsDir = path3.join(process.cwd(), "tools");
|
|
1104
1131
|
try {
|
|
1105
|
-
execSync(
|
|
1132
|
+
execSync(
|
|
1133
|
+
"cargo metadata --no-deps --format-version 1 --manifest-path " + path3.join(toolsDir, "Cargo.toml"),
|
|
1134
|
+
{ stdio: "pipe" }
|
|
1135
|
+
);
|
|
1106
1136
|
return true;
|
|
1107
1137
|
} catch {
|
|
1108
1138
|
return false;
|
|
@@ -1118,12 +1148,16 @@ function tryNativeParse(file, content) {
|
|
|
1118
1148
|
const tmpFile = path3.join(crateDir, "src", "input.rs");
|
|
1119
1149
|
const { writeFileSync: writeFileSync2 } = __require("node:fs");
|
|
1120
1150
|
writeFileSync2(tmpFile, content, "utf8");
|
|
1121
|
-
const result = spawnSync(
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1151
|
+
const result = spawnSync(
|
|
1152
|
+
"cargo",
|
|
1153
|
+
["run", "--manifest-path", path3.join(toolsDir, "Cargo.toml")],
|
|
1154
|
+
{
|
|
1155
|
+
cwd: process.cwd(),
|
|
1156
|
+
encoding: "utf8",
|
|
1157
|
+
timeout: 15e3,
|
|
1158
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1159
|
+
}
|
|
1160
|
+
);
|
|
1127
1161
|
if (result.status === 0 && result.stdout) {
|
|
1128
1162
|
const symbols = JSON.parse(result.stdout);
|
|
1129
1163
|
return {
|
|
@@ -1157,7 +1191,8 @@ function regexParse(opts) {
|
|
|
1157
1191
|
lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
|
|
1158
1192
|
}
|
|
1159
1193
|
function lineFromOffset(offset) {
|
|
1160
|
-
let lo = 0
|
|
1194
|
+
let lo = 0;
|
|
1195
|
+
let hi = lineOffsets.length - 1;
|
|
1161
1196
|
while (lo < hi) {
|
|
1162
1197
|
const mid = lo + hi + 1 >>> 1;
|
|
1163
1198
|
if (lineOffsets[mid] <= offset) lo = mid;
|
|
@@ -1171,8 +1206,7 @@ function regexParse(opts) {
|
|
|
1171
1206
|
}
|
|
1172
1207
|
for (const pattern of RS_PATTERNS) {
|
|
1173
1208
|
pattern.regex.lastIndex = 0;
|
|
1174
|
-
let match;
|
|
1175
|
-
while ((match = pattern.regex.exec(content)) !== null) {
|
|
1209
|
+
for (let match = pattern.regex.exec(content); match !== null; match = pattern.regex.exec(content)) {
|
|
1176
1210
|
const name = match[1];
|
|
1177
1211
|
const offset = match.index;
|
|
1178
1212
|
const line = lineFromOffset(offset);
|
|
@@ -1225,7 +1259,8 @@ function regexParse2(opts) {
|
|
|
1225
1259
|
lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
|
|
1226
1260
|
}
|
|
1227
1261
|
function lineFromOffset(offset) {
|
|
1228
|
-
let lo = 0
|
|
1262
|
+
let lo = 0;
|
|
1263
|
+
let hi = lineOffsets.length - 1;
|
|
1229
1264
|
while (lo < hi) {
|
|
1230
1265
|
const mid = lo + hi + 1 >>> 1;
|
|
1231
1266
|
if (lineOffsets[mid] <= offset) lo = mid;
|
|
@@ -1237,19 +1272,20 @@ function regexParse2(opts) {
|
|
|
1237
1272
|
if (rootMatch) {
|
|
1238
1273
|
const offset = rootMatch.index;
|
|
1239
1274
|
const line = lineFromOffset(offset);
|
|
1240
|
-
symbols.push(
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1275
|
+
symbols.push(
|
|
1276
|
+
makeSymbol({
|
|
1277
|
+
name: path3.basename(file),
|
|
1278
|
+
kind: "object",
|
|
1279
|
+
line,
|
|
1280
|
+
col: 0,
|
|
1281
|
+
signature: `"${path3.basename(file)}" = { ... }`,
|
|
1282
|
+
file,
|
|
1283
|
+
lang
|
|
1284
|
+
})
|
|
1285
|
+
);
|
|
1249
1286
|
}
|
|
1250
1287
|
const topLevelKeyRegex = /^\s*"([^"]+)"\s*:/gm;
|
|
1251
|
-
let match;
|
|
1252
|
-
while ((match = topLevelKeyRegex.exec(content)) !== null) {
|
|
1288
|
+
for (let match = topLevelKeyRegex.exec(content); match !== null; match = topLevelKeyRegex.exec(content)) {
|
|
1253
1289
|
const key = match[1];
|
|
1254
1290
|
const offset = match.index;
|
|
1255
1291
|
const line = lineFromOffset(offset);
|
|
@@ -1276,15 +1312,17 @@ function regexParse2(opts) {
|
|
|
1276
1312
|
signature = `"$ref": "..."`;
|
|
1277
1313
|
}
|
|
1278
1314
|
}
|
|
1279
|
-
symbols.push(
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1315
|
+
symbols.push(
|
|
1316
|
+
makeSymbol({
|
|
1317
|
+
name: key,
|
|
1318
|
+
kind,
|
|
1319
|
+
line,
|
|
1320
|
+
col,
|
|
1321
|
+
signature,
|
|
1322
|
+
file,
|
|
1323
|
+
lang
|
|
1324
|
+
})
|
|
1325
|
+
);
|
|
1288
1326
|
if (isPackageJson && key === "scripts") {
|
|
1289
1327
|
extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset);
|
|
1290
1328
|
}
|
|
@@ -1293,20 +1331,21 @@ function regexParse2(opts) {
|
|
|
1293
1331
|
}
|
|
1294
1332
|
}
|
|
1295
1333
|
const defsRegex = /"\$defs"\s*:|"\$defs"\s*:/g;
|
|
1296
|
-
|
|
1297
|
-
|
|
1334
|
+
const defsMatch = defsRegex.exec(content);
|
|
1335
|
+
if (defsMatch !== null) {
|
|
1298
1336
|
const offset = defsMatch.index;
|
|
1299
1337
|
const line = lineFromOffset(offset);
|
|
1300
|
-
symbols.push(
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1338
|
+
symbols.push(
|
|
1339
|
+
makeSymbol({
|
|
1340
|
+
name: "$defs",
|
|
1341
|
+
kind: "property",
|
|
1342
|
+
line,
|
|
1343
|
+
col: offset - (lineOffsets[line - 1] ?? 0),
|
|
1344
|
+
signature: '"$defs": { ... }',
|
|
1345
|
+
file,
|
|
1346
|
+
lang
|
|
1347
|
+
})
|
|
1348
|
+
);
|
|
1310
1349
|
}
|
|
1311
1350
|
const defsPatterns = [
|
|
1312
1351
|
/"\$defs"\s*:/g,
|
|
@@ -1316,69 +1355,71 @@ function regexParse2(opts) {
|
|
|
1316
1355
|
];
|
|
1317
1356
|
for (const pat of defsPatterns) {
|
|
1318
1357
|
pat.lastIndex = 0;
|
|
1319
|
-
|
|
1358
|
+
for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {
|
|
1320
1359
|
const offset = match.index;
|
|
1321
1360
|
const line = lineFromOffset(offset);
|
|
1322
1361
|
const key = match[0].match(/"([^"]+)"/)?.[1] ?? match[0];
|
|
1323
|
-
symbols.push(
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1362
|
+
symbols.push(
|
|
1363
|
+
makeSymbol({
|
|
1364
|
+
name: key,
|
|
1365
|
+
kind: "property",
|
|
1366
|
+
line,
|
|
1367
|
+
col: offset - (lineOffsets[line - 1] ?? 0),
|
|
1368
|
+
signature: `"${key}": { ... }`,
|
|
1369
|
+
file,
|
|
1370
|
+
lang
|
|
1371
|
+
})
|
|
1372
|
+
);
|
|
1332
1373
|
}
|
|
1333
1374
|
}
|
|
1334
1375
|
return { file, lang, symbols, mtimeMs: Date.now() };
|
|
1335
1376
|
}
|
|
1336
1377
|
function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset) {
|
|
1337
1378
|
const scriptsBlockRegex = /"scripts"\s*:\s*\{([^}]+)\}/g;
|
|
1338
|
-
let match;
|
|
1339
|
-
while ((match = scriptsBlockRegex.exec(content)) !== null) {
|
|
1379
|
+
for (let match = scriptsBlockRegex.exec(content); match !== null; match = scriptsBlockRegex.exec(content)) {
|
|
1340
1380
|
const blockContent = match[0];
|
|
1341
1381
|
const blockOffset = match.index;
|
|
1342
1382
|
const scriptKeyRegex = /"(\w[\w-]*)"\s*:/g;
|
|
1343
|
-
let scriptMatch;
|
|
1344
|
-
while ((scriptMatch = scriptKeyRegex.exec(blockContent)) !== null) {
|
|
1383
|
+
for (let scriptMatch = scriptKeyRegex.exec(blockContent); scriptMatch !== null; scriptMatch = scriptKeyRegex.exec(blockContent)) {
|
|
1345
1384
|
const key = scriptMatch[1];
|
|
1346
1385
|
const keyOffset = blockOffset + scriptMatch.index;
|
|
1347
1386
|
const line = lineFromOffset(keyOffset);
|
|
1348
|
-
symbols.push(
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1387
|
+
symbols.push(
|
|
1388
|
+
makeSymbol({
|
|
1389
|
+
name: key,
|
|
1390
|
+
kind: "function",
|
|
1391
|
+
line,
|
|
1392
|
+
col: keyOffset - (lineOffsets[line - 1] ?? 0),
|
|
1393
|
+
signature: `"${key}": "..."`,
|
|
1394
|
+
file,
|
|
1395
|
+
lang
|
|
1396
|
+
})
|
|
1397
|
+
);
|
|
1357
1398
|
}
|
|
1358
1399
|
}
|
|
1359
1400
|
}
|
|
1360
1401
|
function extractCompilerOptions(content, symbols, file, lang, lineOffsets, parentLine, lineFromOffset) {
|
|
1361
1402
|
const optsBlockRegex = /"compilerOptions"\s*:\s*\{([^}]+)\}/g;
|
|
1362
|
-
let match;
|
|
1363
|
-
while ((match = optsBlockRegex.exec(content)) !== null) {
|
|
1403
|
+
for (let match = optsBlockRegex.exec(content); match !== null; match = optsBlockRegex.exec(content)) {
|
|
1364
1404
|
const blockContent = match[0];
|
|
1365
1405
|
const blockOffset = match.index;
|
|
1366
1406
|
const optKeyRegex = /"(\w[\w]*)"\s*:/g;
|
|
1367
|
-
let optMatch;
|
|
1368
|
-
while ((optMatch = optKeyRegex.exec(blockContent)) !== null) {
|
|
1407
|
+
for (let optMatch = optKeyRegex.exec(blockContent); optMatch !== null; optMatch = optKeyRegex.exec(blockContent)) {
|
|
1369
1408
|
const key = optMatch[1];
|
|
1370
1409
|
const keyOffset = blockOffset + optMatch.index;
|
|
1371
1410
|
const line = lineFromOffset(keyOffset);
|
|
1372
1411
|
if (line <= parentLine) continue;
|
|
1373
|
-
symbols.push(
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1412
|
+
symbols.push(
|
|
1413
|
+
makeSymbol({
|
|
1414
|
+
name: key,
|
|
1415
|
+
kind: "property",
|
|
1416
|
+
line,
|
|
1417
|
+
col: keyOffset - (lineOffsets[line - 1] ?? 0),
|
|
1418
|
+
signature: `"${key}": ...`,
|
|
1419
|
+
file,
|
|
1420
|
+
lang
|
|
1421
|
+
})
|
|
1422
|
+
);
|
|
1382
1423
|
}
|
|
1383
1424
|
}
|
|
1384
1425
|
}
|
|
@@ -1416,7 +1457,8 @@ function regexParse3(opts) {
|
|
|
1416
1457
|
lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
|
|
1417
1458
|
}
|
|
1418
1459
|
function lineFromOffset(offset) {
|
|
1419
|
-
let lo = 0
|
|
1460
|
+
let lo = 0;
|
|
1461
|
+
let hi = lineOffsets.length - 1;
|
|
1420
1462
|
while (lo < hi) {
|
|
1421
1463
|
const mid = lo + hi + 1 >>> 1;
|
|
1422
1464
|
if (lineOffsets[mid] <= offset) lo = mid;
|
|
@@ -1425,40 +1467,43 @@ function regexParse3(opts) {
|
|
|
1425
1467
|
return lo + 1;
|
|
1426
1468
|
}
|
|
1427
1469
|
const anchorRegex = /&(\w[\w-]*)/g;
|
|
1428
|
-
let match;
|
|
1429
|
-
while ((match = anchorRegex.exec(content)) !== null) {
|
|
1470
|
+
for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {
|
|
1430
1471
|
const name = match[1];
|
|
1431
1472
|
const offset = match.index;
|
|
1432
1473
|
const line = lineFromOffset(offset);
|
|
1433
1474
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1434
|
-
symbols.push(
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1475
|
+
symbols.push(
|
|
1476
|
+
makeSymbol2({
|
|
1477
|
+
name,
|
|
1478
|
+
kind: "const",
|
|
1479
|
+
line,
|
|
1480
|
+
col,
|
|
1481
|
+
signature: `&${name}`,
|
|
1482
|
+
file,
|
|
1483
|
+
lang
|
|
1484
|
+
})
|
|
1485
|
+
);
|
|
1443
1486
|
}
|
|
1444
1487
|
const aliasRegex = /\*(\w[\w-]*)/g;
|
|
1445
|
-
|
|
1488
|
+
for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {
|
|
1446
1489
|
const name = match[1];
|
|
1447
1490
|
const offset = match.index;
|
|
1448
1491
|
const line = lineFromOffset(offset);
|
|
1449
1492
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1450
|
-
symbols.push(
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1493
|
+
symbols.push(
|
|
1494
|
+
makeSymbol2({
|
|
1495
|
+
name,
|
|
1496
|
+
kind: "const",
|
|
1497
|
+
line,
|
|
1498
|
+
col,
|
|
1499
|
+
signature: `*${name}`,
|
|
1500
|
+
file,
|
|
1501
|
+
lang
|
|
1502
|
+
})
|
|
1503
|
+
);
|
|
1459
1504
|
}
|
|
1460
1505
|
const kvRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:/gm;
|
|
1461
|
-
|
|
1506
|
+
for (let match = kvRegex.exec(content); match !== null; match = kvRegex.exec(content)) {
|
|
1462
1507
|
const indent = match[1].length;
|
|
1463
1508
|
const key = match[2];
|
|
1464
1509
|
const offset = match.index;
|
|
@@ -1474,38 +1519,42 @@ function regexParse3(opts) {
|
|
|
1474
1519
|
symbols.push(makeSymbol2({ name: key, kind, line, col, signature, file, lang }));
|
|
1475
1520
|
}
|
|
1476
1521
|
const listItemRegex = /^-(\s+)([^:#\s][^:#\s]*)\s*:/gm;
|
|
1477
|
-
|
|
1522
|
+
for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {
|
|
1478
1523
|
const key = match[2];
|
|
1479
1524
|
const offset = match.index;
|
|
1480
1525
|
const line = lineFromOffset(offset);
|
|
1481
1526
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1482
1527
|
const value = extractValue(content, offset + match[0].length);
|
|
1483
1528
|
const kind = isScalar(value) ? "literal" : "property";
|
|
1484
|
-
symbols.push(
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1529
|
+
symbols.push(
|
|
1530
|
+
makeSymbol2({
|
|
1531
|
+
name: key,
|
|
1532
|
+
kind,
|
|
1533
|
+
line,
|
|
1534
|
+
col,
|
|
1535
|
+
signature: `- ${key}: ${truncate(value, 60)}`,
|
|
1536
|
+
file,
|
|
1537
|
+
lang
|
|
1538
|
+
})
|
|
1539
|
+
);
|
|
1493
1540
|
}
|
|
1494
1541
|
const blockScalarRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:\s*[|>](\s|$)/gm;
|
|
1495
|
-
|
|
1542
|
+
for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {
|
|
1496
1543
|
const key = match[2];
|
|
1497
1544
|
const offset = match.index;
|
|
1498
1545
|
const line = lineFromOffset(offset);
|
|
1499
1546
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1500
|
-
symbols.push(
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1547
|
+
symbols.push(
|
|
1548
|
+
makeSymbol2({
|
|
1549
|
+
name: key,
|
|
1550
|
+
kind: "property",
|
|
1551
|
+
line,
|
|
1552
|
+
col,
|
|
1553
|
+
signature: `${key}: | ...`,
|
|
1554
|
+
file,
|
|
1555
|
+
lang
|
|
1556
|
+
})
|
|
1557
|
+
);
|
|
1509
1558
|
}
|
|
1510
1559
|
return { file, lang, symbols, mtimeMs: Date.now() };
|
|
1511
1560
|
}
|