@pretorian-worx/runclaudia-core 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +16 -0
  3. package/dist/adapters/nextjs.d.ts +27 -0
  4. package/dist/adapters/nextjs.js +457 -0
  5. package/dist/adapters/nextjs.js.map +1 -0
  6. package/dist/adapters/prisma.d.ts +22 -0
  7. package/dist/adapters/prisma.js +80 -0
  8. package/dist/adapters/prisma.js.map +1 -0
  9. package/dist/adapters/specs.d.ts +13 -0
  10. package/dist/adapters/specs.js +126 -0
  11. package/dist/adapters/specs.js.map +1 -0
  12. package/dist/adapters/terraform.d.ts +17 -0
  13. package/dist/adapters/terraform.js +82 -0
  14. package/dist/adapters/terraform.js.map +1 -0
  15. package/dist/diff.d.ts +13 -0
  16. package/dist/diff.js +187 -0
  17. package/dist/diff.js.map +1 -0
  18. package/dist/gating.d.ts +29 -0
  19. package/dist/gating.js +59 -0
  20. package/dist/gating.js.map +1 -0
  21. package/dist/index.d.ts +15 -0
  22. package/dist/index.js +12 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/llm.d.ts +24 -0
  25. package/dist/llm.js +135 -0
  26. package/dist/llm.js.map +1 -0
  27. package/dist/map.d.ts +9 -0
  28. package/dist/map.js +55 -0
  29. package/dist/map.js.map +1 -0
  30. package/dist/plan-format.d.ts +3 -0
  31. package/dist/plan-format.js +71 -0
  32. package/dist/plan-format.js.map +1 -0
  33. package/dist/plan.d.ts +21 -0
  34. package/dist/plan.js +44 -0
  35. package/dist/plan.js.map +1 -0
  36. package/dist/prompt.d.ts +40 -0
  37. package/dist/prompt.js +266 -0
  38. package/dist/prompt.js.map +1 -0
  39. package/dist/runner.d.ts +53 -0
  40. package/dist/runner.js +119 -0
  41. package/dist/runner.js.map +1 -0
  42. package/dist/select.d.ts +31 -0
  43. package/dist/select.js +108 -0
  44. package/dist/select.js.map +1 -0
  45. package/dist/types.d.ts +176 -0
  46. package/dist/types.js +17 -0
  47. package/dist/types.js.map +1 -0
  48. package/package.json +54 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Paul Schneider
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # @pretorian-worx/runclaudia-core
2
+
3
+ Programmatic core for [claudia](https://github.com/pretorian-worx/runclaudia) — the diff parser, framework adapters (Next.js App Router, Terraform, Prisma, Playwright/Cypress), prompt builder, Anthropic SDK wrapper, plan/selection/gating/runner primitives.
4
+
5
+ This package is consumed by:
6
+
7
+ - [`@pretorian-worx/runclaudia-cli`](https://www.npmjs.com/package/@pretorian-worx/runclaudia-cli) — the CLI most users invoke via `npx`
8
+ - The runclaudia GitHub Action (`uses: pretorian-worx/runclaudia@v0`)
9
+
10
+ You can also use it directly from your own Node code if you need to wire claudia into a custom CI pipeline or write a different reporter — e.g. `import { runSelect, buildPlaywrightCommand } from "@pretorian-worx/runclaudia-core"`.
11
+
12
+ For the full product documentation, see the [main repo README](https://github.com/pretorian-worx/runclaudia#readme).
13
+
14
+ ## License
15
+
16
+ MIT
@@ -0,0 +1,27 @@
1
+ import type { AppMap, EndpointEntry, HttpMethod } from "../types.js";
2
+ export interface NextAdapterOptions {
3
+ rootDir: string;
4
+ appDir?: string;
5
+ maxDepth?: number;
6
+ }
7
+ export declare function buildNextMap(opts: NextAdapterOptions): AppMap;
8
+ export declare function detectAwsServices(src: string): string[];
9
+ interface DetectedCall {
10
+ path: string;
11
+ method: HttpMethod;
12
+ }
13
+ /**
14
+ * Best-effort static detection of API calls in a source file. Catches the
15
+ * common patterns: `fetch("/api/x")`, `fetch("/api/x", { method: "POST" })`,
16
+ * `axios.post("/api/x", body)`, `useSWR("/api/x")`. Does NOT chase variable
17
+ * indirection — `const url = "/api/x"; fetch(url)` is invisible to this.
18
+ */
19
+ export declare function detectEndpointCalls(file: string): DetectedCall[];
20
+ /**
21
+ * Match a detected call site against the discovered endpoint list. Returns all
22
+ * endpoints whose path + method match. Path matching is segment-aware with
23
+ * wildcard handling — `[id]`, `:id`, and `${id}` interpolations all match any
24
+ * non-empty segment.
25
+ */
26
+ export declare function matchEndpoint(call: DetectedCall, endpoints: EndpointEntry[]): EndpointEntry[];
27
+ export {};
@@ -0,0 +1,457 @@
1
+ import { readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { join, relative, sep } from "node:path";
3
+ import { discoverTerraformResources } from "./terraform.js";
4
+ import { detectPrismaTableUsage, discoverPrismaModels } from "./prisma.js";
5
+ import { discoverSpecs } from "./specs.js";
6
+ const ROUTE_FILES = ["page.tsx", "page.ts", "page.jsx", "page.js"];
7
+ const LAYOUT_FILES = ["layout.tsx", "layout.ts", "layout.jsx", "layout.js"];
8
+ const ENDPOINT_FILES = ["route.ts", "route.tsx", "route.js", "route.jsx"];
9
+ export function buildNextMap(opts) {
10
+ const rootDir = opts.rootDir;
11
+ const appDir = opts.appDir ?? findAppDir(rootDir);
12
+ const tsPaths = loadTsPaths(rootDir);
13
+ const routes = [];
14
+ const endpoints = [];
15
+ const fileToRoutes = {};
16
+ if (appDir) {
17
+ walk(appDir, "", appDir, rootDir, tsPaths, routes, endpoints, fileToRoutes, opts.maxDepth ?? 12);
18
+ }
19
+ // Second pass: link endpoints to caller files.
20
+ // We collect every file the reachability walk visited (anything in fileToRoutes
21
+ // is by definition reachable from at least one route, plus the endpoint handler
22
+ // files themselves are also caller-eligible).
23
+ const fileToEndpoints = {};
24
+ for (const e of endpoints)
25
+ e.callers = [];
26
+ const callerFiles = new Set(Object.keys(fileToRoutes));
27
+ for (const file of callerFiles) {
28
+ const calls = detectEndpointCalls(join(rootDir, file));
29
+ if (calls.length === 0)
30
+ continue;
31
+ for (const call of calls) {
32
+ const matched = matchEndpoint(call, endpoints);
33
+ for (const m of matched) {
34
+ if (!m.callers.includes(file))
35
+ m.callers.push(file);
36
+ (fileToEndpoints[file] ??= []).push(m.route);
37
+ }
38
+ }
39
+ if (fileToEndpoints[file]) {
40
+ fileToEndpoints[file] = uniqSorted(fileToEndpoints[file]);
41
+ }
42
+ }
43
+ for (const e of endpoints)
44
+ e.callers = uniqSorted(e.callers);
45
+ // Third pass: infrastructure discovery (framework-agnostic — runs at the
46
+ // project root, not just under appDir).
47
+ const { infra, fileToInfra } = discoverTerraformResources({ rootDir });
48
+ // Fourth pass: DB schema discovery + per-endpoint table inference.
49
+ const { dbModels, fileToTables } = discoverPrismaModels({ rootDir });
50
+ const knownModelNames = dbModels.map((m) => m.name);
51
+ if (knownModelNames.length > 0) {
52
+ for (const e of endpoints) {
53
+ const abs = join(rootDir, e.file);
54
+ let handlerSrc;
55
+ try {
56
+ handlerSrc = readFileSync(abs, "utf8");
57
+ }
58
+ catch {
59
+ continue;
60
+ }
61
+ e.tables = detectPrismaTableUsage(handlerSrc, knownModelNames);
62
+ }
63
+ }
64
+ // Fifth pass: spec indexing (Playwright/Cypress) for Stage C foundation.
65
+ const { specs, fileToSpecs } = discoverSpecs({ rootDir });
66
+ return {
67
+ framework: "nextjs-app",
68
+ generatedAt: new Date().toISOString(),
69
+ rootDir,
70
+ routes,
71
+ endpoints,
72
+ infra,
73
+ dbModels,
74
+ specs,
75
+ fileToRoutes,
76
+ fileToEndpoints,
77
+ fileToInfra,
78
+ fileToTables,
79
+ fileToSpecs,
80
+ };
81
+ }
82
+ function uniqSorted(xs) {
83
+ return Array.from(new Set(xs)).sort();
84
+ }
85
+ function loadTsPaths(rootDir) {
86
+ for (const name of ["tsconfig.json", "jsconfig.json"]) {
87
+ const abs = join(rootDir, name);
88
+ if (!exists(abs))
89
+ continue;
90
+ try {
91
+ const raw = readFileSync(abs, "utf8");
92
+ const stripped = stripJsonComments(raw);
93
+ const cfg = JSON.parse(stripped);
94
+ const co = cfg.compilerOptions ?? {};
95
+ const baseUrlRel = co.baseUrl ?? ".";
96
+ const baseUrl = join(rootDir, baseUrlRel);
97
+ const paths = Object.entries(co.paths ?? {}).map(([pattern, targets]) => ({
98
+ pattern,
99
+ targets: targets.map((t) => join(baseUrl, t)),
100
+ }));
101
+ return { baseUrl, paths };
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ return null;
108
+ }
109
+ function stripJsonComments(src) {
110
+ return src
111
+ .replace(/\/\*[\s\S]*?\*\//g, "")
112
+ .replace(/(^|[^:\\])\/\/[^\n]*/g, "$1")
113
+ .replace(/,\s*([}\]])/g, "$1");
114
+ }
115
+ function findAppDir(rootDir) {
116
+ for (const candidate of [join(rootDir, "app"), join(rootDir, "src", "app")]) {
117
+ if (exists(candidate) && isDir(candidate))
118
+ return candidate;
119
+ }
120
+ return null;
121
+ }
122
+ function walk(dir, routePath, appRoot, rootDir, tsPaths, routes, endpoints, fileToRoutes, remainingDepth) {
123
+ if (remainingDepth <= 0)
124
+ return;
125
+ const entries = readdirSync(dir, { withFileTypes: true });
126
+ const pageFile = entries.find((e) => e.isFile() && ROUTE_FILES.includes(e.name));
127
+ const endpointFile = entries.find((e) => e.isFile() && ENDPOINT_FILES.includes(e.name));
128
+ if (pageFile) {
129
+ const route = routePath || "/";
130
+ const pageAbs = join(dir, pageFile.name);
131
+ const reachable = new Set();
132
+ collectReachable(pageAbs, rootDir, tsPaths, reachable, 8);
133
+ const layoutFiles = collectLayoutFiles(appRoot, dir);
134
+ for (const layout of layoutFiles) {
135
+ collectReachable(layout, rootDir, tsPaths, reachable, 8);
136
+ }
137
+ const fileList = [...reachable].map((f) => toRel(rootDir, f)).sort();
138
+ routes.push({ route, files: fileList });
139
+ for (const f of fileList) {
140
+ (fileToRoutes[f] ??= []).push(route);
141
+ }
142
+ }
143
+ if (endpointFile) {
144
+ const path = routePath || "/";
145
+ const handlerAbs = join(dir, endpointFile.name);
146
+ const relFile = toRel(rootDir, handlerAbs);
147
+ const parsed = parseEndpointHandler(handlerAbs);
148
+ for (const m of parsed.methods) {
149
+ endpoints.push({
150
+ route: `${m.method} ${path}`,
151
+ path,
152
+ method: m.method,
153
+ file: relFile,
154
+ bodyShape: m.bodyShape,
155
+ callers: [],
156
+ services: parsed.services,
157
+ tables: [],
158
+ });
159
+ }
160
+ (fileToRoutes[relFile] ??= []).push(...parsed.methods.map((m) => `${m.method} ${path}`));
161
+ }
162
+ for (const entry of entries) {
163
+ if (!entry.isDirectory())
164
+ continue;
165
+ if (entry.name.startsWith("_"))
166
+ continue;
167
+ const childRoute = segmentToRoute(entry.name, routePath);
168
+ walk(join(dir, entry.name), childRoute, appRoot, rootDir, tsPaths, routes, endpoints, fileToRoutes, remainingDepth - 1);
169
+ }
170
+ }
171
+ const HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
172
+ function parseEndpointHandler(file) {
173
+ let src;
174
+ try {
175
+ src = readFileSync(file, "utf8");
176
+ }
177
+ catch {
178
+ return { methods: [], services: [] };
179
+ }
180
+ // Find each method's declaration position so we can slice its body region.
181
+ const positions = [];
182
+ for (const m of HTTP_METHODS) {
183
+ const re = new RegExp(`export\\s+(?:async\\s+)?(?:function|const|let|var)\\s+${m}\\b|export\\s*\\{[^}]*\\b(?:[A-Za-z_$][\\w$]*\\s+as\\s+)?${m}\\b`, "g");
184
+ let match;
185
+ while ((match = re.exec(src))) {
186
+ positions.push({ method: m, start: match.index });
187
+ }
188
+ }
189
+ if (positions.length === 0)
190
+ return { methods: [], services: detectAwsServices(src) };
191
+ positions.sort((a, b) => a.start - b.start);
192
+ const methods = [];
193
+ for (let i = 0; i < positions.length; i++) {
194
+ const start = positions[i].start;
195
+ const end = i + 1 < positions.length ? positions[i + 1].start : src.length;
196
+ const body = src.slice(start, end);
197
+ methods.push({ method: positions[i].method, bodyShape: detectBodyShape(body) });
198
+ }
199
+ return { methods, services: detectAwsServices(src) };
200
+ }
201
+ const AWS_SDK_IMPORT_RE = /@aws-sdk\/client-([a-z0-9-]+)/gi;
202
+ export function detectAwsServices(src) {
203
+ const services = new Set();
204
+ AWS_SDK_IMPORT_RE.lastIndex = 0;
205
+ let m;
206
+ while ((m = AWS_SDK_IMPORT_RE.exec(src))) {
207
+ services.add(m[1].toLowerCase());
208
+ }
209
+ return Array.from(services).sort();
210
+ }
211
+ // Look only at request-side body parsing — `req.json()`, `await request.formData()`,
212
+ // etc. Specifically avoid matching `Response.json(...)` / `NextResponse.json(...)`
213
+ // which are output, not input.
214
+ const BODY_SHAPE_PATTERNS = [
215
+ { shape: "json", re: /\b(?:req|request)\s*\.\s*json\s*\(/ },
216
+ { shape: "formData", re: /\b(?:req|request)\s*\.\s*formData\s*\(/ },
217
+ { shape: "text", re: /\b(?:req|request)\s*\.\s*text\s*\(/ },
218
+ { shape: "arrayBuffer", re: /\b(?:req|request)\s*\.\s*arrayBuffer\s*\(/ },
219
+ ];
220
+ function detectBodyShape(src) {
221
+ for (const { shape, re } of BODY_SHAPE_PATTERNS) {
222
+ if (re.test(src))
223
+ return shape;
224
+ }
225
+ return null;
226
+ }
227
+ function segmentToRoute(segment, parent) {
228
+ if (segment.startsWith("(") && segment.endsWith(")"))
229
+ return parent;
230
+ if (segment.startsWith("@"))
231
+ return parent;
232
+ if (segment.startsWith("[") && segment.endsWith("]")) {
233
+ const inner = segment.slice(1, -1);
234
+ if (inner.startsWith("..."))
235
+ return `${parent}/:${inner.slice(3)}*`;
236
+ return `${parent}/:${inner}`;
237
+ }
238
+ return `${parent}/${segment}`;
239
+ }
240
+ function collectLayoutFiles(appRoot, dir) {
241
+ const layouts = [];
242
+ let current = dir;
243
+ while (true) {
244
+ if (!isUnder(appRoot, current))
245
+ break;
246
+ for (const name of LAYOUT_FILES) {
247
+ const candidate = join(current, name);
248
+ if (exists(candidate))
249
+ layouts.push(candidate);
250
+ }
251
+ if (current === appRoot)
252
+ break;
253
+ const parent = join(current, "..");
254
+ if (parent === current)
255
+ break;
256
+ current = parent;
257
+ }
258
+ return layouts;
259
+ }
260
+ const IMPORT_RE = /import\s+(?:[^'"`]+from\s+)?['"]([^'"]+)['"]/g;
261
+ const REQUIRE_RE = /require\(\s*['"]([^'"]+)['"]\s*\)/g;
262
+ const DYNAMIC_RE = /import\(\s*['"]([^'"]+)['"]\s*\)/g;
263
+ function collectReachable(file, rootDir, tsPaths, into, depth) {
264
+ if (depth <= 0)
265
+ return;
266
+ if (into.has(file))
267
+ return;
268
+ if (!exists(file))
269
+ return;
270
+ into.add(file);
271
+ let src;
272
+ try {
273
+ src = readFileSync(file, "utf8");
274
+ }
275
+ catch {
276
+ return;
277
+ }
278
+ const specs = [];
279
+ for (const re of [IMPORT_RE, REQUIRE_RE, DYNAMIC_RE]) {
280
+ re.lastIndex = 0;
281
+ let m;
282
+ while ((m = re.exec(src)))
283
+ specs.push(m[1]);
284
+ }
285
+ for (const spec of specs) {
286
+ const resolved = resolveSpec(spec, file, rootDir, tsPaths);
287
+ if (resolved)
288
+ collectReachable(resolved, rootDir, tsPaths, into, depth - 1);
289
+ }
290
+ }
291
+ const EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
292
+ function resolveSpec(spec, fromFile, rootDir, tsPaths) {
293
+ const bases = candidateBases(spec, fromFile, rootDir, tsPaths);
294
+ for (const base of bases) {
295
+ const found = tryResolveBase(base);
296
+ if (found)
297
+ return found;
298
+ }
299
+ return null;
300
+ }
301
+ function candidateBases(spec, fromFile, rootDir, tsPaths) {
302
+ if (spec.startsWith("."))
303
+ return [join(fromFile, "..", spec)];
304
+ if (spec.startsWith("/"))
305
+ return [join(rootDir, spec)];
306
+ if (tsPaths) {
307
+ for (const { pattern, targets } of tsPaths.paths) {
308
+ if (pattern.endsWith("/*")) {
309
+ const prefix = pattern.slice(0, -1);
310
+ if (spec.startsWith(prefix)) {
311
+ const tail = spec.slice(prefix.length);
312
+ return targets.map((t) => t.endsWith("/*") || t.endsWith(sep + "*") ? join(t.slice(0, -1), tail) : join(t, tail));
313
+ }
314
+ }
315
+ else if (spec === pattern) {
316
+ return targets;
317
+ }
318
+ }
319
+ }
320
+ if (spec.startsWith("@/"))
321
+ return [join(rootDir, spec.slice(2)), join(rootDir, "src", spec.slice(2))];
322
+ return [];
323
+ }
324
+ function tryResolveBase(base) {
325
+ for (const ext of EXTS) {
326
+ const candidate = base + ext;
327
+ if (exists(candidate) && !isDir(candidate))
328
+ return candidate;
329
+ }
330
+ if (exists(base) && isDir(base)) {
331
+ for (const ext of EXTS) {
332
+ const idx = join(base, "index" + ext);
333
+ if (exists(idx))
334
+ return idx;
335
+ }
336
+ }
337
+ if (exists(base) && !isDir(base))
338
+ return base;
339
+ return null;
340
+ }
341
+ function exists(p) {
342
+ try {
343
+ statSync(p);
344
+ return true;
345
+ }
346
+ catch {
347
+ return false;
348
+ }
349
+ }
350
+ function isDir(p) {
351
+ try {
352
+ return statSync(p).isDirectory();
353
+ }
354
+ catch {
355
+ return false;
356
+ }
357
+ }
358
+ function isUnder(root, p) {
359
+ const r = relative(root, p);
360
+ return !r.startsWith("..") && !r.startsWith(sep + "..");
361
+ }
362
+ function toRel(rootDir, p) {
363
+ const r = relative(rootDir, p);
364
+ return r.split(sep).join("/");
365
+ }
366
+ const FETCH_RE = /\bfetch\s*\(\s*['"`]([^'"`\n]+)['"`](?:\s*,\s*\{([\s\S]{0,400}?)\})?/g;
367
+ const AXIOS_RE = /\baxios\s*\.\s*(get|post|put|patch|delete|head|options)\s*\(\s*['"`]([^'"`\n]+)['"`]/gi;
368
+ const SWR_RE = /\buseSWR\s*\(\s*['"`]([^'"`\n]+)['"`]/g;
369
+ const METHOD_IN_OPTS_RE = /method\s*:\s*['"`](GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)['"`]/i;
370
+ /**
371
+ * Best-effort static detection of API calls in a source file. Catches the
372
+ * common patterns: `fetch("/api/x")`, `fetch("/api/x", { method: "POST" })`,
373
+ * `axios.post("/api/x", body)`, `useSWR("/api/x")`. Does NOT chase variable
374
+ * indirection — `const url = "/api/x"; fetch(url)` is invisible to this.
375
+ */
376
+ export function detectEndpointCalls(file) {
377
+ let src;
378
+ try {
379
+ src = readFileSync(file, "utf8");
380
+ }
381
+ catch {
382
+ return [];
383
+ }
384
+ const out = [];
385
+ FETCH_RE.lastIndex = 0;
386
+ let m;
387
+ while ((m = FETCH_RE.exec(src))) {
388
+ const path = m[1];
389
+ if (!looksLikePath(path))
390
+ continue;
391
+ const opts = m[2] ?? "";
392
+ const methodMatch = METHOD_IN_OPTS_RE.exec(opts);
393
+ const method = methodMatch?.[1]?.toUpperCase() ?? "GET";
394
+ out.push({ path, method });
395
+ }
396
+ AXIOS_RE.lastIndex = 0;
397
+ while ((m = AXIOS_RE.exec(src))) {
398
+ const method = m[1].toUpperCase();
399
+ const path = m[2];
400
+ if (!looksLikePath(path))
401
+ continue;
402
+ out.push({ path, method });
403
+ }
404
+ SWR_RE.lastIndex = 0;
405
+ while ((m = SWR_RE.exec(src))) {
406
+ const path = m[1];
407
+ if (!looksLikePath(path))
408
+ continue;
409
+ out.push({ path, method: "GET" });
410
+ }
411
+ return out;
412
+ }
413
+ function looksLikePath(s) {
414
+ // Reject obvious non-paths: http(s) URLs, mailto, etc.
415
+ if (/^[a-z]+:\/\//i.test(s))
416
+ return false;
417
+ if (s.startsWith("mailto:") || s.startsWith("tel:"))
418
+ return false;
419
+ return s.startsWith("/");
420
+ }
421
+ /**
422
+ * Match a detected call site against the discovered endpoint list. Returns all
423
+ * endpoints whose path + method match. Path matching is segment-aware with
424
+ * wildcard handling — `[id]`, `:id`, and `${id}` interpolations all match any
425
+ * non-empty segment.
426
+ */
427
+ export function matchEndpoint(call, endpoints) {
428
+ const callSegs = splitPath(call.path);
429
+ return endpoints.filter((e) => e.method === call.method && pathSegmentsMatch(callSegs, splitPath(e.path)));
430
+ }
431
+ function splitPath(p) {
432
+ // Drop trailing query/hash, split, drop empties.
433
+ const clean = p.split(/[?#]/)[0] ?? p;
434
+ return clean.split("/").filter(Boolean);
435
+ }
436
+ function pathSegmentsMatch(a, b) {
437
+ if (a.length !== b.length)
438
+ return false;
439
+ for (let i = 0; i < a.length; i++) {
440
+ if (isWildcardSegment(a[i]) || isWildcardSegment(b[i]))
441
+ continue;
442
+ if (a[i] !== b[i])
443
+ return false;
444
+ }
445
+ return true;
446
+ }
447
+ function isWildcardSegment(seg) {
448
+ // `:id`, `[id]`, or anything containing `${...}` interpolation.
449
+ if (seg.startsWith(":"))
450
+ return true;
451
+ if (seg.startsWith("[") && seg.endsWith("]"))
452
+ return true;
453
+ if (seg.includes("${"))
454
+ return true;
455
+ return false;
456
+ }
457
+ //# sourceMappingURL=nextjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.js","sourceRoot":"","sources":["../../src/adapters/nextjs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { DbModelEntry } from "../types.js";
2
+ export interface PrismaDiscoveryOptions {
3
+ rootDir: string;
4
+ }
5
+ /**
6
+ * Discover Prisma models. Looks at the canonical locations:
7
+ * - <rootDir>/prisma/schema.prisma
8
+ * - <rootDir>/prisma/schema/*.prisma (multi-file schema, Prisma 5+)
9
+ * - <rootDir>/schema.prisma (less common, but supported)
10
+ */
11
+ export declare function discoverPrismaModels(opts: PrismaDiscoveryOptions): {
12
+ dbModels: DbModelEntry[];
13
+ fileToTables: Record<string, string[]>;
14
+ };
15
+ /**
16
+ * Detect Prisma-style ORM access in a handler source. Matches `prisma.X.op(...)`,
17
+ * `db.X.op(...)`, and `tx.X.op(...)` (transaction client). Returns canonical
18
+ * model names by case-insensitive lookup against the known model list — Prisma
19
+ * client usage is camelCase (`prisma.bug`) while the schema declares PascalCase
20
+ * (`model Bug`), so we normalize.
21
+ */
22
+ export declare function detectPrismaTableUsage(src: string, knownModels: string[]): string[];
@@ -0,0 +1,80 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
2
+ import { join, relative, sep } from "node:path";
3
+ // `model NAME {` — Prisma models always start with an uppercase letter by convention,
4
+ // but the language allows lowercase too. We accept both.
5
+ const MODEL_RE = /^\s*model\s+([A-Za-z_][A-Za-z0-9_]*)\s*\{/gm;
6
+ /**
7
+ * Discover Prisma models. Looks at the canonical locations:
8
+ * - <rootDir>/prisma/schema.prisma
9
+ * - <rootDir>/prisma/schema/*.prisma (multi-file schema, Prisma 5+)
10
+ * - <rootDir>/schema.prisma (less common, but supported)
11
+ */
12
+ export function discoverPrismaModels(opts) {
13
+ const { rootDir } = opts;
14
+ const candidates = [];
15
+ const rootSchema = join(rootDir, "schema.prisma");
16
+ if (existsSync(rootSchema))
17
+ candidates.push(rootSchema);
18
+ const prismaDir = join(rootDir, "prisma");
19
+ if (existsSync(prismaDir) && statSync(prismaDir).isDirectory()) {
20
+ const single = join(prismaDir, "schema.prisma");
21
+ if (existsSync(single))
22
+ candidates.push(single);
23
+ const splitDir = join(prismaDir, "schema");
24
+ if (existsSync(splitDir) && statSync(splitDir).isDirectory()) {
25
+ for (const entry of readdirSync(splitDir, { withFileTypes: true })) {
26
+ if (entry.isFile() && entry.name.endsWith(".prisma")) {
27
+ candidates.push(join(splitDir, entry.name));
28
+ }
29
+ }
30
+ }
31
+ }
32
+ const dbModels = [];
33
+ const fileToTables = {};
34
+ for (const abs of candidates) {
35
+ const relFile = relative(rootDir, abs).split(sep).join("/");
36
+ let src;
37
+ try {
38
+ src = readFileSync(abs, "utf8");
39
+ }
40
+ catch {
41
+ continue;
42
+ }
43
+ MODEL_RE.lastIndex = 0;
44
+ let m;
45
+ while ((m = MODEL_RE.exec(src))) {
46
+ const name = m[1];
47
+ dbModels.push({ orm: "prisma", name, file: relFile });
48
+ (fileToTables[relFile] ??= []).push(name);
49
+ }
50
+ }
51
+ // Stable ordering for diff-stable cached maps.
52
+ dbModels.sort((a, b) => a.name.localeCompare(b.name));
53
+ for (const k of Object.keys(fileToTables)) {
54
+ fileToTables[k] = Array.from(new Set(fileToTables[k])).sort();
55
+ }
56
+ return { dbModels, fileToTables };
57
+ }
58
+ /**
59
+ * Detect Prisma-style ORM access in a handler source. Matches `prisma.X.op(...)`,
60
+ * `db.X.op(...)`, and `tx.X.op(...)` (transaction client). Returns canonical
61
+ * model names by case-insensitive lookup against the known model list — Prisma
62
+ * client usage is camelCase (`prisma.bug`) while the schema declares PascalCase
63
+ * (`model Bug`), so we normalize.
64
+ */
65
+ export function detectPrismaTableUsage(src, knownModels) {
66
+ if (knownModels.length === 0)
67
+ return [];
68
+ const knownByLower = new Map(knownModels.map((m) => [m.toLowerCase(), m]));
69
+ const re = /\b(?:prisma|db|tx)\s*\.\s*([a-z][A-Za-z0-9_]*)\s*\.\s*[A-Za-z_]\w*\s*\(/g;
70
+ const out = new Set();
71
+ let m;
72
+ while ((m = re.exec(src))) {
73
+ const camel = m[1];
74
+ const canonical = knownByLower.get(camel.toLowerCase());
75
+ if (canonical)
76
+ out.add(canonical);
77
+ }
78
+ return Array.from(out).sort();
79
+ }
80
+ //# sourceMappingURL=prisma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/adapters/prisma.ts"],"names":[],"mappings":"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"}