@typespec/http-specs 0.1.0-alpha.34 → 0.1.0-alpha.35-dev.2

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@typespec/http-specs",
3
3
  "displayName": "Http Specs",
4
- "version": "0.1.0-alpha.34",
4
+ "version": "0.1.0-alpha.35-dev.2",
5
5
  "description": "Spec scenarios and mock apis",
6
6
  "main": "dist/index.js",
7
7
  "type": "module",
@@ -22,27 +22,27 @@
22
22
  },
23
23
  "homepage": "https://github.com/microsoft/typespec#readme",
24
24
  "dependencies": {
25
- "deep-equal": "^2.2.0",
26
- "@typespec/spec-api": "^0.1.0-alpha.13",
27
- "@typespec/spector": "^0.1.0-alpha.24"
25
+ "@typespec/spec-api": "^0.1.0-alpha.13 || >= 0.1.0-alpha.14-dev.1",
26
+ "@typespec/spector": "^0.1.0-alpha.24 || >= 0.1.0-dev.1",
27
+ "deep-equal": "^2.2.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/deep-equal": "^1.0.1",
31
31
  "@types/multer": "^2.0.0",
32
32
  "@types/node": "~25.3.0",
33
+ "@typespec/json-schema": "^1.10.0 || >= 1.11.0-dev.0",
34
+ "@typespec/openapi": "^1.10.0 || >= 1.11.0-dev.0",
35
+ "@typespec/openapi3": "^1.10.0 || >= 1.11.0-dev.2",
33
36
  "concurrently": "^9.1.2",
34
37
  "rimraf": "~6.1.3",
35
- "typescript": "~5.9.3",
36
- "@typespec/json-schema": "^1.10.0",
37
- "@typespec/openapi": "^1.10.0",
38
- "@typespec/openapi3": "^1.10.0"
38
+ "typescript": "~5.9.3"
39
39
  },
40
40
  "peerDependencies": {
41
- "@typespec/compiler": "^1.10.0",
42
- "@typespec/http": "^1.10.0",
43
- "@typespec/rest": "^0.80.0",
44
- "@typespec/versioning": "^0.80.0",
45
- "@typespec/xml": "^0.80.0"
41
+ "@typespec/compiler": "^1.10.0 || >= 1.11.0-dev.3",
42
+ "@typespec/http": "^1.10.0 || >= 1.11.0-dev.1",
43
+ "@typespec/rest": "^0.80.0 || >= 0.81.0-dev.0",
44
+ "@typespec/versioning": "^0.80.0 || >= 0.81.0-dev.0",
45
+ "@typespec/xml": "^0.80.0 || >= 0.81.0-dev.0"
46
46
  },
47
47
  "scripts": {
48
48
  "watch": "tsc -p ./tsconfig.build.json --watch",
@@ -58,7 +58,7 @@
58
58
  "upload-coverage": "tsp-spector upload-coverage --generatorName @typespec/http-specs --generatorVersion 0.1.0-alpha.4 --containerName coverages --generatorMode standard --storageAccountName typespec",
59
59
  "validate-mock-apis": "tsp-spector validate-mock-apis ./specs",
60
60
  "check-scenario-coverage": "tsp-spector check-coverage ./specs",
61
- "validate-client-server": "concurrently \"tsp-spector server start ./specs\" \"pnpm knock\"; tsp-spector server stop",
61
+ "validate-client-server": "concurrently \"tsp-spector server start ./specs\" \"pnpm knock\"; code=$?; tsp-spector server stop; exit $code",
62
62
  "build:smoke": "tsp compile smoke/petstore --warn-as-error --no-emit && tsp compile smoke/todoapp --warn-as-error --no-emit",
63
63
  "client": "pnpm knock",
64
64
  "knock": "tsp-spector knock ./specs",
@@ -295,6 +295,11 @@ function createHeaderFloatServerTests(uri: string, value: number) {
295
295
  return passOnSuccess({
296
296
  uri,
297
297
  method: "get",
298
+ request: {
299
+ headers: {
300
+ duration: String(value),
301
+ },
302
+ },
298
303
  response: {
299
304
  status: 204,
300
305
  },
@@ -437,9 +437,11 @@ Scenarios.Payload_MultiPart_FormData_File_uploadFileSpecificContentType = passOn
437
437
  uri: "/multipart/form-data/file/specific-content-type",
438
438
  method: "post",
439
439
  request: {
440
- headers: {
441
- "content-type": "multipart/form-data",
442
- },
440
+ body: multipart({
441
+ files: [
442
+ { fieldname: "file", originalname: "image.png", buffer: pngFile, mimetype: "image/png" },
443
+ ],
444
+ }),
443
445
  },
444
446
  response: {
445
447
  status: 204,
@@ -460,9 +462,11 @@ Scenarios.Payload_MultiPart_FormData_File_uploadFileRequiredFilename = passOnSuc
460
462
  uri: "/multipart/form-data/file/required-filename",
461
463
  method: "post",
462
464
  request: {
463
- headers: {
464
- "content-type": "multipart/form-data",
465
- },
465
+ body: multipart({
466
+ files: [
467
+ { fieldname: "file", originalname: "image.png", buffer: pngFile, mimetype: "image/png" },
468
+ ],
469
+ }),
466
470
  },
467
471
  response: {
468
472
  status: 204,
@@ -483,9 +487,12 @@ Scenarios.Payload_MultiPart_FormData_File_uploadFileArray = passOnSuccess({
483
487
  uri: "/multipart/form-data/file/file-array",
484
488
  method: "post",
485
489
  request: {
486
- headers: {
487
- "content-type": "multipart/form-data",
488
- },
490
+ body: multipart({
491
+ files: [
492
+ { fieldname: "files", originalname: "image.png", buffer: pngFile, mimetype: "image/png" },
493
+ { fieldname: "files", originalname: "image.png", buffer: pngFile, mimetype: "image/png" },
494
+ ],
495
+ }),
489
496
  },
490
497
  response: {
491
498
  status: 204,
@@ -4,6 +4,7 @@ import {
4
4
  json,
5
5
  MockRequest,
6
6
  passOnSuccess,
7
+ ResolverConfig,
7
8
  ScenarioMockApi,
8
9
  ValidationError,
9
10
  xml,
@@ -553,7 +554,7 @@ Scenarios.Payload_Pageable_XmlPagination_listWithContinuation = passOnSuccess([
553
554
  status: 200,
554
555
  body: xml(XmlContTokenFirstPage),
555
556
  headers: {
556
- "content-type": "application/xml",
557
+ "content-type": "application/xml; charset=utf-8",
557
558
  },
558
559
  },
559
560
  handler: (req: MockRequest) => {
@@ -590,7 +591,7 @@ Scenarios.Payload_Pageable_XmlPagination_listWithContinuation = passOnSuccess([
590
591
  status: 200,
591
592
  body: xml(XmlContTokenSecondPage),
592
593
  headers: {
593
- "content-type": "application/xml",
594
+ "content-type": "application/xml; charset=utf-8",
594
595
  },
595
596
  },
596
597
  handler: (req: MockRequest) => {
@@ -659,9 +660,15 @@ Scenarios.Payload_Pageable_XmlPagination_listWithNextLink = passOnSuccess([
659
660
  request: {},
660
661
  response: {
661
662
  status: 200,
662
- body: xml(xmlNextLinkFirstPage("PLACEHOLDER_BASE_URL")),
663
+ body: {
664
+ contentType: "application/xml",
665
+ rawContent: {
666
+ serialize: (config: ResolverConfig) =>
667
+ `<?xml version='1.0' encoding='UTF-8'?>` + xmlNextLinkFirstPage(config.baseUrl),
668
+ },
669
+ },
663
670
  headers: {
664
- "content-type": "application/xml",
671
+ "content-type": "application/xml; charset=utf-8",
665
672
  },
666
673
  },
667
674
  handler: (req: MockRequest) => {
@@ -683,7 +690,7 @@ Scenarios.Payload_Pageable_XmlPagination_listWithNextLink = passOnSuccess([
683
690
  status: 200,
684
691
  body: xml(XmlNextLinkSecondPage),
685
692
  headers: {
686
- "content-type": "application/xml",
693
+ "content-type": "application/xml; charset=utf-8",
687
694
  },
688
695
  },
689
696
  kind: "MockApiDefinition",
@@ -136,6 +136,16 @@ export const modelWithDatetime = `
136
136
  </ModelWithDatetime>
137
137
  `;
138
138
 
139
+ // Some clients serialize UTC datetimes without trailing zero milliseconds. Both
140
+ // "2022-08-26T18:38:00.000Z" and "2022-08-26T18:38:00Z" are valid RFC3339 representations
141
+ // of the same instant; accept either form.
142
+ const modelWithDatetimeNoMs = `
143
+ <ModelWithDatetime>
144
+ <rfc3339>2022-08-26T18:38:00Z</rfc3339>
145
+ <rfc7231>Fri, 26 Aug 2022 14:38:00 GMT</rfc7231>
146
+ </ModelWithDatetime>
147
+ `;
148
+
139
149
  function createServerTests(uri: string, data?: any) {
140
150
  return {
141
151
  get: passOnSuccess({
@@ -251,12 +261,44 @@ const Payload_Xml_ModelWithEnum = createServerTests("/payload/xml/modelWithEnum"
251
261
  Scenarios.Payload_Xml_ModelWithEnumValue_get = Payload_Xml_ModelWithEnum.get;
252
262
  Scenarios.Payload_Xml_ModelWithEnumValue_put = Payload_Xml_ModelWithEnum.put;
253
263
 
254
- const Payload_Xml_ModelWithDatetime = createServerTests(
255
- "/payload/xml/modelWithDatetime",
256
- modelWithDatetime,
257
- );
258
- Scenarios.Payload_Xml_ModelWithDatetimeValue_get = Payload_Xml_ModelWithDatetime.get;
259
- Scenarios.Payload_Xml_ModelWithDatetimeValue_put = Payload_Xml_ModelWithDatetime.put;
264
+ Scenarios.Payload_Xml_ModelWithDatetimeValue_get = passOnSuccess({
265
+ uri: "/payload/xml/modelWithDatetime",
266
+ method: "get",
267
+ request: {},
268
+ response: {
269
+ status: 200,
270
+ body: xml(modelWithDatetime),
271
+ },
272
+ kind: "MockApiDefinition",
273
+ });
274
+
275
+ Scenarios.Payload_Xml_ModelWithDatetimeValue_put = passOnSuccess({
276
+ uri: "/payload/xml/modelWithDatetime",
277
+ method: "put",
278
+ request: {
279
+ body: xml(modelWithDatetime),
280
+ },
281
+ handler: (req: MockRequest) => {
282
+ req.expect.containsHeader("content-type", "application/xml");
283
+ // Accept both "2022-08-26T18:38:00.000Z" and "2022-08-26T18:38:00Z" as equivalent UTC datetimes.
284
+ let firstError: unknown;
285
+ try {
286
+ req.expect.xmlBodyEquals(modelWithDatetime);
287
+ } catch (e) {
288
+ firstError = e;
289
+ }
290
+ if (firstError !== undefined) {
291
+ req.expect.xmlBodyEquals(modelWithDatetimeNoMs);
292
+ }
293
+ return {
294
+ status: 204,
295
+ };
296
+ },
297
+ response: {
298
+ status: 204,
299
+ },
300
+ kind: "MockApiDefinition",
301
+ });
260
302
 
261
303
  export const xmlError = `
262
304
  <XmlErrorBody>