nextjs-cms 0.9.40 → 0.9.41
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.
- package/dist/cli/lib/update-sections.d.ts.map +1 -1
- package/dist/cli/lib/update-sections.js +24 -2
- package/dist/cli/utils/add-table-keys.d.ts.map +1 -1
- package/dist/cli/utils/add-table-keys.js +42 -6
- package/dist/cli/utils/schema-generator.d.ts +41 -0
- package/dist/cli/utils/schema-generator.d.ts.map +1 -1
- package/dist/cli/utils/schema-generator.js +41 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-sections.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/update-sections.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-sections.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/update-sections.ts"],"names":[],"mappings":"AA4oFA,wBAAsB,cAAc,CAAC,SAAS,UAAQ,iBAoBrD"}
|
|
@@ -11,7 +11,7 @@ import { is } from '../../core/helpers/index.js';
|
|
|
11
11
|
import { db } from '../../db/client.js';
|
|
12
12
|
import { NextJsCmsTablesTable } from '../../db/schema.js';
|
|
13
13
|
import { addTableKeys } from '../utils/add-table-keys.js';
|
|
14
|
-
import { generateDrizzleSchema, generateLocalesTableSchema, resolveCaseStyleFns } from '../utils/schema-generator.js';
|
|
14
|
+
import { generateDrizzleSchema, generateLocalesTableSchema, getLocalizedLocalesConstraints, resolveCaseStyleFns, } from '../utils/schema-generator.js';
|
|
15
15
|
/**
|
|
16
16
|
* Returns all DB column names a field owns.
|
|
17
17
|
* Most fields own a single column (field.name), but rarely some fields own two,
|
|
@@ -1535,6 +1535,23 @@ const main = async (spinnerObject) => {
|
|
|
1535
1535
|
order: 0,
|
|
1536
1536
|
});
|
|
1537
1537
|
const localizedFieldInstances = s.fields.filter((f) => f.localized);
|
|
1538
|
+
/**
|
|
1539
|
+
* Propagate the section's own `unique` / `index` / `fulltext` constraints to the
|
|
1540
|
+
* `_locales` table, but only those whose columns are all localized (mirrors
|
|
1541
|
+
* `LocaleSubmit.checkUniqueConstraint`). Unique constraints get `locale` appended so
|
|
1542
|
+
* uniqueness is enforced per locale; indexes/fulltext keep their columns unchanged.
|
|
1543
|
+
*/
|
|
1544
|
+
const localizedFieldNames = new Set(localizedFieldInstances.map((f) => f.name));
|
|
1545
|
+
const localizedConstraints = getLocalizedLocalesConstraints({
|
|
1546
|
+
localesTableName,
|
|
1547
|
+
localizedFieldNames,
|
|
1548
|
+
unique: s.db.unique,
|
|
1549
|
+
index: s.db.index,
|
|
1550
|
+
fulltext: s.db.fulltext,
|
|
1551
|
+
});
|
|
1552
|
+
const localizedUniqueColumns = localizedConstraints.unique;
|
|
1553
|
+
const localizedIndexColumns = localizedConstraints.index;
|
|
1554
|
+
const localizedFulltextColumns = localizedConstraints.fulltext;
|
|
1538
1555
|
desiredTables.push({
|
|
1539
1556
|
name: localesTableName,
|
|
1540
1557
|
fields: [
|
|
@@ -1547,7 +1564,9 @@ const main = async (spinnerObject) => {
|
|
|
1547
1564
|
sectionType: 'locales',
|
|
1548
1565
|
identifier: idFieldConfig,
|
|
1549
1566
|
primaryKey: [idFieldConfig],
|
|
1550
|
-
unique: [{ columns: [parentIdFieldConfig, localeFieldConfig] }],
|
|
1567
|
+
unique: [{ columns: [parentIdFieldConfig, localeFieldConfig] }, ...localizedUniqueColumns],
|
|
1568
|
+
index: localizedIndexColumns.length > 0 ? localizedIndexColumns : undefined,
|
|
1569
|
+
fulltext: localizedFulltextColumns.length > 0 ? localizedFulltextColumns : undefined,
|
|
1551
1570
|
});
|
|
1552
1571
|
const localizedFieldConfigs = s.fieldConfigs.filter((f) => 'localized' in f && f.localized === true);
|
|
1553
1572
|
const localesSchema = generateLocalesTableSchema({
|
|
@@ -1555,6 +1574,9 @@ const main = async (spinnerObject) => {
|
|
|
1555
1574
|
parentIdentifier: s.db.identifier,
|
|
1556
1575
|
localizedFields: localizedFieldConfigs,
|
|
1557
1576
|
caseStyleFns,
|
|
1577
|
+
localizedUnique: localizedConstraints.unique,
|
|
1578
|
+
localizedIndex: localizedConstraints.index,
|
|
1579
|
+
localizedFulltext: localizedConstraints.fulltext,
|
|
1558
1580
|
});
|
|
1559
1581
|
drizzleTableSchemas.push(localesSchema.schema);
|
|
1560
1582
|
localesSchema.drizzleImports.forEach((type) => drizzleImports.add(type));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-table-keys.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/add-table-keys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"add-table-keys.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/add-table-keys.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAE7D,wBAAsB,YAAY,CAC9B,KAAK,EAAE;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,CAAA;KAAE,EAAE,CAAA;IACnD,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,CAAA;KAAE,EAAE,CAAA;IACpD,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,CAAA;KAAE,EAAE,CAAA;CACzD,EACD,YAAY,CAAC,EAAE;IACX,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;IACjD,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;IAChD,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;CACtD,mBA6SJ"}
|
|
@@ -88,7 +88,13 @@ export async function addTableKeys(table, existingKeys) {
|
|
|
88
88
|
*/
|
|
89
89
|
if (!matchingUnique) {
|
|
90
90
|
console.log(chalk.gray(` - Adding unique key with columns [${requestedUnique.columns.map((col) => col.name).join(', ')}] to '${table.name}'`));
|
|
91
|
-
|
|
91
|
+
try {
|
|
92
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD UNIQUE ${requestedUnique.name ?? ''}(${uniqueColumns})`);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
sqlErrors++;
|
|
96
|
+
console.error(chalk.red(` - Error adding unique key [${requestedUnique.columns.map((col) => col.name).join(', ')}] to '${table.name}':`, error));
|
|
97
|
+
}
|
|
92
98
|
}
|
|
93
99
|
}
|
|
94
100
|
/**
|
|
@@ -100,7 +106,13 @@ export async function addTableKeys(table, existingKeys) {
|
|
|
100
106
|
unique.columns.every((col) => existingUnique.columns.includes(col.name)));
|
|
101
107
|
})) {
|
|
102
108
|
console.log(chalk.gray(` - Dropping unique key with columns [${existingUnique.columns.join(', ')}] from '${table.name}'`));
|
|
103
|
-
|
|
109
|
+
try {
|
|
110
|
+
await db.execute(`ALTER TABLE \`${table.name}\` DROP INDEX \`${existingUnique.name}\``);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
sqlErrors++;
|
|
114
|
+
console.error(chalk.red(` - Error dropping unique key '${existingUnique.name}' from '${table.name}':`, error));
|
|
115
|
+
}
|
|
104
116
|
}
|
|
105
117
|
}
|
|
106
118
|
}
|
|
@@ -118,7 +130,13 @@ export async function addTableKeys(table, existingKeys) {
|
|
|
118
130
|
if (!matchingIndex) {
|
|
119
131
|
// Add index
|
|
120
132
|
console.log(chalk.gray(` - Adding index with columns [${index.columns.map((col) => col.name).join(', ')}] to '${table.name}'`));
|
|
121
|
-
|
|
133
|
+
try {
|
|
134
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD INDEX ${index.name ?? ''}(${indexColumns})`);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
sqlErrors++;
|
|
138
|
+
console.error(chalk.red(` - Error adding index [${index.columns.map((col) => col.name).join(', ')}] to '${table.name}':`, error));
|
|
139
|
+
}
|
|
122
140
|
}
|
|
123
141
|
}
|
|
124
142
|
/**
|
|
@@ -130,7 +148,13 @@ export async function addTableKeys(table, existingKeys) {
|
|
|
130
148
|
index.columns.every((col) => existingIndex.columns.includes(col.name)));
|
|
131
149
|
})) {
|
|
132
150
|
console.log(chalk.gray(` - Dropping index with columns [${existingIndex.columns.join(', ')}] from '${table.name}'`));
|
|
133
|
-
|
|
151
|
+
try {
|
|
152
|
+
await db.execute(`ALTER TABLE \`${table.name}\` DROP INDEX \`${existingIndex.name}\``);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
sqlErrors++;
|
|
156
|
+
console.error(chalk.red(` - Error dropping index '${existingIndex.name}' from '${table.name}':`, error));
|
|
157
|
+
}
|
|
134
158
|
}
|
|
135
159
|
}
|
|
136
160
|
}
|
|
@@ -151,7 +175,13 @@ export async function addTableKeys(table, existingKeys) {
|
|
|
151
175
|
if (!matchingFulltext) {
|
|
152
176
|
// Add fulltext index
|
|
153
177
|
console.log(chalk.gray(` - Adding fulltext index with columns [${requestedFullTextIndex.columns.map((col) => col.name).join(', ')}] to '${table.name}'`));
|
|
154
|
-
|
|
178
|
+
try {
|
|
179
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD FULLTEXT ${requestedFullTextIndex.name ?? ''}(${fulltextColumns})`);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
sqlErrors++;
|
|
183
|
+
console.error(chalk.red(` - Error adding fulltext index [${requestedFullTextIndex.columns.map((col) => col.name).join(', ')}] to '${table.name}':`, error));
|
|
184
|
+
}
|
|
155
185
|
}
|
|
156
186
|
}
|
|
157
187
|
/**
|
|
@@ -163,7 +193,13 @@ export async function addTableKeys(table, existingKeys) {
|
|
|
163
193
|
fulltext.columns.every((col) => existingFulltext.columns.includes(col.name)));
|
|
164
194
|
})) {
|
|
165
195
|
console.log(chalk.gray(` - Dropping fulltext index with columns [${existingFulltext.columns.join(', ')}] from '${table.name}'`));
|
|
166
|
-
|
|
196
|
+
try {
|
|
197
|
+
await db.execute(`ALTER TABLE \`${table.name}\` DROP INDEX \`${existingFulltext.name}\``);
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
sqlErrors++;
|
|
201
|
+
console.error(chalk.red(` - Error dropping fulltext index '${existingFulltext.name}' from '${table.name}':`, error));
|
|
202
|
+
}
|
|
167
203
|
}
|
|
168
204
|
}
|
|
169
205
|
}
|
|
@@ -41,6 +41,42 @@ export declare function generateDrizzleSchema(table: {
|
|
|
41
41
|
schema: string;
|
|
42
42
|
drizzleImports: string[];
|
|
43
43
|
};
|
|
44
|
+
/** A constraint definition referencing columns by name (index / unique / fulltext). */
|
|
45
|
+
export type ConstraintDefinition = {
|
|
46
|
+
columns: {
|
|
47
|
+
name: string;
|
|
48
|
+
}[];
|
|
49
|
+
name?: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Computes the `unique` / `index` / `fulltext` constraints a section's `_locales`
|
|
53
|
+
* table should carry, derived from the section's own constraints.
|
|
54
|
+
*
|
|
55
|
+
* Only constraints whose columns are ALL localized fields apply — a constraint that
|
|
56
|
+
* touches a non-localized column belongs to the base table (that column does not
|
|
57
|
+
* exist in the `_locales` table). This mirrors `LocaleSubmit.checkUniqueConstraint`,
|
|
58
|
+
* which only enforces constraints whose columns are all localized.
|
|
59
|
+
*
|
|
60
|
+
* Translation rules:
|
|
61
|
+
* - unique → append `locale` so uniqueness is scoped per locale (matches the
|
|
62
|
+
* app-level check that adds `locale = <current locale>`).
|
|
63
|
+
* - index → columns unchanged.
|
|
64
|
+
* - fulltext → columns unchanged.
|
|
65
|
+
*
|
|
66
|
+
* Names are always `_locales`-scoped so they don't collide with the base table's
|
|
67
|
+
* constraint names in the generated schema.
|
|
68
|
+
*/
|
|
69
|
+
export declare function getLocalizedLocalesConstraints(params: {
|
|
70
|
+
localesTableName: string;
|
|
71
|
+
localizedFieldNames: Set<string>;
|
|
72
|
+
unique?: ConstraintDefinition[];
|
|
73
|
+
index?: ConstraintDefinition[];
|
|
74
|
+
fulltext?: ConstraintDefinition[];
|
|
75
|
+
}): {
|
|
76
|
+
unique: ConstraintDefinition[];
|
|
77
|
+
index: ConstraintDefinition[];
|
|
78
|
+
fulltext: ConstraintDefinition[];
|
|
79
|
+
};
|
|
44
80
|
/**
|
|
45
81
|
* Generates a Drizzle schema for a `_locales` table that stores per-locale
|
|
46
82
|
* translations of fields marked `localized: true`.
|
|
@@ -51,12 +87,17 @@ export declare function generateDrizzleSchema(table: {
|
|
|
51
87
|
* - `locale` – locale code (e.g. "en", "ar")
|
|
52
88
|
* - one column per localized field
|
|
53
89
|
* - a unique constraint on `(parent_id, locale)`
|
|
90
|
+
* - any localized `unique` / `index` / `fulltext` constraints derived from the
|
|
91
|
+
* section (see `getLocalizedLocalesConstraints`)
|
|
54
92
|
*/
|
|
55
93
|
export declare function generateLocalesTableSchema(params: {
|
|
56
94
|
parentTableName: string;
|
|
57
95
|
parentIdentifier: FieldConfig;
|
|
58
96
|
localizedFields: FieldConfig[];
|
|
59
97
|
caseStyleFns: CaseStyleFns;
|
|
98
|
+
localizedUnique?: ConstraintDefinition[];
|
|
99
|
+
localizedIndex?: ConstraintDefinition[];
|
|
100
|
+
localizedFulltext?: ConstraintDefinition[];
|
|
60
101
|
}): {
|
|
61
102
|
schema: string;
|
|
62
103
|
drizzleImports: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-generator.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/schema-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAoB7D,MAAM,WAAW,YAAY;IACzB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACzC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CAC7C;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;IAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;CACpD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CA8BtE;AAED,wBAAgB,qBAAqB,CACjC,KAAK,EAAE;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,UAAU,CAAC,EAAE,WAAW,CAAA;IACxB,mBAAmB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxC,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxD,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzD,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC9D,EACD,YAAY,EAAE,YAAY,GAC3B;IACC,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;CAC3B,CAgNA;AAED
|
|
1
|
+
{"version":3,"file":"schema-generator.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/schema-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAoB7D,MAAM,WAAW,YAAY;IACzB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACzC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CAC7C;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;IAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;CACpD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CA8BtE;AAED,wBAAgB,qBAAqB,CACjC,KAAK,EAAE;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,UAAU,CAAC,EAAE,WAAW,CAAA;IACxB,mBAAmB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxC,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxD,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzD,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC9D,EACD,YAAY,EAAE,YAAY,GAC3B;IACC,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;CAC3B,CAgNA;AAED,uFAAuF;AACvF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACnD,gBAAgB,EAAE,MAAM,CAAA;IACxB,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAA;IAC/B,KAAK,CAAC,EAAE,oBAAoB,EAAE,CAAA;IAC9B,QAAQ,CAAC,EAAE,oBAAoB,EAAE,CAAA;CACpC,GAAG;IACA,MAAM,EAAE,oBAAoB,EAAE,CAAA;IAC9B,KAAK,EAAE,oBAAoB,EAAE,CAAA;IAC7B,QAAQ,EAAE,oBAAoB,EAAE,CAAA;CACnC,CAwBA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IAC/C,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,WAAW,CAAA;IAC7B,eAAe,EAAE,WAAW,EAAE,CAAA;IAC9B,YAAY,EAAE,YAAY,CAAA;IAC1B,eAAe,CAAC,EAAE,oBAAoB,EAAE,CAAA;IACxC,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAA;IACvC,iBAAiB,CAAC,EAAE,oBAAoB,EAAE,CAAA;CAC7C,GAAG;IACA,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;CAC3B,CAiDA"}
|
|
@@ -239,6 +239,42 @@ export function generateDrizzleSchema(table, caseStyleFns) {
|
|
|
239
239
|
drizzleImports,
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* Computes the `unique` / `index` / `fulltext` constraints a section's `_locales`
|
|
244
|
+
* table should carry, derived from the section's own constraints.
|
|
245
|
+
*
|
|
246
|
+
* Only constraints whose columns are ALL localized fields apply — a constraint that
|
|
247
|
+
* touches a non-localized column belongs to the base table (that column does not
|
|
248
|
+
* exist in the `_locales` table). This mirrors `LocaleSubmit.checkUniqueConstraint`,
|
|
249
|
+
* which only enforces constraints whose columns are all localized.
|
|
250
|
+
*
|
|
251
|
+
* Translation rules:
|
|
252
|
+
* - unique → append `locale` so uniqueness is scoped per locale (matches the
|
|
253
|
+
* app-level check that adds `locale = <current locale>`).
|
|
254
|
+
* - index → columns unchanged.
|
|
255
|
+
* - fulltext → columns unchanged.
|
|
256
|
+
*
|
|
257
|
+
* Names are always `_locales`-scoped so they don't collide with the base table's
|
|
258
|
+
* constraint names in the generated schema.
|
|
259
|
+
*/
|
|
260
|
+
export function getLocalizedLocalesConstraints(params) {
|
|
261
|
+
const { localesTableName, localizedFieldNames } = params;
|
|
262
|
+
const allLocalized = (constraint) => constraint.columns.every((column) => localizedFieldNames.has(column.name));
|
|
263
|
+
const columnSlug = (constraint) => constraint.columns.map((column) => column.name).join('_');
|
|
264
|
+
const unique = (params.unique ?? []).filter(allLocalized).map((constraint) => ({
|
|
265
|
+
columns: [...constraint.columns, { name: 'locale' }],
|
|
266
|
+
name: `${localesTableName}_${columnSlug(constraint)}_locale_unique`,
|
|
267
|
+
}));
|
|
268
|
+
const index = (params.index ?? []).filter(allLocalized).map((constraint) => ({
|
|
269
|
+
columns: constraint.columns,
|
|
270
|
+
name: `${localesTableName}_${columnSlug(constraint)}_index`,
|
|
271
|
+
}));
|
|
272
|
+
const fulltext = (params.fulltext ?? []).filter(allLocalized).map((constraint) => ({
|
|
273
|
+
columns: constraint.columns,
|
|
274
|
+
name: `${localesTableName}_${columnSlug(constraint)}_fulltext`,
|
|
275
|
+
}));
|
|
276
|
+
return { unique, index, fulltext };
|
|
277
|
+
}
|
|
242
278
|
/**
|
|
243
279
|
* Generates a Drizzle schema for a `_locales` table that stores per-locale
|
|
244
280
|
* translations of fields marked `localized: true`.
|
|
@@ -249,6 +285,8 @@ export function generateDrizzleSchema(table, caseStyleFns) {
|
|
|
249
285
|
* - `locale` – locale code (e.g. "en", "ar")
|
|
250
286
|
* - one column per localized field
|
|
251
287
|
* - a unique constraint on `(parent_id, locale)`
|
|
288
|
+
* - any localized `unique` / `index` / `fulltext` constraints derived from the
|
|
289
|
+
* section (see `getLocalizedLocalesConstraints`)
|
|
252
290
|
*/
|
|
253
291
|
export function generateLocalesTableSchema(params) {
|
|
254
292
|
const tableName = `${params.parentTableName}_locales`;
|
|
@@ -286,6 +324,8 @@ export function generateLocalesTableSchema(params) {
|
|
|
286
324
|
name: tableName,
|
|
287
325
|
fields: allFields,
|
|
288
326
|
identifier: idField,
|
|
289
|
-
unique: [{ columns: [{ name: 'parent_id' }, { name: 'locale' }] }],
|
|
327
|
+
unique: [{ columns: [{ name: 'parent_id' }, { name: 'locale' }] }, ...(params.localizedUnique ?? [])],
|
|
328
|
+
index: params.localizedIndex,
|
|
329
|
+
fulltext: params.localizedFulltext,
|
|
290
330
|
}, params.caseStyleFns);
|
|
291
331
|
}
|