@docyrus/tanstack-db-generator
Version:
Code generator utilities for TanStack Query / Database integration with Docyrus API
96 lines (94 loc) • 3.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateEndpointCollections = generateEndpointCollections;
const fs_1 = require("fs");
const path_1 = require("path");
async function generateEndpointCollections(spec, endpointGroups, outputDir) {
// Generate individual collection files
for (const group of endpointGroups) {
const collectionContent = generateEndpointCollectionFile(group, spec);
const fileName = `${group.name}.collection.ts`;
(0, fs_1.writeFileSync)((0, path_1.join)(outputDir, fileName), collectionContent);
}
}
function generateEndpointCollectionFile(group, spec) {
const collectionName = `${toPascalCase(group.name)}Collection`;
const methods = group.endpoints.map(endpoint => {
return generateEndpointMethod(endpoint, spec);
}).join(',\n\n');
const imports = getImportTypes(group, spec);
const typeImports = imports.length > 0 ? `import type { ${imports.join(', ')} } from '../types';` : '';
return `// Generated collection for ${group.name}
import { apiClient } from '../../lib/api-client';
${typeImports}
export const ${collectionName} = {
${methods}
};
`;
}
function generateEndpointMethod(endpoint, spec) {
const methodName = endpoint.operationId;
const hasPathParams = endpoint.path.includes('{');
const pathParams = extractPathParams(endpoint.path);
// Build function parameters
const params = [];
if (hasPathParams) {
params.push(...pathParams.map(p => `${p}: string`));
}
if (endpoint.operation.requestBody) {
params.push('data: any');
}
// Generate path with replacements
let pathCode = `'${endpoint.path}'`;
if (hasPathParams) {
pathParams.forEach(param => {
pathCode = `${pathCode}.replace('{${param}}', ${param})`;
});
}
const method = endpoint.method.toLowerCase();
const hasData = endpoint.operation.requestBody;
return ` ${methodName}: (${params.join(', ')}) =>
apiClient.${method}(${pathCode}${hasData ? ', data' : ''})`;
}
function extractPathParams(path) {
const matches = path.match(/\{([^}]+)\}/g);
if (!matches)
return [];
return matches.map(m => m.slice(1, -1));
}
function getImportTypes(group, spec) {
const types = new Set();
for (const endpoint of group.endpoints) {
// Extract types from request/response schemas
const refs = extractRefsFromOperation(endpoint.operation);
refs.forEach(ref => {
const typeName = ref.split('/').pop();
if (typeName)
types.add(typeName);
});
}
return Array.from(types);
}
function extractRefsFromOperation(operation) {
const refs = [];
// From request body
if (operation.requestBody?.content?.['application/json']?.schema?.$ref) {
refs.push(operation.requestBody.content['application/json'].schema.$ref);
}
// From responses
Object.values(operation.responses || {}).forEach((response) => {
if (response.content?.['application/json']?.schema?.$ref) {
refs.push(response.content['application/json'].schema.$ref);
}
// Check nested data property
if (response.content?.['application/json']?.schema?.properties?.data?.$ref) {
refs.push(response.content['application/json'].schema.properties.data.$ref);
}
});
return refs;
}
function toPascalCase(str) {
return str.split(/[_-]/)
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
.join('');
}