{"version":3,"file":"index.mjs","sources":["../../server/src/bootstrap.ts","../../server/src/register.ts","../../server/src/services/image-hotspot.ts","../../server/src/services/index.ts","../../server/src/index.ts"],"sourcesContent":["import type { Core } from \"@strapi/strapi\";\n\nconst bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {\n  strapi.server.use(async (ctx, next) => {\n    if (!ctx.path?.startsWith(\"/api\")) {\n      return next();\n    }\n\n    await next();\n\n    try {\n      const imageHotspotService = strapi\n        .plugin(\"image-hotspot\")\n        .service(\"image-hotspot\");\n\n      const contentTypeUid = imageHotspotService.getContentTypeUid(ctx);\n\n      if (!contentTypeUid) {\n        return;\n      }\n\n      ctx.body = await imageHotspotService.processResponseBody(\n        ctx.body,\n        contentTypeUid,\n      );\n    } catch (error) {\n      strapi.log.error(\n        `Error populating image field for ${ctx.state?.contentTypeUid || \"unknown\"}:`,\n        error,\n      );\n    }\n  });\n};\n\nexport default bootstrap;\n","import type { Core } from \"@strapi/strapi\";\n\nconst register = ({ strapi }: { strapi: Core.Strapi }) => {\n  // Register image-hotspot custom field on the server side\n\n  strapi.customFields.register({\n    name: \"image-hotspot\",\n    plugin: \"image-hotspot\",\n    type: \"json\",\n    inputSize: {\n      default: 12,\n      isResizable: true,\n    },\n  });\n};\n\nexport default register;\n","import type { Core } from \"@strapi/strapi\";\n\nconst IMAGE_HOTSPOT_CUSTOM_FIELD = \"plugin::image-hotspot.image-hotspot\";\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n  getContentTypeUid(ctx: any): string | null {\n    if (ctx.state?.contentTypeUid) {\n      return ctx.state.contentTypeUid;\n    }\n\n    const pathMatch = ctx.path?.match(/\\/api\\/([^\\/]+)/);\n    if (pathMatch) {\n      const apiName = pathMatch[1];\n      const singularName = apiName.replace(/s$/, \"\");\n      return `api::${singularName}.${singularName}`;\n    }\n\n    return null;\n  },\n\n  getImageHotspotAttributes(contentType: any): Record<string, any> {\n    if (!contentType?.attributes) {\n      return {};\n    }\n\n    return Object.keys(contentType.attributes).reduce(\n      (acc, key) => {\n        const attribute = contentType.attributes[key];\n        if (\n          attribute?.type === \"json\" &&\n          attribute?.customField === IMAGE_HOTSPOT_CUSTOM_FIELD\n        ) {\n          acc[key] = attribute;\n        }\n        return acc;\n      },\n      {} as Record<string, any>,\n    );\n  },\n\n  async populateImageField(\n    entity: any,\n    contentTypeUid: string,\n    strapi: Core.Strapi,\n  ): Promise<any> {\n    if (!entity || typeof entity !== \"object\") {\n      return entity;\n    }\n\n    const contentType = strapi.contentTypes[contentTypeUid];\n    if (!contentType) {\n      strapi.log.warn(\n        `Content type ${contentTypeUid} not found, skipping image population`,\n      );\n      return entity;\n    }\n\n    const customFieldAttributes = this.getImageHotspotAttributes(contentType);\n\n    if (Object.keys(customFieldAttributes).length === 0) {\n      return entity;\n    }\n\n    await Promise.all(\n      Object.keys(customFieldAttributes).map(async (key) => {\n        const imageId = entity[key]?.image;\n        if (imageId) {\n          try {\n            const media = await strapi\n              .documents(\"plugin::upload.file\")\n              .findOne({ documentId: imageId });\n            if (media) {\n              entity[key].image = media;\n            } else {\n              entity[key] = null;\n            }\n          } catch (error) {\n            strapi.log.warn(\n              `Failed to fetch media for ${contentTypeUid}.${key}:`,\n              error,\n            );\n          }\n        }\n      }),\n    );\n\n    return entity;\n  },\n  async processResponseBody(body: any, contentTypeUid: string): Promise<any> {\n    if (!body) {\n      return body;\n    }\n\n    if (body.data !== undefined) {\n      if (Array.isArray(body.data)) {\n        body.data = await Promise.all(\n          body.data.map((item: any) =>\n            this.populateImageField(item, contentTypeUid, strapi),\n          ),\n        );\n      } else {\n        body.data = await this.populateImageField(\n          body.data,\n          contentTypeUid,\n          strapi,\n        );\n      }\n    } else if (Array.isArray(body)) {\n      body = await Promise.all(\n        body.map((item: any) =>\n          this.populateImageField(item, contentTypeUid, strapi),\n        ),\n      );\n    } else if (typeof body === \"object\") {\n      body = await this.populateImageField(body, contentTypeUid, strapi);\n    }\n\n    return body;\n  },\n});\n","import imageHotspot from \"./image-hotspot\";\n\nexport default {\n  \"image-hotspot\": imageHotspot,\n};\n","/**\n * Application methods\n */\nimport bootstrap from \"./bootstrap\";\nimport register from \"./register\";\n\n/**\n * Plugin server methods\n */\nimport services from \"./services\";\n\nexport default {\n  register,\n  bootstrap,\n  services,\n};\n"],"names":["strapi"],"mappings":"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"}