{"version":3,"file":"content-source-maps.mjs","sources":["../../src/services/content-source-maps.ts"],"sourcesContent":["import { vercelStegaCombine } from '@vercel/stega';\nimport type { Core, Struct, UID } from '@strapi/types';\nimport { traverseEntity } from '@strapi/utils';\nimport type { FieldContentSourceMap } from '@strapi/admin/strapi-admin';\n\nconst ENCODABLE_TYPES = [\n  'string',\n  'text',\n  'richtext',\n  'biginteger',\n  'date',\n  'time',\n  'datetime',\n  'timestamp',\n  'boolean',\n  'enumeration',\n  'json',\n  'media',\n  'email',\n  'password',\n  /**\n   * We cannot modify the response shape, so types that aren't based on string cannot be encoded:\n   * - json: object\n   * - blocks: object, will require a custom implementation in a dedicated PR\n   * - integer, float and decimal: number\n   * - boolean: boolean (believe it or not)\n   * - uid: can be stringified but would mess up URLs\n   */\n];\n\n// TODO: use a centralized store for these fields that would be shared with the CM and CTB\nconst EXCLUDED_FIELDS = [\n  'id',\n  'documentId',\n  'locale',\n  'localizations',\n  'created_by',\n  'updated_by',\n  'created_at',\n  'updated_at',\n  'publishedAt',\n];\n\ninterface EncodingInfo {\n  data: any;\n  schema: Struct.Schema;\n}\n\nconst isObject = (value: unknown): value is Record<string, any> => {\n  return typeof value === 'object' && value !== null;\n};\n\nconst createContentSourceMapsService = (strapi: Core.Strapi) => {\n  return {\n    encodeField(\n      text: string,\n      { kind, model, documentId, type, path, locale }: FieldContentSourceMap\n    ) {\n      /**\n       * Combine all metadata into into a one string so we only have to deal with one data-atribute\n       * on the frontend. Make it human readable because that data-attribute may be set manually by\n       * users for fields that don't support sourcemap encoding.\n       */\n      const strapiSource = new URLSearchParams();\n      strapiSource.set('documentId', documentId);\n      strapiSource.set('type', type);\n      strapiSource.set('path', path);\n\n      if (model) {\n        strapiSource.set('model', model);\n      }\n      if (kind) {\n        strapiSource.set('kind', kind);\n      }\n      if (locale) {\n        strapiSource.set('locale', locale);\n      }\n\n      const encoded = vercelStegaCombine(\n        text,\n        {\n          strapiSource: strapiSource.toString(),\n        },\n        false\n      );\n\n      return encoded;\n    },\n\n    async encodeEntry({ data, schema }: EncodingInfo): Promise<any> {\n      if (!isObject(data) || data === undefined) {\n        return data;\n      }\n\n      return traverseEntity(\n        ({ key, value, attribute, schema, path, parent }, { set }) => {\n          if (!attribute || EXCLUDED_FIELDS.includes(key)) {\n            return;\n          }\n\n          if (ENCODABLE_TYPES.includes(attribute.type) && typeof value === 'string') {\n            // For inner fields of a multi-media field's items (e.g. `medias.0.url`),\n            // drop the array index so all items share the same encoded path. The\n            // preview groups them under one highlight and opens the multi-media\n            // input as a single field, matching the side editor.\n            const parentAttr = parent?.attribute;\n            const isInsideMultiMedia =\n              parentAttr?.type === 'media' && (parentAttr as any).multiple === true;\n            const encodedPath =\n              isInsideMultiMedia && parent?.path?.rawWithIndices\n                ? `${parent.path.rawWithIndices}.${key}`\n                : path.rawWithIndices!;\n\n            set(\n              key,\n              this.encodeField(value, {\n                path: encodedPath,\n                type: attribute.type,\n                kind: schema.kind,\n                model: schema.uid as UID.Schema,\n                locale: data.locale,\n                documentId: data.documentId,\n              }) as any\n            );\n          }\n        },\n        {\n          schema,\n          getModel: (uid) => strapi.getModel(uid as UID.Schema),\n        },\n        data\n      );\n    },\n\n    async encodeSourceMaps({ data, schema }: EncodingInfo): Promise<any> {\n      try {\n        if (Array.isArray(data)) {\n          return await Promise.all(\n            data.map((item) => this.encodeSourceMaps({ data: item, schema }))\n          );\n        }\n\n        if (!isObject(data)) {\n          return data;\n        }\n\n        return await this.encodeEntry({ data, schema });\n      } catch (error) {\n        strapi.log.error('Error encoding source maps:', error);\n        return data;\n      }\n    },\n  };\n};\n\nexport { createContentSourceMapsService };\n"],"names":["ENCODABLE_TYPES","EXCLUDED_FIELDS","isObject","value","createContentSourceMapsService","strapi","encodeField","text","kind","model","documentId","type","path","locale","strapiSource","URLSearchParams","set","encoded","vercelStegaCombine","toString","encodeEntry","data","schema","undefined","traverseEntity","key","attribute","parent","includes","parentAttr","isInsideMultiMedia","multiple","encodedPath","rawWithIndices","uid","getModel","encodeSourceMaps","Array","isArray","Promise","all","map","item","error","log"],"mappings":";;;AAKA,MAAMA,eAAAA,GAAkB;AACtB,IAAA,QAAA;AACA,IAAA,MAAA;AACA,IAAA,UAAA;AACA,IAAA,YAAA;AACA,IAAA,MAAA;AACA,IAAA,MAAA;AACA,IAAA,UAAA;AACA,IAAA,WAAA;AACA,IAAA,SAAA;AACA,IAAA,aAAA;AACA,IAAA,MAAA;AACA,IAAA,OAAA;AACA,IAAA,OAAA;AACA,IAAA;AASD,CAAA;AAED;AACA,MAAMC,eAAAA,GAAkB;AACtB,IAAA,IAAA;AACA,IAAA,YAAA;AACA,IAAA,QAAA;AACA,IAAA,eAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA;AACD,CAAA;AAOD,MAAMC,WAAW,CAACC,KAAAA,GAAAA;IAChB,OAAO,OAAOA,KAAAA,KAAU,QAAA,IAAYA,KAAAA,KAAU,IAAA;AAChD,CAAA;AAEA,MAAMC,iCAAiC,CAACC,MAAAA,GAAAA;IACtC,OAAO;AACLC,QAAAA,WAAAA,CAAAA,CACEC,IAAY,EACZ,EAAEC,IAAI,EAAEC,KAAK,EAAEC,UAAU,EAAEC,IAAI,EAAEC,IAAI,EAAEC,MAAM,EAAyB,EAAA;AAEtE;;;;UAKA,MAAMC,eAAe,IAAIC,eAAAA,EAAAA;YACzBD,YAAAA,CAAaE,GAAG,CAAC,YAAA,EAAcN,UAAAA,CAAAA;YAC/BI,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQL,IAAAA,CAAAA;YACzBG,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQJ,IAAAA,CAAAA;AAEzB,YAAA,IAAIH,KAAAA,EAAO;gBACTK,YAAAA,CAAaE,GAAG,CAAC,OAAA,EAASP,KAAAA,CAAAA;AAC5B,YAAA;AACA,YAAA,IAAID,IAAAA,EAAM;gBACRM,YAAAA,CAAaE,GAAG,CAAC,MAAA,EAAQR,IAAAA,CAAAA;AAC3B,YAAA;AACA,YAAA,IAAIK,MAAAA,EAAQ;gBACVC,YAAAA,CAAaE,GAAG,CAAC,QAAA,EAAUH,MAAAA,CAAAA;AAC7B,YAAA;YAEA,MAAMI,OAAAA,GAAUC,mBACdX,IAAAA,EACA;AACEO,gBAAAA,YAAAA,EAAcA,aAAaK,QAAQ;aACrC,EACA,KAAA,CAAA;YAGF,OAAOF,OAAAA;AACT,QAAA,CAAA;AAEA,QAAA,MAAMG,WAAAA,CAAAA,CAAY,EAAEC,IAAI,EAAEC,MAAM,EAAgB,EAAA;AAC9C,YAAA,IAAI,CAACpB,QAAAA,CAASmB,IAAAA,CAAAA,IAASA,IAAAA,KAASE,SAAAA,EAAW;gBACzC,OAAOF,IAAAA;AACT,YAAA;AAEA,YAAA,OAAOG,eACL,CAAC,EAAEC,GAAG,EAAEtB,KAAK,EAAEuB,SAAS,EAAEJ,MAAM,EAAEV,IAAI,EAAEe,MAAM,EAAE,EAAE,EAAEX,GAAG,EAAE,GAAA;AACvD,gBAAA,IAAI,CAACU,SAAAA,IAAazB,eAAAA,CAAgB2B,QAAQ,CAACH,GAAAA,CAAAA,EAAM;AAC/C,oBAAA;AACF,gBAAA;gBAEA,IAAIzB,eAAAA,CAAgB4B,QAAQ,CAACF,SAAAA,CAAUf,IAAI,CAAA,IAAK,OAAOR,UAAU,QAAA,EAAU;;;;;AAKzE,oBAAA,MAAM0B,aAAaF,MAAAA,EAAQD,SAAAA;AAC3B,oBAAA,MAAMI,qBACJD,UAAAA,EAAYlB,IAAAA,KAAS,WAAW,UAACkB,CAAmBE,QAAQ,KAAK,IAAA;AACnE,oBAAA,MAAMC,cACJF,kBAAAA,IAAsBH,MAAAA,EAAQf,IAAAA,EAAMqB,cAAAA,GAChC,GAAGN,MAAAA,CAAOf,IAAI,CAACqB,cAAc,CAAC,CAAC,EAAER,GAAAA,CAAAA,CAAK,GACtCb,KAAKqB,cAAc;AAEzBjB,oBAAAA,GAAAA,CACES,GAAAA,EACA,IAAI,CAACnB,WAAW,CAACH,KAAAA,EAAO;wBACtBS,IAAAA,EAAMoB,WAAAA;AACNrB,wBAAAA,IAAAA,EAAMe,UAAUf,IAAI;AACpBH,wBAAAA,IAAAA,EAAMc,OAAOd,IAAI;AACjBC,wBAAAA,KAAAA,EAAOa,OAAOY,GAAG;AACjBrB,wBAAAA,MAAAA,EAAQQ,KAAKR,MAAM;AACnBH,wBAAAA,UAAAA,EAAYW,KAAKX;AACnB,qBAAA,CAAA,CAAA;AAEJ,gBAAA;YACF,CAAA,EACA;AACEY,gBAAAA,MAAAA;AACAa,gBAAAA,QAAAA,EAAU,CAACD,GAAAA,GAAQ7B,MAAAA,CAAO8B,QAAQ,CAACD,GAAAA;aACrC,EACAb,IAAAA,CAAAA;AAEJ,QAAA,CAAA;AAEA,QAAA,MAAMe,gBAAAA,CAAAA,CAAiB,EAAEf,IAAI,EAAEC,MAAM,EAAgB,EAAA;YACnD,IAAI;gBACF,IAAIe,KAAAA,CAAMC,OAAO,CAACjB,IAAAA,CAAAA,EAAO;AACvB,oBAAA,OAAO,MAAMkB,OAAAA,CAAQC,GAAG,CACtBnB,IAAAA,CAAKoB,GAAG,CAAC,CAACC,IAAAA,GAAS,IAAI,CAACN,gBAAgB,CAAC;4BAAEf,IAAAA,EAAMqB,IAAAA;AAAMpB,4BAAAA;AAAO,yBAAA,CAAA,CAAA,CAAA;AAElE,gBAAA;gBAEA,IAAI,CAACpB,SAASmB,IAAAA,CAAAA,EAAO;oBACnB,OAAOA,IAAAA;AACT,gBAAA;AAEA,gBAAA,OAAO,MAAM,IAAI,CAACD,WAAW,CAAC;AAAEC,oBAAAA,IAAAA;AAAMC,oBAAAA;AAAO,iBAAA,CAAA;AAC/C,YAAA,CAAA,CAAE,OAAOqB,KAAAA,EAAO;AACdtC,gBAAAA,MAAAA,CAAOuC,GAAG,CAACD,KAAK,CAAC,6BAAA,EAA+BA,KAAAA,CAAAA;gBAChD,OAAOtB,IAAAA;AACT,YAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}