run402 4.82.0 → 4.84.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 (65) hide show
  1. package/cli.mjs +1 -1
  2. package/gitvault-surface.json +1 -1
  3. package/lib/deploy-v2.mjs +41 -71
  4. package/lib/doctor-source-scan.mjs +2 -547
  5. package/lib/doctor.mjs +28 -8
  6. package/lib/sdk-errors.mjs +7 -0
  7. package/lib/status.mjs +1 -1
  8. package/lib/up.mjs +62 -21
  9. package/lib/up.test.mjs +16 -0
  10. package/lib/update-check.mjs +11 -6
  11. package/lib/update-check.test.mjs +18 -5
  12. package/package.json +1 -1
  13. package/sdk/dist/actions.d.ts +16 -3
  14. package/sdk/dist/actions.d.ts.map +1 -1
  15. package/sdk/dist/config.d.ts +1 -1
  16. package/sdk/dist/config.d.ts.map +1 -1
  17. package/sdk/dist/config.js.map +1 -1
  18. package/sdk/dist/index.d.ts +2 -0
  19. package/sdk/dist/index.d.ts.map +1 -1
  20. package/sdk/dist/index.js +2 -0
  21. package/sdk/dist/index.js.map +1 -1
  22. package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
  23. package/sdk/dist/namespaces/deploy.js +2 -1
  24. package/sdk/dist/namespaces/deploy.js.map +1 -1
  25. package/sdk/dist/namespaces/deploy.types.d.ts +6 -0
  26. package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
  27. package/sdk/dist/namespaces/edge-evidence.d.ts +22 -0
  28. package/sdk/dist/namespaces/edge-evidence.d.ts.map +1 -0
  29. package/sdk/dist/namespaces/edge-evidence.js +38 -0
  30. package/sdk/dist/namespaces/edge-evidence.js.map +1 -0
  31. package/sdk/dist/namespaces/projects.d.ts.map +1 -1
  32. package/sdk/dist/namespaces/projects.js +9 -7
  33. package/sdk/dist/namespaces/projects.js.map +1 -1
  34. package/sdk/dist/node/actions-node.d.ts +18 -0
  35. package/sdk/dist/node/actions-node.d.ts.map +1 -1
  36. package/sdk/dist/node/actions-node.js +139 -91
  37. package/sdk/dist/node/actions-node.js.map +1 -1
  38. package/sdk/dist/node/app-scope.d.ts +24 -0
  39. package/sdk/dist/node/app-scope.d.ts.map +1 -0
  40. package/sdk/dist/node/app-scope.js +47 -0
  41. package/sdk/dist/node/app-scope.js.map +1 -0
  42. package/sdk/dist/node/deploy-manifest.d.ts +6 -0
  43. package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
  44. package/sdk/dist/node/deploy-manifest.js +61 -0
  45. package/sdk/dist/node/deploy-manifest.js.map +1 -1
  46. package/sdk/dist/node/index.d.ts +6 -1
  47. package/sdk/dist/node/index.d.ts.map +1 -1
  48. package/sdk/dist/node/index.js +8 -2
  49. package/sdk/dist/node/index.js.map +1 -1
  50. package/sdk/dist/node/manifest-export.d.ts +5 -0
  51. package/sdk/dist/node/manifest-export.d.ts.map +1 -0
  52. package/sdk/dist/node/manifest-export.js +78 -0
  53. package/sdk/dist/node/manifest-export.js.map +1 -0
  54. package/sdk/dist/node/preflight.d.ts +65 -0
  55. package/sdk/dist/node/preflight.d.ts.map +1 -0
  56. package/sdk/dist/node/preflight.js +23 -0
  57. package/sdk/dist/node/preflight.js.map +1 -0
  58. package/sdk/dist/node/source-scan.d.ts +73 -0
  59. package/sdk/dist/node/source-scan.d.ts.map +1 -0
  60. package/sdk/dist/node/source-scan.js +552 -0
  61. package/sdk/dist/node/source-scan.js.map +1 -0
  62. package/sdk/dist/rest-diagnostics.d.ts +15 -0
  63. package/sdk/dist/rest-diagnostics.d.ts.map +1 -0
  64. package/sdk/dist/rest-diagnostics.js +19 -0
  65. package/sdk/dist/rest-diagnostics.js.map +1 -0
@@ -0,0 +1,552 @@
1
+ import { collectLocalFileReferences } from "./deploy-manifest.js";
2
+ /**
3
+ * `run402 doctor` source-scan module (auth-aware-ssr Section 9).
4
+ *
5
+ * Walks the project's `src/` directory and reports patterns the
6
+ * auth-aware-ssr design specifies as deploy-failing OR runtime warnings:
7
+ *
8
+ * - **Hallucinated SDK names.** `getUser`, `getSession`, `currentUser`,
9
+ * `getCurrentUser`, `getServerSession`, `auth.protect`, `auth.signIn`,
10
+ * `auth.logout`, `auth.middleware`, etc. Each hit emits
11
+ * `R402_AUTH_UNKNOWN_EXPORT` with a structured fix-it (attempted name,
12
+ * canonical replacement, import line, docs URL).
13
+ *
14
+ * - **State-changing GET handlers.** Astro pages that export a GET
15
+ * handler containing DB-mutation patterns (`db().insert`, `db().update`,
16
+ * `db().delete`, `adminDb().sql("UPDATE"`, etc.). Emit
17
+ * `R402_AUTH_STATE_CHANGING_GET`.
18
+ *
19
+ * - **`auth.*` calls in prerendered pages.** Astro pages declaring
20
+ * `export const prerender = true` that also call `auth.*` helpers.
21
+ * Emit `R402_AUTH_PRERENDERED`.
22
+ *
23
+ * - **Direct `internal.sessions.authz_version` mutation.** Consumer
24
+ * migrations that try to `UPDATE internal.sessions SET authz_version`
25
+ * manually. Emit `R402_AUTH_AUTHZ_VERSION_PROHIBITED`.
26
+ *
27
+ * The scanner is regex-based — fast, dependency-free, and good enough
28
+ * for the canonical patterns. The `run402 doctor --json` mode emits the
29
+ * structured envelope; the default mode prints a readable per-finding
30
+ * summary. Wired into `run402 deploy` pre-flight as a deploy-failing
31
+ * gate for the error severities; non-blocking for warning severities.
32
+ *
33
+ * @see the auth-aware-ssr OpenSpec change (functions-sdk-auth-model)
34
+ */
35
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
36
+ import { extname, join, relative } from "node:path";
37
+ /** Severity ladder for scanner findings. `error` blocks deploy; `warn`
38
+ * reports but doesn't block. The `run402 doctor` exit code is non-zero
39
+ * whenever any `error`-severity finding is present. */
40
+ export const SCAN_SEVERITY = Object.freeze({
41
+ ERROR: "error",
42
+ WARN: "warn",
43
+ });
44
+ /** File extensions scanned. Astro frontmatter + TS/JS are the primary
45
+ * surface; the regex matchers fire equally on all of them. `.astro`
46
+ * matters because consumers write SSR pages there. */
47
+ const SCANNED_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".astro"]);
48
+ /** Directories the scanner refuses to descend into. We never report
49
+ * on platform-generated code or vendored dependencies. */
50
+ const SKIPPED_DIRECTORIES = new Set([
51
+ "node_modules",
52
+ ".git",
53
+ ".vscode",
54
+ ".idea",
55
+ "dist",
56
+ "build",
57
+ "out",
58
+ ".astro",
59
+ ".next",
60
+ ".vercel",
61
+ ".netlify",
62
+ "coverage",
63
+ ]);
64
+ /** Hallucinated-name registry from the auth-aware-ssr spec. Each entry
65
+ * carries the canonical replacement so the fix-it is actionable. The
66
+ * list is intentionally exhaustive — every name flagged here came up
67
+ * in pre-launch LLM hallucination samples. */
68
+ const HALLUCINATED_NAMES = [
69
+ // ESM named imports — caught by regex on import lines AND by call-site
70
+ // matching when consumers paste from training-data examples.
71
+ { name: "getUser", canonical: "auth.user() / auth.requireUser()", origin: "supabase / clerk / nextauth legacy" },
72
+ { name: "getUserId", canonical: "(await auth.user())?.id", origin: "run402 v0.x" },
73
+ { name: "getRole", canonical: "auth.requireRole(role)", origin: "run402 v0.x" },
74
+ { name: "getSession", canonical: "auth.user()", origin: "next-auth / nextauth" },
75
+ { name: "currentUser", canonical: "auth.user()", origin: "clerk" },
76
+ { name: "currentSession", canonical: "auth.user()", origin: "clerk" },
77
+ { name: "getCurrentUser", canonical: "auth.user()", origin: "generic" },
78
+ { name: "getCurrentSession", canonical: "auth.user()", origin: "generic" },
79
+ { name: "getServerSession", canonical: "auth.user()", origin: "next-auth" },
80
+ { name: "getAuth", canonical: "auth.user() / auth.requireUser()", origin: "clerk" },
81
+ { name: "requireAuth", canonical: "auth.requireUser()", origin: "generic" },
82
+ { name: "withAuth", canonical: "auth.requireUser() inside the handler", origin: "next-auth-style HOC" },
83
+ { name: "protectRoute", canonical: "auth.requireUser() inside the handler", origin: "generic" },
84
+ { name: "useUser", canonical: "auth.user() (note: server-only; not a React hook)", origin: "clerk / supabase" },
85
+ { name: "useSession", canonical: "auth.user() (note: server-only)", origin: "next-auth / clerk" },
86
+ { name: "createServerClient", canonical: "db() (use the bundled SDK; no client setup needed)", origin: "supabase" },
87
+ { name: "clerkClient", canonical: "auth.user() + db()", origin: "clerk" },
88
+ ];
89
+ /** Property-access hallucinations on the `auth` object. The SDK's
90
+ * Proxy catches these at runtime, but the source scanner fires
91
+ * earlier so the deploy fails before the bundle ships. */
92
+ const HALLUCINATED_AUTH_PROPERTIES = [
93
+ { name: "auth.session", canonical: "auth.user() then read .sessionId" },
94
+ { name: "auth.getSession", canonical: "auth.user()" },
95
+ { name: "auth.currentUser", canonical: "auth.user()" },
96
+ { name: "auth.currentSession", canonical: "auth.user()" },
97
+ { name: "auth.requireAuth", canonical: "auth.requireUser()" },
98
+ { name: "auth.middleware", canonical: "auth.csrfField() / @run402/astro middleware" },
99
+ { name: "auth.signIn", canonical: "POST /auth/sign-in or auth.sessions.createResponseFromIdentity({...})" },
100
+ { name: "auth.signOut", canonical: "auth.sessions.endResponse()" },
101
+ { name: "auth.signout", canonical: "auth.sessions.endResponse()" },
102
+ { name: "auth.logout", canonical: "auth.sessions.endResponse()" },
103
+ { name: "auth.login", canonical: "auth.sessions.createResponseFromIdentity({...})" },
104
+ { name: "auth.redirectToSignIn", canonical: "auth.requireUser() — platform handles redirect" },
105
+ { name: "auth.getUser", canonical: "auth.user()" },
106
+ { name: "auth.getToken", canonical: "auth.requireUser() then read .sessionId (tokens not exposed)" },
107
+ { name: "auth.protect", canonical: "auth.requireUser() / auth.requireRole(...)" },
108
+ ];
109
+ /** Browser-only patterns that should NEVER appear in SSR / Lambda code.
110
+ * These are caught at scan time because the SDK doesn't ship a
111
+ * shim — the line just fails to execute. */
112
+ const BROWSER_ONLY_PATTERNS = [
113
+ {
114
+ pattern: /localStorage\.getItem\(\s*['"]wl_session['"]\s*\)/g,
115
+ name: "localStorage.wl_session",
116
+ canonical: "auth.user() (browser sessions are HttpOnly cookies; no localStorage)",
117
+ },
118
+ {
119
+ // Matches: `Authorization: "Bearer ..."` (bare key + string value)
120
+ // `"Authorization": "Bearer ..."` (string key + string value)
121
+ // `'Authorization': 'Bearer ...'` (single quotes)
122
+ pattern: /['"]?Authorization['"]?\s*[:,]\s*['"]Bearer\s/g,
123
+ name: "Authorization: Bearer (in browser code)",
124
+ canonical: "Browser code doesn't carry JWTs. Use auth.fetch() for same-origin SSR fetches.",
125
+ severity: SCAN_SEVERITY.WARN, // Bearer is fine in server-side machine code; gated by file path.
126
+ },
127
+ ];
128
+ /** Scan a single file's content. Returns the array of findings (zero
129
+ * or more). Pure / no I/O — tests pass strings directly. */
130
+ export function scanFileContent(content, opts = {}) {
131
+ const filePath = opts.filePath ?? "<inline>";
132
+ const findings = [];
133
+ // 1) Hallucinated bare names — import { getSession } from ... OR
134
+ // bare call sites `await getSession(...)`.
135
+ for (const entry of HALLUCINATED_NAMES) {
136
+ // Match in an `import { … }` statement OR a bare function-call site.
137
+ // Negative-lookahead: don't fire on `auth.getSession` etc. (caught
138
+ // separately by the auth-property scanner below).
139
+ const importRegex = new RegExp(`import\\s*\\{[^}]*\\b${escapeRegex(entry.name)}\\b[^}]*\\}\\s*from\\s*['"]@run402/functions['"]`, "g");
140
+ const callRegex = new RegExp(`(?<![.\\w])${escapeRegex(entry.name)}\\s*\\(`, "g");
141
+ let match;
142
+ while ((match = importRegex.exec(content)) !== null) {
143
+ findings.push({
144
+ code: "R402_AUTH_UNKNOWN_EXPORT",
145
+ severity: SCAN_SEVERITY.ERROR,
146
+ file: filePath,
147
+ line: lineNumberFor(content, match.index),
148
+ attempted_name: entry.name,
149
+ canonical_name: entry.canonical,
150
+ import_line: 'import { auth } from "@run402/functions"',
151
+ docs: "https://docs.run402.com/auth/sdk",
152
+ message: `Import '${entry.name}' from @run402/functions is not a working export (origin: ${entry.origin}). Use ${entry.canonical}.`,
153
+ });
154
+ }
155
+ while ((match = callRegex.exec(content)) !== null) {
156
+ findings.push({
157
+ code: "R402_AUTH_UNKNOWN_EXPORT",
158
+ severity: SCAN_SEVERITY.ERROR,
159
+ file: filePath,
160
+ line: lineNumberFor(content, match.index),
161
+ attempted_name: entry.name,
162
+ canonical_name: entry.canonical,
163
+ import_line: 'import { auth } from "@run402/functions"',
164
+ docs: "https://docs.run402.com/auth/sdk",
165
+ message: `Call to '${entry.name}()' will throw R402_AUTH_UNKNOWN_EXPORT at runtime. Use ${entry.canonical}.`,
166
+ });
167
+ }
168
+ }
169
+ // 2) Hallucinated property access on `auth.*`. The SDK Proxy catches
170
+ // these at runtime; we catch earlier at deploy.
171
+ for (const entry of HALLUCINATED_AUTH_PROPERTIES) {
172
+ const regex = new RegExp(`(?<![\\w.])${escapeRegex(entry.name)}\\b`, "g");
173
+ let match;
174
+ while ((match = regex.exec(content)) !== null) {
175
+ findings.push({
176
+ code: "R402_AUTH_UNKNOWN_EXPORT",
177
+ severity: SCAN_SEVERITY.ERROR,
178
+ file: filePath,
179
+ line: lineNumberFor(content, match.index),
180
+ attempted_name: entry.name,
181
+ canonical_name: entry.canonical,
182
+ import_line: 'import { auth } from "@run402/functions"',
183
+ docs: "https://docs.run402.com/auth/sdk",
184
+ message: `'${entry.name}' is not a valid auth.* helper. Use ${entry.canonical}.`,
185
+ });
186
+ }
187
+ }
188
+ // 3) Browser-only / wrong-environment patterns.
189
+ for (const entry of BROWSER_ONLY_PATTERNS) {
190
+ let match;
191
+ while ((match = entry.pattern.exec(content)) !== null) {
192
+ findings.push({
193
+ code: "R402_AUTH_UNKNOWN_EXPORT",
194
+ severity: entry.severity ?? SCAN_SEVERITY.ERROR,
195
+ file: filePath,
196
+ line: lineNumberFor(content, match.index),
197
+ attempted_name: entry.name,
198
+ canonical_name: entry.canonical,
199
+ message: `'${entry.name}' is not supported. ${entry.canonical}.`,
200
+ });
201
+ }
202
+ }
203
+ // 4) Prerendered pages calling auth.*. The Astro adapter throws
204
+ // R402_AUTH_PRERENDERED at build time; this catches earlier.
205
+ if (filePath.endsWith(".astro") || filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
206
+ const declaresPrerender = /export\s+const\s+prerender\s*=\s*true/.test(content);
207
+ if (declaresPrerender) {
208
+ const authCallRegex = /\bauth\.(user|requireUser|requireRole|requireMembership|requireFresh|fetch|csrfToken|csrfField|sessions|identities)\b/g;
209
+ let match;
210
+ while ((match = authCallRegex.exec(content)) !== null) {
211
+ findings.push({
212
+ code: "R402_AUTH_PRERENDERED",
213
+ severity: SCAN_SEVERITY.ERROR,
214
+ file: filePath,
215
+ line: lineNumberFor(content, match.index),
216
+ message: `auth.${match[1]} called from a prerendered page. Convert to SSR (\`export const prerender = false\`) or use a server island.`,
217
+ docs: "https://docs.run402.com/auth/rendering-modes",
218
+ });
219
+ }
220
+ }
221
+ }
222
+ // 5) State-changing GET handlers. Heuristic: an Astro `export const GET`
223
+ // or a `GET` Web-handler containing db-mutation patterns.
224
+ const getHandlerRegex = /export\s+(?:async\s+)?(?:const\s+|function\s+)GET\s*[=(]/g;
225
+ const mutationInGetRegex = /\b(?:db|adminDb)\s*\(\s*\)?[^)]*\)?\s*\.(?:insert|update|delete)\s*\(/g;
226
+ const sqlMutationRegex = /\.sql\s*\(\s*['"`]\s*(?:UPDATE|INSERT|DELETE)\b/gi;
227
+ if (getHandlerRegex.test(content)) {
228
+ let match;
229
+ while ((match = mutationInGetRegex.exec(content)) !== null) {
230
+ findings.push({
231
+ code: "R402_AUTH_STATE_CHANGING_GET",
232
+ severity: SCAN_SEVERITY.ERROR,
233
+ file: filePath,
234
+ line: lineNumberFor(content, match.index),
235
+ message: "GET handler mutates state. Move the mutation to POST.",
236
+ docs: "https://docs.run402.com/auth/hosted-ui#post-only",
237
+ });
238
+ }
239
+ while ((match = sqlMutationRegex.exec(content)) !== null) {
240
+ findings.push({
241
+ code: "R402_AUTH_STATE_CHANGING_GET",
242
+ severity: SCAN_SEVERITY.ERROR,
243
+ file: filePath,
244
+ line: lineNumberFor(content, match.index),
245
+ message: "GET handler runs UPDATE/INSERT/DELETE SQL. Move the mutation to POST.",
246
+ docs: "https://docs.run402.com/auth/hosted-ui#post-only",
247
+ });
248
+ }
249
+ }
250
+ // 6) Direct mutation of internal.sessions.authz_version in consumer
251
+ // migrations or SQL strings. The platform is the sole writer.
252
+ const authzVersionRegex = /UPDATE\s+internal\.sessions\s+SET\s+authz_version\b/gi;
253
+ let m;
254
+ while ((m = authzVersionRegex.exec(content)) !== null) {
255
+ findings.push({
256
+ code: "R402_AUTH_AUTHZ_VERSION_PROHIBITED",
257
+ severity: SCAN_SEVERITY.ERROR,
258
+ file: filePath,
259
+ line: lineNumberFor(content, m.index),
260
+ message: "Consumer code may not mutate internal.sessions.authz_version directly. Register your grants table in the authz manifest so the platform installs the bump trigger.",
261
+ docs: "https://docs.run402.com/auth/db-actor-context#authz-version",
262
+ });
263
+ }
264
+ // 7) Redundant `.eq("user_id", user.id)` against RLS-bound tables.
265
+ // db() propagates the actor via the run402.actor.* settings — PostgREST
266
+ // enforces ownership in RLS. Filtering on user_id again is at best a
267
+ // no-op and at worst a code smell that suggests the developer doesn't
268
+ // trust RLS. Catch the most common shapes:
269
+ //
270
+ // .eq("user_id", user.id)
271
+ // .eq('user_id', actor.id)
272
+ // .eq("user_id", await auth.user()).id (rare; covered by the suffix)
273
+ //
274
+ // Opt-out via inline annotation comment on the preceding or same line:
275
+ // // run402-allow-user-filter: <reason>
276
+ // .eq("user_id", joinedRowOwner)
277
+ //
278
+ // Pattern is intentionally narrow (`user_id` literal column name + a
279
+ // value expression matching `<ident>.id`) to keep the false-positive
280
+ // rate low. Heuristic — RLS-binding is unknown at scan time; the rule
281
+ // fires on the shape, and the operator either annotates or fixes.
282
+ const redundantFilterRegex = /\.eq\s*\(\s*['"]user_id['"]\s*,\s*([a-zA-Z_$][\w$]*)\.id\s*\)/g;
283
+ const lines = content.split(/\r?\n/);
284
+ const cumulativeOffsets = (() => {
285
+ const offsets = [0];
286
+ for (let i = 0; i < lines.length; i++) {
287
+ // +1 for the trailing newline we split on
288
+ offsets.push(offsets[i] + lines[i].length + 1);
289
+ }
290
+ return offsets;
291
+ })();
292
+ function lineIndexFor(charIndex) {
293
+ // Binary search would be faster; lines are typically <2k.
294
+ for (let i = 0; i < cumulativeOffsets.length - 1; i++) {
295
+ if (charIndex < cumulativeOffsets[i + 1])
296
+ return i;
297
+ }
298
+ return cumulativeOffsets.length - 2;
299
+ }
300
+ let f;
301
+ while ((f = redundantFilterRegex.exec(content)) !== null) {
302
+ const lineIdx = lineIndexFor(f.index);
303
+ const thisLine = lines[lineIdx] ?? "";
304
+ const prevLine = lineIdx > 0 ? (lines[lineIdx - 1] ?? "") : "";
305
+ const annotated = /\/\/\s*run402-allow-user-filter/i.test(thisLine) ||
306
+ /\/\/\s*run402-allow-user-filter/i.test(prevLine);
307
+ if (annotated)
308
+ continue;
309
+ findings.push({
310
+ code: "R402_AUTH_REDUNDANT_USER_FILTER",
311
+ severity: SCAN_SEVERITY.WARN,
312
+ file: filePath,
313
+ line: lineIdx + 1,
314
+ message: `Redundant '.eq(\"user_id\", ${f[1]}.id)'. db() propagates the actor — PostgREST RLS enforces ownership server-side. ` +
315
+ `If this is intentional (e.g., the table's RLS scopes on something else and you want to filter additionally), ` +
316
+ `silence with: // run402-allow-user-filter: <reason>`,
317
+ docs: "https://run402.com/errors/#R402_AUTH_REDUNDANT_USER_FILTER",
318
+ });
319
+ }
320
+ // 8) Tenant-assertion session-mint call without the declared capability.
321
+ // `auth.sessions.createResponseFromTenantAssertion(...)` mints a browser
322
+ // session from a tenant's vouching. It works ONLY in a function whose
323
+ // deploy/apply spec declares `capabilities: ["auth.sessionMint"]`
324
+ // (FunctionSpec.capabilities — sibling to `config`, since the platform
325
+ // has no code-export metadata channel). Service-key presence is NOT
326
+ // sufficient. Without the capability the gateway returns
327
+ // R402_AUTH_UNTRUSTED_CONTEXT at runtime and mints no session.
328
+ //
329
+ // The pure file scanner can't see the per-function spec, so the caller
330
+ // threads `opts.declaredCapabilities` (the union of capabilities declared
331
+ // across run402.config.json function entries — see readDeclaredCapabilities).
332
+ // We suppress the finding when "auth.sessionMint" is present anywhere in
333
+ // that union. Global-union (not per-file) is a deliberate precision
334
+ // trade-off: the file→function-entry mapping isn't reliable from source,
335
+ // and the runtime gate catches the rare "function A declared it, function
336
+ // B forgot" case. WARN severity (never block deploy): an inline/SDK spec
337
+ // the doctor can't read might declare the capability.
338
+ const declaredCaps = opts.declaredCapabilities instanceof Set
339
+ ? opts.declaredCapabilities
340
+ : new Set(Array.isArray(opts.declaredCapabilities) ? opts.declaredCapabilities : []);
341
+ if (!declaredCaps.has("auth.sessionMint")) {
342
+ const mintCallRegex = /\bcreateResponseFromTenantAssertion\s*\(/g;
343
+ let mintMatch;
344
+ while ((mintMatch = mintCallRegex.exec(content)) !== null) {
345
+ findings.push({
346
+ code: "R402_DOCTOR_AUTH_SESSION_MINT_CAPABILITY_MISSING",
347
+ severity: SCAN_SEVERITY.WARN,
348
+ file: filePath,
349
+ line: lineNumberFor(content, mintMatch.index),
350
+ message: "createResponseFromTenantAssertion (tenant-assertion session mint) requires the " +
351
+ '"auth.sessionMint" capability, which no function declares in run402.config.json. ' +
352
+ "Without it the gateway returns R402_AUTH_UNTRUSTED_CONTEXT at runtime and mints no session.",
353
+ fix: 'Add "capabilities": ["auth.sessionMint"] to this function\'s entry in run402.config.json ' +
354
+ '(under functions.replace.<name>, a sibling to "config"). A service key is NOT sufficient.',
355
+ docs: "https://docs.run402.com/auth/tenant-assertion#capability",
356
+ });
357
+ }
358
+ }
359
+ return findings;
360
+ }
361
+ /** Recursively walk `srcDir` and scan every file with a relevant
362
+ * extension. Returns the combined findings list, sorted by file +
363
+ * line for stable output. */
364
+ export function scanSourceTree(srcDir, opts = {}) {
365
+ const findings = [];
366
+ // Capability picture for the tenant-assertion mint check (#8). Read from
367
+ // run402.config.json unless the caller passed it explicitly (tests do).
368
+ const declaredCapabilities = opts.declaredCapabilities ?? readDeclaredCapabilities(opts.cwd ?? srcDir);
369
+ walk(srcDir, (filePath) => {
370
+ if (!SCANNED_EXTENSIONS.has(extname(filePath)) || opts.excludeFiles?.has(filePath))
371
+ return;
372
+ let content;
373
+ try {
374
+ content = readFileSync(filePath, "utf8");
375
+ }
376
+ catch (err) {
377
+ findings.push({
378
+ code: "R402_AUTH_SOURCE_SCAN_ERROR",
379
+ severity: SCAN_SEVERITY.WARN,
380
+ file: relative(opts.cwd ?? srcDir, filePath),
381
+ message: `failed to read file: ${err instanceof Error ? err.message : String(err)}`,
382
+ });
383
+ return;
384
+ }
385
+ findings.push(...scanFileContent(content, {
386
+ filePath: relative(opts.cwd ?? srcDir, filePath),
387
+ declaredCapabilities,
388
+ }));
389
+ });
390
+ findings.sort((a, b) => {
391
+ if (a.file !== b.file)
392
+ return a.file < b.file ? -1 : 1;
393
+ return (a.line ?? 0) - (b.line ?? 0);
394
+ });
395
+ return findings;
396
+ }
397
+ /** Scan an explicit list of on-disk file paths — no directory walk.
398
+ * Used by `run402 deploy apply` for manifest/spec/stdin deploys, where
399
+ * the artifact is exactly the set of files the manifest references, NOT
400
+ * whatever happens to live under cwd/src. Files without a
401
+ * scannable extension are ignored; unreadable files become a WARN
402
+ * finding (never throw). Returns the combined findings list, sorted by
403
+ * file + line for stable output, exactly like `scanSourceTree`. */
404
+ export function scanSourceFiles(filePaths, opts = {}) {
405
+ const findings = [];
406
+ const cwd = opts.cwd ?? process.cwd();
407
+ // Same capability picture as scanSourceTree (#8 mint check).
408
+ const declaredCapabilities = opts.declaredCapabilities ?? readDeclaredCapabilities(cwd);
409
+ for (const filePath of filePaths) {
410
+ if (!SCANNED_EXTENSIONS.has(extname(filePath)))
411
+ continue;
412
+ let content;
413
+ try {
414
+ content = readFileSync(filePath, "utf8");
415
+ }
416
+ catch (err) {
417
+ findings.push({
418
+ code: "R402_AUTH_SOURCE_SCAN_ERROR",
419
+ severity: SCAN_SEVERITY.WARN,
420
+ file: relative(cwd, filePath),
421
+ message: `failed to read file: ${err instanceof Error ? err.message : String(err)}`,
422
+ });
423
+ continue;
424
+ }
425
+ findings.push(...scanFileContent(content, {
426
+ filePath: relative(cwd, filePath),
427
+ declaredCapabilities,
428
+ }));
429
+ }
430
+ findings.sort((a, b) => {
431
+ if (a.file !== b.file)
432
+ return a.file < b.file ? -1 : 1;
433
+ return (a.line ?? 0) - (b.line ?? 0);
434
+ });
435
+ return findings;
436
+ }
437
+ function walk(dir, visitor) {
438
+ let entries;
439
+ try {
440
+ entries = readdirSync(dir, { withFileTypes: true });
441
+ }
442
+ catch {
443
+ return;
444
+ }
445
+ for (const entry of entries) {
446
+ if (entry.isDirectory()) {
447
+ if (SKIPPED_DIRECTORIES.has(entry.name))
448
+ continue;
449
+ const child = join(dir, entry.name);
450
+ if (existsSync(join(child, ".git")) || ["run402.json", "run402.deploy.json", "app.json"].some((name) => existsSync(join(child, name))))
451
+ continue;
452
+ walk(child, visitor);
453
+ }
454
+ else if (entry.isFile()) {
455
+ visitor(join(dir, entry.name));
456
+ }
457
+ }
458
+ }
459
+ function lineNumberFor(content, index) {
460
+ let line = 1;
461
+ for (let i = 0; i < index; i++) {
462
+ if (content.charCodeAt(i) === 10)
463
+ line++;
464
+ }
465
+ return line;
466
+ }
467
+ function escapeRegex(s) {
468
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
469
+ }
470
+ /** Convenience for tests: synchronous, no FS access. */
471
+ export function _testOnly_hallucinatedNames() {
472
+ return HALLUCINATED_NAMES.slice();
473
+ }
474
+ export function _testOnly_authProperties() {
475
+ return HALLUCINATED_AUTH_PROPERTIES.slice();
476
+ }
477
+ /** Read the union of `capabilities` declared across all function entries in
478
+ * `run402.config.json` (the apply spec). Used by the tenant-assertion mint
479
+ * check (#8) to suppress the warning when "auth.sessionMint" is declared.
480
+ *
481
+ * Functions live under `functions.replace.<name>` / `functions.set.<name>`
482
+ * with `capabilities?: string[]` as a sibling to `config`. Best-effort:
483
+ * a missing or malformed config returns an empty set (the scanner then
484
+ * warns, which is the safe default — the runtime gate is the hard
485
+ * enforcement). Returns a `Set<string>`. */
486
+ export function readDeclaredCapabilities(cwd = process.cwd()) {
487
+ const caps = new Set();
488
+ let parsed;
489
+ try {
490
+ parsed = JSON.parse(readFileSync(join(cwd, "run402.config.json"), "utf8"));
491
+ }
492
+ catch {
493
+ return caps; // no config / unreadable / malformed → nothing declared
494
+ }
495
+ const fns = parsed?.functions;
496
+ if (!fns || typeof fns !== "object")
497
+ return caps;
498
+ for (const bucket of ["replace", "set", "patch"]) {
499
+ const entries = fns[bucket];
500
+ if (!entries || typeof entries !== "object")
501
+ continue;
502
+ for (const entry of Object.values(entries)) {
503
+ const declared = entry?.capabilities;
504
+ if (Array.isArray(declared)) {
505
+ for (const cap of declared)
506
+ if (typeof cap === "string")
507
+ caps.add(cap);
508
+ }
509
+ }
510
+ }
511
+ return caps;
512
+ }
513
+ /** Resolve the project's src/ directory. Astro convention is `<root>/src`;
514
+ * bare Node projects use `<root>/src` or `<root>`. We prefer `src/` if
515
+ * it exists. */
516
+ export function resolveScanRoot(cwd = process.cwd()) {
517
+ const srcDir = join(cwd, "src");
518
+ try {
519
+ if (statSync(srcDir).isDirectory())
520
+ return srcDir;
521
+ }
522
+ catch {
523
+ // Fall through.
524
+ }
525
+ return cwd;
526
+ }
527
+ /** The same selected-app scope gates up/apply and is reported by doctor. */
528
+ export function scanDeploymentSources(spec, appRoot, sourceRoot) {
529
+ const scanRoot = sourceRoot ?? resolveScanRoot(appRoot);
530
+ const generated = new Set();
531
+ for (const bucket of [spec.functions?.replace, spec.functions?.patch?.set]) {
532
+ for (const fn of Object.values(bucket ?? {})) {
533
+ if (fn.capabilities?.includes("astro.ssr.v1") && fn.source && typeof fn.source === "object" && "path" in fn.source)
534
+ generated.add(fn.source.path);
535
+ }
536
+ }
537
+ const references = collectLocalFileReferences(spec).filter((ref) => ref.expects === "file" && !generated.has(ref.path));
538
+ // Generated SSR bundles must not be re-scanned as consumer source. Their
539
+ // original source remains in the selected application's source tree.
540
+ const files = new Set();
541
+ if (sourceRoot || scanRoot !== appRoot)
542
+ walk(scanRoot, (path) => {
543
+ if (SCANNED_EXTENSIONS.has(extname(path)) && !generated.has(path))
544
+ files.add(path);
545
+ });
546
+ for (const reference of references)
547
+ if (SCANNED_EXTENSIONS.has(extname(reference.path)))
548
+ files.add(reference.path);
549
+ const findings = scanSourceFiles([...files], { cwd: appRoot });
550
+ return { app_root: appRoot, scan_root: scanRoot, checked_files: files.size, explicit_references: references.length, findings, errors: findings.filter((finding) => finding.severity === SCAN_SEVERITY.ERROR) };
551
+ }
552
+ //# sourceMappingURL=source-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-scan.js","sourceRoot":"","sources":["../../src/node/source-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { ApiError, type Run402Error } from "./errors.js";
2
+ /** Client diagnostic only: the original PostgREST body/status remain available. */
3
+ export declare class RestPermissionDenied extends ApiError {
4
+ readonly code = "REST_PERMISSION_DENIED";
5
+ readonly details: {
6
+ source: "postgrest";
7
+ upstream_status: number | null;
8
+ upstream_code: "42501";
9
+ method: string;
10
+ relation: string;
11
+ };
12
+ constructor(error: Run402Error, method: string, relation: string);
13
+ }
14
+ export declare function restDiagnostic(error: unknown, method: string, relation: string): unknown;
15
+ //# sourceMappingURL=rest-diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-diagnostics.d.ts","sourceRoot":"","sources":["../src/rest-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAExE,mFAAmF;AACnF,qBAAa,oBAAqB,SAAQ,QAAQ;IAChD,SAAkB,IAAI,4BAA4B;IAClD,SAAkB,OAAO,EAAE;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;gBACjI,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAIjE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMxF"}
@@ -0,0 +1,19 @@
1
+ import { ApiError, isRun402Error } from "./errors.js";
2
+ /** Client diagnostic only: the original PostgREST body/status remain available. */
3
+ export class RestPermissionDenied extends ApiError {
4
+ code = "REST_PERMISSION_DENIED";
5
+ details;
6
+ constructor(error, method, relation) {
7
+ super("PostgREST denied this operation; check grants and policies for the request role.", error.status, error.body, error.context);
8
+ this.details = { source: "postgrest", upstream_status: error.status, upstream_code: "42501", method, relation };
9
+ }
10
+ }
11
+ export function restDiagnostic(error, method, relation) {
12
+ if (!isRun402Error(error))
13
+ return error;
14
+ const body = error.body;
15
+ // Only the public native SQLSTATE is interpreted. Never parse private schema
16
+ // names out of upstream text or infer exposure/RLS from permission denial.
17
+ return body?.code === "42501" ? new RestPermissionDenied(error, method, relation) : error;
18
+ }
19
+ //# sourceMappingURL=rest-diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-diagnostics.js","sourceRoot":"","sources":["../src/rest-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AAExE,mFAAmF;AACnF,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IAC9B,IAAI,GAAG,wBAAwB,CAAC;IAChC,OAAO,CAAoH;IAC7I,YAAY,KAAkB,EAAE,MAAc,EAAE,QAAgB;QAC9D,KAAK,CAAC,kFAAkF,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACnI,IAAI,CAAC,OAAO,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAClH,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,MAAc,EAAE,QAAgB;IAC7E,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAiC,CAAC;IACrD,6EAA6E;IAC7E,2EAA2E;IAC3E,OAAO,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC5F,CAAC"}