diff --git a/.gitignore b/.gitignore index 40c307af5..d987f42c1 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,6 @@ typings/ # Temp dir for tests test/__temp__/* + +# Built files +dist diff --git a/app/graphql/index.js b/app/graphql/index.js deleted file mode 100644 index ac19c7cfa..000000000 --- a/app/graphql/index.js +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright 2019 Lime Technology Inc. All rights reserved. - * Written by: Alexis Tyler - */ - -module.exports = function ( - $injector, - ApiManager, - AppError, - get, - gql, - log, - mergeGraphqlSchemas, - PluginError, - PluginManager, - resolvers, - typeDefs, - Users, - config -) { - const {mergeTypes} = mergeGraphqlSchemas; - const baseTypes = [gql` - scalar JSON - scalar Long - scalar UUID - - directive @func( - module: String - data: JSON - query: JSON - result: String - extractFromResponse: String - ) on FIELD_DEFINITION - - directive @subscription( - channel: String! - ) on FIELD_DEFINITION - - type Welcome { - message: String! - } - - type Query { - # This should always be available even for guest users - welcome: Welcome! @func(module: "get-welcome") - info: Info! - pluginModule(plugin: String!, module: String!, params: JSON, result: String): JSON @func(result: "json") - } - - type Mutation { - login(username: String!, password: String!): String - - shutdown: String - reboot: String - } - - enum MutationType { - CREATED - UPDATED - DELETED - } - - enum UpdateOnlyMutationType { - UPDATED - } - - type PingSubscription { - mutation: MutationType! - node: String! - } - - type InfoSubscription { - mutation: MutationType! - node: Info! - } - - type PluginModuleSubscription { - mutation: MutationType! - node: JSON! - } - - type Subscription { - ping: PingSubscription! - info: InfoSubscription! - pluginModule(plugin: String!, module: String!, params: JSON, result: String): PluginModuleSubscription! - } - `]; - - // Add test defs in dev mode - if (process.env.NODE_ENV === 'development') { - const testDefs = gql` - # Test query - input testQueryInput { - state: String! - optional: Boolean - } - type Query { - testQuery(id: String!, input: testQueryInput): JSON @func(module: "debug/return-context") - } - - # Test mutation - input testMutationInput { - state: String! - } - type Mutation { - testMutation(id: String!, input: testMutationInput): JSON @func(module: "debug/get-context") - } - - # Test subscription - type Subscription { - testSubscription: String! - } - `; - baseTypes.push(testDefs); - } - - // Add debug defs to all envs apart from production - if (process.env.NODE_ENV !== 'production') { - const debugDefs = gql` - # Debug query - type Context { - query: JSON - params: JSON - data: JSON - user: JSON - } - - type Query { - context: Context @func(module: "debug/get-context") - } - `; - baseTypes.push(debugDefs); - } - - const types = mergeTypes([ - ...baseTypes, - typeDefs - ]); - - const {SchemaDirectiveVisitor} = $injector.resolve('graphql-tools'); - - /** - * Func directive - * - * @see https://github.com/smooth-code/graphql-directive/blob/master/README.md#directive-resolver-function-signature - * - * @param {object} obj - * The result returned from the resolver on the parent field, or, in the case of a top-level Query field, - * the rootValue passed from the server configuration. - * @param {object} directiveArgs - * An object with the arguments passed into the directive in the query or schema. - * For example, if the directive was called with `@dateFormat(format: "DD/MM/YYYY")`, - * the args object would be: `{ "format": "DD/MM/YYYY" }`. - * @param {object} context - * This is an object shared by all resolvers in a particular query, - * and is used to contain per-request state, including authentication information, - * dataloader instances, and anything else that should be taken into account when resolving the query. - * @param {object} info - * This argument should only be used in advanced cases, - * but it contains information about the execution state of the query, - * including the field name, path to the field from the root, and more. - */ - class FuncDirective extends SchemaDirectiveVisitor { - visitFieldDefinition(field) { - const {args} = this; - field.resolve = async function (source, directiveArgs, context, info) { - const path = $injector.resolve('path'); - const paths = $injector.resolve('paths'); - const {module: moduleName, result: resultType} = args; - const coreCwd = path.join(paths.get('core'), 'modules'); - const {plugin: pluginName, module: pluginModuleName, result: pluginType, input, ...params} = directiveArgs; - const operationType = info.operation.operation; - const query = { - ...directiveArgs.query, - ...(operationType === 'query' ? input : {}) - }; - const data = { - ...directiveArgs.data, - ...(operationType === 'mutation' ? input : {}) - }; - let funcPath = path.join(coreCwd, moduleName + '.js'); - - // If we're looking for a plugin verify it's installed and active first - if (pluginName) { - if (!PluginManager.isInstalled(pluginName, pluginModuleName)) { - throw new PluginError('Plugin not installed.'); - } - - if (!PluginManager.isActive(pluginName, pluginModuleName)) { - throw new PluginError('Plugin disabled.'); - } - - const pluginModule = PluginManager.get(pluginName, pluginModuleName); - // Update plugin funcPath - funcPath = pluginModule.filePath; - } - - // Create func locals - // If query @func(param_1, param_2, input: query?) - // If mutation @func(param_1, param_2, input: data) - const locals = { - context: { - query, - params, - data, - user: context.user - } - }; - - // Resolve func - let func; - try { - func = $injector.resolvePath(funcPath, locals); - } catch (error_) { - // Rethrow clean error message about module being missing - if (error_.code === 'MODULE_NOT_FOUND') { - throw new AppError(`Cannot find ${pluginName ? 'Plugin: "' + pluginName + '" ' : ''}Module: "${pluginName ? pluginModuleName : moduleName}"`); - } - - // In production let's just throw an internal error - if (process.env.NODE_ENV === 'production') { - throw new AppError('Internal error occurred'); - } - - // Otherwise re-throw actual error - throw error_; - } - - const pluginOrModule = pluginName ? 'Plugin:' : 'Module:'; - const pluginOrModuleName = pluginModuleName || moduleName; - - // Run function - let [error, result] = await Promise.resolve(func) - .then(result => [undefined, result]) - .catch(error_ => { - // Ensure we aren't leaking anything in production - if (process.env.NODE_ENV === 'production') { - log.error(pluginOrModule, pluginOrModuleName, 'Error:', error_.message); - return [new Error(error_.message)]; - } - - const logger = log[error_.status && error_.status >= 400 ? 'error' : 'warn']; - logger(pluginOrModule, pluginOrModuleName, 'Error:', error_); - return [error_]; - }); - - // Bail if we can't get the method to run - if (error) { - return error; - } - - // If the method's result is a function or promise run/resolve it - result = await Promise.resolve(result).then(result => typeof result === 'function' ? result() : result); - - // Get wanted result type or fallback to json - result = result[pluginType || resultType || 'json']; - - // Allow fields to be extracted - if (directiveArgs.extractFromResponse) { - result = get(result, directiveArgs.extractFromResponse); - } - - log.debug(pluginOrModule, pluginOrModuleName, 'Result:', result); - return result; - }; - } - } - - const {makeExecutableSchema} = $injector.resolve('graphql-tools'); - const schema = makeExecutableSchema({ - typeDefs: types, - resolvers, - schemaDirectives: { - func: FuncDirective - } - }); - - const ensureApiKey = apiKey => { - if (!apiKey) { - throw new AppError('Missing apikey.'); - } - - if (!ApiManager.isValid(apiKey)) { - throw new AppError('Invalid apikey.'); - } - }; - - const {debug} = config; - return { - introspection: debug, - playground: debug, - schema, - types, - resolvers, - subscriptions: { - onConnect: connectionParams => { - const apiKey = connectionParams['x-api-key']; - ensureApiKey(apiKey); - - const user = Users.findOne({apiKey}) || {name: 'guest', apiKey, role: 'guest'}; - - log.info(` ${user.name} connected.`); - - return { - user - }; - }, - onDisconnect: async (_, context) => { - const initialContext = await context.initPromise; - log.info(` ${initialContext.user.name} disconnected.`); - } - }, - context: ({req, connection}) => { - if (connection) { - // Check connection for metadata - return { - ...connection.context - }; - } - - const apiKey = req.headers['x-api-key']; - ensureApiKey(apiKey); - - const user = Users.findOne({apiKey}) || {name: 'guest', apiKey, role: 'guest'}; - - return { - user - }; - } - }; -}; diff --git a/app/graphql/schema/resolvers.js b/app/graphql/schema/resolvers.js deleted file mode 100644 index 928d93c3b..000000000 --- a/app/graphql/schema/resolvers.js +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 2019 Lime Technology Inc. All rights reserved. - * Written by: Alexis Tyler - */ - -module.exports = function ( - $injector, - GraphQLJSON, - GraphQLLong, - GraphQLUUID, - PluginManager, - pubsub, - log, - PluginError, - dee, - debugTimer, - bus, - setIntervalAsync -) { - // Only allows function to publish to pubsub when clients are online - // the reason we do this is otherwise pubsub will cause a memory leak - const canPublishToClients = () => { - return true; - }; - - const handleResult = async possibleResult => { - // Await resolved function if it returns one. - if (typeof possibleResult === 'function') { - const result = await possibleResult(); - return result; - } - - return possibleResult; - }; - - /** - * Run a module and update pubsub - * - * @param {String} channel - * @param {String} mutation - * @param {Object} options - * @param {String} [options.node] - * @param {String} [options.moduleToRun] - * @param {String} [options.filePath] - * @param {Number} [options.interval = 1000] - * @param {Number} [options.total = 1] - * @param {Object} [options.context = {}] - */ - const run = async (channel, mutation, { - node, - moduleToRun, - filePath, - context = {} - }) => { - if (!canPublishToClients()) { - return; - } - - if (!moduleToRun && !filePath) { - pubsub.publish(channel, { - [channel]: { - mutation, - node - } - }); - - return; - } - - try { - // Run module - const result = await new Promise(resolve => { - if (filePath) { - debugTimer(`run:${filePath}`); - const promise = $injector.resolvePath(filePath, { - context - }); - - return resolve(promise); - } - - debugTimer(`run:${moduleToRun}`); - const promise = $injector.resolveModule(`module:${moduleToRun}`, { - context - }); - - return resolve(promise); - }).then(handleResult); - - if (filePath) { - const [pluginName, moduleName] = channel.split('/'); - log.debug('Plugin:', pluginName, 'Module:', moduleName, 'Result:', result); - } else { - log.debug('Module:', channel, 'Result:', result.json); - } - - // Update pubsub channel - pubsub.publish(channel, { - [filePath ? 'pluginModule' : channel]: { - mutation, - node: result.json - } - }); - } catch (error) { - // Ensure we aren't leaking anything in production - if (process.env.NODE_ENV === 'production') { - log.debug('Error:', error.message); - } else { - const logger = log[error.status && error.status >= 400 ? 'error' : 'warn']; - logger('Error:', error.message); - } - } - - debugTimer(filePath ? `run:${filePath}` : `run:${moduleToRun}`); - }; - - // Send test message every 1 second for 10 seconds. - const startPing = async (interval = 1000, total = 10) => { - await run('ping', 'UPDATED', { - node: 'PONG!', - interval, - total - }); - }; - - // Receive test messages. - // pubsub.subscribe('ping', (...rest) => { - // console.log(`CHANNEL: ping DATA: ${JSON.stringify(rest, null, 2)}`); - // }); - - // Update array values when disks change - bus.on('disks', async () => { - await run('array', 'UPDATED', { - moduleToRun: 'get-array', - context: {} - }); - }); - - const createBasicSubscription = name => ({ - subscribe: async () => { - return pubsub.asyncIterator(name); - } - }); - - // On Docker event update info with { apps: { installed, started } } - const updatePubsub = async () => { - if (!canPublishToClients()) { - return; - } - - const {json} = await $injector.resolveModule('module:info/get-apps'); - pubsub.publish('info', { - info: { - mutation: 'UPDATED', - node: { - ...json - } - } - }); - }; - - dee.on('start', updatePubsub); - dee.on('stop', updatePubsub); - - dee.listen(); - - // Republish bus events to pubsub when clients connect - // We need to filter to only the endpoint that're currently connected - // bus.on('*', (...args) => { - // if (!canPublishToClients()) { - // return; - // } - - // const { - // [args.length - 1]: last, - // ...rest - // } = args; - - // pubsub.publish(...Object.values(rest)); - // }); - - // This needs to be fixed to run from events - setIntervalAsync(async () => { - if (!canPublishToClients()) { - return; - } - - await run('services', 'UPDATED', { - moduleToRun: 'get-services' - }); - }, 1000); - - return { - Query: { - info: () => ({}), - vms: () => ({}) - }, - Subscription: { - apikeys: { - // Not sure how we're going to secure this - ...createBasicSubscription('apikeys') - }, - array: { - ...createBasicSubscription('array') - }, - devices: { - ...createBasicSubscription('devices') - }, - dockerContainers: { - ...createBasicSubscription('docker/containers') - }, - dockerNetworks: { - ...createBasicSubscription('docker/networks') - }, - info: { - ...createBasicSubscription('info') - }, - ping: { - subscribe: () => { - startPing(); - return pubsub.asyncIterator('ping'); - } - }, - services: { - ...createBasicSubscription('services') - }, - shares: { - ...createBasicSubscription('shares') - }, - unassignedDevices: { - ...createBasicSubscription('devices/unassigned') - }, - users: { - ...createBasicSubscription('users') - }, - vars: { - ...createBasicSubscription('vars') - }, - vms: { - ...createBasicSubscription('vms/domains') - }, - pluginModule: { - subscribe: async (_, directiveArgs) => { - const {plugin: pluginName, module: pluginModuleName} = directiveArgs; - const name = `${pluginName}/${pluginModuleName}`; - - // Verify plugin is installed and active - if (!PluginManager.isInstalled(pluginName, pluginModuleName)) { - throw new PluginError('Plugin not installed.'); - } - - if (!PluginManager.isActive(pluginName, pluginModuleName)) { - throw new PluginError('Plugin disabled.'); - } - - // It's up to the plugin to publish new data as needed - // so we'll just return the Iterator - return pubsub.asyncIterator(name); - } - } - }, - JSON: GraphQLJSON, - Long: GraphQLLong, - UUID: GraphQLUUID, - UserAccount: { - __resolveType(obj) { - // Only a user has a password field, the current user aka "me" doesn't. - if (obj.password) { - return 'User'; - } - - return 'Me'; - } - } - }; -}; diff --git a/app/graphql/schema/type-defs.js b/app/graphql/schema/type-defs.js deleted file mode 100644 index c27b8731b..000000000 --- a/app/graphql/schema/type-defs.js +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2019 Lime Technology Inc. All rights reserved. - * Written by: Alexis Tyler - */ - -module.exports = function (path, mergeGraphqlSchemas) { - const {join} = path; - const {fileLoader, mergeTypes} = mergeGraphqlSchemas; - const files = fileLoader(join(__dirname, './types/**/*.graphql')); - - return mergeTypes(files, { - all: true - }); -}; diff --git a/app/graphql/schema/types/array/parity.graphql b/app/graphql/schema/types/array/parity.graphql deleted file mode 100644 index c400bb817..000000000 --- a/app/graphql/schema/types/array/parity.graphql +++ /dev/null @@ -1,31 +0,0 @@ -type Query { - parityHistory: [ParityCheck] @func(module: "get-parity-history") -} - -type Mutation { - """Start parity check""" - startParityCheck(correct: Boolean): JSON @func(module: "array/update-parity-check", data: { state: "start" }) - """Pause parity check""" - pauseParityCheck: JSON @func(module: "array/update-parity-check", data: { state: "pause" }) - """Resume parity check""" - resumeParityCheck: JSON @func(module: "array/update-parity-check", data: { state: "resume" }) - """Cancel parity check""" - cancelParityCheck: JSON @func(module: "array/update-parity-check", data: { state: "cancel" }) -} - -type ParityHistorySubscription { - mutation: MutationType! - node: ParityCheck! -} - -type Subscription { - parityHistory: ParityHistorySubscription -} - -type ParityCheck { - date: String! - duration: Int! - speed: String! - status: String! - errors: String! -} \ No newline at end of file diff --git a/app/graphql/schema/types/info/machine-id.graphql b/app/graphql/schema/types/info/machine-id.graphql deleted file mode 100644 index 665be94d6..000000000 --- a/app/graphql/schema/types/info/machine-id.graphql +++ /dev/null @@ -1,4 +0,0 @@ -type Info { - """Machine ID""" - machineId: ID @func(module: "info/get-machine-id") -} \ No newline at end of file diff --git a/app/index.js b/app/index.js deleted file mode 100644 index 78b11a7cb..000000000 --- a/app/index.js +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2019 Lime Technology Inc. All rights reserved. - * Written by: Alexis Tyler - */ - -const path = require('path'); -const am = require('am'); -const camelCase = require('camelcase'); -// eslint-disable-next-line import/no-extraneous-dependencies -const Injector = require('bolus'); - -// Set the working directory to this one. -process.chdir(__dirname); - -// Create an $injector. -const $injector = new Injector(); - -// Register the imported modules with default names. -$injector.registerImports([ - 'net', - 'http', - 'apollo-server-express', - 'apollo-server', - 'express', - 'graphql-subscriptions', - 'graphql-tools', - 'graphql', - 'set-interval-async/dynamic', - 'stoppable' -]); - -// Register modules that need require and not import -$injector.registerRequires([ - 'graphql' -]); - -// Register the imported modules with custom names. -$injector.registerImports({ - dee: '@gridplus/docker-events', - get: 'lodash.get', - gql: 'graphql-tag', - graphqlDirective: 'graphql-directive', - GraphQLJSON: 'graphql-type-json', - GraphQLLong: 'graphql-type-long', - GraphQLUUID: 'graphql-type-uuid', - mergeGraphqlSchemas: 'merge-graphql-schemas' -}); - -$injector.registerValue('setIntervalAsync', $injector.resolve('set-interval-async/dynamic').setIntervalAsync); - -// Register all of the single js files as modules. -$injector.registerPath([ - '*.js', - 'graphql/*.js' -], defaultName => camelCase(defaultName)); - -// Register graphql schema -$injector.registerPath([ - './graphql/schema/**/*.js' -], defaultName => camelCase(defaultName)); - -// Register core -$injector.registerPath(path.resolve(process.env.PATHS_CORE || path.join(__dirname, '../node_modules/@unraid/core'))); - -// Boot app -am(async () => { - const core = $injector.resolve('core'); - - // Load core - await core.load().catch(coreError => { - try { - // Handler non fatal errors - $injector.resolve('globalErrorHandler')(coreError); - } catch { - throw coreError; - } - }); - - // Load server - await core.loadServer('graphql-api'); -}, error => { - // We should only end here if core has an issue loading - - // Log last error - console.error(error); - - // Kill application - // eslint-disable-next-line unicorn/no-process-exit - process.exit(1); -}); diff --git a/app/metrics.js b/app/metrics.js deleted file mode 100644 index b4346e8eb..000000000 --- a/app/metrics.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2019 Lime Technology Inc. All rights reserved. - * Written by: Alexis Tyler - */ - -/** - * The Graphql pm2 metrics reporters. - */ -module.exports = function ($injector) { - const websocketClients = { - name: 'Websocket clients', - value: () => $injector.resolve('ws-clients').size - }; - - const memoryCaches = { - name: 'Memory caches', - value: () => { - const caches = $injector.resolve('caches'); - const keys = caches.keys(); - - // Return amount of caches that exist - return keys.length; - } - }; - - return { - websocketClients, - memoryCaches - }; -}; diff --git a/app/server.js b/app/server.js deleted file mode 100644 index b164df001..000000000 --- a/app/server.js +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2019 Lime Technology Inc. All rights reserved. - * Written by: Alexis Tyler - */ - -/** - * The Graphql server. - */ -module.exports = function ($injector, path, fs, net, express, config, log, getEndpoints, stoppable, http) { - const app = express(); - const port = config.get('graphql-api-port'); - const {ApolloServer} = $injector.resolve('apollo-server-express'); - const graphql = $injector.resolvePath(path.join(__dirname, '/graphql')); - let machineId; - - app.use(async (req, res, next) => { - // Only get the machine ID on first request - // We do this to avoid using async in the main server function - if (!machineId) { - // eslint-disable-next-line require-atomic-updates - machineId = await $injector.resolveModule('module:info/get-machine-id').then(result => result.json); - } - - // Update header with machine ID - res.set('x-machine-id', machineId); - - next(); - }); - - // Mount graph endpoint - const graphApp = new ApolloServer(graphql); - graphApp.applyMiddleware({app}); - - // List all endpoints at start of server - app.get('/', (_, res) => { - return res.send(getEndpoints(app)); - }); - - // Handle errors by logging them and returning a 500. - // eslint-disable-next-line no-unused-vars - app.use((error, _, res, __) => { - log.error(error); - if (error.stack) { - error.stackTrace = error.stack; - } - - res.status(error.status || 500).send(error); - }); - - // Generate types and schema for core modules - // { - // const jsdocx = $injector.resolve('jsdoc-x'); - // const path = $injector.resolve('path'); - // const paths = $injector.resolve('paths'); - // const moduleDir = path.join(paths.get('core'), '/modules/'); - - // console.info('----------------------------') - // console.info('Parsing core modules') - // const docs = jsdocx.parse(`${moduleDir}/**/*.js`) - // .then(docs => { - // console.log('%s', JSON.stringify(docs, null, 0)) - // // const x = gql` - // // type Disk { - // // id: String! - // // } - // // `; - // }) - // .catch(error => console.error(error.stack)); - // console.info('----------------------------') - // } - // (() => { - // const documentedTypeDefs = docs - // .filter(doc => !doc.undocumented) - // .filter(doc => doc.kind === 'typedef') - // .filter(doc => !doc.type.names.find(name => name.startsWith('Array'))); - - // documentedTypeDefs.map(doc => { - // const props = doc.properties ? Object.values(doc.properties).map(prop => { - // const desc = prop.description ? ('"""' + prop.description + '"""') : ''; - // const reservedWords = { - // boolean: 'Boolean', - // number: 'Number', - // string: 'String' - // }; - // const propType = prop.type.names[0]; - // const type = Object.keys(reservedWords).includes(propType) ? reservedWords[propType] : propType; - - // if (doc.name === 'DeviceInfo') { - // console.log({ doc }); - // } - - // return `${desc}\n${prop.name}: ${prop.optional ? '[' : ''}${type || 'JSON'}${!prop.optional ? '!' : ']'}`; - // }) : []; - // const template = ` - // type ${doc.name} { - // ${props.join('\n')} - // } - // `; - - // return template; - // }) - // .forEach(doc => console.info('%s', doc)); - // })() - - const httpServer = http.createServer(app); - const server = stoppable(httpServer); - - const handleError = error => { - if (error.code !== 'EADDRINUSE') { - throw error; - } - - if (!isNaN(parseInt(port, 10))) { - throw error; - } - - server.close(); - - net.connect({ - path: port - }, () => { - // Really in use: re-throw - throw error; - }).on('error', error => { - if (error.code !== 'ECONNREFUSED') { - log.error(error); - - process.exitCode = 1; - } - - // Not in use: delete it and re-listen - fs.unlinkSync(port); - - setTimeout(() => { - server.listen(port); - }, 1000); - }); - }; - - // Port is a UNIX socket file - if (isNaN(parseInt(port, 10))) { - server.on('listening', () => { - // In production this will let pm2 know we're ready - if (process.send) { - process.send('ready'); - } - - // Set permissions - return fs.chmodSync(port, 660); - }); - - server.on('error', handleError); - - process.on('uncaughtException', error => { - // Skip EADDRINUSE as it's already handled above - if (error.code !== 'EADDRINUSE') { - throw error; - } - }); - } - - // Add graphql subscription handlers - graphApp.installSubscriptionHandlers(server); - - // Return an object with a server and start/stop async methods. - return { - server, - async start() { - return server.listen(port, () => { - // Downgrade process user to owner of this file - return fs.stat(__filename, (error, stats) => { - if (error) { - throw error; - } - - return process.setuid(stats.uid); - }); - }); - }, - stop() { - // Stop the server from accepting new connections and close existing connections - return server.close(error => { - if (error) { - log.error(error); - // Exit with error (code 1) - // eslint-disable-next-line unicorn/no-process-exit - process.exit(1); - } - - const name = process.title; - const serverName = `@unraid/${name}`; - log.info(`Successfully stopped ${serverName}`); - - // Gracefully exit - process.exitCode = 0; - }); - } - }; -}; diff --git a/index.js b/index.js deleted file mode 100644 index 4e442a003..000000000 --- a/index.js +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable import/no-unassigned-import */ -/* - * Copyright 2019 Lime Technology Inc. All rights reserved. - * Written by: Alexis Tyler - */ - -// Boot app -require('./app'); diff --git a/package-lock.json b/package-lock.json index 8ace724fd..7c208dd04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -116,7 +116,6 @@ "version": "7.6.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", - "dev": true, "requires": { "@babel/types": "^7.6.3", "jsesc": "^2.5.1", @@ -137,7 +136,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", @@ -148,7 +146,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -218,7 +215,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, "requires": { "@babel/types": "^7.4.4" } @@ -354,7 +350,6 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.6.0", @@ -365,7 +360,6 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", - "dev": true, "requires": { "@babel/code-frame": "^7.5.5", "@babel/generator": "^7.6.3", @@ -382,7 +376,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -393,7 +386,6 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", - "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -1126,13 +1118,14 @@ "dev": true }, "@unraid/core": { - "version": "github:unraid/core#39ba76035121cb17fd83c3e8e5ca501c46f986a4", - "from": "github:unraid/core#master", + "version": "github:unraid/core#6f0fbb457f98f21bd1e4c99bdb3b88fbad8d050c", + "from": "github:unraid/core#feature/add-better-typing", "requires": { "abort-controller": "^3.0.0", "accesscontrol": "^2.2.1", - "apollo-server": "^2.9.12", + "apollo-server": "^2.9.16", "async-exit-hook": "^2.0.1", + "async-mqtt": "2.4.2", "bcryptjs": "^2.4.3", "better-stack-traces": "^1.1.0", "bolus": "github:OmgImAlexis/bolus#04cd4d9", @@ -1141,7 +1134,7 @@ "bytes": "^3.1.0", "camelcase": "^5.3.1", "camelcase-keys": "^6.1.1", - "chokidar": "^3.3.0", + "chokidar": "^3.3.1", "clean-cache": "github:OmgImAlexis/clean-cache#d0df9b1", "clear-module": "^4.0.0", "cli-table": "^0.3.1", @@ -1151,7 +1144,7 @@ "dl-tgz": "^0.7.1", "dockerode": "^3.0.2", "dot-prop": "^5.2.0", - "execa": "^3.4.0", + "execa": "^4.0.0", "express-list-endpoints": "^4.0.1", "flatten": "^1.0.3", "fromentries": "^1.2.0", @@ -1159,7 +1152,7 @@ "fs-proxy": "github:OmgImAlexis/fs-proxy#1f002a7", "get-server-address": "^1.0.1", "glob": "^7.1.6", - "globby": "^10.0.1", + "globby": "^11.0.0", "graphql": "^14.5.8", "htpasswd-js": "^1.0.2", "ini": "^1.3.5", @@ -1168,12 +1161,14 @@ "jsdoc-x": "^4.0.3", "libvirt": "^1.2.1", "map-obj": "^4.1.0", + "micromongo": "0.3.0", "micromongo-class": "github:OmgImAlexis/micromongo-class#f98a9e1", + "mqtt": "3.0.0", "ms": "^2.1.2", "multi-ini": "^2.0.0", - "mustache": "^3.1.0", + "mustache": "^3.2.1", "nanobus": "^4.4.0", - "node-cache": "^5.0.2", + "node-cache": "^5.1.0", "node-fetch": "^2.6.0", "npm-keyword": "^6.1.0", "object.omit": "^3.0.0", @@ -1188,10 +1183,12 @@ "ps-list": "^6.3.0", "request": "^2.88.0", "request-promise-native": "^1.0.8", - "semver": "^6.3.0", - "systeminformation": "^4.16.0", + "semver": "^7.1.1", + "sendmail": "1.6.1", + "systeminformation": "^4.18.3", "temp-write": "^4.0.0", - "tracer": "^1.0.1", + "tracer": "^1.0.2", + "ts-brand-json": "0.1.1", "upcast": "^4.0.0", "validator": "^12.1.0", "xo": "^0.25.3" @@ -1241,9 +1238,9 @@ } }, "execa": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", - "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.0.tgz", + "integrity": "sha512-JbDUxwV3BoT5ZVXQrSVbAiaXhXUkIwvbhPIwZ0N13kX+5yCzOhUNdocxB/UQRuYOHRYYwAxKYwJYc0T4D12pDA==", "requires": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -1252,11 +1249,22 @@ "merge-stream": "^2.0.0", "npm-run-path": "^4.0.0", "onetime": "^5.1.0", - "p-finally": "^2.0.0", "signal-exit": "^3.0.2", "strip-final-newline": "^2.0.0" } }, + "fast-glob": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", + "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + } + }, "fsevents": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", @@ -1284,11 +1292,33 @@ "path-is-absolute": "^1.0.0" } }, + "globby": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", + "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -1310,11 +1340,6 @@ "mimic-fn": "^2.1.0" } }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" - }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1341,6 +1366,11 @@ "picomatch": "^2.0.7" } }, + "semver": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.1.tgz", + "integrity": "sha512-WfuG+fl6eh3eZ2qAf6goB7nhiCd7NPXhmyFxigB/TOkQyeLP8w8GsVehvtGNtnNmyboz4TgeK40B1Kbql/8c5A==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1422,6 +1452,11 @@ "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", "dev": true }, + "addressparser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", + "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=" + }, "aggregate-error": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", @@ -1797,11 +1832,11 @@ } }, "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "requires": { - "default-require-extensions": "^3.0.0" + "default-require-extensions": "^2.0.0" } }, "archy": { @@ -1809,6 +1844,11 @@ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" }, + "arg": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", + "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1916,6 +1956,48 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, + "async-mqtt": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/async-mqtt/-/async-mqtt-2.4.2.tgz", + "integrity": "sha512-w7f8oTXMpQyhtrxJiCEtOaEA6oHRINGHWSyq/xuricfihWEAr9fCanfDN1Jy5m7WqiC/iZ66YUSh5NhWfS3a0A==", + "requires": { + "mqtt": "^2.3.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "mqtt": { + "version": "2.18.8", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.18.8.tgz", + "integrity": "sha512-3h6oHlPY/yWwtC2J3geraYRtVVoRM6wdI+uchF4nvSSafXPZnaKqF8xnX+S22SU/FcgEAgockVIlOaAX3fkMpA==", + "requires": { + "commist": "^1.0.0", + "concat-stream": "^1.6.2", + "end-of-stream": "^1.4.1", + "es6-map": "^0.1.5", + "help-me": "^1.0.1", + "inherits": "^2.0.3", + "minimist": "^1.2.0", + "mqtt-packet": "^5.6.0", + "pump": "^3.0.0", + "readable-stream": "^2.3.6", + "reinterval": "^1.1.0", + "split2": "^2.1.1", + "websocket-stream": "^5.1.2", + "xtend": "^4.0.1" + } + } + } + }, "async-retry": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz", @@ -2261,9 +2343,9 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, "babel-plugin-dynamic-import-node": { "version": "2.3.0", @@ -2406,6 +2488,11 @@ } } }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -2606,6 +2693,36 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "buildmail": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-3.10.0.tgz", + "integrity": "sha1-xoJtcW55RbtvaxQ0tTmF4CmgMVk=", + "requires": { + "addressparser": "1.0.1", + "libbase64": "0.1.0", + "libmime": "2.1.0", + "libqp": "1.1.0", + "nodemailer-fetch": "1.6.0", + "nodemailer-shared": "1.1.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=" + }, + "libmime": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.0.tgz", + "integrity": "sha1-Ubx23iKDFh65BRxLyArtcT5P0c0=", + "requires": { + "iconv-lite": "0.4.13", + "libbase64": "0.1.0", + "libqp": "1.1.0" + } + } + } + }, "bundle-dependencies": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bundle-dependencies/-/bundle-dependencies-1.0.2.tgz", @@ -3063,14 +3180,40 @@ "dev": true }, "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } } }, "call-matcher": { @@ -3104,6 +3247,15 @@ "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", "dev": true }, + "callback-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz", + "integrity": "sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "> 1.0.0 < 3.0.0" + } + }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", @@ -3365,7 +3517,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", @@ -3375,14 +3526,12 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -3472,6 +3621,15 @@ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, + "commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "requires": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, "commitizen": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.0.3.tgz", @@ -4286,7 +4444,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" }, @@ -4294,8 +4451,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -4378,6 +4534,34 @@ } } }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -4426,6 +4610,15 @@ "word-wrap": "^1.0.3" } }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "dargs": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", @@ -4558,18 +4751,11 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" }, "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "requires": { - "strip-bom": "^4.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - } + "strip-bom": "^3.0.0" } }, "defaults": { @@ -4740,6 +4926,11 @@ "streamsearch": "0.1.2" } }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4755,6 +4946,14 @@ } } }, + "dkim-signer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dkim-signer/-/dkim-signer-0.2.2.tgz", + "integrity": "sha1-qoHsBx7u02IngbqpIgRNeADl8wg=", + "requires": { + "libmime": "^2.0.3" + } + }, "dl-tgz": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/dl-tgz/-/dl-tgz-0.7.1.tgz", @@ -4832,9 +5031,9 @@ } }, "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz", + "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -4940,6 +5139,17 @@ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -5061,17 +5271,82 @@ "is-symbol": "^1.0.2" } }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, "es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", "dev": true }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -5742,6 +6017,15 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -5888,6 +6172,21 @@ "resolved": "https://registry.npmjs.org/express-list-endpoints/-/express-list-endpoints-4.0.1.tgz", "integrity": "sha512-KjY7frYk72/Jwk2VgqyvuXlTPslEkWkzjUXPUMCUguVmAWqd6fh60VHr+sEfqJgMAOE3hKhUjm/7tLASVaE2Qg==" }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -6008,6 +6307,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -6020,6 +6320,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -6209,49 +6510,36 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" + "cross-spawn": "^4", + "signal-exit": "^3.0.0" }, "dependencies": { "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "lru-cache": "^4.0.1", + "which": "^1.2.9" } }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "requires": { - "shebang-regex": "^3.0.0" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" } } }, @@ -6351,6 +6639,11 @@ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -6789,6 +7082,42 @@ "is-glob": "^4.0.1" } }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, "glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", @@ -6835,6 +7164,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, "requires": { "@types/glob": "^7.1.1", "array-union": "^2.1.0", @@ -7136,18 +7466,32 @@ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" }, "hasha": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.1.0.tgz", - "integrity": "sha512-OFPDWmzPN1l7atOV1TgBVmNtBxaIysToK6Ve9DK+vT6pYuklw/nPNT+HJbZi0KDcI6vWB+9tgvZ5YD7fA3CXcA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" + "is-stream": "^1.0.1" + } + }, + "help-me": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz", + "integrity": "sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y=", + "requires": { + "callback-stream": "^1.0.2", + "glob-stream": "^6.1.0", + "through2": "^2.0.1", + "xtend": "^4.0.0" }, "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } } } }, @@ -7479,6 +7823,15 @@ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==" }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -7653,6 +8006,11 @@ "js-types": "^1.0.0" } }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=" + }, "is-npm": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-3.0.0.tgz", @@ -7839,169 +8197,30 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" }, "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "requires": { - "append-transform": "^2.0.0" + "append-transform": "^1.0.0" } }, "istanbul-lib-instrument": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz", - "integrity": "sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "requires": { - "@babel/core": "^7.7.5", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "@babel/core": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.7.tgz", - "integrity": "sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.7", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.7", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "@babel/generator": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz", - "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==", - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helpers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", - "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", - "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/parser": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz", - "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==" - }, - "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" } }, "istanbul-lib-processinfo": { @@ -8028,6 +8247,11 @@ "which": "^2.0.1" } }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -8065,37 +8289,48 @@ } }, "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" }, "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "requires": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" } } } }, "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "requires": { "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { @@ -8107,6 +8342,20 @@ "ms": "^2.1.1" } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8115,12 +8364,11 @@ } }, "istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "html-escaper": "^2.0.0" } }, "iterall": { @@ -8325,6 +8573,11 @@ "invert-kv": "^2.0.0" } }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -8334,6 +8587,33 @@ "type-check": "~0.3.2" } }, + "libbase64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", + "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=" + }, + "libmime": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.3.tgz", + "integrity": "sha1-JQF8pataHpiq2+JyUBfPHUikKgw=", + "requires": { + "iconv-lite": "0.4.15", + "libbase64": "0.1.0", + "libqp": "1.1.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" + } + } + }, + "libqp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", + "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=" + }, "libvirt": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/libvirt/-/libvirt-1.2.1.tgz", @@ -8593,6 +8873,32 @@ "yallist": "^3.0.2" } }, + "mailcomposer": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-3.12.0.tgz", + "integrity": "sha1-nF4RiKqOHGLsi4a9Q0aBArY56Pk=", + "requires": { + "buildmail": "3.10.0", + "libmime": "2.1.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=" + }, + "libmime": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.0.tgz", + "integrity": "sha1-Ubx23iKDFh65BRxLyArtcT5P0c0=", + "requires": { + "iconv-lite": "0.4.13", + "libbase64": "0.1.0", + "libqp": "1.1.0" + } + } + } + }, "make-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", @@ -8601,6 +8907,11 @@ "semver": "^6.0.0" } }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -8822,6 +9133,21 @@ "tslib": "1.10.0" } }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -8935,12 +9261,13 @@ } }, "micromongo": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/micromongo/-/micromongo-0.2.14.tgz", - "integrity": "sha512-vpcKlXn5L7hDZW+xaYZbUy9gDTLlR8jb+54TVf023L2FEQ4CUALzQJfTeNSP4zJCWTIGG6sMuHOSV7VxZcBUOw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/micromongo/-/micromongo-0.3.0.tgz", + "integrity": "sha512-xPuj3fFIrc5QoZIiG5WG1eeBWZMMpj6viJGSUkBqKnog9OBrqexT3xzrbbqaQKKGKZaerKHfYHXznXhVEAR26Q==", "requires": { - "lodash": "^4.17.11", - "mini-deep-assign": "^0.0.8" + "lodash": "^4.17.15", + "mini-deep-assign": "^0.0.8", + "nyc": "^14.1.1" } }, "micromongo-class": { @@ -8948,6 +9275,17 @@ "from": "github:OmgImAlexis/micromongo-class#f98a9e1", "requires": { "micromongo": "^0.2.12" + }, + "dependencies": { + "micromongo": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/micromongo/-/micromongo-0.2.14.tgz", + "integrity": "sha512-vpcKlXn5L7hDZW+xaYZbUy9gDTLlR8jb+54TVf023L2FEQ4CUALzQJfTeNSP4zJCWTIGG6sMuHOSV7VxZcBUOw==", + "requires": { + "lodash": "^4.17.11", + "mini-deep-assign": "^0.0.8" + } + } } }, "mime": { @@ -8992,9 +9330,9 @@ } }, "minimist": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", - "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "minimist-options": { "version": "3.0.2", @@ -9078,6 +9416,83 @@ "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", "dev": true }, + "mqtt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-3.0.0.tgz", + "integrity": "sha512-0nKV6MAc1ibKZwaZQUTb3iIdT4NVpj541BsYrqrGBcQdQ7Jd0MnZD1/6/nj1UFdGTboK9ZEUXvkCu2nPCugHFA==", + "requires": { + "base64-js": "^1.3.0", + "commist": "^1.0.0", + "concat-stream": "^1.6.2", + "end-of-stream": "^1.4.1", + "es6-map": "^0.1.5", + "help-me": "^1.0.1", + "inherits": "^2.0.3", + "minimist": "^1.2.0", + "mqtt-packet": "^6.0.0", + "pump": "^3.0.0", + "readable-stream": "^2.3.6", + "reinterval": "^1.1.0", + "split2": "^3.1.0", + "websocket-stream": "^5.1.2", + "xtend": "^4.0.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "mqtt-packet": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.3.0.tgz", + "integrity": "sha512-TjusSKu8uFZCmGZU8K6r4C3Ic+er/4r8rva+Mp5GQgWg/KjSdAfLK/GTucBwkdATE2Z0Da8AssI2WHzs0M9W0w==", + "requires": { + "bl": "^1.2.2", + "inherits": "^2.0.3", + "process-nextick-args": "^2.0.0", + "safe-buffer": "^5.1.2" + } + }, + "split2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.1.1.tgz", + "integrity": "sha512-emNzr1s7ruq4N+1993yht631/JH+jaj0NYBosuKmLcq+JkGQ9MmTw1RB1fGaTCzUuseRIClrlSLHRNYGwWQ58Q==", + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz", + "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + } + } + }, + "mqtt-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.6.1.tgz", + "integrity": "sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww==", + "requires": { + "bl": "^1.2.1", + "inherits": "^2.0.3", + "process-nextick-args": "^2.0.0", + "safe-buffer": "^5.1.0" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -9197,6 +9612,16 @@ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -9456,6 +9881,19 @@ "process-on-spawn": "^1.0.0" } }, + "nodemailer-fetch": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", + "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=" + }, + "nodemailer-shared": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", + "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", + "requires": { + "nodemailer-fetch": "1.6.0" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -9557,175 +9995,129 @@ "dev": true }, "nyc": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.0.tgz", - "integrity": "sha512-qcLBlNCKMDVuKb7d1fpxjPR8sHeMVX0CHarXAVzrVWoFrigCkYR8xcrjfXSPi5HXM7EU78L6ywO7w1c5rZNCNg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", "js-yaml": "^3.13.1", - "make-dir": "^3.0.0", - "node-preload": "^0.2.0", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "uuid": "^3.3.3", - "yargs": "^15.0.2" + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "find-cache-dir": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz", - "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "requires": { "commondir": "^1.0.1", - "make-dir": "^3.0.0", - "pkg-dir": "^4.1.0" + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-fullwidth-code-point": { + "find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "requires": { - "glob": "^7.1.3" + "locate-path": "^3.0.0" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, "yargs": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", - "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", + "cliui": "^5.0.0", + "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^4.2.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^16.1.0" + "yargs-parser": "^13.1.1" } } } @@ -9999,6 +10391,19 @@ } } }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", @@ -10085,12 +10490,12 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", "requires": { "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", + "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" } @@ -10450,6 +10855,27 @@ "once": "^1.3.1" } }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -10544,6 +10970,47 @@ "path-type": "^3.0.0" } }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -10718,6 +11185,11 @@ } } }, + "reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -10789,6 +11261,17 @@ } } }, + "request-promise": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz", + "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==", + "requires": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, "request-promise-core": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", @@ -10940,7 +11423,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -11052,6 +11534,15 @@ } } }, + "sendmail": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sendmail/-/sendmail-1.6.1.tgz", + "integrity": "sha512-lIhvnjSi5e5jL8wA1GPP6j2QVlx6JOEfmdn0QIfmuJdmXYGmJ375kcOU0NSm/34J+nypm4sa1AXrYE5w3uNIIA==", + "requires": { + "dkim-signer": "0.2.2", + "mailcomposer": "3.12.0" + } + }, "serialize-error": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", @@ -11316,7 +11807,6 @@ "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -11325,8 +11815,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -11336,34 +11825,16 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", + "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "dependencies": { - "rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", - "requires": { - "glob": "^7.1.3" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } + "which": "^1.3.0" } }, "spdx-correct": { @@ -11420,7 +11891,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", - "dev": true, "requires": { "through2": "^2.0.2" }, @@ -11429,7 +11899,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -11643,6 +12112,11 @@ "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==" }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "streamsearch": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", @@ -11845,9 +12319,9 @@ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, "systeminformation": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-4.18.1.tgz", - "integrity": "sha512-VvJ0SKvo8tXAYwFjQkJVzQyy9x/4ubPn2CMdFHER3r1K7AIXSFUZHNlNghi6uBRp5MYTalo9BrIYMx6nSuqU1A==" + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-4.19.1.tgz", + "integrity": "sha512-6Jb+0aepgRb2B4vFgxKKcrr8QexhERkPX1z0EzIyCKDMQjILt+ZbNtFxrGjFwa67tn9Wbqs1L5t/CjCUwB1FcA==" }, "table": { "version": "5.4.6", @@ -11996,13 +12470,14 @@ } }, "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" } }, "text-extensions": { @@ -12035,6 +12510,26 @@ "readable-stream": "2 || 3" } }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, "time-zone": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", @@ -12054,6 +12549,15 @@ "os-tmpdir": "~1.0.2" } }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", @@ -12139,10 +12643,535 @@ "tinytim": "0.1.1" }, "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/core": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", + "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helpers": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "@babel/generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", + "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.3.tgz", + "integrity": "sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==", + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", + "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==" + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", + "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "requires": { + "strip-bom": "^4.0.0" + } + }, + "find-cache-dir": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz", + "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.0", + "pkg-dir": "^4.1.0" + } + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "hasha": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.1.0.tgz", + "integrity": "sha512-OFPDWmzPN1l7atOV1TgBVmNtBxaIysToK6Ve9DK+vT6pYuklw/nPNT+HJbZi0KDcI6vWB+9tgvZ5YD7fA3CXcA==", + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz", + "integrity": "sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ==", + "requires": { + "@babel/core": "^7.7.5", + "@babel/parser": "^7.7.5", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "nyc": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.0.tgz", + "integrity": "sha512-qcLBlNCKMDVuKb7d1fpxjPR8sHeMVX0CHarXAVzrVWoFrigCkYR8xcrjfXSPi5HXM7EU78L6ywO7w1c5rZNCNg==", + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.0", + "js-yaml": "^3.13.1", + "make-dir": "^3.0.0", + "node-preload": "^0.2.0", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "uuid": "^3.3.3", + "yargs": "^15.0.2" + } + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "rimraf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", + "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^16.1.0" + } + }, + "yargs-parser": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", + "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, @@ -12163,6 +13192,19 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "ts-brand": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ts-brand/-/ts-brand-0.0.2.tgz", + "integrity": "sha512-UhSzWY4On9ZHIj6DKkRYVN/8OaprbLAZ3b/Y2AJwdl6oozSABsQ0PvwDh4vOVdkvOtWQOkIrjctZ1kj8YfF3jA==" + }, + "ts-brand-json": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ts-brand-json/-/ts-brand-json-0.1.1.tgz", + "integrity": "sha512-2Lb/g531rUtKBLlXnJDmWbEE+Mzv4SuxNDSVqWB2HHS5AJZ9Yh4bl6wFaNsAqWnhDg0zD3zi/oGhS//cDINQpw==", + "requires": { + "ts-brand": "^0.0.2" + } + }, "ts-invariant": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", @@ -12171,6 +13213,18 @@ "tslib": "^1.9.3" } }, + "ts-node": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", + "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "3.1.1" + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -12189,6 +13243,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -12224,6 +13283,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "dev": true + }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -12255,6 +13320,11 @@ "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", "dev": true }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -12304,6 +13374,15 @@ "set-value": "^2.0.1" } }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, "unique-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", @@ -12512,6 +13591,38 @@ "defaults": "^1.0.3" } }, + "websocket-stream": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.5.0.tgz", + "integrity": "sha512-EXy/zXb9kNHI07TIMz1oIUIrPZxQRA8aeJ5XYg5ihV8K4kD1DuA+FY6R96HfdIHzlSzS8HiISAfrm+vVQkZBug==", + "requires": { + "duplexify": "^3.5.1", + "inherits": "^2.0.1", + "readable-stream": "^2.3.3", + "safe-buffer": "^5.1.2", + "ws": "^3.2.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + } + } + }, "well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", @@ -12590,7 +13701,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -12600,14 +13710,12 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -13022,17 +14130,29 @@ "integrity": "sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=", "requires": { "minimist": "^0.1.0" + }, + "dependencies": { + "minimist": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", + "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=" + } } }, "yargs-parser": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", - "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, "zen-observable": { "version": "0.8.14", "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.14.tgz", diff --git a/package.json b/package.json index 3a28e0403..eae2ff2b9 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "@unraid/graphql-api", "version": "2.1.9", - "main": "index.js", + "main": "dist/index.js", "repository": "git@github.com:unraid/graphql-api.git", "author": "Alexis Tyler (https://wvvw.me/)", "license": "UNLICENSED", "scripts": { - "build": "modclean --no-progress --run --path .", + "build": "tsc", + "clean": "modclean --no-progress --run --path .", "commit": "npx git-cz", "lint": "xo --verbose", "lint:quiet": "xo --quiet", @@ -26,7 +27,7 @@ ], "dependencies": { "@gridplus/docker-events": "^1.0.0", - "@unraid/core": "github:unraid/core#master", + "@unraid/core": "github:unraid/core#feature/add-better-typing", "accesscontrol": "^2.2.1", "am": "^1.0.1", "apollo-datasource-rest": "^0.6.11", @@ -44,9 +45,11 @@ "lodash.get": "^4.4.2", "merge-graphql-schemas": "^1.7.6", "p-props": "^3.1.0", + "request-promise": "4.2.5", "set-interval-async": "^1.0.30", "stoppable": "^1.1.0", - "subscriptions-transport-ws": "^0.9.16" + "subscriptions-transport-ws": "^0.9.16", + "ts-node": "8.6.2" }, "optionalDependencies": {}, "devDependencies": { @@ -59,6 +62,7 @@ "modclean": "^3.0.0-beta.1", "node-env-run": "^3.0.2", "standard-version": "^7.0.1", + "typescript": "3.7.5", "xo": "^0.25.3" }, "bundledDependencies": [ diff --git a/src/graphql/index.ts b/src/graphql/index.ts new file mode 100644 index 000000000..b522f346f --- /dev/null +++ b/src/graphql/index.ts @@ -0,0 +1,337 @@ +/*! + * Copyright 2019-2020 Lime Technology Inc. All rights reserved. + * Written by: Alexis Tyler + */ + +import get from 'lodash.get'; +// @ts-ignore +// import * as core from '../../../core/src/index'; +import core from '@unraid/core'; +import { makeExecutableSchema, SchemaDirectiveVisitor } from 'graphql-tools' +import { mergeTypes } from 'merge-graphql-schemas'; +import gql from 'graphql-tag'; +import { typeDefs, resolvers } from './schema'; +import { increaseWsConectionCount, decreaseWsConectionCount } from '../ws'; + +const { apiManager, errors, log, states, config } = core; +const { AppError, FatalAppError } = errors; +const { usersState } = states; + +const baseTypes = [gql` + scalar JSON + scalar Long + scalar UUID + + directive @func( + module: String + data: JSON + query: JSON + result: String + extractFromResponse: String + ) on FIELD_DEFINITION + + directive @subscription( + channel: String! + ) on FIELD_DEFINITION + + type Welcome { + message: String! + } + + type Query { + # This should always be available even for guest users + welcome: Welcome! @func(module: "getWelcome") + info: Info! + pluginModule(plugin: String!, module: String!, params: JSON, result: String): JSON @func(result: "json") + } + + type Mutation { + login(username: String!, password: String!): String + + shutdown: String + reboot: String + } + + enum MutationType { + CREATED + UPDATED + DELETED + } + + enum UpdateOnlyMutationType { + UPDATED + } + + type PingSubscription { + mutation: MutationType! + node: String! + } + + type InfoSubscription { + mutation: MutationType! + node: Info! + } + + type PluginModuleSubscription { + mutation: MutationType! + node: JSON! + } + + type Subscription { + ping: PingSubscription! + info: InfoSubscription! + pluginModule(plugin: String!, module: String!, params: JSON, result: String): PluginModuleSubscription! + } +`]; + +// Add test defs in dev mode +if (process.env.NODE_ENV === 'development') { + const testDefs = gql` + # Test query + input testQueryInput { + state: String! + optional: Boolean + } + type Query { + testQuery(id: String!, input: testQueryInput): JSON @func(module: "getContext") + } + + # Test mutation + input testMutationInput { + state: String! + } + type Mutation { + testMutation(id: String!, input: testMutationInput): JSON @func(module: "getContext") + } + + # Test subscription + type Subscription { + testSubscription: String! + } + `; + baseTypes.push(testDefs); +} + +// Add debug defs to all envs apart from production +if (process.env.NODE_ENV !== 'production') { + const debugDefs = gql` + # Debug query + type Context { + query: JSON + params: JSON + data: JSON + user: JSON + } + + type Query { + context: Context @func(module: "getContext") + } + `; + baseTypes.push(debugDefs); +} + +const types = mergeTypes([ + ...baseTypes, + typeDefs +]); + +/** + * Func directive + * + * @see https://github.com/smooth-code/graphql-directive/blob/master/README.md#directive-resolver-function-signature + * + * @param {object} obj + * The result returned from the resolver on the parent field, or, in the case of a top-level Query field, + * the rootValue passed from the server configuration. + * @param {object} directiveArgs + * An object with the arguments passed into the directive in the query or schema. + * For example, if the directive was called with `@dateFormat(format: "DD/MM/YYYY")`, + * the args object would be: `{ "format": "DD/MM/YYYY" }`. + * @param {object} context + * This is an object shared by all resolvers in a particular query, + * and is used to contain per-request state, including authentication information, + * dataloader instances, and anything else that should be taken into account when resolving the query. + * @param {object} info + * This argument should only be used in advanced cases, + * but it contains information about the execution state of the query, + * including the field name, path to the field from the root, and more. + */ +class FuncDirective extends SchemaDirectiveVisitor { + visitFieldDefinition(field) { + const {args} = this; + field.resolve = async function (source, directiveArgs, { user }, info) { + const {module: moduleName, result: resultType} = args; + const {plugin: pluginName, module: pluginModuleName, result: pluginType, input, ...params} = directiveArgs; + const operationType = info.operation.operation; + const query = { + ...directiveArgs.query, + ...(operationType === 'query' ? input : {}) + }; + const data = { + ...directiveArgs.data, + ...(operationType === 'mutation' ? input : {}) + }; + // let funcPath = path.join(coreCwd, moduleName + '.js'); + + // If we're looking for a plugin verify it's installed and active first + // if (pluginName) { + // if (!PluginManager.isInstalled(pluginName, pluginModuleName)) { + // throw new PluginError('Plugin not installed.'); + // } + + // if (!PluginManager.isActive(pluginName, pluginModuleName)) { + // throw new PluginError('Plugin disabled.'); + // } + + // const pluginModule = PluginManager.get(pluginName, pluginModuleName); + // // Update plugin funcPath + // funcPath = pluginModule.filePath; + // } + + // Create func context + // If query @func(param_1, param_2, input: query?) + // If mutation @func(param_1, param_2, input: data) + const context = { + query, + params, + data, + user + }; + + // Resolve func + let func; + + if (!Object.keys(core.modules).includes(moduleName)) { + throw new FatalAppError(`"${moduleName}" is not a valid core module.`); + } + + try { + func = core.modules[moduleName] + } catch (error_) { + // Rethrow clean error message about module being missing + if (error_.code === 'MODULE_NOT_FOUND') { + throw new AppError(`Cannot find ${pluginName ? 'Plugin: "' + pluginName + '" ' : ''}Module: "${pluginName ? pluginModuleName : moduleName}"`); + } + + // In production let's just throw an internal error + if (process.env.NODE_ENV === 'production') { + throw new AppError('Internal error occurred'); + } + + // Otherwise re-throw actual error + throw error_; + } + + const pluginOrModule = pluginName ? 'Plugin:' : 'Module:'; + const pluginOrModuleName = pluginModuleName || moduleName; + + // Run function + let [error, result] = await Promise.resolve(func(context)) + .then(result => [undefined, result]) + .catch(error_ => { + // Ensure we aren't leaking anything in production + if (process.env.NODE_ENV === 'production') { + log.error(pluginOrModule, pluginOrModuleName, 'Error:', error_.message); + return [new Error(error_.message)]; + } + + const logger = log[error_.status && error_.status >= 400 ? 'error' : 'warn']; + logger(pluginOrModule, pluginOrModuleName, 'Error:', error_); + return [error_]; + }); + + // Bail if we can't get the method to run + if (error) { + return error; + } + + // Get wanted result type or fallback to json + result = result[pluginType || resultType || 'json']; + + // Allow fields to be extracted + if (directiveArgs.extractFromResponse) { + result = get(result, directiveArgs.extractFromResponse); + } + + log.debug(pluginOrModule, pluginOrModuleName, 'Result:', result); + return result; + }; + } +} + +const schema = makeExecutableSchema({ + typeDefs: types, + resolvers, + schemaDirectives: { + func: FuncDirective + } +}); + +const ensureApiKey = (apiKeyToCheck: string) => { + // Check there is atleast one valid key + if (core.apiManager.getValidKeys().length !== 0) { + if (!apiKeyToCheck) { + throw new AppError('Missing API key.'); + } + + if (!apiManager.isValid(apiKeyToCheck)) { + throw new AppError('Invalid API key.'); + } + } else { + if (process.env.NODE_ENV !== 'development') { + throw new AppError('No valid API keys active.'); + } + } +}; + +const debug = config.get('debug') === true; + +export const graphql = { + introspection: debug, + playground: debug, + schema, + types, + resolvers, + subscriptions: { + onConnect: connectionParams => { + const apiKey = connectionParams['x-api-key']; + + ensureApiKey(apiKey); + + const user = usersState.findOne({apiKey}) || { name: 'guest', apiKey, role: 'guest' }; + + log.info(` ${user.name} connected.`); + + // Update ws connection count + increaseWsConectionCount(); + + return { + user + }; + }, + onDisconnect: async (_, websocketContext) => { + const initialContext = await websocketContext.initPromise; + log.info(` ${initialContext.user.name} disconnected.`); + + // Update ws connection count + decreaseWsConectionCount(); + } + }, + context: ({req, connection}) => { + if (connection) { + // Check connection for metadata + return { + ...connection.context + }; + } + + const apiKey = req.headers['x-api-key']; + ensureApiKey(apiKey); + + const user = usersState.findOne({apiKey}) || {name: 'guest', apiKey, role: 'guest'}; + + return { + user + }; + } +}; diff --git a/src/graphql/schema/index.ts b/src/graphql/schema/index.ts new file mode 100644 index 000000000..a5d3ac971 --- /dev/null +++ b/src/graphql/schema/index.ts @@ -0,0 +1,2 @@ +export * from './resolvers'; +export * from './type-defs'; \ No newline at end of file diff --git a/src/graphql/schema/resolvers.ts b/src/graphql/schema/resolvers.ts new file mode 100644 index 000000000..c13fb937b --- /dev/null +++ b/src/graphql/schema/resolvers.ts @@ -0,0 +1,170 @@ +/*! + * Copyright 2019-2020 Lime Technology Inc. All rights reserved. + * Written by: Alexis Tyler + */ + +import core from '@unraid/core'; +// @ts-ignore +// import * as core from '../../../../core/src/index'; +import dee from '@gridplus/docker-events'; +import { setIntervalAsync } from 'set-interval-async/dynamic'; +import GraphQLJSON from 'graphql-type-json'; +import GraphQLLong from 'graphql-type-long'; +import GraphQLUUID from 'graphql-type-uuid'; +import { run, canPublishToClients, updatePubsub } from '../../run'; + +const { pluginManager, pubsub, utils, log, bus, errors } = core; +const { PluginError } = errors; + +// Send test message every 1 second for 10 seconds. +const startPing = async (interval = 1000, total = 10) => { + await run('ping', 'UPDATED', { + node: 'PONG!', + interval, + total + }); +}; + +// Receive test messages. +// pubsub.subscribe('ping', (...rest) => { +// console.log(`CHANNEL: ping DATA: ${JSON.stringify(rest, null, 2)}`); +// }); + +// Update array values when disks change +bus.on('disks', async () => { + await run('array', 'UPDATED', { + moduleToRun: core.modules.getArray, + context: {} + }); +}); + +const createBasicSubscription = name => ({ + subscribe: async () => { + return pubsub.asyncIterator(name); + } +}); + +// On Docker event update info with { apps: { installed, started } } +const updatePubsubWithDockerEvent = async () => { + if (!canPublishToClients()) { + return; + } + + const { json } = await core.modules.getApps(); + updatePubsub('info', 'UPDATED', json); +}; + +dee.on('start', updatePubsubWithDockerEvent); +dee.on('stop', updatePubsubWithDockerEvent); + +dee.listen(); + +// Republish bus events to pubsub when clients connect +// We need to filter to only the endpoint that're currently connected +// bus.on('*', (...args) => { +// if (!canPublishToClients()) { +// return; +// } + +// const { +// [args.length - 1]: last, +// ...rest +// } = args; + +// pubsub.publish(...Object.values(rest)); +// }); + +// This needs to be fixed to run from events +setIntervalAsync(async () => { + if (!canPublishToClients()) { + return; + } + + await run('services', 'UPDATED', { + moduleToRun: core.modules.getServices + }); +}, 1000); + +export const resolvers = { + Query: { + info: () => ({}), + vms: () => ({}) + }, + Subscription: { + apikeys: { + // Not sure how we're going to secure this + ...createBasicSubscription('apikeys') + }, + array: { + ...createBasicSubscription('array') + }, + devices: { + ...createBasicSubscription('devices') + }, + dockerContainers: { + ...createBasicSubscription('docker/containers') + }, + dockerNetworks: { + ...createBasicSubscription('docker/networks') + }, + info: { + ...createBasicSubscription('info') + }, + ping: { + subscribe: () => { + startPing(); + return pubsub.asyncIterator('ping'); + } + }, + services: { + ...createBasicSubscription('services') + }, + shares: { + ...createBasicSubscription('shares') + }, + unassignedDevices: { + ...createBasicSubscription('devices/unassigned') + }, + users: { + ...createBasicSubscription('users') + }, + vars: { + ...createBasicSubscription('vars') + }, + vms: { + ...createBasicSubscription('vms/domains') + }, + pluginModule: { + subscribe: async (_, directiveArgs) => { + const {plugin: pluginName, module: pluginModuleName} = directiveArgs; + const name = `${pluginName}/${pluginModuleName}`; + + // Verify plugin is installed and active + if (!pluginManager.isInstalled(pluginName, pluginModuleName)) { + throw new PluginError('Plugin not installed.'); + } + + if (!pluginManager.isActive(pluginName, pluginModuleName)) { + throw new PluginError('Plugin disabled.'); + } + + // It's up to the plugin to publish new data as needed + // so we'll just return the Iterator + return pubsub.asyncIterator(name); + } + } + }, + JSON: GraphQLJSON, + Long: GraphQLLong, + UUID: GraphQLUUID, + UserAccount: { + __resolveType(obj) { + // Only a user has a password field, the current user aka "me" doesn't. + if (obj.password) { + return 'User'; + } + + return 'Me'; + } + } +}; \ No newline at end of file diff --git a/src/graphql/schema/type-defs.ts b/src/graphql/schema/type-defs.ts new file mode 100644 index 000000000..6bd6eda04 --- /dev/null +++ b/src/graphql/schema/type-defs.ts @@ -0,0 +1,13 @@ +/*! + * Copyright 2019-2020 Lime Technology Inc. All rights reserved. + * Written by: Alexis Tyler + */ + +import { join } from 'path'; +import { fileLoader, mergeTypes } from 'merge-graphql-schemas'; + +const files = fileLoader(join(__dirname, './types/**/*.graphql')); + +export const typeDefs = mergeTypes(files, { + all: true +}); diff --git a/app/graphql/schema/types/apikeys/apikey.graphql b/src/graphql/schema/types/apikeys/apikey.graphql similarity index 81% rename from app/graphql/schema/types/apikeys/apikey.graphql rename to src/graphql/schema/types/apikeys/apikey.graphql index a48c26e2d..70afd92de 100644 --- a/app/graphql/schema/types/apikeys/apikey.graphql +++ b/src/graphql/schema/types/apikeys/apikey.graphql @@ -9,15 +9,15 @@ input updateApikeyInput { type Query { """Get all apikeys""" - apiKeys: [ApiKey] @func(module: "get-apikeys") + apiKeys: [ApiKey] @func(module: "getApikeys") } type Mutation { """Get user apikey""" - getApiKey(name: String!, input: authenticateInput): ApiKey @func(module: "apikeys/name/get-apikey") + getApiKey(name: String!, input: authenticateInput): ApiKey @func(module: "getApikey") """Update apikey""" - updateApikey(name: String!, input: updateApikeyInput): ApiKey @func(module: "apikeys/name/update-apikey") + updateApikey(name: String!, input: updateApikeyInput): ApiKey @func(module: "updateApikey") } type ApikeysSubscription { diff --git a/app/graphql/schema/types/array/array.graphql b/src/graphql/schema/types/array/array.graphql similarity index 93% rename from app/graphql/schema/types/array/array.graphql rename to src/graphql/schema/types/array/array.graphql index 38fb30e7a..f95a2516a 100644 --- a/app/graphql/schema/types/array/array.graphql +++ b/src/graphql/schema/types/array/array.graphql @@ -1,18 +1,18 @@ type Query { """An Unraid array consisting of 1 or 2 Parity disks and a number of Data disks.""" - array: Array @func(module: "get-array") + array: Array @func(module: "getArray") } type Mutation { """Start array""" - startArray: Array @func(module: "array/update-array", data: { state: "start" }) + startArray: Array @func(module: "updateArray", data: { state: "start" }) """Stop array""" - stopArray: Array @func(module: "array/update-array", data: { state: "stop" }) + stopArray: Array @func(module: "updateArray", data: { state: "stop" }) """Add new disk to array""" - addDiskToArray(input: arrayDiskInput): Array @func(module: "array/add-disk") + addDiskToArray(input: arrayDiskInput): Array @func(module: "addDiskToArray") """Remove existing disk from array. NOTE: The array must be stopped before running this otherwise it'll throw an error.""" - removeDiskFromArray(input: arrayDiskInput): Array @func(module: "array/add-disk") + removeDiskFromArray(input: arrayDiskInput): Array @func(module: "removeDiskFromArray") mountArrayDisk(id: ID!): Disk unmountArrayDisk(id: ID!): Disk diff --git a/src/graphql/schema/types/array/parity.graphql b/src/graphql/schema/types/array/parity.graphql new file mode 100644 index 000000000..c0497a966 --- /dev/null +++ b/src/graphql/schema/types/array/parity.graphql @@ -0,0 +1,31 @@ +type Query { + parityHistory: [ParityCheck] @func(module: "getParityHistory") +} + +type Mutation { + """Start parity check""" + startParityCheck(correct: Boolean): JSON @func(module: "updateParityCheck", data: { state: "start" }) + """Pause parity check""" + pauseParityCheck: JSON @func(module: "updateParityCheck", data: { state: "pause" }) + """Resume parity check""" + resumeParityCheck: JSON @func(module: "updateParityCheck", data: { state: "resume" }) + """Cancel parity check""" + cancelParityCheck: JSON @func(module: "updateParityCheck", data: { state: "cancel" }) +} + +type ParityHistorySubscription { + mutation: MutationType! + node: ParityCheck! +} + +type Subscription { + parityHistory: ParityHistorySubscription +} + +type ParityCheck { + date: String! + duration: Int! + speed: String! + status: String! + errors: String! +} \ No newline at end of file diff --git a/app/graphql/schema/types/devices/device.graphql b/src/graphql/schema/types/devices/device.graphql similarity index 83% rename from app/graphql/schema/types/devices/device.graphql rename to src/graphql/schema/types/devices/device.graphql index 7461674be..fe254c266 100644 --- a/app/graphql/schema/types/devices/device.graphql +++ b/src/graphql/schema/types/devices/device.graphql @@ -1,6 +1,7 @@ type Query { + # @todo fix this device(id: ID!): Device @func(module: "devices/device/get-device") - devices: [Device]! @func(module: "get-devices") + devices: [Device]! @func(module: "getDevices") } type Device { diff --git a/app/graphql/schema/types/disks/disk.graphql b/src/graphql/schema/types/disks/disk.graphql similarity index 90% rename from app/graphql/schema/types/disks/disk.graphql rename to src/graphql/schema/types/disks/disk.graphql index 8262929e6..ba02e76f1 100644 --- a/app/graphql/schema/types/disks/disk.graphql +++ b/src/graphql/schema/types/disks/disk.graphql @@ -1,8 +1,8 @@ type Query { """Single disk""" - disk(id: ID!): Disk @func(module: "disks/id/get-disk") + disk(id: ID!): Disk @func(module: "getDisk") """Mulitiple disks""" - disks: [Disk]! @func(module: "get-disks") + disks: [Disk]! @func(module: "getDisks") } type Disk { # /dev/sdb diff --git a/app/graphql/schema/types/docker/container.graphql b/src/graphql/schema/types/docker/container.graphql similarity index 91% rename from app/graphql/schema/types/docker/container.graphql rename to src/graphql/schema/types/docker/container.graphql index e8da93d4a..5cb962d7d 100644 --- a/app/graphql/schema/types/docker/container.graphql +++ b/src/graphql/schema/types/docker/container.graphql @@ -1,8 +1,8 @@ type Query { """Docker container""" - dockerContainer(id: ID!): DockerContainer! @func(module: "docker/get-container") + dockerContainer(id: ID!): DockerContainer! @func(module: "getDockerContainer") """All Docker containers""" - dockerContainers(all: Boolean): [DockerContainer]! @func(module: "docker/get-containers") + dockerContainers(all: Boolean): [DockerContainer]! @func(module: "getDockerContainers") } type DockerContainerSubscription { diff --git a/app/graphql/schema/types/docker/network.graphql b/src/graphql/schema/types/docker/network.graphql similarity index 88% rename from app/graphql/schema/types/docker/network.graphql rename to src/graphql/schema/types/docker/network.graphql index 7de7314bc..5bee2ce48 100644 --- a/app/graphql/schema/types/docker/network.graphql +++ b/src/graphql/schema/types/docker/network.graphql @@ -1,8 +1,8 @@ type Query { """Docker network""" - dockerNetwork(id: ID!): DockerNetwork! @func(module: "docker/get-network") + dockerNetwork(id: ID!): DockerNetwork! @func(module: "getDockerNetwork") """All Docker networks""" - dockerNetworks(all: Boolean): [DockerNetwork]! @func(module: "docker/get-networks") + dockerNetworks(all: Boolean): [DockerNetwork]! @func(module: "getDockerNetworks") } type DockerNetworkSubscription { diff --git a/app/graphql/schema/types/info/apps.graphql b/src/graphql/schema/types/info/apps.graphql similarity index 65% rename from app/graphql/schema/types/info/apps.graphql rename to src/graphql/schema/types/info/apps.graphql index 20e7a5633..5fdb0e46f 100644 --- a/app/graphql/schema/types/info/apps.graphql +++ b/src/graphql/schema/types/info/apps.graphql @@ -1,6 +1,6 @@ type Info { - """Stats on docker containers""" - apps: InfoApps @func(module: "info/get-apps") + """Count of docker containers""" + apps: InfoApps @func(module: "getAppCount") } type InfoApps { diff --git a/app/graphql/schema/types/info/baseboard.graphql b/src/graphql/schema/types/info/baseboard.graphql similarity index 74% rename from app/graphql/schema/types/info/baseboard.graphql rename to src/graphql/schema/types/info/baseboard.graphql index ef812320f..7a6a33a0c 100644 --- a/app/graphql/schema/types/info/baseboard.graphql +++ b/src/graphql/schema/types/info/baseboard.graphql @@ -1,5 +1,5 @@ type Info { - baseboard: Baseboard @func(module: "info/get-baseboard") + baseboard: Baseboard @func(module: "getBaseboard") } type Baseboard { diff --git a/app/graphql/schema/types/info/cpu.graphql b/src/graphql/schema/types/info/cpu.graphql similarity index 92% rename from app/graphql/schema/types/info/cpu.graphql rename to src/graphql/schema/types/info/cpu.graphql index c0940738a..17849a845 100644 --- a/app/graphql/schema/types/info/cpu.graphql +++ b/src/graphql/schema/types/info/cpu.graphql @@ -1,5 +1,5 @@ type Info { - cpu: InfoCpu @func(module: "info/get-cpu") + cpu: InfoCpu @func(module: "getCpu") } type InfoCpu { diff --git a/app/graphql/schema/types/info/devices.graphql b/src/graphql/schema/types/info/devices.graphql similarity index 97% rename from app/graphql/schema/types/info/devices.graphql rename to src/graphql/schema/types/info/devices.graphql index 1a98ed80e..047c84696 100644 --- a/app/graphql/schema/types/info/devices.graphql +++ b/src/graphql/schema/types/info/devices.graphql @@ -1,4 +1,5 @@ type Info { + # @todo finish this devices: Devices @func(module: "info/get-devices") } diff --git a/app/graphql/schema/types/info/display.graphql b/src/graphql/schema/types/info/display.graphql similarity index 88% rename from app/graphql/schema/types/info/display.graphql rename to src/graphql/schema/types/info/display.graphql index bf6751591..30e2afbc8 100644 --- a/app/graphql/schema/types/info/display.graphql +++ b/src/graphql/schema/types/info/display.graphql @@ -1,5 +1,5 @@ type Info { - display: Display @func(module: "info/get-display") + display: Display @func(module: "getDisplay") } type Display { diff --git a/src/graphql/schema/types/info/machine-id.graphql b/src/graphql/schema/types/info/machine-id.graphql new file mode 100644 index 000000000..fbcf069de --- /dev/null +++ b/src/graphql/schema/types/info/machine-id.graphql @@ -0,0 +1,4 @@ +type Info { + """Machine ID""" + machineId: ID @func(module: "getMachineId") +} \ No newline at end of file diff --git a/app/graphql/schema/types/info/memory.graphql b/src/graphql/schema/types/info/memory.graphql similarity index 91% rename from app/graphql/schema/types/info/memory.graphql rename to src/graphql/schema/types/info/memory.graphql index c569d5890..afee83115 100644 --- a/app/graphql/schema/types/info/memory.graphql +++ b/src/graphql/schema/types/info/memory.graphql @@ -1,5 +1,5 @@ type Info { - memory: InfoMemory @func(module: "info/get-memory") + memory: InfoMemory @func(module: "getMemory") } type InfoMemory { diff --git a/app/graphql/schema/types/info/os.graphql b/src/graphql/schema/types/info/os.graphql similarity index 85% rename from app/graphql/schema/types/info/os.graphql rename to src/graphql/schema/types/info/os.graphql index aa86162c5..21889c9dd 100644 --- a/app/graphql/schema/types/info/os.graphql +++ b/src/graphql/schema/types/info/os.graphql @@ -1,5 +1,5 @@ type Info { - os: Os @func(module: "info/get-os") + os: Os @func(module: "getOs") } type Os { diff --git a/app/graphql/schema/types/info/system.graphql b/src/graphql/schema/types/info/system.graphql similarity index 73% rename from app/graphql/schema/types/info/system.graphql rename to src/graphql/schema/types/info/system.graphql index 48b6da1b5..e5c6c630a 100644 --- a/app/graphql/schema/types/info/system.graphql +++ b/src/graphql/schema/types/info/system.graphql @@ -1,5 +1,5 @@ type Info { - system: System @func(module: "info/get-system") + system: System @func(module: "getSystem") } type System { diff --git a/app/graphql/schema/types/info/versions.graphql b/src/graphql/schema/types/info/versions.graphql similarity index 89% rename from app/graphql/schema/types/info/versions.graphql rename to src/graphql/schema/types/info/versions.graphql index ab4500fe0..4b0332441 100644 --- a/app/graphql/schema/types/info/versions.graphql +++ b/src/graphql/schema/types/info/versions.graphql @@ -1,5 +1,5 @@ type Info { - versions: Versions @func(module: "info/get-versions") + versions: Versions @func(module: "getSoftwareVersions") } type Versions { diff --git a/app/graphql/schema/types/plugins/plugin.graphql b/src/graphql/schema/types/plugins/plugin.graphql similarity index 88% rename from app/graphql/schema/types/plugins/plugin.graphql rename to src/graphql/schema/types/plugins/plugin.graphql index 6bad0ffa3..753d30d72 100644 --- a/app/graphql/schema/types/plugins/plugin.graphql +++ b/src/graphql/schema/types/plugins/plugin.graphql @@ -1,11 +1,11 @@ type Query { """Node plugins""" - plugins: [Plugin] @func(module: "get-plugins") + plugins: [Plugin] @func(module: "getPlugins") } type Mutation { """Install plugin via npm""" - addPlugin(name: String!, version: String): JSON @func(module: "add-plugin") + addPlugin(name: String!, version: String): JSON @func(module: "addPlugin") """Update plugin installed via npm""" updatePlugin(name: String!, version: String): JSON diff --git a/app/graphql/schema/types/scopes/scope.graphql b/src/graphql/schema/types/scopes/scope.graphql similarity index 83% rename from app/graphql/schema/types/scopes/scope.graphql rename to src/graphql/schema/types/scopes/scope.graphql index d875a87ed..ad726f79b 100644 --- a/app/graphql/schema/types/scopes/scope.graphql +++ b/src/graphql/schema/types/scopes/scope.graphql @@ -4,7 +4,7 @@ type Permissions { } type Query { - permissions: Permissions @func(module: "get-permissions") + permissions: Permissions @func(module: "getPermissions") } input addScopeInput { @@ -21,8 +21,10 @@ input addScopeToApiKeyInput { } type Mutation { + # @todo finish adding this to core """Add a new permission scope""" addScope(input: addScopeInput!): Scope @func(module: "add-scope") + # @todo finish adding this to core """Add a new permission scope to apiKey""" addScopeToApiKey(input: addScopeToApiKeyInput!): Scope @func(module: "apikeys/name/add-scope") } diff --git a/app/graphql/schema/types/services/service.graphql b/src/graphql/schema/types/services/service.graphql similarity index 85% rename from app/graphql/schema/types/services/service.graphql rename to src/graphql/schema/types/services/service.graphql index e3c647de1..290f8ec90 100644 --- a/app/graphql/schema/types/services/service.graphql +++ b/src/graphql/schema/types/services/service.graphql @@ -1,6 +1,7 @@ type Query { + # @todo finish this service(name: String!): Service @func(module: "services/name/get-service") - services: [Service] @func(module: "get-services") + services: [Service] @func(module: "getServices") } type ServiceSubscription { diff --git a/app/graphql/schema/types/shares/share.graphql b/src/graphql/schema/types/shares/share.graphql similarity index 94% rename from app/graphql/schema/types/shares/share.graphql rename to src/graphql/schema/types/shares/share.graphql index bcd4cf86c..b2f84ce24 100644 --- a/app/graphql/schema/types/shares/share.graphql +++ b/src/graphql/schema/types/shares/share.graphql @@ -1,6 +1,6 @@ type Query { """Network Shares""" - shares: [Share] @func(module: "get-shares") + shares: [Share] @func(module: "getShares") } type ShareSubscription { diff --git a/app/graphql/schema/types/unassigned-devices/mount.graphql b/src/graphql/schema/types/unassigned-devices/mount.graphql similarity index 100% rename from app/graphql/schema/types/unassigned-devices/mount.graphql rename to src/graphql/schema/types/unassigned-devices/mount.graphql diff --git a/app/graphql/schema/types/unassigned-devices/partition.graphql b/src/graphql/schema/types/unassigned-devices/partition.graphql similarity index 100% rename from app/graphql/schema/types/unassigned-devices/partition.graphql rename to src/graphql/schema/types/unassigned-devices/partition.graphql diff --git a/app/graphql/schema/types/unassigned-devices/unassigned-device.graphql b/src/graphql/schema/types/unassigned-devices/unassigned-device.graphql similarity index 95% rename from app/graphql/schema/types/unassigned-devices/unassigned-device.graphql rename to src/graphql/schema/types/unassigned-devices/unassigned-device.graphql index 57133fcfd..86764231a 100644 --- a/app/graphql/schema/types/unassigned-devices/unassigned-device.graphql +++ b/src/graphql/schema/types/unassigned-devices/unassigned-device.graphql @@ -1,5 +1,5 @@ type Query { - unassignedDevices: [UnassignedDevice] @func(module: "get-unassigned-devices") + unassignedDevices: [UnassignedDevice] @func(module: "getUnassignedDevices") } type UnassignedDevicesSubscription { diff --git a/app/graphql/schema/types/users/me.graphql b/src/graphql/schema/types/users/me.graphql similarity index 90% rename from app/graphql/schema/types/users/me.graphql rename to src/graphql/schema/types/users/me.graphql index 752353981..377b060aa 100644 --- a/app/graphql/schema/types/users/me.graphql +++ b/src/graphql/schema/types/users/me.graphql @@ -1,6 +1,6 @@ type Query { """Current user account""" - me: Me @func(module: "get-me") + me: Me @func(module: "getMe") } # type Mutation { diff --git a/app/graphql/schema/types/users/user.graphql b/src/graphql/schema/types/users/user.graphql similarity index 74% rename from app/graphql/schema/types/users/user.graphql rename to src/graphql/schema/types/users/user.graphql index b28941b6a..0a52e93f6 100644 --- a/app/graphql/schema/types/users/user.graphql +++ b/src/graphql/schema/types/users/user.graphql @@ -11,9 +11,9 @@ input usersInput { type Query { """User account""" - user(id: ID!): User @func(module: "users/id/get-user") + user(id: ID!): User @func(module: "getUser") """User accounts""" - users(input: usersInput): [User!]! @func(module: "get-users", query: { slim: false }) + users(input: usersInput): [User!]! @func(module: "getUsers", query: { slim: false }) } input addUserInput { @@ -28,9 +28,9 @@ input deleteUserInput { type Mutation { """Add a new user""" - addUser(input: addUserInput!): User @func(module: "add-user") + addUser(input: addUserInput!): User @func(module: "addUser") """Delete a user""" - deleteUser(input: deleteUserInput!): User @func(module: "users/id/delete-user") + deleteUser(input: deleteUserInput!): User @func(module: "deleteUser") } type UserSubscription { diff --git a/app/graphql/schema/types/vars/vars.graphql b/src/graphql/schema/types/vars/vars.graphql similarity index 99% rename from app/graphql/schema/types/vars/vars.graphql rename to src/graphql/schema/types/vars/vars.graphql index 2ae73319e..f080c907b 100644 --- a/app/graphql/schema/types/vars/vars.graphql +++ b/src/graphql/schema/types/vars/vars.graphql @@ -1,5 +1,5 @@ type Query { - vars: Vars @func(module: "get-vars") + vars: Vars @func(module: "getVars") } type VarsSubscription { diff --git a/app/graphql/schema/types/vms/domain.graphql b/src/graphql/schema/types/vms/domain.graphql similarity index 88% rename from app/graphql/schema/types/vms/domain.graphql rename to src/graphql/schema/types/vms/domain.graphql index 82e5006d1..36101fa25 100644 --- a/app/graphql/schema/types/vms/domain.graphql +++ b/src/graphql/schema/types/vms/domain.graphql @@ -1,12 +1,12 @@ type Query { """Virtual machine""" - vm(name: String!): VmDomain! @func(module: "vms/domains/domain/get-domain") + vm(name: String!): VmDomain! @func(module: "getDomain") """Virtual machines""" vms: Vms } type Vms { - domains: [VmDomain!] @func(module: "vms/get-domains") + domains: [VmDomain!] @func(module: "getDomains") } type VmDomainSubscription { diff --git a/app/graphql/schema/types/vms/network.graphql b/src/graphql/schema/types/vms/network.graphql similarity index 94% rename from app/graphql/schema/types/vms/network.graphql rename to src/graphql/schema/types/vms/network.graphql index 5fc9c2ed4..59253a74c 100644 --- a/app/graphql/schema/types/vms/network.graphql +++ b/src/graphql/schema/types/vms/network.graphql @@ -1,4 +1,5 @@ type Query { + # @todo finish this """Virtual network for vms""" vmNetwork(name: String!): JSON @func(module: "vms/domains/network/get-network") # """Virtual networks for vms""" diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..31f5f66f8 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,23 @@ +/*! + * Copyright 2019-2020 Lime Technology Inc. All rights reserved. + * Written by: Alexis Tyler + */ + +import am from 'am'; +import core from '@unraid/core'; +import { server } from './server'; + +// Boot app +am(async () => { + // Load server + await core.loadServer('graphql-api', server); +}, error => { + // We should only end here if core has an issue loading + + // Log last error + console.error(error); + + // Kill application + // eslint-disable-next-line unicorn/no-process-exit + process.exit(1); +}); diff --git a/src/run.ts b/src/run.ts new file mode 100644 index 000000000..53d55c1f7 --- /dev/null +++ b/src/run.ts @@ -0,0 +1,92 @@ +import { CoreResult } from '@unraid/core/interfaces'; +import * as core from '@unraid/core' +import { getWsConectionCount } from './ws'; + +const { pubsub, utils, log } = core; +const { debugTimer } = utils; + +// Only allows function to publish to pubsub when clients are online +// the reason we do this is otherwise pubsub will cause a memory leak +export const canPublishToClients = () => { + const connectionCount = getWsConectionCount(); + return connectionCount >= 1; +}; + +/** + * Update pubsub. + */ +export const updatePubsub = (channel, mutation, node) => { + if (!canPublishToClients()) { + return; + } + + pubsub.publish(channel, { + [channel]: { + mutation, + node + } + }); +}; + +interface RunOptions { + node?: string + moduleToRun?: Function + interval?: number + total?: number + context?: any +} + +/** + * Run a module. + */ +export const run = async (channel: string, mutation: string, options: RunOptions) => { + const { + node, + moduleToRun, + // moduleToRun, + // filePath, + context + } = options; + + if (!canPublishToClients()) { + return; + } + + if (!moduleToRun) { + return updatePubsub(channel, mutation, node); + } + + try { + // Run module + const result: CoreResult = await new Promise(resolve => { + debugTimer(`run:${moduleToRun.name}`); + return resolve(moduleToRun(context)); + }); + + // if (filePath) { + // const [pluginName, moduleName] = channel.split('/'); + // log.debug('Plugin:', pluginName, 'Module:', moduleName, 'Result:', result); + // } + + log.debug('Module:', moduleToRun.name, 'Result:', result.json); + + // Update pubsub channel + pubsub.publish(channel, { + // [filePath ? 'pluginModule' : channel]: { + [channel]: { + mutation, + node: result.json + } + }); + } catch (error) { + // Ensure we aren't leaking anything in production + if (process.env.NODE_ENV === 'production') { + log.debug('Error:', error.message); + } else { + const logger = log[error.status && error.status >= 400 ? 'error' : 'warn']; + logger('Error:', error.message); + } + } + + debugTimer(`run:${moduleToRun.name}`); +}; diff --git a/src/server.ts b/src/server.ts new file mode 100644 index 000000000..d1d058052 --- /dev/null +++ b/src/server.ts @@ -0,0 +1,153 @@ +/*! + * Copyright 2019-2020 Lime Technology Inc. All rights reserved. + * Written by: Alexis Tyler + */ + +import fs from 'fs'; +import net from 'net'; +import stoppable from 'stoppable'; +import express from 'express'; +import http from 'http'; +import { ApolloServer } from 'apollo-server-express'; +import core from '@unraid/core'; +import { graphql } from './graphql'; + +const { log, config, utils, modules } = core; +const { getEndpoints } = utils; + +/** + * The Graphql server. + */ +// module.exports = function (config, log, getEndpoints, stoppable, http) { +const app = express(); +const port = String(config.get('graphql-api-port')); +let machineId; + +app.use(async (req, res, next) => { + // Only get the machine ID on first request + // We do this to avoid using async in the main server function + if (!machineId) { + // eslint-disable-next-line require-atomic-updates + machineId = await modules.getMachineId().then(result => result.json); + } + + // Update header with machine ID + res.set('x-machine-id', machineId); + + next(); +}); + +// Mount graph endpoint +const graphApp = new ApolloServer(graphql); +graphApp.applyMiddleware({app}); + +// List all endpoints at start of server +app.get('/', (_, res) => { + return res.send(getEndpoints(app)); +}); + +// Handle errors by logging them and returning a 500. +// eslint-disable-next-line no-unused-vars +app.use((error, _, res, __) => { + core.log.error(error); + if (error.stack) { + error.stackTrace = error.stack; + } + + res.status(error.status || 500).send(error); +}); + +const httpServer = http.createServer(app); +const stoppableServer = stoppable(httpServer); + +const handleError = error => { + if (error.code !== 'EADDRINUSE') { + throw error; + } + + if (!isNaN(parseInt(port, 10))) { + throw error; + } + + stoppableServer.close(); + + net.connect({ + path: port + }, () => { + // Really in use: re-throw + throw error; + }).on('error', (error: NodeJS.ErrnoException) => { + if (error.code !== 'ECONNREFUSED') { + log.error(error); + + process.exitCode = 1; + } + + // Not in use: delete it and re-listen + fs.unlinkSync(port); + + setTimeout(() => { + stoppableServer.listen(port); + }, 1000); + }); +}; + +// Port is a UNIX socket file +if (isNaN(parseInt(port, 10))) { + stoppableServer.on('listening', () => { + // In production this will let pm2 know we're ready + if (process.send) { + process.send('ready'); + } + + // Set permissions + return fs.chmodSync(port, 660); + }); + + stoppableServer.on('error', handleError); + + process.on('uncaughtException', (error: NodeJS.ErrnoException) => { + // Skip EADDRINUSE as it's already handled above + if (error.code !== 'EADDRINUSE') { + throw error; + } + }); +} + +// Add graphql subscription handlers +graphApp.installSubscriptionHandlers(stoppableServer); + +// Return an object with a server and start/stop async methods. +export const server = { + server: stoppableServer, + async start() { + return stoppableServer.listen(port, () => { + // Downgrade process user to owner of this file + return fs.stat(__filename, (error, stats) => { + if (error) { + throw error; + } + + return process.setuid(stats.uid); + }); + }); + }, + stop() { + // Stop the server from accepting new connections and close existing connections + return stoppableServer.close(error => { + if (error) { + log.error(error); + // Exit with error (code 1) + // eslint-disable-next-line unicorn/no-process-exit + process.exit(1); + } + + const name = process.title; + const serverName = `@unraid/${name}`; + log.info(`Successfully stopped ${serverName}`); + + // Gracefully exit + process.exitCode = 0; + }); + } +}; \ No newline at end of file diff --git a/src/ws.ts b/src/ws.ts new file mode 100644 index 000000000..c60d0dd99 --- /dev/null +++ b/src/ws.ts @@ -0,0 +1,30 @@ +let connectionCount = 0; + +/** + * Return current ws connection count. + */ +export const getWsConectionCount = () => connectionCount; + +/** + * Set ws connection count to a specific number. + */ +export const setWsConectionCount = (count: number) => { + connectionCount = count; + return count; +}; + +/** + * Increase ws connection count by 1. + */ +export const increaseWsConectionCount = () => { + connectionCount++; + return connectionCount; +}; + +/** + * Decrease ws connection count by 1. + */ +export const decreaseWsConectionCount = () => { + connectionCount--; + return connectionCount; +}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..0436f94c0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,76 @@ +{ + "include": [ + "src/**/*", + "index.d.ts" + ], + "exclude": [ + "node_modules" + ], + "compilerOptions": { + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./dist", /* Redirect output structure to the directory. */ + "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + }, + "typeAcquisition": { + "enable": true + } +}