Skip to content
This repository was archived by the owner on Sep 16, 2025. It is now read-only.

Commit 430f90b

Browse files
refactor(slugController): internalise transform
Resolves #108
1 parent e45d80d commit 430f90b

File tree

2 files changed

+99
-2
lines changed

2 files changed

+99
-2
lines changed

server/controllers/slug-controller.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
const _ = require('lodash');
44
const { NotFoundError } = require('@strapi/utils').errors;
55
const { getPluginService } = require('../utils/getPluginService');
6-
const { transformResponse } = require('@strapi/strapi/dist/core-api/controller/transform');
76
const { isValidFindSlugParams } = require('../utils/isValidFindSlugParams');
87
const { sanitizeOutput } = require('../utils/sanitizeOutput');
98
const { hasRequiredModelScopes } = require('../utils/hasRequiredModelScopes');
9+
const transform = require('../utils/transform');
1010

1111
module.exports = ({ strapi }) => ({
1212
async findSlug(ctx) {
@@ -40,7 +40,7 @@ module.exports = ({ strapi }) => ({
4040

4141
if (data) {
4242
const sanitizedEntity = await sanitizeOutput(data, contentType, auth);
43-
ctx.body = transformResponse(sanitizedEntity, {}, { contentType });
43+
ctx.body = transform.response({ data: sanitizedEntity, schema: contentType });
4444
} else {
4545
throw new NotFoundError();
4646
}

server/utils/transform.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
'use strict';
2+
const { isNil, isPlainObject } = require('lodash/fp');
3+
4+
function response({ data, schema }) {
5+
return transformResponse(data, {}, { contentType: schema });
6+
}
7+
8+
// adapted from https://github.com/strapi/strapi/blob/main/packages/core/strapi/src/core-api/controller/transform.ts
9+
function isEntry(property) {
10+
return property === null || isPlainObject(property) || Array.isArray(property);
11+
}
12+
13+
function isDZEntries(property) {
14+
return Array.isArray(property);
15+
}
16+
17+
function transformResponse(resource, meta = {}, opts = {}) {
18+
if (isNil(resource)) {
19+
return resource;
20+
}
21+
22+
return {
23+
data: transformEntry(resource, opts?.contentType),
24+
meta,
25+
};
26+
}
27+
28+
function transformComponent(data, component) {
29+
if (Array.isArray(data)) {
30+
return data.map((datum) => transformComponent(datum, component));
31+
}
32+
33+
const res = transformEntry(data, component);
34+
35+
if (isNil(res)) {
36+
return res;
37+
}
38+
39+
const { id, attributes } = res;
40+
return { id, ...attributes };
41+
}
42+
43+
function transformEntry(entry, type) {
44+
if (isNil(entry)) {
45+
return entry;
46+
}
47+
48+
if (Array.isArray(entry)) {
49+
return entry.map((singleEntry) => transformEntry(singleEntry, type));
50+
}
51+
52+
if (!isPlainObject(entry)) {
53+
throw new Error('Entry must be an object');
54+
}
55+
56+
const { id, ...properties } = entry;
57+
58+
const attributeValues = {};
59+
60+
for (const key of Object.keys(properties)) {
61+
const property = properties[key];
62+
const attribute = type && type.attributes[key];
63+
64+
if (attribute && attribute.type === 'relation' && isEntry(property) && 'target' in attribute) {
65+
const data = transformEntry(property, strapi.contentType(attribute.target));
66+
67+
attributeValues[key] = { data };
68+
} else if (attribute && attribute.type === 'component' && isEntry(property)) {
69+
attributeValues[key] = transformComponent(property, strapi.components[attribute.component]);
70+
} else if (attribute && attribute.type === 'dynamiczone' && isDZEntries(property)) {
71+
if (isNil(property)) {
72+
attributeValues[key] = property;
73+
}
74+
75+
attributeValues[key] = property.map((subProperty) => {
76+
return transformComponent(subProperty, strapi.components[subProperty.__component]);
77+
});
78+
} else if (attribute && attribute.type === 'media' && isEntry(property)) {
79+
const data = transformEntry(property, strapi.contentType('plugin::upload.file'));
80+
81+
attributeValues[key] = { data };
82+
} else {
83+
attributeValues[key] = property;
84+
}
85+
}
86+
87+
return {
88+
id,
89+
attributes: attributeValues,
90+
// NOTE: not necessary for now
91+
// meta: {},
92+
};
93+
}
94+
95+
module.exports = {
96+
response,
97+
};

0 commit comments

Comments
 (0)