@azure-tools/typespec-ts 0.15.0 → 0.16.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +14 -17
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/lib.d.ts.map +1 -1
  6. package/dist/src/lib.js +3 -3
  7. package/dist/src/lib.js.map +1 -1
  8. package/dist/src/modular/buildClassicalClient.d.ts +2 -3
  9. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
  10. package/dist/src/modular/buildClassicalClient.js +26 -12
  11. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  12. package/dist/src/modular/buildClientContext.d.ts +3 -3
  13. package/dist/src/modular/buildClientContext.d.ts.map +1 -1
  14. package/dist/src/modular/buildClientContext.js +5 -4
  15. package/dist/src/modular/buildClientContext.js.map +1 -1
  16. package/dist/src/modular/buildCodeModel.d.ts +3 -2
  17. package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
  18. package/dist/src/modular/buildCodeModel.js +141 -54
  19. package/dist/src/modular/buildCodeModel.js.map +1 -1
  20. package/dist/src/modular/buildOperations.d.ts +2 -2
  21. package/dist/src/modular/buildOperations.d.ts.map +1 -1
  22. package/dist/src/modular/buildOperations.js +15 -8
  23. package/dist/src/modular/buildOperations.js.map +1 -1
  24. package/dist/src/modular/buildProjectFiles.js +2 -2
  25. package/dist/src/modular/buildProjectFiles.js.map +1 -1
  26. package/dist/src/modular/buildRootIndex.d.ts +4 -4
  27. package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
  28. package/dist/src/modular/buildRootIndex.js +12 -5
  29. package/dist/src/modular/buildRootIndex.js.map +1 -1
  30. package/dist/src/modular/buildSubpathIndex.d.ts +2 -2
  31. package/dist/src/modular/buildSubpathIndex.d.ts.map +1 -1
  32. package/dist/src/modular/buildSubpathIndex.js +7 -4
  33. package/dist/src/modular/buildSubpathIndex.js.map +1 -1
  34. package/dist/src/modular/emitModels.d.ts +3 -3
  35. package/dist/src/modular/emitModels.d.ts.map +1 -1
  36. package/dist/src/modular/emitModels.js +28 -18
  37. package/dist/src/modular/emitModels.js.map +1 -1
  38. package/dist/src/modular/helpers/clientHelpers.js +1 -1
  39. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  40. package/dist/src/modular/helpers/operationHelpers.d.ts +1 -1
  41. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  42. package/dist/src/modular/helpers/operationHelpers.js +140 -77
  43. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  44. package/dist/src/modular/helpers/typeHelpers.d.ts +2 -2
  45. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
  46. package/dist/src/modular/helpers/typeHelpers.js +13 -7
  47. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  48. package/dist/src/modular/modularCodeModel.d.ts +11 -0
  49. package/dist/src/modular/modularCodeModel.d.ts.map +1 -1
  50. package/dist/src/transform/transformHelperFunctionDetails.js +3 -4
  51. package/dist/src/transform/transformHelperFunctionDetails.js.map +1 -1
  52. package/dist/src/transform/transformParameters.d.ts +0 -10
  53. package/dist/src/transform/transformParameters.d.ts.map +1 -1
  54. package/dist/src/transform/transformParameters.js +7 -51
  55. package/dist/src/transform/transformParameters.js.map +1 -1
  56. package/dist/src/transform/transformResponses.js +3 -4
  57. package/dist/src/transform/transformResponses.js.map +1 -1
  58. package/dist/src/transform/transformSchemas.d.ts.map +1 -1
  59. package/dist/src/transform/transformSchemas.js +4 -8
  60. package/dist/src/transform/transformSchemas.js.map +1 -1
  61. package/dist/src/transform/transformTelemetryInfo.d.ts.map +1 -1
  62. package/dist/src/transform/transformTelemetryInfo.js +3 -10
  63. package/dist/src/transform/transformTelemetryInfo.js.map +1 -1
  64. package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
  65. package/dist/src/transform/transfromRLCOptions.js +48 -9
  66. package/dist/src/transform/transfromRLCOptions.js.map +1 -1
  67. package/dist/src/utils/modelUtils.d.ts +2 -1
  68. package/dist/src/utils/modelUtils.d.ts.map +1 -1
  69. package/dist/src/utils/modelUtils.js +83 -73
  70. package/dist/src/utils/modelUtils.js.map +1 -1
  71. package/dist/src/utils/operationUtil.d.ts +15 -1
  72. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  73. package/dist/src/utils/operationUtil.js +82 -3
  74. package/dist/src/utils/operationUtil.js.map +1 -1
  75. package/dist/tsconfig.tsbuildinfo +1 -1
  76. package/package.json +13 -11
  77. package/src/index.ts +24 -51
  78. package/src/lib.ts +3 -3
  79. package/src/modular/buildClassicalClient.ts +29 -16
  80. package/src/modular/buildClientContext.ts +8 -9
  81. package/src/modular/buildCodeModel.ts +183 -60
  82. package/src/modular/buildOperations.ts +16 -11
  83. package/src/modular/buildProjectFiles.ts +2 -2
  84. package/src/modular/buildRootIndex.ts +19 -12
  85. package/src/modular/buildSubpathIndex.ts +10 -8
  86. package/src/modular/emitModels.ts +35 -24
  87. package/src/modular/helpers/clientHelpers.ts +1 -1
  88. package/src/modular/helpers/operationHelpers.ts +231 -118
  89. package/src/modular/helpers/typeHelpers.ts +14 -7
  90. package/src/modular/modularCodeModel.ts +11 -0
  91. package/src/transform/transformHelperFunctionDetails.ts +10 -4
  92. package/src/transform/transformParameters.ts +15 -57
  93. package/src/transform/transformResponses.ts +2 -4
  94. package/src/transform/transformSchemas.ts +5 -9
  95. package/src/transform/transformTelemetryInfo.ts +4 -18
  96. package/src/transform/transfromRLCOptions.ts +67 -9
  97. package/src/utils/modelUtils.ts +81 -72
  98. package/src/utils/operationUtil.ts +121 -4
@@ -25,6 +25,10 @@ import {
25
25
  getFixmeForMultilineDocs,
26
26
  getDocsFromDescription
27
27
  } from "./docsHelpers.js";
28
+ import {
29
+ getCollectionFormatHelper,
30
+ hasCollectionFormatInfo
31
+ } from "../../utils/operationUtil.js";
28
32
 
29
33
  function getRLCResponseType(rlcResponse?: OperationResponse) {
30
34
  if (!rlcResponse?.responses) {
@@ -86,7 +90,7 @@ export function getDeserializePrivateFunction(
86
90
  ): OptionalKind<FunctionDeclarationStructure> {
87
91
  const { name } = getOperationName(operation);
88
92
 
89
- let parameters: OptionalKind<ParameterDeclarationStructure>[] = [
93
+ const parameters: OptionalKind<ParameterDeclarationStructure>[] = [
90
94
  {
91
95
  name: "result",
92
96
  type: getRLCResponseType(operation.rlcResponse)
@@ -97,16 +101,12 @@ export function getDeserializePrivateFunction(
97
101
  const response = operation.responses[0]!;
98
102
  let returnType;
99
103
  if (response?.type?.type) {
100
- returnType = buildType(response.type.name, response.type);
104
+ returnType = buildType(
105
+ response.type.name,
106
+ response.type,
107
+ response.type.format
108
+ );
101
109
  } else {
102
- if (!needUnexpectedHelper) {
103
- parameters = [
104
- {
105
- name: "_result",
106
- type: getRLCResponseType(operation.rlcResponse)
107
- }
108
- ];
109
- }
110
110
  returnType = { name: "", type: "void" };
111
111
  }
112
112
 
@@ -124,6 +124,24 @@ export function getDeserializePrivateFunction(
124
124
  "throw result.body",
125
125
  "}"
126
126
  );
127
+ } else {
128
+ const validStatus = [
129
+ ...new Set(
130
+ operation.responses
131
+ .flatMap((r) => r.statusCodes)
132
+ .filter((s) => s !== "default")
133
+ )
134
+ ];
135
+
136
+ if (validStatus.length > 0) {
137
+ statements.push(
138
+ `if(${validStatus
139
+ .map((s) => `result.status !== "${s}"`)
140
+ .join(" || ")}){`,
141
+ "throw result.body",
142
+ "}"
143
+ );
144
+ }
127
145
  }
128
146
 
129
147
  if (response?.type?.type === "any") {
@@ -134,7 +152,8 @@ export function getDeserializePrivateFunction(
134
152
  response.type,
135
153
  "result.body",
136
154
  importSet,
137
- response.type.nullable !== undefined ? !response.type.nullable : false
155
+ response.type.nullable !== undefined ? !response.type.nullable : false,
156
+ response.type.format
138
157
  )}`
139
158
  );
140
159
  } else if (response?.type?.properties) {
@@ -171,20 +190,21 @@ function getOperationSignatureParameters(
171
190
  (operation.bodyParameter?.type.properties ?? [])
172
191
  .filter((p) => !p.optional)
173
192
  .filter((p) => !p.readonly)
174
- .map((p) => buildType(p.clientName, p.type))
193
+ .map((p) => buildType(p.clientName, p.type, p.format))
175
194
  .forEach((p) => parameters.set(p.name, p));
176
195
  } else if (operation.bodyParameter?.type.type === "list") {
177
196
  const bodyArray = operation.bodyParameter;
178
197
  parameters.set(
179
198
  bodyArray.clientName,
180
- buildType(bodyArray.clientName, bodyArray.type)
199
+ buildType(bodyArray.clientName, bodyArray.type, bodyArray.type.format)
181
200
  );
182
201
  } else if (operation.bodyParameter?.type.type === "byte-array") {
183
202
  parameters.set(
184
203
  operation.bodyParameter.clientName,
185
204
  buildType(
186
205
  operation.bodyParameter.clientName,
187
- operation.bodyParameter.type
206
+ operation.bodyParameter.type,
207
+ operation.bodyParameter.type.format
188
208
  )
189
209
  );
190
210
  }
@@ -197,7 +217,7 @@ function getOperationSignatureParameters(
197
217
  p.clientDefaultValue === undefined &&
198
218
  !p.optional
199
219
  )
200
- .map((p) => buildType(p.clientName, p.type))
220
+ .map((p) => buildType(p.clientName, p.type, p.format))
201
221
  .forEach((p) => {
202
222
  parameters.set(p.name, p);
203
223
  });
@@ -231,7 +251,7 @@ export function getOperationFunction(
231
251
  // TODO: Support operation overloads
232
252
  const response = operation.responses[0]!;
233
253
  const returnType = response?.type?.type
234
- ? buildType(response.type.name, response.type)
254
+ ? buildType(response.type.name, response.type, response.type.format)
235
255
  : { name: "", type: "void" };
236
256
 
237
257
  const { name, fixme = [] } = getOperationName(operation);
@@ -260,10 +280,16 @@ export function getOperationFunction(
260
280
  };
261
281
  }
262
282
 
263
- export function getOperationOptionsName(operation: Operation) {
264
- return `${toPascalCase(operation.groupName)}${toPascalCase(
265
- operation.name
266
- )}Options`;
283
+ export function getOperationOptionsName(
284
+ operation: Operation,
285
+ includeGroupName = false
286
+ ) {
287
+ const prefix = includeGroupName ? toPascalCase(operation.groupName) : "";
288
+ const optionName = `${prefix}${toPascalCase(operation.name)}Options`;
289
+ if (operation.bodyParameter?.type.name === optionName) {
290
+ return optionName.replace(/Options$/, "RequestOptions");
291
+ }
292
+ return optionName;
267
293
  }
268
294
 
269
295
  /**
@@ -278,7 +304,6 @@ function getRequestParameters(
278
304
  if (!operation.parameters) {
279
305
  return "";
280
306
  }
281
-
282
307
  const operationParameters = operation.parameters.filter(
283
308
  (p) => p.implementation !== "Client" && !isContentType(p)
284
309
  );
@@ -309,9 +334,9 @@ function getRequestParameters(
309
334
  }
310
335
 
311
336
  if (parametersImplementation.header.length) {
312
- paramStr = `${paramStr}\nheaders: {${
313
- parametersImplementation.header.join(",\n") + ","
314
- },`;
337
+ paramStr = `${paramStr}\nheaders: {${parametersImplementation.header.join(
338
+ ",\n"
339
+ )}},`;
315
340
  }
316
341
 
317
342
  if (parametersImplementation.query.length) {
@@ -338,14 +363,16 @@ function buildBodyParameter(
338
363
 
339
364
  if (bodyParameter.type.type === "model") {
340
365
  const bodyParts: string[] = [];
341
- let hasSerializeBody = false;
342
366
  for (const param of bodyParameter?.type.properties?.filter(
343
367
  (p) => !p.readonly
344
368
  ) ?? []) {
345
369
  if (param.type.type === "model" && isRequired(param)) {
346
- hasSerializeBody = true;
347
370
  bodyParts.push(
348
- ...getRequestModelMapping(param.type, param.clientName, importSet)
371
+ `"${param.restApiName}": {${getRequestModelMapping(
372
+ param.type,
373
+ param.clientName,
374
+ importSet
375
+ ).join(",\n")}}`
349
376
  );
350
377
  } else {
351
378
  bodyParts.push(getParameterMap(param, importSet));
@@ -353,13 +380,7 @@ function buildBodyParameter(
353
380
  }
354
381
 
355
382
  if (bodyParameter && bodyParameter.type.properties) {
356
- if (hasSerializeBody) {
357
- return `\nbody: {"${bodyParameter.restApiName}": {${bodyParts.join(
358
- ",\n"
359
- )}}},`;
360
- } else {
361
- return `\nbody: {${bodyParts.join(",\n")}},`;
362
- }
383
+ return `\nbody: {${bodyParts.join(",\n")}},`;
363
384
  }
364
385
  }
365
386
 
@@ -395,12 +416,13 @@ function getParameterMap(
395
416
  return getConstantValue(param);
396
417
  }
397
418
 
398
- if (isOptionalWithouDefault(param)) {
399
- return getOptionalWithoutDefault(param, importSet);
419
+ if (hasCollectionFormatInfo((param as any).location, (param as any).format)) {
420
+ return getCollectionFormat(param as Parameter, importSet);
400
421
  }
401
422
 
402
- if (isOptionalWithDefault(param)) {
403
- return getOptionalWithDefault(param, importSet);
423
+ // if the parameter or property is optional, we don't need to handle the default value
424
+ if (isOptional(param)) {
425
+ return getOptional(param, importSet);
404
426
  }
405
427
 
406
428
  if (isRequired(param)) {
@@ -410,6 +432,39 @@ function getParameterMap(
410
432
  throw new Error(`Parameter ${param.clientName} is not supported`);
411
433
  }
412
434
 
435
+ function getCollectionFormat(
436
+ param: Parameter,
437
+ importSet: Map<string, Set<string>>
438
+ ) {
439
+ const collectionInfo = getCollectionFormatHelper(
440
+ param.location,
441
+ param.format ?? ""
442
+ );
443
+ if (!collectionInfo) {
444
+ throw "Has collection format info but without helper function detected";
445
+ }
446
+ const isMulti = (param.format ?? "").toLowerCase() === "multi";
447
+ const additionalParam = isMulti ? `, "${param.restApiName}"` : "";
448
+ if (!param.optional) {
449
+ return `"${param.restApiName}": ${collectionInfo}(${serializeRequestValue(
450
+ param.type,
451
+ param.clientName,
452
+ importSet,
453
+ true,
454
+ param.format
455
+ )}${additionalParam})`;
456
+ }
457
+ return `"${param.restApiName}": options?.${
458
+ param.clientName
459
+ } !== undefined ? ${collectionInfo}(${serializeRequestValue(
460
+ param.type,
461
+ "options?." + param.clientName,
462
+ importSet,
463
+ false,
464
+ param.format
465
+ )}${additionalParam}): undefined`;
466
+ }
467
+
413
468
  function isContentType(param: Parameter): boolean {
414
469
  return (
415
470
  param.location === "header" &&
@@ -450,7 +505,17 @@ function getRequired(param: RequiredType, importSet: Map<string, Set<string>>) {
450
505
  importSet
451
506
  ).join(",")}`;
452
507
  }
453
- return `"${param.restApiName}": ${param.clientName}`;
508
+ return `"${param.restApiName}": ${serializeRequestValue(
509
+ param.type,
510
+ param.clientName,
511
+ importSet,
512
+ true,
513
+ param.format === undefined &&
514
+ (param as Parameter).location === "header" &&
515
+ param.type.type === "datetime"
516
+ ? "headerDefault"
517
+ : param.format
518
+ )}`;
454
519
  }
455
520
 
456
521
  type ConstantType = (Parameter | Property) & {
@@ -476,59 +541,33 @@ function isConstant(param: Parameter | Property): param is ConstantType {
476
541
  );
477
542
  }
478
543
 
479
- type OptionalWithoutDefaultType = (Parameter | Property) & {
480
- type: { optional: true; clientDefaultValue: never };
544
+ type OptionalType = (Parameter | Property) & {
545
+ type: { optional: true };
481
546
  };
482
- function isOptionalWithouDefault(
483
- param: Parameter | Property
484
- ): param is OptionalWithoutDefaultType {
485
- return Boolean(param.optional && !param.clientDefaultValue);
486
- }
487
- function getOptionalWithoutDefault(
488
- param: OptionalWithoutDefaultType,
489
- importSet: Map<string, Set<string>>
490
- ) {
491
- if (param.type.type === "model") {
492
- return `"${param.restApiName}": {${getRequestModelMapping(
493
- param.type,
494
- "options?." + param.clientName + "?",
495
- importSet
496
- ).join(", ")}}`;
497
- }
498
- return `"${param.restApiName}": options?.${param.clientName}`;
499
- }
500
547
 
501
- type OptionalWithDefaultType = (Parameter | Property) & {
502
- type: { optional: true; clientDefaultValue: string };
503
- };
504
- function isOptionalWithDefault(
505
- param: Parameter | Property
506
- ): param is OptionalWithDefaultType {
507
- return Boolean(param.clientDefaultValue);
548
+ function isOptional(param: Parameter | Property): param is OptionalType {
549
+ return Boolean(param.optional);
508
550
  }
509
551
 
510
- function getOptionalWithDefault(
511
- param: OptionalWithDefaultType,
512
- importSet: Map<string, Set<string>>
513
- ) {
552
+ function getOptional(param: OptionalType, importSet: Map<string, Set<string>>) {
514
553
  if (param.type.type === "model") {
515
554
  return `"${param.restApiName}": {${getRequestModelMapping(
516
555
  param.type,
517
- "options?." + param.clientName,
556
+ "options?." + param.clientName + "?",
518
557
  importSet
519
- ).join(", ")}} ?? ${getQuotedValue(param)}`;
520
- }
521
- return `"${param.restApiName}": options.${
522
- param.clientName
523
- } ?? ${getQuotedValue(param)}`;
524
- }
525
-
526
- function getQuotedValue(param: OptionalWithDefaultType) {
527
- if (param.type.type === "string") {
528
- return `"${param.clientDefaultValue}"`;
529
- } else {
530
- return param.clientDefaultValue;
558
+ ).join(", ")}}`;
531
559
  }
560
+ return `"${param.restApiName}": ${serializeRequestValue(
561
+ param.type,
562
+ `options?.${param.clientName}`,
563
+ importSet,
564
+ false,
565
+ param.format === undefined &&
566
+ (param as Parameter).location === "header" &&
567
+ param.type.type === "datetime"
568
+ ? "headerDefault"
569
+ : param.format
570
+ )}`;
532
571
  }
533
572
 
534
573
  /**
@@ -601,7 +640,7 @@ function getRequestModelMapping(
601
640
  if (property.readonly) {
602
641
  continue;
603
642
  }
604
- const propertyFullName = `${propertyPath}.${property.restApiName}`;
643
+ const propertyFullName = `${propertyPath}.${property.clientName}`;
605
644
  if (property.type.type === "model") {
606
645
  let definition;
607
646
  if (property.type.isCoreErrorType) {
@@ -611,6 +650,17 @@ function getRequestModelMapping(
611
650
  )} ${
612
651
  !property.optional ? "" : `!${propertyFullName} ? undefined :`
613
652
  } ${propertyFullName}`;
653
+ } else if (
654
+ (property.restApiName === "message" ||
655
+ property.restApiName === "messages") &&
656
+ (property.type.name === "ChatMessage" ||
657
+ property.type.elementType?.name === "ChatMessage")
658
+ ) {
659
+ definition = `"${property.restApiName}": ${
660
+ !property.optional
661
+ ? `${propertyFullName} as any`
662
+ : `!${propertyFullName} ? undefined : ${propertyFullName} as any`
663
+ }`;
614
664
  } else {
615
665
  definition = `"${property.restApiName}": ${getNullableCheck(
616
666
  propertyFullName,
@@ -619,24 +669,38 @@ function getRequestModelMapping(
619
669
  !property.optional ? "" : `!${propertyFullName} ? undefined :`
620
670
  } {${getRequestModelMapping(
621
671
  property.type,
622
- `${propertyPath}.${property.restApiName}${
672
+ `${propertyPath}.${property.clientName}${
623
673
  property.optional ? "?" : ""
624
674
  }`,
625
675
  importSet
626
676
  )}}`;
627
677
  }
628
678
 
679
+ props.push(definition);
680
+ } else if (
681
+ (property.restApiName === "message" ||
682
+ property.restApiName === "messages") &&
683
+ (property.type.name === "ChatMessage" ||
684
+ property.type.elementType?.name === "ChatMessage")
685
+ ) {
686
+ const definition = `"${property.restApiName}": ${
687
+ !property.optional
688
+ ? `${propertyFullName} as any`
689
+ : `!${propertyFullName} ? undefined : ${propertyFullName} as any`
690
+ }`;
629
691
  props.push(definition);
630
692
  } else {
631
693
  const dot = propertyPath.endsWith("?") ? "." : "";
632
- const restValue = `${
694
+ const clientValue = `${
633
695
  propertyPath ? `${propertyPath}${dot}` : `${dot}`
634
696
  }["${property.clientName}"]`;
635
697
  props.push(
636
698
  `"${property.restApiName}": ${serializeRequestValue(
637
699
  property.type,
638
- restValue,
639
- importSet
700
+ clientValue,
701
+ importSet,
702
+ !property.optional,
703
+ property.format
640
704
  )}`
641
705
  );
642
706
  }
@@ -667,6 +731,17 @@ export function getResponseMapping(
667
731
  )} ${
668
732
  !property.optional ? "" : `!${propertyFullName} ? undefined :`
669
733
  } ${propertyFullName}`;
734
+ } else if (
735
+ (property.restApiName === "message" ||
736
+ property.restApiName === "messages") &&
737
+ (property.type.name === "ChatMessage" ||
738
+ property.type.elementType?.name === "ChatMessage")
739
+ ) {
740
+ definition = `"${property.clientName}": ${
741
+ !property.optional
742
+ ? `${propertyFullName} as any`
743
+ : `!${propertyFullName} ? undefined : ${propertyFullName} as any`
744
+ }`;
670
745
  } else {
671
746
  definition = `"${property.clientName}": ${getNullableCheck(
672
747
  propertyFullName,
@@ -688,14 +763,30 @@ export function getResponseMapping(
688
763
  const restValue = `${
689
764
  propertyPath ? `${propertyPath}${dot}` : `${dot}`
690
765
  }["${property.restApiName}"]`;
691
- props.push(
692
- `"${property.clientName}": ${deserializeResponseValue(
693
- property.type,
694
- restValue,
695
- importSet,
696
- property.optional !== undefined ? !property.optional : false
697
- )}`
698
- );
766
+ if (
767
+ (property.restApiName === "message" ||
768
+ property.restApiName === "messages") &&
769
+ (property.type.name === "ChatMessage" ||
770
+ property.type.elementType?.name === "ChatMessage")
771
+ ) {
772
+ props.push(
773
+ `"${property.clientName}": ${
774
+ !property.optional
775
+ ? `${propertyFullName} as any`
776
+ : `!${propertyFullName} ? undefined : ${propertyFullName} as any`
777
+ }`
778
+ );
779
+ } else {
780
+ props.push(
781
+ `"${property.clientName}": ${deserializeResponseValue(
782
+ property.type,
783
+ restValue,
784
+ importSet,
785
+ property.optional !== undefined ? !property.optional : false,
786
+ property.format
787
+ )}`
788
+ );
789
+ }
699
790
  }
700
791
  }
701
792
 
@@ -711,7 +802,8 @@ function deserializeResponseValue(
711
802
  type: Type,
712
803
  restValue: string,
713
804
  importSet: Map<string, Set<string>>,
714
- required: boolean
805
+ required: boolean,
806
+ format?: string
715
807
  ): string {
716
808
  const coreUtilSet = importSet.get("@azure/core-util");
717
809
  switch (type.type) {
@@ -728,14 +820,13 @@ function deserializeResponseValue(
728
820
  "p",
729
821
  importSet
730
822
  )}}))`;
731
- } else if (
732
- type.elementType?.properties?.some((p) => needsDeserialize(p.type))
733
- ) {
823
+ } else if (needsDeserialize(type.elementType)) {
734
824
  return `(${restValue} ?? []).map(p => ${deserializeResponseValue(
735
825
  type.elementType!,
736
826
  "p",
737
827
  importSet,
738
- required
828
+ required,
829
+ type.elementType?.format
739
830
  )})`;
740
831
  } else {
741
832
  return restValue;
@@ -750,7 +841,7 @@ function deserializeResponseValue(
750
841
  coreUtilSet.add("stringToUint8Array");
751
842
  }
752
843
  return `typeof ${restValue} === 'string'
753
- ? stringToUint8Array(${restValue}, "${type.format ?? "base64"}")
844
+ ? stringToUint8Array(${restValue}, "${format ?? "base64"}")
754
845
  : ${restValue}`;
755
846
  default:
756
847
  return restValue;
@@ -764,30 +855,45 @@ function deserializeResponseValue(
764
855
  */
765
856
  function serializeRequestValue(
766
857
  type: Type,
767
- restValue: string,
768
- importSet: Map<string, Set<string>> = new Map<string, Set<string>>()
858
+ clientValue: string,
859
+ importSet: Map<string, Set<string>>,
860
+ required: boolean,
861
+ format?: string
769
862
  ): string {
770
863
  const coreUtilSet = importSet.get("@azure/core-util");
771
864
  switch (type.type) {
772
865
  case "datetime":
773
- return `${restValue} !== undefined ? new Date(${restValue}): undefined`;
866
+ switch (type.format ?? format) {
867
+ case "date":
868
+ return `${clientValue}${required ? "" : "?"}.toDateString()`;
869
+ case "time":
870
+ return `${clientValue}${required ? "" : "?"}.toTimeString()`;
871
+ case "rfc7231":
872
+ case "headerDefault":
873
+ return `${clientValue}${required ? "" : "?"}.toUTCString()`;
874
+ case "unixTimestamp":
875
+ return `${clientValue}${required ? "" : "?"}.getTime()`;
876
+ case "rfc3339":
877
+ default:
878
+ return `${clientValue}${required ? "" : "?"}.toISOString()`;
879
+ }
774
880
  case "list":
775
881
  if (type.elementType?.type === "model") {
776
- return `(${restValue} ?? []).map(p => ({${getResponseMapping(
777
- type.elementType?.properties ?? [],
882
+ return `(${clientValue} ?? []).map(p => ({${getRequestModelMapping(
883
+ type.elementType,
778
884
  "p",
779
885
  importSet
780
886
  )}}))`;
781
- } else if (
782
- type.elementType?.properties?.some((p) => needsDeserialize(p.type))
783
- ) {
784
- return `(${restValue} ?? []).map(p => ${serializeRequestValue(
887
+ } else if (needsDeserialize(type.elementType)) {
888
+ return `(${clientValue} ?? []).map(p => ${serializeRequestValue(
785
889
  type.elementType!,
786
890
  "p",
787
- importSet
891
+ importSet,
892
+ required,
893
+ type.elementType?.format
788
894
  )})`;
789
895
  } else {
790
- return restValue;
896
+ return clientValue;
791
897
  }
792
898
  case "byte-array":
793
899
  if (!coreUtilSet) {
@@ -798,16 +904,23 @@ function serializeRequestValue(
798
904
  } else {
799
905
  coreUtilSet.add("uint8ArrayToString");
800
906
  }
801
- return `${restValue} !== undefined ? uint8ArrayToString(${restValue}, "${
802
- type.format ?? "base64"
803
- }"): undefined`;
907
+ return required
908
+ ? `uint8ArrayToString(${clientValue}, "${format ?? "base64"}")`
909
+ : `${clientValue} !== undefined ? uint8ArrayToString(${clientValue}, "${
910
+ format ?? "base64"
911
+ }"): undefined`;
804
912
  default:
805
- return restValue;
913
+ return clientValue;
806
914
  }
807
915
  }
808
916
 
809
917
  function needsDeserialize(type?: Type) {
810
- return type?.type === "datetime" || type?.type === "model";
918
+ return (
919
+ type?.type === "datetime" ||
920
+ type?.type === "model" ||
921
+ type?.type === "list" ||
922
+ type?.type === "byte-array"
923
+ );
811
924
  }
812
925
 
813
926
  export function hasLROOperation(codeModel: ModularCodeModel) {
@@ -15,7 +15,7 @@ function getNullableType(name: string, type: Type): string {
15
15
  return name;
16
16
  }
17
17
 
18
- export function getType(type: Type): TypeMetadata {
18
+ export function getType(type: Type, format?: string): TypeMetadata {
19
19
  switch (type.type) {
20
20
  case "Key":
21
21
  return {
@@ -58,7 +58,7 @@ export function getType(type: Type): TypeMetadata {
58
58
  throw new Error("Unable to process Array with no elementType");
59
59
  }
60
60
  return {
61
- name: getNullableType(getType(type.elementType).name, type),
61
+ name: getNullableType(getType(type.elementType, type.elementType.format).name, type),
62
62
  modifier: "Array",
63
63
  originModule:
64
64
  type.elementType?.type === "model" ? "models.js" : undefined
@@ -73,14 +73,20 @@ export function getType(type: Type): TypeMetadata {
73
73
  };
74
74
  case "string":
75
75
  case "duration":
76
- return { name: getNullableType("string", type) };
76
+ switch (format) {
77
+ case "seconds":
78
+ return { name: getNullableType("number", type) };
79
+ case "ISO8601":
80
+ default:
81
+ return { name: getNullableType("string", type) };
82
+ }
77
83
  case "combined": {
78
84
  if (!type.types) {
79
85
  throw new Error("Unable to process combined without combinedTypes");
80
86
  }
81
87
  const name = type.types
82
88
  .map((t) => {
83
- const sdkType = getTypeName(getType(t));
89
+ const sdkType = getTypeName(getType(t, t.format));
84
90
  return `${sdkType}`;
85
91
  })
86
92
  .join(" | ");
@@ -91,7 +97,7 @@ export function getType(type: Type): TypeMetadata {
91
97
  throw new Error("Unable to process dict without elemetType info");
92
98
  }
93
99
  return {
94
- name: `Record<string, ${getTypeName(getType(type.elementType))}>`
100
+ name: `Record<string, ${getTypeName(getType(type.elementType, type.elementType.format))}>`
95
101
  };
96
102
  case "any":
97
103
  return {
@@ -118,13 +124,14 @@ function getTypeName(typeMetadata: TypeMetadata) {
118
124
  */
119
125
  export function buildType(
120
126
  clientName: string | undefined,
121
- type: Type | undefined
127
+ type: Type | undefined,
128
+ format: string | undefined
122
129
  ) {
123
130
  if (!type) {
124
131
  throw new Error("Type should be defined");
125
132
  }
126
133
 
127
- const typeMetadata = getType(type);
134
+ const typeMetadata = getType(type, format);
128
135
  let typeName = typeMetadata.name;
129
136
  if (typeMetadata.modifier === "Array") {
130
137
  typeName = `${typeName}[]`;