@djangocfg/nextjs 2.1.36 → 2.1.38
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 +146 -1
- package/dist/config/index.d.mts +7 -428
- package/dist/config/index.mjs +80 -396
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +80 -396
- package/dist/index.mjs.map +1 -1
- package/dist/plugin-DuRJ_Jq6.d.mts +100 -0
- package/dist/pwa/cli.d.mts +1 -0
- package/dist/pwa/cli.mjs +140 -0
- package/dist/pwa/cli.mjs.map +1 -0
- package/dist/pwa/index.d.mts +274 -0
- package/dist/pwa/index.mjs +327 -0
- package/dist/pwa/index.mjs.map +1 -0
- package/dist/pwa/server/index.d.mts +86 -0
- package/dist/pwa/server/index.mjs +175 -0
- package/dist/pwa/server/index.mjs.map +1 -0
- package/dist/pwa/server/routes.d.mts +2 -0
- package/dist/pwa/server/routes.mjs +149 -0
- package/dist/pwa/server/routes.mjs.map +1 -0
- package/dist/pwa/worker/index.d.mts +56 -0
- package/dist/pwa/worker/index.mjs +97 -0
- package/dist/pwa/worker/index.mjs.map +1 -0
- package/dist/routes-DXA29sS_.d.mts +68 -0
- package/package.json +39 -8
- package/src/config/createNextConfig.ts +9 -13
- package/src/config/index.ts +2 -20
- package/src/config/plugins/devStartup.ts +35 -36
- package/src/config/plugins/index.ts +1 -1
- package/src/config/utils/index.ts +0 -1
- package/src/index.ts +4 -0
- package/src/pwa/cli.ts +171 -0
- package/src/pwa/index.ts +9 -0
- package/src/pwa/manifest.ts +355 -0
- package/src/pwa/notifications.ts +192 -0
- package/src/pwa/plugin.ts +194 -0
- package/src/pwa/server/index.ts +23 -0
- package/src/pwa/server/push.ts +166 -0
- package/src/pwa/server/routes.ts +137 -0
- package/src/pwa/worker/index.ts +174 -0
- package/src/pwa/worker/package.json +3 -0
- package/src/config/plugins/pwa.ts +0 -616
- package/src/config/utils/manifest.ts +0 -214
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { NextConfig } from 'next';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PWA (Progressive Web App) Plugin
|
|
5
|
+
*
|
|
6
|
+
* Configures Serwist for service worker and offline support
|
|
7
|
+
* Modern PWA solution for Next.js 15+ with App Router
|
|
8
|
+
*
|
|
9
|
+
* @see https://serwist.pages.dev/
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface PWAPluginOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Destination directory for service worker files
|
|
15
|
+
* @default 'public'
|
|
16
|
+
* @deprecated Use swDest instead
|
|
17
|
+
*/
|
|
18
|
+
dest?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Path to service worker source file (relative to project root)
|
|
21
|
+
* @default 'app/sw.ts'
|
|
22
|
+
*/
|
|
23
|
+
swSrc?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Destination for compiled service worker
|
|
26
|
+
* @default 'public/sw.js'
|
|
27
|
+
*/
|
|
28
|
+
swDest?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Disable PWA completely
|
|
31
|
+
* @default false in production, true in development
|
|
32
|
+
* @example disable: process.env.NODE_ENV === 'development'
|
|
33
|
+
*/
|
|
34
|
+
disable?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Cache on navigation - cache pages when navigating
|
|
37
|
+
* @default true
|
|
38
|
+
*/
|
|
39
|
+
cacheOnNavigation?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Reload app when device goes back online
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
reloadOnOnline?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Additional Serwist options
|
|
47
|
+
* @see https://serwist.pages.dev/docs/next/configuring
|
|
48
|
+
*/
|
|
49
|
+
serwistOptions?: Record<string, any>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Add PWA configuration to Next.js config using Serwist
|
|
53
|
+
*
|
|
54
|
+
* @example Basic usage
|
|
55
|
+
* ```ts
|
|
56
|
+
* import { createBaseNextConfig, withPWA } from '@djangocfg/nextjs/config';
|
|
57
|
+
*
|
|
58
|
+
* const nextConfig = createBaseNextConfig({...});
|
|
59
|
+
*
|
|
60
|
+
* export default withPWA(nextConfig, {
|
|
61
|
+
* swSrc: 'app/sw.ts',
|
|
62
|
+
* disable: process.env.NODE_ENV === 'development',
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example Integrated with createBaseNextConfig
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { createBaseNextConfig } from '@djangocfg/nextjs/config';
|
|
69
|
+
*
|
|
70
|
+
* const config = createBaseNextConfig({
|
|
71
|
+
* pwa: {
|
|
72
|
+
* swSrc: 'app/sw.ts',
|
|
73
|
+
* disable: false,
|
|
74
|
+
* },
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* export default config;
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
declare function withPWA(nextConfig: NextConfig, options?: PWAPluginOptions): NextConfig;
|
|
81
|
+
/**
|
|
82
|
+
* Get service worker template content
|
|
83
|
+
*
|
|
84
|
+
* Returns ready-to-use service worker code for app/sw.ts
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* import { getServiceWorkerTemplate } from '@djangocfg/nextjs/config';
|
|
89
|
+
*
|
|
90
|
+
* // Copy this to your app/sw.ts file
|
|
91
|
+
* console.log(getServiceWorkerTemplate());
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
declare function getServiceWorkerTemplate(): string;
|
|
95
|
+
declare const defaultRuntimeCaching: any[];
|
|
96
|
+
declare function createApiCacheRule(): {};
|
|
97
|
+
declare function createStaticAssetRule(): {};
|
|
98
|
+
declare function createCdnCacheRule(): {};
|
|
99
|
+
|
|
100
|
+
export { type PWAPluginOptions as P, createStaticAssetRule as a, createCdnCacheRule as b, createApiCacheRule as c, defaultRuntimeCaching as d, getServiceWorkerTemplate as g, withPWA as w };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/pwa/cli.mjs
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/pwa/cli.ts
|
|
4
|
+
import { consola } from "consola";
|
|
5
|
+
import webpush from "web-push";
|
|
6
|
+
var args = process.argv.slice(2);
|
|
7
|
+
var command = args[0];
|
|
8
|
+
async function generateVapidKeys() {
|
|
9
|
+
consola.box("VAPID Keys Generator");
|
|
10
|
+
consola.info("Generating new VAPID key pair...\n");
|
|
11
|
+
const vapidKeys = webpush.generateVAPIDKeys();
|
|
12
|
+
consola.success("\u2705 VAPID keys generated!\n");
|
|
13
|
+
consola.log("Add these to your .env.local:\n");
|
|
14
|
+
consola.log(`NEXT_PUBLIC_VAPID_PUBLIC_KEY=${vapidKeys.publicKey}`);
|
|
15
|
+
consola.log(`VAPID_PRIVATE_KEY=${vapidKeys.privateKey}`);
|
|
16
|
+
consola.log(`VAPID_MAILTO=mailto:your-email@example.com
|
|
17
|
+
`);
|
|
18
|
+
consola.info("Public key (share with clients):");
|
|
19
|
+
consola.log(` ${vapidKeys.publicKey}
|
|
20
|
+
`);
|
|
21
|
+
consola.info("Private key (keep secret):");
|
|
22
|
+
consola.log(` ${vapidKeys.privateKey}
|
|
23
|
+
`);
|
|
24
|
+
}
|
|
25
|
+
async function sendTestPush() {
|
|
26
|
+
consola.box("Send Test Push Notification");
|
|
27
|
+
const publicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY;
|
|
28
|
+
const privateKey = process.env.VAPID_PRIVATE_KEY;
|
|
29
|
+
const mailto = process.env.VAPID_MAILTO || "mailto:test@example.com";
|
|
30
|
+
if (!publicKey || !privateKey) {
|
|
31
|
+
consola.error("\u274C VAPID keys not configured!");
|
|
32
|
+
consola.info("\nGenerate keys with:");
|
|
33
|
+
consola.log(" pnpm pwa vapid\n");
|
|
34
|
+
consola.info("Then add to .env.local:");
|
|
35
|
+
consola.log(" NEXT_PUBLIC_VAPID_PUBLIC_KEY=...");
|
|
36
|
+
consola.log(" VAPID_PRIVATE_KEY=...");
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
const subscriptionArg = args[1];
|
|
40
|
+
if (!subscriptionArg) {
|
|
41
|
+
consola.error("\u274C Subscription required!\n");
|
|
42
|
+
consola.info("Usage:");
|
|
43
|
+
consola.log(` pnpm pwa send '{"endpoint":"...","keys":{...}}'
|
|
44
|
+
`);
|
|
45
|
+
consola.info("To subscribe and get the JSON, visit the playground:");
|
|
46
|
+
consola.log(" http://djangocfg.com/layouts/a2hs-hint\n");
|
|
47
|
+
consola.info("Or use the helper command:");
|
|
48
|
+
consola.log(" pnpm exec djangocfg-pwa status\n");
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const subscription = JSON.parse(subscriptionArg);
|
|
53
|
+
webpush.setVapidDetails(mailto, publicKey, privateKey);
|
|
54
|
+
const payload = JSON.stringify({
|
|
55
|
+
title: "Test Push from CLI",
|
|
56
|
+
body: "This is a test notification sent from @djangocfg/nextjs CLI",
|
|
57
|
+
icon: "/static/logos/192x192.png",
|
|
58
|
+
badge: "/static/logos/192x192.png"
|
|
59
|
+
});
|
|
60
|
+
consola.info("Sending push notification...\n");
|
|
61
|
+
await webpush.sendNotification(subscription, payload);
|
|
62
|
+
consola.success("\u2705 Push notification sent successfully!");
|
|
63
|
+
} catch (err) {
|
|
64
|
+
consola.error("\u274C Failed to send push:", err instanceof Error ? err.message : err);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function showStatus() {
|
|
69
|
+
consola.box("PWA Status");
|
|
70
|
+
const publicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY;
|
|
71
|
+
const privateKey = process.env.VAPID_PRIVATE_KEY;
|
|
72
|
+
const mailto = process.env.VAPID_MAILTO;
|
|
73
|
+
consola.log("Environment Variables:");
|
|
74
|
+
consola.log(` NEXT_PUBLIC_VAPID_PUBLIC_KEY: ${publicKey ? "\u2705 Set" : "\u274C Not set"}`);
|
|
75
|
+
consola.log(` VAPID_PRIVATE_KEY: ${privateKey ? "\u2705 Set" : "\u274C Not set"}`);
|
|
76
|
+
consola.log(` VAPID_MAILTO: ${mailto || "\u26A0\uFE0F Not set (optional)"}
|
|
77
|
+
`);
|
|
78
|
+
if (!publicKey || !privateKey) {
|
|
79
|
+
consola.warn("\u26A0\uFE0F VAPID keys not configured. Run: pnpm pwa vapid\n");
|
|
80
|
+
} else {
|
|
81
|
+
consola.success("\u2705 VAPID keys configured\n");
|
|
82
|
+
consola.log("Public Key:");
|
|
83
|
+
consola.log(` ${publicKey.slice(0, 40)}...
|
|
84
|
+
`);
|
|
85
|
+
}
|
|
86
|
+
consola.log("Quick Start:");
|
|
87
|
+
consola.log(" 1. Generate VAPID keys: pnpm pwa vapid");
|
|
88
|
+
consola.log(" 2. Add to .env.local");
|
|
89
|
+
consola.log(" 3. Visit playground: http://djangocfg.com/layouts/a2hs-hint");
|
|
90
|
+
consola.log(" 4. Send test push: pnpm pwa send '<subscription>'\n");
|
|
91
|
+
}
|
|
92
|
+
async function showInfo() {
|
|
93
|
+
consola.box("DjangoCFG PWA CLI");
|
|
94
|
+
consola.log("Commands:");
|
|
95
|
+
consola.log(" vapid Generate VAPID keys");
|
|
96
|
+
consola.log(" send <subscription> Send test push notification");
|
|
97
|
+
consola.log(" status Show PWA configuration status");
|
|
98
|
+
consola.log(" info Show this help\n");
|
|
99
|
+
consola.log("Examples:");
|
|
100
|
+
consola.log(" # Generate VAPID keys");
|
|
101
|
+
consola.log(" pnpm pwa vapid\n");
|
|
102
|
+
consola.log(" # Check status");
|
|
103
|
+
consola.log(" pnpm pwa status\n");
|
|
104
|
+
consola.log(" # Subscribe");
|
|
105
|
+
consola.log(" Visit: http://djangocfg.com/layouts/a2hs-hint\n");
|
|
106
|
+
consola.log(" # Send test push");
|
|
107
|
+
consola.log(` pnpm pwa send '{"endpoint":"...","keys":{"p256dh":"...","auth":"..."}}'
|
|
108
|
+
`);
|
|
109
|
+
consola.log("Documentation:");
|
|
110
|
+
consola.log(" https://djangocfg.com/docs/pwa");
|
|
111
|
+
}
|
|
112
|
+
async function main() {
|
|
113
|
+
switch (command) {
|
|
114
|
+
case "vapid":
|
|
115
|
+
case "v":
|
|
116
|
+
case "keys":
|
|
117
|
+
await generateVapidKeys();
|
|
118
|
+
break;
|
|
119
|
+
case "send":
|
|
120
|
+
case "s":
|
|
121
|
+
case "push":
|
|
122
|
+
await sendTestPush();
|
|
123
|
+
break;
|
|
124
|
+
case "status":
|
|
125
|
+
case "st":
|
|
126
|
+
await showStatus();
|
|
127
|
+
break;
|
|
128
|
+
case "info":
|
|
129
|
+
case "i":
|
|
130
|
+
case "help":
|
|
131
|
+
case "h":
|
|
132
|
+
await showInfo();
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
await showInfo();
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
main();
|
|
140
|
+
//# sourceMappingURL=cli.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pwa/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * DjangoCFG PWA CLI\n *\n * Usage:\n * pnpm pwa vapid # Generate VAPID keys\n * pnpm pwa send # Send test push notification\n * pnpm pwa status # Show PWA status\n * pnpm pwa info # Show help\n */\n\nimport { consola } from 'consola';\nimport webpush from 'web-push';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nasync function generateVapidKeys() {\n consola.box('VAPID Keys Generator');\n consola.info('Generating new VAPID key pair...\\n');\n\n const vapidKeys = webpush.generateVAPIDKeys();\n\n consola.success('✅ VAPID keys generated!\\n');\n consola.log('Add these to your .env.local:\\n');\n consola.log(`NEXT_PUBLIC_VAPID_PUBLIC_KEY=${vapidKeys.publicKey}`);\n consola.log(`VAPID_PRIVATE_KEY=${vapidKeys.privateKey}`);\n consola.log(`VAPID_MAILTO=mailto:your-email@example.com\\n`);\n\n consola.info('Public key (share with clients):');\n consola.log(` ${vapidKeys.publicKey}\\n`);\n consola.info('Private key (keep secret):');\n consola.log(` ${vapidKeys.privateKey}\\n`);\n}\n\nasync function sendTestPush() {\n consola.box('Send Test Push Notification');\n\n const publicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY;\n const privateKey = process.env.VAPID_PRIVATE_KEY;\n const mailto = process.env.VAPID_MAILTO || 'mailto:test@example.com';\n\n if (!publicKey || !privateKey) {\n consola.error('❌ VAPID keys not configured!');\n consola.info('\\nGenerate keys with:');\n consola.log(' pnpm pwa vapid\\n');\n consola.info('Then add to .env.local:');\n consola.log(' NEXT_PUBLIC_VAPID_PUBLIC_KEY=...');\n consola.log(' VAPID_PRIVATE_KEY=...');\n process.exit(1);\n }\n\n // Get subscription from args or use example\n const subscriptionArg = args[1];\n if (!subscriptionArg) {\n consola.error('❌ Subscription required!\\n');\n consola.info('Usage:');\n consola.log(' pnpm pwa send \\'{\"endpoint\":\"...\",\"keys\":{...}}\\'\\n');\n consola.info('To subscribe and get the JSON, visit the playground:');\n consola.log(' http://djangocfg.com/layouts/a2hs-hint\\n');\n consola.info('Or use the helper command:');\n consola.log(' pnpm exec djangocfg-pwa status\\n');\n process.exit(1);\n }\n\n try {\n const subscription = JSON.parse(subscriptionArg);\n\n webpush.setVapidDetails(mailto, publicKey, privateKey);\n\n const payload = JSON.stringify({\n title: 'Test Push from CLI',\n body: 'This is a test notification sent from @djangocfg/nextjs CLI',\n icon: '/static/logos/192x192.png',\n badge: '/static/logos/192x192.png',\n });\n\n consola.info('Sending push notification...\\n');\n await webpush.sendNotification(subscription, payload);\n consola.success('✅ Push notification sent successfully!');\n } catch (err) {\n consola.error('❌ Failed to send push:', err instanceof Error ? err.message : err);\n process.exit(1);\n }\n}\n\nasync function showStatus() {\n consola.box('PWA Status');\n\n const publicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY;\n const privateKey = process.env.VAPID_PRIVATE_KEY;\n const mailto = process.env.VAPID_MAILTO;\n\n consola.log('Environment Variables:');\n consola.log(` NEXT_PUBLIC_VAPID_PUBLIC_KEY: ${publicKey ? '✅ Set' : '❌ Not set'}`);\n consola.log(` VAPID_PRIVATE_KEY: ${privateKey ? '✅ Set' : '❌ Not set'}`);\n consola.log(` VAPID_MAILTO: ${mailto || '⚠️ Not set (optional)'}\\n`);\n\n if (!publicKey || !privateKey) {\n consola.warn('⚠️ VAPID keys not configured. Run: pnpm pwa vapid\\n');\n } else {\n consola.success('✅ VAPID keys configured\\n');\n consola.log('Public Key:');\n consola.log(` ${publicKey.slice(0, 40)}...\\n`);\n }\n\n consola.log('Quick Start:');\n consola.log(' 1. Generate VAPID keys: pnpm pwa vapid');\n consola.log(' 2. Add to .env.local');\n consola.log(' 3. Visit playground: http://djangocfg.com/layouts/a2hs-hint');\n consola.log(' 4. Send test push: pnpm pwa send \\'<subscription>\\'\\n');\n}\n\nasync function showInfo() {\n consola.box('DjangoCFG PWA CLI');\n consola.log('Commands:');\n consola.log(' vapid Generate VAPID keys');\n consola.log(' send <subscription> Send test push notification');\n consola.log(' status Show PWA configuration status');\n consola.log(' info Show this help\\n');\n\n consola.log('Examples:');\n consola.log(' # Generate VAPID keys');\n consola.log(' pnpm pwa vapid\\n');\n\n consola.log(' # Check status');\n consola.log(' pnpm pwa status\\n');\n\n consola.log(' # Subscribe');\n consola.log(' Visit: http://djangocfg.com/layouts/a2hs-hint\\n');\n\n consola.log(' # Send test push');\n consola.log(' pnpm pwa send \\'{\"endpoint\":\"...\",\"keys\":{\"p256dh\":\"...\",\"auth\":\"...\"}}\\'\\n');\n\n consola.log('Documentation:');\n consola.log(' https://djangocfg.com/docs/pwa');\n}\n\nasync function main() {\n switch (command) {\n case 'vapid':\n case 'v':\n case 'keys':\n await generateVapidKeys();\n break;\n\n case 'send':\n case 's':\n case 'push':\n await sendTestPush();\n break;\n\n case 'status':\n case 'st':\n await showStatus();\n break;\n\n case 'info':\n case 'i':\n case 'help':\n case 'h':\n await showInfo();\n break;\n\n default:\n await showInfo();\n break;\n }\n}\n\nmain();\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { Viewport, Metadata, MetadataRoute } from 'next';
|
|
2
|
+
export { P as PWAPluginOptions, c as createApiCacheRule, b as createCdnCacheRule, a as createStaticAssetRule, d as defaultRuntimeCaching, g as getServiceWorkerTemplate, w as withPWA } from '../plugin-DuRJ_Jq6.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* PWA Push Notifications Client Utilities
|
|
6
|
+
*
|
|
7
|
+
* Functions for requesting permission, subscribing to push notifications,
|
|
8
|
+
* and sending test notifications
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Check if push notifications are supported
|
|
12
|
+
*/
|
|
13
|
+
declare function isPushNotificationSupported(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Get current notification permission status
|
|
16
|
+
*/
|
|
17
|
+
declare function getNotificationPermission(): NotificationPermission;
|
|
18
|
+
/**
|
|
19
|
+
* Request notification permission from user
|
|
20
|
+
*/
|
|
21
|
+
declare function requestNotificationPermission(): Promise<NotificationPermission>;
|
|
22
|
+
interface PushSubscriptionOptions {
|
|
23
|
+
/**
|
|
24
|
+
* VAPID public key (base64 encoded)
|
|
25
|
+
* Generate with: npx web-push generate-vapid-keys
|
|
26
|
+
*/
|
|
27
|
+
vapidPublicKey: string;
|
|
28
|
+
/**
|
|
29
|
+
* User visible only (required for Chrome)
|
|
30
|
+
* @default true
|
|
31
|
+
*/
|
|
32
|
+
userVisibleOnly?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Subscribe to push notifications
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const subscription = await subscribeToPushNotifications({
|
|
40
|
+
* vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* // Send subscription to your backend
|
|
44
|
+
* await fetch('/api/push/subscribe', {
|
|
45
|
+
* method: 'POST',
|
|
46
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
47
|
+
* body: JSON.stringify(subscription),
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function subscribeToPushNotifications(options: PushSubscriptionOptions): Promise<PushSubscription>;
|
|
52
|
+
/**
|
|
53
|
+
* Unsubscribe from push notifications
|
|
54
|
+
*/
|
|
55
|
+
declare function unsubscribeFromPushNotifications(): Promise<boolean>;
|
|
56
|
+
/**
|
|
57
|
+
* Get current push subscription
|
|
58
|
+
*/
|
|
59
|
+
declare function getPushSubscription(): Promise<PushSubscription | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Show a local notification (doesn't require push)
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* await showLocalNotification({
|
|
66
|
+
* title: 'Hello!',
|
|
67
|
+
* body: 'This is a test notification',
|
|
68
|
+
* icon: '/icon.png',
|
|
69
|
+
* data: { url: '/some-page' },
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function showLocalNotification(options: {
|
|
74
|
+
title: string;
|
|
75
|
+
body?: string;
|
|
76
|
+
icon?: string;
|
|
77
|
+
badge?: string;
|
|
78
|
+
tag?: string;
|
|
79
|
+
data?: any;
|
|
80
|
+
requireInteraction?: boolean;
|
|
81
|
+
}): Promise<void>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* PWA Manifest Metadata Utilities
|
|
85
|
+
*
|
|
86
|
+
* Helper functions for creating Next.js metadata for PWA manifest
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
interface ManifestConfig {
|
|
90
|
+
name: string;
|
|
91
|
+
shortName?: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
themeColor?: string;
|
|
94
|
+
backgroundColor?: string;
|
|
95
|
+
display?: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
|
|
96
|
+
orientation?: 'portrait' | 'landscape' | 'any';
|
|
97
|
+
startUrl?: string;
|
|
98
|
+
scope?: string;
|
|
99
|
+
lang?: string;
|
|
100
|
+
dir?: 'ltr' | 'rtl' | 'auto';
|
|
101
|
+
icons?: {
|
|
102
|
+
src: string;
|
|
103
|
+
sizes: string;
|
|
104
|
+
type?: string;
|
|
105
|
+
purpose?: string;
|
|
106
|
+
}[];
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Icon paths configuration
|
|
110
|
+
*/
|
|
111
|
+
interface IconPaths {
|
|
112
|
+
logo192?: string;
|
|
113
|
+
logo384?: string;
|
|
114
|
+
logo512?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Protocol handler configuration
|
|
118
|
+
* Allows your PWA to register as a handler for custom protocols
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* {
|
|
123
|
+
* protocol: "web+music",
|
|
124
|
+
* url: "/play?track=%s"
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
interface ProtocolHandler {
|
|
129
|
+
/** Protocol scheme (e.g., "web+music", "mailto", "magnet") */
|
|
130
|
+
protocol: string;
|
|
131
|
+
/** URL template with %s placeholder for the protocol parameter */
|
|
132
|
+
url: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Create viewport configuration for Next.js app
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* export const viewport: Viewport = createViewport({
|
|
140
|
+
* themeColor: '#ffffff',
|
|
141
|
+
* });
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare function createViewport(config: {
|
|
145
|
+
themeColor?: string;
|
|
146
|
+
}): Viewport;
|
|
147
|
+
/**
|
|
148
|
+
* Create manifest metadata for Next.js app
|
|
149
|
+
*
|
|
150
|
+
* Note: themeColor and viewport should be exported separately using createViewport()
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* export const metadata: Metadata = {
|
|
155
|
+
* ...createManifestMetadata({
|
|
156
|
+
* name: 'My App',
|
|
157
|
+
* shortName: 'App',
|
|
158
|
+
* description: 'My awesome app',
|
|
159
|
+
* }),
|
|
160
|
+
* };
|
|
161
|
+
*
|
|
162
|
+
* export const viewport: Viewport = createViewport({
|
|
163
|
+
* themeColor: '#ffffff',
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
declare function createManifestMetadata(config: ManifestConfig): Metadata;
|
|
168
|
+
/**
|
|
169
|
+
* Create Next.js manifest function
|
|
170
|
+
*
|
|
171
|
+
* Use this in your app/manifest.ts file
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* // app/manifest.ts
|
|
176
|
+
* import { createManifest } from '@djangocfg/nextjs/config';
|
|
177
|
+
* import { settings } from '@core/settings';
|
|
178
|
+
*
|
|
179
|
+
* export default createManifest({
|
|
180
|
+
* name: settings.app.name,
|
|
181
|
+
* description: settings.app.description,
|
|
182
|
+
* icons: {
|
|
183
|
+
* logo192: settings.app.icons.logo192,
|
|
184
|
+
* logo384: settings.app.icons.logo384,
|
|
185
|
+
* logo512: settings.app.icons.logo512,
|
|
186
|
+
* },
|
|
187
|
+
* });
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
interface ScreenshotConfig {
|
|
191
|
+
src: string;
|
|
192
|
+
sizes: string;
|
|
193
|
+
type?: string;
|
|
194
|
+
form_factor?: 'narrow' | 'wide';
|
|
195
|
+
label?: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Smart screenshot configuration
|
|
199
|
+
* Automatically detects everything from path or uses defaults
|
|
200
|
+
*/
|
|
201
|
+
interface SmartScreenshotInput {
|
|
202
|
+
src: string;
|
|
203
|
+
/** Form factor (auto-detected from filename if contains 'desktop'/'mobile', or use default) */
|
|
204
|
+
form_factor?: 'narrow' | 'wide';
|
|
205
|
+
/** Optional label (auto-generated from form_factor) */
|
|
206
|
+
label?: string;
|
|
207
|
+
/** Optional width (defaults based on form_factor) */
|
|
208
|
+
width?: number;
|
|
209
|
+
/** Optional height (defaults based on form_factor) */
|
|
210
|
+
height?: number;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create screenshot config with smart defaults
|
|
214
|
+
* Automatically detects type, sizes, form_factor from path or uses sensible defaults
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* // Minimal - everything auto-detected
|
|
219
|
+
* createScreenshot({ src: '/screenshots/desktop-view.png' })
|
|
220
|
+
* // → form_factor: 'wide', sizes: '1920x1080', type: 'image/png', label: 'Desktop screenshot'
|
|
221
|
+
*
|
|
222
|
+
* createScreenshot({ src: '/screenshots/mobile.png' })
|
|
223
|
+
* // → form_factor: 'narrow', sizes: '390x844', type: 'image/png', label: 'Mobile screenshot'
|
|
224
|
+
*
|
|
225
|
+
* // With custom dimensions
|
|
226
|
+
* createScreenshot({ src: '/screenshots/tablet.png', width: 1024, height: 768 })
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
declare function createScreenshot(input: SmartScreenshotInput | string): ScreenshotConfig;
|
|
230
|
+
/**
|
|
231
|
+
* Create multiple screenshots from array
|
|
232
|
+
* Supports string shorthand or full config objects
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* // Minimal - just paths
|
|
237
|
+
* createScreenshots([
|
|
238
|
+
* '/screenshots/desktop.png', // Auto: wide, 1920x1080
|
|
239
|
+
* '/screenshots/mobile.png', // Auto: narrow, 390x844
|
|
240
|
+
* ])
|
|
241
|
+
*
|
|
242
|
+
* // Mixed
|
|
243
|
+
* createScreenshots([
|
|
244
|
+
* '/screenshots/desktop.png',
|
|
245
|
+
* { src: '/screenshots/tablet.png', width: 1024, height: 768 },
|
|
246
|
+
* ])
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
declare function createScreenshots(inputs: Array<SmartScreenshotInput | string>): ScreenshotConfig[];
|
|
250
|
+
declare function createManifest(config: {
|
|
251
|
+
name: string;
|
|
252
|
+
shortName?: string;
|
|
253
|
+
description?: string;
|
|
254
|
+
themeColor?: string;
|
|
255
|
+
backgroundColor?: string;
|
|
256
|
+
display?: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
|
|
257
|
+
orientation?: 'portrait' | 'landscape' | 'any';
|
|
258
|
+
id?: string;
|
|
259
|
+
startUrl?: string;
|
|
260
|
+
scope?: string;
|
|
261
|
+
lang?: string;
|
|
262
|
+
dir?: 'ltr' | 'rtl' | 'auto';
|
|
263
|
+
icons?: IconPaths | ManifestConfig['icons'];
|
|
264
|
+
screenshots?: ScreenshotConfig[];
|
|
265
|
+
protocol_handlers?: ProtocolHandler[];
|
|
266
|
+
}): () => MetadataRoute.Manifest;
|
|
267
|
+
/**
|
|
268
|
+
* Generate manifest.json content (legacy)
|
|
269
|
+
*
|
|
270
|
+
* @deprecated Use createManifest() instead
|
|
271
|
+
*/
|
|
272
|
+
declare function generateManifest(config: ManifestConfig): Record<string, any>;
|
|
273
|
+
|
|
274
|
+
export { type IconPaths, type ManifestConfig, type ProtocolHandler, type PushSubscriptionOptions, type ScreenshotConfig, type SmartScreenshotInput, createManifest, createManifestMetadata, createScreenshot, createScreenshots, createViewport, generateManifest, getNotificationPermission, getPushSubscription, isPushNotificationSupported, requestNotificationPermission, showLocalNotification, subscribeToPushNotifications, unsubscribeFromPushNotifications };
|