@payloadcms/db-sqlite 3.0.0-canary.e14c80d → 3.0.0-canary.e198dc5

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 +1 @@
1
- {"version":3,"sources":["../../src/schema/createIndex.ts"],"sourcesContent":["import type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core'\n\nimport { index, uniqueIndex } from 'drizzle-orm/sqlite-core'\n\ntype CreateIndexArgs = {\n columnName: string\n name: string | string[]\n tableName: string\n unique?: boolean\n}\n\nexport const createIndex = ({ name, columnName, tableName, unique }: CreateIndexArgs) => {\n return (table: { [x: string]: AnySQLiteColumn }) => {\n let columns\n if (Array.isArray(name)) {\n columns = name\n .map((columnName) => table[columnName])\n // exclude fields were included in compound indexes but do not exist on the table\n .filter((col) => typeof col !== 'undefined')\n } else {\n columns = [table[name]]\n }\n if (unique)\n return uniqueIndex(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))\n return index(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))\n }\n}\n"],"names":["index","uniqueIndex","createIndex","name","columnName","tableName","unique","table","columns","Array","isArray","map","filter","col","on","slice"],"mappings":"AAEA,SAASA,KAAK,EAAEC,WAAW,QAAQ,0BAAyB;AAS5D,OAAO,MAAMC,cAAc,CAAC,EAAEC,IAAI,EAAEC,UAAU,EAAEC,SAAS,EAAEC,MAAM,EAAmB;IAClF,OAAO,CAACC;QACN,IAAIC;QACJ,IAAIC,MAAMC,OAAO,CAACP,OAAO;YACvBK,UAAUL,KACPQ,GAAG,CAAC,CAACP,aAAeG,KAAK,CAACH,WAAW,CACtC,iFAAiF;aAChFQ,MAAM,CAAC,CAACC,MAAQ,OAAOA,QAAQ;QACpC,OAAO;YACLL,UAAU;gBAACD,KAAK,CAACJ,KAAK;aAAC;QACzB;QACA,IAAIG,QACF,OAAOL,YAAY,CAAC,EAAEI,UAAU,CAAC,EAAED,WAAW,IAAI,CAAC,EAAEU,EAAE,CAACN,OAAO,CAAC,EAAE,KAAKA,QAAQO,KAAK,CAAC;QACvF,OAAOf,MAAM,CAAC,EAAEK,UAAU,CAAC,EAAED,WAAW,IAAI,CAAC,EAAEU,EAAE,CAACN,OAAO,CAAC,EAAE,KAAKA,QAAQO,KAAK,CAAC;IACjF;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/schema/createIndex.ts"],"sourcesContent":["import type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core'\n\nimport { index, uniqueIndex } from 'drizzle-orm/sqlite-core'\n\ntype CreateIndexArgs = {\n columnName: string\n name: string | string[]\n tableName: string\n unique?: boolean\n}\n\nexport const createIndex = ({ name, columnName, tableName, unique }: CreateIndexArgs) => {\n return (table: { [x: string]: AnySQLiteColumn }) => {\n let columns\n if (Array.isArray(name)) {\n columns = name\n .map((columnName) => table[columnName])\n // exclude fields were included in compound indexes but do not exist on the table\n .filter((col) => typeof col !== 'undefined')\n } else {\n columns = [table[name]]\n }\n if (unique) {\n return uniqueIndex(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))\n }\n return index(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))\n }\n}\n"],"names":["index","uniqueIndex","createIndex","name","columnName","tableName","unique","table","columns","Array","isArray","map","filter","col","on","slice"],"mappings":"AAEA,SAASA,KAAK,EAAEC,WAAW,QAAQ,0BAAyB;AAS5D,OAAO,MAAMC,cAAc,CAAC,EAAEC,IAAI,EAAEC,UAAU,EAAEC,SAAS,EAAEC,MAAM,EAAmB;IAClF,OAAO,CAACC;QACN,IAAIC;QACJ,IAAIC,MAAMC,OAAO,CAACP,OAAO;YACvBK,UAAUL,KACPQ,GAAG,CAAC,CAACP,aAAeG,KAAK,CAACH,WAAW,CACtC,iFAAiF;aAChFQ,MAAM,CAAC,CAACC,MAAQ,OAAOA,QAAQ;QACpC,OAAO;YACLL,UAAU;gBAACD,KAAK,CAACJ,KAAK;aAAC;QACzB;QACA,IAAIG,QAAQ;YACV,OAAOL,YAAY,CAAC,EAAEI,UAAU,CAAC,EAAED,WAAW,IAAI,CAAC,EAAEU,EAAE,CAACN,OAAO,CAAC,EAAE,KAAKA,QAAQO,KAAK,CAAC;QACvF;QACA,OAAOf,MAAM,CAAC,EAAEK,UAAU,CAAC,EAAED,WAAW,IAAI,CAAC,EAAEU,EAAE,CAACN,OAAO,CAAC,EAAE,KAAKA,QAAQO,KAAK,CAAC;IACjF;AACF,EAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { IndexBuilder, SQLiteColumnBuilder } from 'drizzle-orm/sqlite-core';
2
- import type { Field, TabAsField } from 'payload';
2
+ import type { Field, SanitizedJoins, TabAsField } from 'payload';
3
3
  import type { GenericColumns, IDType, SQLiteAdapter } from '../types.js';
4
4
  import type { RelationMap } from './build.js';
5
5
  type Args = {
@@ -12,17 +12,23 @@ type Args = {
12
12
  fields: (Field | TabAsField)[];
13
13
  forceLocalized?: boolean;
14
14
  indexes: Record<string, (cols: GenericColumns) => IndexBuilder>;
15
+ joins?: SanitizedJoins;
15
16
  locales: [string, ...string[]];
16
17
  localesColumns: Record<string, SQLiteColumnBuilder>;
17
18
  localesIndexes: Record<string, (cols: GenericColumns) => IndexBuilder>;
18
19
  newTableName: string;
19
20
  parentTableName: string;
20
- relationsToBuild: RelationMap;
21
21
  relationships: Set<string>;
22
+ relationsToBuild: RelationMap;
22
23
  rootRelationsToBuild?: RelationMap;
23
24
  rootTableIDColType: IDType;
24
25
  rootTableName: string;
25
26
  versions: boolean;
27
+ /**
28
+ * Tracks whether or not this table is built
29
+ * from the result of a localized array or block field at some point
30
+ */
31
+ withinLocalizedArrayOrBlock?: boolean;
26
32
  };
27
33
  type Result = {
28
34
  hasLocalizedField: boolean;
@@ -32,6 +38,6 @@ type Result = {
32
38
  hasManyNumberField: 'index' | boolean;
33
39
  hasManyTextField: 'index' | boolean;
34
40
  };
35
- export declare const traverseFields: ({ adapter, columnPrefix, columns, disableNotNull, disableUnique, fieldPrefix, fields, forceLocalized, indexes, locales, localesColumns, localesIndexes, newTableName, parentTableName, relationsToBuild, relationships, rootRelationsToBuild, rootTableIDColType, rootTableName, versions, }: Args) => Result;
41
+ export declare const traverseFields: ({ adapter, columnPrefix, columns, disableNotNull, disableUnique, fieldPrefix, fields, forceLocalized, indexes, joins, locales, localesColumns, localesIndexes, newTableName, parentTableName, relationships, relationsToBuild, rootRelationsToBuild, rootTableIDColType, rootTableName, versions, withinLocalizedArrayOrBlock, }: Args) => Result;
36
42
  export {};
37
43
  //# sourceMappingURL=traverseFields.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"traverseFields.d.ts","sourceRoot":"","sources":["../../src/schema/traverseFields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAsBhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,YAAY,CAAA;AAQ9D,KAAK,IAAI,GAAG;IACV,OAAO,EAAE,aAAa,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAC5C,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,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IACnD,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,iSAqBxB,IAAI,KAAG,MA4rBT,CAAA"}
1
+ {"version":3,"file":"traverseFields.d.ts","sourceRoot":"","sources":["../../src/schema/traverseFields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAsBhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,YAAY,CAAA;AAQ9D,KAAK,IAAI,GAAG;IACV,OAAO,EAAE,aAAa,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAC5C,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,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IACnD,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,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,gBAAgB,EAAE,WAAW,CAAA;IAC7B,oBAAoB,CAAC,EAAE,WAAW,CAAA;IAClC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAA;CACtC,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,qUAuBxB,IAAI,KAAG,MAk2BT,CAAA"}
@@ -1,15 +1,15 @@
1
1
  import { createTableName, hasLocalesTable, validateExistingBlockIsIdentical } from '@payloadcms/drizzle';
2
2
  import { relations } from 'drizzle-orm';
3
- import { SQLiteIntegerBuilder, SQLiteNumericBuilder, SQLiteTextBuilder, foreignKey, index, integer, numeric, text } from 'drizzle-orm/sqlite-core';
3
+ import { foreignKey, index, integer, numeric, SQLiteIntegerBuilder, SQLiteNumericBuilder, SQLiteTextBuilder, text } from 'drizzle-orm/sqlite-core';
4
4
  import { InvalidConfiguration } from 'payload';
5
- import { fieldAffectsData, optionIsObject } from 'payload/shared';
5
+ import { fieldAffectsData, fieldIsVirtual, optionIsObject } from 'payload/shared';
6
6
  import toSnakeCase from 'to-snake-case';
7
7
  import { buildTable } from './build.js';
8
8
  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, relationsToBuild, relationships, rootRelationsToBuild, rootTableIDColType, rootTableName, versions })=>{
12
+ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull, disableUnique = false, fieldPrefix, fields, forceLocalized, indexes, joins, locales, localesColumns, localesIndexes, newTableName, parentTableName, relationships, relationsToBuild, rootRelationsToBuild, rootTableIDColType, rootTableName, versions, withinLocalizedArrayOrBlock })=>{
13
13
  let hasLocalizedField = false;
14
14
  let hasLocalizedRelationshipField = false;
15
15
  let hasManyTextField = false;
@@ -17,11 +17,22 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
17
17
  let hasManyNumberField = false;
18
18
  let hasLocalizedManyNumberField = false;
19
19
  let parentIDColType = 'integer';
20
- if (columns.id instanceof SQLiteIntegerBuilder) parentIDColType = 'integer';
21
- if (columns.id instanceof SQLiteNumericBuilder) parentIDColType = 'numeric';
22
- if (columns.id instanceof SQLiteTextBuilder) parentIDColType = 'text';
20
+ if (columns.id instanceof SQLiteIntegerBuilder) {
21
+ parentIDColType = 'integer';
22
+ }
23
+ if (columns.id instanceof SQLiteNumericBuilder) {
24
+ parentIDColType = 'numeric';
25
+ }
26
+ if (columns.id instanceof SQLiteTextBuilder) {
27
+ parentIDColType = 'text';
28
+ }
23
29
  fields.forEach((field)=>{
24
- if ('name' in field && field.name === 'id') return;
30
+ if ('name' in field && field.name === 'id') {
31
+ return;
32
+ }
33
+ if (fieldIsVirtual(field)) {
34
+ return;
35
+ }
25
36
  let columnName;
26
37
  let fieldName;
27
38
  let targetTable = columns;
@@ -53,7 +64,10 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
53
64
  adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue;
54
65
  }
55
66
  targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
56
- name: fieldName,
67
+ name: field.localized ? [
68
+ fieldName,
69
+ '_locale'
70
+ ] : fieldName,
57
71
  columnName,
58
72
  tableName: newTableName,
59
73
  unique
@@ -64,7 +78,8 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
64
78
  case 'text':
65
79
  {
66
80
  if (field.hasMany) {
67
- if (field.localized) {
81
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
82
+ if (isLocalized) {
68
83
  hasLocalizedManyTextField = true;
69
84
  }
70
85
  if (field.index) {
@@ -90,7 +105,8 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
90
105
  case 'number':
91
106
  {
92
107
  if (field.hasMany) {
93
- if (field.localized) {
108
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
109
+ if (isLocalized) {
94
110
  hasLocalizedManyNumberField = true;
95
111
  }
96
112
  if (field.index) {
@@ -165,7 +181,8 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
165
181
  }).onDelete('cascade'),
166
182
  parentIdx: (cols)=>index(`${selectTableName}_parent_idx`).on(cols.parent)
167
183
  };
168
- if (field.localized) {
184
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
185
+ if (isLocalized) {
169
186
  baseColumns.locale = text('locale', {
170
187
  enum: locales
171
188
  }).notNull();
@@ -203,7 +220,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
203
220
  })
204
221
  }));
205
222
  } else {
206
- targetTable[fieldName] = withDefault(text(fieldName, {
223
+ targetTable[fieldName] = withDefault(text(columnName, {
207
224
  enum: options
208
225
  }), field);
209
226
  }
@@ -248,31 +265,46 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
248
265
  }).onDelete('cascade'),
249
266
  _parentIDIdx: (cols)=>index(`${arrayTableName}_parent_id_idx`).on(cols._parentID)
250
267
  };
251
- if (field.localized && adapter.payload.config.localization) {
268
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
269
+ if (isLocalized) {
252
270
  baseColumns._locale = text('_locale', {
253
271
  enum: locales
254
272
  }).notNull();
255
273
  baseExtraConfig._localeIdx = (cols)=>index(`${arrayTableName}_locale_idx`).on(cols._locale);
256
274
  }
257
- const { hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
275
+ const { hasLocalizedManyNumberField: subHasLocalizedManyNumberField, hasLocalizedManyTextField: subHasLocalizedManyTextField, hasLocalizedRelationshipField: subHasLocalizedRelationshipField, hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
258
276
  adapter,
259
277
  baseColumns,
260
278
  baseExtraConfig,
261
279
  disableNotNull: disableNotNullFromHere,
262
280
  disableUnique,
263
281
  fields: disableUnique ? idToUUID(field.fields) : field.fields,
264
- rootRelationsToBuild,
265
282
  rootRelationships: relationships,
283
+ rootRelationsToBuild,
266
284
  rootTableIDColType,
267
285
  rootTableName,
268
286
  tableName: arrayTableName,
269
- versions
287
+ versions,
288
+ withinLocalizedArrayOrBlock: isLocalized
270
289
  });
290
+ if (subHasLocalizedManyNumberField) {
291
+ hasLocalizedManyNumberField = subHasLocalizedManyNumberField;
292
+ }
293
+ if (subHasLocalizedRelationshipField) {
294
+ hasLocalizedRelationshipField = subHasLocalizedRelationshipField;
295
+ }
296
+ if (subHasLocalizedManyTextField) {
297
+ hasLocalizedManyTextField = subHasLocalizedManyTextField;
298
+ }
271
299
  if (subHasManyTextField) {
272
- if (!hasManyTextField || subHasManyTextField === 'index') hasManyTextField = subHasManyTextField;
300
+ if (!hasManyTextField || subHasManyTextField === 'index') {
301
+ hasManyTextField = subHasManyTextField;
302
+ }
273
303
  }
274
304
  if (subHasManyNumberField) {
275
- if (!hasManyNumberField || subHasManyNumberField === 'index') hasManyNumberField = subHasManyNumberField;
305
+ if (!hasManyNumberField || subHasManyNumberField === 'index') {
306
+ hasManyNumberField = subHasManyNumberField;
307
+ }
276
308
  }
277
309
  relationsToBuild.set(fieldName, {
278
310
  type: 'many',
@@ -344,7 +376,6 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
344
376
  };
345
377
  const baseExtraConfig = {
346
378
  _orderIdx: (cols)=>index(`${blockTableName}_order_idx`).on(cols._order),
347
- _parentIDIdx: (cols)=>index(`${blockTableName}_parent_id_idx`).on(cols._parentID),
348
379
  _parentIdFk: (cols)=>foreignKey({
349
380
  name: `${blockTableName}_parent_id_fk`,
350
381
  columns: [
@@ -354,33 +385,49 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
354
385
  adapter.tables[rootTableName].id
355
386
  ]
356
387
  }).onDelete('cascade'),
388
+ _parentIDIdx: (cols)=>index(`${blockTableName}_parent_id_idx`).on(cols._parentID),
357
389
  _pathIdx: (cols)=>index(`${blockTableName}_path_idx`).on(cols._path)
358
390
  };
359
- if (field.localized && adapter.payload.config.localization) {
391
+ const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
392
+ if (isLocalized) {
360
393
  baseColumns._locale = text('_locale', {
361
394
  enum: locales
362
395
  }).notNull();
363
396
  baseExtraConfig._localeIdx = (cols)=>index(`${blockTableName}_locale_idx`).on(cols._locale);
364
397
  }
365
- const { hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
398
+ const { hasLocalizedManyNumberField: subHasLocalizedManyNumberField, hasLocalizedManyTextField: subHasLocalizedManyTextField, hasLocalizedRelationshipField: subHasLocalizedRelationshipField, hasManyNumberField: subHasManyNumberField, hasManyTextField: subHasManyTextField, relationsToBuild: subRelationsToBuild } = buildTable({
366
399
  adapter,
367
400
  baseColumns,
368
401
  baseExtraConfig,
369
402
  disableNotNull: disableNotNullFromHere,
370
403
  disableUnique,
371
404
  fields: disableUnique ? idToUUID(block.fields) : block.fields,
372
- rootRelationsToBuild,
373
405
  rootRelationships: relationships,
406
+ rootRelationsToBuild,
374
407
  rootTableIDColType,
375
408
  rootTableName,
376
409
  tableName: blockTableName,
377
- versions
410
+ versions,
411
+ withinLocalizedArrayOrBlock: isLocalized
378
412
  });
413
+ if (subHasLocalizedManyNumberField) {
414
+ hasLocalizedManyNumberField = subHasLocalizedManyNumberField;
415
+ }
416
+ if (subHasLocalizedRelationshipField) {
417
+ hasLocalizedRelationshipField = subHasLocalizedRelationshipField;
418
+ }
419
+ if (subHasLocalizedManyTextField) {
420
+ hasLocalizedManyTextField = subHasLocalizedManyTextField;
421
+ }
379
422
  if (subHasManyTextField) {
380
- if (!hasManyTextField || subHasManyTextField === 'index') hasManyTextField = subHasManyTextField;
423
+ if (!hasManyTextField || subHasManyTextField === 'index') {
424
+ hasManyTextField = subHasManyTextField;
425
+ }
381
426
  }
382
427
  if (subHasManyNumberField) {
383
- if (!hasManyNumberField || subHasManyNumberField === 'index') hasManyNumberField = subHasManyNumberField;
428
+ if (!hasManyNumberField || subHasManyNumberField === 'index') {
429
+ hasManyNumberField = subHasManyNumberField;
430
+ }
384
431
  }
385
432
  adapter.relations[`relations_${blockTableName}`] = relations(adapter.tables[blockTableName], ({ many, one })=>{
386
433
  const result = {
@@ -453,24 +500,38 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
453
500
  fields: field.fields,
454
501
  forceLocalized,
455
502
  indexes,
503
+ joins,
456
504
  locales,
457
505
  localesColumns,
458
506
  localesIndexes,
459
507
  newTableName,
460
508
  parentTableName,
461
- relationsToBuild,
462
509
  relationships,
510
+ relationsToBuild,
463
511
  rootRelationsToBuild,
464
512
  rootTableIDColType,
465
513
  rootTableName,
466
- versions
514
+ versions,
515
+ withinLocalizedArrayOrBlock
467
516
  });
468
- if (groupHasLocalizedField) hasLocalizedField = true;
469
- if (groupHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
470
- if (groupHasManyTextField) hasManyTextField = true;
471
- if (groupHasLocalizedManyTextField) hasLocalizedManyTextField = true;
472
- if (groupHasManyNumberField) hasManyNumberField = true;
473
- if (groupHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
517
+ if (groupHasLocalizedField) {
518
+ hasLocalizedField = true;
519
+ }
520
+ if (groupHasLocalizedRelationshipField) {
521
+ hasLocalizedRelationshipField = true;
522
+ }
523
+ if (groupHasManyTextField) {
524
+ hasManyTextField = true;
525
+ }
526
+ if (groupHasLocalizedManyTextField) {
527
+ hasLocalizedManyTextField = true;
528
+ }
529
+ if (groupHasManyNumberField) {
530
+ hasManyNumberField = true;
531
+ }
532
+ if (groupHasLocalizedManyNumberField) {
533
+ hasLocalizedManyNumberField = true;
534
+ }
474
535
  break;
475
536
  }
476
537
  const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
@@ -484,24 +545,38 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
484
545
  fields: field.fields,
485
546
  forceLocalized: field.localized,
486
547
  indexes,
548
+ joins,
487
549
  locales,
488
550
  localesColumns,
489
551
  localesIndexes,
490
552
  newTableName: `${parentTableName}_${columnName}`,
491
553
  parentTableName,
492
- relationsToBuild,
493
554
  relationships,
555
+ relationsToBuild,
494
556
  rootRelationsToBuild,
495
557
  rootTableIDColType,
496
558
  rootTableName,
497
- versions
559
+ versions,
560
+ withinLocalizedArrayOrBlock: withinLocalizedArrayOrBlock || field.localized
498
561
  });
499
- if (groupHasLocalizedField) hasLocalizedField = true;
500
- if (groupHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
501
- if (groupHasManyTextField) hasManyTextField = true;
502
- if (groupHasLocalizedManyTextField) hasLocalizedManyTextField = true;
503
- if (groupHasManyNumberField) hasManyNumberField = true;
504
- if (groupHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
562
+ if (groupHasLocalizedField) {
563
+ hasLocalizedField = true;
564
+ }
565
+ if (groupHasLocalizedRelationshipField) {
566
+ hasLocalizedRelationshipField = true;
567
+ }
568
+ if (groupHasManyTextField) {
569
+ hasManyTextField = true;
570
+ }
571
+ if (groupHasLocalizedManyTextField) {
572
+ hasLocalizedManyTextField = true;
573
+ }
574
+ if (groupHasManyNumberField) {
575
+ hasManyNumberField = true;
576
+ }
577
+ if (groupHasLocalizedManyNumberField) {
578
+ hasLocalizedManyNumberField = true;
579
+ }
505
580
  break;
506
581
  }
507
582
  case 'tabs':
@@ -520,24 +595,38 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
520
595
  })),
521
596
  forceLocalized,
522
597
  indexes,
598
+ joins,
523
599
  locales,
524
600
  localesColumns,
525
601
  localesIndexes,
526
602
  newTableName,
527
603
  parentTableName,
528
- relationsToBuild,
529
604
  relationships,
605
+ relationsToBuild,
530
606
  rootRelationsToBuild,
531
607
  rootTableIDColType,
532
608
  rootTableName,
533
- versions
609
+ versions,
610
+ withinLocalizedArrayOrBlock
534
611
  });
535
- if (tabHasLocalizedField) hasLocalizedField = true;
536
- if (tabHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
537
- if (tabHasManyTextField) hasManyTextField = true;
538
- if (tabHasLocalizedManyTextField) hasLocalizedManyTextField = true;
539
- if (tabHasManyNumberField) hasManyNumberField = true;
540
- if (tabHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
612
+ if (tabHasLocalizedField) {
613
+ hasLocalizedField = true;
614
+ }
615
+ if (tabHasLocalizedRelationshipField) {
616
+ hasLocalizedRelationshipField = true;
617
+ }
618
+ if (tabHasManyTextField) {
619
+ hasManyTextField = true;
620
+ }
621
+ if (tabHasLocalizedManyTextField) {
622
+ hasLocalizedManyTextField = true;
623
+ }
624
+ if (tabHasManyNumberField) {
625
+ hasManyNumberField = true;
626
+ }
627
+ if (tabHasLocalizedManyNumberField) {
628
+ hasLocalizedManyNumberField = true;
629
+ }
541
630
  break;
542
631
  }
543
632
  case 'row':
@@ -554,31 +643,45 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
554
643
  fields: field.fields,
555
644
  forceLocalized,
556
645
  indexes,
646
+ joins,
557
647
  locales,
558
648
  localesColumns,
559
649
  localesIndexes,
560
650
  newTableName,
561
651
  parentTableName,
562
- relationsToBuild,
563
652
  relationships,
653
+ relationsToBuild,
564
654
  rootRelationsToBuild,
565
655
  rootTableIDColType,
566
656
  rootTableName,
567
- versions
657
+ versions,
658
+ withinLocalizedArrayOrBlock
568
659
  });
569
- if (rowHasLocalizedField) hasLocalizedField = true;
570
- if (rowHasLocalizedRelationshipField) hasLocalizedRelationshipField = true;
571
- if (rowHasManyTextField) hasManyTextField = true;
572
- if (rowHasLocalizedManyTextField) hasLocalizedManyTextField = true;
573
- if (rowHasManyNumberField) hasManyNumberField = true;
574
- if (rowHasLocalizedManyNumberField) hasLocalizedManyNumberField = true;
660
+ if (rowHasLocalizedField) {
661
+ hasLocalizedField = true;
662
+ }
663
+ if (rowHasLocalizedRelationshipField) {
664
+ hasLocalizedRelationshipField = true;
665
+ }
666
+ if (rowHasManyTextField) {
667
+ hasManyTextField = true;
668
+ }
669
+ if (rowHasLocalizedManyTextField) {
670
+ hasLocalizedManyTextField = true;
671
+ }
672
+ if (rowHasManyNumberField) {
673
+ hasManyNumberField = true;
674
+ }
675
+ if (rowHasLocalizedManyNumberField) {
676
+ hasLocalizedManyNumberField = true;
677
+ }
575
678
  break;
576
679
  }
577
680
  case 'relationship':
578
681
  case 'upload':
579
682
  if (Array.isArray(field.relationTo)) {
580
683
  field.relationTo.forEach((relation)=>relationships.add(relation));
581
- } else if (field.type === 'relationship' && field.hasMany) {
684
+ } else if (field.hasMany) {
582
685
  relationships.add(field.relationTo);
583
686
  } else {
584
687
  // simple relationships get a column on the targetTable with a foreign key to the relationTo table
@@ -587,8 +690,12 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
587
690
  // get the id type of the related collection
588
691
  let colType = 'integer';
589
692
  const relatedCollectionCustomID = relationshipConfig.fields.find((field)=>fieldAffectsData(field) && field.name === 'id');
590
- if (relatedCollectionCustomID?.type === 'number') colType = 'numeric';
591
- if (relatedCollectionCustomID?.type === 'text') colType = 'text';
693
+ if (relatedCollectionCustomID?.type === 'number') {
694
+ colType = 'numeric';
695
+ }
696
+ if (relatedCollectionCustomID?.type === 'text') {
697
+ colType = 'text';
698
+ }
592
699
  // make the foreign key column for relationship using the correct id column type
593
700
  targetTable[fieldName] = getIDColumn({
594
701
  name: `${columnName}_id`,
@@ -600,7 +707,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
600
707
  // add relationship to table
601
708
  relationsToBuild.set(fieldName, {
602
709
  type: 'one',
603
- localized: adapter.payload.config.localization && field.localized,
710
+ localized: adapter.payload.config.localization && (field.localized || forceLocalized),
604
711
  target: tableName
605
712
  });
606
713
  // add notNull when not required
@@ -609,10 +716,32 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
609
716
  }
610
717
  break;
611
718
  }
612
- if (adapter.payload.config.localization && field.localized) {
719
+ if (Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock) {
613
720
  hasLocalizedRelationshipField = true;
614
721
  }
615
722
  break;
723
+ case 'join':
724
+ {
725
+ // fieldName could be 'posts' or 'group_posts'
726
+ // using `on` as the key for the relation
727
+ const localized = adapter.payload.config.localization && field.localized;
728
+ const fieldSchemaPath = `${fieldPrefix || ''}${field.name}`;
729
+ let target;
730
+ const joinConfig = joins[field.collection].find(({ schemaPath })=>fieldSchemaPath === schemaPath);
731
+ if (joinConfig.targetField.hasMany) {
732
+ target = `${adapter.tableNameMap.get(toSnakeCase(field.collection))}${adapter.relationshipsSuffix}`;
733
+ } else {
734
+ target = `${adapter.tableNameMap.get(toSnakeCase(field.collection))}${localized ? adapter.localesSuffix : ''}`;
735
+ }
736
+ relationsToBuild.set(fieldName, {
737
+ type: 'many',
738
+ // joins are not localized on the parent table
739
+ localized: false,
740
+ relationName: field.on.replaceAll('.', '_'),
741
+ target
742
+ });
743
+ break;
744
+ }
616
745
  default:
617
746
  break;
618
747
  }