storyblok 4.0.0-beta.2 → 4.0.0-beta.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/index.mjs CHANGED
@@ -353,7 +353,10 @@ const toPascalCase = (str) => {
353
353
  return str.replace(/(?:^|_)(\w)/g, (_, char) => char.toUpperCase());
354
354
  };
355
355
  const toCamelCase = (str) => {
356
- return str.replace(/(?:^|_)(\w)/g, (_, char) => char.toUpperCase()).replace(/_/g, "").replace(/^[A-Z]/, (char) => char.toLowerCase());
356
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/_/g, "").replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/[^a-z0-9]([a-z])/gi, (_, letter) => letter.toUpperCase()).replace(/[^a-z0-9]/gi, "");
357
+ };
358
+ const capitalize = (str) => {
359
+ return str.charAt(0).toUpperCase() + str.slice(1);
357
360
  };
358
361
  function maskToken(token) {
359
362
  if (token.length <= 4) {
@@ -563,14 +566,18 @@ const getCredentials = async (filePath = join(getStoryblokGlobalPath(), "credent
563
566
  try {
564
567
  await access(filePath);
565
568
  const content = await readFile(filePath);
566
- return JSON.parse(content);
569
+ const parsedContent = JSON.parse(content);
570
+ if (Object.keys(parsedContent).length === 0) {
571
+ return null;
572
+ }
573
+ return parsedContent;
567
574
  } catch (error) {
568
575
  if (error.code === "ENOENT") {
569
576
  await saveToFile(filePath, JSON.stringify({}, null, 2), { mode: 384 });
570
- return {};
577
+ return null;
571
578
  }
572
579
  handleFileSystemError("read", error);
573
- return {};
580
+ return null;
574
581
  }
575
582
  };
576
583
  const addCredentials = async ({
@@ -604,7 +611,7 @@ function createSession() {
604
611
  const state = {
605
612
  isLoggedIn: false
606
613
  };
607
- async function initializeSession(region = "eu") {
614
+ async function initializeSession() {
608
615
  const envCredentials = getEnvCredentials();
609
616
  if (envCredentials) {
610
617
  state.isLoggedIn = true;
@@ -614,9 +621,9 @@ function createSession() {
614
621
  state.envLogin = true;
615
622
  return;
616
623
  }
617
- const machines = await getCredentials();
618
- const creds = machines[regionsDomain[region] || "api.storyblok.com"];
619
- if (creds) {
624
+ const credentials = await getCredentials();
625
+ if (credentials) {
626
+ const creds = Object.values(credentials)[0];
620
627
  state.isLoggedIn = true;
621
628
  state.login = creds.login;
622
629
  state.password = creds.password;
@@ -3223,18 +3230,67 @@ const storyblokSchemas = /* @__PURE__ */ new Map([
3223
3230
  ["richtext", getRichtextJSONSchema]
3224
3231
  ]);
3225
3232
 
3233
+ const STORY_TYPE = "ISbStoryData";
3226
3234
  const DEFAULT_TYPEDEFS_HEADER = [
3227
3235
  "// This file was generated by the storyblok CLI.",
3228
3236
  "// DO NOT MODIFY THIS FILE BY HAND."
3229
3237
  ];
3230
- const getPropertyTypeAnnotation = (property) => {
3238
+ const getPropertyTypeAnnotation = (property, prefix) => {
3231
3239
  if (Array.from(storyblokSchemas.keys()).includes(property.type)) {
3232
3240
  return { type: property.type };
3233
3241
  }
3242
+ let type = "unknown";
3234
3243
  const options = property.options && property.options.length > 0 ? property.options.map((item) => item.value) : [];
3235
3244
  if (options.length > 0 && property.exclude_empty_option !== true) {
3236
3245
  options.unshift("");
3237
3246
  }
3247
+ if (property.source === "internal_stories") {
3248
+ if (property.filter_content_type) {
3249
+ if (typeof property.filter_content_type === "string") {
3250
+ return {
3251
+ tsType: `(${getStoryType(property.filter_content_type, prefix)} | string )${property.type === "options" ? "[]" : ""}`
3252
+ };
3253
+ }
3254
+ return {
3255
+ tsType: `(${property.filter_content_type.map((type2) => getStoryType(type2, prefix)).join(" | ")} | string )${property.type === "options" ? "[]" : ""}`
3256
+ };
3257
+ }
3258
+ }
3259
+ if (
3260
+ // If there is no `source` and there are options, the data source is the component itself
3261
+ // TODO: check if this is an old behaviour (shouldn't this be handled as an "internal" source?)
3262
+ options.length > 0 && !property.source || property.source === "internal_languages" || property.source === "external"
3263
+ ) {
3264
+ type = "string";
3265
+ }
3266
+ if (property.source === "internal") {
3267
+ type = ["number", "string"];
3268
+ }
3269
+ if (property.type === "option") {
3270
+ if (options.length > 0) {
3271
+ return {
3272
+ type,
3273
+ enum: options
3274
+ };
3275
+ }
3276
+ return {
3277
+ type
3278
+ };
3279
+ }
3280
+ if (property.type === "options") {
3281
+ if (options.length > 0) {
3282
+ return {
3283
+ type: "array",
3284
+ items: {
3285
+ enum: options
3286
+ }
3287
+ };
3288
+ }
3289
+ return {
3290
+ type: "array",
3291
+ items: { type }
3292
+ };
3293
+ }
3238
3294
  switch (property.type) {
3239
3295
  case "bloks":
3240
3296
  return { type: "array" };
@@ -3251,6 +3307,9 @@ const getPropertyTypeAnnotation = (property) => {
3251
3307
  return { type: "any" };
3252
3308
  }
3253
3309
  };
3310
+ function getStoryType(property, prefix) {
3311
+ return `${STORY_TYPE}<${prefix ?? ""}${capitalize(toCamelCase(property))}>`;
3312
+ }
3254
3313
  const getComponentType = (componentName, options) => {
3255
3314
  const prefix = options.typePrefix ?? "";
3256
3315
  const sanitizedName = componentName.replace(/[^a-z0-9]/gi, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
@@ -3266,7 +3325,7 @@ const getComponentPropertiesTypeAnnotations = async (component, options, spaceDa
3266
3325
  }
3267
3326
  const propertyType = value.type;
3268
3327
  const propertyTypeAnnotation = {
3269
- [key]: getPropertyTypeAnnotation(value)
3328
+ [key]: getPropertyTypeAnnotation(value, options.typePrefix)
3270
3329
  };
3271
3330
  if (propertyType === "custom" && customFieldsParser) {
3272
3331
  const customField = typeof customFieldsParser === "function" ? customFieldsParser(key, value) : {};
@@ -3354,7 +3413,7 @@ const generateTypes = async (spaceData, options = {
3354
3413
  const schemas = await Promise.all(spaceData.components.map(async (component) => {
3355
3414
  const type = getComponentType(component.name, options);
3356
3415
  const componentPropertiesTypeAnnotations = await getComponentPropertiesTypeAnnotations(component, options, spaceData, customFieldsParser);
3357
- const requiredFields = Object.entries(component.schema).reduce(
3416
+ const requiredFields = Object.entries(component?.schema || {}).reduce(
3358
3417
  (acc, [key, value]) => {
3359
3418
  if (value.required) {
3360
3419
  return [...acc, key];
@@ -3424,45 +3483,12 @@ const saveTypesToFile = async (space, typedefString, options) => {
3424
3483
  const generateStoryblokTypes = async (options = {}) => {
3425
3484
  const { filename = "storyblok", path } = options;
3426
3485
  try {
3427
- const storyblokTypesPath = resolve(process.cwd(), "src", "types", "storyblok.ts");
3486
+ const storyblokTypesPath = resolve(__dirname, "./index.d.ts");
3428
3487
  const storyblokTypesContent = readFileSync(storyblokTypesPath, "utf-8");
3429
- const lines = storyblokTypesContent.split("\n");
3430
- const typeDefinitions = [];
3431
- let isCollecting = false;
3432
- let bracketCount = 0;
3433
- let currentType = "";
3434
- for (let i = 0; i < lines.length; i++) {
3435
- const line = lines[i];
3436
- if (line.includes("export type StoryblokPropertyType") || line.includes("export interface Storyblok")) {
3437
- if (isCollecting) {
3438
- typeDefinitions.push("");
3439
- }
3440
- isCollecting = true;
3441
- typeDefinitions.push(line);
3442
- currentType = line.includes("type") ? "type" : "interface";
3443
- bracketCount += (line.match(/\{/g) || []).length;
3444
- bracketCount -= (line.match(/\}/g) || []).length;
3445
- if (currentType === "type") {
3446
- isCollecting = false;
3447
- continue;
3448
- }
3449
- let j = i + 1;
3450
- while (j < lines.length && bracketCount > 0) {
3451
- const nextLine = lines[j];
3452
- bracketCount += (nextLine.match(/\{/g) || []).length;
3453
- bracketCount -= (nextLine.match(/\}/g) || []).length;
3454
- typeDefinitions.push(nextLine);
3455
- j++;
3456
- }
3457
- i = j - 1;
3458
- isCollecting = false;
3459
- }
3460
- }
3461
3488
  const typeDefs = [
3462
- "// This file was generated by the storyblok CLI.",
3489
+ "// This file was generated by the Storyblok CLI.",
3463
3490
  "// DO NOT MODIFY THIS FILE BY HAND.",
3464
- "",
3465
- ...typeDefinitions
3491
+ storyblokTypesContent
3466
3492
  ].join("\n");
3467
3493
  const resolvedPath = path ? resolve(process.cwd(), path, "types") : resolvePath(path, "types");
3468
3494
  await saveToFile(join(resolvedPath, `${filename}.d.ts`), typeDefs);
@@ -3516,7 +3542,7 @@ typesCommand.command("generate").description("Generate types d.ts for your compo
3516
3542
  }
3517
3543
  });
3518
3544
 
3519
- const version = "4.0.0-beta.2";
3545
+ const version = "4.0.0-beta.3";
3520
3546
  const pkg = {
3521
3547
  version: version};
3522
3548