storyblok 4.0.0-beta.3 → 4.0.0-beta.4

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.mjs CHANGED
@@ -107,7 +107,11 @@ async function customFetch(url, options = {}) {
107
107
  data
108
108
  });
109
109
  }
110
- return data;
110
+ return {
111
+ ...data,
112
+ perPage: Number(response.headers.get("Per-Page")),
113
+ total: Number(response.headers.get("Total"))
114
+ };
111
115
  } catch (error) {
112
116
  if (error instanceof FetchError) {
113
117
  throw error;
@@ -315,6 +319,22 @@ class FileSystemError extends Error {
315
319
  }
316
320
  }
317
321
 
322
+ function handleVerboseError(error) {
323
+ if (error instanceof CommandError || error instanceof APIError || error instanceof FileSystemError) {
324
+ const errorDetails = "getInfo" in error ? error.getInfo() : {};
325
+ if (error instanceof CommandError) {
326
+ konsola.error(`Command Error: ${error.getInfo().message}`, errorDetails);
327
+ } else if (error instanceof APIError) {
328
+ konsola.error(`API Error: ${error.getInfo().cause}`, errorDetails);
329
+ } else if (error instanceof FileSystemError) {
330
+ konsola.error(`File System Error: ${error.getInfo().cause}`, errorDetails);
331
+ } else {
332
+ konsola.error(`Unexpected Error: ${error}`, errorDetails);
333
+ }
334
+ } else {
335
+ konsola.error(`Unexpected Error`, error);
336
+ }
337
+ }
318
338
  function handleError(error, verbose = false) {
319
339
  if (error instanceof APIError || error instanceof FileSystemError) {
320
340
  const messageStack = error.messageStack;
@@ -329,17 +349,8 @@ function handleError(error, verbose = false) {
329
349
  header: true
330
350
  });
331
351
  }
332
- if (verbose && (error instanceof CommandError || error instanceof APIError || error instanceof FileSystemError)) {
333
- const errorDetails = "getInfo" in error ? error.getInfo() : {};
334
- if (error instanceof CommandError) {
335
- konsola.error(`Command Error: ${error.getInfo().message}`, errorDetails);
336
- } else if (error instanceof APIError) {
337
- konsola.error(`API Error: ${error.getInfo().cause}`, errorDetails);
338
- } else if (error instanceof FileSystemError) {
339
- konsola.error(`File System Error: ${error.getInfo().cause}`, errorDetails);
340
- } else {
341
- konsola.error(`Unexpected Error: ${error}`, errorDetails);
342
- }
352
+ if (verbose) {
353
+ handleVerboseError(error);
343
354
  } else {
344
355
  konsola.br();
345
356
  konsola.info("For more information about the error, run the command with the `--verbose` flag");
@@ -1198,16 +1209,18 @@ async function readJsonFile(filePath) {
1198
1209
  }
1199
1210
  }
1200
1211
  const readComponentsFiles = async (options) => {
1201
- const { from, path, separateFiles = false, suffix } = options;
1212
+ const { from, path, separateFiles = false, suffix, space } = options;
1202
1213
  const resolvedPath = resolvePath(path, `components/${from}`);
1203
1214
  try {
1204
1215
  await readdir(resolvedPath);
1205
1216
  } catch (error) {
1206
- const message = `No directory found for space "${from}". Please make sure you have pulled the components first by running:
1217
+ const message = `No local components found for space ${chalk.bold(from)}. To push components, you need to pull them first:
1207
1218
 
1208
- storyblok components pull --space ${from}
1219
+ 1. Pull the components from your source space:
1220
+ ${chalk.cyan(`storyblok components pull --space ${from}`)}
1209
1221
 
1210
- `;
1222
+ 2. Then try pushing again:
1223
+ ${chalk.cyan(`storyblok components push --space ${space} --from ${from}`)}`;
1211
1224
  throw new FileSystemError(
1212
1225
  "file_not_found",
1213
1226
  "read",
@@ -1387,7 +1400,7 @@ componentsCommand.command("pull [componentName]").option("-f, --filename <filena
1387
1400
  }
1388
1401
  });
1389
1402
 
1390
- function findRelatedResources(components, spaceData) {
1403
+ function findRelatedResources(components, spaceData, visitedComponents = /* @__PURE__ */ new Set()) {
1391
1404
  const componentIds = new Set(components.map((c) => c.id));
1392
1405
  const whitelistedComponentNames = /* @__PURE__ */ new Set();
1393
1406
  const componentGroupUuids = /* @__PURE__ */ new Set();
@@ -1472,7 +1485,11 @@ function findRelatedResources(components, spaceData) {
1472
1485
  whitelistedComponents: []
1473
1486
  };
1474
1487
  if (whitelistedComponents.length > 0) {
1475
- additionalResources = findRelatedResources(whitelistedComponents, spaceData);
1488
+ const newComponents = whitelistedComponents.filter((component) => !visitedComponents.has(component.name));
1489
+ if (newComponents.length > 0) {
1490
+ components.forEach((component) => visitedComponents.add(component.name));
1491
+ additionalResources = findRelatedResources(newComponents, spaceData, visitedComponents);
1492
+ }
1476
1493
  }
1477
1494
  const result = {
1478
1495
  groups: Array.from(/* @__PURE__ */ new Set([...Array.from(relatedGroups), ...additionalResources.groups])),
@@ -1766,11 +1783,6 @@ async function handleWhitelists(space, password, region, spaceData) {
1766
1783
  return;
1767
1784
  }
1768
1785
  if (visited.has(componentName)) {
1769
- failedComponents.add(componentName);
1770
- results.failed.push({
1771
- name: componentName,
1772
- error: new Error(`Circular dependency detected for component ${componentName}`)
1773
- });
1774
1786
  return;
1775
1787
  }
1776
1788
  visited.add(componentName);
@@ -2029,11 +2041,14 @@ componentsCommand.command("push [componentName]").description(`Push your space's
2029
2041
  if (!from) {
2030
2042
  options.from = space;
2031
2043
  }
2044
+ konsola.info(`Attempting to push components ${chalk.bold("from")} space ${chalk.hex(colorPalette.COMPONENTS)(options.from)} ${chalk.bold("to")} ${chalk.hex(colorPalette.COMPONENTS)(space)}`);
2045
+ konsola.br();
2032
2046
  const { password, region } = state;
2033
2047
  try {
2034
2048
  let spaceData = await readComponentsFiles({
2035
2049
  ...options,
2036
- path
2050
+ path,
2051
+ space
2037
2052
  });
2038
2053
  if (componentName) {
2039
2054
  spaceData = filterSpaceDataByComponent(spaceData, componentName);
@@ -2248,16 +2263,28 @@ migrationsCommand.command("generate [componentName]").description("Generate a mi
2248
2263
  const fetchStories = async (space, token, region, params) => {
2249
2264
  try {
2250
2265
  const url = getStoryblokUrl(region);
2251
- const { filter_query, ...restParams } = params || {};
2252
- const regularParams = new URLSearchParams(objectToStringParams(restParams)).toString();
2253
- const queryString = filter_query ? `${regularParams ? `${regularParams}&` : ""}${filter_query}` : regularParams;
2254
- const endpoint = `${url}/spaces/${space}/stories${queryString ? `?${queryString}` : ""}`;
2255
- const response = await customFetch(endpoint, {
2256
- headers: {
2257
- Authorization: token
2258
- }
2259
- });
2260
- return response.stories;
2266
+ const allStories = [];
2267
+ let currentPage = 1;
2268
+ let hasMorePages = true;
2269
+ while (hasMorePages) {
2270
+ const { filter_query, ...restParams } = params || {};
2271
+ const regularParams = new URLSearchParams({
2272
+ ...objectToStringParams({ ...restParams, per_page: 100 }),
2273
+ ...currentPage > 1 && { page: currentPage.toString() }
2274
+ }).toString();
2275
+ const queryString = filter_query ? `${regularParams ? `${regularParams}&` : ""}${filter_query}` : regularParams;
2276
+ const endpoint = `${url}/spaces/${space}/stories${queryString ? `?${queryString}` : ""}`;
2277
+ const response = await customFetch(endpoint, {
2278
+ headers: {
2279
+ Authorization: token
2280
+ }
2281
+ });
2282
+ allStories.push(...response.stories);
2283
+ const totalPages = Math.ceil(response.total / response.perPage);
2284
+ hasMorePages = currentPage < totalPages;
2285
+ currentPage++;
2286
+ }
2287
+ return allStories;
2261
2288
  } catch (error) {
2262
2289
  handleAPIError("pull_stories", error);
2263
2290
  }
@@ -3488,6 +3515,7 @@ const generateStoryblokTypes = async (options = {}) => {
3488
3515
  const typeDefs = [
3489
3516
  "// This file was generated by the Storyblok CLI.",
3490
3517
  "// DO NOT MODIFY THIS FILE BY HAND.",
3518
+ `import type { ${STORY_TYPE} } from '@storyblok/js';`,
3491
3519
  storyblokTypesContent
3492
3520
  ].join("\n");
3493
3521
  const resolvedPath = path ? resolve(process.cwd(), path, "types") : resolvePath(path, "types");
@@ -3542,7 +3570,7 @@ typesCommand.command("generate").description("Generate types d.ts for your compo
3542
3570
  }
3543
3571
  });
3544
3572
 
3545
- const version = "4.0.0-beta.3";
3573
+ const version = "4.0.0-beta.4";
3546
3574
  const pkg = {
3547
3575
  version: version};
3548
3576
 
@@ -3559,6 +3587,19 @@ program.on("command:*", () => {
3559
3587
  konsola.br();
3560
3588
  program.help();
3561
3589
  });
3590
+ program.command("test").description("Test the CLI").action(async () => {
3591
+ const { state, initializeSession } = session();
3592
+ await initializeSession();
3593
+ const { password, region } = state;
3594
+ try {
3595
+ const result = await fetchStories("85047", password, region, {
3596
+ per_page: 100
3597
+ });
3598
+ console.log(result?.length);
3599
+ } catch (error) {
3600
+ console.error(error);
3601
+ }
3602
+ });
3562
3603
  try {
3563
3604
  program.parse(process.argv);
3564
3605
  } catch (error) {