diff --git a/.prettierrc.json b/.prettierrc.json
index 681dbab3..3f00fc05 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -2,6 +2,6 @@
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
- "printWidth": 500,
+ "printWidth": 200,
"tabWidth": 4
}
diff --git a/README.md b/README.md
index 338e40c2..8dcc860f 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ const OpenAPI = require('openapi-typescript-codegen');
OpenAPI.generate({
input: './api/openapi.json',
- output: './dist'
+ output: './generated'
});
```
@@ -64,19 +64,20 @@ Or by providing the JSON directly:
```javascript
const OpenAPI = require('openapi-typescript-codegen');
+
const spec = require('./api/openapi.json');
OpenAPI.generate({
input: spec,
- output: './dist'
+ output: './generated'
});
```
## Features
### Argument-style vs. Object-style
-There's no [named parameter](https://en.wikipedia.org/wiki/Named_parameter) in JS/TS, because of that,
-we offer an option `--useOptions` to generate code in two different styles.
+There's no [named parameter](https://en.wikipedia.org/wiki/Named_parameter) in Javascript or Typescript, because of
+that, we offer the flag `--useOptions` to generate code in two different styles.
Argument-style:
```typescript
@@ -84,24 +85,22 @@ function createUser(name: string, password: string, type?: string, address?: str
// ...
}
-// usage
+// Usage
createUser('Jack', '123456', undefined, 'NY US');
```
Object-style:
```typescript
-interface CreateUserOptions {
+function createUser({ name, password, type, address }: {
name: string,
password: string,
type?: string
address?: string
-}
-
-function createUser({ name, password, type, address }: CreateUserOptions) {
+}) {
// ...
}
-// usage
+// Usage
createUser({
name: 'Jack',
password: '123456',
@@ -109,6 +108,118 @@ createUser({
});
```
+
+### Runtime schemas
+By default the OpenAPI generator only exports interfaces for your models. These interfaces will help you during
+development, but will not be available in javascript during runtime. However Swagger allows you to define properties
+that can be useful during runtime, for instance: `maxLength` of a string or a `pattern` to match, etc. Let's say
+we have the following model:
+
+```json
+{
+ "MyModel": {
+ "required": [
+ "key",
+ "name"
+ ],
+ "type": "object",
+ "properties": {
+ "key": {
+ "maxLength": 64,
+ "pattern": "^[a-zA-Z0-9_]*$",
+ "type": "string"
+ },
+ "name": {
+ "maxLength": 255,
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "modified": {
+ "type": "string",
+ "format": "date-time",
+ "readOnly": true
+ }
+ }
+ }
+}
+```
+
+This will generate the following interface:
+
+```typescript
+export interface ModelWithPattern {
+ key: string;
+ name: string;
+ readonly enabled?: boolean;
+ readonly modified?: string;
+}
+```
+
+The interface does not contain any properties like `maxLength` or `pattern`. However they could be useful
+if we wanted to create some form where a user could create such a model. In that form you would iterate
+over the properties to render form fields based on their type and validate the input based on the `maxLength`
+or `pattern` property. This requires us to have this information somewhere... For this we can use the
+flag `--exportSchemas` to generate a runtime model next to the normal interface:
+
+```typescript
+export const $ModelWithPattern = {
+ properties: {
+ key: {
+ type: 'string',
+ isRequired: true,
+ maxLength: 64,
+ pattern: '^[a-zA-Z0-9_]*$',
+ },
+ name: {
+ type: 'string',
+ isRequired: true,
+ maxLength: 255,
+ },
+ enabled: {
+ type: 'boolean',
+ isReadOnly: true,
+ },
+ modified: {
+ type: 'string',
+ isReadOnly: true,
+ format: 'date-time',
+ },
+ },
+};
+```
+
+These runtime object are prefixed with a `$` character and expose all the interesting attributes of a model
+and it's properties. We can now use this object to generate the form:
+
+```typescript jsx
+import { $ModelWithPattern } from './generated';
+
+// Some pseudo code to iterate over the properties and return a form field
+// the form field could be some abstract component that renders the correct
+// field type and validation rules based on the given input.
+const formFields = Object.entries($ModelWithPattern.properties).map(([key, value]) => (
+
+));
+
+const MyForm = () => (
+
+);
+
+```
+
+
### Enum with custom names and descriptions
You can use `x-enum-varnames` and `x-enum-descriptions` in your spec to generate enum with custom names and descriptions.
It's not in official [spec](https://github.com/OAI/OpenAPI-Specification/issues/681) yet. But its a supported extension
@@ -159,6 +270,7 @@ The OpenAPI generator supports Bearer Token authorization. In order to enable th
of tokens in each request you can set the token using the global OpenAPI configuration:
```typescript
-import { OpenAPI } from './'
-OpenAPI.TOKEN = 'some-bearer-token'
+import { OpenAPI } from './generated';
+
+OpenAPI.TOKEN = 'some-bearer-token';
```
diff --git a/bin/index.js b/bin/index.js
index d8e26a0f..dc7cab8f 100755
--- a/bin/index.js
+++ b/bin/index.js
@@ -13,6 +13,8 @@ program
.option('--client [value]', 'HTTP client to generate [fetch, xhr]', 'fetch')
.option('--useOptions', 'Use options vs arguments style functions', false)
.option('--useUnionTypes', 'Use inclusive union types', false)
+ .option('--exportServices', 'Generate services', true)
+ .option('--exportSchemas', 'Generate schemas', false)
.parse(process.argv);
const OpenAPI = require(path.resolve(__dirname, '../dist/index.js'));
@@ -23,6 +25,8 @@ if (OpenAPI) {
output: program.output,
httpClient: program.client,
useOptions: program.useOptions,
- useUnionTypes: program.useUnionTypes
+ useUnionTypes: program.useUnionTypes,
+ exportServices: program.exportServices,
+ exportSchemas: program.exportSchemas,
});
}
diff --git a/package.json b/package.json
index e3535ce0..f262acda 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openapi-typescript-codegen",
- "version": "0.2.4",
+ "version": "0.2.5",
"description": "NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification.",
"author": "Ferdi Koomen",
"homepage": "https://github.com/ferdikoomen/openapi-typescript-codegen",
@@ -63,7 +63,6 @@
"dependencies": {
"camelcase": "5.3.1",
"commander": "4.1.1",
- "glob": "7.1.6",
"handlebars": "4.7.3",
"js-yaml": "3.13.1",
"mkdirp": "1.0.3",
@@ -86,6 +85,7 @@
"eslint-config-prettier": "6.10.0",
"eslint-plugin-prettier": "3.1.2",
"eslint-plugin-simple-import-sort": "5.0.1",
+ "glob": "7.1.6",
"jest": "25.1.0",
"jest-cli": "25.1.0",
"prettier": "1.19.1",
diff --git a/src/index.ts b/src/index.ts
index f02f33be..a22881ad 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -18,6 +18,8 @@ export interface Options {
httpClient?: HttpClient;
useOptions?: boolean;
useUnionTypes?: boolean;
+ exportServices?: boolean;
+ exportSchemas?: boolean;
write?: boolean;
}
@@ -30,9 +32,11 @@ export interface Options {
* @param httpClient The selected httpClient (fetch or XHR).
* @param useOptions Use options or arguments functions.
* @param useUnionTypes Use inclusive union types.
+ * @param exportServices: Generate services.
+ * @param exportSchemas: Generate schemas.
* @param write Write the files to disk (true or false).
*/
-export function generate({ input, output, httpClient = HttpClient.FETCH, useOptions = false, useUnionTypes = false, write = true }: Options): void {
+export function generate({ input, output, httpClient = HttpClient.FETCH, useOptions = false, useUnionTypes = false, exportServices = true, exportSchemas = false, write = true }: Options): void {
try {
// Load the specification, read the OpenAPI version and load the
// handlebar templates for the given language
@@ -45,7 +49,7 @@ export function generate({ input, output, httpClient = HttpClient.FETCH, useOpti
const client = parseV2(openApi);
const clientFinal = postProcessClient(client, useUnionTypes);
if (write) {
- writeClient(clientFinal, templates, output, httpClient, useOptions);
+ writeClient(clientFinal, templates, output, httpClient, useOptions, exportServices, exportSchemas);
}
break;
}
@@ -54,7 +58,7 @@ export function generate({ input, output, httpClient = HttpClient.FETCH, useOpti
const client = parseV3(openApi);
const clientFinal = postProcessClient(client, useUnionTypes);
if (write) {
- writeClient(clientFinal, templates, output, httpClient, useOptions);
+ writeClient(clientFinal, templates, output, httpClient, useOptions, exportServices, exportSchemas);
}
break;
}
diff --git a/src/templates/core/requestUsingFetch.ts b/src/templates/core/requestUsingFetch.ts
index 637285a6..a79714c6 100644
--- a/src/templates/core/requestUsingFetch.ts
+++ b/src/templates/core/requestUsingFetch.ts
@@ -12,7 +12,6 @@ import { Result } from './Result';
* @param response Response object from fetch
*/
async function parseBody(response: Response): Promise {
-
try {
const contentType = response.headers.get('Content-Type');
if (contentType) {
diff --git a/src/templates/core/requestUsingXHR.ts b/src/templates/core/requestUsingXHR.ts
index f0c9b5e1..a3445740 100644
--- a/src/templates/core/requestUsingXHR.ts
+++ b/src/templates/core/requestUsingXHR.ts
@@ -28,7 +28,6 @@ function parseBody(xhr: XMLHttpRequest): any {
} catch (e) {
console.error(e);
}
-
return null;
}
diff --git a/src/templates/index.hbs b/src/templates/index.hbs
index a7b6032d..1377cdab 100644
--- a/src/templates/index.hbs
+++ b/src/templates/index.hbs
@@ -2,25 +2,31 @@
/* tslint:disable */
/* eslint-disable */
/* prettier-ignore */
+{{#if exportServices}}
export { ApiError } from './core/ApiError';
export { isSuccess } from './core/isSuccess';
export { OpenAPI } from './core/OpenAPI';
+{{/if}}
{{#if models}}
{{#each models}}
export { {{{this}}} } from './models/{{{this}}}';
{{/each}}
{{/if}}
+{{#if exportSchemas}}
{{#if models}}
{{#each models}}
export { ${{{this}}} } from './schemas/${{{this}}}';
{{/each}}
{{/if}}
+{{/if}}
+{{#if exportServices}}
{{#if services}}
{{#each services}}
export { {{{this}}} } from './services/{{{this}}}';
{{/each}}
{{/if}}
+{{/if}}
diff --git a/src/utils/readHandlebarsTemplate.ts b/src/utils/readHandlebarsTemplate.ts
index 31c2b0da..9249965b 100644
--- a/src/utils/readHandlebarsTemplate.ts
+++ b/src/utils/readHandlebarsTemplate.ts
@@ -6,26 +6,19 @@ import * as Handlebars from 'handlebars';
* @param filePath
*/
export function readHandlebarsTemplate(filePath: string): Handlebars.TemplateDelegate {
- if (fs.existsSync(filePath)) {
- try {
- const template = fs
- .readFileSync(filePath, 'utf8')
- .toString()
- .trim();
+ const template = fs
+ .readFileSync(filePath, 'utf8')
+ .toString()
+ .trim();
- return Handlebars.compile(template, {
- strict: true,
- noEscape: true,
- preventIndent: true,
- knownHelpersOnly: true,
- knownHelpers: {
- equals: true,
- notEquals: true,
- },
- });
- } catch (e) {
- throw new Error(`Could not compile Handlebar template: "${filePath}"`);
- }
- }
- throw new Error(`Could not find Handlebar template: "${filePath}"`);
+ return Handlebars.compile(template, {
+ strict: true,
+ noEscape: true,
+ preventIndent: true,
+ knownHelpersOnly: true,
+ knownHelpers: {
+ equals: true,
+ notEquals: true,
+ },
+ });
}
diff --git a/src/utils/readHandlebarsTemplates.spec.ts b/src/utils/readHandlebarsTemplates.spec.ts
index 37f49037..d02a3ca1 100644
--- a/src/utils/readHandlebarsTemplates.spec.ts
+++ b/src/utils/readHandlebarsTemplates.spec.ts
@@ -1,20 +1,16 @@
import * as fs from 'fs';
-import * as glob from 'glob';
import { readHandlebarsTemplates } from './readHandlebarsTemplates';
jest.mock('fs');
-jest.mock('glob');
const fsExistsSync = fs.existsSync as jest.MockedFunction;
const fsReadFileSync = fs.readFileSync as jest.MockedFunction;
-const globSync = glob.sync as jest.MockedFunction;
describe('readHandlebarsTemplates', () => {
it('should read the templates', () => {
fsExistsSync.mockReturnValue(true);
fsReadFileSync.mockReturnValue('{{{message}}}');
- globSync.mockReturnValue([]);
const template = readHandlebarsTemplates();
diff --git a/src/utils/readHandlebarsTemplates.ts b/src/utils/readHandlebarsTemplates.ts
index 4f573ef9..775b6b09 100644
--- a/src/utils/readHandlebarsTemplates.ts
+++ b/src/utils/readHandlebarsTemplates.ts
@@ -1,10 +1,13 @@
-import * as glob from 'glob';
import * as Handlebars from 'handlebars';
import * as path from 'path';
import { readHandlebarsTemplate } from './readHandlebarsTemplate';
import { registerHandlebarHelpers } from './registerHandlebarHelpers';
+function resolveTemplate(filePath: string): string {
+ return path.resolve(__dirname, `../../src/templates/${filePath}`);
+}
+
export interface Templates {
index: Handlebars.TemplateDelegate;
model: Handlebars.TemplateDelegate;
@@ -18,27 +21,47 @@ export interface Templates {
* so we can easily access the templates in out generator / write functions.
*/
export function readHandlebarsTemplates(): Templates {
- try {
- registerHandlebarHelpers();
+ registerHandlebarHelpers();
- const templates: Templates = {
- index: readHandlebarsTemplate(path.resolve(__dirname, `../../src/templates/index.hbs`)),
- model: readHandlebarsTemplate(path.resolve(__dirname, `../../src/templates/model.hbs`)),
- schema: readHandlebarsTemplate(path.resolve(__dirname, `../../src/templates/schema.hbs`)),
- service: readHandlebarsTemplate(path.resolve(__dirname, `../../src/templates/service.hbs`)),
- settings: readHandlebarsTemplate(path.resolve(__dirname, `../../src/templates/core/OpenAPI.hbs`)),
- };
+ const templates: Templates = {
+ index: readHandlebarsTemplate(resolveTemplate('index.hbs')),
+ model: readHandlebarsTemplate(resolveTemplate('model.hbs')),
+ schema: readHandlebarsTemplate(resolveTemplate('schema.hbs')),
+ service: readHandlebarsTemplate(resolveTemplate('service.hbs')),
+ settings: readHandlebarsTemplate(resolveTemplate('core/OpenAPI.hbs')),
+ };
- const partials = path.resolve(__dirname, `../../src/templates/partials`);
- const partialsFiles = glob.sync('*.hbs', { cwd: partials });
- partialsFiles.forEach(partial => {
- const templateName = path.basename(partial, '.hbs');
- const template = readHandlebarsTemplate(path.resolve(partials, partial));
- Handlebars.registerPartial(templateName, template);
- });
+ const partials = [
+ 'exportEnum.hbs',
+ 'exportInterface.hbs',
+ 'exportType.hbs',
+ 'extends.hbs',
+ 'isNullable.hbs',
+ 'isReadOnly.hbs',
+ 'isRequired.hbs',
+ 'parameters.hbs',
+ 'result.hbs',
+ 'schema.hbs',
+ 'schemaArray.hbs',
+ 'schemaDictionary.hbs',
+ 'schemaEnum.hbs',
+ 'schemaGeneric.hbs',
+ 'schemaInterface.hbs',
+ 'type.hbs',
+ 'typeArray.hbs',
+ 'typeDictionary.hbs',
+ 'typeEnum.hbs',
+ 'typeGeneric.hbs',
+ 'typeInterface.hbs',
+ 'typeReference.hbs',
+ ];
- return templates;
- } catch (e) {
- throw new Error(`Could not read Handlebar templates`);
- }
+ partials.forEach(partial => {
+ const templatePath = resolveTemplate(`partials/${partial}`);
+ const templateName = path.basename(partial, '.hbs');
+ const template = readHandlebarsTemplate(templatePath);
+ Handlebars.registerPartial(templateName, template);
+ });
+
+ return templates;
}
diff --git a/src/utils/writeClient.spec.ts b/src/utils/writeClient.spec.ts
index 6d81aee7..6f3f62d2 100644
--- a/src/utils/writeClient.spec.ts
+++ b/src/utils/writeClient.spec.ts
@@ -1,5 +1,4 @@
import * as fs from 'fs';
-import * as glob from 'glob';
import * as mkdirp from 'mkdirp';
import * as rimraf from 'rimraf';
@@ -11,12 +10,10 @@ import { writeClient } from './writeClient';
jest.mock('rimraf');
jest.mock('mkdirp');
jest.mock('fs');
-jest.mock('glob');
const rimrafSync = mkdirp.sync as jest.MockedFunction;
const mkdirpSync = rimraf.sync as jest.MockedFunction;
const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction;
-const globSync = glob.sync as jest.MockedFunction;
describe('writeClient', () => {
it('should write to filesystem', () => {
@@ -35,13 +32,10 @@ describe('writeClient', () => {
settings: () => 'dummy',
};
- globSync.mockReturnValue([]);
-
- writeClient(client, templates, '/', HttpClient.FETCH, false);
+ writeClient(client, templates, '/', HttpClient.FETCH, false, true, true);
expect(rimrafSync).toBeCalled();
expect(mkdirpSync).toBeCalled();
expect(fsWriteFileSync).toBeCalled();
- expect(globSync).toBeCalled();
});
});
diff --git a/src/utils/writeClient.ts b/src/utils/writeClient.ts
index da17f36b..ee7592cd 100644
--- a/src/utils/writeClient.ts
+++ b/src/utils/writeClient.ts
@@ -1,5 +1,4 @@
import * as fs from 'fs';
-import * as glob from 'glob';
import * as mkdirp from 'mkdirp';
import * as path from 'path';
import * as rimraf from 'rimraf';
@@ -13,6 +12,10 @@ 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));
+}
+
/**
* Write our OpenAPI client, using the given templates at the given output path.
* @param client Client object with all the models, services, etc.
@@ -20,8 +23,10 @@ import { writeClientSettings } from './writeClientSettings';
* @param output Directory to write the generated files to.
* @param httpClient The selected httpClient (fetch or XHR).
* @param useOptions Use options or arguments functions.
+ * @param exportServices: Generate services.
+ * @param exportSchemas: Generate schemas.
*/
-export function writeClient(client: Client, templates: Templates, output: string, httpClient: HttpClient, useOptions: boolean): void {
+export function writeClient(client: Client, templates: Templates, output: string, httpClient: HttpClient, useOptions: boolean, exportServices: boolean, exportSchemas: boolean): void {
const outputPath = path.resolve(process.cwd(), output);
const outputPathCore = path.resolve(outputPath, 'core');
const outputPathModels = path.resolve(outputPath, 'models');
@@ -29,37 +34,35 @@ export function writeClient(client: Client, templates: Templates, output: string
const outputPathServices = path.resolve(outputPath, 'services');
// Clean output directory
- try {
- rimraf.sync(outputPath);
- } catch (e) {
- throw new Error('Could not clean output directory');
- }
+ rimraf.sync(outputPath);
+ mkdirp.sync(outputPath);
- // Create new directories
- try {
- mkdirp.sync(outputPath);
+ if (exportServices) {
mkdirp.sync(outputPathCore);
- mkdirp.sync(outputPathModels);
- mkdirp.sync(outputPathSchemas);
mkdirp.sync(outputPathServices);
- } catch (e) {
- throw new Error('Could not create output directories');
+
+ copySupportFile('core/ApiError.ts', outputPath);
+ copySupportFile('core/getFormData.ts', outputPath);
+ copySupportFile('core/getQueryString.ts', outputPath);
+ copySupportFile('core/isSuccess.ts', outputPath);
+ copySupportFile('core/OpenAPI.hbs', 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);
+
+ writeClientServices(client.services, templates, outputPathServices, useOptions);
+ writeClientSettings(client, templates, outputPathCore, httpClient);
}
- // Copy all support files
- const supportFiles = path.resolve(__dirname, '../../src/templates/');
- const supportFilesList = glob.sync('**/*.ts', { cwd: supportFiles });
- supportFilesList.forEach(file => {
- fs.copyFileSync(
- path.resolve(supportFiles, file), // From input path
- path.resolve(outputPath, file) // To output path
- );
- });
+ if (exportSchemas) {
+ mkdirp.sync(outputPathSchemas);
+ writeClientSchemas(client.models, templates, outputPathSchemas);
+ }
- // Write the client files
+ mkdirp.sync(outputPathModels);
+ copySupportFile('models/Dictionary.ts', outputPath);
writeClientModels(client.models, templates, outputPathModels);
- writeClientSchemas(client.models, templates, outputPathSchemas);
- writeClientServices(client.services, templates, outputPathServices, useOptions);
- writeClientSettings(client, templates, outputPathCore, httpClient);
- writeClientIndex(client, templates, outputPath);
+ writeClientIndex(client, templates, outputPath, exportServices, exportSchemas);
}
diff --git a/src/utils/writeClientIndex.spec.ts b/src/utils/writeClientIndex.spec.ts
index 2cecb881..38f4a86b 100644
--- a/src/utils/writeClientIndex.spec.ts
+++ b/src/utils/writeClientIndex.spec.ts
@@ -1,15 +1,12 @@
import * as fs from 'fs';
-import * as glob from 'glob';
import { Client } from '../client/interfaces/Client';
import { Templates } from './readHandlebarsTemplates';
import { writeClientIndex } from './writeClientIndex';
jest.mock('fs');
-jest.mock('glob');
const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction;
-const globSync = glob.sync as jest.MockedFunction;
describe('writeClientIndex', () => {
it('should write to filesystem', () => {
@@ -28,9 +25,7 @@ describe('writeClientIndex', () => {
settings: () => 'dummy',
};
- globSync.mockReturnValue([]);
-
- writeClientIndex(client, templates, '/');
+ writeClientIndex(client, templates, '/', true, true);
expect(fsWriteFileSync).toBeCalledWith('/index.ts', 'dummy');
});
diff --git a/src/utils/writeClientIndex.ts b/src/utils/writeClientIndex.ts
index 86e872c8..49e8823e 100644
--- a/src/utils/writeClientIndex.ts
+++ b/src/utils/writeClientIndex.ts
@@ -13,19 +13,19 @@ import { Templates } from './readHandlebarsTemplates';
* @param client Client object, containing, models, schemas and services.
* @param templates The loaded handlebar templates.
* @param outputPath Directory to write the generated files to.
+ * @param exportServices: Generate services.
+ * @param exportSchemas: Generate schemas.
*/
-export function writeClientIndex(client: Client, templates: Templates, outputPath: string): void {
- try {
- fs.writeFileSync(
- path.resolve(outputPath, 'index.ts'),
- templates.index({
- server: client.server,
- version: client.version,
- models: getModelNames(client.models),
- services: getServiceNames(client.services),
- })
- );
- } catch (e) {
- throw new Error(`Could not write index`);
- }
+export function writeClientIndex(client: Client, templates: Templates, outputPath: string, exportServices: boolean, exportSchemas: boolean): void {
+ fs.writeFileSync(
+ path.resolve(outputPath, 'index.ts'),
+ templates.index({
+ exportServices,
+ exportSchemas,
+ server: client.server,
+ version: client.version,
+ models: getModelNames(client.models),
+ services: getServiceNames(client.services),
+ })
+ );
}
diff --git a/test/__snapshots__/index.spec.js.snap b/test/__snapshots__/index.spec.js.snap
index ba5c0d6f..04bd028e 100644
--- a/test/__snapshots__/index.spec.js.snap
+++ b/test/__snapshots__/index.spec.js.snap
@@ -294,7 +294,6 @@ import { Result } from './Result';
* @param response Response object from fetch
*/
async function parseBody(response: Response): Promise {
-
try {
const contentType = response.headers.get('Content-Type');
if (contentType) {
@@ -368,7 +367,6 @@ function parseBody(xhr: XMLHttpRequest): any {
} catch (e) {
console.error(e);
}
-
return null;
}
@@ -461,6 +459,7 @@ export { ModelWithLink } from './models/ModelWithLink';
export { ModelWithNestedEnums } from './models/ModelWithNestedEnums';
export { ModelWithNestedProperties } from './models/ModelWithNestedProperties';
export { ModelWithOrderedProperties } from './models/ModelWithOrderedProperties';
+export { ModelWithPattern } from './models/ModelWithPattern';
export { ModelWithProperties } from './models/ModelWithProperties';
export { ModelWithReference } from './models/ModelWithReference';
export { ModelWithString } from './models/ModelWithString';
@@ -502,6 +501,7 @@ export { $ModelWithLink } from './schemas/$ModelWithLink';
export { $ModelWithNestedEnums } from './schemas/$ModelWithNestedEnums';
export { $ModelWithNestedProperties } from './schemas/$ModelWithNestedProperties';
export { $ModelWithOrderedProperties } from './schemas/$ModelWithOrderedProperties';
+export { $ModelWithPattern } from './schemas/$ModelWithPattern';
export { $ModelWithProperties } from './schemas/$ModelWithProperties';
export { $ModelWithReference } from './schemas/$ModelWithReference';
export { $ModelWithString } from './schemas/$ModelWithString';
@@ -1090,6 +1090,25 @@ export interface ModelWithOrderedProperties {
"
`;
+exports[`generation v2 file(./test/result/v2/models/ModelWithPattern.ts): ./test/result/v2/models/ModelWithPattern.ts 1`] = `
+"/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+/* prettier-ignore */
+
+
+/**
+ * This is a model that contains a some patterns
+ */
+export interface ModelWithPattern {
+ key: string;
+ name: string;
+ readonly enabled?: boolean;
+ readonly modified?: string;
+}
+"
+`;
+
exports[`generation v2 file(./test/result/v2/models/ModelWithProperties.ts): ./test/result/v2/models/ModelWithProperties.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@@ -1690,6 +1709,38 @@ export const $ModelWithOrderedProperties = {
};"
`;
+exports[`generation v2 file(./test/result/v2/schemas/$ModelWithPattern.ts): ./test/result/v2/schemas/$ModelWithPattern.ts 1`] = `
+"/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+/* prettier-ignore */
+
+export const $ModelWithPattern = {
+ properties: {
+ key: {
+ type: 'string',
+ isRequired: true,
+ maxLength: 64,
+ pattern: '^[a-zA-Z0-9_]*$',
+ },
+ name: {
+ type: 'string',
+ isRequired: true,
+ maxLength: 255,
+ },
+ enabled: {
+ type: 'boolean',
+ isReadOnly: true,
+ },
+ modified: {
+ type: 'string',
+ isReadOnly: true,
+ format: 'date-time',
+ },
+ },
+};"
+`;
+
exports[`generation v2 file(./test/result/v2/schemas/$ModelWithProperties.ts): ./test/result/v2/schemas/$ModelWithProperties.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@@ -2647,7 +2698,6 @@ import { Result } from './Result';
* @param response Response object from fetch
*/
async function parseBody(response: Response): Promise {
-
try {
const contentType = response.headers.get('Content-Type');
if (contentType) {
@@ -2721,7 +2771,6 @@ function parseBody(xhr: XMLHttpRequest): any {
} catch (e) {
console.error(e);
}
-
return null;
}
@@ -2816,6 +2865,7 @@ export { ModelWithNestedEnums } from './models/ModelWithNestedEnums';
export { ModelWithNestedProperties } from './models/ModelWithNestedProperties';
export { ModelWithOneOf } from './models/ModelWithOneOf';
export { ModelWithOrderedProperties } from './models/ModelWithOrderedProperties';
+export { ModelWithPattern } from './models/ModelWithPattern';
export { ModelWithProperties } from './models/ModelWithProperties';
export { ModelWithReference } from './models/ModelWithReference';
export { ModelWithString } from './models/ModelWithString';
@@ -2859,6 +2909,7 @@ export { $ModelWithNestedEnums } from './schemas/$ModelWithNestedEnums';
export { $ModelWithNestedProperties } from './schemas/$ModelWithNestedProperties';
export { $ModelWithOneOf } from './schemas/$ModelWithOneOf';
export { $ModelWithOrderedProperties } from './schemas/$ModelWithOrderedProperties';
+export { $ModelWithPattern } from './schemas/$ModelWithPattern';
export { $ModelWithProperties } from './schemas/$ModelWithProperties';
export { $ModelWithReference } from './schemas/$ModelWithReference';
export { $ModelWithString } from './schemas/$ModelWithString';
@@ -3489,6 +3540,25 @@ export interface ModelWithOrderedProperties {
"
`;
+exports[`generation v3 file(./test/result/v3/models/ModelWithPattern.ts): ./test/result/v3/models/ModelWithPattern.ts 1`] = `
+"/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+/* prettier-ignore */
+
+
+/**
+ * This is a model that contains a some patterns
+ */
+export interface ModelWithPattern {
+ key: string;
+ name: string;
+ readonly enabled?: boolean;
+ readonly modified?: string;
+}
+"
+`;
+
exports[`generation v3 file(./test/result/v3/models/ModelWithProperties.ts): ./test/result/v3/models/ModelWithProperties.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@@ -4123,6 +4193,38 @@ export const $ModelWithOrderedProperties = {
};"
`;
+exports[`generation v3 file(./test/result/v3/schemas/$ModelWithPattern.ts): ./test/result/v3/schemas/$ModelWithPattern.ts 1`] = `
+"/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+/* prettier-ignore */
+
+export const $ModelWithPattern = {
+ properties: {
+ key: {
+ type: 'string',
+ isRequired: true,
+ maxLength: 64,
+ pattern: '^[a-zA-Z0-9_]*$',
+ },
+ name: {
+ type: 'string',
+ isRequired: true,
+ maxLength: 255,
+ },
+ enabled: {
+ type: 'boolean',
+ isReadOnly: true,
+ },
+ modified: {
+ type: 'string',
+ isReadOnly: true,
+ format: 'date-time',
+ },
+ },
+};"
+`;
+
exports[`generation v3 file(./test/result/v3/schemas/$ModelWithProperties.ts): ./test/result/v3/schemas/$ModelWithProperties.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
diff --git a/test/index.js b/test/index.js
index 3e37a8db..f1127c38 100644
--- a/test/index.js
+++ b/test/index.js
@@ -24,6 +24,8 @@ OpenAPI.generate({
httpClient: OpenAPI.HttpClient.FETCH,
useOptions: false,
useUnionTypes: false,
+ exportSchemas: true,
+ exportServices: true,
});
OpenAPI.generate({
@@ -32,6 +34,8 @@ OpenAPI.generate({
httpClient: OpenAPI.HttpClient.FETCH,
useOptions: false,
useUnionTypes: false,
+ exportSchemas: true,
+ exportServices: true,
});
compile('./test/result/v2/');
diff --git a/test/index.spec.js b/test/index.spec.js
index 944bb2d1..c1e2b1d0 100644
--- a/test/index.spec.js
+++ b/test/index.spec.js
@@ -12,6 +12,8 @@ describe('generation', () => {
httpClient: OpenAPI.HttpClient.FETCH,
useOptions: false,
useUnionTypes: false,
+ exportSchemas: true,
+ exportServices: true,
});
test.each(glob
@@ -31,6 +33,8 @@ describe('generation', () => {
httpClient: OpenAPI.HttpClient.FETCH,
useOptions: false,
useUnionTypes: false,
+ exportSchemas: true,
+ exportServices: true,
});
test.each(glob
diff --git a/test/mock/v2/spec.json b/test/mock/v2/spec.json
index dc2ed535..2f8d40a5 100644
--- a/test/mock/v2/spec.json
+++ b/test/mock/v2/spec.json
@@ -998,6 +998,34 @@
}
}
]
+ },
+ "ModelWithPattern": {
+ "description": "This is a model that contains a some patterns",
+ "type": "object",
+ "required": [
+ "key",
+ "name"
+ ],
+ "properties": {
+ "key": {
+ "maxLength": 64,
+ "pattern": "^[a-zA-Z0-9_]*$",
+ "type": "string"
+ },
+ "name": {
+ "maxLength": 255,
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "modified": {
+ "type": "string",
+ "format": "date-time",
+ "readOnly": true
+ }
+ }
}
}
}
diff --git a/test/mock/v3/spec.json b/test/mock/v3/spec.json
index 0d7f2827..be5d08d3 100644
--- a/test/mock/v3/spec.json
+++ b/test/mock/v3/spec.json
@@ -1482,6 +1482,34 @@
}
}
]
+ },
+ "ModelWithPattern": {
+ "description": "This is a model that contains a some patterns",
+ "type": "object",
+ "required": [
+ "key",
+ "name"
+ ],
+ "properties": {
+ "key": {
+ "maxLength": 64,
+ "pattern": "^[a-zA-Z0-9_]*$",
+ "type": "string"
+ },
+ "name": {
+ "maxLength": 255,
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "modified": {
+ "type": "string",
+ "format": "date-time",
+ "readOnly": true
+ }
+ }
}
}
}