@azure-tools/typespec-ts 0.11.0 → 0.12.0-alpha.20230501.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 (412) hide show
  1. package/.rush/temp/package-deps_build.json +265 -152
  2. package/.rush/temp/shrinkwrap-deps.json +58 -54
  3. package/CHANGELOG.md +4 -0
  4. package/CONTRIBUTING.md +5 -2
  5. package/README.md +3 -3
  6. package/dist/src/casingUtils.d.ts +4 -0
  7. package/dist/src/casingUtils.d.ts.map +1 -0
  8. package/dist/src/casingUtils.js +39 -0
  9. package/dist/src/casingUtils.js.map +1 -0
  10. package/dist/src/emitUtil.js +7 -1
  11. package/dist/src/emitUtil.js.map +1 -1
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/index.js +41 -9
  14. package/dist/src/index.js.map +1 -1
  15. package/dist/src/lib.d.ts.map +1 -1
  16. package/dist/src/lib.js +2 -1
  17. package/dist/src/lib.js.map +1 -1
  18. package/dist/src/modelUtils.d.ts +22 -1
  19. package/dist/src/modelUtils.d.ts.map +1 -1
  20. package/dist/src/modelUtils.js +105 -13
  21. package/dist/src/modelUtils.js.map +1 -1
  22. package/dist/src/modular/buildApiIndex.d.ts +3 -0
  23. package/dist/src/modular/buildApiIndex.d.ts.map +1 -0
  24. package/dist/src/modular/buildApiIndex.js +12 -0
  25. package/dist/src/modular/buildApiIndex.js.map +1 -0
  26. package/dist/src/modular/buildClassicalClient.d.ts +4 -0
  27. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -0
  28. package/dist/src/modular/buildClassicalClient.js +112 -0
  29. package/dist/src/modular/buildClassicalClient.js.map +1 -0
  30. package/dist/src/modular/buildClientContext.d.ts +7 -0
  31. package/dist/src/modular/buildClientContext.d.ts.map +1 -0
  32. package/dist/src/modular/buildClientContext.js +72 -0
  33. package/dist/src/modular/buildClientContext.js.map +1 -0
  34. package/dist/src/modular/buildCodeModel.d.ts +14 -0
  35. package/dist/src/modular/buildCodeModel.d.ts.map +1 -0
  36. package/dist/src/modular/buildCodeModel.js +1110 -0
  37. package/dist/src/modular/buildCodeModel.js.map +1 -0
  38. package/dist/src/modular/buildOperations.d.ts +13 -0
  39. package/dist/src/modular/buildOperations.d.ts.map +1 -0
  40. package/dist/src/modular/buildOperations.js +70 -0
  41. package/dist/src/modular/buildOperations.js.map +1 -0
  42. package/dist/src/modular/buildProjectFiles.d.ts +5 -0
  43. package/dist/src/modular/buildProjectFiles.d.ts.map +1 -0
  44. package/dist/src/modular/buildProjectFiles.js +182 -0
  45. package/dist/src/modular/buildProjectFiles.js.map +1 -0
  46. package/dist/src/modular/buildRootIndex.d.ts +4 -0
  47. package/dist/src/modular/buildRootIndex.d.ts.map +1 -0
  48. package/dist/src/modular/buildRootIndex.js +66 -0
  49. package/dist/src/modular/buildRootIndex.js.map +1 -0
  50. package/dist/src/modular/buildSharedTypes.d.ts +6 -0
  51. package/dist/src/modular/buildSharedTypes.d.ts.map +1 -0
  52. package/dist/src/modular/buildSharedTypes.js +33 -0
  53. package/dist/src/modular/buildSharedTypes.js.map +1 -0
  54. package/dist/src/modular/emitModels.d.ts +7 -0
  55. package/dist/src/modular/emitModels.d.ts.map +1 -0
  56. package/dist/src/modular/emitModels.js +63 -0
  57. package/dist/src/modular/emitModels.js.map +1 -0
  58. package/dist/src/modular/helpers/clientHelpers.d.ts +4 -0
  59. package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -0
  60. package/dist/src/modular/helpers/clientHelpers.js +31 -0
  61. package/dist/src/modular/helpers/clientHelpers.js.map +1 -0
  62. package/dist/src/modular/helpers/credentialHelpers.d.ts +7 -0
  63. package/dist/src/modular/helpers/credentialHelpers.d.ts.map +1 -0
  64. package/dist/src/modular/helpers/credentialHelpers.js +32 -0
  65. package/dist/src/modular/helpers/credentialHelpers.js.map +1 -0
  66. package/dist/src/modular/helpers/namingHelpers.d.ts +3 -0
  67. package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -0
  68. package/dist/src/modular/helpers/namingHelpers.js +4 -0
  69. package/dist/src/modular/helpers/namingHelpers.js.map +1 -0
  70. package/dist/src/modular/helpers/operationHelpers.d.ts +8 -0
  71. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -0
  72. package/dist/src/modular/helpers/operationHelpers.js +274 -0
  73. package/dist/src/modular/helpers/operationHelpers.js.map +1 -0
  74. package/dist/src/modular/helpers/parameterHelpers.d.ts +3 -0
  75. package/dist/src/modular/helpers/parameterHelpers.d.ts.map +1 -0
  76. package/dist/src/modular/helpers/parameterHelpers.js +16 -0
  77. package/dist/src/modular/helpers/parameterHelpers.js.map +1 -0
  78. package/dist/src/modular/helpers/typeHelpers.d.ts +16 -0
  79. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -0
  80. package/dist/src/modular/helpers/typeHelpers.js +92 -0
  81. package/dist/src/modular/helpers/typeHelpers.js.map +1 -0
  82. package/dist/src/modular/interfaces.d.ts +10 -0
  83. package/dist/src/modular/interfaces.d.ts.map +1 -0
  84. package/dist/src/modular/interfaces.js +2 -0
  85. package/dist/src/modular/interfaces.js.map +1 -0
  86. package/dist/src/modular/modularCodeModel.d.ts +121 -0
  87. package/dist/src/modular/modularCodeModel.d.ts.map +1 -0
  88. package/dist/src/modular/modularCodeModel.js +2 -0
  89. package/dist/src/modular/modularCodeModel.js.map +1 -0
  90. package/dist/src/operationUtil.d.ts +30 -4
  91. package/dist/src/operationUtil.d.ts.map +1 -1
  92. package/dist/src/operationUtil.js +77 -18
  93. package/dist/src/operationUtil.js.map +1 -1
  94. package/dist/src/transform/transform.d.ts +4 -6
  95. package/dist/src/transform/transform.d.ts.map +1 -1
  96. package/dist/src/transform/transform.js +17 -58
  97. package/dist/src/transform/transform.js.map +1 -1
  98. package/dist/src/transform/transformApiVersionInfo.d.ts +5 -0
  99. package/dist/src/transform/transformApiVersionInfo.d.ts.map +1 -0
  100. package/dist/src/transform/transformApiVersionInfo.js +64 -0
  101. package/dist/src/transform/transformApiVersionInfo.js.map +1 -0
  102. package/dist/src/transform/transformHelperFunctionDetails.d.ts +6 -0
  103. package/dist/src/transform/transformHelperFunctionDetails.d.ts.map +1 -0
  104. package/dist/src/transform/{transformAnnotationDetails.js → transformHelperFunctionDetails.js} +2 -2
  105. package/dist/src/transform/transformHelperFunctionDetails.js.map +1 -0
  106. package/dist/src/transform/transformParameters.d.ts +2 -2
  107. package/dist/src/transform/transformParameters.d.ts.map +1 -1
  108. package/dist/src/transform/transformParameters.js +20 -7
  109. package/dist/src/transform/transformParameters.js.map +1 -1
  110. package/dist/src/transform/transformPaths.d.ts +2 -2
  111. package/dist/src/transform/transformPaths.d.ts.map +1 -1
  112. package/dist/src/transform/transformPaths.js +15 -7
  113. package/dist/src/transform/transformPaths.js.map +1 -1
  114. package/dist/src/transform/transformResponses.d.ts +2 -2
  115. package/dist/src/transform/transformResponses.d.ts.map +1 -1
  116. package/dist/src/transform/transformResponses.js +23 -2
  117. package/dist/src/transform/transformResponses.js.map +1 -1
  118. package/dist/src/transform/transformSchemas.d.ts +2 -2
  119. package/dist/src/transform/transformSchemas.d.ts.map +1 -1
  120. package/dist/src/transform/transformSchemas.js +10 -22
  121. package/dist/src/transform/transformSchemas.js.map +1 -1
  122. package/dist/src/transform/transfromRLCOptions.d.ts +2 -2
  123. package/dist/src/transform/transfromRLCOptions.js +1 -1
  124. package/dist/src/transform/transfromRLCOptions.js.map +1 -1
  125. package/dist/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +27 -19
  127. package/src/casingUtils.ts +48 -0
  128. package/src/emitUtil.ts +9 -4
  129. package/src/index.ts +53 -10
  130. package/src/lib.ts +2 -1
  131. package/src/modelUtils.ts +137 -14
  132. package/src/modular/buildApiIndex.ts +13 -0
  133. package/src/modular/buildClassicalClient.ts +147 -0
  134. package/src/modular/buildClientContext.ts +104 -0
  135. package/src/modular/buildCodeModel.ts +1449 -0
  136. package/src/modular/buildOperations.ts +95 -0
  137. package/src/modular/buildProjectFiles.ts +219 -0
  138. package/src/modular/buildRootIndex.ts +94 -0
  139. package/src/modular/buildSharedTypes.ts +40 -0
  140. package/src/modular/emitModels.ts +72 -0
  141. package/src/modular/helpers/clientHelpers.ts +38 -0
  142. package/src/modular/helpers/credentialHelpers.ts +40 -0
  143. package/src/modular/helpers/namingHelpers.ts +5 -0
  144. package/src/modular/helpers/operationHelpers.ts +418 -0
  145. package/src/modular/helpers/parameterHelpers.ts +17 -0
  146. package/src/modular/helpers/typeHelpers.ts +106 -0
  147. package/src/modular/interfaces.ts +10 -0
  148. package/src/modular/modularCodeModel.ts +151 -0
  149. package/src/modular/static/karma.conf.cjs +120 -0
  150. package/src/modular/static/rollup.test.config.js +67 -0
  151. package/src/modular/static/scripts/renameOutput.mjs +17 -0
  152. package/src/operationUtil.ts +119 -31
  153. package/src/transform/transform.ts +33 -96
  154. package/src/transform/transformApiVersionInfo.ts +108 -0
  155. package/src/transform/{transformAnnotationDetails.ts → transformHelperFunctionDetails.ts} +11 -11
  156. package/src/transform/transformParameters.ts +30 -14
  157. package/src/transform/transformPaths.ts +29 -19
  158. package/src/transform/transformResponses.ts +50 -8
  159. package/src/transform/transformSchemas.ts +20 -28
  160. package/src/transform/transfromRLCOptions.ts +3 -3
  161. package/test/commands/cadl-ranch-list.ts +53 -20
  162. package/test/commands/gen-cadl-ranch.ts +6 -2
  163. package/test/commands/run.ts +3 -13
  164. package/test/integration/arrayItemTypes.spec.ts +6 -3
  165. package/test/integration/azurecore.spec.ts +130 -0
  166. package/test/integration/collectionFormat.spec.ts +118 -0
  167. package/test/integration/dictionary.spec.ts +6 -2
  168. package/test/integration/extensibleEnums.spec.ts +8 -8
  169. package/test/integration/fixedEnums.spec.ts +7 -7
  170. package/test/integration/generated/arrays/itemTypes/src/clientDefinitions.ts +33 -18
  171. package/test/integration/generated/arrays/itemTypes/src/parameters.ts +8 -0
  172. package/test/integration/generated/arrays/itemTypes/src/responses.ts +11 -0
  173. package/test/integration/generated/arrays/itemTypes/tspconfig.yaml +5 -2
  174. package/test/integration/generated/authentication/apiKey/package.json +2 -2
  175. package/test/integration/generated/authentication/apiKey/tspconfig.yaml +5 -2
  176. package/test/integration/generated/authentication/oauth2/tspconfig.yaml +5 -2
  177. package/test/integration/generated/authentication/union/tspconfig.yaml +5 -2
  178. package/test/integration/generated/{resiliency/devDriven → azure/core}/README.md +7 -7
  179. package/test/integration/generated/{lro/lroBasic → azure/core}/api-extractor.json +1 -1
  180. package/test/integration/generated/{resiliency/devDriven → azure/core}/package.json +6 -6
  181. package/test/integration/generated/azure/core/src/azureCoreClient.ts +31 -0
  182. package/test/integration/generated/azure/core/src/clientDefinitions.ts +108 -0
  183. package/test/integration/generated/{resiliency/devDriven → azure/core}/src/index.ts +4 -3
  184. package/test/integration/generated/azure/core/src/isUnexpected.ts +178 -0
  185. package/test/integration/generated/azure/core/src/models.ts +18 -0
  186. package/test/integration/generated/azure/core/src/outputModels.ts +32 -0
  187. package/test/integration/generated/{resiliency/devDriven → azure/core}/src/paginateHelper.ts +55 -5
  188. package/test/integration/generated/azure/core/src/parameters.ts +68 -0
  189. package/test/integration/generated/azure/core/src/responses.ts +158 -0
  190. package/test/integration/generated/azure/core/src/serializeHelper.ts +16 -0
  191. package/test/integration/generated/azure/core/tspconfig.yaml +15 -0
  192. package/test/integration/generated/azure/core-traits/README.md +56 -0
  193. package/test/integration/generated/azure/core-traits/api-extractor.json +18 -0
  194. package/test/integration/generated/azure/core-traits/package.json +80 -0
  195. package/test/integration/generated/azure/core-traits/src/azureCoreTraitsClient.ts +31 -0
  196. package/test/integration/generated/azure/core-traits/src/clientDefinitions.ts +22 -0
  197. package/test/integration/generated/azure/core-traits/src/index.ts +13 -0
  198. package/test/integration/generated/{resiliency/devDriven → azure/core-traits}/src/isUnexpected.ts +6 -26
  199. package/test/integration/generated/azure/core-traits/src/outputModels.ts +10 -0
  200. package/test/integration/generated/azure/core-traits/src/parameters.ts +26 -0
  201. package/test/integration/generated/azure/core-traits/src/responses.ts +32 -0
  202. package/test/integration/generated/azure/core-traits/tspconfig.yaml +15 -0
  203. package/test/integration/generated/dictionary/package.json +2 -2
  204. package/test/integration/generated/dictionary/src/clientDefinitions.ts +35 -20
  205. package/test/integration/generated/dictionary/src/parameters.ts +8 -0
  206. package/test/integration/generated/dictionary/src/responses.ts +11 -0
  207. package/test/integration/generated/dictionary/tspconfig.yaml +5 -2
  208. package/test/integration/generated/enums/extensible/README.md +3 -3
  209. package/test/integration/generated/enums/extensible/package.json +2 -2
  210. package/test/integration/generated/enums/extensible/src/clientDefinitions.ts +5 -5
  211. package/test/integration/generated/enums/extensible/src/index.ts +3 -3
  212. package/test/integration/generated/enums/extensible/src/{enumsExtensible.ts → typeEnumExtensible.ts} +4 -4
  213. package/test/integration/generated/enums/extensible/tspconfig.yaml +5 -2
  214. package/test/integration/generated/enums/fixed/README.md +3 -3
  215. package/test/integration/generated/enums/fixed/package.json +2 -2
  216. package/test/integration/generated/enums/fixed/src/clientDefinitions.ts +5 -5
  217. package/test/integration/generated/enums/fixed/src/index.ts +3 -3
  218. package/test/integration/generated/enums/fixed/src/{enumsFixed.ts → typeEnumFixed.ts} +4 -4
  219. package/test/integration/generated/enums/fixed/tspconfig.yaml +5 -2
  220. package/test/integration/generated/hello/package.json +2 -2
  221. package/test/integration/generated/hello/tspconfig.yaml +5 -2
  222. package/test/integration/generated/internal/src/clientDefinitions.ts +27 -0
  223. package/test/integration/generated/internal/src/index.ts +13 -0
  224. package/test/integration/generated/{lro/lroBasic/src/azureLro.ts → internal/src/internalClient.ts} +5 -5
  225. package/test/integration/generated/internal/src/models.ts +8 -0
  226. package/test/integration/generated/internal/src/outputModels.ts +13 -0
  227. package/test/integration/generated/internal/src/parameters.ts +21 -0
  228. package/test/integration/generated/internal/src/responses.ts +20 -0
  229. package/test/integration/generated/internal/tspconfig.yaml +14 -0
  230. package/test/integration/generated/lro/lroCore/.eslintrc.json +11 -0
  231. package/test/integration/generated/lro/lroCore/README.md +56 -0
  232. package/test/integration/generated/{resiliency/devDriven → lro/lroCore}/api-extractor.json +1 -1
  233. package/test/integration/generated/lro/{lroBasic → lroCore}/package.json +6 -6
  234. package/test/integration/generated/lro/lroCore/rollup.config.js +118 -0
  235. package/test/integration/generated/lro/lroCore/src/clientDefinitions.ts +54 -0
  236. package/test/integration/generated/lro/lroCore/src/index.ts +15 -0
  237. package/test/integration/generated/lro/lroCore/src/isUnexpected.ts +135 -0
  238. package/test/integration/generated/lro/lroCore/src/models.ts +8 -0
  239. package/test/integration/generated/lro/lroCore/src/outputModels.ts +50 -0
  240. package/test/integration/generated/lro/lroCore/src/parameters.ts +25 -0
  241. package/test/integration/generated/lro/{lroBasic → lroCore}/src/pollingHelper.ts +38 -0
  242. package/test/integration/generated/lro/lroCore/src/responses.ts +109 -0
  243. package/test/integration/generated/lro/lroCore/src/specsAzureCoreLroStandard.ts +31 -0
  244. package/test/integration/generated/lro/lroCore/tsconfig.json +25 -0
  245. package/test/integration/generated/lro/lroCore/tspconfig.yaml +14 -0
  246. package/test/integration/generated/lro/lroRPC/.eslintrc.json +11 -0
  247. package/test/integration/generated/lro/{lroBasic → lroRPC}/README.md +7 -7
  248. package/test/integration/generated/lro/lroRPC/api-extractor.json +18 -0
  249. package/test/integration/generated/lro/lroRPC/package.json +82 -0
  250. package/test/integration/generated/lro/lroRPC/rollup.config.js +118 -0
  251. package/test/integration/generated/lro/lroRPC/src/clientDefinitions.ts +79 -0
  252. package/test/integration/generated/lro/lroRPC/src/index.ts +15 -0
  253. package/test/integration/generated/lro/lroRPC/src/isUnexpected.ts +153 -0
  254. package/test/integration/generated/lro/lroRPC/src/models.ts +8 -0
  255. package/test/integration/generated/lro/lroRPC/src/outputModels.ts +40 -0
  256. package/test/integration/generated/lro/lroRPC/src/parameters.ts +20 -0
  257. package/test/integration/generated/lro/lroRPC/src/pollingHelper.ts +127 -0
  258. package/test/integration/generated/lro/lroRPC/src/responses.ts +124 -0
  259. package/test/integration/generated/lro/lroRPC/src/specsAzureCoreLroRpc.ts +31 -0
  260. package/test/integration/generated/lro/lroRPC/tsconfig.json +25 -0
  261. package/test/integration/generated/lro/lroRPC/tspconfig.yaml +14 -0
  262. package/test/integration/generated/models/inheritance/README.md +3 -3
  263. package/test/integration/generated/models/inheritance/package.json +2 -2
  264. package/test/integration/generated/models/inheritance/src/clientDefinitions.ts +13 -11
  265. package/test/integration/generated/models/inheritance/src/index.ts +3 -3
  266. package/test/integration/generated/models/inheritance/src/{modelsInheritance.ts → typeModelInheritance.ts} +4 -4
  267. package/test/integration/generated/models/inheritance/tspconfig.yaml +5 -2
  268. package/test/integration/generated/models/propertyNullable/.eslintrc.json +11 -0
  269. package/test/integration/generated/models/propertyNullable/README.md +56 -0
  270. package/test/integration/generated/models/propertyNullable/api-extractor.json +18 -0
  271. package/test/integration/generated/models/propertyNullable/package.json +80 -0
  272. package/test/integration/generated/models/propertyNullable/rollup.config.js +118 -0
  273. package/test/integration/generated/models/propertyNullable/src/clientDefinitions.ts +227 -0
  274. package/test/integration/generated/models/propertyNullable/src/index.ts +13 -0
  275. package/test/integration/generated/models/propertyNullable/src/models.ts +56 -0
  276. package/test/integration/generated/models/propertyNullable/src/outputModels.ts +56 -0
  277. package/test/integration/generated/models/propertyNullable/src/parameters.ts +197 -0
  278. package/test/integration/generated/models/propertyNullable/src/responses.ts +144 -0
  279. package/test/integration/generated/{resiliency/devDriven/src/resiliencyDevDriven.ts → models/propertyNullable/src/typePropertyNullable.ts} +5 -5
  280. package/test/integration/generated/models/propertyNullable/tsconfig.json +25 -0
  281. package/test/integration/generated/models/propertyNullable/tspconfig.yaml +14 -0
  282. package/test/integration/generated/models/propertyOptional/README.md +3 -3
  283. package/test/integration/generated/models/propertyOptional/package.json +2 -2
  284. package/test/integration/generated/models/propertyOptional/src/clientDefinitions.ts +47 -47
  285. package/test/integration/generated/models/propertyOptional/src/index.ts +3 -3
  286. package/test/integration/generated/models/propertyOptional/src/parameters.ts +7 -6
  287. package/test/integration/generated/models/propertyOptional/src/responses.ts +4 -4
  288. package/test/integration/generated/models/propertyOptional/src/{modelsPropertyOptional.ts → typePropertyOptional.ts} +4 -4
  289. package/test/integration/generated/models/propertyOptional/tspconfig.yaml +5 -2
  290. package/test/integration/generated/models/propertyTypes/README.md +3 -3
  291. package/test/integration/generated/models/propertyTypes/package.json +2 -2
  292. package/test/integration/generated/models/propertyTypes/src/clientDefinitions.ts +55 -47
  293. package/test/integration/generated/models/propertyTypes/src/index.ts +3 -3
  294. package/test/integration/generated/models/propertyTypes/src/parameters.ts +8 -6
  295. package/test/integration/generated/models/propertyTypes/src/responses.ts +4 -4
  296. package/test/integration/generated/models/propertyTypes/src/{modelsPropertyTypes.ts → typePropertyValueTypes.ts} +4 -4
  297. package/test/integration/generated/models/propertyTypes/tspconfig.yaml +5 -2
  298. package/test/integration/generated/models/usage/README.md +3 -3
  299. package/test/integration/generated/models/usage/package.json +2 -2
  300. package/test/integration/generated/models/usage/src/clientDefinitions.ts +7 -7
  301. package/test/integration/generated/models/usage/src/index.ts +3 -3
  302. package/test/integration/generated/models/usage/src/{modelsUsage.ts → typeModelUsage.ts} +4 -4
  303. package/test/integration/generated/models/usage/tspconfig.yaml +5 -2
  304. package/test/integration/generated/models/visibility/README.md +3 -3
  305. package/test/integration/generated/models/visibility/package.json +2 -2
  306. package/test/integration/generated/models/visibility/src/clientDefinitions.ts +3 -3
  307. package/test/integration/generated/models/visibility/src/index.ts +3 -3
  308. package/test/integration/generated/models/visibility/src/{modelsVisibilityAutomatic.ts → typeModelVisibility.ts} +4 -4
  309. package/test/integration/generated/models/visibility/tspconfig.yaml +5 -2
  310. package/test/integration/generated/parameters/collection-format/src/clientDefinitions.ts +63 -0
  311. package/test/integration/generated/parameters/collection-format/src/collectionFormatClient.ts +31 -0
  312. package/test/integration/generated/parameters/collection-format/src/index.ts +12 -0
  313. package/test/integration/generated/parameters/collection-format/src/parameters.ts +71 -0
  314. package/test/integration/generated/parameters/collection-format/src/responses.ts +34 -0
  315. package/test/integration/generated/parameters/collection-format/src/serializeHelper.ts +28 -0
  316. package/test/integration/generated/parameters/collection-format/tspconfig.yaml +14 -0
  317. package/test/integration/generated/parameters/spread/src/clientDefinitions.ts +61 -0
  318. package/test/integration/generated/{lro/lroBasic → parameters/spread}/src/index.ts +4 -4
  319. package/test/integration/generated/parameters/spread/src/models.ts +7 -0
  320. package/test/integration/generated/parameters/spread/src/parameters.ts +61 -0
  321. package/test/integration/generated/parameters/spread/src/parametersSpread.ts +31 -0
  322. package/test/integration/generated/parameters/spread/src/responses.ts +25 -0
  323. package/test/integration/generated/parameters/spread/tspconfig.yaml +12 -0
  324. package/test/integration/generated/projection/src/clientDefinitions.ts +71 -0
  325. package/test/integration/generated/projection/src/index.ts +12 -0
  326. package/test/integration/generated/projection/src/models.ts +22 -0
  327. package/test/integration/generated/projection/src/parameters.ts +48 -0
  328. package/test/integration/generated/projection/src/projectionClient.ts +31 -0
  329. package/test/integration/generated/projection/src/responses.ts +34 -0
  330. package/test/integration/generated/projection/tspconfig.yaml +14 -0
  331. package/test/integration/generated/resiliency/srvDriven1/README.md +4 -4
  332. package/test/integration/generated/resiliency/srvDriven1/package.json +2 -2
  333. package/test/integration/generated/resiliency/srvDriven1/src/clientDefinitions.ts +25 -49
  334. package/test/integration/generated/resiliency/srvDriven1/src/index.ts +3 -5
  335. package/test/integration/generated/resiliency/srvDriven1/src/parameters.ts +11 -32
  336. package/test/integration/generated/resiliency/srvDriven1/src/responses.ts +9 -24
  337. package/test/integration/generated/resiliency/srvDriven1/src/serviceDrivenOldClient.ts +39 -0
  338. package/test/integration/generated/resiliency/srvDriven1/tspconfig.yaml +6 -2
  339. package/test/integration/generated/resiliency/srvDriven2/README.md +13 -4
  340. package/test/integration/generated/resiliency/srvDriven2/package.json +2 -2
  341. package/test/integration/generated/resiliency/srvDriven2/src/clientDefinitions.ts +32 -68
  342. package/test/integration/generated/resiliency/srvDriven2/src/index.ts +3 -5
  343. package/test/integration/generated/resiliency/srvDriven2/src/parameters.ts +19 -42
  344. package/test/integration/generated/resiliency/srvDriven2/src/responses.ts +10 -31
  345. package/test/integration/generated/resiliency/srvDriven2/src/serviceDrivenNewClient.ts +39 -0
  346. package/test/integration/generated/resiliency/srvDriven2/tspconfig.yaml +6 -2
  347. package/test/integration/generated/server/path/multiple/src/clientDefinitions.ts +35 -0
  348. package/test/integration/generated/server/path/multiple/src/index.ts +11 -0
  349. package/test/integration/generated/server/path/multiple/src/multipleParamInServerPathClient.ts +39 -0
  350. package/test/integration/generated/server/path/multiple/src/parameters.ts +7 -0
  351. package/test/integration/generated/server/path/multiple/src/responses.ts +14 -0
  352. package/test/integration/generated/server/path/multiple/tspconfig.yaml +14 -0
  353. package/test/integration/generated/server/path/single/src/clientDefinitions.ts +19 -0
  354. package/test/integration/generated/server/path/single/src/index.ts +11 -0
  355. package/test/integration/generated/server/path/single/src/parameters.ts +6 -0
  356. package/test/integration/generated/server/path/single/src/responses.ts +9 -0
  357. package/test/integration/generated/server/path/single/src/singleParamInServerPathClient.ts +34 -0
  358. package/test/integration/generated/server/path/single/tspconfig.yaml +14 -0
  359. package/test/integration/generated/specialWords/tspconfig.yaml +5 -2
  360. package/test/integration/generated/unions/src/clientDefinitions.ts +8 -8
  361. package/test/integration/generated/unions/tspconfig.yaml +5 -2
  362. package/test/integration/internal.spec.ts +43 -0
  363. package/test/integration/lroCore.spec.ts +89 -0
  364. package/test/integration/modelInheritance.spec.ts +13 -13
  365. package/test/integration/modelPropertyNullable.spec.ts +115 -0
  366. package/test/integration/modelPropertyOptional.spec.ts +32 -32
  367. package/test/integration/modelPropertyType.spec.ts +6 -6
  368. package/test/integration/modelUsage.spec.ts +7 -7
  369. package/test/integration/projection.spec.ts +102 -0
  370. package/test/integration/resiliencyDpgCustomization.spec.ts +69 -35
  371. package/test/integration/server.spec.ts +59 -0
  372. package/test/integration/spreadParameters.spec.ts +82 -0
  373. package/test/integration/unions.spec.ts +4 -4
  374. package/test/unit/apiVersion.spec.ts +388 -0
  375. package/test/unit/clientFactoryGenerator.spec.ts +0 -131
  376. package/test/unit/modelsGenerator.spec.ts +2 -2
  377. package/test/unit/parametersGenerator.spec.ts +1 -1
  378. package/test/unit/responsesGenerator.spec.ts +1 -1
  379. package/test/unit/util/emitUtil.ts +6 -5
  380. package/test/unit/util/testUtil.ts +3 -3
  381. package/dist/src/transform/transformAnnotationDetails.d.ts +0 -6
  382. package/dist/src/transform/transformAnnotationDetails.d.ts.map +0 -1
  383. package/dist/src/transform/transformAnnotationDetails.js.map +0 -1
  384. package/dist/src/transform/transformApiVersionParam.d.ts +0 -5
  385. package/dist/src/transform/transformApiVersionParam.d.ts.map +0 -1
  386. package/dist/src/transform/transformApiVersionParam.js +0 -76
  387. package/dist/src/transform/transformApiVersionParam.js.map +0 -1
  388. package/src/transform/transformApiVersionParam.ts +0 -104
  389. package/test/integration/generated/lro/lroBasic/src/clientDefinitions.ts +0 -37
  390. package/test/integration/generated/lro/lroBasic/src/parameters.ts +0 -8
  391. package/test/integration/generated/lro/lroBasic/src/responses.ts +0 -22
  392. package/test/integration/generated/lro/lroBasic/tspconfig.yaml +0 -11
  393. package/test/integration/generated/resiliency/devDriven/src/clientDefinitions.ts +0 -75
  394. package/test/integration/generated/resiliency/devDriven/src/models.ts +0 -8
  395. package/test/integration/generated/resiliency/devDriven/src/outputModels.ts +0 -25
  396. package/test/integration/generated/resiliency/devDriven/src/parameters.ts +0 -17
  397. package/test/integration/generated/resiliency/devDriven/src/responses.ts +0 -62
  398. package/test/integration/generated/resiliency/devDriven/tspconfig.yaml +0 -11
  399. package/test/integration/generated/resiliency/srvDriven1/src/models.ts +0 -6
  400. package/test/integration/generated/resiliency/srvDriven1/src/outputModels.ts +0 -6
  401. package/test/integration/generated/resiliency/srvDriven1/src/resiliencyServiceDriven1.ts +0 -31
  402. package/test/integration/generated/resiliency/srvDriven2/src/models.ts +0 -6
  403. package/test/integration/generated/resiliency/srvDriven2/src/outputModels.ts +0 -6
  404. package/test/integration/generated/resiliency/srvDriven2/src/resiliencyServiceDriven2.ts +0 -31
  405. package/test/integration/helloWorld.spec.ts +0 -20
  406. package/test/integration/lroBasic.spec.ts +0 -25
  407. /package/test/integration/generated/{resiliency/devDriven → azure/core}/.eslintrc.json +0 -0
  408. /package/test/integration/generated/{resiliency/devDriven → azure/core}/rollup.config.js +0 -0
  409. /package/test/integration/generated/{resiliency/devDriven → azure/core}/tsconfig.json +0 -0
  410. /package/test/integration/generated/{lro/lroBasic → azure/core-traits}/.eslintrc.json +0 -0
  411. /package/test/integration/generated/{lro/lroBasic → azure/core-traits}/rollup.config.js +0 -0
  412. /package/test/integration/generated/{lro/lroBasic → azure/core-traits}/tsconfig.json +0 -0
@@ -0,0 +1,1449 @@
1
+ import { getPagedResult, isFixed } from "@azure-tools/typespec-azure-core";
2
+ import {
3
+ EnumMember,
4
+ Enum,
5
+ getDoc,
6
+ getFriendlyName,
7
+ getMaxLength,
8
+ getMaxValue,
9
+ getMinLength,
10
+ getMinValue,
11
+ getPattern,
12
+ getSummary,
13
+ getVisibility,
14
+ ignoreDiagnostics,
15
+ isErrorModel,
16
+ isNeverType,
17
+ Model,
18
+ ModelProperty,
19
+ Namespace,
20
+ Program,
21
+ getEffectiveModelType,
22
+ getDiscriminator,
23
+ Operation,
24
+ isKey,
25
+ Scalar,
26
+ IntrinsicScalarName,
27
+ isStringType,
28
+ getPropertyType,
29
+ isNumericType,
30
+ getFormat,
31
+ getMinItems,
32
+ getMaxItems,
33
+ EmitContext,
34
+ listServices,
35
+ Union,
36
+ isNullType,
37
+ SyntaxKind,
38
+ Type,
39
+ getProjectedName
40
+ } from "@typespec/compiler";
41
+ import {
42
+ getAuthentication,
43
+ getHeaderFieldName,
44
+ getHttpOperation,
45
+ getPathParamName,
46
+ getQueryParamName,
47
+ getServers,
48
+ HttpAuth,
49
+ HttpOperationParameter,
50
+ HttpOperationResponse,
51
+ HttpOperationResponseContent,
52
+ HttpServer,
53
+ isStatusCode,
54
+ HttpOperation,
55
+ isHeader
56
+ } from "@typespec/http";
57
+ import { getAddedOnVersions } from "@typespec/versioning";
58
+ import {
59
+ SdkClient,
60
+ listClients,
61
+ listOperationGroups,
62
+ listOperationsInOperationGroup,
63
+ isApiVersion,
64
+ getDefaultApiVersion,
65
+ getClientNamespaceString,
66
+ createSdkContext,
67
+ SdkContext
68
+ } from "@azure-tools/typespec-client-generator-core";
69
+ import { getResourceOperation } from "@typespec/rest";
70
+ import {
71
+ ModularCodeModel,
72
+ Client as HrlcClient,
73
+ Parameter,
74
+ Operation as HrlcOperation,
75
+ OperationGroup,
76
+ Response,
77
+ Type as HrlcType,
78
+ Header
79
+ } from "./modularCodeModel.js";
80
+ import { transformRLCOptions } from "../transform/transfromRLCOptions.js";
81
+ import { camelToSnakeCase, toCamelCase } from "../casingUtils.js";
82
+
83
+ interface HttpServerParameter {
84
+ type: "endpointPath";
85
+ name: string;
86
+ param: ModelProperty;
87
+ }
88
+
89
+ interface CredentialType {
90
+ kind: "Credential";
91
+ scheme: HttpAuth;
92
+ }
93
+
94
+ interface CredentialTypeUnion {
95
+ kind: "CredentialTypeUnion";
96
+ types: CredentialType[];
97
+ }
98
+
99
+ type EmitterType = Type | CredentialType | CredentialTypeUnion;
100
+
101
+ let CASING: "camel" | "snake" = "snake";
102
+
103
+ export interface EmitterOptions {
104
+ "basic-setup-py"?: boolean;
105
+ "package-version"?: string;
106
+ "package-name"?: string;
107
+ "output-dir"?: string;
108
+ "package-mode"?: string;
109
+ debug?: boolean;
110
+ }
111
+
112
+ function applyCasing(
113
+ name: string,
114
+ options: { casing: "snake" | "camel" } = { casing: "snake" }
115
+ ): string {
116
+ if (options.casing === "camel") {
117
+ return toCamelCase(name);
118
+ }
119
+
120
+ return camelToSnakeCase(name);
121
+ }
122
+
123
+ const typesMap = new Map<EmitterType, HrlcType>();
124
+ const simpleTypesMap = new Map<string, HrlcType>();
125
+ const endpointPathParameters: Record<string, any>[] = [];
126
+ let apiVersionParam: Parameter | undefined = undefined;
127
+
128
+ function isSimpleType(
129
+ program: Program,
130
+ type: EmitterType | undefined
131
+ ): boolean {
132
+ // these decorators can only work for simple type(int/string/float, etc)
133
+ if (type && (type.kind === "Scalar" || type.kind === "ModelProperty")) {
134
+ const funcs = [
135
+ getMinValue,
136
+ getMaxValue,
137
+ getMinLength,
138
+ getMaxLength,
139
+ getPattern
140
+ ];
141
+ for (const func of funcs) {
142
+ if (func(program, type)) {
143
+ return true;
144
+ }
145
+ }
146
+ }
147
+ return false;
148
+ }
149
+
150
+ function getDocStr(program: Program, target: Type): string {
151
+ return getDoc(program, target) ?? "";
152
+ }
153
+
154
+ function isLro(_program: Program, operation: Operation): boolean {
155
+ for (const decorator of operation.decorators) {
156
+ if (decorator.decorator.name === "$pollingOperation") {
157
+ return true;
158
+ }
159
+ }
160
+ return false;
161
+ }
162
+
163
+ function handleDiscriminator(program: Program, type: Model, model: any) {
164
+ const discriminator = getDiscriminator(program, type);
165
+ if (discriminator) {
166
+ let discriminatorProperty;
167
+ for (const childModel of type.derivedModels) {
168
+ const modelType = getType(program, childModel);
169
+ for (const property of modelType.properties) {
170
+ if (property.restApiName === discriminator.propertyName) {
171
+ modelType.discriminatorValue = property.type.value;
172
+ property.isDiscriminator = true;
173
+ model.discriminatedSubtypes[property.type.value] = modelType;
174
+ discriminatorProperty = property;
175
+ }
176
+ }
177
+ }
178
+ // it is not included in properties of cadl but needed by python codegen
179
+ if (discriminatorProperty) {
180
+ const discriminatorType = { ...discriminatorProperty.type };
181
+ discriminatorType.value = null;
182
+ const propertyCopy = {
183
+ ...discriminatorProperty,
184
+ isPolymorphic: true,
185
+ type: discriminatorType
186
+ };
187
+ propertyCopy.description = "";
188
+ model.properties.push(propertyCopy);
189
+ }
190
+ }
191
+ }
192
+
193
+ function getEffectiveSchemaType(program: Program, type: Model): Model {
194
+ function isSchemaProperty(property: ModelProperty) {
195
+ const headerInfo = getHeaderFieldName(program, property);
196
+ const queryInfo = getQueryParamName(program, property);
197
+ const pathInfo = getPathParamName(program, property);
198
+ const statusCodeinfo = isStatusCode(program, property);
199
+ return !(headerInfo || queryInfo || pathInfo || statusCodeinfo);
200
+ }
201
+
202
+ const effective = getEffectiveModelType(program, type, isSchemaProperty);
203
+ if (effective.name) {
204
+ return effective;
205
+ }
206
+ return type;
207
+ }
208
+
209
+ function getType(program: Program, type: EmitterType): any {
210
+ // don't cache simple type(string, int, etc) since decorators may change the result
211
+ const enableCache = !isSimpleType(program, type);
212
+ const effectiveModel =
213
+ type.kind === "Model" ? getEffectiveSchemaType(program, type) : type;
214
+ if (enableCache) {
215
+ const cached = typesMap.get(effectiveModel);
216
+ if (cached) {
217
+ return cached;
218
+ }
219
+ }
220
+ let newValue: any = emitType(program, type);
221
+ if (enableCache) {
222
+ typesMap.set(effectiveModel, newValue);
223
+ if (type.kind === "Model") {
224
+ // need to do properties after insertion to avoid infinite recursion
225
+ for (const property of type.properties.values()) {
226
+ if (
227
+ isStatusCode(program, property) ||
228
+ isNeverType(property.type) ||
229
+ isHeader(program, property)
230
+ ) {
231
+ continue;
232
+ }
233
+ newValue.properties.push(emitProperty(program, property));
234
+ }
235
+ // need to do discriminator outside `emitModel` to avoid infinite recursion
236
+ handleDiscriminator(program, type, newValue);
237
+ }
238
+ } else {
239
+ const key = JSON.stringify(newValue);
240
+ const value = simpleTypesMap.get(key);
241
+ if (value) {
242
+ newValue = value;
243
+ } else {
244
+ simpleTypesMap.set(key, newValue);
245
+ }
246
+ }
247
+
248
+ return newValue;
249
+ }
250
+
251
+ // To pass the yaml dump
252
+ function getAddedOnVersion(p: Program, t: Type): string | undefined {
253
+ return getAddedOnVersions(p, t)?.[0]?.value;
254
+ }
255
+
256
+ type ParamBase = {
257
+ optional: boolean;
258
+ description: string;
259
+ addedOn: string | undefined;
260
+ clientName: string;
261
+ inOverload: boolean;
262
+ };
263
+ function emitParamBase(
264
+ program: Program,
265
+ parameter: ModelProperty | Type
266
+ ): ParamBase {
267
+ let optional: boolean;
268
+ let name: string;
269
+ let description: string = "";
270
+ let addedOn: string | undefined;
271
+
272
+ if (parameter.kind === "ModelProperty") {
273
+ optional = parameter.optional;
274
+ name = parameter.name;
275
+ description = getDocStr(program, parameter);
276
+ addedOn = getAddedOnVersion(program, parameter);
277
+ } else {
278
+ optional = false;
279
+ name = "body";
280
+ }
281
+
282
+ return {
283
+ optional,
284
+ description,
285
+ addedOn,
286
+ clientName: applyCasing(name, { casing: CASING }),
287
+ inOverload: false
288
+ };
289
+ }
290
+
291
+ type BodyParameter = ParamBase & {
292
+ contentTypes: string[];
293
+ type: Type;
294
+ restApiName: string;
295
+ location: "body";
296
+ defaultContentType: string;
297
+ };
298
+
299
+ function getBodyType(program: Program, route: HttpOperation): Type {
300
+ let bodyModel = route.parameters.body?.type;
301
+ if (bodyModel && bodyModel.kind === "Model" && route.operation) {
302
+ const resourceType = getResourceOperation(
303
+ program,
304
+ route.operation
305
+ )?.resourceType;
306
+ if (resourceType && route.responses && route.responses.length > 0) {
307
+ const resp = route.responses[0];
308
+ if (resp && resp.responses && resp.responses.length > 0) {
309
+ const responseBody = resp.responses[0]?.body;
310
+ if (responseBody?.type?.kind === "Model") {
311
+ const bodyTypeInResponse = getEffectiveSchemaType(
312
+ program,
313
+ responseBody.type
314
+ );
315
+ // response body type is reosurce type, and request body type (if templated) contains resource type
316
+ if (
317
+ bodyTypeInResponse === resourceType &&
318
+ bodyModel.templateMapper &&
319
+ bodyModel.templateMapper.args &&
320
+ bodyModel.templateMapper.args.some((it) => {
321
+ return it.kind === "Model" || it.kind === "Union"
322
+ ? it === bodyTypeInResponse
323
+ : false;
324
+ })
325
+ ) {
326
+ bodyModel = resourceType;
327
+ }
328
+ }
329
+ }
330
+ }
331
+ if (resourceType && bodyModel.name === "") {
332
+ bodyModel = resourceType;
333
+ }
334
+ }
335
+ return bodyModel!;
336
+ }
337
+
338
+ function emitBodyParameter(
339
+ program: Program,
340
+ httpOperation: HttpOperation
341
+ ): BodyParameter {
342
+ const params = httpOperation.parameters;
343
+ const body = params.body!;
344
+ const base = emitParamBase(program, body.parameter ?? body.type);
345
+ let contentTypes = body.contentTypes;
346
+ if (contentTypes.length === 0) {
347
+ contentTypes = ["application/json"];
348
+ }
349
+ if (contentTypes.length !== 1) {
350
+ throw Error("Currently only one kind of content-type!");
351
+ }
352
+ const type = getType(program, getBodyType(program, httpOperation));
353
+
354
+ if (type.type === "model" && type.name === "") {
355
+ type.name = capitalize(httpOperation.operation.name) + "Request";
356
+ }
357
+
358
+ return {
359
+ contentTypes,
360
+ type,
361
+ restApiName: body.parameter?.name ?? "body",
362
+ location: "body",
363
+ ...base,
364
+ defaultContentType:
365
+ body.parameter?.default ?? contentTypes.includes("application/json")
366
+ ? "application/json"
367
+ : contentTypes[0]!
368
+ };
369
+ }
370
+
371
+ function emitParameter(
372
+ context: SdkContext,
373
+ parameter: HttpOperationParameter | HttpServerParameter,
374
+ implementation: string
375
+ ): Parameter {
376
+ const base = emitParamBase(context.program, parameter.param);
377
+ let type = getType(context.program, parameter.param.type);
378
+ let clientDefaultValue = undefined;
379
+ if (
380
+ parameter.name.toLowerCase() === "content-type" &&
381
+ type["type"] === "constant"
382
+ ) {
383
+ /// We don't want constant types for content types, so we make sure if it's
384
+ /// a constant, we make it not constant
385
+ clientDefaultValue = type["value"];
386
+ type = type["valueType"];
387
+ }
388
+ const paramMap: any = {
389
+ restApiName: parameter.name,
390
+ location: parameter.type,
391
+ type: type,
392
+ implementation: implementation,
393
+ skipUrlEncoding: parameter.type === "endpointPath"
394
+ };
395
+
396
+ if (paramMap.type.type === "constant") {
397
+ clientDefaultValue = paramMap.type.value;
398
+ }
399
+
400
+ if (isApiVersion(context, parameter as HttpOperationParameter)) {
401
+ const defaultApiVersion = getDefaultApiVersion(
402
+ context,
403
+ getServiceNamespace(context.program)
404
+ );
405
+ paramMap.type = defaultApiVersion
406
+ ? getConstantType(defaultApiVersion.value)
407
+ : { type: "string" };
408
+ paramMap.implementation = "Client";
409
+ paramMap.in_docstring = false;
410
+ if (defaultApiVersion) {
411
+ clientDefaultValue = defaultApiVersion.value;
412
+ }
413
+ }
414
+ return { clientDefaultValue, ...base, ...paramMap };
415
+ }
416
+
417
+ function emitContentTypeParameter(
418
+ bodyParameter: any,
419
+ inOverload: boolean,
420
+ inOverriden: boolean
421
+ ) {
422
+ return {
423
+ checkClientInput: false,
424
+ clientDefaultValue: bodyParameter.defaultContentType,
425
+ clientName: "content_type",
426
+ delimiter: null,
427
+ description: `Body parameter Content-Type. Known values are: ${bodyParameter.contentTypes}.`,
428
+ implementation: "Method",
429
+ inDocstring: true,
430
+ inOverload: inOverload,
431
+ inOverriden: inOverriden,
432
+ location: "header",
433
+ optional: true,
434
+ restApiName: "Content-Type",
435
+ type: { type: "string" }
436
+ };
437
+ }
438
+
439
+ function emitFlattenedParameter(
440
+ bodyParameter: Record<string, any>,
441
+ property: any
442
+ ): Record<string, any> {
443
+ return {
444
+ checkClientInput: false,
445
+ clientDefaultValue: null,
446
+ clientName: property.clientName,
447
+ delimiter: null,
448
+ description: property.description,
449
+ implementation: "Method",
450
+ inDocstring: true,
451
+ inFlattenedBody: true,
452
+ inOverload: false,
453
+ inOverriden: false,
454
+ isApiVersion: bodyParameter["isApiVersion"],
455
+ location: "other",
456
+ optional: property["optional"],
457
+ restApiName: null,
458
+ skipUrlEncoding: false,
459
+ type: property["type"],
460
+ defaultToUnsetSentinel: true
461
+ };
462
+ }
463
+
464
+ function getConstantType(key: string): HrlcType {
465
+ const cache = simpleTypesMap.get(key);
466
+ if (cache) {
467
+ return cache;
468
+ }
469
+ const type: HrlcType = {
470
+ apiVersions: [],
471
+ clientDefaultValue: null,
472
+ type: "constant",
473
+ value: key,
474
+ valueType: { type: "string" },
475
+ xmlMetadata: {}
476
+ };
477
+ simpleTypesMap.set(key, type);
478
+ return type;
479
+ }
480
+
481
+ function emitAcceptParameter(
482
+ _program: Program,
483
+ inOverload: boolean,
484
+ inOverriden: boolean
485
+ ): Record<string, any> {
486
+ return {
487
+ checkClientInput: false,
488
+ clientDefaultValue: "application/json",
489
+ clientName: "accept",
490
+ delimiter: null,
491
+ description: "Accept header.",
492
+ explode: false,
493
+ groupedBy: null,
494
+ implementation: "Method",
495
+ inDocstring: true,
496
+ inOverload: inOverload,
497
+ inOverriden: inOverriden,
498
+ location: "header",
499
+ optional: false,
500
+ restApiName: "Accept",
501
+ skipUrlEncoding: false,
502
+ type: getConstantType("application/json")
503
+ };
504
+ }
505
+
506
+ function emitResponseHeaders(
507
+ program: Program,
508
+ headers?: Record<string, ModelProperty>
509
+ ): Header[] {
510
+ const retval: Header[] = [];
511
+ if (!headers) {
512
+ return retval;
513
+ }
514
+ for (const [key, value] of Object.entries(headers)) {
515
+ retval.push({
516
+ type: getType(program, value.type),
517
+ restApiName: key
518
+ });
519
+ }
520
+ return retval;
521
+ }
522
+
523
+ function isAzureCoreErrorType(t?: Type): boolean {
524
+ if (
525
+ t?.kind !== "Model" ||
526
+ !["Error", "ErrorResponse", "InnerError"].includes(t.name)
527
+ )
528
+ return false;
529
+ const namespaces = ".Azure.Core.Foundations".split(".");
530
+ while (
531
+ namespaces.length > 0 &&
532
+ (t?.kind === "Model" || t?.kind === "Namespace") &&
533
+ t.namespace?.name === namespaces.pop()
534
+ ) {
535
+ t = t.namespace;
536
+ }
537
+ return namespaces.length == 0;
538
+ }
539
+
540
+ function emitResponse(
541
+ program: Program,
542
+ response: HttpOperationResponse,
543
+ innerResponse: HttpOperationResponseContent
544
+ ): Response {
545
+ let type = undefined;
546
+ if (
547
+ innerResponse.body?.type &&
548
+ !isAzureCoreErrorType(innerResponse.body?.type)
549
+ ) {
550
+ // temporary logic. It can be removed after compiler optimize the response
551
+ const candidate = [
552
+ "ResourceOkResponse",
553
+ "ResourceCreatedResponse",
554
+ "AcceptedResponse"
555
+ ];
556
+ const originType = innerResponse.body.type as Model;
557
+ if (
558
+ innerResponse.body.type.kind === "Model" &&
559
+ candidate.find((e) => e === originType.name)
560
+ ) {
561
+ const modelType = getEffectiveSchemaType(program, originType);
562
+ type = getType(program, modelType);
563
+ } else {
564
+ type = getType(program, innerResponse.body.type);
565
+ }
566
+ }
567
+ const statusCodes: (number | "default")[] = [];
568
+ if (response.statusCode === "*") {
569
+ statusCodes.push("default");
570
+ } else {
571
+ statusCodes.push(parseInt(response.statusCode));
572
+ }
573
+ return {
574
+ headers: emitResponseHeaders(program, innerResponse.headers),
575
+ statusCodes: statusCodes ?? [],
576
+ addedOn: getAddedOnVersion(program, response.type),
577
+ discriminator: "basic",
578
+ type: type
579
+ };
580
+ }
581
+
582
+ function emitOperation(
583
+ context: SdkContext,
584
+ operation: Operation,
585
+ operationGroupName: string
586
+ ): HrlcOperation {
587
+ const lro = isLro(context.program, operation);
588
+ const paging = getPagedResult(context.program, operation);
589
+ if (lro && paging) {
590
+ return emitLroPagingOperation(context, operation, operationGroupName);
591
+ } else if (paging) {
592
+ return emitPagingOperation(context, operation, operationGroupName);
593
+ } else if (lro) {
594
+ return emitLroOperation(context, operation, operationGroupName);
595
+ }
596
+ return emitBasicOperation(context, operation, operationGroupName);
597
+ }
598
+
599
+ function addLroInformation(emittedOperation: HrlcOperation) {
600
+ emittedOperation["discriminator"] = "lro";
601
+ }
602
+
603
+ function addPagingInformation(
604
+ program: Program,
605
+ operation: Operation,
606
+ emittedOperation: Record<string, any>
607
+ ) {
608
+ emittedOperation["discriminator"] = "paging";
609
+ const pagedResult = getPagedResult(program, operation);
610
+ if (pagedResult === undefined) {
611
+ throw Error(
612
+ "Trying to add paging information, but not paging metadata for this operation"
613
+ );
614
+ }
615
+ emittedOperation["itemName"] = pagedResult.itemsPath;
616
+ emittedOperation["continuationTokenName"] = pagedResult.nextLinkPath;
617
+ }
618
+
619
+ function emitLroPagingOperation(
620
+ context: SdkContext,
621
+ operation: Operation,
622
+ operationGroupName: string
623
+ ): HrlcOperation {
624
+ const emittedOperation = emitBasicOperation(
625
+ context,
626
+ operation,
627
+ operationGroupName
628
+ );
629
+ addLroInformation(emittedOperation);
630
+ addPagingInformation(context.program, operation, emittedOperation);
631
+ emittedOperation["discriminator"] = "lropaging";
632
+ return emittedOperation;
633
+ }
634
+
635
+ function emitLroOperation(
636
+ context: SdkContext,
637
+ operation: Operation,
638
+ operationGroupName: string
639
+ ): HrlcOperation {
640
+ const emittedOperation = emitBasicOperation(
641
+ context,
642
+ operation,
643
+ operationGroupName
644
+ );
645
+ addLroInformation(emittedOperation);
646
+ return emittedOperation;
647
+ }
648
+
649
+ function emitPagingOperation(
650
+ context: SdkContext,
651
+ operation: Operation,
652
+ operationGroupName: string
653
+ ): HrlcOperation {
654
+ const emittedOperation = emitBasicOperation(
655
+ context,
656
+ operation,
657
+ operationGroupName
658
+ );
659
+ addPagingInformation(context.program, operation, emittedOperation);
660
+ return emittedOperation;
661
+ }
662
+
663
+ function emitBasicOperation(
664
+ context: SdkContext,
665
+ operation: Operation,
666
+ operationGroupName: string
667
+ ): HrlcOperation {
668
+ // Set up parameters for operation
669
+ const parameters: any[] = [];
670
+ if (endpointPathParameters) {
671
+ for (const param of endpointPathParameters) {
672
+ parameters.push(param);
673
+ }
674
+ }
675
+ const httpOperation = ignoreDiagnostics(
676
+ getHttpOperation(context.program, operation)
677
+ );
678
+ for (const param of httpOperation.parameters.parameters) {
679
+ const emittedParam = emitParameter(context, param, "Method");
680
+ if (isApiVersion(context, param) && apiVersionParam === undefined) {
681
+ apiVersionParam = emittedParam;
682
+ }
683
+ parameters.push(emittedParam);
684
+ }
685
+
686
+ // Set up responses for operation
687
+ const responses: Response[] = [];
688
+ const exceptions: Response[] = [];
689
+ const isOverload: boolean = false;
690
+ const isOverriden: boolean = false;
691
+ for (const response of httpOperation.responses) {
692
+ for (const innerResponse of response.responses) {
693
+ const emittedResponse: Response = emitResponse(
694
+ context.program,
695
+ response,
696
+ innerResponse
697
+ );
698
+ if (
699
+ emittedResponse["type"] &&
700
+ parameters.filter((e) => e.restApiName.toLowerCase() === "accept")
701
+ .length === 0
702
+ ) {
703
+ parameters.push(
704
+ emitAcceptParameter(context.program, isOverload, isOverriden)
705
+ );
706
+ }
707
+ if (isErrorModel(context.program, response.type)) {
708
+ // * is valid status code in cadl but invalid for autorest.python
709
+ if (response.statusCode === "*") {
710
+ exceptions.push(emittedResponse);
711
+ }
712
+ } else {
713
+ responses.push(emittedResponse);
714
+ }
715
+ }
716
+ }
717
+
718
+ let bodyParameter: any | undefined;
719
+ if (httpOperation.parameters.body === undefined) {
720
+ bodyParameter = undefined;
721
+ } else {
722
+ bodyParameter = emitBodyParameter(context.program, httpOperation);
723
+ if (
724
+ parameters.filter((e) => e.restApiName.toLowerCase() === "content-type")
725
+ .length === 0
726
+ ) {
727
+ parameters.push(
728
+ emitContentTypeParameter(bodyParameter, isOverload, isOverriden)
729
+ );
730
+ }
731
+ if (
732
+ bodyParameter.type.type === "model" &&
733
+ bodyParameter.type.base === "json"
734
+ ) {
735
+ bodyParameter["propertyToParameterName"] = {};
736
+ if (!isOverload) {
737
+ bodyParameter.defaultToUnsetSentinel = true;
738
+ }
739
+ for (const property of bodyParameter.type.properties) {
740
+ bodyParameter["propertyToParameterName"][property["restApiName"]] =
741
+ property["clientName"];
742
+ parameters.push(emitFlattenedParameter(bodyParameter, property));
743
+ }
744
+ }
745
+ }
746
+ const name = applyCasing(operation.name, { casing: CASING });
747
+ return {
748
+ name: name,
749
+ description: getDocStr(context.program, operation),
750
+ summary: getSummary(context.program, operation) ?? "",
751
+ url: httpOperation.path,
752
+ method: httpOperation.verb.toUpperCase(),
753
+ parameters: parameters,
754
+ bodyParameter: bodyParameter,
755
+ responses: responses ?? [],
756
+ exceptions: exceptions ?? [],
757
+ groupName: operationGroupName,
758
+ addedOn: getAddedOnVersion(context.program, operation),
759
+ discriminator: "basic",
760
+ isOverload: false,
761
+ overloads: [],
762
+ apiVersions: [getAddedOnVersion(context.program, operation)]
763
+ };
764
+ }
765
+
766
+ function isReadOnly(program: Program, type: ModelProperty): boolean {
767
+ // https://microsoft.github.io/cadl/standard-library/rest/operations#automatic-visibility
768
+ // Only "read" should be readOnly
769
+ const visibility = getVisibility(program, type);
770
+ if (visibility) {
771
+ return visibility.includes("read");
772
+ } else {
773
+ return false;
774
+ }
775
+ }
776
+
777
+ function emitProperty(
778
+ program: Program,
779
+ property: ModelProperty
780
+ ): Record<string, any> {
781
+ let clientDefaultValue = undefined;
782
+ const propertyDefaultKind = property.default?.kind;
783
+ if (
784
+ property.default &&
785
+ (propertyDefaultKind === "Number" ||
786
+ propertyDefaultKind === "String" ||
787
+ propertyDefaultKind === "Boolean")
788
+ ) {
789
+ clientDefaultValue = property.default.value;
790
+ }
791
+ const restApiName = getProjectedName(program, property, "json");
792
+ return {
793
+ clientName: applyCasing(property.name, { casing: CASING }),
794
+ restApiName: restApiName ?? property.name,
795
+ type: getType(program, property.type),
796
+ optional: property.optional,
797
+ description: getDocStr(program, property),
798
+ addedOn: getAddedOnVersion(program, property),
799
+ readonly: isReadOnly(program, property) || isKey(program, property),
800
+ clientDefaultValue: clientDefaultValue
801
+ };
802
+ }
803
+
804
+ function getName(program: Program, type: Model): string {
805
+ const friendlyName = getFriendlyName(program, type);
806
+ if (friendlyName) {
807
+ return friendlyName;
808
+ } else {
809
+ if (
810
+ type.templateMapper &&
811
+ type.templateMapper.args &&
812
+ type.templateMapper.args.length > 0
813
+ ) {
814
+ return (
815
+ type.name +
816
+ type.templateMapper.args
817
+ .map((it) => (it.kind === "Model" ? it.name : ""))
818
+ .join("")
819
+ );
820
+ } else {
821
+ return type.name;
822
+ }
823
+ }
824
+ }
825
+
826
+ function emitModel(program: Program, type: Model): Record<string, any> {
827
+ // Now we know it's a defined model
828
+ const properties: Record<string, any>[] = [];
829
+ let baseModel = undefined;
830
+ if (type.baseModel) {
831
+ baseModel = getType(program, type.baseModel);
832
+ }
833
+ const effectiveName = getEffectiveSchemaType(program, type).name;
834
+ const modelName = effectiveName ? effectiveName : getName(program, type);
835
+ return {
836
+ type: "model",
837
+ name: modelName,
838
+ description: getDocStr(program, type),
839
+ parents: baseModel ? [baseModel] : [],
840
+ discriminatedSubtypes: {},
841
+ properties: properties,
842
+ addedOn: getAddedOnVersion(program, type),
843
+ snakeCaseName: modelName
844
+ ? applyCasing(modelName, { casing: CASING })
845
+ : modelName,
846
+ base: modelName === "" ? "json" : "dpg"
847
+ };
848
+ }
849
+
850
+ function intOrFloat(value: number): string {
851
+ return value.toString().indexOf(".") === -1 ? "integer" : "float";
852
+ }
853
+
854
+ function enumName(name: string): string {
855
+ if (name.toUpperCase() === name) {
856
+ return name;
857
+ }
858
+ return applyCasing(name, { casing: CASING }).toUpperCase();
859
+ }
860
+
861
+ function emitEnum(program: Program, type: Enum): Record<string, any> {
862
+ const enumValues = [];
863
+ for (const m of type.members.values()) {
864
+ enumValues.push({
865
+ name: enumName(m.name),
866
+ value: m.value ?? m.name,
867
+ description: getDocStr(program, m)
868
+ });
869
+ }
870
+
871
+ return {
872
+ type: "enum",
873
+ name: type.name,
874
+ description: getDocStr(program, type),
875
+ valueType: { type: enumMemberType(type.members.values().next().value) },
876
+ values: enumValues,
877
+ isFixed: isFixed(program, type)
878
+ };
879
+ function enumMemberType(member: EnumMember) {
880
+ if (typeof member.value === "number") {
881
+ return intOrFloat(member.value);
882
+ }
883
+ return "string";
884
+ }
885
+ }
886
+
887
+ function constantType(value: any, valueType: string): Record<string, any> {
888
+ return { type: "constant", value: value, valueType: { type: valueType } };
889
+ }
890
+
891
+ function emitCredential(auth: HttpAuth): Record<string, any> {
892
+ let credential_type: any = {};
893
+ if (auth.type === "oauth2") {
894
+ credential_type = {
895
+ type: "OAuth2",
896
+ policy: {
897
+ type: "BearerTokenCredentialPolicy",
898
+ credentialScopes: []
899
+ }
900
+ };
901
+ for (const flow of auth.flows) {
902
+ for (const scope of flow.scopes) {
903
+ credential_type.policy.credentialScopes.push(scope.value);
904
+ }
905
+ credential_type.policy.credentialScopes.push();
906
+ }
907
+ } else if (auth.type === "apiKey") {
908
+ credential_type = {
909
+ type: "Key",
910
+ policy: {
911
+ type: "AzureKeyCredentialPolicy",
912
+ key: auth.name
913
+ }
914
+ };
915
+ }
916
+ return credential_type;
917
+ }
918
+
919
+ function emitCredentialUnion(cred_types: CredentialTypeUnion) {
920
+ const result: any = {};
921
+ // Export as CombinedType, which is already a Union Type in autorest codegen
922
+ result.type = "combined";
923
+ result.types = [];
924
+ for (const cred_type of cred_types.types) {
925
+ result.types.push(emitCredential(cred_type.scheme));
926
+ }
927
+
928
+ return result;
929
+ }
930
+
931
+ function emitStdScalar(
932
+ scalar: Scalar & { name: IntrinsicScalarName }
933
+ ): Record<string, any> {
934
+ switch (scalar.name) {
935
+ case "bytes":
936
+ return { type: "byte-array", format: "byte" };
937
+ case "int8":
938
+ case "int16":
939
+ case "int32":
940
+ case "int64":
941
+ case "safeint":
942
+ case "uint8":
943
+ case "uint16":
944
+ case "uint32":
945
+ case "uint64":
946
+ case "integer":
947
+ return { type: "integer" };
948
+ case "float32":
949
+ case "float64":
950
+ case "float":
951
+ return { type: "float" };
952
+ case "url":
953
+ case "string":
954
+ return { type: "string" };
955
+ case "boolean":
956
+ return { type: "boolean" };
957
+ case "plainDate":
958
+ return { type: "date" };
959
+ case "utcDateTime":
960
+ return { type: "datetime", format: "date-time" };
961
+ case "plainTime":
962
+ return { type: "time" };
963
+ case "duration":
964
+ return { type: "duration" };
965
+ case "numeric":
966
+ return {}; // Waiting on design for more precise type https://github.com/microsoft/cadl/issues/1260
967
+ default:
968
+ return {};
969
+ }
970
+ }
971
+
972
+ function applyIntrinsicDecorators(
973
+ program: Program,
974
+ type: Scalar | ModelProperty,
975
+ result: any
976
+ ): Record<string, any> {
977
+ const newResult = { ...result };
978
+ const docStr = getDoc(program, type);
979
+ const isString = isStringType(program, getPropertyType(type));
980
+ const isNumeric = isNumericType(program, getPropertyType(type));
981
+
982
+ if (!result.description && docStr) {
983
+ newResult.description = docStr;
984
+ }
985
+
986
+ const formatStr = getFormat(program, type);
987
+ if (isString && !result.format && formatStr) {
988
+ newResult.format = formatStr;
989
+ }
990
+
991
+ const pattern = getPattern(program, type);
992
+ if (isString && !result.pattern && pattern) {
993
+ newResult.pattern = pattern;
994
+ }
995
+
996
+ const minLength = getMinLength(program, type);
997
+ if (isString && !result.minLength && minLength !== undefined) {
998
+ newResult.minLength = minLength;
999
+ }
1000
+
1001
+ const maxLength = getMaxLength(program, type);
1002
+ if (isString && !result.maxLength && maxLength !== undefined) {
1003
+ newResult.maxLength = maxLength;
1004
+ }
1005
+
1006
+ const minValue = getMinValue(program, type);
1007
+ if (isNumeric && !result.minimum && minValue !== undefined) {
1008
+ newResult.minimum = minValue;
1009
+ }
1010
+
1011
+ const maxValue = getMaxValue(program, type);
1012
+ if (isNumeric && !result.maximum && maxValue !== undefined) {
1013
+ newResult.maximum = maxValue;
1014
+ }
1015
+
1016
+ const minItems = getMinItems(program, type);
1017
+ if (!result.minItems && minItems !== undefined) {
1018
+ newResult.minItems = minItems;
1019
+ }
1020
+
1021
+ const maxItems = getMaxItems(program, type);
1022
+ if (!result.maxItems && maxItems !== undefined) {
1023
+ newResult.maxItems = maxItems;
1024
+ }
1025
+ return newResult;
1026
+ }
1027
+
1028
+ function emitScalar(program: Program, scalar: Scalar): Record<string, any> {
1029
+ let result: Record<string, any> = {};
1030
+ if (program.checker.isStdType(scalar)) {
1031
+ result = emitStdScalar(scalar);
1032
+ } else if (scalar.baseScalar) {
1033
+ result = emitScalar(program, scalar.baseScalar);
1034
+ }
1035
+ return applyIntrinsicDecorators(program, scalar, result);
1036
+ }
1037
+
1038
+ function emitListOrDict(
1039
+ program: Program,
1040
+ type: Model
1041
+ ): Record<string, any> | undefined {
1042
+ if (type.indexer !== undefined) {
1043
+ if (!isNeverType(type.indexer.key)) {
1044
+ const name = type.indexer.key.name;
1045
+ if (name === "string") {
1046
+ return {
1047
+ type: "dict",
1048
+ elementType: getType(program, type.indexer.value!)
1049
+ };
1050
+ } else if (name === "integer") {
1051
+ return {
1052
+ type: "list",
1053
+ elementType: getType(program, type.indexer.value!)
1054
+ };
1055
+ }
1056
+ }
1057
+ }
1058
+ return undefined;
1059
+ }
1060
+
1061
+ function mapCadlType(program: Program, type: Type): any {
1062
+ switch (type.kind) {
1063
+ case "Number":
1064
+ return constantType(type.value, intOrFloat(type.value));
1065
+ case "String":
1066
+ return constantType(type.value, "string");
1067
+ case "Boolean":
1068
+ return constantType(type.value, "boolean");
1069
+ case "Model":
1070
+ return emitListOrDict(program, type);
1071
+ }
1072
+ }
1073
+
1074
+ function capitalize(name: string): string {
1075
+ return name[0]!.toUpperCase() + name.slice(1);
1076
+ }
1077
+
1078
+ function emitUnion(program: Program, type: Union): Record<string, any> {
1079
+ const nonNullOptions = [...type.variants.values()]
1080
+ .map((x) => x.type)
1081
+ .filter((t) => !isNullType(t));
1082
+
1083
+ const notLiteral = (t: Type): boolean =>
1084
+ ["Boolean", "Number", "String"].indexOf(t.kind) < 0;
1085
+ if (nonNullOptions.length > 1) {
1086
+ if (nonNullOptions.every(notLiteral)) {
1087
+ // Generate as CombinedType if non of the options is Literal.
1088
+ const unionName = `MyCombinedType`;
1089
+ return {
1090
+ name: unionName,
1091
+ snakeCaseName: applyCasing(unionName, { casing: CASING }),
1092
+ description: `Type of ${unionName}`,
1093
+ isPublic: false,
1094
+ type: "combined",
1095
+ types: nonNullOptions.map((x) => emitType(program, x)),
1096
+ xmlMetadata: {}
1097
+ };
1098
+ } else if (nonNullOptions.some(notLiteral)) {
1099
+ // Can't generate if this union is a mixed up of literals and sub-types
1100
+ throw Error(`Can't do union for ${JSON.stringify(nonNullOptions)}`);
1101
+ }
1102
+ }
1103
+
1104
+ // Geneate Union of Literals as Python Enum
1105
+ const values: Record<string, any>[] = [];
1106
+ for (const option of nonNullOptions) {
1107
+ const value = emitType(program, option)["value"];
1108
+ values.push({
1109
+ description: "",
1110
+ name: applyCasing(value, { casing: CASING }).toUpperCase(),
1111
+ value: value
1112
+ });
1113
+ }
1114
+ let enumName = "MyEnum";
1115
+ if (
1116
+ type.node &&
1117
+ type.node.parent &&
1118
+ [SyntaxKind.ModelStatement, SyntaxKind.ModelProperty].includes(
1119
+ type.node.parent.kind
1120
+ )
1121
+ ) {
1122
+ if (type.node.parent.kind === SyntaxKind.ModelStatement) {
1123
+ enumName = capitalize(type.node.parent.id.sv);
1124
+ } else if (type.node.parent.kind === SyntaxKind.ModelProperty) {
1125
+ const parent = type.node.parent as any;
1126
+ if (parent.id.sv) {
1127
+ enumName = capitalize(parent.id.sv) + "Type";
1128
+ }
1129
+ }
1130
+ }
1131
+ return {
1132
+ name: enumName,
1133
+ snakeCaseName: applyCasing(enumName, { casing: CASING }),
1134
+ description: `Type of ${enumName}`,
1135
+ isPublic: false,
1136
+ type: "enum",
1137
+ valueType: emitType(program, nonNullOptions[0]!)["valueType"],
1138
+ values: values,
1139
+ xmlMetadata: {}
1140
+ };
1141
+ }
1142
+
1143
+ function emitType(program: Program, type: EmitterType): Record<string, any> {
1144
+ if (type.kind === "Credential") {
1145
+ return emitCredential(type.scheme);
1146
+ }
1147
+ if (type.kind === "CredentialTypeUnion") {
1148
+ return emitCredentialUnion(type);
1149
+ }
1150
+ const builtinType = mapCadlType(program, type);
1151
+ if (builtinType !== undefined) {
1152
+ // add in description elements for types derived from primitive types (SecureString, etc.)
1153
+ const doc = getDoc(program, type);
1154
+ if (doc) {
1155
+ builtinType.description = doc;
1156
+ }
1157
+ return builtinType;
1158
+ }
1159
+
1160
+ switch (type.kind) {
1161
+ case "Intrinsic":
1162
+ return { type: "any" };
1163
+ case "Model":
1164
+ return emitModel(program, type);
1165
+ case "Scalar":
1166
+ return emitScalar(program, type);
1167
+ case "Union":
1168
+ return emitUnion(program, type);
1169
+ case "UnionVariant":
1170
+ return {};
1171
+ case "Enum":
1172
+ return emitEnum(program, type);
1173
+ default:
1174
+ throw Error(`Not supported ${type.kind}`);
1175
+ }
1176
+ }
1177
+
1178
+ function emitOperationGroups(
1179
+ context: SdkContext,
1180
+ client: SdkClient
1181
+ ): OperationGroup[] {
1182
+ const operationGroups: OperationGroup[] = [];
1183
+ for (const operationGroup of listOperationGroups(context, client)) {
1184
+ const operations: HrlcOperation[] = [];
1185
+ const name = operationGroup.type.name;
1186
+ for (const operation of listOperationsInOperationGroup(
1187
+ context,
1188
+ operationGroup
1189
+ )) {
1190
+ operations.push(emitOperation(context, operation, name));
1191
+ }
1192
+ operationGroups.push({
1193
+ className: name,
1194
+ propertyName: name,
1195
+ operations: operations
1196
+ });
1197
+ }
1198
+ const clientOperations: HrlcOperation[] = [];
1199
+ for (const operation of listOperationsInOperationGroup(context, client)) {
1200
+ clientOperations.push(emitOperation(context, operation, ""));
1201
+ }
1202
+ if (clientOperations.length > 0) {
1203
+ operationGroups.push({
1204
+ className: "",
1205
+ propertyName: "",
1206
+ operations: clientOperations
1207
+ });
1208
+ }
1209
+ return operationGroups;
1210
+ }
1211
+
1212
+ function getServerHelper(
1213
+ program: Program,
1214
+ namespace: Namespace
1215
+ ): HttpServer | undefined {
1216
+ const servers = getServers(program, namespace);
1217
+ if (servers === undefined) {
1218
+ return undefined;
1219
+ }
1220
+ return servers[0];
1221
+ }
1222
+
1223
+ function emitServerParams(
1224
+ context: SdkContext,
1225
+ namespace: Namespace
1226
+ ): Parameter[] {
1227
+ const server = getServerHelper(context.program, namespace);
1228
+ if (server === undefined) {
1229
+ return [
1230
+ {
1231
+ optional: false,
1232
+ description: "Service host",
1233
+ clientName: "endpoint",
1234
+ clientDefaultValue: null,
1235
+ restApiName: "$host",
1236
+ location: "path",
1237
+ type: { type: "string" },
1238
+ implementation: "Client",
1239
+ inOverload: false
1240
+ }
1241
+ ];
1242
+ }
1243
+ if (server.parameters) {
1244
+ const params: Parameter[] = [];
1245
+ for (const param of server.parameters.values()) {
1246
+ const serverParameter: HttpServerParameter = {
1247
+ type: "endpointPath",
1248
+ name: param.name,
1249
+ param: param
1250
+ };
1251
+ const emittedParameter = emitParameter(
1252
+ context,
1253
+ serverParameter,
1254
+ "Client"
1255
+ );
1256
+ endpointPathParameters.push(emittedParameter);
1257
+ if (
1258
+ isApiVersion(context, serverParameter as any) &&
1259
+ apiVersionParam == undefined
1260
+ ) {
1261
+ apiVersionParam = emittedParameter;
1262
+ continue;
1263
+ }
1264
+ params.push(emittedParameter);
1265
+ }
1266
+ return params;
1267
+ } else {
1268
+ return [
1269
+ {
1270
+ optional: false,
1271
+ description: "Service host",
1272
+ clientName: "endpoint",
1273
+ clientDefaultValue: server.url,
1274
+ restApiName: "$host",
1275
+ location: "path",
1276
+ type: { type: "string" },
1277
+ implementation: "Client",
1278
+ inOverload: false
1279
+ }
1280
+ ];
1281
+ }
1282
+ }
1283
+
1284
+ function emitCredentialParam(
1285
+ program: Program,
1286
+ namespace: Namespace
1287
+ ): Parameter | undefined {
1288
+ const auth = getAuthentication(program, namespace);
1289
+ if (auth) {
1290
+ const credential_types: CredentialType[] = [];
1291
+ for (const option of auth.options) {
1292
+ for (const scheme of option.schemes) {
1293
+ const type: CredentialType = {
1294
+ kind: "Credential",
1295
+ scheme: scheme
1296
+ };
1297
+ credential_types.push(type);
1298
+ }
1299
+ }
1300
+ if (credential_types.length > 0) {
1301
+ let type: EmitterType;
1302
+ if (credential_types.length === 1 && credential_types[0]) {
1303
+ type = credential_types[0];
1304
+ } else {
1305
+ type = {
1306
+ kind: "CredentialTypeUnion",
1307
+ types: credential_types
1308
+ };
1309
+ }
1310
+ return {
1311
+ type: getType(program, type),
1312
+ optional: false,
1313
+ description: "Credential needed for the client to connect to Azure.",
1314
+ clientName: "credential",
1315
+ location: "other",
1316
+ restApiName: "credential",
1317
+ implementation: "Client",
1318
+ skipUrlEncoding: true,
1319
+ inOverload: false
1320
+ };
1321
+ }
1322
+ }
1323
+ return undefined;
1324
+ }
1325
+
1326
+ function emitGlobalParameters(
1327
+ context: SdkContext,
1328
+ namespace: Namespace
1329
+ ): Parameter[] {
1330
+ const clientParameters = emitServerParams(context, namespace);
1331
+ const credentialParam = emitCredentialParam(context.program, namespace);
1332
+ if (credentialParam) {
1333
+ clientParameters.push(credentialParam);
1334
+ }
1335
+ return clientParameters;
1336
+ }
1337
+
1338
+ function getApiVersionParameter(context: SdkContext): Parameter | void {
1339
+ const version = getDefaultApiVersion(
1340
+ context,
1341
+ getServiceNamespace(context.program)
1342
+ );
1343
+ if (apiVersionParam) {
1344
+ return { ...apiVersionParam, isApiVersion: true };
1345
+ } else if (version !== undefined) {
1346
+ return {
1347
+ clientName: "api_version",
1348
+ clientDefaultValue: version.value,
1349
+ description: "Api Version",
1350
+ implementation: "Client",
1351
+ location: "query",
1352
+ restApiName: "api-version",
1353
+ skipUrlEncoding: false,
1354
+ optional: false,
1355
+ inDocstring: true,
1356
+ inOverload: false,
1357
+ inOverriden: false,
1358
+ type: getConstantType(version.value),
1359
+ isApiVersion: true
1360
+ };
1361
+ }
1362
+ }
1363
+
1364
+ function emitClients(context: SdkContext, namespace: string): HrlcClient[] {
1365
+ const program = context.program;
1366
+ const clients = listClients(context);
1367
+ const retval: HrlcClient[] = [];
1368
+ for (const client of clients) {
1369
+ const clientName = client.name.replace("Client", "");
1370
+ if (getNamespace(context, client.name) !== namespace) {
1371
+ continue;
1372
+ }
1373
+ const server = getServerHelper(program, client.service);
1374
+ const emittedClient: HrlcClient = {
1375
+ name: clientName.split(".").at(-1) ?? "",
1376
+ description: getDocStr(program, client.type),
1377
+ parameters: emitGlobalParameters(context, client.service),
1378
+ operationGroups: emitOperationGroups(context, client),
1379
+ url: server ? server.url : "",
1380
+ apiVersions: []
1381
+ };
1382
+ const emittedApiVersionParam = getApiVersionParameter(context);
1383
+ if (emittedApiVersionParam) {
1384
+ emittedClient.parameters.push(emittedApiVersionParam);
1385
+ }
1386
+ retval.push(emittedClient);
1387
+ }
1388
+ return retval;
1389
+ }
1390
+
1391
+ function getServiceNamespace(program: Program): Namespace {
1392
+ return listServices(program)[0]!.type;
1393
+ }
1394
+
1395
+ function getNamespace(context: SdkContext, clientName: string): string {
1396
+ // We get client namespaces from the client name. If there's a dot, we add that to the namespace
1397
+ const submodule = clientName.split(".").slice(0, -1).join(".").toLowerCase();
1398
+ if (!submodule) {
1399
+ return getClientNamespaceString(context)!.toLowerCase();
1400
+ }
1401
+ return submodule;
1402
+ }
1403
+
1404
+ function getNamespaces(context: SdkContext): Set<string> {
1405
+ const namespaces = new Set<string>();
1406
+ for (const client of listClients(context)) {
1407
+ namespaces.add(getNamespace(context, client.name));
1408
+ }
1409
+ return namespaces;
1410
+ }
1411
+
1412
+ export function emitCodeModel(
1413
+ context: EmitContext<EmitterOptions>,
1414
+ options: { casing: "snake" | "camel" } = { casing: "snake" }
1415
+ ): ModularCodeModel {
1416
+ CASING = options.casing ?? CASING;
1417
+ const dpgContext = createSdkContext(context);
1418
+ const clientNamespaceString =
1419
+ getClientNamespaceString(dpgContext)?.toLowerCase();
1420
+ // Get types
1421
+ const codeModel: ModularCodeModel = {
1422
+ options: transformRLCOptions(
1423
+ context.program,
1424
+ context.options as any,
1425
+ context.emitterOutputDir,
1426
+ dpgContext
1427
+ ),
1428
+ namespace: clientNamespaceString,
1429
+ subnamespaceToClients: {},
1430
+ clients: [],
1431
+ types: []
1432
+ };
1433
+ for (const namespace of getNamespaces(dpgContext)) {
1434
+ if (namespace === clientNamespaceString) {
1435
+ codeModel.clients = emitClients(dpgContext, namespace);
1436
+ } else {
1437
+ codeModel["subnamespaceToClients"][namespace] = emitClients(
1438
+ dpgContext,
1439
+ namespace
1440
+ );
1441
+ }
1442
+ }
1443
+ codeModel.types = [
1444
+ ...[...typesMap.values()].filter((t) => t.name !== "object"),
1445
+ { type: "string" },
1446
+ ...simpleTypesMap.values()
1447
+ ];
1448
+ return codeModel;
1449
+ }