@storyblok/management-api-client 0.3.0 → 1.0.0-alpha.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.
Files changed (300) hide show
  1. package/README.md +3 -1
  2. package/dist/client.cjs +190 -0
  3. package/dist/client.cjs.map +1 -0
  4. package/dist/client.d.cts +632 -0
  5. package/dist/client.d.mts +632 -0
  6. package/dist/client.mjs +189 -0
  7. package/dist/client.mjs.map +1 -0
  8. package/dist/error.cjs.map +1 -1
  9. package/dist/error.d.cts +12 -2
  10. package/dist/error.d.mts +12 -2
  11. package/dist/error.mjs.map +1 -1
  12. package/dist/generated/mapi/_internal.gen.d.cts +541 -0
  13. package/dist/generated/mapi/_internal.gen.d.mts +541 -0
  14. package/dist/generated/{shared → mapi}/client/client.gen.cjs +1 -1
  15. package/dist/generated/mapi/client/client.gen.cjs.map +1 -0
  16. package/dist/generated/{shared → mapi}/client/client.gen.mjs +1 -1
  17. package/dist/generated/mapi/client/client.gen.mjs.map +1 -0
  18. package/dist/generated/{shared → mapi}/client/types.gen.d.cts +1 -1
  19. package/dist/generated/{shared → mapi}/client/types.gen.d.mts +1 -1
  20. package/dist/generated/{shared → mapi}/client/utils.gen.cjs +1 -1
  21. package/dist/generated/mapi/client/utils.gen.cjs.map +1 -0
  22. package/dist/generated/{shared → mapi}/client/utils.gen.d.cts +1 -1
  23. package/dist/generated/{shared → mapi}/client/utils.gen.d.mts +1 -1
  24. package/dist/generated/{shared → mapi}/client/utils.gen.mjs +1 -1
  25. package/dist/generated/mapi/client/utils.gen.mjs.map +1 -0
  26. package/dist/generated/mapi/client.gen.cjs +10 -0
  27. package/dist/generated/mapi/client.gen.cjs.map +1 -0
  28. package/dist/generated/mapi/client.gen.mjs +10 -0
  29. package/dist/generated/mapi/client.gen.mjs.map +1 -0
  30. package/dist/generated/{shared → mapi}/core/auth.gen.cjs +1 -1
  31. package/dist/generated/mapi/core/auth.gen.cjs.map +1 -0
  32. package/dist/generated/{shared → mapi}/core/auth.gen.d.cts +1 -1
  33. package/dist/generated/{shared → mapi}/core/auth.gen.d.mts +1 -1
  34. package/dist/generated/{shared → mapi}/core/auth.gen.mjs +1 -1
  35. package/dist/generated/mapi/core/auth.gen.mjs.map +1 -0
  36. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.cjs +1 -1
  37. package/dist/generated/mapi/core/bodySerializer.gen.cjs.map +1 -0
  38. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.d.cts +1 -1
  39. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.d.mts +1 -1
  40. package/dist/generated/{shared → mapi}/core/bodySerializer.gen.mjs +1 -1
  41. package/dist/generated/mapi/core/bodySerializer.gen.mjs.map +1 -0
  42. package/dist/generated/{shared → mapi}/core/params.gen.cjs +1 -1
  43. package/dist/generated/mapi/core/params.gen.cjs.map +1 -0
  44. package/dist/generated/{shared → mapi}/core/params.gen.mjs +1 -1
  45. package/dist/generated/mapi/core/params.gen.mjs.map +1 -0
  46. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.cjs +1 -1
  47. package/dist/generated/mapi/core/pathSerializer.gen.cjs.map +1 -0
  48. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.d.cts +1 -1
  49. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.d.mts +1 -1
  50. package/dist/generated/{shared → mapi}/core/pathSerializer.gen.mjs +1 -1
  51. package/dist/generated/mapi/core/pathSerializer.gen.mjs.map +1 -0
  52. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.cjs +1 -1
  53. package/dist/generated/mapi/core/serverSentEvents.gen.cjs.map +1 -0
  54. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.d.cts +1 -1
  55. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.d.mts +1 -1
  56. package/dist/generated/{shared → mapi}/core/serverSentEvents.gen.mjs +1 -1
  57. package/dist/generated/mapi/core/serverSentEvents.gen.mjs.map +1 -0
  58. package/dist/generated/{shared → mapi}/core/types.gen.d.cts +1 -1
  59. package/dist/generated/{shared → mapi}/core/types.gen.d.mts +1 -1
  60. package/dist/generated/{shared → mapi}/core/utils.gen.cjs +1 -1
  61. package/dist/generated/mapi/core/utils.gen.cjs.map +1 -0
  62. package/dist/generated/{shared → mapi}/core/utils.gen.mjs +1 -1
  63. package/dist/generated/mapi/core/utils.gen.mjs.map +1 -0
  64. package/dist/generated/mapi/sdk.gen.cjs +1477 -0
  65. package/dist/generated/mapi/sdk.gen.cjs.map +1 -0
  66. package/dist/generated/mapi/sdk.gen.mjs +1399 -0
  67. package/dist/generated/mapi/sdk.gen.mjs.map +1 -0
  68. package/dist/generated/mapi/types-aliased.gen.d.cts +1428 -0
  69. package/dist/generated/mapi/types-aliased.gen.d.mts +1428 -0
  70. package/dist/generated/mapi/types.gen.d.cts +5075 -0
  71. package/dist/generated/mapi/types.gen.d.mts +5075 -0
  72. package/dist/generated/overlay/_internal.gen.d.cts +850 -0
  73. package/dist/generated/overlay/_internal.gen.d.mts +850 -0
  74. package/dist/generated/types/_utils.d.cts +7 -0
  75. package/dist/generated/types/_utils.d.mts +7 -0
  76. package/dist/generated/types/block.d.cts +30 -0
  77. package/dist/generated/types/block.d.mts +30 -0
  78. package/dist/generated/types/field.d.cts +75 -0
  79. package/dist/generated/types/field.d.mts +75 -0
  80. package/dist/generated/types/mapi-story.d.cts +29 -0
  81. package/dist/generated/types/mapi-story.d.mts +29 -0
  82. package/dist/index.cjs +3 -173
  83. package/dist/index.d.cts +13 -433
  84. package/dist/index.d.mts +13 -433
  85. package/dist/index.mjs +2 -171
  86. package/dist/resources/asset-folders.cjs +9 -9
  87. package/dist/resources/asset-folders.cjs.map +1 -1
  88. package/dist/resources/asset-folders.mjs +9 -9
  89. package/dist/resources/asset-folders.mjs.map +1 -1
  90. package/dist/resources/assets.cjs +57 -48
  91. package/dist/resources/assets.cjs.map +1 -1
  92. package/dist/resources/assets.d.cts +23 -27
  93. package/dist/resources/assets.d.mts +23 -27
  94. package/dist/resources/assets.mjs +57 -48
  95. package/dist/resources/assets.mjs.map +1 -1
  96. package/dist/resources/component-folders.cjs +9 -9
  97. package/dist/resources/component-folders.cjs.map +1 -1
  98. package/dist/resources/component-folders.mjs +9 -9
  99. package/dist/resources/component-folders.mjs.map +1 -1
  100. package/dist/resources/components.cjs +28 -20
  101. package/dist/resources/components.cjs.map +1 -1
  102. package/dist/resources/components.d.cts +76 -0
  103. package/dist/resources/components.d.mts +76 -0
  104. package/dist/resources/components.mjs +28 -20
  105. package/dist/resources/components.mjs.map +1 -1
  106. package/dist/resources/datasource-entries.cjs +28 -34
  107. package/dist/resources/datasource-entries.cjs.map +1 -1
  108. package/dist/resources/datasource-entries.mjs +29 -35
  109. package/dist/resources/datasource-entries.mjs.map +1 -1
  110. package/dist/resources/datasources.cjs +27 -9
  111. package/dist/resources/datasources.cjs.map +1 -1
  112. package/dist/resources/datasources.mjs +27 -9
  113. package/dist/resources/datasources.mjs.map +1 -1
  114. package/dist/resources/experiments.cjs +299 -0
  115. package/dist/resources/experiments.cjs.map +1 -0
  116. package/dist/resources/experiments.mjs +299 -0
  117. package/dist/resources/experiments.mjs.map +1 -0
  118. package/dist/resources/internal-tags.cjs +7 -7
  119. package/dist/resources/internal-tags.cjs.map +1 -1
  120. package/dist/resources/internal-tags.mjs +7 -7
  121. package/dist/resources/internal-tags.mjs.map +1 -1
  122. package/dist/resources/presets.cjs +9 -9
  123. package/dist/resources/presets.cjs.map +1 -1
  124. package/dist/resources/presets.mjs +9 -9
  125. package/dist/resources/presets.mjs.map +1 -1
  126. package/dist/resources/shared.cjs +15 -0
  127. package/dist/resources/shared.cjs.map +1 -1
  128. package/dist/resources/shared.mjs +15 -1
  129. package/dist/resources/shared.mjs.map +1 -1
  130. package/dist/resources/spaces.cjs +8 -7
  131. package/dist/resources/spaces.cjs.map +1 -1
  132. package/dist/resources/spaces.d.cts +8 -0
  133. package/dist/resources/spaces.d.mts +7 -0
  134. package/dist/resources/spaces.mjs +8 -7
  135. package/dist/resources/spaces.mjs.map +1 -1
  136. package/dist/resources/stories.cjs +20 -16
  137. package/dist/resources/stories.cjs.map +1 -1
  138. package/dist/resources/stories.d.cts +93 -0
  139. package/dist/resources/stories.d.mts +93 -0
  140. package/dist/resources/stories.mjs +20 -16
  141. package/dist/resources/stories.mjs.map +1 -1
  142. package/dist/resources/users.cjs +3 -3
  143. package/dist/resources/users.cjs.map +1 -1
  144. package/dist/resources/users.mjs +3 -3
  145. package/dist/resources/users.mjs.map +1 -1
  146. package/dist/utils/query-serializer.cjs +54 -0
  147. package/dist/utils/query-serializer.cjs.map +1 -0
  148. package/dist/utils/query-serializer.mjs +54 -0
  149. package/dist/utils/query-serializer.mjs.map +1 -0
  150. package/package.json +16 -14
  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/playground/integration-tests/test/setup.e2e.ts +11 -0
  159. package/playground/integration-tests/test/specs/mapi-round-trip.spec.e2e.ts +520 -0
  160. package/playground/integration-tests/test/types/components.test-d.ts +113 -0
  161. package/playground/integration-tests/test/types/resources.test-d.ts +364 -0
  162. package/playground/integration-tests/test/types/stories.test-d.ts +306 -0
  163. package/playground/integration-tests/vitest.config.e2e.ts +25 -0
  164. package/playground/integration-tests/vitest.config.ts +13 -0
  165. package/test/GUIDE.md +59 -0
  166. package/vitest.config.ts +5 -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 -156
  176. package/dist/generated/asset_folders/types.gen.d.mts +0 -156
  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 -415
  186. package/dist/generated/assets/types.gen.d.mts +0 -415
  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 -118
  196. package/dist/generated/component_folders/types.gen.d.mts +0 -118
  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/components/types.gen.d.cts +0 -855
  206. package/dist/generated/components/types.gen.d.mts +0 -855
  207. package/dist/generated/datasource_entries/client.gen.cjs +0 -10
  208. package/dist/generated/datasource_entries/client.gen.cjs.map +0 -1
  209. package/dist/generated/datasource_entries/client.gen.mjs +0 -10
  210. package/dist/generated/datasource_entries/client.gen.mjs.map +0 -1
  211. package/dist/generated/datasource_entries/sdk.gen.cjs +0 -89
  212. package/dist/generated/datasource_entries/sdk.gen.cjs.map +0 -1
  213. package/dist/generated/datasource_entries/sdk.gen.mjs +0 -85
  214. package/dist/generated/datasource_entries/sdk.gen.mjs.map +0 -1
  215. package/dist/generated/datasource_entries/types.gen.d.cts +0 -156
  216. package/dist/generated/datasource_entries/types.gen.d.mts +0 -156
  217. package/dist/generated/datasources/client.gen.cjs +0 -10
  218. package/dist/generated/datasources/client.gen.cjs.map +0 -1
  219. package/dist/generated/datasources/client.gen.mjs +0 -10
  220. package/dist/generated/datasources/client.gen.mjs.map +0 -1
  221. package/dist/generated/datasources/sdk.gen.cjs +0 -89
  222. package/dist/generated/datasources/sdk.gen.cjs.map +0 -1
  223. package/dist/generated/datasources/sdk.gen.mjs +0 -85
  224. package/dist/generated/datasources/sdk.gen.mjs.map +0 -1
  225. package/dist/generated/datasources/types.gen.d.cts +0 -186
  226. package/dist/generated/datasources/types.gen.d.mts +0 -186
  227. package/dist/generated/internal_tags/client.gen.cjs +0 -10
  228. package/dist/generated/internal_tags/client.gen.cjs.map +0 -1
  229. package/dist/generated/internal_tags/client.gen.mjs +0 -10
  230. package/dist/generated/internal_tags/client.gen.mjs.map +0 -1
  231. package/dist/generated/internal_tags/sdk.gen.cjs +0 -74
  232. package/dist/generated/internal_tags/sdk.gen.cjs.map +0 -1
  233. package/dist/generated/internal_tags/sdk.gen.mjs +0 -71
  234. package/dist/generated/internal_tags/sdk.gen.mjs.map +0 -1
  235. package/dist/generated/internal_tags/types.gen.d.cts +0 -106
  236. package/dist/generated/internal_tags/types.gen.d.mts +0 -106
  237. package/dist/generated/presets/client.gen.cjs +0 -10
  238. package/dist/generated/presets/client.gen.cjs.map +0 -1
  239. package/dist/generated/presets/client.gen.mjs +0 -10
  240. package/dist/generated/presets/client.gen.mjs.map +0 -1
  241. package/dist/generated/presets/sdk.gen.cjs +0 -99
  242. package/dist/generated/presets/sdk.gen.cjs.map +0 -1
  243. package/dist/generated/presets/sdk.gen.mjs +0 -95
  244. package/dist/generated/presets/sdk.gen.mjs.map +0 -1
  245. package/dist/generated/presets/types.gen.d.cts +0 -176
  246. package/dist/generated/presets/types.gen.d.mts +0 -176
  247. package/dist/generated/shared/client/client.gen.cjs.map +0 -1
  248. package/dist/generated/shared/client/client.gen.mjs.map +0 -1
  249. package/dist/generated/shared/client/utils.gen.cjs.map +0 -1
  250. package/dist/generated/shared/client/utils.gen.mjs.map +0 -1
  251. package/dist/generated/shared/core/auth.gen.cjs.map +0 -1
  252. package/dist/generated/shared/core/auth.gen.mjs.map +0 -1
  253. package/dist/generated/shared/core/bodySerializer.gen.cjs.map +0 -1
  254. package/dist/generated/shared/core/bodySerializer.gen.mjs.map +0 -1
  255. package/dist/generated/shared/core/params.gen.cjs.map +0 -1
  256. package/dist/generated/shared/core/params.gen.mjs.map +0 -1
  257. package/dist/generated/shared/core/pathSerializer.gen.cjs.map +0 -1
  258. package/dist/generated/shared/core/pathSerializer.gen.mjs.map +0 -1
  259. package/dist/generated/shared/core/serverSentEvents.gen.cjs.map +0 -1
  260. package/dist/generated/shared/core/serverSentEvents.gen.mjs.map +0 -1
  261. package/dist/generated/shared/core/utils.gen.cjs.map +0 -1
  262. package/dist/generated/shared/core/utils.gen.mjs.map +0 -1
  263. package/dist/generated/spaces/client.gen.cjs +0 -10
  264. package/dist/generated/spaces/client.gen.cjs.map +0 -1
  265. package/dist/generated/spaces/client.gen.mjs +0 -10
  266. package/dist/generated/spaces/client.gen.mjs.map +0 -1
  267. package/dist/generated/spaces/sdk.gen.cjs +0 -99
  268. package/dist/generated/spaces/sdk.gen.cjs.map +0 -1
  269. package/dist/generated/spaces/sdk.gen.mjs +0 -95
  270. package/dist/generated/spaces/sdk.gen.mjs.map +0 -1
  271. package/dist/generated/spaces/types.gen.d.cts +0 -544
  272. package/dist/generated/spaces/types.gen.d.mts +0 -544
  273. package/dist/generated/stories/client.gen.cjs +0 -10
  274. package/dist/generated/stories/client.gen.cjs.map +0 -1
  275. package/dist/generated/stories/client.gen.mjs +0 -10
  276. package/dist/generated/stories/client.gen.mjs.map +0 -1
  277. package/dist/generated/stories/sdk.gen.cjs +0 -138
  278. package/dist/generated/stories/sdk.gen.cjs.map +0 -1
  279. package/dist/generated/stories/sdk.gen.mjs +0 -131
  280. package/dist/generated/stories/sdk.gen.mjs.map +0 -1
  281. package/dist/generated/stories/types.gen.d.cts +0 -1306
  282. package/dist/generated/stories/types.gen.d.mts +0 -1306
  283. package/dist/generated/users/client.gen.cjs +0 -10
  284. package/dist/generated/users/client.gen.cjs.map +0 -1
  285. package/dist/generated/users/client.gen.mjs +0 -10
  286. package/dist/generated/users/client.gen.mjs.map +0 -1
  287. package/dist/generated/users/sdk.gen.cjs +0 -44
  288. package/dist/generated/users/sdk.gen.cjs.map +0 -1
  289. package/dist/generated/users/sdk.gen.mjs +0 -43
  290. package/dist/generated/users/sdk.gen.mjs.map +0 -1
  291. package/dist/generated/users/types.gen.d.cts +0 -348
  292. package/dist/generated/users/types.gen.d.mts +0 -348
  293. package/dist/index.cjs.map +0 -1
  294. package/dist/index.mjs.map +0 -1
  295. package/dist/types.d.cts +0 -130
  296. package/dist/types.d.mts +0 -130
  297. /package/dist/generated/{shared → mapi}/client/client.gen.d.mts +0 -0
  298. /package/dist/generated/{shared → mapi}/client/index.cjs +0 -0
  299. /package/dist/generated/{shared → mapi}/client/index.d.mts +0 -0
  300. /package/dist/generated/{shared → mapi}/client/index.mjs +0 -0
@@ -0,0 +1,364 @@
1
+ import {
2
+ defineAssetFolderCreate,
3
+ defineAssetFolderUpdate,
4
+ defineBlockFolderCreate,
5
+ defineBlockFolderUpdate,
6
+ defineDatasourceCreate,
7
+ defineDatasourceEntryCreate,
8
+ defineDatasourceEntryUpdate,
9
+ defineDatasourceUpdate,
10
+ defineInternalTagCreate,
11
+ defineInternalTagUpdate,
12
+ definePresetCreate,
13
+ definePresetUpdate,
14
+ defineSpaceCreate,
15
+ defineSpaceUpdate,
16
+ defineUserUpdate,
17
+ } from '@storyblok/schema';
18
+ import { createManagementApiClient } from '@storyblok/management-api-client';
19
+ import { describe, expectTypeOf, it } from 'vitest';
20
+
21
+ const CLIENT_CONFIG = { personalAccessToken: 'test-token', spaceId: 12345 };
22
+
23
+ describe('datasources type tests', () => {
24
+ it('should produce a defineDatasourceCreate result assignable to datasources.create body', () => {
25
+ const payload = defineDatasourceCreate({ name: 'Categories', slug: 'categories' });
26
+
27
+ type CreateBody = Parameters<ReturnType<typeof createManagementApiClient>['datasources']['create']>[0]['body'];
28
+ type InnerType = NonNullable<CreateBody['datasource']>;
29
+
30
+ expectTypeOf(payload).toExtend<InnerType>();
31
+ });
32
+
33
+ it('should produce a defineDatasourceUpdate result assignable to datasources.update body', () => {
34
+ const payload = defineDatasourceUpdate({ name: 'Updated Categories' });
35
+
36
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['datasources']['update']>[1]['body'];
37
+ type InnerType = NonNullable<UpdateBody['datasource']>;
38
+
39
+ expectTypeOf(payload).toExtend<InnerType>();
40
+ });
41
+
42
+ it('should return datasource in response from create', async () => {
43
+ const client = createManagementApiClient(CLIENT_CONFIG);
44
+ const result = await client.datasources.create({
45
+ body: { datasource: { name: 'Test', slug: 'test' } },
46
+ });
47
+ if (result.data) {
48
+ expectTypeOf(result.data).toHaveProperty('datasource');
49
+ }
50
+ });
51
+
52
+ it('should return datasource in response from get', async () => {
53
+ const client = createManagementApiClient(CLIENT_CONFIG);
54
+ const result = await client.datasources.get(1);
55
+ if (result.data) {
56
+ expectTypeOf(result.data).toHaveProperty('datasource');
57
+ }
58
+ });
59
+
60
+ it('should return datasources array in response from list', async () => {
61
+ const client = createManagementApiClient(CLIENT_CONFIG);
62
+ const result = await client.datasources.list();
63
+ if (result.data) {
64
+ expectTypeOf(result.data).toHaveProperty('datasources');
65
+ }
66
+ });
67
+ });
68
+
69
+ describe('datasource entries type tests', () => {
70
+ it('should produce a defineDatasourceEntryCreate result assignable to datasourceEntries.create body', () => {
71
+ const payload = defineDatasourceEntryCreate({ name: 'red', value: '#ff0000', datasource_id: 42 });
72
+
73
+ type CreateBody = Parameters<ReturnType<typeof createManagementApiClient>['datasourceEntries']['create']>[0]['body'];
74
+ type InnerType = NonNullable<CreateBody['datasource_entry']>;
75
+
76
+ expectTypeOf(payload).toExtend<InnerType>();
77
+ });
78
+
79
+ it('should produce a defineDatasourceEntryUpdate result assignable to datasourceEntries.update body', () => {
80
+ const payload = defineDatasourceEntryUpdate({ value: '#00ff00' });
81
+
82
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['datasourceEntries']['update']>[1]['body'];
83
+ type InnerType = NonNullable<UpdateBody['datasource_entry']>;
84
+
85
+ expectTypeOf(payload).toExtend<InnerType>();
86
+ });
87
+
88
+ it('should return datasource_entry in response from create', async () => {
89
+ const client = createManagementApiClient(CLIENT_CONFIG);
90
+ const result = await client.datasourceEntries.create({
91
+ body: { datasource_entry: { name: 'red', value: '#ff0000', datasource_id: 42 } },
92
+ });
93
+ if (result.data) {
94
+ expectTypeOf(result.data).toHaveProperty('datasource_entry');
95
+ }
96
+ });
97
+
98
+ it('should return datasource_entry in response from get', async () => {
99
+ const client = createManagementApiClient(CLIENT_CONFIG);
100
+ const result = await client.datasourceEntries.get(1);
101
+ if (result.data) {
102
+ expectTypeOf(result.data).toHaveProperty('datasource_entry');
103
+ }
104
+ });
105
+
106
+ it('should return datasource_entries array in response from list', async () => {
107
+ const client = createManagementApiClient(CLIENT_CONFIG);
108
+ const result = await client.datasourceEntries.list();
109
+ if (result.data) {
110
+ expectTypeOf(result.data).toHaveProperty('datasource_entries');
111
+ }
112
+ });
113
+ });
114
+
115
+ describe('asset folders type tests', () => {
116
+ it('should produce a defineAssetFolderCreate result assignable to assetFolders.create body', () => {
117
+ const payload = defineAssetFolderCreate({ name: 'Images' });
118
+
119
+ type CreateBody = Parameters<ReturnType<typeof createManagementApiClient>['assetFolders']['create']>[0]['body'];
120
+ type InnerType = NonNullable<CreateBody['asset_folder']>;
121
+
122
+ expectTypeOf(payload).toExtend<InnerType>();
123
+ });
124
+
125
+ it('should produce a defineAssetFolderUpdate result assignable to assetFolders.update body', () => {
126
+ const payload = defineAssetFolderUpdate({ name: 'Updated Images' });
127
+
128
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['assetFolders']['update']>[1]['body'];
129
+ type InnerType = NonNullable<UpdateBody['asset_folder']>;
130
+
131
+ expectTypeOf(payload).toExtend<InnerType>();
132
+ });
133
+
134
+ it('should return asset_folder in response from create', async () => {
135
+ const client = createManagementApiClient(CLIENT_CONFIG);
136
+ const result = await client.assetFolders.create({
137
+ body: { asset_folder: { name: 'Photos' } },
138
+ });
139
+ if (result.data) {
140
+ expectTypeOf(result.data).toHaveProperty('asset_folder');
141
+ }
142
+ });
143
+
144
+ it('should return asset_folder in response from get', async () => {
145
+ const client = createManagementApiClient(CLIENT_CONFIG);
146
+ const result = await client.assetFolders.get(1);
147
+ if (result.data) {
148
+ expectTypeOf(result.data).toHaveProperty('asset_folder');
149
+ }
150
+ });
151
+
152
+ it('should return asset_folders array in response from list', async () => {
153
+ const client = createManagementApiClient(CLIENT_CONFIG);
154
+ const result = await client.assetFolders.list();
155
+ if (result.data) {
156
+ expectTypeOf(result.data).toHaveProperty('asset_folders');
157
+ }
158
+ });
159
+ });
160
+
161
+ describe('component folders type tests', () => {
162
+ it('should produce a defineBlockFolderCreate result assignable to componentFolders.create body', () => {
163
+ const payload = defineBlockFolderCreate({ name: 'Layout' });
164
+
165
+ type CreateBody = Parameters<ReturnType<typeof createManagementApiClient>['componentFolders']['create']>[0]['body'];
166
+ type InnerType = NonNullable<CreateBody['component_group']>;
167
+
168
+ expectTypeOf(payload).toExtend<InnerType>();
169
+ });
170
+
171
+ it('should produce a defineBlockFolderUpdate result assignable to componentFolders.update body', () => {
172
+ const payload = defineBlockFolderUpdate({ name: 'Updated Layout' });
173
+
174
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['componentFolders']['update']>[1]['body'];
175
+ type InnerType = NonNullable<UpdateBody['component_group']>;
176
+
177
+ expectTypeOf(payload).toExtend<InnerType>();
178
+ });
179
+
180
+ it('should return component_group in response from create', async () => {
181
+ const client = createManagementApiClient(CLIENT_CONFIG);
182
+ const result = await client.componentFolders.create({
183
+ body: { component_group: { name: 'Layout' } },
184
+ });
185
+ if (result.data) {
186
+ expectTypeOf(result.data).toHaveProperty('component_group');
187
+ }
188
+ });
189
+
190
+ it('should return component_group in response from get', async () => {
191
+ const client = createManagementApiClient(CLIENT_CONFIG);
192
+ const result = await client.componentFolders.get(1);
193
+ if (result.data) {
194
+ expectTypeOf(result.data).toHaveProperty('component_group');
195
+ }
196
+ });
197
+
198
+ it('should return component_groups array in response from list', async () => {
199
+ const client = createManagementApiClient(CLIENT_CONFIG);
200
+ const result = await client.componentFolders.list();
201
+ if (result.data) {
202
+ expectTypeOf(result.data).toHaveProperty('component_groups');
203
+ }
204
+ });
205
+ });
206
+
207
+ describe('internal tags type tests', () => {
208
+ it('should produce a defineInternalTagCreate result assignable to internalTags.create body', () => {
209
+ const payload = defineInternalTagCreate({ name: 'hero', object_type: 'asset' });
210
+
211
+ type CreateBody = Parameters<ReturnType<typeof createManagementApiClient>['internalTags']['create']>[0]['body'];
212
+ type InnerType = NonNullable<CreateBody['internal_tag']>;
213
+
214
+ expectTypeOf(payload).toExtend<InnerType>();
215
+ });
216
+
217
+ it('should produce a defineInternalTagUpdate result assignable to internalTags.update body', () => {
218
+ const payload = defineInternalTagUpdate({ name: 'hero-image' });
219
+
220
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['internalTags']['update']>[1]['body'];
221
+ type InnerType = NonNullable<UpdateBody['internal_tag']>;
222
+
223
+ expectTypeOf(payload).toExtend<InnerType>();
224
+ });
225
+
226
+ it('should return internal_tag in response from create', async () => {
227
+ const client = createManagementApiClient(CLIENT_CONFIG);
228
+ const result = await client.internalTags.create({
229
+ body: { internal_tag: { name: 'hero' } },
230
+ });
231
+ if (result.data) {
232
+ expectTypeOf(result.data).toHaveProperty('internal_tag');
233
+ }
234
+ });
235
+
236
+ it('should return internal_tags array in response from list', async () => {
237
+ const client = createManagementApiClient(CLIENT_CONFIG);
238
+ const result = await client.internalTags.list();
239
+ if (result.data) {
240
+ expectTypeOf(result.data).toHaveProperty('internal_tags');
241
+ }
242
+ });
243
+ });
244
+
245
+ describe('presets type tests', () => {
246
+ it('should produce a definePresetCreate result assignable to presets.create body', () => {
247
+ const payload = definePresetCreate({ name: 'Hero Dark', component_id: 42 });
248
+
249
+ type CreateBody = Parameters<ReturnType<typeof createManagementApiClient>['presets']['create']>[0]['body'];
250
+ type InnerType = NonNullable<CreateBody['preset']>;
251
+
252
+ expectTypeOf(payload).toExtend<InnerType>();
253
+ });
254
+
255
+ it('should produce a definePresetUpdate result assignable to presets.update body', () => {
256
+ const payload = definePresetUpdate({ name: 'Hero Light' });
257
+
258
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['presets']['update']>[1]['body'];
259
+ type InnerType = NonNullable<UpdateBody['preset']>;
260
+
261
+ expectTypeOf(payload).toExtend<InnerType>();
262
+ });
263
+
264
+ it('should return preset in response from create', async () => {
265
+ const client = createManagementApiClient(CLIENT_CONFIG);
266
+ const result = await client.presets.create({
267
+ body: { preset: { name: 'Hero Dark', component_id: 42 } },
268
+ });
269
+ if (result.data) {
270
+ expectTypeOf(result.data).toHaveProperty('preset');
271
+ }
272
+ });
273
+
274
+ it('should return preset in response from get', async () => {
275
+ const client = createManagementApiClient(CLIENT_CONFIG);
276
+ const result = await client.presets.get(1);
277
+ if (result.data) {
278
+ expectTypeOf(result.data).toHaveProperty('preset');
279
+ }
280
+ });
281
+
282
+ it('should return presets array in response from list', async () => {
283
+ const client = createManagementApiClient(CLIENT_CONFIG);
284
+ const result = await client.presets.list();
285
+ if (result.data) {
286
+ expectTypeOf(result.data).toHaveProperty('presets');
287
+ }
288
+ });
289
+ });
290
+
291
+ describe('spaces type tests', () => {
292
+ it('should produce a defineSpaceCreate result assignable to spaces.create body', () => {
293
+ const payload = defineSpaceCreate({ name: 'My New Space' });
294
+
295
+ type CreateBody = Parameters<ReturnType<typeof createManagementApiClient>['spaces']['create']>[0]['body'];
296
+ type InnerType = CreateBody['space'];
297
+
298
+ expectTypeOf(payload).toExtend<InnerType>();
299
+ });
300
+
301
+ it('should produce a defineSpaceUpdate result assignable to spaces.update body', () => {
302
+ const payload = defineSpaceUpdate({ name: 'Updated Space Name' });
303
+
304
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['spaces']['update']>[0]['body'];
305
+ type InnerType = UpdateBody['space'];
306
+
307
+ expectTypeOf(payload).toExtend<InnerType>();
308
+ });
309
+
310
+ it('should return space in response from create', async () => {
311
+ const client = createManagementApiClient(CLIENT_CONFIG);
312
+ const result = await client.spaces.create({
313
+ body: { space: { name: 'Test Space' } },
314
+ });
315
+ if (result.data) {
316
+ expectTypeOf(result.data).toHaveProperty('space');
317
+ }
318
+ });
319
+
320
+ it('should return space in response from get', async () => {
321
+ const client = createManagementApiClient(CLIENT_CONFIG);
322
+ const result = await client.spaces.get();
323
+ if (result.data) {
324
+ expectTypeOf(result.data).toHaveProperty('space');
325
+ }
326
+ });
327
+
328
+ it('should return spaces array in response from list', async () => {
329
+ const client = createManagementApiClient(CLIENT_CONFIG);
330
+ const result = await client.spaces.list();
331
+ if (result.data) {
332
+ expectTypeOf(result.data).toHaveProperty('spaces');
333
+ }
334
+ });
335
+ });
336
+
337
+ describe('users type tests', () => {
338
+ it('should produce a defineUserUpdate result assignable to users.updateMe body', () => {
339
+ const payload = defineUserUpdate({ firstname: 'Jane', lastname: 'Doe' });
340
+
341
+ type UpdateBody = Parameters<ReturnType<typeof createManagementApiClient>['users']['updateMe']>[0]['body'];
342
+ type InnerType = UpdateBody['user'];
343
+
344
+ expectTypeOf(payload).toExtend<InnerType>();
345
+ });
346
+
347
+ it('should return user in response from updateMe', async () => {
348
+ const client = createManagementApiClient(CLIENT_CONFIG);
349
+ const result = await client.users.updateMe({
350
+ body: { user: { firstname: 'Jane' } },
351
+ });
352
+ if (result.data) {
353
+ expectTypeOf(result.data).toHaveProperty('user');
354
+ }
355
+ });
356
+
357
+ it('should return user in response from me', async () => {
358
+ const client = createManagementApiClient(CLIENT_CONFIG);
359
+ const result = await client.users.me();
360
+ if (result.data) {
361
+ expectTypeOf(result.data).toHaveProperty('user');
362
+ }
363
+ });
364
+ });
@@ -0,0 +1,306 @@
1
+ import { defineBlock, defineField, defineStoryCreate, defineStoryUpdate } from '@storyblok/schema';
2
+ import { createManagementApiClient, type Story as StoryMapi } 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
+ schema: [
9
+ defineField('text', { type: 'text' }),
10
+ defineField('image', { type: 'asset' }),
11
+ ],
12
+ id: 0,
13
+ created_at: '',
14
+ updated_at: '',
15
+ });
16
+
17
+ // Root content type that is also nestable (can appear as both a story and inside bloks)
18
+ const heroComponent = defineBlock({
19
+ name: 'hero',
20
+ is_root: true,
21
+ schema: [
22
+ defineField('title', { type: 'text' }),
23
+ defineField('count', { type: 'number' }),
24
+ // bloks field without a whitelist — resolves to nestable components only
25
+ defineField('sections', { type: 'bloks' }),
26
+ ],
27
+ id: 0,
28
+ created_at: '',
29
+ updated_at: '',
30
+ });
31
+
32
+ // Root content type, not nestable
33
+ const _pageComponent = defineBlock({
34
+ name: 'page',
35
+ is_root: true,
36
+ is_nestable: false,
37
+ schema: [
38
+ defineField('headline', { type: 'text' }),
39
+ defineField('body', { type: 'richtext' }),
40
+ defineField('teasers', { type: 'bloks', component_whitelist: [teaserComponent.name] }),
41
+ defineField('hero', { type: 'bloks', component_whitelist: [heroComponent.name] }),
42
+ defineField('blocks', { type: 'bloks', component_whitelist: [heroComponent.name, teaserComponent.name] }),
43
+ ],
44
+ id: 0,
45
+ created_at: '',
46
+ updated_at: '',
47
+ });
48
+
49
+ const CLIENT_CONFIG = { personalAccessToken: 'test-token', spaceId: 12345 };
50
+
51
+ interface StoryblokTypes {
52
+ components: typeof _pageComponent | typeof heroComponent | typeof teaserComponent;
53
+ }
54
+
55
+ describe('createManagementApiClient without .withTypes()', () => {
56
+ it('should return StoryMapi from stories.get()', async () => {
57
+ const client = createManagementApiClient(CLIENT_CONFIG);
58
+ const result = await client.stories.get(123);
59
+ if (result.data) {
60
+ expectTypeOf(result.data.story).toEqualTypeOf<StoryMapi | undefined>();
61
+ }
62
+ });
63
+
64
+ it('should return StoryMapi array from stories.list()', async () => {
65
+ const client = createManagementApiClient(CLIENT_CONFIG);
66
+ const result = await client.stories.list();
67
+ if (result.data) {
68
+ expectTypeOf(result.data.stories).toEqualTypeOf<StoryMapi[] | undefined>();
69
+ }
70
+ });
71
+
72
+ it('should infer ThrowOnError from config without .withTypes()', async () => {
73
+ const client = createManagementApiClient({ ...CLIENT_CONFIG, throwOnError: true });
74
+ const result = await client.stories.get(123);
75
+ // ThrowOnError=true means data is always defined (no optional chaining needed)
76
+ expectTypeOf(result.data.story).toEqualTypeOf<StoryMapi | undefined>();
77
+ });
78
+
79
+ it('should allow per-call throwOnError override to false', async () => {
80
+ const client = createManagementApiClient({ ...CLIENT_CONFIG, throwOnError: true });
81
+ const result = await client.stories.get(123, { throwOnError: false });
82
+ if (result.data) {
83
+ expectTypeOf(result.data.story).toEqualTypeOf<StoryMapi | undefined>();
84
+ }
85
+ });
86
+ });
87
+
88
+ describe('createManagementApiClient with .withTypes()', () => {
89
+ it('should narrow page content fields after component discriminant check on get()', async () => {
90
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
91
+ const result = await client.stories.get(123);
92
+ if (result.data?.story) {
93
+ const story = result.data.story;
94
+ if (story.content.component === 'page') {
95
+ expectTypeOf(story.content.headline).toEqualTypeOf<string | null | undefined>();
96
+ expectTypeOf(story.content.component).toEqualTypeOf<'page'>();
97
+ }
98
+ }
99
+ });
100
+
101
+ it('should narrow hero content fields after component discriminant check on get()', async () => {
102
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
103
+ const result = await client.stories.get(123);
104
+ if (result.data?.story) {
105
+ const story = result.data.story;
106
+ if (story.content.component === 'hero') {
107
+ expectTypeOf(story.content.title).toEqualTypeOf<string | null | undefined>();
108
+ expectTypeOf(story.content.count).toEqualTypeOf<number | null | undefined>();
109
+ expectTypeOf(story.content.component).toEqualTypeOf<'hero'>();
110
+ }
111
+ }
112
+ });
113
+
114
+ it('should have union of literal component names on content', async () => {
115
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
116
+ const result = await client.stories.get(123);
117
+ if (result.data?.story) {
118
+ // Only root components (is_root: true) appear in story content
119
+ expectTypeOf(result.data.story.content.component).toEqualTypeOf<'page' | 'hero'>();
120
+ }
121
+ });
122
+
123
+ it('should narrow discriminated union in stories.list()', async () => {
124
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
125
+ const result = await client.stories.list();
126
+ if (result.data?.stories) {
127
+ for (const story of result.data.stories) {
128
+ if (story.content.component === 'page') {
129
+ expectTypeOf(story.content.headline).toEqualTypeOf<string | null | undefined>();
130
+ }
131
+ if (story.content.component === 'hero') {
132
+ expectTypeOf(story.content.count).toEqualTypeOf<number | null | undefined>();
133
+ }
134
+ }
135
+ }
136
+ });
137
+
138
+ it('should narrow bloks field on page to whitelisted component names', async () => {
139
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
140
+ const result = await client.stories.get(123);
141
+ if (result.data?.story) {
142
+ const story = result.data.story;
143
+ if (story.content.component === 'page') {
144
+ if (story.content.teasers) {
145
+ for (const teaser of story.content.teasers) {
146
+ expectTypeOf(teaser.component).toEqualTypeOf<'teaser'>();
147
+ expectTypeOf(teaser.text).toEqualTypeOf<string | null | undefined>();
148
+ }
149
+ }
150
+ if (story.content.hero) {
151
+ for (const hero of story.content.hero) {
152
+ expectTypeOf(hero.component).toEqualTypeOf<'hero'>();
153
+ expectTypeOf(hero.count).toEqualTypeOf<number | null | undefined>();
154
+ }
155
+ }
156
+ if (story.content.blocks) {
157
+ for (const blok of story.content.blocks) {
158
+ // blocks whitelists both hero and teaser → union of the two
159
+ expectTypeOf(blok.component).toEqualTypeOf<'hero' | 'teaser'>();
160
+ }
161
+ }
162
+ }
163
+ }
164
+ });
165
+
166
+ it('should fall back to all schema components for bloks field without whitelist', async () => {
167
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
168
+ const result = await client.stories.get(123);
169
+ if (result.data?.story) {
170
+ const story = result.data.story;
171
+ if (story.content.component === 'hero' && story.content.sections) {
172
+ // sections has no component_whitelist — falls back to nestable (is_nestable: true)
173
+ // components only; page has is_nestable: false, so it is excluded
174
+ type Sections = typeof story.content.sections;
175
+ expectTypeOf<Sections[number]['component']>().toEqualTypeOf<'hero' | 'teaser'>();
176
+ }
177
+ }
178
+ });
179
+
180
+ it('should infer ThrowOnError alongside .withTypes()', async () => {
181
+ const client = createManagementApiClient({ ...CLIENT_CONFIG, throwOnError: true }).withTypes<StoryblokTypes>();
182
+ const result = await client.stories.get(123);
183
+ if (result.data.story) {
184
+ // ThrowOnError=true keeps data defined; only root components appear in content
185
+ expectTypeOf(result.data.story.content.component).toEqualTypeOf<'page' | 'hero'>();
186
+ }
187
+ });
188
+
189
+ it('should allow per-call throwOnError override to false alongside .withTypes()', async () => {
190
+ const client = createManagementApiClient({ ...CLIENT_CONFIG, throwOnError: true }).withTypes<StoryblokTypes>();
191
+ const result = await client.stories.get(123, { throwOnError: false });
192
+ if (result.data?.story) {
193
+ expectTypeOf(result.data.story.content.component).toEqualTypeOf<'page' | 'hero'>();
194
+ }
195
+ });
196
+
197
+ it('should narrow story in create() response', async () => {
198
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
199
+ const result = await client.stories.create({
200
+ body: { story: { name: 'My Page', content: { component: 'page' } } },
201
+ });
202
+ if (result.data?.story) {
203
+ const story = result.data.story;
204
+ if (story.content.component === 'page') {
205
+ expectTypeOf(story.content.headline).toEqualTypeOf<string | null | undefined>();
206
+ }
207
+ }
208
+ });
209
+
210
+ it('should narrow story in update() response', async () => {
211
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
212
+ const result = await client.stories.update(123, {
213
+ body: { story: { content: { component: 'hero' } } },
214
+ });
215
+ if (result.data?.story) {
216
+ const story = result.data.story;
217
+ if (story.content.component === 'hero') {
218
+ expectTypeOf(story.content.title).toEqualTypeOf<string | null | undefined>();
219
+ }
220
+ }
221
+ });
222
+
223
+ it('should narrow create() body story.content to component union', async () => {
224
+ const _client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
225
+ type CreateBodyType = Parameters<typeof _client.stories.create>[0]['body'];
226
+ type CreateStoryContent = NonNullable<CreateBodyType['story']['content']>;
227
+ // The write payload's content discriminant is narrowed to root component names too
228
+ expectTypeOf<CreateStoryContent['component']>().toEqualTypeOf<'page' | 'hero'>();
229
+ });
230
+
231
+ it('should narrow update() body story.content to component union', async () => {
232
+ const _client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
233
+ type UpdateBodyType = Parameters<typeof _client.stories.update>[1]['body'];
234
+ type UpdateStoryContent = NonNullable<UpdateBodyType['story']['content']>;
235
+ // update() is the second positional arg (id, body); content discriminant is the root union
236
+ expectTypeOf<UpdateStoryContent['component']>().toEqualTypeOf<'page' | 'hero'>();
237
+ });
238
+ });
239
+
240
+ describe('defineStoryCreate / defineStoryUpdate combined with mapi client', () => {
241
+ it('should produce a defineStoryCreate result accepted by untyped stories.create', async () => {
242
+ const createPayload = defineStoryCreate(_pageComponent, {
243
+ name: 'My Page',
244
+ content: { headline: 'Hello' },
245
+ });
246
+
247
+ const client = createManagementApiClient(CLIENT_CONFIG);
248
+ await client.stories.create({ body: { story: createPayload } });
249
+ });
250
+
251
+ it('should produce a defineStoryUpdate result accepted by untyped stories.update', async () => {
252
+ const updatePayload = defineStoryUpdate(_pageComponent, {
253
+ content: { headline: 'Updated' },
254
+ });
255
+
256
+ const client = createManagementApiClient(CLIENT_CONFIG);
257
+ await client.stories.update(1, { body: { story: updatePayload } });
258
+ });
259
+
260
+ it('should produce a defineStoryCreate result for hero component accepted by untyped stories.create', async () => {
261
+ const createPayload = defineStoryCreate(heroComponent, {
262
+ name: 'My Hero',
263
+ content: { title: 'Welcome', count: 42, sections: [] },
264
+ });
265
+
266
+ const client = createManagementApiClient(CLIENT_CONFIG);
267
+ await client.stories.create({ body: { story: createPayload } });
268
+ });
269
+
270
+ it('should reject nestable-only component name in create body content', () => {
271
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
272
+ client.stories.create({
273
+ // @ts-expect-error: teaser is nestable-only, not a root component
274
+ body: { story: { name: 'Bad', content: { component: 'teaser' } } },
275
+ });
276
+ });
277
+
278
+ it('should reject wrong field value type in create body content', () => {
279
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
280
+ client.stories.create({
281
+ body: { story: { name: 'Bad', content: {
282
+ component: 'page',
283
+ // @ts-expect-error: headline must be string, not number
284
+ headline: 123,
285
+ } } },
286
+ });
287
+ });
288
+
289
+ it('should return a typed story with content.component as discriminant from stories.get', async () => {
290
+ const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
291
+ const result = await client.stories.get(123);
292
+
293
+ if (result.data?.story) {
294
+ const story = result.data.story;
295
+ expectTypeOf(story.content.component).toEqualTypeOf<'page' | 'hero'>();
296
+
297
+ if (story.content.component === 'page') {
298
+ const updatePayload = defineStoryUpdate(_pageComponent, {
299
+ name: story.name,
300
+ content: { headline: story.content.headline ?? 'Default' },
301
+ });
302
+ expectTypeOf(updatePayload).toMatchTypeOf<{ name?: string | null }>();
303
+ }
304
+ }
305
+ });
306
+ });