sb-mig 5.7.0-beta.2 → 5.7.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/dist/api/components/components.sync.d.ts +1 -0
- package/dist/api/components/components.sync.js +50 -8
- package/dist/api/datasources/datasource-entries.js +15 -3
- package/dist/api/datasources/datasources.d.ts +2 -1
- package/dist/api/datasources/datasources.js +30 -1
- package/dist/api/datasources/datasources.sync.js +2 -2
- package/dist/api/datasources/datasources.types.d.ts +6 -1
- package/dist/api/migrate.js +50 -12
- package/dist/api/migrate.types.d.ts +14 -6
- package/dist/api/plugins/plugins.d.ts +2 -1
- package/dist/api/plugins/plugins.js +19 -1
- package/dist/api/plugins/plugins.sync.js +8 -4
- package/dist/api/plugins/plugins.types.d.ts +1 -0
- package/dist/api/roles/roles.d.ts +2 -1
- package/dist/api/roles/roles.js +16 -3
- package/dist/api/roles/roles.sync.js +2 -2
- package/dist/api/roles/roles.types.d.ts +6 -3
- package/dist/api/sync/sync.types.d.ts +3 -0
- package/dist/api-v2/sync/index.js +4 -89
- package/dist/cli/cli-descriptions.d.ts +1 -1
- package/dist/cli/cli-descriptions.js +4 -0
- package/dist/cli/commands/sync.js +109 -64
- package/dist/cli/datasources/sync.js +5 -2
- package/dist/cli/roles/sync.js +4 -4
- package/dist-cjs/api/components/components.sync.js +50 -8
- package/dist-cjs/api/datasources/datasource-entries.js +15 -3
- package/dist-cjs/api/datasources/datasources.js +30 -1
- package/dist-cjs/api/plugins/plugins.js +19 -1
- package/dist-cjs/api/roles/roles.js +16 -3
- package/dist-cjs/api-v2/sync/index.js +4 -89
- package/package.json +1 -1
|
@@ -27,12 +27,16 @@ const defaultProgress = (event) => {
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
import { createComponent, createComponentsGroup, getAllComponents, getAllComponentsGroups, removeComponent, removeComponentGroup, updateComponent, } from "./components.js";
|
|
30
|
-
async function ensureComponentGroupsExist(groupNames, config) {
|
|
30
|
+
async function ensureComponentGroupsExist(groupNames, config, options = {}) {
|
|
31
31
|
try {
|
|
32
32
|
const existing = await getAllComponentsGroups(config);
|
|
33
33
|
const existingNames = new Set((existing ?? []).map((g) => g.name));
|
|
34
34
|
for (const groupName of groupNames) {
|
|
35
35
|
if (!existingNames.has(groupName)) {
|
|
36
|
+
if (options.dryRun) {
|
|
37
|
+
Logger.warning(`[dry-run] Would create component group '${groupName}'.`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
36
40
|
await createComponentsGroup(groupName, config);
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -52,7 +56,7 @@ function resolveGroupUuid(component, remoteGroups) {
|
|
|
52
56
|
return { ...component, component_group_uuid: match.uuid };
|
|
53
57
|
}
|
|
54
58
|
export async function syncComponentsData(args, config) {
|
|
55
|
-
const { components, presets, ssot, onProgress } = args;
|
|
59
|
+
const { components, presets, ssot, dryRun, onProgress } = args;
|
|
56
60
|
const progress = onProgress ?? defaultProgress;
|
|
57
61
|
const result = {
|
|
58
62
|
created: [],
|
|
@@ -60,23 +64,37 @@ export async function syncComponentsData(args, config) {
|
|
|
60
64
|
skipped: [],
|
|
61
65
|
errors: [],
|
|
62
66
|
};
|
|
67
|
+
if (dryRun) {
|
|
68
|
+
Logger.warning("[dry-run] Component sync will only read remote data and report planned changes.");
|
|
69
|
+
}
|
|
63
70
|
if (ssot) {
|
|
64
71
|
const existingComponents = await getAllComponents(config);
|
|
65
72
|
const existingGroups = await getAllComponentsGroups(config);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
if (dryRun) {
|
|
74
|
+
for (const component of existingComponents ?? []) {
|
|
75
|
+
Logger.warning(`[dry-run] Would remove component '${component.name}'.`);
|
|
76
|
+
}
|
|
77
|
+
for (const group of existingGroups ?? []) {
|
|
78
|
+
Logger.warning(`[dry-run] Would remove component group '${group.name}'.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
await Promise.allSettled([
|
|
83
|
+
...(existingComponents ?? []).map((c) => removeComponent(c, config)),
|
|
84
|
+
...(existingGroups ?? []).map((g) => removeComponentGroup(g, config)),
|
|
85
|
+
]);
|
|
86
|
+
}
|
|
70
87
|
}
|
|
71
88
|
const nonEmptyComponents = components.filter((c) => !isObjectEmpty(c));
|
|
72
89
|
const groupsToCheck = uniqueValuesFrom(nonEmptyComponents
|
|
73
90
|
.filter((c) => c.component_group_name)
|
|
74
91
|
.map((c) => c.component_group_name));
|
|
75
|
-
await ensureComponentGroupsExist(groupsToCheck, config);
|
|
92
|
+
await ensureComponentGroupsExist(groupsToCheck, config, { dryRun });
|
|
76
93
|
let remoteComponents = [];
|
|
77
94
|
let remoteGroups = [];
|
|
78
95
|
try {
|
|
79
|
-
remoteComponents =
|
|
96
|
+
remoteComponents =
|
|
97
|
+
ssot && dryRun ? [] : ((await getAllComponents(config)) ?? []);
|
|
80
98
|
}
|
|
81
99
|
catch (error) {
|
|
82
100
|
Logger.warning(`Could not fetch remote components: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -121,6 +139,18 @@ export async function syncComponentsData(args, config) {
|
|
|
121
139
|
action: "updating",
|
|
122
140
|
});
|
|
123
141
|
try {
|
|
142
|
+
if (dryRun) {
|
|
143
|
+
Logger.warning(`[dry-run] Would update component '${name}'.`);
|
|
144
|
+
result.updated.push(name);
|
|
145
|
+
progress({
|
|
146
|
+
type: "progress",
|
|
147
|
+
current: currentIndex,
|
|
148
|
+
total: totalComponents,
|
|
149
|
+
name,
|
|
150
|
+
action: "updated",
|
|
151
|
+
});
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
124
154
|
await updateComponent(component, presets, config);
|
|
125
155
|
result.updated.push(name);
|
|
126
156
|
progress({
|
|
@@ -158,6 +188,18 @@ export async function syncComponentsData(args, config) {
|
|
|
158
188
|
action: "creating",
|
|
159
189
|
});
|
|
160
190
|
try {
|
|
191
|
+
if (dryRun) {
|
|
192
|
+
Logger.warning(`[dry-run] Would create component '${name}'.`);
|
|
193
|
+
result.created.push(name);
|
|
194
|
+
progress({
|
|
195
|
+
type: "progress",
|
|
196
|
+
current: currentIndex,
|
|
197
|
+
total: totalComponents,
|
|
198
|
+
name,
|
|
199
|
+
action: "created",
|
|
200
|
+
});
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
161
203
|
await createComponent(component, presets, config);
|
|
162
204
|
result.created.push(name);
|
|
163
205
|
progress({
|
|
@@ -48,16 +48,28 @@ export const getDatasourceEntries = async (args, config) => {
|
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
export const createDatasourceEntries = (args, config) => {
|
|
51
|
-
const { datasource_entries, remoteDatasourceEntries, data } = args;
|
|
51
|
+
const { datasource_entries, remoteDatasourceEntries, data, dryRun } = args;
|
|
52
|
+
const remoteEntries = Array.isArray(remoteDatasourceEntries?.datasource_entries)
|
|
53
|
+
? remoteDatasourceEntries.datasource_entries
|
|
54
|
+
: [];
|
|
52
55
|
return Promise.all(datasource_entries.map((datasourceEntry) => {
|
|
53
|
-
const
|
|
54
|
-
|
|
56
|
+
const datasourceEntryName = datasourceEntry.name ?? Object.values(datasourceEntry)[0];
|
|
57
|
+
const datasourceToBeUpdated = remoteEntries.find((remoteDatasourceEntry) => remoteDatasourceEntry.name === datasourceEntryName);
|
|
58
|
+
if (dryRun) {
|
|
59
|
+
const action = datasourceToBeUpdated ? "update" : "create";
|
|
60
|
+
Logger.warning(`[dry-run] Would ${action} datasource entry '${datasourceEntryName}' in '${data.datasource.name}' datasource.`);
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
55
63
|
if (datasourceToBeUpdated) {
|
|
56
64
|
return updateDatasourceEntry({ data, datasourceEntry, datasourceToBeUpdated }, config);
|
|
57
65
|
}
|
|
58
66
|
return createDatasourceEntry({ data, datasourceEntry }, config);
|
|
59
67
|
}))
|
|
60
68
|
.then((_) => {
|
|
69
|
+
if (dryRun) {
|
|
70
|
+
Logger.warning(`[dry-run] Datasource entries for ${data.datasource.id} datasource id were planned without API writes.`);
|
|
71
|
+
return data;
|
|
72
|
+
}
|
|
61
73
|
Logger.success(`Datasource entries for ${data.datasource.id} datasource id has been successfully synced.`);
|
|
62
74
|
return data;
|
|
63
75
|
})
|
|
@@ -4,6 +4,7 @@ export declare const getAllDatasources: GetAllDatasources;
|
|
|
4
4
|
export declare const getDatasource: GetDatasource;
|
|
5
5
|
export declare const createDatasource: CreateDatasource;
|
|
6
6
|
export declare const updateDatasource: UpdateDatasource;
|
|
7
|
-
export declare const syncDatasourcesData: ({ datasources }: {
|
|
7
|
+
export declare const syncDatasourcesData: ({ datasources, dryRun }: {
|
|
8
8
|
datasources: any[];
|
|
9
|
+
dryRun?: boolean;
|
|
9
10
|
}, config: any) => Promise<SyncResult>;
|
|
@@ -110,13 +110,16 @@ export const updateDatasource = (args, config) => {
|
|
|
110
110
|
.catch((err) => Logger.error(err));
|
|
111
111
|
};
|
|
112
112
|
// File-based sync wrapper lives in `datasources.sync.ts` to keep this module CJS-safe.
|
|
113
|
-
export const syncDatasourcesData = async ({ datasources }, config) => {
|
|
113
|
+
export const syncDatasourcesData = async ({ datasources, dryRun }, config) => {
|
|
114
114
|
const result = {
|
|
115
115
|
created: [],
|
|
116
116
|
updated: [],
|
|
117
117
|
skipped: [],
|
|
118
118
|
errors: [],
|
|
119
119
|
};
|
|
120
|
+
if (dryRun) {
|
|
121
|
+
Logger.warning("[dry-run] Datasource sync will only read remote data and report planned changes.");
|
|
122
|
+
}
|
|
120
123
|
const remoteDatasourcesRaw = await getAllDatasources(config);
|
|
121
124
|
const remoteDatasources = Array.isArray(remoteDatasourcesRaw)
|
|
122
125
|
? remoteDatasourcesRaw
|
|
@@ -129,6 +132,32 @@ export const syncDatasourcesData = async ({ datasources }, config) => {
|
|
|
129
132
|
}
|
|
130
133
|
try {
|
|
131
134
|
const datasourceToBeUpdated = remoteDatasources.find((remoteDatasource) => datasource.name === remoteDatasource.name);
|
|
135
|
+
if (dryRun) {
|
|
136
|
+
if (datasourceToBeUpdated) {
|
|
137
|
+
result.updated.push(name);
|
|
138
|
+
Logger.warning(`[dry-run] Would update datasource '${name}'.`);
|
|
139
|
+
const remoteDatasourceEntries = await getDatasourceEntries({
|
|
140
|
+
datasourceName: name,
|
|
141
|
+
}, config);
|
|
142
|
+
await createDatasourceEntries({
|
|
143
|
+
data: { datasource: datasourceToBeUpdated },
|
|
144
|
+
datasource_entries: datasource.datasource_entries ?? [],
|
|
145
|
+
remoteDatasourceEntries,
|
|
146
|
+
dryRun,
|
|
147
|
+
}, config);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const entriesCount = Array.isArray(datasource.datasource_entries)
|
|
151
|
+
? datasource.datasource_entries.length
|
|
152
|
+
: 0;
|
|
153
|
+
result.created.push(name);
|
|
154
|
+
Logger.warning(`[dry-run] Would create datasource '${name}'.`);
|
|
155
|
+
if (entriesCount > 0) {
|
|
156
|
+
Logger.warning(`[dry-run] Would create ${entriesCount} datasource entries for '${name}' after datasource creation.`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
132
161
|
const opResult = datasourceToBeUpdated
|
|
133
162
|
? await updateDatasource({ datasource, datasourceToBeUpdated }, config)
|
|
134
163
|
: await createDatasource({ datasource }, config);
|
|
@@ -2,10 +2,10 @@ import { getFileContentWithRequire } from "../../utils/files.js";
|
|
|
2
2
|
import Logger from "../../utils/logger.js";
|
|
3
3
|
import { syncDatasourcesData } from "./datasources.js";
|
|
4
4
|
export const syncDatasources = async (args, config) => {
|
|
5
|
-
const { providedDatasources } = args;
|
|
5
|
+
const { providedDatasources, dryRun } = args;
|
|
6
6
|
Logger.log(`Trying to sync provided datasources: `);
|
|
7
7
|
const providedDatasourcesContent = await Promise.all(providedDatasources.map((datasource) => {
|
|
8
8
|
return getFileContentWithRequire({ file: datasource.p });
|
|
9
9
|
}));
|
|
10
|
-
await syncDatasourcesData({ datasources: providedDatasourcesContent }, config);
|
|
10
|
+
await syncDatasourcesData({ datasources: providedDatasourcesContent, dryRun }, config);
|
|
11
11
|
};
|
|
@@ -13,11 +13,15 @@ export type UpdateDatasource = (args: {
|
|
|
13
13
|
}, config: RequestBaseConfig) => Promise<any>;
|
|
14
14
|
export type SyncDatasources = (args: {
|
|
15
15
|
providedDatasources: OneFileElement[];
|
|
16
|
+
dryRun?: boolean;
|
|
16
17
|
}, config: RequestBaseConfig) => Promise<any>;
|
|
17
18
|
export type SyncProvidedDatasources = (args: {
|
|
18
19
|
datasources: string[];
|
|
20
|
+
dryRun?: boolean;
|
|
19
21
|
}, config: RequestBaseConfig) => Promise<void>;
|
|
20
|
-
export type SyncAllDatasources = (config: RequestBaseConfig
|
|
22
|
+
export type SyncAllDatasources = (config: RequestBaseConfig, args?: {
|
|
23
|
+
dryRun?: boolean;
|
|
24
|
+
}) => Promise<void>;
|
|
21
25
|
export type GetDatasourceEntries = (args: {
|
|
22
26
|
datasourceName: string;
|
|
23
27
|
}, config: RequestBaseConfig) => Promise<any>;
|
|
@@ -25,6 +29,7 @@ export type CreateDatasourceEntries = (args: {
|
|
|
25
29
|
data: any;
|
|
26
30
|
datasource_entries: any;
|
|
27
31
|
remoteDatasourceEntries: any;
|
|
32
|
+
dryRun?: boolean;
|
|
28
33
|
}, config: RequestBaseConfig) => Promise<any> | void;
|
|
29
34
|
export type CreateDatasourceEntry = (args: {
|
|
30
35
|
data: any;
|
package/dist/api/migrate.js
CHANGED
|
@@ -53,7 +53,7 @@ const _resolveGroups = async (component, existedGroups, remoteComponentsGroups)
|
|
|
53
53
|
return { ...component, component_group_uuid };
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
|
-
export const syncComponents = async (specifiedComponents, presets, config) => {
|
|
56
|
+
export const syncComponents = async (specifiedComponents, presets, config, options = {}) => {
|
|
57
57
|
Logger.log("sync2Components: ");
|
|
58
58
|
let specifiedComponentsContent = await Promise.all(specifiedComponents.map((component) => {
|
|
59
59
|
return getFileContentWithRequire({ file: component.p });
|
|
@@ -64,9 +64,14 @@ export const syncComponents = async (specifiedComponents, presets, config) => {
|
|
|
64
64
|
* - .sb.resolvers.ts files resolvers
|
|
65
65
|
*/
|
|
66
66
|
specifiedComponentsContent = await resolveGlobalTransformations(specifiedComponentsContent);
|
|
67
|
-
await syncComponentsData({
|
|
67
|
+
await syncComponentsData({
|
|
68
|
+
components: specifiedComponentsContent,
|
|
69
|
+
presets,
|
|
70
|
+
ssot: options.ssot,
|
|
71
|
+
dryRun: options.dryRun,
|
|
72
|
+
}, config);
|
|
68
73
|
};
|
|
69
|
-
export const syncAllComponents = async (presets, config) => {
|
|
74
|
+
export const syncAllComponents = async (presets, config, options = {}) => {
|
|
70
75
|
// #1: discover all external .sb.js files
|
|
71
76
|
const allLocalSbComponentsSchemaFiles = await discover({
|
|
72
77
|
scope: SCOPE.local,
|
|
@@ -83,9 +88,12 @@ export const syncAllComponents = async (presets, config) => {
|
|
|
83
88
|
external: allExternalSbComponentsSchemaFiles,
|
|
84
89
|
});
|
|
85
90
|
// #4: sync - do all stuff already done (groups resolving, and so on)
|
|
86
|
-
return await syncComponents([...local, ...external], presets, config
|
|
91
|
+
return await syncComponents([...local, ...external], presets, config, {
|
|
92
|
+
dryRun: options.dryRun,
|
|
93
|
+
ssot: options.ssot,
|
|
94
|
+
});
|
|
87
95
|
};
|
|
88
|
-
export const syncProvidedComponents = async (presets, components, packageName, config) => {
|
|
96
|
+
export const syncProvidedComponents = async (presets, components, packageName, config, options = {}) => {
|
|
89
97
|
if (!packageName) {
|
|
90
98
|
// #1: discover all external .sb.js files
|
|
91
99
|
const allLocalSbComponentsSchemaFiles = await discoverMany({
|
|
@@ -105,7 +113,9 @@ export const syncProvidedComponents = async (presets, components, packageName, c
|
|
|
105
113
|
external: allExternalSbComponentsSchemaFiles,
|
|
106
114
|
});
|
|
107
115
|
// #4: sync - do all stuff already done (groups resolving, and so on)
|
|
108
|
-
return await syncComponents([...local, ...external], presets, config
|
|
116
|
+
return await syncComponents([...local, ...external], presets, config, {
|
|
117
|
+
dryRun: options.dryRun,
|
|
118
|
+
});
|
|
109
119
|
}
|
|
110
120
|
else {
|
|
111
121
|
// implement discovering and syncrhonizing with packageName
|
|
@@ -125,13 +135,20 @@ export const syncProvidedComponents = async (presets, components, packageName, c
|
|
|
125
135
|
external: allExternalSbComponentsSchemaFiles,
|
|
126
136
|
});
|
|
127
137
|
// #4: sync - do all stuff already done (groups resolving, and so on)
|
|
128
|
-
return syncComponents([...local, ...external], presets, config
|
|
138
|
+
return syncComponents([...local, ...external], presets, config, {
|
|
139
|
+
dryRun: options.dryRun,
|
|
140
|
+
});
|
|
129
141
|
}
|
|
130
142
|
};
|
|
131
|
-
export const syncAssets = async ({ transmission: { from, to }, syncDirection }, config) => {
|
|
143
|
+
export const syncAssets = async ({ transmission: { from, to }, syncDirection, dryRun }, config) => {
|
|
132
144
|
Logger.log(`We would try to migrate Assets data from: ${from} to: ${to}`);
|
|
133
145
|
const allAssets = await getAllAssets({ spaceId: from }, config);
|
|
134
|
-
|
|
146
|
+
const assets = Array.isArray(allAssets?.assets) ? allAssets.assets : [];
|
|
147
|
+
if (dryRun) {
|
|
148
|
+
Logger.warning(`[dry-run] Would sync ${assets.length} assets from ${from} to ${to}.`);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
await Promise.all(assets.map((asset) => {
|
|
135
152
|
const { id, created_at, updated_at, ...newAssetPayload } = asset;
|
|
136
153
|
return migrateAsset({
|
|
137
154
|
migrateTo: to,
|
|
@@ -139,13 +156,18 @@ export const syncAssets = async ({ transmission: { from, to }, syncDirection },
|
|
|
139
156
|
syncDirection,
|
|
140
157
|
}, config);
|
|
141
158
|
}));
|
|
159
|
+
return true;
|
|
142
160
|
};
|
|
143
|
-
const syncStories = async ({ transmission: { from, to }, stories, toSpaceId }, config) => {
|
|
161
|
+
const syncStories = async ({ transmission: { from, to }, stories, toSpaceId, dryRun }, config) => {
|
|
144
162
|
Logger.log(`We would try to migrate Stories data from: ${from} to: ${to}`);
|
|
145
163
|
const storiesToPass = stories
|
|
146
164
|
.map((item) => item.story)
|
|
147
165
|
.map((item) => item.parent_id === 0 ? { ...item, parent_id: null } : item);
|
|
148
166
|
Logger.warning(`Amount of all stories to migrate: ${storiesToPass.length}`);
|
|
167
|
+
if (dryRun) {
|
|
168
|
+
Logger.warning(`[dry-run] Would sync ${storiesToPass.length} stories from ${from} to ${to}.`);
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
149
171
|
const storiesToPassJson = JSON.stringify(storiesToPass, null, 2);
|
|
150
172
|
if (config.debug) {
|
|
151
173
|
dumpToFile("storiesToPass.json", storiesToPassJson);
|
|
@@ -156,10 +178,23 @@ const syncStories = async ({ transmission: { from, to }, stories, toSpaceId }, c
|
|
|
156
178
|
dumpToFile("tree.json", jsonString);
|
|
157
179
|
}
|
|
158
180
|
await traverseAndCreate({ tree, realParentId: null, spaceId: toSpaceId }, config);
|
|
181
|
+
return true;
|
|
159
182
|
};
|
|
160
|
-
export const syncContent = async ({ type, transmission, syncDirection, filename }, config) => {
|
|
183
|
+
export const syncContent = async ({ type, transmission, syncDirection, filename, dryRun }, config) => {
|
|
184
|
+
if (dryRun) {
|
|
185
|
+
Logger.warning("[dry-run] Content sync will only read source data and report planned changes.");
|
|
186
|
+
}
|
|
161
187
|
if (type === "stories") {
|
|
162
188
|
if (syncDirection === "fromSpaceToFile") {
|
|
189
|
+
if (dryRun) {
|
|
190
|
+
const stories = await getAllStories({}, {
|
|
191
|
+
...config,
|
|
192
|
+
spaceId: transmission.from,
|
|
193
|
+
sbApi: config.sbApi,
|
|
194
|
+
});
|
|
195
|
+
Logger.warning(`[dry-run] Would back up ${stories.length} stories from ${transmission.from} to '${transmission.to}'.`);
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
163
198
|
await backupStories({
|
|
164
199
|
filename: transmission.to,
|
|
165
200
|
suffix: ".sb.stories",
|
|
@@ -176,6 +211,7 @@ export const syncContent = async ({ type, transmission, syncDirection, filename
|
|
|
176
211
|
transmission,
|
|
177
212
|
stories,
|
|
178
213
|
toSpaceId: transmission.to,
|
|
214
|
+
dryRun,
|
|
179
215
|
}, config);
|
|
180
216
|
}
|
|
181
217
|
if (syncDirection === "fromFileToSpace") {
|
|
@@ -191,6 +227,7 @@ export const syncContent = async ({ type, transmission, syncDirection, filename
|
|
|
191
227
|
transmission,
|
|
192
228
|
stories: storiesFileContent[0],
|
|
193
229
|
toSpaceId: transmission.to,
|
|
230
|
+
dryRun,
|
|
194
231
|
}, config);
|
|
195
232
|
}
|
|
196
233
|
if (syncDirection === "fromAWSToSpace") {
|
|
@@ -199,6 +236,7 @@ export const syncContent = async ({ type, transmission, syncDirection, filename
|
|
|
199
236
|
transmission,
|
|
200
237
|
stories: data.stories,
|
|
201
238
|
toSpaceId: transmission.to,
|
|
239
|
+
dryRun,
|
|
202
240
|
}, config);
|
|
203
241
|
}
|
|
204
242
|
return true;
|
|
@@ -209,7 +247,7 @@ export const syncContent = async ({ type, transmission, syncDirection, filename
|
|
|
209
247
|
}
|
|
210
248
|
else if (syncDirection === "fromSpaceToSpace" ||
|
|
211
249
|
syncDirection === "fromSpaceToFile") {
|
|
212
|
-
await syncAssets({ transmission, syncDirection }, config);
|
|
250
|
+
await syncAssets({ transmission, syncDirection, dryRun }, config);
|
|
213
251
|
}
|
|
214
252
|
else {
|
|
215
253
|
Logger.warning(`${syncDirection} with ${type} This is not implemented yet!`);
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { RequestBaseConfig } from "./utils/request.js";
|
|
2
2
|
import type { SyncDirection } from "../cli/sync.types.js";
|
|
3
|
+
import type { SyncOptions } from "./sync/sync.types.js";
|
|
3
4
|
import type { OneFileElement } from "../cli/utils/discover.js";
|
|
4
|
-
export type SyncComponents = (specifiedComponents: OneFileElement[], presets: boolean, config: RequestBaseConfig
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export type
|
|
5
|
+
export type SyncComponents = (specifiedComponents: OneFileElement[], presets: boolean, config: RequestBaseConfig, options?: SyncOptions & {
|
|
6
|
+
ssot?: boolean;
|
|
7
|
+
}) => Promise<any>;
|
|
8
|
+
export type SyncAllComponents = (presets: boolean, config: RequestBaseConfig, options?: SyncOptions & {
|
|
9
|
+
ssot?: boolean;
|
|
10
|
+
}) => Promise<any>;
|
|
11
|
+
export type SyncProvidedComponents = (presets: boolean, components: string[], packageName: boolean, config: RequestBaseConfig, options?: SyncOptions) => Promise<any>;
|
|
12
|
+
export type SyncStories = ({ transmission, stories, toSpaceId, dryRun, }: {
|
|
8
13
|
transmission: SyncContent["transmission"];
|
|
9
14
|
stories: any[];
|
|
10
15
|
toSpaceId: string;
|
|
16
|
+
dryRun?: boolean;
|
|
11
17
|
}, config: RequestBaseConfig) => Promise<any>;
|
|
12
18
|
export interface SyncContent {
|
|
13
19
|
type: "stories" | "assets";
|
|
@@ -17,9 +23,11 @@ export interface SyncContent {
|
|
|
17
23
|
};
|
|
18
24
|
syncDirection: SyncDirection;
|
|
19
25
|
filename?: string;
|
|
26
|
+
dryRun?: boolean;
|
|
20
27
|
}
|
|
21
|
-
export type SyncContentFunction = ({ type, transmission, syncDirection, filename }: SyncContent, config: RequestBaseConfig) => Promise<any>;
|
|
22
|
-
export type SyncAssets = ({ transmission, }: {
|
|
28
|
+
export type SyncContentFunction = ({ type, transmission, syncDirection, filename, dryRun }: SyncContent, config: RequestBaseConfig) => Promise<any>;
|
|
29
|
+
export type SyncAssets = ({ transmission, dryRun, }: {
|
|
23
30
|
transmission: SyncContent["transmission"];
|
|
24
31
|
syncDirection: SyncDirection;
|
|
32
|
+
dryRun?: boolean;
|
|
25
33
|
}, config: RequestBaseConfig) => Promise<any>;
|
|
@@ -5,9 +5,10 @@ export declare const getPlugin: GetPlugin;
|
|
|
5
5
|
export declare const getPluginDetails: GetPluginDetails;
|
|
6
6
|
export declare const updatePlugin: UpdatePlugin;
|
|
7
7
|
export declare const createPlugin: CreatePlugin;
|
|
8
|
-
export declare const syncPluginsData: ({ plugins }: {
|
|
8
|
+
export declare const syncPluginsData: ({ plugins, dryRun, }: {
|
|
9
9
|
plugins: {
|
|
10
10
|
name: string;
|
|
11
11
|
body: string;
|
|
12
12
|
}[];
|
|
13
|
+
dryRun?: boolean;
|
|
13
14
|
}, config: any) => Promise<SyncResult>;
|
|
@@ -87,13 +87,17 @@ export const createPlugin = (pluginName, config) => {
|
|
|
87
87
|
});
|
|
88
88
|
};
|
|
89
89
|
// File-based sync wrapper lives in `plugins.sync.ts` to keep this module CJS-safe.
|
|
90
|
-
export const syncPluginsData = async ({ plugins }, config) => {
|
|
90
|
+
export const syncPluginsData = async ({ plugins, dryRun, }, config) => {
|
|
91
91
|
const result = {
|
|
92
92
|
created: [],
|
|
93
93
|
updated: [],
|
|
94
94
|
skipped: [],
|
|
95
95
|
errors: [],
|
|
96
96
|
};
|
|
97
|
+
if (dryRun) {
|
|
98
|
+
Logger.warning("[dry-run] Plugin sync will only read remote data and report planned changes.");
|
|
99
|
+
}
|
|
100
|
+
const remotePlugins = dryRun ? await getAllPlugins(config) : [];
|
|
97
101
|
for (const p of plugins) {
|
|
98
102
|
const name = String(p?.name ?? "unknown");
|
|
99
103
|
if (!p?.name) {
|
|
@@ -101,6 +105,20 @@ export const syncPluginsData = async ({ plugins }, config) => {
|
|
|
101
105
|
continue;
|
|
102
106
|
}
|
|
103
107
|
try {
|
|
108
|
+
if (dryRun) {
|
|
109
|
+
const plugin = Array.isArray(remotePlugins)
|
|
110
|
+
? remotePlugins.find((remotePlugin) => remotePlugin.name === name)
|
|
111
|
+
: undefined;
|
|
112
|
+
if (plugin) {
|
|
113
|
+
Logger.warning(`[dry-run] Would update plugin '${name}'.`);
|
|
114
|
+
result.updated.push(name);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
Logger.warning(`[dry-run] Would create plugin '${name}'.`);
|
|
118
|
+
result.created.push(name);
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
104
122
|
const plugin = await getPlugin(name, config);
|
|
105
123
|
if (plugin) {
|
|
106
124
|
await updatePlugin({ plugin: plugin.field_type, body: p.body }, config);
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { readFile } from "../../utils/files.js";
|
|
2
2
|
import { syncPluginsData } from "./plugins.js";
|
|
3
|
-
export const syncProvidedPlugins = async ({ plugins }, config) => {
|
|
4
|
-
const body = await readFile("dist/export.js");
|
|
5
|
-
if (!body) {
|
|
3
|
+
export const syncProvidedPlugins = async ({ plugins, dryRun }, config) => {
|
|
4
|
+
const body = dryRun ? "" : await readFile("dist/export.js");
|
|
5
|
+
if (!body && !dryRun) {
|
|
6
6
|
throw new Error("Unable to read plugin bundle from dist/export.js");
|
|
7
7
|
}
|
|
8
8
|
await syncPluginsData({
|
|
9
|
-
plugins: plugins.map((name) => ({
|
|
9
|
+
plugins: plugins.map((name) => ({
|
|
10
|
+
name: String(name),
|
|
11
|
+
body: body ?? "",
|
|
12
|
+
})),
|
|
13
|
+
dryRun,
|
|
10
14
|
}, config);
|
|
11
15
|
};
|
|
@@ -9,6 +9,7 @@ interface UpdatePluginDTO {
|
|
|
9
9
|
}
|
|
10
10
|
interface SyncProvidedPluginsDTO {
|
|
11
11
|
plugins: string[];
|
|
12
|
+
dryRun?: boolean;
|
|
12
13
|
}
|
|
13
14
|
export type GetPlugin = (pluginName: string | undefined, config: RequestBaseConfig) => Promise<any>;
|
|
14
15
|
export type GetAllPlugins = (config: RequestBaseConfig) => Promise<any>;
|
|
@@ -4,6 +4,7 @@ export declare const createRole: CreateRole;
|
|
|
4
4
|
export declare const updateRole: UpdateRole;
|
|
5
5
|
export declare const getAllRoles: GetAllRoles;
|
|
6
6
|
export declare const getRole: GetRole;
|
|
7
|
-
export declare const syncRolesData: ({ roles }: {
|
|
7
|
+
export declare const syncRolesData: ({ roles, dryRun }: {
|
|
8
8
|
roles: any[];
|
|
9
|
+
dryRun?: boolean;
|
|
9
10
|
}, config: any) => Promise<SyncResult>;
|
package/dist/api/roles/roles.js
CHANGED
|
@@ -75,13 +75,16 @@ export const getRole = async (roleName, config) => {
|
|
|
75
75
|
})
|
|
76
76
|
.catch((err) => Logger.error(err));
|
|
77
77
|
};
|
|
78
|
-
export const syncRolesData = async ({ roles }, config) => {
|
|
78
|
+
export const syncRolesData = async ({ roles, dryRun }, config) => {
|
|
79
79
|
const result = {
|
|
80
80
|
created: [],
|
|
81
81
|
updated: [],
|
|
82
82
|
skipped: [],
|
|
83
83
|
errors: [],
|
|
84
84
|
};
|
|
85
|
+
if (dryRun) {
|
|
86
|
+
Logger.warning("[dry-run] Role sync will only read remote data and report planned changes.");
|
|
87
|
+
}
|
|
85
88
|
const space_roles_raw = await getAllRoles(config);
|
|
86
89
|
const space_roles = Array.isArray(space_roles_raw) ? space_roles_raw : [];
|
|
87
90
|
const rolesToUpdate = [];
|
|
@@ -99,17 +102,27 @@ export const syncRolesData = async ({ roles }, config) => {
|
|
|
99
102
|
rolesToCreate.push(role);
|
|
100
103
|
}
|
|
101
104
|
}
|
|
102
|
-
const updateResults =
|
|
105
|
+
const updateResults = dryRun
|
|
106
|
+
? rolesToUpdate.map(() => ({ status: "fulfilled" }))
|
|
107
|
+
: await Promise.allSettled(rolesToUpdate.map((role) => updateRole(role, config)));
|
|
103
108
|
updateResults.forEach((r, idx) => {
|
|
104
109
|
const name = String(rolesToUpdate[idx]?.role ?? "unknown");
|
|
110
|
+
if (dryRun) {
|
|
111
|
+
Logger.warning(`[dry-run] Would update role '${name}'.`);
|
|
112
|
+
}
|
|
105
113
|
if (r.status === "fulfilled")
|
|
106
114
|
result.updated.push(name);
|
|
107
115
|
else
|
|
108
116
|
result.errors.push({ name, message: String(r.reason) });
|
|
109
117
|
});
|
|
110
|
-
const createResults =
|
|
118
|
+
const createResults = dryRun
|
|
119
|
+
? rolesToCreate.map(() => ({ status: "fulfilled" }))
|
|
120
|
+
: await Promise.allSettled(rolesToCreate.map((role) => createRole(role, config)));
|
|
111
121
|
createResults.forEach((r, idx) => {
|
|
112
122
|
const name = String(rolesToCreate[idx]?.role ?? "unknown");
|
|
123
|
+
if (dryRun) {
|
|
124
|
+
Logger.warning(`[dry-run] Would create role '${name}'.`);
|
|
125
|
+
}
|
|
113
126
|
if (r.status === "fulfilled")
|
|
114
127
|
result.created.push(name);
|
|
115
128
|
else
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getFileContentWithRequire } from "../../utils/files.js";
|
|
2
2
|
import { syncRolesData } from "./roles.js";
|
|
3
|
-
export const syncRoles = async ({ specifiedRoles }, config) => {
|
|
3
|
+
export const syncRoles = async ({ specifiedRoles, dryRun }, config) => {
|
|
4
4
|
const specifiedRolesContent = await Promise.all(specifiedRoles.map((roles) => getFileContentWithRequire({ file: roles.p })));
|
|
5
|
-
await syncRolesData({ roles: specifiedRolesContent }, config);
|
|
5
|
+
await syncRolesData({ roles: specifiedRolesContent, dryRun }, config);
|
|
6
6
|
};
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import type { OneFileElement } from "../../utils/path-utils.js";
|
|
2
|
+
import type { SyncOptions } from "../sync/sync.types.js";
|
|
2
3
|
import type { RequestBaseConfig } from "../utils/request.js";
|
|
3
4
|
export type GetRole = (roleName: string | undefined, config: RequestBaseConfig) => Promise<void>;
|
|
4
5
|
export type GetAllRoles = (config: RequestBaseConfig) => Promise<any>;
|
|
5
6
|
export type CreateRole = (role: any, config: RequestBaseConfig) => void;
|
|
6
7
|
export type UpdateRole = (role: any, config: RequestBaseConfig) => void;
|
|
7
|
-
export type SyncRoles = ({ specifiedRoles }: {
|
|
8
|
+
export type SyncRoles = ({ specifiedRoles, dryRun, }: {
|
|
8
9
|
specifiedRoles: OneFileElement[];
|
|
10
|
+
dryRun?: boolean;
|
|
9
11
|
}, config: RequestBaseConfig) => Promise<void>;
|
|
10
|
-
export type SyncAllRoles = (config: RequestBaseConfig) => Promise<void>;
|
|
11
|
-
export type SyncProvidedRoles = ({ roles }: {
|
|
12
|
+
export type SyncAllRoles = (config: RequestBaseConfig, options?: SyncOptions) => Promise<void>;
|
|
13
|
+
export type SyncProvidedRoles = ({ roles, dryRun }: {
|
|
12
14
|
roles: string[];
|
|
15
|
+
dryRun?: boolean;
|
|
13
16
|
}, config: RequestBaseConfig) => Promise<void>;
|