New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

openapi-typescript

Package Overview
Dependencies
Maintainers
1
Versions
145
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openapi-typescript - npm Package Compare versions

Comparing version 6.4.2 to 6.4.3

6

CHANGELOG.md
# openapi-typescript
## 6.4.3
### Patch Changes
- [#1287](https://github.com/drwpow/openapi-typescript/pull/1287) [`8a9d8ed`](https://github.com/drwpow/openapi-typescript/commit/8a9d8ede95802370c4015846a4856fd0701ada33) Thanks [@drwpow](https://github.com/drwpow)! - Fix oneOf handling with empty object parent type
## 6.4.2

@@ -4,0 +10,0 @@

4

CONTRIBUTING.md

@@ -9,3 +9,3 @@ # Contributing

Please check out the [the open issues](https://github.com/drwpow/openapi-typescript/issues). Issues labelled [**Help Wanted**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [**Good First Issue**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) are especially good to help with.
Please check out the [the open issues](https://github.com/drwpow/openapi-typescript/issues). Issues labelled [**Good First Issue**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)are especially good to start with.

@@ -30,3 +30,3 @@ Contributing doesn’t have to be in code! Simply answering questions in open issues, or providing workarounds, is just as important a contribution as making pull requests.

While best practices for commit messages are encouraged (e.g. start with an imperative verb, keep it short, use the body if needed), this repo doesn’t follow any specific guidelines like [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Clarity is favored over strict rules. Changelogs are generated separately from git (see [the Changelogs section](#changelogs)
While best practices for commit messages are encouraged (e.g. start with an imperative verb, keep it short, use the body if needed), this repo doesn’t follow any specific guidelines. Clarity is favored over strict rules. Changelogs are generated separately from git (see [the Changelogs section](#changelogs))

@@ -33,0 +33,0 @@ When working locally, run:

@@ -17,3 +17,3 @@ /// <reference types="node" resolution-mode="require"/>

urlCache: Set<string>;
httpHeaders?: Record<string, any>;
httpHeaders?: Record<string, unknown>;
httpMethod?: string;

@@ -20,0 +20,0 @@ fetch: Fetch;

@@ -14,3 +14,3 @@ import fs from "node:fs";

catch (err) {
error(`YAML: ${err.toString()}`);
error(`YAML: ${String(err)}`);
process.exit(1);

@@ -24,3 +24,3 @@ }

catch (err) {
error(`JSON: ${err.toString()}`);
error(`JSON: ${String(err)}`);
process.exit(1);

@@ -206,3 +206,3 @@ }

for (const subschemaID of Object.keys(options.schemas)) {
walk(options.schemas[subschemaID].schema, (rawNode, nodePath) => {
walk(options.schemas[subschemaID].schema, (rawNode) => {
if (!("$ref" in rawNode) || typeof rawNode.$ref !== "string")

@@ -209,0 +209,0 @@ return;

@@ -58,3 +58,3 @@ import { escObjKey, escStr, getEntries, getSchemaObjectComment, indent, parseRef, tsArrayOf, tsIntersectionOf, tsOmit, tsOneOf, tsOptionalProperty, tsReadonly, tsTupleOf, tsUnionOf, tsWithRequired } from "../utils.js";

const oneOfTypes = oneOfNormalized.some((t) => typeof t === "string" && t.includes("{")) ? tsOneOf(...oneOfNormalized) : tsUnionOf(...oneOfNormalized);
if ("type" in schemaObject && schemaObject.type === "object") {
if ("type" in schemaObject && schemaObject.type === "object" && (schemaObject.properties || schemaObject.additionalProperties)) {
return tsIntersectionOf(transformSchemaObject({ ...schemaObject, oneOf: undefined, enum: undefined }, { path, ctx }), oneOfTypes);

@@ -157,3 +157,3 @@ }

if (discriminator.mapping) {
const matchedValue = Object.entries(discriminator.mapping).find(([_, v]) => (!v.startsWith("#") && v === value) || (v.startsWith("#") && parseRef(v).path.pop() === value));
const matchedValue = Object.entries(discriminator.mapping).find(([, v]) => (!v.startsWith("#") && v === value) || (v.startsWith("#") && parseRef(v).path.pop() === value));
if (matchedValue)

@@ -179,3 +179,3 @@ value = matchedValue[0];

}
if ("oneOf" in schemaObject && Array.isArray(schemaObject.oneOf)) {
if (Array.isArray(schemaObject.oneOf) && schemaObject.oneOf.length) {
const oneOfType = tsUnionOf(...collectCompositions(schemaObject.oneOf));

@@ -185,3 +185,3 @@ finalType = finalType ? tsIntersectionOf(finalType, oneOfType) : oneOfType;

else {
if ("allOf" in schemaObject && Array.isArray(schemaObject.allOf)) {
if (Array.isArray(schemaObject.allOf) && schemaObject.allOf.length) {
finalType = tsIntersectionOf(...(finalType ? [finalType] : []), ...collectCompositions(schemaObject.allOf));

@@ -192,3 +192,3 @@ if ("required" in schemaObject && Array.isArray(schemaObject.required)) {

}
if ("anyOf" in schemaObject && Array.isArray(schemaObject.anyOf)) {
if (Array.isArray(schemaObject.anyOf) && schemaObject.anyOf.length) {
const anyOfTypes = tsUnionOf(...collectCompositions(schemaObject.anyOf));

@@ -195,0 +195,0 @@ finalType = finalType ? tsIntersectionOf(finalType, anyOfTypes) : anyOfTypes;

@@ -207,15 +207,9 @@ /// <reference types="node" resolution-mode="require"/>

nullable?: boolean;
oneOf?: (SchemaObject | ReferenceObject)[];
allOf?: (SchemaObject | ReferenceObject)[];
anyOf?: (SchemaObject | ReferenceObject)[];
required?: string[];
[key: `x-${string}`]: any;
} & ({
oneOf: (SchemaObject | ReferenceObject)[];
} | StringSubtype | NumberSubtype | IntegerSubtype | ArraySubtype | BooleanSubtype | NullSubtype | ObjectSubtype | {
} & (StringSubtype | NumberSubtype | IntegerSubtype | ArraySubtype | BooleanSubtype | NullSubtype | ObjectSubtype | {
type: ("string" | "number" | "integer" | "array" | "boolean" | "null" | "object")[];
} | {
allOf: (SchemaObject | ReferenceObject)[];
anyOf?: (SchemaObject | ReferenceObject)[];
required?: string[];
} | {
allOf?: (SchemaObject | ReferenceObject)[];
anyOf: (SchemaObject | ReferenceObject)[];
required?: string[];
} | {});

@@ -222,0 +216,0 @@ export interface StringSubtype {

@@ -42,3 +42,3 @@ import c from "ansi-colors";

export declare function tsUnionOf(...types: (string | number | boolean)[]): string;
export declare function escStr(input: any): string;
export declare function escStr(input: unknown): string;
export declare function escObjKey(input: string): string;

@@ -45,0 +45,0 @@ export declare function indent(input: string, level: number): string;

{
"name": "openapi-typescript",
"description": "Generate TypeScript types from Swagger OpenAPI specs",
"version": "6.4.2",
"version": "6.4.3",
"author": {

@@ -44,6 +44,6 @@ "name": "Drew Powers",

"ansi-colors": "^4.1.3",
"fast-glob": "^3.3.0",
"fast-glob": "^3.3.1",
"js-yaml": "^4.1.0",
"supports-color": "^9.4.0",
"undici": "^5.22.1",
"undici": "^5.23.0",
"yargs-parser": "^21.1.1"

@@ -54,8 +54,8 @@ },

"@types/js-yaml": "^4.0.5",
"@types/node": "^20.4.0",
"@types/node": "^20.4.9",
"degit": "^2.8.4",
"del-cli": "^5.0.0",
"esbuild": "^0.18.17",
"esbuild": "^0.19.0",
"execa": "^6.1.0",
"vite": "^4.4.1",
"vite": "^4.4.9",
"vite-node": "^0.33.0",

@@ -62,0 +62,0 @@ "vitest": "^0.33.0"

@@ -1,2 +0,2 @@

import type { GlobalContext, OpenAPI3, OpenAPITSOptions, Subschema } from "./types.js";
import type { GlobalContext, OpenAPI3, OpenAPITSOptions, SchemaObject, Subschema } from "./types.js";
import type { Readable } from "node:stream";

@@ -78,2 +78,3 @@ import { URL } from "node:url";

const subschema = allSchemas[k];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (typeof (subschema.schema as any).swagger === "string") {

@@ -160,3 +161,3 @@ error("Swagger 2.0 and older no longer supported. Please use v5.");

if (typeof subschema.schema === "object" && ("schema" in subschema.schema || "type" in subschema.schema)) {
subschemaOutput = transformSchemaObject(subschema.schema as any, { path, ctx: { ...ctx, indentLv } });
subschemaOutput = transformSchemaObject(subschema.schema as SchemaObject, { path, ctx: { ...ctx, indentLv } });
} else {

@@ -186,3 +187,3 @@ subschemaOutput += "{\n";

if (!schemaObject || typeof schemaObject !== "object") continue;
const c = getSchemaObjectComment(schemaObject as any, indentLv);
const c = getSchemaObjectComment(schemaObject as SchemaObject, indentLv);
if (c) subschemaOutput += indent(c, indentLv);

@@ -194,3 +195,3 @@

if (method in schemaObject) {
subschemaOutput += indent(`${escObjKey(name)}: ${transformPathItemObject(schemaObject as any, { path: `${path}${name}`, ctx: { ...ctx, indentLv } })};\n`, indentLv);
subschemaOutput += indent(`${escObjKey(name)}: ${transformPathItemObject(schemaObject, { path: `${path}${name}`, ctx: { ...ctx, indentLv } })};\n`, indentLv);
continue outer;

@@ -214,3 +215,3 @@ }

default: {
error(`Could not resolve subschema ${subschemaID}. Unknown type "${(subschema as any).hint}".`);
error(`Could not resolve subschema ${subschemaID}. Unknown type "${subschema.hint}".`);
process.exit(1);

@@ -252,3 +253,3 @@ }

"type OneOf<T extends any[]> = T extends [infer Only] ? Only : T extends [infer A, infer B, ...infer Rest] ? OneOf<[XOR<A, B>, ...Rest]> : never;",
""
"",
);

@@ -255,0 +256,0 @@ }

@@ -17,7 +17,7 @@ import type { ComponentsObject, Fetch, GlobalContext, OpenAPI3, OperationObject, ParameterObject, PathItemObject, ReferenceObject, RequestBodyObject, ResponseObject, SchemaObject, Subschema } from "./types.js";

function parseYAML(schema: any): any {
function parseYAML(schema: string) {
try {
return yaml.load(schema);
} catch (err: any) {
error(`YAML: ${err.toString()}`);
} catch (err) {
error(`YAML: ${String(err)}`);
process.exit(1);

@@ -27,7 +27,7 @@ }

function parseJSON(schema: any): any {
function parseJSON(schema: string) {
try {
return JSON.parse(schema);
} catch (err: any) {
error(`JSON: ${err.toString()}`);
} catch (err) {
error(`JSON: ${String(err)}`);
process.exit(1);

@@ -61,3 +61,3 @@ }

*/
function parseHttpHeaders(httpHeaders: Record<string, any>): Record<string, any> {
function parseHttpHeaders(httpHeaders: Record<string, unknown>): Record<string, unknown> {
const finalHeaders: Record<string, string> = {};

@@ -90,3 +90,3 @@

urlCache: Set<string>;
httpHeaders?: Record<string, any>;
httpHeaders?: Record<string, unknown>;
httpMethod?: string;

@@ -115,3 +115,3 @@ fetch: Fetch;

if (schema.protocol.startsWith("http")) {
const headers: Record<string, any> = { "User-Agent": "openapi-typescript" };
const headers: Record<string, string> = { "User-Agent": "openapi-typescript" };
if (options.auth) headers.Authorization = options.auth;

@@ -123,3 +123,3 @@

for (const [k, v] of Object.entries(parsedHeaders)) {
headers[k] = v;
headers[k] = v as string;
}

@@ -140,3 +140,3 @@ }

hint,
schema: parseYAML(await res.text()),
schema: parseYAML(await res.text()) as any, // eslint-disable-line @typescript-eslint/no-explicit-any
};

@@ -151,3 +151,3 @@ }

hint,
schema: parseYAML(contents),
schema: parseYAML(contents) as any, // eslint-disable-line @typescript-eslint/no-explicit-any
};

@@ -202,3 +202,3 @@ else if (ext === ".json")

const refPromises: Promise<any>[] = [];
const refPromises: Promise<unknown>[] = [];
walk(currentSchema, (rawNode, nodePath) => {

@@ -208,3 +208,3 @@ // filter custom properties from allOf, anyOf, oneOf

if (Array.isArray(rawNode[k])) {
rawNode[k] = (rawNode as any)[k].filter((o: SchemaObject | ReferenceObject) => {
rawNode[k] = (rawNode as Record<string, SchemaObject[]>)[k].filter((o: SchemaObject | ReferenceObject) => {
if (!o || typeof o !== "object" || Array.isArray(o)) throw new Error(`${nodePath}.${k}: Expected array of objects. Is your schema valid?`);

@@ -227,3 +227,3 @@ if (!("$ref" in o) || typeof o.$ref !== "string") return true;

if (ref.path.some((i) => i.startsWith("x-"))) {
delete (node as any).$ref;
delete (node as unknown as Record<string, unknown>).$ref;
return;

@@ -269,3 +269,3 @@ }

for (const subschemaID of Object.keys(options.schemas)) {
walk(options.schemas[subschemaID].schema, (rawNode, nodePath) => {
walk(options.schemas[subschemaID].schema, (rawNode) => {
if (!("$ref" in rawNode) || typeof rawNode.$ref !== "string") return;

@@ -300,3 +300,3 @@

const key = k === "." ? makeTSIndex(nodePath) : makeTSIndex(["external", k, ...nodePath]);
options.parameters[key] = rawNode as any;
options.parameters[key] = rawNode as unknown as ParameterObject;
}

@@ -303,0 +303,0 @@ });

@@ -105,4 +105,4 @@ import type { ComponentsObject, GlobalContext } from "../types.js";

})};`,
indentLv
)
indentLv,
),
);

@@ -168,4 +168,4 @@ } else {

})};`,
indentLv
)
indentLv,
),
);

@@ -172,0 +172,0 @@ }

@@ -102,4 +102,4 @@ import type { GlobalContext, OperationObject, ParameterObject } from "../types.js";

})};`,
indentLv
)
indentLv,
),
);

@@ -106,0 +106,0 @@ } else {

@@ -26,4 +26,4 @@ import type { GlobalContext, ParameterObject, ReferenceObject } from "../types.js";

})};`,
ctx.indentLv
)
ctx.indentLv,
),
);

@@ -30,0 +30,0 @@ }

@@ -53,4 +53,4 @@ import type { GlobalContext, PathsObject, PathItemObject, ParameterObject, ReferenceObject, OperationObject } from "../types.js";

})};`,
indentLv
)
indentLv,
),
);

@@ -57,0 +57,0 @@ }

@@ -30,4 +30,4 @@ import type { GlobalContext, RequestBodyObject } from "../types.js";

})};`,
indentLv
)
indentLv,
),
);

@@ -34,0 +34,0 @@ } else {

@@ -40,4 +40,4 @@ import type { GlobalContext, ResponseObject } from "../types.js";

})};`,
indentLv
)
indentLv,
),
);

@@ -65,4 +65,4 @@ }

})};`,
indentLv
)
indentLv,
),
);

@@ -69,0 +69,0 @@ }

import type { GlobalContext, ReferenceObject, SchemaObject } from "../types.js";
import { escObjKey, escStr, getEntries, getSchemaObjectComment, indent, parseRef, tsArrayOf, tsIntersectionOf, tsOmit, tsOneOf, tsOptionalProperty, tsReadonly, tsTupleOf, tsUnionOf, tsWithRequired } from "../utils.js";
// There’s just no getting around some really complex type intersections that TS
// has trouble following
/* eslint-disable @typescript-eslint/no-explicit-any */
export interface TransformSchemaObjectOptions {

@@ -55,6 +59,6 @@ /** The full ID for this object (mostly used in error messages) */

// enum (valid for any type, but for objects, treat as oneOf below)
if (typeof schemaObject === "object" && !!(schemaObject as any).enum && (schemaObject as any).type !== "object") {
let items = (schemaObject as any).enum as any[];
if (typeof schemaObject === "object" && !!schemaObject.enum && (schemaObject as any).type !== "object") {
let items = schemaObject.enum as string[];
if ("type" in schemaObject) {
if (schemaObject.type === "string" || (Array.isArray(schemaObject.type) && schemaObject.type.includes("string" as any))) {
if (schemaObject.type === "string" || (Array.isArray(schemaObject.type) && (schemaObject.type as string[]).includes("string"))) {
items = items.map((t) => escStr(t));

@@ -71,3 +75,3 @@ }

// oneOf (no discriminator)
const oneOf = ((typeof schemaObject === "object" && !(schemaObject as any).discriminator && (schemaObject as any).oneOf) || (schemaObject as any).enum || undefined) as (SchemaObject | ReferenceObject)[] | undefined; // note: for objects, treat enum as oneOf
const oneOf = ((typeof schemaObject === "object" && !schemaObject.discriminator && schemaObject.oneOf) || schemaObject.enum || undefined) as (SchemaObject | ReferenceObject)[] | undefined; // note: for objects, treat enum as oneOf
if (oneOf && !oneOf.some((t) => "$ref" in t && ctx.discriminators[t.$ref])) {

@@ -87,3 +91,3 @@ const oneOfNormalized = oneOf.map((item) => transformSchemaObject(item, { path, ctx }));

// handle oneOf + object type
if ("type" in schemaObject && schemaObject.type === "object") {
if ("type" in schemaObject && schemaObject.type === "object" && (schemaObject.properties || schemaObject.additionalProperties)) {
return tsIntersectionOf(transformSchemaObject({ ...schemaObject, oneOf: undefined, enum: undefined } as any, { path, ctx }), oneOfTypes);

@@ -141,3 +145,3 @@ }

return ctx.immutableTypes || schemaObject.readOnly ? tsReadonly(t) : t;
})
}),
);

@@ -204,3 +208,3 @@ }

// Mapping value can either be a fully-qualified ref (#/components/schemas/XYZ) or a schema name (XYZ)
const matchedValue = Object.entries(discriminator.mapping).find(([_, v]) => (!v.startsWith("#") && v === value) || (v.startsWith("#") && parseRef(v).path.pop() === value));
const matchedValue = Object.entries(discriminator.mapping).find(([, v]) => (!v.startsWith("#") && v === value) || (v.startsWith("#") && parseRef(v).path.pop() === value));
if (matchedValue) value = matchedValue[0]; // why was this designed backwards!?

@@ -230,3 +234,3 @@ }

// oneOf (discriminator)
if ("oneOf" in schemaObject && Array.isArray(schemaObject.oneOf)) {
if (Array.isArray(schemaObject.oneOf) && schemaObject.oneOf.length) {
const oneOfType = tsUnionOf(...collectCompositions(schemaObject.oneOf));

@@ -236,4 +240,4 @@ finalType = finalType ? tsIntersectionOf(finalType, oneOfType) : oneOfType;

// allOf
if ("allOf" in schemaObject && Array.isArray(schemaObject.allOf)) {
finalType = tsIntersectionOf(...(finalType ? [finalType] : []), ...collectCompositions(schemaObject.allOf));
if (Array.isArray((schemaObject as any).allOf) && schemaObject.allOf!.length) {
finalType = tsIntersectionOf(...(finalType ? [finalType] : []), ...collectCompositions(schemaObject.allOf!));
if ("required" in schemaObject && Array.isArray(schemaObject.required)) {

@@ -244,3 +248,3 @@ finalType = tsWithRequired(finalType, schemaObject.required);

// anyOf
if ("anyOf" in schemaObject && Array.isArray(schemaObject.anyOf)) {
if (Array.isArray(schemaObject.anyOf) && schemaObject.anyOf.length) {
const anyOfTypes = tsUnionOf(...collectCompositions(schemaObject.anyOf));

@@ -247,0 +251,0 @@ finalType = finalType ? tsIntersectionOf(finalType, anyOfTypes) : anyOfTypes;

@@ -16,4 +16,4 @@ import type { GlobalContext, WebhooksObject } from "../types.js";

})};`,
indentLv
)
indentLv,
),
);

@@ -20,0 +20,0 @@ }

@@ -5,2 +5,5 @@ import type { URL } from "node:url";

// Many types allow for true “any”
/* eslint-disable @typescript-eslint/no-explicit-any */
export interface Extensable {

@@ -433,5 +436,8 @@ [key: `x-${string}`]: any;

nullable?: boolean;
oneOf?: (SchemaObject | ReferenceObject)[];
allOf?: (SchemaObject | ReferenceObject)[];
anyOf?: (SchemaObject | ReferenceObject)[];
required?: string[];
[key: `x-${string}`]: any;
} & (
| { oneOf: (SchemaObject | ReferenceObject)[] }
| StringSubtype

@@ -445,4 +451,3 @@ | NumberSubtype

| { type: ("string" | "number" | "integer" | "array" | "boolean" | "null" | "object")[] }
| { allOf: (SchemaObject | ReferenceObject)[]; anyOf?: (SchemaObject | ReferenceObject)[]; required?: string[] }
| { allOf?: (SchemaObject | ReferenceObject)[]; anyOf: (SchemaObject | ReferenceObject)[]; required?: string[] }
// eslint-disable-next-line @typescript-eslint/ban-types
| {}

@@ -449,0 +454,0 @@ );

@@ -44,4 +44,4 @@ import c from "ansi-colors";

}
cb(obj as any, path);
for (const k of Object.keys(obj)) walk((obj as any)[k], cb, path.concat(k));
cb(obj as Record<string, unknown>, path);
for (const k of Object.keys(obj)) walk((obj as Record<string, unknown>)[k], cb, path.concat(k));
}

@@ -275,3 +275,3 @@

/** escape string value */
export function escStr(input: any): string {
export function escStr(input: unknown): string {
if (typeof input !== "string") return JSON.stringify(input);

@@ -320,3 +320,4 @@ return `"${input.replace(LB_RE, "").replace(DOUBLE_QUOTE_RE, '\\"')}"`;

export function getDefaultFetch(): Fetch {
const globalFetch: Fetch | undefined = (globalThis as any).fetch;
// @ts-expect-error globalThis doesn’t have a type
const globalFetch: Fetch | undefined = globalThis.fetch;
if (typeof globalFetch === "undefined") {

@@ -323,0 +324,0 @@ return unidiciFetch;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc