Skip to content

Commit

Permalink
Add schema to postTransform options (#2049)
Browse files Browse the repository at this point in the history
* Add schema to postTransform options

Closes #2013

* fixup! Add schema to postTransform options

Closes #2013

* fixup! Add schema to postTransform options

Closes #2013

* fixup! Add schema to postTransform options
  • Loading branch information
duncanbeevers authored Jan 3, 2025
1 parent 5bb2e15 commit 39f9b2f
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-worms-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-typescript": patch
---

Add schema to postTransform options
14 changes: 12 additions & 2 deletions docs/6.x/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ Resultant diff with correctly-typed `file` property:
+ file?: Blob;
```
Any [Schema Object](https://spec.openapis.org/oas/latest.html#schema-object) present in your schema will be run through this formatter (even remote ones!). Also be sure to check the `metadata` parameter for additional context that may be helpful.
#### transform / postTransform metadata
There are many other uses for this besides checking `format`. Because this must return a **string** you can produce any arbitrary TypeScript code you’d like (even your own custom types).
Any [Schema Object](https://spec.openapis.org/oas/latest.html#schema-object) present in your schema will be run through `transform`, prior to its conversion to a TypeScript AST node, and `postTransform` after its conversion, including remote schemas!
The `metadata` parameter present on both `transform` and `postTransform` has additional context that may be helpful.
| Property | Description |
|-|-|
| `metadata.path` | A [`$ref`](https://json-schema.org/understanding-json-schema/structuring#dollarref) URI string, pointing to the current schema object |
| `metadata.schema` | The schema object being transformed (only present for `postTransform`) |
| `metadata.ctx` | The GlobalContext object, containing
There are many other uses for this besides checking `format`. Because `tranform` may return a **string** you can produce any arbitrary TypeScript code you’d like (even your own custom types).
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,18 @@ export default function transformComponentsObject(componentsObject: ComponentsOb

const items: ts.TypeElement[] = [];
if (componentsObject[key]) {
for (const [name, item] of getEntries(componentsObject[key], ctx)) {
for (const [name, item] of getEntries<SchemaObject>(componentsObject[key], ctx)) {
let subType = transformers[key](item, {
path: createRef(["components", key, name]),
schema: item,
ctx,
});

let hasQuestionToken = false;
if (ctx.transform) {
const result = ctx.transform(item as SchemaObject, {
const result = ctx.transform(item, {
path: createRef(["components", key, name]),
schema: item,
ctx,
});
if (result) {
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-typescript/src/transform/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const transformers: Record<SchemaTransforms, (node: any, options: GlobalContext)
paths: transformPathsObject,
webhooks: transformWebhooksObject,
components: transformComponentsObject,
$defs: (node, options) => transformSchemaObject(node, { path: createRef(["$defs"]), ctx: options }),
$defs: (node, options) => transformSchemaObject(node, { path: createRef(["$defs"]), ctx: options, schema: node }),
};

export default function transformSchema(schema: OpenAPI3, ctx: GlobalContext) {
Expand Down
1 change: 1 addition & 0 deletions packages/openapi-typescript/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -710,5 +710,6 @@ export type $defs = Record<string, SchemaObject>;
/** generic options for most internal transform* functions */
export interface TransformNodeOptions {
path?: string;
schema?: SchemaObject | ReferenceObject;
ctx: GlobalContext;
}
35 changes: 34 additions & 1 deletion packages/openapi-typescript/test/node-api.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fileURLToPath } from "node:url";
import ts from "typescript";
import openapiTS, { COMMENT_HEADER, astToString } from "../src/index.js";
import type { OpenAPITSOptions } from "../src/types.js";
import type { OpenAPITSOptions, ReferenceObject, SchemaObject } from "../src/types.js";
import type { TestCase } from "./test-helpers.js";

const EXAMPLES_DIR = new URL("../examples/", import.meta.url);
Expand Down Expand Up @@ -537,6 +537,11 @@ export type operations = Record<string, never>;`,
components: {
schemas: {
Date: { type: "string", format: "date-time" },
Set: {
"x-string-enum-to-set": true,
type: "string",
enum: ["low", "medium", "high"],
},
},
},
},
Expand All @@ -546,6 +551,8 @@ export interface components {
schemas: {
/** Format: date-time */
Date: DateOrTime;
/** @enum {string} */
Set: Set<"low" | "medium" | "high">;
};
responses: never;
parameters: never;
Expand All @@ -565,6 +572,32 @@ export type operations = Record<string, never>;`,
*/
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("DateOrTime"));
}

// Previously, in order to access the schema in postTransform,
// you could resolve the schema using the path.
// Now, the schema is made available directly on the options.
// const schema = options.path
// ? options.ctx.resolve<ReferenceObject | SchemaObject>(options.path)
// : undefined;
const schema = options.schema;

if (
schema &&
!("$ref" in schema) &&
Object.hasOwn(schema, "x-string-enum-to-set") &&
schema.type === "string" &&
schema.enum?.every((enumMember) => {
return typeof enumMember === "string";
})
) {
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Set"), [
ts.factory.createUnionTypeNode(
schema.enum.map((value) => {
return ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value));
}),
),
]);
}
},
},
},
Expand Down

0 comments on commit 39f9b2f

Please sign in to comment.