From 93f3ab6ca4a92eb52eff6c5f1c34d425349d0037 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Thu, 18 Jul 2024 14:35:45 -0700 Subject: [PATCH] TCGC generate decorator signatures (#1201) --- ...-tcgc-dec-signatures-2024-6-18-13-22-29.md | 6 + .../reference/decorators.md | 4 +- .../typespec-client-generator-core/README.md | 4 +- .../Azure.ClientGenerator.Core.ts | 433 ++++++++++++++++++ .../Azure.ClientGenerator.Core.ts-test.ts | 60 +++ .../lib/decorators.tsp | 2 +- .../package.json | 3 +- .../src/decorators.ts | 98 ++-- .../tsconfig.json | 2 +- 9 files changed, 570 insertions(+), 42 deletions(-) create mode 100644 .chronus/changes/generate-tcgc-dec-signatures-2024-6-18-13-22-29.md create mode 100644 packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts create mode 100644 packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts diff --git a/.chronus/changes/generate-tcgc-dec-signatures-2024-6-18-13-22-29.md b/.chronus/changes/generate-tcgc-dec-signatures-2024-6-18-13-22-29.md new file mode 100644 index 0000000000..40b3c23d94 --- /dev/null +++ b/.chronus/changes/generate-tcgc-dec-signatures-2024-6-18-13-22-29.md @@ -0,0 +1,6 @@ +--- +changeKind: internal +packages: + - "@azure-tools/typespec-client-generator-core" +--- + diff --git a/docs/libraries/typespec-client-generator-core/reference/decorators.md b/docs/libraries/typespec-client-generator-core/reference/decorators.md index 4efe92395c..36bd651b37 100644 --- a/docs/libraries/typespec-client-generator-core/reference/decorators.md +++ b/docs/libraries/typespec-client-generator-core/reference/decorators.md @@ -152,7 +152,7 @@ op func8(@body body: Test5): void; Create a ClientGenerator.Core client out of a namespace or interface ```typespec -@Azure.ClientGenerator.Core.client(value?: {}, scope?: valueof string) +@Azure.ClientGenerator.Core.client(value?: Model, scope?: valueof string) ``` #### Target @@ -163,7 +163,7 @@ Create a ClientGenerator.Core client out of a namespace or interface | Name | Type | Description | | ----- | ---------------- | ------------------------------------------------------------------------------------------------------------- | -| value | `{}` | Optional configuration for the service. | +| value | `Model` | Optional configuration for the service. | | scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters | #### Examples diff --git a/packages/typespec-client-generator-core/README.md b/packages/typespec-client-generator-core/README.md index 76f11fbe28..13e4b1f39a 100644 --- a/packages/typespec-client-generator-core/README.md +++ b/packages/typespec-client-generator-core/README.md @@ -169,7 +169,7 @@ op func8(@body body: Test5): void; Create a ClientGenerator.Core client out of a namespace or interface ```typespec -@Azure.ClientGenerator.Core.client(value?: {}, scope?: valueof string) +@Azure.ClientGenerator.Core.client(value?: Model, scope?: valueof string) ``` ##### Target @@ -180,7 +180,7 @@ Create a ClientGenerator.Core client out of a namespace or interface | Name | Type | Description | | ----- | ---------------- | ------------------------------------------------------------------------------------------------------------- | -| value | `{}` | Optional configuration for the service. | +| value | `Model` | Optional configuration for the service. | | scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters | ##### Examples diff --git a/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts new file mode 100644 index 0000000000..c4facd7f8e --- /dev/null +++ b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts @@ -0,0 +1,433 @@ +import type { + DecoratorContext, + Enum, + EnumMember, + Interface, + Model, + ModelProperty, + Namespace, + Operation, + Type, + Union, +} from "@typespec/compiler"; + +/** + * Changes the name of a method, parameter, property, or model generated in the client SDK + * + * @param rename The rename you want applied to the object + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @clientName("nameInClient") + * op nameInService: void; + * ``` + * @example + * ```typespec + * @clientName("nameForJava", "java") + * @clientName("name_for_python", "python") + * @clientName("nameForCsharp", "csharp") + * @clientName("nameForJavascript", "javascript") + * op nameInService: void; + * ``` + */ +export type ClientNameDecorator = ( + context: DecoratorContext, + target: Type, + rename: string, + scope?: string +) => void; + +/** + * Whether you want to generate an operation as a convenient operation. + * + * @param value Whether to generate the operation as convenience method or not. + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @convenientAPI(false) + * op test: void; + * ``` + */ +export type ConvenientAPIDecorator = ( + context: DecoratorContext, + target: Operation, + value?: boolean, + scope?: string +) => void; + +/** + * Whether you want to generate an operation as a protocol operation. + * + * @param value Whether to generate the operation as protocol or not. + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @protocolAPI(false) + * op test: void; + * ``` + */ +export type ProtocolAPIDecorator = ( + context: DecoratorContext, + target: Operation, + value?: boolean, + scope?: string +) => void; + +/** + * Create a ClientGenerator.Core client out of a namespace or interface + * + * @param value Optional configuration for the service. + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example Basic client setting + * ```typespec + * @client + * namespace MyService {} + * ``` + * @example Setting with other service + * ```typespec + * namespace MyService {} + * + * @client({service: MyService}) + * interface MyInterface {} + * ``` + * @example Changing client name if you don't want Client + * ```typespec + * @client({client: MySpecialClient}) + * interface MyInterface {} + * ``` + * @example + * + * + */ +export type ClientDecorator = ( + context: DecoratorContext, + target: Namespace | Interface, + value?: Model, + scope?: string +) => void; + +/** + * Create a ClientGenerator.Core operation group out of a namespace or interface + * + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @operationGroup + * interface MyInterface{} + * ``` + */ +export type OperationGroupDecorator = ( + context: DecoratorContext, + target: Namespace | Interface, + scope?: string +) => void; + +/** + * DEPRECATED: Use `@usage` and `@access` decorator instead. + * + * Whether to exclude a model from generation for specific languages. By default we generate + * all models that are included in operations. + * + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @exclude("python") + * model ModelToExclude { + * prop: string; + * } + * ``` + */ +export type ExcludeDecorator = (context: DecoratorContext, target: Model, scope?: string) => void; + +/** + * DEPRECATED: Use `@usage` and `@access` decorator instead. + * + * Whether to include a model in generation for specific languages. By default we generate + * all models that are included in operations. + * + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @include("python") + * model ModelToInclude { + * prop: string; + * } + * ``` + */ +export type IncludeDecorator = (context: DecoratorContext, target: Model, scope?: string) => void; + +/** + * DEPRECATED: Use `@encode` decorator in `@typespec/compiler` instead. + * + * Can be used to explain the client type that the current TYPESPEC + * type should map to. + * + * @param value The client format to apply. + * @example + * ```typespec + * model MyModel { + * @clientFormat("unixtime") + * created_at?: int64 + * } + * ``` + */ +export type ClientFormatDecorator = ( + context: DecoratorContext, + target: ModelProperty, + value: "unixtime" | "iso8601" | "rfc1123" | "seconds" +) => void; + +/** + * DEPRECATED: Use `@access` decorator instead. + * + * Whether to mark an operation as internal for specific languages, + * meaning it should not be exposed to end SDK users + * + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * @internal("python") + * op test: void; + * ``` + */ +export type InternalDecorator = ( + context: DecoratorContext, + target: Operation, + scope?: string +) => void; + +/** + * Expand usage for models/enums. + * A model/enum's default usage info is always calculated by the operations that use it. + * You could use this decorator to expand the default usage info. + * For example, with operation definition `op test(): OutputModel`, + * the model `OutputModel` has default usage `Usage.output`. + * After adding decorator `@@usage(OutputModel, Usage.input)`, + * the final usage result for `OutputModel` is `Usage.input | Usage.output`. + * The calculation of default usage info for models will be propagated to models' properties, + * parent models, discriminated sub models. + * But the expanded usage from `@usage` decorator will not be propagated. + * If you want to do any customization for the usage of a model, + * you need to take care of all related models/enums. + * + * @param value The usage info you want to set for this model. + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example Expand usage for model + * ```typespec + * op test(): OutputModel; + * + * // usage result for `OutputModel` is `Usage.input | Usage.output` + * @usage(Usage.input) + * model OutputModel { + * prop: string + * } + * ``` + * @example Propagation of usage + * ```typespec + * // Usage.output + * @discriminator("kind") + * model Fish { + * age: int32; + * } + * + * // Usage.input | Usage.output + * @discriminator("sharktype") + * @usage(Usage.input) + * model Shark extends Fish { + * kind: "shark"; + * origin: Origin; + * } + * + * // Usage.output + * model Salmon extends Fish { + * kind: "salmon"; + * } + * + * // Usage.output + * model SawShark extends Shark { + * sharktype: "saw"; + * } + * + * // Usage.output + * model Origin { + * country: string; + * city: string; + * manufacture: string; + * } + * + * @get + * op getModel(): Fish; + * ``` + */ +export type UsageDecorator = ( + context: DecoratorContext, + target: Model | Enum | Union, + value: EnumMember | Union, + scope?: string +) => void; + +/** + * Set explicit access for operations, models and enums. + * When setting access for models, + * the access info wll not be propagated to models' properties, base models or sub models. + * When setting access for an operation, + * it will influence the access info for models/enums that are used by this operation. + * Models/enums that are used in any operations with `@access(Access.public)` will be implicitly set to access "public" + * Models/enums that are only used in operations with `@access(Access.internal)` will be implicitly set to access "internal". + * This influence will be propagated to models' properties, parent models, discriminated sub models. + * But this influence will be override by `@usage` decorator on models/enums directly. + * If an operation/model/enum has no `@access` decorator and is not influenced by any operation with `@access` decorator, + * the access result is undefined. + * + * @param value The access info you want to set for this model or operation. + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example Set access + * ```typespec + * // Access.internal + * @access(Access.internal) + * model ModelToHide { + * prop: string; + * } + * // Access.internal + * @access(Access.internal) + * op test: void; + * ``` + * @example Access propagation + * ```typespec + * // Access.internal + * @discriminator("kind") + * model Fish { + * age: int32; + * } + * + * // Access.internal + * @discriminator("sharktype") + * model Shark extends Fish { + * kind: "shark"; + * origin: Origin; + * } + * + * // Access.internal + * model Salmon extends Fish { + * kind: "salmon"; + * } + * + * // Access.internal + * model SawShark extends Shark { + * sharktype: "saw"; + * } + * + * // Access.internal + * model Origin { + * country: string; + * city: string; + * manufacture: string; + * } + * + * // Access.internal + * @get + * @access(Access.internal) + * op getModel(): Fish; + * ``` + * @example Access influence from operation + * ```typespec + * // Access.internal + * model Test1 { + * } + * + * // Access.internal + * @access(Access.internal) + * @route("/func1") + * op func1( + * @body body: Test1 + * ): void; + * + * // undefined + * model Test2 { + * } + * + * // undefined + * @route("/func2") + * op func2( + * @body body: Test2 + * ): void; + * + * // Access.public + * model Test3 { + * } + * + * // Access.public + * @access(Access.public) + * @route("/func3") + * op func3( + * @body body: Test3 + * ): void; + * + * // undefined + * model Test4 { + * } + * + * // Access.internal + * @access(Access.internal) + * @route("/func4") + * op func4( + * @body body: Test4 + * ): void; + * + * // undefined + * @route("/func5") + * op func5( + * @body body: Test4 + * ): void; + * + * // Access.public + * model Test5 { + * } + * + * // Access.internal + * @access(Access.internal) + * @route("/func6") + * op func6( + * @body body: Test5 + * ): void; + * + * // undefined + * @route("/func7") + * op func7( + * @body body: Test5 + * ): void; + * + * // Access.public + * @access(Access.public) + * @route("/func8") + * op func8( + * @body body: Test5 + * ): void; + * ``` + */ +export type AccessDecorator = ( + context: DecoratorContext, + target: Model | Operation | Enum | Union, + value: EnumMember, + scope?: string +) => void; + +/** + * Set whether a model property should be flattened or not. + * + * @param scope The language scope you want this decorator to apply to. If not specified, will apply to all language emitters + * @example + * ```typespec + * model Foo { + * @flattenProperty + * prop: Bar; + * } + * model Bar { + * } + * ``` + */ +export type FlattenPropertyDecorator = ( + context: DecoratorContext, + target: ModelProperty, + scope?: string +) => void; diff --git a/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts new file mode 100644 index 0000000000..87f2dbfe3e --- /dev/null +++ b/packages/typespec-client-generator-core/generated-defs/Azure.ClientGenerator.Core.ts-test.ts @@ -0,0 +1,60 @@ +/** An error here would mean that the decorator is not exported or doesn't have the right name. */ +import { + $access, + $client, + $clientFormat, + $clientName, + $convenientAPI, + $exclude, + $flattenProperty, + $include, + $internal, + $operationGroup, + $protocolAPI, + $usage, +} from "@azure-tools/typespec-client-generator-core"; +import type { + AccessDecorator, + ClientDecorator, + ClientFormatDecorator, + ClientNameDecorator, + ConvenientAPIDecorator, + ExcludeDecorator, + FlattenPropertyDecorator, + IncludeDecorator, + InternalDecorator, + OperationGroupDecorator, + ProtocolAPIDecorator, + UsageDecorator, +} from "./Azure.ClientGenerator.Core.js"; + +type Decorators = { + $clientName: ClientNameDecorator; + $convenientAPI: ConvenientAPIDecorator; + $protocolAPI: ProtocolAPIDecorator; + $client: ClientDecorator; + $operationGroup: OperationGroupDecorator; + $exclude: ExcludeDecorator; + $include: IncludeDecorator; + $clientFormat: ClientFormatDecorator; + $internal: InternalDecorator; + $usage: UsageDecorator; + $access: AccessDecorator; + $flattenProperty: FlattenPropertyDecorator; +}; + +/** An error here would mean that the exported decorator is not using the same signature. Make sure to have export const $decName: DecNameDecorator = (...) => ... */ +const _: Decorators = { + $clientName, + $convenientAPI, + $protocolAPI, + $client, + $operationGroup, + $exclude, + $include, + $clientFormat, + $internal, + $usage, + $access, + $flattenProperty, +}; diff --git a/packages/typespec-client-generator-core/lib/decorators.tsp b/packages/typespec-client-generator-core/lib/decorators.tsp index b258f72761..324590da89 100644 --- a/packages/typespec-client-generator-core/lib/decorators.tsp +++ b/packages/typespec-client-generator-core/lib/decorators.tsp @@ -77,7 +77,7 @@ extern dec protocolAPI(target: Operation, value?: valueof boolean, scope?: value * * @example */ -extern dec client(target: Namespace | Interface, value?: {}, scope?: valueof string); +extern dec client(target: Namespace | Interface, value?: Model, scope?: valueof string); /** * Create a ClientGenerator.Core operation group out of a namespace or interface diff --git a/packages/typespec-client-generator-core/package.json b/packages/typespec-client-generator-core/package.json index b67598c337..b8c780c918 100644 --- a/packages/typespec-client-generator-core/package.json +++ b/packages/typespec-client-generator-core/package.json @@ -36,8 +36,9 @@ }, "scripts": { "clean": "rimraf ./dist ./temp", - "build": "tsc -p . && npm run lint-typespec-library", + "build": "npm run gen-extern-signature && tsc -p . && npm run lint-typespec-library", "watch": "tsc -p . --watch", + "gen-extern-signature": "tspd --enable-experimental gen-extern-signature .", "lint-typespec-library": "tsp compile . --warn-as-error --import @typespec/library-linter --no-emit", "test": "vitest run", "test:watch": "vitest -w", diff --git a/packages/typespec-client-generator-core/src/decorators.ts b/packages/typespec-client-generator-core/src/decorators.ts index 4735775550..2a7d8ad373 100644 --- a/packages/typespec-client-generator-core/src/decorators.ts +++ b/packages/typespec-client-generator-core/src/decorators.ts @@ -29,6 +29,20 @@ import { } from "@typespec/compiler"; import { isHeader } from "@typespec/http"; import { buildVersionProjections, getVersions } from "@typespec/versioning"; +import { + AccessDecorator, + ClientDecorator, + ClientFormatDecorator, + ClientNameDecorator, + ConvenientAPIDecorator, + ExcludeDecorator, + FlattenPropertyDecorator, + IncludeDecorator, + InternalDecorator, + OperationGroupDecorator, + ProtocolAPIDecorator, + UsageDecorator, +} from "../generated-defs/Azure.ClientGenerator.Core.js"; import { defaultDecoratorsAllowList } from "./configs.js"; import { AccessFlags, @@ -123,12 +137,12 @@ function isArm(service: Namespace): boolean { ); } -export function $client( +export const $client: ClientDecorator = ( context: DecoratorContext, target: Namespace | Interface, options?: Model, scope?: LanguageScopes -) { +) => { if ((context.decoratorTarget as Node).kind === SyntaxKind.AugmentDecoratorStatement) { reportDiagnostic(context.program, { code: "wrong-client-decorator", @@ -168,7 +182,7 @@ export function $client( crossLanguageDefinitionId: `${getNamespaceFullName(service)}.${name}`, }; setScopedDecoratorData(context, $client, clientKey, target, client, scope); -} +}; function findClientService( program: Program, @@ -330,11 +344,11 @@ export function listClients(context: TCGCContext): SdkClient[] { const operationGroupKey = createStateSymbol("operationGroup"); -export function $operationGroup( +export const $operationGroup: OperationGroupDecorator = ( context: DecoratorContext, target: Namespace | Interface, scope?: LanguageScopes -) { +) => { if ((context.decoratorTarget as Node).kind === SyntaxKind.AugmentDecoratorStatement) { reportDiagnostic(context.program, { code: "wrong-client-decorator", @@ -363,7 +377,7 @@ export function $operationGroup( }, scope ); -} +}; /** * Check a namespace or interface is an operation group. @@ -645,25 +659,25 @@ export function createSdkContext< const protocolAPIKey = createStateSymbol("protocolAPI"); -export function $protocolAPI( +export const $protocolAPI: ProtocolAPIDecorator = ( context: DecoratorContext, entity: Operation, - value: boolean, + value?: boolean, scope?: LanguageScopes -) { +) => { setScopedDecoratorData(context, $protocolAPI, protocolAPIKey, entity, value, scope); -} +}; const convenientAPIKey = createStateSymbol("convenientAPI"); -export function $convenientAPI( +export const $convenientAPI: ConvenientAPIDecorator = ( context: DecoratorContext, entity: Operation, - value: boolean, + value?: boolean, scope?: LanguageScopes -) { +) => { setScopedDecoratorData(context, $convenientAPI, convenientAPIKey, entity, value, scope); -} +}; export function shouldGenerateProtocol(context: TCGCContext, entity: Operation): boolean { const value = getScopedDecoratorData(context, protocolAPIKey, entity); @@ -680,18 +694,26 @@ const excludeKey = createStateSymbol("exclude"); /** * @deprecated Use `usage` and `access` decorator instead. */ -export function $exclude(context: DecoratorContext, entity: Model, scope?: LanguageScopes) { +export const $exclude: ExcludeDecorator = ( + context: DecoratorContext, + entity: Model, + scope?: LanguageScopes +) => { setScopedDecoratorData(context, $exclude, excludeKey, entity, true, scope); // eslint-disable-line deprecation/deprecation -} +}; const includeKey = createStateSymbol("include"); /** * @deprecated Use `usage` and `access` decorator instead. */ -export function $include(context: DecoratorContext, entity: Model, scope?: LanguageScopes) { +export const $include: IncludeDecorator = ( + context: DecoratorContext, + entity: Model, + scope?: LanguageScopes +) => { modelTransitiveSet(context, $include, includeKey, entity, true, scope); // eslint-disable-line deprecation/deprecation -} +}; /** * @deprecated This function is unused and will be removed in a future release. @@ -745,12 +767,12 @@ export type ClientFormat = "unixtime" | "iso8601" | "rfc1123" | "seconds"; /** * @deprecated Use `encode` decorator in `@typespec/core` instead. */ -export function $clientFormat( +export const $clientFormat: ClientFormatDecorator = ( context: DecoratorContext, target: ModelProperty, format: ClientFormat, scope?: LanguageScopes -) { +) => { const expectedTargetTypes = allowedClientFormatToTargetTypeMap[format]; if ( context.program.checker.isStdType(target.type) && @@ -764,7 +786,7 @@ export function $clientFormat( target: context.decoratorTarget, }); } -} +}; /** * Gets additional information on how to serialize / deserialize TYPESPEC standard types depending @@ -802,10 +824,16 @@ const internalKey = createStateSymbol("internal"); * @param target Operation to mark as internal * @param scope Names of the projection (e.g. "python", "csharp", "java", "javascript") * @deprecated Use `access` decorator instead. + * + * @internal */ -export function $internal(context: DecoratorContext, target: Operation, scope?: LanguageScopes) { +export const $internal: InternalDecorator = ( + context: DecoratorContext, + target: Operation, + scope?: LanguageScopes +) => { setScopedDecoratorData(context, $internal, internalKey, target, true, scope); // eslint-disable-line deprecation/deprecation -} +}; /** * Whether a model / operation is internal or not. If it's internal, emitters @@ -840,12 +868,12 @@ export function isInternal( const usageKey = createStateSymbol("usage"); -export function $usage( +export const $usage: UsageDecorator = ( context: DecoratorContext, entity: Model | Enum | Union, value: EnumMember | Union, scope?: LanguageScopes -) { +) => { const isValidValue = (value: number): boolean => value === 2 || value === 4; if (value.kind === "EnumMember") { @@ -876,7 +904,7 @@ export function $usage( format: {}, target: entity, }); -} +}; export function getUsageOverride( context: TCGCContext, @@ -893,12 +921,12 @@ export function getUsage(context: TCGCContext, entity: Model | Enum): UsageFlags const accessKey = createStateSymbol("access"); -export function $access( +export const $access: AccessDecorator = ( context: DecoratorContext, entity: Model | Enum | Operation | Union, value: EnumMember, scope?: LanguageScopes -) { +) => { if (typeof value.value !== "string" || (value.value !== "public" && value.value !== "internal")) { reportDiagnostic(context.program, { code: "access", @@ -907,7 +935,7 @@ export function $access( }); } setScopedDecoratorData(context, $access, accessKey, entity, value.value, scope); -} +}; export function getAccessOverride( context: TCGCContext, @@ -948,13 +976,13 @@ const flattenPropertyKey = createStateSymbol("flattenPropertyKey"); * @param scope Names of the projection (e.g. "python", "csharp", "java", "javascript") * @deprecated This decorator is not recommended to use. */ -export function $flattenProperty( +export const $flattenProperty: FlattenPropertyDecorator = ( context: DecoratorContext, target: ModelProperty, scope?: LanguageScopes -) { +) => { setScopedDecoratorData(context, $flattenProperty, flattenPropertyKey, target, true, scope); // eslint-disable-line deprecation/deprecation -} +}; /** * Whether a model property should be flattened or not. @@ -967,12 +995,12 @@ export function shouldFlattenProperty(context: TCGCContext, target: ModelPropert return getScopedDecoratorData(context, flattenPropertyKey, target) ?? false; } -export function $clientName( +export const $clientName: ClientNameDecorator = ( context: DecoratorContext, entity: Type, value: string, scope?: LanguageScopes -) { +) => { // workaround for current lack of functionality in compiler // https://github.com/microsoft/typespec/issues/2717 if (entity.kind === "Model" || entity.kind === "Operation") { @@ -1001,7 +1029,7 @@ export function $clientName( }); } setScopedDecoratorData(context, $clientName, clientNameKey, entity, value, scope); -} +}; export function getClientNameOverride( context: TCGCContext, diff --git a/packages/typespec-client-generator-core/tsconfig.json b/packages/typespec-client-generator-core/tsconfig.json index b58c2a0526..39afc5d83a 100644 --- a/packages/typespec-client-generator-core/tsconfig.json +++ b/packages/typespec-client-generator-core/tsconfig.json @@ -12,5 +12,5 @@ "rootDir": ".", "tsBuildInfoFile": "temp/tsconfig.tsbuildinfo" }, - "include": ["src/**/*.ts", "test/**/*.ts", "e2e/**/*.ts"] + "include": ["src/**/*.ts", "generated-defs/**/*.ts", "test/**/*.ts", "e2e/**/*.ts"] }