@typespec/http-specs 0.1.0-alpha.9 → 0.1.0-dev.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 (224) hide show
  1. package/CHANGELOG.md +260 -3
  2. package/README.md +11 -3
  3. package/dist/specs/authentication/noauth/union/mockapi.d.ts +3 -0
  4. package/dist/specs/authentication/noauth/union/mockapi.d.ts.map +1 -0
  5. package/dist/specs/authentication/noauth/union/mockapi.js +25 -0
  6. package/dist/specs/authentication/noauth/union/mockapi.js.map +1 -0
  7. package/dist/specs/documentation/mockapi.d.ts +3 -0
  8. package/dist/specs/documentation/mockapi.d.ts.map +1 -0
  9. package/dist/specs/documentation/mockapi.js +40 -0
  10. package/dist/specs/documentation/mockapi.js.map +1 -0
  11. package/dist/specs/encode/array/mockapi.d.ts +3 -0
  12. package/dist/specs/encode/array/mockapi.d.ts.map +1 -0
  13. package/dist/specs/encode/array/mockapi.js +33 -0
  14. package/dist/specs/encode/array/mockapi.js.map +1 -0
  15. package/dist/specs/encode/bytes/mockapi.js +16 -24
  16. package/dist/specs/encode/bytes/mockapi.js.map +1 -1
  17. package/dist/specs/encode/datetime/mockapi.js +2 -2
  18. package/dist/specs/encode/datetime/mockapi.js.map +1 -1
  19. package/dist/specs/encode/duration/mockapi.d.ts.map +1 -1
  20. package/dist/specs/encode/duration/mockapi.js +115 -3
  21. package/dist/specs/encode/duration/mockapi.js.map +1 -1
  22. package/dist/specs/encode/numeric/mockapi.js +2 -2
  23. package/dist/specs/encode/numeric/mockapi.js.map +1 -1
  24. package/dist/specs/helper.d.ts +2 -2
  25. package/dist/specs/helper.d.ts.map +1 -1
  26. package/dist/specs/parameters/basic/mockapi.d.ts.map +1 -1
  27. package/dist/specs/parameters/basic/mockapi.js +3 -3
  28. package/dist/specs/parameters/basic/mockapi.js.map +1 -1
  29. package/dist/specs/parameters/body-optionality/mockapi.d.ts.map +1 -1
  30. package/dist/specs/parameters/body-optionality/mockapi.js +14 -4
  31. package/dist/specs/parameters/body-optionality/mockapi.js.map +1 -1
  32. package/dist/specs/parameters/collection-format/mockapi.js +4 -15
  33. package/dist/specs/parameters/collection-format/mockapi.js.map +1 -1
  34. package/dist/specs/parameters/path/mockapi.d.ts +3 -0
  35. package/dist/specs/parameters/path/mockapi.d.ts.map +1 -0
  36. package/dist/specs/parameters/path/mockapi.js +29 -0
  37. package/dist/specs/parameters/path/mockapi.js.map +1 -0
  38. package/dist/specs/parameters/query/mockapi.d.ts +3 -0
  39. package/dist/specs/parameters/query/mockapi.d.ts.map +1 -0
  40. package/dist/specs/parameters/query/mockapi.js +14 -0
  41. package/dist/specs/parameters/query/mockapi.js.map +1 -0
  42. package/dist/specs/parameters/spread/mockapi.d.ts.map +1 -1
  43. package/dist/specs/parameters/spread/mockapi.js +19 -19
  44. package/dist/specs/parameters/spread/mockapi.js.map +1 -1
  45. package/dist/specs/payload/json-merge-patch/mockapi.js +4 -4
  46. package/dist/specs/payload/json-merge-patch/mockapi.js.map +1 -1
  47. package/dist/specs/payload/media-type/mockapi.js +2 -2
  48. package/dist/specs/payload/media-type/mockapi.js.map +1 -1
  49. package/dist/specs/payload/multipart/mockapi.d.ts.map +1 -1
  50. package/dist/specs/payload/multipart/mockapi.js +196 -60
  51. package/dist/specs/payload/multipart/mockapi.js.map +1 -1
  52. package/dist/specs/payload/pageable/mockapi.d.ts.map +1 -1
  53. package/dist/specs/payload/pageable/mockapi.js +626 -14
  54. package/dist/specs/payload/pageable/mockapi.js.map +1 -1
  55. package/dist/specs/payload/xml/mockapi.d.ts +19 -5
  56. package/dist/specs/payload/xml/mockapi.d.ts.map +1 -1
  57. package/dist/specs/payload/xml/mockapi.js +311 -55
  58. package/dist/specs/payload/xml/mockapi.js.map +1 -1
  59. package/dist/specs/response/status-code-range/mockapi.d.ts.map +1 -1
  60. package/dist/specs/response/status-code-range/mockapi.js +5 -9
  61. package/dist/specs/response/status-code-range/mockapi.js.map +1 -1
  62. package/dist/specs/routes/mockapi.js +16 -16
  63. package/dist/specs/routes/mockapi.js.map +1 -1
  64. package/dist/specs/serialization/encoded-name/json/mockapi.js +1 -1
  65. package/dist/specs/serialization/encoded-name/json/mockapi.js.map +1 -1
  66. package/dist/specs/server/versions/not-versioned/mockapi.js +1 -1
  67. package/dist/specs/server/versions/not-versioned/mockapi.js.map +1 -1
  68. package/dist/specs/server/versions/versioned/mockapi.js +8 -12
  69. package/dist/specs/server/versions/versioned/mockapi.js.map +1 -1
  70. package/dist/specs/special-words/mockapi.d.ts.map +1 -1
  71. package/dist/specs/special-words/mockapi.js +59 -6
  72. package/dist/specs/special-words/mockapi.js.map +1 -1
  73. package/dist/specs/streaming/jsonl/mockapi.d.ts +3 -0
  74. package/dist/specs/streaming/jsonl/mockapi.d.ts.map +1 -0
  75. package/dist/specs/streaming/jsonl/mockapi.js +30 -0
  76. package/dist/specs/streaming/jsonl/mockapi.js.map +1 -0
  77. package/dist/specs/type/array/mockapi.js +1 -1
  78. package/dist/specs/type/array/mockapi.js.map +1 -1
  79. package/dist/specs/type/dictionary/mockapi.js +1 -1
  80. package/dist/specs/type/dictionary/mockapi.js.map +1 -1
  81. package/dist/specs/type/enum/extensible/mockapi.js +1 -1
  82. package/dist/specs/type/enum/extensible/mockapi.js.map +1 -1
  83. package/dist/specs/type/enum/fixed/mockapi.js +2 -2
  84. package/dist/specs/type/enum/fixed/mockapi.js.map +1 -1
  85. package/dist/specs/type/file/mockapi.d.ts +3 -0
  86. package/dist/specs/type/file/mockapi.d.ts.map +1 -0
  87. package/dist/specs/type/file/mockapi.js +187 -0
  88. package/dist/specs/type/file/mockapi.js.map +1 -0
  89. package/dist/specs/type/model/empty/mockapi.js +2 -2
  90. package/dist/specs/type/model/empty/mockapi.js.map +1 -1
  91. package/dist/specs/type/model/inheritance/enum-discriminator/mockapi.js +1 -1
  92. package/dist/specs/type/model/inheritance/enum-discriminator/mockapi.js.map +1 -1
  93. package/dist/specs/type/model/inheritance/nested-discriminator/mockapi.js +2 -2
  94. package/dist/specs/type/model/inheritance/nested-discriminator/mockapi.js.map +1 -1
  95. package/dist/specs/type/model/inheritance/not-discriminated/mockapi.js +2 -2
  96. package/dist/specs/type/model/inheritance/not-discriminated/mockapi.js.map +1 -1
  97. package/dist/specs/type/model/inheritance/recursive/mockapi.js +1 -1
  98. package/dist/specs/type/model/inheritance/recursive/mockapi.js.map +1 -1
  99. package/dist/specs/type/model/inheritance/single-discriminator/mockapi.js +2 -2
  100. package/dist/specs/type/model/inheritance/single-discriminator/mockapi.js.map +1 -1
  101. package/dist/specs/type/model/usage/mockapi.js +4 -4
  102. package/dist/specs/type/model/usage/mockapi.js.map +1 -1
  103. package/dist/specs/type/model/visibility/mockapi.js +9 -10
  104. package/dist/specs/type/model/visibility/mockapi.js.map +1 -1
  105. package/dist/specs/type/property/additional-properties/mockapi.js +9 -6
  106. package/dist/specs/type/property/additional-properties/mockapi.js.map +1 -1
  107. package/dist/specs/type/property/nullable/mockapi.js +2 -6
  108. package/dist/specs/type/property/nullable/mockapi.js.map +1 -1
  109. package/dist/specs/type/property/optionality/mockapi.js +1 -1
  110. package/dist/specs/type/property/optionality/mockapi.js.map +1 -1
  111. package/dist/specs/type/property/value-types/mockapi.js +3 -3
  112. package/dist/specs/type/property/value-types/mockapi.js.map +1 -1
  113. package/dist/specs/type/scalar/mockapi.js +9 -9
  114. package/dist/specs/type/scalar/mockapi.js.map +1 -1
  115. package/dist/specs/type/union/discriminated/mockapi.d.ts +3 -0
  116. package/dist/specs/type/union/discriminated/mockapi.d.ts.map +1 -0
  117. package/dist/specs/type/union/discriminated/mockapi.js +212 -0
  118. package/dist/specs/type/union/discriminated/mockapi.js.map +1 -0
  119. package/dist/specs/type/union/mockapi.js +2 -2
  120. package/dist/specs/type/union/mockapi.js.map +1 -1
  121. package/dist/specs/versioning/added/mockapi.js +6 -6
  122. package/dist/specs/versioning/added/mockapi.js.map +1 -1
  123. package/dist/specs/versioning/madeOptional/mockapi.js +2 -2
  124. package/dist/specs/versioning/madeOptional/mockapi.js.map +1 -1
  125. package/dist/specs/versioning/removed/mockapi.js +11 -11
  126. package/dist/specs/versioning/removed/mockapi.js.map +1 -1
  127. package/dist/specs/versioning/renamedFrom/mockapi.js +5 -5
  128. package/dist/specs/versioning/renamedFrom/mockapi.js.map +1 -1
  129. package/dist/specs/versioning/returnTypeChangedFrom/mockapi.js +1 -1
  130. package/dist/specs/versioning/returnTypeChangedFrom/mockapi.js.map +1 -1
  131. package/dist/specs/versioning/typeChangedFrom/mockapi.js +3 -3
  132. package/dist/specs/versioning/typeChangedFrom/mockapi.js.map +1 -1
  133. package/manifest.json +11545 -0
  134. package/package.json +31 -20
  135. package/smoke/petstore/main.tsp +96 -0
  136. package/smoke/todoapp/main.tsp +293 -0
  137. package/spec-summary.md +2137 -121
  138. package/specs/authentication/noauth/union/main.tsp +30 -0
  139. package/specs/authentication/noauth/union/mockapi.ts +27 -0
  140. package/specs/documentation/main.tsp +158 -0
  141. package/specs/documentation/mockapi.ts +59 -0
  142. package/specs/encode/array/main.tsp +339 -0
  143. package/specs/encode/array/mockapi.ts +83 -0
  144. package/specs/encode/bytes/main.tsp +29 -20
  145. package/specs/encode/bytes/mockapi.ts +13 -31
  146. package/specs/encode/datetime/main.tsp +2 -7
  147. package/specs/encode/datetime/mockapi.ts +2 -2
  148. package/specs/encode/duration/main.tsp +420 -7
  149. package/specs/encode/duration/mockapi.ts +221 -2
  150. package/specs/encode/numeric/mockapi.ts +2 -2
  151. package/specs/parameters/basic/mockapi.ts +3 -3
  152. package/specs/parameters/body-optionality/main.tsp +2 -0
  153. package/specs/parameters/body-optionality/mockapi.ts +24 -4
  154. package/specs/parameters/collection-format/main.tsp +5 -25
  155. package/specs/parameters/collection-format/mockapi.ts +4 -16
  156. package/specs/parameters/path/main.tsp +48 -0
  157. package/specs/parameters/path/mockapi.ts +34 -0
  158. package/specs/parameters/query/main.tsp +22 -0
  159. package/specs/parameters/query/mockapi.ts +15 -0
  160. package/specs/parameters/spread/mockapi.ts +19 -19
  161. package/specs/payload/json-merge-patch/main.tsp +2 -2
  162. package/specs/payload/json-merge-patch/mockapi.ts +4 -4
  163. package/specs/payload/media-type/mockapi.ts +2 -2
  164. package/specs/payload/multipart/main.tsp +230 -32
  165. package/specs/payload/multipart/mockapi.ts +207 -59
  166. package/specs/payload/pageable/main.tsp +648 -0
  167. package/specs/payload/pageable/mockapi.ts +691 -14
  168. package/specs/payload/xml/main.tsp +532 -132
  169. package/specs/payload/xml/mockapi.ts +402 -67
  170. package/specs/response/status-code-range/main.tsp +2 -2
  171. package/specs/response/status-code-range/mockapi.ts +5 -9
  172. package/specs/routes/main.tsp +29 -29
  173. package/specs/routes/mockapi.ts +16 -16
  174. package/specs/serialization/encoded-name/json/main.tsp +1 -1
  175. package/specs/serialization/encoded-name/json/mockapi.ts +1 -1
  176. package/specs/server/endpoint/not-defined/main.tsp +1 -3
  177. package/specs/server/path/multiple/main.tsp +3 -5
  178. package/specs/server/versions/not-versioned/mockapi.ts +1 -1
  179. package/specs/server/versions/versioned/main.tsp +1 -1
  180. package/specs/server/versions/versioned/mockapi.ts +6 -12
  181. package/specs/special-headers/conditional-request/main.tsp +1 -1
  182. package/specs/special-headers/repeatability/main.tsp +2 -2
  183. package/specs/special-words/main.tsp +124 -6
  184. package/specs/special-words/mockapi.ts +62 -6
  185. package/specs/streaming/jsonl/main.tsp +33 -0
  186. package/specs/streaming/jsonl/mockapi.ts +32 -0
  187. package/specs/type/array/mockapi.ts +1 -1
  188. package/specs/type/dictionary/mockapi.ts +1 -1
  189. package/specs/type/enum/extensible/main.tsp +18 -2
  190. package/specs/type/enum/extensible/mockapi.ts +1 -1
  191. package/specs/type/enum/fixed/main.tsp +15 -3
  192. package/specs/type/enum/fixed/mockapi.ts +2 -2
  193. package/specs/type/file/main.tsp +109 -0
  194. package/specs/type/file/mockapi.ts +200 -0
  195. package/specs/type/model/empty/mockapi.ts +2 -2
  196. package/specs/type/model/inheritance/enum-discriminator/mockapi.ts +1 -1
  197. package/specs/type/model/inheritance/nested-discriminator/mockapi.ts +2 -2
  198. package/specs/type/model/inheritance/not-discriminated/mockapi.ts +2 -2
  199. package/specs/type/model/inheritance/recursive/mockapi.ts +1 -1
  200. package/specs/type/model/inheritance/single-discriminator/mockapi.ts +2 -2
  201. package/specs/type/model/usage/mockapi.ts +4 -4
  202. package/specs/type/model/visibility/main.tsp +9 -17
  203. package/specs/type/model/visibility/mockapi.ts +9 -10
  204. package/specs/type/property/additional-properties/main.tsp +17 -17
  205. package/specs/type/property/additional-properties/mockapi.ts +10 -10
  206. package/specs/type/property/nullable/mockapi.ts +7 -8
  207. package/specs/type/property/optionality/mockapi.ts +1 -1
  208. package/specs/type/property/value-types/mockapi.ts +3 -3
  209. package/specs/type/scalar/main.tsp +58 -9
  210. package/specs/type/scalar/mockapi.ts +9 -9
  211. package/specs/type/union/discriminated/main.tsp +251 -0
  212. package/specs/type/union/discriminated/mockapi.ts +230 -0
  213. package/specs/type/union/mockapi.ts +2 -2
  214. package/specs/versioning/added/mockapi.ts +6 -6
  215. package/specs/versioning/madeOptional/mockapi.ts +2 -2
  216. package/specs/versioning/removed/main.tsp +5 -5
  217. package/specs/versioning/removed/mockapi.ts +11 -11
  218. package/specs/versioning/renamedFrom/mockapi.ts +5 -5
  219. package/specs/versioning/returnTypeChangedFrom/main.tsp +17 -2
  220. package/specs/versioning/returnTypeChangedFrom/mockapi.ts +1 -1
  221. package/specs/versioning/typeChangedFrom/mockapi.ts +3 -3
  222. package/temp/.tsbuildinfo +1 -1
  223. package/tsconfig.build.json +0 -4
  224. package/tspconfig.yaml +0 -2
@@ -1,4 +1,4 @@
1
- import { passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
1
+ import { json, MockRequest, passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
2
2
 
3
3
  export const Scenarios: Record<string, ScenarioMockApi> = {};
4
4
 
@@ -6,9 +6,46 @@ Scenarios.SpecialWords_ModelProperties_sameAsModel = passOnSuccess({
6
6
  uri: "/special-words/model-properties/same-as-model",
7
7
  method: "post",
8
8
  request: {
9
- body: {
9
+ body: json({
10
10
  SameAsModel: "ok",
11
- },
11
+ }),
12
+ },
13
+ response: {
14
+ status: 204,
15
+ },
16
+ kind: "MockApiDefinition",
17
+ });
18
+
19
+ Scenarios.SpecialWords_ModelProperties_dictMethods = passOnSuccess({
20
+ uri: "/special-words/model-properties/dict-methods",
21
+ method: "post",
22
+ request: {
23
+ body: json({
24
+ keys: "ok",
25
+ items: "ok",
26
+ values: "ok",
27
+ popitem: "ok",
28
+ clear: "ok",
29
+ update: "ok",
30
+ setdefault: "ok",
31
+ pop: "ok",
32
+ get: "ok",
33
+ copy: "ok",
34
+ }),
35
+ },
36
+ response: {
37
+ status: 204,
38
+ },
39
+ kind: "MockApiDefinition",
40
+ });
41
+
42
+ Scenarios.SpecialWords_ModelProperties_withList = passOnSuccess({
43
+ uri: "/special-words/model-properties/list",
44
+ method: "post",
45
+ request: {
46
+ body: json({
47
+ list: "ok",
48
+ }),
12
49
  },
13
50
  response: {
14
51
  status: 204,
@@ -21,9 +58,9 @@ function createModelsTests(uri: string) {
21
58
  uri,
22
59
  method: "post",
23
60
  request: {
24
- body: {
61
+ body: json({
25
62
  name: "ok",
26
- },
63
+ }),
27
64
  },
28
65
  response: {
29
66
  status: 204,
@@ -134,7 +171,7 @@ function createParametersTests(uri: string, data: any, paramName: string) {
134
171
  uri,
135
172
  method: "get",
136
173
  request: {
137
- params: data,
174
+ query: data,
138
175
  },
139
176
  response: {
140
177
  status: 204,
@@ -382,3 +419,22 @@ Scenarios.SpecialWords_Parameters_cancellationToken = createParametersTests(
382
419
  },
383
420
  "cancellationToken",
384
421
  );
422
+
423
+ Scenarios.SpecialWords_ExtensibleStrings_putExtensibleStringValue = passOnSuccess({
424
+ uri: `/special-words/extensible-strings/string`,
425
+ method: "put",
426
+ request: {
427
+ body: json("class"),
428
+ },
429
+ response: {
430
+ status: 200,
431
+ body: json("class"),
432
+ },
433
+ handler: (req: MockRequest) => {
434
+ return {
435
+ status: 200,
436
+ body: json(req.body),
437
+ };
438
+ },
439
+ kind: "MockApiDefinition",
440
+ });
@@ -0,0 +1,33 @@
1
+ import "@typespec/http";
2
+ import "@typespec/http/streams";
3
+ import "@typespec/spector";
4
+
5
+ using Http;
6
+ using Http.Streams;
7
+ using Spector;
8
+
9
+ @doc("Test of jsonl streaming.")
10
+ @scenarioService("/streaming/jsonl")
11
+ namespace Streaming.Jsonl;
12
+
13
+ @route("basic")
14
+ namespace Basic {
15
+ @scenario
16
+ @scenarioDoc("""
17
+ Basic jsonl streaming for request.
18
+ """)
19
+ @route("send")
20
+ @post
21
+ op send(stream: JsonlStream<Info>): NoContentResponse;
22
+
23
+ @scenario
24
+ @scenarioDoc("""
25
+ Basic jsonl streaming for response.
26
+ """)
27
+ @route("receive")
28
+ op receive(): JsonlStream<Info>;
29
+
30
+ model Info {
31
+ desc: string;
32
+ }
33
+ }
@@ -0,0 +1,32 @@
1
+ import { passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
2
+
3
+ export const Scenarios: Record<string, ScenarioMockApi> = {};
4
+
5
+ Scenarios.Streaming_Jsonl_Basic_send = passOnSuccess({
6
+ uri: "/streaming/jsonl/basic/send",
7
+ method: "post",
8
+ request: {
9
+ body: {
10
+ rawContent: Buffer.from('{"desc": "one"}\n{"desc": "two"}\n{"desc": "three"}'),
11
+ contentType: "application/jsonl",
12
+ },
13
+ },
14
+ response: {
15
+ status: 204,
16
+ },
17
+ kind: "MockApiDefinition",
18
+ });
19
+
20
+ Scenarios.Streaming_Jsonl_Basic_receive = passOnSuccess({
21
+ uri: "/streaming/jsonl/basic/receive",
22
+ method: "get",
23
+ request: {},
24
+ response: {
25
+ status: 200,
26
+ body: {
27
+ rawContent: Buffer.from('{"desc": "one"}\n{"desc": "two"}\n{"desc": "three"}'),
28
+ contentType: "application/jsonl",
29
+ },
30
+ },
31
+ kind: "MockApiDefinition",
32
+ });
@@ -18,7 +18,7 @@ function createServerTests(uri: string, data: any) {
18
18
  uri,
19
19
  method: "put",
20
20
  request: {
21
- body: data,
21
+ body: json(data),
22
22
  },
23
23
  response: {
24
24
  status: 204,
@@ -18,7 +18,7 @@ function createServerTests(uri: string, data: any) {
18
18
  uri,
19
19
  method: "put",
20
20
  request: {
21
- body: data,
21
+ body: json(data),
22
22
  },
23
23
  response: {
24
24
  status: 204,
@@ -40,6 +40,9 @@ interface String {
40
40
  @get
41
41
  @route("/known-value")
42
42
  getKnownValue(): {
43
+ @header
44
+ contentType: "application/json";
45
+
43
46
  @body body: DaysOfWeekExtensibleEnum;
44
47
  };
45
48
 
@@ -48,6 +51,9 @@ interface String {
48
51
  @get
49
52
  @route("/unknown-value")
50
53
  getUnknownValue(): {
54
+ @header
55
+ contentType: "application/json";
56
+
51
57
  @body body: DaysOfWeekExtensibleEnum;
52
58
  };
53
59
 
@@ -55,11 +61,21 @@ interface String {
55
61
  @scenarioDoc("Expect to send a known value. Mock api expect to receive 'Monday'")
56
62
  @put
57
63
  @route("/known-value")
58
- putKnownValue(@body body: DaysOfWeekExtensibleEnum): void;
64
+ putKnownValue(
65
+ @header
66
+ contentType: "application/json",
67
+
68
+ @body body: DaysOfWeekExtensibleEnum,
69
+ ): void;
59
70
 
60
71
  @scenario
61
72
  @scenarioDoc("Expect to handle an unknown value. Mock api expect to receive 'Weekend'")
62
73
  @put
63
74
  @route("/unknown-value")
64
- putUnknownValue(@body body: DaysOfWeekExtensibleEnum): void;
75
+ putUnknownValue(
76
+ @header
77
+ contentType: "application/json",
78
+
79
+ @body body: DaysOfWeekExtensibleEnum,
80
+ ): void;
65
81
  }
@@ -18,7 +18,7 @@ function createMockServerTests(uri: string, data: any) {
18
18
  uri,
19
19
  method: "put",
20
20
  request: {
21
- body: data,
21
+ body: json(data),
22
22
  headers: {
23
23
  "Content-Type": "text/plain",
24
24
  },
@@ -40,7 +40,13 @@ interface String {
40
40
  @get
41
41
  @route("/known-value")
42
42
  @doc("getKnownValue")
43
- getKnownValue(): DaysOfWeekEnum;
43
+ getKnownValue(): {
44
+ @header
45
+ contentType: "application/json";
46
+
47
+ @body
48
+ body: DaysOfWeekEnum;
49
+ };
44
50
 
45
51
  #suppress "@azure-tools/typespec-azure-core/use-standard-operations" "For testing"
46
52
  @scenario
@@ -48,7 +54,10 @@ interface String {
48
54
  @put
49
55
  @route("/known-value")
50
56
  @doc("putKnownValue")
51
- putKnownValue(@body @doc("_") body: DaysOfWeekEnum): void;
57
+ putKnownValue(
58
+ @header contentType: "application/json",
59
+ @body @doc("_") body: DaysOfWeekEnum,
60
+ ): void;
52
61
 
53
62
  #suppress "@azure-tools/typespec-azure-core/use-standard-operations" "For testing"
54
63
  @scenario
@@ -56,5 +65,8 @@ interface String {
56
65
  @put
57
66
  @route("/unknown-value")
58
67
  @doc("putUnknownValue")
59
- putUnknownValue(@body @doc("_") body: DaysOfWeekEnum): void;
68
+ putUnknownValue(
69
+ @header contentType: "application/json",
70
+ @body @doc("_") body: DaysOfWeekEnum,
71
+ ): void;
60
72
  }
@@ -16,7 +16,7 @@ Scenarios.Type_Enum_Fixed_String_putKnownValue = passOnSuccess({
16
16
  uri: "/type/enum/fixed/string/known-value",
17
17
  method: "put",
18
18
  request: {
19
- body: "Monday",
19
+ body: json("Monday"),
20
20
  headers: {
21
21
  "Content-Type": "application/json",
22
22
  },
@@ -31,7 +31,7 @@ Scenarios.Type_Enum_Fixed_String_putUnknownValue = passOnCode(500, {
31
31
  uri: "/type/enum/fixed/string/unknown-value",
32
32
  method: "put",
33
33
  request: {
34
- body: "Weekend",
34
+ body: json("Weekend"),
35
35
  headers: {
36
36
  "Content-Type": "application/json",
37
37
  },
@@ -0,0 +1,109 @@
1
+ import "@typespec/http";
2
+ import "@typespec/spector";
3
+
4
+ using Http;
5
+ using Spector;
6
+
7
+ @doc("Test for File type usage in request and response bodies")
8
+ @scenarioService("/type/file")
9
+ namespace Type.File;
10
+
11
+ /**
12
+ * Test File as request and response body with specific content type
13
+ */
14
+ @route("/body")
15
+ namespace Body {
16
+ @scenario
17
+ @scenarioDoc("""
18
+ Test File type as request body with specific content type.
19
+ Expected request:
20
+ - Content-Type header: image/png
21
+ - Body: binary content matching packages/http-specs/assets/image.png
22
+ """)
23
+ @post
24
+ @route("/request/specific-content-type")
25
+ op uploadFileSpecificContentType(@bodyRoot file: Http.File<"image/png">): NoContentResponse;
26
+
27
+ @scenario
28
+ @scenarioDoc("""
29
+ Test File type as request body with JSON content type.
30
+ Expected request:
31
+ - Content-Type header: application/json
32
+ - Body: JSON content with file data
33
+ """)
34
+ @post
35
+ @route("/request/json-content-type")
36
+ op uploadFileJsonContentType(@bodyRoot file: Http.File<"application/json">): NoContentResponse;
37
+
38
+ @scenario
39
+ @scenarioDoc("""
40
+ Test File type as response body with JSON content type.
41
+ Expected response:
42
+ - Content-Type header: application/json
43
+ - Body: JSON content with file data
44
+ """)
45
+ @get
46
+ @route("/response/json-content-type")
47
+ op downloadFileJsonContentType(): Http.File<"application/json">;
48
+
49
+ @scenario
50
+ @scenarioDoc("""
51
+ Test File type as response body with specific content type.
52
+ Expected response:
53
+ - Content-Type header: image/png
54
+ - Body: binary content matching packages/http-specs/assets/image.png
55
+ """)
56
+ @get
57
+ @route("/response/specific-content-type")
58
+ op downloadFileSpecificContentType(): Http.File<"image/png">;
59
+
60
+ @scenario
61
+ @scenarioDoc("""
62
+ Test File type as request body with multiple allowed content types (image/png or image/jpeg).
63
+ Client should send image/png.
64
+ Expected request:
65
+ - Content-Type header: image/png
66
+ - Body: binary content matching packages/http-specs/assets/image.png
67
+ """)
68
+ @post
69
+ @route("/request/multiple-content-types")
70
+ op uploadFileMultipleContentTypes(
71
+ @bodyRoot file: Http.File<"image/png" | "image/jpeg">,
72
+ ): NoContentResponse;
73
+
74
+ @scenario
75
+ @scenarioDoc("""
76
+ Test File type as response body with multiple allowed content types.
77
+ Service will return image/png.
78
+ Expected response:
79
+ - Content-Type header: image/png
80
+ - Body: binary content matching packages/http-specs/assets/image.png
81
+ """)
82
+ @get
83
+ @route("/response/multiple-content-types")
84
+ op downloadFileMultipleContentTypes(): Http.File<"image/png" | "image/jpeg">;
85
+
86
+ @scenario
87
+ @scenarioDoc("""
88
+ Test File type as request body with unspecified content type.
89
+ The File type accepts any content type. For testing, sender will use image/png.
90
+ Expected request:
91
+ - Content-Type header: image/png
92
+ - Body: binary content matching packages/http-specs/assets/image.png
93
+ """)
94
+ @post
95
+ @route("/request/default-content-type")
96
+ op uploadFileDefaultContentType(@bodyRoot file: Http.File): NoContentResponse;
97
+
98
+ @scenario
99
+ @scenarioDoc("""
100
+ Test File type as response body with unspecified content type.
101
+ The File type accepts any content type. For testing, server will return image/png.
102
+ Expected response:
103
+ - Content-Type header: image/png
104
+ - Body: binary content matching packages/http-specs/assets/image.png
105
+ """)
106
+ @get
107
+ @route("/response/default-content-type")
108
+ op downloadFileDefaultContentType(): Http.File;
109
+ }
@@ -0,0 +1,200 @@
1
+ import { MockRequest, passOnSuccess, ScenarioMockApi, ValidationError } from "@typespec/spec-api";
2
+ import { pngFile } from "../../helper.js";
3
+
4
+ export const Scenarios: Record<string, ScenarioMockApi> = {};
5
+
6
+ // Helper function to check file content
7
+ function checkFileContent(req: MockRequest, expectedFile: Buffer) {
8
+ req.expect.rawBodyEquals(expectedFile);
9
+ }
10
+
11
+ // Body tests - Request with specific content type
12
+ Scenarios.Type_File_Body_uploadFileSpecificContentType = passOnSuccess({
13
+ uri: "/type/file/body/request/specific-content-type",
14
+ method: "post",
15
+ request: {
16
+ body: {
17
+ contentType: "image/png",
18
+ rawContent: pngFile,
19
+ },
20
+ },
21
+ response: {
22
+ status: 204,
23
+ },
24
+ handler(req: MockRequest) {
25
+ req.expect.containsHeader("content-type", "image/png");
26
+ checkFileContent(req, pngFile);
27
+ return { status: 204 };
28
+ },
29
+ kind: "MockApiDefinition",
30
+ });
31
+
32
+ // Body tests - Request with JSON content type
33
+ Scenarios.Type_File_Body_uploadFileJsonContentType = passOnSuccess({
34
+ uri: "/type/file/body/request/json-content-type",
35
+ method: "post",
36
+ request: {
37
+ body: {
38
+ contentType: "application/json",
39
+ rawContent: JSON.stringify({ message: "test file content" }),
40
+ },
41
+ },
42
+ response: {
43
+ status: 204,
44
+ },
45
+ handler(req: MockRequest) {
46
+ req.expect.containsHeader("content-type", "application/json");
47
+ req.expect.rawBodyEquals(JSON.stringify({ message: "test file content" }));
48
+ return { status: 204 };
49
+ },
50
+ kind: "MockApiDefinition",
51
+ });
52
+
53
+ // Body tests - Response with JSON content type
54
+ Scenarios.Type_File_Body_downloadFileJsonContentType = passOnSuccess({
55
+ uri: "/type/file/body/response/json-content-type",
56
+ method: "get",
57
+ request: {},
58
+ response: {
59
+ status: 200,
60
+ body: {
61
+ contentType: "application/json",
62
+ rawContent: JSON.stringify({ message: "test file content" }),
63
+ },
64
+ },
65
+ handler(req: MockRequest) {
66
+ return {
67
+ status: 200,
68
+ body: {
69
+ contentType: "application/json",
70
+ rawContent: JSON.stringify({ message: "test file content" }),
71
+ },
72
+ };
73
+ },
74
+ kind: "MockApiDefinition",
75
+ });
76
+
77
+ // Body tests - Response with specific content type
78
+ Scenarios.Type_File_Body_downloadFileSpecificContentType = passOnSuccess({
79
+ uri: "/type/file/body/response/specific-content-type",
80
+ method: "get",
81
+ request: {},
82
+ response: {
83
+ status: 200,
84
+ body: {
85
+ contentType: "image/png",
86
+ rawContent: pngFile,
87
+ },
88
+ },
89
+ handler(req: MockRequest) {
90
+ return {
91
+ status: 200,
92
+ body: {
93
+ contentType: "image/png",
94
+ rawContent: pngFile,
95
+ },
96
+ };
97
+ },
98
+ kind: "MockApiDefinition",
99
+ });
100
+
101
+ // Body tests - Request with multiple content types
102
+ Scenarios.Type_File_Body_uploadFileMultipleContentTypes = passOnSuccess({
103
+ uri: "/type/file/body/request/multiple-content-types",
104
+ method: "post",
105
+ request: {
106
+ body: {
107
+ contentType: "image/png",
108
+ rawContent: pngFile,
109
+ },
110
+ },
111
+ response: {
112
+ status: 204,
113
+ },
114
+ handler(req: MockRequest) {
115
+ // Client should send image/png (one of the allowed types)
116
+ const contentType = req.headers["content-type"];
117
+ if (contentType !== "image/png" && contentType !== "image/jpeg") {
118
+ throw new ValidationError(
119
+ "Expected content-type to be image/png or image/jpeg",
120
+ "image/png or image/jpeg",
121
+ contentType,
122
+ );
123
+ }
124
+ checkFileContent(req, pngFile);
125
+ return { status: 204 };
126
+ },
127
+ kind: "MockApiDefinition",
128
+ });
129
+
130
+ // Body tests - Response with multiple content types
131
+ Scenarios.Type_File_Body_downloadFileMultipleContentTypes = passOnSuccess({
132
+ uri: "/type/file/body/response/multiple-content-types",
133
+ method: "get",
134
+ request: {},
135
+ response: {
136
+ status: 200,
137
+ body: {
138
+ contentType: "image/png",
139
+ rawContent: pngFile,
140
+ },
141
+ },
142
+ handler(req: MockRequest) {
143
+ // Server returns image/png (one of the allowed types)
144
+ return {
145
+ status: 200,
146
+ body: {
147
+ contentType: "image/png",
148
+ rawContent: pngFile,
149
+ },
150
+ };
151
+ },
152
+ kind: "MockApiDefinition",
153
+ });
154
+
155
+ // Body tests - Request with default content type
156
+ Scenarios.Type_File_Body_uploadFileDefaultContentType = passOnSuccess({
157
+ uri: "/type/file/body/request/default-content-type",
158
+ method: "post",
159
+ request: {
160
+ body: {
161
+ contentType: "image/png",
162
+ rawContent: pngFile,
163
+ },
164
+ },
165
+ response: {
166
+ status: 204,
167
+ },
168
+ handler(req: MockRequest) {
169
+ // File type accepts any content type, but for testing we expect image/png
170
+ req.expect.containsHeader("content-type", "image/png");
171
+ checkFileContent(req, pngFile);
172
+ return { status: 204 };
173
+ },
174
+ kind: "MockApiDefinition",
175
+ });
176
+
177
+ // Body tests - Response with default content type
178
+ Scenarios.Type_File_Body_downloadFileDefaultContentType = passOnSuccess({
179
+ uri: "/type/file/body/response/default-content-type",
180
+ method: "get",
181
+ request: {},
182
+ response: {
183
+ status: 200,
184
+ body: {
185
+ contentType: "image/png",
186
+ rawContent: pngFile,
187
+ },
188
+ },
189
+ handler(req: MockRequest) {
190
+ // File type accepts any content type, but for testing we return image/png
191
+ return {
192
+ status: 200,
193
+ body: {
194
+ contentType: "image/png",
195
+ rawContent: pngFile,
196
+ },
197
+ };
198
+ },
199
+ kind: "MockApiDefinition",
200
+ });
@@ -8,7 +8,7 @@ Scenarios.Type_Model_Empty_putEmpty = passOnSuccess({
8
8
  uri: "/type/model/empty/alone",
9
9
  method: "put",
10
10
  request: {
11
- body: body,
11
+ body: json(body),
12
12
  },
13
13
  response: {
14
14
  status: 204,
@@ -30,7 +30,7 @@ Scenarios.Type_Model_Empty_postRoundTripEmpty = passOnSuccess({
30
30
  uri: "/type/model/empty/round-trip",
31
31
  method: "post",
32
32
  request: {
33
- body: body,
33
+ body: json(body),
34
34
  },
35
35
  response: {
36
36
  status: 200,
@@ -39,7 +39,7 @@ function createGetPutServerTests(uri: string, data: any) {
39
39
  uri: uri,
40
40
  method: "put",
41
41
  request: {
42
- body: data,
42
+ body: json(data),
43
43
  },
44
44
  response: {
45
45
  status: 204,
@@ -78,7 +78,7 @@ Scenarios.Type_Model_Inheritance_NestedDiscriminator_putModel = passOnSuccess({
78
78
  uri: "/type/model/inheritance/nested-discriminator/model",
79
79
  method: "put",
80
80
  request: {
81
- body: validPolymorphicBody,
81
+ body: json(validPolymorphicBody),
82
82
  },
83
83
  response: {
84
84
  status: 204,
@@ -100,7 +100,7 @@ Scenarios.Type_Model_Inheritance_NestedDiscriminator_putRecursiveModel = passOnS
100
100
  uri: "/type/model/inheritance/nested-discriminator/recursivemodel",
101
101
  method: "put",
102
102
  request: {
103
- body: validRecursiveBody,
103
+ body: json(validRecursiveBody),
104
104
  },
105
105
  response: {
106
106
  status: 204,
@@ -8,7 +8,7 @@ Scenarios.Type_Model_Inheritance_NotDiscriminated_postValid = passOnSuccess({
8
8
  uri: "/type/model/inheritance/not-discriminated/valid",
9
9
  method: "post",
10
10
  request: {
11
- body: inheritanceValidBody,
11
+ body: json(inheritanceValidBody),
12
12
  },
13
13
  response: {
14
14
  status: 204,
@@ -29,7 +29,7 @@ Scenarios.Type_Model_Inheritance_NotDiscriminated_putValid = passOnSuccess({
29
29
  uri: "/type/model/inheritance/not-discriminated/valid",
30
30
  method: "put",
31
31
  request: {
32
- body: inheritanceValidBody,
32
+ body: json(inheritanceValidBody),
33
33
  },
34
34
  response: {
35
35
  status: 200,
@@ -22,7 +22,7 @@ Scenarios.Type_Model_Inheritance_Recursive_put = passOnSuccess({
22
22
  uri: "/type/model/inheritance/recursive",
23
23
  method: "put",
24
24
  request: {
25
- body: body,
25
+ body: json(body),
26
26
  },
27
27
  response: {
28
28
  status: 204,