@payloadcms/drizzle 3.0.0-beta.84 → 3.0.0-beta.85

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