@lucidcms/plugin-pages
Version:
The official Pages plugin for Lucid
1,300 lines (1,273 loc) • 41.4 kB
JavaScript
// src/translations/en-gb.json
var en_gb_default = {
cannot_find_collection: "Cannot find the collection of {{collection}}.",
cannot_find_required_field_message: "Cannot find required fields for the pages plugin.",
cannot_have_self_as_parent_page_message: "A page cannot be its own parent, please select a different parent page.",
slug_cannot_be_slash_and_parent_page_set_message: "The slug cannot be / when a parent page is set.",
duplicate_slug_field_found_message: "Please ensure the slug field is unique within the collection.",
duplicate_slug_and_parent_page_field_found_message: "Another document in this collection has the same slug and parent page selected. Please ensure the slug field is unique within the collection.",
an_unknown_error_occurred_checking_for_duplicate_slugs: "An error occurred while checking for duplicate slugs.",
an_unknown_error_occurred_checking_for_circular_parents: "An error occurred while checking for circular parents.",
circular_parents_error_message: "The selected page is either a child/grandchild of this one. Please select a different parent page.",
parent_page_not_found_or_doesnt_have_a_published_version: "The parent page document of the same version (draft/published) was not found, or doesnt have a slug.",
an_unknown_error_occurred_getting_parent_fields: "An error occurred while getting the parent page fields.",
an_unknown_error_occurred_getting_descendant_fields: "An error occurred while getting the descendant page fields.",
an_unknown_error_occurred_updating_fullslug_fields: "An error occurred while updating the fullSlug children fields.",
slug_field_validation_error_message: "The slug field may only contain letters, numbers, underscores, and hyphens.",
an_unknown_error_occurred_getting_document_version_fields: "An error occurred while getting the document version fields.",
full_slug: "Full Slug",
slug: "Slug",
parent_page: "Parent Page",
field_required: "This field is required."
};
// src/translations/index.ts
var selectedLang = en_gb_default;
var T = (key, data) => {
const translation = selectedLang[key];
if (!translation) {
return key;
}
if (!data) {
return translation;
}
return translation.replace(
/\{\{(\w+)\}\}/g,
(_, p1) => data[p1]
);
};
var translations_default = T;
// src/constants.ts
var PLUGIN_KEY = "plugin-pages";
var LUCID_VERSION = "0.x.x";
var constants_default = {
collectionFieldBrickId: "collection-pseudo-brick",
fields: {
parentPage: {
key: "parentPage"
},
slug: {
key: "slug"
},
fullSlug: {
key: "fullSlug"
}
}
};
// src/plugin.ts
import { logger } from "@lucidcms/core";
// src/services/register-fields.ts
import { z } from "@lucidcms/core";
var registerFields = (collection, config) => {
collection.addText(constants_default.fields.fullSlug.key, {
details: {
label: translations_default("full_slug")
},
config: {
useTranslations: config.useTranslations,
isHidden: !config.displayFullSlug,
isDisabled: true
},
displayInListing: config.displayFullSlug
}).addText(constants_default.fields.slug.key, {
details: {
label: translations_default("slug")
},
config: {
useTranslations: config.useTranslations,
isHidden: false,
isDisabled: false
},
validation: {
required: true,
zod: z.union([
z.literal("/"),
z.string().regex(
/^[a-zA-Z0-9_-]+$/,
translations_default("slug_field_validation_error_message")
)
])
},
displayInListing: true
}).addDocument(constants_default.fields.parentPage.key, {
collection: collection.key,
details: {
label: translations_default("parent_page")
},
config: {
isHidden: false,
isDisabled: false
}
});
};
var register_fields_default = registerFields;
// src/services/plugin-options.ts
var pluginOptions = (given) => {
return {
collections: given.collections.map((c) => ({
collectionKey: c.collectionKey,
useTranslations: c?.useTranslations ?? false,
displayFullSlug: c?.displayFullSlug ?? false
// fallbackSlugSource: c?.fallbackSlugSource ?? undefined,
}))
};
};
var plugin_options_default = pluginOptions;
// src/services/get-target-collection.ts
var getTargetCollection = (data) => {
const targetCollection = data.options.collections.find(
(c) => c.collectionKey === data.collectionKey
);
if (!targetCollection) {
return {
error: {
type: "basic",
status: 500,
message: translations_default("cannot_find_collection", {
collection: data.collectionKey
})
},
data: void 0
};
}
return {
error: void 0,
data: targetCollection
};
};
var get_target_collection_default = getTargetCollection;
// src/services/get-parent-fields.ts
import { prefixGeneratedColName } from "@lucidcms/core/helpers";
var getParentFields = async (context, data) => {
try {
const { version: versionTable, documentFields: fieldsTable } = data.tables;
const slugColumn = prefixGeneratedColName(constants_default.fields.slug.key);
const parentPageColumn = prefixGeneratedColName(
constants_default.fields.parentPage.key
);
const fullSlugColumn = prefixGeneratedColName(
constants_default.fields.fullSlug.key
);
const parentFields = await context.db.selectFrom(fieldsTable).innerJoin(
versionTable,
`${versionTable}.id`,
`${fieldsTable}.document_version_id`
).select([
`${fieldsTable}.${slugColumn}`,
`${fieldsTable}.${fullSlugColumn}`,
`${fieldsTable}.${parentPageColumn}`,
`${versionTable}.document_id`,
`${fieldsTable}.locale`
]).where(`${versionTable}.document_id`, "=", data.fields.parentPage.value).where(`${versionTable}.type`, "=", data.versionType).execute();
if (!parentFields || parentFields.length === 0) {
return {
error: {
type: "basic",
status: 404,
message: translations_default(
"parent_page_not_found_or_doesnt_have_a_published_version"
),
errorResponse: {
body: {
fields: [
{
key: constants_default.fields.parentPage.key,
localeCode: data.defaultLocale,
message: translations_default(
"parent_page_not_found_or_doesnt_have_a_published_version"
)
}
]
}
}
},
data: void 0
};
}
return {
error: void 0,
data: parentFields
};
} catch (error) {
return {
error: {
type: "basic",
status: 500,
message: translations_default("an_unknown_error_occurred_getting_parent_fields")
},
data: void 0
};
}
};
var get_parent_fields_default = getParentFields;
// src/utils/build-fullslug-from-fullslug.ts
var buildFullSlug = (data) => {
if (data.slug === null || data.slug === void 0) return null;
let result = data.slug;
const targetParentFullSlugField = data.parentFields.find((field) => {
return field.locale === data.targetLocale;
});
if (targetParentFullSlugField?._fullSlug) {
result = `${targetParentFullSlugField._fullSlug}/${data.slug}`;
}
if (!result.startsWith("/")) {
result = `/${result}`;
}
result = result.replace(/\/\//g, "/");
return result;
};
var build_fullslug_from_fullslug_default = buildFullSlug;
// src/services/construct-parent-fullslug.ts
var constructParentFullSlug = (data) => {
const fullSlug = data.localisation.locales.reduce(
(acc, locale) => {
acc[locale.code] = null;
return acc;
},
{}
);
if (data.collection.useTranslations && data.fields.slug.translations) {
for (let i = 0; i < data.localisation.locales.length; i++) {
const locale = data.localisation.locales[i];
if (!locale) continue;
fullSlug[locale.code] = build_fullslug_from_fullslug_default({
parentFields: data.parentFields || [],
targetLocale: locale.code,
slug: data.fields.slug.translations[locale.code]
});
}
} else {
fullSlug[data.localisation.defaultLocale] = build_fullslug_from_fullslug_default({
parentFields: data.parentFields || [],
targetLocale: data.localisation.defaultLocale,
slug: data.fields.slug.value
});
}
return {
error: void 0,
data: fullSlug
};
};
var construct_parent_fullslug_default = constructParentFullSlug;
// src/services/set-full-slug.ts
var setFullSlug = (data) => {
if (data.collection.useTranslations) {
data.fields.fullSlug.translations = data.fullSlug;
} else {
data.fields.fullSlug.value = data.fullSlug[data.defaultLocale];
}
return {
error: void 0,
data: void 0
};
};
var set_full_slug_default = setFullSlug;
// src/services/get-descendant-fields.ts
import { prefixGeneratedColName as prefixGeneratedColName2 } from "@lucidcms/core/helpers";
import { inspect } from "node:util";
var getDescendantFields = async (context, data) => {
try {
const { documentFields: fieldsTable, version: versionTable } = data.tables;
const slugColumn = prefixGeneratedColName2(constants_default.fields.slug.key);
const fullSlugColumn = prefixGeneratedColName2(
constants_default.fields.fullSlug.key
);
const parentPageColumn = prefixGeneratedColName2(
constants_default.fields.parentPage.key
);
const descendants = await context.db.with(
"recursive_cte",
(db) => db.selectFrom(fieldsTable).innerJoin(
versionTable,
`${versionTable}.id`,
`${fieldsTable}.document_version_id`
).select([
`${versionTable}.document_id as document_id`,
`${fieldsTable}.${parentPageColumn} as parent_id`,
`${fieldsTable}.document_version_id`
]).where(
({ eb }) => (
// @ts-expect-error
eb(`${fieldsTable}.${parentPageColumn}`, "in", data.ids)
)
).where(`${versionTable}.type`, "=", data.versionType).unionAll(
db.selectFrom(fieldsTable).innerJoin(
versionTable,
`${versionTable}.id`,
`${fieldsTable}.document_version_id`
).innerJoin(
// @ts-expect-error
"recursive_cte as rc",
"rc.document_id",
`${fieldsTable}.${parentPageColumn}`
).select([
`${versionTable}.document_id as document_id`,
`${fieldsTable}.${parentPageColumn} as parent_id`,
`${fieldsTable}.document_version_id`
]).where(`${versionTable}.type`, "=", data.versionType)
)
).selectFrom("recursive_cte").select((eb) => [
"document_id",
"document_version_id",
context.config.db.jsonArrayFrom(
eb.selectFrom(fieldsTable).innerJoin(
versionTable,
`${versionTable}.id`,
`${fieldsTable}.document_version_id`
).select([
`${fieldsTable}.locale`,
`${fieldsTable}.${slugColumn} as _slug`,
`${fieldsTable}.${fullSlugColumn} as _fullSlug`,
`${fieldsTable}.${parentPageColumn} as _parentPage`
]).whereRef(
`${versionTable}.document_id`,
"=",
"recursive_cte.document_id"
).where(`${versionTable}.type`, "=", data.versionType)
).as("rows")
]).where(({ eb }) => eb("document_id", "not in", data.ids)).execute();
return {
error: void 0,
data: descendants.filter((d, i, self) => {
return self.findIndex(
(e) => e.document_id === d.document_id && e.document_version_id === d.document_version_id
) === i;
})
};
} catch (error) {
console.log(
inspect(error, {
depth: Number.POSITIVE_INFINITY,
colors: true
})
);
return {
error: {
type: "basic",
status: 500,
message: translations_default("an_unknown_error_occurred_getting_descendant_fields")
},
data: void 0
};
}
};
var get_descendant_fields_default = getDescendantFields;
// src/utils/build-fullslug-from-slugs.ts
var buildFullSlugFromSlugs = (data) => {
const rowForLocale = data.currentDescendant.rows.find(
(row) => row.locale === data.targetLocale
);
if (!rowForLocale || !rowForLocale._slug) return null;
const slugFieldValue = rowForLocale._slug;
const parentPageValue = rowForLocale._parentPage;
if (!parentPageValue) {
return postSlugFormat(
joinSlugs(data.topLevelFullSlug || "", slugFieldValue)
);
}
const parentDescendant = data.descendants.find(
(descendant) => descendant.document_id === parentPageValue
);
if (!parentDescendant) {
return postSlugFormat(
joinSlugs(data.topLevelFullSlug || "", slugFieldValue)
);
}
const parentFullSlug = buildFullSlugFromSlugs({
targetLocale: data.targetLocale,
currentDescendant: parentDescendant,
descendants: data.descendants,
topLevelFullSlug: data.topLevelFullSlug
});
return postSlugFormat(
joinSlugs(parentFullSlug || data.topLevelFullSlug || "", slugFieldValue)
);
};
var joinSlugs = (...parts) => {
return parts.filter(Boolean).join("/").replace(/\/+/g, "/");
};
var postSlugFormat = (slug) => {
if (!slug) return null;
let res = slug;
if (!res.startsWith("/")) {
res = `/${res}`;
}
return res.replace(/\/\//g, "/");
};
var build_fullslug_from_slugs_default = buildFullSlugFromSlugs;
// src/services/construct-child-fullslugs.ts
var constructChildFullSlug = (data) => {
const documentFullSlugs = [];
for (const descendant of data.descendants) {
const fullSlug = {};
if (data.collection.useTranslations) {
if (data.parentFullSlugField !== void 0 && !data.parentFullSlugField.translations)
break;
for (const locale of data.localisation.locales) {
const currentFullSlugValue = data.parentFullSlugField?.translations?.[locale.code];
if (data.parentFullSlugField !== void 0 && !currentFullSlugValue) {
continue;
}
fullSlug[locale.code] = build_fullslug_from_slugs_default({
targetLocale: locale.code,
currentDescendant: descendant,
descendants: data.descendants,
topLevelFullSlug: currentFullSlugValue
});
}
} else {
if (data.parentFullSlugField !== void 0 && !data.parentFullSlugField.value)
break;
fullSlug[data.localisation.defaultLocale] = build_fullslug_from_slugs_default({
targetLocale: data.localisation.defaultLocale,
currentDescendant: descendant,
descendants: data.descendants,
topLevelFullSlug: data.parentFullSlugField?.value
});
}
documentFullSlugs.push({
documentId: descendant.document_id,
versionId: descendant.document_version_id,
fullSlugs: fullSlug
});
}
return {
error: void 0,
data: documentFullSlugs
};
};
var construct_child_fullslugs_default = constructChildFullSlug;
// src/services/update-fullslug-fields.ts
import { prefixGeneratedColName as prefixGeneratedColName3 } from "@lucidcms/core/helpers";
var updateFullSlugFields = async (context, data) => {
try {
const { documentFields: fieldsTable, version: versionTable } = data.tables;
const fullSlugColumn = prefixGeneratedColName3(
constants_default.fields.fullSlug.key
);
const updateFullSlugsPromises = [];
for (const doc of data.docFullSlugs) {
for (const [locale, fullSlug] of Object.entries(doc.fullSlugs)) {
updateFullSlugsPromises.push(
context.db.updateTable(fieldsTable).set({ [fullSlugColumn]: fullSlug }).where(
(eb) => eb.exists(
eb.selectFrom(versionTable).selectAll().where(`${versionTable}.id`, "=", doc.versionId).where(`${versionTable}.document_id`, "=", doc.documentId).where(`${versionTable}.type`, "=", data.versionType)
)
).where("document_version_id", "=", doc.versionId).where("locale", "=", locale).execute()
);
}
}
await Promise.all(updateFullSlugsPromises);
return {
error: void 0,
data: void 0
};
} catch (error) {
return {
error: {
type: "basic",
status: 500,
message: translations_default("an_unknown_error_occurred_updating_fullslug_fields")
},
data: void 0
};
}
};
var update_fullslug_fields_default = updateFullSlugFields;
// src/services/get-document-version-fields.ts
import { prefixGeneratedColName as prefixGeneratedColName4 } from "@lucidcms/core/helpers";
var getDocumentVersionFields = async (context, data) => {
try {
const { version: versionTable, documentFields: fieldsTable } = data.tables;
const slugColumn = prefixGeneratedColName4(constants_default.fields.slug.key);
const fullSlugColumn = prefixGeneratedColName4(
constants_default.fields.fullSlug.key
);
const parentPageColumn = prefixGeneratedColName4(
constants_default.fields.parentPage.key
);
const fields = await context.db.selectFrom(fieldsTable).innerJoin(
versionTable,
`${versionTable}.id`,
`${fieldsTable}.document_version_id`
).select([
`${fieldsTable}.locale`,
`${versionTable}.document_id`,
`${fieldsTable}.${slugColumn}`,
`${fieldsTable}.${fullSlugColumn}`,
`${fieldsTable}.${parentPageColumn}`
]).where(`${versionTable}.document_id`, "=", data.documentId).where(`${versionTable}.id`, "=", data.versionId).where(`${versionTable}.type`, "=", data.versionType).execute();
if (!fields || fields.length === 0) {
return {
error: void 0,
data: null
};
}
return {
error: void 0,
data: fields
};
} catch (error) {
return {
error: {
type: "basic",
status: 500,
message: translations_default("an_unknown_error_occurred_getting_document_version_fields")
},
data: void 0
};
}
};
var get_document_version_fields_default = getDocumentVersionFields;
// src/services/checks/duplicate-slug-parents.ts
import { prefixGeneratedColName as prefixGeneratedColName5 } from "@lucidcms/core/helpers";
var checkDuplicateSlugParents = async (context, data) => {
try {
const {
document: documentTable,
version: versionTable,
documentFields: fieldsTable
} = data.tables;
const slugConditions = Object.entries(
data.fields.slug.translations || {}
).map(([localeCode, slug]) => ({
localeCode,
slug
}));
if (data.fields.slug.value) {
slugConditions.push({
localeCode: context.config.localisation.defaultLocale,
slug: data.fields.slug.value
});
}
const slugColumn = prefixGeneratedColName5(constants_default.fields.slug.key);
const parentPageColumn = prefixGeneratedColName5(
constants_default.fields.parentPage.key
);
const duplicates = await context.db.selectFrom(documentTable).leftJoin(
versionTable,
// @ts-expect-error
`${versionTable}.document_id`,
`${documentTable}.id`
).leftJoin(
fieldsTable,
// @ts-expect-error
`${fieldsTable}.document_version_id`,
`${versionTable}.id`
).select([
`${documentTable}.id`,
`${documentTable}.collection_key`,
`${fieldsTable}.${slugColumn}`,
`${fieldsTable}.locale`,
`${fieldsTable}.${parentPageColumn}`
]).where(
({ eb, and, or }) => and([
or(
slugConditions.map(
({ localeCode, slug }) => and([
eb(`${fieldsTable}.${slugColumn}`, "=", slug),
localeCode ? eb(`${fieldsTable}.locale`, "=", localeCode) : eb(`${fieldsTable}.locale`, "is", null)
])
)
),
data.fields.parentPage.value ? eb(
`${fieldsTable}.${parentPageColumn}`,
"=",
data.fields.parentPage.value
) : eb(`${fieldsTable}.${parentPageColumn}`, "is", null),
eb(`${versionTable}.type`, "=", data.versionType)
])
).where(`${documentTable}.id`, "!=", data.documentId || null).where(`${documentTable}.collection_key`, "=", data.collectionKey).where(
`${documentTable}.is_deleted`,
"=",
context.config.db.getDefault("boolean", "false")
).execute();
if (duplicates.length > 0) {
const fieldErrors = [];
for (const duplicate of duplicates) {
fieldErrors.push({
key: constants_default.fields.slug.key,
localeCode: duplicate.locale || void 0,
message: duplicate[parentPageColumn] === null ? translations_default("duplicate_slug_field_found_message") : translations_default("duplicate_slug_and_parent_page_field_found_message")
});
}
return {
error: {
type: "basic",
status: 400,
message: translations_default("duplicate_slug_field_found_message"),
errorResponse: {
body: {
fields: fieldErrors
}
}
},
data: void 0
};
}
return {
error: void 0,
data: void 0
};
} catch (error) {
return {
error: {
type: "basic",
status: 500,
message: translations_default("an_unknown_error_occurred_checking_for_duplicate_slugs")
},
data: void 0
};
}
};
var duplicate_slug_parents_default = checkDuplicateSlugParents;
// src/services/checks/root-slug-withparent.ts
var checkRootSlugWithParent = (data) => {
if (data.collection.useTranslations && data.fields.slug.translations) {
const fieldErrors = [];
for (const [key, value] of Object.entries(data.fields.slug.translations)) {
if (value === "/" && data.fields.parentPage.value) {
fieldErrors.push({
key: constants_default.fields.slug.key,
localeCode: key,
message: translations_default("slug_cannot_be_slash_and_parent_page_set_message")
});
}
}
if (fieldErrors.length > 0) {
return {
error: {
type: "basic",
status: 400,
message: translations_default("slug_cannot_be_slash_and_parent_page_set_message"),
errorResponse: {
body: {
fields: fieldErrors
}
}
},
data: void 0
};
}
} else if (data.fields.slug.value === "/" && data.fields.parentPage.value) {
return {
error: {
type: "basic",
status: 400,
message: translations_default("slug_cannot_be_slash_and_parent_page_set_message"),
errorResponse: {
body: {
fields: [
{
key: constants_default.fields.parentPage.key,
message: translations_default("slug_cannot_be_slash_and_parent_page_set_message")
}
]
}
}
},
data: void 0
};
}
return {
error: void 0,
data: void 0
};
};
var root_slug_withparent_default = checkRootSlugWithParent;
// src/services/checks/page-is-parent-of-self.ts
var checkParentIsPageOfSelf = (data) => {
if (data.fields.parentPage.value && data.fields.parentPage.value === data.documentId) {
return {
error: {
type: "basic",
status: 400,
message: translations_default("cannot_have_self_as_parent_page_message"),
errorResponse: {
body: {
fields: [
{
key: constants_default.fields.parentPage.key,
localeCode: data.defaultLocale,
//* parentPage doesnt use translations so always use default locale
message: translations_default("cannot_have_self_as_parent_page_message")
}
]
}
}
},
data: void 0
};
}
return {
error: void 0,
data: void 0
};
};
var page_is_parent_of_self_default = checkParentIsPageOfSelf;
// src/services/checks/check-fields-exist.ts
var checkFieldsExist = (data) => {
const fieldErrors = [];
if (data.fields.slug === void 0) {
fieldErrors.push({
key: "slug",
localeCode: null,
message: translations_default("field_required")
});
}
if (data.fields.parentPage === void 0) {
fieldErrors.push({
key: "parentPage",
localeCode: null,
message: translations_default("field_required")
});
}
if (data.fields.fullSlug === void 0) {
fieldErrors.push({
key: "fullSlug",
localeCode: null,
message: translations_default("field_required")
});
}
if (fieldErrors.length) {
return {
error: {
type: "basic",
message: translations_default("cannot_find_required_field_message"),
status: 400,
errorResponse: {
body: {
fields: fieldErrors
}
}
},
data: void 0
};
}
return {
error: void 0,
data: {
slug: data.fields.slug,
parentPage: data.fields.parentPage,
fullSlug: data.fields.fullSlug
}
};
};
var check_fields_exist_default = checkFieldsExist;
// src/services/checks/circular-parents.ts
import { prefixGeneratedColName as prefixGeneratedColName6 } from "@lucidcms/core/helpers";
var checkCircularParents = async (context, data) => {
try {
if (!data.documentId || !data.fields.parentPage.value) {
return {
error: void 0,
data: void 0
};
}
const { version: versionTable, documentFields: fieldsTable } = data.tables;
const parentPageField = prefixGeneratedColName6(
constants_default.fields.parentPage.key
);
const result = await context.db.with(
"ancestors",
(db) => db.selectFrom(fieldsTable).innerJoin(
versionTable,
`${versionTable}.id`,
`${fieldsTable}.document_version_id`
).select([
`${versionTable}.document_id as current_id`,
`${fieldsTable}.${parentPageField} as parent_id`
]).where(`${fieldsTable}.locale`, "=", data.defaultLocale).where(`${versionTable}.type`, "=", data.versionType).where(
`${versionTable}.document_id`,
"=",
data.fields.parentPage.value
).unionAll(
db.selectFrom(fieldsTable).innerJoin(
versionTable,
`${versionTable}.id`,
`${fieldsTable}.document_version_id`
).innerJoin(
// @ts-expect-error
"ancestors",
"ancestors.parent_id",
`${versionTable}.document_id`
).select([
`${versionTable}.document_id as current_id`,
`${fieldsTable}.${parentPageField} as parent_id`
]).where(`${fieldsTable}.locale`, "=", data.defaultLocale).where(`${versionTable}.type`, "=", data.versionType)
)
).selectFrom("ancestors").select("parent_id").where("parent_id", "=", data.documentId).executeTakeFirst();
if (result) {
return {
error: {
type: "basic",
status: 400,
message: translations_default("circular_parents_error_message"),
errorResponse: {
body: {
fields: [
{
key: constants_default.fields.parentPage.key,
localeCode: data.defaultLocale,
//* parentPage doesnt use translations so always use default locale
message: translations_default("circular_parents_error_message")
}
]
}
}
},
data: void 0
};
}
return {
error: void 0,
data: void 0
};
} catch (error) {
return {
error: {
type: "basic",
status: 500,
message: translations_default("an_unknown_error_occurred_checking_for_circular_parents")
},
data: void 0
};
}
};
var circular_parents_default = checkCircularParents;
// src/services/hooks/before-upsert-handler.ts
var beforeUpsertHandler = (options) => async (context, data) => {
const targetCollectionRes = get_target_collection_default({
options,
collectionKey: data.meta.collectionKey
});
if (targetCollectionRes.error) {
return {
error: void 0,
data: data.data
};
}
const tablesRes = data.meta.collection.tableNames;
if (tablesRes.error) return tablesRes;
const checkFieldsExistRes = check_fields_exist_default({
fields: {
slug: data.data.fields?.find(
(f) => f.key === constants_default.fields.slug.key && f.type === "text"
),
parentPage: data.data.fields?.find(
(f) => f.key === constants_default.fields.parentPage.key && f.type === "document"
),
//* dont care what this value is - only needed to update translations/value
fullSlug: data.data.fields?.find(
(f) => f.key === constants_default.fields.fullSlug.key && f.type === "text"
)
}
});
if (checkFieldsExistRes.error) return checkFieldsExistRes;
const { slug, parentPage, fullSlug } = checkFieldsExistRes.data;
const checkParentIsPageOfSelfRes = page_is_parent_of_self_default({
defaultLocale: context.config.localisation.defaultLocale,
documentId: data.data.documentId,
fields: {
parentPage
}
});
if (checkParentIsPageOfSelfRes.error) return checkParentIsPageOfSelfRes;
const checkRootSlugWithParentRes = root_slug_withparent_default({
collection: targetCollectionRes.data,
defaultLocale: context.config.localisation.defaultLocale,
fields: {
slug,
parentPage
}
});
if (checkRootSlugWithParentRes.error) return checkRootSlugWithParentRes;
const checkDuplicateSlugParentsRes = await duplicate_slug_parents_default(
context,
{
documentId: data.data.documentId,
versionId: data.data.versionId,
versionType: data.data.versionType,
collectionKey: targetCollectionRes.data.collectionKey,
fields: {
slug,
parentPage
},
tables: tablesRes.data
}
);
if (checkDuplicateSlugParentsRes.error) return checkDuplicateSlugParentsRes;
let parentFieldsData = [];
if (parentPage.value) {
const circularParentsRes = await circular_parents_default(context, {
documentId: data.data.documentId,
versionType: data.data.versionType,
defaultLocale: context.config.localisation.defaultLocale,
fields: {
parentPage
},
tables: tablesRes.data
});
if (circularParentsRes.error) return circularParentsRes;
const parentFieldsRes = await get_parent_fields_default(context, {
defaultLocale: context.config.localisation.defaultLocale,
versionType: data.data.versionType,
fields: {
parentPage
},
tables: tablesRes.data
});
if (parentFieldsRes.error) return parentFieldsRes;
parentFieldsData = parentFieldsRes.data;
}
const fullSlugRes = construct_parent_fullslug_default({
parentFields: parentFieldsData,
localisation: context.config.localisation,
collection: targetCollectionRes.data,
fields: {
slug
}
});
if (fullSlugRes.error) return fullSlugRes;
set_full_slug_default({
fullSlug: fullSlugRes.data,
defaultLocale: context.config.localisation.defaultLocale,
collection: targetCollectionRes.data,
fields: {
fullSlug
}
});
return {
error: void 0,
data: data.data
};
};
var before_upsert_handler_default = beforeUpsertHandler;
// src/services/hooks/after-upsert-handler.ts
var afterUpsertHandler = (options) => async (context, data) => {
const targetCollectionRes = get_target_collection_default({
options,
collectionKey: data.meta.collectionKey
});
if (targetCollectionRes.error) {
return {
error: void 0,
data: void 0
};
}
const tablesRes = data.meta.collection.tableNames;
if (tablesRes.error) return tablesRes;
const descendantsRes = await get_descendant_fields_default(context, {
ids: [data.data.documentId],
versionType: data.data.versionType,
tables: tablesRes.data
});
if (descendantsRes.error) return descendantsRes;
if (descendantsRes.data.length === 0) {
return {
error: void 0,
data: void 0
};
}
const currentFullSlugField = data.data.fields.find((field) => {
return field.key === constants_default.fields.fullSlug.key;
});
if (!currentFullSlugField) {
return {
error: void 0,
data: void 0
};
}
const docFullSlugsRes = construct_child_fullslugs_default({
descendants: descendantsRes.data,
localisation: context.config.localisation,
parentFullSlugField: currentFullSlugField,
collection: targetCollectionRes.data
});
if (docFullSlugsRes.error) return docFullSlugsRes;
await update_fullslug_fields_default(context, {
docFullSlugs: docFullSlugsRes.data,
versionType: data.data.versionType,
tables: tablesRes.data
});
return {
error: void 0,
data: void 0
};
};
var after_upsert_handler_default = afterUpsertHandler;
// src/services/hooks/before-delete-handler.ts
var beforeDeleteHandler = (options) => async (context, data) => {
const targetCollectionRes = get_target_collection_default({
options,
collectionKey: data.meta.collectionKey
});
if (targetCollectionRes.error) {
return {
error: void 0,
data: void 0
};
}
const tablesRes = data.meta.collection.tableNames;
if (tablesRes.error) return tablesRes;
const versionTypes = ["draft", "published"];
for (const versionType of versionTypes) {
const descendantsRes = await get_descendant_fields_default(context, {
ids: data.data.ids,
versionType,
tables: tablesRes.data
});
if (descendantsRes.error) return descendantsRes;
if (descendantsRes.data.length === 0) {
continue;
}
const docFullSlugsRes = construct_child_fullslugs_default({
descendants: descendantsRes.data,
localisation: context.config.localisation,
collection: targetCollectionRes.data
});
if (docFullSlugsRes.error) return docFullSlugsRes;
await update_fullslug_fields_default(context, {
docFullSlugs: docFullSlugsRes.data,
versionType,
tables: tablesRes.data
});
}
return {
error: void 0,
data: void 0
};
};
var before_delete_handler_default = beforeDeleteHandler;
// src/utils/field-res-to-schema.ts
var fieldResToSchema = (key, useTranslations, defaultLocale, items) => {
const fieldType = getFieldTypeFromKey(key);
if (!fieldType) {
throw new Error(`Unable to determine field type for key: ${key}`);
}
const result = {
key,
type: fieldType
};
if (useTranslations) {
result.translations = {};
for (const item of items) {
if (fieldType === "text") {
result.translations[item.locale] = item[`_${key}`];
} else if (fieldType === "document") {
result.translations[item.locale] = item[`_${key}`];
}
}
} else {
const defaultItem = items.find((item) => item.locale === defaultLocale) || items[0];
if (fieldType === "text") {
result.value = defaultItem[`_${key}`];
} else if (fieldType === "document") {
result.value = defaultItem[`_${key}`];
}
}
return result;
};
function getFieldTypeFromKey(key) {
switch (key) {
case "slug":
case "fullSlug":
return "text";
case "parentPage":
return "document";
default:
return void 0;
}
}
var field_res_to_schema_default = fieldResToSchema;
// src/services/hooks/version-promote.ts
var versionPromoteHandler = (options) => async (context, data) => {
const targetCollectionRes = get_target_collection_default({
options,
collectionKey: data.meta.collectionKey
});
if (targetCollectionRes.error) {
return {
error: void 0,
data: void 0
};
}
const tablesRes = data.meta.collection.tableNames;
if (tablesRes.error) return tablesRes;
let createFullSlug = true;
const docVersionFieldRes = await get_document_version_fields_default(context, {
documentId: data.data.documentId,
versionId: data.data.versionId,
versionType: data.data.versionType,
tables: tablesRes.data
});
if (docVersionFieldRes.error) return docVersionFieldRes;
if (docVersionFieldRes.data === null) createFullSlug = false;
const checkFieldsExistRes = check_fields_exist_default({
fields: {
slug: field_res_to_schema_default(
constants_default.fields.slug.key,
targetCollectionRes.data.useTranslations,
context.config.localisation.defaultLocale,
docVersionFieldRes.data || []
),
parentPage: field_res_to_schema_default(
constants_default.fields.parentPage.key,
false,
context.config.localisation.defaultLocale,
docVersionFieldRes.data || []
),
fullSlug: field_res_to_schema_default(
constants_default.fields.fullSlug.key,
targetCollectionRes.data.useTranslations,
context.config.localisation.defaultLocale,
docVersionFieldRes.data || []
)
}
});
if (checkFieldsExistRes.error) return checkFieldsExistRes;
const { slug, parentPage, fullSlug } = checkFieldsExistRes.data;
if (createFullSlug) {
const checkDuplicateSlugParentsRes = await duplicate_slug_parents_default(
context,
{
documentId: data.data.documentId,
versionId: data.data.versionId,
versionType: data.data.versionType,
collectionKey: targetCollectionRes.data.collectionKey,
fields: {
slug,
parentPage
},
tables: tablesRes.data
}
);
if (checkDuplicateSlugParentsRes.error)
return checkDuplicateSlugParentsRes;
let parentFieldsData = [];
if (parentPage.value) {
const circularParentsRes = await circular_parents_default(context, {
documentId: data.data.documentId,
versionType: data.data.versionType,
defaultLocale: context.config.localisation.defaultLocale,
fields: {
parentPage
},
tables: tablesRes.data
});
if (circularParentsRes.error) return circularParentsRes;
const parentFieldsRes = await get_parent_fields_default(context, {
defaultLocale: context.config.localisation.defaultLocale,
versionType: data.data.versionType,
fields: {
parentPage
},
tables: tablesRes.data
});
if (parentFieldsRes.error) return parentFieldsRes;
parentFieldsData = parentFieldsRes.data;
}
const fullSlugRes = construct_parent_fullslug_default({
parentFields: parentFieldsData,
localisation: context.config.localisation,
collection: targetCollectionRes.data,
fields: {
slug
}
});
if (fullSlugRes.error) return fullSlugRes;
set_full_slug_default({
fullSlug: fullSlugRes.data,
defaultLocale: context.config.localisation.defaultLocale,
collection: targetCollectionRes.data,
fields: {
fullSlug
}
});
const updateFullSlugRes = await update_fullslug_fields_default(context, {
docFullSlugs: [
{
documentId: data.data.documentId,
versionId: data.data.versionId,
fullSlugs: fullSlugRes.data
}
],
versionType: data.data.versionType,
tables: tablesRes.data
});
if (updateFullSlugRes.error) return updateFullSlugRes;
}
await after_upsert_handler_default(options)(context, {
meta: {
collection: data.meta.collection,
collectionKey: data.meta.collectionKey,
userId: data.meta.userId
},
data: {
documentId: data.data.documentId,
versionId: data.data.versionId,
versionType: data.data.versionType,
bricks: [],
fields: [slug, parentPage, fullSlug]
}
});
return {
error: void 0,
data: void 0
};
};
var version_promote_default = versionPromoteHandler;
// src/plugin.ts
var plugin = async (config, plugin2) => {
const options = plugin_options_default(plugin2);
for (const collectionConfig of options.collections) {
const collectionInstance = config.collections.find(
(c) => c.key === collectionConfig.collectionKey
);
if (!collectionInstance) {
logger("warn", {
message: translations_default("cannot_find_collection", {
collection: collectionConfig.collectionKey
}),
scope: PLUGIN_KEY
});
continue;
}
register_fields_default(collectionInstance, collectionConfig);
if (!collectionInstance.config.hooks) {
collectionInstance.config.hooks = [];
}
}
config.hooks.push({
service: "documents",
event: "beforeUpsert",
handler: before_upsert_handler_default(options)
});
config.hooks.push({
service: "documents",
event: "afterUpsert",
handler: after_upsert_handler_default(options)
});
config.hooks.push({
service: "documents",
event: "beforeDelete",
handler: before_delete_handler_default(options)
});
config.hooks.push({
service: "documents",
event: "versionPromote",
handler: version_promote_default(options)
});
return {
key: PLUGIN_KEY,
lucid: LUCID_VERSION,
config
};
};
var plugin_default = plugin;
// src/index.ts
var lucidPagesPlugin = (pluginOptions2) => (config) => plugin_default(config, pluginOptions2);
var index_default = lucidPagesPlugin;
export {
index_default as default
};
//# sourceMappingURL=index.js.map