UNPKG

@lucidcms/core

Version:

The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.

1,702 lines (1,679 loc) 46.5 kB
import { build_table_name_default, create_cdn_url_default, formatters_default, objectify_translations_default } from "./chunk-5BJFGYMM.js"; import "./chunk-FRZBD5RL.js"; import { tidy_zod_errors_default } from "./chunk-7SRFYA4B.js"; import { constants_default, translations_default } from "./chunk-7XW7FQ7W.js"; // src/libs/custom-fields/fields/checkbox.ts import z from "zod"; // src/libs/custom-fields/utils/zod-safe-parse.ts var modifyMessage = (errorMessage) => { return errorMessage.replace(/\n/g, " ").trim().replaceAll(" \u2192", " \u2192"); }; var zodSafeParse = (value, schema) => { const response = schema.safeParse(value); if (response?.success) { return { valid: true }; } return { valid: false, message: modifyMessage(tidy_zod_errors_default(response.error)) ?? translations_default("an_unknown_error_occurred_validating_the_field") }; }; var zod_safe_parse_default = zodSafeParse; // src/libs/custom-fields/custom-field.ts var CustomField = class { repeater = null; // Methods validate(props) { if (this.config.type === "tab") return { valid: true }; const fieldTypeRes = this.fieldTypeValidation(props.type); if (fieldTypeRes.valid === false) return fieldTypeRes; const requiredRes = this.requiredCheck(props.value); if (!requiredRes.valid) return requiredRes; const zodRes = this.zodCheck(props.value); if (!zodRes.valid) return zodRes; if (props.value === null || props.value === void 0) { return { valid: true }; } return this.cfSpecificValidation(props.value, props.relationData); } fieldTypeValidation(type) { if (this.errors.fieldType.condition?.(type)) { return { valid: false, message: translations_default("field_type_mismatch", { received: type, expected: this.config.type }) }; } return { valid: true }; } requiredCheck(value) { if (this.config.type === "tab") return { valid: true }; if (this.config.type === "repeater") return { valid: true }; if (this.config.validation?.required === true && this.errors.required.condition?.(value)) { return { valid: false, message: this.errors.required.message }; } return { valid: true }; } zodCheck(value) { if (this.config.type === "tab") return { valid: true }; if (this.config.type === "repeater") return { valid: true }; if (this.config.type === "media") return { valid: true }; if (this.config.type === "checkbox") return { valid: true }; if (this.config.type === "select") return { valid: true }; if (this.config.type === "colour") return { valid: true }; if (this.config.type === "link") return { valid: true }; if (this.config.type === "user") return { valid: true }; if (this.config.type === "wysiwyg") return { valid: true }; if (this.config.type === "document") return { valid: true }; if (!this.config.validation?.zod) return { valid: true }; return zod_safe_parse_default(value, this.config.validation?.zod); } // Getters get errors() { return { fieldType: { condition: (value) => value !== this.type, message: translations_default("field_type_mismatch", { received: "unknown", expected: this.config.type }) }, required: { condition: (value) => value === void 0 || value === null || value === "", message: translations_default("generic_field_required") }, zod: { message: translations_default("generic_field_invalid") } }; } }; var custom_field_default = CustomField; // src/libs/custom-fields/fields/checkbox.ts import merge from "lodash.merge"; // src/libs/custom-fields/utils/key-to-title.ts var keyToTitle = (key) => { if (typeof key !== "string") return key; const title = key.split(/[-_]/g).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "); return title; }; var key_to_title_default = keyToTitle; // src/libs/custom-fields/fields/checkbox.ts var CheckboxCustomField = class extends custom_field_default { type = "checkbox"; column = "bool_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, true: this.props?.details?.true, false: this.props?.details?.false }, config: { useTranslations: this.props?.config?.useTranslations ?? false, default: this.props?.config?.default ?? false, isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("boolean"), nullable: true, default: props.db.formatInsertValue( "boolean", this.config.config.default ) } ] }, error: void 0 }; } formatResponseValue(value) { return formatters_default.formatBoolean( Boolean(value) ?? this.config.config.default ); } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z.union([z.literal(1), z.literal(0), z.boolean()]); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; return { valid: true }; } // Getters get errors() { return merge(super.errors, { required: { condition: (value) => value === void 0 || value === null || value === 0, message: translations_default("checkbox_field_required") } }); } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var checkbox_default = CheckboxCustomField; // src/libs/custom-fields/fields/colour.ts import z2 from "zod"; var ColourCustomField = class extends custom_field_default { type = "colour"; column = "text_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary }, presets: this.props?.presets ?? [], config: { useTranslations: this.props?.config?.useTranslations ?? false, default: this.props?.config?.default ?? "", isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("text"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z2.string(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var colour_default = ColourCustomField; // src/libs/custom-fields/fields/datetime.ts import z3 from "zod"; import { isValid } from "date-fns"; var DatetimeCustomField = class extends custom_field_default { type = "datetime"; column = "text_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, config: { useTranslations: this.props?.config?.useTranslations ?? false, default: this.props?.config?.default ?? "", isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("timestamp"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z3.union([z3.string(), z3.number(), z3.date()]); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; const date = new Date(value); if (!isValid(date)) { return { valid: false, message: translations_default("field_date_invalid") }; } return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var datetime_default = DatetimeCustomField; // src/libs/custom-fields/fields/json.ts import z4 from "zod"; var JsonCustomField = class extends custom_field_default { type = "json"; column = "json_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, config: { useTranslations: this.props?.config?.useTranslations ?? false, default: this.props?.config?.default || {}, isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("json"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z4.record( z4.union([z4.string(), z4.number(), z4.symbol()]), z4.unknown() ); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var json_default = JsonCustomField; // src/libs/custom-fields/fields/link.ts import z5 from "zod"; var LinkCustomField = class extends custom_field_default { type = "link"; column = "text_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, config: { useTranslations: this.props?.config?.useTranslations ?? false, default: this.props?.config?.default ?? { url: null, label: null, target: null }, isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("json"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return { url: value?.url ?? this.config.config.default.url ?? null, label: value?.label ?? this.config.config.default.label ?? null, target: value?.target ?? this.config.config.default.target ?? null }; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z5.object({ url: z5.string().optional().nullable(), target: z5.string().optional().nullable(), label: z5.string().optional().nullable() }); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; const val = value; if (val.target && !constants_default.customFields.link.targets.includes(val.target)) { return { valid: false, message: translations_default("field_link_target_error_message", { valid: constants_default.customFields.link.targets.join(", ") }) }; } return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var link_default = LinkCustomField; // src/libs/custom-fields/fields/media.ts import z6 from "zod"; var MediaCustomField = class extends custom_field_default { type = "media"; column = "media_id"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary }, config: { useTranslations: this.props?.config?.useTranslations ?? false, isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("integer"), nullable: true, foreignKey: { table: "lucid_media", column: "id", onDelete: "set null" } } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? null; } formatResponseMeta(value, meta) { if (value === null || value === void 0) return null; return { id: value?.id ?? null, url: create_cdn_url_default(meta.host, value?.key ?? ""), key: value?.key ?? null, mimeType: value?.mime_type ?? null, extension: value?.file_extension ?? null, fileSize: value?.file_size ?? null, width: value?.width ?? null, height: value?.height ?? null, blurHash: value?.blur_hash ?? null, averageColour: value?.average_colour ?? null, isDark: formatters_default.formatBoolean(value?.is_dark ?? null), isLight: formatters_default.formatBoolean(value?.is_light ?? null), title: objectify_translations_default( value?.title_translations || [], meta.localisation.locales ), alt: objectify_translations_default( value?.alt_translations || [], meta.localisation.locales ), type: value?.type ?? null }; } cfSpecificValidation(value, relationData) { const valueSchema = z6.number(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; const findMedia = relationData?.find((m) => m.id === value); if (findMedia === void 0) { return { valid: false, message: translations_default("field_media_not_found") }; } if (this.config.validation?.extensions?.length) { const extension = findMedia.file_extension; if (!this.config.validation.extensions.includes(extension)) { return { valid: false, message: translations_default("field_media_extension", { extensions: this.config.validation.extensions.join(", ") }) }; } } if (this.config.validation?.type) { const type = findMedia.type; if (!type) { return { valid: false, message: translations_default("field_media_doenst_have_type") }; } if (this.config.validation.type !== type) { return { valid: false, message: translations_default("field_media_type", { type: this.config.validation.type }) }; } } if (this.config.validation?.width && findMedia.type === "image") { const width = findMedia.width; if (!width) { return { valid: false, message: translations_default("field_media_doenst_have_width") }; } if (this.config.validation.width.min && width < this.config.validation.width.min) { return { valid: false, message: translations_default("field_media_min_width", { min: this.config.validation.width.min }) }; } if (this.config.validation.width.max && width > this.config.validation.width.max) { return { valid: false, message: translations_default("field_media_max_width", { max: this.config.validation.width.max }) }; } } if (this.config.validation?.height && findMedia.type === "image") { const height = findMedia.height; if (!height) { return { valid: false, message: translations_default("field_media_doenst_have_height") }; } if (this.config.validation.height.min && height < this.config.validation.height.min) { return { valid: false, message: translations_default("field_media_min_height", { min: this.config.validation.height.min }) }; } if (this.config.validation.height.max && height > this.config.validation.height.max) { return { valid: false, message: translations_default("field_media_max_height", { max: this.config.validation.height.max }) }; } } return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return null; } }; var media_default = MediaCustomField; // src/libs/custom-fields/fields/number.ts import z7 from "zod"; var NumberCustomField = class extends custom_field_default { type = "number"; column = "int_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, config: { useTranslations: this.props?.config?.useTranslations ?? false, default: this.props?.config?.default, isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("integer"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z7.number(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var number_default = NumberCustomField; // src/libs/custom-fields/fields/repeater.ts var RepeaterCustomField = class extends custom_field_default { type = "repeater"; column = null; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary }, config: { isDisabled: this.props?.config?.isDisabled }, fields: [], validation: this.props?.validation }; } // Methods getSchemaDefinition() { return { data: { columns: [] }, error: void 0 }; } formatResponseValue() { return null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { if (Array.isArray(value) && typeof this.config.validation?.maxGroups === "number") { if (value.length > this.config.validation?.maxGroups) { return { valid: false, message: translations_default("repeater_max_groups_exceeded", { groups: this.config.validation.maxGroups }) }; } } if (Array.isArray(value) && typeof this.config.validation?.minGroups === "number") { if (this.config.validation?.minGroups > value.length) { return { valid: false, message: translations_default("repeater_groups_exceeded_min", { groups: this.config.validation.minGroups }) }; } } return { valid: true }; } get translationsEnabled() { return false; } get defaultValue() { return null; } }; var repeater_default = RepeaterCustomField; // src/libs/custom-fields/fields/select.ts import z8 from "zod"; import merge2 from "lodash.merge"; var SelectCustomField = class extends custom_field_default { type = "select"; column = "text_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, options: this.props?.options ?? [], config: { useTranslations: this.props?.config?.useTranslations ?? false, default: this.props?.config?.default ?? "", isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("text"), nullable: true } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z8.string(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; if (this.config.options) { const optionValues = this.config.options.map((option) => option.value); if (!optionValues.includes(value)) { return { valid: false, message: translations_default("please_ensure_a_valid_option_is_selected") }; } } return { valid: true }; } // Getters get errors() { return merge2(super.errors, { required: { message: translations_default("select_field_required") } }); } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var select_default = SelectCustomField; // src/libs/custom-fields/fields/text.ts import z9 from "zod"; var TextCustomField = class extends custom_field_default { type = "text"; column = "text_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, config: { useTranslations: this.props?.config?.useTranslations ?? true, default: this.props?.config?.default ?? "", isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("text"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z9.string(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var text_default = TextCustomField; // src/libs/custom-fields/fields/textarea.ts import z10 from "zod"; var TextareaCustomField = class extends custom_field_default { type = "textarea"; column = "text_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, config: { useTranslations: this.props?.config?.useTranslations ?? true, default: this.props?.config?.default ?? "", isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("text"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z10.string(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var textarea_default = TextareaCustomField; // src/libs/custom-fields/fields/user.ts import z11 from "zod"; var UserCustomField = class extends custom_field_default { type = "user"; column = "user_id"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary }, config: { useTranslations: this.props?.config?.useTranslations ?? false, isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("integer"), nullable: true, foreignKey: { table: "lucid_users", column: "id", onDelete: "set null" } } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? null; } formatResponseMeta(value, meta) { if (value === null || value === void 0) return null; return { email: value?.email ?? null, username: value?.username ?? null, firstName: value?.first_name ?? null, lastName: value?.last_name ?? null }; } cfSpecificValidation(value, relationData) { const valueSchema = z11.number(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; const findUser = relationData?.find((u) => u.id === value); if (findUser === void 0) { return { valid: false, message: translations_default("field_user_not_found") }; } return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return null; } }; var user_default = UserCustomField; // src/libs/custom-fields/fields/wysiwyg.ts import z12 from "zod"; import sanitizeHtml from "sanitize-html"; var WysiwygCustomField = class extends custom_field_default { type = "wysiwyg"; column = "text_value"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary, placeholder: this.props?.details?.placeholder }, config: { useTranslations: this.props?.config?.useTranslations ?? true, default: this.props?.config?.default ?? "", isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { return { data: { columns: [ { name: this.key, type: props.db.getDataType("text"), nullable: true, default: this.config.config.default } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? this.config.config.default ?? null; } formatResponseMeta() { return null; } cfSpecificValidation(value) { const valueSchema = z12.string(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; const sanitizedValue = sanitizeHtml(value); if (this.config.validation?.zod) { return zod_safe_parse_default(sanitizedValue, this.config.validation?.zod); } return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return this.config.config.default; } }; var wysiwyg_default = WysiwygCustomField; // src/libs/custom-fields/fields/document.ts import z13 from "zod"; var DocumentFieldsFormatter = formatters_default.get("document-fields"); var DocumentBricksFormatter = formatters_default.get("document-bricks"); var DocumentCustomField = class extends custom_field_default { type = "document"; column = "document_id"; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, collection: this.props.collection, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary }, config: { useTranslations: this.props?.config?.useTranslations ?? false, isHidden: this.props?.config?.isHidden, isDisabled: this.props?.config?.isDisabled }, validation: this.props?.validation }; } // Methods getSchemaDefinition(props) { const documentTableRes = build_table_name_default("document", { collection: this.config.collection }); if (documentTableRes.error) return documentTableRes; return { data: { columns: [ { name: this.key, type: props.db.getDataType("integer"), nullable: true, foreignKey: { table: documentTableRes.data, column: "id", onDelete: "set null" } } ] }, error: void 0 }; } formatResponseValue(value) { return value ?? null; } formatResponseMeta(value, meta) { if (value === null || value === void 0) return null; const collection = meta.config.collections.find( (c) => c.key === this.props.collection ); if (!collection || !value) { return { id: value?.document_id ?? null, collectionKey: value?.collection_key ?? null, fields: null }; } const documentFields = DocumentFieldsFormatter.objectifyFields( DocumentBricksFormatter.formatDocumentFields({ bricksQuery: value, bricksSchema: collection.bricksTableSchema, relationMetaData: {}, collection, config: meta.config }) ); return { id: value?.id ?? null, collectionKey: value?.collection_key ?? null, fields: Object.keys(documentFields).length > 0 ? documentFields : null }; } cfSpecificValidation(value, relationData) { const valueSchema = z13.number(); const valueValidate = zod_safe_parse_default(value, valueSchema); if (!valueValidate.valid) return valueValidate; const findDocument = relationData?.find( (d) => d.id === value && d.collection_key === this.config.collection ); if (findDocument === void 0) { return { valid: false, message: translations_default("field_document_not_found") }; } return { valid: true }; } get translationsEnabled() { return this.config.config.useTranslations; } get defaultValue() { return null; } }; var document_default = DocumentCustomField; // src/libs/builders/field-builder/index.ts var FieldBuilder = class { fields = /* @__PURE__ */ new Map(); repeaterStack = []; meta = { fieldKeys: [], repeaterDepth: {} }; // Custom Fields addRepeater(key, props) { this.meta.repeaterDepth[key] = this.repeaterStack.length; this.fields.set(key, new repeater_default(key, props)); this.repeaterStack.push(key); return this; } addText(key, props) { this.fields.set(key, new text_default(key, props)); this.meta.fieldKeys.push(key); return this; } addWysiwyg(key, props) { this.fields.set(key, new wysiwyg_default(key, props)); this.meta.fieldKeys.push(key); return this; } addMedia(key, props) { this.fields.set(key, new media_default(key, props)); this.meta.fieldKeys.push(key); return this; } addDocument(key, props) { this.fields.set(key, new document_default(key, props)); this.meta.fieldKeys.push(key); return this; } addNumber(key, props) { this.fields.set(key, new number_default(key, props)); this.meta.fieldKeys.push(key); return this; } addCheckbox(key, props) { this.fields.set(key, new checkbox_default(key, props)); this.meta.fieldKeys.push(key); return this; } addSelect(key, props) { this.fields.set(key, new select_default(key, props)); this.meta.fieldKeys.push(key); return this; } addTextarea(key, props) { this.fields.set(key, new textarea_default(key, props)); this.meta.fieldKeys.push(key); return this; } addJSON(key, props) { this.fields.set(key, new json_default(key, props)); this.meta.fieldKeys.push(key); return this; } addColour(key, props) { this.fields.set(key, new colour_default(key, props)); this.meta.fieldKeys.push(key); return this; } addDateTime(key, props) { this.fields.set(key, new datetime_default(key, props)); this.meta.fieldKeys.push(key); return this; } addLink(key, props) { this.fields.set(key, new link_default(key, props)); this.meta.fieldKeys.push(key); return this; } addUser(key, props) { this.fields.set(key, new user_default(key, props)); this.meta.fieldKeys.push(key); return this; } endRepeater() { const key = this.repeaterStack.pop(); if (!key) return this; const fields = Array.from(this.fields.values()); const selectedRepeaterIndex = fields.findIndex( (field) => field.type === "repeater" && field.key === key ); if (selectedRepeaterIndex === -1) return this; const fieldsAfter = fields.slice(selectedRepeaterIndex + 1); for (const field of fieldsAfter) { if (field.type === "tab" || field.repeater) continue; field.repeater = key; } return this; } // Private Methods nestFields(excludeTabs) { const fields = Array.from(this.fields.values()).filter((field) => { if (excludeTabs) { return field.type !== "tab"; } return true; }); const result = []; let currentTab = null; const repeaterStack = /* @__PURE__ */ new Map(); for (const field of fields) { const config = JSON.parse(JSON.stringify(field.config)); if (field.type === "tab") { if (currentTab) result.push(currentTab); currentTab = config; continue; } if (field.type === "repeater") repeaterStack.set(field.key, config); const targetPush = currentTab ? currentTab.fields : result; if (field.repeater) { const repeater = repeaterStack.get(field.repeater); if (repeater) repeater.fields.push( config ); } else { targetPush.push(config); } } if (currentTab) result.push(currentTab); return result; } // Getters get fieldTree() { return this.nestFields(false); } get fieldTreeNoTab() { return this.nestFields(true); } get flatFields() { const config = []; for (const [_, value] of this.fields) { config.push(value.config); } return config; } }; var field_builder_default = FieldBuilder; // src/libs/custom-fields/fields/tab.ts var TabCustomField = class extends custom_field_default { type = "tab"; column = null; config; key; props; constructor(key, props) { super(); this.key = key; this.props = props; this.config = { key: this.key, type: this.type, details: { label: this.props?.details?.label ?? key_to_title_default(this.key), summary: this.props?.details?.summary }, fields: [] }; } // Methods getSchemaDefinition() { return { data: { columns: [] }, error: void 0 }; } formatResponseValue() { return null; } formatResponseMeta() { return null; } cfSpecificValidation() { return { valid: true }; } get translationsEnabled() { return false; } get defaultValue() { return null; } }; var tab_default = TabCustomField; // src/libs/builders/brick-builder/index.ts var BrickBuilder = class extends field_builder_default { key; config; constructor(key, config) { super(); this.key = key; this.config = { key: this.key, details: { name: config?.details?.name || key, summary: config?.details?.summary }, preview: config?.preview || {} }; } // Builder methods addFields(Builder) { const fields = Array.from(Builder.fields.values()); for (const field of fields) { this.fields.set(field.key, field); this.meta.fieldKeys.push(field.key); } return this; } addTab(key, props) { this.fields.set(key, new tab_default(key, props)); this.meta.fieldKeys.push(key); return this; } }; var brick_builder_default = BrickBuilder; // src/libs/builders/collection-builder/index.ts var CollectionBuilder = class extends field_builder_default { key; config; displayInListing = []; collectionTableSchema; constructor(key, config) { super(); this.key = key; this.config = { key: this.key, ...config }; if (this.config.bricks?.fixed) { this.config.bricks.fixed = this.#removeDuplicateBricks( config.bricks?.fixed ); } if (this.config.bricks?.builder) { this.config.bricks.builder = this.#removeDuplicateBricks( config.bricks?.builder ); } } // ------------------------------------ // Builder Methods addText(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addText(key, props); return this; } addNumber(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addNumber(key, props); return this; } addCheckbox(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addCheckbox(key, props); return this; } addSelect(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addSelect(key, props); return this; } addTextarea(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addTextarea(key, props); return this; } addDateTime(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addDateTime(key, props); return this; } addUser(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addUser(key, props); return this; } addMedia(key, props) { this.#fieldCollectionHelper(key, props?.displayInListing); super.addMedia(key, props); return this; } // ------------------------------------ // Private Methods #removeDuplicateBricks = (bricks) => { if (!bricks) return void 0; return bricks.filter( (brick, index) => bricks.findIndex((b) => b.key === brick.key) === index ); }; #fieldCollectionHelper = (key, display) => { if (display) this.displayInListing.push(key); }; // ------------------------------------ // Getters get getData() { return { key: this.key, mode: this.config.mode, details: { name: this.config.details.name, singularName: this.config.details.singularName, summary: this.config.details.summary ?? null }, config: { isLocked: this.config.config?.isLocked ?? constants_default.collectionBuilder.isLocked, useDrafts: this.config.config?.useDrafts ?? constants_default.collectionBuilder.useDrafts, useRevisions: this.config.config?.useRevisions ?? constants_default.collectionBuilder.useRevisions, useTranslations: this.config.config?.useTranslations ?? constants_default.collectionBuilder.useTranslations, displayInListing: this.displayInListing } }; } get fixedBricks() { return this.config.bricks?.fixed?.map((brick) => ({ key: brick.key, details: brick.config.details, preview: brick.config.preview, fields: brick.fieldTree })) ?? []; } get builderBricks() { return this.config.bricks?.builder?.map((brick) => ({ key: brick.key, details: brick.config.details, preview: brick.config.preview, fields: brick.fieldTree })) ?? []; } get brickInstances() { return (this.config.bricks?.builder || []).concat( this.config.bricks?.fixed || [] ); } get bricksTableSchema() { return this.collectionTableSchema?.tables.filter( (table) => table.type !== "document" && table.type !== "versions" ) ?? []; } get documentTableSchema() { return this.collectionTableSchema?.tables.find( (t) => t.type === "document" ); } get documentFieldsTableSchema() { return this.collectionTableSchema?.tables.find( (t) => t.type === "document-fields" ); } get documentVersionTableSchema() { return this.collectionTableSchema?.tables.find( (t) => t.type === "versions" ); } get tableNames() { const versionTable = this.documentVersionTableSchema?.name; const documentTable = this.documentTableSchema?.name; const documentFields = this.documentFieldsTableSchema?.name; if (!versionTable || !documentTable || !documentFields) { return { error: { message: translations_default("error_getting_collection_names"), status: 500 }, data: void 0 }; } return { data: { version: versionTable, document: documentTable, documentFields }, error: void 0 }; } }; var collection_builder_default = CollectionBuilder; export { brick_builder_default as BrickBuilder, collection_builder_default as CollectionBuilder, field_builder_default as FieldBuilder }; //# sourceMappingURL=builders.js.map