Gathering detailed insights and metrics for swagger-typescript-api
Gathering detailed insights and metrics for swagger-typescript-api
Gathering detailed insights and metrics for swagger-typescript-api
Gathering detailed insights and metrics for swagger-typescript-api
Generate the API Client for Fetch or Axios from an OpenAPI Specification
npm install swagger-typescript-api
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
3,394 Stars
879 Commits
361 Forks
10 Watching
5 Branches
71 Contributors
Updated on 28 Nov 2024
TypeScript (87.08%)
EJS (12.86%)
Shell (0.06%)
Cumulative downloads
Total Downloads
Last day
9.6%
48,326
Compared to previous day
Last week
7.3%
237,873
Compared to previous week
Last month
-9.3%
1,011,907
Compared to previous month
Last year
71.2%
10,463,366
Compared to previous year
12
Any questions you can ask here
All examples you can find here
1Usage: sta [options] 2Usage: swagger-typescript-api [options] 3Usage: swagger-typescript-api generate-templates [options] 4 5Options: 6 -v, --version output the current version 7 -p, --path <string> path/url to swagger scheme 8 -o, --output <string> output path of typescript api file (default: "./") 9 -n, --name <string> name of output typescript api file (default: "Api.ts") 10 -t, --templates <string> path to folder containing templates 11 -d, --default-as-success use "default" response status code as success response too. 12 some swagger schemas use "default" response status code as success response type by default. (default: false) 13 -r, --responses generate additional information about request responses 14 also add typings for bad responses (default: false) 15 --union-enums generate all "enum" types as union types (T1 | T2 | TN) (default: false) 16 --add-readonly generate readonly properties (default: false) 17 --route-types generate type definitions for API routes (default: false) 18 --no-client do not generate an API class 19 --enum-names-as-values use values in 'x-enumNames' as enum values (not only as keys) (default: false) 20 --extract-request-params extract request params to data contract (Also combine path params and query params into one object) (default: false) 21 --extract-request-body extract request body type to data contract (default: false) 22 --extract-response-body extract response body type to data contract (default: false) 23 --extract-response-error extract response error type to data contract (default: false) 24 --modular generate separated files for http client, data contracts, and routes (default: false) 25 --js generate js api module with declaration file (default: false) 26 --module-name-index <number> determines which path index should be used for routes separation (example: GET:/fruits/getFruit -> index:0 -> moduleName -> fruits) (default: 0) 27 --module-name-first-tag splits routes based on the first tag (default: false) 28 --axios generate axios http client (default: false) 29 --unwrap-response-data unwrap the data item from the response (default: false) 30 --disable-throw-on-error Do not throw an error when response.ok is not true (default: false) 31 --single-http-client Ability to send HttpClient instance to Api constructor (default: false) 32 --silent Output only errors to console (default: false) 33 --default-response <type> default type for empty response schema (default: "void") 34 --type-prefix <string> data contract name prefix (default: "") 35 --type-suffix <string> data contract name suffix (default: "") 36 --clean-output clean output folder before generate api. WARNING: May cause data loss (default: false) 37 --api-class-name <string> name of the api class (default: "Api") 38 --patch fix up small errors in the swagger source definition (default: false) 39 --debug additional information about processes inside this tool (default: false) 40 --another-array-type generate array types as Array<Type> (by default Type[]) (default: false) 41 --sort-types sort fields and types (default: false) 42 --sort-routes sort routes in alphabetical order (default: false) 43 --custom-config <string> custom config: primitiveTypeConstructs, hooks, ... (default: "") 44 --extract-enums extract all enums from inline interface\type content to typescript enum construction (default: false) 45 -h, --help display help for command 46 47Commands: 48 generate-templates Generate ".ejs" templates needed for generate api 49 -o, --output <string> output path of generated templates 50 -m, --modular generate templates needed to separate files for http client, data contracts, and routes (default: false) 51 --http-client <string> http client type (possible values: "fetch", "axios") (default: "fetch") 52 -c, --clean-output clean output folder before generate template. WARNING: May cause data loss (default: false) 53 -r, --rewrite rewrite content in existing templates (default: false) 54 --silent Output only errors to console (default: false) 55 -h, --help display help for command
Also you can use npx
:
npx swagger-typescript-api -p ./swagger.json -o ./src -n myApi.ts
You can use this package from nodejs:
1import fs from "node:fs"; 2import path from "node:path"; 3import { generateApi, generateTemplates } from "swagger-typescript-api"; 4 5/* NOTE: all fields are optional expect one of `input`, `url`, `spec` */ 6generateApi({ 7 name: "MySuperbApi.ts", 8 // set to `false` to prevent the tool from writing to disk 9 output: path.resolve(process.cwd(), "./src/__generated__"), 10 url: "http://api.com/swagger.json", 11 input: path.resolve(process.cwd(), "./foo/swagger.json"), 12 spec: { 13 swagger: "2.0", 14 info: { 15 version: "1.0.0", 16 title: "Swagger Petstore", 17 }, 18 // ... 19 }, 20 templates: path.resolve(process.cwd(), "./api-templates"), 21 httpClientType: "axios", // or "fetch" 22 defaultResponseAsSuccess: false, 23 generateClient: true, 24 generateRouteTypes: false, 25 generateResponses: true, 26 toJS: false, 27 extractRequestParams: false, 28 extractRequestBody: false, 29 extractEnums: false, 30 unwrapResponseData: false, 31 prettier: { 32 // By default prettier config is load from your project 33 printWidth: 120, 34 tabWidth: 2, 35 trailingComma: "all", 36 parser: "typescript", 37 }, 38 defaultResponseType: "void", 39 singleHttpClient: true, 40 cleanOutput: false, 41 enumNamesAsValues: false, 42 moduleNameFirstTag: false, 43 generateUnionEnums: false, 44 typePrefix: "", 45 typeSuffix: "", 46 enumKeyPrefix: "", 47 enumKeySuffix: "", 48 addReadonly: false, 49 sortTypes: false, 50 sortRouters: false, 51 extractingOptions: { 52 requestBodySuffix: ["Payload", "Body", "Input"], 53 requestParamsSuffix: ["Params"], 54 responseBodySuffix: ["Data", "Result", "Output"], 55 responseErrorSuffix: [ 56 "Error", 57 "Fail", 58 "Fails", 59 "ErrorData", 60 "HttpError", 61 "BadResponse", 62 ], 63 }, 64 /** allow to generate extra files based with this extra templates, see more below */ 65 extraTemplates: [], 66 anotherArrayType: false, 67 fixInvalidTypeNamePrefix: "Type", 68 fixInvalidEnumKeyPrefix: "Value", 69 codeGenConstructs: (constructs) => ({ 70 ...constructs, 71 RecordType: (key, value) => `MyRecord<key, value>`, 72 }), 73 primitiveTypeConstructs: (constructs) => ({ 74 ...constructs, 75 string: { 76 "date-time": "Date", 77 }, 78 }), 79 hooks: { 80 onCreateComponent: (component) => {}, 81 onCreateRequestParams: (rawType) => {}, 82 onCreateRoute: (routeData) => {}, 83 onCreateRouteName: (routeNameInfo, rawRouteInfo) => {}, 84 onFormatRouteName: (routeInfo, templateRouteName) => {}, 85 onFormatTypeName: (typeName, rawTypeName, schemaType) => {}, 86 onInit: (configuration) => {}, 87 onPreParseSchema: (originalSchema, typeName, schemaType) => {}, 88 onParseSchema: (originalSchema, parsedSchema) => {}, 89 onPrepareConfig: (currentConfiguration) => {}, 90 }, 91}) 92 .then(({ files, configuration }) => { 93 files.forEach(({ content, name }) => { 94 fs.writeFile(path, content); 95 }); 96 }) 97 .catch((e) => console.error(e)); 98 99generateTemplates({ 100 cleanOutput: false, 101 output: PATH_TO_OUTPUT_DIR, 102 httpClientType: "fetch", 103 modular: false, 104 silent: false, 105 rewrite: false, 106});
--templates
This option needed for cases when you don't want to use the default swagger-typescript-api
output structure
You can create custom templates with extensions .ejs
or .eta
Templates:
api.ejs
- (generates file) Api class module (locations: /templates/default, /templates/modular)data-contracts.ejs
- (generates file) all types (data contracts) from swagger schema (locations: /templates/base)http-client.ejs
- (generates file) HttpClient class module (locations: /templates/base)procedure-call.ejs
- (subtemplate) route in Api class (locations: /templates/default, /templates/modular)route-docs.ejs
- (generates file) documentation for route in Api class (locations: /templates/base)route-name.ejs
- (subtemplate) route name for route in Api class (locations: /templates/base)route-type.ejs
- (--route-types
option) (subtemplate) (locations: /templates/base)route-types.ejs
- (--route-types
option) (subtemplate) (locations: /templates/base)data-contract-jsdoc.ejs
- (subtemplate) generates JSDOC for data contract (locations: /templates/base)How to use it:
swagger-typescript-api
templates into your place in project
--modular
option)--templates PATH_TO_YOUR_TEMPLATES
optionNOTE:
Eta has special directive to render template in your Eta templates - includeFile(pathToTemplate, payload)
If you want to use some default templates from this tool you can use path prefixes: @base
, @default
, @modular
.
@base
- path to base templates
@default
- path to single api file templates
@modular
- path to multiple api files templates
Examples: - includeFile("@base/data-contracts.ejs", { ...yourData, ...it })
- includeFile("@default/api.ejs", { ...yourData, ...it })
- includeFile("@default/procedure-call.ejs", { ...yourData, ...it })
- includeFile("@modular/api.ejs", { ...yourData, ...it })
- includeFile("@modular/procedure-call.ejs", { ...yourData, ...it })
- includeFile("@base/route-docs.ejs", { ...yourData, ...it })
- includeFile("@base/route-name.ejs", { ...yourData, ...it })
- includeFile("@base/route-type.ejs", { ...yourData, ...it })
- includeFile("@base/route-types.ejs", { ...yourData, ...it })
--module-name-index
This option should be used in cases when you have api with one global prefix like /api
Example:
GET:/api/fruits/getFruits
POST:/api/fruits/addFruits
GET:/api/vegetables/addVegetable
with --module-name-index 0
Api class will have one property api
When we change it to --module-name-index 1
then Api class have two properties fruits
and vegetables
--module-name-first-tag
This option will group your API operations based on their first tag - mirroring how the Swagger UI groups displayed operations
extraTemplates
(NodeJS option)type (Record<string, any> & { name: string, path: string })[]
This thing allow you to generate extra ts\js files based on extra templates (one extra template for one ts\js file)
Example here
generate-templates
commandThis command allows you to generate source templates which using with option --templates
You are able to modify TypeScript internal structs using for generating output with using generateApi
options codeGenConstructs
and primitiveTypeConstructs
.
codeGenConstructs
This option has type (struct: CodeGenConstruct) => Partial<CodeGenConstruct>
.
1generateApi({ 2 // ... 3 codeGenConstructs: (struct) => ({ 4 Keyword: { 5 Number: "number", 6 String: "string", 7 Boolean: "boolean", 8 Any: "any", 9 Void: "void", 10 Unknown: "unknown", 11 Null: "null", 12 Undefined: "undefined", 13 Object: "object", 14 File: "File", 15 Date: "Date", 16 Type: "type", 17 Enum: "enum", 18 Interface: "interface", 19 Array: "Array", 20 Record: "Record", 21 Intersection: "&", 22 Union: "|", 23 }, 24 CodeGenKeyword: { 25 UtilRequiredKeys: "UtilRequiredKeys", 26 }, 27 /** 28 * $A[] or Array<$A> 29 */ 30 ArrayType: (content) => { 31 if (this.anotherArrayType) { 32 return `Array<${content}>`; 33 } 34 35 return `(${content})[]`; 36 }, 37 /** 38 * "$A" 39 */ 40 StringValue: (content) => `"${content}"`, 41 /** 42 * $A 43 */ 44 BooleanValue: (content) => `${content}`, 45 /** 46 * $A 47 */ 48 NumberValue: (content) => `${content}`, 49 /** 50 * $A 51 */ 52 NullValue: (content) => content, 53 /** 54 * $A1 | $A2 55 */ 56 UnionType: (contents) => _.join(_.uniq(contents), ` | `), 57 /** 58 * ($A1) 59 */ 60 ExpressionGroup: (content) => (content ? `(${content})` : ""), 61 /** 62 * $A1 & $A2 63 */ 64 IntersectionType: (contents) => _.join(_.uniq(contents), ` & `), 65 /** 66 * Record<$A1, $A2> 67 */ 68 RecordType: (key, value) => `Record<${key}, ${value}>`, 69 /** 70 * readonly $key?:$value 71 */ 72 TypeField: ({ readonly, key, optional, value }) => 73 _.compact([ 74 readonly && "readonly ", 75 key, 76 optional && "?", 77 ": ", 78 value, 79 ]).join(""), 80 /** 81 * [key: $A1]: $A2 82 */ 83 InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`, 84 /** 85 * $A1 = $A2 86 */ 87 EnumField: (key, value) => `${key} = ${value}`, 88 /** 89 * $A0.key = $A0.value, 90 * $A1.key = $A1.value, 91 * $AN.key = $AN.value, 92 */ 93 EnumFieldsWrapper: (contents) => 94 _.map(contents, ({ key, value }) => ` ${key} = ${value}`).join(",\n"), 95 /** 96 * {\n $A \n} 97 */ 98 ObjectWrapper: (content) => `{\n${content}\n}`, 99 /** 100 * /** $A *\/ 101 */ 102 MultilineComment: (contents, formatFn) => 103 [ 104 ...(contents.length === 1 105 ? [`/** ${contents[0]} */`] 106 : ["/**", ...contents.map((content) => ` * ${content}`), " */"]), 107 ].map((part) => `${formatFn ? formatFn(part) : part}\n`), 108 /** 109 * $A1<...$A2.join(,)> 110 */ 111 TypeWithGeneric: (typeName, genericArgs) => { 112 return `${typeName}${ 113 genericArgs.length ? `<${genericArgs.join(",")}>` : "" 114 }`; 115 }, 116 }), 117});
For example, if you need to generate output Record<string, any>
instead of object
you can do it with using following code:
1generateApi({ 2 // ... 3 codeGenConstructs: (struct) => ({ 4 Keyword: { 5 Object: "Record<string, any>", 6 }, 7 }), 8});
primitiveTypeConstructs
It is type mapper or translator swagger schema objects. primitiveTypeConstructs
translates type
/format
schema fields to typescript structs.
This option has type
1type PrimitiveTypeStructValue = 2 | string 3 | (( 4 schema: Record<string, any>, 5 parser: import("./src/schema-parser/schema-parser").SchemaParser 6 ) => string); 7 8type PrimitiveTypeStruct = Record< 9 "integer" | "number" | "boolean" | "object" | "file" | "string" | "array", 10 | string 11 | ({ $default: PrimitiveTypeStructValue } & Record< 12 string, 13 PrimitiveTypeStructValue 14 >) 15>; 16 17declare const primitiveTypeConstructs: ( 18 struct: PrimitiveTypeStruct 19) => Partial<PrimitiveTypeStruct>; 20 21generateApi({ 22 // ... 23 primitiveTypeConstructs: (struct) => ({ 24 integer: () => "number", 25 number: () => "number", 26 boolean: () => "boolean", 27 object: () => "object", 28 file: () => "File", 29 string: { 30 $default: () => "string", 31 32 /** formats */ 33 binary: () => "File", 34 file: () => "File", 35 "date-time": () => "string", 36 time: () => "string", 37 date: () => "string", 38 duration: () => "string", 39 email: () => "string", 40 "idn-email": () => "string", 41 "idn-hostname": () => "string", 42 ipv4: () => "string", 43 ipv6: () => "string", 44 uuid: () => "string", 45 uri: () => "string", 46 "uri-reference": () => "string", 47 "uri-template": () => "string", 48 "json-pointer": () => "string", 49 "relative-json-pointer": () => "string", 50 regex: () => "string", 51 }, 52 array: (schema, parser) => { 53 const content = parser.getInlineParseContent(schema.items); 54 return parser.safeAddNullToType(schema, `(${content})[]`); 55 }, 56 }), 57});
For example, if you need to change "string"/"date-time"
default output as string
to Date
you can do it with using following code:
1generateApi({ 2 primitiveTypeConstructs: (struct) => ({ 3 string: { 4 "date-time": "Date", 5 }, 6 }), 7});
See more about swagger schema type/format data here
Licensed under the MIT License.
No vulnerabilities found.
Reason
30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Reason
no dangerous workflow patterns detected
Reason
GitHub workflow tokens follow principle of least privilege
Details
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 existing vulnerabilities detected
Reason
SAST tool is not run on all commits -- score normalized to 8
Details
Reason
Found 1/6 approved changesets -- score normalized to 1
Reason
branch protection is not maximal on development and all release branches
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
project is not fuzzed
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More