@ttt-productions/repo-guards 0.1.1 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/modules/frontend-actions/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/modules/frontend-actions/auth.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,9 @@ import { fromStatements, moduleImports, namesModule } from '../../support/import
6
6
  import { escapeRegExp, isUnder } from '../../support/text.js';
7
7
  import { memberOrBareCalls, throughNamespace } from './text.js';
8
8
  const APP_CODE = { roots: ['app'], kinds: ['code'], tests: false };
9
- const declares = (code, name) => new RegExp(`\\b(?:function|const|let)\\s+${escapeRegExp(name)}\\b`).test(code);
9
+ /** The keywords that declare a name a module can export: a function, a binding, or a class. */
10
+ const DECLARATION_KEYWORDS = '(?:function|const|let|class)';
11
+ const declares = (code, name) => new RegExp(`\\b${DECLARATION_KEYWORDS}\\s+${escapeRegExp(name)}\\b`).test(code);
10
12
  /**
11
13
  * Each place outside the boundary that derives identity, claims, or auth loading itself. A call is
12
14
  * matched bare or as a member (`auth.onAuthStateChanged(cb)`, `getAuth().onIdTokenChanged(cb)`),
@@ -235,7 +237,7 @@ export const signOutLivenessGuard = {
235
237
  return problems;
236
238
  },
237
239
  build(facts) {
238
- const redeclared = new RegExp(`\\b(?:function|const)\\s+(?:${facts.ownerExports.map(escapeRegExp).join('|')})\\b`, 'g');
240
+ const redeclared = new RegExp(`\\b${DECLARATION_KEYWORDS}\\s+(?:${facts.ownerExports.map(escapeRegExp).join('|')})\\b`, 'g');
239
241
  const negatedSkip = new RegExp(`!\\s*${escapeRegExp(facts.authAccessor)}\\(\\)\\s*\\??\\.\\s*currentUser`, 'g');
240
242
  return [
241
243
  {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/modules/frontend-actions/auth.ts"],"names":[],"mappings":"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","sourcesContent":["// The guards over the client's auth boundary: one place that answers \"who is this\", auth failures\n// that reach monitoring, sign-out liveness through its owner, and editors no permission read can drop.\n\nimport ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../config.js';\nimport type { Finding, Guard } from '../../guard.js';\nimport type { Reviewed } from '../../reader/layout.js';\nimport type { Scope } from '../../reader/reader.js';\nimport type { FileView } from '../../reader/view.js';\nimport { namesProblem, objectProblem, reviewedProblems, textProblem } from '../../support/facts.js';\nimport { fromStatements, moduleImports, namesModule } from '../../support/imports.js';\nimport { escapeRegExp, isUnder } from '../../support/text.js';\nimport { memberOrBareCalls, throughNamespace } from './text.js';\n\nconst APP_CODE: Scope = { roots: ['app'], kinds: ['code'], tests: false };\n\nconst declares = (code: string, name: string) => new RegExp(`\\\\b(?:function|const|let)\\\\s+${escapeRegExp(name)}\\\\b`).test(code);\n\n// ---------------------------------------------------------------------------------------------\n// Client auth boundary: one derivation of identity and claims, and one auth context and accessor.\n// Where a signed-out visitor is sent is business: an app browsable signed out shows a sign-in gate in\n// place, an app that requires sign-in sends the visitor to its sign-in route. It is not checked here.\n\nexport interface ClientAuthBoundaryFacts {\n /** The modules that ARE the boundary — the provider mount, its configuration, the accessor — each with why. */\n boundaryModules: readonly Reviewed[];\n /** The one accessor every other module reads auth through. */\n accessor: { file: string; name: string };\n /** Symbols that derive identity, claims, or auth loading state. */\n derivationSymbols: readonly string[];\n /** Modules those symbols can be reached through as a namespace (a module covers its subpaths). */\n authSourceModules: readonly string[];\n /** Names only an auth context holds; a `createContext` beside one is a second auth context. */\n authContextVocabulary: readonly string[];\n}\n\n/**\n * Each place outside the boundary that derives identity, claims, or auth loading itself. A call is\n * matched bare or as a member (`auth.onAuthStateChanged(cb)`, `getAuth().onIdTokenChanged(cb)`),\n * since the SDK hands out the same derivations as instance methods.\n */\nexport function boundaryDerivations(file: FileView, facts: Pick<ClientAuthBoundaryFacts, 'derivationSymbols' | 'authSourceModules'>): Array<{ index: number; detail: string }> {\n const { code, sourceFile } = file;\n const out: Array<{ index: number; detail: string }> = [];\n for (const site of moduleImports(sourceFile, ['import'])) {\n if (site.typeOnly) continue;\n for (const { imported, typeOnly } of site.named) {\n if (!typeOnly && facts.derivationSymbols.includes(imported)) out.push({ index: site.node.getStart(sourceFile), detail: `imports ${imported}` });\n }\n }\n const namespaces: string[] = [];\n for (const site of fromStatements(sourceFile)) {\n if (site.namespace && facts.authSourceModules.some((m) => namesModule(site.spec, m))) namespaces.push(site.namespace);\n }\n for (const namespace of namespaces) {\n for (const symbol of facts.derivationSymbols) {\n const m = new RegExp(`\\\\b${escapeRegExp(namespace)}\\\\s*\\\\.\\\\s*${escapeRegExp(symbol)}\\\\b`).exec(code);\n if (m) out.push({ index: m.index, detail: `reaches ${namespace}.${symbol}` });\n }\n }\n for (const symbol of facts.derivationSymbols) {\n const call = memberOrBareCalls(code, symbol).find((index) => !throughNamespace(code, index, namespaces));\n if (call !== undefined) out.push({ index: call, detail: `calls ${symbol}(` });\n }\n return out;\n}\n\n/** A second export of the accessor's name, or a context holding auth vocabulary, in one file. */\nexport function secondAuthAccessors(\n path: string,\n code: string,\n facts: Pick<ClientAuthBoundaryFacts, 'accessor' | 'authContextVocabulary' | 'boundaryModules'>,\n): Array<{ index: number; detail: string }> {\n const out: Array<{ index: number; detail: string }> = [];\n const name = escapeRegExp(facts.accessor.name);\n if (path !== facts.accessor.file) {\n const exported =\n new RegExp(`\\\\bexport\\\\s+function\\\\s+${name}\\\\s*[(<]`).exec(code) ??\n new RegExp(`\\\\bexport\\\\s+(?:const|let|var)\\\\s+${name}\\\\b`).exec(code) ??\n new RegExp(`\\\\bexport\\\\s*\\\\{[^}]*\\\\b${name}\\\\b[^}]*\\\\}`).exec(code);\n if (exported) out.push({ index: exported.index, detail: `a second export of ${facts.accessor.name}` });\n }\n if (!facts.boundaryModules.some((m) => m.path === path)) {\n const vocabulary = new RegExp(`\\\\b(?:${facts.authContextVocabulary.map(escapeRegExp).join('|')})\\\\b`);\n if (vocabulary.test(code)) {\n for (const m of code.matchAll(/\\bcreateContext\\s*[<(]/g)) out.push({ index: m.index!, detail: 'a second auth context' });\n }\n }\n return out;\n}\n\nexport const clientAuthBoundaryGuard: GenericGuardDefinition<ClientAuthBoundaryFacts> = {\n id: 'clientAuthBoundary',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n reviewedProblems(facts?.boundaryModules, 'boundaryModules', problems);\n if (objectProblem(facts?.accessor, 'accessor', problems)) {\n textProblem(facts.accessor.file, 'accessor.file', problems);\n textProblem(facts.accessor.name, 'accessor.name', problems);\n if (Array.isArray(facts.boundaryModules) && !facts.boundaryModules.some((m) => m?.path === facts.accessor.file)) {\n problems.push(`the accessor ${facts.accessor.file} is not one of the boundaryModules`);\n }\n }\n namesProblem(facts?.derivationSymbols, 'derivationSymbols', problems);\n namesProblem(facts?.authSourceModules, 'authSourceModules', problems);\n namesProblem(facts?.authContextVocabulary, 'authContextVocabulary', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'the client has one auth boundary',\n description:\n `Identity, claims, and auth loading state come from one provider, read through \\`${facts.accessor.name}\\` ` +\n `(${facts.accessor.file}). Outside the boundary modules nothing imports, reaches, or calls ` +\n `${facts.derivationSymbols.join(', ')}; no other module exports \\`${facts.accessor.name}\\` or creates a ` +\n 'context holding auth state. Read the accessor.',\n run(context) {\n const findings: Finding[] = [];\n for (const file of context.files(APP_CODE)) {\n const inBoundary = facts.boundaryModules.some((m) => m.path === file.path);\n const hits = [\n ...(inBoundary ? [] : boundaryDerivations(file, facts)),\n ...secondAuthAccessors(file.path, file.code, facts),\n ];\n for (const hit of hits) findings.push({ file: file.path, line: file.lineOf(hit.index), detail: hit.detail });\n }\n for (const module of facts.boundaryModules) {\n if (!context.reader.exists(module.path)) findings.push({ file: module.path, detail: 'stale boundary module: it no longer exists' });\n }\n if (context.reader.exists(facts.accessor.file)) {\n const code = context.file(facts.accessor.file).code;\n if (!new RegExp(`\\\\bexport\\\\s+(?:function|const)\\\\s+${escapeRegExp(facts.accessor.name)}\\\\b`).test(code)) {\n findings.push({ file: facts.accessor.file, detail: `the accessor no longer exports ${facts.accessor.name}` });\n }\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Banned auth calls: a call the auth surfaces must never make.\n\nexport interface BannedAuthCallFacts {\n /** The folders and files that make up the auth surfaces. */\n surfaces: readonly string[];\n /** Each banned call and why it is banned. */\n banned: ReadonlyArray<{ name: string; why: string }>;\n /** A long-lived auth surface the scan must reach. */\n anchor: string;\n}\n\nexport const bannedAuthCallGuard: GenericGuardDefinition<BannedAuthCallFacts> = {\n id: 'bannedAuthCalls',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.surfaces, 'surfaces', problems);\n if (!Array.isArray(facts?.banned) || !facts.banned.length) problems.push('banned is missing or empty');\n else for (const b of facts.banned) {\n textProblem(b?.name, 'a banned call', problems);\n textProblem(b?.why, `banned call ${String(b?.name)}'s why`, problems);\n }\n textProblem(facts?.anchor, 'anchor', problems);\n if (typeof facts?.anchor === 'string' && Array.isArray(facts?.surfaces) && !facts.surfaces.some((s) => isUnder(facts.anchor, s))) {\n problems.push(`the anchor ${facts.anchor} is not inside any surface`);\n }\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'the auth surfaces never name a banned auth call',\n description:\n `No file under ${facts.surfaces.join(', ')} imports or calls ` +\n facts.banned.map((b) => `\\`${b.name}\\` (${b.why})`).join('; ') +\n '. The symbol must not be reachable from these modules at all.',\n run(context) {\n const findings: Finding[] = [];\n const files = context.files(APP_CODE).filter((f) => facts.surfaces.some((s) => isUnder(f.path, s)));\n if (!files.some((f) => f.path === facts.anchor)) findings.push({ file: facts.anchor, detail: 'the anchor surface was not reached (gone, or outside the surfaces)' });\n for (const file of files) {\n for (const { name, why } of facts.banned) {\n const re = new RegExp(`\\\\b${escapeRegExp(name)}\\\\b`, 'g');\n for (let m = re.exec(file.code); m; m = re.exec(file.code)) {\n findings.push({ file: file.path, line: file.lineOf(m.index), detail: `names ${name}: ${why}` });\n }\n }\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Auth failure capture: every source calling a Firebase Auth operation that can fail reports it.\n\nexport interface AuthFailureCaptureFacts {\n /** The function every auth failure is reported through. */\n reporter: string;\n /** Sources that leave the report to the code that catches their failure, each with why and the file that reports it. */\n reportedElsewhere: ReadonlyArray<{ path: string; why: string; reportedBy: string }>;\n}\n\n/** The Firebase Auth operations that reach the service and can fail. */\nconst FAILING_AUTH_OPERATION =\n /^(?:createUserWithEmailAndPassword|signInWith\\w+|signOut|sendPasswordResetEmail|confirmPasswordReset|verifyPasswordResetCode|checkActionCode|applyActionCode|sendEmailVerification|reauthenticateWith\\w+|updatePassword|updateEmail|verifyBeforeUpdateEmail|linkWith\\w+|deleteUser)$/;\n\n/** The failing operations a source imports as values from the Firebase Auth SDK. */\nexport function failingAuthImports(file: FileView): string[] {\n const names: string[] = [];\n for (const site of moduleImports(file.sourceFile, ['import'])) {\n if (site.typeOnly || site.spec !== 'firebase/auth') continue;\n for (const { imported, typeOnly } of site.named) if (!typeOnly && FAILING_AUTH_OPERATION.test(imported)) names.push(imported);\n }\n return names;\n}\n\nexport const authFailureCaptureGuard: GenericGuardDefinition<AuthFailureCaptureFacts> = {\n id: 'authFailureCapture',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.reporter, 'reporter', problems);\n reviewedProblems(facts?.reportedElsewhere, 'reportedElsewhere', problems);\n for (const e of Array.isArray(facts?.reportedElsewhere) ? facts.reportedElsewhere : []) {\n if (e && (typeof e.reportedBy !== 'string' || !e.reportedBy.trim())) {\n problems.push(`reportedElsewhere entry ${e.path} names no reportedBy file (the file that reports its failures)`);\n }\n }\n return problems;\n },\n build(facts) {\n const reports = new RegExp(`\\\\b${escapeRegExp(facts.reporter)}\\\\s*\\\\(`);\n return [\n {\n title: 'every Firebase Auth failure reaches monitoring',\n description:\n `A source that calls a Firebase Auth operation that can fail reports its failure through \\`${facts.reporter}\\`; ` +\n 'a catch that only shows a message leaves a broken sign-up or sign-in invisible to monitoring. A source that ' +\n 'never catches the failure itself is a reviewed entry naming who reports for it; an entry that no longer calls ' +\n 'a failing operation, now reports itself, or whose reporter no longer reports is stale.',\n run(context) {\n const findings: Finding[] = [];\n const callers = context.files(APP_CODE).map((f) => ({ file: f, ops: failingAuthImports(f) })).filter((c) => c.ops.length);\n if (!callers.length) findings.push({ file: '(app)', detail: 'no source imports a failing Firebase Auth operation — the scan found no auth surface' });\n const reviewed = new Map(facts.reportedElsewhere.map((e) => [e.path, e]));\n for (const { file, ops } of callers) {\n if (!reports.test(file.code) && !reviewed.has(file.path)) findings.push({ file: file.path, detail: `calls ${ops.join(', ')} and never reports a failure` });\n }\n for (const entry of facts.reportedElsewhere) {\n const caller = callers.find((c) => c.file.path === entry.path);\n if (!caller) findings.push({ file: entry.path, detail: 'stale entry: it no longer calls a failing auth operation' });\n else if (reports.test(caller.file.code)) findings.push({ file: entry.path, detail: 'stale entry: it reports its own failures now' });\n if (!context.reader.exists(entry.reportedBy)) findings.push({ file: entry.reportedBy, detail: `the reporter named for ${entry.path} no longer exists` });\n else if (!reports.test(context.file(entry.reportedBy).code)) findings.push({ file: entry.reportedBy, detail: `the reporter named for ${entry.path} no longer reports` });\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Sign-out liveness: the \"still signed in\" check has one owner.\n\nexport interface SignOutLivenessFacts {\n /** The module that owns the liveness check. */\n owner: string;\n /** The names the owner exports for it. */\n ownerExports: readonly string[];\n /** The function that returns the client auth instance. */\n authAccessor: string;\n}\n\nexport const signOutLivenessGuard: GenericGuardDefinition<SignOutLivenessFacts> = {\n id: 'signOutLiveness',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.owner, 'owner', problems);\n namesProblem(facts?.ownerExports, 'ownerExports', problems);\n textProblem(facts?.authAccessor, 'authAccessor', problems);\n return problems;\n },\n build(facts) {\n const redeclared = new RegExp(`\\\\b(?:function|const)\\\\s+(?:${facts.ownerExports.map(escapeRegExp).join('|')})\\\\b`, 'g');\n const negatedSkip = new RegExp(`!\\\\s*${escapeRegExp(facts.authAccessor)}\\\\(\\\\)\\\\s*\\\\??\\\\.\\\\s*currentUser`, 'g');\n return [\n {\n title: 'the signed-in check before an awaited call has one owner',\n description:\n `A check that the user is still signed in, made across an awaited hop before a call, is ${facts.owner}'s ` +\n `(${facts.ownerExports.join(', ')}). Nothing else re-declares those names or hand-rolls a negated ` +\n `\\`${facts.authAccessor}().currentUser\\` skip guard: import the owner.`,\n run(context) {\n const findings: Finding[] = [];\n for (const file of context.files(APP_CODE)) {\n if (file.path === facts.owner) continue;\n for (const re of [redeclared, negatedSkip]) {\n re.lastIndex = 0;\n for (let m = re.exec(file.code); m; m = re.exec(file.code)) {\n findings.push({ file: file.path, line: file.lineOf(m.index), detail: re === redeclared ? `re-declares ${m[0].split(/\\s+/).pop()}` : 'hand-rolls a negated currentUser skip guard' });\n }\n }\n }\n if (!context.reader.exists(facts.owner)) findings.push({ file: facts.owner, detail: 'the owner no longer exists' });\n else {\n const code = context.file(facts.owner).code;\n for (const name of facts.ownerExports) if (!declares(code, name)) findings.push({ file: facts.owner, detail: `the owner no longer declares ${name}` });\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Editor permission gate: an editor holding typed input is never mounted under a permission read.\n\nexport interface EditorPermissionGateFacts {\n /** The hook an editor calls to guard its unsaved input: a file calling it holds an editor. */\n editorMarker: string;\n /** The element the editor mounts in. */\n editorElement: string;\n /** Permission reads: identifiers starting with this prefix and a capital letter. */\n permissionNamePrefix: string;\n /** Permission reads: calls to these functions (declare [] when none). */\n permissionCalls: readonly string[];\n}\n\n/** Each editor element with an ancestor `{<permission read> && …}`. */\nexport function permissionGatedEditors(sf: ts.SourceFile, facts: Omit<EditorPermissionGateFacts, 'editorMarker'>): ts.Node[] {\n const prefix = new RegExp(`^${escapeRegExp(facts.permissionNamePrefix)}[A-Z]`);\n const readsPermission = (expr: ts.Expression) => {\n let found = false;\n const visit = (node: ts.Node) => {\n if (ts.isIdentifier(node) && prefix.test(node.text)) found = true;\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && facts.permissionCalls.includes(node.expression.text)) found = true;\n ts.forEachChild(node, visit);\n };\n visit(expr);\n return found;\n };\n const out: ts.Node[] = [];\n const visit = (node: ts.Node) => {\n if ((ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) && node.tagName.getText(sf) === facts.editorElement) {\n for (let p: ts.Node | undefined = node.parent; p; p = p.parent) {\n if (\n ts.isJsxExpression(p) &&\n p.expression &&\n ts.isBinaryExpression(p.expression) &&\n p.expression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken &&\n readsPermission(p.expression.left)\n ) {\n out.push(node);\n break;\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return out;\n}\n\nexport const editorPermissionGateGuard: GenericGuardDefinition<EditorPermissionGateFacts> = {\n id: 'editorPermissionGate',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.editorMarker, 'editorMarker', problems);\n textProblem(facts?.editorElement, 'editorElement', problems);\n textProblem(facts?.permissionNamePrefix, 'permissionNamePrefix', problems);\n namesProblem(facts?.permissionCalls, 'permissionCalls', problems, { nonEmpty: false });\n return problems;\n },\n build(facts): Guard[] {\n return [\n {\n title: 'an editor holding typed input is never mounted under a permission gate',\n description:\n `A component that guards its unsaved input (\\`${facts.editorMarker}\\`) gates only the control that opens its ` +\n `editor on a permission; its \\`<${facts.editorElement}>\\` stays mounted, so a permission read that changes or ` +\n 'fails while it is open can never unmount it and drop what was typed. Gate the trigger, and key the editor to ' +\n 'the account that opened it.',\n run(context) {\n const findings: Finding[] = [];\n const marker = new RegExp(`\\\\b${escapeRegExp(facts.editorMarker)}\\\\s*\\\\(`);\n const editors = context.files(APP_CODE).filter((f) => marker.test(f.code));\n if (!editors.length) findings.push({ file: '(app)', detail: `no component calls ${facts.editorMarker} — the scan found no editor to check` });\n for (const file of editors) {\n for (const node of permissionGatedEditors(file.sourceFile, facts)) {\n findings.push({ file: file.path, line: file.lineOf(node.getStart(file.sourceFile)), detail: `<${facts.editorElement}> mounted under a permission gate` });\n }\n }\n return findings;\n },\n },\n ];\n },\n};\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/modules/frontend-actions/auth.ts"],"names":[],"mappings":"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","sourcesContent":["// The guards over the client's auth boundary: one place that answers \"who is this\", auth failures\n// that reach monitoring, sign-out liveness through its owner, and editors no permission read can drop.\n\nimport ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../config.js';\nimport type { Finding, Guard } from '../../guard.js';\nimport type { Reviewed } from '../../reader/layout.js';\nimport type { Scope } from '../../reader/reader.js';\nimport type { FileView } from '../../reader/view.js';\nimport { namesProblem, objectProblem, reviewedProblems, textProblem } from '../../support/facts.js';\nimport { fromStatements, moduleImports, namesModule } from '../../support/imports.js';\nimport { escapeRegExp, isUnder } from '../../support/text.js';\nimport { memberOrBareCalls, throughNamespace } from './text.js';\n\nconst APP_CODE: Scope = { roots: ['app'], kinds: ['code'], tests: false };\n\n/** The keywords that declare a name a module can export: a function, a binding, or a class. */\nconst DECLARATION_KEYWORDS = '(?:function|const|let|class)';\nconst declares = (code: string, name: string) => new RegExp(`\\\\b${DECLARATION_KEYWORDS}\\\\s+${escapeRegExp(name)}\\\\b`).test(code);\n\n// ---------------------------------------------------------------------------------------------\n// Client auth boundary: one derivation of identity and claims, and one auth context and accessor.\n// Where a signed-out visitor is sent is business: an app browsable signed out shows a sign-in gate in\n// place, an app that requires sign-in sends the visitor to its sign-in route. It is not checked here.\n\nexport interface ClientAuthBoundaryFacts {\n /** The modules that ARE the boundary — the provider mount, its configuration, the accessor — each with why. */\n boundaryModules: readonly Reviewed[];\n /** The one accessor every other module reads auth through. */\n accessor: { file: string; name: string };\n /** Symbols that derive identity, claims, or auth loading state. */\n derivationSymbols: readonly string[];\n /** Modules those symbols can be reached through as a namespace (a module covers its subpaths). */\n authSourceModules: readonly string[];\n /** Names only an auth context holds; a `createContext` beside one is a second auth context. */\n authContextVocabulary: readonly string[];\n}\n\n/**\n * Each place outside the boundary that derives identity, claims, or auth loading itself. A call is\n * matched bare or as a member (`auth.onAuthStateChanged(cb)`, `getAuth().onIdTokenChanged(cb)`),\n * since the SDK hands out the same derivations as instance methods.\n */\nexport function boundaryDerivations(file: FileView, facts: Pick<ClientAuthBoundaryFacts, 'derivationSymbols' | 'authSourceModules'>): Array<{ index: number; detail: string }> {\n const { code, sourceFile } = file;\n const out: Array<{ index: number; detail: string }> = [];\n for (const site of moduleImports(sourceFile, ['import'])) {\n if (site.typeOnly) continue;\n for (const { imported, typeOnly } of site.named) {\n if (!typeOnly && facts.derivationSymbols.includes(imported)) out.push({ index: site.node.getStart(sourceFile), detail: `imports ${imported}` });\n }\n }\n const namespaces: string[] = [];\n for (const site of fromStatements(sourceFile)) {\n if (site.namespace && facts.authSourceModules.some((m) => namesModule(site.spec, m))) namespaces.push(site.namespace);\n }\n for (const namespace of namespaces) {\n for (const symbol of facts.derivationSymbols) {\n const m = new RegExp(`\\\\b${escapeRegExp(namespace)}\\\\s*\\\\.\\\\s*${escapeRegExp(symbol)}\\\\b`).exec(code);\n if (m) out.push({ index: m.index, detail: `reaches ${namespace}.${symbol}` });\n }\n }\n for (const symbol of facts.derivationSymbols) {\n const call = memberOrBareCalls(code, symbol).find((index) => !throughNamespace(code, index, namespaces));\n if (call !== undefined) out.push({ index: call, detail: `calls ${symbol}(` });\n }\n return out;\n}\n\n/** A second export of the accessor's name, or a context holding auth vocabulary, in one file. */\nexport function secondAuthAccessors(\n path: string,\n code: string,\n facts: Pick<ClientAuthBoundaryFacts, 'accessor' | 'authContextVocabulary' | 'boundaryModules'>,\n): Array<{ index: number; detail: string }> {\n const out: Array<{ index: number; detail: string }> = [];\n const name = escapeRegExp(facts.accessor.name);\n if (path !== facts.accessor.file) {\n const exported =\n new RegExp(`\\\\bexport\\\\s+function\\\\s+${name}\\\\s*[(<]`).exec(code) ??\n new RegExp(`\\\\bexport\\\\s+(?:const|let|var)\\\\s+${name}\\\\b`).exec(code) ??\n new RegExp(`\\\\bexport\\\\s*\\\\{[^}]*\\\\b${name}\\\\b[^}]*\\\\}`).exec(code);\n if (exported) out.push({ index: exported.index, detail: `a second export of ${facts.accessor.name}` });\n }\n if (!facts.boundaryModules.some((m) => m.path === path)) {\n const vocabulary = new RegExp(`\\\\b(?:${facts.authContextVocabulary.map(escapeRegExp).join('|')})\\\\b`);\n if (vocabulary.test(code)) {\n for (const m of code.matchAll(/\\bcreateContext\\s*[<(]/g)) out.push({ index: m.index!, detail: 'a second auth context' });\n }\n }\n return out;\n}\n\nexport const clientAuthBoundaryGuard: GenericGuardDefinition<ClientAuthBoundaryFacts> = {\n id: 'clientAuthBoundary',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n reviewedProblems(facts?.boundaryModules, 'boundaryModules', problems);\n if (objectProblem(facts?.accessor, 'accessor', problems)) {\n textProblem(facts.accessor.file, 'accessor.file', problems);\n textProblem(facts.accessor.name, 'accessor.name', problems);\n if (Array.isArray(facts.boundaryModules) && !facts.boundaryModules.some((m) => m?.path === facts.accessor.file)) {\n problems.push(`the accessor ${facts.accessor.file} is not one of the boundaryModules`);\n }\n }\n namesProblem(facts?.derivationSymbols, 'derivationSymbols', problems);\n namesProblem(facts?.authSourceModules, 'authSourceModules', problems);\n namesProblem(facts?.authContextVocabulary, 'authContextVocabulary', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'the client has one auth boundary',\n description:\n `Identity, claims, and auth loading state come from one provider, read through \\`${facts.accessor.name}\\` ` +\n `(${facts.accessor.file}). Outside the boundary modules nothing imports, reaches, or calls ` +\n `${facts.derivationSymbols.join(', ')}; no other module exports \\`${facts.accessor.name}\\` or creates a ` +\n 'context holding auth state. Read the accessor.',\n run(context) {\n const findings: Finding[] = [];\n for (const file of context.files(APP_CODE)) {\n const inBoundary = facts.boundaryModules.some((m) => m.path === file.path);\n const hits = [\n ...(inBoundary ? [] : boundaryDerivations(file, facts)),\n ...secondAuthAccessors(file.path, file.code, facts),\n ];\n for (const hit of hits) findings.push({ file: file.path, line: file.lineOf(hit.index), detail: hit.detail });\n }\n for (const module of facts.boundaryModules) {\n if (!context.reader.exists(module.path)) findings.push({ file: module.path, detail: 'stale boundary module: it no longer exists' });\n }\n if (context.reader.exists(facts.accessor.file)) {\n const code = context.file(facts.accessor.file).code;\n if (!new RegExp(`\\\\bexport\\\\s+(?:function|const)\\\\s+${escapeRegExp(facts.accessor.name)}\\\\b`).test(code)) {\n findings.push({ file: facts.accessor.file, detail: `the accessor no longer exports ${facts.accessor.name}` });\n }\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Banned auth calls: a call the auth surfaces must never make.\n\nexport interface BannedAuthCallFacts {\n /** The folders and files that make up the auth surfaces. */\n surfaces: readonly string[];\n /** Each banned call and why it is banned. */\n banned: ReadonlyArray<{ name: string; why: string }>;\n /** A long-lived auth surface the scan must reach. */\n anchor: string;\n}\n\nexport const bannedAuthCallGuard: GenericGuardDefinition<BannedAuthCallFacts> = {\n id: 'bannedAuthCalls',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.surfaces, 'surfaces', problems);\n if (!Array.isArray(facts?.banned) || !facts.banned.length) problems.push('banned is missing or empty');\n else for (const b of facts.banned) {\n textProblem(b?.name, 'a banned call', problems);\n textProblem(b?.why, `banned call ${String(b?.name)}'s why`, problems);\n }\n textProblem(facts?.anchor, 'anchor', problems);\n if (typeof facts?.anchor === 'string' && Array.isArray(facts?.surfaces) && !facts.surfaces.some((s) => isUnder(facts.anchor, s))) {\n problems.push(`the anchor ${facts.anchor} is not inside any surface`);\n }\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'the auth surfaces never name a banned auth call',\n description:\n `No file under ${facts.surfaces.join(', ')} imports or calls ` +\n facts.banned.map((b) => `\\`${b.name}\\` (${b.why})`).join('; ') +\n '. The symbol must not be reachable from these modules at all.',\n run(context) {\n const findings: Finding[] = [];\n const files = context.files(APP_CODE).filter((f) => facts.surfaces.some((s) => isUnder(f.path, s)));\n if (!files.some((f) => f.path === facts.anchor)) findings.push({ file: facts.anchor, detail: 'the anchor surface was not reached (gone, or outside the surfaces)' });\n for (const file of files) {\n for (const { name, why } of facts.banned) {\n const re = new RegExp(`\\\\b${escapeRegExp(name)}\\\\b`, 'g');\n for (let m = re.exec(file.code); m; m = re.exec(file.code)) {\n findings.push({ file: file.path, line: file.lineOf(m.index), detail: `names ${name}: ${why}` });\n }\n }\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Auth failure capture: every source calling a Firebase Auth operation that can fail reports it.\n\nexport interface AuthFailureCaptureFacts {\n /** The function every auth failure is reported through. */\n reporter: string;\n /** Sources that leave the report to the code that catches their failure, each with why and the file that reports it. */\n reportedElsewhere: ReadonlyArray<{ path: string; why: string; reportedBy: string }>;\n}\n\n/** The Firebase Auth operations that reach the service and can fail. */\nconst FAILING_AUTH_OPERATION =\n /^(?:createUserWithEmailAndPassword|signInWith\\w+|signOut|sendPasswordResetEmail|confirmPasswordReset|verifyPasswordResetCode|checkActionCode|applyActionCode|sendEmailVerification|reauthenticateWith\\w+|updatePassword|updateEmail|verifyBeforeUpdateEmail|linkWith\\w+|deleteUser)$/;\n\n/** The failing operations a source imports as values from the Firebase Auth SDK. */\nexport function failingAuthImports(file: FileView): string[] {\n const names: string[] = [];\n for (const site of moduleImports(file.sourceFile, ['import'])) {\n if (site.typeOnly || site.spec !== 'firebase/auth') continue;\n for (const { imported, typeOnly } of site.named) if (!typeOnly && FAILING_AUTH_OPERATION.test(imported)) names.push(imported);\n }\n return names;\n}\n\nexport const authFailureCaptureGuard: GenericGuardDefinition<AuthFailureCaptureFacts> = {\n id: 'authFailureCapture',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.reporter, 'reporter', problems);\n reviewedProblems(facts?.reportedElsewhere, 'reportedElsewhere', problems);\n for (const e of Array.isArray(facts?.reportedElsewhere) ? facts.reportedElsewhere : []) {\n if (e && (typeof e.reportedBy !== 'string' || !e.reportedBy.trim())) {\n problems.push(`reportedElsewhere entry ${e.path} names no reportedBy file (the file that reports its failures)`);\n }\n }\n return problems;\n },\n build(facts) {\n const reports = new RegExp(`\\\\b${escapeRegExp(facts.reporter)}\\\\s*\\\\(`);\n return [\n {\n title: 'every Firebase Auth failure reaches monitoring',\n description:\n `A source that calls a Firebase Auth operation that can fail reports its failure through \\`${facts.reporter}\\`; ` +\n 'a catch that only shows a message leaves a broken sign-up or sign-in invisible to monitoring. A source that ' +\n 'never catches the failure itself is a reviewed entry naming who reports for it; an entry that no longer calls ' +\n 'a failing operation, now reports itself, or whose reporter no longer reports is stale.',\n run(context) {\n const findings: Finding[] = [];\n const callers = context.files(APP_CODE).map((f) => ({ file: f, ops: failingAuthImports(f) })).filter((c) => c.ops.length);\n if (!callers.length) findings.push({ file: '(app)', detail: 'no source imports a failing Firebase Auth operation — the scan found no auth surface' });\n const reviewed = new Map(facts.reportedElsewhere.map((e) => [e.path, e]));\n for (const { file, ops } of callers) {\n if (!reports.test(file.code) && !reviewed.has(file.path)) findings.push({ file: file.path, detail: `calls ${ops.join(', ')} and never reports a failure` });\n }\n for (const entry of facts.reportedElsewhere) {\n const caller = callers.find((c) => c.file.path === entry.path);\n if (!caller) findings.push({ file: entry.path, detail: 'stale entry: it no longer calls a failing auth operation' });\n else if (reports.test(caller.file.code)) findings.push({ file: entry.path, detail: 'stale entry: it reports its own failures now' });\n if (!context.reader.exists(entry.reportedBy)) findings.push({ file: entry.reportedBy, detail: `the reporter named for ${entry.path} no longer exists` });\n else if (!reports.test(context.file(entry.reportedBy).code)) findings.push({ file: entry.reportedBy, detail: `the reporter named for ${entry.path} no longer reports` });\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Sign-out liveness: the \"still signed in\" check has one owner.\n\nexport interface SignOutLivenessFacts {\n /** The module that owns the liveness check. */\n owner: string;\n /** The names the owner exports for it. */\n ownerExports: readonly string[];\n /** The function that returns the client auth instance. */\n authAccessor: string;\n}\n\nexport const signOutLivenessGuard: GenericGuardDefinition<SignOutLivenessFacts> = {\n id: 'signOutLiveness',\n absentWhen: 'the app has no signed-in users',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.owner, 'owner', problems);\n namesProblem(facts?.ownerExports, 'ownerExports', problems);\n textProblem(facts?.authAccessor, 'authAccessor', problems);\n return problems;\n },\n build(facts) {\n const redeclared = new RegExp(`\\\\b${DECLARATION_KEYWORDS}\\\\s+(?:${facts.ownerExports.map(escapeRegExp).join('|')})\\\\b`, 'g');\n const negatedSkip = new RegExp(`!\\\\s*${escapeRegExp(facts.authAccessor)}\\\\(\\\\)\\\\s*\\\\??\\\\.\\\\s*currentUser`, 'g');\n return [\n {\n title: 'the signed-in check before an awaited call has one owner',\n description:\n `A check that the user is still signed in, made across an awaited hop before a call, is ${facts.owner}'s ` +\n `(${facts.ownerExports.join(', ')}). Nothing else re-declares those names or hand-rolls a negated ` +\n `\\`${facts.authAccessor}().currentUser\\` skip guard: import the owner.`,\n run(context) {\n const findings: Finding[] = [];\n for (const file of context.files(APP_CODE)) {\n if (file.path === facts.owner) continue;\n for (const re of [redeclared, negatedSkip]) {\n re.lastIndex = 0;\n for (let m = re.exec(file.code); m; m = re.exec(file.code)) {\n findings.push({ file: file.path, line: file.lineOf(m.index), detail: re === redeclared ? `re-declares ${m[0].split(/\\s+/).pop()}` : 'hand-rolls a negated currentUser skip guard' });\n }\n }\n }\n if (!context.reader.exists(facts.owner)) findings.push({ file: facts.owner, detail: 'the owner no longer exists' });\n else {\n const code = context.file(facts.owner).code;\n for (const name of facts.ownerExports) if (!declares(code, name)) findings.push({ file: facts.owner, detail: `the owner no longer declares ${name}` });\n }\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// Editor permission gate: an editor holding typed input is never mounted under a permission read.\n\nexport interface EditorPermissionGateFacts {\n /** The hook an editor calls to guard its unsaved input: a file calling it holds an editor. */\n editorMarker: string;\n /** The element the editor mounts in. */\n editorElement: string;\n /** Permission reads: identifiers starting with this prefix and a capital letter. */\n permissionNamePrefix: string;\n /** Permission reads: calls to these functions (declare [] when none). */\n permissionCalls: readonly string[];\n}\n\n/** Each editor element with an ancestor `{<permission read> && …}`. */\nexport function permissionGatedEditors(sf: ts.SourceFile, facts: Omit<EditorPermissionGateFacts, 'editorMarker'>): ts.Node[] {\n const prefix = new RegExp(`^${escapeRegExp(facts.permissionNamePrefix)}[A-Z]`);\n const readsPermission = (expr: ts.Expression) => {\n let found = false;\n const visit = (node: ts.Node) => {\n if (ts.isIdentifier(node) && prefix.test(node.text)) found = true;\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && facts.permissionCalls.includes(node.expression.text)) found = true;\n ts.forEachChild(node, visit);\n };\n visit(expr);\n return found;\n };\n const out: ts.Node[] = [];\n const visit = (node: ts.Node) => {\n if ((ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) && node.tagName.getText(sf) === facts.editorElement) {\n for (let p: ts.Node | undefined = node.parent; p; p = p.parent) {\n if (\n ts.isJsxExpression(p) &&\n p.expression &&\n ts.isBinaryExpression(p.expression) &&\n p.expression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken &&\n readsPermission(p.expression.left)\n ) {\n out.push(node);\n break;\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return out;\n}\n\nexport const editorPermissionGateGuard: GenericGuardDefinition<EditorPermissionGateFacts> = {\n id: 'editorPermissionGate',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.editorMarker, 'editorMarker', problems);\n textProblem(facts?.editorElement, 'editorElement', problems);\n textProblem(facts?.permissionNamePrefix, 'permissionNamePrefix', problems);\n namesProblem(facts?.permissionCalls, 'permissionCalls', problems, { nonEmpty: false });\n return problems;\n },\n build(facts): Guard[] {\n return [\n {\n title: 'an editor holding typed input is never mounted under a permission gate',\n description:\n `A component that guards its unsaved input (\\`${facts.editorMarker}\\`) gates only the control that opens its ` +\n `editor on a permission; its \\`<${facts.editorElement}>\\` stays mounted, so a permission read that changes or ` +\n 'fails while it is open can never unmount it and drop what was typed. Gate the trigger, and key the editor to ' +\n 'the account that opened it.',\n run(context) {\n const findings: Finding[] = [];\n const marker = new RegExp(`\\\\b${escapeRegExp(facts.editorMarker)}\\\\s*\\\\(`);\n const editors = context.files(APP_CODE).filter((f) => marker.test(f.code));\n if (!editors.length) findings.push({ file: '(app)', detail: `no component calls ${facts.editorMarker} — the scan found no editor to check` });\n for (const file of editors) {\n for (const node of permissionGatedEditors(file.sourceFile, facts)) {\n findings.push({ file: file.path, line: file.lineOf(node.getStart(file.sourceFile)), detail: `<${facts.editorElement}> mounted under a permission gate` });\n }\n }\n return findings;\n },\n },\n ];\n },\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/modules/frontend-reads/cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/modules/frontend-reads/cache.ts"],"names":[],"mappings":"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"}
@@ -467,7 +467,11 @@ export const domainEventRegistryGuard = {
467
467
  description: `Every variant of the core's domain-event schema has an entry in the registry in ${facts.registry.path}, and the entry answers, ` +
468
468
  'for every shape of its ids (each optional id present and absent), a list of invalidations that are each an exact or prefix ' +
469
469
  'target with a non-empty key, or a predicate with a description and a matcher.',
470
- async run() {
470
+ async run(context) {
471
+ // The loaded registry is judged, but the file the facts name must be the one it comes from.
472
+ if (!context.reader.exists(facts.registry.path))
473
+ return [{ file: facts.registry.path, detail: 'the registry file does not exist' }];
474
+ context.file(facts.registry.path);
471
475
  const registry = (await facts.registry.load()) ?? {};
472
476
  const schema = (await facts.eventSchema());
473
477
  const variants = (schema?.options ?? []);
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/modules/frontend-reads/cache.ts"],"names":[],"mappings":"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","sourcesContent":["// What may touch the query cache, and how: invalidation only through the domain-event registry,\n// aimed at keys a live query reads and never at an infinite list; an infinite list never reloaded\n// by an action; a whole-cache drop only by the session-retirement owner; and a registry whose every\n// event is produced, well formed, and awaited.\n\nimport ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../config.js';\nimport type { Finding, Guard, GuardContext } from '../../guard.js';\nimport type { FileView } from '../../reader/view.js';\nimport { identifierProblem, loaderProblem, pathProblem, reviewedProblems, type Loader } from '../../support/facts.js';\nimport { escapeRegExp } from '../../support/text.js';\nimport {\n APP_CODE,\n alternation,\n callSpan,\n collapse,\n familyOf,\n filesUnder,\n identifierListProblem,\n infiniteKeyFamilies,\n isPrefix,\n keyModuleProblem,\n loadKeyObjects,\n pathListProblem,\n reachesInfinite,\n requiredFile,\n reviewedCallProblem,\n sampleKey,\n type KeyBuilders,\n type KeyModuleFacts,\n type ReviewedCall,\n} from './shared.js';\n\n/** query-core's registry factory and the two invalidation builders a registry entry uses. */\nconst REGISTRY_FACTORY = 'createDomainEventInvalidator';\nconst EXACT = 'exact';\n\n/** The registry: where it is. */\nexport interface RegistryFacts {\n path: string;\n}\n\n/** The object literal the registry module hands to query-core's registry factory, as code. */\nexport function registryObjectCode(file: FileView): { name: string; code: string } | null {\n const sf = file.sourceFile;\n let name: string | null = null;\n const find = (node: ts.Node) => {\n if (!name && ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === REGISTRY_FACTORY && node.arguments[0] && ts.isIdentifier(node.arguments[0])) {\n name = node.arguments[0].text;\n }\n ts.forEachChild(node, find);\n };\n find(sf);\n if (!name) return null;\n let found: { name: string; code: string } | null = null;\n const visit = (node: ts.Node) => {\n if (!found && ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === name && node.initializer) {\n found = { name: name!, code: file.code.slice(node.initializer.getStart(sf), node.initializer.getEnd()) };\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\nconst keyRefPattern = (objects: readonly string[]) => new RegExp(`\\\\b(${alternation(objects)})\\\\.(\\\\w+)`, 'g');\n\n// =============================================================================================\n// Cache invalidation only through the registry; the registry's targets are read, and never an infinite list.\n// =============================================================================================\n\nexport interface CacheInvalidationFacts {\n registry: RegistryFacts;\n keyModule: KeyModuleFacts;\n /** The trees whose `queryKey:` sites are the app's live reads (hooks, components, pages). */\n readTrees: readonly string[];\n /** The suffix the key module names a family helper with (`listPrefix()` → `Prefix`). */\n familySuffix: string;\n}\n\n/** What the registry rule leaves to the other cache owners: the session-retirement owner, and a person's own refreshes. */\ninterface OwnedElsewhere {\n sessionOwner: string;\n memberRefreshes: readonly ReviewedCall[];\n}\n\nconst CLEAR_CALL = /\\.\\s*(invalidateQueries|removeQueries|resetQueries)(\\s*\\()/g;\nconst CACHE_WRITE_CALL =\n /\\b(refetchQueries|resetQueries|cancelQueries|setQueryData|setQueriesData|getQueryData|getQueriesData|invalidateQueries|removeQueries|ensureQueryData|prefetchQuery)\\b/;\n\n/** Every invalidate / remove / reset call in a file, as its collapsed text from the method name on. */\nexport function clearCalls(file: FileView): Array<{ index: number; call: string }> {\n return [...file.code.matchAll(CLEAR_CALL)].map((m) => {\n const name = (m.index ?? 0) + m[0].indexOf(m[1]);\n const open = (m.index ?? 0) + m[0].length - 1;\n return { index: name, call: collapse(callSpan(file.code, name, open)) };\n });\n}\n\n/** Key families some live query reads: a `queryKey` built from a key method outside a cache call, or a key object handed whole. */\nexport function readKeyFamilies(files: ReadonlyArray<{ code: string }>, objects: readonly string[], familySuffix: string): Set<string> {\n const read = new Set<string>();\n const names = alternation(objects);\n for (const { code } of files) {\n for (const line of code.split('\\n')) {\n if (CACHE_WRITE_CALL.test(line)) continue;\n for (const m of line.matchAll(new RegExp(`\\\\bqueryKey\\\\s*[:=]\\\\s*(${names})\\\\.(\\\\w+)`, 'g'))) read.add(familyOf(`${m[1]}.${m[2]}`, familySuffix));\n for (const m of line.matchAll(new RegExp(`[\\\\w$]+\\\\s*:\\\\s*(${names})\\\\b(?![\\\\w$]|\\\\s*\\\\.)`, 'g'))) read.add(`${m[1]}.*`);\n }\n }\n return read;\n}\n\n/** The argument count of the call whose `(` is at `open`, or null when there is no call there. */\nfunction argCountAt(code: string, open: number): number | null {\n if (code[open] !== '(') return null;\n let depth = 0;\n let count = 0;\n let sawToken = false;\n for (let i = open; i < code.length; i += 1) {\n const ch = code[i];\n if ('([{'.includes(ch)) {\n depth += 1;\n if (depth > 1) sawToken = true;\n } else if (')]}'.includes(ch)) {\n depth -= 1;\n if (depth === 0) return sawToken ? count + 1 : 0;\n } else if (ch === ',' && depth === 1) count += 1;\n else if (depth >= 1 && !/\\s/.test(ch)) sawToken = true;\n }\n return null;\n}\n\n/** Each key method → the argument counts the app's live reads build it with. */\nexport function readArgCounts(files: ReadonlyArray<{ code: string }>, objects: readonly string[]): Map<string, Set<number>> {\n const counts = new Map<string, Set<number>>();\n const re = new RegExp(`\\\\bqueryKey\\\\s*[:=]\\\\s*(${alternation(objects)})\\\\.(\\\\w+)\\\\(`, 'g');\n for (const { code } of files) {\n for (const line of code.split('\\n')) {\n if (CACHE_WRITE_CALL.test(line)) continue;\n for (const m of line.matchAll(re)) {\n const n = argCountAt(line, (m.index ?? 0) + m[0].length - 1);\n if (n === null) continue;\n const ref = `${m[1]}.${m[2]}`;\n counts.set(ref, (counts.get(ref) ?? new Set()).add(n));\n }\n }\n }\n return counts;\n}\n\n/** Registry targets that miss: unread, an exact on a family, an exact shaped unlike every read, or one reaching an infinite list. */\nexport function registryTargetProblems(input: {\n registryCode: string;\n reads: ReadonlyArray<{ code: string }>;\n builders: KeyBuilders;\n familySuffix: string;\n}): string[] {\n const { registryCode, reads, builders, familySuffix } = input;\n const objects = Object.keys(builders);\n const refs = [...new Set([...registryCode.matchAll(keyRefPattern(objects))].map((m) => `${m[1]}.${m[2]}`))];\n const read = readKeyFamilies(reads, objects, familySuffix);\n const readKeys = [...read].map((f) => sampleKey(f, builders)).filter((k): k is unknown[] => k !== null);\n const problems: string[] = [];\n for (const ref of refs) {\n if (read.has(familyOf(ref, familySuffix)) || read.has(`${ref.split('.')[0]}.*`)) continue;\n const key = sampleKey(ref, builders);\n if (key === null || !readKeys.some((readKey) => isPrefix(key, readKey))) problems.push(`${ref}: no live query reads this key`);\n }\n const counts = readArgCounts(reads, objects);\n const exactRe = new RegExp(`\\\\b${EXACT}\\\\(\\\\s*(${alternation(objects)})\\\\.(\\\\w+)`, 'g');\n const shaped = new Set<string>();\n for (const m of registryCode.matchAll(exactRe)) {\n const ref = `${m[1]}.${m[2]}`;\n if (shaped.has(ref)) continue;\n if (m[2] === 'all' || (m[2].endsWith(familySuffix) && m[2] !== familySuffix)) {\n shaped.add(ref);\n problems.push(`${ref}: an exact target on a key family (only a prefix target reaches a family)`);\n continue;\n }\n const n = argCountAt(registryCode, (m.index ?? 0) + m[0].length);\n const readCounts = counts.get(ref);\n if (n !== null && readCounts && !readCounts.has(n)) {\n shaped.add(ref);\n problems.push(`${ref}: an exact target built with ${n} argument(s), which no live read builds`);\n }\n }\n const infinite = infiniteKeyFamilies(reads, objects, familySuffix);\n for (const ref of refs) if (reachesInfinite(ref, infinite, builders, familySuffix)) problems.push(`${ref}: reaches an infinite list`);\n return problems;\n}\n\nfunction registryProblem(value: unknown, problems: string[]): void {\n const facts = value as RegistryFacts | undefined;\n if (!facts || typeof facts !== 'object') problems.push('registry is missing');\n else pathProblem(facts.path, 'registry.path', problems);\n}\n\nconst cacheInvalidationProblems = (facts: CacheInvalidationFacts) => {\n const problems: string[] = [];\n registryProblem(facts?.registry, problems);\n keyModuleProblem(facts?.keyModule, problems);\n pathListProblem(facts?.readTrees, 'readTrees', problems);\n identifierProblem(facts?.familySuffix, 'familySuffix', problems);\n return problems;\n};\n\nconst cacheInvalidationGuards = (facts: CacheInvalidationFacts, owned: OwnedElsewhere): Guard[] => [\n {\n title: 'saved reads are refreshed, removed, or reset only through the domain-event registry',\n description:\n `${facts.registry.path} — the object it hands to query-core's ${REGISTRY_FACTORY} — is the one place that turns something that ` +\n 'happened into what the cache does: refresh, remove, or reset. No other file calls invalidateQueries, removeQueries, or ' +\n 'resetQueries: emit the domain event instead, and patch an infinite list in place. The only other owners are the session-' +\n `retirement owner (${owned.sessionOwner}) and a person's own refresh, declared once beside the list-reload rule.`,\n run(context) {\n const { file: registry, findings } = requiredFile(context, facts.registry.path, 'the domain-event registry');\n if (registry && !registryObjectCode(registry)) findings.push({ file: registry.path, detail: `no registry object handed to ${REGISTRY_FACTORY}` });\n const refreshes = new Set(owned.memberRefreshes.map((r) => `${r.path} ${r.call}`));\n for (const file of context.files(APP_CODE)) {\n if (file.path === facts.registry.path || file.path === owned.sessionOwner) continue;\n for (const { index, call } of clearCalls(file)) {\n if (refreshes.has(`${file.path} ${call}`)) continue;\n findings.push({ file: file.path, line: file.lineOf(index), detail: `outside the registry: ${call.slice(0, 120)}` });\n }\n }\n return findings;\n },\n },\n {\n title: 'every registry cache target is a key a live query reads, and never an infinite list',\n description:\n `Every key the registry in ${facts.registry.path} writes is reached by a live query's key (a queryKey built from the same key ` +\n `method in ${facts.readTrees.join(', ')}, or a key object handed whole to a reader); an exact target names a leaf the reads build ` +\n `with the same arguments, never a family (all, or a …${facts.familySuffix} helper); and no target reaches an infinite list — named, ` +\n \"through its family helper, or through its scope. A write aimed at a key nothing reads is a silent no-op, and invalidating an \" +\n 'infinite list re-runs every loaded page.',\n timeoutMs: 120_000,\n async run(context: GuardContext): Promise<Finding[]> {\n const { file: registry, findings } = requiredFile(context, facts.registry.path, 'the domain-event registry');\n if (!registry) return findings;\n const object = registryObjectCode(registry);\n if (!object) return [{ file: registry.path, detail: `no registry object handed to ${REGISTRY_FACTORY}` }];\n const builders = await loadKeyObjects(facts.keyModule);\n const { files, findings: missing } = filesUnder(context, facts.readTrees);\n findings.push(...missing);\n for (const detail of registryTargetProblems({ registryCode: object.code, reads: files, builders, familySuffix: facts.familySuffix })) {\n findings.push({ file: registry.path, detail });\n }\n return findings;\n },\n },\n];\n\n// =============================================================================================\n// No action-driven reload of an infinite list.\n// =============================================================================================\n\nexport interface ListResetFacts {\n keyModule: KeyModuleFacts;\n familySuffix: string;\n /** The app predicate that is true for a query holding loaded pages; a reload filtered by its negation reloads no shown list. */\n loadedPagesPredicate: string;\n /** A person's own refreshes (pull-to-refresh, a Refresh button): each call site with its why. */\n memberRefreshes: readonly ReviewedCall[];\n /** Hooks that run a member's own refresh, each handed only to its refresh control on the named prop; [] for none. */\n refreshHandoffs: ReadonlyArray<{ hook: string; control: string; prop: string }>;\n}\n\nconst RELOAD_CALL = /\\b(resetQueries|refetchQueries|removeQueries)\\s*\\(/g;\nconst PATCH_CALL = /\\b(setQueryData|setQueriesData)\\s*(?:<[^>]*>)?\\s*\\(/g;\nconst FIRST_PAGE_TRIM = /\\bpages\\.slice\\(\\s*0\\s*,\\s*1\\s*\\)|\\bpageParams\\.slice\\(\\s*0\\s*,\\s*1\\s*\\)|\\bpages\\s*:\\s*\\[\\s*[\\w.?]+\\.pages\\[0\\]\\s*\\]/;\n\n/** The key refs a call targets: its key method, or every one a constant map it indexes holds; null when unresolved. */\nfunction targetRefs(call: string, code: string, objects: readonly string[]): string[] | null {\n const names = alternation(objects);\n const direct = call.match(new RegExp(`\\\\bqueryKey\\\\s*:\\\\s*(${names})\\\\.(\\\\w+)`));\n if (direct) return [`${direct[1]}.${direct[2]}`];\n const indexed = call.match(/\\bqueryKey\\s*:\\s*([A-Za-z_]\\w*)\\[/);\n if (!indexed) return null;\n const decl = code.match(new RegExp(`\\\\bconst \\\\s*${escapeRegExp(indexed[1])}\\\\b[^=]*=\\\\s*\\\\{`));\n if (!decl) return null;\n const open = (decl.index ?? 0) + decl[0].length - 1;\n const refs = [...callSpan(code, open, open).matchAll(keyRefPattern(objects))].map((m) => `${m[1]}.${m[2]}`);\n return refs.length ? refs : null;\n}\n\n/** Every call that reloads or trims an infinite list, outside the reviewed reloads. */\nexport function listReloads(\n files: readonly FileView[],\n builders: KeyBuilders,\n facts: Pick<ListResetFacts, 'familySuffix' | 'loadedPagesPredicate' | 'memberRefreshes'>,\n sessionOwner?: string,\n) {\n const objects = Object.keys(builders);\n const infinite = infiniteKeyFamilies(files, objects, facts.familySuffix);\n const pinned = new Set(facts.memberRefreshes.map((r) => `${r.path} ${r.call}`));\n const excluded = new RegExp(`!${escapeRegExp(facts.loadedPagesPredicate)}\\\\(\\\\s*query\\\\s*\\\\)`);\n const found: Finding[] = [];\n const present = new Set<string>();\n for (const file of files) {\n if (file.path === sessionOwner) continue;\n const code = file.code;\n for (const m of code.matchAll(RELOAD_CALL)) {\n const call = collapse(callSpan(code, m.index ?? 0, (m.index ?? 0) + m[0].length - 1));\n present.add(`${file.path} ${call}`);\n if (pinned.has(`${file.path} ${call}`)) continue;\n const refs = targetRefs(call, code, objects);\n const reloads = refs ? refs.some((ref) => reachesInfinite(ref, infinite, builders, facts.familySuffix)) : !excluded.test(call);\n if (reloads) found.push({ file: file.path, line: file.lineOf(m.index ?? 0), detail: `${refs ? 'reloads an infinite list' : 'reloads queries its key does not name'}: ${call.slice(0, 120)}` });\n }\n for (const m of code.matchAll(PATCH_CALL)) {\n const call = callSpan(code, m.index ?? 0, (m.index ?? 0) + m[0].length - 1);\n if (FIRST_PAGE_TRIM.test(call)) found.push({ file: file.path, line: file.lineOf(m.index ?? 0), detail: `trims a list to its first page: ${collapse(call).slice(0, 120)}` });\n }\n }\n for (const r of facts.memberRefreshes) if (!present.has(`${r.path} ${r.call}`)) found.push({ file: r.path, detail: `stale member refresh: ${r.call} is no longer there` });\n return { infinite, findings: found };\n}\n\n/** Each refresh hook's result used anywhere but on its refresh control's prop, and each hook no file calls. */\nexport function refreshHandoffMisuses(files: readonly FileView[], handoffs: ListResetFacts['refreshHandoffs']): Finding[] {\n const findings: Finding[] = [];\n for (const { hook, control, prop } of handoffs) {\n let callers = 0;\n for (const file of files) {\n for (const m of file.code.matchAll(new RegExp(`const\\\\s+(\\\\w+)\\\\s*=\\\\s*${escapeRegExp(hook)}\\\\(`, 'g'))) {\n callers += 1;\n const name = m[1];\n const uses = [...file.code.matchAll(new RegExp(`\\\\b${name}\\\\b`, 'g'))].length - 1;\n const handed = [...file.code.matchAll(new RegExp(`<${escapeRegExp(control)}[^>]*${escapeRegExp(prop)}=\\\\{${name}\\\\}`, 'g'))].length;\n if (uses !== handed) findings.push({ file: file.path, line: file.lineOf(m.index ?? 0), detail: `${hook}()'s refresh is used other than as <${control} ${prop}>` });\n }\n }\n if (!callers) findings.push({ file: '(refreshHandoffs)', detail: `stale entry: nothing calls ${hook}` });\n }\n return findings;\n}\n\nconst listResetProblems = (facts: ListResetFacts) => {\n const problems: string[] = [];\n keyModuleProblem(facts?.keyModule, problems);\n identifierProblem(facts?.familySuffix, 'familySuffix', problems);\n identifierProblem(facts?.loadedPagesPredicate, 'loadedPagesPredicate', problems);\n reviewedCallProblem(facts?.memberRefreshes, 'memberRefreshes', problems);\n if (!Array.isArray(facts?.refreshHandoffs)) problems.push('refreshHandoffs is missing (declare [] when there is none)');\n else\n facts.refreshHandoffs.forEach((h, i) => {\n identifierProblem(h?.hook, `refreshHandoffs[${i}].hook`, problems);\n identifierProblem(h?.control, `refreshHandoffs[${i}].control`, problems);\n identifierProblem(h?.prop, `refreshHandoffs[${i}].prop`, problems);\n });\n return problems;\n};\n\nconst listResetGuards = (facts: ListResetFacts, sessionOwner: string): Guard[] => [\n {\n title: 'an action never reloads an infinite list',\n description:\n \"An action's change is placed, moved, or patched in place in an infinite list; no resetQueries / refetchQueries / removeQueries \" +\n `whose key reaches one (directly, through its family helper or scope, or through a constant map of keys), none whose key cannot ` +\n `be resolved unless its predicate excludes every query holding loaded pages (!${facts.loadedPagesPredicate}(query)), and no cache ` +\n \"write that trims a list to its first page. A person's own refresh is declared with its why, and a refresh hook's result is only \" +\n 'ever handed to its refresh control.',\n timeoutMs: 120_000,\n async run(context) {\n const builders = await loadKeyObjects(facts.keyModule);\n const files = context.files(APP_CODE);\n const { infinite, findings } = listReloads(files, builders, facts, sessionOwner);\n if (!infinite.size) findings.push({ file: facts.keyModule.path, detail: 'no infinite list found in the app, so the guard checks nothing' });\n findings.push(...refreshHandoffMisuses(files, facts.refreshHandoffs));\n return findings;\n },\n },\n];\n\n// =============================================================================================\n// An unscoped cancel or a whole-cache clear only by session retirement.\n// =============================================================================================\n\nexport interface SessionRetirementFacts {\n /** The session-retirement owner. */\n owner: string;\n /** Retirements beyond a session's end that the owner runs by predicate (a member leaving a group), each with its why; [] for none. */\n predicateRetirements: ReadonlyArray<{ trigger: string; why: string }>;\n}\n\nconst WHOLE_CACHE_DROP = [\n /\\bcancelQueries\\(\\s*\\)/g,\n /\\bcancelQueries\\(\\s*undefined\\b/g,\n /\\bcancelQueries\\(\\s*\\{(?![^}]*\\bqueryKey\\b)/g,\n /\\bget(?:Query|Mutation)Cache\\(\\)\\s*\\.clear\\(/g,\n /\\b\\w*[cC]lient\\s*\\.clear\\(\\s*\\)/g,\n];\n\nexport function wholeCacheDrops(file: FileView): Array<{ index: number; text: string }> {\n return WHOLE_CACHE_DROP.flatMap((re) => [...file.code.matchAll(re)].map((m) => ({ index: m.index ?? 0, text: m[0] }))).sort((a, b) => a.index - b.index);\n}\n\nconst sessionRetirementPart = {\n factProblems(facts: SessionRetirementFacts) {\n const problems: string[] = [];\n pathProblem(facts?.owner, 'owner', problems);\n reviewedProblems(facts?.predicateRetirements, 'predicateRetirements', problems, { key: 'trigger' });\n return problems;\n },\n build: (facts: SessionRetirementFacts): Guard[] => [\n {\n title: 'an unscoped cancel or a whole-cache clear runs only in the session-retirement owner',\n description:\n `A cancelQueries with no key (bare, or selected by a predicate) and a query or mutation cache clear drop reads the call site ` +\n `cannot name, so only ${facts.owner} runs them: when a session ends it cancels every query and clears the query cache` +\n (facts.predicateRetirements.length ? `, and it cancels by predicate for ${facts.predicateRetirements.map((r) => r.trigger).join('; ')}` : '') +\n '. Everywhere else a cancel names its key, and nothing clears a cache.',\n run(context) {\n const { file: owner, findings } = requiredFile(context, facts.owner, 'the session-retirement owner');\n for (const file of context.files(APP_CODE)) {\n if (file.path === facts.owner) continue;\n for (const drop of wholeCacheDrops(file)) findings.push({ file: file.path, line: file.lineOf(drop.index), detail: `outside the session-retirement owner: ${drop.text}` });\n }\n if (owner) {\n if (!/\\bcancelQueries\\(\\s*\\)/.test(owner.code)) findings.push({ file: owner.path, detail: 'the owner no longer cancels every query when a session ends' });\n if (!/getQueryCache\\(\\)\\s*\\.clear\\(/.test(owner.code)) findings.push({ file: owner.path, detail: 'the owner no longer clears the query cache when a session ends' });\n const byPredicate = [...owner.code.matchAll(/\\bcancelQueries\\(\\s*\\{\\s*predicate\\s*:/g)].length;\n if (byPredicate !== facts.predicateRetirements.length) {\n findings.push({ file: owner.path, detail: `the owner cancels by predicate ${byPredicate} time(s); ${facts.predicateRetirements.length} predicate retirement(s) are reviewed` });\n }\n }\n return findings;\n },\n },\n ],\n};\n\n// =============================================================================================\n// The domain-event registry: every event produced, every variant registered and well formed, every\n// notification handed on.\n// =============================================================================================\n\nexport interface DomainEventRegistryFacts {\n registry: RegistryFacts & {\n /** A loader of the registry object itself (event type → invalidation builder). */\n load: Loader<Record<string, unknown>>;\n };\n /** A loader of the core's domain-event schema: a discriminated union on `type`, each variant carrying an `ids` object. */\n eventSchema: Loader<unknown>;\n /** The app's functions that dispatch a domain event and return the refresh's promise. */\n notifiers: readonly string[];\n}\n\ntype ZodLike = { def?: any; _def?: any; shape?: Record<string, ZodLike>; options?: unknown[]; value?: unknown };\nconst defOf = (field: ZodLike) => field?.def ?? field?._def ?? {};\nconst kindOf = (field: ZodLike): 'optional' | 'nullable' | 'enum' | 'required' => {\n const type = defOf(field).type;\n return type === 'optional' || type === 'nullable' || type === 'enum' ? type : 'required';\n};\n\n/** Synthetic `ids` for one variant: every field filled, then each optional field dropped in turn. */\nexport function syntheticIds(idsSchema: ZodLike): Array<Record<string, unknown>> {\n const baseline: Record<string, unknown> = {};\n const optional: string[] = [];\n for (const [key, field] of Object.entries(idsSchema?.shape ?? {})) {\n const kind = kindOf(field);\n if (kind === 'enum') baseline[key] = (field.options as unknown[])[0];\n else if (kind === 'optional') {\n optional.push(key);\n const inner = defOf(field).innerType as ZodLike;\n baseline[key] = kindOf(inner) === 'enum' ? (inner.options as unknown[])[0] : `test-${key}`;\n } else baseline[key] = `test-${key}`;\n }\n return [{ ...baseline }, ...optional.map((key) => Object.fromEntries(Object.entries(baseline).filter(([k]) => k !== key)))];\n}\n\n/** What a query-core registry entry may do to the reads it matches, and how a refresh refetches. */\nconst CACHE_ACTIONS: ReadonlySet<unknown> = new Set([undefined, 'refresh', 'remove', 'reset']);\nconst REFETCH_TYPES: ReadonlySet<unknown> = new Set([undefined, 'active', 'all', 'none']);\n\n/** Why a builder's answer is not a list of well-formed invalidations, or null. */\nexport function malformedInvalidations(answer: unknown): string | null {\n if (!Array.isArray(answer)) return 'does not answer a list of invalidations';\n for (const inv of answer as Array<Record<string, unknown>>) {\n if (inv?.kind === 'exact' || inv?.kind === 'prefix') {\n if (!Array.isArray(inv.queryKey) || !inv.queryKey.length) return `a ${inv.kind} invalidation with no key`;\n } else if (inv?.kind === 'predicate') {\n if (typeof inv.description !== 'string' || !inv.description || typeof inv.match !== 'function') return 'a predicate invalidation with no description or matcher';\n } else return `an invalidation of unknown kind ${String(inv?.kind)}`;\n if (!CACHE_ACTIONS.has(inv.action)) return `a ${inv.kind} invalidation with unknown action ${String(inv.action)}`;\n if (!REFETCH_TYPES.has(inv.refetchType)) return `a ${inv.kind} invalidation with unknown refetchType ${String(inv.refetchType)}`;\n if ((inv.action === 'remove' || inv.action === 'reset') && inv.refetchType !== undefined) {\n return `a ${inv.action} invalidation with a refetchType, which only a refresh takes`;\n }\n }\n return null;\n}\n\n/** Whether the call at `index` starts a statement, so its promise is dropped. */\nfunction startsStatement(code: string, index: number): boolean {\n const before = code.slice(0, index).trimEnd();\n return before.length === 0 || ';{})'.includes(before.charAt(before.length - 1));\n}\n\nexport function droppedNotifications(file: FileView, notifiers: readonly string[]): Array<{ index: number; name: string }> {\n const hits: Array<{ index: number; name: string }> = [];\n for (const m of file.code.matchAll(new RegExp(`\\\\b(${alternation(notifiers)})\\\\(`, 'g'))) {\n const index = m.index ?? 0;\n if (/function\\s+$/.test(file.code.slice(0, index))) continue;\n if (startsStatement(file.code, index)) hits.push({ index, name: m[1] });\n }\n return hits;\n}\n\nexport const domainEventRegistryGuard: GenericGuardDefinition<DomainEventRegistryFacts> = {\n id: 'domainEventRegistry',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n registryProblem(facts?.registry, problems);\n loaderProblem(facts?.registry?.load, 'registry.load', problems);\n loaderProblem(facts?.eventSchema, 'eventSchema', problems);\n identifierListProblem(facts?.notifiers, 'notifiers', problems, { nonEmpty: true });\n return problems;\n },\n build: (facts) => [\n {\n title: 'every registered domain event has a producer in the app',\n description:\n `Every event type the registry in ${facts.registry.path} handles is emitted somewhere in the app's own code (its quoted type ` +\n \"outside the registry, in the client or functions tree); the core's schema holds every variant by construction, so it is no \" +\n 'evidence. Restore the producer, or delete the event from the core and the registry.',\n async run(context) {\n const registry = (await facts.registry.load()) ?? {};\n const findings: Finding[] = [];\n const haystack = context\n .files({ roots: ['app', 'functions'], optionalRoots: ['functions'], kinds: ['code'], tests: false })\n .filter((f) => f.path !== facts.registry.path)\n .map((f) => f.code)\n .join('\\n');\n const produced = (type: string) => haystack.includes(`'${type}'`) || haystack.includes(`\"${type}\"`);\n for (const type of Object.keys(registry)) if (!produced(type)) findings.push({ file: facts.registry.path, detail: `${type}: no producer in the app` });\n return findings;\n },\n },\n {\n title: \"every core domain-event variant has a registry entry with well-formed invalidations\",\n description:\n `Every variant of the core's domain-event schema has an entry in the registry in ${facts.registry.path}, and the entry answers, ` +\n 'for every shape of its ids (each optional id present and absent), a list of invalidations that are each an exact or prefix ' +\n 'target with a non-empty key, or a predicate with a description and a matcher.',\n async run() {\n const registry = (await facts.registry.load()) ?? {};\n const schema = (await facts.eventSchema()) as ZodLike;\n const variants = (schema?.options ?? []) as ZodLike[];\n if (!variants.length) return [{ file: '(eventSchema)', detail: 'the loader did not answer a discriminated union of variants' }];\n const findings: Finding[] = [];\n for (const variant of variants) {\n const type = String(variant.shape?.type?.value ?? '');\n if (!type) {\n findings.push({ file: '(eventSchema)', detail: 'a variant carries no literal type' });\n continue;\n }\n const build = registry[type];\n if (typeof build !== 'function') {\n findings.push({ file: facts.registry.path, detail: `${type}: no registry entry` });\n continue;\n }\n for (const ids of syntheticIds(variant.shape?.ids as ZodLike)) {\n let problem: string | null;\n try {\n problem = malformedInvalidations((build as (ids: unknown) => unknown)(ids));\n } catch (err) {\n problem = `throws for ids ${JSON.stringify(ids)}: ${(err as Error)?.message ?? err}`;\n }\n if (problem) findings.push({ file: facts.registry.path, detail: `${type}: ${problem}` });\n }\n }\n return findings;\n },\n },\n {\n title: 'every domain-event notification hands its refresh promise on',\n description:\n `A call to ${facts.notifiers.join(' / ')} returns the promise of the refresh it starts; a mutation returns or awaits it so it stays ` +\n 'pending until the refreshed data is on screen. A call in statement position drops it silently: return it, await it, pass it ' +\n 'on, or mark a deliberate fire-and-forget with void.',\n run(context) {\n const findings: Finding[] = [];\n let calls = 0;\n const callRe = new RegExp(`\\\\b(?:${alternation(facts.notifiers)})\\\\(`, 'g');\n for (const file of context.files(APP_CODE)) {\n calls += [...file.code.matchAll(callRe)].length;\n for (const hit of droppedNotifications(file, facts.notifiers)) {\n findings.push({ file: file.path, line: file.lineOf(hit.index), detail: `${hit.name}(…) in statement position drops its refresh` });\n }\n }\n if (!calls) findings.push({ file: '(notifiers)', detail: `nothing in the app calls ${facts.notifiers.join(' / ')}, so the guard checks nothing` });\n return findings;\n },\n },\n ],\n};\n\n/**\n * Every fact the query-cache owners need, declared once: the registry (the one place something that\n * happened changes saved reads), a person's own refreshes, and the session-retirement owner.\n */\nexport interface QueryCacheFacts extends CacheInvalidationFacts {\n loadedPagesPredicate: string;\n memberRefreshes: readonly ReviewedCall[];\n refreshHandoffs: ListResetFacts['refreshHandoffs'];\n sessionOwner: string;\n predicateRetirements: SessionRetirementFacts['predicateRetirements'];\n}\n\nconst listFacts = (f: QueryCacheFacts | undefined): ListResetFacts => ({\n keyModule: f?.keyModule as KeyModuleFacts,\n familySuffix: f?.familySuffix as string,\n loadedPagesPredicate: f?.loadedPagesPredicate as string,\n memberRefreshes: f?.memberRefreshes as readonly ReviewedCall[],\n refreshHandoffs: f?.refreshHandoffs as ListResetFacts['refreshHandoffs'],\n});\n\nexport const queryCacheGuard: GenericGuardDefinition<QueryCacheFacts> = {\n id: 'queryCache',\n absentWhen: false,\n factProblems: (f) => [\n ...new Set([\n ...cacheInvalidationProblems(f),\n ...listResetProblems(listFacts(f)),\n ...sessionRetirementPart.factProblems({ owner: f?.sessionOwner, predicateRetirements: f?.predicateRetirements }).map((p) =>\n p.startsWith('owner') ? `session${p[0].toUpperCase()}${p.slice(1)}` : p,\n ),\n ]),\n ],\n build: (f) => [\n ...cacheInvalidationGuards(f, { sessionOwner: f.sessionOwner, memberRefreshes: f.memberRefreshes }),\n ...listResetGuards(listFacts(f), f.sessionOwner),\n ...sessionRetirementPart.build({ owner: f.sessionOwner, predicateRetirements: f.predicateRetirements }),\n ],\n};\n\nexport const CACHE_GUARDS = [queryCacheGuard, domainEventRegistryGuard] as const;\n"]}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/modules/frontend-reads/cache.ts"],"names":[],"mappings":"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","sourcesContent":["// What may touch the query cache, and how: invalidation only through the domain-event registry,\n// aimed at keys a live query reads and never at an infinite list; an infinite list never reloaded\n// by an action; a whole-cache drop only by the session-retirement owner; and a registry whose every\n// event is produced, well formed, and awaited.\n\nimport ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../config.js';\nimport type { Finding, Guard, GuardContext } from '../../guard.js';\nimport type { FileView } from '../../reader/view.js';\nimport { identifierProblem, loaderProblem, pathProblem, reviewedProblems, type Loader } from '../../support/facts.js';\nimport { escapeRegExp } from '../../support/text.js';\nimport {\n APP_CODE,\n alternation,\n callSpan,\n collapse,\n familyOf,\n filesUnder,\n identifierListProblem,\n infiniteKeyFamilies,\n isPrefix,\n keyModuleProblem,\n loadKeyObjects,\n pathListProblem,\n reachesInfinite,\n requiredFile,\n reviewedCallProblem,\n sampleKey,\n type KeyBuilders,\n type KeyModuleFacts,\n type ReviewedCall,\n} from './shared.js';\n\n/** query-core's registry factory and the two invalidation builders a registry entry uses. */\nconst REGISTRY_FACTORY = 'createDomainEventInvalidator';\nconst EXACT = 'exact';\n\n/** The registry: where it is. */\nexport interface RegistryFacts {\n path: string;\n}\n\n/** The object literal the registry module hands to query-core's registry factory, as code. */\nexport function registryObjectCode(file: FileView): { name: string; code: string } | null {\n const sf = file.sourceFile;\n let name: string | null = null;\n const find = (node: ts.Node) => {\n if (!name && ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === REGISTRY_FACTORY && node.arguments[0] && ts.isIdentifier(node.arguments[0])) {\n name = node.arguments[0].text;\n }\n ts.forEachChild(node, find);\n };\n find(sf);\n if (!name) return null;\n let found: { name: string; code: string } | null = null;\n const visit = (node: ts.Node) => {\n if (!found && ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === name && node.initializer) {\n found = { name: name!, code: file.code.slice(node.initializer.getStart(sf), node.initializer.getEnd()) };\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\nconst keyRefPattern = (objects: readonly string[]) => new RegExp(`\\\\b(${alternation(objects)})\\\\.(\\\\w+)`, 'g');\n\n// =============================================================================================\n// Cache invalidation only through the registry; the registry's targets are read, and never an infinite list.\n// =============================================================================================\n\nexport interface CacheInvalidationFacts {\n registry: RegistryFacts;\n keyModule: KeyModuleFacts;\n /** The trees whose `queryKey:` sites are the app's live reads (hooks, components, pages). */\n readTrees: readonly string[];\n /** The suffix the key module names a family helper with (`listPrefix()` → `Prefix`). */\n familySuffix: string;\n}\n\n/** What the registry rule leaves to the other cache owners: the session-retirement owner, and a person's own refreshes. */\ninterface OwnedElsewhere {\n sessionOwner: string;\n memberRefreshes: readonly ReviewedCall[];\n}\n\nconst CLEAR_CALL = /\\.\\s*(invalidateQueries|removeQueries|resetQueries)(\\s*\\()/g;\nconst CACHE_WRITE_CALL =\n /\\b(refetchQueries|resetQueries|cancelQueries|setQueryData|setQueriesData|getQueryData|getQueriesData|invalidateQueries|removeQueries|ensureQueryData|prefetchQuery)\\b/;\n\n/** Every invalidate / remove / reset call in a file, as its collapsed text from the method name on. */\nexport function clearCalls(file: FileView): Array<{ index: number; call: string }> {\n return [...file.code.matchAll(CLEAR_CALL)].map((m) => {\n const name = (m.index ?? 0) + m[0].indexOf(m[1]);\n const open = (m.index ?? 0) + m[0].length - 1;\n return { index: name, call: collapse(callSpan(file.code, name, open)) };\n });\n}\n\n/** Key families some live query reads: a `queryKey` built from a key method outside a cache call, or a key object handed whole. */\nexport function readKeyFamilies(files: ReadonlyArray<{ code: string }>, objects: readonly string[], familySuffix: string): Set<string> {\n const read = new Set<string>();\n const names = alternation(objects);\n for (const { code } of files) {\n for (const line of code.split('\\n')) {\n if (CACHE_WRITE_CALL.test(line)) continue;\n for (const m of line.matchAll(new RegExp(`\\\\bqueryKey\\\\s*[:=]\\\\s*(${names})\\\\.(\\\\w+)`, 'g'))) read.add(familyOf(`${m[1]}.${m[2]}`, familySuffix));\n for (const m of line.matchAll(new RegExp(`[\\\\w$]+\\\\s*:\\\\s*(${names})\\\\b(?![\\\\w$]|\\\\s*\\\\.)`, 'g'))) read.add(`${m[1]}.*`);\n }\n }\n return read;\n}\n\n/** The argument count of the call whose `(` is at `open`, or null when there is no call there. */\nfunction argCountAt(code: string, open: number): number | null {\n if (code[open] !== '(') return null;\n let depth = 0;\n let count = 0;\n let sawToken = false;\n for (let i = open; i < code.length; i += 1) {\n const ch = code[i];\n if ('([{'.includes(ch)) {\n depth += 1;\n if (depth > 1) sawToken = true;\n } else if (')]}'.includes(ch)) {\n depth -= 1;\n if (depth === 0) return sawToken ? count + 1 : 0;\n } else if (ch === ',' && depth === 1) count += 1;\n else if (depth >= 1 && !/\\s/.test(ch)) sawToken = true;\n }\n return null;\n}\n\n/** Each key method → the argument counts the app's live reads build it with. */\nexport function readArgCounts(files: ReadonlyArray<{ code: string }>, objects: readonly string[]): Map<string, Set<number>> {\n const counts = new Map<string, Set<number>>();\n const re = new RegExp(`\\\\bqueryKey\\\\s*[:=]\\\\s*(${alternation(objects)})\\\\.(\\\\w+)\\\\(`, 'g');\n for (const { code } of files) {\n for (const line of code.split('\\n')) {\n if (CACHE_WRITE_CALL.test(line)) continue;\n for (const m of line.matchAll(re)) {\n const n = argCountAt(line, (m.index ?? 0) + m[0].length - 1);\n if (n === null) continue;\n const ref = `${m[1]}.${m[2]}`;\n counts.set(ref, (counts.get(ref) ?? new Set()).add(n));\n }\n }\n }\n return counts;\n}\n\n/** Registry targets that miss: unread, an exact on a family, an exact shaped unlike every read, or one reaching an infinite list. */\nexport function registryTargetProblems(input: {\n registryCode: string;\n reads: ReadonlyArray<{ code: string }>;\n builders: KeyBuilders;\n familySuffix: string;\n}): string[] {\n const { registryCode, reads, builders, familySuffix } = input;\n const objects = Object.keys(builders);\n const refs = [...new Set([...registryCode.matchAll(keyRefPattern(objects))].map((m) => `${m[1]}.${m[2]}`))];\n const read = readKeyFamilies(reads, objects, familySuffix);\n const readKeys = [...read].map((f) => sampleKey(f, builders)).filter((k): k is unknown[] => k !== null);\n const problems: string[] = [];\n for (const ref of refs) {\n if (read.has(familyOf(ref, familySuffix)) || read.has(`${ref.split('.')[0]}.*`)) continue;\n const key = sampleKey(ref, builders);\n if (key === null || !readKeys.some((readKey) => isPrefix(key, readKey))) problems.push(`${ref}: no live query reads this key`);\n }\n const counts = readArgCounts(reads, objects);\n const exactRe = new RegExp(`\\\\b${EXACT}\\\\(\\\\s*(${alternation(objects)})\\\\.(\\\\w+)`, 'g');\n const shaped = new Set<string>();\n for (const m of registryCode.matchAll(exactRe)) {\n const ref = `${m[1]}.${m[2]}`;\n if (shaped.has(ref)) continue;\n if (m[2] === 'all' || (m[2].endsWith(familySuffix) && m[2] !== familySuffix)) {\n shaped.add(ref);\n problems.push(`${ref}: an exact target on a key family (only a prefix target reaches a family)`);\n continue;\n }\n const n = argCountAt(registryCode, (m.index ?? 0) + m[0].length);\n const readCounts = counts.get(ref);\n if (n !== null && readCounts && !readCounts.has(n)) {\n shaped.add(ref);\n problems.push(`${ref}: an exact target built with ${n} argument(s), which no live read builds`);\n }\n }\n const infinite = infiniteKeyFamilies(reads, objects, familySuffix);\n for (const ref of refs) if (reachesInfinite(ref, infinite, builders, familySuffix)) problems.push(`${ref}: reaches an infinite list`);\n return problems;\n}\n\nfunction registryProblem(value: unknown, problems: string[]): void {\n const facts = value as RegistryFacts | undefined;\n if (!facts || typeof facts !== 'object') problems.push('registry is missing');\n else pathProblem(facts.path, 'registry.path', problems);\n}\n\nconst cacheInvalidationProblems = (facts: CacheInvalidationFacts) => {\n const problems: string[] = [];\n registryProblem(facts?.registry, problems);\n keyModuleProblem(facts?.keyModule, problems);\n pathListProblem(facts?.readTrees, 'readTrees', problems);\n identifierProblem(facts?.familySuffix, 'familySuffix', problems);\n return problems;\n};\n\nconst cacheInvalidationGuards = (facts: CacheInvalidationFacts, owned: OwnedElsewhere): Guard[] => [\n {\n title: 'saved reads are refreshed, removed, or reset only through the domain-event registry',\n description:\n `${facts.registry.path} — the object it hands to query-core's ${REGISTRY_FACTORY} — is the one place that turns something that ` +\n 'happened into what the cache does: refresh, remove, or reset. No other file calls invalidateQueries, removeQueries, or ' +\n 'resetQueries: emit the domain event instead, and patch an infinite list in place. The only other owners are the session-' +\n `retirement owner (${owned.sessionOwner}) and a person's own refresh, declared once beside the list-reload rule.`,\n run(context) {\n const { file: registry, findings } = requiredFile(context, facts.registry.path, 'the domain-event registry');\n if (registry && !registryObjectCode(registry)) findings.push({ file: registry.path, detail: `no registry object handed to ${REGISTRY_FACTORY}` });\n const refreshes = new Set(owned.memberRefreshes.map((r) => `${r.path} ${r.call}`));\n for (const file of context.files(APP_CODE)) {\n if (file.path === facts.registry.path || file.path === owned.sessionOwner) continue;\n for (const { index, call } of clearCalls(file)) {\n if (refreshes.has(`${file.path} ${call}`)) continue;\n findings.push({ file: file.path, line: file.lineOf(index), detail: `outside the registry: ${call.slice(0, 120)}` });\n }\n }\n return findings;\n },\n },\n {\n title: 'every registry cache target is a key a live query reads, and never an infinite list',\n description:\n `Every key the registry in ${facts.registry.path} writes is reached by a live query's key (a queryKey built from the same key ` +\n `method in ${facts.readTrees.join(', ')}, or a key object handed whole to a reader); an exact target names a leaf the reads build ` +\n `with the same arguments, never a family (all, or a …${facts.familySuffix} helper); and no target reaches an infinite list — named, ` +\n \"through its family helper, or through its scope. A write aimed at a key nothing reads is a silent no-op, and invalidating an \" +\n 'infinite list re-runs every loaded page.',\n timeoutMs: 120_000,\n async run(context: GuardContext): Promise<Finding[]> {\n const { file: registry, findings } = requiredFile(context, facts.registry.path, 'the domain-event registry');\n if (!registry) return findings;\n const object = registryObjectCode(registry);\n if (!object) return [{ file: registry.path, detail: `no registry object handed to ${REGISTRY_FACTORY}` }];\n const builders = await loadKeyObjects(facts.keyModule);\n const { files, findings: missing } = filesUnder(context, facts.readTrees);\n findings.push(...missing);\n for (const detail of registryTargetProblems({ registryCode: object.code, reads: files, builders, familySuffix: facts.familySuffix })) {\n findings.push({ file: registry.path, detail });\n }\n return findings;\n },\n },\n];\n\n// =============================================================================================\n// No action-driven reload of an infinite list.\n// =============================================================================================\n\nexport interface ListResetFacts {\n keyModule: KeyModuleFacts;\n familySuffix: string;\n /** The app predicate that is true for a query holding loaded pages; a reload filtered by its negation reloads no shown list. */\n loadedPagesPredicate: string;\n /** A person's own refreshes (pull-to-refresh, a Refresh button): each call site with its why. */\n memberRefreshes: readonly ReviewedCall[];\n /** Hooks that run a member's own refresh, each handed only to its refresh control on the named prop; [] for none. */\n refreshHandoffs: ReadonlyArray<{ hook: string; control: string; prop: string }>;\n}\n\nconst RELOAD_CALL = /\\b(resetQueries|refetchQueries|removeQueries)\\s*\\(/g;\nconst PATCH_CALL = /\\b(setQueryData|setQueriesData)\\s*(?:<[^>]*>)?\\s*\\(/g;\nconst FIRST_PAGE_TRIM = /\\bpages\\.slice\\(\\s*0\\s*,\\s*1\\s*\\)|\\bpageParams\\.slice\\(\\s*0\\s*,\\s*1\\s*\\)|\\bpages\\s*:\\s*\\[\\s*[\\w.?]+\\.pages\\[0\\]\\s*\\]/;\n\n/** The key refs a call targets: its key method, or every one a constant map it indexes holds; null when unresolved. */\nfunction targetRefs(call: string, code: string, objects: readonly string[]): string[] | null {\n const names = alternation(objects);\n const direct = call.match(new RegExp(`\\\\bqueryKey\\\\s*:\\\\s*(${names})\\\\.(\\\\w+)`));\n if (direct) return [`${direct[1]}.${direct[2]}`];\n const indexed = call.match(/\\bqueryKey\\s*:\\s*([A-Za-z_]\\w*)\\[/);\n if (!indexed) return null;\n const decl = code.match(new RegExp(`\\\\bconst \\\\s*${escapeRegExp(indexed[1])}\\\\b[^=]*=\\\\s*\\\\{`));\n if (!decl) return null;\n const open = (decl.index ?? 0) + decl[0].length - 1;\n const refs = [...callSpan(code, open, open).matchAll(keyRefPattern(objects))].map((m) => `${m[1]}.${m[2]}`);\n return refs.length ? refs : null;\n}\n\n/** Every call that reloads or trims an infinite list, outside the reviewed reloads. */\nexport function listReloads(\n files: readonly FileView[],\n builders: KeyBuilders,\n facts: Pick<ListResetFacts, 'familySuffix' | 'loadedPagesPredicate' | 'memberRefreshes'>,\n sessionOwner?: string,\n) {\n const objects = Object.keys(builders);\n const infinite = infiniteKeyFamilies(files, objects, facts.familySuffix);\n const pinned = new Set(facts.memberRefreshes.map((r) => `${r.path} ${r.call}`));\n const excluded = new RegExp(`!${escapeRegExp(facts.loadedPagesPredicate)}\\\\(\\\\s*query\\\\s*\\\\)`);\n const found: Finding[] = [];\n const present = new Set<string>();\n for (const file of files) {\n if (file.path === sessionOwner) continue;\n const code = file.code;\n for (const m of code.matchAll(RELOAD_CALL)) {\n const call = collapse(callSpan(code, m.index ?? 0, (m.index ?? 0) + m[0].length - 1));\n present.add(`${file.path} ${call}`);\n if (pinned.has(`${file.path} ${call}`)) continue;\n const refs = targetRefs(call, code, objects);\n const reloads = refs ? refs.some((ref) => reachesInfinite(ref, infinite, builders, facts.familySuffix)) : !excluded.test(call);\n if (reloads) found.push({ file: file.path, line: file.lineOf(m.index ?? 0), detail: `${refs ? 'reloads an infinite list' : 'reloads queries its key does not name'}: ${call.slice(0, 120)}` });\n }\n for (const m of code.matchAll(PATCH_CALL)) {\n const call = callSpan(code, m.index ?? 0, (m.index ?? 0) + m[0].length - 1);\n if (FIRST_PAGE_TRIM.test(call)) found.push({ file: file.path, line: file.lineOf(m.index ?? 0), detail: `trims a list to its first page: ${collapse(call).slice(0, 120)}` });\n }\n }\n for (const r of facts.memberRefreshes) if (!present.has(`${r.path} ${r.call}`)) found.push({ file: r.path, detail: `stale member refresh: ${r.call} is no longer there` });\n return { infinite, findings: found };\n}\n\n/** Each refresh hook's result used anywhere but on its refresh control's prop, and each hook no file calls. */\nexport function refreshHandoffMisuses(files: readonly FileView[], handoffs: ListResetFacts['refreshHandoffs']): Finding[] {\n const findings: Finding[] = [];\n for (const { hook, control, prop } of handoffs) {\n let callers = 0;\n for (const file of files) {\n for (const m of file.code.matchAll(new RegExp(`const\\\\s+(\\\\w+)\\\\s*=\\\\s*${escapeRegExp(hook)}\\\\(`, 'g'))) {\n callers += 1;\n const name = m[1];\n const uses = [...file.code.matchAll(new RegExp(`\\\\b${name}\\\\b`, 'g'))].length - 1;\n const handed = [...file.code.matchAll(new RegExp(`<${escapeRegExp(control)}[^>]*${escapeRegExp(prop)}=\\\\{${name}\\\\}`, 'g'))].length;\n if (uses !== handed) findings.push({ file: file.path, line: file.lineOf(m.index ?? 0), detail: `${hook}()'s refresh is used other than as <${control} ${prop}>` });\n }\n }\n if (!callers) findings.push({ file: '(refreshHandoffs)', detail: `stale entry: nothing calls ${hook}` });\n }\n return findings;\n}\n\nconst listResetProblems = (facts: ListResetFacts) => {\n const problems: string[] = [];\n keyModuleProblem(facts?.keyModule, problems);\n identifierProblem(facts?.familySuffix, 'familySuffix', problems);\n identifierProblem(facts?.loadedPagesPredicate, 'loadedPagesPredicate', problems);\n reviewedCallProblem(facts?.memberRefreshes, 'memberRefreshes', problems);\n if (!Array.isArray(facts?.refreshHandoffs)) problems.push('refreshHandoffs is missing (declare [] when there is none)');\n else\n facts.refreshHandoffs.forEach((h, i) => {\n identifierProblem(h?.hook, `refreshHandoffs[${i}].hook`, problems);\n identifierProblem(h?.control, `refreshHandoffs[${i}].control`, problems);\n identifierProblem(h?.prop, `refreshHandoffs[${i}].prop`, problems);\n });\n return problems;\n};\n\nconst listResetGuards = (facts: ListResetFacts, sessionOwner: string): Guard[] => [\n {\n title: 'an action never reloads an infinite list',\n description:\n \"An action's change is placed, moved, or patched in place in an infinite list; no resetQueries / refetchQueries / removeQueries \" +\n `whose key reaches one (directly, through its family helper or scope, or through a constant map of keys), none whose key cannot ` +\n `be resolved unless its predicate excludes every query holding loaded pages (!${facts.loadedPagesPredicate}(query)), and no cache ` +\n \"write that trims a list to its first page. A person's own refresh is declared with its why, and a refresh hook's result is only \" +\n 'ever handed to its refresh control.',\n timeoutMs: 120_000,\n async run(context) {\n const builders = await loadKeyObjects(facts.keyModule);\n const files = context.files(APP_CODE);\n const { infinite, findings } = listReloads(files, builders, facts, sessionOwner);\n if (!infinite.size) findings.push({ file: facts.keyModule.path, detail: 'no infinite list found in the app, so the guard checks nothing' });\n findings.push(...refreshHandoffMisuses(files, facts.refreshHandoffs));\n return findings;\n },\n },\n];\n\n// =============================================================================================\n// An unscoped cancel or a whole-cache clear only by session retirement.\n// =============================================================================================\n\nexport interface SessionRetirementFacts {\n /** The session-retirement owner. */\n owner: string;\n /** Retirements beyond a session's end that the owner runs by predicate (a member leaving a group), each with its why; [] for none. */\n predicateRetirements: ReadonlyArray<{ trigger: string; why: string }>;\n}\n\nconst WHOLE_CACHE_DROP = [\n /\\bcancelQueries\\(\\s*\\)/g,\n /\\bcancelQueries\\(\\s*undefined\\b/g,\n /\\bcancelQueries\\(\\s*\\{(?![^}]*\\bqueryKey\\b)/g,\n /\\bget(?:Query|Mutation)Cache\\(\\)\\s*\\.clear\\(/g,\n /\\b\\w*[cC]lient\\s*\\.clear\\(\\s*\\)/g,\n];\n\nexport function wholeCacheDrops(file: FileView): Array<{ index: number; text: string }> {\n return WHOLE_CACHE_DROP.flatMap((re) => [...file.code.matchAll(re)].map((m) => ({ index: m.index ?? 0, text: m[0] }))).sort((a, b) => a.index - b.index);\n}\n\nconst sessionRetirementPart = {\n factProblems(facts: SessionRetirementFacts) {\n const problems: string[] = [];\n pathProblem(facts?.owner, 'owner', problems);\n reviewedProblems(facts?.predicateRetirements, 'predicateRetirements', problems, { key: 'trigger' });\n return problems;\n },\n build: (facts: SessionRetirementFacts): Guard[] => [\n {\n title: 'an unscoped cancel or a whole-cache clear runs only in the session-retirement owner',\n description:\n `A cancelQueries with no key (bare, or selected by a predicate) and a query or mutation cache clear drop reads the call site ` +\n `cannot name, so only ${facts.owner} runs them: when a session ends it cancels every query and clears the query cache` +\n (facts.predicateRetirements.length ? `, and it cancels by predicate for ${facts.predicateRetirements.map((r) => r.trigger).join('; ')}` : '') +\n '. Everywhere else a cancel names its key, and nothing clears a cache.',\n run(context) {\n const { file: owner, findings } = requiredFile(context, facts.owner, 'the session-retirement owner');\n for (const file of context.files(APP_CODE)) {\n if (file.path === facts.owner) continue;\n for (const drop of wholeCacheDrops(file)) findings.push({ file: file.path, line: file.lineOf(drop.index), detail: `outside the session-retirement owner: ${drop.text}` });\n }\n if (owner) {\n if (!/\\bcancelQueries\\(\\s*\\)/.test(owner.code)) findings.push({ file: owner.path, detail: 'the owner no longer cancels every query when a session ends' });\n if (!/getQueryCache\\(\\)\\s*\\.clear\\(/.test(owner.code)) findings.push({ file: owner.path, detail: 'the owner no longer clears the query cache when a session ends' });\n const byPredicate = [...owner.code.matchAll(/\\bcancelQueries\\(\\s*\\{\\s*predicate\\s*:/g)].length;\n if (byPredicate !== facts.predicateRetirements.length) {\n findings.push({ file: owner.path, detail: `the owner cancels by predicate ${byPredicate} time(s); ${facts.predicateRetirements.length} predicate retirement(s) are reviewed` });\n }\n }\n return findings;\n },\n },\n ],\n};\n\n// =============================================================================================\n// The domain-event registry: every event produced, every variant registered and well formed, every\n// notification handed on.\n// =============================================================================================\n\nexport interface DomainEventRegistryFacts {\n registry: RegistryFacts & {\n /** A loader of the registry object itself (event type → invalidation builder). */\n load: Loader<Record<string, unknown>>;\n };\n /** A loader of the core's domain-event schema: a discriminated union on `type`, each variant carrying an `ids` object. */\n eventSchema: Loader<unknown>;\n /** The app's functions that dispatch a domain event and return the refresh's promise. */\n notifiers: readonly string[];\n}\n\ntype ZodLike = { def?: any; _def?: any; shape?: Record<string, ZodLike>; options?: unknown[]; value?: unknown };\nconst defOf = (field: ZodLike) => field?.def ?? field?._def ?? {};\nconst kindOf = (field: ZodLike): 'optional' | 'nullable' | 'enum' | 'required' => {\n const type = defOf(field).type;\n return type === 'optional' || type === 'nullable' || type === 'enum' ? type : 'required';\n};\n\n/** Synthetic `ids` for one variant: every field filled, then each optional field dropped in turn. */\nexport function syntheticIds(idsSchema: ZodLike): Array<Record<string, unknown>> {\n const baseline: Record<string, unknown> = {};\n const optional: string[] = [];\n for (const [key, field] of Object.entries(idsSchema?.shape ?? {})) {\n const kind = kindOf(field);\n if (kind === 'enum') baseline[key] = (field.options as unknown[])[0];\n else if (kind === 'optional') {\n optional.push(key);\n const inner = defOf(field).innerType as ZodLike;\n baseline[key] = kindOf(inner) === 'enum' ? (inner.options as unknown[])[0] : `test-${key}`;\n } else baseline[key] = `test-${key}`;\n }\n return [{ ...baseline }, ...optional.map((key) => Object.fromEntries(Object.entries(baseline).filter(([k]) => k !== key)))];\n}\n\n/** What a query-core registry entry may do to the reads it matches, and how a refresh refetches. */\nconst CACHE_ACTIONS: ReadonlySet<unknown> = new Set([undefined, 'refresh', 'remove', 'reset']);\nconst REFETCH_TYPES: ReadonlySet<unknown> = new Set([undefined, 'active', 'all', 'none']);\n\n/** Why a builder's answer is not a list of well-formed invalidations, or null. */\nexport function malformedInvalidations(answer: unknown): string | null {\n if (!Array.isArray(answer)) return 'does not answer a list of invalidations';\n for (const inv of answer as Array<Record<string, unknown>>) {\n if (inv?.kind === 'exact' || inv?.kind === 'prefix') {\n if (!Array.isArray(inv.queryKey) || !inv.queryKey.length) return `a ${inv.kind} invalidation with no key`;\n } else if (inv?.kind === 'predicate') {\n if (typeof inv.description !== 'string' || !inv.description || typeof inv.match !== 'function') return 'a predicate invalidation with no description or matcher';\n } else return `an invalidation of unknown kind ${String(inv?.kind)}`;\n if (!CACHE_ACTIONS.has(inv.action)) return `a ${inv.kind} invalidation with unknown action ${String(inv.action)}`;\n if (!REFETCH_TYPES.has(inv.refetchType)) return `a ${inv.kind} invalidation with unknown refetchType ${String(inv.refetchType)}`;\n if ((inv.action === 'remove' || inv.action === 'reset') && inv.refetchType !== undefined) {\n return `a ${inv.action} invalidation with a refetchType, which only a refresh takes`;\n }\n }\n return null;\n}\n\n/** Whether the call at `index` starts a statement, so its promise is dropped. */\nfunction startsStatement(code: string, index: number): boolean {\n const before = code.slice(0, index).trimEnd();\n return before.length === 0 || ';{})'.includes(before.charAt(before.length - 1));\n}\n\nexport function droppedNotifications(file: FileView, notifiers: readonly string[]): Array<{ index: number; name: string }> {\n const hits: Array<{ index: number; name: string }> = [];\n for (const m of file.code.matchAll(new RegExp(`\\\\b(${alternation(notifiers)})\\\\(`, 'g'))) {\n const index = m.index ?? 0;\n if (/function\\s+$/.test(file.code.slice(0, index))) continue;\n if (startsStatement(file.code, index)) hits.push({ index, name: m[1] });\n }\n return hits;\n}\n\nexport const domainEventRegistryGuard: GenericGuardDefinition<DomainEventRegistryFacts> = {\n id: 'domainEventRegistry',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n registryProblem(facts?.registry, problems);\n loaderProblem(facts?.registry?.load, 'registry.load', problems);\n loaderProblem(facts?.eventSchema, 'eventSchema', problems);\n identifierListProblem(facts?.notifiers, 'notifiers', problems, { nonEmpty: true });\n return problems;\n },\n build: (facts) => [\n {\n title: 'every registered domain event has a producer in the app',\n description:\n `Every event type the registry in ${facts.registry.path} handles is emitted somewhere in the app's own code (its quoted type ` +\n \"outside the registry, in the client or functions tree); the core's schema holds every variant by construction, so it is no \" +\n 'evidence. Restore the producer, or delete the event from the core and the registry.',\n async run(context) {\n const registry = (await facts.registry.load()) ?? {};\n const findings: Finding[] = [];\n const haystack = context\n .files({ roots: ['app', 'functions'], optionalRoots: ['functions'], kinds: ['code'], tests: false })\n .filter((f) => f.path !== facts.registry.path)\n .map((f) => f.code)\n .join('\\n');\n const produced = (type: string) => haystack.includes(`'${type}'`) || haystack.includes(`\"${type}\"`);\n for (const type of Object.keys(registry)) if (!produced(type)) findings.push({ file: facts.registry.path, detail: `${type}: no producer in the app` });\n return findings;\n },\n },\n {\n title: \"every core domain-event variant has a registry entry with well-formed invalidations\",\n description:\n `Every variant of the core's domain-event schema has an entry in the registry in ${facts.registry.path}, and the entry answers, ` +\n 'for every shape of its ids (each optional id present and absent), a list of invalidations that are each an exact or prefix ' +\n 'target with a non-empty key, or a predicate with a description and a matcher.',\n async run(context) {\n // The loaded registry is judged, but the file the facts name must be the one it comes from.\n if (!context.reader.exists(facts.registry.path)) return [{ file: facts.registry.path, detail: 'the registry file does not exist' }];\n context.file(facts.registry.path);\n const registry = (await facts.registry.load()) ?? {};\n const schema = (await facts.eventSchema()) as ZodLike;\n const variants = (schema?.options ?? []) as ZodLike[];\n if (!variants.length) return [{ file: '(eventSchema)', detail: 'the loader did not answer a discriminated union of variants' }];\n const findings: Finding[] = [];\n for (const variant of variants) {\n const type = String(variant.shape?.type?.value ?? '');\n if (!type) {\n findings.push({ file: '(eventSchema)', detail: 'a variant carries no literal type' });\n continue;\n }\n const build = registry[type];\n if (typeof build !== 'function') {\n findings.push({ file: facts.registry.path, detail: `${type}: no registry entry` });\n continue;\n }\n for (const ids of syntheticIds(variant.shape?.ids as ZodLike)) {\n let problem: string | null;\n try {\n problem = malformedInvalidations((build as (ids: unknown) => unknown)(ids));\n } catch (err) {\n problem = `throws for ids ${JSON.stringify(ids)}: ${(err as Error)?.message ?? err}`;\n }\n if (problem) findings.push({ file: facts.registry.path, detail: `${type}: ${problem}` });\n }\n }\n return findings;\n },\n },\n {\n title: 'every domain-event notification hands its refresh promise on',\n description:\n `A call to ${facts.notifiers.join(' / ')} returns the promise of the refresh it starts; a mutation returns or awaits it so it stays ` +\n 'pending until the refreshed data is on screen. A call in statement position drops it silently: return it, await it, pass it ' +\n 'on, or mark a deliberate fire-and-forget with void.',\n run(context) {\n const findings: Finding[] = [];\n let calls = 0;\n const callRe = new RegExp(`\\\\b(?:${alternation(facts.notifiers)})\\\\(`, 'g');\n for (const file of context.files(APP_CODE)) {\n calls += [...file.code.matchAll(callRe)].length;\n for (const hit of droppedNotifications(file, facts.notifiers)) {\n findings.push({ file: file.path, line: file.lineOf(hit.index), detail: `${hit.name}(…) in statement position drops its refresh` });\n }\n }\n if (!calls) findings.push({ file: '(notifiers)', detail: `nothing in the app calls ${facts.notifiers.join(' / ')}, so the guard checks nothing` });\n return findings;\n },\n },\n ],\n};\n\n/**\n * Every fact the query-cache owners need, declared once: the registry (the one place something that\n * happened changes saved reads), a person's own refreshes, and the session-retirement owner.\n */\nexport interface QueryCacheFacts extends CacheInvalidationFacts {\n loadedPagesPredicate: string;\n memberRefreshes: readonly ReviewedCall[];\n refreshHandoffs: ListResetFacts['refreshHandoffs'];\n sessionOwner: string;\n predicateRetirements: SessionRetirementFacts['predicateRetirements'];\n}\n\nconst listFacts = (f: QueryCacheFacts | undefined): ListResetFacts => ({\n keyModule: f?.keyModule as KeyModuleFacts,\n familySuffix: f?.familySuffix as string,\n loadedPagesPredicate: f?.loadedPagesPredicate as string,\n memberRefreshes: f?.memberRefreshes as readonly ReviewedCall[],\n refreshHandoffs: f?.refreshHandoffs as ListResetFacts['refreshHandoffs'],\n});\n\nexport const queryCacheGuard: GenericGuardDefinition<QueryCacheFacts> = {\n id: 'queryCache',\n absentWhen: false,\n factProblems: (f) => [\n ...new Set([\n ...cacheInvalidationProblems(f),\n ...listResetProblems(listFacts(f)),\n ...sessionRetirementPart.factProblems({ owner: f?.sessionOwner, predicateRetirements: f?.predicateRetirements }).map((p) =>\n p.startsWith('owner') ? `session${p[0].toUpperCase()}${p.slice(1)}` : p,\n ),\n ]),\n ],\n build: (f) => [\n ...cacheInvalidationGuards(f, { sessionOwner: f.sessionOwner, memberRefreshes: f.memberRefreshes }),\n ...listResetGuards(listFacts(f), f.sessionOwner),\n ...sessionRetirementPart.build({ owner: f.sessionOwner, predicateRetirements: f.predicateRetirements }),\n ],\n};\n\nexport const CACHE_GUARDS = [queryCacheGuard, domainEventRegistryGuard] as const;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-overrides.d.ts","sourceRoot":"","sources":["../../../src/modules/repo/dependency-overrides.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAI9D,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC1C;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAU/K;AAED,eAAO,MAAM,uBAAuB,EAAE,sBAAsB,CAAC,uBAAuB,CA8CnF,CAAC"}
1
+ {"version":3,"file":"dependency-overrides.d.ts","sourceRoot":"","sources":["../../../src/modules/repo/dependency-overrides.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAI9D,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC1C;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAU/K;AAED,eAAO,MAAM,uBAAuB,EAAE,sBAAsB,CAAC,uBAAuB,CA+CnF,CAAC"}
@@ -25,8 +25,9 @@ export const dependencyOverrideGuard = {
25
25
  const problems = [];
26
26
  reviewedProblems(facts?.overrides, 'overrides', problems, {
27
27
  key: 'parent',
28
- id: (o) => (isText(o.child) ? `${o.parent} → ${o.child}` : undefined),
29
- idNames: 'child',
28
+ // One override per manifest: each manifest that installs the parent carries its own copy.
29
+ id: (o) => (isText(o.child) && isText(o.manifest) ? `${o.manifest}: ${o.parent} → ${o.child}` : undefined),
30
+ idNames: 'manifest or child',
30
31
  nonEmpty: true,
31
32
  extra(o, label) {
32
33
  textProblem(o.manifest, `${label}'s manifest`, problems);
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-overrides.js","sourceRoot":"","sources":["../../../src/modules/repo/dependency-overrides.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,mGAAmG;AACnG,oGAAoG;AACpG,8BAA8B;AAE9B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAkB/E,4FAA4F;AAC5F,MAAM,UAAU,eAAe,CAAC,CAA4D,EAAE,WAA+B,EAAE,aAAiC;IAC9J,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,CAAC,MAAM,uBAAuB,CAAC,CAAC,KAAK,uBAAuB,CAAC;IACvG,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3F,OAAO,GAAG,CAAC,CAAC,MAAM,iBAAiB,CAAC,CAAC,KAAK,IAAI,WAAW,0DAA0D,CAAC;IACtH,CAAC;IACD,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,CAAC,MAAM,mBAAmB,CAAC,CAAC,KAAK,IAAI,WAAW,gEAAgE,CAAC;IAC7J,IAAI,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9F,OAAO,qBAAqB,CAAC,CAAC,KAAK,OAAO,aAAa,uCAAuC,CAAC,CAAC,QAAQ,GAAG,CAAC;IAC9G,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAoD;IACtF,EAAE,EAAE,qBAAqB;IACzB,UAAU,EAAE,wCAAwC;IACpD,YAAY,CAAC,KAAK;QAChB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE;YACxD,GAAG,EAAE,QAAQ;YACb,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACrE,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,IAAI;YACd,KAAK,CAAC,CAAC,EAAE,KAAK;gBACZ,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,KAAK,aAAa,EAAE,QAAQ,CAAC,CAAC;gBACzD,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ;oBAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,2DAA2D,CAAC,CAAC;gBAC7H,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,IAAI;oBAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,mCAAmC,CAAC,CAAC;YAChI,CAAC;SACF,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO;YACL;gBACE,KAAK,EAAE,+FAA+F;gBACtG,WAAW,EACT,iHAAiH;oBACjH,kHAAkH;oBAClH,mBAAmB;gBACrB,GAAG,CAAC,OAAO;oBACT,MAAM,QAAQ,GAAc,EAAE,CAAC;oBAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;wBAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAA4C,CAAC;wBACtG,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,MAAM,eAAe,CAAC;wBAC5G,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;4BACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,2BAA2B,CAAC,CAAC,cAAc,IAAI,UAAU,oCAAoC,EAAE,CAAC,CAAC;4BACtJ,SAAS;wBACX,CAAC;wBACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAA8C,CAAC;wBACtG,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;wBAC9C,MAAM,MAAM,GAAG,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAE,MAAkC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;wBACxH,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;wBACpH,IAAI,OAAO;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;oBACpE,CAAC;oBACD,OAAO,QAAQ,CAAC;gBAClB,CAAC;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["// A dependency override exists only while it is needed: while the parent's declared range for the\n// child can still resolve to an affected version. Once the parent's range can no longer reach one,\n// the override is redundant and is removed; while it can, the override is present and its own range\n// admits no affected version.\n\nimport semver from 'semver';\nimport type { GenericGuardDefinition } from '../../config.js';\nimport type { Finding } from '../../guard.js';\nimport { isText, reviewedProblems, textProblem } from '../../support/facts.js';\n\nexport interface DependencyOverride {\n /** The manifest holding the parent-scoped `overrides` entry, repo-relative. */\n manifest: string;\n /** The folder whose `node_modules` holds the installed parent ('' for the repository root). */\n installedUnder: string;\n parent: string;\n child: string;\n /** The child's affected versions, as a semver range. */\n affected: string;\n why: string;\n}\n\nexport interface DependencyOverrideFacts {\n overrides: readonly DependencyOverride[];\n}\n\n/** Why the override is wrong for these ranges, or null when it is exactly as it must be. */\nexport function overrideProblem(o: Pick<DependencyOverride, 'parent' | 'child' | 'affected'>, parentRange: string | undefined, overrideRange: string | undefined): string | null {\n if (parentRange === undefined) return `${o.parent} no longer declares ${o.child}: remove the override`;\n if (semver.validRange(parentRange) !== null && !semver.intersects(parentRange, o.affected)) {\n return `${o.parent} now declares ${o.child} ${parentRange}, which reaches no affected version: remove the override`;\n }\n if (overrideRange === undefined) return `${o.parent} still declares ${o.child} ${parentRange}, which can reach an affected version, and no override pins it`;\n if (semver.validRange(overrideRange) === null || semver.intersects(overrideRange, o.affected)) {\n return `the override pins ${o.child} to ${overrideRange}, which admits an affected version (${o.affected})`;\n }\n return null;\n}\n\nexport const dependencyOverrideGuard: GenericGuardDefinition<DependencyOverrideFacts> = {\n id: 'dependencyOverrides',\n absentWhen: 'the app carries no dependency override',\n factProblems(facts) {\n const problems: string[] = [];\n reviewedProblems(facts?.overrides, 'overrides', problems, {\n key: 'parent',\n id: (o) => (isText(o.child) ? `${o.parent} → ${o.child}` : undefined),\n idNames: 'child',\n nonEmpty: true,\n extra(o, label) {\n textProblem(o.manifest, `${label}'s manifest`, problems);\n if (typeof o.installedUnder !== 'string') problems.push(`${label}'s installedUnder is missing ('' for the repository root)`);\n if (!isText(o.affected) || semver.validRange(o.affected) === null) problems.push(`${label}'s affected is not a semver range`);\n },\n });\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'every dependency override exists exactly while its parent can still reach an affected version',\n description:\n \"An override pins a child dependency under one parent because the parent's own range can resolve to an affected \" +\n \"version. Once it cannot, the override is redundant and is removed; while it can, the override's range admits no \" +\n 'affected version.',\n run(context) {\n const findings: Finding[] = [];\n for (const o of facts.overrides) {\n const manifest = JSON.parse(context.file(o.manifest).text) as { overrides?: Record<string, unknown> };\n const parentPath = `${o.installedUnder ? `${o.installedUnder}/` : ''}node_modules/${o.parent}/package.json`;\n if (!context.reader.exists(parentPath)) {\n findings.push({ file: o.manifest, detail: `${o.parent} is not installed under ${o.installedUnder || 'the root'}, so the override cannot be judged` });\n continue;\n }\n const parent = JSON.parse(context.file(parentPath).text) as { dependencies?: Record<string, string> };\n const scoped = manifest.overrides?.[o.parent];\n const pinned = scoped !== null && typeof scoped === 'object' ? (scoped as Record<string, unknown>)[o.child] : undefined;\n const problem = overrideProblem(o, parent.dependencies?.[o.child], typeof pinned === 'string' ? pinned : undefined);\n if (problem) findings.push({ file: o.manifest, detail: problem });\n }\n return findings;\n },\n },\n ];\n },\n};\n"]}
1
+ {"version":3,"file":"dependency-overrides.js","sourceRoot":"","sources":["../../../src/modules/repo/dependency-overrides.ts"],"names":[],"mappings":"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","sourcesContent":["// A dependency override exists only while it is needed: while the parent's declared range for the\n// child can still resolve to an affected version. Once the parent's range can no longer reach one,\n// the override is redundant and is removed; while it can, the override is present and its own range\n// admits no affected version.\n\nimport semver from 'semver';\nimport type { GenericGuardDefinition } from '../../config.js';\nimport type { Finding } from '../../guard.js';\nimport { isText, reviewedProblems, textProblem } from '../../support/facts.js';\n\nexport interface DependencyOverride {\n /** The manifest holding the parent-scoped `overrides` entry, repo-relative. */\n manifest: string;\n /** The folder whose `node_modules` holds the installed parent ('' for the repository root). */\n installedUnder: string;\n parent: string;\n child: string;\n /** The child's affected versions, as a semver range. */\n affected: string;\n why: string;\n}\n\nexport interface DependencyOverrideFacts {\n overrides: readonly DependencyOverride[];\n}\n\n/** Why the override is wrong for these ranges, or null when it is exactly as it must be. */\nexport function overrideProblem(o: Pick<DependencyOverride, 'parent' | 'child' | 'affected'>, parentRange: string | undefined, overrideRange: string | undefined): string | null {\n if (parentRange === undefined) return `${o.parent} no longer declares ${o.child}: remove the override`;\n if (semver.validRange(parentRange) !== null && !semver.intersects(parentRange, o.affected)) {\n return `${o.parent} now declares ${o.child} ${parentRange}, which reaches no affected version: remove the override`;\n }\n if (overrideRange === undefined) return `${o.parent} still declares ${o.child} ${parentRange}, which can reach an affected version, and no override pins it`;\n if (semver.validRange(overrideRange) === null || semver.intersects(overrideRange, o.affected)) {\n return `the override pins ${o.child} to ${overrideRange}, which admits an affected version (${o.affected})`;\n }\n return null;\n}\n\nexport const dependencyOverrideGuard: GenericGuardDefinition<DependencyOverrideFacts> = {\n id: 'dependencyOverrides',\n absentWhen: 'the app carries no dependency override',\n factProblems(facts) {\n const problems: string[] = [];\n reviewedProblems(facts?.overrides, 'overrides', problems, {\n key: 'parent',\n // One override per manifest: each manifest that installs the parent carries its own copy.\n id: (o) => (isText(o.child) && isText(o.manifest) ? `${o.manifest}: ${o.parent} → ${o.child}` : undefined),\n idNames: 'manifest or child',\n nonEmpty: true,\n extra(o, label) {\n textProblem(o.manifest, `${label}'s manifest`, problems);\n if (typeof o.installedUnder !== 'string') problems.push(`${label}'s installedUnder is missing ('' for the repository root)`);\n if (!isText(o.affected) || semver.validRange(o.affected) === null) problems.push(`${label}'s affected is not a semver range`);\n },\n });\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'every dependency override exists exactly while its parent can still reach an affected version',\n description:\n \"An override pins a child dependency under one parent because the parent's own range can resolve to an affected \" +\n \"version. Once it cannot, the override is redundant and is removed; while it can, the override's range admits no \" +\n 'affected version.',\n run(context) {\n const findings: Finding[] = [];\n for (const o of facts.overrides) {\n const manifest = JSON.parse(context.file(o.manifest).text) as { overrides?: Record<string, unknown> };\n const parentPath = `${o.installedUnder ? `${o.installedUnder}/` : ''}node_modules/${o.parent}/package.json`;\n if (!context.reader.exists(parentPath)) {\n findings.push({ file: o.manifest, detail: `${o.parent} is not installed under ${o.installedUnder || 'the root'}, so the override cannot be judged` });\n continue;\n }\n const parent = JSON.parse(context.file(parentPath).text) as { dependencies?: Record<string, string> };\n const scoped = manifest.overrides?.[o.parent];\n const pinned = scoped !== null && typeof scoped === 'object' ? (scoped as Record<string, unknown>)[o.child] : undefined;\n const problem = overrideProblem(o, parent.dependencies?.[o.child], typeof pinned === 'string' ? pinned : undefined);\n if (problem) findings.push({ file: o.manifest, detail: problem });\n }\n return findings;\n },\n },\n ];\n },\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/repo-guards",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ttt-productions/ttt-packages.git",