Skip to content

Commit 696c1da

Browse files
committed
Initial commit
1 parent af4f3db commit 696c1da

File tree

11 files changed

+236
-2
lines changed

11 files changed

+236
-2
lines changed

.DS_Store

6 KB
Binary file not shown.

CONTRIBUTION.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
# Contributions
3+
4+
Thank you for considering contributing to **strapi-plugin-nested-populator**! Your support and contributions are invaluable to us and help make this project even better.
5+
6+
## Ways to Contribute
7+
8+
You can contribute in the following ways:
9+
10+
1. **Reporting Bugs**: If you encounter any bugs or issues, please report them by opening an issue on our [GitHub repository](https://github.com/encoresky/strapi-plugin-nested-populator/issues). Include as much detail as possible, including steps to reproduce the issue and any relevant screenshots or error messages.
11+
12+
2. **Suggesting Features**: If you have a feature request or idea for improving the project, feel free to open an issue with the label "feature request" and describe your suggestion in detail.
13+
14+
3. **Improving Documentation**: You can help us by improving the documentation, fixing typos, or expanding sections that you think need more explanation.
15+
16+
4. **Submitting Pull Requests**: We welcome code contributions! If you want to implement a feature or fix a bug, feel free to submit a pull request. Make sure to follow the guidelines below
17+
18+
## Pull Request Guidelines
19+
20+
To ensure a smooth contribution process, please follow these guidelines
21+
22+
- Fork the repository and create your branch from the main branch.
23+
- Ensure that your code follows the project’s coding style and conventions.
24+
- Test your changes thoroughly and include tests for new features or bug fixes.
25+
- Write clear commit messages and provide a detailed description of your pull request.
26+
- Make sure your pull request passes all CI checks.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
21+
SOFTWARE.

README.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,58 @@
1-
# strapi-plugin-nested-populator
1+
# Strapi plugin nested populator
2+
Unleash the full potential of your Strapi content with nested, customizable population!
3+
4+
## Features
5+
6+
- Effortlessly populate nested content structures via REST API
7+
- Customize population depth on-the-fly
8+
- Works seamlessly with all collections and single types
9+
- Simple installation and configuration
10+
11+
## Installation
12+
13+
`npm install strapi-plugin-nested-populator`
14+
15+
`yarn add strapi-plugin-nested-populator`
16+
17+
18+
## Usages
19+
20+
- Deep populate with default depth
21+
22+
`/api/pages?customPopulate=nested`
23+
24+
- Specify custom depth
25+
26+
`/api/pages?customPopulate=nested&customDepth=4`
27+
28+
## Good to know
29+
30+
- Default maximum depth: 6 levels
31+
- Compatible with findOne and findMany methods
32+
- Depth easily customizable via API parameters or plugin configuration
33+
34+
## Configuration
35+
36+
Tailor the default depth to your needs by editing `config/plugins.js`
37+
38+
```
39+
module.exports = ({ env }) => ({
40+
'strapi-plugin-nested-populator': {
41+
config: {
42+
defaultDepth: 4, // Default is 6
43+
}
44+
},
45+
});
46+
```
47+
48+
## Keywords
49+
50+
strapi, strapi plugin, populate, strapi populate, custom populate, depth, custom depth, deep populate, nested, nested fetch, nested populate
51+
52+
## Contributing
53+
54+
We welcome contributions! Feel free to open issues or submit pull requests to help improve this plugin.
55+
56+
## License
57+
58+
[MIT](https://github.com/encoresky/strapi-plugin-nested-populator/blob/main/LICENSE)

main/.DS_Store

6 KB
Binary file not shown.

main/configuration/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
module.exports = {
4+
default: {
5+
defaultDepth: 6,
6+
skipCreatorFields: true,
7+
},
8+
validator: () => { },
9+
};

main/framework.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
const { buildPopulateTree } = require('./utils');
4+
5+
module.exports = ({ strapi }) => {
6+
// Subscribe to the relevant lifecycle events.
7+
strapi.db.lifecycles.subscribe((event) => {
8+
const { action, params, model } = event;
9+
10+
// Only proceed for 'beforeFindMany' or 'beforeFindOne' actions.
11+
if (action === 'beforeFindMany' || action === 'beforeFindOne') {
12+
const { customPopulate, customDepth } = params || {};
13+
14+
// Get the default depth from plugin config, fallback to 5 if undefined.
15+
const defaultDepth = strapi
16+
.plugin('strapi-plugin-nested-populator')
17+
?.config('defaultDepth') || 5;
18+
19+
// Apply population logic if 'nested' population is requested.
20+
if (customPopulate === 'nested') {
21+
const depth = customDepth > 0 ? customDepth : defaultDepth;
22+
const modelObject = buildPopulateTree(model.uid, depth, []);
23+
24+
// Update the event params with the computed population object.
25+
params.populate = modelObject.populate;
26+
}
27+
}
28+
});
29+
};

main/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
const bootstrap = require('./framework');
4+
const config = require('./configuration')
5+
6+
module.exports = {
7+
bootstrap,
8+
config
9+
};

main/utils/index.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const { isEmpty, merge } = require("lodash/fp");
2+
3+
const extractModelAttributes = (model) => {
4+
// Remove 'related' field for 'upload.file', return other attributes.
5+
if (model.uid === "plugin::upload.file") {
6+
const { related, ...attributes } = model.attributes;
7+
return attributes;
8+
}
9+
return model.attributes;
10+
};
11+
12+
const buildPopulateTree = (modelUid, maxDepth = 20, ignore = []) => {
13+
const skipCreatorFields = strapi
14+
.plugin('strapi-plugin-nested-populator')
15+
?.config('skipCreatorFields');
16+
17+
// Base conditions to terminate recursion.
18+
if (maxDepth <= 1) return true;
19+
if (modelUid === "admin::user" && skipCreatorFields) return undefined;
20+
21+
const populate = {};
22+
const model = strapi.getModel(modelUid);
23+
24+
// Add model's collection name to ignore list if not already present.
25+
if (!ignore.includes(model.collectionName)) {
26+
ignore.push(model.collectionName);
27+
}
28+
29+
for (const [key, value] of Object.entries(extractModelAttributes(model))) {
30+
if (ignore.includes(key)) continue;
31+
32+
if (value) {
33+
switch (value.type) {
34+
case "component":
35+
populate[key] = buildPopulateTree(value.component, maxDepth - 1);
36+
break;
37+
38+
case "dynamiczone":
39+
const dynamicPopulate = value.components.reduce((acc, comp) => {
40+
const componentPopulate = buildPopulateTree(comp, maxDepth - 1);
41+
return componentPopulate === true ? acc : merge(acc, componentPopulate);
42+
}, {});
43+
populate[key] = isEmpty(dynamicPopulate) ? true : dynamicPopulate;
44+
break;
45+
46+
case "relation":
47+
const relationPopulate = buildPopulateTree(
48+
value.target,
49+
key === "localizations" && maxDepth > 2 ? 1 : maxDepth - 1,
50+
ignore
51+
);
52+
if (relationPopulate) {
53+
populate[key] = relationPopulate;
54+
}
55+
break;
56+
57+
case "media":
58+
populate[key] = true;
59+
break;
60+
61+
default:
62+
break;
63+
}
64+
}
65+
}
66+
67+
// Return the full populate object or true if no populates were added.
68+
return isEmpty(populate) ? true : { populate };
69+
};
70+
71+
module.exports = {
72+
buildPopulateTree
73+
};

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "strapi-plugin-nested-populator",
3+
"version": "1.0.0",
4+
"description": "Strapi plugin that populates nested content structures via REST API",
5+
"strapi": {
6+
"name": "strapi-plugin-nested-populator",
7+
"description": "Api helper to populate nested content structures.",
8+
"kind": "plugin"
9+
},
10+
"dependencies": {},
11+
"author": {
12+
"name": "EncoreSky Technologies"
13+
},
14+
"maintainers": [
15+
{
16+
"name": "EncoreSky Technologies"
17+
}
18+
],
19+
"repository": {
20+
"type": "git",
21+
"url": "https://github.com/encoresky/strapi-plugin-nested-populator"
22+
},
23+
"engines": {
24+
"node": ">=14.19.1 <=20.x.x",
25+
"npm": ">=6.0.0"
26+
},
27+
"license": "MIT"
28+
}

0 commit comments

Comments
 (0)