Skip to content

Commit 6d76268

Browse files
dhokofaessler
andauthored
feat: migrate custom params to valid strapi params._q (#23)
* feat: migrate custom params to valid strapi params._q https://github.com/strapi/strapi/blob/develop/packages/core/core/src/services/document-service/repository.ts#L327 And allowelisted is the :sweep: variant here https://github.com/strapi/strapi/blob/develop/packages/core/core/src/services/document-service/transform/query.ts#L9 Starting from there it's not possible to get back our extra populateAll: true anymore. Everything is hardcoded https://github.com/strapi/strapi/blob/develop/packages/core/utils/src/content-api-constants.ts#L7 https://github.com/strapi/strapi/blob/develop/packages/core/core/src/services/document-service/params.ts Also remove the KoaJS Router state from the DB lifecycle, it doesn't work inside the UI. * fix: detect koa state and bind _q tag * feat: improve readme * fix: resolve lint error no unused imports --------- Co-authored-by: Jan Fässler <git@faessler.be>
1 parent 67bddfa commit 6d76268

5 files changed

Lines changed: 68 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ module.exports = {
5151
- The plugin provides a global middleware that intercepts requests with `?populate=all` and rewrites the query to trigger recursive population.
5252
- In the background, it builds a standard Strapi populate query as described in the [Strapi documentation](https://docs.strapi.io/cms/api/rest/populate-select).
5353
- You can control which relations are included using the relations config option.
54-
- Inside the document API, you can set `populate: '*'` and `populateAll: true` to make it work
54+
- Inside the document API, you can set `populate: '*'` and `_q: "populate-all"` to make it work ("populate-all" can be anywhere inside `_q`, we detect it via .includes)

sandbox/tests/populate-all.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,44 @@ describe("strapi-plugin-populate-all", () => {
2121
"category"
2222
);
2323
});
24+
25+
test("if everything is populated with populateAll=true", async () => {
26+
const response = await strapiRequest.get(
27+
"/api/articles?status=draft&populateAll=true"
28+
);
29+
30+
// request succeeds
31+
expect(response.statusCode).toBe(200);
32+
33+
// has first level of population
34+
expect(response.body.data[0]).toHaveProperty("cover");
35+
expect(response.body.data[0]).toHaveProperty("author");
36+
expect(response.body.data[0]).toHaveProperty("category");
37+
expect(response.body.data[0]).toHaveProperty("blocks");
38+
39+
// doesn't loop
40+
expect(response.body.data[0].category.articles[0]).not.toHaveProperty(
41+
"category"
42+
);
43+
});
44+
45+
test("if everything is populated with ?populateAll", async () => {
46+
const response = await strapiRequest.get(
47+
"/api/articles?status=draft&populateAll"
48+
);
49+
50+
// request succeeds
51+
expect(response.statusCode).toBe(200);
52+
53+
// has first level of population
54+
expect(response.body.data[0]).toHaveProperty("cover");
55+
expect(response.body.data[0]).toHaveProperty("author");
56+
expect(response.body.data[0]).toHaveProperty("category");
57+
expect(response.body.data[0]).toHaveProperty("blocks");
58+
59+
// doesn't loop
60+
expect(response.body.data[0].category.articles[0]).not.toHaveProperty(
61+
"category"
62+
);
63+
});
2464
});

server/src/bootstrap.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Core, UID } from "@strapi/strapi";
2+
import { PLUGIN_QUERY_DOCUMENT_TAG } from "./config";
23
import { getPopulateQuery } from "./utils/getPopulateQuery";
34

45
const bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {
@@ -8,7 +9,11 @@ const bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {
89
event.action === "beforeFindMany" ||
910
event.action === "beforeFindOne"
1011
) {
11-
if (strapi.requestContext.get()?.query?.populateAll) {
12+
// There is a whitelist of keys we can use to detect our
13+
// filter from the params
14+
// https://github.com/strapi/strapi/blob/develop/packages/core/utils/src/content-api-constants.ts
15+
// We cheat.
16+
if (event.params._q?.includes(PLUGIN_QUERY_DOCUMENT_TAG)) {
1217
strapi.log.debug(
1318
`[populate-all] recursively populate ${event.model.uid}`
1419
);
@@ -17,6 +22,14 @@ const bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {
1722
if (populateQuery?.populate) {
1823
event.params.populate = populateQuery.populate;
1924
}
25+
26+
// Clean our tag from the custom query.
27+
const query = event.params._q.replace(PLUGIN_QUERY_DOCUMENT_TAG, "");
28+
if (query.length > 0) {
29+
event.params._q = query;
30+
} else {
31+
delete event.params._q;
32+
}
2033
}
2134
}
2235
} catch (error) {

server/src/config/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export const PLUGIN_QUERY_DOCUMENT_TAG = "populate-all";
2+
13
export default {
24
default: {
35
relations: true,

server/src/middlewares/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Context, Next } from "koa";
2+
import { PLUGIN_QUERY_DOCUMENT_TAG } from "../config";
23

34
export default {
45
/**
@@ -8,9 +9,18 @@ export default {
89
* The bootstrap script later picks up `?populateAll=true` to apply the desired populate logic.
910
*/
1011
populateAll: async (ctx: Context, next: Next) => {
12+
// always bind the tag so we can load the execpected populate hook
13+
// populateAll=true or ?populateAll (value can be 'true' or null)
14+
if (
15+
(ctx.query.populateAll && ctx.query.populateAll !== "false") ||
16+
ctx.query.populateAll === null
17+
) {
18+
ctx.query._q = [ctx.query._q || "", PLUGIN_QUERY_DOCUMENT_TAG].join("");
19+
}
20+
1121
if (ctx.query.populate === "all") {
1222
ctx.query.populate = undefined;
13-
ctx.query.populateAll = true;
23+
ctx.query._q = [ctx.query._q || "", PLUGIN_QUERY_DOCUMENT_TAG].join("");
1424
}
1525
await next();
1626
},

0 commit comments

Comments
 (0)