@typespec/http-server-csharp 0.58.0-alpha.28 → 0.58.0-alpha.29-dev.3

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 (279) hide show
  1. package/dist/src/cli/cli.js +118 -154
  2. package/dist/src/cli/cli.js.map +1 -1
  3. package/dist/src/components/controller-action/controller-action.d.ts +16 -0
  4. package/dist/src/components/controller-action/controller-action.d.ts.map +1 -0
  5. package/dist/src/components/controller-action/controller-action.js +251 -0
  6. package/dist/src/components/controller-action/controller-action.js.map +1 -0
  7. package/dist/src/components/controller-action/controller-action.test.d.ts +2 -0
  8. package/dist/src/components/controller-action/controller-action.test.d.ts.map +1 -0
  9. package/dist/src/components/controller-action/controller-action.test.js +106 -0
  10. package/dist/src/components/controller-action/controller-action.test.js.map +1 -0
  11. package/dist/src/components/controller-action/parameter-binding.d.ts +17 -0
  12. package/dist/src/components/controller-action/parameter-binding.d.ts.map +1 -0
  13. package/dist/src/components/controller-action/parameter-binding.js +77 -0
  14. package/dist/src/components/controller-action/parameter-binding.js.map +1 -0
  15. package/dist/src/components/controller-action/response-analysis.d.ts +10 -0
  16. package/dist/src/components/controller-action/response-analysis.d.ts.map +1 -0
  17. package/dist/src/components/controller-action/response-analysis.js +61 -0
  18. package/dist/src/components/controller-action/response-analysis.js.map +1 -0
  19. package/dist/src/components/controllers/controllers.d.ts +18 -0
  20. package/dist/src/components/controllers/controllers.d.ts.map +1 -0
  21. package/dist/src/components/controllers/controllers.js +64 -0
  22. package/dist/src/components/controllers/controllers.js.map +1 -0
  23. package/dist/src/components/controllers/controllers.test.d.ts +2 -0
  24. package/dist/src/components/controllers/controllers.test.d.ts.map +1 -0
  25. package/dist/src/components/controllers/controllers.test.js +84 -0
  26. package/dist/src/components/controllers/controllers.test.js.map +1 -0
  27. package/dist/src/components/csharp-file.d.ts +15 -0
  28. package/dist/src/components/csharp-file.d.ts.map +1 -0
  29. package/dist/src/components/csharp-file.js +28 -0
  30. package/dist/src/components/csharp-file.js.map +1 -0
  31. package/dist/src/components/enums/enums.d.ts +28 -0
  32. package/dist/src/components/enums/enums.d.ts.map +1 -0
  33. package/dist/src/components/enums/enums.js +158 -0
  34. package/dist/src/components/enums/enums.js.map +1 -0
  35. package/dist/src/components/enums/enums.test.d.ts +2 -0
  36. package/dist/src/components/enums/enums.test.d.ts.map +1 -0
  37. package/dist/src/components/enums/enums.test.js +112 -0
  38. package/dist/src/components/enums/enums.test.js.map +1 -0
  39. package/dist/src/components/interfaces/interfaces.d.ts +17 -0
  40. package/dist/src/components/interfaces/interfaces.d.ts.map +1 -0
  41. package/dist/src/components/interfaces/interfaces.js +153 -0
  42. package/dist/src/components/interfaces/interfaces.js.map +1 -0
  43. package/dist/src/components/interfaces/interfaces.test.d.ts +2 -0
  44. package/dist/src/components/interfaces/interfaces.test.d.ts.map +1 -0
  45. package/dist/src/components/interfaces/interfaces.test.js +76 -0
  46. package/dist/src/components/interfaces/interfaces.test.js.map +1 -0
  47. package/dist/src/components/models/anonymous-models.d.ts +9 -0
  48. package/dist/src/components/models/anonymous-models.d.ts.map +1 -0
  49. package/dist/src/components/models/anonymous-models.js +37 -0
  50. package/dist/src/components/models/anonymous-models.js.map +1 -0
  51. package/dist/src/components/models/error-models.d.ts +5 -0
  52. package/dist/src/components/models/error-models.d.ts.map +1 -0
  53. package/dist/src/components/models/error-models.js +84 -0
  54. package/dist/src/components/models/error-models.js.map +1 -0
  55. package/dist/src/components/models/model-helpers.d.ts +40 -0
  56. package/dist/src/components/models/model-helpers.d.ts.map +1 -0
  57. package/dist/src/components/models/model-helpers.js +239 -0
  58. package/dist/src/components/models/model-helpers.js.map +1 -0
  59. package/dist/src/components/models/models.d.ts +15 -0
  60. package/dist/src/components/models/models.d.ts.map +1 -0
  61. package/dist/src/components/models/models.js +234 -0
  62. package/dist/src/components/models/models.js.map +1 -0
  63. package/dist/src/components/models/models.test.d.ts +2 -0
  64. package/dist/src/components/models/models.test.d.ts.map +1 -0
  65. package/dist/src/components/models/models.test.js +151 -0
  66. package/dist/src/components/models/models.test.js.map +1 -0
  67. package/dist/src/components/project/csproj.d.ts +12 -0
  68. package/dist/src/components/project/csproj.d.ts.map +1 -0
  69. package/dist/src/components/project/csproj.js +35 -0
  70. package/dist/src/components/project/csproj.js.map +1 -0
  71. package/dist/src/components/project/csproj.test.d.ts +2 -0
  72. package/dist/src/components/project/csproj.test.d.ts.map +1 -0
  73. package/dist/src/components/project/csproj.test.js +42 -0
  74. package/dist/src/components/project/csproj.test.js.map +1 -0
  75. package/dist/src/components/project/launch-settings.d.ts +16 -0
  76. package/dist/src/components/project/launch-settings.d.ts.map +1 -0
  77. package/dist/src/components/project/launch-settings.js +73 -0
  78. package/dist/src/components/project/launch-settings.js.map +1 -0
  79. package/dist/src/components/project/launch-settings.test.d.ts +2 -0
  80. package/dist/src/components/project/launch-settings.test.d.ts.map +1 -0
  81. package/dist/src/components/project/launch-settings.test.js +48 -0
  82. package/dist/src/components/project/launch-settings.test.js.map +1 -0
  83. package/dist/src/components/project/program.d.ts +14 -0
  84. package/dist/src/components/project/program.d.ts.map +1 -0
  85. package/dist/src/components/project/program.js +75 -0
  86. package/dist/src/components/project/program.js.map +1 -0
  87. package/dist/src/components/project/program.test.d.ts +2 -0
  88. package/dist/src/components/project/program.test.d.ts.map +1 -0
  89. package/dist/src/components/project/program.test.js +50 -0
  90. package/dist/src/components/project/program.test.js.map +1 -0
  91. package/dist/src/components/render-root.d.ts +14 -0
  92. package/dist/src/components/render-root.d.ts.map +1 -0
  93. package/dist/src/components/render-root.js +122 -0
  94. package/dist/src/components/render-root.js.map +1 -0
  95. package/dist/src/components/request-models.d.ts +15 -0
  96. package/dist/src/components/request-models.d.ts.map +1 -0
  97. package/dist/src/components/request-models.js +97 -0
  98. package/dist/src/components/request-models.js.map +1 -0
  99. package/dist/src/components/scaffolding/documentation.d.ts +12 -0
  100. package/dist/src/components/scaffolding/documentation.d.ts.map +1 -0
  101. package/dist/src/{lib/doc.js → components/scaffolding/documentation.js} +56 -46
  102. package/dist/src/components/scaffolding/documentation.js.map +1 -0
  103. package/dist/src/components/scaffolding/mock-helpers.d.ts +10 -0
  104. package/dist/src/components/scaffolding/mock-helpers.d.ts.map +1 -0
  105. package/dist/src/components/scaffolding/mock-helpers.js +268 -0
  106. package/dist/src/components/scaffolding/mock-helpers.js.map +1 -0
  107. package/dist/src/components/scaffolding/mock-implementations.d.ts +14 -0
  108. package/dist/src/components/scaffolding/mock-implementations.d.ts.map +1 -0
  109. package/dist/src/components/scaffolding/mock-implementations.js +152 -0
  110. package/dist/src/components/scaffolding/mock-implementations.js.map +1 -0
  111. package/dist/src/components/scaffolding/mock-return-utils.d.ts +11 -0
  112. package/dist/src/components/scaffolding/mock-return-utils.d.ts.map +1 -0
  113. package/dist/src/components/scaffolding/mock-return-utils.js +62 -0
  114. package/dist/src/components/scaffolding/mock-return-utils.js.map +1 -0
  115. package/dist/src/components/scaffolding/mock-scaffolding.d.ts +6 -0
  116. package/dist/src/components/scaffolding/mock-scaffolding.d.ts.map +1 -0
  117. package/dist/src/components/scaffolding/mock-scaffolding.js +5 -0
  118. package/dist/src/components/scaffolding/mock-scaffolding.js.map +1 -0
  119. package/dist/src/components/scaffolding/mock-scaffolding.test.d.ts +2 -0
  120. package/dist/src/components/scaffolding/mock-scaffolding.test.d.ts.map +1 -0
  121. package/dist/src/components/scaffolding/mock-scaffolding.test.js +59 -0
  122. package/dist/src/components/scaffolding/mock-scaffolding.test.js.map +1 -0
  123. package/dist/src/components/serialization/base64-url-json-converter.d.ts +7 -0
  124. package/dist/src/components/serialization/base64-url-json-converter.d.ts.map +1 -0
  125. package/dist/src/components/serialization/base64-url-json-converter.js +58 -0
  126. package/dist/src/components/serialization/base64-url-json-converter.js.map +1 -0
  127. package/dist/src/components/serialization/constraint-attributes.d.ts +7 -0
  128. package/dist/src/components/serialization/constraint-attributes.d.ts.map +1 -0
  129. package/dist/src/components/serialization/constraint-attributes.js +556 -0
  130. package/dist/src/components/serialization/constraint-attributes.js.map +1 -0
  131. package/dist/src/components/serialization/http-service-exception-filter.d.ts +8 -0
  132. package/dist/src/components/serialization/http-service-exception-filter.d.ts.map +1 -0
  133. package/dist/src/components/serialization/http-service-exception-filter.js +71 -0
  134. package/dist/src/components/serialization/http-service-exception-filter.js.map +1 -0
  135. package/dist/src/components/serialization/json-converters.d.ts +7 -0
  136. package/dist/src/components/serialization/json-converters.d.ts.map +1 -0
  137. package/dist/src/components/serialization/json-converters.js +22 -0
  138. package/dist/src/components/serialization/json-converters.js.map +1 -0
  139. package/dist/src/components/serialization/json-converters.test.d.ts +2 -0
  140. package/dist/src/components/serialization/json-converters.test.d.ts.map +1 -0
  141. package/dist/src/components/serialization/json-converters.test.js +136 -0
  142. package/dist/src/components/serialization/json-converters.test.js.map +1 -0
  143. package/dist/src/components/serialization/json-serialization-provider.d.ts +7 -0
  144. package/dist/src/components/serialization/json-serialization-provider.d.ts.map +1 -0
  145. package/dist/src/components/serialization/json-serialization-provider.js +90 -0
  146. package/dist/src/components/serialization/json-serialization-provider.js.map +1 -0
  147. package/dist/src/components/serialization/time-span-duration-converter.d.ts +7 -0
  148. package/dist/src/components/serialization/time-span-duration-converter.d.ts.map +1 -0
  149. package/dist/src/components/serialization/time-span-duration-converter.js +44 -0
  150. package/dist/src/components/serialization/time-span-duration-converter.js.map +1 -0
  151. package/dist/src/components/serialization/unix-epoch-date-time-converter.d.ts +7 -0
  152. package/dist/src/components/serialization/unix-epoch-date-time-converter.d.ts.map +1 -0
  153. package/dist/src/components/serialization/unix-epoch-date-time-converter.js +71 -0
  154. package/dist/src/components/serialization/unix-epoch-date-time-converter.js.map +1 -0
  155. package/dist/src/components/type-expression/type-expression.d.ts +24 -0
  156. package/dist/src/components/type-expression/type-expression.d.ts.map +1 -0
  157. package/dist/src/components/type-expression/type-expression.js +223 -0
  158. package/dist/src/components/type-expression/type-expression.js.map +1 -0
  159. package/dist/src/components/type-expression/type-expression.test.d.ts +2 -0
  160. package/dist/src/components/type-expression/type-expression.test.d.ts.map +1 -0
  161. package/dist/src/components/type-expression/type-expression.test.js +207 -0
  162. package/dist/src/components/type-expression/type-expression.test.js.map +1 -0
  163. package/dist/src/context/emitter-options-context.d.ts +13 -0
  164. package/dist/src/context/emitter-options-context.d.ts.map +1 -0
  165. package/dist/src/context/emitter-options-context.js +15 -0
  166. package/dist/src/context/emitter-options-context.js.map +1 -0
  167. package/dist/src/diagnostics.d.ts +8 -0
  168. package/dist/src/diagnostics.d.ts.map +1 -0
  169. package/dist/src/diagnostics.js +164 -0
  170. package/dist/src/diagnostics.js.map +1 -0
  171. package/dist/src/emitter.d.ts +8 -0
  172. package/dist/src/emitter.d.ts.map +1 -0
  173. package/dist/src/emitter.js +180 -0
  174. package/dist/src/emitter.js.map +1 -0
  175. package/dist/src/{lib/index.d.ts → index.d.ts} +1 -1
  176. package/dist/src/index.d.ts.map +1 -0
  177. package/dist/src/{lib/index.js → index.js} +1 -1
  178. package/dist/src/index.js.map +1 -0
  179. package/dist/src/{lib/lib.d.ts → lib.d.ts} +4 -14
  180. package/dist/src/lib.d.ts.map +1 -0
  181. package/dist/src/lib.js +133 -0
  182. package/dist/src/lib.js.map +1 -0
  183. package/dist/src/output-writer.d.ts +11 -0
  184. package/dist/src/output-writer.d.ts.map +1 -0
  185. package/dist/src/output-writer.js +72 -0
  186. package/dist/src/output-writer.js.map +1 -0
  187. package/dist/src/service-discovery.d.ts +13 -0
  188. package/dist/src/service-discovery.d.ts.map +1 -0
  189. package/dist/src/service-discovery.js +93 -0
  190. package/dist/src/service-discovery.js.map +1 -0
  191. package/dist/src/service-resolution.d.ts +34 -0
  192. package/dist/src/service-resolution.d.ts.map +1 -0
  193. package/dist/src/service-resolution.js +244 -0
  194. package/dist/src/service-resolution.js.map +1 -0
  195. package/dist/src/testing/index.d.ts +2 -0
  196. package/dist/src/testing/index.d.ts.map +1 -0
  197. package/dist/src/testing/index.js +2 -0
  198. package/dist/src/testing/index.js.map +1 -0
  199. package/dist/src/utils/attributes.d.ts +8 -0
  200. package/dist/src/utils/attributes.d.ts.map +1 -0
  201. package/dist/src/utils/attributes.js +224 -0
  202. package/dist/src/utils/attributes.js.map +1 -0
  203. package/dist/src/utils/csharp-libs.d.ts +87 -0
  204. package/dist/src/utils/csharp-libs.d.ts.map +1 -0
  205. package/dist/src/utils/csharp-libs.js +90 -0
  206. package/dist/src/utils/csharp-libs.js.map +1 -0
  207. package/dist/src/utils/doc-comments.d.ts +2 -0
  208. package/dist/src/utils/doc-comments.d.ts.map +1 -0
  209. package/dist/src/utils/doc-comments.js +4 -0
  210. package/dist/src/utils/doc-comments.js.map +1 -0
  211. package/dist/src/utils/http-helpers.d.ts +19 -0
  212. package/dist/src/utils/http-helpers.d.ts.map +1 -0
  213. package/dist/src/utils/http-helpers.js +70 -0
  214. package/dist/src/utils/http-helpers.js.map +1 -0
  215. package/dist/src/utils/http-helpers.test.d.ts +2 -0
  216. package/dist/src/utils/http-helpers.test.d.ts.map +1 -0
  217. package/dist/src/utils/http-helpers.test.js +68 -0
  218. package/dist/src/utils/http-helpers.test.js.map +1 -0
  219. package/dist/src/utils/namespace-utils.d.ts +13 -0
  220. package/dist/src/utils/namespace-utils.d.ts.map +1 -0
  221. package/dist/src/utils/namespace-utils.js +55 -0
  222. package/dist/src/utils/namespace-utils.js.map +1 -0
  223. package/dist/src/utils/naming.d.ts +31 -0
  224. package/dist/src/utils/naming.d.ts.map +1 -0
  225. package/dist/src/utils/naming.js +87 -0
  226. package/dist/src/utils/naming.js.map +1 -0
  227. package/dist/src/utils/naming.test.d.ts +2 -0
  228. package/dist/src/utils/naming.test.d.ts.map +1 -0
  229. package/dist/src/utils/naming.test.js +86 -0
  230. package/dist/src/utils/naming.test.js.map +1 -0
  231. package/dist/src/utils/port.d.ts +5 -0
  232. package/dist/src/utils/port.d.ts.map +1 -0
  233. package/dist/src/utils/port.js +33 -0
  234. package/dist/src/utils/port.js.map +1 -0
  235. package/dist/src/utils/return-type-helpers.d.ts +8 -0
  236. package/dist/src/utils/return-type-helpers.d.ts.map +1 -0
  237. package/dist/src/utils/return-type-helpers.js +59 -0
  238. package/dist/src/utils/return-type-helpers.js.map +1 -0
  239. package/package.json +36 -28
  240. package/dist/src/lib/attributes.d.ts +0 -43
  241. package/dist/src/lib/attributes.d.ts.map +0 -1
  242. package/dist/src/lib/attributes.js +0 -422
  243. package/dist/src/lib/attributes.js.map +0 -1
  244. package/dist/src/lib/boilerplate.d.ts +0 -6
  245. package/dist/src/lib/boilerplate.d.ts.map +0 -1
  246. package/dist/src/lib/boilerplate.js +0 -792
  247. package/dist/src/lib/boilerplate.js.map +0 -1
  248. package/dist/src/lib/doc.d.ts +0 -5
  249. package/dist/src/lib/doc.d.ts.map +0 -1
  250. package/dist/src/lib/doc.js.map +0 -1
  251. package/dist/src/lib/index.d.ts.map +0 -1
  252. package/dist/src/lib/index.js.map +0 -1
  253. package/dist/src/lib/interfaces.d.ts +0 -183
  254. package/dist/src/lib/interfaces.d.ts.map +0 -1
  255. package/dist/src/lib/interfaces.js +0 -287
  256. package/dist/src/lib/interfaces.js.map +0 -1
  257. package/dist/src/lib/lib.d.ts.map +0 -1
  258. package/dist/src/lib/lib.js +0 -146
  259. package/dist/src/lib/lib.js.map +0 -1
  260. package/dist/src/lib/project.d.ts +0 -5
  261. package/dist/src/lib/project.d.ts.map +0 -1
  262. package/dist/src/lib/project.js +0 -101
  263. package/dist/src/lib/project.js.map +0 -1
  264. package/dist/src/lib/scaffolding.d.ts +0 -22
  265. package/dist/src/lib/scaffolding.d.ts.map +0 -1
  266. package/dist/src/lib/scaffolding.js +0 -461
  267. package/dist/src/lib/scaffolding.js.map +0 -1
  268. package/dist/src/lib/service.d.ts +0 -4
  269. package/dist/src/lib/service.d.ts.map +0 -1
  270. package/dist/src/lib/service.js +0 -1208
  271. package/dist/src/lib/service.js.map +0 -1
  272. package/dist/src/lib/type-helpers.d.ts +0 -44
  273. package/dist/src/lib/type-helpers.d.ts.map +0 -1
  274. package/dist/src/lib/type-helpers.js +0 -106
  275. package/dist/src/lib/type-helpers.js.map +0 -1
  276. package/dist/src/lib/utils.d.ts +0 -120
  277. package/dist/src/lib/utils.d.ts.map +0 -1
  278. package/dist/src/lib/utils.js +0 -1580
  279. package/dist/src/lib/utils.js.map +0 -1
@@ -1,1580 +0,0 @@
1
- import { StringBuilder, code, } from "@typespec/asset-emitter";
2
- import { NoTarget, getFriendlyName, getMinValue, isArrayModelType, isErrorModel, isNullType, isNumericType, isTemplateInstance, isUnknownType, isVoidType, resolveCompilerOptions, resolvePath, serializeValueAsJson, } from "@typespec/compiler";
3
- import { $ } from "@typespec/compiler/typekit";
4
- import { Visibility, createMetadataInfo, getHeaderFieldName, isBody, isBodyRoot, isHeader, isMetadata, isPathParam, isQueryParam, isStatusCode, } from "@typespec/http";
5
- import { getUniqueItems } from "@typespec/json-schema";
6
- import { camelCase, pascalCase } from "change-case";
7
- import { createServer } from "net";
8
- import { getAttributes } from "./attributes.js";
9
- import { BooleanValue, CSharpCollectionType, CSharpType, CollectionType, NameCasingType, NullValue, NumericValue, StringValue, checkOrAddNamespaceToScope, } from "./interfaces.js";
10
- import { CSharpServiceOptions, reportDiagnostic } from "./lib.js";
11
- import { getDoubleType, getEnumType } from "./type-helpers.js";
12
- const _scalars = new Map();
13
- export function getCSharpTypeForScalar(program, scalar) {
14
- if (_scalars.has(scalar))
15
- return _scalars.get(scalar);
16
- if (program.checker.isStdType(scalar)) {
17
- return getCSharpTypeForStdScalars(program, scalar);
18
- }
19
- if (scalar.baseScalar) {
20
- return getCSharpTypeForScalar(program, scalar.baseScalar);
21
- }
22
- reportDiagnostic(program, {
23
- code: "unrecognized-scalar",
24
- format: { typeName: scalar.name },
25
- target: scalar,
26
- });
27
- const result = new CSharpType({
28
- name: "object",
29
- namespace: "System",
30
- isBuiltIn: true,
31
- isValueType: false,
32
- });
33
- _scalars.set(scalar, result);
34
- return result;
35
- }
36
- export const UnknownType = new CSharpType({
37
- name: "JsonNode",
38
- namespace: "System.Text.Json.Nodes",
39
- isValueType: false,
40
- isBuiltIn: false,
41
- isClass: true,
42
- });
43
- export const RecordType = new CSharpType({
44
- name: "JsonObject",
45
- namespace: "System.Text.Json.Nodes",
46
- isBuiltIn: false,
47
- isValueType: false,
48
- isClass: true,
49
- });
50
- export function getCSharpType(program, type, namespace) {
51
- const known = getKnownType(program, type);
52
- if (known !== undefined)
53
- return { type: known };
54
- switch (type.kind) {
55
- case "Boolean":
56
- return { type: standardScalars.get("boolean"), value: new BooleanValue(type.value) };
57
- case "Number":
58
- return { type: standardScalars.get("numeric"), value: new NumericValue(type.value) };
59
- case "String":
60
- return { type: standardScalars.get("string"), value: new StringValue(type.value) };
61
- case "EnumMember":
62
- const enumValue = type.value === undefined ? type.name : type.value;
63
- if (typeof enumValue === "string")
64
- return { type: standardScalars.get("string"), value: new StringValue(enumValue) };
65
- else
66
- return { type: standardScalars.get("numeric"), value: new NumericValue(enumValue) };
67
- case "Intrinsic":
68
- return getCSharpTypeForIntrinsic(program, type);
69
- case "ModelProperty":
70
- return getCSharpType(program, type.type, namespace);
71
- case "Scalar":
72
- return { type: getCSharpTypeForScalar(program, type) };
73
- case "Tuple":
74
- const resolvedItem = coalesceTypes(program, type.values, namespace);
75
- const itemType = resolvedItem.type;
76
- return {
77
- type: new CSharpType({
78
- name: `${itemType.name}[]`,
79
- namespace: itemType.namespace,
80
- isBuiltIn: itemType.isBuiltIn,
81
- isValueType: false,
82
- }),
83
- };
84
- case "UnionVariant":
85
- return getCSharpType(program, type.type, namespace);
86
- case "Union":
87
- return coalesceTypes(program, [...type.variants.values()].map((v) => v.type), namespace);
88
- case "Interface":
89
- return {
90
- type: new CSharpType({
91
- name: ensureCSharpIdentifier(program, type, type.name, NameCasingType.Class),
92
- namespace: `${namespace}`,
93
- isBuiltIn: false,
94
- isValueType: false,
95
- isClass: true,
96
- }),
97
- };
98
- case "Enum":
99
- if (getEnumType(type) === "double")
100
- return { type: getDoubleType() };
101
- return {
102
- type: new CSharpType({
103
- name: ensureCSharpIdentifier(program, type, type.name, NameCasingType.Class),
104
- namespace: `${namespace}`,
105
- isBuiltIn: false,
106
- isValueType: true,
107
- }),
108
- };
109
- case "Model":
110
- if (type.indexer !== undefined && isNumericType(program, type.indexer?.key)) {
111
- const resolvedItem = getCSharpType(program, type.indexer.value, namespace);
112
- if (resolvedItem === undefined)
113
- return undefined;
114
- const { type: itemType, value: _ } = resolvedItem;
115
- const uniqueItems = getUniqueItems(program, type);
116
- const isByte = ["byte", "SByte"].includes(itemType.name);
117
- const collectionType = CSharpServiceOptions.getInstance().collectionType;
118
- const returnTypeCollection = uniqueItems
119
- ? CollectionType.ISet
120
- : isByte
121
- ? CollectionType.Array
122
- : collectionType;
123
- const returnType = returnTypeCollection === CollectionType.Array
124
- ? `${itemType.name}[]`
125
- : `${returnTypeCollection}<${itemType.name}>`;
126
- return {
127
- type: new CSharpCollectionType({
128
- name: returnType,
129
- namespace: itemType.namespace,
130
- isBuiltIn: itemType.isBuiltIn,
131
- isValueType: false,
132
- isClass: itemType.isClass,
133
- isCollection: true,
134
- }, returnTypeCollection, itemType.name),
135
- };
136
- }
137
- if (isRecord(type))
138
- return {
139
- type: RecordType,
140
- };
141
- let name = type.name;
142
- if (isTemplateInstance(type)) {
143
- name = getModelInstantiationName(program, type, name);
144
- }
145
- return {
146
- type: new CSharpType({
147
- name: ensureCSharpIdentifier(program, type, name, NameCasingType.Class),
148
- namespace: `${namespace}`,
149
- isBuiltIn: false,
150
- isValueType: false,
151
- isClass: true,
152
- }),
153
- };
154
- default:
155
- return undefined;
156
- }
157
- }
158
- export function resolveReferenceFromScopes(targetDeclaration, declarationScopes, referenceScopes) {
159
- function getSourceFile(scopes) {
160
- for (const scope of scopes) {
161
- if (scope.kind === "sourceFile") {
162
- return { scope: scope, file: scope.sourceFile };
163
- }
164
- }
165
- return undefined;
166
- }
167
- const decl = getSourceFile(declarationScopes);
168
- const ref = getSourceFile(referenceScopes);
169
- if (targetDeclaration.name && decl) {
170
- const declNs = decl.file.meta["ResolvedNamespace"];
171
- if (!ref)
172
- return declNs ? `${declNs}.${targetDeclaration.name} ` : undefined;
173
- if (checkOrAddNamespaceToScope(declNs, ref.scope)) {
174
- return targetDeclaration.name;
175
- }
176
- return declNs ? `${declNs}.${targetDeclaration.name} ` : undefined;
177
- }
178
- return undefined;
179
- }
180
- export function coalesceTypes(program, types, namespace) {
181
- const visited = new Map();
182
- let candidateType = undefined;
183
- let candidateValue = undefined;
184
- for (const type of types) {
185
- if (!isNullType(type)) {
186
- if (!visited.has(type)) {
187
- const resolvedType = getCSharpType(program, type, namespace);
188
- if (resolvedType === undefined)
189
- return { type: UnknownType };
190
- if (resolvedType.type === UnknownType)
191
- return resolvedType;
192
- if (candidateType === undefined) {
193
- candidateType = resolvedType.type;
194
- candidateValue = resolvedType.value;
195
- }
196
- else {
197
- if (candidateValue !== resolvedType.value)
198
- candidateValue = undefined;
199
- if (candidateType !== resolvedType.type)
200
- return { type: UnknownType };
201
- }
202
- visited.set(type, resolvedType);
203
- }
204
- }
205
- }
206
- return { type: candidateType !== undefined ? candidateType : UnknownType, value: candidateValue };
207
- }
208
- export function getKnownType(program, type) {
209
- return undefined;
210
- }
211
- export function getCSharpTypeForIntrinsic(program, type) {
212
- if (isUnknownType(type)) {
213
- return { type: UnknownType };
214
- }
215
- if (isVoidType(type)) {
216
- return {
217
- type: new CSharpType({
218
- name: "void",
219
- namespace: "System",
220
- isBuiltIn: true,
221
- isValueType: false,
222
- }),
223
- };
224
- }
225
- if (isNullType(type)) {
226
- return {
227
- type: new CSharpType({
228
- name: "object",
229
- namespace: "System",
230
- isBuiltIn: true,
231
- isValueType: false,
232
- }),
233
- value: new NullValue(),
234
- };
235
- }
236
- return undefined;
237
- }
238
- const standardScalars = new Map([
239
- [
240
- "bytes",
241
- new CSharpType({ name: "byte[]", namespace: "System", isBuiltIn: true, isValueType: false }),
242
- ],
243
- [
244
- "int8",
245
- new CSharpType({ name: "SByte", namespace: "System", isBuiltIn: true, isValueType: true }),
246
- ],
247
- [
248
- "uint8",
249
- new CSharpType({ name: "Byte", namespace: "System", isBuiltIn: true, isValueType: true }),
250
- ],
251
- [
252
- "int16",
253
- new CSharpType({ name: "Int16", namespace: "System", isBuiltIn: true, isValueType: true }),
254
- ],
255
- [
256
- "uint16",
257
- new CSharpType({ name: "UInt16", namespace: "System", isBuiltIn: true, isValueType: true }),
258
- ],
259
- [
260
- "int16",
261
- new CSharpType({ name: "Int16", namespace: "System", isBuiltIn: true, isValueType: true }),
262
- ],
263
- [
264
- "uint16",
265
- new CSharpType({ name: "UInt16", namespace: "System", isBuiltIn: true, isValueType: true }),
266
- ],
267
- [
268
- "int32",
269
- new CSharpType({ name: "int", namespace: "System", isBuiltIn: true, isValueType: true }),
270
- ],
271
- [
272
- "uint32",
273
- new CSharpType({ name: "UInt32", namespace: "System", isBuiltIn: true, isValueType: true }),
274
- ],
275
- [
276
- "integer",
277
- new CSharpType({ name: "long", namespace: "System", isBuiltIn: true, isValueType: true }),
278
- ],
279
- [
280
- "int64",
281
- new CSharpType({ name: "long", namespace: "System", isBuiltIn: true, isValueType: true }),
282
- ],
283
- [
284
- "uint64",
285
- new CSharpType({ name: "UInt64", namespace: "System", isBuiltIn: true, isValueType: true }),
286
- ],
287
- [
288
- "safeint",
289
- new CSharpType({ name: "long", namespace: "System", isBuiltIn: true, isValueType: true }),
290
- ],
291
- [
292
- "float",
293
- new CSharpType({ name: "double", namespace: "System", isBuiltIn: true, isValueType: true }),
294
- ],
295
- [
296
- "float64",
297
- new CSharpType({ name: "double", namespace: "System", isBuiltIn: true, isValueType: true }),
298
- ],
299
- [
300
- "float32",
301
- new CSharpType({ name: "float", namespace: "System", isBuiltIn: true, isValueType: true }),
302
- ],
303
- [
304
- "string",
305
- new CSharpType({ name: "string", namespace: "System", isBuiltIn: true, isValueType: false }),
306
- ],
307
- [
308
- "boolean",
309
- new CSharpType({ name: "bool", namespace: "System", isBuiltIn: true, isValueType: true }),
310
- ],
311
- [
312
- "plainDate",
313
- new CSharpType({ name: "DateTime", namespace: "System", isBuiltIn: true, isValueType: true }),
314
- ],
315
- [
316
- "utcDateTime",
317
- new CSharpType({
318
- name: "DateTimeOffset",
319
- namespace: "System",
320
- isBuiltIn: true,
321
- isValueType: true,
322
- }),
323
- ],
324
- [
325
- "offsetDateTime",
326
- new CSharpType({
327
- name: "DateTimeOffset",
328
- namespace: "System",
329
- isBuiltIn: true,
330
- isValueType: true,
331
- }),
332
- ],
333
- [
334
- "unixTimestamp32",
335
- new CSharpType({
336
- name: "DateTimeOffset",
337
- namespace: "System",
338
- isBuiltIn: true,
339
- isValueType: true,
340
- }),
341
- ],
342
- [
343
- "plainTime",
344
- new CSharpType({ name: "DateTime", namespace: "System", isBuiltIn: true, isValueType: true }),
345
- ],
346
- [
347
- "duration",
348
- new CSharpType({ name: "TimeSpan", namespace: "System", isBuiltIn: true, isValueType: true }),
349
- ],
350
- [
351
- "numeric",
352
- new CSharpType({ name: "object", namespace: "System", isBuiltIn: true, isValueType: false }),
353
- ],
354
- [
355
- "url",
356
- new CSharpType({ name: "string", namespace: "System", isBuiltIn: true, isValueType: false }),
357
- ],
358
- [
359
- "decimal",
360
- new CSharpType({ name: "decimal", namespace: "System", isBuiltIn: true, isValueType: true }),
361
- ],
362
- [
363
- "decimal128",
364
- new CSharpType({ name: "decimal", namespace: "System", isBuiltIn: true, isValueType: true }),
365
- ],
366
- ]);
367
- export function getCSharpTypeForStdScalars(program, scalar) {
368
- const cached = _scalars.get(scalar);
369
- if (cached !== undefined)
370
- return cached;
371
- const builtIn = standardScalars.get(scalar.name);
372
- if (builtIn !== undefined) {
373
- _scalars.set(scalar, builtIn);
374
- if (scalar.name === "numeric" || scalar.name === "integer" || scalar.name === "float") {
375
- reportDiagnostic(program, {
376
- code: "no-numeric",
377
- format: { sourceType: scalar.name, targetType: builtIn?.getTypeReference() },
378
- target: scalar,
379
- });
380
- }
381
- return builtIn;
382
- }
383
- reportDiagnostic(program, {
384
- code: "unrecognized-scalar",
385
- format: { typeName: scalar.name },
386
- target: scalar,
387
- });
388
- return new CSharpType({
389
- name: "Object",
390
- namespace: "System",
391
- isBuiltIn: true,
392
- isValueType: false,
393
- });
394
- }
395
- export function isValueType(program, type) {
396
- if (type.kind === "Boolean" ||
397
- type.kind === "Number" ||
398
- type.kind === "Enum" ||
399
- type.kind === "EnumMember")
400
- return true;
401
- if (type.kind === "Scalar")
402
- return getCSharpTypeForScalar(program, type).isValueType;
403
- if (type.kind !== "Union")
404
- return false;
405
- return [...type.variants.values()]
406
- .flatMap((v) => v.type)
407
- .every((t) => isNullType(t) || isValueType(program, t));
408
- }
409
- export function formatComment(text, lineLength = 76, lineEnd = "\n") {
410
- function getNextLine(target) {
411
- for (let i = lineLength - 1; i > 0; i--) {
412
- if ([" ", ";"].includes(target.charAt(i))) {
413
- return `${target.substring(0, i)}`;
414
- }
415
- }
416
- for (let i = lineLength - 1; i < target.length; i++) {
417
- if ([" ", ";"].includes(target.charAt(i))) {
418
- return `${target.substring(0, i)}`;
419
- }
420
- }
421
- return `${target.substring(0, lineLength)}`;
422
- }
423
- let remaining = text.replaceAll("\n", " ");
424
- const lines = [];
425
- while (remaining.length > lineLength) {
426
- const currentLine = getNextLine(remaining);
427
- remaining =
428
- remaining.length > currentLine.length ? remaining.substring(currentLine.length + 1) : "";
429
- lines.push(`/// ${currentLine}`);
430
- }
431
- if (remaining.length > 0)
432
- lines.push(`/// ${remaining}`);
433
- return `///<summary>${lineEnd}${lines.join(lineEnd)}${lineEnd}///</summary>`;
434
- }
435
- export function getCSharpIdentifier(name, context = NameCasingType.Class, checkReserved = true) {
436
- if (name === undefined)
437
- return "Placeholder";
438
- name = replaceCSharpReservedWord(name, context);
439
- switch (context) {
440
- case NameCasingType.Namespace:
441
- const parts = [];
442
- for (const part of name.split(".")) {
443
- parts.push(getCSharpIdentifier(part, NameCasingType.Class));
444
- }
445
- return parts.join(".");
446
- case NameCasingType.Parameter:
447
- case NameCasingType.Variable:
448
- return `${camelCase(name)}`;
449
- default:
450
- return `${pascalCase(name)}`;
451
- }
452
- }
453
- export function ensureCSharpIdentifier(program, target, name, context = NameCasingType.Class) {
454
- let location = "";
455
- let includeDot = false;
456
- switch (target.kind) {
457
- case "Enum":
458
- location = `enum ${target.name}`;
459
- break;
460
- case "EnumMember":
461
- location = `enum ${target.enum.name}`;
462
- break;
463
- case "Interface":
464
- location = `interface ${target.name}`;
465
- break;
466
- case "Model":
467
- location = `model ${target.name}`;
468
- break;
469
- case "ModelProperty": {
470
- const model = target.model;
471
- if (!model) {
472
- reportDiagnostic(program, {
473
- code: "missing-type-parent",
474
- format: { type: "ModelProperty", name: target.name },
475
- target: target,
476
- });
477
- }
478
- else {
479
- location = `property '${target.name}' in model ${model?.name}`;
480
- if (!model.name) {
481
- location = `parameter '${target.name}' in operation`;
482
- }
483
- }
484
- break;
485
- }
486
- case "Namespace":
487
- location = `namespace ${target.name}`;
488
- let invalid = false;
489
- for (const part of name.split(".")) {
490
- if (!isValidCSharpIdentifier(part)) {
491
- invalid = true;
492
- }
493
- }
494
- if (invalid) {
495
- reportDiagnostic(program, {
496
- code: "invalid-identifier",
497
- format: { identifier: name, location: location },
498
- target: target.node ?? NoTarget,
499
- });
500
- }
501
- includeDot = true;
502
- break;
503
- case "Operation": {
504
- const parent = target.interface
505
- ? `interface ${target.interface.name}`
506
- : `namespace ${target.namespace?.name}`;
507
- location = `operation ${target.name} in ${parent}`;
508
- break;
509
- }
510
- case "Union":
511
- location = `union ${target.name}`;
512
- break;
513
- case "UnionVariant": {
514
- location = `variant ${String(target.name)} in union ${target.union.name}`;
515
- break;
516
- }
517
- }
518
- if (!isValidCSharpIdentifier(name, includeDot)) {
519
- reportDiagnostic(program, {
520
- code: "invalid-identifier",
521
- format: { identifier: name, location: location },
522
- target: target.node ?? NoTarget,
523
- });
524
- return getCSharpIdentifier(transformInvalidIdentifier(name), context);
525
- }
526
- return getCSharpIdentifier(name, context);
527
- }
528
- export function getModelAttributes(program, entity, cSharpName) {
529
- return getAttributes(program, entity, cSharpName);
530
- }
531
- export function getModelDeclarationName(program, model, defaultSuffix) {
532
- if (model.name !== null && model.name.length > 0) {
533
- return ensureCSharpIdentifier(program, model, model.name, NameCasingType.Class);
534
- }
535
- if (model.sourceModel && model.sourceModel.name && model.sourceModel.name.length > 0) {
536
- return ensureCSharpIdentifier(program, model, `${model.sourceModel.name}${defaultSuffix}`, NameCasingType.Class);
537
- }
538
- if (model.sourceModels.length > 0) {
539
- const sourceNames = model.sourceModels
540
- .filter((m) => m.model.name !== undefined && m.model.name.length > 0)
541
- .flatMap((m) => ensureCSharpIdentifier(program, model, m.model.name, NameCasingType.Class));
542
- if (sourceNames.length > 0) {
543
- return `${sourceNames.join()}${defaultSuffix}`;
544
- }
545
- }
546
- return `Model${defaultSuffix}`;
547
- }
548
- export function getModelInstantiationName(program, model, name) {
549
- const friendlyName = getFriendlyName(program, model);
550
- if (friendlyName && friendlyName.length > 0)
551
- return friendlyName;
552
- if (name === undefined || name.length < 1)
553
- name = ensureCSharpIdentifier(program, model, "", NameCasingType.Class);
554
- const names = [name];
555
- if (model.templateMapper !== undefined) {
556
- for (const paramType of model.templateMapper.args) {
557
- if (paramType.entityKind === "Type") {
558
- switch (paramType.kind) {
559
- case "Enum":
560
- case "EnumMember":
561
- case "Model":
562
- case "ModelProperty":
563
- case "Namespace":
564
- case "Scalar":
565
- case "Union":
566
- names.push(getCSharpIdentifier(paramType?.name ?? paramType.kind, NameCasingType.Class));
567
- break;
568
- default:
569
- names.push(getCSharpIdentifier(paramType.kind, NameCasingType.Class));
570
- break;
571
- }
572
- }
573
- }
574
- }
575
- return ensureCSharpIdentifier(program, model, names.join(""), NameCasingType.Class);
576
- }
577
- export class ModelInfo {
578
- visited = [];
579
- getAllProperties(program, model) {
580
- if (this.visited.includes(model))
581
- return undefined;
582
- this.visited.push(model);
583
- const props = [];
584
- for (const prop of model.properties.values())
585
- props.push(prop);
586
- if (model.baseModel) {
587
- const additional = this.getAllProperties(program, model.baseModel);
588
- if (additional !== undefined)
589
- props.concat(additional);
590
- }
591
- return props;
592
- }
593
- filterAllProperties(program, model, filter) {
594
- if (this.visited.includes(model))
595
- return undefined;
596
- this.visited.push(model);
597
- for (const prop of model.properties.values()) {
598
- if (filter(prop))
599
- return prop;
600
- }
601
- if (model.baseModel !== undefined) {
602
- return this.filterAllProperties(program, model.baseModel, filter);
603
- }
604
- return undefined;
605
- }
606
- }
607
- export function getPropertySource(program, property) {
608
- let result = property.model;
609
- while (property.sourceProperty !== undefined) {
610
- const current = property.sourceProperty;
611
- result = current.model;
612
- property = property.sourceProperty;
613
- }
614
- return result;
615
- }
616
- export function getSourceModel(program, model) {
617
- const modelTracker = new Set();
618
- for (const prop of model.properties.values()) {
619
- const source = getPropertySource(program, prop);
620
- if (source === undefined)
621
- return undefined;
622
- modelTracker.add(source);
623
- }
624
- if (modelTracker.size === 1)
625
- return [...modelTracker.values()][0];
626
- return undefined;
627
- }
628
- export class HttpMetadata {
629
- resolveLogicalResponseType(program, response) {
630
- const responseType = response.type;
631
- const metaInfo = createMetadataInfo(program, {
632
- canonicalVisibility: Visibility.Read,
633
- canShareProperty: (p) => true,
634
- });
635
- switch (responseType.kind) {
636
- case "Model":
637
- if (responseType.indexer && responseType.indexer.key.name !== "string")
638
- return responseType;
639
- if (isRecord(responseType))
640
- return responseType;
641
- const bodyProp = new ModelInfo().filterAllProperties(program, responseType, (p) => isBody(program, p) || isBodyRoot(program, p));
642
- if (bodyProp !== undefined)
643
- return metaInfo.getEffectivePayloadType(bodyProp.type, Visibility.Read);
644
- const anyProp = new ModelInfo().filterAllProperties(program, responseType, (p) => !isMetadata(program, p) && !isStatusCode(program, p));
645
- if (anyProp === undefined)
646
- return $(program).intrinsic.void;
647
- if (responseType.name === "") {
648
- return metaInfo.getEffectivePayloadType(responseType, Visibility.Read);
649
- }
650
- break;
651
- }
652
- return responseType;
653
- }
654
- }
655
- export function getOperationAttributes(program, entity) {
656
- return getAttributes(program, entity);
657
- }
658
- export function transformInvalidIdentifier(name) {
659
- const result = new StringBuilder();
660
- for (let i = 0; i < name.length; ++i) {
661
- result.pushLiteralSegment(getValidChar(name.charAt(i), i));
662
- }
663
- return result.segments.join("");
664
- }
665
- export function getOperationVerbDecorator(operation) {
666
- switch (operation.verb) {
667
- case "delete":
668
- return "HttpDelete";
669
- case "get":
670
- return "HttpGet";
671
- case "patch":
672
- return "HttpPatch";
673
- case "post":
674
- return "HttpPost";
675
- case "put":
676
- return "HttpPut";
677
- default:
678
- return "HttpGet";
679
- }
680
- }
681
- export function hasNonMetadataProperties(program, model) {
682
- const props = [...model.properties.values()].filter((p) => !isMetadata(program, p));
683
- return props.length > 0;
684
- }
685
- export async function ensureCleanDirectory(program, targetPath) {
686
- try {
687
- await program.host.stat(targetPath);
688
- await program.host.rm(targetPath, { recursive: true });
689
- }
690
- catch { }
691
- await program.host.mkdirp(targetPath);
692
- }
693
- export function isValidCSharpIdentifier(identifier, isNamespace = false) {
694
- if (!isNamespace)
695
- return identifier?.match(/^[A-Za-z_][\w]*$/) !== null;
696
- return identifier?.match(/^[A-Za-z_][\w.]*$/) !== null;
697
- }
698
- export function replaceCSharpReservedWord(identifier, context) {
699
- function generateReplacement(input) {
700
- return [input, `${pascalCase(input)}Name`];
701
- }
702
- const contextualWords = [
703
- "add",
704
- "allows",
705
- "alias",
706
- "and",
707
- "ascending",
708
- "args",
709
- "async",
710
- "await",
711
- "by",
712
- "descending",
713
- "dynamic",
714
- "equals",
715
- "field",
716
- "file",
717
- "from",
718
- "get",
719
- "global",
720
- "group",
721
- "init",
722
- "into",
723
- "join",
724
- "let",
725
- "managed",
726
- "nameof",
727
- "nint",
728
- "not",
729
- "notnull",
730
- "nuint",
731
- "on",
732
- "or",
733
- "orderby",
734
- "partial",
735
- "record",
736
- "remove",
737
- "required",
738
- "scoped",
739
- "select",
740
- "set",
741
- "unmanaged",
742
- "value",
743
- "var",
744
- "when",
745
- "where",
746
- "with",
747
- "yield",
748
- ];
749
- const reservedWords = [
750
- "abstract",
751
- "as",
752
- "base",
753
- "bool",
754
- "boolean",
755
- "break",
756
- "byte",
757
- "case",
758
- "catch",
759
- "char",
760
- "checked",
761
- "class",
762
- "const",
763
- "continue",
764
- "decimal",
765
- "default",
766
- "do",
767
- "double",
768
- "else",
769
- "enum",
770
- "event",
771
- "explicit",
772
- "extern",
773
- "false",
774
- "finally",
775
- "fixed",
776
- "float",
777
- "for",
778
- "foreach",
779
- "goto",
780
- "if",
781
- "implicit",
782
- "in",
783
- "int",
784
- "interface",
785
- "internal",
786
- "is",
787
- "lock",
788
- "long",
789
- "namespace",
790
- "new",
791
- "null",
792
- "object",
793
- "operator",
794
- "out",
795
- "override",
796
- "params",
797
- "private",
798
- "protected",
799
- "public",
800
- "readonly",
801
- "ref",
802
- "return",
803
- "sbyte",
804
- "sealed",
805
- "short",
806
- "sizeof",
807
- "stackalloc",
808
- "static",
809
- "string",
810
- "struct",
811
- "switch",
812
- "this",
813
- "throw",
814
- "true",
815
- "try",
816
- "type",
817
- "typeof",
818
- "uint",
819
- "ulong",
820
- "unchecked",
821
- "unsafe",
822
- "ushort",
823
- "using",
824
- "virtual",
825
- "void",
826
- "volatile",
827
- "while",
828
- ];
829
- const reserved = new Map(reservedWords.concat(contextualWords).map((w) => generateReplacement(w)));
830
- const check = reserved.get(identifier.toLowerCase());
831
- if (check !== undefined) {
832
- return getCSharpIdentifier(check, context, false);
833
- }
834
- return identifier;
835
- }
836
- export function getValidChar(target, position) {
837
- if (position === 0) {
838
- if (target.match(/[A-Za-z_]/))
839
- return target;
840
- return `Generated_${target.match(/\w/) ? target : ""}`;
841
- }
842
- if (!target.match(/[\w]/))
843
- return "_";
844
- return target;
845
- }
846
- export function getCSharpStatusCode(entry) {
847
- switch (entry) {
848
- case 200:
849
- return "HttpStatusCode.OK";
850
- case 201:
851
- return "HttpStatusCode.Created";
852
- case 202:
853
- return "HttpStatusCode.Accepted";
854
- case 204:
855
- return "HttpStatusCode.NoContent";
856
- default:
857
- return undefined;
858
- }
859
- }
860
- /**
861
- * Returns the full return statement for a controller action based on the HTTP status code.
862
- * Maps well-known status codes to their idiomatic ASP.NET Core ControllerBase methods,
863
- * and falls back to `StatusCode(code, ...)` for all other numeric codes.
864
- */
865
- export function getControllerReturnStatement(status, hasValue) {
866
- if (typeof status === "number") {
867
- switch (status) {
868
- case 200:
869
- return hasValue ? "return Ok(result);" : "return Ok();";
870
- case 202:
871
- return hasValue ? "return Accepted(result);" : "return Accepted();";
872
- case 204:
873
- return "return NoContent();";
874
- default:
875
- return hasValue ? `return StatusCode(${status}, result);` : `return StatusCode(${status});`;
876
- }
877
- }
878
- // Fallback for ranges and "*"
879
- return hasValue ? "return Ok(result);" : "return Ok();";
880
- }
881
- export function isEmptyResponseModel(program, model) {
882
- if (model.kind !== "Model")
883
- return false;
884
- if (model.properties.size === 0 && !model.baseModel)
885
- return true;
886
- return (model.properties.size === 1 &&
887
- isStatusCode(program, [...model.properties.values()][0]) &&
888
- !isErrorModel(program, model));
889
- }
890
- export function isContentTypeHeader(program, parameter) {
891
- return (isHeader(program, parameter) &&
892
- (parameter.name === "contentType" || getHeaderFieldName(program, parameter) === "Content-type"));
893
- }
894
- export function isValidParameter(program, parameter) {
895
- return (!isContentTypeHeader(program, parameter) &&
896
- (parameter.type.kind !== "Intrinsic" || parameter.type.name !== "never") &&
897
- parameter.model?.name === "");
898
- }
899
- /** Determine whether the given parameter is http metadata */
900
- export function isHttpMetadata(program, property) {
901
- return (isPathParam(program, property) || isHeader(program, property) || isQueryParam(program, property));
902
- }
903
- export function getBusinessLogicCallParameters(parameters) {
904
- const builder = new StringBuilder();
905
- const blParameters = parameters.filter((p) => p.operationKind === "BusinessLogic" || p.operationKind === "All");
906
- let i = 0;
907
- for (const param of blParameters) {
908
- builder.push(code `${getBusinessLogicCallParameter(param)}${++i < blParameters.length ? ", " : ""}`);
909
- }
910
- return builder.reduce();
911
- }
912
- export function getBusinessLogicDeclParameters(parameters) {
913
- const builder = new StringBuilder();
914
- const blParameters = parameters.filter((p) => p.operationKind === "BusinessLogic" || p.operationKind === "All");
915
- let i = 0;
916
- for (const param of blParameters) {
917
- builder.push(code `${getBusinessLogicSignatureParameter(param)}${++i < blParameters.length ? ", " : ""}`);
918
- }
919
- return builder.reduce();
920
- }
921
- export function getHttpDeclParameters(parameters) {
922
- const builder = new StringBuilder();
923
- const blParameters = parameters.filter((p) => p.operationKind === "Http" || p.operationKind === "All");
924
- let i = 0;
925
- for (const param of blParameters) {
926
- builder.push(code `${getHttpSignatureParameter(param)}${++i < blParameters.length ? ", " : ""}`);
927
- }
928
- return builder.reduce();
929
- }
930
- export function getBusinessLogicCallParameter(param) {
931
- const builder = new StringBuilder();
932
- builder.push(code `${param.callName}`);
933
- return builder.reduce();
934
- }
935
- export function getBusinessLogicSignatureParameter(param) {
936
- const builder = new StringBuilder();
937
- builder.push(code `${param.typeName}${param.optional || param.nullable ? "? " : " "}${param.name}`);
938
- return builder.reduce();
939
- }
940
- export function getHttpSignatureParameter(param) {
941
- const builder = new StringBuilder();
942
- builder.push(code `${getHttpParameterDecorator(param)}${getBusinessLogicSignatureParameter(param)}${param.defaultValue === undefined ? "" : code ` = ${typeof param.defaultValue === "boolean" ? code `${param.defaultValue.toString()}` : code `${param.defaultValue}`}`}`);
943
- return builder.reduce();
944
- }
945
- export function getHttpParameterDecorator(parameter) {
946
- switch (parameter.httpParameterKind) {
947
- case "query":
948
- return code `[FromQuery${parameter.httpParameterName ? code `(Name="${parameter.httpParameterName}")` : ""}] `;
949
- case "header":
950
- return code `[FromHeader${parameter.httpParameterName ? code `(Name="${parameter.httpParameterName}")` : ""}] `;
951
- default:
952
- return "";
953
- }
954
- }
955
- export function getParameterKind(parameter) {
956
- switch (parameter.type) {
957
- case "path":
958
- return "path";
959
- case "cookie":
960
- case "header":
961
- return "header";
962
- case "query":
963
- return "query";
964
- }
965
- }
966
- export function canHaveDefault(program, type) {
967
- switch (type.kind) {
968
- case "Boolean":
969
- case "EnumMember":
970
- case "Enum":
971
- case "Number":
972
- case "String":
973
- case "Scalar":
974
- case "StringTemplate":
975
- return true;
976
- case "ModelProperty":
977
- return canHaveDefault(program, type.type);
978
- default:
979
- return false;
980
- }
981
- }
982
- export class CSharpOperationHelpers {
983
- constructor(inEmitter) {
984
- this.emitter = inEmitter;
985
- this.#anonymousModels = new Map();
986
- this.#opCache = new Map();
987
- }
988
- emitter;
989
- #anonymousModels;
990
- #opCache;
991
- getResponse(program, operation) {
992
- return new CSharpType({
993
- name: "void",
994
- namespace: "System",
995
- isBuiltIn: true,
996
- isValueType: true,
997
- });
998
- }
999
- getParameters(program, operation) {
1000
- function safeConcat(...names) {
1001
- return names
1002
- .filter((n) => n !== undefined && n !== null && n.length > 0)
1003
- .flatMap((s) => getCSharpIdentifier(s, NameCasingType.Class))
1004
- .join();
1005
- }
1006
- const cached = this.#opCache.get(operation.operation);
1007
- if (cached)
1008
- return cached;
1009
- const bodyParam = operation.parameters.body;
1010
- const isExplicitBodyParam = bodyParam?.property !== undefined;
1011
- const result = [];
1012
- if (!cached && operation.verb === "get" && operation.parameters.body !== undefined) {
1013
- reportDiagnostic(program, {
1014
- code: "get-request-body",
1015
- target: operation.operation,
1016
- format: {},
1017
- });
1018
- this.#opCache.set(operation.operation, result);
1019
- return result;
1020
- }
1021
- const validParams = operation.parameters.parameters.filter((p) => isValidParameter(program, p.param));
1022
- const requiredParams = validParams.filter((p) => p.type === "path" || (!p.param.optional && p.param.defaultValue === undefined));
1023
- const optionalParams = validParams.filter((p) => p.type !== "path" && (p.param.optional || p.param.defaultValue !== undefined));
1024
- for (const parameter of requiredParams) {
1025
- let { typeReference: paramType, defaultValue: paramValue } = this.getTypeInfo(program, parameter.param.type);
1026
- // cSharp does not allow array defaults in operation parameters
1027
- if (!canHaveDefault(program, parameter.param)) {
1028
- paramValue = undefined;
1029
- }
1030
- const paramName = ensureCSharpIdentifier(program, parameter.param, parameter.param.name, NameCasingType.Parameter);
1031
- result.push({
1032
- isExplicitBody: false,
1033
- name: paramName,
1034
- callName: paramName,
1035
- optional: false,
1036
- typeName: paramType,
1037
- defaultValue: paramValue,
1038
- httpParameterKind: getParameterKind(parameter),
1039
- httpParameterName: parameter.name,
1040
- nullable: false,
1041
- operationKind: "All",
1042
- });
1043
- }
1044
- const overrideParameters = getExplicitBodyParameters(program, operation);
1045
- if (overrideParameters !== undefined) {
1046
- for (const overrideParam of overrideParameters) {
1047
- result.push(overrideParam);
1048
- }
1049
- }
1050
- else if (bodyParam !== undefined && isExplicitBodyParam) {
1051
- let { typeReference: bodyType, defaultValue: bodyValue, nullableType: isNullable, } = this.getTypeInfo(program, bodyParam.type);
1052
- if (!canHaveDefault(program, bodyParam.type)) {
1053
- bodyValue = undefined;
1054
- }
1055
- result.push({
1056
- isExplicitBody: true,
1057
- httpParameterKind: "body",
1058
- name: "body",
1059
- callName: "body",
1060
- typeName: bodyType,
1061
- nullable: isNullable,
1062
- defaultValue: bodyValue,
1063
- optional: bodyParam.property?.optional ?? false,
1064
- operationKind: "All",
1065
- });
1066
- }
1067
- else if (bodyParam !== undefined) {
1068
- switch (bodyParam.type.kind) {
1069
- case "Model":
1070
- let tsBody = bodyParam.type;
1071
- if (!bodyParam.type.name) {
1072
- tsBody = program.checker.cloneType(bodyParam.type, {
1073
- name: safeConcat(operation.operation.interface?.name, operation.operation.name, "Request"),
1074
- });
1075
- }
1076
- const { typeReference: bodyType } = this.getTypeInfo(program, tsBody);
1077
- const bodyName = ensureCSharpIdentifier(program, bodyParam.type, "body", NameCasingType.Parameter);
1078
- result.push({
1079
- isExplicitBody: false,
1080
- httpParameterKind: "body",
1081
- name: bodyName,
1082
- callName: bodyName,
1083
- typeName: bodyType,
1084
- nullable: false,
1085
- defaultValue: undefined,
1086
- optional: false,
1087
- operationKind: "Http",
1088
- });
1089
- for (const [propName, propDef] of bodyParam.type.properties) {
1090
- let { typeReference: csType, defaultValue: csValue, nullableType: isNullable, } = this.getTypeInfo(program, propDef.type, propDef);
1091
- // cSharp does not allow array defaults in operation parameters
1092
- if (!canHaveDefault(program, propDef)) {
1093
- csValue = undefined;
1094
- }
1095
- const paramName = ensureCSharpIdentifier(program, propDef, propName, NameCasingType.Parameter);
1096
- const refName = ensureCSharpIdentifier(program, propDef, propName, NameCasingType.Property);
1097
- result.push({
1098
- isExplicitBody: false,
1099
- httpParameterKind: "body",
1100
- name: paramName,
1101
- callName: `body.${refName}`,
1102
- typeName: csType,
1103
- nullable: isNullable,
1104
- defaultValue: csValue,
1105
- optional: propDef.optional,
1106
- operationKind: "BusinessLogic",
1107
- });
1108
- }
1109
- break;
1110
- case "ModelProperty":
1111
- {
1112
- let { typeReference: csType, defaultValue: csValue, nullableType: isNullable, } = this.getTypeInfo(program, bodyParam.type.type, bodyParam.type);
1113
- if (!canHaveDefault(program, bodyParam.type)) {
1114
- csValue = undefined;
1115
- }
1116
- const optName = ensureCSharpIdentifier(program, bodyParam.type.type, bodyParam.type.name, NameCasingType.Parameter);
1117
- result.push({
1118
- isExplicitBody: true,
1119
- httpParameterKind: "body",
1120
- name: optName,
1121
- callName: optName,
1122
- typeName: csType,
1123
- nullable: isNullable,
1124
- defaultValue: csValue,
1125
- optional: bodyParam.type.optional,
1126
- operationKind: "All",
1127
- });
1128
- }
1129
- break;
1130
- default: {
1131
- let { typeReference: csType, defaultValue: csValue, nullableType: isNullable, } = this.getTypeInfo(program, bodyParam.type);
1132
- if (!canHaveDefault(program, bodyParam.type)) {
1133
- csValue = undefined;
1134
- }
1135
- result.push({
1136
- isExplicitBody: true,
1137
- httpParameterKind: "body",
1138
- name: "body",
1139
- callName: "body",
1140
- typeName: csType,
1141
- nullable: isNullable,
1142
- defaultValue: csValue,
1143
- optional: false,
1144
- operationKind: "All",
1145
- });
1146
- }
1147
- }
1148
- }
1149
- for (const parameter of optionalParams) {
1150
- const { typeReference: paramType, defaultValue: paramValue, nullableType: isNullable, } = this.getTypeInfo(program, parameter.param.type, parameter.param);
1151
- const optName = ensureCSharpIdentifier(program, parameter.param, parameter.param.name, NameCasingType.Parameter);
1152
- result.push({
1153
- isExplicitBody: false,
1154
- name: optName,
1155
- callName: optName,
1156
- optional: true,
1157
- typeName: paramType,
1158
- defaultValue: paramValue,
1159
- httpParameterKind: getParameterKind(parameter),
1160
- httpParameterName: parameter.name,
1161
- nullable: isNullable,
1162
- operationKind: "All",
1163
- });
1164
- }
1165
- return result;
1166
- }
1167
- getDefaultValue(program, tsType, defaultValue) {
1168
- if (defaultValue === undefined)
1169
- return undefined;
1170
- switch (tsType.kind) {
1171
- case "Enum":
1172
- if (defaultValue.valueKind === "EnumValue") {
1173
- const retVal = this.getTypeInfo(program, tsType);
1174
- return `${retVal.typeReference}.${ensureCSharpIdentifier(program, defaultValue.value, defaultValue.value.name, NameCasingType.Property)}`;
1175
- }
1176
- return JSON.stringify(serializeValueAsJson(this.emitter.getProgram(), defaultValue, tsType));
1177
- case "Union":
1178
- const { typeReference: typeRef } = this.getUnionInfo(program, tsType);
1179
- if (defaultValue.valueKind === "StringValue" && isStringEnumType(program, tsType)) {
1180
- const matches = [...tsType.variants].filter((v) => typeof v[0] === "string" &&
1181
- v[1].type.kind === "String" &&
1182
- v[1].type.value === defaultValue.value);
1183
- if (matches.length === 1) {
1184
- return `${typeRef}.${ensureCSharpIdentifier(program, matches[0][1], matches[0][0], NameCasingType.Property)}`;
1185
- }
1186
- return undefined;
1187
- }
1188
- if (defaultValue.valueKind === "StringValue") {
1189
- return JSON.stringify(serializeValueAsJson(this.emitter.getProgram(), defaultValue, tsType));
1190
- }
1191
- return undefined;
1192
- default:
1193
- return JSON.stringify(serializeValueAsJson(this.emitter.getProgram(), defaultValue, tsType));
1194
- }
1195
- }
1196
- getTypeInfo(program, tsType, modelProperty) {
1197
- const myEmitter = this.emitter;
1198
- function extractStringValue(type, span) {
1199
- switch (type.kind) {
1200
- case "String":
1201
- return type.value;
1202
- case "Boolean":
1203
- return `${type.value}`;
1204
- case "Number":
1205
- return type.valueAsString;
1206
- case "StringTemplateSpan":
1207
- if (type.isInterpolated) {
1208
- return extractStringValue(type.type, span);
1209
- }
1210
- else {
1211
- return type.type.value;
1212
- }
1213
- case "ModelProperty":
1214
- return extractStringValue(type.type, span);
1215
- case "EnumMember":
1216
- if (type.value === undefined)
1217
- return type.name;
1218
- if (typeof type.value === "string")
1219
- return type.value;
1220
- if (typeof type.value === "number")
1221
- return `${type.value}`;
1222
- }
1223
- reportDiagnostic(myEmitter.getProgram(), {
1224
- code: "invalid-interpolation",
1225
- target: span,
1226
- format: {},
1227
- });
1228
- return "";
1229
- }
1230
- switch (tsType.kind) {
1231
- case "String":
1232
- return {
1233
- typeReference: code `string`,
1234
- defaultValue: `"${tsType.value}"`,
1235
- nullableType: false,
1236
- };
1237
- case "StringTemplate":
1238
- const template = tsType;
1239
- if (template.stringValue !== undefined)
1240
- return {
1241
- typeReference: code `string`,
1242
- defaultValue: `"${template.stringValue}"`,
1243
- nullableType: false,
1244
- };
1245
- const spanResults = [];
1246
- for (const span of template.spans) {
1247
- spanResults.push(extractStringValue(span, span));
1248
- }
1249
- return {
1250
- typeReference: code `string`,
1251
- defaultValue: `"${spanResults.join("")}"`,
1252
- nullableType: false,
1253
- };
1254
- case "Boolean":
1255
- return {
1256
- typeReference: code `bool`,
1257
- defaultValue: `${tsType.value === true ? true : false}`,
1258
- nullableType: false,
1259
- };
1260
- case "Number":
1261
- const [type, value] = findNumericType(tsType);
1262
- return { typeReference: code `${type}`, defaultValue: `${value}`, nullableType: false };
1263
- case "Tuple":
1264
- const defaults = [];
1265
- const [csharpType, isObject] = coalesceTsTypes(program, tsType.values);
1266
- if (isObject)
1267
- return { typeReference: "object[]", defaultValue: undefined, nullableType: false };
1268
- for (const value of tsType.values) {
1269
- const { defaultValue: itemDefault } = this.getTypeInfo(program, value);
1270
- defaults.push(itemDefault);
1271
- }
1272
- const collectionType = CSharpServiceOptions.getInstance().collectionType;
1273
- switch (collectionType) {
1274
- case CollectionType.IEnumerable:
1275
- return {
1276
- typeReference: code `IEnumerable<${csharpType.getTypeReference(myEmitter.getContext()?.scope)}>`,
1277
- defaultValue: `new List<${csharpType.getTypeReference(myEmitter.getContext()?.scope)}> {${defaults.join(", ")}}`,
1278
- nullableType: csharpType.isNullable,
1279
- };
1280
- case CollectionType.Array:
1281
- default:
1282
- return {
1283
- typeReference: code `${csharpType.getTypeReference(myEmitter.getContext()?.scope)}[]`,
1284
- defaultValue: `[${defaults.join(", ")}]`,
1285
- nullableType: csharpType.isNullable,
1286
- };
1287
- }
1288
- case "Model":
1289
- let modelResult;
1290
- const hasUniqueItems = modelProperty
1291
- ? getUniqueItems(program, modelProperty) !== undefined
1292
- : false;
1293
- const cachedResult = this.#anonymousModels.get(tsType);
1294
- if (cachedResult && cachedResult.hasUniqueItems === hasUniqueItems) {
1295
- return cachedResult;
1296
- }
1297
- if (isRecord(tsType)) {
1298
- modelResult = {
1299
- typeReference: code `${RecordType.getTypeReference(myEmitter.getContext().scope)}`,
1300
- nullableType: false,
1301
- hasUniqueItems: hasUniqueItems,
1302
- };
1303
- }
1304
- else if (isArrayModelType(tsType)) {
1305
- const typeReference = code `${this.emitter.emitTypeReference(tsType.indexer.value)}`;
1306
- modelResult = isByteType(tsType.indexer.value)
1307
- ? {
1308
- typeReference: code `${typeReference}[]`,
1309
- nullableType: false,
1310
- hasUniqueItems: hasUniqueItems,
1311
- }
1312
- : {
1313
- typeReference: hasUniqueItems
1314
- ? code `ISet<${typeReference}>`
1315
- : code `${this.emitter.emitTypeReference(tsType)}`,
1316
- nullableType: false,
1317
- hasUniqueItems: hasUniqueItems,
1318
- };
1319
- }
1320
- else {
1321
- modelResult = {
1322
- typeReference: code `${this.emitter.emitTypeReference(tsType, this.emitter.getContext())}`,
1323
- nullableType: false,
1324
- hasUniqueItems: hasUniqueItems,
1325
- };
1326
- }
1327
- return modelResult;
1328
- case "ModelProperty":
1329
- return this.getTypeInfo(program, tsType.type, tsType);
1330
- case "Enum":
1331
- if (getEnumType(tsType) === "double")
1332
- return { typeReference: getDoubleType().getTypeReference(), nullableType: false };
1333
- return {
1334
- typeReference: code `${this.emitter.emitTypeReference(tsType)}`,
1335
- nullableType: false,
1336
- };
1337
- case "EnumMember":
1338
- if (typeof tsType.value === "number") {
1339
- const stringValue = tsType.value.toString();
1340
- if (stringValue.includes(".") || stringValue.includes("e"))
1341
- return { typeReference: "double", defaultValue: stringValue, nullableType: false };
1342
- return { typeReference: "int", defaultValue: stringValue, nullableType: false };
1343
- }
1344
- if (typeof tsType.value === "string") {
1345
- const retVal = this.getTypeInfo(program, tsType.enum);
1346
- retVal.defaultValue = `${retVal.typeReference}.${ensureCSharpIdentifier(program, tsType, tsType.name, NameCasingType.Property)}`;
1347
- return retVal;
1348
- }
1349
- return { typeReference: code `object`, nullableType: false };
1350
- case "Union":
1351
- return this.getUnionInfo(program, tsType);
1352
- case "UnionVariant":
1353
- if (isStringEnumType(program, tsType.union) &&
1354
- tsType.type.kind === "String" &&
1355
- typeof tsType.name === "string") {
1356
- const retVal = this.getUnionInfo(program, tsType.union);
1357
- retVal.defaultValue = `${retVal.typeReference}.${ensureCSharpIdentifier(program, tsType, tsType.name, NameCasingType.Property)}`;
1358
- return retVal;
1359
- }
1360
- return this.getTypeInfo(program, tsType.type);
1361
- default:
1362
- return {
1363
- typeReference: code `${this.emitter.emitTypeReference(tsType)}`,
1364
- nullableType: false,
1365
- };
1366
- }
1367
- }
1368
- getUnionInfo(program, union) {
1369
- const propResult = getNonNullableTsType(union);
1370
- if (propResult === undefined || isStringEnumType(program, union)) {
1371
- return {
1372
- typeReference: code `${this.emitter.emitTypeReference(union)}`,
1373
- nullableType: [...union.variants.values()].some((v) => isNullType(v.type)),
1374
- };
1375
- }
1376
- const candidate = this.getTypeInfo(program, propResult.type);
1377
- candidate.nullableType = propResult.nullable;
1378
- return candidate;
1379
- }
1380
- }
1381
- export function getExplicitBodyParameters(program, httpOperation) {
1382
- if (httpOperation.parameters.body && httpOperation.parameters.body.bodyKind === "multipart") {
1383
- return [
1384
- {
1385
- name: "reader",
1386
- callName: "reader",
1387
- nullable: false,
1388
- optional: false,
1389
- typeName: "MultipartReader",
1390
- isExplicitBody: false,
1391
- httpParameterKind: "body",
1392
- operationKind: "BusinessLogic",
1393
- },
1394
- ];
1395
- }
1396
- return undefined;
1397
- }
1398
- export function findNumericType(type) {
1399
- const stringValue = type.valueAsString;
1400
- if (stringValue.includes(".") || stringValue.includes("e"))
1401
- return ["double", stringValue];
1402
- return ["int", stringValue];
1403
- }
1404
- export function isStringEnumType(program, union) {
1405
- const baseType = coalesceUnionTypes(program, union);
1406
- if (!baseType.isBuiltIn || baseType.name !== "string")
1407
- return false;
1408
- return ![...union.variants.values()].some((v) => (v.type.kind === "String" ||
1409
- v.type.kind === "StringTemplate" ||
1410
- v.type.kind === "StringTemplateSpan") &&
1411
- typeof v.name !== "string");
1412
- }
1413
- export function coalesceUnionTypes(program, union) {
1414
- const [result, _] = coalesceTsTypes(program, [...union.variants.values()].flatMap((v) => v.type));
1415
- return result;
1416
- }
1417
- export function getNonNullableTsType(union) {
1418
- const types = [...union.variants.values()];
1419
- const nulls = types.flatMap((v) => v.type).filter((t) => isNullType(t));
1420
- const nonNulls = types.flatMap((v) => v.type).filter((t) => !isNullType(t));
1421
- if (nonNulls.length === 1)
1422
- return { type: nonNulls[0], nullable: nulls.length > 0 };
1423
- return undefined;
1424
- }
1425
- export function coalesceTsTypes(program, types) {
1426
- const defaultValue = [
1427
- new CSharpType({
1428
- name: "object",
1429
- namespace: "System",
1430
- isBuiltIn: true,
1431
- isValueType: false,
1432
- }),
1433
- true,
1434
- ];
1435
- let current = undefined;
1436
- let nullable = false;
1437
- for (const type of types) {
1438
- let candidate;
1439
- switch (type.kind) {
1440
- case "Boolean":
1441
- candidate = new CSharpType({ name: "bool", namespace: "System", isValueType: true });
1442
- break;
1443
- case "StringTemplate":
1444
- case "String":
1445
- candidate = new CSharpType({ name: "string", namespace: "System", isValueType: false });
1446
- break;
1447
- case "Number":
1448
- const stringValue = type.valueAsString;
1449
- if (stringValue.includes(".") || stringValue.includes("e")) {
1450
- candidate = new CSharpType({
1451
- name: "double",
1452
- namespace: "System",
1453
- isValueType: true,
1454
- });
1455
- }
1456
- else {
1457
- candidate = new CSharpType({ name: "int", namespace: "System", isValueType: true });
1458
- }
1459
- break;
1460
- case "Union":
1461
- candidate = coalesceUnionTypes(program, type);
1462
- break;
1463
- case "Scalar":
1464
- candidate = getCSharpTypeForScalar(program, type);
1465
- break;
1466
- case "Intrinsic":
1467
- if (isNullType(type)) {
1468
- nullable = true;
1469
- candidate = current;
1470
- }
1471
- else {
1472
- return defaultValue;
1473
- }
1474
- break;
1475
- default:
1476
- return defaultValue;
1477
- }
1478
- current = current ?? candidate;
1479
- if (current === undefined || (candidate !== undefined && !candidate.equals(current)))
1480
- return defaultValue;
1481
- }
1482
- if (current !== undefined && nullable === true)
1483
- current.isNullable = true;
1484
- return current === undefined ? defaultValue : [current, false];
1485
- }
1486
- export function isRecord(type) {
1487
- return type.kind === "Model" && type.name === "Record" && type.indexer !== undefined;
1488
- }
1489
- export async function getFreePort(minPort, maxPort, tries = 100) {
1490
- const min = Math.floor(minPort);
1491
- const max = Math.floor(maxPort);
1492
- if (tries === 0)
1493
- return min;
1494
- const diff = Math.abs(max - min);
1495
- const port = min + Math.floor(Math.random() * diff);
1496
- const server = createServer();
1497
- const free = await checkPort(port);
1498
- if (free) {
1499
- return port;
1500
- }
1501
- // This seems like a bug? tries-- does nothing?
1502
- // eslint-disable-next-line no-useless-assignment
1503
- return await getFreePort(min, max, tries--);
1504
- async function checkPort(port, timeout = 100) {
1505
- return new Promise((resolve, _) => {
1506
- server.on("error", (_) => {
1507
- server.close();
1508
- resolve(false);
1509
- });
1510
- server.listen(port, async () => {
1511
- try {
1512
- setTimeout(() => resolve(true), timeout);
1513
- }
1514
- catch (e) {
1515
- resolve(false);
1516
- }
1517
- finally {
1518
- server.close();
1519
- }
1520
- });
1521
- });
1522
- }
1523
- }
1524
- export async function getOpenApiConfig(program) {
1525
- const root = program.projectRoot;
1526
- const [options, _] = await resolveCompilerOptions(program.host, {
1527
- cwd: root,
1528
- entrypoint: resolvePath(root, "main.tsp"),
1529
- });
1530
- const oaiOptions = options.options !== undefined && Object.keys(options.options).includes("@typespec/openapi3")
1531
- ? options.options["@typespec/openapi3"]
1532
- : undefined;
1533
- return {
1534
- emitted: options.emit !== undefined && options.emit.includes("@typespec/openapi3"),
1535
- outputDir: oaiOptions?.["emitter-output-dir"],
1536
- fileName: oaiOptions?.["output-file"],
1537
- options: oaiOptions,
1538
- };
1539
- }
1540
- export function getStatusCode(program, model) {
1541
- const statusCodeProperty = new ModelInfo().filterAllProperties(program, model, (p) => isStatusCode(program, p));
1542
- if (!statusCodeProperty)
1543
- return undefined;
1544
- const { type } = statusCodeProperty;
1545
- switch (type.kind) {
1546
- case "Union":
1547
- return {
1548
- name: statusCodeProperty.name,
1549
- value: statusCodeProperty.name,
1550
- requiresConstructorArgument: true,
1551
- };
1552
- case "Number":
1553
- return {
1554
- value: type.value,
1555
- };
1556
- default:
1557
- return { value: getMinValue(program, statusCodeProperty) ?? `default` };
1558
- }
1559
- }
1560
- export function isByteType(type) {
1561
- return type.kind === "Scalar" && ["int8", "uint8"].includes(type.name);
1562
- }
1563
- export function getImports(scope, visited) {
1564
- if (scope === undefined)
1565
- return [];
1566
- if (!visited)
1567
- visited = new Set();
1568
- if (visited.has(scope))
1569
- return [];
1570
- visited.add(scope);
1571
- switch (scope.kind) {
1572
- case "namespace":
1573
- return getImports(scope.parentScope, visited);
1574
- case "sourceFile":
1575
- return [...scope.sourceFile.imports.keys()];
1576
- default:
1577
- return [];
1578
- }
1579
- }
1580
- //# sourceMappingURL=utils.js.map