sb-mig 5.5.4-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.d.ts +6 -2
- package/dist/api/data-migration/component-data-migration.js +35 -11
- 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 +5 -13
- 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/cli-descriptions.d.ts +1 -1
- package/dist/cli/cli-descriptions.js +4 -0
- package/dist/cli/commands/backup.js +7 -3
- package/dist/cli/commands/copy.js +2 -2
- package/dist/cli/commands/migrate.js +13 -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 +8 -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,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path and glob pattern utilities for file discovery
|
|
3
|
+
*/
|
|
4
|
+
import path from "path";
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes an array of directory segments for glob pattern usage.
|
|
7
|
+
* Handles the glob.sync quirk where single segments don't need braces,
|
|
8
|
+
* but multiple segments need {segment1,segment2} format.
|
|
9
|
+
*
|
|
10
|
+
* @param segments - Array of directory path segments
|
|
11
|
+
* @returns Normalized string for glob pattern
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* normalizeDiscover({ segments: [] }) // => ""
|
|
15
|
+
* normalizeDiscover({ segments: ["src"] }) // => "src"
|
|
16
|
+
* normalizeDiscover({ segments: ["src", "lib"] }) // => "{src,lib}"
|
|
17
|
+
*/
|
|
18
|
+
export const normalizeDiscover = ({ segments, }) => {
|
|
19
|
+
if (segments.length === 0) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
if (segments.length === 1) {
|
|
23
|
+
return segments[0];
|
|
24
|
+
}
|
|
25
|
+
return `{${segments.join(",")}}`;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Builds a glob file pattern for discovering files with a specific extension.
|
|
29
|
+
* Automatically handles single vs multiple directory paths.
|
|
30
|
+
*
|
|
31
|
+
* @param mainDirectory - The root directory to search from
|
|
32
|
+
* @param componentDirectories - Array of subdirectories to search in
|
|
33
|
+
* @param ext - File extension to match (without leading dot)
|
|
34
|
+
* @returns A glob pattern string
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* filesPattern({
|
|
38
|
+
* mainDirectory: "/project",
|
|
39
|
+
* componentDirectories: ["src"],
|
|
40
|
+
* ext: "sb.js"
|
|
41
|
+
* })
|
|
42
|
+
* // => "/project/src/**\/[^_]*.sb.js"
|
|
43
|
+
*
|
|
44
|
+
* filesPattern({
|
|
45
|
+
* mainDirectory: "/project",
|
|
46
|
+
* componentDirectories: ["src", "lib"],
|
|
47
|
+
* ext: "sb.js"
|
|
48
|
+
* })
|
|
49
|
+
* // => "/project/{src,lib}/**\/[^_]*.sb.js"
|
|
50
|
+
*/
|
|
51
|
+
export const filesPattern = ({ mainDirectory, componentDirectories, ext, }) => {
|
|
52
|
+
return componentDirectories.length === 1
|
|
53
|
+
? path.join(`${mainDirectory}`, `${componentDirectories[0]}`, "**", `[^_]*.${ext}`)
|
|
54
|
+
: path.join(`${mainDirectory}`, `{${componentDirectories.join(",")}}`, "**", `[^_]*.${ext}`);
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Compares local and external file path arrays.
|
|
58
|
+
* Splits paths to extract file names, filters out duplicates from external
|
|
59
|
+
* (preferring local files), and filters out nested node_modules.
|
|
60
|
+
*
|
|
61
|
+
* @param request - Object containing local and external path arrays
|
|
62
|
+
* @returns CompareResult with processed local and external file elements
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* compare({
|
|
66
|
+
* local: ["/project/src/hero.sb.js"],
|
|
67
|
+
* external: ["/project/node_modules/pkg/hero.sb.js", "/project/node_modules/pkg/card.sb.js"]
|
|
68
|
+
* })
|
|
69
|
+
* // => {
|
|
70
|
+
* // local: [{ name: "hero.sb.js", p: "/project/src/hero.sb.js" }],
|
|
71
|
+
* // external: [{ name: "card.sb.js", p: "/project/node_modules/pkg/card.sb.js" }]
|
|
72
|
+
* // }
|
|
73
|
+
*/
|
|
74
|
+
export const compare = (request) => {
|
|
75
|
+
const { local, external } = request;
|
|
76
|
+
const splittedLocal = local.map((p) => {
|
|
77
|
+
return {
|
|
78
|
+
name: p.split(path.sep)[p.split(path.sep).length - 1], // last element of split array - file name
|
|
79
|
+
p,
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
const splittedExternal = external
|
|
83
|
+
.map((p) => {
|
|
84
|
+
return {
|
|
85
|
+
name: p.split(path.sep)[p.split(path.sep).length - 1], // last element of split array - file name
|
|
86
|
+
p,
|
|
87
|
+
};
|
|
88
|
+
})
|
|
89
|
+
.filter((file) => {
|
|
90
|
+
// Filter out files from nested node_modules (node_modules within node_modules)
|
|
91
|
+
const nodeModulesCount = (file.p.match(/node_modules/g) || [])
|
|
92
|
+
.length;
|
|
93
|
+
return nodeModulesCount <= 1;
|
|
94
|
+
});
|
|
95
|
+
// Filter external array to remove items that exist locally (local takes priority)
|
|
96
|
+
const result = {
|
|
97
|
+
local: splittedLocal,
|
|
98
|
+
external: splittedExternal.filter((externalComponent) => {
|
|
99
|
+
if (splittedLocal.find((localComponent) => externalComponent.name === localComponent.name)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
}),
|
|
104
|
+
};
|
|
105
|
+
return result;
|
|
106
|
+
};
|
package/dist/utils/pkg.d.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Package loading utilities
|
|
3
|
+
* ESM-compatible require wrapper for loading JSON/JS files dynamically
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Load a package/module from the given path using require
|
|
7
|
+
* Works in ESM context by using createRequire
|
|
8
|
+
*
|
|
9
|
+
* @param path - Path to the package/module to load
|
|
10
|
+
* @returns The loaded module content
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const packageJson = pkg('./package.json');
|
|
14
|
+
* const config = pkg('some-config-file');
|
|
15
|
+
*/
|
|
16
|
+
export declare const pkg: (path: string) => any;
|
package/dist/utils/pkg.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package loading utilities
|
|
3
|
+
* ESM-compatible require wrapper for loading JSON/JS files dynamically
|
|
4
|
+
*/
|
|
1
5
|
import { createRequire } from "module";
|
|
2
6
|
const require = createRequire(import.meta.url);
|
|
3
|
-
|
|
4
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Load a package/module from the given path using require
|
|
9
|
+
* Works in ESM context by using createRequire
|
|
10
|
+
*
|
|
11
|
+
* @param path - Path to the package/module to load
|
|
12
|
+
* @returns The loaded module content
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const packageJson = pkg('./package.json');
|
|
16
|
+
* const config = pkg('some-config-file');
|
|
17
|
+
*/
|
|
18
|
+
export const pkg = (path) => {
|
|
5
19
|
return require(path);
|
|
6
20
|
};
|
|
7
|
-
export { pkg };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String manipulation utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extracts the filename from a file URL or path.
|
|
6
|
+
* Returns the last segment after splitting by "/".
|
|
7
|
+
*
|
|
8
|
+
* @param fileUrl - The URL or path string to extract filename from
|
|
9
|
+
* @returns The extracted filename
|
|
10
|
+
* @throws Error if filename cannot be extracted (empty string or no segments)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* getFileName("https://example.com/assets/image.png") // => "image.png"
|
|
14
|
+
* getFileName("/path/to/file.txt") // => "file.txt"
|
|
15
|
+
* getFileName("simple.js") // => "simple.js"
|
|
16
|
+
*/
|
|
17
|
+
export declare const getFileName: (fileUrl: string) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Extracts the size segment from a Storyblok asset URL.
|
|
20
|
+
* Storyblok asset URLs have the format: .../size/hash/filename
|
|
21
|
+
* This function extracts the size segment (3 positions before the end).
|
|
22
|
+
*
|
|
23
|
+
* @param fileUrl - The Storyblok asset URL
|
|
24
|
+
* @returns The size segment from the URL
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* getSizeFromURL("https://a.storyblok.com/f/12345/1920x1080/abc123/image.png")
|
|
28
|
+
* // => "1920x1080"
|
|
29
|
+
*
|
|
30
|
+
* getSizeFromURL("https://a.storyblok.com/f/12345/100x100/xyz789/thumb.jpg")
|
|
31
|
+
* // => "100x100"
|
|
32
|
+
*/
|
|
33
|
+
export declare const getSizeFromURL: (fileUrl: string) => string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String manipulation utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extracts the filename from a file URL or path.
|
|
6
|
+
* Returns the last segment after splitting by "/".
|
|
7
|
+
*
|
|
8
|
+
* @param fileUrl - The URL or path string to extract filename from
|
|
9
|
+
* @returns The extracted filename
|
|
10
|
+
* @throws Error if filename cannot be extracted (empty string or no segments)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* getFileName("https://example.com/assets/image.png") // => "image.png"
|
|
14
|
+
* getFileName("/path/to/file.txt") // => "file.txt"
|
|
15
|
+
* getFileName("simple.js") // => "simple.js"
|
|
16
|
+
*/
|
|
17
|
+
export const getFileName = (fileUrl) => {
|
|
18
|
+
const fileName = fileUrl.split("/").pop();
|
|
19
|
+
if (fileName) {
|
|
20
|
+
return fileName;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw Error("File name couldn't be extracted from URL.");
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Extracts the size segment from a Storyblok asset URL.
|
|
28
|
+
* Storyblok asset URLs have the format: .../size/hash/filename
|
|
29
|
+
* This function extracts the size segment (3 positions before the end).
|
|
30
|
+
*
|
|
31
|
+
* @param fileUrl - The Storyblok asset URL
|
|
32
|
+
* @returns The size segment from the URL
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* getSizeFromURL("https://a.storyblok.com/f/12345/1920x1080/abc123/image.png")
|
|
36
|
+
* // => "1920x1080"
|
|
37
|
+
*
|
|
38
|
+
* getSizeFromURL("https://a.storyblok.com/f/12345/100x100/xyz789/thumb.jpg")
|
|
39
|
+
* // => "100x100"
|
|
40
|
+
*/
|
|
41
|
+
export const getSizeFromURL = (fileUrl) => {
|
|
42
|
+
const data = fileUrl.split("/");
|
|
43
|
+
const sizePos = data.length - 3;
|
|
44
|
+
return data[sizePos];
|
|
45
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object transformation utilities
|
|
3
|
+
* Pure functions for deep object manipulation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Recursively extend a field in a nested object
|
|
7
|
+
* If the field is an array, appends unique values
|
|
8
|
+
* If the field is an object, merges properties
|
|
9
|
+
*
|
|
10
|
+
* @param obj - The object to search and extend
|
|
11
|
+
* @param targetField - The field name to find and extend
|
|
12
|
+
* @param newValue - The value(s) to add
|
|
13
|
+
* @returns true if field was found and extended, false otherwise
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const obj = { schema: { items: ['a', 'b'] } };
|
|
17
|
+
* extendField(obj, 'items', ['c', 'd']);
|
|
18
|
+
* // obj.schema.items is now ['a', 'b', 'c', 'd']
|
|
19
|
+
*/
|
|
20
|
+
export declare const extendField: (obj: any, targetField: string, newValue: any) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Deep transform an object using a transformer specification
|
|
23
|
+
* Supports function transformers, nested object transformers, and literal values
|
|
24
|
+
*
|
|
25
|
+
* @param obj - The source object to transform
|
|
26
|
+
* @param transformers - Specification object where:
|
|
27
|
+
* - function values: called with current value, result used as new value
|
|
28
|
+
* - object values: recursively applied to nested objects
|
|
29
|
+
* - other values: used directly as the new value
|
|
30
|
+
* @returns New transformed object (original is not mutated)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const obj = { name: 'hero', count: 5 };
|
|
34
|
+
* const result = deepTransform(obj, {
|
|
35
|
+
* name: (v) => v.toUpperCase(),
|
|
36
|
+
* count: (v) => v * 2,
|
|
37
|
+
* });
|
|
38
|
+
* // result: { name: 'HERO', count: 10 }
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Nested transformation
|
|
42
|
+
* const obj = { schema: { title: 'old' } };
|
|
43
|
+
* const result = deepTransform(obj, {
|
|
44
|
+
* schema: { title: 'new' }
|
|
45
|
+
* });
|
|
46
|
+
* // result: { schema: { title: 'new' } }
|
|
47
|
+
*/
|
|
48
|
+
export declare function deepTransform(obj: any, transformers: any): any;
|
|
49
|
+
/**
|
|
50
|
+
* Check if a component has content available as bloks
|
|
51
|
+
*
|
|
52
|
+
* @param component - Storyblok component schema
|
|
53
|
+
* @returns true if component.schema.content is a bloks field with whitelist
|
|
54
|
+
*/
|
|
55
|
+
export declare const isContentAvailableAsBloks: (component: any) => boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Check if a component has items available as bloks
|
|
58
|
+
*
|
|
59
|
+
* @param component - Storyblok component schema
|
|
60
|
+
* @returns true if component.schema.items is a bloks field with whitelist
|
|
61
|
+
*/
|
|
62
|
+
export declare const isItemsAvailableAsBloks: (component: any) => boolean;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object transformation utilities
|
|
3
|
+
* Pure functions for deep object manipulation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Recursively extend a field in a nested object
|
|
7
|
+
* If the field is an array, appends unique values
|
|
8
|
+
* If the field is an object, merges properties
|
|
9
|
+
*
|
|
10
|
+
* @param obj - The object to search and extend
|
|
11
|
+
* @param targetField - The field name to find and extend
|
|
12
|
+
* @param newValue - The value(s) to add
|
|
13
|
+
* @returns true if field was found and extended, false otherwise
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const obj = { schema: { items: ['a', 'b'] } };
|
|
17
|
+
* extendField(obj, 'items', ['c', 'd']);
|
|
18
|
+
* // obj.schema.items is now ['a', 'b', 'c', 'd']
|
|
19
|
+
*/
|
|
20
|
+
export const extendField = (obj, targetField, newValue) => {
|
|
21
|
+
if (typeof obj !== "object" || obj === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (obj.hasOwnProperty(targetField)) {
|
|
25
|
+
if (Array.isArray(obj[targetField])) {
|
|
26
|
+
for (const element of newValue) {
|
|
27
|
+
if (!obj[targetField].includes(element)) {
|
|
28
|
+
obj[targetField] = [...obj[targetField], element];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (typeof obj[targetField] === "object") {
|
|
33
|
+
obj[targetField] = { ...obj[targetField], ...newValue };
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
for (const key in obj) {
|
|
38
|
+
if (extendField(obj[key], targetField, newValue)) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Deep transform an object using a transformer specification
|
|
46
|
+
* Supports function transformers, nested object transformers, and literal values
|
|
47
|
+
*
|
|
48
|
+
* @param obj - The source object to transform
|
|
49
|
+
* @param transformers - Specification object where:
|
|
50
|
+
* - function values: called with current value, result used as new value
|
|
51
|
+
* - object values: recursively applied to nested objects
|
|
52
|
+
* - other values: used directly as the new value
|
|
53
|
+
* @returns New transformed object (original is not mutated)
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* const obj = { name: 'hero', count: 5 };
|
|
57
|
+
* const result = deepTransform(obj, {
|
|
58
|
+
* name: (v) => v.toUpperCase(),
|
|
59
|
+
* count: (v) => v * 2,
|
|
60
|
+
* });
|
|
61
|
+
* // result: { name: 'HERO', count: 10 }
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Nested transformation
|
|
65
|
+
* const obj = { schema: { title: 'old' } };
|
|
66
|
+
* const result = deepTransform(obj, {
|
|
67
|
+
* schema: { title: 'new' }
|
|
68
|
+
* });
|
|
69
|
+
* // result: { schema: { title: 'new' } }
|
|
70
|
+
*/
|
|
71
|
+
export function deepTransform(obj, transformers) {
|
|
72
|
+
if (typeof obj !== "object" || obj === null) {
|
|
73
|
+
return obj;
|
|
74
|
+
}
|
|
75
|
+
const result = Array.isArray(obj) ? [...obj] : { ...obj };
|
|
76
|
+
for (const key in transformers) {
|
|
77
|
+
if (typeof transformers[key] === "function") {
|
|
78
|
+
result[key] = transformers[key](obj[key]);
|
|
79
|
+
}
|
|
80
|
+
else if (typeof transformers[key] === "object" &&
|
|
81
|
+
transformers[key] !== null) {
|
|
82
|
+
result[key] = deepTransform(obj[key] || {}, transformers[key]);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
result[key] = transformers[key];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Preserve untransformed properties
|
|
89
|
+
for (const key in obj) {
|
|
90
|
+
if (!(key in transformers)) {
|
|
91
|
+
result[key] = obj[key];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if a component has content available as bloks
|
|
98
|
+
*
|
|
99
|
+
* @param component - Storyblok component schema
|
|
100
|
+
* @returns true if component.schema.content is a bloks field with whitelist
|
|
101
|
+
*/
|
|
102
|
+
export const isContentAvailableAsBloks = (component) => "content" in component.schema &&
|
|
103
|
+
component.schema.content.component_whitelist &&
|
|
104
|
+
component.schema.content.type === "bloks";
|
|
105
|
+
/**
|
|
106
|
+
* Check if a component has items available as bloks
|
|
107
|
+
*
|
|
108
|
+
* @param component - Storyblok component schema
|
|
109
|
+
* @returns true if component.schema.items is a bloks field with whitelist
|
|
110
|
+
*/
|
|
111
|
+
export const isItemsAvailableAsBloks = (component) => "items" in component.schema &&
|
|
112
|
+
component.schema.items.component_whitelist &&
|
|
113
|
+
component.schema.items.type === "bloks";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasAccessToSpace = exports.getCurrentUser = void 0;
|
|
4
|
+
const spaces_js_1 = require("../spaces/spaces.js");
|
|
5
|
+
const getCurrentUser = async (config) => {
|
|
6
|
+
const { sbApi } = config;
|
|
7
|
+
console.log("Trying to get current user current OAuthToken");
|
|
8
|
+
const currentUser = await sbApi
|
|
9
|
+
.get(`users/me`, {
|
|
10
|
+
per_page: 100,
|
|
11
|
+
})
|
|
12
|
+
.then((res) => {
|
|
13
|
+
return res.data.user;
|
|
14
|
+
})
|
|
15
|
+
.catch((err) => {
|
|
16
|
+
console.error(err);
|
|
17
|
+
return err;
|
|
18
|
+
});
|
|
19
|
+
return currentUser;
|
|
20
|
+
};
|
|
21
|
+
exports.getCurrentUser = getCurrentUser;
|
|
22
|
+
const hasAccessToSpace = async (args, config) => {
|
|
23
|
+
const { spaceId } = args;
|
|
24
|
+
const allSpaces = await (0, spaces_js_1.getAllSpaces)(config);
|
|
25
|
+
const hasAccess = allSpaces.find((space) => Number(space.id) === Number(spaceId));
|
|
26
|
+
return !!hasAccess;
|
|
27
|
+
};
|
|
28
|
+
exports.hasAccessToSpace = hasAccessToSpace;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createComponentsGroup = exports.removeComponentGroup = exports.getComponentsGroup = exports.getAllComponentsGroups = exports.removeComponent = exports.updateComponent = exports.createComponent = exports.getComponent = exports.getAllComponents = void 0;
|
|
7
|
+
const logger_js_1 = __importDefault(require("../../utils/logger.js"));
|
|
8
|
+
const resolvePresets_js_1 = __importDefault(require("../presets/resolvePresets.js"));
|
|
9
|
+
const request_js_1 = require("../utils/request.js");
|
|
10
|
+
/*
|
|
11
|
+
*
|
|
12
|
+
* GET ALL components
|
|
13
|
+
*
|
|
14
|
+
* */
|
|
15
|
+
const getAllComponents = (config) => {
|
|
16
|
+
const { spaceId, sbApi } = config;
|
|
17
|
+
logger_js_1.default.log("Trying to get all components.");
|
|
18
|
+
return (0, request_js_1.getAllItemsWithPagination)({
|
|
19
|
+
apiFn: ({ per_page, page }) => sbApi
|
|
20
|
+
.get(`spaces/${spaceId}/components/`, { per_page, page })
|
|
21
|
+
.then((res) => {
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* Not every endpoint in storyblok give us pagination...
|
|
25
|
+
* so only for this who paginate we want to console log amount found.
|
|
26
|
+
*
|
|
27
|
+
* */
|
|
28
|
+
if (res.total) {
|
|
29
|
+
logger_js_1.default.log(`Amount of components: ${res.total}`);
|
|
30
|
+
}
|
|
31
|
+
return res;
|
|
32
|
+
})
|
|
33
|
+
.catch((err) => console.error(err)),
|
|
34
|
+
params: {
|
|
35
|
+
spaceId,
|
|
36
|
+
},
|
|
37
|
+
itemsKey: "components",
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
exports.getAllComponents = getAllComponents;
|
|
41
|
+
/*
|
|
42
|
+
*
|
|
43
|
+
* GET ONE component
|
|
44
|
+
*
|
|
45
|
+
* */
|
|
46
|
+
const getComponent = (componentName, config) => {
|
|
47
|
+
logger_js_1.default.log(`Trying to get '${componentName}' component.`);
|
|
48
|
+
return (0, exports.getAllComponents)(config)
|
|
49
|
+
.then((res) => res.filter((component) => component.name === componentName))
|
|
50
|
+
.then((res) => {
|
|
51
|
+
if (Array.isArray(res) && res.length === 0) {
|
|
52
|
+
console.info(`There is no component named '${componentName}'`);
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return res;
|
|
56
|
+
})
|
|
57
|
+
.catch((err) => console.error(err));
|
|
58
|
+
};
|
|
59
|
+
exports.getComponent = getComponent;
|
|
60
|
+
// CREATE
|
|
61
|
+
const createComponent = (component, presets, config) => {
|
|
62
|
+
const { spaceId, sbApi } = config;
|
|
63
|
+
logger_js_1.default.log(`Trying to create '${component.name}'`);
|
|
64
|
+
const componentWithPresets = component;
|
|
65
|
+
const { all_presets, ...componentWithoutPresets } = componentWithPresets;
|
|
66
|
+
return sbApi
|
|
67
|
+
.post(`spaces/${spaceId}/components/`, {
|
|
68
|
+
component: componentWithoutPresets,
|
|
69
|
+
})
|
|
70
|
+
.then((res) => {
|
|
71
|
+
logger_js_1.default.success(`Component '${component.name}' has been created.`);
|
|
72
|
+
if (presets) {
|
|
73
|
+
(0, resolvePresets_js_1.default)(res, all_presets, component, config);
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.catch((err) => {
|
|
77
|
+
logger_js_1.default.error(`${err.message} in migration of ${component.name} in createComponent function`);
|
|
78
|
+
throw err;
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
exports.createComponent = createComponent;
|
|
82
|
+
/*
|
|
83
|
+
*
|
|
84
|
+
* PUT ONE Component
|
|
85
|
+
*
|
|
86
|
+
* */
|
|
87
|
+
const updateComponent = (component, presets, config) => {
|
|
88
|
+
const { spaceId, sbApi } = config;
|
|
89
|
+
logger_js_1.default.log(`Trying to update '${component.name}' with id ${component.id}`);
|
|
90
|
+
const componentWithPresets = component;
|
|
91
|
+
const { all_presets, ...componentWithoutPresets } = componentWithPresets;
|
|
92
|
+
return sbApi
|
|
93
|
+
.put(`spaces/${spaceId}/components/${component.id}`, {
|
|
94
|
+
component: componentWithoutPresets,
|
|
95
|
+
})
|
|
96
|
+
.then(async (res) => {
|
|
97
|
+
logger_js_1.default.success(`Component '${component.name}' has been updated.`);
|
|
98
|
+
if (presets) {
|
|
99
|
+
return await (0, resolvePresets_js_1.default)(res, all_presets, component, config);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
.catch((err) => {
|
|
106
|
+
logger_js_1.default.error(`${err.message} in migration of ${component.name} in updateComponent function`);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
exports.updateComponent = updateComponent;
|
|
110
|
+
/*
|
|
111
|
+
*
|
|
112
|
+
* DEL one Component
|
|
113
|
+
*
|
|
114
|
+
* */
|
|
115
|
+
const removeComponent = (component, config) => {
|
|
116
|
+
const { id, name } = component;
|
|
117
|
+
const { spaceId, sbApi } = config;
|
|
118
|
+
console.log(`Removing '${name}' component.`);
|
|
119
|
+
return sbApi
|
|
120
|
+
.delete(`spaces/${spaceId}/components/${id}`, {})
|
|
121
|
+
.then((res) => res.data)
|
|
122
|
+
.catch((err) => console.error(err));
|
|
123
|
+
};
|
|
124
|
+
exports.removeComponent = removeComponent;
|
|
125
|
+
/*
|
|
126
|
+
*
|
|
127
|
+
* GET All Component Groups
|
|
128
|
+
*
|
|
129
|
+
* */
|
|
130
|
+
const getAllComponentsGroups = async (config) => {
|
|
131
|
+
const { spaceId, sbApi } = config;
|
|
132
|
+
logger_js_1.default.log("Trying to get all groups.");
|
|
133
|
+
// TODO: All Components Groups doesnt support pagination...
|
|
134
|
+
// https://github.com/storyblok/storyblok-js-client/issues/535
|
|
135
|
+
return (0, request_js_1.getAllItemsWithPagination)({
|
|
136
|
+
apiFn: ({ per_page, page }) => sbApi
|
|
137
|
+
.get(`spaces/${spaceId}/component_groups/`, { per_page, page })
|
|
138
|
+
.then((res) => {
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* Not every endpoint in storyblok give us pagination...
|
|
142
|
+
* so only for this who paginate we want to console log amount found.
|
|
143
|
+
*
|
|
144
|
+
* */
|
|
145
|
+
if (res.total) {
|
|
146
|
+
logger_js_1.default.log(`Amount of component groups: ${res.total}`);
|
|
147
|
+
}
|
|
148
|
+
return res;
|
|
149
|
+
})
|
|
150
|
+
.catch((err) => console.error(err)),
|
|
151
|
+
params: {
|
|
152
|
+
spaceId,
|
|
153
|
+
},
|
|
154
|
+
itemsKey: "component_groups",
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
exports.getAllComponentsGroups = getAllComponentsGroups;
|
|
158
|
+
const getComponentsGroup = (groupName, config) => {
|
|
159
|
+
console.log(`Trying to get '${groupName}' group.`);
|
|
160
|
+
return (0, exports.getAllComponentsGroups)(config)
|
|
161
|
+
.then((res) => {
|
|
162
|
+
return res.filter((group) => group.name === groupName);
|
|
163
|
+
})
|
|
164
|
+
.then((res) => {
|
|
165
|
+
if (Array.isArray(res) && res.length === 0) {
|
|
166
|
+
console.info(`There is no group named '${groupName}'`);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
return res;
|
|
170
|
+
})
|
|
171
|
+
.catch((err) => console.error(err));
|
|
172
|
+
};
|
|
173
|
+
exports.getComponentsGroup = getComponentsGroup;
|
|
174
|
+
const removeComponentGroup = (componentGroup, config) => {
|
|
175
|
+
const { id, name } = componentGroup;
|
|
176
|
+
const { spaceId, sbApi } = config;
|
|
177
|
+
console.log(`Removing '${name}' component group.`);
|
|
178
|
+
return sbApi
|
|
179
|
+
.delete(`spaces/${spaceId}/component_groups/${id}`, {})
|
|
180
|
+
.then((res) => res.data)
|
|
181
|
+
.catch((err) => console.error(err));
|
|
182
|
+
};
|
|
183
|
+
exports.removeComponentGroup = removeComponentGroup;
|
|
184
|
+
const createComponentsGroup = (groupName, config) => {
|
|
185
|
+
const { spaceId, sbApi } = config;
|
|
186
|
+
console.log(`Trying to create '${groupName}' group`);
|
|
187
|
+
return sbApi
|
|
188
|
+
.post(`spaces/${spaceId}/component_groups/`, {
|
|
189
|
+
component_group: {
|
|
190
|
+
name: groupName,
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
.then((res) => {
|
|
194
|
+
console.info(`'${groupName}' created with uuid: ${res.data.component_group.uuid}`);
|
|
195
|
+
return res.data;
|
|
196
|
+
})
|
|
197
|
+
.catch((err) => {
|
|
198
|
+
console.log(err.message);
|
|
199
|
+
console.error("Error happened :()");
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
exports.createComponentsGroup = createComponentsGroup;
|