sb-mig 5.6.0-beta.1 → 5.6.0-beta.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 +20 -19
- package/dist/api/assets/assets.js +1 -14
- 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 +36 -0
- package/dist/api-v2/discover/discover.js +281 -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 +4 -51
- 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 +321 -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 +37 -20
- package/dist/utils/pkg-require.d.ts +0 -2
- package/dist/utils/pkg-require.js +0 -4
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object transformation utilities
|
|
3
|
+
* Pure functions for deep object manipulation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Recursively extend a field in a nested object
|
|
7
|
+
* If the field is an array, appends unique values
|
|
8
|
+
* If the field is an object, merges properties
|
|
9
|
+
*
|
|
10
|
+
* @param obj - The object to search and extend
|
|
11
|
+
* @param targetField - The field name to find and extend
|
|
12
|
+
* @param newValue - The value(s) to add
|
|
13
|
+
* @returns true if field was found and extended, false otherwise
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const obj = { schema: { items: ['a', 'b'] } };
|
|
17
|
+
* extendField(obj, 'items', ['c', 'd']);
|
|
18
|
+
* // obj.schema.items is now ['a', 'b', 'c', 'd']
|
|
19
|
+
*/
|
|
20
|
+
export declare const extendField: (obj: any, targetField: string, newValue: any) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Deep transform an object using a transformer specification
|
|
23
|
+
* Supports function transformers, nested object transformers, and literal values
|
|
24
|
+
*
|
|
25
|
+
* @param obj - The source object to transform
|
|
26
|
+
* @param transformers - Specification object where:
|
|
27
|
+
* - function values: called with current value, result used as new value
|
|
28
|
+
* - object values: recursively applied to nested objects
|
|
29
|
+
* - other values: used directly as the new value
|
|
30
|
+
* @returns New transformed object (original is not mutated)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const obj = { name: 'hero', count: 5 };
|
|
34
|
+
* const result = deepTransform(obj, {
|
|
35
|
+
* name: (v) => v.toUpperCase(),
|
|
36
|
+
* count: (v) => v * 2,
|
|
37
|
+
* });
|
|
38
|
+
* // result: { name: 'HERO', count: 10 }
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Nested transformation
|
|
42
|
+
* const obj = { schema: { title: 'old' } };
|
|
43
|
+
* const result = deepTransform(obj, {
|
|
44
|
+
* schema: { title: 'new' }
|
|
45
|
+
* });
|
|
46
|
+
* // result: { schema: { title: 'new' } }
|
|
47
|
+
*/
|
|
48
|
+
export declare function deepTransform(obj: any, transformers: any): any;
|
|
49
|
+
/**
|
|
50
|
+
* Check if a component has content available as bloks
|
|
51
|
+
*
|
|
52
|
+
* @param component - Storyblok component schema
|
|
53
|
+
* @returns true if component.schema.content is a bloks field with whitelist
|
|
54
|
+
*/
|
|
55
|
+
export declare const isContentAvailableAsBloks: (component: any) => boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Check if a component has items available as bloks
|
|
58
|
+
*
|
|
59
|
+
* @param component - Storyblok component schema
|
|
60
|
+
* @returns true if component.schema.items is a bloks field with whitelist
|
|
61
|
+
*/
|
|
62
|
+
export declare const isItemsAvailableAsBloks: (component: any) => boolean;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object transformation utilities
|
|
3
|
+
* Pure functions for deep object manipulation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Recursively extend a field in a nested object
|
|
7
|
+
* If the field is an array, appends unique values
|
|
8
|
+
* If the field is an object, merges properties
|
|
9
|
+
*
|
|
10
|
+
* @param obj - The object to search and extend
|
|
11
|
+
* @param targetField - The field name to find and extend
|
|
12
|
+
* @param newValue - The value(s) to add
|
|
13
|
+
* @returns true if field was found and extended, false otherwise
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const obj = { schema: { items: ['a', 'b'] } };
|
|
17
|
+
* extendField(obj, 'items', ['c', 'd']);
|
|
18
|
+
* // obj.schema.items is now ['a', 'b', 'c', 'd']
|
|
19
|
+
*/
|
|
20
|
+
export const extendField = (obj, targetField, newValue) => {
|
|
21
|
+
if (typeof obj !== "object" || obj === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (obj.hasOwnProperty(targetField)) {
|
|
25
|
+
if (Array.isArray(obj[targetField])) {
|
|
26
|
+
for (const element of newValue) {
|
|
27
|
+
if (!obj[targetField].includes(element)) {
|
|
28
|
+
obj[targetField] = [...obj[targetField], element];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (typeof obj[targetField] === "object") {
|
|
33
|
+
obj[targetField] = { ...obj[targetField], ...newValue };
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
for (const key in obj) {
|
|
38
|
+
if (extendField(obj[key], targetField, newValue)) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Deep transform an object using a transformer specification
|
|
46
|
+
* Supports function transformers, nested object transformers, and literal values
|
|
47
|
+
*
|
|
48
|
+
* @param obj - The source object to transform
|
|
49
|
+
* @param transformers - Specification object where:
|
|
50
|
+
* - function values: called with current value, result used as new value
|
|
51
|
+
* - object values: recursively applied to nested objects
|
|
52
|
+
* - other values: used directly as the new value
|
|
53
|
+
* @returns New transformed object (original is not mutated)
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* const obj = { name: 'hero', count: 5 };
|
|
57
|
+
* const result = deepTransform(obj, {
|
|
58
|
+
* name: (v) => v.toUpperCase(),
|
|
59
|
+
* count: (v) => v * 2,
|
|
60
|
+
* });
|
|
61
|
+
* // result: { name: 'HERO', count: 10 }
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Nested transformation
|
|
65
|
+
* const obj = { schema: { title: 'old' } };
|
|
66
|
+
* const result = deepTransform(obj, {
|
|
67
|
+
* schema: { title: 'new' }
|
|
68
|
+
* });
|
|
69
|
+
* // result: { schema: { title: 'new' } }
|
|
70
|
+
*/
|
|
71
|
+
export function deepTransform(obj, transformers) {
|
|
72
|
+
if (typeof obj !== "object" || obj === null) {
|
|
73
|
+
return obj;
|
|
74
|
+
}
|
|
75
|
+
const result = Array.isArray(obj) ? [...obj] : { ...obj };
|
|
76
|
+
for (const key in transformers) {
|
|
77
|
+
if (typeof transformers[key] === "function") {
|
|
78
|
+
result[key] = transformers[key](obj[key]);
|
|
79
|
+
}
|
|
80
|
+
else if (typeof transformers[key] === "object" &&
|
|
81
|
+
transformers[key] !== null) {
|
|
82
|
+
result[key] = deepTransform(obj[key] || {}, transformers[key]);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
result[key] = transformers[key];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Preserve untransformed properties
|
|
89
|
+
for (const key in obj) {
|
|
90
|
+
if (!(key in transformers)) {
|
|
91
|
+
result[key] = obj[key];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if a component has content available as bloks
|
|
98
|
+
*
|
|
99
|
+
* @param component - Storyblok component schema
|
|
100
|
+
* @returns true if component.schema.content is a bloks field with whitelist
|
|
101
|
+
*/
|
|
102
|
+
export const isContentAvailableAsBloks = (component) => "content" in component.schema &&
|
|
103
|
+
component.schema.content.component_whitelist &&
|
|
104
|
+
component.schema.content.type === "bloks";
|
|
105
|
+
/**
|
|
106
|
+
* Check if a component has items available as bloks
|
|
107
|
+
*
|
|
108
|
+
* @param component - Storyblok component schema
|
|
109
|
+
* @returns true if component.schema.items is a bloks field with whitelist
|
|
110
|
+
*/
|
|
111
|
+
export const isItemsAvailableAsBloks = (component) => "items" in component.schema &&
|
|
112
|
+
component.schema.items.component_whitelist &&
|
|
113
|
+
component.schema.items.type === "bloks";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasAccessToSpace = exports.getCurrentUser = void 0;
|
|
4
|
+
const spaces_js_1 = require("../spaces/spaces.js");
|
|
5
|
+
const getCurrentUser = async (config) => {
|
|
6
|
+
const { sbApi } = config;
|
|
7
|
+
console.log("Trying to get current user current OAuthToken");
|
|
8
|
+
const currentUser = await sbApi
|
|
9
|
+
.get(`users/me`, {
|
|
10
|
+
per_page: 100,
|
|
11
|
+
})
|
|
12
|
+
.then((res) => {
|
|
13
|
+
return res.data.user;
|
|
14
|
+
})
|
|
15
|
+
.catch((err) => {
|
|
16
|
+
console.error(err);
|
|
17
|
+
return err;
|
|
18
|
+
});
|
|
19
|
+
return currentUser;
|
|
20
|
+
};
|
|
21
|
+
exports.getCurrentUser = getCurrentUser;
|
|
22
|
+
const hasAccessToSpace = async (args, config) => {
|
|
23
|
+
const { spaceId } = args;
|
|
24
|
+
const allSpaces = await (0, spaces_js_1.getAllSpaces)(config);
|
|
25
|
+
const hasAccess = allSpaces.find((space) => Number(space.id) === Number(spaceId));
|
|
26
|
+
return !!hasAccess;
|
|
27
|
+
};
|
|
28
|
+
exports.hasAccessToSpace = hasAccessToSpace;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createComponentsGroup = exports.removeComponentGroup = exports.getComponentsGroup = exports.getAllComponentsGroups = exports.removeComponent = exports.updateComponent = exports.createComponent = exports.getComponent = exports.getAllComponents = void 0;
|
|
7
|
+
const logger_js_1 = __importDefault(require("../../utils/logger.js"));
|
|
8
|
+
const resolvePresets_js_1 = __importDefault(require("../presets/resolvePresets.js"));
|
|
9
|
+
const request_js_1 = require("../utils/request.js");
|
|
10
|
+
/*
|
|
11
|
+
*
|
|
12
|
+
* GET ALL components
|
|
13
|
+
*
|
|
14
|
+
* */
|
|
15
|
+
const getAllComponents = (config) => {
|
|
16
|
+
const { spaceId, sbApi } = config;
|
|
17
|
+
logger_js_1.default.log("Trying to get all components.");
|
|
18
|
+
return (0, request_js_1.getAllItemsWithPagination)({
|
|
19
|
+
apiFn: ({ per_page, page }) => sbApi
|
|
20
|
+
.get(`spaces/${spaceId}/components/`, { per_page, page })
|
|
21
|
+
.then((res) => {
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* Not every endpoint in storyblok give us pagination...
|
|
25
|
+
* so only for this who paginate we want to console log amount found.
|
|
26
|
+
*
|
|
27
|
+
* */
|
|
28
|
+
if (res.total) {
|
|
29
|
+
logger_js_1.default.log(`Amount of components: ${res.total}`);
|
|
30
|
+
}
|
|
31
|
+
return res;
|
|
32
|
+
})
|
|
33
|
+
.catch((err) => console.error(err)),
|
|
34
|
+
params: {
|
|
35
|
+
spaceId,
|
|
36
|
+
},
|
|
37
|
+
itemsKey: "components",
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
exports.getAllComponents = getAllComponents;
|
|
41
|
+
/*
|
|
42
|
+
*
|
|
43
|
+
* GET ONE component
|
|
44
|
+
*
|
|
45
|
+
* */
|
|
46
|
+
const getComponent = (componentName, config) => {
|
|
47
|
+
logger_js_1.default.log(`Trying to get '${componentName}' component.`);
|
|
48
|
+
return (0, exports.getAllComponents)(config)
|
|
49
|
+
.then((res) => res.filter((component) => component.name === componentName))
|
|
50
|
+
.then((res) => {
|
|
51
|
+
if (Array.isArray(res) && res.length === 0) {
|
|
52
|
+
console.info(`There is no component named '${componentName}'`);
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return res;
|
|
56
|
+
})
|
|
57
|
+
.catch((err) => console.error(err));
|
|
58
|
+
};
|
|
59
|
+
exports.getComponent = getComponent;
|
|
60
|
+
// CREATE
|
|
61
|
+
const createComponent = (component, presets, config) => {
|
|
62
|
+
const { spaceId, sbApi } = config;
|
|
63
|
+
logger_js_1.default.log(`Trying to create '${component.name}'`);
|
|
64
|
+
const componentWithPresets = component;
|
|
65
|
+
const { all_presets, ...componentWithoutPresets } = componentWithPresets;
|
|
66
|
+
return sbApi
|
|
67
|
+
.post(`spaces/${spaceId}/components/`, {
|
|
68
|
+
component: componentWithoutPresets,
|
|
69
|
+
})
|
|
70
|
+
.then((res) => {
|
|
71
|
+
logger_js_1.default.success(`Component '${component.name}' has been created.`);
|
|
72
|
+
if (presets) {
|
|
73
|
+
(0, resolvePresets_js_1.default)(res, all_presets, component, config);
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.catch((err) => {
|
|
77
|
+
logger_js_1.default.error(`${err.message} in migration of ${component.name} in createComponent function`);
|
|
78
|
+
throw err;
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
exports.createComponent = createComponent;
|
|
82
|
+
/*
|
|
83
|
+
*
|
|
84
|
+
* PUT ONE Component
|
|
85
|
+
*
|
|
86
|
+
* */
|
|
87
|
+
const updateComponent = (component, presets, config) => {
|
|
88
|
+
const { spaceId, sbApi } = config;
|
|
89
|
+
logger_js_1.default.log(`Trying to update '${component.name}' with id ${component.id}`);
|
|
90
|
+
const componentWithPresets = component;
|
|
91
|
+
const { all_presets, ...componentWithoutPresets } = componentWithPresets;
|
|
92
|
+
return sbApi
|
|
93
|
+
.put(`spaces/${spaceId}/components/${component.id}`, {
|
|
94
|
+
component: componentWithoutPresets,
|
|
95
|
+
})
|
|
96
|
+
.then(async (res) => {
|
|
97
|
+
logger_js_1.default.success(`Component '${component.name}' has been updated.`);
|
|
98
|
+
if (presets) {
|
|
99
|
+
return await (0, resolvePresets_js_1.default)(res, all_presets, component, config);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
.catch((err) => {
|
|
106
|
+
logger_js_1.default.error(`${err.message} in migration of ${component.name} in updateComponent function`);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
exports.updateComponent = updateComponent;
|
|
110
|
+
/*
|
|
111
|
+
*
|
|
112
|
+
* DEL one Component
|
|
113
|
+
*
|
|
114
|
+
* */
|
|
115
|
+
const removeComponent = (component, config) => {
|
|
116
|
+
const { id, name } = component;
|
|
117
|
+
const { spaceId, sbApi } = config;
|
|
118
|
+
console.log(`Removing '${name}' component.`);
|
|
119
|
+
return sbApi
|
|
120
|
+
.delete(`spaces/${spaceId}/components/${id}`, {})
|
|
121
|
+
.then((res) => res.data)
|
|
122
|
+
.catch((err) => console.error(err));
|
|
123
|
+
};
|
|
124
|
+
exports.removeComponent = removeComponent;
|
|
125
|
+
/*
|
|
126
|
+
*
|
|
127
|
+
* GET All Component Groups
|
|
128
|
+
*
|
|
129
|
+
* */
|
|
130
|
+
const getAllComponentsGroups = async (config) => {
|
|
131
|
+
const { spaceId, sbApi } = config;
|
|
132
|
+
logger_js_1.default.log("Trying to get all groups.");
|
|
133
|
+
// TODO: All Components Groups doesnt support pagination...
|
|
134
|
+
// https://github.com/storyblok/storyblok-js-client/issues/535
|
|
135
|
+
return (0, request_js_1.getAllItemsWithPagination)({
|
|
136
|
+
apiFn: ({ per_page, page }) => sbApi
|
|
137
|
+
.get(`spaces/${spaceId}/component_groups/`, { per_page, page })
|
|
138
|
+
.then((res) => {
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* Not every endpoint in storyblok give us pagination...
|
|
142
|
+
* so only for this who paginate we want to console log amount found.
|
|
143
|
+
*
|
|
144
|
+
* */
|
|
145
|
+
if (res.total) {
|
|
146
|
+
logger_js_1.default.log(`Amount of component groups: ${res.total}`);
|
|
147
|
+
}
|
|
148
|
+
return res;
|
|
149
|
+
})
|
|
150
|
+
.catch((err) => console.error(err)),
|
|
151
|
+
params: {
|
|
152
|
+
spaceId,
|
|
153
|
+
},
|
|
154
|
+
itemsKey: "component_groups",
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
exports.getAllComponentsGroups = getAllComponentsGroups;
|
|
158
|
+
const getComponentsGroup = (groupName, config) => {
|
|
159
|
+
console.log(`Trying to get '${groupName}' group.`);
|
|
160
|
+
return (0, exports.getAllComponentsGroups)(config)
|
|
161
|
+
.then((res) => {
|
|
162
|
+
return res.filter((group) => group.name === groupName);
|
|
163
|
+
})
|
|
164
|
+
.then((res) => {
|
|
165
|
+
if (Array.isArray(res) && res.length === 0) {
|
|
166
|
+
console.info(`There is no group named '${groupName}'`);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
return res;
|
|
170
|
+
})
|
|
171
|
+
.catch((err) => console.error(err));
|
|
172
|
+
};
|
|
173
|
+
exports.getComponentsGroup = getComponentsGroup;
|
|
174
|
+
const removeComponentGroup = (componentGroup, config) => {
|
|
175
|
+
const { id, name } = componentGroup;
|
|
176
|
+
const { spaceId, sbApi } = config;
|
|
177
|
+
console.log(`Removing '${name}' component group.`);
|
|
178
|
+
return sbApi
|
|
179
|
+
.delete(`spaces/${spaceId}/component_groups/${id}`, {})
|
|
180
|
+
.then((res) => res.data)
|
|
181
|
+
.catch((err) => console.error(err));
|
|
182
|
+
};
|
|
183
|
+
exports.removeComponentGroup = removeComponentGroup;
|
|
184
|
+
const createComponentsGroup = (groupName, config) => {
|
|
185
|
+
const { spaceId, sbApi } = config;
|
|
186
|
+
console.log(`Trying to create '${groupName}' group`);
|
|
187
|
+
return sbApi
|
|
188
|
+
.post(`spaces/${spaceId}/component_groups/`, {
|
|
189
|
+
component_group: {
|
|
190
|
+
name: groupName,
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
.then((res) => {
|
|
194
|
+
console.info(`'${groupName}' created with uuid: ${res.data.component_group.uuid}`);
|
|
195
|
+
return res.data;
|
|
196
|
+
})
|
|
197
|
+
.catch((err) => {
|
|
198
|
+
console.log(err.message);
|
|
199
|
+
console.error("Error happened :()");
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
exports.createComponentsGroup = createComponentsGroup;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.syncComponentsData = syncComponentsData;
|
|
7
|
+
const array_utils_js_1 = require("../../utils/array-utils.js");
|
|
8
|
+
const logger_js_1 = __importDefault(require("../../utils/logger.js"));
|
|
9
|
+
const object_utils_js_1 = require("../../utils/object-utils.js");
|
|
10
|
+
/**
|
|
11
|
+
* Default progress callback that logs to console
|
|
12
|
+
*/
|
|
13
|
+
const defaultProgress = (event) => {
|
|
14
|
+
if (event.type === "start") {
|
|
15
|
+
logger_js_1.default.log(`Starting sync of ${event.total} components...`);
|
|
16
|
+
}
|
|
17
|
+
else if (event.type === "progress" && event.name) {
|
|
18
|
+
const status = event.action === "creating"
|
|
19
|
+
? "Creating"
|
|
20
|
+
: event.action === "updating"
|
|
21
|
+
? "Updating"
|
|
22
|
+
: event.action === "created"
|
|
23
|
+
? "✓ Created"
|
|
24
|
+
: event.action === "updated"
|
|
25
|
+
? "✓ Updated"
|
|
26
|
+
: event.action === "skipped"
|
|
27
|
+
? "⏭ Skipped"
|
|
28
|
+
: "✘ Error";
|
|
29
|
+
logger_js_1.default.log(`[${event.current}/${event.total}] ${status}: ${event.name}`);
|
|
30
|
+
}
|
|
31
|
+
else if (event.type === "complete") {
|
|
32
|
+
logger_js_1.default.success(`Sync complete: ${event.message ?? "done"}`);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const components_js_1 = require("./components.js");
|
|
36
|
+
async function ensureComponentGroupsExist(groupNames, config) {
|
|
37
|
+
try {
|
|
38
|
+
const existing = await (0, components_js_1.getAllComponentsGroups)(config);
|
|
39
|
+
const existingNames = new Set((existing ?? []).map((g) => g.name));
|
|
40
|
+
for (const groupName of groupNames) {
|
|
41
|
+
if (!existingNames.has(groupName)) {
|
|
42
|
+
await (0, components_js_1.createComponentsGroup)(groupName, config);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
// Log but don't fail - component groups are optional
|
|
48
|
+
logger_js_1.default.warning(`Could not fetch component groups: ${error instanceof Error ? error.message : String(error)}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function resolveGroupUuid(component, remoteGroups) {
|
|
52
|
+
if (!component.component_group_name) {
|
|
53
|
+
return { ...component, component_group_uuid: null };
|
|
54
|
+
}
|
|
55
|
+
const match = remoteGroups.find((g) => g.name === component.component_group_name);
|
|
56
|
+
if (!match)
|
|
57
|
+
return { ...component, component_group_uuid: null };
|
|
58
|
+
return { ...component, component_group_uuid: match.uuid };
|
|
59
|
+
}
|
|
60
|
+
async function syncComponentsData(args, config) {
|
|
61
|
+
const { components, presets, ssot, onProgress } = args;
|
|
62
|
+
const progress = onProgress ?? defaultProgress;
|
|
63
|
+
const result = {
|
|
64
|
+
created: [],
|
|
65
|
+
updated: [],
|
|
66
|
+
skipped: [],
|
|
67
|
+
errors: [],
|
|
68
|
+
};
|
|
69
|
+
if (ssot) {
|
|
70
|
+
const existingComponents = await (0, components_js_1.getAllComponents)(config);
|
|
71
|
+
const existingGroups = await (0, components_js_1.getAllComponentsGroups)(config);
|
|
72
|
+
await Promise.allSettled([
|
|
73
|
+
...(existingComponents ?? []).map((c) => (0, components_js_1.removeComponent)(c, config)),
|
|
74
|
+
...(existingGroups ?? []).map((g) => (0, components_js_1.removeComponentGroup)(g, config)),
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
const nonEmptyComponents = components.filter((c) => !(0, object_utils_js_1.isObjectEmpty)(c));
|
|
78
|
+
const groupsToCheck = (0, array_utils_js_1.uniqueValuesFrom)(nonEmptyComponents
|
|
79
|
+
.filter((c) => c.component_group_name)
|
|
80
|
+
.map((c) => c.component_group_name));
|
|
81
|
+
await ensureComponentGroupsExist(groupsToCheck, config);
|
|
82
|
+
let remoteComponents = [];
|
|
83
|
+
let remoteGroups = [];
|
|
84
|
+
try {
|
|
85
|
+
remoteComponents = (await (0, components_js_1.getAllComponents)(config)) ?? [];
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
logger_js_1.default.warning(`Could not fetch remote components: ${error instanceof Error ? error.message : String(error)}`);
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
remoteGroups = (await (0, components_js_1.getAllComponentsGroups)(config)) ?? [];
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
logger_js_1.default.warning(`Could not fetch remote groups: ${error instanceof Error ? error.message : String(error)}`);
|
|
95
|
+
}
|
|
96
|
+
const componentsToUpdate = [];
|
|
97
|
+
const componentsToCreate = [];
|
|
98
|
+
for (const component of nonEmptyComponents) {
|
|
99
|
+
if (!component?.name) {
|
|
100
|
+
result.skipped.push("unknown");
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const remote = remoteComponents.find((rc) => rc.name === component.name);
|
|
104
|
+
if (remote) {
|
|
105
|
+
componentsToUpdate.push({ id: remote.id, ...component });
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
componentsToCreate.push(component);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Resolve group uuids after ensureComponentGroupsExist
|
|
112
|
+
const updatePayloads = componentsToUpdate.map((c) => resolveGroupUuid(c, remoteGroups));
|
|
113
|
+
const createPayloads = componentsToCreate.map((c) => resolveGroupUuid(c, remoteGroups));
|
|
114
|
+
const totalComponents = updatePayloads.length + createPayloads.length;
|
|
115
|
+
let currentIndex = 0;
|
|
116
|
+
// Report start
|
|
117
|
+
progress({ type: "start", total: totalComponents });
|
|
118
|
+
// Process updates sequentially for progress reporting
|
|
119
|
+
for (const component of updatePayloads) {
|
|
120
|
+
const name = String(component?.name ?? "unknown");
|
|
121
|
+
currentIndex++;
|
|
122
|
+
progress({
|
|
123
|
+
type: "progress",
|
|
124
|
+
current: currentIndex,
|
|
125
|
+
total: totalComponents,
|
|
126
|
+
name,
|
|
127
|
+
action: "updating",
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
await (0, components_js_1.updateComponent)(component, presets, config);
|
|
131
|
+
result.updated.push(name);
|
|
132
|
+
progress({
|
|
133
|
+
type: "progress",
|
|
134
|
+
current: currentIndex,
|
|
135
|
+
total: totalComponents,
|
|
136
|
+
name,
|
|
137
|
+
action: "updated",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
result.errors.push({
|
|
142
|
+
name,
|
|
143
|
+
message: error instanceof Error ? error.message : String(error),
|
|
144
|
+
});
|
|
145
|
+
progress({
|
|
146
|
+
type: "progress",
|
|
147
|
+
current: currentIndex,
|
|
148
|
+
total: totalComponents,
|
|
149
|
+
name,
|
|
150
|
+
action: "error",
|
|
151
|
+
message: error instanceof Error ? error.message : String(error),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Process creates sequentially for progress reporting
|
|
156
|
+
for (const component of createPayloads) {
|
|
157
|
+
const name = String(component?.name ?? "unknown");
|
|
158
|
+
currentIndex++;
|
|
159
|
+
progress({
|
|
160
|
+
type: "progress",
|
|
161
|
+
current: currentIndex,
|
|
162
|
+
total: totalComponents,
|
|
163
|
+
name,
|
|
164
|
+
action: "creating",
|
|
165
|
+
});
|
|
166
|
+
try {
|
|
167
|
+
await (0, components_js_1.createComponent)(component, presets, config);
|
|
168
|
+
result.created.push(name);
|
|
169
|
+
progress({
|
|
170
|
+
type: "progress",
|
|
171
|
+
current: currentIndex,
|
|
172
|
+
total: totalComponents,
|
|
173
|
+
name,
|
|
174
|
+
action: "created",
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
result.errors.push({
|
|
179
|
+
name,
|
|
180
|
+
message: error instanceof Error ? error.message : String(error),
|
|
181
|
+
});
|
|
182
|
+
progress({
|
|
183
|
+
type: "progress",
|
|
184
|
+
current: currentIndex,
|
|
185
|
+
total: totalComponents,
|
|
186
|
+
name,
|
|
187
|
+
action: "error",
|
|
188
|
+
message: error instanceof Error ? error.message : String(error),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Report completion
|
|
193
|
+
progress({
|
|
194
|
+
type: "complete",
|
|
195
|
+
total: totalComponents,
|
|
196
|
+
message: `${result.created.length} created, ${result.updated.length} updated, ${result.errors.length} errors`,
|
|
197
|
+
});
|
|
198
|
+
return result;
|
|
199
|
+
}
|