@embeddable.com/sdk-core
Version:
Core Embeddable SDK module responsible for web-components bundling and publishing.
168 lines (147 loc) • 4.34 kB
text/typescript
import generate from "./generate";
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { checkNodeVersion } from "./utils";
import { loadConfig, createCompiler } from "@stencil/core/compiler";
import { findFiles, getContentHash } from "@embeddable.com/sdk-utils";
import { ResolvedEmbeddableConfig } from "./defineConfig";
const config = {
client: {
rootDir: "rootDir",
srcDir: "srcDir",
buildDir: "buildDir",
tmpDir: "tmpDir",
stencilBuild: "stencilBuild",
componentDir: "componentDir",
webComponentRoot: "webComponentRoot",
bundleHash: "hash",
componentLibraries: [],
},
core: {
rootDir: "rootDir",
templatesDir: "templatesDir",
configsDir: "configsDir",
},
"sdk-react": {
rootDir: "rootDir",
templatesDir: "templatesDir",
configsDir: "configsDir",
outputOptions: {
buildName: "buildName",
},
},
};
vi.mock("@embeddable.com/sdk-utils", () => ({
getContentHash: vi.fn(),
findFiles: vi.fn(),
}));
vi.mock("./utils", () => ({
checkNodeVersion: vi.fn(),
}));
vi.mock("./provideConfig", () => ({
provideConfig: vi.fn().mockResolvedValue(config),
}));
vi.mock("node:fs/promises", () => ({
writeFile: vi.fn(),
readdir: vi.fn(),
readFile: vi.fn(),
rename: vi.fn(),
cp: vi.fn(),
rm: vi.fn(),
}));
vi.mock("node:path", async () => {
const actual = await vi.importActual("node:path");
return {
...actual,
resolve: vi.fn(),
join: vi.fn(),
};
});
vi.mock("@stencil/core/compiler", () => ({
createCompiler: vi.fn(),
loadConfig: vi.fn(),
}));
describe("generate", () => {
beforeEach(() => {
vi.mocked(checkNodeVersion).mockResolvedValue(true);
vi.mocked(fs.readdir).mockResolvedValue([
"embeddable-wrapper.esm.js",
"embeddable-wrapper.esm.js.map",
"styles.css",
] as any);
vi.mocked(path.resolve).mockImplementation((...args) => args.join("/"));
vi.mocked(fs.readFile).mockResolvedValue("");
vi.mocked(loadConfig).mockResolvedValue({
config: {},
} as any);
vi.mocked(createCompiler).mockResolvedValue({
build: vi.fn().mockResolvedValue({
hasError: false,
}),
destroy: vi.fn(),
} as any);
vi.mocked(getContentHash).mockReturnValue("hash");
vi.mocked(findFiles).mockResolvedValue([["", ""]]);
Object.defineProperties(process, {
chdir: {
value: vi.fn(),
},
});
});
it("should generate bundle", async () => {
await generate(config as unknown as ResolvedEmbeddableConfig, "sdk-react");
// should inject css
expect(fs.writeFile).toHaveBeenCalledWith("componentDir/style.css", "");
// should inject bundle renderer
expect(fs.writeFile).toHaveBeenCalledWith("componentDir/component.tsx", "");
expect(loadConfig).toHaveBeenCalled();
expect(createCompiler).toHaveBeenCalledWith({});
// check if the file is renamed
expect(fs.rename).toHaveBeenCalledWith(
"stencilBuild/embeddable-wrapper.esm.js",
"stencilBuild/embeddable-wrapper.esm-hash.js",
);
});
it("should generate bundle in dev mode", async () => {
const ctx = {
...config,
dev: {
watch: true,
logger: vi.fn(),
sys: vi.fn(),
},
};
vi.mocked(fs.readFile).mockResolvedValue(
"replace-this-with-component-name",
);
await generate(ctx as unknown as ResolvedEmbeddableConfig, "sdk-react");
expect(createCompiler).toHaveBeenCalled();
expect(fs.writeFile).toHaveBeenCalledWith(
"componentDir/component.tsx",
expect.stringContaining("embeddable-component"),
);
expect(loadConfig).toHaveBeenCalledWith({
config: {
configPath: "webComponentRoot/stencil.config.ts",
devMode: true,
maxConcurrentWorkers: process.platform === "win32" ? 0 : 8,
minifyCss: false,
minifyJs: false,
namespace: "embeddable-wrapper",
outputTargets: [
{
type: "dist",
buildDir: "buildDir/dist",
},
],
rootDir: "webComponentRoot",
sourceMap: true,
srcDir: "componentDir",
tsconfig: "webComponentRoot/tsconfig.json",
},
initTsConfig: true,
logger: expect.any(Function),
sys: expect.any(Function),
});
});
});