Browse Source

moved stuff

master
Daniel Hübleitner 2 years ago
parent
commit
0c38130296
4 changed files with 444 additions and 354 deletions
  1. 93
    7
      package-lock.json
  2. 1
    0
      package.json
  3. 350
    0
      src/backend/Extension.ts
  4. 0
    347
      src/backend/UpdateManger.ts

+ 93
- 7
package-lock.json View File

@@ -733,6 +733,21 @@
733 733
         "qs": "6.7.0",
734 734
         "raw-body": "2.4.0",
735 735
         "type-is": "~1.6.17"
736
+      },
737
+      "dependencies": {
738
+        "debug": {
739
+          "version": "2.6.9",
740
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
741
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
742
+          "requires": {
743
+            "ms": "2.0.0"
744
+          }
745
+        },
746
+        "ms": {
747
+          "version": "2.0.0",
748
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
749
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
750
+        }
736 751
       }
737 752
     },
738 753
     "brace-expansion": {
@@ -1362,11 +1377,11 @@
1362 1377
       "dev": true
1363 1378
     },
1364 1379
     "debug": {
1365
-      "version": "2.6.9",
1366
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1367
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1380
+      "version": "4.1.1",
1381
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
1382
+      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
1368 1383
       "requires": {
1369
-        "ms": "2.0.0"
1384
+        "ms": "^2.1.1"
1370 1385
       }
1371 1386
     },
1372 1387
     "decamelize": {
@@ -1675,6 +1690,14 @@
1675 1690
         "to-regex": "^3.0.1"
1676 1691
       },
1677 1692
       "dependencies": {
1693
+        "debug": {
1694
+          "version": "2.6.9",
1695
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1696
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1697
+          "requires": {
1698
+            "ms": "2.0.0"
1699
+          }
1700
+        },
1678 1701
         "define-property": {
1679 1702
           "version": "0.2.5",
1680 1703
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
@@ -1690,6 +1713,11 @@
1690 1713
           "requires": {
1691 1714
             "is-extendable": "^0.1.0"
1692 1715
           }
1716
+        },
1717
+        "ms": {
1718
+          "version": "2.0.0",
1719
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1720
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
1693 1721
         }
1694 1722
       }
1695 1723
     },
@@ -1736,6 +1764,21 @@
1736 1764
         "type-is": "~1.6.18",
1737 1765
         "utils-merge": "1.0.1",
1738 1766
         "vary": "~1.1.2"
1767
+      },
1768
+      "dependencies": {
1769
+        "debug": {
1770
+          "version": "2.6.9",
1771
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1772
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1773
+          "requires": {
1774
+            "ms": "2.0.0"
1775
+          }
1776
+        },
1777
+        "ms": {
1778
+          "version": "2.0.0",
1779
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1780
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
1781
+        }
1739 1782
       }
1740 1783
     },
1741 1784
     "extend": {
@@ -1875,6 +1918,21 @@
1875 1918
         "parseurl": "~1.3.3",
1876 1919
         "statuses": "~1.5.0",
1877 1920
         "unpipe": "~1.0.0"
1921
+      },
1922
+      "dependencies": {
1923
+        "debug": {
1924
+          "version": "2.6.9",
1925
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1926
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1927
+          "requires": {
1928
+            "ms": "2.0.0"
1929
+          }
1930
+        },
1931
+        "ms": {
1932
+          "version": "2.0.0",
1933
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1934
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
1935
+        }
1878 1936
       }
1879 1937
     },
1880 1938
     "find-cache-dir": {
@@ -3864,9 +3922,9 @@
3864 3922
       }
3865 3923
     },
3866 3924
     "ms": {
3867
-      "version": "2.0.0",
3868
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
3869
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
3925
+      "version": "2.1.2",
3926
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
3927
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
3870 3928
     },
3871 3929
     "mysql": {
3872 3930
       "version": "2.17.1",
@@ -4984,6 +5042,21 @@
4984 5042
         "statuses": "~1.5.0"
4985 5043
       },
4986 5044
       "dependencies": {
5045
+        "debug": {
5046
+          "version": "2.6.9",
5047
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
5048
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
5049
+          "requires": {
5050
+            "ms": "2.0.0"
5051
+          },
5052
+          "dependencies": {
5053
+            "ms": {
5054
+              "version": "2.0.0",
5055
+              "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
5056
+              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
5057
+            }
5058
+          }
5059
+        },
4987 5060
         "ms": {
4988 5061
           "version": "2.1.1",
4989 5062
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
@@ -5118,6 +5191,14 @@
5118 5191
         "use": "^3.1.0"
5119 5192
       },
5120 5193
       "dependencies": {
5194
+        "debug": {
5195
+          "version": "2.6.9",
5196
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
5197
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
5198
+          "requires": {
5199
+            "ms": "2.0.0"
5200
+          }
5201
+        },
5121 5202
         "define-property": {
5122 5203
           "version": "0.2.5",
5123 5204
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
@@ -5134,6 +5215,11 @@
5134 5215
             "is-extendable": "^0.1.0"
5135 5216
           }
5136 5217
         },
5218
+        "ms": {
5219
+          "version": "2.0.0",
5220
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
5221
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
5222
+        },
5137 5223
         "source-map": {
5138 5224
           "version": "0.5.7",
5139 5225
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",

+ 1
- 0
package.json View File

@@ -24,6 +24,7 @@
24 24
     "bsert": "0.0.10",
25 25
     "bsock": "^0.1.9",
26 26
     "child-process-promise": "^2.2.1",
27
+    "debug": "^4.1.1",
27 28
     "express": "^4.16.4",
28 29
     "frontblock": "^0.14.0",
29 30
     "frontblock-generic": "^0.30.1",

+ 350
- 0
src/backend/Extension.ts View File

@@ -0,0 +1,350 @@
1
+
2
+import * as Logger from 'log4js'
3
+import * as path from "path";
4
+import { promises as fs } from "fs"
5
+import * as git from "simple-git/promise"
6
+import * as trash from "trash"
7
+
8
+
9
+Logger.configure({
10
+    appenders: 
11
+    {
12
+    "admin/extension": { type: 'stdout' },
13
+    //app: { type: 'file', filename: 'application.log' }
14
+    },
15
+    categories: 
16
+    {
17
+    default: { appenders: [ 'admin/extension' ], level: 'debug' }
18
+    }
19
+})
20
+const exec = require('child-process-promise').exec;
21
+const logger = Logger.getLogger("admin/updatemanager") 
22
+
23
+type SharedStatus = {
24
+    name: string
25
+    installed?: boolean
26
+    outdated?: boolean
27
+}
28
+
29
+abstract class Extension<Status extends SharedStatus>{
30
+    constructor(
31
+        protected name: string
32
+    ){}
33
+
34
+    /**
35
+     * the generic Status object
36
+     */
37
+    protected async status():Promise<Status>{
38
+        const installed = await this.isInstalled()
39
+        const outdated = await this.isOutdated()
40
+        return <Status>{ name: this.name, installed: installed, outdated: outdated }
41
+    }
42
+
43
+    /**
44
+     * true => extension was installed
45
+     * false => extension was not install
46
+     * undefined => signals error
47
+     */
48
+    abstract async install():Promise<boolean | undefined>
49
+
50
+    /**
51
+     * reverts the install procedure
52
+     */
53
+    abstract async uninstall():Promise<void>
54
+
55
+    /**
56
+     * true => an update was performed
57
+     * false => no update was performed
58
+     * undefined => signals error
59
+     */
60
+    abstract async update(force?: boolean): Promise<boolean | undefined>
61
+
62
+    /**
63
+     * true => update would install a newer version
64
+     * false => nothing would be updated if update would be performed
65
+     * undefined => signals error
66
+     */
67
+    abstract async isOutdated():Promise<boolean | undefined>
68
+
69
+    /**
70
+     * promises a boolean
71
+     * true => install would do nothing would it be called
72
+     * false => install would try to install the newest extension
73
+     * undefined => signals error
74
+     */
75
+    abstract async isInstalled():Promise<boolean | undefined>
76
+}
77
+
78
+export type FSStatus = SharedStatus & {
79
+    prefix: string 
80
+    empty?: boolean
81
+}
82
+
83
+export abstract class FSExtension<Status extends FSStatus> extends Extension<Status>{
84
+    constructor(
85
+        name: string, 
86
+        protected readonly prefix: string){
87
+            super(name)
88
+    }
89
+
90
+    public async status(): Promise<Status>{
91
+        const shdStatus = await super.status()
92
+        const empty = await this.isEmpty()
93
+        return <Status>{...shdStatus, prefix: this.prefix, empty: empty}
94
+    }
95
+
96
+    public async install():Promise<boolean>{
97
+        const installed = await this.isInstalled()
98
+        if (!installed) {
99
+            logger.info('Installing extension to', path.resolve(this.prefix, this.name))
100
+            await fs.mkdir(path.resolve(this.prefix, this.name), {recursive: true})
101
+            return true
102
+        }
103
+        logger.warn('Extension already installed at', path.resolve(this.prefix, this.name))
104
+        return false
105
+    }
106
+
107
+    public async uninstall(): Promise<void>{
108
+        logger.info('Uninstalling extension from', path.resolve(this.prefix, this.name))
109
+        return await trash(path.resolve(this.prefix, this.name))
110
+    }
111
+
112
+    public async update(force?: boolean): Promise<boolean | undefined>{
113
+        if (force) await this.uninstall()
114
+        return await this.install()
115
+    }
116
+
117
+    public async isEmpty(): Promise<boolean | undefined>{
118
+        if (!this.isInstalled()) return true
119
+        try {
120
+            const files = await fs.readdir(path.resolve(this.prefix, this.name))
121
+            return files.length === 0
122
+        } catch (error) {
123
+            logger.warn('TODO')
124
+            return
125
+        }
126
+    }
127
+
128
+    public async isInstalled(): Promise<boolean>{
129
+        try {
130
+            await fs.access(path.resolve(this.prefix, this.name))
131
+            return true
132
+        } catch (error) {
133
+            return false
134
+        }
135
+    }
136
+}
137
+
138
+type NPMStatus = FSStatus & {
139
+    latest?: string,
140
+    current?: string,
141
+    author?: string
142
+}
143
+
144
+export class NPMExtension extends FSExtension<NPMStatus>{
145
+
146
+    constructor(
147
+        pkgName: string,
148
+        prefix: string){
149
+        super(pkgName, prefix)
150
+    }
151
+
152
+    public async status(): Promise<NPMStatus> {
153
+
154
+        const fsStatus = await super.status()
155
+        const latest = await this.getLatestVersion()
156
+        const author = await this.getAuthor()
157
+        const current = await this.getCurrentVersion()
158
+        return {  
159
+            ...fsStatus, 
160
+            latest: latest,
161
+            author: author,
162
+            current: current
163
+        }
164
+    }
165
+
166
+    public async install(): Promise<boolean> {
167
+        super.install()
168
+        logger.info("npm install", this.name, 'to', path.resolve(this.prefix, this.name))
169
+        const { error, stdout, stderr } = await exec('npm install --prefix '+ this.prefix + ' ' + this.name)
170
+        if (error !== null) {
171
+            logger.warn('npm install', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
172
+            return false
173
+        } else {
174
+            logger.info('npm install', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
175
+            return true
176
+        }
177
+    }
178
+    
179
+    public async uninstall(force?: boolean): Promise<void> {
180
+        super.uninstall()
181
+        logger.info("npm uninstall", this.name, 'from', path.resolve(this.prefix, this.name))
182
+        const { error, stdout, stderr } = await exec('npm uninstall --prefix '+ this.prefix + ' ' + this.name)
183
+        if (error) {
184
+            logger.warn('npm uninstall', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
185
+        } else {
186
+            logger.info('npm uninstall', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
187
+        }
188
+    }
189
+
190
+    public async update(force?: boolean): Promise<boolean> {
191
+        super.update(force)
192
+        logger.info("npm update", path.resolve(this.prefix, this.name))
193
+        const { error, stdout, stderr } = await exec('npm update --prefix '+ this.prefix + ' ' + this.name)
194
+        if (error) {
195
+            logger.warn('npm update', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
196
+            return false
197
+        } else {
198
+            logger.info('npm update', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
199
+            return true
200
+        }
201
+    }
202
+
203
+    public async isOutdated(): Promise<boolean | undefined> {
204
+        try {
205
+            const { 
206
+                error, 
207
+                stdout, 
208
+                stderr } = await exec('npm outdated --prefix ' + this.prefix + " --json" + ' ' + this.name)
209
+            if (error) throw new Error(stderr)
210
+            if (Object.keys(JSON.parse(stdout)).length > 0) return true
211
+            else return false
212
+        } catch (error) {
213
+            logger.warn('npm outdated', this.name, 'from prefix', this.prefix, 'stderr:', error)
214
+            return
215
+        }
216
+    }
217
+
218
+    private async getAuthor(): Promise<string | undefined>{
219
+        const { 
220
+            error, 
221
+            stdout, 
222
+            stderr } = await exec('npm author ls --prefix ' + this.prefix + ' ' + this.name)
223
+
224
+        if(error){
225
+            logger.warn(stderr)
226
+            return
227
+        } else {
228
+            logger.info(stdout)
229
+            return stdout
230
+        }
231
+    }
232
+
233
+    private async getLatestVersion(): Promise<string | undefined>{
234
+        const { 
235
+            error, 
236
+            stdout, 
237
+            stderr } = await exec('npm view --prefix ' + this.prefix + ' ' + this.name + " version")
238
+
239
+        if(error){
240
+            logger.warn(stderr)
241
+            return
242
+        } else {
243
+            logger.info(stdout)
244
+            return stdout
245
+        }
246
+    }
247
+
248
+    private async getCurrentVersion(): Promise<string | undefined>{
249
+        return //TODO
250
+    }
251
+}
252
+
253
+export type GitStatus = FSStatus & {
254
+    branch?: string
255
+    remote?: string
256
+    latest?: string
257
+}
258
+
259
+export class GitExtension<Status extends GitStatus> extends FSExtension<Status>{
260
+    protected repo: git.SimpleGit
261
+    constructor(
262
+        repoName:string,
263
+        localPrefix:string,
264
+        protected gitCloneURL: string,
265
+        protected credentials?: [string, string]
266
+    ){
267
+        super(repoName, localPrefix)
268
+    }
269
+
270
+    public async status(): Promise<Status>{
271
+        const fsStatus = await super.status()
272
+
273
+        return {  
274
+            ...fsStatus, 
275
+            branch: 'wat',
276
+            remote: this.gitCloneURL,
277
+            latest: 'kek'
278
+        }
279
+    }
280
+
281
+    public async install(): Promise<boolean> {
282
+        if (super.install()){
283
+            if (this.credentials){
284
+
285
+            } else {
286
+
287
+            }
288
+        } else {
289
+
290
+        }
291
+    }
292
+    
293
+
294
+    public async update(): Promise<boolean> {
295
+        return true // do git pull remote origin && git checkout 
296
+    }
297
+
298
+    public async isOutdated(): Promise<boolean> {
299
+        return true
300
+    }
301
+}
302
+
303
+export type PluginStatus = GitStatus & {
304
+    hasFrontend: boolean,
305
+    hasBackend: boolean,
306
+    isFrontendLoaded: boolean,
307
+    isBackendLoaded: boolean
308
+}
309
+
310
+export class PluginExtension<Status extends GitStatus> extends GitExtension<Status> {
311
+    protected frontendLoaded: boolean
312
+    protected backendLoaded: boolean
313
+
314
+    constructor(
315
+        pluginName: string,
316
+        gitCloneURL: string,
317
+        localPrefix: string = './plugins',
318
+        credentials?: [string, string],
319
+        protected hasBackend: boolean = true,
320
+        protected hasFrontend: boolean = true){
321
+        super(pluginName,localPrefix,gitCloneURL,credentials)
322
+    }
323
+
324
+    public async load(): Promise<void>{
325
+        if (this.hasFrontend) await this.loadFrontend()
326
+        if (this.hasBackend) await this.loadBackend()
327
+    }
328
+
329
+    public async loadFrontend(): Promise<void>{
330
+        return //TODO
331
+    }
332
+
333
+    public async loadBackend(): Promise<void>{
334
+        return //TODO
335
+    }
336
+
337
+    public async unload(): Promise<void>{
338
+        if (this.hasFrontend) await this.unloadFrontend()
339
+        if (this.hasBackend) await this.unloadBackend()
340
+    }
341
+
342
+    public async unloadFrontend(): Promise<void>{
343
+        return //TODO
344
+    }
345
+
346
+    public async unloadBackend(): Promise<void>{
347
+        return //TODO
348
+    }
349
+
350
+}

+ 0
- 347
src/backend/UpdateManger.ts View File

@@ -28,353 +28,6 @@ Logger.configure({
28 28
 })
29 29
 const logger = Logger.getLogger("admin/updatemanager") 
30 30
 
31
-/* 
32
-cool snibbet
33
-
34
-const SharedStatus = <Status>
35
-    (privateStatus: Status) =>
36
-    (name: string) => 
37
-    (installed: boolean) => 
38
-    (outdated: boolean) => 
39
-    { 
40
-        return {
41
-            name: name,
42
-            installed: installed,
43
-            outdated: outdated,
44
-            ...privateStatus
45
-        } 
46
-    }
47
-*/
48
-
49
-type SharedStatus = {
50
-    name: string
51
-    installed?: boolean
52
-    outdated?: boolean
53
-}
54
-
55
-abstract class Extension<Status extends SharedStatus>{
56
-    constructor(
57
-        protected name: string
58
-    ){}
59
-
60
-    /**
61
-     * the generic Status object
62
-     */
63
-    protected async status():Promise<Status>{
64
-        const installed = await this.isInstalled()
65
-        const outdated = await this.isOutdated()
66
-        return <Status>{ name: this.name, installed: installed, outdated: outdated }
67
-    }
68
-
69
-    /**
70
-     * true => extension was installed
71
-     * false => extension was not install
72
-     * undefined => signals error
73
-     */
74
-    abstract async install():Promise<boolean | undefined>
75
-
76
-    /**
77
-     * reverts the install procedure
78
-     */
79
-    abstract async uninstall():Promise<void>
80
-
81
-    /**
82
-     * true => an update was performed
83
-     * false => no update was performed
84
-     * undefined => signals error
85
-     */
86
-    abstract async update(force?: boolean): Promise<boolean | undefined>
87
-
88
-    /**
89
-     * true => update would install a newer version
90
-     * false => nothing would be updated if update would be performed
91
-     * undefined => signals error
92
-     */
93
-    abstract async isOutdated():Promise<boolean | undefined>
94
-
95
-    /**
96
-     * promises a boolean
97
-     * true => install would do nothing would it be called
98
-     * false => install would try to install the newest extension
99
-     * undefined => signals error
100
-     */
101
-    abstract async isInstalled():Promise<boolean | undefined>
102
-}
103
-
104
-export type FSStatus = SharedStatus & {
105
-    prefix: string 
106
-    empty?: boolean
107
-}
108
-
109
-export abstract class FSExtension<Status extends FSStatus> extends Extension<Status>{
110
-    constructor(
111
-        name: string, 
112
-        protected readonly prefix: string){
113
-            super(name)
114
-    }
115
-
116
-    public async status(): Promise<Status>{
117
-        const shdStatus = await super.status()
118
-        const empty = await this.isEmpty()
119
-        return <Status>{...shdStatus, prefix: this.prefix, empty: empty}
120
-    }
121
-
122
-    public async install():Promise<boolean>{
123
-        const installed = await this.isInstalled()
124
-        if (!installed) {
125
-            logger.info('Installing extension to', path.resolve(this.prefix, this.name))
126
-            await fs.mkdir(path.resolve(this.prefix, this.name), {recursive: true})
127
-            return true
128
-        }
129
-        logger.warn('Extension already installed at', path.resolve(this.prefix, this.name))
130
-        return false
131
-    }
132
-
133
-    public async uninstall(): Promise<void>{
134
-        logger.info('Uninstalling extension from', path.resolve(this.prefix, this.name))
135
-        return await trash(path.resolve(this.prefix, this.name))
136
-    }
137
-
138
-    public async update(force?: boolean): Promise<boolean | undefined>{
139
-        if (force) await this.uninstall()
140
-        return await this.install()
141
-    }
142
-
143
-    public async isEmpty(): Promise<boolean | undefined>{
144
-        if (!this.isInstalled()) return true
145
-        try {
146
-            const files = await fs.readdir(path.resolve(this.prefix, this.name))
147
-            return files.length === 0
148
-        } catch (error) {
149
-            logger.warn('TODO')
150
-            return
151
-        }
152
-    }
153
-
154
-    public async isInstalled(): Promise<boolean>{
155
-        try {
156
-            await fs.access(path.resolve(this.prefix, this.name))
157
-            return true
158
-        } catch (error) {
159
-            return false
160
-        }
161
-    }
162
-}
163
-
164
-type NPMStatus = FSStatus & {
165
-    latest?: string,
166
-    current?: string,
167
-    author?: string
168
-}
169
-
170
-export class NPMExtension extends FSExtension<NPMStatus>{
171
-
172
-    constructor(
173
-        pkgName: string,
174
-        prefix: string){
175
-        super(pkgName, prefix)
176
-    }
177
-
178
-    public async status(): Promise<NPMStatus> {
179
-
180
-        const fsStatus = await super.status()
181
-        const latest = await this.getLatestVersion()
182
-        const author = await this.getAuthor()
183
-        const current = await this.getCurrentVersion()
184
-        return {  
185
-            ...fsStatus, 
186
-            latest: latest,
187
-            author: author,
188
-            current: current
189
-        }
190
-    }
191
-
192
-    public async install(): Promise<boolean> {
193
-        super.install()
194
-        logger.info("npm install", this.name, 'to', path.resolve(this.prefix, this.name))
195
-        const { error, stdout, stderr } = await exec('npm install --prefix '+ this.prefix + ' ' + this.name)
196
-        if (error !== null) {
197
-            logger.warn('npm install', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
198
-            return false
199
-        } else {
200
-            logger.info('npm install', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
201
-            return true
202
-        }
203
-    }
204
-    
205
-    public async uninstall(force?: boolean): Promise<void> {
206
-        super.uninstall()
207
-        logger.info("npm uninstall", this.name, 'from', path.resolve(this.prefix, this.name))
208
-        const { error, stdout, stderr } = await exec('npm uninstall --prefix '+ this.prefix + ' ' + this.name)
209
-        if (error) {
210
-            logger.warn('npm uninstall', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
211
-        } else {
212
-            logger.info('npm uninstall', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
213
-        }
214
-    }
215
-
216
-    public async update(force?: boolean): Promise<boolean> {
217
-        super.update(force)
218
-        logger.info("npm update", path.resolve(this.prefix, this.name))
219
-        const { error, stdout, stderr } = await exec('npm update --prefix '+ this.prefix + ' ' + this.name)
220
-        if (error) {
221
-            logger.warn('npm update', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
222
-            return false
223
-        } else {
224
-            logger.info('npm update', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
225
-            return true
226
-        }
227
-    }
228
-
229
-    public async isOutdated(): Promise<boolean | undefined> {
230
-        try {
231
-            const { 
232
-                error, 
233
-                stdout, 
234
-                stderr } = await exec('npm outdated --prefix ' + this.prefix + " --json" + ' ' + this.name)
235
-            if (error) throw new Error(stderr)
236
-            if (Object.keys(JSON.parse(stdout)).length > 0) return true
237
-            else return false
238
-        } catch (error) {
239
-            logger.warn('npm outdated', this.name, 'from prefix', this.prefix, 'stderr:', error)
240
-            return
241
-        }
242
-    }
243
-
244
-    private async getAuthor(): Promise<string | undefined>{
245
-        const { 
246
-            error, 
247
-            stdout, 
248
-            stderr } = await exec('npm author ls --prefix ' + this.prefix + ' ' + this.name)
249
-
250
-        if(error){
251
-            logger.warn(stderr)
252
-            return
253
-        } else {
254
-            logger.info(stdout)
255
-            return stdout
256
-        }
257
-    }
258
-
259
-    private async getLatestVersion(): Promise<string | undefined>{
260
-        const { 
261
-            error, 
262
-            stdout, 
263
-            stderr } = await exec('npm view --prefix ' + this.prefix + ' ' + this.name + " version")
264
-
265
-        if(error){
266
-            logger.warn(stderr)
267
-            return
268
-        } else {
269
-            logger.info(stdout)
270
-            return stdout
271
-        }
272
-    }
273
-
274
-    private async getCurrentVersion(): Promise<string | undefined>{
275
-        return //TODO
276
-    }
277
-}
278
-
279
-export type GitStatus = FSStatus & {
280
-    branch?: string
281
-    remote?: string
282
-    latest?: string
283
-}
284
-
285
-export class GitExtension<Status extends GitStatus> extends FSExtension<Status>{
286
-    protected repo: git.SimpleGit
287
-    constructor(
288
-        repoName:string,
289
-        localPrefix:string,
290
-        protected gitCloneURL: string,
291
-        protected credentials?: [string, string]
292
-    ){
293
-        super(repoName, localPrefix)
294
-    }
295
-
296
-    public async status(): Promise<Status>{
297
-        const fsStatus = await super.status()
298
-
299
-        return {  
300
-            ...fsStatus, 
301
-            branch: 'wat',
302
-            remote: this.gitCloneURL,
303
-            latest: 'kek'
304
-        }
305
-    }
306
-
307
-    public async install(): Promise<boolean> {
308
-        if (super.install()){
309
-            if (this.credentials){
310
-
311
-            } else {
312
-
313
-            }
314
-        } else {
315
-
316
-        }
317
-    }
318
-    
319
-
320
-    public async update(): Promise<boolean> {
321
-        return true // do git pull remote origin && git checkout 
322
-    }
323
-
324
-    public async isOutdated(): Promise<boolean> {
325
-        return true
326
-    }
327
-}
328
-
329
-export type PluginStatus = GitStatus & {
330
-    hasFrontend: boolean,
331
-    hasBackend: boolean,
332
-    isFrontendLoaded: boolean,
333
-    isBackendLoaded: boolean
334
-}
335
-
336
-export class PluginExtension<Status extends GitStatus> extends GitExtension<Status> {
337
-    protected frontendLoaded: boolean
338
-    protected backendLoaded: boolean
339
-
340
-    constructor(
341
-        pluginName: string,
342
-        gitCloneURL: string,
343
-        localPrefix: string = './plugins',
344
-        credentials?: [string, string],
345
-        protected hasBackend: boolean = true,
346
-        protected hasFrontend: boolean = true){
347
-        super(pluginName,localPrefix,gitCloneURL,credentials)
348
-    }
349
-
350
-    public async load(): Promise<void>{
351
-        if (this.hasFrontend) await this.loadFrontend()
352
-        if (this.hasBackend) await this.loadBackend()
353
-    }
354
-
355
-    public async loadFrontend(): Promise<void>{
356
-        return //TODO
357
-    }
358
-
359
-    public async loadBackend(): Promise<void>{
360
-        return //TODO
361
-    }
362
-
363
-    public async unload(): Promise<void>{
364
-        if (this.hasFrontend) await this.unloadFrontend()
365
-        if (this.hasBackend) await this.unloadBackend()
366
-    }
367
-
368
-    public async unloadFrontend(): Promise<void>{
369
-        return //TODO
370
-    }
371
-
372
-    public async unloadBackend(): Promise<void>{
373
-        return //TODO
374
-    }
375
-
376
-}
377
-
378 31
 export class UpdateManager extends Plugin{
379 32
     
380 33
     private loadedPlugins:{[name in string]:Plugin} = {}

Loading…
Cancel
Save