Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@typespec/openapi3"
---

Adds support for emitting tuples for Open API 3.1
17 changes: 17 additions & 0 deletions packages/openapi3/src/schema-emitter-3-1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import {
Program,
Scalar,
serializeValueAsJson,
Tuple,
Type,
Union,
} from "@typespec/compiler";
import {
ArrayBuilder,
AssetEmitter,
createAssetEmitter,
EmitterOutput,
Expand Down Expand Up @@ -239,4 +241,19 @@ export class OpenAPI31SchemaEmitter extends OpenAPI3SchemaEmitterBase<OpenAPISch
});
return {};
}

tupleLiteral(tuple: Tuple): EmitterOutput<Record<string, any>> {
return new ObjectBuilder({
type: "array",
prefixItems: this.emitter.emitTupleLiteralValues(tuple),
});
}

tupleLiteralValues(tuple: Tuple): EmitterOutput<Record<string, any>> {
const values = new ArrayBuilder();
for (const value of tuple.values.values()) {
values.push(this.emitter.emitType(value));
}
return values;
}
}
56 changes: 55 additions & 1 deletion packages/openapi3/test/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,10 @@ worksFor(["3.0.0", "3.1.0"], ({ oapiForModel, openApiFor }) => {

strictEqual(res.schemas.Foo.title, "FooArray");
});
});

it("can specify tuple defaults using tuple syntax", async () => {
worksFor(["3.0.0"], ({ oapiForModel }) => {
it("can specify tuple defaults using tuple syntax (empty items)", async () => {
const res = await oapiForModel(
"Pet",
`
Expand Down Expand Up @@ -258,3 +260,55 @@ worksFor(["3.0.0", "3.1.0"], ({ oapiForModel, openApiFor }) => {
});
});
});

worksFor(["3.1.0"], ({ oapiForModel }) => {
it("can specify tuple defaults using tuple syntax (prefix items)", async () => {
const res = await oapiForModel(
"Pet",
`
model Pet {
names: [string, int32] = #["bismarck", 12];
decimals: [string, decimal] = #["hi", 456.7];
decimal128s: [string, decimal128] = #["hi", 456.7];
};
`,
);

deepStrictEqual(res.schemas.Pet.properties.names, {
type: "array",
prefixItems: [{ type: "string" }, { type: "integer", format: "int32" }],
default: ["bismarck", 12],
});

deepStrictEqual(res.schemas.Pet.properties.decimals, {
type: "array",
prefixItems: [{ type: "string" }, { type: "number", format: "decimal" }],
default: ["hi", 456.7],
});

deepStrictEqual(res.schemas.Pet.properties.decimal128s, {
type: "array",
prefixItems: [{ type: "string" }, { type: "number", format: "decimal128" }],
default: ["hi", 456.7],
});
});

it("can specify tuple with constants", async () => {
const res = await oapiForModel(
"Pet",
`
model Pet {
names: ["bismark", 32];
};
`,
);

deepStrictEqual(res.schemas.Pet.properties.names, {
type: "array",
prefixItems: [
{ type: "string", enum: ["bismark"] },
{ type: "number", enum: [32] },
],
});
});
});