@strapi/database 5.5.1 → 5.6.0

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.
@@ -2,6 +2,7 @@ import type { Database } from '..';
2
2
  import type { Schema } from '../schema';
3
3
  export interface SchemaInspector {
4
4
  getSchema(): Promise<Schema>;
5
+ getTables(): Promise<string[]>;
5
6
  }
6
7
  export default class Dialect {
7
8
  db: Database;
@@ -10,6 +11,7 @@ export default class Dialect {
10
11
  constructor(db: Database, client: string);
11
12
  configure(conn?: any): void;
12
13
  initialize(_nativeConnection?: unknown): Promise<void>;
14
+ getTables(): void;
13
15
  getSqlType(type: unknown): unknown;
14
16
  canAlterConstraints(): boolean;
15
17
  usesForeignKeys(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../../src/dialects/dialect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,CAAC,OAAO,OAAO,OAAO;IAC1B,EAAE,EAAE,QAAQ,CAAC;IAEb,eAAe,EAAE,eAAe,CAAyB;IAEzD,MAAM,EAAE,MAAM,CAAC;gBAEH,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM;IAMxC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG;IAGd,UAAU,CAAC,iBAAiB,CAAC,EAAE,OAAO;IAI5C,UAAU,CAAC,IAAI,EAAE,OAAO;IAIxB,mBAAmB;IAInB,eAAe;IAIf,YAAY;IAIZ,gBAAgB;IAIhB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAKtC,iBAAiB;IAIjB,eAAe;IAIrB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE;IAQlD,gBAAgB;CAGjB"}
1
+ {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../../src/dialects/dialect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAChC;AAED,MAAM,CAAC,OAAO,OAAO,OAAO;IAC1B,EAAE,EAAE,QAAQ,CAAC;IAEb,eAAe,EAAE,eAAe,CAAyB;IAEzD,MAAM,EAAE,MAAM,CAAC;gBAEH,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM;IAMxC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG;IAGd,UAAU,CAAC,iBAAiB,CAAC,EAAE,OAAO;IAI5C,SAAS;IAIT,UAAU,CAAC,IAAI,EAAE,OAAO;IAIxB,mBAAmB;IAInB,eAAe;IAIf,YAAY;IAIZ,gBAAgB;IAIhB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAKtC,iBAAiB;IAIjB,eAAe;IAIrB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE;IAQlD,gBAAgB;CAGjB"}
package/dist/index.d.ts CHANGED
@@ -3,13 +3,13 @@ import { Dialect } from './dialects';
3
3
  import { SchemaProvider } from './schema';
4
4
  import { Metadata } from './metadata';
5
5
  import { EntityManager } from './entity-manager';
6
- import { MigrationProvider } from './migrations';
6
+ import { MigrationProvider, type Migration } from './migrations';
7
7
  import { LifecycleProvider } from './lifecycles';
8
8
  import * as errors from './errors';
9
9
  import { Callback, TransactionObject } from './transaction-context';
10
10
  import type { Model } from './types';
11
- import type { Migration } from './migrations';
12
- import { type Identifiers } from './utils/identifiers';
11
+ import type { Identifiers } from './utils/identifiers';
12
+ import { type RepairManager } from './repairs';
13
13
  export { isKnexQuery } from './utils/knex';
14
14
  interface Settings {
15
15
  forceMigration?: boolean;
@@ -34,6 +34,7 @@ declare class Database {
34
34
  migrations: MigrationProvider;
35
35
  lifecycles: LifecycleProvider;
36
36
  entityManager: EntityManager;
37
+ repair: RepairManager;
37
38
  logger: Logger;
38
39
  constructor(config: DatabaseConfig);
39
40
  init({ models }: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGjC,OAAO,EAAE,OAAO,EAAc,MAAM,YAAY,CAAC;AACjD,OAAO,EAAwB,cAAc,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAuB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAA4B,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAA4B,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE3E,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAkB,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAEpF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,UAAU,QAAQ;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE;QACV,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,MAAM,GAAG,MAAM,CACzB,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EACnC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CACpD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAcD,cAAM,QAAQ;IACZ,UAAU,EAAE,IAAI,CAAC;IAEjB,OAAO,EAAE,OAAO,CAAC;IAEjB,MAAM,EAAE,cAAc,CAAC;IAEvB,QAAQ,EAAE,QAAQ,CAAC;IAEnB,MAAM,EAAE,cAAc,CAAC;IAEvB,UAAU,EAAE,iBAAiB,CAAC;IAE9B,UAAU,EAAE,iBAAiB,CAAC;IAE9B,aAAa,EAAE,aAAa,CAAC;IAE7B,MAAM,EAAE,MAAM,CAAC;gBAEH,MAAM,EAAE,cAAc;IAmD5B,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,EAAE,KAAK,EAAE,CAAA;KAAE;IA2B1C,KAAK,CAAC,GAAG,EAAE,MAAM;IAQjB,aAAa;IAIb,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IACzC,WAAW,CAAC,SAAS,SAAS,QAAQ,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IA4CrF,aAAa,IAAI,MAAM,GAAG,SAAS;IAInC,aAAa,IAAI,IAAI;IACrB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,YAAY;IAQpD,OAAO;;;;;IA2BP,mBAAmB,CAAC,GAAG,mBAAkB;IAKzC,YAAY,CAAC,GAAG,EAAE,MAAM;IAIlB,OAAO;CAId;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC5B,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGjC,OAAO,EAAE,OAAO,EAAc,MAAM,YAAY,CAAC;AACjD,OAAO,EAAwB,cAAc,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAuB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAA4B,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAA4B,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE3E,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAkB,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAEpF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,UAAU,QAAQ;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE;QACV,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,MAAM,GAAG,MAAM,CACzB,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EACnC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CACpD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAcD,cAAM,QAAQ;IACZ,UAAU,EAAE,IAAI,CAAC;IAEjB,OAAO,EAAE,OAAO,CAAC;IAEjB,MAAM,EAAE,cAAc,CAAC;IAEvB,QAAQ,EAAE,QAAQ,CAAC;IAEnB,MAAM,EAAE,cAAc,CAAC;IAEvB,UAAU,EAAE,iBAAiB,CAAC;IAE9B,UAAU,EAAE,iBAAiB,CAAC;IAE9B,aAAa,EAAE,aAAa,CAAC;IAE7B,MAAM,EAAE,aAAa,CAAC;IAEtB,MAAM,EAAE,MAAM,CAAC;gBAEH,MAAM,EAAE,cAAc;IAqD5B,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,EAAE,KAAK,EAAE,CAAA;KAAE;IA2B1C,KAAK,CAAC,GAAG,EAAE,MAAM;IAQjB,aAAa;IAIb,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IACzC,WAAW,CAAC,SAAS,SAAS,QAAQ,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IA4CrF,aAAa,IAAI,MAAM,GAAG,SAAS;IAInC,aAAa,IAAI,IAAI;IACrB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,YAAY;IAQpD,OAAO;;;;;IA2BP,mBAAmB,CAAC,GAAG,mBAAkB;IAKzC,YAAY,CAAC,GAAG,EAAE,MAAM;IAIlB,OAAO;CAId;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC5B,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -62,6 +62,9 @@ class Dialect {
62
62
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
63
63
  async initialize(_nativeConnection) {
64
64
  }
65
+ getTables() {
66
+ throw new Error("getTables not implemented for this dialect");
67
+ }
65
68
  getSqlType(type) {
66
69
  return type;
67
70
  }
@@ -2238,6 +2241,7 @@ const createSchemaProvider = (db) => {
2238
2241
  await this.builder.updateSchema(diff);
2239
2242
  }
2240
2243
  await this.schemaStorage.add(this.schema);
2244
+ return status;
2241
2245
  },
2242
2246
  // TODO: support options to migrate softly or forcefully
2243
2247
  // TODO: support option to disable auto migration & run a CLI command instead to avoid doing it at startup
@@ -2260,6 +2264,7 @@ const createSchemaProvider = (db) => {
2260
2264
  return this.syncSchema();
2261
2265
  }
2262
2266
  debug$1("Schema unchanged");
2267
+ return "UNCHANGED";
2263
2268
  }
2264
2269
  };
2265
2270
  };
@@ -6935,6 +6940,64 @@ const validateRelations = async (db) => {
6935
6940
  async function validateDatabase(db) {
6936
6941
  await validateRelations(db);
6937
6942
  }
6943
+ const isMorphRelationWithPivot = (attribute, pivot) => {
6944
+ 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);
6945
+ };
6946
+ const filterMorphRelationalAttributes = (attributes, pivot) => {
6947
+ return Object.values(attributes).filter(
6948
+ (attribute) => isMorphRelationWithPivot(attribute, pivot)
6949
+ );
6950
+ };
6951
+ const removeOrphanMorphType = async (db, { pivot }) => {
6952
+ db.logger.debug(`Removing orphaned morph type: ${JSON.stringify(pivot)}`);
6953
+ const mdValues = db.metadata.values();
6954
+ for (const model of mdValues) {
6955
+ const attributes = filterMorphRelationalAttributes(model.attributes || {}, pivot);
6956
+ for (const attribute of attributes) {
6957
+ const joinTableName = attribute.joinTable.name;
6958
+ const morphTypes = await db.connection(joinTableName).distinct(pivot).pluck(pivot);
6959
+ for (const morphType of morphTypes) {
6960
+ const deleteComponentType = await (async () => {
6961
+ try {
6962
+ return !db.metadata.get(morphType);
6963
+ } catch {
6964
+ db.logger.debug(
6965
+ `Metadata for morph type "${morphType}" in table "${joinTableName}" not found`
6966
+ );
6967
+ return true;
6968
+ }
6969
+ })();
6970
+ if (deleteComponentType) {
6971
+ db.logger.debug(
6972
+ `Removing invalid morph type "${morphType}" from table "${joinTableName}".`
6973
+ );
6974
+ try {
6975
+ await db.connection(joinTableName).where(pivot, morphType).del();
6976
+ } catch (error) {
6977
+ const errorMessage = error instanceof Error ? error.message : String(error);
6978
+ db.logger.error(
6979
+ `Failed to remove invalid morph type "${morphType}" from table "${joinTableName}": ${errorMessage}`
6980
+ );
6981
+ }
6982
+ }
6983
+ }
6984
+ }
6985
+ }
6986
+ };
6987
+ const asyncCurry = (fn) => {
6988
+ const curried = (...args) => {
6989
+ if (args.length >= fn.length) {
6990
+ return fn(...args);
6991
+ }
6992
+ return (...moreArgs) => curried(...args, ...moreArgs);
6993
+ };
6994
+ return curried;
6995
+ };
6996
+ const createRepairManager = (db) => {
6997
+ return {
6998
+ removeOrphanMorphType: asyncCurry(removeOrphanMorphType)(db)
6999
+ };
7000
+ };
6938
7001
  const afterCreate = (db) => (nativeConnection, done) => {
6939
7002
  db.dialect.initialize(nativeConnection).then(() => {
6940
7003
  return done(null, nativeConnection);
@@ -6949,6 +7012,7 @@ class Database {
6949
7012
  migrations;
6950
7013
  lifecycles;
6951
7014
  entityManager;
7015
+ repair;
6952
7016
  logger;
6953
7017
  constructor(config) {
6954
7018
  this.config = {
@@ -6985,6 +7049,7 @@ class Database {
6985
7049
  this.migrations = createMigrationsProvider(this);
6986
7050
  this.lifecycles = createLifecyclesProvider(this);
6987
7051
  this.entityManager = createEntityManager(this);
7052
+ this.repair = createRepairManager(this);
6988
7053
  }
6989
7054
  async init({ models }) {
6990
7055
  if (typeof this.config.connection.connection === "function") {