@djangocfg/nextjs 2.1.426 → 2.1.428
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 +33 -0
- package/dist/config/index.d.mts +12 -3
- package/dist/config/index.mjs +39 -21
- package/dist/config/index.mjs.map +1 -1
- package/dist/i18n/request.d.mts +3 -3
- package/dist/i18n/request.mjs.map +1 -1
- package/dist/index.mjs +39 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/config/constants.ts +0 -6
- package/src/config/createNextConfig.ts +71 -19
- package/src/i18n/request.ts +3 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/i18n/request.ts","../../src/i18n/routing.ts"],"sourcesContent":["/**\n * i18n Request Configuration for Server Components\n *\n * Provides translations to server components via next-intl's request scope\n *\n * @example\n * ```ts\n * // i18n/request.ts in your app\n * import { createRequestConfig } from '@djangocfg/nextjs/i18n';\n * import { en, ru, ko } from '@djangocfg/i18n';\n
|
|
1
|
+
{"version":3,"sources":["../../src/i18n/request.ts","../../src/i18n/routing.ts"],"sourcesContent":["/**\n * i18n Request Configuration for Server Components\n *\n * Provides translations to server components via next-intl's request scope\n *\n * @example\n * ```ts\n * // i18n/request.ts in your app\n * import { createRequestConfig } from '@djangocfg/nextjs/i18n';\n * import { en, ru, ko } from '@djangocfg/i18n';\n *\n * export default createRequestConfig({\n * locales: { en, ru, ko },\n * });\n * ```\n */\n\nimport { getRequestConfig } from 'next-intl/server';\n\nimport { en, ko, mergeTranslations, ru } from '@djangocfg/i18n';\n\nimport { routing } from './routing';\n\nimport type { I18nTranslations, LocaleCode } from '@djangocfg/i18n';\nimport type { Messages } from './types';\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface RequestConfigOptions {\n /** Base locale translations from @djangocfg/i18n */\n locales?: Record<LocaleCode, I18nTranslations>;\n /** Extension i18n instances to merge */\n extensions?: Array<{\n namespace: string;\n locales: Record<string, Record<string, unknown>>;\n }>;\n /** Custom message loader (overrides locales) */\n loadMessages?: (locale: LocaleCode) => Promise<Messages> | Messages;\n /** Time zone for date/time formatting */\n timeZone?: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Default Locales\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst DEFAULT_LOCALES: Record<LocaleCode, I18nTranslations> = {\n en,\n ru,\n ko,\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Message Loading\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Load and merge messages for a locale\n */\nfunction loadMessages(\n locale: LocaleCode,\n options: RequestConfigOptions\n): Messages {\n // Get base translations\n const locales = options.locales ?? DEFAULT_LOCALES;\n const baseMessages = locales[locale] ?? locales.en ?? en;\n\n // If no extensions, return base\n if (!options.extensions?.length) {\n return baseMessages as Messages;\n }\n\n // Merge extension translations\n let mergedMessages = { ...baseMessages } as Messages;\n\n for (const extension of options.extensions) {\n const extMessages = extension.locales[locale] ?? extension.locales.en;\n if (extMessages) {\n mergedMessages = mergeTranslations(mergedMessages, {\n [extension.namespace]: extMessages,\n }) as Messages;\n }\n }\n\n return mergedMessages;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Request Config Factory\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create request configuration for next-intl\n *\n * This is used in your app's `i18n/request.ts` file\n *\n * @example\n * ```ts\n * // i18n/request.ts\n * import { createRequestConfig } from '@djangocfg/nextjs/i18n';\n *\n * // `extensions` merges extra namespaced translation bundles, each shaped\n * // as `{ namespace: string, locales: Record<LocaleCode, Messages> }`.\n * export default createRequestConfig({\n * extensions: [myFeatureI18n],\n * });\n * ```\n */\nexport function createRequestConfig(options: RequestConfigOptions = {}) {\n return getRequestConfig(async ({ requestLocale }) => {\n // Get locale from request or default\n let locale = await requestLocale;\n\n // Validate and fallback to default\n if (!locale || !routing.locales.includes(locale as LocaleCode)) {\n locale = routing.defaultLocale;\n }\n\n // Load messages\n const messages = options.loadMessages\n ? await options.loadMessages(locale as LocaleCode)\n : loadMessages(locale as LocaleCode, options);\n\n return {\n locale,\n messages,\n timeZone: options.timeZone ?? 'UTC',\n };\n });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Default Export\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Default request config with base @djangocfg/i18n translations\n * Can be used directly if no extensions are needed\n */\nexport default createRequestConfig();\n","/**\n * i18n Routing Configuration\n *\n * Creates routing configuration for next-intl\n * Used by proxy and navigation components\n */\n\nimport { defineRouting } from 'next-intl/routing';\n\nimport type { I18nConfig, LocaleCode } from './types';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Default Configuration\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const DEFAULT_LOCALES: LocaleCode[] = ['en', 'ru', 'ko', 'ja', 'de', 'fr', 'zh', 'it', 'es', 'nl', 'ar', 'tr', 'pt-BR', 'pl', 'sv', 'no', 'da'];\nexport const DEFAULT_LOCALE: LocaleCode = 'en';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Routing Factory\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create routing configuration for next-intl\n *\n * @example\n * ```ts\n * // i18n/routing.ts\n * import { createRouting } from '@djangocfg/nextjs/i18n';\n *\n * export const routing = createRouting({\n * locales: ['en', 'ru', 'ko'],\n * defaultLocale: 'en',\n * });\n * ```\n */\nexport function createRouting(config?: Partial<I18nConfig>) {\n const locales = config?.locales ?? DEFAULT_LOCALES;\n const defaultLocale = config?.defaultLocale ?? DEFAULT_LOCALE;\n const localePrefix = config?.localePrefix ?? 'as-needed';\n\n return defineRouting({\n locales,\n defaultLocale,\n localePrefix,\n });\n}\n\n/**\n * Default routing configuration\n * Can be overridden by app-specific configuration\n */\nexport const routing = createRouting();\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Locale Utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Check if a locale is supported\n */\nexport function isValidLocale(\n locale: string,\n supportedLocales: readonly string[] = DEFAULT_LOCALES\n): locale is LocaleCode {\n return supportedLocales.includes(locale as LocaleCode);\n}\n\n/**\n * Get locale from params (handles async params in Next.js 15+)\n */\nexport async function getLocaleFromParams(\n params: Promise<{ locale: string }> | { locale: string }\n): Promise<LocaleCode> {\n const resolved = await params;\n return resolved.locale as LocaleCode;\n}\n\n/**\n * Generate static params for all locales\n * Use in generateStaticParams for locale pages\n */\nexport function generateLocaleParams(locales: readonly string[] = DEFAULT_LOCALES) {\n return locales.map((locale) => ({ locale }));\n}\n"],"mappings":";AAiBA,SAAS,wBAAwB;AAEjC,SAAS,IAAI,IAAI,mBAAmB,UAAU;;;ACZ9C,SAAS,qBAAqB;AAQvB,IAAM,kBAAgC,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,SAAS,MAAM,MAAM,MAAM,IAAI;AAC9I,IAAM,iBAA6B;AAoBnC,SAAS,cAAc,QAA8B;AAC1D,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,eAAe,QAAQ,gBAAgB;AAE7C,SAAO,cAAc;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAMO,IAAM,UAAU,cAAc;;;ADLrC,IAAMA,mBAAwD;AAAA,EAC5D;AAAA,EACA;AAAA,EACA;AACF;AASA,SAAS,aACP,QACA,SACU;AAEV,QAAM,UAAU,QAAQ,WAAWA;AACnC,QAAM,eAAe,QAAQ,MAAM,KAAK,QAAQ,MAAM;AAGtD,MAAI,CAAC,QAAQ,YAAY,QAAQ;AAC/B,WAAO;AAAA,EACT;AAGA,MAAI,iBAAiB,EAAE,GAAG,aAAa;AAEvC,aAAW,aAAa,QAAQ,YAAY;AAC1C,UAAM,cAAc,UAAU,QAAQ,MAAM,KAAK,UAAU,QAAQ;AACnE,QAAI,aAAa;AACf,uBAAiB,kBAAkB,gBAAgB;AAAA,QACjD,CAAC,UAAU,SAAS,GAAG;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAuBO,SAAS,oBAAoB,UAAgC,CAAC,GAAG;AACtE,SAAO,iBAAiB,OAAO,EAAE,cAAc,MAAM;AAEnD,QAAI,SAAS,MAAM;AAGnB,QAAI,CAAC,UAAU,CAAC,QAAQ,QAAQ,SAAS,MAAoB,GAAG;AAC9D,eAAS,QAAQ;AAAA,IACnB;AAGA,UAAM,WAAW,QAAQ,eACrB,MAAM,QAAQ,aAAa,MAAoB,IAC/C,aAAa,QAAsB,OAAO;AAE9C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,QAAQ,YAAY;AAAA,IAChC;AAAA,EACF,CAAC;AACH;AAUA,IAAO,kBAAQ,oBAAoB;","names":["DEFAULT_LOCALES"]}
|
package/dist/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.428",
|
|
18
18
|
description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
19
19
|
keywords: [
|
|
20
20
|
"nextjs",
|
|
@@ -534,7 +534,6 @@ var DJANGO_CFG_BANNER = `
|
|
|
534
534
|
`;
|
|
535
535
|
var DJANGOCFG_PACKAGES = [
|
|
536
536
|
"@djangocfg/ui-core",
|
|
537
|
-
"@djangocfg/ui-nextjs",
|
|
538
537
|
"@djangocfg/layouts",
|
|
539
538
|
"@djangocfg/nextjs",
|
|
540
539
|
"@djangocfg/api",
|
|
@@ -545,20 +544,15 @@ var DJANGOCFG_PACKAGES = [
|
|
|
545
544
|
var DEFAULT_TRANSPILE_PACKAGES = [
|
|
546
545
|
"@djangocfg/i18n",
|
|
547
546
|
"@djangocfg/ui-core",
|
|
548
|
-
"@djangocfg/ui-nextjs",
|
|
549
547
|
"@djangocfg/layouts",
|
|
550
548
|
"@djangocfg/ui-tools",
|
|
551
549
|
"@djangocfg/api",
|
|
552
550
|
"@djangocfg/centrifugo",
|
|
553
551
|
"@djangocfg/debuger",
|
|
554
|
-
"@djangocfg/monitor"
|
|
555
|
-
// Extensions (for source imports without build)
|
|
556
|
-
"@djangocfg/ext-support",
|
|
557
|
-
"@djangocfg/ext-payments"
|
|
552
|
+
"@djangocfg/monitor"
|
|
558
553
|
];
|
|
559
554
|
var DEFAULT_OPTIMIZE_PACKAGES = [
|
|
560
555
|
"@djangocfg/ui-core",
|
|
561
|
-
"@djangocfg/ui-nextjs",
|
|
562
556
|
"@djangocfg/layouts",
|
|
563
557
|
"lucide-react",
|
|
564
558
|
"recharts"
|
|
@@ -1627,6 +1621,10 @@ function createBaseNextConfig(options = {}) {
|
|
|
1627
1621
|
const baseConfig = {
|
|
1628
1622
|
reactStrictMode: true,
|
|
1629
1623
|
trailingSlash: true,
|
|
1624
|
+
// Dev indicator position — set explicitly so it's managed from one place
|
|
1625
|
+
// across every @djangocfg app. Apps can override via `devIndicators` in
|
|
1626
|
+
// their options (deep-merged over this). Kept bottom-left for now.
|
|
1627
|
+
devIndicators: { position: "bottom-left" },
|
|
1630
1628
|
// Static export configuration
|
|
1631
1629
|
...isStaticBuild && {
|
|
1632
1630
|
output: "export",
|
|
@@ -1646,6 +1644,9 @@ function createBaseNextConfig(options = {}) {
|
|
|
1646
1644
|
NEXT_PUBLIC_BASE_PATH: basePath,
|
|
1647
1645
|
NEXT_PUBLIC_API_URL: apiUrl,
|
|
1648
1646
|
NEXT_PUBLIC_SITE_URL: siteUrl,
|
|
1647
|
+
// DPoP toggle for the generated auth client (RFC 9449). Only inlined when
|
|
1648
|
+
// explicitly enabled, so non-DPoP apps stay on the plain Bearer path.
|
|
1649
|
+
...options.dpop ? { NEXT_PUBLIC_DPOP_ENABLED: "true" } : {},
|
|
1649
1650
|
// Disable Next.js telemetry (Next.js 15+ uses env var instead of config option)
|
|
1650
1651
|
NEXT_TELEMETRY_DISABLED: "1",
|
|
1651
1652
|
...options.env
|
|
@@ -1666,19 +1667,35 @@ function createBaseNextConfig(options = {}) {
|
|
|
1666
1667
|
]
|
|
1667
1668
|
}
|
|
1668
1669
|
];
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1670
|
+
const hasIframeAllowlist = !!options.allowIframeFrom && options.allowIframeFrom.length > 0;
|
|
1671
|
+
const frameAncestors = hasIframeAllowlist ? options.allowIframeFrom.includes("*") ? "*" : `'self' ${options.allowIframeFrom.join(" ")}` : "'none'";
|
|
1672
|
+
const connectSrc = isDev ? "connect-src 'self' http: https: ws: wss:" : "connect-src 'self' https: wss:";
|
|
1673
|
+
const imgSrc = isDev ? "img-src 'self' data: blob: http: https:" : "img-src 'self' data: blob: https:";
|
|
1674
|
+
const cspDirectives = [
|
|
1675
|
+
"default-src 'self'",
|
|
1676
|
+
// Next.js requires inline + eval for its runtime/HMR. Tighten to nonces later.
|
|
1677
|
+
"script-src 'self' 'unsafe-inline' 'unsafe-eval'",
|
|
1678
|
+
"style-src 'self' 'unsafe-inline'",
|
|
1679
|
+
imgSrc,
|
|
1680
|
+
"font-src 'self' data:",
|
|
1681
|
+
// API/websocket calls go cross-origin to Django/Centrifugo.
|
|
1682
|
+
connectSrc,
|
|
1683
|
+
"object-src 'none'",
|
|
1684
|
+
"base-uri 'self'",
|
|
1685
|
+
"form-action 'self'",
|
|
1686
|
+
`frame-ancestors ${frameAncestors}`
|
|
1687
|
+
];
|
|
1688
|
+
headers.push({
|
|
1689
|
+
source: "/:path*",
|
|
1690
|
+
headers: [
|
|
1691
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
1692
|
+
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
|
1693
|
+
{ key: "Content-Security-Policy", value: cspDirectives.join("; ") },
|
|
1694
|
+
// X-Frame-Options for older browsers. Omitted when a wildcard iframe
|
|
1695
|
+
// allowlist is set (browsers then rely on CSP frame-ancestors).
|
|
1696
|
+
...hasIframeAllowlist && options.allowIframeFrom.includes("*") ? [] : [{ key: "X-Frame-Options", value: hasIframeAllowlist ? "SAMEORIGIN" : "DENY" }]
|
|
1697
|
+
]
|
|
1698
|
+
});
|
|
1682
1699
|
const userHeaders = options.headers ? await options.headers() : [];
|
|
1683
1700
|
return [...headers, ...userHeaders];
|
|
1684
1701
|
},
|
|
@@ -1780,6 +1797,7 @@ function createBaseNextConfig(options = {}) {
|
|
|
1780
1797
|
checkPackages: checkPackages2,
|
|
1781
1798
|
autoInstall,
|
|
1782
1799
|
allowIframeFrom,
|
|
1800
|
+
dpop,
|
|
1783
1801
|
...nextConfigOptions
|
|
1784
1802
|
} = options;
|
|
1785
1803
|
let finalConfig = deepMerge(baseConfig, nextConfigOptions);
|