@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1,054 lines (1,028 loc) • 33.3 kB
JavaScript
import {
prefix_generated_column_name_default
} from "./chunk-FRZBD5RL.js";
import {
lucid_error_default
} from "./chunk-7SRFYA4B.js";
import {
constants_default,
translations_default
} from "./chunk-7XW7FQ7W.js";
// src/utils/media/create-cdn-url.ts
var createCdnUrl = (host, key) => `${host}/cdn/v1/${key}`;
var create_cdn_url_default = createCdnUrl;
// src/utils/media/choose-accept-header-format.ts
var chooseAcceptHeaderFormat = (accept, queryFormat) => {
if (queryFormat) return queryFormat;
if (accept) {
if (accept.includes("image/webp")) return "webp";
if (accept.includes("image/avif")) return "avif";
}
return void 0;
};
var choose_accept_header_format_default = chooseAcceptHeaderFormat;
// src/utils/media/generate-process-key.ts
var generateProcessKey = (data) => {
const [targetK, ext] = data.key.split(".");
let key = `processed/${targetK}`;
if (data.options.quality) key = key.concat(`-${data.options.quality}`);
if (data.options.width) key = key.concat(`-${data.options.width}`);
if (data.options.height) key = key.concat(`-${data.options.height}`);
if (data.options.format) key = key.concat(`.${data.options.format}`);
else key = key.concat(`.${ext}`);
return key;
};
var generate_process_key_default = generateProcessKey;
// src/libs/formatters/user-permissions.ts
var UserPermissionsFormatter = class {
formatMultiple = (props) => {
if (!props.roles) {
return {
roles: [],
permissions: []
};
}
const permissionsSet = /* @__PURE__ */ new Set();
for (const role of props.roles) {
if (!role.permissions) continue;
for (const permission of role.permissions) {
permissionsSet.add(permission.permission);
}
}
return {
roles: props.roles.map(({ id, name }) => ({ id, name })),
permissions: Array.from(permissionsSet)
};
};
};
// src/libs/formatters/users.ts
var UsersFormatter = class {
formatMultiple = (props) => {
return props.users.map(
(u) => this.formatSingle({
user: u
})
);
};
formatSingle = (props) => {
const { roles, permissions } = new UserPermissionsFormatter().formatMultiple({
roles: props.user.roles || []
});
return {
id: props.user.id,
superAdmin: formatters_default.formatBoolean(props.user.super_admin ?? false),
email: props.user.email,
username: props.user.username,
firstName: props.user.first_name,
lastName: props.user.last_name,
roles,
permissions,
triggerPasswordReset: formatters_default.formatBoolean(
props.user.triggered_password_reset
),
createdAt: formatters_default.formatDate(props.user.created_at),
updatedAt: formatters_default.formatDate(props.user.updated_at)
};
};
};
// src/libs/formatters/roles.ts
var RolesFormatter = class {
formatMultiple = (props) => {
return props.roles.map(
(r) => this.formatSingle({
role: r
})
);
};
formatSingle = (props) => {
return {
id: props.role.id,
name: props.role.name,
description: props.role.description,
permissions: props.role.permissions?.map((p) => {
return {
id: p.id,
permission: p.permission
};
}),
createdAt: formatters_default.formatDate(props.role.created_at),
updatedAt: formatters_default.formatDate(props.role.updated_at)
};
};
};
// src/libs/formatters/settings.ts
var SettingsFormatter = class {
formatSingle = (props) => {
return {
email: {
enabled: props.config.email !== void 0,
from: props.config.email?.from ?? null
},
media: {
enabled: props.config.media?.strategy !== void 0,
storage: {
total: props.config.media.storage,
remaining: props.config.media.storage - props.settings.mediaStorageUsed,
used: props.settings.mediaStorageUsed
},
processed: {
stored: props.config.media.processed.store,
imageLimit: props.config.media.processed.limit,
total: props.settings.processedImageCount
}
}
};
};
};
// src/libs/formatters/permissions.ts
var PermissionsFormatter = class {
formatMultiple = (props) => {
return Object.values(props.permissions);
};
};
// src/libs/formatters/options.ts
var OptionsFormatter = class {
formatSingle = (props) => {
return {
name: props.option.name,
valueText: props.option.value_text,
valueInt: props.option.value_int,
valueBool: formatters_default.formatBoolean(props.option.value_bool)
};
};
};
// src/libs/formatters/media.ts
var MediaFormatter = class {
formatMultiple = (props) => {
return props.media.map(
(m) => this.formatSingle({
media: m,
host: props.host
})
);
};
formatSingle = (props) => {
return {
id: props.media.id,
key: props.media.key,
url: create_cdn_url_default(props.host, props.media.key),
title: props.media.title_translations?.map((t) => ({
value: t.value,
localeCode: t.locale_code
})) ?? [],
alt: props.media.alt_translations?.map((t) => ({
value: t.value,
localeCode: t.locale_code
})) ?? [],
type: props.media.type,
meta: {
mimeType: props.media.mime_type,
extension: props.media.file_extension,
fileSize: props.media.file_size,
width: props.media.width,
height: props.media.height,
blurHash: props.media.blur_hash,
averageColour: props.media.average_colour,
isDark: formatters_default.formatBoolean(props.media.is_dark),
isLight: formatters_default.formatBoolean(props.media.is_light)
},
createdAt: formatters_default.formatDate(props.media.created_at),
updatedAt: formatters_default.formatDate(props.media.updated_at)
};
};
};
// src/libs/formatters/locales.ts
var LocalesFormatter = class {
formatMultiple = (props) => {
return props.locales.map((l) => {
const configLocale = props.localisation.locales.find(
(locale) => locale.code === l.code
);
if (!configLocale) {
return null;
}
return this.formatSingle({
locale: l,
configLocale,
defaultLocale: props.localisation.defaultLocale
});
}).filter((l) => l !== null);
};
formatSingle = (props) => {
return {
code: props.locale.code,
name: props.configLocale.label,
isDefault: props.locale.code === props.defaultLocale,
createdAt: formatters_default.formatDate(props.locale.created_at),
updatedAt: formatters_default.formatDate(props.locale.updated_at)
};
};
};
// src/libs/formatters/emails.ts
var EmailsFormatter = class {
formatMultiple = (props) => {
return props.emails.map(
(e) => this.formatSingle({
email: e
})
);
};
formatSingle = (props) => {
return {
id: props.email.id,
emailHash: props.email.email_hash,
type: props.email.type,
deliveryStatus: props.email.delivery_status,
mailDetails: {
from: {
address: props.email.from_address,
name: props.email.from_name
},
to: props.email.to_address,
subject: props.email.subject,
cc: props.email.cc,
bcc: props.email.bcc,
template: props.email.template
},
data: props.email.data ?? null,
sentCount: props.email.sent_count || 0,
errorCount: props.email.error_count || 0,
errorMessage: props.email.last_error_message,
html: props.html ?? null,
lastSuccessAt: formatters_default.formatDate(props.email.last_success_at),
lastAttemptAt: formatters_default.formatDate(props.email.last_attempt_at),
createdAt: formatters_default.formatDate(props.email.created_at)
};
};
};
// src/libs/formatters/collections.ts
var CollectionsFormatter = class {
formatMultiple = (props) => {
return props.collections.map(
(c) => this.formatSingle({
collection: c,
include: props.include,
documents: props.documents
})
);
};
formatSingle = (props) => {
const collectionData = props.collection.getData;
const key = props.collection.key;
return {
key,
mode: collectionData.mode,
documentId: props.include?.document_id ? this.getDocumentId(key, props.documents) : void 0,
details: {
name: collectionData.details.name,
singularName: collectionData.details.singularName,
summary: collectionData.details.summary
},
config: {
useTranslations: collectionData.config.useTranslations,
useDrafts: collectionData.config.useDrafts,
useRevisions: collectionData.config.useRevisions,
isLocked: collectionData.config.isLocked,
displayInListing: props.collection.displayInListing
},
fixedBricks: props.include?.bricks ? props.collection.fixedBricks ?? [] : [],
builderBricks: props.include?.bricks ? props.collection.builderBricks ?? [] : [],
fields: props.include?.fields ? props.collection.fieldTree ?? [] : []
};
};
getDocumentId = (collectionKey, documents) => {
const document = documents?.find(
(document2) => document2.collection_key === collectionKey
);
return document?.id ?? void 0;
};
};
// src/libs/formatters/client-integrations.ts
var ClientIntegrationsFormatter = class {
formatMultiple = (props) => {
return props.integrations.map(
(i) => this.formatSingle({
integration: i
})
);
};
formatSingle = (props) => {
return {
id: props.integration.id,
key: props.integration.key,
name: props.integration.name,
description: props.integration.description,
enabled: formatters_default.formatBoolean(props.integration.enabled),
createdAt: formatters_default.formatDate(props.integration.created_at),
updatedAt: formatters_default.formatDate(props.integration.updated_at)
};
};
};
// src/libs/formatters/document-bricks.ts
import crypto from "node:crypto";
var DocumentBricksFormatter = class {
formatMultiple = (props) => {
const brickSchemas = props.bricksSchema.filter(
(schema) => schema.type === "brick"
);
if (brickSchemas.length === 0) return [];
const brickResponses = [];
for (const schema of brickSchemas) {
const tableData = props.bricksQuery[schema.name];
if (!tableData || tableData.length === 0) continue;
const rowsByBrickInstanceId = Map.groupBy(
tableData,
(item) => item.brick_instance_id
);
for (const [position, rows] of rowsByBrickInstanceId.entries()) {
if (position === void 0 || !rows || rows.length === 0) continue;
const firstRow = rows[0];
if (!firstRow) continue;
if (!firstRow.brick_type) continue;
const brickKey = schema.key.brick;
if (!brickKey) continue;
const brickBuilder = props.collection.brickInstances.find(
(b) => b.key === brickKey
);
if (!brickBuilder) continue;
const DocumentFieldsFormatter2 = formatters_default.get("document-fields");
brickResponses.push({
ref: crypto.randomUUID(),
key: brickKey,
order: firstRow.position,
open: formatters_default.formatBoolean(firstRow.is_open),
type: firstRow.brick_type,
fields: DocumentFieldsFormatter2.formatMultiple(
{
brickRows: rows,
bricksQuery: props.bricksQuery,
bricksSchema: props.bricksSchema,
relationMetaData: props.relationMetaData
},
{
host: props.config.host,
builder: brickBuilder,
collection: props.collection,
localisation: {
locales: props.config.localisation.locales.map((l) => l.code),
default: props.config.localisation.defaultLocale
},
brickKey,
config: props.config
}
)
});
}
}
return brickResponses.sort((a, b) => a.order - b.order);
};
formatDocumentFields = (props) => {
const documentFieldsSchema = props.bricksSchema.find(
(bs) => bs.type === "document-fields"
);
if (!documentFieldsSchema) return [];
const tableData = props.bricksQuery[documentFieldsSchema.name];
if (!tableData) return [];
const rowsByPos = Map.groupBy(tableData, (item) => item.position);
const rowOne = rowsByPos.get(0);
if (!rowOne) return [];
const DocumentFieldsFormatter2 = formatters_default.get("document-fields");
return DocumentFieldsFormatter2.formatMultiple(
{
brickRows: rowOne,
bricksQuery: props.bricksQuery,
bricksSchema: props.bricksSchema,
relationMetaData: props.relationMetaData
},
{
host: props.config.host,
builder: props.collection,
collection: props.collection,
localisation: {
locales: props.config.localisation.locales.map((l) => l.code),
default: props.config.localisation.defaultLocale
},
brickKey: void 0,
config: props.config
}
);
};
/**
* Works out the target repeater table based on props and schema, and returns all the rows for it from the brciksQuery prop
*/
static getBrickRepeaterRows = (props) => {
const matchingSchema = props.bricksSchema.find((schema) => {
if (schema.key.collection !== props.collectionKey) return false;
if (props.brickKey !== void 0 && schema.key.brick !== props.brickKey)
return false;
if (schema.type !== "repeater") return false;
if (props.brickKey === void 0 && schema.key.brick !== void 0)
return false;
if (!schema.key.repeater || schema.key.repeater.length === 0)
return false;
if (schema.key.repeater.length !== props.repeaterLevel + 1) return false;
if (schema.key.repeater[schema.key.repeater.length - 1] !== props.repeaterKey)
return false;
return true;
});
if (matchingSchema && matchingSchema.name in props.bricksQuery) {
const rows = props.bricksQuery[matchingSchema.name];
if (!rows) return [];
if (props.repeaterLevel === 0) {
return rows.filter(
(r) => r.brick_id && props.relationIds.includes(r.brick_id)
);
}
return rows.filter(
(r) => r.parent_id && props.relationIds.includes(r.parent_id)
);
}
return [];
};
};
// src/libs/formatters/document-fields.ts
import crypto2 from "node:crypto";
var DocumentFieldsFormatter = class {
/**
* The entry point for building out the FieldResponse array.
*
* Formats, creates groups, creates nested structure, marries relationMetaData etc.
*/
formatMultiple = (data, meta) => {
return this.buildFieldTree(data, {
builder: meta.builder,
fieldConfig: meta.builder.fieldTreeNoTab,
host: meta.host,
localisation: meta.localisation,
collection: meta.collection,
brickKey: meta.brickKey,
config: meta.config
});
};
/**
* Recursively build out the FieldResponse based on the nested fieldConfig
*/
buildFieldTree = (data, meta) => {
const fieldsRes = [];
for (const config of meta.fieldConfig) {
if (config.type === "repeater") {
fieldsRes.push({
key: config.key,
type: config.type,
groupRef: meta.groupRef,
groups: this.buildGroups(data, {
builder: meta.builder,
repeaterConfig: config,
host: meta.host,
localisation: meta.localisation,
collection: meta.collection,
brickKey: meta.brickKey,
repeaterLevel: meta.repeaterLevel || 0,
config: meta.config
})
});
continue;
}
const fieldKey = prefix_generated_column_name_default(config.key);
const fieldValues = data.brickRows.flatMap(
(row) => ({
value: row[fieldKey],
locale: row.locale
})
);
const fieldValue = this.buildField(
{
values: fieldValues,
relationMetaData: data.relationMetaData
},
{
builder: meta.builder,
fieldConfig: config,
host: meta.host,
localisation: meta.localisation,
collection: meta.collection,
brickKey: meta.brickKey,
config: meta.config,
groupRef: meta.groupRef
}
);
if (fieldValue) fieldsRes.push(fieldValue);
}
return fieldsRes;
};
/**
* Responsible for building a single FieldResponse object.
*
* Adds in empty locale values, formats the value and constructs either translations or values based on the fields config
*/
buildField = (data, meta) => {
const cfInstance = meta.builder.fields.get(meta.fieldConfig.key);
if (!cfInstance) return null;
if (meta.fieldConfig.type !== "repeater" && meta.fieldConfig.type !== "tab" && meta.fieldConfig.config.useTranslations === true && meta.collection.getData.config.useTranslations === true) {
const fieldTranslations = {};
const fieldMeta = {};
for (const locale of meta.localisation.locales) {
const localeValue = data.values.find((v) => v.locale === locale);
if (localeValue) {
fieldTranslations[locale] = cfInstance.formatResponseValue(
localeValue.value
);
fieldMeta[locale] = cfInstance.formatResponseMeta(
this.fetchRelationData(data.relationMetaData, {
type: meta.fieldConfig.type,
value: localeValue.value,
fieldConfig: meta.fieldConfig
}),
meta
);
} else {
fieldTranslations[locale] = null;
fieldMeta[locale] = null;
}
}
return {
key: meta.fieldConfig.key,
type: meta.fieldConfig.type,
groupRef: meta.groupRef,
translations: fieldTranslations,
meta: fieldMeta
};
}
const defaultValue = data.values.find(
(f) => f.locale === meta.localisation.default
);
if (!defaultValue) return null;
return {
key: meta.fieldConfig.key,
type: meta.fieldConfig.type,
value: cfInstance.formatResponseValue(defaultValue.value),
groupRef: meta.groupRef,
meta: cfInstance.formatResponseMeta(
this.fetchRelationData(data.relationMetaData, {
type: meta.fieldConfig.type,
value: defaultValue.value,
fieldConfig: meta.fieldConfig
}),
meta
)
};
};
/**
* Responsible for building out groups for a repeater field
*/
buildGroups = (data, meta) => {
const groupsRes = [];
const repeaterFields = meta.repeaterConfig.fields;
if (!repeaterFields) return groupsRes;
const repeaterTables = DocumentBricksFormatter.getBrickRepeaterRows({
bricksQuery: data.bricksQuery,
bricksSchema: data.bricksSchema,
collectionKey: meta.collection.key,
brickKey: meta.brickKey,
repeaterKey: meta.repeaterConfig.key,
repeaterLevel: meta.repeaterLevel,
relationIds: data.brickRows.flatMap((b) => b.id)
});
const groups = Map.groupBy(repeaterTables, (item) => {
return item.position;
});
groups.forEach((localeRows, key) => {
const openState = localeRows[0]?.is_open ?? false;
const ref = crypto2.randomUUID();
groupsRes.push({
ref,
order: key,
open: formatters_default.formatBoolean(openState),
fields: this.buildFieldTree(
{
brickRows: localeRows,
bricksQuery: data.bricksQuery,
bricksSchema: data.bricksSchema,
relationMetaData: data.relationMetaData
},
{
builder: meta.builder,
host: meta.host,
localisation: meta.localisation,
collection: meta.collection,
brickKey: meta.brickKey,
fieldConfig: repeaterFields,
repeaterLevel: meta.repeaterLevel + 1,
config: meta.config,
groupRef: ref
}
)
});
});
return groupsRes.sort((a, b) => a.order - b.order);
};
/**
* Returns fields as an object, with the keys being the custom field keys instead of an array of fields
*/
objectifyFields = (fields) => {
return fields.reduce(
(acc, field) => {
if (!field) return acc;
acc[field.key] = {
...field,
groups: field.groups?.map((g) => {
return {
...g,
fields: this.objectifyFields(g.fields || [])
};
})
};
return acc;
},
{}
);
};
/**
* Fetch relation meta data
*/
fetchRelationData = (relationData, props) => {
switch (props.type) {
case "document": {
return relationData.document?.find((d) => {
return d.collection_key === props.fieldConfig?.collection && d.document_id === props.value;
});
}
default: {
return relationData[props.type]?.find((i) => i?.id === props.value);
}
}
};
};
// src/libs/formatters/document-versions.ts
var DocumentVersions = class {
formatMultiple(props) {
return props.versions.map(
(v) => this.formatSingle({
version: v,
bricksSchema: props.bricksSchema
})
);
}
formatSingle(props) {
const formattedBricks = {
builder: [],
fixed: []
};
for (const schema of props.bricksSchema) {
const tableName = schema.name;
if (tableName in props.version && Array.isArray(props.version[tableName])) {
const brickInstances = /* @__PURE__ */ new Map();
for (const row of props.version[tableName]) {
brickInstances.set(row.brick_instance_id, row.brick_type);
}
for (const [_, brickType] of brickInstances.entries()) {
formattedBricks[brickType].push({
brickKey: schema.key.brick || null
});
}
}
}
return {
id: props.version.id,
versionType: props.version.type,
promotedFrom: props.version.promoted_from,
createdAt: formatters_default.formatDate(props.version.created_at),
createdBy: props.version.created_by ?? null,
document: {
id: props.version.document_id ?? null,
collectionKey: props.version.collection_key,
createdBy: props.version.document_created_by ?? null,
createdAt: formatters_default.formatDate(props.version.document_created_at),
updatedAt: formatters_default.formatDate(props.version.document_updated_at),
updatedBy: props.version.document_updated_by ?? null
},
bricks: formattedBricks
};
}
};
// src/libs/formatters/documents.ts
var DocumentsFormatter = class {
formatMultiple = (props) => {
const DocumentBricksFormatter2 = formatters_default.get("document-bricks");
return props.documents.map((d) => {
let fields = null;
let bricks = null;
if (props.hasFields) {
fields = DocumentBricksFormatter2.formatDocumentFields({
bricksQuery: d,
bricksSchema: props.collection.bricksTableSchema,
relationMetaData: props.relationData || {},
collection: props.collection,
config: props.config
});
}
if (props.hasBricks) {
bricks = DocumentBricksFormatter2.formatMultiple({
bricksQuery: d,
bricksSchema: props.collection.bricksTableSchema,
relationMetaData: props.relationData || {},
collection: props.collection,
config: props.config
});
}
return this.formatSingle({
document: d,
collection: props.collection,
config: props.config,
fields,
bricks: bricks || void 0
});
});
};
formatSingle = (props) => {
return {
id: props.document.id,
collectionKey: props.document.collection_key,
status: props.document.version_type ?? null,
versionId: props.document.version_id ?? null,
version: this.formatVersion({
document: props.document
}),
bricks: props.bricks ?? null,
fields: props.fields ?? null,
createdBy: props.document.cb_user_id ? {
id: props.document.cb_user_id,
email: props.document.cb_user_email ?? null,
firstName: props.document.cb_user_first_name ?? null,
lastName: props.document.cb_user_last_name ?? null,
username: props.document.cb_user_username ?? null
} : null,
updatedBy: props.document.ub_user_id ? {
id: props.document.ub_user_id,
email: props.document.ub_user_email ?? null,
firstName: props.document.ub_user_first_name ?? null,
lastName: props.document.ub_user_last_name ?? null,
username: props.document.ub_user_username ?? null
} : null,
createdAt: formatters_default.formatDate(props.document.created_at),
updatedAt: formatters_default.formatDate(props.document.updated_at)
};
};
formatVersion = (props) => {
const draftVersion = props.document.versions?.find(
(v) => v.type === "draft"
);
const publishedVersion = props.document.versions?.find(
(v) => v.type === "published"
);
return {
draft: draftVersion?.id ? {
id: draftVersion.id,
promotedFrom: draftVersion.promoted_from,
createdAt: formatters_default.formatDate(draftVersion.created_at),
createdBy: draftVersion.created_by
} : null,
published: publishedVersion?.id ? {
id: publishedVersion.id,
promotedFrom: publishedVersion.promoted_from,
createdAt: formatters_default.formatDate(publishedVersion.created_at),
createdBy: publishedVersion.created_by
} : null
};
};
formatClientMultiple = (props) => {
const DocumentBricksFormatter2 = formatters_default.get("document-bricks");
return props.documents.map((d) => {
let fields = null;
let bricks = null;
if (props.hasFields) {
fields = DocumentBricksFormatter2.formatDocumentFields({
bricksQuery: d,
bricksSchema: props.collection.bricksTableSchema,
relationMetaData: props.relationData || {},
collection: props.collection,
config: props.config
});
}
if (props.hasBricks) {
bricks = DocumentBricksFormatter2.formatMultiple({
bricksQuery: d,
bricksSchema: props.collection.bricksTableSchema,
relationMetaData: props.relationData || {},
collection: props.collection,
config: props.config
});
}
return this.formatClientSingle({
document: d,
collection: props.collection,
config: props.config,
fields,
bricks: bricks || void 0
});
});
};
formatClientSingle = (props) => {
const FieldsFormatter = formatters_default.get("document-fields");
const res = this.formatSingle({
document: props.document,
collection: props.collection,
bricks: props.bricks,
fields: props.fields,
config: props.config
});
return {
...res,
bricks: res.bricks ? res.bricks.map((b) => {
return {
...b,
fields: FieldsFormatter.objectifyFields(b.fields)
};
}) : null,
fields: res.fields ? FieldsFormatter.objectifyFields(res.fields) : null
};
};
};
// src/libs/formatters/index.ts
var Formatter = class {
static get(format) {
switch (format) {
case "users":
return new UsersFormatter();
case "user-permissions":
return new UserPermissionsFormatter();
case "settings":
return new SettingsFormatter();
case "roles":
return new RolesFormatter();
case "permissions":
return new PermissionsFormatter();
case "options":
return new OptionsFormatter();
case "media":
return new MediaFormatter();
case "locales":
return new LocalesFormatter();
case "emails":
return new EmailsFormatter();
case "collections":
return new CollectionsFormatter();
case "client-integrations":
return new ClientIntegrationsFormatter();
case "document-bricks":
return new DocumentBricksFormatter();
case "document-fields":
return new DocumentFieldsFormatter();
case "document-versions":
return new DocumentVersions();
case "documents":
return new DocumentsFormatter();
default:
throw new lucid_error_default({
message: translations_default("cannot_find_formatter", {
name: format
})
});
}
}
// helpers
static formatDate = (date) => {
if (typeof date === "string") {
return date;
}
return date ? date.toISOString() : null;
};
static parseJSON = (json) => {
if (typeof json === "object") return json;
if (!json) return null;
try {
return JSON.parse(json);
} catch (error) {
return null;
}
};
static stringifyJSON = (json) => {
try {
if (!json) return null;
return JSON.stringify(json);
} catch (error) {
return null;
}
};
static parseCount = (count) => {
return Number.parseInt(count || "0") || 0;
};
static formatBoolean(bool) {
if (bool === null || bool === void 0) return null;
if (typeof bool === "boolean") return bool;
return bool === 1;
}
};
var formatters_default = Formatter;
// src/utils/translations/objectify-translations.ts
var objectifyTranslations = (values, locales) => {
return locales.reduce((acc, locale) => {
const value = values.find((v) => v.locale_code === locale);
if (!value) {
acc[locale] = "";
} else {
acc[locale] = value.value ?? "";
}
return acc;
}, {});
};
var objectify_translations_default = objectifyTranslations;
// src/utils/translations/remove-duplicates.ts
var removeDuplicates = (translations) => translations.filter(
(translation, index, self) => index === self.findIndex((t) => t.localeCode === translation.localeCode)
);
var remove_duplicates_default = removeDuplicates;
// src/utils/translations/merge-translation-groups.ts
var mergeTranslationGroups = (items) => {
const translations = [];
for (const item of items) {
const itemTranslations = remove_duplicates_default(item.translations);
for (const translation of itemTranslations) {
translations.push({
...translation,
key: item.key
});
}
}
return translations;
};
var merge_translation_groups_default = mergeTranslationGroups;
// src/utils/translations/get-unique-locale-codes.ts
var getUniqueLocaleCodes = (items) => {
const localeCodes = items.flatMap((t) => t.map((t2) => t2.localeCode));
return Array.from(new Set(localeCodes));
};
var get_unique_locale_codes_default = getUniqueLocaleCodes;
// src/utils/translations/should-update-translations.ts
var shouldUpdateTranslations = (item) => item.some((t) => t !== void 0 && t.length > 0);
var should_update_translations_default = shouldUpdateTranslations;
// src/services/collection-migrator/helpers/build-table-name.ts
var collectionTableParts = {
document: "document",
fields: "fields",
versions: "versions"
};
var buildTableName = (type, keys) => {
const parts = [collectionTableParts.document, keys.collection];
switch (type) {
case "document": {
break;
}
case "versions": {
parts.push(collectionTableParts.versions);
break;
}
case "brick": {
if (!keys.brick) {
return {
data: void 0,
error: {
message: translations_default(
"collection_migrator_table_name_brick_key_missing_message"
)
}
};
}
parts.push(keys.brick);
break;
}
case "document-fields": {
parts.push(collectionTableParts.fields);
break;
}
case "repeater": {
if (keys.repeater === void 0 || keys.repeater?.length === 0) {
return {
data: void 0,
error: {
message: translations_default(
"collection_migrator_table_name_repeater_keys_missing_message"
)
}
};
}
if (!keys.brick) {
parts.push(collectionTableParts.fields);
} else parts.push(keys.brick);
parts.push(...keys.repeater);
}
}
return {
data: `${constants_default.db.prefix}${parts.join(constants_default.db.collectionKeysJoin)}`,
error: void 0
};
};
var build_table_name_default = buildTableName;
export {
choose_accept_header_format_default,
generate_process_key_default,
create_cdn_url_default,
formatters_default,
merge_translation_groups_default,
get_unique_locale_codes_default,
should_update_translations_default,
objectify_translations_default,
collectionTableParts,
build_table_name_default
};
//# sourceMappingURL=chunk-5BJFGYMM.js.map