@vite-pwa/nuxt 1.1.1 → 2.0.1
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/README.md +28 -59
- package/config/index.d.mts +1 -0
- package/config/index.mjs +3 -0
- package/configuration.d.ts +3 -0
- package/dist/chunks/create-nuxt-pwa-context.mjs +27 -0
- package/dist/chunks/prepare-module.mjs +871 -0
- package/dist/chunks/prepare-pwa-icons.mjs +161 -0
- package/dist/module.d.mts +42 -89
- package/dist/module.json +4 -4
- package/dist/module.mjs +40 -8
- package/dist/runtime/components/NuxtPwaAssets.d.ts +1 -1
- package/dist/runtime/components/NuxtPwaAssets.js +8 -4
- package/dist/runtime/components/{VitePwaManifest.d.ts → NuxtPwaManifest.d.ts} +1 -1
- package/dist/runtime/components/{VitePwaManifest.js → NuxtPwaManifest.js} +2 -2
- package/dist/runtime/{composables/index.d.ts → composables.d.ts} +12 -28
- package/dist/runtime/{composables/index.js → composables.js} +1 -11
- package/dist/runtime/plugins/pwa-install.client.d.ts +6 -0
- package/dist/runtime/plugins/pwa-install.client.js +70 -0
- package/dist/runtime/plugins/pwa.client.d.ts +1 -1
- package/dist/runtime/plugins/pwa.client.js +90 -77
- package/dist/runtime/plugins/types.d.ts +70 -129
- package/dist/runtime/plugins/types.js +0 -0
- package/dist/types.d.mts +5 -5
- package/package.json +40 -59
- package/dist/chunks/dev.mjs +0 -37
- package/dist/chunks/pwa-icons.mjs +0 -155
- package/dist/module.cjs +0 -5
- package/dist/module.d.ts +0 -110
- package/dist/runtime/components/PwaAppleImage.vue +0 -12
- package/dist/runtime/components/PwaAppleImage.vue.d.ts +0 -2
- package/dist/runtime/components/PwaAppleSplashScreenImage.vue +0 -12
- package/dist/runtime/components/PwaAppleSplashScreenImage.vue.d.ts +0 -2
- package/dist/runtime/components/PwaFaviconImage.vue +0 -12
- package/dist/runtime/components/PwaFaviconImage.vue.d.ts +0 -2
- package/dist/runtime/components/PwaMaskableImage.vue +0 -12
- package/dist/runtime/components/PwaMaskableImage.vue.d.ts +0 -2
- package/dist/runtime/components/PwaTransparentImage.vue +0 -12
- package/dist/runtime/components/PwaTransparentImage.vue.d.ts +0 -2
- package/dist/runtime/components/nuxt4/PwaAppleImage.d.ts +0 -4
- package/dist/runtime/components/nuxt4/PwaAppleImage.js +0 -15
- package/dist/runtime/components/nuxt4/PwaAppleSplashScreenImage.d.ts +0 -4
- package/dist/runtime/components/nuxt4/PwaAppleSplashScreenImage.js +0 -15
- package/dist/runtime/components/nuxt4/PwaFaviconImage.d.ts +0 -4
- package/dist/runtime/components/nuxt4/PwaFaviconImage.js +0 -15
- package/dist/runtime/components/nuxt4/PwaMaskableImage.d.ts +0 -4
- package/dist/runtime/components/nuxt4/PwaMaskableImage.js +0 -15
- package/dist/runtime/components/nuxt4/PwaTransparentImage.d.ts +0 -4
- package/dist/runtime/components/nuxt4/PwaTransparentImage.js +0 -15
- package/dist/shared/nuxt.9518178d.mjs +0 -734
- package/dist/types.d.ts +0 -15
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
import fs, { promises, existsSync } from 'node:fs';
|
|
2
|
+
import { addTemplate, addPluginTemplate, useLogger, addPlugin, addComponent, addImports } from '@nuxt/kit';
|
|
3
|
+
import { resolveDefaultConfig } from '@unplugin-pwa/core/config';
|
|
4
|
+
import { preparePWAAssetsGenerator, normalizeManifest, normalizePath as normalizePath$1, preparePWAStrategy } from '@unplugin-pwa/core/helpers';
|
|
5
|
+
import { loadPwaConfiguration } from '@vite-pwa/nuxt-core';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { generateWebManifest } from '@unplugin-pwa/core/generate-web-manifest';
|
|
8
|
+
import { INSPECTOR_BASE_PATH_URL, INSPECTOR_BASE_PATH } from '@unplugin-pwa/core/constants';
|
|
9
|
+
import { defu } from 'defu';
|
|
10
|
+
import { access, lstat } from 'node:fs/promises';
|
|
11
|
+
import { prepareSwNamesAndGlobDirectory } from '@unplugin-pwa/core/dev/prepare-sw-names-and-glob-directory';
|
|
12
|
+
import process from 'node:process';
|
|
13
|
+
import { resolveSWNames, normalizePath, extractSwDestNameFromSource } from '@vite-pwa/workbox-build/utils/resolve-sw-names';
|
|
14
|
+
import { hash } from 'node:crypto';
|
|
15
|
+
import { getMajor } from 'verkit';
|
|
16
|
+
import { createRequire } from 'node:module';
|
|
17
|
+
|
|
18
|
+
async function buildPwaAssets(ctx, nuxt) {
|
|
19
|
+
const pwaAssetsGenerator = await ctx.pwaAssetsGenerator;
|
|
20
|
+
if (pwaAssetsGenerator) {
|
|
21
|
+
await pwaAssetsGenerator.generate();
|
|
22
|
+
pwaAssetsGenerator.injectManifestIcons();
|
|
23
|
+
}
|
|
24
|
+
if (ctx.resolvedOptions.manifest) {
|
|
25
|
+
const webManifest = generateWebManifest(ctx);
|
|
26
|
+
await promises.writeFile(
|
|
27
|
+
path.resolve(ctx.outDir, ctx.resolvedOptions.manifestFilename || "manifest.webmanifest"),
|
|
28
|
+
webManifest,
|
|
29
|
+
"utf-8"
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
if (!ctx.resolvedOptions.disable) {
|
|
33
|
+
await nuxt.callHook("pwa:beforeBuildServiceWorker", ctx.resolvedOptions);
|
|
34
|
+
await ctx.runBuild();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function buildBeforeHook(ctx) {
|
|
39
|
+
return async () => {
|
|
40
|
+
await ctx.nuxt.prepareNuxtOptions();
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function devtoolsCustomTabsHook(ctx) {
|
|
45
|
+
return (tabs) => {
|
|
46
|
+
if (ctx.resolvedOptions.devOptions?.inspector) {
|
|
47
|
+
tabs.push({
|
|
48
|
+
title: "Unplugin PWA Inspector",
|
|
49
|
+
name: "vite-pwa:nuxt:inspector",
|
|
50
|
+
icon: `${INSPECTOR_BASE_PATH}/icon_gray.svg`,
|
|
51
|
+
view: {
|
|
52
|
+
type: "iframe",
|
|
53
|
+
src: INSPECTOR_BASE_PATH_URL
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function nitroConfigHook(ctx, nuxt) {
|
|
61
|
+
return (nitroConfig) => {
|
|
62
|
+
if (nuxt.options.experimental.payloadExtraction) {
|
|
63
|
+
ctx.nuxt.enableGlobPatterns = !!nuxt.options.nitro.static || !!nitroConfig.prerender?.routes?.length || Object.values(nitroConfig.routeRules ?? {}).some((r) => r.prerender);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function initPwaAssetsGenerator(ctx, nuxt) {
|
|
69
|
+
if (ctx.resolvedOptions.pwaAssets) {
|
|
70
|
+
const config = ctx.resolvedOptions.pwaAssets.config;
|
|
71
|
+
if (typeof config === "string") {
|
|
72
|
+
ctx.resolvedOptions.pwaAssets.config = await ctx.nuxt.moduleResolver.resolvePath(
|
|
73
|
+
config,
|
|
74
|
+
{
|
|
75
|
+
cwd: nuxt.options.rootDir,
|
|
76
|
+
alias: nuxt.options.alias
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
ctx.resolvedOptions.pwaAssets.integration = {
|
|
81
|
+
baseUrl: ctx.base,
|
|
82
|
+
publicDir: ctx.publicDir,
|
|
83
|
+
outDir: ctx.outDir,
|
|
84
|
+
resolveImage: resolveImageFactory(ctx, nuxt)
|
|
85
|
+
};
|
|
86
|
+
preparePWAAssetsGenerator(ctx);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function checkFileExists(pathname) {
|
|
90
|
+
try {
|
|
91
|
+
await access(pathname, fs.constants.R_OK);
|
|
92
|
+
} catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
function* preparePaths(nuxt, imageName, layers = false) {
|
|
98
|
+
if (layers) {
|
|
99
|
+
for (const [idx, layer] of nuxt.options._layers.entries()) {
|
|
100
|
+
if (idx === 0) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
yield path.resolve(layer.config.rootDir, imageName);
|
|
104
|
+
yield path.resolve(layer.config.srcDir, imageName);
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (nuxt.options.nitro.publicAssets) {
|
|
109
|
+
for (const publicAsset of nuxt.options.nitro.publicAssets) {
|
|
110
|
+
if (publicAsset?.dir) {
|
|
111
|
+
yield path.resolve(publicAsset.dir, imageName);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
yield path.resolve(nuxt.options.rootDir, imageName);
|
|
116
|
+
yield path.resolve(nuxt.options.srcDir, imageName);
|
|
117
|
+
}
|
|
118
|
+
async function* tryToResolveImage(ctx, nuxt, imageName) {
|
|
119
|
+
for (const imagePath of preparePaths(nuxt, imageName)) {
|
|
120
|
+
if (await checkFileExists(imagePath)) {
|
|
121
|
+
yield imagePath;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const imagePath = await ctx.nuxt.moduleResolver.resolvePath(imageName, {
|
|
126
|
+
cwd: nuxt.options.rootDir,
|
|
127
|
+
alias: nuxt.options.alias
|
|
128
|
+
});
|
|
129
|
+
if (await checkFileExists(imagePath)) {
|
|
130
|
+
yield imagePath;
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
for (const imagePath of preparePaths(nuxt, imageName, true)) {
|
|
135
|
+
if (await checkFileExists(imagePath)) {
|
|
136
|
+
yield imagePath;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function resolveImageFactory(ctx, nuxt) {
|
|
141
|
+
return async (image) => {
|
|
142
|
+
for await (const imagePath of tryToResolveImage(ctx, nuxt, image)) {
|
|
143
|
+
if (imagePath) {
|
|
144
|
+
return imagePath;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`PWA Assets image '${image}' cannot be resolved!`);
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function prepareBuildSwNames(ctx, nitroPublicDir) {
|
|
152
|
+
let swSrc;
|
|
153
|
+
let options;
|
|
154
|
+
switch (ctx.strategy) {
|
|
155
|
+
case "generate-sw":
|
|
156
|
+
swSrc = "x";
|
|
157
|
+
options = ctx.resolvedOptions.generateSW;
|
|
158
|
+
break;
|
|
159
|
+
case "inject-manifest":
|
|
160
|
+
swSrc = ctx.resolvedOptions.injectManifest.swSrc;
|
|
161
|
+
options = ctx.resolvedOptions.injectManifest;
|
|
162
|
+
break;
|
|
163
|
+
case "build-sw":
|
|
164
|
+
swSrc = ctx.resolvedOptions.buildSW.swSrc;
|
|
165
|
+
options = ctx.resolvedOptions.buildSW;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
if (options) {
|
|
169
|
+
const {
|
|
170
|
+
swDest,
|
|
171
|
+
classicSWDest,
|
|
172
|
+
moduleSWDest
|
|
173
|
+
} = resolveSWNames(
|
|
174
|
+
normalizePath(path.relative(process.cwd(), path.resolve(nitroPublicDir, options.swDest))),
|
|
175
|
+
swSrc,
|
|
176
|
+
ctx.strategy === "generate-sw"
|
|
177
|
+
);
|
|
178
|
+
ctx.swNames = {
|
|
179
|
+
hasNames: true,
|
|
180
|
+
name: swDest,
|
|
181
|
+
classic: classicSWDest,
|
|
182
|
+
module: moduleSWDest
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function prepareNitroRoutes(ctx, nuxt) {
|
|
188
|
+
const isDev = nuxt.options.dev;
|
|
189
|
+
let swDisabled = false;
|
|
190
|
+
if (isDev) {
|
|
191
|
+
ctx.devEnvironment = true;
|
|
192
|
+
if (ctx.resolvedOptions.disable) {
|
|
193
|
+
swDisabled = true;
|
|
194
|
+
} else {
|
|
195
|
+
const devOptions = ctx.resolvedOptions.devOptions;
|
|
196
|
+
if (devOptions) {
|
|
197
|
+
swDisabled = !(devOptions.enabled === true);
|
|
198
|
+
} else {
|
|
199
|
+
swDisabled = true;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
if (ctx.resolvedOptions.disable) {
|
|
204
|
+
swDisabled = true;
|
|
205
|
+
}
|
|
206
|
+
if (!swDisabled) {
|
|
207
|
+
prepareBuildSwNames(
|
|
208
|
+
ctx,
|
|
209
|
+
ctx.outDir
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const webManifest = ctx.resolvedOptions.manifest;
|
|
214
|
+
let swNames;
|
|
215
|
+
if (isDev) {
|
|
216
|
+
if (!swDisabled) {
|
|
217
|
+
await prepareSwNamesAndGlobDirectory(ctx);
|
|
218
|
+
swNames = ctx.dev.options.swNames;
|
|
219
|
+
await promises.mkdir(ctx.outDir, { recursive: true });
|
|
220
|
+
}
|
|
221
|
+
} else {
|
|
222
|
+
swNames = ctx.swNames;
|
|
223
|
+
}
|
|
224
|
+
const routeRules = ctx.nuxt.nitroPWAOptions.routeRules;
|
|
225
|
+
if (swNames?.hasNames) {
|
|
226
|
+
if (ctx.resolvedOptions.swType === "classic-and-module") {
|
|
227
|
+
routeRules[`${ctx.base}${path.basename(swNames.classic)}`] = {
|
|
228
|
+
headers: {
|
|
229
|
+
"Cache-Control": "public, max-age=0, must-revalidate"
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
routeRules[`${ctx.base}${path.basename(swNames.module)}`] = {
|
|
233
|
+
headers: {
|
|
234
|
+
"Cache-Control": "public, max-age=0, must-revalidate"
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
} else {
|
|
238
|
+
routeRules[`${ctx.base}${path.basename(swNames.name)}`] = {
|
|
239
|
+
headers: {
|
|
240
|
+
"Cache-Control": "public, max-age=0, must-revalidate"
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if ((nuxt.options.dev || ctx.nuxt.registerWebManifestInRouteRules) && webManifest) {
|
|
246
|
+
routeRules[`${ctx.base}${ctx.resolvedOptions.manifestFilename ?? "manifest.webmanifest"}`] = {
|
|
247
|
+
headers: {
|
|
248
|
+
"Content-Type": "application/manifest+json",
|
|
249
|
+
"Cache-Control": "public, max-age=0, must-revalidate"
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async function prepareResolvedPwaOptions(ctx, nuxt, outDir) {
|
|
256
|
+
normalizeManifest(ctx);
|
|
257
|
+
let config;
|
|
258
|
+
if (ctx.strategy === "build-sw") {
|
|
259
|
+
ctx.resolvedOptions.buildSW.swSrc = await ctx.nuxt.moduleResolver.resolvePath(
|
|
260
|
+
ctx.resolvedOptions.buildSW.swSrc,
|
|
261
|
+
{
|
|
262
|
+
cwd: nuxt.options.rootDir,
|
|
263
|
+
alias: nuxt.options.alias
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
ctx.consumerOptions.filename = ctx.consumerOptions.filename ?? normalizePath$1(
|
|
267
|
+
path.resolve(ctx.outDir, extractSwDestNameFromSource(ctx.resolvedOptions.buildSW.swSrc))
|
|
268
|
+
);
|
|
269
|
+
ctx.resolvedOptions.buildSW.swDest = ctx.consumerOptions.filename;
|
|
270
|
+
ctx.resolvedOptions.buildSW.alias = nuxt.options.alias;
|
|
271
|
+
config = ctx.resolvedOptions.buildSW;
|
|
272
|
+
} else if (ctx.strategy === "generate-sw") {
|
|
273
|
+
ctx.resolvedOptions.generateSW ??= {};
|
|
274
|
+
const generateSW = ctx.resolvedOptions.generateSW;
|
|
275
|
+
if (ctx.resolvedOptions.registerType === "autoUpdate" && (ctx.nuxt.client.registerPlugin || ctx.resolvedOptions.injectRegister === "script" || ctx.resolvedOptions.injectRegister === "inline")) {
|
|
276
|
+
generateSW.clientsClaim = true;
|
|
277
|
+
generateSW.skipWaiting = true;
|
|
278
|
+
}
|
|
279
|
+
if (nuxt.options.dev) {
|
|
280
|
+
generateSW.navigateFallback = generateSW.navigateFallback ?? nuxt.options.app.baseURL ?? "/";
|
|
281
|
+
const devOptions = ctx.resolvedOptions.devOptions;
|
|
282
|
+
if (devOptions?.enabled && !devOptions.navigateFallbackAllowlist) {
|
|
283
|
+
const baseURL = nuxt.options.app.baseURL;
|
|
284
|
+
devOptions.navigateFallbackAllowlist = [
|
|
285
|
+
baseURL ? new RegExp(`^${baseURL.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")}$`) : /^\/$/
|
|
286
|
+
];
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (!("navigateFallback" in generateSW)) {
|
|
290
|
+
generateSW.navigateFallback = ctx.base;
|
|
291
|
+
}
|
|
292
|
+
config = generateSW;
|
|
293
|
+
} else if (ctx.strategy === "inject-manifest") {
|
|
294
|
+
ctx.resolvedOptions.injectManifest ??= {};
|
|
295
|
+
ctx.resolvedOptions.injectManifest.swSrc = await ctx.nuxt.moduleResolver.resolvePath(
|
|
296
|
+
ctx.resolvedOptions.injectManifest.swSrc,
|
|
297
|
+
{
|
|
298
|
+
cwd: nuxt.options.rootDir,
|
|
299
|
+
alias: nuxt.options.alias
|
|
300
|
+
}
|
|
301
|
+
);
|
|
302
|
+
ctx.consumerOptions.filename = ctx.consumerOptions.filename ?? normalizePath$1(
|
|
303
|
+
path.resolve(ctx.outDir, extractSwDestNameFromSource(ctx.resolvedOptions.injectManifest.swSrc))
|
|
304
|
+
);
|
|
305
|
+
ctx.resolvedOptions.injectManifest.swDest = ctx.consumerOptions.filename;
|
|
306
|
+
config = ctx.resolvedOptions.injectManifest;
|
|
307
|
+
}
|
|
308
|
+
if (!config) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (!nuxt.options.dev) {
|
|
312
|
+
config.globDirectory = outDir;
|
|
313
|
+
}
|
|
314
|
+
if (!("globPatterns" in config)) {
|
|
315
|
+
config.globPatterns = ["**/*.{js,css,html}"];
|
|
316
|
+
}
|
|
317
|
+
const buildAssetsDir = ctx.nuxt.buildAssetsDir;
|
|
318
|
+
if (!("dontCacheBustURLsMatching" in config)) {
|
|
319
|
+
config.dontCacheBustURLsMatching = new RegExp(`^${buildAssetsDir.replace(/^\.*\//, "")}`);
|
|
320
|
+
}
|
|
321
|
+
if (ctx.nuxt.enableGlobPatterns) {
|
|
322
|
+
config.globPatterns = config.globPatterns ?? [];
|
|
323
|
+
config.globPatterns.push("**/_payload.json");
|
|
324
|
+
if (ctx.resolvedOptions.strategy === "generate-sw" && (ctx.nuxt.experimental?.enableWorkboxPayloadQueryParams === true || ctx.nuxt.experimental?.enableGenerateSWPayloadQueryParams === true)) {
|
|
325
|
+
const generateSW = ctx.resolvedOptions.generateSW;
|
|
326
|
+
generateSW.runtimeCaching = generateSW.runtimeCaching ?? [];
|
|
327
|
+
generateSW.runtimeCaching.push({
|
|
328
|
+
urlPattern: /\/_payload\.json\?/,
|
|
329
|
+
handler: "NetworkOnly",
|
|
330
|
+
options: {
|
|
331
|
+
plugins: [
|
|
332
|
+
{
|
|
333
|
+
/* this callback will be called when the fetch call fails */
|
|
334
|
+
handlerDidError: async ({ request }) => {
|
|
335
|
+
const url = new URL(request.url);
|
|
336
|
+
url.search = "";
|
|
337
|
+
return Response.redirect(url.href, 302);
|
|
338
|
+
},
|
|
339
|
+
/* this callback will prevent caching the response */
|
|
340
|
+
cacheWillUpdate: async () => null
|
|
341
|
+
}
|
|
342
|
+
]
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
let appManifestFolder;
|
|
348
|
+
if (nuxt.options.experimental.appManifest) {
|
|
349
|
+
config.globPatterns = config.globPatterns ?? [];
|
|
350
|
+
appManifestFolder = `${buildAssetsDir}builds/`;
|
|
351
|
+
config.globPatterns.push(`${appManifestFolder}**/*.json`);
|
|
352
|
+
}
|
|
353
|
+
if (!nuxt.options.dev && !config.manifestTransforms) {
|
|
354
|
+
config.manifestTransforms = [
|
|
355
|
+
createManifestTransform(ctx.base ?? "/", outDir, appManifestFolder)
|
|
356
|
+
];
|
|
357
|
+
}
|
|
358
|
+
await preparePWAStrategy(
|
|
359
|
+
ctx,
|
|
360
|
+
nuxt.options.rootDir,
|
|
361
|
+
ctx.outDir,
|
|
362
|
+
buildAssetsDir
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
function createManifestTransform(base, publicFolder, appManifestFolder) {
|
|
366
|
+
return async (entries) => {
|
|
367
|
+
const regexp = /\.html$/;
|
|
368
|
+
for (const e of entries) {
|
|
369
|
+
if (!e.url.endsWith(".html")) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
const url = e.url.startsWith("/") ? e.url.slice(1) : e.url;
|
|
373
|
+
if (url === "index.html") {
|
|
374
|
+
e.url = base;
|
|
375
|
+
} else {
|
|
376
|
+
const parts = url.split("/");
|
|
377
|
+
parts[parts.length - 1] = parts[parts.length - 1].replace(regexp, "");
|
|
378
|
+
e.url = parts.length > 1 ? parts.slice(0, parts.length - 1).join("/") : parts[0];
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (appManifestFolder) {
|
|
382
|
+
const regExp = /(\/)?[0-9a-f]{8}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{12}\.json$/i;
|
|
383
|
+
entries.filter((e) => e.url.startsWith(appManifestFolder) && regExp.test(e.url)).forEach((e) => {
|
|
384
|
+
e.revision = null;
|
|
385
|
+
});
|
|
386
|
+
const latest = `${appManifestFolder}latest.json`;
|
|
387
|
+
const latestJson = path.resolve(publicFolder, latest);
|
|
388
|
+
const data = await lstat(latestJson).catch(() => void 0);
|
|
389
|
+
if (data?.isFile()) {
|
|
390
|
+
const revision = hash("md5", await promises.readFile(latestJson, "utf-8"), "hex");
|
|
391
|
+
const latestEntry = entries.find((e) => e.url === latest);
|
|
392
|
+
if (latestEntry)
|
|
393
|
+
latestEntry.revision = revision;
|
|
394
|
+
else
|
|
395
|
+
entries.push({ url: latest, revision, size: data.size });
|
|
396
|
+
} else {
|
|
397
|
+
entries = entries.filter((e) => e.url !== latest);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return { manifest: entries, warnings: [] };
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function addPwaTemplate(filename, content) {
|
|
405
|
+
if (content?.length) {
|
|
406
|
+
return addTemplate({
|
|
407
|
+
write: true,
|
|
408
|
+
filename: `pwa-icons/${filename}.d.ts`,
|
|
409
|
+
getContents: () => content
|
|
410
|
+
}).filename;
|
|
411
|
+
} else {
|
|
412
|
+
return addTemplate({
|
|
413
|
+
write: true,
|
|
414
|
+
filename: `pwa-icons/${filename}.d.ts`,
|
|
415
|
+
getContents: () => generatePwaImageType(filename)
|
|
416
|
+
}).filename;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function pwaIcons(types) {
|
|
420
|
+
return `// Generated by @vite-pwa/nuxt
|
|
421
|
+
import type { AppleSplashScreenLink, FaviconLink, HtmlLink, IconAsset } from '@vite-pwa/assets-generator/api'
|
|
422
|
+
|
|
423
|
+
export interface PWAAssetIconImage {
|
|
424
|
+
width?: number | string
|
|
425
|
+
height?: number | string
|
|
426
|
+
key: string
|
|
427
|
+
src: string
|
|
428
|
+
}
|
|
429
|
+
export type PWAAssetIcon<T extends HtmlLink> = Omit<IconAsset<T>, 'buffer'> & {
|
|
430
|
+
asImage: PWAAssetIconImage
|
|
431
|
+
}
|
|
432
|
+
export interface PWAIcons {
|
|
433
|
+
transparent: Record<${generateTypes(types?.transparent)}, PWAAssetIcon<HtmlLink>>
|
|
434
|
+
maskable: Record<${generateTypes(types?.maskable)}, PWAAssetIcon<HtmlLink>>
|
|
435
|
+
favicon: Record<${generateTypes(types?.favicon)}, PWAAssetIcon<FaviconLink>>
|
|
436
|
+
apple: Record<${generateTypes(types?.apple)}, PWAAssetIcon<HtmlLink>>
|
|
437
|
+
appleSplashScreen: Record<${generateTypes(types?.appleSplashScreen)}, PWAAssetIcon<AppleSplashScreenLink>>
|
|
438
|
+
}
|
|
439
|
+
`;
|
|
440
|
+
}
|
|
441
|
+
function generatePwaImageType(propsName, names) {
|
|
442
|
+
return `// Generated by @vite-pwa/nuxt
|
|
443
|
+
import type { ImgHTMLAttributes } from 'vue'
|
|
444
|
+
|
|
445
|
+
export type PWAVueImageType = Omit<ImgHTMLAttributes, 'src'>
|
|
446
|
+
|
|
447
|
+
export type ${propsName} = PWAVueImageType & {
|
|
448
|
+
/**
|
|
449
|
+
* Name of the PWA icon to render.
|
|
450
|
+
* @type {${generateTypes(names)}}
|
|
451
|
+
*/
|
|
452
|
+
image: ${generateTypes(names)}
|
|
453
|
+
}
|
|
454
|
+
`;
|
|
455
|
+
}
|
|
456
|
+
function generateTypes(types) {
|
|
457
|
+
return types?.length ? types.map((name) => `'${name}'`).join(" | ") : "string";
|
|
458
|
+
}
|
|
459
|
+
function addPWAIconsPluginTemplate(ctx, nuxt, nuxt4, pwaAssetsEnabled) {
|
|
460
|
+
const buildDir = ctx.nuxt.moduleResolver.resolve(nuxt.options.buildDir, "pwa-icons");
|
|
461
|
+
const resolvePluginJsPath = (name) => ctx.nuxt.moduleResolver.resolve(
|
|
462
|
+
buildDir,
|
|
463
|
+
name
|
|
464
|
+
);
|
|
465
|
+
if (nuxt4) {
|
|
466
|
+
addTemplate({
|
|
467
|
+
filename: resolvePluginJsPath("plugin.d.ts"),
|
|
468
|
+
write: true,
|
|
469
|
+
getContents: () => `// Generated by @vite-pwa/nuxt
|
|
470
|
+
import type { Plugin } from '#app';
|
|
471
|
+
import type { PWAIcons } from '#build/pwa-icons';
|
|
472
|
+
declare const plugin: Plugin<{
|
|
473
|
+
pwaIcons?: PWAIcons;
|
|
474
|
+
}>;
|
|
475
|
+
export default plugin;
|
|
476
|
+
`
|
|
477
|
+
});
|
|
478
|
+
addPWAIconPluginTemplate(
|
|
479
|
+
resolvePluginJsPath,
|
|
480
|
+
pwaAssetsEnabled,
|
|
481
|
+
"all"
|
|
482
|
+
);
|
|
483
|
+
} else {
|
|
484
|
+
addPWAIconPluginTemplate(
|
|
485
|
+
resolvePluginJsPath,
|
|
486
|
+
pwaAssetsEnabled,
|
|
487
|
+
"client"
|
|
488
|
+
);
|
|
489
|
+
addPWAIconPluginTemplate(
|
|
490
|
+
resolvePluginJsPath,
|
|
491
|
+
pwaAssetsEnabled,
|
|
492
|
+
"server"
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
function addPWAIconPluginTemplate(resolvePluginJsPath, pwaAssetsEnabled, mode) {
|
|
497
|
+
const suffix = mode === "all" ? "" : `:${mode}`;
|
|
498
|
+
const filename = mode === "all" ? "plugin" : `plugin.${mode}`;
|
|
499
|
+
if (mode !== "all") {
|
|
500
|
+
addTemplate({
|
|
501
|
+
filename: resolvePluginJsPath(`plugin.${mode}.d.ts`),
|
|
502
|
+
write: true,
|
|
503
|
+
getContents: () => `// Generated by @vite-pwa/nuxt
|
|
504
|
+
import type { Plugin } from '#app';
|
|
505
|
+
import type { PWAIcons } from '#build/pwa-icons';
|
|
506
|
+
|
|
507
|
+
declare const plugin: Plugin<{
|
|
508
|
+
pwaIcons?: PWAIcons;
|
|
509
|
+
}>;
|
|
510
|
+
export default plugin;
|
|
511
|
+
`
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
if (pwaAssetsEnabled) {
|
|
515
|
+
addPluginTemplate({
|
|
516
|
+
filename: resolvePluginJsPath(`${filename}.js`),
|
|
517
|
+
name: `vite-pwa:nuxt:pwa-icons${suffix}:plugin`,
|
|
518
|
+
write: true,
|
|
519
|
+
mode,
|
|
520
|
+
getContents: () => `// Generated by @vite-pwa/nuxt
|
|
521
|
+
import { pwaAssetsIcons } from 'virtual:pwa-assets/icons';
|
|
522
|
+
import { defineNuxtPlugin } from '#imports';
|
|
523
|
+
|
|
524
|
+
export default defineNuxtPlugin(() => ({
|
|
525
|
+
provide: {
|
|
526
|
+
pwaIcons: {
|
|
527
|
+
transparent: configureEntry("transparent"),
|
|
528
|
+
maskable: configureEntry("maskable"),
|
|
529
|
+
favicon: configureEntry("favicon"),
|
|
530
|
+
apple: configureEntry("apple"),
|
|
531
|
+
appleSplashScreen: configureEntry("appleSplashScreen")
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}))
|
|
535
|
+
|
|
536
|
+
function configureEntry(key) {
|
|
537
|
+
return Object.values(pwaAssetsIcons[key] ?? {}).reduce((acc, icon) => {
|
|
538
|
+
const entry = Object.assign({}, icon, {
|
|
539
|
+
asImage: {
|
|
540
|
+
src: icon.url,
|
|
541
|
+
key: \`\${key}-\${icon.name}\`
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
if (icon.width && icon.height) {
|
|
545
|
+
entry.asImage.width = icon.width;
|
|
546
|
+
entry.asImage.height = icon.height;
|
|
547
|
+
}
|
|
548
|
+
acc[icon.name] = entry;
|
|
549
|
+
return acc;
|
|
550
|
+
}, {});
|
|
551
|
+
}
|
|
552
|
+
`
|
|
553
|
+
});
|
|
554
|
+
} else {
|
|
555
|
+
addPluginTemplate({
|
|
556
|
+
filename: resolvePluginJsPath(`${filename}.js`),
|
|
557
|
+
name: `vite-pwa:nuxt:pwa-icons${suffix}:plugin`,
|
|
558
|
+
write: true,
|
|
559
|
+
mode,
|
|
560
|
+
getContents: () => `// Generated by @vite-pwa/nuxt
|
|
561
|
+
import { defineNuxtPlugin } from '#imports'
|
|
562
|
+
|
|
563
|
+
export default defineNuxtPlugin(() => ({
|
|
564
|
+
provide: {
|
|
565
|
+
pwaIcons: {
|
|
566
|
+
transparent: {},
|
|
567
|
+
maskable: {},
|
|
568
|
+
favicon: {},
|
|
569
|
+
apple: {},
|
|
570
|
+
appleSplashScreen: {}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}))
|
|
574
|
+
`
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
async function registerPwaIconsTypes(ctx, nuxt) {
|
|
580
|
+
const options = ctx.resolvedOptions;
|
|
581
|
+
const pwaAssets = options.pwaAssets && !options.pwaAssets.disabled;
|
|
582
|
+
let dts;
|
|
583
|
+
if (pwaAssets) {
|
|
584
|
+
try {
|
|
585
|
+
const { preparePWAIcons } = await import('./prepare-pwa-icons.mjs');
|
|
586
|
+
dts = await preparePWAIcons(nuxt, ctx);
|
|
587
|
+
} catch (error) {
|
|
588
|
+
useLogger("@vite-pwa/nuxt").warn("Unable to generate PWA icons types.", error);
|
|
589
|
+
dts = void 0;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
const templates = [];
|
|
593
|
+
const dtsContent = dts?.dts;
|
|
594
|
+
if (dtsContent) {
|
|
595
|
+
templates.push(addTemplate({
|
|
596
|
+
write: true,
|
|
597
|
+
filename: "pwa-icons/index.d.ts",
|
|
598
|
+
getContents: () => dtsContent
|
|
599
|
+
}).filename);
|
|
600
|
+
} else {
|
|
601
|
+
templates.push(addTemplate({
|
|
602
|
+
write: true,
|
|
603
|
+
filename: "pwa-icons/index.d.ts",
|
|
604
|
+
getContents: () => pwaIcons()
|
|
605
|
+
}).filename);
|
|
606
|
+
}
|
|
607
|
+
templates.push(addPwaTemplate("PwaTransparentImageProps", dts?.transparent));
|
|
608
|
+
templates.push(addPwaTemplate("PwaMaskableImageProps", dts?.maskable));
|
|
609
|
+
templates.push(addPwaTemplate("PwaFaviconImageProps", dts?.favicon));
|
|
610
|
+
templates.push(addPwaTemplate("PwaAppleImageProps", dts?.apple));
|
|
611
|
+
templates.push(addPwaTemplate("PwaAppleSplashScreenImageProps", dts?.appleSplashScreen));
|
|
612
|
+
addPWAIconsPluginTemplate(
|
|
613
|
+
ctx,
|
|
614
|
+
nuxt,
|
|
615
|
+
getMajor(ctx.nuxt.nuxtVersion) >= 4,
|
|
616
|
+
pwaAssets === true
|
|
617
|
+
);
|
|
618
|
+
const pwaInjectionPath = normalizePath$1(path.relative(
|
|
619
|
+
ctx.nuxt.moduleResolver.resolve(nuxt.options.buildDir, "types"),
|
|
620
|
+
ctx.nuxt.moduleResolver.resolve("runtime/plugins/types")
|
|
621
|
+
));
|
|
622
|
+
const nuxt5 = getMajor(ctx.nuxt.nuxtVersion) > 4;
|
|
623
|
+
addTemplate({
|
|
624
|
+
write: true,
|
|
625
|
+
filename: "types/pwa-augments.d.ts",
|
|
626
|
+
getContents: () => prepareVueModuleAugmentation(
|
|
627
|
+
pwaInjectionPath,
|
|
628
|
+
nuxt5
|
|
629
|
+
)
|
|
630
|
+
});
|
|
631
|
+
const pwaPath = addTemplate({
|
|
632
|
+
filename: "types/pwa.d.ts",
|
|
633
|
+
write: true,
|
|
634
|
+
getContents: () => templates.map(
|
|
635
|
+
(t) => `/// <reference path="../${t}" />`
|
|
636
|
+
).join("\n")
|
|
637
|
+
}).dst;
|
|
638
|
+
nuxt.hook("prepare:types", (context) => {
|
|
639
|
+
context.references.push({ path: pwaPath });
|
|
640
|
+
if (getMajor(ctx.nuxt.nuxtVersion) >= 4) {
|
|
641
|
+
context.nodeReferences.push({ path: pwaPath });
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
function prepareVueModuleAugmentation(pwaInjectionPath, nuxt5) {
|
|
646
|
+
const footer = nuxt5 ? "" : `
|
|
647
|
+
export {}
|
|
648
|
+
`;
|
|
649
|
+
return `// Generated by @vite-pwa/nuxt
|
|
650
|
+
import { UnwrapNestedRefs } from 'vue'
|
|
651
|
+
import { PWAIcons } from '#build/pwa-icons'
|
|
652
|
+
import { PwaInjection, PwaInstallPromptInjection } from '${pwaInjectionPath}'
|
|
653
|
+
|
|
654
|
+
declare module '#app' {
|
|
655
|
+
interface NuxtApp {
|
|
656
|
+
/**
|
|
657
|
+
* Reactive PWA state and controls provided by \`@vite-pwa/nuxt\`.
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* \`\`\`ts
|
|
661
|
+
* const { $pwa } = useNuxtApp()
|
|
662
|
+
* if ($pwa?.needRefresh) await $pwa.updateServiceWorker()
|
|
663
|
+
* \`\`\`
|
|
664
|
+
*/
|
|
665
|
+
$pwa?: UnwrapNestedRefs<PwaInjection>
|
|
666
|
+
/**
|
|
667
|
+
* Internal usage, use \`$pwa\` instead.
|
|
668
|
+
*/
|
|
669
|
+
$pwaInstallPrompt: PwaInstallPromptInjection
|
|
670
|
+
/**
|
|
671
|
+
* Available PWA icons.
|
|
672
|
+
*/
|
|
673
|
+
$pwaIcons?: PWAIcons
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
declare module 'vue' {
|
|
678
|
+
interface ComponentCustomProperties {
|
|
679
|
+
/**
|
|
680
|
+
* Reactive PWA state and controls provided by \`@vite-pwa/nuxt\`.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* \`\`\`ts
|
|
684
|
+
* const { $pwa } = useNuxtApp()
|
|
685
|
+
* if ($pwa?.needRefresh) await $pwa.updateServiceWorker()
|
|
686
|
+
* \`\`\`
|
|
687
|
+
*/
|
|
688
|
+
$pwa?: UnwrapNestedRefs<PwaInjection>
|
|
689
|
+
/**
|
|
690
|
+
* Internal usage, use \`$pwa\` instead.
|
|
691
|
+
*/
|
|
692
|
+
$pwaInstallPrompt: PwaInstallPromptInjection
|
|
693
|
+
/**
|
|
694
|
+
* Available PWA icons.
|
|
695
|
+
*/
|
|
696
|
+
$pwaIcons?: PWAIcons
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
${footer}
|
|
700
|
+
`;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
function nitroInitHook(ctx, nuxt) {
|
|
704
|
+
return async (nitro) => {
|
|
705
|
+
ctx.resolvedOptions.includeManifestIcons = false;
|
|
706
|
+
ctx.resolvedOptions.includeManifestScreenshots = false;
|
|
707
|
+
ctx.resolvedOptions.includeManifestShortcutIcons = false;
|
|
708
|
+
ctx.publicDir = nuxt.options.dir.public;
|
|
709
|
+
ctx.rootDir = nuxt.options.rootDir;
|
|
710
|
+
if (nuxt.options.dev) {
|
|
711
|
+
ctx.devEnvironment = true;
|
|
712
|
+
const internalDevOptions = ctx.dev.options;
|
|
713
|
+
internalDevOptions.tempFolder = path.resolve(nuxt.options.buildDir, "pwa-dev/.dev-dist");
|
|
714
|
+
ctx.outDir = internalDevOptions.tempFolder;
|
|
715
|
+
} else {
|
|
716
|
+
ctx.outDir = normalizePath$1(nitro.options.output.publicDir);
|
|
717
|
+
}
|
|
718
|
+
ctx.resolvedOptions.outDir = ctx.outDir;
|
|
719
|
+
ctx.strategy = ctx.resolvedOptions.strategy;
|
|
720
|
+
ctx.resolvedOptions.base ??= ctx.base;
|
|
721
|
+
ctx.resolvedOptions.buildBase ??= ctx.base;
|
|
722
|
+
ctx.resolvedOptions.scope ??= ctx.base;
|
|
723
|
+
await prepareResolvedPwaOptions(ctx, nuxt, ctx.outDir);
|
|
724
|
+
await ctx.nuxt.preparePwaConfiguration?.();
|
|
725
|
+
await initPwaAssetsGenerator(ctx, nuxt);
|
|
726
|
+
await registerPwaIconsTypes(ctx, nuxt);
|
|
727
|
+
await prepareNitroRoutes(ctx, nuxt);
|
|
728
|
+
const routeRules = ctx.nuxt.nitroPWAOptions.routeRules;
|
|
729
|
+
if (Object.keys(routeRules).length > 0) {
|
|
730
|
+
for (const [route, rules] of Object.entries(routeRules)) {
|
|
731
|
+
nitro.options.routeRules[route] = defu(nitro.options.routeRules[route], rules);
|
|
732
|
+
}
|
|
733
|
+
nitro.routing?.sync();
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
function prepareTypesHook(ctx) {
|
|
739
|
+
return (context) => {
|
|
740
|
+
const unpluginPwaCoreDir = path.dirname(
|
|
741
|
+
createRequire(import.meta.url).resolve("@unplugin-pwa/core/package.json")
|
|
742
|
+
);
|
|
743
|
+
const references = [
|
|
744
|
+
{
|
|
745
|
+
path: ctx.nuxt.moduleResolver.resolve("../configuration.d.ts")
|
|
746
|
+
},
|
|
747
|
+
...["vue.d.ts", "info.d.ts", "pwa-assets.d.ts"].map((file) => ({
|
|
748
|
+
path: path.join(unpluginPwaCoreDir, file)
|
|
749
|
+
})),
|
|
750
|
+
{ path: "types/pwa-augments.d.ts" }
|
|
751
|
+
];
|
|
752
|
+
context.references.push(...references);
|
|
753
|
+
if (getMajor(ctx.nuxt.nuxtVersion) >= 4) {
|
|
754
|
+
context.nodeReferences.push(...references);
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
function serverDevHandlerHook(ctx, nuxt) {
|
|
760
|
+
return async () => {
|
|
761
|
+
const devOptions = ctx.resolvedOptions.devOptions;
|
|
762
|
+
if (nuxt.options.dev && devOptions && devOptions.inspector) {
|
|
763
|
+
await ctx.hooks.callHook("context:ready");
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
async function prepareModule(ctx, nuxt) {
|
|
769
|
+
const resolver = ctx.nuxt.moduleResolver;
|
|
770
|
+
const consumerOptions = ctx.consumerOptions;
|
|
771
|
+
if (consumerOptions.path) {
|
|
772
|
+
consumerOptions.path = await resolver.resolvePath(
|
|
773
|
+
consumerOptions.path,
|
|
774
|
+
{
|
|
775
|
+
cwd: nuxt.options.rootDir,
|
|
776
|
+
alias: nuxt.options.alias
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
} else {
|
|
780
|
+
for (const dir of [nuxt.options.srcDir, nuxt.options.rootDir]) {
|
|
781
|
+
const resolvedPath = resolveDefaultConfig(dir);
|
|
782
|
+
if (resolvedPath) {
|
|
783
|
+
consumerOptions.path = normalizePath$1(resolvedPath);
|
|
784
|
+
break;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
ctx.externalConfigurationLoader = true;
|
|
789
|
+
ctx.base ??= consumerOptions.base || "/";
|
|
790
|
+
consumerOptions.base ??= ctx.base;
|
|
791
|
+
consumerOptions.scope ??= ctx.base;
|
|
792
|
+
const publicDirs = /* @__PURE__ */ new Set();
|
|
793
|
+
for (const layer of nuxt.options._layers) {
|
|
794
|
+
publicDirs.add(normalizePath$1(resolver.resolve(layer.config.rootDir, layer.config.dir?.public || "public")));
|
|
795
|
+
}
|
|
796
|
+
ctx.nuxt.publicDirs = [...publicDirs].filter((dir) => existsSync(dir));
|
|
797
|
+
await loadPwaConfiguration(ctx, nuxt);
|
|
798
|
+
if (ctx.resolvedOptions.path) {
|
|
799
|
+
nuxt.options.watch.push(ctx.resolvedOptions.path);
|
|
800
|
+
applyExternalNuxtOptions(ctx);
|
|
801
|
+
}
|
|
802
|
+
const runtimeDir = resolver.resolve("./runtime");
|
|
803
|
+
nuxt.options.build.transpile.push(runtimeDir);
|
|
804
|
+
nuxt.options.alias["#pwa"] = resolver.resolve(runtimeDir, "composables");
|
|
805
|
+
if (ctx.nuxt.client.registerPlugin) {
|
|
806
|
+
addPlugin({
|
|
807
|
+
src: resolver.resolve(runtimeDir, "plugins/pwa.client"),
|
|
808
|
+
mode: "client"
|
|
809
|
+
});
|
|
810
|
+
addPlugin({
|
|
811
|
+
src: resolver.resolve(runtimeDir, "plugins/pwa-install.client"),
|
|
812
|
+
mode: "client"
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
nuxt.hook("nitro:config", nitroConfigHook(ctx, nuxt));
|
|
816
|
+
nuxt.hook("nitro:init", nitroInitHook(ctx, nuxt));
|
|
817
|
+
nuxt.hook("prepare:types", prepareTypesHook(ctx));
|
|
818
|
+
nuxt.hook("devtools:customTabs", devtoolsCustomTabsHook(ctx));
|
|
819
|
+
for (const name of ["NuxtPwaAssets", "NuxtPwaManifest"]) {
|
|
820
|
+
addComponent({
|
|
821
|
+
name,
|
|
822
|
+
global: !nuxt.options.imports.autoImport,
|
|
823
|
+
filePath: resolver.resolve(runtimeDir, `components/${name}`)
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
addImports([
|
|
827
|
+
"usePWA",
|
|
828
|
+
"useTransparentPwaIcon",
|
|
829
|
+
"useMaskablePwaIcon",
|
|
830
|
+
"useFaviconPwaIcon",
|
|
831
|
+
"useApplePwaIcon",
|
|
832
|
+
"useAppleSplashScreenPwaIcon"
|
|
833
|
+
].map((name) => ({
|
|
834
|
+
name,
|
|
835
|
+
from: resolver.resolve(runtimeDir, "composables")
|
|
836
|
+
})));
|
|
837
|
+
nuxt.hook("server:devHandler", serverDevHandlerHook(ctx, nuxt));
|
|
838
|
+
nuxt.hook("build:before", buildBeforeHook(ctx));
|
|
839
|
+
if (!nuxt.options.dev) {
|
|
840
|
+
nuxt.hook("nitro:build:public-assets", async () => {
|
|
841
|
+
await buildPwaAssets(ctx, nuxt);
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
function applyExternalNuxtOptions(ctx) {
|
|
846
|
+
const {
|
|
847
|
+
client,
|
|
848
|
+
experimental,
|
|
849
|
+
registerWebManifestInRouteRules,
|
|
850
|
+
writePlugin
|
|
851
|
+
} = ctx.resolvedOptions;
|
|
852
|
+
if (client) {
|
|
853
|
+
Object.assign(ctx.nuxt.client, client);
|
|
854
|
+
}
|
|
855
|
+
if (experimental) {
|
|
856
|
+
ctx.nuxt.experimental = experimental;
|
|
857
|
+
}
|
|
858
|
+
if (registerWebManifestInRouteRules !== void 0) {
|
|
859
|
+
ctx.nuxt.registerWebManifestInRouteRules = registerWebManifestInRouteRules;
|
|
860
|
+
}
|
|
861
|
+
if (writePlugin !== void 0) {
|
|
862
|
+
ctx.nuxt.writePlugin = writePlugin;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
const prepareModule$1 = {
|
|
867
|
+
__proto__: null,
|
|
868
|
+
prepareModule: prepareModule
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
export { prepareModule$1 as a, generatePwaImageType as g, pwaIcons as p };
|