Skip to content

Commit

Permalink
feat: introduce plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
toomuchdesign committed Sep 14, 2023
1 parent 3a83352 commit 568c2b9
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 1 deletion.
62 changes: 62 additions & 0 deletions src/plugins/generateRefTypesAsArrayPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { makeRelativePath, formatTypeScript, saveFile } from '../utils';
import type { Plugin, SchemaMetaData } from '../types';

const FILE_NAME = 'refTypesAsArray.ts';

const generateRefTypesAsArrayPlugin: Plugin = async ({
outputPath,
metaData,
}) => {
const refs: SchemaMetaData[] = [];
metaData.schemas.forEach((schema) => {
if (schema.isRef) {
refs.push(schema);
}
});

if (refs.length === 0) {
return;
}

const schemas = refs.map(
({ schemaAbsoluteImportPath, schemaUniqueName, schemaId }) => {
return {
importPath: makeRelativePath({
fromDirectory: outputPath,
to: schemaAbsoluteImportPath,
}),
schemaUniqueName,
schemaId,
};
},
);

let output = '';

schemas.forEach((schema) => {
output += `\n import ${schema.schemaUniqueName} from "${schema.importPath}";`;
});

output += '\n\n';

schemas.forEach((schema) => {
output += `\n const ${schema.schemaUniqueName}WithId = {...${schema.schemaUniqueName}, $id: "${schema.schemaId}"} as const;`;
});

output += `\n\n
type RefTypes = [
${schemas
.map((schema) => `typeof ${schema.schemaUniqueName}WithId`)
.join(',')}
];`;

output += '\n\nexport default RefTypes';

const formattedOutput = await formatTypeScript(output);
await saveFile({
path: [outputPath, FILE_NAME],
data: formattedOutput,
});
};

export default generateRefTypesAsArrayPlugin;
Empty file added src/plugins/types.ts
Empty file.
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ export type SchemaMetaDataMap = Map<
string, // Schema file relative path
SchemaMetaData
>;

export type Plugin = (args: {
outputPath: string;
metaData: { schemas: SchemaMetaDataMap };
}) => Promise<void>;
1 change: 0 additions & 1 deletion test/dereferencing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import fs from 'fs/promises';
import { describe, it, expect } from 'vitest';
import { importFresh } from './test-utils';
import { openapiToTsJsonSchema } from '../src';
import { formatTypeScript } from '../src/utils';

const fixtures = path.resolve(__dirname, 'fixtures');

Expand Down
58 changes: 58 additions & 0 deletions test/plugins/generateRefTypesAsArrayPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import path from 'path';
import fs from 'fs/promises';
import { describe, it, expect } from 'vitest';
import { openapiToTsJsonSchema } from '../../src';
import generateRefTypesAsArrayPlugin from '../../src/plugins/generateRefTypesAsArrayPlugin';
import { importFresh } from '../test-utils';
import { formatTypeScript } from '../../src/utils';

const fixtures = path.resolve(__dirname, '../fixtures');

describe('generateRefTypesAsArrayPlugin plugin', async () => {
it('generates expected file', async () => {
const { outputPath, metaData } = await openapiToTsJsonSchema({
openApiSchema: path.resolve(fixtures, 'complex/specs.yaml'),
definitionPathsToGenerateFrom: ['components.months', 'paths'],
experimentalImportRefs: true,
silent: false,
});

await generateRefTypesAsArrayPlugin({ outputPath, metaData });

const actual = await fs.readFile(
path.resolve(outputPath, 'refTypesAsArray.ts'),
{
encoding: 'utf8',
},
);

// @TODO find a better way to assert against generated types
const expected = await formatTypeScript(`
import componentsSchemasAnswer from "./components/schemas/Answer";
import componentsMonthsJanuary from "./components/months/January";
import componentsMonthsFebruary from "./components/months/February";
const componentsSchemasAnswerWithId = {
...componentsSchemasAnswer,
$id: "#/components/schemas/Answer",
} as const;
const componentsMonthsJanuaryWithId = {
...componentsMonthsJanuary,
$id: "#/components/months/January",
} as const;
const componentsMonthsFebruaryWithId = {
...componentsMonthsFebruary,
$id: "#/components/months/February",
} as const;
type RefTypes = [
typeof componentsSchemasAnswerWithId,
typeof componentsMonthsJanuaryWithId,
typeof componentsMonthsFebruaryWithId,
];
export default RefTypes;`);

expect(actual).toBe(expected);
});
});

0 comments on commit 568c2b9

Please sign in to comment.