110 lines
3.9 KiB
JavaScript
110 lines
3.9 KiB
JavaScript
|
|
import { addTemplate, defineNuxtModule, useNitro } from "@nuxt/kit";
|
||
|
|
import { Buffer } from "node:buffer";
|
||
|
|
import EventEmitter from "node:events";
|
||
|
|
import { mkdir, open, readFile, writeFile } from "node:fs/promises";
|
||
|
|
import { watch } from "chokidar";
|
||
|
|
import { dirname, join } from "pathe";
|
||
|
|
|
||
|
|
//#region package.json
|
||
|
|
var name = "@dxup/nuxt";
|
||
|
|
|
||
|
|
//#endregion
|
||
|
|
//#region src/event/client.ts
|
||
|
|
const responseRE = /^```json \{(?<key>.*)\}\n(?<value>[\s\S]*?)\n```$/;
|
||
|
|
async function createEventClient(nuxt) {
|
||
|
|
const path = join(nuxt.options.buildDir, "dxup/events.md");
|
||
|
|
await mkdir(dirname(path), { recursive: true });
|
||
|
|
await writeFile(path, "");
|
||
|
|
const fd = await open(path, "r");
|
||
|
|
const watcher = watch(path, { ignoreInitial: true });
|
||
|
|
nuxt.hook("close", async () => {
|
||
|
|
await fd.close();
|
||
|
|
await watcher.close();
|
||
|
|
});
|
||
|
|
const client = new EventEmitter();
|
||
|
|
let offset = 0;
|
||
|
|
watcher.on("change", async (path$1, stats) => {
|
||
|
|
if (!stats || stats.size <= offset) return;
|
||
|
|
const pos = offset;
|
||
|
|
offset = stats.size;
|
||
|
|
const buffer = Buffer.alloc(offset - pos);
|
||
|
|
await fd.read(buffer, 0, buffer.length, pos);
|
||
|
|
const match = buffer.toString("utf-8").trim().match(responseRE);
|
||
|
|
if (match) {
|
||
|
|
const { key, value } = match.groups;
|
||
|
|
client.emit(key, JSON.parse(value));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return client;
|
||
|
|
}
|
||
|
|
|
||
|
|
//#endregion
|
||
|
|
//#region src/module/events.ts
|
||
|
|
const uppercaseRE = /[A-Z]/;
|
||
|
|
async function onComponentsRename(nuxt, { fileName, references }) {
|
||
|
|
const component = Object.values(nuxt.apps).flatMap((app) => app.components).find((c) => c.filePath === fileName);
|
||
|
|
if (!component) return;
|
||
|
|
const tasks = Object.entries(references).map(async ([fileName$1, references$1]) => {
|
||
|
|
const code = await readFile(fileName$1, "utf-8");
|
||
|
|
const chunks = [];
|
||
|
|
let offset = 0;
|
||
|
|
for (const { textSpan, lazy } of references$1) {
|
||
|
|
const start = textSpan.start;
|
||
|
|
const end = start + textSpan.length;
|
||
|
|
const oldName = code.slice(start, end);
|
||
|
|
const newName = uppercaseRE.test(oldName) ? lazy ? "Lazy" + component.pascalName : component.pascalName : lazy ? "lazy-" + component.kebabName : component.kebabName;
|
||
|
|
chunks.push(code.slice(offset, start), newName);
|
||
|
|
offset = end;
|
||
|
|
}
|
||
|
|
chunks.push(code.slice(offset));
|
||
|
|
await writeFile(fileName$1, chunks.join(""));
|
||
|
|
});
|
||
|
|
await Promise.all(tasks);
|
||
|
|
}
|
||
|
|
|
||
|
|
//#endregion
|
||
|
|
//#region src/module/index.ts
|
||
|
|
var module_default = defineNuxtModule({
|
||
|
|
meta: {
|
||
|
|
name,
|
||
|
|
configKey: "dxup"
|
||
|
|
},
|
||
|
|
defaults: { features: {
|
||
|
|
components: true,
|
||
|
|
importGlob: true,
|
||
|
|
nitroRoutes: true,
|
||
|
|
runtimeConfig: true,
|
||
|
|
unimport: true
|
||
|
|
} },
|
||
|
|
async setup(options, nuxt) {
|
||
|
|
const pluginsTs = [{ name: "@dxup/nuxt" }];
|
||
|
|
if (options.features?.unimport) pluginsTs.unshift({ name: "@dxup/unimport" });
|
||
|
|
append(pluginsTs, nuxt.options, "typescript", "tsConfig", "compilerOptions");
|
||
|
|
append(pluginsTs, nuxt.options.nitro, "typescript", "tsConfig", "compilerOptions");
|
||
|
|
append(pluginsTs, nuxt.options, "typescript", "sharedTsConfig", "compilerOptions");
|
||
|
|
append(pluginsTs, nuxt.options, "typescript", "nodeTsConfig", "compilerOptions");
|
||
|
|
addTemplate({
|
||
|
|
filename: "dxup/data.json",
|
||
|
|
write: true,
|
||
|
|
getContents({ nuxt: nuxt$1 }) {
|
||
|
|
const nitro = useNitro();
|
||
|
|
const data = {
|
||
|
|
buildDir: nuxt$1.options.buildDir,
|
||
|
|
publicDir: nuxt$1.options.dir.public,
|
||
|
|
configFiles: [...nuxt$1.options._nuxtConfigFiles, ...nuxt$1.options._layers.map((layer) => layer._configFile).filter(Boolean)],
|
||
|
|
nitroRoutes: Object.fromEntries(nitro.scannedHandlers.filter((item) => item.route).map((item) => [`${item.route}+${item.method ?? "get"}`, item.handler])),
|
||
|
|
features: options.features
|
||
|
|
};
|
||
|
|
return JSON.stringify(data, null, 2);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
if (nuxt.options.dev) (await createEventClient(nuxt)).on("components:rename", (data) => onComponentsRename(nuxt, data));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
function append(plugins, target, ...keys) {
|
||
|
|
for (const key of keys) target = target[key] ??= {};
|
||
|
|
(target.plugins ??= []).push(...plugins);
|
||
|
|
}
|
||
|
|
|
||
|
|
//#endregion
|
||
|
|
export { module_default as default };
|