{"version":3,"file":"syncJSON.cjs","names":["parseFilePathPattern","buildFilePathPatternContext","createSyncPlugin","createFileAdapter","jsonCodec","readJSONEntry"],"sources":["../../src/syncJSON.ts"],"sourcesContent":["import { parseFilePathPattern } from '@intlayer/config/utils';\nimport {\n  buildFilePathPatternContext,\n  createFileAdapter,\n  createSyncPlugin,\n  type SplitKeysMode,\n} from '@intlayer/engine/syncPluginKit';\nimport type {\n  DictionaryFormat,\n  DictionaryLocation,\n} from '@intlayer/types/dictionary';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport type { Plugin } from '@intlayer/types/plugin';\nimport { jsonCodec, readJSONEntry } from './jsonCodec';\n\n// Re-exported for backward compatibility: this helper used to live here.\nexport { extractKeyAndLocaleFromPath } from '@intlayer/engine/syncPluginKit';\n\nexport type SyncJSONPluginOptions = {\n  /**\n   * The source of the plugin.\n   * Is a function to build the source from the key and locale.\n   *\n   * ```ts\n   * syncJSON({\n   * source: ({ key, locale }) => `./messages/${locale}/${key}.json`\n   * })\n   * ```\n   */\n  source: FilePathPattern;\n\n  /**\n   * Because Intlayer transform the JSON files into Dictionary, we need to identify the plugin in the dictionary.\n   * Used to identify the plugin in the dictionary.\n   *\n   * In the case you have multiple plugins, you can use this to identify the plugin in the dictionary.\n   *\n   * ```ts\n   * // Example usage:\n   * const config = {\n   *   plugins: [\n   *     syncJSON({\n   *       source: ({ key, locale }) => `./resources/${locale}/${key}.json`,\n   *       location: 'plugin-i18next',\n   *     }),\n   *     syncJSON({\n   *       source: ({ key, locale }) => `./messages/${locale}/${key}.json`,\n   *       location: 'plugin-next-intl',\n   *     }),\n   *   ]\n   * }\n   * ```\n   */\n  location?: DictionaryLocation | (string & {});\n\n  /**\n   * The priority of the dictionaries created by the plugin.\n   *\n   * In the case of conflicts with remote dictionaries, or .content files, the dictionary with the highest priority will override the other dictionaries.\n   *\n   * Default is -1. (.content file priority is 0)\n   *\n   */\n  priority?: number;\n\n  /**\n   * The format of the dictionaries created by the plugin.\n   *\n   * Default: 'intlayer'\n   *\n   * The format of the dictionaries created by the plugin.\n   */\n  format?: DictionaryFormat;\n\n  /**\n   * Whether each top-level key of the JSON file should become its own\n   * dictionary (keyed by that top-level key) instead of a single dictionary\n   * holding the whole file.\n   *\n   * This matches the namespace model of libraries such as `next-intl` /\n   * `react-intl`, where a single `messages/{locale}.json` file groups several\n   * namespaces by its first-level keys and each namespace is addressed\n   * independently (e.g. `useTranslations('Hero')` → dictionary `Hero`).\n   *\n   * Pass `'key-prefix'` for *flat* catalogs whose keys are dotted ids rather\n   * than nested objects — the single-catalog model of `lingui` and of\n   * i18next's default `translation` namespace. Each id's first dot-segment\n   * becomes a dictionary and the remainder becomes the key inside it, so\n   * `'footer.github'` is addressed as dictionary `footer`, key `github`.\n   * Write-back restores the flat dotted ids, leaving the source file in the\n   * shape its library expects.\n   *\n   * When omitted, it is auto-detected: the file is split when the `source`\n   * pattern has no `{{key}}` segment (i.e. one file holds every namespace),\n   * and kept as a single dictionary otherwise (one file per key).\n   *\n   * @example\n   * ```ts\n   * // messages/en.json → dictionaries: Hero, Nav, About, …\n   * syncJSON({\n   *   source: ({ locale }) => `./messages/${locale}.json`,\n   *   splitKeys: true,\n   * })\n   *\n   * // locales/en/messages.json → { 'footer.github': …, 'hero.title': … }\n   * //   → dictionaries: footer, hero, …\n   * syncJSON({\n   *   source: ({ locale }) => `./locales/${locale}/messages.json`,\n   *   splitKeys: 'key-prefix',\n   * })\n   * ```\n   */\n  splitKeys?: SplitKeysMode;\n};\n\n/**\n * Two-way JSON synchronization plugin: ingests JSON message files as\n * dictionaries and writes the merged build output back to the same files.\n */\nexport const syncJSON = async (\n  options: SyncJSONPluginOptions\n): Promise<Plugin> => {\n  // Generate a unique default location based on the source pattern.\n  // This ensures that if you have multiple plugins, they don't share the same 'plugin' ID.\n  const patternMarker = await parseFilePathPattern(\n    options.source,\n    buildFilePathPatternContext('{{key}}', '{{locale}}')\n  );\n  const defaultLocation = `sync-json::${patternMarker}`;\n\n  return createSyncPlugin({\n    name: 'sync-json',\n    adapter: createFileAdapter({\n      source: options.source,\n      codec: jsonCodec,\n      readEntry: readJSONEntry,\n      discovery: 'strict',\n    }),\n    direction: 'both',\n    location: options.location ?? defaultLocation,\n    priority: options.priority ?? 0,\n    format: options.format,\n    // Auto-detected by the file adapter when omitted: split when the source\n    // pattern has no `{{key}}` segment (one file holds every namespace).\n    splitKeys: options.splitKeys,\n  });\n};\n"],"mappings":";;;;;;;;;;AAuHA,MAAa,WAAW,OACtB,YACoB;CAOpB,MAAM,kBAAkB,cAAc,UAJVA,6CAC1B,QAAQ,YACRC,4DAA4B,WAAW,YAAY,CACrD;CAGA,WAAOC,iDAAiB;EACtB,MAAM;EACN,aAASC,kDAAkB;GACzB,QAAQ,QAAQ;GAChB,OAAOC;GACP,WAAWC;GACX,WAAW;EACb,CAAC;EACD,WAAW;EACX,UAAU,QAAQ,YAAY;EAC9B,UAAU,QAAQ,YAAY;EAC9B,QAAQ,QAAQ;EAGhB,WAAW,QAAQ;CACrB,CAAC;AACH"}