@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
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  MockRequest,
3
+ multipart,
3
4
  passOnSuccess,
4
5
  ScenarioMockApi,
5
6
  ValidationError,
@@ -29,7 +30,7 @@ function checkFile(
29
30
  fileName: string | undefined = undefined,
30
31
  mustCheckContentType: boolean = true,
31
32
  ) {
32
- // cadl-ranch depends on multer, which sets the mimetype to "text/plain" if this part has no content-type header
33
+ // server depends on multer, which sets the mimetype to "text/plain" if this part has no content-type header
33
34
  if (mustCheckContentType || file.mimetype !== "text/plain") {
34
35
  req.expect.deepEqual(file.mimetype, contentType);
35
36
  }
@@ -185,11 +186,7 @@ Scenarios.Payload_MultiPart_FormData_basic = passOnSuccess({
185
186
  uri: "/multipart/form-data/mixed-parts",
186
187
  method: "post",
187
188
  request: {
188
- headers: {
189
- "Content-Type": "multipart/form-data",
190
- },
191
- body: { id: 123 },
192
- files: [files[0]],
189
+ body: multipart({ parts: { id: 123 }, files: [files[0]] }),
193
190
  },
194
191
  response: { status: 204 },
195
192
  handler: (req: MockRequest) => createHandler(req, [checkId, checkProfileImage]),
@@ -199,11 +196,10 @@ Scenarios.Payload_MultiPart_FormData_fileArrayAndBasic = passOnSuccess({
199
196
  uri: "/multipart/form-data/complex-parts",
200
197
  method: "post",
201
198
  request: {
202
- headers: {
203
- "Content-Type": "multipart/form-data",
204
- },
205
- body: { id: 123, address: { city: "X" } },
206
- files: [files[0], files[1], files[1]],
199
+ body: multipart({
200
+ parts: { id: 123, address: { city: "X" } },
201
+ files: [files[0], files[1], files[1]],
202
+ }),
207
203
  },
208
204
  response: { status: 204 },
209
205
  handler: (req: MockRequest) => createHandler(req, [checkId, checkAddress, checkAllFiles]),
@@ -213,11 +209,7 @@ Scenarios.Payload_MultiPart_FormData_jsonPart = passOnSuccess({
213
209
  uri: "/multipart/form-data/json-part",
214
210
  method: "post",
215
211
  request: {
216
- headers: {
217
- "Content-Type": "multipart/form-data",
218
- },
219
- body: { address: { city: "X" } },
220
- files: [files[0]],
212
+ body: multipart({ parts: { address: { city: "X" } }, files: [files[0]] }),
221
213
  },
222
214
  response: { status: 204 },
223
215
  handler: (req: MockRequest) => createHandler(req, [checkAddress, checkProfileImage]),
@@ -227,11 +219,7 @@ Scenarios.Payload_MultiPart_FormData_binaryArrayParts = passOnSuccess({
227
219
  uri: "/multipart/form-data/binary-array-parts",
228
220
  method: "post",
229
221
  request: {
230
- headers: {
231
- "Content-Type": "multipart/form-data",
232
- },
233
- body: { id: 123 },
234
- files: [files[1], files[1]],
222
+ body: multipart({ parts: { id: 123 }, files: [files[1], files[1]] }),
235
223
  },
236
224
  response: { status: 204 },
237
225
  handler: (req: MockRequest) => createHandler(req, [checkId, checkPictures]),
@@ -245,10 +233,9 @@ Scenarios.Payload_MultiPart_FormData_multiBinaryParts = withServiceKeys([
245
233
  uri: "/multipart/form-data/multi-binary-parts",
246
234
  method: "post",
247
235
  request: {
248
- headers: {
249
- "Content-Type": "multipart/form-data",
250
- },
251
- files: [files[0]],
236
+ body: multipart({
237
+ files: [files[0]],
238
+ }),
252
239
  },
253
240
  response: { status: 204 },
254
241
  handler: createMultiBinaryPartsHandler,
@@ -258,10 +245,9 @@ Scenarios.Payload_MultiPart_FormData_multiBinaryParts = withServiceKeys([
258
245
  uri: "/multipart/form-data/multi-binary-parts",
259
246
  method: "post",
260
247
  request: {
261
- headers: {
262
- "Content-Type": "multipart/form-data",
263
- },
264
- files: [files[0], { ...files[1], fieldname: "picture" }],
248
+ body: multipart({
249
+ files: [files[0], { ...files[1], fieldname: "picture" }],
250
+ }),
265
251
  },
266
252
  response: { status: 204 },
267
253
  handler: createMultiBinaryPartsHandler,
@@ -272,11 +258,10 @@ Scenarios.Payload_MultiPart_FormData_checkFileNameAndContentType = passOnSuccess
272
258
  uri: "/multipart/form-data/check-filename-and-content-type",
273
259
  method: "post",
274
260
  request: {
275
- headers: {
276
- "Content-Type": "multipart/form-data",
277
- },
278
- body: { id: 123 },
279
- files: [{ ...files[0], mimetype: "image/jpg", originalname: "hello.jpg" }],
261
+ body: multipart({
262
+ parts: { id: 123 },
263
+ files: [{ ...files[0], mimetype: "image/jpg", originalname: "hello.jpg" }],
264
+ }),
280
265
  },
281
266
  response: { status: 204 },
282
267
  handler: (req: MockRequest) => createHandler(req, [checkId, checkFileNameAndContentType]),
@@ -286,10 +271,9 @@ Scenarios.Payload_MultiPart_FormData_anonymousModel = passOnSuccess({
286
271
  uri: "/multipart/form-data/anonymous-model",
287
272
  method: "post",
288
273
  request: {
289
- headers: {
290
- "Content-Type": "multipart/form-data",
291
- },
292
- files: [files[0]],
274
+ body: multipart({
275
+ files: [files[0]],
276
+ }),
293
277
  },
294
278
  response: { status: 204 },
295
279
  handler: (req: MockRequest) => createHandler(req, [checkProfileImage]),
@@ -299,10 +283,9 @@ Scenarios.Payload_MultiPart_FormData_HttpParts_ContentType_imageJpegContentType
299
283
  uri: "/multipart/form-data/check-filename-and-specific-content-type-with-httppart",
300
284
  method: "post",
301
285
  request: {
302
- headers: {
303
- "Content-Type": "multipart/form-data",
304
- },
305
- files: [{ ...files[0], mimetype: "image/jpg", originalname: "hello.jpg" }],
286
+ body: multipart({
287
+ files: [{ ...files[0], mimetype: "image/jpg", originalname: "hello.jpg" }],
288
+ }),
306
289
  },
307
290
  response: { status: 204 },
308
291
  handler: (req: MockRequest) => createHandler(req, [checkFileNameAndContentType]),
@@ -312,10 +295,9 @@ Scenarios.Payload_MultiPart_FormData_HttpParts_ContentType_requiredContentType =
312
295
  uri: "/multipart/form-data/check-filename-and-required-content-type-with-httppart",
313
296
  method: "post",
314
297
  request: {
315
- headers: {
316
- "Content-Type": "multipart/form-data",
317
- },
318
- files: [files[0]],
298
+ body: multipart({
299
+ files: [files[0]],
300
+ }),
319
301
  },
320
302
  response: { status: 204 },
321
303
  handler: (req: MockRequest) => createHandler(req, [checkProfileImage]),
@@ -325,10 +307,9 @@ Scenarios.Payload_MultiPart_FormData_HttpParts_ContentType_optionalContentType =
325
307
  uri: "/multipart/form-data/file-with-http-part-optional-content-type",
326
308
  method: "post",
327
309
  request: {
328
- headers: {
329
- "Content-Type": "multipart/form-data",
330
- },
331
- files: [files[0]],
310
+ body: multipart({
311
+ files: [files[0]],
312
+ }),
332
313
  },
333
314
  response: { status: 204 },
334
315
  handler: (req: MockRequest) => createHandler(req, [checkOptionalContentType]),
@@ -338,11 +319,14 @@ Scenarios.Payload_MultiPart_FormData_HttpParts_jsonArrayAndFileArray = passOnSuc
338
319
  uri: "/multipart/form-data/complex-parts-with-httppart",
339
320
  method: "post",
340
321
  request: {
341
- headers: {
342
- "Content-Type": "multipart/form-data",
343
- },
344
- body: { id: 123, address: { city: "X" }, previousAddresses: [{ city: "Y" }, { city: "Z" }] },
345
- files: [files[0], files[1], files[1]],
322
+ body: multipart({
323
+ parts: {
324
+ id: 123,
325
+ address: { city: "X" },
326
+ previousAddresses: [{ city: "Y" }, { city: "Z" }],
327
+ },
328
+ files: [files[0], files[1], files[1]],
329
+ }),
346
330
  },
347
331
  response: { status: 204 },
348
332
  handler: (req: MockRequest) =>
@@ -353,10 +337,9 @@ Scenarios.Payload_MultiPart_FormData_HttpParts_NonString_float = passOnSuccess({
353
337
  uri: "/multipart/form-data/non-string-float",
354
338
  method: "post",
355
339
  request: {
356
- body: { temperature: 0.5 },
357
- headers: {
358
- "Content-Type": "multipart/form-data",
359
- },
340
+ body: multipart({
341
+ parts: { temperature: 0.5 },
342
+ }),
360
343
  },
361
344
  response: { status: 204 },
362
345
  handler: (req: MockRequest) => createHandler(req, [checkFloat]),
@@ -15,6 +15,11 @@ model Pet {
15
15
  name: string;
16
16
  }
17
17
 
18
+ alias HeaderAndQuery = {
19
+ @header foo?: string;
20
+ @query bar?: string;
21
+ };
22
+
18
23
  @route("/server-driven-pagination")
19
24
  namespace ServerDrivenPagination {
20
25
  @scenario
@@ -30,9 +35,7 @@ namespace ServerDrivenPagination {
30
35
  { "id": "1", "name": "dog" },
31
36
  { "id": "2", "name": "cat" }
32
37
  ],
33
- "links": {
34
- "next": "http://[host]:[port]/payload/pageable/server-driven-pagination/link/nextPage"
35
- }
38
+ "next": "http://[host]:[port]/payload/pageable/server-driven-pagination/link/nextPage"
36
39
  }
37
40
  ```
38
41
  2. Next page request:
@@ -47,15 +50,467 @@ namespace ServerDrivenPagination {
47
50
  ```
48
51
  """)
49
52
  @route("/link")
53
+ @list
50
54
  op link(): {
51
55
  @pageItems
52
56
  pets: Pet[];
53
57
 
54
- links: {
58
+ @nextLink next?: url;
59
+ };
60
+
61
+ @scenario
62
+ @scenarioDoc("""
63
+ Test case for using link as pagination with string nextLink.
64
+
65
+ Two requests need to be tested.
66
+ 1. Initial request:
67
+ Expected route: /payload/pageable/server-driven-pagination/link-string
68
+ Expected response body:
69
+ ```json
70
+ { "pets": [
71
+ { "id": "1", "name": "dog" },
72
+ { "id": "2", "name": "cat" }
73
+ ],
74
+ "next": "http://[host]:[port]/payload/pageable/server-driven-pagination/link-string/nextPage"
75
+ }
76
+ ```
77
+ 2. Next page request:
78
+ Expected route: /payload/pageable/server-driven-pagination/link-string/nextPage
79
+ Expected response body:
80
+ ```json
81
+ { "pets": [
82
+ { "id": "3", "name": "bird" },
83
+ { "id": "4", "name": "fish" }
84
+ ]
85
+ }
86
+ ```
87
+ """)
88
+ @route("/link-string")
89
+ @list
90
+ op linkString(): {
91
+ @pageItems
92
+ pets: Pet[];
93
+
94
+ @nextLink next?: string;
95
+ };
96
+
97
+ @scenario
98
+ @scenarioDoc("""
99
+ Test case for using link as pagination with nested structure.
100
+
101
+ Two requests need to be tested.
102
+ 1. Initial request:
103
+ Expected route: /payload/pageable/server-driven-pagination/nested-link
104
+ Expected response body:
105
+ ```json
106
+ { "nestedItems": {
107
+ "pets": [
108
+ { "id": "1", "name": "dog" },
109
+ { "id": "2", "name": "cat" }
110
+ ]
111
+ },
112
+ "nestedNext": {
113
+ "next": "http://[host]:[port]/payload/pageable/server-driven-pagination/nested-link/nextPage"
114
+ }
115
+ }
116
+ ```
117
+ 2. Next page request:
118
+ Expected route: /payload/pageable/server-driven-pagination/nested-link/nextPage
119
+ Expected response body:
120
+ ```json
121
+ { "nestedItems": {
122
+ "pets": [
123
+ { "id": "3", "name": "bird" },
124
+ { "id": "4", "name": "fish" }
125
+ ]
126
+ }
127
+ }
128
+ ```
129
+ """)
130
+ @route("/nested-link")
131
+ @list
132
+ op nestedLink(): {
133
+ nestedItems: {
134
+ @pageItems
135
+ pets: Pet[];
136
+ };
137
+ nestedNext: {
55
138
  @nextLink next?: url;
56
- @prevLink prev?: url;
57
- @firstLink first?: url;
58
- @lastLink last?: url;
59
139
  };
60
140
  };
141
+
142
+ @route("/continuationtoken")
143
+ namespace ContinuationToken {
144
+ @scenario
145
+ @scenarioDoc("""
146
+ Test case for using continuation token as pagination. Continuation token is passed in the request query and response body.
147
+
148
+ Two requests need to be tested.
149
+
150
+ 1. Initial request:
151
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-query-response-body?bar=bar
152
+
153
+ Expected request header:
154
+ foo=foo
155
+
156
+ Expected response body:
157
+ ```json
158
+ { "pets": [
159
+ { "id": "1", "name": "dog" },
160
+ { "id": "2", "name": "cat" }
161
+ ],
162
+ "nextToken": "page2"
163
+ }
164
+ ```
165
+
166
+ 2. Next page request:
167
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-query-response-body?bar=bar&token=page2
168
+
169
+ Expected request header:
170
+ foo=foo
171
+
172
+ Expected response body:
173
+ ```json
174
+ { "pets": [
175
+ { "id": "3", "name": "bird" },
176
+ { "id": "4", "name": "fish" }
177
+ ]
178
+ }
179
+ ```
180
+ """)
181
+ @route("/request-query-response-body")
182
+ @list
183
+ op requestQueryResponseBody(@continuationToken @query token?: string, ...HeaderAndQuery): {
184
+ @pageItems
185
+ pets: Pet[];
186
+
187
+ @continuationToken nextToken?: string;
188
+ };
189
+
190
+ @scenario
191
+ @scenarioDoc("""
192
+ Test case for using continuation token as pagination. Continuation token is passed in the request header and response body.
193
+
194
+ Two requests need to be tested.
195
+
196
+ 1. Initial request:
197
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-header-response-body?bar=bar
198
+
199
+ Expected request header:
200
+ foo=foo
201
+
202
+ Expected response body:
203
+ ```json
204
+ { "pets": [
205
+ { "id": "1", "name": "dog" },
206
+ { "id": "2", "name": "cat" }
207
+ ],
208
+ "nextToken": "page2"
209
+ }
210
+ ```
211
+
212
+ 2. Next page request:
213
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-header-response-body?bar=bar
214
+
215
+ Expected request header:
216
+ token=page2
217
+ foo=foo
218
+
219
+ Expected response body:
220
+ ```json
221
+ { "pets": [
222
+ { "id": "3", "name": "bird" },
223
+ { "id": "4", "name": "fish" }
224
+ ]
225
+ }
226
+ ```
227
+ """)
228
+ @route("/request-header-response-body")
229
+ @list
230
+ op requestHeaderResponseBody(@continuationToken @header token?: string, ...HeaderAndQuery): {
231
+ @pageItems
232
+ pets: Pet[];
233
+
234
+ @continuationToken nextToken?: string;
235
+ };
236
+
237
+ @scenario
238
+ @scenarioDoc("""
239
+ Test case for using continuation token as pagination. Continuation token is passed in the request query and response header.
240
+
241
+ Two requests need to be tested.
242
+
243
+ 1. Initial request:
244
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-query-response-header?bar=bar
245
+
246
+ Expected request header:
247
+ foo=foo
248
+
249
+ Expected response body:
250
+ ```json
251
+ { "pets": [
252
+ { "id": "1", "name": "dog" },
253
+ { "id": "2", "name": "cat" }
254
+ ]
255
+ }
256
+ ```
257
+
258
+ Expected response header:
259
+ next-token=page2
260
+
261
+ 2. Next page request:
262
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-query-response-header?bar=bar&token=page2
263
+
264
+ Expected request header:
265
+ foo=foo
266
+
267
+ Expected response body:
268
+ ```json
269
+ { "pets": [
270
+ { "id": "3", "name": "bird" },
271
+ { "id": "4", "name": "fish" }
272
+ ]
273
+ }
274
+ ```
275
+ """)
276
+ @route("/request-query-response-header")
277
+ @list
278
+ op requestQueryResponseHeader(@continuationToken @query token?: string, ...HeaderAndQuery): {
279
+ @pageItems
280
+ pets: Pet[];
281
+
282
+ @continuationToken @header nextToken?: string;
283
+ };
284
+
285
+ @scenario
286
+ @scenarioDoc("""
287
+ Test case for using continuation token as pagination. Continuation token is passed in the request header and response header.
288
+
289
+ Two requests need to be tested.
290
+ 1. Initial request:
291
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-header-response-header?bar=bar
292
+
293
+ Expected request header:
294
+ foo=foo
295
+
296
+ Expected response body:
297
+ ```json
298
+ { "pets": [
299
+ { "id": "1", "name": "dog" },
300
+ { "id": "2", "name": "cat" }
301
+ ]
302
+ }
303
+ ```
304
+
305
+ Expected response header:
306
+ next-token=page2
307
+
308
+ 2. Next page request:
309
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-header-response-header?bar=bar
310
+
311
+ Expected request header:
312
+ token=page2
313
+ foo=foo
314
+
315
+ Expected response body:
316
+ ```json
317
+ { "pets": [
318
+ { "id": "3", "name": "bird" },
319
+ { "id": "4", "name": "fish" }
320
+ ]
321
+ }
322
+ ```
323
+ """)
324
+ @route("/request-header-response-header")
325
+ @list
326
+ op requestHeaderResponseHeader(@continuationToken @header token?: string, ...HeaderAndQuery): {
327
+ @pageItems
328
+ pets: Pet[];
329
+
330
+ @continuationToken @header nextToken?: string;
331
+ };
332
+
333
+ @scenario
334
+ @scenarioDoc("""
335
+ Test case for using continuation token as pagination with nested response structure. Continuation token is passed in the request query and nested within response body.
336
+
337
+ Two requests need to be tested.
338
+
339
+ 1. Initial request:
340
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-query-nested-response-body?bar=bar
341
+
342
+ Expected request header:
343
+ foo=foo
344
+
345
+ Expected response body:
346
+ ```json
347
+ { "nestedItems": {
348
+ "pets": [
349
+ { "id": "1", "name": "dog" },
350
+ { "id": "2", "name": "cat" }
351
+ ]
352
+ },
353
+ "nestedNext": {
354
+ "nextToken": "page2"
355
+ }
356
+ }
357
+ ```
358
+
359
+ 2. Next page request:
360
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-query-nested-response-body?bar=bar&token=page2
361
+
362
+ Expected request header:
363
+ foo=foo
364
+
365
+ Expected response body:
366
+ ```json
367
+ { "nestedItems": {
368
+ "pets": [
369
+ { "id": "3", "name": "bird" },
370
+ { "id": "4", "name": "fish" }
371
+ ]
372
+ }
373
+ }
374
+ ```
375
+ """)
376
+ @route("/request-query-nested-response-body")
377
+ @list
378
+ op requestQueryNestedResponseBody(
379
+ @continuationToken @query token?: string,
380
+ ...HeaderAndQuery,
381
+ ): {
382
+ nestedItems: {
383
+ @pageItems
384
+ pets: Pet[];
385
+ };
386
+ nestedNext?: {
387
+ @continuationToken nextToken?: string;
388
+ };
389
+ };
390
+
391
+ @scenario
392
+ @scenarioDoc("""
393
+ Test case for using continuation token as pagination with nested response structure. Continuation token is passed in the request header and nested within response body.
394
+
395
+ Two requests need to be tested.
396
+
397
+ 1. Initial request:
398
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-header-nested-response-body?bar=bar
399
+
400
+ Expected request header:
401
+ foo=foo
402
+
403
+ Expected response body:
404
+ ```json
405
+ { "nestedItems": {
406
+ "pets": [
407
+ { "id": "1", "name": "dog" },
408
+ { "id": "2", "name": "cat" }
409
+ ]
410
+ },
411
+ "next": {
412
+ "nextToken": "page2"
413
+ }
414
+ }
415
+ ```
416
+
417
+ 2. Next page request:
418
+ Expected route: /payload/pageable/server-driven-pagination/continuationtoken/request-header-nested-response-body?bar=bar
419
+
420
+ Expected request header:
421
+ token=page2
422
+ foo=foo
423
+
424
+ Expected response body:
425
+ ```json
426
+ { "nestedItems": {
427
+ "pets": [
428
+ { "id": "3", "name": "bird" },
429
+ { "id": "4", "name": "fish" }
430
+ ]
431
+ }
432
+ }
433
+ ```
434
+ """)
435
+ @route("/request-header-nested-response-body")
436
+ @list
437
+ op requestHeaderNestedResponseBody(
438
+ @continuationToken @header token?: string,
439
+ ...HeaderAndQuery,
440
+ ): {
441
+ nestedItems: {
442
+ @pageItems
443
+ pets: Pet[];
444
+ };
445
+ nestedNext?: {
446
+ @continuationToken nextToken?: string;
447
+ };
448
+ };
449
+ }
450
+ }
451
+
452
+ @route("/pagesize")
453
+ namespace PageSize {
454
+ @scenario
455
+ @scenarioDoc("""
456
+ Test case for simple pagination without nextlink or continuationToken.
457
+
458
+ Single request:
459
+ Expected route: /payload/pageable/pagesize/without-continuation
460
+
461
+ Expected response body:
462
+ ```json
463
+ { "pets": [
464
+ { "id": "1", "name": "dog" },
465
+ { "id": "2", "name": "cat" },
466
+ { "id": "3", "name": "bird" },
467
+ { "id": "4", "name": "fish" }
468
+ ]
469
+ }
470
+ ```
471
+ """)
472
+ @route("/without-continuation")
473
+ @list
474
+ op listWithoutContinuation(): {
475
+ @pageItems
476
+ pets: Pet[];
477
+ };
478
+
479
+ @scenario
480
+ @scenarioDoc("""
481
+ Test case for pagination with a regular @pageSize parameter.
482
+
483
+ Two requests need to be tested:
484
+ 1. Request with pageSize=2:
485
+ Expected route: /payload/pageable/pagesize/list?pageSize=2
486
+
487
+ Expected response body:
488
+ ```json
489
+ { "pets": [
490
+ { "id": "1", "name": "dog" },
491
+ { "id": "2", "name": "cat" }
492
+ ]
493
+ }
494
+ ```
495
+
496
+ 2. Request with pageSize=4:
497
+ Expected route: /payload/pageable/pagesize/list?pageSize=4
498
+
499
+ Expected response body:
500
+ ```json
501
+ { "pets": [
502
+ { "id": "1", "name": "dog" },
503
+ { "id": "2", "name": "cat" },
504
+ { "id": "3", "name": "bird" },
505
+ { "id": "4", "name": "fish" }
506
+ ]
507
+ }
508
+ ```
509
+ """)
510
+ @route("/list")
511
+ @list
512
+ op listWithPageSize(@pageSize @query pageSize?: int32): {
513
+ @pageItems
514
+ pets: Pet[];
515
+ };
61
516
  }