diff --git a/package-lock.json b/package-lock.json index f3eb2ee0..f1926327 100644 --- a/package-lock.json +++ b/package-lock.json @@ -361,16 +361,6 @@ "integrity": "sha512-KZfv4ea6bEbdQhfwpxtDuTPO2mHAAXMQqPOZyS4MgNyCymKoLHp0FVzzYq3H2zCeIotN4h1453TahLCCm8rf2w==", "dev": true }, - "@types/knex": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@types/knex/-/knex-0.15.2.tgz", - "integrity": "sha512-mw8OT8v+FK0SsgDdmio2XSkEM/yLD7ybFtiqW7I65EDTlr2aZtG+p9FhryErpNJDJ2FEXgQhe3JVBG0Gh7YbvQ==", - "dev": true, - "requires": { - "@types/bluebird": "*", - "@types/node": "*" - } - }, "@types/lockfile": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/lockfile/-/lockfile-1.0.1.tgz", @@ -2441,6 +2431,12 @@ "simple-swizzle": "^0.2.2" } }, + "colorette": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.1.0.tgz", + "integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg==", + "dev": true + }, "colornames": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", @@ -4023,6 +4019,12 @@ } } }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -5134,32 +5136,21 @@ } }, "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", "dev": true, "requires": { "detect-file": "^1.0.0", - "is-glob": "^3.1.0", + "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } } }, "fined": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz", - "integrity": "sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, "requires": { "expand-tilde": "^2.0.2", @@ -5406,6 +5397,12 @@ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, + "getopts": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", + "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -6374,9 +6371,9 @@ } }, "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.0.0.tgz", + "integrity": "sha512-e0/LknJ8wpMMhTiWcjivB+ESwIuvHnBSlBbmP/pSb8CQJldoj1p2qv7xGZ/+BtbTziYRFSz8OsvdbiX45LtYQA==", "dev": true }, "invariant": { @@ -6958,72 +6955,60 @@ } }, "knex": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.15.2.tgz", - "integrity": "sha1-YFm4dIlgX0zIdZmm0qnSZXCek0A=", + "version": "0.20.13", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.20.13.tgz", + "integrity": "sha512-YVl//Te0G5suc+d9KyeI6WuhtgVlxu6HXYQB+WqrccFkSZAbHqlqZlUMogYG3UoVq69c3kiFbbxgUNkrO0PVfg==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "bluebird": "^3.5.1", - "chalk": "2.3.2", - "commander": "^2.16.0", - "debug": "3.1.0", - "inherits": "~2.0.3", - "interpret": "^1.1.0", - "liftoff": "2.5.0", - "lodash": "^4.17.10", - "minimist": "1.2.0", + "colorette": "1.1.0", + "commander": "^4.1.1", + "debug": "4.1.1", + "esm": "^3.2.25", + "getopts": "2.2.5", + "inherits": "~2.0.4", + "interpret": "^2.0.0", + "liftoff": "3.1.0", + "lodash": "^4.17.15", "mkdirp": "^0.5.1", - "pg-connection-string": "2.0.0", - "tarn": "^1.1.4", - "tildify": "1.2.0", - "uuid": "^3.3.2", - "v8flags": "^3.1.1" + "pg-connection-string": "2.1.0", + "tarn": "^2.0.0", + "tildify": "2.0.0", + "uuid": "^7.0.1", + "v8flags": "^3.1.3" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.3.2", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ms": "^2.1.1" } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true } } }, @@ -7074,13 +7059,13 @@ } }, "liftoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", - "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", "dev": true, "requires": { "extend": "^3.0.0", - "findup-sync": "^2.0.0", + "findup-sync": "^3.0.0", "fined": "^1.0.1", "flagged-respawn": "^1.0.0", "is-plain-object": "^2.0.4", @@ -8944,9 +8929,9 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pg-connection-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.0.0.tgz", - "integrity": "sha1-Pu/lmX4G2Ugh5NUC5CtqHHP434I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.1.0.tgz", + "integrity": "sha512-bhlV7Eq09JrRIvo1eKngpwuqKtJnNhZdpdOlvrPrA4dxqXPjxSrbNrfnIDmTpwMyRszrcV4kU5ZA4mMsQUrjdg==", "dev": true }, "picomatch": { @@ -10676,9 +10661,9 @@ } }, "tarn": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/tarn/-/tarn-1.1.4.tgz", - "integrity": "sha512-j4samMCQCP5+6Il9/cxCqBd3x4vvlLeVdoyGex0KixPKl4F8LpNbDSC6NDhjianZgUngElRr9UI1ryZqJDhwGg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-2.0.0.tgz", + "integrity": "sha512-7rNMCZd3s9bhQh47ksAQd92ADFcJUjjbyOvyFjNLwTPpGieFHMC84S+LOzw0fx1uh6hnDz/19r8CPMnIjJlMMA==", "dev": true }, "term-size": { @@ -11025,13 +11010,10 @@ } }, "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", + "dev": true }, "time-stamp": { "version": "1.1.0", @@ -11699,9 +11681,9 @@ "dev": true }, "v8flags": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz", - "integrity": "sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", "dev": true, "requires": { "homedir-polyfill": "^1.0.1" diff --git a/package.json b/package.json index a7804c1b..0299c075 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "@types/dockerode": "^2.5.25", "@types/event-stream": "^3.3.34", "@types/express": "^4.17.3", - "@types/knex": "^0.15.2", "@types/lockfile": "^1.0.1", "@types/lodash": "^4.14.149", "@types/memoizee": "^0.4.3", @@ -92,7 +91,7 @@ "io-ts-reporters": "^1.0.0", "istanbul": "^0.4.5", "json-mask": "^0.3.9", - "knex": "^0.15.2", + "knex": "^0.20.13", "lint-staged": "^10.0.8", "livepush": "^3.3.0", "lockfile": "^1.0.4", diff --git a/src/compose/images.ts b/src/compose/images.ts index d135e07c..97abea4c 100644 --- a/src/compose/images.ts +++ b/src/compose/images.ts @@ -362,7 +362,7 @@ export class Images extends (EventEmitter as new () => ImageEventEmitter) { this.db .models('image') .select('dockerImageId') - .map((img: Image) => img.dockerImageId), + .then(vals => vals.map((img: Image) => img.dockerImageId)), ]); const supervisorRepos = [supervisorImageInfo.imageName]; diff --git a/src/config/index.ts b/src/config/index.ts index be08ea29..0e9ee433 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -123,11 +123,11 @@ export class Config extends (EventEmitter as new () => ConfigEventEmitter) { }) as Bluebird<{ [key in T]: SchemaReturn }>; } - public set( + public async set( keyValues: ConfigMap, trx?: Transaction, - ): Bluebird { - const setValuesInTransaction = (tx: Transaction) => { + ): Promise { + const setValuesInTransaction = async (tx: Transaction) => { const configJsonVals: Dictionary = {}; const dbVals: Dictionary = {}; @@ -150,77 +150,67 @@ export class Config extends (EventEmitter as new () => ConfigEventEmitter) { }); const dbKeys = _.keys(dbVals) as T[]; - return this.getMany(dbKeys, tx) - .then(oldValues => { - return Bluebird.map(dbKeys, (key: T) => { - const value = dbVals[key]; + const oldValues = await this.getMany(dbKeys, tx); + await Bluebird.map(dbKeys, async (key: T) => { + const value = dbVals[key]; - // if we have anything other than a string, it must be converted to - // a string before being stored in the db - const strValue = Config.valueToString(value, key); + // if we have anything other than a string, it must be converted to + // a string before being stored in the db + const strValue = Config.valueToString(value, key); - if (oldValues[key] !== value) { - return this.db.upsertModel( - 'config', - { key, value: strValue }, - { key }, - tx, - ); - } - }); - }) - .then(() => { - if (!_.isEmpty(configJsonVals)) { - return this.configJsonBackend.set( - configJsonVals as { - [key in Schema.SchemaKey]: unknown; - }, - ); - } - }); + if (oldValues[key] !== value) { + await this.db.upsertModel( + 'config', + { key, value: strValue }, + { key }, + tx, + ); + } + }); + + if (!_.isEmpty(configJsonVals)) { + await this.configJsonBackend.set( + configJsonVals as { + [name in Schema.SchemaKey]: unknown; + }, + ); + } }; - return Bluebird.try(() => { - // Firstly validate and coerce all of the types as - // they are being set - keyValues = this.validateConfigMap(keyValues); + // Firstly validate and coerce all of the types as + // they are being set + keyValues = this.validateConfigMap(keyValues); - if (trx != null) { - return setValuesInTransaction(trx).return(); - } else { - return this.db - .transaction((tx: Transaction) => setValuesInTransaction(tx)) - .return(); - } - }).then(() => { - this.emit('change', keyValues as ConfigMap); - }); + if (trx != null) { + await setValuesInTransaction(trx); + } else { + await this.db.transaction((tx: Transaction) => + setValuesInTransaction(tx), + ); + } + this.emit('change', keyValues as ConfigMap); } - public remove(key: T): Bluebird { - return Bluebird.try(() => { - if (Schema.schema[key] == null || !Schema.schema[key].mutable) { - throw new Error( - `Attempt to delete non-existent or immutable key ${key}`, - ); - } - if (Schema.schema[key].source === 'config.json') { - return this.configJsonBackend.remove(key); - } else if (Schema.schema[key].source === 'db') { - return this.db - .models('config') - .del() - .where({ key }); - } else { - throw new Error( - `Unknown or unsupported config backend: ${Schema.schema[key].source}`, - ); - } - }); + public async remove(key: T): Promise { + if (Schema.schema[key] == null || !Schema.schema[key].mutable) { + throw new Error(`Attempt to delete non-existent or immutable key ${key}`); + } + if (Schema.schema[key].source === 'config.json') { + return this.configJsonBackend.remove(key); + } else if (Schema.schema[key].source === 'db') { + await this.db + .models('config') + .del() + .where({ key }); + } else { + throw new Error( + `Unknown or unsupported config backend: ${Schema.schema[key].source}`, + ); + } } - public regenerateRegistrationFields(): Bluebird { - return this.set({ + public async regenerateRegistrationFields(): Promise { + await this.set({ uuid: this.newUniqueKey(), deviceApiKey: this.newUniqueKey(), }); diff --git a/src/db.ts b/src/db.ts index 3e63744c..18c3dbb8 100644 --- a/src/db.ts +++ b/src/db.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird'; import * as Knex from 'knex'; import * as path from 'path'; @@ -27,42 +26,38 @@ export class DB { }); } - public init(): Bluebird { - return this.knex('knex_migrations_lock') - .update({ is_locked: 0 }) - .catch(() => { - return; - }) - .then(() => { - return this.knex.migrate.latest({ - directory: path.join(__dirname, 'migrations'), - }); - }); + public async init(): Promise { + try { + await this.knex('knex_migrations_lock').update({ is_locked: 0 }); + } catch { + /* ignore */ + } + return this.knex.migrate.latest({ + directory: path.join(__dirname, 'migrations'), + }); } public models(modelName: string): Knex.QueryBuilder { return this.knex(modelName); } - public upsertModel( + public async upsertModel( modelName: string, obj: any, id: Dictionary, trx?: Knex.Transaction, - ): Bluebird { + ): Promise { const knex = trx || this.knex; - return knex(modelName) + const n = await knex(modelName) .update(obj) - .where(id) - .then((n: number) => { - if (n === 0) { - return knex(modelName).insert(obj); - } - }); + .where(id); + if (n === 0) { + return knex(modelName).insert(obj); + } } - public transaction(cb: DBTransactionCallback): Bluebird { + public transaction(cb: DBTransactionCallback): Promise { return this.knex.transaction(cb); } } diff --git a/src/proxyvisor.js b/src/proxyvisor.js index db93c754..a554d99b 100644 --- a/src/proxyvisor.js +++ b/src/proxyvisor.js @@ -510,16 +510,17 @@ export class Proxyvisor { if (this.actionExecutors[step.action] == null) { throw new Error(`Invalid proxyvisor action ${step.action}`); } + return this.actionExecutors[step.action](step); }); } getCurrentStates() { return Promise.join( - this.db - .models('dependentApp') - .select() - .map(this.normaliseDependentAppFromDB), + Promise.map( + this.db.models('dependentApp').select(), + this.normaliseDependentAppFromDB, + ), this.db.models('dependentDevice').select(), function(apps, devicesFromDB) { const devices = _.map(devicesFromDB, function(device) { @@ -693,14 +694,14 @@ export class Proxyvisor { getTarget() { return Promise.props({ - apps: this.db - .models('dependentAppTarget') - .select() - .map(this.normaliseDependentAppFromDB), - devices: this.db - .models('dependentDeviceTarget') - .select() - .map(this.normaliseDependentDeviceTargetFromDB), + apps: Promise.map( + this.db.models('dependentAppTarget').select(), + this.normaliseDependentAppFromDB, + ), + devices: Promise.map( + this.db.models('dependentDeviceTarget').select(), + this.normaliseDependentDeviceTargetFromDB, + ), }); } diff --git a/test/03-config.spec.ts b/test/03-config.spec.ts index ea8fa707..b5a515ae 100644 --- a/test/03-config.spec.ts +++ b/test/03-config.spec.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird'; import * as _ from 'lodash'; import { fs } from 'mz'; @@ -16,14 +15,14 @@ import constants = require('../src/lib/constants'); describe('Config', () => { let db: DB; let conf: Config; - let initialization: Bluebird; - before(() => { + before(async () => { prepare(); db = new DB(); conf = new Config({ db }); - initialization = db.init().then(() => conf.init()); + await db.init(); + await conf.init(); }); it('uses the correct config.json path', async () => { @@ -39,10 +38,6 @@ describe('Config', () => { ); }); - it('initializes correctly', () => { - return expect(initialization).to.be.fulfilled; - }); - it('reads and exposes values from the config.json', async () => { const id = await conf.get('applicationId'); return expect(id).to.equal(78373);