| | import yaml from 'js-yaml' |
| | import dereferenceJsonSchema from 'dereference-json-schema' |
| | import { existsSync } from 'fs' |
| | import { readFile, readdir } from 'fs/promises' |
| |
|
| | |
| | |
| | |
| | interface OpenAPISchema { |
| | openapi?: string |
| | info?: any |
| | servers?: any[] |
| | paths?: Record<string, Record<string, any>> |
| | [key: string]: any |
| | } |
| |
|
| | export const MODELS_GATEWAY_ROOT = 'models-gateway' |
| | const MODELS_GATEWAY_PATH = 'docs/api' |
| |
|
| | |
| | |
| | |
| | |
| | export async function injectModelsSchema(schema: any, schemaName: string): Promise<any> { |
| | if (!schemaName.includes('fpt')) { |
| | return schema |
| | } |
| |
|
| | const modelEndpoints = ( |
| | await readdir(`./${MODELS_GATEWAY_ROOT}/${MODELS_GATEWAY_PATH}`, { |
| | recursive: true, |
| | }) |
| | ).filter((name) => name.endsWith('.yaml') || name.endsWith('.yml')) |
| |
|
| | for (let endpointPath of modelEndpoints) { |
| | endpointPath = `./${MODELS_GATEWAY_ROOT}/${MODELS_GATEWAY_PATH}/${endpointPath}` |
| | if (!existsSync(endpointPath)) { |
| | console.warn( |
| | `⚠️ Models gateway YAML file not found at ${endpointPath}. Skipping injection for ${schemaName}.`, |
| | ) |
| | continue |
| | } |
| |
|
| | const yamlContent = await readFile(endpointPath, 'utf8') |
| | const loadedYaml = yaml.load(yamlContent) as { |
| | openapi: string |
| | info: any |
| | servers: any[] |
| | paths: { [x: string]: any } |
| | } |
| | const deferencedYaml = dereferenceJsonSchema.dereferenceSync(loadedYaml) |
| |
|
| | |
| | |
| | const openApiYaml = deferencedYaml as OpenAPISchema |
| | schema.openapi = schema.openapi || openApiYaml.openapi |
| | schema.info = schema.info || openApiYaml.info |
| | schema.servers = schema.servers || openApiYaml.servers |
| |
|
| | |
| | for (const path of Object.keys(openApiYaml.paths || {})) { |
| | for (const operation of Object.keys(openApiYaml.paths![path])) { |
| | const operationObject = openApiYaml.paths![path][operation] |
| |
|
| | |
| | const name = operationObject.summary || '' |
| | const description = operationObject.description || '' |
| | const category = operationObject['x-github']?.category || 'models' |
| |
|
| | console.log(`⏳ Processing operation: ${name} (${path} ${operation})`) |
| |
|
| | |
| | |
| | const enhancedOperation = { |
| | ...operationObject, |
| | operationId: operationObject.operationId, |
| | tags: operationObject.tags || ['models'], |
| | verb: operation, |
| | requestPath: path, |
| | category, |
| | subcategory: operationObject['x-github']?.subcategory || '', |
| | summary: name, |
| | description, |
| | 'x-github': { |
| | ...operationObject['x-github'], |
| | category, |
| | enabledForGitHubApps: operationObject['x-github']?.enabledForGitHubApps, |
| | githubCloudOnly: operationObject['x-github']?.githubCloudOnly, |
| | permissions: operationObject['x-github']?.permissions || {}, |
| | externalDocs: operationObject['x-github']?.externalDocs || {}, |
| | }, |
| | parameters: operationObject.parameters || [], |
| | responses: { |
| | ...operationObject.responses, |
| | '200': operationObject.responses?.['200'], |
| | }, |
| | } |
| |
|
| | |
| | |
| | if (openApiYaml.servers) { |
| | enhancedOperation.servers = openApiYaml.servers |
| | } |
| |
|
| | |
| | schema.paths[path] = schema.paths[path] || {} |
| | schema.paths[path][operation] = enhancedOperation |
| |
|
| | console.log(`✅ Processed operation: ${name} (${path} ${operation})`) |
| | } |
| | } |
| | } |
| |
|
| | return schema |
| | } |
| |
|