@strapi/database 5.12.0 → 5.12.2

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 (321) hide show
  1. package/dist/connection.js +43 -0
  2. package/dist/connection.js.map +1 -0
  3. package/dist/connection.mjs +41 -0
  4. package/dist/connection.mjs.map +1 -0
  5. package/dist/dialects/dialect.js +54 -0
  6. package/dist/dialects/dialect.js.map +1 -0
  7. package/dist/dialects/dialect.mjs +52 -0
  8. package/dist/dialects/dialect.mjs.map +1 -0
  9. package/dist/dialects/index.js +44 -0
  10. package/dist/dialects/index.js.map +1 -0
  11. package/dist/dialects/index.mjs +42 -0
  12. package/dist/dialects/index.mjs.map +1 -0
  13. package/dist/dialects/mysql/constants.js +8 -0
  14. package/dist/dialects/mysql/constants.js.map +1 -0
  15. package/dist/dialects/mysql/constants.mjs +5 -0
  16. package/dist/dialects/mysql/constants.mjs.map +1 -0
  17. package/dist/dialects/mysql/database-inspector.js +35 -0
  18. package/dist/dialects/mysql/database-inspector.js.map +1 -0
  19. package/dist/dialects/mysql/database-inspector.mjs +33 -0
  20. package/dist/dialects/mysql/database-inspector.mjs.map +1 -0
  21. package/dist/dialects/mysql/index.js +75 -0
  22. package/dist/dialects/mysql/index.js.map +1 -0
  23. package/dist/dialects/mysql/index.mjs +73 -0
  24. package/dist/dialects/mysql/index.mjs.map +1 -0
  25. package/dist/dialects/mysql/schema-inspector.js +297 -0
  26. package/dist/dialects/mysql/schema-inspector.js.map +1 -0
  27. package/dist/dialects/mysql/schema-inspector.mjs +295 -0
  28. package/dist/dialects/mysql/schema-inspector.mjs.map +1 -0
  29. package/dist/dialects/postgresql/index.js +62 -0
  30. package/dist/dialects/postgresql/index.js.map +1 -0
  31. package/dist/dialects/postgresql/index.mjs +60 -0
  32. package/dist/dialects/postgresql/index.mjs.map +1 -0
  33. package/dist/dialects/postgresql/schema-inspector.js +316 -0
  34. package/dist/dialects/postgresql/schema-inspector.js.map +1 -0
  35. package/dist/dialects/postgresql/schema-inspector.mjs +314 -0
  36. package/dist/dialects/postgresql/schema-inspector.mjs.map +1 -0
  37. package/dist/dialects/sqlite/index.js +82 -0
  38. package/dist/dialects/sqlite/index.js.map +1 -0
  39. package/dist/dialects/sqlite/index.mjs +80 -0
  40. package/dist/dialects/sqlite/index.mjs.map +1 -0
  41. package/dist/dialects/sqlite/schema-inspector.js +211 -0
  42. package/dist/dialects/sqlite/schema-inspector.js.map +1 -0
  43. package/dist/dialects/sqlite/schema-inspector.mjs +209 -0
  44. package/dist/dialects/sqlite/schema-inspector.mjs.map +1 -0
  45. package/dist/entity-manager/entity-repository.js +139 -0
  46. package/dist/entity-manager/entity-repository.js.map +1 -0
  47. package/dist/entity-manager/entity-repository.mjs +137 -0
  48. package/dist/entity-manager/entity-repository.mjs.map +1 -0
  49. package/dist/entity-manager/index.js +1186 -0
  50. package/dist/entity-manager/index.js.map +1 -0
  51. package/dist/entity-manager/index.mjs +1184 -0
  52. package/dist/entity-manager/index.mjs.map +1 -0
  53. package/dist/entity-manager/morph-relations.js +73 -0
  54. package/dist/entity-manager/morph-relations.js.map +1 -0
  55. package/dist/entity-manager/morph-relations.mjs +69 -0
  56. package/dist/entity-manager/morph-relations.mjs.map +1 -0
  57. package/dist/entity-manager/regular-relations.js +247 -0
  58. package/dist/entity-manager/regular-relations.js.map +1 -0
  59. package/dist/entity-manager/regular-relations.mjs +242 -0
  60. package/dist/entity-manager/regular-relations.mjs.map +1 -0
  61. package/dist/entity-manager/relations-orderer.js +221 -0
  62. package/dist/entity-manager/relations-orderer.js.map +1 -0
  63. package/dist/entity-manager/relations-orderer.mjs +218 -0
  64. package/dist/entity-manager/relations-orderer.mjs.map +1 -0
  65. package/dist/errors/database.js +13 -0
  66. package/dist/errors/database.js.map +1 -0
  67. package/dist/errors/database.mjs +11 -0
  68. package/dist/errors/database.mjs.map +1 -0
  69. package/dist/errors/index.js +18 -0
  70. package/dist/errors/index.js.map +1 -0
  71. package/dist/errors/index.mjs +7 -0
  72. package/dist/errors/index.mjs.map +1 -0
  73. package/dist/errors/invalid-date.js +13 -0
  74. package/dist/errors/invalid-date.js.map +1 -0
  75. package/dist/errors/invalid-date.mjs +11 -0
  76. package/dist/errors/invalid-date.mjs.map +1 -0
  77. package/dist/errors/invalid-datetime.js +13 -0
  78. package/dist/errors/invalid-datetime.js.map +1 -0
  79. package/dist/errors/invalid-datetime.mjs +11 -0
  80. package/dist/errors/invalid-datetime.mjs.map +1 -0
  81. package/dist/errors/invalid-relation.js +13 -0
  82. package/dist/errors/invalid-relation.js.map +1 -0
  83. package/dist/errors/invalid-relation.mjs +11 -0
  84. package/dist/errors/invalid-relation.mjs.map +1 -0
  85. package/dist/errors/invalid-time.js +13 -0
  86. package/dist/errors/invalid-time.js.map +1 -0
  87. package/dist/errors/invalid-time.mjs +11 -0
  88. package/dist/errors/invalid-time.mjs.map +1 -0
  89. package/dist/errors/not-null.js +17 -0
  90. package/dist/errors/not-null.js.map +1 -0
  91. package/dist/errors/not-null.mjs +15 -0
  92. package/dist/errors/not-null.mjs.map +1 -0
  93. package/dist/fields/biginteger.js +9 -0
  94. package/dist/fields/biginteger.js.map +1 -0
  95. package/dist/fields/biginteger.mjs +7 -0
  96. package/dist/fields/biginteger.mjs.map +1 -0
  97. package/dist/fields/boolean.js +48 -0
  98. package/dist/fields/boolean.js.map +1 -0
  99. package/dist/fields/boolean.mjs +46 -0
  100. package/dist/fields/boolean.mjs.map +1 -0
  101. package/dist/fields/date.js +16 -0
  102. package/dist/fields/date.js.map +1 -0
  103. package/dist/fields/date.mjs +14 -0
  104. package/dist/fields/date.mjs.map +1 -0
  105. package/dist/fields/datetime.js +37 -0
  106. package/dist/fields/datetime.js.map +1 -0
  107. package/dist/fields/datetime.mjs +16 -0
  108. package/dist/fields/datetime.mjs.map +1 -0
  109. package/dist/fields/field.js +16 -0
  110. package/dist/fields/field.js.map +1 -0
  111. package/dist/fields/field.mjs +14 -0
  112. package/dist/fields/field.mjs.map +1 -0
  113. package/dist/fields/index.js +45 -0
  114. package/dist/fields/index.js.map +1 -0
  115. package/dist/fields/index.mjs +43 -0
  116. package/dist/fields/index.mjs.map +1 -0
  117. package/dist/fields/json.js +36 -0
  118. package/dist/fields/json.js.map +1 -0
  119. package/dist/fields/json.mjs +34 -0
  120. package/dist/fields/json.mjs.map +1 -0
  121. package/dist/fields/number.js +20 -0
  122. package/dist/fields/number.js.map +1 -0
  123. package/dist/fields/number.mjs +18 -0
  124. package/dist/fields/number.mjs.map +1 -0
  125. package/dist/fields/shared/parsers.js +91 -0
  126. package/dist/fields/shared/parsers.js.map +1 -0
  127. package/dist/fields/shared/parsers.mjs +68 -0
  128. package/dist/fields/shared/parsers.mjs.map +1 -0
  129. package/dist/fields/string.js +16 -0
  130. package/dist/fields/string.js.map +1 -0
  131. package/dist/fields/string.mjs +14 -0
  132. package/dist/fields/string.mjs.map +1 -0
  133. package/dist/fields/time.js +17 -0
  134. package/dist/fields/time.js.map +1 -0
  135. package/dist/fields/time.mjs +15 -0
  136. package/dist/fields/time.mjs.map +1 -0
  137. package/dist/fields/timestamp.js +37 -0
  138. package/dist/fields/timestamp.js.map +1 -0
  139. package/dist/fields/timestamp.mjs +16 -0
  140. package/dist/fields/timestamp.mjs.map +1 -0
  141. package/dist/index.js +33 -8569
  142. package/dist/index.js.map +1 -1
  143. package/dist/index.mjs +16 -8532
  144. package/dist/index.mjs.map +1 -1
  145. package/dist/lifecycles/index.js +73 -0
  146. package/dist/lifecycles/index.js.map +1 -0
  147. package/dist/lifecycles/index.mjs +71 -0
  148. package/dist/lifecycles/index.mjs.map +1 -0
  149. package/dist/lifecycles/subscribers/index.js +10 -0
  150. package/dist/lifecycles/subscribers/index.js.map +1 -0
  151. package/dist/lifecycles/subscribers/index.mjs +8 -0
  152. package/dist/lifecycles/subscribers/index.mjs.map +1 -0
  153. package/dist/lifecycles/subscribers/models-lifecycles.js +13 -0
  154. package/dist/lifecycles/subscribers/models-lifecycles.js.map +1 -0
  155. package/dist/lifecycles/subscribers/models-lifecycles.mjs +11 -0
  156. package/dist/lifecycles/subscribers/models-lifecycles.mjs.map +1 -0
  157. package/dist/lifecycles/subscribers/timestamps.js +55 -0
  158. package/dist/lifecycles/subscribers/timestamps.js.map +1 -0
  159. package/dist/lifecycles/subscribers/timestamps.mjs +53 -0
  160. package/dist/lifecycles/subscribers/timestamps.mjs.map +1 -0
  161. package/dist/metadata/index.js +24 -0
  162. package/dist/metadata/index.js.map +1 -0
  163. package/dist/metadata/index.mjs +16 -0
  164. package/dist/metadata/index.mjs.map +1 -0
  165. package/dist/metadata/metadata.js +100 -0
  166. package/dist/metadata/metadata.js.map +1 -0
  167. package/dist/metadata/metadata.mjs +98 -0
  168. package/dist/metadata/metadata.mjs.map +1 -0
  169. package/dist/metadata/relations.js +545 -0
  170. package/dist/metadata/relations.js.map +1 -0
  171. package/dist/metadata/relations.mjs +536 -0
  172. package/dist/metadata/relations.mjs.map +1 -0
  173. package/dist/migrations/common.js +8 -0
  174. package/dist/migrations/common.js.map +1 -0
  175. package/dist/migrations/common.mjs +6 -0
  176. package/dist/migrations/common.mjs.map +1 -0
  177. package/dist/migrations/index.js +39 -0
  178. package/dist/migrations/index.js.map +1 -0
  179. package/dist/migrations/index.mjs +37 -0
  180. package/dist/migrations/index.mjs.map +1 -0
  181. package/dist/migrations/internal-migrations/5.0.0-01-convert-identifiers-long-than-max-length.js +179 -0
  182. package/dist/migrations/internal-migrations/5.0.0-01-convert-identifiers-long-than-max-length.js.map +1 -0
  183. package/dist/migrations/internal-migrations/5.0.0-01-convert-identifiers-long-than-max-length.mjs +177 -0
  184. package/dist/migrations/internal-migrations/5.0.0-01-convert-identifiers-long-than-max-length.mjs.map +1 -0
  185. package/dist/migrations/internal-migrations/5.0.0-02-document-id.js +125 -0
  186. package/dist/migrations/internal-migrations/5.0.0-02-document-id.js.map +1 -0
  187. package/dist/migrations/internal-migrations/5.0.0-02-document-id.mjs +123 -0
  188. package/dist/migrations/internal-migrations/5.0.0-02-document-id.mjs.map +1 -0
  189. package/dist/migrations/internal-migrations/5.0.0-03-locale.js +41 -0
  190. package/dist/migrations/internal-migrations/5.0.0-03-locale.js.map +1 -0
  191. package/dist/migrations/internal-migrations/5.0.0-03-locale.mjs +39 -0
  192. package/dist/migrations/internal-migrations/5.0.0-03-locale.mjs.map +1 -0
  193. package/dist/migrations/internal-migrations/5.0.0-04-published-at.js +45 -0
  194. package/dist/migrations/internal-migrations/5.0.0-04-published-at.js.map +1 -0
  195. package/dist/migrations/internal-migrations/5.0.0-04-published-at.mjs +43 -0
  196. package/dist/migrations/internal-migrations/5.0.0-04-published-at.mjs.map +1 -0
  197. package/dist/migrations/internal-migrations/5.0.0-05-drop-slug-unique-index.js +43 -0
  198. package/dist/migrations/internal-migrations/5.0.0-05-drop-slug-unique-index.js.map +1 -0
  199. package/dist/migrations/internal-migrations/5.0.0-05-drop-slug-unique-index.mjs +41 -0
  200. package/dist/migrations/internal-migrations/5.0.0-05-drop-slug-unique-index.mjs.map +1 -0
  201. package/dist/migrations/internal-migrations/index.js +26 -0
  202. package/dist/migrations/internal-migrations/index.js.map +1 -0
  203. package/dist/migrations/internal-migrations/index.mjs +24 -0
  204. package/dist/migrations/internal-migrations/index.mjs.map +1 -0
  205. package/dist/migrations/internal.js +63 -0
  206. package/dist/migrations/internal.js.map +1 -0
  207. package/dist/migrations/internal.mjs +61 -0
  208. package/dist/migrations/internal.mjs.map +1 -0
  209. package/dist/migrations/logger.js +24 -0
  210. package/dist/migrations/logger.js.map +1 -0
  211. package/dist/migrations/logger.mjs +22 -0
  212. package/dist/migrations/logger.mjs.map +1 -0
  213. package/dist/migrations/storage.js +39 -0
  214. package/dist/migrations/storage.js.map +1 -0
  215. package/dist/migrations/storage.mjs +37 -0
  216. package/dist/migrations/storage.mjs.map +1 -0
  217. package/dist/migrations/users.js +87 -0
  218. package/dist/migrations/users.js.map +1 -0
  219. package/dist/migrations/users.mjs +85 -0
  220. package/dist/migrations/users.mjs.map +1 -0
  221. package/dist/query/helpers/join.js +127 -0
  222. package/dist/query/helpers/join.js.map +1 -0
  223. package/dist/query/helpers/join.mjs +122 -0
  224. package/dist/query/helpers/join.mjs.map +1 -0
  225. package/dist/query/helpers/order-by.js +167 -0
  226. package/dist/query/helpers/order-by.js.map +1 -0
  227. package/dist/query/helpers/order-by.mjs +163 -0
  228. package/dist/query/helpers/order-by.mjs.map +1 -0
  229. package/dist/query/helpers/populate/apply.js +592 -0
  230. package/dist/query/helpers/populate/apply.js.map +1 -0
  231. package/dist/query/helpers/populate/apply.mjs +590 -0
  232. package/dist/query/helpers/populate/apply.mjs.map +1 -0
  233. package/dist/query/helpers/populate/process.js +92 -0
  234. package/dist/query/helpers/populate/process.js.map +1 -0
  235. package/dist/query/helpers/populate/process.mjs +90 -0
  236. package/dist/query/helpers/populate/process.mjs.map +1 -0
  237. package/dist/query/helpers/search.js +67 -0
  238. package/dist/query/helpers/search.js.map +1 -0
  239. package/dist/query/helpers/search.mjs +65 -0
  240. package/dist/query/helpers/search.mjs.map +1 -0
  241. package/dist/query/helpers/streams/readable.js +131 -0
  242. package/dist/query/helpers/streams/readable.js.map +1 -0
  243. package/dist/query/helpers/streams/readable.mjs +129 -0
  244. package/dist/query/helpers/streams/readable.mjs.map +1 -0
  245. package/dist/query/helpers/transform.js +77 -0
  246. package/dist/query/helpers/transform.js.map +1 -0
  247. package/dist/query/helpers/transform.mjs +73 -0
  248. package/dist/query/helpers/transform.mjs.map +1 -0
  249. package/dist/query/helpers/where.js +372 -0
  250. package/dist/query/helpers/where.js.map +1 -0
  251. package/dist/query/helpers/where.mjs +369 -0
  252. package/dist/query/helpers/where.mjs.map +1 -0
  253. package/dist/query/query-builder.js +507 -0
  254. package/dist/query/query-builder.js.map +1 -0
  255. package/dist/query/query-builder.mjs +505 -0
  256. package/dist/query/query-builder.mjs.map +1 -0
  257. package/dist/repairs/index.js +13 -0
  258. package/dist/repairs/index.js.map +1 -0
  259. package/dist/repairs/index.mjs +11 -0
  260. package/dist/repairs/index.mjs.map +1 -0
  261. package/dist/repairs/operations/remove-orphan-morph-types.js +54 -0
  262. package/dist/repairs/operations/remove-orphan-morph-types.js.map +1 -0
  263. package/dist/repairs/operations/remove-orphan-morph-types.mjs +52 -0
  264. package/dist/repairs/operations/remove-orphan-morph-types.mjs.map +1 -0
  265. package/dist/schema/builder.js +354 -0
  266. package/dist/schema/builder.js.map +1 -0
  267. package/dist/schema/builder.mjs +352 -0
  268. package/dist/schema/builder.mjs.map +1 -0
  269. package/dist/schema/diff.js +379 -0
  270. package/dist/schema/diff.js.map +1 -0
  271. package/dist/schema/diff.mjs +377 -0
  272. package/dist/schema/diff.mjs.map +1 -0
  273. package/dist/schema/index.js +93 -0
  274. package/dist/schema/index.js.map +1 -0
  275. package/dist/schema/index.mjs +91 -0
  276. package/dist/schema/index.mjs.map +1 -0
  277. package/dist/schema/schema.js +266 -0
  278. package/dist/schema/schema.js.map +1 -0
  279. package/dist/schema/schema.mjs +264 -0
  280. package/dist/schema/schema.mjs.map +1 -0
  281. package/dist/schema/storage.js +58 -0
  282. package/dist/schema/storage.js.map +1 -0
  283. package/dist/schema/storage.mjs +56 -0
  284. package/dist/schema/storage.mjs.map +1 -0
  285. package/dist/transaction-context.js +65 -0
  286. package/dist/transaction-context.js.map +1 -0
  287. package/dist/transaction-context.mjs +63 -0
  288. package/dist/transaction-context.mjs.map +1 -0
  289. package/dist/utils/async-curry.js +19 -0
  290. package/dist/utils/async-curry.js.map +1 -0
  291. package/dist/utils/async-curry.mjs +17 -0
  292. package/dist/utils/async-curry.mjs.map +1 -0
  293. package/dist/utils/identifiers/hash.js +30 -0
  294. package/dist/utils/identifiers/hash.js.map +1 -0
  295. package/dist/utils/identifiers/hash.mjs +28 -0
  296. package/dist/utils/identifiers/hash.mjs.map +1 -0
  297. package/dist/utils/identifiers/index.js +414 -0
  298. package/dist/utils/identifiers/index.js.map +1 -0
  299. package/dist/utils/identifiers/index.mjs +411 -0
  300. package/dist/utils/identifiers/index.mjs.map +1 -0
  301. package/dist/utils/knex.js +21 -0
  302. package/dist/utils/knex.js.map +1 -0
  303. package/dist/utils/knex.mjs +18 -0
  304. package/dist/utils/knex.mjs.map +1 -0
  305. package/dist/utils/types.js +51 -0
  306. package/dist/utils/types.js.map +1 -0
  307. package/dist/utils/types.mjs +44 -0
  308. package/dist/utils/types.mjs.map +1 -0
  309. package/dist/validations/index.js +12 -0
  310. package/dist/validations/index.js.map +1 -0
  311. package/dist/validations/index.mjs +10 -0
  312. package/dist/validations/index.mjs.map +1 -0
  313. package/dist/validations/relations/bidirectional.js +64 -0
  314. package/dist/validations/relations/bidirectional.js.map +1 -0
  315. package/dist/validations/relations/bidirectional.mjs +62 -0
  316. package/dist/validations/relations/bidirectional.mjs.map +1 -0
  317. package/dist/validations/relations/index.js +13 -0
  318. package/dist/validations/relations/index.js.map +1 -0
  319. package/dist/validations/relations/index.mjs +11 -0
  320. package/dist/validations/relations/index.mjs.map +1 -0
  321. package/package.json +4 -4
@@ -0,0 +1,590 @@
1
+ import _ from 'lodash/fp';
2
+ import { fromRow } from '../transform.mjs';
3
+
4
+ // We must select the join column id, however whatever it is named will overwrite an attribute of the same name
5
+ // Therefore, we will prefix with something unlikely to conflict with a user attribute
6
+ // TODO: ...and completely restrict the strapi_ prefix for an attribute name in the future
7
+ const joinColPrefix = '__strapi';
8
+ /**
9
+ * Populate oneToOne and manyToOne relation
10
+ * @param {*} input
11
+ * @param {*} ctx
12
+ * @returns
13
+ */ const XtoOne = async (input, ctx)=>{
14
+ const { attribute, attributeName, results, populateValue, targetMeta, isCount } = input;
15
+ const { db, qb } = ctx;
16
+ const fromTargetRow = (rowOrRows)=>fromRow(targetMeta, rowOrRows);
17
+ if ('joinColumn' in attribute && attribute.joinColumn) {
18
+ const { name: joinColumnName, referencedColumn: referencedColumnName } = attribute.joinColumn;
19
+ const referencedValues = _.uniq(results.map((r)=>r[joinColumnName]).filter((value)=>!_.isNil(value)));
20
+ if (_.isEmpty(referencedValues)) {
21
+ results.forEach((result)=>{
22
+ result[attributeName] = null;
23
+ });
24
+ return;
25
+ }
26
+ const rows = await db.entityManager.createQueryBuilder(targetMeta.uid).init(populateValue).addSelect(`${qb.alias}.${referencedColumnName}`).where({
27
+ [referencedColumnName]: referencedValues
28
+ }).execute({
29
+ mapResults: false
30
+ });
31
+ const map = _.groupBy(referencedColumnName)(rows);
32
+ results.forEach((result)=>{
33
+ result[attributeName] = fromTargetRow(_.first(map[result[joinColumnName]]));
34
+ });
35
+ return;
36
+ }
37
+ if ('joinTable' in attribute && attribute.joinTable) {
38
+ const { joinTable } = attribute;
39
+ const qb = db.entityManager.createQueryBuilder(targetMeta.uid);
40
+ const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
41
+ const alias = qb.getAlias();
42
+ const joinColAlias = `${alias}.${joinColumnName}`;
43
+ const joinColRenameAs = `${joinColPrefix}${joinColumnName}`;
44
+ const joinColSelect = `${joinColAlias} as ${joinColRenameAs}`;
45
+ const referencedValues = _.uniq(results.map((r)=>r[referencedColumnName]).filter((value)=>!_.isNil(value)));
46
+ if (isCount) {
47
+ if (_.isEmpty(referencedValues)) {
48
+ results.forEach((result)=>{
49
+ result[attributeName] = {
50
+ count: 0
51
+ };
52
+ });
53
+ return;
54
+ }
55
+ const rows = await qb.init(populateValue).join({
56
+ alias,
57
+ referencedTable: joinTable.name,
58
+ referencedColumn: joinTable.inverseJoinColumn.name,
59
+ rootColumn: joinTable.inverseJoinColumn.referencedColumn,
60
+ rootTable: qb.alias,
61
+ on: joinTable.on
62
+ }).select([
63
+ joinColAlias,
64
+ qb.raw('count(*) AS count')
65
+ ]).where({
66
+ [joinColAlias]: referencedValues
67
+ }).groupBy(joinColAlias).execute({
68
+ mapResults: false
69
+ });
70
+ const map = rows.reduce((map, row)=>{
71
+ map[row[joinColumnName]] = {
72
+ count: Number(row.count)
73
+ };
74
+ return map;
75
+ }, {});
76
+ results.forEach((result)=>{
77
+ result[attributeName] = map[result[referencedColumnName]] || {
78
+ count: 0
79
+ };
80
+ });
81
+ return;
82
+ }
83
+ if (_.isEmpty(referencedValues)) {
84
+ results.forEach((result)=>{
85
+ result[attributeName] = null;
86
+ });
87
+ return;
88
+ }
89
+ const rows = await qb.init(populateValue).join({
90
+ alias,
91
+ referencedTable: joinTable.name,
92
+ referencedColumn: joinTable.inverseJoinColumn.name,
93
+ rootColumn: joinTable.inverseJoinColumn.referencedColumn,
94
+ rootTable: qb.alias,
95
+ on: joinTable.on,
96
+ orderBy: joinTable.orderBy
97
+ }).addSelect(joinColSelect).where({
98
+ [joinColAlias]: referencedValues
99
+ }).execute({
100
+ mapResults: false
101
+ });
102
+ const map = _.groupBy(joinColRenameAs)(rows);
103
+ results.forEach((result)=>{
104
+ result[attributeName] = fromTargetRow(_.first(map[result[referencedColumnName]]));
105
+ });
106
+ }
107
+ };
108
+ const oneToMany = async (input, ctx)=>{
109
+ const { attribute, attributeName, results, populateValue, targetMeta, isCount } = input;
110
+ const { db, qb } = ctx;
111
+ const fromTargetRow = (rowOrRows)=>fromRow(targetMeta, rowOrRows);
112
+ if ('joinColumn' in attribute && attribute.joinColumn) {
113
+ const { name: joinColumnName, referencedColumn: referencedColumnName, on } = attribute.joinColumn;
114
+ const referencedValues = _.uniq(results.map((r)=>r[joinColumnName]).filter((value)=>!_.isNil(value)));
115
+ if (_.isEmpty(referencedValues)) {
116
+ results.forEach((result)=>{
117
+ result[attributeName] = null;
118
+ });
119
+ return;
120
+ }
121
+ const rows = await db.entityManager.createQueryBuilder(targetMeta.uid).init(populateValue).addSelect(`${qb.alias}.${referencedColumnName}`).where({
122
+ [referencedColumnName]: referencedValues,
123
+ ...on && typeof on === 'function' ? on({
124
+ populateValue,
125
+ results
126
+ }) : {}
127
+ }).execute({
128
+ mapResults: false
129
+ });
130
+ const map = _.groupBy(referencedColumnName)(rows);
131
+ results.forEach((result)=>{
132
+ result[attributeName] = fromTargetRow(map[result[joinColumnName]] || []);
133
+ });
134
+ return;
135
+ }
136
+ if ('joinTable' in attribute && attribute.joinTable) {
137
+ const { joinTable } = attribute;
138
+ const qb = db.entityManager.createQueryBuilder(targetMeta.uid);
139
+ const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
140
+ const alias = qb.getAlias();
141
+ const joinColAlias = `${alias}.${joinColumnName}`;
142
+ const joinColRenameAs = `${joinColPrefix}${joinColumnName}`;
143
+ const joinColSelect = `${joinColAlias} as ${joinColRenameAs}`;
144
+ const referencedValues = _.uniq(results.map((r)=>r[referencedColumnName]).filter((value)=>!_.isNil(value)));
145
+ if (isCount) {
146
+ if (_.isEmpty(referencedValues)) {
147
+ results.forEach((result)=>{
148
+ result[attributeName] = {
149
+ count: 0
150
+ };
151
+ });
152
+ return;
153
+ }
154
+ const rows = await qb.init(populateValue).join({
155
+ alias,
156
+ referencedTable: joinTable.name,
157
+ referencedColumn: joinTable.inverseJoinColumn.name,
158
+ rootColumn: joinTable.inverseJoinColumn.referencedColumn,
159
+ rootTable: qb.alias,
160
+ on: joinTable.on
161
+ }).select([
162
+ joinColSelect,
163
+ qb.raw('count(*) AS count')
164
+ ]).where({
165
+ [joinColAlias]: referencedValues
166
+ }).groupBy(joinColAlias).execute({
167
+ mapResults: false
168
+ });
169
+ const map = rows.reduce((map, row)=>{
170
+ map[row[joinColRenameAs]] = {
171
+ count: Number(row.count)
172
+ };
173
+ return map;
174
+ }, {});
175
+ results.forEach((result)=>{
176
+ result[attributeName] = map[result[referencedColumnName]] || {
177
+ count: 0
178
+ };
179
+ });
180
+ return;
181
+ }
182
+ if (_.isEmpty(referencedValues)) {
183
+ results.forEach((result)=>{
184
+ result[attributeName] = [];
185
+ });
186
+ return;
187
+ }
188
+ const rows = await qb.init(populateValue).join({
189
+ alias,
190
+ referencedTable: joinTable.name,
191
+ referencedColumn: joinTable.inverseJoinColumn.name,
192
+ rootColumn: joinTable.inverseJoinColumn.referencedColumn,
193
+ rootTable: qb.alias,
194
+ on: joinTable.on,
195
+ orderBy: _.mapValues((v)=>populateValue.ordering || v, joinTable.orderBy)
196
+ }).addSelect(joinColSelect).where({
197
+ [joinColAlias]: referencedValues
198
+ }).execute({
199
+ mapResults: false
200
+ });
201
+ const map = _.groupBy(joinColRenameAs)(rows);
202
+ results.forEach((r)=>{
203
+ r[attributeName] = fromTargetRow(map[r[referencedColumnName]] || []);
204
+ });
205
+ }
206
+ };
207
+ const manyToMany = async (input, ctx)=>{
208
+ const { attribute, attributeName, results, populateValue, targetMeta, isCount } = input;
209
+ const { db } = ctx;
210
+ const fromTargetRow = (rowOrRows)=>fromRow(targetMeta, rowOrRows);
211
+ const { joinTable } = attribute;
212
+ const populateQb = db.entityManager.createQueryBuilder(targetMeta.uid);
213
+ const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
214
+ const alias = populateQb.getAlias();
215
+ const joinColAlias = `${alias}.${joinColumnName}`;
216
+ const joinColRenameAs = `${joinColPrefix}${joinColumnName}`;
217
+ const joinColSelect = `${joinColAlias} as ${joinColRenameAs}`;
218
+ const referencedValues = _.uniq(results.map((r)=>r[referencedColumnName]).filter((value)=>!_.isNil(value)));
219
+ if (isCount) {
220
+ if (_.isEmpty(referencedValues)) {
221
+ results.forEach((result)=>{
222
+ result[attributeName] = {
223
+ count: 0
224
+ };
225
+ });
226
+ return;
227
+ }
228
+ const rows = await populateQb.init(populateValue).join({
229
+ alias,
230
+ referencedTable: joinTable.name,
231
+ referencedColumn: joinTable.inverseJoinColumn.name,
232
+ rootColumn: joinTable.inverseJoinColumn.referencedColumn,
233
+ rootTable: populateQb.alias,
234
+ on: joinTable.on
235
+ }).select([
236
+ joinColAlias,
237
+ populateQb.raw('count(*) AS count')
238
+ ]).where({
239
+ [joinColAlias]: referencedValues
240
+ }).groupBy(joinColAlias).execute({
241
+ mapResults: false
242
+ });
243
+ const map = rows.reduce((map, row)=>{
244
+ map[row[joinColumnName]] = {
245
+ count: Number(row.count)
246
+ };
247
+ return map;
248
+ }, {});
249
+ results.forEach((result)=>{
250
+ result[attributeName] = map[result[referencedColumnName]] || {
251
+ count: 0
252
+ };
253
+ });
254
+ return;
255
+ }
256
+ if (_.isEmpty(referencedValues)) {
257
+ results.forEach((result)=>{
258
+ result[attributeName] = [];
259
+ });
260
+ return;
261
+ }
262
+ const rows = await populateQb.init(populateValue).join({
263
+ alias,
264
+ referencedTable: joinTable.name,
265
+ referencedColumn: joinTable.inverseJoinColumn.name,
266
+ rootColumn: joinTable.inverseJoinColumn.referencedColumn,
267
+ rootTable: populateQb.alias,
268
+ on: joinTable.on,
269
+ orderBy: _.mapValues((v)=>populateValue.ordering || v, joinTable.orderBy)
270
+ }).addSelect(joinColSelect).where({
271
+ [joinColAlias]: referencedValues
272
+ }).execute({
273
+ mapResults: false
274
+ });
275
+ const map = _.groupBy(joinColRenameAs)(rows);
276
+ results.forEach((result)=>{
277
+ result[attributeName] = fromTargetRow(map[result[referencedColumnName]] || []);
278
+ });
279
+ };
280
+ const morphX = async (input, ctx)=>{
281
+ const { attribute, attributeName, results, populateValue, targetMeta } = input;
282
+ const { db, uid } = ctx;
283
+ const fromTargetRow = (rowOrRows)=>fromRow(targetMeta, rowOrRows);
284
+ const { target, morphBy } = attribute;
285
+ const targetAttribute = db.metadata.get(target).attributes[morphBy];
286
+ if (targetAttribute.type === 'relation' && targetAttribute.relation === 'morphToOne') {
287
+ const { idColumn, typeColumn } = targetAttribute.morphColumn;
288
+ const referencedValues = _.uniq(results.map((r)=>r[idColumn.referencedColumn]).filter((value)=>!_.isNil(value)));
289
+ if (_.isEmpty(referencedValues)) {
290
+ results.forEach((result)=>{
291
+ result[attributeName] = null;
292
+ });
293
+ return;
294
+ }
295
+ const rows = await db.entityManager.createQueryBuilder(target).init(populateValue)// .addSelect(`${qb.alias}.${idColumn.referencedColumn}`)
296
+ .where({
297
+ [idColumn.name]: referencedValues,
298
+ [typeColumn.name]: uid
299
+ }).execute({
300
+ mapResults: false
301
+ });
302
+ const map = _.groupBy(idColumn.name)(rows);
303
+ results.forEach((result)=>{
304
+ const matchingRows = map[result[idColumn.referencedColumn]];
305
+ const matchingValue = attribute.relation === 'morphOne' ? _.first(matchingRows) : matchingRows;
306
+ result[attributeName] = fromTargetRow(matchingValue);
307
+ });
308
+ } else if (targetAttribute.type === 'relation' && targetAttribute.relation === 'morphToMany') {
309
+ const { joinTable } = targetAttribute;
310
+ const { joinColumn, morphColumn } = joinTable;
311
+ const { idColumn, typeColumn } = morphColumn;
312
+ const referencedValues = _.uniq(results.map((r)=>r[idColumn.referencedColumn]).filter((value)=>!_.isNil(value)));
313
+ if (_.isEmpty(referencedValues)) {
314
+ results.forEach((result)=>{
315
+ result[attributeName] = attribute.relation === 'morphOne' ? null : [];
316
+ });
317
+ return;
318
+ }
319
+ // find with join table
320
+ const qb = db.entityManager.createQueryBuilder(target);
321
+ const alias = qb.getAlias();
322
+ const rows = await qb.init(populateValue).join({
323
+ alias,
324
+ referencedTable: joinTable.name,
325
+ referencedColumn: joinColumn.name,
326
+ rootColumn: joinColumn.referencedColumn,
327
+ rootTable: qb.alias,
328
+ on: {
329
+ ...joinTable.on || {},
330
+ field: attributeName
331
+ },
332
+ orderBy: _.mapValues((v)=>populateValue.ordering || v, joinTable.orderBy)
333
+ }).addSelect([
334
+ `${alias}.${idColumn.name}`,
335
+ `${alias}.${typeColumn.name}`
336
+ ]).where({
337
+ [`${alias}.${idColumn.name}`]: referencedValues,
338
+ [`${alias}.${typeColumn.name}`]: uid
339
+ }).execute({
340
+ mapResults: false
341
+ });
342
+ const map = _.groupBy(idColumn.name)(rows);
343
+ results.forEach((result)=>{
344
+ const matchingRows = map[result[idColumn.referencedColumn]];
345
+ const matchingValue = attribute.relation === 'morphOne' ? _.first(matchingRows) : matchingRows;
346
+ result[attributeName] = fromTargetRow(matchingValue);
347
+ });
348
+ }
349
+ };
350
+ const morphToMany = async (input, ctx)=>{
351
+ const { attribute, attributeName, results, populateValue } = input;
352
+ const { db } = ctx;
353
+ // find with join table
354
+ const { joinTable } = attribute;
355
+ const { joinColumn, morphColumn } = joinTable;
356
+ const { idColumn, typeColumn, typeField = '__type' } = morphColumn;
357
+ // fetch join table to create the ids map then do the same as morphToOne without the first
358
+ const referencedValues = _.uniq(results.map((r)=>r[joinColumn.referencedColumn]).filter((value)=>!_.isNil(value)));
359
+ const qb = db.entityManager.createQueryBuilder(joinTable.name);
360
+ const joinRows = await qb.where({
361
+ [joinColumn.name]: referencedValues,
362
+ ...joinTable.on || {},
363
+ // If the populateValue contains an "on" property,
364
+ // only populate the types defined in it
365
+ ...'on' in populateValue ? {
366
+ [morphColumn.typeColumn.name]: Object.keys(populateValue.on ?? {})
367
+ } : {}
368
+ }).orderBy([
369
+ joinColumn.name,
370
+ 'order'
371
+ ]).execute({
372
+ mapResults: false
373
+ });
374
+ const joinMap = _.groupBy(joinColumn.name, joinRows);
375
+ const idsByType = joinRows.reduce((acc, result)=>{
376
+ const idValue = result[morphColumn.idColumn.name];
377
+ const typeValue = result[morphColumn.typeColumn.name];
378
+ if (!idValue || !typeValue) {
379
+ return acc;
380
+ }
381
+ if (!_.has(typeValue, acc)) {
382
+ acc[typeValue] = [];
383
+ }
384
+ acc[typeValue].push(idValue);
385
+ return acc;
386
+ }, {});
387
+ const map = {};
388
+ const { on, ...typePopulate } = populateValue;
389
+ for (const type of Object.keys(idsByType)){
390
+ const ids = idsByType[type];
391
+ // type was removed but still in morph relation
392
+ if (!db.metadata.get(type)) {
393
+ map[type] = {};
394
+ continue;
395
+ }
396
+ const qb = db.entityManager.createQueryBuilder(type);
397
+ const rows = await qb.init(on?.[type] ?? typePopulate).addSelect(`${qb.alias}.${idColumn.referencedColumn}`).where({
398
+ [idColumn.referencedColumn]: ids
399
+ }).execute({
400
+ mapResults: false
401
+ });
402
+ map[type] = _.groupBy(idColumn.referencedColumn)(rows);
403
+ }
404
+ results.forEach((result)=>{
405
+ const joinResults = joinMap[result[joinColumn.referencedColumn]] || [];
406
+ const matchingRows = joinResults.flatMap((joinResult)=>{
407
+ const id = joinResult[idColumn.name];
408
+ const type = joinResult[typeColumn.name];
409
+ const targetMeta = db.metadata.get(type);
410
+ const fromTargetRow = (rowOrRows)=>fromRow(targetMeta, rowOrRows);
411
+ return (map[type][id] || []).map((row)=>{
412
+ return {
413
+ [typeField]: type,
414
+ ...fromTargetRow(row)
415
+ };
416
+ });
417
+ });
418
+ result[attributeName] = matchingRows;
419
+ });
420
+ };
421
+ const morphToOne = async (input, ctx)=>{
422
+ const { attribute, attributeName, results, populateValue } = input;
423
+ const { db } = ctx;
424
+ const { morphColumn } = attribute;
425
+ const { idColumn, typeColumn } = morphColumn;
426
+ // make a map for each type what ids to return
427
+ // make a nested map per id
428
+ const idsByType = results.reduce((acc, result)=>{
429
+ const idValue = result[morphColumn.idColumn.name];
430
+ const typeValue = result[morphColumn.typeColumn.name];
431
+ if (!idValue || !typeValue) {
432
+ return acc;
433
+ }
434
+ if (!(typeValue in acc)) {
435
+ acc[typeValue] = [];
436
+ }
437
+ acc[typeValue].push(idValue);
438
+ return acc;
439
+ }, {});
440
+ const map = {};
441
+ const { on, ...typePopulate } = populateValue;
442
+ for (const type of Object.keys(idsByType)){
443
+ const ids = idsByType[type];
444
+ // type was removed but still in morph relation
445
+ if (!db.metadata.get(type)) {
446
+ map[type] = {};
447
+ return;
448
+ }
449
+ const qb = db.entityManager.createQueryBuilder(type);
450
+ const rows = await qb.init(on?.[type] ?? typePopulate).addSelect(`${qb.alias}.${idColumn.referencedColumn}`).where({
451
+ [idColumn.referencedColumn]: ids
452
+ }).execute({
453
+ mapResults: false
454
+ });
455
+ map[type] = _.groupBy(idColumn.referencedColumn)(rows);
456
+ }
457
+ results.forEach((result)=>{
458
+ const id = result[idColumn.name];
459
+ const type = result[typeColumn.name];
460
+ if (!type || !id) {
461
+ result[attributeName] = null;
462
+ return;
463
+ }
464
+ const matchingRows = map[type][id];
465
+ const fromTargetRow = (rowOrRows)=>fromRow(db.metadata.get(type), rowOrRows);
466
+ result[attributeName] = fromTargetRow(_.first(matchingRows));
467
+ });
468
+ };
469
+ // TODO: Omit limit & offset to avoid needing a query per result to avoid making too many queries
470
+ const pickPopulateParams = (populate)=>{
471
+ const fieldsToPick = [
472
+ 'select',
473
+ 'count',
474
+ 'where',
475
+ 'populate',
476
+ 'orderBy',
477
+ 'filters',
478
+ 'ordering',
479
+ 'on'
480
+ ];
481
+ if (populate.count !== true) {
482
+ fieldsToPick.push('limit', 'offset');
483
+ }
484
+ return _.pick(fieldsToPick, populate);
485
+ };
486
+ const applyPopulate = async (results, populate, ctx)=>{
487
+ const { db, uid, qb } = ctx;
488
+ const meta = db.metadata.get(uid);
489
+ if (_.isEmpty(results)) {
490
+ return results;
491
+ }
492
+ for (const attributeName of Object.keys(populate)){
493
+ const attribute = meta.attributes[attributeName];
494
+ if (attribute.type !== 'relation') {
495
+ throw new Error(`Invalid populate attribute ${attributeName}`);
496
+ }
497
+ const populateValue = {
498
+ filters: qb.state.filters,
499
+ ...pickPopulateParams(populate[attributeName])
500
+ };
501
+ const isCount = 'count' in populateValue && populateValue.count === true;
502
+ switch(attribute.relation){
503
+ case 'oneToOne':
504
+ case 'manyToOne':
505
+ {
506
+ const targetMeta = db.metadata.get(attribute.target);
507
+ const input = {
508
+ attribute,
509
+ attributeName,
510
+ results,
511
+ populateValue,
512
+ targetMeta,
513
+ isCount
514
+ };
515
+ await XtoOne(input, ctx);
516
+ break;
517
+ }
518
+ case 'oneToMany':
519
+ {
520
+ const targetMeta = db.metadata.get(attribute.target);
521
+ const input = {
522
+ attribute,
523
+ attributeName,
524
+ results,
525
+ populateValue,
526
+ targetMeta,
527
+ isCount
528
+ };
529
+ await oneToMany(input, ctx);
530
+ break;
531
+ }
532
+ case 'manyToMany':
533
+ {
534
+ const targetMeta = db.metadata.get(attribute.target);
535
+ const input = {
536
+ attribute,
537
+ attributeName,
538
+ results,
539
+ populateValue,
540
+ targetMeta,
541
+ isCount
542
+ };
543
+ await manyToMany(input, ctx);
544
+ break;
545
+ }
546
+ case 'morphOne':
547
+ case 'morphMany':
548
+ {
549
+ const targetMeta = db.metadata.get(attribute.target);
550
+ const input = {
551
+ attribute,
552
+ attributeName,
553
+ results,
554
+ populateValue,
555
+ targetMeta,
556
+ isCount
557
+ };
558
+ await morphX(input, ctx);
559
+ break;
560
+ }
561
+ case 'morphToMany':
562
+ {
563
+ const input = {
564
+ attribute,
565
+ attributeName,
566
+ results,
567
+ populateValue,
568
+ isCount
569
+ };
570
+ await morphToMany(input, ctx);
571
+ break;
572
+ }
573
+ case 'morphToOne':
574
+ {
575
+ const input = {
576
+ attribute,
577
+ attributeName,
578
+ results,
579
+ populateValue,
580
+ isCount
581
+ };
582
+ await morphToOne(input, ctx);
583
+ break;
584
+ }
585
+ }
586
+ }
587
+ };
588
+
589
+ export { applyPopulate as default };
590
+ //# sourceMappingURL=apply.mjs.map