strapi-plugin-website-builder-v5
Version:
V5 port of https://market.strapi.io/plugins/strapi-plugin-website-builder
341 lines (340 loc) • 10.4 kB
JavaScript
"use strict";
const strapi = require("@strapi/strapi");
const axios = require("axios");
const defu = require("defu");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
const axios__default = /* @__PURE__ */ _interopDefault(axios);
const defu__default = /* @__PURE__ */ _interopDefault(defu);
const PLUGIN_ID = "strapi-plugin-website-builder-v5";
const FILE_UID = "plugin::upload.file";
const LOG_UID = `plugin::${PLUGIN_ID}.log`;
const EMIT_ACTIONS = ["create", "update", "delete", "publish", "unpublish"];
function getService({ strapi: strapi2, name, plugin = PLUGIN_ID }) {
return strapi2.plugin(plugin).service(name);
}
async function resolveValue({ value, args }) {
if (typeof value === "function") {
return await value(args);
}
return value;
}
function bootstrapCron({ strapi: strapi2, build: build2 }) {
strapi2.cron.add({
[build2.name]: {
options: {
rule: build2.trigger.expression
},
task: () => {
getService({ strapi: strapi2, name: "build" }).trigger({ name: build2.name, trigger: { type: "cron" } });
}
}
});
}
function bootstrapEvents({ strapi: strapi2, build: build2 }) {
const events = /* @__PURE__ */ new Map();
build2.trigger.events.forEach((event) => {
let actions = /* @__PURE__ */ new Set();
if (event.actions === "*") {
EMIT_ACTIONS.forEach((action) => actions.add(action));
} else {
event.actions.forEach((action) => actions.add(action));
}
if (event.uid === "*") {
Object.keys(strapi2.contentTypes).filter((uid) => /^api::/.test(uid) || uid === FILE_UID).forEach((uid) => {
events.set(uid, actions);
});
} else {
events.set(event.uid, actions);
}
});
EMIT_ACTIONS.forEach((action) => {
strapi2.eventHub.on(`entry.${action}`, ({ uid, entry: record }) => {
const entry = events.get(uid);
if (entry && entry.has(action)) {
getService({ strapi: strapi2, name: "build" }).trigger({
name: build2.name,
record,
trigger: { type: "event" }
});
}
});
});
}
const bootstrap = ({ strapi: strapi2 }) => {
const builds = getService({ strapi: strapi2, name: "settings" }).get({ path: "builds", defaultValue: [] });
builds.filter((b) => b.enabled || typeof b.enabled === "undefined").forEach((build2) => {
if (build2.trigger.type === "cron") {
bootstrapCron({ strapi: strapi2, build: build2 });
} else if (build2.trigger.type === "event") {
bootstrapEvents({ strapi: strapi2, build: build2 });
}
strapi2.log.info(`[website builder] ${build2.trigger.type} trigger enabled for ${build2.name} build`);
});
};
const destroy = ({ strapi: strapi2 }) => {
};
const register = ({ strapi: strapi2 }) => {
};
const yup = require("yup");
const pluginConfigSchema = yup.object({
shared: yup.object(),
hooks: yup.object(),
builds: yup.array().of(
yup.object({
enabled: yup.bool(),
name: yup.string().required("A build name must be provided"),
url: yup.string().required("A URL is required"),
trigger: yup.object({
type: yup.string().oneOf(["manual", "cron", "event"]).required("A trigger type is required"),
expression: yup.lazy((_value, { parent }) => {
return parent?.type === "cron" ? yup.string().required("A cron expression must be entered") : yup.string().notRequired();
}),
events: yup.lazy((_value, { parent }) => {
if (parent?.type === "event") {
return yup.array().of(
yup.object({
uid: yup.string().required("A uid is required"),
actions: yup.mixed().test({
name: "actions",
exclusive: true,
message: "${path} must be a string or valid actions",
test: async (value) => {
if (typeof value === "string") return true;
const isValid = await yup.array().of(
yup.string().oneOf(["create", "update", "delete", "publish", "unpublish"])
).required("uid actions are required").isValid(value);
return isValid;
}
})
})
).min(1, "At least one event must be provided").required("events is required");
} else {
return yup.mixed().notRequired();
}
})
}).required("A trigger is required"),
method: yup.mixed().oneOf(["GET", "POST"]).optional(),
params: yup.mixed().test({
name: "params",
exclusive: true,
message: "${path} must be an object or function",
test: async (value) => typeof value === "function" || await yup.object().isValid(value)
}),
headers: yup.mixed().test({
name: "headers",
exclusive: true,
message: "${path} must be an object or function",
test: async (value) => typeof value === "function" || await yup.object().isValid(value)
}),
body: yup.mixed().test({
name: "body",
exclusive: true,
message: "${path} must be an object or function",
test: async (value) => typeof value === "function" || await yup.object().isValid(value)
})
})
)
}).required("A config is required");
const config = {
default: {},
validator: async (config2) => await pluginConfigSchema.validate(config2)
};
const contentTypes = {
log: {
schema: {
kind: "collectionType",
collectionName: "logs",
info: {
singularName: "log",
pluralName: "logs",
displayName: "logs"
},
pluginOptions: {
"content-manager": {
visible: false
},
"content-type-builder": {
visible: false
}
},
options: {
draftAndPublish: false
},
attributes: {
status: {
type: "integer"
},
build: {
type: "string"
},
trigger: {
type: "string"
},
method: {
type: "string"
},
response: {
type: "json"
}
}
}
}
};
const controller = ({ strapi: strapi2 }) => ({
/**
* Trigger a website build
*
* @return {Object}
*/
async trigger(ctx) {
try {
const { status } = await getService({ strapi: strapi2, name: "build" }).trigger({
name: ctx.request.body.data.name,
trigger: { type: "manual" }
});
ctx.send({ data: { status } });
} catch (error) {
ctx.badRequest();
}
},
/**
* Get all builds
*
* @return {Object}
*/
async find(ctx) {
ctx.send({ data: getService({ strapi: strapi2, name: "settings" }).get({ path: "builds" }) });
}
});
const log$1 = strapi.factories.createCoreController(LOG_UID);
const controllers = {
build: controller,
log: log$1
};
const middlewares = {};
const policies = {};
const buildAPIRoutes = [
{
method: "POST",
path: "/builds",
handler: "build.trigger"
},
{
method: "GET",
path: "/builds",
handler: "build.find"
}
];
const logAPIRoutes = [
{
method: "GET",
path: "/logs",
handler: "log.find"
},
{
method: "DELETE",
path: "/logs/:id",
handler: "log.delete"
}
];
const routes = {
"admin": {
type: "admin",
routes: [...buildAPIRoutes, ...logAPIRoutes]
}
};
const build = ({ strapi: strapi2 }) => ({
async trigger({ name, record, trigger }) {
let log2 = { trigger: trigger.type, status: 500, build: name, response: null };
try {
const request2 = await getService({ strapi: strapi2, name: "request" }).build({
name,
record,
trigger
});
const response = await getService({ strapi: strapi2, name: "request" }).execute(request2);
console.log("here", response);
log2.status = response.status;
log2.response = response.data;
} catch (error) {
console.log("error", error);
if (error.response) {
log2.status = error.response.status;
} else if (error.request) {
log2.response = {};
} else {
log2.response = error.message;
}
}
getService({ strapi: strapi2, name: "log" }).create({ data: log2 });
return { status: log2.status };
}
});
const log = strapi.factories.createCoreService(LOG_UID);
const settings = ({ strapi: strapi2 }) => ({
get({ path, defaultValue } = { path: "" }) {
if (path.length) {
path = `.${path}`;
}
return strapi2.config.get(`plugin::${PLUGIN_ID}${path}`, defaultValue);
},
set({ path = "", value }) {
return strapi2.config.set(`plugin::${PLUGIN_ID}${path}`, value);
}
});
const request = ({ strapi: strapi2 }) => ({
async build({ name, record, trigger }) {
let request2 = {};
const { shared, builds } = getService({ strapi: strapi2, name: "settings" }).get();
const build2 = builds.find((b) => b.name === name);
if (!build2) {
return;
}
request2.method = build2.method || "POST";
request2.url = build2.url;
if (build2.body) {
request2.data = await resolveValue({ value: build2.body, args: { record, trigger } });
}
if (shared?.params) {
request2.params = await resolveValue({ value: shared.params, args: { record, trigger } });
}
if (build2.params) {
const paramsValue = await resolveValue({ value: build2.params, args: { record, trigger } });
request2.params = defu__default.default(paramsValue, request2.params || {});
}
if (shared?.headers) {
request2.headers = await resolveValue({ value: shared.headers, args: { record, trigger } });
}
if (build2.headers) {
const headerValue = await resolveValue({ value: build2.headers, args: { record, trigger } });
request2.headers = defu__default.default(headerValue, request2.headers || {});
}
return request2;
},
async execute(request2) {
const hooks = getService({ strapi: strapi2, name: "settings" }).get({ path: "hooks" });
if (hooks?.beforeRequest) {
axios__default.default.interceptors.request.use(hooks.beforeRequest);
}
return axios__default.default(request2);
}
});
const services = {
build,
log,
settings,
request
};
const index = {
register,
bootstrap,
destroy,
config,
controllers,
routes,
services,
contentTypes,
policies,
middlewares
};
module.exports = index;