@typespec/http-specs 0.1.0-alpha.3-dev.6 → 0.1.0-alpha.30-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/CHANGELOG.md +238 -0
  2. package/README.md +11 -3
  3. package/dist/specs/documentation/mockapi.d.ts.map +1 -0
  4. package/dist/specs/documentation/mockapi.js +38 -0
  5. package/dist/specs/documentation/mockapi.js.map +1 -0
  6. package/dist/specs/encode/array/mockapi.d.ts +3 -0
  7. package/dist/specs/encode/array/mockapi.d.ts.map +1 -0
  8. package/dist/specs/encode/array/mockapi.js +25 -0
  9. package/dist/specs/encode/array/mockapi.js.map +1 -0
  10. package/dist/specs/encode/bytes/mockapi.js +16 -24
  11. package/dist/specs/encode/bytes/mockapi.js.map +1 -1
  12. package/dist/specs/encode/datetime/mockapi.js +2 -2
  13. package/dist/specs/encode/datetime/mockapi.js.map +1 -1
  14. package/dist/specs/encode/duration/mockapi.js +74 -2
  15. package/dist/specs/encode/duration/mockapi.js.map +1 -1
  16. package/dist/specs/encode/numeric/mockapi.js +2 -2
  17. package/dist/specs/encode/numeric/mockapi.js.map +1 -1
  18. package/dist/specs/helper.d.ts +2 -2
  19. package/dist/specs/helper.d.ts.map +1 -1
  20. package/dist/specs/parameters/basic/mockapi.d.ts.map +1 -1
  21. package/dist/specs/parameters/basic/mockapi.js +3 -3
  22. package/dist/specs/parameters/basic/mockapi.js.map +1 -1
  23. package/dist/specs/parameters/body-optionality/mockapi.d.ts.map +1 -1
  24. package/dist/specs/parameters/body-optionality/mockapi.js +14 -4
  25. package/dist/specs/parameters/body-optionality/mockapi.js.map +1 -1
  26. package/dist/specs/parameters/collection-format/mockapi.js +4 -15
  27. package/dist/specs/parameters/collection-format/mockapi.js.map +1 -1
  28. package/dist/specs/parameters/path/mockapi.d.ts +3 -0
  29. package/dist/specs/parameters/path/mockapi.d.ts.map +1 -0
  30. package/dist/specs/parameters/path/mockapi.js +29 -0
  31. package/dist/specs/parameters/path/mockapi.js.map +1 -0
  32. package/dist/specs/parameters/spread/mockapi.d.ts.map +1 -1
  33. package/dist/specs/parameters/spread/mockapi.js +19 -19
  34. package/dist/specs/parameters/spread/mockapi.js.map +1 -1
  35. package/dist/specs/payload/json-merge-patch/mockapi.js +4 -4
  36. package/dist/specs/payload/json-merge-patch/mockapi.js.map +1 -1
  37. package/dist/specs/payload/media-type/mockapi.js +2 -2
  38. package/dist/specs/payload/media-type/mockapi.js.map +1 -1
  39. package/dist/specs/payload/multipart/mockapi.d.ts.map +1 -1
  40. package/dist/specs/payload/multipart/mockapi.js +42 -60
  41. package/dist/specs/payload/multipart/mockapi.js.map +1 -1
  42. package/dist/specs/payload/pageable/mockapi.d.ts.map +1 -1
  43. package/dist/specs/payload/pageable/mockapi.js +425 -18
  44. package/dist/specs/payload/pageable/mockapi.js.map +1 -1
  45. package/dist/specs/payload/xml/mockapi.js +1 -4
  46. package/dist/specs/payload/xml/mockapi.js.map +1 -1
  47. package/dist/specs/response/status-code-range/mockapi.d.ts +3 -0
  48. package/dist/specs/response/status-code-range/mockapi.d.ts.map +1 -0
  49. package/dist/specs/response/status-code-range/mockapi.js +29 -0
  50. package/dist/specs/response/status-code-range/mockapi.js.map +1 -0
  51. package/dist/specs/routes/mockapi.js +25 -25
  52. package/dist/specs/routes/mockapi.js.map +1 -1
  53. package/dist/specs/serialization/encoded-name/json/mockapi.js +1 -1
  54. package/dist/specs/serialization/encoded-name/json/mockapi.js.map +1 -1
  55. package/dist/specs/server/versions/not-versioned/mockapi.js +1 -1
  56. package/dist/specs/server/versions/not-versioned/mockapi.js.map +1 -1
  57. package/dist/specs/server/versions/versioned/mockapi.js +8 -12
  58. package/dist/specs/server/versions/versioned/mockapi.js.map +1 -1
  59. package/dist/specs/special-words/mockapi.d.ts.map +1 -1
  60. package/dist/specs/special-words/mockapi.js +28 -6
  61. package/dist/specs/special-words/mockapi.js.map +1 -1
  62. package/dist/specs/streaming/jsonl/mockapi.d.ts +3 -0
  63. package/dist/specs/streaming/jsonl/mockapi.d.ts.map +1 -0
  64. package/dist/specs/streaming/jsonl/mockapi.js +30 -0
  65. package/dist/specs/streaming/jsonl/mockapi.js.map +1 -0
  66. package/dist/specs/type/array/mockapi.js +1 -1
  67. package/dist/specs/type/array/mockapi.js.map +1 -1
  68. package/dist/specs/type/dictionary/mockapi.js +1 -1
  69. package/dist/specs/type/dictionary/mockapi.js.map +1 -1
  70. package/dist/specs/type/enum/extensible/mockapi.js +1 -1
  71. package/dist/specs/type/enum/extensible/mockapi.js.map +1 -1
  72. package/dist/specs/type/enum/fixed/mockapi.js +2 -2
  73. package/dist/specs/type/enum/fixed/mockapi.js.map +1 -1
  74. package/dist/specs/type/model/empty/mockapi.js +2 -2
  75. package/dist/specs/type/model/empty/mockapi.js.map +1 -1
  76. package/dist/specs/type/model/inheritance/enum-discriminator/mockapi.js +1 -1
  77. package/dist/specs/type/model/inheritance/enum-discriminator/mockapi.js.map +1 -1
  78. package/dist/specs/type/model/inheritance/nested-discriminator/mockapi.js +2 -2
  79. package/dist/specs/type/model/inheritance/nested-discriminator/mockapi.js.map +1 -1
  80. package/dist/specs/type/model/inheritance/not-discriminated/mockapi.js +2 -2
  81. package/dist/specs/type/model/inheritance/not-discriminated/mockapi.js.map +1 -1
  82. package/dist/specs/type/model/inheritance/recursive/mockapi.js +1 -1
  83. package/dist/specs/type/model/inheritance/recursive/mockapi.js.map +1 -1
  84. package/dist/specs/type/model/inheritance/single-discriminator/mockapi.js +2 -2
  85. package/dist/specs/type/model/inheritance/single-discriminator/mockapi.js.map +1 -1
  86. package/dist/specs/type/model/usage/mockapi.js +4 -4
  87. package/dist/specs/type/model/usage/mockapi.js.map +1 -1
  88. package/dist/specs/type/model/visibility/mockapi.js +9 -10
  89. package/dist/specs/type/model/visibility/mockapi.js.map +1 -1
  90. package/dist/specs/type/property/additional-properties/mockapi.js +9 -6
  91. package/dist/specs/type/property/additional-properties/mockapi.js.map +1 -1
  92. package/dist/specs/type/property/nullable/mockapi.js +2 -6
  93. package/dist/specs/type/property/nullable/mockapi.js.map +1 -1
  94. package/dist/specs/type/property/optionality/mockapi.js +1 -1
  95. package/dist/specs/type/property/optionality/mockapi.js.map +1 -1
  96. package/dist/specs/type/property/value-types/mockapi.js +3 -3
  97. package/dist/specs/type/property/value-types/mockapi.js.map +1 -1
  98. package/dist/specs/type/scalar/mockapi.js +9 -9
  99. package/dist/specs/type/scalar/mockapi.js.map +1 -1
  100. package/dist/specs/type/union/discriminated/mockapi.d.ts +3 -0
  101. package/dist/specs/type/union/discriminated/mockapi.d.ts.map +1 -0
  102. package/dist/specs/type/union/discriminated/mockapi.js +212 -0
  103. package/dist/specs/type/union/discriminated/mockapi.js.map +1 -0
  104. package/dist/specs/type/union/mockapi.js +2 -2
  105. package/dist/specs/type/union/mockapi.js.map +1 -1
  106. package/dist/specs/versioning/added/mockapi.js +6 -6
  107. package/dist/specs/versioning/added/mockapi.js.map +1 -1
  108. package/dist/specs/versioning/madeOptional/mockapi.js +2 -2
  109. package/dist/specs/versioning/madeOptional/mockapi.js.map +1 -1
  110. package/dist/specs/versioning/removed/mockapi.js +46 -2
  111. package/dist/specs/versioning/removed/mockapi.js.map +1 -1
  112. package/dist/specs/versioning/renamedFrom/mockapi.js +5 -5
  113. package/dist/specs/versioning/renamedFrom/mockapi.js.map +1 -1
  114. package/dist/specs/versioning/returnTypeChangedFrom/mockapi.js +1 -1
  115. package/dist/specs/versioning/returnTypeChangedFrom/mockapi.js.map +1 -1
  116. package/dist/specs/versioning/typeChangedFrom/mockapi.js +3 -3
  117. package/dist/specs/versioning/typeChangedFrom/mockapi.js.map +1 -1
  118. package/package.json +32 -19
  119. package/smoke/petstore/main.tsp +96 -0
  120. package/smoke/todoapp/main.tsp +293 -0
  121. package/spec-summary.md +1289 -265
  122. package/specs/documentation/main.tsp +158 -0
  123. package/specs/documentation/mockapi.ts +57 -0
  124. package/specs/encode/array/main.tsp +112 -0
  125. package/specs/encode/array/mockapi.ts +43 -0
  126. package/specs/encode/bytes/main.tsp +29 -20
  127. package/specs/encode/bytes/mockapi.ts +13 -31
  128. package/specs/encode/datetime/main.tsp +2 -7
  129. package/specs/encode/datetime/mockapi.ts +2 -2
  130. package/specs/encode/duration/main.tsp +420 -7
  131. package/specs/encode/duration/mockapi.ts +174 -2
  132. package/specs/encode/numeric/mockapi.ts +2 -2
  133. package/specs/parameters/basic/mockapi.ts +3 -3
  134. package/specs/parameters/body-optionality/main.tsp +2 -0
  135. package/specs/parameters/body-optionality/mockapi.ts +24 -4
  136. package/specs/parameters/collection-format/main.tsp +5 -25
  137. package/specs/parameters/collection-format/mockapi.ts +4 -16
  138. package/specs/parameters/path/main.tsp +48 -0
  139. package/specs/parameters/path/mockapi.ts +34 -0
  140. package/specs/parameters/spread/mockapi.ts +19 -19
  141. package/specs/payload/json-merge-patch/main.tsp +2 -2
  142. package/specs/payload/json-merge-patch/mockapi.ts +4 -4
  143. package/specs/payload/media-type/mockapi.ts +2 -2
  144. package/specs/payload/multipart/main.tsp +34 -32
  145. package/specs/payload/multipart/mockapi.ts +42 -59
  146. package/specs/payload/pageable/main.tsp +462 -7
  147. package/specs/payload/pageable/mockapi.ts +478 -18
  148. package/specs/payload/xml/mockapi.ts +1 -4
  149. package/specs/response/status-code-range/main.tsp +82 -0
  150. package/specs/response/status-code-range/mockapi.ts +31 -0
  151. package/specs/routes/main.tsp +48 -48
  152. package/specs/routes/mockapi.ts +25 -25
  153. package/specs/serialization/encoded-name/json/main.tsp +1 -1
  154. package/specs/serialization/encoded-name/json/mockapi.ts +1 -1
  155. package/specs/server/endpoint/not-defined/main.tsp +1 -3
  156. package/specs/server/path/multiple/main.tsp +3 -5
  157. package/specs/server/versions/not-versioned/mockapi.ts +1 -1
  158. package/specs/server/versions/versioned/main.tsp +1 -1
  159. package/specs/server/versions/versioned/mockapi.ts +6 -12
  160. package/specs/special-headers/conditional-request/main.tsp +1 -1
  161. package/specs/special-headers/repeatability/main.tsp +2 -2
  162. package/specs/special-words/main.tsp +44 -6
  163. package/specs/special-words/mockapi.ts +29 -6
  164. package/specs/streaming/jsonl/main.tsp +33 -0
  165. package/specs/streaming/jsonl/mockapi.ts +32 -0
  166. package/specs/type/array/mockapi.ts +1 -1
  167. package/specs/type/dictionary/mockapi.ts +1 -1
  168. package/specs/type/enum/extensible/main.tsp +18 -2
  169. package/specs/type/enum/extensible/mockapi.ts +1 -1
  170. package/specs/type/enum/fixed/main.tsp +15 -3
  171. package/specs/type/enum/fixed/mockapi.ts +2 -2
  172. package/specs/type/model/empty/mockapi.ts +2 -2
  173. package/specs/type/model/inheritance/enum-discriminator/mockapi.ts +1 -1
  174. package/specs/type/model/inheritance/nested-discriminator/mockapi.ts +2 -2
  175. package/specs/type/model/inheritance/not-discriminated/mockapi.ts +2 -2
  176. package/specs/type/model/inheritance/recursive/mockapi.ts +1 -1
  177. package/specs/type/model/inheritance/single-discriminator/mockapi.ts +2 -2
  178. package/specs/type/model/usage/mockapi.ts +4 -4
  179. package/specs/type/model/visibility/main.tsp +15 -23
  180. package/specs/type/model/visibility/mockapi.ts +9 -10
  181. package/specs/type/property/additional-properties/main.tsp +17 -17
  182. package/specs/type/property/additional-properties/mockapi.ts +10 -10
  183. package/specs/type/property/nullable/mockapi.ts +7 -8
  184. package/specs/type/property/optionality/mockapi.ts +1 -1
  185. package/specs/type/property/value-types/mockapi.ts +3 -3
  186. package/specs/type/scalar/main.tsp +58 -9
  187. package/specs/type/scalar/mockapi.ts +9 -9
  188. package/specs/type/union/discriminated/main.tsp +251 -0
  189. package/specs/type/union/discriminated/mockapi.ts +230 -0
  190. package/specs/type/union/mockapi.ts +2 -2
  191. package/specs/versioning/added/mockapi.ts +6 -6
  192. package/specs/versioning/madeOptional/mockapi.ts +2 -2
  193. package/specs/versioning/removed/main.tsp +65 -3
  194. package/specs/versioning/removed/mockapi.ts +49 -2
  195. package/specs/versioning/renamedFrom/mockapi.ts +5 -5
  196. package/specs/versioning/returnTypeChangedFrom/main.tsp +17 -2
  197. package/specs/versioning/returnTypeChangedFrom/mockapi.ts +1 -1
  198. package/specs/versioning/typeChangedFrom/mockapi.ts +3 -3
  199. package/temp/.tsbuildinfo +1 -1
  200. package/tspconfig.yaml +0 -2
  201. package/dist/specs/type/model/templated/mockapi.d.ts.map +0 -1
  202. package/dist/specs/type/model/templated/mockapi.js +0 -63
  203. package/dist/specs/type/model/templated/mockapi.js.map +0 -1
  204. package/specs/type/model/templated/main.tsp +0 -130
  205. package/specs/type/model/templated/mockapi.ts +0 -66
  206. /package/dist/specs/{type/model/templated → documentation}/mockapi.d.ts +0 -0
@@ -7,9 +7,9 @@ function createTests(uri: string, value: any) {
7
7
  uri,
8
8
  method: "post",
9
9
  request: {
10
- body: {
10
+ body: json({
11
11
  value,
12
- },
12
+ }),
13
13
  },
14
14
  response: {
15
15
  status: 200,
@@ -1,4 +1,4 @@
1
- import { passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
1
+ import { json, passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
2
2
 
3
3
  export const Scenarios: Record<string, ScenarioMockApi> = {};
4
4
  function createServerTests(uri: string) {
@@ -6,9 +6,9 @@ function createServerTests(uri: string) {
6
6
  uri,
7
7
  method: "put",
8
8
  request: {
9
- body: {
9
+ body: json({
10
10
  name: "foo",
11
- },
11
+ }),
12
12
  },
13
13
  response: {
14
14
  status: 204,
@@ -33,8 +33,10 @@ op requiredExplicit(@body body: BodyModel): NoContentResponse;
33
33
  ```json
34
34
  { "name": "foo" }
35
35
  ```
36
+ Expected Content-Type header: application/json
36
37
 
37
38
  Expected no request body for `omit`
39
+ Expected Content-Type header: must NOT be present
38
40
  """)
39
41
  @route("/optional-explicit")
40
42
  namespace OptionalExplicit {
@@ -1,4 +1,10 @@
1
- import { MockRequest, passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
1
+ import {
2
+ json,
3
+ MockRequest,
4
+ passOnSuccess,
5
+ ScenarioMockApi,
6
+ ValidationError,
7
+ } from "@typespec/spec-api";
2
8
 
3
9
  export const Scenarios: Record<string, ScenarioMockApi> = {};
4
10
  function createServerTests(uri: string, data: any) {
@@ -6,7 +12,7 @@ function createServerTests(uri: string, data: any) {
6
12
  uri,
7
13
  method: "post",
8
14
  request: {
9
- body: data,
15
+ body: json(data),
10
16
  },
11
17
  response: {
12
18
  status: 204,
@@ -27,13 +33,18 @@ Scenarios.Parameters_BodyOptionality_OptionalExplicit = passOnSuccess([
27
33
  uri: "/parameters/body-optionality/optional-explicit/set",
28
34
  method: "post",
29
35
  request: {
30
- body: {
36
+ body: json({
31
37
  name: "foo",
32
- },
38
+ }),
33
39
  },
34
40
  response: {
35
41
  status: 204,
36
42
  },
43
+ handler: (req: MockRequest) => {
44
+ // Validate that Content-Type header is present when body is provided
45
+ req.expect.containsHeader("content-type", "application/json");
46
+ return { status: 204 };
47
+ },
37
48
  kind: "MockApiDefinition",
38
49
  },
39
50
  {
@@ -45,6 +56,15 @@ Scenarios.Parameters_BodyOptionality_OptionalExplicit = passOnSuccess([
45
56
  },
46
57
  handler: (req: MockRequest) => {
47
58
  req.expect.rawBodyEquals(undefined);
59
+ // Validate that Content-Type header is NOT present when body is omitted
60
+ const contentTypeHeader = req.headers["content-type"];
61
+ if (contentTypeHeader !== undefined) {
62
+ throw new ValidationError(
63
+ "Content-Type header must NOT be present when body is omitted",
64
+ undefined,
65
+ contentTypeHeader,
66
+ );
67
+ }
48
68
  return { status: 204 };
49
69
  },
50
70
  kind: "MockApiDefinition",
@@ -27,25 +27,9 @@ namespace Query {
27
27
  """)
28
28
  @route("/ssv")
29
29
  op ssv(
30
- #suppress "deprecated" "Deprecated in next release"
31
30
  @doc("Possible values for colors are [blue,red,green]")
32
- @query({
33
- format: "ssv",
34
- })
35
- colors: string[],
36
- ): NoContentResponse;
37
-
38
- @scenario
39
- @scenarioDoc("""
40
- This test is testing sending a tsv collection format array query parameters
41
- """)
42
- @route("/tsv")
43
- op tsv(
44
- #suppress "deprecated" "Deprecated in next release"
45
- @doc("Possible values for colors are [blue,red,green]")
46
- @query({
47
- format: "tsv",
48
- })
31
+ @query
32
+ @encode(ArrayEncoding.spaceDelimited)
49
33
  colors: string[],
50
34
  ): NoContentResponse;
51
35
 
@@ -55,11 +39,9 @@ namespace Query {
55
39
  """)
56
40
  @route("/pipes")
57
41
  op pipes(
58
- #suppress "deprecated" "Deprecated in next release"
59
42
  @doc("Possible values for colors are [blue,red,green]")
60
- @query({
61
- format: "pipes",
62
- })
43
+ @query
44
+ @encode(ArrayEncoding.pipeDelimited)
63
45
  colors: string[],
64
46
  ): NoContentResponse;
65
47
 
@@ -84,9 +66,7 @@ namespace Header {
84
66
  @route("/csv")
85
67
  op csv(
86
68
  @doc("Possible values for colors are [blue,red,green]")
87
- @header({
88
- format: "csv",
89
- })
69
+ @header
90
70
  colors: string[],
91
71
  ): NoContentResponse;
92
72
  }
@@ -8,7 +8,7 @@ Scenarios.Parameters_CollectionFormat_Query_multi = passOnSuccess({
8
8
  uri: `/parameters/collection-format/query/multi`,
9
9
  method: "get",
10
10
  request: {
11
- params: { colors: ["blue", "red", "green"] },
11
+ query: { colors: ["blue", "red", "green"] },
12
12
  },
13
13
  response: {
14
14
  status: 204,
@@ -26,7 +26,7 @@ Scenarios.Parameters_CollectionFormat_Query_csv = passOnSuccess({
26
26
  uri: `/parameters/collection-format/query/csv`,
27
27
  method: "get",
28
28
  request: {
29
- params: { colors: colors.join(",") },
29
+ query: { colors: colors.join(",") },
30
30
  },
31
31
  response: {
32
32
  status: 204,
@@ -38,19 +38,7 @@ Scenarios.Parameters_CollectionFormat_Query_ssv = passOnSuccess({
38
38
  uri: `/parameters/collection-format/query/ssv`,
39
39
  method: "get",
40
40
  request: {
41
- params: { colors: colors.join(" ") },
42
- },
43
- response: {
44
- status: 204,
45
- },
46
- kind: "MockApiDefinition",
47
- });
48
-
49
- Scenarios.Parameters_CollectionFormat_Query_tsv = passOnSuccess({
50
- uri: `/parameters/collection-format/query/tsv`,
51
- method: "get",
52
- request: {
53
- params: { colors: colors.join("\t") },
41
+ query: { colors: colors.join(" ") },
54
42
  },
55
43
  response: {
56
44
  status: 204,
@@ -62,7 +50,7 @@ Scenarios.Parameters_CollectionFormat_Query_pipes = passOnSuccess({
62
50
  uri: `/parameters/collection-format/query/pipes`,
63
51
  method: "get",
64
52
  request: {
65
- params: { colors: colors.join("|") },
53
+ query: { colors: colors.join("|") },
66
54
  },
67
55
  response: {
68
56
  status: 204,
@@ -0,0 +1,48 @@
1
+ import "@typespec/http";
2
+ import "@typespec/spector";
3
+
4
+ using Http;
5
+ using Spector;
6
+
7
+ @doc("Test for path parameters cases.")
8
+ @scenarioService("/parameters/path")
9
+ namespace Parameters.Path;
10
+
11
+ @scenario
12
+ @scenarioDoc("""
13
+ Test case for normal path parameter.
14
+
15
+ Should generate an operation like below:
16
+ ```
17
+ normal(name: string)
18
+ ```
19
+
20
+ Expected request path:
21
+ ```
22
+ /normal/foo
23
+ ```
24
+ """)
25
+ @route("/normal/{name}")
26
+ op normal(@path name: string): NoContentResponse;
27
+
28
+ @scenario
29
+ @scenarioDoc("""
30
+ Test case for optional path parameter.
31
+
32
+ Should generate an operation like below:
33
+ ```
34
+ optional(name?: string)
35
+ ```
36
+
37
+ Expected two request:
38
+ First request path:
39
+ ```
40
+ /optional
41
+ ```
42
+ Second request path:
43
+ ```
44
+ /optional/foo
45
+ ```
46
+ """)
47
+ @route("/optional{/name}")
48
+ op optional(@path name?: string): NoContentResponse;
@@ -0,0 +1,34 @@
1
+ import { passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
2
+
3
+ export const Scenarios: Record<string, ScenarioMockApi> = {};
4
+
5
+ Scenarios.Parameters_Path_normal = passOnSuccess({
6
+ uri: "/parameters/path/normal/foo",
7
+ method: "get",
8
+
9
+ response: {
10
+ status: 204,
11
+ },
12
+ kind: "MockApiDefinition",
13
+ });
14
+
15
+ Scenarios.Parameters_Path_optional = passOnSuccess([
16
+ {
17
+ uri: "/parameters/path/optional",
18
+ method: "get",
19
+
20
+ response: {
21
+ status: 204,
22
+ },
23
+ kind: "MockApiDefinition",
24
+ },
25
+ {
26
+ uri: "/parameters/path/optional/foo",
27
+ method: "get",
28
+
29
+ response: {
30
+ status: 204,
31
+ },
32
+ kind: "MockApiDefinition",
33
+ },
34
+ ]);
@@ -1,4 +1,4 @@
1
- import { passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
1
+ import { json, passOnSuccess, ScenarioMockApi } from "@typespec/spec-api";
2
2
 
3
3
  export const Scenarios: Record<string, ScenarioMockApi> = {};
4
4
 
@@ -6,9 +6,9 @@ Scenarios.Parameters_Spread_Model_spreadAsRequestBody = passOnSuccess({
6
6
  uri: `/parameters/spread/model/request-body`,
7
7
  method: "put",
8
8
  request: {
9
- body: {
9
+ body: json({
10
10
  name: "foo",
11
- },
11
+ }),
12
12
  },
13
13
  response: {
14
14
  status: 204,
@@ -20,9 +20,9 @@ Scenarios.Parameters_Spread_Model_spreadCompositeRequestOnlyWithBody = passOnSuc
20
20
  uri: `/parameters/spread/model/composite-request-only-with-body`,
21
21
  method: "put",
22
22
  request: {
23
- body: {
23
+ body: json({
24
24
  name: "foo",
25
- },
25
+ }),
26
26
  },
27
27
  response: {
28
28
  status: 204,
@@ -48,9 +48,9 @@ Scenarios.Parameters_Spread_Model_spreadCompositeRequest = passOnSuccess({
48
48
  uri: `/parameters/spread/model/composite-request/foo`,
49
49
  method: "put",
50
50
  request: {
51
- body: {
51
+ body: json({
52
52
  name: "foo",
53
- },
53
+ }),
54
54
  headers: {
55
55
  "test-header": "bar",
56
56
  },
@@ -65,9 +65,9 @@ Scenarios.Parameters_Spread_Model_spreadCompositeRequestMix = passOnSuccess({
65
65
  uri: `/parameters/spread/model/composite-request-mix/foo`,
66
66
  method: "put",
67
67
  request: {
68
- body: {
68
+ body: json({
69
69
  prop: "foo",
70
- },
70
+ }),
71
71
  headers: {
72
72
  "test-header": "bar",
73
73
  },
@@ -82,9 +82,9 @@ Scenarios.Parameters_Spread_Alias_spreadAsRequestBody = passOnSuccess({
82
82
  uri: `/parameters/spread/alias/request-body`,
83
83
  method: "put",
84
84
  request: {
85
- body: {
85
+ body: json({
86
86
  name: "foo",
87
- },
87
+ }),
88
88
  },
89
89
  response: {
90
90
  status: 204,
@@ -96,9 +96,9 @@ Scenarios.Parameters_Spread_Alias_spreadAsRequestParameter = passOnSuccess({
96
96
  uri: `/parameters/spread/alias/request-parameter/1`,
97
97
  method: "put",
98
98
  request: {
99
- body: {
99
+ body: json({
100
100
  name: "foo",
101
- },
101
+ }),
102
102
  headers: {
103
103
  "x-ms-test-header": "bar",
104
104
  },
@@ -113,12 +113,12 @@ Scenarios.Parameters_Spread_Alias_spreadWithMultipleParameters = passOnSuccess({
113
113
  uri: `/parameters/spread/alias/multiple-parameters/1`,
114
114
  method: "put",
115
115
  request: {
116
- body: {
116
+ body: json({
117
117
  requiredString: "foo",
118
118
  optionalInt: 1,
119
119
  requiredIntList: [1, 2],
120
120
  optionalStringList: ["foo", "bar"],
121
- },
121
+ }),
122
122
  headers: {
123
123
  "x-ms-test-header": "bar",
124
124
  },
@@ -133,9 +133,9 @@ Scenarios.Parameters_Spread_Alias_spreadParameterWithInnerModel = passOnSuccess(
133
133
  uri: `/parameters/spread/alias/inner-model-parameter/1`,
134
134
  method: "post",
135
135
  request: {
136
- body: {
136
+ body: json({
137
137
  name: "foo",
138
- },
138
+ }),
139
139
  headers: {
140
140
  "x-ms-test-header": "bar",
141
141
  },
@@ -150,10 +150,10 @@ Scenarios.Parameters_Spread_Alias_spreadParameterWithInnerAlias = passOnSuccess(
150
150
  uri: `/parameters/spread/alias/inner-alias-parameter/1`,
151
151
  method: "post",
152
152
  request: {
153
- body: {
153
+ body: json({
154
154
  name: "foo",
155
155
  age: 1,
156
- },
156
+ }),
157
157
  headers: {
158
158
  "x-ms-test-header": "bar",
159
159
  },
@@ -58,7 +58,7 @@ model InnerModel {
58
58
  }
59
59
  ],
60
60
  "intValue": 1,
61
- "floatValue": 1.1,
61
+ "floatValue": 1.25,
62
62
  "innerModel": {
63
63
  "name": "InnerMadge",
64
64
  "description": "innerDesc"
@@ -85,7 +85,7 @@ model InnerModel {
85
85
  }
86
86
  ],
87
87
  "intValue": 1,
88
- "floatValue": 1.1,
88
+ "floatValue": 1.25,
89
89
  "innerModel": {
90
90
  "name": "InnerMadge",
91
91
  "description": "innerDesc"
@@ -18,7 +18,7 @@ export const expectedCreateBody = {
18
18
  },
19
19
  ],
20
20
  intValue: 1,
21
- floatValue: 1.1,
21
+ floatValue: 1.25,
22
22
  innerModel: {
23
23
  name: "InnerMadge",
24
24
  description: "innerDesc",
@@ -45,7 +45,7 @@ Scenarios.Payload_JsonMergePatch_createResource = passOnSuccess({
45
45
  uri: "/json-merge-patch/create/resource",
46
46
  method: "put",
47
47
  request: {
48
- body: expectedCreateBody,
48
+ body: json(expectedCreateBody),
49
49
  },
50
50
  response: {
51
51
  status: 200,
@@ -58,7 +58,7 @@ Scenarios.Payload_JsonMergePatch_updateResource = passOnSuccess({
58
58
  uri: "/json-merge-patch/update/resource",
59
59
  method: "patch",
60
60
  request: {
61
- body: expectedUpdateBody,
61
+ body: json(expectedUpdateBody),
62
62
  },
63
63
  response: {
64
64
  status: 200,
@@ -78,7 +78,7 @@ Scenarios.Payload_JsonMergePatch_updateOptionalResource = passOnSuccess({
78
78
  uri: "/json-merge-patch/update/resource/optional",
79
79
  method: "patch",
80
80
  request: {
81
- body: expectedUpdateBody,
81
+ body: json(expectedUpdateBody),
82
82
  },
83
83
  response: {
84
84
  status: 200,
@@ -6,7 +6,7 @@ Scenarios.Payload_MediaType_StringBody_sendAsText = passOnSuccess({
6
6
  uri: "/payload/media-type/string-body/sendAsText",
7
7
  method: "post",
8
8
  request: {
9
- body: "{cat}",
9
+ body: json("{cat}"),
10
10
  headers: {
11
11
  "Content-Type": "text/plain",
12
12
  },
@@ -36,7 +36,7 @@ Scenarios.Payload_MediaType_StringBody_sendAsJson = passOnSuccess({
36
36
  uri: "/payload/media-type/string-body/sendAsJson",
37
37
  method: "post",
38
38
  request: {
39
- body: "foo",
39
+ body: json("foo"),
40
40
  headers: {
41
41
  "Content-Type": "application/json",
42
42
  },
@@ -9,8 +9,8 @@ using Spector;
9
9
  namespace Payload.MultiPart;
10
10
 
11
11
  model MultiPartRequest {
12
- id: string;
13
- profileImage: bytes;
12
+ id: HttpPart<string>;
13
+ profileImage: HttpPart<bytes>;
14
14
  }
15
15
 
16
16
  model Address {
@@ -52,25 +52,25 @@ model ComplexHttpPartsModelRequest {
52
52
  }
53
53
 
54
54
  model ComplexPartsRequest {
55
- id: string;
56
- address: Address;
57
- profileImage: bytes;
58
- pictures: bytes[];
55
+ id: HttpPart<string>;
56
+ address: HttpPart<Address>;
57
+ profileImage: HttpPart<bytes>;
58
+ pictures: HttpPart<bytes>[];
59
59
  }
60
60
 
61
61
  model JsonPartRequest {
62
- address: Address;
63
- profileImage: bytes;
62
+ address: HttpPart<Address>;
63
+ profileImage: HttpPart<bytes>;
64
64
  }
65
65
 
66
66
  model BinaryArrayPartsRequest {
67
- id: string;
68
- pictures: bytes[];
67
+ id: HttpPart<string>;
68
+ pictures: HttpPart<bytes>[];
69
69
  }
70
70
 
71
71
  model MultiBinaryPartsRequest {
72
- profileImage: bytes;
73
- picture?: bytes;
72
+ profileImage: HttpPart<bytes>;
73
+ picture?: HttpPart<bytes>;
74
74
  }
75
75
 
76
76
  @route("/form-data")
@@ -79,9 +79,9 @@ namespace FormData {
79
79
  @scenarioDoc("""
80
80
  Expect request (
81
81
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.4, content-type of file part shall be labeled with
82
- appropriate media type, cadl-ranch will check it; content-type of other parts is optional, cadl-ranch will ignore it.
82
+ appropriate media type, server will check it; content-type of other parts is optional, server will ignore it.
83
83
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.2, filename of file part SHOULD be supplied.
84
- If there are duplicated filename in same fieldName, cadl-ranch can't parse them all.
84
+ If there are duplicated filename in same fieldName, server can't parse them all.
85
85
  ):
86
86
  ```
87
87
  POST /upload HTTP/1.1
@@ -106,16 +106,16 @@ namespace FormData {
106
106
  @route("/mixed-parts")
107
107
  op basic(
108
108
  @header contentType: "multipart/form-data",
109
- @body body: MultiPartRequest,
109
+ @multipartBody body: MultiPartRequest,
110
110
  ): NoContentResponse;
111
111
 
112
112
  @scenario
113
113
  @scenarioDoc("""
114
114
  Expect request (
115
115
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.4, content-type of file part shall be labeled with
116
- appropriate media type, cadl-ranch will check it; content-type of other parts is optional, cadl-ranch will ignore it.
116
+ appropriate media type, server will check it; content-type of other parts is optional, server will ignore it.
117
117
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.2, filename of file part SHOULD be supplied.
118
- If there are duplicated filename in same fieldName, cadl-ranch can't parse them all.
118
+ If there are duplicated filename in same fieldName, server can't parse them all.
119
119
  ):
120
120
  ```
121
121
  POST /upload HTTP/1.1
@@ -166,16 +166,16 @@ namespace FormData {
166
166
  @route("/complex-parts")
167
167
  op fileArrayAndBasic(
168
168
  @header contentType: "multipart/form-data",
169
- @body body: ComplexPartsRequest,
169
+ @multipartBody body: ComplexPartsRequest,
170
170
  ): NoContentResponse;
171
171
 
172
172
  @scenario
173
173
  @scenarioDoc("""
174
174
  Expect request (
175
175
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.4, content-type of file part shall be labeled with
176
- appropriate media type, cadl-ranch will check it; content-type of other parts is optional, cadl-ranch will ignore it.
176
+ appropriate media type, server will check it; content-type of other parts is optional, server will ignore it.
177
177
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.2, filename of file part SHOULD be supplied.
178
- If there are duplicated filename in same fieldName, cadl-ranch can't parse them all.
178
+ If there are duplicated filename in same fieldName, server can't parse them all.
179
179
  ):
180
180
  ```
181
181
  POST /upload HTTP/1.1
@@ -202,16 +202,16 @@ namespace FormData {
202
202
  @route("/json-part")
203
203
  op jsonPart(
204
204
  @header contentType: "multipart/form-data",
205
- @body body: JsonPartRequest,
205
+ @multipartBody body: JsonPartRequest,
206
206
  ): NoContentResponse;
207
207
 
208
208
  @scenario
209
209
  @scenarioDoc("""
210
210
  Expect request (
211
211
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.4, content-type of file part shall be labeled with
212
- appropriate media type, cadl-ranch will check it; content-type of other parts is optional, cadl-ranch will ignore it.
212
+ appropriate media type, server will check it; content-type of other parts is optional, server will ignore it.
213
213
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.2, filename of file part SHOULD be supplied.
214
- If there are duplicated filename in same fieldName, cadl-ranch can't parse them all.
214
+ If there are duplicated filename in same fieldName, server can't parse them all.
215
215
  ):
216
216
  ```
217
217
  POST /upload HTTP/1.1
@@ -241,16 +241,16 @@ namespace FormData {
241
241
  @route("/binary-array-parts")
242
242
  op binaryArrayParts(
243
243
  @header contentType: "multipart/form-data",
244
- @body body: BinaryArrayPartsRequest,
244
+ @multipartBody body: BinaryArrayPartsRequest,
245
245
  ): NoContentResponse;
246
246
 
247
247
  @scenario
248
248
  @scenarioDoc("""
249
249
  Please send request twice, first time with only profileImage, second time with both profileImage and picture(
250
250
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.4, content-type of file part shall be labeled with
251
- appropriate media type, cadl-ranch will check it; content-type of other parts is optional, cadl-ranch will ignore it.
251
+ appropriate media type, server will check it; content-type of other parts is optional, server will ignore it.
252
252
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.2, filename of file part SHOULD be supplied.
253
- If there are duplicated filename in same fieldName, cadl-ranch can't parse them all.
253
+ If there are duplicated filename in same fieldName, server can't parse them all.
254
254
  ):
255
255
  ```
256
256
  POST /upload HTTP/1.1
@@ -275,7 +275,7 @@ namespace FormData {
275
275
  @route("/multi-binary-parts")
276
276
  op multiBinaryParts(
277
277
  @header contentType: "multipart/form-data",
278
- @body body: MultiBinaryPartsRequest,
278
+ @multipartBody body: MultiBinaryPartsRequest,
279
279
  ): NoContentResponse;
280
280
 
281
281
  @scenario
@@ -304,16 +304,16 @@ namespace FormData {
304
304
  @route("/check-filename-and-content-type")
305
305
  op checkFileNameAndContentType(
306
306
  @header contentType: "multipart/form-data",
307
- @body body: MultiPartRequest,
307
+ @multipartBody body: MultiPartRequest,
308
308
  ): NoContentResponse;
309
309
 
310
310
  @scenario
311
311
  @scenarioDoc("""
312
312
  Expect request (
313
313
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.4, content-type of file part shall be labeled with
314
- appropriate media type, cadl-ranch will check it; content-type of other parts is optional, cadl-ranch will ignore it.
314
+ appropriate media type, server will check it; content-type of other parts is optional, server will ignore it.
315
315
  - according to https://datatracker.ietf.org/doc/html/rfc7578#section-4.2, filename of file part SHOULD be supplied.
316
- If there are duplicated filename in same filedName, cadl-ranch can't parse them all.
316
+ If there are duplicated filename in same filedName, server can't parse them all.
317
317
  ):
318
318
  ```
319
319
  POST /multipart/form-data/anonymous-model HTTP/1.1
@@ -333,7 +333,9 @@ namespace FormData {
333
333
  @route("/anonymous-model")
334
334
  op anonymousModel(
335
335
  @header contentType: "multipart/form-data",
336
- profileImage: MultiPartRequest.profileImage,
336
+ @multipartBody body: {
337
+ profileImage: HttpPart<bytes>;
338
+ },
337
339
  ): NoContentResponse;
338
340
 
339
341
  namespace HttpParts {
@@ -412,7 +414,7 @@ namespace FormData {
412
414
  }
413
415
  @scenario
414
416
  @scenarioDoc("""
415
- For File part, filename will not be checked but it is necessary otherwise cadl-ranch can't parse it;
417
+ For File part, filename will not be checked but it is necessary otherwise server can't parse it;
416
418
  content-type will be checked with value "application/octet-stream". Expect request:
417
419
  ```
418
420
  POST /upload HTTP/1.1