@typespec/http-specs 0.1.0-alpha.9-dev.5 → 0.1.0-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 (224) hide show
  1. package/CHANGELOG.md +256 -2
  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 +110 -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 +189 -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 +594 -14
  54. package/dist/specs/payload/pageable/mockapi.js.map +1 -1
  55. package/dist/specs/payload/xml/mockapi.d.ts +3 -0
  56. package/dist/specs/payload/xml/mockapi.d.ts.map +1 -1
  57. package/dist/specs/payload/xml/mockapi.js +35 -5
  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 +11200 -0
  134. package/package.json +30 -19
  135. package/smoke/petstore/main.tsp +96 -0
  136. package/smoke/todoapp/main.tsp +293 -0
  137. package/spec-summary.md +1745 -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 +216 -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 +200 -59
  166. package/specs/payload/pageable/main.tsp +601 -0
  167. package/specs/payload/pageable/mockapi.ts +656 -14
  168. package/specs/payload/xml/main.tsp +89 -0
  169. package/specs/payload/xml/mockapi.ts +44 -5
  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 +118 -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
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@typespec/http-specs",
3
- "version": "0.1.0-alpha.9-dev.5",
3
+ "displayName": "Http Specs",
4
+ "version": "0.1.0-dev.0",
4
5
  "description": "Spec scenarios and mock apis",
5
6
  "main": "dist/index.js",
6
7
  "type": "module",
@@ -11,6 +12,9 @@
11
12
  "type": "git",
12
13
  "url": "git+https://github.com/microsoft/typespec.git"
13
14
  },
15
+ "spector": {
16
+ "sourceUrl": "https://github.com/microsoft/typespec/tree/main/packages/http-specs/specs/{scenarioPath}"
17
+ },
14
18
  "author": "Microsoft",
15
19
  "license": "MIT",
16
20
  "bugs": {
@@ -18,39 +22,46 @@
18
22
  },
19
23
  "homepage": "https://github.com/microsoft/typespec#readme",
20
24
  "dependencies": {
21
- "@typespec/spec-api": "~0.1.0-alpha.0 || >=0.1.0-alpha.1-dev <0.1.0-alpha.1",
22
- "@typespec/spector": "~0.1.0-alpha.6 || >=0.1.0-alpha.7-dev <0.1.0-alpha.7"
25
+ "@typespec/spec-api": "^0.1.0-alpha.13 || >= 0.1.0-dev.0",
26
+ "@typespec/spector": "^0.1.0-alpha.24 || >= 0.1.0-dev.0",
27
+ "deep-equal": "^2.2.0"
23
28
  },
24
29
  "devDependencies": {
25
- "@types/multer": "^1.4.10",
26
- "@types/node": "~22.10.10",
27
- "@typespec/openapi": "~0.64.0 || >=0.65.0-dev <0.65.0",
28
- "@typespec/openapi3": "~0.64.0 || >=0.65.0-dev <0.65.0",
30
+ "@types/deep-equal": "^1.0.1",
31
+ "@types/multer": "^2.0.0",
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.0",
29
36
  "concurrently": "^9.1.2",
30
- "rimraf": "~6.0.1",
31
- "typescript": "~5.7.3"
37
+ "rimraf": "~6.1.3",
38
+ "typescript": "~5.9.3"
32
39
  },
33
40
  "peerDependencies": {
34
- "@typespec/compiler": "~0.64.0 || >=0.65.0-dev <0.65.0",
35
- "@typespec/http": "~0.64.0 || >=0.65.0-dev <0.65.0",
36
- "@typespec/rest": "~0.64.0 || >=0.65.0-dev <0.65.0",
37
- "@typespec/versioning": "~0.64.0 || >=0.65.0-dev <0.65.0",
38
- "@typespec/xml": "~0.64.0 || >=0.65.0-dev <0.65.0"
41
+ "@typespec/compiler": "^1.10.0 || >= 1.11.0-dev.0",
42
+ "@typespec/http": "^1.10.0 || >= 1.11.0-dev.0",
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"
39
46
  },
40
47
  "scripts": {
41
48
  "watch": "tsc -p ./tsconfig.build.json --watch",
42
- "build": "tsc -p ./tsconfig.build.json",
49
+ "build": "tsc -p ./tsconfig.build.json && pnpm validate-scenarios && pnpm build:smoke",
43
50
  "clean": "rimraf dist/ temp/",
44
- "test:e2e": "pnpm validate-scenarios && pnpm validate-mock-apis && pnpm validate-client-server",
51
+ "test:e2e": "pnpm validate-mock-apis && pnpm validate-client-server",
52
+ "validate:all": "pnpm build && pnpm regen-docs && pnpm test:e2e",
53
+ "ci": "prettier specs --write && pnpm validate:all",
45
54
  "validate-scenarios": "tsp-spector validate-scenarios ./specs",
46
55
  "generate-scenarios-summary": "tsp-spector generate-scenarios-summary ./specs",
47
56
  "regen-docs": "pnpm generate-scenarios-summary",
48
- "upload-manifest": "tsp-spector upload-manifest ./specs --setName @typespec/http-specs --containerName manifests-typespec --storageAccountName typespec",
57
+ "upload-manifest": "tsp-spector upload-manifest ./specs --containerName coverages --storageAccountName typespec --manifestName http-specs",
49
58
  "upload-coverage": "tsp-spector upload-coverage --generatorName @typespec/http-specs --generatorVersion 0.1.0-alpha.4 --containerName coverages --generatorMode standard --storageAccountName typespec",
50
59
  "validate-mock-apis": "tsp-spector validate-mock-apis ./specs",
51
60
  "check-scenario-coverage": "tsp-spector check-coverage ./specs",
52
- "validate-client-server": "concurrently \"tsp-spector server start ./specs\" \"npm run client\" && tsp-spector server stop",
53
- "client": "tsp-spector server-test ./specs",
61
+ "validate-client-server": "concurrently \"tsp-spector server start ./specs\" \"pnpm knock\"; tsp-spector server stop",
62
+ "build:smoke": "tsp compile smoke/petstore --warn-as-error --no-emit && tsp compile smoke/todoapp --warn-as-error --no-emit",
63
+ "client": "pnpm knock",
64
+ "knock": "tsp-spector knock ./specs",
54
65
  "serve": "tsp-spector serve ./specs",
55
66
  "test": "echo \"Error: no test specified\""
56
67
  }
@@ -0,0 +1,96 @@
1
+ import "@typespec/rest";
2
+ import "@typespec/openapi";
3
+
4
+ @service(#{ title: "Pet Store Service" })
5
+ namespace PetStore;
6
+
7
+ using TypeSpec.Http;
8
+ using TypeSpec.Rest;
9
+ using TypeSpec.Rest.Resource;
10
+
11
+ @error
12
+ model PetStoreError {
13
+ code: int32;
14
+ message: string;
15
+ }
16
+
17
+ @resource("pets")
18
+ model Pet {
19
+ @key("petId")
20
+ id: int32;
21
+
22
+ name: string;
23
+ tag?: string;
24
+
25
+ @minValue(0)
26
+ @maxValue(20)
27
+ age: int32;
28
+
29
+ ownerId: int64;
30
+ }
31
+
32
+ @resource("toys")
33
+ @parentResource(Pet)
34
+ model Toy {
35
+ @key("toyId")
36
+ id: int64;
37
+
38
+ petId: int64;
39
+ name: string;
40
+ }
41
+
42
+ @resource("owners")
43
+ model Owner {
44
+ @key("ownerId")
45
+ id: int64;
46
+
47
+ name: string;
48
+ age: int32;
49
+ }
50
+
51
+ @resource("checkups")
52
+ model Checkup {
53
+ @key("checkupId")
54
+ id: int32;
55
+
56
+ vetName: string;
57
+ notes: string;
58
+ }
59
+
60
+ @segment("insurance")
61
+ model Insurance {
62
+ provider: string;
63
+ premium: int32;
64
+ deductible: int32;
65
+ }
66
+
67
+ interface Pets extends ResourceOperations<Pet, PetStoreError> {}
68
+
69
+ interface PetCheckups
70
+ extends ExtensionResourceCreateOrUpdate<Checkup, Pet, PetStoreError>,
71
+ ExtensionResourceList<Checkup, Pet, PetStoreError> {}
72
+
73
+ interface PetInsurance extends SingletonResourceOperations<Insurance, Pet, PetStoreError> {}
74
+
75
+ interface Toys extends ResourceRead<Toy, PetStoreError> {
76
+ @autoRoute
77
+ @listsResource(Toy)
78
+ list(
79
+ ...ParentKeysOf<Toy>,
80
+ @query nameFilter: string,
81
+ ): CollectionWithNextLink<Toy> | PetStoreError;
82
+ }
83
+
84
+ interface ToyInsurance extends SingletonResourceOperations<Insurance, Toy, PetStoreError> {}
85
+
86
+ interface Checkups
87
+ extends ResourceCreateOrUpdate<Checkup, PetStoreError>,
88
+ ResourceList<Checkup, PetStoreError> {}
89
+
90
+ interface Owners extends ResourceOperations<Owner, PetStoreError> {}
91
+
92
+ interface OwnerCheckups
93
+ extends ExtensionResourceCreateOrUpdate<Checkup, Owner, PetStoreError>,
94
+ ExtensionResourceList<Checkup, Owner, PetStoreError> {}
95
+
96
+ interface OwnerInsurance extends SingletonResourceOperations<Insurance, Owner, PetStoreError> {}
@@ -0,0 +1,293 @@
1
+ import "@typespec/http";
2
+ import "@typespec/rest";
3
+ import "@typespec/openapi";
4
+ import "@typespec/json-schema";
5
+ using Http;
6
+ using JsonSchema;
7
+
8
+ @service(#{ title: "Todo App" })
9
+ @useAuth(BearerAuth | ApiKeyAuth<ApiKeyLocation.cookie, "session-id">)
10
+ @jsonSchema
11
+ namespace Todo;
12
+
13
+ @jsonSchema
14
+ model User {
15
+ /** An autogenerated unique id for the user */
16
+ @key
17
+ @visibility(Lifecycle.Read)
18
+ id: safeint;
19
+
20
+ /** The user's username */
21
+ @minLength(2)
22
+ @maxLength(50)
23
+ username: string;
24
+
25
+ /** The user's email address */
26
+ // @format("email") - crashes emitters for now
27
+ email: string;
28
+
29
+ /**
30
+ * The user's password, provided when creating a user
31
+ * but is otherwise not visible (and hashed by the backend)
32
+ */
33
+ @visibility(Lifecycle.Create)
34
+ password: string;
35
+
36
+ /** Whether the user is validated. Never visible to the API. */
37
+ @invisible(Lifecycle) validated: boolean;
38
+ }
39
+
40
+ @jsonSchema
41
+ model TodoItem {
42
+ /** The item's unique id */
43
+ @visibility(Lifecycle.Read) @key id: safeint;
44
+
45
+ /** The item's title */
46
+ @maxLength(255)
47
+ title: string;
48
+
49
+ /** User that created the todo */
50
+ @visibility(Lifecycle.Read) createdBy: User.id;
51
+
52
+ /** User that the todo is assigned to */
53
+ assignedTo?: User.id;
54
+
55
+ /** A longer description of the todo item in markdown format */
56
+ description?: string;
57
+
58
+ /** The status of the todo item */
59
+ status: "NotStarted" | "InProgress" | "Completed";
60
+
61
+ /** When the todo item was created. */
62
+ @visibility(Lifecycle.Read) createdAt: utcDateTime;
63
+
64
+ /** When the todo item was last updated */
65
+ @visibility(Lifecycle.Read) updatedAt: utcDateTime;
66
+
67
+ /** When the todo item was marked as completed */
68
+ @visibility(Lifecycle.Read) completedAt?: utcDateTime;
69
+
70
+ // Want the read form to be normalized to TodoLabelRecord[], but can't
71
+ // https://github.com/microsoft/typespec/issues/2926
72
+ labels?: TodoLabels;
73
+
74
+ // hack to get a different schema for create
75
+ // (fastify glue doesn't support readonly)
76
+ @visibility(Lifecycle.Create) _dummy?: string;
77
+ }
78
+
79
+ model ToDoItemMultipartRequest {
80
+ item: HttpPart<TodoItem>;
81
+ attachments?: HttpPart<File>[];
82
+ }
83
+
84
+ model FileAttachmentMultipartRequest {
85
+ contents: HttpPart<File>;
86
+ }
87
+
88
+ @jsonSchema
89
+ union TodoLabels {
90
+ string,
91
+ string[],
92
+ TodoLabelRecord,
93
+ TodoLabelRecord[],
94
+ }
95
+
96
+ @jsonSchema
97
+ model TodoLabelRecord {
98
+ name: string;
99
+
100
+ @pattern("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$")
101
+ color?: string;
102
+ }
103
+
104
+ @jsonSchema
105
+ model TodoAttachment {
106
+ /** The file name of the attachment */
107
+ @maxLength(255)
108
+ filename: string;
109
+
110
+ /** The media type of the attachment */
111
+ mediaType: string;
112
+
113
+ /** The contents of the file */
114
+ contents: bytes;
115
+ }
116
+
117
+ @jsonSchema
118
+ @error
119
+ model ApiError {
120
+ /** A machine readable error code */
121
+ code: string;
122
+
123
+ /** A human readable message */
124
+ // https://github.com/microsoft/OpenAPI/blob/main/extensions/x-ms-primary-error-message.md
125
+ @OpenAPI.extension("x-ms-primary-error-message", true)
126
+ message: string;
127
+ }
128
+
129
+ /**
130
+ * Something is wrong with you.
131
+ */
132
+ model Standard4XXResponse extends ApiError {
133
+ @minValue(400)
134
+ @maxValue(499)
135
+ @statusCode
136
+ statusCode: int32;
137
+ }
138
+
139
+ /**
140
+ * Something is wrong with me.
141
+ */
142
+ model Standard5XXResponse extends ApiError {
143
+ @minValue(500)
144
+ @maxValue(599)
145
+ @statusCode
146
+ statusCode: int32;
147
+ }
148
+
149
+ alias WithStandardErrors<T> = T | Standard4XXResponse | Standard5XXResponse;
150
+
151
+ @useAuth(NoAuth)
152
+ namespace Users {
153
+ // would prefer to extend
154
+ // https://github.com/microsoft/typespec/issues/2922
155
+
156
+ model UserCreatedResponse {
157
+ ...User;
158
+ ...OkResponse;
159
+
160
+ /** The token to use to construct the validate email address url */
161
+ token: string;
162
+ }
163
+
164
+ /** The user already exists */
165
+ model UserExistsResponse extends ApiError {
166
+ ...ConflictResponse;
167
+ code: "user-exists";
168
+ }
169
+
170
+ /** The user is invalid (e.g. forgot to enter email address) */
171
+ model InvalidUserResponse extends ApiError {
172
+ @statusCode statusCode: 422;
173
+ code: "invalid-user";
174
+ }
175
+
176
+ @route("/users")
177
+ @post
178
+ op create(
179
+ @body user: User,
180
+ ): WithStandardErrors<UserCreatedResponse | UserExistsResponse | InvalidUserResponse>;
181
+ }
182
+
183
+ @route("items")
184
+ namespace TodoItems {
185
+ model PaginationControls {
186
+ /** The limit to the number of items */
187
+ @query limit?: int32 = 50;
188
+
189
+ /** The offset to start paginating at */
190
+ @query offset?: int32 = 0;
191
+ }
192
+
193
+ model TodoPage {
194
+ /** The items in the page */
195
+ @pageItems items: TodoItem[];
196
+
197
+ /** The number of items returned in this page */
198
+ pageSize: int32;
199
+
200
+ /** The total number of items */
201
+ totalSize: int32;
202
+
203
+ ...PaginationControls;
204
+
205
+ /** A link to the previous page, if it exists */
206
+ @prevLink
207
+ prevLink?: url;
208
+
209
+ /** A link to the next page, if it exists */
210
+ @nextLink
211
+ nextLink?: url;
212
+ }
213
+
214
+ // deeply annoying that I have to copy/paste this...
215
+ model TodoItemPatch {
216
+ /** The item's title */
217
+ title?: TodoItem.title;
218
+
219
+ /** User that the todo is assigned to */
220
+ assignedTo?: TodoItem.assignedTo | null;
221
+
222
+ /** A longer description of the todo item in markdown format */
223
+ description?: TodoItem.description | null;
224
+
225
+ /** The status of the todo item */
226
+ status?: "NotStarted" | "InProgress" | "Completed";
227
+ }
228
+
229
+ model InvalidTodoItem extends ApiError {
230
+ @statusCode statusCode: 422;
231
+ }
232
+
233
+ @error
234
+ model NotFoundErrorResponse {
235
+ @statusCode statusCode: 404;
236
+ code: "not-found";
237
+ }
238
+
239
+ //@friendlyName("{name}List", T)
240
+ model Page<T> {
241
+ @pageItems items: T[];
242
+ }
243
+
244
+ @list op list(...PaginationControls): WithStandardErrors<TodoPage>;
245
+
246
+ @sharedRoute
247
+ @post
248
+ op createJson(
249
+ @header contentType: "application/json",
250
+ item: TodoItem,
251
+ attachments?: TodoAttachment[],
252
+ ): WithStandardErrors<TodoItem | InvalidTodoItem>;
253
+
254
+ @sharedRoute
255
+ @post
256
+ op createForm(
257
+ @header contentType: "multipart/form-data",
258
+ @multipartBody body: ToDoItemMultipartRequest,
259
+ ): WithStandardErrors<TodoItem | InvalidTodoItem>;
260
+
261
+ @get op get(@path id: TodoItem.id): TodoItem | NotFoundErrorResponse;
262
+ @patch op update(
263
+ @header contentType: "application/merge-patch+json",
264
+ @path id: TodoItem.id,
265
+ @body patch: TodoItemPatch,
266
+ ): TodoItem;
267
+ @delete op delete(
268
+ @path id: TodoItem.id,
269
+ ): WithStandardErrors<NoContentResponse | NotFoundErrorResponse>;
270
+
271
+ @route("{itemId}/attachments")
272
+ namespace Attachments {
273
+ @list op list(
274
+ @path itemId: TodoItem.id,
275
+ ): WithStandardErrors<Page<TodoAttachment> | NotFoundErrorResponse>;
276
+
277
+ @sharedRoute
278
+ @post
279
+ op createJsonAttachment(
280
+ @header contentType: "application/json",
281
+ @path itemId: TodoItem.id,
282
+ @body contents: TodoAttachment,
283
+ ): WithStandardErrors<NoContentResponse | NotFoundErrorResponse>;
284
+
285
+ @sharedRoute
286
+ @post
287
+ op createFileAttachment(
288
+ @header contentType: "multipart/form-data",
289
+ @path itemId: TodoItem.id,
290
+ @multipartBody body: FileAttachmentMultipartRequest,
291
+ ): WithStandardErrors<NoContentResponse | NotFoundErrorResponse>;
292
+ }
293
+ }