@azure-tools/typespec-ts 0.46.1 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -3
- package/LICENSE +21 -0
- package/dist/src/framework/hooks/sdkTypes.d.ts +7 -1
- package/dist/src/framework/hooks/sdkTypes.d.ts.map +1 -1
- package/dist/src/framework/hooks/sdkTypes.js +59 -1
- package/dist/src/framework/hooks/sdkTypes.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +20 -1
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +18 -1
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
- package/dist/src/modular/buildClassicalClient.js +137 -23
- package/dist/src/modular/buildClassicalClient.js.map +1 -1
- package/dist/src/modular/buildRootIndex.d.ts +2 -1
- package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
- package/dist/src/modular/buildRootIndex.js +23 -0
- package/dist/src/modular/buildRootIndex.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +57 -14
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/emitSamples.d.ts.map +1 -1
- package/dist/src/modular/emitSamples.js +53 -26
- package/dist/src/modular/emitSamples.js.map +1 -1
- package/dist/src/modular/helpers/classicalOperationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/classicalOperationHelpers.js +73 -23
- package/dist/src/modular/helpers/classicalOperationHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +7 -4
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +115 -23
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.d.ts +3 -1
- package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.js +7 -3
- package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.d.ts +4 -2
- package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.js +60 -17
- package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/buildSerializerFunction.d.ts +4 -2
- package/dist/src/modular/serialization/buildSerializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildSerializerFunction.js +61 -19
- package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/serializeUtils.d.ts +11 -0
- package/dist/src/modular/serialization/serializeUtils.d.ts.map +1 -1
- package/dist/src/modular/serialization/serializeUtils.js +15 -0
- package/dist/src/modular/serialization/serializeUtils.js.map +1 -1
- package/dist/src/modular/static-helpers-metadata.d.ts +17 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
- package/dist/src/modular/static-helpers-metadata.js +17 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +2 -0
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/namespaceUtils.d.ts.map +1 -1
- package/dist/src/utils/namespaceUtils.js +19 -4
- package/dist/src/utils/namespaceUtils.js.map +1 -1
- package/dist/src/utils/operationUtil.d.ts +1 -0
- package/dist/src/utils/operationUtil.d.ts.map +1 -1
- package/dist/src/utils/operationUtil.js +26 -0
- package/dist/src/utils/operationUtil.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -11
- package/src/framework/hooks/sdkTypes.ts +102 -2
- package/src/index.ts +2 -0
- package/src/lib.ts +20 -1
- package/src/modular/buildClassicalClient.ts +182 -25
- package/src/modular/buildRootIndex.ts +53 -1
- package/src/modular/emitModels.ts +72 -19
- package/src/modular/emitSamples.ts +86 -21
- package/src/modular/helpers/classicalOperationHelpers.ts +112 -30
- package/src/modular/helpers/operationHelpers.ts +163 -43
- package/src/modular/helpers/typeHelpers.ts +19 -3
- package/src/modular/serialization/buildDeserializerFunction.ts +87 -35
- package/src/modular/serialization/buildSerializerFunction.ts +86 -36
- package/src/modular/serialization/serializeUtils.ts +37 -0
- package/src/modular/static-helpers-metadata.ts +18 -0
- package/src/transform/transfromRLCOptions.ts +2 -0
- package/src/utils/namespaceUtils.ts +19 -3
- package/src/utils/operationUtil.ts +35 -0
- package/static/static-helpers/serialization/check-prop-undefined.ts +17 -0
- package/static/static-helpers/simplePollerHelpers.ts +125 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0",
|
|
4
4
|
"description": "An experimental TypeSpec emitter for TypeScript RLC",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@azure-rest/core-client": "^2.3.1",
|
|
21
|
-
"@typespec/http-specs": "0.1.0-alpha.29-dev.
|
|
22
|
-
"@typespec/spector": "0.1.0-alpha.21-dev.
|
|
23
|
-
"@typespec/spec-api": "0.1.0-alpha.11-dev.
|
|
21
|
+
"@typespec/http-specs": "0.1.0-alpha.29-dev.5",
|
|
22
|
+
"@typespec/spector": "0.1.0-alpha.21-dev.3",
|
|
23
|
+
"@typespec/spec-api": "0.1.0-alpha.11-dev.1",
|
|
24
24
|
"@typespec/tspd": "0.73.1",
|
|
25
|
-
"@azure-tools/azure-http-specs": "0.1.0-alpha.33-dev.
|
|
25
|
+
"@azure-tools/azure-http-specs": "0.1.0-alpha.33-dev.4",
|
|
26
26
|
"@azure-tools/typespec-autorest": "^0.62.0",
|
|
27
27
|
"@azure-tools/typespec-azure-core": "^0.62.0",
|
|
28
|
-
"@azure-tools/typespec-azure-resource-manager": "^0.62.
|
|
28
|
+
"@azure-tools/typespec-azure-resource-manager": "^0.62.1",
|
|
29
29
|
"@azure-tools/typespec-client-generator-core": "^0.62.0",
|
|
30
30
|
"@azure/abort-controller": "^2.1.2",
|
|
31
31
|
"@azure/core-auth": "^1.6.0",
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"@types/fs-extra": "^9.0.13",
|
|
39
39
|
"@types/lodash": "^4.17.4",
|
|
40
40
|
"@types/mocha": "^10.0.6",
|
|
41
|
-
"@types/node": "^18.0.0",
|
|
42
41
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
|
43
42
|
"@typescript-eslint/parser": "^8.28.0",
|
|
44
43
|
"@typespec/compiler": "^1.6.0",
|
|
@@ -51,14 +50,11 @@
|
|
|
51
50
|
"chalk": "^4.0.0",
|
|
52
51
|
"cross-env": "^7.0.3",
|
|
53
52
|
"eslint-plugin-require-extensions": "0.1.3",
|
|
54
|
-
"eslint": "^8.9.0",
|
|
55
53
|
"mkdirp": "^3.0.1",
|
|
56
54
|
"mocha": "^10.4.0",
|
|
57
55
|
"npm-run-all": "~4.1.5",
|
|
58
56
|
"prettier": "^3.3.3",
|
|
59
|
-
"rimraf": "^5.0.0",
|
|
60
57
|
"ts-node": "~10.9.1",
|
|
61
|
-
"typescript": "~5.8.2",
|
|
62
58
|
"vitest": "~1.6.0",
|
|
63
59
|
"@vitest/coverage-v8": "~1.6.0",
|
|
64
60
|
"@vitest/coverage-istanbul": "~1.6.0",
|
|
@@ -77,7 +73,7 @@
|
|
|
77
73
|
"@typespec/xml": "^0.76.0"
|
|
78
74
|
},
|
|
79
75
|
"dependencies": {
|
|
80
|
-
"@azure-tools/rlc-common": "^0.
|
|
76
|
+
"@azure-tools/rlc-common": "^0.47.0",
|
|
81
77
|
"fs-extra": "^11.1.0",
|
|
82
78
|
"lodash": "^4.17.21",
|
|
83
79
|
"prettier": "^3.3.3",
|
|
@@ -2,6 +2,8 @@ import { Operation, Type, getNamespaceFullName } from "@typespec/compiler";
|
|
|
2
2
|
import {
|
|
3
3
|
SdkClientType,
|
|
4
4
|
SdkHttpOperation,
|
|
5
|
+
SdkModelPropertyType,
|
|
6
|
+
SdkModelType,
|
|
5
7
|
SdkServiceMethod,
|
|
6
8
|
SdkType,
|
|
7
9
|
getClientType
|
|
@@ -10,12 +12,27 @@ import { provideContext, useContext } from "../../contextManager.js";
|
|
|
10
12
|
|
|
11
13
|
import { visitPackageTypes } from "../../modular/emitModels.js";
|
|
12
14
|
import { SdkContext } from "../../utils/interfaces.js";
|
|
15
|
+
import {
|
|
16
|
+
getAllAncestors,
|
|
17
|
+
getAllProperties
|
|
18
|
+
} from "../../modular/helpers/operationHelpers.js";
|
|
19
|
+
import { normalizeModelPropertyName } from "../../modular/type-expressions/get-type-expression.js";
|
|
20
|
+
import { reportDiagnostic } from "../../lib.js";
|
|
21
|
+
import { NameType, normalizeName } from "@azure-tools/rlc-common";
|
|
13
22
|
|
|
14
23
|
export const emitQueue: Set<SdkType> = new Set<SdkType>();
|
|
24
|
+
export const flattenPropertyModelMap: Map<SdkModelPropertyType, SdkModelType> =
|
|
25
|
+
new Map<SdkModelPropertyType, SdkModelType>();
|
|
15
26
|
|
|
16
27
|
export interface SdkTypeContext {
|
|
17
28
|
operations: Map<Type, SdkServiceMethod<SdkHttpOperation>>;
|
|
18
29
|
types: Map<Type, SdkType>;
|
|
30
|
+
flattenProperties: Map<SdkModelPropertyType, SdkFlattenPropertyContext>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SdkFlattenPropertyContext {
|
|
34
|
+
baseModel: SdkModelType;
|
|
35
|
+
conflictMap?: Map<SdkModelPropertyType, string>;
|
|
19
36
|
}
|
|
20
37
|
|
|
21
38
|
export function useSdkTypes() {
|
|
@@ -56,11 +73,20 @@ export function useSdkTypes() {
|
|
|
56
73
|
|
|
57
74
|
export function provideSdkTypes(context: SdkContext) {
|
|
58
75
|
const { sdkPackage } = context;
|
|
59
|
-
const sdkTypesContext = {
|
|
76
|
+
const sdkTypesContext: SdkTypeContext = {
|
|
60
77
|
operations: new Map<Type, SdkServiceMethod<SdkHttpOperation>>(),
|
|
61
|
-
types: new Map<Type, SdkType>()
|
|
78
|
+
types: new Map<Type, SdkType>(),
|
|
79
|
+
flattenProperties: new Map<
|
|
80
|
+
SdkModelPropertyType,
|
|
81
|
+
SdkFlattenPropertyContext
|
|
82
|
+
>()
|
|
62
83
|
};
|
|
63
84
|
visitPackageTypes(context);
|
|
85
|
+
enrichFlattenProperties(
|
|
86
|
+
context,
|
|
87
|
+
sdkTypesContext.flattenProperties,
|
|
88
|
+
flattenPropertyModelMap
|
|
89
|
+
);
|
|
64
90
|
for (const sdkModel of emitQueue) {
|
|
65
91
|
switch (sdkModel.kind) {
|
|
66
92
|
case "model":
|
|
@@ -126,6 +152,80 @@ export function provideSdkTypes(context: SdkContext) {
|
|
|
126
152
|
provideContext("sdkTypes", sdkTypesContext);
|
|
127
153
|
}
|
|
128
154
|
|
|
155
|
+
// Enrich flatten properties with their base models and conflict maps
|
|
156
|
+
function enrichFlattenProperties(
|
|
157
|
+
context: SdkContext,
|
|
158
|
+
propertyContextMap: Map<SdkModelPropertyType, SdkFlattenPropertyContext>,
|
|
159
|
+
propertyModelMap: Map<SdkModelPropertyType, SdkModelType>
|
|
160
|
+
) {
|
|
161
|
+
// Build a map of base model to its existing properties excluding flatten properties
|
|
162
|
+
// To check for conflicts later
|
|
163
|
+
const baseModelProperties = new Map<SdkModelType, Set<string>>();
|
|
164
|
+
propertyModelMap.forEach((baseModel, _) => {
|
|
165
|
+
if (!baseModelProperties.has(baseModel)) {
|
|
166
|
+
const propertiesExcludedFlatten = getAllProperties(
|
|
167
|
+
context,
|
|
168
|
+
baseModel,
|
|
169
|
+
getAllAncestors(baseModel)
|
|
170
|
+
)
|
|
171
|
+
.filter((p) => p.flatten === false || p.flatten === undefined)
|
|
172
|
+
.map((p) => normalizeModelPropertyName(context, p));
|
|
173
|
+
baseModelProperties.set(
|
|
174
|
+
baseModel,
|
|
175
|
+
new Set<string>(propertiesExcludedFlatten)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
for (const [flattenProperty, baseModel] of propertyModelMap) {
|
|
180
|
+
const flattenContext: SdkFlattenPropertyContext = {
|
|
181
|
+
baseModel: baseModel
|
|
182
|
+
};
|
|
183
|
+
propertyContextMap.set(flattenProperty, flattenContext);
|
|
184
|
+
const existingProperties = baseModelProperties.get(baseModel)!;
|
|
185
|
+
const conflictMap = new Map<SdkModelPropertyType, string>();
|
|
186
|
+
const flattenModel = flattenProperty.type;
|
|
187
|
+
|
|
188
|
+
if (flattenModel.kind !== "model") {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (baseModelProperties.has(flattenModel)) {
|
|
192
|
+
// If the flatten model is also a base model of other flatten properties, which means it has multiple consecutive flatten operations
|
|
193
|
+
// Since we cannot handle the flatten transition, report warning and skip it for now
|
|
194
|
+
reportDiagnostic(context.program, {
|
|
195
|
+
code: "unsupported-flatten-transition",
|
|
196
|
+
format: {
|
|
197
|
+
propertyName: flattenProperty.name,
|
|
198
|
+
modelName: baseModel.name
|
|
199
|
+
},
|
|
200
|
+
target: flattenProperty.__raw!
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
const allFlattenProperties = getAllProperties(
|
|
204
|
+
context,
|
|
205
|
+
flattenModel,
|
|
206
|
+
getAllAncestors(flattenModel)
|
|
207
|
+
);
|
|
208
|
+
for (const flattenChildProperty of allFlattenProperties) {
|
|
209
|
+
let childPropertyName = normalizeModelPropertyName(
|
|
210
|
+
context,
|
|
211
|
+
flattenChildProperty
|
|
212
|
+
);
|
|
213
|
+
if (existingProperties.has(childPropertyName)) {
|
|
214
|
+
childPropertyName = normalizeName(
|
|
215
|
+
`${childPropertyName}_${flattenProperty.name}_${childPropertyName}`,
|
|
216
|
+
NameType.Property
|
|
217
|
+
);
|
|
218
|
+
conflictMap.set(flattenChildProperty, childPropertyName);
|
|
219
|
+
}
|
|
220
|
+
existingProperties.add(childPropertyName);
|
|
221
|
+
}
|
|
222
|
+
if (conflictMap.size === 0) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
flattenContext.conflictMap = conflictMap;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
129
229
|
export function getAllOperationsFromClient(
|
|
130
230
|
client: SdkClientType<SdkHttpOperation>
|
|
131
231
|
) {
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
PagingHelpers,
|
|
18
18
|
PollingHelpers,
|
|
19
19
|
SerializationHelpers,
|
|
20
|
+
SimplePollerHelpers,
|
|
20
21
|
UrlTemplateHelpers
|
|
21
22
|
} from "./modular/static-helpers-metadata.js";
|
|
22
23
|
import {
|
|
@@ -131,6 +132,7 @@ export async function $onEmit(context: EmitContext) {
|
|
|
131
132
|
...SerializationHelpers,
|
|
132
133
|
...PagingHelpers,
|
|
133
134
|
...PollingHelpers,
|
|
135
|
+
...SimplePollerHelpers,
|
|
134
136
|
...UrlTemplateHelpers,
|
|
135
137
|
...MultipartHelpers,
|
|
136
138
|
...CloudSettingHelpers
|
package/src/lib.ts
CHANGED
|
@@ -60,6 +60,7 @@ export interface EmitterOptions {
|
|
|
60
60
|
"enable-model-namespace"?: boolean;
|
|
61
61
|
"hierarchy-client"?: boolean;
|
|
62
62
|
"compatibility-mode"?: boolean;
|
|
63
|
+
"compatibility-lro"?: boolean;
|
|
63
64
|
"experimental-extensible-enums"?: boolean;
|
|
64
65
|
"clear-output-folder"?: boolean;
|
|
65
66
|
"ignore-property-name-normalize"?: boolean;
|
|
@@ -281,6 +282,12 @@ export const RLCOptionsSchema: JSONSchemaType<EmitterOptions> = {
|
|
|
281
282
|
description:
|
|
282
283
|
"Whether to affect the generation of the additional property feature for the Modular client. Defaults to `false`."
|
|
283
284
|
},
|
|
285
|
+
"compatibility-lro": {
|
|
286
|
+
type: "boolean",
|
|
287
|
+
nullable: true,
|
|
288
|
+
description:
|
|
289
|
+
"[deprecated] Whether to generate the legacy LRO interface. When `true`, we will generate legacy beginXXX and beginXXXAndWait LRO methods."
|
|
290
|
+
},
|
|
284
291
|
"experimental-extensible-enums": {
|
|
285
292
|
type: "boolean",
|
|
286
293
|
nullable: true,
|
|
@@ -542,6 +549,12 @@ const libDef = {
|
|
|
542
549
|
default: paramMessage`The parameter name ${"parameterName"} has conflicts with others and please use @clientName to rename it.`
|
|
543
550
|
}
|
|
544
551
|
},
|
|
552
|
+
"unsupported-flatten-transition": {
|
|
553
|
+
severity: "warning",
|
|
554
|
+
messages: {
|
|
555
|
+
default: paramMessage`The property "${"propertyName"}" in "${"modelName"}" has multiple consecutive flatten operations. Flatten transitions are not supported so consecutive transitions will be ignored.`
|
|
556
|
+
}
|
|
557
|
+
},
|
|
545
558
|
"unsupported-parameter-type": {
|
|
546
559
|
severity: "error",
|
|
547
560
|
messages: {
|
|
@@ -589,6 +602,12 @@ const libDef = {
|
|
|
589
602
|
messages: {
|
|
590
603
|
default: paramMessage`Error traversing directory ${"directory"}: ${"error"}`
|
|
591
604
|
}
|
|
605
|
+
},
|
|
606
|
+
"detected-model-name-conflict": {
|
|
607
|
+
severity: "warning",
|
|
608
|
+
messages: {
|
|
609
|
+
default: paramMessage`Model name conflict detected: "${"modelName"}" exists in multiple namespaces: ${"namespaces"}. Please use @clientName to rename them.`
|
|
610
|
+
}
|
|
592
611
|
}
|
|
593
612
|
},
|
|
594
613
|
emitter: {
|
|
@@ -604,7 +623,7 @@ export const prettierTypeScriptOptions: Options = {
|
|
|
604
623
|
arrowParens: "always",
|
|
605
624
|
bracketSpacing: true,
|
|
606
625
|
endOfLine: "lf",
|
|
607
|
-
printWidth:
|
|
626
|
+
printWidth: 100,
|
|
608
627
|
semi: true,
|
|
609
628
|
singleQuote: false,
|
|
610
629
|
tabWidth: 2
|
|
@@ -31,9 +31,14 @@ import {
|
|
|
31
31
|
SdkServiceMethod,
|
|
32
32
|
SdkServiceOperation
|
|
33
33
|
} from "@azure-tools/typespec-client-generator-core";
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
getMethodHierarchiesMap,
|
|
36
|
+
isTenantLevelOperation
|
|
37
|
+
} from "../utils/operationUtil.js";
|
|
35
38
|
import { useContext } from "../contextManager.js";
|
|
36
39
|
import { refkey } from "../framework/refkey.js";
|
|
40
|
+
import { SimplePollerHelpers } from "./static-helpers-metadata.js";
|
|
41
|
+
import { AzurePollingDependencies } from "./external-dependencies.js";
|
|
37
42
|
|
|
38
43
|
export function buildClassicalClient(
|
|
39
44
|
dpgContext: SdkContext,
|
|
@@ -117,11 +122,28 @@ export function buildClassicalClient(
|
|
|
117
122
|
});
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
//
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
// Check if constructor overloads for subscriptionId is needed
|
|
126
|
+
const hasSubscriptionIdParam = classicalParams.some(
|
|
127
|
+
(param) => param.name.toLowerCase() === "subscriptionid"
|
|
128
|
+
);
|
|
129
|
+
const shouldSubscriptionIdOptional =
|
|
130
|
+
dpgContext.arm &&
|
|
131
|
+
hasSubscriptionIdParam &&
|
|
132
|
+
hasTenantLevelOperations(client, dpgContext);
|
|
133
|
+
|
|
134
|
+
let constructor;
|
|
135
|
+
if (shouldSubscriptionIdOptional) {
|
|
136
|
+
constructor = generateConstructorWithOverloads(
|
|
137
|
+
clientClass,
|
|
138
|
+
classicalParams,
|
|
139
|
+
client
|
|
140
|
+
);
|
|
141
|
+
} else {
|
|
142
|
+
constructor = clientClass.addConstructor({
|
|
143
|
+
docs: getDocsFromDescription(client.doc),
|
|
144
|
+
parameters: classicalParams
|
|
145
|
+
});
|
|
146
|
+
}
|
|
125
147
|
|
|
126
148
|
const paramNames = (contextParams ?? [])
|
|
127
149
|
.map((p) => p.name)
|
|
@@ -132,6 +154,11 @@ export function buildClassicalClient(
|
|
|
132
154
|
emitterOptions,
|
|
133
155
|
"azsdk-js-client"
|
|
134
156
|
)}}`;
|
|
157
|
+
} else if (
|
|
158
|
+
x.toLowerCase() === "subscriptionid" &&
|
|
159
|
+
shouldSubscriptionIdOptional
|
|
160
|
+
) {
|
|
161
|
+
return `subscriptionId ?? ""`;
|
|
135
162
|
} else {
|
|
136
163
|
return x;
|
|
137
164
|
}
|
|
@@ -204,24 +231,69 @@ function generateMethod(
|
|
|
204
231
|
context: SdkContext,
|
|
205
232
|
clientType: string,
|
|
206
233
|
method: [string[], SdkServiceMethod<SdkServiceOperation>]
|
|
207
|
-
) {
|
|
208
|
-
const
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
234
|
+
): MethodDeclarationStructure[] {
|
|
235
|
+
const res: MethodDeclarationStructure[] = [];
|
|
236
|
+
const declaration = getOperationFunction(context, method, clientType);
|
|
237
|
+
const methodName = declaration.propertyName ?? declaration.name ?? "FIXME";
|
|
238
|
+
const methodParams =
|
|
239
|
+
declaration.parameters?.filter((p) => p.name !== "context") ?? [];
|
|
240
|
+
const declarationRefKey = resolveReference(refkey(method[1], "api"));
|
|
241
|
+
const methodParamStr = [
|
|
242
|
+
"this._client",
|
|
243
|
+
...methodParams.map((p) => p.name)
|
|
244
|
+
].join(", ");
|
|
245
|
+
|
|
246
|
+
res.push({
|
|
247
|
+
docs: declaration.docs,
|
|
248
|
+
name: methodName,
|
|
212
249
|
kind: StructureKind.Method,
|
|
213
|
-
returnType:
|
|
214
|
-
parameters:
|
|
215
|
-
statements: `return ${
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
250
|
+
returnType: declaration.returnType,
|
|
251
|
+
parameters: methodParams,
|
|
252
|
+
statements: `return ${declarationRefKey}(${methodParamStr})`
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// add LRO helper methods if applicable
|
|
256
|
+
if (context.rlcOptions?.compatibilityLro && declaration?.isLro) {
|
|
257
|
+
const operationStateReference = resolveReference(
|
|
258
|
+
AzurePollingDependencies.OperationState
|
|
259
|
+
);
|
|
260
|
+
const simplePollerLikeReference = resolveReference(
|
|
261
|
+
SimplePollerHelpers.SimplePollerLike
|
|
262
|
+
);
|
|
263
|
+
const getSimplePollerReference = resolveReference(
|
|
264
|
+
SimplePollerHelpers.getSimplePoller
|
|
265
|
+
);
|
|
266
|
+
const returnType = declaration?.lroFinalReturnType ?? "void";
|
|
267
|
+
const beginName = normalizeName(`begin_${methodName}`, NameType.Method);
|
|
268
|
+
const beginAndWaitName = normalizeName(
|
|
269
|
+
`${beginName}_andWait`,
|
|
270
|
+
NameType.Method
|
|
271
|
+
);
|
|
272
|
+
// add begin method
|
|
273
|
+
res.push({
|
|
274
|
+
isAsync: true,
|
|
275
|
+
docs: [`@deprecated use ${methodName} instead`],
|
|
276
|
+
name: beginName,
|
|
277
|
+
kind: StructureKind.Method,
|
|
278
|
+
returnType: `Promise<${simplePollerLikeReference}<${operationStateReference}<${returnType}>, ${returnType}>>`,
|
|
279
|
+
parameters: methodParams,
|
|
280
|
+
statements: `const poller = ${declarationRefKey}(${methodParamStr});
|
|
281
|
+
await poller.submitted();
|
|
282
|
+
return ${getSimplePollerReference}(poller);`
|
|
283
|
+
});
|
|
284
|
+
// add begin and wait method
|
|
285
|
+
res.push({
|
|
286
|
+
isAsync: true,
|
|
287
|
+
docs: [`@deprecated use ${methodName} instead`],
|
|
288
|
+
name: beginAndWaitName,
|
|
289
|
+
kind: StructureKind.Method,
|
|
290
|
+
returnType: `Promise<${returnType}>`,
|
|
291
|
+
parameters: methodParams,
|
|
292
|
+
statements: `return await ${declarationRefKey}(${methodParamStr});`
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return res;
|
|
225
297
|
}
|
|
226
298
|
function buildClientOperationGroups(
|
|
227
299
|
clientMap: [string[], SdkClientType<SdkServiceOperation>],
|
|
@@ -240,8 +312,8 @@ function buildClientOperationGroups(
|
|
|
240
312
|
const layer = 0;
|
|
241
313
|
if (prefixKey === "") {
|
|
242
314
|
operations.forEach((op) => {
|
|
243
|
-
const
|
|
244
|
-
clientClass.
|
|
315
|
+
const methods = generateMethod(dpgContext, clientType, [prefixes, op]);
|
|
316
|
+
clientClass.addMethods(methods);
|
|
245
317
|
});
|
|
246
318
|
} else {
|
|
247
319
|
// The `rawGroupName` is used to any places where we need normalized name twice so we need to keep the raw as PascalCase.
|
|
@@ -323,3 +395,88 @@ function addChildClient(
|
|
|
323
395
|
)`
|
|
324
396
|
);
|
|
325
397
|
}
|
|
398
|
+
|
|
399
|
+
function hasTenantLevelOperations(
|
|
400
|
+
client: SdkClientType<SdkServiceOperation>,
|
|
401
|
+
dpgContext: SdkContext
|
|
402
|
+
): boolean {
|
|
403
|
+
const methodMap = getMethodHierarchiesMap(dpgContext, client);
|
|
404
|
+
|
|
405
|
+
for (const [_, operations] of methodMap) {
|
|
406
|
+
for (const op of operations) {
|
|
407
|
+
if (isTenantLevelOperation(op, client)) {
|
|
408
|
+
// Found a tenant-level operation
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function generateConstructorWithOverloads(
|
|
418
|
+
clientClass: ClassDeclaration,
|
|
419
|
+
classicalParams: any[],
|
|
420
|
+
client: SdkClientType<SdkServiceOperation>
|
|
421
|
+
) {
|
|
422
|
+
const filteredParams = classicalParams.filter(
|
|
423
|
+
(p) =>
|
|
424
|
+
p.name.toLowerCase() !== "subscriptionid" &&
|
|
425
|
+
p.name.toLowerCase() !== "options"
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
const clientConstructor = clientClass.addConstructor({
|
|
429
|
+
docs: getDocsFromDescription(client.doc),
|
|
430
|
+
parameters: [
|
|
431
|
+
...filteredParams,
|
|
432
|
+
{
|
|
433
|
+
name: "subscriptionIdOrOptions",
|
|
434
|
+
type: `string | ${getClassicalClientName(client)}OptionalParams`,
|
|
435
|
+
hasQuestionToken: true
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
name: "options",
|
|
439
|
+
type: `${getClassicalClientName(client)}OptionalParams`,
|
|
440
|
+
hasQuestionToken: true
|
|
441
|
+
}
|
|
442
|
+
]
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
clientConstructor.addOverload({
|
|
446
|
+
parameters: [
|
|
447
|
+
...filteredParams,
|
|
448
|
+
{
|
|
449
|
+
name: "options",
|
|
450
|
+
type: `${getClassicalClientName(client)}OptionalParams`,
|
|
451
|
+
hasQuestionToken: true
|
|
452
|
+
}
|
|
453
|
+
]
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
clientConstructor.addOverload({
|
|
457
|
+
parameters: [
|
|
458
|
+
...filteredParams,
|
|
459
|
+
...classicalParams.filter(
|
|
460
|
+
(p) => p.name.toLowerCase() === "subscriptionid"
|
|
461
|
+
),
|
|
462
|
+
{
|
|
463
|
+
name: "options",
|
|
464
|
+
type: `${getClassicalClientName(client)}OptionalParams`,
|
|
465
|
+
hasQuestionToken: true
|
|
466
|
+
}
|
|
467
|
+
]
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
clientConstructor.addStatements([
|
|
471
|
+
`let subscriptionId: string | undefined;`,
|
|
472
|
+
``,
|
|
473
|
+
`if (typeof subscriptionIdOrOptions === "string") {`,
|
|
474
|
+
` subscriptionId = subscriptionIdOrOptions;`,
|
|
475
|
+
`} else if (typeof subscriptionIdOrOptions === "object") {`,
|
|
476
|
+
` options = subscriptionIdOrOptions;`,
|
|
477
|
+
`}`,
|
|
478
|
+
`options = options ?? {};`
|
|
479
|
+
]);
|
|
480
|
+
|
|
481
|
+
return clientConstructor;
|
|
482
|
+
}
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
} from "./static-helpers-metadata.js";
|
|
11
11
|
import {
|
|
12
12
|
SdkClientType,
|
|
13
|
-
SdkContext,
|
|
14
13
|
SdkServiceOperation
|
|
15
14
|
} from "@azure-tools/typespec-client-generator-core";
|
|
16
15
|
import { getModularClientOptions } from "../utils/clientUtils.js";
|
|
@@ -19,6 +18,8 @@ import { join } from "path/posix";
|
|
|
19
18
|
import { useContext } from "../contextManager.js";
|
|
20
19
|
import { reportDiagnostic } from "../lib.js";
|
|
21
20
|
import { NoTarget } from "@typespec/compiler";
|
|
21
|
+
import { isLroOnlyOperation } from "./helpers/operationHelpers.js";
|
|
22
|
+
import { SdkContext } from "../utils/interfaces.js";
|
|
22
23
|
|
|
23
24
|
export function buildRootIndex(
|
|
24
25
|
context: SdkContext,
|
|
@@ -55,6 +56,14 @@ export function buildRootIndex(
|
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
exportClassicalClient(client, rootIndexFile, subfolder ?? "");
|
|
59
|
+
exportSimplePollerLike(
|
|
60
|
+
context,
|
|
61
|
+
clientMap,
|
|
62
|
+
rootIndexFile,
|
|
63
|
+
project,
|
|
64
|
+
srcPath,
|
|
65
|
+
subfolder
|
|
66
|
+
);
|
|
58
67
|
exportRestoreHelpers(
|
|
59
68
|
rootIndexFile,
|
|
60
69
|
project,
|
|
@@ -188,6 +197,41 @@ function addExportsToRootIndexFile(
|
|
|
188
197
|
}
|
|
189
198
|
}
|
|
190
199
|
|
|
200
|
+
function exportSimplePollerLike(
|
|
201
|
+
context: SdkContext,
|
|
202
|
+
clientMap: [string[], SdkClientType<SdkServiceOperation>],
|
|
203
|
+
indexFile: SourceFile,
|
|
204
|
+
project: Project,
|
|
205
|
+
srcPath: string,
|
|
206
|
+
subfolder: string = "",
|
|
207
|
+
isTopLevel: boolean = false
|
|
208
|
+
) {
|
|
209
|
+
const [_, client] = clientMap;
|
|
210
|
+
|
|
211
|
+
const methodMap = getMethodHierarchiesMap(context, client);
|
|
212
|
+
const hasLro = Array.from(methodMap.values()).some((operations) => {
|
|
213
|
+
return operations.some(isLroOnlyOperation);
|
|
214
|
+
});
|
|
215
|
+
if (!hasLro || context.rlcOptions?.compatibilityLro !== true) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const helperFile = project.getSourceFile(
|
|
219
|
+
`${srcPath}/${
|
|
220
|
+
subfolder && subfolder !== "" ? subfolder + "/" : ""
|
|
221
|
+
}static-helpers/simplePollerHelpers.ts`
|
|
222
|
+
);
|
|
223
|
+
if (!helperFile) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const moduleSpecifier = `./${
|
|
227
|
+
isTopLevel && subfolder && subfolder !== "" ? subfolder + "/" : ""
|
|
228
|
+
}static-helpers/simplePollerHelpers.js`;
|
|
229
|
+
indexFile.addExportDeclaration({
|
|
230
|
+
moduleSpecifier,
|
|
231
|
+
namedExports: ["SimplePollerLike"]
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
191
235
|
function exportRestoreHelpers(
|
|
192
236
|
indexFile: SourceFile,
|
|
193
237
|
project: Project,
|
|
@@ -381,6 +425,14 @@ export function buildSubClientIndexFile(
|
|
|
381
425
|
}
|
|
382
426
|
|
|
383
427
|
exportClassicalClient(client, subClientIndexFile, subfolder ?? "", true);
|
|
428
|
+
exportSimplePollerLike(
|
|
429
|
+
context,
|
|
430
|
+
clientMap,
|
|
431
|
+
subClientIndexFile,
|
|
432
|
+
project,
|
|
433
|
+
srcPath,
|
|
434
|
+
subfolder
|
|
435
|
+
);
|
|
384
436
|
exportRestoreHelpers(
|
|
385
437
|
subClientIndexFile,
|
|
386
438
|
project,
|