@strapi/content-manager 5.39.0 → 5.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/hooks/useDocument.js +21 -5
- package/dist/admin/hooks/useDocument.js.map +1 -1
- package/dist/admin/hooks/useDocument.mjs +22 -6
- package/dist/admin/hooks/useDocument.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.js +1 -0
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +3 -2
- package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.mjs +4 -4
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +71 -44
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +54 -46
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +107 -88
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +109 -90
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +91 -106
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +94 -109
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js +43 -23
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs +45 -25
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +2 -2
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +30 -19
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +34 -23
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.mjs +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.mjs +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.mjs +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.js +23 -3
- package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormLayout.mjs +4 -3
- package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/Header.js +59 -9
- package/dist/admin/pages/EditView/components/Header.js.map +1 -1
- package/dist/admin/pages/EditView/components/Header.mjs +63 -13
- package/dist/admin/pages/EditView/components/Header.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/InputRenderer.js +19 -7
- package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
- package/dist/admin/pages/EditView/components/InputRenderer.mjs +20 -8
- package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +47 -0
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.mjs +50 -3
- package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js +15 -19
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs +15 -20
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs.map +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/NonRepeatable.d.ts +3 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Repeatable.d.ts +3 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +1 -1
- package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +3 -0
- package/dist/admin/src/pages/ListView/components/Filters.d.ts +3 -0
- package/dist/admin/translations/en.json.js +3 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +3 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/controllers/collection-types.js +25 -28
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +20 -23
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/controllers/single-types.js +2 -1
- package/dist/server/controllers/single-types.js.map +1 -1
- package/dist/server/controllers/single-types.mjs +2 -1
- package/dist/server/controllers/single-types.mjs.map +1 -1
- package/dist/server/services/document-manager.js +10 -9
- package/dist/server/services/document-manager.js.map +1 -1
- package/dist/server/services/document-manager.mjs +10 -9
- package/dist/server/services/document-manager.mjs.map +1 -1
- package/dist/server/services/document-metadata.js +84 -41
- package/dist/server/services/document-metadata.js.map +1 -1
- package/dist/server/services/document-metadata.mjs +85 -42
- package/dist/server/services/document-metadata.mjs.map +1 -1
- package/dist/server/services/populate-builder.js +11 -0
- package/dist/server/services/populate-builder.js.map +1 -1
- package/dist/server/services/populate-builder.mjs +12 -1
- package/dist/server/services/populate-builder.mjs.map +1 -1
- package/dist/server/services/utils/configuration/attributes.js +2 -1
- package/dist/server/services/utils/configuration/attributes.js.map +1 -1
- package/dist/server/services/utils/configuration/attributes.mjs +2 -1
- package/dist/server/services/utils/configuration/attributes.mjs.map +1 -1
- package/dist/server/services/utils/draft.js +8 -1
- package/dist/server/services/utils/draft.js.map +1 -1
- package/dist/server/services/utils/draft.mjs +8 -1
- package/dist/server/services/utils/draft.mjs.map +1 -1
- package/dist/server/services/utils/populate.js +73 -8
- package/dist/server/services/utils/populate.js.map +1 -1
- package/dist/server/services/utils/populate.mjs +73 -9
- package/dist/server/services/utils/populate.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +2 -2
- package/dist/server/src/index.d.ts +18 -3
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +9 -3
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -0
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +18 -3
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/populate-builder.d.ts +7 -0
- package/dist/server/src/services/populate-builder.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/attributes.d.ts.map +1 -1
- package/dist/server/src/services/utils/draft.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +21 -17
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-metadata.js","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\nimport { getPopulateForValidation } from './utils/populate';\n\nconst { getScalarAttributes, getMediaAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\nconst AVAILABLE_STATUS_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'documentId',\n];\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n const { populate = {}, fields = [] } = getPopulateForValidation(uid);\n\n // Include non-translatable scalar and media fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n let nonLocalizedMediaFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n const model = strapi.getModel(uid);\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get scalar and media attributes separately\n const scalarAttrs = getScalarAttributes(model);\n const mediaAttrs = getMediaAttributes(model);\n\n // Separate scalar fields (can be in fields array) from media fields (need to be populated)\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n nonLocalizedMediaFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && mediaAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n // Build populate object for non-localized media fields\n const mediaPopulate = nonLocalizedMediaFields.reduce(\n (acc, field) => {\n acc[field] = {\n populate: {\n folder: true,\n },\n };\n return acc;\n },\n {} as Record<string, { populate: { folder: boolean } }>\n );\n\n const params = {\n populate: {\n ...populate,\n ...mediaPopulate,\n // NOTE: creator fields are selected in this way to avoid exposing sensitive data\n createdBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n updatedBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const meta = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations) {\n const otherStatus = await this.getManyAvailableStatus(uid, document.localizations);\n\n document.localizations = document.localizations.map((d) => {\n const status = otherStatus.find(\n (s) => s.documentId === d.documentId && s.locale === d.locale\n );\n return {\n ...d,\n status: this.getStatus(d, status ? [status] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","getMediaAttributes","contentTypes","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","publishedAt","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","$null","query","findMany","select","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","populate","fields","getPopulateForValidation","nonLocalizedFields","nonLocalizedMediaFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","mediaAttrs","field","includes","error","mediaPopulate","reduce","acc","folder","params","createdBy","updatedBy","uniq","filters","dbParams","get","transform","versions","db","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","otherStatus","s","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-metadata.js","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\n\nconst { getScalarAttributes, getMediaAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\n// Scalar fields that can be used in a DB `select`\nconst AVAILABLE_STATUS_SCALAR_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n];\n// Relation populate shared by both the fast path and the full path\nconst AVAILABLE_STATUS_POPULATE = {\n createdBy: { select: ['id', 'firstname', 'lastname', 'email'] },\n updatedBy: { select: ['id', 'firstname', 'lastname', 'email'] },\n};\n// All fields to pick from a hydrated result (scalars + populated relations + virtual)\nconst AVAILABLE_STATUS_FIELDS = [\n ...AVAILABLE_STATUS_SCALAR_FIELDS,\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n];\n\n/** Returns a DB filter that matches the opposite publish status. */\nconst oppositePublishStatus = (publishedAt: unknown) =>\n publishedAt !== null ? { $null: true } : { $notNull: true };\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: AVAILABLE_STATUS_SCALAR_FIELDS,\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n const model = strapi.getModel(uid);\n const hasDnP = contentTypes.hasDraftAndPublish(model);\n const isLocalized = (model.pluginOptions?.i18n as any)?.localized === true;\n\n if (!availableLocales && !availableStatus) {\n // Nothing to compute.\n return { availableLocales: [], availableStatus: [], versions: [] as DocumentVersion[] };\n }\n if (!isLocalized && !hasDnP) {\n // If there are no locales and no draft/publish, there's only ever 1 version of any document.\n return { availableLocales: [], availableStatus: [], versions: [] as DocumentVersion[] };\n }\n\n const onlyStatusIsRelevant = hasDnP && (!isLocalized || !availableLocales);\n if (onlyStatusIsRelevant) {\n const otherVersion = availableStatus\n ? await strapi.db.query(uid).findOne({\n where: {\n documentId: version.documentId,\n ...(version.locale ? { locale: version.locale } : {}),\n publishedAt: oppositePublishStatus(version.publishedAt),\n },\n select: AVAILABLE_STATUS_SCALAR_FIELDS,\n populate: AVAILABLE_STATUS_POPULATE,\n })\n : null;\n return {\n availableLocales: [],\n availableStatus: otherVersion ? [pick(AVAILABLE_STATUS_FIELDS, otherVersion)] : [],\n versions: [] as DocumentVersion[],\n };\n }\n\n // Full path for localized content types\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n\n // Include non-translatable scalar and media fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n let nonLocalizedMediaFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get scalar and media attributes separately\n const scalarAttrs = getScalarAttributes(model);\n const mediaAttrs = getMediaAttributes(model);\n\n // Separate scalar fields (can be in fields array) from media fields (need to be populated)\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n nonLocalizedMediaFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && mediaAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n // Build populate object for non-localized media fields\n const mediaPopulate = nonLocalizedMediaFields.reduce(\n (acc, field) => {\n acc[field] = {\n populate: {\n folder: true,\n },\n };\n return acc;\n },\n {} as Record<string, { populate: { folder: boolean } }>\n );\n\n const params = {\n populate: {\n ...mediaPopulate,\n ...AVAILABLE_STATUS_POPULATE,\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n versions,\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const { versions, ...meta } = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations?.length) {\n document.localizations = document.localizations.map((d) => {\n // Find the counterpart version (same documentId + locale, opposite publishedAt) from\n // the already-fetched versions array, avoiding an extra DB query.\n const counterpart = versions.find(\n (v) =>\n v.documentId === d.documentId &&\n v.locale === d.locale &&\n (d.publishedAt === null) !== (v.publishedAt === null)\n );\n return {\n ...d,\n status: this.getStatus(d, counterpart ? [counterpart] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","getMediaAttributes","contentTypes","AVAILABLE_STATUS_SCALAR_FIELDS","AVAILABLE_STATUS_POPULATE","createdBy","select","updatedBy","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","oppositePublishStatus","publishedAt","$null","$notNull","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","query","findMany","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","hasDnP","isLocalized","pluginOptions","i18n","localized","versions","onlyStatusIsRelevant","db","findOne","populate","nonLocalizedFields","nonLocalizedMediaFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","mediaAttrs","field","includes","error","mediaPopulate","reduce","acc","folder","params","fields","uniq","filters","dbParams","get","transform","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","counterpart","undefined"],"mappings":"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"}
|
|
@@ -1,15 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pick, uniq, groupBy } from 'lodash/fp';
|
|
2
2
|
import { contentTypes, async } from '@strapi/utils';
|
|
3
|
-
import { getPopulateForValidation } from './utils/populate.mjs';
|
|
4
3
|
|
|
5
4
|
const { getScalarAttributes, getMediaAttributes } = contentTypes;
|
|
6
|
-
|
|
5
|
+
// Scalar fields that can be used in a DB `select`
|
|
6
|
+
const AVAILABLE_STATUS_SCALAR_FIELDS = [
|
|
7
7
|
'id',
|
|
8
8
|
'documentId',
|
|
9
9
|
'locale',
|
|
10
10
|
'updatedAt',
|
|
11
11
|
'createdAt',
|
|
12
|
-
'publishedAt'
|
|
12
|
+
'publishedAt'
|
|
13
|
+
];
|
|
14
|
+
// Relation populate shared by both the fast path and the full path
|
|
15
|
+
const AVAILABLE_STATUS_POPULATE = {
|
|
16
|
+
createdBy: {
|
|
17
|
+
select: [
|
|
18
|
+
'id',
|
|
19
|
+
'firstname',
|
|
20
|
+
'lastname',
|
|
21
|
+
'email'
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
updatedBy: {
|
|
25
|
+
select: [
|
|
26
|
+
'id',
|
|
27
|
+
'firstname',
|
|
28
|
+
'lastname',
|
|
29
|
+
'email'
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
// All fields to pick from a hydrated result (scalars + populated relations + virtual)
|
|
34
|
+
const AVAILABLE_STATUS_FIELDS = [
|
|
35
|
+
...AVAILABLE_STATUS_SCALAR_FIELDS,
|
|
13
36
|
'createdBy',
|
|
14
37
|
'updatedBy',
|
|
15
38
|
'status'
|
|
@@ -20,9 +43,13 @@ const AVAILABLE_LOCALES_FIELDS = [
|
|
|
20
43
|
'locale',
|
|
21
44
|
'updatedAt',
|
|
22
45
|
'createdAt',
|
|
23
|
-
'publishedAt'
|
|
24
|
-
'documentId'
|
|
46
|
+
'publishedAt'
|
|
25
47
|
];
|
|
48
|
+
/** Returns a DB filter that matches the opposite publish status. */ const oppositePublishStatus = (publishedAt)=>publishedAt !== null ? {
|
|
49
|
+
$null: true
|
|
50
|
+
} : {
|
|
51
|
+
$notNull: true
|
|
52
|
+
};
|
|
26
53
|
const CONTENT_MANAGER_STATUS = {
|
|
27
54
|
PUBLISHED: 'published',
|
|
28
55
|
DRAFT: 'draft',
|
|
@@ -110,14 +137,7 @@ var documentMetadata = (({ strapi })=>({
|
|
|
110
137
|
}
|
|
111
138
|
return strapi.query(uid).findMany({
|
|
112
139
|
where,
|
|
113
|
-
select:
|
|
114
|
-
'id',
|
|
115
|
-
'documentId',
|
|
116
|
-
'locale',
|
|
117
|
-
'updatedAt',
|
|
118
|
-
'createdAt',
|
|
119
|
-
'publishedAt'
|
|
120
|
-
]
|
|
140
|
+
select: AVAILABLE_STATUS_SCALAR_FIELDS
|
|
121
141
|
});
|
|
122
142
|
},
|
|
123
143
|
getStatus (version, otherDocumentStatuses) {
|
|
@@ -146,9 +166,49 @@ var documentMetadata = (({ strapi })=>({
|
|
|
146
166
|
// We could refactor this so the locales are only loaded when they're
|
|
147
167
|
// needed. e.g. in the bulk locale action modal.
|
|
148
168
|
async getMetadata (uid, version, { availableLocales = true, availableStatus = true } = {}) {
|
|
169
|
+
const model = strapi.getModel(uid);
|
|
170
|
+
const hasDnP = contentTypes.hasDraftAndPublish(model);
|
|
171
|
+
const isLocalized = model.pluginOptions?.i18n?.localized === true;
|
|
172
|
+
if (!availableLocales && !availableStatus) {
|
|
173
|
+
// Nothing to compute.
|
|
174
|
+
return {
|
|
175
|
+
availableLocales: [],
|
|
176
|
+
availableStatus: [],
|
|
177
|
+
versions: []
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (!isLocalized && !hasDnP) {
|
|
181
|
+
// If there are no locales and no draft/publish, there's only ever 1 version of any document.
|
|
182
|
+
return {
|
|
183
|
+
availableLocales: [],
|
|
184
|
+
availableStatus: [],
|
|
185
|
+
versions: []
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
const onlyStatusIsRelevant = hasDnP && (!isLocalized || !availableLocales);
|
|
189
|
+
if (onlyStatusIsRelevant) {
|
|
190
|
+
const otherVersion = availableStatus ? await strapi.db.query(uid).findOne({
|
|
191
|
+
where: {
|
|
192
|
+
documentId: version.documentId,
|
|
193
|
+
...version.locale ? {
|
|
194
|
+
locale: version.locale
|
|
195
|
+
} : {},
|
|
196
|
+
publishedAt: oppositePublishStatus(version.publishedAt)
|
|
197
|
+
},
|
|
198
|
+
select: AVAILABLE_STATUS_SCALAR_FIELDS,
|
|
199
|
+
populate: AVAILABLE_STATUS_POPULATE
|
|
200
|
+
}) : null;
|
|
201
|
+
return {
|
|
202
|
+
availableLocales: [],
|
|
203
|
+
availableStatus: otherVersion ? [
|
|
204
|
+
pick(AVAILABLE_STATUS_FIELDS, otherVersion)
|
|
205
|
+
] : [],
|
|
206
|
+
versions: []
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
// Full path for localized content types
|
|
149
210
|
// TODO: Ignore publishedAt if availableStatus=false, and ignore locale if
|
|
150
211
|
// i18n is disabled
|
|
151
|
-
const { populate = {}, fields = [] } = getPopulateForValidation(uid);
|
|
152
212
|
// Include non-translatable scalar and media fields in availableLocales for i18n prefilling
|
|
153
213
|
let nonLocalizedFields = [];
|
|
154
214
|
let nonLocalizedMediaFields = [];
|
|
@@ -157,7 +217,6 @@ var documentMetadata = (({ strapi })=>({
|
|
|
157
217
|
if (i18nPlugin) {
|
|
158
218
|
const i18nService = i18nPlugin.service('content-types');
|
|
159
219
|
if (i18nService?.getNonLocalizedAttributes) {
|
|
160
|
-
const model = strapi.getModel(uid);
|
|
161
220
|
if (model?.attributes) {
|
|
162
221
|
const allNonLocalized = i18nService.getNonLocalizedAttributes(model);
|
|
163
222
|
// Get scalar and media attributes separately
|
|
@@ -183,29 +242,11 @@ var documentMetadata = (({ strapi })=>({
|
|
|
183
242
|
}, {});
|
|
184
243
|
const params = {
|
|
185
244
|
populate: {
|
|
186
|
-
...populate,
|
|
187
245
|
...mediaPopulate,
|
|
188
|
-
|
|
189
|
-
createdBy: {
|
|
190
|
-
select: [
|
|
191
|
-
'id',
|
|
192
|
-
'firstname',
|
|
193
|
-
'lastname',
|
|
194
|
-
'email'
|
|
195
|
-
]
|
|
196
|
-
},
|
|
197
|
-
updatedBy: {
|
|
198
|
-
select: [
|
|
199
|
-
'id',
|
|
200
|
-
'firstname',
|
|
201
|
-
'lastname',
|
|
202
|
-
'email'
|
|
203
|
-
]
|
|
204
|
-
}
|
|
246
|
+
...AVAILABLE_STATUS_POPULATE
|
|
205
247
|
},
|
|
206
248
|
fields: uniq([
|
|
207
249
|
...AVAILABLE_LOCALES_FIELDS,
|
|
208
|
-
...fields,
|
|
209
250
|
...nonLocalizedFields
|
|
210
251
|
]),
|
|
211
252
|
filters: {
|
|
@@ -221,7 +262,8 @@ var documentMetadata = (({ strapi })=>({
|
|
|
221
262
|
availableLocales: availableLocalesResult,
|
|
222
263
|
availableStatus: availableStatusResult ? [
|
|
223
264
|
availableStatusResult
|
|
224
|
-
] : []
|
|
265
|
+
] : [],
|
|
266
|
+
versions
|
|
225
267
|
};
|
|
226
268
|
},
|
|
227
269
|
/**
|
|
@@ -243,16 +285,17 @@ var documentMetadata = (({ strapi })=>({
|
|
|
243
285
|
if (!hasDraftAndPublish) {
|
|
244
286
|
opts.availableStatus = false;
|
|
245
287
|
}
|
|
246
|
-
const meta = await this.getMetadata(uid, document, opts);
|
|
288
|
+
const { versions, ...meta } = await this.getMetadata(uid, document, opts);
|
|
247
289
|
// Populate localization statuses
|
|
248
|
-
if (document.localizations) {
|
|
249
|
-
const otherStatus = await this.getManyAvailableStatus(uid, document.localizations);
|
|
290
|
+
if (document.localizations?.length) {
|
|
250
291
|
document.localizations = document.localizations.map((d)=>{
|
|
251
|
-
|
|
292
|
+
// Find the counterpart version (same documentId + locale, opposite publishedAt) from
|
|
293
|
+
// the already-fetched versions array, avoiding an extra DB query.
|
|
294
|
+
const counterpart = versions.find((v)=>v.documentId === d.documentId && v.locale === d.locale && d.publishedAt === null !== (v.publishedAt === null));
|
|
252
295
|
return {
|
|
253
296
|
...d,
|
|
254
|
-
status: this.getStatus(d,
|
|
255
|
-
|
|
297
|
+
status: this.getStatus(d, counterpart ? [
|
|
298
|
+
counterpart
|
|
256
299
|
] : [])
|
|
257
300
|
};
|
|
258
301
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-metadata.mjs","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\nimport { getPopulateForValidation } from './utils/populate';\n\nconst { getScalarAttributes, getMediaAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\nconst AVAILABLE_STATUS_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n 'documentId',\n];\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n const { populate = {}, fields = [] } = getPopulateForValidation(uid);\n\n // Include non-translatable scalar and media fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n let nonLocalizedMediaFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n const model = strapi.getModel(uid);\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get scalar and media attributes separately\n const scalarAttrs = getScalarAttributes(model);\n const mediaAttrs = getMediaAttributes(model);\n\n // Separate scalar fields (can be in fields array) from media fields (need to be populated)\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n nonLocalizedMediaFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && mediaAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n // Build populate object for non-localized media fields\n const mediaPopulate = nonLocalizedMediaFields.reduce(\n (acc, field) => {\n acc[field] = {\n populate: {\n folder: true,\n },\n };\n return acc;\n },\n {} as Record<string, { populate: { folder: boolean } }>\n );\n\n const params = {\n populate: {\n ...populate,\n ...mediaPopulate,\n // NOTE: creator fields are selected in this way to avoid exposing sensitive data\n createdBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n updatedBy: {\n select: ['id', 'firstname', 'lastname', 'email'],\n },\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const meta = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations) {\n const otherStatus = await this.getManyAvailableStatus(uid, document.localizations);\n\n document.localizations = document.localizations.map((d) => {\n const status = otherStatus.find(\n (s) => s.documentId === d.documentId && s.locale === d.locale\n );\n return {\n ...d,\n status: this.getStatus(d, status ? [status] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","getMediaAttributes","contentTypes","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","publishedAt","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","$null","query","findMany","select","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","populate","fields","getPopulateForValidation","nonLocalizedFields","nonLocalizedMediaFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","mediaAttrs","field","includes","error","mediaPopulate","reduce","acc","folder","params","createdBy","updatedBy","uniq","filters","dbParams","get","transform","versions","db","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","otherStatus","s","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-metadata.mjs","sources":["../../../server/src/services/document-metadata.ts"],"sourcesContent":["import { groupBy, pick, uniq } from 'lodash/fp';\n\nimport { async, contentTypes } from '@strapi/utils';\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport type { DocumentMetadata } from '../../../shared/contracts/collection-types';\n\nconst { getScalarAttributes, getMediaAttributes } = contentTypes;\n\nexport interface DocumentVersion {\n id: string | number;\n documentId: Modules.Documents.ID;\n locale?: string;\n localizations?: DocumentVersion[];\n updatedAt?: string | null | Date;\n publishedAt?: string | null | Date;\n}\n\n// Scalar fields that can be used in a DB `select`\nconst AVAILABLE_STATUS_SCALAR_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n];\n// Relation populate shared by both the fast path and the full path\nconst AVAILABLE_STATUS_POPULATE = {\n createdBy: { select: ['id', 'firstname', 'lastname', 'email'] },\n updatedBy: { select: ['id', 'firstname', 'lastname', 'email'] },\n};\n// All fields to pick from a hydrated result (scalars + populated relations + virtual)\nconst AVAILABLE_STATUS_FIELDS = [\n ...AVAILABLE_STATUS_SCALAR_FIELDS,\n 'createdBy',\n 'updatedBy',\n 'status',\n];\nconst AVAILABLE_LOCALES_FIELDS = [\n 'id',\n 'documentId',\n 'locale',\n 'updatedAt',\n 'createdAt',\n 'publishedAt',\n];\n\n/** Returns a DB filter that matches the opposite publish status. */\nconst oppositePublishStatus = (publishedAt: unknown) =>\n publishedAt !== null ? { $null: true } : { $notNull: true };\n\nconst CONTENT_MANAGER_STATUS = {\n PUBLISHED: 'published',\n DRAFT: 'draft',\n MODIFIED: 'modified',\n};\n\n/**\n * Controls the metadata properties to be returned\n *\n * If `availableLocales` is set to `true` (default), the returned metadata will include\n * the available locales of the document for its current status.\n *\n * If `availableStatus` is set to `true` (default), the returned metadata will include\n * the available status of the document for its current locale.\n */\nexport interface GetMetadataOptions {\n availableLocales?: boolean;\n availableStatus?: boolean;\n}\n\n/**\n * Checks if the provided document version has been modified after all other versions.\n */\nconst getIsVersionLatestModification = (\n version?: DocumentVersion,\n otherVersion?: DocumentVersion\n): boolean => {\n if (!version || !version.updatedAt) {\n return false;\n }\n\n const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;\n\n const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;\n\n return versionUpdatedAt > otherUpdatedAt;\n};\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n /**\n * Returns available locales of a document for the current status\n */\n async getAvailableLocales(\n uid: UID.ContentType,\n version: DocumentVersion,\n allVersions: DocumentVersion[]\n ) {\n // Group all versions by locale\n const versionsByLocale = groupBy('locale', allVersions);\n\n // Delete the current locale\n if (version.locale) {\n delete versionsByLocale[version.locale];\n }\n\n // For each locale, get the ones with the same status\n // There will not be a draft and a version counterpart if the content\n // type does not have draft and publish\n const model = strapi.getModel(uid);\n\n const mappingResult = await async.map(\n Object.values(versionsByLocale),\n async (localeVersions: DocumentVersion[]) => {\n if (!contentTypes.hasDraftAndPublish(model)) {\n return localeVersions[0];\n }\n\n const draftVersion = localeVersions.find((v) => v.publishedAt === null);\n const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);\n\n if (!draftVersion) {\n return;\n }\n\n return {\n ...draftVersion,\n status: this.getStatus(draftVersion, otherVersions as any),\n };\n }\n );\n\n return (\n mappingResult\n // Filter just in case there is a document with no drafts\n .filter(Boolean) as unknown as DocumentMetadata['availableLocales']\n );\n },\n\n /**\n * Returns available status of a document for the current locale\n */\n getAvailableStatus(version: DocumentVersion, allVersions: DocumentVersion[]) {\n // Find the other status of the document\n const status =\n version.publishedAt !== null\n ? CONTENT_MANAGER_STATUS.DRAFT\n : CONTENT_MANAGER_STATUS.PUBLISHED;\n\n // Get version that match the current locale and not match the current status\n const availableStatus = allVersions.find((v) => {\n const matchLocale = v.locale === version.locale;\n const matchStatus = status === 'published' ? v.publishedAt !== null : v.publishedAt === null;\n return matchLocale && matchStatus;\n });\n\n if (!availableStatus) return availableStatus;\n\n // Pick status fields (at fields, status, by fields), use lodash fp\n return pick(AVAILABLE_STATUS_FIELDS, availableStatus);\n },\n\n /**\n * Get the available status of many documents, useful for batch operations\n * @param uid\n * @param documents\n * @returns\n */\n async getManyAvailableStatus(uid: UID.ContentType, documents: DocumentVersion[]) {\n if (!documents.length) return [];\n\n // The status and locale of all documents should be the same\n const status = documents[0].publishedAt !== null ? 'published' : 'draft';\n const locales = documents.map((d) => d.locale).filter(Boolean);\n\n const where: Record<string, any> = {\n documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },\n publishedAt: { $null: status === 'published' },\n };\n\n // If there is any locale to filter (if i18n is enabled)\n if (locales.length) {\n where.locale = { $in: locales };\n }\n\n return strapi.query(uid).findMany({\n where,\n select: AVAILABLE_STATUS_SCALAR_FIELDS,\n });\n },\n\n getStatus(version: DocumentVersion, otherDocumentStatuses?: DocumentMetadata['availableStatus']) {\n let draftVersion: DocumentVersion | undefined;\n let publishedVersion: DocumentVersion | undefined;\n\n if (version.publishedAt) {\n publishedVersion = version;\n } else {\n draftVersion = version;\n }\n\n const otherVersion = otherDocumentStatuses?.at(0);\n if (otherVersion?.publishedAt) {\n publishedVersion = otherVersion;\n } else if (otherVersion) {\n draftVersion = otherVersion;\n }\n\n if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;\n if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;\n\n /*\n * The document is modified if the draft version has been updated more\n * recently than the published version.\n */\n const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);\n return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;\n },\n\n // TODO is it necessary to return metadata on every page of the CM\n // We could refactor this so the locales are only loaded when they're\n // needed. e.g. in the bulk locale action modal.\n async getMetadata(\n uid: UID.ContentType,\n version: DocumentVersion,\n { availableLocales = true, availableStatus = true }: GetMetadataOptions = {}\n ) {\n const model = strapi.getModel(uid);\n const hasDnP = contentTypes.hasDraftAndPublish(model);\n const isLocalized = (model.pluginOptions?.i18n as any)?.localized === true;\n\n if (!availableLocales && !availableStatus) {\n // Nothing to compute.\n return { availableLocales: [], availableStatus: [], versions: [] as DocumentVersion[] };\n }\n if (!isLocalized && !hasDnP) {\n // If there are no locales and no draft/publish, there's only ever 1 version of any document.\n return { availableLocales: [], availableStatus: [], versions: [] as DocumentVersion[] };\n }\n\n const onlyStatusIsRelevant = hasDnP && (!isLocalized || !availableLocales);\n if (onlyStatusIsRelevant) {\n const otherVersion = availableStatus\n ? await strapi.db.query(uid).findOne({\n where: {\n documentId: version.documentId,\n ...(version.locale ? { locale: version.locale } : {}),\n publishedAt: oppositePublishStatus(version.publishedAt),\n },\n select: AVAILABLE_STATUS_SCALAR_FIELDS,\n populate: AVAILABLE_STATUS_POPULATE,\n })\n : null;\n return {\n availableLocales: [],\n availableStatus: otherVersion ? [pick(AVAILABLE_STATUS_FIELDS, otherVersion)] : [],\n versions: [] as DocumentVersion[],\n };\n }\n\n // Full path for localized content types\n // TODO: Ignore publishedAt if availableStatus=false, and ignore locale if\n // i18n is disabled\n\n // Include non-translatable scalar and media fields in availableLocales for i18n prefilling\n let nonLocalizedFields: string[] = [];\n let nonLocalizedMediaFields: string[] = [];\n try {\n const i18nPlugin = strapi.plugin('i18n');\n if (i18nPlugin) {\n const i18nService = i18nPlugin.service('content-types');\n if (i18nService?.getNonLocalizedAttributes) {\n if (model?.attributes) {\n const allNonLocalized = i18nService.getNonLocalizedAttributes(model);\n // Get scalar and media attributes separately\n const scalarAttrs = getScalarAttributes(model);\n const mediaAttrs = getMediaAttributes(model);\n\n // Separate scalar fields (can be in fields array) from media fields (need to be populated)\n nonLocalizedFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && scalarAttrs.includes(field)\n );\n nonLocalizedMediaFields = allNonLocalized.filter(\n (field: string) => field in model.attributes && mediaAttrs.includes(field)\n );\n }\n }\n }\n } catch (error) {\n // i18n plugin might not be enabled or might error, ignore silently\n }\n\n // Build populate object for non-localized media fields\n const mediaPopulate = nonLocalizedMediaFields.reduce(\n (acc, field) => {\n acc[field] = {\n populate: {\n folder: true,\n },\n };\n return acc;\n },\n {} as Record<string, { populate: { folder: boolean } }>\n );\n\n const params = {\n populate: {\n ...mediaPopulate,\n ...AVAILABLE_STATUS_POPULATE,\n },\n fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...nonLocalizedFields]),\n filters: {\n documentId: version.documentId,\n },\n };\n\n const dbParams = strapi.get('query-params').transform(uid, params);\n const versions = await strapi.db.query(uid).findMany(dbParams);\n\n // TODO: Remove use of available locales and use localizations instead\n const availableLocalesResult = availableLocales\n ? await this.getAvailableLocales(uid, version, versions)\n : [];\n\n const availableStatusResult = availableStatus\n ? this.getAvailableStatus(version, versions)\n : null;\n\n return {\n availableLocales: availableLocalesResult,\n availableStatus: availableStatusResult ? [availableStatusResult] : [],\n versions,\n };\n },\n\n /**\n * Returns associated metadata of a document:\n * - Available locales of the document for the current status\n * - Available status of the document for the current locale\n */\n async formatDocumentWithMetadata(\n uid: UID.ContentType,\n document: DocumentVersion,\n opts: GetMetadataOptions = {}\n ) {\n if (!document) {\n return {\n data: document,\n meta: {\n availableLocales: [],\n availableStatus: [],\n },\n };\n }\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n\n // Ignore available status if the content type does not have draft and publish\n if (!hasDraftAndPublish) {\n opts.availableStatus = false;\n }\n\n const { versions, ...meta } = await this.getMetadata(uid, document, opts);\n\n // Populate localization statuses\n if (document.localizations?.length) {\n document.localizations = document.localizations.map((d) => {\n // Find the counterpart version (same documentId + locale, opposite publishedAt) from\n // the already-fetched versions array, avoiding an extra DB query.\n const counterpart = versions.find(\n (v) =>\n v.documentId === d.documentId &&\n v.locale === d.locale &&\n (d.publishedAt === null) !== (v.publishedAt === null)\n );\n return {\n ...d,\n status: this.getStatus(d, counterpart ? [counterpart] : []),\n };\n });\n }\n\n return {\n data: {\n ...document,\n // Add status to the document only if draft and publish is enabled\n status: hasDraftAndPublish\n ? this.getStatus(document, meta.availableStatus as any)\n : undefined,\n },\n meta,\n };\n },\n});\n"],"names":["getScalarAttributes","getMediaAttributes","contentTypes","AVAILABLE_STATUS_SCALAR_FIELDS","AVAILABLE_STATUS_POPULATE","createdBy","select","updatedBy","AVAILABLE_STATUS_FIELDS","AVAILABLE_LOCALES_FIELDS","oppositePublishStatus","publishedAt","$null","$notNull","CONTENT_MANAGER_STATUS","PUBLISHED","DRAFT","MODIFIED","getIsVersionLatestModification","version","otherVersion","updatedAt","versionUpdatedAt","Date","getTime","otherUpdatedAt","strapi","getAvailableLocales","uid","allVersions","versionsByLocale","groupBy","locale","model","getModel","mappingResult","async","map","Object","values","localeVersions","hasDraftAndPublish","draftVersion","find","v","otherVersions","filter","id","status","getStatus","Boolean","getAvailableStatus","availableStatus","matchLocale","matchStatus","pick","getManyAvailableStatus","documents","length","locales","d","where","documentId","$in","query","findMany","otherDocumentStatuses","publishedVersion","at","isDraftModified","getMetadata","availableLocales","hasDnP","isLocalized","pluginOptions","i18n","localized","versions","onlyStatusIsRelevant","db","findOne","populate","nonLocalizedFields","nonLocalizedMediaFields","i18nPlugin","plugin","i18nService","service","getNonLocalizedAttributes","attributes","allNonLocalized","scalarAttrs","mediaAttrs","field","includes","error","mediaPopulate","reduce","acc","folder","params","fields","uniq","filters","dbParams","get","transform","availableLocalesResult","availableStatusResult","formatDocumentWithMetadata","document","opts","data","meta","localizations","counterpart","undefined"],"mappings":"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"}
|
|
@@ -54,6 +54,17 @@ var populate = require('./utils/populate.js');
|
|
|
54
54
|
return builder;
|
|
55
55
|
},
|
|
56
56
|
/**
|
|
57
|
+
* Override the populate for specific attributes, taking precedence over
|
|
58
|
+
* query-derived or deep populate defaults.
|
|
59
|
+
*
|
|
60
|
+
* @param overrides - Populate overrides to merge (e.g. { localizations: { fields: ['locale'] } })
|
|
61
|
+
*/ withPopulateOverride (overrides) {
|
|
62
|
+
const prev = getInitialPopulate;
|
|
63
|
+
// merge(base, overrides): overrides win for overlapping keys, so e.g. localizations
|
|
64
|
+
getInitialPopulate = async ()=>fp.merge(await prev() || {}, overrides);
|
|
65
|
+
return builder;
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
57
68
|
* Construct the populate object based on the builder options.
|
|
58
69
|
* @returns Populate object
|
|
59
70
|
*/ async build () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"populate-builder.js","sources":["../../../server/src/services/populate-builder.ts"],"sourcesContent":["import { isNil } from 'lodash/fp';\nimport type { UID } from '@strapi/types';\nimport { type Populate, getDeepPopulate, getQueryPopulate } from './utils/populate';\n\n/**\n * Builder to create a Strapi populate object.\n *\n * @param uid - Content type UID\n *\n * @example\n * const populate = await populateBuilder('api::article.article').countRelations().build();\n * // populate = { article: { populate: { count: true } } }\n *\n */\nconst populateBuilder = (uid: UID.Schema) => {\n let getInitialPopulate = async (): Promise<undefined | Populate> => {\n return undefined;\n };\n const deepPopulateOptions = {\n countMany: false,\n countOne: false,\n maxLevel: -1,\n };\n\n const builder = {\n /**\n * Populates all attribute fields present in a query.\n * @param query - Strapi query object\n */\n populateFromQuery(query: object) {\n getInitialPopulate = async () => getQueryPopulate(uid, query);\n return builder;\n },\n\n /**\n * Populate relations as count.\n * @param [options]\n * @param [options.toMany] - Populate XtoMany relations as count if true.\n * @param [options.toOne] - Populate XtoOne relations as count if true.\n */\n countRelations({ toMany, toOne } = { toMany: true, toOne: true }) {\n if (!isNil(toMany)) {\n deepPopulateOptions.countMany = toMany;\n }\n if (!isNil(toOne)) {\n deepPopulateOptions.countOne = toOne;\n }\n return builder;\n },\n\n /**\n * Populate relations deeply, up to a certain level.\n * @param [level=Infinity] - Max level of nested populate.\n */\n populateDeep(level = Infinity) {\n deepPopulateOptions.maxLevel = level;\n return builder;\n },\n\n /**\n * Construct the populate object based on the builder options.\n * @returns Populate object\n */\n async build() {\n const initialPopulate = await getInitialPopulate();\n\n if (deepPopulateOptions.maxLevel === -1) {\n return initialPopulate;\n }\n\n return getDeepPopulate(uid, { ...deepPopulateOptions, initialPopulate });\n },\n };\n\n return builder;\n};\n\nexport default () => populateBuilder;\n"],"names":["populateBuilder","uid","getInitialPopulate","undefined","deepPopulateOptions","countMany","countOne","maxLevel","builder","populateFromQuery","query","getQueryPopulate","countRelations","toMany","toOne","isNil","populateDeep","level","Infinity","build","initialPopulate","getDeepPopulate"],"mappings":";;;;;AAIA;;;;;;;;;IAUA,MAAMA,kBAAkB,CAACC,GAAAA,GAAAA;AACvB,IAAA,IAAIC,kBAAAA,GAAqB,UAAA;QACvB,OAAOC,SAAAA;AACT,IAAA,CAAA;AACA,IAAA,MAAMC,mBAAAA,GAAsB;QAC1BC,SAAAA,EAAW,KAAA;QACXC,QAAAA,EAAU,KAAA;AACVC,QAAAA,QAAAA,EAAU;AACZ,KAAA;AAEA,IAAA,MAAMC,OAAAA,GAAU;AACd;;;AAGC,QACDC,mBAAkBC,KAAa,EAAA;YAC7BR,kBAAAA,GAAqB,UAAYS,0BAAiBV,GAAAA,EAAKS,KAAAA,CAAAA;YACvD,OAAOF,OAAAA;AACT,QAAA,CAAA;AAEA;;;;;AAKC,QACDI,gBAAe,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAG;YAAED,MAAAA,EAAQ,IAAA;YAAMC,KAAAA,EAAO;SAAM,EAAA;YAC9D,IAAI,CAACC,SAAMF,MAAAA,CAAAA,EAAS;AAClBT,gBAAAA,mBAAAA,CAAoBC,SAAS,GAAGQ,MAAAA;AAClC,YAAA;YACA,IAAI,CAACE,SAAMD,KAAAA,CAAAA,EAAQ;AACjBV,gBAAAA,mBAAAA,CAAoBE,QAAQ,GAAGQ,KAAAA;AACjC,YAAA;YACA,OAAON,OAAAA;AACT,QAAA,CAAA;AAEA;;;QAIAQ,YAAAA,CAAAA,CAAaC,QAAQC,QAAQ,EAAA;AAC3Bd,YAAAA,mBAAAA,CAAoBG,QAAQ,GAAGU,KAAAA;YAC/B,OAAOT,OAAAA;AACT,QAAA,CAAA;AAEA;;;AAGC,QACD,
|
|
1
|
+
{"version":3,"file":"populate-builder.js","sources":["../../../server/src/services/populate-builder.ts"],"sourcesContent":["import { isNil, merge } from 'lodash/fp';\nimport type { UID } from '@strapi/types';\nimport { type Populate, getDeepPopulate, getQueryPopulate } from './utils/populate';\n\n/**\n * Builder to create a Strapi populate object.\n *\n * @param uid - Content type UID\n *\n * @example\n * const populate = await populateBuilder('api::article.article').countRelations().build();\n * // populate = { article: { populate: { count: true } } }\n *\n */\nconst populateBuilder = (uid: UID.Schema) => {\n let getInitialPopulate = async (): Promise<undefined | Populate> => {\n return undefined;\n };\n const deepPopulateOptions = {\n countMany: false,\n countOne: false,\n maxLevel: -1,\n };\n\n const builder = {\n /**\n * Populates all attribute fields present in a query.\n * @param query - Strapi query object\n */\n populateFromQuery(query: object) {\n getInitialPopulate = async () => getQueryPopulate(uid, query);\n return builder;\n },\n\n /**\n * Populate relations as count.\n * @param [options]\n * @param [options.toMany] - Populate XtoMany relations as count if true.\n * @param [options.toOne] - Populate XtoOne relations as count if true.\n */\n countRelations({ toMany, toOne } = { toMany: true, toOne: true }) {\n if (!isNil(toMany)) {\n deepPopulateOptions.countMany = toMany;\n }\n if (!isNil(toOne)) {\n deepPopulateOptions.countOne = toOne;\n }\n return builder;\n },\n\n /**\n * Populate relations deeply, up to a certain level.\n * @param [level=Infinity] - Max level of nested populate.\n */\n populateDeep(level = Infinity) {\n deepPopulateOptions.maxLevel = level;\n return builder;\n },\n\n /**\n * Override the populate for specific attributes, taking precedence over\n * query-derived or deep populate defaults.\n *\n * @param overrides - Populate overrides to merge (e.g. { localizations: { fields: ['locale'] } })\n */\n withPopulateOverride(overrides: Record<string, any>) {\n const prev = getInitialPopulate;\n // merge(base, overrides): overrides win for overlapping keys, so e.g. localizations\n getInitialPopulate = async () => merge((await prev()) || {}, overrides);\n return builder;\n },\n\n /**\n * Construct the populate object based on the builder options.\n * @returns Populate object\n */\n async build() {\n const initialPopulate = await getInitialPopulate();\n\n if (deepPopulateOptions.maxLevel === -1) {\n return initialPopulate;\n }\n\n return getDeepPopulate(uid, { ...deepPopulateOptions, initialPopulate });\n },\n };\n\n return builder;\n};\n\nexport default () => populateBuilder;\n"],"names":["populateBuilder","uid","getInitialPopulate","undefined","deepPopulateOptions","countMany","countOne","maxLevel","builder","populateFromQuery","query","getQueryPopulate","countRelations","toMany","toOne","isNil","populateDeep","level","Infinity","withPopulateOverride","overrides","prev","merge","build","initialPopulate","getDeepPopulate"],"mappings":";;;;;AAIA;;;;;;;;;IAUA,MAAMA,kBAAkB,CAACC,GAAAA,GAAAA;AACvB,IAAA,IAAIC,kBAAAA,GAAqB,UAAA;QACvB,OAAOC,SAAAA;AACT,IAAA,CAAA;AACA,IAAA,MAAMC,mBAAAA,GAAsB;QAC1BC,SAAAA,EAAW,KAAA;QACXC,QAAAA,EAAU,KAAA;AACVC,QAAAA,QAAAA,EAAU;AACZ,KAAA;AAEA,IAAA,MAAMC,OAAAA,GAAU;AACd;;;AAGC,QACDC,mBAAkBC,KAAa,EAAA;YAC7BR,kBAAAA,GAAqB,UAAYS,0BAAiBV,GAAAA,EAAKS,KAAAA,CAAAA;YACvD,OAAOF,OAAAA;AACT,QAAA,CAAA;AAEA;;;;;AAKC,QACDI,gBAAe,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAG;YAAED,MAAAA,EAAQ,IAAA;YAAMC,KAAAA,EAAO;SAAM,EAAA;YAC9D,IAAI,CAACC,SAAMF,MAAAA,CAAAA,EAAS;AAClBT,gBAAAA,mBAAAA,CAAoBC,SAAS,GAAGQ,MAAAA;AAClC,YAAA;YACA,IAAI,CAACE,SAAMD,KAAAA,CAAAA,EAAQ;AACjBV,gBAAAA,mBAAAA,CAAoBE,QAAQ,GAAGQ,KAAAA;AACjC,YAAA;YACA,OAAON,OAAAA;AACT,QAAA,CAAA;AAEA;;;QAIAQ,YAAAA,CAAAA,CAAaC,QAAQC,QAAQ,EAAA;AAC3Bd,YAAAA,mBAAAA,CAAoBG,QAAQ,GAAGU,KAAAA;YAC/B,OAAOT,OAAAA;AACT,QAAA,CAAA;AAEA;;;;;AAKC,QACDW,sBAAqBC,SAA8B,EAAA;AACjD,YAAA,MAAMC,IAAAA,GAAOnB,kBAAAA;;AAEbA,YAAAA,kBAAAA,GAAqB,UAAYoB,QAAAA,CAAO,MAAMD,IAAAA,EAAAA,IAAW,EAAC,EAAGD,SAAAA,CAAAA;YAC7D,OAAOZ,OAAAA;AACT,QAAA,CAAA;AAEA;;;AAGC,QACD,MAAMe,KAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMC,kBAAkB,MAAMtB,kBAAAA,EAAAA;AAE9B,YAAA,IAAIE,mBAAAA,CAAoBG,QAAQ,KAAK,EAAC,EAAG;gBACvC,OAAOiB,eAAAA;AACT,YAAA;AAEA,YAAA,OAAOC,yBAAgBxB,GAAAA,EAAK;AAAE,gBAAA,GAAGG,mBAAmB;AAAEoB,gBAAAA;AAAgB,aAAA,CAAA;AACxE,QAAA;AACF,KAAA;IAEA,OAAOhB,OAAAA;AACT,CAAA;AAEA,wBAAe,CAAA,IAAMR,eAAc;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNil } from 'lodash/fp';
|
|
1
|
+
import { merge, isNil } from 'lodash/fp';
|
|
2
2
|
import { getQueryPopulate, getDeepPopulate } from './utils/populate.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -52,6 +52,17 @@ import { getQueryPopulate, getDeepPopulate } from './utils/populate.mjs';
|
|
|
52
52
|
return builder;
|
|
53
53
|
},
|
|
54
54
|
/**
|
|
55
|
+
* Override the populate for specific attributes, taking precedence over
|
|
56
|
+
* query-derived or deep populate defaults.
|
|
57
|
+
*
|
|
58
|
+
* @param overrides - Populate overrides to merge (e.g. { localizations: { fields: ['locale'] } })
|
|
59
|
+
*/ withPopulateOverride (overrides) {
|
|
60
|
+
const prev = getInitialPopulate;
|
|
61
|
+
// merge(base, overrides): overrides win for overlapping keys, so e.g. localizations
|
|
62
|
+
getInitialPopulate = async ()=>merge(await prev() || {}, overrides);
|
|
63
|
+
return builder;
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
55
66
|
* Construct the populate object based on the builder options.
|
|
56
67
|
* @returns Populate object
|
|
57
68
|
*/ async build () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"populate-builder.mjs","sources":["../../../server/src/services/populate-builder.ts"],"sourcesContent":["import { isNil } from 'lodash/fp';\nimport type { UID } from '@strapi/types';\nimport { type Populate, getDeepPopulate, getQueryPopulate } from './utils/populate';\n\n/**\n * Builder to create a Strapi populate object.\n *\n * @param uid - Content type UID\n *\n * @example\n * const populate = await populateBuilder('api::article.article').countRelations().build();\n * // populate = { article: { populate: { count: true } } }\n *\n */\nconst populateBuilder = (uid: UID.Schema) => {\n let getInitialPopulate = async (): Promise<undefined | Populate> => {\n return undefined;\n };\n const deepPopulateOptions = {\n countMany: false,\n countOne: false,\n maxLevel: -1,\n };\n\n const builder = {\n /**\n * Populates all attribute fields present in a query.\n * @param query - Strapi query object\n */\n populateFromQuery(query: object) {\n getInitialPopulate = async () => getQueryPopulate(uid, query);\n return builder;\n },\n\n /**\n * Populate relations as count.\n * @param [options]\n * @param [options.toMany] - Populate XtoMany relations as count if true.\n * @param [options.toOne] - Populate XtoOne relations as count if true.\n */\n countRelations({ toMany, toOne } = { toMany: true, toOne: true }) {\n if (!isNil(toMany)) {\n deepPopulateOptions.countMany = toMany;\n }\n if (!isNil(toOne)) {\n deepPopulateOptions.countOne = toOne;\n }\n return builder;\n },\n\n /**\n * Populate relations deeply, up to a certain level.\n * @param [level=Infinity] - Max level of nested populate.\n */\n populateDeep(level = Infinity) {\n deepPopulateOptions.maxLevel = level;\n return builder;\n },\n\n /**\n * Construct the populate object based on the builder options.\n * @returns Populate object\n */\n async build() {\n const initialPopulate = await getInitialPopulate();\n\n if (deepPopulateOptions.maxLevel === -1) {\n return initialPopulate;\n }\n\n return getDeepPopulate(uid, { ...deepPopulateOptions, initialPopulate });\n },\n };\n\n return builder;\n};\n\nexport default () => populateBuilder;\n"],"names":["populateBuilder","uid","getInitialPopulate","undefined","deepPopulateOptions","countMany","countOne","maxLevel","builder","populateFromQuery","query","getQueryPopulate","countRelations","toMany","toOne","isNil","populateDeep","level","Infinity","build","initialPopulate","getDeepPopulate"],"mappings":";;;AAIA;;;;;;;;;IAUA,MAAMA,oBAAkB,CAACC,GAAAA,GAAAA;AACvB,IAAA,IAAIC,kBAAAA,GAAqB,UAAA;QACvB,OAAOC,SAAAA;AACT,IAAA,CAAA;AACA,IAAA,MAAMC,mBAAAA,GAAsB;QAC1BC,SAAAA,EAAW,KAAA;QACXC,QAAAA,EAAU,KAAA;AACVC,QAAAA,QAAAA,EAAU;AACZ,KAAA;AAEA,IAAA,MAAMC,OAAAA,GAAU;AACd;;;AAGC,QACDC,mBAAkBC,KAAa,EAAA;YAC7BR,kBAAAA,GAAqB,UAAYS,iBAAiBV,GAAAA,EAAKS,KAAAA,CAAAA;YACvD,OAAOF,OAAAA;AACT,QAAA,CAAA;AAEA;;;;;AAKC,QACDI,gBAAe,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAG;YAAED,MAAAA,EAAQ,IAAA;YAAMC,KAAAA,EAAO;SAAM,EAAA;YAC9D,IAAI,CAACC,MAAMF,MAAAA,CAAAA,EAAS;AAClBT,gBAAAA,mBAAAA,CAAoBC,SAAS,GAAGQ,MAAAA;AAClC,YAAA;YACA,IAAI,CAACE,MAAMD,KAAAA,CAAAA,EAAQ;AACjBV,gBAAAA,mBAAAA,CAAoBE,QAAQ,GAAGQ,KAAAA;AACjC,YAAA;YACA,OAAON,OAAAA;AACT,QAAA,CAAA;AAEA;;;QAIAQ,YAAAA,CAAAA,CAAaC,QAAQC,QAAQ,EAAA;AAC3Bd,YAAAA,mBAAAA,CAAoBG,QAAQ,GAAGU,KAAAA;YAC/B,OAAOT,OAAAA;AACT,QAAA,CAAA;AAEA;;;AAGC,QACD,
|
|
1
|
+
{"version":3,"file":"populate-builder.mjs","sources":["../../../server/src/services/populate-builder.ts"],"sourcesContent":["import { isNil, merge } from 'lodash/fp';\nimport type { UID } from '@strapi/types';\nimport { type Populate, getDeepPopulate, getQueryPopulate } from './utils/populate';\n\n/**\n * Builder to create a Strapi populate object.\n *\n * @param uid - Content type UID\n *\n * @example\n * const populate = await populateBuilder('api::article.article').countRelations().build();\n * // populate = { article: { populate: { count: true } } }\n *\n */\nconst populateBuilder = (uid: UID.Schema) => {\n let getInitialPopulate = async (): Promise<undefined | Populate> => {\n return undefined;\n };\n const deepPopulateOptions = {\n countMany: false,\n countOne: false,\n maxLevel: -1,\n };\n\n const builder = {\n /**\n * Populates all attribute fields present in a query.\n * @param query - Strapi query object\n */\n populateFromQuery(query: object) {\n getInitialPopulate = async () => getQueryPopulate(uid, query);\n return builder;\n },\n\n /**\n * Populate relations as count.\n * @param [options]\n * @param [options.toMany] - Populate XtoMany relations as count if true.\n * @param [options.toOne] - Populate XtoOne relations as count if true.\n */\n countRelations({ toMany, toOne } = { toMany: true, toOne: true }) {\n if (!isNil(toMany)) {\n deepPopulateOptions.countMany = toMany;\n }\n if (!isNil(toOne)) {\n deepPopulateOptions.countOne = toOne;\n }\n return builder;\n },\n\n /**\n * Populate relations deeply, up to a certain level.\n * @param [level=Infinity] - Max level of nested populate.\n */\n populateDeep(level = Infinity) {\n deepPopulateOptions.maxLevel = level;\n return builder;\n },\n\n /**\n * Override the populate for specific attributes, taking precedence over\n * query-derived or deep populate defaults.\n *\n * @param overrides - Populate overrides to merge (e.g. { localizations: { fields: ['locale'] } })\n */\n withPopulateOverride(overrides: Record<string, any>) {\n const prev = getInitialPopulate;\n // merge(base, overrides): overrides win for overlapping keys, so e.g. localizations\n getInitialPopulate = async () => merge((await prev()) || {}, overrides);\n return builder;\n },\n\n /**\n * Construct the populate object based on the builder options.\n * @returns Populate object\n */\n async build() {\n const initialPopulate = await getInitialPopulate();\n\n if (deepPopulateOptions.maxLevel === -1) {\n return initialPopulate;\n }\n\n return getDeepPopulate(uid, { ...deepPopulateOptions, initialPopulate });\n },\n };\n\n return builder;\n};\n\nexport default () => populateBuilder;\n"],"names":["populateBuilder","uid","getInitialPopulate","undefined","deepPopulateOptions","countMany","countOne","maxLevel","builder","populateFromQuery","query","getQueryPopulate","countRelations","toMany","toOne","isNil","populateDeep","level","Infinity","withPopulateOverride","overrides","prev","merge","build","initialPopulate","getDeepPopulate"],"mappings":";;;AAIA;;;;;;;;;IAUA,MAAMA,oBAAkB,CAACC,GAAAA,GAAAA;AACvB,IAAA,IAAIC,kBAAAA,GAAqB,UAAA;QACvB,OAAOC,SAAAA;AACT,IAAA,CAAA;AACA,IAAA,MAAMC,mBAAAA,GAAsB;QAC1BC,SAAAA,EAAW,KAAA;QACXC,QAAAA,EAAU,KAAA;AACVC,QAAAA,QAAAA,EAAU;AACZ,KAAA;AAEA,IAAA,MAAMC,OAAAA,GAAU;AACd;;;AAGC,QACDC,mBAAkBC,KAAa,EAAA;YAC7BR,kBAAAA,GAAqB,UAAYS,iBAAiBV,GAAAA,EAAKS,KAAAA,CAAAA;YACvD,OAAOF,OAAAA;AACT,QAAA,CAAA;AAEA;;;;;AAKC,QACDI,gBAAe,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAG;YAAED,MAAAA,EAAQ,IAAA;YAAMC,KAAAA,EAAO;SAAM,EAAA;YAC9D,IAAI,CAACC,MAAMF,MAAAA,CAAAA,EAAS;AAClBT,gBAAAA,mBAAAA,CAAoBC,SAAS,GAAGQ,MAAAA;AAClC,YAAA;YACA,IAAI,CAACE,MAAMD,KAAAA,CAAAA,EAAQ;AACjBV,gBAAAA,mBAAAA,CAAoBE,QAAQ,GAAGQ,KAAAA;AACjC,YAAA;YACA,OAAON,OAAAA;AACT,QAAA,CAAA;AAEA;;;QAIAQ,YAAAA,CAAAA,CAAaC,QAAQC,QAAQ,EAAA;AAC3Bd,YAAAA,mBAAAA,CAAoBG,QAAQ,GAAGU,KAAAA;YAC/B,OAAOT,OAAAA;AACT,QAAA,CAAA;AAEA;;;;;AAKC,QACDW,sBAAqBC,SAA8B,EAAA;AACjD,YAAA,MAAMC,IAAAA,GAAOnB,kBAAAA;;AAEbA,YAAAA,kBAAAA,GAAqB,UAAYoB,KAAAA,CAAO,MAAMD,IAAAA,EAAAA,IAAW,EAAC,EAAGD,SAAAA,CAAAA;YAC7D,OAAOZ,OAAAA;AACT,QAAA,CAAA;AAEA;;;AAGC,QACD,MAAMe,KAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMC,kBAAkB,MAAMtB,kBAAAA,EAAAA;AAE9B,YAAA,IAAIE,mBAAAA,CAAoBG,QAAQ,KAAK,EAAC,EAAG;gBACvC,OAAOiB,eAAAA;AACT,YAAA;AAEA,YAAA,OAAOC,gBAAgBxB,GAAAA,EAAK;AAAE,gBAAA,GAAGG,mBAAmB;AAAEoB,gBAAAA;AAAgB,aAAA,CAAA;AACxE,QAAA;AACF,KAAA;IAEA,OAAOhB,OAAAA;AACT,CAAA;AAEA,sBAAe,CAAA,IAAMR,iBAAc;;;;"}
|
|
@@ -164,8 +164,9 @@ const getDefaultMainField = (schema)=>findFirstStringAttribute(schema) || 'id';
|
|
|
164
164
|
const validAttributes = Object.keys(schema.attributes).filter((key)=>isListable(schema, key));
|
|
165
165
|
const model = strapi.getModel(schema.uid);
|
|
166
166
|
const nonVisibleWritableAttributes = fp.intersection(getNonVisibleAttributes(model), getWritableAttributes(model));
|
|
167
|
+
const identifierField = _.has(schema.attributes, 'documentId') ? 'documentId' : 'id';
|
|
167
168
|
return [
|
|
168
|
-
|
|
169
|
+
identifierField,
|
|
169
170
|
...validAttributes,
|
|
170
171
|
...nonVisibleWritableAttributes,
|
|
171
172
|
CREATED_BY_ATTRIBUTE,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.js","sources":["../../../../../server/src/services/utils/configuration/attributes.ts"],"sourcesContent":["import _ from 'lodash';\nimport { intersection } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\n\nconst { getNonVisibleAttributes, getWritableAttributes } = contentTypesUtils;\nconst { PUBLISHED_AT_ATTRIBUTE, CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } =\n contentTypesUtils.constants;\n\nconst NON_SORTABLES = ['component', 'json', 'media', 'richtext', 'dynamiczone', 'blocks'];\nconst SORTABLE_RELATIONS = ['oneToOne', 'manyToOne'];\n\nconst NON_LISTABLES = ['json', 'password', 'richtext', 'dynamiczone', 'blocks'];\nconst LISTABLE_RELATIONS = ['oneToOne', 'oneToMany', 'manyToOne', 'manyToMany'];\n\n// hidden fields are fields that are configured to be hidden from list, and edit views\nconst isHidden = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n const isHidden = _.get(schema, ['config', 'attributes', name, 'hidden'], false);\n if (isHidden === true) {\n return true;\n }\n\n return false;\n};\n\nconst isListable = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n const attribute = schema.attributes[name];\n if (NON_LISTABLES.includes(attribute.type)) {\n return false;\n }\n\n if (isRelation(attribute) && !LISTABLE_RELATIONS.includes(attribute.relationType)) {\n return false;\n }\n\n return true;\n};\n\nconst isSortable = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (schema.modelType === 'component' && name === 'id') return false;\n\n const attribute = schema.attributes[name];\n if (NON_SORTABLES.includes(attribute.type)) {\n return false;\n }\n\n if (isRelation(attribute) && !SORTABLE_RELATIONS.includes(attribute.relationType)) {\n return false;\n }\n\n return true;\n};\n\nconst isSearchable = (schema: any, name: any) => {\n return isSortable(schema, name);\n};\n\nconst isVisible = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n if (isTimestamp(schema, name) || name === 'id' || name === 'documentId') {\n return false;\n }\n\n if (isPublicationField(name)) {\n return false;\n }\n\n if (isCreatorField(schema, name)) {\n return false;\n }\n\n return true;\n};\n\nconst isPublicationField = (name: any) => PUBLISHED_AT_ATTRIBUTE === name;\n\nconst isTimestamp = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n const timestamps = contentTypesUtils.getTimestamps(schema);\n if (!timestamps || !Array.isArray(timestamps)) {\n return false;\n }\n\n if (timestamps.includes(name)) {\n return true;\n }\n};\n\nconst isCreatorField = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n const creatorFields = contentTypesUtils.getCreatorFields(schema);\n if (!creatorFields || !Array.isArray(creatorFields)) {\n return false;\n }\n\n if (creatorFields.includes(name)) {\n return true;\n }\n};\n\nconst isRelation = (attribute: any) => attribute.type === 'relation';\n\nconst hasRelationAttribute = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n if (!isVisible(schema, name)) {\n return false;\n }\n\n return isRelation(schema.attributes[name]);\n};\n\nconst hasEditableAttribute = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n if (!isVisible(schema, name)) {\n return false;\n }\n\n return true;\n};\n\nconst findFirstStringAttribute = (schema: any) => {\n return Object.keys(schema.attributes || {}).find((key) => {\n const { type } = schema.attributes[key];\n return type === 'string' && key !== 'id';\n });\n};\n\nconst getDefaultMainField = (schema: any) => findFirstStringAttribute(schema) || 'id';\n\n/**\n * Returns list of all sortable attributes for a given content type schema\n * TODO V5: Refactor non visible fields to be a part of content-manager schema so we can use isSortable instead\n * @param {*} schema\n * @returns\n */\nconst getSortableAttributes = (schema: any) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n const model = strapi.getModel(schema.uid);\n const nonVisibleWritableAttributes = intersection(\n getNonVisibleAttributes(model),\n getWritableAttributes(model)\n );\n\n return [\n 'id',\n ...validAttributes,\n ...nonVisibleWritableAttributes,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n ];\n};\n\nexport {\n isSortable,\n isVisible,\n isSearchable,\n isRelation,\n isListable,\n hasEditableAttribute,\n hasRelationAttribute,\n getDefaultMainField,\n getSortableAttributes,\n};\n"],"names":["getNonVisibleAttributes","getWritableAttributes","contentTypesUtils","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","constants","NON_SORTABLES","SORTABLE_RELATIONS","NON_LISTABLES","LISTABLE_RELATIONS","isHidden","schema","name","_","has","attributes","get","isListable","attribute","includes","type","isRelation","relationType","isSortable","modelType","isSearchable","isVisible","isTimestamp","isPublicationField","isCreatorField","timestamps","getTimestamps","Array","isArray","creatorFields","getCreatorFields","hasRelationAttribute","hasEditableAttribute","findFirstStringAttribute","Object","keys","find","key","getDefaultMainField","getSortableAttributes","validAttributes","filter","model","strapi","getModel","uid","nonVisibleWritableAttributes","intersection"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"attributes.js","sources":["../../../../../server/src/services/utils/configuration/attributes.ts"],"sourcesContent":["import _ from 'lodash';\nimport { intersection } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\n\nconst { getNonVisibleAttributes, getWritableAttributes } = contentTypesUtils;\nconst { PUBLISHED_AT_ATTRIBUTE, CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } =\n contentTypesUtils.constants;\n\nconst NON_SORTABLES = ['component', 'json', 'media', 'richtext', 'dynamiczone', 'blocks'];\nconst SORTABLE_RELATIONS = ['oneToOne', 'manyToOne'];\n\nconst NON_LISTABLES = ['json', 'password', 'richtext', 'dynamiczone', 'blocks'];\nconst LISTABLE_RELATIONS = ['oneToOne', 'oneToMany', 'manyToOne', 'manyToMany'];\n\n// hidden fields are fields that are configured to be hidden from list, and edit views\nconst isHidden = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n const isHidden = _.get(schema, ['config', 'attributes', name, 'hidden'], false);\n if (isHidden === true) {\n return true;\n }\n\n return false;\n};\n\nconst isListable = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n const attribute = schema.attributes[name];\n if (NON_LISTABLES.includes(attribute.type)) {\n return false;\n }\n\n if (isRelation(attribute) && !LISTABLE_RELATIONS.includes(attribute.relationType)) {\n return false;\n }\n\n return true;\n};\n\nconst isSortable = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (schema.modelType === 'component' && name === 'id') return false;\n\n const attribute = schema.attributes[name];\n if (NON_SORTABLES.includes(attribute.type)) {\n return false;\n }\n\n if (isRelation(attribute) && !SORTABLE_RELATIONS.includes(attribute.relationType)) {\n return false;\n }\n\n return true;\n};\n\nconst isSearchable = (schema: any, name: any) => {\n return isSortable(schema, name);\n};\n\nconst isVisible = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n if (isTimestamp(schema, name) || name === 'id' || name === 'documentId') {\n return false;\n }\n\n if (isPublicationField(name)) {\n return false;\n }\n\n if (isCreatorField(schema, name)) {\n return false;\n }\n\n return true;\n};\n\nconst isPublicationField = (name: any) => PUBLISHED_AT_ATTRIBUTE === name;\n\nconst isTimestamp = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n const timestamps = contentTypesUtils.getTimestamps(schema);\n if (!timestamps || !Array.isArray(timestamps)) {\n return false;\n }\n\n if (timestamps.includes(name)) {\n return true;\n }\n};\n\nconst isCreatorField = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n const creatorFields = contentTypesUtils.getCreatorFields(schema);\n if (!creatorFields || !Array.isArray(creatorFields)) {\n return false;\n }\n\n if (creatorFields.includes(name)) {\n return true;\n }\n};\n\nconst isRelation = (attribute: any) => attribute.type === 'relation';\n\nconst hasRelationAttribute = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n if (!isVisible(schema, name)) {\n return false;\n }\n\n return isRelation(schema.attributes[name]);\n};\n\nconst hasEditableAttribute = (schema: any, name: any) => {\n if (!_.has(schema.attributes, name)) {\n return false;\n }\n\n if (isHidden(schema, name)) {\n return false;\n }\n\n if (!isVisible(schema, name)) {\n return false;\n }\n\n return true;\n};\n\nconst findFirstStringAttribute = (schema: any) => {\n return Object.keys(schema.attributes || {}).find((key) => {\n const { type } = schema.attributes[key];\n return type === 'string' && key !== 'id';\n });\n};\n\nconst getDefaultMainField = (schema: any) => findFirstStringAttribute(schema) || 'id';\n\n/**\n * Returns list of all sortable attributes for a given content type schema\n * TODO V5: Refactor non visible fields to be a part of content-manager schema so we can use isSortable instead\n * @param {*} schema\n * @returns\n */\nconst getSortableAttributes = (schema: any) => {\n const validAttributes = Object.keys(schema.attributes).filter((key) => isListable(schema, key));\n\n const model = strapi.getModel(schema.uid);\n const nonVisibleWritableAttributes = intersection(\n getNonVisibleAttributes(model),\n getWritableAttributes(model)\n );\n\n const identifierField = _.has(schema.attributes, 'documentId') ? 'documentId' : 'id';\n return [\n identifierField,\n ...validAttributes,\n ...nonVisibleWritableAttributes,\n CREATED_BY_ATTRIBUTE,\n UPDATED_BY_ATTRIBUTE,\n ];\n};\n\nexport {\n isSortable,\n isVisible,\n isSearchable,\n isRelation,\n isListable,\n hasEditableAttribute,\n hasRelationAttribute,\n getDefaultMainField,\n getSortableAttributes,\n};\n"],"names":["getNonVisibleAttributes","getWritableAttributes","contentTypesUtils","PUBLISHED_AT_ATTRIBUTE","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","constants","NON_SORTABLES","SORTABLE_RELATIONS","NON_LISTABLES","LISTABLE_RELATIONS","isHidden","schema","name","_","has","attributes","get","isListable","attribute","includes","type","isRelation","relationType","isSortable","modelType","isSearchable","isVisible","isTimestamp","isPublicationField","isCreatorField","timestamps","getTimestamps","Array","isArray","creatorFields","getCreatorFields","hasRelationAttribute","hasEditableAttribute","findFirstStringAttribute","Object","keys","find","key","getDefaultMainField","getSortableAttributes","validAttributes","filter","model","strapi","getModel","uid","nonVisibleWritableAttributes","intersection","identifierField"],"mappings":"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"}
|
|
@@ -162,8 +162,9 @@ const getDefaultMainField = (schema)=>findFirstStringAttribute(schema) || 'id';
|
|
|
162
162
|
const validAttributes = Object.keys(schema.attributes).filter((key)=>isListable(schema, key));
|
|
163
163
|
const model = strapi.getModel(schema.uid);
|
|
164
164
|
const nonVisibleWritableAttributes = intersection(getNonVisibleAttributes(model), getWritableAttributes(model));
|
|
165
|
+
const identifierField = _.has(schema.attributes, 'documentId') ? 'documentId' : 'id';
|
|
165
166
|
return [
|
|
166
|
-
|
|
167
|
+
identifierField,
|
|
167
168
|
...validAttributes,
|
|
168
169
|
...nonVisibleWritableAttributes,
|
|
169
170
|
CREATED_BY_ATTRIBUTE,
|