@payloadcms/db-sqlite 3.0.0-canary.8789b0b → 3.0.0-canary.893f1e5

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.
@@ -1,4 +1,4 @@
1
- import { createTableName, hasLocalesTable, validateExistingBlockIsIdentical } from '@payloadcms/drizzle';
1
+ import { buildIndexName, createTableName, hasLocalesTable, validateExistingBlockIsIdentical } from '@payloadcms/drizzle';
2
2
  import { relations } from 'drizzle-orm';
3
3
  import { foreignKey, index, integer, numeric, SQLiteIntegerBuilder, SQLiteNumericBuilder, SQLiteTextBuilder, text } from 'drizzle-orm/sqlite-core';
4
4
  import { InvalidConfiguration } from 'payload';
@@ -9,7 +9,7 @@ import { createIndex } from './createIndex.js';
9
9
  import { getIDColumn } from './getIDColumn.js';
10
10
  import { idToUUID } from './idToUUID.js';
11
11
  import { withDefault } from './withDefault.js';
12
- export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull, disableUnique = false, fieldPrefix, fields, forceLocalized, indexes, locales, localesColumns, localesIndexes, newTableName, parentTableName, relationships, relationsToBuild, rootRelationsToBuild, rootTableIDColType, rootTableName, versions, withinLocalizedArrayOrBlock })=>{
12
+ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull, disableRelsTableUnique, disableUnique = false, fieldPrefix, fields, forceLocalized, indexes, locales, localesColumns, localesIndexes, newTableName, parentTableName, relationships, relationsToBuild, rootRelationsToBuild, rootTableIDColType, rootTableName, uniqueRelationships, versions, withinLocalizedArrayOrBlock })=>{
13
13
  let hasLocalizedField = false;
14
14
  let hasLocalizedRelationshipField = false;
15
15
  let hasManyTextField = false;
@@ -47,14 +47,15 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
47
47
  targetTable = localesColumns;
48
48
  targetIndexes = localesIndexes;
49
49
  }
50
- if ((field.unique || field.index) && ![
50
+ if ((field.unique || field.index || [
51
+ 'relationship',
52
+ 'upload'
53
+ ].includes(field.type)) && ![
51
54
  'array',
52
55
  'blocks',
53
56
  'group',
54
- 'point',
55
- 'relationship',
56
- 'upload'
57
- ].includes(field.type) && !('hasMany' in field && field.hasMany === true)) {
57
+ 'point'
58
+ ].includes(field.type) && !('hasMany' in field && field.hasMany === true) && !('relationTo' in field && Array.isArray(field.relationTo))) {
58
59
  const unique = disableUnique !== true && field.unique;
59
60
  if (unique) {
60
61
  const constraintValue = `${fieldPrefix || ''}${field.name}`;
@@ -63,176 +64,21 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
63
64
  }
64
65
  adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue;
65
66
  }
66
- targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
67
+ const indexName = buildIndexName({
68
+ name: `${newTableName}_${columnName}`,
69
+ adapter: adapter
70
+ });
71
+ targetIndexes[indexName] = createIndex({
67
72
  name: field.localized ? [
68
73
  fieldName,
69
74
  '_locale'
70
75
  ] : fieldName,
71
- columnName,
72
- tableName: newTableName,
76
+ indexName,
73
77
  unique
74
78
  });
75
79
  }
76
80
  }
77
81
  switch(field.type){
78
- case 'text':
79
- {
80
- if (field.hasMany) {
81
- const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
82
- if (isLocalized) {
83
- hasLocalizedManyTextField = true;
84
- }
85
- if (field.index) {
86
- hasManyTextField = 'index';
87
- } else if (!hasManyTextField) {
88
- hasManyTextField = true;
89
- }
90
- if (field.unique) {
91
- throw new InvalidConfiguration('Unique is not supported in SQLite for hasMany text fields.');
92
- }
93
- } else {
94
- targetTable[fieldName] = withDefault(text(columnName), field);
95
- }
96
- break;
97
- }
98
- case 'email':
99
- case 'code':
100
- case 'textarea':
101
- {
102
- targetTable[fieldName] = withDefault(text(columnName), field);
103
- break;
104
- }
105
- case 'number':
106
- {
107
- if (field.hasMany) {
108
- const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
109
- if (isLocalized) {
110
- hasLocalizedManyNumberField = true;
111
- }
112
- if (field.index) {
113
- hasManyNumberField = 'index';
114
- } else if (!hasManyNumberField) {
115
- hasManyNumberField = true;
116
- }
117
- if (field.unique) {
118
- throw new InvalidConfiguration('Unique is not supported in Postgres for hasMany number fields.');
119
- }
120
- } else {
121
- targetTable[fieldName] = withDefault(numeric(columnName), field);
122
- }
123
- break;
124
- }
125
- case 'richText':
126
- case 'json':
127
- {
128
- targetTable[fieldName] = withDefault(text(columnName, {
129
- mode: 'json'
130
- }), field);
131
- break;
132
- }
133
- case 'date':
134
- {
135
- targetTable[fieldName] = withDefault(text(columnName), field);
136
- break;
137
- }
138
- case 'point':
139
- {
140
- break;
141
- }
142
- case 'radio':
143
- case 'select':
144
- {
145
- const options = field.options.map((option)=>{
146
- if (optionIsObject(option)) {
147
- return option.value;
148
- }
149
- return option;
150
- });
151
- if (field.type === 'select' && field.hasMany) {
152
- const selectTableName = createTableName({
153
- adapter,
154
- config: field,
155
- parentTableName: newTableName,
156
- prefix: `${newTableName}_`,
157
- versionsCustomName: versions
158
- });
159
- const baseColumns = {
160
- order: integer('order').notNull(),
161
- parent: getIDColumn({
162
- name: 'parent_id',
163
- type: parentIDColType,
164
- notNull: true,
165
- primaryKey: false
166
- }),
167
- value: text('value', {
168
- enum: options
169
- })
170
- };
171
- const baseExtraConfig = {
172
- orderIdx: (cols)=>index(`${selectTableName}_order_idx`).on(cols.order),
173
- parentFk: (cols)=>foreignKey({
174
- name: `${selectTableName}_parent_fk`,
175
- columns: [
176
- cols.parent
177
- ],
178
- foreignColumns: [
179
- adapter.tables[parentTableName].id
180
- ]
181
- }).onDelete('cascade'),
182
- parentIdx: (cols)=>index(`${selectTableName}_parent_idx`).on(cols.parent)
183
- };
184
- const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
185
- if (isLocalized) {
186
- baseColumns.locale = text('locale', {
187
- enum: locales
188
- }).notNull();
189
- baseExtraConfig.localeIdx = (cols)=>index(`${selectTableName}_locale_idx`).on(cols.locale);
190
- }
191
- if (field.index) {
192
- baseExtraConfig.value = (cols)=>index(`${selectTableName}_value_idx`).on(cols.value);
193
- }
194
- buildTable({
195
- adapter,
196
- baseColumns,
197
- baseExtraConfig,
198
- disableNotNull,
199
- disableUnique,
200
- fields: [],
201
- rootTableName,
202
- tableName: selectTableName,
203
- versions
204
- });
205
- relationsToBuild.set(fieldName, {
206
- type: 'many',
207
- // selects have their own localized table, independent of the base table.
208
- localized: false,
209
- target: selectTableName
210
- });
211
- adapter.relations[`relations_${selectTableName}`] = relations(adapter.tables[selectTableName], ({ one })=>({
212
- parent: one(adapter.tables[parentTableName], {
213
- fields: [
214
- adapter.tables[selectTableName].parent
215
- ],
216
- references: [
217
- adapter.tables[parentTableName].id
218
- ],
219
- relationName: fieldName
220
- })
221
- }));
222
- } else {
223
- targetTable[fieldName] = withDefault(text(fieldName, {
224
- enum: options
225
- }), field);
226
- }
227
- break;
228
- }
229
- case 'checkbox':
230
- {
231
- targetTable[fieldName] = withDefault(integer(columnName, {
232
- mode: 'boolean'
233
- }), field);
234
- break;
235
- }
236
82
  case 'array':
237
83
  {
238
84
  const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
@@ -277,12 +123,14 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
277
123
  baseColumns,
278
124
  baseExtraConfig,
279
125
  disableNotNull: disableNotNullFromHere,
126
+ disableRelsTableUnique: true,
280
127
  disableUnique,
281
128
  fields: disableUnique ? idToUUID(field.fields) : field.fields,
282
129
  rootRelationships: relationships,
283
130
  rootRelationsToBuild,
284
131
  rootTableIDColType,
285
132
  rootTableName,
133
+ rootUniqueRelationships: uniqueRelationships,
286
134
  tableName: arrayTableName,
287
135
  versions,
288
136
  withinLocalizedArrayOrBlock: isLocalized
@@ -400,12 +248,14 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
400
248
  baseColumns,
401
249
  baseExtraConfig,
402
250
  disableNotNull: disableNotNullFromHere,
251
+ disableRelsTableUnique: true,
403
252
  disableUnique,
404
253
  fields: disableUnique ? idToUUID(block.fields) : block.fields,
405
254
  rootRelationships: relationships,
406
255
  rootRelationsToBuild,
407
256
  rootTableIDColType,
408
257
  rootTableName,
258
+ rootUniqueRelationships: uniqueRelationships,
409
259
  tableName: blockTableName,
410
260
  versions,
411
261
  withinLocalizedArrayOrBlock: isLocalized
@@ -486,8 +336,75 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
486
336
  });
487
337
  break;
488
338
  }
489
- case 'tab':
339
+ case 'checkbox':
340
+ {
341
+ targetTable[fieldName] = withDefault(integer(columnName, {
342
+ mode: 'boolean'
343
+ }), field);
344
+ break;
345
+ }
346
+ case 'code':
347
+ case 'email':
348
+ case 'textarea':
349
+ {
350
+ targetTable[fieldName] = withDefault(text(columnName), field);
351
+ break;
352
+ }
353
+ case 'collapsible':
354
+ case 'row':
355
+ {
356
+ const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
357
+ const { hasLocalizedField: rowHasLocalizedField, hasLocalizedManyNumberField: rowHasLocalizedManyNumberField, hasLocalizedManyTextField: rowHasLocalizedManyTextField, hasLocalizedRelationshipField: rowHasLocalizedRelationshipField, hasManyNumberField: rowHasManyNumberField, hasManyTextField: rowHasManyTextField } = traverseFields({
358
+ adapter,
359
+ columnPrefix,
360
+ columns,
361
+ disableNotNull: disableNotNullFromHere,
362
+ disableUnique,
363
+ fieldPrefix,
364
+ fields: field.fields,
365
+ forceLocalized,
366
+ indexes,
367
+ locales,
368
+ localesColumns,
369
+ localesIndexes,
370
+ newTableName,
371
+ parentTableName,
372
+ relationships,
373
+ relationsToBuild,
374
+ rootRelationsToBuild,
375
+ rootTableIDColType,
376
+ rootTableName,
377
+ uniqueRelationships,
378
+ versions,
379
+ withinLocalizedArrayOrBlock
380
+ });
381
+ if (rowHasLocalizedField) {
382
+ hasLocalizedField = true;
383
+ }
384
+ if (rowHasLocalizedRelationshipField) {
385
+ hasLocalizedRelationshipField = true;
386
+ }
387
+ if (rowHasManyTextField) {
388
+ hasManyTextField = true;
389
+ }
390
+ if (rowHasLocalizedManyTextField) {
391
+ hasLocalizedManyTextField = true;
392
+ }
393
+ if (rowHasManyNumberField) {
394
+ hasManyNumberField = true;
395
+ }
396
+ if (rowHasLocalizedManyNumberField) {
397
+ hasLocalizedManyNumberField = true;
398
+ }
399
+ break;
400
+ }
401
+ case 'date':
402
+ {
403
+ targetTable[fieldName] = withDefault(text(columnName), field);
404
+ break;
405
+ }
490
406
  case 'group':
407
+ case 'tab':
491
408
  {
492
409
  if (!('name' in field)) {
493
410
  const { hasLocalizedField: groupHasLocalizedField, hasLocalizedManyNumberField: groupHasLocalizedManyNumberField, hasLocalizedManyTextField: groupHasLocalizedManyTextField, hasLocalizedRelationshipField: groupHasLocalizedRelationshipField, hasManyNumberField: groupHasManyNumberField, hasManyTextField: groupHasManyTextField } = traverseFields({
@@ -510,6 +427,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
510
427
  rootRelationsToBuild,
511
428
  rootTableIDColType,
512
429
  rootTableName,
430
+ uniqueRelationships,
513
431
  versions,
514
432
  withinLocalizedArrayOrBlock
515
433
  });
@@ -554,6 +472,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
554
472
  rootRelationsToBuild,
555
473
  rootTableIDColType,
556
474
  rootTableName,
475
+ uniqueRelationships,
557
476
  versions,
558
477
  withinLocalizedArrayOrBlock: withinLocalizedArrayOrBlock || field.localized
559
478
  });
@@ -577,108 +496,139 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
577
496
  }
578
497
  break;
579
498
  }
580
- case 'tabs':
499
+ case 'json':
500
+ case 'richText':
581
501
  {
582
- const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
583
- const { hasLocalizedField: tabHasLocalizedField, hasLocalizedManyNumberField: tabHasLocalizedManyNumberField, hasLocalizedManyTextField: tabHasLocalizedManyTextField, hasLocalizedRelationshipField: tabHasLocalizedRelationshipField, hasManyNumberField: tabHasManyNumberField, hasManyTextField: tabHasManyTextField } = traverseFields({
584
- adapter,
585
- columnPrefix,
586
- columns,
587
- disableNotNull: disableNotNullFromHere,
588
- disableUnique,
589
- fieldPrefix,
590
- fields: field.tabs.map((tab)=>({
591
- ...tab,
592
- type: 'tab'
593
- })),
594
- forceLocalized,
595
- indexes,
596
- locales,
597
- localesColumns,
598
- localesIndexes,
599
- newTableName,
600
- parentTableName,
601
- relationships,
602
- relationsToBuild,
603
- rootRelationsToBuild,
604
- rootTableIDColType,
605
- rootTableName,
606
- versions,
607
- withinLocalizedArrayOrBlock
608
- });
609
- if (tabHasLocalizedField) {
610
- hasLocalizedField = true;
611
- }
612
- if (tabHasLocalizedRelationshipField) {
613
- hasLocalizedRelationshipField = true;
614
- }
615
- if (tabHasManyTextField) {
616
- hasManyTextField = true;
617
- }
618
- if (tabHasLocalizedManyTextField) {
619
- hasLocalizedManyTextField = true;
620
- }
621
- if (tabHasManyNumberField) {
622
- hasManyNumberField = true;
623
- }
624
- if (tabHasLocalizedManyNumberField) {
625
- hasLocalizedManyNumberField = true;
502
+ targetTable[fieldName] = withDefault(text(columnName, {
503
+ mode: 'json'
504
+ }), field);
505
+ break;
506
+ }
507
+ case 'number':
508
+ {
509
+ if (field.hasMany) {
510
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
511
+ if (isLocalized) {
512
+ hasLocalizedManyNumberField = true;
513
+ }
514
+ if (field.index) {
515
+ hasManyNumberField = 'index';
516
+ } else if (!hasManyNumberField) {
517
+ hasManyNumberField = true;
518
+ }
519
+ if (field.unique) {
520
+ throw new InvalidConfiguration('Unique is not supported in Postgres for hasMany number fields.');
521
+ }
522
+ } else {
523
+ targetTable[fieldName] = withDefault(numeric(columnName), field);
626
524
  }
627
525
  break;
628
526
  }
629
- case 'row':
630
- case 'collapsible':
527
+ case 'point':
631
528
  {
632
- const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
633
- const { hasLocalizedField: rowHasLocalizedField, hasLocalizedManyNumberField: rowHasLocalizedManyNumberField, hasLocalizedManyTextField: rowHasLocalizedManyTextField, hasLocalizedRelationshipField: rowHasLocalizedRelationshipField, hasManyNumberField: rowHasManyNumberField, hasManyTextField: rowHasManyTextField } = traverseFields({
634
- adapter,
635
- columnPrefix,
636
- columns,
637
- disableNotNull: disableNotNullFromHere,
638
- disableUnique,
639
- fieldPrefix,
640
- fields: field.fields,
641
- forceLocalized,
642
- indexes,
643
- locales,
644
- localesColumns,
645
- localesIndexes,
646
- newTableName,
647
- parentTableName,
648
- relationships,
649
- relationsToBuild,
650
- rootRelationsToBuild,
651
- rootTableIDColType,
652
- rootTableName,
653
- versions,
654
- withinLocalizedArrayOrBlock
529
+ break;
530
+ }
531
+ case 'radio':
532
+ case 'select':
533
+ {
534
+ const options = field.options.map((option)=>{
535
+ if (optionIsObject(option)) {
536
+ return option.value;
537
+ }
538
+ return option;
655
539
  });
656
- if (rowHasLocalizedField) {
657
- hasLocalizedField = true;
658
- }
659
- if (rowHasLocalizedRelationshipField) {
660
- hasLocalizedRelationshipField = true;
661
- }
662
- if (rowHasManyTextField) {
663
- hasManyTextField = true;
664
- }
665
- if (rowHasLocalizedManyTextField) {
666
- hasLocalizedManyTextField = true;
667
- }
668
- if (rowHasManyNumberField) {
669
- hasManyNumberField = true;
670
- }
671
- if (rowHasLocalizedManyNumberField) {
672
- hasLocalizedManyNumberField = true;
540
+ if (field.type === 'select' && field.hasMany) {
541
+ const selectTableName = createTableName({
542
+ adapter,
543
+ config: field,
544
+ parentTableName: newTableName,
545
+ prefix: `${newTableName}_`,
546
+ versionsCustomName: versions
547
+ });
548
+ const baseColumns = {
549
+ order: integer('order').notNull(),
550
+ parent: getIDColumn({
551
+ name: 'parent_id',
552
+ type: parentIDColType,
553
+ notNull: true,
554
+ primaryKey: false
555
+ }),
556
+ value: text('value', {
557
+ enum: options
558
+ })
559
+ };
560
+ const baseExtraConfig = {
561
+ orderIdx: (cols)=>index(`${selectTableName}_order_idx`).on(cols.order),
562
+ parentFk: (cols)=>foreignKey({
563
+ name: `${selectTableName}_parent_fk`,
564
+ columns: [
565
+ cols.parent
566
+ ],
567
+ foreignColumns: [
568
+ adapter.tables[parentTableName].id
569
+ ]
570
+ }).onDelete('cascade'),
571
+ parentIdx: (cols)=>index(`${selectTableName}_parent_idx`).on(cols.parent)
572
+ };
573
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
574
+ if (isLocalized) {
575
+ baseColumns.locale = text('locale', {
576
+ enum: locales
577
+ }).notNull();
578
+ baseExtraConfig.localeIdx = (cols)=>index(`${selectTableName}_locale_idx`).on(cols.locale);
579
+ }
580
+ if (field.index) {
581
+ baseExtraConfig.value = (cols)=>index(`${selectTableName}_value_idx`).on(cols.value);
582
+ }
583
+ buildTable({
584
+ adapter,
585
+ baseColumns,
586
+ baseExtraConfig,
587
+ disableNotNull,
588
+ disableUnique,
589
+ fields: [],
590
+ rootTableName,
591
+ tableName: selectTableName,
592
+ versions
593
+ });
594
+ relationsToBuild.set(fieldName, {
595
+ type: 'many',
596
+ // selects have their own localized table, independent of the base table.
597
+ localized: false,
598
+ target: selectTableName
599
+ });
600
+ adapter.relations[`relations_${selectTableName}`] = relations(adapter.tables[selectTableName], ({ one })=>({
601
+ parent: one(adapter.tables[parentTableName], {
602
+ fields: [
603
+ adapter.tables[selectTableName].parent
604
+ ],
605
+ references: [
606
+ adapter.tables[parentTableName].id
607
+ ],
608
+ relationName: fieldName
609
+ })
610
+ }));
611
+ } else {
612
+ targetTable[fieldName] = withDefault(text(columnName, {
613
+ enum: options
614
+ }), field);
673
615
  }
674
616
  break;
675
617
  }
676
618
  case 'relationship':
677
619
  case 'upload':
678
620
  if (Array.isArray(field.relationTo)) {
679
- field.relationTo.forEach((relation)=>relationships.add(relation));
621
+ field.relationTo.forEach((relation)=>{
622
+ relationships.add(relation);
623
+ if (field.unique && !disableUnique && !disableRelsTableUnique) {
624
+ uniqueRelationships.add(relation);
625
+ }
626
+ });
680
627
  } else if (field.hasMany) {
681
628
  relationships.add(field.relationTo);
629
+ if (field.unique && !disableUnique && !disableRelsTableUnique) {
630
+ uniqueRelationships.add(field.relationTo);
631
+ }
682
632
  } else {
683
633
  // simple relationships get a column on the targetTable with a foreign key to the relationTo table
684
634
  const relationshipConfig = adapter.payload.collections[field.relationTo].config;
@@ -716,19 +666,74 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
716
666
  hasLocalizedRelationshipField = true;
717
667
  }
718
668
  break;
719
- case 'join':
669
+ case 'tabs':
720
670
  {
721
- // fieldName could be 'posts' or 'group_posts'
722
- // using on as the key for the relation
723
- const localized = adapter.payload.config.localization && field.localized;
724
- const target = `${adapter.tableNameMap.get(toSnakeCase(field.collection))}${localized ? adapter.localesSuffix : ''}`;
725
- relationsToBuild.set(fieldName, {
726
- type: 'many',
727
- // joins are not localized on the parent table
728
- localized: false,
729
- relationName: field.on.replaceAll('.', '_'),
730
- target
671
+ const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
672
+ const { hasLocalizedField: tabHasLocalizedField, hasLocalizedManyNumberField: tabHasLocalizedManyNumberField, hasLocalizedManyTextField: tabHasLocalizedManyTextField, hasLocalizedRelationshipField: tabHasLocalizedRelationshipField, hasManyNumberField: tabHasManyNumberField, hasManyTextField: tabHasManyTextField } = traverseFields({
673
+ adapter,
674
+ columnPrefix,
675
+ columns,
676
+ disableNotNull: disableNotNullFromHere,
677
+ disableUnique,
678
+ fieldPrefix,
679
+ fields: field.tabs.map((tab)=>({
680
+ ...tab,
681
+ type: 'tab'
682
+ })),
683
+ forceLocalized,
684
+ indexes,
685
+ locales,
686
+ localesColumns,
687
+ localesIndexes,
688
+ newTableName,
689
+ parentTableName,
690
+ relationships,
691
+ relationsToBuild,
692
+ rootRelationsToBuild,
693
+ rootTableIDColType,
694
+ rootTableName,
695
+ uniqueRelationships,
696
+ versions,
697
+ withinLocalizedArrayOrBlock
731
698
  });
699
+ if (tabHasLocalizedField) {
700
+ hasLocalizedField = true;
701
+ }
702
+ if (tabHasLocalizedRelationshipField) {
703
+ hasLocalizedRelationshipField = true;
704
+ }
705
+ if (tabHasManyTextField) {
706
+ hasManyTextField = true;
707
+ }
708
+ if (tabHasLocalizedManyTextField) {
709
+ hasLocalizedManyTextField = true;
710
+ }
711
+ if (tabHasManyNumberField) {
712
+ hasManyNumberField = true;
713
+ }
714
+ if (tabHasLocalizedManyNumberField) {
715
+ hasLocalizedManyNumberField = true;
716
+ }
717
+ break;
718
+ }
719
+ case 'text':
720
+ {
721
+ if (field.hasMany) {
722
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
723
+ if (isLocalized) {
724
+ hasLocalizedManyTextField = true;
725
+ }
726
+ if (field.index) {
727
+ hasManyTextField = 'index';
728
+ } else if (!hasManyTextField) {
729
+ hasManyTextField = true;
730
+ }
731
+ if (field.unique) {
732
+ throw new InvalidConfiguration('Unique is not supported in SQLite for hasMany text fields.');
733
+ }
734
+ } else {
735
+ targetTable[fieldName] = withDefault(text(columnName), field);
736
+ }
732
737
  break;
733
738
  }
734
739
  default: