multi-content-type-relation 0.1.0 → 2.0.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.
Files changed (98) hide show
  1. package/dist/_chunks/en-Bk9okOMP.js +32 -0
  2. package/dist/_chunks/en-Cj4T04Z2.mjs +32 -0
  3. package/dist/_chunks/fr-KHPiQOFP.mjs +32 -0
  4. package/dist/_chunks/fr-ZS3aTnjj.js +32 -0
  5. package/dist/_chunks/index-5liGVtQX.js +3566 -0
  6. package/dist/_chunks/index-CQ_pNHWj.js +335 -0
  7. package/dist/_chunks/index-Cyd6H1uV.mjs +336 -0
  8. package/dist/_chunks/index-D3M5NaOA.mjs +3564 -0
  9. package/dist/admin/index.js +3 -0
  10. package/dist/admin/index.mjs +4 -0
  11. package/dist/admin/src/components/Input/InputContentSuggestions.d.ts +13 -0
  12. package/dist/admin/src/components/Input/MainInput.d.ts +16 -0
  13. package/dist/admin/src/components/Input/PublicationState.d.ts +6 -0
  14. package/dist/admin/src/components/Input/TableItem.d.ts +12 -0
  15. package/dist/admin/src/components/Input/index.d.ts +2 -0
  16. package/dist/admin/src/components/PluginIcon/index.d.ts +2 -0
  17. package/dist/admin/src/components/SidePanel/SidePanel.d.ts +7 -0
  18. package/dist/admin/src/helpers/content.d.ts +5 -0
  19. package/dist/admin/src/helpers/storage.d.ts +15 -0
  20. package/dist/admin/src/hooks/useSearchedEntries.d.ts +6 -0
  21. package/dist/admin/src/hooks/useTranslate.d.ts +4 -0
  22. package/dist/admin/src/index.d.ts +9 -0
  23. package/dist/admin/src/interface.d.ts +33 -0
  24. package/dist/admin/src/pluginId.d.ts +2 -0
  25. package/dist/server/index.js +506 -25
  26. package/dist/server/index.mjs +509 -0
  27. package/dist/server/src/bootstrap.d.ts +5 -0
  28. package/dist/server/src/config/index.d.ts +13 -0
  29. package/dist/server/src/content-types/index.d.ts +35 -0
  30. package/dist/server/src/content-types/mctr-relation/index.d.ts +33 -0
  31. package/dist/server/src/content-types/mctr-relation/schema.d.ts +31 -0
  32. package/dist/server/src/controllers/controller.d.ts +27 -0
  33. package/dist/server/src/controllers/index.d.ts +28 -0
  34. package/dist/server/src/destroy.d.ts +5 -0
  35. package/dist/server/src/helpers/index.d.ts +2 -0
  36. package/dist/server/src/index.d.ts +113 -0
  37. package/dist/server/src/interface.d.ts +42 -0
  38. package/dist/server/src/middlewares/index.d.ts +4 -0
  39. package/dist/server/src/middlewares/middleware.d.ts +2 -0
  40. package/dist/server/src/policies/index.d.ts +2 -0
  41. package/dist/server/src/register.d.ts +5 -0
  42. package/dist/server/src/routes/index.d.ts +18 -0
  43. package/dist/server/src/services/index.d.ts +8 -0
  44. package/dist/server/src/services/service.d.ts +7 -0
  45. package/dist/server/src/utils.d.ts +3 -0
  46. package/package.json +55 -27
  47. package/TODO.md +0 -4
  48. package/admin/src/components/Input/InputContentSuggestions.tsx +0 -162
  49. package/admin/src/components/Input/MainInput.tsx +0 -135
  50. package/admin/src/components/Input/PublicationState.tsx +0 -28
  51. package/admin/src/components/Input/TableItem.tsx +0 -109
  52. package/admin/src/components/Input/index.tsx +0 -27
  53. package/admin/src/components/PluginIcon/index.tsx +0 -12
  54. package/admin/src/helpers/content.ts +0 -60
  55. package/admin/src/helpers/storage.ts +0 -32
  56. package/admin/src/hooks/useSearchedEntries.ts +0 -41
  57. package/admin/src/index.tsx +0 -140
  58. package/admin/src/interface.ts +0 -37
  59. package/admin/src/pluginId.ts +0 -5
  60. package/admin/src/translations/en.json +0 -1
  61. package/admin/src/translations/fr.json +0 -1
  62. package/admin/src/utils/getTrad.ts +0 -5
  63. package/dist/server/bootstrap.js +0 -5
  64. package/dist/server/config/index.js +0 -27
  65. package/dist/server/content-types/index.js +0 -3
  66. package/dist/server/controllers/controller.js +0 -92
  67. package/dist/server/controllers/index.js +0 -9
  68. package/dist/server/destroy.js +0 -5
  69. package/dist/server/interface.js +0 -2
  70. package/dist/server/middlewares/index.js +0 -9
  71. package/dist/server/middlewares/middleware.js +0 -163
  72. package/dist/server/policies/index.js +0 -3
  73. package/dist/server/register.js +0 -15
  74. package/dist/server/routes/index.js +0 -29
  75. package/dist/server/services/index.js +0 -9
  76. package/dist/server/services/service.js +0 -8
  77. package/dist/server/utils.js +0 -15
  78. package/dist/tsconfig.server.tsbuildinfo +0 -1
  79. package/server/bootstrap.ts +0 -5
  80. package/server/config/index.ts +0 -28
  81. package/server/content-types/index.ts +0 -1
  82. package/server/controllers/controller.ts +0 -107
  83. package/server/controllers/index.ts +0 -5
  84. package/server/destroy.ts +0 -5
  85. package/server/index.ts +0 -23
  86. package/server/interface.ts +0 -50
  87. package/server/middlewares/index.ts +0 -5
  88. package/server/middlewares/middleware.ts +0 -197
  89. package/server/policies/index.ts +0 -1
  90. package/server/register.ts +0 -14
  91. package/server/routes/index.ts +0 -27
  92. package/server/services/index.ts +0 -5
  93. package/server/services/service.ts +0 -11
  94. package/server/utils.ts +0 -14
  95. package/strapi-admin.js +0 -3
  96. package/strapi-server.js +0 -3
  97. package/tsconfig.json +0 -20
  98. package/tsconfig.server.json +0 -25
@@ -0,0 +1,509 @@
1
+ const bootstrap = ({ strapi: strapi2 }) => {
2
+ };
3
+ const destroy = ({ strapi: strapi2 }) => {
4
+ };
5
+ const getPluginConfiguration = () => {
6
+ const pluginConfiguration = strapi.config.get(
7
+ "plugin::multi-content-type-relation"
8
+ );
9
+ return pluginConfiguration;
10
+ };
11
+ const log = (message) => {
12
+ const { debug } = getPluginConfiguration();
13
+ if (debug) {
14
+ console.log(`[MCTR DEBUG] ${message}`);
15
+ }
16
+ };
17
+ const flattenObj = (obj, parent, res = {}) => {
18
+ for (let key in obj) {
19
+ let propName = parent ? parent + "." + key : key;
20
+ if (typeof obj[key] == "object") {
21
+ flattenObj(obj[key], propName, res);
22
+ } else {
23
+ res[propName] = obj[key];
24
+ }
25
+ }
26
+ return res;
27
+ };
28
+ const unflatten = (data) => {
29
+ var result = {};
30
+ for (var i in data) {
31
+ var keys = i.split(".");
32
+ keys.reduce(function(r, e, j) {
33
+ return r[e] || (r[e] = isNaN(Number(keys[j + 1])) ? keys.length - 1 == j ? data[i] : {} : []);
34
+ }, result);
35
+ }
36
+ return result;
37
+ };
38
+ const middleware = async (ctx, next) => {
39
+ await next();
40
+ if (!ctx.body) return;
41
+ if (!ctx.body.data) return;
42
+ if ([
43
+ "collection-types.create",
44
+ "collection-types.update",
45
+ "single-types.createOrUpdate"
46
+ ].includes(ctx?.state?.route?.handler)) {
47
+ const [, _, __, rest] = ctx?.request.url.split("/");
48
+ const contentType = rest.split("?")[0];
49
+ const isDraftAndPublish = strapi.contentTypes[contentType].options?.draftAndPublish;
50
+ if (isDraftAndPublish) {
51
+ log(`[MIDDLEWARE] ${contentType}is draft and publish`);
52
+ return;
53
+ }
54
+ const documentId = ctx.body.data.documentId;
55
+ syncMctrRelation(documentId, contentType);
56
+ }
57
+ if (["collection-types.publish", "single-types.publish"].includes(
58
+ ctx?.state?.route?.handler
59
+ )) {
60
+ const [, _, __, rest] = ctx?.request.url.split("/");
61
+ const contentType = rest.split("?")[0];
62
+ const documentId = ctx.body.data.documentId;
63
+ syncMctrRelation(documentId, contentType);
64
+ }
65
+ if (!ctx?.request?.url?.startsWith("/api")) return;
66
+ if (ctx.request.method !== "GET") return;
67
+ if (!ctx.body) return;
68
+ const configuration = getPluginConfiguration();
69
+ const handler = ctx.state.route.handler;
70
+ const contentTypes2 = Object.keys(strapi.contentTypes);
71
+ log(`[MIDDLEWARE] URL: ${ctx.request.url} (${ctx.request.method})`);
72
+ log(`[MIDDLEWARE] Strapi Route: ${JSON.stringify(ctx.state.route, null, 2)}`);
73
+ if (typeof handler !== "string") return;
74
+ const validHandler = contentTypes2.filter((contentType) => contentType.startsWith("api::")).some(
75
+ (contentType) => handler.includes(`${contentType}.findOne`) || handler.includes(`${contentType}.findMany`) || handler.includes(`${contentType}.find`)
76
+ );
77
+ log(`[MIDDLEWARE] Is valid handler: ${validHandler}`);
78
+ if (!validHandler) return;
79
+ const context = {
80
+ configuration,
81
+ publicationState: ctx.request.query?.["publicationState"] ?? "live"
82
+ };
83
+ log(`[MIDDLEWARE] Context Body: ${JSON.stringify(ctx.body, null, 2)}`);
84
+ if (ctx.body.error || !ctx.body?.data) return;
85
+ const hydratedData = await augmentMRCT(ctx.body, 1, context);
86
+ ctx.body.data = hydratedData;
87
+ };
88
+ const augmentMRCT = async (strapiResponse, currentDepth, context) => {
89
+ if (Array.isArray(strapiResponse.data)) {
90
+ const promises = strapiResponse.data.map(
91
+ (item) => hydrateMRCT(item, currentDepth, context)
92
+ );
93
+ return await Promise.all(promises);
94
+ } else {
95
+ return await hydrateMRCT(strapiResponse.data, currentDepth, context);
96
+ }
97
+ };
98
+ const hydrateMRCT = async (content, currentDepth, context) => {
99
+ const eligibleProperties = /* @__PURE__ */ new Set();
100
+ const contentsToFetch = /* @__PURE__ */ new Set();
101
+ const { configuration } = context;
102
+ const flattenedProperties = flattenObj(content, null);
103
+ for (const [key, value] of Object.entries(flattenedProperties)) {
104
+ if (typeof value !== "string" || !value.includes("MRCT")) continue;
105
+ try {
106
+ const field = JSON.parse(value);
107
+ if (!Array.isArray(field)) continue;
108
+ for (const item of field) {
109
+ if (Object.keys(item).length !== 3 || !item.uid && typeof item.uid !== "string" || !item.documentId)
110
+ continue;
111
+ const compositeID = `${item.uid}####${item.documentId}`;
112
+ eligibleProperties.add(key);
113
+ if (contentsToFetch.has(compositeID)) continue;
114
+ else contentsToFetch.add(compositeID);
115
+ }
116
+ } catch (e) {
117
+ continue;
118
+ }
119
+ }
120
+ if (!contentsToFetch.size) return content;
121
+ log(
122
+ `[MCTR HYDRATOR] Depth: ${currentDepth}, Hydrating MCTR for ID ${content.id}`
123
+ );
124
+ const promises = [];
125
+ for (const item of Array.from(contentsToFetch)) {
126
+ const [uid, documentId] = item.split("####");
127
+ const promise = strapi.documents(uid).findOne({ documentId, populate: "*", status: "published" }).then(async (response) => {
128
+ if (!response) return { uid, response };
129
+ if (configuration.recursive.enabled && currentDepth < configuration.recursive.maxDepth) {
130
+ const hydratedResponse = await hydrateMRCT(
131
+ response,
132
+ //TODO: fix me
133
+ currentDepth + 1,
134
+ context
135
+ );
136
+ return {
137
+ uid,
138
+ response: {
139
+ documentId: response.documentId,
140
+ ...hydratedResponse
141
+ }
142
+ };
143
+ } else {
144
+ return {
145
+ uid,
146
+ response: {
147
+ documentId: response.documentId,
148
+ ...response
149
+ }
150
+ };
151
+ }
152
+ });
153
+ promises.push(promise);
154
+ }
155
+ const linkedEntries = await Promise.all(promises);
156
+ const filteredLinkedEntries = linkedEntries.filter((linkedEntry) => Boolean(linkedEntry.response)).filter((linkedEntry) => {
157
+ const contentTypeConfiguration = strapi.contentTypes[linkedEntry.uid];
158
+ if (!contentTypeConfiguration) return true;
159
+ if (!contentTypeConfiguration.options?.draftAndPublish) return true;
160
+ if (context.publicationState === "preview") return true;
161
+ return typeof linkedEntry.response?.publishedAt === "string";
162
+ });
163
+ for (const key of Array.from(eligibleProperties)) {
164
+ const hydratedArray = [];
165
+ const unhydratedField = JSON.parse(flattenedProperties[key]);
166
+ for (const item of unhydratedField) {
167
+ const matchingContent = filteredLinkedEntries.find(
168
+ (linkedEntry) => item.uid === linkedEntry.uid && item.documentId === linkedEntry.response.documentId
169
+ );
170
+ if (matchingContent) {
171
+ hydratedArray.push(matchingContent.response);
172
+ }
173
+ }
174
+ flattenedProperties[key] = hydratedArray;
175
+ }
176
+ const newContent = unflatten(flattenedProperties);
177
+ return {
178
+ ...content,
179
+ ...newContent
180
+ };
181
+ };
182
+ const syncMctrRelation = async (documentId, uid) => {
183
+ const mctrDocuments = await strapi.documents("plugin::multi-content-type-relation.mctr-relation").findMany({
184
+ filters: {
185
+ sourceDocId: documentId
186
+ }
187
+ });
188
+ if (mctrDocuments.length !== 0) {
189
+ log(`[SYNC] Delete MCTR relations for ${documentId}`);
190
+ await Promise.all(
191
+ mctrDocuments.map(async ({ documentId: documentId2 }) => {
192
+ await strapi.documents("plugin::multi-content-type-relation.mctr-relation").delete({
193
+ documentId: documentId2
194
+ });
195
+ })
196
+ );
197
+ }
198
+ log(`[SYNC] Find document ${documentId}`);
199
+ const document = await strapi.documents(uid).findOne({
200
+ documentId
201
+ });
202
+ const contentTypeKey = Object.keys(strapi.contentTypes).find(
203
+ (ct) => strapi.contentTypes[ct].uid === uid
204
+ );
205
+ if (!contentTypeKey) return;
206
+ const contentType = strapi.contentTypes[contentTypeKey];
207
+ const mctrFields = Object.keys(contentType.attributes).filter(
208
+ (field) => contentType.attributes[field].customField === "plugin::multi-content-type-relation.multi-content-type-relation"
209
+ );
210
+ if (mctrFields.length === 0) return;
211
+ const targetJSON = [];
212
+ mctrFields.forEach(async (field) => {
213
+ const fieldValue = document[field];
214
+ if (!fieldValue) return;
215
+ try {
216
+ const mctrField = JSON.parse(fieldValue);
217
+ mctrField.forEach((item) => {
218
+ targetJSON.push(`${field}##${item.uid}##${item.documentId}`);
219
+ });
220
+ } catch (e) {
221
+ log(`[SYNC] Error parsing field ${field} ${fieldValue}`);
222
+ }
223
+ });
224
+ log(`[SYNC] Target JSON ${targetJSON}`);
225
+ if (targetJSON.length === 0) return;
226
+ await strapi.documents("plugin::multi-content-type-relation.mctr-relation").create({
227
+ data: {
228
+ sourceUID: uid,
229
+ sourceDocId: documentId,
230
+ target: targetJSON
231
+ }
232
+ });
233
+ log(`[SYNC] MCTR relation created for ${documentId}`);
234
+ };
235
+ const middlewares = {
236
+ middleware
237
+ };
238
+ const register = ({ strapi: strapi2 }) => {
239
+ strapi2.customFields.register({
240
+ name: "multi-content-type-relation",
241
+ plugin: "multi-content-type-relation",
242
+ type: "richtext"
243
+ });
244
+ strapi2.server.use(middlewares.middleware);
245
+ };
246
+ const config = {
247
+ default: ({ env }) => {
248
+ return {
249
+ recursive: {
250
+ enabled: false,
251
+ maxDepth: 1
252
+ },
253
+ debug: false
254
+ };
255
+ },
256
+ validator(config2) {
257
+ if (typeof config2.recursive !== "object") {
258
+ throw new Error("recursive must be an object");
259
+ }
260
+ if (typeof config2.recursive.enabled !== "boolean") {
261
+ throw new Error("recursive.enabled must be a boolean");
262
+ }
263
+ if (typeof config2.recursive.maxDepth !== "number") {
264
+ throw new Error("recursive.maxDepth must be a number");
265
+ }
266
+ if (typeof config2.debug !== "boolean") {
267
+ throw new Error("Debug must be a boolean");
268
+ }
269
+ }
270
+ };
271
+ const schema = {
272
+ collectionName: "mctr-relation",
273
+ info: {
274
+ singularName: "mctr-relation",
275
+ pluralName: "mctr-relations",
276
+ displayName: "MCTR Relation",
277
+ name: "mctr-relation"
278
+ },
279
+ pluginOptions: {
280
+ "content-manager": {
281
+ visible: false
282
+ },
283
+ "content-type-builder": {
284
+ visible: false
285
+ }
286
+ },
287
+ attributes: {
288
+ sourceUID: {
289
+ type: "string",
290
+ required: true
291
+ },
292
+ sourceDocId: {
293
+ type: "string",
294
+ required: true
295
+ },
296
+ target: {
297
+ type: "json"
298
+ }
299
+ }
300
+ };
301
+ const mctrRelation = {
302
+ schema
303
+ };
304
+ const contentTypes = {
305
+ "mctr-relation": mctrRelation
306
+ };
307
+ const controller = ({ strapi: strapi2 }) => ({
308
+ getMatchingContent(ctx) {
309
+ const contentTypes2 = strapi2.contentTypes;
310
+ const body = ctx.request.body;
311
+ const requestedContentTypes = body.contentTypes;
312
+ const keyword = body.keyword;
313
+ const locale = body.locale;
314
+ const mapping = requestedContentTypes.reduce(
315
+ (accumulator, contentType) => {
316
+ Object.keys(contentTypes2).forEach((model) => {
317
+ const strapiContentType = contentTypes2[model];
318
+ if (strapiContentType.info.singularName === contentType || strapiContentType.info.pluralName === contentType) {
319
+ accumulator[contentType] = {
320
+ uid: model,
321
+ displayName: contentTypes2[model].info.displayName,
322
+ searchableField: strapi2.plugin("multi-content-type-relation").service("service").getFirstStringFieldInContentType(contentTypes2[model])
323
+ };
324
+ }
325
+ });
326
+ return accumulator;
327
+ },
328
+ {}
329
+ );
330
+ const promises = Object.keys(mapping).map((contentType) => {
331
+ const uid = mapping[contentType].uid;
332
+ return strapi2.documents(uid).findMany({
333
+ filters: {
334
+ [mapping[contentType].searchableField]: {
335
+ $containsi: keyword
336
+ }
337
+ },
338
+ locale,
339
+ status: "published"
340
+ }).then((results) => {
341
+ let contents = Array.isArray(results) ? results : typeof results === "object" && results ? [results] : [];
342
+ const contentTypeDefinition = strapi2.contentType(uid);
343
+ if (contentTypeDefinition?.options?.draftAndPublish) {
344
+ contents = contents.filter(
345
+ (content) => content.publishedAt !== null
346
+ );
347
+ }
348
+ return {
349
+ uid,
350
+ displayName: mapping[contentType].displayName,
351
+ searchableField: mapping[contentType].searchableField,
352
+ results: contents
353
+ };
354
+ });
355
+ });
356
+ return Promise.all(promises);
357
+ },
358
+ validateRelations: async function(ctx) {
359
+ const contentTypes2 = strapi2.contentTypes;
360
+ const body = ctx.request.body;
361
+ const entries = body.entries;
362
+ const promises = entries.map((entry) => {
363
+ return strapi2.documents(entry.uid).findOne({
364
+ documentId: entry.documentId,
365
+ populate: "*",
366
+ status: "published"
367
+ }).then((result) => {
368
+ return {
369
+ uid: entry.uid,
370
+ result
371
+ };
372
+ });
373
+ });
374
+ const responses = await Promise.all(promises);
375
+ return responses.map((response) => {
376
+ return {
377
+ displayName: contentTypes2[response.uid].info.displayName,
378
+ uid: response.uid,
379
+ searchableField: strapi2.plugin("multi-content-type-relation").service("service").getFirstStringFieldInContentType(contentTypes2[response.uid]),
380
+ item: response.result
381
+ };
382
+ }).filter((entry) => entry.item);
383
+ },
384
+ listContentTypes: async function() {
385
+ const contentTypes2 = [];
386
+ for (const contentType of Object.values(strapi2.contentTypes)) {
387
+ if ((contentType.kind === "collectionType" || contentType.kind === "singleType") && !contentType.plugin) {
388
+ contentTypes2.push(contentType);
389
+ }
390
+ }
391
+ return contentTypes2;
392
+ },
393
+ fetchRevertRelations: async function(ctx) {
394
+ const body = ctx.request.body;
395
+ let documentId = body.documentId;
396
+ const uid = body.uid;
397
+ const isSingleType = body.isSingleType;
398
+ if (isSingleType) {
399
+ const document = await strapi2.documents(uid).findFirst({
400
+ populate: "*",
401
+ status: "published"
402
+ });
403
+ if (!document) return [];
404
+ documentId = document.documentId;
405
+ }
406
+ const mctrRelations = await strapi2.documents("plugin::multi-content-type-relation.mctr-relation").findMany({
407
+ filters: {
408
+ target: {
409
+ $containsi: `${uid}##${documentId}`
410
+ }
411
+ }
412
+ });
413
+ const relations = await Promise.all(
414
+ mctrRelations.map(async (relation) => {
415
+ const sourceDocumentId = relation.sourceDocId;
416
+ const sourceUid = relation.sourceUID;
417
+ const target = relation.target.find(
418
+ (target2) => target2.includes(`${uid}##${documentId}`)
419
+ );
420
+ const [field] = target.split("##");
421
+ const contentTypeName = Object.keys(strapi2.contentTypes).find(
422
+ (key) => strapi2.contentTypes[key].uid === sourceUid
423
+ );
424
+ if (!contentTypeName) return null;
425
+ const contentType = strapi2.contentTypes[contentTypeName];
426
+ const document = await strapi2.documents(sourceUid).findOne({
427
+ documentId: sourceDocumentId,
428
+ populate: "*",
429
+ status: "published"
430
+ });
431
+ const searchableField = strapi2.plugin("multi-content-type-relation").service("service").getFirstStringFieldInContentType(contentType);
432
+ return {
433
+ title: document[searchableField],
434
+ uid: sourceUid,
435
+ isSingleType: contentType.kind === "singleType",
436
+ field,
437
+ type: contentType.info.displayName,
438
+ documentId: sourceDocumentId
439
+ };
440
+ })
441
+ );
442
+ return relations;
443
+ }
444
+ });
445
+ const controllers = {
446
+ controller
447
+ };
448
+ const policies = {};
449
+ const routes = [
450
+ {
451
+ method: "GET",
452
+ path: "/list-content-types",
453
+ handler: "controller.listContentTypes",
454
+ config: {
455
+ policies: [],
456
+ auth: false
457
+ }
458
+ },
459
+ {
460
+ method: "POST",
461
+ path: "/get-content",
462
+ handler: "controller.getMatchingContent",
463
+ config: {
464
+ policies: []
465
+ }
466
+ },
467
+ {
468
+ method: "POST",
469
+ path: "/validate-relations",
470
+ handler: "controller.validateRelations",
471
+ config: {
472
+ policies: []
473
+ }
474
+ },
475
+ {
476
+ method: "POST",
477
+ path: "/fetch-revert-relations",
478
+ handler: "controller.fetchRevertRelations",
479
+ config: {
480
+ policies: []
481
+ }
482
+ }
483
+ ];
484
+ const service = ({ strapi: strapi2 }) => ({
485
+ getFirstStringFieldInContentType(contentType) {
486
+ const result = Object.keys(contentType.attributes).find(
487
+ (attribute) => contentType.attributes[attribute].type === "string"
488
+ );
489
+ return result;
490
+ }
491
+ });
492
+ const services = {
493
+ service
494
+ };
495
+ const index = {
496
+ register,
497
+ bootstrap,
498
+ destroy,
499
+ config,
500
+ controllers,
501
+ routes,
502
+ services,
503
+ contentTypes,
504
+ policies,
505
+ middlewares
506
+ };
507
+ export {
508
+ index as default
509
+ };
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ declare const bootstrap: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default bootstrap;
@@ -0,0 +1,13 @@
1
+ declare const _default: {
2
+ default: ({ env }: {
3
+ env: any;
4
+ }) => {
5
+ recursive: {
6
+ enabled: boolean;
7
+ maxDepth: number;
8
+ };
9
+ debug: boolean;
10
+ };
11
+ validator(config: any): void;
12
+ };
13
+ export default _default;
@@ -0,0 +1,35 @@
1
+ declare const _default: {
2
+ 'mctr-relation': {
3
+ schema: {
4
+ collectionName: string;
5
+ info: {
6
+ singularName: string;
7
+ pluralName: string;
8
+ displayName: string;
9
+ name: string;
10
+ };
11
+ pluginOptions: {
12
+ 'content-manager': {
13
+ visible: boolean;
14
+ };
15
+ 'content-type-builder': {
16
+ visible: boolean;
17
+ };
18
+ };
19
+ attributes: {
20
+ sourceUID: {
21
+ type: string;
22
+ required: boolean;
23
+ };
24
+ sourceDocId: {
25
+ type: string;
26
+ required: boolean;
27
+ };
28
+ target: {
29
+ type: string;
30
+ };
31
+ };
32
+ };
33
+ };
34
+ };
35
+ export default _default;
@@ -0,0 +1,33 @@
1
+ declare const _default: {
2
+ schema: {
3
+ collectionName: string;
4
+ info: {
5
+ singularName: string;
6
+ pluralName: string;
7
+ displayName: string;
8
+ name: string;
9
+ };
10
+ pluginOptions: {
11
+ 'content-manager': {
12
+ visible: boolean;
13
+ };
14
+ 'content-type-builder': {
15
+ visible: boolean;
16
+ };
17
+ };
18
+ attributes: {
19
+ sourceUID: {
20
+ type: string;
21
+ required: boolean;
22
+ };
23
+ sourceDocId: {
24
+ type: string;
25
+ required: boolean;
26
+ };
27
+ target: {
28
+ type: string;
29
+ };
30
+ };
31
+ };
32
+ };
33
+ export default _default;
@@ -0,0 +1,31 @@
1
+ declare const _default: {
2
+ collectionName: string;
3
+ info: {
4
+ singularName: string;
5
+ pluralName: string;
6
+ displayName: string;
7
+ name: string;
8
+ };
9
+ pluginOptions: {
10
+ 'content-manager': {
11
+ visible: boolean;
12
+ };
13
+ 'content-type-builder': {
14
+ visible: boolean;
15
+ };
16
+ };
17
+ attributes: {
18
+ sourceUID: {
19
+ type: string;
20
+ required: boolean;
21
+ };
22
+ sourceDocId: {
23
+ type: string;
24
+ required: boolean;
25
+ };
26
+ target: {
27
+ type: string;
28
+ };
29
+ };
30
+ };
31
+ export default _default;
@@ -0,0 +1,27 @@
1
+ import type { Core, UID } from '@strapi/strapi';
2
+ declare const _default: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => {
5
+ getMatchingContent(ctx: any): Promise<{
6
+ uid: UID.ContentType;
7
+ displayName: string;
8
+ searchableField: string;
9
+ results: import("@strapi/types/dist/modules/documents").AnyDocument[];
10
+ }[]>;
11
+ validateRelations: (ctx: any) => Promise<{
12
+ displayName: any;
13
+ uid: string;
14
+ searchableField: any;
15
+ item: import("@strapi/types/dist/modules/documents").AnyDocument;
16
+ }[]>;
17
+ listContentTypes: () => Promise<Record<string, unknown>[]>;
18
+ fetchRevertRelations: (ctx: any) => Promise<{
19
+ title: any;
20
+ uid: any;
21
+ isSingleType: boolean;
22
+ field: any;
23
+ type: any;
24
+ documentId: any;
25
+ }[]>;
26
+ };
27
+ export default _default;
@@ -0,0 +1,28 @@
1
+ declare const _default: {
2
+ controller: ({ strapi }: {
3
+ strapi: import("@strapi/types/dist/core").Strapi;
4
+ }) => {
5
+ getMatchingContent(ctx: any): Promise<{
6
+ uid: import("@strapi/types/dist/uid").ContentType;
7
+ displayName: string;
8
+ searchableField: string;
9
+ results: import("@strapi/types/dist/modules/documents").AnyDocument[];
10
+ }[]>;
11
+ validateRelations: (ctx: any) => Promise<{
12
+ displayName: any;
13
+ uid: string;
14
+ searchableField: any;
15
+ item: import("@strapi/types/dist/modules/documents").AnyDocument;
16
+ }[]>;
17
+ listContentTypes: () => Promise<Record<string, unknown>[]>;
18
+ fetchRevertRelations: (ctx: any) => Promise<{
19
+ title: any;
20
+ uid: any;
21
+ isSingleType: boolean;
22
+ field: any;
23
+ type: any;
24
+ documentId: any;
25
+ }[]>;
26
+ };
27
+ };
28
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import type { Core } from '@strapi/strapi';
2
+ declare const destroy: ({ strapi }: {
3
+ strapi: Core.Strapi;
4
+ }) => void;
5
+ export default destroy;
@@ -0,0 +1,2 @@
1
+ export declare const flattenObj: (obj: any, parent: any, res?: Record<string, any>) => Record<string, any>;
2
+ export declare const unflatten: (data: any) => {};