Skip to main content
It is unknown whether this package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers
It is unknown whether this package works with Cloudflare Workers
It is unknown whether this package works with Node.js
It is unknown whether this package works with Deno
It is unknown whether this package works with Bun
It is unknown whether this package works with Browsers
JSR Score
41%
Published
5 months ago (0.0.35)
Package root>context>CoreContext.ts
import 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() } }