mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
- Added request property
This commit is contained in:
parent
56f9289ff1
commit
b0bea2daae
@ -12,13 +12,14 @@ program
|
||||
.version(pkg.version)
|
||||
.requiredOption('-i, --input <value>', 'OpenAPI specification, can be a path, url or string content (required)')
|
||||
.requiredOption('-o, --output <value>', 'Output directory (required)')
|
||||
.option('-c, --client <value>', 'HTTP client to generate [fetch, xhr, node] or path to custom request file', 'fetch')
|
||||
.option('-c, --client <value>', 'HTTP client to generate [fetch, xhr, node]', 'fetch')
|
||||
.option('--useOptions', 'Use options instead of arguments')
|
||||
.option('--useUnionTypes', 'Use union types instead of enums')
|
||||
.option('--exportCore <value>', 'Write core files to disk', true)
|
||||
.option('--exportServices <value>', 'Write services to disk', true)
|
||||
.option('--exportModels <value>', 'Write models to disk', true)
|
||||
.option('--exportSchemas <value>', 'Write schemas to disk', false)
|
||||
.option('--request <value>', 'Path to custom request file')
|
||||
.parse(process.argv);
|
||||
|
||||
const OpenAPI = require(path.resolve(__dirname, '../dist/index.js'));
|
||||
@ -34,6 +35,7 @@ if (OpenAPI) {
|
||||
exportServices: JSON.parse(program.exportServices) === true,
|
||||
exportModels: JSON.parse(program.exportModels) === true,
|
||||
exportSchemas: JSON.parse(program.exportSchemas) === true,
|
||||
request: program.request,
|
||||
})
|
||||
.then(() => {
|
||||
process.exit(0);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openapi-typescript-codegen",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"description": "Library that generates Typescript clients based on the OpenAPI specification.",
|
||||
"author": "Ferdi Koomen",
|
||||
"homepage": "https://github.com/ferdikoomen/openapi-typescript-codegen",
|
||||
@ -91,7 +91,6 @@
|
||||
"express": "4.17.1",
|
||||
"form-data": "3.0.0",
|
||||
"glob": "7.1.6",
|
||||
"httpntlm": "1.7.6",
|
||||
"jest": "26.6.3",
|
||||
"jest-cli": "26.6.3",
|
||||
"node-fetch": "2.6.1",
|
||||
|
||||
@ -13,13 +13,14 @@ export { HttpClient } from './HttpClient';
|
||||
export type Options = {
|
||||
input: string | Record<string, any>;
|
||||
output: string;
|
||||
httpClient?: string | HttpClient;
|
||||
httpClient?: HttpClient;
|
||||
useOptions?: boolean;
|
||||
useUnionTypes?: boolean;
|
||||
exportCore?: boolean;
|
||||
exportServices?: boolean;
|
||||
exportModels?: boolean;
|
||||
exportSchemas?: boolean;
|
||||
request?: string;
|
||||
write?: boolean;
|
||||
};
|
||||
|
||||
@ -36,6 +37,7 @@ export type Options = {
|
||||
* @param exportServices: Generate services
|
||||
* @param exportModels: Generate models
|
||||
* @param exportSchemas: Generate schemas
|
||||
* @param request: Path to custom request file
|
||||
* @param write Write the files to disk (true or false)
|
||||
*/
|
||||
export async function generate({
|
||||
@ -48,6 +50,7 @@ export async function generate({
|
||||
exportServices = true,
|
||||
exportModels = true,
|
||||
exportSchemas = false,
|
||||
request,
|
||||
write = true,
|
||||
}: Options): Promise<void> {
|
||||
const openApi = isString(input) ? await getOpenApiSpec(input) : input;
|
||||
@ -59,7 +62,7 @@ export async function generate({
|
||||
const client = parseV2(openApi);
|
||||
const clientFinal = postProcessClient(client);
|
||||
if (!write) break;
|
||||
await writeClient(clientFinal, templates, output, httpClient, useOptions, useUnionTypes, exportCore, exportServices, exportModels, exportSchemas);
|
||||
await writeClient(clientFinal, templates, output, httpClient, useOptions, useUnionTypes, exportCore, exportServices, exportModels, exportSchemas, request);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -67,7 +70,7 @@ export async function generate({
|
||||
const client = parseV3(openApi);
|
||||
const clientFinal = postProcessClient(client);
|
||||
if (!write) break;
|
||||
await writeClient(clientFinal, templates, output, httpClient, useOptions, useUnionTypes, exportCore, exportServices, exportModels, exportSchemas);
|
||||
await writeClient(clientFinal, templates, output, httpClient, useOptions, useUnionTypes, exportCore, exportServices, exportModels, exportSchemas, request);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,18 +23,20 @@ import { writeClientServices } from './writeClientServices';
|
||||
* @param exportServices: Generate services
|
||||
* @param exportModels: Generate models
|
||||
* @param exportSchemas: Generate schemas
|
||||
* @param request: Path to custom request file
|
||||
*/
|
||||
export async function writeClient(
|
||||
client: Client,
|
||||
templates: Templates,
|
||||
output: string,
|
||||
httpClient: string | HttpClient,
|
||||
httpClient: HttpClient,
|
||||
useOptions: boolean,
|
||||
useUnionTypes: boolean,
|
||||
exportCore: boolean,
|
||||
exportServices: boolean,
|
||||
exportModels: boolean,
|
||||
exportSchemas: boolean
|
||||
exportSchemas: boolean,
|
||||
request?: string
|
||||
): Promise<void> {
|
||||
const outputPath = resolve(process.cwd(), output);
|
||||
const outputPathCore = resolve(outputPath, 'core');
|
||||
@ -49,7 +51,7 @@ export async function writeClient(
|
||||
if (exportCore) {
|
||||
await rmdir(outputPathCore);
|
||||
await mkdir(outputPathCore);
|
||||
await writeClientCore(client, templates, outputPathCore, httpClient);
|
||||
await writeClientCore(client, templates, outputPathCore, httpClient, request);
|
||||
}
|
||||
|
||||
if (exportServices) {
|
||||
|
||||
@ -11,8 +11,9 @@ import { Templates } from './registerHandlebarTemplates';
|
||||
* @param templates The loaded handlebar templates
|
||||
* @param outputPath Directory to write the generated files to
|
||||
* @param httpClient The selected httpClient (fetch, xhr or node)
|
||||
* @param request: Path to custom request file
|
||||
*/
|
||||
export async function writeClientCore(client: Client, templates: Templates, outputPath: string, httpClient: string | HttpClient): Promise<void> {
|
||||
export async function writeClientCore(client: Client, templates: Templates, outputPath: string, httpClient: HttpClient, request?: string): Promise<void> {
|
||||
const context = {
|
||||
httpClient,
|
||||
server: client.server,
|
||||
@ -23,20 +24,14 @@ export async function writeClientCore(client: Client, templates: Templates, outp
|
||||
await writeFile(resolve(outputPath, 'ApiError.ts'), templates.core.apiError({}));
|
||||
await writeFile(resolve(outputPath, 'ApiRequestOptions.ts'), templates.core.apiRequestOptions({}));
|
||||
await writeFile(resolve(outputPath, 'ApiResult.ts'), templates.core.apiResult({}));
|
||||
await writeFile(resolve(outputPath, 'request.ts'), templates.core.request(context));
|
||||
|
||||
switch (httpClient) {
|
||||
case HttpClient.FETCH:
|
||||
case HttpClient.XHR:
|
||||
case HttpClient.NODE:
|
||||
await writeFile(resolve(outputPath, 'request.ts'), templates.core.request(context));
|
||||
break;
|
||||
default:
|
||||
const customRequestFile = resolve(process.cwd(), httpClient);
|
||||
const customRequestFileExists = await exists(customRequestFile);
|
||||
if (!customRequestFileExists) {
|
||||
throw new Error(`Custom request file "${customRequestFile}" does not exists`);
|
||||
}
|
||||
await copyFile(customRequestFile, resolve(outputPath, 'request.ts'));
|
||||
break;
|
||||
if (request) {
|
||||
const requestFile = resolve(process.cwd(), request);
|
||||
const requestFileExists = await exists(requestFile);
|
||||
if (!requestFileExists) {
|
||||
throw new Error(`Custom request file "${requestFile}" does not exists`);
|
||||
}
|
||||
await copyFile(requestFile, resolve(outputPath, 'request.ts'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ import { Templates } from './registerHandlebarTemplates';
|
||||
* @param httpClient The selected httpClient (fetch, xhr or node)
|
||||
* @param useUnionTypes Use union types instead of enums
|
||||
*/
|
||||
export async function writeClientModels(models: Model[], templates: Templates, outputPath: string, httpClient: string | HttpClient, useUnionTypes: boolean): Promise<void> {
|
||||
export async function writeClientModels(models: Model[], templates: Templates, outputPath: string, httpClient: HttpClient, useUnionTypes: boolean): Promise<void> {
|
||||
for (const model of models) {
|
||||
const file = resolve(outputPath, `${model.name}.ts`);
|
||||
const templateResult = templates.exports.model({
|
||||
|
||||
@ -14,7 +14,7 @@ import { Templates } from './registerHandlebarTemplates';
|
||||
* @param httpClient The selected httpClient (fetch, xhr or node)
|
||||
* @param useUnionTypes Use union types instead of enums
|
||||
*/
|
||||
export async function writeClientSchemas(models: Model[], templates: Templates, outputPath: string, httpClient: string | HttpClient, useUnionTypes: boolean): Promise<void> {
|
||||
export async function writeClientSchemas(models: Model[], templates: Templates, outputPath: string, httpClient: HttpClient, useUnionTypes: boolean): Promise<void> {
|
||||
for (const model of models) {
|
||||
const file = resolve(outputPath, `$${model.name}.ts`);
|
||||
const templateResult = templates.exports.schema({
|
||||
|
||||
@ -17,7 +17,7 @@ const VERSION_TEMPLATE_STRING = 'OpenAPI.VERSION';
|
||||
* @param useUnionTypes Use union types instead of enums
|
||||
* @param useOptions Use options or arguments functions
|
||||
*/
|
||||
export async function writeClientServices(services: Service[], templates: Templates, outputPath: string, httpClient: string | HttpClient, useUnionTypes: boolean, useOptions: boolean): Promise<void> {
|
||||
export async function writeClientServices(services: Service[], templates: Templates, outputPath: string, httpClient: HttpClient, useUnionTypes: boolean, useOptions: boolean): Promise<void> {
|
||||
for (const service of services) {
|
||||
const file = resolve(outputPath, `${service.name}.ts`);
|
||||
const useVersion = service.operations.some(operation => operation.path.includes(VERSION_TEMPLATE_STRING));
|
||||
|
||||
@ -1,60 +1,23 @@
|
||||
// @ts-ignore
|
||||
import httpntlm from 'httpntlm';
|
||||
import { promisify } from 'util';
|
||||
import { stringify } from 'qs';
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
import type { ApiResult } from './ApiResult';
|
||||
import { OpenAPI } from './OpenAPI';
|
||||
|
||||
type TRequestOptions = {
|
||||
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
|
||||
readonly path: string;
|
||||
readonly cookies?: Record<string, any>;
|
||||
readonly headers?: Record<string, any>;
|
||||
readonly query?: Record<string, any>;
|
||||
readonly formData?: Record<string, any>;
|
||||
readonly body?: any;
|
||||
readonly responseHeader?: string;
|
||||
readonly errors?: Record<number, string>;
|
||||
}
|
||||
export async function request(options: ApiRequestOptions): Promise<ApiResult> {
|
||||
|
||||
type TResult = {
|
||||
readonly url: string;
|
||||
readonly ok: boolean;
|
||||
readonly status: number;
|
||||
readonly statusText: string;
|
||||
readonly body: any;
|
||||
}
|
||||
const url = `${OpenAPI.BASE}${options.path}`;
|
||||
|
||||
export async function request(options: TRequestOptions): Promise<TResult> {
|
||||
|
||||
const path = options.path.replace(/[:]/g, '_');
|
||||
const query = stringify(options.query);
|
||||
const host = 'http://localhost:8080';
|
||||
const url = `${host}${path}${query}`;
|
||||
|
||||
const body = options.body && JSON.stringify(options.body);
|
||||
const headers = {
|
||||
...options.headers,
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Accept-Encoding': 'identity',
|
||||
}
|
||||
|
||||
const method = options.method.toLowerCase();
|
||||
const fetch = promisify(httpntlm[method]);
|
||||
|
||||
const response = await fetch({
|
||||
url,
|
||||
domain: 'domain',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
headers,
|
||||
body,
|
||||
});
|
||||
// Do your request...
|
||||
|
||||
return {
|
||||
url,
|
||||
ok: response.ok,
|
||||
status: response.statusCode,
|
||||
statusText: response.statusText,
|
||||
body: JSON.parse(response.body),
|
||||
ok: true,
|
||||
status: 200,
|
||||
statusText: 'dummy',
|
||||
body: {
|
||||
...options
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ async function generateV2() {
|
||||
exportSchemas: true,
|
||||
exportModels: true,
|
||||
exportServices: true,
|
||||
request: './test/custom/request.ts',
|
||||
});
|
||||
}
|
||||
|
||||
@ -27,6 +28,7 @@ async function generateV3() {
|
||||
exportSchemas: true,
|
||||
exportModels: true,
|
||||
exportServices: true,
|
||||
request: './test/custom/request.ts',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
@ -7,13 +7,14 @@ export declare enum HttpClient {
|
||||
export type Options = {
|
||||
input: string | Record<string, any>;
|
||||
output: string;
|
||||
httpClient?: string | HttpClient;
|
||||
httpClient?: HttpClient;
|
||||
useOptions?: boolean;
|
||||
useUnionTypes?: boolean;
|
||||
exportCore?: boolean;
|
||||
exportServices?: boolean;
|
||||
exportModels?: boolean;
|
||||
exportSchemas?: boolean;
|
||||
request?: string;
|
||||
write?: boolean;
|
||||
};
|
||||
|
||||
|
||||
30
yarn.lock
30
yarn.lock
@ -2345,9 +2345,9 @@ ee-first@1.1.1:
|
||||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
||||
|
||||
electron-to-chromium@^1.3.621:
|
||||
version "1.3.628"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.628.tgz#be5a14ddf3a455de876274c84de0926439a287a7"
|
||||
integrity sha512-fmhO4YGo/kapy+xL9Eq/cZwDASaTHZu3psIFYo4yc+RY1LzbZr84xjKlDImDrlrmWhOxsrDi98nX097U/xK/cQ==
|
||||
version "1.3.629"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.629.tgz#a08d13b64d90e3c77ec5b9bffa3efbc5b4a00969"
|
||||
integrity sha512-iSPPJtPvHrMAvYOt+9cdbDmTasPqwnwz4lkP8Dn200gDNUBQOLQ96xUsWXBwXslAo5XxdoXAoQQ3RAy4uao9IQ==
|
||||
|
||||
emittery@^0.7.1:
|
||||
version "0.7.2"
|
||||
@ -2939,9 +2939,9 @@ get-caller-file@^2.0.1:
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-intrinsic@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be"
|
||||
integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
|
||||
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
@ -3174,19 +3174,6 @@ http-signature@~1.2.0:
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
httpntlm@1.7.6:
|
||||
version "1.7.6"
|
||||
resolved "https://registry.yarnpkg.com/httpntlm/-/httpntlm-1.7.6.tgz#6991e8352836007d67101b83db8ed0f915f906d0"
|
||||
integrity sha1-aZHoNSg2AH1nEBuD247Q+RX5BtA=
|
||||
dependencies:
|
||||
httpreq ">=0.4.22"
|
||||
underscore "~1.7.0"
|
||||
|
||||
httpreq@>=0.4.22:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/httpreq/-/httpreq-0.4.24.tgz#4335ffd82cd969668a39465c929ac61d6393627f"
|
||||
integrity sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=
|
||||
|
||||
https-proxy-agent@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b"
|
||||
@ -5724,11 +5711,6 @@ unbzip2-stream@^1.3.3:
|
||||
buffer "^5.2.1"
|
||||
through "^2.3.8"
|
||||
|
||||
underscore@~1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
|
||||
integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user