@premieroctet/next-admin
Version:
Next-Admin provides a customizable and turnkey admin dashboard for applications built with Next.js and powered by the Prisma ORM. It aims to simplify the development process by providing a turnkey admin system that can be easily integrated into your proje
280 lines (279 loc) • 11.2 kB
JavaScript
"use strict";
var __webpack_require__ = {};
(()=>{
__webpack_require__.d = (exports1, definition)=>{
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
enumerable: true,
get: definition[key]
});
};
})();
(()=>{
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
__webpack_require__.r = (exports1)=>{
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
value: 'Module'
});
Object.defineProperty(exports1, '__esModule', {
value: true
});
};
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
createHandler: ()=>createHandler
});
const external_next_connect_namespaceObject = require("next-connect");
const HookError_js_namespaceObject = require("./exceptions/HookError.js");
const options_js_namespaceObject = require("./handlers/options.js");
const resources_js_namespaceObject = require("./handlers/resources.js");
const external_types_js_namespaceObject = require("./types.js");
const permissions_js_namespaceObject = require("./utils/permissions.js");
const prisma_js_namespaceObject = require("./utils/prisma.js");
const server_js_namespaceObject = require("./utils/server.js");
const globals_js_namespaceObject = require("./utils/globals.js");
const createHandler = ({ apiBasePath, options, prisma, paramKey = "nextadmin", onRequest })=>{
const router = (0, external_next_connect_namespaceObject.createEdgeRouter)();
router.use(async (req, res, next)=>{
await (0, globals_js_namespaceObject.initGlobals)();
return next();
});
if (onRequest) router.use(async (req, ctxPromise, next)=>{
const ctx = await ctxPromise;
const response = await onRequest(req, ctx);
if (response) return response;
return next();
});
router.get(`${apiBasePath}/:model/raw`, async (req, ctx)=>{
const resources = (0, server_js_namespaceObject.getResources)(options);
const params = await ctx.params;
const resource = (0, server_js_namespaceObject.getResourceFromParams)(params[paramKey], resources);
if (!resource) return Response.json({
error: "Resource not found"
}, {
status: 404
});
const searchParams = new URL(req.url).searchParams;
const ids = searchParams.get("ids")?.split(",").map((id)=>(0, server_js_namespaceObject.formatId)(resource, id));
const depth = searchParams.get("depth");
if (!ids) return Response.json({
error: "No ids provided"
}, {
status: 400
});
if (depth && isNaN(Number(depth))) return Response.json({
error: "Depth should be a number"
}, {
status: 400
});
const data = await (0, prisma_js_namespaceObject.getRawData)({
prisma,
resource,
resourceIds: ids,
maxDepth: depth ? Number(depth) : void 0
});
return Response.json(data);
}).post(`${apiBasePath}/:model/actions/:id`, async (req, ctx)=>{
const resources = (0, server_js_namespaceObject.getResources)(options);
const params = await ctx.params;
const id = params[paramKey].at(-1);
const resource = (0, server_js_namespaceObject.getResourceFromParams)([
params[paramKey][0]
], resources);
if (!resource) return Response.json({
type: "error",
message: "Resource not found"
}, {
status: 404
});
const modelAction = options?.model?.[resource]?.actions?.find((action)=>action.id === id);
if (!modelAction) return Response.json({
type: "error",
message: "Action not found"
}, {
status: 404
});
if ("type" in modelAction && "dialog" === modelAction.type) return Response.json({
type: "error",
message: "Action not found"
}, {
status: 404
});
const body = await req.json();
try {
const result = await modelAction.action(body);
return Response.json(result ?? null);
} catch (e) {
return Response.json({
type: "error",
message: e.message
}, {
status: 500
});
}
}).post(`${apiBasePath}/options`, async (req, _ctx)=>{
const body = await req.json();
const data = await (0, options_js_namespaceObject.handleOptionsSearch)(body, prisma, options);
return Response.json(data);
}).post(`${apiBasePath}/:model/order`, async (req, ctx)=>{
const resources = (0, server_js_namespaceObject.getResources)(options);
const body = await req.json();
const params = await ctx.params;
const resource = (0, server_js_namespaceObject.getResourceFromParams)(params[paramKey], resources);
const optimisticData = body;
if (!resource) return Response.json({
error: "Resource not found"
}, {
status: 404
});
if (!resource) return Response.json({
error: "Resource not found"
}, {
status: 404
});
const resourceIdField = (0, server_js_namespaceObject.getModelIdProperty)(resource);
const orderField = options?.model?.[resource]?.list?.orderField;
if (!orderField) return Response.json({
error: "Order field not found"
}, {
status: 404
});
await prisma.$transaction(async (tx)=>{
for (const item of optimisticData)await tx[resource].update({
where: {
[resourceIdField]: item[resourceIdField].value
},
data: {
[orderField]: item[orderField].value
}
});
});
return Response.json({
ok: true
});
}).post(`${apiBasePath}/:model/:id?`, async (req, ctx)=>{
const resources = (0, server_js_namespaceObject.getResources)(options);
const params = await ctx.params;
const resource = (0, server_js_namespaceObject.getResourceFromParams)(params[paramKey], resources);
if (!resource) return Response.json({
error: "Resource not found"
}, {
status: 404
});
const body = await (0, server_js_namespaceObject.getFormValuesFromFormData)(await req.formData(), options?.model?.[resource]?.edit?.fields);
const id = 2 === params[paramKey].length ? (0, server_js_namespaceObject.formatId)(resource, params[paramKey].at(-1)) : void 0;
const editOptions = options?.model?.[resource]?.edit;
const mode = id ? "edit" : "create";
try {
const transformedBody = await editOptions?.hooks?.beforeDb?.(body, mode, req);
let response = await (0, resources_js_namespaceObject.submitResource)({
prisma,
resource,
body: transformedBody ?? body,
id,
options,
schema: (0, globals_js_namespaceObject.getSchema)()
});
if (response.error) return Response.json({
error: response.error,
validation: response.validation
}, {
status: 400
});
response = await editOptions?.hooks?.afterDb?.(response, mode, req) ?? response;
return Response.json(response, {
status: id ? 200 : 201
});
} catch (e) {
if (e instanceof HookError_js_namespaceObject.HookError) return Response.json(e.data, {
status: e.status
});
return Response.json({
error: e.message
}, {
status: 500
});
}
}).delete(`${apiBasePath}/:model/:id`, async (req, ctx)=>{
const resources = (0, server_js_namespaceObject.getResources)(options);
const params = await ctx.params;
const resource = (0, server_js_namespaceObject.getResourceFromParams)(params[paramKey], resources);
if (!resource) return Response.json({
error: "Resource not found"
}, {
status: 404
});
if (!(0, permissions_js_namespaceObject.hasPermission)(options?.model?.[resource], external_types_js_namespaceObject.Permission.DELETE)) return Response.json({
error: "You don't have permission to delete this resource"
}, {
status: 403
});
try {
const deleted = await (0, resources_js_namespaceObject.deleteResource)({
body: [
params[paramKey][1]
],
prisma,
resource,
modelOptions: options?.model?.[resource]
});
if (!deleted) throw new Error("Deletion failed");
return Response.json({
ok: true
});
} catch (e) {
return Response.json({
error: e.message
}, {
status: 500
});
}
}).delete(`${apiBasePath}/:model`, async (req, ctx)=>{
const resources = (0, server_js_namespaceObject.getResources)(options);
const params = await ctx.params;
const resource = (0, server_js_namespaceObject.getResourceFromParams)(params[paramKey], resources);
if (!resource) return Response.json({
error: "Resource not found"
}, {
status: 404
});
if (!(0, permissions_js_namespaceObject.hasPermission)(options?.model?.[resource], external_types_js_namespaceObject.Permission.DELETE)) return Response.json({
error: "You don't have permission to delete this resource"
}, {
status: 403
});
try {
const body = await req.json();
await (0, resources_js_namespaceObject.deleteResource)({
body,
prisma,
resource,
modelOptions: options?.model?.[resource]
});
return Response.json({
ok: true
});
} catch (e) {
return Response.json({
error: e.message
}, {
status: 500
});
}
});
const executeRouteHandler = (req, context)=>router.run(req, context);
return {
run: executeRouteHandler,
router
};
};
exports.createHandler = __webpack_exports__.createHandler;
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
"createHandler"
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
Object.defineProperty(exports, '__esModule', {
value: true
});