Skip to content

Commit fc8277c

Browse files
committed
Abstracted package manager utility functions (#28)
1 parent a4cb9c2 commit fc8277c

File tree

3 files changed

+95
-40
lines changed

3 files changed

+95
-40
lines changed

src/packages.js

+15-29
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,17 @@ const fs = require('fs-extra');
3232
const fg = require('fast-glob');
3333
const path = require('path');
3434
const consola = require('consola');
35-
const bent = require('bent');
36-
const tar = require('tar');
3735
const Package = require('./package.js');
3836
const {getPrefix} = require('./utils/vfs.js');
39-
const logger = consola.withTag('Packages');
40-
41-
const relative = filename => filename.replace(process.cwd(), '');
37+
const {
38+
relative,
39+
archiveName,
40+
fetchSteam,
41+
readOrDefault,
42+
extract
43+
} = require('./utils/packages.js');
4244

43-
const readOrDefault = filename => fs.existsSync(filename)
44-
? fs.readJsonSync(filename)
45-
: [];
46-
47-
const extract = (stream, target) => new Promise((resolve, reject) => {
48-
stream.once('end', () => resolve());
49-
stream.once('error', error => reject(error));
50-
stream.pipe(tar.extract({C: target}));
51-
});
45+
const logger = consola.withTag('Packages');
5246

5347
/**
5448
* @typedef InstallPackageOptions
@@ -156,30 +150,22 @@ class Packages {
156150
* @param {object} user
157151
*/
158152
async installPackage(url, options, user) {
153+
const {realpath} = this.core.make('osjs/vfs');
154+
159155
if (!options.root) {
160156
throw new Error('Missing package installation root path');
161157
}
162158

163-
const {realpath} = this.core.make('osjs/vfs');
164-
165-
const name = path.basename(url.split('?')[0])
166-
.replace(/\.[^/.]+$/, '');
167-
168-
const userRoot = options.root;
169-
const target = await realpath(`${userRoot}/${name}`, user);
159+
const name = archiveName(url);
160+
const target = await realpath(`${options.root}/${name}`, user);
170161

171162
if (await fs.exists(target)) {
172163
throw new Error('Target already exists');
173-
}
174-
175-
if (options.system) {
164+
} else if (options.system) {
176165
throw new Error('System packages not yet implemented');
177166
}
178167

179-
const stream = await bent()(url, null, {
180-
headers: options.headers || {}
181-
});
182-
168+
const stream = await fetchSteam(url, options);
183169
await fs.mkdir(target);
184170
await extract(stream, target);
185171

@@ -190,7 +176,7 @@ class Packages {
190176
throw new Error('Invalid package');
191177
}
192178

193-
await this.writeUserManifest(userRoot, user);
179+
await this.writeUserManifest(options.root, user);
194180

195181
return {
196182
reload: !options.system

src/providers/packages.js

+17-11
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,23 @@ class PackageServiceProvider extends ServiceProvider {
7878
res.status(400).json({error: 'Action failed'});
7979
});
8080

81-
routeAuthenticated('GET', '/api/packages/metadata', usingPackageManager((req, res) => {
82-
return this.packages.readPackageManifests(req.query.root || [], req.session.user);
83-
}));
84-
85-
routeAuthenticated('POST', '/api/packages/install', usingPackageManager((req, res) => {
86-
return this.packages.installPackage(req.body.url, req.body.options, req.session.user);
87-
}));
88-
89-
routeAuthenticated('POST', '/api/packages/uninstall', usingPackageManager((req, res) => {
90-
return this.packages.uninstallPackage(req.body.name, req.body.options, req.session.user);
91-
}));
81+
routeAuthenticated(
82+
'GET',
83+
'/api/packages/metadata',
84+
usingPackageManager(req => this.packages.readPackageManifests(req.query.root || [], req.session.user))
85+
);
86+
87+
routeAuthenticated(
88+
'POST',
89+
'/api/packages/install',
90+
usingPackageManager(req => this.packages.installPackage(req.body.url, req.body.options, req.session.user))
91+
);
92+
93+
routeAuthenticated(
94+
'POST',
95+
'/api/packages/uninstall',
96+
usingPackageManager(req => this.packages.uninstallPackage(req.body.name, req.body.options, req.session.user))
97+
);
9298

9399
return this.packages.init();
94100
}

src/utils/packages.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* OS.js - JavaScript Cloud/Web Desktop Platform
3+
*
4+
* Copyright (c) 2011-2020, Anders Evenrud <[email protected]>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice, this
11+
* list of conditions and the following disclaimer
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*
27+
* @author Anders Evenrud <[email protected]>
28+
* @licence Simplified BSD License
29+
*/
30+
31+
const bent = require('bent');
32+
const tar = require('tar');
33+
const path = require('path');
34+
const fs = require('fs-extra');
35+
36+
const relative = filename => filename
37+
.replace(process.cwd(), '');
38+
39+
const archiveName = url => path
40+
.basename(url.split('?')[0])
41+
.replace(/\.[^/.]+$/, '');
42+
43+
const fetchSteam = (url, options) => bent()(url, null, {
44+
headers: options.headers || {}
45+
});
46+
47+
const readOrDefault = filename => fs.existsSync(filename)
48+
? fs.readJsonSync(filename)
49+
: [];
50+
51+
const extract = (stream, target) => new Promise((resolve, reject) => {
52+
stream.once('end', () => resolve());
53+
stream.once('error', error => reject(error));
54+
stream.pipe(tar.extract({C: target}));
55+
});
56+
57+
module.exports = {
58+
relative,
59+
archiveName,
60+
fetchSteam,
61+
readOrDefault,
62+
extract
63+
};

0 commit comments

Comments
 (0)