@strapi/core 0.0.0-experimental.90ca9123352ed07e0a9cedaf4bcad1475e74137f → 0.0.0-experimental.e3e48deb89bd0a1b6cc69b698696566fa7854a95

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 (254) hide show
  1. package/dist/Strapi.d.ts +5 -3
  2. package/dist/Strapi.d.ts.map +1 -1
  3. package/dist/Strapi.js +19 -7
  4. package/dist/Strapi.js.map +1 -1
  5. package/dist/Strapi.mjs +19 -7
  6. package/dist/Strapi.mjs.map +1 -1
  7. package/dist/configuration/index.d.ts.map +1 -1
  8. package/dist/configuration/index.js +4 -4
  9. package/dist/configuration/index.js.map +1 -1
  10. package/dist/configuration/index.mjs +1 -1
  11. package/dist/configuration/index.mjs.map +1 -1
  12. package/dist/configuration/urls.d.ts +8 -0
  13. package/dist/configuration/urls.d.ts.map +1 -0
  14. package/dist/configuration/urls.js +68 -0
  15. package/dist/configuration/urls.js.map +1 -0
  16. package/dist/configuration/urls.mjs +66 -0
  17. package/dist/configuration/urls.mjs.map +1 -0
  18. package/dist/core-api/controller/collection-type.js.map +1 -1
  19. package/dist/core-api/controller/collection-type.mjs.map +1 -1
  20. package/dist/core-api/controller/index.d.ts.map +1 -1
  21. package/dist/core-api/controller/index.js +6 -1
  22. package/dist/core-api/controller/index.js.map +1 -1
  23. package/dist/core-api/controller/index.mjs +6 -1
  24. package/dist/core-api/controller/index.mjs.map +1 -1
  25. package/dist/core-api/controller/single-type.js.map +1 -1
  26. package/dist/core-api/controller/single-type.mjs.map +1 -1
  27. package/dist/core-api/controller/transform.d.ts +8 -7
  28. package/dist/core-api/controller/transform.d.ts.map +1 -1
  29. package/dist/core-api/controller/transform.js +16 -7
  30. package/dist/core-api/controller/transform.js.map +1 -1
  31. package/dist/core-api/controller/transform.mjs +16 -7
  32. package/dist/core-api/controller/transform.mjs.map +1 -1
  33. package/dist/core-api/service/collection-type.d.ts.map +1 -1
  34. package/dist/core-api/service/collection-type.js.map +1 -1
  35. package/dist/core-api/service/collection-type.mjs.map +1 -1
  36. package/dist/core-api/service/single-type.d.ts +3 -2
  37. package/dist/core-api/service/single-type.d.ts.map +1 -1
  38. package/dist/core-api/service/single-type.js +14 -3
  39. package/dist/core-api/service/single-type.js.map +1 -1
  40. package/dist/core-api/service/single-type.mjs +14 -3
  41. package/dist/core-api/service/single-type.mjs.map +1 -1
  42. package/dist/domain/content-type/index.d.ts.map +1 -1
  43. package/dist/domain/content-type/index.js +3 -0
  44. package/dist/domain/content-type/index.js.map +1 -1
  45. package/dist/domain/content-type/index.mjs +3 -0
  46. package/dist/domain/content-type/index.mjs.map +1 -1
  47. package/dist/domain/content-type/validator.d.ts.map +1 -1
  48. package/dist/domain/content-type/validator.js +1 -1
  49. package/dist/domain/content-type/validator.js.map +1 -1
  50. package/dist/domain/content-type/validator.mjs +2 -2
  51. package/dist/domain/content-type/validator.mjs.map +1 -1
  52. package/dist/domain/module/index.d.ts.map +1 -1
  53. package/dist/domain/module/index.js +2 -3
  54. package/dist/domain/module/index.js.map +1 -1
  55. package/dist/domain/module/index.mjs +2 -3
  56. package/dist/domain/module/index.mjs.map +1 -1
  57. package/dist/ee/index.js.map +1 -1
  58. package/dist/ee/index.mjs.map +1 -1
  59. package/dist/loaders/apis.js +1 -1
  60. package/dist/loaders/apis.js.map +1 -1
  61. package/dist/loaders/apis.mjs +2 -2
  62. package/dist/loaders/apis.mjs.map +1 -1
  63. package/dist/loaders/plugins/get-enabled-plugins.js +1 -1
  64. package/dist/loaders/plugins/get-enabled-plugins.js.map +1 -1
  65. package/dist/loaders/plugins/get-enabled-plugins.mjs +2 -2
  66. package/dist/loaders/plugins/get-enabled-plugins.mjs.map +1 -1
  67. package/dist/middlewares/security.d.ts.map +1 -1
  68. package/dist/middlewares/security.js +2 -2
  69. package/dist/middlewares/security.js.map +1 -1
  70. package/dist/middlewares/security.mjs +2 -2
  71. package/dist/middlewares/security.mjs.map +1 -1
  72. package/dist/migrations/draft-publish.d.ts +17 -0
  73. package/dist/migrations/draft-publish.d.ts.map +1 -0
  74. package/dist/migrations/draft-publish.js +59 -0
  75. package/dist/migrations/draft-publish.js.map +1 -0
  76. package/dist/migrations/draft-publish.mjs +59 -0
  77. package/dist/migrations/draft-publish.mjs.map +1 -0
  78. package/dist/registries/config.d.ts +2 -2
  79. package/dist/registries/config.d.ts.map +1 -1
  80. package/dist/registries/config.js +14 -6
  81. package/dist/registries/config.js.map +1 -1
  82. package/dist/registries/config.mjs +15 -5
  83. package/dist/registries/config.mjs.map +1 -1
  84. package/dist/services/document-service/common.d.ts +2 -2
  85. package/dist/services/document-service/common.d.ts.map +1 -1
  86. package/dist/services/document-service/common.js.map +1 -1
  87. package/dist/services/document-service/common.mjs.map +1 -1
  88. package/dist/services/document-service/draft-and-publish.d.ts +9 -23
  89. package/dist/services/document-service/draft-and-publish.d.ts.map +1 -1
  90. package/dist/services/document-service/draft-and-publish.js +37 -9
  91. package/dist/services/document-service/draft-and-publish.js.map +1 -1
  92. package/dist/services/document-service/draft-and-publish.mjs +38 -10
  93. package/dist/services/document-service/draft-and-publish.mjs.map +1 -1
  94. package/dist/services/document-service/index.d.ts.map +1 -1
  95. package/dist/services/document-service/index.js +4 -4
  96. package/dist/services/document-service/index.js.map +1 -1
  97. package/dist/services/document-service/index.mjs +2 -2
  98. package/dist/services/document-service/index.mjs.map +1 -1
  99. package/dist/services/document-service/internationalization.d.ts +2 -1
  100. package/dist/services/document-service/internationalization.d.ts.map +1 -1
  101. package/dist/services/document-service/internationalization.js +14 -0
  102. package/dist/services/document-service/internationalization.js.map +1 -1
  103. package/dist/services/document-service/internationalization.mjs +15 -1
  104. package/dist/services/document-service/internationalization.mjs.map +1 -1
  105. package/dist/services/document-service/repository.d.ts +3 -0
  106. package/dist/services/document-service/repository.d.ts.map +1 -0
  107. package/dist/services/document-service/repository.js +295 -0
  108. package/dist/services/document-service/repository.js.map +1 -0
  109. package/dist/services/document-service/repository.mjs +295 -0
  110. package/dist/services/document-service/repository.mjs.map +1 -0
  111. package/dist/services/document-service/transform/fields.d.ts.map +1 -1
  112. package/dist/services/document-service/transform/fields.js +11 -10
  113. package/dist/services/document-service/transform/fields.js.map +1 -1
  114. package/dist/services/document-service/transform/fields.mjs +11 -10
  115. package/dist/services/document-service/transform/fields.mjs.map +1 -1
  116. package/dist/services/document-service/transform/id-map.d.ts +1 -1
  117. package/dist/services/document-service/transform/id-map.d.ts.map +1 -1
  118. package/dist/services/document-service/transform/id-map.js +15 -9
  119. package/dist/services/document-service/transform/id-map.js.map +1 -1
  120. package/dist/services/document-service/transform/id-map.mjs +16 -10
  121. package/dist/services/document-service/transform/id-map.mjs.map +1 -1
  122. package/dist/services/document-service/transform/id-transform.d.ts +4 -25
  123. package/dist/services/document-service/transform/id-transform.d.ts.map +1 -1
  124. package/dist/services/document-service/transform/id-transform.js +19 -43
  125. package/dist/services/document-service/transform/id-transform.js.map +1 -1
  126. package/dist/services/document-service/transform/id-transform.mjs +20 -44
  127. package/dist/services/document-service/transform/id-transform.mjs.map +1 -1
  128. package/dist/services/document-service/transform/populate.d.ts +5 -2
  129. package/dist/services/document-service/transform/populate.d.ts.map +1 -1
  130. package/dist/services/document-service/transform/populate.js +0 -10
  131. package/dist/services/document-service/transform/populate.js.map +1 -1
  132. package/dist/services/document-service/transform/populate.mjs +0 -10
  133. package/dist/services/document-service/transform/populate.mjs.map +1 -1
  134. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts +1 -1
  135. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts.map +1 -1
  136. package/dist/services/document-service/transform/relations/extract/data-ids.js +28 -14
  137. package/dist/services/document-service/transform/relations/extract/data-ids.js.map +1 -1
  138. package/dist/services/document-service/transform/relations/extract/data-ids.mjs +28 -14
  139. package/dist/services/document-service/transform/relations/extract/data-ids.mjs.map +1 -1
  140. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts +1 -1
  141. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts.map +1 -1
  142. package/dist/services/document-service/transform/relations/transform/data-ids.js +65 -39
  143. package/dist/services/document-service/transform/relations/transform/data-ids.js.map +1 -1
  144. package/dist/services/document-service/transform/relations/transform/data-ids.mjs +66 -40
  145. package/dist/services/document-service/transform/relations/transform/data-ids.mjs.map +1 -1
  146. package/dist/services/document-service/transform/relations/utils/data.d.ts +2 -4
  147. package/dist/services/document-service/transform/relations/utils/data.d.ts.map +1 -1
  148. package/dist/services/document-service/transform/relations/utils/data.js +1 -1
  149. package/dist/services/document-service/transform/relations/utils/data.js.map +1 -1
  150. package/dist/services/document-service/transform/relations/utils/data.mjs +1 -1
  151. package/dist/services/document-service/transform/relations/utils/data.mjs.map +1 -1
  152. package/dist/services/document-service/transform/relations/utils/dp.d.ts +10 -0
  153. package/dist/services/document-service/transform/relations/utils/dp.d.ts.map +1 -0
  154. package/dist/services/document-service/transform/relations/utils/dp.js +25 -0
  155. package/dist/services/document-service/transform/relations/utils/dp.js.map +1 -0
  156. package/dist/services/document-service/transform/relations/utils/dp.mjs +25 -0
  157. package/dist/services/document-service/transform/relations/utils/dp.mjs.map +1 -0
  158. package/dist/services/document-service/transform/relations/utils/i18n.d.ts +2 -2
  159. package/dist/services/document-service/transform/relations/utils/i18n.d.ts.map +1 -1
  160. package/dist/services/document-service/transform/relations/utils/i18n.js.map +1 -1
  161. package/dist/services/document-service/transform/relations/utils/i18n.mjs.map +1 -1
  162. package/dist/services/document-service/transform/relations/utils/types.d.ts +9 -2
  163. package/dist/services/document-service/transform/relations/utils/types.d.ts.map +1 -1
  164. package/dist/services/document-service/transform/types.d.ts +1 -1
  165. package/dist/services/document-service/transform/types.d.ts.map +1 -1
  166. package/dist/services/document-service/utils/populate.d.ts +8 -1
  167. package/dist/services/document-service/utils/populate.d.ts.map +1 -1
  168. package/dist/services/document-service/utils/populate.js +5 -5
  169. package/dist/services/document-service/utils/populate.js.map +1 -1
  170. package/dist/services/document-service/utils/populate.mjs +5 -5
  171. package/dist/services/document-service/utils/populate.mjs.map +1 -1
  172. package/dist/services/entity-service/components.d.ts +1 -4
  173. package/dist/services/entity-service/components.d.ts.map +1 -1
  174. package/dist/services/entity-service/components.js +13 -99
  175. package/dist/services/entity-service/components.js.map +1 -1
  176. package/dist/services/entity-service/components.mjs +14 -100
  177. package/dist/services/entity-service/components.mjs.map +1 -1
  178. package/dist/services/entity-service/index.d.ts +1 -3
  179. package/dist/services/entity-service/index.d.ts.map +1 -1
  180. package/dist/services/entity-service/index.js +34 -199
  181. package/dist/services/entity-service/index.js.map +1 -1
  182. package/dist/services/entity-service/index.mjs +27 -192
  183. package/dist/services/entity-service/index.mjs.map +1 -1
  184. package/dist/services/entity-service/params.d.ts +4 -4
  185. package/dist/services/entity-service/params.d.ts.map +1 -1
  186. package/dist/services/entity-service/params.js +1 -1
  187. package/dist/services/entity-service/params.js.map +1 -1
  188. package/dist/services/entity-service/params.mjs +1 -1
  189. package/dist/services/entity-service/params.mjs.map +1 -1
  190. package/dist/services/entity-validator/index.js +1 -1
  191. package/dist/services/entity-validator/index.js.map +1 -1
  192. package/dist/services/entity-validator/index.mjs +1 -1
  193. package/dist/services/entity-validator/index.mjs.map +1 -1
  194. package/dist/utils/is-initialized.js +1 -1
  195. package/dist/utils/is-initialized.js.map +1 -1
  196. package/dist/utils/is-initialized.mjs +1 -1
  197. package/dist/utils/is-initialized.mjs.map +1 -1
  198. package/dist/utils/load-config-file.js +1 -1
  199. package/dist/utils/load-config-file.js.map +1 -1
  200. package/dist/utils/load-config-file.mjs +2 -2
  201. package/dist/utils/load-config-file.mjs.map +1 -1
  202. package/dist/utils/transform-content-types-to-models.d.ts +174 -3
  203. package/dist/utils/transform-content-types-to-models.d.ts.map +1 -1
  204. package/dist/utils/transform-content-types-to-models.js +80 -41
  205. package/dist/utils/transform-content-types-to-models.js.map +1 -1
  206. package/dist/utils/transform-content-types-to-models.mjs +79 -41
  207. package/dist/utils/transform-content-types-to-models.mjs.map +1 -1
  208. package/package.json +14 -14
  209. package/dist/services/document-service/collection-type.d.ts +0 -4
  210. package/dist/services/document-service/collection-type.d.ts.map +0 -1
  211. package/dist/services/document-service/collection-type.js +0 -145
  212. package/dist/services/document-service/collection-type.js.map +0 -1
  213. package/dist/services/document-service/collection-type.mjs +0 -145
  214. package/dist/services/document-service/collection-type.mjs.map +0 -1
  215. package/dist/services/document-service/document-engine.d.ts +0 -8
  216. package/dist/services/document-service/document-engine.d.ts.map +0 -1
  217. package/dist/services/document-service/document-engine.js +0 -249
  218. package/dist/services/document-service/document-engine.js.map +0 -1
  219. package/dist/services/document-service/document-engine.mjs +0 -250
  220. package/dist/services/document-service/document-engine.mjs.map +0 -1
  221. package/dist/services/document-service/repository-factory.d.ts +0 -3
  222. package/dist/services/document-service/repository-factory.d.ts.map +0 -1
  223. package/dist/services/document-service/repository-factory.js +0 -12
  224. package/dist/services/document-service/repository-factory.js.map +0 -1
  225. package/dist/services/document-service/repository-factory.mjs +0 -12
  226. package/dist/services/document-service/repository-factory.mjs.map +0 -1
  227. package/dist/services/document-service/single-type.d.ts +0 -4
  228. package/dist/services/document-service/single-type.d.ts.map +0 -1
  229. package/dist/services/document-service/single-type.js +0 -92
  230. package/dist/services/document-service/single-type.js.map +0 -1
  231. package/dist/services/document-service/single-type.mjs +0 -92
  232. package/dist/services/document-service/single-type.mjs.map +0 -1
  233. package/dist/services/document-service/transform/filters.js +0 -49
  234. package/dist/services/document-service/transform/filters.js.map +0 -1
  235. package/dist/services/document-service/transform/filters.mjs +0 -49
  236. package/dist/services/document-service/transform/filters.mjs.map +0 -1
  237. package/dist/services/document-service/transform/relations/transform/output-ids.js +0 -26
  238. package/dist/services/document-service/transform/relations/transform/output-ids.js.map +0 -1
  239. package/dist/services/document-service/transform/relations/transform/output-ids.mjs +0 -26
  240. package/dist/services/document-service/transform/relations/transform/output-ids.mjs.map +0 -1
  241. package/dist/services/document-service/transform/sort.js +0 -44
  242. package/dist/services/document-service/transform/sort.js.map +0 -1
  243. package/dist/services/document-service/transform/sort.mjs +0 -44
  244. package/dist/services/document-service/transform/sort.mjs.map +0 -1
  245. package/dist/services/document-service/transform/utils.js +0 -23
  246. package/dist/services/document-service/transform/utils.js.map +0 -1
  247. package/dist/services/document-service/transform/utils.mjs +0 -23
  248. package/dist/services/document-service/transform/utils.mjs.map +0 -1
  249. package/dist/services/utils/upload-files.d.ts +0 -8
  250. package/dist/services/utils/upload-files.d.ts.map +0 -1
  251. package/dist/services/utils/upload-files.js +0 -64
  252. package/dist/services/utils/upload-files.js.map +0 -1
  253. package/dist/services/utils/upload-files.mjs +0 -63
  254. package/dist/services/utils/upload-files.mjs.map +0 -1
@@ -1,9 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const database = require("@strapi/database");
3
4
  const cuid2 = require("@paralleldrive/cuid2");
4
5
  const assert = require("node:assert");
6
+ const _ = require("lodash/fp");
5
7
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
6
8
  const assert__default = /* @__PURE__ */ _interopDefault(assert);
9
+ const ___default = /* @__PURE__ */ _interopDefault(_);
10
+ const { identifiers } = database.utils;
11
+ const COMPONENT_JOIN_TABLE_SUFFIX = "components";
12
+ const DZ_JOIN_TABLE_SUFFIX = "components";
13
+ const COMPONENT_INVERSE_COLUMN_NAME = "component";
14
+ const COMPONENT_TYPE_COLUMN = "component_type";
15
+ const ENTITY = "entity";
16
+ const getComponentJoinTableName = (collectionName) => identifiers.getTableName(collectionName, { suffix: COMPONENT_JOIN_TABLE_SUFFIX });
17
+ const getDzJoinTableName = (collectionName) => identifiers.getTableName(collectionName, { suffix: DZ_JOIN_TABLE_SUFFIX });
18
+ const { ID_COLUMN: id, FIELD_COLUMN: field, ORDER_COLUMN: order } = identifiers;
7
19
  const transformAttribute = (name, attribute, contentType) => {
8
20
  switch (attribute.type) {
9
21
  case "media": {
@@ -15,6 +27,11 @@ const transformAttribute = (name, attribute, contentType) => {
15
27
  };
16
28
  }
17
29
  case "component": {
30
+ const joinTableName = getComponentJoinTableName(contentType.collectionName);
31
+ const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);
32
+ const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(
33
+ COMPONENT_INVERSE_COLUMN_NAME
34
+ );
18
35
  return {
19
36
  type: "relation",
20
37
  relation: attribute.repeatable === true ? "oneToMany" : "oneToOne",
@@ -22,45 +39,50 @@ const transformAttribute = (name, attribute, contentType) => {
22
39
  // We need the join table name to be deterministic,
23
40
  // We need to allow passing the join table name as an option
24
41
  joinTable: {
25
- name: `${contentType.collectionName}_components`,
42
+ name: joinTableName,
26
43
  joinColumn: {
27
- name: "entity_id",
28
- referencedColumn: "id"
44
+ name: joinColumnEntityName,
45
+ referencedColumn: id
29
46
  },
30
47
  inverseJoinColumn: {
31
- name: "component_id",
32
- referencedColumn: "id"
48
+ name: joinColumnInverseName,
49
+ referencedColumn: id
33
50
  },
34
51
  on: {
35
52
  field: name
36
53
  },
37
- orderColumnName: "order",
54
+ orderColumnName: order,
38
55
  orderBy: {
39
56
  order: "asc"
40
57
  },
41
- pivotColumns: ["entity_id", "component_id", "field", "component_type"]
58
+ pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN]
42
59
  }
43
60
  };
44
61
  }
45
62
  case "dynamiczone": {
63
+ const joinTableName = getDzJoinTableName(contentType.collectionName);
64
+ const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);
65
+ const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(
66
+ COMPONENT_INVERSE_COLUMN_NAME
67
+ );
46
68
  return {
47
69
  type: "relation",
48
70
  relation: "morphToMany",
49
71
  // TODO: handle restrictions at some point
50
72
  // target: attribute.components,
51
73
  joinTable: {
52
- name: `${contentType.collectionName}_components`,
74
+ name: joinTableName,
53
75
  joinColumn: {
54
- name: "entity_id",
55
- referencedColumn: "id"
76
+ name: joinColumnEntityName,
77
+ referencedColumn: id
56
78
  },
57
79
  morphColumn: {
58
80
  idColumn: {
59
- name: "component_id",
60
- referencedColumn: "id"
81
+ name: joinColumnInverseName,
82
+ referencedColumn: id
61
83
  },
62
84
  typeColumn: {
63
- name: "component_type"
85
+ name: COMPONENT_TYPE_COLUMN
64
86
  },
65
87
  typeField: "__component"
66
88
  },
@@ -70,7 +92,7 @@ const transformAttribute = (name, attribute, contentType) => {
70
92
  orderBy: {
71
93
  order: "asc"
72
94
  },
73
- pivotColumns: ["entity_id", "component_id", "field", "component_type"]
95
+ pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN]
74
96
  }
75
97
  };
76
98
  }
@@ -88,41 +110,44 @@ const transformAttributes = (contentType) => {
88
110
  }, {});
89
111
  };
90
112
  const hasComponentsOrDz = (contentType) => {
91
- return Object.values(contentType.attributes).some(
113
+ return Object.values(contentType.attributes || {}).some(
92
114
  ({ type }) => type === "dynamiczone" || type === "component"
93
115
  );
94
116
  };
95
117
  const createDocumentId = cuid2.createId;
96
118
  const createCompoLinkModel = (contentType) => {
97
- const name = `${contentType.collectionName}_components`;
119
+ const name = getComponentJoinTableName(contentType.collectionName);
120
+ const entityId = identifiers.getJoinColumnAttributeIdName(ENTITY);
121
+ const componentId = identifiers.getJoinColumnAttributeIdName(COMPONENT_INVERSE_COLUMN_NAME);
122
+ const fkIndex = identifiers.getFkIndexName([contentType.collectionName, ENTITY]);
98
123
  return {
99
124
  // TODO: make sure there can't be any conflicts with a prefix
100
125
  singularName: name,
101
126
  uid: name,
102
127
  tableName: name,
103
128
  attributes: {
104
- id: {
129
+ [id]: {
105
130
  type: "increments"
106
131
  },
107
- entity_id: {
132
+ [entityId]: {
108
133
  type: "integer",
109
134
  column: {
110
135
  unsigned: true
111
136
  }
112
137
  },
113
- component_id: {
138
+ [componentId]: {
114
139
  type: "integer",
115
140
  column: {
116
141
  unsigned: true
117
142
  }
118
143
  },
119
- component_type: {
144
+ [COMPONENT_TYPE_COLUMN]: {
120
145
  type: "string"
121
146
  },
122
- field: {
147
+ [field]: {
123
148
  type: "string"
124
149
  },
125
- order: {
150
+ [order]: {
126
151
  type: "float",
127
152
  column: {
128
153
  unsigned: true,
@@ -132,29 +157,30 @@ const createCompoLinkModel = (contentType) => {
132
157
  },
133
158
  indexes: [
134
159
  {
135
- name: `${contentType.collectionName}_field_index`,
136
- columns: ["field"]
160
+ name: identifiers.getIndexName([contentType.collectionName, field]),
161
+ columns: [field]
137
162
  },
138
163
  {
139
- name: `${contentType.collectionName}_component_type_index`,
140
- columns: ["component_type"]
164
+ name: identifiers.getIndexName([contentType.collectionName, COMPONENT_TYPE_COLUMN]),
165
+ columns: [COMPONENT_TYPE_COLUMN]
141
166
  },
142
167
  {
143
- name: `${contentType.collectionName}_entity_fk`,
144
- columns: ["entity_id"]
168
+ name: fkIndex,
169
+ columns: [entityId]
145
170
  },
146
171
  {
147
- name: `${contentType.collectionName}_unique`,
148
- columns: ["entity_id", "component_id", "field", "component_type"],
172
+ // NOTE: since we don't include attribute names, we need to be careful not to create another unique index
173
+ name: identifiers.getUniqueIndexName([contentType.collectionName]),
174
+ columns: [entityId, componentId, field, COMPONENT_TYPE_COLUMN],
149
175
  type: "unique"
150
176
  }
151
177
  ],
152
178
  foreignKeys: [
153
179
  {
154
- name: `${contentType.collectionName}_entity_fk`,
155
- columns: ["entity_id"],
156
- referencedColumns: ["id"],
157
- referencedTable: contentType.collectionName,
180
+ name: fkIndex,
181
+ columns: [entityId],
182
+ referencedColumns: [id],
183
+ referencedTable: identifiers.getTableName(contentType.collectionName),
158
184
  onDelete: "CASCADE"
159
185
  }
160
186
  ]
@@ -163,12 +189,16 @@ const createCompoLinkModel = (contentType) => {
163
189
  const transformContentTypesToModels = (contentTypes) => {
164
190
  const models = [];
165
191
  contentTypes.forEach((contentType) => {
192
+ assert__default.default(contentType.collectionName, 'Content type "collectionName" is required');
193
+ assert__default.default(contentType.modelName, 'Content type "modelName" is required');
194
+ assert__default.default(contentType.uid, 'Content type "uid" is required');
166
195
  const documentIdAttribute = contentType.modelType === "contentType" ? { documentId: { type: "string", default: createDocumentId } } : {};
167
- const reservedAttributeNames = ["documentId", "document_id", "id"];
168
- reservedAttributeNames.forEach((reservedAttributeName) => {
169
- if (reservedAttributeName in contentType.attributes) {
196
+ const reservedAttributeNames = ["document_id", id];
197
+ Object.keys(contentType.attributes || {}).forEach((attributeName) => {
198
+ const snakeCasedAttributeName = ___default.default.snakeCase(attributeName);
199
+ if (reservedAttributeNames.includes(snakeCasedAttributeName)) {
170
200
  throw new Error(
171
- `The attribute "${reservedAttributeName}" is reserved and cannot be used in a modelPlease rename "${contentType.modelName}" attribute "${reservedAttributeName}" to something else.`
201
+ `The attribute "${attributeName}" is reserved and cannot be used in a model. Please rename "${contentType.modelName}" attribute "${attributeName}" to something else.`
172
202
  );
173
203
  }
174
204
  });
@@ -176,13 +206,12 @@ const transformContentTypesToModels = (contentTypes) => {
176
206
  const compoLinkModel = createCompoLinkModel(contentType);
177
207
  models.push(compoLinkModel);
178
208
  }
179
- assert__default.default(contentType.collectionName, "Collection name is required");
180
209
  const model = {
181
210
  uid: contentType.uid,
182
211
  singularName: contentType.modelName,
183
- tableName: contentType.collectionName,
212
+ tableName: identifiers.getTableName(contentType.collectionName),
184
213
  attributes: {
185
- id: {
214
+ [id]: {
186
215
  type: "increments"
187
216
  },
188
217
  ...documentIdAttribute,
@@ -193,6 +222,16 @@ const transformContentTypesToModels = (contentTypes) => {
193
222
  });
194
223
  return models;
195
224
  };
225
+ exports.COMPONENT_INVERSE_COLUMN_NAME = COMPONENT_INVERSE_COLUMN_NAME;
226
+ exports.COMPONENT_JOIN_TABLE_SUFFIX = COMPONENT_JOIN_TABLE_SUFFIX;
227
+ exports.COMPONENT_TYPE_COLUMN = COMPONENT_TYPE_COLUMN;
228
+ exports.DZ_JOIN_TABLE_SUFFIX = DZ_JOIN_TABLE_SUFFIX;
229
+ exports.ENTITY = ENTITY;
196
230
  exports.createDocumentId = createDocumentId;
231
+ exports.getComponentJoinTableName = getComponentJoinTableName;
232
+ exports.getDzJoinTableName = getDzJoinTableName;
233
+ exports.hasComponentsOrDz = hasComponentsOrDz;
234
+ exports.transformAttribute = transformAttribute;
235
+ exports.transformAttributes = transformAttributes;
197
236
  exports.transformContentTypesToModels = transformContentTypesToModels;
198
237
  //# sourceMappingURL=transform-content-types-to-models.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transform-content-types-to-models.js","sources":["../../src/utils/transform-content-types-to-models.ts"],"sourcesContent":["import { Model } from '@strapi/database';\nimport { Schema, Attribute } from '@strapi/types';\nimport { createId } from '@paralleldrive/cuid2';\nimport assert from 'node:assert';\n\nconst transformAttribute = (\n name: string,\n attribute: Attribute.Any,\n contentType: Schema.ContentType\n) => {\n switch (attribute.type) {\n case 'media': {\n return {\n type: 'relation',\n relation: attribute.multiple === true ? 'morphMany' : 'morphOne',\n target: 'plugin::upload.file',\n morphBy: 'related',\n };\n }\n case 'component': {\n return {\n type: 'relation',\n relation: attribute.repeatable === true ? 'oneToMany' : 'oneToOne',\n target: attribute.component,\n\n // We need the join table name to be deterministic,\n // We need to allow passing the join table name as an option\n joinTable: {\n name: `${contentType.collectionName}_components`,\n joinColumn: {\n name: 'entity_id',\n referencedColumn: 'id',\n },\n inverseJoinColumn: {\n name: 'component_id',\n referencedColumn: 'id',\n },\n on: {\n field: name,\n },\n orderColumnName: 'order',\n orderBy: {\n order: 'asc',\n },\n pivotColumns: ['entity_id', 'component_id', 'field', 'component_type'],\n },\n };\n }\n case 'dynamiczone': {\n return {\n type: 'relation',\n relation: 'morphToMany',\n // TODO: handle restrictions at some point\n // target: attribute.components,\n joinTable: {\n name: `${contentType.collectionName}_components`,\n joinColumn: {\n name: 'entity_id',\n referencedColumn: 'id',\n },\n morphColumn: {\n idColumn: {\n name: 'component_id',\n referencedColumn: 'id',\n },\n typeColumn: {\n name: 'component_type',\n },\n typeField: '__component',\n },\n on: {\n field: name,\n },\n orderBy: {\n order: 'asc',\n },\n pivotColumns: ['entity_id', 'component_id', 'field', 'component_type'],\n },\n };\n }\n default: {\n return attribute;\n }\n }\n};\n\nconst transformAttributes = (contentType: Schema.ContentType) => {\n return Object.keys(contentType.attributes! || {}).reduce((attrs, attrName) => {\n return {\n ...attrs,\n [attrName]: transformAttribute(attrName, contentType.attributes[attrName]!, contentType),\n };\n }, {});\n};\n\nconst hasComponentsOrDz = (contentType: Schema.ContentType) => {\n return Object.values(contentType.attributes).some(\n ({ type }) => type === 'dynamiczone' || type === 'component'\n );\n};\n\nexport const createDocumentId = createId;\n\nconst createCompoLinkModel = (contentType: Schema.ContentType): Model => {\n const name = `${contentType.collectionName}_components`;\n\n return {\n // TODO: make sure there can't be any conflicts with a prefix\n singularName: name,\n uid: name,\n tableName: name,\n attributes: {\n id: {\n type: 'increments',\n },\n entity_id: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n component_id: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n component_type: {\n type: 'string',\n },\n field: {\n type: 'string',\n },\n order: {\n type: 'float',\n column: {\n unsigned: true,\n defaultTo: null,\n },\n },\n },\n indexes: [\n {\n name: `${contentType.collectionName}_field_index`,\n columns: ['field'],\n },\n {\n name: `${contentType.collectionName}_component_type_index`,\n columns: ['component_type'],\n },\n {\n name: `${contentType.collectionName}_entity_fk`,\n columns: ['entity_id'],\n },\n {\n name: `${contentType.collectionName}_unique`,\n columns: ['entity_id', 'component_id', 'field', 'component_type'],\n type: 'unique',\n },\n ],\n foreignKeys: [\n {\n name: `${contentType.collectionName}_entity_fk`,\n columns: ['entity_id'],\n referencedColumns: ['id'],\n referencedTable: contentType.collectionName!,\n onDelete: 'CASCADE',\n },\n ],\n };\n};\n\nexport const transformContentTypesToModels = (contentTypes: Schema.ContentType[]): Model[] => {\n const models: Model[] = [];\n\n contentTypes.forEach((contentType) => {\n // Add document id to content types\n // as it is not documented\n const documentIdAttribute: Record<string, Attribute.Any> =\n contentType.modelType === 'contentType'\n ? { documentId: { type: 'string', default: createDocumentId } }\n : {};\n\n // Prevent user from creating a documentId attribute\n const reservedAttributeNames = ['documentId', 'document_id', 'id'];\n reservedAttributeNames.forEach((reservedAttributeName) => {\n if (reservedAttributeName in contentType.attributes) {\n throw new Error(\n `The attribute \"${reservedAttributeName}\" is reserved and cannot be used in a model` +\n `Please rename \"${contentType.modelName}\" attribute \"${reservedAttributeName}\" to something else.`\n );\n }\n });\n\n if (hasComponentsOrDz(contentType)) {\n const compoLinkModel = createCompoLinkModel(contentType);\n models.push(compoLinkModel);\n }\n\n assert(contentType.collectionName, 'Collection name is required');\n\n const model: Model = {\n uid: contentType.uid,\n singularName: contentType.modelName,\n tableName: contentType.collectionName,\n attributes: {\n id: {\n type: 'increments',\n },\n ...documentIdAttribute,\n ...transformAttributes(contentType),\n },\n };\n\n models.push(model);\n });\n\n return models;\n};\n"],"names":["createId","assert"],"mappings":"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"}
1
+ {"version":3,"file":"transform-content-types-to-models.js","sources":["../../src/utils/transform-content-types-to-models.ts"],"sourcesContent":["import { type Model, utils } from '@strapi/database';\nimport { Schema, Attribute } from '@strapi/types';\nimport { createId } from '@paralleldrive/cuid2';\nimport assert from 'node:assert';\nimport _ from 'lodash/fp';\n\nconst { identifiers } = utils;\n\n/**\n * Because strapi/database models don't know about things like components or dynamic zones, we use this file to convert them\n * to a relations format that it recognizes\n *\n * Therefore we have to keep an additional set of helpers/extensions to the database naming methods\n */\n\nexport const COMPONENT_JOIN_TABLE_SUFFIX = 'components';\nexport const DZ_JOIN_TABLE_SUFFIX = 'components';\nexport const COMPONENT_INVERSE_COLUMN_NAME = 'component';\nexport const COMPONENT_TYPE_COLUMN = 'component_type';\nexport const ENTITY = 'entity';\n\nexport const getComponentJoinTableName = (collectionName: string) =>\n identifiers.getTableName(collectionName, { suffix: COMPONENT_JOIN_TABLE_SUFFIX });\n\nexport const getDzJoinTableName = (collectionName: string) =>\n identifiers.getTableName(collectionName, { suffix: DZ_JOIN_TABLE_SUFFIX });\n\nconst { ID_COLUMN: id, FIELD_COLUMN: field, ORDER_COLUMN: order } = identifiers;\n\nexport type LoadedContentTypeModel = Schema.ContentType &\n Required<Pick<Schema.ContentType, 'collectionName' | 'uid' | 'modelName'>>;\n\n// Transforms an attribute (particularly for relation types) into the format that strapi/database accepts\nexport const transformAttribute = (\n name: string,\n attribute: Attribute.Any,\n contentType: LoadedContentTypeModel\n) => {\n switch (attribute.type) {\n case 'media': {\n return {\n type: 'relation',\n relation: attribute.multiple === true ? 'morphMany' : 'morphOne',\n target: 'plugin::upload.file',\n morphBy: 'related',\n };\n }\n case 'component': {\n const joinTableName = getComponentJoinTableName(contentType.collectionName);\n const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);\n const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(\n COMPONENT_INVERSE_COLUMN_NAME\n );\n\n return {\n type: 'relation',\n relation: attribute.repeatable === true ? 'oneToMany' : 'oneToOne',\n target: attribute.component,\n\n // We need the join table name to be deterministic,\n // We need to allow passing the join table name as an option\n joinTable: {\n name: joinTableName,\n joinColumn: {\n name: joinColumnEntityName,\n referencedColumn: id,\n },\n inverseJoinColumn: {\n name: joinColumnInverseName,\n referencedColumn: id,\n },\n on: {\n field: name,\n },\n orderColumnName: order,\n orderBy: {\n order: 'asc',\n },\n pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN],\n },\n };\n }\n case 'dynamiczone': {\n const joinTableName = getDzJoinTableName(contentType.collectionName);\n const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);\n const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(\n COMPONENT_INVERSE_COLUMN_NAME\n );\n\n return {\n type: 'relation',\n relation: 'morphToMany',\n // TODO: handle restrictions at some point\n // target: attribute.components,\n joinTable: {\n name: joinTableName,\n joinColumn: {\n name: joinColumnEntityName,\n referencedColumn: id,\n },\n morphColumn: {\n idColumn: {\n name: joinColumnInverseName,\n referencedColumn: id,\n },\n typeColumn: {\n name: COMPONENT_TYPE_COLUMN,\n },\n typeField: '__component',\n },\n on: {\n field: name,\n },\n orderBy: {\n order: 'asc',\n },\n pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN],\n },\n };\n }\n default: {\n return attribute;\n }\n }\n};\n\nexport const transformAttributes = (contentType: LoadedContentTypeModel) => {\n return Object.keys(contentType.attributes! || {}).reduce((attrs, attrName) => {\n return {\n ...attrs,\n [attrName]: transformAttribute(attrName, contentType.attributes[attrName]!, contentType),\n };\n }, {});\n};\n\nexport const hasComponentsOrDz = (\n contentType: LoadedContentTypeModel\n): contentType is LoadedContentTypeModel & { type: 'dynamiczone' | 'component' } => {\n return Object.values(contentType.attributes || {}).some(\n ({ type }) => type === 'dynamiczone' || type === 'component'\n );\n};\n\nexport const createDocumentId = createId;\n\n// Creates the\nconst createCompoLinkModel = (contentType: LoadedContentTypeModel): Model => {\n const name = getComponentJoinTableName(contentType.collectionName);\n\n const entityId = identifiers.getJoinColumnAttributeIdName(ENTITY);\n const componentId = identifiers.getJoinColumnAttributeIdName(COMPONENT_INVERSE_COLUMN_NAME);\n const fkIndex = identifiers.getFkIndexName([contentType.collectionName, ENTITY]);\n\n return {\n // TODO: make sure there can't be any conflicts with a prefix\n singularName: name,\n uid: name,\n tableName: name,\n attributes: {\n [id]: {\n type: 'increments',\n },\n [entityId]: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n [componentId]: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n [COMPONENT_TYPE_COLUMN]: {\n type: 'string',\n },\n [field]: {\n type: 'string',\n },\n [order]: {\n type: 'float',\n column: {\n unsigned: true,\n defaultTo: null,\n },\n },\n },\n indexes: [\n {\n name: identifiers.getIndexName([contentType.collectionName, field]),\n columns: [field],\n },\n {\n name: identifiers.getIndexName([contentType.collectionName, COMPONENT_TYPE_COLUMN]),\n columns: [COMPONENT_TYPE_COLUMN],\n },\n {\n name: fkIndex,\n columns: [entityId],\n },\n {\n // NOTE: since we don't include attribute names, we need to be careful not to create another unique index\n name: identifiers.getUniqueIndexName([contentType.collectionName]),\n columns: [entityId, componentId, field, COMPONENT_TYPE_COLUMN],\n type: 'unique',\n },\n ],\n foreignKeys: [\n {\n name: fkIndex,\n columns: [entityId],\n referencedColumns: [id],\n referencedTable: identifiers.getTableName(contentType.collectionName),\n onDelete: 'CASCADE',\n },\n ],\n };\n};\n\nexport const transformContentTypesToModels = (contentTypes: LoadedContentTypeModel[]): Model[] => {\n const models: Model[] = [];\n\n contentTypes.forEach((contentType) => {\n assert(contentType.collectionName, 'Content type \"collectionName\" is required');\n assert(contentType.modelName, 'Content type \"modelName\" is required');\n assert(contentType.uid, 'Content type \"uid\" is required');\n\n // Add document id to content types\n // as it is not documented\n const documentIdAttribute: Record<string, Attribute.Any> =\n contentType.modelType === 'contentType'\n ? { documentId: { type: 'string', default: createDocumentId } }\n : {};\n\n // TODO: this needs to be combined with getReservedNames, we should not be maintaining two lists\n // Prevent user from creating a documentId attribute\n const reservedAttributeNames = ['document_id', id];\n Object.keys(contentType.attributes || {}).forEach((attributeName) => {\n const snakeCasedAttributeName = _.snakeCase(attributeName);\n if (reservedAttributeNames.includes(snakeCasedAttributeName)) {\n throw new Error(\n `The attribute \"${attributeName}\" is reserved and cannot be used in a model. Please rename \"${contentType.modelName}\" attribute \"${attributeName}\" to something else.`\n );\n }\n });\n\n if (hasComponentsOrDz(contentType)) {\n const compoLinkModel = createCompoLinkModel(contentType);\n models.push(compoLinkModel);\n }\n\n const model: Model = {\n uid: contentType.uid,\n singularName: contentType.modelName,\n tableName: identifiers.getTableName(contentType.collectionName),\n attributes: {\n [id]: {\n type: 'increments',\n },\n ...documentIdAttribute,\n ...transformAttributes(contentType),\n },\n };\n\n models.push(model);\n });\n\n return models;\n};\n"],"names":["utils","createId","assert","_"],"mappings":";;;;;;;;;AAMA,MAAM,EAAE,YAAgB,IAAAA;AASjB,MAAM,8BAA8B;AACpC,MAAM,uBAAuB;AAC7B,MAAM,gCAAgC;AACtC,MAAM,wBAAwB;AAC9B,MAAM,SAAS;AAET,MAAA,4BAA4B,CAAC,mBACxC,YAAY,aAAa,gBAAgB,EAAE,QAAQ,6BAA6B;AAErE,MAAA,qBAAqB,CAAC,mBACjC,YAAY,aAAa,gBAAgB,EAAE,QAAQ,sBAAsB;AAE3E,MAAM,EAAE,WAAW,IAAI,cAAc,OAAO,cAAc,MAAU,IAAA;AAM7D,MAAM,qBAAqB,CAChC,MACA,WACA,gBACG;AACH,UAAQ,UAAU,MAAM;AAAA,IACtB,KAAK,SAAS;AACL,aAAA;AAAA,QACL,MAAM;AAAA,QACN,UAAU,UAAU,aAAa,OAAO,cAAc;AAAA,QACtD,QAAQ;AAAA,QACR,SAAS;AAAA,MAAA;AAAA,IAEb;AAAA,IACA,KAAK,aAAa;AACV,YAAA,gBAAgB,0BAA0B,YAAY,cAAc;AACpE,YAAA,uBAAuB,YAAY,6BAA6B,MAAM;AAC5E,YAAM,wBAAwB,YAAY;AAAA,QACxC;AAAA,MAAA;AAGK,aAAA;AAAA,QACL,MAAM;AAAA,QACN,UAAU,UAAU,eAAe,OAAO,cAAc;AAAA,QACxD,QAAQ,UAAU;AAAA;AAAA;AAAA,QAIlB,WAAW;AAAA,UACT,MAAM;AAAA,UACN,YAAY;AAAA,YACV,MAAM;AAAA,YACN,kBAAkB;AAAA,UACpB;AAAA,UACA,mBAAmB;AAAA,YACjB,MAAM;AAAA,YACN,kBAAkB;AAAA,UACpB;AAAA,UACA,IAAI;AAAA,YACF,OAAO;AAAA,UACT;AAAA,UACA,iBAAiB;AAAA,UACjB,SAAS;AAAA,YACP,OAAO;AAAA,UACT;AAAA,UACA,cAAc,CAAC,sBAAsB,uBAAuB,OAAO,qBAAqB;AAAA,QAC1F;AAAA,MAAA;AAAA,IAEJ;AAAA,IACA,KAAK,eAAe;AACZ,YAAA,gBAAgB,mBAAmB,YAAY,cAAc;AAC7D,YAAA,uBAAuB,YAAY,6BAA6B,MAAM;AAC5E,YAAM,wBAAwB,YAAY;AAAA,QACxC;AAAA,MAAA;AAGK,aAAA;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA;AAAA;AAAA,QAGV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,YAAY;AAAA,YACV,MAAM;AAAA,YACN,kBAAkB;AAAA,UACpB;AAAA,UACA,aAAa;AAAA,YACX,UAAU;AAAA,cACR,MAAM;AAAA,cACN,kBAAkB;AAAA,YACpB;AAAA,YACA,YAAY;AAAA,cACV,MAAM;AAAA,YACR;AAAA,YACA,WAAW;AAAA,UACb;AAAA,UACA,IAAI;AAAA,YACF,OAAO;AAAA,UACT;AAAA,UACA,SAAS;AAAA,YACP,OAAO;AAAA,UACT;AAAA,UACA,cAAc,CAAC,sBAAsB,uBAAuB,OAAO,qBAAqB;AAAA,QAC1F;AAAA,MAAA;AAAA,IAEJ;AAAA,IACA,SAAS;AACA,aAAA;AAAA,IACT;AAAA,EACF;AACF;AAEa,MAAA,sBAAsB,CAAC,gBAAwC;AACnE,SAAA,OAAO,KAAK,YAAY,cAAe,CAAE,CAAA,EAAE,OAAO,CAAC,OAAO,aAAa;AACrE,WAAA;AAAA,MACL,GAAG;AAAA,MACH,CAAC,QAAQ,GAAG,mBAAmB,UAAU,YAAY,WAAW,QAAQ,GAAI,WAAW;AAAA,IAAA;AAAA,EAE3F,GAAG,CAAE,CAAA;AACP;AAEa,MAAA,oBAAoB,CAC/B,gBACkF;AAClF,SAAO,OAAO,OAAO,YAAY,cAAc,CAAA,CAAE,EAAE;AAAA,IACjD,CAAC,EAAE,KAAW,MAAA,SAAS,iBAAiB,SAAS;AAAA,EAAA;AAErD;AAEO,MAAM,mBAAmBC,MAAA;AAGhC,MAAM,uBAAuB,CAAC,gBAA+C;AACrE,QAAA,OAAO,0BAA0B,YAAY,cAAc;AAE3D,QAAA,WAAW,YAAY,6BAA6B,MAAM;AAC1D,QAAA,cAAc,YAAY,6BAA6B,6BAA6B;AAC1F,QAAM,UAAU,YAAY,eAAe,CAAC,YAAY,gBAAgB,MAAM,CAAC;AAExE,SAAA;AAAA;AAAA,IAEL,cAAc;AAAA,IACd,KAAK;AAAA,IACL,WAAW;AAAA,IACX,YAAY;AAAA,MACV,CAAC,EAAE,GAAG;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,MACA,CAAC,QAAQ,GAAG;AAAA,QACV,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,MACA,CAAC,WAAW,GAAG;AAAA,QACb,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,MACA,CAAC,qBAAqB,GAAG;AAAA,QACvB,MAAM;AAAA,MACR;AAAA,MACA,CAAC,KAAK,GAAG;AAAA,QACP,MAAM;AAAA,MACR;AAAA,MACA,CAAC,KAAK,GAAG;AAAA,QACP,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,UAAU;AAAA,UACV,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,MAAM,YAAY,aAAa,CAAC,YAAY,gBAAgB,KAAK,CAAC;AAAA,QAClE,SAAS,CAAC,KAAK;AAAA,MACjB;AAAA,MACA;AAAA,QACE,MAAM,YAAY,aAAa,CAAC,YAAY,gBAAgB,qBAAqB,CAAC;AAAA,QAClF,SAAS,CAAC,qBAAqB;AAAA,MACjC;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS,CAAC,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA;AAAA,QAEE,MAAM,YAAY,mBAAmB,CAAC,YAAY,cAAc,CAAC;AAAA,QACjE,SAAS,CAAC,UAAU,aAAa,OAAO,qBAAqB;AAAA,QAC7D,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,aAAa;AAAA,MACX;AAAA,QACE,MAAM;AAAA,QACN,SAAS,CAAC,QAAQ;AAAA,QAClB,mBAAmB,CAAC,EAAE;AAAA,QACtB,iBAAiB,YAAY,aAAa,YAAY,cAAc;AAAA,QACpE,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EAAA;AAEJ;AAEa,MAAA,gCAAgC,CAAC,iBAAoD;AAChG,QAAM,SAAkB,CAAA;AAEX,eAAA,QAAQ,CAAC,gBAAgB;AAC7BC,oBAAAA,QAAA,YAAY,gBAAgB,2CAA2C;AACvEA,oBAAAA,QAAA,YAAY,WAAW,sCAAsC;AAC7DA,oBAAAA,QAAA,YAAY,KAAK,gCAAgC;AAIxD,UAAM,sBACJ,YAAY,cAAc,gBACtB,EAAE,YAAY,EAAE,MAAM,UAAU,SAAS,iBAAiB,EAAA,IAC1D,CAAA;AAIA,UAAA,yBAAyB,CAAC,eAAe,EAAE;AAC1C,WAAA,KAAK,YAAY,cAAc,CAAA,CAAE,EAAE,QAAQ,CAAC,kBAAkB;AAC7D,YAAA,0BAA0BC,WAAAA,QAAE,UAAU,aAAa;AACrD,UAAA,uBAAuB,SAAS,uBAAuB,GAAG;AAC5D,cAAM,IAAI;AAAA,UACR,kBAAkB,aAAa,+DAA+D,YAAY,SAAS,gBAAgB,aAAa;AAAA,QAAA;AAAA,MAEpJ;AAAA,IAAA,CACD;AAEG,QAAA,kBAAkB,WAAW,GAAG;AAC5B,YAAA,iBAAiB,qBAAqB,WAAW;AACvD,aAAO,KAAK,cAAc;AAAA,IAC5B;AAEA,UAAM,QAAe;AAAA,MACnB,KAAK,YAAY;AAAA,MACjB,cAAc,YAAY;AAAA,MAC1B,WAAW,YAAY,aAAa,YAAY,cAAc;AAAA,MAC9D,YAAY;AAAA,QACV,CAAC,EAAE,GAAG;AAAA,UACJ,MAAM;AAAA,QACR;AAAA,QACA,GAAG;AAAA,QACH,GAAG,oBAAoB,WAAW;AAAA,MACpC;AAAA,IAAA;AAGF,WAAO,KAAK,KAAK;AAAA,EAAA,CAClB;AAEM,SAAA;AACT;;;;;;;;;;;;;"}
@@ -1,5 +1,16 @@
1
+ import { utils } from "@strapi/database";
1
2
  import { createId } from "@paralleldrive/cuid2";
2
3
  import assert from "node:assert";
4
+ import _ from "lodash/fp";
5
+ const { identifiers } = utils;
6
+ const COMPONENT_JOIN_TABLE_SUFFIX = "components";
7
+ const DZ_JOIN_TABLE_SUFFIX = "components";
8
+ const COMPONENT_INVERSE_COLUMN_NAME = "component";
9
+ const COMPONENT_TYPE_COLUMN = "component_type";
10
+ const ENTITY = "entity";
11
+ const getComponentJoinTableName = (collectionName) => identifiers.getTableName(collectionName, { suffix: COMPONENT_JOIN_TABLE_SUFFIX });
12
+ const getDzJoinTableName = (collectionName) => identifiers.getTableName(collectionName, { suffix: DZ_JOIN_TABLE_SUFFIX });
13
+ const { ID_COLUMN: id, FIELD_COLUMN: field, ORDER_COLUMN: order } = identifiers;
3
14
  const transformAttribute = (name, attribute, contentType) => {
4
15
  switch (attribute.type) {
5
16
  case "media": {
@@ -11,6 +22,11 @@ const transformAttribute = (name, attribute, contentType) => {
11
22
  };
12
23
  }
13
24
  case "component": {
25
+ const joinTableName = getComponentJoinTableName(contentType.collectionName);
26
+ const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);
27
+ const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(
28
+ COMPONENT_INVERSE_COLUMN_NAME
29
+ );
14
30
  return {
15
31
  type: "relation",
16
32
  relation: attribute.repeatable === true ? "oneToMany" : "oneToOne",
@@ -18,45 +34,50 @@ const transformAttribute = (name, attribute, contentType) => {
18
34
  // We need the join table name to be deterministic,
19
35
  // We need to allow passing the join table name as an option
20
36
  joinTable: {
21
- name: `${contentType.collectionName}_components`,
37
+ name: joinTableName,
22
38
  joinColumn: {
23
- name: "entity_id",
24
- referencedColumn: "id"
39
+ name: joinColumnEntityName,
40
+ referencedColumn: id
25
41
  },
26
42
  inverseJoinColumn: {
27
- name: "component_id",
28
- referencedColumn: "id"
43
+ name: joinColumnInverseName,
44
+ referencedColumn: id
29
45
  },
30
46
  on: {
31
47
  field: name
32
48
  },
33
- orderColumnName: "order",
49
+ orderColumnName: order,
34
50
  orderBy: {
35
51
  order: "asc"
36
52
  },
37
- pivotColumns: ["entity_id", "component_id", "field", "component_type"]
53
+ pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN]
38
54
  }
39
55
  };
40
56
  }
41
57
  case "dynamiczone": {
58
+ const joinTableName = getDzJoinTableName(contentType.collectionName);
59
+ const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);
60
+ const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(
61
+ COMPONENT_INVERSE_COLUMN_NAME
62
+ );
42
63
  return {
43
64
  type: "relation",
44
65
  relation: "morphToMany",
45
66
  // TODO: handle restrictions at some point
46
67
  // target: attribute.components,
47
68
  joinTable: {
48
- name: `${contentType.collectionName}_components`,
69
+ name: joinTableName,
49
70
  joinColumn: {
50
- name: "entity_id",
51
- referencedColumn: "id"
71
+ name: joinColumnEntityName,
72
+ referencedColumn: id
52
73
  },
53
74
  morphColumn: {
54
75
  idColumn: {
55
- name: "component_id",
56
- referencedColumn: "id"
76
+ name: joinColumnInverseName,
77
+ referencedColumn: id
57
78
  },
58
79
  typeColumn: {
59
- name: "component_type"
80
+ name: COMPONENT_TYPE_COLUMN
60
81
  },
61
82
  typeField: "__component"
62
83
  },
@@ -66,7 +87,7 @@ const transformAttribute = (name, attribute, contentType) => {
66
87
  orderBy: {
67
88
  order: "asc"
68
89
  },
69
- pivotColumns: ["entity_id", "component_id", "field", "component_type"]
90
+ pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN]
70
91
  }
71
92
  };
72
93
  }
@@ -84,41 +105,44 @@ const transformAttributes = (contentType) => {
84
105
  }, {});
85
106
  };
86
107
  const hasComponentsOrDz = (contentType) => {
87
- return Object.values(contentType.attributes).some(
108
+ return Object.values(contentType.attributes || {}).some(
88
109
  ({ type }) => type === "dynamiczone" || type === "component"
89
110
  );
90
111
  };
91
112
  const createDocumentId = createId;
92
113
  const createCompoLinkModel = (contentType) => {
93
- const name = `${contentType.collectionName}_components`;
114
+ const name = getComponentJoinTableName(contentType.collectionName);
115
+ const entityId = identifiers.getJoinColumnAttributeIdName(ENTITY);
116
+ const componentId = identifiers.getJoinColumnAttributeIdName(COMPONENT_INVERSE_COLUMN_NAME);
117
+ const fkIndex = identifiers.getFkIndexName([contentType.collectionName, ENTITY]);
94
118
  return {
95
119
  // TODO: make sure there can't be any conflicts with a prefix
96
120
  singularName: name,
97
121
  uid: name,
98
122
  tableName: name,
99
123
  attributes: {
100
- id: {
124
+ [id]: {
101
125
  type: "increments"
102
126
  },
103
- entity_id: {
127
+ [entityId]: {
104
128
  type: "integer",
105
129
  column: {
106
130
  unsigned: true
107
131
  }
108
132
  },
109
- component_id: {
133
+ [componentId]: {
110
134
  type: "integer",
111
135
  column: {
112
136
  unsigned: true
113
137
  }
114
138
  },
115
- component_type: {
139
+ [COMPONENT_TYPE_COLUMN]: {
116
140
  type: "string"
117
141
  },
118
- field: {
142
+ [field]: {
119
143
  type: "string"
120
144
  },
121
- order: {
145
+ [order]: {
122
146
  type: "float",
123
147
  column: {
124
148
  unsigned: true,
@@ -128,29 +152,30 @@ const createCompoLinkModel = (contentType) => {
128
152
  },
129
153
  indexes: [
130
154
  {
131
- name: `${contentType.collectionName}_field_index`,
132
- columns: ["field"]
155
+ name: identifiers.getIndexName([contentType.collectionName, field]),
156
+ columns: [field]
133
157
  },
134
158
  {
135
- name: `${contentType.collectionName}_component_type_index`,
136
- columns: ["component_type"]
159
+ name: identifiers.getIndexName([contentType.collectionName, COMPONENT_TYPE_COLUMN]),
160
+ columns: [COMPONENT_TYPE_COLUMN]
137
161
  },
138
162
  {
139
- name: `${contentType.collectionName}_entity_fk`,
140
- columns: ["entity_id"]
163
+ name: fkIndex,
164
+ columns: [entityId]
141
165
  },
142
166
  {
143
- name: `${contentType.collectionName}_unique`,
144
- columns: ["entity_id", "component_id", "field", "component_type"],
167
+ // NOTE: since we don't include attribute names, we need to be careful not to create another unique index
168
+ name: identifiers.getUniqueIndexName([contentType.collectionName]),
169
+ columns: [entityId, componentId, field, COMPONENT_TYPE_COLUMN],
145
170
  type: "unique"
146
171
  }
147
172
  ],
148
173
  foreignKeys: [
149
174
  {
150
- name: `${contentType.collectionName}_entity_fk`,
151
- columns: ["entity_id"],
152
- referencedColumns: ["id"],
153
- referencedTable: contentType.collectionName,
175
+ name: fkIndex,
176
+ columns: [entityId],
177
+ referencedColumns: [id],
178
+ referencedTable: identifiers.getTableName(contentType.collectionName),
154
179
  onDelete: "CASCADE"
155
180
  }
156
181
  ]
@@ -159,12 +184,16 @@ const createCompoLinkModel = (contentType) => {
159
184
  const transformContentTypesToModels = (contentTypes) => {
160
185
  const models = [];
161
186
  contentTypes.forEach((contentType) => {
187
+ assert(contentType.collectionName, 'Content type "collectionName" is required');
188
+ assert(contentType.modelName, 'Content type "modelName" is required');
189
+ assert(contentType.uid, 'Content type "uid" is required');
162
190
  const documentIdAttribute = contentType.modelType === "contentType" ? { documentId: { type: "string", default: createDocumentId } } : {};
163
- const reservedAttributeNames = ["documentId", "document_id", "id"];
164
- reservedAttributeNames.forEach((reservedAttributeName) => {
165
- if (reservedAttributeName in contentType.attributes) {
191
+ const reservedAttributeNames = ["document_id", id];
192
+ Object.keys(contentType.attributes || {}).forEach((attributeName) => {
193
+ const snakeCasedAttributeName = _.snakeCase(attributeName);
194
+ if (reservedAttributeNames.includes(snakeCasedAttributeName)) {
166
195
  throw new Error(
167
- `The attribute "${reservedAttributeName}" is reserved and cannot be used in a modelPlease rename "${contentType.modelName}" attribute "${reservedAttributeName}" to something else.`
196
+ `The attribute "${attributeName}" is reserved and cannot be used in a model. Please rename "${contentType.modelName}" attribute "${attributeName}" to something else.`
168
197
  );
169
198
  }
170
199
  });
@@ -172,13 +201,12 @@ const transformContentTypesToModels = (contentTypes) => {
172
201
  const compoLinkModel = createCompoLinkModel(contentType);
173
202
  models.push(compoLinkModel);
174
203
  }
175
- assert(contentType.collectionName, "Collection name is required");
176
204
  const model = {
177
205
  uid: contentType.uid,
178
206
  singularName: contentType.modelName,
179
- tableName: contentType.collectionName,
207
+ tableName: identifiers.getTableName(contentType.collectionName),
180
208
  attributes: {
181
- id: {
209
+ [id]: {
182
210
  type: "increments"
183
211
  },
184
212
  ...documentIdAttribute,
@@ -190,7 +218,17 @@ const transformContentTypesToModels = (contentTypes) => {
190
218
  return models;
191
219
  };
192
220
  export {
221
+ COMPONENT_INVERSE_COLUMN_NAME,
222
+ COMPONENT_JOIN_TABLE_SUFFIX,
223
+ COMPONENT_TYPE_COLUMN,
224
+ DZ_JOIN_TABLE_SUFFIX,
225
+ ENTITY,
193
226
  createDocumentId,
227
+ getComponentJoinTableName,
228
+ getDzJoinTableName,
229
+ hasComponentsOrDz,
230
+ transformAttribute,
231
+ transformAttributes,
194
232
  transformContentTypesToModels
195
233
  };
196
234
  //# sourceMappingURL=transform-content-types-to-models.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"transform-content-types-to-models.mjs","sources":["../../src/utils/transform-content-types-to-models.ts"],"sourcesContent":["import { Model } from '@strapi/database';\nimport { Schema, Attribute } from '@strapi/types';\nimport { createId } from '@paralleldrive/cuid2';\nimport assert from 'node:assert';\n\nconst transformAttribute = (\n name: string,\n attribute: Attribute.Any,\n contentType: Schema.ContentType\n) => {\n switch (attribute.type) {\n case 'media': {\n return {\n type: 'relation',\n relation: attribute.multiple === true ? 'morphMany' : 'morphOne',\n target: 'plugin::upload.file',\n morphBy: 'related',\n };\n }\n case 'component': {\n return {\n type: 'relation',\n relation: attribute.repeatable === true ? 'oneToMany' : 'oneToOne',\n target: attribute.component,\n\n // We need the join table name to be deterministic,\n // We need to allow passing the join table name as an option\n joinTable: {\n name: `${contentType.collectionName}_components`,\n joinColumn: {\n name: 'entity_id',\n referencedColumn: 'id',\n },\n inverseJoinColumn: {\n name: 'component_id',\n referencedColumn: 'id',\n },\n on: {\n field: name,\n },\n orderColumnName: 'order',\n orderBy: {\n order: 'asc',\n },\n pivotColumns: ['entity_id', 'component_id', 'field', 'component_type'],\n },\n };\n }\n case 'dynamiczone': {\n return {\n type: 'relation',\n relation: 'morphToMany',\n // TODO: handle restrictions at some point\n // target: attribute.components,\n joinTable: {\n name: `${contentType.collectionName}_components`,\n joinColumn: {\n name: 'entity_id',\n referencedColumn: 'id',\n },\n morphColumn: {\n idColumn: {\n name: 'component_id',\n referencedColumn: 'id',\n },\n typeColumn: {\n name: 'component_type',\n },\n typeField: '__component',\n },\n on: {\n field: name,\n },\n orderBy: {\n order: 'asc',\n },\n pivotColumns: ['entity_id', 'component_id', 'field', 'component_type'],\n },\n };\n }\n default: {\n return attribute;\n }\n }\n};\n\nconst transformAttributes = (contentType: Schema.ContentType) => {\n return Object.keys(contentType.attributes! || {}).reduce((attrs, attrName) => {\n return {\n ...attrs,\n [attrName]: transformAttribute(attrName, contentType.attributes[attrName]!, contentType),\n };\n }, {});\n};\n\nconst hasComponentsOrDz = (contentType: Schema.ContentType) => {\n return Object.values(contentType.attributes).some(\n ({ type }) => type === 'dynamiczone' || type === 'component'\n );\n};\n\nexport const createDocumentId = createId;\n\nconst createCompoLinkModel = (contentType: Schema.ContentType): Model => {\n const name = `${contentType.collectionName}_components`;\n\n return {\n // TODO: make sure there can't be any conflicts with a prefix\n singularName: name,\n uid: name,\n tableName: name,\n attributes: {\n id: {\n type: 'increments',\n },\n entity_id: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n component_id: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n component_type: {\n type: 'string',\n },\n field: {\n type: 'string',\n },\n order: {\n type: 'float',\n column: {\n unsigned: true,\n defaultTo: null,\n },\n },\n },\n indexes: [\n {\n name: `${contentType.collectionName}_field_index`,\n columns: ['field'],\n },\n {\n name: `${contentType.collectionName}_component_type_index`,\n columns: ['component_type'],\n },\n {\n name: `${contentType.collectionName}_entity_fk`,\n columns: ['entity_id'],\n },\n {\n name: `${contentType.collectionName}_unique`,\n columns: ['entity_id', 'component_id', 'field', 'component_type'],\n type: 'unique',\n },\n ],\n foreignKeys: [\n {\n name: `${contentType.collectionName}_entity_fk`,\n columns: ['entity_id'],\n referencedColumns: ['id'],\n referencedTable: contentType.collectionName!,\n onDelete: 'CASCADE',\n },\n ],\n };\n};\n\nexport const transformContentTypesToModels = (contentTypes: Schema.ContentType[]): Model[] => {\n const models: Model[] = [];\n\n contentTypes.forEach((contentType) => {\n // Add document id to content types\n // as it is not documented\n const documentIdAttribute: Record<string, Attribute.Any> =\n contentType.modelType === 'contentType'\n ? { documentId: { type: 'string', default: createDocumentId } }\n : {};\n\n // Prevent user from creating a documentId attribute\n const reservedAttributeNames = ['documentId', 'document_id', 'id'];\n reservedAttributeNames.forEach((reservedAttributeName) => {\n if (reservedAttributeName in contentType.attributes) {\n throw new Error(\n `The attribute \"${reservedAttributeName}\" is reserved and cannot be used in a model` +\n `Please rename \"${contentType.modelName}\" attribute \"${reservedAttributeName}\" to something else.`\n );\n }\n });\n\n if (hasComponentsOrDz(contentType)) {\n const compoLinkModel = createCompoLinkModel(contentType);\n models.push(compoLinkModel);\n }\n\n assert(contentType.collectionName, 'Collection name is required');\n\n const model: Model = {\n uid: contentType.uid,\n singularName: contentType.modelName,\n tableName: contentType.collectionName,\n attributes: {\n id: {\n type: 'increments',\n },\n ...documentIdAttribute,\n ...transformAttributes(contentType),\n },\n };\n\n models.push(model);\n });\n\n return models;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transform-content-types-to-models.mjs","sources":["../../src/utils/transform-content-types-to-models.ts"],"sourcesContent":["import { type Model, utils } from '@strapi/database';\nimport { Schema, Attribute } from '@strapi/types';\nimport { createId } from '@paralleldrive/cuid2';\nimport assert from 'node:assert';\nimport _ from 'lodash/fp';\n\nconst { identifiers } = utils;\n\n/**\n * Because strapi/database models don't know about things like components or dynamic zones, we use this file to convert them\n * to a relations format that it recognizes\n *\n * Therefore we have to keep an additional set of helpers/extensions to the database naming methods\n */\n\nexport const COMPONENT_JOIN_TABLE_SUFFIX = 'components';\nexport const DZ_JOIN_TABLE_SUFFIX = 'components';\nexport const COMPONENT_INVERSE_COLUMN_NAME = 'component';\nexport const COMPONENT_TYPE_COLUMN = 'component_type';\nexport const ENTITY = 'entity';\n\nexport const getComponentJoinTableName = (collectionName: string) =>\n identifiers.getTableName(collectionName, { suffix: COMPONENT_JOIN_TABLE_SUFFIX });\n\nexport const getDzJoinTableName = (collectionName: string) =>\n identifiers.getTableName(collectionName, { suffix: DZ_JOIN_TABLE_SUFFIX });\n\nconst { ID_COLUMN: id, FIELD_COLUMN: field, ORDER_COLUMN: order } = identifiers;\n\nexport type LoadedContentTypeModel = Schema.ContentType &\n Required<Pick<Schema.ContentType, 'collectionName' | 'uid' | 'modelName'>>;\n\n// Transforms an attribute (particularly for relation types) into the format that strapi/database accepts\nexport const transformAttribute = (\n name: string,\n attribute: Attribute.Any,\n contentType: LoadedContentTypeModel\n) => {\n switch (attribute.type) {\n case 'media': {\n return {\n type: 'relation',\n relation: attribute.multiple === true ? 'morphMany' : 'morphOne',\n target: 'plugin::upload.file',\n morphBy: 'related',\n };\n }\n case 'component': {\n const joinTableName = getComponentJoinTableName(contentType.collectionName);\n const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);\n const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(\n COMPONENT_INVERSE_COLUMN_NAME\n );\n\n return {\n type: 'relation',\n relation: attribute.repeatable === true ? 'oneToMany' : 'oneToOne',\n target: attribute.component,\n\n // We need the join table name to be deterministic,\n // We need to allow passing the join table name as an option\n joinTable: {\n name: joinTableName,\n joinColumn: {\n name: joinColumnEntityName,\n referencedColumn: id,\n },\n inverseJoinColumn: {\n name: joinColumnInverseName,\n referencedColumn: id,\n },\n on: {\n field: name,\n },\n orderColumnName: order,\n orderBy: {\n order: 'asc',\n },\n pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN],\n },\n };\n }\n case 'dynamiczone': {\n const joinTableName = getDzJoinTableName(contentType.collectionName);\n const joinColumnEntityName = identifiers.getJoinColumnAttributeIdName(ENTITY);\n const joinColumnInverseName = identifiers.getJoinColumnAttributeIdName(\n COMPONENT_INVERSE_COLUMN_NAME\n );\n\n return {\n type: 'relation',\n relation: 'morphToMany',\n // TODO: handle restrictions at some point\n // target: attribute.components,\n joinTable: {\n name: joinTableName,\n joinColumn: {\n name: joinColumnEntityName,\n referencedColumn: id,\n },\n morphColumn: {\n idColumn: {\n name: joinColumnInverseName,\n referencedColumn: id,\n },\n typeColumn: {\n name: COMPONENT_TYPE_COLUMN,\n },\n typeField: '__component',\n },\n on: {\n field: name,\n },\n orderBy: {\n order: 'asc',\n },\n pivotColumns: [joinColumnEntityName, joinColumnInverseName, field, COMPONENT_TYPE_COLUMN],\n },\n };\n }\n default: {\n return attribute;\n }\n }\n};\n\nexport const transformAttributes = (contentType: LoadedContentTypeModel) => {\n return Object.keys(contentType.attributes! || {}).reduce((attrs, attrName) => {\n return {\n ...attrs,\n [attrName]: transformAttribute(attrName, contentType.attributes[attrName]!, contentType),\n };\n }, {});\n};\n\nexport const hasComponentsOrDz = (\n contentType: LoadedContentTypeModel\n): contentType is LoadedContentTypeModel & { type: 'dynamiczone' | 'component' } => {\n return Object.values(contentType.attributes || {}).some(\n ({ type }) => type === 'dynamiczone' || type === 'component'\n );\n};\n\nexport const createDocumentId = createId;\n\n// Creates the\nconst createCompoLinkModel = (contentType: LoadedContentTypeModel): Model => {\n const name = getComponentJoinTableName(contentType.collectionName);\n\n const entityId = identifiers.getJoinColumnAttributeIdName(ENTITY);\n const componentId = identifiers.getJoinColumnAttributeIdName(COMPONENT_INVERSE_COLUMN_NAME);\n const fkIndex = identifiers.getFkIndexName([contentType.collectionName, ENTITY]);\n\n return {\n // TODO: make sure there can't be any conflicts with a prefix\n singularName: name,\n uid: name,\n tableName: name,\n attributes: {\n [id]: {\n type: 'increments',\n },\n [entityId]: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n [componentId]: {\n type: 'integer',\n column: {\n unsigned: true,\n },\n },\n [COMPONENT_TYPE_COLUMN]: {\n type: 'string',\n },\n [field]: {\n type: 'string',\n },\n [order]: {\n type: 'float',\n column: {\n unsigned: true,\n defaultTo: null,\n },\n },\n },\n indexes: [\n {\n name: identifiers.getIndexName([contentType.collectionName, field]),\n columns: [field],\n },\n {\n name: identifiers.getIndexName([contentType.collectionName, COMPONENT_TYPE_COLUMN]),\n columns: [COMPONENT_TYPE_COLUMN],\n },\n {\n name: fkIndex,\n columns: [entityId],\n },\n {\n // NOTE: since we don't include attribute names, we need to be careful not to create another unique index\n name: identifiers.getUniqueIndexName([contentType.collectionName]),\n columns: [entityId, componentId, field, COMPONENT_TYPE_COLUMN],\n type: 'unique',\n },\n ],\n foreignKeys: [\n {\n name: fkIndex,\n columns: [entityId],\n referencedColumns: [id],\n referencedTable: identifiers.getTableName(contentType.collectionName),\n onDelete: 'CASCADE',\n },\n ],\n };\n};\n\nexport const transformContentTypesToModels = (contentTypes: LoadedContentTypeModel[]): Model[] => {\n const models: Model[] = [];\n\n contentTypes.forEach((contentType) => {\n assert(contentType.collectionName, 'Content type \"collectionName\" is required');\n assert(contentType.modelName, 'Content type \"modelName\" is required');\n assert(contentType.uid, 'Content type \"uid\" is required');\n\n // Add document id to content types\n // as it is not documented\n const documentIdAttribute: Record<string, Attribute.Any> =\n contentType.modelType === 'contentType'\n ? { documentId: { type: 'string', default: createDocumentId } }\n : {};\n\n // TODO: this needs to be combined with getReservedNames, we should not be maintaining two lists\n // Prevent user from creating a documentId attribute\n const reservedAttributeNames = ['document_id', id];\n Object.keys(contentType.attributes || {}).forEach((attributeName) => {\n const snakeCasedAttributeName = _.snakeCase(attributeName);\n if (reservedAttributeNames.includes(snakeCasedAttributeName)) {\n throw new Error(\n `The attribute \"${attributeName}\" is reserved and cannot be used in a model. Please rename \"${contentType.modelName}\" attribute \"${attributeName}\" to something else.`\n );\n }\n });\n\n if (hasComponentsOrDz(contentType)) {\n const compoLinkModel = createCompoLinkModel(contentType);\n models.push(compoLinkModel);\n }\n\n const model: Model = {\n uid: contentType.uid,\n singularName: contentType.modelName,\n tableName: identifiers.getTableName(contentType.collectionName),\n attributes: {\n [id]: {\n type: 'increments',\n },\n ...documentIdAttribute,\n ...transformAttributes(contentType),\n },\n };\n\n models.push(model);\n });\n\n return models;\n};\n"],"names":[],"mappings":"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"}