diff --git a/src/config.js b/src/config.js index c5335b13..9614730a 100644 --- a/src/config.js +++ b/src/config.js @@ -131,7 +131,9 @@ export const defaultConfiguration = { defaults: { 'osjs/default-application': {}, 'osjs/session': [], - 'osjs/desktop': {}, + 'osjs/desktop': { + __revision__: 0 + }, 'osjs/locale': {} } }, diff --git a/src/core.js b/src/core.js index bbf36209..ad500d32 100644 --- a/src/core.js +++ b/src/core.js @@ -144,7 +144,8 @@ export default class Core extends CoreBase { this.user = user; if (this.has('osjs/settings')) { - this.make('osjs/settings').load() + const settings = this.make('osjs/settings'); + settings.load(true) .then(() => done()) .catch(() => done()); } else { diff --git a/src/providers/settings.js b/src/providers/settings.js index 37c8cce6..b81512dd 100644 --- a/src/providers/settings.js +++ b/src/providers/settings.js @@ -58,7 +58,7 @@ export default class SettingsServiceProvider extends ServiceProvider { init() { this.core.singleton('osjs/settings', () => ({ save: () => this.settings.save(), - load: () => this.settings.load(), + load: migrate => this.settings.load(migrate), clear: (...args) => this.settings.clear(...args), get: (...args) => this.settings.get(...args), set: (...args) => this.settings.set(...args) diff --git a/src/settings.js b/src/settings.js index d6f1367a..5ac6384f 100644 --- a/src/settings.js +++ b/src/settings.js @@ -106,9 +106,10 @@ export default class Settings { /** * Loads settings + * @param {boolean} [migrate] Run migrations * @return {Promise} */ - load() { + load(migrate) { const defaults = this.core.config('settings.defaults', {}); return this.adapter.load() @@ -117,6 +118,9 @@ export default class Settings { arrayMerge: (dest, source) => source }); + return migrate ? this.migrate() : Promise.resolve(); + }) + .then(() => { this.core.emit('osjs/settings:load'); return true; @@ -128,6 +132,38 @@ export default class Settings { }); } + /** + * Runs migrations for settings + */ + migrate() { + const defaults = this.core.config('settings.defaults', {}); + + const revisionsChanged = Object.keys(defaults) + .filter(key => { + const currentRevision = defaults[key].__revision__; + const userRevision = this.settings[key] + ? this.settings[key].__revision__ + : undefined; + + if (typeof currentRevision === 'undefined') { + return false; + } + + return userRevision < currentRevision; + }); + + if (revisionsChanged.length > 0) { + revisionsChanged.forEach(key => { + this.settings[key] = merge(defaults[key], {}); + }); + + return this.save() + .catch(err => console.warn('Settings#migrate', 'failed to save after migration', err)); + } + + return Promise.resolve(); + } + /** * Gets a settings entry by key *