Skip to content

Strapi Queries

La función findOne recibe la colección y los parámetros necesarios para encontrar un único registro. Ahora soporta options para locale y enableLocaleFallback.

  • Todas las funciones devuelven Errors.NOT_FOUND cuando no encuentran resultados.
  • Usa fields para limitar el payload.
  • Si pasas options.locale, la búsqueda/actualización apunta a esa variante; con enableLocaleFallback: true se intenta en otros locales si no hay resultados.
  • Orden de búsqueda con fallback en findOne: (1) locale explícito (si se envía) → (2) default (sin locale) → (3) resto de locales soportados.

Firma

export async function findOne(
collection,
fields,
filters,
populate,
status?: Status,
options?: Options // { locale?, enableLocaleFallback? }
);

Comportamiento

  1. Si options.locale está definido:
    • Busca primero en ese locale.
    • Si no encuentra y enableLocaleFallback es false (por defecto), retorna Errors.NOT_FOUND.
  2. Prueba sin locale (default).
  3. Si enableLocaleFallback es true, itera sobre el resto de locales soportados y retorna el primero que encuentre.
  4. Si nada aparece, retorna Errors.NOT_FOUND.
export async function findOne(
collection,
fields,
filters,
populate,
status?: Status,
options?: Options
) {
try {
const { locale, enableLocaleFallback = false } = options || {};
const search = async (targetLocale?: SupportedLocale) =>
await strapi.documents(collection).findFirst({
fields,
filters,
populate,
status,
...(targetLocale ? { locale: targetLocale } : {}),
});
if (locale) {
const localeFound = await search(locale);
if (localeFound && localeFound.length !== 0) return localeFound;
if (!enableLocaleFallback) return Errors.NOT_FOUND;
}
const defaultFound = await search();
if (defaultFound && defaultFound.length !== 0) return defaultFound;
if (enableLocaleFallback) {
for (const fallbackLocale of allLocales) {
if (fallbackLocale === locale) continue;
const found = await search(fallbackLocale);
if (found && found.length !== 0) return found;
}
}
return Errors.NOT_FOUND;
} catch (error) {
console.log(Errors.ERROR_FIND_ONE + error);
}
}
// Búsqueda simple (sin opciones)
const usuario = await findOne(
"api::usuario.usuario",
["nombre", "email"],
{ id: 1 },
{ profile: true },
"published"
);
if (usuario === Errors.NOT_FOUND) {
console.log("Usuario no encontrado");
} else {
console.log("Usuario encontrado:", usuario);
}
// Búsqueda en un locale específico, sin fallback
const categoriaEn = await findOne(
"api::category.category",
["name", "slug"],
{ documentId: "abc123" },
null,
undefined,
{ locale: "en", enableLocaleFallback: false }
);
// Búsqueda con fallback activado (intentará default y otros locales)
const categoriaConFallback = await findOne(
"api::category.category",
["name", "slug"],
{ documentId: "abc123" },
null,
undefined,
{ enableLocaleFallback: true }
);

La función findMany permite obtener múltiples registros desde una colección. Ahora soporta options para locale y enableLocaleFallback.

Firma

export async function findMany(
collection,
fields = null,
filters = null,
populate = null,
status?: Status,
options?: Options // { locale?, enableLocaleFallback? }
);

Comportamiento

  • Si enableLocaleFallback es true:
    • Consulta todos los locales soportados y concatena los resultados.
    • Si no hay resultados en ningún locale, retorna Errors.NOT_FOUND.
  • Si enableLocaleFallback es false:
    • Realiza una única consulta, con locale si se pasó en options.
    • Si no hay resultados, retorna Errors.NOT_FOUND.
export async function findMany(
collection,
fields = null,
filters = null,
populate = null,
status?: Status,
options?: Options
) {
try {
const { locale, enableLocaleFallback = false } = options || {};
if (enableLocaleFallback) {
let allEntries = [];
for (const targetLocale of allLocales) {
const entries = await strapi.documents(collection).findMany({
fields,
filters,
populate,
status,
locale: targetLocale,
});
if (entries && entries.length > 0) {
allEntries = allEntries.concat(entries);
}
}
return allEntries.length > 0 ? allEntries : Errors.NOT_FOUND;
}
const entries = await strapi.documents(collection).findMany({
fields,
filters,
populate,
status,
...(locale && { locale }),
});
return entries && entries.length > 0 ? entries : Errors.NOT_FOUND;
} catch (error) {
console.log(Errors.ERROR_FIND_MANY_FILTERS + error);
}
}
// Múltiples registros sin opciones
const resultados = await findMany(
"api::prueba.prueba",
["titulo", "descripcion"],
{ categoria: { $eq: "tecnologia" } },
{ autor: true },
"published"
);
if (resultados === Errors.NOT_FOUND) {
console.log("No se encontraron registros.");
} else {
console.log("Registros encontrados:", resultados);
}
// Solo en un locale específico
const productsEn = await findMany(
"api::product.product",
["name", "price"],
null,
null,
"published",
{ locale: "en" }
);
// Con fallback (agrega resultados de todos los locales)
const tagsAllLocales = await findMany(
"api::tag.tag",
["name"],
null,
null,
undefined,
{ enableLocaleFallback: true }
);

La función update recibe la colección, el parámetro where (condición para determinar qué item modificar), los nuevos datos y, de forma opcional, el status y el locale a actualizar. Si se proporciona un documentId, lo usa directamente; si no, busca el documento a través de findOne y actualiza la variante correcta (respetando el locale).

Firma

export async function update(
collection,
where, // { documentId?: string } u otros filtros
data,
status?: Status, // opcional
locale?: SupportedLocale // opcional (variante a actualizar)
);

Comportamiento

  • Si where.documentId NO está presente:
    • Hace un findOne interno pidiendo ['documentId', 'locale'].
    • Si se pasó locale, desactiva fallback para buscar solo ese locale.
    • Si no se pasó locale, activa fallback para encontrar la variante existente.
    • Determina targetLocale como el locale explícito o el document.locale encontrado.
    • Actualiza usando { documentId, data, status?, locale?: targetLocale }.
  • Si where.documentId SÍ está presente:
    • Actualiza directamente con ese documentId y pasa locale si se proporcionó.
  • Si no se actualiza nada, retorna Errors.NOT_FOUND; si todo va bien, retorna el documento actualizado.
export async function update(
collection,
where,
data,
status?: Status,
locale?: SupportedLocale
) {
try {
let updated = "";
if (!where.documentId) {
const document = await findOne(
collection,
[documentId, "locale"],
where,
[],
undefined,
{
...(locale && { locale }),
enableLocaleFallback: locale ? false : true,
}
);
if (document === Errors.NOT_FOUND) return Errors.NOT_FOUND;
const targetLocale = locale ?? document.locale;
updated = await strapi.documents(collection).update({
documentId: document.documentId,
data: data,
...(status && { status }),
...(targetLocale ? { locale: targetLocale } : {}),
});
} else {
updated = await strapi.documents(collection).update({
documentId: where.documentId,
data: data,
...(status && { status }),
...(locale && { locale }),
});
}
if (!updated || (Array.isArray(updated) && updated.length === 0)) {
return Errors.NOT_FOUND;
} else {
return updated;
}
} catch (error) {
console.log(Errors.ERROR_UPDATE + error);
}
}
// Update por documentId en un locale específico
await update(
"api::category.category",
{ documentId: "abc123" },
{ name: "Updated Name EN" },
undefined,
"en"
);
// Update por filtro (sin documentId), sin locale explícito
await update(
"api::user.user",
{ email: "someone@example.com" },
{ displayName: "New Name" }
);
// Update por filtro con locale explícito
await update(
"api::user.user",
{ email: "someone@example.com" },
{ bio: "Nueva bio" },
undefined,
"es"
);
// Update con status
await update(
"api::article.article",
{ documentId: "abc123" },
{ title: "Nuevo título" },
"published"
);

Cuándo pasar locale

  • Pásalo cuando necesites modificar una variante concreta (ej. slug en ‘en’).
  • Omítelo para que el helper detecte y actualice automáticamente la variante encontrada por los filtros.

Actualiza en masa todas las variantes (traducciones) de un documento, excepto un locale excluido.

Firma

export async function updateMany(
collection: string,
documentId: string,
data: Record<string, any>,
excludeLocale: SupportedLocale
);

Comportamiento

  • Actualiza todas las filas con ese documentId cuyo locale sea distinto de excludeLocale.
  • Retorna Errors.NOT_FOUND si no se actualizó ninguna fila.
export async function updateMany(collection, documentId, data, excludeLocale) {
try {
const updated = await strapi.db.query(collection).updateMany({
where: {
documentId,
locale: { $ne: excludeLocale },
},
data,
});
if (!updated || updated.count === 0) {
return Errors.NOT_FOUND;
}
return updated;
} catch (error) {
console.error(Errors.ERROR_UPDATE + error);
return Errors.ERROR_UPDATE;
}
}
await updateMany(
"api::product.product",
"abc123",
{ isArchived: true },
"es" // no toca 'es', actualiza el resto
);

La función create recibe como parametros la colección y los datos del nuevo item.

export async function create(collection, data) {
try {
await strapi.documents(collection).create(data);
} catch (error) {
console.log(errorCreate + error);
}
}

La implementación del if (!result.publishedAt) asegura que la entidad se cree solo una vez, ya que verifica si el contenido está en estado de borrador. Si es así, la creación de la entidad se realiza solo en modo draft (borrador). Una vez que el contenido se publica, la condición no se vuelve a cumplir y no se crea de nuevo. En este caso, se utiliza un ejemplo en un lifecycle hook debido a que, con la nueva versión de Strapi 5, se ha introducido la funcionalidad de publish y draft en el Content Manager para gestionar el contenido. Esto provoca que al crear una nueva entidad con la función create, esta se guarde dos veces: una como draft y otra como published. En el ejemplo se proporciona una solución para que solo se guarde una vez.

import { create } from "../../../../utils/strapi-queries";
module.exports = {
async afterCreate(event) {
const { result } = event;
if (!result.publishedAt) {
await create("api::blog.blog", {
name: `Welcome blog for ${result.name}`,
numpage: 1,
description: `This is the first blog for the user ${result.name}.`,
author: result.id,
});
}
},
};

La implementación del if (!result.publishedAt) asegura que la entidad se cree solo una vez, ya que verifica si el contenido está en estado de borrador. Si es así, la creación de la entidad se realiza solo en modo draft (borrador). Una vez que el contenido se publica, la condición no se vuelve a cumplir y no se crea de nuevo.

Esta funcion es la encargada de enviar un email a un usuario especifico utilizando el plugin de Email.

export async function sendEmail(
email: string,
subject: string,
text: string,
html: string
) {
if (!email || !subject || (!text && !html)) {
return Errors.ERROR_EMAIL_MISSING_PARAMETERTS;
}
try {
return await strapi.plugins[USER_STRIPE_EMAIL_PLUGIN].services.email.send({
to: email,
subject,
text,
html,
});
} catch (error) {
console.error(Errors.ERROR_SEND_EMAIL + error);
return Errors.ERROR_SEND_EMAIL;
}
}
const lang = validateLang(body.lang);
const { subject, text, html } = EMAIL_CONTENT[lang].updated;
await sendEmail(email, subject, text(vertical), html(vertical));

La parte del lenguaje y llenado de datos verse al final de reset password.