UNPKG

strapi-plugin-oembed

Version:
162 lines (161 loc) 4.21 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); const bootstrap = () => { }; const config = { default: {}, validator() { } }; const contentTypes = {}; const strapi = { name: "oembed" }; const pkgJson = { strapi }; const controller = ({ strapi: strapi2 }) => ({ async fetch(ctx) { ctx.body = await strapi2.plugin(pkgJson.strapi.name).service("oembed").fetch(ctx.request.query.url); } }); const controllers = { oembed: controller }; const destroy = () => { }; const middlewares = {}; const policies = {}; const register = ({ strapi: strapi2 }) => { strapi2.customFields.register({ name: "oembed", plugin: pkgJson.strapi.name, type: "json", inputSize: { default: 6, isResizable: true } }); }; const adminRoutes = [ { method: "GET", path: "/fetch", handler: "oembed.fetch", config: { policies: [] } } ]; const routes = { admin: { type: "admin", routes: adminRoutes } }; const service = () => ({ async fetch(url) { const { extract } = await import("@extractus/oembed-extractor"); try { new URL(url); } catch { return { error: "The URL is invalid." }; } try { const rawOembed = await extract(url); const oembed = await this.postprocess(rawOembed); const thumbnail = await this.generateThumbnail(oembed); return { url, oembed, thumbnail }; } catch (error) { if (error.response.status === 404) { return { error: "This URL can't be found" }; } else if (error.response.status === 401) { return { error: "Embedding has been disabled for this media" }; } else { throw new Error(error); } } }, postprocess(oembed) { if (oembed.provider_name === "YouTube") { return this.postprocessYouTube(oembed); } return oembed; }, /** * YouTube offers high resolution images */ postprocessYouTube(oembed) { const thumbnailUrl = oembed.thumbnail_url; if (!thumbnailUrl) { return null; } oembed.thumbnail_url = oembed.thumbnail_url.substring(0, thumbnailUrl.lastIndexOf("/") + 1) + "maxresdefault.jpg"; return oembed; }, /** * For cookie privacy, download the thumbnail and store as an inline image. * This also gets around CSP issues. */ async generateThumbnail(oembed) { const thumbnailUrl = oembed.thumbnail_url; if (!thumbnailUrl) { return null; } return await this.generateBase64FromUrl(thumbnailUrl); }, async generateBase64FromUrl(url) { const response = await fetch(url); const buffer = await response.arrayBuffer(); const string = Buffer.from(buffer).toString("base64"); const contentType = response.headers.get("content-type"); return `data:${contentType};base64,${string}`; } }); const services = { oembed: service }; const index = { register, bootstrap, destroy, config, controllers, routes, services, contentTypes, policies, middlewares }; module.exports = index;