sb-mig 5.6.0-beta.1 → 5.6.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/README.md +20 -19
- package/dist/api/assets/assets.js +2 -15
- package/dist/api/auth/auth.types.d.ts +1 -1
- 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 +47 -0
- package/dist/api-v2/discover/discover.js +328 -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 +53 -100
- 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 +368 -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 +43 -27
- package/dist/utils/pkg-require.d.ts +0 -2
- package/dist/utils/pkg-require.js +0 -4
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { mkdir, rm } from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { rollup } from "rollup";
|
|
4
|
+
import ts from "rollup-plugin-ts";
|
|
5
|
+
/**
|
|
6
|
+
* Extract the component name from a file path
|
|
7
|
+
* e.g., "/path/to/my-component.sb.ts" -> "my-component.sb"
|
|
8
|
+
*/
|
|
9
|
+
export const extractComponentName = (filePath) => {
|
|
10
|
+
const separator = "/";
|
|
11
|
+
const parts = filePath.split(separator);
|
|
12
|
+
const lastElement = parts[parts.length - 1];
|
|
13
|
+
return lastElement.replace(/\.ts$/, "");
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Build a single file using Rollup
|
|
17
|
+
*/
|
|
18
|
+
async function buildFile(inputPath, outputCjs, outputEsm) {
|
|
19
|
+
const inputOptions = {
|
|
20
|
+
input: inputPath,
|
|
21
|
+
plugins: [
|
|
22
|
+
ts({
|
|
23
|
+
transpileOnly: true,
|
|
24
|
+
transpiler: "swc",
|
|
25
|
+
}),
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
const outputOptionsList = [
|
|
29
|
+
{ file: outputCjs, format: "cjs" },
|
|
30
|
+
{ file: outputEsm, format: "es" },
|
|
31
|
+
];
|
|
32
|
+
let bundle;
|
|
33
|
+
try {
|
|
34
|
+
bundle = await rollup(inputOptions);
|
|
35
|
+
for (const outputOptions of outputOptionsList) {
|
|
36
|
+
await bundle.write(outputOptions);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
if (bundle) {
|
|
41
|
+
await bundle.close();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Precompile TypeScript schema files to JavaScript
|
|
47
|
+
*
|
|
48
|
+
* This uses Rollup with SWC for fast transpilation, producing
|
|
49
|
+
* both CommonJS (.cjs) and ESM (.js) outputs.
|
|
50
|
+
*
|
|
51
|
+
* @param files - Array of TypeScript file paths to compile
|
|
52
|
+
* @param options - Precompile options
|
|
53
|
+
* @returns Result with compiled files and any errors
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const result = await precompile([
|
|
58
|
+
* '/path/to/hero.sb.ts',
|
|
59
|
+
* '/path/to/card.sb.ts',
|
|
60
|
+
* ], { cacheDir: '.cache/sb-mig' });
|
|
61
|
+
*
|
|
62
|
+
* // Use compiled CJS files
|
|
63
|
+
* for (const compiled of result.compiled) {
|
|
64
|
+
* const content = require(compiled.outputCjs);
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export async function precompile(files, options = {}) {
|
|
69
|
+
const { cacheDir = ".sb-mig-cache", flushCache = true, projectDir = process.cwd(), } = options;
|
|
70
|
+
const fullCacheDir = path.join(projectDir, cacheDir, "sb-mig");
|
|
71
|
+
// Optionally clear cache
|
|
72
|
+
if (flushCache) {
|
|
73
|
+
try {
|
|
74
|
+
await rm(fullCacheDir, { recursive: true, force: true });
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Ignore if doesn't exist
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Ensure cache directory exists
|
|
81
|
+
await mkdir(fullCacheDir, { recursive: true });
|
|
82
|
+
const result = {
|
|
83
|
+
compiled: [],
|
|
84
|
+
errors: [],
|
|
85
|
+
};
|
|
86
|
+
// Filter to only TypeScript files
|
|
87
|
+
const tsFiles = files.filter((f) => f.endsWith(".ts"));
|
|
88
|
+
if (tsFiles.length === 0) {
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
// Compile all files in parallel
|
|
92
|
+
await Promise.all(tsFiles.map(async (inputPath) => {
|
|
93
|
+
const componentName = extractComponentName(inputPath);
|
|
94
|
+
const outputCjs = path.join(fullCacheDir, `${componentName}.cjs`);
|
|
95
|
+
const outputEsm = path.join(fullCacheDir, `${componentName}.js`);
|
|
96
|
+
try {
|
|
97
|
+
await buildFile(inputPath, outputCjs, outputEsm);
|
|
98
|
+
result.compiled.push({
|
|
99
|
+
input: inputPath,
|
|
100
|
+
outputCjs,
|
|
101
|
+
outputEsm,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
result.errors.push({
|
|
106
|
+
input: inputPath,
|
|
107
|
+
error: error instanceof Error ? error.message : String(error),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}));
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get the compiled file path for a TypeScript source file
|
|
115
|
+
*
|
|
116
|
+
* @param tsFilePath - Original .ts file path
|
|
117
|
+
* @param options - Options with cacheDir and projectDir
|
|
118
|
+
* @param format - Output format ('cjs' or 'esm')
|
|
119
|
+
* @returns Path to the compiled file
|
|
120
|
+
*/
|
|
121
|
+
export function getCompiledPath(tsFilePath, options = {}, format = "cjs") {
|
|
122
|
+
const { cacheDir = ".sb-mig-cache", projectDir = process.cwd() } = options;
|
|
123
|
+
const fullCacheDir = path.join(projectDir, cacheDir, "sb-mig");
|
|
124
|
+
const componentName = extractComponentName(tsFilePath);
|
|
125
|
+
const ext = format === "cjs" ? ".cjs" : ".js";
|
|
126
|
+
return path.join(fullCacheDir, `${componentName}${ext}`);
|
|
127
|
+
}
|
|
@@ -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
|
+
}>;
|