@strapi/content-type-builder 5.55.1 → 5.57.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.
Files changed (152) hide show
  1. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js +117 -13
  2. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js.map +1 -1
  3. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs +118 -13
  4. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs.map +1 -1
  5. package/dist/admin/components/AIChat/providers/SchemaProvider.js +31 -19
  6. package/dist/admin/components/AIChat/providers/SchemaProvider.js.map +1 -1
  7. package/dist/admin/components/AIChat/providers/SchemaProvider.mjs +31 -19
  8. package/dist/admin/components/AIChat/providers/SchemaProvider.mjs.map +1 -1
  9. package/dist/admin/components/DataManager/DataManagerContext.js.map +1 -1
  10. package/dist/admin/components/DataManager/DataManagerContext.mjs.map +1 -1
  11. package/dist/admin/components/DataManager/DataManagerProvider.js +166 -6
  12. package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
  13. package/dist/admin/components/DataManager/DataManagerProvider.mjs +165 -7
  14. package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
  15. package/dist/admin/components/DataManager/RenameMigrationModal.js +285 -0
  16. package/dist/admin/components/DataManager/RenameMigrationModal.js.map +1 -0
  17. package/dist/admin/components/DataManager/RenameMigrationModal.mjs +257 -0
  18. package/dist/admin/components/DataManager/RenameMigrationModal.mjs.map +1 -0
  19. package/dist/admin/components/DataManager/reducer.js +107 -2
  20. package/dist/admin/components/DataManager/reducer.js.map +1 -1
  21. package/dist/admin/components/DataManager/reducer.mjs +106 -2
  22. package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
  23. package/dist/admin/components/DataManager/utils/cleanData.js +8 -1
  24. package/dist/admin/components/DataManager/utils/cleanData.js.map +1 -1
  25. package/dist/admin/components/DataManager/utils/cleanData.mjs +8 -1
  26. package/dist/admin/components/DataManager/utils/cleanData.mjs.map +1 -1
  27. package/dist/admin/components/DataManager/utils/groupRenameChains.js +86 -0
  28. package/dist/admin/components/DataManager/utils/groupRenameChains.js.map +1 -0
  29. package/dist/admin/components/DataManager/utils/groupRenameChains.mjs +84 -0
  30. package/dist/admin/components/DataManager/utils/groupRenameChains.mjs.map +1 -0
  31. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.js +29 -0
  32. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.js.map +1 -0
  33. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.mjs +27 -0
  34. package/dist/admin/components/DataManager/utils/isStorageCompatibleRename.mjs.map +1 -0
  35. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.js +35 -0
  36. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.js.map +1 -0
  37. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.mjs +33 -0
  38. package/dist/admin/components/DataManager/utils/resolveAfterEditRenameConsent.mjs.map +1 -0
  39. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.js +48 -0
  40. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.js.map +1 -0
  41. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.mjs +45 -0
  42. package/dist/admin/components/DataManager/utils/splitChainsByInheritedConsent.mjs.map +1 -0
  43. package/dist/admin/components/FormModal/FormModal.js +143 -9
  44. package/dist/admin/components/FormModal/FormModal.js.map +1 -1
  45. package/dist/admin/components/FormModal/FormModal.mjs +144 -10
  46. package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
  47. package/dist/admin/components/FormModal/attributes/validation/common.js +6 -5
  48. package/dist/admin/components/FormModal/attributes/validation/common.js.map +1 -1
  49. package/dist/admin/components/FormModal/attributes/validation/common.mjs +1 -1
  50. package/dist/admin/components/FormModal/attributes/validation/common.mjs.map +1 -1
  51. package/dist/admin/components/FormModal/component/createComponentSchema.js +10 -7
  52. package/dist/admin/components/FormModal/component/createComponentSchema.js.map +1 -1
  53. package/dist/admin/components/FormModal/component/createComponentSchema.mjs +1 -1
  54. package/dist/admin/components/FormModal/component/createComponentSchema.mjs.map +1 -1
  55. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.js +24 -21
  56. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.js.map +1 -1
  57. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.mjs +1 -1
  58. package/dist/admin/components/FormModal/contentType/createContentTypeSchema.mjs.map +1 -1
  59. package/dist/admin/components/FormModal/forms/utils/createCollectionName.js +3 -2
  60. package/dist/admin/components/FormModal/forms/utils/createCollectionName.js.map +1 -1
  61. package/dist/admin/components/FormModal/forms/utils/createCollectionName.mjs +1 -1
  62. package/dist/admin/components/FormModal/forms/utils/createCollectionName.mjs.map +1 -1
  63. package/dist/admin/components/FormModal/utils/getRenameStorageChange.js +73 -0
  64. package/dist/admin/components/FormModal/utils/getRenameStorageChange.js.map +1 -0
  65. package/dist/admin/components/FormModal/utils/getRenameStorageChange.mjs +70 -0
  66. package/dist/admin/components/FormModal/utils/getRenameStorageChange.mjs.map +1 -0
  67. package/dist/admin/src/components/AIChat/components/AnimatedBox.d.ts +2 -2
  68. package/dist/admin/src/components/AIChat/components/Input.d.ts +2 -2
  69. package/dist/admin/src/components/AIChat/lib/transforms/schemas/toCTB.d.ts +4 -3
  70. package/dist/admin/src/components/AIChat/lib/types/schema.d.ts +6 -1
  71. package/dist/admin/src/components/AttributeOptions/OptionBoxWrapper.d.ts +2 -2
  72. package/dist/admin/src/components/ComponentRow.d.ts +2 -2
  73. package/dist/admin/src/components/DataManager/DataManagerContext.d.ts +28 -2
  74. package/dist/admin/src/components/DataManager/RenameMigrationModal.d.ts +73 -0
  75. package/dist/admin/src/components/DataManager/reducer.d.ts +17 -2
  76. package/dist/admin/src/components/DataManager/utils/cleanData.d.ts +16 -0
  77. package/dist/admin/src/components/DataManager/utils/groupRenameChains.d.ts +31 -0
  78. package/dist/admin/src/components/DataManager/utils/isStorageCompatibleRename.d.ts +10 -0
  79. package/dist/admin/src/components/DataManager/utils/resolveAfterEditRenameConsent.d.ts +24 -0
  80. package/dist/admin/src/components/DataManager/utils/splitChainsByInheritedConsent.d.ts +26 -0
  81. package/dist/admin/src/components/FormModal/utils/getRenameStorageChange.d.ts +40 -0
  82. package/dist/admin/src/components/List.d.ts +2 -2
  83. package/dist/admin/src/components/Relation/RelationNaturePicker/Components.d.ts +4 -4
  84. package/dist/admin/src/types.d.ts +23 -0
  85. package/dist/admin/translations/en.json.js +12 -0
  86. package/dist/admin/translations/en.json.js.map +1 -1
  87. package/dist/admin/translations/en.json.mjs +12 -0
  88. package/dist/admin/translations/en.json.mjs.map +1 -1
  89. package/dist/server/config.js +24 -3
  90. package/dist/server/config.js.map +1 -1
  91. package/dist/server/config.mjs +21 -3
  92. package/dist/server/config.mjs.map +1 -1
  93. package/dist/server/controllers/schema.js +2 -2
  94. package/dist/server/controllers/schema.js.map +1 -1
  95. package/dist/server/controllers/schema.mjs +1 -1
  96. package/dist/server/controllers/schema.mjs.map +1 -1
  97. package/dist/server/controllers/validation/content-type.js +9 -11
  98. package/dist/server/controllers/validation/content-type.js.map +1 -1
  99. package/dist/server/controllers/validation/content-type.mjs +7 -9
  100. package/dist/server/controllers/validation/content-type.mjs.map +1 -1
  101. package/dist/server/controllers/validation/model-schema.js +2 -3
  102. package/dist/server/controllers/validation/model-schema.js.map +1 -1
  103. package/dist/server/controllers/validation/model-schema.mjs +1 -2
  104. package/dist/server/controllers/validation/model-schema.mjs.map +1 -1
  105. package/dist/server/controllers/validation/relations.js +1 -2
  106. package/dist/server/controllers/validation/relations.js.map +1 -1
  107. package/dist/server/controllers/validation/relations.mjs +1 -2
  108. package/dist/server/controllers/validation/relations.mjs.map +1 -1
  109. package/dist/server/controllers/validation/schema.js +42 -23
  110. package/dist/server/controllers/validation/schema.js.map +1 -1
  111. package/dist/server/controllers/validation/schema.mjs +43 -24
  112. package/dist/server/controllers/validation/schema.mjs.map +1 -1
  113. package/dist/server/index.js +1 -1
  114. package/dist/server/index.js.map +1 -1
  115. package/dist/server/services/content-types.js +1 -2
  116. package/dist/server/services/content-types.js.map +1 -1
  117. package/dist/server/services/content-types.mjs +2 -3
  118. package/dist/server/services/content-types.mjs.map +1 -1
  119. package/dist/server/services/migration-builder/index.js +580 -0
  120. package/dist/server/services/migration-builder/index.js.map +1 -0
  121. package/dist/server/services/migration-builder/index.mjs +573 -0
  122. package/dist/server/services/migration-builder/index.mjs.map +1 -0
  123. package/dist/server/services/schema-builder/content-type-builder.js +31 -1
  124. package/dist/server/services/schema-builder/content-type-builder.js.map +1 -1
  125. package/dist/server/services/schema-builder/content-type-builder.mjs +31 -1
  126. package/dist/server/services/schema-builder/content-type-builder.mjs.map +1 -1
  127. package/dist/server/services/schema-mutation.js +30 -2
  128. package/dist/server/services/schema-mutation.js.map +1 -1
  129. package/dist/server/services/schema-mutation.mjs +10 -2
  130. package/dist/server/services/schema-mutation.mjs.map +1 -1
  131. package/dist/server/services/schema.js +259 -15
  132. package/dist/server/services/schema.js.map +1 -1
  133. package/dist/server/services/schema.mjs +252 -9
  134. package/dist/server/services/schema.mjs.map +1 -1
  135. package/dist/server/src/config.d.ts +23 -2
  136. package/dist/server/src/config.d.ts.map +1 -1
  137. package/dist/server/src/controllers/validation/content-type.d.ts +0 -1
  138. package/dist/server/src/controllers/validation/content-type.d.ts.map +1 -1
  139. package/dist/server/src/controllers/validation/relations.d.ts.map +1 -1
  140. package/dist/server/src/controllers/validation/schema.d.ts +28 -0
  141. package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
  142. package/dist/server/src/index.d.ts +10 -2
  143. package/dist/server/src/index.d.ts.map +1 -1
  144. package/dist/server/src/services/content-types.d.ts.map +1 -1
  145. package/dist/server/src/services/migration-builder/index.d.ts +83 -0
  146. package/dist/server/src/services/migration-builder/index.d.ts.map +1 -0
  147. package/dist/server/src/services/schema-builder/content-type-builder.d.ts.map +1 -1
  148. package/dist/server/src/services/schema-mutation.d.ts +4 -2
  149. package/dist/server/src/services/schema-mutation.d.ts.map +1 -1
  150. package/dist/server/src/services/schema.d.ts +19 -0
  151. package/dist/server/src/services/schema.d.ts.map +1 -1
  152. package/package.json +11 -10
@@ -0,0 +1,70 @@
1
+ import { isStorageCompatibleRename } from '../../DataManager/utils/isStorageCompatibleRename.mjs';
2
+
3
+ /**
4
+ * Human label for what defines an attribute's storage: the type, plus the
5
+ * relation kind/target for relations and the component uid (+ repeatable) for
6
+ * components, so a warning can say what changed.
7
+ */ const describeAttributeStorage = (attribute)=>{
8
+ const type = attribute.type ?? 'unknown';
9
+ if (type === 'relation') {
10
+ const details = [
11
+ attribute.relation,
12
+ attribute.target ? `to ${attribute.target}` : undefined
13
+ ].filter(Boolean).join(' ');
14
+ return details ? `${type} (${details})` : type;
15
+ }
16
+ if (type === 'component') {
17
+ const details = [
18
+ attribute.component,
19
+ attribute.repeatable ? 'repeatable' : undefined
20
+ ].filter(Boolean).join(', ');
21
+ return details ? `${type} (${details})` : type;
22
+ }
23
+ return type;
24
+ };
25
+ /**
26
+ * Detects an attribute edit that renames an existing field *and* changes its
27
+ * storage (type, relation kind/target, component uid/repeatable). Such a rename
28
+ * cannot be replayed as a data-preserving migration, so the field is dropped
29
+ * and recreated empty — the user should be warned before saving.
30
+ *
31
+ * For a relation, renaming the other side (`targetAttribute`) counts as well:
32
+ * the warning then names that field.
33
+ *
34
+ * Returns `null` when there is nothing to warn about: rename migrations are
35
+ * disabled, the field is brand new (no data yet), no name changed, or the
36
+ * storage is unchanged.
37
+ */ const getRenameStorageChange = (initial, modified, mode)=>{
38
+ if (mode === 'never' || initial.status === 'NEW') {
39
+ return null;
40
+ }
41
+ const isRenamed = (oldName, newName)=>Boolean(oldName) && Boolean(newName) && oldName !== newName;
42
+ const renamed = [
43
+ [
44
+ initial.name,
45
+ modified.name
46
+ ],
47
+ ...initial.type === 'relation' ? [
48
+ [
49
+ initial.targetAttribute,
50
+ modified.targetAttribute
51
+ ]
52
+ ] : []
53
+ ].find(([oldName, newName])=>isRenamed(oldName, newName));
54
+ if (!renamed) {
55
+ return null;
56
+ }
57
+ const [oldName, newName] = renamed;
58
+ if (isStorageCompatibleRename(initial, modified)) {
59
+ return null;
60
+ }
61
+ return {
62
+ oldName,
63
+ newName,
64
+ oldType: describeAttributeStorage(initial),
65
+ newType: describeAttributeStorage(modified)
66
+ };
67
+ };
68
+
69
+ export { describeAttributeStorage, getRenameStorageChange };
70
+ //# sourceMappingURL=getRenameStorageChange.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getRenameStorageChange.mjs","sources":["../../../../../admin/src/components/FormModal/utils/getRenameStorageChange.ts"],"sourcesContent":["import { isStorageCompatibleRename } from '../../DataManager/utils/isStorageCompatibleRename';\n\nimport type { AnyAttribute, Status } from '../../../types';\nimport type { AttributeRenameMigrationMode } from '../../DataManager/RenameMigrationModal';\n\n/** The loosely typed attribute data held by the form reducer (`FormModalData`). */\nexport type AttributeFormData = Record<string, unknown> & {\n name?: string;\n status?: Status;\n type?: string;\n relation?: string;\n target?: string | null;\n component?: string;\n repeatable?: boolean;\n};\n\nexport interface RenameStorageChange {\n oldName: string;\n newName: string;\n /** Human label of the field's storage before the edit (e.g. `relation (oneToMany to api::tag.tag)`). */\n oldType: string;\n /** Human label of the field's storage after the edit. */\n newType: string;\n}\n\n/**\n * Human label for what defines an attribute's storage: the type, plus the\n * relation kind/target for relations and the component uid (+ repeatable) for\n * components, so a warning can say what changed.\n */\nexport const describeAttributeStorage = (attribute: AttributeFormData): string => {\n const type = attribute.type ?? 'unknown';\n\n if (type === 'relation') {\n const details = [attribute.relation, attribute.target ? `to ${attribute.target}` : undefined]\n .filter(Boolean)\n .join(' ');\n return details ? `${type} (${details})` : type;\n }\n\n if (type === 'component') {\n const details = [attribute.component, attribute.repeatable ? 'repeatable' : undefined]\n .filter(Boolean)\n .join(', ');\n return details ? `${type} (${details})` : type;\n }\n\n return type;\n};\n\n/**\n * Detects an attribute edit that renames an existing field *and* changes its\n * storage (type, relation kind/target, component uid/repeatable). Such a rename\n * cannot be replayed as a data-preserving migration, so the field is dropped\n * and recreated empty — the user should be warned before saving.\n *\n * For a relation, renaming the other side (`targetAttribute`) counts as well:\n * the warning then names that field.\n *\n * Returns `null` when there is nothing to warn about: rename migrations are\n * disabled, the field is brand new (no data yet), no name changed, or the\n * storage is unchanged.\n */\nexport const getRenameStorageChange = (\n initial: AttributeFormData,\n modified: AttributeFormData,\n mode: AttributeRenameMigrationMode\n): RenameStorageChange | null => {\n if (mode === 'never' || initial.status === 'NEW') {\n return null;\n }\n\n const isRenamed = (oldName: unknown, newName: unknown) =>\n Boolean(oldName) && Boolean(newName) && oldName !== newName;\n\n const renamed = [\n [initial.name, modified.name],\n ...(initial.type === 'relation' ? [[initial.targetAttribute, modified.targetAttribute]] : []),\n ].find(([oldName, newName]) => isRenamed(oldName, newName));\n if (!renamed) {\n return null;\n }\n\n const [oldName, newName] = renamed as [string, string];\n\n if (\n isStorageCompatibleRename(\n initial as unknown as AnyAttribute,\n modified as unknown as AnyAttribute\n )\n ) {\n return null;\n }\n\n return {\n oldName,\n newName,\n oldType: describeAttributeStorage(initial),\n newType: describeAttributeStorage(modified),\n };\n};\n"],"names":["describeAttributeStorage","attribute","type","details","relation","target","undefined","filter","Boolean","join","component","repeatable","getRenameStorageChange","initial","modified","mode","status","isRenamed","oldName","newName","renamed","name","targetAttribute","find","isStorageCompatibleRename","oldType","newType"],"mappings":";;AAyBA;;;;IAKO,MAAMA,wBAAAA,GAA2B,CAACC,SAAAA,GAAAA;IACvC,MAAMC,IAAAA,GAAOD,SAAAA,CAAUC,IAAI,IAAI,SAAA;AAE/B,IAAA,IAAIA,SAAS,UAAA,EAAY;AACvB,QAAA,MAAMC,OAAAA,GAAU;AAACF,YAAAA,SAAAA,CAAUG,QAAQ;YAAEH,SAAAA,CAAUI,MAAM,GAAG,CAAC,GAAG,EAAEJ,SAAAA,CAAUI,MAAM,EAAE,GAAGC;AAAU,SAAA,CAC1FC,MAAM,CAACC,OAAAA,CAAAA,CACPC,IAAI,CAAC,GAAA,CAAA;QACR,OAAON,OAAAA,GAAU,GAAGD,IAAAA,CAAK,EAAE,EAAEC,OAAAA,CAAQ,CAAC,CAAC,GAAGD,IAAAA;AAC5C,IAAA;AAEA,IAAA,IAAIA,SAAS,WAAA,EAAa;AACxB,QAAA,MAAMC,OAAAA,GAAU;AAACF,YAAAA,SAAAA,CAAUS,SAAS;YAAET,SAAAA,CAAUU,UAAU,GAAG,YAAA,GAAeL;AAAU,SAAA,CACnFC,MAAM,CAACC,OAAAA,CAAAA,CACPC,IAAI,CAAC,IAAA,CAAA;QACR,OAAON,OAAAA,GAAU,GAAGD,IAAAA,CAAK,EAAE,EAAEC,OAAAA,CAAQ,CAAC,CAAC,GAAGD,IAAAA;AAC5C,IAAA;IAEA,OAAOA,IAAAA;AACT;AAEA;;;;;;;;;;;;AAYC,IACM,MAAMU,sBAAAA,GAAyB,CACpCC,SACAC,QAAAA,EACAC,IAAAA,GAAAA;AAEA,IAAA,IAAIA,IAAAA,KAAS,OAAA,IAAWF,OAAAA,CAAQG,MAAM,KAAK,KAAA,EAAO;QAChD,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,SAAAA,GAAY,CAACC,OAAAA,EAAkBC,OAAAA,GACnCX,QAAQU,OAAAA,CAAAA,IAAYV,OAAAA,CAAQW,YAAYD,OAAAA,KAAYC,OAAAA;AAEtD,IAAA,MAAMC,OAAAA,GAAU;AACd,QAAA;AAACP,YAAAA,OAAAA,CAAQQ,IAAI;AAAEP,YAAAA,QAAAA,CAASO;AAAK,SAAA;WACzBR,OAAAA,CAAQX,IAAI,KAAK,UAAA,GAAa;AAAC,YAAA;AAACW,gBAAAA,OAAAA,CAAQS,eAAe;AAAER,gBAAAA,QAAAA,CAASQ;AAAgB;AAAC,SAAA,GAAG;KAC3F,CAACC,IAAI,CAAC,CAAC,CAACL,SAASC,OAAAA,CAAQ,GAAKF,UAAUC,OAAAA,EAASC,OAAAA,CAAAA,CAAAA;AAClD,IAAA,IAAI,CAACC,OAAAA,EAAS;QACZ,OAAO,IAAA;AACT,IAAA;IAEA,MAAM,CAACF,OAAAA,EAASC,OAAAA,CAAQ,GAAGC,OAAAA;IAE3B,IACEI,yBAAAA,CACEX,SACAC,QAAAA,CAAAA,EAEF;QACA,OAAO,IAAA;AACT,IAAA;IAEA,OAAO;AACLI,QAAAA,OAAAA;AACAC,QAAAA,OAAAA;AACAM,QAAAA,OAAAA,EAASzB,wBAAAA,CAAyBa,OAAAA,CAAAA;AAClCa,QAAAA,OAAAA,EAAS1B,wBAAAA,CAAyBc,QAAAA;AACpC,KAAA;AACF;;;;"}
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export declare const AnimatedBox: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
5
5
  children?: React.ReactNode;
6
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
6
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
7
7
  ref?: any;
8
8
  }, "ref"> & {
9
9
  ref?: any;
@@ -11,7 +11,7 @@ export declare const AnimatedBox: import("styled-components/dist/types").IStyled
11
11
  $direction?: "up" | "left";
12
12
  }, never> & Partial<Pick<import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
13
13
  children?: React.ReactNode;
14
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
14
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
15
15
  ref?: any;
16
16
  }, "ref"> & {
17
17
  ref?: any;
@@ -27,13 +27,13 @@ export declare const Input: {
27
27
  Header: ({ children, ...props }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
28
28
  HeaderItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
29
29
  children?: React.ReactNode;
30
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
30
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
31
31
  ref?: any;
32
32
  }, "ref"> & {
33
33
  ref?: any;
34
34
  }, never> & Partial<Pick<Omit<import("@strapi/design-system").TransientBoxProps & {
35
35
  children?: React.ReactNode;
36
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
36
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
37
37
  ref?: any;
38
38
  }, "ref"> & {
39
39
  ref?: any;
@@ -1,10 +1,11 @@
1
1
  import type { ContentType, Component, AnyAttribute } from '../../../../../types';
2
2
  import type { Schema } from '../../types/schema';
3
3
  /**
4
- * Transform attributes from Chat format to CTB format
5
- * Also performs a diff to determine the status of each attribute
4
+ * Transform attributes from Chat format to CTB format.
5
+ *
6
+ * Keep the existing array return type for callers that only need attributes.
6
7
  */
7
- export declare const transformAttributesFromChatToCTB: ({ action, attributes }: Schema, oldSchema?: ContentType | Component) => AnyAttribute[];
8
+ export declare const transformAttributesFromChatToCTB: (schema: Schema, oldSchema?: ContentType | Component) => AnyAttribute[];
8
9
  /**
9
10
  * Transform schema format
10
11
  * AI chat -> CTB
@@ -1,4 +1,4 @@
1
- import type { AnyAttribute } from '../../../../types';
1
+ import type { AnyAttribute, RenameHop } from '../../../../types';
2
2
  export type SchemaAttribute = Omit<AnyAttribute, 'name' | 'status'> & Record<string, unknown>;
3
3
  /**
4
4
  * Strapi schema, this is a simplification to make it easier to work with
@@ -17,6 +17,11 @@ export type Schema = {
17
17
  draftAndPublish?: boolean;
18
18
  localized?: boolean;
19
19
  };
20
+ /**
21
+ * Optional ordered rename hops for this schema. The AI server does not emit
22
+ * this today, but the CTB admin transform accepts it for forward compatibility.
23
+ */
24
+ renames?: RenameHop[];
20
25
  attributes: Record<string, SchemaAttribute>;
21
26
  sources?: unknown;
22
27
  };
@@ -1,12 +1,12 @@
1
1
  export declare const OptionBoxWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
2
2
  children?: React.ReactNode;
3
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
3
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
4
4
  ref?: any;
5
5
  }, "ref"> & {
6
6
  ref?: any;
7
7
  }, never> & Partial<Pick<Omit<import("@strapi/design-system").TransientBoxProps & {
8
8
  children?: React.ReactNode;
9
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
9
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
10
10
  ref?: any;
11
11
  }, "ref"> & {
12
12
  ref?: any;
@@ -1,6 +1,6 @@
1
1
  export declare const ComponentRow: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
2
2
  children?: React.ReactNode;
3
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
3
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
4
4
  ref?: any;
5
5
  }, "ref"> & {
6
6
  ref?: any;
@@ -9,7 +9,7 @@ export declare const ComponentRow: import("styled-components/dist/types").IStyle
9
9
  $isChildOfDynamicZone?: boolean;
10
10
  }, never> & Partial<Pick<import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
11
11
  children?: React.ReactNode;
12
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
12
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
13
13
  ref?: any;
14
14
  }, "ref"> & {
15
15
  ref?: any;
@@ -1,3 +1,4 @@
1
+ import type { AttributeRenameMigrationMode } from './RenameMigrationModal';
1
2
  import type { ContentStructure, FolderSelection, SectionKey } from './utils/contentStructure';
2
3
  import type { Component, ContentType } from '../../types';
3
4
  import type { ComponentWithChildren } from './utils/retrieveComponentsThatHaveComponents';
@@ -15,6 +16,10 @@ export interface DataManagerContextValue {
15
16
  forTarget: Struct.ModelType;
16
17
  targetUid: Internal.UID.Schema;
17
18
  name: string;
19
+ recordRename?: boolean;
20
+ declineRename?: boolean;
21
+ recordTargetRename?: boolean;
22
+ declineTargetRename?: boolean;
18
23
  }) => void;
19
24
  moveAttribute: (opts: {
20
25
  forTarget: Struct.ModelType;
@@ -32,7 +37,22 @@ export interface DataManagerContextValue {
32
37
  forTarget: Struct.ModelType;
33
38
  targetUid: Internal.UID.Schema;
34
39
  name: string;
35
- }) => void;
40
+ recordRename?: boolean;
41
+ declineRename?: boolean;
42
+ }) => void;
43
+ /**
44
+ * Resolves the user's consent to preserve data for one rename hop performed
45
+ * in the attribute form: `true` records the hop, `false` declines it (and the
46
+ * rest of its chain), `null` means the user cancelled the edit.
47
+ */
48
+ confirmAttributeRenameMigration: (rename: {
49
+ forTarget: Struct.ModelType;
50
+ uid: Internal.UID.Schema;
51
+ oldName: string;
52
+ newName: string;
53
+ }) => Promise<boolean | null>;
54
+ /** Effective `renameMigrations.attributes` plugin setting. */
55
+ attributeRenameMigrationMode: AttributeRenameMigrationMode;
36
56
  addCreatedComponentToDynamicZone: (opts: {
37
57
  forTarget: Struct.ModelType;
38
58
  targetUid: Internal.UID.Schema;
@@ -164,10 +184,16 @@ export interface DataManagerContextValue {
164
184
  saveSchema(): Promise<void>;
165
185
  isModified: boolean;
166
186
  isSaving: boolean;
187
+ /**
188
+ * Applies a whole-type change (AI chat). Rename hops declared by the change
189
+ * go through the same preservation consent as manual renames, so this may
190
+ * prompt the user. Resolves `false` when the user cancelled and nothing was
191
+ * applied.
192
+ */
167
193
  applyChange: (opts: {
168
194
  action: 'add' | 'update' | 'delete';
169
195
  schema: ContentType | Component;
170
- }) => void;
196
+ }) => Promise<boolean>;
171
197
  history: {
172
198
  undo(): void;
173
199
  redo(): void;
@@ -0,0 +1,73 @@
1
+ import { type RenameChain, type RenamePair } from './utils/groupRenameChains';
2
+ import type { RenameHop } from '../../types';
3
+ export type AttributeRenameMigrationMode = 'always' | 'never' | 'prompt-after-edit' | 'prompt-before-save';
4
+ export type AttributeRenameDecision = boolean | 'prompt';
5
+ export declare const getAttributeRenameDecision: (mode: AttributeRenameMigrationMode) => AttributeRenameDecision;
6
+ export declare const shouldPromptForRenamesBeforeSave: (mode: AttributeRenameMigrationMode) => boolean;
7
+ /**
8
+ * One rename *chain* on an existing type, shown as a single row in the
9
+ * confirmation modal. Consent is given per chain, never per hop: replaying a
10
+ * partial chain either fails or silently skips hops whose target column still
11
+ * exists. `key` is the chain id (`${uid}:chain:${firstHopIndex}`) so a decision
12
+ * maps back to every hop of that chain in the type's ordered `renames` array.
13
+ */
14
+ export interface PendingRename {
15
+ key: string;
16
+ uid: string;
17
+ typeName: string;
18
+ /** Net effect of the chain (`old -> new`); the raw hops for a pure swap-back. */
19
+ pairs: RenamePair[];
20
+ /** Intermediate names the chain routes through (e.g. `tmp`). */
21
+ via: string[];
22
+ /** True when the chain's net effect is empty (fields swapped back) but data still moves. */
23
+ isSwapBack?: boolean;
24
+ }
25
+ interface RenameMigrationModalProps {
26
+ renames: PendingRename[];
27
+ /**
28
+ * Resolves with the keys of the hops the user chose to preserve (every row
29
+ * is checked by default), or an empty set for "don't preserve data".
30
+ */
31
+ onConfirm: (acceptedKeys: Set<string>) => void;
32
+ /** Aborts the current edit or save and returns to editing. */
33
+ onCancel: () => void;
34
+ }
35
+ declare const RenameMigrationModal: ({ renames, onConfirm, onCancel }: RenameMigrationModalProps) => import("react/jsx-runtime").JSX.Element;
36
+ export { RenameMigrationModal };
37
+ type RenameAwareEntry = {
38
+ action?: string;
39
+ uid: string;
40
+ displayName?: string;
41
+ renames?: RenameHop[];
42
+ };
43
+ /**
44
+ * Builds the modal row for one chain. A chain whose net effect is empty (the
45
+ * user renamed fields back to their original names through a swap) still has
46
+ * to run every hop, so its raw hops are shown instead of an empty row.
47
+ */
48
+ export declare const toPendingRename: (chain: RenameChain, renames: RenameHop[], { uid, typeName }: {
49
+ uid: string;
50
+ typeName: string;
51
+ }) => PendingRename;
52
+ /**
53
+ * Groups the ordered per-type `renames` arrays in a request payload into
54
+ * chains for display, one `PendingRename` per chain, preserving order.
55
+ */
56
+ export declare const collectPendingRenames: (requestData: {
57
+ contentTypes: RenameAwareEntry[];
58
+ components: RenameAwareEntry[];
59
+ }) => PendingRename[];
60
+ /**
61
+ * Keeps only the hops of `renames` that belong to an accepted chain. Filtering
62
+ * by index preserves the original order, and a chain is always kept or dropped
63
+ * as a whole, so the result can never be a truncated chain.
64
+ */
65
+ export declare const filterRenamesByAcceptedChains: (uid: string, renames: RenameHop[], acceptedChainIds: Set<string>) => RenameHop[];
66
+ /**
67
+ * Mutates the request payload so each type keeps only the rename chains the
68
+ * user accepted; types left with no accepted hops drop their `renames` entirely.
69
+ */
70
+ export declare const applyRenameDecisions: (requestData: {
71
+ contentTypes: RenameAwareEntry[];
72
+ components: RenameAwareEntry[];
73
+ }, acceptedKeys: Set<string>) => void;
@@ -110,13 +110,28 @@ type CreateSchemaPayload = {
110
110
  };
111
111
  folder?: FolderAssignmentPayload;
112
112
  };
113
- type EditAttributePayload = {
113
+ type RenameConsentPayload = {
114
+ /** Record the hop so the server preserves data (default). */
115
+ recordRename?: boolean;
116
+ /**
117
+ * The user declined to preserve data for this hop: remember both names so
118
+ * later hops of the same chain are declined without another prompt.
119
+ */
120
+ declineRename?: boolean;
121
+ /**
122
+ * Same pair for the other side of a bidirectional relation, when the edit
123
+ * renames it on the target type.
124
+ */
125
+ recordTargetRename?: boolean;
126
+ declineTargetRename?: boolean;
127
+ };
128
+ type EditAttributePayload = RenameConsentPayload & {
114
129
  attributeToSet: AttributeMutation;
115
130
  forTarget: Struct.ModelType;
116
131
  targetUid: string;
117
132
  name: string;
118
133
  };
119
- type EditCustomFieldAttributePayload = {
134
+ type EditCustomFieldAttributePayload = RenameConsentPayload & {
120
135
  attributeToSet: AttributeMutation;
121
136
  forTarget: Struct.ModelType;
122
137
  targetUid: string;
@@ -46,6 +46,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
46
46
  [k: string]: unknown;
47
47
  };
48
48
  })[];
49
+ renames?: import("../../../types").RenameHop[];
49
50
  displayName: string;
50
51
  description?: string;
51
52
  icon?: string;
@@ -66,6 +67,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
66
67
  plugin?: string | undefined;
67
68
  info?: import("@strapi/types/dist/struct/schema.js").SchemaInfo | undefined;
68
69
  status?: import("../../../types").Status | undefined;
70
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
69
71
  action: string;
70
72
  } | {
71
73
  attributes: ({
@@ -79,6 +81,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
79
81
  [k: string]: unknown;
80
82
  };
81
83
  })[];
84
+ renames?: import("../../../types").RenameHop[];
82
85
  singularName: string;
83
86
  pluralName: string;
84
87
  displayName: string;
@@ -101,6 +104,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
101
104
  plugin?: string | undefined;
102
105
  info?: import("@strapi/types/dist/struct/schema.js").SchemaInfo | undefined;
103
106
  status?: import("../../../types").Status | undefined;
107
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
104
108
  action: string;
105
109
  } | {
106
110
  attributes: ({
@@ -114,6 +118,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
114
118
  [k: string]: unknown;
115
119
  };
116
120
  })[];
121
+ renames?: import("../../../types").RenameHop[];
117
122
  displayName: string;
118
123
  description?: string;
119
124
  icon?: string;
@@ -138,6 +143,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
138
143
  visible?: boolean | undefined;
139
144
  status?: import("../../../types").Status | undefined;
140
145
  restrictRelationsTo?: import("@strapi/types/dist/schema/attribute/index.js").RelationKind.Any[] | null | undefined;
146
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
141
147
  action: string;
142
148
  category: string | undefined;
143
149
  } | {
@@ -152,6 +158,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
152
158
  [k: string]: unknown;
153
159
  };
154
160
  })[];
161
+ renames?: import("../../../types").RenameHop[];
155
162
  singularName: string;
156
163
  pluralName: string;
157
164
  displayName: string;
@@ -178,6 +185,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
178
185
  visible?: boolean | undefined;
179
186
  status?: import("../../../types").Status | undefined;
180
187
  restrictRelationsTo?: import("@strapi/types/dist/schema/attribute/index.js").RelationKind.Any[] | null | undefined;
188
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
181
189
  action: string;
182
190
  category: string | undefined;
183
191
  })[];
@@ -196,6 +204,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
196
204
  [k: string]: unknown;
197
205
  };
198
206
  })[];
207
+ renames?: import("../../../types").RenameHop[];
199
208
  displayName: string;
200
209
  description?: string;
201
210
  icon?: string;
@@ -216,6 +225,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
216
225
  plugin?: string | undefined;
217
226
  info?: import("@strapi/types/dist/struct/schema.js").SchemaInfo | undefined;
218
227
  status?: import("../../../types").Status | undefined;
228
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
219
229
  action: string;
220
230
  } | {
221
231
  attributes: ({
@@ -229,6 +239,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
229
239
  [k: string]: unknown;
230
240
  };
231
241
  })[];
242
+ renames?: import("../../../types").RenameHop[];
232
243
  singularName: string;
233
244
  pluralName: string;
234
245
  displayName: string;
@@ -251,6 +262,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
251
262
  plugin?: string | undefined;
252
263
  info?: import("@strapi/types/dist/struct/schema.js").SchemaInfo | undefined;
253
264
  status?: import("../../../types").Status | undefined;
265
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
254
266
  action: string;
255
267
  } | {
256
268
  attributes: ({
@@ -264,6 +276,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
264
276
  [k: string]: unknown;
265
277
  };
266
278
  })[];
279
+ renames?: import("../../../types").RenameHop[];
267
280
  displayName: string;
268
281
  description?: string;
269
282
  icon?: string;
@@ -288,6 +301,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
288
301
  visible?: boolean | undefined;
289
302
  status?: import("../../../types").Status | undefined;
290
303
  restrictRelationsTo?: import("@strapi/types/dist/schema/attribute/index.js").RelationKind.Any[] | null | undefined;
304
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
291
305
  action: string;
292
306
  category: string | undefined;
293
307
  } | {
@@ -302,6 +316,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
302
316
  [k: string]: unknown;
303
317
  };
304
318
  })[];
319
+ renames?: import("../../../types").RenameHop[];
305
320
  singularName: string;
306
321
  pluralName: string;
307
322
  displayName: string;
@@ -328,6 +343,7 @@ declare const stateToRequestData: ({ components, contentTypes, contentStructure,
328
343
  visible?: boolean | undefined;
329
344
  status?: import("../../../types").Status | undefined;
330
345
  restrictRelationsTo?: import("@strapi/types/dist/schema/attribute/index.js").RelationKind.Any[] | null | undefined;
346
+ declinedRenameNames?: import("../../../types").DeclinedRenameNames | undefined;
331
347
  action: string;
332
348
  category: string | undefined;
333
349
  })[];
@@ -0,0 +1,31 @@
1
+ import type { RenameHop } from '../../../types';
2
+ export interface RenamePair {
3
+ oldName: string;
4
+ newName: string;
5
+ }
6
+ /**
7
+ * A group of rename hops on one type that share attribute names, transitively:
8
+ * `a -> b`, `b -> c` is one chain, so is the swap `a -> tmp`, `b -> a`,
9
+ * `tmp -> b`, while `a -> b` and `x -> y` are two chains. Consent to preserve
10
+ * data is given per chain, never per hop, because replaying a partial chain
11
+ * either fails or silently skips hops whose target column still exists.
12
+ */
13
+ export interface RenameChain {
14
+ /** `${uid}:chain:${firstHopIndex}` — stable key for consent decisions. */
15
+ id: string;
16
+ /** Indexes into the type's ordered `renames[]`, ascending. */
17
+ hopIndexes: number[];
18
+ /** Net effect after replaying the chain's hops, in first-appearance order. */
19
+ pairs: RenamePair[];
20
+ /** Names that only ever appear as intermediates (e.g. `tmp`). */
21
+ via: string[];
22
+ }
23
+ /**
24
+ * Groups a type's ordered `renames[]` into chains (see `RenameChain`). Chains
25
+ * are ordered by their first hop; hops inside a chain keep their index order.
26
+ */
27
+ export declare const groupRenameChains: (uid: string, renames: RenameHop[]) => RenameChain[];
28
+ /**
29
+ * Maps every hop index of `renames` to the chain it belongs to.
30
+ */
31
+ export declare const chainByHopIndex: (chains: RenameChain[]) => Map<number, RenameChain>;
@@ -0,0 +1,10 @@
1
+ import type { AnyAttribute } from '../../../types';
2
+ /**
3
+ * Whether `newAttribute` keeps the storage of `previousAttribute`, i.e. whether
4
+ * renaming the underlying database artifact is enough to carry the data over.
5
+ * A type change (or a relation retargeted or its direction switched, or a
6
+ * component swapped) must go through the regular drop-and-recreate path:
7
+ * renaming the column and letting schema sync alter its type in place can fail
8
+ * at startup on Postgres/MySQL.
9
+ */
10
+ export declare const isStorageCompatibleRename: (previousAttribute: AnyAttribute, newAttribute: AnyAttribute) => boolean;
@@ -0,0 +1,24 @@
1
+ import { type AttributeRenameMigrationMode } from '../RenameMigrationModal';
2
+ import type { RenameHop } from '../../../types';
3
+ export type AfterEditRenameConsent = 'accept' | 'decline' | 'prompt';
4
+ /**
5
+ * Decides whether a single rename hop (`oldName -> newName`) performed in the
6
+ * attribute form needs the user's consent to preserve data, given the hops
7
+ * already recorded on the type and the names of chains the user has declined.
8
+ *
9
+ * Consent inherits along a chain, so a chain is always accepted or declined as
10
+ * a whole (replaying a partial chain either fails or silently skips hops):
11
+ *
12
+ * 1. A hop that joins an accepted chain — it continues a recorded hop
13
+ * (`oldName` was produced by one) or swaps into a name a recorded hop
14
+ * vacated (`newName`) — is accepted without a prompt.
15
+ * 2. A hop that touches a declined name is declined without a prompt.
16
+ * 3. Otherwise the mode decides; `prompt-after-edit` asks the user.
17
+ */
18
+ export declare const resolveAfterEditRenameConsent: ({ renames, declinedRenameNames, oldName, newName, mode, }: {
19
+ renames: RenameHop[];
20
+ declinedRenameNames: string[];
21
+ oldName: string;
22
+ newName: string;
23
+ mode: AttributeRenameMigrationMode;
24
+ }) => AfterEditRenameConsent;
@@ -0,0 +1,26 @@
1
+ import type { RenameChain } from './groupRenameChains';
2
+ import type { RenameHop } from '../../../types';
3
+ export interface SplitChains {
4
+ /** Chains that join a chain the user already accepted: kept without a prompt. */
5
+ keep: RenameChain[];
6
+ /** Chains touching a name the user already declined: dropped without a prompt. */
7
+ decline: RenameChain[];
8
+ /** Chains with no prior decision: the user has to be asked. */
9
+ prompt: RenameChain[];
10
+ }
11
+ /**
12
+ * Buckets incoming rename chains (e.g. declared by the AI chat) by the consent
13
+ * the user already gave for the hops recorded on the type, using the same rules
14
+ * as the per-edit prompt (see `resolveAfterEditRenameConsent`): a chain that
15
+ * continues a recorded hop or swaps into a name one vacated is kept, a chain
16
+ * touching a declined name is declined, anything else needs a prompt.
17
+ */
18
+ export declare const splitChainsByInheritedConsent: ({ recorded, declinedRenameNames, chains, renames, }: {
19
+ recorded: RenameHop[];
20
+ declinedRenameNames: string[];
21
+ chains: RenameChain[];
22
+ /** The ordered hops the chains index into. */
23
+ renames: RenameHop[];
24
+ }) => SplitChains;
25
+ /** Every attribute name a set of chains touches, deduplicated, in hop order. */
26
+ export declare const namesOfChains: (chains: RenameChain[], renames: RenameHop[]) => string[];
@@ -0,0 +1,40 @@
1
+ import type { Status } from '../../../types';
2
+ import type { AttributeRenameMigrationMode } from '../../DataManager/RenameMigrationModal';
3
+ /** The loosely typed attribute data held by the form reducer (`FormModalData`). */
4
+ export type AttributeFormData = Record<string, unknown> & {
5
+ name?: string;
6
+ status?: Status;
7
+ type?: string;
8
+ relation?: string;
9
+ target?: string | null;
10
+ component?: string;
11
+ repeatable?: boolean;
12
+ };
13
+ export interface RenameStorageChange {
14
+ oldName: string;
15
+ newName: string;
16
+ /** Human label of the field's storage before the edit (e.g. `relation (oneToMany to api::tag.tag)`). */
17
+ oldType: string;
18
+ /** Human label of the field's storage after the edit. */
19
+ newType: string;
20
+ }
21
+ /**
22
+ * Human label for what defines an attribute's storage: the type, plus the
23
+ * relation kind/target for relations and the component uid (+ repeatable) for
24
+ * components, so a warning can say what changed.
25
+ */
26
+ export declare const describeAttributeStorage: (attribute: AttributeFormData) => string;
27
+ /**
28
+ * Detects an attribute edit that renames an existing field *and* changes its
29
+ * storage (type, relation kind/target, component uid/repeatable). Such a rename
30
+ * cannot be replayed as a data-preserving migration, so the field is dropped
31
+ * and recreated empty — the user should be warned before saving.
32
+ *
33
+ * For a relation, renaming the other side (`targetAttribute`) counts as well:
34
+ * the warning then names that field.
35
+ *
36
+ * Returns `null` when there is nothing to warn about: rename migrations are
37
+ * disabled, the field is brand new (no data yet), no name changed, or the
38
+ * storage is unchanged.
39
+ */
40
+ export declare const getRenameStorageChange: (initial: AttributeFormData, modified: AttributeFormData, mode: AttributeRenameMigrationMode) => RenameStorageChange | null;
@@ -2,13 +2,13 @@ import type { Component, ContentType } from '../types';
2
2
  import type { UID } from '@strapi/types';
3
3
  export declare const ListGrid: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("@strapi/design-system").TransientBoxProps & {
4
4
  children?: React.ReactNode;
5
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
5
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
6
6
  ref?: any;
7
7
  }, "ref"> & {
8
8
  ref?: any;
9
9
  }, never> & Partial<Pick<Omit<import("@strapi/design-system").TransientBoxProps & {
10
10
  children?: React.ReactNode;
11
- } & import("@strapi/design-system/dist/types").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
11
+ } & import("@strapi/design-system/dist/types.js").AsProp<import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements>> & Omit<Omit<any, "ref">, "children" | keyof import("@strapi/design-system/dist/types.js").AsProp<C> | keyof import("@strapi/design-system").TransientBoxProps> & {
12
12
  ref?: any;
13
13
  }, "ref"> & {
14
14
  ref?: any;