@embeddable.com/sdk-core 3.3.0 → 3.4.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.
- package/bin/embeddable +5 -1
- package/lib/cleanup.d.ts +8 -0
- package/lib/index.esm.js +302 -146
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +300 -144
- package/lib/index.js.map +1 -1
- package/lib/login.d.ts +1 -0
- package/lib/utils.d.ts +3 -1
- package/lib/validate.d.ts +1 -0
- package/package.json +5 -3
- package/src/build.test.ts +96 -0
- package/src/buildTypes.test.ts +98 -0
- package/src/buildTypes.ts +20 -12
- package/src/cleanup.test.ts +85 -0
- package/src/cleanup.ts +89 -18
- package/src/login.test.ts +121 -0
- package/src/login.ts +1 -1
- package/src/provideConfig.test.ts +32 -0
- package/src/push.ts +5 -2
- package/src/utils.test.ts +99 -0
- package/src/utils.ts +27 -6
- package/src/validate.test.ts +96 -0
- package/src/validate.ts +2 -15
package/lib/login.d.ts
CHANGED
package/lib/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const checkNodeVersion: () => Promise<
|
|
1
|
+
export declare const checkNodeVersion: () => Promise<boolean>;
|
|
2
2
|
/**
|
|
3
3
|
* Get the value of a process argument by key
|
|
4
4
|
* Example: getArgumentByKey("--email") or getArgumentByKey(["--email", "-e"])
|
|
@@ -6,6 +6,7 @@ export declare const checkNodeVersion: () => Promise<void>;
|
|
|
6
6
|
* @returns
|
|
7
7
|
*/
|
|
8
8
|
export declare const getArgumentByKey: (key: string | string[]) => string | undefined;
|
|
9
|
+
export declare const SUCCESS_FLAG_FILE: string;
|
|
9
10
|
/**
|
|
10
11
|
* Store a flag in the credentials directory to indicate a successful build
|
|
11
12
|
* This is used to determine if the build was successful or not
|
|
@@ -19,3 +20,4 @@ export declare const removeBuildSuccessFlag: () => Promise<void>;
|
|
|
19
20
|
* Check if the build was successful
|
|
20
21
|
*/
|
|
21
22
|
export declare const checkBuildSuccess: () => Promise<boolean>;
|
|
23
|
+
export declare const getPackageVersion: (packageName: string) => any;
|
package/lib/validate.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
declare const _default: (ctx: any, exitIfInvalid?: boolean) => Promise<boolean>;
|
|
2
2
|
export default _default;
|
|
3
3
|
export declare function dataModelsValidation(filesList: [string, string][]): Promise<string[]>;
|
|
4
|
+
export declare function securityContextValidation(filesList: [string, string][]): Promise<string[]>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@embeddable.com/sdk-core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Core Embeddable SDK module responsible for web-components bundling and publishing.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"embeddable",
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
"directory": "packages/core-sdk"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "rollup -c"
|
|
19
|
+
"build": "rollup -c",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest"
|
|
20
22
|
},
|
|
21
23
|
"author": "Embeddable.com <engineering@embeddable.com>",
|
|
22
24
|
"files": [
|
|
@@ -49,7 +51,7 @@
|
|
|
49
51
|
"ora": "^8.0.1",
|
|
50
52
|
"serve-static": "^1.15.0",
|
|
51
53
|
"sorcery": "^0.11.0",
|
|
52
|
-
"vite": "^
|
|
54
|
+
"vite": "^5.3.1",
|
|
53
55
|
"ws": "^8.17.0",
|
|
54
56
|
"yaml": "^2.3.3"
|
|
55
57
|
},
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import build from "./build";
|
|
2
|
+
import prepare from "./prepare";
|
|
3
|
+
import validate from "./validate";
|
|
4
|
+
import buildTypes from "./buildTypes";
|
|
5
|
+
import provideConfig from "./provideConfig";
|
|
6
|
+
import generate from "./generate";
|
|
7
|
+
import cleanup from "./cleanup";
|
|
8
|
+
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
import reportErrorToRollbar from "./rollbar.mjs";
|
|
11
|
+
import { storeBuildSuccessFlag } from "./utils";
|
|
12
|
+
|
|
13
|
+
const mockPlugin = {
|
|
14
|
+
validate: vi.fn(),
|
|
15
|
+
build: vi.fn(),
|
|
16
|
+
cleanup: vi.fn(),
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
vi.mock("./provideConfig", () => ({
|
|
20
|
+
default: vi.fn(),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
vi.mock("./buildTypes", () => ({
|
|
24
|
+
default: vi.fn(),
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
vi.mock("./rollbar.mjs", () => ({
|
|
28
|
+
default: vi.fn(),
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
vi.mock("./validate", () => ({
|
|
32
|
+
default: vi.fn(),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
vi.mock("./prepare", () => ({
|
|
36
|
+
default: vi.fn(),
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
vi.mock("./generate", () => ({
|
|
40
|
+
default: vi.fn(),
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
vi.mock("./cleanup", () => ({
|
|
44
|
+
default: vi.fn(),
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
vi.mock("./utils", async () => {
|
|
48
|
+
const actual = await vi.importActual("./utils");
|
|
49
|
+
return {
|
|
50
|
+
...actual,
|
|
51
|
+
storeBuildSuccessFlag: vi.fn(),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const config = {
|
|
56
|
+
plugins: [() => mockPlugin],
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
describe("build", () => {
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
vi.mocked(provideConfig).mockResolvedValue(config);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should call all the necessary functions", async () => {
|
|
65
|
+
await build();
|
|
66
|
+
|
|
67
|
+
expect(validate).toHaveBeenCalledWith(config);
|
|
68
|
+
expect(prepare).toHaveBeenCalledWith(config);
|
|
69
|
+
expect(buildTypes).toHaveBeenCalledWith(config);
|
|
70
|
+
|
|
71
|
+
// Plugin
|
|
72
|
+
expect(mockPlugin.validate).toHaveBeenCalledWith(config);
|
|
73
|
+
expect(mockPlugin.build).toHaveBeenCalledWith(config);
|
|
74
|
+
expect(mockPlugin.cleanup).toHaveBeenCalledWith(config);
|
|
75
|
+
|
|
76
|
+
expect(generate).toHaveBeenCalledWith(config, "sdk-react");
|
|
77
|
+
|
|
78
|
+
expect(cleanup).toHaveBeenCalledWith(config);
|
|
79
|
+
expect(storeBuildSuccessFlag).toHaveBeenCalled();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("should call reportErrorToRollbar and exit if an error occurs", async () => {
|
|
83
|
+
vi.spyOn(process, "exit").mockImplementation(() => null as never);
|
|
84
|
+
vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
85
|
+
const error = new Error("test error");
|
|
86
|
+
|
|
87
|
+
vi.mocked(validate).mockRejectedValue(error);
|
|
88
|
+
vi.mocked(reportErrorToRollbar).mockResolvedValue(undefined);
|
|
89
|
+
|
|
90
|
+
await build();
|
|
91
|
+
|
|
92
|
+
expect(reportErrorToRollbar).toHaveBeenCalledWith(error);
|
|
93
|
+
expect(console.log).toHaveBeenCalledWith(error);
|
|
94
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import buildTypes, { EMB_TYPE_FILE_REGEX } from "./buildTypes";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { build } from "vite";
|
|
5
|
+
import { findFiles, getContentHash } from "@embeddable.com/sdk-utils";
|
|
6
|
+
|
|
7
|
+
const config = {
|
|
8
|
+
client: {
|
|
9
|
+
srcDir: "src",
|
|
10
|
+
rootDir: "root",
|
|
11
|
+
buildDir: "build",
|
|
12
|
+
},
|
|
13
|
+
outputOptions: {
|
|
14
|
+
typesEntryPointFilename: "typesEntryPointFilename",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const startMock = {
|
|
19
|
+
succeed: vi.fn(),
|
|
20
|
+
fail: vi.fn(),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
vi.mock("ora", () => ({
|
|
24
|
+
default: () => ({
|
|
25
|
+
start: vi.fn().mockImplementation(() => startMock),
|
|
26
|
+
info: vi.fn(),
|
|
27
|
+
fail: vi.fn(),
|
|
28
|
+
}),
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
vi.mock("@embeddable.com/sdk-utils", () => ({
|
|
32
|
+
findFiles: vi.fn(),
|
|
33
|
+
getContentHash: vi.fn(),
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
vi.mock("node:path", () => ({
|
|
37
|
+
resolve: vi.fn(),
|
|
38
|
+
relative: vi.fn(),
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
vi.mock("node:fs/promises", () => ({
|
|
42
|
+
writeFile: vi.fn(),
|
|
43
|
+
rm: vi.fn(),
|
|
44
|
+
readFile: vi.fn(),
|
|
45
|
+
rename: vi.fn(),
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
vi.mock("vite", () => ({
|
|
49
|
+
build: vi.fn(),
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
describe("buildTypes", () => {
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
vi.mocked(findFiles).mockResolvedValue([["fileName", "filePath"]]);
|
|
55
|
+
vi.mocked(path.relative).mockReturnValue("relativePath");
|
|
56
|
+
vi.mocked(path.resolve).mockReturnValue("resolvedPath");
|
|
57
|
+
vi.mocked(fs.readFile).mockResolvedValue("fileContent");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should build types", async () => {
|
|
61
|
+
await buildTypes(config);
|
|
62
|
+
|
|
63
|
+
expect(findFiles).toHaveBeenCalledWith("src", EMB_TYPE_FILE_REGEX);
|
|
64
|
+
|
|
65
|
+
expect(build).toHaveBeenCalledWith({
|
|
66
|
+
build: {
|
|
67
|
+
emptyOutDir: false,
|
|
68
|
+
lib: {
|
|
69
|
+
entry: "resolvedPath",
|
|
70
|
+
fileName: "embeddable-types",
|
|
71
|
+
formats: ["es"],
|
|
72
|
+
},
|
|
73
|
+
outDir: "build",
|
|
74
|
+
},
|
|
75
|
+
logLevel: "error",
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(fs.readFile).toHaveBeenCalledWith("resolvedPath", "utf8");
|
|
79
|
+
expect(getContentHash).toHaveBeenCalledWith("fileContent");
|
|
80
|
+
|
|
81
|
+
expect(startMock.succeed).toHaveBeenCalledWith("Types built completed");
|
|
82
|
+
|
|
83
|
+
expect(fs.writeFile).toHaveBeenCalledWith(
|
|
84
|
+
"resolvedPath",
|
|
85
|
+
`import '../relativePath';
|
|
86
|
+
import '../relativePath';`,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
expect(fs.rm).toHaveBeenCalledWith("resolvedPath");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should not add hash to the file name when watch is enabled", async () => {
|
|
93
|
+
await buildTypes({ ...config, dev: { watch: true } });
|
|
94
|
+
|
|
95
|
+
expect(getContentHash).not.toHaveBeenCalled();
|
|
96
|
+
expect(fs.rename).not.toHaveBeenCalled();
|
|
97
|
+
});
|
|
98
|
+
});
|
package/src/buildTypes.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as fs from "node:fs/promises";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import * as vite from "vite";
|
|
4
4
|
const oraP = import("ora");
|
|
5
|
-
import { findFiles } from "@embeddable.com/sdk-utils";
|
|
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$/;
|
|
@@ -48,28 +48,36 @@ async function generate(ctx: any) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
async function build(ctx: any) {
|
|
51
|
+
const typesFilePath = path.resolve(
|
|
52
|
+
ctx.client.buildDir,
|
|
53
|
+
ctx.outputOptions.typesEntryPointFilename,
|
|
54
|
+
);
|
|
55
|
+
|
|
51
56
|
await vite.build({
|
|
52
57
|
logLevel: "error",
|
|
53
58
|
build: {
|
|
54
59
|
emptyOutDir: false,
|
|
55
60
|
lib: {
|
|
56
|
-
entry:
|
|
57
|
-
ctx.client.buildDir,
|
|
58
|
-
ctx.outputOptions.typesEntryPointFilename,
|
|
59
|
-
),
|
|
61
|
+
entry: typesFilePath,
|
|
60
62
|
formats: ["es"],
|
|
61
63
|
fileName: "embeddable-types",
|
|
62
64
|
},
|
|
63
|
-
rollupOptions: ctx.dev?.watch
|
|
64
|
-
? undefined
|
|
65
|
-
: {
|
|
66
|
-
output: {
|
|
67
|
-
entryFileNames: "embeddable-types-[hash].js",
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
65
|
outDir: ctx.client.buildDir,
|
|
71
66
|
},
|
|
72
67
|
});
|
|
68
|
+
|
|
69
|
+
if (!ctx.dev?.watch) {
|
|
70
|
+
const fileContent = await fs.readFile(typesFilePath, "utf8");
|
|
71
|
+
|
|
72
|
+
const fileHash = getContentHash(fileContent);
|
|
73
|
+
|
|
74
|
+
const fileName = `embeddable-types-${fileHash}.js`;
|
|
75
|
+
|
|
76
|
+
await fs.rename(
|
|
77
|
+
path.resolve(ctx.client.buildDir, "embeddable-types.js"),
|
|
78
|
+
path.resolve(ctx.client.buildDir, fileName),
|
|
79
|
+
);
|
|
80
|
+
}
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
async function cleanup(ctx: any) {
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { createManifest } from "./cleanup";
|
|
4
|
+
import { findFiles } from "@embeddable.com/sdk-utils";
|
|
5
|
+
|
|
6
|
+
const ctx = {
|
|
7
|
+
client: {
|
|
8
|
+
tmpDir: "tmpDir",
|
|
9
|
+
stencilBuild: "stencilBuild",
|
|
10
|
+
buildDir: "buildDir",
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
vi.mock("node:fs/promises", () => ({
|
|
15
|
+
writeFile: vi.fn(),
|
|
16
|
+
rename: vi.fn(),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
vi.mock("@embeddable.com/sdk-utils", () => ({
|
|
20
|
+
findFiles: vi.fn(),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
vi.mock("node:path", async () => {
|
|
24
|
+
const actual = await vi.importActual("node:path");
|
|
25
|
+
return {
|
|
26
|
+
...actual,
|
|
27
|
+
resolve: vi.fn(),
|
|
28
|
+
basename: vi.fn(),
|
|
29
|
+
join: vi.fn(),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("cleanup", () => {
|
|
34
|
+
describe("createManifest", () => {
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
vi.mocked(fs.writeFile).mockImplementation(async () => undefined);
|
|
37
|
+
vi.mocked(fs.rename).mockImplementation(async () => undefined);
|
|
38
|
+
vi.mocked(findFiles).mockResolvedValue([["", ""]]);
|
|
39
|
+
vi.mocked(path.basename).mockReturnValue("basename");
|
|
40
|
+
vi.mocked(path.join).mockImplementation((...args) => args.join("/"));
|
|
41
|
+
|
|
42
|
+
Object.defineProperties(process, {
|
|
43
|
+
platform: {
|
|
44
|
+
value: "darwin",
|
|
45
|
+
},
|
|
46
|
+
version: {
|
|
47
|
+
value: "v18.20.2",
|
|
48
|
+
},
|
|
49
|
+
env: {
|
|
50
|
+
value: {
|
|
51
|
+
npm_config_user_agent: "npm/10.7.0",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
it("should create manifest", async () => {
|
|
57
|
+
await createManifest({
|
|
58
|
+
ctx,
|
|
59
|
+
typesFileName: "typesFileName",
|
|
60
|
+
metaFileName: "metaFileName",
|
|
61
|
+
editorsMetaFileName: "editorsMetaFileName",
|
|
62
|
+
stencilWrapperFileName: "stencilWrapperFileName",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expect(fs.writeFile).toHaveBeenCalledWith(
|
|
66
|
+
"tmpDir/embeddable-manifest.json",
|
|
67
|
+
JSON.stringify({
|
|
68
|
+
entryFiles: {
|
|
69
|
+
"embeddable-types.js": "typesFileName",
|
|
70
|
+
"embeddable-components-meta.js": "metaFileName",
|
|
71
|
+
"embeddable-editors-meta.js": "editorsMetaFileName",
|
|
72
|
+
"embeddable-wrapper.esm.js": "stencilWrapperFileName",
|
|
73
|
+
},
|
|
74
|
+
metadata: {
|
|
75
|
+
nodeVersion: "v18.20.2",
|
|
76
|
+
platform: "darwin",
|
|
77
|
+
sdkVersions: {},
|
|
78
|
+
packageManager: "npm",
|
|
79
|
+
packageManagerVersion: "10.7.0",
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
package/src/cleanup.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { findFiles } from "@embeddable.com/sdk-utils";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import { getPackageVersion } from "./utils";
|
|
4
5
|
|
|
5
6
|
export default async (ctx: any) => {
|
|
6
7
|
await extractBuild(ctx);
|
|
@@ -10,57 +11,127 @@ export default async (ctx: any) => {
|
|
|
10
11
|
await moveBuildTOBuildDir(ctx);
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
type ManifestArgs = {
|
|
15
|
+
ctx: any;
|
|
16
|
+
typesFileName: string;
|
|
17
|
+
metaFileName: string;
|
|
18
|
+
editorsMetaFileName: string;
|
|
19
|
+
stencilWrapperFileName: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export async function createManifest({
|
|
23
|
+
ctx,
|
|
24
|
+
typesFileName,
|
|
25
|
+
metaFileName,
|
|
26
|
+
editorsMetaFileName,
|
|
27
|
+
stencilWrapperFileName,
|
|
28
|
+
}: ManifestArgs) {
|
|
29
|
+
const packageNames = [
|
|
30
|
+
"@embeddable.com/core",
|
|
31
|
+
"@embeddable.com/react",
|
|
32
|
+
"@embeddable.com/sdk-core",
|
|
33
|
+
"@embeddable.com/sdk-react",
|
|
34
|
+
"@embeddable.com/sdk-utils",
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const sdkVersions = packageNames.reduce<Record<string, string>>(
|
|
38
|
+
(acc, packageName) => {
|
|
39
|
+
const version = getPackageVersion(packageName);
|
|
40
|
+
if (version) {
|
|
41
|
+
acc[packageName] = version;
|
|
42
|
+
}
|
|
43
|
+
return acc;
|
|
44
|
+
},
|
|
45
|
+
{},
|
|
46
|
+
);
|
|
47
|
+
// identify user's package manager and its version
|
|
48
|
+
let packageManager = "npm";
|
|
49
|
+
if (process.env.npm_config_user_agent?.includes("yarn")) {
|
|
50
|
+
packageManager = "yarn";
|
|
51
|
+
}
|
|
52
|
+
if (process.env.npm_config_user_agent?.includes("pnpm")) {
|
|
53
|
+
packageManager = "pnpm";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const packageManagerVersion =
|
|
57
|
+
process.env.npm_config_user_agent?.match(/(\d+\.\d+\.\d+)/)?.[0] ||
|
|
58
|
+
"unknown";
|
|
59
|
+
|
|
60
|
+
// write manifest file with files with hash
|
|
61
|
+
const manifest = {
|
|
62
|
+
entryFiles: {
|
|
63
|
+
"embeddable-types.js": typesFileName,
|
|
64
|
+
"embeddable-components-meta.js": metaFileName,
|
|
65
|
+
"embeddable-editors-meta.js": editorsMetaFileName,
|
|
66
|
+
"embeddable-wrapper.esm.js": stencilWrapperFileName,
|
|
67
|
+
},
|
|
68
|
+
metadata: {
|
|
69
|
+
nodeVersion: process.version,
|
|
70
|
+
platform: process.platform,
|
|
71
|
+
sdkVersions,
|
|
72
|
+
packageManager,
|
|
73
|
+
packageManagerVersion,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
await fs.writeFile(
|
|
78
|
+
path.join(ctx.client.tmpDir, "embeddable-manifest.json"),
|
|
79
|
+
JSON.stringify(manifest),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
13
83
|
async function extractBuild(ctx: any) {
|
|
14
|
-
const
|
|
84
|
+
const stencilBuildFiles = await findFiles(
|
|
15
85
|
ctx.client.stencilBuild,
|
|
16
86
|
/embeddable-wrapper.esm-[a-z0-9]+\.js/,
|
|
17
87
|
);
|
|
18
88
|
|
|
89
|
+
const [[, stencilWrapperFilePath]] = stencilBuildFiles || [];
|
|
90
|
+
|
|
19
91
|
const stencilWrapperFileName = path.basename(stencilWrapperFilePath);
|
|
20
92
|
await fs.rename(
|
|
21
93
|
path.resolve(ctx.client.buildDir, ctx.client.stencilBuild),
|
|
22
94
|
ctx.client.tmpDir,
|
|
23
95
|
);
|
|
24
96
|
|
|
25
|
-
const
|
|
97
|
+
const typesBuildFiles = await findFiles(
|
|
26
98
|
ctx.client.buildDir,
|
|
27
99
|
/embeddable-types-[a-z0-9]+\.js/,
|
|
28
100
|
);
|
|
29
101
|
|
|
102
|
+
const [[, typesFilePath]] = typesBuildFiles || [];
|
|
103
|
+
|
|
30
104
|
const typesFileName = path.basename(typesFilePath);
|
|
31
105
|
await fs.rename(typesFilePath, path.join(ctx.client.tmpDir, typesFileName));
|
|
32
106
|
|
|
33
|
-
const
|
|
107
|
+
const metaBuildFiles = await findFiles(
|
|
34
108
|
ctx.client.buildDir,
|
|
35
109
|
/embeddable-components-meta-[a-z0-9]+\.js/,
|
|
36
110
|
);
|
|
111
|
+
|
|
112
|
+
const [[, metaFilePath]] = metaBuildFiles || [];
|
|
37
113
|
const metaFileName = path.basename(metaFilePath);
|
|
38
114
|
await fs.rename(metaFilePath, path.join(ctx.client.tmpDir, metaFileName));
|
|
39
115
|
|
|
40
|
-
const
|
|
116
|
+
const editorsMetaBuildFiles = await findFiles(
|
|
41
117
|
ctx.client.buildDir,
|
|
42
118
|
/embeddable-editors-meta-[a-z0-9]+\.js/,
|
|
43
119
|
);
|
|
120
|
+
|
|
121
|
+
const [[, editorsMetaFilePath]] = editorsMetaBuildFiles || [];
|
|
44
122
|
const editorsMetaFileName = path.basename(editorsMetaFilePath);
|
|
45
123
|
await fs.rename(
|
|
46
124
|
editorsMetaFilePath,
|
|
47
125
|
path.join(ctx.client.tmpDir, editorsMetaFileName),
|
|
48
126
|
);
|
|
49
127
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
await fs.writeFile(
|
|
61
|
-
path.join(ctx.client.tmpDir, "embeddable-manifest.json"),
|
|
62
|
-
JSON.stringify(manifest),
|
|
63
|
-
);
|
|
128
|
+
await createManifest({
|
|
129
|
+
ctx,
|
|
130
|
+
typesFileName,
|
|
131
|
+
metaFileName,
|
|
132
|
+
editorsMetaFileName,
|
|
133
|
+
stencilWrapperFileName,
|
|
134
|
+
});
|
|
64
135
|
}
|
|
65
136
|
|
|
66
137
|
async function removeObsoleteDir(dir: string) {
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { server } from "./../../../mocks/server";
|
|
2
|
+
import login, { resolveFiles, getToken } from "./login";
|
|
3
|
+
import { vi } from "vitest";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { mkdir, access, writeFile, readFile } from "fs/promises";
|
|
7
|
+
import { CREDENTIALS_DIR, CREDENTIALS_FILE } from "./credentials";
|
|
8
|
+
import { http, HttpResponse } from "msw";
|
|
9
|
+
import { AxiosError } from "axios";
|
|
10
|
+
|
|
11
|
+
vi.mock("fs/promises", () => ({
|
|
12
|
+
readFile: vi.fn(),
|
|
13
|
+
writeFile: vi.fn(),
|
|
14
|
+
access: vi.fn(),
|
|
15
|
+
mkdir: vi.fn(),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
const startMock = {
|
|
19
|
+
succeed: vi.fn(),
|
|
20
|
+
fail: vi.fn(),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
vi.mock("ora", () => ({
|
|
24
|
+
default: () => ({
|
|
25
|
+
start: vi.fn().mockImplementation(() => startMock),
|
|
26
|
+
info: vi.fn(),
|
|
27
|
+
}),
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
vi.mock("./rollbar.mjs", () => ({
|
|
31
|
+
default: vi.fn(),
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
vi.mock("open", () => ({
|
|
35
|
+
default: vi.fn(),
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
vi.mock("node:fs", () => ({
|
|
39
|
+
existsSync: vi.fn(),
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
vi.mock("node:url", () => ({
|
|
43
|
+
pathToFileURL: vi.fn(),
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
vi.mock(`${process.cwd()}/embeddable.config.ts`, () => ({
|
|
47
|
+
default: {
|
|
48
|
+
authDomain: "test-domain.com",
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
describe("login", () => {
|
|
53
|
+
beforeEach(async () => {
|
|
54
|
+
vi.mocked(readFile).mockImplementation(async () =>
|
|
55
|
+
Buffer.from(`{"access_token":"mocked-token"}`),
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
vi.mocked(access).mockImplementation(async () => {
|
|
59
|
+
throw new Error();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
vi.mocked(mkdir).mockImplementation(async () => "mocked");
|
|
63
|
+
|
|
64
|
+
vi.mocked(writeFile).mockImplementation(async () => undefined);
|
|
65
|
+
|
|
66
|
+
vi.mocked(existsSync).mockImplementation(() => true);
|
|
67
|
+
vi.mocked(pathToFileURL).mockImplementation(
|
|
68
|
+
() => new URL("mocked-config-path"),
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
vi.mock("./reportErrorToRollbar", () => vi.fn());
|
|
73
|
+
vi.mock("./sleep", () => vi.fn());
|
|
74
|
+
|
|
75
|
+
it("should resolve files", async () => {
|
|
76
|
+
await resolveFiles();
|
|
77
|
+
|
|
78
|
+
expect(access).toHaveBeenCalledWith(CREDENTIALS_DIR);
|
|
79
|
+
expect(mkdir).toHaveBeenCalledWith(CREDENTIALS_DIR);
|
|
80
|
+
expect(writeFile).toHaveBeenCalledWith(CREDENTIALS_FILE, "");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("should get token", async () => {
|
|
84
|
+
const token = await getToken();
|
|
85
|
+
|
|
86
|
+
expect(token).toBe("mocked-token");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("should login by saving token in the credentials file", async () => {
|
|
90
|
+
await login();
|
|
91
|
+
expect(startMock.succeed).toHaveBeenCalledWith(
|
|
92
|
+
"You are successfully authenticated now!",
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
expect(writeFile).toHaveBeenCalledWith(
|
|
96
|
+
CREDENTIALS_FILE,
|
|
97
|
+
JSON.stringify({ access_token: "mocked-token " }),
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("should fail to login when the response returns 500 error", async () => {
|
|
102
|
+
vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
103
|
+
vi.spyOn(process, "exit").mockImplementation(() => undefined as never);
|
|
104
|
+
|
|
105
|
+
server.use(
|
|
106
|
+
http.post("**/oauth/device/code", () => {
|
|
107
|
+
return new HttpResponse(null, { status: 500 });
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
await login();
|
|
112
|
+
|
|
113
|
+
expect(startMock.fail).toHaveBeenCalledWith(
|
|
114
|
+
"Authentication failed. Please try again.",
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
expect(console.log).toHaveBeenCalledWith(
|
|
118
|
+
new AxiosError("Request failed with status code 500"),
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
});
|
package/src/login.ts
CHANGED