@azure-tools/typespec-ts 0.46.1 → 0.47.0-alpha.20251208.1

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.
Files changed (93) hide show
  1. package/CHANGELOG.md +15 -3
  2. package/LICENSE +21 -0
  3. package/dist/src/framework/hooks/sdkTypes.d.ts +7 -1
  4. package/dist/src/framework/hooks/sdkTypes.d.ts.map +1 -1
  5. package/dist/src/framework/hooks/sdkTypes.js +59 -1
  6. package/dist/src/framework/hooks/sdkTypes.js.map +1 -1
  7. package/dist/src/index.d.ts.map +1 -1
  8. package/dist/src/index.js +2 -1
  9. package/dist/src/index.js.map +1 -1
  10. package/dist/src/lib.d.ts +20 -1
  11. package/dist/src/lib.d.ts.map +1 -1
  12. package/dist/src/lib.js +18 -1
  13. package/dist/src/lib.js.map +1 -1
  14. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
  15. package/dist/src/modular/buildClassicalClient.js +137 -23
  16. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  17. package/dist/src/modular/buildClientContext.d.ts.map +1 -1
  18. package/dist/src/modular/buildClientContext.js +71 -24
  19. package/dist/src/modular/buildClientContext.js.map +1 -1
  20. package/dist/src/modular/buildRootIndex.d.ts +2 -1
  21. package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
  22. package/dist/src/modular/buildRootIndex.js +23 -0
  23. package/dist/src/modular/buildRootIndex.js.map +1 -1
  24. package/dist/src/modular/emitModels.d.ts.map +1 -1
  25. package/dist/src/modular/emitModels.js +57 -14
  26. package/dist/src/modular/emitModels.js.map +1 -1
  27. package/dist/src/modular/emitSamples.d.ts.map +1 -1
  28. package/dist/src/modular/emitSamples.js +53 -26
  29. package/dist/src/modular/emitSamples.js.map +1 -1
  30. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts.map +1 -1
  31. package/dist/src/modular/helpers/classicalOperationHelpers.js +73 -23
  32. package/dist/src/modular/helpers/classicalOperationHelpers.js.map +1 -1
  33. package/dist/src/modular/helpers/clientHelpers.d.ts +4 -1
  34. package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
  35. package/dist/src/modular/helpers/clientHelpers.js +7 -4
  36. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  37. package/dist/src/modular/helpers/operationHelpers.d.ts +7 -4
  38. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  39. package/dist/src/modular/helpers/operationHelpers.js +115 -23
  40. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  41. package/dist/src/modular/helpers/typeHelpers.d.ts +3 -1
  42. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
  43. package/dist/src/modular/helpers/typeHelpers.js +7 -3
  44. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  45. package/dist/src/modular/serialization/buildDeserializerFunction.d.ts +4 -2
  46. package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
  47. package/dist/src/modular/serialization/buildDeserializerFunction.js +60 -17
  48. package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
  49. package/dist/src/modular/serialization/buildSerializerFunction.d.ts +4 -2
  50. package/dist/src/modular/serialization/buildSerializerFunction.d.ts.map +1 -1
  51. package/dist/src/modular/serialization/buildSerializerFunction.js +61 -19
  52. package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
  53. package/dist/src/modular/serialization/serializeUtils.d.ts +11 -0
  54. package/dist/src/modular/serialization/serializeUtils.d.ts.map +1 -1
  55. package/dist/src/modular/serialization/serializeUtils.js +15 -0
  56. package/dist/src/modular/serialization/serializeUtils.js.map +1 -1
  57. package/dist/src/modular/static-helpers-metadata.d.ts +17 -0
  58. package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
  59. package/dist/src/modular/static-helpers-metadata.js +17 -0
  60. package/dist/src/modular/static-helpers-metadata.js.map +1 -1
  61. package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
  62. package/dist/src/transform/transfromRLCOptions.js +2 -0
  63. package/dist/src/transform/transfromRLCOptions.js.map +1 -1
  64. package/dist/src/utils/namespaceUtils.d.ts.map +1 -1
  65. package/dist/src/utils/namespaceUtils.js +19 -4
  66. package/dist/src/utils/namespaceUtils.js.map +1 -1
  67. package/dist/src/utils/operationUtil.d.ts +1 -0
  68. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  69. package/dist/src/utils/operationUtil.js +26 -0
  70. package/dist/src/utils/operationUtil.js.map +1 -1
  71. package/dist/tsconfig.tsbuildinfo +1 -1
  72. package/package.json +7 -11
  73. package/src/framework/hooks/sdkTypes.ts +102 -2
  74. package/src/index.ts +2 -0
  75. package/src/lib.ts +20 -1
  76. package/src/modular/buildClassicalClient.ts +182 -25
  77. package/src/modular/buildClientContext.ts +88 -31
  78. package/src/modular/buildRootIndex.ts +53 -1
  79. package/src/modular/emitModels.ts +72 -19
  80. package/src/modular/emitSamples.ts +86 -21
  81. package/src/modular/helpers/classicalOperationHelpers.ts +112 -30
  82. package/src/modular/helpers/clientHelpers.ts +8 -5
  83. package/src/modular/helpers/operationHelpers.ts +163 -43
  84. package/src/modular/helpers/typeHelpers.ts +19 -3
  85. package/src/modular/serialization/buildDeserializerFunction.ts +87 -35
  86. package/src/modular/serialization/buildSerializerFunction.ts +86 -36
  87. package/src/modular/serialization/serializeUtils.ts +37 -0
  88. package/src/modular/static-helpers-metadata.ts +18 -0
  89. package/src/transform/transfromRLCOptions.ts +2 -0
  90. package/src/utils/namespaceUtils.ts +19 -3
  91. package/src/utils/operationUtil.ts +35 -0
  92. package/static/static-helpers/serialization/check-prop-undefined.ts +17 -0
  93. package/static/static-helpers/simplePollerHelpers.ts +125 -0
@@ -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,
@@ -40,8 +40,14 @@ import {
40
40
 
41
41
  import { SdkContext } from "../utils/interfaces.js";
42
42
  import { addDeclaration } from "../framework/declaration.js";
43
- import { buildModelDeserializer } from "./serialization/buildDeserializerFunction.js";
44
- import { buildModelSerializer } from "./serialization/buildSerializerFunction.js";
43
+ import {
44
+ buildModelDeserializer,
45
+ buildPropertyDeserializer
46
+ } from "./serialization/buildDeserializerFunction.js";
47
+ import {
48
+ buildModelSerializer,
49
+ buildPropertySerializer
50
+ } from "./serialization/buildSerializerFunction.js";
45
51
  import path from "path";
46
52
  import { refkey } from "../framework/refkey.js";
47
53
  import { useContext } from "../contextManager.js";
@@ -50,6 +56,7 @@ import { isAzureCoreErrorType } from "../utils/modelUtils.js";
50
56
  import { isExtensibleEnum } from "./type-expressions/get-enum-expression.js";
51
57
  import {
52
58
  getAllDiscriminatedValues,
59
+ getPropertyWithOverrides,
53
60
  isDiscriminatedUnion
54
61
  } from "./serialization/serializeUtils.js";
55
62
  import { reportDiagnostic } from "../lib.js";
@@ -60,6 +67,7 @@ import {
60
67
  } from "./type-expressions/get-type-expression.js";
61
68
  import {
62
69
  emitQueue,
70
+ flattenPropertyModelMap,
63
71
  getAllOperationsFromClient
64
72
  } from "../framework/hooks/sdkTypes.js";
65
73
  import { resolveReference } from "../framework/reference.js";
@@ -122,6 +130,14 @@ export function emitTypes(
122
130
  emitType(context, type, sourceFile);
123
131
  }
124
132
 
133
+ // Emit serialization/deserialization functions for flattened properties
134
+ for (const [property, _] of flattenPropertyModelMap) {
135
+ const namespaces = getModelNamespaces(context, property.type);
136
+ const filepath = getModelsPath(sourceRoot, namespaces);
137
+ sourceFile = outputProject.getSourceFile(filepath);
138
+ addSerializationFunctions(context, property, sourceFile!);
139
+ }
140
+
125
141
  const modelFiles = outputProject.getSourceFiles(
126
142
  sourceRoot + "/models/**/*.ts"
127
143
  );
@@ -310,36 +326,38 @@ export function getModelNamespaces(
310
326
 
311
327
  function addSerializationFunctions(
312
328
  context: SdkContext,
313
- type: SdkType,
329
+ typeOrProperty: SdkType | SdkModelPropertyType,
314
330
  sourceFile: SourceFile,
315
- skipDiscriminatedUnion = false
331
+ skipDiscriminatedUnionSuffix = false
316
332
  ) {
317
- const serializationFunction = buildModelSerializer(
318
- context,
319
- type,
320
- skipDiscriminatedUnion
321
- );
333
+ const options = {
334
+ nameOnly: false,
335
+ skipDiscriminatedUnionSuffix
336
+ };
337
+ const serializationFunction =
338
+ typeOrProperty.kind === "property"
339
+ ? buildPropertySerializer(context, typeOrProperty, options)
340
+ : buildModelSerializer(context, typeOrProperty, options);
322
341
 
323
- const serializerRefkey = refkey(type, "serializer");
324
- const deserailizerRefKey = refkey(type, "deserializer");
342
+ const serializerRefKey = refkey(typeOrProperty, "serializer");
343
+ const deserializerRefKey = refkey(typeOrProperty, "deserializer");
325
344
  if (
326
345
  serializationFunction &&
327
346
  typeof serializationFunction !== "string" &&
328
347
  serializationFunction.name
329
348
  ) {
330
- addDeclaration(sourceFile, serializationFunction, serializerRefkey);
349
+ addDeclaration(sourceFile, serializationFunction, serializerRefKey);
331
350
  }
332
- const deserializationFunction = buildModelDeserializer(
333
- context,
334
- type,
335
- skipDiscriminatedUnion
336
- );
351
+ const deserializationFunction =
352
+ typeOrProperty.kind === "property"
353
+ ? buildPropertyDeserializer(context, typeOrProperty, options)
354
+ : buildModelDeserializer(context, typeOrProperty, options);
337
355
  if (
338
356
  deserializationFunction &&
339
357
  typeof deserializationFunction !== "string" &&
340
358
  deserializationFunction.name
341
359
  ) {
342
- addDeclaration(sourceFile, deserializationFunction, deserailizerRefKey);
360
+ addDeclaration(sourceFile, deserializationFunction, deserializerRefKey);
343
361
  }
344
362
  }
345
363
 
@@ -474,16 +492,47 @@ function buildModelInterface(
474
492
  context: SdkContext,
475
493
  type: SdkModelType
476
494
  ): InterfaceDeclarationStructure {
495
+ const flattenPropertySet = new Set<SdkModelPropertyType>();
477
496
  const interfaceStructure = {
478
497
  kind: StructureKind.Interface,
479
498
  name: normalizeModelName(context, type, NameType.Interface, true),
480
499
  isExported: true,
481
500
  properties: type.properties
482
501
  .filter((p) => !isMetadata(context.program, p.__raw!))
502
+ .filter((p) => {
503
+ // filter out the flatten property to be processed later
504
+ if (p.flatten) {
505
+ flattenPropertySet.add(p);
506
+ return false;
507
+ }
508
+ return true;
509
+ })
483
510
  .map((p) => {
484
511
  return buildModelProperty(context, p, type);
485
512
  })
486
513
  } as InterfaceStructure;
514
+ for (const flatten of flattenPropertySet.keys()) {
515
+ if (flatten.type?.kind !== "model" || !flatten.type.properties) {
516
+ continue;
517
+ }
518
+ const conflictMap =
519
+ useContext("sdkTypes").flattenProperties.get(flatten)?.conflictMap;
520
+ const allProperties = getAllProperties(
521
+ context,
522
+ flatten.type,
523
+ getAllAncestors(flatten.type)
524
+ ).filter((p) => !isMetadata(context.program, p.__raw!));
525
+ interfaceStructure.properties!.push(
526
+ ...allProperties.map((p) => {
527
+ // when the flattened property is optional, all its child properties should be optional too
528
+ const property = getPropertyWithOverrides(p, {
529
+ allOptional: flatten.optional,
530
+ propertyRenames: conflictMap
531
+ });
532
+ return buildModelProperty(context, property, type);
533
+ })
534
+ );
535
+ }
487
536
 
488
537
  if (type.baseModel) {
489
538
  const parentReference = getModelExpression(context, type.baseModel, {
@@ -635,7 +684,7 @@ function buildModelPolymorphicType(context: SdkContext, type: SdkModelType) {
635
684
  }
636
685
  const typeDeclaration: TypeAliasDeclarationStructure = {
637
686
  kind: StructureKind.TypeAlias,
638
- name: `${normalizeName(type.name, NameType.Interface)}Union`,
687
+ name: `${normalizeModelName(context, type, NameType.Interface, true)}Union`,
639
688
  isExported: true,
640
689
  type: directSubtypes
641
690
  .filter((p) => {
@@ -747,6 +796,7 @@ function buildModelProperty(
747
796
  export function visitPackageTypes(context: SdkContext) {
748
797
  const { sdkPackage } = context;
749
798
  emitQueue.clear();
799
+ flattenPropertyModelMap.clear();
750
800
  // Add all models in the package to the emit queue
751
801
  for (const model of sdkPackage.models) {
752
802
  visitType(context, model);
@@ -852,6 +902,9 @@ function visitType(context: SdkContext, type: SdkType | undefined) {
852
902
  if (!emitQueue.has(property.type)) {
853
903
  visitType(context, property.type);
854
904
  }
905
+ if (property.flatten && property.type.kind === "model") {
906
+ flattenPropertyModelMap.set(property, type);
907
+ }
855
908
  }
856
909
  if (type.discriminatedSubtypes) {
857
910
  for (const subType of Object.values(type.discriminatedSubtypes)) {
@@ -34,11 +34,13 @@ import {
34
34
  } from "../utils/credentialUtils.js";
35
35
  import {
36
36
  getMethodHierarchiesMap,
37
+ isTenantLevelOperation,
37
38
  ServiceOperation
38
39
  } from "../utils/operationUtil.js";
39
40
  import { getSubscriptionId } from "../transform/transfromRLCOptions.js";
40
41
  import { getClientParametersDeclaration } from "./helpers/clientHelpers.js";
41
42
  import { getOperationFunction } from "./helpers/operationHelpers.js";
43
+ import { ModelOverrideOptions } from "./serialization/serializeUtils.js";
42
44
 
43
45
  /**
44
46
  * Interfaces for samples generations
@@ -272,6 +274,7 @@ function buildParameterValueMap(example: SdkHttpOperationExample) {
272
274
  }
273
275
 
274
276
  function prepareExampleValue(
277
+ context: SdkContext,
275
278
  name: string,
276
279
  value: SdkExampleValue | string,
277
280
  isOptional?: boolean,
@@ -279,7 +282,8 @@ function prepareExampleValue(
279
282
  ): ExampleValue {
280
283
  return {
281
284
  name: normalizeName(name, NameType.Parameter),
282
- value: typeof value === "string" ? value : getParameterValue(value),
285
+ value:
286
+ typeof value === "string" ? value : getParameterValue(context, value),
283
287
  isOptional: Boolean(isOptional),
284
288
  onClient: Boolean(onClient)
285
289
  };
@@ -327,7 +331,8 @@ function prepareExampleParameters(
327
331
  result.push(credentialExampleValue);
328
332
  }
329
333
 
330
- let subscriptionIdValue = `"00000000-0000-0000-0000-00000000000"`;
334
+ let subscriptionIdValue = `"00000000-0000-0000-0000-000000000000"`;
335
+ let isSubscriptionIdAdded = false;
331
336
  // required parameters
332
337
  for (const param of method.operation.parameters) {
333
338
  if (
@@ -339,6 +344,26 @@ function prepareExampleParameters(
339
344
  }
340
345
 
341
346
  const exampleValue = parameterMap[param.serializedName];
347
+
348
+ // Handle subscriptionId parameter separately for ARM clients
349
+ // Add it as long as it's the parameter of the method, even no example provided
350
+ if (param.name.toLowerCase() === "subscriptionid" && dpgContext.arm) {
351
+ isSubscriptionIdAdded = true;
352
+ if (exampleValue && exampleValue.value) {
353
+ subscriptionIdValue = getParameterValue(dpgContext, exampleValue.value);
354
+ }
355
+ result.push(
356
+ prepareExampleValue(
357
+ dpgContext,
358
+ param.name,
359
+ subscriptionIdValue,
360
+ param.optional,
361
+ param.onClient
362
+ )
363
+ );
364
+ continue;
365
+ }
366
+
342
367
  if (!exampleValue || !exampleValue.value) {
343
368
  // report diagnostic if required parameter is missing
344
369
  reportDiagnostic(dpgContext.program, {
@@ -352,16 +377,9 @@ function prepareExampleParameters(
352
377
  continue;
353
378
  }
354
379
 
355
- if (
356
- param.name.toLowerCase() === "subscriptionid" &&
357
- dpgContext.arm &&
358
- exampleValue
359
- ) {
360
- subscriptionIdValue = getParameterValue(exampleValue.value);
361
- continue;
362
- }
363
380
  result.push(
364
381
  prepareExampleValue(
382
+ dpgContext,
365
383
  exampleValue.parameter.name,
366
384
  exampleValue.value,
367
385
  param.optional,
@@ -369,12 +387,26 @@ function prepareExampleParameters(
369
387
  )
370
388
  );
371
389
  }
372
- // add subscriptionId for ARM clients if ARM clients need it
373
- if (dpgContext.arm && getSubscriptionId(dpgContext)) {
390
+
391
+ // If client-level subscriptionId is needed on the client for this method, then add it
392
+ // For example, Operations_List
393
+ if (
394
+ dpgContext.arm &&
395
+ getSubscriptionId(dpgContext) &&
396
+ !isSubscriptionIdAdded &&
397
+ !isTenantLevelOperation(method, topLevelClient)
398
+ ) {
374
399
  result.push(
375
- prepareExampleValue("subscriptionId", subscriptionIdValue, false, true)
400
+ prepareExampleValue(
401
+ dpgContext,
402
+ "subscriptionId",
403
+ subscriptionIdValue,
404
+ false,
405
+ true
406
+ )
376
407
  );
377
408
  }
409
+
378
410
  // required/optional body parameters
379
411
  const bodyParam = method.operation.bodyParam;
380
412
  const bodySerializeName = bodyParam?.serializedName;
@@ -392,6 +424,7 @@ function prepareExampleParameters(
392
424
  }
393
425
  result.push(
394
426
  prepareExampleValue(
427
+ dpgContext,
395
428
  prop.name,
396
429
  propExample,
397
430
  prop.optional,
@@ -402,6 +435,7 @@ function prepareExampleParameters(
402
435
  } else {
403
436
  result.push(
404
437
  prepareExampleValue(
438
+ dpgContext,
405
439
  bodyParam.name,
406
440
  bodyExample.value,
407
441
  bodyParam.optional,
@@ -422,6 +456,7 @@ function prepareExampleParameters(
422
456
  .forEach((param) => {
423
457
  result.push(
424
458
  prepareExampleValue(
459
+ dpgContext,
425
460
  param.parameter.name,
426
461
  param.value,
427
462
  true,
@@ -471,7 +506,13 @@ function getCredentialExampleValue(
471
506
  return undefined;
472
507
  }
473
508
 
474
- function getParameterValue(value: SdkExampleValue): string {
509
+ function getParameterValue(
510
+ context: SdkContext,
511
+ value: SdkExampleValue,
512
+ options?: {
513
+ overrides?: ModelOverrideOptions;
514
+ }
515
+ ): string {
475
516
  let retValue = `{} as any`;
476
517
  switch (value.kind) {
477
518
  case "string": {
@@ -509,21 +550,43 @@ function getParameterValue(value: SdkExampleValue): string {
509
550
  break;
510
551
  case "dict":
511
552
  case "model": {
512
- const mapper = buildPropertyNameMapper(value.type);
553
+ const mapper = buildPropertyNameMapper(
554
+ context,
555
+ value.type,
556
+ options?.overrides
557
+ );
513
558
  const values = [];
514
559
  const additionalPropertiesValue =
515
560
  value.kind === "model" ? (value.additionalPropertiesValue ?? {}) : {};
516
561
  for (const propName in {
517
562
  ...value.value
518
563
  }) {
564
+ let property;
565
+ if (value.type.kind === "model") {
566
+ property = value.type.properties.find((p) => p.name === propName);
567
+ }
519
568
  const propValue = value.value[propName];
520
569
  if (propValue === undefined || propValue === null) {
521
570
  continue;
522
571
  }
523
- const propRetValue =
524
- `"${mapper.get(propName) ?? propName}": ` +
525
- getParameterValue(propValue);
526
- values.push(propRetValue);
572
+ let propRetValue;
573
+
574
+ if (property?.flatten && property.type.kind === "model") {
575
+ const paramValue = getParameterValue(context, propValue, {
576
+ overrides: {
577
+ propertyRenames:
578
+ useContext("sdkTypes").flattenProperties.get(property)
579
+ ?.conflictMap
580
+ }
581
+ });
582
+ propRetValue =
583
+ paramValue.length > 2 ? paramValue.slice(1, -1) : undefined;
584
+ } else {
585
+ propRetValue =
586
+ `"${mapper.get(propName) ?? propName}": ` +
587
+ getParameterValue(context, propValue);
588
+ }
589
+ if (propRetValue) values.push(propRetValue);
527
590
  }
528
591
  const additionalBags = [];
529
592
  for (const propName in {
@@ -535,7 +598,7 @@ function getParameterValue(value: SdkExampleValue): string {
535
598
  }
536
599
  const propRetValue =
537
600
  `"${mapper.get(propName) ?? propName}": ` +
538
- getParameterValue(propValue);
601
+ getParameterValue(context, propValue);
539
602
  additionalBags.push(propRetValue);
540
603
  }
541
604
  if (additionalBags.length > 0) {
@@ -551,7 +614,9 @@ function getParameterValue(value: SdkExampleValue): string {
551
614
  break;
552
615
  }
553
616
  case "array": {
554
- const valuesArr = value.value.map(getParameterValue);
617
+ const valuesArr = value.value.map((item) =>
618
+ getParameterValue(context, item)
619
+ );
555
620
  retValue = `[${valuesArr.join(", ")}]`;
556
621
  break;
557
622
  }
@@ -19,6 +19,21 @@ import { ServiceOperation } from "../../utils/operationUtil.js";
19
19
  import { refkey } from "../../framework/refkey.js";
20
20
  import { resolveReference } from "../../framework/reference.js";
21
21
  import { addDeclaration } from "../../framework/declaration.js";
22
+ import { SimplePollerHelpers } from "../static-helpers-metadata.js";
23
+ import { AzurePollingDependencies } from "../external-dependencies.js";
24
+
25
+ interface OperationDeclarationInfo {
26
+ // the operation function
27
+ declaration: OptionalKind<FunctionDeclarationStructure>;
28
+ // the original operation name
29
+ oriName: string | undefined;
30
+ // the refkey of the operation declaration
31
+ declarationRefKey: string | undefined;
32
+ // the default is false
33
+ isLro?: boolean;
34
+ // only set when isLro is true
35
+ lroFinalReturnType?: string;
36
+ }
22
37
 
23
38
  export function getClassicalOperation(
24
39
  dpgContext: SdkContext,
@@ -51,27 +66,25 @@ export function getClassicalOperation(
51
66
  });
52
67
  }
53
68
 
54
- const operationMap = new Map<
55
- OptionalKind<FunctionDeclarationStructure>,
56
- string | undefined
57
- >();
58
- const operationKeyMap = new Map<
69
+ const operationDeclarationMap = new Map<
59
70
  OptionalKind<FunctionDeclarationStructure>,
60
- string | undefined
71
+ OperationDeclarationInfo | undefined
61
72
  >();
62
73
  const operationDeclarations: OptionalKind<FunctionDeclarationStructure>[] =
63
74
  operations.map((operation) => {
64
- const declarations = getOperationFunction(
75
+ const declaration = getOperationFunction(
65
76
  dpgContext,
66
77
  [prefixes, operation],
67
78
  rlcClientName
68
79
  );
69
- operationMap.set(declarations, operation.oriName);
70
- operationKeyMap.set(
71
- declarations,
72
- resolveReference(refkey(operation, "api"))
73
- );
74
- return declarations;
80
+ operationDeclarationMap.set(declaration, {
81
+ declaration,
82
+ oriName: operation.oriName,
83
+ declarationRefKey: resolveReference(refkey(operation, "api")),
84
+ isLro: declaration.isLro,
85
+ lroFinalReturnType: declaration.lroFinalReturnType
86
+ });
87
+ return declaration;
75
88
  });
76
89
 
77
90
  const interfaceNamePrefix = getClassicalLayerPrefix(
@@ -111,24 +124,52 @@ export function getClassicalOperation(
111
124
  }
112
125
  } else {
113
126
  operationDeclarations.forEach((d) => {
127
+ const operationInfo = operationDeclarationMap.get(d);
128
+ const paramStr = d.parameters
129
+ ?.filter((p) => p.name !== "context")
130
+ .map(
131
+ (p) =>
132
+ p.name +
133
+ (p.type?.toString().endsWith("operationOptions__") ||
134
+ p.hasQuestionToken
135
+ ? "?"
136
+ : "") +
137
+ ": " +
138
+ p.type
139
+ )
140
+ .join(",");
141
+ // add the operation method signature
114
142
  properties.push({
115
143
  kind: StructureKind.PropertySignature,
116
144
  name: getClassicalMethodName(d),
117
- type: `(${d.parameters
118
- ?.filter((p) => p.name !== "context")
119
- .map(
120
- (p) =>
121
- p.name +
122
- (p.type?.toString().endsWith("operationOptions__") ||
123
- p.hasQuestionToken
124
- ? "?"
125
- : "") +
126
- ": " +
127
- p.type
128
- )
129
- .join(",")}) => ${d.returnType}`,
145
+ type: `(${paramStr}) => ${d.returnType}`,
130
146
  docs: d.docs
131
147
  });
148
+ // add LRO helper methods if applicable
149
+ if (dpgContext.rlcOptions?.compatibilityLro && operationInfo?.isLro) {
150
+ const operationStateReference = resolveReference(
151
+ AzurePollingDependencies.OperationState
152
+ );
153
+ const simplePollerLikeReference = resolveReference(
154
+ SimplePollerHelpers.SimplePollerLike
155
+ );
156
+ const returnType = operationInfo?.lroFinalReturnType ?? "void";
157
+ const beginName = `begin_${getClassicalMethodName(d)}`;
158
+ const beginAndWaitName = `${beginName}_andWait`;
159
+
160
+ properties.push({
161
+ kind: StructureKind.PropertySignature,
162
+ name: `${normalizeName(beginName, NameType.Method)}`,
163
+ type: `(${paramStr}) => Promise<${simplePollerLikeReference}<${operationStateReference}<${returnType}>, ${returnType}>>`,
164
+ docs: [`@deprecated use ${getClassicalMethodName(d)} instead`]
165
+ });
166
+ properties.push({
167
+ kind: StructureKind.PropertySignature,
168
+ name: `${normalizeName(beginAndWaitName, NameType.Method)}`,
169
+ type: `(${paramStr}) => Promise<${returnType}>`,
170
+ docs: [`@deprecated use ${getClassicalMethodName(d)} instead`]
171
+ });
172
+ }
132
173
  });
133
174
  }
134
175
  if (existInterface) {
@@ -168,7 +209,8 @@ export function getClassicalOperation(
168
209
  statements: `return {
169
210
  ${operationDeclarations
170
211
  .map((d) => {
171
- return `${getClassicalMethodName(d)}: (${d.parameters
212
+ const operationInfo = operationDeclarationMap.get(d);
213
+ const classicalParamStr = d.parameters
172
214
  ?.filter((p) => p.name !== "context")
173
215
  .map(
174
216
  (p) =>
@@ -180,12 +222,52 @@ export function getClassicalOperation(
180
222
  ": " +
181
223
  p.type
182
224
  )
183
- .join(",")}) => ${operationKeyMap.get(d)}(${[
225
+ .join(",");
226
+ const apiParamStr = [
184
227
  "context",
185
228
  ...[
186
229
  d.parameters?.map((p) => p.name).filter((p) => p !== "context")
187
230
  ]
188
- ].join(",")})`;
231
+ ].join(",");
232
+ const ret = [
233
+ `${getClassicalMethodName(d)}: (${classicalParamStr}) => ${operationInfo?.declarationRefKey}(${
234
+ apiParamStr
235
+ })`
236
+ ];
237
+ // add LRO helper methods if applicable
238
+ if (
239
+ dpgContext.rlcOptions?.compatibilityLro &&
240
+ operationInfo?.isLro
241
+ ) {
242
+ const getSimplePollerReference = resolveReference(
243
+ SimplePollerHelpers.getSimplePoller
244
+ );
245
+ const beginName = `begin_${getClassicalMethodName(d)}`;
246
+ const beginAndWaitName = `${beginName}_andWait`;
247
+ ret.push(
248
+ `${normalizeName(
249
+ beginName,
250
+ NameType.Method
251
+ )}: async (${classicalParamStr}) => {
252
+ const poller = ${operationInfo?.declarationRefKey}(${
253
+ apiParamStr
254
+ });
255
+ await poller.submitted();
256
+ return ${getSimplePollerReference}(poller);
257
+ }`
258
+ );
259
+ ret.push(
260
+ `${normalizeName(
261
+ beginAndWaitName,
262
+ NameType.Method
263
+ )}: async (${classicalParamStr}) => {
264
+ return await ${operationInfo?.declarationRefKey}(${
265
+ apiParamStr
266
+ });
267
+ }`
268
+ );
269
+ }
270
+ return ret.join(",");
189
271
  })
190
272
  .join(",")}
191
273
  }`
@@ -280,7 +362,7 @@ export function getClassicalOperation(
280
362
  }
281
363
  ) {
282
364
  return normalizeName(
283
- operationMap.get(declaration) ??
365
+ operationDeclarationMap.get(declaration)?.oriName ??
284
366
  declaration.propertyName ??
285
367
  declaration.name ??
286
368
  "FIXME",