storyblok 4.17.1 → 4.17.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.
- package/dist/index.d.mts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.mjs +99 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -68,7 +68,7 @@ interface StoryblokMultilinkUrl {
|
|
|
68
68
|
url: string;
|
|
69
69
|
full_slug: string;
|
|
70
70
|
}
|
|
71
|
-
interface
|
|
71
|
+
interface StoryblokMultilinkBase {
|
|
72
72
|
fieldtype: 'multilink';
|
|
73
73
|
id: string;
|
|
74
74
|
url: string;
|
|
@@ -78,10 +78,18 @@ interface StoryblokMultilink {
|
|
|
78
78
|
rel?: string;
|
|
79
79
|
title?: string;
|
|
80
80
|
prep?: string;
|
|
81
|
-
linktype: 'story' | 'url' | 'email' | 'asset';
|
|
82
|
-
story?: StoryblokMultilinkStory | StoryblokMultilinkLink | StoryblokMultilinkUrl;
|
|
83
|
-
email?: string;
|
|
84
81
|
}
|
|
82
|
+
type StoryblokMultilink = (StoryblokMultilinkBase & {
|
|
83
|
+
linktype: 'story';
|
|
84
|
+
story?: StoryblokMultilinkStory | StoryblokMultilinkLink | StoryblokMultilinkUrl;
|
|
85
|
+
}) | (StoryblokMultilinkBase & {
|
|
86
|
+
linktype: 'url';
|
|
87
|
+
}) | (StoryblokMultilinkBase & {
|
|
88
|
+
linktype: 'email';
|
|
89
|
+
email: string;
|
|
90
|
+
}) | (StoryblokMultilinkBase & {
|
|
91
|
+
linktype: 'asset';
|
|
92
|
+
});
|
|
85
93
|
interface StoryblokTable {
|
|
86
94
|
fieldtype: 'table';
|
|
87
95
|
thead: Array<{
|
package/dist/index.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ interface StoryblokMultilinkUrl {
|
|
|
68
68
|
url: string;
|
|
69
69
|
full_slug: string;
|
|
70
70
|
}
|
|
71
|
-
interface
|
|
71
|
+
interface StoryblokMultilinkBase {
|
|
72
72
|
fieldtype: 'multilink';
|
|
73
73
|
id: string;
|
|
74
74
|
url: string;
|
|
@@ -78,10 +78,18 @@ interface StoryblokMultilink {
|
|
|
78
78
|
rel?: string;
|
|
79
79
|
title?: string;
|
|
80
80
|
prep?: string;
|
|
81
|
-
linktype: 'story' | 'url' | 'email' | 'asset';
|
|
82
|
-
story?: StoryblokMultilinkStory | StoryblokMultilinkLink | StoryblokMultilinkUrl;
|
|
83
|
-
email?: string;
|
|
84
81
|
}
|
|
82
|
+
type StoryblokMultilink = (StoryblokMultilinkBase & {
|
|
83
|
+
linktype: 'story';
|
|
84
|
+
story?: StoryblokMultilinkStory | StoryblokMultilinkLink | StoryblokMultilinkUrl;
|
|
85
|
+
}) | (StoryblokMultilinkBase & {
|
|
86
|
+
linktype: 'url';
|
|
87
|
+
}) | (StoryblokMultilinkBase & {
|
|
88
|
+
linktype: 'email';
|
|
89
|
+
email: string;
|
|
90
|
+
}) | (StoryblokMultilinkBase & {
|
|
91
|
+
linktype: 'asset';
|
|
92
|
+
});
|
|
85
93
|
interface StoryblokTable {
|
|
86
94
|
fieldtype: 'table';
|
|
87
95
|
thead: Array<{
|
package/dist/index.mjs
CHANGED
|
@@ -578,10 +578,12 @@ function setActiveConfig(config) {
|
|
|
578
578
|
|
|
579
579
|
class FetchError extends Error {
|
|
580
580
|
response;
|
|
581
|
-
|
|
581
|
+
request;
|
|
582
|
+
constructor(message, response, request = {}) {
|
|
582
583
|
super(message);
|
|
583
584
|
this.name = "FetchError";
|
|
584
585
|
this.response = response;
|
|
586
|
+
this.request = request;
|
|
585
587
|
}
|
|
586
588
|
}
|
|
587
589
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -589,6 +591,7 @@ async function customFetch(url, options = {}) {
|
|
|
589
591
|
const { api } = getActiveConfig();
|
|
590
592
|
const maxRetries = options.maxRetries ?? api.maxRetries;
|
|
591
593
|
const baseDelay = options.baseDelay ?? 500;
|
|
594
|
+
const requestContext = { url, method: options.method ?? "GET" };
|
|
592
595
|
let attempt = 0;
|
|
593
596
|
while (attempt <= maxRetries) {
|
|
594
597
|
try {
|
|
@@ -612,7 +615,7 @@ async function customFetch(url, options = {}) {
|
|
|
612
615
|
status: response.status,
|
|
613
616
|
statusText: response.statusText,
|
|
614
617
|
data: null
|
|
615
|
-
});
|
|
618
|
+
}, requestContext);
|
|
616
619
|
}
|
|
617
620
|
if (!response.ok) {
|
|
618
621
|
if (response.status === 429 && attempt < maxRetries) {
|
|
@@ -625,7 +628,7 @@ async function customFetch(url, options = {}) {
|
|
|
625
628
|
status: response.status,
|
|
626
629
|
statusText: response.statusText,
|
|
627
630
|
data
|
|
628
|
-
});
|
|
631
|
+
}, requestContext);
|
|
629
632
|
}
|
|
630
633
|
return {
|
|
631
634
|
...data,
|
|
@@ -640,14 +643,14 @@ async function customFetch(url, options = {}) {
|
|
|
640
643
|
status: 0,
|
|
641
644
|
statusText: "Network Error",
|
|
642
645
|
data: null
|
|
643
|
-
});
|
|
646
|
+
}, requestContext);
|
|
644
647
|
}
|
|
645
648
|
}
|
|
646
649
|
throw new FetchError("Max retries exceeded", {
|
|
647
650
|
status: 429,
|
|
648
651
|
statusText: "Rate Limit Exceeded",
|
|
649
652
|
data: null
|
|
650
|
-
});
|
|
653
|
+
}, requestContext);
|
|
651
654
|
}
|
|
652
655
|
|
|
653
656
|
const API_ACTIONS = {
|
|
@@ -719,9 +722,14 @@ function handleAPIError(action, error, customMessage) {
|
|
|
719
722
|
}
|
|
720
723
|
const response = error?.response;
|
|
721
724
|
if (response?.status) {
|
|
725
|
+
const reqCandidate = error?.request;
|
|
722
726
|
const wrappedError = new FetchError(
|
|
723
727
|
response.statusText ?? error.message,
|
|
724
|
-
{ status: response.status, statusText: response.statusText ?? "", data: response.data }
|
|
728
|
+
{ status: response.status, statusText: response.statusText ?? "", data: response.data },
|
|
729
|
+
{
|
|
730
|
+
url: typeof reqCandidate?.url === "string" ? reqCandidate.url : void 0,
|
|
731
|
+
method: typeof reqCandidate?.method === "string" ? reqCandidate.method : void 0
|
|
732
|
+
}
|
|
725
733
|
);
|
|
726
734
|
const errorId = getErrorId(response.status);
|
|
727
735
|
throw new APIError(errorId, action, wrappedError, customMessage);
|
|
@@ -763,6 +771,8 @@ class APIError extends Error {
|
|
|
763
771
|
}
|
|
764
772
|
}
|
|
765
773
|
getInfo() {
|
|
774
|
+
const request = this.error?.request;
|
|
775
|
+
const hasRequestContext = Boolean(request && (request.url || request.method));
|
|
766
776
|
return {
|
|
767
777
|
name: this.name,
|
|
768
778
|
message: this.message,
|
|
@@ -770,7 +780,8 @@ class APIError extends Error {
|
|
|
770
780
|
cause: this.cause,
|
|
771
781
|
errorId: this.errorId,
|
|
772
782
|
stack: this.stack,
|
|
773
|
-
responseData: this.response?.data
|
|
783
|
+
responseData: this.response?.data,
|
|
784
|
+
...hasRequestContext ? { request: { url: request.url, method: request.method } } : {}
|
|
774
785
|
};
|
|
775
786
|
}
|
|
776
787
|
}
|
|
@@ -2268,16 +2279,40 @@ const DEFAULT_GROUPS_FILENAME = "groups";
|
|
|
2268
2279
|
const DEFAULT_PRESETS_FILENAME = "presets";
|
|
2269
2280
|
const DEFAULT_TAGS_FILENAME = "tags";
|
|
2270
2281
|
|
|
2282
|
+
async function fetchAllPages(fetchFunction, extractDataFunction) {
|
|
2283
|
+
const items = [];
|
|
2284
|
+
let page = 1;
|
|
2285
|
+
while (true) {
|
|
2286
|
+
const { data, response } = await fetchFunction(page);
|
|
2287
|
+
const totalHeader = response.headers.get("total");
|
|
2288
|
+
const fetchedItems = extractDataFunction(data);
|
|
2289
|
+
items.push(...fetchedItems);
|
|
2290
|
+
if (!totalHeader) {
|
|
2291
|
+
return items;
|
|
2292
|
+
}
|
|
2293
|
+
const total = Number(totalHeader);
|
|
2294
|
+
if (Number.isNaN(total) || items.length >= total || fetchedItems.length === 0) {
|
|
2295
|
+
return items;
|
|
2296
|
+
}
|
|
2297
|
+
page++;
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2271
2301
|
const fetchComponents = async (spaceId) => {
|
|
2272
2302
|
try {
|
|
2273
2303
|
const client = getMapiClient();
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2304
|
+
return await fetchAllPages(
|
|
2305
|
+
(page) => client.components.list({
|
|
2306
|
+
path: {
|
|
2307
|
+
space_id: Number(spaceId)
|
|
2308
|
+
},
|
|
2309
|
+
query: {
|
|
2310
|
+
page
|
|
2311
|
+
},
|
|
2312
|
+
throwOnError: true
|
|
2313
|
+
}),
|
|
2314
|
+
(data) => data?.components ?? []
|
|
2315
|
+
);
|
|
2281
2316
|
} catch (error) {
|
|
2282
2317
|
handleAPIError("pull_components", error);
|
|
2283
2318
|
}
|
|
@@ -2285,16 +2320,20 @@ const fetchComponents = async (spaceId) => {
|
|
|
2285
2320
|
const fetchComponent = async (spaceId, componentName) => {
|
|
2286
2321
|
try {
|
|
2287
2322
|
const client = getMapiClient();
|
|
2288
|
-
const
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2323
|
+
const matches = await fetchAllPages(
|
|
2324
|
+
(page) => client.components.list({
|
|
2325
|
+
path: {
|
|
2326
|
+
space_id: Number(spaceId)
|
|
2327
|
+
},
|
|
2328
|
+
query: {
|
|
2329
|
+
page,
|
|
2330
|
+
search: componentName
|
|
2331
|
+
},
|
|
2332
|
+
throwOnError: true
|
|
2333
|
+
}),
|
|
2334
|
+
(data) => data?.components ?? []
|
|
2335
|
+
);
|
|
2336
|
+
return matches.find((c) => c.name === componentName);
|
|
2298
2337
|
} catch (error) {
|
|
2299
2338
|
handleAPIError("pull_components", error, `Failed to fetch component ${componentName}`);
|
|
2300
2339
|
}
|
|
@@ -2328,12 +2367,19 @@ const fetchComponentPresets = async (spaceId) => {
|
|
|
2328
2367
|
const fetchComponentInternalTags = async (spaceId) => {
|
|
2329
2368
|
try {
|
|
2330
2369
|
const client = getMapiClient();
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2370
|
+
return await fetchAllPages(
|
|
2371
|
+
(page) => client.internalTags.list({
|
|
2372
|
+
path: {
|
|
2373
|
+
space_id: Number(spaceId)
|
|
2374
|
+
},
|
|
2375
|
+
query: {
|
|
2376
|
+
page,
|
|
2377
|
+
by_object_type: "component"
|
|
2378
|
+
},
|
|
2379
|
+
throwOnError: true
|
|
2380
|
+
}),
|
|
2381
|
+
(data) => data?.internal_tags ?? []
|
|
2382
|
+
);
|
|
2337
2383
|
} catch (error) {
|
|
2338
2384
|
handleAPIError("pull_component_internal_tags", error);
|
|
2339
2385
|
}
|
|
@@ -6114,20 +6160,6 @@ generateCmd.action(async (options, command) => {
|
|
|
6114
6160
|
const program$6 = getProgram();
|
|
6115
6161
|
const datasourcesCommand = program$6.command(commands.DATASOURCES).alias("ds").description(`Manage your space's datasources`);
|
|
6116
6162
|
|
|
6117
|
-
async function fetchAllPages(fetchFunction, extractDataFunction, page = 1, collectedItems = []) {
|
|
6118
|
-
const { data, response } = await fetchFunction(page);
|
|
6119
|
-
const totalHeader = response.headers.get("total");
|
|
6120
|
-
const total = Number(totalHeader);
|
|
6121
|
-
const fetchedItems = extractDataFunction(data);
|
|
6122
|
-
const allItems = [...collectedItems, ...fetchedItems];
|
|
6123
|
-
if (!totalHeader || Number.isNaN(total)) {
|
|
6124
|
-
return allItems;
|
|
6125
|
-
}
|
|
6126
|
-
if (allItems.length < total && fetchedItems.length > 0) {
|
|
6127
|
-
return fetchAllPages(fetchFunction, extractDataFunction, page + 1, allItems);
|
|
6128
|
-
}
|
|
6129
|
-
return allItems;
|
|
6130
|
-
}
|
|
6131
6163
|
const fetchDatasourceEntries = async (spaceId, datasourceId) => {
|
|
6132
6164
|
try {
|
|
6133
6165
|
const client = getMapiClient();
|
|
@@ -6180,16 +6212,20 @@ const fetchDatasources = async (spaceId) => {
|
|
|
6180
6212
|
const fetchDatasource = async (spaceId, datasourceName) => {
|
|
6181
6213
|
try {
|
|
6182
6214
|
const client = getMapiClient();
|
|
6183
|
-
const
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6215
|
+
const matches = await fetchAllPages(
|
|
6216
|
+
(page) => client.datasources.list({
|
|
6217
|
+
path: {
|
|
6218
|
+
space_id: Number(spaceId)
|
|
6219
|
+
},
|
|
6220
|
+
query: {
|
|
6221
|
+
page,
|
|
6222
|
+
search: datasourceName
|
|
6223
|
+
},
|
|
6224
|
+
throwOnError: true
|
|
6225
|
+
}),
|
|
6226
|
+
(data) => data.datasources || []
|
|
6227
|
+
);
|
|
6228
|
+
const found = matches.find((d) => d.name === datasourceName);
|
|
6193
6229
|
if (!found) {
|
|
6194
6230
|
return void 0;
|
|
6195
6231
|
}
|
|
@@ -8057,13 +8093,6 @@ const fetchStoryStream = ({
|
|
|
8057
8093
|
}
|
|
8058
8094
|
});
|
|
8059
8095
|
};
|
|
8060
|
-
const getUUIDFromFilename = (filename) => {
|
|
8061
|
-
const uuid = basename(filename, extname(filename)).split("_").at(-1);
|
|
8062
|
-
if (!uuid) {
|
|
8063
|
-
throw new Error(`Unable to extract UUID from local story "${filename}"`);
|
|
8064
|
-
}
|
|
8065
|
-
return uuid;
|
|
8066
|
-
};
|
|
8067
8096
|
const readLocalStoriesStream = ({
|
|
8068
8097
|
directoryPath,
|
|
8069
8098
|
fileFilter = () => true,
|
|
@@ -8073,7 +8102,7 @@ const readLocalStoriesStream = ({
|
|
|
8073
8102
|
onStoryError
|
|
8074
8103
|
}) => {
|
|
8075
8104
|
const listGenerator = async function* localStoryIterator() {
|
|
8076
|
-
const files = (await readDirectory(directoryPath)).filter((f) => extname(f) === ".json" && fileFilter({
|
|
8105
|
+
const files = (await readDirectory(directoryPath)).filter((f) => extname(f) === ".json" && fileFilter({ filename: f }));
|
|
8077
8106
|
setTotalStories?.(files.length);
|
|
8078
8107
|
for (const file of files) {
|
|
8079
8108
|
try {
|
|
@@ -8141,10 +8170,13 @@ const scanLocalStoryIndex = async ({
|
|
|
8141
8170
|
const filePath = join(directoryPath, file);
|
|
8142
8171
|
const fileContent = await readFile$1(filePath, "utf-8");
|
|
8143
8172
|
const story = JSON.parse(fileContent);
|
|
8173
|
+
if (!story.uuid) {
|
|
8174
|
+
throw new Error(`Story "${file}" is missing a uuid and cannot be pushed.`);
|
|
8175
|
+
}
|
|
8144
8176
|
entries.push({
|
|
8145
8177
|
filename: file,
|
|
8146
8178
|
id: story.id,
|
|
8147
|
-
uuid: story.uuid
|
|
8179
|
+
uuid: story.uuid,
|
|
8148
8180
|
slug: story.slug ?? "",
|
|
8149
8181
|
name: story.name ?? "",
|
|
8150
8182
|
full_slug: story.full_slug ?? "",
|
|
@@ -9248,12 +9280,14 @@ pushCmd.action(async (options, command) => {
|
|
|
9248
9280
|
pendingWarnings.push(message);
|
|
9249
9281
|
logger.warn(message);
|
|
9250
9282
|
}
|
|
9283
|
+
const uuidByFilename = new Map(storyIndex.map((entry) => [entry.filename, entry.uuid]));
|
|
9251
9284
|
await pipeline$1(
|
|
9252
9285
|
// Read local stories from `.json` files.
|
|
9253
9286
|
readLocalStoriesStream({
|
|
9254
9287
|
directoryPath: storiesDirectoryPath,
|
|
9255
|
-
fileFilter({
|
|
9256
|
-
|
|
9288
|
+
fileFilter({ filename }) {
|
|
9289
|
+
const uuid = uuidByFilename.get(filename);
|
|
9290
|
+
return uuid != null && Boolean(maps.stories.get(uuid));
|
|
9257
9291
|
},
|
|
9258
9292
|
setTotalStories(total) {
|
|
9259
9293
|
summary.processResults.total = total;
|