@payloadcms/drizzle 3.0.0-canary.cb7fa00 → 3.0.0-canary.cdb9474

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 (125) hide show
  1. package/dist/exports/postgres.d.ts +14 -0
  2. package/dist/exports/postgres.d.ts.map +1 -0
  3. package/dist/exports/postgres.js +15 -0
  4. package/dist/exports/postgres.js.map +1 -0
  5. package/dist/find/traverseFields.d.ts.map +1 -1
  6. package/dist/find/traverseFields.js +2 -2
  7. package/dist/find/traverseFields.js.map +1 -1
  8. package/dist/postgres/countDistinct.d.ts +3 -0
  9. package/dist/postgres/countDistinct.d.ts.map +1 -0
  10. package/dist/postgres/countDistinct.js +24 -0
  11. package/dist/postgres/countDistinct.js.map +1 -0
  12. package/dist/postgres/createJSONQuery/convertPathToJSONTraversal.d.ts +2 -0
  13. package/dist/postgres/createJSONQuery/convertPathToJSONTraversal.d.ts.map +1 -0
  14. package/dist/postgres/createJSONQuery/convertPathToJSONTraversal.js +14 -0
  15. package/dist/postgres/createJSONQuery/convertPathToJSONTraversal.js.map +1 -0
  16. package/dist/postgres/createJSONQuery/formatJSONPathSegment.d.ts +2 -0
  17. package/dist/postgres/createJSONQuery/formatJSONPathSegment.d.ts.map +1 -0
  18. package/dist/postgres/createJSONQuery/formatJSONPathSegment.js +5 -0
  19. package/dist/postgres/createJSONQuery/formatJSONPathSegment.js.map +1 -0
  20. package/dist/postgres/createJSONQuery/index.d.ts +10 -0
  21. package/dist/postgres/createJSONQuery/index.d.ts.map +1 -0
  22. package/dist/postgres/createJSONQuery/index.js +54 -0
  23. package/dist/postgres/createJSONQuery/index.js.map +1 -0
  24. package/dist/postgres/createMigration.d.ts +3 -0
  25. package/dist/postgres/createMigration.d.ts.map +1 -0
  26. package/dist/postgres/createMigration.js +92 -0
  27. package/dist/postgres/createMigration.js.map +1 -0
  28. package/dist/postgres/defaultSnapshot.d.ts +3 -0
  29. package/dist/postgres/defaultSnapshot.d.ts.map +1 -0
  30. package/dist/postgres/defaultSnapshot.js +17 -0
  31. package/dist/postgres/defaultSnapshot.js.map +1 -0
  32. package/dist/postgres/deleteWhere.d.ts +3 -0
  33. package/dist/postgres/deleteWhere.d.ts.map +1 -0
  34. package/dist/postgres/deleteWhere.js +6 -0
  35. package/dist/postgres/deleteWhere.js.map +1 -0
  36. package/dist/postgres/dropDatabase.d.ts +3 -0
  37. package/dist/postgres/dropDatabase.d.ts.map +1 -0
  38. package/dist/postgres/dropDatabase.js +9 -0
  39. package/dist/postgres/dropDatabase.js.map +1 -0
  40. package/dist/postgres/execute.d.ts +3 -0
  41. package/dist/postgres/execute.d.ts.map +1 -0
  42. package/dist/postgres/execute.js +11 -0
  43. package/dist/postgres/execute.js.map +1 -0
  44. package/dist/postgres/getMigrationTemplate.d.ts +4 -0
  45. package/dist/postgres/getMigrationTemplate.d.ts.map +1 -0
  46. package/dist/postgres/getMigrationTemplate.js +13 -0
  47. package/dist/postgres/getMigrationTemplate.js.map +1 -0
  48. package/dist/postgres/init.d.ts +3 -0
  49. package/dist/postgres/init.d.ts.map +1 -0
  50. package/dist/postgres/init.js +95 -0
  51. package/dist/postgres/init.js.map +1 -0
  52. package/dist/postgres/insert.d.ts +3 -0
  53. package/dist/postgres/insert.d.ts.map +1 -0
  54. package/dist/postgres/insert.js +12 -0
  55. package/dist/postgres/insert.js.map +1 -0
  56. package/dist/postgres/requireDrizzleKit.d.ts +3 -0
  57. package/dist/postgres/requireDrizzleKit.d.ts.map +1 -0
  58. package/dist/postgres/requireDrizzleKit.js +5 -0
  59. package/dist/postgres/requireDrizzleKit.js.map +1 -0
  60. package/dist/postgres/schema/build.d.ts +40 -0
  61. package/dist/postgres/schema/build.d.ts.map +1 -0
  62. package/dist/postgres/schema/build.js +373 -0
  63. package/dist/postgres/schema/build.js.map +1 -0
  64. package/dist/postgres/schema/createIndex.d.ts +12 -0
  65. package/dist/postgres/schema/createIndex.d.ts.map +1 -0
  66. package/dist/postgres/schema/createIndex.js +18 -0
  67. package/dist/postgres/schema/createIndex.js.map +1 -0
  68. package/dist/postgres/schema/idToUUID.d.ts +3 -0
  69. package/dist/postgres/schema/idToUUID.d.ts.map +1 -0
  70. package/dist/postgres/schema/idToUUID.js +11 -0
  71. package/dist/postgres/schema/idToUUID.js.map +1 -0
  72. package/dist/postgres/schema/parentIDColumnMap.d.ts +4 -0
  73. package/dist/postgres/schema/parentIDColumnMap.d.ts.map +1 -0
  74. package/dist/postgres/schema/parentIDColumnMap.js +9 -0
  75. package/dist/postgres/schema/parentIDColumnMap.js.map +1 -0
  76. package/dist/postgres/schema/setColumnID.d.ts +11 -0
  77. package/dist/postgres/schema/setColumnID.d.ts.map +1 -0
  78. package/dist/postgres/schema/setColumnID.js +24 -0
  79. package/dist/postgres/schema/setColumnID.js.map +1 -0
  80. package/dist/postgres/schema/traverseFields.d.ts +40 -0
  81. package/dist/postgres/schema/traverseFields.d.ts.map +1 -0
  82. package/dist/postgres/schema/traverseFields.js +644 -0
  83. package/dist/postgres/schema/traverseFields.js.map +1 -0
  84. package/dist/postgres/schema/withDefault.d.ts +4 -0
  85. package/dist/postgres/schema/withDefault.d.ts.map +1 -0
  86. package/dist/postgres/schema/withDefault.js +10 -0
  87. package/dist/postgres/schema/withDefault.js.map +1 -0
  88. package/dist/postgres/types.d.ts +112 -0
  89. package/dist/postgres/types.d.ts.map +1 -0
  90. package/dist/postgres/types.js +3 -0
  91. package/dist/postgres/types.js.map +1 -0
  92. package/dist/queries/getTableColumnFromPath.js +1 -1
  93. package/dist/queries/getTableColumnFromPath.js.map +1 -1
  94. package/dist/transform/read/hasManyNumber.d.ts +2 -1
  95. package/dist/transform/read/hasManyNumber.d.ts.map +1 -1
  96. package/dist/transform/read/hasManyNumber.js +12 -2
  97. package/dist/transform/read/hasManyNumber.js.map +1 -1
  98. package/dist/transform/read/hasManyText.d.ts +2 -1
  99. package/dist/transform/read/hasManyText.d.ts.map +1 -1
  100. package/dist/transform/read/hasManyText.js +12 -2
  101. package/dist/transform/read/hasManyText.js.map +1 -1
  102. package/dist/transform/read/relationship.d.ts +2 -1
  103. package/dist/transform/read/relationship.d.ts.map +1 -1
  104. package/dist/transform/read/relationship.js +15 -6
  105. package/dist/transform/read/relationship.js.map +1 -1
  106. package/dist/transform/read/traverseFields.d.ts +5 -1
  107. package/dist/transform/read/traverseFields.d.ts.map +1 -1
  108. package/dist/transform/read/traverseFields.js +45 -27
  109. package/dist/transform/read/traverseFields.js.map +1 -1
  110. package/dist/transform/write/array.d.ts +6 -1
  111. package/dist/transform/write/array.d.ts.map +1 -1
  112. package/dist/transform/write/array.js +7 -3
  113. package/dist/transform/write/array.js.map +1 -1
  114. package/dist/transform/write/blocks.d.ts +6 -1
  115. package/dist/transform/write/blocks.d.ts.map +1 -1
  116. package/dist/transform/write/blocks.js +5 -3
  117. package/dist/transform/write/blocks.js.map +1 -1
  118. package/dist/transform/write/traverseFields.d.ts +6 -1
  119. package/dist/transform/write/traverseFields.d.ts.map +1 -1
  120. package/dist/transform/write/traverseFields.js +26 -12
  121. package/dist/transform/write/traverseFields.js.map +1 -1
  122. package/dist/upsertRow/index.d.ts.map +1 -1
  123. package/dist/upsertRow/index.js +35 -7
  124. package/dist/upsertRow/index.js.map +1 -1
  125. package/package.json +13 -6
@@ -0,0 +1,644 @@
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';
3
+ import { InvalidConfiguration } from 'payload';
4
+ import { fieldAffectsData, optionIsObject } from 'payload/shared';
5
+ import toSnakeCase from 'to-snake-case';
6
+ import { createTableName } from '../../createTableName.js';
7
+ import { hasLocalesTable } from '../../utilities/hasLocalesTable.js';
8
+ import { validateExistingBlockIsIdentical } from '../../utilities/validateExistingBlockIsIdentical.js';
9
+ import { buildTable } from './build.js';
10
+ import { createIndex } from './createIndex.js';
11
+ import { idToUUID } from './idToUUID.js';
12
+ import { parentIDColumnMap } from './parentIDColumnMap.js';
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, withinLocalizedArrayOrBlock })=>{
15
+ const throwValidationError = true;
16
+ let hasLocalizedField = false;
17
+ let hasLocalizedRelationshipField = false;
18
+ let hasManyTextField = false;
19
+ let hasLocalizedManyTextField = false;
20
+ let hasManyNumberField = false;
21
+ let hasLocalizedManyNumberField = false;
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';
26
+ fields.forEach((field)=>{
27
+ if ('name' in field && field.name === 'id') return;
28
+ let columnName;
29
+ let fieldName;
30
+ let targetTable = columns;
31
+ let targetIndexes = indexes;
32
+ if (fieldAffectsData(field)) {
33
+ columnName = `${columnPrefix || ''}${field.name[0] === '_' ? '_' : ''}${toSnakeCase(field.name)}`;
34
+ fieldName = `${fieldPrefix?.replace('.', '_') || ''}${field.name}`;
35
+ // If field is localized,
36
+ // add the column to the locale table instead of main table
37
+ if (adapter.payload.config.localization && (field.localized || forceLocalized) && field.type !== 'array' && field.type !== 'blocks' && ('hasMany' in field && field.hasMany !== true || !('hasMany' in field))) {
38
+ hasLocalizedField = true;
39
+ targetTable = localesColumns;
40
+ targetIndexes = localesIndexes;
41
+ }
42
+ if ((field.unique || field.index) && ![
43
+ 'array',
44
+ 'blocks',
45
+ 'group',
46
+ 'point',
47
+ 'relationship',
48
+ 'upload'
49
+ ].includes(field.type) && !('hasMany' in field && field.hasMany === true)) {
50
+ const unique = disableUnique !== true && field.unique;
51
+ if (unique) {
52
+ const constraintValue = `${fieldPrefix || ''}${field.name}`;
53
+ if (!adapter.fieldConstraints?.[rootTableName]) {
54
+ adapter.fieldConstraints[rootTableName] = {};
55
+ }
56
+ adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue;
57
+ }
58
+ targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
59
+ name: fieldName,
60
+ columnName,
61
+ tableName: newTableName,
62
+ unique
63
+ });
64
+ }
65
+ }
66
+ switch(field.type){
67
+ case 'text':
68
+ {
69
+ if (field.hasMany) {
70
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
71
+ if (isLocalized) {
72
+ hasLocalizedManyTextField = true;
73
+ }
74
+ if (field.index) {
75
+ hasManyTextField = 'index';
76
+ } else if (!hasManyTextField) {
77
+ hasManyTextField = true;
78
+ }
79
+ if (field.unique) {
80
+ throw new InvalidConfiguration('Unique is not supported in Postgres for hasMany text fields.');
81
+ }
82
+ } else {
83
+ targetTable[fieldName] = withDefault(varchar(columnName), field);
84
+ }
85
+ break;
86
+ }
87
+ case 'email':
88
+ case 'code':
89
+ case 'textarea':
90
+ {
91
+ targetTable[fieldName] = withDefault(varchar(columnName), field);
92
+ break;
93
+ }
94
+ case 'number':
95
+ {
96
+ if (field.hasMany) {
97
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
98
+ if (isLocalized) {
99
+ hasLocalizedManyNumberField = true;
100
+ }
101
+ if (field.index) {
102
+ hasManyNumberField = 'index';
103
+ } else if (!hasManyNumberField) {
104
+ hasManyNumberField = true;
105
+ }
106
+ if (field.unique) {
107
+ throw new InvalidConfiguration('Unique is not supported in Postgres for hasMany number fields.');
108
+ }
109
+ } else {
110
+ targetTable[fieldName] = withDefault(numeric(columnName), field);
111
+ }
112
+ break;
113
+ }
114
+ case 'richText':
115
+ case 'json':
116
+ {
117
+ targetTable[fieldName] = withDefault(jsonb(columnName), field);
118
+ break;
119
+ }
120
+ case 'date':
121
+ {
122
+ targetTable[fieldName] = withDefault(timestamp(columnName, {
123
+ mode: 'string',
124
+ precision: 3,
125
+ withTimezone: true
126
+ }), field);
127
+ break;
128
+ }
129
+ case 'point':
130
+ {
131
+ break;
132
+ }
133
+ case 'radio':
134
+ case 'select':
135
+ {
136
+ const enumName = createTableName({
137
+ adapter,
138
+ config: field,
139
+ parentTableName: newTableName,
140
+ prefix: `enum_${newTableName}_`,
141
+ target: 'enumName',
142
+ throwValidationError
143
+ });
144
+ adapter.enums[enumName] = adapter.pgSchema.enum(enumName, field.options.map((option)=>{
145
+ if (optionIsObject(option)) {
146
+ return option.value;
147
+ }
148
+ return option;
149
+ }));
150
+ if (field.type === 'select' && field.hasMany) {
151
+ const selectTableName = createTableName({
152
+ adapter,
153
+ config: field,
154
+ parentTableName: newTableName,
155
+ prefix: `${newTableName}_`,
156
+ throwValidationError,
157
+ versionsCustomName: versions
158
+ });
159
+ const baseColumns = {
160
+ order: integer('order').notNull(),
161
+ parent: parentIDColumnMap[parentIDColType]('parent_id').notNull(),
162
+ value: adapter.enums[enumName]('value')
163
+ };
164
+ const baseExtraConfig = {
165
+ orderIdx: (cols)=>index(`${selectTableName}_order_idx`).on(cols.order),
166
+ parentFk: (cols)=>foreignKey({
167
+ name: `${selectTableName}_parent_fk`,
168
+ columns: [
169
+ cols.parent
170
+ ],
171
+ foreignColumns: [
172
+ adapter.tables[parentTableName].id
173
+ ]
174
+ }).onDelete('cascade'),
175
+ parentIdx: (cols)=>index(`${selectTableName}_parent_idx`).on(cols.parent)
176
+ };
177
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
178
+ if (isLocalized) {
179
+ baseColumns.locale = adapter.enums.enum__locales('locale').notNull();
180
+ baseExtraConfig.localeIdx = (cols)=>index(`${selectTableName}_locale_idx`).on(cols.locale);
181
+ }
182
+ if (field.index) {
183
+ baseExtraConfig.value = (cols)=>index(`${selectTableName}_value_idx`).on(cols.value);
184
+ }
185
+ buildTable({
186
+ adapter,
187
+ baseColumns,
188
+ baseExtraConfig,
189
+ disableNotNull,
190
+ disableUnique,
191
+ fields: [],
192
+ rootTableName,
193
+ tableName: selectTableName,
194
+ versions
195
+ });
196
+ relationsToBuild.set(fieldName, {
197
+ type: 'many',
198
+ // selects have their own localized table, independent of the base table.
199
+ localized: false,
200
+ target: selectTableName
201
+ });
202
+ adapter.relations[`relations_${selectTableName}`] = relations(adapter.tables[selectTableName], ({ one })=>({
203
+ parent: one(adapter.tables[parentTableName], {
204
+ fields: [
205
+ adapter.tables[selectTableName].parent
206
+ ],
207
+ references: [
208
+ adapter.tables[parentTableName].id
209
+ ],
210
+ relationName: fieldName
211
+ })
212
+ }));
213
+ } else {
214
+ targetTable[fieldName] = withDefault(adapter.enums[enumName](fieldName), field);
215
+ }
216
+ break;
217
+ }
218
+ case 'checkbox':
219
+ {
220
+ targetTable[fieldName] = withDefault(boolean(columnName), field);
221
+ break;
222
+ }
223
+ case 'array':
224
+ {
225
+ const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
226
+ const arrayTableName = createTableName({
227
+ adapter,
228
+ config: field,
229
+ parentTableName: newTableName,
230
+ prefix: `${newTableName}_`,
231
+ throwValidationError,
232
+ versionsCustomName: versions
233
+ });
234
+ const baseColumns = {
235
+ _order: integer('_order').notNull(),
236
+ _parentID: parentIDColumnMap[parentIDColType]('_parent_id').notNull()
237
+ };
238
+ const baseExtraConfig = {
239
+ _orderIdx: (cols)=>index(`${arrayTableName}_order_idx`).on(cols._order),
240
+ _parentIDFk: (cols)=>foreignKey({
241
+ name: `${arrayTableName}_parent_id_fk`,
242
+ columns: [
243
+ cols['_parentID']
244
+ ],
245
+ foreignColumns: [
246
+ adapter.tables[parentTableName].id
247
+ ]
248
+ }).onDelete('cascade'),
249
+ _parentIDIdx: (cols)=>index(`${arrayTableName}_parent_id_idx`).on(cols._parentID)
250
+ };
251
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
252
+ if (isLocalized) {
253
+ baseColumns._locale = adapter.enums.enum__locales('_locale').notNull();
254
+ baseExtraConfig._localeIdx = (cols)=>index(`${arrayTableName}_locale_idx`).on(cols._locale);
255
+ }
256
+ const { hasLocalizedManyNumberField: subHasLocalizedManyNumberField, hasLocalizedManyTextField: subHasLocalizedManyTextField, hasLocalizedRelationshipField: subHasLocalizedRelationshipField, hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
257
+ adapter,
258
+ baseColumns,
259
+ baseExtraConfig,
260
+ disableNotNull: disableNotNullFromHere,
261
+ disableUnique,
262
+ fields: disableUnique ? idToUUID(field.fields) : field.fields,
263
+ rootRelationsToBuild,
264
+ rootRelationships: relationships,
265
+ rootTableIDColType,
266
+ rootTableName,
267
+ tableName: arrayTableName,
268
+ versions,
269
+ withinLocalizedArrayOrBlock: isLocalized
270
+ });
271
+ if (subHasLocalizedManyNumberField) {
272
+ hasLocalizedManyNumberField = subHasLocalizedManyNumberField;
273
+ }
274
+ if (subHasLocalizedRelationshipField) {
275
+ hasLocalizedRelationshipField = subHasLocalizedRelationshipField;
276
+ }
277
+ if (subHasLocalizedManyTextField) {
278
+ hasLocalizedManyTextField = subHasLocalizedManyTextField;
279
+ }
280
+ if (subHasManyTextField) {
281
+ if (!hasManyTextField || subHasManyTextField === 'index') hasManyTextField = subHasManyTextField;
282
+ }
283
+ if (subHasManyNumberField) {
284
+ if (!hasManyNumberField || subHasManyNumberField === 'index') hasManyNumberField = subHasManyNumberField;
285
+ }
286
+ relationsToBuild.set(fieldName, {
287
+ type: 'many',
288
+ // arrays have their own localized table, independent of the base table.
289
+ localized: false,
290
+ target: arrayTableName
291
+ });
292
+ adapter.relations[`relations_${arrayTableName}`] = relations(adapter.tables[arrayTableName], ({ many, one })=>{
293
+ const result = {
294
+ _parentID: one(adapter.tables[parentTableName], {
295
+ fields: [
296
+ adapter.tables[arrayTableName]._parentID
297
+ ],
298
+ references: [
299
+ adapter.tables[parentTableName].id
300
+ ],
301
+ relationName: fieldName
302
+ })
303
+ };
304
+ if (hasLocalesTable(field.fields)) {
305
+ result._locales = many(adapter.tables[`${arrayTableName}${adapter.localesSuffix}`], {
306
+ relationName: '_locales'
307
+ });
308
+ }
309
+ subRelationsToBuild.forEach(({ type, localized, target }, key)=>{
310
+ if (type === 'one') {
311
+ const arrayWithLocalized = localized ? `${arrayTableName}${adapter.localesSuffix}` : arrayTableName;
312
+ result[key] = one(adapter.tables[target], {
313
+ fields: [
314
+ adapter.tables[arrayWithLocalized][key]
315
+ ],
316
+ references: [
317
+ adapter.tables[target].id
318
+ ],
319
+ relationName: key
320
+ });
321
+ }
322
+ if (type === 'many') {
323
+ result[key] = many(adapter.tables[target], {
324
+ relationName: key
325
+ });
326
+ }
327
+ });
328
+ return result;
329
+ });
330
+ break;
331
+ }
332
+ case 'blocks':
333
+ {
334
+ const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
335
+ field.blocks.forEach((block)=>{
336
+ const blockTableName = createTableName({
337
+ adapter,
338
+ config: block,
339
+ parentTableName: rootTableName,
340
+ prefix: `${rootTableName}_blocks_`,
341
+ throwValidationError,
342
+ versionsCustomName: versions
343
+ });
344
+ if (!adapter.tables[blockTableName]) {
345
+ const baseColumns = {
346
+ _order: integer('_order').notNull(),
347
+ _parentID: parentIDColumnMap[rootTableIDColType]('_parent_id').notNull(),
348
+ _path: text('_path').notNull()
349
+ };
350
+ const baseExtraConfig = {
351
+ _orderIdx: (cols)=>index(`${blockTableName}_order_idx`).on(cols._order),
352
+ _parentIDIdx: (cols)=>index(`${blockTableName}_parent_id_idx`).on(cols._parentID),
353
+ _parentIdFk: (cols)=>foreignKey({
354
+ name: `${blockTableName}_parent_id_fk`,
355
+ columns: [
356
+ cols._parentID
357
+ ],
358
+ foreignColumns: [
359
+ adapter.tables[rootTableName].id
360
+ ]
361
+ }).onDelete('cascade'),
362
+ _pathIdx: (cols)=>index(`${blockTableName}_path_idx`).on(cols._path)
363
+ };
364
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
365
+ if (isLocalized) {
366
+ baseColumns._locale = adapter.enums.enum__locales('_locale').notNull();
367
+ baseExtraConfig._localeIdx = (cols)=>index(`${blockTableName}_locale_idx`).on(cols._locale);
368
+ }
369
+ const { hasLocalizedManyNumberField: subHasLocalizedManyNumberField, hasLocalizedManyTextField: subHasLocalizedManyTextField, hasLocalizedRelationshipField: subHasLocalizedRelationshipField, hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
370
+ adapter,
371
+ baseColumns,
372
+ baseExtraConfig,
373
+ disableNotNull: disableNotNullFromHere,
374
+ disableUnique,
375
+ fields: disableUnique ? idToUUID(block.fields) : block.fields,
376
+ rootRelationsToBuild,
377
+ rootRelationships: relationships,
378
+ rootTableIDColType,
379
+ rootTableName,
380
+ tableName: blockTableName,
381
+ versions,
382
+ withinLocalizedArrayOrBlock: isLocalized
383
+ });
384
+ if (subHasLocalizedManyNumberField) {
385
+ hasLocalizedManyNumberField = subHasLocalizedManyNumberField;
386
+ }
387
+ if (subHasLocalizedRelationshipField) {
388
+ hasLocalizedRelationshipField = subHasLocalizedRelationshipField;
389
+ }
390
+ if (subHasLocalizedManyTextField) {
391
+ hasLocalizedManyTextField = subHasLocalizedManyTextField;
392
+ }
393
+ if (subHasManyTextField) {
394
+ if (!hasManyTextField || subHasManyTextField === 'index') hasManyTextField = subHasManyTextField;
395
+ }
396
+ if (subHasManyNumberField) {
397
+ if (!hasManyNumberField || subHasManyNumberField === 'index') hasManyNumberField = subHasManyNumberField;
398
+ }
399
+ adapter.relations[`relations_${blockTableName}`] = relations(adapter.tables[blockTableName], ({ many, one })=>{
400
+ const result = {
401
+ _parentID: one(adapter.tables[rootTableName], {
402
+ fields: [
403
+ adapter.tables[blockTableName]._parentID
404
+ ],
405
+ references: [
406
+ adapter.tables[rootTableName].id
407
+ ],
408
+ relationName: `_blocks_${block.slug}`
409
+ })
410
+ };
411
+ if (hasLocalesTable(block.fields)) {
412
+ result._locales = many(adapter.tables[`${blockTableName}${adapter.localesSuffix}`], {
413
+ relationName: '_locales'
414
+ });
415
+ }
416
+ subRelationsToBuild.forEach(({ type, localized, target }, key)=>{
417
+ if (type === 'one') {
418
+ const blockWithLocalized = localized ? `${blockTableName}${adapter.localesSuffix}` : blockTableName;
419
+ result[key] = one(adapter.tables[target], {
420
+ fields: [
421
+ adapter.tables[blockWithLocalized][key]
422
+ ],
423
+ references: [
424
+ adapter.tables[target].id
425
+ ],
426
+ relationName: key
427
+ });
428
+ }
429
+ if (type === 'many') {
430
+ result[key] = many(adapter.tables[target], {
431
+ relationName: key
432
+ });
433
+ }
434
+ });
435
+ return result;
436
+ });
437
+ } else if (process.env.NODE_ENV !== 'production' && !versions) {
438
+ validateExistingBlockIsIdentical({
439
+ block,
440
+ localized: field.localized,
441
+ rootTableName,
442
+ table: adapter.tables[blockTableName],
443
+ tableLocales: adapter.tables[`${blockTableName}${adapter.localesSuffix}`]
444
+ });
445
+ }
446
+ // blocks relationships are defined from the collection or globals table down to the block, bypassing any subBlocks
447
+ rootRelationsToBuild.set(`_blocks_${block.slug}`, {
448
+ type: 'many',
449
+ // blocks are not localized on the parent table
450
+ localized: false,
451
+ target: blockTableName
452
+ });
453
+ });
454
+ break;
455
+ }
456
+ case 'tab':
457
+ case 'group':
458
+ {
459
+ if (!('name' in field)) {
460
+ const { hasLocalizedField: groupHasLocalizedField, hasLocalizedManyNumberField: groupHasLocalizedManyNumberField, hasLocalizedManyTextField: groupHasLocalizedManyTextField, hasLocalizedRelationshipField: groupHasLocalizedRelationshipField, hasManyNumberField: groupHasManyNumberField, hasManyTextField: groupHasManyTextField } = traverseFields({
461
+ adapter,
462
+ columnPrefix,
463
+ columns,
464
+ disableNotNull,
465
+ disableUnique,
466
+ fieldPrefix,
467
+ fields: field.fields,
468
+ forceLocalized,
469
+ indexes,
470
+ localesColumns,
471
+ localesIndexes,
472
+ newTableName,
473
+ parentTableName,
474
+ relationsToBuild,
475
+ relationships,
476
+ rootRelationsToBuild,
477
+ rootTableIDColType,
478
+ rootTableName,
479
+ versions,
480
+ withinLocalizedArrayOrBlock
481
+ });
482
+ if (groupHasLocalizedField) hasLocalizedField = true;
483
+ if (groupHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
484
+ if (groupHasManyTextField) hasManyTextField = true;
485
+ if (groupHasLocalizedManyTextField) hasLocalizedManyTextField = true;
486
+ if (groupHasManyNumberField) hasManyNumberField = true;
487
+ if (groupHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
488
+ break;
489
+ }
490
+ const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
491
+ const { hasLocalizedField: groupHasLocalizedField, hasLocalizedManyNumberField: groupHasLocalizedManyNumberField, hasLocalizedManyTextField: groupHasLocalizedManyTextField, hasLocalizedRelationshipField: groupHasLocalizedRelationshipField, hasManyNumberField: groupHasManyNumberField, hasManyTextField: groupHasManyTextField } = traverseFields({
492
+ adapter,
493
+ columnPrefix: `${columnName}_`,
494
+ columns,
495
+ disableNotNull: disableNotNullFromHere,
496
+ disableUnique,
497
+ fieldPrefix: `${fieldName}.`,
498
+ fields: field.fields,
499
+ forceLocalized: field.localized,
500
+ indexes,
501
+ localesColumns,
502
+ localesIndexes,
503
+ newTableName: `${parentTableName}_${columnName}`,
504
+ parentTableName,
505
+ relationsToBuild,
506
+ relationships,
507
+ rootRelationsToBuild,
508
+ rootTableIDColType,
509
+ rootTableName,
510
+ versions,
511
+ withinLocalizedArrayOrBlock
512
+ });
513
+ if (groupHasLocalizedField) hasLocalizedField = true;
514
+ if (groupHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
515
+ if (groupHasManyTextField) hasManyTextField = true;
516
+ if (groupHasLocalizedManyTextField) hasLocalizedManyTextField = true;
517
+ if (groupHasManyNumberField) hasManyNumberField = true;
518
+ if (groupHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
519
+ break;
520
+ }
521
+ case 'tabs':
522
+ {
523
+ const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
524
+ const { hasLocalizedField: tabHasLocalizedField, hasLocalizedManyNumberField: tabHasLocalizedManyNumberField, hasLocalizedManyTextField: tabHasLocalizedManyTextField, hasLocalizedRelationshipField: tabHasLocalizedRelationshipField, hasManyNumberField: tabHasManyNumberField, hasManyTextField: tabHasManyTextField } = traverseFields({
525
+ adapter,
526
+ columnPrefix,
527
+ columns,
528
+ disableNotNull: disableNotNullFromHere,
529
+ disableUnique,
530
+ fieldPrefix,
531
+ fields: field.tabs.map((tab)=>({
532
+ ...tab,
533
+ type: 'tab'
534
+ })),
535
+ forceLocalized,
536
+ indexes,
537
+ localesColumns,
538
+ localesIndexes,
539
+ newTableName,
540
+ parentTableName,
541
+ relationsToBuild,
542
+ relationships,
543
+ rootRelationsToBuild,
544
+ rootTableIDColType,
545
+ rootTableName,
546
+ versions,
547
+ withinLocalizedArrayOrBlock
548
+ });
549
+ if (tabHasLocalizedField) hasLocalizedField = true;
550
+ if (tabHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
551
+ if (tabHasManyTextField) hasManyTextField = true;
552
+ if (tabHasLocalizedManyTextField) hasLocalizedManyTextField = true;
553
+ if (tabHasManyNumberField) hasManyNumberField = true;
554
+ if (tabHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
555
+ break;
556
+ }
557
+ case 'row':
558
+ case 'collapsible':
559
+ {
560
+ const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
561
+ const { hasLocalizedField: rowHasLocalizedField, hasLocalizedManyNumberField: rowHasLocalizedManyNumberField, hasLocalizedManyTextField: rowHasLocalizedManyTextField, hasLocalizedRelationshipField: rowHasLocalizedRelationshipField, hasManyNumberField: rowHasManyNumberField, hasManyTextField: rowHasManyTextField } = traverseFields({
562
+ adapter,
563
+ columnPrefix,
564
+ columns,
565
+ disableNotNull: disableNotNullFromHere,
566
+ disableUnique,
567
+ fieldPrefix,
568
+ fields: field.fields,
569
+ forceLocalized,
570
+ indexes,
571
+ localesColumns,
572
+ localesIndexes,
573
+ newTableName,
574
+ parentTableName,
575
+ relationsToBuild,
576
+ relationships,
577
+ rootRelationsToBuild,
578
+ rootTableIDColType,
579
+ rootTableName,
580
+ versions,
581
+ withinLocalizedArrayOrBlock
582
+ });
583
+ if (rowHasLocalizedField) hasLocalizedField = true;
584
+ if (rowHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
585
+ if (rowHasManyTextField) hasManyTextField = true;
586
+ if (rowHasLocalizedManyTextField) hasLocalizedManyTextField = true;
587
+ if (rowHasManyNumberField) hasManyNumberField = true;
588
+ if (rowHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
589
+ break;
590
+ }
591
+ case 'relationship':
592
+ case 'upload':
593
+ if (Array.isArray(field.relationTo)) {
594
+ field.relationTo.forEach((relation)=>relationships.add(relation));
595
+ } else if (field.hasMany) {
596
+ relationships.add(field.relationTo);
597
+ } else {
598
+ // simple relationships get a column on the targetTable with a foreign key to the relationTo table
599
+ const relationshipConfig = adapter.payload.collections[field.relationTo].config;
600
+ const tableName = adapter.tableNameMap.get(toSnakeCase(field.relationTo));
601
+ // get the id type of the related collection
602
+ let colType = adapter.idType === 'uuid' ? 'uuid' : 'integer';
603
+ const relatedCollectionCustomID = relationshipConfig.fields.find((field)=>fieldAffectsData(field) && field.name === 'id');
604
+ if (relatedCollectionCustomID?.type === 'number') colType = 'numeric';
605
+ if (relatedCollectionCustomID?.type === 'text') colType = 'varchar';
606
+ // make the foreign key column for relationship using the correct id column type
607
+ targetTable[fieldName] = parentIDColumnMap[colType](`${columnName}_id`).references(()=>adapter.tables[tableName].id, {
608
+ onDelete: 'set null'
609
+ });
610
+ // add relationship to table
611
+ relationsToBuild.set(fieldName, {
612
+ type: 'one',
613
+ localized: adapter.payload.config.localization && field.localized,
614
+ target: tableName
615
+ });
616
+ // add notNull when not required
617
+ if (!disableNotNull && field.required && !field.admin?.condition) {
618
+ targetTable[fieldName].notNull();
619
+ }
620
+ break;
621
+ }
622
+ if (Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock) {
623
+ hasLocalizedRelationshipField = true;
624
+ }
625
+ break;
626
+ default:
627
+ break;
628
+ }
629
+ const condition = field.admin && field.admin.condition;
630
+ if (!disableNotNull && targetTable[fieldName] && 'required' in field && field.required && !condition) {
631
+ targetTable[fieldName].notNull();
632
+ }
633
+ });
634
+ return {
635
+ hasLocalizedField,
636
+ hasLocalizedManyNumberField,
637
+ hasLocalizedManyTextField,
638
+ hasLocalizedRelationshipField,
639
+ hasManyNumberField,
640
+ hasManyTextField
641
+ };
642
+ };
643
+
644
+ //# sourceMappingURL=traverseFields.js.map