storyblok 4.6.2 → 4.6.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 +87 -93
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -9,12 +9,11 @@ import { Spinner } from '@topcli/spinner';
|
|
|
9
9
|
import { select, password, input, confirm } from '@inquirer/prompts';
|
|
10
10
|
import { ManagementApiClient } from '@storyblok/management-api-client';
|
|
11
11
|
import { RateLimit, Sema } from 'async-sema';
|
|
12
|
-
import fs, { mkdir, writeFile, readFile as readFile$1, access, readdir } from 'node:fs/promises';
|
|
12
|
+
import fs, { mkdir, writeFile, readFile as readFile$1, appendFile, access, readdir } from 'node:fs/promises';
|
|
13
13
|
import path, { join, parse, resolve } from 'node:path';
|
|
14
14
|
import filenamify from 'filenamify';
|
|
15
15
|
import { exec, spawn } from 'node:child_process';
|
|
16
16
|
import { promisify } from 'node:util';
|
|
17
|
-
import { getRegion } from '@storyblok/region-helper';
|
|
18
17
|
import { minimatch } from 'minimatch';
|
|
19
18
|
import { Readable, pipeline, Transform, Writable } from 'node:stream';
|
|
20
19
|
import { hash } from 'ohash';
|
|
@@ -669,6 +668,22 @@ const saveToFile = async (filePath, data, options) => {
|
|
|
669
668
|
handleFileSystemError("write", writeError);
|
|
670
669
|
}
|
|
671
670
|
};
|
|
671
|
+
const appendToFile = async (filePath, data, options) => {
|
|
672
|
+
const resolvedPath = parse(filePath).dir;
|
|
673
|
+
try {
|
|
674
|
+
await mkdir(resolvedPath, { recursive: true });
|
|
675
|
+
} catch (mkdirError) {
|
|
676
|
+
handleFileSystemError("mkdir", mkdirError);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
try {
|
|
680
|
+
const dataWithNewline = data.endsWith("\n") ? data : `${data}
|
|
681
|
+
`;
|
|
682
|
+
await appendFile(filePath, dataWithNewline, options);
|
|
683
|
+
} catch (writeError) {
|
|
684
|
+
handleFileSystemError("write", writeError);
|
|
685
|
+
}
|
|
686
|
+
};
|
|
672
687
|
const readFile = async (filePath) => {
|
|
673
688
|
try {
|
|
674
689
|
return await readFile$1(filePath, "utf8");
|
|
@@ -1083,30 +1098,8 @@ program$f.command(commands.USER).description("Get the current user").action(asyn
|
|
|
1083
1098
|
konsola.br();
|
|
1084
1099
|
});
|
|
1085
1100
|
|
|
1086
|
-
function getRegionFromSpaceId(spaceId) {
|
|
1087
|
-
try {
|
|
1088
|
-
const region = getRegion(spaceId);
|
|
1089
|
-
return region;
|
|
1090
|
-
} catch (error) {
|
|
1091
|
-
console.warn(`Failed to determine region from space ID: ${error}`);
|
|
1092
|
-
return void 0;
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
const resolveRegion = async (thisCommand) => {
|
|
1096
|
-
const options = thisCommand.opts();
|
|
1097
|
-
const spaceId = options.space;
|
|
1098
|
-
if (spaceId) {
|
|
1099
|
-
const { state, initializeSession } = session();
|
|
1100
|
-
await initializeSession();
|
|
1101
|
-
const detectedRegion = getRegionFromSpaceId(spaceId);
|
|
1102
|
-
if (detectedRegion) {
|
|
1103
|
-
state.region = detectedRegion;
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
};
|
|
1107
|
-
|
|
1108
1101
|
const program$e = getProgram();
|
|
1109
|
-
const componentsCommand = program$e.command(commands.COMPONENTS).alias("comp").description(`Manage your space's block schema`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/components")
|
|
1102
|
+
const componentsCommand = program$e.command(commands.COMPONENTS).alias("comp").description(`Manage your space's block schema`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/components");
|
|
1110
1103
|
|
|
1111
1104
|
const fetchComponents = async (spaceId) => {
|
|
1112
1105
|
try {
|
|
@@ -2721,7 +2714,7 @@ const saveLanguagesToFile = async (space, internationalizationOptions, options)
|
|
|
2721
2714
|
};
|
|
2722
2715
|
|
|
2723
2716
|
const program$b = getProgram();
|
|
2724
|
-
const languagesCommand = program$b.command(commands.LANGUAGES).alias("lang").description(`Manage your space's languages`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/languages")
|
|
2717
|
+
const languagesCommand = program$b.command(commands.LANGUAGES).alias("lang").description(`Manage your space's languages`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/languages");
|
|
2725
2718
|
languagesCommand.command("pull").description(`Download your space's languages schema as json`).option("-f, --filename <filename>", "filename to save the file as <filename>.<suffix>.json").option("--su, --suffix <suffix>", "suffix to add to the file name (e.g. languages.<suffix>.json). By default, the space ID is used.").action(async (options) => {
|
|
2726
2719
|
konsola.title(`${commands.LANGUAGES}`, colorPalette.LANGUAGES);
|
|
2727
2720
|
const verbose = program$b.opts().verbose;
|
|
@@ -2772,7 +2765,7 @@ languagesCommand.command("pull").description(`Download your space's languages sc
|
|
|
2772
2765
|
});
|
|
2773
2766
|
|
|
2774
2767
|
const program$a = getProgram();
|
|
2775
|
-
const migrationsCommand = program$a.command(commands.MIGRATIONS).alias("mig").description(`Manage your space's migrations`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/migrations")
|
|
2768
|
+
const migrationsCommand = program$a.command(commands.MIGRATIONS).alias("mig").description(`Manage your space's migrations`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/migrations");
|
|
2776
2769
|
|
|
2777
2770
|
const getMigrationTemplate = () => {
|
|
2778
2771
|
return `export default function (block) {
|
|
@@ -2922,7 +2915,8 @@ async function* storiesIterator(spaceId, params, onTotal) {
|
|
|
2922
2915
|
const result = await fetchStories(spaceId, {
|
|
2923
2916
|
...transformedParams,
|
|
2924
2917
|
per_page: perPage,
|
|
2925
|
-
page: 1
|
|
2918
|
+
page: 1,
|
|
2919
|
+
story_only: true
|
|
2926
2920
|
});
|
|
2927
2921
|
if (!result) {
|
|
2928
2922
|
return;
|
|
@@ -2938,7 +2932,8 @@ async function* storiesIterator(spaceId, params, onTotal) {
|
|
|
2938
2932
|
const result2 = await fetchStories(spaceId, {
|
|
2939
2933
|
...transformedParams,
|
|
2940
2934
|
per_page: perPage,
|
|
2941
|
-
page
|
|
2935
|
+
page,
|
|
2936
|
+
story_only: true
|
|
2942
2937
|
});
|
|
2943
2938
|
if (!result2) {
|
|
2944
2939
|
return;
|
|
@@ -3069,69 +3064,58 @@ async function getMigrationFunction(fileName, space, basePath) {
|
|
|
3069
3064
|
}
|
|
3070
3065
|
}
|
|
3071
3066
|
function applyMigrationToAllBlocks(content, migrationFunction, targetComponent) {
|
|
3067
|
+
let processed = false;
|
|
3072
3068
|
if (!content || typeof content !== "object") {
|
|
3073
|
-
return
|
|
3069
|
+
return processed;
|
|
3074
3070
|
}
|
|
3075
|
-
let modified = false;
|
|
3076
3071
|
const baseTargetComponent = targetComponent.split(".")[0];
|
|
3072
|
+
let migratedContent = null;
|
|
3077
3073
|
if (content.component === baseTargetComponent) {
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
modified = true;
|
|
3074
|
+
migratedContent = migrationFunction({ ...content });
|
|
3075
|
+
processed = true;
|
|
3081
3076
|
}
|
|
3082
|
-
for (const key
|
|
3083
|
-
if (
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3077
|
+
for (const key of Object.keys(content)) {
|
|
3078
|
+
if (migratedContent) {
|
|
3079
|
+
if (!(key in migratedContent)) {
|
|
3080
|
+
delete content[key];
|
|
3081
|
+
continue;
|
|
3082
|
+
}
|
|
3083
|
+
content[key] = migratedContent[key];
|
|
3084
|
+
}
|
|
3085
|
+
if (Array.isArray(content[key])) {
|
|
3086
|
+
for (const value of content[key]) {
|
|
3087
|
+
if (value && typeof value === "object") {
|
|
3088
|
+
const blockProcessed = applyMigrationToAllBlocks(value, migrationFunction, targetComponent);
|
|
3089
|
+
processed = processed || blockProcessed;
|
|
3091
3090
|
}
|
|
3092
|
-
} else if (value && typeof value === "object") {
|
|
3093
|
-
const blockModified = applyMigrationToAllBlocks(value, migrationFunction, targetComponent);
|
|
3094
|
-
modified = modified || blockModified;
|
|
3095
3091
|
}
|
|
3092
|
+
} else if (content[key] && typeof content[key] === "object") {
|
|
3093
|
+
const blockProcessed = applyMigrationToAllBlocks(content[key], migrationFunction, targetComponent);
|
|
3094
|
+
processed = processed || blockProcessed;
|
|
3096
3095
|
}
|
|
3097
3096
|
}
|
|
3098
|
-
return
|
|
3097
|
+
return processed;
|
|
3099
3098
|
}
|
|
3100
3099
|
|
|
3101
3100
|
async function saveRollbackData({
|
|
3102
3101
|
space,
|
|
3103
3102
|
path,
|
|
3104
|
-
|
|
3103
|
+
story,
|
|
3104
|
+
migrationTimestamp,
|
|
3105
3105
|
migrationFile
|
|
3106
3106
|
}) {
|
|
3107
3107
|
const rollbackData = {
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
content: story.content
|
|
3112
|
-
}))
|
|
3108
|
+
storyId: story.id,
|
|
3109
|
+
name: story.name,
|
|
3110
|
+
content: story.content
|
|
3113
3111
|
};
|
|
3114
3112
|
const rollbacksPath = resolvePath(path, `migrations/${space}/rollbacks`);
|
|
3115
|
-
const
|
|
3116
|
-
const rollbackFileName = `${migrationFile.replace(".js", "")}.${timestamp}.json`;
|
|
3113
|
+
const rollbackFileName = `${migrationFile.replace(".js", "")}.${migrationTimestamp}.jsonl`;
|
|
3117
3114
|
const rollbackFilePath = join(rollbacksPath, rollbackFileName);
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
);
|
|
3123
|
-
} catch (error) {
|
|
3124
|
-
if (error.code === "ENOENT") {
|
|
3125
|
-
const fs = await import('node:fs/promises');
|
|
3126
|
-
await fs.mkdir(rollbacksPath, { recursive: true });
|
|
3127
|
-
await saveToFile(
|
|
3128
|
-
rollbackFilePath,
|
|
3129
|
-
JSON.stringify(rollbackData, null, 2)
|
|
3130
|
-
);
|
|
3131
|
-
} else {
|
|
3132
|
-
throw error;
|
|
3133
|
-
}
|
|
3134
|
-
}
|
|
3115
|
+
await appendToFile(
|
|
3116
|
+
rollbackFilePath,
|
|
3117
|
+
JSON.stringify(rollbackData)
|
|
3118
|
+
);
|
|
3135
3119
|
}
|
|
3136
3120
|
async function readRollbackFile({
|
|
3137
3121
|
space,
|
|
@@ -3141,8 +3125,10 @@ async function readRollbackFile({
|
|
|
3141
3125
|
try {
|
|
3142
3126
|
const resolvedPath = resolvePath(path, `migrations/${space}/rollbacks`);
|
|
3143
3127
|
const rollbackFilePath = join(resolvedPath, migrationFile);
|
|
3144
|
-
const filePath = rollbackFilePath.endsWith(".
|
|
3145
|
-
return
|
|
3128
|
+
const filePath = rollbackFilePath.endsWith(".jsonl") ? rollbackFilePath : `${rollbackFilePath}.jsonl`;
|
|
3129
|
+
return {
|
|
3130
|
+
stories: (await readFile$1(filePath, "utf-8")).trim().split("\n").filter(Boolean).map((x) => JSON.parse(x))
|
|
3131
|
+
};
|
|
3146
3132
|
} catch (error) {
|
|
3147
3133
|
throw new CommandError(`Failed to read rollback file: ${error.message}`);
|
|
3148
3134
|
}
|
|
@@ -3161,22 +3147,22 @@ class MigrationStream extends Transform {
|
|
|
3161
3147
|
totalProcessed: 0
|
|
3162
3148
|
};
|
|
3163
3149
|
}
|
|
3150
|
+
timestamp = Date.now();
|
|
3164
3151
|
results;
|
|
3165
3152
|
migrationFunctions = /* @__PURE__ */ new Map();
|
|
3166
3153
|
totalProcessed = 0;
|
|
3167
|
-
_transform(chunk, _encoding, callback) {
|
|
3154
|
+
async _transform(chunk, _encoding, callback) {
|
|
3168
3155
|
try {
|
|
3169
|
-
this.processStory(chunk)
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
}
|
|
3156
|
+
const results = await this.processStory(chunk);
|
|
3157
|
+
this.results.totalProcessed++;
|
|
3158
|
+
this.options.onProgress?.(this.results.totalProcessed);
|
|
3159
|
+
if (results.length > 0) {
|
|
3160
|
+
this.totalProcessed += results.length;
|
|
3161
|
+
this.options.onTotal?.(this.totalProcessed);
|
|
3162
|
+
for (const result of results) {
|
|
3163
|
+
this.push(result);
|
|
3178
3164
|
}
|
|
3179
|
-
}
|
|
3165
|
+
}
|
|
3180
3166
|
callback();
|
|
3181
3167
|
} catch (error) {
|
|
3182
3168
|
callback(error);
|
|
@@ -3228,16 +3214,17 @@ class MigrationStream extends Transform {
|
|
|
3228
3214
|
await saveRollbackData({
|
|
3229
3215
|
space: this.options.space,
|
|
3230
3216
|
path: this.options.path,
|
|
3231
|
-
|
|
3217
|
+
story: { id: story.id, name: story.name || "", content: story.content },
|
|
3218
|
+
migrationTimestamp: this.timestamp,
|
|
3232
3219
|
migrationFile: migrationFile.name
|
|
3233
3220
|
});
|
|
3234
3221
|
const storyContent = structuredClone(story.content);
|
|
3235
|
-
const originalContentHash = hash(
|
|
3222
|
+
const originalContentHash = hash(storyContent);
|
|
3236
3223
|
const targetComponent = this.options.componentName || getComponentNameFromFilename(migrationFile.name);
|
|
3237
|
-
const
|
|
3224
|
+
const processed = applyMigrationToAllBlocks(storyContent, migrationFunction, targetComponent);
|
|
3238
3225
|
const newContentHash = hash(storyContent);
|
|
3239
3226
|
const contentChanged = originalContentHash !== newContentHash;
|
|
3240
|
-
if (
|
|
3227
|
+
if (processed && contentChanged) {
|
|
3241
3228
|
this.results.successful.push({
|
|
3242
3229
|
storyId: story.id,
|
|
3243
3230
|
name: story.name,
|
|
@@ -3249,7 +3236,7 @@ class MigrationStream extends Transform {
|
|
|
3249
3236
|
name: story.name,
|
|
3250
3237
|
content: storyContent
|
|
3251
3238
|
};
|
|
3252
|
-
} else if (
|
|
3239
|
+
} else if (processed && !contentChanged) {
|
|
3253
3240
|
this.results.skipped.push({
|
|
3254
3241
|
storyId: story.id,
|
|
3255
3242
|
name: story.name,
|
|
@@ -3557,6 +3544,13 @@ migrationsCommand.command("rollback [migrationFile]").description("Rollback a mi
|
|
|
3557
3544
|
handleError(new CommandError(`Please provide the space as argument --space YOUR_SPACE_ID.`), verbose);
|
|
3558
3545
|
return;
|
|
3559
3546
|
}
|
|
3547
|
+
const { password, region } = state;
|
|
3548
|
+
mapiClient({
|
|
3549
|
+
token: {
|
|
3550
|
+
accessToken: password
|
|
3551
|
+
},
|
|
3552
|
+
region
|
|
3553
|
+
});
|
|
3560
3554
|
try {
|
|
3561
3555
|
const rollbackData = await readRollbackFile({
|
|
3562
3556
|
space,
|
|
@@ -3585,7 +3579,7 @@ migrationsCommand.command("rollback [migrationFile]").description("Rollback a mi
|
|
|
3585
3579
|
});
|
|
3586
3580
|
|
|
3587
3581
|
const program$6 = getProgram();
|
|
3588
|
-
const typesCommand = program$6.command(commands.TYPES).alias("ts").description(`Generate types d.ts for your component schemas`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/types")
|
|
3582
|
+
const typesCommand = program$6.command(commands.TYPES).alias("ts").description(`Generate types d.ts for your component schemas`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/types");
|
|
3589
3583
|
|
|
3590
3584
|
const getAssetJSONSchema = (title) => ({
|
|
3591
3585
|
$id: "#/asset",
|
|
@@ -4342,7 +4336,7 @@ typesCommand.command("generate").description("Generate types d.ts for your compo
|
|
|
4342
4336
|
});
|
|
4343
4337
|
|
|
4344
4338
|
const program$4 = getProgram();
|
|
4345
|
-
const datasourcesCommand = program$4.command(commands.DATASOURCES).alias("ds").description(`Manage your space's datasources`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/datasources")
|
|
4339
|
+
const datasourcesCommand = program$4.command(commands.DATASOURCES).alias("ds").description(`Manage your space's datasources`).option("-s, --space <space>", "space ID").option("-p, --path <path>", "path to save the file. Default is .storyblok/datasources");
|
|
4346
4340
|
|
|
4347
4341
|
const fetchDatasourceEntries = async (spaceId, datasourceId) => {
|
|
4348
4342
|
try {
|
|
@@ -5163,7 +5157,7 @@ program$1.command(`${commands.CREATE} [project-path]`).alias("c").description(`S
|
|
|
5163
5157
|
konsola.br();
|
|
5164
5158
|
});
|
|
5165
5159
|
|
|
5166
|
-
const version = "4.6.
|
|
5160
|
+
const version = "4.6.4";
|
|
5167
5161
|
const pkg = {
|
|
5168
5162
|
version: version};
|
|
5169
5163
|
|