@storyblok/management-api-client 1.0.0-alpha.1 → 1.0.0-alpha.3

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 (294) hide show
  1. package/README.md +3 -1
  2. package/dist/client.cjs +9 -9
  3. package/dist/client.cjs.map +1 -1
  4. package/dist/client.d.cts +217 -203
  5. package/dist/client.d.mts +217 -203
  6. package/dist/client.mjs +9 -9
  7. package/dist/client.mjs.map +1 -1
  8. package/dist/generated/mapi/_internal.gen.d.cts +371 -0
  9. package/dist/generated/mapi/_internal.gen.d.mts +371 -0
  10. package/dist/generated/{shared → mapi}/client/client.gen.cjs +1 -1
  11. package/dist/generated/mapi/client/client.gen.cjs.map +1 -0
  12. package/dist/generated/{shared → mapi}/client/client.gen.mjs +1 -1
  13. package/dist/generated/mapi/client/client.gen.mjs.map +1 -0
  14. package/dist/generated/{shared → mapi}/client/types.gen.d.cts +1 -1
  15. package/dist/generated/{shared → mapi}/client/types.gen.d.mts +1 -1
  16. package/dist/generated/{shared → mapi}/client/utils.gen.cjs +1 -1
  17. package/dist/generated/mapi/client/utils.gen.cjs.map +1 -0
  18. package/dist/generated/{shared → mapi}/client/utils.gen.d.cts +1 -1
  19. package/dist/generated/{shared → mapi}/client/utils.gen.d.mts +1 -1
  20. package/dist/generated/{shared → mapi}/client/utils.gen.mjs +1 -1
  21. package/dist/generated/mapi/client/utils.gen.mjs.map +1 -0
  22. package/dist/generated/mapi/client.gen.cjs +10 -0
  23. package/dist/generated/mapi/client.gen.cjs.map +1 -0
  24. package/dist/generated/mapi/client.gen.mjs +10 -0
  25. package/dist/generated/mapi/client.gen.mjs.map +1 -0
  26. package/dist/generated/{shared → mapi}/core/auth.gen.cjs +1 -1
  27. package/dist/generated/mapi/core/auth.gen.cjs.map +1 -0
  28. package/dist/generated/{shared → mapi}/core/auth.gen.d.cts +1 -1
  29. package/dist/generated/{shared → mapi}/core/auth.gen.d.mts +1 -1
  30. package/dist/generated/{shared → mapi}/core/auth.gen.mjs +1 -1
  31. package/dist/generated/mapi/core/auth.gen.mjs.map +1 -0
  32. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.cjs +1 -1
  33. package/dist/generated/mapi/core/bodySerializer.gen.cjs.map +1 -0
  34. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.d.cts +1 -1
  35. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.d.mts +1 -1
  36. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.mjs +1 -1
  37. package/dist/generated/mapi/core/bodySerializer.gen.mjs.map +1 -0
  38. package/dist/generated/{shared → mapi}/core/params.gen.cjs +1 -1
  39. package/dist/generated/mapi/core/params.gen.cjs.map +1 -0
  40. package/dist/generated/{shared → mapi}/core/params.gen.mjs +1 -1
  41. package/dist/generated/mapi/core/params.gen.mjs.map +1 -0
  42. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.cjs +1 -1
  43. package/dist/generated/mapi/core/pathSerializer.gen.cjs.map +1 -0
  44. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.d.cts +1 -1
  45. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.d.mts +1 -1
  46. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.mjs +1 -1
  47. package/dist/generated/mapi/core/pathSerializer.gen.mjs.map +1 -0
  48. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.cjs +1 -1
  49. package/dist/generated/mapi/core/serverSentEvents.gen.cjs.map +1 -0
  50. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.d.cts +1 -1
  51. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.d.mts +1 -1
  52. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.mjs +1 -1
  53. package/dist/generated/mapi/core/serverSentEvents.gen.mjs.map +1 -0
  54. package/dist/generated/{shared → mapi}/core/types.gen.d.cts +1 -1
  55. package/dist/generated/{shared → mapi}/core/types.gen.d.mts +1 -1
  56. package/dist/generated/{shared → mapi}/core/utils.gen.cjs +1 -1
  57. package/dist/generated/mapi/core/utils.gen.cjs.map +1 -0
  58. package/dist/generated/{shared → mapi}/core/utils.gen.mjs +1 -1
  59. package/dist/generated/mapi/core/utils.gen.mjs.map +1 -0
  60. package/dist/generated/mapi/sdk.gen.cjs +1477 -0
  61. package/dist/generated/mapi/sdk.gen.cjs.map +1 -0
  62. package/dist/generated/mapi/sdk.gen.mjs +1399 -0
  63. package/dist/generated/mapi/sdk.gen.mjs.map +1 -0
  64. package/dist/generated/mapi/types-aliased.gen.d.cts +1598 -0
  65. package/dist/generated/mapi/types-aliased.gen.d.mts +1598 -0
  66. package/dist/generated/mapi/types.gen.d.cts +5075 -0
  67. package/dist/generated/mapi/types.gen.d.mts +5075 -0
  68. package/dist/generated/{components/types.gen.d.cts → overlay/_internal.gen.d.cts} +281 -457
  69. package/dist/generated/{components/types.gen.d.mts → overlay/_internal.gen.d.mts} +281 -457
  70. package/dist/generated/types/_utils.d.cts +7 -0
  71. package/dist/generated/types/_utils.d.mts +7 -0
  72. package/dist/generated/types/block.d.cts +49 -0
  73. package/dist/generated/types/block.d.mts +49 -0
  74. package/dist/generated/types/field.d.cts +87 -0
  75. package/dist/generated/types/field.d.mts +87 -0
  76. package/dist/generated/types/mapi-story.d.cts +29 -0
  77. package/dist/generated/types/mapi-story.d.mts +29 -0
  78. package/dist/index.d.cts +8 -4
  79. package/dist/index.d.mts +8 -4
  80. package/dist/resources/asset-folders.cjs +9 -9
  81. package/dist/resources/asset-folders.cjs.map +1 -1
  82. package/dist/resources/asset-folders.mjs +9 -9
  83. package/dist/resources/asset-folders.mjs.map +1 -1
  84. package/dist/resources/assets.cjs +64 -46
  85. package/dist/resources/assets.cjs.map +1 -1
  86. package/dist/resources/assets.d.cts +23 -28
  87. package/dist/resources/assets.d.mts +23 -28
  88. package/dist/resources/assets.mjs +64 -46
  89. package/dist/resources/assets.mjs.map +1 -1
  90. package/dist/resources/component-folders.cjs +9 -9
  91. package/dist/resources/component-folders.cjs.map +1 -1
  92. package/dist/resources/component-folders.mjs +9 -9
  93. package/dist/resources/component-folders.mjs.map +1 -1
  94. package/dist/resources/components.cjs +28 -20
  95. package/dist/resources/components.cjs.map +1 -1
  96. package/dist/resources/components.d.cts +76 -0
  97. package/dist/resources/components.d.mts +76 -0
  98. package/dist/resources/components.mjs +28 -20
  99. package/dist/resources/components.mjs.map +1 -1
  100. package/dist/resources/datasource-entries.cjs +28 -34
  101. package/dist/resources/datasource-entries.cjs.map +1 -1
  102. package/dist/resources/datasource-entries.mjs +29 -35
  103. package/dist/resources/datasource-entries.mjs.map +1 -1
  104. package/dist/resources/datasources.cjs +27 -9
  105. package/dist/resources/datasources.cjs.map +1 -1
  106. package/dist/resources/datasources.mjs +27 -9
  107. package/dist/resources/datasources.mjs.map +1 -1
  108. package/dist/resources/experiments.cjs +299 -0
  109. package/dist/resources/experiments.cjs.map +1 -0
  110. package/dist/resources/experiments.mjs +299 -0
  111. package/dist/resources/experiments.mjs.map +1 -0
  112. package/dist/resources/internal-tags.cjs +7 -7
  113. package/dist/resources/internal-tags.cjs.map +1 -1
  114. package/dist/resources/internal-tags.mjs +7 -7
  115. package/dist/resources/internal-tags.mjs.map +1 -1
  116. package/dist/resources/presets.cjs +9 -9
  117. package/dist/resources/presets.cjs.map +1 -1
  118. package/dist/resources/presets.mjs +9 -9
  119. package/dist/resources/presets.mjs.map +1 -1
  120. package/dist/resources/shared.cjs +15 -0
  121. package/dist/resources/shared.cjs.map +1 -1
  122. package/dist/resources/shared.mjs +15 -1
  123. package/dist/resources/shared.mjs.map +1 -1
  124. package/dist/resources/spaces.cjs +8 -7
  125. package/dist/resources/spaces.cjs.map +1 -1
  126. package/dist/resources/spaces.d.cts +8 -0
  127. package/dist/resources/spaces.d.mts +7 -0
  128. package/dist/resources/spaces.mjs +8 -7
  129. package/dist/resources/spaces.mjs.map +1 -1
  130. package/dist/resources/stories.cjs +20 -16
  131. package/dist/resources/stories.cjs.map +1 -1
  132. package/dist/resources/stories.d.cts +30 -42
  133. package/dist/resources/stories.d.mts +30 -42
  134. package/dist/resources/stories.mjs +20 -16
  135. package/dist/resources/stories.mjs.map +1 -1
  136. package/dist/resources/users.cjs +3 -3
  137. package/dist/resources/users.cjs.map +1 -1
  138. package/dist/resources/users.mjs +3 -3
  139. package/dist/resources/users.mjs.map +1 -1
  140. package/dist/utils/query-serializer.cjs +54 -0
  141. package/dist/utils/query-serializer.cjs.map +1 -0
  142. package/dist/utils/query-serializer.mjs +54 -0
  143. package/dist/utils/query-serializer.mjs.map +1 -0
  144. package/dist/utils/rate-limit.cjs +15 -74
  145. package/dist/utils/rate-limit.cjs.map +1 -1
  146. package/dist/utils/rate-limit.d.cts +5 -6
  147. package/dist/utils/rate-limit.d.mts +5 -6
  148. package/dist/utils/rate-limit.mjs +15 -74
  149. package/dist/utils/rate-limit.mjs.map +1 -1
  150. package/package.json +13 -13
  151. package/playground/integration-tests/README.md +24 -0
  152. package/playground/integration-tests/eslint.config.js +5 -0
  153. package/playground/integration-tests/node_modules/.bin/eslint +16 -0
  154. package/playground/integration-tests/node_modules/.bin/tsc +16 -0
  155. package/playground/integration-tests/node_modules/.bin/tsserver +16 -0
  156. package/playground/integration-tests/node_modules/.bin/vitest +16 -0
  157. package/playground/integration-tests/package.json +24 -0
  158. package/{test → playground/integration-tests/test}/setup.e2e.ts +2 -2
  159. package/{test → playground/integration-tests/test}/specs/mapi-round-trip.spec.e2e.ts +31 -41
  160. package/playground/integration-tests/test/types/components.test-d.ts +74 -0
  161. package/playground/integration-tests/test/types/resources.test-d.ts +212 -0
  162. package/playground/integration-tests/test/types/stories.test-d.ts +273 -0
  163. package/{vitest.config.e2e.ts → playground/integration-tests/vitest.config.e2e.ts} +1 -2
  164. package/playground/integration-tests/vitest.config.ts +13 -0
  165. package/test/GUIDE.md +4 -4
  166. package/vitest.config.ts +2 -0
  167. package/dist/generated/asset_folders/client.gen.cjs +0 -10
  168. package/dist/generated/asset_folders/client.gen.cjs.map +0 -1
  169. package/dist/generated/asset_folders/client.gen.mjs +0 -10
  170. package/dist/generated/asset_folders/client.gen.mjs.map +0 -1
  171. package/dist/generated/asset_folders/sdk.gen.cjs +0 -99
  172. package/dist/generated/asset_folders/sdk.gen.cjs.map +0 -1
  173. package/dist/generated/asset_folders/sdk.gen.mjs +0 -95
  174. package/dist/generated/asset_folders/sdk.gen.mjs.map +0 -1
  175. package/dist/generated/asset_folders/types.gen.d.cts +0 -130
  176. package/dist/generated/asset_folders/types.gen.d.mts +0 -130
  177. package/dist/generated/assets/client.gen.cjs +0 -10
  178. package/dist/generated/assets/client.gen.cjs.map +0 -1
  179. package/dist/generated/assets/client.gen.mjs +0 -10
  180. package/dist/generated/assets/client.gen.mjs.map +0 -1
  181. package/dist/generated/assets/sdk.gen.cjs +0 -179
  182. package/dist/generated/assets/sdk.gen.cjs.map +0 -1
  183. package/dist/generated/assets/sdk.gen.mjs +0 -171
  184. package/dist/generated/assets/sdk.gen.mjs.map +0 -1
  185. package/dist/generated/assets/types.gen.d.cts +0 -343
  186. package/dist/generated/assets/types.gen.d.mts +0 -343
  187. package/dist/generated/component_folders/client.gen.cjs +0 -10
  188. package/dist/generated/component_folders/client.gen.cjs.map +0 -1
  189. package/dist/generated/component_folders/client.gen.mjs +0 -10
  190. package/dist/generated/component_folders/client.gen.mjs.map +0 -1
  191. package/dist/generated/component_folders/sdk.gen.cjs +0 -99
  192. package/dist/generated/component_folders/sdk.gen.cjs.map +0 -1
  193. package/dist/generated/component_folders/sdk.gen.mjs +0 -95
  194. package/dist/generated/component_folders/sdk.gen.mjs.map +0 -1
  195. package/dist/generated/component_folders/types.gen.d.cts +0 -102
  196. package/dist/generated/component_folders/types.gen.d.mts +0 -102
  197. package/dist/generated/components/client.gen.cjs +0 -10
  198. package/dist/generated/components/client.gen.cjs.map +0 -1
  199. package/dist/generated/components/client.gen.mjs +0 -10
  200. package/dist/generated/components/client.gen.mjs.map +0 -1
  201. package/dist/generated/components/sdk.gen.cjs +0 -171
  202. package/dist/generated/components/sdk.gen.cjs.map +0 -1
  203. package/dist/generated/components/sdk.gen.mjs +0 -163
  204. package/dist/generated/components/sdk.gen.mjs.map +0 -1
  205. package/dist/generated/datasource_entries/client.gen.cjs +0 -10
  206. package/dist/generated/datasource_entries/client.gen.cjs.map +0 -1
  207. package/dist/generated/datasource_entries/client.gen.mjs +0 -10
  208. package/dist/generated/datasource_entries/client.gen.mjs.map +0 -1
  209. package/dist/generated/datasource_entries/sdk.gen.cjs +0 -89
  210. package/dist/generated/datasource_entries/sdk.gen.cjs.map +0 -1
  211. package/dist/generated/datasource_entries/sdk.gen.mjs +0 -85
  212. package/dist/generated/datasource_entries/sdk.gen.mjs.map +0 -1
  213. package/dist/generated/datasource_entries/types.gen.d.cts +0 -130
  214. package/dist/generated/datasource_entries/types.gen.d.mts +0 -130
  215. package/dist/generated/datasources/client.gen.cjs +0 -10
  216. package/dist/generated/datasources/client.gen.cjs.map +0 -1
  217. package/dist/generated/datasources/client.gen.mjs +0 -10
  218. package/dist/generated/datasources/client.gen.mjs.map +0 -1
  219. package/dist/generated/datasources/sdk.gen.cjs +0 -89
  220. package/dist/generated/datasources/sdk.gen.cjs.map +0 -1
  221. package/dist/generated/datasources/sdk.gen.mjs +0 -85
  222. package/dist/generated/datasources/sdk.gen.mjs.map +0 -1
  223. package/dist/generated/datasources/types.gen.d.cts +0 -165
  224. package/dist/generated/datasources/types.gen.d.mts +0 -165
  225. package/dist/generated/internal_tags/client.gen.cjs +0 -10
  226. package/dist/generated/internal_tags/client.gen.cjs.map +0 -1
  227. package/dist/generated/internal_tags/client.gen.mjs +0 -10
  228. package/dist/generated/internal_tags/client.gen.mjs.map +0 -1
  229. package/dist/generated/internal_tags/sdk.gen.cjs +0 -74
  230. package/dist/generated/internal_tags/sdk.gen.cjs.map +0 -1
  231. package/dist/generated/internal_tags/sdk.gen.mjs +0 -71
  232. package/dist/generated/internal_tags/sdk.gen.mjs.map +0 -1
  233. package/dist/generated/internal_tags/types.gen.d.cts +0 -102
  234. package/dist/generated/internal_tags/types.gen.d.mts +0 -102
  235. package/dist/generated/presets/client.gen.cjs +0 -10
  236. package/dist/generated/presets/client.gen.cjs.map +0 -1
  237. package/dist/generated/presets/client.gen.mjs +0 -10
  238. package/dist/generated/presets/client.gen.mjs.map +0 -1
  239. package/dist/generated/presets/sdk.gen.cjs +0 -99
  240. package/dist/generated/presets/sdk.gen.cjs.map +0 -1
  241. package/dist/generated/presets/sdk.gen.mjs +0 -95
  242. package/dist/generated/presets/sdk.gen.mjs.map +0 -1
  243. package/dist/generated/presets/types.gen.d.cts +0 -171
  244. package/dist/generated/presets/types.gen.d.mts +0 -171
  245. package/dist/generated/shared/client/client.gen.cjs.map +0 -1
  246. package/dist/generated/shared/client/client.gen.mjs.map +0 -1
  247. package/dist/generated/shared/client/utils.gen.cjs.map +0 -1
  248. package/dist/generated/shared/client/utils.gen.mjs.map +0 -1
  249. package/dist/generated/shared/core/auth.gen.cjs.map +0 -1
  250. package/dist/generated/shared/core/auth.gen.mjs.map +0 -1
  251. package/dist/generated/shared/core/bodySerializer.gen.cjs.map +0 -1
  252. package/dist/generated/shared/core/bodySerializer.gen.mjs.map +0 -1
  253. package/dist/generated/shared/core/params.gen.cjs.map +0 -1
  254. package/dist/generated/shared/core/params.gen.mjs.map +0 -1
  255. package/dist/generated/shared/core/pathSerializer.gen.cjs.map +0 -1
  256. package/dist/generated/shared/core/pathSerializer.gen.mjs.map +0 -1
  257. package/dist/generated/shared/core/serverSentEvents.gen.cjs.map +0 -1
  258. package/dist/generated/shared/core/serverSentEvents.gen.mjs.map +0 -1
  259. package/dist/generated/shared/core/utils.gen.cjs.map +0 -1
  260. package/dist/generated/shared/core/utils.gen.mjs.map +0 -1
  261. package/dist/generated/spaces/client.gen.cjs +0 -10
  262. package/dist/generated/spaces/client.gen.cjs.map +0 -1
  263. package/dist/generated/spaces/client.gen.mjs +0 -10
  264. package/dist/generated/spaces/client.gen.mjs.map +0 -1
  265. package/dist/generated/spaces/sdk.gen.cjs +0 -99
  266. package/dist/generated/spaces/sdk.gen.cjs.map +0 -1
  267. package/dist/generated/spaces/sdk.gen.mjs +0 -95
  268. package/dist/generated/spaces/sdk.gen.mjs.map +0 -1
  269. package/dist/generated/spaces/types.gen.d.cts +0 -504
  270. package/dist/generated/spaces/types.gen.d.mts +0 -504
  271. package/dist/generated/stories/client.gen.cjs +0 -10
  272. package/dist/generated/stories/client.gen.cjs.map +0 -1
  273. package/dist/generated/stories/client.gen.mjs +0 -10
  274. package/dist/generated/stories/client.gen.mjs.map +0 -1
  275. package/dist/generated/stories/sdk.gen.cjs +0 -138
  276. package/dist/generated/stories/sdk.gen.cjs.map +0 -1
  277. package/dist/generated/stories/sdk.gen.mjs +0 -131
  278. package/dist/generated/stories/sdk.gen.mjs.map +0 -1
  279. package/dist/generated/stories/types.gen.d.cts +0 -1314
  280. package/dist/generated/stories/types.gen.d.mts +0 -1314
  281. package/dist/generated/users/client.gen.cjs +0 -10
  282. package/dist/generated/users/client.gen.cjs.map +0 -1
  283. package/dist/generated/users/client.gen.mjs +0 -10
  284. package/dist/generated/users/client.gen.mjs.map +0 -1
  285. package/dist/generated/users/sdk.gen.cjs +0 -44
  286. package/dist/generated/users/sdk.gen.cjs.map +0 -1
  287. package/dist/generated/users/sdk.gen.mjs +0 -43
  288. package/dist/generated/users/sdk.gen.mjs.map +0 -1
  289. package/dist/generated/users/types.gen.d.cts +0 -249
  290. package/dist/generated/users/types.gen.d.mts +0 -249
  291. /package/dist/generated/{shared → mapi}/client/client.gen.d.mts +0 -0
  292. /package/dist/generated/{shared → mapi}/client/index.cjs +0 -0
  293. /package/dist/generated/{shared → mapi}/client/index.d.mts +0 -0
  294. /package/dist/generated/{shared → mapi}/client/index.mjs +0 -0
@@ -0,0 +1,24 @@
1
+ # @storyblok/mapi-integration-tests
2
+
3
+ Integration tests for [`@storyblok/management-api-client`](../../) paired with [`@storyblok/schema`](../../../schema).
4
+
5
+ This playground exists so the management-api-client package itself stays free of a runtime dependency on `@storyblok/schema`, while still letting us verify that the two packages line up.
6
+
7
+ ## Type tests
8
+
9
+ `test/types/*.test-d.ts` assert that `defineBlock` / `defineX*` payloads from `@storyblok/schema` are assignable to the corresponding MAPI request bodies, and that `.withTypes()` narrows responses correctly. They run in CI:
10
+
11
+ ```bash
12
+ pnpm --filter @storyblok/mapi-integration-tests test
13
+ pnpm --filter @storyblok/mapi-integration-tests test:types
14
+ ```
15
+
16
+ ## End-to-end tests
17
+
18
+ `test/specs/*.spec.e2e.ts` exercise a real round-trip against the Storyblok MAPI using a personal access token. Run manually only:
19
+
20
+ ```bash
21
+ pnpm --filter @storyblok/mapi-integration-tests test:e2e
22
+ ```
23
+
24
+ Requires `.env.qa-engineer-manual` at the repo root with `STORYBLOK_TOKEN` and `STORYBLOK_SPACE_ID`.
@@ -0,0 +1,5 @@
1
+ import { storyblokLintConfig } from '@storyblok/eslint-config';
2
+
3
+ export default storyblokLintConfig({}, {
4
+ ignores: ['**/*.md'],
5
+ });
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -x "$basedir/node" ]; then
13
+ exec "$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@"
14
+ else
15
+ exec node "$basedir/../eslint/bin/eslint.js" "$@"
16
+ fi
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -x "$basedir/node" ]; then
13
+ exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
14
+ else
15
+ exec node "$basedir/../typescript/bin/tsc" "$@"
16
+ fi
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -x "$basedir/node" ]; then
13
+ exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
14
+ else
15
+ exec node "$basedir/../typescript/bin/tsserver" "$@"
16
+ fi
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -x "$basedir/node" ]; then
13
+ exec "$basedir/node" "$basedir/../vitest/vitest.mjs" "$@"
14
+ else
15
+ exec node "$basedir/../vitest/vitest.mjs" "$@"
16
+ fi
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@storyblok/mapi-integration-tests",
3
+ "type": "module",
4
+ "version": "0.0.0",
5
+ "private": true,
6
+ "description": "Integration tests for @storyblok/management-api-client paired with @storyblok/schema",
7
+ "scripts": {
8
+ "test": "vitest run",
9
+ "test:types": "tsc --noEmit --skipLibCheck",
10
+ "test:e2e": "vitest run -c vitest.config.e2e.ts",
11
+ "lint": "eslint .",
12
+ "lint:fix": "eslint . --fix"
13
+ },
14
+ "devDependencies": {
15
+ "@storyblok/eslint-config": "workspace:*",
16
+ "@storyblok/management-api-client": "workspace:*",
17
+ "@storyblok/schema": "workspace:*",
18
+ "@types/node": "^24.1.0",
19
+ "dotenv": "^17.3.1",
20
+ "eslint": "^9.39.2",
21
+ "typescript": "5.8.3",
22
+ "vitest": "^4.1.3"
23
+ }
24
+ }
@@ -1,7 +1,7 @@
1
- import { config } from 'dotenv';
2
1
  import { resolve } from 'node:path';
2
+ import { config } from 'dotenv';
3
3
 
4
- config({ path: resolve(import.meta.dirname, '../../../.env.qa-engineer-manual') });
4
+ config({ path: resolve(import.meta.dirname, '../../../../../.env.qa-engineer-manual') });
5
5
 
6
6
  if (!process.env.STORYBLOK_TOKEN || !process.env.STORYBLOK_SPACE_ID) {
7
7
  throw new Error(
@@ -9,7 +9,7 @@
9
9
  * 4. Zod schemas generated from the OpenAPI spec accept real API responses.
10
10
  *
11
11
  * Run manually (never in CI):
12
- * pnpm --filter @storyblok/management-api-client test:e2e
12
+ * pnpm --filter @storyblok/mapi-integration-tests test:e2e
13
13
  *
14
14
  * Requires .env.qa-engineer-manual at the repo root with:
15
15
  * STORYBLOK_TOKEN=<personal-access-token>
@@ -18,16 +18,10 @@
18
18
 
19
19
  import { afterAll, beforeAll, describe, expect, it } from 'vitest';
20
20
  import { createManagementApiClient } from '@storyblok/management-api-client';
21
+ import type { StoryCreate, StoryUpdate } from '@storyblok/management-api-client';
21
22
  import {
22
- createStoryHelpers,
23
23
  defineBlock,
24
- defineBlockCreate,
25
- defineBlockFolderCreate,
26
- defineDatasourceCreate,
27
- defineDatasourceEntryCreate,
28
24
  defineField,
29
- defineInternalTagCreate,
30
- definePresetCreate,
31
25
  } from '@storyblok/schema';
32
26
 
33
27
  const token = process.env.STORYBLOK_TOKEN!;
@@ -43,7 +37,7 @@ const STORY_SLUG = `${STORY_SLUG_PREFIX}test-page`;
43
37
 
44
38
  const teaserComponent = defineBlock({
45
39
  name: `${PREFIX}teaser`,
46
- schema: [
40
+ fields: [
47
41
  defineField('title', { type: 'text', required: true }),
48
42
  defineField('image', { type: 'asset' }),
49
43
  ],
@@ -51,21 +45,21 @@ const teaserComponent = defineBlock({
51
45
  // Level-2 container: holds teasers in its `items` bloks field (level 3)
52
46
  const sectionComponent = defineBlock({
53
47
  name: `${PREFIX}section`,
54
- schema: [
48
+ fields: [
55
49
  defineField('title', { type: 'text' }),
56
- defineField('items', { type: 'bloks', component_whitelist: [teaserComponent.name], required: true }),
50
+ defineField('items', { type: 'bloks', allow: [teaserComponent.name], required: true }),
57
51
  ],
58
52
  });
59
53
  const pageComponent = defineBlock({
60
54
  name: `${PREFIX}page`,
61
55
  is_root: true,
62
- schema: [
56
+ fields: [
63
57
  defineField('headline', { type: 'text', required: true }),
64
58
  defineField('rating', { type: 'number' }),
65
59
  defineField('is_featured', { type: 'boolean' }),
66
60
  defineField('description', { type: 'richtext' }),
67
- defineField('body', { type: 'bloks', component_whitelist: [teaserComponent.name, sectionComponent.name], required: true }),
68
- defineField('category', { type: 'option', source: 'internal', datasource_slug: DATASOURCE_SLUG }),
61
+ defineField('body', { type: 'bloks', allow: [teaserComponent.name, sectionComponent.name], required: true }),
62
+ defineField('category', { type: 'option', source: 'internal', datasource: DATASOURCE_SLUG }),
69
63
  defineField('any_blocks', { type: 'bloks', required: true }),
70
64
  ],
71
65
  });
@@ -74,7 +68,7 @@ interface StoryblokTypes {
74
68
  components: typeof pageComponent | typeof teaserComponent | typeof sectionComponent;
75
69
  }
76
70
 
77
- const { defineStoryCreate, defineStoryUpdate } = createStoryHelpers().withTypes<StoryblokTypes>();
71
+ type Blocks = StoryblokTypes['components'];
78
72
 
79
73
  const client = createManagementApiClient({
80
74
  personalAccessToken: token,
@@ -155,53 +149,50 @@ describe('schema + mapi-client MAPI round-trip', () => {
155
149
 
156
150
  // 1. Datasource + entries first — the page component schema references the datasource slug,
157
151
  // and the MAPI validates that the datasource exists at component creation time.
158
- const datasourcePayload = defineDatasourceCreate({
152
+ // Create payloads are plain MAPI wire objects validated by the typed client.
153
+ const dsRes = await client.datasources.create({ body: { datasource: {
159
154
  name: DATASOURCE_NAME,
160
155
  slug: DATASOURCE_SLUG,
161
- });
162
- const dsRes = await client.datasources.create({ body: { datasource: datasourcePayload } });
156
+ } } });
163
157
  datasourceId = dsRes.data!.datasource!.id!;
164
158
 
165
159
  for (const entry of [
166
- defineDatasourceEntryCreate({ name: 'Technology', value: 'tech', datasource_id: datasourceId }),
167
- defineDatasourceEntryCreate({ name: 'Design', value: 'design', datasource_id: datasourceId }),
168
- defineDatasourceEntryCreate({ name: 'Business', value: 'business', datasource_id: datasourceId }),
160
+ { name: 'Technology', value: 'tech', datasource_id: datasourceId },
161
+ { name: 'Design', value: 'design', datasource_id: datasourceId },
162
+ { name: 'Business', value: 'business', datasource_id: datasourceId },
169
163
  ]) {
170
164
  await client.datasourceEntries.create({ body: { datasource_entry: entry } });
171
165
  }
172
166
 
173
167
  // 2. Component folder
174
- const folderPayload = defineBlockFolderCreate({ name: `${PREFIX}folder` });
175
- const folderRes = await client.componentFolders.create({ body: { component_group: folderPayload } });
168
+ const folderRes = await client.componentFolders.create({ body: { component_group: { name: `${PREFIX}folder` } } });
176
169
  componentFolderId = folderRes.data!.component_group!.id!;
177
170
  const folderUuid = folderRes.data!.component_group!.uuid;
178
171
 
179
172
  // 3. Teaser component (innermost — whitelisted by section)
180
- const teaserPayload = defineBlockCreate({
173
+ const teaserRes = await client.components.create({ body: { component: {
181
174
  name: teaserComponent.name,
182
175
  schema: {
183
176
  title: { type: 'text', required: true, pos: 0 },
184
177
  image: { type: 'asset', pos: 1 },
185
178
  },
186
179
  component_group_uuid: folderUuid,
187
- });
188
- const teaserRes = await client.components.create({ body: { component: teaserPayload } });
180
+ } } });
189
181
  teaserComponentId = teaserRes.data!.component!.id!;
190
182
 
191
183
  // 4. Section component (level 2 — whitelists teaser, whitelisted by page)
192
- const sectionPayload = defineBlockCreate({
184
+ const sectionRes = await client.components.create({ body: { component: {
193
185
  name: sectionComponent.name,
194
186
  schema: {
195
187
  title: { type: 'text', pos: 0 },
196
188
  items: { type: 'bloks', component_whitelist: [teaserComponent.name], pos: 1 },
197
189
  },
198
190
  component_group_uuid: folderUuid,
199
- });
200
- const sectionRes = await client.components.create({ body: { component: sectionPayload } });
191
+ } } });
201
192
  sectionComponentId = sectionRes.data!.component!.id!;
202
193
 
203
194
  // 5. Page component (level 1 — whitelists both teaser and section in body)
204
- const pagePayload = defineBlockCreate({
195
+ const pageRes = await client.components.create({ body: { component: {
205
196
  name: pageComponent.name,
206
197
  schema: {
207
198
  headline: { type: 'text', required: true, pos: 0 },
@@ -214,30 +205,28 @@ describe('schema + mapi-client MAPI round-trip', () => {
214
205
  },
215
206
  component_group_uuid: folderUuid,
216
207
  is_root: true,
217
- });
218
- const pageRes = await client.components.create({ body: { component: pagePayload } });
208
+ } } });
219
209
  pageComponentId = pageRes.data!.component!.id!;
220
210
 
221
211
  // 5. Internal tag
222
- const tagPayload = defineInternalTagCreate({ name: `${PREFIX}tag`, object_type: 'component' });
223
- const tagRes = await client.internalTags.create({ body: { internal_tag: tagPayload } });
212
+ const tagRes = await client.internalTags.create({ body: { internal_tag: { name: `${PREFIX}tag`, object_type: 'component' } } });
224
213
  internalTagId = tagRes.data!.internal_tag!.id!;
225
214
 
226
215
  // 6. Preset for page component
227
- const presetPayload = definePresetCreate({
216
+ const presetRes = await client.presets.create({ body: { preset: {
228
217
  name: `${PREFIX}default_page`,
229
218
  component_id: pageComponentId,
230
219
  preset: { headline: 'Default Headline', rating: 0, is_featured: false },
231
220
  description: `Default preset for ${pageComponent.name}`,
232
- });
233
- const presetRes = await client.presets.create({ body: { preset: presetPayload } });
221
+ } } });
234
222
  presetId = presetRes.data!.preset!.id!;
235
223
 
236
224
  // 8. Story: body[0]=teaser (level 2), body[1]=section{items:[teaser]} (levels 2+3)
237
- const storyPayload = defineStoryCreate(pageComponent, {
225
+ const storyPayload: StoryCreate<Blocks> = {
238
226
  name: STORY_NAME,
239
227
  slug: STORY_SLUG,
240
228
  content: {
229
+ component: pageComponent.name,
241
230
  headline: 'Hello from e2e',
242
231
  rating: 42,
243
232
  is_featured: true,
@@ -269,7 +258,7 @@ describe('schema + mapi-client MAPI round-trip', () => {
269
258
  },
270
259
  ],
271
260
  },
272
- });
261
+ };
273
262
  const storyRes = await client.stories.create({ body: { story: storyPayload } });
274
263
  storyId = storyRes.data!.story!.id!;
275
264
  });
@@ -485,10 +474,11 @@ describe('schema + mapi-client MAPI round-trip', () => {
485
474
  });
486
475
 
487
476
  it('should round-trip story update correctly', async () => {
488
- const updatedPayload = defineStoryUpdate(pageComponent, {
477
+ const updatedPayload: StoryUpdate<Blocks> = {
489
478
  name: `${STORY_NAME} (Updated)`,
490
479
  slug: STORY_SLUG,
491
480
  content: {
481
+ component: pageComponent.name,
492
482
  headline: 'Updated headline',
493
483
  rating: 100,
494
484
  is_featured: false,
@@ -500,7 +490,7 @@ describe('schema + mapi-client MAPI round-trip', () => {
500
490
  category: 'design',
501
491
  any_blocks: [],
502
492
  },
503
- });
493
+ };
504
494
 
505
495
  await client.stories.update(storyId, { body: { story: updatedPayload } });
506
496
 
@@ -0,0 +1,74 @@
1
+ import { defineBlock, defineField } from '@storyblok/schema';
2
+ import { type Component as ComponentMapi, createManagementApiClient } from '@storyblok/management-api-client';
3
+ import { describe, expectTypeOf, it } from 'vitest';
4
+
5
+ // Nestable block — not a root story type
6
+ const teaserComponent = defineBlock({
7
+ name: 'teaser',
8
+ fields: [
9
+ defineField('text', { type: 'text' }),
10
+ defineField('image', { type: 'asset' }),
11
+ ],
12
+ });
13
+
14
+ // Root content type, not nestable
15
+ const _pageComponent = defineBlock({
16
+ name: 'page',
17
+ is_root: true,
18
+ is_nestable: false,
19
+ fields: [
20
+ defineField('headline', { type: 'text', required: true }),
21
+ defineField('body', { type: 'richtext' }),
22
+ defineField('teasers', { type: 'bloks', allow: [teaserComponent.name] }),
23
+ ],
24
+ });
25
+
26
+ const CLIENT_CONFIG = { personalAccessToken: 'test-token', spaceId: 12345 };
27
+
28
+ describe('components.get response shape', () => {
29
+ it('should return the wire Component (a `schema` record) from components.get', async () => {
30
+ const client = createManagementApiClient(CLIENT_CONFIG);
31
+ const result = await client.components.get(123);
32
+
33
+ if (result.data?.component) {
34
+ // components.get() returns the wire-shaped Component definition (a `schema`
35
+ // record), not the DSL `fields` block.
36
+ expectTypeOf(result.data.component.id).toEqualTypeOf<ComponentMapi['id']>();
37
+ expectTypeOf(result.data.component.name).toEqualTypeOf<ComponentMapi['name']>();
38
+ expectTypeOf(result.data.component).toHaveProperty('schema');
39
+ }
40
+ });
41
+ });
42
+
43
+ describe('defineBlock result used in .withTypes() interface', () => {
44
+ interface StoryblokTypes {
45
+ components: typeof _pageComponent | typeof teaserComponent;
46
+ }
47
+
48
+ it('should narrow story content to page or teaser after withTypes', async () => {
49
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
50
+ const result = await client.stories.get(123);
51
+
52
+ if (result.data?.story) {
53
+ // Only page is a root component (is_root: true); teaser is nestable-only
54
+ expectTypeOf(result.data.story.content.component).toEqualTypeOf<'page'>();
55
+ }
56
+ });
57
+
58
+ it('should narrow bloks field on page to whitelisted teasers', async () => {
59
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
60
+ const result = await client.stories.get(123);
61
+
62
+ if (result.data?.story) {
63
+ const story = result.data.story;
64
+ if (story.content.component === 'page') {
65
+ if (story.content.teasers) {
66
+ for (const teaser of story.content.teasers) {
67
+ // teasers whitelists only the teaser component
68
+ expectTypeOf(teaser.component).toEqualTypeOf<'teaser'>();
69
+ }
70
+ }
71
+ }
72
+ }
73
+ });
74
+ });
@@ -0,0 +1,212 @@
1
+ import { createManagementApiClient } from '@storyblok/management-api-client';
2
+ import { describe, expectTypeOf, it } from 'vitest';
3
+
4
+ const CLIENT_CONFIG = { personalAccessToken: 'test-token', spaceId: 12345 };
5
+
6
+ describe('datasources type tests', () => {
7
+ it('should return datasource in response from create', async () => {
8
+ const client = createManagementApiClient(CLIENT_CONFIG);
9
+ const result = await client.datasources.create({
10
+ body: { datasource: { name: 'Test', slug: 'test' } },
11
+ });
12
+ if (result.data) {
13
+ expectTypeOf(result.data).toHaveProperty('datasource');
14
+ }
15
+ });
16
+
17
+ it('should return datasource in response from get', async () => {
18
+ const client = createManagementApiClient(CLIENT_CONFIG);
19
+ const result = await client.datasources.get(1);
20
+ if (result.data) {
21
+ expectTypeOf(result.data).toHaveProperty('datasource');
22
+ }
23
+ });
24
+
25
+ it('should return datasources array in response from list', async () => {
26
+ const client = createManagementApiClient(CLIENT_CONFIG);
27
+ const result = await client.datasources.list();
28
+ if (result.data) {
29
+ expectTypeOf(result.data).toHaveProperty('datasources');
30
+ }
31
+ });
32
+ });
33
+
34
+ describe('datasource entries type tests', () => {
35
+ it('should return datasource_entry in response from create', async () => {
36
+ const client = createManagementApiClient(CLIENT_CONFIG);
37
+ const result = await client.datasourceEntries.create({
38
+ body: { datasource_entry: { name: 'red', value: '#ff0000', datasource_id: 42 } },
39
+ });
40
+ if (result.data) {
41
+ expectTypeOf(result.data).toHaveProperty('datasource_entry');
42
+ }
43
+ });
44
+
45
+ it('should return datasource_entry in response from get', async () => {
46
+ const client = createManagementApiClient(CLIENT_CONFIG);
47
+ const result = await client.datasourceEntries.get(1);
48
+ if (result.data) {
49
+ expectTypeOf(result.data).toHaveProperty('datasource_entry');
50
+ }
51
+ });
52
+
53
+ it('should return datasource_entries array in response from list', async () => {
54
+ const client = createManagementApiClient(CLIENT_CONFIG);
55
+ const result = await client.datasourceEntries.list();
56
+ if (result.data) {
57
+ expectTypeOf(result.data).toHaveProperty('datasource_entries');
58
+ }
59
+ });
60
+ });
61
+
62
+ describe('asset folders type tests', () => {
63
+ it('should return asset_folder in response from create', async () => {
64
+ const client = createManagementApiClient(CLIENT_CONFIG);
65
+ const result = await client.assetFolders.create({
66
+ body: { asset_folder: { name: 'Photos' } },
67
+ });
68
+ if (result.data) {
69
+ expectTypeOf(result.data).toHaveProperty('asset_folder');
70
+ }
71
+ });
72
+
73
+ it('should return asset_folder in response from get', async () => {
74
+ const client = createManagementApiClient(CLIENT_CONFIG);
75
+ const result = await client.assetFolders.get(1);
76
+ if (result.data) {
77
+ expectTypeOf(result.data).toHaveProperty('asset_folder');
78
+ }
79
+ });
80
+
81
+ it('should return asset_folders array in response from list', async () => {
82
+ const client = createManagementApiClient(CLIENT_CONFIG);
83
+ const result = await client.assetFolders.list();
84
+ if (result.data) {
85
+ expectTypeOf(result.data).toHaveProperty('asset_folders');
86
+ }
87
+ });
88
+ });
89
+
90
+ describe('component folders type tests', () => {
91
+ it('should return component_group in response from create', async () => {
92
+ const client = createManagementApiClient(CLIENT_CONFIG);
93
+ const result = await client.componentFolders.create({
94
+ body: { component_group: { name: 'Layout' } },
95
+ });
96
+ if (result.data) {
97
+ expectTypeOf(result.data).toHaveProperty('component_group');
98
+ }
99
+ });
100
+
101
+ it('should return component_group in response from get', async () => {
102
+ const client = createManagementApiClient(CLIENT_CONFIG);
103
+ const result = await client.componentFolders.get(1);
104
+ if (result.data) {
105
+ expectTypeOf(result.data).toHaveProperty('component_group');
106
+ }
107
+ });
108
+
109
+ it('should return component_groups array in response from list', async () => {
110
+ const client = createManagementApiClient(CLIENT_CONFIG);
111
+ const result = await client.componentFolders.list();
112
+ if (result.data) {
113
+ expectTypeOf(result.data).toHaveProperty('component_groups');
114
+ }
115
+ });
116
+ });
117
+
118
+ describe('internal tags type tests', () => {
119
+ it('should return internal_tag in response from create', async () => {
120
+ const client = createManagementApiClient(CLIENT_CONFIG);
121
+ const result = await client.internalTags.create({
122
+ body: { internal_tag: { name: 'hero' } },
123
+ });
124
+ if (result.data) {
125
+ expectTypeOf(result.data).toHaveProperty('internal_tag');
126
+ }
127
+ });
128
+
129
+ it('should return internal_tags array in response from list', async () => {
130
+ const client = createManagementApiClient(CLIENT_CONFIG);
131
+ const result = await client.internalTags.list();
132
+ if (result.data) {
133
+ expectTypeOf(result.data).toHaveProperty('internal_tags');
134
+ }
135
+ });
136
+ });
137
+
138
+ describe('presets type tests', () => {
139
+ it('should return preset in response from create', async () => {
140
+ const client = createManagementApiClient(CLIENT_CONFIG);
141
+ const result = await client.presets.create({
142
+ body: { preset: { name: 'Hero Dark', component_id: 42 } },
143
+ });
144
+ if (result.data) {
145
+ expectTypeOf(result.data).toHaveProperty('preset');
146
+ }
147
+ });
148
+
149
+ it('should return preset in response from get', async () => {
150
+ const client = createManagementApiClient(CLIENT_CONFIG);
151
+ const result = await client.presets.get(1);
152
+ if (result.data) {
153
+ expectTypeOf(result.data).toHaveProperty('preset');
154
+ }
155
+ });
156
+
157
+ it('should return presets array in response from list', async () => {
158
+ const client = createManagementApiClient(CLIENT_CONFIG);
159
+ const result = await client.presets.list();
160
+ if (result.data) {
161
+ expectTypeOf(result.data).toHaveProperty('presets');
162
+ }
163
+ });
164
+ });
165
+
166
+ describe('spaces type tests', () => {
167
+ it('should return space in response from create', async () => {
168
+ const client = createManagementApiClient(CLIENT_CONFIG);
169
+ const result = await client.spaces.create({
170
+ body: { space: { name: 'Test Space' } },
171
+ });
172
+ if (result.data) {
173
+ expectTypeOf(result.data).toHaveProperty('space');
174
+ }
175
+ });
176
+
177
+ it('should return space in response from get', async () => {
178
+ const client = createManagementApiClient(CLIENT_CONFIG);
179
+ const result = await client.spaces.get();
180
+ if (result.data) {
181
+ expectTypeOf(result.data).toHaveProperty('space');
182
+ }
183
+ });
184
+
185
+ it('should return spaces array in response from list', async () => {
186
+ const client = createManagementApiClient(CLIENT_CONFIG);
187
+ const result = await client.spaces.list();
188
+ if (result.data) {
189
+ expectTypeOf(result.data).toHaveProperty('spaces');
190
+ }
191
+ });
192
+ });
193
+
194
+ describe('users type tests', () => {
195
+ it('should return user in response from updateMe', async () => {
196
+ const client = createManagementApiClient(CLIENT_CONFIG);
197
+ const result = await client.users.updateMe({
198
+ body: { user: { firstname: 'Jane' } },
199
+ });
200
+ if (result.data) {
201
+ expectTypeOf(result.data).toHaveProperty('user');
202
+ }
203
+ });
204
+
205
+ it('should return user in response from me', async () => {
206
+ const client = createManagementApiClient(CLIENT_CONFIG);
207
+ const result = await client.users.me();
208
+ if (result.data) {
209
+ expectTypeOf(result.data).toHaveProperty('user');
210
+ }
211
+ });
212
+ });