@djangocfg/nextjs 2.1.35 → 2.1.37

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.
Files changed (44) hide show
  1. package/README.md +146 -22
  2. package/dist/config/index.d.mts +7 -409
  3. package/dist/config/index.mjs +79 -394
  4. package/dist/config/index.mjs.map +1 -1
  5. package/dist/index.d.mts +2 -1
  6. package/dist/index.mjs +79 -394
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/plugin-DuRJ_Jq6.d.mts +100 -0
  9. package/dist/pwa/cli.d.mts +1 -0
  10. package/dist/pwa/cli.mjs +140 -0
  11. package/dist/pwa/cli.mjs.map +1 -0
  12. package/dist/pwa/index.d.mts +274 -0
  13. package/dist/pwa/index.mjs +327 -0
  14. package/dist/pwa/index.mjs.map +1 -0
  15. package/dist/pwa/server/index.d.mts +86 -0
  16. package/dist/pwa/server/index.mjs +175 -0
  17. package/dist/pwa/server/index.mjs.map +1 -0
  18. package/dist/pwa/server/routes.d.mts +2 -0
  19. package/dist/pwa/server/routes.mjs +149 -0
  20. package/dist/pwa/server/routes.mjs.map +1 -0
  21. package/dist/pwa/worker/index.d.mts +56 -0
  22. package/dist/pwa/worker/index.mjs +97 -0
  23. package/dist/pwa/worker/index.mjs.map +1 -0
  24. package/dist/routes-DXA29sS_.d.mts +68 -0
  25. package/package.json +38 -9
  26. package/src/config/createNextConfig.ts +9 -13
  27. package/src/config/index.ts +2 -19
  28. package/src/config/plugins/devStartup.ts +35 -36
  29. package/src/config/plugins/index.ts +1 -1
  30. package/src/config/utils/index.ts +0 -1
  31. package/src/index.ts +4 -0
  32. package/src/pwa/cli.ts +171 -0
  33. package/src/pwa/index.ts +9 -0
  34. package/src/pwa/manifest.ts +355 -0
  35. package/src/pwa/notifications.ts +192 -0
  36. package/src/pwa/plugin.ts +194 -0
  37. package/src/pwa/server/index.ts +23 -0
  38. package/src/pwa/server/push.ts +166 -0
  39. package/src/pwa/server/routes.ts +137 -0
  40. package/src/pwa/worker/index.ts +174 -0
  41. package/src/pwa/worker/package.json +3 -0
  42. package/bin/dev-with-browser.js +0 -114
  43. package/src/config/plugins/pwa.ts +0 -616
  44. package/src/config/utils/manifest.ts +0 -195
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Service Worker Utilities
3
+ *
4
+ * Ready-to-use Serwist configuration for Next.js PWA
5
+ */
6
+
7
+ /// <reference lib="webworker" />
8
+
9
+ import { defaultCache } from '@serwist/next/worker';
10
+ import { Serwist } from 'serwist';
11
+
12
+ export interface ServiceWorkerOptions {
13
+ /**
14
+ * Offline fallback URL
15
+ * @default '/_offline'
16
+ */
17
+ offlineFallback?: string;
18
+
19
+ /**
20
+ * Skip waiting - activate new SW immediately
21
+ * @default true
22
+ */
23
+ skipWaiting?: boolean;
24
+
25
+ /**
26
+ * Take control of all clients immediately
27
+ * @default true
28
+ */
29
+ clientsClaim?: boolean;
30
+
31
+ /**
32
+ * Enable navigation preload for faster loads
33
+ * @default true
34
+ */
35
+ navigationPreload?: boolean;
36
+
37
+ /**
38
+ * Enable push notifications
39
+ * @default false
40
+ */
41
+ enablePushNotifications?: boolean;
42
+
43
+ /**
44
+ * Default notification icon
45
+ */
46
+ notificationIcon?: string;
47
+
48
+ /**
49
+ * Default notification badge
50
+ */
51
+ notificationBadge?: string;
52
+ }
53
+
54
+ /**
55
+ * Create and initialize Serwist service worker
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * // app/sw.ts
60
+ * import { createServiceWorker } from '@djangocfg/nextjs/worker';
61
+ *
62
+ * createServiceWorker({
63
+ * offlineFallback: '/_offline',
64
+ * });
65
+ * ```
66
+ */
67
+ export function createServiceWorker(options: ServiceWorkerOptions = {}) {
68
+ const {
69
+ offlineFallback = '/_offline',
70
+ skipWaiting = true,
71
+ clientsClaim = true,
72
+ navigationPreload = true,
73
+ enablePushNotifications = false,
74
+ notificationIcon,
75
+ notificationBadge,
76
+ } = options;
77
+
78
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
+ const self = globalThis as any;
80
+ console.log('SW: Worker Initialized 🚀');
81
+
82
+ const serwist = new Serwist({
83
+ // Precache entries injected by Serwist build plugin
84
+ precacheEntries: self.__SW_MANIFEST,
85
+
86
+ // Skip waiting - activate new SW immediately
87
+ skipWaiting,
88
+
89
+ // Take control of all clients immediately
90
+ clientsClaim,
91
+
92
+ // Enable navigation preload for faster loads
93
+ navigationPreload,
94
+
95
+ // Use default Next.js runtime caching strategies
96
+ runtimeCaching: defaultCache,
97
+
98
+ // Fallback pages for offline
99
+ fallbacks: {
100
+ entries: [
101
+ {
102
+ url: offlineFallback,
103
+ matcher({ request }) {
104
+ return request.destination === 'document';
105
+ },
106
+ },
107
+ ],
108
+ },
109
+ });
110
+
111
+ serwist.addEventListeners();
112
+
113
+ // Push notification support
114
+ if (enablePushNotifications) {
115
+ // Handle push events
116
+ self.addEventListener('push', (event: PushEvent) => {
117
+ let data;
118
+ try {
119
+ data = event.data?.json() || {};
120
+ console.log('SW: Push Received (JSON)', data);
121
+ } catch (err) {
122
+ console.log('SW: Push Received (Raw)', event.data?.text());
123
+ data = {};
124
+ }
125
+
126
+ const {
127
+ title = 'Notification',
128
+ body = '',
129
+ icon = notificationIcon,
130
+ badge = notificationBadge,
131
+ data: notificationData = {},
132
+ tag,
133
+ requireInteraction = false,
134
+ vibrate = [200, 100, 200], // Default vibration pattern
135
+ silent = false, // Default to playing sound
136
+ } = data;
137
+
138
+ event.waitUntil(
139
+ self.registration.showNotification(title, {
140
+ body,
141
+ icon,
142
+ badge,
143
+ data: notificationData,
144
+ tag,
145
+ requireInteraction,
146
+ vibrate,
147
+ silent,
148
+ })
149
+ );
150
+ });
151
+
152
+ // Handle notification clicks
153
+ self.addEventListener('notificationclick', (event: NotificationEvent) => {
154
+ event.notification.close();
155
+
156
+ const urlToOpen = event.notification.data?.url || '/';
157
+
158
+ event.waitUntil(
159
+ self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList: readonly WindowClient[]) => {
160
+ // Check if there's already a window open with the URL
161
+ for (const client of clientList) {
162
+ if (client.url === urlToOpen && 'focus' in client) {
163
+ return client.focus();
164
+ }
165
+ }
166
+ // If not, open a new window
167
+ if (self.clients.openWindow) {
168
+ return self.clients.openWindow(urlToOpen);
169
+ }
170
+ })
171
+ );
172
+ });
173
+ }
174
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -1,114 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Next.js Dev Server with Auto Browser Opening
4
- *
5
- * Cross-platform solution that works with both Turbopack and webpack
6
- * Opens browser automatically when server is ready
7
- *
8
- * Usage:
9
- * "dev": "dev-with-browser"
10
- * "dev": "dev-with-browser --port 3000"
11
- * "dev": "dev-with-browser --webpack"
12
- */
13
-
14
- const { spawn } = require('child_process');
15
- const { exec } = require('child_process');
16
- const consola = require('consola');
17
-
18
- // Parse arguments
19
- const args = process.argv.slice(2);
20
-
21
- // Extract port
22
- let PORT = process.env.PORT || '3000';
23
- const portIndex = args.findIndex(arg => arg === '-p' || arg === '--port');
24
- if (portIndex !== -1 && args[portIndex + 1]) {
25
- PORT = args[portIndex + 1];
26
- }
27
-
28
- // Build next dev command
29
- const nextArgs = ['dev', '-p', PORT];
30
-
31
- // Check if --webpack flag is present
32
- const hasWebpackFlag = args.includes('--webpack');
33
-
34
- // Add --turbopack by default (unless --webpack is specified)
35
- // This silences the "webpack config with no turbopack config" warning
36
- if (!hasWebpackFlag) {
37
- nextArgs.push('--turbopack');
38
- }
39
-
40
- // Pass through other flags, excluding port arguments
41
- args.forEach((arg, i) => {
42
- const isPreviousPort = i > 0 && (args[i - 1] === '-p' || args[i - 1] === '--port');
43
- const isPortFlag = arg === '-p' || arg === '--port';
44
-
45
- if (!isPortFlag && !isPreviousPort) {
46
- nextArgs.push(arg);
47
- }
48
- });
49
-
50
- const URL = `http://localhost:${PORT}`;
51
-
52
- consola.info(`Starting Next.js dev server on port ${PORT}...`);
53
-
54
- // Start Next.js dev server
55
- const devServer = spawn('next', nextArgs, {
56
- stdio: 'inherit',
57
- shell: true,
58
- });
59
-
60
- // Wait for server to be ready, then open browser
61
- let serverReady = false;
62
- let attempts = 0;
63
- const maxAttempts = 60; // 30 seconds max
64
-
65
- const checkInterval = setInterval(async () => {
66
- if (serverReady || attempts >= maxAttempts) {
67
- if (attempts >= maxAttempts) {
68
- consola.warn('Server took too long to start, skipping browser open');
69
- }
70
- clearInterval(checkInterval);
71
- return;
72
- }
73
-
74
- attempts++;
75
-
76
- try {
77
- const response = await fetch(URL);
78
- if (response.ok) {
79
- serverReady = true;
80
- clearInterval(checkInterval);
81
-
82
- consola.success(`Server ready! Opening browser at ${URL}`);
83
-
84
- // Open browser (cross-platform)
85
- const command = process.platform === 'darwin'
86
- ? 'open'
87
- : process.platform === 'win32'
88
- ? 'start'
89
- : 'xdg-open';
90
-
91
- exec(`${command} ${URL}`, (error) => {
92
- if (error) {
93
- consola.warn(`Failed to open browser: ${error.message}`);
94
- consola.info(`Please open manually: ${URL}`);
95
- }
96
- });
97
- }
98
- } catch (err) {
99
- // Server not ready yet, continue checking
100
- }
101
- }, 500);
102
-
103
- // Cleanup on exit
104
- process.on('SIGINT', () => {
105
- clearInterval(checkInterval);
106
- devServer.kill();
107
- process.exit();
108
- });
109
-
110
- process.on('SIGTERM', () => {
111
- clearInterval(checkInterval);
112
- devServer.kill();
113
- process.exit();
114
- });