sb-mig 6.0.0-beta.6 → 6.0.0-beta.7
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/api/data-migration/component-data-migration.js +1 -2
- package/dist/api/stories/stories.js +4 -2
- package/dist/config/helper.js +6 -7
- package/dist/utils/async-utils.d.ts +1 -0
- package/dist/utils/async-utils.js +16 -0
- package/dist/utils/files.d.ts +1 -0
- package/dist/utils/files.js +26 -15
- package/dist-cjs/api/stories/stories.js +4 -2
- package/dist-cjs/utils/async-utils.js +34 -0
- package/package.json +2 -2
|
@@ -246,7 +246,6 @@ const applySingleMigrationToItems = ({ itemType, itemsToMigrate, preparedMigrati
|
|
|
246
246
|
};
|
|
247
247
|
};
|
|
248
248
|
export const runMigrationPipelineInMemory = ({ itemType, itemsToMigrate, preparedMigrationConfigs, }) => {
|
|
249
|
-
const originalItems = deepClone(itemsToMigrate);
|
|
250
249
|
let workingItems = deepClone(itemsToMigrate);
|
|
251
250
|
const stepReports = [];
|
|
252
251
|
for (const preparedMigrationConfig of preparedMigrationConfigs) {
|
|
@@ -283,7 +282,7 @@ export const runMigrationPipelineInMemory = ({ itemType, itemsToMigrate, prepare
|
|
|
283
282
|
stepReports.push(stepReport);
|
|
284
283
|
}
|
|
285
284
|
const changedItems = workingItems.filter((item, index) => {
|
|
286
|
-
const originalItem =
|
|
285
|
+
const originalItem = itemsToMigrate[index];
|
|
287
286
|
if (!originalItem) {
|
|
288
287
|
return true;
|
|
289
288
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import { mapWithConcurrency } from "../../utils/async-utils.js";
|
|
2
3
|
import Logger from "../../utils/logger.js";
|
|
3
4
|
import { notNullish } from "../../utils/object-utils.js";
|
|
4
5
|
import { getAllItemsWithPagination } from "../utils/request.js";
|
|
5
6
|
const resolveStoryLabel = (content, storyId) => content?.full_slug || content?.slug || content?.name || String(storyId);
|
|
6
7
|
const DEFAULT_PUBLISH_LANGUAGE = "[default]";
|
|
8
|
+
const STORY_CONTENT_FETCH_CONCURRENCY = 10;
|
|
7
9
|
const isDefaultLanguageToken = (language) => language.toLowerCase() === "default" ||
|
|
8
10
|
language === DEFAULT_PUBLISH_LANGUAGE;
|
|
9
11
|
const normalizePublishLanguageCodes = (languages) => {
|
|
@@ -144,7 +146,7 @@ export const getAllStories = async (args, config) => {
|
|
|
144
146
|
});
|
|
145
147
|
Logger.success(`Successfully pre-fetched ${allStoriesWithoutContent.length} stories.`);
|
|
146
148
|
let heartBeat = 0;
|
|
147
|
-
const allStories = await
|
|
149
|
+
const allStories = await mapWithConcurrency(allStoriesWithoutContent, STORY_CONTENT_FETCH_CONCURRENCY, async (story) => {
|
|
148
150
|
const result = await getStoryById(story.id, config);
|
|
149
151
|
heartBeat++;
|
|
150
152
|
if (heartBeat % 10 === 0 ||
|
|
@@ -152,7 +154,7 @@ export const getAllStories = async (args, config) => {
|
|
|
152
154
|
Logger.success(`Successfully fetched ${heartBeat} stories with full content.`);
|
|
153
155
|
}
|
|
154
156
|
return result;
|
|
155
|
-
})
|
|
157
|
+
});
|
|
156
158
|
return allStories;
|
|
157
159
|
};
|
|
158
160
|
// GET
|
package/dist/config/helper.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { pathToFileURL } from "url";
|
|
1
2
|
import Logger from "../utils/logger.js";
|
|
3
|
+
const toImportSpecifier = (filePath) => process.platform === "win32" ? pathToFileURL(filePath).href : filePath;
|
|
2
4
|
export { defaultConfig } from "./defaultConfig.js";
|
|
3
5
|
export { SCHEMA } from "./constants.js";
|
|
4
6
|
export const getStoryblokConfigContent = (data) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
return import(`${prefix}${data.filePath}${data.ext}`)
|
|
7
|
+
const configSpecifier = toImportSpecifier(`${data.filePath}${data.ext}`);
|
|
8
|
+
const fallbackConfigSpecifier = toImportSpecifier(`${data.filePath}.mjs`);
|
|
9
|
+
return import(/* @vite-ignore */ configSpecifier)
|
|
10
10
|
.then((res) => {
|
|
11
11
|
Logger.success("Found storyblok.config.js!");
|
|
12
12
|
return res.default;
|
|
@@ -14,10 +14,9 @@ export const getStoryblokConfigContent = (data) => {
|
|
|
14
14
|
.catch(() => {
|
|
15
15
|
Logger.warning("Cannot find requested file with .js extension.");
|
|
16
16
|
Logger.log("Trying .mjs extension\n");
|
|
17
|
-
return import(
|
|
17
|
+
return import(/* @vite-ignore */ fallbackConfigSpecifier)
|
|
18
18
|
.then((res) => {
|
|
19
19
|
Logger.success("Found storyblok.config.mjs!");
|
|
20
|
-
console.log("res", res);
|
|
21
20
|
return res.default;
|
|
22
21
|
})
|
|
23
22
|
.catch(() => {
|
|
@@ -11,3 +11,19 @@
|
|
|
11
11
|
* await delay(1000); // Wait 1 second
|
|
12
12
|
*/
|
|
13
13
|
export const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));
|
|
14
|
+
export const mapWithConcurrency = async (items, concurrency, mapper) => {
|
|
15
|
+
if (items.length === 0) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const limit = Math.max(1, Math.floor(concurrency));
|
|
19
|
+
const results = new Array(items.length);
|
|
20
|
+
let nextIndex = 0;
|
|
21
|
+
const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
22
|
+
while (nextIndex < items.length) {
|
|
23
|
+
const currentIndex = nextIndex++;
|
|
24
|
+
results[currentIndex] = await mapper(items[currentIndex], currentIndex);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
await Promise.all(workers);
|
|
28
|
+
return results;
|
|
29
|
+
};
|
package/dist/utils/files.d.ts
CHANGED
package/dist/utils/files.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import { writeFile } from "fs";
|
|
3
3
|
import { createRequire } from "module";
|
|
4
|
-
import
|
|
4
|
+
import nodePath from "path";
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
5
6
|
import pkg from "ncp";
|
|
6
7
|
import { generateDatestamp } from "./date-utils.js";
|
|
7
8
|
import Logger from "./logger.js";
|
|
8
9
|
const { ncp } = pkg;
|
|
10
|
+
const resolveFromCwd = (filePath, pathApi = nodePath) => pathApi.isAbsolute(filePath)
|
|
11
|
+
? filePath
|
|
12
|
+
: pathApi.resolve(process.cwd(), filePath);
|
|
13
|
+
export const toImportSpecifier = (filePath, platform = process.platform) => {
|
|
14
|
+
if (/^(file|data|node):/.test(filePath)) {
|
|
15
|
+
return filePath;
|
|
16
|
+
}
|
|
17
|
+
const pathApi = platform === "win32" ? nodePath.win32 : nodePath;
|
|
18
|
+
const resolvedPath = resolveFromCwd(filePath, pathApi);
|
|
19
|
+
return platform === "win32"
|
|
20
|
+
? pathToFileURL(resolvedPath, { windows: true }).href
|
|
21
|
+
: resolvedPath;
|
|
22
|
+
};
|
|
9
23
|
// ============================================================================
|
|
10
24
|
// File Content Loading
|
|
11
25
|
// ============================================================================
|
|
@@ -17,7 +31,7 @@ const { ncp } = pkg;
|
|
|
17
31
|
* @returns The default export of the imported module
|
|
18
32
|
*/
|
|
19
33
|
export const getFileContent = (data) => {
|
|
20
|
-
return import(data.file)
|
|
34
|
+
return import(/* @vite-ignore */ toImportSpecifier(data.file))
|
|
21
35
|
.then((res) => {
|
|
22
36
|
return res.default;
|
|
23
37
|
})
|
|
@@ -56,14 +70,14 @@ export const getFilesContentWithRequire = (data) => {
|
|
|
56
70
|
* @returns Parsed package.json object
|
|
57
71
|
*/
|
|
58
72
|
export const getPackageJson = () => {
|
|
59
|
-
const packageJsonPath =
|
|
73
|
+
const packageJsonPath = nodePath.join(process.cwd(), "package.json");
|
|
60
74
|
const packageJsonContent = fs.readFileSync(packageJsonPath, "utf-8");
|
|
61
75
|
const packageJson = JSON.parse(packageJsonContent);
|
|
62
76
|
return packageJson;
|
|
63
77
|
};
|
|
64
78
|
export const isDirectoryExists = (path) => fs.existsSync(path);
|
|
65
79
|
export const createDir = async (dirPath) => {
|
|
66
|
-
await fs.promises.mkdir(
|
|
80
|
+
await fs.promises.mkdir(resolveFromCwd(dirPath), {
|
|
67
81
|
recursive: true,
|
|
68
82
|
});
|
|
69
83
|
};
|
|
@@ -103,10 +117,10 @@ export const copyFolder = async (src, dest) => {
|
|
|
103
117
|
});
|
|
104
118
|
};
|
|
105
119
|
export const copyFile = async (src, dest) => {
|
|
106
|
-
const directory =
|
|
107
|
-
const fileName =
|
|
108
|
-
if (!isDirectoryExists(directory
|
|
109
|
-
await createDir(directory
|
|
120
|
+
const directory = nodePath.dirname(dest);
|
|
121
|
+
const fileName = nodePath.basename(src);
|
|
122
|
+
if (!isDirectoryExists(directory)) {
|
|
123
|
+
await createDir(directory);
|
|
110
124
|
}
|
|
111
125
|
fs.copyFile(src, dest, (err) => {
|
|
112
126
|
if (err) {
|
|
@@ -141,10 +155,7 @@ export const createAndSaveToFile = async (args, config) => {
|
|
|
141
155
|
Logger.success(`All response written to a file: ${fullPath}`);
|
|
142
156
|
}
|
|
143
157
|
if (path) {
|
|
144
|
-
const folderPath = path
|
|
145
|
-
.split("/")
|
|
146
|
-
.slice(0, path.split("/").length - 1)
|
|
147
|
-
.join("/");
|
|
158
|
+
const folderPath = nodePath.dirname(path);
|
|
148
159
|
await createDir(folderPath);
|
|
149
160
|
await createJsonFile(JSON.stringify(res, undefined, 2), path);
|
|
150
161
|
Logger.success(`All response written to a file: ${path}`);
|
|
@@ -169,7 +180,7 @@ export const createAndSaveComponentListToFile = async ({ file, folder, res, time
|
|
|
169
180
|
Logger.success(`All components written to a file: ${filename}`);
|
|
170
181
|
};
|
|
171
182
|
export const readFile = async (pathToFile) => {
|
|
172
|
-
const absolutePath =
|
|
183
|
+
const absolutePath = resolveFromCwd(pathToFile);
|
|
173
184
|
try {
|
|
174
185
|
const result = await fs.promises.readFile(absolutePath);
|
|
175
186
|
return result.toString();
|
|
@@ -192,13 +203,13 @@ export const dumpToFile = async (path, content) => {
|
|
|
192
203
|
};
|
|
193
204
|
export const getConsumerPackageJson = async () => {
|
|
194
205
|
const consumerPkg = await getFileContentWithRequire({
|
|
195
|
-
file:
|
|
206
|
+
file: nodePath.join(process.cwd(), "package.json"),
|
|
196
207
|
});
|
|
197
208
|
return consumerPkg;
|
|
198
209
|
};
|
|
199
210
|
export const getSbMigPackageJson = async () => {
|
|
200
211
|
const sbMigPkg = await getFileContentWithRequire({
|
|
201
|
-
file:
|
|
212
|
+
file: nodePath.join("..", "..", "package.json"),
|
|
202
213
|
});
|
|
203
214
|
return sbMigPkg;
|
|
204
215
|
};
|
|
@@ -5,11 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.deepUpsertStory = exports.upsertStory = exports.updateStories = exports.publishStoryLanguages = exports.updateStory = exports.createStory = exports.getStoryBySlug = exports.getStoryById = exports.getAllStories = exports.removeAllStories = exports.removeStory = exports.resolvePublishLanguageCodes = exports.parsePublishLanguagesOption = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const async_utils_js_1 = require("../../utils/async-utils.js");
|
|
8
9
|
const logger_js_1 = __importDefault(require("../../utils/logger.js"));
|
|
9
10
|
const object_utils_js_1 = require("../../utils/object-utils.js");
|
|
10
11
|
const request_js_1 = require("../utils/request.js");
|
|
11
12
|
const resolveStoryLabel = (content, storyId) => content?.full_slug || content?.slug || content?.name || String(storyId);
|
|
12
13
|
const DEFAULT_PUBLISH_LANGUAGE = "[default]";
|
|
14
|
+
const STORY_CONTENT_FETCH_CONCURRENCY = 10;
|
|
13
15
|
const isDefaultLanguageToken = (language) => language.toLowerCase() === "default" ||
|
|
14
16
|
language === DEFAULT_PUBLISH_LANGUAGE;
|
|
15
17
|
const normalizePublishLanguageCodes = (languages) => {
|
|
@@ -154,7 +156,7 @@ const getAllStories = async (args, config) => {
|
|
|
154
156
|
});
|
|
155
157
|
logger_js_1.default.success(`Successfully pre-fetched ${allStoriesWithoutContent.length} stories.`);
|
|
156
158
|
let heartBeat = 0;
|
|
157
|
-
const allStories = await
|
|
159
|
+
const allStories = await (0, async_utils_js_1.mapWithConcurrency)(allStoriesWithoutContent, STORY_CONTENT_FETCH_CONCURRENCY, async (story) => {
|
|
158
160
|
const result = await (0, exports.getStoryById)(story.id, config);
|
|
159
161
|
heartBeat++;
|
|
160
162
|
if (heartBeat % 10 === 0 ||
|
|
@@ -162,7 +164,7 @@ const getAllStories = async (args, config) => {
|
|
|
162
164
|
logger_js_1.default.success(`Successfully fetched ${heartBeat} stories with full content.`);
|
|
163
165
|
}
|
|
164
166
|
return result;
|
|
165
|
-
})
|
|
167
|
+
});
|
|
166
168
|
return allStories;
|
|
167
169
|
};
|
|
168
170
|
exports.getAllStories = getAllStories;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Async utility functions
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.mapWithConcurrency = exports.delay = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Delay execution for a specified time
|
|
9
|
+
*
|
|
10
|
+
* @param time - Time to delay in milliseconds
|
|
11
|
+
* @returns Promise that resolves after the delay
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* await delay(1000); // Wait 1 second
|
|
15
|
+
*/
|
|
16
|
+
const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));
|
|
17
|
+
exports.delay = delay;
|
|
18
|
+
const mapWithConcurrency = async (items, concurrency, mapper) => {
|
|
19
|
+
if (items.length === 0) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
const limit = Math.max(1, Math.floor(concurrency));
|
|
23
|
+
const results = new Array(items.length);
|
|
24
|
+
let nextIndex = 0;
|
|
25
|
+
const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
26
|
+
while (nextIndex < items.length) {
|
|
27
|
+
const currentIndex = nextIndex++;
|
|
28
|
+
results[currentIndex] = await mapper(items[currentIndex], currentIndex);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
await Promise.all(workers);
|
|
32
|
+
return results;
|
|
33
|
+
};
|
|
34
|
+
exports.mapWithConcurrency = mapWithConcurrency;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sb-mig",
|
|
3
|
-
"version": "6.0.0-beta.
|
|
3
|
+
"version": "6.0.0-beta.7",
|
|
4
4
|
"description": "CLI to rule the world. (and handle stuff related to Storyblok CMS)",
|
|
5
5
|
"author": "Marcin Krawczyk <marckraw@icloud.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
],
|
|
43
43
|
"scripts": {
|
|
44
44
|
"lint-staged": "node ./src/scripts/fix-esm.js && lint-staged",
|
|
45
|
-
"build": "
|
|
45
|
+
"build": "node ./src/scripts/clean-build.js && tsc -p tsconfig.json && tsc -p tsconfig.api-v2.cjs.json && node ./src/scripts/write-cjs-package.js && node ./src/scripts/make-cli-executable.js",
|
|
46
46
|
"build:dev": "chokidar 'src/**/*.{js,ts,cjs,mjs}' -c 'npm run build'",
|
|
47
47
|
"lint": "eslint . --max-warnings=0",
|
|
48
48
|
"lint:fix": "eslint --fix",
|