multi-content-type-relation 2.0.1 → 2.1.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/_chunks/en-Bk9okOMP.js +1 -0
- package/dist/_chunks/en-Bk9okOMP.js.map +1 -0
- package/dist/_chunks/en-Cj4T04Z2.mjs +1 -0
- package/dist/_chunks/en-Cj4T04Z2.mjs.map +1 -0
- package/dist/_chunks/fr-KHPiQOFP.mjs +1 -0
- package/dist/_chunks/fr-KHPiQOFP.mjs.map +1 -0
- package/dist/_chunks/fr-ZS3aTnjj.js +1 -0
- package/dist/_chunks/fr-ZS3aTnjj.js.map +1 -0
- package/dist/_chunks/{index-Cyd6H1uV.mjs → index-BHcolZ4N.mjs} +4 -6
- package/dist/_chunks/index-BHcolZ4N.mjs.map +1 -0
- package/dist/_chunks/{index-CQ_pNHWj.js → index-BtldAbIW.js} +4 -6
- package/dist/_chunks/index-BtldAbIW.js.map +1 -0
- package/dist/_chunks/index-CktBIBSM.js +333 -0
- package/dist/_chunks/index-CktBIBSM.js.map +1 -0
- package/dist/_chunks/index-CxWt3llJ.js +3567 -0
- package/dist/_chunks/index-CxWt3llJ.js.map +1 -0
- package/dist/_chunks/{index-5liGVtQX.js → index-CyBD50Lc.js} +4 -2
- package/dist/_chunks/index-CyBD50Lc.js.map +1 -0
- package/dist/_chunks/index-D6nv39Fp.mjs +3565 -0
- package/dist/_chunks/index-D6nv39Fp.mjs.map +1 -0
- package/dist/_chunks/{index-D3M5NaOA.mjs → index-DGcImy9s.mjs} +5 -3
- package/dist/_chunks/index-DGcImy9s.mjs.map +1 -0
- package/dist/_chunks/index-DdX2rVzB.mjs +334 -0
- package/dist/_chunks/index-DdX2rVzB.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +2 -1
- package/dist/admin/index.mjs.map +1 -0
- package/dist/server/index.js +3 -2
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +3 -2
- package/dist/server/index.mjs.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { PuzzlePiece } from "@strapi/icons";
|
|
3
|
+
import { getFetchClient, unstable_useContentManagerContext } from "@strapi/strapi/admin";
|
|
4
|
+
import { useState, useEffect } from "react";
|
|
5
|
+
import { Box, Loader, Divider, Flex, Typography, CardBadge } from "@strapi/design-system";
|
|
6
|
+
import { useIntl } from "react-intl";
|
|
7
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
8
|
+
const v = glob[path];
|
|
9
|
+
if (v) {
|
|
10
|
+
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
11
|
+
}
|
|
12
|
+
return new Promise((_, reject) => {
|
|
13
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
14
|
+
reject.bind(
|
|
15
|
+
null,
|
|
16
|
+
new Error(
|
|
17
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
const name$1 = "multi-content-type-relation";
|
|
24
|
+
const strapi = {
|
|
25
|
+
name: "multi-content-type-relation"
|
|
26
|
+
};
|
|
27
|
+
const pluginPkg = {
|
|
28
|
+
name: name$1,
|
|
29
|
+
strapi
|
|
30
|
+
};
|
|
31
|
+
const PluginIcon = () => /* @__PURE__ */ jsx(PuzzlePiece, {});
|
|
32
|
+
const pluginId = pluginPkg.name.replace(
|
|
33
|
+
/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i,
|
|
34
|
+
""
|
|
35
|
+
);
|
|
36
|
+
const fetchMatchingContent = async (keyword, contentTypes, locale) => {
|
|
37
|
+
const { post } = getFetchClient();
|
|
38
|
+
const response = await post(`/${pluginId}/get-content`, {
|
|
39
|
+
contentTypes: contentTypes.split(","),
|
|
40
|
+
keyword,
|
|
41
|
+
locale
|
|
42
|
+
});
|
|
43
|
+
const data = response.data;
|
|
44
|
+
if (!data) throw new Error("No data returned from API");
|
|
45
|
+
const total = data.reduce((accumulator, option) => {
|
|
46
|
+
if (!option.results) return accumulator;
|
|
47
|
+
return accumulator + option.results.length;
|
|
48
|
+
}, 0);
|
|
49
|
+
return {
|
|
50
|
+
data,
|
|
51
|
+
total
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
const formatToStrapiField = (entries) => {
|
|
55
|
+
if (entries.length === 0) return "";
|
|
56
|
+
return JSON.stringify(
|
|
57
|
+
entries.map((entry) => ({
|
|
58
|
+
uid: entry.uid,
|
|
59
|
+
documentId: entry.item.documentId,
|
|
60
|
+
MRCT: true
|
|
61
|
+
})).filter(Boolean)
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
const validateCurrentRelations = async (entries) => {
|
|
65
|
+
const { post } = getFetchClient();
|
|
66
|
+
const response = await post(`/${pluginId}/validate-relations`, {
|
|
67
|
+
entries
|
|
68
|
+
});
|
|
69
|
+
return response.data;
|
|
70
|
+
};
|
|
71
|
+
const listContentTypes = async () => {
|
|
72
|
+
try {
|
|
73
|
+
const { get } = getFetchClient();
|
|
74
|
+
const response = await get(`/${pluginId}/list-content-types`);
|
|
75
|
+
return response.data;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error(error);
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const STORAGE_KEY = "mctr::content_types";
|
|
82
|
+
function getContentTypes() {
|
|
83
|
+
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
84
|
+
return raw ? JSON.parse(raw) : void 0;
|
|
85
|
+
}
|
|
86
|
+
function getContentTypeForUid(uid) {
|
|
87
|
+
const contentTypes = getContentTypes();
|
|
88
|
+
if (!Array.isArray(contentTypes)) return;
|
|
89
|
+
return contentTypes.find((contentType) => contentType.uid === uid);
|
|
90
|
+
}
|
|
91
|
+
function setContentTypes(contentTypes) {
|
|
92
|
+
const stringified = JSON.stringify(contentTypes);
|
|
93
|
+
sessionStorage.setItem(STORAGE_KEY, stringified);
|
|
94
|
+
}
|
|
95
|
+
const useTranslate = () => {
|
|
96
|
+
const { formatMessage } = useIntl();
|
|
97
|
+
const translate = (key, values) => {
|
|
98
|
+
return formatMessage({ id: key }, values);
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
translate
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
const SidePanel = () => {
|
|
105
|
+
const { translate } = useTranslate();
|
|
106
|
+
const {
|
|
107
|
+
id: documentId,
|
|
108
|
+
model: uid,
|
|
109
|
+
isSingleType
|
|
110
|
+
} = unstable_useContentManagerContext();
|
|
111
|
+
const [linkedContent, setLinkedContent] = useState([]);
|
|
112
|
+
const [loading, setLoading] = useState(false);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
const fetchRevertRelations = async () => {
|
|
115
|
+
const { post } = getFetchClient();
|
|
116
|
+
const response = await post(`/${pluginId}/fetch-revert-relations`, {
|
|
117
|
+
documentId,
|
|
118
|
+
uid,
|
|
119
|
+
isSingleType
|
|
120
|
+
});
|
|
121
|
+
setLinkedContent(Array.isArray(response.data) ? response.data.filter(Boolean) : []);
|
|
122
|
+
setLoading(false);
|
|
123
|
+
};
|
|
124
|
+
fetchRevertRelations();
|
|
125
|
+
}, []);
|
|
126
|
+
if (loading)
|
|
127
|
+
return /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(Loader, {}) });
|
|
128
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
129
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
130
|
+
/* @__PURE__ */ jsxs(Box, { width: "100%", marginTop: 4, children: [
|
|
131
|
+
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
|
132
|
+
Typography,
|
|
133
|
+
{
|
|
134
|
+
variant: "sigma",
|
|
135
|
+
fontWeight: "bold",
|
|
136
|
+
textTransform: "uppercase",
|
|
137
|
+
marginBottom: 1,
|
|
138
|
+
textColor: "neutral600",
|
|
139
|
+
children: translate("sidePanel.linkedContent")
|
|
140
|
+
}
|
|
141
|
+
) }),
|
|
142
|
+
linkedContent.length > 0 ? /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsxs(Typography, { variant: "omega", textColor: "neutral600", marginBottom: 3, children: [
|
|
143
|
+
translate("sidePanel.referencedIn"),
|
|
144
|
+
" ",
|
|
145
|
+
linkedContent.length,
|
|
146
|
+
" ",
|
|
147
|
+
translate("sidePanel.otherContents")
|
|
148
|
+
] }) }) : /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", marginBottom: 3, children: translate("sidePanel.notReferenced") }) }),
|
|
149
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 2, children: linkedContent.map((content, idx) => /* @__PURE__ */ jsxs(
|
|
150
|
+
Box,
|
|
151
|
+
{
|
|
152
|
+
marginBottom: idx < linkedContent.length - 1 ? 3 : 0,
|
|
153
|
+
children: [
|
|
154
|
+
/* @__PURE__ */ jsxs(
|
|
155
|
+
Flex,
|
|
156
|
+
{
|
|
157
|
+
direction: "row",
|
|
158
|
+
justifyContent: "space-between",
|
|
159
|
+
alignItems: "flex-start",
|
|
160
|
+
paddingY: 2,
|
|
161
|
+
paddingX: 3,
|
|
162
|
+
children: [
|
|
163
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
164
|
+
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
|
|
165
|
+
"a",
|
|
166
|
+
{
|
|
167
|
+
href: content.isSingleType ? `/admin/content-manager/single-types/${content.uid}` : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`,
|
|
168
|
+
target: "_blank",
|
|
169
|
+
style: { textDecoration: "none" },
|
|
170
|
+
children: /* @__PURE__ */ jsx(
|
|
171
|
+
Typography,
|
|
172
|
+
{
|
|
173
|
+
children: content.title ?? content.documentId
|
|
174
|
+
}
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
) }),
|
|
178
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(
|
|
179
|
+
Typography,
|
|
180
|
+
{
|
|
181
|
+
variant: "pi",
|
|
182
|
+
textColor: "neutral600",
|
|
183
|
+
style: { lineHeight: 1.2 },
|
|
184
|
+
children: [
|
|
185
|
+
translate("sidePanel.field"),
|
|
186
|
+
" ",
|
|
187
|
+
content.field
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
) })
|
|
191
|
+
] }),
|
|
192
|
+
/* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(CardBadge, { children: content.type }) })
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
),
|
|
196
|
+
idx < linkedContent.length - 1 && /* @__PURE__ */ jsx(Box, { marginY: 1, children: /* @__PURE__ */ jsx(Divider, {}) })
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
content.documentId
|
|
200
|
+
)) })
|
|
201
|
+
] })
|
|
202
|
+
] });
|
|
203
|
+
};
|
|
204
|
+
const name = pluginPkg.strapi.name;
|
|
205
|
+
const index = {
|
|
206
|
+
async register(app) {
|
|
207
|
+
const contentTypes = await listContentTypes();
|
|
208
|
+
setContentTypes(contentTypes);
|
|
209
|
+
app.customFields.register({
|
|
210
|
+
name,
|
|
211
|
+
pluginId,
|
|
212
|
+
type: "richtext",
|
|
213
|
+
intlLabel: {
|
|
214
|
+
id: "multi-content-type-relation.text-ai.label",
|
|
215
|
+
defaultMessage: "Multi Content Type Relation"
|
|
216
|
+
},
|
|
217
|
+
intlDescription: {
|
|
218
|
+
id: "multi-content-type-relation.text-ai.description",
|
|
219
|
+
defaultMessage: "Write content types separated by commas"
|
|
220
|
+
},
|
|
221
|
+
icon: PluginIcon,
|
|
222
|
+
// don't forget to create/import your icon component
|
|
223
|
+
components: {
|
|
224
|
+
Input: () => import(
|
|
225
|
+
/* webpackChunkName: "input-component" */
|
|
226
|
+
"./index-DGcImy9s.mjs"
|
|
227
|
+
)
|
|
228
|
+
},
|
|
229
|
+
inputSize: {
|
|
230
|
+
default: 12,
|
|
231
|
+
isResizable: false
|
|
232
|
+
},
|
|
233
|
+
options: {
|
|
234
|
+
base: [
|
|
235
|
+
/*
|
|
236
|
+
Declare settings to be added to the "Base settings" section
|
|
237
|
+
of the field in the Content-Type Builder
|
|
238
|
+
*/
|
|
239
|
+
{
|
|
240
|
+
sectionTitle: {
|
|
241
|
+
id: "multi-content-type-relation.text-ai.length",
|
|
242
|
+
defaultMessage: "Content types"
|
|
243
|
+
},
|
|
244
|
+
items: contentTypes.map((contentType) => {
|
|
245
|
+
const value = contentType.info.singularName;
|
|
246
|
+
return {
|
|
247
|
+
intlLabel: {
|
|
248
|
+
id: `multi-content-type-relation.options.${contentType.uid}`,
|
|
249
|
+
defaultMessage: contentType.info.displayName
|
|
250
|
+
},
|
|
251
|
+
type: "checkbox",
|
|
252
|
+
name: `options.contentTypes.${value}`
|
|
253
|
+
};
|
|
254
|
+
})
|
|
255
|
+
}
|
|
256
|
+
],
|
|
257
|
+
advanced: [
|
|
258
|
+
{
|
|
259
|
+
sectionTitle: {
|
|
260
|
+
id: "global.settings",
|
|
261
|
+
defaultMessage: "Settings"
|
|
262
|
+
},
|
|
263
|
+
items: [
|
|
264
|
+
{
|
|
265
|
+
name: "required",
|
|
266
|
+
type: "checkbox",
|
|
267
|
+
intlLabel: {
|
|
268
|
+
id: "content-type-relation-select.options.advanced.requiredField",
|
|
269
|
+
defaultMessage: "Required field"
|
|
270
|
+
},
|
|
271
|
+
description: {
|
|
272
|
+
id: "content-type-relation-select.options.advanced.requiredField.description",
|
|
273
|
+
defaultMessage: "You won't be able to create an entry if this field is empty"
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: "options.min",
|
|
278
|
+
type: "number",
|
|
279
|
+
intlLabel: {
|
|
280
|
+
id: "content-type-relation-select.options.advanced.minField",
|
|
281
|
+
defaultMessage: "Minimum values"
|
|
282
|
+
},
|
|
283
|
+
description: {
|
|
284
|
+
id: "content-type-relation-select.options.advanced.minField.description",
|
|
285
|
+
defaultMessage: "Minimum number of entries"
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "options.max",
|
|
290
|
+
type: "number",
|
|
291
|
+
intlLabel: {
|
|
292
|
+
id: "content-type-relation-select.options.advanced.maxField",
|
|
293
|
+
defaultMessage: "Maximum values"
|
|
294
|
+
},
|
|
295
|
+
description: {
|
|
296
|
+
id: "content-type-relation-select.options.advanced.maxField.description",
|
|
297
|
+
defaultMessage: "Maximum number of entries"
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
},
|
|
306
|
+
bootstrap(app) {
|
|
307
|
+
app.getPlugin("content-manager").injectComponent("editView", "right-links", {
|
|
308
|
+
name: "side-panel",
|
|
309
|
+
Component: SidePanel
|
|
310
|
+
});
|
|
311
|
+
},
|
|
312
|
+
async registerTrads(app) {
|
|
313
|
+
const { locales } = app;
|
|
314
|
+
const importedTrads = await Promise.all(
|
|
315
|
+
locales.map(async (locale) => {
|
|
316
|
+
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-Cj4T04Z2.mjs"), "./translations/fr.json": () => import("./fr-KHPiQOFP.mjs") }), `./translations/${locale}.json`, 3);
|
|
317
|
+
return {
|
|
318
|
+
data,
|
|
319
|
+
locale
|
|
320
|
+
};
|
|
321
|
+
})
|
|
322
|
+
);
|
|
323
|
+
return Promise.resolve(importedTrads);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
export {
|
|
327
|
+
formatToStrapiField as a,
|
|
328
|
+
fetchMatchingContent as f,
|
|
329
|
+
getContentTypeForUid as g,
|
|
330
|
+
index as i,
|
|
331
|
+
useTranslate as u,
|
|
332
|
+
validateCurrentRelations as v
|
|
333
|
+
};
|
|
334
|
+
//# sourceMappingURL=index-DdX2rVzB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-DdX2rVzB.mjs","sources":["../../admin/src/components/PluginIcon/index.tsx","../../admin/src/pluginId.ts","../../admin/src/helpers/content.ts","../../admin/src/helpers/storage.ts","../../admin/src/hooks/useTranslate.ts","../../admin/src/components/SidePanel/SidePanel.tsx","../../admin/src/index.ts"],"sourcesContent":["import { PuzzlePiece } from '@strapi/icons';\n\nconst PluginIcon = () => <PuzzlePiece />;\n\nexport default PluginIcon;\n","import pluginPkg from '../../package.json';\n\nconst pluginId = pluginPkg.name.replace(\n /^(@[^-,.][\\w,-]+\\/|strapi-)plugin-/i,\n ''\n);\n\nexport default pluginId;\n","import { getFetchClient } from '@strapi/strapi/admin';\n\nimport pluginId from '../pluginId';\nimport {\n FormattedStrapiEntry,\n MatchingContent,\n MatchingContentResponse,\n SelectedEntry,\n} from '../interface';\n\nexport const fetchMatchingContent = async (\n keyword: string,\n contentTypes: string,\n locale: string\n): Promise<MatchingContentResponse> => {\n const { post } = getFetchClient();\n const response = await post(`/${pluginId}/get-content`, {\n contentTypes: contentTypes.split(','),\n keyword,\n locale,\n });\n\n const data = response.data as MatchingContent[];\n\n if (!data) throw new Error('No data returned from API');\n\n const total = data.reduce((accumulator, option) => {\n if (!option.results) return accumulator;\n\n return accumulator + option.results.length;\n }, 0);\n\n return {\n data,\n total,\n };\n};\n\nexport const formatToStrapiField = (entries: SelectedEntry[]) => {\n if (entries.length === 0) return '';\n\n return JSON.stringify(\n entries\n .map((entry) => ({\n uid: entry.uid,\n documentId: entry.item.documentId,\n MRCT: true,\n }))\n .filter(Boolean)\n );\n};\n\nexport const validateCurrentRelations = async (\n entries: FormattedStrapiEntry[]\n) => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/validate-relations`, {\n entries,\n });\n\n return response.data as SelectedEntry[];\n};\n\nexport const listContentTypes = async () => {\n try {\n const { get } = getFetchClient();\n const response = await get(`/${pluginId}/list-content-types`);\n\n return response.data;\n } catch (error) {\n console.error(error);\n return [];\n }\n};\n","export type LightContentType = {\n apiName: string;\n attributes: Record<string, Record<string, unknown>>[];\n collectionName: string;\n globalId: string;\n modelName: string;\n modelType: string;\n options?: { draftAndPublish?: boolean };\n uid: string;\n};\n\nconst STORAGE_KEY = 'mctr::content_types';\n\nexport function getContentTypes() {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as LightContentType[]) : undefined;\n}\n\nexport function getContentTypeForUid(uid: string) {\n const contentTypes = getContentTypes();\n\n if (!Array.isArray(contentTypes)) return;\n\n return contentTypes.find((contentType) => contentType.uid === uid);\n}\n\nexport function setContentTypes(contentTypes: LightContentType[]) {\n const stringified = JSON.stringify(contentTypes);\n\n sessionStorage.setItem(STORAGE_KEY, stringified);\n}\n","import { useIntl } from 'react-intl';\n\nconst useTranslate = () => {\n const { formatMessage } = useIntl();\n\n const translate = (key: string, values?: Record<string, any>) => {\n return formatMessage({ id: key }, values);\n };\n\n return {\n translate\n };\n};\n\nexport default useTranslate;\n","import React, { useEffect, useState } from 'react';\nimport {\n Box,\n Typography,\n Card,\n CardBody,\n Flex,\n Divider\n} from '@strapi/design-system';\nimport { CardTitle, CardContent, CardBadge } from '@strapi/design-system';\nimport { getFetchClient } from '@strapi/strapi/admin';\nimport pluginId from '../../pluginId';\nimport { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport { Loader } from '@strapi/design-system';\nimport useTranslate from '../../hooks/useTranslate';\n\ninterface LinkedContent {\n documentId: string;\n title: string;\n type: string;\n uid: string;\n field: string;\n isSingleType: boolean;\n}\n\ninterface SidePanelProps {\n contentType?: string;\n contentId?: string;\n}\n\nconst SidePanel: React.FC<SidePanelProps> = () => {\n const { translate } = useTranslate();\n const {\n id: documentId,\n model: uid,\n isSingleType\n } = useContentManagerContext();\n\n const [linkedContent, setLinkedContent] = useState<LinkedContent[]>([]);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n const fetchRevertRelations = async () => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/fetch-revert-relations`, {\n documentId,\n uid,\n isSingleType\n });\n\n setLinkedContent(Array.isArray(response.data) ? response.data.filter(Boolean) : []);\n setLoading(false);\n };\n\n fetchRevertRelations();\n }, []);\n\n if (loading)\n return (\n <Box width=\"100%\">\n <Loader />\n </Box>\n );\n\n return (\n <>\n <Divider />\n <Box width=\"100%\" marginTop={4}>\n <Flex>\n <Typography\n variant=\"sigma\"\n fontWeight=\"bold\"\n textTransform=\"uppercase\"\n marginBottom={1}\n textColor=\"neutral600\"\n >\n {translate('sidePanel.linkedContent')}\n </Typography>\n </Flex>\n\n {linkedContent.length > 0 ? (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.referencedIn')} {linkedContent.length}{' '}\n {translate('sidePanel.otherContents')}\n </Typography>\n </Flex>\n ) : (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.notReferenced')}\n </Typography>\n </Flex>\n )}\n\n <Box marginTop={2}>\n {linkedContent.map((content, idx) => (\n <Box\n key={content.documentId}\n marginBottom={idx < linkedContent.length - 1 ? 3 : 0}\n >\n <Flex\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"flex-start\"\n paddingY={2}\n paddingX={3}\n >\n <Box>\n <Box>\n <a\n href={\n content.isSingleType\n ? `/admin/content-manager/single-types/${content.uid}`\n : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`\n }\n target=\"_blank\"\n style={{ textDecoration: 'none' }}\n >\n <Typography\n >\n {content.title ?? content.documentId}\n </Typography>\n </a>\n </Box>\n <Box marginTop={1}>\n <Typography\n variant=\"pi\"\n textColor=\"neutral600\"\n style={{ lineHeight: 1.2 }}\n >\n {translate('sidePanel.field')} {content.field}\n </Typography>\n </Box>\n </Box>\n <Box marginLeft={2}>\n <CardBadge>{content.type}</CardBadge>\n </Box>\n </Flex>\n {idx < linkedContent.length - 1 && (\n <Box marginY={1}>\n <Divider />\n </Box>\n )}\n </Box>\n ))}\n </Box>\n </Box>\n </>\n );\n};\n\nexport default SidePanel;\n","import React, { ComponentType } from 'react';\n\nimport pluginPkg from '../../package.json';\n\nimport PluginIcon from './components/PluginIcon';\nimport pluginId from './pluginId';\nimport { listContentTypes } from './helpers/content';\nimport { setContentTypes } from './helpers/storage';\nimport SidePanel from './components/SidePanel/SidePanel';\n\nconst name = pluginPkg.strapi.name;\n\nexport default {\n async register(app: any) {\n const contentTypes = await listContentTypes();\n setContentTypes(contentTypes);\n\n app.customFields.register({\n name,\n pluginId,\n type: 'richtext',\n intlLabel: {\n id: 'multi-content-type-relation.text-ai.label',\n defaultMessage: 'Multi Content Type Relation'\n },\n intlDescription: {\n id: 'multi-content-type-relation.text-ai.description',\n defaultMessage: 'Write content types separated by commas'\n },\n icon: PluginIcon, // don't forget to create/import your icon component\n components: {\n Input: () =>\n import(\n /* webpackChunkName: \"input-component\" */ './components/Input'\n ) as unknown as ComponentType\n },\n inputSize: {\n default: 12,\n isResizable: false\n },\n options: {\n base: [\n /*\n Declare settings to be added to the \"Base settings\" section\n of the field in the Content-Type Builder\n */\n {\n sectionTitle: {\n id: 'multi-content-type-relation.text-ai.length',\n defaultMessage: 'Content types'\n },\n items: contentTypes.map((contentType: any) => {\n const value = contentType.info.singularName;\n\n return {\n intlLabel: {\n id: `multi-content-type-relation.options.${contentType.uid}`,\n defaultMessage: contentType.info.displayName\n },\n type: 'checkbox',\n name: `options.contentTypes.${value}`\n };\n })\n }\n ],\n advanced: [\n {\n sectionTitle: {\n id: 'global.settings',\n defaultMessage: 'Settings'\n },\n items: [\n {\n name: 'required',\n type: 'checkbox',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.requiredField',\n defaultMessage: 'Required field'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.requiredField.description',\n defaultMessage:\n \"You won't be able to create an entry if this field is empty\"\n }\n },\n {\n name: 'options.min',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.minField',\n defaultMessage: 'Minimum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.minField.description',\n defaultMessage: 'Minimum number of entries'\n }\n },\n {\n name: 'options.max',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.maxField',\n defaultMessage: 'Maximum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.maxField.description',\n defaultMessage: 'Maximum number of entries'\n }\n }\n ]\n }\n ]\n }\n });\n },\n\n bootstrap(app: any) {\n app\n .getPlugin('content-manager')\n .injectComponent('editView', 'right-links', {\n name: 'side-panel',\n Component: SidePanel\n });\n },\n\n async registerTrads(app: any) {\n const { locales } = app;\n\n const importedTrads = await Promise.all(\n (locales as any[]).map(async (locale) => {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return {\n data,\n locale\n };\n })\n );\n\n return Promise.resolve(importedTrads);\n }\n};\n"],"names":["useContentManagerContext"],"mappings":"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"}
|
package/dist/admin/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/dist/admin/index.mjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
package/dist/server/index.js
CHANGED
|
@@ -169,7 +169,7 @@ const hydrateMRCT = async (content, currentDepth, context) => {
|
|
|
169
169
|
(linkedEntry) => item.uid === linkedEntry.uid && item.documentId === linkedEntry.response.documentId
|
|
170
170
|
);
|
|
171
171
|
if (matchingContent) {
|
|
172
|
-
hydratedArray.push(matchingContent.response);
|
|
172
|
+
hydratedArray.push({ uid: matchingContent.uid, ...matchingContent.response });
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
flattenedProperties[key] = hydratedArray;
|
|
@@ -440,7 +440,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
440
440
|
};
|
|
441
441
|
})
|
|
442
442
|
);
|
|
443
|
-
return relations;
|
|
443
|
+
return relations.filter(Boolean);
|
|
444
444
|
}
|
|
445
445
|
});
|
|
446
446
|
const controllers = {
|
|
@@ -506,3 +506,4 @@ const index = {
|
|
|
506
506
|
middlewares
|
|
507
507
|
};
|
|
508
508
|
module.exports = index;
|
|
509
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../server/src/bootstrap.ts","../../server/src/destroy.ts","../../server/src/utils.ts","../../server/src/helpers/index.ts","../../server/src/middlewares/middleware.ts","../../server/src/middlewares/index.ts","../../server/src/register.ts","../../server/src/config/index.ts","../../server/src/content-types/mctr-relation/schema.ts","../../server/src/content-types/mctr-relation/index.ts","../../server/src/content-types/index.ts","../../server/src/controllers/controller.ts","../../server/src/controllers/index.ts","../../server/src/policies/index.ts","../../server/src/routes/index.ts","../../server/src/services/service.ts","../../server/src/services/index.ts","../../server/src/index.ts"],"sourcesContent":["import type { Core } from '@strapi/strapi';\n\nconst bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {};\nexport default bootstrap;\n","import type { Core } from '@strapi/strapi';\n\nconst destroy = ({ strapi }: { strapi: Core.Strapi }) => {\n // destroy phase\n};\n\nexport default destroy;\n","import { Configuration } from './interface';\n\nexport const getPluginConfiguration = (): Configuration => {\n const pluginConfiguration = strapi.config.get(\n 'plugin::multi-content-type-relation'\n ) as Configuration;\n\n return pluginConfiguration;\n};\nexport const log = (message: string) => {\n const { debug } = getPluginConfiguration();\n\n if (debug) {\n console.log(`[MCTR DEBUG] ${message}`);\n }\n};\n","export const flattenObj = (\n obj: any,\n parent: any,\n res: Record<string, any> = {}\n) => {\n for (let key in obj) {\n let propName = parent ? parent + '.' + key : key;\n if (typeof obj[key] == 'object') {\n flattenObj(obj[key], propName, res);\n } else {\n res[propName] = obj[key];\n }\n }\n return res;\n};\n\nexport const unflatten = (data: any) => {\n var result = {};\n for (var i in data) {\n var keys = i.split('.');\n keys.reduce(function (r: any, e, j) {\n return (\n r[e] ||\n (r[e] = isNaN(Number(keys[j + 1]))\n ? keys.length - 1 == j\n ? data[i]\n : {}\n : [])\n );\n }, result);\n }\n return result;\n};\n","import { getPluginConfiguration, log } from '../utils';\nimport type { Context, StrapiResponse, AnyEntity } from '../interface';\nimport { flattenObj, unflatten } from '../helpers';\nimport type { UID } from '@strapi/strapi';\n\nexport default async (ctx, next) => {\n await next();\n\n if (!ctx.body) return;\n if (!ctx.body.data) return;\n\n if (\n [\n 'collection-types.create',\n 'collection-types.update',\n 'single-types.createOrUpdate'\n ].includes(ctx?.state?.route?.handler)\n ) {\n const [, _, __, rest] = ctx?.request.url.split('/');\n const contentType = rest.split('?')[0];\n\n const isDraftAndPublish =\n strapi.contentTypes[contentType].options?.draftAndPublish;\n\n // We want to update relation only on publish for those who have it activated\n if (isDraftAndPublish) {\n log(`[MIDDLEWARE] ${contentType}is draft and publish`);\n return;\n }\n\n const documentId = ctx.body.data.documentId;\n syncMctrRelation(documentId, contentType as UID.ContentType);\n }\n\n if (\n ['collection-types.publish', 'single-types.publish'].includes(\n ctx?.state?.route?.handler\n )\n ) {\n const [, _, __, rest] = ctx?.request.url.split('/');\n const contentType = rest.split('?')[0];\n\n const documentId = ctx.body.data.documentId;\n syncMctrRelation(documentId, contentType as UID.ContentType);\n }\n\n // Only on specific handlerswith public API we want to hydrate the MCTR relation\n if (!ctx?.request?.url?.startsWith('/api')) return;\n if (ctx.request.method !== 'GET') return;\n if (!ctx.body) return;\n\n const configuration = getPluginConfiguration();\n\n const handler = ctx.state.route.handler;\n const contentTypes = Object.keys(strapi.contentTypes);\n\n log(`[MIDDLEWARE] URL: ${ctx.request.url} (${ctx.request.method})`);\n log(`[MIDDLEWARE] Strapi Route: ${JSON.stringify(ctx.state.route, null, 2)}`);\n\n if (typeof handler !== 'string') return;\n\n const validHandler = contentTypes\n .filter((contentType) => contentType.startsWith('api::'))\n .some(\n (contentType) =>\n handler.includes(`${contentType}.findOne`) ||\n handler.includes(`${contentType}.findMany`) ||\n handler.includes(`${contentType}.find`)\n );\n\n log(`[MIDDLEWARE] Is valid handler: ${validHandler}`);\n\n // Allow only findOne/findMany for native contentypes that have api::\n if (!validHandler) return;\n\n const context = {\n configuration,\n publicationState: ctx.request.query?.['publicationState'] ?? 'live'\n };\n\n log(`[MIDDLEWARE] Context Body: ${JSON.stringify(ctx.body, null, 2)}`);\n if (ctx.body.error || !ctx.body?.data) return;\n\n const hydratedData = await augmentMRCT(ctx.body, 1, context);\n\n ctx.body.data = hydratedData;\n};\n\nconst augmentMRCT = async (\n strapiResponse: StrapiResponse,\n currentDepth: number,\n context: Context\n): Promise<AnyEntity | AnyEntity[]> => {\n if (Array.isArray(strapiResponse.data)) {\n const promises = strapiResponse.data.map((item) =>\n hydrateMRCT(item, currentDepth, context)\n );\n\n return await Promise.all(promises);\n } else {\n return await hydrateMRCT(strapiResponse.data, currentDepth, context);\n }\n};\n\nconst hydrateMRCT = async (\n content: AnyEntity,\n currentDepth: number,\n context: Context\n) => {\n const eligibleProperties: Set<string> = new Set();\n const contentsToFetch: Set<string> = new Set();\n\n const { configuration } = context;\n\n const flattenedProperties = flattenObj(content, null);\n\n for (const [key, value] of Object.entries(flattenedProperties)) {\n if (typeof value !== 'string' || !value.includes('MRCT')) continue;\n\n try {\n const field = JSON.parse(value);\n\n if (!Array.isArray(field)) continue;\n\n for (const item of field) {\n if (\n Object.keys(item).length !== 3 ||\n (!item.uid && typeof item.uid !== 'string') ||\n !item.documentId\n )\n continue;\n\n const compositeID = `${item.uid}####${item.documentId}`;\n\n eligibleProperties.add(key);\n\n if (contentsToFetch.has(compositeID)) continue;\n else contentsToFetch.add(compositeID);\n }\n } catch (e) {\n continue;\n }\n }\n\n if (!contentsToFetch.size) return content;\n\n log(\n `[MCTR HYDRATOR] Depth: ${currentDepth}, Hydrating MCTR for ID ${content.id}`\n );\n\n const promises: Promise<any>[] = [];\n for (const item of Array.from(contentsToFetch)) {\n const [uid, documentId] = item.split('####');\n const promise = strapi\n .documents(uid as any)\n .findOne({ documentId, populate: '*', status: 'published' })\n .then(async (response) => {\n if (!response) return { uid, response };\n\n if (\n configuration.recursive.enabled &&\n currentDepth < configuration.recursive.maxDepth\n ) {\n // Entity service serve the content flattened, so we need to rebuild the API format for the hydrate recursion\n const hydratedResponse = await hydrateMRCT(\n response as unknown as AnyEntity, //TODO: fix me\n currentDepth + 1,\n context\n );\n\n return {\n uid,\n response: {\n documentId: response.documentId,\n ...hydratedResponse\n }\n };\n } else {\n return {\n uid,\n response: {\n documentId: response.documentId,\n ...response\n }\n };\n }\n });\n\n promises.push(promise);\n }\n\n const linkedEntries: any[] = await Promise.all(promises);\n\n const filteredLinkedEntries: { uid: string; response: AnyEntity }[] =\n linkedEntries\n .filter((linkedEntry) => Boolean(linkedEntry.response))\n .filter((linkedEntry) => {\n const contentTypeConfiguration = strapi.contentTypes[linkedEntry.uid];\n\n if (!contentTypeConfiguration) return true;\n if (!contentTypeConfiguration.options?.draftAndPublish) return true;\n if (context.publicationState === 'preview') return true;\n\n return typeof linkedEntry.response?.publishedAt === 'string';\n });\n\n for (const key of Array.from(eligibleProperties)) {\n const hydratedArray: AnyEntity[] = [];\n\n const unhydratedField = JSON.parse(flattenedProperties[key]) as {\n uid: string;\n documentId: string;\n }[];\n\n for (const item of unhydratedField) {\n const matchingContent = filteredLinkedEntries.find(\n (linkedEntry) =>\n item.uid === linkedEntry.uid &&\n item.documentId === linkedEntry.response.documentId\n );\n\n if (matchingContent) {\n hydratedArray.push({ uid: matchingContent.uid, ...matchingContent.response });\n }\n }\n\n flattenedProperties[key] = hydratedArray;\n }\n\n const newContent = unflatten(flattenedProperties);\n return {\n ...content,\n ...newContent\n };\n};\n\nconst syncMctrRelation = async (documentId: string, uid: UID.ContentType) => {\n const mctrDocuments = await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .findMany({\n filters: {\n sourceDocId: documentId\n }\n });\n\n if (mctrDocuments.length !== 0) {\n log(`[SYNC] Delete MCTR relations for ${documentId}`);\n // delete the mctr relation\n await Promise.all(\n mctrDocuments.map(async ({ documentId }) => {\n await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .delete({\n documentId\n });\n })\n );\n }\n\n log(`[SYNC] Find document ${documentId}`);\n const document = await strapi.documents(uid).findOne({\n documentId\n });\n\n // Explore document to find the mctr relation\n const contentTypeKey = Object.keys(strapi.contentTypes).find(\n (ct) => strapi.contentTypes[ct].uid === uid\n );\n\n if (!contentTypeKey) return;\n\n const contentType = strapi.contentTypes[contentTypeKey];\n\n // TODO: recursive find the mctr relation\n const mctrFields = Object.keys(contentType.attributes).filter(\n (field) =>\n contentType.attributes[field].customField ===\n 'plugin::multi-content-type-relation.multi-content-type-relation'\n );\n\n if (mctrFields.length === 0) return;\n\n const targetJSON = [];\n\n // Create the mctr relation to have a sync\n mctrFields.forEach(async (field) => {\n const fieldValue = document[field];\n if (!fieldValue) return;\n\n try {\n const mctrField = JSON.parse(fieldValue);\n mctrField.forEach((item) => {\n targetJSON.push(`${field}##${item.uid}##${item.documentId}`);\n });\n } catch (e) {\n log(`[SYNC] Error parsing field ${field} ${fieldValue}`);\n }\n });\n\n log(`[SYNC] Target JSON ${targetJSON}`);\n if (targetJSON.length === 0) return;\n\n await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .create({\n data: {\n sourceUID: uid,\n sourceDocId: documentId,\n target: targetJSON\n }\n });\n\n log(`[SYNC] MCTR relation created for ${documentId}`);\n};\n","import middleware from './middleware';\n\nexport default {\n middleware,\n};\n","import middlewares from './middlewares';\n\nimport type { Core } from '@strapi/strapi';\n\nconst register = ({ strapi }: { strapi: Core.Strapi }) => {\n // register phase\n strapi.customFields.register({\n name: 'multi-content-type-relation',\n plugin: 'multi-content-type-relation',\n type: 'richtext'\n });\n\n strapi.server.use(middlewares.middleware);\n};\n\nexport default register;\n","export default {\n default: ({ env }) => {\n return {\n recursive: {\n enabled: false,\n maxDepth: 1,\n },\n debug: false,\n };\n },\n validator(config) {\n if (typeof config.recursive !== 'object') {\n throw new Error('recursive must be an object');\n }\n\n if (typeof config.recursive.enabled !== 'boolean') {\n throw new Error('recursive.enabled must be a boolean');\n }\n\n if (typeof config.recursive.maxDepth !== 'number') {\n throw new Error('recursive.maxDepth must be a number');\n }\n\n if (typeof config.debug !== 'boolean') {\n throw new Error('Debug must be a boolean');\n }\n },\n};\n","export default {\n collectionName: 'mctr-relation',\n info: {\n singularName: 'mctr-relation',\n pluralName: 'mctr-relations',\n displayName: 'MCTR Relation',\n name: 'mctr-relation'\n },\n pluginOptions: {\n 'content-manager': {\n visible: false\n },\n 'content-type-builder': {\n visible: false\n }\n },\n attributes: {\n sourceUID: {\n type: 'string',\n required: true\n },\n sourceDocId: {\n type: 'string',\n required: true\n },\n target: {\n type: 'json'\n }\n }\n};\n","'use strict';\n\nimport schema from './schema';\n\nexport default {\n schema\n};\n","import mctrRelation from './mctr-relation';\n\nexport default {\n 'mctr-relation': mctrRelation\n};\n","import type { Core, UID } from '@strapi/strapi';\nimport { FormattedStrapiEntry } from '../interface';\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n getMatchingContent(ctx) {\n const contentTypes = strapi.contentTypes;\n const body = ctx.request.body;\n\n const requestedContentTypes = body.contentTypes as string[];\n const keyword = body.keyword as string;\n const locale = body.locale as string;\n\n const mapping = requestedContentTypes.reduce(\n (accumulator, contentType) => {\n Object.keys(contentTypes).forEach((model) => {\n const strapiContentType = contentTypes[model];\n if (\n strapiContentType.info.singularName === contentType ||\n strapiContentType.info.pluralName === contentType\n ) {\n accumulator[contentType] = {\n uid: model as UID.ContentType,\n displayName: contentTypes[model].info.displayName,\n searchableField: strapi\n .plugin('multi-content-type-relation')\n .service('service')\n .getFirstStringFieldInContentType(contentTypes[model])\n };\n }\n });\n\n return accumulator;\n },\n {} as Record<\n string,\n { uid: UID.ContentType; displayName: string; searchableField: string }\n >\n );\n\n const promises = Object.keys(mapping).map((contentType) => {\n const uid = mapping[contentType].uid;\n\n return strapi\n .documents(uid)\n .findMany({\n filters: {\n [mapping[contentType].searchableField]: {\n $containsi: keyword\n }\n },\n locale,\n status: 'published'\n })\n .then((results) => {\n let contents = Array.isArray(results)\n ? results\n : typeof results === 'object' && results\n ? [results]\n : [];\n\n const contentTypeDefinition = strapi.contentType(uid);\n if (contentTypeDefinition?.options?.draftAndPublish) {\n contents = contents.filter(\n (content) => content.publishedAt !== null\n );\n }\n\n return {\n uid,\n displayName: mapping[contentType].displayName,\n searchableField: mapping[contentType].searchableField,\n results: contents\n };\n });\n });\n\n return Promise.all(promises);\n },\n validateRelations: async function (ctx) {\n const contentTypes = strapi.contentTypes;\n const body = ctx.request.body;\n\n const entries = body.entries as FormattedStrapiEntry[];\n\n const promises = entries.map((entry) => {\n return strapi\n .documents(entry.uid as any)\n .findOne({\n documentId: entry.documentId,\n populate: '*',\n status: 'published'\n })\n .then((result) => {\n return {\n uid: entry.uid,\n result\n };\n });\n });\n\n const responses = await Promise.all(promises);\n\n return responses\n .map((response) => {\n return {\n displayName: contentTypes[response.uid].info.displayName,\n uid: response.uid,\n searchableField: strapi\n .plugin('multi-content-type-relation')\n .service('service')\n .getFirstStringFieldInContentType(contentTypes[response.uid]),\n item: response.result\n };\n })\n .filter((entry) => entry.item);\n },\n listContentTypes: async function () {\n const contentTypes: Record<string, unknown>[] = [];\n\n for (const contentType of Object.values(strapi.contentTypes)) {\n if (\n (contentType.kind === 'collectionType' ||\n contentType.kind === 'singleType') &&\n !contentType.plugin\n ) {\n contentTypes.push(contentType);\n }\n }\n\n return contentTypes;\n },\n fetchRevertRelations: async function (ctx) {\n const body = ctx.request.body;\n let documentId = body.documentId as string;\n const uid = body.uid as UID.ContentType;\n const isSingleType = body.isSingleType as boolean;\n\n if (isSingleType) {\n const document = await strapi.documents(uid).findFirst({\n populate: '*',\n status: 'published'\n });\n\n if (!document) return [];\n\n documentId = document.documentId;\n }\n\n const mctrRelations = await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .findMany({\n filters: {\n target: {\n $containsi: `${uid}##${documentId}`\n }\n }\n });\n\n const relations = await Promise.all(\n mctrRelations.map(async (relation) => {\n const sourceDocumentId = relation.sourceDocId;\n const sourceUid = relation.sourceUID;\n\n const target = relation.target.find((target) =>\n target.includes(`${uid}##${documentId}`)\n );\n\n const [field] = target.split('##');\n\n const contentTypeName = Object.keys(strapi.contentTypes).find(\n (key) => strapi.contentTypes[key].uid === sourceUid\n );\n\n if (!contentTypeName) return null;\n\n const contentType = strapi.contentTypes[contentTypeName];\n\n const document = await strapi.documents(sourceUid).findOne({\n documentId: sourceDocumentId,\n populate: '*',\n status: 'published'\n });\n\n const searchableField = strapi\n .plugin('multi-content-type-relation')\n .service('service')\n .getFirstStringFieldInContentType(contentType);\n\n return {\n title: document[searchableField],\n uid: sourceUid,\n isSingleType: contentType.kind === 'singleType',\n field,\n type: contentType.info.displayName,\n documentId: sourceDocumentId\n };\n })\n );\n\n return relations.filter(Boolean);\n }\n});\n","import controller from './controller';\n\nexport default {\n controller,\n};\n","export default {};\n","export default [\n {\n method: 'GET',\n path: '/list-content-types',\n handler: 'controller.listContentTypes',\n config: {\n policies: [],\n auth: false\n }\n },\n {\n method: 'POST',\n path: '/get-content',\n handler: 'controller.getMatchingContent',\n config: {\n policies: []\n }\n },\n {\n method: 'POST',\n path: '/validate-relations',\n handler: 'controller.validateRelations',\n config: {\n policies: []\n }\n },\n {\n method: 'POST',\n path: '/fetch-revert-relations',\n handler: 'controller.fetchRevertRelations',\n config: {\n policies: []\n }\n }\n];\n","import type { Core } from '@strapi/strapi';\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n getFirstStringFieldInContentType(contentType) {\n const result = Object.keys(contentType.attributes).find(\n (attribute) => contentType.attributes[attribute].type === 'string'\n );\n\n return result;\n }\n});\n","import service from './service';\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\nimport destroy from './destroy';\nimport register from './register';\n\n/**\n * Plugin server methods\n */\nimport config from './config';\nimport contentTypes from './content-types';\nimport controllers from './controllers';\nimport middlewares from './middlewares';\nimport policies from './policies';\nimport routes from './routes';\nimport services from './services';\n\nexport default {\n register,\n bootstrap,\n destroy,\n config,\n controllers,\n routes,\n services,\n contentTypes,\n policies,\n middlewares,\n};\n"],"names":["strapi","contentTypes","documentId","config","target"],"mappings":"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"}
|
package/dist/server/index.mjs
CHANGED
|
@@ -168,7 +168,7 @@ const hydrateMRCT = async (content, currentDepth, context) => {
|
|
|
168
168
|
(linkedEntry) => item.uid === linkedEntry.uid && item.documentId === linkedEntry.response.documentId
|
|
169
169
|
);
|
|
170
170
|
if (matchingContent) {
|
|
171
|
-
hydratedArray.push(matchingContent.response);
|
|
171
|
+
hydratedArray.push({ uid: matchingContent.uid, ...matchingContent.response });
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
flattenedProperties[key] = hydratedArray;
|
|
@@ -439,7 +439,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
439
439
|
};
|
|
440
440
|
})
|
|
441
441
|
);
|
|
442
|
-
return relations;
|
|
442
|
+
return relations.filter(Boolean);
|
|
443
443
|
}
|
|
444
444
|
});
|
|
445
445
|
const controllers = {
|
|
@@ -507,3 +507,4 @@ const index = {
|
|
|
507
507
|
export {
|
|
508
508
|
index as default
|
|
509
509
|
};
|
|
510
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../server/src/bootstrap.ts","../../server/src/destroy.ts","../../server/src/utils.ts","../../server/src/helpers/index.ts","../../server/src/middlewares/middleware.ts","../../server/src/middlewares/index.ts","../../server/src/register.ts","../../server/src/config/index.ts","../../server/src/content-types/mctr-relation/schema.ts","../../server/src/content-types/mctr-relation/index.ts","../../server/src/content-types/index.ts","../../server/src/controllers/controller.ts","../../server/src/controllers/index.ts","../../server/src/policies/index.ts","../../server/src/routes/index.ts","../../server/src/services/service.ts","../../server/src/services/index.ts","../../server/src/index.ts"],"sourcesContent":["import type { Core } from '@strapi/strapi';\n\nconst bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {};\nexport default bootstrap;\n","import type { Core } from '@strapi/strapi';\n\nconst destroy = ({ strapi }: { strapi: Core.Strapi }) => {\n // destroy phase\n};\n\nexport default destroy;\n","import { Configuration } from './interface';\n\nexport const getPluginConfiguration = (): Configuration => {\n const pluginConfiguration = strapi.config.get(\n 'plugin::multi-content-type-relation'\n ) as Configuration;\n\n return pluginConfiguration;\n};\nexport const log = (message: string) => {\n const { debug } = getPluginConfiguration();\n\n if (debug) {\n console.log(`[MCTR DEBUG] ${message}`);\n }\n};\n","export const flattenObj = (\n obj: any,\n parent: any,\n res: Record<string, any> = {}\n) => {\n for (let key in obj) {\n let propName = parent ? parent + '.' + key : key;\n if (typeof obj[key] == 'object') {\n flattenObj(obj[key], propName, res);\n } else {\n res[propName] = obj[key];\n }\n }\n return res;\n};\n\nexport const unflatten = (data: any) => {\n var result = {};\n for (var i in data) {\n var keys = i.split('.');\n keys.reduce(function (r: any, e, j) {\n return (\n r[e] ||\n (r[e] = isNaN(Number(keys[j + 1]))\n ? keys.length - 1 == j\n ? data[i]\n : {}\n : [])\n );\n }, result);\n }\n return result;\n};\n","import { getPluginConfiguration, log } from '../utils';\nimport type { Context, StrapiResponse, AnyEntity } from '../interface';\nimport { flattenObj, unflatten } from '../helpers';\nimport type { UID } from '@strapi/strapi';\n\nexport default async (ctx, next) => {\n await next();\n\n if (!ctx.body) return;\n if (!ctx.body.data) return;\n\n if (\n [\n 'collection-types.create',\n 'collection-types.update',\n 'single-types.createOrUpdate'\n ].includes(ctx?.state?.route?.handler)\n ) {\n const [, _, __, rest] = ctx?.request.url.split('/');\n const contentType = rest.split('?')[0];\n\n const isDraftAndPublish =\n strapi.contentTypes[contentType].options?.draftAndPublish;\n\n // We want to update relation only on publish for those who have it activated\n if (isDraftAndPublish) {\n log(`[MIDDLEWARE] ${contentType}is draft and publish`);\n return;\n }\n\n const documentId = ctx.body.data.documentId;\n syncMctrRelation(documentId, contentType as UID.ContentType);\n }\n\n if (\n ['collection-types.publish', 'single-types.publish'].includes(\n ctx?.state?.route?.handler\n )\n ) {\n const [, _, __, rest] = ctx?.request.url.split('/');\n const contentType = rest.split('?')[0];\n\n const documentId = ctx.body.data.documentId;\n syncMctrRelation(documentId, contentType as UID.ContentType);\n }\n\n // Only on specific handlerswith public API we want to hydrate the MCTR relation\n if (!ctx?.request?.url?.startsWith('/api')) return;\n if (ctx.request.method !== 'GET') return;\n if (!ctx.body) return;\n\n const configuration = getPluginConfiguration();\n\n const handler = ctx.state.route.handler;\n const contentTypes = Object.keys(strapi.contentTypes);\n\n log(`[MIDDLEWARE] URL: ${ctx.request.url} (${ctx.request.method})`);\n log(`[MIDDLEWARE] Strapi Route: ${JSON.stringify(ctx.state.route, null, 2)}`);\n\n if (typeof handler !== 'string') return;\n\n const validHandler = contentTypes\n .filter((contentType) => contentType.startsWith('api::'))\n .some(\n (contentType) =>\n handler.includes(`${contentType}.findOne`) ||\n handler.includes(`${contentType}.findMany`) ||\n handler.includes(`${contentType}.find`)\n );\n\n log(`[MIDDLEWARE] Is valid handler: ${validHandler}`);\n\n // Allow only findOne/findMany for native contentypes that have api::\n if (!validHandler) return;\n\n const context = {\n configuration,\n publicationState: ctx.request.query?.['publicationState'] ?? 'live'\n };\n\n log(`[MIDDLEWARE] Context Body: ${JSON.stringify(ctx.body, null, 2)}`);\n if (ctx.body.error || !ctx.body?.data) return;\n\n const hydratedData = await augmentMRCT(ctx.body, 1, context);\n\n ctx.body.data = hydratedData;\n};\n\nconst augmentMRCT = async (\n strapiResponse: StrapiResponse,\n currentDepth: number,\n context: Context\n): Promise<AnyEntity | AnyEntity[]> => {\n if (Array.isArray(strapiResponse.data)) {\n const promises = strapiResponse.data.map((item) =>\n hydrateMRCT(item, currentDepth, context)\n );\n\n return await Promise.all(promises);\n } else {\n return await hydrateMRCT(strapiResponse.data, currentDepth, context);\n }\n};\n\nconst hydrateMRCT = async (\n content: AnyEntity,\n currentDepth: number,\n context: Context\n) => {\n const eligibleProperties: Set<string> = new Set();\n const contentsToFetch: Set<string> = new Set();\n\n const { configuration } = context;\n\n const flattenedProperties = flattenObj(content, null);\n\n for (const [key, value] of Object.entries(flattenedProperties)) {\n if (typeof value !== 'string' || !value.includes('MRCT')) continue;\n\n try {\n const field = JSON.parse(value);\n\n if (!Array.isArray(field)) continue;\n\n for (const item of field) {\n if (\n Object.keys(item).length !== 3 ||\n (!item.uid && typeof item.uid !== 'string') ||\n !item.documentId\n )\n continue;\n\n const compositeID = `${item.uid}####${item.documentId}`;\n\n eligibleProperties.add(key);\n\n if (contentsToFetch.has(compositeID)) continue;\n else contentsToFetch.add(compositeID);\n }\n } catch (e) {\n continue;\n }\n }\n\n if (!contentsToFetch.size) return content;\n\n log(\n `[MCTR HYDRATOR] Depth: ${currentDepth}, Hydrating MCTR for ID ${content.id}`\n );\n\n const promises: Promise<any>[] = [];\n for (const item of Array.from(contentsToFetch)) {\n const [uid, documentId] = item.split('####');\n const promise = strapi\n .documents(uid as any)\n .findOne({ documentId, populate: '*', status: 'published' })\n .then(async (response) => {\n if (!response) return { uid, response };\n\n if (\n configuration.recursive.enabled &&\n currentDepth < configuration.recursive.maxDepth\n ) {\n // Entity service serve the content flattened, so we need to rebuild the API format for the hydrate recursion\n const hydratedResponse = await hydrateMRCT(\n response as unknown as AnyEntity, //TODO: fix me\n currentDepth + 1,\n context\n );\n\n return {\n uid,\n response: {\n documentId: response.documentId,\n ...hydratedResponse\n }\n };\n } else {\n return {\n uid,\n response: {\n documentId: response.documentId,\n ...response\n }\n };\n }\n });\n\n promises.push(promise);\n }\n\n const linkedEntries: any[] = await Promise.all(promises);\n\n const filteredLinkedEntries: { uid: string; response: AnyEntity }[] =\n linkedEntries\n .filter((linkedEntry) => Boolean(linkedEntry.response))\n .filter((linkedEntry) => {\n const contentTypeConfiguration = strapi.contentTypes[linkedEntry.uid];\n\n if (!contentTypeConfiguration) return true;\n if (!contentTypeConfiguration.options?.draftAndPublish) return true;\n if (context.publicationState === 'preview') return true;\n\n return typeof linkedEntry.response?.publishedAt === 'string';\n });\n\n for (const key of Array.from(eligibleProperties)) {\n const hydratedArray: AnyEntity[] = [];\n\n const unhydratedField = JSON.parse(flattenedProperties[key]) as {\n uid: string;\n documentId: string;\n }[];\n\n for (const item of unhydratedField) {\n const matchingContent = filteredLinkedEntries.find(\n (linkedEntry) =>\n item.uid === linkedEntry.uid &&\n item.documentId === linkedEntry.response.documentId\n );\n\n if (matchingContent) {\n hydratedArray.push({ uid: matchingContent.uid, ...matchingContent.response });\n }\n }\n\n flattenedProperties[key] = hydratedArray;\n }\n\n const newContent = unflatten(flattenedProperties);\n return {\n ...content,\n ...newContent\n };\n};\n\nconst syncMctrRelation = async (documentId: string, uid: UID.ContentType) => {\n const mctrDocuments = await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .findMany({\n filters: {\n sourceDocId: documentId\n }\n });\n\n if (mctrDocuments.length !== 0) {\n log(`[SYNC] Delete MCTR relations for ${documentId}`);\n // delete the mctr relation\n await Promise.all(\n mctrDocuments.map(async ({ documentId }) => {\n await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .delete({\n documentId\n });\n })\n );\n }\n\n log(`[SYNC] Find document ${documentId}`);\n const document = await strapi.documents(uid).findOne({\n documentId\n });\n\n // Explore document to find the mctr relation\n const contentTypeKey = Object.keys(strapi.contentTypes).find(\n (ct) => strapi.contentTypes[ct].uid === uid\n );\n\n if (!contentTypeKey) return;\n\n const contentType = strapi.contentTypes[contentTypeKey];\n\n // TODO: recursive find the mctr relation\n const mctrFields = Object.keys(contentType.attributes).filter(\n (field) =>\n contentType.attributes[field].customField ===\n 'plugin::multi-content-type-relation.multi-content-type-relation'\n );\n\n if (mctrFields.length === 0) return;\n\n const targetJSON = [];\n\n // Create the mctr relation to have a sync\n mctrFields.forEach(async (field) => {\n const fieldValue = document[field];\n if (!fieldValue) return;\n\n try {\n const mctrField = JSON.parse(fieldValue);\n mctrField.forEach((item) => {\n targetJSON.push(`${field}##${item.uid}##${item.documentId}`);\n });\n } catch (e) {\n log(`[SYNC] Error parsing field ${field} ${fieldValue}`);\n }\n });\n\n log(`[SYNC] Target JSON ${targetJSON}`);\n if (targetJSON.length === 0) return;\n\n await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .create({\n data: {\n sourceUID: uid,\n sourceDocId: documentId,\n target: targetJSON\n }\n });\n\n log(`[SYNC] MCTR relation created for ${documentId}`);\n};\n","import middleware from './middleware';\n\nexport default {\n middleware,\n};\n","import middlewares from './middlewares';\n\nimport type { Core } from '@strapi/strapi';\n\nconst register = ({ strapi }: { strapi: Core.Strapi }) => {\n // register phase\n strapi.customFields.register({\n name: 'multi-content-type-relation',\n plugin: 'multi-content-type-relation',\n type: 'richtext'\n });\n\n strapi.server.use(middlewares.middleware);\n};\n\nexport default register;\n","export default {\n default: ({ env }) => {\n return {\n recursive: {\n enabled: false,\n maxDepth: 1,\n },\n debug: false,\n };\n },\n validator(config) {\n if (typeof config.recursive !== 'object') {\n throw new Error('recursive must be an object');\n }\n\n if (typeof config.recursive.enabled !== 'boolean') {\n throw new Error('recursive.enabled must be a boolean');\n }\n\n if (typeof config.recursive.maxDepth !== 'number') {\n throw new Error('recursive.maxDepth must be a number');\n }\n\n if (typeof config.debug !== 'boolean') {\n throw new Error('Debug must be a boolean');\n }\n },\n};\n","export default {\n collectionName: 'mctr-relation',\n info: {\n singularName: 'mctr-relation',\n pluralName: 'mctr-relations',\n displayName: 'MCTR Relation',\n name: 'mctr-relation'\n },\n pluginOptions: {\n 'content-manager': {\n visible: false\n },\n 'content-type-builder': {\n visible: false\n }\n },\n attributes: {\n sourceUID: {\n type: 'string',\n required: true\n },\n sourceDocId: {\n type: 'string',\n required: true\n },\n target: {\n type: 'json'\n }\n }\n};\n","'use strict';\n\nimport schema from './schema';\n\nexport default {\n schema\n};\n","import mctrRelation from './mctr-relation';\n\nexport default {\n 'mctr-relation': mctrRelation\n};\n","import type { Core, UID } from '@strapi/strapi';\nimport { FormattedStrapiEntry } from '../interface';\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n getMatchingContent(ctx) {\n const contentTypes = strapi.contentTypes;\n const body = ctx.request.body;\n\n const requestedContentTypes = body.contentTypes as string[];\n const keyword = body.keyword as string;\n const locale = body.locale as string;\n\n const mapping = requestedContentTypes.reduce(\n (accumulator, contentType) => {\n Object.keys(contentTypes).forEach((model) => {\n const strapiContentType = contentTypes[model];\n if (\n strapiContentType.info.singularName === contentType ||\n strapiContentType.info.pluralName === contentType\n ) {\n accumulator[contentType] = {\n uid: model as UID.ContentType,\n displayName: contentTypes[model].info.displayName,\n searchableField: strapi\n .plugin('multi-content-type-relation')\n .service('service')\n .getFirstStringFieldInContentType(contentTypes[model])\n };\n }\n });\n\n return accumulator;\n },\n {} as Record<\n string,\n { uid: UID.ContentType; displayName: string; searchableField: string }\n >\n );\n\n const promises = Object.keys(mapping).map((contentType) => {\n const uid = mapping[contentType].uid;\n\n return strapi\n .documents(uid)\n .findMany({\n filters: {\n [mapping[contentType].searchableField]: {\n $containsi: keyword\n }\n },\n locale,\n status: 'published'\n })\n .then((results) => {\n let contents = Array.isArray(results)\n ? results\n : typeof results === 'object' && results\n ? [results]\n : [];\n\n const contentTypeDefinition = strapi.contentType(uid);\n if (contentTypeDefinition?.options?.draftAndPublish) {\n contents = contents.filter(\n (content) => content.publishedAt !== null\n );\n }\n\n return {\n uid,\n displayName: mapping[contentType].displayName,\n searchableField: mapping[contentType].searchableField,\n results: contents\n };\n });\n });\n\n return Promise.all(promises);\n },\n validateRelations: async function (ctx) {\n const contentTypes = strapi.contentTypes;\n const body = ctx.request.body;\n\n const entries = body.entries as FormattedStrapiEntry[];\n\n const promises = entries.map((entry) => {\n return strapi\n .documents(entry.uid as any)\n .findOne({\n documentId: entry.documentId,\n populate: '*',\n status: 'published'\n })\n .then((result) => {\n return {\n uid: entry.uid,\n result\n };\n });\n });\n\n const responses = await Promise.all(promises);\n\n return responses\n .map((response) => {\n return {\n displayName: contentTypes[response.uid].info.displayName,\n uid: response.uid,\n searchableField: strapi\n .plugin('multi-content-type-relation')\n .service('service')\n .getFirstStringFieldInContentType(contentTypes[response.uid]),\n item: response.result\n };\n })\n .filter((entry) => entry.item);\n },\n listContentTypes: async function () {\n const contentTypes: Record<string, unknown>[] = [];\n\n for (const contentType of Object.values(strapi.contentTypes)) {\n if (\n (contentType.kind === 'collectionType' ||\n contentType.kind === 'singleType') &&\n !contentType.plugin\n ) {\n contentTypes.push(contentType);\n }\n }\n\n return contentTypes;\n },\n fetchRevertRelations: async function (ctx) {\n const body = ctx.request.body;\n let documentId = body.documentId as string;\n const uid = body.uid as UID.ContentType;\n const isSingleType = body.isSingleType as boolean;\n\n if (isSingleType) {\n const document = await strapi.documents(uid).findFirst({\n populate: '*',\n status: 'published'\n });\n\n if (!document) return [];\n\n documentId = document.documentId;\n }\n\n const mctrRelations = await strapi\n .documents('plugin::multi-content-type-relation.mctr-relation')\n .findMany({\n filters: {\n target: {\n $containsi: `${uid}##${documentId}`\n }\n }\n });\n\n const relations = await Promise.all(\n mctrRelations.map(async (relation) => {\n const sourceDocumentId = relation.sourceDocId;\n const sourceUid = relation.sourceUID;\n\n const target = relation.target.find((target) =>\n target.includes(`${uid}##${documentId}`)\n );\n\n const [field] = target.split('##');\n\n const contentTypeName = Object.keys(strapi.contentTypes).find(\n (key) => strapi.contentTypes[key].uid === sourceUid\n );\n\n if (!contentTypeName) return null;\n\n const contentType = strapi.contentTypes[contentTypeName];\n\n const document = await strapi.documents(sourceUid).findOne({\n documentId: sourceDocumentId,\n populate: '*',\n status: 'published'\n });\n\n const searchableField = strapi\n .plugin('multi-content-type-relation')\n .service('service')\n .getFirstStringFieldInContentType(contentType);\n\n return {\n title: document[searchableField],\n uid: sourceUid,\n isSingleType: contentType.kind === 'singleType',\n field,\n type: contentType.info.displayName,\n documentId: sourceDocumentId\n };\n })\n );\n\n return relations.filter(Boolean);\n }\n});\n","import controller from './controller';\n\nexport default {\n controller,\n};\n","export default {};\n","export default [\n {\n method: 'GET',\n path: '/list-content-types',\n handler: 'controller.listContentTypes',\n config: {\n policies: [],\n auth: false\n }\n },\n {\n method: 'POST',\n path: '/get-content',\n handler: 'controller.getMatchingContent',\n config: {\n policies: []\n }\n },\n {\n method: 'POST',\n path: '/validate-relations',\n handler: 'controller.validateRelations',\n config: {\n policies: []\n }\n },\n {\n method: 'POST',\n path: '/fetch-revert-relations',\n handler: 'controller.fetchRevertRelations',\n config: {\n policies: []\n }\n }\n];\n","import type { Core } from '@strapi/strapi';\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n getFirstStringFieldInContentType(contentType) {\n const result = Object.keys(contentType.attributes).find(\n (attribute) => contentType.attributes[attribute].type === 'string'\n );\n\n return result;\n }\n});\n","import service from './service';\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\nimport destroy from './destroy';\nimport register from './register';\n\n/**\n * Plugin server methods\n */\nimport config from './config';\nimport contentTypes from './content-types';\nimport controllers from './controllers';\nimport middlewares from './middlewares';\nimport policies from './policies';\nimport routes from './routes';\nimport services from './services';\n\nexport default {\n register,\n bootstrap,\n destroy,\n config,\n controllers,\n routes,\n services,\n contentTypes,\n policies,\n middlewares,\n};\n"],"names":["strapi","contentTypes","documentId","config","target"],"mappings":"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"}
|