sb-mig 6.2.0 → 6.3.0-beta.1

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 (39) hide show
  1. package/README.md +15 -4
  2. package/dist/api/assets/asset-folders.d.ts +3 -0
  3. package/dist/api/assets/asset-folders.js +56 -0
  4. package/dist/api/assets/asset-folders.types.d.ts +29 -0
  5. package/dist/api/assets/asset-folders.types.js +1 -0
  6. package/dist/api/assets/assets.d.ts +4 -1
  7. package/dist/api/assets/assets.js +61 -16
  8. package/dist/api/assets/assets.types.d.ts +12 -1
  9. package/dist/api/assets/index.d.ts +4 -2
  10. package/dist/api/assets/index.js +2 -1
  11. package/dist/api/copy/assets.d.ts +12 -0
  12. package/dist/api/copy/assets.js +84 -0
  13. package/dist/api/copy/graph.d.ts +8 -0
  14. package/dist/api/copy/graph.js +27 -0
  15. package/dist/api/copy/index.d.ts +6 -0
  16. package/dist/api/copy/index.js +6 -0
  17. package/dist/api/copy/manifest.d.ts +23 -0
  18. package/dist/api/copy/manifest.js +115 -0
  19. package/dist/api/copy/reference-rewriter.d.ts +6 -0
  20. package/dist/api/copy/reference-rewriter.js +153 -0
  21. package/dist/api/copy/reference-scanner.d.ts +23 -0
  22. package/dist/api/copy/reference-scanner.js +322 -0
  23. package/dist/api/copy/types.d.ts +196 -0
  24. package/dist/api/copy/types.js +1 -0
  25. package/dist/api/managementApi.d.ts +6 -0
  26. package/dist/api/stories/stories.js +3 -3
  27. package/dist/api/stories/stories.types.d.ts +3 -1
  28. package/dist/api/testApi.d.ts +6 -0
  29. package/dist/api-v2/requestConfig.d.ts +17 -1
  30. package/dist/api-v2/requestConfig.js +28 -0
  31. package/dist/cli/cli-descriptions.d.ts +2 -2
  32. package/dist/cli/cli-descriptions.js +83 -18
  33. package/dist/cli/commands/copy.js +2091 -145
  34. package/dist/cli/index.js +0 -0
  35. package/dist/utils/files.d.ts +1 -0
  36. package/dist/utils/files.js +77 -3
  37. package/dist-cjs/api/stories/stories.js +3 -3
  38. package/dist-cjs/api-v2/requestConfig.js +29 -0
  39. package/package.json +2 -2
package/dist/cli/index.js CHANGED
File without changes
@@ -38,6 +38,7 @@ export declare const getPackageJson: () => any;
38
38
  export declare const isDirectoryExists: (path: string) => boolean;
39
39
  export declare const createDir: (dirPath: string) => Promise<void>;
40
40
  export declare const createJsonFile: (content: string, pathWithFilename: string) => Promise<void>;
41
+ export declare const writeJsonArrayStreamed: (items: any[], pathWithFilename: string) => Promise<void>;
41
42
  export declare const createJSAllComponentsFile: (content: string, pathWithFilename: string, timestamp?: boolean) => Promise<void>;
42
43
  export declare const copyFolder: (src: string, dest: string) => Promise<unknown>;
43
44
  export declare const copyFile: (src: string, dest: string) => Promise<void>;
@@ -84,6 +84,75 @@ export const createDir = async (dirPath) => {
84
84
  export const createJsonFile = async (content, pathWithFilename) => {
85
85
  await fs.promises.writeFile(pathWithFilename, content, { flag: "w" });
86
86
  };
87
+ /*
88
+ * Streams an array to disk as a pretty-printed (2-space) JSON array,
89
+ * one element at a time. Avoids building the whole document as a single
90
+ * string, which overflows V8's max string length (~512 MB) for large
91
+ * migration sets. Output is byte-for-byte identical to
92
+ * JSON.stringify(items, null, 2).
93
+ * */
94
+ export const writeJsonArrayStreamed = (items, pathWithFilename) => {
95
+ return new Promise((resolve, reject) => {
96
+ const stream = fs.createWriteStream(pathWithFilename, { flags: "w" });
97
+ let settled = false;
98
+ const fail = (err) => {
99
+ if (settled)
100
+ return;
101
+ settled = true;
102
+ reject(err);
103
+ };
104
+ stream.on("error", fail);
105
+ stream.on("finish", () => {
106
+ if (settled)
107
+ return;
108
+ settled = true;
109
+ resolve();
110
+ });
111
+ const indentElement = (item) => {
112
+ const serialized = JSON.stringify(item, null, 2);
113
+ const body = serialized === undefined ? "null" : serialized;
114
+ return ` ${body.replace(/\n/g, "\n ")}`;
115
+ };
116
+ const writeChunk = (chunk) => new Promise((res, rej) => {
117
+ const onErr = (err) => rej(err);
118
+ const ok = stream.write(chunk, (err) => {
119
+ if (err) {
120
+ rej(err);
121
+ return;
122
+ }
123
+ if (ok) {
124
+ stream.removeListener("error", onErr);
125
+ res();
126
+ }
127
+ });
128
+ if (!ok) {
129
+ stream.once("drain", () => {
130
+ stream.removeListener("error", onErr);
131
+ res();
132
+ });
133
+ }
134
+ stream.once("error", onErr);
135
+ });
136
+ const writeChunks = async () => {
137
+ if (items.length === 0) {
138
+ stream.write("[]");
139
+ return;
140
+ }
141
+ await writeChunk("[\n");
142
+ for (let i = 0; i < items.length; i++) {
143
+ const prefix = i === 0 ? "" : ",\n";
144
+ await writeChunk(`${prefix}${indentElement(items[i])}`);
145
+ }
146
+ await writeChunk("\n]");
147
+ };
148
+ writeChunks()
149
+ .then(() => stream.end())
150
+ .catch((err) => {
151
+ stream.destroy();
152
+ fail(err);
153
+ });
154
+ });
155
+ };
87
156
  export const createJSAllComponentsFile = async (content, pathWithFilename, timestamp = false) => {
88
157
  const datestamp = new Date();
89
158
  const finalContent = `/*
@@ -146,8 +215,8 @@ export const createAndSaveToFile = async (args, config) => {
146
215
  const finalFilename = `${prefix}${filename}${datestamp ? `__${timestamp}` : ""}`;
147
216
  const fullPath = `${sbmigWorkingDirectory}/${folder}/${finalFilename}${suffix}.${ext}`;
148
217
  await createDir(`${sbmigWorkingDirectory}/${folder}/`);
149
- if (ext === "json") {
150
- await createJsonFile(JSON.stringify(res, undefined, 2), fullPath);
218
+ if (Array.isArray(res)) {
219
+ await writeJsonArrayStreamed(res, fullPath);
151
220
  }
152
221
  else {
153
222
  await createJsonFile(JSON.stringify(res, undefined, 2), fullPath);
@@ -157,7 +226,12 @@ export const createAndSaveToFile = async (args, config) => {
157
226
  if (path) {
158
227
  const folderPath = nodePath.dirname(path);
159
228
  await createDir(folderPath);
160
- await createJsonFile(JSON.stringify(res, undefined, 2), path);
229
+ if (Array.isArray(res)) {
230
+ await writeJsonArrayStreamed(res, path);
231
+ }
232
+ else {
233
+ await createJsonFile(JSON.stringify(res, undefined, 2), path);
234
+ }
161
235
  Logger.success(`All response written to a file: ${path}`);
162
236
  }
163
237
  };
@@ -354,13 +354,13 @@ const getStoryVersions = async ({ storyId, showContent = true, page = 1, perPage
354
354
  };
355
355
  exports.getStoryVersions = getStoryVersions;
356
356
  // CREATE
357
- const createStory = (content, config) => {
357
+ const createStory = (content, config, options) => {
358
358
  const { spaceId, sbApi } = config;
359
359
  logger_js_1.default.log(`Creating story with name: ${content.name} in space: ${spaceId}`);
360
360
  return sbApi
361
361
  .post(`spaces/${spaceId}/stories/`, {
362
362
  story: content,
363
- publish: true,
363
+ publish: options?.publish ?? true,
364
364
  })
365
365
  .then((res) => res.data)
366
366
  .catch((err) => console.error(err));
@@ -371,7 +371,7 @@ const updateStory = (content, storyId, options, config) => {
371
371
  const { spaceId, sbApi } = config;
372
372
  const storyLabel = resolveStoryLabel(content, storyId);
373
373
  logger_js_1.default.warning("Trying to update Story...");
374
- logger_js_1.default.log(`Updating story with name: ${content.name} in space: ${spaceId}`);
374
+ logger_js_1.default.log(`Updating story '${storyLabel}' in space: ${spaceId}`);
375
375
  // console.log("THis is content to update: ");
376
376
  // console.log(JSON.stringify(content, null, 2));
377
377
  return sbApi
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toRequestConfig = toRequestConfig;
4
+ exports.configToClient = configToClient;
4
5
  function toRequestConfig(client, overrides) {
5
6
  return {
6
7
  spaceId: overrides?.spaceId ?? client.spaceId,
@@ -35,3 +36,31 @@ function toRequestConfig(client, overrides) {
35
36
  storyblokComponentsLocalDirectory: overrides?.storyblokComponentsLocalDirectory,
36
37
  };
37
38
  }
39
+ /**
40
+ * Inverse of `toRequestConfig`: adapt a legacy `RequestBaseConfig` into an
41
+ * `ApiClient`.
42
+ *
43
+ * This is the primitive used by the Strategy-B shims (see SDK-REFACTOR.md §3): a
44
+ * legacy `api/<x>` function receives a `RequestBaseConfig` and delegates to the
45
+ * moved `api-v2/<x>` function, which takes an `ApiClient`. The live `sbApi`
46
+ * instance is reused (not recreated) so rate-limit and cache state are preserved.
47
+ *
48
+ * Note: `ApiClient` intentionally carries only the data-API essentials (`sbApi`,
49
+ * `spaceId`, tokens). The remaining `IStoryblokConfig` fields on
50
+ * `RequestBaseConfig` (directories, extensions, resolvers, …) are node-tier /
51
+ * file-discovery concerns handled separately — they are not represented on
52
+ * `ApiClient`. See SDK-REFACTOR.md §4 and ticket F5.
53
+ */
54
+ function configToClient(config, overrides) {
55
+ const clientConfig = {
56
+ oauthToken: overrides?.oauthToken ?? config.oauthToken ?? "",
57
+ spaceId: overrides?.spaceId ?? config.spaceId,
58
+ accessToken: overrides?.accessToken ?? config.accessToken,
59
+ rateLimit: overrides?.rateLimit ?? config.rateLimit,
60
+ };
61
+ return {
62
+ config: clientConfig,
63
+ sbApi: config.sbApi,
64
+ spaceId: clientConfig.spaceId,
65
+ };
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sb-mig",
3
- "version": "6.2.0",
3
+ "version": "6.3.0-beta.1",
4
4
  "description": "CLI to rule the world. (and handle stuff related to Storyblok CMS)",
5
5
  "author": "Marcin Krawczyk <marckraw@icloud.com>",
6
6
  "license": "MIT",
@@ -15,7 +15,7 @@
15
15
  "access": "public"
16
16
  },
17
17
  "bugs": "https://github.com/sb-mig/sb-mig/issues",
18
- "homepage": "https://github.com/sb-mig/sb-mig",
18
+ "homepage": "https://sb-mig.vercel.app",
19
19
  "keywords": [
20
20
  "cli",
21
21
  "storyblok",