@strapi/content-type-builder 5.17.0 → 5.18.0
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/admin/components/DataManager/DataManagerProvider.js +5 -0
- package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
- package/dist/admin/components/DataManager/DataManagerProvider.mjs +6 -1
- package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
- package/dist/admin/components/DataManager/utils/cleanData.js +5 -1
- package/dist/admin/components/DataManager/utils/cleanData.js.map +1 -1
- package/dist/admin/components/DataManager/utils/cleanData.mjs +5 -1
- package/dist/admin/components/DataManager/utils/cleanData.mjs.map +1 -1
- package/dist/admin/components/FormModal/FormModal.js +16 -1
- package/dist/admin/components/FormModal/FormModal.js.map +1 -1
- package/dist/admin/components/FormModal/FormModal.mjs +16 -1
- package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
- package/dist/admin/pages/ListView/EmptyState.js +27 -19
- package/dist/admin/pages/ListView/EmptyState.js.map +1 -1
- package/dist/admin/pages/ListView/EmptyState.mjs +29 -21
- package/dist/admin/pages/ListView/EmptyState.mjs.map +1 -1
- package/dist/admin/src/types.d.ts +3 -0
- package/dist/server/controllers/schema.js +2 -1
- package/dist/server/controllers/schema.js.map +1 -1
- package/dist/server/controllers/schema.mjs +2 -1
- package/dist/server/controllers/schema.mjs.map +1 -1
- package/dist/server/services/schema-builder/content-type-builder.js +67 -33
- package/dist/server/services/schema-builder/content-type-builder.js.map +1 -1
- package/dist/server/services/schema-builder/content-type-builder.mjs +67 -33
- package/dist/server/services/schema-builder/content-type-builder.mjs.map +1 -1
- package/dist/server/services/schema-builder/index.js +6 -2
- package/dist/server/services/schema-builder/index.js.map +1 -1
- package/dist/server/services/schema-builder/index.mjs +6 -2
- package/dist/server/services/schema-builder/index.mjs.map +1 -1
- package/dist/server/services/schema.js +5 -1
- package/dist/server/services/schema.js.map +1 -1
- package/dist/server/services/schema.mjs +5 -1
- package/dist/server/services/schema.mjs.map +1 -1
- package/dist/server/src/controllers/schema.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/content-type-builder.d.ts +8 -2
- package/dist/server/src/services/schema-builder/content-type-builder.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/index.d.ts +6 -2
- package/dist/server/src/services/schema-builder/index.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/types.d.ts +23 -0
- package/dist/server/src/services/schema-builder/types.d.ts.map +1 -0
- package/dist/server/src/services/schema.d.ts +240 -240
- package/dist/server/src/services/schema.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.mjs","sources":["../../../server/src/controllers/schema.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { isEmpty } from 'lodash/fp';\n\nimport { getService } from '../utils';\nimport { validateUpdateSchema } from './validation/schema';\n\nexport default () => {\n const internals = {\n isUpdating: false,\n };\n\n return {\n async getSchema(ctx: Context) {\n const schema = await getService('schema').getSchema();\n\n ctx.send({ data: schema });\n },\n\n async updateSchema(ctx: Context) {\n if (internals.isUpdating === true) {\n return ctx.conflict('Schema update is already in progress.');\n }\n\n try {\n const { data } = await validateUpdateSchema(ctx.request.body);\n\n if (isEmpty(data.components) && isEmpty(data.contentTypes)) {\n ctx.body = {};\n return;\n }\n\n internals.isUpdating = true;\n strapi.reload.isWatching = false;\n\n await getService('schema').updateSchema(data);\n\n // NOTE: we do not set isUpdating to false here.\n // We want to wait for the server to restart to get the isUpdate = false only\n setImmediate(() => {\n strapi.reload();\n });\n\n ctx.body = {};\n } catch (error) {\n internals.isUpdating = false;\n return ctx.send({ error }, 400);\n }\n },\n\n async getUpdateSchemaStatus(ctx: Context) {\n ctx.send({ data: { isUpdating: internals.isUpdating } });\n },\n };\n};\n"],"names":["internals","isUpdating","getSchema","ctx","schema","getService","send","data","updateSchema","conflict","validateUpdateSchema","request","body","isEmpty","components","contentTypes","strapi","reload","isWatching","setImmediate","error","getUpdateSchemaStatus"],"mappings":";;;;AAMA,aAAe,CAAA,IAAA;AACb,IAAA,MAAMA,SAAY,GAAA;QAChBC,UAAY,EAAA;AACd,KAAA;IAEA,OAAO;AACL,QAAA,MAAMC,WAAUC,GAAY,EAAA;AAC1B,YAAA,MAAMC,MAAS,GAAA,MAAMC,UAAW,CAAA,QAAA,CAAA,CAAUH,SAAS,EAAA;AAEnDC,YAAAA,GAAAA,CAAIG,IAAI,CAAC;gBAAEC,IAAMH,EAAAA;AAAO,aAAA,CAAA;AAC1B,SAAA;AAEA,QAAA,MAAMI,cAAaL,GAAY,EAAA;YAC7B,IAAIH,SAAAA,CAAUC,UAAU,KAAK,IAAM,EAAA;gBACjC,OAAOE,GAAAA,CAAIM,QAAQ,CAAC,uCAAA,CAAA;AACtB;YAEA,IAAI;gBACF,MAAM,EAAEF,IAAI,EAAE,GAAG,MAAMG,oBAAqBP,CAAAA,GAAAA,CAAIQ,OAAO,CAACC,IAAI,CAAA;AAE5D,gBAAA,IAAIC,QAAQN,IAAKO,CAAAA,UAAU,KAAKD,OAAQN,CAAAA,IAAAA,CAAKQ,YAAY,CAAG,EAAA;oBAC1DZ,GAAIS,CAAAA,IAAI,GAAG,EAAC;AACZ,oBAAA;AACF;AAEAZ,gBAAAA,SAAAA,CAAUC,UAAU,GAAG,IAAA;gBACvBe,MAAOC,CAAAA,MAAM,CAACC,UAAU,GAAG,KAAA;gBAE3B,MAAMb,UAAAA,CAAW,QAAUG,CAAAA,CAAAA,YAAY,CAACD,IAAAA,CAAAA;;;gBAIxCY,YAAa,CAAA,IAAA;AACXH,oBAAAA,MAAAA,CAAOC,MAAM,EAAA;AACf,iBAAA,CAAA;gBAEAd,GAAIS,CAAAA,IAAI,GAAG,EAAC;AACd,aAAA,CAAE,OAAOQ,KAAO,EAAA;AACdpB,gBAAAA,SAAAA,CAAUC,UAAU,GAAG,KAAA;
|
|
1
|
+
{"version":3,"file":"schema.mjs","sources":["../../../server/src/controllers/schema.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport { isEmpty } from 'lodash/fp';\n\nimport { getService } from '../utils';\nimport { validateUpdateSchema } from './validation/schema';\n\nexport default () => {\n const internals = {\n isUpdating: false,\n };\n\n return {\n async getSchema(ctx: Context) {\n const schema = await getService('schema').getSchema();\n\n ctx.send({ data: schema });\n },\n\n async updateSchema(ctx: Context) {\n if (internals.isUpdating === true) {\n return ctx.conflict('Schema update is already in progress.');\n }\n\n try {\n const { data } = await validateUpdateSchema(ctx.request.body);\n\n if (isEmpty(data.components) && isEmpty(data.contentTypes)) {\n ctx.body = {};\n return;\n }\n\n internals.isUpdating = true;\n strapi.reload.isWatching = false;\n\n await getService('schema').updateSchema(data);\n\n // NOTE: we do not set isUpdating to false here.\n // We want to wait for the server to restart to get the isUpdate = false only\n setImmediate(() => {\n strapi.reload();\n });\n\n ctx.body = {};\n } catch (error) {\n internals.isUpdating = false;\n const errorMessage = error instanceof Error ? error.message : String(error);\n return ctx.send({ error: errorMessage }, 400);\n }\n },\n\n async getUpdateSchemaStatus(ctx: Context) {\n ctx.send({ data: { isUpdating: internals.isUpdating } });\n },\n };\n};\n"],"names":["internals","isUpdating","getSchema","ctx","schema","getService","send","data","updateSchema","conflict","validateUpdateSchema","request","body","isEmpty","components","contentTypes","strapi","reload","isWatching","setImmediate","error","errorMessage","Error","message","String","getUpdateSchemaStatus"],"mappings":";;;;AAMA,aAAe,CAAA,IAAA;AACb,IAAA,MAAMA,SAAY,GAAA;QAChBC,UAAY,EAAA;AACd,KAAA;IAEA,OAAO;AACL,QAAA,MAAMC,WAAUC,GAAY,EAAA;AAC1B,YAAA,MAAMC,MAAS,GAAA,MAAMC,UAAW,CAAA,QAAA,CAAA,CAAUH,SAAS,EAAA;AAEnDC,YAAAA,GAAAA,CAAIG,IAAI,CAAC;gBAAEC,IAAMH,EAAAA;AAAO,aAAA,CAAA;AAC1B,SAAA;AAEA,QAAA,MAAMI,cAAaL,GAAY,EAAA;YAC7B,IAAIH,SAAAA,CAAUC,UAAU,KAAK,IAAM,EAAA;gBACjC,OAAOE,GAAAA,CAAIM,QAAQ,CAAC,uCAAA,CAAA;AACtB;YAEA,IAAI;gBACF,MAAM,EAAEF,IAAI,EAAE,GAAG,MAAMG,oBAAqBP,CAAAA,GAAAA,CAAIQ,OAAO,CAACC,IAAI,CAAA;AAE5D,gBAAA,IAAIC,QAAQN,IAAKO,CAAAA,UAAU,KAAKD,OAAQN,CAAAA,IAAAA,CAAKQ,YAAY,CAAG,EAAA;oBAC1DZ,GAAIS,CAAAA,IAAI,GAAG,EAAC;AACZ,oBAAA;AACF;AAEAZ,gBAAAA,SAAAA,CAAUC,UAAU,GAAG,IAAA;gBACvBe,MAAOC,CAAAA,MAAM,CAACC,UAAU,GAAG,KAAA;gBAE3B,MAAMb,UAAAA,CAAW,QAAUG,CAAAA,CAAAA,YAAY,CAACD,IAAAA,CAAAA;;;gBAIxCY,YAAa,CAAA,IAAA;AACXH,oBAAAA,MAAAA,CAAOC,MAAM,EAAA;AACf,iBAAA,CAAA;gBAEAd,GAAIS,CAAAA,IAAI,GAAG,EAAC;AACd,aAAA,CAAE,OAAOQ,KAAO,EAAA;AACdpB,gBAAAA,SAAAA,CAAUC,UAAU,GAAG,KAAA;AACvB,gBAAA,MAAMoB,eAAeD,KAAiBE,YAAAA,KAAAA,GAAQF,KAAMG,CAAAA,OAAO,GAAGC,MAAOJ,CAAAA,KAAAA,CAAAA;gBACrE,OAAOjB,GAAAA,CAAIG,IAAI,CAAC;oBAAEc,KAAOC,EAAAA;iBAAgB,EAAA,GAAA,CAAA;AAC3C;AACF,SAAA;AAEA,QAAA,MAAMI,uBAAsBtB,GAAY,EAAA;AACtCA,YAAAA,GAAAA,CAAIG,IAAI,CAAC;gBAAEC,IAAM,EAAA;AAAEN,oBAAAA,UAAAA,EAAYD,UAAUC;AAAW;AAAE,aAAA,CAAA;AACxD;AACF,KAAA;AACF,CAAA;;;;"}
|
|
@@ -16,7 +16,8 @@ const reuseUnsetPreviousProperties = (newAttribute, oldAttribute)=>{
|
|
|
16
16
|
'unique',
|
|
17
17
|
'pluginOptions',
|
|
18
18
|
'inversedBy',
|
|
19
|
-
'mappedBy'
|
|
19
|
+
'mappedBy',
|
|
20
|
+
'conditions'
|
|
20
21
|
]));
|
|
21
22
|
};
|
|
22
23
|
function createComponentBuilder() {
|
|
@@ -33,19 +34,24 @@ function createComponentBuilder() {
|
|
|
33
34
|
if (!attribute.targetAttribute) {
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
37
|
+
// When generating the inverse relation, preserve existing conditions if they exist
|
|
38
|
+
// If the target attribute already exists and has conditions, preserve them
|
|
39
|
+
const targetAttributeData = targetAttribute || {};
|
|
40
|
+
// If the source doesn't have conditions but the target does, preserve target's conditions
|
|
36
41
|
targetCT.setAttribute(attribute.targetAttribute, generateRelation({
|
|
37
42
|
key,
|
|
38
43
|
attribute,
|
|
39
44
|
uid,
|
|
40
|
-
targetAttribute
|
|
45
|
+
targetAttribute: targetAttributeData
|
|
41
46
|
}));
|
|
42
47
|
},
|
|
43
48
|
unsetRelation (attribute) {
|
|
44
|
-
if (!
|
|
49
|
+
if (!('target' in attribute) || !attribute.target) {
|
|
45
50
|
return;
|
|
46
51
|
}
|
|
47
52
|
const targetCT = this.contentTypes.get(attribute.target);
|
|
48
|
-
const
|
|
53
|
+
const relationAttribute = attribute;
|
|
54
|
+
const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;
|
|
49
55
|
const targetAttribute = targetCT.getAttribute(targetAttributeName);
|
|
50
56
|
if (!targetAttribute) return;
|
|
51
57
|
return targetCT.deleteAttribute(targetAttributeName);
|
|
@@ -66,26 +72,27 @@ function createComponentBuilder() {
|
|
|
66
72
|
Object.keys(attributes$1).forEach((key)=>{
|
|
67
73
|
const attribute = attributes$1[key];
|
|
68
74
|
if (attributes.isRelation(attribute)) {
|
|
75
|
+
const relationAttribute = attribute;
|
|
69
76
|
if ([
|
|
70
77
|
'manyToMany',
|
|
71
78
|
'oneToOne'
|
|
72
|
-
].includes(
|
|
73
|
-
if (
|
|
79
|
+
].includes(relationAttribute.relation)) {
|
|
80
|
+
if (relationAttribute.target === uid && relationAttribute.targetAttribute !== undefined) {
|
|
74
81
|
// self referencing relation
|
|
75
|
-
const targetAttribute = attributes$1[
|
|
82
|
+
const targetAttribute = attributes$1[relationAttribute.targetAttribute];
|
|
76
83
|
if (targetAttribute.dominant === undefined) {
|
|
77
|
-
|
|
84
|
+
relationAttribute.dominant = true;
|
|
78
85
|
} else {
|
|
79
|
-
|
|
86
|
+
relationAttribute.dominant = false;
|
|
80
87
|
}
|
|
81
88
|
} else {
|
|
82
|
-
|
|
89
|
+
relationAttribute.dominant = true;
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
92
|
this.setRelation({
|
|
86
93
|
key,
|
|
87
94
|
uid,
|
|
88
|
-
attribute
|
|
95
|
+
attribute: relationAttribute
|
|
89
96
|
});
|
|
90
97
|
}
|
|
91
98
|
});
|
|
@@ -136,10 +143,13 @@ function createComponentBuilder() {
|
|
|
136
143
|
// remove old relations
|
|
137
144
|
deletedKeys.forEach((key)=>{
|
|
138
145
|
const attribute = oldAttributes[key];
|
|
139
|
-
const targetAttributeName = attribute.inversedBy || attribute.mappedBy;
|
|
140
146
|
// if the old relation has a target attribute. we need to remove it in the target type
|
|
141
|
-
if (attributes.isConfigurable(attribute) && attributes.isRelation(attribute)
|
|
142
|
-
|
|
147
|
+
if (attributes.isConfigurable(attribute) && attributes.isRelation(attribute)) {
|
|
148
|
+
const relationAttribute = attribute;
|
|
149
|
+
const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;
|
|
150
|
+
if (targetAttributeName !== null && targetAttributeName !== undefined) {
|
|
151
|
+
this.unsetRelation(attribute);
|
|
152
|
+
}
|
|
143
153
|
}
|
|
144
154
|
});
|
|
145
155
|
remainingKeys.forEach((key)=>{
|
|
@@ -149,30 +159,47 @@ function createComponentBuilder() {
|
|
|
149
159
|
return this.setRelation({
|
|
150
160
|
key,
|
|
151
161
|
uid,
|
|
152
|
-
attribute:
|
|
162
|
+
attribute: newAttribute
|
|
153
163
|
});
|
|
154
164
|
}
|
|
155
165
|
if (attributes.isRelation(oldAttribute) && !attributes.isRelation(newAttribute)) {
|
|
156
166
|
return this.unsetRelation(oldAttribute);
|
|
157
167
|
}
|
|
158
168
|
if (attributes.isRelation(oldAttribute) && attributes.isRelation(newAttribute)) {
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
const
|
|
169
|
+
const relationAttribute = newAttribute;
|
|
170
|
+
const oldRelationAttribute = oldAttribute;
|
|
171
|
+
const oldTargetAttributeName = oldRelationAttribute.inversedBy || oldRelationAttribute.mappedBy;
|
|
172
|
+
const sameRelation = oldAttribute.relation === relationAttribute.relation;
|
|
173
|
+
const targetAttributeHasChanged = oldTargetAttributeName !== relationAttribute.targetAttribute;
|
|
162
174
|
if (!sameRelation || targetAttributeHasChanged) {
|
|
163
175
|
this.unsetRelation(oldAttribute);
|
|
164
176
|
}
|
|
165
177
|
// keep extra options that were set manually on oldAttribute
|
|
166
|
-
reuseUnsetPreviousProperties(
|
|
167
|
-
if
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
178
|
+
reuseUnsetPreviousProperties(relationAttribute, oldAttribute);
|
|
179
|
+
// Handle conditions explicitly - only preserve if present and not undefined in new attribute
|
|
180
|
+
const newAttributeFromInfos = newAttributes[key];
|
|
181
|
+
const hasNewConditions = newAttributeFromInfos.conditions !== undefined && newAttributeFromInfos.conditions !== null;
|
|
182
|
+
if (oldAttribute.conditions) {
|
|
183
|
+
if (hasNewConditions) {
|
|
184
|
+
// Conditions are still present, keep them
|
|
185
|
+
relationAttribute.conditions = newAttributeFromInfos.conditions;
|
|
186
|
+
} else {
|
|
187
|
+
// Conditions were removed (undefined or null), ensure they're not preserved
|
|
188
|
+
delete relationAttribute.conditions;
|
|
189
|
+
}
|
|
190
|
+
} else if (hasNewConditions) {
|
|
191
|
+
// New conditions added
|
|
192
|
+
relationAttribute.conditions = newAttributeFromInfos.conditions;
|
|
193
|
+
}
|
|
194
|
+
if (oldRelationAttribute.inversedBy) {
|
|
195
|
+
relationAttribute.dominant = true;
|
|
196
|
+
} else if (oldRelationAttribute.mappedBy) {
|
|
197
|
+
relationAttribute.dominant = false;
|
|
171
198
|
}
|
|
172
199
|
return this.setRelation({
|
|
173
200
|
key,
|
|
174
201
|
uid,
|
|
175
|
-
attribute:
|
|
202
|
+
attribute: relationAttribute
|
|
176
203
|
});
|
|
177
204
|
}
|
|
178
205
|
});
|
|
@@ -180,26 +207,27 @@ function createComponentBuilder() {
|
|
|
180
207
|
newKeys.forEach((key)=>{
|
|
181
208
|
const attribute = newAttributes[key];
|
|
182
209
|
if (attributes.isRelation(attribute)) {
|
|
210
|
+
const relationAttribute = attribute;
|
|
183
211
|
if ([
|
|
184
212
|
'manyToMany',
|
|
185
213
|
'oneToOne'
|
|
186
|
-
].includes(
|
|
187
|
-
if (
|
|
214
|
+
].includes(relationAttribute.relation)) {
|
|
215
|
+
if (relationAttribute.target === uid && relationAttribute.targetAttribute !== undefined) {
|
|
188
216
|
// self referencing relation
|
|
189
|
-
const targetAttribute = newAttributes[
|
|
217
|
+
const targetAttribute = newAttributes[relationAttribute.targetAttribute];
|
|
190
218
|
if (targetAttribute.dominant === undefined) {
|
|
191
|
-
|
|
219
|
+
relationAttribute.dominant = true;
|
|
192
220
|
} else {
|
|
193
|
-
|
|
221
|
+
relationAttribute.dominant = false;
|
|
194
222
|
}
|
|
195
223
|
} else {
|
|
196
|
-
|
|
224
|
+
relationAttribute.dominant = true;
|
|
197
225
|
}
|
|
198
226
|
}
|
|
199
227
|
this.setRelation({
|
|
200
228
|
key,
|
|
201
229
|
uid,
|
|
202
|
-
attribute
|
|
230
|
+
attribute: relationAttribute
|
|
203
231
|
});
|
|
204
232
|
}
|
|
205
233
|
});
|
|
@@ -241,7 +269,12 @@ const generateRelation = ({ key, attribute, uid, targetAttribute = {} })=>{
|
|
|
241
269
|
type: 'relation',
|
|
242
270
|
target: uid,
|
|
243
271
|
private: targetAttribute.private || undefined,
|
|
244
|
-
pluginOptions: targetAttribute.pluginOptions || undefined
|
|
272
|
+
pluginOptions: targetAttribute.pluginOptions || undefined,
|
|
273
|
+
// Preserve conditions from targetAttribute if they exist
|
|
274
|
+
// This allows each side of the relation to maintain its own conditions
|
|
275
|
+
...targetAttribute.conditions && {
|
|
276
|
+
conditions: targetAttribute.conditions
|
|
277
|
+
}
|
|
245
278
|
};
|
|
246
279
|
switch(attribute.relation){
|
|
247
280
|
case 'oneToOne':
|
|
@@ -279,12 +312,13 @@ const generateRelation = ({ key, attribute, uid, targetAttribute = {} })=>{
|
|
|
279
312
|
}
|
|
280
313
|
// we do this just to make sure we have the same key order when writing to files
|
|
281
314
|
const { type, relation, target, ...restOptions } = opts;
|
|
282
|
-
|
|
315
|
+
const result = {
|
|
283
316
|
type,
|
|
284
317
|
relation,
|
|
285
318
|
target,
|
|
286
319
|
...restOptions
|
|
287
320
|
};
|
|
321
|
+
return result;
|
|
288
322
|
};
|
|
289
323
|
|
|
290
324
|
module.exports = createComponentBuilder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-type-builder.js","sources":["../../../../server/src/services/schema-builder/content-type-builder.ts"],"sourcesContent":["import path from 'path';\nimport _ from 'lodash';\n\nimport { strings, errors } from '@strapi/utils';\nimport type { Schema, Internal } from '@strapi/types';\nimport { isRelation, isConfigurable } from '../../utils/attributes';\nimport { typeKinds } from '../constants';\nimport createSchemaHandler from './schema-handler';\nimport { CreateContentTypeInput } from '../../controllers/validation/content-type';\n\nconst { ApplicationError } = errors;\n\nconst reuseUnsetPreviousProperties = (\n newAttribute: Schema.Attribute.AnyAttribute,\n oldAttribute: Schema.Attribute.AnyAttribute\n) => {\n _.defaults(\n newAttribute,\n _.omit(oldAttribute, [\n 'configurable',\n 'required',\n 'private',\n 'unique',\n 'pluginOptions',\n 'inversedBy',\n 'mappedBy',\n ])\n );\n};\n\nexport default function createComponentBuilder() {\n return {\n setRelation(this: any, { key, uid, attribute }: any) {\n if (!_.has(attribute, 'target')) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n if (!targetCT) {\n throw new ApplicationError(`Content type ${attribute.target} not found`);\n }\n\n const targetAttribute = targetCT.getAttribute(attribute.targetAttribute);\n\n if (!attribute.targetAttribute) {\n return;\n }\n\n targetCT.setAttribute(\n attribute.targetAttribute,\n generateRelation({ key, attribute, uid, targetAttribute })\n );\n },\n\n unsetRelation(this: any, attribute: any) {\n if (!_.has(attribute, 'target')) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n const targetAttributeName = attribute.inversedBy || attribute.mappedBy;\n const targetAttribute = targetCT.getAttribute(targetAttributeName);\n\n if (!targetAttribute) return;\n\n return targetCT.deleteAttribute(targetAttributeName);\n },\n\n createContentTypeAttributes(\n this: any,\n uid: string,\n attributes: CreateContentTypeInput['attributes']\n ) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n // support self referencing content type relation\n Object.keys(attributes).forEach((key) => {\n const { target } = attributes[key];\n if (target === '__self__') {\n attributes[key].target = uid;\n }\n });\n\n contentType.setAttributes(this.convertAttributes(attributes));\n\n Object.keys(attributes).forEach((key) => {\n const attribute = attributes[key];\n\n if (isRelation(attribute)) {\n if (['manyToMany', 'oneToOne'].includes(attribute.relation)) {\n if (attribute.target === uid && attribute.targetAttribute !== undefined) {\n // self referencing relation\n const targetAttribute = attributes[attribute.targetAttribute];\n\n if (targetAttribute.dominant === undefined) {\n attribute.dominant = true;\n } else {\n attribute.dominant = false;\n }\n } else {\n attribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute,\n });\n }\n });\n\n return contentType;\n },\n\n /**\n * Creates a content type in memory to be written to files later on\n */\n createContentType(this: any, infos: CreateContentTypeInput) {\n // TODO:: check for unique uid / singularName & pluralName & collectionName\n\n if (infos.uid && infos.uid !== createContentTypeUID(infos)) {\n throw new ApplicationError('contentType.invalidUID');\n }\n\n const uid = infos.uid ?? createContentTypeUID(infos);\n\n if (this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.alreadyExists');\n }\n\n const contentType = createSchemaHandler({\n modelName: infos.singularName,\n dir: path.join(\n strapi.dirs.app.api,\n infos.singularName,\n 'content-types',\n infos.singularName\n ),\n filename: `schema.json`,\n });\n\n this.contentTypes.set(uid, contentType);\n\n contentType\n .setUID(uid)\n .set('kind', infos.kind || typeKinds.COLLECTION_TYPE)\n .set(\n 'collectionName',\n infos.collectionName || strings.nameToCollectionName(infos.pluralName)\n )\n .set('info', {\n singularName: infos.singularName,\n pluralName: infos.pluralName,\n displayName: infos.displayName,\n description: infos.description,\n })\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .set('config', infos.config);\n\n this.createContentTypeAttributes(uid, infos.attributes);\n\n return contentType;\n },\n\n editContentType(this: any, infos: any) {\n const { uid } = infos;\n\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n const oldAttributes = contentType.schema.attributes;\n\n const newAttributes = _.omitBy(infos.attributes, (attr, key) => {\n return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);\n });\n\n const newKeys = _.difference(Object.keys(newAttributes), Object.keys(oldAttributes));\n const deletedKeys = _.difference(Object.keys(oldAttributes), Object.keys(newAttributes));\n const remainingKeys = _.intersection(Object.keys(oldAttributes), Object.keys(newAttributes));\n\n // remove old relations\n deletedKeys.forEach((key) => {\n const attribute = oldAttributes[key];\n\n const targetAttributeName = attribute.inversedBy || attribute.mappedBy;\n\n // if the old relation has a target attribute. we need to remove it in the target type\n if (isConfigurable(attribute) && isRelation(attribute) && !_.isNil(targetAttributeName)) {\n this.unsetRelation(attribute);\n }\n });\n\n remainingKeys.forEach((key) => {\n const oldAttribute = oldAttributes[key];\n const newAttribute = newAttributes[key];\n\n if (!isRelation(oldAttribute) && isRelation(newAttribute)) {\n return this.setRelation({\n key,\n uid,\n attribute: newAttributes[key],\n });\n }\n\n if (isRelation(oldAttribute) && !isRelation(newAttribute)) {\n return this.unsetRelation(oldAttribute);\n }\n\n if (isRelation(oldAttribute) && isRelation(newAttribute)) {\n const oldTargetAttributeName = oldAttribute.inversedBy || oldAttribute.mappedBy;\n\n const sameRelation = oldAttribute.relation === newAttribute.relation;\n const targetAttributeHasChanged = oldTargetAttributeName !== newAttribute.targetAttribute;\n\n if (!sameRelation || targetAttributeHasChanged) {\n this.unsetRelation(oldAttribute);\n }\n\n // keep extra options that were set manually on oldAttribute\n reuseUnsetPreviousProperties(newAttribute, oldAttribute);\n\n if (oldAttribute.inversedBy) {\n newAttribute.dominant = true;\n } else if (oldAttribute.mappedBy) {\n newAttribute.dominant = false;\n }\n\n return this.setRelation({\n key,\n uid,\n attribute: newAttribute,\n });\n }\n });\n\n // add new relations\n newKeys.forEach((key) => {\n const attribute = newAttributes[key];\n\n if (isRelation(attribute)) {\n if (['manyToMany', 'oneToOne'].includes(attribute.relation)) {\n if (attribute.target === uid && attribute.targetAttribute !== undefined) {\n // self referencing relation\n const targetAttribute = newAttributes[attribute.targetAttribute];\n\n if (targetAttribute.dominant === undefined) {\n attribute.dominant = true;\n } else {\n attribute.dominant = false;\n }\n } else {\n attribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute,\n });\n }\n });\n\n contentType\n .set('kind', infos.kind || contentType.schema.kind)\n .set(['info', 'displayName'], infos.displayName)\n .set(['info', 'description'], infos.description)\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .setAttributes(this.convertAttributes(newAttributes));\n\n return contentType;\n },\n\n deleteContentType(this: any, uid: string) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n this.components.forEach((compo: any) => {\n compo.removeContentType(uid);\n });\n\n this.contentTypes.forEach((ct: any) => {\n ct.removeContentType(uid);\n });\n\n return this.contentTypes.get(uid).delete();\n },\n };\n}\n\n/**\n * Returns a uid from a content type infos\n *\n * @param {object} options options\n * @param {string} options.singularName content-type singularName\n * @returns {string} uid\n */\nconst createContentTypeUID = ({\n singularName,\n}: {\n singularName: string;\n}): Internal.UID.ContentType => `api::${singularName}.${singularName}`;\n\nconst generateRelation = ({ key, attribute, uid, targetAttribute = {} }: any) => {\n const opts: any = {\n type: 'relation',\n target: uid,\n private: targetAttribute.private || undefined,\n pluginOptions: targetAttribute.pluginOptions || undefined,\n };\n\n switch (attribute.relation) {\n case 'oneToOne': {\n opts.relation = 'oneToOne';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n break;\n }\n case 'oneToMany': {\n opts.relation = 'manyToOne';\n opts.inversedBy = key;\n break;\n }\n case 'manyToOne': {\n opts.relation = 'oneToMany';\n opts.mappedBy = key;\n break;\n }\n case 'manyToMany': {\n opts.relation = 'manyToMany';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n\n break;\n }\n default:\n }\n\n // we do this just to make sure we have the same key order when writing to files\n const { type, relation, target, ...restOptions } = opts;\n\n return {\n type,\n relation,\n target,\n ...restOptions,\n };\n};\n"],"names":["ApplicationError","errors","reuseUnsetPreviousProperties","newAttribute","oldAttribute","_","defaults","omit","createComponentBuilder","setRelation","key","uid","attribute","has","targetCT","contentTypes","get","target","targetAttribute","getAttribute","setAttribute","generateRelation","unsetRelation","targetAttributeName","inversedBy","mappedBy","deleteAttribute","createContentTypeAttributes","attributes","contentType","Object","keys","forEach","setAttributes","convertAttributes","isRelation","includes","relation","undefined","dominant","createContentType","infos","createContentTypeUID","createSchemaHandler","modelName","singularName","dir","path","join","strapi","dirs","app","api","filename","set","setUID","kind","typeKinds","COLLECTION_TYPE","collectionName","strings","nameToCollectionName","pluralName","displayName","description","options","draftAndPublish","pluginOptions","config","editContentType","oldAttributes","schema","newAttributes","omitBy","attr","isConfigurable","newKeys","difference","deletedKeys","remainingKeys","intersection","isNil","oldTargetAttributeName","sameRelation","targetAttributeHasChanged","deleteContentType","components","compo","removeContentType","ct","delete","opts","type","private","restOptions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"content-type-builder.js","sources":["../../../../server/src/services/schema-builder/content-type-builder.ts"],"sourcesContent":["import path from 'path';\nimport _ from 'lodash';\n\nimport { strings, errors } from '@strapi/utils';\nimport type { Schema, Internal } from '@strapi/types';\nimport { isRelation, isConfigurable } from '../../utils/attributes';\nimport { typeKinds } from '../constants';\nimport createSchemaHandler from './schema-handler';\nimport { CreateContentTypeInput } from '../../controllers/validation/content-type';\nimport type { InternalRelationAttribute, InternalAttribute } from './types';\n\nconst { ApplicationError } = errors;\n\nconst reuseUnsetPreviousProperties = (\n newAttribute: Schema.Attribute.AnyAttribute,\n oldAttribute: Schema.Attribute.AnyAttribute\n) => {\n _.defaults(\n newAttribute,\n _.omit(oldAttribute, [\n 'configurable',\n 'required',\n 'private',\n 'unique',\n 'pluginOptions',\n 'inversedBy',\n 'mappedBy',\n 'conditions', // Don't automatically preserve conditions\n ])\n );\n};\n\nexport default function createComponentBuilder() {\n return {\n setRelation(\n this: any,\n { key, uid, attribute }: { key: string; uid: string; attribute: InternalRelationAttribute }\n ) {\n if (!_.has(attribute, 'target')) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n if (!targetCT) {\n throw new ApplicationError(`Content type ${attribute.target} not found`);\n }\n\n const targetAttribute = targetCT.getAttribute(attribute.targetAttribute);\n\n if (!attribute.targetAttribute) {\n return;\n }\n\n // When generating the inverse relation, preserve existing conditions if they exist\n // If the target attribute already exists and has conditions, preserve them\n const targetAttributeData = targetAttribute || {};\n\n // If the source doesn't have conditions but the target does, preserve target's conditions\n\n targetCT.setAttribute(\n attribute.targetAttribute,\n generateRelation({ key, attribute, uid, targetAttribute: targetAttributeData })\n );\n },\n\n unsetRelation(\n this: any,\n attribute: Schema.Attribute.Relation<Schema.Attribute.RelationKind.Any>\n ) {\n if (!('target' in attribute) || !attribute.target) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n const targetAttribute = targetCT.getAttribute(targetAttributeName);\n\n if (!targetAttribute) return;\n\n return targetCT.deleteAttribute(targetAttributeName);\n },\n\n createContentTypeAttributes(\n this: any,\n uid: string,\n attributes: CreateContentTypeInput['attributes']\n ) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n // support self referencing content type relation\n Object.keys(attributes).forEach((key) => {\n const { target } = attributes[key];\n if (target === '__self__') {\n attributes[key].target = uid;\n }\n });\n\n contentType.setAttributes(this.convertAttributes(attributes));\n\n Object.keys(attributes).forEach((key) => {\n const attribute = attributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = attributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n return contentType;\n },\n\n /**\n * Creates a content type in memory to be written to files later on\n */\n createContentType(this: any, infos: CreateContentTypeInput) {\n // TODO:: check for unique uid / singularName & pluralName & collectionName\n\n if (infos.uid && infos.uid !== createContentTypeUID(infos)) {\n throw new ApplicationError('contentType.invalidUID');\n }\n\n const uid = infos.uid ?? createContentTypeUID(infos);\n\n if (this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.alreadyExists');\n }\n\n const contentType = createSchemaHandler({\n modelName: infos.singularName,\n dir: path.join(\n strapi.dirs.app.api,\n infos.singularName,\n 'content-types',\n infos.singularName\n ),\n filename: `schema.json`,\n });\n\n this.contentTypes.set(uid, contentType);\n\n contentType\n .setUID(uid)\n .set('kind', infos.kind || typeKinds.COLLECTION_TYPE)\n .set(\n 'collectionName',\n infos.collectionName || strings.nameToCollectionName(infos.pluralName)\n )\n .set('info', {\n singularName: infos.singularName,\n pluralName: infos.pluralName,\n displayName: infos.displayName,\n description: infos.description,\n })\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .set('config', infos.config);\n\n this.createContentTypeAttributes(uid, infos.attributes);\n\n return contentType;\n },\n\n editContentType(this: any, infos: any) {\n const { uid } = infos;\n\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n const oldAttributes = contentType.schema.attributes;\n\n const newAttributes = _.omitBy(infos.attributes, (attr, key) => {\n return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);\n });\n\n const newKeys = _.difference(Object.keys(newAttributes), Object.keys(oldAttributes));\n const deletedKeys = _.difference(Object.keys(oldAttributes), Object.keys(newAttributes));\n const remainingKeys = _.intersection(Object.keys(oldAttributes), Object.keys(newAttributes));\n\n // remove old relations\n deletedKeys.forEach((key) => {\n const attribute = oldAttributes[key];\n\n // if the old relation has a target attribute. we need to remove it in the target type\n if (isConfigurable(attribute) && isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n\n if (targetAttributeName !== null && targetAttributeName !== undefined) {\n this.unsetRelation(attribute);\n }\n }\n });\n\n remainingKeys.forEach((key) => {\n const oldAttribute = oldAttributes[key];\n const newAttribute = newAttributes[key] as InternalAttribute;\n\n if (!isRelation(oldAttribute) && isRelation(newAttribute)) {\n return this.setRelation({\n key,\n uid,\n attribute: newAttribute as InternalRelationAttribute,\n });\n }\n\n if (isRelation(oldAttribute) && !isRelation(newAttribute)) {\n return this.unsetRelation(oldAttribute);\n }\n\n if (isRelation(oldAttribute) && isRelation(newAttribute)) {\n const relationAttribute = newAttribute as InternalRelationAttribute;\n const oldRelationAttribute = oldAttribute as InternalRelationAttribute;\n const oldTargetAttributeName =\n oldRelationAttribute.inversedBy || oldRelationAttribute.mappedBy;\n\n const sameRelation = oldAttribute.relation === relationAttribute.relation;\n const targetAttributeHasChanged =\n oldTargetAttributeName !== relationAttribute.targetAttribute;\n\n if (!sameRelation || targetAttributeHasChanged) {\n this.unsetRelation(oldAttribute);\n }\n\n // keep extra options that were set manually on oldAttribute\n reuseUnsetPreviousProperties(relationAttribute, oldAttribute);\n\n // Handle conditions explicitly - only preserve if present and not undefined in new attribute\n const newAttributeFromInfos = newAttributes[key];\n const hasNewConditions =\n newAttributeFromInfos.conditions !== undefined &&\n newAttributeFromInfos.conditions !== null;\n\n if (oldAttribute.conditions) {\n if (hasNewConditions) {\n // Conditions are still present, keep them\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n } else {\n // Conditions were removed (undefined or null), ensure they're not preserved\n delete relationAttribute.conditions;\n }\n } else if (hasNewConditions) {\n // New conditions added\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n }\n\n if (oldRelationAttribute.inversedBy) {\n relationAttribute.dominant = true;\n } else if (oldRelationAttribute.mappedBy) {\n relationAttribute.dominant = false;\n }\n\n return this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n // add new relations\n newKeys.forEach((key) => {\n const attribute = newAttributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = newAttributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n contentType\n .set('kind', infos.kind || contentType.schema.kind)\n .set(['info', 'displayName'], infos.displayName)\n .set(['info', 'description'], infos.description)\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .setAttributes(this.convertAttributes(newAttributes));\n\n return contentType;\n },\n\n deleteContentType(this: any, uid: string) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n this.components.forEach((compo: any) => {\n compo.removeContentType(uid);\n });\n\n this.contentTypes.forEach((ct: any) => {\n ct.removeContentType(uid);\n });\n\n return this.contentTypes.get(uid).delete();\n },\n };\n}\n\n/**\n * Returns a uid from a content type infos\n *\n * @param {object} options options\n * @param {string} options.singularName content-type singularName\n * @returns {string} uid\n */\nconst createContentTypeUID = ({\n singularName,\n}: {\n singularName: string;\n}): Internal.UID.ContentType => `api::${singularName}.${singularName}`;\n\nconst generateRelation = ({\n key,\n attribute,\n uid,\n targetAttribute = {},\n}: {\n key: string;\n attribute: InternalRelationAttribute;\n uid: string;\n targetAttribute?: Partial<InternalRelationAttribute>;\n}) => {\n const opts: any = {\n type: 'relation',\n target: uid,\n private: targetAttribute.private || undefined,\n pluginOptions: targetAttribute.pluginOptions || undefined,\n // Preserve conditions from targetAttribute if they exist\n // This allows each side of the relation to maintain its own conditions\n ...(targetAttribute.conditions && { conditions: targetAttribute.conditions }),\n };\n\n switch (attribute.relation) {\n case 'oneToOne': {\n opts.relation = 'oneToOne';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n break;\n }\n case 'oneToMany': {\n opts.relation = 'manyToOne';\n opts.inversedBy = key;\n break;\n }\n case 'manyToOne': {\n opts.relation = 'oneToMany';\n opts.mappedBy = key;\n break;\n }\n case 'manyToMany': {\n opts.relation = 'manyToMany';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n\n break;\n }\n default:\n }\n\n // we do this just to make sure we have the same key order when writing to files\n const { type, relation, target, ...restOptions } = opts;\n\n const result = {\n type,\n relation,\n target,\n ...restOptions,\n };\n\n return result;\n};\n"],"names":["ApplicationError","errors","reuseUnsetPreviousProperties","newAttribute","oldAttribute","_","defaults","omit","createComponentBuilder","setRelation","key","uid","attribute","has","targetCT","contentTypes","get","target","targetAttribute","getAttribute","targetAttributeData","setAttribute","generateRelation","unsetRelation","relationAttribute","targetAttributeName","inversedBy","mappedBy","deleteAttribute","createContentTypeAttributes","attributes","contentType","Object","keys","forEach","setAttributes","convertAttributes","isRelation","includes","relation","undefined","dominant","createContentType","infos","createContentTypeUID","createSchemaHandler","modelName","singularName","dir","path","join","strapi","dirs","app","api","filename","set","setUID","kind","typeKinds","COLLECTION_TYPE","collectionName","strings","nameToCollectionName","pluralName","displayName","description","options","draftAndPublish","pluginOptions","config","editContentType","oldAttributes","schema","newAttributes","omitBy","attr","isConfigurable","newKeys","difference","deletedKeys","remainingKeys","intersection","oldRelationAttribute","oldTargetAttributeName","sameRelation","targetAttributeHasChanged","newAttributeFromInfos","hasNewConditions","conditions","deleteContentType","components","compo","removeContentType","ct","delete","opts","type","private","restOptions","result"],"mappings":"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"}
|
|
@@ -14,7 +14,8 @@ const reuseUnsetPreviousProperties = (newAttribute, oldAttribute)=>{
|
|
|
14
14
|
'unique',
|
|
15
15
|
'pluginOptions',
|
|
16
16
|
'inversedBy',
|
|
17
|
-
'mappedBy'
|
|
17
|
+
'mappedBy',
|
|
18
|
+
'conditions'
|
|
18
19
|
]));
|
|
19
20
|
};
|
|
20
21
|
function createComponentBuilder() {
|
|
@@ -31,19 +32,24 @@ function createComponentBuilder() {
|
|
|
31
32
|
if (!attribute.targetAttribute) {
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
35
|
+
// When generating the inverse relation, preserve existing conditions if they exist
|
|
36
|
+
// If the target attribute already exists and has conditions, preserve them
|
|
37
|
+
const targetAttributeData = targetAttribute || {};
|
|
38
|
+
// If the source doesn't have conditions but the target does, preserve target's conditions
|
|
34
39
|
targetCT.setAttribute(attribute.targetAttribute, generateRelation({
|
|
35
40
|
key,
|
|
36
41
|
attribute,
|
|
37
42
|
uid,
|
|
38
|
-
targetAttribute
|
|
43
|
+
targetAttribute: targetAttributeData
|
|
39
44
|
}));
|
|
40
45
|
},
|
|
41
46
|
unsetRelation (attribute) {
|
|
42
|
-
if (!
|
|
47
|
+
if (!('target' in attribute) || !attribute.target) {
|
|
43
48
|
return;
|
|
44
49
|
}
|
|
45
50
|
const targetCT = this.contentTypes.get(attribute.target);
|
|
46
|
-
const
|
|
51
|
+
const relationAttribute = attribute;
|
|
52
|
+
const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;
|
|
47
53
|
const targetAttribute = targetCT.getAttribute(targetAttributeName);
|
|
48
54
|
if (!targetAttribute) return;
|
|
49
55
|
return targetCT.deleteAttribute(targetAttributeName);
|
|
@@ -64,26 +70,27 @@ function createComponentBuilder() {
|
|
|
64
70
|
Object.keys(attributes).forEach((key)=>{
|
|
65
71
|
const attribute = attributes[key];
|
|
66
72
|
if (isRelation(attribute)) {
|
|
73
|
+
const relationAttribute = attribute;
|
|
67
74
|
if ([
|
|
68
75
|
'manyToMany',
|
|
69
76
|
'oneToOne'
|
|
70
|
-
].includes(
|
|
71
|
-
if (
|
|
77
|
+
].includes(relationAttribute.relation)) {
|
|
78
|
+
if (relationAttribute.target === uid && relationAttribute.targetAttribute !== undefined) {
|
|
72
79
|
// self referencing relation
|
|
73
|
-
const targetAttribute = attributes[
|
|
80
|
+
const targetAttribute = attributes[relationAttribute.targetAttribute];
|
|
74
81
|
if (targetAttribute.dominant === undefined) {
|
|
75
|
-
|
|
82
|
+
relationAttribute.dominant = true;
|
|
76
83
|
} else {
|
|
77
|
-
|
|
84
|
+
relationAttribute.dominant = false;
|
|
78
85
|
}
|
|
79
86
|
} else {
|
|
80
|
-
|
|
87
|
+
relationAttribute.dominant = true;
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
this.setRelation({
|
|
84
91
|
key,
|
|
85
92
|
uid,
|
|
86
|
-
attribute
|
|
93
|
+
attribute: relationAttribute
|
|
87
94
|
});
|
|
88
95
|
}
|
|
89
96
|
});
|
|
@@ -134,10 +141,13 @@ function createComponentBuilder() {
|
|
|
134
141
|
// remove old relations
|
|
135
142
|
deletedKeys.forEach((key)=>{
|
|
136
143
|
const attribute = oldAttributes[key];
|
|
137
|
-
const targetAttributeName = attribute.inversedBy || attribute.mappedBy;
|
|
138
144
|
// if the old relation has a target attribute. we need to remove it in the target type
|
|
139
|
-
if (isConfigurable(attribute) && isRelation(attribute)
|
|
140
|
-
|
|
145
|
+
if (isConfigurable(attribute) && isRelation(attribute)) {
|
|
146
|
+
const relationAttribute = attribute;
|
|
147
|
+
const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;
|
|
148
|
+
if (targetAttributeName !== null && targetAttributeName !== undefined) {
|
|
149
|
+
this.unsetRelation(attribute);
|
|
150
|
+
}
|
|
141
151
|
}
|
|
142
152
|
});
|
|
143
153
|
remainingKeys.forEach((key)=>{
|
|
@@ -147,30 +157,47 @@ function createComponentBuilder() {
|
|
|
147
157
|
return this.setRelation({
|
|
148
158
|
key,
|
|
149
159
|
uid,
|
|
150
|
-
attribute:
|
|
160
|
+
attribute: newAttribute
|
|
151
161
|
});
|
|
152
162
|
}
|
|
153
163
|
if (isRelation(oldAttribute) && !isRelation(newAttribute)) {
|
|
154
164
|
return this.unsetRelation(oldAttribute);
|
|
155
165
|
}
|
|
156
166
|
if (isRelation(oldAttribute) && isRelation(newAttribute)) {
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
const
|
|
167
|
+
const relationAttribute = newAttribute;
|
|
168
|
+
const oldRelationAttribute = oldAttribute;
|
|
169
|
+
const oldTargetAttributeName = oldRelationAttribute.inversedBy || oldRelationAttribute.mappedBy;
|
|
170
|
+
const sameRelation = oldAttribute.relation === relationAttribute.relation;
|
|
171
|
+
const targetAttributeHasChanged = oldTargetAttributeName !== relationAttribute.targetAttribute;
|
|
160
172
|
if (!sameRelation || targetAttributeHasChanged) {
|
|
161
173
|
this.unsetRelation(oldAttribute);
|
|
162
174
|
}
|
|
163
175
|
// keep extra options that were set manually on oldAttribute
|
|
164
|
-
reuseUnsetPreviousProperties(
|
|
165
|
-
if
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
176
|
+
reuseUnsetPreviousProperties(relationAttribute, oldAttribute);
|
|
177
|
+
// Handle conditions explicitly - only preserve if present and not undefined in new attribute
|
|
178
|
+
const newAttributeFromInfos = newAttributes[key];
|
|
179
|
+
const hasNewConditions = newAttributeFromInfos.conditions !== undefined && newAttributeFromInfos.conditions !== null;
|
|
180
|
+
if (oldAttribute.conditions) {
|
|
181
|
+
if (hasNewConditions) {
|
|
182
|
+
// Conditions are still present, keep them
|
|
183
|
+
relationAttribute.conditions = newAttributeFromInfos.conditions;
|
|
184
|
+
} else {
|
|
185
|
+
// Conditions were removed (undefined or null), ensure they're not preserved
|
|
186
|
+
delete relationAttribute.conditions;
|
|
187
|
+
}
|
|
188
|
+
} else if (hasNewConditions) {
|
|
189
|
+
// New conditions added
|
|
190
|
+
relationAttribute.conditions = newAttributeFromInfos.conditions;
|
|
191
|
+
}
|
|
192
|
+
if (oldRelationAttribute.inversedBy) {
|
|
193
|
+
relationAttribute.dominant = true;
|
|
194
|
+
} else if (oldRelationAttribute.mappedBy) {
|
|
195
|
+
relationAttribute.dominant = false;
|
|
169
196
|
}
|
|
170
197
|
return this.setRelation({
|
|
171
198
|
key,
|
|
172
199
|
uid,
|
|
173
|
-
attribute:
|
|
200
|
+
attribute: relationAttribute
|
|
174
201
|
});
|
|
175
202
|
}
|
|
176
203
|
});
|
|
@@ -178,26 +205,27 @@ function createComponentBuilder() {
|
|
|
178
205
|
newKeys.forEach((key)=>{
|
|
179
206
|
const attribute = newAttributes[key];
|
|
180
207
|
if (isRelation(attribute)) {
|
|
208
|
+
const relationAttribute = attribute;
|
|
181
209
|
if ([
|
|
182
210
|
'manyToMany',
|
|
183
211
|
'oneToOne'
|
|
184
|
-
].includes(
|
|
185
|
-
if (
|
|
212
|
+
].includes(relationAttribute.relation)) {
|
|
213
|
+
if (relationAttribute.target === uid && relationAttribute.targetAttribute !== undefined) {
|
|
186
214
|
// self referencing relation
|
|
187
|
-
const targetAttribute = newAttributes[
|
|
215
|
+
const targetAttribute = newAttributes[relationAttribute.targetAttribute];
|
|
188
216
|
if (targetAttribute.dominant === undefined) {
|
|
189
|
-
|
|
217
|
+
relationAttribute.dominant = true;
|
|
190
218
|
} else {
|
|
191
|
-
|
|
219
|
+
relationAttribute.dominant = false;
|
|
192
220
|
}
|
|
193
221
|
} else {
|
|
194
|
-
|
|
222
|
+
relationAttribute.dominant = true;
|
|
195
223
|
}
|
|
196
224
|
}
|
|
197
225
|
this.setRelation({
|
|
198
226
|
key,
|
|
199
227
|
uid,
|
|
200
|
-
attribute
|
|
228
|
+
attribute: relationAttribute
|
|
201
229
|
});
|
|
202
230
|
}
|
|
203
231
|
});
|
|
@@ -239,7 +267,12 @@ const generateRelation = ({ key, attribute, uid, targetAttribute = {} })=>{
|
|
|
239
267
|
type: 'relation',
|
|
240
268
|
target: uid,
|
|
241
269
|
private: targetAttribute.private || undefined,
|
|
242
|
-
pluginOptions: targetAttribute.pluginOptions || undefined
|
|
270
|
+
pluginOptions: targetAttribute.pluginOptions || undefined,
|
|
271
|
+
// Preserve conditions from targetAttribute if they exist
|
|
272
|
+
// This allows each side of the relation to maintain its own conditions
|
|
273
|
+
...targetAttribute.conditions && {
|
|
274
|
+
conditions: targetAttribute.conditions
|
|
275
|
+
}
|
|
243
276
|
};
|
|
244
277
|
switch(attribute.relation){
|
|
245
278
|
case 'oneToOne':
|
|
@@ -277,12 +310,13 @@ const generateRelation = ({ key, attribute, uid, targetAttribute = {} })=>{
|
|
|
277
310
|
}
|
|
278
311
|
// we do this just to make sure we have the same key order when writing to files
|
|
279
312
|
const { type, relation, target, ...restOptions } = opts;
|
|
280
|
-
|
|
313
|
+
const result = {
|
|
281
314
|
type,
|
|
282
315
|
relation,
|
|
283
316
|
target,
|
|
284
317
|
...restOptions
|
|
285
318
|
};
|
|
319
|
+
return result;
|
|
286
320
|
};
|
|
287
321
|
|
|
288
322
|
export { createComponentBuilder as default };
|