Skip to content
Draft
13 changes: 8 additions & 5 deletions __mocks__/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ class Worker {

const noop = () => {};

const dummyMetadata = [{
name: 'ValidApplication',
mimes: ['valid/bazz'],
files: []
}];

const fetchMocks = {
text: {

Expand All @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ export const defaultConfiguration = {
},

packages: {
manifest: '/metadata.json',
manifest: '/api/packages/metadata',
vfsPaths: [
'home:/.packages'
],
metadata: []
},

Expand Down
76 changes: 75 additions & 1 deletion src/packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -134,8 +149,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))
Expand Down Expand Up @@ -333,6 +352,60 @@ 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._manageApiRequest('uninstall', options, {name});
}

/**
* Installs a package
* @param {string} url URL to package
* @param {PackageInstallationOption} [options]
*/
install(url, options = {}) {
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();
}
});
}

/**
* Creates a new API request
* @param {string} endpoint
* @param {object} body
* @return {object} JSON
*/
_apiRequest(endpoint, body) {
return this.core
.request(`/api/packages/${endpoint}`, {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(body)
})
.then(response => response.json());
}

/**
* Registers a package
*
Expand Down Expand Up @@ -369,6 +442,7 @@ export default class Packages {
if (list instanceof Array) {
const append = list
.map(iter => Object.assign({
_vfs: null,
type: 'application',
files: []
}, iter));
Expand Down
6 changes: 5 additions & 1 deletion src/utils/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ export const urlResolver = configuration => {
metadata.type === 'icons' ? 'icons' : 'apps'
);

url = `${type}/${metadata.name}${path}`;
if (metadata._vfs) {
url = `vfs/readfile?path=${encodeURIComponent(`${metadata._vfs}/${metadata.name}${path}`)}`;
} else {
url = `${type}/${metadata.name}${path}`;
}
}

return prefix
Expand Down