{"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\nimport { indexByDocumentId } from './utils/document-status';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n  id: Data.ID;\n  documentId: Modules.Documents.ID;\n  updatedAt: string | Date;\n  publishedAt?: string | Date;\n  [key: string]: unknown;\n}\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n  params.filters = params.filters || {};\n  params.filters.$and = params.filters.$and || [];\n  params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n  const permissionChecker = getService('permission-checker').create({\n    userAbility,\n    model: model.uid,\n  });\n\n  // Whether the main field can be displayed or not, regardless of permissions.\n  const isMainFieldListable = isListable(model, mainField);\n  // Whether the user has the permission to access the model's main field (using RBAC abilities)\n  const canReadMainField = permissionChecker.can.read(null, mainField);\n\n  if (!isMainFieldListable || !canReadMainField) {\n    // Default to 'documentId' if the actual main field shouldn't be displayed\n    return 'documentId';\n  }\n\n  // Edge cases\n\n  // 1. Enforce 'name' as the main field for users and permissions' roles\n  if (model.uid === 'plugin::users-permissions.role') {\n    return 'name';\n  }\n\n  return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n  if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n    return relations;\n  }\n\n  const documentMetadata = getService('document-metadata');\n\n  if (!relations.length) {\n    return relations;\n  }\n\n  const firstRelation = relations[0];\n\n  const filters: any = {\n    documentId: { $in: relations.map((r) => r.documentId) },\n    // NOTE: find the \"opposite\" status\n    publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n  };\n\n  const availableStatus = await strapi.query(targetUid).findMany({\n    select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n    filters,\n  });\n\n  const statusByDocumentId = indexByDocumentId(availableStatus);\n\n  return relations.map((relation: RelationEntity) => {\n    const candidates = statusByDocumentId.get(relation.documentId as string) || [];\n    const availableStatuses = relation.locale\n      ? candidates.filter((c) => c.locale === relation.locale)\n      : candidates;\n\n    return {\n      ...relation,\n      status: documentMetadata.getStatus(relation, availableStatuses),\n    };\n  });\n};\n\nconst getPublishedAtClause = (status: string, uid: UID.Schema) => {\n  const model = strapi.getModel(uid);\n\n  /**\n   * If dp is disabled, ignore the filter\n   */\n  if (!model || !contentTypes.hasDraftAndPublish(model)) {\n    return {};\n  }\n\n  // Prioritize the draft status in case it's not provided\n  return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n  const sourceModel = strapi.getModel(sourceUid);\n  const targetModel = strapi.getModel(targetUid);\n\n  const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n  const isSourceLocalized = isLocalized(sourceModel);\n  const isTargetLocalized = isLocalized(targetModel);\n\n  return {\n    locale,\n    isSourceLocalized,\n    isTargetLocalized,\n  };\n};\n\nconst validateStatus = (\n  sourceUid: UID.Schema,\n  status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n  const sourceModel = strapi.getModel(sourceUid);\n\n  const isDP = contentTypes.hasDraftAndPublish;\n  const isSourceDP = isDP(sourceModel);\n\n  // Default to draft if not set\n  if (!isSourceDP && sourceModel.modelType === 'contentType') {\n    return { status: undefined };\n  }\n\n  switch (status) {\n    case 'published':\n      return { status: 'published' };\n    default:\n      // Assign to draft if the status is not valid\n      return { status: 'draft' };\n  }\n};\n\nexport default {\n  async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n    const { userAbility } = ctx.state;\n    const { model, targetField } = ctx.params;\n\n    const sourceSchema = strapi.getModel(model);\n    if (!sourceSchema) {\n      throw new errors.ValidationError(`The model ${model} doesn't exist`);\n    }\n\n    const attribute: any = sourceSchema.attributes[targetField];\n    if (!attribute || attribute.type !== 'relation') {\n      throw new errors.ValidationError(\n        `The relational field ${targetField} doesn't exist on ${model}`\n      );\n    }\n\n    const sourceUid = model;\n    const targetUid = attribute.target;\n\n    const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n      sourceUid,\n      targetUid,\n      ctx.request?.query?.locale\n    );\n    const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n    const permissionChecker = getService('permission-checker').create({\n      userAbility,\n      model,\n    });\n\n    const isComponent = sourceSchema.modelType === 'component';\n    if (!isComponent) {\n      if (permissionChecker.cannot.read(null, targetField)) {\n        return ctx.forbidden();\n      }\n    }\n\n    let entryId: string | number | null = null;\n\n    if (id) {\n      const where: Record<string, any> = {};\n\n      if (!isComponent) {\n        where.documentId = id;\n\n        if (status) {\n          where.publishedAt = getPublishedAtClause(status, sourceUid);\n        }\n\n        if (locale && isSourceLocalized) {\n          where.locale = locale;\n        }\n      } else {\n        // If the source is a component, we only need to filter by the\n        // component's entity id\n        where.id = id;\n      }\n\n      const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n      const populate = await getService('populate-builder')(model)\n        .populateFromQuery(permissionQuery)\n        .build();\n\n      const currentEntity = await strapi.db.query(model).findOne({\n        where,\n        populate,\n      });\n\n      // We need to check if the entity exists\n      // and if the user has the permission to read it in this way\n      // There may be multiple entities (publication states) under this\n      // documentId + locale. We only need to check if one exists\n      if (!currentEntity) {\n        throw new errors.NotFoundError();\n      }\n\n      if (!isComponent) {\n        if (permissionChecker.cannot.read(currentEntity, targetField)) {\n          throw new errors.ForbiddenError();\n        }\n      }\n\n      entryId = currentEntity.id;\n    }\n\n    const modelConfig = isComponent\n      ? await getService('components').findConfiguration(sourceSchema)\n      : await getService('content-types').findConfiguration(sourceSchema);\n\n    const targetSchema = strapi.getModel(targetUid);\n\n    const mainField = flow(\n      prop(`metadatas.${targetField}.edit.mainField`),\n      (mainField) => mainField || 'id',\n      (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n    )(modelConfig);\n\n    const fieldsToSelect = uniq([\n      mainField,\n      PUBLISHED_AT_ATTRIBUTE,\n      UPDATED_AT_ATTRIBUTE,\n      'documentId',\n    ]);\n\n    if (isTargetLocalized) {\n      fieldsToSelect.push('locale');\n    }\n\n    return {\n      entryId,\n      locale,\n      status,\n      attribute,\n      fieldsToSelect,\n      mainField,\n      source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n      target: { schema: targetSchema, isLocalized: isTargetLocalized },\n      sourceSchema,\n      targetSchema,\n      targetField,\n    };\n  },\n\n  /**\n   * Used to find new relations to add in a relational field.\n   *\n   * Component and document relations are dealt a bit differently (they don't have a document_id).\n   */\n  async findAvailable(ctx: any) {\n    const { id } = ctx.request.query;\n\n    await validateFindAvailable(ctx.request.query);\n\n    const {\n      locale,\n      status,\n      targetField,\n      fieldsToSelect,\n      mainField,\n      source: {\n        schema: { uid: sourceUid, modelType: sourceModelType },\n        isLocalized: isSourceLocalized,\n      },\n      target: {\n        schema: { uid: targetUid },\n        isLocalized: isTargetLocalized,\n      },\n    } = await this.extractAndValidateRequestInfo(ctx, id);\n\n    const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;\n\n    const permissionChecker = getService('permission-checker').create({\n      userAbility: ctx.state.userAbility,\n      model: targetUid,\n    });\n    const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n    const queryParams = {\n      sort: mainField,\n      // cannot select other fields as the user may not have the permissions\n      fields: fieldsToSelect,\n      ...permissionQuery,\n    };\n\n    // If no status is requested, we find all the draft relations and later update them\n    // with the latest available status\n    addFiltersClause(queryParams, {\n      publishedAt: getPublishedAtClause(status, targetUid),\n    });\n\n    // We will only filter by locale if the target content type is localized\n    const filterByLocale = isTargetLocalized && locale;\n    if (filterByLocale) {\n      addFiltersClause(queryParams, { locale });\n    }\n\n    if (id) {\n      /**\n       * Exclude the relations that are already related to the source\n       *\n       * We also optionally filter the target relations by the requested\n       * status and locale if provided.\n       */\n      const subQuery = strapi.db.queryBuilder(sourceUid);\n\n      // The alias refers to the DB table of the target content type model\n      const alias = subQuery.getAlias();\n\n      const where: Record<string, any> = {\n        [`${alias}.id`]: { $notNull: true },\n        [`${alias}.document_id`]: { $notNull: true },\n      };\n\n      /**\n       * Content Types -> Specify document id\n       * Components    -> Specify entity id (they don't have a document id)\n       */\n      if (sourceModelType === 'contentType') {\n        where.document_id = id;\n      } else {\n        where.id = id;\n      }\n\n      // Add the status and locale filters if they are provided\n      const publishedAt = getPublishedAtClause(status, targetUid);\n      if (!isEmpty(publishedAt)) {\n        where[`${alias}.published_at`] = publishedAt;\n      }\n\n      // If target has localization we need to filter by locale\n      if (isTargetLocalized && locale) {\n        where[`${alias}.locale`] = locale;\n      }\n\n      if (isSourceLocalized && locale) {\n        where.locale = locale;\n      }\n\n      /**\n       * UI can provide a list of ids to omit,\n       * those are the relations user set in the UI but has not persisted.\n       * We don't want to include them in the available relations.\n       */\n      if ((idsToInclude?.length ?? 0) !== 0) {\n        where[`${alias}.id`].$notIn = idsToInclude;\n      }\n\n      const knexSubQuery = subQuery\n        .where(where)\n        .join({ alias, targetField })\n        .select(`${alias}.id`)\n        .getKnexQuery();\n\n      addFiltersClause(queryParams, {\n        id: { $notIn: knexSubQuery },\n      });\n    }\n\n    /**\n     * Apply a filter to the mainField based on the search query and filter operator\n     * searching should be allowed only on mainField for permission reasons\n     */\n    if (_q) {\n      const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n      addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\n    }\n\n    if (idsToOmit?.length > 0) {\n      // If we have ids to omit, we should filter them out\n      addFiltersClause(queryParams, {\n        id: { $notIn: uniq(idsToOmit) },\n      });\n    }\n\n    const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n    const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n    ctx.body = {\n      ...res,\n      results: await addStatusToRelations(targetUid, res.results),\n    };\n  },\n\n  async findExisting(ctx: any) {\n    const { userAbility } = ctx.state;\n    const { id } = ctx.params;\n\n    await validateFindExisting(ctx.request.query);\n\n    const {\n      entryId,\n      attribute,\n      targetField,\n      fieldsToSelect,\n      status,\n      source: { schema: sourceSchema },\n      target: { schema: targetSchema },\n    } = await this.extractAndValidateRequestInfo(ctx, id);\n\n    const { uid: sourceUid } = sourceSchema;\n    const { uid: targetUid } = targetSchema;\n\n    const permissionQuery = await getService('permission-checker')\n      .create({ userAbility, model: targetUid })\n      .sanitizedQuery.read({ fields: fieldsToSelect });\n\n    /**\n     * loadPages can not be used for single relations,\n     * this unifies the loading regardless of it's type\n     *\n     * NOTE: Relations need to be loaded using any db.query method\n     *       to ensure the proper ordering is applied\n     */\n    const dbQuery = strapi.db.query(sourceUid);\n    const loadRelations = relations.isAnyToMany(attribute)\n      ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n      : (...args: Parameters<typeof dbQuery.load>) =>\n          dbQuery\n            .load(...args)\n            // Ensure response is an array\n            .then((res) => ({ results: res ? [res] : [] }));\n\n    const filters: {\n      publishedAt?: Record<string, any>;\n    } = {};\n\n    if (sourceSchema?.options?.draftAndPublish || sourceSchema?.modelType === 'component') {\n      if (targetSchema?.options?.draftAndPublish) {\n        if (status === 'published') {\n          filters.publishedAt = { $notNull: true };\n        } else {\n          filters.publishedAt = { $null: true };\n        }\n      }\n    } else if (targetSchema?.options?.draftAndPublish) {\n      // NOTE: we must return the drafts as some targets might not have a published version yet\n      filters.publishedAt = { $null: true };\n    }\n\n    /**\n     * If user does not have access to specific relations (custom conditions),\n     * only the ids of the relations are returned.\n     *\n     * - First query loads all the ids.\n     * - Second one also loads the main field, and excludes forbidden relations.\n     *\n     * The response contains the union of the two queries.\n     */\n    const res = await loadRelations({ id: entryId }, targetField, {\n      select: ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'],\n      ordering: 'desc',\n      page: ctx.request.query.page,\n      pageSize: ctx.request.query.pageSize,\n      filters,\n    });\n\n    /**\n     * Add all ids to load in permissionQuery\n     * If any of the relations are not accessible, the permissionQuery will exclude them\n     */\n    const loadedIds = res.results.map((item: any) => item.id);\n    addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n    /**\n     * Load the relations with the main field, the sanitized permission query\n     * will exclude the relations the user does not have access to.\n     *\n     * Pagination is not necessary as the permissionQuery contains the ids to load.\n     */\n    const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n      ...strapi.get('query-params').transform(targetUid, permissionQuery),\n      ordering: 'desc',\n    });\n\n    // NOTE: the order is very important to make sure sanitized relations are kept in priority\n    const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\n\n    ctx.body = {\n      pagination: res.pagination || {\n        page: 1,\n        pageCount: 1,\n        pageSize: 10,\n        total: relationsUnion.length,\n      },\n      results: await addStatusToRelations(targetUid, relationsUnion),\n    };\n  },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","query","findMany","select","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","modelType","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","ordering","page","pageSize","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat","pagination","pageCount","total"],"mappings":"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"}