@storyblok/management-api-client 1.0.0-alpha.2 → 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.
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +11 -5
- package/dist/client.d.mts +11 -5
- package/dist/client.mjs.map +1 -1
- package/dist/generated/mapi/_internal.gen.d.cts +1 -171
- package/dist/generated/mapi/_internal.gen.d.mts +1 -171
- package/dist/generated/mapi/types-aliased.gen.d.cts +171 -1
- package/dist/generated/mapi/types-aliased.gen.d.mts +171 -1
- package/dist/generated/types/block.d.cts +27 -8
- package/dist/generated/types/block.d.mts +27 -8
- package/dist/generated/types/field.d.cts +24 -12
- package/dist/generated/types/field.d.mts +24 -12
- package/dist/index.d.cts +3 -4
- package/dist/index.d.mts +3 -4
- package/dist/resources/components.cjs.map +1 -1
- package/dist/resources/components.d.cts +17 -17
- package/dist/resources/components.d.mts +17 -17
- package/dist/resources/components.mjs.map +1 -1
- package/package.json +1 -1
- package/playground/integration-tests/test/specs/mapi-round-trip.spec.e2e.ts +30 -40
- package/playground/integration-tests/test/types/components.test-d.ts +7 -46
- package/playground/integration-tests/test/types/resources.test-d.ts +0 -152
- package/playground/integration-tests/test/types/stories.test-d.ts +9 -42
- package/test/GUIDE.md +2 -2
|
@@ -1,44 +1,9 @@
|
|
|
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
1
|
import { createManagementApiClient } from '@storyblok/management-api-client';
|
|
19
2
|
import { describe, expectTypeOf, it } from 'vitest';
|
|
20
3
|
|
|
21
4
|
const CLIENT_CONFIG = { personalAccessToken: 'test-token', spaceId: 12345 };
|
|
22
5
|
|
|
23
6
|
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
7
|
it('should return datasource in response from create', async () => {
|
|
43
8
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
44
9
|
const result = await client.datasources.create({
|
|
@@ -67,24 +32,6 @@ describe('datasources type tests', () => {
|
|
|
67
32
|
});
|
|
68
33
|
|
|
69
34
|
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
35
|
it('should return datasource_entry in response from create', async () => {
|
|
89
36
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
90
37
|
const result = await client.datasourceEntries.create({
|
|
@@ -113,24 +60,6 @@ describe('datasource entries type tests', () => {
|
|
|
113
60
|
});
|
|
114
61
|
|
|
115
62
|
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
63
|
it('should return asset_folder in response from create', async () => {
|
|
135
64
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
136
65
|
const result = await client.assetFolders.create({
|
|
@@ -159,24 +88,6 @@ describe('asset folders type tests', () => {
|
|
|
159
88
|
});
|
|
160
89
|
|
|
161
90
|
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
91
|
it('should return component_group in response from create', async () => {
|
|
181
92
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
182
93
|
const result = await client.componentFolders.create({
|
|
@@ -205,24 +116,6 @@ describe('component folders type tests', () => {
|
|
|
205
116
|
});
|
|
206
117
|
|
|
207
118
|
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
119
|
it('should return internal_tag in response from create', async () => {
|
|
227
120
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
228
121
|
const result = await client.internalTags.create({
|
|
@@ -243,24 +136,6 @@ describe('internal tags type tests', () => {
|
|
|
243
136
|
});
|
|
244
137
|
|
|
245
138
|
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
139
|
it('should return preset in response from create', async () => {
|
|
265
140
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
266
141
|
const result = await client.presets.create({
|
|
@@ -289,24 +164,6 @@ describe('presets type tests', () => {
|
|
|
289
164
|
});
|
|
290
165
|
|
|
291
166
|
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
167
|
it('should return space in response from create', async () => {
|
|
311
168
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
312
169
|
const result = await client.spaces.create({
|
|
@@ -335,15 +192,6 @@ describe('spaces type tests', () => {
|
|
|
335
192
|
});
|
|
336
193
|
|
|
337
194
|
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
195
|
it('should return user in response from updateMe', async () => {
|
|
348
196
|
const client = createManagementApiClient(CLIENT_CONFIG);
|
|
349
197
|
const result = await client.users.updateMe({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { defineBlock, defineField
|
|
1
|
+
import { defineBlock, defineField } from '@storyblok/schema';
|
|
2
2
|
import { createManagementApiClient, type Story as StoryMapi } from '@storyblok/management-api-client';
|
|
3
3
|
import { describe, expectTypeOf, it } from 'vitest';
|
|
4
4
|
|
|
5
5
|
// Nestable block — not a root story type
|
|
6
6
|
const teaserComponent = defineBlock({
|
|
7
7
|
name: 'teaser',
|
|
8
|
-
|
|
8
|
+
fields: [
|
|
9
9
|
defineField('text', { type: 'text' }),
|
|
10
10
|
defineField('image', { type: 'asset' }),
|
|
11
11
|
],
|
|
@@ -18,7 +18,7 @@ const teaserComponent = defineBlock({
|
|
|
18
18
|
const heroComponent = defineBlock({
|
|
19
19
|
name: 'hero',
|
|
20
20
|
is_root: true,
|
|
21
|
-
|
|
21
|
+
fields: [
|
|
22
22
|
defineField('title', { type: 'text' }),
|
|
23
23
|
defineField('count', { type: 'number' }),
|
|
24
24
|
// bloks field without a whitelist — resolves to nestable components only
|
|
@@ -34,12 +34,12 @@ const _pageComponent = defineBlock({
|
|
|
34
34
|
name: 'page',
|
|
35
35
|
is_root: true,
|
|
36
36
|
is_nestable: false,
|
|
37
|
-
|
|
37
|
+
fields: [
|
|
38
38
|
defineField('headline', { type: 'text' }),
|
|
39
39
|
defineField('body', { type: 'richtext' }),
|
|
40
|
-
defineField('teasers', { type: 'bloks',
|
|
41
|
-
defineField('hero', { type: 'bloks',
|
|
42
|
-
defineField('blocks', { type: 'bloks',
|
|
40
|
+
defineField('teasers', { type: 'bloks', allow: [teaserComponent.name] }),
|
|
41
|
+
defineField('hero', { type: 'bloks', allow: [heroComponent.name] }),
|
|
42
|
+
defineField('blocks', { type: 'bloks', allow: [heroComponent.name, teaserComponent.name] }),
|
|
43
43
|
],
|
|
44
44
|
id: 0,
|
|
45
45
|
created_at: '',
|
|
@@ -237,36 +237,7 @@ describe('createManagementApiClient with .withTypes()', () => {
|
|
|
237
237
|
});
|
|
238
238
|
});
|
|
239
239
|
|
|
240
|
-
describe('
|
|
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
|
-
|
|
240
|
+
describe('withTypes() write-body narrowing', () => {
|
|
270
241
|
it('should reject nestable-only component name in create body content', () => {
|
|
271
242
|
const client = createManagementApiClient(CLIENT_CONFIG).withTypes<StoryblokTypes>();
|
|
272
243
|
client.stories.create({
|
|
@@ -295,11 +266,7 @@ describe('defineStoryCreate / defineStoryUpdate combined with mapi client', () =
|
|
|
295
266
|
expectTypeOf(story.content.component).toEqualTypeOf<'page' | 'hero'>();
|
|
296
267
|
|
|
297
268
|
if (story.content.component === 'page') {
|
|
298
|
-
|
|
299
|
-
name: story.name,
|
|
300
|
-
content: { headline: story.content.headline ?? 'Default' },
|
|
301
|
-
});
|
|
302
|
-
expectTypeOf(updatePayload).toMatchTypeOf<{ name?: string | null }>();
|
|
269
|
+
expectTypeOf(story.content.headline).toEqualTypeOf<string | null | undefined>();
|
|
303
270
|
}
|
|
304
271
|
}
|
|
305
272
|
});
|
package/test/GUIDE.md
CHANGED
|
@@ -48,7 +48,7 @@ node packages/cli/dist/index.mjs components push \
|
|
|
48
48
|
|
|
49
49
|
**Always push components before stories.** The CLI validates that each story's `content.component` (and any nested block components) exist in the space. Pushing stories first fails if the referenced components are not yet present.
|
|
50
50
|
|
|
51
|
-
You can do the same with stories
|
|
51
|
+
You can do the same with stories. **Story filename convention:** the CLI requires files named `{slug}_{uuid}.json` where the part after the last `_` exactly matches `story.uuid` in the JSON. Use hyphens (not underscores) in UUIDs. A mismatch causes Pass 2 of the push (reference mapping + content update) to silently skip all stories.
|
|
52
52
|
|
|
53
53
|
## Known quirks
|
|
54
54
|
|
|
@@ -56,4 +56,4 @@ You can do the same with stories and `defineStory`. **Story filename convention:
|
|
|
56
56
|
- **MAPI `stories.get` takes a positional ID, not an options object:** `client.stories.get(id)` — there is no `getBySlug`. The `list` response does not include `content`; call `get(id)` for full content.
|
|
57
57
|
- **MAPI client constructor uses `personalAccessToken`:** `createManagementApiClient({ personalAccessToken: '...', spaceId: ... })`.
|
|
58
58
|
- **Delete methods are `delete`:** Use `client.RESOURCE.delete(id)`.
|
|
59
|
-
- **Each story JSON must have a unique `id`.**
|
|
59
|
+
- **Each story JSON must have a unique `id`.** If multiple story files share the same `id`, the CLI's manifest maps all of them to the same `old_id` entry, causing "slug already taken" errors.
|