Files
DeviceManager/node_modules/@vite-pwa/sveltekit/dist/index.mjs

235 lines
8.3 KiB
JavaScript

import { VitePWA } from 'vite-plugin-pwa';
import { mkdir, rm, readFile, writeFile, lstat } from 'node:fs/promises';
import { join } from 'node:path';
import fg from 'fast-glob';
function configureSvelteKitOptions(kit, viteOptions, options) {
const {
base = viteOptions.base ?? "/",
adapterFallback,
outDir = `${viteOptions.root}/.svelte-kit`
} = kit;
if (typeof options.includeManifestIcons === "undefined")
options.includeManifestIcons = false;
let config;
if (options.strategies === "injectManifest") {
if (!options.srcDir)
options.srcDir = "src";
if (!options.filename)
options.filename = "service-worker.js";
options.injectManifest = options.injectManifest ?? {};
config = options.injectManifest;
} else {
options.workbox = options.workbox ?? {};
if (!options.workbox.navigateFallback)
options.workbox.navigateFallback = adapterFallback ?? base;
config = options.workbox;
}
if (!config.globDirectory)
config.globDirectory = `${outDir}/output`;
if (!config.modifyURLPrefix)
config.globPatterns = buildGlobPatterns(config.globPatterns);
config.globIgnores = buildGlobIgnores(config.globIgnores);
if (!config.manifestTransforms) {
config.manifestTransforms = [createManifestTransform(
base,
options.strategies === "injectManifest" ? void 0 : options.manifestFilename ?? "manifest.webmanifest",
kit
)];
}
}
function createManifestTransform(base, webManifestName, options) {
return async (entries) => {
const defaultAdapterFallback = "prerendered/fallback.html";
const suffix = options?.trailingSlash === "always" ? "/" : "";
let adapterFallback = options?.adapterFallback;
let excludeFallback = false;
if (!adapterFallback) {
adapterFallback = defaultAdapterFallback;
excludeFallback = true;
}
const manifest = entries.filter(({ url }) => !(excludeFallback && url === defaultAdapterFallback)).map((e) => {
let url = e.url;
if (url.startsWith("client/"))
url = url.slice(7);
else if (url.startsWith("prerendered/pages/"))
url = url.slice(18);
else if (url === defaultAdapterFallback)
url = adapterFallback;
if (url.endsWith(".html")) {
if (url.startsWith("/"))
url = url.slice(1);
if (url === "index.html") {
url = base;
} else {
const idx = url.lastIndexOf("/");
if (idx > -1) {
if (url.endsWith("/index.html"))
url = `${url.slice(0, idx)}${suffix}`;
else
url = `${url.substring(0, url.lastIndexOf("."))}${suffix}`;
} else {
url = `${url.substring(0, url.lastIndexOf("."))}${suffix}`;
}
}
}
e.url = url;
return e;
});
if (!webManifestName)
return { manifest };
return { manifest: manifest.filter((e) => e.url !== webManifestName) };
};
}
function buildGlobPatterns(globPatterns) {
if (globPatterns) {
if (!globPatterns.some((g) => g.startsWith("prerendered/")))
globPatterns.push("prerendered/**/*.html");
if (!globPatterns.some((g) => g.startsWith("client/")))
globPatterns.push("client/**/*.{js,css,ico,png,svg,webp,webmanifest}");
if (!globPatterns.some((g) => g.includes("webmanifest")))
globPatterns.push("client/*.webmanifest");
return globPatterns;
}
return ["client/**/*.{js,css,ico,png,svg,webp,webmanifest}", "prerendered/**/*.html"];
}
function buildGlobIgnores(globIgnores) {
if (globIgnores) {
if (!globIgnores.some((g) => g.startsWith("server/")))
globIgnores.push("server/*.*");
return globIgnores;
}
return ["server/*.*"];
}
function SvelteKitPlugin(options, apiResolver) {
let viteConfig;
return {
name: "vite-plugin-pwa:sveltekit:build",
apply: "build",
enforce: "pre",
configResolved(config) {
viteConfig = config;
},
generateBundle(_, bundle) {
if (viteConfig.build.ssr)
return;
apiResolver()?.generateBundle(bundle);
},
closeBundle: {
sequential: true,
enforce: "pre",
async handler() {
const api = apiResolver();
if (api && !api.disabled && viteConfig.build.ssr) {
const webManifest = options.manifestFilename ?? "manifest.webmanifest";
let swName = options.filename ?? "sw.js";
const outDir = options.outDir ?? `${viteConfig.root}/.svelte-kit/output`;
const clientOutputDir = join(outDir, "client");
await mkdir(clientOutputDir, { recursive: true });
if (!options.strategies || options.strategies === "generateSW" || options.selfDestroying) {
let path;
let existsFile;
if (options.selfDestroying && options.strategies === "injectManifest") {
if (swName.endsWith(".ts"))
swName = swName.replace(/\.ts$/, ".js");
path = join(clientOutputDir, "service-worker.js").replace("\\/g", "/");
existsFile = await isFile(path);
if (existsFile)
await rm(path);
}
await api.generateSW();
const serverOutputDir = join(outDir, "server");
path = join(serverOutputDir, swName).replace(/\\/g, "/");
existsFile = await isFile(path);
if (existsFile) {
const sw = await readFile(path, "utf-8");
await writeFile(
join(clientOutputDir, swName).replace("\\/g", "/"),
sw,
"utf-8"
);
await rm(path);
}
const result = await fg(
["workbox-*.js"],
{
cwd: serverOutputDir,
onlyFiles: true,
unique: true
}
);
if (result && result.length > 0) {
path = join(serverOutputDir, result[0]).replace(/\\/g, "/");
await writeFile(
join(clientOutputDir, result[0]).replace("\\/g", "/"),
await readFile(path, "utf-8"),
"utf-8"
);
await rm(path);
}
path = join(serverOutputDir, webManifest).replace(/\\/g, "/");
existsFile = await isFile(path);
if (existsFile)
await rm(path);
return;
}
if (swName.endsWith(".ts"))
swName = swName.replace(/\.ts$/, ".js");
const injectManifestOptions = {
globDirectory: outDir.replace(/\\/g, "/"),
...options.injectManifest ?? {},
swSrc: join(clientOutputDir, "service-worker.js").replace(/\\/g, "/"),
swDest: join(clientOutputDir, "service-worker.js").replace(/\\/g, "/")
};
const [injectManifest, logWorkboxResult] = await Promise.all([
import('workbox-build').then((m) => m.injectManifest),
import('./chunks/log.mjs').then((m) => m.logWorkboxResult)
]);
const buildResult = await injectManifest(injectManifestOptions);
logWorkboxResult("injectManifest", buildResult, viteConfig);
if (swName !== "service-worker.js") {
await writeFile(
join(clientOutputDir, swName).replace("\\/g", "/"),
await readFile(injectManifestOptions.swSrc, "utf-8"),
"utf-8"
);
await rm(injectManifestOptions.swDest);
}
}
}
}
};
}
async function isFile(path) {
try {
const stats = await lstat(path);
return stats.isFile();
} catch {
return false;
}
}
function SvelteKitPWA(userOptions = {}) {
if (!userOptions.integration)
userOptions.integration = {};
userOptions.integration.closeBundleOrder = "pre";
userOptions.integration.configureOptions = (viteConfig, options) => configureSvelteKitOptions(
userOptions.kit ?? {},
viteConfig,
options
);
const plugins = VitePWA(userOptions);
const plugin = plugins.find((p) => p && typeof p === "object" && "name" in p && p.name === "vite-plugin-pwa");
const resolveVitePluginPWAAPI = () => {
return plugin?.api;
};
return [
// remove the build plugin: we're using a custom one
...plugins.filter((p) => p && typeof p === "object" && "name" in p && p.name !== "vite-plugin-pwa:build"),
SvelteKitPlugin(userOptions, resolveVitePluginPWAAPI)
];
}
export { SvelteKitPWA };