strapi-plugin-oembed
Version:
Embed content from third-party sites in Strapi
162 lines (161 loc) • 4.21 kB
JavaScript
;
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;