From ce75754d8d445e2b9a3da55c7fa0526e6de85a3f Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Fri, 10 Apr 2020 22:18:11 +0200 Subject: [PATCH 01/11] Changed manifest endpoint to server-side (#106) --- src/config.js | 2 +- src/packages.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config.js b/src/config.js index 10b92f09..6d9ec19c 100644 --- a/src/config.js +++ b/src/config.js @@ -70,7 +70,7 @@ export const defaultConfiguration = { }, packages: { - manifest: '/metadata.json', + manifest: '/api/packages/manifest', metadata: [] }, diff --git a/src/packages.js b/src/packages.js index 3302ee83..0f6be4ce 100644 --- a/src/packages.js +++ b/src/packages.js @@ -369,6 +369,7 @@ export default class Packages { if (list instanceof Array) { const append = list .map(iter => Object.assign({ + _user: false, type: 'application', files: [] }, iter)); From cda63a3ca52d1085a28e5e0558a03be6d2389d2e Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Fri, 10 Apr 2020 22:18:45 +0200 Subject: [PATCH 02/11] Update URL resolver to support home VFS (#106) --- src/utils/url.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils/url.js b/src/utils/url.js index 68c73aa5..2f3cfba1 100644 --- a/src/utils/url.js +++ b/src/utils/url.js @@ -52,7 +52,11 @@ export const urlResolver = configuration => { metadata.type === 'icons' ? 'icons' : 'apps' ); - url = `${type}/${metadata.name}${path}`; + if (metadata._user) { + url = `vfs/readfile?path=${encodeURIComponent(`home:/.packages/${metadata.name}${path}`)}`; + } else { + url = `${type}/${metadata.name}${path}`; + } } return prefix From 8e235fd70c43e528310ae919d85b01c60b1eea31 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Fri, 10 Apr 2020 22:19:05 +0200 Subject: [PATCH 03/11] Added Packages#install (#106) --- src/packages.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/packages.js b/src/packages.js index 0f6be4ce..c51517da 100644 --- a/src/packages.js +++ b/src/packages.js @@ -333,6 +333,27 @@ export default class Packages { [...meta, ...configured].forEach(({name, args}) => this.launch(name, args || {})); } + /** + * Installs a package + * @param {string} url URL to package + * @param {options} [options] + * @param {boolean} [options.system] Install as system package + */ + install(url, options = {}) { + const body = { + url, + options: Object.assign({}, { + system: false + }, options) + }; + + return this.core + .request('/api/packages/install', { + method: 'post', + body + }); + } + /** * Registers a package * From 1de1c61be95b35628e0598d164f7e7c7dbfdb3ba Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Fri, 10 Apr 2020 22:39:55 +0200 Subject: [PATCH 04/11] Configurable package location paths (#106) --- src/config.js | 3 +++ src/packages.js | 8 ++++++-- src/utils/url.js | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/config.js b/src/config.js index 6d9ec19c..b513a620 100644 --- a/src/config.js +++ b/src/config.js @@ -71,6 +71,9 @@ export const defaultConfiguration = { packages: { manifest: '/api/packages/manifest', + vfsPaths: [ + 'home:/.packages' + ], metadata: [] }, diff --git a/src/packages.js b/src/packages.js index c51517da..1b4c72fe 100644 --- a/src/packages.js +++ b/src/packages.js @@ -134,8 +134,12 @@ export default class Packages { const manifest = this.core.config('packages.manifest'); + const query = this.core.config('packages.vfsPaths', []) + .map(str => `root[]=${encodeURIComponent(str)}`) + .join('&'); + return manifest - ? this.core.request(manifest, {}, 'json') + ? this.core.request(`${manifest}?${query}`, {}, 'json') .then(metadata => this.addPackages(metadata)) .then(() => true) .catch(error => logger.error(error)) @@ -390,7 +394,7 @@ export default class Packages { if (list instanceof Array) { const append = list .map(iter => Object.assign({ - _user: false, + _vfs: null, type: 'application', files: [] }, iter)); diff --git a/src/utils/url.js b/src/utils/url.js index 2f3cfba1..6990245e 100644 --- a/src/utils/url.js +++ b/src/utils/url.js @@ -52,8 +52,8 @@ export const urlResolver = configuration => { metadata.type === 'icons' ? 'icons' : 'apps' ); - if (metadata._user) { - url = `vfs/readfile?path=${encodeURIComponent(`home:/.packages/${metadata.name}${path}`)}`; + if (metadata._vfs) { + url = `vfs/readfile?path=${encodeURIComponent(`${metadata._vfs}/${metadata.name}${path}`)}`; } else { url = `${type}/${metadata.name}${path}`; } From 7f697879e1c101744f952989c52f419b0604aa0a Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Fri, 10 Apr 2020 23:42:15 +0200 Subject: [PATCH 05/11] Updated package install request content type (#106) --- src/packages.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/packages.js b/src/packages.js index 1b4c72fe..7bd6d8cb 100644 --- a/src/packages.js +++ b/src/packages.js @@ -354,8 +354,12 @@ export default class Packages { return this.core .request('/api/packages/install', { method: 'post', - body - }); + headers: { + 'content-type': 'application/json' + }, + body: JSON.stringify(body) + }) + .then(response => response.json()); } /** From 46e895bb18d00f4b47135997321e2248eb62eac5 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sat, 11 Apr 2020 00:11:00 +0200 Subject: [PATCH 06/11] Added default package installation path (#106) --- src/packages.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/packages.js b/src/packages.js index 7bd6d8cb..df123f0b 100644 --- a/src/packages.js +++ b/src/packages.js @@ -342,11 +342,13 @@ export default class Packages { * @param {string} url URL to package * @param {options} [options] * @param {boolean} [options.system] Install as system package + * @param {string} [options.root] Root installation path */ install(url, options = {}) { const body = { url, options: Object.assign({}, { + root: 'home:/.packages', system: false }, options) }; From ec4bbb2664f15bb5433dbbe52bc181d4753ae7a6 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sat, 11 Apr 2020 00:11:16 +0200 Subject: [PATCH 07/11] Reload package manifest on user package installation (#106) --- src/packages.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/packages.js b/src/packages.js index df123f0b..fb1fbe2b 100644 --- a/src/packages.js +++ b/src/packages.js @@ -361,7 +361,12 @@ export default class Packages { }, body: JSON.stringify(body) }) - .then(response => response.json()); + .then(response => response.json()) + .then((body) => { + if (body.reload) { + this.init(); + } + }); } /** From d8e77ed37d453a85852aa5b253df6793686e4269 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sat, 11 Apr 2020 00:21:39 +0200 Subject: [PATCH 08/11] Added Packages#uninstall (#106) --- src/packages.js | 67 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/src/packages.js b/src/packages.js index fb1fbe2b..d9be22da 100644 --- a/src/packages.js +++ b/src/packages.js @@ -55,6 +55,21 @@ import logger from './logger'; * @typedef PackageMetadata */ +/** + * @property {string} root Installation root (except on system) + * @property {boolean} [system] Install on system + * @property {object} [headers] Forward HTTP headers + * @typedef PackageInstallationOption + */ + +/** + * @return {PackageInstallationOption} + */ +const createPackageInstallationOptions = options => Object.assign({}, { + root: 'home:/.packages', + system: false +}, options); + /** * Package Manager * @@ -337,36 +352,56 @@ export default class Packages { [...meta, ...configured].forEach(({name, args}) => this.launch(name, args || {})); } + /** + * Uninstalls a package + * @param {string} name Package name + * @param {PackageInstallationOption} [options] + */ + uninstall(name, options = {}) { + return this._apiRequest('uninstall', { + name, + options: createPackageInstallationOptions(options) + }) + .then((body) => { + if (body.reload) { + this.init(); + } + }); + } + /** * Installs a package * @param {string} url URL to package - * @param {options} [options] - * @param {boolean} [options.system] Install as system package - * @param {string} [options.root] Root installation path + * @param {PackageInstallationOption} [options] */ install(url, options = {}) { - const body = { + return this._apiRequest('install', { url, - options: Object.assign({}, { - root: 'home:/.packages', - system: false - }, options) - }; + options: createPackageInstallationOptions(options) + }) + .then((body) => { + if (body.reload) { + this.init(); + } + }); + } + /** + * Creates a new API request + * @param {string} endpoint + * @param {object} body + * @return {object} JSON + */ + _apiRequest(endpoint, body) { return this.core - .request('/api/packages/install', { + .request(`/api/packages/${endpoint}`, { method: 'post', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }) - .then(response => response.json()) - .then((body) => { - if (body.reload) { - this.init(); - } - }); + .then(response => response.json()); } /** From 2fb5b38ba08c700a8dce1077e20a09468ed7681e Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sat, 11 Apr 2020 00:40:34 +0200 Subject: [PATCH 09/11] Updated server metadata fetch URI (#106) --- src/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.js b/src/config.js index b513a620..560c72a7 100644 --- a/src/config.js +++ b/src/config.js @@ -70,7 +70,7 @@ export const defaultConfiguration = { }, packages: { - manifest: '/api/packages/manifest', + manifest: '/api/packages/metadata', vfsPaths: [ 'home:/.packages' ], From e6ffd5831d52c64e81392d8817feb5b879ddccf8 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sat, 11 Apr 2020 00:40:46 +0200 Subject: [PATCH 10/11] Updated unit tests (#106) --- __mocks__/setup.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/__mocks__/setup.js b/__mocks__/setup.js index cf0ec6da..4e8b03d4 100644 --- a/__mocks__/setup.js +++ b/__mocks__/setup.js @@ -28,6 +28,12 @@ class Worker { const noop = () => {}; +const dummyMetadata = [{ + name: 'ValidApplication', + mimes: ['valid/bazz'], + files: [] +}]; + const fetchMocks = { text: { @@ -46,11 +52,8 @@ const fetchMocks = { '/apps/Jest/test': true, - '/metadata.json': [{ - name: 'ValidApplication', - mimes: ['valid/bazz'], - files: [] - }], + '/metadata.json': dummyMetadata, + '/api/packages/metadata': dummyMetadata, '/settings': ({method}) => String(method).toLowerCase() === 'post' ? true From a7eeeeff5fc016ee68d7838792ecc6e97025f941 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sat, 11 Apr 2020 00:54:51 +0200 Subject: [PATCH 11/11] Abstracted some package management functionality (#106) --- src/packages.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/packages.js b/src/packages.js index d9be22da..d090252e 100644 --- a/src/packages.js +++ b/src/packages.js @@ -358,15 +358,7 @@ export default class Packages { * @param {PackageInstallationOption} [options] */ uninstall(name, options = {}) { - return this._apiRequest('uninstall', { - name, - options: createPackageInstallationOptions(options) - }) - .then((body) => { - if (body.reload) { - this.init(); - } - }); + return this._manageApiRequest('uninstall', options, {name}); } /** @@ -375,10 +367,20 @@ export default class Packages { * @param {PackageInstallationOption} [options] */ install(url, options = {}) { - return this._apiRequest('install', { - url, + return this._manageApiRequest('install', options, {url}); + } + + /** + * Creates a new API request for package management + * @param {string} endpoint + * @param {object} body + * @param {object} append + * @return {object} JSON + */ + _manageApiRequest(endpoint, options, append) { + return this._apiRequest(endpoint, Object.assign({ options: createPackageInstallationOptions(options) - }) + }, append)) .then((body) => { if (body.reload) { this.init();