sb-mig 5.6.0-beta.1 → 5.6.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/README.md +20 -19
- package/dist/api/assets/assets.js +2 -15
- package/dist/api/auth/auth.types.d.ts +1 -1
- package/dist/api/components/components.js +2 -1
- package/dist/api/components/components.sync.d.ts +8 -0
- package/dist/api/components/components.sync.js +193 -0
- package/dist/api/data-migration/component-data-migration.js +2 -2
- package/dist/api/datasources/datasource-entries.js +4 -5
- package/dist/api/datasources/datasources.d.ts +5 -2
- package/dist/api/datasources/datasources.js +42 -35
- package/dist/api/datasources/datasources.sync.d.ts +2 -0
- package/dist/api/datasources/datasources.sync.js +11 -0
- package/dist/api/datasources/datasources.types.d.ts +1 -1
- package/dist/api/datasources/index.d.ts +2 -1
- package/dist/api/datasources/index.js +2 -1
- package/dist/api/managementApi.d.ts +2 -2
- package/dist/api/migrate.d.ts +1 -1
- package/dist/api/migrate.js +3 -48
- package/dist/api/plugins/index.d.ts +2 -1
- package/dist/api/plugins/index.js +2 -1
- package/dist/api/plugins/plugins.d.ts +7 -2
- package/dist/api/plugins/plugins.js +28 -15
- package/dist/api/plugins/plugins.sync.d.ts +2 -0
- package/dist/api/plugins/plugins.sync.js +11 -0
- package/dist/api/roles/index.d.ts +2 -1
- package/dist/api/roles/index.js +2 -1
- package/dist/api/roles/roles.d.ts +5 -2
- package/dist/api/roles/roles.js +34 -11
- package/dist/api/roles/roles.sync.d.ts +2 -0
- package/dist/api/roles/roles.sync.js +6 -0
- package/dist/api/roles/roles.types.d.ts +1 -1
- package/dist/api/stories/stories.js +3 -11
- package/dist/api/sync/sync.types.d.ts +30 -0
- package/dist/api/sync/sync.types.js +1 -0
- package/dist/api/testApi.d.ts +2 -2
- package/dist/api/utils/helper-functions.d.ts +5 -1
- package/dist/api/utils/helper-functions.js +6 -1
- package/dist/api/utils/request.d.ts +1 -1
- package/dist/api/utils/request.js +11 -2
- package/dist/api/utils/resolverTransformations.js +2 -57
- package/dist/api-v2/assets/index.d.ts +13 -0
- package/dist/api-v2/assets/index.js +25 -0
- package/dist/api-v2/auth/index.d.ts +3 -0
- package/dist/api-v2/auth/index.js +8 -0
- package/dist/api-v2/client.d.ts +13 -0
- package/dist/api-v2/client.js +17 -0
- package/dist/api-v2/components/index.d.ts +10 -0
- package/dist/api-v2/components/index.js +29 -0
- package/dist/api-v2/datasources/index.d.ts +8 -0
- package/dist/api-v2/datasources/index.js +58 -0
- package/dist/api-v2/discover/discover.d.ts +47 -0
- package/dist/api-v2/discover/discover.js +328 -0
- package/dist/api-v2/discover/index.d.ts +2 -0
- package/dist/api-v2/discover/index.js +1 -0
- package/dist/api-v2/index.d.ts +19 -0
- package/dist/api-v2/index.js +21 -0
- package/dist/api-v2/plugins/index.d.ts +9 -0
- package/dist/api-v2/plugins/index.js +42 -0
- package/dist/api-v2/precompile/index.d.ts +2 -0
- package/dist/api-v2/precompile/index.js +1 -0
- package/dist/api-v2/precompile/precompile.d.ts +65 -0
- package/dist/api-v2/precompile/precompile.js +127 -0
- package/dist/api-v2/presets/index.d.ts +13 -0
- package/dist/api-v2/presets/index.js +25 -0
- package/dist/api-v2/requestConfig.d.ts +5 -0
- package/dist/api-v2/requestConfig.js +34 -0
- package/dist/api-v2/roles/index.d.ts +5 -0
- package/dist/api-v2/roles/index.js +35 -0
- package/dist/api-v2/spaces/index.d.ts +7 -0
- package/dist/api-v2/spaces/index.js +11 -0
- package/dist/api-v2/stories/index.d.ts +34 -0
- package/dist/api-v2/stories/index.js +172 -0
- package/dist/api-v2/stories/types.d.ts +28 -0
- package/dist/api-v2/stories/types.js +1 -0
- package/dist/api-v2/sync/index.d.ts +24 -0
- package/dist/api-v2/sync/index.js +109 -0
- package/dist/api-v2/sync/types.d.ts +1 -0
- package/dist/api-v2/sync/types.js +1 -0
- package/dist/api-v2/test.d.ts +15 -0
- package/dist/api-v2/test.js +21 -0
- package/dist/cli/commands/backup.js +7 -3
- package/dist/cli/commands/copy.js +2 -2
- package/dist/cli/commands/migrate.js +1 -2
- package/dist/cli/commands/migrations.js +2 -2
- package/dist/cli/commands/remove.js +1 -1
- package/dist/cli/commands/revert.js +2 -2
- package/dist/cli/commands/sync.js +1 -2
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/cli-utils.d.ts +69 -0
- package/dist/cli/utils/cli-utils.js +100 -0
- package/dist/cli/utils/discover.d.ts +3 -22
- package/dist/cli/utils/discover.js +53 -100
- package/dist/config/config.d.ts +2 -39
- package/dist/config/config.types.d.ts +40 -0
- package/dist/config/config.types.js +1 -0
- package/dist/config/defaultConfig.d.ts +1 -1
- package/dist/config/defaultConfig.js +2 -2
- package/dist/utils/array-utils.d.ts +20 -0
- package/dist/utils/array-utils.js +20 -0
- package/dist/utils/async-utils.d.ts +13 -0
- package/dist/utils/async-utils.js +13 -0
- package/dist/utils/date-utils.d.ts +14 -0
- package/dist/utils/date-utils.js +21 -0
- package/dist/utils/files.d.ts +35 -0
- package/dist/utils/files.js +57 -2
- package/dist/utils/main.d.ts +8 -18
- package/dist/utils/main.js +12 -104
- package/dist/utils/migrations.d.ts +9 -3
- package/dist/utils/object-utils.d.ts +46 -0
- package/dist/utils/object-utils.js +71 -0
- package/dist/utils/others.d.ts +6 -9
- package/dist/utils/others.js +8 -15
- package/dist/utils/path-utils.d.ts +89 -0
- package/dist/utils/path-utils.js +106 -0
- package/dist/utils/pkg.d.ts +16 -2
- package/dist/utils/pkg.js +16 -3
- package/dist/utils/string-utils.d.ts +33 -0
- package/dist/utils/string-utils.js +45 -0
- package/dist/utils/transform-utils.d.ts +62 -0
- package/dist/utils/transform-utils.js +113 -0
- package/dist-cjs/api/auth/auth.js +28 -0
- package/dist-cjs/api/auth/auth.types.js +2 -0
- package/dist-cjs/api/components/components.js +202 -0
- package/dist-cjs/api/components/components.sync.js +199 -0
- package/dist-cjs/api/components/components.types.js +2 -0
- package/dist-cjs/api/datasources/datasource-entries.js +166 -0
- package/dist-cjs/api/datasources/datasources.js +166 -0
- package/dist-cjs/api/datasources/datasources.types.js +2 -0
- package/dist-cjs/api/plugins/plugins.js +132 -0
- package/dist-cjs/api/plugins/plugins.types.js +2 -0
- package/dist-cjs/api/presets/componentPresets.js +25 -0
- package/dist-cjs/api/presets/presets.js +92 -0
- package/dist-cjs/api/presets/presets.types.js +2 -0
- package/dist-cjs/api/presets/resolvePresets.js +49 -0
- package/dist-cjs/api/roles/roles.js +131 -0
- package/dist-cjs/api/roles/roles.types.js +2 -0
- package/dist-cjs/api/spaces/spaces.js +34 -0
- package/dist-cjs/api/spaces/spaces.types.js +2 -0
- package/dist-cjs/api/stories/stories.js +214 -0
- package/dist-cjs/api/stories/stories.types.js +2 -0
- package/dist-cjs/api/sync/sync.types.js +2 -0
- package/dist-cjs/api/utils/request.js +48 -0
- package/dist-cjs/api/utils/resolvers.types.js +2 -0
- package/dist-cjs/api-v2/assets/index.js +30 -0
- package/dist-cjs/api-v2/auth/index.js +12 -0
- package/dist-cjs/api-v2/client.js +23 -0
- package/dist-cjs/api-v2/components/index.js +40 -0
- package/dist-cjs/api-v2/datasources/index.js +64 -0
- package/dist-cjs/api-v2/discover/discover.js +368 -0
- package/dist-cjs/api-v2/discover/index.js +9 -0
- package/dist-cjs/api-v2/index.js +60 -0
- package/dist-cjs/api-v2/plugins/index.js +49 -0
- package/dist-cjs/api-v2/precompile/index.js +7 -0
- package/dist-cjs/api-v2/precompile/precompile.js +136 -0
- package/dist-cjs/api-v2/presets/index.js +33 -0
- package/dist-cjs/api-v2/requestConfig.js +37 -0
- package/dist-cjs/api-v2/roles/index.js +41 -0
- package/dist-cjs/api-v2/spaces/index.js +16 -0
- package/dist-cjs/api-v2/stories/index.js +180 -0
- package/dist-cjs/api-v2/stories/types.js +2 -0
- package/dist-cjs/api-v2/sync/index.js +115 -0
- package/dist-cjs/api-v2/sync/types.js +2 -0
- package/dist-cjs/api-v2/test.js +25 -0
- package/dist-cjs/config/config.types.js +2 -0
- package/dist-cjs/config/constants.js +29 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/utils/array-utils.js +24 -0
- package/dist-cjs/utils/logger.js +32 -0
- package/dist-cjs/utils/object-utils.js +77 -0
- package/dist-cjs/utils/path-utils.js +115 -0
- package/package.json +43 -27
- package/dist/utils/pkg-require.d.ts +0 -2
- package/dist/utils/pkg-require.js +0 -4
package/README.md
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
<p align="center">
|
|
3
2
|
<img width="250" height="250" src="./sb-mig-logo.png" alt="Logo" />
|
|
4
3
|
</p>
|
|
@@ -10,17 +9,16 @@ If you've found an issue or you have feature request - <a href="https://github.c
|
|
|
10
9
|
[](https://github.com/sb-mig/sb-mig/issues?q=is%3Aopen+is%3Aissue)
|
|
11
10
|

|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
12
|
# Requirements:
|
|
16
13
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
| Node
|
|
14
|
+
| | |
|
|
15
|
+
| ---- | ------------ |
|
|
16
|
+
| Node | LTS (18.x.x) |
|
|
20
17
|
|
|
21
18
|
# 5.x.x version released!
|
|
22
19
|
|
|
23
20
|
## Important Updates
|
|
21
|
+
|
|
24
22
|
- Complete codebase overhaul to facilitate the utilization of features and requests to Storyblok. This development decreases the tight coupling with CLI, while improving folder and file structure.
|
|
25
23
|
- New feature: Content synchronization (including stories and assets) in various directions, ranging from space to space, from space to file, and from file to space.
|
|
26
24
|
- New feature: Introduced support for TypeScript Schema, with the added ability to precompile them on-the-fly before synchronization, improving usage with sb-mig.
|
|
@@ -33,12 +31,12 @@ If you've found an issue or you have feature request - <a href="https://github.c
|
|
|
33
31
|
- Expanded test coverage (with more additions anticipated).
|
|
34
32
|
|
|
35
33
|
## Breaking changes
|
|
34
|
+
|
|
36
35
|
- Please note that sb-mig no longer extends support for Node versions older than 18.x.x, as part of its adoption of native ESM support.
|
|
37
36
|
- The sb-mig backup command has now been aligned with all other commands, causing minor changes in its execution (although functionalities have been preserved).
|
|
38
37
|
|
|
39
38
|
Do not hesitate to get in touch if you encounter any issues or require further clarification on any points.
|
|
40
39
|
|
|
41
|
-
|
|
42
40
|
# 4.x.x version released!
|
|
43
41
|
|
|
44
42
|
- Whole deployment now, is handled by [semantic-release](https://github.com/semantic-release/semantic-release). And is just normal repository, instead of Lerna monorepo which is not needed anymore, and it was recently unmaintained (now it was passed to `nrwl` to maintain (https://github.com/lerna/lerna/issues/3121) will see what will happen in future with it :)
|
|
@@ -57,10 +55,10 @@ Do not hesitate to get in touch if you encounter any issues or require further c
|
|
|
57
55
|
|
|
58
56
|
- [How to install and configure](#how-to-install-and-configure)
|
|
59
57
|
- [Schema documentation:](#schema-documentation)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
- [Basics](#basics)
|
|
59
|
+
- [Syncing components](#syncing-components)
|
|
60
|
+
- [Syncing datasources](#syncing-datasources)
|
|
61
|
+
- [Presets support](#presets-support)
|
|
64
62
|
- [Development](#development)
|
|
65
63
|
- [Roadmap](#roadmap)
|
|
66
64
|
|
|
@@ -189,7 +187,6 @@ sb-mig sync components row column
|
|
|
189
187
|
|
|
190
188
|
This command will look for `row.sb.js` and `column.sb.js` files inside a directories mentioned in `componentDirectories` field. (You can change directories name mapping by modifying `componentDirectories` inside `storyblok.config.js`). You can also change the extension searched by changing `schemaFileExt`. [How to install and configure](#how-to-install-and-configure))
|
|
191
189
|
|
|
192
|
-
|
|
193
190
|
## Syncing datasources
|
|
194
191
|
|
|
195
192
|
You can also sync your `datasources`.
|
|
@@ -269,7 +266,6 @@ You can also sync all datasources, and that's the command we strongly recommend.
|
|
|
269
266
|
sb-mig sync datasources --all
|
|
270
267
|
```
|
|
271
268
|
|
|
272
|
-
|
|
273
269
|
## Presets support
|
|
274
270
|
|
|
275
271
|
Writing your own predefined data (presets) for components can be a pain, so with `sb-mig` you can create presets for your components in the storyblok gui, and then export them to a schema based `.sb.js` file to be picked up while syncing.
|
|
@@ -342,36 +338,41 @@ git clone git@github.com:sb-mig/sb-mig.git
|
|
|
342
338
|
Install packages
|
|
343
339
|
|
|
344
340
|
```
|
|
345
|
-
|
|
341
|
+
npm install
|
|
346
342
|
```
|
|
347
343
|
|
|
348
344
|
Run development command
|
|
345
|
+
|
|
349
346
|
```bash
|
|
350
|
-
|
|
347
|
+
npm run build:dev
|
|
351
348
|
```
|
|
352
349
|
|
|
353
350
|
It will watch a file change, and on every change, will rebuild typescript and build the whole lib/cli.
|
|
354
351
|
|
|
355
|
-
The you can use
|
|
352
|
+
The you can use
|
|
353
|
+
|
|
356
354
|
```
|
|
357
|
-
node dist/index.js debug
|
|
355
|
+
node dist/index.js debug
|
|
358
356
|
```
|
|
357
|
+
|
|
359
358
|
to access `sb-mig`
|
|
360
359
|
|
|
361
360
|
For your conveniece, you can also, link it to proper `sb-mi` name:
|
|
361
|
+
|
|
362
362
|
```
|
|
363
|
-
|
|
363
|
+
npm link
|
|
364
364
|
```
|
|
365
365
|
|
|
366
366
|
And then you can use it like that:
|
|
367
|
+
|
|
367
368
|
```
|
|
368
369
|
sb-mig debug
|
|
369
370
|
```
|
|
370
371
|
|
|
371
|
-
|
|
372
372
|
# Releasing
|
|
373
373
|
|
|
374
374
|
## Flow of branching out and merging
|
|
375
|
+
|
|
375
376
|
- Before creating feature branch from beta, make sure you have newest beta. (by `git pull origin beta`).
|
|
376
377
|
- Create feature branch from beta
|
|
377
378
|
- Do your changes
|
|
@@ -4,6 +4,7 @@ import path from "path";
|
|
|
4
4
|
import FormData from "form-data";
|
|
5
5
|
import { createDir, isDirectoryExists } from "../../utils/files.js";
|
|
6
6
|
import Logger from "../../utils/logger.js";
|
|
7
|
+
import { getFileName, getSizeFromURL } from "../../utils/string-utils.js";
|
|
7
8
|
// GET
|
|
8
9
|
export const getAllAssets = async (args, config) => {
|
|
9
10
|
const { spaceId, search } = args;
|
|
@@ -37,7 +38,7 @@ export const getAssetByName = async ({ spaceId, fileName }, config) => {
|
|
|
37
38
|
};
|
|
38
39
|
const requestSignedUploadUrl = ({ spaceId, payload }, config) => {
|
|
39
40
|
const { sbApi, debug } = config;
|
|
40
|
-
const { filename: _1, asset_folder_id, ext_id, space_id, ...restPayload } = payload;
|
|
41
|
+
const { filename: _1, asset_folder_id, ext_id, space_id, deleted_at: _2, ...restPayload } = payload;
|
|
41
42
|
const filename = getFileName(payload.filename);
|
|
42
43
|
const size = getSizeFromURL(payload.filename);
|
|
43
44
|
return sbApi
|
|
@@ -77,20 +78,6 @@ const uploadFile = ({ signedResponseObject, pathToFile }) => {
|
|
|
77
78
|
}
|
|
78
79
|
});
|
|
79
80
|
};
|
|
80
|
-
const getFileName = (fileUrl) => {
|
|
81
|
-
const fileName = fileUrl.split("/").pop();
|
|
82
|
-
if (fileName) {
|
|
83
|
-
return fileName;
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
throw Error("File name couldn't be extracted from URL.");
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
const getSizeFromURL = (fileUrl) => {
|
|
90
|
-
const data = fileUrl.split("/");
|
|
91
|
-
const sizePos = data.length - 3;
|
|
92
|
-
return data[sizePos];
|
|
93
|
-
};
|
|
94
81
|
const downloadAsset = async (args, config) => {
|
|
95
82
|
const { debug, sbmigWorkingDirectory } = config;
|
|
96
83
|
const { payload } = args;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RequestBaseConfig } from "../utils/request.js";
|
|
2
|
-
import type { ISbResult } from "storyblok-js-client
|
|
2
|
+
import type { ISbResult } from "storyblok-js-client";
|
|
3
3
|
export interface Org {
|
|
4
4
|
}
|
|
5
5
|
export interface CurrentUserResult extends ISbResult {
|
|
@@ -55,7 +55,7 @@ export const createComponent = (component, presets, config) => {
|
|
|
55
55
|
Logger.log(`Trying to create '${component.name}'`);
|
|
56
56
|
const componentWithPresets = component;
|
|
57
57
|
const { all_presets, ...componentWithoutPresets } = componentWithPresets;
|
|
58
|
-
sbApi
|
|
58
|
+
return sbApi
|
|
59
59
|
.post(`spaces/${spaceId}/components/`, {
|
|
60
60
|
component: componentWithoutPresets,
|
|
61
61
|
})
|
|
@@ -67,6 +67,7 @@ export const createComponent = (component, presets, config) => {
|
|
|
67
67
|
})
|
|
68
68
|
.catch((err) => {
|
|
69
69
|
Logger.error(`${err.message} in migration of ${component.name} in createComponent function`);
|
|
70
|
+
throw err;
|
|
70
71
|
});
|
|
71
72
|
};
|
|
72
73
|
/*
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SyncProgressCallback, SyncResult } from "../sync/sync.types.js";
|
|
2
|
+
import type { RequestBaseConfig } from "../utils/request.js";
|
|
3
|
+
export declare function syncComponentsData(args: {
|
|
4
|
+
components: any[];
|
|
5
|
+
presets: boolean;
|
|
6
|
+
ssot?: boolean;
|
|
7
|
+
onProgress?: SyncProgressCallback;
|
|
8
|
+
}, config: RequestBaseConfig): Promise<SyncResult>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { uniqueValuesFrom } from "../../utils/array-utils.js";
|
|
2
|
+
import Logger from "../../utils/logger.js";
|
|
3
|
+
import { isObjectEmpty } from "../../utils/object-utils.js";
|
|
4
|
+
/**
|
|
5
|
+
* Default progress callback that logs to console
|
|
6
|
+
*/
|
|
7
|
+
const defaultProgress = (event) => {
|
|
8
|
+
if (event.type === "start") {
|
|
9
|
+
Logger.log(`Starting sync of ${event.total} components...`);
|
|
10
|
+
}
|
|
11
|
+
else if (event.type === "progress" && event.name) {
|
|
12
|
+
const status = event.action === "creating"
|
|
13
|
+
? "Creating"
|
|
14
|
+
: event.action === "updating"
|
|
15
|
+
? "Updating"
|
|
16
|
+
: event.action === "created"
|
|
17
|
+
? "✓ Created"
|
|
18
|
+
: event.action === "updated"
|
|
19
|
+
? "✓ Updated"
|
|
20
|
+
: event.action === "skipped"
|
|
21
|
+
? "⏭ Skipped"
|
|
22
|
+
: "✘ Error";
|
|
23
|
+
Logger.log(`[${event.current}/${event.total}] ${status}: ${event.name}`);
|
|
24
|
+
}
|
|
25
|
+
else if (event.type === "complete") {
|
|
26
|
+
Logger.success(`Sync complete: ${event.message ?? "done"}`);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
import { createComponent, createComponentsGroup, getAllComponents, getAllComponentsGroups, removeComponent, removeComponentGroup, updateComponent, } from "./components.js";
|
|
30
|
+
async function ensureComponentGroupsExist(groupNames, config) {
|
|
31
|
+
try {
|
|
32
|
+
const existing = await getAllComponentsGroups(config);
|
|
33
|
+
const existingNames = new Set((existing ?? []).map((g) => g.name));
|
|
34
|
+
for (const groupName of groupNames) {
|
|
35
|
+
if (!existingNames.has(groupName)) {
|
|
36
|
+
await createComponentsGroup(groupName, config);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
// Log but don't fail - component groups are optional
|
|
42
|
+
Logger.warning(`Could not fetch component groups: ${error instanceof Error ? error.message : String(error)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function resolveGroupUuid(component, remoteGroups) {
|
|
46
|
+
if (!component.component_group_name) {
|
|
47
|
+
return { ...component, component_group_uuid: null };
|
|
48
|
+
}
|
|
49
|
+
const match = remoteGroups.find((g) => g.name === component.component_group_name);
|
|
50
|
+
if (!match)
|
|
51
|
+
return { ...component, component_group_uuid: null };
|
|
52
|
+
return { ...component, component_group_uuid: match.uuid };
|
|
53
|
+
}
|
|
54
|
+
export async function syncComponentsData(args, config) {
|
|
55
|
+
const { components, presets, ssot, onProgress } = args;
|
|
56
|
+
const progress = onProgress ?? defaultProgress;
|
|
57
|
+
const result = {
|
|
58
|
+
created: [],
|
|
59
|
+
updated: [],
|
|
60
|
+
skipped: [],
|
|
61
|
+
errors: [],
|
|
62
|
+
};
|
|
63
|
+
if (ssot) {
|
|
64
|
+
const existingComponents = await getAllComponents(config);
|
|
65
|
+
const existingGroups = await getAllComponentsGroups(config);
|
|
66
|
+
await Promise.allSettled([
|
|
67
|
+
...(existingComponents ?? []).map((c) => removeComponent(c, config)),
|
|
68
|
+
...(existingGroups ?? []).map((g) => removeComponentGroup(g, config)),
|
|
69
|
+
]);
|
|
70
|
+
}
|
|
71
|
+
const nonEmptyComponents = components.filter((c) => !isObjectEmpty(c));
|
|
72
|
+
const groupsToCheck = uniqueValuesFrom(nonEmptyComponents
|
|
73
|
+
.filter((c) => c.component_group_name)
|
|
74
|
+
.map((c) => c.component_group_name));
|
|
75
|
+
await ensureComponentGroupsExist(groupsToCheck, config);
|
|
76
|
+
let remoteComponents = [];
|
|
77
|
+
let remoteGroups = [];
|
|
78
|
+
try {
|
|
79
|
+
remoteComponents = (await getAllComponents(config)) ?? [];
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
Logger.warning(`Could not fetch remote components: ${error instanceof Error ? error.message : String(error)}`);
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
remoteGroups = (await getAllComponentsGroups(config)) ?? [];
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
Logger.warning(`Could not fetch remote groups: ${error instanceof Error ? error.message : String(error)}`);
|
|
89
|
+
}
|
|
90
|
+
const componentsToUpdate = [];
|
|
91
|
+
const componentsToCreate = [];
|
|
92
|
+
for (const component of nonEmptyComponents) {
|
|
93
|
+
if (!component?.name) {
|
|
94
|
+
result.skipped.push("unknown");
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const remote = remoteComponents.find((rc) => rc.name === component.name);
|
|
98
|
+
if (remote) {
|
|
99
|
+
componentsToUpdate.push({ id: remote.id, ...component });
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
componentsToCreate.push(component);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Resolve group uuids after ensureComponentGroupsExist
|
|
106
|
+
const updatePayloads = componentsToUpdate.map((c) => resolveGroupUuid(c, remoteGroups));
|
|
107
|
+
const createPayloads = componentsToCreate.map((c) => resolveGroupUuid(c, remoteGroups));
|
|
108
|
+
const totalComponents = updatePayloads.length + createPayloads.length;
|
|
109
|
+
let currentIndex = 0;
|
|
110
|
+
// Report start
|
|
111
|
+
progress({ type: "start", total: totalComponents });
|
|
112
|
+
// Process updates sequentially for progress reporting
|
|
113
|
+
for (const component of updatePayloads) {
|
|
114
|
+
const name = String(component?.name ?? "unknown");
|
|
115
|
+
currentIndex++;
|
|
116
|
+
progress({
|
|
117
|
+
type: "progress",
|
|
118
|
+
current: currentIndex,
|
|
119
|
+
total: totalComponents,
|
|
120
|
+
name,
|
|
121
|
+
action: "updating",
|
|
122
|
+
});
|
|
123
|
+
try {
|
|
124
|
+
await updateComponent(component, presets, config);
|
|
125
|
+
result.updated.push(name);
|
|
126
|
+
progress({
|
|
127
|
+
type: "progress",
|
|
128
|
+
current: currentIndex,
|
|
129
|
+
total: totalComponents,
|
|
130
|
+
name,
|
|
131
|
+
action: "updated",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
result.errors.push({
|
|
136
|
+
name,
|
|
137
|
+
message: error instanceof Error ? error.message : String(error),
|
|
138
|
+
});
|
|
139
|
+
progress({
|
|
140
|
+
type: "progress",
|
|
141
|
+
current: currentIndex,
|
|
142
|
+
total: totalComponents,
|
|
143
|
+
name,
|
|
144
|
+
action: "error",
|
|
145
|
+
message: error instanceof Error ? error.message : String(error),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Process creates sequentially for progress reporting
|
|
150
|
+
for (const component of createPayloads) {
|
|
151
|
+
const name = String(component?.name ?? "unknown");
|
|
152
|
+
currentIndex++;
|
|
153
|
+
progress({
|
|
154
|
+
type: "progress",
|
|
155
|
+
current: currentIndex,
|
|
156
|
+
total: totalComponents,
|
|
157
|
+
name,
|
|
158
|
+
action: "creating",
|
|
159
|
+
});
|
|
160
|
+
try {
|
|
161
|
+
await createComponent(component, presets, config);
|
|
162
|
+
result.created.push(name);
|
|
163
|
+
progress({
|
|
164
|
+
type: "progress",
|
|
165
|
+
current: currentIndex,
|
|
166
|
+
total: totalComponents,
|
|
167
|
+
name,
|
|
168
|
+
action: "created",
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
result.errors.push({
|
|
173
|
+
name,
|
|
174
|
+
message: error instanceof Error ? error.message : String(error),
|
|
175
|
+
});
|
|
176
|
+
progress({
|
|
177
|
+
type: "progress",
|
|
178
|
+
current: currentIndex,
|
|
179
|
+
total: totalComponents,
|
|
180
|
+
name,
|
|
181
|
+
action: "error",
|
|
182
|
+
message: error instanceof Error ? error.message : String(error),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Report completion
|
|
187
|
+
progress({
|
|
188
|
+
type: "complete",
|
|
189
|
+
total: totalComponents,
|
|
190
|
+
message: `${result.created.length} created, ${result.updated.length} updated, ${result.errors.length} errors`,
|
|
191
|
+
});
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
@@ -2,10 +2,10 @@ import path from "path";
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import { discoverMigrationConfig, discoverStories, LOOKUP_TYPE, SCOPE, } from "../../cli/utils/discover.js";
|
|
4
4
|
import storyblokConfig from "../../config/config.js";
|
|
5
|
-
import { createAndSaveToFile } from "../../utils/files.js";
|
|
5
|
+
import { createAndSaveToFile, getFilesContentWithRequire, } from "../../utils/files.js";
|
|
6
6
|
import Logger from "../../utils/logger.js";
|
|
7
|
-
import { getFilesContentWithRequire, isObjectEmpty } from "../../utils/main.js";
|
|
8
7
|
import { modifyOrCreateAppliedMigrationsFile } from "../../utils/migrations.js";
|
|
8
|
+
import { isObjectEmpty } from "../../utils/object-utils.js";
|
|
9
9
|
import { managementApi } from "../managementApi.js";
|
|
10
10
|
function replaceComponentData({ parent, key, components, mapper, depth, maxDepth, sumOfReplacing, }) {
|
|
11
11
|
let currentMaxDepth = depth;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import storyblokConfig from "../../config/config.js";
|
|
3
2
|
import Logger from "../../utils/logger.js";
|
|
4
|
-
import { isObjectEmpty } from "../../utils/
|
|
3
|
+
import { isObjectEmpty } from "../../utils/object-utils.js";
|
|
5
4
|
import { getDatasource } from "./datasources.js";
|
|
6
5
|
const _decorateWithDimensions = async (args, config) => {
|
|
7
6
|
const { currentDatasource, dimensionsData, _callback } = args;
|
|
@@ -67,7 +66,7 @@ export const createDatasourceEntries = (args, config) => {
|
|
|
67
66
|
const _createDatasourceEntry = (args, config) => {
|
|
68
67
|
const { currentDatasource, finalDatasource_entry } = args;
|
|
69
68
|
const { spaceId, sbApi } = config;
|
|
70
|
-
if (
|
|
69
|
+
if (config.debug) {
|
|
71
70
|
console.log("############# Entity to Create: ");
|
|
72
71
|
console.log(finalDatasource_entry);
|
|
73
72
|
console.log("################################");
|
|
@@ -81,7 +80,7 @@ const _createDatasourceEntry = (args, config) => {
|
|
|
81
80
|
return data;
|
|
82
81
|
})
|
|
83
82
|
.catch((err) => {
|
|
84
|
-
if (
|
|
83
|
+
if (config.debug) {
|
|
85
84
|
console.log("Full Create error: ");
|
|
86
85
|
console.log(err);
|
|
87
86
|
}
|
|
@@ -122,7 +121,7 @@ const _updateDatasourceEntry = (args, config) => {
|
|
|
122
121
|
return true;
|
|
123
122
|
})
|
|
124
123
|
.catch((err) => {
|
|
125
|
-
if (
|
|
124
|
+
if (config.debug) {
|
|
126
125
|
console.log("Full update error: ");
|
|
127
126
|
console.log(err);
|
|
128
127
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type { CreateDatasource, GetAllDatasources, GetDatasource,
|
|
1
|
+
import type { CreateDatasource, GetAllDatasources, GetDatasource, UpdateDatasource } from "./datasources.types.js";
|
|
2
|
+
import type { SyncResult } from "../sync/sync.types.js";
|
|
2
3
|
export declare const getAllDatasources: GetAllDatasources;
|
|
3
4
|
export declare const getDatasource: GetDatasource;
|
|
4
5
|
export declare const createDatasource: CreateDatasource;
|
|
5
6
|
export declare const updateDatasource: UpdateDatasource;
|
|
6
|
-
export declare const
|
|
7
|
+
export declare const syncDatasourcesData: ({ datasources }: {
|
|
8
|
+
datasources: any[];
|
|
9
|
+
}, config: any) => Promise<SyncResult>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import Logger from "../../utils/logger.js";
|
|
2
|
-
import { getFileContentWithRequire, } from "../../utils/main.js";
|
|
3
2
|
import { getAllItemsWithPagination } from "../utils/request.js";
|
|
4
3
|
import { createDatasourceEntries, getDatasourceEntries, } from "./datasource-entries.js";
|
|
5
4
|
// GET
|
|
@@ -110,39 +109,47 @@ export const updateDatasource = (args, config) => {
|
|
|
110
109
|
})
|
|
111
110
|
.catch((err) => Logger.error(err));
|
|
112
111
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
112
|
+
// File-based sync wrapper lives in `datasources.sync.ts` to keep this module CJS-safe.
|
|
113
|
+
export const syncDatasourcesData = async ({ datasources }, config) => {
|
|
114
|
+
const result = {
|
|
115
|
+
created: [],
|
|
116
|
+
updated: [],
|
|
117
|
+
skipped: [],
|
|
118
|
+
errors: [],
|
|
119
|
+
};
|
|
120
|
+
const remoteDatasourcesRaw = await getAllDatasources(config);
|
|
121
|
+
const remoteDatasources = Array.isArray(remoteDatasourcesRaw)
|
|
122
|
+
? remoteDatasourcesRaw
|
|
123
|
+
: [];
|
|
124
|
+
for (const datasource of datasources) {
|
|
125
|
+
const name = String(datasource?.name ?? "unknown");
|
|
126
|
+
if (!datasource || typeof datasource !== "object" || !datasource.name) {
|
|
127
|
+
result.skipped.push(name);
|
|
128
|
+
continue;
|
|
124
129
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
130
|
+
try {
|
|
131
|
+
const datasourceToBeUpdated = remoteDatasources.find((remoteDatasource) => datasource.name === remoteDatasource.name);
|
|
132
|
+
const opResult = datasourceToBeUpdated
|
|
133
|
+
? await updateDatasource({ datasource, datasourceToBeUpdated }, config)
|
|
134
|
+
: await createDatasource({ datasource }, config);
|
|
135
|
+
if (datasourceToBeUpdated)
|
|
136
|
+
result.updated.push(name);
|
|
137
|
+
else
|
|
138
|
+
result.created.push(name);
|
|
139
|
+
if (opResult?.data?.datasource && opResult?.datasource_entries) {
|
|
140
|
+
const remoteDatasourceEntries = await getDatasourceEntries({
|
|
141
|
+
datasourceName: opResult.data.datasource.name,
|
|
142
|
+
}, config);
|
|
143
|
+
await createDatasourceEntries({
|
|
144
|
+
data: opResult.data,
|
|
145
|
+
datasource_entries: opResult.datasource_entries,
|
|
146
|
+
remoteDatasourceEntries,
|
|
147
|
+
}, config);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
result.errors.push({ name, message: String(e) });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
148
155
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getFileContentWithRequire } from "../../utils/files.js";
|
|
2
|
+
import Logger from "../../utils/logger.js";
|
|
3
|
+
import { syncDatasourcesData } from "./datasources.js";
|
|
4
|
+
export const syncDatasources = async (args, config) => {
|
|
5
|
+
const { providedDatasources } = args;
|
|
6
|
+
Logger.log(`Trying to sync provided datasources: `);
|
|
7
|
+
const providedDatasourcesContent = await Promise.all(providedDatasources.map((datasource) => {
|
|
8
|
+
return getFileContentWithRequire({ file: datasource.p });
|
|
9
|
+
}));
|
|
10
|
+
await syncDatasourcesData({ datasources: providedDatasourcesContent }, config);
|
|
11
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OneFileElement } from "../../
|
|
1
|
+
import type { OneFileElement } from "../../utils/path-utils.js";
|
|
2
2
|
import type { RequestBaseConfig } from "../utils/request.js";
|
|
3
3
|
export type GetAllDatasources = (config: RequestBaseConfig) => Promise<any>;
|
|
4
4
|
export type GetDatasource = (args: {
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { createDatasource, getDatasource, getAllDatasources,
|
|
1
|
+
export { createDatasource, getDatasource, getAllDatasources, updateDatasource, } from "./datasources.js";
|
|
2
|
+
export { syncDatasources } from "./datasources.sync.js";
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { createDatasource, getDatasource, getAllDatasources,
|
|
1
|
+
export { createDatasource, getDatasource, getAllDatasources, updateDatasource, } from "./datasources.js";
|
|
2
|
+
export { syncDatasources } from "./datasources.sync.js";
|
|
@@ -25,8 +25,8 @@ export declare const managementApi: {
|
|
|
25
25
|
createDatasource: import("./datasources/datasources.types.js").CreateDatasource;
|
|
26
26
|
getDatasource: import("./datasources/datasources.types.js").GetDatasource;
|
|
27
27
|
getAllDatasources: import("./datasources/datasources.types.js").GetAllDatasources;
|
|
28
|
-
syncDatasources: import("./datasources/datasources.types.js").SyncDatasources;
|
|
29
28
|
updateDatasource: import("./datasources/datasources.types.js").UpdateDatasource;
|
|
29
|
+
syncDatasources: import("./datasources/datasources.types.js").SyncDatasources;
|
|
30
30
|
};
|
|
31
31
|
plugins: {
|
|
32
32
|
getAllPlugins: import("./plugins/plugins.types.js").GetAllPlugins;
|
|
@@ -48,8 +48,8 @@ export declare const managementApi: {
|
|
|
48
48
|
createRole: import("./roles/roles.types.js").CreateRole;
|
|
49
49
|
getRole: import("./roles/roles.types.js").GetRole;
|
|
50
50
|
getAllRoles: import("./roles/roles.types.js").GetAllRoles;
|
|
51
|
-
syncRoles: import("./roles/roles.types.js").SyncRoles;
|
|
52
51
|
updateRole: import("./roles/roles.types.js").UpdateRole;
|
|
52
|
+
syncRoles: import("./roles/roles.types.js").SyncRoles;
|
|
53
53
|
};
|
|
54
54
|
stories: {
|
|
55
55
|
createStory: import("./stories/stories.types.js").CreateStory;
|
package/dist/api/migrate.d.ts
CHANGED
|
@@ -10,6 +10,6 @@ export declare const syncAssets: SyncAssets;
|
|
|
10
10
|
export declare const syncContent: SyncContentFunction;
|
|
11
11
|
export declare const setComponentDefaultPreset: ({ presets, componentsToSync, apiConfig, }: {
|
|
12
12
|
presets: boolean;
|
|
13
|
-
componentsToSync?: string[]
|
|
13
|
+
componentsToSync?: string[];
|
|
14
14
|
apiConfig: RequestBaseConfig;
|
|
15
15
|
}) => Promise<false | any[]>;
|