Skip to content

Commit

Permalink
Backmerge various union hotfixes into main (#252)
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheeguerin authored Feb 12, 2024
1 parent 266bc7d commit 8ab2f16
Show file tree
Hide file tree
Showing 25 changed files with 356 additions and 136 deletions.
8 changes: 4 additions & 4 deletions docs/libraries/azure-core/reference/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Identifies an EnumMember as a long-running "Canceled" terminal state.

#### Target

`EnumMember`
`union EnumMember | UnionVariant`

#### Parameters

Expand Down Expand Up @@ -124,7 +124,7 @@ Identifies an enum member as a long-running "Failed" terminal state.

#### Target

`EnumMember`
`union EnumMember | UnionVariant`

#### Parameters

Expand Down Expand Up @@ -160,7 +160,7 @@ status.

#### Target

`union Enum | ModelProperty`
`union Enum | Union | ModelProperty`

#### Parameters

Expand All @@ -177,7 +177,7 @@ Identifies an EnumMember as a long-running "Succeeded" terminal state.

#### Target

`EnumMember`
`union EnumMember | UnionVariant`

#### Parameters

Expand Down
9 changes: 9 additions & 0 deletions docs/libraries/azure-core/rules/no-enum.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,12 @@ union PetKind {
string,
}
```

Ok. Enum is allowed for versioning purposes.

```tsp
enum Version {
2021_01_01: "2021-01-01",
2022_01_01: "2022-01-01",
}
```
7 changes: 7 additions & 0 deletions packages/typespec-autorest/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Change Log - @azure-tools/typespec-autorest

## 0.39.2

### Patch Changes

- 9baadd2: `readonly` was not added when `use-read-only-status-schema` is set to `true` for union types.
- 9baadd2: Fix `UnionType | null` would be inlined instead of referencing `UnionType`

## 0.39.1

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/typespec-autorest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure-tools/typespec-autorest",
"version": "0.39.1",
"version": "0.39.2",
"author": "Microsoft Corporation",
"description": "TypeSpec library for emitting openapi from the TypeSpec REST protocol binding",
"homepage": "https://azure.github.io/typespec-azure",
Expand Down
18 changes: 12 additions & 6 deletions packages/typespec-autorest/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1507,7 +1507,7 @@ function createOAPIEmitter(
}> = [];
let foundCustom = false;
for (const [name, member] of e.flattenedMembers.entries()) {
const description = getDoc(program, member.variant);
const description = getDoc(program, member.type);
values.push({
name: typeof name === "string" ? name : `${member.value}`,
value: member.value,
Expand All @@ -1532,15 +1532,16 @@ function createOAPIEmitter(
if (e.nullable) {
schema["x-nullable"] = true;
}
if (options.useReadOnlyStatusSchema) {
const [values, _] = extractLroStates(program, union);
if (values !== undefined) {
schema.readOnly = true;
}
}
return applyIntrinsicDecorators(union, schema);
}

function getSchemaForUnion(union: Union, visibility: Visibility): OpenAPI2Schema {
const [asEnum, _] = getUnionAsEnum(union);
if (asEnum) {
return getSchemaForUnionEnum(union, asEnum);
}

const nonNullOptions = [...union.variants.values()]
.map((x) => x.type)
.filter((t) => !isNullType(t));
Expand All @@ -1552,6 +1553,7 @@ function createOAPIEmitter(

if (nonNullOptions.length === 1) {
const type = nonNullOptions[0];

// Get the schema for the model type
const schema = getSchemaOrRef(type, visibility);
if (schema.$ref) {
Expand All @@ -1565,6 +1567,10 @@ function createOAPIEmitter(
return schema;
}
} else {
const [asEnum, _] = getUnionAsEnum(union);
if (asEnum) {
return getSchemaForUnionEnum(union, asEnum);
}
reportDiagnostic(program, {
code: "union-unsupported",
target: union,
Expand Down
62 changes: 62 additions & 0 deletions packages/typespec-autorest/test/models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,68 @@ describe("typespec-autorest: model definitions", () => {
required: ["name"],
});
});

it("defines nullable enum", async () => {
const res = await oapiForModel(
"Pet",
`
enum PetKind { dog, cat }
model Pet {
kind: PetKind | null;
};
`
);
ok(res.isRef);
deepStrictEqual(res.defs.Pet, {
type: "object",
properties: {
kind: {
$ref: "#/definitions/PetKind",
"x-nullable": true,
},
},
required: ["kind"],
});
deepStrictEqual(res.defs.PetKind, {
type: "string",
enum: ["dog", "cat"],
"x-ms-enum": {
modelAsString: true,
name: "PetKind",
},
});
});

it("defines nullable union", async () => {
const res = await oapiForModel(
"Pet",
`
union PetKind { "dog", "cat" }
model Pet {
kind: PetKind | null;
};
`
);
ok(res.isRef);
deepStrictEqual(res.defs.Pet, {
type: "object",
properties: {
kind: {
$ref: "#/definitions/PetKind",
"x-nullable": true,
},
},
required: ["kind"],
});
deepStrictEqual(res.defs.PetKind, {
type: "string",
enum: ["dog", "cat"],
"x-ms-enum": {
modelAsString: false,
name: "PetKind",
},
});
});
});

it("recovers logical type name", async () => {
Expand Down
81 changes: 0 additions & 81 deletions packages/typespec-autorest/test/openapi-output.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,87 +402,6 @@ describe("typespec-autorest: definitions", () => {
deepStrictEqual(res.defs.Pet.properties.someString.default, "withDefault");
});

describe("nullable", () => {
it("defines nullable properties", async () => {
const res = await oapiForModel(
"Pet",
`
model Pet {
name: string | null;
};
`
);
ok(res.isRef);
deepStrictEqual(res.defs.Pet, {
type: "object",
properties: {
name: {
type: "string",
"x-nullable": true,
},
},
required: ["name"],
});
});

it("defines nullable array", async () => {
const res = await oapiForModel(
"Pet",
`
model Pet {
name: int32[] | null;
};
`
);
ok(res.isRef);
deepStrictEqual(res.defs.Pet, {
type: "object",
properties: {
name: {
type: "array",
items: {
type: "integer",
format: "int32",
},
"x-nullable": true,
},
},
required: ["name"],
});
});

it("defines nullable enum", async () => {
const res = await oapiForModel(
"Pet",
`
enum PetKind { dog, cat }
model Pet {
kind: PetKind | null;
};
`
);
ok(res.isRef);
deepStrictEqual(res.defs.Pet, {
type: "object",
properties: {
kind: {
$ref: "#/definitions/PetKind",
"x-nullable": true,
},
},
required: ["kind"],
});
deepStrictEqual(res.defs.PetKind, {
type: "string",
enum: ["dog", "cat"],
"x-ms-enum": {
modelAsString: true,
name: "PetKind",
},
});
});
});

describe("unions", () => {
it("emit a warning", async () => {
const diagnostics = await diagnoseOpenApiFor(`
Expand Down
36 changes: 36 additions & 0 deletions packages/typespec-autorest/test/property-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,40 @@ describe("typespec-autorest: Property schema tests", () => {
ok(!result.isRef);
deepStrictEqual(result.definitions.FooPrime.readOnly, true);
});

it("creates readOnly schema for status properties when set to 'use-read-only-status-schema': true for unions", async () => {
const result = await openApiFor(
`
@service({title: "Test"})
namespace Test;
model Bar {propB: int32;}
model Foo { prop1: string;}
union FooPrime { "Succeeded", "Failed", "Canceled"}
@pattern("[a-Z0-9]+")
scalar BarPrime extends string;
model UsesAll {
@visibility("read")
fooProp: Foo;
@visibility("read")
primeProp: FooPrime;
@visibility("read")
barPrimeProp: BarPrime;
otherProp: FooPrime;
}
op myOp(): void;
`,
undefined,
{ "use-read-only-status-schema": true }
);

ok(!result.isRef);
deepStrictEqual(result.definitions.FooPrime.readOnly, true);
});
});
8 changes: 8 additions & 0 deletions packages/typespec-azure-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Change Log - @azure-tools/typespec-azure-core

## 0.39.1

### Patch Changes

- 9baadd2: Allow to define lroStatus on a union type
- 9baadd2: `no-enum` linter rule allows the `Version` enum.


## 0.39.0

### Patch Changes
Expand Down
8 changes: 4 additions & 4 deletions packages/typespec-azure-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Identifies an EnumMember as a long-running "Canceled" terminal state.

##### Target

`EnumMember`
`union EnumMember | UnionVariant`

##### Parameters

Expand Down Expand Up @@ -202,7 +202,7 @@ Identifies an enum member as a long-running "Failed" terminal state.

##### Target

`EnumMember`
`union EnumMember | UnionVariant`

##### Parameters

Expand Down Expand Up @@ -238,7 +238,7 @@ status.

##### Target

`union Enum | ModelProperty`
`union Enum | Union | ModelProperty`

##### Parameters

Expand All @@ -255,7 +255,7 @@ Identifies an EnumMember as a long-running "Succeeded" terminal state.

##### Target

`EnumMember`
`union EnumMember | UnionVariant`

##### Parameters

Expand Down
8 changes: 4 additions & 4 deletions packages/typespec-azure-core/lib/decorators.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,25 @@ namespace Azure {
* Identifies an Enum or ModelProperty as containing long-running operation
* status.
*/
extern dec lroStatus(entity: Enum | ModelProperty);
extern dec lroStatus(entity: Enum | Union | ModelProperty);

/**
* Used for custom StatusMonitor implementation.
* Identifies an EnumMember as a long-running "Succeeded" terminal state.
*/
extern dec lroSucceeded(entity: EnumMember);
extern dec lroSucceeded(entity: EnumMember | UnionVariant);

/**
* Used for custom StatusMonitor implementation.
* Identifies an EnumMember as a long-running "Canceled" terminal state.
*/
extern dec lroCanceled(entity: EnumMember);
extern dec lroCanceled(entity: EnumMember | UnionVariant);

/**
* Used for custom StatusMonitor implementation.
* Identifies an enum member as a long-running "Failed" terminal state.
*/
extern dec lroFailed(entity: EnumMember);
extern dec lroFailed(entity: EnumMember | UnionVariant);

/**
* Used for custom StatusMonitor implementation.
Expand Down
Loading

0 comments on commit 8ab2f16

Please sign in to comment.