@strapi/content-manager 5.40.0 → 5.41.1
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/pages/EditView/components/Header.js +56 -9
- package/dist/admin/pages/EditView/components/Header.js.map +1 -1
- package/dist/admin/pages/EditView/components/Header.mjs +60 -13
- package/dist/admin/pages/EditView/components/Header.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 +4 -4
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs +4 -4
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs.map +1 -1
- 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/populate.js +57 -7
- package/dist/server/services/utils/populate.js.map +1 -1
- package/dist/server/services/utils/populate.mjs +57 -8
- 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/populate.d.ts +21 -17
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.mjs","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":";;;;AAIA,MAAM,EAAEA,uBAAuB,EAAEC,qBAAqB,EAAE,GAAGC,YAAAA;AAC3D,MAAM,EAAEC,sBAAsB,EAAEC,oBAAoB,EAAEC,oBAAoB,EAAE,GAC1EH,YAAAA,CAAkBI,SAAS;AAE7B,MAAMC,aAAAA,GAAgB;AAAC,IAAA,WAAA;AAAa,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA,UAAA;AAAY,IAAA,aAAA;AAAe,IAAA;AAAS,CAAA;AACzF,MAAMC,kBAAAA,GAAqB;AAAC,IAAA,UAAA;AAAY,IAAA;AAAY,CAAA;AAEpD,MAAMC,aAAAA,GAAgB;AAAC,IAAA,MAAA;AAAQ,IAAA,UAAA;AAAY,IAAA,UAAA;AAAY,IAAA,aAAA;AAAe,IAAA;AAAS,CAAA;AAC/E,MAAMC,kBAAAA,GAAqB;AAAC,IAAA,UAAA;AAAY,IAAA,WAAA;AAAa,IAAA,WAAA;AAAa,IAAA;AAAa,CAAA;AAE/E;AACA,MAAMC,QAAAA,GAAW,CAACC,MAAAA,EAAaC,IAAAA,GAAAA;AAC7B,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,MAAMF,QAAAA,GAAWG,CAAAA,CAAEG,GAAG,CAACL,MAAAA,EAAQ;AAAC,QAAA,QAAA;AAAU,QAAA,YAAA;AAAcC,QAAAA,IAAAA;AAAM,QAAA;KAAS,EAAE,KAAA,CAAA;AACzE,IAAA,IAAIF,aAAa,IAAA,EAAM;QACrB,OAAO,IAAA;AACT,IAAA;IAEA,OAAO,KAAA;AACT,CAAA;AAEA,MAAMO,UAAAA,GAAa,CAACN,MAAAA,EAAaC,IAAAA,GAAAA;AAC/B,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;IAEA,IAAIF,QAAAA,CAASC,QAAQC,IAAAA,CAAAA,EAAO;QAC1B,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,MAAMM,SAAAA,GAAYP,MAAAA,CAAOI,UAAU,CAACH,IAAAA,CAAK;AACzC,IAAA,IAAIJ,aAAAA,CAAcW,QAAQ,CAACD,SAAAA,CAAUE,IAAI,CAAA,EAAG;QAC1C,OAAO,KAAA;AACT,IAAA;IAEA,IAAIC,UAAAA,CAAWH,cAAc,CAACT,kBAAAA,CAAmBU,QAAQ,CAACD,SAAAA,CAAUI,YAAY,CAAA,EAAG;QACjF,OAAO,KAAA;AACT,IAAA;IAEA,OAAO,IAAA;AACT;AAEA,MAAMC,UAAAA,GAAa,CAACZ,MAAAA,EAAaC,IAAAA,GAAAA;AAC/B,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,IAAID,OAAOa,SAAS,KAAK,WAAA,IAAeZ,IAAAA,KAAS,MAAM,OAAO,KAAA;AAE9D,IAAA,MAAMM,SAAAA,GAAYP,MAAAA,CAAOI,UAAU,CAACH,IAAAA,CAAK;AACzC,IAAA,IAAIN,aAAAA,CAAca,QAAQ,CAACD,SAAAA,CAAUE,IAAI,CAAA,EAAG;QAC1C,OAAO,KAAA;AACT,IAAA;IAEA,IAAIC,UAAAA,CAAWH,cAAc,CAACX,kBAAAA,CAAmBY,QAAQ,CAACD,SAAAA,CAAUI,YAAY,CAAA,EAAG;QACjF,OAAO,KAAA;AACT,IAAA;IAEA,OAAO,IAAA;AACT;AAEA,MAAMG,YAAAA,GAAe,CAACd,MAAAA,EAAaC,IAAAA,GAAAA;AACjC,IAAA,OAAOW,WAAWZ,MAAAA,EAAQC,IAAAA,CAAAA;AAC5B;AAEA,MAAMc,SAAAA,GAAY,CAACf,MAAAA,EAAaC,IAAAA,GAAAA;AAC9B,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;IAEA,IAAIF,QAAAA,CAASC,QAAQC,IAAAA,CAAAA,EAAO;QAC1B,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,IAAIe,YAAYhB,MAAAA,EAAQC,IAAAA,CAAAA,IAASA,IAAAA,KAAS,IAAA,IAAQA,SAAS,YAAA,EAAc;QACvE,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,IAAIgB,mBAAmBhB,IAAAA,CAAAA,EAAO;QAC5B,OAAO,KAAA;AACT,IAAA;IAEA,IAAIiB,cAAAA,CAAelB,QAAQC,IAAAA,CAAAA,EAAO;QAChC,OAAO,KAAA;AACT,IAAA;IAEA,OAAO,IAAA;AACT;AAEA,MAAMgB,kBAAAA,GAAqB,CAAChB,IAAAA,GAAcV,sBAAAA,KAA2BU,IAAAA;AAErE,MAAMe,WAAAA,GAAc,CAAChB,MAAAA,EAAaC,IAAAA,GAAAA;AAChC,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;IAEA,MAAMkB,UAAAA,GAAa7B,YAAAA,CAAkB8B,aAAa,CAACpB,MAAAA,CAAAA;AACnD,IAAA,IAAI,CAACmB,UAAAA,IAAc,CAACE,KAAAA,CAAMC,OAAO,CAACH,UAAAA,CAAAA,EAAa;QAC7C,OAAO,KAAA;AACT,IAAA;IAEA,IAAIA,UAAAA,CAAWX,QAAQ,CAACP,IAAAA,CAAAA,EAAO;QAC7B,OAAO,IAAA;AACT,IAAA;AACF,CAAA;AAEA,MAAMiB,cAAAA,GAAiB,CAAClB,MAAAA,EAAaC,IAAAA,GAAAA;AACnC,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;IAEA,MAAMsB,aAAAA,GAAgBjC,YAAAA,CAAkBkC,gBAAgB,CAACxB,MAAAA,CAAAA;AACzD,IAAA,IAAI,CAACuB,aAAAA,IAAiB,CAACF,KAAAA,CAAMC,OAAO,CAACC,aAAAA,CAAAA,EAAgB;QACnD,OAAO,KAAA;AACT,IAAA;IAEA,IAAIA,aAAAA,CAAcf,QAAQ,CAACP,IAAAA,CAAAA,EAAO;QAChC,OAAO,IAAA;AACT,IAAA;AACF,CAAA;AAEA,MAAMS,UAAAA,GAAa,CAACH,SAAAA,GAAmBA,SAAAA,CAAUE,IAAI,KAAK;AAE1D,MAAMgB,oBAAAA,GAAuB,CAACzB,MAAAA,EAAaC,IAAAA,GAAAA;AACzC,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;IAEA,IAAIF,QAAAA,CAASC,QAAQC,IAAAA,CAAAA,EAAO;QAC1B,OAAO,KAAA;AACT,IAAA;IAEA,IAAI,CAACc,SAAAA,CAAUf,MAAAA,EAAQC,IAAAA,CAAAA,EAAO;QAC5B,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,OAAOS,UAAAA,CAAWV,MAAAA,CAAOI,UAAU,CAACH,IAAAA,CAAK,CAAA;AAC3C;AAEA,MAAMyB,oBAAAA,GAAuB,CAAC1B,MAAAA,EAAaC,IAAAA,GAAAA;AACzC,IAAA,IAAI,CAACC,CAAAA,CAAEC,GAAG,CAACH,MAAAA,CAAOI,UAAU,EAAEH,IAAAA,CAAAA,EAAO;QACnC,OAAO,KAAA;AACT,IAAA;IAEA,IAAIF,QAAAA,CAASC,QAAQC,IAAAA,CAAAA,EAAO;QAC1B,OAAO,KAAA;AACT,IAAA;IAEA,IAAI,CAACc,SAAAA,CAAUf,MAAAA,EAAQC,IAAAA,CAAAA,EAAO;QAC5B,OAAO,KAAA;AACT,IAAA;IAEA,OAAO,IAAA;AACT;AAEA,MAAM0B,2BAA2B,CAAC3B,MAAAA,GAAAA;IAChC,OAAO4B,MAAAA,CAAOC,IAAI,CAAC7B,MAAAA,CAAOI,UAAU,IAAI,EAAC,CAAA,CAAG0B,IAAI,CAAC,CAACC,GAAAA,GAAAA;AAChD,QAAA,MAAM,EAAEtB,IAAI,EAAE,GAAGT,MAAAA,CAAOI,UAAU,CAAC2B,GAAAA,CAAI;QACvC,OAAOtB,IAAAA,KAAS,YAAYsB,GAAAA,KAAQ,IAAA;AACtC,IAAA,CAAA,CAAA;AACF,CAAA;AAEA,MAAMC,mBAAAA,GAAsB,CAAChC,MAAAA,GAAgB2B,wBAAAA,CAAyB3B,MAAAA,CAAAA,IAAW;AAEjF;;;;;IAMA,MAAMiC,wBAAwB,CAACjC,MAAAA,GAAAA;AAC7B,IAAA,MAAMkC,eAAAA,GAAkBN,MAAAA,CAAOC,IAAI,CAAC7B,MAAAA,CAAOI,UAAU,CAAA,CAAE+B,MAAM,CAAC,CAACJ,GAAAA,GAAQzB,UAAAA,CAAWN,MAAAA,EAAQ+B,GAAAA,CAAAA,CAAAA;AAE1F,IAAA,MAAMK,KAAAA,GAAQC,MAAAA,CAAOC,QAAQ,CAACtC,OAAOuC,GAAG,CAAA;AACxC,IAAA,MAAMC,4BAAAA,GAA+BC,YAAAA,CACnCrD,uBAAAA,CAAwBgD,KAAAA,CAAAA,EACxB/C,qBAAAA,CAAsB+C,KAAAA,CAAAA,CAAAA;IAGxB,OAAO;AACL,QAAA,IAAA;AACGF,QAAAA,GAAAA,eAAAA;AACAM,QAAAA,GAAAA,4BAAAA;AACHhD,QAAAA,oBAAAA;AACAC,QAAAA;AACD,KAAA;AACH;;;;"}
|
|
1
|
+
{"version":3,"file":"attributes.mjs","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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"}
|
|
@@ -21,7 +21,8 @@ const isDynamicZone = fp.propEq('type', 'dynamiczone');
|
|
|
21
21
|
* @param options - Options to apply while populating
|
|
22
22
|
*/ function getPopulateForRelation(attribute, model, attributeName, { countMany, countOne, initialPopulate }) {
|
|
23
23
|
const isManyRelation = isAnyToMany(attribute);
|
|
24
|
-
|
|
24
|
+
// Use initialPopulate when explicitly provided (including `false` to suppress population)
|
|
25
|
+
if (initialPopulate !== undefined) {
|
|
25
26
|
return initialPopulate;
|
|
26
27
|
}
|
|
27
28
|
// If populating localizations attribute, also include validatable fields
|
|
@@ -126,12 +127,17 @@ const isDynamicZone = fp.propEq('type', 'dynamiczone');
|
|
|
126
127
|
* @param uid - Unique identifier of the model
|
|
127
128
|
* @param options - Options to apply while populating
|
|
128
129
|
* @param level - Current level of nested call
|
|
129
|
-
*/ const
|
|
130
|
+
*/ const validationPopulateCache = new Map();
|
|
131
|
+
const getPopulateForValidation = (uid)=>{
|
|
132
|
+
const cached = validationPopulateCache.get(uid);
|
|
133
|
+
if (cached) {
|
|
134
|
+
return cached;
|
|
135
|
+
}
|
|
130
136
|
const model = strapi.getModel(uid);
|
|
131
137
|
if (!model) {
|
|
132
138
|
return {};
|
|
133
139
|
}
|
|
134
|
-
|
|
140
|
+
const result = Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute])=>{
|
|
135
141
|
if (isScalarAttribute(attribute)) {
|
|
136
142
|
// If the scalar attribute requires validation, add it to the fields array
|
|
137
143
|
if (getDoesAttributeRequireValidation(attribute)) {
|
|
@@ -184,6 +190,8 @@ const isDynamicZone = fp.propEq('type', 'dynamiczone');
|
|
|
184
190
|
}
|
|
185
191
|
return populateAcc;
|
|
186
192
|
}, {});
|
|
193
|
+
validationPopulateCache.set(uid, result);
|
|
194
|
+
return result;
|
|
187
195
|
};
|
|
188
196
|
/**
|
|
189
197
|
* getDeepPopulateDraftCount works recursively on the attributes of a model
|
|
@@ -193,7 +201,12 @@ const isDynamicZone = fp.propEq('type', 'dynamiczone');
|
|
|
193
201
|
* @returns result
|
|
194
202
|
* @returns result.populate
|
|
195
203
|
* @returns result.hasRelations
|
|
196
|
-
*/ const
|
|
204
|
+
*/ const draftCountPopulateCache = new Map();
|
|
205
|
+
const getDeepPopulateDraftCount = (uid)=>{
|
|
206
|
+
const cached = draftCountPopulateCache.get(uid);
|
|
207
|
+
if (cached) {
|
|
208
|
+
return cached;
|
|
209
|
+
}
|
|
197
210
|
const model = strapi.getModel(uid);
|
|
198
211
|
if (!model) {
|
|
199
212
|
return {
|
|
@@ -270,10 +283,12 @@ const isDynamicZone = fp.propEq('type', 'dynamiczone');
|
|
|
270
283
|
}
|
|
271
284
|
return populateAcc;
|
|
272
285
|
}, {});
|
|
273
|
-
|
|
286
|
+
const result = {
|
|
274
287
|
populate,
|
|
275
288
|
hasRelations
|
|
276
289
|
};
|
|
290
|
+
draftCountPopulateCache.set(uid, result);
|
|
291
|
+
return result;
|
|
277
292
|
};
|
|
278
293
|
/**
|
|
279
294
|
* Create a Strapi populate object which populates all attribute fields of a Strapi query.
|
|
@@ -303,13 +318,48 @@ const isDynamicZone = fp.propEq('type', 'dynamiczone');
|
|
|
303
318
|
}, query);
|
|
304
319
|
return populateQuery;
|
|
305
320
|
};
|
|
306
|
-
const
|
|
307
|
-
|
|
321
|
+
const deepPopulateCache = new Map();
|
|
322
|
+
const buildDeepPopulate = async (uid)=>{
|
|
323
|
+
const cached = deepPopulateCache.get(uid);
|
|
324
|
+
if (cached) {
|
|
325
|
+
return cached;
|
|
326
|
+
}
|
|
327
|
+
const result = await index.getService('populate-builder')(uid).populateDeep(Infinity).countRelations().build();
|
|
328
|
+
deepPopulateCache.set(uid, result);
|
|
329
|
+
return result;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Restrict localizations populate to only metadata fields for localized content types.
|
|
333
|
+
* Returns an empty object for non-localized content types.
|
|
334
|
+
*
|
|
335
|
+
* By default, localizations are deeply populated which includes all relations and
|
|
336
|
+
* components for every locale — this is expensive and unnecessary for CM responses.
|
|
337
|
+
* The CM only needs these fields from localizations:
|
|
338
|
+
* - locale: to identify which locales exist
|
|
339
|
+
* - documentId: to link to the localized document
|
|
340
|
+
* - publishedAt: to determine published/draft status
|
|
341
|
+
* - updatedAt: to support the modified state indicator in the UI
|
|
342
|
+
*/ const getPopulateForLocalizations = (model)=>{
|
|
343
|
+
const modelSchema = strapi.getModel(model);
|
|
344
|
+
if (modelSchema.pluginOptions?.i18n?.localized) {
|
|
345
|
+
return {
|
|
346
|
+
localizations: {
|
|
347
|
+
fields: [
|
|
348
|
+
'locale',
|
|
349
|
+
'documentId',
|
|
350
|
+
'publishedAt',
|
|
351
|
+
'updatedAt'
|
|
352
|
+
]
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
return {};
|
|
308
357
|
};
|
|
309
358
|
|
|
310
359
|
exports.buildDeepPopulate = buildDeepPopulate;
|
|
311
360
|
exports.getDeepPopulate = getDeepPopulate;
|
|
312
361
|
exports.getDeepPopulateDraftCount = getDeepPopulateDraftCount;
|
|
362
|
+
exports.getPopulateForLocalizations = getPopulateForLocalizations;
|
|
313
363
|
exports.getPopulateForValidation = getPopulateForValidation;
|
|
314
364
|
exports.getQueryPopulate = getQueryPopulate;
|
|
315
365
|
//# sourceMappingURL=populate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"populate.js","sources":["../../../../server/src/services/utils/populate.ts"],"sourcesContent":["import { merge, isEmpty, set, propEq } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport type { UID, Schema, Modules } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst {\n isVisibleAttribute,\n isScalarAttribute,\n getDoesAttributeRequireValidation,\n hasDraftAndPublish,\n} = strapiUtils.contentTypes;\nconst { isAnyToMany } = strapiUtils.relations;\nconst { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;\n\nconst isMorphToRelation = (attribute: any) =>\n isRelation(attribute) && attribute.relation.includes('morphTo');\nconst isMedia = propEq('type', 'media');\nconst isRelation = propEq('type', 'relation');\nconst isComponent = propEq('type', 'component');\nconst isDynamicZone = propEq('type', 'dynamiczone');\n\n// TODO: Import from @strapi/types when it's available there\ntype Model = Parameters<typeof isVisibleAttribute>[0];\nexport type Populate = Modules.EntityService.Params.Populate.Any<UID.Schema>;\n\ntype PopulateOptions = {\n initialPopulate?: Populate;\n countMany?: boolean;\n countOne?: boolean;\n maxLevel?: number;\n};\n\n/**\n * Populate the model for relation\n * @param attribute - Attribute containing a relation\n * @param attribute.relation - type of relation\n * @param model - Model of the populated entity\n * @param attributeName\n * @param options - Options to apply while populating\n */\nfunction getPopulateForRelation(\n attribute: Schema.Attribute.AnyAttribute,\n model: Model,\n attributeName: string,\n { countMany, countOne, initialPopulate }: PopulateOptions\n) {\n const isManyRelation = isAnyToMany(attribute);\n\n if (initialPopulate) {\n return initialPopulate;\n }\n\n // If populating localizations attribute, also include validatable fields\n // Mainly needed for bulk locale publishing, so the Client has all the information necessary to perform validations\n if (attributeName === 'localizations') {\n const validationPopulate = getPopulateForValidation(model.uid as UID.Schema);\n\n return {\n populate: validationPopulate.populate,\n };\n }\n\n // always populate createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n return true;\n }\n\n if ((isManyRelation && countMany) || (!isManyRelation && countOne)) {\n return { count: true };\n }\n\n return true;\n}\n\n/**\n * Populate the model for Dynamic Zone components\n * @param attribute - Attribute containing the components\n * @param attribute.components - IDs of components\n * @param options - Options to apply while populating\n */\nfunction getPopulateForDZ(\n attribute: Schema.Attribute.DynamicZone,\n options: PopulateOptions,\n level: number\n) {\n // Use fragments to populate the dynamic zone components\n const populatedComponents = (attribute.components || []).reduce(\n (acc: any, componentUID: UID.Component) => ({\n ...acc,\n [componentUID]: {\n populate: getDeepPopulate(componentUID, options, level + 1),\n },\n }),\n {}\n );\n\n return { on: populatedComponents };\n}\n\n/**\n * Get the populated value based on the type of the attribute\n * @param attributeName - Name of the attribute\n * @param model - Model of the populated entity\n * @param model.attributes\n * @param options - Options to apply while populating\n * @param options.countMany\n * @param options.countOne\n * @param options.maxLevel\n * @param level\n */\nfunction getPopulateFor(\n attributeName: string,\n model: any,\n options: PopulateOptions,\n level: number\n): { [key: string]: boolean | object } {\n const attribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation':\n // @ts-expect-error - TODO: support populate count typing\n return {\n [attributeName]: getPopulateForRelation(attribute, model, attributeName, options),\n };\n case 'component':\n return {\n [attributeName]: {\n populate: getDeepPopulate(attribute.component, options, level + 1),\n },\n };\n case 'media':\n return {\n [attributeName]: {\n populate: {\n folder: true,\n },\n },\n };\n case 'dynamiczone':\n return {\n [attributeName]: getPopulateForDZ(attribute, options, level),\n };\n default:\n return {};\n }\n}\n\n/**\n * Deeply populate a model based on UID\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst getDeepPopulate = (\n uid: UID.Schema,\n {\n initialPopulate = {} as any,\n countMany = false,\n countOne = false,\n maxLevel = Infinity,\n }: PopulateOptions = {},\n level = 1\n) => {\n if (level > maxLevel) {\n return {};\n }\n\n const model = strapi.getModel(uid);\n\n if (!model) {\n return {};\n }\n\n return Object.keys(model.attributes).reduce(\n (populateAcc, attributeName: string) =>\n merge(\n populateAcc,\n getPopulateFor(\n attributeName,\n model,\n {\n // @ts-expect-error - improve types\n initialPopulate: initialPopulate?.[attributeName],\n countMany,\n countOne,\n maxLevel,\n },\n level\n )\n ),\n {}\n );\n};\n\n/**\n * Deeply populate a model based on UID. Only populating fields that require validation.\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst getPopulateForValidation = (uid: UID.Schema): Record<string, any> => {\n const model = strapi.getModel(uid);\n if (!model) {\n return {};\n }\n\n return Object.entries(model.attributes).reduce((populateAcc: any, [attributeName, attribute]) => {\n if (isScalarAttribute(attribute)) {\n // If the scalar attribute requires validation, add it to the fields array\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.fields = populateAcc.fields || [];\n populateAcc.fields.push(attributeName);\n }\n return populateAcc;\n }\n\n if (isMedia(attribute)) {\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = {\n populate: {\n folder: true,\n },\n };\n return populateAcc;\n }\n }\n\n if (isComponent(attribute)) {\n // @ts-expect-error - should be a component\n const component = attribute.component;\n\n // Get the validation result for this component\n const componentResult = getPopulateForValidation(component);\n\n if (Object.keys(componentResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = componentResult;\n }\n\n return populateAcc;\n }\n\n if (isDynamicZone(attribute)) {\n const components = (attribute as Schema.Attribute.DynamicZone).components;\n // Handle dynamic zone components\n const componentsResult = (components || []).reduce(\n (acc, componentUID) => {\n // Get validation populate for this component\n const componentResult = getPopulateForValidation(componentUID);\n\n // Only include component if it has fields requiring validation\n if (Object.keys(componentResult).length > 0) {\n acc[componentUID] = componentResult;\n }\n\n return acc;\n },\n {} as Record<string, any>\n );\n\n // Only add to populate if we have components requiring validation\n if (Object.keys(componentsResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = { on: componentsResult };\n }\n }\n\n return populateAcc;\n }, {});\n};\n\n/**\n * getDeepPopulateDraftCount works recursively on the attributes of a model\n * creating a populated object to count all the unpublished relations within the model\n * These relations can be direct to this content type or contained within components/dynamic zones\n * @param uid of the model\n * @returns result\n * @returns result.populate\n * @returns result.hasRelations\n */\nconst getDeepPopulateDraftCount = (uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n if (!model) {\n return { populate: {}, hasRelations: false };\n }\n let hasRelations = false;\n\n const populate = Object.keys(model.attributes).reduce((populateAcc: any, attributeName) => {\n const attribute: Schema.Attribute.AnyAttribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation': {\n // TODO: Support polymorphic relations\n const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');\n if (isMorphRelation) {\n break;\n }\n\n // Skip relations to content types without draft & publish,\n // as they don't have a publishedAt attribute and can't have drafts\n if (!('target' in attribute)) {\n break;\n }\n\n const targetModel = strapi.getModel(attribute.target);\n if (!targetModel || !hasDraftAndPublish(targetModel)) {\n break;\n }\n\n if (isVisibleAttribute(model, attributeName)) {\n populateAcc[attributeName] = {\n count: true,\n filters: { [PUBLISHED_AT_ATTRIBUTE]: { $null: true } },\n };\n hasRelations = true;\n }\n break;\n }\n case 'component': {\n const { populate, hasRelations: childHasRelations } = getDeepPopulateDraftCount(\n attribute.component\n );\n if (childHasRelations) {\n populateAcc[attributeName] = {\n populate,\n };\n hasRelations = true;\n }\n break;\n }\n case 'dynamiczone': {\n const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {\n const { populate: componentPopulate, hasRelations: componentHasRelations } =\n getDeepPopulateDraftCount(componentUID);\n\n if (componentHasRelations) {\n hasRelations = true;\n\n return { ...acc, [componentUID]: { populate: componentPopulate } };\n }\n\n return acc;\n }, {});\n\n if (!isEmpty(dzPopulateFragment)) {\n populateAcc[attributeName] = { on: dzPopulateFragment };\n }\n break;\n }\n default:\n }\n\n return populateAcc;\n }, {});\n\n return { populate, hasRelations };\n};\n\n/**\n * Create a Strapi populate object which populates all attribute fields of a Strapi query.\n */\nconst getQueryPopulate = async (uid: UID.Schema, query: object): Promise<Populate> => {\n let populateQuery: Populate = {};\n\n await strapiUtils.traverse.traverseQueryFilters(\n /**\n *\n * @param {Object} param0\n * @param {string} param0.key - Attribute name\n * @param {Object} param0.attribute - Attribute definition\n * @param {string} param0.path - Content Type path to the attribute\n * @returns\n */\n ({ attribute, path }: any) => {\n // TODO: handle dynamic zones and morph relations\n if (!attribute || isDynamicZone(attribute) || isMorphToRelation(attribute)) {\n return;\n }\n\n // Populate all relations, components and media\n if (isRelation(attribute) || isMedia(attribute) || isComponent(attribute)) {\n const populatePath = path.attribute.replace(/\\./g, '.populate.');\n // @ts-expect-error - lodash doesn't resolve the Populate type correctly\n populateQuery = set(populatePath, {}, populateQuery);\n }\n },\n { schema: strapi.getModel(uid), getModel: strapi.getModel.bind(strapi) },\n query\n );\n\n return populateQuery;\n};\n\nconst buildDeepPopulate = (uid: UID.CollectionType) => {\n return getService('populate-builder')(uid).populateDeep(Infinity).countRelations().build();\n};\n\nexport {\n getDeepPopulate,\n getDeepPopulateDraftCount,\n getPopulateForValidation,\n getQueryPopulate,\n buildDeepPopulate,\n};\n"],"names":["isVisibleAttribute","isScalarAttribute","getDoesAttributeRequireValidation","hasDraftAndPublish","strapiUtils","contentTypes","isAnyToMany","relations","PUBLISHED_AT_ATTRIBUTE","constants","isMorphToRelation","attribute","isRelation","relation","includes","isMedia","propEq","isComponent","isDynamicZone","getPopulateForRelation","model","attributeName","countMany","countOne","initialPopulate","isManyRelation","validationPopulate","getPopulateForValidation","uid","populate","count","getPopulateForDZ","options","level","populatedComponents","components","reduce","acc","componentUID","getDeepPopulate","on","getPopulateFor","attributes","type","component","folder","maxLevel","Infinity","strapi","getModel","Object","keys","populateAcc","merge","entries","fields","push","componentResult","length","componentsResult","getDeepPopulateDraftCount","hasRelations","isMorphRelation","toLowerCase","startsWith","targetModel","target","filters","$null","childHasRelations","dzPopulateFragment","componentPopulate","componentHasRelations","isEmpty","getQueryPopulate","query","populateQuery","traverse","traverseQueryFilters","path","populatePath","replace","set","schema","bind","buildDeepPopulate","getService","populateDeep","countRelations","build"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"populate.js","sources":["../../../../server/src/services/utils/populate.ts"],"sourcesContent":["import { merge, isEmpty, set, propEq } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport type { UID, Schema, Modules } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst {\n isVisibleAttribute,\n isScalarAttribute,\n getDoesAttributeRequireValidation,\n hasDraftAndPublish,\n} = strapiUtils.contentTypes;\nconst { isAnyToMany } = strapiUtils.relations;\nconst { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;\n\nconst isMorphToRelation = (attribute: any) =>\n isRelation(attribute) && attribute.relation.includes('morphTo');\nconst isMedia = propEq('type', 'media');\nconst isRelation = propEq('type', 'relation');\nconst isComponent = propEq('type', 'component');\nconst isDynamicZone = propEq('type', 'dynamiczone');\n\n// TODO: Import from @strapi/types when it's available there\ntype Model = Parameters<typeof isVisibleAttribute>[0];\nexport type Populate = Modules.EntityService.Params.Populate.Any<UID.Schema>;\n\ntype PopulateOptions = {\n initialPopulate?: Populate;\n countMany?: boolean;\n countOne?: boolean;\n maxLevel?: number;\n};\n\n/**\n * Populate the model for relation\n * @param attribute - Attribute containing a relation\n * @param attribute.relation - type of relation\n * @param model - Model of the populated entity\n * @param attributeName\n * @param options - Options to apply while populating\n */\nfunction getPopulateForRelation(\n attribute: Schema.Attribute.AnyAttribute,\n model: Model,\n attributeName: string,\n { countMany, countOne, initialPopulate }: PopulateOptions\n) {\n const isManyRelation = isAnyToMany(attribute);\n\n // Use initialPopulate when explicitly provided (including `false` to suppress population)\n if (initialPopulate !== undefined) {\n return initialPopulate;\n }\n\n // If populating localizations attribute, also include validatable fields\n // Mainly needed for bulk locale publishing, so the Client has all the information necessary to perform validations\n if (attributeName === 'localizations') {\n const validationPopulate = getPopulateForValidation(model.uid as UID.Schema);\n\n return {\n populate: validationPopulate.populate,\n };\n }\n\n // always populate createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n return true;\n }\n\n if ((isManyRelation && countMany) || (!isManyRelation && countOne)) {\n return { count: true };\n }\n\n return true;\n}\n\n/**\n * Populate the model for Dynamic Zone components\n * @param attribute - Attribute containing the components\n * @param attribute.components - IDs of components\n * @param options - Options to apply while populating\n */\nfunction getPopulateForDZ(\n attribute: Schema.Attribute.DynamicZone,\n options: PopulateOptions,\n level: number\n) {\n // Use fragments to populate the dynamic zone components\n const populatedComponents = (attribute.components || []).reduce(\n (acc: any, componentUID: UID.Component) => ({\n ...acc,\n [componentUID]: {\n populate: getDeepPopulate(componentUID, options, level + 1),\n },\n }),\n {}\n );\n\n return { on: populatedComponents };\n}\n\n/**\n * Get the populated value based on the type of the attribute\n * @param attributeName - Name of the attribute\n * @param model - Model of the populated entity\n * @param model.attributes\n * @param options - Options to apply while populating\n * @param options.countMany\n * @param options.countOne\n * @param options.maxLevel\n * @param level\n */\nfunction getPopulateFor(\n attributeName: string,\n model: any,\n options: PopulateOptions,\n level: number\n): { [key: string]: boolean | object } {\n const attribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation':\n // @ts-expect-error - TODO: support populate count typing\n return {\n [attributeName]: getPopulateForRelation(attribute, model, attributeName, options),\n };\n case 'component':\n return {\n [attributeName]: {\n populate: getDeepPopulate(attribute.component, options, level + 1),\n },\n };\n case 'media':\n return {\n [attributeName]: {\n populate: {\n folder: true,\n },\n },\n };\n case 'dynamiczone':\n return {\n [attributeName]: getPopulateForDZ(attribute, options, level),\n };\n default:\n return {};\n }\n}\n\n/**\n * Deeply populate a model based on UID\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst getDeepPopulate = (\n uid: UID.Schema,\n {\n initialPopulate = {} as any,\n countMany = false,\n countOne = false,\n maxLevel = Infinity,\n }: PopulateOptions = {},\n level = 1\n) => {\n if (level > maxLevel) {\n return {};\n }\n\n const model = strapi.getModel(uid);\n\n if (!model) {\n return {};\n }\n\n return Object.keys(model.attributes).reduce(\n (populateAcc, attributeName: string) =>\n merge(\n populateAcc,\n getPopulateFor(\n attributeName,\n model,\n {\n // @ts-expect-error - improve types\n initialPopulate: initialPopulate?.[attributeName],\n countMany,\n countOne,\n maxLevel,\n },\n level\n )\n ),\n {}\n );\n};\n\n/**\n * Deeply populate a model based on UID. Only populating fields that require validation.\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst validationPopulateCache = new Map<string, Record<string, any>>();\n\nconst getPopulateForValidation = (uid: UID.Schema): Record<string, any> => {\n const cached = validationPopulateCache.get(uid);\n if (cached) {\n return cached;\n }\n\n const model = strapi.getModel(uid);\n if (!model) {\n return {};\n }\n\n const result = Object.entries(model.attributes).reduce(\n (populateAcc: any, [attributeName, attribute]) => {\n if (isScalarAttribute(attribute)) {\n // If the scalar attribute requires validation, add it to the fields array\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.fields = populateAcc.fields || [];\n populateAcc.fields.push(attributeName);\n }\n return populateAcc;\n }\n\n if (isMedia(attribute)) {\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = {\n populate: {\n folder: true,\n },\n };\n return populateAcc;\n }\n }\n\n if (isComponent(attribute)) {\n // @ts-expect-error - should be a component\n const component = attribute.component;\n\n // Get the validation result for this component\n const componentResult = getPopulateForValidation(component);\n\n if (Object.keys(componentResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = componentResult;\n }\n\n return populateAcc;\n }\n\n if (isDynamicZone(attribute)) {\n const components = (attribute as Schema.Attribute.DynamicZone).components;\n // Handle dynamic zone components\n const componentsResult = (components || []).reduce(\n (acc, componentUID) => {\n // Get validation populate for this component\n const componentResult = getPopulateForValidation(componentUID);\n\n // Only include component if it has fields requiring validation\n if (Object.keys(componentResult).length > 0) {\n acc[componentUID] = componentResult;\n }\n\n return acc;\n },\n {} as Record<string, any>\n );\n\n // Only add to populate if we have components requiring validation\n if (Object.keys(componentsResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = { on: componentsResult };\n }\n }\n\n return populateAcc;\n },\n {}\n );\n\n validationPopulateCache.set(uid, result);\n return result;\n};\n\n/**\n * getDeepPopulateDraftCount works recursively on the attributes of a model\n * creating a populated object to count all the unpublished relations within the model\n * These relations can be direct to this content type or contained within components/dynamic zones\n * @param uid of the model\n * @returns result\n * @returns result.populate\n * @returns result.hasRelations\n */\nconst draftCountPopulateCache = new Map<string, { populate: any; hasRelations: boolean }>();\n\nconst getDeepPopulateDraftCount = (uid: UID.Schema) => {\n const cached = draftCountPopulateCache.get(uid);\n if (cached) {\n return cached;\n }\n\n const model = strapi.getModel(uid);\n if (!model) {\n return { populate: {}, hasRelations: false };\n }\n let hasRelations = false;\n\n const populate = Object.keys(model.attributes).reduce((populateAcc: any, attributeName) => {\n const attribute: Schema.Attribute.AnyAttribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation': {\n // TODO: Support polymorphic relations\n const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');\n if (isMorphRelation) {\n break;\n }\n\n // Skip relations to content types without draft & publish,\n // as they don't have a publishedAt attribute and can't have drafts\n if (!('target' in attribute)) {\n break;\n }\n\n const targetModel = strapi.getModel(attribute.target);\n if (!targetModel || !hasDraftAndPublish(targetModel)) {\n break;\n }\n\n if (isVisibleAttribute(model, attributeName)) {\n populateAcc[attributeName] = {\n count: true,\n filters: { [PUBLISHED_AT_ATTRIBUTE]: { $null: true } },\n };\n hasRelations = true;\n }\n break;\n }\n case 'component': {\n const { populate, hasRelations: childHasRelations } = getDeepPopulateDraftCount(\n attribute.component\n );\n if (childHasRelations) {\n populateAcc[attributeName] = {\n populate,\n };\n hasRelations = true;\n }\n break;\n }\n case 'dynamiczone': {\n const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {\n const { populate: componentPopulate, hasRelations: componentHasRelations } =\n getDeepPopulateDraftCount(componentUID);\n\n if (componentHasRelations) {\n hasRelations = true;\n\n return { ...acc, [componentUID]: { populate: componentPopulate } };\n }\n\n return acc;\n }, {});\n\n if (!isEmpty(dzPopulateFragment)) {\n populateAcc[attributeName] = { on: dzPopulateFragment };\n }\n break;\n }\n default:\n }\n\n return populateAcc;\n }, {});\n\n const result = { populate, hasRelations };\n draftCountPopulateCache.set(uid, result);\n return result;\n};\n\n/**\n * Create a Strapi populate object which populates all attribute fields of a Strapi query.\n */\nconst getQueryPopulate = async (uid: UID.Schema, query: object): Promise<Populate> => {\n let populateQuery: Populate = {};\n\n await strapiUtils.traverse.traverseQueryFilters(\n /**\n *\n * @param {Object} param0\n * @param {string} param0.key - Attribute name\n * @param {Object} param0.attribute - Attribute definition\n * @param {string} param0.path - Content Type path to the attribute\n * @returns\n */\n ({ attribute, path }: any) => {\n // TODO: handle dynamic zones and morph relations\n if (!attribute || isDynamicZone(attribute) || isMorphToRelation(attribute)) {\n return;\n }\n\n // Populate all relations, components and media\n if (isRelation(attribute) || isMedia(attribute) || isComponent(attribute)) {\n const populatePath = path.attribute.replace(/\\./g, '.populate.');\n // @ts-expect-error - lodash doesn't resolve the Populate type correctly\n populateQuery = set(populatePath, {}, populateQuery);\n }\n },\n { schema: strapi.getModel(uid), getModel: strapi.getModel.bind(strapi) },\n query\n );\n\n return populateQuery;\n};\n\nconst deepPopulateCache = new Map<string, object>();\n\nconst buildDeepPopulate = async (uid: UID.CollectionType) => {\n const cached = deepPopulateCache.get(uid);\n if (cached) {\n return cached;\n }\n\n const result = await getService('populate-builder')(uid)\n .populateDeep(Infinity)\n .countRelations()\n .build();\n\n deepPopulateCache.set(uid, result);\n\n return result;\n};\n\n/**\n * Restrict localizations populate to only metadata fields for localized content types.\n * Returns an empty object for non-localized content types.\n *\n * By default, localizations are deeply populated which includes all relations and\n * components for every locale — this is expensive and unnecessary for CM responses.\n * The CM only needs these fields from localizations:\n * - locale: to identify which locales exist\n * - documentId: to link to the localized document\n * - publishedAt: to determine published/draft status\n * - updatedAt: to support the modified state indicator in the UI\n */\nconst getPopulateForLocalizations = (model: UID.Schema) => {\n const modelSchema = strapi.getModel(model);\n if (\n (modelSchema as unknown as { pluginOptions: { i18n: { localized?: boolean } } }).pluginOptions\n ?.i18n?.localized\n ) {\n return { localizations: { fields: ['locale', 'documentId', 'publishedAt', 'updatedAt'] } };\n }\n\n return {};\n};\n\nexport {\n getDeepPopulate,\n getDeepPopulateDraftCount,\n getPopulateForValidation,\n getQueryPopulate,\n buildDeepPopulate,\n getPopulateForLocalizations,\n};\n"],"names":["isVisibleAttribute","isScalarAttribute","getDoesAttributeRequireValidation","hasDraftAndPublish","strapiUtils","contentTypes","isAnyToMany","relations","PUBLISHED_AT_ATTRIBUTE","constants","isMorphToRelation","attribute","isRelation","relation","includes","isMedia","propEq","isComponent","isDynamicZone","getPopulateForRelation","model","attributeName","countMany","countOne","initialPopulate","isManyRelation","undefined","validationPopulate","getPopulateForValidation","uid","populate","count","getPopulateForDZ","options","level","populatedComponents","components","reduce","acc","componentUID","getDeepPopulate","on","getPopulateFor","attributes","type","component","folder","maxLevel","Infinity","strapi","getModel","Object","keys","populateAcc","merge","validationPopulateCache","Map","cached","get","result","entries","fields","push","componentResult","length","componentsResult","set","draftCountPopulateCache","getDeepPopulateDraftCount","hasRelations","isMorphRelation","toLowerCase","startsWith","targetModel","target","filters","$null","childHasRelations","dzPopulateFragment","componentPopulate","componentHasRelations","isEmpty","getQueryPopulate","query","populateQuery","traverse","traverseQueryFilters","path","populatePath","replace","schema","bind","deepPopulateCache","buildDeepPopulate","getService","populateDeep","countRelations","build","getPopulateForLocalizations","modelSchema","pluginOptions","i18n","localized","localizations"],"mappings":"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"}
|
|
@@ -19,7 +19,8 @@ const isDynamicZone = propEq('type', 'dynamiczone');
|
|
|
19
19
|
* @param options - Options to apply while populating
|
|
20
20
|
*/ function getPopulateForRelation(attribute, model, attributeName, { countMany, countOne, initialPopulate }) {
|
|
21
21
|
const isManyRelation = isAnyToMany(attribute);
|
|
22
|
-
|
|
22
|
+
// Use initialPopulate when explicitly provided (including `false` to suppress population)
|
|
23
|
+
if (initialPopulate !== undefined) {
|
|
23
24
|
return initialPopulate;
|
|
24
25
|
}
|
|
25
26
|
// If populating localizations attribute, also include validatable fields
|
|
@@ -124,12 +125,17 @@ const isDynamicZone = propEq('type', 'dynamiczone');
|
|
|
124
125
|
* @param uid - Unique identifier of the model
|
|
125
126
|
* @param options - Options to apply while populating
|
|
126
127
|
* @param level - Current level of nested call
|
|
127
|
-
*/ const
|
|
128
|
+
*/ const validationPopulateCache = new Map();
|
|
129
|
+
const getPopulateForValidation = (uid)=>{
|
|
130
|
+
const cached = validationPopulateCache.get(uid);
|
|
131
|
+
if (cached) {
|
|
132
|
+
return cached;
|
|
133
|
+
}
|
|
128
134
|
const model = strapi.getModel(uid);
|
|
129
135
|
if (!model) {
|
|
130
136
|
return {};
|
|
131
137
|
}
|
|
132
|
-
|
|
138
|
+
const result = Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute])=>{
|
|
133
139
|
if (isScalarAttribute(attribute)) {
|
|
134
140
|
// If the scalar attribute requires validation, add it to the fields array
|
|
135
141
|
if (getDoesAttributeRequireValidation(attribute)) {
|
|
@@ -182,6 +188,8 @@ const isDynamicZone = propEq('type', 'dynamiczone');
|
|
|
182
188
|
}
|
|
183
189
|
return populateAcc;
|
|
184
190
|
}, {});
|
|
191
|
+
validationPopulateCache.set(uid, result);
|
|
192
|
+
return result;
|
|
185
193
|
};
|
|
186
194
|
/**
|
|
187
195
|
* getDeepPopulateDraftCount works recursively on the attributes of a model
|
|
@@ -191,7 +199,12 @@ const isDynamicZone = propEq('type', 'dynamiczone');
|
|
|
191
199
|
* @returns result
|
|
192
200
|
* @returns result.populate
|
|
193
201
|
* @returns result.hasRelations
|
|
194
|
-
*/ const
|
|
202
|
+
*/ const draftCountPopulateCache = new Map();
|
|
203
|
+
const getDeepPopulateDraftCount = (uid)=>{
|
|
204
|
+
const cached = draftCountPopulateCache.get(uid);
|
|
205
|
+
if (cached) {
|
|
206
|
+
return cached;
|
|
207
|
+
}
|
|
195
208
|
const model = strapi.getModel(uid);
|
|
196
209
|
if (!model) {
|
|
197
210
|
return {
|
|
@@ -268,10 +281,12 @@ const isDynamicZone = propEq('type', 'dynamiczone');
|
|
|
268
281
|
}
|
|
269
282
|
return populateAcc;
|
|
270
283
|
}, {});
|
|
271
|
-
|
|
284
|
+
const result = {
|
|
272
285
|
populate,
|
|
273
286
|
hasRelations
|
|
274
287
|
};
|
|
288
|
+
draftCountPopulateCache.set(uid, result);
|
|
289
|
+
return result;
|
|
275
290
|
};
|
|
276
291
|
/**
|
|
277
292
|
* Create a Strapi populate object which populates all attribute fields of a Strapi query.
|
|
@@ -301,9 +316,43 @@ const isDynamicZone = propEq('type', 'dynamiczone');
|
|
|
301
316
|
}, query);
|
|
302
317
|
return populateQuery;
|
|
303
318
|
};
|
|
304
|
-
const
|
|
305
|
-
|
|
319
|
+
const deepPopulateCache = new Map();
|
|
320
|
+
const buildDeepPopulate = async (uid)=>{
|
|
321
|
+
const cached = deepPopulateCache.get(uid);
|
|
322
|
+
if (cached) {
|
|
323
|
+
return cached;
|
|
324
|
+
}
|
|
325
|
+
const result = await getService('populate-builder')(uid).populateDeep(Infinity).countRelations().build();
|
|
326
|
+
deepPopulateCache.set(uid, result);
|
|
327
|
+
return result;
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* Restrict localizations populate to only metadata fields for localized content types.
|
|
331
|
+
* Returns an empty object for non-localized content types.
|
|
332
|
+
*
|
|
333
|
+
* By default, localizations are deeply populated which includes all relations and
|
|
334
|
+
* components for every locale — this is expensive and unnecessary for CM responses.
|
|
335
|
+
* The CM only needs these fields from localizations:
|
|
336
|
+
* - locale: to identify which locales exist
|
|
337
|
+
* - documentId: to link to the localized document
|
|
338
|
+
* - publishedAt: to determine published/draft status
|
|
339
|
+
* - updatedAt: to support the modified state indicator in the UI
|
|
340
|
+
*/ const getPopulateForLocalizations = (model)=>{
|
|
341
|
+
const modelSchema = strapi.getModel(model);
|
|
342
|
+
if (modelSchema.pluginOptions?.i18n?.localized) {
|
|
343
|
+
return {
|
|
344
|
+
localizations: {
|
|
345
|
+
fields: [
|
|
346
|
+
'locale',
|
|
347
|
+
'documentId',
|
|
348
|
+
'publishedAt',
|
|
349
|
+
'updatedAt'
|
|
350
|
+
]
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
return {};
|
|
306
355
|
};
|
|
307
356
|
|
|
308
|
-
export { buildDeepPopulate, getDeepPopulate, getDeepPopulateDraftCount, getPopulateForValidation, getQueryPopulate };
|
|
357
|
+
export { buildDeepPopulate, getDeepPopulate, getDeepPopulateDraftCount, getPopulateForLocalizations, getPopulateForValidation, getQueryPopulate };
|
|
309
358
|
//# sourceMappingURL=populate.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"populate.mjs","sources":["../../../../server/src/services/utils/populate.ts"],"sourcesContent":["import { merge, isEmpty, set, propEq } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport type { UID, Schema, Modules } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst {\n isVisibleAttribute,\n isScalarAttribute,\n getDoesAttributeRequireValidation,\n hasDraftAndPublish,\n} = strapiUtils.contentTypes;\nconst { isAnyToMany } = strapiUtils.relations;\nconst { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;\n\nconst isMorphToRelation = (attribute: any) =>\n isRelation(attribute) && attribute.relation.includes('morphTo');\nconst isMedia = propEq('type', 'media');\nconst isRelation = propEq('type', 'relation');\nconst isComponent = propEq('type', 'component');\nconst isDynamicZone = propEq('type', 'dynamiczone');\n\n// TODO: Import from @strapi/types when it's available there\ntype Model = Parameters<typeof isVisibleAttribute>[0];\nexport type Populate = Modules.EntityService.Params.Populate.Any<UID.Schema>;\n\ntype PopulateOptions = {\n initialPopulate?: Populate;\n countMany?: boolean;\n countOne?: boolean;\n maxLevel?: number;\n};\n\n/**\n * Populate the model for relation\n * @param attribute - Attribute containing a relation\n * @param attribute.relation - type of relation\n * @param model - Model of the populated entity\n * @param attributeName\n * @param options - Options to apply while populating\n */\nfunction getPopulateForRelation(\n attribute: Schema.Attribute.AnyAttribute,\n model: Model,\n attributeName: string,\n { countMany, countOne, initialPopulate }: PopulateOptions\n) {\n const isManyRelation = isAnyToMany(attribute);\n\n if (initialPopulate) {\n return initialPopulate;\n }\n\n // If populating localizations attribute, also include validatable fields\n // Mainly needed for bulk locale publishing, so the Client has all the information necessary to perform validations\n if (attributeName === 'localizations') {\n const validationPopulate = getPopulateForValidation(model.uid as UID.Schema);\n\n return {\n populate: validationPopulate.populate,\n };\n }\n\n // always populate createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n return true;\n }\n\n if ((isManyRelation && countMany) || (!isManyRelation && countOne)) {\n return { count: true };\n }\n\n return true;\n}\n\n/**\n * Populate the model for Dynamic Zone components\n * @param attribute - Attribute containing the components\n * @param attribute.components - IDs of components\n * @param options - Options to apply while populating\n */\nfunction getPopulateForDZ(\n attribute: Schema.Attribute.DynamicZone,\n options: PopulateOptions,\n level: number\n) {\n // Use fragments to populate the dynamic zone components\n const populatedComponents = (attribute.components || []).reduce(\n (acc: any, componentUID: UID.Component) => ({\n ...acc,\n [componentUID]: {\n populate: getDeepPopulate(componentUID, options, level + 1),\n },\n }),\n {}\n );\n\n return { on: populatedComponents };\n}\n\n/**\n * Get the populated value based on the type of the attribute\n * @param attributeName - Name of the attribute\n * @param model - Model of the populated entity\n * @param model.attributes\n * @param options - Options to apply while populating\n * @param options.countMany\n * @param options.countOne\n * @param options.maxLevel\n * @param level\n */\nfunction getPopulateFor(\n attributeName: string,\n model: any,\n options: PopulateOptions,\n level: number\n): { [key: string]: boolean | object } {\n const attribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation':\n // @ts-expect-error - TODO: support populate count typing\n return {\n [attributeName]: getPopulateForRelation(attribute, model, attributeName, options),\n };\n case 'component':\n return {\n [attributeName]: {\n populate: getDeepPopulate(attribute.component, options, level + 1),\n },\n };\n case 'media':\n return {\n [attributeName]: {\n populate: {\n folder: true,\n },\n },\n };\n case 'dynamiczone':\n return {\n [attributeName]: getPopulateForDZ(attribute, options, level),\n };\n default:\n return {};\n }\n}\n\n/**\n * Deeply populate a model based on UID\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst getDeepPopulate = (\n uid: UID.Schema,\n {\n initialPopulate = {} as any,\n countMany = false,\n countOne = false,\n maxLevel = Infinity,\n }: PopulateOptions = {},\n level = 1\n) => {\n if (level > maxLevel) {\n return {};\n }\n\n const model = strapi.getModel(uid);\n\n if (!model) {\n return {};\n }\n\n return Object.keys(model.attributes).reduce(\n (populateAcc, attributeName: string) =>\n merge(\n populateAcc,\n getPopulateFor(\n attributeName,\n model,\n {\n // @ts-expect-error - improve types\n initialPopulate: initialPopulate?.[attributeName],\n countMany,\n countOne,\n maxLevel,\n },\n level\n )\n ),\n {}\n );\n};\n\n/**\n * Deeply populate a model based on UID. Only populating fields that require validation.\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst getPopulateForValidation = (uid: UID.Schema): Record<string, any> => {\n const model = strapi.getModel(uid);\n if (!model) {\n return {};\n }\n\n return Object.entries(model.attributes).reduce((populateAcc: any, [attributeName, attribute]) => {\n if (isScalarAttribute(attribute)) {\n // If the scalar attribute requires validation, add it to the fields array\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.fields = populateAcc.fields || [];\n populateAcc.fields.push(attributeName);\n }\n return populateAcc;\n }\n\n if (isMedia(attribute)) {\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = {\n populate: {\n folder: true,\n },\n };\n return populateAcc;\n }\n }\n\n if (isComponent(attribute)) {\n // @ts-expect-error - should be a component\n const component = attribute.component;\n\n // Get the validation result for this component\n const componentResult = getPopulateForValidation(component);\n\n if (Object.keys(componentResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = componentResult;\n }\n\n return populateAcc;\n }\n\n if (isDynamicZone(attribute)) {\n const components = (attribute as Schema.Attribute.DynamicZone).components;\n // Handle dynamic zone components\n const componentsResult = (components || []).reduce(\n (acc, componentUID) => {\n // Get validation populate for this component\n const componentResult = getPopulateForValidation(componentUID);\n\n // Only include component if it has fields requiring validation\n if (Object.keys(componentResult).length > 0) {\n acc[componentUID] = componentResult;\n }\n\n return acc;\n },\n {} as Record<string, any>\n );\n\n // Only add to populate if we have components requiring validation\n if (Object.keys(componentsResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = { on: componentsResult };\n }\n }\n\n return populateAcc;\n }, {});\n};\n\n/**\n * getDeepPopulateDraftCount works recursively on the attributes of a model\n * creating a populated object to count all the unpublished relations within the model\n * These relations can be direct to this content type or contained within components/dynamic zones\n * @param uid of the model\n * @returns result\n * @returns result.populate\n * @returns result.hasRelations\n */\nconst getDeepPopulateDraftCount = (uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n if (!model) {\n return { populate: {}, hasRelations: false };\n }\n let hasRelations = false;\n\n const populate = Object.keys(model.attributes).reduce((populateAcc: any, attributeName) => {\n const attribute: Schema.Attribute.AnyAttribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation': {\n // TODO: Support polymorphic relations\n const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');\n if (isMorphRelation) {\n break;\n }\n\n // Skip relations to content types without draft & publish,\n // as they don't have a publishedAt attribute and can't have drafts\n if (!('target' in attribute)) {\n break;\n }\n\n const targetModel = strapi.getModel(attribute.target);\n if (!targetModel || !hasDraftAndPublish(targetModel)) {\n break;\n }\n\n if (isVisibleAttribute(model, attributeName)) {\n populateAcc[attributeName] = {\n count: true,\n filters: { [PUBLISHED_AT_ATTRIBUTE]: { $null: true } },\n };\n hasRelations = true;\n }\n break;\n }\n case 'component': {\n const { populate, hasRelations: childHasRelations } = getDeepPopulateDraftCount(\n attribute.component\n );\n if (childHasRelations) {\n populateAcc[attributeName] = {\n populate,\n };\n hasRelations = true;\n }\n break;\n }\n case 'dynamiczone': {\n const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {\n const { populate: componentPopulate, hasRelations: componentHasRelations } =\n getDeepPopulateDraftCount(componentUID);\n\n if (componentHasRelations) {\n hasRelations = true;\n\n return { ...acc, [componentUID]: { populate: componentPopulate } };\n }\n\n return acc;\n }, {});\n\n if (!isEmpty(dzPopulateFragment)) {\n populateAcc[attributeName] = { on: dzPopulateFragment };\n }\n break;\n }\n default:\n }\n\n return populateAcc;\n }, {});\n\n return { populate, hasRelations };\n};\n\n/**\n * Create a Strapi populate object which populates all attribute fields of a Strapi query.\n */\nconst getQueryPopulate = async (uid: UID.Schema, query: object): Promise<Populate> => {\n let populateQuery: Populate = {};\n\n await strapiUtils.traverse.traverseQueryFilters(\n /**\n *\n * @param {Object} param0\n * @param {string} param0.key - Attribute name\n * @param {Object} param0.attribute - Attribute definition\n * @param {string} param0.path - Content Type path to the attribute\n * @returns\n */\n ({ attribute, path }: any) => {\n // TODO: handle dynamic zones and morph relations\n if (!attribute || isDynamicZone(attribute) || isMorphToRelation(attribute)) {\n return;\n }\n\n // Populate all relations, components and media\n if (isRelation(attribute) || isMedia(attribute) || isComponent(attribute)) {\n const populatePath = path.attribute.replace(/\\./g, '.populate.');\n // @ts-expect-error - lodash doesn't resolve the Populate type correctly\n populateQuery = set(populatePath, {}, populateQuery);\n }\n },\n { schema: strapi.getModel(uid), getModel: strapi.getModel.bind(strapi) },\n query\n );\n\n return populateQuery;\n};\n\nconst buildDeepPopulate = (uid: UID.CollectionType) => {\n return getService('populate-builder')(uid).populateDeep(Infinity).countRelations().build();\n};\n\nexport {\n getDeepPopulate,\n getDeepPopulateDraftCount,\n getPopulateForValidation,\n getQueryPopulate,\n buildDeepPopulate,\n};\n"],"names":["isVisibleAttribute","isScalarAttribute","getDoesAttributeRequireValidation","hasDraftAndPublish","strapiUtils","contentTypes","isAnyToMany","relations","PUBLISHED_AT_ATTRIBUTE","constants","isMorphToRelation","attribute","isRelation","relation","includes","isMedia","propEq","isComponent","isDynamicZone","getPopulateForRelation","model","attributeName","countMany","countOne","initialPopulate","isManyRelation","validationPopulate","getPopulateForValidation","uid","populate","count","getPopulateForDZ","options","level","populatedComponents","components","reduce","acc","componentUID","getDeepPopulate","on","getPopulateFor","attributes","type","component","folder","maxLevel","Infinity","strapi","getModel","Object","keys","populateAcc","merge","entries","fields","push","componentResult","length","componentsResult","getDeepPopulateDraftCount","hasRelations","isMorphRelation","toLowerCase","startsWith","targetModel","target","filters","$null","childHasRelations","dzPopulateFragment","componentPopulate","componentHasRelations","isEmpty","getQueryPopulate","query","populateQuery","traverse","traverseQueryFilters","path","populatePath","replace","set","schema","bind","buildDeepPopulate","getService","populateDeep","countRelations","build"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"populate.mjs","sources":["../../../../server/src/services/utils/populate.ts"],"sourcesContent":["import { merge, isEmpty, set, propEq } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport type { UID, Schema, Modules } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst {\n isVisibleAttribute,\n isScalarAttribute,\n getDoesAttributeRequireValidation,\n hasDraftAndPublish,\n} = strapiUtils.contentTypes;\nconst { isAnyToMany } = strapiUtils.relations;\nconst { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;\n\nconst isMorphToRelation = (attribute: any) =>\n isRelation(attribute) && attribute.relation.includes('morphTo');\nconst isMedia = propEq('type', 'media');\nconst isRelation = propEq('type', 'relation');\nconst isComponent = propEq('type', 'component');\nconst isDynamicZone = propEq('type', 'dynamiczone');\n\n// TODO: Import from @strapi/types when it's available there\ntype Model = Parameters<typeof isVisibleAttribute>[0];\nexport type Populate = Modules.EntityService.Params.Populate.Any<UID.Schema>;\n\ntype PopulateOptions = {\n initialPopulate?: Populate;\n countMany?: boolean;\n countOne?: boolean;\n maxLevel?: number;\n};\n\n/**\n * Populate the model for relation\n * @param attribute - Attribute containing a relation\n * @param attribute.relation - type of relation\n * @param model - Model of the populated entity\n * @param attributeName\n * @param options - Options to apply while populating\n */\nfunction getPopulateForRelation(\n attribute: Schema.Attribute.AnyAttribute,\n model: Model,\n attributeName: string,\n { countMany, countOne, initialPopulate }: PopulateOptions\n) {\n const isManyRelation = isAnyToMany(attribute);\n\n // Use initialPopulate when explicitly provided (including `false` to suppress population)\n if (initialPopulate !== undefined) {\n return initialPopulate;\n }\n\n // If populating localizations attribute, also include validatable fields\n // Mainly needed for bulk locale publishing, so the Client has all the information necessary to perform validations\n if (attributeName === 'localizations') {\n const validationPopulate = getPopulateForValidation(model.uid as UID.Schema);\n\n return {\n populate: validationPopulate.populate,\n };\n }\n\n // always populate createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n return true;\n }\n\n if ((isManyRelation && countMany) || (!isManyRelation && countOne)) {\n return { count: true };\n }\n\n return true;\n}\n\n/**\n * Populate the model for Dynamic Zone components\n * @param attribute - Attribute containing the components\n * @param attribute.components - IDs of components\n * @param options - Options to apply while populating\n */\nfunction getPopulateForDZ(\n attribute: Schema.Attribute.DynamicZone,\n options: PopulateOptions,\n level: number\n) {\n // Use fragments to populate the dynamic zone components\n const populatedComponents = (attribute.components || []).reduce(\n (acc: any, componentUID: UID.Component) => ({\n ...acc,\n [componentUID]: {\n populate: getDeepPopulate(componentUID, options, level + 1),\n },\n }),\n {}\n );\n\n return { on: populatedComponents };\n}\n\n/**\n * Get the populated value based on the type of the attribute\n * @param attributeName - Name of the attribute\n * @param model - Model of the populated entity\n * @param model.attributes\n * @param options - Options to apply while populating\n * @param options.countMany\n * @param options.countOne\n * @param options.maxLevel\n * @param level\n */\nfunction getPopulateFor(\n attributeName: string,\n model: any,\n options: PopulateOptions,\n level: number\n): { [key: string]: boolean | object } {\n const attribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation':\n // @ts-expect-error - TODO: support populate count typing\n return {\n [attributeName]: getPopulateForRelation(attribute, model, attributeName, options),\n };\n case 'component':\n return {\n [attributeName]: {\n populate: getDeepPopulate(attribute.component, options, level + 1),\n },\n };\n case 'media':\n return {\n [attributeName]: {\n populate: {\n folder: true,\n },\n },\n };\n case 'dynamiczone':\n return {\n [attributeName]: getPopulateForDZ(attribute, options, level),\n };\n default:\n return {};\n }\n}\n\n/**\n * Deeply populate a model based on UID\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst getDeepPopulate = (\n uid: UID.Schema,\n {\n initialPopulate = {} as any,\n countMany = false,\n countOne = false,\n maxLevel = Infinity,\n }: PopulateOptions = {},\n level = 1\n) => {\n if (level > maxLevel) {\n return {};\n }\n\n const model = strapi.getModel(uid);\n\n if (!model) {\n return {};\n }\n\n return Object.keys(model.attributes).reduce(\n (populateAcc, attributeName: string) =>\n merge(\n populateAcc,\n getPopulateFor(\n attributeName,\n model,\n {\n // @ts-expect-error - improve types\n initialPopulate: initialPopulate?.[attributeName],\n countMany,\n countOne,\n maxLevel,\n },\n level\n )\n ),\n {}\n );\n};\n\n/**\n * Deeply populate a model based on UID. Only populating fields that require validation.\n * @param uid - Unique identifier of the model\n * @param options - Options to apply while populating\n * @param level - Current level of nested call\n */\nconst validationPopulateCache = new Map<string, Record<string, any>>();\n\nconst getPopulateForValidation = (uid: UID.Schema): Record<string, any> => {\n const cached = validationPopulateCache.get(uid);\n if (cached) {\n return cached;\n }\n\n const model = strapi.getModel(uid);\n if (!model) {\n return {};\n }\n\n const result = Object.entries(model.attributes).reduce(\n (populateAcc: any, [attributeName, attribute]) => {\n if (isScalarAttribute(attribute)) {\n // If the scalar attribute requires validation, add it to the fields array\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.fields = populateAcc.fields || [];\n populateAcc.fields.push(attributeName);\n }\n return populateAcc;\n }\n\n if (isMedia(attribute)) {\n if (getDoesAttributeRequireValidation(attribute)) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = {\n populate: {\n folder: true,\n },\n };\n return populateAcc;\n }\n }\n\n if (isComponent(attribute)) {\n // @ts-expect-error - should be a component\n const component = attribute.component;\n\n // Get the validation result for this component\n const componentResult = getPopulateForValidation(component);\n\n if (Object.keys(componentResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = componentResult;\n }\n\n return populateAcc;\n }\n\n if (isDynamicZone(attribute)) {\n const components = (attribute as Schema.Attribute.DynamicZone).components;\n // Handle dynamic zone components\n const componentsResult = (components || []).reduce(\n (acc, componentUID) => {\n // Get validation populate for this component\n const componentResult = getPopulateForValidation(componentUID);\n\n // Only include component if it has fields requiring validation\n if (Object.keys(componentResult).length > 0) {\n acc[componentUID] = componentResult;\n }\n\n return acc;\n },\n {} as Record<string, any>\n );\n\n // Only add to populate if we have components requiring validation\n if (Object.keys(componentsResult).length > 0) {\n populateAcc.populate = populateAcc.populate || {};\n populateAcc.populate[attributeName] = { on: componentsResult };\n }\n }\n\n return populateAcc;\n },\n {}\n );\n\n validationPopulateCache.set(uid, result);\n return result;\n};\n\n/**\n * getDeepPopulateDraftCount works recursively on the attributes of a model\n * creating a populated object to count all the unpublished relations within the model\n * These relations can be direct to this content type or contained within components/dynamic zones\n * @param uid of the model\n * @returns result\n * @returns result.populate\n * @returns result.hasRelations\n */\nconst draftCountPopulateCache = new Map<string, { populate: any; hasRelations: boolean }>();\n\nconst getDeepPopulateDraftCount = (uid: UID.Schema) => {\n const cached = draftCountPopulateCache.get(uid);\n if (cached) {\n return cached;\n }\n\n const model = strapi.getModel(uid);\n if (!model) {\n return { populate: {}, hasRelations: false };\n }\n let hasRelations = false;\n\n const populate = Object.keys(model.attributes).reduce((populateAcc: any, attributeName) => {\n const attribute: Schema.Attribute.AnyAttribute = model.attributes[attributeName];\n\n switch (attribute.type) {\n case 'relation': {\n // TODO: Support polymorphic relations\n const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');\n if (isMorphRelation) {\n break;\n }\n\n // Skip relations to content types without draft & publish,\n // as they don't have a publishedAt attribute and can't have drafts\n if (!('target' in attribute)) {\n break;\n }\n\n const targetModel = strapi.getModel(attribute.target);\n if (!targetModel || !hasDraftAndPublish(targetModel)) {\n break;\n }\n\n if (isVisibleAttribute(model, attributeName)) {\n populateAcc[attributeName] = {\n count: true,\n filters: { [PUBLISHED_AT_ATTRIBUTE]: { $null: true } },\n };\n hasRelations = true;\n }\n break;\n }\n case 'component': {\n const { populate, hasRelations: childHasRelations } = getDeepPopulateDraftCount(\n attribute.component\n );\n if (childHasRelations) {\n populateAcc[attributeName] = {\n populate,\n };\n hasRelations = true;\n }\n break;\n }\n case 'dynamiczone': {\n const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {\n const { populate: componentPopulate, hasRelations: componentHasRelations } =\n getDeepPopulateDraftCount(componentUID);\n\n if (componentHasRelations) {\n hasRelations = true;\n\n return { ...acc, [componentUID]: { populate: componentPopulate } };\n }\n\n return acc;\n }, {});\n\n if (!isEmpty(dzPopulateFragment)) {\n populateAcc[attributeName] = { on: dzPopulateFragment };\n }\n break;\n }\n default:\n }\n\n return populateAcc;\n }, {});\n\n const result = { populate, hasRelations };\n draftCountPopulateCache.set(uid, result);\n return result;\n};\n\n/**\n * Create a Strapi populate object which populates all attribute fields of a Strapi query.\n */\nconst getQueryPopulate = async (uid: UID.Schema, query: object): Promise<Populate> => {\n let populateQuery: Populate = {};\n\n await strapiUtils.traverse.traverseQueryFilters(\n /**\n *\n * @param {Object} param0\n * @param {string} param0.key - Attribute name\n * @param {Object} param0.attribute - Attribute definition\n * @param {string} param0.path - Content Type path to the attribute\n * @returns\n */\n ({ attribute, path }: any) => {\n // TODO: handle dynamic zones and morph relations\n if (!attribute || isDynamicZone(attribute) || isMorphToRelation(attribute)) {\n return;\n }\n\n // Populate all relations, components and media\n if (isRelation(attribute) || isMedia(attribute) || isComponent(attribute)) {\n const populatePath = path.attribute.replace(/\\./g, '.populate.');\n // @ts-expect-error - lodash doesn't resolve the Populate type correctly\n populateQuery = set(populatePath, {}, populateQuery);\n }\n },\n { schema: strapi.getModel(uid), getModel: strapi.getModel.bind(strapi) },\n query\n );\n\n return populateQuery;\n};\n\nconst deepPopulateCache = new Map<string, object>();\n\nconst buildDeepPopulate = async (uid: UID.CollectionType) => {\n const cached = deepPopulateCache.get(uid);\n if (cached) {\n return cached;\n }\n\n const result = await getService('populate-builder')(uid)\n .populateDeep(Infinity)\n .countRelations()\n .build();\n\n deepPopulateCache.set(uid, result);\n\n return result;\n};\n\n/**\n * Restrict localizations populate to only metadata fields for localized content types.\n * Returns an empty object for non-localized content types.\n *\n * By default, localizations are deeply populated which includes all relations and\n * components for every locale — this is expensive and unnecessary for CM responses.\n * The CM only needs these fields from localizations:\n * - locale: to identify which locales exist\n * - documentId: to link to the localized document\n * - publishedAt: to determine published/draft status\n * - updatedAt: to support the modified state indicator in the UI\n */\nconst getPopulateForLocalizations = (model: UID.Schema) => {\n const modelSchema = strapi.getModel(model);\n if (\n (modelSchema as unknown as { pluginOptions: { i18n: { localized?: boolean } } }).pluginOptions\n ?.i18n?.localized\n ) {\n return { localizations: { fields: ['locale', 'documentId', 'publishedAt', 'updatedAt'] } };\n }\n\n return {};\n};\n\nexport {\n getDeepPopulate,\n getDeepPopulateDraftCount,\n getPopulateForValidation,\n getQueryPopulate,\n buildDeepPopulate,\n getPopulateForLocalizations,\n};\n"],"names":["isVisibleAttribute","isScalarAttribute","getDoesAttributeRequireValidation","hasDraftAndPublish","strapiUtils","contentTypes","isAnyToMany","relations","PUBLISHED_AT_ATTRIBUTE","constants","isMorphToRelation","attribute","isRelation","relation","includes","isMedia","propEq","isComponent","isDynamicZone","getPopulateForRelation","model","attributeName","countMany","countOne","initialPopulate","isManyRelation","undefined","validationPopulate","getPopulateForValidation","uid","populate","count","getPopulateForDZ","options","level","populatedComponents","components","reduce","acc","componentUID","getDeepPopulate","on","getPopulateFor","attributes","type","component","folder","maxLevel","Infinity","strapi","getModel","Object","keys","populateAcc","merge","validationPopulateCache","Map","cached","get","result","entries","fields","push","componentResult","length","componentsResult","set","draftCountPopulateCache","getDeepPopulateDraftCount","hasRelations","isMorphRelation","toLowerCase","startsWith","targetModel","target","filters","$null","childHasRelations","dzPopulateFragment","componentPopulate","componentHasRelations","isEmpty","getQueryPopulate","query","populateQuery","traverse","traverseQueryFilters","path","populatePath","replace","schema","bind","deepPopulateCache","buildDeepPopulate","getService","populateDeep","countRelations","build","getPopulateForLocalizations","modelSchema","pluginOptions","i18n","localized","localizations"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/collection-types.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"collection-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/collection-types.ts"],"names":[],"mappings":";cAiPkB,GAAG;iBA+FA,GAAG;gBA2DJ,GAAG;gBA0BH,GAAG;eAYJ,GAAG;mBA4CC,GAAG;gBAmBN,GAAG;IAoCrB;;;OAGG;iBACgB,GAAG;qBA+FC,GAAG;uBA8CD,GAAG;mBAyCP,GAAG;iBAyDL,GAAG;oBAwCA,GAAG;6BA6CM,GAAG;wCAqCQ,GAAG;;AAjpB/C,wBA4qBE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/single-types.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"single-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/single-types.ts"],"names":[],"mappings":";cA8FkB,GAAG;wBAgDO,GAAG;gBAYX,GAAG;iBAsCF,GAAG;mBAiDD,GAAG;iBAiDL,GAAG;6BAiCS,GAAG;;AAtOpC,wBAkQE"}
|
|
@@ -7,8 +7,8 @@ import type { AvailableLocaleDocument } from '../../../../shared/contracts/colle
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const formatDocumentWithMetadata: (permissionChecker: any, uid: UID.ContentType, document: DocumentVersion, opts?: GetMetadataOptions) => Promise<{
|
|
9
9
|
meta: {
|
|
10
|
-
availableLocales: AvailableLocaleDocument[];
|
|
11
|
-
availableStatus: Partial<DocumentVersion>[];
|
|
10
|
+
availableLocales: never[] | AvailableLocaleDocument[];
|
|
11
|
+
availableStatus: Pick<any, string>[] | Partial<DocumentVersion>[];
|
|
12
12
|
};
|
|
13
13
|
data: {
|
|
14
14
|
status: string | undefined;
|
|
@@ -187,8 +187,13 @@ declare const _default: () => {
|
|
|
187
187
|
getManyAvailableStatus(uid: import("@strapi/types/dist/uid").ContentType, documents: import("./services/document-metadata").DocumentVersion[]): Promise<any[]>;
|
|
188
188
|
getStatus(version: import("./services/document-metadata").DocumentVersion, otherDocumentStatuses?: import("../../shared/contracts/collection-types").AvailableStatusDocument[] | undefined): string;
|
|
189
189
|
getMetadata(uid: import("@strapi/types/dist/uid").ContentType, version: import("./services/document-metadata").DocumentVersion, { availableLocales, availableStatus }?: import("./services/document-metadata").GetMetadataOptions): Promise<{
|
|
190
|
+
availableLocales: never[];
|
|
191
|
+
availableStatus: Pick<any, string>[];
|
|
192
|
+
versions: import("./services/document-metadata").DocumentVersion[];
|
|
193
|
+
} | {
|
|
190
194
|
availableLocales: import("../../shared/contracts/collection-types").AvailableLocaleDocument[];
|
|
191
195
|
availableStatus: Partial<import("./services/document-metadata").DocumentVersion>[];
|
|
196
|
+
versions: any[];
|
|
192
197
|
}>;
|
|
193
198
|
formatDocumentWithMetadata(uid: import("@strapi/types/dist/uid").ContentType, document: import("./services/document-metadata").DocumentVersion, opts?: import("./services/document-metadata").GetMetadataOptions): Promise<{
|
|
194
199
|
data: {
|
|
@@ -201,6 +206,9 @@ declare const _default: () => {
|
|
|
201
206
|
publishedAt?: string | Date | null | undefined;
|
|
202
207
|
};
|
|
203
208
|
meta: {
|
|
209
|
+
availableLocales: never[];
|
|
210
|
+
availableStatus: Pick<any, string>[];
|
|
211
|
+
} | {
|
|
204
212
|
availableLocales: import("../../shared/contracts/collection-types").AvailableLocaleDocument[];
|
|
205
213
|
availableStatus: Partial<import("./services/document-metadata").DocumentVersion>[];
|
|
206
214
|
};
|
|
@@ -232,13 +240,19 @@ declare const _default: () => {
|
|
|
232
240
|
}): Promise<{
|
|
233
241
|
count: number;
|
|
234
242
|
}>;
|
|
235
|
-
publish(id: string, uid: `admin::${string}` | `strapi::${string}` | `api::${string}.${string}` | `plugin::${string}.${string}`, opts?: Omit<import("@strapi/types/dist/modules/documents/params/document-engine").Publish<import("@strapi/types/dist/uid").ContentType>, "documentId">
|
|
243
|
+
publish(id: string, uid: `admin::${string}` | `strapi::${string}` | `api::${string}.${string}` | `plugin::${string}.${string}`, opts?: Omit<import("@strapi/types/dist/modules/documents/params/document-engine").Publish<import("@strapi/types/dist/uid").ContentType>, "documentId"> & {
|
|
244
|
+
populate?: object | undefined;
|
|
245
|
+
}): Promise<import("@strapi/types/dist/modules/documents").AnyDocument[]>;
|
|
236
246
|
publishMany(uid: import("@strapi/types/dist/uid").ContentType, documentIds: string[], locale?: string | string[] | undefined): Promise<number>;
|
|
237
247
|
unpublishMany(documentIds: string[], uid: `admin::${string}` | `strapi::${string}` | `api::${string}.${string}` | `plugin::${string}.${string}`, opts?: Omit<import("@strapi/types/dist/modules/documents/params/document-engine").Unpublish<import("@strapi/types/dist/uid").ContentType>, "documentId">): Promise<{
|
|
238
248
|
count: number;
|
|
239
249
|
}>;
|
|
240
|
-
unpublish(id: string, uid: `admin::${string}` | `strapi::${string}` | `api::${string}.${string}` | `plugin::${string}.${string}`, opts?: Omit<import("@strapi/types/dist/modules/documents/params/document-engine").Unpublish<import("@strapi/types/dist/uid").ContentType>, "documentId">
|
|
241
|
-
|
|
250
|
+
unpublish(id: string, uid: `admin::${string}` | `strapi::${string}` | `api::${string}.${string}` | `plugin::${string}.${string}`, opts?: Omit<import("@strapi/types/dist/modules/documents/params/document-engine").Unpublish<import("@strapi/types/dist/uid").ContentType>, "documentId"> & {
|
|
251
|
+
populate?: object | undefined;
|
|
252
|
+
}): Promise<import("@strapi/types/dist/modules/documents").AnyDocument | undefined>;
|
|
253
|
+
discardDraft(id: string, uid: `admin::${string}` | `strapi::${string}` | `api::${string}.${string}` | `plugin::${string}.${string}`, opts?: Omit<import("@strapi/types/dist/modules/documents/params/document-engine").DiscardDraft<import("@strapi/types/dist/uid").ContentType>, "documentId"> & {
|
|
254
|
+
populate?: object | undefined;
|
|
255
|
+
}): Promise<import("@strapi/types/dist/modules/documents").AnyDocument | undefined>;
|
|
242
256
|
countDraftRelations(id: string, uid: import("@strapi/types/dist/uid").ContentType, locale: string): Promise<number>;
|
|
243
257
|
countManyEntriesDraftRelations(documentIds: string[], uid: `admin::${string}` | `strapi::${string}` | `api::${string}.${string}` | `plugin::${string}.${string}`, locale: string | string[]): Promise<number>;
|
|
244
258
|
};
|
|
@@ -340,6 +354,7 @@ declare const _default: () => {
|
|
|
340
354
|
toOne: boolean;
|
|
341
355
|
}): any;
|
|
342
356
|
populateDeep(level?: number): any;
|
|
357
|
+
withPopulateOverride(overrides: Record<string, any>): any;
|
|
343
358
|
build(): Promise<{} | undefined>;
|
|
344
359
|
};
|
|
345
360
|
uid: ({ strapi }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,wBAUE"}
|