UNPKG

strapi-plugin-navigation

Version:
1,795 lines 351 kB
import de, { uniqBy as lu, isNil as Ke, find as Gn, includes as fu, last as qn, capitalize as pu, isEmpty as nt, once as fi, omit as gn, get as un, toString as du, pick as Ia, differenceBy as hu, upperFirst as dr, isObject as hr, isArray as jr, isString as Ji, zipWith as mu, first as mr, cloneDeep as gu, isNaN as yu } from "lodash"; import * as y from "zod"; import { z as Oa } from "zod"; import { union as vu, getOr as wu, curry as De, isObject as $e, isNil as oe, clone as Eu, isArray as We, pick as eo, isEmpty as ze, cloneDeep as pi, omit as bu, isString as Ue, trim as yn, pipe as xu, split as Hr, map as Su, flatten as Au, first as Na, constant as Br, identity as _u, join as Tu, eq as Cu, get as to } from "lodash/fp"; import no from "crypto"; import vn from "child_process"; import wn from "lodash/has"; import Pa from "lodash/mapValues"; import ro from "lodash/snakeCase"; import Ru from "lodash/camelCase"; import Fu from "lodash/mapKeys"; import Kn from "os"; import Ee from "path"; import Ve from "fs"; import La from "assert"; import $u from "events"; import Iu from "buffer"; import Wn from "stream"; import ut from "util"; import Ou from "constants"; import "node:stream"; import Nu from "@sindresorhus/slugify"; import * as q from "zod/v4"; import io from "pluralize"; const di = y.object({ name: y.string({ required_error: "requiredError" }).nonempty("requiredError").refine((e) => !e.includes(" "), { message: "noSpaceError" }), label: y.string({ required_error: "requiredError" }).nonempty("requiredError"), description: y.string().optional(), placeholder: y.string().optional(), required: y.boolean().optional(), enabled: y.boolean().optional() }), Pu = di.extend({ type: y.literal("select"), multi: y.boolean(), options: y.array(y.string(), { required_error: "requiredError" }).min(1, { message: "requiredError" }) }), Lu = di.extend({ type: y.enum(["boolean", "string"]), multi: y.literal(!1).optional(), options: y.array(y.string()).max(0).optional() }), ku = di.extend({ type: y.literal("media"), multi: y.literal(!1).optional(), options: y.array(y.string()).max(0).optional() }), ka = y.discriminatedUnion("type", [ Lu, ku, Pu ]), Da = y.union([ y.literal("audience"), ka ]), Du = y.object({ additionalFields: y.array(Da), allowedLevels: y.number(), contentTypes: y.array(y.string()), defaultContentType: y.string().optional(), contentTypesNameFields: y.record(y.string(), y.array(y.string())), contentTypesPopulate: y.record(y.string(), y.array(y.string())), gql: y.object({ navigationItemRelated: y.array(y.string()) }), pathDefaultFields: y.record(y.string(), y.any()), cascadeMenuAttached: y.boolean(), preferCustomContentTypes: y.boolean(), isCacheEnabled: y.boolean().optional() }), Ma = y.object({ id: y.number(), documentId: y.string(), name: y.string(), key: y.string() }), Mu = y.enum(["INTERNAL", "EXTERNAL", "WRAPPER"]), hi = y.object({ id: y.number(), documentId: y.string(), title: y.string(), type: Mu, path: y.string().or(y.null()).optional(), slug: y.string().or(y.null()).optional(), externalPath: y.string().or(y.null()).optional(), uiRouterKey: y.string(), menuAttached: y.boolean(), order: y.number().int(), collapsed: y.boolean(), related: y.object({ documentId: y.string().optional(), __type: y.string() }).catchall(y.unknown()).nullish().optional(), additionalFields: y.record(y.string(), y.unknown()).or(y.null()).optional(), audience: y.array(Ma).or(y.null()).optional(), autoSync: y.boolean().or(y.null()).optional() }), ju = hi.omit({ related: !0 }).pick({ path: !0, type: !0, uiRouterKey: !0, title: !0, externalPath: !0 }).extend({ related: y.unknown().optional() }), Ht = hi.extend({ parent: y.lazy(() => Ht.or(y.null())).optional(), items: y.lazy(() => Ht.array()).optional(), master: y.lazy(() => et(!1)).optional() }), oo = y.array(Ht), et = (e) => y.object({ id: y.number(), documentId: y.string(), name: y.string(), slug: y.string(), locale: y.string(), visible: y.boolean(), items: e ? y.array(Ht) : Ht.array().optional() }), Hu = et(!1).omit({ items: !0, id: !0, documentId: !0, slug: !0, locale: !0 }).extend({ documentId: y.string().optional(), id: y.undefined().optional() }), Bu = hi.omit({ id: !0, documentId: !0 }).extend({ id: y.number().optional(), documentId: y.string().optional(), items: y.lazy(() => ja).or(y.null()).optional(), updated: y.boolean().optional(), removed: y.boolean().optional() }), ja = y.array(Bu), Uu = et(!1).extend({ items: ja }).partial().required({ id: !0, documentId: !0 }), Gu = y.enum(["collectionType", "singleType"]), qu = y.object({ singularName: y.string(), pluralName: y.string(), displayName: y.string(), description: y.string().optional(), name: y.string().optional() }), Ha = y.object({ required: y.boolean().optional(), max: y.number().optional(), min: y.number().optional(), minLength: y.number().optional(), maxLength: y.number().optional(), private: y.boolean().optional(), configurable: y.boolean().optional(), default: y.any().optional() }), Ku = y.enum([ "string", "text", "richtext", "blocks", "email", "password", "date", "time", "datetime", "timestamp", "boolean", "integer", "biginteger", "float", "decimal", "json", "relation", "media" ]), Wu = Ha.extend({ type: Ku }), zu = Ha.extend({ type: y.literal("enumeration"), enum: y.string().array() }), Yu = y.object({ type: y.literal("component"), component: y.string(), repeatable: y.boolean().optional() }), Qu = y.object({ type: y.literal("dynamiczone"), components: y.string().array() }), Vu = y.object({ type: y.literal("uid") }), Xu = y.object({ type: y.literal("media"), allowedTypes: y.enum(["images", "videos", "audios", "files"]).array(), required: y.boolean().optional() }), Zu = y.enum([ "oneToOne", "oneToMany", "manyToOne", "manyToMany", "morphToMany", "manyToMorph" ]), Ju = y.object({ type: y.literal("relation"), relation: Zu, target: y.string(), mappedBy: y.string().optional(), inversedBy: y.string().optional() }), el = y.record( y.string(), y.union([ Wu, zu, Yu, Qu, Ju, Xu, Vu ]) ), Ur = y.object({ kind: Gu, collectionName: y.string(), info: qu, options: y.object({ draftAndPublish: y.boolean().optional(), hidden: y.boolean().optional(), templateName: y.string().optional() }).optional(), attributes: el, actions: y.record(y.string(), y.any()).optional(), lifecycles: y.record(y.string(), y.any()).optional(), uid: y.string(), apiName: y.string().optional(), // TODO?: remove associations: y.object({ model: y.string(), alias: y.string() }).array().optional(), modelName: y.string().optional(), plugin: y.string().optional(), pluginOptions: y.record(y.string(), y.any()).optional(), isSingle: y.boolean().optional() }); Ur.pick({ info: !0, kind: !0, attributes: !0, options: !0 }); const Gt = (e, t) => (n) => { t(n(e())); }; let Gr = Du; const tl = Gt( () => Gr, (e) => { Gr = e; } ); let qr = Da; const nl = Gt( () => qr, (e) => { qr = e; } ); let Kr = ka; const rl = Gt( () => Kr, (e) => { Kr = e; } ); let Wr = Hu; const il = Gt( () => Wr, (e) => { Wr = e; } ); let zr = Uu; const ol = Gt( () => zr, (e) => { zr = e; } ), _e = { get configSchema() { return Gr; }, get navigationItemAdditionalField() { return qr; }, get navigationItemCustomField() { return Kr; }, get createNavigationSchema() { return Wr; }, get updateNavigationSchema() { return zr; } }, al = /^(?<type>[a-z0-9-]+)\:{2}(?<api>[a-z0-9-]+)\.{1}(?<contentType>[a-z0-9-]+)$/i, sl = [ "beforeCreate", "beforeCreateMany", "afterCreate", "afterCreateMany", "beforeUpdate", "beforeUpdateMany", "afterUpdate", "afterUpdateMany", "beforeDelete", "beforeDeleteMany", "afterDelete", "afterDeleteMany", "beforeCount", "afterCount", "beforeFindOne", "afterFindOne", "beforeFindMany", "afterFindMany" ], cl = "$", Ba = ["api::", "plugin::"], Ua = [ "admin::", "plugin::content-releases", "plugin::i18n.locale", "plugin::navigation", "plugin::review-workflows", "plugin::users-permissions", "plugin::upload.folder" ], ul = ["title", "subject", "name"], ao = { SINGLE: "singleType" }, so = [ "title", "type", "path", "externalPath", "uiRouterKey", "menuAttached", "order", "collapsed", "related", "parent", "master", "audience", "additionalFields" ], ll = (e) => e.filter((t) => t !== "audience"), Ga = (e) => { const t = ll(e); if (t.length !== lu(t, "name").length) throw new Error("All names of custom fields must be unique."); if (!Ke( Gn( t, (n) => typeof n == "object" && fu(so, n.name) ) )) throw new Error( `Name of custom field cannot be one of: ${so.join(", ")}` ); }, qa = (e, t) => { if (e == null) throw t ?? new Error("Non-empty value expected, empty given"); }, fl = (e = "") => { const t = (a) => a.split("-").map((o) => pu(o)).join(""), [n, r, i] = pl(e); return n === "api" ? t(i) : `${t(r)}${t(i)}`; }, pl = (e = "") => e.split(al).filter((t) => t && t.length > 0), dl = (e, t) => (n) => [ n, async (r) => { await te(t, "common").runLifeCycleHook({ contentTypeName: e, hookName: n, event: r }); } ], Ka = (e, t) => Object.fromEntries(sl.map(dl(e, t))), ye = ({ strapi: e }) => { const t = e.plugin("navigation"); return { masterModel: t.contentType("navigation"), itemModel: t.contentType("navigation-item"), relatedModel: t.contentType("navigations-items-related"), audienceModel: t.contentType("audience") }; }; function te({ strapi: e }, t) { return e.plugin("navigation").service(t); } const Jt = (e) => e === "*" ? "*" : typeof e == "string" ? [e] : e === !1 ? [] : e === !0 ? "*" : e, hl = (e = "") => { const t = !!Ba.find((r) => e.includes(r)), n = !Ua.find((r) => e.includes(r) || e === r); return !!e && t && n; }, co = (e = "") => qn(e) === "s" ? e.substr(0, e.length - 1) : e, Wa = async ({ strapi: e, forceDefault: t = !1 }) => { const n = e.store({ type: "plugin", name: "navigation" }), r = await e.plugin("navigation").config, i = t ? {} : { ...Yr.default, ...await n.get({ key: "config" }) ?? Yr.default }; let a = nt(i) ? i : _e.configSchema.parse(i); const o = ml(a, r); return a = { additionalFields: o("additionalFields"), contentTypes: o("contentTypes"), contentTypesNameFields: o("contentTypesNameFields"), contentTypesPopulate: o("contentTypesPopulate"), defaultContentType: o("defaultContentType"), allowedLevels: o("allowedLevels"), gql: o("gql"), pathDefaultFields: o("pathDefaultFields"), cascadeMenuAttached: o("cascadeMenuAttached"), preferCustomContentTypes: o("preferCustomContentTypes"), isCacheEnabled: o("isCacheEnabled") }, gl(a, { strapi: e }), Ga(a.additionalFields), await n.set({ key: "config", value: a }), a; }, ml = (e, t) => (n) => { const r = e?.[n] ?? t(n); return qa(r, new Error(`[Navigation] Config "${n}" is undefined`)), r; }, gl = (e, { strapi: t }) => { const n = e.contentTypes.filter( (i) => !t.contentTypes[i] ); if (n.length === 0) return; const r = n.map(fl); e.contentTypes = e.contentTypes.filter( (i) => !n.includes(i) ), e.contentTypesNameFields = Object.fromEntries( Object.entries(e.contentTypesNameFields).filter( ([i]) => !n.includes(i) ) ), e.gql.navigationItemRelated = e.gql.navigationItemRelated.filter( (i) => !r.includes(i) ); }, Yr = { default: { additionalFields: [], allowedLevels: 2, contentTypes: [], defaultContentType: "", contentTypesNameFields: {}, contentTypesPopulate: {}, gql: { navigationItemRelated: [] }, pathDefaultFields: {}, pruneObsoleteI18nNavigations: !1, cascadeMenuAttached: !0, preferCustomContentTypes: !1, isCacheEnabled: !1 } }, yl = fi((e) => ({ find(t, n) { const { audienceModel: { uid: r } } = ye(e); return e.strapi.query(r).findMany({ where: t, limit: n }).then(Ma.array().parse); } })), En = (e, t) => ({ findFirst(n, r, i = {}) { return e.strapi.documents(t).findFirst({ populate: Jt(n), status: r, ...i }); }, findById(n, r, i, a = {}) { return e.strapi.documents(t).findOne({ documentId: n, populate: Jt(r), status: i, ...a }); }, findManyById(n, r, i) { return e.strapi.documents(t).findMany({ where: { documentId: { $in: n } }, populate: Jt(r), status: i }); }, findMany(n, r, i, a) { return e.strapi.documents(t).findMany({ where: n, populate: Jt(r), status: i, locale: a }); }, count(n, r) { return e.strapi.documents(t).count({ where: n, status: r }); } }), Pe = fi((e) => ({ async save({ item: t, locale: n }) { const { itemModel: r } = ye(e), { __type: i, documentId: a } = t?.related ?? {}, o = i ? En(e, i) : void 0, s = i && o ? a ? await o.findById(a, void 0, void 0, { locale: n }) : await o.findFirst(void 0, void 0, { locale: n }) : void 0; if (typeof t.documentId == "string") { const { documentId: c, ...f } = t; return e.strapi.documents(r.uid).update({ documentId: t.documentId, data: { ...f, related: s ? { ...s, __type: i } : void 0 }, locale: n }); } else return e.strapi.documents(r.uid).create({ data: { ...t, related: s ? { ...s, __type: i } : void 0 }, locale: n }); }, find({ filters: t, locale: n, limit: r, order: i, populate: a }) { const { itemModel: o } = ye(e); return e.strapi.documents(o.uid).findMany({ filters: t, locale: n, limit: r, populate: a, orderBy: i }).then((s) => s.map(Qr)).then(oo.parse).then((s) => s.map(bn)); }, findV4({ filters: t, locale: n, limit: r, order: i, populate: a }) { const { itemModel: o } = ye(e); return e.strapi.documents(o.uid).findMany({ filters: t, locale: n, limit: r, populate: a, orderBy: i }); }, count(t) { const { itemModel: n } = ye(e); return e.strapi.query(n.uid).count({ where: t }); }, remove(t) { const { itemModel: n } = ye(e); return e.strapi.documents(n.uid).delete({ documentId: t.documentId, populate: "*" }); }, removeForIds(t) { const { itemModel: n } = ye(e); return t.map( (r) => e.strapi.documents(n.uid).delete({ documentId: r, populate: "*" }) ); }, findForMasterIds(t) { const { itemModel: n } = ye(e); return e.strapi.query(n.uid).findMany({ where: { $or: t.map((r) => ({ master: r })) }, limit: Number.MAX_SAFE_INTEGER }).then(oo.parse); } })), vl = ["id", "publishedAt", "createdAt", "updatedAt", "locale"], bn = ({ related: e, items: t = [], ...n }) => ({ ...n, items: t.map(bn), related: e ? gn(e, vl) : void 0 }), Qr = ({ related: e, ...t }) => ({ ...t, related: e?.[0] }); class Ct extends Error { constructor(t, n) { super(t), this.additionalInfo = n, this.type = "NavigationError"; } } class gr extends Ct { constructor() { super(...arguments), this.type = "FillNavigationError"; } } class wl extends Ct { constructor() { super(...arguments), this.type = "InvalidParamNavigationError"; } } const uo = (e) => e === !0 ? !0 : Array.isArray(e) ? e.includes("items") : !1, Fe = fi((e) => ({ find({ filters: t, locale: n, limit: r, orderBy: i, populate: a }) { const { masterModel: o } = ye(e); return e.strapi.documents(o.uid).findMany({ filters: t, locale: n, limit: r, populate: a, orderBy: i }).then( (s) => s.map(({ items: c, ...f }) => ({ ...f, items: c?.map(Qr) })) ).then( (s) => s.map(({ items: c, ...f }) => ({ ...f, items: c?.map(bn) })) ).then((s) => et(uo(a)).array().parse(s)); }, findOne({ locale: t, filters: n, populate: r }) { const { masterModel: i } = ye(e); return e.strapi.documents(i.uid).findOne({ documentId: n.documentId, locale: t, populate: r }).then((a) => a && { ...a, items: a.items?.map(Qr) }).then((a) => et(uo(r)).parse(a)).then((a) => ({ ...a, items: a.items?.map(bn) })); }, async save(t) { const { masterModel: n } = ye(e), { documentId: r, locale: i, ...a } = t; return r ? e.strapi.documents(n.uid).update({ locale: i, documentId: r, data: gn(a, ["id", "documentId"]), populate: ["items"] }).then(et(!1).parse) : e.strapi.documents(n.uid).create({ locale: i, data: { ...a, populate: ["items"] } }).then(et(!1).parse); }, remove(t) { const { masterModel: n } = ye(e); if (!t.documentId) throw new Ct("Document id is required."); return e.strapi.documents(n.uid).delete({ documentId: t.documentId }); } })), El = "Navigation", bl = "navigation", xl = async (e) => { const t = te(e, "common"), { defaultLocale: n, restLocale: r = [] } = await t.readLocale(), i = Fe(e), a = await i.find({ limit: Number.MAX_SAFE_INTEGER, filters: {}, locale: "*" }); a.length === 0 && a.push( await i.save({ name: El, visible: !0, locale: n, slug: bl }) ); const o = a.filter(({ locale: s }) => s === n); for (const s of o) for (const c of r) !a.find( ({ locale: u, documentId: l }) => l === s.documentId && c === u ) && await i.save({ documentId: s.documentId, name: s.name, locale: c, visible: s.visible, slug: s.slug }); }, pe = { render: function(e) { return `plugin::navigation.${e}`; }, navigation: { read: "read", update: "update", settings: "settings" } }, Sl = async ({ strapi: e }) => { const t = [ { section: "plugins", displayName: "Read", uid: pe.navigation.read, pluginName: "navigation" }, { section: "plugins", displayName: "Update", uid: pe.navigation.update, pluginName: "navigation" }, { section: "plugins", displayName: "Settings", uid: pe.navigation.settings, pluginName: "navigation" } ]; await e.admin.services.permission.actionProvider.registerMany(t); }, Al = "I18NLocaleCode", _l = ({ strapi: e, nexus: t }) => { const { nonNull: n, list: r, stringArg: i, booleanArg: a } = t; return { args: { navigationIdOrSlug: n(i()), type: "NavigationRenderType", menuOnly: a(), path: i(), locale: t.arg({ type: Al }) }, type: n(r("NavigationItem")), resolve(c, { navigationIdOrSlug: f, type: u, menuOnly: l, path: p, locale: d }) { const h = Oa.string().parse(f); return te({ strapi: e }, "client").render({ idOrSlug: h, type: u, rootPath: p, locale: d, menuOnly: l, wrapRelated: !0 }); } }; }, Tl = ({ strapi: e, nexus: t }) => { const { nonNull: n, list: r, stringArg: i, booleanArg: a } = t; return { type: n(r("NavigationItem")), args: { documentId: n(i()), childUiKey: n(i()), type: "NavigationRenderType", menuOnly: a() }, resolve(o, s) { const { documentId: c, childUIKey: f, type: u, menuOnly: l } = s, p = Oa.string().parse(c); return te({ strapi: e }, "client").renderChildren({ idOrSlug: p, childUIKey: f, type: u, menuOnly: l, wrapRelated: !0 }); } }; }, Cl = (e) => { const t = { renderNavigationChild: Tl, renderNavigation: _l }; return e.nexus.extendType({ type: "Query", definition(n) { for (const [r, i] of Object.entries(t)) { const a = i(e); n.field(r, a); } } }); }, Rl = () => ({ "Query.renderNavigationChild": { auth: !1 }, "Query.renderNavigation": { auth: !1 } }), Fl = ({ nexus: e }) => e.objectType({ name: "ContentTypes", definition(t) { t.nonNull.string("uid"), t.nonNull.string("name"), t.nonNull.boolean("isSingle"), t.nonNull.string("collectionName"), t.nonNull.string("contentTypeName"), t.nonNull.string("label"), t.nonNull.string("relatedField"), t.nonNull.string("labelSingular"), t.nonNull.string("endpoint"), t.nonNull.boolean("available"), t.nonNull.boolean("visible"); } }), $l = ({ nexus: e, strapi: t }) => e.objectType({ name: "ContentTypesNameFields", async definition(n) { n.nonNull.list.nonNull.string("default"); const i = await te({ strapi: t }, "common").getPluginStore(), o = _e.configSchema.parse(await i.get({ key: "config" })).contentTypesNameFields; Object.keys(o || {}).forEach((s) => n.nonNull.list.string(s)); } }), Il = ({ nexus: e }) => e.inputObjectType({ name: "CreateNavigation", definition(t) { t.nonNull.string("name"), t.nonNull.list.field("items", { type: "CreateNavigationItem" }); } }), Ol = ({ nexus: e }) => e.inputObjectType({ name: "CreateNavigationItem", definition(t) { t.nonNull.string("title"), t.nonNull.field("type", { type: "NavigationItemType" }), t.string("path"), t.string("externalPath"), t.nonNull.string("uiRouterKey"), t.nonNull.boolean("menuAttached"), t.nonNull.int("order"), t.string("parent"), t.string("master"), t.list.field("items", { type: "CreateNavigationItem" }), t.list.string("audience"), t.field("related", { type: "CreateNavigationRelated" }); } }), Nl = ({ nexus: e }) => e.inputObjectType({ name: "CreateNavigationRelated", definition(t) { t.nonNull.string("ref"), t.nonNull.string("field"), t.nonNull.string("refId"); } }), Pl = ({ nexus: e }) => e.objectType({ name: "Navigation", definition(t) { t.nonNull.string("id"), t.nonNull.string("documentId"), t.nonNull.string("name"), t.nonNull.string("slug"), t.nonNull.boolean("visible"); } }), Ll = ({ nexus: e }) => e.objectType({ name: "NavigationConfig", definition(t) { t.int("allowedLevels"), t.nonNull.list.string("additionalFields"), t.field("contentTypesNameFields", { type: "ContentTypesNameFields" }), t.list.field("contentTypes", { type: "ContentTypes" }); } }), kl = ({ nexus: e }) => e.objectType({ name: "NavigationDetails", definition(t) { t.nonNull.string("id"), t.nonNull.string("documentId"), t.nonNull.string("name"), t.nonNull.string("slug"), t.nonNull.boolean("visible"), t.nonNull.list.field("items", { type: "NavigationItem" }); } }), Dl = ({ nexus: e, config: t }) => e.objectType({ name: "NavigationItem", definition(n) { n.nonNull.int("id"), n.nonNull.string("documentId"), n.nonNull.string("title"), n.nonNull.field("type", { type: "NavigationItemType" }), n.string("path"), n.string("externalPath"), n.nonNull.string("uiRouterKey"), n.nonNull.boolean("menuAttached"), n.nonNull.int("order"), n.field("parent", { type: "NavigationItem" }), n.string("master"), n.list.field("items", { type: "NavigationItem" }), n.field("related", { type: "NavigationItemRelated" }), t.additionalFields.find((r) => r === "audience") && n.list.string("audience"), n.field("additionalFields", { type: "NavigationItemAdditionalFields" }), n.string("created_at"), n.string("updated_at"), n.string("created_by"), n.string("updated_by"), n.string("createdAt"), n.string("updatedAt"), n.string("createdBy"), n.string("updatedBy"); } }), Ml = ({ nexus: e, config: t }) => e.objectType({ name: "NavigationItemAdditionalFields", definition(n) { t.additionalFields.forEach((r) => { if (r !== "audience" && r.enabled) switch (r.type) { case "media": n.field(r.name, { type: "UploadFile" }); break; case "string": n.string(r.name); break; case "boolean": n.boolean(r.name); break; case "select": r.multi ? n.list.string(r.name) : n.string(r.name); break; default: throw new Error( `Type "${JSON.stringify(r.type)}" is unsupported by custom fields` ); } }); } }), jl = ({ strapi: e, nexus: t, config: n }) => { const r = n.gql?.navigationItemRelated, i = "NavigationItemRelated"; return r?.length ? t.unionType({ name: i, definition(a) { a.members(...r); }, resolveType: (a) => e.contentTypes[a.__type]?.globalId }) : t.objectType({ name: i, definition(a) { a.int("id"), a.string("documentId"), a.string("title"), a.string("name"); } }); }, Hl = ({ nexus: e }) => e.enumType({ name: "NavigationItemType", members: ["INTERNAL", "EXTERNAL", "WRAPPER"] }), Bl = ({ nexus: e }) => e.enumType({ name: "NavigationRenderType", members: ["FLAT", "TREE"] }), Ul = [ Ml, jl, Dl, Bl, Pl, kl, $l, Fl, Ll, Nl, Ol, Il, Hl ], Gl = (e) => Ul.map((t) => t(e)), ql = async ({ strapi: e }) => { const t = e.plugin("graphql").service("extension"); t.shadowCRUD("plugin::navigation.audience").disable(), t.shadowCRUD("plugin::navigation.navigation").disable(), t.shadowCRUD("plugin::navigation.navigation-item").disable(), t.shadowCRUD("plugin::navigation.navigations-items-related").disable(); const r = await te({ strapi: e }, "common").getPluginStore(), i = _e.configSchema.parse(await r.get({ key: "config" })); t.use(({ strapi: a, nexus: o }) => { const s = Gl({ strapi: a, nexus: o, config: i }), c = Cl({ strapi: a, nexus: o }), f = Rl(); return { types: [s, c], resolversConfig: f }; }); }, Kl = async ({ strapi: e }) => { !!e.plugin("graphql") && await ql({ strapi: e }); }, Wl = async (e) => { await Wa(e), await xl(e), await Sl(e), await Kl(e), await strapi.service("plugin::navigation.migrate").migrateRelatedIdToDocumentId(), strapi.db.lifecycles.subscribe({ models: ["plugin::i18n.locale"], async afterCreate(t) { await te(e, "admin").refreshNavigationLocale(t.result?.code); } }); }, zl = ({ strapi: e }) => { }, Yl = ({ strapi: e }) => { }, Ql = { collectionName: "audience", info: { singularName: "audience", pluralName: "audiences", displayName: "Audience", name: "audience" }, options: { increments: !0, comment: "Audience" }, attributes: { name: { type: "string", required: !0 }, key: { type: "uid", targetField: "name" } } }, Vl = { schema: Ql }, Xl = Ka("navigation", { strapi }), Zl = { collectionName: "navigations", info: { singularName: "navigation", pluralName: "navigations", displayName: "Navigation", name: "navigation" }, options: { comment: "" }, pluginOptions: { "content-manager": { visible: !1 }, "content-type-builder": { visible: !1 }, i18n: { localized: !0 } }, attributes: { name: { type: "text", configurable: !1, required: !0 }, slug: { type: "uid", target: "name", configurable: !1, required: !0 }, visible: { type: "boolean", default: !1, configurable: !1 }, items: { type: "relation", relation: "oneToMany", target: "plugin::navigation.navigation-item", configurable: !1, mappedBy: "master" } } }, Jl = { schema: Zl, lifecycles: Xl }, ef = Ka("navigation-item", { strapi }), tf = { collectionName: "navigations_items", info: { singularName: "navigation-item", pluralName: "navigation-items", displayName: "Navigation Item", name: "navigation-item" }, options: { increments: !0, timestamps: !0, comment: "Navigation Item" }, pluginOptions: { "content-manager": { visible: !1 }, "content-type-builder": { visible: !1 }, i18n: { localized: !1 } }, attributes: { title: { type: "text", configurable: !1, required: !0, pluginOptions: { i18n: { localized: !1 } } }, type: { type: "enumeration", enum: ["INTERNAL", "EXTERNAL", "WRAPPER"], default: "INTERNAL", configurable: !1 }, path: { type: "text", targetField: "title", configurable: !1 }, externalPath: { type: "text", configurable: !1 }, uiRouterKey: { type: "string", configurable: !1 }, menuAttached: { type: "boolean", default: !1, configurable: !1 }, order: { type: "integer", default: 0, configurable: !1 }, collapsed: { type: "boolean", default: !1, configurable: !1 }, autoSync: { type: "boolean", default: !0, configurable: !1 }, related: { type: "relation", relation: "morphToMany", required: !0, configurable: !1 }, parent: { type: "relation", relation: "oneToOne", target: "plugin::navigation.navigation-item", configurable: !1, default: null }, master: { type: "relation", relation: "manyToOne", target: "plugin::navigation.navigation", configurable: !1, inversedBy: "items" }, audience: { type: "relation", relation: "oneToMany", target: "plugin::navigation.audience" }, additionalFields: { type: "json", require: !1, default: {} } } }, nf = { schema: tf, lifecycles: ef }, rf = { audience: Vl, navigation: Jl, "navigation-item": nf }, za = y.enum(["true", "false"]), en = y.string(), of = y.object({ locale: y.string().optional(), orderBy: y.string().optional(), orderDirection: y.enum(["DESC", "ASC"]).optional() }), Ya = y.enum(["FLAT", "TREE", "RFR"]), Qa = y.union([y.boolean(), y.string(), y.string().array(), y.undefined()]), af = y.object({ type: Ya.optional(), menu: za.optional(), path: y.string().optional(), locale: y.string().optional(), populate: Qa.optional() }), sf = y.object({ type: Ya.optional(), menu: za.optional(), locale: y.string().optional() }), cf = y.object({ source: y.string().min(1), target: y.string().min(1), documentId: y.string().min(1) }); function uf(e) { return { getAdminService() { return te(e, "admin"); }, getCommonService() { return te(e, "common"); }, async get() { return await this.getAdminService().get({}); }, async post(t) { const { auditLog: n } = t; try { return await this.getAdminService().post({ payload: _e.createNavigationSchema.parse(t.request.body), auditLog: n }); } catch (r) { const i = r instanceof Error ? { name: r.name, message: r.message } : {}; return t.internalServerError("Unable to create", { originalError: i }); } }, async put(t) { const { params: { documentId: n }, auditLog: r } = t, i = y.record(y.string(), y.unknown()).parse(t.request.body); try { return await this.getAdminService().put({ auditLog: r, payload: _e.updateNavigationSchema.parse({ ...i, documentId: n }) }); } catch (a) { const o = a instanceof Error ? { name: a.name, message: a.message } : {}; return t.internalServerError("Unable to update", { originalError: o }); } }, async delete(t) { const { auditLog: n, params: { documentId: r } } = t; return await this.getAdminService().delete({ documentId: en.parse(r), auditLog: n }), {}; }, config() { return this.getAdminService().config({ viaSettingsPage: !1 }); }, async updateConfig(t) { return await this.getAdminService().updateConfig({ config: _e.configSchema.parse(t.request.body) }), {}; }, async restoreConfig() { return await this.getAdminService().restoreConfig(), {}; }, settingsConfig() { return this.getAdminService().config({ viaSettingsPage: !0 }); }, async settingsRestart() { return await this.getAdminService().restart(), {}; }, getById(t) { const { params: { documentId: n } } = t; return this.getAdminService().getById({ documentId: en.parse(n) }); }, getContentTypeItems(t) { const { params: { model: n }, query: r = {} } = t; return this.getAdminService().getContentTypeItems({ query: y.record(y.string(), y.unknown()).parse(r), uid: y.string().parse(n) }); }, async fillFromOtherLocale(t) { const { params: n, auditLog: r } = t, { source: i, target: a, documentId: o } = cf.parse(n); return await this.getAdminService().fillFromOtherLocale({ source: i, target: a, documentId: o, auditLog: r }); }, readNavigationItemFromLocale(t) { const { params: { source: n, target: r }, query: { path: i } } = t; return this.getAdminService().readNavigationItemFromLocale({ path: y.string().parse(i), source: en.parse(n), target: en.parse(r) }); }, getSlug(t) { const { query: { q: n } } = t; return this.getCommonService().getSlug({ query: y.string().parse(n) }).then((r) => ({ slug: r })); }, settingsLocale() { return this.getCommonService().readLocale(); } }; } const lf = (e) => { if (!(!e || e === !0 || e === "*") && typeof e != "object") return Array.isArray(e), e; }; function ff(e) { return { getService() { return te(e, "client"); }, async readAll(t) { try { const { query: n = {} } = t, { locale: r, orderBy: i, orderDirection: a } = of.parse(n); return await this.getService().readAll({ locale: r, orderBy: i, orderDirection: a }); } catch (n) { if (n instanceof Error) return t.badRequest(n.message); throw n; } }, async render(t) { const { params: n, query: r = {} } = t, { type: i, menu: a, path: o, locale: s, populate: c } = af.parse(r), f = y.string().parse(n.idOrSlug); return await this.getService().render({ idOrSlug: f, type: i, menuOnly: a === "true", rootPath: o, locale: s, populate: lf( Qa.parse( c === "true" ? !0 : c === "false" ? !1 : Array.isArray(c) ? c.map((u) => u === "true" ? !0 : u === "false" ? !1 : c) : c ) ) }); }, async renderChild(t) { const { params: n, query: r = {} } = t, { type: i, menu: a, locale: o } = sf.parse(r), s = y.string().parse(n.documentId), c = y.string().parse(n.childUIKey); return await this.getService().renderChildren({ idOrSlug: s, childUIKey: c, type: i, menuOnly: a === "true", locale: o }); } }; } const pf = { admin: uf, client: ff }, df = {}, hf = {}, mf = { type: "admin", routes: [ { method: "GET", path: "/", handler: "admin.get", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("read")] } } ] } }, { method: "POST", path: "/", handler: "admin.post", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("update")] } } ] } }, { method: "GET", path: "/config", handler: "admin.config", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("read")] } } ] } }, { method: "PUT", path: "/config", handler: "admin.updateConfig", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("settings")] } } ] } }, { method: "DELETE", path: "/config", handler: "admin.restoreConfig", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("settings")] } } ] } }, { method: "GET", path: "/slug", handler: "admin.getSlug", config: { policies: ["admin::isAuthenticatedAdmin"] } }, { method: "GET", path: "/:documentId", handler: "admin.getById", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("read")] } } ] } }, { method: "PUT", path: "/:documentId", handler: "admin.put", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("update")] } } ] } }, { method: "DELETE", path: "/:documentId", handler: "admin.delete", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("update")] } } ] } }, { method: "GET", path: "/content-type-items/:model", handler: "admin.getContentTypeItems", config: { policies: ["admin::isAuthenticatedAdmin"] } }, { method: "GET", path: "/settings/locale", handler: "admin.settingsLocale", config: { policies: ["admin::isAuthenticatedAdmin"] } }, { method: "GET", path: "/settings/config", handler: "admin.settingsConfig", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("settings")] } } ] } }, { method: "GET", path: "/settings/restart", handler: "admin.settingsRestart", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("settings")] } } ] } }, { method: "PUT", path: "/i18n/copy/:documentId/:source/:target", handler: "admin.fillFromOtherLocale", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("update")] } } ] } }, { method: "GET", path: "/i18n/item/read/:source/:target", handler: "admin.readNavigationItemFromLocale", config: { policies: [ { name: "admin::hasPermissions", config: { actions: [pe.render("read")] } } ] } } ] }, gf = { type: "content-api", routes: [ { method: "GET", path: "/render/:idOrSlug", handler: "client.render", config: { policies: [] } }, { method: "GET", path: "/render/:idOrSlug/:childUIKey", handler: "client.renderChild", config: { policies: [] } }, { method: "GET", path: "/", handler: "client.readAll", config: { policies: [] } } ] }, yf = { admin: mf, "content-api": gf }; function vf(e, t) { return de.has(process.env, e) ? process.env[e] : t; } function pt(e) { return process.env[e] ?? ""; } const wf = { int(e, t) { return de.has(process.env, e) ? parseInt(pt(e), 10) : t; }, float(e, t) { return de.has(process.env, e) ? parseFloat(pt(e)) : t; }, bool(e, t) { return de.has(process.env, e) ? pt(e) === "true" : t; }, json(e, t) { if (!de.has(process.env, e)) return t; try { return JSON.parse(pt(e)); } catch (n) { throw n instanceof Error ? new Error(`Invalid json environment variable ${e}: ${n.message}`) : n; } }, array(e, t) { if (!de.has(process.env, e)) return t; let n = pt(e); return n.startsWith("[") && n.endsWith("]") && (n = n.substring(1, n.length - 1)), n.split(",").map((r) => de.trim(de.trim(r, " "), '"')); }, date(e, t) { return de.has(process.env, e) ? new Date(pt(e)) : t; }, /** * Gets a value from env that matches oneOf provided values * @param {string} key * @param {string[]} expectedValues * @param {string|undefined} defaultValue * @returns {string|undefined} */ oneOf(e, t, n) { if (!t) throw new Error("env.oneOf requires expectedValues"); if (n && !t.includes(n)) throw new Error("env.oneOf requires defaultValue to be included in expectedValues"); const r = Ef(e, n); return t.includes(r) ? r : n; } }, Ef = Object.assign(vf, wf), bf = "id", xf = "documentId", Sf = { ID_ATTRIBUTE: bf, DOC_ID_ATTRIBUTE: xf }, Af = (e) => vu(strapi?.config?.get("api.responses.privateAttributes", []) ?? [], wu([], "options.privateAttributes", e)), _f = (e, t) => e?.attributes?.[t]?.private === !0 ? !0 : Af(e).includes(t), Va = (e) => e && ![ "media", "component", "relation", "dynamiczone" ].includes(e.type), Tf = (e) => e?.type === "media", Xa = (e) => e?.type === "relation", Cf = (e) => !!e && e.type === "dynamiczone", Za = (e) => !!e && Xa(e) && e.relation?.startsWith?.("morphTo"), wt = async (e, t, n) => { const { path: r = { raw: null, attribute: null }, schema: i, getModel: a } = t; let o = t.parent; const s = async (m, g, b) => { const T = { schema: a(b.__type), path: g, getModel: a, parent: o }; return wt(m, T, b); }, c = (m) => async (g, b, x) => wt(g, { schema: m, path: b, getModel: a, parent: o }, x), f = async (m, g, b) => { const _ = { schema: a("plugin::upload.file"), path: g, getModel: a, parent: o }; return wt(m, _, b); }, u = async (m, g, b, x) => wt(m, { schema: b, path: g, getModel: a, parent: o }, x), l = async (m, g, b) => { const T = { schema: a(b.__component), path: g, getModel: a, parent: o }; return wt(m, T, b); }; if (!$e(n) || oe(i)) return n; const p = Eu(n), d = Rf({ data: p }), h = Object.keys(p); for (let m = 0; m < h.length; m += 1) { const g = h[m], b = i.attributes[g], x = { ...r }; x.raw = oe(r.raw) ? g : `${r.raw}.${g}`, oe(b) || (x.attribute = oe(r.attribute) ? g : `${r.attribute}.${g}`); const T = { data: p, schema: i, key: g, value: p[g], attribute: b, path: x, getModel: a, parent: o }; await e(T, d); const _ = p[g]; if (!(oe(_) || oe(b))) { if (o = { schema: i, key: g, attribute: b, path: x }, Xa(b)) { const R = b.relation.toLowerCase().startsWith("morph") ? s : c(a(b.target)); if (We(_)) { const D = new Array(_.length); for (let S = 0; S < _.length; S += 1) D[S] = await R(e, x, _[S]); p[g] = D; } else p[g] = await R(e, x, _); continue; } if (Tf(b)) { if (We(_)) { const C = new Array(_.length); for (let R = 0; R < _.length; R += 1) C[R] = await f(e, x, _[R]); p[g] = C; } else p[g] = await f(e, x, _); continue; } if (b.type === "component") { const C = a(b.component); if (We(_)) { const R = new Array(_.length); for (let D = 0; D < _.length; D += 1) R[D] = await u(e, x, C, _[D]); p[g] = R; } else p[g] = await u(e, x, C, _); continue; } if (b.type === "dynamiczone" && We(_)) { const C = new Array(_.length); for (let R = 0; R < _.length; R += 1) C[R] = await l(e, x, _[R]); p[g] = C; continue; } } } return p; }, Rf = ({ data: e }) => ({ remove(t) { delete e[t]; }, set(t, n) { e[t] = n; } }); var Ff = De(wt), ve = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; function Ja(e) { return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e; } var $f = { exports: {} }; (function(e, t) { (function(n, r) { e.exports = r(vn, no); })(ve, function(n, r) { return function(i) { function a(s) { if (o[s]) return o[s].exports; var c = o[s] = { exports: {}, id: s, loaded: !1 }; return i[s].call(c.exports, c, c.exports, a), c.loaded = !0, c.exports; } var o = {}; return a.m = i, a.c = o, a.p = "", a(0); }([function(i, a, o) { i.exports = o(34); }, function(i, a, o) { var s = o(29)("wks"), c = o(33), f = o(2).Symbol, u = typeof f == "function", l = i.exports = function(p) { return s[p] || (s[p] = u && f[p] || (u ? f : c)("Symbol." + p)); }; l.store = s; }, function(i, a) { var o = i.exports = typeof window < "u" && window.Math == Math ? window : typeof self < "u" && self.Math == Math ? self : Function("return this")(); typeof __g == "number" && (__g = o); }, function(i, a, o) { var s = o(9); i.exports = function(c) { if (!s(c)) throw TypeError(c + " is not an object!"); return c; }; }, function(i, a, o) { i.exports = !o(24)(function() { return Object.defineProperty({}, "a", { get: function() { return 7; } }).a != 7; }); }, function(i, a, o) { var s = o(12), c = o(17); i.exports = o(4) ? function(f, u, l) { return s.f(f, u, c(1, l)); } : function(f, u, l) { return f[u] = l, f; }; }, function(i, a) { var o = i.exports = { version: "2.4.0" }; typeof __e == "number" && (__e = o); }, function(i, a, o) { var s = o(14); i.exports = function(c, f, u) { if (s(c), f === void 0) return c; switch (u) { case 1: return function(l) { return c.call(f, l); }; case 2: return function(l, p) { return c.call(f, l, p); }; case 3: return function(l, p, d) { return c.call(f, l, p, d); }; } return function() { return c.apply(f, arguments); }; }; }, function(i, a) { var o = {}.hasOwnProperty; i.exports = function(s, c) { return o.call(s, c); }; }, function(i, a) { i.exports = function(o) { return typeof o == "object" ? o !== null : typeof o == "function"; }; }, function(i, a) { i.exports = {}; }, function(i, a) { var o = {}.toString; i.exports = function(s) { return o.call(s).slice(8, -1); }; }, function(i, a, o) { var s = o(3), c = o(26), f = o(32), u = Object.defineProperty; a.f = o(4) ? Object.defineProperty : function(l, p, d) { if (s(l), p = f(p, !0), s(d), c) try { return u(l, p, d); } catch { } if ("get" in d || "set" in d) throw TypeError("Accessors not supported!"); return "value" in d && (l[p] = d.value), l; }; }, function(i, a, o) { var s = o(42), c = o(15); i.exports = function(f) { return s(c(f)); }; }, function(i, a) { i.exports = function(o) { if (typeof o != "function") throw TypeError(o + " is not a function!"); return o; }; }, function(i, a) { i.exports = function(o) { if (o == null) throw TypeError("Can't call method on " + o); return o; }; }, function(i, a, o) { var s = o(9), c = o(2).document, f = s(c) && s(c.createElement); i.exports = function(u) { return f ? c.createElement(u) : {}; }; }, function(i, a) { i.exports = function(o, s) { return { enumerable: !(1 & o), configurable: !(2 & o), writable: !(4 & o), value: s }; }; }, function(i, a, o) { var s = o(12).f, c = o(8), f = o(1)("toStringTag"); i.exports = function(u, l, p) { u && !c(u = p ? u : u.prototype, f) && s(u, f, { configurable: !0, value: l }); }; }, function(i, a, o) { var s = o(29)("keys"), c = o(33); i.exports = function(f) { return s[f] || (s[f] = c(f)); }; }, function(i, a) { var o = Math.ceil, s = Math.floor; i.exports = function(c) { return isNaN(c = +c) ? 0 : (c > 0 ? s : o)(c); }; }, function(i, a, o) { var s = o(11), c = o(1)("toStringTag"), f = s(/* @__PURE__ */ function() { return arguments; }()) == "Arguments", u = function(l, p) { try { return l[p]; } catch { } }; i.exports = function(l) { var p, d, h; return l === void 0 ? "Undefined" : l === null ? "Null" : typeof (d = u(p = Object(l), c)) == "string" ? d : f ? s(p) : (h = s(p)) == "Object" && typeof p.callee == "function" ? "Arguments" : h; }; }, function(i, a) { i.exports = "constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLoc