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.
Files changed (172) hide show
  1. package/README.md +20 -19
  2. package/dist/api/assets/assets.js +1 -14
  3. package/dist/api/components/components.js +2 -1
  4. package/dist/api/components/components.sync.d.ts +8 -0
  5. package/dist/api/components/components.sync.js +193 -0
  6. package/dist/api/data-migration/component-data-migration.js +2 -2
  7. package/dist/api/datasources/datasource-entries.js +4 -5
  8. package/dist/api/datasources/datasources.d.ts +5 -2
  9. package/dist/api/datasources/datasources.js +42 -35
  10. package/dist/api/datasources/datasources.sync.d.ts +2 -0
  11. package/dist/api/datasources/datasources.sync.js +11 -0
  12. package/dist/api/datasources/datasources.types.d.ts +1 -1
  13. package/dist/api/datasources/index.d.ts +2 -1
  14. package/dist/api/datasources/index.js +2 -1
  15. package/dist/api/managementApi.d.ts +2 -2
  16. package/dist/api/migrate.d.ts +1 -1
  17. package/dist/api/migrate.js +3 -48
  18. package/dist/api/plugins/index.d.ts +2 -1
  19. package/dist/api/plugins/index.js +2 -1
  20. package/dist/api/plugins/plugins.d.ts +7 -2
  21. package/dist/api/plugins/plugins.js +28 -15
  22. package/dist/api/plugins/plugins.sync.d.ts +2 -0
  23. package/dist/api/plugins/plugins.sync.js +11 -0
  24. package/dist/api/roles/index.d.ts +2 -1
  25. package/dist/api/roles/index.js +2 -1
  26. package/dist/api/roles/roles.d.ts +5 -2
  27. package/dist/api/roles/roles.js +34 -11
  28. package/dist/api/roles/roles.sync.d.ts +2 -0
  29. package/dist/api/roles/roles.sync.js +6 -0
  30. package/dist/api/roles/roles.types.d.ts +1 -1
  31. package/dist/api/stories/stories.js +3 -11
  32. package/dist/api/sync/sync.types.d.ts +30 -0
  33. package/dist/api/sync/sync.types.js +1 -0
  34. package/dist/api/testApi.d.ts +2 -2
  35. package/dist/api/utils/helper-functions.d.ts +5 -1
  36. package/dist/api/utils/helper-functions.js +6 -1
  37. package/dist/api/utils/request.d.ts +1 -1
  38. package/dist/api/utils/request.js +11 -2
  39. package/dist/api/utils/resolverTransformations.js +2 -57
  40. package/dist/api-v2/assets/index.d.ts +13 -0
  41. package/dist/api-v2/assets/index.js +25 -0
  42. package/dist/api-v2/auth/index.d.ts +3 -0
  43. package/dist/api-v2/auth/index.js +8 -0
  44. package/dist/api-v2/client.d.ts +13 -0
  45. package/dist/api-v2/client.js +17 -0
  46. package/dist/api-v2/components/index.d.ts +10 -0
  47. package/dist/api-v2/components/index.js +29 -0
  48. package/dist/api-v2/datasources/index.d.ts +8 -0
  49. package/dist/api-v2/datasources/index.js +58 -0
  50. package/dist/api-v2/discover/discover.d.ts +36 -0
  51. package/dist/api-v2/discover/discover.js +281 -0
  52. package/dist/api-v2/discover/index.d.ts +2 -0
  53. package/dist/api-v2/discover/index.js +1 -0
  54. package/dist/api-v2/index.d.ts +19 -0
  55. package/dist/api-v2/index.js +21 -0
  56. package/dist/api-v2/plugins/index.d.ts +9 -0
  57. package/dist/api-v2/plugins/index.js +42 -0
  58. package/dist/api-v2/precompile/index.d.ts +2 -0
  59. package/dist/api-v2/precompile/index.js +1 -0
  60. package/dist/api-v2/precompile/precompile.d.ts +65 -0
  61. package/dist/api-v2/precompile/precompile.js +127 -0
  62. package/dist/api-v2/presets/index.d.ts +13 -0
  63. package/dist/api-v2/presets/index.js +25 -0
  64. package/dist/api-v2/requestConfig.d.ts +5 -0
  65. package/dist/api-v2/requestConfig.js +34 -0
  66. package/dist/api-v2/roles/index.d.ts +5 -0
  67. package/dist/api-v2/roles/index.js +35 -0
  68. package/dist/api-v2/spaces/index.d.ts +7 -0
  69. package/dist/api-v2/spaces/index.js +11 -0
  70. package/dist/api-v2/stories/index.d.ts +34 -0
  71. package/dist/api-v2/stories/index.js +172 -0
  72. package/dist/api-v2/stories/types.d.ts +28 -0
  73. package/dist/api-v2/stories/types.js +1 -0
  74. package/dist/api-v2/sync/index.d.ts +24 -0
  75. package/dist/api-v2/sync/index.js +109 -0
  76. package/dist/api-v2/sync/types.d.ts +1 -0
  77. package/dist/api-v2/sync/types.js +1 -0
  78. package/dist/api-v2/test.d.ts +15 -0
  79. package/dist/api-v2/test.js +21 -0
  80. package/dist/cli/commands/backup.js +7 -3
  81. package/dist/cli/commands/copy.js +2 -2
  82. package/dist/cli/commands/migrate.js +1 -2
  83. package/dist/cli/commands/migrations.js +2 -2
  84. package/dist/cli/commands/remove.js +1 -1
  85. package/dist/cli/commands/revert.js +2 -2
  86. package/dist/cli/commands/sync.js +1 -2
  87. package/dist/cli/index.js +1 -1
  88. package/dist/cli/utils/cli-utils.d.ts +69 -0
  89. package/dist/cli/utils/cli-utils.js +100 -0
  90. package/dist/cli/utils/discover.d.ts +3 -22
  91. package/dist/cli/utils/discover.js +4 -51
  92. package/dist/config/config.d.ts +2 -39
  93. package/dist/config/config.types.d.ts +40 -0
  94. package/dist/config/config.types.js +1 -0
  95. package/dist/config/defaultConfig.d.ts +1 -1
  96. package/dist/config/defaultConfig.js +2 -2
  97. package/dist/utils/array-utils.d.ts +20 -0
  98. package/dist/utils/array-utils.js +20 -0
  99. package/dist/utils/async-utils.d.ts +13 -0
  100. package/dist/utils/async-utils.js +13 -0
  101. package/dist/utils/date-utils.d.ts +14 -0
  102. package/dist/utils/date-utils.js +21 -0
  103. package/dist/utils/files.d.ts +35 -0
  104. package/dist/utils/files.js +57 -2
  105. package/dist/utils/main.d.ts +8 -18
  106. package/dist/utils/main.js +12 -104
  107. package/dist/utils/migrations.d.ts +9 -3
  108. package/dist/utils/object-utils.d.ts +46 -0
  109. package/dist/utils/object-utils.js +71 -0
  110. package/dist/utils/others.d.ts +6 -9
  111. package/dist/utils/others.js +8 -15
  112. package/dist/utils/path-utils.d.ts +89 -0
  113. package/dist/utils/path-utils.js +106 -0
  114. package/dist/utils/pkg.d.ts +16 -2
  115. package/dist/utils/pkg.js +16 -3
  116. package/dist/utils/string-utils.d.ts +33 -0
  117. package/dist/utils/string-utils.js +45 -0
  118. package/dist/utils/transform-utils.d.ts +62 -0
  119. package/dist/utils/transform-utils.js +113 -0
  120. package/dist-cjs/api/auth/auth.js +28 -0
  121. package/dist-cjs/api/auth/auth.types.js +2 -0
  122. package/dist-cjs/api/components/components.js +202 -0
  123. package/dist-cjs/api/components/components.sync.js +199 -0
  124. package/dist-cjs/api/components/components.types.js +2 -0
  125. package/dist-cjs/api/datasources/datasource-entries.js +166 -0
  126. package/dist-cjs/api/datasources/datasources.js +166 -0
  127. package/dist-cjs/api/datasources/datasources.types.js +2 -0
  128. package/dist-cjs/api/plugins/plugins.js +132 -0
  129. package/dist-cjs/api/plugins/plugins.types.js +2 -0
  130. package/dist-cjs/api/presets/componentPresets.js +25 -0
  131. package/dist-cjs/api/presets/presets.js +92 -0
  132. package/dist-cjs/api/presets/presets.types.js +2 -0
  133. package/dist-cjs/api/presets/resolvePresets.js +49 -0
  134. package/dist-cjs/api/roles/roles.js +131 -0
  135. package/dist-cjs/api/roles/roles.types.js +2 -0
  136. package/dist-cjs/api/spaces/spaces.js +34 -0
  137. package/dist-cjs/api/spaces/spaces.types.js +2 -0
  138. package/dist-cjs/api/stories/stories.js +214 -0
  139. package/dist-cjs/api/stories/stories.types.js +2 -0
  140. package/dist-cjs/api/sync/sync.types.js +2 -0
  141. package/dist-cjs/api/utils/request.js +48 -0
  142. package/dist-cjs/api/utils/resolvers.types.js +2 -0
  143. package/dist-cjs/api-v2/assets/index.js +30 -0
  144. package/dist-cjs/api-v2/auth/index.js +12 -0
  145. package/dist-cjs/api-v2/client.js +23 -0
  146. package/dist-cjs/api-v2/components/index.js +40 -0
  147. package/dist-cjs/api-v2/datasources/index.js +64 -0
  148. package/dist-cjs/api-v2/discover/discover.js +321 -0
  149. package/dist-cjs/api-v2/discover/index.js +9 -0
  150. package/dist-cjs/api-v2/index.js +60 -0
  151. package/dist-cjs/api-v2/plugins/index.js +49 -0
  152. package/dist-cjs/api-v2/precompile/index.js +7 -0
  153. package/dist-cjs/api-v2/precompile/precompile.js +136 -0
  154. package/dist-cjs/api-v2/presets/index.js +33 -0
  155. package/dist-cjs/api-v2/requestConfig.js +37 -0
  156. package/dist-cjs/api-v2/roles/index.js +41 -0
  157. package/dist-cjs/api-v2/spaces/index.js +16 -0
  158. package/dist-cjs/api-v2/stories/index.js +180 -0
  159. package/dist-cjs/api-v2/stories/types.js +2 -0
  160. package/dist-cjs/api-v2/sync/index.js +115 -0
  161. package/dist-cjs/api-v2/sync/types.js +2 -0
  162. package/dist-cjs/api-v2/test.js +25 -0
  163. package/dist-cjs/config/config.types.js +2 -0
  164. package/dist-cjs/config/constants.js +29 -0
  165. package/dist-cjs/package.json +3 -0
  166. package/dist-cjs/utils/array-utils.js +24 -0
  167. package/dist-cjs/utils/logger.js +32 -0
  168. package/dist-cjs/utils/object-utils.js +77 -0
  169. package/dist-cjs/utils/path-utils.js +115 -0
  170. package/package.json +37 -20
  171. package/dist/utils/pkg-require.d.ts +0 -2
  172. 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, getPackageJson, isItFactory, unpackOne, } from "../../utils/main.js";
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
- }, { ...apiConfig, sbmigWorkingDirectory: "." });
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 end
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",