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,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAllRoles = getAllRoles;
|
|
4
|
+
exports.getRole = getRole;
|
|
5
|
+
exports.createRole = createRole;
|
|
6
|
+
exports.updateRole = updateRole;
|
|
7
|
+
const request_js_1 = require("../../api/utils/request.js");
|
|
8
|
+
async function getAllRoles(client) {
|
|
9
|
+
const spaceId = client.spaceId;
|
|
10
|
+
return (0, request_js_1.getAllItemsWithPagination)({
|
|
11
|
+
apiFn: ({ per_page, page }) => client.sbApi.get(`spaces/${spaceId}/space_roles/`, {
|
|
12
|
+
per_page,
|
|
13
|
+
page,
|
|
14
|
+
}),
|
|
15
|
+
params: {
|
|
16
|
+
spaceId,
|
|
17
|
+
},
|
|
18
|
+
itemsKey: "space_roles",
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function getRole(client, roleName) {
|
|
22
|
+
const roles = await getAllRoles(client);
|
|
23
|
+
const match = roles.filter((r) => r.role === roleName);
|
|
24
|
+
if (Array.isArray(match) && match.length === 0)
|
|
25
|
+
return false;
|
|
26
|
+
return match;
|
|
27
|
+
}
|
|
28
|
+
async function createRole(client, role) {
|
|
29
|
+
const spaceId = client.spaceId;
|
|
30
|
+
return client.sbApi
|
|
31
|
+
.post(`spaces/${spaceId}/space_roles/`, { space_role: role })
|
|
32
|
+
.then((res) => res.data);
|
|
33
|
+
}
|
|
34
|
+
async function updateRole(client, role) {
|
|
35
|
+
const spaceId = client.spaceId;
|
|
36
|
+
return client.sbApi
|
|
37
|
+
.put(`spaces/${spaceId}/space_roles/${role.id}`, {
|
|
38
|
+
space_role: role,
|
|
39
|
+
})
|
|
40
|
+
.then((res) => res.data);
|
|
41
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAllSpaces = getAllSpaces;
|
|
4
|
+
exports.getSpace = getSpace;
|
|
5
|
+
exports.updateSpace = updateSpace;
|
|
6
|
+
const spaces_js_1 = require("../../api/spaces/spaces.js");
|
|
7
|
+
const requestConfig_js_1 = require("../requestConfig.js");
|
|
8
|
+
async function getAllSpaces(client) {
|
|
9
|
+
return await (0, spaces_js_1.getAllSpaces)((0, requestConfig_js_1.toRequestConfig)(client));
|
|
10
|
+
}
|
|
11
|
+
async function getSpace(client, spaceId) {
|
|
12
|
+
return await (0, spaces_js_1.getSpace)({ spaceId }, (0, requestConfig_js_1.toRequestConfig)(client));
|
|
13
|
+
}
|
|
14
|
+
async function updateSpace(client, args) {
|
|
15
|
+
return await (0, spaces_js_1.updateSpace)(args, (0, requestConfig_js_1.toRequestConfig)(client));
|
|
16
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAllStories = getAllStories;
|
|
4
|
+
exports.getStoryById = getStoryById;
|
|
5
|
+
exports.getStoryBySlug = getStoryBySlug;
|
|
6
|
+
exports.createStory = createStory;
|
|
7
|
+
exports.fetchStories = fetchStories;
|
|
8
|
+
exports.copyStories = copyStories;
|
|
9
|
+
const stories_js_1 = require("../../api/stories/stories.js");
|
|
10
|
+
const requestConfig_js_1 = require("../requestConfig.js");
|
|
11
|
+
/**
|
|
12
|
+
* Build a tree structure from flat story list
|
|
13
|
+
*/
|
|
14
|
+
function buildTree(stories) {
|
|
15
|
+
const storyMap = new Map();
|
|
16
|
+
// First pass: create all nodes
|
|
17
|
+
for (const storyData of stories) {
|
|
18
|
+
const story = storyData.story || storyData;
|
|
19
|
+
storyMap.set(story.id, {
|
|
20
|
+
id: story.id,
|
|
21
|
+
name: story.name,
|
|
22
|
+
slug: story.slug,
|
|
23
|
+
full_slug: story.full_slug,
|
|
24
|
+
is_folder: story.is_folder,
|
|
25
|
+
is_startpage: story.is_startpage,
|
|
26
|
+
parent_id: story.parent_id,
|
|
27
|
+
children: [],
|
|
28
|
+
story,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// Second pass: build tree structure
|
|
32
|
+
const rootNodes = [];
|
|
33
|
+
for (const storyData of stories) {
|
|
34
|
+
const story = storyData.story || storyData;
|
|
35
|
+
const node = storyMap.get(story.id);
|
|
36
|
+
if (story.parent_id === null || story.parent_id === 0) {
|
|
37
|
+
rootNodes.push(node);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const parent = storyMap.get(story.parent_id);
|
|
41
|
+
if (parent) {
|
|
42
|
+
parent.children.push(node);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
rootNodes.push(node);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Sort children
|
|
50
|
+
const sortNodes = (nodes) => {
|
|
51
|
+
nodes.sort((a, b) => {
|
|
52
|
+
if (a.is_folder && !b.is_folder)
|
|
53
|
+
return -1;
|
|
54
|
+
if (!a.is_folder && b.is_folder)
|
|
55
|
+
return 1;
|
|
56
|
+
if (a.story.position !== b.story.position) {
|
|
57
|
+
return a.story.position - b.story.position;
|
|
58
|
+
}
|
|
59
|
+
return a.name.localeCompare(b.name);
|
|
60
|
+
});
|
|
61
|
+
for (const node of nodes) {
|
|
62
|
+
if (node.children.length > 0) {
|
|
63
|
+
sortNodes(node.children);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
sortNodes(rootNodes);
|
|
68
|
+
return rootNodes;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get all stories from a space
|
|
72
|
+
*/
|
|
73
|
+
async function getAllStories(client, options) {
|
|
74
|
+
const config = (0, requestConfig_js_1.toRequestConfig)(client);
|
|
75
|
+
return await (0, stories_js_1.getAllStories)({ options }, config);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get a single story by ID
|
|
79
|
+
*/
|
|
80
|
+
async function getStoryById(client, storyId) {
|
|
81
|
+
const config = (0, requestConfig_js_1.toRequestConfig)(client);
|
|
82
|
+
return await (0, stories_js_1.getStoryById)(String(storyId), config);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get a story by slug
|
|
86
|
+
*/
|
|
87
|
+
async function getStoryBySlug(client, slug) {
|
|
88
|
+
const config = (0, requestConfig_js_1.toRequestConfig)(client);
|
|
89
|
+
return await (0, stories_js_1.getStoryBySlug)(slug, config);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a story in a space
|
|
93
|
+
*/
|
|
94
|
+
async function createStory(client, content) {
|
|
95
|
+
const config = (0, requestConfig_js_1.toRequestConfig)(client);
|
|
96
|
+
return await (0, stories_js_1.createStory)(content, config);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Fetch all stories and build a tree structure
|
|
100
|
+
*/
|
|
101
|
+
async function fetchStories(client, options) {
|
|
102
|
+
const stories = await getAllStories(client, options);
|
|
103
|
+
const tree = buildTree(stories);
|
|
104
|
+
return {
|
|
105
|
+
stories,
|
|
106
|
+
tree,
|
|
107
|
+
total: stories.length,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Copy stories from source space to target space
|
|
112
|
+
*/
|
|
113
|
+
async function copyStories(sourceClient, targetClient, options, onProgress) {
|
|
114
|
+
const errors = [];
|
|
115
|
+
let copiedCount = 0;
|
|
116
|
+
// Fetch all stories with their full content
|
|
117
|
+
const storiesToCopy = [];
|
|
118
|
+
for (let i = 0; i < options.storyIds.length; i++) {
|
|
119
|
+
const storyId = options.storyIds[i];
|
|
120
|
+
if (storyId === undefined)
|
|
121
|
+
continue;
|
|
122
|
+
onProgress?.({
|
|
123
|
+
current: i + 1,
|
|
124
|
+
total: options.storyIds.length,
|
|
125
|
+
currentStory: `Fetching story ${storyId}...`,
|
|
126
|
+
status: "copying",
|
|
127
|
+
});
|
|
128
|
+
try {
|
|
129
|
+
const storyData = await getStoryById(sourceClient, storyId);
|
|
130
|
+
storiesToCopy.push(storyData);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
134
|
+
errors.push(`Failed to fetch story ${storyId}: ${errorMsg}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Build tree from selected stories
|
|
138
|
+
const tree = buildTree(storiesToCopy);
|
|
139
|
+
// Recursive function to create stories maintaining hierarchy
|
|
140
|
+
const createInOrder = async (nodes, newParentId) => {
|
|
141
|
+
for (const node of nodes) {
|
|
142
|
+
onProgress?.({
|
|
143
|
+
current: copiedCount + 1,
|
|
144
|
+
total: storiesToCopy.length,
|
|
145
|
+
currentStory: node.name,
|
|
146
|
+
status: "copying",
|
|
147
|
+
});
|
|
148
|
+
try {
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
150
|
+
const { id, uuid, created_at, updated_at, ...storyData } = node.story;
|
|
151
|
+
const newStory = await createStory(targetClient, {
|
|
152
|
+
...storyData,
|
|
153
|
+
parent_id: newParentId,
|
|
154
|
+
});
|
|
155
|
+
copiedCount++;
|
|
156
|
+
// Recursively create children
|
|
157
|
+
if (node.children.length > 0) {
|
|
158
|
+
await createInOrder(node.children, newStory.story.id);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
163
|
+
errors.push(`Failed to create "${node.name}": ${errorMsg}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
// Start creating from root nodes
|
|
168
|
+
await createInOrder(tree, options.destinationParentId ?? null);
|
|
169
|
+
onProgress?.({
|
|
170
|
+
current: copiedCount,
|
|
171
|
+
total: storiesToCopy.length,
|
|
172
|
+
currentStory: "Complete",
|
|
173
|
+
status: errors.length > 0 ? "error" : "done",
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
success: errors.length === 0,
|
|
177
|
+
copiedCount,
|
|
178
|
+
errors,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.syncComponents = syncComponents;
|
|
4
|
+
exports.syncDatasources = syncDatasources;
|
|
5
|
+
exports.syncRoles = syncRoles;
|
|
6
|
+
exports.syncPlugins = syncPlugins;
|
|
7
|
+
const components_sync_js_1 = require("../../api/components/components.sync.js");
|
|
8
|
+
const datasources_js_1 = require("../../api/datasources/datasources.js");
|
|
9
|
+
const plugins_js_1 = require("../../api/plugins/plugins.js");
|
|
10
|
+
const roles_js_1 = require("../../api/roles/roles.js");
|
|
11
|
+
const requestConfig_js_1 = require("../requestConfig.js");
|
|
12
|
+
async function syncComponents(client, args) {
|
|
13
|
+
const presets = args.presets ?? false;
|
|
14
|
+
if (args.dryRun) {
|
|
15
|
+
// minimal dry-run: compare names against remote
|
|
16
|
+
const remote = await client.sbApi.get(`spaces/${client.spaceId}/components/`, {
|
|
17
|
+
per_page: 100,
|
|
18
|
+
page: 1,
|
|
19
|
+
});
|
|
20
|
+
const remoteNames = new Set(remote.data?.components?.map((c) => c.name) ?? []);
|
|
21
|
+
const created = [];
|
|
22
|
+
const updated = [];
|
|
23
|
+
const skipped = [];
|
|
24
|
+
for (const c of args.components) {
|
|
25
|
+
const name = String(c?.name ?? "unknown");
|
|
26
|
+
if (!c?.name) {
|
|
27
|
+
skipped.push(name);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (remoteNames.has(c.name))
|
|
31
|
+
updated.push(name);
|
|
32
|
+
else
|
|
33
|
+
created.push(name);
|
|
34
|
+
}
|
|
35
|
+
return { created, updated, skipped, errors: [] };
|
|
36
|
+
}
|
|
37
|
+
return (await (0, components_sync_js_1.syncComponentsData)({
|
|
38
|
+
components: args.components,
|
|
39
|
+
presets,
|
|
40
|
+
ssot: args.ssot,
|
|
41
|
+
onProgress: args.onProgress,
|
|
42
|
+
}, (0, requestConfig_js_1.toRequestConfig)(client)));
|
|
43
|
+
}
|
|
44
|
+
async function syncDatasources(client, args) {
|
|
45
|
+
if (args.dryRun) {
|
|
46
|
+
const remote = await client.sbApi.get(`spaces/${client.spaceId}/datasources/`);
|
|
47
|
+
const remoteNames = new Set(remote.data?.datasources?.map((d) => d.name) ?? []);
|
|
48
|
+
const created = [];
|
|
49
|
+
const updated = [];
|
|
50
|
+
const skipped = [];
|
|
51
|
+
for (const d of args.datasources) {
|
|
52
|
+
const name = String(d?.name ?? "unknown");
|
|
53
|
+
if (!d?.name) {
|
|
54
|
+
skipped.push(name);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (remoteNames.has(d.name))
|
|
58
|
+
updated.push(name);
|
|
59
|
+
else
|
|
60
|
+
created.push(name);
|
|
61
|
+
}
|
|
62
|
+
return { created, updated, skipped, errors: [] };
|
|
63
|
+
}
|
|
64
|
+
return (await (0, datasources_js_1.syncDatasourcesData)({ datasources: args.datasources }, (0, requestConfig_js_1.toRequestConfig)(client)));
|
|
65
|
+
}
|
|
66
|
+
async function syncRoles(client, args) {
|
|
67
|
+
if (args.dryRun) {
|
|
68
|
+
const remote = await client.sbApi.get(`spaces/${client.spaceId}/space_roles/`, {
|
|
69
|
+
per_page: 100,
|
|
70
|
+
page: 1,
|
|
71
|
+
});
|
|
72
|
+
const remoteNames = new Set(remote.data?.space_roles?.map((r) => r.role) ?? []);
|
|
73
|
+
const created = [];
|
|
74
|
+
const updated = [];
|
|
75
|
+
const skipped = [];
|
|
76
|
+
for (const r of args.roles) {
|
|
77
|
+
const name = String(r?.role ?? "unknown");
|
|
78
|
+
if (!r?.role) {
|
|
79
|
+
skipped.push(name);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (remoteNames.has(r.role))
|
|
83
|
+
updated.push(name);
|
|
84
|
+
else
|
|
85
|
+
created.push(name);
|
|
86
|
+
}
|
|
87
|
+
return { created, updated, skipped, errors: [] };
|
|
88
|
+
}
|
|
89
|
+
return (await (0, roles_js_1.syncRolesData)({ roles: args.roles }, (0, requestConfig_js_1.toRequestConfig)(client)));
|
|
90
|
+
}
|
|
91
|
+
async function syncPlugins(client, args) {
|
|
92
|
+
if (args.dryRun) {
|
|
93
|
+
const remote = await client.sbApi.get("field_types", {
|
|
94
|
+
per_page: 100,
|
|
95
|
+
page: 1,
|
|
96
|
+
});
|
|
97
|
+
const remoteNames = new Set(remote.data?.field_types?.map((p) => p.name) ?? []);
|
|
98
|
+
const created = [];
|
|
99
|
+
const updated = [];
|
|
100
|
+
const skipped = [];
|
|
101
|
+
for (const p of args.plugins) {
|
|
102
|
+
const name = String(p?.name ?? "unknown");
|
|
103
|
+
if (!p?.name) {
|
|
104
|
+
skipped.push(name);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (remoteNames.has(p.name))
|
|
108
|
+
updated.push(name);
|
|
109
|
+
else
|
|
110
|
+
created.push(name);
|
|
111
|
+
}
|
|
112
|
+
return { created, updated, skipped, errors: [] };
|
|
113
|
+
}
|
|
114
|
+
return (await (0, plugins_js_1.syncPluginsData)({ plugins: args.plugins }, (0, requestConfig_js_1.toRequestConfig)(client)));
|
|
115
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.testConnection = testConnection;
|
|
4
|
+
exports.testAsyncConnection = testAsyncConnection;
|
|
5
|
+
/**
|
|
6
|
+
* Simple test function with no dependencies to verify ESM/CJS interop
|
|
7
|
+
*/
|
|
8
|
+
function testConnection() {
|
|
9
|
+
return {
|
|
10
|
+
success: true,
|
|
11
|
+
message: "sb-mig api-v2 connection successful!",
|
|
12
|
+
timestamp: new Date().toISOString(),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Async test function to verify async imports work
|
|
17
|
+
*/
|
|
18
|
+
async function testAsyncConnection() {
|
|
19
|
+
// Simulate a small delay
|
|
20
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
21
|
+
return {
|
|
22
|
+
success: true,
|
|
23
|
+
message: "sb-mig api-v2 async connection successful!",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.storyblokApiMapping = exports.SCHEMA = void 0;
|
|
4
|
+
exports.SCHEMA = {
|
|
5
|
+
TS: "ts",
|
|
6
|
+
JS: "js",
|
|
7
|
+
};
|
|
8
|
+
exports.storyblokApiMapping = {
|
|
9
|
+
eu: {
|
|
10
|
+
managementApi: "https://mapi.storyblok.com/v1",
|
|
11
|
+
deliveryApi: "https://api.storyblok.com/v2",
|
|
12
|
+
graphql: "https://gapi.storyblok.com/v1/api",
|
|
13
|
+
},
|
|
14
|
+
us: {
|
|
15
|
+
managementApi: "https://api-us.storyblok.com/v1",
|
|
16
|
+
deliveryApi: "https://api-us.storyblok.com/v2",
|
|
17
|
+
graphql: "https://gapi-us.storyblok.com/v1/api",
|
|
18
|
+
},
|
|
19
|
+
cn: {
|
|
20
|
+
managementApi: "https://app.storyblokchina.cn",
|
|
21
|
+
deliveryApi: "https://app.storyblokchina.cn",
|
|
22
|
+
graphql: "",
|
|
23
|
+
},
|
|
24
|
+
ap: {
|
|
25
|
+
managementApi: "https://api-ap.storyblok.com/v1",
|
|
26
|
+
deliveryApi: "https://api-ap.storyblok.com/v2",
|
|
27
|
+
graphql: "https://gapi-ap.storyblok.com/v1/api",
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Array utility functions
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports._uniqueValuesFrom = exports.uniqueValuesFrom = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Get unique values from an array
|
|
9
|
+
* Uses Set for O(n) deduplication
|
|
10
|
+
*
|
|
11
|
+
* @param array - The array to deduplicate
|
|
12
|
+
* @returns A new array with only unique values
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* uniqueValuesFrom([1, 2, 2, 3, 3, 3]) // => [1, 2, 3]
|
|
16
|
+
* uniqueValuesFrom(['a', 'b', 'a']) // => ['a', 'b']
|
|
17
|
+
*/
|
|
18
|
+
const uniqueValuesFrom = (array) => [...new Set(array)];
|
|
19
|
+
exports.uniqueValuesFrom = uniqueValuesFrom;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Use uniqueValuesFrom instead
|
|
22
|
+
* Alias for backwards compatibility
|
|
23
|
+
*/
|
|
24
|
+
exports._uniqueValuesFrom = exports.uniqueValuesFrom;
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
7
|
+
class Logger {
|
|
8
|
+
static log(content) {
|
|
9
|
+
console.log(content);
|
|
10
|
+
}
|
|
11
|
+
static success(content) {
|
|
12
|
+
console.log(chalk_1.default.green(`✓ ${content}`));
|
|
13
|
+
}
|
|
14
|
+
static warning(content) {
|
|
15
|
+
console.log(chalk_1.default.yellow(`! ${content}`));
|
|
16
|
+
}
|
|
17
|
+
static error(content, { verbose } = { verbose: false }) {
|
|
18
|
+
if (verbose) {
|
|
19
|
+
console.log(content);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(chalk_1.default.red(`✘ ${content}`));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
static upload(content) {
|
|
26
|
+
console.log(chalk_1.default.blue(`↑ ${content}`));
|
|
27
|
+
}
|
|
28
|
+
static download(content) {
|
|
29
|
+
console.log(chalk_1.default.yellow(`↓ ${content}`));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.default = Logger;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* General object utility functions
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractFields = exports.isObjectEmpty = exports.notNullish = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Filter out null and undefined values from an object
|
|
9
|
+
* Keeps all properties that have defined values (including falsy values like 0, '', false)
|
|
10
|
+
*
|
|
11
|
+
* @param params - The object to filter
|
|
12
|
+
* @returns A new object with only non-nullish values
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* notNullish({ a: 1, b: null, c: undefined, d: 0 }) // => { a: 1, d: 0 }
|
|
16
|
+
*/
|
|
17
|
+
const notNullish = (params) => {
|
|
18
|
+
return Object.keys(params).reduce((acc, key) => {
|
|
19
|
+
if (params[key] !== null && params[key] !== undefined) {
|
|
20
|
+
acc[key] = params[key];
|
|
21
|
+
}
|
|
22
|
+
return acc;
|
|
23
|
+
}, {});
|
|
24
|
+
};
|
|
25
|
+
exports.notNullish = notNullish;
|
|
26
|
+
/**
|
|
27
|
+
* Check if an object is empty (has no own properties)
|
|
28
|
+
* Returns true for null, undefined, and empty objects {}
|
|
29
|
+
* Returns false for arrays (even empty ones) and objects with properties
|
|
30
|
+
*
|
|
31
|
+
* @param obj - The object to check
|
|
32
|
+
* @returns true if the object is empty, null, or undefined
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* isObjectEmpty({}) // => true
|
|
36
|
+
* isObjectEmpty(null) // => true
|
|
37
|
+
* isObjectEmpty({ name: 'test' }) // => false
|
|
38
|
+
* isObjectEmpty([]) // => false (arrays are not plain objects)
|
|
39
|
+
*/
|
|
40
|
+
const isObjectEmpty = (obj) => {
|
|
41
|
+
if (obj) {
|
|
42
|
+
return Object.keys(obj).length === 0 && obj.constructor === Object;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.isObjectEmpty = isObjectEmpty;
|
|
49
|
+
/**
|
|
50
|
+
* Extract specific fields from an object based on a filter object
|
|
51
|
+
* Supports nested object extraction
|
|
52
|
+
*
|
|
53
|
+
* @param data - The source object to extract fields from
|
|
54
|
+
* @param filter - An object where true means include the field, nested objects for nested extraction
|
|
55
|
+
* @returns A new object containing only the specified fields
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const data = { name: 'hero', id: 123, schema: { title: 'text' } };
|
|
59
|
+
* extractFields(data, { name: true, id: true }) // => { name: 'hero', id: 123 }
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Nested extraction
|
|
63
|
+
* extractFields(data, { schema: { title: true } }) // => { schema: { title: 'text' } }
|
|
64
|
+
*/
|
|
65
|
+
const extractFields = (data, filter) => {
|
|
66
|
+
const result = {};
|
|
67
|
+
for (const key in filter) {
|
|
68
|
+
if (filter[key] === true) {
|
|
69
|
+
result[key] = data[key];
|
|
70
|
+
}
|
|
71
|
+
else if (typeof filter[key] === "object") {
|
|
72
|
+
result[key] = (0, exports.extractFields)(data[key], filter[key]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
};
|
|
77
|
+
exports.extractFields = extractFields;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Path and glob pattern utilities for file discovery
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.compare = exports.filesPattern = exports.normalizeDiscover = void 0;
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
/**
|
|
12
|
+
* Normalizes an array of directory segments for glob pattern usage.
|
|
13
|
+
* Handles the glob.sync quirk where single segments don't need braces,
|
|
14
|
+
* but multiple segments need {segment1,segment2} format.
|
|
15
|
+
*
|
|
16
|
+
* @param segments - Array of directory path segments
|
|
17
|
+
* @returns Normalized string for glob pattern
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* normalizeDiscover({ segments: [] }) // => ""
|
|
21
|
+
* normalizeDiscover({ segments: ["src"] }) // => "src"
|
|
22
|
+
* normalizeDiscover({ segments: ["src", "lib"] }) // => "{src,lib}"
|
|
23
|
+
*/
|
|
24
|
+
const normalizeDiscover = ({ segments, }) => {
|
|
25
|
+
if (segments.length === 0) {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
28
|
+
if (segments.length === 1) {
|
|
29
|
+
return segments[0];
|
|
30
|
+
}
|
|
31
|
+
return `{${segments.join(",")}}`;
|
|
32
|
+
};
|
|
33
|
+
exports.normalizeDiscover = normalizeDiscover;
|
|
34
|
+
/**
|
|
35
|
+
* Builds a glob file pattern for discovering files with a specific extension.
|
|
36
|
+
* Automatically handles single vs multiple directory paths.
|
|
37
|
+
*
|
|
38
|
+
* @param mainDirectory - The root directory to search from
|
|
39
|
+
* @param componentDirectories - Array of subdirectories to search in
|
|
40
|
+
* @param ext - File extension to match (without leading dot)
|
|
41
|
+
* @returns A glob pattern string
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* filesPattern({
|
|
45
|
+
* mainDirectory: "/project",
|
|
46
|
+
* componentDirectories: ["src"],
|
|
47
|
+
* ext: "sb.js"
|
|
48
|
+
* })
|
|
49
|
+
* // => "/project/src/**\/[^_]*.sb.js"
|
|
50
|
+
*
|
|
51
|
+
* filesPattern({
|
|
52
|
+
* mainDirectory: "/project",
|
|
53
|
+
* componentDirectories: ["src", "lib"],
|
|
54
|
+
* ext: "sb.js"
|
|
55
|
+
* })
|
|
56
|
+
* // => "/project/{src,lib}/**\/[^_]*.sb.js"
|
|
57
|
+
*/
|
|
58
|
+
const filesPattern = ({ mainDirectory, componentDirectories, ext, }) => {
|
|
59
|
+
return componentDirectories.length === 1
|
|
60
|
+
? path_1.default.join(`${mainDirectory}`, `${componentDirectories[0]}`, "**", `[^_]*.${ext}`)
|
|
61
|
+
: path_1.default.join(`${mainDirectory}`, `{${componentDirectories.join(",")}}`, "**", `[^_]*.${ext}`);
|
|
62
|
+
};
|
|
63
|
+
exports.filesPattern = filesPattern;
|
|
64
|
+
/**
|
|
65
|
+
* Compares local and external file path arrays.
|
|
66
|
+
* Splits paths to extract file names, filters out duplicates from external
|
|
67
|
+
* (preferring local files), and filters out nested node_modules.
|
|
68
|
+
*
|
|
69
|
+
* @param request - Object containing local and external path arrays
|
|
70
|
+
* @returns CompareResult with processed local and external file elements
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* compare({
|
|
74
|
+
* local: ["/project/src/hero.sb.js"],
|
|
75
|
+
* external: ["/project/node_modules/pkg/hero.sb.js", "/project/node_modules/pkg/card.sb.js"]
|
|
76
|
+
* })
|
|
77
|
+
* // => {
|
|
78
|
+
* // local: [{ name: "hero.sb.js", p: "/project/src/hero.sb.js" }],
|
|
79
|
+
* // external: [{ name: "card.sb.js", p: "/project/node_modules/pkg/card.sb.js" }]
|
|
80
|
+
* // }
|
|
81
|
+
*/
|
|
82
|
+
const compare = (request) => {
|
|
83
|
+
const { local, external } = request;
|
|
84
|
+
const splittedLocal = local.map((p) => {
|
|
85
|
+
return {
|
|
86
|
+
name: p.split(path_1.default.sep)[p.split(path_1.default.sep).length - 1], // last element of split array - file name
|
|
87
|
+
p,
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
const splittedExternal = external
|
|
91
|
+
.map((p) => {
|
|
92
|
+
return {
|
|
93
|
+
name: p.split(path_1.default.sep)[p.split(path_1.default.sep).length - 1], // last element of split array - file name
|
|
94
|
+
p,
|
|
95
|
+
};
|
|
96
|
+
})
|
|
97
|
+
.filter((file) => {
|
|
98
|
+
// Filter out files from nested node_modules (node_modules within node_modules)
|
|
99
|
+
const nodeModulesCount = (file.p.match(/node_modules/g) || [])
|
|
100
|
+
.length;
|
|
101
|
+
return nodeModulesCount <= 1;
|
|
102
|
+
});
|
|
103
|
+
// Filter external array to remove items that exist locally (local takes priority)
|
|
104
|
+
const result = {
|
|
105
|
+
local: splittedLocal,
|
|
106
|
+
external: splittedExternal.filter((externalComponent) => {
|
|
107
|
+
if (splittedLocal.find((localComponent) => externalComponent.name === localComponent.name)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
}),
|
|
112
|
+
};
|
|
113
|
+
return result;
|
|
114
|
+
};
|
|
115
|
+
exports.compare = compare;
|