import { assert, assertEquals } from "@std/assert"; import type { TransformationDiagnostic } from "../src/mod.ts"; import { validateFiles, validateSource } from "./utils.ts"; import { COMMONFABRIC_TYPES } from "./commonfabric-test-types.ts"; /** * Exercises the branches of the WriteAuthorizedBy validation transformer that * the existing cfc-authoring tests do not reach: property-access `toSchema` * call sites, non-identifier `typeof` bindings, recursion guards while walking * local type declarations, index-signature traversal, the generic type-argument * substitution over array/union/intersection/operator/parenthesized shapes, and * the initializer-unwrapping loop that sees through parentheses and assertions. */ async function cfcDiagnostics( source: string, ): Promise { const { diagnostics } = await validateSource(source, { types: COMMONFABRIC_TYPES, }); return diagnostics.filter((diagnostic) => diagnostic.type === "cfc-write-authorized-by" ); } Deno.test( "property-access toSchema call site is validated for WriteAuthorizedBy", async () => { const source = `/// import { WriteAuthorizedBy } from "commonfabric"; declare const ns: { toSchema(): unknown }; const arbitrary = 123; const schema = ns.toSchema< WriteAuthorizedBy<{ title: string }, typeof arbitrary> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert( diagnostics[0]!.message.includes( "handler(), module(), requireEventIntegrity()", ), ); }, ); Deno.test( "typeof of a qualified name reports the simple-identifier requirement", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const container = { saver() {} }; const schema = toSchema< WriteAuthorizedBy<{ title: string }, typeof container.saver> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert(diagnostics[0]!.message.includes("simple identifier binding")); }, ); Deno.test( "index-signature members of a referenced interface are traversed for bindings", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; interface Bag { [key: string]: WriteAuthorizedBy<{ title: string }, typeof arbitrary>; } const schema = toSchema(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert( diagnostics[0]!.message.includes( "handler(), module(), requireEventIntegrity()", ), ); }, ); Deno.test( "self-referential type alias terminates and still reports the binding error", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Recursive = { self?: Recursive; write: WriteAuthorizedBy<{ title: string }, typeof arbitrary>; }; const schema = toSchema(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); // // The substitution walker's branches // // These cases place the generic alias parameter *inside* the schema type // argument of WriteAuthorizedBy, wrapped in a distinct type shape. When the // validator substitutes the actual type into the alias parameter, it must // descend through that shape to rebuild the WriteAuthorizedBy reference. The // cases pin the walker's branches — array, union with parenthesization, // intersection, type operator, index signature, and a type literal with // non-property members — and each asserts the binding is still validated // afterward. // Deno.test( "generic alias substitutes schema through array element types", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Wrap = { write: WriteAuthorizedBy; }; const schema = toSchema>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); Deno.test( "generic alias substitutes schema through union and parenthesized types", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Wrap = { write: WriteAuthorizedBy<(T | undefined), typeof arbitrary>; }; const schema = toSchema>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); Deno.test( "generic alias substitutes schema through intersection types", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Wrap = { write: WriteAuthorizedBy; }; const schema = toSchema>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); Deno.test( "generic alias substitutes schema through readonly type-operator types", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Wrap = { write: WriteAuthorizedBy; }; const schema = toSchema>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); Deno.test( "generic alias substitutes schema through index-signature member types", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Wrap = { write: WriteAuthorizedBy<{ [key: string]: T }, typeof arbitrary>; }; const schema = toSchema>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); Deno.test( "generic alias substitutes schema literals with non-property members", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Wrap = { write: WriteAuthorizedBy<{ payload: T; describe(): string }, typeof arbitrary>; }; const schema = toSchema>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); // // A binding the walker never has to enter // // The parentheses and assertions here wrap the binding VALUE, not a type, so // no substitution happens and the walker is not reached at all. // Deno.test( "supported binding wrapped in parentheses and assertions is accepted", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; declare function handler(fn: (event: E, state: S) => void): () => void; const saver = (handler((_e, _s) => {}) as unknown)!; const schema = toSchema< WriteAuthorizedBy<{ title: string }, typeof saver> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 0); }, ); Deno.test( "a foreign constructor's type arguments are not writer claims", async () => { // `Map` generates no cell schema; its unresolved `Binding` is not a defect. const source = `/// import { WriteAuthorizedBy } from "commonfabric"; export function empty() { return new Map>(); } `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 0); }, ); Deno.test( "a cell constructor's type arguments are writer claims", async () => { const source = `/// import { Writable, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; export const cell = new Writable< WriteAuthorizedBy >(""); `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert(diagnostics[0]!.message.includes("only supports handler()")); }, ); Deno.test( "a writer declared in a declaration file is refused", async () => { const { diagnostics } = await validateFiles({ "/main.tsx": `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; import { ambient } from "./ambient.d.ts"; const schema = toSchema< WriteAuthorizedBy<{ title: string }, typeof ambient> >(); export { schema }; `, "/ambient.d.ts": "export declare function ambient(): void;", }, { types: COMMONFABRIC_TYPES }); const cfc = diagnostics.filter((diagnostic) => diagnostic.type === "cfc-write-authorized-by" ); assertEquals(cfc.length, 1); assert(cfc[0]!.message.includes("authored module")); }, ); Deno.test( "a policy carried by a declaration file's alias is validated", async () => { // The generator resolves the alias and would emit its claim; the writer // it names has no provenance, so the claim is refused here instead. const { diagnostics } = await validateFiles({ "/main.tsx": `/// import { toSchema } from "commonfabric"; import type { Guarded } from "./guarded.d.ts"; const schema = toSchema(); export { schema }; `, "/guarded.d.ts": `import type { WriteAuthorizedBy } from "commonfabric"; export declare function ambient(): void; export type Guarded = WriteAuthorizedBy<{ title: string }, typeof ambient>;`, }, { types: COMMONFABRIC_TYPES }); const cfc = diagnostics.filter((diagnostic) => diagnostic.type === "cfc-write-authorized-by" ); assertEquals(cfc.length, 1); assert(cfc[0]!.message.includes("authored module")); }, ); Deno.test( "a module-level writer is found when a local of the same name shadows it", async () => { // A name scan of the file would have found the module-level handler and // accepted the claim; the claim names the local. const source = `/// import { handler, toSchema, WriteAuthorizedBy } from "commonfabric"; const saver = handler((_e, _s) => {}); export function schemaFor() { const saver = 123; return toSchema>(); } `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert(diagnostics[0]!.message.includes("only supports handler()")); }, ); // A namespace-qualified policy is the policy the schema generator reads, so // its claim is validated like one written by name, and a writer built through // the namespace is supported like one built by name. for ( const [spelling, declarations, reference] of [ ["written in place", "", "cf.WriteAuthorizedBy"], [ "through a plain alias", "type Guarded = cf.WriteAuthorizedBy;", "Guarded", ], [ "through a generic alias's binding parameter", "type Guarded = cf.WriteAuthorizedBy;", "Guarded", ], ] as const ) { for ( const [binding, refused] of [["arbitrary", true], ["saver", false]] as const ) { Deno.test( `a namespace-qualified policy ${spelling} ${ refused ? "refuses" : "accepts" } ${binding}`, async () => { const source = `/// import * as cf from "commonfabric"; const saver = cf.handler((_e, _s) => {}); const arbitrary = 123; ${declarations.replaceAll("BINDING", binding)} const schema = cf.toSchema<${ reference.replaceAll("BINDING", binding) }>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, refused ? 1 : 0); if (refused) { assert(diagnostics[0]!.message.includes("only supports handler()")); } }, ); } } Deno.test( "a builder-named member of an object that is not a Common Fabric namespace is not a writer", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const unrelated = { handler: (_fn: unknown) => () => {} }; const saver = unrelated.handler((_e: unknown, _s: unknown) => {}); const schema = toSchema< WriteAuthorizedBy<{ title: string }, typeof saver> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert(diagnostics[0]!.message.includes("only supports handler()")); }, ); // A builder named on a namespace from anywhere but Common Fabric is not one: // a local object, another module, or a declaration file that re-exports a // namespace under the library's names. for ( const [label, imports, files] of [ [ "a namespace import of another module", `import * as other from "./other.ts";`, { "/other.ts": "export const handler = (fn: () => void) => fn;" }, ], [ "a named Common Fabric import, which is a value and not the namespace", `import { pattern as other } from "commonfabric";`, {}, ], [ "a namespace a declaration file re-exports", `import { other } from "./other.d.ts";`, { "/other.d.ts": `import * as impl from "./impl.ts";\nexport { impl as other };`, "/impl.ts": "export const handler = (fn: () => void) => fn;", }, ], ] as const ) { Deno.test(`a builder called through ${label} is not a writer`, async () => { const { diagnostics } = await validateFiles({ "/main.tsx": `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; ${imports} const saver = (other as any).handler(() => {}); const schema = toSchema< WriteAuthorizedBy<{ title: string }, typeof saver> >(); export { schema }; `, ...files, }, { types: COMMONFABRIC_TYPES }); const cfc = diagnostics.filter((diagnostic) => diagnostic.type === "cfc-write-authorized-by" ); assertEquals(cfc.length, 1); assert(cfc[0]!.message.includes("only supports handler()")); }); } Deno.test( "a builder called through a namespace an authored module re-exports from Common Fabric is a writer", async () => { const { diagnostics } = await validateFiles({ "/main.tsx": `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; import { cf } from "./barrel.ts"; const saver = cf.handler((_e, _s) => {}); const schema = toSchema< WriteAuthorizedBy<{ title: string }, typeof saver> >(); export { schema }; `, "/barrel.ts": `export * as cf from "commonfabric";`, }, { types: COMMONFABRIC_TYPES }); assertEquals( diagnostics.filter((diagnostic) => diagnostic.type === "cfc-write-authorized-by" ), [], ); }, ); Deno.test( "a WritePolicyAnyOf member's binding is validated like a lone one's", async () => { const source = `/// import { handler, toSchema, TrustedActionWrite, WriteAuthorizedBy, WritePolicyAnyOf, } from "commonfabric"; const send = handler(() => {}); const arbitrary = 123; const schema = toSchema< WritePolicyAnyOf, WriteAuthorizedBy, ]> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert( diagnostics[0]!.message.includes( "handler(), module(), requireEventIntegrity()", ), ); }, ); Deno.test( "a WritePolicyAnyOf whose members all name handlers reports nothing", async () => { const source = `/// import { handler, toSchema, TrustedActionWrite, WritePolicyAnyOf, } from "commonfabric"; const send = handler(() => {}); const edit = handler(() => {}); const schema = toSchema< WritePolicyAnyOf, TrustedActionWrite, ]> >(); export { schema }; `; assertEquals(await cfcDiagnostics(source), []); }, ); Deno.test( "an author's alias named CfcTag is walked like any other alias", async () => { const source = `/// import { toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type CfcTag = T; const schema = toSchema< CfcTag, {}> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert( diagnostics[0]!.message.includes( "handler(), module(), requireEventIntegrity()", ), ); }, ); Deno.test( "a carrier whose payload only its tag holds has the payload's writer validated", async () => { // A `Cfc` that does not also intersect its payload with its tag holds // that payload in the tag alone, so the tag is walked whole. const source = `/// import { toSchema, type WriteAuthorizedBy } from "commonfabric"; type CfcTag = { readonly __ct_cfc__?: { readonly meta?: M; readonly of?: T }; }; type Cfc = CfcTag; const arbitrary = 123; const schema = toSchema< Cfc, {}> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert( diagnostics[0]!.message.includes( "handler(), module(), requireEventIntegrity()", ), ); }, ); Deno.test( "a carrier whose payload only its tag holds accepts a supported writer", async () => { const source = `/// import { handler, toSchema, type WriteAuthorizedBy } from "commonfabric"; type CfcTag = { readonly __ct_cfc__?: { readonly meta?: M; readonly of?: T }; }; type Cfc = CfcTag; const saver = handler((_e, _s) => {}); const schema = toSchema< Cfc, {}> >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 0); }, ); Deno.test( "a policy inside a CFC carrier's payload is reported once", async () => { const source = `/// import { Confidential, toSchema, WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; const schema = toSchema< Confidential< WriteAuthorizedBy<{ title: string }, typeof arbitrary>, ["secret"] > >(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); }, ); Deno.test( "a policy a type parameter's default names is validated where the reference leaves it out", async () => { const source = `/// import { toSchema, type WriteAuthorizedBy } from "commonfabric"; const arbitrary = 123; type Guarded> = P; const schema = toSchema>(); export { schema }; `; const diagnostics = await cfcDiagnostics(source); assertEquals(diagnostics.length, 1); assert( diagnostics[0]!.message.includes( "handler(), module(), requireEventIntegrity()", ), ); }, );