@strapi/database 4.25.18 → 4.25.20
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/dialects/dialect.d.ts +2 -0
- package/dist/dialects/dialect.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +97 -26
- package/dist/index.mjs.map +1 -1
- package/dist/lifecycles/index.d.ts +2 -0
- package/dist/lifecycles/index.d.ts.map +1 -1
- package/dist/repairs/index.d.ts +6 -0
- package/dist/repairs/index.d.ts.map +1 -0
- package/dist/repairs/operations/remove-orphan-morph-types.d.ts +18 -0
- package/dist/repairs/operations/remove-orphan-morph-types.d.ts.map +1 -0
- package/dist/schema/index.d.ts +3 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/utils/async-curry.d.ts +9 -0
- package/dist/utils/async-curry.d.ts.map +1 -0
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -28,6 +28,9 @@ class Dialect {
|
|
|
28
28
|
}
|
|
29
29
|
initialize() {
|
|
30
30
|
}
|
|
31
|
+
getTables() {
|
|
32
|
+
throw new Error("getTables not implemented for this dialect");
|
|
33
|
+
}
|
|
31
34
|
getSqlType(type) {
|
|
32
35
|
return type;
|
|
33
36
|
}
|
|
@@ -983,7 +986,7 @@ const getDialect = (db) => {
|
|
|
983
986
|
const dialect = new constructor(db, dialectName);
|
|
984
987
|
return dialect;
|
|
985
988
|
};
|
|
986
|
-
const debug$
|
|
989
|
+
const debug$2 = createDebug("strapi::database");
|
|
987
990
|
const createSchemaBuilder = (db) => {
|
|
988
991
|
const helpers2 = createHelpers(db);
|
|
989
992
|
return {
|
|
@@ -1009,12 +1012,12 @@ const createSchemaBuilder = (db) => {
|
|
|
1009
1012
|
*/
|
|
1010
1013
|
async createTables(tables, trx) {
|
|
1011
1014
|
for (const table of tables) {
|
|
1012
|
-
debug$
|
|
1015
|
+
debug$2(`Creating table: ${table.name}`);
|
|
1013
1016
|
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
1014
1017
|
await helpers2.createTable(schemaBuilder, table);
|
|
1015
1018
|
}
|
|
1016
1019
|
for (const table of tables) {
|
|
1017
|
-
debug$
|
|
1020
|
+
debug$2(`Creating table foreign keys: ${table.name}`);
|
|
1018
1021
|
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
1019
1022
|
await helpers2.createTableForeignKeys(schemaBuilder, table);
|
|
1020
1023
|
}
|
|
@@ -1045,18 +1048,18 @@ const createSchemaBuilder = (db) => {
|
|
|
1045
1048
|
await this.createTables(schemaDiff.tables.added, trx);
|
|
1046
1049
|
if (forceMigration) {
|
|
1047
1050
|
for (const table of schemaDiff.tables.removed) {
|
|
1048
|
-
debug$
|
|
1051
|
+
debug$2(`Removing table foreign keys: ${table.name}`);
|
|
1049
1052
|
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
1050
1053
|
await helpers2.dropTableForeignKeys(schemaBuilder, table);
|
|
1051
1054
|
}
|
|
1052
1055
|
for (const table of schemaDiff.tables.removed) {
|
|
1053
|
-
debug$
|
|
1056
|
+
debug$2(`Removing table: ${table.name}`);
|
|
1054
1057
|
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
1055
1058
|
await helpers2.dropTable(schemaBuilder, table);
|
|
1056
1059
|
}
|
|
1057
1060
|
}
|
|
1058
1061
|
for (const table of schemaDiff.tables.updated) {
|
|
1059
|
-
debug$
|
|
1062
|
+
debug$2(`Updating table: ${table.name}`);
|
|
1060
1063
|
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
1061
1064
|
await helpers2.alterTable(schemaBuilder, table);
|
|
1062
1065
|
}
|
|
@@ -1152,27 +1155,27 @@ const createHelpers = (db) => {
|
|
|
1152
1155
|
const alterTable = async (schemaBuilder, table) => {
|
|
1153
1156
|
await schemaBuilder.alterTable(table.name, (tableBuilder) => {
|
|
1154
1157
|
for (const removedIndex of table.indexes.removed) {
|
|
1155
|
-
debug$
|
|
1158
|
+
debug$2(`Dropping index ${removedIndex.name}`);
|
|
1156
1159
|
dropIndex(tableBuilder, removedIndex);
|
|
1157
1160
|
}
|
|
1158
1161
|
for (const updateddIndex of table.indexes.updated) {
|
|
1159
|
-
debug$
|
|
1162
|
+
debug$2(`Dropping updated index ${updateddIndex.name}`);
|
|
1160
1163
|
dropIndex(tableBuilder, updateddIndex.object);
|
|
1161
1164
|
}
|
|
1162
1165
|
for (const removedForeignKey of table.foreignKeys.removed) {
|
|
1163
|
-
debug$
|
|
1166
|
+
debug$2(`Dropping foreign key ${removedForeignKey.name}`);
|
|
1164
1167
|
dropForeignKey(tableBuilder, removedForeignKey);
|
|
1165
1168
|
}
|
|
1166
1169
|
for (const updatedForeignKey of table.foreignKeys.updated) {
|
|
1167
|
-
debug$
|
|
1170
|
+
debug$2(`Dropping updated foreign key ${updatedForeignKey.name}`);
|
|
1168
1171
|
dropForeignKey(tableBuilder, updatedForeignKey.object);
|
|
1169
1172
|
}
|
|
1170
1173
|
for (const removedColumn of table.columns.removed) {
|
|
1171
|
-
debug$
|
|
1174
|
+
debug$2(`Dropping column ${removedColumn.name}`);
|
|
1172
1175
|
dropColumn(tableBuilder, removedColumn);
|
|
1173
1176
|
}
|
|
1174
1177
|
for (const updatedColumn of table.columns.updated) {
|
|
1175
|
-
debug$
|
|
1178
|
+
debug$2(`Updating column ${updatedColumn.name}`);
|
|
1176
1179
|
const { object } = updatedColumn;
|
|
1177
1180
|
if (object.type === "increments") {
|
|
1178
1181
|
createColumn2(tableBuilder, { ...object, type: "integer" }).alter();
|
|
@@ -1181,15 +1184,15 @@ const createHelpers = (db) => {
|
|
|
1181
1184
|
}
|
|
1182
1185
|
}
|
|
1183
1186
|
for (const updatedForeignKey of table.foreignKeys.updated) {
|
|
1184
|
-
debug$
|
|
1187
|
+
debug$2(`Recreating updated foreign key ${updatedForeignKey.name}`);
|
|
1185
1188
|
createForeignKey(tableBuilder, updatedForeignKey.object);
|
|
1186
1189
|
}
|
|
1187
1190
|
for (const updatedIndex of table.indexes.updated) {
|
|
1188
|
-
debug$
|
|
1191
|
+
debug$2(`Recreating updated index ${updatedIndex.name}`);
|
|
1189
1192
|
createIndex(tableBuilder, updatedIndex.object);
|
|
1190
1193
|
}
|
|
1191
1194
|
for (const addedColumn of table.columns.added) {
|
|
1192
|
-
debug$
|
|
1195
|
+
debug$2(`Creating column ${addedColumn.name}`);
|
|
1193
1196
|
if (addedColumn.type === "increments" && !db.dialect.canAddIncrements()) {
|
|
1194
1197
|
tableBuilder.integer(addedColumn.name).unsigned();
|
|
1195
1198
|
tableBuilder.primary([addedColumn.name]);
|
|
@@ -1198,11 +1201,11 @@ const createHelpers = (db) => {
|
|
|
1198
1201
|
}
|
|
1199
1202
|
}
|
|
1200
1203
|
for (const addedForeignKey of table.foreignKeys.added) {
|
|
1201
|
-
debug$
|
|
1204
|
+
debug$2(`Creating foreign keys ${addedForeignKey.name}`);
|
|
1202
1205
|
createForeignKey(tableBuilder, addedForeignKey);
|
|
1203
1206
|
}
|
|
1204
1207
|
for (const addedIndex of table.indexes.added) {
|
|
1205
|
-
debug$
|
|
1208
|
+
debug$2(`Creating index ${addedIndex.name}`);
|
|
1206
1209
|
createIndex(tableBuilder, addedIndex);
|
|
1207
1210
|
}
|
|
1208
1211
|
});
|
|
@@ -1788,7 +1791,7 @@ const metadataToSchema = (metadata) => {
|
|
|
1788
1791
|
});
|
|
1789
1792
|
return schema;
|
|
1790
1793
|
};
|
|
1791
|
-
const debug = createDebug("strapi::database");
|
|
1794
|
+
const debug$1 = createDebug("strapi::database");
|
|
1792
1795
|
const createSchemaProvider = (db) => {
|
|
1793
1796
|
const schema = metadataToSchema(db.metadata);
|
|
1794
1797
|
return {
|
|
@@ -1799,7 +1802,7 @@ const createSchemaProvider = (db) => {
|
|
|
1799
1802
|
* Drops the database schema
|
|
1800
1803
|
*/
|
|
1801
1804
|
async drop() {
|
|
1802
|
-
debug("Dropping database schema");
|
|
1805
|
+
debug$1("Dropping database schema");
|
|
1803
1806
|
const DBSchema = await db.dialect.schemaInspector.getSchema();
|
|
1804
1807
|
await this.builder.dropSchema(DBSchema);
|
|
1805
1808
|
},
|
|
@@ -1807,47 +1810,49 @@ const createSchemaProvider = (db) => {
|
|
|
1807
1810
|
* Creates the database schema
|
|
1808
1811
|
*/
|
|
1809
1812
|
async create() {
|
|
1810
|
-
debug("Created database schema");
|
|
1813
|
+
debug$1("Created database schema");
|
|
1811
1814
|
await this.builder.createSchema(schema);
|
|
1812
1815
|
},
|
|
1813
1816
|
/**
|
|
1814
1817
|
* Resets the database schema
|
|
1815
1818
|
*/
|
|
1816
1819
|
async reset() {
|
|
1817
|
-
debug("Resetting database schema");
|
|
1820
|
+
debug$1("Resetting database schema");
|
|
1818
1821
|
await this.drop();
|
|
1819
1822
|
await this.create();
|
|
1820
1823
|
},
|
|
1821
1824
|
async syncSchema() {
|
|
1822
|
-
debug("Synchronizing database schema");
|
|
1825
|
+
debug$1("Synchronizing database schema");
|
|
1823
1826
|
const DBSchema = await db.dialect.schemaInspector.getSchema();
|
|
1824
1827
|
const { status, diff } = await this.schemaDiff.diff(DBSchema, schema);
|
|
1825
1828
|
if (status === "CHANGED") {
|
|
1826
1829
|
await this.builder.updateSchema(diff);
|
|
1827
1830
|
}
|
|
1828
1831
|
await this.schemaStorage.add(schema);
|
|
1832
|
+
return status;
|
|
1829
1833
|
},
|
|
1830
1834
|
// TODO: support options to migrate softly or forcefully
|
|
1831
1835
|
// TODO: support option to disable auto migration & run a CLI command instead to avoid doing it at startup
|
|
1832
1836
|
// TODO: Allow keeping extra indexes / extra tables / extra columns (globally or on a per table basis)
|
|
1833
1837
|
async sync() {
|
|
1834
1838
|
if (await db.migrations.shouldRun()) {
|
|
1835
|
-
debug("Found migrations to run");
|
|
1839
|
+
debug$1("Found migrations to run");
|
|
1836
1840
|
await db.migrations.up();
|
|
1837
1841
|
return this.syncSchema();
|
|
1838
1842
|
}
|
|
1839
1843
|
const oldSchema = await this.schemaStorage.read();
|
|
1840
1844
|
if (!oldSchema) {
|
|
1841
|
-
debug("Schema not persisted yet");
|
|
1845
|
+
debug$1("Schema not persisted yet");
|
|
1842
1846
|
return this.syncSchema();
|
|
1843
1847
|
}
|
|
1844
1848
|
const { hash: oldHash } = oldSchema;
|
|
1845
1849
|
const hash = await this.schemaStorage.hashSchema(schema);
|
|
1846
1850
|
if (oldHash !== hash) {
|
|
1847
|
-
debug("Schema changed");
|
|
1851
|
+
debug$1("Schema changed");
|
|
1848
1852
|
return this.syncSchema();
|
|
1849
1853
|
}
|
|
1850
|
-
debug("Schema unchanged");
|
|
1854
|
+
debug$1("Schema unchanged");
|
|
1855
|
+
return "UNCHANGED";
|
|
1851
1856
|
}
|
|
1852
1857
|
};
|
|
1853
1858
|
};
|
|
@@ -5955,6 +5960,7 @@ const createLifecyclesProvider = (db) => {
|
|
|
5955
5960
|
timestampsLifecyclesSubscriber,
|
|
5956
5961
|
modelsLifecyclesSubscriber
|
|
5957
5962
|
];
|
|
5963
|
+
let isLifecycleHooksDisabled = false;
|
|
5958
5964
|
return {
|
|
5959
5965
|
subscribe(subscriber) {
|
|
5960
5966
|
strict(
|
|
@@ -5964,6 +5970,12 @@ const createLifecyclesProvider = (db) => {
|
|
|
5964
5970
|
subscribers.push(subscriber);
|
|
5965
5971
|
return () => subscribers.splice(subscribers.indexOf(subscriber), 1);
|
|
5966
5972
|
},
|
|
5973
|
+
disable() {
|
|
5974
|
+
isLifecycleHooksDisabled = true;
|
|
5975
|
+
},
|
|
5976
|
+
enable() {
|
|
5977
|
+
isLifecycleHooksDisabled = false;
|
|
5978
|
+
},
|
|
5967
5979
|
clear() {
|
|
5968
5980
|
subscribers = [];
|
|
5969
5981
|
},
|
|
@@ -5983,6 +5995,8 @@ const createLifecyclesProvider = (db) => {
|
|
|
5983
5995
|
* @param {Map<any, any>} states
|
|
5984
5996
|
*/
|
|
5985
5997
|
async run(action, uid, properties, states = /* @__PURE__ */ new Map()) {
|
|
5998
|
+
if (isLifecycleHooksDisabled)
|
|
5999
|
+
return states;
|
|
5986
6000
|
for (let i = 0; i < subscribers.length; i += 1) {
|
|
5987
6001
|
const subscriber = subscribers[i];
|
|
5988
6002
|
if (typeof subscriber === "function") {
|
|
@@ -6048,6 +6062,61 @@ const createConnection = (config) => {
|
|
|
6048
6062
|
}
|
|
6049
6063
|
return knex(knexConfig);
|
|
6050
6064
|
};
|
|
6065
|
+
const debug = createDebug("strapi::database");
|
|
6066
|
+
const isMorphRelationWithPivot = (attribute, pivot) => {
|
|
6067
|
+
return attribute.type === "relation" && "relation" in attribute && "joinTable" in attribute && "target" in attribute && "name" in attribute.joinTable && "pivotColumns" in attribute.joinTable && attribute.joinTable.pivotColumns.includes(pivot);
|
|
6068
|
+
};
|
|
6069
|
+
const filterMorphRelationalAttributes = (attributes, pivot) => {
|
|
6070
|
+
return Object.values(attributes).filter(
|
|
6071
|
+
(attribute) => isMorphRelationWithPivot(attribute, pivot)
|
|
6072
|
+
);
|
|
6073
|
+
};
|
|
6074
|
+
const removeOrphanMorphType = async (db, { pivot }) => {
|
|
6075
|
+
debug(`Removing orphaned morph type: ${JSON.stringify(pivot)}`);
|
|
6076
|
+
const mdValues = db.metadata.values();
|
|
6077
|
+
for (const model of mdValues) {
|
|
6078
|
+
const attributes = filterMorphRelationalAttributes(model.attributes || {}, pivot);
|
|
6079
|
+
for (const attribute of attributes) {
|
|
6080
|
+
const joinTableName = attribute.joinTable.name;
|
|
6081
|
+
const morphTypes = await db.connection(joinTableName).distinct(pivot).pluck(pivot);
|
|
6082
|
+
for (const morphType of morphTypes) {
|
|
6083
|
+
const deleteComponentType = await (async () => {
|
|
6084
|
+
try {
|
|
6085
|
+
return !db.metadata.get(morphType);
|
|
6086
|
+
} catch {
|
|
6087
|
+
debug(`Metadata for morph type "${morphType}" in table "${joinTableName}" not found`);
|
|
6088
|
+
return true;
|
|
6089
|
+
}
|
|
6090
|
+
})();
|
|
6091
|
+
if (deleteComponentType) {
|
|
6092
|
+
debug(`Removing invalid morph type "${morphType}" from table "${joinTableName}".`);
|
|
6093
|
+
try {
|
|
6094
|
+
await db.connection(joinTableName).where(pivot, morphType).del();
|
|
6095
|
+
} catch (error) {
|
|
6096
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6097
|
+
debug(
|
|
6098
|
+
`Failed to remove invalid morph type "${morphType}" from table "${joinTableName}": ${errorMessage}`
|
|
6099
|
+
);
|
|
6100
|
+
}
|
|
6101
|
+
}
|
|
6102
|
+
}
|
|
6103
|
+
}
|
|
6104
|
+
}
|
|
6105
|
+
};
|
|
6106
|
+
const asyncCurry = (fn) => {
|
|
6107
|
+
const curried = (...args) => {
|
|
6108
|
+
if (args.length >= fn.length) {
|
|
6109
|
+
return fn(...args);
|
|
6110
|
+
}
|
|
6111
|
+
return (...moreArgs) => curried(...args, ...moreArgs);
|
|
6112
|
+
};
|
|
6113
|
+
return curried;
|
|
6114
|
+
};
|
|
6115
|
+
const createRepairManager = (db) => {
|
|
6116
|
+
return {
|
|
6117
|
+
removeOrphanMorphType: asyncCurry(removeOrphanMorphType)(db)
|
|
6118
|
+
};
|
|
6119
|
+
};
|
|
6051
6120
|
const transformAttribute = (attribute) => {
|
|
6052
6121
|
switch (attribute.type) {
|
|
6053
6122
|
case "media": {
|
|
@@ -6145,6 +6214,7 @@ class Database {
|
|
|
6145
6214
|
migrations;
|
|
6146
6215
|
lifecycles;
|
|
6147
6216
|
entityManager;
|
|
6217
|
+
repair;
|
|
6148
6218
|
static transformContentTypes = transformContentTypes;
|
|
6149
6219
|
static async init(config) {
|
|
6150
6220
|
const db = new Database(config);
|
|
@@ -6169,6 +6239,7 @@ class Database {
|
|
|
6169
6239
|
this.migrations = createMigrationsProvider(this);
|
|
6170
6240
|
this.lifecycles = createLifecyclesProvider(this);
|
|
6171
6241
|
this.entityManager = createEntityManager(this);
|
|
6242
|
+
this.repair = createRepairManager(this);
|
|
6172
6243
|
}
|
|
6173
6244
|
query(uid) {
|
|
6174
6245
|
if (!this.metadata.has(uid)) {
|