UNPKG

@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

406 lines (405 loc) 16.9 kB
"use strict"; var __webpack_require__ = {}; (()=>{ __webpack_require__.n = (module)=>{ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module; __webpack_require__.d(getter, { a: getter }); return getter; }; })(); (()=>{ __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__, { setInternalPathToBlocks: ()=>setInternalPathToBlocks, buildQueryBlocks: ()=>buildQueryBlocks, isSchemaPropertyScalarArray: ()=>isSchemaPropertyScalarArray, buildUIBlocks: ()=>buildUIBlocks, cleanEmptyBlocks: ()=>cleanEmptyBlocks, isFieldNullable: ()=>isFieldNullable, contentTypeFromSchemaType: ()=>contentTypeFromSchemaType, getQueryCondition: ()=>getQueryCondition, validateQuery: ()=>validateQuery }); const external_lodash_get_namespaceObject = require("lodash.get"); var external_lodash_get_default = /*#__PURE__*/ __webpack_require__.n(external_lodash_get_namespaceObject); const external_lodash_set_namespaceObject = require("lodash.set"); var external_lodash_set_default = /*#__PURE__*/ __webpack_require__.n(external_lodash_set_namespaceObject); const external_zod_namespaceObject = require("zod"); var external_zod_default = /*#__PURE__*/ __webpack_require__.n(external_zod_namespaceObject); const queryConditionsSchema = external_zod_default().union([ external_zod_default().literal("equals"), external_zod_default().literal("not"), external_zod_default().literal("in"), external_zod_default().literal("notIn"), external_zod_default().literal("lt"), external_zod_default().literal("lte"), external_zod_default().literal("gt"), external_zod_default().literal("gte"), external_zod_default().literal("contains"), external_zod_default().literal("search"), external_zod_default().literal("startsWith"), external_zod_default().literal("endsWith"), external_zod_default().literal("has") ]); const filterSchema = external_zod_default().record(external_zod_default().string(), external_zod_default().union([ external_zod_default().record(queryConditionsSchema, external_zod_default().union([ external_zod_default().string(), external_zod_default().number(), external_zod_default().boolean(), external_zod_default()["null"](), external_zod_default().array(external_zod_default().any()) ])), external_zod_default().lazy(()=>filterSchema), external_zod_default().lazy(()=>relationshipSchema) ])); const relationshipSchema = external_zod_default().object({ some: external_zod_default().union([ external_zod_default().lazy(()=>queryBlockSchema), external_zod_default().lazy(()=>filterSchema) ]) }); const queryBlockSchema = external_zod_default().union([ external_zod_default().object({ AND: external_zod_default().lazy(()=>queryBlockSchema.array()) }), external_zod_default().object({ OR: external_zod_default().lazy(()=>queryBlockSchema.array()) }), filterSchema ]); const validateQuery = (query)=>{ try { const parsed = JSON.parse(query); return queryBlockSchema.parse(parsed); } catch (e) { return false; } }; const getQueryCondition = (condition)=>{ try { const queryCondition = queryConditionsSchema.parse(condition); return queryCondition; } catch { return false; } }; const contentTypeFromSchemaType = (schemaProperty)=>{ const { type: schemaType, format, enum: schemaEnum } = schemaProperty; const type = Array.isArray(schemaType) ? schemaType[0] : schemaType; switch(type){ case "string": if ("date-time" === format) return "datetime"; if (schemaEnum) return "enum"; return "text"; case "integer": case "number": return "number"; case "boolean": return "boolean"; default: return "text"; } }; const isFieldNullable = (schemaType)=>{ const isArrayType = Array.isArray(schemaType); if (isArrayType) return schemaType.includes("null"); return "null" === schemaType; }; const isSchemaPropertyScalarArray = (definition, property)=>{ const schemaProperty = definition.properties[property]; return schemaProperty?.type === "array" && !schemaProperty.items?.$ref; }; const setInternalPathToBlocks = (blocks, path = "")=>{ blocks.forEach((block, index)=>{ block.internalPath = `${path}[${index}]`; if ("filter" !== block.type && block.children) setInternalPathToBlocks(block.children, `${path}[${index}].children`); }); }; const cleanEmptyBlocks = (blocks)=>{ for(let i = 0; i < blocks.length; i++){ const block = blocks[i]; if (block) { if ("filter" !== block.type && block.children) block.children = cleanEmptyBlocks(block.children); } } const indicesToRemove = []; for(let i = 0; i < blocks.length; i++){ const block = blocks[i]; if (!block) indicesToRemove.push(i); } indicesToRemove.forEach((idx)=>{ blocks.splice(idx, 1); }); return blocks; }; const getConditionFromValue = (value, condition)=>{ if (null === value) return "equals" === condition ? "null" : "nnull"; if ("has" === condition) return "equals"; return condition; }; const getQueryBlockValue = (value, contentType, condition)=>{ if ("datetime" === contentType) try { const dateString = new Date(value).toJSON(); return dateString.substring(0, dateString.length - 8); } catch { return value; } if (("in" === condition || "notIn" === condition) && Array.isArray(value)) return value.join(", "); return value; }; const buildUIBlocks = (blocks, { resource, schema, options, t }, fields = [], displayFields = [])=>{ if (blocks) { const entries = Object.entries(blocks); const uiBlocks = entries.flatMap(([key, value])=>{ if ("AND" === key || "OR" === key) return { type: "AND" === key ? "and" : "or", id: crypto.randomUUID(), children: value.flatMap((block)=>buildUIBlocks(block, { resource, schema, options }, fields, displayFields)) }; { const resourceInSchema = schema.definitions[resource]; const schemaProperty = resourceInSchema.properties[key]; const conditions = Object.entries(value); const displayKeyFallback = options?.[resource]?.aliases?.[key] ?? key; const displayKey = t?.(`model.${resource}.fields.${key}`, {}, displayKeyFallback) ?? displayKeyFallback; if (schemaProperty) return conditions.flatMap(([conditionKey])=>{ const queryCondition = getQueryCondition(conditionKey); if (queryCondition) { const queryValue = value[conditionKey]; const contentType = contentTypeFromSchemaType(schemaProperty); return { type: "filter", path: [ ...fields, key ].join("."), condition: getConditionFromValue(queryValue, queryCondition), value: getQueryBlockValue(queryValue, contentType, queryCondition), id: crypto.randomUUID(), ..."enum" === contentType ? { enum: schemaProperty.enum } : {}, defaultValue: schemaProperty.default, contentType: contentType, canHaveChildren: false, nullable: isFieldNullable(schemaProperty.type), displayPath: [ ...displayFields, displayKey ].join(" \u2192 ") }; } { let isArrayConditionKey = "some" === conditionKey; if ("array" !== schemaProperty.type && isArrayConditionKey) if (!schemaProperty.properties?.some) return; else isArrayConditionKey = false; const childResourceName = (schemaProperty.__nextadmin?.relation?.$ref || schemaProperty?.anyOf?.[0]?.$ref)?.split("/")?.at(-1); const childEntries = Object.entries(isArrayConditionKey ? value.some : value); return childEntries.map(([childKey, childValue])=>{ if ("AND" === childKey || "OR" === childKey) return { type: "AND" === childKey ? "and" : "or", id: crypto.randomUUID(), children: childValue.flatMap((block)=>buildUIBlocks(block, { resource: childResourceName, schema, options }, [ ...fields, key ], [ ...displayFields, displayKey ])).filter(Boolean) }; return buildUIBlocks({ [childKey]: childValue }, { resource: childResourceName, schema, options }, [ ...fields, key ], [ ...displayFields, displayKey ]); }).flat(); } }); return; } }).filter(Boolean); setInternalPathToBlocks(uiBlocks); return uiBlocks; } return []; }; const getValueForUiBlock = (block)=>{ if ("filter" === block.type) { if ("null" === block.condition || "nnull" === block.condition) return null; if ("datetime" === block.contentType) return new Date(block.value).toISOString(); if ("in" === block.condition || "notIn" === block.condition) return block.value.split(",").map((val)=>{ val = val.trim(); if ("number" === block.contentType) return +val; return val; }).filter(Boolean); if ("number" === block.contentType && !!block.value) return +block.value; return block.value; } }; const getQueryBlockValueForUiBlock = (uiBlock)=>{ if ("filter" === uiBlock.type) { if ("null" === uiBlock.condition) return { equals: null }; if ("nnull" === uiBlock.condition) return { not: null }; return { [uiBlock.condition]: getValueForUiBlock(uiBlock) }; } return {}; }; const buildQueryBlocks = (blocks, { resource, schema }, acc = {}, path = "")=>{ blocks.forEach((block)=>{ if ("and" === block.type || "or" === block.type) { const children = block.children; if (children?.length) { const blockKey = "and" === block.type ? "AND" : "OR"; const finalPath = [ path, blockKey ].filter(Boolean).join("."); external_lodash_set_default()(acc, finalPath, []); block.children?.forEach((child, index)=>{ buildQueryBlocks([ child ], { resource, schema }, acc, `${finalPath}[${index}]`); }); } } else if ("filter" === block.type) { const [basePath, ...rest] = block.path.split("."); const resourceInSchema = schema.definitions[resource]; const schemaProperty = resourceInSchema.properties[basePath]; if (schemaProperty?.type === "array") if (isSchemaPropertyScalarArray(resourceInSchema, basePath)) external_lodash_set_default()(acc, [ path, basePath ].filter(Boolean).join("."), { has: getValueForUiBlock(block) }); else { const childResource = schemaProperty.__nextadmin?.relation?.$ref?.split("/")?.at(-1); if (!external_lodash_get_default()(acc, [ path, basePath ].filter(Boolean))) external_lodash_set_default()(acc, [ path, basePath ].filter(Boolean).join("."), { some: {} }); buildQueryBlocks([ { ...block, path: rest.join(".") } ], { resource: childResource, schema }, acc, [ path, basePath, "some" ].filter(Boolean).join(".")); } else if (schemaProperty && (schemaProperty?.__nextadmin?.relation?.$ref || schemaProperty?.anyOf?.[0]?.$ref)) { const ref = schemaProperty?.__nextadmin?.relation?.$ref || schemaProperty?.anyOf?.[0]?.$ref; const childResource = ref.split("/").at(-1); if (!external_lodash_get_default()(acc, [ path, basePath ].filter(Boolean))) external_lodash_set_default()(acc, [ path, basePath ].filter(Boolean).join("."), {}); buildQueryBlocks([ { ...block, path: rest.join(".") } ], { resource: childResource, schema }, acc, [ path, basePath ].filter(Boolean).join(".")); } else external_lodash_set_default()(acc, [ path, basePath ].filter(Boolean).join("."), { ...external_lodash_get_default()(acc, [ path, basePath ].filter(Boolean)), ...getQueryBlockValueForUiBlock(block) }); } }); return acc; }; exports.buildQueryBlocks = __webpack_exports__.buildQueryBlocks; exports.buildUIBlocks = __webpack_exports__.buildUIBlocks; exports.cleanEmptyBlocks = __webpack_exports__.cleanEmptyBlocks; exports.contentTypeFromSchemaType = __webpack_exports__.contentTypeFromSchemaType; exports.getQueryCondition = __webpack_exports__.getQueryCondition; exports.isFieldNullable = __webpack_exports__.isFieldNullable; exports.isSchemaPropertyScalarArray = __webpack_exports__.isSchemaPropertyScalarArray; exports.setInternalPathToBlocks = __webpack_exports__.setInternalPathToBlocks; exports.validateQuery = __webpack_exports__.validateQuery; for(var __webpack_i__ in __webpack_exports__)if (-1 === [ "buildQueryBlocks", "buildUIBlocks", "cleanEmptyBlocks", "contentTypeFromSchemaType", "getQueryCondition", "isFieldNullable", "isSchemaPropertyScalarArray", "setInternalPathToBlocks", "validateQuery" ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; Object.defineProperty(exports, '__esModule', { value: true });