Skip to content

Commit

Permalink
[tcgc] add @clientInitialization decorator (Azure#1398)
Browse files Browse the repository at this point in the history
fixes Azure#914

---------

Co-authored-by: iscai-msft <[email protected]>
  • Loading branch information
2 people authored and markcowl committed Sep 7, 2024
1 parent dfdf6cc commit 3e36dd9
Show file tree
Hide file tree
Showing 14 changed files with 993 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@azure-tools/typespec-client-generator-core"
---

add `@clientInitialization` decorator
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,45 @@ interface MyInterface {}
interface MyInterface {}
```

### `@clientInitialization` {#@Azure.ClientGenerator.Core.clientInitialization}

Client parameters you would like to add to the client. By default, we apply endpoint, credential, and api-version parameters. If you add clientInitialization, we will append those to the default list of parameters.

```typespec
@Azure.ClientGenerator.Core.clientInitialization(options: Model, scope?: valueof string)
```

#### Target

`Namespace | Interface`

#### Parameters

| Name | Type | Description |
| ------- | ---------------- | ------------------------------------------------------------------------------------------------------------- |
| options | `Model` | |
| scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters |

#### Examples

```typespec
// main.tsp
namespace MyService;
op upload(blobName: string): void;
op download(blobName: string): void;
// client.tsp
namespace MyCustomizations;
model MyServiceClientOptions {
blobName: string;
}
@@clientInitialization(MyService, MyServiceClientOptions)
// The generated client will have `blobName` on it. We will also
// elevate the existing `blobName` parameter to the client level.
```

### `@clientName` {#@Azure.ClientGenerator.Core.clientName}

Changes the name of a method, parameter, property, or model generated in the client SDK
Expand Down Expand Up @@ -378,6 +417,46 @@ op myOperationCustomization(params: Params): void;
// method signature is now `op myOperation(params: Params)` just for csharp
```

### `@paramAlias` {#@Azure.ClientGenerator.Core.paramAlias}

Alias the name of a client parameter to a different name. This permits you to have a different name for the parameter in client initialization then on individual methods and still refer to the same parameter.

```typespec
@Azure.ClientGenerator.Core.paramAlias(paramAlias: valueof string, scope?: valueof string)
```

#### Target

`ModelProperty`

#### Parameters

| Name | Type | Description |
| ---------- | ---------------- | ------------------------------------------------------------------------------------------------------------- |
| paramAlias | `valueof string` | |
| scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters |

#### Examples

```typespec
// main.tsp
namespace MyService;
op upload(blobName: string): void;
// client.tsp
namespace MyCustomizations;
model MyServiceClientOptions {
blob: string;
}
@@clientInitialization(MyService, MyServiceClientOptions)
@@paramAlias(MyServiceClientOptions.blob, "blobName")
// The generated client will have `blobName` on it. We will also
// elevate the existing `blob` parameter to the client level.
```

### `@protocolAPI` {#@Azure.ClientGenerator.Core.protocolAPI}

Whether you want to generate an operation as a protocol operation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ npm install --save-peer @azure-tools/typespec-client-generator-core

- [`@access`](./decorators.md#@Azure.ClientGenerator.Core.access)
- [`@client`](./decorators.md#@Azure.ClientGenerator.Core.client)
- [`@clientInitialization`](./decorators.md#@Azure.ClientGenerator.Core.clientInitialization)
- [`@clientName`](./decorators.md#@Azure.ClientGenerator.Core.clientName)
- [`@convenientAPI`](./decorators.md#@Azure.ClientGenerator.Core.convenientAPI)
- [`@flattenProperty`](./decorators.md#@Azure.ClientGenerator.Core.flattenProperty)
- [`@operationGroup`](./decorators.md#@Azure.ClientGenerator.Core.operationGroup)
- [`@override`](./decorators.md#@Azure.ClientGenerator.Core.override)
- [`@paramAlias`](./decorators.md#@Azure.ClientGenerator.Core.paramAlias)
- [`@protocolAPI`](./decorators.md#@Azure.ClientGenerator.Core.protocolAPI)
- [`@usage`](./decorators.md#@Azure.ClientGenerator.Core.usage)
- [`@useSystemTextJsonConverter`](./decorators.md#@Azure.ClientGenerator.Core.useSystemTextJsonConverter)
81 changes: 81 additions & 0 deletions packages/typespec-client-generator-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ npm install @azure-tools/typespec-client-generator-core

- [`@access`](#@access)
- [`@client`](#@client)
- [`@clientInitialization`](#@clientinitialization)
- [`@clientName`](#@clientname)
- [`@convenientAPI`](#@convenientapi)
- [`@flattenProperty`](#@flattenproperty)
- [`@operationGroup`](#@operationgroup)
- [`@override`](#@override)
- [`@paramAlias`](#@paramalias)
- [`@protocolAPI`](#@protocolapi)
- [`@usage`](#@usage)
- [`@useSystemTextJsonConverter`](#@usesystemtextjsonconverter)
Expand Down Expand Up @@ -216,6 +218,45 @@ interface MyInterface {}
interface MyInterface {}
```

#### `@clientInitialization`

Client parameters you would like to add to the client. By default, we apply endpoint, credential, and api-version parameters. If you add clientInitialization, we will append those to the default list of parameters.

```typespec
@Azure.ClientGenerator.Core.clientInitialization(options: Model, scope?: valueof string)
```

##### Target

`Namespace | Interface`

##### Parameters

| Name | Type | Description |
| ------- | ---------------- | ------------------------------------------------------------------------------------------------------------- |
| options | `Model` | |
| scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters |

##### Examples

```typespec
// main.tsp
namespace MyService;
op upload(blobName: string): void;
op download(blobName: string): void;
// client.tsp
namespace MyCustomizations;
model MyServiceClientOptions {
blobName: string;
}
@@clientInitialization(MyService, MyServiceClientOptions)
// The generated client will have `blobName` on it. We will also
// elevate the existing `blobName` parameter to the client level.
```

#### `@clientName`

Changes the name of a method, parameter, property, or model generated in the client SDK
Expand Down Expand Up @@ -391,6 +432,46 @@ op myOperationCustomization(params: Params): void;
// method signature is now `op myOperation(params: Params)` just for csharp
```

#### `@paramAlias`

Alias the name of a client parameter to a different name. This permits you to have a different name for the parameter in client initialization then on individual methods and still refer to the same parameter.

```typespec
@Azure.ClientGenerator.Core.paramAlias(paramAlias: valueof string, scope?: valueof string)
```

##### Target

`ModelProperty`

##### Parameters

| Name | Type | Description |
| ---------- | ---------------- | ------------------------------------------------------------------------------------------------------------- |
| paramAlias | `valueof string` | |
| scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters |

##### Examples

```typespec
// main.tsp
namespace MyService;
op upload(blobName: string): void;
// client.tsp
namespace MyCustomizations;
model MyServiceClientOptions {
blob: string;
}
@@clientInitialization(MyService, MyServiceClientOptions)
@@paramAlias(MyServiceClientOptions.blob, "blobName")
// The generated client will have `blobName` on it. We will also
// elevate the existing `blob` parameter to the client level.
```

#### `@protocolAPI`

Whether you want to generate an operation as a protocol operation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,67 @@ export type UseSystemTextJsonConverterDecorator = (
scope?: string
) => void;

/**
* Client parameters you would like to add to the client. By default, we apply endpoint, credential, and api-version parameters. If you add clientInitialization, we will append those to the default list of parameters.
*
* @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters
* @example
* ```typespec
* // main.tsp
* namespace MyService;
*
* op upload(blobName: string): void;
* op download(blobName: string): void;
*
* // client.tsp
* namespace MyCustomizations;
* model MyServiceClientOptions {
* blobName: string;
* }
*
* @@clientInitialization(MyService, MyServiceClientOptions)
* // The generated client will have `blobName` on it. We will also
* // elevate the existing `blobName` parameter to the client level.
* ```
*/
export type ClientInitializationDecorator = (
context: DecoratorContext,
target: Namespace | Interface,
options: Model,
scope?: string
) => void;

/**
* Alias the name of a client parameter to a different name. This permits you to have a different name for the parameter in client initialization then on individual methods and still refer to the same parameter.
*
* @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters
* @example
* ```typespec
* // main.tsp
* namespace MyService;
*
* op upload(blobName: string): void;
*
* // client.tsp
* namespace MyCustomizations;
* model MyServiceClientOptions {
* blob: string;
* }
*
* @@clientInitialization(MyService, MyServiceClientOptions)
* @@paramAlias(MyServiceClientOptions.blob, "blobName")
*
* // The generated client will have `blobName` on it. We will also
* // elevate the existing `blob` parameter to the client level.
* ```
*/
export type ParamAliasDecorator = (
context: DecoratorContext,
original: ModelProperty,
paramAlias: string,
scope?: string
) => void;

export type AzureClientGeneratorCoreDecorators = {
clientName: ClientNameDecorator;
convenientAPI: ConvenientAPIDecorator;
Expand All @@ -444,4 +505,6 @@ export type AzureClientGeneratorCoreDecorators = {
flattenProperty: FlattenPropertyDecorator;
override: OverrideDecorator;
useSystemTextJsonConverter: UseSystemTextJsonConverterDecorator;
clientInitialization: ClientInitializationDecorator;
paramAlias: ParamAliasDecorator;
};
55 changes: 55 additions & 0 deletions packages/typespec-client-generator-core/lib/decorators.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,58 @@ extern dec override(original: Operation, override: Operation, scope?: valueof st
* ```
*/
extern dec useSystemTextJsonConverter(target: Model, scope?: valueof string);

/**
* Client parameters you would like to add to the client. By default, we apply endpoint, credential, and api-version parameters. If you add clientInitialization, we will append those to the default list of parameters.
* @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters
*
* @example
* ```typespec
* // main.tsp
* namespace MyService;
*
* op upload(blobName: string): void;
* op download(blobName: string): void;
*
* // client.tsp
* namespace MyCustomizations;
* model MyServiceClientOptions {
* blobName: string;
* }
*
* @@clientInitialization(MyService, MyServiceClientOptions)
* // The generated client will have `blobName` on it. We will also
* // elevate the existing `blobName` parameter to the client level.
* ```
*/
extern dec clientInitialization(
target: Namespace | Interface,
options: Model,
scope?: valueof string
);

/**
* Alias the name of a client parameter to a different name. This permits you to have a different name for the parameter in client initialization then on individual methods and still refer to the same parameter.
* @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters
*
* @example
* ```typespec
* // main.tsp
* namespace MyService;
*
* op upload(blobName: string): void;
*
* // client.tsp
* namespace MyCustomizations;
* model MyServiceClientOptions {
* blob: string;
* }
*
* @@clientInitialization(MyService, MyServiceClientOptions)
* @@paramAlias(MyServiceClientOptions.blob, "blobName")
*
* // The generated client will have `blobName` on it. We will also
* // elevate the existing `blob` parameter to the client level.
* ```
*/
extern dec paramAlias(original: ModelProperty, paramAlias: valueof string, scope?: valueof string);
Loading

0 comments on commit 3e36dd9

Please sign in to comment.