@schematicos/codegen@0.0.35
latest
SchematicOS/codegenIt is unknown whether this package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers
JSR Score
41%
Published
5 months ago (0.0.35)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230import type { ParseContext } from './ParseContext.ts' import { GenerateContext } from './GenerateContext.ts' import type { ToTypeSystemArgs, RegisterArgs } from './GenerateContext.ts' import type { ReportArgs, Reporter } from './Reporter.ts' import { match } from 'npm:ts-pattern@5.1.1' import type { PrettierConfigType } from '../schematic-types/prettierConfig.ts' import type { Stringable } from '../dsl/Stringable.ts' import type { TypeSystem } from '../schematic-types/plugins.ts' import type { OasDocument } from '../oas-elements/Document.ts' import type { Settings } from '../settings/Settings.ts' import { RenderContext } from './RenderContext.ts' import type { FileContents, RenderOptions } from './types.ts' type SharedContext = | { type: 'parse' context: ParseContext } | { type: 'group' context: GenerateContext } | { type: 'render' context: RenderContext } type GenerateArgs = { schemaModel: OasDocument settings: Settings typeSystem: TypeSystem } type CoreContextArgs = { phase: SharedContext reporter: Reporter } type RenderArgs = { files: Map<string, FileContents> prettier?: PrettierConfigType } export class CoreContext { reporter: Reporter private phase: SharedContext private constructor({ phase, reporter }: CoreContextArgs) { this.phase = phase this.reporter = reporter } static create({ phase, reporter }: CoreContextArgs): CoreContext { return new CoreContext({ phase, reporter }) } setupGeneratePhase({ schemaModel, settings, typeSystem }: GenerateArgs) { const generateContext = GenerateContext.create({ schemaModel, settings, typeSystem, reporter: this.reporter }) this.phase = { type: 'group', context: generateContext } } setupRenderPhase({ files, prettier }: RenderArgs) { const renderContext = RenderContext.create({ files, prettier, reporter: this.reporter }) this.phase = { type: 'render', context: renderContext } } private report({ level, trail, message }: Omit<ReportArgs, 'phase'>) { this.reporter.report({ level, phase: this.phase.type, trail, message }) } error(args: Omit<ReportArgs, 'level' | 'phase'>): never { this.report({ ...args, level: 'error' }) throw new Error(args.message) } info(args: Omit<ReportArgs, 'level' | 'phase'>): void { this.report({ ...args, level: 'info' }) } warn(args: Omit<ReportArgs, 'level' | 'phase'>): void { this.report({ ...args, level: 'warn' }) } register({ destinationPath, ...args }: RegisterArgs): void { return match(this.phase) .with({ type: 'group' }, ({ context }) => { return context.register({ destinationPath, ...args }) }) .with({ type: 'parse' }, () => { throw new Error('Cannot register in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot register in render phase') }) .exhaustive() } getFile(filePath: string): FileContents { return match(this.phase) .with({ type: 'group' }, ({ context }) => { return context.getFile(filePath) }) .with({ type: 'parse' }, () => { throw new Error('Cannot get file in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot get file in render phase') }) .exhaustive() } async render(options: RenderOptions): Promise<Record<string, string>> { return await match(this.phase) .with({ type: 'group' }, () => { throw new Error('Cannot render in parse phase') }) .with({ type: 'parse' }, () => { throw new Error('Cannot render in parse phase') }) .with({ type: 'render' }, ({ context }) => context.render(options)) .exhaustive() } addFile(normalisedPath: string): FileContents { return match(this.phase) .with({ type: 'group' }, ({ context }) => { return context.addFile(normalisedPath) }) .with({ type: 'parse' }, () => { throw new Error('Cannot add file in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot add file in render phase') }) .exhaustive() } toTypeSystem({ value, required, destinationPath }: ToTypeSystemArgs): Stringable { return match(this.phase) .with({ type: 'group' }, ({ context }) => { return context.toTypeSystem({ value, required, destinationPath }, this) }) .with({ type: 'parse' }, () => { throw new Error('Cannot access type system in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot access type system in render phase') }) .exhaustive() } toInferType(value: Stringable): Stringable { return match(this.phase) .with({ type: 'group' }, ({ context }) => { return context.toInferType(value, this) }) .with({ type: 'parse' }, () => { throw new Error('Cannot access type system in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot access type system in render phase') }) .exhaustive() } get files(): Map<string, FileContents> { return match(this.phase) .with({ type: 'group' }, ({ context }) => context.files) .with({ type: 'parse' }, () => { throw new Error('Cannot access files in parse phase') }) .with({ type: 'render' }, ({ context }) => context.files) .exhaustive() } get schemaModel(): OasDocument { return match(this.phase) .with({ type: 'group' }, ({ context }) => context.schemaModel) .with({ type: 'parse' }, () => { throw new Error('Cannot access schema model in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot access schema model in render phase') }) .exhaustive() } get settings(): Settings { return match(this.phase) .with({ type: 'group' }, ({ context }) => context.settings) .with({ type: 'parse' }, () => { throw new Error('Cannot access settings in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot access settings in render phase') }) .exhaustive() } get typeSystemInfo(): Omit<TypeSystem, 'create'> { return match(this.phase) .with({ type: 'group' }, ({ context }) => context.typeSystemInfo) .with({ type: 'parse' }, () => { throw new Error('Cannot access type system in parse phase') }) .with({ type: 'render' }, () => { throw new Error('Cannot access type system in render phase') }) .exhaustive() } }