{"version":3,"file":"index.mjs","sources":["../../src/schema/index.ts"],"sourcesContent":["import createDebug from 'debug';\n\nimport createSchemaBuilder from './builder';\nimport createSchemaDiff from './diff';\nimport createSchemaStorage from './storage';\nimport { metadataToSchema } from './schema';\n\nimport type { Schema, SchemaDiff } from './types';\nimport type { Database } from '..';\n\nexport type * from './types';\n\nconst debug = createDebug('strapi::database');\n\nexport interface SchemaProvider {\n  builder: ReturnType<typeof createSchemaBuilder>;\n  schemaDiff: ReturnType<typeof createSchemaDiff>;\n  schemaStorage: ReturnType<typeof createSchemaStorage>;\n  sync(): Promise<SchemaDiff['status']>;\n  syncSchema(): Promise<SchemaDiff['status']>;\n  reset(): Promise<void>;\n  create(): Promise<void>;\n  drop(): Promise<void>;\n  schema: Schema;\n}\n\ninterface State {\n  schema?: Schema;\n}\n\nexport const createSchemaProvider = (db: Database): SchemaProvider => {\n  const state: State = {};\n\n  return {\n    get schema() {\n      if (!state.schema) {\n        debug('Converting metadata to database schema');\n        state.schema = metadataToSchema(db.metadata);\n      }\n\n      return state.schema;\n    },\n    builder: createSchemaBuilder(db),\n    schemaDiff: createSchemaDiff(db),\n    schemaStorage: createSchemaStorage(db),\n\n    /**\n     * Drops the database schema\n     */\n    async drop() {\n      debug('Dropping database schema');\n\n      const DBSchema = await db.dialect.schemaInspector.getSchema();\n      await this.builder.dropSchema(DBSchema);\n    },\n\n    /**\n     * Creates the database schema\n     */\n    async create() {\n      debug('Created database schema');\n      await this.builder.createSchema(this.schema);\n    },\n\n    /**\n     * Resets the database schema\n     */\n    async reset() {\n      debug('Resetting database schema');\n      await this.drop();\n      await this.create();\n    },\n\n    async syncSchema(): Promise<SchemaDiff['status']> {\n      debug('Synchronizing database schema');\n\n      const databaseSchema = await db.dialect.schemaInspector.getSchema();\n      const storedSchema = await this.schemaStorage.read();\n\n      /*\n        3way diff - DB schema / previous metadataSchema / new metadataSchema\n\n        - When something doesn't exist in the previous metadataSchema -> It's not tracked by us and should be ignored\n        - If no previous metadataSchema => use new metadataSchema so we start tracking them and ignore everything else\n        - Apply this logic to Tables / Columns / Indexes / FKs ...\n        - Handle errors (indexes or fks on incompatible stuff ...)\n\n      */\n\n      const { status, diff } = await this.schemaDiff.diff({\n        previousSchema: storedSchema?.schema,\n        databaseSchema,\n        userSchema: this.schema,\n      });\n\n      if (status === 'CHANGED') {\n        await this.builder.updateSchema(diff);\n      }\n\n      await this.schemaStorage.add(this.schema);\n\n      return status;\n    },\n\n    // TODO: support options to migrate softly or forcefully\n    // TODO: support option to disable auto migration & run a CLI command instead to avoid doing it at startup\n    // TODO: Allow keeping extra indexes / extra tables / extra columns (globally or on a per table basis)\n    async sync(): Promise<SchemaDiff['status']> {\n      if (await db.migrations.shouldRun()) {\n        debug('Found migrations to run');\n        await db.migrations.up();\n\n        return this.syncSchema();\n      }\n\n      const oldSchema = await this.schemaStorage.read();\n\n      if (!oldSchema) {\n        debug('Schema not persisted yet');\n        return this.syncSchema();\n      }\n\n      const { hash: oldHash } = oldSchema;\n      const hash = await this.schemaStorage.hashSchema(this.schema);\n\n      if (oldHash !== hash) {\n        debug('Schema changed');\n\n        return this.syncSchema();\n      }\n\n      debug('Schema unchanged');\n\n      return 'UNCHANGED';\n    },\n  };\n};\n"],"names":["debug","createDebug","createSchemaProvider","db","state","schema","metadataToSchema","metadata","builder","createSchemaBuilder","schemaDiff","createSchemaDiff","schemaStorage","createSchemaStorage","drop","DBSchema","dialect","schemaInspector","getSchema","dropSchema","create","createSchema","reset","syncSchema","databaseSchema","storedSchema","read","status","diff","previousSchema","userSchema","updateSchema","add","sync","migrations","shouldRun","up","oldSchema","hash","oldHash","hashSchema"],"mappings":"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"}