server: strip and update dependencies

This commit is contained in:
Koushik Dutta
2023-06-07 08:17:13 -07:00
parent 93556dd404
commit 73cd40b540
9 changed files with 605 additions and 618 deletions

906
server/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,6 @@
"lodash": "^4.17.21",
"memfs": "^3.5.2",
"mime": "^3.0.0",
"mkdirp": "^3.0.1",
"nan": "^2.17.0",
"node-dijkstra": "^2.5.0",
"node-forge": "^1.3.1",
@@ -43,7 +42,6 @@
"@types/ip": "^1.1.0",
"@types/lodash": "^4.14.195",
"@types/mime": "^3.0.1",
"@types/mkdirp": "^1.0.2",
"@types/node-dijkstra": "^2.5.3",
"@types/node-forge": "^1.3.2",
"@types/pem": "^1.9.6",

View File

@@ -1,27 +1,4 @@
// Type definitions for abstract-leveldown 5.0
// Project: https://github.com/Level/abstract-leveldown
// Definitions by: Meirion Hughes <https://github.com/MeirionHughes>
// Daniel Byrne <https://github.com/danwbyrne>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
export interface AbstractOptions {
// wtf is this?
readonly [k: string]: any;
}
export type ErrorCallback = (err: Error | undefined) => void;
export type ErrorValueCallback<V> = (err: Error | undefined, value: V) => void;
export type ErrorKeyValueCallback<K, V> = (err: Error | undefined, key: K, value: V) => void;
export interface AbstractOpenOptions extends AbstractOptions {
createIfMissing?: boolean;
errorIfExists?: boolean;
}
export interface AbstractGetOptions extends AbstractOptions {
asBuffer?: boolean;
}
import { GetOptions, Level, OpenOptions, PutOptions } from 'level';
export interface LevelDocument {
_id?: any;
@@ -32,265 +9,107 @@ export interface LevelDocumentConstructor<T extends LevelDocument> {
new(): T;
}
export interface AbstractLevelDOWN<K = any, V = any> /* extends AbstractOptions */ {
open(cb?: ErrorCallback): Promise<void>;
open(options: AbstractOpenOptions, cb?: ErrorCallback): Promise<void>;
close(cb?: ErrorCallback): void;
get(key: K, cb?: ErrorValueCallback<V>): Promise<V>;
get(key: K, options: AbstractGetOptions, cb?: ErrorValueCallback<V>): Promise<V>;
put(key: K, value: V, cb?: ErrorCallback): Promise<void>;
put(key: K, value: V, options: AbstractOptions, cb?: ErrorCallback): Promise<void>;
del(key: K, cb?: ErrorCallback): Promise<void>;
del(key: K, options: AbstractOptions, cb?: ErrorCallback): Promise<void>;
batch(): AbstractChainedBatch<K, V>;
batch(array: ReadonlyArray<AbstractBatch<K, V>>, cb?: ErrorCallback): AbstractChainedBatch<K, V>;
batch(
array: ReadonlyArray<AbstractBatch<K, V>>,
options: AbstractOptions,
cb?: ErrorCallback,
): AbstractChainedBatch<K, V>;
iterator(options?: AbstractIteratorOptions<K>): AbstractIterator<K, V>;
[Symbol.asyncIterator](): AsyncIterator<{ key: K, value: V }>;
nextId(): number;
tryGet<T extends LevelDocument>(documentConstructor: LevelDocumentConstructor<T>, _id: any, options?: AbstractGetOptions): Promise<T | undefined>;
getAll<T extends LevelDocument>(documentConstructor: LevelDocumentConstructor<T>, options?: AbstractGetOptions): AsyncIterable<T>;
upsert<T extends LevelDocument>(value: T, options?: AbstractOptions): Promise<T>;
remove<T extends LevelDocument>(value: T): Promise<void>;
removeId<T extends LevelDocument>(documentConstructor: LevelDocumentConstructor<T>, _id: any): Promise<void>;
removeAll<T extends LevelDocument>(documentConstructor: LevelDocumentConstructor<T>): Promise<void>;
getCount<T extends LevelDocument>(documentConstructor: LevelDocumentConstructor<T>, options?: AbstractGetOptions): Promise<number>;
}
export interface AbstractLevelDOWNConstructor {
// tslint:disable-next-line no-unnecessary-generics
new <K = any, V = any>(location: string): AbstractLevelDOWN<K, V>;
// tslint:disable-next-line no-unnecessary-generics
<K = any, V = any>(location: string): AbstractLevelDOWN<K, V>;
}
export interface AbstractIteratorOptions<K = any> extends AbstractOptions {
gt?: K;
gte?: K;
lt?: K;
lte?: K;
reverse?: boolean;
limit?: number;
keys?: boolean;
values?: boolean;
keyAsBuffer?: boolean;
valueAsBuffer?: boolean;
}
export type AbstractBatch<K = any, V = any> = PutBatch<K, V> | DelBatch<K, V>;
export interface PutBatch<K = any, V = any> {
readonly type: 'put';
readonly key: K;
readonly value: V;
}
export interface DelBatch<K = any, V = any> {
readonly type: 'del';
readonly key: K;
}
export interface AbstractChainedBatch<K = any, V = any> extends AbstractOptions {
put: (key: K, value: V) => this;
del: (key: K) => this;
clear: () => this;
write(cb?: ErrorCallback): any;
write(options: any, cb?: ErrorCallback): any;
}
export interface AbstractChainedBatchConstructor {
// tslint:disable-next-line no-unnecessary-generics
new <K = any, V = any>(db: any): AbstractChainedBatch<K, V>;
// tslint:disable-next-line no-unnecessary-generics
<K = any, V = any>(db: any): AbstractChainedBatch<K, V>;
}
export interface AbstractIterator<K, V> extends AbstractOptions {
db: AbstractLevelDOWN<K, V>;
next(cb?: ErrorKeyValueCallback<K, V>): this;
end(cb?: ErrorCallback): void;
}
export interface AbstractIteratorConstructor {
// tslint:disable-next-line no-unnecessary-generics
new <K = any, V = any>(db: any): AbstractIterator<K, V>;
// tslint:disable-next-line no-unnecessary-generics
<K = any, V = any>(db: any): AbstractIterator<K, V>;
}
export interface Level extends AbstractLevelDOWN {
readonly location: string;
readonly prefix: string;
readonly version: string | number;
destroy(location: string, cb?: (err: Error | undefined) => void): void;
destroy(location: string, prefix: string, cb?: (err: Error | undefined) => void): void;
}
interface LevelOptions {
readonly prefix?: string;
readonly version?: string | number;
}
interface LevelConstructor {
new(location: string, options?: LevelOptions, callback?: (err: Error) => void): Level;
(location: string, options?: LevelOptions, callback?: (err: Error) => void): Level;
}
declare const Level: LevelConstructor;
const level = require('level') as LevelConstructor;
function createLevelDocument(documentConstructor: any, json: any) {
const doc = new documentConstructor();
Object.assign(doc, JSON.parse(json));
return doc;
}
const wrapped = (location: string, options?: LevelOptions, callback?: (err: Error) => void) => {
const ret = level(location, options, callback);
ret.tryGet = async (documentConstructor: any, _id: any, options?: AbstractGetOptions): Promise<any> => {
export class WrappedLevel extends Level<string, string | number> {
curId: number;
async open(): Promise<void>;
async open(options?: OpenOptions): Promise<void> {
await super.open(options);
try {
this.curId = parseInt(await this.get('_id') as string);
}
catch (e) {
}
if (!this.curId)
this.curId = 0;
}
async tryGet(documentConstructor: any, _id: any, options?: GetOptions<string, string | number>) {
try {
const _documentType = documentConstructor.name;
const key = `${_documentType}/${_id}`;
const json = await ret.get(key, options);
const json = await this.get(key, options)
return createLevelDocument(documentConstructor, json);
}
catch (e) {
}
}
const iterable = {
async*[Symbol.asyncIterator]() {
const iterator = ret.iterator();
try {
while (true) {
const { key, value } = await new Promise<{ key: any, value: any }>((resolve, reject) => {
iterator.next((err, key, value) => {
if (err) {
reject(err);
}
else {
resolve({ key, value });
}
})
});
if (key == null && value == null)
break;
yield {
key,
value,
}
}
}
finally {
await new Promise(resolve => iterator.end(resolve));
}
}
};
ret[Symbol.asyncIterator] = iterable[Symbol.asyncIterator] as any;
ret.getAll = (documentConstructor: any, options?: AbstractGetOptions): AsyncIterable<any> => {
async* getAll(documentConstructor: any): AsyncIterable<any> {
const _documentType = documentConstructor.name;
const prefix = `${_documentType}/`;
return {
async*[Symbol.asyncIterator]() {
for await (const entry of ret) {
if (entry.key.startsWith(prefix)) {
const doc = createLevelDocument(documentConstructor, entry.value);
if (doc._documentType === _documentType) {
yield doc;
}
}
for await (const [key, value] of this.iterator()) {
if (key.startsWith(prefix)) {
const doc = createLevelDocument(documentConstructor, value);
if (doc._documentType === _documentType) {
yield doc;
}
}
}
}
ret.getCount = async (documentConstructor: any, options?: AbstractGetOptions): Promise<any> => {
async getCount(documentConstructor: any) {
let count = 0;
for await (const doc of ret.getAll(documentConstructor)) {
for await (const doc of this.getAll(documentConstructor)) {
count++;
}
return count;
}
let curId: number;
const oldOpen = ret.open.bind(ret);
(ret as any).open = async (...args: any) => {
try {
curId = parseInt(await ret.get('_id'));
}
catch (e) {
}
if (!curId)
curId = 0;
return oldOpen(...args);
}
ret.nextId = () => {
if (typeof curId !== 'number')
nextId() {
if (typeof this.curId !== 'number')
throw new Error('curId is not a number');
return ++curId;
return ++this.curId;
}
const saveId = async () => {
return ret.put("_id", curId);
async saveId() {
return this.put("_id", this.curId);
}
ret.upsert = async (value: LevelDocument, options?: AbstractOptions): Promise<any> => {
async upsert(value: LevelDocument, options?: PutOptions<string, string | number>): Promise<any> {
const _documentType = value.constructor.name;
if (!value._id)
value._id = ret.nextId();
value._id = this.nextId();
await saveId();
await this.saveId();
value._documentType = _documentType;
const key = `${_documentType}/${value._id}`;
await ret.put(key, JSON.stringify(value), options);
await this.put(key, JSON.stringify(value), options);
return value;
};
ret.remove = async (value: LevelDocument) => {
async remove(value: LevelDocument) {
const _documentType = value.constructor.name;
let { _id } = value;
const key = `${_documentType}/${_id}`;
await ret.del(key);
await this.del(key);
}
ret.removeId = async (documentConstructor: LevelDocumentConstructor<any>, _id: any) => {
async removeId(documentConstructor: LevelDocumentConstructor<any>, _id: any) {
const _documentType = documentConstructor.name;
const key = `${_documentType}/${_id}`;
await ret.del(key);
await this.del(key);
}
ret.removeAll = async (documentConstructor: LevelDocumentConstructor<any>) => {
async removeAll(documentConstructor: LevelDocumentConstructor<any>) {
const _documentType = documentConstructor.name;
const prefix = `${_documentType}/`;
for await (const entry of ret) {
if (entry.key.startsWith(prefix)) {
const doc = createLevelDocument(documentConstructor, entry.value);
for await (const [key, value] of this.iterator()) {
if (key.startsWith(prefix)) {
const doc = createLevelDocument(documentConstructor, value);
if (doc._documentType === _documentType) {
await ret.del(entry.key);
await this.del(key);
}
}
}
}
}
return ret;
};
export default wrapped as LevelConstructor;
export default WrappedLevel;

View File

@@ -4,13 +4,12 @@ import pathToFfmpeg from 'ffmpeg-static';
import fs from 'fs';
import https from 'https';
import mimeType from 'mime';
import mkdirp from "mkdirp";
import Graph from 'node-dijkstra';
import os from 'os';
import path from 'path';
import MimeType from 'whatwg-mimetype';
import { MediaObjectRemote } from "./plugin-api";
import { MediaObject } from "./mediaobject";
import { MediaObjectRemote } from "./plugin-api";
function typeMatches(target: string, candidate: string): boolean {
// candidate will accept anything
@@ -202,7 +201,9 @@ export abstract class MediaManagerBase implements MediaManager {
if (!filesPath)
throw new Error('SCRYPTED_PLUGIN_VOLUME env variable not set?');
const ret = path.join(filesPath, 'files');
mkdirp.sync(ret);
await fs.promises.mkdir(ret, {
recursive: true,
});
return ret;
}

View File

@@ -1,11 +1,10 @@
import os from 'os';
import { Device, EngineIOHandler } from '@scrypted/types';
import AdmZip from 'adm-zip';
import crypto from 'crypto';
import * as io from 'engine.io';
import fs from 'fs';
import mkdirp from 'mkdirp';
import net from 'net';
import os from 'os';
import path from 'path';
import rimraf from 'rimraf';
import { Duplex } from 'stream';
@@ -207,7 +206,9 @@ export class PluginHost {
if (!fs.existsSync(zipFile)) {
rimraf.sync(zipDirTmp);
rimraf.sync(zipDir);
mkdirp.sync(zipDirTmp);
fs.mkdirSync(zipDirTmp, {
recursive: true,
});
fs.writeFileSync(path.join(zipDirTmp, zipFilename), zipBuffer);
const admZip = new AdmZip(zipBuffer);
admZip.extractAllTo(path.join(zipDirTmp, 'unzipped'), true);

View File

@@ -1,7 +1,6 @@
import child_process from 'child_process';
import { once } from 'events';
import fs from 'fs';
import mkdirp from "mkdirp";
import os from 'os';
import path from 'path';
import process from 'process';
@@ -66,7 +65,9 @@ export async function installOptionalDependencies(console: Console, packageJson:
delete reduced.devDependencies;
delete reduced.scripts;
mkdirp.sync(nodePrefix);
await fs.promises.mkdir(nodePrefix, {
recursive: true,
})
fs.writeFileSync(packageJsonPath, JSON.stringify(reduced));
const cp = npmExecFunction(['--prefix', nodePrefix, 'install'], {

View File

@@ -1,6 +1,6 @@
import fs from 'fs';
import os from 'os';
import path from 'path';
import mkdirp from 'mkdirp';
export function getScryptedVolume() {
const volumeDir = process.env.SCRYPTED_VOLUME || path.join(os.homedir(), '.scrypted', 'volume');
@@ -16,7 +16,9 @@ export function getPluginVolume(pluginId: string) {
export function ensurePluginVolume(pluginId: string) {
const pluginVolume = getPluginVolume(pluginId);
try {
mkdirp.sync(pluginVolume);
fs.mkdirSync(pluginVolume, {
recursive: true,
})
}
catch (e) {
}

View File

@@ -20,7 +20,7 @@ import { Plugin, PluginDevice, ScryptedAlert, ScryptedUser } from './db-types';
import { createResponseInterface } from './http-interfaces';
import { getDisplayName, getDisplayRoom, getDisplayType, getProvidedNameOrDefault, getProvidedRoomOrDefault, getProvidedTypeOrDefault } from './infer-defaults';
import { IOServer } from './io';
import { Level } from './level';
import Level from './level';
import { LogEntry, Logger, makeAlertId } from './logger';
import { getMixins, hasMixinCycle } from './mixin/mixin-cycle';
import { AccessControls } from './plugin/acl';

View File

@@ -7,7 +7,6 @@ import fs from 'fs';
import http from 'http';
import httpAuth from 'http-auth';
import https from 'https';
import mkdirp from 'mkdirp';
import net from 'net';
import os from 'os';
import path from 'path';
@@ -16,7 +15,7 @@ import semver from 'semver';
import { install as installSourceMapSupport } from 'source-map-support';
import { createSelfSignedCertificate, CURRENT_SELF_SIGNED_CERTIFICATE_VERSION } from './cert';
import { Plugin, ScryptedUser, Settings } from './db-types';
import level, { Level } from './level';
import Level from './level';
import { PluginError } from './plugin/plugin-error';
import { getScryptedVolume } from './plugin/plugin-volume';
import { RPCResultError } from './rpc';
@@ -116,15 +115,11 @@ async function start(mainFilename: string, options?: {
onRuntimeCreated?: (runtime: ScryptedRuntime) => Promise<void>,
}) {
const volumeDir = getScryptedVolume();
mkdirp.sync(volumeDir);
await fs.promises.mkdir(volumeDir, {
recursive: true
});
const dbPath = path.join(volumeDir, 'scrypted.db');
const db = await new Promise<Level>((r, f) => {
const db = level(dbPath, undefined, (e) => {
if (e)
return f(e);
r(db);
});
})
const db = new Level(dbPath);
await db.open();
let certSetting = await db.tryGet(Settings, 'certificate') as Settings;