import { existsSync, mkdtempSync, rmSync, writeFileSync, mkdirSync, readFileSync, symlinkSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { spawnSync } from "node:child_process";
const root = new URL("..", import.meta.url).pathname;
const workdir = mkdtempSync(join(tmpdir(), "gnexus-ui-kit-vue-pack-"));
const appdir = join(workdir, "consumer");
const npmCache = join(workdir, "npm-cache");
const exampleNodeModules = join(root, "examples/vue/node_modules");
const packageJson = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
if (!existsSync(join(exampleNodeModules, "vue")) || !existsSync(join(exampleNodeModules, "vite"))) {
throw new Error("Run npm --prefix examples/vue install before npm run test:vue-package");
}
function run(command, args, options = {}) {
const result = spawnSync(command, args, {
cwd: options.cwd || root,
env: {
...process.env,
npm_config_cache: npmCache
},
stdio: "inherit",
shell: false
});
if (result.status !== 0) {
throw new Error(`${command} ${args.join(" ")} failed`);
}
}
function writeConsumerApp(tarball) {
mkdirSync(join(appdir, "src"), { recursive: true });
mkdirSync(join(appdir, "node_modules/gnexus-ui-kit"), { recursive: true });
writeFileSync(
join(appdir, "package.json"),
`${JSON.stringify(
{
private: true,
type: "module",
scripts: {
build: "vite build"
},
dependencies: {
"gnexus-ui-kit": `file:${tarball}`,
vue: "^3.5.22"
},
devDependencies: {}
},
null,
2
)}\n`
);
writeFileSync(
join(appdir, "index.html"),
`<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GNexus Vue Package Smoke</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
`
);
writeFileSync(
join(appdir, "src/main.js"),
`import { createApp, ref } from "vue";
import "gnexus-ui-kit/dist/css/kit.css";
import "gnexus-ui-kit/dist/assets/fonts/phosphor-icons/src/css/icons.css";
import { GnButton, GnInput, GnModal, GnTabs, GnToastProvider, useToast } from "gnexus-ui-kit/vue";
const SmokeScreen = {
components: { GnButton, GnInput, GnModal, GnTabs },
setup() {
const open = ref(false);
const name = ref("GNexus");
const tab = ref("one");
const toast = useToast();
const tabs = [
{ id: "one", label: "One" },
{ id: "two", label: "Two" }
];
function showToast() {
toast.success({ title: "Ready", text: name.value });
}
return { open, name, tab, tabs, showToast };
},
template: \`
<main class="container py-4">
<GnInput v-model="name" label="Name" />
<GnTabs v-model="tab" :items="tabs">
<template #one>First tab</template>
<template #two>Second tab</template>
</GnTabs>
<GnButton variant="accent" icon="ph-sparkle" @click="showToast">Toast</GnButton>
<GnButton variant="secondary" @click="open = true">Modal</GnButton>
<GnModal v-model:open="open" title="Pack smoke">
Imported from tarball.
</GnModal>
</main>
\`
};
createApp({
components: { GnToastProvider, SmokeScreen },
template: \`
<GnToastProvider>
<SmokeScreen />
</GnToastProvider>
\`
}).mount("#app");
`
);
}
function installPackedKit(tarball) {
run("tar", ["-xzf", tarball, "--strip-components=1", "-C", join(appdir, "node_modules/gnexus-ui-kit")]);
symlinkSync(join(exampleNodeModules, "vue"), join(appdir, "node_modules/vue"), "dir");
}
try {
run("npm", ["run", "build"]);
run("npm", ["pack", "--pack-destination", workdir]);
const tarball = join(workdir, `gnexus-ui-kit-${packageJson.version}.tgz`);
writeConsumerApp(tarball);
installPackedKit(tarball);
run("node", [join(exampleNodeModules, "vite/bin/vite.js"), "build"], { cwd: appdir });
} finally {
rmSync(workdir, { recursive: true, force: true });
}