Skip to content

Commit

Permalink
Add @externalTypeRef decorator to give a solution for duplicated comm…
Browse files Browse the repository at this point in the history
…on types on compute (#2091)

This will be part of Legacy as for now is intended and planned for
compute use.
Issue: #2058

---------

Co-authored-by: Allen Zhang <allenzhang@live.com>
  • Loading branch information
AlitzelMendez and allenjzhang authored Jan 24, 2025
1 parent db67bee commit 0c7a14b
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
changeKind: feature
packages:
- "@azure-tools/typespec-autorest"
- "@azure-tools/typespec-azure-resource-manager"
---

Add `@externalTypeRef` decorator, to been able to specify an external reference that should be used when emitting.
8 changes: 8 additions & 0 deletions packages/typespec-autorest/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from "@azure-tools/typespec-azure-core";
import {
getArmCommonTypeOpenAPIRef,
getExternalTypeRef,
isArmCommonType,
isAzureResource,
isConditionallyFlattened,
Expand Down Expand Up @@ -936,6 +937,13 @@ export async function getOpenAPIForService(
};
}

const externalTypeRefUrl = getExternalTypeRef(program, type);
if (externalTypeRefUrl) {
return {
$ref: expandRef(externalTypeRefUrl),
};
}

if (
isArmCommonType(type) &&
(type.kind === "Model" ||
Expand Down
19 changes: 19 additions & 0 deletions packages/typespec-azure-resource-manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ This allows sharing Azure Resource Manager resource types across specifications
### Azure.ResourceManager.Legacy

- [`@customAzureResource`](#@customazureresource)
- [`@externalTypeRef`](#@externaltyperef)

#### `@customAzureResource`

Expand All @@ -518,3 +519,21 @@ but need to be identified as such.
##### Parameters

None

#### `@externalTypeRef`

Specify an external reference that should be used when emitting this type.

```typespec
@Azure.ResourceManager.Legacy.externalTypeRef(jsonRef: valueof string)
```

##### Target

`Model | ModelProperty`

##### Parameters

| Name | Type | Description |
| ------- | ---------------- | ------------------------------------------------------------- |
| jsonRef | `valueof string` | External reference(e.g. "../../common.json#/definitions/Foo") |
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
EnumValue,
Interface,
Model,
ModelProperty,
Namespace,
Operation,
Type,
Expand Down Expand Up @@ -266,6 +267,17 @@ export type ResourceBaseTypeDecorator = (
baseType: Type,
) => void;

/**
* * Specify an external reference that should be used when emitting this type.
* * @param jsonRef - External reference(e.g. "../../common.json#/definitions/Foo")
*
*/
export type ExternalTypeRefDecorator = (
context: DecoratorContext,
entity: Model | ModelProperty,
jsonRef: string,
) => void;

export type AzureResourceManagerDecorators = {
armResourceCollectionAction: ArmResourceCollectionActionDecorator;
armProviderNameValue: ArmProviderNameValueDecorator;
Expand All @@ -292,4 +304,5 @@ export type AzureResourceManagerDecorators = {

export type AzureResourceManagerLegacyDecorators = {
customAzureResource: CustomAzureResourceDecorator;
externalTypeRef: ExternalTypeRefDecorator;
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ namespace Azure.ResourceManager.Legacy;
* but need to be identified as such.
*/
extern dec customAzureResource(target: Model);

/**
* Specify an external reference that should be used when emitting this type.
* @param jsonRef - External reference(e.g. "../../common.json#/definitions/Foo")
*/
extern dec externalTypeRef(entity: Model | ModelProperty, jsonRef: valueof string);
17 changes: 16 additions & 1 deletion packages/typespec-azure-resource-manager/src/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
isTypeSpecValueTypeOf,
} from "@typespec/compiler";
import { $useDependency, getVersion } from "@typespec/versioning";
import { ArmCommonTypesVersionDecorator } from "../generated-defs/Azure.ResourceManager.js";
import {
ArmCommonTypesVersionDecorator,
ExternalTypeRefDecorator,
} from "../generated-defs/Azure.ResourceManager.js";
import {
ArmCommonTypeRecord,
ArmCommonTypesDefaultVersion,
Expand Down Expand Up @@ -247,3 +250,15 @@ function resolveCommonTypesVersion(
allVersions: allVersions ?? [],
};
}

export const $externalTypeRef: ExternalTypeRefDecorator = (
context: DecoratorContext,
entity: Model | ModelProperty,
jsonRef: string,
) => {
context.program.stateMap(ArmStateKeys.externalTypeRef).set(entity, jsonRef);
};

export function getExternalTypeRef(program: Program, entity: Type): string | undefined {
return program.stateMap(ArmStateKeys.externalTypeRef).get(entity);
}
1 change: 1 addition & 0 deletions packages/typespec-azure-resource-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export {
getArmCommonTypeOpenAPIRef,
getArmCommonTypesVersion,
getArmCommonTypesVersions,
getExternalTypeRef,
isArmCommonType,
type ArmCommonTypeVersions,
type ArmCommonTypesResolutionOptions,
Expand Down
1 change: 1 addition & 0 deletions packages/typespec-azure-resource-manager/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const ArmStateKeys = {
armLibraryNamespaces: azureResourceManagerCreateStateSymbol("armLibraryNamespaces"),
usesArmLibraryNamespaces: azureResourceManagerCreateStateSymbol("usesArmLibraryNamespaces"),
armCommonTypesVersion: azureResourceManagerCreateStateSymbol("armCommonTypesVersion"),
externalTypeRef: azureResourceManagerCreateStateSymbol("externalTypeRef"),

// resource.ts
armResourcesCached: azureResourceManagerCreateStateSymbol("armResourcesCached"),
Expand Down
3 changes: 2 additions & 1 deletion packages/typespec-azure-resource-manager/src/tsp-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
AzureResourceManagerDecorators,
AzureResourceManagerLegacyDecorators,
} from "../generated-defs/Azure.ResourceManager.js";
import { $armCommonTypesVersion } from "./common-types.js";
import { $armCommonTypesVersion, $externalTypeRef } from "./common-types.js";
import { $armLibraryNamespace, $armProviderNamespace, $useLibraryNamespace } from "./namespace.js";
import {
$armResourceAction,
Expand Down Expand Up @@ -57,6 +57,7 @@ export const $decorators = {
} satisfies AzureResourceManagerDecorators,
"Azure.ResourceManager.Legacy": {
customAzureResource: $customAzureResource,
externalTypeRef: $externalTypeRef,
} satisfies AzureResourceManagerLegacyDecorators,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Diagnostic, Model, ModelProperty, Namespace } from "@typespec/compiler";
import { getService } from "@typespec/compiler";
import { expectDiagnosticEmpty, expectDiagnostics } from "@typespec/compiler/testing";
import { strictEqual } from "assert";
import { describe, expect, it } from "vitest";
import { findArmCommonTypeRecord } from "../src/common-types.js";
import { findArmCommonTypeRecord, getExternalTypeRef } from "../src/common-types.js";
import type { ArmCommonTypeRecord } from "../src/commontypes.private.decorators.js";
import { createAzureResourceManagerTestRunner } from "./test-host.js";

Expand Down Expand Up @@ -205,3 +206,16 @@ describe("common parameters", () => {
});
});
});

describe("common types ref", () => {
it("set external reference", async () => {
const runner = await createAzureResourceManagerTestRunner();
const [{ Foo }, diagnostics] = await runner.compileAndDiagnose(`
@test @Azure.ResourceManager.Legacy.externalTypeRef("../common.json#/definitions/Foo")
model Foo {}
`);

expectDiagnosticEmpty(diagnostics);
strictEqual(getExternalTypeRef(runner.program, Foo), "../common.json#/definitions/Foo");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -435,3 +435,21 @@ but need to be identified as such.
#### Parameters

None

### `@externalTypeRef` {#@Azure.ResourceManager.Legacy.externalTypeRef}

Specify an external reference that should be used when emitting this type.

```typespec
@Azure.ResourceManager.Legacy.externalTypeRef(jsonRef: valueof string)
```

#### Target

`Model | ModelProperty`

#### Parameters

| Name | Type | Description |
| ------- | ---------------- | ------------------------------------------------------------- |
| jsonRef | `valueof string` | External reference(e.g. "../../common.json#/definitions/Foo") |
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ npm install --save-peer @azure-tools/typespec-azure-resource-manager
### Decorators

- [`@customAzureResource`](./decorators.md#@Azure.ResourceManager.Legacy.customAzureResource)
- [`@externalTypeRef`](./decorators.md#@Azure.ResourceManager.Legacy.externalTypeRef)

### Models

Expand Down

0 comments on commit 0c7a14b

Please sign in to comment.