feat: add custom widget flow workbench
This commit is contained in:
1 parent
c32a5317ca
commit
a6bdbbb4ea
259 files changed
+23875
-1293
No files matched your search
@@ -0,0 +1,44 @@
|
||||
/** Keep public schema metadata honest. Full runtime validation also runs in
|
||||
* Homarr's shared validator before publication, preview, and installation. */
|
||||
const validateSubmissionSchema = (record) => {
|
||||
if (record.getString("type") === "customCss") {
|
||||
if (record.getString("widgetSchema") !== "homarr-custom-css-v1") {
|
||||
throw new BadRequestError("CSS submission schema does not match its type");
|
||||
}
|
||||
return;
|
||||
}
|
||||
let widget;
|
||||
try {
|
||||
widget = JSON.parse(record.getString("content"));
|
||||
} catch {
|
||||
throw new BadRequestError("Widget content must be JSON");
|
||||
}
|
||||
if (!widget || typeof widget !== "object" || Array.isArray(widget)) {
|
||||
throw new BadRequestError("Widget content must be an object");
|
||||
}
|
||||
if (widget.$schema !== "homarr-custom-widget-v2" && widget.$schema !== "homarr-custom-widget-v3") {
|
||||
throw new BadRequestError("Unsupported widget schema");
|
||||
}
|
||||
if (widget.$schema !== record.getString("widgetSchema")) {
|
||||
throw new BadRequestError("Widget schema metadata must match its content");
|
||||
}
|
||||
if (widget.$schema === "homarr-custom-widget-v2" && widget.extensions !== undefined) {
|
||||
throw new BadRequestError("Widget extensions require homarr-custom-widget-v3");
|
||||
}
|
||||
const allowedFields = [
|
||||
"$schema",
|
||||
"name",
|
||||
"description",
|
||||
"iconUrl",
|
||||
"sources",
|
||||
"requests",
|
||||
"options",
|
||||
"template",
|
||||
"extensions",
|
||||
];
|
||||
if (Object.keys(widget).some((key) => !allowedFields.includes(key))) {
|
||||
throw new BadRequestError("Widget content contains unsupported fields");
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { validateSubmissionSchema };
|
||||
@@ -58,6 +58,8 @@ routerAdd("GET", "/workshop/{id}", workshopDetailPage);
|
||||
routerAdd("GET", "/workshop/{id}/{$}", workshopDetailPage);
|
||||
|
||||
onRecordCreateRequest((event) => {
|
||||
const { validateSubmissionSchema } = require(`${__hooks}/workshop-content.js`);
|
||||
validateSubmissionSchema(event.record);
|
||||
event.record.set("revision", 1);
|
||||
event.record.set("expectedRevision", 0);
|
||||
event.record.set("changelog", "");
|
||||
@@ -68,6 +70,13 @@ onRecordCreateRequest((event) => {
|
||||
onRecordUpdateRequest((event) => {
|
||||
const { rejectRequest } = require(`${__hooks}/workshop-utils.js`);
|
||||
const original = event.record.original();
|
||||
if (
|
||||
original.getString("content") !== event.record.getString("content") ||
|
||||
original.getString("widgetSchema") !== event.record.getString("widgetSchema")
|
||||
) {
|
||||
const { validateSubmissionSchema } = require(`${__hooks}/workshop-content.js`);
|
||||
validateSubmissionSchema(event.record);
|
||||
}
|
||||
const currentRevision = original.getInt("revision");
|
||||
const expectedRevision = event.record.getInt("expectedRevision");
|
||||
if (!Number.isSafeInteger(expectedRevision) || expectedRevision < 1) {
|
||||
|
||||
Reference in new issue
Block a user