[OpenAPI3 Emitter] Add option to map `safeint` to `double-int` (#2933)
fix #2367 Format was added to the schema registry so we are safe to use that now https://spec.openapis.org/registry/format/double-int.html --------- Co-authored-by: Brian Terlson <brian.terlson@microsoft.com>
This commit is contained in:
Родитель
02ed01e79b
Коммит
9654dd836b
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
|
||||
changeKind: feature
|
||||
packages:
|
||||
- "@typespec/openapi3"
|
||||
---
|
||||
|
||||
Add a new option `safeint-strategy` that can be set to `double-int` to emit `type: integer, format: double-int` instead of `type: integer, format: int64` when using the `safeint` scalar.
|
|
@ -81,3 +81,14 @@ By default all types declared under the service namespace will be included. With
|
|||
|
||||
If the generated openapi types should have the `x-typespec-name` extension set with the name of the TypeSpec type that created it.
|
||||
This extension is meant for debugging and should not be depended on.
|
||||
|
||||
### `safeint-strategy`
|
||||
|
||||
**Type:** `"double-int" | "int64"`
|
||||
|
||||
How to handle safeint type. Options are:
|
||||
|
||||
- `double-int`: Will produce `type: integer, format: double-int`
|
||||
- `int64`: Will produce `type: integer, format: int64`
|
||||
|
||||
Default: `int64`
|
||||
|
|
|
@ -86,6 +86,17 @@ By default all types declared under the service namespace will be included. With
|
|||
If the generated openapi types should have the `x-typespec-name` extension set with the name of the TypeSpec type that created it.
|
||||
This extension is meant for debugging and should not be depended on.
|
||||
|
||||
#### `safeint-strategy`
|
||||
|
||||
**Type:** `"double-int" | "int64"`
|
||||
|
||||
How to handle safeint type. Options are:
|
||||
|
||||
- `double-int`: Will produce `type: integer, format: double-int`
|
||||
- `int64`: Will produce `type: integer, format: int64`
|
||||
|
||||
Default: `int64`
|
||||
|
||||
## Decorators
|
||||
|
||||
### TypeSpec.OpenAPI
|
||||
|
|
|
@ -54,6 +54,14 @@ export interface OpenAPI3EmitterOptions {
|
|||
* @default "never"
|
||||
*/
|
||||
"include-x-typespec-name"?: "inline-only" | "never";
|
||||
|
||||
/**
|
||||
* How to handle safeint type. Options are:
|
||||
* - `double-int`: Will produce `type: integer, format: double-int`
|
||||
* - `int64`: Will produce `type: integer, format: int64`
|
||||
* @default "int64"
|
||||
*/
|
||||
"safeint-strategy"?: "double-int" | "int64";
|
||||
}
|
||||
|
||||
const EmitterOptionsSchema: JSONSchemaType<OpenAPI3EmitterOptions> = {
|
||||
|
@ -117,6 +125,19 @@ const EmitterOptionsSchema: JSONSchemaType<OpenAPI3EmitterOptions> = {
|
|||
description:
|
||||
"If the generated openapi types should have the `x-typespec-name` extension set with the name of the TypeSpec type that created it.\nThis extension is meant for debugging and should not be depended on.",
|
||||
},
|
||||
"safeint-strategy": {
|
||||
type: "string",
|
||||
enum: ["double-int", "int64"],
|
||||
nullable: true,
|
||||
default: "int64",
|
||||
description: [
|
||||
"How to handle safeint type. Options are:",
|
||||
" - `double-int`: Will produce `type: integer, format: double-int`",
|
||||
" - `int64`: Will produce `type: integer, format: int64`",
|
||||
"",
|
||||
"Default: `int64`",
|
||||
].join("\n"),
|
||||
},
|
||||
},
|
||||
required: [],
|
||||
};
|
||||
|
|
|
@ -118,6 +118,7 @@ const defaultOptions = {
|
|||
"new-line": "lf",
|
||||
"omit-unreachable-types": false,
|
||||
"include-x-typespec-name": "never",
|
||||
"safeint-strategy": "int64",
|
||||
} as const;
|
||||
|
||||
export async function $onEmit(context: EmitContext<OpenAPI3EmitterOptions>) {
|
||||
|
@ -186,6 +187,7 @@ export function resolveOptions(
|
|||
newLine: resolvedOptions["new-line"],
|
||||
omitUnreachableTypes: resolvedOptions["omit-unreachable-types"],
|
||||
includeXTypeSpecName: resolvedOptions["include-x-typespec-name"],
|
||||
safeintStrategy: resolvedOptions["safeint-strategy"],
|
||||
outputFile: resolvePath(context.emitterOutputDir, outputFile),
|
||||
};
|
||||
}
|
||||
|
@ -196,6 +198,7 @@ export interface ResolvedOpenAPI3EmitterOptions {
|
|||
newLine: NewLine;
|
||||
omitUnreachableTypes: boolean;
|
||||
includeXTypeSpecName: "inline-only" | "never";
|
||||
safeintStrategy: "double-int" | "int64";
|
||||
}
|
||||
|
||||
function createOAPIEmitter(
|
||||
|
|
|
@ -699,7 +699,13 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter<
|
|||
case "int64":
|
||||
return { type: "integer", format: "int64" };
|
||||
case "safeint":
|
||||
return { type: "integer", format: "int64" };
|
||||
switch (this.#options.safeintStrategy) {
|
||||
case "double-int":
|
||||
return { type: "integer", format: "double-int" };
|
||||
case "int64":
|
||||
default:
|
||||
return { type: "integer", format: "int64" };
|
||||
}
|
||||
case "uint8":
|
||||
return { type: "integer", format: "uint8" };
|
||||
case "uint16":
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { deepStrictEqual, ok, strictEqual } from "assert";
|
||||
import { describe, it } from "vitest";
|
||||
import { OpenAPI3Schema } from "../src/types.js";
|
||||
import { oapiForModel } from "./test-host.js";
|
||||
import { oapiForModel, openApiFor } from "./test-host.js";
|
||||
|
||||
describe("openapi3: primitives", () => {
|
||||
describe("handle TypeSpec intrinsic types", () => {
|
||||
|
@ -48,6 +48,34 @@ describe("openapi3: primitives", () => {
|
|||
}
|
||||
});
|
||||
|
||||
describe("safeint-strategy", () => {
|
||||
it("produce type: integer, format: double-int for safeint when safeint-strategy is double-int", async () => {
|
||||
const res = await openApiFor(
|
||||
`
|
||||
model Pet { name: safeint };
|
||||
`,
|
||||
undefined,
|
||||
{ "safeint-strategy": "double-int" }
|
||||
);
|
||||
|
||||
const schema = res.components.schemas.Pet.properties.name;
|
||||
deepStrictEqual(schema, { type: "integer", format: "double-int" });
|
||||
});
|
||||
|
||||
it("produce type: integer, format: int64 for safeint when safeint-strategy is int64", async () => {
|
||||
const res = await openApiFor(
|
||||
`
|
||||
model Pet { name: safeint };
|
||||
`,
|
||||
undefined,
|
||||
{ "safeint-strategy": "int64" }
|
||||
);
|
||||
|
||||
const schema = res.components.schemas.Pet.properties.name;
|
||||
deepStrictEqual(schema, { type: "integer", format: "int64" });
|
||||
});
|
||||
});
|
||||
|
||||
it("defines models extended from primitives", async () => {
|
||||
const res = await oapiForModel(
|
||||
"Pet",
|
||||
|
|
Загрузка…
Ссылка в новой задаче