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,13 @@
|
|
|
1
|
+
import type { ApiClient } from "../client.js";
|
|
2
|
+
export declare function getAllPresets(client: ApiClient): Promise<any>;
|
|
3
|
+
export declare function getPreset(client: ApiClient, presetId: string): Promise<any>;
|
|
4
|
+
export declare function createPreset(client: ApiClient, preset: any): Promise<any>;
|
|
5
|
+
export declare function updatePreset(client: ApiClient, preset: any): Promise<any>;
|
|
6
|
+
export declare function updatePresets(client: ApiClient, args: {
|
|
7
|
+
presets: any[];
|
|
8
|
+
spaceId: string;
|
|
9
|
+
options?: {
|
|
10
|
+
publish?: boolean;
|
|
11
|
+
};
|
|
12
|
+
}): Promise<any>;
|
|
13
|
+
export declare function getComponentPresets(client: ApiClient, componentName: string): Promise<any>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getComponentPresets as apiGetComponentPresets } from "../../api/presets/componentPresets.js";
|
|
2
|
+
import { getAllPresets as apiGetAllPresets, getPreset as apiGetPreset, createPreset as apiCreatePreset, updatePreset as apiUpdatePreset, updatePresets as apiUpdatePresets, } from "../../api/presets/presets.js";
|
|
3
|
+
import { toRequestConfig } from "../requestConfig.js";
|
|
4
|
+
export async function getAllPresets(client) {
|
|
5
|
+
return await apiGetAllPresets(toRequestConfig(client));
|
|
6
|
+
}
|
|
7
|
+
export async function getPreset(client, presetId) {
|
|
8
|
+
return await apiGetPreset({ presetId }, toRequestConfig(client));
|
|
9
|
+
}
|
|
10
|
+
export async function createPreset(client, preset) {
|
|
11
|
+
return await apiCreatePreset(preset, toRequestConfig(client));
|
|
12
|
+
}
|
|
13
|
+
export async function updatePreset(client, preset) {
|
|
14
|
+
return await apiUpdatePreset({ p: preset }, toRequestConfig(client));
|
|
15
|
+
}
|
|
16
|
+
export async function updatePresets(client, args) {
|
|
17
|
+
return await apiUpdatePresets({
|
|
18
|
+
presets: args.presets,
|
|
19
|
+
spaceId: args.spaceId,
|
|
20
|
+
options: args.options ?? {},
|
|
21
|
+
}, toRequestConfig(client));
|
|
22
|
+
}
|
|
23
|
+
export async function getComponentPresets(client, componentName) {
|
|
24
|
+
return await apiGetComponentPresets(componentName, toRequestConfig(client));
|
|
25
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ApiClient } from "./client.js";
|
|
2
|
+
import type { RequestBaseConfig } from "../api/utils/request.js";
|
|
3
|
+
export declare function toRequestConfig(client: ApiClient, overrides?: Partial<Omit<RequestBaseConfig, "sbApi">> & {
|
|
4
|
+
spaceId?: string;
|
|
5
|
+
}): RequestBaseConfig;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function toRequestConfig(client, overrides) {
|
|
2
|
+
return {
|
|
3
|
+
spaceId: overrides?.spaceId ?? client.spaceId,
|
|
4
|
+
sbApi: client.sbApi,
|
|
5
|
+
oauthToken: overrides?.oauthToken ?? client.config.oauthToken,
|
|
6
|
+
accessToken: overrides?.accessToken ?? client.config.accessToken,
|
|
7
|
+
storyblokApiUrl: overrides?.storyblokApiUrl,
|
|
8
|
+
storyblokDeliveryApiUrl: overrides?.storyblokDeliveryApiUrl,
|
|
9
|
+
storyblokGraphqlApiUrl: overrides?.storyblokGraphqlApiUrl,
|
|
10
|
+
schemaFileExt: overrides?.schemaFileExt,
|
|
11
|
+
datasourceExt: overrides?.datasourceExt,
|
|
12
|
+
rolesExt: overrides?.rolesExt,
|
|
13
|
+
storiesExt: overrides?.storiesExt,
|
|
14
|
+
migrationConfigExt: overrides?.migrationConfigExt,
|
|
15
|
+
sbmigWorkingDirectory: overrides?.sbmigWorkingDirectory,
|
|
16
|
+
presetsBackupDirectory: overrides?.presetsBackupDirectory,
|
|
17
|
+
storiesBackupDirectory: overrides?.storiesBackupDirectory,
|
|
18
|
+
componentsDirectories: overrides?.componentsDirectories,
|
|
19
|
+
flushCache: overrides?.flushCache,
|
|
20
|
+
cacheDir: overrides?.cacheDir,
|
|
21
|
+
debug: overrides?.debug,
|
|
22
|
+
rateLimit: overrides?.rateLimit,
|
|
23
|
+
openaiToken: overrides?.openaiToken,
|
|
24
|
+
boilerplateSpaceId: overrides?.boilerplateSpaceId,
|
|
25
|
+
schemaType: overrides?.schemaType,
|
|
26
|
+
awsBucketData: overrides?.awsBucketData,
|
|
27
|
+
metadataSelection: overrides?.metadataSelection,
|
|
28
|
+
contentHubOriginUrl: overrides?.contentHubOriginUrl,
|
|
29
|
+
contentHubAuthorizationToken: overrides?.contentHubAuthorizationToken,
|
|
30
|
+
resolvers: overrides?.resolvers,
|
|
31
|
+
advancedResolvers: overrides?.advancedResolvers,
|
|
32
|
+
storyblokComponentsLocalDirectory: overrides?.storyblokComponentsLocalDirectory,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ApiClient } from "../client.js";
|
|
2
|
+
export declare function getAllRoles(client: ApiClient): Promise<any>;
|
|
3
|
+
export declare function getRole(client: ApiClient, roleName: string): Promise<any>;
|
|
4
|
+
export declare function createRole(client: ApiClient, role: any): Promise<any>;
|
|
5
|
+
export declare function updateRole(client: ApiClient, role: any): Promise<any>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getAllItemsWithPagination } from "../../api/utils/request.js";
|
|
2
|
+
export async function getAllRoles(client) {
|
|
3
|
+
const spaceId = client.spaceId;
|
|
4
|
+
return getAllItemsWithPagination({
|
|
5
|
+
apiFn: ({ per_page, page }) => client.sbApi.get(`spaces/${spaceId}/space_roles/`, {
|
|
6
|
+
per_page,
|
|
7
|
+
page,
|
|
8
|
+
}),
|
|
9
|
+
params: {
|
|
10
|
+
spaceId,
|
|
11
|
+
},
|
|
12
|
+
itemsKey: "space_roles",
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export async function getRole(client, roleName) {
|
|
16
|
+
const roles = await getAllRoles(client);
|
|
17
|
+
const match = roles.filter((r) => r.role === roleName);
|
|
18
|
+
if (Array.isArray(match) && match.length === 0)
|
|
19
|
+
return false;
|
|
20
|
+
return match;
|
|
21
|
+
}
|
|
22
|
+
export async function createRole(client, role) {
|
|
23
|
+
const spaceId = client.spaceId;
|
|
24
|
+
return client.sbApi
|
|
25
|
+
.post(`spaces/${spaceId}/space_roles/`, { space_role: role })
|
|
26
|
+
.then((res) => res.data);
|
|
27
|
+
}
|
|
28
|
+
export async function updateRole(client, role) {
|
|
29
|
+
const spaceId = client.spaceId;
|
|
30
|
+
return client.sbApi
|
|
31
|
+
.put(`spaces/${spaceId}/space_roles/${role.id}`, {
|
|
32
|
+
space_role: role,
|
|
33
|
+
})
|
|
34
|
+
.then((res) => res.data);
|
|
35
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ApiClient } from "../client.js";
|
|
2
|
+
export declare function getAllSpaces(client: ApiClient): Promise<any>;
|
|
3
|
+
export declare function getSpace(client: ApiClient, spaceId: string): Promise<any>;
|
|
4
|
+
export declare function updateSpace(client: ApiClient, args: {
|
|
5
|
+
spaceId: string;
|
|
6
|
+
params: Record<string, any>;
|
|
7
|
+
}): Promise<any>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getAllSpaces as apiGetAllSpaces, getSpace as apiGetSpace, updateSpace as apiUpdateSpace, } from "../../api/spaces/spaces.js";
|
|
2
|
+
import { toRequestConfig } from "../requestConfig.js";
|
|
3
|
+
export async function getAllSpaces(client) {
|
|
4
|
+
return await apiGetAllSpaces(toRequestConfig(client));
|
|
5
|
+
}
|
|
6
|
+
export async function getSpace(client, spaceId) {
|
|
7
|
+
return await apiGetSpace({ spaceId }, toRequestConfig(client));
|
|
8
|
+
}
|
|
9
|
+
export async function updateSpace(client, args) {
|
|
10
|
+
return await apiUpdateSpace(args, toRequestConfig(client));
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ApiClient } from "../client.js";
|
|
2
|
+
import type { CopyProgress, CopyResult, StoryTreeNode } from "./types.js";
|
|
3
|
+
import type { ExtendedISbStoriesParams } from "../../api/stories/stories.types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Get all stories from a space
|
|
6
|
+
*/
|
|
7
|
+
export declare function getAllStories(client: ApiClient, options?: ExtendedISbStoriesParams): Promise<any[]>;
|
|
8
|
+
/**
|
|
9
|
+
* Get a single story by ID
|
|
10
|
+
*/
|
|
11
|
+
export declare function getStoryById(client: ApiClient, storyId: number | string): Promise<any>;
|
|
12
|
+
/**
|
|
13
|
+
* Get a story by slug
|
|
14
|
+
*/
|
|
15
|
+
export declare function getStoryBySlug(client: ApiClient, slug: string): Promise<any>;
|
|
16
|
+
/**
|
|
17
|
+
* Create a story in a space
|
|
18
|
+
*/
|
|
19
|
+
export declare function createStory(client: ApiClient, content: any): Promise<any>;
|
|
20
|
+
/**
|
|
21
|
+
* Fetch all stories and build a tree structure
|
|
22
|
+
*/
|
|
23
|
+
export declare function fetchStories(client: ApiClient, options?: ExtendedISbStoriesParams): Promise<{
|
|
24
|
+
stories: any[];
|
|
25
|
+
tree: StoryTreeNode[];
|
|
26
|
+
total: number;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Copy stories from source space to target space
|
|
30
|
+
*/
|
|
31
|
+
export declare function copyStories(sourceClient: ApiClient, targetClient: ApiClient, options: {
|
|
32
|
+
storyIds: number[];
|
|
33
|
+
destinationParentId?: number | null;
|
|
34
|
+
}, onProgress?: (progress: CopyProgress) => void): Promise<CopyResult>;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { getAllStories as apiGetAllStories, getStoryById as apiGetStoryById, getStoryBySlug as apiGetStoryBySlug, createStory as apiCreateStory, } from "../../api/stories/stories.js";
|
|
2
|
+
import { toRequestConfig } from "../requestConfig.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a tree structure from flat story list
|
|
5
|
+
*/
|
|
6
|
+
function buildTree(stories) {
|
|
7
|
+
const storyMap = new Map();
|
|
8
|
+
// First pass: create all nodes
|
|
9
|
+
for (const storyData of stories) {
|
|
10
|
+
const story = storyData.story || storyData;
|
|
11
|
+
storyMap.set(story.id, {
|
|
12
|
+
id: story.id,
|
|
13
|
+
name: story.name,
|
|
14
|
+
slug: story.slug,
|
|
15
|
+
full_slug: story.full_slug,
|
|
16
|
+
is_folder: story.is_folder,
|
|
17
|
+
is_startpage: story.is_startpage,
|
|
18
|
+
parent_id: story.parent_id,
|
|
19
|
+
children: [],
|
|
20
|
+
story,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
// Second pass: build tree structure
|
|
24
|
+
const rootNodes = [];
|
|
25
|
+
for (const storyData of stories) {
|
|
26
|
+
const story = storyData.story || storyData;
|
|
27
|
+
const node = storyMap.get(story.id);
|
|
28
|
+
if (story.parent_id === null || story.parent_id === 0) {
|
|
29
|
+
rootNodes.push(node);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const parent = storyMap.get(story.parent_id);
|
|
33
|
+
if (parent) {
|
|
34
|
+
parent.children.push(node);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
rootNodes.push(node);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Sort children
|
|
42
|
+
const sortNodes = (nodes) => {
|
|
43
|
+
nodes.sort((a, b) => {
|
|
44
|
+
if (a.is_folder && !b.is_folder)
|
|
45
|
+
return -1;
|
|
46
|
+
if (!a.is_folder && b.is_folder)
|
|
47
|
+
return 1;
|
|
48
|
+
if (a.story.position !== b.story.position) {
|
|
49
|
+
return a.story.position - b.story.position;
|
|
50
|
+
}
|
|
51
|
+
return a.name.localeCompare(b.name);
|
|
52
|
+
});
|
|
53
|
+
for (const node of nodes) {
|
|
54
|
+
if (node.children.length > 0) {
|
|
55
|
+
sortNodes(node.children);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
sortNodes(rootNodes);
|
|
60
|
+
return rootNodes;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get all stories from a space
|
|
64
|
+
*/
|
|
65
|
+
export async function getAllStories(client, options) {
|
|
66
|
+
const config = toRequestConfig(client);
|
|
67
|
+
return await apiGetAllStories({ options }, config);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get a single story by ID
|
|
71
|
+
*/
|
|
72
|
+
export async function getStoryById(client, storyId) {
|
|
73
|
+
const config = toRequestConfig(client);
|
|
74
|
+
return await apiGetStoryById(String(storyId), config);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get a story by slug
|
|
78
|
+
*/
|
|
79
|
+
export async function getStoryBySlug(client, slug) {
|
|
80
|
+
const config = toRequestConfig(client);
|
|
81
|
+
return await apiGetStoryBySlug(slug, config);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a story in a space
|
|
85
|
+
*/
|
|
86
|
+
export async function createStory(client, content) {
|
|
87
|
+
const config = toRequestConfig(client);
|
|
88
|
+
return await apiCreateStory(content, config);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Fetch all stories and build a tree structure
|
|
92
|
+
*/
|
|
93
|
+
export async function fetchStories(client, options) {
|
|
94
|
+
const stories = await getAllStories(client, options);
|
|
95
|
+
const tree = buildTree(stories);
|
|
96
|
+
return {
|
|
97
|
+
stories,
|
|
98
|
+
tree,
|
|
99
|
+
total: stories.length,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Copy stories from source space to target space
|
|
104
|
+
*/
|
|
105
|
+
export async function copyStories(sourceClient, targetClient, options, onProgress) {
|
|
106
|
+
const errors = [];
|
|
107
|
+
let copiedCount = 0;
|
|
108
|
+
// Fetch all stories with their full content
|
|
109
|
+
const storiesToCopy = [];
|
|
110
|
+
for (let i = 0; i < options.storyIds.length; i++) {
|
|
111
|
+
const storyId = options.storyIds[i];
|
|
112
|
+
if (storyId === undefined)
|
|
113
|
+
continue;
|
|
114
|
+
onProgress?.({
|
|
115
|
+
current: i + 1,
|
|
116
|
+
total: options.storyIds.length,
|
|
117
|
+
currentStory: `Fetching story ${storyId}...`,
|
|
118
|
+
status: "copying",
|
|
119
|
+
});
|
|
120
|
+
try {
|
|
121
|
+
const storyData = await getStoryById(sourceClient, storyId);
|
|
122
|
+
storiesToCopy.push(storyData);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
126
|
+
errors.push(`Failed to fetch story ${storyId}: ${errorMsg}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Build tree from selected stories
|
|
130
|
+
const tree = buildTree(storiesToCopy);
|
|
131
|
+
// Recursive function to create stories maintaining hierarchy
|
|
132
|
+
const createInOrder = async (nodes, newParentId) => {
|
|
133
|
+
for (const node of nodes) {
|
|
134
|
+
onProgress?.({
|
|
135
|
+
current: copiedCount + 1,
|
|
136
|
+
total: storiesToCopy.length,
|
|
137
|
+
currentStory: node.name,
|
|
138
|
+
status: "copying",
|
|
139
|
+
});
|
|
140
|
+
try {
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
142
|
+
const { id, uuid, created_at, updated_at, ...storyData } = node.story;
|
|
143
|
+
const newStory = await createStory(targetClient, {
|
|
144
|
+
...storyData,
|
|
145
|
+
parent_id: newParentId,
|
|
146
|
+
});
|
|
147
|
+
copiedCount++;
|
|
148
|
+
// Recursively create children
|
|
149
|
+
if (node.children.length > 0) {
|
|
150
|
+
await createInOrder(node.children, newStory.story.id);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
155
|
+
errors.push(`Failed to create "${node.name}": ${errorMsg}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
// Start creating from root nodes
|
|
160
|
+
await createInOrder(tree, options.destinationParentId ?? null);
|
|
161
|
+
onProgress?.({
|
|
162
|
+
current: copiedCount,
|
|
163
|
+
total: storiesToCopy.length,
|
|
164
|
+
currentStory: "Complete",
|
|
165
|
+
status: errors.length > 0 ? "error" : "done",
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
success: errors.length === 0,
|
|
169
|
+
copiedCount,
|
|
170
|
+
errors,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface CopyProgress {
|
|
2
|
+
current: number;
|
|
3
|
+
total: number;
|
|
4
|
+
currentStory: string;
|
|
5
|
+
status: "pending" | "copying" | "done" | "error";
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CopyResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
copiedCount: number;
|
|
11
|
+
errors: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface StoryTreeNode {
|
|
14
|
+
id: number;
|
|
15
|
+
name: string;
|
|
16
|
+
slug: string;
|
|
17
|
+
full_slug: string;
|
|
18
|
+
is_folder: boolean;
|
|
19
|
+
is_startpage: boolean;
|
|
20
|
+
parent_id: number | null;
|
|
21
|
+
children: StoryTreeNode[];
|
|
22
|
+
story: any;
|
|
23
|
+
}
|
|
24
|
+
export interface FetchStoriesResult {
|
|
25
|
+
stories: any[];
|
|
26
|
+
tree: StoryTreeNode[];
|
|
27
|
+
total: number;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ApiClient } from "../client.js";
|
|
2
|
+
import type { SyncProgressCallback, SyncResult } from "./types.js";
|
|
3
|
+
export declare function syncComponents(client: ApiClient, args: {
|
|
4
|
+
components: any[];
|
|
5
|
+
presets?: boolean;
|
|
6
|
+
ssot?: boolean;
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
onProgress?: SyncProgressCallback;
|
|
9
|
+
}): Promise<SyncResult>;
|
|
10
|
+
export declare function syncDatasources(client: ApiClient, args: {
|
|
11
|
+
datasources: any[];
|
|
12
|
+
dryRun?: boolean;
|
|
13
|
+
}): Promise<SyncResult>;
|
|
14
|
+
export declare function syncRoles(client: ApiClient, args: {
|
|
15
|
+
roles: any[];
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
}): Promise<SyncResult>;
|
|
18
|
+
export declare function syncPlugins(client: ApiClient, args: {
|
|
19
|
+
plugins: {
|
|
20
|
+
name: string;
|
|
21
|
+
body: string;
|
|
22
|
+
}[];
|
|
23
|
+
dryRun?: boolean;
|
|
24
|
+
}): Promise<SyncResult>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { syncComponentsData } from "../../api/components/components.sync.js";
|
|
2
|
+
import { syncDatasourcesData } from "../../api/datasources/datasources.js";
|
|
3
|
+
import { syncPluginsData } from "../../api/plugins/plugins.js";
|
|
4
|
+
import { syncRolesData } from "../../api/roles/roles.js";
|
|
5
|
+
import { toRequestConfig } from "../requestConfig.js";
|
|
6
|
+
export async function syncComponents(client, args) {
|
|
7
|
+
const presets = args.presets ?? false;
|
|
8
|
+
if (args.dryRun) {
|
|
9
|
+
// minimal dry-run: compare names against remote
|
|
10
|
+
const remote = await client.sbApi.get(`spaces/${client.spaceId}/components/`, {
|
|
11
|
+
per_page: 100,
|
|
12
|
+
page: 1,
|
|
13
|
+
});
|
|
14
|
+
const remoteNames = new Set(remote.data?.components?.map((c) => c.name) ?? []);
|
|
15
|
+
const created = [];
|
|
16
|
+
const updated = [];
|
|
17
|
+
const skipped = [];
|
|
18
|
+
for (const c of args.components) {
|
|
19
|
+
const name = String(c?.name ?? "unknown");
|
|
20
|
+
if (!c?.name) {
|
|
21
|
+
skipped.push(name);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (remoteNames.has(c.name))
|
|
25
|
+
updated.push(name);
|
|
26
|
+
else
|
|
27
|
+
created.push(name);
|
|
28
|
+
}
|
|
29
|
+
return { created, updated, skipped, errors: [] };
|
|
30
|
+
}
|
|
31
|
+
return (await syncComponentsData({
|
|
32
|
+
components: args.components,
|
|
33
|
+
presets,
|
|
34
|
+
ssot: args.ssot,
|
|
35
|
+
onProgress: args.onProgress,
|
|
36
|
+
}, toRequestConfig(client)));
|
|
37
|
+
}
|
|
38
|
+
export async function syncDatasources(client, args) {
|
|
39
|
+
if (args.dryRun) {
|
|
40
|
+
const remote = await client.sbApi.get(`spaces/${client.spaceId}/datasources/`);
|
|
41
|
+
const remoteNames = new Set(remote.data?.datasources?.map((d) => d.name) ?? []);
|
|
42
|
+
const created = [];
|
|
43
|
+
const updated = [];
|
|
44
|
+
const skipped = [];
|
|
45
|
+
for (const d of args.datasources) {
|
|
46
|
+
const name = String(d?.name ?? "unknown");
|
|
47
|
+
if (!d?.name) {
|
|
48
|
+
skipped.push(name);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (remoteNames.has(d.name))
|
|
52
|
+
updated.push(name);
|
|
53
|
+
else
|
|
54
|
+
created.push(name);
|
|
55
|
+
}
|
|
56
|
+
return { created, updated, skipped, errors: [] };
|
|
57
|
+
}
|
|
58
|
+
return (await syncDatasourcesData({ datasources: args.datasources }, toRequestConfig(client)));
|
|
59
|
+
}
|
|
60
|
+
export async function syncRoles(client, args) {
|
|
61
|
+
if (args.dryRun) {
|
|
62
|
+
const remote = await client.sbApi.get(`spaces/${client.spaceId}/space_roles/`, {
|
|
63
|
+
per_page: 100,
|
|
64
|
+
page: 1,
|
|
65
|
+
});
|
|
66
|
+
const remoteNames = new Set(remote.data?.space_roles?.map((r) => r.role) ?? []);
|
|
67
|
+
const created = [];
|
|
68
|
+
const updated = [];
|
|
69
|
+
const skipped = [];
|
|
70
|
+
for (const r of args.roles) {
|
|
71
|
+
const name = String(r?.role ?? "unknown");
|
|
72
|
+
if (!r?.role) {
|
|
73
|
+
skipped.push(name);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (remoteNames.has(r.role))
|
|
77
|
+
updated.push(name);
|
|
78
|
+
else
|
|
79
|
+
created.push(name);
|
|
80
|
+
}
|
|
81
|
+
return { created, updated, skipped, errors: [] };
|
|
82
|
+
}
|
|
83
|
+
return (await syncRolesData({ roles: args.roles }, toRequestConfig(client)));
|
|
84
|
+
}
|
|
85
|
+
export async function syncPlugins(client, args) {
|
|
86
|
+
if (args.dryRun) {
|
|
87
|
+
const remote = await client.sbApi.get("field_types", {
|
|
88
|
+
per_page: 100,
|
|
89
|
+
page: 1,
|
|
90
|
+
});
|
|
91
|
+
const remoteNames = new Set(remote.data?.field_types?.map((p) => p.name) ?? []);
|
|
92
|
+
const created = [];
|
|
93
|
+
const updated = [];
|
|
94
|
+
const skipped = [];
|
|
95
|
+
for (const p of args.plugins) {
|
|
96
|
+
const name = String(p?.name ?? "unknown");
|
|
97
|
+
if (!p?.name) {
|
|
98
|
+
skipped.push(name);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (remoteNames.has(p.name))
|
|
102
|
+
updated.push(name);
|
|
103
|
+
else
|
|
104
|
+
created.push(name);
|
|
105
|
+
}
|
|
106
|
+
return { created, updated, skipped, errors: [] };
|
|
107
|
+
}
|
|
108
|
+
return (await syncPluginsData({ plugins: args.plugins }, toRequestConfig(client)));
|
|
109
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { SyncError, SyncResult, SyncProgressEvent, SyncProgressCallback, } from "../../api/sync/sync.types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple test function with no dependencies to verify ESM/CJS interop
|
|
3
|
+
*/
|
|
4
|
+
export declare function testConnection(): {
|
|
5
|
+
success: boolean;
|
|
6
|
+
message: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Async test function to verify async imports work
|
|
11
|
+
*/
|
|
12
|
+
export declare function testAsyncConnection(): Promise<{
|
|
13
|
+
success: boolean;
|
|
14
|
+
message: string;
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple test function with no dependencies to verify ESM/CJS interop
|
|
3
|
+
*/
|
|
4
|
+
export function testConnection() {
|
|
5
|
+
return {
|
|
6
|
+
success: true,
|
|
7
|
+
message: "sb-mig api-v2 connection successful!",
|
|
8
|
+
timestamp: new Date().toISOString(),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Async test function to verify async imports work
|
|
13
|
+
*/
|
|
14
|
+
export async function testAsyncConnection() {
|
|
15
|
+
// Simulate a small delay
|
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
17
|
+
return {
|
|
18
|
+
success: true,
|
|
19
|
+
message: "sb-mig api-v2 async connection successful!",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { managementApi } from "../../api/managementApi.js";
|
|
2
2
|
import { backupStories } from "../../api/stories/backup.js";
|
|
3
3
|
import storyblokConfig from "../../config/config.js";
|
|
4
|
-
import { createAndSaveToFile } from "../../utils/files.js";
|
|
4
|
+
import { createAndSaveToFile, getPackageJson } from "../../utils/files.js";
|
|
5
5
|
import Logger from "../../utils/logger.js";
|
|
6
|
-
import { extractFields
|
|
6
|
+
import { extractFields } from "../../utils/object-utils.js";
|
|
7
7
|
import { apiConfig } from "../api-config.js";
|
|
8
|
+
import { isItFactory, unpackOne } from "../utils/cli-utils.js";
|
|
8
9
|
const BACKUP_COMMANDS = {
|
|
9
10
|
components: "components",
|
|
10
11
|
stories: "stories",
|
|
@@ -276,7 +277,10 @@ export const backup = async (props) => {
|
|
|
276
277
|
filename: `${component.name}.presets.sb`,
|
|
277
278
|
res: { allPresets: res, ...metadata },
|
|
278
279
|
folder: storyblokConfig.presetsBackupDirectory,
|
|
279
|
-
}, {
|
|
280
|
+
}, {
|
|
281
|
+
...apiConfig,
|
|
282
|
+
sbmigWorkingDirectory: ".",
|
|
283
|
+
});
|
|
280
284
|
}
|
|
281
285
|
})
|
|
282
286
|
.catch((err) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { managementApi } from "../../api/managementApi.js";
|
|
2
2
|
import { createTree, traverseAndCreate } from "../../api/stories/tree.js";
|
|
3
3
|
import Logger from "../../utils/logger.js";
|
|
4
|
-
import { getSourceSpace, getTargetSpace, getWhat, getWhere, } from "../../utils/others.js";
|
|
5
4
|
import { apiConfig } from "../api-config.js";
|
|
5
|
+
import { getSourceSpace, getTargetSpace, getWhat, getWhere, } from "../utils/cli-utils.js";
|
|
6
6
|
const COPY_COMMANDS = {
|
|
7
7
|
stories: "stories",
|
|
8
8
|
};
|
|
@@ -19,7 +19,7 @@ const decideStrategy = async (args) => {
|
|
|
19
19
|
const { what, sourceSpace } = args;
|
|
20
20
|
// Check if path ends with /* for recursive folder strategy
|
|
21
21
|
if (what.endsWith("/*")) {
|
|
22
|
-
const folderPath = what.slice(0, -2); // Remove /* from the
|
|
22
|
+
const folderPath = what.slice(0, -2); // Remove /* from the endcurso
|
|
23
23
|
const entryStory = await managementApi.stories.getStoryBySlug(folderPath, {
|
|
24
24
|
...apiConfig,
|
|
25
25
|
spaceId: sourceSpace,
|
|
@@ -3,10 +3,9 @@ import { managementApi } from "../../api/managementApi.js";
|
|
|
3
3
|
import { backupStories } from "../../api/stories/backup.js";
|
|
4
4
|
import { createAndSaveToFile } from "../../utils/files.js";
|
|
5
5
|
import Logger from "../../utils/logger.js";
|
|
6
|
-
import { isItFactory, unpackElements } from "../../utils/main.js";
|
|
7
|
-
import { getFrom, getTo } from "../../utils/others.js";
|
|
8
6
|
import { apiConfig } from "../api-config.js";
|
|
9
7
|
import { askForConfirmation } from "../helpers.js";
|
|
8
|
+
import { isItFactory, unpackElements, getFrom, getTo, } from "../utils/cli-utils.js";
|
|
10
9
|
const MIGRATE_COMMANDS = {
|
|
11
10
|
content: "content",
|
|
12
11
|
presets: "presets",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import { readFile } from "../../utils/files.js";
|
|
2
|
+
import { readFile, getFileContentWithRequire, getFilesContentWithRequire, } from "../../utils/files.js";
|
|
3
3
|
import Logger from "../../utils/logger.js";
|
|
4
|
-
import { getFileContentWithRequire, getFilesContentWithRequire, isItFactory, } from "../../utils/main.js";
|
|
5
4
|
import { preselectMigrations } from "../../utils/migrations.js";
|
|
5
|
+
import { isItFactory } from "../utils/cli-utils.js";
|
|
6
6
|
import { discoverVersionMapping, LOOKUP_TYPE, SCOPE, } from "../utils/discover.js";
|
|
7
7
|
const MIGRATIONS_COMMANDS = {
|
|
8
8
|
recognize: "recognize",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { managementApi } from "../../api/managementApi.js";
|
|
2
2
|
import { removeAllComponents, removeSpecifiedComponents, } from "../../api/migrate.js";
|
|
3
3
|
import Logger from "../../utils/logger.js";
|
|
4
|
-
import { unpackElements } from "../../utils/main.js";
|
|
5
4
|
import { apiConfig } from "../api-config.js";
|
|
5
|
+
import { unpackElements } from "../utils/cli-utils.js";
|
|
6
6
|
const REMOVE_COMMANDS = {
|
|
7
7
|
story: "story",
|
|
8
8
|
components: "components",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { managementApi } from "../../api/managementApi.js";
|
|
2
|
+
import { getFilesContentWithRequire } from "../../utils/files.js";
|
|
2
3
|
import Logger from "../../utils/logger.js";
|
|
3
|
-
import { getFilesContentWithRequire, isItFactory } from "../../utils/main.js";
|
|
4
|
-
import { getFrom, getTo } from "../../utils/others.js";
|
|
5
4
|
import { apiConfig } from "../api-config.js";
|
|
6
5
|
import { askForConfirmation } from "../helpers.js";
|
|
6
|
+
import { isItFactory, getFrom, getTo } from "../utils/cli-utils.js";
|
|
7
7
|
import { discoverStories, LOOKUP_TYPE, SCOPE } from "../utils/discover.js";
|
|
8
8
|
const REVERT_COMMANDS = {
|
|
9
9
|
content: "content",
|