@djangocfg/nextjs 2.1.483 → 2.1.486
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 +1 -2
- package/dist/config/index.d.mts +18 -0
- package/dist/config/index.mjs +35 -24
- package/dist/config/index.mjs.map +1 -1
- package/dist/health/index.d.mts +1 -1
- package/dist/health/index.mjs.map +1 -1
- package/dist/i18n/routing.d.mts +2 -2
- package/dist/index.mjs +35 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/config/createNextConfig.ts +9 -1
- package/src/config/utils/env.ts +59 -0
- package/src/health/route.ts +1 -2
package/README.md
CHANGED
|
@@ -370,7 +370,7 @@ registration, cache layers, and deployment notes.
|
|
|
370
370
|
Create a health monitoring endpoint:
|
|
371
371
|
|
|
372
372
|
```tsx
|
|
373
|
-
// app/
|
|
373
|
+
// app/healthz/route.ts
|
|
374
374
|
import { createHealthHandler } from '@djangocfg/nextjs/health';
|
|
375
375
|
|
|
376
376
|
export const GET = createHealthHandler({
|
|
@@ -717,4 +717,3 @@ Issues and pull requests are welcome at [GitHub](https://github.com/markolofsen/
|
|
|
717
717
|
## License
|
|
718
718
|
|
|
719
719
|
MIT - see [LICENSE](./LICENSE) for details
|
|
720
|
-
|
package/dist/config/index.d.mts
CHANGED
|
@@ -361,6 +361,24 @@ declare const isDev: boolean;
|
|
|
361
361
|
declare const isProduction: boolean;
|
|
362
362
|
declare const isCI: boolean;
|
|
363
363
|
declare function getBasePath(isDefaultCfgAdmin?: boolean): string;
|
|
364
|
+
/**
|
|
365
|
+
* Resolve the API origin that gets inlined into the client bundle.
|
|
366
|
+
*
|
|
367
|
+
* `NEXT_PUBLIC_*` is substituted at BUILD time, so a value supplied only at
|
|
368
|
+
* container runtime (a compose `environment:` entry, a `docker run -e`) arrives
|
|
369
|
+
* far too late — the bundle already shipped with whatever was present during
|
|
370
|
+
* `next build`.
|
|
371
|
+
*
|
|
372
|
+
* An empty result means "no API origin is configured". Callers MUST treat that
|
|
373
|
+
* as *do not send the request* rather than falling back to a relative path: the
|
|
374
|
+
* browser resolves a relative URL against the CURRENT page, so on an
|
|
375
|
+
* i18n-prefixed route `/cfg/accounts/profile` silently becomes
|
|
376
|
+
* `https://site.com/<locale>/cfg/accounts/profile` — a 404 that reproduces only
|
|
377
|
+
* in production. Use {@link hasApiUrl} to gate those call sites.
|
|
378
|
+
*
|
|
379
|
+
* The one case where empty legitimately means "relative": a static build served
|
|
380
|
+
* from the same origin as Django.
|
|
381
|
+
*/
|
|
364
382
|
declare function getApiUrl(): string;
|
|
365
383
|
declare function getSiteUrl(): string;
|
|
366
384
|
|
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.486",
|
|
18
18
|
description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
19
19
|
keywords: [
|
|
20
20
|
"nextjs",
|
|
@@ -399,6 +399,7 @@ import { createRequire } from "module";
|
|
|
399
399
|
import { join } from "path";
|
|
400
400
|
|
|
401
401
|
// src/config/utils/env.ts
|
|
402
|
+
import consola2 from "consola";
|
|
402
403
|
var isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === "true";
|
|
403
404
|
var isDev = process.env.NODE_ENV === "development";
|
|
404
405
|
var isProduction = !isDev;
|
|
@@ -410,6 +411,15 @@ function getBasePath(isDefaultCfgAdmin) {
|
|
|
410
411
|
function getApiUrl() {
|
|
411
412
|
return isStaticBuild ? "" : process.env.NEXT_PUBLIC_API_URL || "";
|
|
412
413
|
}
|
|
414
|
+
function hasApiUrl() {
|
|
415
|
+
return isStaticBuild || Boolean(process.env.NEXT_PUBLIC_API_URL);
|
|
416
|
+
}
|
|
417
|
+
function warnIfApiUrlMissing() {
|
|
418
|
+
if (hasApiUrl() || isDev) return;
|
|
419
|
+
consola2.warn(
|
|
420
|
+
"NEXT_PUBLIC_API_URL is not set \u2014 API-backed features are disabled in this build.\nRequests that need it are skipped rather than sent to a relative path.\nIf this app DOES have a backend, the value must be present at BUILD time:\n \u2022 commit it to the app's `.env.production`, and check no `.dockerignore`\n rule (e.g. `**/.env*`) strips that file from the build context;\n \u2022 or pass it as a Dockerfile ARG/ENV before the build step.\nA compose `environment:` entry is too late \u2014 it only exists at runtime."
|
|
421
|
+
);
|
|
422
|
+
}
|
|
413
423
|
function getSiteUrl() {
|
|
414
424
|
return isStaticBuild ? "" : process.env.NEXT_PUBLIC_SITE_URL || "";
|
|
415
425
|
}
|
|
@@ -585,7 +595,7 @@ Example queries:
|
|
|
585
595
|
import chalk from "chalk";
|
|
586
596
|
import { execSync, spawn } from "child_process";
|
|
587
597
|
import Conf from "conf";
|
|
588
|
-
import
|
|
598
|
+
import consola3 from "consola";
|
|
589
599
|
import { createInterface } from "readline";
|
|
590
600
|
function createMemoryCache() {
|
|
591
601
|
const store = /* @__PURE__ */ new Map();
|
|
@@ -804,13 +814,13 @@ async function installPackagesWithProgress(packages) {
|
|
|
804
814
|
}
|
|
805
815
|
console.log("");
|
|
806
816
|
if (failedPackages.length === 0) {
|
|
807
|
-
|
|
817
|
+
consola3.success(`All ${total} packages installed successfully!`);
|
|
808
818
|
return true;
|
|
809
819
|
} else if (successCount > 0) {
|
|
810
|
-
|
|
820
|
+
consola3.warn(`${successCount}/${total} packages installed. Failed: ${failedPackages.join(", ")}`);
|
|
811
821
|
return false;
|
|
812
822
|
} else {
|
|
813
|
-
|
|
823
|
+
consola3.error(`Failed to install packages: ${failedPackages.join(", ")}`);
|
|
814
824
|
return false;
|
|
815
825
|
}
|
|
816
826
|
}
|
|
@@ -821,7 +831,7 @@ async function installPackages(packages) {
|
|
|
821
831
|
if (packages.length === 0) return true;
|
|
822
832
|
const pm = detectPackageManager();
|
|
823
833
|
const command = buildInstallCommand(packages, pm);
|
|
824
|
-
|
|
834
|
+
consola3.info(`Installing: ${chalk.cyan(packages.map((p) => p.name).join(", "))}`);
|
|
825
835
|
const spinner = createSpinner("Installing packages...");
|
|
826
836
|
spinner.start();
|
|
827
837
|
return new Promise((resolve) => {
|
|
@@ -861,7 +871,7 @@ async function checkAndInstallPackages(options = {}) {
|
|
|
861
871
|
return installPackages(toInstall);
|
|
862
872
|
}
|
|
863
873
|
console.log("");
|
|
864
|
-
|
|
874
|
+
consola3.box("\u{1F4E6} Missing Optional Packages");
|
|
865
875
|
console.log("");
|
|
866
876
|
for (const pkg of toInstall) {
|
|
867
877
|
console.log(` ${chalk.yellow("\u2022")} ${chalk.bold(pkg.name)}`);
|
|
@@ -885,7 +895,7 @@ async function checkAndInstallPackages(options = {}) {
|
|
|
885
895
|
);
|
|
886
896
|
if (enableAuto) {
|
|
887
897
|
installerCache.set("autoInstall", true);
|
|
888
|
-
|
|
898
|
+
consola3.info("Auto-install enabled. Run with --no-auto-install to disable.");
|
|
889
899
|
}
|
|
890
900
|
}
|
|
891
901
|
return success;
|
|
@@ -896,7 +906,7 @@ async function checkAndInstallPackages(options = {}) {
|
|
|
896
906
|
if (skipPermanently) {
|
|
897
907
|
const currentSkip = installerCache.get("skipPackages") || [];
|
|
898
908
|
installerCache.set("skipPackages", [...currentSkip, ...toInstall.map((p) => p.name)]);
|
|
899
|
-
|
|
909
|
+
consola3.info("Packages added to skip list.");
|
|
900
910
|
}
|
|
901
911
|
return false;
|
|
902
912
|
}
|
|
@@ -904,19 +914,19 @@ function printMissingPackagesInfo(packages) {
|
|
|
904
914
|
if (packages.length === 0) return;
|
|
905
915
|
const pm = detectPackageManager();
|
|
906
916
|
const command = buildInstallCommand(packages, pm);
|
|
907
|
-
|
|
908
|
-
|
|
917
|
+
consola3.warn(`Missing optional packages: ${packages.map((p) => p.name).join(", ")}`);
|
|
918
|
+
consola3.info(`Install with: ${chalk.cyan(command)}`);
|
|
909
919
|
}
|
|
910
920
|
function resetInstallerPreferences() {
|
|
911
921
|
installerCache.clear();
|
|
912
|
-
|
|
922
|
+
consola3.success("Installer preferences reset");
|
|
913
923
|
}
|
|
914
924
|
|
|
915
925
|
// src/config/packages/updater.ts
|
|
916
926
|
import chalk2 from "chalk";
|
|
917
927
|
import { spawn as spawn2 } from "child_process";
|
|
918
928
|
import Conf2 from "conf";
|
|
919
|
-
import
|
|
929
|
+
import consola4 from "consola";
|
|
920
930
|
import { createRequire as createRequire2 } from "module";
|
|
921
931
|
import { join as join2 } from "path";
|
|
922
932
|
import { createInterface as createInterface2 } from "readline";
|
|
@@ -1176,13 +1186,13 @@ async function updatePackagesWithProgress(packages) {
|
|
|
1176
1186
|
}
|
|
1177
1187
|
console.log("");
|
|
1178
1188
|
if (failedPackages.length === 0) {
|
|
1179
|
-
|
|
1189
|
+
consola4.success(`All ${total} packages updated successfully!`);
|
|
1180
1190
|
return true;
|
|
1181
1191
|
} else if (successCount > 0) {
|
|
1182
|
-
|
|
1192
|
+
consola4.warn(`${successCount}/${total} packages updated. Failed: ${failedPackages.join(", ")}`);
|
|
1183
1193
|
return false;
|
|
1184
1194
|
} else {
|
|
1185
|
-
|
|
1195
|
+
consola4.error(`Failed to update packages: ${failedPackages.join(", ")}`);
|
|
1186
1196
|
return false;
|
|
1187
1197
|
}
|
|
1188
1198
|
}
|
|
@@ -1207,7 +1217,7 @@ async function checkAndUpdatePackages(options = {}) {
|
|
|
1207
1217
|
return updatePackagesWithProgress(outdated);
|
|
1208
1218
|
}
|
|
1209
1219
|
console.log("");
|
|
1210
|
-
|
|
1220
|
+
consola4.box("\u{1F4E6} Updates Available");
|
|
1211
1221
|
console.log("");
|
|
1212
1222
|
for (const pkg of outdated) {
|
|
1213
1223
|
console.log(
|
|
@@ -1226,7 +1236,7 @@ async function checkAndUpdatePackages(options = {}) {
|
|
|
1226
1236
|
);
|
|
1227
1237
|
if (enableAuto) {
|
|
1228
1238
|
updaterCache.set("autoUpdate", true);
|
|
1229
|
-
|
|
1239
|
+
consola4.info("Auto-update enabled.");
|
|
1230
1240
|
}
|
|
1231
1241
|
}
|
|
1232
1242
|
return success;
|
|
@@ -1242,19 +1252,19 @@ async function checkAndUpdatePackages(options = {}) {
|
|
|
1242
1252
|
}
|
|
1243
1253
|
}
|
|
1244
1254
|
updaterCache.set("skippedVersions", skipped);
|
|
1245
|
-
|
|
1255
|
+
consola4.info("Versions skipped. Will prompt again for newer versions.");
|
|
1246
1256
|
}
|
|
1247
1257
|
return false;
|
|
1248
1258
|
}
|
|
1249
1259
|
function resetUpdaterPreferences() {
|
|
1250
1260
|
updaterCache.clear();
|
|
1251
|
-
|
|
1261
|
+
consola4.success("Updater preferences reset");
|
|
1252
1262
|
}
|
|
1253
1263
|
|
|
1254
1264
|
// src/config/utils/version.ts
|
|
1255
1265
|
import chalk3 from "chalk";
|
|
1256
1266
|
import Conf3 from "conf";
|
|
1257
|
-
import
|
|
1267
|
+
import consola5 from "consola";
|
|
1258
1268
|
import semver2 from "semver";
|
|
1259
1269
|
function createMemoryCache3() {
|
|
1260
1270
|
const store = /* @__PURE__ */ new Map();
|
|
@@ -1346,10 +1356,10 @@ function getUpdateCommand() {
|
|
|
1346
1356
|
async function printVersionInfo() {
|
|
1347
1357
|
const { hasUpdate, currentVersion, latestVersion } = await checkForUpdate();
|
|
1348
1358
|
if (!currentVersion) return;
|
|
1349
|
-
|
|
1359
|
+
consola5.box(`\u{1F4E6} @djangocfg/nextjs v${currentVersion}`);
|
|
1350
1360
|
if (hasUpdate && latestVersion) {
|
|
1351
|
-
|
|
1352
|
-
|
|
1361
|
+
consola5.warn(`Update Available! ${chalk3.red(currentVersion)} \u2192 ${chalk3.green(latestVersion)}`);
|
|
1362
|
+
consola5.info(`Run: ${chalk3.cyan(getUpdateCommand())}`);
|
|
1353
1363
|
console.log("");
|
|
1354
1364
|
}
|
|
1355
1365
|
}
|
|
@@ -1449,6 +1459,7 @@ function deepMerge(target, source) {
|
|
|
1449
1459
|
// src/config/createNextConfig.ts
|
|
1450
1460
|
function createBaseNextConfig(options = {}) {
|
|
1451
1461
|
const basePath = getBasePath(options.isDefaultCfgAdmin);
|
|
1462
|
+
warnIfApiUrlMissing();
|
|
1452
1463
|
const apiUrl = getApiUrl();
|
|
1453
1464
|
const siteUrl = getSiteUrl();
|
|
1454
1465
|
const baseConfig = {
|