@djangocfg/nextjs 2.1.41 → 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.
@@ -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.41",
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/utils/deepMerge.ts
219
- function deepMerge(target, source) {
220
- const output = { ...target };
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
- var installerCache = new Conf2({
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${chalk2.cyan(frame)} ${currentText}`);
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${chalk2.green("\u2713")} ${text2 || currentText}
559
+ process.stdout.write(`\r${chalk.green("\u2713")} ${text2 || currentText}
582
560
  `);
583
561
  } else {
584
- console.log(` ${chalk2.green("\u2713")} ${text2 || currentText}`);
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${chalk2.red("\u2717")} ${text2 || currentText}
569
+ process.stdout.write(`\r${chalk.red("\u2717")} ${text2 || currentText}
592
570
  `);
593
571
  } else {
594
- console.log(` ${chalk2.red("\u2717")} ${text2 || currentText}`);
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(`${chalk2.dim(progress)} Installing ${chalk2.cyan(pkg.name)}...`);
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(`${chalk2.dim(progress)} ${chalk2.cyan(pkg.name)} ${chalk2.green("installed")}`);
603
+ spinner.succeed(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.green("installed")}`);
626
604
  resolve(true);
627
605
  } else {
628
- spinner.fail(`${chalk2.dim(progress)} ${chalk2.cyan(pkg.name)} ${chalk2.red("failed")}`);
606
+ spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red("failed")}`);
629
607
  if (stderr) {
630
- console.log(chalk2.dim(` ${stderr.split("\n")[0]}`));
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(`${chalk2.dim(progress)} ${chalk2.cyan(pkg.name)} ${chalk2.red("failed")}`);
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(chalk2.bold(` Installing ${total} package${total > 1 ? "s" : ""}...`));
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: ${chalk2.cyan(packages.map((p) => p.name).join(", "))}`);
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(` ${chalk2.yellow("\u2022")} ${chalk2.bold(pkg.name)}`);
721
- console.log(` ${chalk2.dim(pkg.description)}`);
722
- console.log(` ${chalk2.dim(pkg.reason)}`);
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(` ${chalk2.cyan("Command:")} ${command}`);
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
- `${chalk2.green("?")} Install these packages now? ${chalk2.dim("[Y/n]")} `
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
- `${chalk2.green("?")} Enable auto-install for future? ${chalk2.dim("[y/N]")} `
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
- `${chalk2.green("?")} Skip these packages in future prompts? ${chalk2.dim("[y/N]")} `
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: ${chalk2.cyan(command)}`);
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 { createInterface as createInterface2 } from "readline";
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 chalk3 from "chalk";
774
- import consola3 from "consola";
775
- import Conf3 from "conf";
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 fetchLatestVersion2(packageName) {
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 fetchLatestVersion2(PACKAGE_NAME);
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 && semver2.gt(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${chalk3.cyan(frame)} ${currentText}`);
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${chalk3.green("\u2713")} ${text2 || currentText}
895
+ process.stdout.write(`\r${chalk2.green("\u2713")} ${text2 || currentText}
918
896
  `);
919
897
  } else {
920
- console.log(` ${chalk3.green("\u2713")} ${text2 || currentText}`);
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${chalk3.red("\u2717")} ${text2 || currentText}
905
+ process.stdout.write(`\r${chalk2.red("\u2717")} ${text2 || currentText}
928
906
  `);
929
907
  } else {
930
- console.log(` ${chalk3.red("\u2717")} ${text2 || currentText}`);
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 = `${chalk3.red(pkg.current)} \u2192 ${chalk3.green(pkg.latest)}`;
939
+ const versionInfo = `${chalk2.red(pkg.current)} \u2192 ${chalk2.green(pkg.latest)}`;
962
940
  const spinner = createSpinner2(
963
- `${chalk3.dim(progress)} Updating ${chalk3.cyan(pkg.name)} ${versionInfo}`
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
- `${chalk3.dim(progress)} ${chalk3.cyan(pkg.name)} ${chalk3.green(pkg.latest)}`
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
- `${chalk3.dim(progress)} ${chalk3.cyan(pkg.name)} ${chalk3.red("failed")}`
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(`${chalk3.dim(progress)} ${chalk3.cyan(pkg.name)} ${chalk3.red("failed")}`);
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(chalk3.bold(` Updating ${total} package${total > 1 ? "s" : ""}...`));
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(chalk3.dim(` Found ${outdated.length} outdated package(s)`));
1011
+ console.log(chalk2.dim(` Found ${outdated.length} outdated package(s)`));
1034
1012
  if (outdated.length === 0) {
1035
- console.log(chalk3.green(" \u2713 All packages are up to date"));
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
- ` ${chalk3.yellow("\u2022")} ${chalk3.bold(pkg.name)} ${chalk3.red(pkg.current)} \u2192 ${chalk3.green(pkg.latest)}`
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
- `${chalk3.green("?")} Update these packages now? ${chalk3.dim("[Y/n]")} `
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
- `${chalk3.green("?")} Enable auto-update for future? ${chalk3.dim("[y/N]")} `
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
- `${chalk3.green("?")} Skip these versions in future? ${chalk3.dim("[y/N]")} `
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/plugins/compression.ts
1157
- var DEFAULT_OPTIONS = {
1158
- gzip: true,
1159
- brotli: true,
1160
- threshold: 8192,
1161
- minRatio: 0.8,
1162
- brotliLevel: 8
1163
- };
1164
- function addCompressionPlugins(config, options = {}) {
1165
- if (!isPackageInstalled("compression-webpack-plugin")) {
1166
- return false;
1167
- }
1168
- const opts = { ...DEFAULT_OPTIONS, ...options };
1169
- try {
1170
- const CompressionPlugin = __require("compression-webpack-plugin");
1171
- if (!config.plugins) {
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,