strapi-plugin-navigation
Version:
Strapi - Navigation plugin
1,795 lines • 351 kB
JavaScript
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