storyblok 4.16.0 → 4.16.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/README.md +3 -3
- package/dist/index.mjs +237 -128
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -8
package/README.md
CHANGED
|
@@ -99,7 +99,7 @@ Then you can set breakpoints directly to the typescript files and the debugger w
|
|
|
99
99
|
|
|
100
100
|
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
|
|
101
101
|
|
|
102
|
-
- [Discuss Storyblok on
|
|
102
|
+
- [Discuss Storyblok on GitHub Discussions](https://github.com/storyblok/storyblok/discussions)
|
|
103
103
|
|
|
104
104
|
For community support, chatting with other users, please visit:
|
|
105
105
|
|
|
@@ -114,7 +114,7 @@ For bugs or feature requests, please [submit an issue](https://github.com/storyb
|
|
|
114
114
|
|
|
115
115
|
### I can't share my company project code
|
|
116
116
|
|
|
117
|
-
We understand that you might not be able to share your company's project code. Please provide a minimal reproducible example that demonstrates the issue by using tools like [Stackblitz](https://stackblitz.com) or a link to a
|
|
117
|
+
We understand that you might not be able to share your company's project code. Please provide a minimal reproducible example that demonstrates the issue by using tools like [Stackblitz](https://stackblitz.com) or a link to a GitHub repo. Please make sure you include a README file with the instructions to build and run the project, important not to include any access token, password or personal information of any kind.
|
|
118
118
|
|
|
119
119
|
### I only have a question
|
|
120
120
|
|
|
@@ -122,7 +122,7 @@ If you have a question, please ask in the [Discuss Storyblok on Discord](https:/
|
|
|
122
122
|
|
|
123
123
|
## Contributing
|
|
124
124
|
|
|
125
|
-
If you're interested in contributing to Storyblok CLI, please read our [contributing docs](
|
|
125
|
+
If you're interested in contributing to Storyblok CLI, please read our [contributing docs](../../CONTRIBUTING.md) before submitting a pull request.
|
|
126
126
|
|
|
127
127
|
## License
|
|
128
128
|
|
package/dist/index.mjs
CHANGED
|
@@ -3995,6 +3995,8 @@ generateCmd$1.action(async (componentName, options, command) => {
|
|
|
3995
3995
|
}
|
|
3996
3996
|
});
|
|
3997
3997
|
|
|
3998
|
+
const normalizeFullSlug = (slug) => slug.replace(/\/$/, "");
|
|
3999
|
+
|
|
3998
4000
|
const fetchStories = async (spaceId, params) => {
|
|
3999
4001
|
try {
|
|
4000
4002
|
const client = getMapiClient();
|
|
@@ -4096,9 +4098,15 @@ const prefetchTargetStories = async (spaceId, options) => {
|
|
|
4096
4098
|
options?.onTotal?.(total);
|
|
4097
4099
|
}
|
|
4098
4100
|
for (const story of response.stories) {
|
|
4099
|
-
const ref = { id: story.id, uuid: story.uuid };
|
|
4101
|
+
const ref = { id: story.id, uuid: story.uuid, is_folder: story.is_folder };
|
|
4100
4102
|
if (story.full_slug) {
|
|
4101
|
-
|
|
4103
|
+
const key = normalizeFullSlug(story.full_slug);
|
|
4104
|
+
const existing = result.bySlug.get(key);
|
|
4105
|
+
if (existing) {
|
|
4106
|
+
existing.push(ref);
|
|
4107
|
+
} else {
|
|
4108
|
+
result.bySlug.set(key, [ref]);
|
|
4109
|
+
}
|
|
4102
4110
|
}
|
|
4103
4111
|
result.byId.set(story.id, ref);
|
|
4104
4112
|
}
|
|
@@ -5994,16 +6002,17 @@ const generateCmd = typesCommand.command("generate").description("Generate types
|
|
|
5994
6002
|
).option("--sf, --separate-files", "Generate one .d.ts file per component instead of a single combined file").option("--strict", "strict mode, no loose typing").option("--type-prefix <prefix>", "prefix to be prepended to all generated component type names").option("--type-suffix <suffix>", "suffix to be appended to all generated component type names").option("--suffix <suffix>", "Components suffix").option("--custom-fields-parser <path>", "Path to the parser file for Custom Field Types").option("--compiler-options <options>", "path to the compiler options from json-schema-to-typescript").option("-s, --space <space>", "space ID").option("-p, --path <path>", "path for file storage");
|
|
5995
6003
|
generateCmd.action(async (options, command) => {
|
|
5996
6004
|
konsola.title(`${commands.TYPES}`, colorPalette.TYPES, "Generating types...");
|
|
5997
|
-
const { space, path, verbose } = command.optsWithGlobals();
|
|
6005
|
+
const { space, path, verbose, suffix, filename, separateFiles } = command.optsWithGlobals();
|
|
5998
6006
|
const spinner = new Spinner({
|
|
5999
|
-
verbose
|
|
6007
|
+
verbose
|
|
6000
6008
|
});
|
|
6001
6009
|
try {
|
|
6002
6010
|
spinner.start(`Generating types...`);
|
|
6003
6011
|
const componentsData = await readComponentsFiles({
|
|
6004
6012
|
from: space,
|
|
6005
6013
|
path,
|
|
6006
|
-
|
|
6014
|
+
separateFiles,
|
|
6015
|
+
suffix,
|
|
6007
6016
|
verbose
|
|
6008
6017
|
});
|
|
6009
6018
|
let dataSourceData;
|
|
@@ -6011,7 +6020,8 @@ generateCmd.action(async (options, command) => {
|
|
|
6011
6020
|
dataSourceData = await readDatasourcesFiles({
|
|
6012
6021
|
from: space,
|
|
6013
6022
|
path,
|
|
6014
|
-
|
|
6023
|
+
separateFiles,
|
|
6024
|
+
suffix,
|
|
6015
6025
|
verbose
|
|
6016
6026
|
});
|
|
6017
6027
|
} catch (error) {
|
|
@@ -6029,18 +6039,17 @@ generateCmd.action(async (options, command) => {
|
|
|
6029
6039
|
...dataSourceData
|
|
6030
6040
|
};
|
|
6031
6041
|
const typedefData = await generateTypes(spaceDataWithComponentsAndDatasources, {
|
|
6032
|
-
...options
|
|
6033
|
-
path
|
|
6042
|
+
...options
|
|
6034
6043
|
});
|
|
6035
6044
|
if (typedefData) {
|
|
6036
6045
|
await saveTypesToComponentsFile(space, typedefData, {
|
|
6037
|
-
filename
|
|
6046
|
+
filename,
|
|
6038
6047
|
path,
|
|
6039
|
-
separateFiles
|
|
6048
|
+
separateFiles
|
|
6040
6049
|
});
|
|
6041
6050
|
}
|
|
6042
6051
|
spinner.succeed();
|
|
6043
|
-
if (
|
|
6052
|
+
if (separateFiles && filename) {
|
|
6044
6053
|
konsola.warn(`The --filename option is ignored when using --separate-files`);
|
|
6045
6054
|
}
|
|
6046
6055
|
konsola.ok(`Successfully generated types for space ${space}`, true);
|
|
@@ -8216,87 +8225,172 @@ const mapReferencesStream = ({
|
|
|
8216
8225
|
}
|
|
8217
8226
|
});
|
|
8218
8227
|
};
|
|
8219
|
-
const
|
|
8220
|
-
const { id: _id, uuid: _uuid, parent_id: _parentId, is_startpage: _isStartpage, content, ...newStoryData } = localStory;
|
|
8221
|
-
if (!localStory.is_folder && !content?.component) {
|
|
8222
|
-
throw new Error(`Story "${localStory.slug}" is missing a content type (content.component). Every story must define a content field with a valid component.`);
|
|
8223
|
-
}
|
|
8224
|
-
const remoteStory = await createStory(spaceId, {
|
|
8225
|
-
story: {
|
|
8226
|
-
...newStoryData,
|
|
8227
|
-
...content?.component ? { content: { _uid: "", component: "__migration_artifact__" } } : {}
|
|
8228
|
-
},
|
|
8229
|
-
publish: 0
|
|
8230
|
-
});
|
|
8231
|
-
if (!remoteStory) {
|
|
8232
|
-
throw new Error("No response!");
|
|
8233
|
-
}
|
|
8234
|
-
return remoteStory;
|
|
8235
|
-
};
|
|
8236
|
-
const makeAppendToManifestFSTransport = ({ manifestFile }) => async (localStory, remoteStory) => {
|
|
8228
|
+
const makeAppendToManifestFSTransport = ({ manifestFile }) => async (entry, remoteStory) => {
|
|
8237
8229
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
8238
8230
|
await appendToFile(manifestFile, JSON.stringify({
|
|
8239
|
-
old_id:
|
|
8231
|
+
old_id: entry.uuid,
|
|
8240
8232
|
new_id: remoteStory.uuid,
|
|
8241
8233
|
created_at: createdAt
|
|
8242
8234
|
}));
|
|
8243
8235
|
await appendToFile(manifestFile, JSON.stringify({
|
|
8244
|
-
old_id:
|
|
8236
|
+
old_id: entry.id,
|
|
8245
8237
|
new_id: remoteStory.id,
|
|
8246
8238
|
created_at: createdAt
|
|
8247
8239
|
}));
|
|
8248
8240
|
};
|
|
8249
|
-
const
|
|
8241
|
+
const scanLocalStoryIndex = async ({
|
|
8242
|
+
directoryPath,
|
|
8243
|
+
setTotalStories,
|
|
8244
|
+
onIncrement,
|
|
8245
|
+
onError
|
|
8246
|
+
}) => {
|
|
8247
|
+
const files = (await readDirectory(directoryPath)).filter((f) => extname(f) === ".json");
|
|
8248
|
+
setTotalStories?.(files.length);
|
|
8249
|
+
const entries = [];
|
|
8250
|
+
for (const file of files) {
|
|
8251
|
+
try {
|
|
8252
|
+
const filePath = join(directoryPath, file);
|
|
8253
|
+
const fileContent = await readFile$1(filePath, "utf-8");
|
|
8254
|
+
const story = JSON.parse(fileContent);
|
|
8255
|
+
entries.push({
|
|
8256
|
+
filename: file,
|
|
8257
|
+
id: story.id,
|
|
8258
|
+
uuid: story.uuid ?? "",
|
|
8259
|
+
slug: story.slug ?? "",
|
|
8260
|
+
name: story.name ?? "",
|
|
8261
|
+
full_slug: story.full_slug ?? "",
|
|
8262
|
+
is_folder: story.is_folder ?? false,
|
|
8263
|
+
is_startpage: story.is_startpage === true,
|
|
8264
|
+
parent_id: story.parent_id ?? null,
|
|
8265
|
+
component: story.content?.component
|
|
8266
|
+
});
|
|
8267
|
+
} catch (maybeError) {
|
|
8268
|
+
onError?.(toError(maybeError), file);
|
|
8269
|
+
} finally {
|
|
8270
|
+
onIncrement?.();
|
|
8271
|
+
}
|
|
8272
|
+
}
|
|
8273
|
+
return entries;
|
|
8274
|
+
};
|
|
8275
|
+
const groupStoriesByDepth = (entries) => {
|
|
8276
|
+
const depthMap = /* @__PURE__ */ new Map();
|
|
8277
|
+
for (const entry of entries) {
|
|
8278
|
+
const slug = normalizeFullSlug(entry.full_slug || "");
|
|
8279
|
+
const depth = slug === "" ? 0 : slug.split("/").length - 1;
|
|
8280
|
+
if (!depthMap.has(depth)) {
|
|
8281
|
+
depthMap.set(depth, []);
|
|
8282
|
+
}
|
|
8283
|
+
depthMap.get(depth).push(entry);
|
|
8284
|
+
}
|
|
8285
|
+
const maxDepth = depthMap.size > 0 ? Math.max(...depthMap.keys()) : 0;
|
|
8286
|
+
const levels = [];
|
|
8287
|
+
for (let d = 0; d <= maxDepth; d++) {
|
|
8288
|
+
const level = depthMap.get(d);
|
|
8289
|
+
if (!level || level.length === 0) {
|
|
8290
|
+
continue;
|
|
8291
|
+
}
|
|
8292
|
+
level.sort((a, b) => {
|
|
8293
|
+
if (a.is_folder && !b.is_folder) {
|
|
8294
|
+
return -1;
|
|
8295
|
+
}
|
|
8296
|
+
if (!a.is_folder && b.is_folder) {
|
|
8297
|
+
return 1;
|
|
8298
|
+
}
|
|
8299
|
+
return 0;
|
|
8300
|
+
});
|
|
8301
|
+
levels.push(level);
|
|
8302
|
+
}
|
|
8303
|
+
return levels;
|
|
8304
|
+
};
|
|
8305
|
+
const findSlugMatch = ({
|
|
8306
|
+
entry,
|
|
8307
|
+
existingTargetStories,
|
|
8308
|
+
claimedRemoteIds
|
|
8309
|
+
}) => {
|
|
8310
|
+
const normalizedSlug = entry.full_slug ? normalizeFullSlug(entry.full_slug) : void 0;
|
|
8311
|
+
const slugCandidates = normalizedSlug ? existingTargetStories.bySlug.get(normalizedSlug) : void 0;
|
|
8312
|
+
if (!slugCandidates) {
|
|
8313
|
+
return void 0;
|
|
8314
|
+
}
|
|
8315
|
+
const unclaimed = slugCandidates.filter((ref) => !claimedRemoteIds.has(ref.id));
|
|
8316
|
+
return unclaimed.find((ref) => ref.is_folder === entry.is_folder) ?? unclaimed[0];
|
|
8317
|
+
};
|
|
8318
|
+
const createStoriesForLevel = async ({
|
|
8319
|
+
level,
|
|
8320
|
+
spaceId,
|
|
8250
8321
|
maps,
|
|
8251
8322
|
existingTargetStories,
|
|
8323
|
+
claimedRemoteIds,
|
|
8252
8324
|
isCrossSpace,
|
|
8253
|
-
|
|
8254
|
-
|
|
8325
|
+
dryRun,
|
|
8326
|
+
appendToManifest,
|
|
8255
8327
|
onStorySuccess,
|
|
8256
8328
|
onStorySkipped,
|
|
8257
8329
|
onStoryError
|
|
8258
8330
|
}) => {
|
|
8259
|
-
const
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
onStorySkipped?.(localStory, existingBySlug);
|
|
8278
|
-
return;
|
|
8279
|
-
}
|
|
8280
|
-
}
|
|
8281
|
-
const newRemoteStory = await transports.createStory(localStory);
|
|
8282
|
-
await transports.appendStoryManifest(localStory, newRemoteStory);
|
|
8283
|
-
onStorySuccess?.(localStory, newRemoteStory);
|
|
8284
|
-
} catch (maybeError) {
|
|
8285
|
-
onStoryError?.(toError(maybeError), localStory);
|
|
8331
|
+
const processEntry = async (entry) => {
|
|
8332
|
+
await apiConcurrencyLock.acquire();
|
|
8333
|
+
try {
|
|
8334
|
+
const mappedStoryId = maps.stories?.get(entry.id);
|
|
8335
|
+
const mappedRemoteStory = mappedStoryId ? existingTargetStories.byId.get(Number(mappedStoryId)) : void 0;
|
|
8336
|
+
if (mappedRemoteStory) {
|
|
8337
|
+
claimedRemoteIds.add(mappedRemoteStory.id);
|
|
8338
|
+
onStorySkipped?.(entry, mappedRemoteStory, "matched by manifest mapping from a previous push");
|
|
8339
|
+
return;
|
|
8340
|
+
}
|
|
8341
|
+
const match = findSlugMatch({ entry, existingTargetStories, claimedRemoteIds });
|
|
8342
|
+
if (match) {
|
|
8343
|
+
const isMatchConfirmed = isCrossSpace || match.uuid === entry.uuid;
|
|
8344
|
+
if (isMatchConfirmed) {
|
|
8345
|
+
claimedRemoteIds.add(match.id);
|
|
8346
|
+
await appendToManifest(entry, match);
|
|
8347
|
+
onStorySkipped?.(entry, match, "matched by slug in target space");
|
|
8348
|
+
return;
|
|
8286
8349
|
}
|
|
8287
|
-
}
|
|
8288
|
-
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8350
|
+
}
|
|
8351
|
+
if (!entry.is_folder && !entry.component) {
|
|
8352
|
+
throw new Error(`Story "${entry.slug}" (${entry.filename}) is missing a content type (content.component). Every story must define a content field with a valid component.`);
|
|
8353
|
+
}
|
|
8354
|
+
const resolvedParentId = entry.parent_id != null ? maps.stories?.get(entry.parent_id) : void 0;
|
|
8355
|
+
if (dryRun) {
|
|
8356
|
+
const fakeRemote = { id: entry.id, uuid: entry.uuid };
|
|
8357
|
+
onStorySuccess?.(entry, fakeRemote);
|
|
8358
|
+
return;
|
|
8359
|
+
}
|
|
8360
|
+
const remoteStory = await createStory(spaceId, {
|
|
8361
|
+
story: {
|
|
8362
|
+
slug: entry.slug,
|
|
8363
|
+
name: entry.name,
|
|
8364
|
+
is_folder: entry.is_folder,
|
|
8365
|
+
...resolvedParentId != null ? { parent_id: Number(resolvedParentId) } : {},
|
|
8366
|
+
...entry.is_startpage && resolvedParentId != null ? { is_startpage: true } : {},
|
|
8367
|
+
...entry.component ? { content: { _uid: "", component: entry.component } } : {}
|
|
8368
|
+
},
|
|
8369
|
+
publish: 0
|
|
8293
8370
|
});
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8371
|
+
if (!remoteStory) {
|
|
8372
|
+
throw new Error("No response!");
|
|
8373
|
+
}
|
|
8374
|
+
await appendToManifest(entry, remoteStory);
|
|
8375
|
+
onStorySuccess?.(entry, remoteStory);
|
|
8376
|
+
} catch (maybeError) {
|
|
8377
|
+
onStoryError?.(toError(maybeError), entry);
|
|
8378
|
+
} finally {
|
|
8379
|
+
apiConcurrencyLock.release();
|
|
8298
8380
|
}
|
|
8299
|
-
}
|
|
8381
|
+
};
|
|
8382
|
+
const folders = level.filter((e) => e.is_folder);
|
|
8383
|
+
const nonFolders = level.filter((e) => !e.is_folder);
|
|
8384
|
+
const folderTasks = [];
|
|
8385
|
+
for (const entry of folders) {
|
|
8386
|
+
folderTasks.push(processEntry(entry));
|
|
8387
|
+
}
|
|
8388
|
+
await Promise.all(folderTasks);
|
|
8389
|
+
const storyTasks = [];
|
|
8390
|
+
for (const entry of nonFolders) {
|
|
8391
|
+
storyTasks.push(processEntry(entry));
|
|
8392
|
+
}
|
|
8393
|
+
await Promise.all(storyTasks);
|
|
8300
8394
|
};
|
|
8301
8395
|
const makeWriteStoryFSTransport = ({ directoryPath }) => async (story) => {
|
|
8302
8396
|
await saveToFile(resolve(directoryPath, getStoryFilename(story)), JSON.stringify(story, null, 2));
|
|
@@ -8306,15 +8400,25 @@ const makeWriteStoryAPITransport = ({ spaceId, publish }) => (mappedLocalStory)
|
|
|
8306
8400
|
story: mappedLocalStory,
|
|
8307
8401
|
publish: publish ?? (isStoryPublishedWithoutChanges(mappedLocalStory) ? 1 : 0)
|
|
8308
8402
|
});
|
|
8309
|
-
const makeCleanupStoryFSTransport = ({ directoryPath, maps }) =>
|
|
8310
|
-
const
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8403
|
+
const makeCleanupStoryFSTransport = ({ directoryPath, maps }) => {
|
|
8404
|
+
const reverseUuidMap = /* @__PURE__ */ new Map();
|
|
8405
|
+
if (maps.stories) {
|
|
8406
|
+
for (const [key, value] of maps.stories.entries()) {
|
|
8407
|
+
if (typeof key === "string") {
|
|
8408
|
+
reverseUuidMap.set(value, key);
|
|
8409
|
+
}
|
|
8410
|
+
}
|
|
8411
|
+
}
|
|
8412
|
+
return async (mappedStory) => {
|
|
8413
|
+
const uuid = mappedStory.uuid ?? "";
|
|
8414
|
+
const originalUuid = reverseUuidMap.get(uuid) ?? uuid;
|
|
8415
|
+
const storyFilename = getStoryFilename({
|
|
8416
|
+
slug: mappedStory.slug,
|
|
8417
|
+
uuid: originalUuid
|
|
8418
|
+
});
|
|
8419
|
+
const storyFilePath = resolve(directoryPath, storyFilename);
|
|
8420
|
+
await unlink(storyFilePath);
|
|
8421
|
+
};
|
|
8318
8422
|
};
|
|
8319
8423
|
const writeStoryStream = ({
|
|
8320
8424
|
transports,
|
|
@@ -8921,75 +9025,80 @@ pushCmd.action(async (options, command) => {
|
|
|
8921
9025
|
});
|
|
8922
9026
|
fetchProgress.stop();
|
|
8923
9027
|
const storiesDirectoryPath = resolveCommandPath(directories.stories, fromSpace, basePath);
|
|
9028
|
+
const scanProgress = ui.createProgressBar({ title: "Scanning Stories...".padEnd(21) });
|
|
9029
|
+
const storyIndex = await scanLocalStoryIndex({
|
|
9030
|
+
directoryPath: storiesDirectoryPath,
|
|
9031
|
+
setTotalStories(total) {
|
|
9032
|
+
scanProgress.setTotal(total);
|
|
9033
|
+
},
|
|
9034
|
+
onIncrement() {
|
|
9035
|
+
scanProgress.increment();
|
|
9036
|
+
},
|
|
9037
|
+
onError(error, filename) {
|
|
9038
|
+
summary.creationResults.failed += 1;
|
|
9039
|
+
handleError(error, verbose, { storyFile: filename });
|
|
9040
|
+
}
|
|
9041
|
+
});
|
|
9042
|
+
const levels = groupStoriesByDepth(storyIndex);
|
|
9043
|
+
scanProgress.stop();
|
|
8924
9044
|
const creationProgress = ui.createProgressBar({ title: "Creating Stories...".padEnd(21) });
|
|
8925
9045
|
const processProgress = ui.createProgressBar({ title: "Processing Stories...".padEnd(21) });
|
|
8926
9046
|
const updateProgress = ui.createProgressBar({ title: "Updating Stories...".padEnd(21) });
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
summary.creationResults.failed += 1;
|
|
8941
|
-
summary.processResults.total -= 1;
|
|
8942
|
-
summary.updateResults.total -= 1;
|
|
8943
|
-
processProgress.setTotal(summary.processResults.total);
|
|
8944
|
-
updateProgress.setTotal(summary.updateResults.total);
|
|
8945
|
-
creationProgress.increment();
|
|
8946
|
-
handleError(error, verbose, { storyFile: filename });
|
|
8947
|
-
}
|
|
8948
|
-
}),
|
|
8949
|
-
// Create remote stories.
|
|
8950
|
-
createStoryPlaceholderStream({
|
|
9047
|
+
const totalStories = storyIndex.length + summary.creationResults.failed;
|
|
9048
|
+
summary.creationResults.total = totalStories;
|
|
9049
|
+
summary.processResults.total = totalStories;
|
|
9050
|
+
summary.updateResults.total = totalStories;
|
|
9051
|
+
creationProgress.setTotal(totalStories);
|
|
9052
|
+
processProgress.setTotal(totalStories);
|
|
9053
|
+
updateProgress.setTotal(totalStories);
|
|
9054
|
+
const appendToManifest = options.dryRun ? (() => Promise.resolve()) : makeAppendToManifestFSTransport({ manifestFile });
|
|
9055
|
+
const claimedRemoteIds = /* @__PURE__ */ new Set();
|
|
9056
|
+
for (const level of levels) {
|
|
9057
|
+
await createStoriesForLevel({
|
|
9058
|
+
level,
|
|
9059
|
+
spaceId: space,
|
|
8951
9060
|
maps,
|
|
8952
9061
|
existingTargetStories,
|
|
9062
|
+
claimedRemoteIds,
|
|
8953
9063
|
isCrossSpace: fromSpace !== space,
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
appendStoryManifest: options.dryRun ? () => Promise.resolve() : makeAppendToManifestFSTransport({
|
|
8959
|
-
manifestFile
|
|
8960
|
-
})
|
|
8961
|
-
},
|
|
8962
|
-
onStorySuccess(localStory, remoteStory) {
|
|
8963
|
-
if (!localStory.uuid || !remoteStory.uuid) {
|
|
9064
|
+
dryRun: options.dryRun ?? false,
|
|
9065
|
+
appendToManifest,
|
|
9066
|
+
onStorySuccess(entry, remoteStory) {
|
|
9067
|
+
if (!entry.uuid || !remoteStory.uuid) {
|
|
8964
9068
|
throw new Error("Invalid story provided!");
|
|
8965
9069
|
}
|
|
8966
|
-
maps.stories.set(
|
|
8967
|
-
maps.stories.set(
|
|
9070
|
+
maps.stories.set(entry.id, remoteStory.id);
|
|
9071
|
+
maps.stories.set(entry.uuid, remoteStory.uuid);
|
|
8968
9072
|
logger.info("Created story", { storyId: remoteStory.uuid });
|
|
8969
9073
|
summary.creationResults.succeeded += 1;
|
|
9074
|
+
creationProgress.increment();
|
|
8970
9075
|
},
|
|
8971
|
-
onStorySkipped(
|
|
8972
|
-
if (!
|
|
9076
|
+
onStorySkipped(entry, remoteStory, reason) {
|
|
9077
|
+
if (!entry.uuid || !remoteStory.uuid) {
|
|
8973
9078
|
throw new Error("Invalid story provided!");
|
|
8974
9079
|
}
|
|
8975
|
-
maps.stories.set(
|
|
8976
|
-
maps.stories.set(
|
|
8977
|
-
logger.info(
|
|
9080
|
+
maps.stories.set(entry.id, remoteStory.id);
|
|
9081
|
+
maps.stories.set(entry.uuid, remoteStory.uuid);
|
|
9082
|
+
logger.info(`Skipped creating story: ${reason}`, { storyId: entry.uuid });
|
|
8978
9083
|
summary.creationResults.skipped += 1;
|
|
9084
|
+
creationProgress.increment();
|
|
8979
9085
|
},
|
|
8980
|
-
onStoryError(error,
|
|
9086
|
+
onStoryError(error, entry) {
|
|
8981
9087
|
summary.creationResults.failed += 1;
|
|
8982
9088
|
summary.processResults.total -= 1;
|
|
8983
9089
|
summary.updateResults.total -= 1;
|
|
8984
9090
|
processProgress.setTotal(summary.processResults.total);
|
|
8985
9091
|
updateProgress.setTotal(summary.updateResults.total);
|
|
8986
|
-
handleError(error, verbose, { storyId: localStory?.uuid });
|
|
8987
|
-
},
|
|
8988
|
-
onIncrement() {
|
|
8989
9092
|
creationProgress.increment();
|
|
9093
|
+
handleError(error, verbose, { storyId: entry?.uuid });
|
|
8990
9094
|
}
|
|
8991
|
-
})
|
|
8992
|
-
|
|
9095
|
+
});
|
|
9096
|
+
}
|
|
9097
|
+
if (summary.creationResults.failed > 0) {
|
|
9098
|
+
const message = `${summary.creationResults.failed} ${summary.creationResults.failed === 1 ? "story" : "stories"} failed to create. References to these stories will be left unmapped.`;
|
|
9099
|
+
ui.warn(message);
|
|
9100
|
+
logger.warn(message);
|
|
9101
|
+
}
|
|
8993
9102
|
await pipeline$1(
|
|
8994
9103
|
// Read local stories from `.json` files.
|
|
8995
9104
|
readLocalStoriesStream({
|