@spec2ts/openapi 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as usage, n as describe, r as handler, t as builder } from "../command-kheR7V25.mjs";
2
+ import { i as usage, n as describe, r as handler, t as builder } from "../command-BDMCeG0A.mjs";
3
3
  import yargs from "yargs";
4
4
  import { hideBin } from "yargs/helpers";
5
5
  //#region src/bin/oapi2ts.ts
@@ -1,4 +1,4 @@
1
- import { t as ParseOpenApiOptions } from "../openapi-parser-RoDGKcjO.mjs";
1
+ import { t as ParseOpenApiOptions } from "../openapi-parser-BJ3RQyRq.mjs";
2
2
  import { Argv } from "yargs";
3
3
  //#region src/cli/command.d.ts
4
4
  interface BuildTsFromOpenApiOptions extends ParseOpenApiOptions {
@@ -1,2 +1,2 @@
1
- import { i as usage, n as describe, r as handler, t as builder } from "../command-kheR7V25.mjs";
1
+ import { i as usage, n as describe, r as handler, t as builder } from "../command-BDMCeG0A.mjs";
2
2
  export { builder, describe, handler, usage };
@@ -1,4 +1,4 @@
1
- import { n as parseOpenApiFile } from "./openapi-parser-CQvFG8Kq.mjs";
1
+ import { n as parseOpenApiFile } from "./openapi-parser-3wx-i5_G.mjs";
2
2
  import { cli, printer } from "@spec2ts/core";
3
3
  //#region src/cli/command.ts
4
4
  const usage = "$0 <input..>";
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as parseParameters, a as ParamType, c as createOpenApiResult, d as getOperationName, f as getParamType, g as parseOperation, h as getSchemaFromContent, i as OApiParserContext, l as getContentDeclaration, m as getResponseName, n as parseOpenApi, o as ParseOpenApiResult, p as getPathName, r as parseOpenApiFile, s as addToOpenApiResult, t as ParseOpenApiOptions, u as getOperationIdentifier, v as parsePathItem, y as parseReference } from "./openapi-parser-RoDGKcjO.mjs";
1
+ import { _ as parseParameters, a as ParamType, c as createOpenApiResult, d as getOperationName, f as getParamType, g as parseOperation, h as getSchemaFromContent, i as OApiParserContext, l as getContentDeclaration, m as getResponseName, n as parseOpenApi, o as ParseOpenApiResult, p as getPathName, r as parseOpenApiFile, s as addToOpenApiResult, t as ParseOpenApiOptions, u as getOperationIdentifier, v as parsePathItem, y as parseReference } from "./openapi-parser-BJ3RQyRq.mjs";
2
2
  export { OApiParserContext, ParamType, ParseOpenApiOptions, ParseOpenApiResult, addToOpenApiResult, createOpenApiResult, getContentDeclaration, getOperationIdentifier, getOperationName, getParamType, getPathName, getResponseName, getSchemaFromContent, parseOpenApi, parseOpenApiFile, parseOperation, parseParameters, parsePathItem, parseReference };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as getContentDeclaration, c as getParamType, d as getSchemaFromContent, f as parseOperation, h as parseReference, i as createOpenApiResult, l as getPathName, m as parsePathItem, n as parseOpenApiFile, o as getOperationIdentifier, p as parseParameters, r as addToOpenApiResult, s as getOperationName, t as parseOpenApi, u as getResponseName } from "./openapi-parser-CQvFG8Kq.mjs";
1
+ import { a as getContentDeclaration, c as getParamType, d as getSchemaFromContent, f as parseOperation, h as parseReference, i as createOpenApiResult, l as getPathName, m as parsePathItem, n as parseOpenApiFile, o as getOperationIdentifier, p as parseParameters, r as addToOpenApiResult, s as getOperationName, t as parseOpenApi, u as getResponseName } from "./openapi-parser-3wx-i5_G.mjs";
2
2
  export { addToOpenApiResult, createOpenApiResult, getContentDeclaration, getOperationIdentifier, getOperationName, getParamType, getPathName, getResponseName, getSchemaFromContent, parseOpenApi, parseOpenApiFile, parseOperation, parseParameters, parsePathItem, parseReference };
@@ -0,0 +1,184 @@
1
+ import * as core from "@spec2ts/core";
2
+ import { createContext, createRefContext, getTypeFromProperties, getTypeFromSchema, pascalCase, resolveReference } from "@spec2ts/jsonschema";
3
+ import ts from "typescript";
4
+ import $RefParser from "@apidevtools/json-schema-ref-parser";
5
+ import path from "node:path";
6
+ //#region src/lib/core-parser.ts
7
+ const VERBS = [
8
+ "GET",
9
+ "PUT",
10
+ "POST",
11
+ "DELETE",
12
+ "OPTIONS",
13
+ "HEAD",
14
+ "PATCH",
15
+ "TRACE"
16
+ ];
17
+ function parsePathItem(path, item, context, result) {
18
+ const baseParams = item.parameters && parseParameters(getPathName(path, context), item.parameters, void 0, context, result);
19
+ Object.entries(item).filter(([verb]) => VERBS.includes(verb.toUpperCase())).forEach(([verb, entry]) => parseOperation(path, verb, entry, baseParams, context, result));
20
+ }
21
+ function parseOperation(path, verb, operation, baseParams, context, result) {
22
+ const name = getOperationName(verb, path, operation.operationId, context);
23
+ if (operation.parameters) parseParameters(name, operation.parameters, baseParams, context, result);
24
+ if (operation.requestBody) {
25
+ const requestBody = resolveReference(operation.requestBody, context);
26
+ const decla = getContentDeclaration(name + "Body", requestBody.content, context);
27
+ if (decla) addToOpenApiResult(result, "body", decla);
28
+ }
29
+ if (operation.responses) {
30
+ const responses = resolveReference(operation.responses, context);
31
+ Object.entries(responses).forEach(([status, responseObj]) => {
32
+ const response = resolveReference(responseObj, context);
33
+ const decla = getContentDeclaration(getResponseName(name, status, context), response.content, context);
34
+ if (decla) addToOpenApiResult(result, "responses", decla);
35
+ });
36
+ }
37
+ }
38
+ function parseParameters(baseName, data, baseParams = {}, context, result) {
39
+ const params = [];
40
+ const query = [];
41
+ const headers = [];
42
+ const cookie = [];
43
+ const res = {};
44
+ data.forEach((item) => {
45
+ item = resolveReference(item, context);
46
+ switch (item.in) {
47
+ case "path":
48
+ params.push(item);
49
+ break;
50
+ case "header":
51
+ headers.push(item);
52
+ break;
53
+ case "query":
54
+ query.push(item);
55
+ break;
56
+ case "cookie":
57
+ cookie.push(item);
58
+ break;
59
+ }
60
+ });
61
+ addParams(params, "params");
62
+ addParams(headers, "headers");
63
+ addParams(query, "query");
64
+ addParams(cookie, "cookie");
65
+ return res;
66
+ function addParams(params, paramType) {
67
+ if (!params.length) return;
68
+ const name = baseName + pascalCase(paramType);
69
+ const type = getParamType(paramType, params, baseParams[paramType], context);
70
+ addToOpenApiResult(result, paramType, core.createTypeOrInterfaceDeclaration({
71
+ modifiers: [core.modifier.export],
72
+ name,
73
+ type
74
+ }));
75
+ res[paramType] = ts.factory.createTypeReferenceNode(name, void 0);
76
+ }
77
+ }
78
+ function parseReference(ref, context) {
79
+ const type = getTypeFromSchema(ref.schema, createRefContext(ref, context));
80
+ context.aliases.push(core.createTypeOrInterfaceDeclaration({
81
+ modifiers: [core.modifier.export],
82
+ name: ref.name,
83
+ type
84
+ }));
85
+ }
86
+ function getContentDeclaration(name, content, context) {
87
+ if (!content) return;
88
+ content = resolveReference(content, context);
89
+ const schema = getSchemaFromContent(content);
90
+ if (!schema) return;
91
+ const type = getTypeFromSchema(schema, context);
92
+ return core.createTypeOrInterfaceDeclaration({
93
+ modifiers: [core.modifier.export],
94
+ name,
95
+ type
96
+ });
97
+ }
98
+ function getParamType(paramType, data, baseType, context) {
99
+ const required = [];
100
+ const props = {};
101
+ data.forEach((m) => {
102
+ let name = m.name;
103
+ if (paramType === "headers" && context.options.lowerHeaders) name = name.toLowerCase();
104
+ props[name] = m.schema || {};
105
+ if (m.required) required.push(name);
106
+ });
107
+ const type = getTypeFromProperties(props, required, false, paramType === "query" && typeof context.options.enableDateForQueryParams !== "undefined" ? {
108
+ ...context,
109
+ options: {
110
+ ...context.options,
111
+ enableDate: context.options.enableDateForQueryParams
112
+ }
113
+ } : context);
114
+ if (baseType) return ts.factory.createIntersectionTypeNode([baseType, type]);
115
+ return type;
116
+ }
117
+ function getSchemaFromContent(content) {
118
+ return content?.["application/json"]?.schema || content?.["application/x-www-form-urlencoded"]?.schema || content?.["multipart/form-data"]?.schema || content?.["*/*"]?.schema;
119
+ }
120
+ function getResponseName(operationName, statusCode, context) {
121
+ let name = operationName + "Response";
122
+ const status = parseInt(statusCode);
123
+ if (status >= 200 && status < 300) {
124
+ if ((context.names[name] = (context.names[name] || 0) + 1) > 1) name += statusCode;
125
+ } else if (!isNaN(status)) name += statusCode;
126
+ else name += pascalCase(statusCode);
127
+ return name;
128
+ }
129
+ function getOperationName(verb, path, operationId, context) {
130
+ const id = getOperationIdentifier(operationId);
131
+ if (id) return id;
132
+ return getPathName(`${verb} ${path}`, context);
133
+ }
134
+ function getPathName(path, context) {
135
+ path = path.replace(/\{(.+?)\}/, "by $1").replace(/\{(.+?)\}/g, "and $1");
136
+ let name = pascalCase(path);
137
+ const count = context.names[name] = (context.names[name] || 0) + 1;
138
+ if (count > 1) name += count;
139
+ return name;
140
+ }
141
+ function getOperationIdentifier(id) {
142
+ if (!id) return;
143
+ if (id.match(/[^\w\s]/)) return;
144
+ id = pascalCase(id);
145
+ if (core.isValidIdentifier(id)) return id;
146
+ }
147
+ function addToOpenApiResult(result, prop, statement) {
148
+ const statements = Array.isArray(statement) ? statement : [statement];
149
+ result[prop].push(...statements);
150
+ result.all.push(...statements);
151
+ }
152
+ function createOpenApiResult() {
153
+ return {
154
+ params: [],
155
+ query: [],
156
+ headers: [],
157
+ body: [],
158
+ responses: [],
159
+ models: [],
160
+ cookie: [],
161
+ import: [],
162
+ all: []
163
+ };
164
+ }
165
+ //#endregion
166
+ //#region src/lib/openapi-parser.ts
167
+ async function parseOpenApiFile(file, options = {}) {
168
+ return parseOpenApi(await $RefParser.parse(file), {
169
+ cwd: path.resolve(path.dirname(file)) + "/",
170
+ ...options
171
+ });
172
+ }
173
+ async function parseOpenApi(spec, options = {}) {
174
+ if (!options.parseReference) options.parseReference = parseReference;
175
+ const context = await createContext(spec, options);
176
+ const result = createOpenApiResult();
177
+ Object.entries(spec.paths ?? {}).forEach(([path, item]) => {
178
+ parsePathItem(path, item, context, result);
179
+ });
180
+ addToOpenApiResult(result, "models", context.aliases);
181
+ return result;
182
+ }
183
+ //#endregion
184
+ export { getContentDeclaration as a, getParamType as c, getSchemaFromContent as d, parseOperation as f, parseReference as h, createOpenApiResult as i, getPathName as l, parsePathItem as m, parseOpenApiFile as n, getOperationIdentifier as o, parseParameters as p, addToOpenApiResult as r, getOperationName as s, parseOpenApi as t, getResponseName as u };
@@ -1,5 +1,5 @@
1
1
  import { ParsedReference, ParserContext, ParserOptions } from "@spec2ts/jsonschema";
2
- import * as ts from "typescript";
2
+ import ts from "typescript";
3
3
  import { ContentObject, OpenAPIObject, OperationObject, ParameterObject, PathItemObject, ReferenceObject, SchemaObject } from "openapi3-ts/oas31";
4
4
  //#region src/lib/core-parser.d.ts
5
5
  interface ParseOpenApiResult {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spec2ts/openapi",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "description": "Utility to convert OpenAPI v3 specifications to Typescript using TypeScript native compiler",
5
5
  "keywords": [
6
6
  "ast",
@@ -67,8 +67,9 @@
67
67
  "prepublishOnly": "npm run test:prepublish && npm run build"
68
68
  },
69
69
  "dependencies": {
70
- "@spec2ts/core": "^4.0.0",
71
- "@spec2ts/jsonschema": "^4.0.0",
70
+ "@apidevtools/json-schema-ref-parser": "^10.1.0",
71
+ "@spec2ts/core": "^4.0.1",
72
+ "@spec2ts/jsonschema": "^4.0.1",
72
73
  "openapi3-ts": "^4.6.0",
73
74
  "typescript": "^6.0.0",
74
75
  "yargs": "^18.0.0"