@embeddable.com/sdk-core 3.12.6 → 3.13.0-next.0

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 (46) hide show
  1. package/lib/index.esm.js +112 -239
  2. package/lib/index.esm.js.map +1 -1
  3. package/loader/custom-esm-loader.mjs +16 -11
  4. package/loader/entryPoint.js +1 -1
  5. package/loader/entryPoint.test.js +1 -1
  6. package/package.json +10 -6
  7. package/src/build.test.ts +4 -0
  8. package/src/build.ts +0 -1
  9. package/src/buildTypes.ts +1 -3
  10. package/src/defineConfig.ts +2 -0
  11. package/src/dev.test.ts +7 -1
  12. package/src/dev.ts +7 -14
  13. package/src/generate.ts +1 -1
  14. package/src/logger.test.ts +16 -4
  15. package/src/login.test.ts +2 -2
  16. package/src/push.test.ts +30 -9
  17. package/src/push.ts +8 -11
  18. package/src/types.d.ts +3 -0
  19. package/src/utils.test.ts +24 -5
  20. package/src/utils.ts +13 -3
  21. package/src/validate.test.ts +5 -0
  22. package/src/validate.ts +1 -1
  23. package/lib/index.js +0 -22612
  24. package/lib/index.js.map +0 -1
  25. package/lib/src/build.d.ts +0 -2
  26. package/lib/src/build.test.d.ts +0 -1
  27. package/lib/src/buildTypes.d.ts +0 -4
  28. package/lib/src/buildTypes.test.d.ts +0 -1
  29. package/lib/src/cleanup.d.ts +0 -16
  30. package/lib/src/cleanup.test.d.ts +0 -1
  31. package/lib/src/createContext.d.ts +0 -23
  32. package/lib/src/credentials.d.ts +0 -2
  33. package/lib/src/defineConfig.d.ts +0 -65
  34. package/lib/src/dev.d.ts +0 -2
  35. package/lib/src/generate.d.ts +0 -2
  36. package/lib/src/globalCleanup.d.ts +0 -2
  37. package/lib/src/index.d.ts +0 -5
  38. package/lib/src/login.d.ts +0 -4
  39. package/lib/src/prepare.d.ts +0 -3
  40. package/lib/src/provideConfig.d.ts +0 -2
  41. package/lib/src/provideConfig.test.d.ts +0 -1
  42. package/lib/src/push.d.ts +0 -26
  43. package/lib/src/utils.d.ts +0 -25
  44. package/lib/src/utils.test.d.ts +0 -1
  45. package/lib/src/validate.d.ts +0 -8
  46. package/lib/src/validate.test.d.ts +0 -1
@@ -62,9 +62,10 @@ const isWindows = process.platform === "win32";
62
62
 
63
63
  function cleanWindowsFileURL(url) {
64
64
  // Remove any duplicate file:/ prefixes and normalize slashes
65
- return url.replace(/file:\/+/g, 'file:///')
66
- .replace(/\\/g, '/')
67
- .replace(/file:\/+([A-Za-z]:)/, 'file:///$1');
65
+ return url
66
+ .replace(/file:\/+/g, "file:///")
67
+ .replace(/\\/g, "/")
68
+ .replace(/file:\/+([A-Za-z]:)/, "file:///$1");
68
69
  }
69
70
 
70
71
  export const resolve = async (specifier, context, nextResolve) => {
@@ -86,13 +87,13 @@ export const resolve = async (specifier, context, nextResolve) => {
86
87
  if (!context.parentURL) {
87
88
  if (isWindows) {
88
89
  // Handle the case where the specifier contains both the cwd and the actual path
89
- const parts = specifier.split('file:/');
90
+ const parts = specifier.split("file:/");
90
91
  const lastPart = parts[parts.length - 1];
91
-
92
+
92
93
  // Convert the path to a proper file URL
93
- const cleanPath = lastPart.replace(/^\/+/, '');
94
+ const cleanPath = lastPart.replace(/^\/+/, "");
94
95
  const entryPointPath = pathToFileURL(cleanPath).href;
95
-
96
+
96
97
  return {
97
98
  format: isTS ? "ts" : undefined,
98
99
  url: cleanWindowsFileURL(entryPointPath),
@@ -108,14 +109,18 @@ export const resolve = async (specifier, context, nextResolve) => {
108
109
  }
109
110
 
110
111
  // Handle SDK relative imports
111
- if (isWindows && specifier.startsWith('.') && context.parentURL?.includes('embeddable-sdk')) {
112
+ if (
113
+ isWindows &&
114
+ specifier.startsWith(".") &&
115
+ context.parentURL?.includes("embeddable-sdk")
116
+ ) {
112
117
  const parentPath = fileURLToPath(context.parentURL);
113
118
  const parentDir = dirname(parentPath);
114
119
  let resolvedPath = join(parentDir, specifier);
115
-
120
+
116
121
  // If no extension is provided, try common extensions
117
122
  if (!path.extname(resolvedPath)) {
118
- const extensions = ['.js', '.mjs', '.cjs', '.ts', '.mts'];
123
+ const extensions = [".js", ".mjs", ".cjs", ".ts", ".mts"];
119
124
  for (const ext of extensions) {
120
125
  const pathWithExt = resolvedPath + ext;
121
126
  if (fs.existsSync(pathWithExt) && fs.statSync(pathWithExt).isFile()) {
@@ -129,7 +134,7 @@ export const resolve = async (specifier, context, nextResolve) => {
129
134
  if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isFile()) {
130
135
  return {
131
136
  url: pathToFileURL(resolvedPath).href,
132
- shortCircuit: true
137
+ shortCircuit: true,
133
138
  };
134
139
  }
135
140
  }
@@ -1,4 +1,4 @@
1
- import { build, defineConfig, dev, login, push } from "../lib/index.js";
1
+ import { build, defineConfig, dev, login, push } from "../lib/index.esm.js";
2
2
  import { spawn } from "child_process";
3
3
  import path from "path";
4
4
  import fs from "fs";
@@ -7,7 +7,7 @@ import path from "path";
7
7
  vi.mock("child_process");
8
8
  vi.mock("fs");
9
9
  vi.mock("path");
10
- vi.mock("../lib/index.js", () => ({
10
+ vi.mock("../lib/index.esm.js", () => ({
11
11
  build: vi.fn().mockResolvedValue(undefined),
12
12
  login: vi.fn().mockResolvedValue(undefined),
13
13
  push: vi.fn().mockResolvedValue(undefined),
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@embeddable.com/sdk-core",
3
- "version": "3.12.6",
3
+ "version": "3.13.0-next.0",
4
4
  "description": "Core Embeddable SDK module responsible for web-components bundling and publishing.",
5
5
  "keywords": [
6
6
  "embeddable",
7
7
  "sdk",
8
8
  "web-components"
9
9
  ],
10
- "main": "lib/index.js",
10
+ "main": "lib/index.esm.js",
11
11
  "module": "lib/index.esm.js",
12
12
  "types": "lib/index.d.ts",
13
+ "type": "module",
13
14
  "repository": {
14
15
  "type": "git",
15
16
  "url": "git+https://github.com/embeddable-hq/embeddable-sdk.git",
@@ -38,11 +39,11 @@
38
39
  },
39
40
  "license": "MIT",
40
41
  "dependencies": {
41
- "@embeddable.com/sdk-utils": "0.6.2",
42
+ "@embeddable.com/sdk-utils": "0.7.0-next.0",
42
43
  "@inquirer/prompts": "^7.2.1",
43
44
  "@stencil/core": "^4.23.0",
44
45
  "@swc-node/register": "^1.10.9",
45
- "archiver": "^5.3.2",
46
+ "archiver": "^7.0.1",
46
47
  "axios": "^1.7.9",
47
48
  "chokidar": "^4.0.3",
48
49
  "dotenv": "^16.4.7",
@@ -53,7 +54,7 @@
53
54
  "open": "^9.1.0",
54
55
  "ora": "^8.1.1",
55
56
  "serve-static": "^1.16.2",
56
- "sorcery": "^0.11.1",
57
+ "sorcery": "^1.0.0",
57
58
  "vite": "^5.4.11",
58
59
  "ws": "^8.18.0",
59
60
  "yaml": "^2.6.1"
@@ -64,7 +65,10 @@
64
65
  ]
65
66
  },
66
67
  "devDependencies": {
67
- "@types/archiver": "^5.3.4",
68
+ "@types/archiver": "^6.0.3",
69
+ "@types/finalhandler": "^1.2.3",
70
+ "@types/minimist": "^1.2.5",
71
+ "@types/serve-static": "^1.15.7",
68
72
  "@types/ws": "^8.5.13"
69
73
  }
70
74
  }
package/src/build.test.ts CHANGED
@@ -85,6 +85,8 @@ describe("build", () => {
85
85
  });
86
86
 
87
87
  it("should call reportErrorToRollbar and exit if an error occurs", async () => {
88
+ const originalConsoleError = console.error;
89
+ console.error = vi.fn();
88
90
  vi.spyOn(process, "exit").mockImplementation(() => null as never);
89
91
  vi.spyOn(console, "log").mockImplementation(() => undefined);
90
92
  const error = new Error("test error");
@@ -97,5 +99,7 @@ describe("build", () => {
97
99
  expect(reportErrorToRollbar).toHaveBeenCalledWith(error);
98
100
  expect(console.log).toHaveBeenCalledWith(error);
99
101
  expect(process.exit).toHaveBeenCalledWith(1);
102
+
103
+ console.error = originalConsoleError;
100
104
  });
101
105
  });
package/src/build.ts CHANGED
@@ -22,7 +22,6 @@ export default async () => {
22
22
  checkNodeVersion();
23
23
  breadcrumbs.push("checkNodeVersion");
24
24
  removeBuildSuccessFlag();
25
-
26
25
  const config = await provideConfig();
27
26
 
28
27
  await validate(config);
package/src/buildTypes.ts CHANGED
@@ -1,15 +1,13 @@
1
1
  import * as fs from "node:fs/promises";
2
2
  import * as path from "node:path";
3
3
  import * as vite from "vite";
4
- const oraP = import("ora");
4
+ import ora from "ora";
5
5
  import { findFiles, getContentHash } from "@embeddable.com/sdk-utils";
6
6
 
7
7
  export const EMB_TYPE_FILE_REGEX = /^(.*)\.type\.emb\.[jt]s$/;
8
8
  export const EMB_OPTIONS_FILE_REGEX = /^(.*)\.options\.emb\.[jt]s$/;
9
9
 
10
10
  export default async (ctx: any) => {
11
- const ora = (await oraP).default;
12
-
13
11
  const progress = ora("Building types...").start();
14
12
 
15
13
  await generate(ctx);
@@ -82,6 +82,8 @@ export default ({
82
82
 
83
83
  const regionConfig = REGION_CONFIGS[region];
84
84
 
85
+ const __dirname = import.meta.dirname;
86
+
85
87
  const coreRoot = path.resolve(__dirname, "..");
86
88
  const clientRoot = process.cwd();
87
89
 
package/src/dev.test.ts CHANGED
@@ -79,7 +79,7 @@ describe("dev command", () => {
79
79
  vi.mocked(provideConfig).mockResolvedValue(mockConfig);
80
80
  vi.mocked(getToken).mockResolvedValue("mock-token");
81
81
  vi.mocked(axios.get).mockResolvedValue({
82
- data: "mock-workspace",
82
+ data: [{ id: "mock-workspace" }],
83
83
  });
84
84
  });
85
85
 
@@ -108,6 +108,8 @@ describe("dev command", () => {
108
108
  });
109
109
 
110
110
  it("should log errors and exit on failure", async () => {
111
+ const originalConsoleLog = console.log;
112
+ console.log = vi.fn();
111
113
  const error = new Error("Test error");
112
114
  const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
113
115
  throw new Error("process.exit");
@@ -119,11 +121,15 @@ describe("dev command", () => {
119
121
 
120
122
  await expect(dev()).rejects.toThrow("process.exit");
121
123
 
124
+ expect(console.log).toHaveBeenCalledWith(error);
125
+
122
126
  expect(logError).toHaveBeenCalledWith({
123
127
  command: "dev",
124
128
  breadcrumbs: ["run dev"],
125
129
  error,
126
130
  });
127
131
  expect(exitSpy).toHaveBeenCalledWith(1);
132
+
133
+ console.log = originalConsoleLog;
128
134
  });
129
135
  });
package/src/dev.ts CHANGED
@@ -26,21 +26,20 @@ import validate from "./validate";
26
26
  import { checkNodeVersion } from "./utils";
27
27
  import { createManifest } from "./cleanup";
28
28
  import { selectWorkspace } from "./workspaceUtils";
29
- import * as fs from "fs";
30
- const minimist = require("minimist");
29
+ import * as fs from "node:fs/promises";
30
+ import minimist from "minimist";
31
31
  import { initLogger, logError } from "./logger";
32
32
  import fg from "fast-glob";
33
33
  import * as dotenv from "dotenv";
34
- import { pathToFileURL } from "node:url";
35
-
34
+ import ora from "ora";
35
+ import finalhandler from "finalhandler";
36
+ import serveStatic from "serve-static";
36
37
  dotenv.config();
37
38
 
38
- const oraP = import("ora");
39
39
  let wss: WSServer;
40
40
  let changedFiles: string[] = [];
41
41
  let browserWindow: ChildProcess | null = null;
42
42
 
43
- let ora: any;
44
43
  let previewWorkspace: string;
45
44
 
46
45
  const SERVER_PORT = 8926;
@@ -53,7 +52,6 @@ const buildWebComponent = async (config: any) => {
53
52
 
54
53
  const addToGitingore = async () => {
55
54
  try {
56
- const fs = require("fs").promises;
57
55
  const gitignorePath = path.resolve(process.cwd(), ".gitignore");
58
56
  const gitignoreContent = await fs.readFile(gitignorePath, "utf8");
59
57
 
@@ -83,8 +81,6 @@ export default async () => {
83
81
  checkNodeVersion();
84
82
  addToGitingore();
85
83
 
86
- ora = (await oraP).default;
87
-
88
84
  process.on("warning", (e) => console.warn(e.stack));
89
85
 
90
86
  const logger = createNodeLogger();
@@ -116,9 +112,6 @@ export default async () => {
116
112
  breadcrumbs.push("prepare config");
117
113
  await prepare(config);
118
114
 
119
- const finalhandler = require("finalhandler");
120
- const serveStatic = require("serve-static");
121
-
122
115
  const serve = serveStatic(config.client.buildDir);
123
116
 
124
117
  let workspacePreparation = ora("Preparing workspace...").start();
@@ -149,7 +142,7 @@ export default async () => {
149
142
  workspacePreparation.succeed("Workspace is ready");
150
143
 
151
144
  const server = http.createServer(
152
- (request: IncomingMessage, res: ServerResponse) => {
145
+ async (request: IncomingMessage, res: ServerResponse) => {
153
146
  res.setHeader("Access-Control-Allow-Origin", "*");
154
147
  res.setHeader(
155
148
  "Access-Control-Allow-Methods",
@@ -172,7 +165,7 @@ export default async () => {
172
165
  try {
173
166
  if (request.url?.endsWith(GLOBAL_CSS)) {
174
167
  res.writeHead(200, { "Content-Type": "text/css" });
175
- res.end(fs.readFileSync(config.client.globalCss));
168
+ res.end(await fs.readFile(config.client.globalCss));
176
169
  return;
177
170
  }
178
171
  } catch {}
package/src/generate.ts CHANGED
@@ -4,7 +4,7 @@ import { createNodeLogger, createNodeSys } from "@stencil/core/sys/node";
4
4
  import { createCompiler, loadConfig } from "@stencil/core/compiler";
5
5
  import { findFiles, getContentHash } from "@embeddable.com/sdk-utils";
6
6
 
7
- const sorcery = require("sorcery");
7
+ import * as sorcery from "sorcery";
8
8
 
9
9
  const STYLE_IMPORTS_TOKEN = "{{STYLES_IMPORT}}";
10
10
  const RENDER_IMPORT_TOKEN = "{{RENDER_IMPORT}}";
@@ -1,4 +1,4 @@
1
- import { describe, it, expect, beforeEach, vi, afterEach } from "vitest";
1
+ import { describe, it, expect, beforeEach, vi } from "vitest";
2
2
  import { initLogger, logError, ERROR_LOG_FILE } from "./logger";
3
3
  import * as fs from "node:fs/promises";
4
4
 
@@ -7,9 +7,24 @@ vi.mock("fs/promises", () => ({
7
7
  appendFile: vi.fn(),
8
8
  access: vi.fn(),
9
9
  mkdir: vi.fn(),
10
+ stat: vi.fn(),
10
11
  }));
11
12
 
12
13
  describe("Logger", () => {
14
+ let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
15
+
16
+ beforeEach(() => {
17
+ consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
18
+
19
+ vi.mocked(fs.stat).mockResolvedValue({
20
+ size: 100,
21
+ } as any);
22
+ });
23
+
24
+ afterEach(() => {
25
+ consoleErrorSpy.mockRestore();
26
+ });
27
+
13
28
  describe("initLogger", () => {
14
29
  it("should create log directory if it does not exist", async () => {
15
30
  await initLogger("test");
@@ -24,9 +39,6 @@ describe("Logger", () => {
24
39
  });
25
40
 
26
41
  it("should handle errors when creating log directory", async () => {
27
- const consoleErrorSpy = vi
28
- .spyOn(console, "error")
29
- .mockImplementation(() => {});
30
42
  vi.mocked(fs.mkdir).mockRejectedValueOnce(
31
43
  new Error("Failed to create directory"),
32
44
  );
package/src/login.test.ts CHANGED
@@ -132,8 +132,8 @@ describe("login", () => {
132
132
  "Authentication failed. Please try again.",
133
133
  );
134
134
 
135
- expect(console.log).toHaveBeenCalledWith(
136
- new AxiosError("Request failed with status code 500"),
135
+ expect((console.log as any).mock.calls[0][0]).toMatchInlineSnapshot(
136
+ `[AxiosError: Request failed with status code 500]`,
137
137
  );
138
138
  });
139
139
  });
package/src/push.test.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import push from "./push";
2
2
  import provideConfig from "./provideConfig";
3
3
  import { fileFromPath } from "formdata-node/file-from-path";
4
- import * as archiver from "archiver";
4
+ import archiver from "archiver";
5
5
  import * as fs from "node:fs/promises";
6
6
  import * as fsSync from "node:fs";
7
7
  import { findFiles } from "@embeddable.com/sdk-utils";
@@ -44,6 +44,8 @@ vi.mock("node:fs/promises", () => ({
44
44
  access: vi.fn(),
45
45
  rm: vi.fn(),
46
46
  mkdir: vi.fn(),
47
+ stat: vi.fn(),
48
+ appendFile: vi.fn(),
47
49
  }));
48
50
 
49
51
  vi.mock("node:fs", () => ({
@@ -51,7 +53,13 @@ vi.mock("node:fs", () => ({
51
53
  }));
52
54
 
53
55
  vi.mock("./provideConfig", () => ({
54
- default: vi.fn(),
56
+ default: vi.fn().mockResolvedValue({
57
+ client: {
58
+ rootDir: "rootDir",
59
+ buildDir: "buildDir",
60
+ archiveFile: "embeddable-build.zip",
61
+ },
62
+ }),
55
63
  }));
56
64
 
57
65
  vi.mock("./rollbar.mjs", () => ({
@@ -63,7 +71,9 @@ vi.mock("@embeddable.com/sdk-utils", () => ({
63
71
  }));
64
72
 
65
73
  vi.mock("archiver", () => ({
66
- create: vi.fn(),
74
+ default: {
75
+ create: vi.fn(),
76
+ },
67
77
  }));
68
78
 
69
79
  vi.mock("formdata-node/file-from-path", () => ({
@@ -81,6 +91,13 @@ const config = {
81
91
  };
82
92
 
83
93
  describe("push", () => {
94
+ const archiveMock = {
95
+ finalize: vi.fn(),
96
+ pipe: vi.fn(),
97
+ directory: vi.fn(),
98
+ file: vi.fn(),
99
+ };
100
+
84
101
  beforeEach(() => {
85
102
  vi.mocked(checkNodeVersion).mockResolvedValue(true);
86
103
  vi.mocked(checkBuildSuccess).mockResolvedValue(true);
@@ -90,17 +107,15 @@ describe("push", () => {
90
107
  vi.mocked(fs.readFile).mockImplementation(async () =>
91
108
  Buffer.from(`{"access_token":"mocked-token"}`),
92
109
  );
110
+ vi.mocked(fs.stat).mockResolvedValue({
111
+ size: 100,
112
+ } as any);
93
113
 
94
114
  vi.mocked(findFiles).mockResolvedValue([["fileName", "filePath"]]);
95
115
  vi.mocked(fileFromPath).mockReturnValue(
96
116
  new Blob([new ArrayBuffer(8)]) as any,
97
117
  );
98
- vi.mocked(archiver.create).mockReturnValue({
99
- finalize: vi.fn(),
100
- pipe: vi.fn(),
101
- directory: vi.fn(),
102
- file: vi.fn(),
103
- } as any);
118
+ vi.mocked(archiver.create).mockReturnValue(archiveMock as any);
104
119
 
105
120
  vi.mocked(fsSync.createWriteStream).mockReturnValue({
106
121
  on: (event: string, cb: () => void) => {
@@ -128,6 +143,12 @@ describe("push", () => {
128
143
  config.client.archiveFile,
129
144
  );
130
145
 
146
+ expect(archiveMock.pipe).toHaveBeenCalled();
147
+ expect(archiveMock.file).toHaveBeenCalledWith("filePath", {
148
+ name: "filePath",
149
+ });
150
+ expect(archiveMock.directory).toHaveBeenCalledWith("buildDir", false);
151
+ expect(archiveMock.finalize).toHaveBeenCalled();
131
152
  // after publishing the file gets removed
132
153
  expect(fs.rm).toHaveBeenCalledWith(config.client.archiveFile);
133
154
 
package/src/push.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as fs from "node:fs/promises";
2
2
  import * as fsSync from "node:fs";
3
- import * as archiver from "archiver";
3
+ import archiver from "archiver";
4
4
  import axios from "axios";
5
- const oraP = import("ora");
5
+ import ora from "ora";
6
6
  import { initLogger, logError } from "./logger";
7
7
  import * as path from "path";
8
8
 
@@ -21,7 +21,6 @@ export const CUBE_FILES = /^(.*)\.cube\.(ya?ml|js)$/;
21
21
  // grab security context and client context files
22
22
  export const PRESET_FILES = /^(.*)\.(sc|cc)\.ya?ml$/;
23
23
 
24
- let ora: any;
25
24
  export default async () => {
26
25
  await initLogger("push");
27
26
  const breadcrumbs: string[] = [];
@@ -38,8 +37,6 @@ export default async () => {
38
37
  process.exit(1);
39
38
  }
40
39
 
41
- ora = (await oraP).default;
42
-
43
40
  const config = await provideConfig();
44
41
 
45
42
  if (process.argv.includes("--api-key") || process.argv.includes("-k")) {
@@ -164,25 +161,25 @@ export async function archive(
164
161
  ) {
165
162
  const output = fsSync.createWriteStream(ctx.client.archiveFile);
166
163
 
167
- const _archiver = archiver.create("zip", {
164
+ const archive = archiver.create("zip", {
168
165
  zlib: { level: 9 },
169
166
  });
170
167
 
171
- _archiver.pipe(output);
168
+ archive.pipe(output);
172
169
  if (!isDev) {
173
- _archiver.directory(ctx.client.buildDir, false);
174
- _archiver.file(ctx.client.globalCss, {
170
+ archive.directory(ctx.client.buildDir, false);
171
+ archive.file(ctx.client.globalCss, {
175
172
  name: "global.css",
176
173
  });
177
174
  }
178
175
 
179
176
  for (const fileData of yamlFiles) {
180
- _archiver.file(fileData[1], {
177
+ archive.file(fileData[1], {
181
178
  name: fileData[0],
182
179
  });
183
180
  }
184
181
 
185
- await _archiver.finalize();
182
+ await archive.finalize();
186
183
 
187
184
  return new Promise((resolve, _reject) => {
188
185
  output.on("close", resolve);
package/src/types.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ declare module "sorcery" {
2
+ export function load(path: string): Promise<{ write: () => Promise<void> }>;
3
+ }
package/src/utils.test.ts CHANGED
@@ -40,6 +40,13 @@ vi.mock("fs/promises", () => ({
40
40
  describe("utils", () => {
41
41
  describe("checkNodeVersion", () => {
42
42
  it("should return true if the node version is greater than 14", async () => {
43
+ vi.mocked(fs.readFile).mockResolvedValue(
44
+ JSON.stringify({
45
+ engines: {
46
+ node: "16.x",
47
+ },
48
+ }),
49
+ );
43
50
  const result = await checkNodeVersion();
44
51
 
45
52
  expect(result).toBe(true);
@@ -51,11 +58,13 @@ describe("utils", () => {
51
58
  configurable: true,
52
59
  });
53
60
 
54
- vi.mock("../package.json", () => ({
55
- engines: {
56
- node: "16.x",
57
- },
58
- }));
61
+ vi.mocked(fs.readFile).mockResolvedValue(
62
+ JSON.stringify({
63
+ engines: {
64
+ node: "16.x",
65
+ },
66
+ }),
67
+ );
59
68
 
60
69
  vi.spyOn(process, "exit").mockImplementation(() => null as never);
61
70
 
@@ -66,6 +75,16 @@ describe("utils", () => {
66
75
 
67
76
  expect(result).toBe(undefined);
68
77
  });
78
+
79
+ it("should throw an error if the package.json file cannot be read", async () => {
80
+ vi.spyOn(process, "exit").mockImplementation(() => null as never);
81
+ vi.mocked(fs.readFile).mockRejectedValue(
82
+ new Error("Failed to read package.json of core-sdk"),
83
+ );
84
+ await expect(checkNodeVersion()).rejects.toThrow(
85
+ "Failed to read package.json of core-sdk",
86
+ );
87
+ });
69
88
  });
70
89
 
71
90
  describe("getArgumentByKey", () => {
package/src/utils.ts CHANGED
@@ -1,14 +1,24 @@
1
- const oraP = import("ora");
2
1
  import * as fs from "node:fs/promises";
3
2
  import { CREDENTIALS_DIR } from "./credentials";
4
3
  import path from "node:path";
4
+ import ora from "ora";
5
5
 
6
6
  export const checkNodeVersion = async () => {
7
- const ora = (await oraP).default;
8
7
  const spinner = ora("Checking node version...").start();
9
8
  const [major, minor] = process.versions.node.split(".").map(Number);
10
9
 
11
- const packageJson = await import("../package.json");
10
+ let packageJson;
11
+ try {
12
+ packageJson = JSON.parse(
13
+ await fs.readFile(
14
+ path.join(import.meta.dirname, "../package.json"),
15
+ "utf-8",
16
+ ),
17
+ );
18
+ } catch (e) {
19
+ throw new Error("Failed to read package.json of core-sdk");
20
+ }
21
+
12
22
  const {
13
23
  engines: { node },
14
24
  } = packageJson;
@@ -10,6 +10,11 @@ const startMock = {
10
10
  fail: vi.fn(),
11
11
  };
12
12
 
13
+ vi.mock("@embeddable.com/sdk-utils", () => ({
14
+ errorFormatter: vi.fn(),
15
+ findFiles: vi.fn(),
16
+ }));
17
+
13
18
  const failMock = vi.fn();
14
19
 
15
20
  const validYaml = `cubes:
package/src/validate.ts CHANGED
@@ -2,6 +2,7 @@ import * as fs from "node:fs/promises";
2
2
  import * as YAML from "yaml";
3
3
  import { errorFormatter, findFiles } from "@embeddable.com/sdk-utils";
4
4
  import { z } from "zod";
5
+ import ora from "ora";
5
6
  import { checkNodeVersion } from "./utils";
6
7
 
7
8
  const CUBE_YAML_FILE_REGEX = /^(.*)\.cube\.ya?ml$/;
@@ -10,7 +11,6 @@ const CLIENT_CONTEXT_FILE_REGEX = /^(.*)\.cc\.ya?ml$/;
10
11
 
11
12
  export default async (ctx: any) => {
12
13
  checkNodeVersion();
13
- const ora = (await import("ora")).default;
14
14
 
15
15
  const spinnerValidate = ora("Data model validation...").start();
16
16