{"version":3,"file":"buildBrowserConfiguration.mjs","names":[],"sources":["../../../src/configFile/buildBrowserConfiguration.ts"],"sourcesContent":["import type {\n  CustomIntlayerConfig,\n  CustomRoutingConfig,\n  EditorConfig,\n  InternationalizationConfig,\n  IntlayerConfig,\n  LogConfig,\n  LogFunctions,\n  RoutingConfig,\n} from '@intlayer/types/config';\nimport {\n  APPLICATION_URL,\n  BACKEND_URL,\n  CMS_URL,\n  DICTIONARY_PRIORITY_STRATEGY,\n  EDITOR_URL,\n  IS_ENABLED,\n  LIVE_SYNC,\n  LIVE_SYNC_PORT,\n  PORT,\n} from '../defaultValues/editor';\nimport {\n  DEFAULT_LOCALE,\n  LOCALES,\n  REQUIRED_LOCALES,\n  STRICT_MODE,\n} from '../defaultValues/internationalization';\nimport { MODE, PREFIX } from '../defaultValues/log';\nimport { BASE_PATH, ROUTING_MODE, STORAGE } from '../defaultValues/routing';\nimport { getStorageAttributes } from '../utils/getStorageAttributes';\n\n// ---------------------------------------------------------------------------\n// Type\n// ---------------------------------------------------------------------------\n\n/**\n * Browser-safe subset of {@link IntlayerConfig}.\n *\n * Excludes server-only fields (`system`, `content`, `build`, `compiler`,\n * `dictionary`, `ai`) and sensitive editor credentials (`clientId`,\n * `clientSecret`) that must never be shipped to the browser.\n */\nexport type BrowserIntlayerConfig = {\n  internationalization: Pick<\n    InternationalizationConfig,\n    'locales' | 'defaultLocale'\n  >;\n  routing: RoutingConfig;\n  editor: Omit<EditorConfig, 'clientId' | 'clientSecret'>;\n  log: Pick<LogConfig, 'mode' | 'prefix'>;\n};\n\ndeclare global {\n  interface Window {\n    /** Browser-safe Intlayer configuration injected by a build plugin or `installIntlayer`. */\n    INTLAYER_CONFIG?: BrowserIntlayerConfig;\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Shared field builders (browser-safe — no Node.js APIs)\n//\n// These functions are re-used by both `buildBrowserConfiguration` (browser)\n// and `buildConfigurationFields` (server) to avoid duplication.\n// ---------------------------------------------------------------------------\n\n/**\n * Build the internationalization section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied internationalization config.\n * @returns A fully-defaulted {@link InternationalizationConfig}.\n */\nexport const buildInternationalizationFields = (\n  customConfiguration?: Partial<InternationalizationConfig>\n): InternationalizationConfig => ({\n  /**\n   * Locales available in the application\n   *\n   * Default: ['en']\n   *\n   */\n  locales: customConfiguration?.locales ?? LOCALES,\n\n  /**\n   * Locales required by TypeScript to ensure strong implementations of internationalized content using typescript.\n   *\n   * Default: []\n   *\n   * If empty, all locales are required in `strict` mode.\n   *\n   * Ensure required locales are also defined in the `locales` field.\n   */\n  requiredLocales:\n    customConfiguration?.requiredLocales ??\n    customConfiguration?.locales ??\n    REQUIRED_LOCALES,\n\n  /**\n   * Ensure strong implementations of internationalized content using typescript.\n   * - If set to \"strict\", the translation `t` function will require each declared locales to be defined. If one locale is missing, or if a locale is not declared in your config, it will throw an error.\n   * - If set to \"inclusive\", the translation `t` function will require each declared locales to be defined. If one locale is missing, it will throw a warning. But will accept if a locale is not declared in your config, but exist.\n   * - If set to \"loose\", the translation `t` function will accept any existing locale.\n   *\n   * Default: \"inclusive\"\n   */\n  strictMode: customConfiguration?.strictMode ?? STRICT_MODE,\n\n  /**\n   * Default locale of the application for fallback\n   *\n   * Default: 'en'\n   */\n  defaultLocale: customConfiguration?.defaultLocale ?? DEFAULT_LOCALE,\n});\n\n/**\n * Build the routing section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied routing config.\n * @returns A fully-defaulted {@link RoutingConfig}.\n */\nexport const buildRoutingFields = (\n  customConfiguration?: Partial<CustomRoutingConfig>\n): RoutingConfig => {\n  const storage = customConfiguration?.storage ?? STORAGE;\n\n  return {\n    /**\n     * URL routing mode for locale handling\n     *\n     * Controls how locales are represented in application URLs:\n     * - 'prefix-no-default': Prefix all locales except the default locale (default)\n     *    - en → /dashboard\n     *    - fr → /fr/dashboard\n     *\n     * - 'prefix-all': Prefix all locales including the default locale\n     *    - en → /en/dashboard\n     *    - fr → /fr/dashboard\n     *\n     * - 'search-params': Use search parameters for locale handling\n     *    - en → /dashboard?locale=en\n     *    - fr → /fr/dashboard?locale=fr\n     *\n     * - 'no-prefix': No locale prefixing in URLs\n     *    - en → /dashboard\n     *    - fr → /dashboard\n     *\n     * Default: 'prefix-no-default'\n     */\n    mode: customConfiguration?.mode ?? ROUTING_MODE,\n\n    /**\n     * Configuration for storing the locale in the client (localStorage or sessionStorage)\n     *\n     * If false, the locale will not be stored by the middleware.\n     * If true, the locale storage will consider all default values. (cookie and header)\n     *\n     * Default: ['cookie', 'header']\n     *\n     */\n    storage: getStorageAttributes(storage),\n\n    /**\n     * Base path of the application URL\n     *\n     * Default: ''\n     *\n     * Example:\n     * - If the application is hosted at https://example.com/my-app\n     * - The base path is '/my-app'\n     * - The URL will be https://example.com/my-app/en\n     * - If the base path is not set, the URL will be https://example.com/en\n     */\n    basePath: customConfiguration?.basePath ?? BASE_PATH,\n\n    /**\n     * Custom URL rewriting rules that override the default routing mode for specific paths.\n     * Allows you to define locale-specific paths that differ from the standard routing behavior.\n     * Supports dynamic route parameters using `[param]` syntax.\n     *\n     * Default: undefined\n     *\n     * Example:\n     * ```typescript\n     * rewrite: {\n     *   \"/about\": {\n     *     en: \"/about\",\n     *     fr: \"/a-propos\",\n     *   },\n     *   \"/product/[slug]\": {\n     *     en: \"/product/[slug]\",\n     *     fr: \"/produit/[slug]\",\n     *   },\n     * }\n     * ```\n     *\n     * Note:\n     * - The rewrite rules take precedence over the default `mode` behavior.\n     * - If a path matches a rewrite rule, the localized path from the rewrite configuration will be used.\n     * - Dynamic route parameters are supported using bracket notation (e.g., `[slug]`, `[id]`).\n     * - Works with both Next.js and Vite applications.\n     */\n    rewrite: customConfiguration?.rewrite,\n\n    /**\n     * Maps locales to specific domain hostnames for domain-based routing.\n     *\n     * Default: undefined\n     */\n    domains: customConfiguration?.domains,\n  };\n};\n\n/**\n * Build the editor section of the Intlayer configuration.\n *\n * Returns the **full** {@link EditorConfig} including sensitive fields\n * (`clientId`, `clientSecret`). The browser-safe {@link BrowserIntlayerConfig}\n * omits those fields when exposing config to the client.\n *\n * @param customConfiguration - Partial user-supplied editor config.\n * @returns A fully-defaulted {@link EditorConfig}.\n */\nexport const buildEditorFields = (\n  customConfiguration?: Partial<EditorConfig>\n): EditorConfig => {\n  const liveSyncPort = customConfiguration?.liveSyncPort ?? LIVE_SYNC_PORT;\n  return {\n    /**\n     * URL of the application. Used to restrict the origin of the editor for security reasons.\n     *\n     * > '*' means that the editor is accessible from any origin\n     *\n     * Default: '*'\n     */\n    applicationURL: customConfiguration?.applicationURL || APPLICATION_URL,\n\n    /**\n     * URL of the editor server. Used to restrict the origin of the editor for security reasons.\n     *\n     * > '*' means that the editor is accessible from any origin\n     *\n     * Default: '*'\n     */\n    editorURL: customConfiguration?.editorURL || EDITOR_URL,\n\n    /**\n     * URL of the CMS server. Used to restrict the origin of the editor for security reasons.\n     */\n    cmsURL: customConfiguration?.cmsURL || CMS_URL,\n\n    /**\n     * URL of the editor server\n     *\n     * Default: 'https://back.intlayer.org'\n     */\n    backendURL: customConfiguration?.backendURL || BACKEND_URL,\n\n    /** Port of the editor server\n     *\n     * Default: 8000\n     */\n    port: customConfiguration?.port ?? PORT,\n\n    /**\n     * Indicates if the application interact with the visual editor\n     *\n     * Default: false;\n     *\n     * If true, the editor will be able to interact with the application.\n     * If false, the editor will not be able to interact with the application.\n     * In any case, the editor can only be enabled by the visual editor.\n     * Disabling the editor for specific environments is a way to enforce the security.\n     *\n     * Usage:\n     * ```js\n     * {\n     *  // Other configurations\n     *  editor: {\n     *   enabled: process.env.NODE_ENV !== 'production',\n     *  }\n     * };\n     * ```\n     */\n    enabled: customConfiguration?.enabled ?? IS_ENABLED,\n\n    /**\n     * clientId and clientSecret allow the intlayer packages to authenticate with the backend using oAuth2 authentication.\n     * An access token is use to authenticate the user related to the project.\n     * To get an access token, go to https://app.intlayer.org/project and create an account.\n     *\n     * Default: undefined\n     *\n     * > Important: The clientId and clientSecret should be kept secret and not shared publicly. Please ensure to keep them in a secure location, such as environment variables.\n     */\n    clientId: customConfiguration?.clientId ?? undefined,\n\n    /**\n     * clientId and clientSecret allow the intlayer packages to authenticate with the backend using oAuth2 authentication.\n     * An access token is use to authenticate the user related to the project.\n     * To get an access token, go to https://app.intlayer.org/project and create an account.\n     *\n     * Default: undefined\n     *\n     * > Important: The clientId and clientSecret should be kept secret and not shared publicly. Please ensure to keep them in a secure location, such as environment variables.\n     */\n    clientSecret: customConfiguration?.clientSecret ?? undefined,\n\n    /**\n     * Strategy for prioritizing dictionaries. If a dictionary is both present online and locally, the content will be merge.\n     * However, is a field is defined in both dictionary, this setting determines which fields takes the priority over the other.\n     *\n     * Default: 'local_first'\n     *\n     * The strategy for prioritizing dictionaries. It can be either 'local_first' or 'distant_first'.\n     * - 'local_first': The first dictionary found in the locale is used.\n     * - 'distant_first': The first dictionary found in the distant locales is used.\n     */\n    dictionaryPriorityStrategy:\n      customConfiguration?.dictionaryPriorityStrategy ??\n      DICTIONARY_PRIORITY_STRATEGY,\n\n    /**\n     * Indicates if the application should hot reload the locale configurations when a change is detected.\n     * For example, when a new dictionary is added or updated, the application will update the content tu display in the page.\n     *\n     * The hot reload is only available for clients of the `enterprise` plan.\n     *\n     * Default: false\n     */\n    liveSync: customConfiguration?.liveSync ?? LIVE_SYNC,\n\n    /**\n     * Port of the live sync server\n     *\n     * Default: 4000\n     */\n    liveSyncPort,\n\n    /**\n     * URL of the live sync server in case of remote live sync server\n     *\n     * Default: `http://localhost:${LIVE_SYNC_PORT}`\n     */\n    liveSyncURL:\n      customConfiguration?.liveSyncURL ?? `http://localhost:${liveSyncPort}`,\n  };\n};\n\n/**\n * Build the log section of the Intlayer configuration.\n *\n * @param customConfiguration - Partial user-supplied log config.\n * @param logFunctions - Optional custom log function overrides (server-only).\n * @returns A fully-defaulted {@link LogConfig}.\n */\nexport const buildLogFields = (\n  customConfiguration?: Partial<LogConfig>,\n  logFunctions?: LogFunctions\n): LogConfig => ({\n  /**\n   * Indicates if the logger is enabled\n   *\n   * Default: 'prefix-no-default'\n   *\n   * If 'default', the logger is enabled and can be used.\n   * If 'verbose', the logger will be enabled and can be used, but will log more information.\n   * If 'disabled', the logger is disabled and cannot be used.\n   */\n  mode: customConfiguration?.mode ?? MODE,\n\n  /**\n   * Prefix of the logger\n   *\n   * Default: '[intlayer]'\n   *\n   * The prefix of the logger.\n   */\n  prefix: customConfiguration?.prefix ?? PREFIX,\n\n  /**\n   * Functions to log\n   */\n  error: logFunctions?.error,\n  log: logFunctions?.log,\n  info: logFunctions?.info,\n  warn: logFunctions?.warn,\n});\n\n// ---------------------------------------------------------------------------\n// Browser configuration builders\n// ---------------------------------------------------------------------------\n\n/**\n * Build a browser-safe {@link BrowserIntlayerConfig} from a raw user config.\n *\n * Applies defaults for every field and strips all server-only or sensitive\n * information (`system`, `content`, `build`, `compiler`, `dictionary`, `ai`,\n * `editor.clientId`, `editor.clientSecret`).\n *\n * This is the browser counterpart of `buildConfigurationFields`. It is safe\n * to call in browser environments because it has no Node.js dependencies.\n *\n * @param customConfig - Optional partial user-supplied Intlayer config.\n * @returns A browser-safe configuration object ready for `window.INTLAYER_CONFIG`.\n *\n * @example\n * ```ts\n * import { buildBrowserConfiguration } from '@intlayer/config/client';\n *\n * window.INTLAYER_CONFIG = buildBrowserConfiguration({\n *   internationalization: { locales: ['en', 'fr'], defaultLocale: 'en' },\n * });\n * ```\n */\nexport const buildBrowserConfiguration = (\n  customConfig?: CustomIntlayerConfig\n): BrowserIntlayerConfig => {\n  const { locales, defaultLocale } = buildInternationalizationFields(\n    customConfig?.internationalization\n  );\n  const routing = buildRoutingFields(customConfig?.routing);\n  const {\n    clientId: _clientId,\n    clientSecret: _clientSecret,\n    ...editorPublic\n  } = buildEditorFields(customConfig?.editor);\n  const { mode, prefix } = buildLogFields(customConfig?.log);\n\n  return {\n    internationalization: { locales, defaultLocale },\n    routing,\n    editor: editorPublic,\n    log: { mode, prefix },\n  };\n};\n\n/**\n * Extract a {@link BrowserIntlayerConfig} from an already-built full\n * {@link IntlayerConfig}.\n *\n * Used by build plugins (`vite-intlayer`, `withIntlayer`) which already hold\n * the full server-side config and need to inject the browser-safe subset at\n * compile time via a bundler `define`.\n *\n * @param config - A fully-built server-side Intlayer configuration.\n * @returns The browser-safe subset of that configuration.\n */\nexport const extractBrowserConfiguration = (\n  config: IntlayerConfig\n): BrowserIntlayerConfig => ({\n  internationalization: {\n    locales: config.internationalization.locales,\n    defaultLocale: config.internationalization.defaultLocale,\n  },\n  routing: {\n    mode: config.routing.mode,\n    storage: config.routing.storage,\n    basePath: config.routing.basePath,\n    rewrite: config.routing.rewrite,\n  },\n  editor: {\n    applicationURL: config.editor.applicationURL,\n    editorURL: config.editor.editorURL,\n    cmsURL: config.editor.cmsURL,\n    backendURL: config.editor.backendURL,\n    port: config.editor.port,\n    enabled: config.editor.enabled,\n    dictionaryPriorityStrategy: config.editor.dictionaryPriorityStrategy,\n    liveSync: config.editor.liveSync,\n    liveSyncPort: config.editor.liveSyncPort,\n    liveSyncURL: config.editor.liveSyncURL,\n  },\n  log: {\n    mode: config.log.mode,\n    prefix: config.log.prefix,\n  },\n});\n"],"mappings":";;;;;;;;;;;;;AAwEA,MAAa,mCACX,yBACgC;;;;;;;CAOhC,SAAS,qBAAqB,WAAW;;;;;;;;;;CAWzC,iBACE,qBAAqB,mBACrB,qBAAqB,WACrB;;;;;;;;;CAUF,YAAY,qBAAqB;;;;;;CAOjC,eAAe,qBAAqB;CACrC;;;;;;;AAQD,MAAa,sBACX,wBACkB;CAClB,MAAM,UAAU,qBAAqB,WAAW;AAEhD,QAAO;;;;;;;;;;;;;;;;;;;;;;;EAuBL,MAAM,qBAAqB;;;;;;;;;;EAW3B,SAAS,qBAAqB,QAAQ;;;;;;;;;;;;EAatC,UAAU,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6B/B,SAAS,qBAAqB;;;;;;EAO9B,SAAS,qBAAqB;EAC/B;;;;;;;;;;;;AAaH,MAAa,qBACX,wBACiB;CACjB,MAAM,eAAe,qBAAqB;AAC1C,QAAO;;;;;;;;EAQL,gBAAgB,qBAAqB;;;;;;;;EASrC,WAAW,qBAAqB;;;;EAKhC,QAAQ,qBAAqB;;;;;;EAO7B,YAAY,qBAAqB;;;;;EAMjC,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;EAsB3B,SAAS,qBAAqB;;;;;;;;;;EAW9B,UAAU,qBAAqB,YAAY;;;;;;;;;;EAW3C,cAAc,qBAAqB,gBAAgB;;;;;;;;;;;EAYnD,4BACE,qBAAqB;;;;;;;;;EAWvB,UAAU,qBAAqB;;;;;;EAO/B;;;;;;EAOA,aACE,qBAAqB,eAAe,oBAAoB;EAC3D;;;;;;;;;AAUH,MAAa,kBACX,qBACA,kBACe;;;;;;;;;;CAUf,MAAM,qBAAqB;;;;;;;;CAS3B,QAAQ,qBAAqB,UAAU;;;;CAKvC,OAAO,cAAc;CACrB,KAAK,cAAc;CACnB,MAAM,cAAc;CACpB,MAAM,cAAc;CACrB;;;;;;;;;;;;;;;;;;;;;;;AA4BD,MAAa,6BACX,iBAC0B;CAC1B,MAAM,EAAE,SAAS,kBAAkB,gCACjC,cAAc,qBACf;CACD,MAAM,UAAU,mBAAmB,cAAc,QAAQ;CACzD,MAAM,EACJ,UAAU,WACV,cAAc,eACd,GAAG,iBACD,kBAAkB,cAAc,OAAO;CAC3C,MAAM,EAAE,MAAM,WAAW,eAAe,cAAc,IAAI;AAE1D,QAAO;EACL,sBAAsB;GAAE;GAAS;GAAe;EAChD;EACA,QAAQ;EACR,KAAK;GAAE;GAAM;GAAQ;EACtB;;;;;;;;;;;;;AAcH,MAAa,+BACX,YAC2B;CAC3B,sBAAsB;EACpB,SAAS,OAAO,qBAAqB;EACrC,eAAe,OAAO,qBAAqB;EAC5C;CACD,SAAS;EACP,MAAM,OAAO,QAAQ;EACrB,SAAS,OAAO,QAAQ;EACxB,UAAU,OAAO,QAAQ;EACzB,SAAS,OAAO,QAAQ;EACzB;CACD,QAAQ;EACN,gBAAgB,OAAO,OAAO;EAC9B,WAAW,OAAO,OAAO;EACzB,QAAQ,OAAO,OAAO;EACtB,YAAY,OAAO,OAAO;EAC1B,MAAM,OAAO,OAAO;EACpB,SAAS,OAAO,OAAO;EACvB,4BAA4B,OAAO,OAAO;EAC1C,UAAU,OAAO,OAAO;EACxB,cAAc,OAAO,OAAO;EAC5B,aAAa,OAAO,OAAO;EAC5B;CACD,KAAK;EACH,MAAM,OAAO,IAAI;EACjB,QAAQ,OAAO,IAAI;EACpB;CACF"}