diff --git a/.eslintignore b/.eslintignore index 32b900c2f..3a11cb7f1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,5 @@ dist node_modules -samples temp test/e2e/generated test/generated diff --git a/.gitignore b/.gitignore index a24612ba8..9abd3a293 100644 --- a/.gitignore +++ b/.gitignore @@ -11,9 +11,6 @@ yarn-error.log* *.iml dist coverage -samples/generated -samples/swagger-codegen-cli-v2.jar -samples/swagger-codegen-cli-v3.jar .env # test files diff --git a/README.md b/README.md index 63bc744b7..20c2d3bff 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ or yarn add @nicolas-chaulet/openapi-typescript-codegen -D ``` -and add a script to your `package.json` file +If you want to use `openapi-ts` with CLI, add a script to your `package.json` file ```json "scripts": { @@ -57,6 +57,17 @@ and add a script to your `package.json` file } ``` +You can also generate your client programmatically by importing `openapi-ts` in a `.ts` file. + +```ts +import { createClient } from '@nicolas-chaulet/openapi-typescript-codegen' + +createClient({ + input: 'path/to/openapi.json', + output: 'src/client', +}) +``` + > ⚠️ You need to be running Node.js v18 or newer ## Configuration diff --git a/bin/index.js b/bin/index.js index 82e11a7eb..6c114f213 100755 --- a/bin/index.js +++ b/bin/index.js @@ -39,11 +39,8 @@ const params = program async function start() { try { - const OpenAPI = await import(new URL('../dist/index.js', import.meta.url)); - await OpenAPI.generate({ - ...params, - clientName: params.name, - }); + const { createClient } = await import(new URL('../dist/index.js', import.meta.url)); + await createClient(params); process.exit(0); } catch (error) { console.error(error); diff --git a/package.json b/package.json index 77c7b8948..e5c1cda2b 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "build-types-check": "tsc --project tsconfig.check.json", "build-types-roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", "build-types-temp": "tsc --emitDeclarationOnly --outDir temp -p src/node", - "clean": "rimraf dist test/generated test/e2e/generated samples/generated coverage node_modules/.cache", + "clean": "rimraf dist test/generated test/e2e/generated coverage node_modules/.cache", "eslint:fix": "eslint . --fix", "eslint": "eslint .", "prepublishOnly": "npm run build", diff --git a/samples/codegen.sh b/samples/codegen.sh deleted file mode 100755 index 89cf5e54d..000000000 --- a/samples/codegen.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -rm -rf dist -rm swagger-codegen-cli-v2.jar -rm swagger-codegen-cli-v3.jar - -curl https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.15/swagger-codegen-cli-2.4.15.jar -o swagger-codegen-cli-v2.jar -curl https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.21/swagger-codegen-cli-3.0.21.jar -o swagger-codegen-cli-v3.jar - -java -jar ./swagger-codegen-cli-v2.jar generate -i spec/v2.json -l typescript-aurelia -o generated/v2/typescript-aurelia/ -java -jar ./swagger-codegen-cli-v2.jar generate -i spec/v2.json -l typescript-angular -o generated/v2/typescript-angular/ -java -jar ./swagger-codegen-cli-v2.jar generate -i spec/v2.json -l typescript-inversify -o generated/v2/typescript-inversify/ -java -jar ./swagger-codegen-cli-v2.jar generate -i spec/v2.json -l typescript-fetch -o generated/v2/typescript-fetch/ -java -jar ./swagger-codegen-cli-v2.jar generate -i spec/v2.json -l typescript-jquery -o generated/v2/typescript-jquery/ -java -jar ./swagger-codegen-cli-v2.jar generate -i spec/v2.json -l typescript-node -o generated/v2/typescript-node/ - -java -jar ./swagger-codegen-cli-v3.jar generate -i spec/v3.json -l typescript-angular -o generated/v3/typescript-angular/ -java -jar ./swagger-codegen-cli-v3.jar generate -i spec/v3.json -l typescript-fetch -o generated/v3/typescript-fetch/ - -node ../bin/index.js --input spec/v2.json --output generated/v2/openapi-typescript-codegen/ -node ../bin/index.js --input spec/v3.json --output generated/v3/openapi-typescript-codegen/ diff --git a/samples/spec/v2.json b/samples/spec/v2.json deleted file mode 100644 index 46b4183ac..000000000 --- a/samples/spec/v2.json +++ /dev/null @@ -1,1061 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", - "version": "1.0.5", - "title": "Swagger Petstore", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "email": "apiteam@swagger.io" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - } - }, - "host": "petstore.swagger.io", - "basePath": "/v2", - "tags": [ - { - "name": "pet", - "description": "Everything about your Pets", - "externalDocs": { - "description": "Find out more", - "url": "http://swagger.io" - } - }, - { - "name": "store", - "description": "Access to Petstore orders" - }, - { - "name": "user", - "description": "Operations about user", - "externalDocs": { - "description": "Find out more about our store", - "url": "http://swagger.io" - } - } - ], - "schemes": [ - "https", - "http" - ], - "paths": { - "/pet/{petId}/uploadImage": { - "post": { - "tags": [ - "pet" - ], - "summary": "uploads an image", - "description": "", - "operationId": "uploadFile", - "consumes": [ - "multipart/form-data" - ], - "produces": [ - "application/json" - ], - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet to update", - "required": true, - "type": "integer", - "format": "int64" - }, - { - "name": "additionalMetadata", - "in": "formData", - "description": "Additional data to pass to server", - "required": false, - "type": "string" - }, - { - "name": "file", - "in": "formData", - "description": "file to upload", - "required": false, - "type": "file" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/ApiResponse" - } - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet": { - "post": { - "tags": [ - "pet" - ], - "summary": "Add a new pet to the store", - "description": "", - "operationId": "addPet", - "consumes": [ - "application/json", - "application/xml" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "Pet object that needs to be added to the store", - "required": true, - "schema": { - "$ref": "#/definitions/Pet" - } - } - ], - "responses": { - "405": { - "description": "Invalid input" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - }, - "put": { - "tags": [ - "pet" - ], - "summary": "Update an existing pet", - "description": "", - "operationId": "updatePet", - "consumes": [ - "application/json", - "application/xml" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "Pet object that needs to be added to the store", - "required": true, - "schema": { - "$ref": "#/definitions/Pet" - } - } - ], - "responses": { - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - }, - "405": { - "description": "Validation exception" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByStatus": { - "get": { - "tags": [ - "pet" - ], - "summary": "Finds Pets by status", - "description": "Multiple status values can be provided with comma separated strings", - "operationId": "findPetsByStatus", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "status", - "in": "query", - "description": "Status values that need to be considered for filter", - "required": true, - "type": "array", - "items": { - "type": "string", - "enum": [ - "available", - "pending", - "sold" - ], - "default": "available" - }, - "collectionFormat": "multi" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Pet" - } - } - }, - "400": { - "description": "Invalid status value" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByTags": { - "get": { - "tags": [ - "pet" - ], - "summary": "Finds Pets by tags", - "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", - "operationId": "findPetsByTags", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "tags", - "in": "query", - "description": "Tags to filter by", - "required": true, - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Pet" - } - } - }, - "400": { - "description": "Invalid tag value" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ], - "deprecated": true - } - }, - "/pet/{petId}": { - "get": { - "tags": [ - "pet" - ], - "summary": "Find pet by ID", - "description": "Returns a single pet", - "operationId": "getPetById", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet to return", - "required": true, - "type": "integer", - "format": "int64" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/Pet" - } - }, - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - } - }, - "security": [ - { - "api_key": [] - } - ] - }, - "post": { - "tags": [ - "pet" - ], - "summary": "Updates a pet in the store with form data", - "description": "", - "operationId": "updatePetWithForm", - "consumes": [ - "application/x-www-form-urlencoded" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet that needs to be updated", - "required": true, - "type": "integer", - "format": "int64" - }, - { - "name": "name", - "in": "formData", - "description": "Updated name of the pet", - "required": false, - "type": "string" - }, - { - "name": "status", - "in": "formData", - "description": "Updated status of the pet", - "required": false, - "type": "string" - } - ], - "responses": { - "405": { - "description": "Invalid input" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - }, - "delete": { - "tags": [ - "pet" - ], - "summary": "Deletes a pet", - "description": "", - "operationId": "deletePet", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "api_key", - "in": "header", - "required": false, - "type": "string" - }, - { - "name": "petId", - "in": "path", - "description": "Pet id to delete", - "required": true, - "type": "integer", - "format": "int64" - } - ], - "responses": { - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/store/order": { - "post": { - "tags": [ - "store" - ], - "summary": "Place an order for a pet", - "description": "", - "operationId": "placeOrder", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "order placed for purchasing the pet", - "required": true, - "schema": { - "$ref": "#/definitions/Order" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/Order" - } - }, - "400": { - "description": "Invalid Order" - } - } - } - }, - "/store/order/{orderId}": { - "get": { - "tags": [ - "store" - ], - "summary": "Find purchase order by ID", - "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions", - "operationId": "getOrderById", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "orderId", - "in": "path", - "description": "ID of pet that needs to be fetched", - "required": true, - "type": "integer", - "maximum": 10, - "minimum": 1, - "format": "int64" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/Order" - } - }, - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Order not found" - } - } - }, - "delete": { - "tags": [ - "store" - ], - "summary": "Delete purchase order by ID", - "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors", - "operationId": "deleteOrder", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "orderId", - "in": "path", - "description": "ID of the order that needs to be deleted", - "required": true, - "type": "integer", - "minimum": 1, - "format": "int64" - } - ], - "responses": { - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Order not found" - } - } - } - }, - "/store/inventory": { - "get": { - "tags": [ - "store" - ], - "summary": "Returns pet inventories by status", - "description": "Returns a map of status codes to quantities", - "operationId": "getInventory", - "produces": [ - "application/json" - ], - "parameters": [], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "object", - "additionalProperties": { - "type": "integer", - "format": "int32" - } - } - } - }, - "security": [ - { - "api_key": [] - } - ] - } - }, - "/user/createWithArray": { - "post": { - "tags": [ - "user" - ], - "summary": "Creates list of users with given input array", - "description": "", - "operationId": "createUsersWithArrayInput", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "List of user object", - "required": true, - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/User" - } - } - } - ], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user/createWithList": { - "post": { - "tags": [ - "user" - ], - "summary": "Creates list of users with given input array", - "description": "", - "operationId": "createUsersWithListInput", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "List of user object", - "required": true, - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/User" - } - } - } - ], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user/{username}": { - "get": { - "tags": [ - "user" - ], - "summary": "Get user by user name", - "description": "", - "operationId": "getUserByName", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "username", - "in": "path", - "description": "The name that needs to be fetched. Use user1 for testing. ", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/User" - } - }, - "400": { - "description": "Invalid username supplied" - }, - "404": { - "description": "User not found" - } - } - }, - "put": { - "tags": [ - "user" - ], - "summary": "Updated user", - "description": "This can only be done by the logged in user.", - "operationId": "updateUser", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "username", - "in": "path", - "description": "name that need to be updated", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "body", - "description": "Updated user object", - "required": true, - "schema": { - "$ref": "#/definitions/User" - } - } - ], - "responses": { - "400": { - "description": "Invalid user supplied" - }, - "404": { - "description": "User not found" - } - } - }, - "delete": { - "tags": [ - "user" - ], - "summary": "Delete user", - "description": "This can only be done by the logged in user.", - "operationId": "deleteUser", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "username", - "in": "path", - "description": "The name that needs to be deleted", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "Invalid username supplied" - }, - "404": { - "description": "User not found" - } - } - } - }, - "/user/login": { - "get": { - "tags": [ - "user" - ], - "summary": "Logs user into the system", - "description": "", - "operationId": "loginUser", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "name": "username", - "in": "query", - "description": "The user name for login", - "required": true, - "type": "string" - }, - { - "name": "password", - "in": "query", - "description": "The password for login in clear text", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "successful operation", - "headers": { - "X-Expires-After": { - "type": "string", - "format": "date-time", - "description": "date in UTC when token expires" - }, - "X-Rate-Limit": { - "type": "integer", - "format": "int32", - "description": "calls per hour allowed by the user" - } - }, - "schema": { - "type": "string" - } - }, - "400": { - "description": "Invalid username/password supplied" - } - } - } - }, - "/user/logout": { - "get": { - "tags": [ - "user" - ], - "summary": "Logs out current logged in user session", - "description": "", - "operationId": "logoutUser", - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user": { - "post": { - "tags": [ - "user" - ], - "summary": "Create user", - "description": "This can only be done by the logged in user.", - "operationId": "createUser", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json", - "application/xml" - ], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "Created user object", - "required": true, - "schema": { - "$ref": "#/definitions/User" - } - } - ], - "responses": { - "default": { - "description": "successful operation" - } - } - } - } - }, - "securityDefinitions": { - "api_key": { - "type": "apiKey", - "name": "api_key", - "in": "header" - }, - "petstore_auth": { - "type": "oauth2", - "authorizationUrl": "https://petstore.swagger.io/oauth/authorize", - "flow": "implicit", - "scopes": { - "read:pets": "read your pets", - "write:pets": "modify pets in your account" - } - } - }, - "definitions": { - "ApiResponse": { - "type": "object", - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "type": { - "type": "string" - }, - "message": { - "type": "string" - } - } - }, - "Category": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - } - }, - "xml": { - "name": "Category" - } - }, - "Pet": { - "type": "object", - "required": [ - "name", - "photoUrls" - ], - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - }, - "name": { - "type": "string", - "example": "doggie" - }, - "photoUrls": { - "type": "array", - "xml": { - "wrapped": true - }, - "items": { - "type": "string", - "xml": { - "name": "photoUrl" - } - } - }, - "tags": { - "type": "array", - "xml": { - "wrapped": true - }, - "items": { - "xml": { - "name": "tag" - }, - "$ref": "#/definitions/Tag" - } - }, - "status": { - "type": "string", - "description": "pet status in the store", - "enum": [ - "available", - "pending", - "sold" - ] - } - }, - "xml": { - "name": "Pet" - } - }, - "Tag": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - } - }, - "xml": { - "name": "Tag" - } - }, - "Order": { - "type": "object", - "properties": { - "bool": { - "description": "Simple boolean enum", - "type": "boolean", - "enum": [ - true - ] - }, - "id": { - "type": "integer", - "format": "int64" - }, - "petId": { - "type": "integer", - "format": "int64" - }, - "quantity": { - "type": "integer", - "format": "int32" - }, - "shipDate": { - "type": "string", - "format": "date-time" - }, - "status": { - "type": "string", - "description": "Order Status", - "enum": [ - "placed", - "approved", - "delivered" - ] - }, - "complete": { - "type": "boolean" - } - }, - "xml": { - "name": "Order" - } - }, - "User": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "username": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "email": { - "type": "string" - }, - "password": { - "type": "string" - }, - "phone": { - "type": "string" - }, - "userStatus": { - "type": "integer", - "format": "int32", - "description": "User Status" - } - }, - "xml": { - "name": "User" - } - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - } -} diff --git a/samples/spec/v3.json b/samples/spec/v3.json deleted file mode 100644 index 2cddc31b1..000000000 --- a/samples/spec/v3.json +++ /dev/null @@ -1,1225 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "Swagger Petstore - OpenAPI 3.0", - "description": "This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about\nSwagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!\nYou can now help us improve the API whether it's by making changes to the definition itself or to the code.\nThat way, with time, we can improve the API in general, and expose some of the new features in OAS3.\n\nSome useful links:\n- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)\n- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) ", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "email": "apiteam@swagger.io" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - }, - "version": "1.0.4" - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "servers": [ - { - "url": "/api/v3" - } - ], - "tags": [ - { - "name": "pet", - "description": "Everything about your Pets", - "externalDocs": { - "description": "Find out more", - "url": "http://swagger.io" - } - }, - { - "name": "store", - "description": "Operations about user" - }, - { - "name": "user", - "description": "Access to Petstore orders", - "externalDocs": { - "description": "Find out more about our store", - "url": "http://swagger.io" - } - } - ], - "paths": { - "/pet": { - "put": { - "tags": [ - "pet" - ], - "summary": "Update an existing pet", - "description": "Update an existing pet by Id", - "operationId": "updatePet", - "requestBody": { - "description": "Update an existent pet in the store", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful operation", - "content": { - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - }, - "405": { - "description": "Validation exception" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - }, - "post": { - "tags": [ - "pet" - ], - "summary": "Add a new pet to the store", - "description": "Add a new pet to the store", - "operationId": "addPet", - "requestBody": { - "description": "Create a new pet in the store", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful operation", - "content": { - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "405": { - "description": "Invalid input" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByStatus": { - "get": { - "tags": [ - "pet" - ], - "summary": "Finds Pets by status", - "description": "Multiple status values can be provided with comma separated strings", - "operationId": "findPetsByStatus", - "parameters": [ - { - "name": "status", - "in": "query", - "description": "Status values that need to be considered for filter", - "required": false, - "explode": true, - "schema": { - "type": "string", - "default": "available", - "enum": [ - "available", - "pending", - "sold" - ] - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/xml": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Pet" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - }, - "400": { - "description": "Invalid status value" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByTags": { - "get": { - "tags": [ - "pet" - ], - "summary": "Finds Pets by tags", - "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", - "operationId": "findPetsByTags", - "parameters": [ - { - "name": "tags", - "in": "query", - "description": "Tags to filter by", - "required": false, - "explode": true, - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/xml": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Pet" - } - } - }, - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Pet" - } - } - } - } - }, - "400": { - "description": "Invalid tag value" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/{petId}": { - "get": { - "tags": [ - "pet" - ], - "summary": "Find pet by ID", - "description": "Returns a single pet", - "operationId": "getPetById", - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet to return", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - } - }, - "security": [ - { - "api_key": [] - }, - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - }, - "post": { - "tags": [ - "pet" - ], - "summary": "Updates a pet in the store with form data", - "description": "", - "operationId": "updatePetWithForm", - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet that needs to be updated", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "name", - "in": "query", - "description": "Name of pet that needs to be updated", - "schema": { - "type": "string" - } - }, - { - "name": "status", - "in": "query", - "description": "Status of pet that needs to be updated", - "schema": { - "type": "string" - } - } - ], - "responses": { - "405": { - "description": "Invalid input" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - }, - "delete": { - "tags": [ - "pet" - ], - "summary": "Deletes a pet", - "description": "", - "operationId": "deletePet", - "parameters": [ - { - "name": "api_key", - "in": "header", - "description": "", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "petId", - "in": "path", - "description": "Pet id to delete", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "responses": { - "400": { - "description": "Invalid pet value" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/{petId}/uploadImage": { - "post": { - "tags": [ - "pet" - ], - "summary": "uploads an image", - "description": "", - "operationId": "uploadFile", - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet to update", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "additionalMetadata", - "in": "query", - "description": "Additional Metadata", - "required": false, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/octet-stream": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiResponse" - } - } - } - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/store/inventory": { - "get": { - "tags": [ - "store" - ], - "summary": "Returns pet inventories by status", - "description": "Returns a map of status codes to quantities", - "operationId": "getInventory", - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/json": { - "schema": { - "type": "object", - "additionalProperties": { - "type": "integer", - "format": "int32" - } - } - } - } - } - }, - "security": [ - { - "api_key": [] - } - ] - } - }, - "/store/order": { - "post": { - "tags": [ - "store" - ], - "summary": "Place an order for a pet", - "description": "Place a new order in the store", - "operationId": "placeOrder", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Order" - } - }, - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Order" - } - }, - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/Order" - } - } - } - }, - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Order" - } - } - } - }, - "405": { - "description": "Invalid input" - } - } - } - }, - "/store/order/{orderId}": { - "get": { - "tags": [ - "store" - ], - "summary": "Find purchase order by ID", - "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", - "operationId": "getOrderById", - "parameters": [ - { - "name": "orderId", - "in": "path", - "description": "ID of order that needs to be fetched", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Order" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/Order" - } - } - } - }, - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Order not found" - } - } - }, - "delete": { - "tags": [ - "store" - ], - "summary": "Delete purchase order by ID", - "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", - "operationId": "deleteOrder", - "parameters": [ - { - "name": "orderId", - "in": "path", - "description": "ID of the order that needs to be deleted", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], - "responses": { - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Order not found" - } - } - } - }, - "/user": { - "post": { - "tags": [ - "user" - ], - "summary": "Create user", - "description": "This can only be done by the logged in user.", - "operationId": "createUser", - "requestBody": { - "description": "Created user object", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/xml": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "responses": { - "default": { - "description": "successful operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/xml": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - } - } - } - }, - "/user/createWithList": { - "post": { - "tags": [ - "user" - ], - "summary": "Creates list of users with given input array", - "description": "Creates list of users with given input array", - "operationId": "createUsersWithListInput", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "responses": { - "200": { - "description": "Successful operation", - "content": { - "application/xml": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "default": { - "description": "successful operation" - } - } - } - }, - "/user/login": { - "get": { - "tags": [ - "user" - ], - "summary": "Logs user into the system", - "description": "", - "operationId": "loginUser", - "parameters": [ - { - "name": "username", - "in": "query", - "description": "The user name for login", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "password", - "in": "query", - "description": "The password for login in clear text", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "headers": { - "X-Rate-Limit": { - "description": "calls per hour allowed by the user", - "schema": { - "type": "integer", - "format": "int32" - } - }, - "X-Expires-After": { - "description": "date in UTC when token expires", - "schema": { - "type": "string", - "format": "date-time" - } - } - }, - "content": { - "application/xml": { - "schema": { - "type": "string" - } - }, - "application/json": { - "schema": { - "type": "string" - } - } - } - }, - "400": { - "description": "Invalid username/password supplied" - } - } - } - }, - "/user/logout": { - "get": { - "tags": [ - "user" - ], - "summary": "Logs out current logged in user session", - "description": "", - "operationId": "logoutUser", - "parameters": [], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user/{username}": { - "get": { - "tags": [ - "user" - ], - "summary": "Get user by user name", - "description": "", - "operationId": "getUserByName", - "parameters": [ - { - "name": "username", - "in": "path", - "description": "The name that needs to be fetched. Use user1 for testing. ", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/xml": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "400": { - "description": "Invalid username supplied" - }, - "404": { - "description": "User not found" - } - } - }, - "put": { - "tags": [ - "user" - ], - "summary": "Update user", - "description": "This can only be done by the logged in user.", - "operationId": "updateUser", - "parameters": [ - { - "name": "username", - "in": "path", - "description": "name that need to be deleted", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "description": "Update an existent user in the store", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/xml": { - "schema": { - "$ref": "#/components/schemas/User" - } - }, - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/User" - } - } - } - }, - "responses": { - "default": { - "description": "successful operation" - } - } - }, - "delete": { - "tags": [ - "user" - ], - "summary": "Delete user", - "description": "This can only be done by the logged in user.", - "operationId": "deleteUser", - "parameters": [ - { - "name": "username", - "in": "path", - "description": "The name that needs to be deleted", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "400": { - "description": "Invalid username supplied" - }, - "404": { - "description": "User not found" - } - } - } - } - }, - "components": { - "schemas": { - "Order": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "example": 10 - }, - "petId": { - "type": "integer", - "format": "int64", - "example": 198772 - }, - "quantity": { - "type": "integer", - "format": "int32", - "example": 7 - }, - "shipDate": { - "type": "string", - "format": "date-time" - }, - "status": { - "type": "string", - "description": "Order Status", - "example": "approved", - "enum": [ - "placed", - "approved", - "delivered" - ] - }, - "complete": { - "type": "boolean" - } - }, - "xml": { - "name": "order" - } - }, - "Customer": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "example": 100000 - }, - "username": { - "type": "string", - "example": "fehguy" - }, - "address": { - "type": "array", - "xml": { - "name": "addresses", - "wrapped": true - }, - "items": { - "$ref": "#/components/schemas/Address" - } - } - }, - "xml": { - "name": "customer" - } - }, - "Address": { - "type": "object", - "properties": { - "street": { - "type": "string", - "example": "437 Lytton" - }, - "city": { - "type": "string", - "example": "Palo Alto" - }, - "state": { - "type": "string", - "example": "CA" - }, - "zip": { - "type": "string", - "example": "94301" - } - }, - "xml": { - "name": "address" - } - }, - "Category": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "type": "string", - "example": "Dogs" - } - }, - "xml": { - "name": "category" - } - }, - "User": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "example": 10 - }, - "username": { - "type": "string", - "example": "theUser" - }, - "firstName": { - "type": "string", - "example": "John" - }, - "lastName": { - "type": "string", - "example": "James" - }, - "email": { - "type": "string", - "example": "john@email.com" - }, - "password": { - "type": "string", - "example": "12345" - }, - "phone": { - "type": "string", - "example": "12345" - }, - "userStatus": { - "type": "integer", - "description": "User Status", - "format": "int32", - "example": 1 - } - }, - "xml": { - "name": "user" - } - }, - "Tag": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - } - }, - "xml": { - "name": "tag" - } - }, - "Pet": { - "required": [ - "name", - "photoUrls" - ], - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "example": 10 - }, - "name": { - "type": "string", - "example": "doggie" - }, - "category": { - "$ref": "#/components/schemas/Category" - }, - "photoUrls": { - "type": "array", - "xml": { - "wrapped": true - }, - "items": { - "type": "string", - "xml": { - "name": "photoUrl" - } - } - }, - "tags": { - "type": "array", - "xml": { - "wrapped": true - }, - "items": { - "$ref": "#/components/schemas/Tag" - } - }, - "status": { - "type": "string", - "description": "pet status in the store", - "enum": [ - "available", - "pending", - "sold" - ] - } - }, - "xml": { - "name": "pet" - } - }, - "ApiResponse": { - "type": "object", - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "type": { - "type": "string" - }, - "message": { - "type": "string" - } - }, - "xml": { - "name": "##default" - } - } - }, - "requestBodies": { - "Pet": { - "description": "Pet object that needs to be added to the store", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - }, - "application/xml": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "UserArray": { - "description": "List of user object", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - } - } - } - } - }, - "securitySchemes": { - "petstore_auth": { - "type": "oauth2", - "flows": { - "implicit": { - "authorizationUrl": "https://petstore3.swagger.io/oauth/authorize", - "scopes": { - "write:pets": "modify pets in your account", - "read:pets": "read your pets" - } - } - } - }, - "api_key": { - "type": "apiKey", - "name": "api_key", - "in": "header" - } - } - } -} diff --git a/src/index.spec.ts b/src/index.spec.ts index 7b365b261..6d2abb3a9 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -1,10 +1,10 @@ -import { generate, parseOpenApiSpecification } from './index'; +import { createClient, parseOpenApiSpecification } from './index'; import * as parseV2 from './openApi/v2'; import * as parseV3 from './openApi/v3'; describe('index', () => { it('parses v2 without issues', async () => { - await generate({ + await createClient({ input: './test/spec/v2.json', output: './generated/v2/', write: false, @@ -12,7 +12,7 @@ describe('index', () => { }); it('parses v3 without issues', async () => { - await generate({ + await createClient({ input: './test/spec/v3.json', output: './generated/v3/', write: false, @@ -20,7 +20,7 @@ describe('index', () => { }); it('downloads and parses v2 without issues', async () => { - await generate({ + await createClient({ input: 'https://raw.githubusercontent.com/ferdikoomen/openapi-typescript-codegen/master/test/spec/v2.json', output: './generated/v2-downloaded/', write: false, @@ -28,7 +28,7 @@ describe('index', () => { }); it('downloads and parses v3 without issues', async () => { - await generate({ + await createClient({ input: 'https://raw.githubusercontent.com/ferdikoomen/openapi-typescript-codegen/master/test/spec/v3.json', output: './generated/v3-downloaded/', write: false, diff --git a/src/index.ts b/src/index.ts index f553a7b5a..a490c5c4c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import { pathToFileURL } from 'node:url'; import { sync } from 'cross-spawn'; +import type { Client } from './client/interfaces/Client'; import { parse as parseV2 } from './openApi/v2'; import { parse as parseV3 } from './openApi/v3'; import type { Config, UserConfig } from './types/config'; @@ -79,19 +80,19 @@ const getConfigFromFile = async (): Promise => { const getConfig = async (userConfig: UserConfig, dependencies: Dependencies) => { const userConfigFromFile = await getConfigFromFile(); if (userConfigFromFile) { - userConfig = { ...userConfig, ...userConfigFromFile }; + userConfig = { ...userConfigFromFile, ...userConfig }; } const { autoformat = true, base, - clientName, enums = false, exportCore = true, exportModels = true, exportSchemas = false, exportServices = true, input, + name, operationId = true, output, postfixModels = '', @@ -109,13 +110,13 @@ const getConfig = async (userConfig: UserConfig, dependencies: Dependencies) => autoformat, base, client, - clientName, enums, exportCore, exportModels, exportSchemas, exportServices, input, + name, operationId, output, postfixModels, @@ -142,9 +143,9 @@ const getConfig = async (userConfig: UserConfig, dependencies: Dependencies) => * Generate the OpenAPI client. This method will read the OpenAPI specification and based on the * given language it will generate the client, including the typed models, validation schemas, * service layer, etc. - * @param userConfig {@link UserConfig} passed to the generate method + * @param userConfig {@link UserConfig} passed to the `createClient()` method */ -export const generate = async (userConfig: UserConfig): Promise => { +export async function createClient(userConfig: UserConfig): Promise { const pkg = JSON.parse(readFileSync(path.resolve(process.cwd(), 'package.json')).toString()); const dependencies = [pkg.dependencies, pkg.devDependencies].reduce( @@ -172,8 +173,17 @@ export const generate = async (userConfig: UserConfig): Promise => { } console.log('✨ Done! Your client is located in:', config.output); -}; + return client; +} + +/** + * Type helper for openapi-ts.config.ts, returns {@link UserConfig} object + */ +export function defineConfig(config: UserConfig): UserConfig { + return config; +} export default { - generate, + createClient, + defineConfig, }; diff --git a/src/node/index.ts b/src/node/index.ts index 6cdc9c07a..b59ae1e31 100644 --- a/src/node/index.ts +++ b/src/node/index.ts @@ -1,10 +1,2 @@ -import type { UserConfig } from '../types/config'; - +export { createClient, defineConfig } from '../'; export type { UserConfig } from '../types/config'; - -/** - * Type helper for openapi-ts.config.ts, returns {@link UserConfig} object - */ -export function defineConfig(config: UserConfig): UserConfig { - return config; -} diff --git a/src/openApi/v2/index.ts b/src/openApi/v2/index.ts index 849ca6315..3ca605386 100644 --- a/src/openApi/v2/index.ts +++ b/src/openApi/v2/index.ts @@ -10,7 +10,7 @@ import { getServiceVersion } from './parser/getServiceVersion'; * Parse the OpenAPI specification to a Client model that contains * all the models, services and schema's we should output. * @param openApi The OpenAPI spec that we have loaded from disk. - * @param options Options passed to the generate method + * @param options {@link Config} passed to the `createClient()` method */ export const parse = (openApi: OpenApi, options: Config): Client => { const version = getServiceVersion(openApi.info.version); diff --git a/src/openApi/v3/index.ts b/src/openApi/v3/index.ts index e93092cbb..1a0104d7a 100644 --- a/src/openApi/v3/index.ts +++ b/src/openApi/v3/index.ts @@ -10,7 +10,7 @@ import { getServiceVersion } from './parser/service'; * Parse the OpenAPI specification to a Client model that contains * all the models, services and schema's we should output. * @param openApi The OpenAPI spec that we have loaded from disk. - * @param options Options passed to the generate method + * @param options {@link Config} passed to the `createClient()` method */ export const parse = (openApi: OpenApi, options: Config): Client => { const version = getServiceVersion(openApi.info.version); diff --git a/src/templates/client.hbs b/src/templates/client.hbs index 7082b3e67..775bcae70 100644 --- a/src/templates/client.hbs +++ b/src/templates/client.hbs @@ -45,11 +45,11 @@ import { {{{name}}}{{{@root.$config.postfixServices}}} } from './services/{{{nam {{/each}} ] }) -export class {{{@root.$config.clientName}}} {} +export class {{{@root.$config.name}}} {} {{else}} type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest; -export class {{{@root.$config.clientName}}} { +export class {{{@root.$config.name}}} { {{#each services}} public readonly {{{camelCase name}}}: {{{name}}}{{{@root.$config.postfixServices}}}; diff --git a/src/templates/exportService.hbs b/src/templates/exportService.hbs index 103f8c305..356c421f9 100644 --- a/src/templates/exportService.hbs +++ b/src/templates/exportService.hbs @@ -1,5 +1,5 @@ {{#equals @root.$config.client 'angular'}} -{{#if @root.$config.clientName}} +{{#if @root.$config.name}} import { Injectable } from '@angular/core'; import type { Observable } from 'rxjs'; {{else}} @@ -15,7 +15,7 @@ import type { ApiResult } from '../core/ApiResult'; {{#notEquals @root.$config.client 'angular'}} import type { CancelablePromise } from '../core/CancelablePromise'; {{/notEquals}} -{{#if @root.$config.clientName}} +{{#if @root.$config.name}} {{#equals @root.$config.client 'angular'}} import { BaseHttpRequest } from '../core/BaseHttpRequest'; {{else}} @@ -45,7 +45,7 @@ import { request as __request } from '../core/request'; }) {{/equals}} export class {{{name}}}{{{@root.$config.postfixServices}}} { - {{#if @root.$config.clientName}} + {{#if @root.$config.name}} constructor(public readonly httpRequest: BaseHttpRequest) {} {{else}} @@ -78,7 +78,7 @@ export class {{{name}}}{{{@root.$config.postfixServices}}} { {{/each}} * @throws ApiError */ - {{#if @root.$config.clientName}} + {{#if @root.$config.name}} {{#equals @root.$config.client 'angular'}} public {{{name}}}{{>operationTypes}}({{>operationParameters}}): Observable<{{>operationResult}}> { {{>dataDestructure}} diff --git a/src/templates/index.hbs b/src/templates/index.hbs index c0e03c88d..184d3f50b 100644 --- a/src/templates/index.hbs +++ b/src/templates/index.hbs @@ -1,10 +1,10 @@ -{{#if @root.$config.clientName}} -export { {{{@root.$config.clientName}}} } from './{{{@root.$config.clientName}}}'; +{{#if @root.$config.name}} +export { {{{@root.$config.name}}} } from './{{{@root.$config.name}}}'; {{/if}} {{#if @root.$config.exportCore}} export { ApiError } from './core/ApiError'; -{{#if @root.$config.clientName}} +{{#if @root.$config.name}} export { BaseHttpRequest } from './core/BaseHttpRequest'; {{/if}} export { CancelablePromise, CancelError } from './core/CancelablePromise'; diff --git a/src/templates/partials/dataDestructure.hbs b/src/templates/partials/dataDestructure.hbs index 3c1ddc107..e99bed7e9 100644 --- a/src/templates/partials/dataDestructure.hbs +++ b/src/templates/partials/dataDestructure.hbs @@ -1,4 +1,4 @@ -{{~#if @root.$config.clientName~}} +{{~#if @root.$config.name~}} {{#if @root.$config.useOptions~}} {{#if parameters}} const { diff --git a/src/templates/partials/operationParameters.hbs b/src/templates/partials/operationParameters.hbs index 852f9e269..2d466da83 100644 --- a/src/templates/partials/operationParameters.hbs +++ b/src/templates/partials/operationParameters.hbs @@ -1,5 +1,5 @@ {{#if @root.$config.useOptions~}} -{{~#if @root.$config.clientName~}} +{{~#if @root.$config.name~}} {{#if parameters}}data: {{{nameOperationDataType name}}}{{#ifOperationDataOptional parameters}} = {}{{/ifOperationDataOptional}}{{/if}} {{~else~}} {{~#notEquals @root.$config.serviceResponse 'generics'~}} diff --git a/src/templates/partials/operationResult.hbs b/src/templates/partials/operationResult.hbs index 730491e48..1045e1e4d 100644 --- a/src/templates/partials/operationResult.hbs +++ b/src/templates/partials/operationResult.hbs @@ -2,7 +2,7 @@ {{~#notEquals @root.$config.serviceResponse 'generics'~}} {{~#equals @root.$config.serviceResponse 'response'}}ApiResult<{{/equals~}} {{~else~}} -{{~#unless @root.$config.clientName}}TApiResponse{{/equals~}} {{~else~}} -{{~#unless @root.$config.clientName}}>{{/unless~}} +{{~#unless @root.$config.name}}>{{/unless~}} {{~/notEquals~}} -{{~/if~}} \ No newline at end of file +{{~/if~}} diff --git a/src/templates/partials/operationTypes.hbs b/src/templates/partials/operationTypes.hbs index eb1700fc5..fcdcfcae0 100644 --- a/src/templates/partials/operationTypes.hbs +++ b/src/templates/partials/operationTypes.hbs @@ -1,6 +1,6 @@ {{#if @root.$config.useOptions~}} {{#equals @root.$config.serviceResponse 'generics'}} -{{~#unless @root.$config.clientName~}} +{{~#unless @root.$config.name~}} {{~/unless~}} {{/equals}} diff --git a/src/types/config.ts b/src/types/config.ts index 508700191..7f781478a 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -13,10 +13,6 @@ export interface UserConfig { * @default 'fetch' */ client?: 'angular' | 'axios' | 'fetch' | 'node' | 'xhr'; - /** - * Custom client class name - */ - clientName?: string; /** * Generate JavaScript objects from enum definitions * @default false @@ -46,6 +42,10 @@ export interface UserConfig { * The relative location of the OpenAPI spec */ input: string | Record; + /** + * Custom client class name + */ + name?: string; /** * Use operation ID to generate operation names? * @default true @@ -91,5 +91,5 @@ export interface UserConfig { write?: boolean; } -export type Config = Omit, 'base' | 'clientName' | 'request'> & - Pick; +export type Config = Omit, 'base' | 'name' | 'request'> & + Pick; diff --git a/src/utils/write/__tests__/class.spec.ts b/src/utils/write/__tests__/class.spec.ts index affe574f1..9ede16f77 100644 --- a/src/utils/write/__tests__/class.spec.ts +++ b/src/utils/write/__tests__/class.spec.ts @@ -36,8 +36,8 @@ describe('writeClientClass', () => { await writeClientClass(client, templates, './dist', { client: 'fetch', - clientName: 'AppClient', enums: true, + name: 'AppClient', postfixServices: '', }); diff --git a/src/utils/write/class.ts b/src/utils/write/class.ts index ab81a092d..c50a25558 100644 --- a/src/utils/write/class.ts +++ b/src/utils/write/class.ts @@ -20,7 +20,7 @@ export const writeClientClass = async ( client: Client, templates: Templates, outputPath: string, - options: Pick, 'client' | 'clientName' | 'enums' | 'postfixServices'> + options: Pick, 'client' | 'enums' | 'name' | 'postfixServices'> ): Promise => { const templateResult = templates.client({ $config: options, @@ -31,5 +31,5 @@ export const writeClientClass = async ( version: client.version, }); - await writeFileSync(path.resolve(outputPath, `${options.clientName}.ts`), templateResult); + await writeFileSync(path.resolve(outputPath, `${options.name}.ts`), templateResult); }; diff --git a/src/utils/write/client.ts b/src/utils/write/client.ts index 216e370fd..7ba407b71 100644 --- a/src/utils/write/client.ts +++ b/src/utils/write/client.ts @@ -16,7 +16,7 @@ import { writeClientServices } from './services'; * Write our OpenAPI client, using the given templates at the given output * @param client Client containing models, schemas, and services * @param templates Templates wrapper with all loaded Handlebars templates - * @param options {@link Config} passed to the `generate()` function + * @param options {@link Config} passed to the `createClient()` method */ export const writeClient = async (client: Client, templates: Templates, options: Config): Promise => { const outputPath = path.resolve(process.cwd(), options.output); @@ -83,13 +83,13 @@ export const writeClient = async (client: Client, templates: Templates, options: await writeClientServices(client, templates, outputPathServices, options); } - if (options.clientName) { + if (options.name) { await mkdirSync(outputPath, { recursive: true, }); await writeClientClass(client, templates, outputPath, { ...options, - clientName: options.clientName, + name: options.name, }); } diff --git a/src/utils/write/core.ts b/src/utils/write/core.ts index 6be712ac0..80ef60ace 100644 --- a/src/utils/write/core.ts +++ b/src/utils/write/core.ts @@ -75,7 +75,7 @@ export const writeClientCore = async ( }) ); - if (options.clientName) { + if (options.name) { await writeFileSync( path.resolve(outputPath, 'BaseHttpRequest.ts'), templates.core.baseHttpRequest({ diff --git a/src/utils/write/index.ts b/src/utils/write/index.ts index 41815d56f..6a8d6b06d 100644 --- a/src/utils/write/index.ts +++ b/src/utils/write/index.ts @@ -29,7 +29,7 @@ export const writeClientIndex = async ( | 'postfixServices' | 'postfixModels' > & - Pick + Pick ): Promise => { const templateResult = templates.index({ $config: options, diff --git a/src/utils/write/services.ts b/src/utils/write/services.ts index 752f41d63..44b1f07f0 100644 --- a/src/utils/write/services.ts +++ b/src/utils/write/services.ts @@ -10,7 +10,7 @@ import type { Templates } from '../handlebars'; * @param client Client containing models, schemas, and services * @param templates The loaded handlebar templates * @param outputPath Directory to write the generated files to - * @param options {@link Config} passed to the `generate()` function + * @param options {@link Config} passed to the `createClient()` method */ export const writeClientServices = async ( client: Client, diff --git a/test/e2e/scripts/generateClient.ts b/test/e2e/scripts/generateClient.ts index d4163427a..e3fd08644 100644 --- a/test/e2e/scripts/generateClient.ts +++ b/test/e2e/scripts/generateClient.ts @@ -1,16 +1,16 @@ -import { generate as __generate } from '../../../'; +import { createClient } from '../../../'; export const generateClient = async ( dir: string, version: string, client: 'fetch' | 'xhr' | 'node' | 'axios' | 'angular', useOptions: boolean = false, - clientName?: string + name?: string ) => { - await __generate({ + await createClient({ client, - clientName, input: `./test/spec/${version}.json`, + name, output: `./test/e2e/generated/${dir}/`, useOptions, }); diff --git a/test/index.spec.ts b/test/index.spec.ts index bdbd1b8d2..a365430c0 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -2,11 +2,11 @@ import { readFileSync } from 'node:fs'; import { sync } from 'glob'; -import { generate } from '../'; +import { createClient } from '../'; describe('v2', () => { it('should generate', async () => { - await generate({ + await createClient({ client: 'fetch', enums: true, exportCore: true, @@ -27,7 +27,7 @@ describe('v2', () => { describe('v3', () => { it('should generate', async () => { - await generate({ + await createClient({ client: 'fetch', enums: true, exportCore: true, @@ -46,7 +46,7 @@ describe('v3', () => { }); it('should generate Date types', async () => { - await generate({ + await createClient({ client: 'fetch', enums: true, exportCore: false, @@ -66,7 +66,7 @@ describe('v3', () => { }); it('should generate optional argument', async () => { - await generate({ + await createClient({ client: 'fetch', enums: true, exportCore: true, diff --git a/test/sample.cjs b/test/sample.cjs index eefdd00ce..791ef9473 100644 --- a/test/sample.cjs +++ b/test/sample.cjs @@ -11,8 +11,8 @@ const main = async () => { useOptions: true, }; - const { generate } = await import(path.resolve(process.cwd(), 'dist/index.js')); - await generate(config); + const { createClient } = await import(path.resolve(process.cwd(), 'dist/index.js')); + await createClient(config); }; main();