gt-next 11.0.2 → 11.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/config-dir/props/withGTConfigProps.d.ts +2 -0
  3. package/dist/config-dir/props/withGTConfigProps.d.ts.map +1 -1
  4. package/dist/config-dir/props/withGTConfigProps.js.map +1 -1
  5. package/dist/config-dir/props/withGTConfigProps.mjs.map +1 -1
  6. package/dist/config.d.ts +1 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +5 -1
  9. package/dist/config.js.map +1 -1
  10. package/dist/config.mjs +5 -1
  11. package/dist/config.mjs.map +1 -1
  12. package/dist/errors/createErrors.d.ts +1 -1
  13. package/dist/errors/createErrors.d.ts.map +1 -1
  14. package/dist/errors/createErrors.js +4 -4
  15. package/dist/errors/createErrors.js.map +1 -1
  16. package/dist/errors/createErrors.mjs +4 -4
  17. package/dist/errors/createErrors.mjs.map +1 -1
  18. package/dist/middleware-dir/createNextMiddleware.d.ts +1 -3
  19. package/dist/middleware-dir/createNextMiddleware.d.ts.map +1 -1
  20. package/dist/middleware-dir/createNextMiddleware.js +4 -9
  21. package/dist/middleware-dir/createNextMiddleware.js.map +1 -1
  22. package/dist/middleware-dir/createNextMiddleware.mjs +5 -10
  23. package/dist/middleware-dir/createNextMiddleware.mjs.map +1 -1
  24. package/dist/utils/client-boundary.d.ts.map +1 -1
  25. package/dist/utils/client-boundary.js +3 -1
  26. package/dist/utils/client-boundary.js.map +1 -1
  27. package/dist/utils/client-boundary.mjs +3 -1
  28. package/dist/utils/client-boundary.mjs.map +1 -1
  29. package/dist/utils/pathRegex.d.ts +3 -0
  30. package/dist/utils/pathRegex.d.ts.map +1 -0
  31. package/dist/utils/pathRegex.js +19 -0
  32. package/dist/utils/pathRegex.js.map +1 -0
  33. package/dist/utils/pathRegex.mjs +17 -0
  34. package/dist/utils/pathRegex.mjs.map +1 -0
  35. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"createErrors.js","names":["createGtNextDiagnostic","createGtNextPluginDiagnostic","SWC_PLUGIN_SUPPORT","BABEL_PLUGIN_SUPPORT"],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport { getLocaleProperties } from '@generaltranslation/format';\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n formatDiagnosticErrorDetails,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedCustomLoadDictionaryError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadDictionary() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadDictionary() function from the configured file',\n});\n\nexport const unresolvedCustomLoadTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadTranslations() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadTranslations() function from the configured file',\n});\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\nexport const createInvalidRequestLocaleWarning = (\n locale: string,\n defaultLocale: string\n) =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `Locale \"${locale}\" is not valid or is not supported by this app`,\n wayOut: `The default locale \"${defaultLocale}\" will be used for this request`,\n fix: 'Use a valid BCP 47 locale code, add a custom mapping, or configure the locale in gt-next',\n });\n\nexport const createInvalidMiddlewareRegexError = (\n regexFilter: string,\n error: unknown\n) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `regexFilter \"${regexFilter}\" is not a valid regular expression`,\n fix: 'Pass a valid JavaScript regular expression string to createNextMiddleware()',\n details: formatDiagnosticErrorDetails(error),\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const createUnsupportedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales are currently unsupported by our service: ${locales\n .map((locale) => {\n const { name } = getLocaleProperties(locale);\n return `${locale} (${name})`;\n })\n .join(', ')}`;\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n `gt-next (plugin): The GT ${type} compiler could not be resolved. Skipping compiler optimizations.`;\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"createErrors.js","names":["createGtNextDiagnostic","createGtNextPluginDiagnostic","SWC_PLUGIN_SUPPORT","BABEL_PLUGIN_SUPPORT"],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport { getLocaleProperties } from '@generaltranslation/format';\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n formatDiagnosticErrorDetails,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedCustomLoadDictionaryError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadDictionary() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadDictionary() function from the configured file',\n});\n\nexport const unresolvedCustomLoadTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadTranslations() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadTranslations() function from the configured file',\n});\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\nexport const createInvalidRequestLocaleWarning = (\n locale: string,\n defaultLocale: string\n) =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `Locale \"${locale}\" is not valid or is not supported by this app`,\n wayOut: `The default locale \"${defaultLocale}\" will be used for this request`,\n fix: 'Use a valid BCP 47 locale code, add a custom mapping, or configure the locale in gt-next',\n });\n\nexport const createInvalidPathRegexError = (\n pathRegex: string,\n error: unknown\n) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `pathRegex \"${pathRegex}\" is not a valid regular expression`,\n fix: 'Pass a valid JavaScript regular expression string to withGTConfig()',\n details: formatDiagnosticErrorDetails(error),\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const createUnsupportedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales are currently unsupported by our service: ${locales\n .map((locale) => {\n const { name } = getLocaleProperties(locale);\n return `${locale} (${name})`;\n })\n .join(', ')}`;\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n `gt-next (plugin): The GT ${type} compiler could not be resolved. Skipping compiler optimizations.`;\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":";;;;;;;AAUA,MAAa,0BAA0BA,2BAAAA,uBAAuB;CAC5D,UAAU;CACV,cAAc;CACd,KAAK;CACL,QAAQ;CACT,CAAC;AAEF,MAAa,+BAA+B,SAAiB,OAC3DA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc,kDAAkD,SAAS,SAAS,OAAO,KAAK;CAC9F,KAAK;CACN,CAAC;AAEJ,MAAa,+BAA+B,SAAiB,OAC3DA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc,2CAA2C,SAAS,SAAS,OAAO,KAAK;CACvF,KAAK;CACN,CAAC;AAEJ,MAAa,oCAAoC,UAC/CA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc;CACd,KAAK;CACL,SAAS,MAAM;CAChB,CAAC;AAEJ,MAAa,qCAAqC,UAChDA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc;CACd,KAAK;CACL,SAAS,MAAM;CAChB,CAAC;AAEJ,MAAa,qCAAqCA,2BAAAA,uBAAuB;CACvE,UAAU;CACV,cAAc;CACd,KAAK;CACN,CAAC;AAEF,MAAa,+BAA+B,IAAY,iBACtDA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc,GAAG,aAAa,YAAY,GAAG;CAC7C,KAAK;CACN,CAAC;AAEJ,MAAa,sCAAsCA,2BAAAA,uBAAuB;CACxE,UAAU;CACV,cACE;CACF,KAAK;CACN,CAAC;AAEF,MAAa,wCAAwCA,2BAAAA,uBAAuB;CAC1E,UAAU;CACV,cACE;CACF,KAAK;CACN,CAAC;AAEF,MAAa,sCAAsC,SACjDA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc,+DAA+D;CAC7E,KAAK;CACN,CAAC;AAEJ,MAAa,wCAAwC,SACnDA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc,iEAAiE;CAC/E,KAAK;CACN,CAAC;AAEJ,MAAa,sCAAsC,cACjD,2CACE,UAAU,SAAS,IAAI,MAAM,GAC9B,wEAAwE,UAAU,KACjF,KACD;AAEH,MAAa,iBAAiBA,2BAAAA,uBAAuB;CACnD,UAAU;CACV,cAAc;CACd,KAAK;CACN,CAAC;AAEF,MAAa,kCAAkCA,2BAAAA,uBAAuB;CACpE,UAAU;CACV,cACE;CACF,KAAK;CACN,CAAC;AAEF,MAAa,uBAAuB,YAClCA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc;CACd,KAAK;CACL,SAAS;CACV,CAAC;AAEJ,MAAa,gCAAgC,YAC3CA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc;CACd,KAAK;CACL,SAAS;CACV,CAAC;AAEJ,MAAa,qCACX,QACA,kBAEAA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc,WAAW,OAAO;CAChC,QAAQ,uBAAuB,cAAc;CAC7C,KAAK;CACN,CAAC;AAEJ,MAAa,+BACX,WACA,UAEAA,2BAAAA,uBAAuB;CACrB,UAAU;CACV,cAAc,cAAc,UAAU;CACtC,KAAK;CACL,UAAA,GAAA,4BAAA,8BAAsC,MAAM;CAC7C,CAAC;AAIJ,MAAa,4BAA4B,UAAkB,QACzDA,2BAAAA,uBAAuB;CACrB,cAAc,GAAG,SAAS,gBAAgB,IAAI,KAAK,OAAO,CAAC;CAC3D,KAAK;CACN,CAAC;AAEJ,MAAa,mCAAmC,YAC9C,4EAA4E,QACzE,KAAK,WAAW;CACf,MAAM,EAAE,UAAA,GAAA,2BAAA,qBAA6B,OAAO;AAC5C,QAAO,GAAG,OAAO,IAAI,KAAK;EAC1B,CACD,KAAK,KAAK;AAEf,MAAa,uBAAuBA,2BAAAA,uBAAuB;CACzD,cAAc;CACd,KAAK;CACL,SAAS;CACV,CAAC;AAEF,MAAa,oBAAoBC,2BAAAA,6BAA6B;CAC5D,cAAc;CACd,KAAK;CACN,CAAC;AAEF,MAAa,8BAA8B,YACzC,qDAAqD,QAAQ,KAAK,KAAK,CAAC;AAE1E,MAAa,uCAAuC,YAClD,+DAA+D,QAAQ,KAAK,KAAK,CAAC;AAEpF,MAAa,qCAAqC,SAChD,4BAA4B,KAAK;AAEnC,MAAa,mCAAmCD,2BAAAA,uBAAuB;CACrE,cAAc;CACd,QAAQ;CACR,KAAK;CACN,CAAC;AAEF,MAAa,mCAAmCA,2BAAAA,uBAAuB;CACrE,cAAc;CACd,QAAQ;CACR,KAAK;CACN,CAAC;AAEF,MAAa,sCAAsC,SACjD,SAAS,QACL,mEAAmEE,yBAAAA,mBAAmB,sCACtF,0DAA0DC,yBAAAA,qBAAqB;AAErF,MAAa,2CACX;AAGF,MAAa,kCAAkC;AAE/C,MAAa,sCAAsC,wGAAwGD,yBAAAA,mBAAmB"}
@@ -89,10 +89,10 @@ const createInvalidRequestLocaleWarning = (locale, defaultLocale) => createGtNex
89
89
  wayOut: `The default locale "${defaultLocale}" will be used for this request`,
90
90
  fix: "Use a valid BCP 47 locale code, add a custom mapping, or configure the locale in gt-next"
91
91
  });
92
- const createInvalidMiddlewareRegexError = (regexFilter, error) => createGtNextDiagnostic({
92
+ const createInvalidPathRegexError = (pathRegex, error) => createGtNextDiagnostic({
93
93
  severity: "Error",
94
- whatHappened: `regexFilter "${regexFilter}" is not a valid regular expression`,
95
- fix: "Pass a valid JavaScript regular expression string to createNextMiddleware()",
94
+ whatHappened: `pathRegex "${pathRegex}" is not a valid regular expression`,
95
+ fix: "Pass a valid JavaScript regular expression string to withGTConfig()",
96
96
  details: formatDiagnosticErrorDetails(error)
97
97
  });
98
98
  const createBadFilepathWarning = (filename, dir) => createGtNextDiagnostic({
@@ -130,6 +130,6 @@ const babelCompilerTurbopackUnavailableWarning = "gt-next (plugin): The GT babel
130
130
  const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;
131
131
  const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;
132
132
  //#endregion
133
- export { APIKeyMissingWarn, babelCompilerTurbopackUnavailableWarning, conflictingConfigurationBuildError, createBadFilepathWarning, createDictionarySubsetError, createGTCompilerUnavailableWarning, createGTCompilerUnresolvedWarning, createInvalidMiddlewareRegexError, createInvalidRequestLocaleWarning, createUnresolvedNextVersionError, createUnresolvedReactVersionError, createUnsupportedLocalesWarning, customGetLocaleUnresolvedWarning, customGetRegionUnresolvedWarning, customLoadDictionaryWarning, customLoadTranslationsError, devApiKeyIncludedInProductionError, disablingCompileTimeHashWarning, getTranslationsSnapshotRscError, invalidCanonicalLocalesError, invalidLocalesError, projectIdMissingWarn, remoteTranslationsError, standardizedCanonicalLocalesWarning, standardizedLocalesWarning, swcPluginCompatibilityChangeWarning, typesFileError, unresolvedCustomLoadDictionaryError, unresolvedCustomLoadTranslationsError, unresolvedLoadDictionaryBuildError, unresolvedLoadTranslationsBuildError };
133
+ export { APIKeyMissingWarn, babelCompilerTurbopackUnavailableWarning, conflictingConfigurationBuildError, createBadFilepathWarning, createDictionarySubsetError, createGTCompilerUnavailableWarning, createGTCompilerUnresolvedWarning, createInvalidPathRegexError, createInvalidRequestLocaleWarning, createUnresolvedNextVersionError, createUnresolvedReactVersionError, createUnsupportedLocalesWarning, customGetLocaleUnresolvedWarning, customGetRegionUnresolvedWarning, customLoadDictionaryWarning, customLoadTranslationsError, devApiKeyIncludedInProductionError, disablingCompileTimeHashWarning, getTranslationsSnapshotRscError, invalidCanonicalLocalesError, invalidLocalesError, projectIdMissingWarn, remoteTranslationsError, standardizedCanonicalLocalesWarning, standardizedLocalesWarning, swcPluginCompatibilityChangeWarning, typesFileError, unresolvedCustomLoadDictionaryError, unresolvedCustomLoadTranslationsError, unresolvedLoadDictionaryBuildError, unresolvedLoadTranslationsBuildError };
134
134
 
135
135
  //# sourceMappingURL=createErrors.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"createErrors.mjs","names":[],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport { getLocaleProperties } from '@generaltranslation/format';\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n formatDiagnosticErrorDetails,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedCustomLoadDictionaryError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadDictionary() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadDictionary() function from the configured file',\n});\n\nexport const unresolvedCustomLoadTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadTranslations() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadTranslations() function from the configured file',\n});\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\nexport const createInvalidRequestLocaleWarning = (\n locale: string,\n defaultLocale: string\n) =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `Locale \"${locale}\" is not valid or is not supported by this app`,\n wayOut: `The default locale \"${defaultLocale}\" will be used for this request`,\n fix: 'Use a valid BCP 47 locale code, add a custom mapping, or configure the locale in gt-next',\n });\n\nexport const createInvalidMiddlewareRegexError = (\n regexFilter: string,\n error: unknown\n) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `regexFilter \"${regexFilter}\" is not a valid regular expression`,\n fix: 'Pass a valid JavaScript regular expression string to createNextMiddleware()',\n details: formatDiagnosticErrorDetails(error),\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const createUnsupportedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales are currently unsupported by our service: ${locales\n .map((locale) => {\n const { name } = getLocaleProperties(locale);\n return `${locale} (${name})`;\n })\n .join(', ')}`;\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n `gt-next (plugin): The GT ${type} compiler could not be resolved. Skipping compiler optimizations.`;\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"createErrors.mjs","names":[],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport { getLocaleProperties } from '@generaltranslation/format';\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n formatDiagnosticErrorDetails,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedCustomLoadDictionaryError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadDictionary() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadDictionary() function from the configured file',\n});\n\nexport const unresolvedCustomLoadTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'loadTranslations() was found during the build but could not be resolved at runtime',\n fix: 'Export a loadTranslations() function from the configured file',\n});\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\nexport const createInvalidRequestLocaleWarning = (\n locale: string,\n defaultLocale: string\n) =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `Locale \"${locale}\" is not valid or is not supported by this app`,\n wayOut: `The default locale \"${defaultLocale}\" will be used for this request`,\n fix: 'Use a valid BCP 47 locale code, add a custom mapping, or configure the locale in gt-next',\n });\n\nexport const createInvalidPathRegexError = (\n pathRegex: string,\n error: unknown\n) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `pathRegex \"${pathRegex}\" is not a valid regular expression`,\n fix: 'Pass a valid JavaScript regular expression string to withGTConfig()',\n details: formatDiagnosticErrorDetails(error),\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const createUnsupportedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales are currently unsupported by our service: ${locales\n .map((locale) => {\n const { name } = getLocaleProperties(locale);\n return `${locale} (${name})`;\n })\n .join(', ')}`;\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n `gt-next (plugin): The GT ${type} compiler could not be resolved. Skipping compiler optimizations.`;\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":"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"}
@@ -11,15 +11,13 @@ import { PathConfig } from './utils';
11
11
  * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.
12
12
  * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about
13
13
  * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps
14
- * @param {string} [config.regexFilter] - Regular expression that request pathnames must match for i18n middleware to be applied
15
14
  * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing
16
15
  * @returns {function} - A middleware function that processes the request and response.
17
16
  */
18
- export declare function createNextMiddleware({ localeRouting, prefixDefaultLocale, ignoreSourceMaps, regexFilter, pathConfig, }?: {
17
+ export declare function createNextMiddleware({ localeRouting, prefixDefaultLocale, ignoreSourceMaps, pathConfig, }?: {
19
18
  localeRouting?: boolean;
20
19
  prefixDefaultLocale?: boolean;
21
20
  ignoreSourceMaps?: boolean;
22
- regexFilter?: string;
23
21
  pathConfig?: PathConfig;
24
22
  }): (req: NextRequest) => NextResponse<unknown>;
25
23
  //# sourceMappingURL=createNextMiddleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createNextMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware-dir/createNextMiddleware.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASxD,OAAO,EACL,UAAU,EAQX,MAAM,SAAS,CAAC;AAcjB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,aAAoB,EACpB,mBAA2B,EAC3B,gBAAuB,EACvB,WAAW,EACX,UAAe,GAChB,GAAE;IACD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;CACpB,SAkHqB,WAAW,2BA6MrC"}
1
+ {"version":3,"file":"createNextMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware-dir/createNextMiddleware.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASxD,OAAO,EACL,UAAU,EAQX,MAAM,SAAS,CAAC;AAejB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,aAAoB,EACpB,mBAA2B,EAC3B,gBAAuB,EACvB,UAAe,GAChB,GAAE;IACD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;CACpB,SA6GqB,WAAW,2BA6MrC"}
@@ -3,6 +3,7 @@ require("../_virtual/_rolldown/runtime.js");
3
3
  require("../utils/headers.js");
4
4
  require("../utils/cookies.js");
5
5
  const require_errors_createErrors = require("../errors/createErrors.js");
6
+ const require_utils_pathRegex = require("../utils/pathRegex.js");
6
7
  const require_middleware_dir_utils = require("./utils.js");
7
8
  let generaltranslation_internal = require("generaltranslation/internal");
8
9
  let _generaltranslation_react_core_pure = require("@generaltranslation/react-core/pure");
@@ -22,17 +23,11 @@ const NEXT_JS_SOURCE_MAP_PATH = "/__nextjs_source-map";
22
23
  * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.
23
24
  * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about
24
25
  * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps
25
- * @param {string} [config.regexFilter] - Regular expression that request pathnames must match for i18n middleware to be applied
26
26
  * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing
27
27
  * @returns {function} - A middleware function that processes the request and response.
28
28
  */
29
- function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, regexFilter, pathConfig = {} } = {}) {
30
- let pathFilter;
31
- if (regexFilter !== void 0) try {
32
- pathFilter = new RegExp(regexFilter);
33
- } catch (error) {
34
- throw new Error(require_errors_createErrors.createInvalidMiddlewareRegexError(regexFilter, error));
35
- }
29
+ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, pathConfig = {} } = {}) {
30
+ const pathRegex = require_utils_pathRegex.compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);
36
31
  let envParams;
37
32
  if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) try {
38
33
  envParams = JSON.parse(process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS);
@@ -77,7 +72,7 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
77
72
  * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.
78
73
  */
79
74
  function middleware(req) {
80
- if (pathFilter && !pathFilter.test(req.nextUrl.pathname)) return next_server_js.NextResponse.next();
75
+ if (!require_utils_pathRegex.pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) return next_server_js.NextResponse.next();
81
76
  if (ignoreSourceMaps && req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)) return next_server_js.NextResponse.next();
82
77
  const { userLocale, pathnameLocale, unstandardizedPathnameLocale, clearResetCookie } = require_middleware_dir_utils.getLocaleFromRequest(req, defaultLocale, locales, localeRouting, gtServicesEnabled, prefixDefaultLocale, defaultLocalePaths, referrerLocaleCookieName, localeCookieName, resetLocaleCookieName, gt);
83
78
  const headerList = new Headers(req.headers);
@@ -1 +1 @@
1
- {"version":3,"file":"createNextMiddleware.js","names":["createInvalidMiddlewareRegexError","GTRuntime","libraryDefaultLocale","defaultLocaleCookieName","defaultResetLocaleCookieName","createUnsupportedLocalesWarning","createPathToSharedPathMap","NextResponse","getLocaleFromRequest","getResponse","getSharedPath","replaceDynamicSegments","getLocalizedPath"],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { isSameDialect, standardizeLocale } from '@generaltranslation/format';\nimport { GTRuntime } from 'generaltranslation/runtime';\nimport { libraryDefaultLocale } from 'generaltranslation/internal';\nimport {\n createInvalidMiddlewareRegexError,\n createUnsupportedLocalesWarning,\n} from '../errors/createErrors';\nimport { NextRequest, NextResponse } from 'next/server';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from '../utils/cookies';\nimport {\n defaultLocaleCookieName,\n defaultResetLocaleCookieName,\n} from '@generaltranslation/react-core/pure';\nimport {\n PathConfig,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n createPathToSharedPathMap,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n} from './utils';\nimport { defaultLocaleHeaderName } from '../utils/headers';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport type { HeadersAndCookies } from '../config-dir/props/withGTConfigProps';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\ntype MiddlewareEnvConfig = {\n customMapping?: CustomMapping;\n defaultLocale?: string;\n locales?: string[];\n headersAndCookies?: HeadersAndCookies;\n};\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {string} [config.regexFilter] - Regular expression that request pathnames must match for i18n middleware to be applied\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware({\n localeRouting = true,\n prefixDefaultLocale = false,\n ignoreSourceMaps = true,\n regexFilter,\n pathConfig = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: boolean;\n ignoreSourceMaps?: boolean;\n regexFilter?: string;\n pathConfig?: PathConfig;\n} = {}) {\n let pathFilter: RegExp | undefined;\n if (regexFilter !== undefined) {\n try {\n pathFilter = new RegExp(regexFilter);\n } catch (error) {\n throw new Error(createInvalidMiddlewareRegexError(regexFilter, error));\n }\n }\n\n // i18n config\n let envParams: MiddlewareEnvConfig | undefined;\n if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) {\n try {\n envParams = JSON.parse(\n process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS\n );\n } catch (error) {\n console.error(`gt-next middleware:`, error);\n }\n }\n\n // gt instance\n const gt = new GTRuntime({\n customMapping: envParams?.customMapping,\n });\n\n // using gt services\n const gtServicesEnabled =\n process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === 'true';\n\n // i18n config\n const defaultLocale: string =\n envParams?.defaultLocale || libraryDefaultLocale;\n const locales: string[] = envParams?.locales || [defaultLocale];\n\n // add canonical locales\n const canonicalLocales = Object.values(envParams?.customMapping || {})\n .filter(\n (locale): locale is { code: string } =>\n typeof locale === 'object' &&\n locale !== null &&\n 'code' in locale &&\n typeof locale.code === 'string' &&\n locale.code.length > 0\n )\n .map((locale) => locale.code);\n locales.push(...canonicalLocales);\n\n // cookies and header names\n const headersAndCookies = envParams?.headersAndCookies || {};\n const localeRoutingEnabledCookieName =\n headersAndCookies?.localeRoutingEnabledCookieName ||\n defaultLocaleRoutingEnabledCookieName;\n const referrerLocaleCookieName =\n headersAndCookies?.referrerLocaleCookieName ||\n defaultReferrerLocaleCookieName;\n const localeCookieName =\n headersAndCookies?.localeCookieName || defaultLocaleCookieName;\n const resetLocaleCookieName =\n headersAndCookies?.resetLocaleCookieName || defaultResetLocaleCookieName;\n const localeHeaderName =\n headersAndCookies?.localeHeaderName || defaultLocaleHeaderName;\n\n if (!gt.isValidLocale(defaultLocale))\n throw new Error(\n `gt-next middleware: defaultLocale \"${defaultLocale}\" is not a valid locale.`\n );\n\n const warningLocales = locales.filter((locale) => !gt.isValidLocale(locale));\n if (warningLocales.length)\n console.warn(createUnsupportedLocalesWarning(warningLocales));\n\n // ---------- PRE-PROCESSING PATHS ---------- //\n\n // Standardize pathConfig paths\n pathConfig = Object.entries(pathConfig).reduce<PathConfig>(\n (acc, [sharedPath, localizedPath]) => {\n if (typeof localizedPath === 'string') {\n acc[sharedPath] = localizedPath;\n } else {\n acc[sharedPath] = Object.entries(localizedPath).reduce<{\n [key: string]: string;\n }>((acc, [locale, localizedPath]) => {\n acc[gtServicesEnabled ? standardizeLocale(locale) : locale] =\n localizedPath;\n return acc;\n }, {});\n }\n return acc;\n },\n {}\n );\n\n // Create the path mapping\n const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(\n pathConfig,\n prefixDefaultLocale,\n defaultLocale\n );\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (pathFilter && !pathFilter.test(req.nextUrl.pathname)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale,\n pathnameLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n gtServicesEnabled,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt\n );\n\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'redirect', ...responseConfig });\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPath = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n `/${userLocale}${sharedPath}`\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n localizedPath\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n if (pathnameLocale) {\n // REDIRECT CASE: used setLocale (/fr/customers -> /customers) (/en/customers -> /customers)\n if (clearResetCookie) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(`/${userLocale}${pathname}`);\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: remove locale prefix when setLocale is used (/en/blog -> /blog) (/fr/fr-about -> /en-about)\n if (clearResetCookie) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n localizedPathWithParameters !== `/${userLocale}${pathname}`\n ) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ''\n ) || '/'\n );\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (pathname !== localizedPathWithParameters) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n if (\n standardizedPathname !== sharedPathWithParameters // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createNextMiddleware.js","names":["compilePathRegex","GTRuntime","libraryDefaultLocale","defaultLocaleCookieName","defaultResetLocaleCookieName","createUnsupportedLocalesWarning","createPathToSharedPathMap","pathnameMatchesRegex","NextResponse","getLocaleFromRequest","getResponse","getSharedPath","replaceDynamicSegments","getLocalizedPath"],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { isSameDialect, standardizeLocale } from '@generaltranslation/format';\nimport { GTRuntime } from 'generaltranslation/runtime';\nimport { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { createUnsupportedLocalesWarning } from '../errors/createErrors';\nimport { NextRequest, NextResponse } from 'next/server';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from '../utils/cookies';\nimport {\n defaultLocaleCookieName,\n defaultResetLocaleCookieName,\n} from '@generaltranslation/react-core/pure';\nimport {\n PathConfig,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n createPathToSharedPathMap,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n} from './utils';\nimport { defaultLocaleHeaderName } from '../utils/headers';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport type { HeadersAndCookies } from '../config-dir/props/withGTConfigProps';\nimport { compilePathRegex, pathnameMatchesRegex } from '../utils/pathRegex';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\ntype MiddlewareEnvConfig = {\n customMapping?: CustomMapping;\n defaultLocale?: string;\n locales?: string[];\n headersAndCookies?: HeadersAndCookies;\n};\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware({\n localeRouting = true,\n prefixDefaultLocale = false,\n ignoreSourceMaps = true,\n pathConfig = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: boolean;\n ignoreSourceMaps?: boolean;\n pathConfig?: PathConfig;\n} = {}) {\n const pathRegex = compilePathRegex(\n process.env._GENERALTRANSLATION_PATH_REGEX\n );\n\n // i18n config\n let envParams: MiddlewareEnvConfig | undefined;\n if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) {\n try {\n envParams = JSON.parse(\n process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS\n );\n } catch (error) {\n console.error(`gt-next middleware:`, error);\n }\n }\n\n // gt instance\n const gt = new GTRuntime({\n customMapping: envParams?.customMapping,\n });\n\n // using gt services\n const gtServicesEnabled =\n process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === 'true';\n\n // i18n config\n const defaultLocale: string =\n envParams?.defaultLocale || libraryDefaultLocale;\n const locales: string[] = envParams?.locales || [defaultLocale];\n\n // add canonical locales\n const canonicalLocales = Object.values(envParams?.customMapping || {})\n .filter(\n (locale): locale is { code: string } =>\n typeof locale === 'object' &&\n locale !== null &&\n 'code' in locale &&\n typeof locale.code === 'string' &&\n locale.code.length > 0\n )\n .map((locale) => locale.code);\n locales.push(...canonicalLocales);\n\n // cookies and header names\n const headersAndCookies = envParams?.headersAndCookies || {};\n const localeRoutingEnabledCookieName =\n headersAndCookies?.localeRoutingEnabledCookieName ||\n defaultLocaleRoutingEnabledCookieName;\n const referrerLocaleCookieName =\n headersAndCookies?.referrerLocaleCookieName ||\n defaultReferrerLocaleCookieName;\n const localeCookieName =\n headersAndCookies?.localeCookieName || defaultLocaleCookieName;\n const resetLocaleCookieName =\n headersAndCookies?.resetLocaleCookieName || defaultResetLocaleCookieName;\n const localeHeaderName =\n headersAndCookies?.localeHeaderName || defaultLocaleHeaderName;\n\n if (!gt.isValidLocale(defaultLocale))\n throw new Error(\n `gt-next middleware: defaultLocale \"${defaultLocale}\" is not a valid locale.`\n );\n\n const warningLocales = locales.filter((locale) => !gt.isValidLocale(locale));\n if (warningLocales.length)\n console.warn(createUnsupportedLocalesWarning(warningLocales));\n\n // ---------- PRE-PROCESSING PATHS ---------- //\n\n // Standardize pathConfig paths\n pathConfig = Object.entries(pathConfig).reduce<PathConfig>(\n (acc, [sharedPath, localizedPath]) => {\n if (typeof localizedPath === 'string') {\n acc[sharedPath] = localizedPath;\n } else {\n acc[sharedPath] = Object.entries(localizedPath).reduce<{\n [key: string]: string;\n }>((acc, [locale, localizedPath]) => {\n acc[gtServicesEnabled ? standardizeLocale(locale) : locale] =\n localizedPath;\n return acc;\n }, {});\n }\n return acc;\n },\n {}\n );\n\n // Create the path mapping\n const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(\n pathConfig,\n prefixDefaultLocale,\n defaultLocale\n );\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale,\n pathnameLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n gtServicesEnabled,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt\n );\n\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'redirect', ...responseConfig });\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPath = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n `/${userLocale}${sharedPath}`\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n localizedPath\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n if (pathnameLocale) {\n // REDIRECT CASE: used setLocale (/fr/customers -> /customers) (/en/customers -> /customers)\n if (clearResetCookie) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(`/${userLocale}${pathname}`);\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: remove locale prefix when setLocale is used (/en/blog -> /blog) (/fr/fr-about -> /en-about)\n if (clearResetCookie) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n localizedPathWithParameters !== `/${userLocale}${pathname}`\n ) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ''\n ) || '/'\n );\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (pathname !== localizedPathWithParameters) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n if (\n standardizedPathname !== sharedPathWithParameters // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import "../utils/headers.mjs";
2
2
  import "../utils/cookies.mjs";
3
- import { createInvalidMiddlewareRegexError, createUnsupportedLocalesWarning } from "../errors/createErrors.mjs";
3
+ import { createUnsupportedLocalesWarning } from "../errors/createErrors.mjs";
4
+ import { compilePathRegex, pathnameMatchesRegex } from "../utils/pathRegex.mjs";
4
5
  import { createPathToSharedPathMap, getLocaleFromRequest, getLocalizedPath, getResponse, getSharedPath, replaceDynamicSegments } from "./utils.mjs";
5
6
  import { libraryDefaultLocale } from "generaltranslation/internal";
6
7
  import { defaultLocaleCookieName, defaultResetLocaleCookieName } from "@generaltranslation/react-core/pure";
@@ -20,17 +21,11 @@ const NEXT_JS_SOURCE_MAP_PATH = "/__nextjs_source-map";
20
21
  * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.
21
22
  * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about
22
23
  * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps
23
- * @param {string} [config.regexFilter] - Regular expression that request pathnames must match for i18n middleware to be applied
24
24
  * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing
25
25
  * @returns {function} - A middleware function that processes the request and response.
26
26
  */
27
- function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, regexFilter, pathConfig = {} } = {}) {
28
- let pathFilter;
29
- if (regexFilter !== void 0) try {
30
- pathFilter = new RegExp(regexFilter);
31
- } catch (error) {
32
- throw new Error(createInvalidMiddlewareRegexError(regexFilter, error));
33
- }
27
+ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, pathConfig = {} } = {}) {
28
+ const pathRegex = compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);
34
29
  let envParams;
35
30
  if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) try {
36
31
  envParams = JSON.parse(process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS);
@@ -75,7 +70,7 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
75
70
  * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.
76
71
  */
77
72
  function middleware(req) {
78
- if (pathFilter && !pathFilter.test(req.nextUrl.pathname)) return NextResponse.next();
73
+ if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) return NextResponse.next();
79
74
  if (ignoreSourceMaps && req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)) return NextResponse.next();
80
75
  const { userLocale, pathnameLocale, unstandardizedPathnameLocale, clearResetCookie } = getLocaleFromRequest(req, defaultLocale, locales, localeRouting, gtServicesEnabled, prefixDefaultLocale, defaultLocalePaths, referrerLocaleCookieName, localeCookieName, resetLocaleCookieName, gt);
81
76
  const headerList = new Headers(req.headers);
@@ -1 +1 @@
1
- {"version":3,"file":"createNextMiddleware.mjs","names":[],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { isSameDialect, standardizeLocale } from '@generaltranslation/format';\nimport { GTRuntime } from 'generaltranslation/runtime';\nimport { libraryDefaultLocale } from 'generaltranslation/internal';\nimport {\n createInvalidMiddlewareRegexError,\n createUnsupportedLocalesWarning,\n} from '../errors/createErrors';\nimport { NextRequest, NextResponse } from 'next/server';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from '../utils/cookies';\nimport {\n defaultLocaleCookieName,\n defaultResetLocaleCookieName,\n} from '@generaltranslation/react-core/pure';\nimport {\n PathConfig,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n createPathToSharedPathMap,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n} from './utils';\nimport { defaultLocaleHeaderName } from '../utils/headers';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport type { HeadersAndCookies } from '../config-dir/props/withGTConfigProps';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\ntype MiddlewareEnvConfig = {\n customMapping?: CustomMapping;\n defaultLocale?: string;\n locales?: string[];\n headersAndCookies?: HeadersAndCookies;\n};\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {string} [config.regexFilter] - Regular expression that request pathnames must match for i18n middleware to be applied\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware({\n localeRouting = true,\n prefixDefaultLocale = false,\n ignoreSourceMaps = true,\n regexFilter,\n pathConfig = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: boolean;\n ignoreSourceMaps?: boolean;\n regexFilter?: string;\n pathConfig?: PathConfig;\n} = {}) {\n let pathFilter: RegExp | undefined;\n if (regexFilter !== undefined) {\n try {\n pathFilter = new RegExp(regexFilter);\n } catch (error) {\n throw new Error(createInvalidMiddlewareRegexError(regexFilter, error));\n }\n }\n\n // i18n config\n let envParams: MiddlewareEnvConfig | undefined;\n if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) {\n try {\n envParams = JSON.parse(\n process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS\n );\n } catch (error) {\n console.error(`gt-next middleware:`, error);\n }\n }\n\n // gt instance\n const gt = new GTRuntime({\n customMapping: envParams?.customMapping,\n });\n\n // using gt services\n const gtServicesEnabled =\n process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === 'true';\n\n // i18n config\n const defaultLocale: string =\n envParams?.defaultLocale || libraryDefaultLocale;\n const locales: string[] = envParams?.locales || [defaultLocale];\n\n // add canonical locales\n const canonicalLocales = Object.values(envParams?.customMapping || {})\n .filter(\n (locale): locale is { code: string } =>\n typeof locale === 'object' &&\n locale !== null &&\n 'code' in locale &&\n typeof locale.code === 'string' &&\n locale.code.length > 0\n )\n .map((locale) => locale.code);\n locales.push(...canonicalLocales);\n\n // cookies and header names\n const headersAndCookies = envParams?.headersAndCookies || {};\n const localeRoutingEnabledCookieName =\n headersAndCookies?.localeRoutingEnabledCookieName ||\n defaultLocaleRoutingEnabledCookieName;\n const referrerLocaleCookieName =\n headersAndCookies?.referrerLocaleCookieName ||\n defaultReferrerLocaleCookieName;\n const localeCookieName =\n headersAndCookies?.localeCookieName || defaultLocaleCookieName;\n const resetLocaleCookieName =\n headersAndCookies?.resetLocaleCookieName || defaultResetLocaleCookieName;\n const localeHeaderName =\n headersAndCookies?.localeHeaderName || defaultLocaleHeaderName;\n\n if (!gt.isValidLocale(defaultLocale))\n throw new Error(\n `gt-next middleware: defaultLocale \"${defaultLocale}\" is not a valid locale.`\n );\n\n const warningLocales = locales.filter((locale) => !gt.isValidLocale(locale));\n if (warningLocales.length)\n console.warn(createUnsupportedLocalesWarning(warningLocales));\n\n // ---------- PRE-PROCESSING PATHS ---------- //\n\n // Standardize pathConfig paths\n pathConfig = Object.entries(pathConfig).reduce<PathConfig>(\n (acc, [sharedPath, localizedPath]) => {\n if (typeof localizedPath === 'string') {\n acc[sharedPath] = localizedPath;\n } else {\n acc[sharedPath] = Object.entries(localizedPath).reduce<{\n [key: string]: string;\n }>((acc, [locale, localizedPath]) => {\n acc[gtServicesEnabled ? standardizeLocale(locale) : locale] =\n localizedPath;\n return acc;\n }, {});\n }\n return acc;\n },\n {}\n );\n\n // Create the path mapping\n const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(\n pathConfig,\n prefixDefaultLocale,\n defaultLocale\n );\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (pathFilter && !pathFilter.test(req.nextUrl.pathname)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale,\n pathnameLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n gtServicesEnabled,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt\n );\n\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'redirect', ...responseConfig });\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPath = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n `/${userLocale}${sharedPath}`\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n localizedPath\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n if (pathnameLocale) {\n // REDIRECT CASE: used setLocale (/fr/customers -> /customers) (/en/customers -> /customers)\n if (clearResetCookie) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(`/${userLocale}${pathname}`);\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: remove locale prefix when setLocale is used (/en/blog -> /blog) (/fr/fr-about -> /en-about)\n if (clearResetCookie) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n localizedPathWithParameters !== `/${userLocale}${pathname}`\n ) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ''\n ) || '/'\n );\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (pathname !== localizedPathWithParameters) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n if (\n standardizedPathname !== sharedPathWithParameters // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createNextMiddleware.mjs","names":[],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { isSameDialect, standardizeLocale } from '@generaltranslation/format';\nimport { GTRuntime } from 'generaltranslation/runtime';\nimport { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { createUnsupportedLocalesWarning } from '../errors/createErrors';\nimport { NextRequest, NextResponse } from 'next/server';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from '../utils/cookies';\nimport {\n defaultLocaleCookieName,\n defaultResetLocaleCookieName,\n} from '@generaltranslation/react-core/pure';\nimport {\n PathConfig,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n createPathToSharedPathMap,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n} from './utils';\nimport { defaultLocaleHeaderName } from '../utils/headers';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport type { HeadersAndCookies } from '../config-dir/props/withGTConfigProps';\nimport { compilePathRegex, pathnameMatchesRegex } from '../utils/pathRegex';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\ntype MiddlewareEnvConfig = {\n customMapping?: CustomMapping;\n defaultLocale?: string;\n locales?: string[];\n headersAndCookies?: HeadersAndCookies;\n};\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware({\n localeRouting = true,\n prefixDefaultLocale = false,\n ignoreSourceMaps = true,\n pathConfig = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: boolean;\n ignoreSourceMaps?: boolean;\n pathConfig?: PathConfig;\n} = {}) {\n const pathRegex = compilePathRegex(\n process.env._GENERALTRANSLATION_PATH_REGEX\n );\n\n // i18n config\n let envParams: MiddlewareEnvConfig | undefined;\n if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) {\n try {\n envParams = JSON.parse(\n process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS\n );\n } catch (error) {\n console.error(`gt-next middleware:`, error);\n }\n }\n\n // gt instance\n const gt = new GTRuntime({\n customMapping: envParams?.customMapping,\n });\n\n // using gt services\n const gtServicesEnabled =\n process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === 'true';\n\n // i18n config\n const defaultLocale: string =\n envParams?.defaultLocale || libraryDefaultLocale;\n const locales: string[] = envParams?.locales || [defaultLocale];\n\n // add canonical locales\n const canonicalLocales = Object.values(envParams?.customMapping || {})\n .filter(\n (locale): locale is { code: string } =>\n typeof locale === 'object' &&\n locale !== null &&\n 'code' in locale &&\n typeof locale.code === 'string' &&\n locale.code.length > 0\n )\n .map((locale) => locale.code);\n locales.push(...canonicalLocales);\n\n // cookies and header names\n const headersAndCookies = envParams?.headersAndCookies || {};\n const localeRoutingEnabledCookieName =\n headersAndCookies?.localeRoutingEnabledCookieName ||\n defaultLocaleRoutingEnabledCookieName;\n const referrerLocaleCookieName =\n headersAndCookies?.referrerLocaleCookieName ||\n defaultReferrerLocaleCookieName;\n const localeCookieName =\n headersAndCookies?.localeCookieName || defaultLocaleCookieName;\n const resetLocaleCookieName =\n headersAndCookies?.resetLocaleCookieName || defaultResetLocaleCookieName;\n const localeHeaderName =\n headersAndCookies?.localeHeaderName || defaultLocaleHeaderName;\n\n if (!gt.isValidLocale(defaultLocale))\n throw new Error(\n `gt-next middleware: defaultLocale \"${defaultLocale}\" is not a valid locale.`\n );\n\n const warningLocales = locales.filter((locale) => !gt.isValidLocale(locale));\n if (warningLocales.length)\n console.warn(createUnsupportedLocalesWarning(warningLocales));\n\n // ---------- PRE-PROCESSING PATHS ---------- //\n\n // Standardize pathConfig paths\n pathConfig = Object.entries(pathConfig).reduce<PathConfig>(\n (acc, [sharedPath, localizedPath]) => {\n if (typeof localizedPath === 'string') {\n acc[sharedPath] = localizedPath;\n } else {\n acc[sharedPath] = Object.entries(localizedPath).reduce<{\n [key: string]: string;\n }>((acc, [locale, localizedPath]) => {\n acc[gtServicesEnabled ? standardizeLocale(locale) : locale] =\n localizedPath;\n return acc;\n }, {});\n }\n return acc;\n },\n {}\n );\n\n // Create the path mapping\n const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(\n pathConfig,\n prefixDefaultLocale,\n defaultLocale\n );\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale,\n pathnameLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n gtServicesEnabled,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt\n );\n\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'redirect', ...responseConfig });\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPath = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n `/${userLocale}${sharedPath}`\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined\n ? replaceDynamicSegments(\n pathnameLocale\n ? standardizedPathname\n : `/${userLocale}${standardizedPathname}`,\n localizedPath\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n if (pathnameLocale) {\n // REDIRECT CASE: used setLocale (/fr/customers -> /customers) (/en/customers -> /customers)\n if (clearResetCookie) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(`/${userLocale}${pathname}`);\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: remove locale prefix when setLocale is used (/en/blog -> /blog) (/fr/fr-about -> /en-about)\n if (clearResetCookie) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n localizedPathWithParameters !== `/${userLocale}${pathname}`\n ) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ''\n ) || '/'\n );\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (pathname !== localizedPathWithParameters) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n if (\n standardizedPathname !== sharedPathWithParameters // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"client-boundary.d.ts","sourceRoot":"","sources":["../../src/utils/client-boundary.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGnE,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAkBlE;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,2CAS7D"}
1
+ {"version":3,"file":"client-boundary.d.ts","sourceRoot":"","sources":["../../src/utils/client-boundary.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGnE,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAsBlE;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,2CAS7D"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  require("../_virtual/_rolldown/runtime.js");
4
4
  const require_utils_cookies = require("./cookies.js");
5
+ const require_utils_pathRegex = require("./pathRegex.js");
5
6
  const require_setup_initGT_client = require("../setup/initGT.client.js");
6
7
  let gt_i18n_internal = require("gt-i18n/internal");
7
8
  let gt_react = require("gt-react");
@@ -9,6 +10,7 @@ let react = require("react");
9
10
  let react_jsx_runtime = require("react/jsx-runtime");
10
11
  let next_navigation_js = require("next/navigation.js");
11
12
  //#region src/utils/client-boundary.tsx
13
+ const pathRegex = require_utils_pathRegex.compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);
12
14
  /**
13
15
  * Only need to initalize client. We know server was already
14
16
  * inialaized by index.rsc.ts. We do not know yet if client
@@ -43,7 +45,7 @@ function usePathCheck({ reloadServer, locale, referrerLocaleCookieName = require
43
45
  document.cookie = `${referrerLocaleCookieName}=${i18nConfig.resolveAliasLocale(locale)};path=/`;
44
46
  const locales = i18nConfig.getLocales();
45
47
  const defaultLocale = i18nConfig.getDefaultLocale();
46
- if (document.cookie.split("; ").find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))?.split("=")[1] === "true") {
48
+ if (document.cookie.split("; ").find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))?.split("=")[1] === "true" && require_utils_pathRegex.pathnameMatchesRegex(pathname, pathRegex)) {
47
49
  const extractedLocale = extractLocale(pathname, i18nConfig) || defaultLocale;
48
50
  let pathLocale = i18nConfig.determineLocale([i18nConfig.isGTServicesEnabled() ? i18nConfig.standardizeLocale(extractedLocale) : extractedLocale, defaultLocale], locales);
49
51
  if (pathLocale) pathLocale = i18nConfig.resolveAliasLocale(pathLocale);
@@ -1 +1 @@
1
- {"version":3,"file":"client-boundary.js","names":["GTProvider","defaultReferrerLocaleCookieName","defaultLocaleRoutingEnabledCookieName"],"sources":["../../src/utils/client-boundary.tsx"],"sourcesContent":["'use client';\n\n/**\n * This is a small boundary for RSC consumption of client components\n * Cannot be consumed through gt-react/index.rsc as deciding btwn\n * gt-react/index.server and gt-react/index.client can only happen\n * here. This matters for GTProvider, but not for LocaleSelector.\n * This pattern is just good to follow for carrying over different\n * behaviors between client and server from gt-react.\n */\n\nexport { LocaleSelector as Client_LocaleSelector } from 'gt-react';\nexport { RegionSelector as Client_RegionSelector } from 'gt-react';\n\nimport { getI18nConfig, I18nConfig } from 'gt-i18n/internal';\nimport { GTProvider, type SharedGTProviderProps } from 'gt-react';\nimport { usePathname, useRouter } from 'next/navigation';\nimport { useCallback, useEffect } from 'react';\nimport { initializeGTClient } from '../setup/initGT.client';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from './cookies';\n\n/**\n * Only need to initalize client. We know server was already\n * inialaized by index.rsc.ts. We do not know yet if client\n * has been initialized by index.client.ts.\n */\nif (typeof window !== 'undefined') {\n initializeGTClient();\n}\n\n/**\n * Small wrapper to embed nextjs app router behavior\n */\nexport function Client_GTProvider(props: SharedGTProviderProps) {\n const router = useRouter();\n const reload = useCallback(() => {\n // Reload server components\n router.refresh();\n }, [router]);\n // TODO: when routing is enabled, validate the path matches the locale\n usePathCheck({ reloadServer: reload, locale: props.locale });\n return <GTProvider {...props} _reload={reload} />;\n}\n\n/**\n * Reloads the server components if\n * TODO: optimize this hook\n */\nfunction usePathCheck({\n reloadServer,\n locale,\n referrerLocaleCookieName = defaultReferrerLocaleCookieName,\n localeRoutingEnabledCookieName = defaultLocaleRoutingEnabledCookieName,\n}: {\n reloadServer: () => void;\n locale: string;\n referrerLocaleCookieName?: string;\n localeRoutingEnabledCookieName?: string;\n}) {\n const pathname = usePathname();\n\n useEffect(() => {\n // Track the referrer locale for middleware\n const i18nConfig = getI18nConfig();\n document.cookie = `${referrerLocaleCookieName}=${i18nConfig.resolveAliasLocale(locale)};path=/`;\n\n // Reload the server components if the pathname changes\n const locales = i18nConfig.getLocales();\n const defaultLocale = i18nConfig.getDefaultLocale();\n const middlewareEnabled =\n document.cookie\n .split('; ')\n .find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))\n ?.split('=')[1] === 'true';\n if (middlewareEnabled) {\n // Extract locale from pathname\n const extractedLocale =\n extractLocale(pathname, i18nConfig) || defaultLocale;\n let pathLocale = i18nConfig.determineLocale(\n [\n i18nConfig.isGTServicesEnabled()\n ? i18nConfig.standardizeLocale(extractedLocale)\n : extractedLocale,\n defaultLocale,\n ],\n locales\n );\n if (pathLocale) {\n pathLocale = i18nConfig.resolveAliasLocale(pathLocale);\n }\n\n if (pathLocale && locales.includes(pathLocale) && pathLocale !== locale) {\n // clear cookie (avoids infinite loop when there is no middleware)\n document.cookie = `${localeRoutingEnabledCookieName}=;path=/`;\n\n // reload page\n reloadServer();\n }\n }\n }, [\n pathname,\n locale,\n referrerLocaleCookieName,\n localeRoutingEnabledCookieName,\n reloadServer,\n ]);\n}\n\nfunction extractLocale(\n pathname: string,\n i18nConfig: I18nConfig\n): string | null {\n const matches = pathname.match(/^\\/([^/]+)(?:\\/|$)/);\n return matches ? i18nConfig.resolveAliasLocale(matches[1]) : null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6BA,IAAI,OAAO,WAAW,YACpB,6BAAA,oBAAoB;;;;AAMtB,SAAgB,kBAAkB,OAA8B;CAC9D,MAAM,UAAA,GAAA,mBAAA,YAAoB;CAC1B,MAAM,UAAA,GAAA,MAAA,mBAA2B;AAE/B,SAAO,SAAS;IACf,CAAC,OAAO,CAAC;AAEZ,cAAa;EAAE,cAAc;EAAQ,QAAQ,MAAM;EAAQ,CAAC;AAC5D,QAAO,iBAAA,GAAA,kBAAA,KAACA,SAAAA,YAAD;EAAY,GAAI;EAAO,SAAS;EAAU,CAAA;;;;;;AAOnD,SAAS,aAAa,EACpB,cACA,QACA,2BAA2BC,sBAAAA,iCAC3B,iCAAiCC,sBAAAA,yCAMhC;CACD,MAAM,YAAA,GAAA,mBAAA,cAAwB;AAE9B,EAAA,GAAA,MAAA,iBAAgB;EAEd,MAAM,cAAA,GAAA,iBAAA,gBAA4B;AAClC,WAAS,SAAS,GAAG,yBAAyB,GAAG,WAAW,mBAAmB,OAAO,CAAC;EAGvF,MAAM,UAAU,WAAW,YAAY;EACvC,MAAM,gBAAgB,WAAW,kBAAkB;AAMnD,MAJE,SAAS,OACN,MAAM,KAAK,CACX,MAAM,QAAQ,IAAI,WAAW,GAAG,+BAA+B,GAAG,CAAC,EAClE,MAAM,IAAI,CAAC,OAAO,QACD;GAErB,MAAM,kBACJ,cAAc,UAAU,WAAW,IAAI;GACzC,IAAI,aAAa,WAAW,gBAC1B,CACE,WAAW,qBAAqB,GAC5B,WAAW,kBAAkB,gBAAgB,GAC7C,iBACJ,cACD,EACD,QACD;AACD,OAAI,WACF,cAAa,WAAW,mBAAmB,WAAW;AAGxD,OAAI,cAAc,QAAQ,SAAS,WAAW,IAAI,eAAe,QAAQ;AAEvE,aAAS,SAAS,GAAG,+BAA+B;AAGpD,kBAAc;;;IAGjB;EACD;EACA;EACA;EACA;EACA;EACD,CAAC;;AAGJ,SAAS,cACP,UACA,YACe;CACf,MAAM,UAAU,SAAS,MAAM,qBAAqB;AACpD,QAAO,UAAU,WAAW,mBAAmB,QAAQ,GAAG,GAAG"}
1
+ {"version":3,"file":"client-boundary.js","names":["compilePathRegex","GTProvider","defaultReferrerLocaleCookieName","defaultLocaleRoutingEnabledCookieName","pathnameMatchesRegex"],"sources":["../../src/utils/client-boundary.tsx"],"sourcesContent":["'use client';\n\n/**\n * This is a small boundary for RSC consumption of client components\n * Cannot be consumed through gt-react/index.rsc as deciding btwn\n * gt-react/index.server and gt-react/index.client can only happen\n * here. This matters for GTProvider, but not for LocaleSelector.\n * This pattern is just good to follow for carrying over different\n * behaviors between client and server from gt-react.\n */\n\nexport { LocaleSelector as Client_LocaleSelector } from 'gt-react';\nexport { RegionSelector as Client_RegionSelector } from 'gt-react';\n\nimport { getI18nConfig, I18nConfig } from 'gt-i18n/internal';\nimport { GTProvider, type SharedGTProviderProps } from 'gt-react';\nimport { usePathname, useRouter } from 'next/navigation';\nimport { useCallback, useEffect } from 'react';\nimport { initializeGTClient } from '../setup/initGT.client';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from './cookies';\nimport { compilePathRegex, pathnameMatchesRegex } from './pathRegex';\n\n// withGTConfig exposes this build-time value to both middleware and client code.\nconst pathRegex = compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);\n\n/**\n * Only need to initalize client. We know server was already\n * inialaized by index.rsc.ts. We do not know yet if client\n * has been initialized by index.client.ts.\n */\nif (typeof window !== 'undefined') {\n initializeGTClient();\n}\n\n/**\n * Small wrapper to embed nextjs app router behavior\n */\nexport function Client_GTProvider(props: SharedGTProviderProps) {\n const router = useRouter();\n const reload = useCallback(() => {\n // Reload server components\n router.refresh();\n }, [router]);\n // TODO: when routing is enabled, validate the path matches the locale\n usePathCheck({ reloadServer: reload, locale: props.locale });\n return <GTProvider {...props} _reload={reload} />;\n}\n\n/**\n * Reloads the server components if\n * TODO: optimize this hook\n */\nfunction usePathCheck({\n reloadServer,\n locale,\n referrerLocaleCookieName = defaultReferrerLocaleCookieName,\n localeRoutingEnabledCookieName = defaultLocaleRoutingEnabledCookieName,\n}: {\n reloadServer: () => void;\n locale: string;\n referrerLocaleCookieName?: string;\n localeRoutingEnabledCookieName?: string;\n}) {\n const pathname = usePathname();\n\n useEffect(() => {\n // Track the referrer locale for middleware\n const i18nConfig = getI18nConfig();\n document.cookie = `${referrerLocaleCookieName}=${i18nConfig.resolveAliasLocale(locale)};path=/`;\n\n // Reload the server components if the pathname changes\n const locales = i18nConfig.getLocales();\n const defaultLocale = i18nConfig.getDefaultLocale();\n const middlewareEnabled =\n document.cookie\n .split('; ')\n .find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))\n ?.split('=')[1] === 'true';\n if (middlewareEnabled && pathnameMatchesRegex(pathname, pathRegex)) {\n // Extract locale from pathname\n const extractedLocale =\n extractLocale(pathname, i18nConfig) || defaultLocale;\n let pathLocale = i18nConfig.determineLocale(\n [\n i18nConfig.isGTServicesEnabled()\n ? i18nConfig.standardizeLocale(extractedLocale)\n : extractedLocale,\n defaultLocale,\n ],\n locales\n );\n if (pathLocale) {\n pathLocale = i18nConfig.resolveAliasLocale(pathLocale);\n }\n\n if (pathLocale && locales.includes(pathLocale) && pathLocale !== locale) {\n // clear cookie (avoids infinite loop when there is no middleware)\n document.cookie = `${localeRoutingEnabledCookieName}=;path=/`;\n\n // reload page\n reloadServer();\n }\n }\n }, [\n pathname,\n locale,\n referrerLocaleCookieName,\n localeRoutingEnabledCookieName,\n reloadServer,\n ]);\n}\n\nfunction extractLocale(\n pathname: string,\n i18nConfig: I18nConfig\n): string | null {\n const matches = pathname.match(/^\\/([^/]+)(?:\\/|$)/);\n return matches ? i18nConfig.resolveAliasLocale(matches[1]) : null;\n}\n"],"mappings":";;;;;;;;;;;;AA0BA,MAAM,YAAYA,wBAAAA,iBAAiB,QAAQ,IAAI,+BAA+B;;;;;;AAO9E,IAAI,OAAO,WAAW,YACpB,6BAAA,oBAAoB;;;;AAMtB,SAAgB,kBAAkB,OAA8B;CAC9D,MAAM,UAAA,GAAA,mBAAA,YAAoB;CAC1B,MAAM,UAAA,GAAA,MAAA,mBAA2B;AAE/B,SAAO,SAAS;IACf,CAAC,OAAO,CAAC;AAEZ,cAAa;EAAE,cAAc;EAAQ,QAAQ,MAAM;EAAQ,CAAC;AAC5D,QAAO,iBAAA,GAAA,kBAAA,KAACC,SAAAA,YAAD;EAAY,GAAI;EAAO,SAAS;EAAU,CAAA;;;;;;AAOnD,SAAS,aAAa,EACpB,cACA,QACA,2BAA2BC,sBAAAA,iCAC3B,iCAAiCC,sBAAAA,yCAMhC;CACD,MAAM,YAAA,GAAA,mBAAA,cAAwB;AAE9B,EAAA,GAAA,MAAA,iBAAgB;EAEd,MAAM,cAAA,GAAA,iBAAA,gBAA4B;AAClC,WAAS,SAAS,GAAG,yBAAyB,GAAG,WAAW,mBAAmB,OAAO,CAAC;EAGvF,MAAM,UAAU,WAAW,YAAY;EACvC,MAAM,gBAAgB,WAAW,kBAAkB;AAMnD,MAJE,SAAS,OACN,MAAM,KAAK,CACX,MAAM,QAAQ,IAAI,WAAW,GAAG,+BAA+B,GAAG,CAAC,EAClE,MAAM,IAAI,CAAC,OAAO,UACCC,wBAAAA,qBAAqB,UAAU,UAAU,EAAE;GAElE,MAAM,kBACJ,cAAc,UAAU,WAAW,IAAI;GACzC,IAAI,aAAa,WAAW,gBAC1B,CACE,WAAW,qBAAqB,GAC5B,WAAW,kBAAkB,gBAAgB,GAC7C,iBACJ,cACD,EACD,QACD;AACD,OAAI,WACF,cAAa,WAAW,mBAAmB,WAAW;AAGxD,OAAI,cAAc,QAAQ,SAAS,WAAW,IAAI,eAAe,QAAQ;AAEvE,aAAS,SAAS,GAAG,+BAA+B;AAGpD,kBAAc;;;IAGjB;EACD;EACA;EACA;EACA;EACA;EACD,CAAC;;AAGJ,SAAS,cACP,UACA,YACe;CACf,MAAM,UAAU,SAAS,MAAM,qBAAqB;AACpD,QAAO,UAAU,WAAW,mBAAmB,QAAQ,GAAG,GAAG"}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { defaultLocaleRoutingEnabledCookieName, defaultReferrerLocaleCookieName } from "./cookies.mjs";
3
+ import { compilePathRegex, pathnameMatchesRegex } from "./pathRegex.mjs";
3
4
  import { initializeGTClient } from "../setup/initGT.client.mjs";
4
5
  import { getI18nConfig } from "gt-i18n/internal";
5
6
  import { GTProvider, LocaleSelector as Client_LocaleSelector, RegionSelector as Client_RegionSelector } from "gt-react";
@@ -7,6 +8,7 @@ import { useCallback, useEffect } from "react";
7
8
  import { jsx } from "react/jsx-runtime";
8
9
  import { usePathname, useRouter } from "next/navigation.js";
9
10
  //#region src/utils/client-boundary.tsx
11
+ const pathRegex = compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);
10
12
  /**
11
13
  * Only need to initalize client. We know server was already
12
14
  * inialaized by index.rsc.ts. We do not know yet if client
@@ -41,7 +43,7 @@ function usePathCheck({ reloadServer, locale, referrerLocaleCookieName = default
41
43
  document.cookie = `${referrerLocaleCookieName}=${i18nConfig.resolveAliasLocale(locale)};path=/`;
42
44
  const locales = i18nConfig.getLocales();
43
45
  const defaultLocale = i18nConfig.getDefaultLocale();
44
- if (document.cookie.split("; ").find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))?.split("=")[1] === "true") {
46
+ if (document.cookie.split("; ").find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))?.split("=")[1] === "true" && pathnameMatchesRegex(pathname, pathRegex)) {
45
47
  const extractedLocale = extractLocale(pathname, i18nConfig) || defaultLocale;
46
48
  let pathLocale = i18nConfig.determineLocale([i18nConfig.isGTServicesEnabled() ? i18nConfig.standardizeLocale(extractedLocale) : extractedLocale, defaultLocale], locales);
47
49
  if (pathLocale) pathLocale = i18nConfig.resolveAliasLocale(pathLocale);
@@ -1 +1 @@
1
- {"version":3,"file":"client-boundary.mjs","names":[],"sources":["../../src/utils/client-boundary.tsx"],"sourcesContent":["'use client';\n\n/**\n * This is a small boundary for RSC consumption of client components\n * Cannot be consumed through gt-react/index.rsc as deciding btwn\n * gt-react/index.server and gt-react/index.client can only happen\n * here. This matters for GTProvider, but not for LocaleSelector.\n * This pattern is just good to follow for carrying over different\n * behaviors between client and server from gt-react.\n */\n\nexport { LocaleSelector as Client_LocaleSelector } from 'gt-react';\nexport { RegionSelector as Client_RegionSelector } from 'gt-react';\n\nimport { getI18nConfig, I18nConfig } from 'gt-i18n/internal';\nimport { GTProvider, type SharedGTProviderProps } from 'gt-react';\nimport { usePathname, useRouter } from 'next/navigation';\nimport { useCallback, useEffect } from 'react';\nimport { initializeGTClient } from '../setup/initGT.client';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from './cookies';\n\n/**\n * Only need to initalize client. We know server was already\n * inialaized by index.rsc.ts. We do not know yet if client\n * has been initialized by index.client.ts.\n */\nif (typeof window !== 'undefined') {\n initializeGTClient();\n}\n\n/**\n * Small wrapper to embed nextjs app router behavior\n */\nexport function Client_GTProvider(props: SharedGTProviderProps) {\n const router = useRouter();\n const reload = useCallback(() => {\n // Reload server components\n router.refresh();\n }, [router]);\n // TODO: when routing is enabled, validate the path matches the locale\n usePathCheck({ reloadServer: reload, locale: props.locale });\n return <GTProvider {...props} _reload={reload} />;\n}\n\n/**\n * Reloads the server components if\n * TODO: optimize this hook\n */\nfunction usePathCheck({\n reloadServer,\n locale,\n referrerLocaleCookieName = defaultReferrerLocaleCookieName,\n localeRoutingEnabledCookieName = defaultLocaleRoutingEnabledCookieName,\n}: {\n reloadServer: () => void;\n locale: string;\n referrerLocaleCookieName?: string;\n localeRoutingEnabledCookieName?: string;\n}) {\n const pathname = usePathname();\n\n useEffect(() => {\n // Track the referrer locale for middleware\n const i18nConfig = getI18nConfig();\n document.cookie = `${referrerLocaleCookieName}=${i18nConfig.resolveAliasLocale(locale)};path=/`;\n\n // Reload the server components if the pathname changes\n const locales = i18nConfig.getLocales();\n const defaultLocale = i18nConfig.getDefaultLocale();\n const middlewareEnabled =\n document.cookie\n .split('; ')\n .find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))\n ?.split('=')[1] === 'true';\n if (middlewareEnabled) {\n // Extract locale from pathname\n const extractedLocale =\n extractLocale(pathname, i18nConfig) || defaultLocale;\n let pathLocale = i18nConfig.determineLocale(\n [\n i18nConfig.isGTServicesEnabled()\n ? i18nConfig.standardizeLocale(extractedLocale)\n : extractedLocale,\n defaultLocale,\n ],\n locales\n );\n if (pathLocale) {\n pathLocale = i18nConfig.resolveAliasLocale(pathLocale);\n }\n\n if (pathLocale && locales.includes(pathLocale) && pathLocale !== locale) {\n // clear cookie (avoids infinite loop when there is no middleware)\n document.cookie = `${localeRoutingEnabledCookieName}=;path=/`;\n\n // reload page\n reloadServer();\n }\n }\n }, [\n pathname,\n locale,\n referrerLocaleCookieName,\n localeRoutingEnabledCookieName,\n reloadServer,\n ]);\n}\n\nfunction extractLocale(\n pathname: string,\n i18nConfig: I18nConfig\n): string | null {\n const matches = pathname.match(/^\\/([^/]+)(?:\\/|$)/);\n return matches ? i18nConfig.resolveAliasLocale(matches[1]) : null;\n}\n"],"mappings":";;;;;;;;;;;;;;AA6BA,IAAI,OAAO,WAAW,YACpB,qBAAoB;;;;AAMtB,SAAgB,kBAAkB,OAA8B;CAC9D,MAAM,SAAS,WAAW;CAC1B,MAAM,SAAS,kBAAkB;AAE/B,SAAO,SAAS;IACf,CAAC,OAAO,CAAC;AAEZ,cAAa;EAAE,cAAc;EAAQ,QAAQ,MAAM;EAAQ,CAAC;AAC5D,QAAO,oBAAC,YAAD;EAAY,GAAI;EAAO,SAAS;EAAU,CAAA;;;;;;AAOnD,SAAS,aAAa,EACpB,cACA,QACA,2BAA2B,iCAC3B,iCAAiC,yCAMhC;CACD,MAAM,WAAW,aAAa;AAE9B,iBAAgB;EAEd,MAAM,aAAa,eAAe;AAClC,WAAS,SAAS,GAAG,yBAAyB,GAAG,WAAW,mBAAmB,OAAO,CAAC;EAGvF,MAAM,UAAU,WAAW,YAAY;EACvC,MAAM,gBAAgB,WAAW,kBAAkB;AAMnD,MAJE,SAAS,OACN,MAAM,KAAK,CACX,MAAM,QAAQ,IAAI,WAAW,GAAG,+BAA+B,GAAG,CAAC,EAClE,MAAM,IAAI,CAAC,OAAO,QACD;GAErB,MAAM,kBACJ,cAAc,UAAU,WAAW,IAAI;GACzC,IAAI,aAAa,WAAW,gBAC1B,CACE,WAAW,qBAAqB,GAC5B,WAAW,kBAAkB,gBAAgB,GAC7C,iBACJ,cACD,EACD,QACD;AACD,OAAI,WACF,cAAa,WAAW,mBAAmB,WAAW;AAGxD,OAAI,cAAc,QAAQ,SAAS,WAAW,IAAI,eAAe,QAAQ;AAEvE,aAAS,SAAS,GAAG,+BAA+B;AAGpD,kBAAc;;;IAGjB;EACD;EACA;EACA;EACA;EACA;EACD,CAAC;;AAGJ,SAAS,cACP,UACA,YACe;CACf,MAAM,UAAU,SAAS,MAAM,qBAAqB;AACpD,QAAO,UAAU,WAAW,mBAAmB,QAAQ,GAAG,GAAG"}
1
+ {"version":3,"file":"client-boundary.mjs","names":[],"sources":["../../src/utils/client-boundary.tsx"],"sourcesContent":["'use client';\n\n/**\n * This is a small boundary for RSC consumption of client components\n * Cannot be consumed through gt-react/index.rsc as deciding btwn\n * gt-react/index.server and gt-react/index.client can only happen\n * here. This matters for GTProvider, but not for LocaleSelector.\n * This pattern is just good to follow for carrying over different\n * behaviors between client and server from gt-react.\n */\n\nexport { LocaleSelector as Client_LocaleSelector } from 'gt-react';\nexport { RegionSelector as Client_RegionSelector } from 'gt-react';\n\nimport { getI18nConfig, I18nConfig } from 'gt-i18n/internal';\nimport { GTProvider, type SharedGTProviderProps } from 'gt-react';\nimport { usePathname, useRouter } from 'next/navigation';\nimport { useCallback, useEffect } from 'react';\nimport { initializeGTClient } from '../setup/initGT.client';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from './cookies';\nimport { compilePathRegex, pathnameMatchesRegex } from './pathRegex';\n\n// withGTConfig exposes this build-time value to both middleware and client code.\nconst pathRegex = compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);\n\n/**\n * Only need to initalize client. We know server was already\n * inialaized by index.rsc.ts. We do not know yet if client\n * has been initialized by index.client.ts.\n */\nif (typeof window !== 'undefined') {\n initializeGTClient();\n}\n\n/**\n * Small wrapper to embed nextjs app router behavior\n */\nexport function Client_GTProvider(props: SharedGTProviderProps) {\n const router = useRouter();\n const reload = useCallback(() => {\n // Reload server components\n router.refresh();\n }, [router]);\n // TODO: when routing is enabled, validate the path matches the locale\n usePathCheck({ reloadServer: reload, locale: props.locale });\n return <GTProvider {...props} _reload={reload} />;\n}\n\n/**\n * Reloads the server components if\n * TODO: optimize this hook\n */\nfunction usePathCheck({\n reloadServer,\n locale,\n referrerLocaleCookieName = defaultReferrerLocaleCookieName,\n localeRoutingEnabledCookieName = defaultLocaleRoutingEnabledCookieName,\n}: {\n reloadServer: () => void;\n locale: string;\n referrerLocaleCookieName?: string;\n localeRoutingEnabledCookieName?: string;\n}) {\n const pathname = usePathname();\n\n useEffect(() => {\n // Track the referrer locale for middleware\n const i18nConfig = getI18nConfig();\n document.cookie = `${referrerLocaleCookieName}=${i18nConfig.resolveAliasLocale(locale)};path=/`;\n\n // Reload the server components if the pathname changes\n const locales = i18nConfig.getLocales();\n const defaultLocale = i18nConfig.getDefaultLocale();\n const middlewareEnabled =\n document.cookie\n .split('; ')\n .find((row) => row.startsWith(`${localeRoutingEnabledCookieName}=`))\n ?.split('=')[1] === 'true';\n if (middlewareEnabled && pathnameMatchesRegex(pathname, pathRegex)) {\n // Extract locale from pathname\n const extractedLocale =\n extractLocale(pathname, i18nConfig) || defaultLocale;\n let pathLocale = i18nConfig.determineLocale(\n [\n i18nConfig.isGTServicesEnabled()\n ? i18nConfig.standardizeLocale(extractedLocale)\n : extractedLocale,\n defaultLocale,\n ],\n locales\n );\n if (pathLocale) {\n pathLocale = i18nConfig.resolveAliasLocale(pathLocale);\n }\n\n if (pathLocale && locales.includes(pathLocale) && pathLocale !== locale) {\n // clear cookie (avoids infinite loop when there is no middleware)\n document.cookie = `${localeRoutingEnabledCookieName}=;path=/`;\n\n // reload page\n reloadServer();\n }\n }\n }, [\n pathname,\n locale,\n referrerLocaleCookieName,\n localeRoutingEnabledCookieName,\n reloadServer,\n ]);\n}\n\nfunction extractLocale(\n pathname: string,\n i18nConfig: I18nConfig\n): string | null {\n const matches = pathname.match(/^\\/([^/]+)(?:\\/|$)/);\n return matches ? i18nConfig.resolveAliasLocale(matches[1]) : null;\n}\n"],"mappings":";;;;;;;;;;AA0BA,MAAM,YAAY,iBAAiB,QAAQ,IAAI,+BAA+B;;;;;;AAO9E,IAAI,OAAO,WAAW,YACpB,qBAAoB;;;;AAMtB,SAAgB,kBAAkB,OAA8B;CAC9D,MAAM,SAAS,WAAW;CAC1B,MAAM,SAAS,kBAAkB;AAE/B,SAAO,SAAS;IACf,CAAC,OAAO,CAAC;AAEZ,cAAa;EAAE,cAAc;EAAQ,QAAQ,MAAM;EAAQ,CAAC;AAC5D,QAAO,oBAAC,YAAD;EAAY,GAAI;EAAO,SAAS;EAAU,CAAA;;;;;;AAOnD,SAAS,aAAa,EACpB,cACA,QACA,2BAA2B,iCAC3B,iCAAiC,yCAMhC;CACD,MAAM,WAAW,aAAa;AAE9B,iBAAgB;EAEd,MAAM,aAAa,eAAe;AAClC,WAAS,SAAS,GAAG,yBAAyB,GAAG,WAAW,mBAAmB,OAAO,CAAC;EAGvF,MAAM,UAAU,WAAW,YAAY;EACvC,MAAM,gBAAgB,WAAW,kBAAkB;AAMnD,MAJE,SAAS,OACN,MAAM,KAAK,CACX,MAAM,QAAQ,IAAI,WAAW,GAAG,+BAA+B,GAAG,CAAC,EAClE,MAAM,IAAI,CAAC,OAAO,UACC,qBAAqB,UAAU,UAAU,EAAE;GAElE,MAAM,kBACJ,cAAc,UAAU,WAAW,IAAI;GACzC,IAAI,aAAa,WAAW,gBAC1B,CACE,WAAW,qBAAqB,GAC5B,WAAW,kBAAkB,gBAAgB,GAC7C,iBACJ,cACD,EACD,QACD;AACD,OAAI,WACF,cAAa,WAAW,mBAAmB,WAAW;AAGxD,OAAI,cAAc,QAAQ,SAAS,WAAW,IAAI,eAAe,QAAQ;AAEvE,aAAS,SAAS,GAAG,+BAA+B;AAGpD,kBAAc;;;IAGjB;EACD;EACA;EACA;EACA;EACA;EACD,CAAC;;AAGJ,SAAS,cACP,UACA,YACe;CACf,MAAM,UAAU,SAAS,MAAM,qBAAqB;AACpD,QAAO,UAAU,WAAW,mBAAmB,QAAQ,GAAG,GAAG"}
@@ -0,0 +1,3 @@
1
+ export declare function compilePathRegex(pathRegex?: string): RegExp | undefined;
2
+ export declare function pathnameMatchesRegex(pathname: string, pathRegex?: RegExp): boolean;
3
+ //# sourceMappingURL=pathRegex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathRegex.d.ts","sourceRoot":"","sources":["../../src/utils/pathRegex.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQvE;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAET"}
@@ -0,0 +1,19 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_errors_createErrors = require("../errors/createErrors.js");
3
+ //#region src/utils/pathRegex.ts
4
+ function compilePathRegex(pathRegex) {
5
+ if (pathRegex === void 0) return void 0;
6
+ try {
7
+ return new RegExp(pathRegex);
8
+ } catch (error) {
9
+ throw new Error(require_errors_createErrors.createInvalidPathRegexError(pathRegex, error));
10
+ }
11
+ }
12
+ function pathnameMatchesRegex(pathname, pathRegex) {
13
+ return pathRegex?.test(pathname) ?? true;
14
+ }
15
+ //#endregion
16
+ exports.compilePathRegex = compilePathRegex;
17
+ exports.pathnameMatchesRegex = pathnameMatchesRegex;
18
+
19
+ //# sourceMappingURL=pathRegex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathRegex.js","names":["createInvalidPathRegexError"],"sources":["../../src/utils/pathRegex.ts"],"sourcesContent":["import { createInvalidPathRegexError } from '../errors/createErrors';\n\nexport function compilePathRegex(pathRegex?: string): RegExp | undefined {\n if (pathRegex === undefined) return undefined;\n\n try {\n return new RegExp(pathRegex);\n } catch (error) {\n throw new Error(createInvalidPathRegexError(pathRegex, error));\n }\n}\n\nexport function pathnameMatchesRegex(\n pathname: string,\n pathRegex?: RegExp\n): boolean {\n return pathRegex?.test(pathname) ?? true;\n}\n"],"mappings":";;;AAEA,SAAgB,iBAAiB,WAAwC;AACvE,KAAI,cAAc,KAAA,EAAW,QAAO,KAAA;AAEpC,KAAI;AACF,SAAO,IAAI,OAAO,UAAU;UACrB,OAAO;AACd,QAAM,IAAI,MAAMA,4BAAAA,4BAA4B,WAAW,MAAM,CAAC;;;AAIlE,SAAgB,qBACd,UACA,WACS;AACT,QAAO,WAAW,KAAK,SAAS,IAAI"}
@@ -0,0 +1,17 @@
1
+ import { createInvalidPathRegexError } from "../errors/createErrors.mjs";
2
+ //#region src/utils/pathRegex.ts
3
+ function compilePathRegex(pathRegex) {
4
+ if (pathRegex === void 0) return void 0;
5
+ try {
6
+ return new RegExp(pathRegex);
7
+ } catch (error) {
8
+ throw new Error(createInvalidPathRegexError(pathRegex, error));
9
+ }
10
+ }
11
+ function pathnameMatchesRegex(pathname, pathRegex) {
12
+ return pathRegex?.test(pathname) ?? true;
13
+ }
14
+ //#endregion
15
+ export { compilePathRegex, pathnameMatchesRegex };
16
+
17
+ //# sourceMappingURL=pathRegex.mjs.map