openapi-typescript
Advanced tools
Comparing version 7.0.0-next.2 to 7.0.0-next.3
@@ -70,2 +70,4 @@ # openapi-typescript | ||
- [#1374](https://github.com/drwpow/openapi-typescript/pull/1374) [`7ac5174`](https://github.com/drwpow/openapi-typescript/commit/7ac5174a1f767c1103573543bb17622ac8d25fe4) Thanks [@ElForastero](https://github.com/ElForastero)! - Add support for x-enum-varnames and x-enum-descriptions | ||
### Patch Changes | ||
@@ -72,0 +74,0 @@ |
@@ -38,7 +38,13 @@ import ts from "typescript"; | ||
export declare function tsDedupe(types: ts.TypeNode[]): ts.TypeNode[]; | ||
export declare function tsEnum(name: string, members: (string | number)[], options?: { | ||
export declare function tsEnum(name: string, members: (string | number)[], metadata?: { | ||
name?: string; | ||
description?: string; | ||
}[], options?: { | ||
readonly?: boolean; | ||
export?: boolean; | ||
}): ts.EnumDeclaration; | ||
export declare function tsEnumMember(value: string | number): ts.EnumMember; | ||
export declare function tsEnumMember(value: string | number, metadata?: { | ||
name?: string; | ||
description?: string; | ||
}): ts.EnumMember; | ||
export declare function tsIntersection(types: ts.TypeNode[]): ts.TypeNode; | ||
@@ -45,0 +51,0 @@ export declare function tsIsPrimitive(type: ts.TypeNode): boolean; |
@@ -118,3 +118,3 @@ import { parseRef } from "@redocly/openapi-core/lib/ref-utils.js"; | ||
} | ||
export function tsEnum(name, members, options) { | ||
export function tsEnum(name, members, metadata, options) { | ||
let enumName = name.replace(JS_ENUM_INVALID_CHARS_RE, (c) => { | ||
@@ -135,16 +135,23 @@ const last = c[c.length - 1]; | ||
}) | ||
: undefined, enumName, members.map(tsEnumMember)); | ||
: undefined, enumName, members.map((value, i) => tsEnumMember(value, metadata?.[i]))); | ||
} | ||
export function tsEnumMember(value) { | ||
if (typeof value === "number") { | ||
return ts.factory.createEnumMember(`Value${String(value)}`.replace(".", "_"), ts.factory.createNumericLiteral(value)); | ||
} | ||
let name = value; | ||
export function tsEnumMember(value, metadata = {}) { | ||
let name = metadata.name ?? String(value); | ||
if (!JS_PROPERTY_INDEX_RE.test(name)) { | ||
if (Number(name[0]) >= 0) { | ||
name = `Value${name}`; | ||
name = `Value${name}`.replace(".", "_"); | ||
} | ||
name = name.replace(JS_PROPERTY_INDEX_INVALID_CHARS_RE, "_"); | ||
} | ||
return ts.factory.createEnumMember(name, ts.factory.createStringLiteral(value)); | ||
let member; | ||
if (typeof value === "number") { | ||
member = ts.factory.createEnumMember(name, ts.factory.createNumericLiteral(value)); | ||
} | ||
else { | ||
member = ts.factory.createEnumMember(name, ts.factory.createStringLiteral(value)); | ||
} | ||
if (metadata.description == undefined) { | ||
return member; | ||
} | ||
return ts.addSyntheticLeadingComment(member, ts.SyntaxKind.SingleLineCommentTrivia, " ".concat(metadata.description.trim()), true); | ||
} | ||
@@ -151,0 +158,0 @@ export function tsIntersection(types) { |
import ts from "typescript"; | ||
import { NEVER, addJSDocComment, tsModifiers, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { NEVER, QUESTION_TOKEN, addJSDocComment, tsModifiers, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { createRef, debug, getEntries } from "../lib/utils.js"; | ||
@@ -25,7 +25,23 @@ import transformHeaderObject from "./header-object.js"; | ||
for (const [name, item] of getEntries(componentsObject[key], ctx)) { | ||
const subType = transformers[key](item, { | ||
let subType = transformers[key](item, { | ||
path: createRef(["components", key, name]), | ||
ctx, | ||
}); | ||
const property = ts.factory.createPropertySignature(tsModifiers({ readonly: ctx.immutable }), tsPropertyIndex(name), undefined, subType); | ||
let hasQuestionToken = false; | ||
if (ctx.transform) { | ||
const result = ctx.transform(item, { | ||
path: createRef(["components", key, name]), | ||
ctx, | ||
}); | ||
if (result) { | ||
if ("schema" in result) { | ||
subType = result.schema; | ||
hasQuestionToken = result.questionToken; | ||
} | ||
else { | ||
subType = result; | ||
} | ||
} | ||
} | ||
const property = ts.factory.createPropertySignature(tsModifiers({ readonly: ctx.immutable }), tsPropertyIndex(name), hasQuestionToken ? QUESTION_TOKEN : undefined, subType); | ||
addJSDocComment(item, property); | ||
@@ -32,0 +48,0 @@ items.push(property); |
@@ -17,6 +17,3 @@ import ts from "typescript"; | ||
for (const root of Object.keys(transformers)) { | ||
const emptyObj = ts.factory.createTypeAliasDeclaration(tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), root, undefined, tsRecord(STRING, NEVER)); | ||
const emptyObj = ts.factory.createTypeAliasDeclaration(tsModifiers({ export: true }), root, undefined, tsRecord(STRING, NEVER)); | ||
if (schema[root] && typeof schema[root] === "object") { | ||
@@ -27,10 +24,4 @@ const rootT = performance.now(); | ||
type.push(ctx.exportType | ||
? ts.factory.createTypeAliasDeclaration(tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), root, undefined, subType) | ||
: ts.factory.createInterfaceDeclaration(tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), root, undefined, undefined, subType.members)); | ||
? ts.factory.createTypeAliasDeclaration(tsModifiers({ export: true }), root, undefined, subType) | ||
: ts.factory.createInterfaceDeclaration(tsModifiers({ export: true }), root, undefined, undefined, subType.members)); | ||
debug(`${root} done`, "ts", performance.now() - rootT); | ||
@@ -57,6 +48,3 @@ } | ||
if (!hasOperations) { | ||
type.push(ts.factory.createTypeAliasDeclaration(tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), "operations", undefined, tsRecord(STRING, NEVER))); | ||
type.push(ts.factory.createTypeAliasDeclaration(tsModifiers({ export: true }), "operations", undefined, tsRecord(STRING, NEVER))); | ||
} | ||
@@ -63,0 +51,0 @@ return type; |
@@ -25,5 +25,5 @@ import ts from "typescript"; | ||
else { | ||
type.push(ts.factory.createPropertySignature(undefined, tsPropertyIndex("requestBody"), QUESTION_TOKEN, NEVER)); | ||
type.push(ts.factory.createPropertySignature(tsModifiers({ readonly: options.ctx.immutable }), tsPropertyIndex("requestBody"), QUESTION_TOKEN, NEVER)); | ||
} | ||
type.push(ts.factory.createPropertySignature(undefined, tsPropertyIndex("responses"), undefined, transformResponsesObject(operationObject.responses ?? {}, options))); | ||
type.push(ts.factory.createPropertySignature(tsModifiers({ readonly: options.ctx.immutable }), tsPropertyIndex("responses"), undefined, transformResponsesObject(operationObject.responses ?? {}, options))); | ||
return type; | ||
@@ -37,3 +37,2 @@ } | ||
export: true, | ||
readonly: options.ctx.immutable, | ||
}), ts.factory.createIdentifier("operations"), undefined, undefined, []); | ||
@@ -40,0 +39,0 @@ options.ctx.injectFooter.push(operations); |
import ts from "typescript"; | ||
import { NEVER, QUESTION_TOKEN, addJSDocComment, oapiRef, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { NEVER, QUESTION_TOKEN, addJSDocComment, oapiRef, tsModifiers, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { createRef } from "../lib/utils.js"; | ||
@@ -43,3 +43,3 @@ import transformParameterObject from "./parameter-object.js"; | ||
}); | ||
const property = ts.factory.createPropertySignature(undefined, tsPropertyIndex(resolved?.name), optional, subType); | ||
const property = ts.factory.createPropertySignature(tsModifiers({ readonly: options.ctx.immutable }), tsPropertyIndex(resolved?.name), optional, subType); | ||
addJSDocComment(resolved, property); | ||
@@ -49,3 +49,3 @@ paramLocType.push(property); | ||
const allOptional = paramLocType.every((node) => !!node.questionToken); | ||
paramType.push(ts.factory.createPropertySignature(undefined, tsPropertyIndex(paramIn), allOptional || !paramLocType.length | ||
paramType.push(ts.factory.createPropertySignature(tsModifiers({ readonly: options.ctx.immutable }), tsPropertyIndex(paramIn), allOptional || !paramLocType.length | ||
? QUESTION_TOKEN | ||
@@ -56,3 +56,3 @@ : undefined, paramLocType.length | ||
} | ||
type.push(ts.factory.createPropertySignature(undefined, tsPropertyIndex("parameters"), !paramType.length ? QUESTION_TOKEN : undefined, paramType.length | ||
type.push(ts.factory.createPropertySignature(tsModifiers({ readonly: options.ctx.immutable }), tsPropertyIndex("parameters"), !paramType.length ? QUESTION_TOKEN : undefined, paramType.length | ||
? ts.factory.createTypeLiteralNode(paramType) | ||
@@ -59,0 +59,0 @@ : NEVER)); |
import ts from "typescript"; | ||
import { NEVER, QUESTION_TOKEN, addJSDocComment, oapiRef, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { NEVER, QUESTION_TOKEN, addJSDocComment, oapiRef, tsModifiers, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { createRef } from "../lib/utils.js"; | ||
@@ -28,3 +28,3 @@ import transformOperationObject, { injectOperationObject, } from "./operation-object.js"; | ||
: operationObject)?.deprecated)) { | ||
type.push(ts.factory.createPropertySignature(undefined, tsPropertyIndex(method), QUESTION_TOKEN, NEVER)); | ||
type.push(ts.factory.createPropertySignature(tsModifiers({ readonly: options.ctx.immutable }), tsPropertyIndex(method), QUESTION_TOKEN, NEVER)); | ||
continue; | ||
@@ -53,3 +53,3 @@ } | ||
} | ||
const property = ts.factory.createPropertySignature(undefined, tsPropertyIndex(method), undefined, operationType); | ||
const property = ts.factory.createPropertySignature(tsModifiers({ readonly: options.ctx.immutable }), tsPropertyIndex(method), undefined, operationType); | ||
addJSDocComment(operationObject, property); | ||
@@ -56,0 +56,0 @@ type.push(property); |
import ts from "typescript"; | ||
import { addJSDocComment, oapiRef, stringToAST, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { addJSDocComment, oapiRef, stringToAST, tsModifiers, tsPropertyIndex, } from "../lib/ts.js"; | ||
import { createRef, debug, getEntries } from "../lib/utils.js"; | ||
@@ -14,3 +14,3 @@ import transformPathItemObject from "./path-item-object.js"; | ||
if ("$ref" in pathItemObject) { | ||
const property = ts.factory.createPropertySignature(undefined, tsPropertyIndex(url), undefined, oapiRef(pathItemObject.$ref)); | ||
const property = ts.factory.createPropertySignature(tsModifiers({ readonly: ctx.immutable }), tsPropertyIndex(url), undefined, oapiRef(pathItemObject.$ref)); | ||
addJSDocComment(pathItemObject, property); | ||
@@ -40,3 +40,3 @@ } | ||
if (pathType) { | ||
type.push(ts.factory.createIndexSignature(undefined, [ | ||
type.push(ts.factory.createIndexSignature(tsModifiers({ readonly: ctx.immutable }), [ | ||
ts.factory.createParameterDeclaration(undefined, undefined, "path", undefined, pathType, undefined), | ||
@@ -48,3 +48,3 @@ ], pathItemType)); | ||
} | ||
type.push(ts.factory.createPropertySignature(undefined, tsPropertyIndex(url), undefined, pathItemType)); | ||
type.push(ts.factory.createPropertySignature(tsModifiers({ readonly: ctx.immutable }), tsPropertyIndex(url), undefined, pathItemType)); | ||
debug(`Transformed path "${url}"`, "ts", performance.now() - pathT); | ||
@@ -51,0 +51,0 @@ } |
@@ -28,8 +28,2 @@ import { parseRef } from "@redocly/openapi-core/lib/ref-utils.js"; | ||
} | ||
if (typeof options.ctx.transform === "function") { | ||
const result = options.ctx.transform(schemaObject, options); | ||
if (result !== undefined && result !== null) { | ||
return result; | ||
} | ||
} | ||
if (schemaObject.const !== null && schemaObject.const !== undefined) { | ||
@@ -46,3 +40,7 @@ return tsLiteral(schemaObject.const); | ||
enumName = enumName.replace("components/schemas", ""); | ||
const enumType = tsEnum(enumName, schemaObject.enum, { export: true, readonly: options.ctx.immutable }); | ||
const metadata = schemaObject.enum.map((_, i) => ({ | ||
name: schemaObject["x-enum-varnames"]?.[i], | ||
description: schemaObject["x-enum-descriptions"]?.[i], | ||
})); | ||
const enumType = tsEnum(enumName, schemaObject.enum, metadata, { export: true, readonly: options.ctx.immutable }); | ||
options.ctx.injectFooter.push(enumType); | ||
@@ -155,5 +153,2 @@ return ts.factory.createTypeReferenceNode(enumType.name); | ||
itemType = transformSchemaObject(schemaObject.items, options); | ||
if (options.ctx.immutable) { | ||
itemType = ts.factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, itemType); | ||
} | ||
} | ||
@@ -252,7 +247,9 @@ const min = typeof schemaObject.minItems === "number" && schemaObject.minItems >= 0 | ||
} | ||
const optional = schemaObject.required?.includes(k) || | ||
("default" in v && options.ctx.defaultNonNullable) | ||
let optional = schemaObject.required?.includes(k) || | ||
("default" in v && | ||
options.ctx.defaultNonNullable && | ||
!options.path?.includes("parameters")) | ||
? undefined | ||
: QUESTION_TOKEN; | ||
const type = "$ref" in v | ||
let type = "$ref" in v | ||
? oapiRef(v.$ref) | ||
@@ -263,2 +260,14 @@ : transformSchemaObject(v, { | ||
}); | ||
if (typeof options.ctx.transform === "function") { | ||
const result = options.ctx.transform(v, options); | ||
if (result) { | ||
if ("schema" in result) { | ||
type = result.schema; | ||
optional = result.questionToken ? QUESTION_TOKEN : optional; | ||
} | ||
else { | ||
type = result; | ||
} | ||
} | ||
} | ||
const property = ts.factory.createPropertySignature(tsModifiers({ | ||
@@ -285,5 +294,3 @@ readonly: options.ctx.immutable || ("readOnly" in v && !!v.readOnly), | ||
} | ||
coreObjectType.push(ts.factory.createPropertySignature(tsModifiers({ | ||
readonly: options.ctx.immutable, | ||
}), tsPropertyIndex("$defs"), undefined, ts.factory.createTypeLiteralNode(defKeys))); | ||
coreObjectType.push(ts.factory.createPropertySignature(undefined, tsPropertyIndex("$defs"), undefined, ts.factory.createTypeLiteralNode(defKeys))); | ||
} | ||
@@ -290,0 +297,0 @@ if (schemaObject.additionalProperties || options.ctx.additionalProperties) { |
@@ -216,2 +216,6 @@ /// <reference types="node" /> | ||
} | {}); | ||
export interface TransformObject { | ||
schema: ts.TypeNode; | ||
questionToken: boolean; | ||
} | ||
export interface StringSubtype { | ||
@@ -313,3 +317,3 @@ type: "string" | ["string", "null"]; | ||
defaultNonNullable?: boolean; | ||
transform?: (schemaObject: SchemaObject, options: TransformNodeOptions) => ts.TypeNode | undefined; | ||
transform?: (schemaObject: SchemaObject, options: TransformNodeOptions) => ts.TypeNode | TransformObject | undefined; | ||
postTransform?: (type: ts.TypeNode, options: TransformNodeOptions) => ts.TypeNode | undefined; | ||
@@ -316,0 +320,0 @@ immutable?: boolean; |
{ | ||
"name": "openapi-typescript", | ||
"description": "Convert OpenAPI 3.0 & 3.1 schemas to TypeScript", | ||
"version": "7.0.0-next.2", | ||
"version": "7.0.0-next.3", | ||
"author": { | ||
@@ -75,3 +75,3 @@ "name": "Drew Powers", | ||
"del-cli": "^5.1.0", | ||
"esbuild": "^0.19.4", | ||
"esbuild": "^0.19.5", | ||
"execa": "^7.2.0", | ||
@@ -78,0 +78,0 @@ "vite": "^4.4.9", |
@@ -28,3 +28,3 @@ <img src="../../docs/public/assets/openapi-ts.svg" alt="openapi-typescript" width="200" height="40" /> | ||
> | ||
> Enabling [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in `tsconfig.json` can go along way to improve type safety ([read more](/docs/src/content/docs/advanced.md#enable-nouncheckedindexedaccess-in-your-tsconfigjson)) | ||
> Enabling [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in `tsconfig.json` can go along way to improve type safety ([read more](../../docs/src/content/docs/advanced.md#enable-nouncheckedindexedaccess-in-your-tsconfigjson)) | ||
@@ -89,2 +89,2 @@ ## Basic usage | ||
[View Docs](https://openapi-ts.pages.dev/) | ||
[View Docs](https://openapi-ts.pages.dev/introduction/) |
@@ -232,2 +232,3 @@ import { parseRef } from "@redocly/openapi-core/lib/ref-utils.js"; | ||
members: (string | number)[], | ||
metadata?: { name?: string; description?: string }[], | ||
options?: { readonly?: boolean; export?: boolean }, | ||
@@ -253,3 +254,5 @@ ) { | ||
/* name */ enumName, | ||
/* members */ members.map(tsEnumMember), | ||
/* members */ members.map((value, i) => | ||
tsEnumMember(value, metadata?.[i]), | ||
), | ||
); | ||
@@ -259,19 +262,36 @@ } | ||
/** Sanitize TS enum member expression */ | ||
export function tsEnumMember(value: string | number) { | ||
if (typeof value === "number") { | ||
return ts.factory.createEnumMember( | ||
`Value${String(value)}`.replace(".", "_"), // don’t forget decimals | ||
ts.factory.createNumericLiteral(value), | ||
); | ||
} | ||
let name = value; | ||
export function tsEnumMember( | ||
value: string | number, | ||
metadata: { name?: string; description?: string } = {}, | ||
) { | ||
let name = metadata.name ?? String(value); | ||
if (!JS_PROPERTY_INDEX_RE.test(name)) { | ||
if (Number(name[0]) >= 0) { | ||
name = `Value${name}`; | ||
name = `Value${name}`.replace(".", "_"); // don't forged decimals; | ||
} | ||
name = name.replace(JS_PROPERTY_INDEX_INVALID_CHARS_RE, "_"); | ||
} | ||
return ts.factory.createEnumMember( | ||
name, | ||
ts.factory.createStringLiteral(value), | ||
let member; | ||
if (typeof value === "number") { | ||
member = ts.factory.createEnumMember( | ||
name, | ||
ts.factory.createNumericLiteral(value), | ||
); | ||
} else { | ||
member = ts.factory.createEnumMember( | ||
name, | ||
ts.factory.createStringLiteral(value), | ||
); | ||
} | ||
if (metadata.description == undefined) { | ||
return member; | ||
} | ||
return ts.addSyntheticLeadingComment( | ||
member, | ||
ts.SyntaxKind.SingleLineCommentTrivia, | ||
" ".concat(metadata.description.trim()), | ||
true, | ||
); | ||
@@ -278,0 +298,0 @@ } |
import ts from "typescript"; | ||
import { | ||
NEVER, | ||
QUESTION_TOKEN, | ||
addJSDocComment, | ||
@@ -12,2 +13,3 @@ tsModifiers, | ||
GlobalContext, | ||
SchemaObject, | ||
TransformNodeOptions, | ||
@@ -55,10 +57,27 @@ } from "../types.js"; | ||
for (const [name, item] of getEntries(componentsObject[key], ctx)) { | ||
const subType = transformers[key](item, { | ||
let subType = transformers[key](item, { | ||
path: createRef(["components", key, name]), | ||
ctx, | ||
}); | ||
let hasQuestionToken = false; | ||
if (ctx.transform) { | ||
const result = ctx.transform(item as SchemaObject, { | ||
path: createRef(["components", key, name]), | ||
ctx, | ||
}); | ||
if (result) { | ||
if ("schema" in result) { | ||
subType = result.schema; | ||
hasQuestionToken = result.questionToken; | ||
} else { | ||
subType = result; | ||
} | ||
} | ||
} | ||
const property = ts.factory.createPropertySignature( | ||
/* modifiers */ tsModifiers({ readonly: ctx.immutable }), | ||
/* name */ tsPropertyIndex(name), | ||
/* questionToken */ undefined, | ||
/* questionToken */ hasQuestionToken ? QUESTION_TOKEN : undefined, | ||
/* type */ subType, | ||
@@ -65,0 +84,0 @@ ); |
@@ -31,6 +31,3 @@ import ts, { InterfaceDeclaration, TypeLiteralNode } from "typescript"; | ||
const emptyObj = ts.factory.createTypeAliasDeclaration( | ||
/* modifiers */ tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), | ||
/* modifiers */ tsModifiers({ export: true }), | ||
/* name */ root, | ||
@@ -48,6 +45,3 @@ /* typeParameters */ undefined, | ||
? ts.factory.createTypeAliasDeclaration( | ||
/* modifiers */ tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), | ||
/* modifiers */ tsModifiers({ export: true }), | ||
/* name */ root, | ||
@@ -58,6 +52,3 @@ /* typeParameters */ undefined, | ||
: ts.factory.createInterfaceDeclaration( | ||
/* modifiers */ tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), | ||
/* modifiers */ tsModifiers({ export: true }), | ||
/* name */ root, | ||
@@ -95,6 +86,3 @@ /* typeParameters */ undefined, | ||
ts.factory.createTypeAliasDeclaration( | ||
/* modifiers */ tsModifiers({ | ||
export: true, | ||
readonly: ctx.immutable, | ||
}), | ||
/* modifiers */ tsModifiers({ export: true }), | ||
/* name */ "operations", | ||
@@ -101,0 +89,0 @@ /* typeParameters */ undefined, |
@@ -62,3 +62,3 @@ import ts from "typescript"; | ||
ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: options.ctx.immutable }), | ||
/* name */ tsPropertyIndex("requestBody"), | ||
@@ -74,3 +74,3 @@ /* questionToken */ QUESTION_TOKEN, | ||
ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: options.ctx.immutable }), | ||
/* name */ tsPropertyIndex("responses"), | ||
@@ -104,3 +104,3 @@ /* questionToken */ undefined, | ||
export: true, | ||
readonly: options.ctx.immutable, | ||
// important: do NOT make this immutable | ||
}), | ||
@@ -107,0 +107,0 @@ /* name */ ts.factory.createIdentifier("operations"), |
@@ -7,2 +7,3 @@ import ts from "typescript"; | ||
oapiRef, | ||
tsModifiers, | ||
tsPropertyIndex, | ||
@@ -70,3 +71,3 @@ } from "../lib/ts.js"; | ||
const property = ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: options.ctx.immutable }), | ||
/* name */ tsPropertyIndex(resolved?.name), | ||
@@ -82,3 +83,3 @@ /* questionToken */ optional, | ||
ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: options.ctx.immutable }), | ||
/* name */ tsPropertyIndex(paramIn), | ||
@@ -96,3 +97,3 @@ /* questionToken */ allOptional || !paramLocType.length | ||
ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: options.ctx.immutable }), | ||
/* name */ tsPropertyIndex("parameters"), | ||
@@ -99,0 +100,0 @@ /* questionToken */ !paramType.length ? QUESTION_TOKEN : undefined, |
@@ -7,2 +7,3 @@ import ts from "typescript"; | ||
oapiRef, | ||
tsModifiers, | ||
tsPropertyIndex, | ||
@@ -73,3 +74,3 @@ } from "../lib/ts.js"; | ||
ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: options.ctx.immutable }), | ||
/* name */ tsPropertyIndex(method), | ||
@@ -121,3 +122,3 @@ /* questionToken */ QUESTION_TOKEN, | ||
const property = ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: options.ctx.immutable }), | ||
/* name */ tsPropertyIndex(method), | ||
@@ -124,0 +125,0 @@ /* questionToken */ undefined, |
@@ -6,2 +6,3 @@ import ts from "typescript"; | ||
stringToAST, | ||
tsModifiers, | ||
tsPropertyIndex, | ||
@@ -41,3 +42,3 @@ } from "../lib/ts.js"; | ||
const property = ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: ctx.immutable }), | ||
/* name */ tsPropertyIndex(url), | ||
@@ -79,3 +80,3 @@ /* questionToken */ undefined, | ||
ts.factory.createIndexSignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: ctx.immutable }), | ||
/* parameters */ [ | ||
@@ -102,3 +103,3 @@ ts.factory.createParameterDeclaration( | ||
ts.factory.createPropertySignature( | ||
/* modifiers */ undefined, | ||
/* modifiers */ tsModifiers({ readonly: ctx.immutable }), | ||
/* name */ tsPropertyIndex(url), | ||
@@ -105,0 +106,0 @@ /* questionToken */ undefined, |
@@ -91,12 +91,2 @@ import { parseRef } from "@redocly/openapi-core/lib/ref-utils.js"; | ||
/** | ||
* transform() | ||
*/ | ||
if (typeof options.ctx.transform === "function") { | ||
const result = options.ctx.transform(schemaObject, options); | ||
if (result !== undefined && result !== null) { | ||
return result; | ||
} | ||
} | ||
/** | ||
* const (valid for any type) | ||
@@ -128,5 +118,10 @@ */ | ||
enumName = enumName.replace("components/schemas", ""); | ||
const metadata = schemaObject.enum.map((_, i) => ({ | ||
name: schemaObject["x-enum-varnames"]?.[i], | ||
description: schemaObject["x-enum-descriptions"]?.[i], | ||
})); | ||
const enumType = tsEnum( | ||
enumName, | ||
schemaObject.enum as (string | number)[], | ||
metadata, | ||
{ export: true, readonly: options.ctx.immutable }, | ||
@@ -309,8 +304,2 @@ ); | ||
itemType = transformSchemaObject(schemaObject.items, options); | ||
if (options.ctx.immutable) { | ||
itemType = ts.factory.createTypeOperatorNode( | ||
ts.SyntaxKind.ReadonlyKeyword, | ||
itemType, | ||
); | ||
} | ||
} | ||
@@ -462,8 +451,10 @@ | ||
} | ||
const optional = | ||
let optional = | ||
schemaObject.required?.includes(k) || | ||
("default" in v && options.ctx.defaultNonNullable) | ||
("default" in v && | ||
options.ctx.defaultNonNullable && | ||
!options.path?.includes("parameters")) // parameters can’t be required, even with defaults | ||
? undefined | ||
: QUESTION_TOKEN; | ||
const type = | ||
let type = | ||
"$ref" in v | ||
@@ -475,2 +466,15 @@ ? oapiRef(v.$ref) | ||
}); | ||
if (typeof options.ctx.transform === "function") { | ||
const result = options.ctx.transform(v, options); | ||
if (result) { | ||
if ("schema" in result) { | ||
type = result.schema; | ||
optional = result.questionToken ? QUESTION_TOKEN : optional; | ||
} else { | ||
type = result; | ||
} | ||
} | ||
} | ||
const property = ts.factory.createPropertySignature( | ||
@@ -499,3 +503,3 @@ /* modifiers */ tsModifiers({ | ||
const property = ts.factory.createPropertySignature( | ||
/* modifiers */ tsModifiers({ | ||
/* modifiers */ tsModifiers({ | ||
readonly: | ||
@@ -516,5 +520,3 @@ options.ctx.immutable || ("readonly" in v && !!v.readOnly), | ||
ts.factory.createPropertySignature( | ||
/* modifiers */ tsModifiers({ | ||
readonly: options.ctx.immutable, | ||
}), | ||
/* modifiers */ undefined, | ||
/* name */ tsPropertyIndex("$defs"), | ||
@@ -521,0 +523,0 @@ /* questionToken */ undefined, |
@@ -470,2 +470,7 @@ import type { Config as RedoclyConfig } from "@redocly/openapi-core"; | ||
export interface TransformObject { | ||
schema: ts.TypeNode; | ||
questionToken: boolean; | ||
} | ||
export interface StringSubtype { | ||
@@ -650,3 +655,3 @@ type: "string" | ["string", "null"]; | ||
options: TransformNodeOptions, | ||
) => ts.TypeNode | undefined; | ||
) => ts.TypeNode | TransformObject | undefined; | ||
/** Modify TypeScript types built from Schema Objects */ | ||
@@ -653,0 +658,0 @@ postTransform?: ( |
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
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
405396
87
7687