@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/pack.js CHANGED
@@ -5,9 +5,9 @@ import { dirname } from 'node:path';
5
5
  import * as os from 'node:os';
6
6
  import * as fs11 from 'node:fs/promises';
7
7
  import { stat } from 'node:fs/promises';
8
+ import { createRequire } from 'node:module';
8
9
  import * as fs from 'node:fs';
9
10
  import { statSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs';
10
- import { DatabaseSync } from 'node:sqlite';
11
11
  import * as ts from 'typescript';
12
12
  import * as dns from 'node:dns/promises';
13
13
  import * as net from 'node:net';
@@ -952,12 +952,39 @@ function lspKindToInternalKind(k) {
952
952
  // src/codebase-index/writer.ts
953
953
  var INDEX_DIR = ".codebase-index";
954
954
  var DB_FILE = "index.db";
955
+ var warningSilenced = false;
956
+ function silenceSqliteExperimentalWarning() {
957
+ if (warningSilenced) return;
958
+ warningSilenced = true;
959
+ const original = process.emitWarning.bind(process);
960
+ process.emitWarning = ((warning, ...rest) => {
961
+ const msg = typeof warning === "string" ? warning : warning?.message ?? "";
962
+ const name = typeof warning === "string" ? String(rest[0] ?? "") : warning?.name ?? "";
963
+ if (/sqlite/i.test(msg) && /experimental/i.test(`${name} ${msg}`)) return;
964
+ original(warning, ...rest);
965
+ });
966
+ }
967
+ var DatabaseSyncCtor;
968
+ function loadDatabaseSync() {
969
+ if (DatabaseSyncCtor) return DatabaseSyncCtor;
970
+ silenceSqliteExperimentalWarning();
971
+ try {
972
+ const req = createRequire(import.meta.url);
973
+ DatabaseSyncCtor = req("node:sqlite").DatabaseSync;
974
+ } catch (err) {
975
+ throw new Error(
976
+ `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)}`
977
+ );
978
+ }
979
+ return DatabaseSyncCtor;
980
+ }
955
981
  var IndexStore = class {
956
982
  constructor(projectRoot) {
957
983
  this.projectRoot = projectRoot;
958
984
  const dir = path.join(projectRoot, INDEX_DIR);
959
985
  fs.mkdirSync(dir, { recursive: true });
960
- this.db = new DatabaseSync(path.join(dir, DB_FILE));
986
+ const Database = loadDatabaseSync();
987
+ this.db = new Database(path.join(dir, DB_FILE));
961
988
  this.initSchema();
962
989
  }
963
990
  projectRoot;
@@ -1972,7 +1999,10 @@ function checkNativeParser() {
1972
1999
  execSync("rustc --version", { stdio: "pipe" });
1973
2000
  const toolsDir = path.join(process.cwd(), "tools");
1974
2001
  try {
1975
- execSync("cargo metadata --no-deps --format-version 1 --manifest-path " + path.join(toolsDir, "Cargo.toml"), { stdio: "pipe" });
2002
+ execSync(
2003
+ "cargo metadata --no-deps --format-version 1 --manifest-path " + path.join(toolsDir, "Cargo.toml"),
2004
+ { stdio: "pipe" }
2005
+ );
1976
2006
  return true;
1977
2007
  } catch {
1978
2008
  return false;
@@ -1988,12 +2018,16 @@ function tryNativeParse(file, content) {
1988
2018
  const tmpFile = path.join(crateDir, "src", "input.rs");
1989
2019
  const { writeFileSync: writeFileSync2 } = __require("node:fs");
1990
2020
  writeFileSync2(tmpFile, content, "utf8");
1991
- const result = spawnSync("cargo", ["run", "--manifest-path", path.join(toolsDir, "Cargo.toml")], {
1992
- cwd: process.cwd(),
1993
- encoding: "utf8",
1994
- timeout: 15e3,
1995
- stdio: ["pipe", "pipe", "pipe"]
1996
- });
2021
+ const result = spawnSync(
2022
+ "cargo",
2023
+ ["run", "--manifest-path", path.join(toolsDir, "Cargo.toml")],
2024
+ {
2025
+ cwd: process.cwd(),
2026
+ encoding: "utf8",
2027
+ timeout: 15e3,
2028
+ stdio: ["pipe", "pipe", "pipe"]
2029
+ }
2030
+ );
1997
2031
  if (result.status === 0 && result.stdout) {
1998
2032
  const symbols = JSON.parse(result.stdout);
1999
2033
  return {
@@ -2027,7 +2061,8 @@ function regexParse(opts) {
2027
2061
  lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
2028
2062
  }
2029
2063
  function lineFromOffset(offset) {
2030
- let lo = 0, hi = lineOffsets.length - 1;
2064
+ let lo = 0;
2065
+ let hi = lineOffsets.length - 1;
2031
2066
  while (lo < hi) {
2032
2067
  const mid = lo + hi + 1 >>> 1;
2033
2068
  if (lineOffsets[mid] <= offset) lo = mid;
@@ -2041,8 +2076,7 @@ function regexParse(opts) {
2041
2076
  }
2042
2077
  for (const pattern of RS_PATTERNS) {
2043
2078
  pattern.regex.lastIndex = 0;
2044
- let match;
2045
- while ((match = pattern.regex.exec(content)) !== null) {
2079
+ for (let match = pattern.regex.exec(content); match !== null; match = pattern.regex.exec(content)) {
2046
2080
  const name = match[1];
2047
2081
  const offset = match.index;
2048
2082
  const line = lineFromOffset(offset);
@@ -2095,7 +2129,8 @@ function regexParse2(opts) {
2095
2129
  lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
2096
2130
  }
2097
2131
  function lineFromOffset(offset) {
2098
- let lo = 0, hi = lineOffsets.length - 1;
2132
+ let lo = 0;
2133
+ let hi = lineOffsets.length - 1;
2099
2134
  while (lo < hi) {
2100
2135
  const mid = lo + hi + 1 >>> 1;
2101
2136
  if (lineOffsets[mid] <= offset) lo = mid;
@@ -2107,19 +2142,20 @@ function regexParse2(opts) {
2107
2142
  if (rootMatch) {
2108
2143
  const offset = rootMatch.index;
2109
2144
  const line = lineFromOffset(offset);
2110
- symbols.push(makeSymbol({
2111
- name: path.basename(file),
2112
- kind: "object",
2113
- line,
2114
- col: 0,
2115
- signature: `"${path.basename(file)}" = { ... }`,
2116
- file,
2117
- lang
2118
- }));
2145
+ symbols.push(
2146
+ makeSymbol({
2147
+ name: path.basename(file),
2148
+ kind: "object",
2149
+ line,
2150
+ col: 0,
2151
+ signature: `"${path.basename(file)}" = { ... }`,
2152
+ file,
2153
+ lang
2154
+ })
2155
+ );
2119
2156
  }
2120
2157
  const topLevelKeyRegex = /^\s*"([^"]+)"\s*:/gm;
2121
- let match;
2122
- while ((match = topLevelKeyRegex.exec(content)) !== null) {
2158
+ for (let match = topLevelKeyRegex.exec(content); match !== null; match = topLevelKeyRegex.exec(content)) {
2123
2159
  const key = match[1];
2124
2160
  const offset = match.index;
2125
2161
  const line = lineFromOffset(offset);
@@ -2146,15 +2182,17 @@ function regexParse2(opts) {
2146
2182
  signature = `"$ref": "..."`;
2147
2183
  }
2148
2184
  }
2149
- symbols.push(makeSymbol({
2150
- name: key,
2151
- kind,
2152
- line,
2153
- col,
2154
- signature,
2155
- file,
2156
- lang
2157
- }));
2185
+ symbols.push(
2186
+ makeSymbol({
2187
+ name: key,
2188
+ kind,
2189
+ line,
2190
+ col,
2191
+ signature,
2192
+ file,
2193
+ lang
2194
+ })
2195
+ );
2158
2196
  if (isPackageJson && key === "scripts") {
2159
2197
  extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset);
2160
2198
  }
@@ -2163,20 +2201,21 @@ function regexParse2(opts) {
2163
2201
  }
2164
2202
  }
2165
2203
  const defsRegex = /"\$defs"\s*:|"\$defs"\s*:/g;
2166
- let defsMatch;
2167
- while ((defsMatch = defsRegex.exec(content)) !== null) {
2204
+ const defsMatch = defsRegex.exec(content);
2205
+ if (defsMatch !== null) {
2168
2206
  const offset = defsMatch.index;
2169
2207
  const line = lineFromOffset(offset);
2170
- symbols.push(makeSymbol({
2171
- name: "$defs",
2172
- kind: "property",
2173
- line,
2174
- col: offset - (lineOffsets[line - 1] ?? 0),
2175
- signature: '"$defs": { ... }',
2176
- file,
2177
- lang
2178
- }));
2179
- break;
2208
+ symbols.push(
2209
+ makeSymbol({
2210
+ name: "$defs",
2211
+ kind: "property",
2212
+ line,
2213
+ col: offset - (lineOffsets[line - 1] ?? 0),
2214
+ signature: '"$defs": { ... }',
2215
+ file,
2216
+ lang
2217
+ })
2218
+ );
2180
2219
  }
2181
2220
  const defsPatterns = [
2182
2221
  /"\$defs"\s*:/g,
@@ -2186,69 +2225,71 @@ function regexParse2(opts) {
2186
2225
  ];
2187
2226
  for (const pat of defsPatterns) {
2188
2227
  pat.lastIndex = 0;
2189
- while ((match = pat.exec(content)) !== null) {
2228
+ for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {
2190
2229
  const offset = match.index;
2191
2230
  const line = lineFromOffset(offset);
2192
2231
  const key = match[0].match(/"([^"]+)"/)?.[1] ?? match[0];
2193
- symbols.push(makeSymbol({
2194
- name: key,
2195
- kind: "property",
2196
- line,
2197
- col: offset - (lineOffsets[line - 1] ?? 0),
2198
- signature: `"${key}": { ... }`,
2199
- file,
2200
- lang
2201
- }));
2232
+ symbols.push(
2233
+ makeSymbol({
2234
+ name: key,
2235
+ kind: "property",
2236
+ line,
2237
+ col: offset - (lineOffsets[line - 1] ?? 0),
2238
+ signature: `"${key}": { ... }`,
2239
+ file,
2240
+ lang
2241
+ })
2242
+ );
2202
2243
  }
2203
2244
  }
2204
2245
  return { file, lang, symbols, mtimeMs: Date.now() };
2205
2246
  }
2206
2247
  function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset) {
2207
2248
  const scriptsBlockRegex = /"scripts"\s*:\s*\{([^}]+)\}/g;
2208
- let match;
2209
- while ((match = scriptsBlockRegex.exec(content)) !== null) {
2249
+ for (let match = scriptsBlockRegex.exec(content); match !== null; match = scriptsBlockRegex.exec(content)) {
2210
2250
  const blockContent = match[0];
2211
2251
  const blockOffset = match.index;
2212
2252
  const scriptKeyRegex = /"(\w[\w-]*)"\s*:/g;
2213
- let scriptMatch;
2214
- while ((scriptMatch = scriptKeyRegex.exec(blockContent)) !== null) {
2253
+ for (let scriptMatch = scriptKeyRegex.exec(blockContent); scriptMatch !== null; scriptMatch = scriptKeyRegex.exec(blockContent)) {
2215
2254
  const key = scriptMatch[1];
2216
2255
  const keyOffset = blockOffset + scriptMatch.index;
2217
2256
  const line = lineFromOffset(keyOffset);
2218
- symbols.push(makeSymbol({
2219
- name: key,
2220
- kind: "function",
2221
- line,
2222
- col: keyOffset - (lineOffsets[line - 1] ?? 0),
2223
- signature: `"${key}": "..."`,
2224
- file,
2225
- lang
2226
- }));
2257
+ symbols.push(
2258
+ makeSymbol({
2259
+ name: key,
2260
+ kind: "function",
2261
+ line,
2262
+ col: keyOffset - (lineOffsets[line - 1] ?? 0),
2263
+ signature: `"${key}": "..."`,
2264
+ file,
2265
+ lang
2266
+ })
2267
+ );
2227
2268
  }
2228
2269
  }
2229
2270
  }
2230
2271
  function extractCompilerOptions(content, symbols, file, lang, lineOffsets, parentLine, lineFromOffset) {
2231
2272
  const optsBlockRegex = /"compilerOptions"\s*:\s*\{([^}]+)\}/g;
2232
- let match;
2233
- while ((match = optsBlockRegex.exec(content)) !== null) {
2273
+ for (let match = optsBlockRegex.exec(content); match !== null; match = optsBlockRegex.exec(content)) {
2234
2274
  const blockContent = match[0];
2235
2275
  const blockOffset = match.index;
2236
2276
  const optKeyRegex = /"(\w[\w]*)"\s*:/g;
2237
- let optMatch;
2238
- while ((optMatch = optKeyRegex.exec(blockContent)) !== null) {
2277
+ for (let optMatch = optKeyRegex.exec(blockContent); optMatch !== null; optMatch = optKeyRegex.exec(blockContent)) {
2239
2278
  const key = optMatch[1];
2240
2279
  const keyOffset = blockOffset + optMatch.index;
2241
2280
  const line = lineFromOffset(keyOffset);
2242
2281
  if (line <= parentLine) continue;
2243
- symbols.push(makeSymbol({
2244
- name: key,
2245
- kind: "property",
2246
- line,
2247
- col: keyOffset - (lineOffsets[line - 1] ?? 0),
2248
- signature: `"${key}": ...`,
2249
- file,
2250
- lang
2251
- }));
2282
+ symbols.push(
2283
+ makeSymbol({
2284
+ name: key,
2285
+ kind: "property",
2286
+ line,
2287
+ col: keyOffset - (lineOffsets[line - 1] ?? 0),
2288
+ signature: `"${key}": ...`,
2289
+ file,
2290
+ lang
2291
+ })
2292
+ );
2252
2293
  }
2253
2294
  }
2254
2295
  }
@@ -2286,7 +2327,8 @@ function regexParse3(opts) {
2286
2327
  lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
2287
2328
  }
2288
2329
  function lineFromOffset(offset) {
2289
- let lo = 0, hi = lineOffsets.length - 1;
2330
+ let lo = 0;
2331
+ let hi = lineOffsets.length - 1;
2290
2332
  while (lo < hi) {
2291
2333
  const mid = lo + hi + 1 >>> 1;
2292
2334
  if (lineOffsets[mid] <= offset) lo = mid;
@@ -2295,40 +2337,43 @@ function regexParse3(opts) {
2295
2337
  return lo + 1;
2296
2338
  }
2297
2339
  const anchorRegex = /&(\w[\w-]*)/g;
2298
- let match;
2299
- while ((match = anchorRegex.exec(content)) !== null) {
2340
+ for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {
2300
2341
  const name = match[1];
2301
2342
  const offset = match.index;
2302
2343
  const line = lineFromOffset(offset);
2303
2344
  const col = offset - (lineOffsets[line - 1] ?? 0);
2304
- symbols.push(makeSymbol2({
2305
- name,
2306
- kind: "const",
2307
- line,
2308
- col,
2309
- signature: `&${name}`,
2310
- file,
2311
- lang
2312
- }));
2345
+ symbols.push(
2346
+ makeSymbol2({
2347
+ name,
2348
+ kind: "const",
2349
+ line,
2350
+ col,
2351
+ signature: `&${name}`,
2352
+ file,
2353
+ lang
2354
+ })
2355
+ );
2313
2356
  }
2314
2357
  const aliasRegex = /\*(\w[\w-]*)/g;
2315
- while ((match = aliasRegex.exec(content)) !== null) {
2358
+ for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {
2316
2359
  const name = match[1];
2317
2360
  const offset = match.index;
2318
2361
  const line = lineFromOffset(offset);
2319
2362
  const col = offset - (lineOffsets[line - 1] ?? 0);
2320
- symbols.push(makeSymbol2({
2321
- name,
2322
- kind: "const",
2323
- line,
2324
- col,
2325
- signature: `*${name}`,
2326
- file,
2327
- lang
2328
- }));
2363
+ symbols.push(
2364
+ makeSymbol2({
2365
+ name,
2366
+ kind: "const",
2367
+ line,
2368
+ col,
2369
+ signature: `*${name}`,
2370
+ file,
2371
+ lang
2372
+ })
2373
+ );
2329
2374
  }
2330
2375
  const kvRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:/gm;
2331
- while ((match = kvRegex.exec(content)) !== null) {
2376
+ for (let match = kvRegex.exec(content); match !== null; match = kvRegex.exec(content)) {
2332
2377
  const indent = match[1].length;
2333
2378
  const key = match[2];
2334
2379
  const offset = match.index;
@@ -2344,38 +2389,42 @@ function regexParse3(opts) {
2344
2389
  symbols.push(makeSymbol2({ name: key, kind, line, col, signature, file, lang }));
2345
2390
  }
2346
2391
  const listItemRegex = /^-(\s+)([^:#\s][^:#\s]*)\s*:/gm;
2347
- while ((match = listItemRegex.exec(content)) !== null) {
2392
+ for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {
2348
2393
  const key = match[2];
2349
2394
  const offset = match.index;
2350
2395
  const line = lineFromOffset(offset);
2351
2396
  const col = offset - (lineOffsets[line - 1] ?? 0);
2352
2397
  const value = extractValue(content, offset + match[0].length);
2353
2398
  const kind = isScalar(value) ? "literal" : "property";
2354
- symbols.push(makeSymbol2({
2355
- name: key,
2356
- kind,
2357
- line,
2358
- col,
2359
- signature: `- ${key}: ${truncate(value, 60)}`,
2360
- file,
2361
- lang
2362
- }));
2399
+ symbols.push(
2400
+ makeSymbol2({
2401
+ name: key,
2402
+ kind,
2403
+ line,
2404
+ col,
2405
+ signature: `- ${key}: ${truncate(value, 60)}`,
2406
+ file,
2407
+ lang
2408
+ })
2409
+ );
2363
2410
  }
2364
2411
  const blockScalarRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:\s*[|>](\s|$)/gm;
2365
- while ((match = blockScalarRegex.exec(content)) !== null) {
2412
+ for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {
2366
2413
  const key = match[2];
2367
2414
  const offset = match.index;
2368
2415
  const line = lineFromOffset(offset);
2369
2416
  const col = offset - (lineOffsets[line - 1] ?? 0);
2370
- symbols.push(makeSymbol2({
2371
- name: key,
2372
- kind: "property",
2373
- line,
2374
- col,
2375
- signature: `${key}: | ...`,
2376
- file,
2377
- lang
2378
- }));
2417
+ symbols.push(
2418
+ makeSymbol2({
2419
+ name: key,
2420
+ kind: "property",
2421
+ line,
2422
+ col,
2423
+ signature: `${key}: | ...`,
2424
+ file,
2425
+ lang
2426
+ })
2427
+ );
2379
2428
  }
2380
2429
  return { file, lang, symbols, mtimeMs: Date.now() };
2381
2430
  }