UNPKG

3.98 kBJavaScriptView Raw
1/*
2 * OS.js - JavaScript Cloud/Web Desktop Platform
3 *
4 * Copyright (c) 2011-2020, Anders Evenrud <andersevenrud@gmail.com>
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 <andersevenrud@gmail.com>
28 * @licence Simplified BSD License
29 */
30
31const path = require('path');
32const chokidar = require('chokidar');
33
34/**
35 * OS.js Package Abstraction
36 */
37class Package {
38
39 /**
40 * Create new instance
41 * @param {Core} core Core reference
42 * @param {object} [options] Instance options
43 */
44 constructor(core, options = {}) {
45 this.core = core;
46
47 this.script = options.metadata.server
48 ? path.resolve(path.dirname(options.filename), options.metadata.server)
49 : null;
50
51 this.filename = options.filename;
52 this.metadata = options.metadata;
53 this.handler = null;
54 this.watcher = null;
55 }
56
57 /**
58 * Destroys instance
59 */
60 async destroy() {
61 this.action('destroy');
62
63 if (this.watcher) {
64 await this.watcher.close();
65 this.watcher = null;
66 }
67 }
68
69 /**
70 * Run method on package script
71 * @param {string} method Method name
72 * @param {*} [...args] Pass arguments
73 * @return {boolean}
74 */
75 action(method, ...args) {
76 try {
77 if (this.handler && typeof this.handler[method] === 'function') {
78 this.handler[method](...args);
79
80 return true;
81 }
82 } catch (e) {
83 this.core.logger.warn(e);
84 }
85
86 return false;
87 }
88
89 /**
90 * Validates this package
91 * @param {object[]} manifest Global manifest
92 * @return {boolean}
93 */
94 validate(manifest) {
95 return this.script &&
96 this.metadata &&
97 !!manifest.find(iter => iter.name === this.metadata.name);
98 }
99
100 /**
101 * Initializes this package
102 * @return {Promise<undefined>}
103 */
104 init() {
105 const handler = require(this.script);
106
107 this.handler = handler(this.core, this);
108
109 if (typeof this.handler.init === 'function') {
110 return this.handler.init();
111 }
112
113 return Promise.resolve();
114 }
115
116 /**
117 * Starts server scripts
118 * @return {Promise<undefined>}
119 */
120 start() {
121 return this.action('start');
122 }
123
124 /**
125 * Creates a watch in package dist
126 * @return {string} Watched path
127 */
128 watch(cb) {
129 const pub = this.core.config('public');
130 const dist = path.join(pub, 'apps', this.metadata.name);
131
132 this.watcher = chokidar.watch(dist);
133 this.watcher.on('change', () => cb(this.metadata));
134
135 return dist;
136 }
137
138 /**
139 * Resolve an URL for resource
140 * @param {string} path Input path
141 * @return {string}
142 */
143 resource(path) {
144 if (path.substr(0, 1) !== '/') {
145 path = '/' + path;
146 }
147
148 return `/apps/${this.metadata.name}${path}`;
149 }
150}
151
152module.exports = Package;