@storyblok/management-api-client 0.2.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,522 @@
1
+ //#region src/generated/experiments/types.gen.d.ts
2
+ /**
3
+ * An A/B testing experiment
4
+ */
5
+ type Experiment = {
6
+ /**
7
+ * Numeric ID of the experiment
8
+ */
9
+ id: number;
10
+ /**
11
+ * Internal name (lowercase letters, numbers, underscores)
12
+ */
13
+ name: string;
14
+ /**
15
+ * Human-readable display name
16
+ */
17
+ display_name: string;
18
+ /**
19
+ * Optional description of the experiment
20
+ */
21
+ description?: string | null;
22
+ /**
23
+ * Current status of the experiment
24
+ */
25
+ status: 'draft' | 'running' | 'paused' | 'completed';
26
+ /**
27
+ * Timestamp when the experiment was first activated
28
+ */
29
+ started_at?: string | null;
30
+ /**
31
+ * Timestamp when the experiment was completed
32
+ */
33
+ ended_at?: string | null;
34
+ /**
35
+ * Creation timestamp
36
+ */
37
+ created_at: string;
38
+ /**
39
+ * Last update timestamp
40
+ */
41
+ updated_at: string;
42
+ /**
43
+ * IDs of original stories assigned to this experiment
44
+ */
45
+ story_ids: Array<number>;
46
+ /**
47
+ * ID of the winning variant (set when completed with a winner)
48
+ */
49
+ winning_variant_id?: number | null;
50
+ };
51
+ /**
52
+ * Mapping between an original story and its variant copy
53
+ */
54
+ type StoryMapping = {
55
+ /**
56
+ * ID of the variant this mapping belongs to
57
+ */
58
+ experiment_variant_id?: number;
59
+ /**
60
+ * ID of the original story
61
+ */
62
+ original_story_id?: number;
63
+ /**
64
+ * ID of the variant story copy
65
+ */
66
+ variant_story_id?: number | null;
67
+ /**
68
+ * Full slug of the original story
69
+ */
70
+ original_slug?: string | null;
71
+ /**
72
+ * Full slug of the variant story copy
73
+ */
74
+ variant_slug?: string | null;
75
+ /**
76
+ * The variant story object, when expanded
77
+ */
78
+ variant_story?: {
79
+ [key: string]: unknown;
80
+ } | null;
81
+ };
82
+ /**
83
+ * A variant within an experiment
84
+ */
85
+ type ExperimentVariant = {
86
+ /**
87
+ * Numeric ID of the variant
88
+ */
89
+ id: number;
90
+ /**
91
+ * Internal name (lowercase, numbers, underscores)
92
+ */
93
+ name: string;
94
+ /**
95
+ * Human-readable display name
96
+ */
97
+ display_name: string;
98
+ /**
99
+ * Public identifier used for stable bucketing
100
+ */
101
+ public_id: string;
102
+ /**
103
+ * Traffic weight percentage (0-100)
104
+ */
105
+ weight: number;
106
+ /**
107
+ * Whether this is the control variant
108
+ */
109
+ is_control: boolean;
110
+ /**
111
+ * Story-level variant mappings
112
+ */
113
+ story_mappings: Array<StoryMapping>;
114
+ };
115
+ type ExperimentDetail = Experiment & {
116
+ /**
117
+ * Variants belonging to this experiment
118
+ */
119
+ experiment_variants: Array<ExperimentVariant>;
120
+ /**
121
+ * Metrics assigned to this experiment
122
+ */
123
+ experiment_assigned_metrics?: Array<{
124
+ [key: string]: unknown;
125
+ }>;
126
+ };
127
+ /**
128
+ * Input for creating an experiment
129
+ */
130
+ type ExperimentCreate = {
131
+ /**
132
+ * Internal name (lowercase letters, numbers, underscores only)
133
+ */
134
+ name: string;
135
+ /**
136
+ * Human-readable display name
137
+ */
138
+ display_name: string;
139
+ /**
140
+ * Optional description of the experiment
141
+ */
142
+ description?: string;
143
+ /**
144
+ * IDs of stories to assign to this experiment
145
+ */
146
+ story_ids?: Array<number>;
147
+ /**
148
+ * Variants to create with the experiment
149
+ */
150
+ experiment_variants_attributes?: Array<{
151
+ name: string;
152
+ display_name: string;
153
+ weight?: number;
154
+ is_control?: boolean;
155
+ }>;
156
+ };
157
+ /**
158
+ * Input for updating an experiment
159
+ */
160
+ type ExperimentUpdate = {
161
+ display_name?: string;
162
+ description?: string;
163
+ story_ids?: Array<number>;
164
+ /**
165
+ * Variants to add, update, or remove
166
+ */
167
+ experiment_variants_attributes?: Array<{
168
+ /**
169
+ * ID of an existing variant (required for update or delete)
170
+ */
171
+ id?: number;
172
+ name?: string;
173
+ display_name?: string;
174
+ weight?: number;
175
+ is_control?: boolean;
176
+ /**
177
+ * Set to true to remove this variant
178
+ */
179
+ _destroy?: boolean;
180
+ }>;
181
+ };
182
+ /**
183
+ * Bar chart with variant comparison data
184
+ */
185
+ type BarChart = {
186
+ kind: 'bar';
187
+ title?: string | null;
188
+ xLabel?: string | null;
189
+ yLabel?: string | null;
190
+ labels: Array<string>;
191
+ series: Array<ChartSeries>;
192
+ };
193
+ /**
194
+ * Line chart for time-series data
195
+ */
196
+ type LineChart = {
197
+ kind: 'line';
198
+ title?: string | null;
199
+ xLabel?: string | null;
200
+ yLabel?: string | null;
201
+ labels: Array<string>;
202
+ series: Array<ChartSeries>;
203
+ };
204
+ /**
205
+ * Text-only block for insights or summary copy
206
+ */
207
+ type TextChart = {
208
+ kind: 'text';
209
+ title?: string | null;
210
+ /**
211
+ * Insight text content
212
+ */
213
+ body: string;
214
+ };
215
+ type ChartSeries = {
216
+ /**
217
+ * Series label
218
+ */
219
+ label: string;
220
+ /**
221
+ * Numeric data points aligned with labels
222
+ */
223
+ data: Array<number>;
224
+ };
225
+ /**
226
+ * A result chart. The kind field determines the chart type.
227
+ */
228
+ type Chart = BarChart | LineChart | TextChart;
229
+ /**
230
+ * Pre-computed result charts for an experiment
231
+ */
232
+ type ExperimentResult = {
233
+ id: number;
234
+ experiment_id: number;
235
+ charts: Array<Chart>;
236
+ pushed_at: string;
237
+ created_at: string;
238
+ updated_at: string;
239
+ };
240
+ type ListData = {
241
+ body?: never;
242
+ path: {
243
+ /**
244
+ * The ID of the Storyblok space (can be integer or string)
245
+ */
246
+ space_id: number | string;
247
+ };
248
+ query?: {
249
+ /**
250
+ * Filter experiments by status
251
+ */
252
+ by_status?: 'draft' | 'running' | 'paused' | 'completed';
253
+ /**
254
+ * Filter experiments that include the given original story id
255
+ */
256
+ by_story_id?: number;
257
+ /**
258
+ * Filter experiments that include the given variant story id
259
+ */
260
+ by_variant_story_id?: number;
261
+ /**
262
+ * Page number for pagination
263
+ */
264
+ page?: number;
265
+ /**
266
+ * Number of experiments per page
267
+ */
268
+ per_page?: number;
269
+ };
270
+ url: '/v1/spaces/{space_id}/experiments';
271
+ };
272
+ type ListResponses = {
273
+ /**
274
+ * List of experiments
275
+ */
276
+ 200: {
277
+ experiments: Array<ExperimentDetail>;
278
+ };
279
+ };
280
+ type CreateData = {
281
+ body: {
282
+ experiment: ExperimentCreate;
283
+ };
284
+ path: {
285
+ /**
286
+ * The ID of the Storyblok space (can be integer or string)
287
+ */
288
+ space_id: number | string;
289
+ };
290
+ query?: never;
291
+ url: '/v1/spaces/{space_id}/experiments';
292
+ };
293
+ type CreateResponses = {
294
+ /**
295
+ * Experiment created
296
+ */
297
+ 201: {
298
+ experiment: ExperimentDetail;
299
+ };
300
+ };
301
+ type DeleteResponses = {
302
+ /**
303
+ * Experiment deleted
304
+ */
305
+ 204: void;
306
+ };
307
+ type GetResponses = {
308
+ /**
309
+ * Experiment details
310
+ */
311
+ 200: {
312
+ experiment: ExperimentDetail;
313
+ };
314
+ };
315
+ type UpdateData = {
316
+ body: {
317
+ experiment: ExperimentUpdate;
318
+ };
319
+ path: {
320
+ /**
321
+ * The ID of the Storyblok space (can be integer or string)
322
+ */
323
+ space_id: number | string;
324
+ /**
325
+ * The numeric ID of the experiment
326
+ */
327
+ experiment_id: number | string;
328
+ };
329
+ query?: never;
330
+ url: '/v1/spaces/{space_id}/experiments/{experiment_id}';
331
+ };
332
+ type UpdateResponses = {
333
+ /**
334
+ * Experiment updated
335
+ */
336
+ 200: {
337
+ experiment: ExperimentDetail;
338
+ };
339
+ };
340
+ type ActivateData = {
341
+ body?: never;
342
+ path: {
343
+ /**
344
+ * The ID of the Storyblok space (can be integer or string)
345
+ */
346
+ space_id: number | string;
347
+ /**
348
+ * The numeric ID of the experiment
349
+ */
350
+ experiment_id: number | string;
351
+ };
352
+ query?: {
353
+ /**
354
+ * Optional scheduled end date for the experiment (ISO 8601)
355
+ */
356
+ end_date?: string;
357
+ };
358
+ url: '/v1/spaces/{space_id}/experiments/{experiment_id}/activate';
359
+ };
360
+ type ActivateResponses = {
361
+ /**
362
+ * Experiment details
363
+ */
364
+ 200: {
365
+ experiment: ExperimentDetail;
366
+ };
367
+ };
368
+ type PauseResponses = {
369
+ /**
370
+ * Experiment details
371
+ */
372
+ 200: {
373
+ experiment: ExperimentDetail;
374
+ };
375
+ };
376
+ type CompleteResponses = {
377
+ /**
378
+ * Experiment details
379
+ */
380
+ 200: {
381
+ experiment: ExperimentDetail;
382
+ };
383
+ };
384
+ type CompleteWithWinnerResponses = {
385
+ /**
386
+ * Experiment details
387
+ */
388
+ 200: {
389
+ experiment: ExperimentDetail;
390
+ };
391
+ };
392
+ type SelectWinnerResponses = {
393
+ /**
394
+ * Experiment details
395
+ */
396
+ 200: {
397
+ experiment: ExperimentDetail;
398
+ };
399
+ };
400
+ type CreateExperimentStoryData = {
401
+ body: {
402
+ experiment_story: {
403
+ /**
404
+ * ID of the story to link
405
+ */
406
+ story_id: number;
407
+ };
408
+ };
409
+ path: {
410
+ /**
411
+ * The ID of the Storyblok space (can be integer or string)
412
+ */
413
+ space_id: number | string;
414
+ /**
415
+ * The numeric ID of the experiment
416
+ */
417
+ experiment_id: number | string;
418
+ };
419
+ query?: never;
420
+ url: '/v1/spaces/{space_id}/experiments/{experiment_id}/stories';
421
+ };
422
+ type CreateExperimentStoryResponses = {
423
+ /**
424
+ * Story linked
425
+ */
426
+ 201: {
427
+ experiment: ExperimentDetail;
428
+ };
429
+ };
430
+ type DeleteExperimentStoryResponses = {
431
+ /**
432
+ * Story unlinked
433
+ */
434
+ 204: void;
435
+ };
436
+ type CreateStoryMappingData = {
437
+ body: {
438
+ story_mapping: {
439
+ /**
440
+ * ID of the original story to map
441
+ */
442
+ original_story_id: number;
443
+ /**
444
+ * ID of an existing story to link as the variant. Omit to duplicate the original.
445
+ */
446
+ variant_story_id?: number | null;
447
+ };
448
+ };
449
+ path: {
450
+ /**
451
+ * The ID of the Storyblok space (can be integer or string)
452
+ */
453
+ space_id: number | string;
454
+ /**
455
+ * The numeric ID of the experiment
456
+ */
457
+ experiment_id: number | string;
458
+ /**
459
+ * The numeric ID of the experiment variant
460
+ */
461
+ variant_id: number | string;
462
+ };
463
+ query?: never;
464
+ url: '/v1/spaces/{space_id}/experiments/{experiment_id}/variants/{variant_id}/story_mappings';
465
+ };
466
+ type CreateStoryMappingResponses = {
467
+ /**
468
+ * Story mapping created
469
+ */
470
+ 201: {
471
+ story_mapping: StoryMapping;
472
+ };
473
+ };
474
+ type DeleteStoryMappingResponses = {
475
+ /**
476
+ * Story mapping deleted
477
+ */
478
+ 204: void;
479
+ };
480
+ type GetResultsResponses = {
481
+ /**
482
+ * Experiment results
483
+ */
484
+ 200: {
485
+ experiment_result: ExperimentResult;
486
+ };
487
+ /**
488
+ * No results have been pushed yet
489
+ */
490
+ 204: void;
491
+ };
492
+ type PushResultsData = {
493
+ body: {
494
+ /**
495
+ * Pre-computed chart snapshots (max 20)
496
+ */
497
+ charts: Array<Chart>;
498
+ };
499
+ path: {
500
+ /**
501
+ * The ID of the Storyblok space (can be integer or string)
502
+ */
503
+ space_id: number | string;
504
+ /**
505
+ * The numeric ID of the experiment
506
+ */
507
+ experiment_id: number | string;
508
+ };
509
+ query?: never;
510
+ url: '/v1/spaces/{space_id}/experiments/{experiment_id}/results';
511
+ };
512
+ type PushResultsResponses = {
513
+ /**
514
+ * Experiment results stored
515
+ */
516
+ 200: {
517
+ experiment_result: ExperimentResult;
518
+ };
519
+ };
520
+ //#endregion
521
+ export { ActivateData, ActivateResponses, CompleteResponses, CompleteWithWinnerResponses, CreateData, CreateExperimentStoryData, CreateExperimentStoryResponses, CreateResponses, CreateStoryMappingData, CreateStoryMappingResponses, DeleteExperimentStoryResponses, DeleteResponses, DeleteStoryMappingResponses, GetResponses, GetResultsResponses, ListData, ListResponses, PauseResponses, PushResultsData, PushResultsResponses, SelectWinnerResponses, UpdateData, UpdateResponses };
522
+ //# sourceMappingURL=types.gen.d.mts.map
package/dist/index.cjs CHANGED
@@ -11,6 +11,7 @@ const require_component_folders = require('./resources/component-folders.cjs');
11
11
  const require_components = require('./resources/components.cjs');
12
12
  const require_datasource_entries = require('./resources/datasource-entries.cjs');
13
13
  const require_datasources = require('./resources/datasources.cjs');
14
+ const require_experiments = require('./resources/experiments.cjs');
14
15
  const require_internal_tags = require('./resources/internal-tags.cjs');
15
16
  const require_presets = require('./resources/presets.cjs');
16
17
  const require_spaces = require('./resources/spaces.cjs');
@@ -154,6 +155,7 @@ const createManagementApiClient = (config) => {
154
155
  components: require_components.createComponentsResource(deps),
155
156
  datasourceEntries: require_datasource_entries.createDatasourceEntriesResource(deps),
156
157
  datasources: require_datasources.createDatasourcesResource(deps),
158
+ experiments: require_experiments.createExperimentsResource(deps),
157
159
  delete: httpDelete,
158
160
  get: httpGet,
159
161
  patch: httpPatch,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createThrottleManager","createClient","createConfig","ClientError","createAssetFoldersResource","createAssetsResource","createComponentFoldersResource","createComponentsResource","createDatasourceEntriesResource","createDatasourcesResource","createInternalTagsResource","createPresetsResource","createSpacesResource","createStoriesResource","createUsersResource"],"sources":["../src/index.ts"],"sourcesContent":["import type { Client, ResolvedRequestOptions } from './generated/shared/client';\nimport type { Middleware } from './generated/shared/client/utils.gen';\nimport { createClient, createConfig } from './generated/shared/client';\nimport { getManagementBaseUrl } from '@storyblok/region-helper';\nimport { ClientError } from './error';\nimport { createThrottleManager } from './utils/rate-limit';\nimport { createAssetFoldersResource } from './resources/asset-folders';\nimport { createAssetsResource } from './resources/assets';\nimport { createComponentFoldersResource } from './resources/component-folders';\nimport { createComponentsResource } from './resources/components';\nimport { createDatasourceEntriesResource } from './resources/datasource-entries';\nimport { createDatasourcesResource } from './resources/datasources';\nimport { createInternalTagsResource } from './resources/internal-tags';\nimport { createPresetsResource } from './resources/presets';\nimport { createSpacesResource } from './resources/spaces';\nimport { createStoriesResource } from './resources/stories';\nimport { createUsersResource } from './resources/users';\nimport type {\n ApiResponse,\n HttpRequestOptions,\n ManagementApiClientConfig,\n MapiResourceDeps,\n} from './types';\n\nexport { ClientError } from './error';\n\nfunction getAuthorizationHeader(config: ManagementApiClientConfig): string | undefined {\n if (config.personalAccessToken) {\n return config.personalAccessToken;\n }\n if (config.oauthToken) {\n return `Bearer ${config.oauthToken.replace(/^Bearer\\s+/i, '')}`;\n }\n return undefined;\n}\n\nexport const createManagementApiClient = (config: ManagementApiClientConfig) => {\n const {\n spaceId,\n region = 'eu',\n baseUrl,\n headers = {},\n throwOnError = false,\n retry = {\n limit: 12,\n backoffLimit: 20_000,\n methods: ['get', 'post', 'put', 'delete', 'patch', 'head', 'options', 'trace'],\n statusCodes: [429],\n },\n timeout = 30_000,\n rateLimit,\n } = config;\n\n const throttleManager = createThrottleManager(rateLimit ?? {});\n const authHeader = getAuthorizationHeader(config);\n\n const client: Client = createClient(\n createConfig({\n baseUrl: baseUrl || getManagementBaseUrl(region),\n headers: {\n ...(authHeader ? { Authorization: authHeader } : {}),\n ...headers,\n },\n throwOnError,\n kyOptions: {\n throwHttpErrors: true,\n timeout,\n retry,\n },\n }),\n );\n\n client.interceptors.error.use(\n (error: unknown, response: Response) =>\n new ClientError(response?.statusText || 'API request failed', {\n status: response?.status ?? 0,\n statusText: response?.statusText ?? '',\n data: error,\n }),\n );\n\n /**\n * Wraps an SDK call with throttling.\n * When throwOnError is true, errors throw and data is guaranteed non-null.\n */\n function wrapRequest<TData, ThrowOnError extends boolean = false>(\n fn: () => Promise<unknown>,\n _throwOnError?: ThrowOnError,\n ): Promise<ApiResponse<TData, ThrowOnError>> {\n return throttleManager.execute(\n () => fn() as Promise<ApiResponse<TData, ThrowOnError>>,\n );\n }\n\n const deps: MapiResourceDeps = { client, spaceId, wrapRequest };\n\n /**\n * Escape hatch: send a GET request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpGet = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.get({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a POST request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpPost = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.post({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a PUT request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpPut = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.put({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a PATCH request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpPatch = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.patch({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a DELETE request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpDelete = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.delete({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n return {\n assetFolders: createAssetFoldersResource(deps),\n assets: createAssetsResource(deps),\n componentFolders: createComponentFoldersResource(deps),\n components: createComponentsResource(deps),\n datasourceEntries: createDatasourceEntriesResource(deps),\n datasources: createDatasourcesResource(deps),\n delete: httpDelete,\n get: httpGet,\n patch: httpPatch,\n interceptors: client.interceptors as Middleware<Request, Response, unknown, ResolvedRequestOptions>,\n internalTags: createInternalTagsResource(deps),\n post: httpPost,\n presets: createPresetsResource(deps),\n put: httpPut,\n spaces: createSpacesResource(deps),\n stories: createStoriesResource(deps),\n users: createUsersResource({ client, wrapRequest }),\n };\n};\n\nexport type ManagementApiClient = ReturnType<typeof createManagementApiClient>;\n\nexport type {\n ApiResponse,\n Asset,\n AssetCreate,\n AssetField,\n AssetFolder,\n AssetFolderCreate,\n AssetFolderUpdate,\n AssetListQuery,\n AssetSignRequest,\n AssetUpdate,\n AssetUpdateRequest,\n AssetUploadRequest,\n Component,\n ComponentCreate,\n ComponentFolder,\n ComponentSchemaField,\n ComponentUpdate,\n Datasource,\n DatasourceCreate,\n DatasourceEntry,\n DatasourceEntryCreate,\n DatasourceEntryUpdate,\n DatasourceUpdate,\n FetchOptions,\n HttpRequestOptions,\n InternalTag,\n ManagementApiClientConfig,\n MapiResourceDeps,\n MultilinkField,\n PluginField,\n Preset,\n RateLimitConfig,\n RequestConfigOverrides,\n RichtextField,\n SignedResponseObject,\n Space,\n SpaceCreate,\n SpaceUpdate,\n Story,\n StoryAlternate,\n StoryContent,\n StoryCreate,\n StoryListQuery,\n StoryLocalizedPath,\n StoryTranslatedSlug,\n StoryUpdate,\n TableField,\n User,\n} from './types';\nexport { normalizeAssetUrl } from './utils/normalize-asset-url';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["createThrottleManager","createClient","createConfig","ClientError","createAssetFoldersResource","createAssetsResource","createComponentFoldersResource","createComponentsResource","createDatasourceEntriesResource","createDatasourcesResource","createExperimentsResource","createInternalTagsResource","createPresetsResource","createSpacesResource","createStoriesResource","createUsersResource"],"sources":["../src/index.ts"],"sourcesContent":["import type { Client, ResolvedRequestOptions } from './generated/shared/client';\nimport type { Middleware } from './generated/shared/client/utils.gen';\nimport { createClient, createConfig } from './generated/shared/client';\nimport { getManagementBaseUrl } from '@storyblok/region-helper';\nimport { ClientError } from './error';\nimport { createThrottleManager } from './utils/rate-limit';\nimport { createAssetFoldersResource } from './resources/asset-folders';\nimport { createAssetsResource } from './resources/assets';\nimport { createComponentFoldersResource } from './resources/component-folders';\nimport { createComponentsResource } from './resources/components';\nimport { createDatasourceEntriesResource } from './resources/datasource-entries';\nimport { createDatasourcesResource } from './resources/datasources';\nimport { createExperimentsResource } from './resources/experiments';\nimport { createInternalTagsResource } from './resources/internal-tags';\nimport { createPresetsResource } from './resources/presets';\nimport { createSpacesResource } from './resources/spaces';\nimport { createStoriesResource } from './resources/stories';\nimport { createUsersResource } from './resources/users';\nimport type {\n ApiResponse,\n HttpRequestOptions,\n ManagementApiClientConfig,\n MapiResourceDeps,\n} from './types';\n\nexport { ClientError } from './error';\n\nfunction getAuthorizationHeader(config: ManagementApiClientConfig): string | undefined {\n if (config.personalAccessToken) {\n return config.personalAccessToken;\n }\n if (config.oauthToken) {\n return `Bearer ${config.oauthToken.replace(/^Bearer\\s+/i, '')}`;\n }\n return undefined;\n}\n\nexport const createManagementApiClient = (config: ManagementApiClientConfig) => {\n const {\n spaceId,\n region = 'eu',\n baseUrl,\n headers = {},\n throwOnError = false,\n retry = {\n limit: 12,\n backoffLimit: 20_000,\n methods: ['get', 'post', 'put', 'delete', 'patch', 'head', 'options', 'trace'],\n statusCodes: [429],\n },\n timeout = 30_000,\n rateLimit,\n } = config;\n\n const throttleManager = createThrottleManager(rateLimit ?? {});\n const authHeader = getAuthorizationHeader(config);\n\n const client: Client = createClient(\n createConfig({\n baseUrl: baseUrl || getManagementBaseUrl(region),\n headers: {\n ...(authHeader ? { Authorization: authHeader } : {}),\n ...headers,\n },\n throwOnError,\n kyOptions: {\n throwHttpErrors: true,\n timeout,\n retry,\n },\n }),\n );\n\n client.interceptors.error.use(\n (error: unknown, response: Response) =>\n new ClientError(response?.statusText || 'API request failed', {\n status: response?.status ?? 0,\n statusText: response?.statusText ?? '',\n data: error,\n }),\n );\n\n /**\n * Wraps an SDK call with throttling.\n * When throwOnError is true, errors throw and data is guaranteed non-null.\n */\n function wrapRequest<TData, ThrowOnError extends boolean = false>(\n fn: () => Promise<unknown>,\n _throwOnError?: ThrowOnError,\n ): Promise<ApiResponse<TData, ThrowOnError>> {\n return throttleManager.execute(\n () => fn() as Promise<ApiResponse<TData, ThrowOnError>>,\n );\n }\n\n const deps: MapiResourceDeps = { client, spaceId, wrapRequest };\n\n /**\n * Escape hatch: send a GET request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpGet = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.get({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a POST request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpPost = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.post({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a PUT request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpPut = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.put({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a PATCH request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpPatch = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.patch({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n /**\n * Escape hatch: send a DELETE request to any MAPI endpoint not yet wrapped\n * in a dedicated resource method.\n */\n const httpDelete = <TData = unknown>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<ApiResponse<TData>> => {\n const { fetchOptions, ...rest } = options;\n return wrapRequest<TData>(() =>\n client.delete({ url: path, ...rest, ...(fetchOptions ? { kyOptions: { ...client.getConfig().kyOptions, ...fetchOptions } } : {}) }),\n );\n };\n\n return {\n assetFolders: createAssetFoldersResource(deps),\n assets: createAssetsResource(deps),\n componentFolders: createComponentFoldersResource(deps),\n components: createComponentsResource(deps),\n datasourceEntries: createDatasourceEntriesResource(deps),\n datasources: createDatasourcesResource(deps),\n experiments: createExperimentsResource(deps),\n delete: httpDelete,\n get: httpGet,\n patch: httpPatch,\n interceptors: client.interceptors as Middleware<Request, Response, unknown, ResolvedRequestOptions>,\n internalTags: createInternalTagsResource(deps),\n post: httpPost,\n presets: createPresetsResource(deps),\n put: httpPut,\n spaces: createSpacesResource(deps),\n stories: createStoriesResource(deps),\n users: createUsersResource({ client, wrapRequest }),\n };\n};\n\nexport type ManagementApiClient = ReturnType<typeof createManagementApiClient>;\n\nexport type {\n ApiResponse,\n Asset,\n AssetCreate,\n AssetField,\n AssetFolder,\n AssetFolderCreate,\n AssetFolderUpdate,\n AssetListQuery,\n AssetSignRequest,\n AssetUpdate,\n AssetUpdateRequest,\n AssetUploadRequest,\n Component,\n ComponentCreate,\n ComponentFolder,\n ComponentSchemaField,\n ComponentUpdate,\n Datasource,\n DatasourceCreate,\n DatasourceEntry,\n DatasourceEntryCreate,\n DatasourceEntryUpdate,\n DatasourceUpdate,\n FetchOptions,\n HttpRequestOptions,\n InternalTag,\n ManagementApiClientConfig,\n MapiResourceDeps,\n MultilinkField,\n PluginField,\n Preset,\n RateLimitConfig,\n RequestConfigOverrides,\n RichtextField,\n SignedResponseObject,\n Space,\n SpaceCreate,\n SpaceUpdate,\n Story,\n StoryAlternate,\n StoryContent,\n StoryCreate,\n StoryListQuery,\n StoryLocalizedPath,\n StoryTranslatedSlug,\n StoryUpdate,\n TableField,\n User,\n} from './types';\nexport { normalizeAssetUrl } from './utils/normalize-asset-url';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAS,uBAAuB,QAAuD;AACrF,KAAI,OAAO,oBACT,QAAO,OAAO;AAEhB,KAAI,OAAO,WACT,QAAO,UAAU,OAAO,WAAW,QAAQ,eAAe,GAAG;;AAKjE,MAAa,6BAA6B,WAAsC;CAC9E,MAAM,EACJ,SACA,SAAS,MACT,SACA,UAAU,EAAE,EACZ,eAAe,OACf,QAAQ;EACN,OAAO;EACP,cAAc;EACd,SAAS;GAAC;GAAO;GAAQ;GAAO;GAAU;GAAS;GAAQ;GAAW;GAAQ;EAC9E,aAAa,CAAC,IAAI;EACnB,EACD,UAAU,KACV,cACE;CAEJ,MAAM,kBAAkBA,yCAAsB,aAAa,EAAE,CAAC;CAC9D,MAAM,aAAa,uBAAuB,OAAO;CAEjD,MAAM,SAAiBC,gCACrBC,+BAAa;EACX,SAAS,8DAAgC,OAAO;EAChD,SAAS;GACP,GAAI,aAAa,EAAE,eAAe,YAAY,GAAG,EAAE;GACnD,GAAG;GACJ;EACD;EACA,WAAW;GACT,iBAAiB;GACjB;GACA;GACD;EACF,CAAC,CACH;AAED,QAAO,aAAa,MAAM,KACvB,OAAgB,aACf,IAAIC,0BAAY,UAAU,cAAc,sBAAsB;EAC5D,QAAQ,UAAU,UAAU;EAC5B,YAAY,UAAU,cAAc;EACpC,MAAM;EACP,CAAC,CACL;;;;;CAMD,SAAS,YACP,IACA,eAC2C;AAC3C,SAAO,gBAAgB,cACf,IAAI,CACX;;CAGH,MAAM,OAAyB;EAAE;EAAQ;EAAS;EAAa;;;;;CAM/D,MAAM,WACJ,MACA,UAA8B,EAAE,KACA;EAChC,MAAM,EAAE,cAAc,GAAG,SAAS;AAClC,SAAO,kBACL,OAAO,IAAI;GAAE,KAAK;GAAM,GAAG;GAAM,GAAI,eAAe,EAAE,WAAW;IAAE,GAAG,OAAO,WAAW,CAAC;IAAW,GAAG;IAAc,EAAE,GAAG,EAAE;GAAG,CAAC,CACjI;;;;;;CAOH,MAAM,YACJ,MACA,UAA8B,EAAE,KACA;EAChC,MAAM,EAAE,cAAc,GAAG,SAAS;AAClC,SAAO,kBACL,OAAO,KAAK;GAAE,KAAK;GAAM,GAAG;GAAM,GAAI,eAAe,EAAE,WAAW;IAAE,GAAG,OAAO,WAAW,CAAC;IAAW,GAAG;IAAc,EAAE,GAAG,EAAE;GAAG,CAAC,CAClI;;;;;;CAOH,MAAM,WACJ,MACA,UAA8B,EAAE,KACA;EAChC,MAAM,EAAE,cAAc,GAAG,SAAS;AAClC,SAAO,kBACL,OAAO,IAAI;GAAE,KAAK;GAAM,GAAG;GAAM,GAAI,eAAe,EAAE,WAAW;IAAE,GAAG,OAAO,WAAW,CAAC;IAAW,GAAG;IAAc,EAAE,GAAG,EAAE;GAAG,CAAC,CACjI;;;;;;CAOH,MAAM,aACJ,MACA,UAA8B,EAAE,KACA;EAChC,MAAM,EAAE,cAAc,GAAG,SAAS;AAClC,SAAO,kBACL,OAAO,MAAM;GAAE,KAAK;GAAM,GAAG;GAAM,GAAI,eAAe,EAAE,WAAW;IAAE,GAAG,OAAO,WAAW,CAAC;IAAW,GAAG;IAAc,EAAE,GAAG,EAAE;GAAG,CAAC,CACnI;;;;;;CAOH,MAAM,cACJ,MACA,UAA8B,EAAE,KACA;EAChC,MAAM,EAAE,cAAc,GAAG,SAAS;AAClC,SAAO,kBACL,OAAO,OAAO;GAAE,KAAK;GAAM,GAAG;GAAM,GAAI,eAAe,EAAE,WAAW;IAAE,GAAG,OAAO,WAAW,CAAC;IAAW,GAAG;IAAc,EAAE,GAAG,EAAE;GAAG,CAAC,CACpI;;AAGH,QAAO;EACL,cAAcC,iDAA2B,KAAK;EAC9C,QAAQC,oCAAqB,KAAK;EAClC,kBAAkBC,yDAA+B,KAAK;EACtD,YAAYC,4CAAyB,KAAK;EAC1C,mBAAmBC,2DAAgC,KAAK;EACxD,aAAaC,8CAA0B,KAAK;EAC5C,aAAaC,8CAA0B,KAAK;EAC5C,QAAQ;EACR,KAAK;EACL,OAAO;EACP,cAAc,OAAO;EACrB,cAAcC,iDAA2B,KAAK;EAC9C,MAAM;EACN,SAASC,sCAAsB,KAAK;EACpC,KAAK;EACL,QAAQC,oCAAqB,KAAK;EAClC,SAASC,sCAAsB,KAAK;EACpC,OAAOC,kCAAoB;GAAE;GAAQ;GAAa,CAAC;EACpD"}