@apistudio/apim-cli
Version:
CLI for API Management Products
170 lines (138 loc) ⢠4.73 kB
JavaScript
/**
* Script to sync exports from api-model-kinds_generated.ts to api-model-kinds-exports.ts
*
* Usage:
* node packages/inventory/src/resources/scripts/sync-exports.js
*
* Or add to package.json scripts:
* "sync-exports": "node src/resources/scripts/sync-exports.js"
*/
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// Get __dirname equivalent in ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Configuration
const CONFIG = {
sourceFile: path.join(__dirname, '../../api-model-kinds_generated.ts'),
targetFile: path.join(__dirname, '../../api-model-kinds-exports.ts'),
};
/**
* Extract schema names from the generated TypeScript file
* @param {string} filePath - Path to the source file
* @returns {string[]} Array of schema names
*/
function extractSchemaNames(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf-8');
// Find the schemas section - look for "schemas: {" and capture until the matching closing brace
const lines = content.split('\n');
const schemaNames = [];
let inSchemas = false;
let braceCount = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// Check if we're entering the schemas section
if (line.trim().startsWith('schemas:')) {
inSchemas = true;
braceCount = 0;
continue;
}
if (inSchemas) {
// Count braces to track nesting
for (const char of line) {
if (char === '{') braceCount++;
if (char === '}') braceCount--;
}
// If we're back to 0 braces, we've exited the schemas section
if (braceCount < 0) {
break;
}
// Look for schema definitions at the top level (indentation level 8 spaces or 2 tabs)
// Pattern: " SchemaName: {" or " SchemaName: {"
const match = line.match(/^\s{8}(\w+):\s*\{/);
if (match && braceCount === 1) {
schemaNames.push(match[1]);
}
}
}
return schemaNames.sort();
} catch (error) {
console.error(`Error reading file ${filePath}:`, error.message);
throw error;
}
}
/**
* Generate the exports file content
* @param {string[]} schemaNames - Array of schema names
* @returns {string} Generated file content
*/
function generateExportsContent(schemaNames) {
const header = `/**
* Auto-generated exports from api-model-kinds_generated.ts
*
* This file is automatically generated by sync-exports.js
* Do not edit manually - run 'npm run sync-exports' to regenerate
*
* Generated on: ${new Date().toISOString()}
*/
import { components } from './api-model-kinds_generated.js';
// Export individual schema types
`;
const typeExports = schemaNames
.map(name => `export type ${name} = components['schemas']['${name}'];`)
.join('\n');
const schemasObject = `
// Export a convenience object that contains all schemas
export const Schemas = {
${schemaNames.map(name => ` ${name}: {} as ${name},`).join('\n')}
};
`;
return header + typeExports + schemasObject;
}
/**
* Write content to the target file
* @param {string} filePath - Path to the target file
* @param {string} content - Content to write
*/
function writeExportsFile(filePath, content) {
try {
// Create directory if it doesn't exist
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(filePath, content, 'utf-8');
console.log(`ā
Successfully wrote exports to: ${filePath}`);
} catch (error) {
console.error(`Error writing file ${filePath}:`, error.message);
throw error;
}
}
/**
* Main function to sync exports
*/
function syncExports() {
console.log('š Starting export sync...\n');
console.log(`š Reading schemas from: ${CONFIG.sourceFile}`);
const schemaNames = extractSchemaNames(CONFIG.sourceFile);
if (schemaNames.length === 0) {
console.error('ā No schemas found in the source file');
process.exit(1);
}
console.log(`⨠Found ${schemaNames.length} schemas:\n`);
schemaNames.forEach((name, index) => {
console.log(` ${index + 1}. ${name}`);
});
console.log(`\nš Generating exports file...`);
const content = generateExportsContent(schemaNames);
console.log(`š¾ Writing to: ${CONFIG.targetFile}`);
writeExportsFile(CONFIG.targetFile, content);
console.log('\nā
Export sync completed successfully!');
}
// Run the script
syncExports();
export { syncExports, extractSchemaNames, generateExportsContent };
// Made with Bob