@ttt-productions/repo-guards 0.1.23 → 0.1.24

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.
@@ -27,7 +27,7 @@ export interface TextFieldDeclarationFacts {
27
27
  why: string;
28
28
  }>;
29
29
  declarations: Loader<Readonly<Record<string, unknown>>>;
30
- fieldSchema: Loader<FieldSchemaOf['schemaOf']>;
30
+ fieldSchema: Loader<FieldSchemaOf>;
31
31
  }
32
32
  interface Site {
33
33
  key: string;
@@ -1 +1 @@
1
- {"version":3,"file":"text-field-declarations.d.ts","sourceRoot":"","sources":["../../../src/modules/core-definitions/text-field-declarations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAIL,KAAK,MAAM,EAEZ,MAAM,wBAAwB,CAAC;AAIhC,KAAK,cAAc,GAAG,aAAa,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC,CAAC;AACH,KAAK,WAAW,GAAG;IAAE,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,CAAC;AAI3F,UAAU,aAAa;IACrB,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,WAAW,CAAC;CAC7C;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,WAAW,EAAE,cAAc,CAAC;IAC5B,kBAAkB,EAAE,cAAc,CAAC;IACnC,WAAW,EAAE,aAAa,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACxD,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;CAChD;AA+BD,UAAU,IAAI;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,CAyBxD;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,GAC5C,IAAI,EAAE,CAiCR;AAsDD,eAAO,MAAM,0BAA0B,EAAE,sBAAsB,CAAC,yBAAyB,CAmKxF,CAAC"}
1
+ {"version":3,"file":"text-field-declarations.d.ts","sourceRoot":"","sources":["../../../src/modules/core-definitions/text-field-declarations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAIL,KAAK,MAAM,EAEZ,MAAM,wBAAwB,CAAC;AAIhC,KAAK,cAAc,GAAG,aAAa,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC,CAAC;AACH,KAAK,WAAW,GAAG;IAAE,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,CAAC;AAI3F,UAAU,aAAa;IACrB,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,WAAW,CAAC;CAC7C;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,WAAW,EAAE,cAAc,CAAC;IAC5B,kBAAkB,EAAE,cAAc,CAAC;IACnC,WAAW,EAAE,aAAa,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACxD,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;CACpC;AA+BD,UAAU,IAAI;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,CAyBxD;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,GAC5C,IAAI,EAAE,CAiCR;AAsDD,eAAO,MAAM,0BAA0B,EAAE,sBAAsB,CAAC,yBAAyB,CAmKxF,CAAC"}
@@ -232,14 +232,14 @@ export const textFieldDeclarationsGuard = {
232
232
  const findings = [];
233
233
  coreBuild(context, findings);
234
234
  const declarations = textDeclarations(await facts.declarations());
235
- const schemaOf = await facts.fieldSchema();
235
+ const reader = await facts.fieldSchema();
236
236
  if (!declarations.length)
237
237
  findings.push({
238
238
  file: facts.declarationsFile,
239
239
  detail: 'no text-field declaration was loaded',
240
240
  });
241
241
  for (const [name, declaration] of declarations) {
242
- const schema = schemaOf(declaration);
242
+ const schema = reader.schemaOf(declaration);
243
243
  const min = typeof declaration.min === 'number' ? declaration.min : 0;
244
244
  if (min >= 1 && schema.safeParse(' \n\t ').success)
245
245
  findings.push({
@@ -1 +1 @@
1
- {"version":3,"file":"text-field-declarations.js","sourceRoot":"","sources":["../../../src/modules/core-definitions/text-field-declarations.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript';\nimport type { Finding, GuardContext } from '../../guard.js';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { FileView } from '../../reader/view.js';\nimport { lineOfNode } from '../../support/ast.js';\nimport {\n namesProblem,\n reviewedProblems,\n loaderProblem,\n type Loader,\n textProblem,\n} from '../../support/facts.js';\nimport { CORE_CODE, coreBuild, filesIn, isCount, topLevelDeclaration } from './shared.js';\nimport { REPOSITORY_GUARD_TIMEOUT_MS } from '../../support/timeouts.js';\n\ntype ReviewedCounts = ReadonlyArray<{\n file: string;\n declaration: string;\n count: number;\n why: string;\n}>;\ntype FieldSchema = { safeParse: (value: unknown) => { success: boolean; data?: unknown } };\n\n// A method, so the app's own reader — typed on its declaration type — fits it as declared, and the\n// guard hands it the declarations it loaded from that same module.\ninterface FieldSchemaOf {\n schemaOf(declaration: unknown): FieldSchema;\n}\n\nexport interface TextFieldDeclarationFacts {\n wireFolders: readonly string[];\n declarationsFile: string;\n wireInputNameSuffixes: readonly string[];\n selfBounded: ReviewedCounts;\n undeclaredFreeText: ReviewedCounts;\n keepAsTyped: ReadonlyArray<{ declaration: string; why: string }>;\n declarations: Loader<Readonly<Record<string, unknown>>>;\n fieldSchema: Loader<FieldSchemaOf['schemaOf']>;\n}\n\nconst isZString = (node: ts.Node): node is ts.CallExpression =>\n ts.isCallExpression(node) &&\n ts.isPropertyAccessExpression(node.expression) &&\n node.expression.name.text === 'string' &&\n ts.isIdentifier(node.expression.expression) &&\n node.expression.expression.text === 'z';\n\nconst TEXT_LENGTH_CONSTANT = /^(MAX|MIN)_(?![A-Z0-9_]*_ID_LENGTH$)[A-Z0-9_]*LENGTH$/;\nconst FREE_TEXT_PROPERTY =\n /reason|message|text|note|comment|title|description|name|subject|caption|summary|statement|facts|letter|label|heading|body|query|content|suggestion|region|country|value|intro|points|strings|term/i;\nconst BUILT_IN_FORMAT_METHODS = new Set(['regex', 'url', 'email', 'uuid']);\n\nfunction chainedCalls(root: ts.CallExpression): ts.CallExpression[] {\n const calls: ts.CallExpression[] = [];\n let node: ts.Node = root;\n while (\n ts.isPropertyAccessExpression(node.parent) &&\n node.parent.expression === node &&\n ts.isCallExpression(node.parent.parent)\n ) {\n calls.push(node.parent.parent);\n node = node.parent.parent;\n }\n return calls;\n}\n\nconst methodOf = (call: ts.CallExpression) =>\n (call.expression as ts.PropertyAccessExpression).name.text;\n\ninterface Site {\n key: string;\n line: number;\n}\n\nexport function selfBoundedChains(file: FileView): Site[] {\n const sites: Site[] = [];\n const visit = (node: ts.Node): void => {\n if (isZString(node)) {\n const bounded = chainedCalls(node).some((call) => {\n const method = methodOf(call);\n if (method === 'trim') return true;\n if (method !== 'min' && method !== 'max') return false;\n const [argument] = call.arguments;\n return (\n argument !== undefined &&\n ts.isIdentifier(argument) &&\n TEXT_LENGTH_CONSTANT.test(argument.text)\n );\n });\n if (bounded)\n sites.push({\n key: `${file.path}#${topLevelDeclaration(node)}`,\n line: lineOfNode(file, node),\n });\n }\n ts.forEachChild(node, visit);\n };\n visit(file.sourceFile);\n return sites;\n}\n\nexport function undeclaredFreeText(\n file: FileView,\n isWireInput: (declaration: string) => boolean,\n): Site[] {\n const sites: Site[] = [];\n const visit = (node: ts.Node): void => {\n if (isZString(node)) {\n const declaration = topLevelDeclaration(node);\n const calls = chainedCalls(node);\n const outer: ts.Node = calls.length ? calls[calls.length - 1] : node;\n const parent = outer.parent;\n let property: string | null = null;\n if (parent && ts.isPropertyAssignment(parent))\n property = parent.name.getText(file.sourceFile);\n else if (\n parent &&\n ts.isCallExpression(parent) &&\n parent.parent &&\n ts.isPropertyAssignment(parent.parent)\n ) {\n property = parent.parent.name.getText(file.sourceFile);\n }\n const builtIn = calls.some((call) => BUILT_IN_FORMAT_METHODS.has(methodOf(call)));\n if (\n property !== null &&\n isWireInput(declaration) &&\n FREE_TEXT_PROPERTY.test(property) &&\n !builtIn\n ) {\n sites.push({ key: `${file.path}#${declaration}`, line: lineOfNode(file, node) });\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(file.sourceFile);\n return sites;\n}\n\nfunction compareReviewed(\n sites: readonly Site[],\n reviewed: ReviewedCounts,\n what: string,\n): Finding[] {\n const findings: Finding[] = [];\n const byKey = new Map<string, Site[]>();\n for (const site of sites) byKey.set(site.key, [...(byKey.get(site.key) ?? []), site]);\n const allowed = new Map(reviewed.map((e) => [`${e.file}#${e.declaration}`, e.count]));\n for (const [key, found] of byKey) {\n const count = allowed.get(key) ?? 0;\n const file = key.slice(0, key.indexOf('#'));\n for (const site of found.slice(count))\n findings.push({\n file,\n line: site.line,\n detail: `${what} in ${key.slice(key.indexOf('#') + 1)}${count ? ` beyond the ${count} reviewed` : ''}`,\n });\n }\n for (const [key, count] of allowed) {\n const found = byKey.get(key)?.length ?? 0;\n if (found < count)\n findings.push({\n file: key.slice(0, key.indexOf('#')),\n detail: `stale reviewed count for ${key}: reviewed ${count}, found ${found}`,\n });\n }\n return findings;\n}\n\ntype Declaration = { format?: unknown; min?: number; keepAsTyped?: unknown };\n\nconst FREE_TEXT_FORMAT = 'none';\nconst textDeclarations = (exports: Readonly<Record<string, unknown>>) =>\n Object.entries(exports).filter(\n (e): e is [string, Declaration] =>\n typeof e[1] === 'object' && e[1] !== null && 'format' in e[1],\n );\n\nconst reviewedCountProblems = (value: unknown, what: string, problems: string[]) =>\n reviewedProblems(value, what, problems, {\n key: 'file',\n id: (e) =>\n typeof e.declaration === 'string' && e.declaration.trim()\n ? `${e.file}#${e.declaration}`\n : undefined,\n idNames: 'declaration',\n extra(entry, label) {\n if (!isCount(entry.count)) problems.push(`${label}'s count must be a positive whole number`);\n },\n });\n\nexport const textFieldDeclarationsGuard: GenericGuardDefinition<TextFieldDeclarationFacts> = {\n id: 'textFieldDeclarations',\n absentWhen: \"the app's core declares no text field through input-format-core\",\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.wireFolders, 'wireFolders', problems);\n textProblem(facts?.declarationsFile, 'declarationsFile', problems);\n namesProblem(facts?.wireInputNameSuffixes, 'wireInputNameSuffixes', problems);\n reviewedCountProblems(facts?.selfBounded, 'selfBounded', problems);\n reviewedCountProblems(facts?.undeclaredFreeText, 'undeclaredFreeText', problems);\n reviewedProblems(facts?.keepAsTyped, 'keepAsTyped', problems, { key: 'declaration' });\n loaderProblem(facts?.declarations, 'declarations', problems);\n loaderProblem(facts?.fieldSchema, 'fieldSchema', problems);\n return problems;\n },\n build(facts) {\n const isWireInput = (name: string) => facts.wireInputNameSuffixes.some((s) => name.endsWith(s));\n const wireFiles = (context: GuardContext, findings: Finding[]) =>\n filesIn(context.files(CORE_CODE), facts.wireFolders, findings);\n return [\n {\n title: 'every free-text property of a core wire input is a declared text field',\n description:\n 'A wire input property that names free text (reason, message, title, …) reads its declared text field through ' +\n \"the core's field-schema builder, or carries a built-in format (.regex / .url / .email / .uuid). Wire text no \" +\n 'person types is a reviewed module#declaration count with why; a count that no longer matches fails.',\n timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,\n run(context) {\n const findings: Finding[] = [];\n const sites = wireFiles(context, findings).flatMap((f) =>\n undeclaredFreeText(f, isWireInput),\n );\n return [\n ...findings,\n ...compareReviewed(\n sites,\n facts.undeclaredFreeText,\n 'an undeclared free-text z.string() property',\n ),\n ];\n },\n },\n {\n title: 'no core wire schema trims or bounds a text field itself',\n description:\n 'A wire z.string() chain never trims itself or bounds itself by a text-length constant: that is a second ' +\n \"declaration of the field. Read the field's declaration through the core's field-schema builder. Wire text no \" +\n 'person types (stored values, fixed strings, ids, addresses) is a reviewed module#declaration count with why.',\n timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,\n run(context) {\n const findings: Finding[] = [];\n const sites = wireFiles(context, findings).flatMap(selfBoundedChains);\n return [\n ...findings,\n ...compareReviewed(sites, facts.selfBounded, 'a self-bounded z.string() chain'),\n ];\n },\n },\n {\n title: 'text fields are declared only in the core declarations module',\n description:\n 'defineInputFormat is called, and keepAsTyped is set, only in the one module that declares every text field, ' +\n 'so each field has one declaration. Move the declaration there and import it.',\n timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,\n run(context) {\n const findings: Finding[] = [];\n const files = context.files(CORE_CODE);\n if (!files.some((f) => f.path === facts.declarationsFile)) {\n findings.push({\n file: facts.declarationsFile,\n detail: 'the declarations module is not in the core build',\n });\n }\n for (const file of files) {\n if (file.path === facts.declarationsFile) continue;\n for (const m of file.code.matchAll(/\\bdefineInputFormat\\s*\\(|\\bkeepAsTyped\\b/g)) {\n findings.push({\n file: file.path,\n line: file.lineOf(m.index ?? 0),\n detail: `${m[0].replace(/\\s*\\($/, '')} outside the declarations module`,\n });\n }\n }\n return findings;\n },\n },\n {\n title: 'only the reviewed text fields keep their text as typed',\n description:\n 'Every declared text field is trimmed unless it is a reviewed keep-as-typed declaration with why (a legal or ' +\n 'statutory text whose exact characters matter). A declaration that newly keeps its text fails until reviewed, ' +\n 'and a reviewed one that no longer does is stale.',\n async run(context) {\n const findings: Finding[] = [];\n coreBuild(context, findings);\n const kept = new Set(\n textDeclarations(await facts.declarations())\n .filter(([, d]) => 'keepAsTyped' in d)\n .map(([n]) => n),\n );\n const reviewed = new Set(facts.keepAsTyped.map((e) => e.declaration));\n for (const name of [...kept].sort())\n if (!reviewed.has(name))\n findings.push({\n file: `(core) ${name}`,\n detail: 'keeps its text as typed without review',\n });\n for (const name of reviewed)\n if (!kept.has(name))\n findings.push({\n file: `(core) ${name}`,\n detail:\n 'stale keep-as-typed entry: the declaration no longer keeps its text, or is gone',\n });\n return findings;\n },\n },\n {\n title:\n 'every declared text field trims, one that holds words keeps one space for each run of spaces, and a required one refuses blank text',\n description:\n \"Each text field's wire schema, built from its declaration, refuses whitespace-only text when the field requires \" +\n 'text (min of 1 or more), and trims the text of every field that does not keep it as typed; a field whose format ' +\n \"holds words (every format but free text, 'none') keeps one space for a run of them — so the form, the wire, and the writer agree, and a \" +\n 'name spaced twice is never stored, searched, or reserved apart from the same name spaced once.',\n async run(context) {\n const findings: Finding[] = [];\n coreBuild(context, findings);\n const declarations = textDeclarations(await facts.declarations());\n const schemaOf = await facts.fieldSchema();\n if (!declarations.length)\n findings.push({\n file: facts.declarationsFile,\n detail: 'no text-field declaration was loaded',\n });\n for (const [name, declaration] of declarations) {\n const schema = schemaOf(declaration);\n const min = typeof declaration.min === 'number' ? declaration.min : 0;\n if (min >= 1 && schema.safeParse(' \\n\\t ').success)\n findings.push({\n file: `(core) ${name}`,\n detail: 'accepts whitespace-only text although the field requires text',\n });\n if ('keepAsTyped' in declaration) continue;\n const sample = 'a'.repeat(Math.max(min, 1));\n const parsed = schema.safeParse(` ${sample} `);\n if (!parsed.success || parsed.data !== sample)\n findings.push({ file: `(core) ${name}`, detail: 'does not trim its text' });\n if (declaration.format === FREE_TEXT_FORMAT) continue;\n const word = 'a'.repeat(Math.max(min - 2, 1));\n if (!schema.safeParse(`${word} a`).success) continue;\n const run = schema.safeParse(`${word} a`);\n if (!run.success || run.data !== `${word} a`)\n findings.push({\n file: `(core) ${name}`,\n detail: 'keeps a run of spaces instead of one space',\n });\n }\n return findings;\n },\n },\n ];\n },\n};\n"]}
1
+ {"version":3,"file":"text-field-declarations.js","sourceRoot":"","sources":["../../../src/modules/core-definitions/text-field-declarations.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript';\nimport type { Finding, GuardContext } from '../../guard.js';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { FileView } from '../../reader/view.js';\nimport { lineOfNode } from '../../support/ast.js';\nimport {\n namesProblem,\n reviewedProblems,\n loaderProblem,\n type Loader,\n textProblem,\n} from '../../support/facts.js';\nimport { CORE_CODE, coreBuild, filesIn, isCount, topLevelDeclaration } from './shared.js';\nimport { REPOSITORY_GUARD_TIMEOUT_MS } from '../../support/timeouts.js';\n\ntype ReviewedCounts = ReadonlyArray<{\n file: string;\n declaration: string;\n count: number;\n why: string;\n}>;\ntype FieldSchema = { safeParse: (value: unknown) => { success: boolean; data?: unknown } };\n\n// A method, so the app's own reader — typed on its declaration type — fits it as declared, and the\n// guard hands it the declarations it loaded from that same module.\ninterface FieldSchemaOf {\n schemaOf(declaration: unknown): FieldSchema;\n}\n\nexport interface TextFieldDeclarationFacts {\n wireFolders: readonly string[];\n declarationsFile: string;\n wireInputNameSuffixes: readonly string[];\n selfBounded: ReviewedCounts;\n undeclaredFreeText: ReviewedCounts;\n keepAsTyped: ReadonlyArray<{ declaration: string; why: string }>;\n declarations: Loader<Readonly<Record<string, unknown>>>;\n fieldSchema: Loader<FieldSchemaOf>;\n}\n\nconst isZString = (node: ts.Node): node is ts.CallExpression =>\n ts.isCallExpression(node) &&\n ts.isPropertyAccessExpression(node.expression) &&\n node.expression.name.text === 'string' &&\n ts.isIdentifier(node.expression.expression) &&\n node.expression.expression.text === 'z';\n\nconst TEXT_LENGTH_CONSTANT = /^(MAX|MIN)_(?![A-Z0-9_]*_ID_LENGTH$)[A-Z0-9_]*LENGTH$/;\nconst FREE_TEXT_PROPERTY =\n /reason|message|text|note|comment|title|description|name|subject|caption|summary|statement|facts|letter|label|heading|body|query|content|suggestion|region|country|value|intro|points|strings|term/i;\nconst BUILT_IN_FORMAT_METHODS = new Set(['regex', 'url', 'email', 'uuid']);\n\nfunction chainedCalls(root: ts.CallExpression): ts.CallExpression[] {\n const calls: ts.CallExpression[] = [];\n let node: ts.Node = root;\n while (\n ts.isPropertyAccessExpression(node.parent) &&\n node.parent.expression === node &&\n ts.isCallExpression(node.parent.parent)\n ) {\n calls.push(node.parent.parent);\n node = node.parent.parent;\n }\n return calls;\n}\n\nconst methodOf = (call: ts.CallExpression) =>\n (call.expression as ts.PropertyAccessExpression).name.text;\n\ninterface Site {\n key: string;\n line: number;\n}\n\nexport function selfBoundedChains(file: FileView): Site[] {\n const sites: Site[] = [];\n const visit = (node: ts.Node): void => {\n if (isZString(node)) {\n const bounded = chainedCalls(node).some((call) => {\n const method = methodOf(call);\n if (method === 'trim') return true;\n if (method !== 'min' && method !== 'max') return false;\n const [argument] = call.arguments;\n return (\n argument !== undefined &&\n ts.isIdentifier(argument) &&\n TEXT_LENGTH_CONSTANT.test(argument.text)\n );\n });\n if (bounded)\n sites.push({\n key: `${file.path}#${topLevelDeclaration(node)}`,\n line: lineOfNode(file, node),\n });\n }\n ts.forEachChild(node, visit);\n };\n visit(file.sourceFile);\n return sites;\n}\n\nexport function undeclaredFreeText(\n file: FileView,\n isWireInput: (declaration: string) => boolean,\n): Site[] {\n const sites: Site[] = [];\n const visit = (node: ts.Node): void => {\n if (isZString(node)) {\n const declaration = topLevelDeclaration(node);\n const calls = chainedCalls(node);\n const outer: ts.Node = calls.length ? calls[calls.length - 1] : node;\n const parent = outer.parent;\n let property: string | null = null;\n if (parent && ts.isPropertyAssignment(parent))\n property = parent.name.getText(file.sourceFile);\n else if (\n parent &&\n ts.isCallExpression(parent) &&\n parent.parent &&\n ts.isPropertyAssignment(parent.parent)\n ) {\n property = parent.parent.name.getText(file.sourceFile);\n }\n const builtIn = calls.some((call) => BUILT_IN_FORMAT_METHODS.has(methodOf(call)));\n if (\n property !== null &&\n isWireInput(declaration) &&\n FREE_TEXT_PROPERTY.test(property) &&\n !builtIn\n ) {\n sites.push({ key: `${file.path}#${declaration}`, line: lineOfNode(file, node) });\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(file.sourceFile);\n return sites;\n}\n\nfunction compareReviewed(\n sites: readonly Site[],\n reviewed: ReviewedCounts,\n what: string,\n): Finding[] {\n const findings: Finding[] = [];\n const byKey = new Map<string, Site[]>();\n for (const site of sites) byKey.set(site.key, [...(byKey.get(site.key) ?? []), site]);\n const allowed = new Map(reviewed.map((e) => [`${e.file}#${e.declaration}`, e.count]));\n for (const [key, found] of byKey) {\n const count = allowed.get(key) ?? 0;\n const file = key.slice(0, key.indexOf('#'));\n for (const site of found.slice(count))\n findings.push({\n file,\n line: site.line,\n detail: `${what} in ${key.slice(key.indexOf('#') + 1)}${count ? ` beyond the ${count} reviewed` : ''}`,\n });\n }\n for (const [key, count] of allowed) {\n const found = byKey.get(key)?.length ?? 0;\n if (found < count)\n findings.push({\n file: key.slice(0, key.indexOf('#')),\n detail: `stale reviewed count for ${key}: reviewed ${count}, found ${found}`,\n });\n }\n return findings;\n}\n\ntype Declaration = { format?: unknown; min?: number; keepAsTyped?: unknown };\n\nconst FREE_TEXT_FORMAT = 'none';\nconst textDeclarations = (exports: Readonly<Record<string, unknown>>) =>\n Object.entries(exports).filter(\n (e): e is [string, Declaration] =>\n typeof e[1] === 'object' && e[1] !== null && 'format' in e[1],\n );\n\nconst reviewedCountProblems = (value: unknown, what: string, problems: string[]) =>\n reviewedProblems(value, what, problems, {\n key: 'file',\n id: (e) =>\n typeof e.declaration === 'string' && e.declaration.trim()\n ? `${e.file}#${e.declaration}`\n : undefined,\n idNames: 'declaration',\n extra(entry, label) {\n if (!isCount(entry.count)) problems.push(`${label}'s count must be a positive whole number`);\n },\n });\n\nexport const textFieldDeclarationsGuard: GenericGuardDefinition<TextFieldDeclarationFacts> = {\n id: 'textFieldDeclarations',\n absentWhen: \"the app's core declares no text field through input-format-core\",\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.wireFolders, 'wireFolders', problems);\n textProblem(facts?.declarationsFile, 'declarationsFile', problems);\n namesProblem(facts?.wireInputNameSuffixes, 'wireInputNameSuffixes', problems);\n reviewedCountProblems(facts?.selfBounded, 'selfBounded', problems);\n reviewedCountProblems(facts?.undeclaredFreeText, 'undeclaredFreeText', problems);\n reviewedProblems(facts?.keepAsTyped, 'keepAsTyped', problems, { key: 'declaration' });\n loaderProblem(facts?.declarations, 'declarations', problems);\n loaderProblem(facts?.fieldSchema, 'fieldSchema', problems);\n return problems;\n },\n build(facts) {\n const isWireInput = (name: string) => facts.wireInputNameSuffixes.some((s) => name.endsWith(s));\n const wireFiles = (context: GuardContext, findings: Finding[]) =>\n filesIn(context.files(CORE_CODE), facts.wireFolders, findings);\n return [\n {\n title: 'every free-text property of a core wire input is a declared text field',\n description:\n 'A wire input property that names free text (reason, message, title, …) reads its declared text field through ' +\n \"the core's field-schema builder, or carries a built-in format (.regex / .url / .email / .uuid). Wire text no \" +\n 'person types is a reviewed module#declaration count with why; a count that no longer matches fails.',\n timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,\n run(context) {\n const findings: Finding[] = [];\n const sites = wireFiles(context, findings).flatMap((f) =>\n undeclaredFreeText(f, isWireInput),\n );\n return [\n ...findings,\n ...compareReviewed(\n sites,\n facts.undeclaredFreeText,\n 'an undeclared free-text z.string() property',\n ),\n ];\n },\n },\n {\n title: 'no core wire schema trims or bounds a text field itself',\n description:\n 'A wire z.string() chain never trims itself or bounds itself by a text-length constant: that is a second ' +\n \"declaration of the field. Read the field's declaration through the core's field-schema builder. Wire text no \" +\n 'person types (stored values, fixed strings, ids, addresses) is a reviewed module#declaration count with why.',\n timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,\n run(context) {\n const findings: Finding[] = [];\n const sites = wireFiles(context, findings).flatMap(selfBoundedChains);\n return [\n ...findings,\n ...compareReviewed(sites, facts.selfBounded, 'a self-bounded z.string() chain'),\n ];\n },\n },\n {\n title: 'text fields are declared only in the core declarations module',\n description:\n 'defineInputFormat is called, and keepAsTyped is set, only in the one module that declares every text field, ' +\n 'so each field has one declaration. Move the declaration there and import it.',\n timeoutMs: REPOSITORY_GUARD_TIMEOUT_MS,\n run(context) {\n const findings: Finding[] = [];\n const files = context.files(CORE_CODE);\n if (!files.some((f) => f.path === facts.declarationsFile)) {\n findings.push({\n file: facts.declarationsFile,\n detail: 'the declarations module is not in the core build',\n });\n }\n for (const file of files) {\n if (file.path === facts.declarationsFile) continue;\n for (const m of file.code.matchAll(/\\bdefineInputFormat\\s*\\(|\\bkeepAsTyped\\b/g)) {\n findings.push({\n file: file.path,\n line: file.lineOf(m.index ?? 0),\n detail: `${m[0].replace(/\\s*\\($/, '')} outside the declarations module`,\n });\n }\n }\n return findings;\n },\n },\n {\n title: 'only the reviewed text fields keep their text as typed',\n description:\n 'Every declared text field is trimmed unless it is a reviewed keep-as-typed declaration with why (a legal or ' +\n 'statutory text whose exact characters matter). A declaration that newly keeps its text fails until reviewed, ' +\n 'and a reviewed one that no longer does is stale.',\n async run(context) {\n const findings: Finding[] = [];\n coreBuild(context, findings);\n const kept = new Set(\n textDeclarations(await facts.declarations())\n .filter(([, d]) => 'keepAsTyped' in d)\n .map(([n]) => n),\n );\n const reviewed = new Set(facts.keepAsTyped.map((e) => e.declaration));\n for (const name of [...kept].sort())\n if (!reviewed.has(name))\n findings.push({\n file: `(core) ${name}`,\n detail: 'keeps its text as typed without review',\n });\n for (const name of reviewed)\n if (!kept.has(name))\n findings.push({\n file: `(core) ${name}`,\n detail:\n 'stale keep-as-typed entry: the declaration no longer keeps its text, or is gone',\n });\n return findings;\n },\n },\n {\n title:\n 'every declared text field trims, one that holds words keeps one space for each run of spaces, and a required one refuses blank text',\n description:\n \"Each text field's wire schema, built from its declaration, refuses whitespace-only text when the field requires \" +\n 'text (min of 1 or more), and trims the text of every field that does not keep it as typed; a field whose format ' +\n \"holds words (every format but free text, 'none') keeps one space for a run of them — so the form, the wire, and the writer agree, and a \" +\n 'name spaced twice is never stored, searched, or reserved apart from the same name spaced once.',\n async run(context) {\n const findings: Finding[] = [];\n coreBuild(context, findings);\n const declarations = textDeclarations(await facts.declarations());\n const reader = await facts.fieldSchema();\n if (!declarations.length)\n findings.push({\n file: facts.declarationsFile,\n detail: 'no text-field declaration was loaded',\n });\n for (const [name, declaration] of declarations) {\n const schema = reader.schemaOf(declaration);\n const min = typeof declaration.min === 'number' ? declaration.min : 0;\n if (min >= 1 && schema.safeParse(' \\n\\t ').success)\n findings.push({\n file: `(core) ${name}`,\n detail: 'accepts whitespace-only text although the field requires text',\n });\n if ('keepAsTyped' in declaration) continue;\n const sample = 'a'.repeat(Math.max(min, 1));\n const parsed = schema.safeParse(` ${sample} `);\n if (!parsed.success || parsed.data !== sample)\n findings.push({ file: `(core) ${name}`, detail: 'does not trim its text' });\n if (declaration.format === FREE_TEXT_FORMAT) continue;\n const word = 'a'.repeat(Math.max(min - 2, 1));\n if (!schema.safeParse(`${word} a`).success) continue;\n const run = schema.safeParse(`${word} a`);\n if (!run.success || run.data !== `${word} a`)\n findings.push({\n file: `(core) ${name}`,\n detail: 'keeps a run of spaces instead of one space',\n });\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.23",
3
+ "version": "0.1.24",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ttt-productions/ttt-packages.git",