import { writeFile } from 'fs/promises'; import getSpecs from './specs.js'; type Method = "POST" | "DELETE" | "UPDATE" | "GET" interface Param { name: string required: boolean type: string } type Api = { method: Method, endpoint?: string, return: string, params: Param[] name?: '#update' | '#post' | "#delete" | "#get" } interface Field { name: string, type: string } interface Spec { apis: Api[] fields: Field[] } async function main() { const { nodes, enum_types } = await getSpecs() const enumTypesFormatted = enum_types.map(type => `type ${type.name} = "${type.values.join('" | "')}"`) const specs = Object.entries(nodes).map(([key, node]) => makeSpec(node, key).join('\n')) const first = ["// @ts-nocheck", "import {map, list, bool, float, int, datetime, uint, rootParamsAnd, FormatParams4Input, Field, Connection, BaseQuery} from './imports.js'"].join('\n') writeFile('./export/index.ts', `${first}\n${enumTypesFormatted.join('\n')}\n${specs.join('\n')}`) } function makeSpec(spec: Spec, specName: string) { const res: string[] = [] const rootReqs: string[] = [] const childReqs: { [key: string]: typeof rootReqs } = {} const connections: string[] = [] spec.apis.map(({ endpoint, params, method, return: returning }) => { const _method = method.toLocaleLowerCase() if (returning !== 'Object' && params.some((v) => v.name === 'fields') === false) params.push({ name: 'fields', required: true, type: `${returning}` }) const EXTENDING = `${specName}${endpoint ? `$${endpoint}` : ''}$${_method}` res.push(`interface ${EXTENDING} { ${params.map(({ name, required, type }) => `${name}${required ? '' : '?'}: ${formatType(type)}`)} }`) if (!endpoint) { rootReqs.push(`${_method} = async , outParams = rootParamsAnd<${EXTENDING}>>(params: inParams) => BaseQuery.${_method}(params, this.id${endpoint ? `+'/${endpoint}'` : ''})`) } else { const fn = `${_method}: async , outParams = rootParamsAnd<${EXTENDING}>>(params: inParams) => BaseQuery.${_method}(params, this.id${endpoint ? `+'/${endpoint}'` : ''})` // @ts-expect-error if (childReqs[endpoint]) { childReqs[endpoint].push(fn) } else { childReqs[endpoint] = [fn] } if (method == "GET") { connections.push(`${endpoint}: Connection<${specName}$${endpoint}$get>`) } } }) res.push(`interface ${specName}$Fields { ${spec.fields.map(({ name, type }) => `"${name}": Field<${formatType(type)}>`).join(', ')} }`) res.push(`interface ${specName}$Connections { ${connections.join(', ')} }`) res.push(`type ${specName} = ${specName}$Fields & ${specName}$Connections`) const queryClass = `export class ${specName}Query extends BaseQuery {\n ${rootReqs.join('\n ')}\n${Object.entries(childReqs).map(([key, items]) => ` ${key} = {\n ${items.join(',\n ')}\n }`).join('\n')}\n}` if (spec.apis.length) res.push(queryClass) return res } function formatType(str: string) { return str.replaceAll('unsigned int', 'uint') } main()