@payloadcms/drizzle 3.0.0-canary.690108d → 3.0.0-canary.71da5b9

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 (237) hide show
  1. package/dist/count.d.ts.map +1 -1
  2. package/dist/count.js +1 -1
  3. package/dist/count.js.map +1 -1
  4. package/dist/createGlobalVersion.d.ts +1 -1
  5. package/dist/createGlobalVersion.d.ts.map +1 -1
  6. package/dist/createGlobalVersion.js +6 -2
  7. package/dist/createGlobalVersion.js.map +1 -1
  8. package/dist/createTableName.d.ts.map +1 -1
  9. package/dist/createTableName.js +6 -2
  10. package/dist/createTableName.js.map +1 -1
  11. package/dist/createVersion.d.ts +1 -1
  12. package/dist/createVersion.d.ts.map +1 -1
  13. package/dist/createVersion.js +21 -14
  14. package/dist/createVersion.js.map +1 -1
  15. package/dist/deleteOne.d.ts.map +1 -1
  16. package/dist/deleteOne.js +5 -3
  17. package/dist/deleteOne.js.map +1 -1
  18. package/dist/deleteVersions.js +1 -1
  19. package/dist/deleteVersions.js.map +1 -1
  20. package/dist/destroy.d.ts.map +1 -1
  21. package/dist/destroy.js +3 -1
  22. package/dist/destroy.js.map +1 -1
  23. package/dist/exports/postgres.d.ts +1 -0
  24. package/dist/exports/postgres.d.ts.map +1 -1
  25. package/dist/exports/postgres.js +1 -0
  26. package/dist/exports/postgres.js.map +1 -1
  27. package/dist/find/buildFindManyArgs.d.ts +13 -7
  28. package/dist/find/buildFindManyArgs.d.ts.map +1 -1
  29. package/dist/find/buildFindManyArgs.js +7 -1
  30. package/dist/find/buildFindManyArgs.js.map +1 -1
  31. package/dist/find/findMany.d.ts +1 -1
  32. package/dist/find/findMany.d.ts.map +1 -1
  33. package/dist/find/findMany.js +6 -3
  34. package/dist/find/findMany.js.map +1 -1
  35. package/dist/find/traverseFields.d.ts +7 -3
  36. package/dist/find/traverseFields.d.ts.map +1 -1
  37. package/dist/find/traverseFields.js +147 -16
  38. package/dist/find/traverseFields.js.map +1 -1
  39. package/dist/find.d.ts.map +1 -1
  40. package/dist/find.js +2 -1
  41. package/dist/find.js.map +1 -1
  42. package/dist/findGlobalVersions.js +1 -1
  43. package/dist/findGlobalVersions.js.map +1 -1
  44. package/dist/findMigrationDir.d.ts.map +1 -1
  45. package/dist/findMigrationDir.js +3 -1
  46. package/dist/findMigrationDir.js.map +1 -1
  47. package/dist/findOne.d.ts +1 -1
  48. package/dist/findOne.d.ts.map +1 -1
  49. package/dist/findOne.js +2 -1
  50. package/dist/findOne.js.map +1 -1
  51. package/dist/findVersions.js +1 -1
  52. package/dist/findVersions.js.map +1 -1
  53. package/dist/index.d.ts +2 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +2 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/migrate.js +1 -0
  58. package/dist/migrate.js.map +1 -1
  59. package/dist/migrateDown.d.ts.map +1 -1
  60. package/dist/migrateDown.js +1 -1
  61. package/dist/migrateDown.js.map +1 -1
  62. package/dist/migrateFresh.d.ts.map +1 -1
  63. package/dist/migrateFresh.js +1 -0
  64. package/dist/migrateFresh.js.map +1 -1
  65. package/dist/migrateRefresh.d.ts.map +1 -1
  66. package/dist/migrateRefresh.js +2 -1
  67. package/dist/migrateRefresh.js.map +1 -1
  68. package/dist/migrateReset.d.ts.map +1 -1
  69. package/dist/migrateReset.js +4 -2
  70. package/dist/migrateReset.js.map +1 -1
  71. package/dist/migrateStatus.js +0 -1
  72. package/dist/migrateStatus.js.map +1 -1
  73. package/dist/postgres/countDistinct.d.ts.map +1 -1
  74. package/dist/postgres/countDistinct.js +3 -3
  75. package/dist/postgres/countDistinct.js.map +1 -1
  76. package/dist/postgres/createDatabase.d.ts +14 -0
  77. package/dist/postgres/createDatabase.d.ts.map +1 -0
  78. package/dist/postgres/createDatabase.js +73 -0
  79. package/dist/postgres/createDatabase.js.map +1 -0
  80. package/dist/postgres/createJSONQuery/convertPathToJSONTraversal.d.ts.map +1 -1
  81. package/dist/postgres/createJSONQuery/convertPathToJSONTraversal.js +3 -1
  82. package/dist/postgres/createJSONQuery/convertPathToJSONTraversal.js.map +1 -1
  83. package/dist/postgres/createMigration.d.ts.map +1 -1
  84. package/dist/postgres/createMigration.js +1 -0
  85. package/dist/postgres/createMigration.js.map +1 -1
  86. package/dist/postgres/getMigrationTemplate.d.ts +1 -1
  87. package/dist/postgres/getMigrationTemplate.d.ts.map +1 -1
  88. package/dist/postgres/getMigrationTemplate.js +1 -1
  89. package/dist/postgres/getMigrationTemplate.js.map +1 -1
  90. package/dist/postgres/init.d.ts.map +1 -1
  91. package/dist/postgres/init.js +13 -3
  92. package/dist/postgres/init.js.map +1 -1
  93. package/dist/postgres/schema/build.d.ts +14 -3
  94. package/dist/postgres/schema/build.d.ts.map +1 -1
  95. package/dist/postgres/schema/build.js +42 -10
  96. package/dist/postgres/schema/build.js.map +1 -1
  97. package/dist/postgres/schema/createIndex.d.ts.map +1 -1
  98. package/dist/postgres/schema/createIndex.js +3 -1
  99. package/dist/postgres/schema/createIndex.js.map +1 -1
  100. package/dist/postgres/schema/traverseFields.d.ts +11 -3
  101. package/dist/postgres/schema/traverseFields.d.ts.map +1 -1
  102. package/dist/postgres/schema/traverseFields.js +214 -68
  103. package/dist/postgres/schema/traverseFields.js.map +1 -1
  104. package/dist/postgres/schema/withDefault.d.ts.map +1 -1
  105. package/dist/postgres/schema/withDefault.js +3 -1
  106. package/dist/postgres/schema/withDefault.js.map +1 -1
  107. package/dist/postgres/types.d.ts +32 -5
  108. package/dist/postgres/types.d.ts.map +1 -1
  109. package/dist/postgres/types.js.map +1 -1
  110. package/dist/queries/buildAndOrConditions.d.ts +1 -1
  111. package/dist/queries/buildAndOrConditions.d.ts.map +1 -1
  112. package/dist/queries/buildAndOrConditions.js +2 -4
  113. package/dist/queries/buildAndOrConditions.js.map +1 -1
  114. package/dist/queries/buildOrderBy.d.ts +18 -0
  115. package/dist/queries/buildOrderBy.d.ts.map +1 -0
  116. package/dist/queries/buildOrderBy.js +52 -0
  117. package/dist/queries/buildOrderBy.js.map +1 -0
  118. package/dist/queries/buildQuery.d.ts +5 -4
  119. package/dist/queries/buildQuery.d.ts.map +1 -1
  120. package/dist/queries/buildQuery.js +12 -47
  121. package/dist/queries/buildQuery.js.map +1 -1
  122. package/dist/queries/getTableColumnFromPath.d.ts +8 -3
  123. package/dist/queries/getTableColumnFromPath.d.ts.map +1 -1
  124. package/dist/queries/getTableColumnFromPath.js +73 -23
  125. package/dist/queries/getTableColumnFromPath.js.map +1 -1
  126. package/dist/queries/operatorMap.d.ts.map +1 -1
  127. package/dist/queries/operatorMap.js.map +1 -1
  128. package/dist/queries/parseParams.d.ts +1 -1
  129. package/dist/queries/parseParams.d.ts.map +1 -1
  130. package/dist/queries/parseParams.js +52 -6
  131. package/dist/queries/parseParams.js.map +1 -1
  132. package/dist/queries/sanitizeQueryValue.d.ts +12 -1
  133. package/dist/queries/sanitizeQueryValue.d.ts.map +1 -1
  134. package/dist/queries/sanitizeQueryValue.js +77 -21
  135. package/dist/queries/sanitizeQueryValue.js.map +1 -1
  136. package/dist/queries/selectDistinct.d.ts +3 -4
  137. package/dist/queries/selectDistinct.d.ts.map +1 -1
  138. package/dist/queries/selectDistinct.js.map +1 -1
  139. package/dist/queryDrafts.d.ts.map +1 -1
  140. package/dist/queryDrafts.js +2 -5
  141. package/dist/queryDrafts.js.map +1 -1
  142. package/dist/transactions/beginTransaction.d.ts.map +1 -1
  143. package/dist/transactions/beginTransaction.js +5 -1
  144. package/dist/transactions/beginTransaction.js.map +1 -1
  145. package/dist/transactions/commitTransaction.d.ts.map +1 -1
  146. package/dist/transactions/commitTransaction.js +3 -1
  147. package/dist/transactions/commitTransaction.js.map +1 -1
  148. package/dist/transform/read/hasManyNumber.d.ts +2 -1
  149. package/dist/transform/read/hasManyNumber.d.ts.map +1 -1
  150. package/dist/transform/read/hasManyNumber.js +12 -2
  151. package/dist/transform/read/hasManyNumber.js.map +1 -1
  152. package/dist/transform/read/hasManyText.d.ts +2 -1
  153. package/dist/transform/read/hasManyText.d.ts.map +1 -1
  154. package/dist/transform/read/hasManyText.js +12 -2
  155. package/dist/transform/read/hasManyText.js.map +1 -1
  156. package/dist/transform/read/index.d.ts +3 -2
  157. package/dist/transform/read/index.d.ts.map +1 -1
  158. package/dist/transform/read/index.js +3 -2
  159. package/dist/transform/read/index.js.map +1 -1
  160. package/dist/transform/read/relationship.d.ts +2 -1
  161. package/dist/transform/read/relationship.d.ts.map +1 -1
  162. package/dist/transform/read/relationship.js +15 -6
  163. package/dist/transform/read/relationship.js.map +1 -1
  164. package/dist/transform/read/traverseFields.d.ts +10 -2
  165. package/dist/transform/read/traverseFields.d.ts.map +1 -1
  166. package/dist/transform/read/traverseFields.js +170 -56
  167. package/dist/transform/read/traverseFields.js.map +1 -1
  168. package/dist/transform/write/array.d.ts +6 -1
  169. package/dist/transform/write/array.d.ts.map +1 -1
  170. package/dist/transform/write/array.js +7 -3
  171. package/dist/transform/write/array.js.map +1 -1
  172. package/dist/transform/write/blocks.d.ts +8 -3
  173. package/dist/transform/write/blocks.d.ts.map +1 -1
  174. package/dist/transform/write/blocks.js +19 -7
  175. package/dist/transform/write/blocks.js.map +1 -1
  176. package/dist/transform/write/index.d.ts.map +1 -1
  177. package/dist/transform/write/index.js +1 -1
  178. package/dist/transform/write/index.js.map +1 -1
  179. package/dist/transform/write/relationships.d.ts.map +1 -1
  180. package/dist/transform/write/relationships.js +6 -2
  181. package/dist/transform/write/relationships.js.map +1 -1
  182. package/dist/transform/write/selects.d.ts.map +1 -1
  183. package/dist/transform/write/selects.js +1 -1
  184. package/dist/transform/write/selects.js.map +1 -1
  185. package/dist/transform/write/traverseFields.d.ts +6 -1
  186. package/dist/transform/write/traverseFields.d.ts.map +1 -1
  187. package/dist/transform/write/traverseFields.js +46 -17
  188. package/dist/transform/write/traverseFields.js.map +1 -1
  189. package/dist/types.d.ts +1 -1
  190. package/dist/types.d.ts.map +1 -1
  191. package/dist/types.js.map +1 -1
  192. package/dist/update.d.ts.map +1 -1
  193. package/dist/update.js +3 -2
  194. package/dist/update.js.map +1 -1
  195. package/dist/updateGlobalVersion.js +2 -2
  196. package/dist/updateGlobalVersion.js.map +1 -1
  197. package/dist/updateVersion.js +2 -2
  198. package/dist/updateVersion.js.map +1 -1
  199. package/dist/upsertRow/deleteExistingRowsByPath.d.ts.map +1 -1
  200. package/dist/upsertRow/deleteExistingRowsByPath.js +6 -2
  201. package/dist/upsertRow/deleteExistingRowsByPath.js.map +1 -1
  202. package/dist/upsertRow/index.d.ts +1 -1
  203. package/dist/upsertRow/index.d.ts.map +1 -1
  204. package/dist/upsertRow/index.js +50 -12
  205. package/dist/upsertRow/index.js.map +1 -1
  206. package/dist/upsertRow/insertArrays.d.ts.map +1 -1
  207. package/dist/upsertRow/insertArrays.js +5 -2
  208. package/dist/upsertRow/insertArrays.js.map +1 -1
  209. package/dist/upsertRow/types.d.ts +8 -5
  210. package/dist/upsertRow/types.d.ts.map +1 -1
  211. package/dist/upsertRow/types.js.map +1 -1
  212. package/dist/utilities/createBlocksMap.d.ts.map +1 -1
  213. package/dist/utilities/createBlocksMap.js +4 -2
  214. package/dist/utilities/createBlocksMap.js.map +1 -1
  215. package/dist/utilities/createRelationshipMap.d.ts.map +1 -1
  216. package/dist/utilities/createRelationshipMap.js +3 -1
  217. package/dist/utilities/createRelationshipMap.js.map +1 -1
  218. package/dist/utilities/executeSchemaHooks.d.ts +24 -0
  219. package/dist/utilities/executeSchemaHooks.d.ts.map +1 -0
  220. package/dist/utilities/executeSchemaHooks.js +21 -0
  221. package/dist/utilities/executeSchemaHooks.js.map +1 -0
  222. package/dist/utilities/extendDrizzleTable.d.ts +19 -0
  223. package/dist/utilities/extendDrizzleTable.d.ts.map +1 -0
  224. package/dist/utilities/extendDrizzleTable.js +38 -0
  225. package/dist/utilities/extendDrizzleTable.js.map +1 -0
  226. package/dist/utilities/getCollectionIdType.d.ts +7 -0
  227. package/dist/utilities/getCollectionIdType.d.ts.map +1 -0
  228. package/dist/utilities/getCollectionIdType.js +11 -0
  229. package/dist/utilities/getCollectionIdType.js.map +1 -0
  230. package/dist/utilities/hasLocalesTable.d.ts.map +1 -1
  231. package/dist/utilities/hasLocalesTable.js +12 -4
  232. package/dist/utilities/hasLocalesTable.js.map +1 -1
  233. package/dist/utilities/isPolymorphicRelationship.d.ts +6 -0
  234. package/dist/utilities/isPolymorphicRelationship.d.ts.map +1 -0
  235. package/dist/utilities/isPolymorphicRelationship.js +5 -0
  236. package/dist/utilities/isPolymorphicRelationship.js.map +1 -0
  237. package/package.json +7 -5
@@ -1,7 +1,7 @@
1
1
  import { relations } from 'drizzle-orm';
2
- import { PgNumericBuilder, PgUUIDBuilder, PgVarcharBuilder, boolean, foreignKey, index, integer, jsonb, numeric, text, timestamp, varchar } from 'drizzle-orm/pg-core';
2
+ import { boolean, foreignKey, index, integer, jsonb, numeric, PgNumericBuilder, PgUUIDBuilder, PgVarcharBuilder, text, timestamp, varchar } from 'drizzle-orm/pg-core';
3
3
  import { InvalidConfiguration } from 'payload';
4
- import { fieldAffectsData, optionIsObject } from 'payload/shared';
4
+ import { fieldAffectsData, fieldIsVirtual, optionIsObject } from 'payload/shared';
5
5
  import toSnakeCase from 'to-snake-case';
6
6
  import { createTableName } from '../../createTableName.js';
7
7
  import { hasLocalesTable } from '../../utilities/hasLocalesTable.js';
@@ -11,7 +11,7 @@ import { createIndex } from './createIndex.js';
11
11
  import { idToUUID } from './idToUUID.js';
12
12
  import { parentIDColumnMap } from './parentIDColumnMap.js';
13
13
  import { withDefault } from './withDefault.js';
14
- export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull, disableUnique = false, fieldPrefix, fields, forceLocalized, indexes, localesColumns, localesIndexes, newTableName, parentTableName, relationsToBuild, relationships, rootRelationsToBuild, rootTableIDColType, rootTableName, versions })=>{
14
+ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull, disableRelsTableUnique, disableUnique = false, fieldPrefix, fields, forceLocalized, indexes, joins, localesColumns, localesIndexes, newTableName, parentTableName, relationships, relationsToBuild, rootRelationsToBuild, rootTableIDColType, rootTableName, uniqueRelationships, versions, withinLocalizedArrayOrBlock })=>{
15
15
  const throwValidationError = true;
16
16
  let hasLocalizedField = false;
17
17
  let hasLocalizedRelationshipField = false;
@@ -20,11 +20,22 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
20
20
  let hasManyNumberField = false;
21
21
  let hasLocalizedManyNumberField = false;
22
22
  let parentIDColType = 'integer';
23
- if (columns.id instanceof PgUUIDBuilder) parentIDColType = 'uuid';
24
- if (columns.id instanceof PgNumericBuilder) parentIDColType = 'numeric';
25
- if (columns.id instanceof PgVarcharBuilder) parentIDColType = 'varchar';
23
+ if (columns.id instanceof PgUUIDBuilder) {
24
+ parentIDColType = 'uuid';
25
+ }
26
+ if (columns.id instanceof PgNumericBuilder) {
27
+ parentIDColType = 'numeric';
28
+ }
29
+ if (columns.id instanceof PgVarcharBuilder) {
30
+ parentIDColType = 'varchar';
31
+ }
26
32
  fields.forEach((field)=>{
27
- if ('name' in field && field.name === 'id') return;
33
+ if ('name' in field && field.name === 'id') {
34
+ return;
35
+ }
36
+ if (fieldIsVirtual(field)) {
37
+ return;
38
+ }
28
39
  let columnName;
29
40
  let fieldName;
30
41
  let targetTable = columns;
@@ -39,14 +50,15 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
39
50
  targetTable = localesColumns;
40
51
  targetIndexes = localesIndexes;
41
52
  }
42
- if ((field.unique || field.index) && ![
53
+ if ((field.unique || field.index || [
54
+ 'relationship',
55
+ 'upload'
56
+ ].includes(field.type)) && ![
43
57
  'array',
44
58
  'blocks',
45
59
  'group',
46
- 'point',
47
- 'relationship',
48
- 'upload'
49
- ].includes(field.type) && !('hasMany' in field && field.hasMany === true)) {
60
+ 'point'
61
+ ].includes(field.type) && !('hasMany' in field && field.hasMany === true) && !('relationTo' in field && Array.isArray(field.relationTo))) {
50
62
  const unique = disableUnique !== true && field.unique;
51
63
  if (unique) {
52
64
  const constraintValue = `${fieldPrefix || ''}${field.name}`;
@@ -56,7 +68,10 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
56
68
  adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue;
57
69
  }
58
70
  targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
59
- name: fieldName,
71
+ name: field.localized ? [
72
+ fieldName,
73
+ '_locale'
74
+ ] : fieldName,
60
75
  columnName,
61
76
  tableName: newTableName,
62
77
  unique
@@ -67,7 +82,8 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
67
82
  case 'text':
68
83
  {
69
84
  if (field.hasMany) {
70
- if (field.localized) {
85
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
86
+ if (isLocalized) {
71
87
  hasLocalizedManyTextField = true;
72
88
  }
73
89
  if (field.index) {
@@ -93,7 +109,8 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
93
109
  case 'number':
94
110
  {
95
111
  if (field.hasMany) {
96
- if (field.localized) {
112
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
113
+ if (isLocalized) {
97
114
  hasLocalizedManyNumberField = true;
98
115
  }
99
116
  if (field.index) {
@@ -172,7 +189,8 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
172
189
  }).onDelete('cascade'),
173
190
  parentIdx: (cols)=>index(`${selectTableName}_parent_idx`).on(cols.parent)
174
191
  };
175
- if (field.localized) {
192
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
193
+ if (isLocalized) {
176
194
  baseColumns.locale = adapter.enums.enum__locales('locale').notNull();
177
195
  baseExtraConfig.localeIdx = (cols)=>index(`${selectTableName}_locale_idx`).on(cols.locale);
178
196
  }
@@ -208,7 +226,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
208
226
  })
209
227
  }));
210
228
  } else {
211
- targetTable[fieldName] = withDefault(adapter.enums[enumName](fieldName), field);
229
+ targetTable[fieldName] = withDefault(adapter.enums[enumName](columnName), field);
212
230
  }
213
231
  break;
214
232
  }
@@ -245,29 +263,46 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
245
263
  }).onDelete('cascade'),
246
264
  _parentIDIdx: (cols)=>index(`${arrayTableName}_parent_id_idx`).on(cols._parentID)
247
265
  };
248
- if (field.localized && adapter.payload.config.localization) {
266
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
267
+ if (isLocalized) {
249
268
  baseColumns._locale = adapter.enums.enum__locales('_locale').notNull();
250
269
  baseExtraConfig._localeIdx = (cols)=>index(`${arrayTableName}_locale_idx`).on(cols._locale);
251
270
  }
252
- const { hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
271
+ const { hasLocalizedManyNumberField: subHasLocalizedManyNumberField, hasLocalizedManyTextField: subHasLocalizedManyTextField, hasLocalizedRelationshipField: subHasLocalizedRelationshipField, hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
253
272
  adapter,
254
273
  baseColumns,
255
274
  baseExtraConfig,
256
275
  disableNotNull: disableNotNullFromHere,
276
+ disableRelsTableUnique: true,
257
277
  disableUnique,
258
278
  fields: disableUnique ? idToUUID(field.fields) : field.fields,
259
- rootRelationsToBuild,
260
279
  rootRelationships: relationships,
280
+ rootRelationsToBuild,
261
281
  rootTableIDColType,
262
282
  rootTableName,
283
+ rootUniqueRelationships: uniqueRelationships,
263
284
  tableName: arrayTableName,
264
- versions
285
+ versions,
286
+ withinLocalizedArrayOrBlock: isLocalized
265
287
  });
288
+ if (subHasLocalizedManyNumberField) {
289
+ hasLocalizedManyNumberField = subHasLocalizedManyNumberField;
290
+ }
291
+ if (subHasLocalizedRelationshipField) {
292
+ hasLocalizedRelationshipField = subHasLocalizedRelationshipField;
293
+ }
294
+ if (subHasLocalizedManyTextField) {
295
+ hasLocalizedManyTextField = subHasLocalizedManyTextField;
296
+ }
266
297
  if (subHasManyTextField) {
267
- if (!hasManyTextField || subHasManyTextField === 'index') hasManyTextField = subHasManyTextField;
298
+ if (!hasManyTextField || subHasManyTextField === 'index') {
299
+ hasManyTextField = subHasManyTextField;
300
+ }
268
301
  }
269
302
  if (subHasManyNumberField) {
270
- if (!hasManyNumberField || subHasManyNumberField === 'index') hasManyNumberField = subHasManyNumberField;
303
+ if (!hasManyNumberField || subHasManyNumberField === 'index') {
304
+ hasManyNumberField = subHasManyNumberField;
305
+ }
271
306
  }
272
307
  relationsToBuild.set(fieldName, {
273
308
  type: 'many',
@@ -335,7 +370,6 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
335
370
  };
336
371
  const baseExtraConfig = {
337
372
  _orderIdx: (cols)=>index(`${blockTableName}_order_idx`).on(cols._order),
338
- _parentIDIdx: (cols)=>index(`${blockTableName}_parent_id_idx`).on(cols._parentID),
339
373
  _parentIdFk: (cols)=>foreignKey({
340
374
  name: `${blockTableName}_parent_id_fk`,
341
375
  columns: [
@@ -345,31 +379,49 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
345
379
  adapter.tables[rootTableName].id
346
380
  ]
347
381
  }).onDelete('cascade'),
382
+ _parentIDIdx: (cols)=>index(`${blockTableName}_parent_id_idx`).on(cols._parentID),
348
383
  _pathIdx: (cols)=>index(`${blockTableName}_path_idx`).on(cols._path)
349
384
  };
350
- if (field.localized && adapter.payload.config.localization) {
385
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
386
+ if (isLocalized) {
351
387
  baseColumns._locale = adapter.enums.enum__locales('_locale').notNull();
352
388
  baseExtraConfig._localeIdx = (cols)=>index(`${blockTableName}_locale_idx`).on(cols._locale);
353
389
  }
354
- const { hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
390
+ const { hasLocalizedManyNumberField: subHasLocalizedManyNumberField, hasLocalizedManyTextField: subHasLocalizedManyTextField, hasLocalizedRelationshipField: subHasLocalizedRelationshipField, hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
355
391
  adapter,
356
392
  baseColumns,
357
393
  baseExtraConfig,
358
394
  disableNotNull: disableNotNullFromHere,
395
+ disableRelsTableUnique: true,
359
396
  disableUnique,
360
397
  fields: disableUnique ? idToUUID(block.fields) : block.fields,
361
- rootRelationsToBuild,
362
398
  rootRelationships: relationships,
399
+ rootRelationsToBuild,
363
400
  rootTableIDColType,
364
401
  rootTableName,
402
+ rootUniqueRelationships: uniqueRelationships,
365
403
  tableName: blockTableName,
366
- versions
404
+ versions,
405
+ withinLocalizedArrayOrBlock: isLocalized
367
406
  });
407
+ if (subHasLocalizedManyNumberField) {
408
+ hasLocalizedManyNumberField = subHasLocalizedManyNumberField;
409
+ }
410
+ if (subHasLocalizedRelationshipField) {
411
+ hasLocalizedRelationshipField = subHasLocalizedRelationshipField;
412
+ }
413
+ if (subHasLocalizedManyTextField) {
414
+ hasLocalizedManyTextField = subHasLocalizedManyTextField;
415
+ }
368
416
  if (subHasManyTextField) {
369
- if (!hasManyTextField || subHasManyTextField === 'index') hasManyTextField = subHasManyTextField;
417
+ if (!hasManyTextField || subHasManyTextField === 'index') {
418
+ hasManyTextField = subHasManyTextField;
419
+ }
370
420
  }
371
421
  if (subHasManyNumberField) {
372
- if (!hasManyNumberField || subHasManyNumberField === 'index') hasManyNumberField = subHasManyNumberField;
422
+ if (!hasManyNumberField || subHasManyNumberField === 'index') {
423
+ hasManyNumberField = subHasManyNumberField;
424
+ }
373
425
  }
374
426
  adapter.relations[`relations_${blockTableName}`] = relations(adapter.tables[blockTableName], ({ many, one })=>{
375
427
  const result = {
@@ -442,23 +494,38 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
442
494
  fields: field.fields,
443
495
  forceLocalized,
444
496
  indexes,
497
+ joins,
445
498
  localesColumns,
446
499
  localesIndexes,
447
500
  newTableName,
448
501
  parentTableName,
449
- relationsToBuild,
450
502
  relationships,
503
+ relationsToBuild,
451
504
  rootRelationsToBuild,
452
505
  rootTableIDColType,
453
506
  rootTableName,
454
- versions
507
+ uniqueRelationships,
508
+ versions,
509
+ withinLocalizedArrayOrBlock
455
510
  });
456
- if (groupHasLocalizedField) hasLocalizedField = true;
457
- if (groupHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
458
- if (groupHasManyTextField) hasManyTextField = true;
459
- if (groupHasLocalizedManyTextField) hasLocalizedManyTextField = true;
460
- if (groupHasManyNumberField) hasManyNumberField = true;
461
- if (groupHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
511
+ if (groupHasLocalizedField) {
512
+ hasLocalizedField = true;
513
+ }
514
+ if (groupHasLocalizedRelationshipField) {
515
+ hasLocalizedRelationshipField = true;
516
+ }
517
+ if (groupHasManyTextField) {
518
+ hasManyTextField = true;
519
+ }
520
+ if (groupHasLocalizedManyTextField) {
521
+ hasLocalizedManyTextField = true;
522
+ }
523
+ if (groupHasManyNumberField) {
524
+ hasManyNumberField = true;
525
+ }
526
+ if (groupHasLocalizedManyNumberField) {
527
+ hasLocalizedManyNumberField = true;
528
+ }
462
529
  break;
463
530
  }
464
531
  const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
@@ -472,23 +539,38 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
472
539
  fields: field.fields,
473
540
  forceLocalized: field.localized,
474
541
  indexes,
542
+ joins,
475
543
  localesColumns,
476
544
  localesIndexes,
477
545
  newTableName: `${parentTableName}_${columnName}`,
478
546
  parentTableName,
479
- relationsToBuild,
480
547
  relationships,
548
+ relationsToBuild,
481
549
  rootRelationsToBuild,
482
550
  rootTableIDColType,
483
551
  rootTableName,
484
- versions
552
+ uniqueRelationships,
553
+ versions,
554
+ withinLocalizedArrayOrBlock: withinLocalizedArrayOrBlock || field.localized
485
555
  });
486
- if (groupHasLocalizedField) hasLocalizedField = true;
487
- if (groupHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
488
- if (groupHasManyTextField) hasManyTextField = true;
489
- if (groupHasLocalizedManyTextField) hasLocalizedManyTextField = true;
490
- if (groupHasManyNumberField) hasManyNumberField = true;
491
- if (groupHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
556
+ if (groupHasLocalizedField) {
557
+ hasLocalizedField = true;
558
+ }
559
+ if (groupHasLocalizedRelationshipField) {
560
+ hasLocalizedRelationshipField = true;
561
+ }
562
+ if (groupHasManyTextField) {
563
+ hasManyTextField = true;
564
+ }
565
+ if (groupHasLocalizedManyTextField) {
566
+ hasLocalizedManyTextField = true;
567
+ }
568
+ if (groupHasManyNumberField) {
569
+ hasManyNumberField = true;
570
+ }
571
+ if (groupHasLocalizedManyNumberField) {
572
+ hasLocalizedManyNumberField = true;
573
+ }
492
574
  break;
493
575
  }
494
576
  case 'tabs':
@@ -507,23 +589,38 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
507
589
  })),
508
590
  forceLocalized,
509
591
  indexes,
592
+ joins,
510
593
  localesColumns,
511
594
  localesIndexes,
512
595
  newTableName,
513
596
  parentTableName,
514
- relationsToBuild,
515
597
  relationships,
598
+ relationsToBuild,
516
599
  rootRelationsToBuild,
517
600
  rootTableIDColType,
518
601
  rootTableName,
519
- versions
602
+ uniqueRelationships,
603
+ versions,
604
+ withinLocalizedArrayOrBlock
520
605
  });
521
- if (tabHasLocalizedField) hasLocalizedField = true;
522
- if (tabHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
523
- if (tabHasManyTextField) hasManyTextField = true;
524
- if (tabHasLocalizedManyTextField) hasLocalizedManyTextField = true;
525
- if (tabHasManyNumberField) hasManyNumberField = true;
526
- if (tabHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
606
+ if (tabHasLocalizedField) {
607
+ hasLocalizedField = true;
608
+ }
609
+ if (tabHasLocalizedRelationshipField) {
610
+ hasLocalizedRelationshipField = true;
611
+ }
612
+ if (tabHasManyTextField) {
613
+ hasManyTextField = true;
614
+ }
615
+ if (tabHasLocalizedManyTextField) {
616
+ hasLocalizedManyTextField = true;
617
+ }
618
+ if (tabHasManyNumberField) {
619
+ hasManyNumberField = true;
620
+ }
621
+ if (tabHasLocalizedManyNumberField) {
622
+ hasLocalizedManyNumberField = true;
623
+ }
527
624
  break;
528
625
  }
529
626
  case 'row':
@@ -540,31 +637,54 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
540
637
  fields: field.fields,
541
638
  forceLocalized,
542
639
  indexes,
640
+ joins,
543
641
  localesColumns,
544
642
  localesIndexes,
545
643
  newTableName,
546
644
  parentTableName,
547
- relationsToBuild,
548
645
  relationships,
646
+ relationsToBuild,
549
647
  rootRelationsToBuild,
550
648
  rootTableIDColType,
551
649
  rootTableName,
552
- versions
650
+ uniqueRelationships,
651
+ versions,
652
+ withinLocalizedArrayOrBlock
553
653
  });
554
- if (rowHasLocalizedField) hasLocalizedField = true;
555
- if (rowHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
556
- if (rowHasManyTextField) hasManyTextField = true;
557
- if (rowHasLocalizedManyTextField) hasLocalizedManyTextField = true;
558
- if (rowHasManyNumberField) hasManyNumberField = true;
559
- if (rowHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
654
+ if (rowHasLocalizedField) {
655
+ hasLocalizedField = true;
656
+ }
657
+ if (rowHasLocalizedRelationshipField) {
658
+ hasLocalizedRelationshipField = true;
659
+ }
660
+ if (rowHasManyTextField) {
661
+ hasManyTextField = true;
662
+ }
663
+ if (rowHasLocalizedManyTextField) {
664
+ hasLocalizedManyTextField = true;
665
+ }
666
+ if (rowHasManyNumberField) {
667
+ hasManyNumberField = true;
668
+ }
669
+ if (rowHasLocalizedManyNumberField) {
670
+ hasLocalizedManyNumberField = true;
671
+ }
560
672
  break;
561
673
  }
562
674
  case 'relationship':
563
675
  case 'upload':
564
676
  if (Array.isArray(field.relationTo)) {
565
- field.relationTo.forEach((relation)=>relationships.add(relation));
566
- } else if (field.type === 'relationship' && field.hasMany) {
677
+ field.relationTo.forEach((relation)=>{
678
+ relationships.add(relation);
679
+ if (field.unique && !disableUnique && !disableRelsTableUnique) {
680
+ uniqueRelationships.add(relation);
681
+ }
682
+ });
683
+ } else if (field.hasMany) {
567
684
  relationships.add(field.relationTo);
685
+ if (field.unique && !disableUnique && !disableRelsTableUnique) {
686
+ uniqueRelationships.add(field.relationTo);
687
+ }
568
688
  } else {
569
689
  // simple relationships get a column on the targetTable with a foreign key to the relationTo table
570
690
  const relationshipConfig = adapter.payload.collections[field.relationTo].config;
@@ -572,8 +692,12 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
572
692
  // get the id type of the related collection
573
693
  let colType = adapter.idType === 'uuid' ? 'uuid' : 'integer';
574
694
  const relatedCollectionCustomID = relationshipConfig.fields.find((field)=>fieldAffectsData(field) && field.name === 'id');
575
- if (relatedCollectionCustomID?.type === 'number') colType = 'numeric';
576
- if (relatedCollectionCustomID?.type === 'text') colType = 'varchar';
695
+ if (relatedCollectionCustomID?.type === 'number') {
696
+ colType = 'numeric';
697
+ }
698
+ if (relatedCollectionCustomID?.type === 'text') {
699
+ colType = 'varchar';
700
+ }
577
701
  // make the foreign key column for relationship using the correct id column type
578
702
  targetTable[fieldName] = parentIDColumnMap[colType](`${columnName}_id`).references(()=>adapter.tables[tableName].id, {
579
703
  onDelete: 'set null'
@@ -581,7 +705,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
581
705
  // add relationship to table
582
706
  relationsToBuild.set(fieldName, {
583
707
  type: 'one',
584
- localized: adapter.payload.config.localization && field.localized,
708
+ localized: adapter.payload.config.localization && (field.localized || forceLocalized),
585
709
  target: tableName
586
710
  });
587
711
  // add notNull when not required
@@ -590,10 +714,32 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
590
714
  }
591
715
  break;
592
716
  }
593
- if (adapter.payload.config.localization && field.localized) {
717
+ if (Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock) {
594
718
  hasLocalizedRelationshipField = true;
595
719
  }
596
720
  break;
721
+ case 'join':
722
+ {
723
+ // fieldName could be 'posts' or 'group_posts'
724
+ // using `on` as the key for the relation
725
+ const localized = adapter.payload.config.localization && field.localized;
726
+ const fieldSchemaPath = `${fieldPrefix || ''}${field.name}`;
727
+ let target;
728
+ const joinConfig = joins[field.collection].find(({ schemaPath })=>fieldSchemaPath === schemaPath);
729
+ if (joinConfig.targetField.hasMany) {
730
+ target = `${adapter.tableNameMap.get(toSnakeCase(field.collection))}${adapter.relationshipsSuffix}`;
731
+ } else {
732
+ target = `${adapter.tableNameMap.get(toSnakeCase(field.collection))}${localized ? adapter.localesSuffix : ''}`;
733
+ }
734
+ relationsToBuild.set(fieldName, {
735
+ type: 'many',
736
+ // joins are not localized on the parent table
737
+ localized: false,
738
+ relationName: field.on.replaceAll('.', '_'),
739
+ target
740
+ });
741
+ break;
742
+ }
597
743
  default:
598
744
  break;
599
745
  }