@djangocfg/nextjs 2.1.42 → 2.1.43
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/dist/ai/cli.mjs.map +1 -1
- package/dist/ai/index.mjs.map +1 -1
- package/dist/config/index.mjs +261 -263
- package/dist/config/index.mjs.map +1 -1
- package/dist/health/index.mjs.map +1 -1
- package/dist/index.mjs +580 -582
- package/dist/index.mjs.map +1 -1
- package/dist/og-image/index.mjs +468 -468
- package/dist/og-image/index.mjs.map +1 -1
- package/dist/og-image/utils/index.mjs.map +1 -1
- package/dist/pwa/server/index.mjs +1 -1
- package/dist/pwa/server/index.mjs.map +1 -1
- package/dist/pwa/server/routes.mjs +1 -1
- package/dist/pwa/server/routes.mjs.map +1 -1
- package/dist/pwa/worker/index.mjs +1 -1
- package/dist/pwa/worker/index.mjs.map +1 -1
- package/dist/scripts/index.mjs +75 -73
- package/dist/scripts/index.mjs.map +1 -1
- package/dist/sitemap/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/ai/cli.ts +2 -1
- package/src/ai/client.ts +2 -6
- package/src/config/createNextConfig.ts +5 -5
- package/src/config/packages/checker.ts +3 -2
- package/src/config/packages/installer.ts +6 -5
- package/src/config/packages/updater.ts +5 -4
- package/src/config/plugins/devStartup.ts +3 -2
- package/src/config/utils/version.ts +4 -3
- package/src/health/route.ts +1 -0
- package/src/og-image/route.tsx +4 -2
- package/src/og-image/utils/metadata.ts +1 -1
- package/src/pwa/server/push.ts +1 -1
- package/src/pwa/server/routes.ts +1 -0
- package/src/pwa/worker/index.ts +2 -1
- package/src/scripts/check-links.ts +4 -4
- package/src/sitemap/route.ts +3 -1
package/dist/config/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports, module) {
|
|
15
15
|
module.exports = {
|
|
16
16
|
name: "@djangocfg/nextjs",
|
|
17
|
-
version: "2.1.
|
|
17
|
+
version: "2.1.43",
|
|
18
18
|
description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
19
19
|
keywords: [
|
|
20
20
|
"nextjs",
|
|
@@ -179,6 +179,37 @@ var require_package = __commonJS({
|
|
|
179
179
|
}
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
+
// src/pwa/plugin.ts
|
|
183
|
+
import { consola } from "consola";
|
|
184
|
+
function withPWA(nextConfig, options = {}) {
|
|
185
|
+
const isDev2 = process.env.NODE_ENV === "development";
|
|
186
|
+
const isStaticBuild2 = process.env.NEXT_PUBLIC_STATIC_BUILD === "true";
|
|
187
|
+
const shouldDisable = options.disable !== void 0 ? options.disable : isDev2 || isStaticBuild2;
|
|
188
|
+
const defaultOptions = {
|
|
189
|
+
swSrc: "app/sw.ts",
|
|
190
|
+
swDest: "public/sw.js",
|
|
191
|
+
disable: shouldDisable,
|
|
192
|
+
cacheOnNavigation: true,
|
|
193
|
+
reloadOnOnline: true,
|
|
194
|
+
...options
|
|
195
|
+
};
|
|
196
|
+
try {
|
|
197
|
+
const withSerwistInit = __require("@serwist/next").default;
|
|
198
|
+
const withSerwist = withSerwistInit({
|
|
199
|
+
swSrc: defaultOptions.swSrc,
|
|
200
|
+
swDest: defaultOptions.swDest,
|
|
201
|
+
disable: defaultOptions.disable,
|
|
202
|
+
cacheOnNavigation: defaultOptions.cacheOnNavigation,
|
|
203
|
+
reloadOnOnline: defaultOptions.reloadOnOnline,
|
|
204
|
+
...defaultOptions.serwistOptions
|
|
205
|
+
});
|
|
206
|
+
return withSerwist(nextConfig);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
consola.error("Failed to configure Serwist:", error);
|
|
209
|
+
return nextConfig;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
182
213
|
// src/config/constants.ts
|
|
183
214
|
var PACKAGE_NAME = "@djangocfg/nextjs";
|
|
184
215
|
var VERSION_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -215,26 +246,9 @@ var DEFAULT_OPTIMIZE_PACKAGES = [
|
|
|
215
246
|
"recharts"
|
|
216
247
|
];
|
|
217
248
|
|
|
218
|
-
// src/config/
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
for (const key in source) {
|
|
222
|
-
if (source[key] === void 0) continue;
|
|
223
|
-
if (Array.isArray(source[key])) {
|
|
224
|
-
output[key] = source[key];
|
|
225
|
-
} else if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
226
|
-
const targetValue = output[key];
|
|
227
|
-
if (targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
228
|
-
output[key] = deepMerge(targetValue, source[key]);
|
|
229
|
-
} else {
|
|
230
|
-
output[key] = source[key];
|
|
231
|
-
}
|
|
232
|
-
} else {
|
|
233
|
-
output[key] = source[key];
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return output;
|
|
237
|
-
}
|
|
249
|
+
// src/config/packages/checker.ts
|
|
250
|
+
import { createRequire } from "module";
|
|
251
|
+
import { join } from "path";
|
|
238
252
|
|
|
239
253
|
// src/config/utils/env.ts
|
|
240
254
|
var isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === "true";
|
|
@@ -252,121 +266,6 @@ function getSiteUrl() {
|
|
|
252
266
|
return isStaticBuild ? "" : process.env.NEXT_PUBLIC_SITE_URL || "";
|
|
253
267
|
}
|
|
254
268
|
|
|
255
|
-
// src/config/plugins/devStartup.ts
|
|
256
|
-
import chalk4 from "chalk";
|
|
257
|
-
|
|
258
|
-
// src/ai/constants.ts
|
|
259
|
-
var MCP_BASE_URL = "https://mcp.djangocfg.com";
|
|
260
|
-
var MCP_SERVER_URL = `${MCP_BASE_URL}/mcp`;
|
|
261
|
-
var MCP_API_URL = `${MCP_BASE_URL}/api/search`;
|
|
262
|
-
var AI_DOCS_HINT = `\u{1F916} AI Docs: ${MCP_SERVER_URL} | pnpm ai-docs search "query"`;
|
|
263
|
-
var AI_HINT = `
|
|
264
|
-
DjangoCFG Documentation is available via MCP server.
|
|
265
|
-
|
|
266
|
-
To get help with DjangoCFG configuration:
|
|
267
|
-
1. Use the MCP server: ${MCP_SERVER_URL}
|
|
268
|
-
2. Or search directly: ${MCP_API_URL}?q=YOUR_QUERY&limit=5
|
|
269
|
-
|
|
270
|
-
Example queries:
|
|
271
|
-
- "How to configure PostgreSQL database?"
|
|
272
|
-
- "What is DatabaseConfig?"
|
|
273
|
-
- "How to setup Redis cache?"
|
|
274
|
-
- "Email configuration with SMTP"
|
|
275
|
-
`;
|
|
276
|
-
|
|
277
|
-
// src/config/utils/version.ts
|
|
278
|
-
import chalk from "chalk";
|
|
279
|
-
import semver from "semver";
|
|
280
|
-
import consola from "consola";
|
|
281
|
-
import Conf from "conf";
|
|
282
|
-
var versionCache = new Conf({
|
|
283
|
-
projectName: "djangocfg-nextjs",
|
|
284
|
-
projectVersion: "1.0.0"
|
|
285
|
-
});
|
|
286
|
-
function getCurrentVersion() {
|
|
287
|
-
try {
|
|
288
|
-
const packageJson = require_package();
|
|
289
|
-
return packageJson.version || null;
|
|
290
|
-
} catch {
|
|
291
|
-
return null;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
async function fetchLatestVersion() {
|
|
295
|
-
const lastCheck = versionCache.get("lastCheck") || 0;
|
|
296
|
-
const cachedVersion = versionCache.get("latestVersion");
|
|
297
|
-
if (cachedVersion && Date.now() - lastCheck < VERSION_CACHE_TTL_MS) {
|
|
298
|
-
return cachedVersion;
|
|
299
|
-
}
|
|
300
|
-
try {
|
|
301
|
-
const https = await import("https");
|
|
302
|
-
return new Promise((resolve) => {
|
|
303
|
-
const req = https.get(
|
|
304
|
-
`https://registry.npmjs.org/${PACKAGE_NAME}/latest`,
|
|
305
|
-
{ timeout: 5e3 },
|
|
306
|
-
(res) => {
|
|
307
|
-
let data = "";
|
|
308
|
-
res.on("data", (chunk) => {
|
|
309
|
-
data += chunk;
|
|
310
|
-
});
|
|
311
|
-
res.on("end", () => {
|
|
312
|
-
try {
|
|
313
|
-
const json = JSON.parse(data);
|
|
314
|
-
const version = json.version || null;
|
|
315
|
-
if (version) {
|
|
316
|
-
versionCache.set("latestVersion", version);
|
|
317
|
-
versionCache.set("lastCheck", Date.now());
|
|
318
|
-
}
|
|
319
|
-
resolve(version);
|
|
320
|
-
} catch {
|
|
321
|
-
resolve(cachedVersion || null);
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
);
|
|
326
|
-
req.on("error", () => resolve(cachedVersion || null));
|
|
327
|
-
req.on("timeout", () => {
|
|
328
|
-
req.destroy();
|
|
329
|
-
resolve(cachedVersion || null);
|
|
330
|
-
});
|
|
331
|
-
});
|
|
332
|
-
} catch {
|
|
333
|
-
return cachedVersion || null;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
async function checkForUpdate() {
|
|
337
|
-
const currentVersion = getCurrentVersion();
|
|
338
|
-
if (!currentVersion) {
|
|
339
|
-
return { hasUpdate: false, currentVersion: null, latestVersion: null };
|
|
340
|
-
}
|
|
341
|
-
const latestVersion = await fetchLatestVersion();
|
|
342
|
-
const hasUpdate = !!(latestVersion && semver.gt(latestVersion, currentVersion));
|
|
343
|
-
return { hasUpdate, currentVersion, latestVersion };
|
|
344
|
-
}
|
|
345
|
-
function getUpdateCommand() {
|
|
346
|
-
return `pnpm add ${DJANGOCFG_PACKAGES.map((p) => `${p}@latest`).join(" ")}`;
|
|
347
|
-
}
|
|
348
|
-
async function printVersionInfo() {
|
|
349
|
-
const { hasUpdate, currentVersion, latestVersion } = await checkForUpdate();
|
|
350
|
-
if (!currentVersion) return;
|
|
351
|
-
consola.box(`\u{1F4E6} @djangocfg/nextjs v${currentVersion}`);
|
|
352
|
-
if (hasUpdate && latestVersion) {
|
|
353
|
-
consola.warn(`Update Available! ${chalk.red(currentVersion)} \u2192 ${chalk.green(latestVersion)}`);
|
|
354
|
-
consola.info(`Run: ${chalk.cyan(getUpdateCommand())}`);
|
|
355
|
-
console.log("");
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// src/config/packages/installer.ts
|
|
360
|
-
import { execSync, spawn } from "child_process";
|
|
361
|
-
import { createInterface } from "readline";
|
|
362
|
-
import chalk2 from "chalk";
|
|
363
|
-
import consola2 from "consola";
|
|
364
|
-
import Conf2 from "conf";
|
|
365
|
-
|
|
366
|
-
// src/config/packages/checker.ts
|
|
367
|
-
import { createRequire } from "module";
|
|
368
|
-
import { join } from "path";
|
|
369
|
-
|
|
370
269
|
// src/config/packages/definitions.ts
|
|
371
270
|
var OPTIONAL_PACKAGES = [
|
|
372
271
|
{
|
|
@@ -460,8 +359,87 @@ function getReasonText(pkg) {
|
|
|
460
359
|
}
|
|
461
360
|
}
|
|
462
361
|
|
|
362
|
+
// src/config/plugins/compression.ts
|
|
363
|
+
var DEFAULT_OPTIONS = {
|
|
364
|
+
gzip: true,
|
|
365
|
+
brotli: true,
|
|
366
|
+
threshold: 8192,
|
|
367
|
+
minRatio: 0.8,
|
|
368
|
+
brotliLevel: 8
|
|
369
|
+
};
|
|
370
|
+
function addCompressionPlugins(config, options = {}) {
|
|
371
|
+
if (!isPackageInstalled("compression-webpack-plugin")) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
375
|
+
try {
|
|
376
|
+
const CompressionPlugin = __require("compression-webpack-plugin");
|
|
377
|
+
if (!config.plugins) {
|
|
378
|
+
config.plugins = [];
|
|
379
|
+
}
|
|
380
|
+
if (opts.gzip) {
|
|
381
|
+
config.plugins.push(
|
|
382
|
+
new CompressionPlugin({
|
|
383
|
+
filename: "[path][base].gz",
|
|
384
|
+
algorithm: "gzip",
|
|
385
|
+
test: /\.(js|css|html|svg|json)$/,
|
|
386
|
+
threshold: opts.threshold,
|
|
387
|
+
minRatio: opts.minRatio
|
|
388
|
+
})
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
if (opts.brotli) {
|
|
392
|
+
config.plugins.push(
|
|
393
|
+
new CompressionPlugin({
|
|
394
|
+
filename: "[path][base].br",
|
|
395
|
+
algorithm: "brotliCompress",
|
|
396
|
+
test: /\.(js|css|html|svg|json)$/,
|
|
397
|
+
threshold: opts.threshold,
|
|
398
|
+
minRatio: opts.minRatio,
|
|
399
|
+
compressionOptions: {
|
|
400
|
+
level: opts.brotliLevel
|
|
401
|
+
}
|
|
402
|
+
})
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
return true;
|
|
406
|
+
} catch (error) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function isCompressionAvailable() {
|
|
411
|
+
return isPackageInstalled("compression-webpack-plugin");
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// src/config/plugins/devStartup.ts
|
|
415
|
+
import chalk4 from "chalk";
|
|
416
|
+
|
|
417
|
+
// src/ai/constants.ts
|
|
418
|
+
var MCP_BASE_URL = "https://mcp.djangocfg.com";
|
|
419
|
+
var MCP_SERVER_URL = `${MCP_BASE_URL}/mcp`;
|
|
420
|
+
var MCP_API_URL = `${MCP_BASE_URL}/api/search`;
|
|
421
|
+
var AI_DOCS_HINT = `\u{1F916} AI Docs: ${MCP_SERVER_URL} | pnpm ai-docs search "query"`;
|
|
422
|
+
var AI_HINT = `
|
|
423
|
+
DjangoCFG Documentation is available via MCP server.
|
|
424
|
+
|
|
425
|
+
To get help with DjangoCFG configuration:
|
|
426
|
+
1. Use the MCP server: ${MCP_SERVER_URL}
|
|
427
|
+
2. Or search directly: ${MCP_API_URL}?q=YOUR_QUERY&limit=5
|
|
428
|
+
|
|
429
|
+
Example queries:
|
|
430
|
+
- "How to configure PostgreSQL database?"
|
|
431
|
+
- "What is DatabaseConfig?"
|
|
432
|
+
- "How to setup Redis cache?"
|
|
433
|
+
- "Email configuration with SMTP"
|
|
434
|
+
`;
|
|
435
|
+
|
|
463
436
|
// src/config/packages/installer.ts
|
|
464
|
-
|
|
437
|
+
import chalk from "chalk";
|
|
438
|
+
import { execSync, spawn } from "child_process";
|
|
439
|
+
import Conf from "conf";
|
|
440
|
+
import consola2 from "consola";
|
|
441
|
+
import { createInterface } from "readline";
|
|
442
|
+
var installerCache = new Conf({
|
|
465
443
|
projectName: "djangocfg-nextjs-installer",
|
|
466
444
|
projectVersion: "1.0.0"
|
|
467
445
|
});
|
|
@@ -555,7 +533,7 @@ function createSpinner(text) {
|
|
|
555
533
|
let currentText = text;
|
|
556
534
|
const render = () => {
|
|
557
535
|
const frame = SPINNER_FRAMES[frameIndex];
|
|
558
|
-
process.stdout.write(`\r${
|
|
536
|
+
process.stdout.write(`\r${chalk.cyan(frame)} ${currentText}`);
|
|
559
537
|
frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
|
|
560
538
|
};
|
|
561
539
|
return {
|
|
@@ -578,20 +556,20 @@ function createSpinner(text) {
|
|
|
578
556
|
succeed(text2) {
|
|
579
557
|
if (interval) clearInterval(interval);
|
|
580
558
|
if (process.stdout.isTTY) {
|
|
581
|
-
process.stdout.write(`\r${
|
|
559
|
+
process.stdout.write(`\r${chalk.green("\u2713")} ${text2 || currentText}
|
|
582
560
|
`);
|
|
583
561
|
} else {
|
|
584
|
-
console.log(` ${
|
|
562
|
+
console.log(` ${chalk.green("\u2713")} ${text2 || currentText}`);
|
|
585
563
|
}
|
|
586
564
|
return this;
|
|
587
565
|
},
|
|
588
566
|
fail(text2) {
|
|
589
567
|
if (interval) clearInterval(interval);
|
|
590
568
|
if (process.stdout.isTTY) {
|
|
591
|
-
process.stdout.write(`\r${
|
|
569
|
+
process.stdout.write(`\r${chalk.red("\u2717")} ${text2 || currentText}
|
|
592
570
|
`);
|
|
593
571
|
} else {
|
|
594
|
-
console.log(` ${
|
|
572
|
+
console.log(` ${chalk.red("\u2717")} ${text2 || currentText}`);
|
|
595
573
|
}
|
|
596
574
|
return this;
|
|
597
575
|
},
|
|
@@ -607,7 +585,7 @@ function createSpinner(text) {
|
|
|
607
585
|
async function installSinglePackage(pkg, pm, index, total) {
|
|
608
586
|
const command = buildSingleInstallCommand(pkg.name, pkg.devDependency, pm);
|
|
609
587
|
const progress = `[${index + 1}/${total}]`;
|
|
610
|
-
const spinner = createSpinner(`${
|
|
588
|
+
const spinner = createSpinner(`${chalk.dim(progress)} Installing ${chalk.cyan(pkg.name)}...`);
|
|
611
589
|
spinner.start();
|
|
612
590
|
return new Promise((resolve) => {
|
|
613
591
|
const [cmd, ...args] = command.split(" ");
|
|
@@ -622,18 +600,18 @@ async function installSinglePackage(pkg, pm, index, total) {
|
|
|
622
600
|
});
|
|
623
601
|
proc.on("close", (code) => {
|
|
624
602
|
if (code === 0) {
|
|
625
|
-
spinner.succeed(`${
|
|
603
|
+
spinner.succeed(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.green("installed")}`);
|
|
626
604
|
resolve(true);
|
|
627
605
|
} else {
|
|
628
|
-
spinner.fail(`${
|
|
606
|
+
spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red("failed")}`);
|
|
629
607
|
if (stderr) {
|
|
630
|
-
console.log(
|
|
608
|
+
console.log(chalk.dim(` ${stderr.split("\n")[0]}`));
|
|
631
609
|
}
|
|
632
610
|
resolve(false);
|
|
633
611
|
}
|
|
634
612
|
});
|
|
635
613
|
proc.on("error", () => {
|
|
636
|
-
spinner.fail(`${
|
|
614
|
+
spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red("failed")}`);
|
|
637
615
|
resolve(false);
|
|
638
616
|
});
|
|
639
617
|
});
|
|
@@ -643,7 +621,7 @@ async function installPackagesWithProgress(packages) {
|
|
|
643
621
|
const pm = detectPackageManager();
|
|
644
622
|
const total = packages.length;
|
|
645
623
|
console.log("");
|
|
646
|
-
console.log(
|
|
624
|
+
console.log(chalk.bold(` Installing ${total} package${total > 1 ? "s" : ""}...`));
|
|
647
625
|
console.log("");
|
|
648
626
|
let successCount = 0;
|
|
649
627
|
let failedPackages = [];
|
|
@@ -674,7 +652,7 @@ async function installPackages(packages) {
|
|
|
674
652
|
if (packages.length === 0) return true;
|
|
675
653
|
const pm = detectPackageManager();
|
|
676
654
|
const command = buildInstallCommand(packages, pm);
|
|
677
|
-
consola2.info(`Installing: ${
|
|
655
|
+
consola2.info(`Installing: ${chalk.cyan(packages.map((p) => p.name).join(", "))}`);
|
|
678
656
|
const spinner = createSpinner("Installing packages...");
|
|
679
657
|
spinner.start();
|
|
680
658
|
return new Promise((resolve) => {
|
|
@@ -717,24 +695,24 @@ async function checkAndInstallPackages(options = {}) {
|
|
|
717
695
|
consola2.box("\u{1F4E6} Missing Optional Packages");
|
|
718
696
|
console.log("");
|
|
719
697
|
for (const pkg of toInstall) {
|
|
720
|
-
console.log(` ${
|
|
721
|
-
console.log(` ${
|
|
722
|
-
console.log(` ${
|
|
698
|
+
console.log(` ${chalk.yellow("\u2022")} ${chalk.bold(pkg.name)}`);
|
|
699
|
+
console.log(` ${chalk.dim(pkg.description)}`);
|
|
700
|
+
console.log(` ${chalk.dim(pkg.reason)}`);
|
|
723
701
|
console.log("");
|
|
724
702
|
}
|
|
725
703
|
const pm = detectPackageManager();
|
|
726
704
|
const command = buildInstallCommand(toInstall, pm);
|
|
727
|
-
console.log(` ${
|
|
705
|
+
console.log(` ${chalk.cyan("Command:")} ${command}`);
|
|
728
706
|
console.log("");
|
|
729
707
|
installerCache.set("lastPrompt", Date.now());
|
|
730
708
|
const shouldInstall = await askConfirmation(
|
|
731
|
-
`${
|
|
709
|
+
`${chalk.green("?")} Install these packages now? ${chalk.dim("[Y/n]")} `
|
|
732
710
|
);
|
|
733
711
|
if (shouldInstall) {
|
|
734
712
|
const success = await installPackages(toInstall);
|
|
735
713
|
if (success) {
|
|
736
714
|
const enableAuto = await askConfirmation(
|
|
737
|
-
`${
|
|
715
|
+
`${chalk.green("?")} Enable auto-install for future? ${chalk.dim("[y/N]")} `
|
|
738
716
|
);
|
|
739
717
|
if (enableAuto) {
|
|
740
718
|
installerCache.set("autoInstall", true);
|
|
@@ -744,7 +722,7 @@ async function checkAndInstallPackages(options = {}) {
|
|
|
744
722
|
return success;
|
|
745
723
|
}
|
|
746
724
|
const skipPermanently = await askConfirmation(
|
|
747
|
-
`${
|
|
725
|
+
`${chalk.green("?")} Skip these packages in future prompts? ${chalk.dim("[y/N]")} `
|
|
748
726
|
);
|
|
749
727
|
if (skipPermanently) {
|
|
750
728
|
const currentSkip = installerCache.get("skipPackages") || [];
|
|
@@ -758,7 +736,7 @@ function printMissingPackagesInfo(packages) {
|
|
|
758
736
|
const pm = detectPackageManager();
|
|
759
737
|
const command = buildInstallCommand(packages, pm);
|
|
760
738
|
consola2.warn(`Missing optional packages: ${packages.map((p) => p.name).join(", ")}`);
|
|
761
|
-
consola2.info(`Install with: ${
|
|
739
|
+
consola2.info(`Install with: ${chalk.cyan(command)}`);
|
|
762
740
|
}
|
|
763
741
|
function resetInstallerPreferences() {
|
|
764
742
|
installerCache.clear();
|
|
@@ -766,15 +744,15 @@ function resetInstallerPreferences() {
|
|
|
766
744
|
}
|
|
767
745
|
|
|
768
746
|
// src/config/packages/updater.ts
|
|
747
|
+
import chalk2 from "chalk";
|
|
769
748
|
import { spawn as spawn2 } from "child_process";
|
|
770
|
-
import
|
|
749
|
+
import Conf2 from "conf";
|
|
750
|
+
import consola3 from "consola";
|
|
771
751
|
import { createRequire as createRequire2 } from "module";
|
|
772
752
|
import { join as join2 } from "path";
|
|
773
|
-
import
|
|
774
|
-
import
|
|
775
|
-
|
|
776
|
-
import semver2 from "semver";
|
|
777
|
-
var updaterCache = new Conf3({
|
|
753
|
+
import { createInterface as createInterface2 } from "readline";
|
|
754
|
+
import semver from "semver";
|
|
755
|
+
var updaterCache = new Conf2({
|
|
778
756
|
projectName: "djangocfg-nextjs-updater",
|
|
779
757
|
projectVersion: "1.0.0"
|
|
780
758
|
});
|
|
@@ -821,7 +799,7 @@ function getInstalledVersion(packageName) {
|
|
|
821
799
|
function shouldCheckUpdates(packageName) {
|
|
822
800
|
return !isWorkspacePackage(packageName);
|
|
823
801
|
}
|
|
824
|
-
async function
|
|
802
|
+
async function fetchLatestVersion(packageName) {
|
|
825
803
|
try {
|
|
826
804
|
const https = await import("https");
|
|
827
805
|
return new Promise((resolve) => {
|
|
@@ -855,7 +833,7 @@ async function fetchLatestVersion2(packageName) {
|
|
|
855
833
|
}
|
|
856
834
|
async function checkForUpdates(options = {}) {
|
|
857
835
|
const results = [];
|
|
858
|
-
const masterLatest = await
|
|
836
|
+
const masterLatest = await fetchLatestVersion(PACKAGE_NAME);
|
|
859
837
|
if (!masterLatest) {
|
|
860
838
|
return results;
|
|
861
839
|
}
|
|
@@ -868,7 +846,7 @@ async function checkForUpdates(options = {}) {
|
|
|
868
846
|
if (!current) {
|
|
869
847
|
return null;
|
|
870
848
|
}
|
|
871
|
-
const hasUpdate = !!(masterLatest && current &&
|
|
849
|
+
const hasUpdate = !!(masterLatest && current && semver.gt(masterLatest, current));
|
|
872
850
|
return { name, current, latest: masterLatest, hasUpdate };
|
|
873
851
|
});
|
|
874
852
|
const checkResults = await Promise.all(checks);
|
|
@@ -894,7 +872,7 @@ function createSpinner2(text) {
|
|
|
894
872
|
let currentText = text;
|
|
895
873
|
const render = () => {
|
|
896
874
|
const frame = SPINNER_FRAMES2[frameIndex];
|
|
897
|
-
process.stdout.write(`\r${
|
|
875
|
+
process.stdout.write(`\r${chalk2.cyan(frame)} ${currentText}`);
|
|
898
876
|
frameIndex = (frameIndex + 1) % SPINNER_FRAMES2.length;
|
|
899
877
|
};
|
|
900
878
|
return {
|
|
@@ -914,20 +892,20 @@ function createSpinner2(text) {
|
|
|
914
892
|
succeed(text2) {
|
|
915
893
|
if (interval) clearInterval(interval);
|
|
916
894
|
if (process.stdout.isTTY) {
|
|
917
|
-
process.stdout.write(`\r${
|
|
895
|
+
process.stdout.write(`\r${chalk2.green("\u2713")} ${text2 || currentText}
|
|
918
896
|
`);
|
|
919
897
|
} else {
|
|
920
|
-
console.log(` ${
|
|
898
|
+
console.log(` ${chalk2.green("\u2713")} ${text2 || currentText}`);
|
|
921
899
|
}
|
|
922
900
|
return this;
|
|
923
901
|
},
|
|
924
902
|
fail(text2) {
|
|
925
903
|
if (interval) clearInterval(interval);
|
|
926
904
|
if (process.stdout.isTTY) {
|
|
927
|
-
process.stdout.write(`\r${
|
|
905
|
+
process.stdout.write(`\r${chalk2.red("\u2717")} ${text2 || currentText}
|
|
928
906
|
`);
|
|
929
907
|
} else {
|
|
930
|
-
console.log(` ${
|
|
908
|
+
console.log(` ${chalk2.red("\u2717")} ${text2 || currentText}`);
|
|
931
909
|
}
|
|
932
910
|
return this;
|
|
933
911
|
},
|
|
@@ -958,9 +936,9 @@ async function askConfirmation2(question) {
|
|
|
958
936
|
}
|
|
959
937
|
async function updateSinglePackage(pkg, pm, index, total) {
|
|
960
938
|
const progress = `[${index + 1}/${total}]`;
|
|
961
|
-
const versionInfo = `${
|
|
939
|
+
const versionInfo = `${chalk2.red(pkg.current)} \u2192 ${chalk2.green(pkg.latest)}`;
|
|
962
940
|
const spinner = createSpinner2(
|
|
963
|
-
`${
|
|
941
|
+
`${chalk2.dim(progress)} Updating ${chalk2.cyan(pkg.name)} ${versionInfo}`
|
|
964
942
|
);
|
|
965
943
|
spinner.start();
|
|
966
944
|
const command = pm === "pnpm" ? `pnpm add ${pkg.name}@latest` : pm === "yarn" ? `yarn add ${pkg.name}@latest` : `npm install ${pkg.name}@latest`;
|
|
@@ -973,18 +951,18 @@ async function updateSinglePackage(pkg, pm, index, total) {
|
|
|
973
951
|
proc.on("close", (code) => {
|
|
974
952
|
if (code === 0) {
|
|
975
953
|
spinner.succeed(
|
|
976
|
-
`${
|
|
954
|
+
`${chalk2.dim(progress)} ${chalk2.cyan(pkg.name)} ${chalk2.green(pkg.latest)}`
|
|
977
955
|
);
|
|
978
956
|
resolve(true);
|
|
979
957
|
} else {
|
|
980
958
|
spinner.fail(
|
|
981
|
-
`${
|
|
959
|
+
`${chalk2.dim(progress)} ${chalk2.cyan(pkg.name)} ${chalk2.red("failed")}`
|
|
982
960
|
);
|
|
983
961
|
resolve(false);
|
|
984
962
|
}
|
|
985
963
|
});
|
|
986
964
|
proc.on("error", () => {
|
|
987
|
-
spinner.fail(`${
|
|
965
|
+
spinner.fail(`${chalk2.dim(progress)} ${chalk2.cyan(pkg.name)} ${chalk2.red("failed")}`);
|
|
988
966
|
resolve(false);
|
|
989
967
|
});
|
|
990
968
|
});
|
|
@@ -994,7 +972,7 @@ async function updatePackagesWithProgress(packages) {
|
|
|
994
972
|
const pm = detectPackageManager();
|
|
995
973
|
const total = packages.length;
|
|
996
974
|
console.log("");
|
|
997
|
-
console.log(
|
|
975
|
+
console.log(chalk2.bold(` Updating ${total} package${total > 1 ? "s" : ""}...`));
|
|
998
976
|
console.log("");
|
|
999
977
|
let successCount = 0;
|
|
1000
978
|
const failedPackages = [];
|
|
@@ -1030,9 +1008,9 @@ async function checkAndUpdatePackages(options = {}) {
|
|
|
1030
1008
|
forceCheckWorkspace: options.forceCheckWorkspace
|
|
1031
1009
|
});
|
|
1032
1010
|
spinner.stop();
|
|
1033
|
-
console.log(
|
|
1011
|
+
console.log(chalk2.dim(` Found ${outdated.length} outdated package(s)`));
|
|
1034
1012
|
if (outdated.length === 0) {
|
|
1035
|
-
console.log(
|
|
1013
|
+
console.log(chalk2.green(" \u2713 All packages are up to date"));
|
|
1036
1014
|
return true;
|
|
1037
1015
|
}
|
|
1038
1016
|
if (options.autoUpdate || updaterCache.get("autoUpdate")) {
|
|
@@ -1043,18 +1021,18 @@ async function checkAndUpdatePackages(options = {}) {
|
|
|
1043
1021
|
console.log("");
|
|
1044
1022
|
for (const pkg of outdated) {
|
|
1045
1023
|
console.log(
|
|
1046
|
-
` ${
|
|
1024
|
+
` ${chalk2.yellow("\u2022")} ${chalk2.bold(pkg.name)} ${chalk2.red(pkg.current)} \u2192 ${chalk2.green(pkg.latest)}`
|
|
1047
1025
|
);
|
|
1048
1026
|
}
|
|
1049
1027
|
console.log("");
|
|
1050
1028
|
const shouldUpdate = await askConfirmation2(
|
|
1051
|
-
`${
|
|
1029
|
+
`${chalk2.green("?")} Update these packages now? ${chalk2.dim("[Y/n]")} `
|
|
1052
1030
|
);
|
|
1053
1031
|
if (shouldUpdate) {
|
|
1054
1032
|
const success = await updatePackagesWithProgress(outdated);
|
|
1055
1033
|
if (success) {
|
|
1056
1034
|
const enableAuto = await askConfirmation2(
|
|
1057
|
-
`${
|
|
1035
|
+
`${chalk2.green("?")} Enable auto-update for future? ${chalk2.dim("[y/N]")} `
|
|
1058
1036
|
);
|
|
1059
1037
|
if (enableAuto) {
|
|
1060
1038
|
updaterCache.set("autoUpdate", true);
|
|
@@ -1064,7 +1042,7 @@ async function checkAndUpdatePackages(options = {}) {
|
|
|
1064
1042
|
return success;
|
|
1065
1043
|
}
|
|
1066
1044
|
const skipVersions = await askConfirmation2(
|
|
1067
|
-
`${
|
|
1045
|
+
`${chalk2.green("?")} Skip these versions in future? ${chalk2.dim("[y/N]")} `
|
|
1068
1046
|
);
|
|
1069
1047
|
if (skipVersions) {
|
|
1070
1048
|
const skipped = updaterCache.get("skippedVersions") || {};
|
|
@@ -1083,6 +1061,88 @@ function resetUpdaterPreferences() {
|
|
|
1083
1061
|
consola3.success("Updater preferences reset");
|
|
1084
1062
|
}
|
|
1085
1063
|
|
|
1064
|
+
// src/config/utils/version.ts
|
|
1065
|
+
import chalk3 from "chalk";
|
|
1066
|
+
import Conf3 from "conf";
|
|
1067
|
+
import consola4 from "consola";
|
|
1068
|
+
import semver2 from "semver";
|
|
1069
|
+
var versionCache = new Conf3({
|
|
1070
|
+
projectName: "djangocfg-nextjs",
|
|
1071
|
+
projectVersion: "1.0.0"
|
|
1072
|
+
});
|
|
1073
|
+
function getCurrentVersion() {
|
|
1074
|
+
try {
|
|
1075
|
+
const packageJson = require_package();
|
|
1076
|
+
return packageJson.version || null;
|
|
1077
|
+
} catch {
|
|
1078
|
+
return null;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
async function fetchLatestVersion2() {
|
|
1082
|
+
const lastCheck = versionCache.get("lastCheck") || 0;
|
|
1083
|
+
const cachedVersion = versionCache.get("latestVersion");
|
|
1084
|
+
if (cachedVersion && Date.now() - lastCheck < VERSION_CACHE_TTL_MS) {
|
|
1085
|
+
return cachedVersion;
|
|
1086
|
+
}
|
|
1087
|
+
try {
|
|
1088
|
+
const https = await import("https");
|
|
1089
|
+
return new Promise((resolve) => {
|
|
1090
|
+
const req = https.get(
|
|
1091
|
+
`https://registry.npmjs.org/${PACKAGE_NAME}/latest`,
|
|
1092
|
+
{ timeout: 5e3 },
|
|
1093
|
+
(res) => {
|
|
1094
|
+
let data = "";
|
|
1095
|
+
res.on("data", (chunk) => {
|
|
1096
|
+
data += chunk;
|
|
1097
|
+
});
|
|
1098
|
+
res.on("end", () => {
|
|
1099
|
+
try {
|
|
1100
|
+
const json = JSON.parse(data);
|
|
1101
|
+
const version = json.version || null;
|
|
1102
|
+
if (version) {
|
|
1103
|
+
versionCache.set("latestVersion", version);
|
|
1104
|
+
versionCache.set("lastCheck", Date.now());
|
|
1105
|
+
}
|
|
1106
|
+
resolve(version);
|
|
1107
|
+
} catch {
|
|
1108
|
+
resolve(cachedVersion || null);
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
);
|
|
1113
|
+
req.on("error", () => resolve(cachedVersion || null));
|
|
1114
|
+
req.on("timeout", () => {
|
|
1115
|
+
req.destroy();
|
|
1116
|
+
resolve(cachedVersion || null);
|
|
1117
|
+
});
|
|
1118
|
+
});
|
|
1119
|
+
} catch {
|
|
1120
|
+
return cachedVersion || null;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
async function checkForUpdate() {
|
|
1124
|
+
const currentVersion = getCurrentVersion();
|
|
1125
|
+
if (!currentVersion) {
|
|
1126
|
+
return { hasUpdate: false, currentVersion: null, latestVersion: null };
|
|
1127
|
+
}
|
|
1128
|
+
const latestVersion = await fetchLatestVersion2();
|
|
1129
|
+
const hasUpdate = !!(latestVersion && semver2.gt(latestVersion, currentVersion));
|
|
1130
|
+
return { hasUpdate, currentVersion, latestVersion };
|
|
1131
|
+
}
|
|
1132
|
+
function getUpdateCommand() {
|
|
1133
|
+
return `pnpm add ${DJANGOCFG_PACKAGES.map((p) => `${p}@latest`).join(" ")}`;
|
|
1134
|
+
}
|
|
1135
|
+
async function printVersionInfo() {
|
|
1136
|
+
const { hasUpdate, currentVersion, latestVersion } = await checkForUpdate();
|
|
1137
|
+
if (!currentVersion) return;
|
|
1138
|
+
consola4.box(`\u{1F4E6} @djangocfg/nextjs v${currentVersion}`);
|
|
1139
|
+
if (hasUpdate && latestVersion) {
|
|
1140
|
+
consola4.warn(`Update Available! ${chalk3.red(currentVersion)} \u2192 ${chalk3.green(latestVersion)}`);
|
|
1141
|
+
consola4.info(`Run: ${chalk3.cyan(getUpdateCommand())}`);
|
|
1142
|
+
console.log("");
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1086
1146
|
// src/config/plugins/devStartup.ts
|
|
1087
1147
|
var startupDone = false;
|
|
1088
1148
|
var DevStartupPlugin = class {
|
|
@@ -1153,87 +1213,25 @@ function resetDevStartupState() {
|
|
|
1153
1213
|
startupDone = false;
|
|
1154
1214
|
}
|
|
1155
1215
|
|
|
1156
|
-
// src/config/
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
config.plugins = [];
|
|
1173
|
-
}
|
|
1174
|
-
if (opts.gzip) {
|
|
1175
|
-
config.plugins.push(
|
|
1176
|
-
new CompressionPlugin({
|
|
1177
|
-
filename: "[path][base].gz",
|
|
1178
|
-
algorithm: "gzip",
|
|
1179
|
-
test: /\.(js|css|html|svg|json)$/,
|
|
1180
|
-
threshold: opts.threshold,
|
|
1181
|
-
minRatio: opts.minRatio
|
|
1182
|
-
})
|
|
1183
|
-
);
|
|
1184
|
-
}
|
|
1185
|
-
if (opts.brotli) {
|
|
1186
|
-
config.plugins.push(
|
|
1187
|
-
new CompressionPlugin({
|
|
1188
|
-
filename: "[path][base].br",
|
|
1189
|
-
algorithm: "brotliCompress",
|
|
1190
|
-
test: /\.(js|css|html|svg|json)$/,
|
|
1191
|
-
threshold: opts.threshold,
|
|
1192
|
-
minRatio: opts.minRatio,
|
|
1193
|
-
compressionOptions: {
|
|
1194
|
-
level: opts.brotliLevel
|
|
1195
|
-
}
|
|
1196
|
-
})
|
|
1197
|
-
);
|
|
1216
|
+
// src/config/utils/deepMerge.ts
|
|
1217
|
+
function deepMerge(target, source) {
|
|
1218
|
+
const output = { ...target };
|
|
1219
|
+
for (const key in source) {
|
|
1220
|
+
if (source[key] === void 0) continue;
|
|
1221
|
+
if (Array.isArray(source[key])) {
|
|
1222
|
+
output[key] = source[key];
|
|
1223
|
+
} else if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
1224
|
+
const targetValue = output[key];
|
|
1225
|
+
if (targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
1226
|
+
output[key] = deepMerge(targetValue, source[key]);
|
|
1227
|
+
} else {
|
|
1228
|
+
output[key] = source[key];
|
|
1229
|
+
}
|
|
1230
|
+
} else {
|
|
1231
|
+
output[key] = source[key];
|
|
1198
1232
|
}
|
|
1199
|
-
return true;
|
|
1200
|
-
} catch (error) {
|
|
1201
|
-
return false;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
function isCompressionAvailable() {
|
|
1205
|
-
return isPackageInstalled("compression-webpack-plugin");
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
// src/pwa/plugin.ts
|
|
1209
|
-
import { consola as consola4 } from "consola";
|
|
1210
|
-
function withPWA(nextConfig, options = {}) {
|
|
1211
|
-
const isDev2 = process.env.NODE_ENV === "development";
|
|
1212
|
-
const isStaticBuild2 = process.env.NEXT_PUBLIC_STATIC_BUILD === "true";
|
|
1213
|
-
const shouldDisable = options.disable !== void 0 ? options.disable : isDev2 || isStaticBuild2;
|
|
1214
|
-
const defaultOptions = {
|
|
1215
|
-
swSrc: "app/sw.ts",
|
|
1216
|
-
swDest: "public/sw.js",
|
|
1217
|
-
disable: shouldDisable,
|
|
1218
|
-
cacheOnNavigation: true,
|
|
1219
|
-
reloadOnOnline: true,
|
|
1220
|
-
...options
|
|
1221
|
-
};
|
|
1222
|
-
try {
|
|
1223
|
-
const withSerwistInit = __require("@serwist/next").default;
|
|
1224
|
-
const withSerwist = withSerwistInit({
|
|
1225
|
-
swSrc: defaultOptions.swSrc,
|
|
1226
|
-
swDest: defaultOptions.swDest,
|
|
1227
|
-
disable: defaultOptions.disable,
|
|
1228
|
-
cacheOnNavigation: defaultOptions.cacheOnNavigation,
|
|
1229
|
-
reloadOnOnline: defaultOptions.reloadOnOnline,
|
|
1230
|
-
...defaultOptions.serwistOptions
|
|
1231
|
-
});
|
|
1232
|
-
return withSerwist(nextConfig);
|
|
1233
|
-
} catch (error) {
|
|
1234
|
-
consola4.error("Failed to configure Serwist:", error);
|
|
1235
|
-
return nextConfig;
|
|
1236
1233
|
}
|
|
1234
|
+
return output;
|
|
1237
1235
|
}
|
|
1238
1236
|
|
|
1239
1237
|
// src/config/createNextConfig.ts
|
|
@@ -1401,7 +1399,7 @@ export {
|
|
|
1401
1399
|
createBaseNextConfig,
|
|
1402
1400
|
deepMerge,
|
|
1403
1401
|
detectPackageManager,
|
|
1404
|
-
fetchLatestVersion,
|
|
1402
|
+
fetchLatestVersion2 as fetchLatestVersion,
|
|
1405
1403
|
getApiUrl,
|
|
1406
1404
|
getBasePath,
|
|
1407
1405
|
getCurrentVersion,
|