mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
- Creating async await compatible version
This commit is contained in:
parent
216804e892
commit
4ceabd8bba
13
.babelrc.js
13
.babelrc.js
@ -2,7 +2,14 @@
|
||||
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@babel/preset-env',
|
||||
'@babel/preset-typescript'
|
||||
]
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
esmodules: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
};
|
||||
|
||||
@ -32,5 +32,12 @@ if (OpenAPI) {
|
||||
exportServices: program.exportServices,
|
||||
exportModels: program.exportModels,
|
||||
exportSchemas: program.exportSchemas,
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
process.exit(0);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ export default {
|
||||
file: './dist/index.js',
|
||||
format: 'cjs',
|
||||
},
|
||||
external: ['fs', 'os', ...external],
|
||||
external: ['fs', 'os', 'util', ...external],
|
||||
plugins: [
|
||||
handlebarsPlugin(),
|
||||
typescript({
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import * as OpenAPI from '.';
|
||||
|
||||
describe('index', () => {
|
||||
it('parses v2 without issues', () => {
|
||||
OpenAPI.generate({
|
||||
it('parses v2 without issues', async () => {
|
||||
await OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
useOptions: true,
|
||||
@ -11,8 +11,8 @@ describe('index', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('parses v3 without issues', () => {
|
||||
OpenAPI.generate({
|
||||
it('parses v3 without issues', async () => {
|
||||
await OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
useOptions: true,
|
||||
|
||||
53
src/index.ts
53
src/index.ts
@ -4,7 +4,7 @@ import { getOpenApiSpec } from './utils/getOpenApiSpec';
|
||||
import { getOpenApiVersion, OpenApiVersion } from './utils/getOpenApiVersion';
|
||||
import { isString } from './utils/isString';
|
||||
import { postProcessClient } from './utils/postProcessClient';
|
||||
import { readHandlebarsTemplates } from './utils/readHandlebarsTemplates';
|
||||
import { registerHandlebarsTemplates } from './utils/registerHandlebarsTemplates';
|
||||
import { writeClient } from './utils/writeClient';
|
||||
|
||||
export enum HttpClient {
|
||||
@ -40,7 +40,7 @@ export interface Options {
|
||||
* @param exportSchemas: Generate schemas.
|
||||
* @param write Write the files to disk (true or false).
|
||||
*/
|
||||
export function generate({
|
||||
export async function generate({
|
||||
input,
|
||||
output,
|
||||
httpClient = HttpClient.FETCH,
|
||||
@ -51,35 +51,30 @@ export function generate({
|
||||
exportModels = true,
|
||||
exportSchemas = false,
|
||||
write = true,
|
||||
}: Options): void {
|
||||
try {
|
||||
// Load the specification, read the OpenAPI version and load the
|
||||
// handlebar templates for the given language
|
||||
const openApi = isString(input) ? getOpenApiSpec(input) : input;
|
||||
const openApiVersion = getOpenApiVersion(openApi);
|
||||
const templates = readHandlebarsTemplates();
|
||||
}: Options): Promise<void> {
|
||||
// Load the specification, read the OpenAPI version and load the
|
||||
// handlebar templates for the given language
|
||||
const openApi = isString(input) ? await getOpenApiSpec(input) : input;
|
||||
const openApiVersion = getOpenApiVersion(openApi);
|
||||
const templates = registerHandlebarsTemplates();
|
||||
|
||||
switch (openApiVersion) {
|
||||
case OpenApiVersion.V2: {
|
||||
const client = parseV2(openApi);
|
||||
const clientFinal = postProcessClient(client, useUnionTypes);
|
||||
if (write) {
|
||||
writeClient(clientFinal, templates, output, httpClient, useOptions, exportCore, exportServices, exportModels, exportSchemas);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenApiVersion.V3: {
|
||||
const client = parseV3(openApi);
|
||||
const clientFinal = postProcessClient(client, useUnionTypes);
|
||||
if (write) {
|
||||
writeClient(clientFinal, templates, output, httpClient, useOptions, exportCore, exportServices, exportModels, exportSchemas);
|
||||
}
|
||||
break;
|
||||
switch (openApiVersion) {
|
||||
case OpenApiVersion.V2: {
|
||||
const client = parseV2(openApi);
|
||||
const clientFinal = postProcessClient(client, useUnionTypes);
|
||||
if (write) {
|
||||
await writeClient(clientFinal, templates, output, httpClient, useOptions, exportCore, exportServices, exportModels, exportSchemas);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenApiVersion.V3: {
|
||||
const client = parseV3(openApi);
|
||||
const clientFinal = postProcessClient(client, useUnionTypes);
|
||||
if (write) {
|
||||
await writeClient(clientFinal, templates, output, httpClient, useOptions, exportCore, exportServices, exportModels, exportSchemas);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
6
src/utils/__mocks__/fileSystem.ts
Normal file
6
src/utils/__mocks__/fileSystem.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export const readFile = jest.fn();
|
||||
export const writeFile = jest.fn();
|
||||
export const copyFile = jest.fn();
|
||||
export const exists = jest.fn();
|
||||
export const rmdir = jest.fn();
|
||||
export const mkdir = jest.fn();
|
||||
25
src/utils/fileSystem.ts
Normal file
25
src/utils/fileSystem.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import * as fs from 'fs';
|
||||
import * as mkdirp from 'mkdirp';
|
||||
import rimraf from 'rimraf';
|
||||
import * as util from 'util';
|
||||
|
||||
// Wrapped file system calls
|
||||
export const readFile = util.promisify(fs.readFile);
|
||||
export const writeFile = util.promisify(fs.writeFile);
|
||||
export const copyFile = util.promisify(fs.copyFile);
|
||||
export const exists = util.promisify(fs.exists);
|
||||
|
||||
// Re-export from mkdirp to make mocking easier
|
||||
export const mkdir = mkdirp;
|
||||
|
||||
// Promisified version of rimraf
|
||||
export const rmdir = (path: string) =>
|
||||
new Promise((resolve, reject) => {
|
||||
rimraf(path, (error: Error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,24 +1,27 @@
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { exists, readFile } from './fileSystem';
|
||||
import { getOpenApiSpec } from './getOpenApiSpec';
|
||||
|
||||
jest.mock('fs');
|
||||
jest.mock('./fileSystem');
|
||||
|
||||
const fsExistsSync = fs.existsSync as jest.MockedFunction<typeof fs.existsSync>;
|
||||
const fsReadFileSync = fs.readFileSync as jest.MockedFunction<typeof fs.readFileSync>;
|
||||
const existsMocked = exists as jest.MockedFunction<typeof exists>;
|
||||
const readFileMocked = readFile as jest.MockedFunction<typeof readFile>;
|
||||
|
||||
function mockPromise<T>(value: T): Promise<T> {
|
||||
return new Promise<T>(resolve => resolve(value));
|
||||
}
|
||||
|
||||
describe('getOpenApiSpec', () => {
|
||||
it('should read the json file', () => {
|
||||
fsExistsSync.mockReturnValue(true);
|
||||
fsReadFileSync.mockReturnValue('{"message": "Hello World!"}');
|
||||
const spec = getOpenApiSpec('spec.json');
|
||||
it('should read the json file', async () => {
|
||||
existsMocked.mockReturnValue(mockPromise(true));
|
||||
readFileMocked.mockReturnValue(mockPromise('{"message": "Hello World!"}'));
|
||||
const spec = await getOpenApiSpec('spec.json');
|
||||
expect(spec.message).toEqual('Hello World!');
|
||||
});
|
||||
|
||||
it('should read the yaml file', () => {
|
||||
fsExistsSync.mockReturnValue(true);
|
||||
fsReadFileSync.mockReturnValue('message: "Hello World!"');
|
||||
const spec = getOpenApiSpec('spec.yaml');
|
||||
it('should read the yaml file', async () => {
|
||||
existsMocked.mockReturnValue(mockPromise(true));
|
||||
readFileMocked.mockReturnValue(mockPromise('message: "Hello World!"'));
|
||||
const spec = await getOpenApiSpec('spec.yaml');
|
||||
expect(spec.message).toEqual('Hello World!');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
import * as fs from 'fs';
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as path from 'path';
|
||||
|
||||
import { exists, readFile } from './fileSystem';
|
||||
|
||||
/**
|
||||
* Check if given file exists and try to read the content as string.
|
||||
* @param filePath
|
||||
*/
|
||||
function read(filePath: string): string {
|
||||
if (fs.existsSync(filePath)) {
|
||||
async function read(filePath: string): Promise<string> {
|
||||
const fileExists = await exists(filePath);
|
||||
if (fileExists) {
|
||||
try {
|
||||
return fs.readFileSync(filePath, 'utf8').toString();
|
||||
const content = await readFile(filePath, 'utf8');
|
||||
return content.toString();
|
||||
} catch (e) {
|
||||
throw new Error(`Could not read OpenApi spec: "${filePath}"`);
|
||||
}
|
||||
@ -23,10 +26,10 @@ function read(filePath: string): string {
|
||||
* on parsing the file as JSON.
|
||||
* @param input
|
||||
*/
|
||||
export function getOpenApiSpec(input: string): any {
|
||||
export async function getOpenApiSpec(input: string): Promise<any> {
|
||||
const file = path.resolve(process.cwd(), input);
|
||||
const extname = path.extname(file).toLowerCase();
|
||||
const content = read(file);
|
||||
const content = await read(file);
|
||||
switch (extname) {
|
||||
case '.yml':
|
||||
case '.yaml':
|
||||
|
||||
@ -41,7 +41,7 @@ export interface Templates {
|
||||
* Read all the Handlebar templates that we need and return on wrapper object
|
||||
* so we can easily access the templates in out generator / write functions.
|
||||
*/
|
||||
export function readHandlebarsTemplates(): Templates {
|
||||
export function registerHandlebarsTemplates(): Templates {
|
||||
registerHandlebarHelpers();
|
||||
|
||||
const templates: Templates = {
|
||||
@ -1,22 +1,13 @@
|
||||
import * as fs from 'fs';
|
||||
import * as mkdirp from 'mkdirp';
|
||||
import * as rimraf from 'rimraf';
|
||||
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { HttpClient } from '../index';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { mkdir, rmdir, writeFile } from './fileSystem';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
import { writeClient } from './writeClient';
|
||||
|
||||
jest.mock('rimraf');
|
||||
jest.mock('mkdirp');
|
||||
jest.mock('fs');
|
||||
|
||||
const rimrafSync = mkdirp.sync as jest.MockedFunction<typeof mkdirp.sync>;
|
||||
const mkdirpSync = rimraf.sync as jest.MockedFunction<typeof rimraf.sync>;
|
||||
const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeFileSync>;
|
||||
jest.mock('./fileSystem');
|
||||
|
||||
describe('writeClient', () => {
|
||||
it('should write to filesystem', () => {
|
||||
it('should write to filesystem', async () => {
|
||||
const client: Client = {
|
||||
server: 'http://localhost:8080',
|
||||
version: 'v1',
|
||||
@ -32,10 +23,10 @@ describe('writeClient', () => {
|
||||
settings: () => 'dummy',
|
||||
};
|
||||
|
||||
writeClient(client, templates, '/', HttpClient.FETCH, false, true, true, true, true);
|
||||
await writeClient(client, templates, '/', HttpClient.FETCH, false, true, true, true, true);
|
||||
|
||||
expect(rimrafSync).toBeCalled();
|
||||
expect(mkdirpSync).toBeCalled();
|
||||
expect(fsWriteFileSync).toBeCalled();
|
||||
expect(rmdir).toBeCalled();
|
||||
expect(mkdir).toBeCalled();
|
||||
expect(writeFile).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,19 +1,17 @@
|
||||
import * as fs from 'fs';
|
||||
import * as mkdirp from 'mkdirp';
|
||||
import * as path from 'path';
|
||||
import * as rimraf from 'rimraf';
|
||||
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { HttpClient } from '../index';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { copyFile, mkdir, rmdir } from './fileSystem';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
import { writeClientIndex } from './writeClientIndex';
|
||||
import { writeClientModels } from './writeClientModels';
|
||||
import { writeClientSchemas } from './writeClientSchemas';
|
||||
import { writeClientServices } from './writeClientServices';
|
||||
import { writeClientSettings } from './writeClientSettings';
|
||||
|
||||
function copySupportFile(filePath: string, outputPath: string): void {
|
||||
fs.copyFileSync(path.resolve(__dirname, `../src/templates/${filePath}`), path.resolve(outputPath, filePath));
|
||||
async function copySupportFile(filePath: string, outputPath: string): Promise<void> {
|
||||
await copyFile(path.resolve(__dirname, `../src/templates/${filePath}`), path.resolve(outputPath, filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,7 +26,7 @@ function copySupportFile(filePath: string, outputPath: string): void {
|
||||
* @param exportModels: Generate models.
|
||||
* @param exportSchemas: Generate schemas.
|
||||
*/
|
||||
export function writeClient(
|
||||
export async function writeClient(
|
||||
client: Client,
|
||||
templates: Templates,
|
||||
output: string,
|
||||
@ -38,7 +36,7 @@ export function writeClient(
|
||||
exportServices: boolean,
|
||||
exportModels: boolean,
|
||||
exportSchemas: boolean
|
||||
): void {
|
||||
): Promise<void> {
|
||||
const outputPath = path.resolve(process.cwd(), output);
|
||||
const outputPathCore = path.resolve(outputPath, 'core');
|
||||
const outputPathModels = path.resolve(outputPath, 'models');
|
||||
@ -46,38 +44,38 @@ export function writeClient(
|
||||
const outputPathServices = path.resolve(outputPath, 'services');
|
||||
|
||||
// Clean output directory
|
||||
rimraf.sync(outputPath);
|
||||
mkdirp.sync(outputPath);
|
||||
await rmdir(outputPath);
|
||||
await mkdir(outputPath);
|
||||
|
||||
if (exportCore) {
|
||||
mkdirp.sync(outputPathCore);
|
||||
copySupportFile('core/ApiError.ts', outputPath);
|
||||
copySupportFile('core/getFormData.ts', outputPath);
|
||||
copySupportFile('core/getQueryString.ts', outputPath);
|
||||
copySupportFile('core/isSuccess.ts', outputPath);
|
||||
copySupportFile('core/request.ts', outputPath);
|
||||
copySupportFile('core/RequestOptions.ts', outputPath);
|
||||
copySupportFile('core/requestUsingFetch.ts', outputPath);
|
||||
copySupportFile('core/requestUsingXHR.ts', outputPath);
|
||||
copySupportFile('core/Result.ts', outputPath);
|
||||
await mkdir(outputPathCore);
|
||||
await copySupportFile('core/ApiError.ts', outputPath);
|
||||
await copySupportFile('core/getFormData.ts', outputPath);
|
||||
await copySupportFile('core/getQueryString.ts', outputPath);
|
||||
await copySupportFile('core/isSuccess.ts', outputPath);
|
||||
await copySupportFile('core/request.ts', outputPath);
|
||||
await copySupportFile('core/RequestOptions.ts', outputPath);
|
||||
await copySupportFile('core/requestUsingFetch.ts', outputPath);
|
||||
await copySupportFile('core/requestUsingXHR.ts', outputPath);
|
||||
await copySupportFile('core/Result.ts', outputPath);
|
||||
}
|
||||
|
||||
if (exportServices) {
|
||||
mkdirp.sync(outputPathServices);
|
||||
writeClientSettings(client, templates, outputPathCore, httpClient);
|
||||
writeClientServices(client.services, templates, outputPathServices, useOptions);
|
||||
await mkdir(outputPathServices);
|
||||
await writeClientSettings(client, templates, outputPathCore, httpClient);
|
||||
await writeClientServices(client.services, templates, outputPathServices, useOptions);
|
||||
}
|
||||
|
||||
if (exportSchemas) {
|
||||
mkdirp.sync(outputPathSchemas);
|
||||
writeClientSchemas(client.models, templates, outputPathSchemas);
|
||||
await mkdir(outputPathSchemas);
|
||||
await writeClientSchemas(client.models, templates, outputPathSchemas);
|
||||
}
|
||||
|
||||
if (exportModels) {
|
||||
mkdirp.sync(outputPathModels);
|
||||
copySupportFile('models/Dictionary.ts', outputPath);
|
||||
writeClientModels(client.models, templates, outputPathModels);
|
||||
await mkdir(outputPathModels);
|
||||
await copySupportFile('models/Dictionary.ts', outputPath);
|
||||
await writeClientModels(client.models, templates, outputPathModels);
|
||||
}
|
||||
|
||||
writeClientIndex(client, templates, outputPath, exportCore, exportModels, exportServices, exportSchemas);
|
||||
await writeClientIndex(client, templates, outputPath, exportCore, exportModels, exportServices, exportSchemas);
|
||||
}
|
||||
|
||||
@ -1,15 +1,12 @@
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
import { writeClientIndex } from './writeClientIndex';
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeFileSync>;
|
||||
jest.mock('./fileSystem');
|
||||
|
||||
describe('writeClientIndex', () => {
|
||||
it('should write to filesystem', () => {
|
||||
it('should write to filesystem', async () => {
|
||||
const client: Client = {
|
||||
server: 'http://localhost:8080',
|
||||
version: '1.0',
|
||||
@ -25,8 +22,8 @@ describe('writeClientIndex', () => {
|
||||
settings: () => 'dummy',
|
||||
};
|
||||
|
||||
writeClientIndex(client, templates, '/', true, true, true, true);
|
||||
await writeClientIndex(client, templates, '/', true, true, true, true);
|
||||
|
||||
expect(fsWriteFileSync).toBeCalledWith('/index.ts', 'dummy');
|
||||
expect(writeFile).toBeCalledWith('/index.ts', 'dummy');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { getModelNames } from './getModelNames';
|
||||
import { getServiceNames } from './getServiceNames';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
|
||||
/**
|
||||
* Generate the OpenAPI client index file using the Handlebar template and write it to disk.
|
||||
@ -18,8 +18,16 @@ import { Templates } from './readHandlebarsTemplates';
|
||||
* @param exportModels: Generate models.
|
||||
* @param exportSchemas: Generate schemas.
|
||||
*/
|
||||
export function writeClientIndex(client: Client, templates: Templates, outputPath: string, exportCore: boolean, exportServices: boolean, exportModels: boolean, exportSchemas: boolean): void {
|
||||
fs.writeFileSync(
|
||||
export async function writeClientIndex(
|
||||
client: Client,
|
||||
templates: Templates,
|
||||
outputPath: string,
|
||||
exportCore: boolean,
|
||||
exportServices: boolean,
|
||||
exportModels: boolean,
|
||||
exportSchemas: boolean
|
||||
): Promise<void> {
|
||||
await writeFile(
|
||||
path.resolve(outputPath, 'index.ts'),
|
||||
templates.index({
|
||||
exportCore,
|
||||
|
||||
@ -1,15 +1,12 @@
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
import { writeClientModels } from './writeClientModels';
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeFileSync>;
|
||||
jest.mock('./fileSystem');
|
||||
|
||||
describe('writeClientModels', () => {
|
||||
it('should write to filesystem', () => {
|
||||
it('should write to filesystem', async () => {
|
||||
const models: Model[] = [
|
||||
{
|
||||
export: 'interface',
|
||||
@ -39,8 +36,8 @@ describe('writeClientModels', () => {
|
||||
settings: () => 'dummy',
|
||||
};
|
||||
|
||||
writeClientModels(models, templates, '/');
|
||||
await writeClientModels(models, templates, '/');
|
||||
|
||||
expect(fsWriteFileSync).toBeCalledWith('/Item.ts', 'dummy');
|
||||
expect(writeFile).toBeCalledWith('/Item.ts', 'dummy');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { format } from './format';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
|
||||
/**
|
||||
* Generate Models using the Handlebar template and write to disk.
|
||||
@ -11,10 +11,10 @@ import { Templates } from './readHandlebarsTemplates';
|
||||
* @param templates The loaded handlebar templates.
|
||||
* @param outputPath Directory to write the generated files to.
|
||||
*/
|
||||
export function writeClientModels(models: Model[], templates: Templates, outputPath: string): void {
|
||||
models.forEach(model => {
|
||||
export async function writeClientModels(models: Model[], templates: Templates, outputPath: string): Promise<void> {
|
||||
for (const model of models) {
|
||||
const file = path.resolve(outputPath, `${model.name}.ts`);
|
||||
const templateResult = templates.model(model);
|
||||
fs.writeFileSync(file, format(templateResult));
|
||||
});
|
||||
await writeFile(file, format(templateResult));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,11 @@
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
import { writeClientModels } from './writeClientModels';
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeFileSync>;
|
||||
|
||||
jest.mock('./fileSystem');
|
||||
describe('writeClientModels', () => {
|
||||
it('should write to filesystem', () => {
|
||||
it('should write to filesystem', async () => {
|
||||
const models: Model[] = [
|
||||
{
|
||||
export: 'interface',
|
||||
@ -39,8 +35,8 @@ describe('writeClientModels', () => {
|
||||
settings: () => 'dummy',
|
||||
};
|
||||
|
||||
writeClientModels(models, templates, '/');
|
||||
await writeClientModels(models, templates, '/');
|
||||
|
||||
expect(fsWriteFileSync).toBeCalledWith('/Item.ts', 'dummy');
|
||||
expect(writeFile).toBeCalledWith('/Item.ts', 'dummy');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { format } from './format';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
|
||||
/**
|
||||
* Generate Schemas using the Handlebar template and write to disk.
|
||||
@ -11,10 +11,10 @@ import { Templates } from './readHandlebarsTemplates';
|
||||
* @param templates The loaded handlebar templates.
|
||||
* @param outputPath Directory to write the generated files to.
|
||||
*/
|
||||
export function writeClientSchemas(models: Model[], templates: Templates, outputPath: string): void {
|
||||
models.forEach(model => {
|
||||
export async function writeClientSchemas(models: Model[], templates: Templates, outputPath: string): Promise<void> {
|
||||
for (const model of models) {
|
||||
const file = path.resolve(outputPath, `$${model.name}.ts`);
|
||||
const templateResult = templates.schema(model);
|
||||
fs.writeFileSync(file, format(templateResult));
|
||||
});
|
||||
await writeFile(file, format(templateResult));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,11 @@
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
import { writeClientServices } from './writeClientServices';
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeFileSync>;
|
||||
|
||||
jest.mock('./fileSystem');
|
||||
describe('writeClientServices', () => {
|
||||
it('should write to filesystem', () => {
|
||||
it('should write to filesystem', async () => {
|
||||
const services: Service[] = [
|
||||
{
|
||||
name: 'Item',
|
||||
@ -26,8 +22,8 @@ describe('writeClientServices', () => {
|
||||
settings: () => 'dummy',
|
||||
};
|
||||
|
||||
writeClientServices(services, templates, '/', false);
|
||||
await writeClientServices(services, templates, '/', false);
|
||||
|
||||
expect(fsWriteFileSync).toBeCalledWith('/Item.ts', 'dummy');
|
||||
expect(writeFile).toBeCalledWith('/Item.ts', 'dummy');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { format } from './format';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
|
||||
/**
|
||||
* Generate Services using the Handlebar template and write to disk.
|
||||
@ -12,13 +12,13 @@ import { Templates } from './readHandlebarsTemplates';
|
||||
* @param outputPath Directory to write the generated files to.
|
||||
* @param useOptions Use options or arguments functions.
|
||||
*/
|
||||
export function writeClientServices(services: Service[], templates: Templates, outputPath: string, useOptions: boolean): void {
|
||||
services.forEach(service => {
|
||||
export async function writeClientServices(services: Service[], templates: Templates, outputPath: string, useOptions: boolean): Promise<void> {
|
||||
for (const service of services) {
|
||||
const file = path.resolve(outputPath, `${service.name}.ts`);
|
||||
const templateResult = templates.service({
|
||||
...service,
|
||||
useOptions,
|
||||
});
|
||||
fs.writeFileSync(file, format(templateResult));
|
||||
});
|
||||
await writeFile(file, format(templateResult));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { HttpClient } from '../index';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { writeFile } from './fileSystem';
|
||||
import { Templates } from './registerHandlebarsTemplates';
|
||||
|
||||
/**
|
||||
* Generate OpenAPI configuration file "OpenAPI.ts"
|
||||
@ -12,8 +12,8 @@ import { Templates } from './readHandlebarsTemplates';
|
||||
* @param outputPath Directory to write the generated files to.
|
||||
* @param httpClient The selected httpClient (fetch or XHR).
|
||||
*/
|
||||
export function writeClientSettings(client: Client, templates: Templates, outputPath: string, httpClient: HttpClient): void {
|
||||
fs.writeFileSync(
|
||||
export async function writeClientSettings(client: Client, templates: Templates, outputPath: string, httpClient: HttpClient): Promise<void> {
|
||||
await writeFile(
|
||||
path.resolve(outputPath, 'OpenAPI.ts'),
|
||||
templates.settings({
|
||||
httpClient,
|
||||
|
||||
@ -20,29 +20,33 @@ function compile(dir) {
|
||||
compiler.emit();
|
||||
}
|
||||
|
||||
console.time('generate');
|
||||
async function run() {
|
||||
console.time('generate');
|
||||
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportSchemas: true,
|
||||
exportServices: true
|
||||
});
|
||||
await OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportSchemas: true,
|
||||
exportServices: true,
|
||||
});
|
||||
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportSchemas: true,
|
||||
exportServices: true
|
||||
});
|
||||
await OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportSchemas: true,
|
||||
exportServices: true,
|
||||
});
|
||||
|
||||
console.timeEnd('generate');
|
||||
console.timeEnd('generate');
|
||||
|
||||
compile('./test/result/v2/');
|
||||
compile('./test/result/v3/');
|
||||
compile('./test/result/v2/');
|
||||
compile('./test/result/v3/');
|
||||
}
|
||||
|
||||
run();
|
||||
|
||||
@ -5,52 +5,49 @@ const glob = require('glob');
|
||||
const fs = require('fs');
|
||||
|
||||
describe('generation', () => {
|
||||
|
||||
describe('v2', () => {
|
||||
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportCore: true,
|
||||
exportSchemas: true,
|
||||
exportModels: true,
|
||||
exportServices: true,
|
||||
it('generated v2', async () => {
|
||||
await OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportCore: true,
|
||||
exportSchemas: true,
|
||||
exportModels: true,
|
||||
exportServices: true,
|
||||
});
|
||||
});
|
||||
|
||||
test.each(glob
|
||||
.sync('./test/result/v2/**/*.ts')
|
||||
.map(file => [file])
|
||||
)('file(%s)', file => {
|
||||
const files = glob.sync('./test/result/v2/**/*.ts');
|
||||
|
||||
test.each(files.map(file => [file]))('file(%s)', file => {
|
||||
const content = fs.readFileSync(file, 'utf8').toString();
|
||||
expect(content).toMatchSnapshot(file);
|
||||
});
|
||||
});
|
||||
|
||||
describe('v3', () => {
|
||||
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportCore: true,
|
||||
exportSchemas: true,
|
||||
exportModels: true,
|
||||
exportServices: true,
|
||||
it('generated v3', async () => {
|
||||
await OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: true,
|
||||
useUnionTypes: true,
|
||||
exportCore: true,
|
||||
exportSchemas: true,
|
||||
exportModels: true,
|
||||
exportServices: true,
|
||||
});
|
||||
});
|
||||
|
||||
test.each(glob
|
||||
.sync('./test/result/v3/**/*.ts')
|
||||
.map(file => [file])
|
||||
)('file(%s)', file => {
|
||||
const files = glob.sync('./test/result/v3/**/*.ts');
|
||||
|
||||
test.each(files.map(file => [file]))('file(%s)', file => {
|
||||
const content = fs.readFileSync(file, 'utf8').toString();
|
||||
expect(content).toMatchSnapshot(file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"target": "es6",
|
||||
"module": "es6",
|
||||
"target": "ES2017",
|
||||
"module": "ES6",
|
||||
"moduleResolution": "node",
|
||||
"lib": ["es6", "dom"],
|
||||
"lib": ["ES2017"],
|
||||
"types": ["node", "jest"],
|
||||
"typeRoots": ["node_modules/@types"],
|
||||
"declaration": false,
|
||||
@ -19,9 +19,9 @@
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"importHelpers": false,
|
||||
"removeComments": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
|
||||
"files": [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user