/** * 0.19.0+ (slowcook#36) — TypeORM entity-graph extractor. Walks all * `**\/*.entity.ts` files containing `@Entity(...)` decorators and emits * a Mermaid ERD + per-entity summary table to * `.brewing/diagrams/entities.md`. * * Why: slowcook's existing `emitSchemaDiagram` only knows about * `supabase/migrations/*.sql`. Consumers on TypeORM (delgoosh, plus * any NestJS monorepo) get nothing from the brownfield-extract step, * leaving their slowcook agents (vibe / recipe / brew / chef / * investigate) without entity grounding. Hand-curated entities.md * is the workaround — this module replaces it with auto-extraction. * * Detection signal: any `*.entity.ts` file with `@Entity(` decorator. * (Skips `node_modules`, `dist`, `.next`, `coverage`.) * * Parser is regex-based — TypeORM decorators have a strict shape * across the ecosystem. Same approach as `ddlToMermaidErd` in * refine/mermaid.ts; no AST tooling needed. */ export interface TypeOrmColumn { /** TS property name (camelCase). */ property: string; /** SQL column name (snake_case, from `@Column({ name: 'snake_case' })`). */ columnName?: string; /** TypeORM column type ('uuid', 'text', 'enum', 'jsonb', etc.). */ columnType?: string; /** Whether the column is nullable. */ nullable?: boolean; /** TS type from the property declaration (for context). */ tsType?: string; /** JSDoc COLUMN-DESCRIPTION text, if present. */ description?: string; } export interface TypeOrmRelation { /** TS property name on the entity. */ property: string; /** Relation kind. */ kind: "ManyToOne" | "OneToOne" | "OneToMany" | "ManyToMany"; /** Target entity class name (the `() => User` part). */ target: string; /** Optional foreign-key column name from @JoinColumn. */ joinColumn?: string; } export interface TypeOrmEntity { /** Class name (PascalCase). */ className: string; /** SQL table name from `@Entity('table_name')`. Falls back to class name in snake_case if missing. */ tableName: string; /** Whether the class `extends BaseEntity`. */ extendsBaseEntity: boolean; /** Repo-relative path to the source file. */ sourcePath: string; /** JSDoc TABLE-DESCRIPTION text, if present. */ description?: string; columns: TypeOrmColumn[]; relations: TypeOrmRelation[]; } /** * Recursive walk under `root` collecting absolute file paths matching * the predicate. Skips EXCLUDED_DIRS at any depth. */ declare function walk(root: string, predicate: (path: string) => boolean): string[]; /** * Find all `*.entity.ts` files under `repoRoot` whose content contains * an `@Entity(` decorator. Returns paths sorted alphabetically for * deterministic output. */ export declare function findEntityFiles(repoRoot: string): string[]; /** * Parse one TypeORM entity source file. Returns null if no `@Entity` * decorator is found (defense-in-depth — findEntityFiles already * filtered). */ export declare function parseEntityFile(source: string, sourcePath: string): TypeOrmEntity | null; /** * Render one Mermaid `erDiagram` covering all entities + their * relations. For very large graphs (>40 entities) the diagram is hard * to read — but splitting by domain requires semantic knowledge we * don't have. We render one big ERD; consumers can grep for entities * they care about + use the per-entity table below for details. */ export declare function entitiesToMermaidErd(entities: TypeOrmEntity[]): string; /** * Render the per-entity summary table for the entities.md artifact. * Pairs with the Mermaid ERD above to give agents structured access * to the entity vocabulary. */ export declare function entitiesToSummaryTable(entities: TypeOrmEntity[]): string; /** * Full entities.md document body. Static header + conventions section * (drawn from delgoosh dogfood — these are the same conventions every * NestJS+TypeORM consumer follows) + the ERD + summary table. */ export declare function renderEntitiesMarkdown(entities: TypeOrmEntity[]): string; /** * Public entry — walks the repo, parses entities, returns the rendered * markdown body PLUS counts for the caller (which writes the file). * Skipped silently if no .entity.ts files with @Entity are found — * consumer probably uses Prisma / Drizzle / Supabase / raw SQL. */ export declare function buildEntitiesArtifact(repoRoot: string): { written: boolean; body?: string; entityCount?: number; relationCount?: number; fileCount?: number; skippedReason?: string; }; export declare const __testOnly__: { parseEntityFile: typeof parseEntityFile; walk: typeof walk; entitiesToMermaidErd: typeof entitiesToMermaidErd; entitiesToSummaryTable: typeof entitiesToSummaryTable; }; export {}; //# sourceMappingURL=emit-typeorm.d.ts.map