Skip to content

Commit

Permalink
Release 5.1.0 (#157)
Browse files Browse the repository at this point in the history
* chore: make exportable ApiConfig interface; chore: change eslint-disable line at first line of generated file

* feat: --single-http-client option which allows to send HttpClient instance to Api constructor (issue #155)

* feat: onCreateRouteName hook; internal: clearing routeNameDuplicatesMap

* docs: update CHANGELOG

* chore: refresh tests schemas

* fix: nested object properties are generated are optional (issue #156, thanks @Fabiencdp)

* bump: up project version to 5.1.0
  • Loading branch information
js2me authored Feb 15, 2021
1 parent 58573bc commit 21c64fd
Show file tree
Hide file tree
Showing 81 changed files with 1,128 additions and 856 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# next release

# 5.1.0

Fixes:
- Bug with optional nested properties of object schema type (issue #156, thanks @Fabiencdp)

Features:
- `onCreateRouteName(routeNameInfo: RouteNameInfo, rawRouteInfo: RawRouteInfo): RouteNameInfo | void` hook
Which allows to customize route name without customizing `route-name.eta` template
- Improved content kinds for request infos
- `--single-http-client` option which allows to send HttpClient instance to Api constructor and not to create many count of HttpClient instances with `--modular` api (issue #155)

Minor:
- A bit improve type declaration file (index.d.ts) for this tool
- make exportable `ApiConfig` interface

Internal:
- clearing `routeNameDuplicatesMap` before each `parseRoutes()` function call
- Changed templates:
- `http-client.eta`
- `procedure-call.eta`
- `api.eta`

# 5.0.0

Fixes:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Options:
--modular generate separated files for http client, data contracts, and routes (default: false)
--disableStrictSSL disabled strict SSL (default: false)
--clean-output clean output folder before generate api. WARNING: May cause data loss (default: false)
--single-http-client Ability to send HttpClient instance to Api constructor (default: false)
--default-response <type> default type for empty response schema (default: "void")
-h, --help display help for command
```
Expand Down
82 changes: 57 additions & 25 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ interface GenerateApiParams {
* default type for empty response schema (default: "void")
*/
defaultResponseType?: boolean;
/**
* Ability to send HttpClient instance to Api constructor
*/
singleHttpClient?: boolean;
cleanOutput?: boolean;
enumNamesAsValues?: boolean;

Expand All @@ -92,6 +96,10 @@ interface GenerateApiParams {
onInit?: <C extends GenerateApiConfiguration["config"]>(configuration: C) => C | void;
/** customize configuration object before sending it to ETA templates */
onPrepareConfig?: <C extends GenerateApiConfiguration>(currentConfiguration: C) => C | void;
onCreateRouteName?: (
routeNameInfo: RouteNameInfo,
rawRouteInfo: RawRouteInfo,
) => RouteNameInfo | void;
onCreateRequestParams?: (
rawType: SchemaComponent["rawTypeData"],
) => SchemaComponent["rawTypeData"] | void;
Expand All @@ -102,6 +110,14 @@ interface GenerateApiParams {
extraTemplates?: { name: string; path: string }[];
}

export interface RouteNameRouteInfo {}

export type RouteNameInfo = {
usage: string;
original: string;
duplicate: boolean;
};

export type SchemaTypePrimitiveContent = {
$parsedSchema: boolean;
schemaType: string;
Expand Down Expand Up @@ -139,6 +155,13 @@ export interface ParsedSchema<C> {
content: C;
}

export interface PathArgInfo {
name: string;
optional: boolean;
type: string;
description?: string;
}

export interface SchemaComponent {
$ref: string;
typeName: string;
Expand Down Expand Up @@ -167,41 +190,50 @@ export interface SchemaComponent {
> | null;
}

export enum RequestContentKind {
JSON = "JSON",
URL_ENCODED = "URL_ENCODED",
FORM_DATA = "FORM_DATA",
IMAGE = "IMAGE",
OTHER = "OTHER",
}

export interface RequestResponseInfo {
contentTypes: string[];
contentKind: RequestContentKind;
type: string;
description: string;
status: string | number;
isSuccess: boolean;
}

export type RawRouteInfo = {
operationId: string;
method: string;
route: string;
moduleName: string;
responsesTypes: RequestResponseInfo[];
description?: string;
tags?: string[];
summary?: string;
responses?: import("swagger-schema-official").Spec["responses"];
produces?: string[];
requestBody?: object;
consumes?: string[];
};

export interface ParsedRoute {
id: string;
jsDocLines: string;
namespace: string;
request: Request;
response: Response;
routeName: {
usage: string;
original: string;
duplicate: boolean;
};
raw: {
method: string;
route: string;
moduleName: string;
responsesTypes: {
type: string;
description: string;
status: number;
isSuccess: boolean;
}[];
};
routeName: RouteNameInfo;
raw: RawRouteInfo;
}

export interface GenerateApiConfiguration {
apiConfig: {
props: {
name: string;
optional: boolean;
type: string;
}[];
generic: {
name: string;
defaultValue: string;
}[];
baseUrl: string;
title: string;
version: string;
Expand Down
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ program
0,
)
.option("--disableStrictSSL", "disabled strict SSL", false)
.option("--single-http-client", "Ability to send HttpClient instance to Api constructor", false)
.option("--default-response <type>", "default type for empty response schema", TS_KEYWORDS.VOID)
.option(
"--clean-output",
Expand Down Expand Up @@ -89,6 +90,7 @@ const {
disableStrictSSL,
cleanOutput,
defaultResponse,
singleHttpClient,
} = program;

generateApi({
Expand All @@ -109,5 +111,6 @@ generateApi({
enumNamesAsValues: enumNamesAsValues,
moduleNameIndex: +(moduleNameIndex || 0),
disableStrictSSL: !!disableStrictSSL,
singleHttpClient: !!singleHttpClient,
cleanOutput: !!cleanOutput,
});
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swagger-typescript-api",
"version": "5.0.0",
"version": "5.1.0",
"description": "Create typescript api module from swagger schema",
"scripts": {
"cli:json": "node index.js -r -d -p ./swagger-test-cli.json -n swagger-test-cli.ts --extract-request-params --enum-names-as-values",
Expand All @@ -25,6 +25,7 @@
"test:specProperty": "node tests/spec/specProperty/test.js",
"test:--module-name-index": "node tests/spec/moduleNameIndex/test.js",
"test:--modular": "node tests/spec/modular/test.js",
"test:--single-http-client": "node tests/spec/singleHttpClient/test.js",
"test:--extract-request-params": "node tests/spec/extractRequestParams/test.js",
"test:--enum-names-as-values": "node tests/spec/enumNamesAsValues/test.js",
"test:--default-response": "node tests/spec/defaultResponse/test.js",
Expand Down
3 changes: 3 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const config = {
httpClient: "http-client",
outOfModuleApi: "Common",
},
routeNameDuplicatesMap: new Map(),
prettierOptions: constants.PRETTIER_OPTIONS,
hooks: {
onCreateComponent: (schema) => schema,
Expand All @@ -44,8 +45,10 @@ const config = {
onInit: (config) => config,
onPrepareConfig: (apiConfig) => apiConfig,
onCreateRequestParams: (rawType) => {},
onCreateRouteName: () => {},
},
defaultResponseType: constants.TS_KEYWORDS.VOID,
singleHttpClient: false,
};

/** needs to use data everywhere in project */
Expand Down
4 changes: 2 additions & 2 deletions src/filePrefix.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
filePrefix: `/* tslint:disable */
/* eslint-disable */
filePrefix: `/* eslint:disable */
/* tslint-disable */
/*
* ---------------------------------------------------------------
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
Expand Down
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module.exports = {
moduleNameIndex = config.moduleNameIndex,
extractRequestParams = config.extractRequestParams,
defaultResponseType = config.defaultResponseType,
singleHttpClient = config.singleHttpClient,
prettier: prettierOptions = constants.PRETTIER_OPTIONS,
hooks: rawHooks,
extraTemplates,
Expand All @@ -61,6 +62,7 @@ module.exports = {
disableStrictSSL,
cleanOutput,
defaultResponseType,
singleHttpClient,
});
(spec ? convertSwaggerObject(spec) : getSwaggerObject(input, url, disableStrictSSL))
.then(({ usageSchema, originalSchema }) => {
Expand All @@ -83,6 +85,9 @@ module.exports = {
const componentsMap = createComponentsMap(components);

const parsedSchemas = parseSchemas(components);

config.routeNameDuplicatesMap.clear();

const routes = parseRoutes({
usageSchema,
parsedSchemas,
Expand Down
4 changes: 3 additions & 1 deletion src/routeNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ const getRouteName = (routeInfo) => {

const duplicates = routeNameDuplicatesMap.get(duplicateIdentifier);

return {
const routeNameInfo = {
usage: routeName + (duplicates > 1 ? duplicates : ""),
original: routeName,
duplicate: duplicates > 1,
};

return config.hooks.onCreateRouteName(routeNameInfo, routeInfo) || routeNameInfo;
};

module.exports = {
Expand Down
47 changes: 20 additions & 27 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const {
TS_KEYWORDS,
} = require("./constants");
const { formatDescription, classNameCase } = require("./common");
const { config, addToConfig } = require("./config");
const { config } = require("./config");
const { nanoid } = require("nanoid");
const { getRouteName } = require("./routeNames");
const { createComponent } = require("./components");
Expand Down Expand Up @@ -336,7 +336,10 @@ const CONTENT_KIND = {
};

const getContentKind = (contentTypes) => {
if (contentTypes.includes("application/json")) {
if (
_.includes(contentTypes, "application/json") ||
_.some(contentTypes, (contentType) => _.endsWith(contentType, "+json"))
) {
return CONTENT_KIND.JSON;
}

Expand Down Expand Up @@ -434,9 +437,6 @@ const getResponseBodyInfo = (routeInfo, routeParams, parsedSchemas) => {
const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, extractRequestParams }) => {
const { paths, security: globalSecurity } = usageSchema;
const pathsEntries = _.entries(paths);
addToConfig({
routeNameDuplicatesMap: new Map(),
});

return pathsEntries.reduce((routes, [rawRoute, routeInfoByMethodsMap]) => {
if (rawRoute.startsWith("x-")) return routes;
Expand Down Expand Up @@ -481,11 +481,8 @@ const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, extractReque
const requestBodyInfo = getRequestBodyInfo(routeInfo, routeParams, parsedSchemas);
const responseBodyInfo = getResponseBodyInfo(routeInfo, routeParams, parsedSchemas);

const queryObjectSchema = convertRouteParamsIntoObject(routeParams.query);
const pathObjectSchema = convertRouteParamsIntoObject(routeParams.path);
const headersObjectSchema = convertRouteParamsIntoObject(routeParams.header);

const routeName = getRouteName({
const rawRouteInfo = {
pathArgs,
operationId,
method,
route: rawRoute,
Expand All @@ -494,8 +491,18 @@ const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, extractReque
description,
tags,
summary,
pathArgs,
});
responses,
produces,
requestBody,
consumes,
...otherInfo,
};

const queryObjectSchema = convertRouteParamsIntoObject(routeParams.query);
const pathObjectSchema = convertRouteParamsIntoObject(routeParams.path);
const headersObjectSchema = convertRouteParamsIntoObject(routeParams.header);

const routeName = getRouteName(rawRouteInfo);

const requestParamsSchema = createRequestParamsSchema({
queryParams: routeParams.query,
Expand Down Expand Up @@ -615,21 +622,7 @@ const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, extractReque
type: responseBodyInfo.success.type,
errorType: responseBodyInfo.error.type,
},
raw: {
operationId,
method,
route: rawRoute,
moduleName,
responsesTypes: responseBodyInfo.responses,
description,
tags,
summary,
responses,
produces,
requestBody,
consumes,
...otherInfo,
},
raw: rawRouteInfo,
};

return config.hooks.onCreateRoute(routeData) || routeData;
Expand Down
Loading

0 comments on commit 21c64fd

Please sign in to comment.