Something went wrong. Try again.
fork of hey-api/openapi-ts because I need some additional things
Something went wrong. Try again.
5.5 kB · 218 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219import path from 'node:path';
import type { ExportModule, ImportModule } from '../bindings';import { fileBrand } from '../brands';import type { Language } from '../languages/types';import { log } from '../log';import type { INode } from '../nodes/node';import type { NameScopes } from '../planner/scope';import type { IProject } from '../project/types';import type { Renderer } from '../renderer';import type { IFileIn } from './types';
export class File<Node extends INode = INode> { /** * Exports from this file. */ private _exports: Array<ExportModule> = []; /** * File extension (e.g. `.ts`). */ private _extension?: string; /** * Actual emitted file path, including extension and directories. */ private _finalPath?: string; /** * Imports to this file. */ private _imports: Array<ImportModule> = []; /** * Language of the file. */ private _language?: Language; /** * Logical, extension-free path used for planning and routing. */ private _logicalFilePath: string; /** * Base name of the file (without extension). */ private _name?: string; /** * Syntax nodes contained in this file. */ private _nodes: Array<Node> = []; /** * Renderer assigned to this file. */ private _renderer?: Renderer;
/** Brand used for identifying files. */ readonly '~brand' = fileBrand; /** All names defined in this file, including local scopes. */ allNames: NameScopes = new Map(); /** Whether this file is external to the project. */ external: boolean; /** Unique identifier for the file. */ readonly id: number; /** The project this file belongs to. */ readonly project: IProject; /** Names declared at the top level of the file. */ topLevelNames: NameScopes = new Map();
constructor(input: IFileIn, id: number, project: IProject) { this.external = input.external ?? false; this.id = id; if (input.language !== undefined) this._language = input.language; this._logicalFilePath = input.logicalFilePath.split(path.sep).join('/'); if (input.name !== undefined) this._name = input.name; this.project = project; }
/** * Exports from this file. */ get exports(): ReadonlyArray<ExportModule> { return [...this._exports]; }
/** * Read-only accessor for the file extension. */ get extension(): string | undefined { if (this.external) return; if (this._extension) return this._extension; const language = this.language; const extension = language ? this.project.extensions[language] : undefined; if (extension && extension[0]) return extension[0]; return; }
/** * Read-only accessor for the final emitted path. * * If undefined, the file has not yet been assigned a final path * or is external to the project and should not be emitted. */ get finalPath(): string | undefined { if (this._finalPath) return this._finalPath; const dirs = this._logicalFilePath ? this._logicalFilePath.split('/').slice(0, -1) : []; return [...dirs, `${this.name}${this.extension ?? ''}`].join('/'); }
/** * Imports to this file. */ get imports(): ReadonlyArray<ImportModule> { return [...this._imports]; }
/** * Language of the file; inferred from nodes or fallback if not set explicitly. */ get language(): Language | undefined { if (this._language) return this._language; if (this._nodes[0]) return this._nodes[0].language; return; }
/** * Logical, extension-free path used for planning and routing. */ get logicalFilePath(): string { return this._logicalFilePath; }
/** * Base name of the file (without extension). * * If no name was set explicitly, it is inferred from the logical file path. */ get name(): string { if (this._name) return this._name; const name = this._logicalFilePath.split('/').pop(); if (name) return name; const message = `File ${this.toString()} has no name`; log.debug(message, 'file'); throw new Error(message); }
/** * Syntax nodes contained in this file. */ get nodes(): ReadonlyArray<Node> { return [...this._nodes]; }
/** * Renderer assigned to this file. */ get renderer(): Renderer | undefined { return this._renderer; }
/** * Add an export group to the file. */ addExport(group: ExportModule): void { this._exports.push(group); }
/** * Add an import group to the file. */ addImport(group: ImportModule): void { this._imports.push(group); }
/** * Add a syntax node to the file. */ addNode(node: Node): void { this._nodes.push(node); node.file = this; }
/** * Sets the file extension. */ setExtension(extension: string): void { this._extension = extension; }
/** * Sets the final emitted path of the file. */ setFinalPath(path: string): void { this._finalPath = path; }
/** * Sets the language of the file. */ setLanguage(lang: Language): void { this._language = lang; }
/** * Sets the name of the file. */ setName(name: string): void { this._name = name; }
/** * Sets the renderer assigned to this file. */ setRenderer(renderer: Renderer): void { this._renderer = renderer; }
/** * Returns a debug‑friendly string representation identifying the file. */ toString(): string { return `[File ${this._logicalFilePath}#${this.id}]`; }}