use reflect-metadata for decorators, fix npm version checker, support gzip and deflate in http
This commit is contained in:
parent
3337222bdf
commit
320e4cef84
15
package-lock.json
generated
15
package-lock.json
generated
@ -1,16 +1,17 @@
|
||||
{
|
||||
"name": "@squeebot/core",
|
||||
"version": "3.3.5",
|
||||
"version": "3.4.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@squeebot/core",
|
||||
"version": "3.3.5",
|
||||
"version": "3.4.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dateformat": "^4.5.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.11"
|
||||
},
|
||||
@ -1410,6 +1411,11 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/reflect-metadata": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
|
||||
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
|
||||
},
|
||||
"node_modules/regexpp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||
@ -2719,6 +2725,11 @@
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true
|
||||
},
|
||||
"reflect-metadata": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
|
||||
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@squeebot/core",
|
||||
"version": "3.4.1",
|
||||
"version": "3.5.0",
|
||||
"description": "Squeebot v3 core for the execution environment",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
@ -30,6 +30,7 @@
|
||||
"dependencies": {
|
||||
"dateformat": "^4.5.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.11"
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
import http, { RequestOptions } from 'http';
|
||||
import https from 'https';
|
||||
import fs from 'fs-extra';
|
||||
import { createGunzip, createInflate } from 'zlib';
|
||||
import { URL } from 'url';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
/**
|
||||
* Create an HTTP GET request.
|
||||
@ -87,11 +89,27 @@ export function httpGET(
|
||||
reject(new Error('Request took too long!'));
|
||||
}, 5000);
|
||||
|
||||
res.on('data', (chunk) => {
|
||||
let output: Readable = res;
|
||||
|
||||
// Decompress GZip
|
||||
if (res.headers['content-encoding'] === 'gzip') {
|
||||
const gzip = createGunzip();
|
||||
res.pipe(gzip);
|
||||
output = gzip;
|
||||
}
|
||||
|
||||
// Deflate
|
||||
if (res.headers['content-encoding'] === 'deflate') {
|
||||
const inflate = createInflate();
|
||||
res.pipe(inflate);
|
||||
output = inflate;
|
||||
}
|
||||
|
||||
output.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
output.on('end', () => {
|
||||
clearTimeout(reqTimeOut);
|
||||
|
||||
resolve(data || saveTo);
|
||||
|
@ -65,10 +65,10 @@ export class NPMExecutor {
|
||||
|
||||
const pkgRefSplit = pkg.split('@');
|
||||
const pkgFullName = (spi === 1 ? '@' : '') + pkgRefSplit[spi];
|
||||
const pkgVersion = this.removeVersionWildcard(pkgRefSplit[spi + 1]);
|
||||
const pkgVersion = this.removeVersionWildcard(pkgRefSplit[spi + 1]) || 'latest';
|
||||
const installedVersion = this.installed[pkgFullName];
|
||||
if (installedVersion && installedVersion !== 'latest' && pkgVersion !== 'latest') {
|
||||
const cardless = this.removeVersionWildcard(installedVersion);
|
||||
const cardless = this.removeVersionWildcard(installedVersion) as string;
|
||||
if (semver.lte(pkgVersion, cardless)) {
|
||||
return;
|
||||
}
|
||||
@ -101,7 +101,7 @@ export class NPMExecutor {
|
||||
await this.loadPackageFile();
|
||||
}
|
||||
|
||||
private removeVersionWildcard(str: string): string {
|
||||
return str.replace(/\^|>|=/, '');
|
||||
private removeVersionWildcard(str?: string): string | undefined {
|
||||
return str?.replace(/\^|>|=/, '');
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
/**
|
||||
* Automatically execute method on plugin initialization
|
||||
*/
|
||||
export function Auto(): (...args: any[]) => void {
|
||||
export function Auto() {
|
||||
return (
|
||||
target: any,
|
||||
propertyKey: string,
|
||||
descriptor: PropertyDescriptor,
|
||||
) => {
|
||||
descriptor.value.prototype.__autoexec = 1;
|
||||
let autorunners: Array<string> = Reflect.getMetadata('sb:autorunners', target);
|
||||
if (!autorunners) {
|
||||
Reflect.defineMetadata('sb:autorunners', autorunners = [], target);
|
||||
}
|
||||
autorunners.push(propertyKey);
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
/**
|
||||
* Declare this plugin as one that the user can configure.
|
||||
* @param defconf Default configuration
|
||||
*/
|
||||
export function Configurable(defconf: any): (...arg: any[]) => any {
|
||||
return (constructor: (...arg: any[]) => any): void => {
|
||||
constructor.prototype.__defconf = defconf;
|
||||
export function Configurable(defconf: any) {
|
||||
return (constructor: any): void => {
|
||||
Reflect.defineMetadata('sb:defconf', defconf, constructor);
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { Auto } from './auto';
|
||||
|
||||
/**
|
||||
* Fire the following method automatically when a dependency is (re)loaded.
|
||||
* @param dep Name of the dependency
|
||||
* @param dependency Name of the dependency
|
||||
*/
|
||||
export function DependencyLoad(dep: string): (...args: any[]) => void {
|
||||
export function DependencyLoad(dependency: string) {
|
||||
return (
|
||||
target: any,
|
||||
propertyKey: string,
|
||||
@ -17,23 +18,23 @@ export function DependencyLoad(dep: string): (...args: any[]) => void {
|
||||
return;
|
||||
}
|
||||
const nameof = plugin.manifest.name;
|
||||
if (nameof !== dep) {
|
||||
if (nameof !== dependency) {
|
||||
return;
|
||||
}
|
||||
originalMethod.call(self, plugin);
|
||||
});
|
||||
};
|
||||
// Set the function to be autoexecuted when the plugin is initialized.
|
||||
descriptor.value.prototype.__autoexec = 1;
|
||||
Auto()(target, propertyKey, descriptor);
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire the following method automatically when a dependency is unloaded.
|
||||
* @param dep Name of the dependency
|
||||
* @param dependency Name of the dependency
|
||||
*/
|
||||
export function DependencyUnload(dep: string): (...args: any[]) => void {
|
||||
export function DependencyUnload(dependency: string) {
|
||||
return (
|
||||
target: any,
|
||||
propertyKey: string,
|
||||
@ -47,13 +48,14 @@ export function DependencyUnload(dep: string): (...args: any[]) => void {
|
||||
if (typeof plugin !== 'string') {
|
||||
nameof = plugin.manifest.name;
|
||||
}
|
||||
if (nameof !== dep) {
|
||||
if (nameof !== dependency) {
|
||||
return;
|
||||
}
|
||||
originalMethod.call(self, plugin);
|
||||
});
|
||||
};
|
||||
descriptor.value.prototype.__autoexec = 1;
|
||||
// Set the function to be autoexecuted when the plugin is initialized.
|
||||
Auto()(target, propertyKey, descriptor);
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { Auto } from './auto';
|
||||
|
||||
/**
|
||||
* Listen for an event targeted towards this plugin.
|
||||
* @param event Event name
|
||||
*/
|
||||
export function EventListener(event: string): (...args: any[]) => void {
|
||||
export function EventListener(event: string) {
|
||||
return (
|
||||
target: any,
|
||||
propertyKey: string,
|
||||
@ -19,7 +20,7 @@ export function EventListener(event: string): (...args: any[]) => void {
|
||||
);
|
||||
};
|
||||
// Set the function to be autoexecuted when the plugin is initialized.
|
||||
descriptor.value.prototype.__autoexec = 1;
|
||||
Auto()(target, propertyKey, descriptor);
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
/**
|
||||
* Declare this plugin as one that utilises services.
|
||||
* @param servtype Service class, usually a Protocol
|
||||
* @param injectedService Service class, usually a Protocol
|
||||
*/
|
||||
export function InjectService(servtype: any): (...arg: any[]) => any {
|
||||
return (constructor: (...arg: any[]) => any): void => {
|
||||
constructor.prototype.__service = servtype;
|
||||
export function InjectService(injectedService: any) {
|
||||
return (constructor: any): void => {
|
||||
Reflect.defineMetadata('sb:service', injectedService, constructor);
|
||||
};
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'reflect-metadata';
|
||||
import * as path from 'path';
|
||||
import { IEnvironment, Service } from '../types';
|
||||
import { IPlugin, IPluginManifest } from './plugin';
|
||||
@ -232,8 +233,8 @@ export class PluginManager {
|
||||
}
|
||||
|
||||
// Find default configuration, if it's configured, load the configuration
|
||||
if (PluginModule.prototype.__defconf && config) {
|
||||
config.setDefaults(PluginModule.prototype.__defconf);
|
||||
if (Reflect.hasOwnMetadata('sb:defconf', PluginModule) && config) {
|
||||
config.setDefaults(Reflect.getOwnMetadata('sb:defconf', PluginModule));
|
||||
await config.load();
|
||||
}
|
||||
|
||||
@ -242,8 +243,8 @@ export class PluginManager {
|
||||
const loaded = new PluginModule(plugin, this.stream, config);
|
||||
try {
|
||||
// Give the plugin a service
|
||||
if (PluginModule.prototype.__service) {
|
||||
loaded.service = new Service(PluginModule.prototype.__service);
|
||||
if (Reflect.hasOwnMetadata('sb:service', PluginModule)) {
|
||||
loaded.service = new Service(Reflect.getOwnMetadata('sb:service', PluginModule));
|
||||
}
|
||||
|
||||
// Call the initializer
|
||||
@ -252,17 +253,12 @@ export class PluginManager {
|
||||
}
|
||||
|
||||
// Call methods that are supposed to be executed automatically on load.
|
||||
// This is really nasty and probably shouldn't be done, but I don't care!
|
||||
for (const name of Object.getOwnPropertyNames(PluginModule.prototype)) {
|
||||
// Prevent double initialization
|
||||
if (name === 'initialize') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PluginModule.prototype[name] &&
|
||||
PluginModule.prototype[name].prototype &&
|
||||
PluginModule.prototype[name].prototype.__autoexec) {
|
||||
loaded[name].call(loaded);
|
||||
const autorunFunctions: Array<string> = Reflect.getOwnMetadata('sb:autorunners', PluginModule.prototype);
|
||||
if (autorunFunctions?.length) {
|
||||
for (const autoFunction of autorunFunctions) {
|
||||
if (!loaded[autoFunction]) continue;
|
||||
if (autoFunction === 'initialize') continue;
|
||||
loaded[autoFunction].call(loaded);
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
|
@ -11,7 +11,7 @@ export * from './checksum';
|
||||
*/
|
||||
export function requireNoCache(file: string): object | undefined {
|
||||
const fullPath = path.resolve(file);
|
||||
// TODO: maybe use new "import" function?
|
||||
// TODO: maybe use new "import" function? <- currently has no cache invalidation
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const mod = require(fullPath);
|
||||
if (require.cache && require.cache[fullPath]) {
|
||||
|
Loading…
Reference in New Issue
Block a user