mirror of
				https://github.com/reduxjs/redux-devtools.git
				synced 2025-11-04 01:47:25 +03:00 
			
		
		
		
	chore(cli): convert to TypeScript (#656)
* chore(cli): convert to TypeScript * Fix knex usage * Fix eslintrc * Ignore dist
This commit is contained in:
		
							parent
							
								
									ee52c29a8d
								
							
						
					
					
						commit
						c91471a41d
					
				
							
								
								
									
										2
									
								
								packages/redux-devtools-cli/.eslintignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								packages/redux-devtools-cli/.eslintignore
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
dist
 | 
			
		||||
umd
 | 
			
		||||
							
								
								
									
										21
									
								
								packages/redux-devtools-cli/.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								packages/redux-devtools-cli/.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
module.exports = {
 | 
			
		||||
  extends: '../../.eslintrc',
 | 
			
		||||
  overrides: [
 | 
			
		||||
    {
 | 
			
		||||
      files: ['*.ts', '*.tsx'],
 | 
			
		||||
      extends: '../../eslintrc.ts.base.json',
 | 
			
		||||
      parserOptions: {
 | 
			
		||||
        tsconfigRootDir: __dirname,
 | 
			
		||||
        project: ['./tsconfig.json'],
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      files: ['test/*.ts', 'test/*.tsx'],
 | 
			
		||||
      extends: '../../eslintrc.ts.jest.base.json',
 | 
			
		||||
      parserOptions: {
 | 
			
		||||
        tsconfigRootDir: __dirname,
 | 
			
		||||
        project: ['./test/tsconfig.json'],
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,95 +0,0 @@
 | 
			
		|||
var fs = require('fs');
 | 
			
		||||
var path = require('path');
 | 
			
		||||
var semver = require('semver');
 | 
			
		||||
 | 
			
		||||
var name = 'redux-devtools-cli';
 | 
			
		||||
var startFlag = '/* ' + name + ' start */';
 | 
			
		||||
var endFlag = '/* ' + name + ' end */';
 | 
			
		||||
var serverFlags = {
 | 
			
		||||
  'react-native': {
 | 
			
		||||
    '0.0.1': '    _server(argv, config, resolve, reject);',
 | 
			
		||||
    '0.31.0':
 | 
			
		||||
      "  runServer(args, config, () => console.log('\\nReact packager ready.\\n'));",
 | 
			
		||||
    '0.44.0-rc.0': '  runServer(args, config, startedCallback, readyCallback);',
 | 
			
		||||
    '0.46.0-rc.0':
 | 
			
		||||
      '  runServer(runServerArgs, configT, startedCallback, readyCallback);',
 | 
			
		||||
    '0.57.0': '  runServer(args, configT);',
 | 
			
		||||
  },
 | 
			
		||||
  'react-native-desktop': {
 | 
			
		||||
    '0.0.1': '    _server(argv, config, resolve, reject);',
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function getModuleVersion(modulePath) {
 | 
			
		||||
  return JSON.parse(
 | 
			
		||||
    fs.readFileSync(path.join(modulePath, 'package.json'), 'utf-8')
 | 
			
		||||
  ).version;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getServerFlag(moduleName, version) {
 | 
			
		||||
  var flags = serverFlags[moduleName || 'react-native'];
 | 
			
		||||
  var versions = Object.keys(flags);
 | 
			
		||||
  var flag;
 | 
			
		||||
  for (var i = 0; i < versions.length; i++) {
 | 
			
		||||
    if (semver.gte(version, versions[i])) {
 | 
			
		||||
      flag = flags[versions[i]];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return flag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.dir = 'local-cli/server';
 | 
			
		||||
exports.file = 'server.js';
 | 
			
		||||
exports.fullPath = path.join(exports.dir, exports.file);
 | 
			
		||||
 | 
			
		||||
exports.inject = function (modulePath, options, moduleName) {
 | 
			
		||||
  var filePath = path.join(modulePath, exports.fullPath);
 | 
			
		||||
  if (!fs.existsSync(filePath)) return false;
 | 
			
		||||
 | 
			
		||||
  var serverFlag = getServerFlag(moduleName, getModuleVersion(modulePath));
 | 
			
		||||
  var code = [
 | 
			
		||||
    startFlag,
 | 
			
		||||
    '    require("' + name + '")(' + JSON.stringify(options) + ')',
 | 
			
		||||
    '      .then(_remotedev =>',
 | 
			
		||||
    '        _remotedev.on("ready", () => {',
 | 
			
		||||
    '          if (!_remotedev.portAlreadyUsed) console.log("-".repeat(80));',
 | 
			
		||||
    '      ' + serverFlag,
 | 
			
		||||
    '        })',
 | 
			
		||||
    '      );',
 | 
			
		||||
    endFlag,
 | 
			
		||||
  ].join('\n');
 | 
			
		||||
 | 
			
		||||
  var serverCode = fs.readFileSync(filePath, 'utf-8');
 | 
			
		||||
  var start = serverCode.indexOf(startFlag); // already injected ?
 | 
			
		||||
  var end = serverCode.indexOf(endFlag) + endFlag.length;
 | 
			
		||||
  if (start === -1) {
 | 
			
		||||
    start = serverCode.indexOf(serverFlag);
 | 
			
		||||
    end = start + serverFlag.length;
 | 
			
		||||
  }
 | 
			
		||||
  fs.writeFileSync(
 | 
			
		||||
    filePath,
 | 
			
		||||
    serverCode.substr(0, start) +
 | 
			
		||||
      code +
 | 
			
		||||
      serverCode.substr(end, serverCode.length)
 | 
			
		||||
  );
 | 
			
		||||
  return true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.revert = function (modulePath, moduleName) {
 | 
			
		||||
  var filePath = path.join(modulePath, exports.fullPath);
 | 
			
		||||
  if (!fs.existsSync(filePath)) return false;
 | 
			
		||||
 | 
			
		||||
  var serverFlag = getServerFlag(moduleName, getModuleVersion(modulePath));
 | 
			
		||||
  var serverCode = fs.readFileSync(filePath, 'utf-8');
 | 
			
		||||
  var start = serverCode.indexOf(startFlag); // already injected ?
 | 
			
		||||
  var end = serverCode.indexOf(endFlag) + endFlag.length;
 | 
			
		||||
  if (start !== -1) {
 | 
			
		||||
    fs.writeFileSync(
 | 
			
		||||
      filePath,
 | 
			
		||||
      serverCode.substr(0, start) +
 | 
			
		||||
        serverFlag +
 | 
			
		||||
        serverCode.substr(end, serverCode.length)
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										93
									
								
								packages/redux-devtools-cli/bin/redux-devtools.js
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										93
									
								
								packages/redux-devtools-cli/bin/redux-devtools.js
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
						 | 
				
			
			@ -1,94 +1,3 @@
 | 
			
		|||
#! /usr/bin/env node
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
var path = require('path');
 | 
			
		||||
var argv = require('minimist')(process.argv.slice(2));
 | 
			
		||||
var chalk = require('chalk');
 | 
			
		||||
var injectServer = require('./injectServer');
 | 
			
		||||
var getOptions = require('./../src/options');
 | 
			
		||||
var server = require('../index');
 | 
			
		||||
var openApp = require('./openApp');
 | 
			
		||||
 | 
			
		||||
var options = getOptions(argv);
 | 
			
		||||
 | 
			
		||||
function readFile(filePath) {
 | 
			
		||||
  return fs.readFileSync(path.resolve(process.cwd(), filePath), 'utf-8');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (argv.protocol === 'https') {
 | 
			
		||||
  argv.key = argv.key ? readFile(argv.key) : null;
 | 
			
		||||
  argv.cert = argv.cert ? readFile(argv.cert) : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function log(pass, msg) {
 | 
			
		||||
  var prefix = pass ? chalk.green.bgBlack('PASS') : chalk.red.bgBlack('FAIL');
 | 
			
		||||
  var color = pass ? chalk.blue : chalk.red;
 | 
			
		||||
  console.log(prefix, color(msg)); // eslint-disable-line no-console
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getModuleName(type) {
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case 'macos':
 | 
			
		||||
      return 'react-native-macos';
 | 
			
		||||
    // react-native-macos is renamed from react-native-desktop
 | 
			
		||||
    case 'desktop':
 | 
			
		||||
      return 'react-native-desktop';
 | 
			
		||||
    case 'reactnative':
 | 
			
		||||
    default:
 | 
			
		||||
      return 'react-native';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getModulePath(moduleName) {
 | 
			
		||||
  return path.join(process.cwd(), 'node_modules', moduleName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getModule(type) {
 | 
			
		||||
  var moduleName = getModuleName(type);
 | 
			
		||||
  var modulePath = getModulePath(moduleName);
 | 
			
		||||
  if (type === 'desktop' && !fs.existsSync(modulePath)) {
 | 
			
		||||
    moduleName = getModuleName('macos');
 | 
			
		||||
    modulePath = getModulePath(moduleName);
 | 
			
		||||
  }
 | 
			
		||||
  return {
 | 
			
		||||
    name: moduleName,
 | 
			
		||||
    path: modulePath,
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function injectRN(type, msg) {
 | 
			
		||||
  var module = getModule(type);
 | 
			
		||||
  var fn = type === 'revert' ? injectServer.revert : injectServer.inject;
 | 
			
		||||
  var pass = fn(module.path, options, module.name);
 | 
			
		||||
  log(
 | 
			
		||||
    pass,
 | 
			
		||||
    msg +
 | 
			
		||||
      (pass
 | 
			
		||||
        ? '.'
 | 
			
		||||
        : ', the file `' +
 | 
			
		||||
          path.join(module.name, injectServer.fullPath) +
 | 
			
		||||
          '` not found.')
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  process.exit(pass ? 0 : 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (argv.revert) {
 | 
			
		||||
  injectRN(
 | 
			
		||||
    argv.revert,
 | 
			
		||||
    'Revert injection of ReduxDevTools server from React Native local server'
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
if (argv.injectserver) {
 | 
			
		||||
  injectRN(
 | 
			
		||||
    argv.injectserver,
 | 
			
		||||
    'Inject ReduxDevTools server into React Native local server'
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
server(argv).then(function (r) {
 | 
			
		||||
  if (argv.open && argv.open !== 'false') {
 | 
			
		||||
    r.on('ready', function () {
 | 
			
		||||
      openApp(argv.open, options);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
require('../dist/bin/redux-devtools.js');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								packages/redux-devtools-cli/jest.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/redux-devtools-cli/jest.config.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
module.exports = {
 | 
			
		||||
  preset: 'ts-jest',
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -2,10 +2,12 @@
 | 
			
		|||
  "name": "redux-devtools-cli",
 | 
			
		||||
  "version": "1.0.0-4",
 | 
			
		||||
  "description": "CLI for remote debugging with Redux DevTools.",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "bin": {
 | 
			
		||||
    "redux-devtools": "bin/redux-devtools.js"
 | 
			
		||||
  "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-cli",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/reduxjs/redux-devtools/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "author": "Mihail Diordiev <zalmoxisus@gmail.com> (https://github.com/zalmoxisus)",
 | 
			
		||||
  "files": [
 | 
			
		||||
    "bin",
 | 
			
		||||
    "src",
 | 
			
		||||
| 
						 | 
				
			
			@ -13,25 +15,31 @@
 | 
			
		|||
    "index.js",
 | 
			
		||||
    "defaultDbOptions.json"
 | 
			
		||||
  ],
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "start": "node ./bin/redux-devtools.js",
 | 
			
		||||
    "start:electron": "node ./bin/redux-devtools.js --open",
 | 
			
		||||
    "test": "jest",
 | 
			
		||||
    "prepublishOnly": "npm run test"
 | 
			
		||||
  "main": "dist/index.js",
 | 
			
		||||
  "types": "dist/index.d.ts",
 | 
			
		||||
  "bin": {
 | 
			
		||||
    "redux-devtools": "bin/redux-devtools.js"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "https://github.com/reduxjs/redux-devtools.git"
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "build": "tsc && ncp ./src/api/schema_def.graphql ./dist/api/schema_def.graphql",
 | 
			
		||||
    "start": "node ./bin/redux-devtools.js",
 | 
			
		||||
    "start:electron": "node ./bin/redux-devtools.js --open",
 | 
			
		||||
    "clean": "rimraf dist",
 | 
			
		||||
    "test": "jest",
 | 
			
		||||
    "lint": "eslint . --ext .ts,.tsx",
 | 
			
		||||
    "lint:fix": "eslint . --ext .ts,.tsx --fix",
 | 
			
		||||
    "type-check": "tsc --noEmit",
 | 
			
		||||
    "type-check:watch": "npm run type-check -- --watch",
 | 
			
		||||
    "preversion": "npm run type-check && npm run lint && npm run test",
 | 
			
		||||
    "prepublishOnly": "npm run clean && npm run build"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": ">=6.0.0"
 | 
			
		||||
    "node": ">=10.0.0"
 | 
			
		||||
  },
 | 
			
		||||
  "author": "Mihail Diordiev <zalmoxisus@gmail.com> (https://github.com/zalmoxisus)",
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/reduxjs/redux-devtools/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": "https://github.com/reduxjs/redux-devtools",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "apollo-server": "^2.18.2",
 | 
			
		||||
    "apollo-server-express": "^2.18.2",
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +50,7 @@
 | 
			
		|||
    "electron": "^9.2.0",
 | 
			
		||||
    "express": "^4.17.1",
 | 
			
		||||
    "getport": "^0.1.0",
 | 
			
		||||
    "graphql": "^15.3.0",
 | 
			
		||||
    "graphql": "^14.7.0",
 | 
			
		||||
    "knex": "^0.19.5",
 | 
			
		||||
    "lodash": "^4.17.19",
 | 
			
		||||
    "minimist": "^1.2.5",
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +65,13 @@
 | 
			
		|||
    "uuid": "^8.3.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/cross-spawn": "^6.0.2",
 | 
			
		||||
    "@types/morgan": "^1.9.1",
 | 
			
		||||
    "@types/semver": "^7.3.4",
 | 
			
		||||
    "@types/supertest": "^2.0.10",
 | 
			
		||||
    "@types/uuid": "^8.3.0",
 | 
			
		||||
    "jest": "^26.2.2",
 | 
			
		||||
    "ncp": "^2.0.0",
 | 
			
		||||
    "socketcluster-client": "^14.3.1",
 | 
			
		||||
    "supertest": "^4.0.2"
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,21 +0,0 @@
 | 
			
		|||
var makeExecutableSchema = require('apollo-server').makeExecutableSchema;
 | 
			
		||||
var requireSchema = require('../utils/requireSchema');
 | 
			
		||||
var schema = requireSchema('./schema_def.graphql', require);
 | 
			
		||||
 | 
			
		||||
var resolvers = {
 | 
			
		||||
  Query: {
 | 
			
		||||
    reports: function report(source, args, context) {
 | 
			
		||||
      return context.store.listAll();
 | 
			
		||||
    },
 | 
			
		||||
    report: function report(source, args, context) {
 | 
			
		||||
      return context.store.get(args.id);
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var executableSchema = makeExecutableSchema({
 | 
			
		||||
  typeDefs: schema,
 | 
			
		||||
  resolvers: resolvers,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
module.exports = executableSchema;
 | 
			
		||||
							
								
								
									
										33
									
								
								packages/redux-devtools-cli/src/api/schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/redux-devtools-cli/src/api/schema.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
import fs from 'fs';
 | 
			
		||||
import { makeExecutableSchema } from 'apollo-server';
 | 
			
		||||
import { Store } from '../store';
 | 
			
		||||
 | 
			
		||||
const schema = fs
 | 
			
		||||
  .readFileSync(require.resolve('./schema_def.graphql'))
 | 
			
		||||
  .toString();
 | 
			
		||||
 | 
			
		||||
const resolvers = {
 | 
			
		||||
  Query: {
 | 
			
		||||
    reports: function report(
 | 
			
		||||
      source: unknown,
 | 
			
		||||
      args: unknown,
 | 
			
		||||
      context: { store: Store }
 | 
			
		||||
    ) {
 | 
			
		||||
      return context.store.listAll();
 | 
			
		||||
    },
 | 
			
		||||
    report: function report(
 | 
			
		||||
      source: unknown,
 | 
			
		||||
      args: { id: string },
 | 
			
		||||
      context: { store: Store }
 | 
			
		||||
    ) {
 | 
			
		||||
      return context.store.get(args.id);
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const executableSchema = makeExecutableSchema({
 | 
			
		||||
  typeDefs: schema,
 | 
			
		||||
  resolvers: resolvers,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default executableSchema;
 | 
			
		||||
							
								
								
									
										104
									
								
								packages/redux-devtools-cli/src/bin/injectServer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								packages/redux-devtools-cli/src/bin/injectServer.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
import fs from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import semver from 'semver';
 | 
			
		||||
import { Options } from '../options';
 | 
			
		||||
 | 
			
		||||
const name = 'redux-devtools-cli';
 | 
			
		||||
const startFlag = '/* ' + name + ' start */';
 | 
			
		||||
const endFlag = '/* ' + name + ' end */';
 | 
			
		||||
const serverFlags: { [moduleName: string]: { [version: string]: string } } = {
 | 
			
		||||
  'react-native': {
 | 
			
		||||
    '0.0.1': '    _server(argv, config, resolve, reject);',
 | 
			
		||||
    '0.31.0':
 | 
			
		||||
      "  runServer(args, config, () => console.log('\\nReact packager ready.\\n'));",
 | 
			
		||||
    '0.44.0-rc.0': '  runServer(args, config, startedCallback, readyCallback);',
 | 
			
		||||
    '0.46.0-rc.0':
 | 
			
		||||
      '  runServer(runServerArgs, configT, startedCallback, readyCallback);',
 | 
			
		||||
    '0.57.0': '  runServer(args, configT);',
 | 
			
		||||
  },
 | 
			
		||||
  'react-native-desktop': {
 | 
			
		||||
    '0.0.1': '    _server(argv, config, resolve, reject);',
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function getModuleVersion(modulePath: string) {
 | 
			
		||||
  return JSON.parse(
 | 
			
		||||
    fs.readFileSync(path.join(modulePath, 'package.json'), 'utf-8')
 | 
			
		||||
  ).version;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getServerFlag(moduleName: string, version: string): string {
 | 
			
		||||
  const flags = serverFlags[moduleName || 'react-native'];
 | 
			
		||||
  const versions = Object.keys(flags);
 | 
			
		||||
  let flag;
 | 
			
		||||
  for (let i = 0; i < versions.length; i++) {
 | 
			
		||||
    if (semver.gte(version, versions[i])) {
 | 
			
		||||
      flag = flags[versions[i]];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return flag as string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const dir = 'local-cli/server';
 | 
			
		||||
export const file = 'server.js';
 | 
			
		||||
export const fullPath = path.join(exports.dir, exports.file);
 | 
			
		||||
 | 
			
		||||
export function inject(
 | 
			
		||||
  modulePath: string,
 | 
			
		||||
  options: Options,
 | 
			
		||||
  moduleName: string
 | 
			
		||||
) {
 | 
			
		||||
  const filePath = path.join(modulePath, exports.fullPath);
 | 
			
		||||
  if (!fs.existsSync(filePath)) return false;
 | 
			
		||||
 | 
			
		||||
  const serverFlag = getServerFlag(moduleName, getModuleVersion(modulePath));
 | 
			
		||||
  const code = [
 | 
			
		||||
    startFlag,
 | 
			
		||||
    '    require("' + name + '")(' + JSON.stringify(options) + ')',
 | 
			
		||||
    '      .then(_remotedev =>',
 | 
			
		||||
    '        _remotedev.on("ready", () => {',
 | 
			
		||||
    '          if (!_remotedev.portAlreadyUsed) console.log("-".repeat(80));',
 | 
			
		||||
    '      ' + serverFlag,
 | 
			
		||||
    '        })',
 | 
			
		||||
    '      );',
 | 
			
		||||
    endFlag,
 | 
			
		||||
  ].join('\n');
 | 
			
		||||
 | 
			
		||||
  const serverCode = fs.readFileSync(filePath, 'utf-8');
 | 
			
		||||
  let start = serverCode.indexOf(startFlag); // already injected ?
 | 
			
		||||
  let end = serverCode.indexOf(endFlag) + endFlag.length;
 | 
			
		||||
  if (start === -1) {
 | 
			
		||||
    start = serverCode.indexOf(serverFlag);
 | 
			
		||||
    end = start + serverFlag.length;
 | 
			
		||||
  }
 | 
			
		||||
  fs.writeFileSync(
 | 
			
		||||
    filePath,
 | 
			
		||||
    serverCode.substr(0, start) +
 | 
			
		||||
      code +
 | 
			
		||||
      serverCode.substr(end, serverCode.length)
 | 
			
		||||
  );
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function revert(
 | 
			
		||||
  modulePath: string,
 | 
			
		||||
  options: Options,
 | 
			
		||||
  moduleName: string
 | 
			
		||||
) {
 | 
			
		||||
  const filePath = path.join(modulePath, exports.fullPath);
 | 
			
		||||
  if (!fs.existsSync(filePath)) return false;
 | 
			
		||||
 | 
			
		||||
  const serverFlag = getServerFlag(moduleName, getModuleVersion(modulePath));
 | 
			
		||||
  const serverCode = fs.readFileSync(filePath, 'utf-8');
 | 
			
		||||
  const start = serverCode.indexOf(startFlag); // already injected ?
 | 
			
		||||
  const end = serverCode.indexOf(endFlag) + endFlag.length;
 | 
			
		||||
  if (start !== -1) {
 | 
			
		||||
    fs.writeFileSync(
 | 
			
		||||
      filePath,
 | 
			
		||||
      serverCode.substr(0, start) +
 | 
			
		||||
        serverFlag +
 | 
			
		||||
        serverCode.substr(end, serverCode.length)
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,13 @@
 | 
			
		|||
var open = require('open');
 | 
			
		||||
var path = require('path');
 | 
			
		||||
var spawn = require('cross-spawn');
 | 
			
		||||
import open from 'open';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import spawn from 'cross-spawn';
 | 
			
		||||
import { Options } from '../options';
 | 
			
		||||
 | 
			
		||||
function openApp(app, options) {
 | 
			
		||||
export default function openApp(app: boolean | string, options: Options) {
 | 
			
		||||
  if (app === true || app === 'electron') {
 | 
			
		||||
    try {
 | 
			
		||||
      var port = options.port ? '--port=' + options.port : '';
 | 
			
		||||
      const port = options.port ? `--port=${options.port}` : '';
 | 
			
		||||
      // eslint-disable-next-line @typescript-eslint/no-var-requires
 | 
			
		||||
      spawn.sync(require('electron'), [
 | 
			
		||||
        path.join(__dirname, '..', 'app'),
 | 
			
		||||
        port,
 | 
			
		||||
| 
						 | 
				
			
			@ -29,10 +31,9 @@ function openApp(app, options) {
 | 
			
		|||
    }
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
  open(
 | 
			
		||||
    'http://localhost:' + options.port + '/',
 | 
			
		||||
    app !== 'browser' ? { app: app } : undefined
 | 
			
		||||
    `http://localhost:${options.port}/`,
 | 
			
		||||
    app !== 'browser' ? { app: app as string } : undefined
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = openApp;
 | 
			
		||||
							
								
								
									
										97
									
								
								packages/redux-devtools-cli/src/bin/redux-devtools.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								packages/redux-devtools-cli/src/bin/redux-devtools.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,97 @@
 | 
			
		|||
#! /usr/bin/env node
 | 
			
		||||
import fs from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import parseArgs from 'minimist';
 | 
			
		||||
import chalk from 'chalk';
 | 
			
		||||
import * as injectServer from './injectServer';
 | 
			
		||||
import getOptions from '../options';
 | 
			
		||||
import server from '../index';
 | 
			
		||||
import openApp from './openApp';
 | 
			
		||||
 | 
			
		||||
const argv = parseArgs(process.argv.slice(2));
 | 
			
		||||
 | 
			
		||||
const options = getOptions(argv);
 | 
			
		||||
 | 
			
		||||
function readFile(filePath: string) {
 | 
			
		||||
  return fs.readFileSync(path.resolve(process.cwd(), filePath), 'utf-8');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (argv.protocol === 'https') {
 | 
			
		||||
  argv.key = argv.key ? readFile(argv.key) : null;
 | 
			
		||||
  argv.cert = argv.cert ? readFile(argv.cert) : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function log(pass: boolean, msg: string) {
 | 
			
		||||
  const prefix = pass ? chalk.green.bgBlack('PASS') : chalk.red.bgBlack('FAIL');
 | 
			
		||||
  const color = pass ? chalk.blue : chalk.red;
 | 
			
		||||
  console.log(prefix, color(msg)); // eslint-disable-line no-console
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getModuleName(type: string) {
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case 'macos':
 | 
			
		||||
      return 'react-native-macos';
 | 
			
		||||
    // react-native-macos is renamed from react-native-desktop
 | 
			
		||||
    case 'desktop':
 | 
			
		||||
      return 'react-native-desktop';
 | 
			
		||||
    case 'reactnative':
 | 
			
		||||
    default:
 | 
			
		||||
      return 'react-native';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getModulePath(moduleName: string) {
 | 
			
		||||
  return path.join(process.cwd(), 'node_modules', moduleName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getModule(type: string) {
 | 
			
		||||
  let moduleName = getModuleName(type);
 | 
			
		||||
  let modulePath = getModulePath(moduleName);
 | 
			
		||||
  if (type === 'desktop' && !fs.existsSync(modulePath)) {
 | 
			
		||||
    moduleName = getModuleName('macos');
 | 
			
		||||
    modulePath = getModulePath(moduleName);
 | 
			
		||||
  }
 | 
			
		||||
  return {
 | 
			
		||||
    name: moduleName,
 | 
			
		||||
    path: modulePath,
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function injectRN(type: string, msg: string) {
 | 
			
		||||
  const module = getModule(type);
 | 
			
		||||
  const fn = type === 'revert' ? injectServer.revert : injectServer.inject;
 | 
			
		||||
  const pass = fn(module.path, options, module.name);
 | 
			
		||||
  log(
 | 
			
		||||
    pass,
 | 
			
		||||
    msg +
 | 
			
		||||
      (pass
 | 
			
		||||
        ? '.'
 | 
			
		||||
        : ', the file `' +
 | 
			
		||||
          path.join(module.name, injectServer.fullPath) +
 | 
			
		||||
          '` not found.')
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  process.exit(pass ? 0 : 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (argv.revert) {
 | 
			
		||||
  injectRN(
 | 
			
		||||
    argv.revert,
 | 
			
		||||
    'Revert injection of ReduxDevTools server from React Native local server'
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
if (argv.injectserver) {
 | 
			
		||||
  injectRN(
 | 
			
		||||
    argv.injectserver,
 | 
			
		||||
    'Inject ReduxDevTools server into React Native local server'
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
server(argv).then(function (r) {
 | 
			
		||||
  if (argv.open && argv.open !== 'false') {
 | 
			
		||||
    r.on('ready', function () {
 | 
			
		||||
      openApp(argv.open, options);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
var path = require('path');
 | 
			
		||||
var knexModule = require('knex');
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import knexModule from 'knex';
 | 
			
		||||
import { SCServer } from 'socketcluster-server';
 | 
			
		||||
 | 
			
		||||
module.exports = function connector(options) {
 | 
			
		||||
  var dbOptions = options.dbOptions;
 | 
			
		||||
export default function connector(options: SCServer.SCServerOptions) {
 | 
			
		||||
  const dbOptions = options.dbOptions;
 | 
			
		||||
  dbOptions.useNullAsDefault = true;
 | 
			
		||||
  if (!dbOptions.migrate) {
 | 
			
		||||
    return knexModule(dbOptions);
 | 
			
		||||
| 
						 | 
				
			
			@ -10,13 +11,13 @@ module.exports = function connector(options) {
 | 
			
		|||
 | 
			
		||||
  dbOptions.migrations = { directory: path.resolve(__dirname, 'migrations') };
 | 
			
		||||
  dbOptions.seeds = { directory: path.resolve(__dirname, 'seeds') };
 | 
			
		||||
  var knex = knexModule(dbOptions);
 | 
			
		||||
  const knex = knexModule(dbOptions);
 | 
			
		||||
 | 
			
		||||
  /* eslint-disable no-console */
 | 
			
		||||
  knex.migrate
 | 
			
		||||
    .latest()
 | 
			
		||||
    .latest({ loadExtensions: ['.js'] })
 | 
			
		||||
    .then(function () {
 | 
			
		||||
      return knex.seed.run();
 | 
			
		||||
      return knex.seed.run({ loadExtensions: ['.js'] });
 | 
			
		||||
    })
 | 
			
		||||
    .then(function () {
 | 
			
		||||
      console.log('   \x1b[0;32m[Done]\x1b[0m Migrations are finished\n');
 | 
			
		||||
| 
						 | 
				
			
			@ -27,4 +28,4 @@ module.exports = function connector(options) {
 | 
			
		|||
  /* eslint-enable no-console */
 | 
			
		||||
 | 
			
		||||
  return knex;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
exports.up = function (knex) {
 | 
			
		||||
import type knexModule from 'knex';
 | 
			
		||||
 | 
			
		||||
export function up(knex: knexModule) {
 | 
			
		||||
  return Promise.all([
 | 
			
		||||
    knex.schema.createTable('remotedev_reports', function (table) {
 | 
			
		||||
      table.uuid('id').primary();
 | 
			
		||||
| 
						 | 
				
			
			@ -75,11 +77,11 @@ exports.up = function (knex) {
 | 
			
		|||
        .onUpdate('CASCADE');
 | 
			
		||||
    }),
 | 
			
		||||
  ]);
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.down = function (knex) {
 | 
			
		||||
export function down(knex: knexModule) {
 | 
			
		||||
  return Promise.all([
 | 
			
		||||
    knex.schema.dropTable('remotedev_reports'),
 | 
			
		||||
    knex.schema.dropTable('remotedev_apps'),
 | 
			
		||||
  ]);
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
exports.seed = function (knex) {
 | 
			
		||||
import type knexModule from 'knex';
 | 
			
		||||
 | 
			
		||||
export function seed(knex: knexModule) {
 | 
			
		||||
  return Promise.all([knex('remotedev_apps').del()]).then(function () {
 | 
			
		||||
    return Promise.all([
 | 
			
		||||
      knex('remotedev_apps').insert({
 | 
			
		||||
| 
						 | 
				
			
			@ -7,4 +9,4 @@ exports.seed = function (knex) {
 | 
			
		|||
      }),
 | 
			
		||||
    ]);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								packages/redux-devtools-cli/src/getport.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								packages/redux-devtools-cli/src/getport.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
declare module 'getport' {
 | 
			
		||||
  export default function getport(
 | 
			
		||||
    start: number,
 | 
			
		||||
    callback: (e: Error | undefined, port: number) => void
 | 
			
		||||
  ): void;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,19 +1,29 @@
 | 
			
		|||
var getPort = require('getport');
 | 
			
		||||
var SocketCluster = require('socketcluster');
 | 
			
		||||
var getOptions = require('./src/options');
 | 
			
		||||
import getPort from 'getport';
 | 
			
		||||
import SocketCluster from 'socketcluster';
 | 
			
		||||
import getOptions, { Options } from './options';
 | 
			
		||||
 | 
			
		||||
// var LOG_LEVEL_NONE = 0;
 | 
			
		||||
var LOG_LEVEL_ERROR = 1;
 | 
			
		||||
var LOG_LEVEL_WARN = 2;
 | 
			
		||||
var LOG_LEVEL_INFO = 3;
 | 
			
		||||
const LOG_LEVEL_ERROR = 1;
 | 
			
		||||
const LOG_LEVEL_WARN = 2;
 | 
			
		||||
const LOG_LEVEL_INFO = 3;
 | 
			
		||||
 | 
			
		||||
module.exports = function (argv) {
 | 
			
		||||
  var options = Object.assign(getOptions(argv), {
 | 
			
		||||
    workerController: __dirname + '/src/worker.js',
 | 
			
		||||
export interface ExtendedOptions extends Options {
 | 
			
		||||
  workerController: string;
 | 
			
		||||
  allowClientPublish: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default function (argv: {
 | 
			
		||||
  [arg: string]: any;
 | 
			
		||||
}): Promise<{
 | 
			
		||||
  portAlreadyUsed?: boolean;
 | 
			
		||||
  on: (status: 'ready', cb: () => void) => void;
 | 
			
		||||
}> {
 | 
			
		||||
  const options = Object.assign(getOptions(argv), {
 | 
			
		||||
    workerController: __dirname + '/worker.js',
 | 
			
		||||
    allowClientPublish: false,
 | 
			
		||||
  });
 | 
			
		||||
  var port = options.port;
 | 
			
		||||
  var logLevel =
 | 
			
		||||
  const port = options.port;
 | 
			
		||||
  const logLevel =
 | 
			
		||||
    options.logLevel === undefined ? LOG_LEVEL_INFO : options.logLevel;
 | 
			
		||||
  return new Promise(function (resolve) {
 | 
			
		||||
    // Check port already used
 | 
			
		||||
| 
						 | 
				
			
			@ -27,13 +37,11 @@ module.exports = function (argv) {
 | 
			
		|||
      }
 | 
			
		||||
      if (port !== p) {
 | 
			
		||||
        if (logLevel >= LOG_LEVEL_WARN) {
 | 
			
		||||
          console.log(
 | 
			
		||||
            '[ReduxDevTools] Server port ' + port + ' is already used.'
 | 
			
		||||
          );
 | 
			
		||||
          console.log(`[ReduxDevTools] Server port ${port} is already used.`);
 | 
			
		||||
        }
 | 
			
		||||
        resolve({
 | 
			
		||||
          portAlreadyUsed: true,
 | 
			
		||||
          on: function (status, cb) {
 | 
			
		||||
          on: function (status: string, cb: () => void) {
 | 
			
		||||
            cb();
 | 
			
		||||
          },
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -47,4 +55,4 @@ module.exports = function (argv) {
 | 
			
		|||
      /* eslint-enable no-console */
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
var ApolloServer = require('apollo-server-express').ApolloServer;
 | 
			
		||||
var schema = require('../api/schema');
 | 
			
		||||
import { ApolloServer } from 'apollo-server-express';
 | 
			
		||||
import schema from '../api/schema';
 | 
			
		||||
import { Store } from '../store';
 | 
			
		||||
 | 
			
		||||
module.exports = function (store) {
 | 
			
		||||
export default function (store: Store) {
 | 
			
		||||
  return new ApolloServer({
 | 
			
		||||
    schema,
 | 
			
		||||
    context: {
 | 
			
		||||
| 
						 | 
				
			
			@ -24,4 +25,4 @@ module.exports = function (store) {
 | 
			
		|||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,33 +0,0 @@
 | 
			
		|||
var path = require('path');
 | 
			
		||||
 | 
			
		||||
module.exports = function getOptions(argv) {
 | 
			
		||||
  var dbOptions = argv.dbOptions;
 | 
			
		||||
  if (typeof dbOptions === 'string') {
 | 
			
		||||
    dbOptions = require(path.resolve(process.cwd(), argv.dbOptions));
 | 
			
		||||
  } else if (typeof dbOptions === 'undefined') {
 | 
			
		||||
    dbOptions = require('../defaultDbOptions.json');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    host: argv.hostname || process.env.npm_package_remotedev_hostname || null,
 | 
			
		||||
    port: Number(argv.port || process.env.npm_package_remotedev_port) || 8000,
 | 
			
		||||
    protocol:
 | 
			
		||||
      argv.protocol || process.env.npm_package_remotedev_protocol || 'http',
 | 
			
		||||
    protocolOptions: !(argv.protocol === 'https')
 | 
			
		||||
      ? null
 | 
			
		||||
      : {
 | 
			
		||||
          key: argv.key || process.env.npm_package_remotedev_key || null,
 | 
			
		||||
          cert: argv.cert || process.env.npm_package_remotedev_cert || null,
 | 
			
		||||
          passphrase:
 | 
			
		||||
            argv.passphrase ||
 | 
			
		||||
            process.env.npm_package_remotedev_passphrase ||
 | 
			
		||||
            null,
 | 
			
		||||
        },
 | 
			
		||||
    dbOptions: dbOptions,
 | 
			
		||||
    maxRequestBody: argv.passphrase || '16mb',
 | 
			
		||||
    logHTTPRequests: argv.logHTTPRequests,
 | 
			
		||||
    logLevel: argv.logLevel || 3,
 | 
			
		||||
    wsEngine:
 | 
			
		||||
      argv.wsEngine || process.env.npm_package_remotedev_wsengine || 'ws',
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										63
									
								
								packages/redux-devtools-cli/src/options.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								packages/redux-devtools-cli/src/options.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
import path from 'path';
 | 
			
		||||
 | 
			
		||||
interface ProtocolOptions {
 | 
			
		||||
  key: string | undefined;
 | 
			
		||||
  cert: string | undefined;
 | 
			
		||||
  passphrase: string | undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface DbOptions {
 | 
			
		||||
  client: string;
 | 
			
		||||
  connection: {
 | 
			
		||||
    filename: string;
 | 
			
		||||
  };
 | 
			
		||||
  useNullAsDefault: boolean;
 | 
			
		||||
  debug: boolean;
 | 
			
		||||
  migrate: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Options {
 | 
			
		||||
  host: string | undefined;
 | 
			
		||||
  port: number;
 | 
			
		||||
  protocol: 'http' | 'https';
 | 
			
		||||
  protocolOptions: ProtocolOptions | undefined;
 | 
			
		||||
  dbOptions: DbOptions;
 | 
			
		||||
  maxRequestBody: string;
 | 
			
		||||
  logHTTPRequests?: boolean;
 | 
			
		||||
  logLevel: 0 | 1 | 3 | 2;
 | 
			
		||||
  wsEngine: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default function getOptions(argv: { [arg: string]: any }): Options {
 | 
			
		||||
  let dbOptions = argv.dbOptions;
 | 
			
		||||
  if (typeof dbOptions === 'string') {
 | 
			
		||||
    dbOptions = require(path.resolve(process.cwd(), argv.dbOptions));
 | 
			
		||||
  } else if (typeof dbOptions === 'undefined') {
 | 
			
		||||
    dbOptions = require('../defaultDbOptions.json');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    host:
 | 
			
		||||
      argv.hostname || process.env.npm_package_remotedev_hostname || undefined,
 | 
			
		||||
    port: Number(argv.port || process.env.npm_package_remotedev_port) || 8000,
 | 
			
		||||
    protocol:
 | 
			
		||||
      argv.protocol || process.env.npm_package_remotedev_protocol || 'http',
 | 
			
		||||
    protocolOptions: !(argv.protocol === 'https')
 | 
			
		||||
      ? undefined
 | 
			
		||||
      : {
 | 
			
		||||
          key: argv.key || process.env.npm_package_remotedev_key || undefined,
 | 
			
		||||
          cert:
 | 
			
		||||
            argv.cert || process.env.npm_package_remotedev_cert || undefined,
 | 
			
		||||
          passphrase:
 | 
			
		||||
            argv.passphrase ||
 | 
			
		||||
            process.env.npm_package_remotedev_passphrase ||
 | 
			
		||||
            undefined,
 | 
			
		||||
        },
 | 
			
		||||
    dbOptions: dbOptions,
 | 
			
		||||
    maxRequestBody: argv.passphrase || '16mb',
 | 
			
		||||
    logHTTPRequests: argv.logHTTPRequests,
 | 
			
		||||
    logLevel: argv.logLevel || 3,
 | 
			
		||||
    wsEngine:
 | 
			
		||||
      argv.wsEngine || process.env.npm_package_remotedev_wsengine || 'ws',
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +1,15 @@
 | 
			
		|||
var path = require('path');
 | 
			
		||||
var express = require('express');
 | 
			
		||||
var morgan = require('morgan');
 | 
			
		||||
var bodyParser = require('body-parser');
 | 
			
		||||
var cors = require('cors');
 | 
			
		||||
var graphqlMiddleware = require('./middleware/graphql');
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import express from 'express';
 | 
			
		||||
import morgan from 'morgan';
 | 
			
		||||
import bodyParser from 'body-parser';
 | 
			
		||||
import cors from 'cors';
 | 
			
		||||
import { SCServer } from 'socketcluster-server';
 | 
			
		||||
import graphqlMiddleware from './middleware/graphql';
 | 
			
		||||
import { ReportBaseFields, Store } from './store';
 | 
			
		||||
 | 
			
		||||
var app = express.Router();
 | 
			
		||||
const app = express.Router();
 | 
			
		||||
 | 
			
		||||
function serveUmdModule(name) {
 | 
			
		||||
function serveUmdModule(name: string) {
 | 
			
		||||
  app.use(
 | 
			
		||||
    express.static(
 | 
			
		||||
      path.dirname(require.resolve(name + '/package.json')) + '/umd'
 | 
			
		||||
| 
						 | 
				
			
			@ -15,9 +17,13 @@ function serveUmdModule(name) {
 | 
			
		|||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function routes(options, store, scServer) {
 | 
			
		||||
  var limit = options.maxRequestBody;
 | 
			
		||||
  var logHTTPRequests = options.logHTTPRequests;
 | 
			
		||||
function routes(
 | 
			
		||||
  options: SCServer.SCServerOptions,
 | 
			
		||||
  store: Store,
 | 
			
		||||
  scServer: SCServer
 | 
			
		||||
) {
 | 
			
		||||
  const limit = options.maxRequestBody;
 | 
			
		||||
  const logHTTPRequests = options.logHTTPRequests;
 | 
			
		||||
 | 
			
		||||
  if (logHTTPRequests) {
 | 
			
		||||
    if (typeof logHTTPRequests === 'object')
 | 
			
		||||
| 
						 | 
				
			
			@ -25,14 +31,16 @@ function routes(options, store, scServer) {
 | 
			
		|||
    else app.use(morgan('combined'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  graphqlMiddleware(store).applyMiddleware({ app });
 | 
			
		||||
  graphqlMiddleware(store).applyMiddleware({ app } as {
 | 
			
		||||
    app: express.Application;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  serveUmdModule('react');
 | 
			
		||||
  serveUmdModule('react-dom');
 | 
			
		||||
  serveUmdModule('redux-devtools-core');
 | 
			
		||||
 | 
			
		||||
  app.get('/port.js', function (req, res) {
 | 
			
		||||
    res.send('reduxDevToolsPort = ' + options.port);
 | 
			
		||||
    res.send(`reduxDevToolsPort = ${options.port!}`);
 | 
			
		||||
  });
 | 
			
		||||
  app.get('*', function (req, res) {
 | 
			
		||||
    res.sendFile(path.join(__dirname, '../app/index.html'));
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +79,10 @@ function routes(options, store, scServer) {
 | 
			
		|||
        store
 | 
			
		||||
          .add(req.body)
 | 
			
		||||
          .then(function (r) {
 | 
			
		||||
            res.send({ id: r.id, error: r.error });
 | 
			
		||||
            res.send({
 | 
			
		||||
              id: (r as ReportBaseFields).id,
 | 
			
		||||
              error: (r as { error: string }).error,
 | 
			
		||||
            });
 | 
			
		||||
            scServer.exchange.publish('report', {
 | 
			
		||||
              type: 'add',
 | 
			
		||||
              data: r,
 | 
			
		||||
| 
						 | 
				
			
			@ -86,4 +97,4 @@ function routes(options, store, scServer) {
 | 
			
		|||
  return app;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = routes;
 | 
			
		||||
export default routes;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,106 +0,0 @@
 | 
			
		|||
var { v4: uuidV4 } = require('uuid');
 | 
			
		||||
var pick = require('lodash/pick');
 | 
			
		||||
var connector = require('./db/connector');
 | 
			
		||||
 | 
			
		||||
var reports = 'remotedev_reports';
 | 
			
		||||
// var payloads = 'remotedev_payloads';
 | 
			
		||||
var knex;
 | 
			
		||||
 | 
			
		||||
var baseFields = ['id', 'title', 'added'];
 | 
			
		||||
 | 
			
		||||
function error(msg) {
 | 
			
		||||
  return new Promise(function (resolve) {
 | 
			
		||||
    return resolve({ error: msg });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function list(query, fields) {
 | 
			
		||||
  var r = knex.select(fields || baseFields).from(reports);
 | 
			
		||||
  if (query) return r.where(query);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function listAll(query) {
 | 
			
		||||
  var r = knex.select().from(reports);
 | 
			
		||||
  if (query) return r.where(query);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get(id) {
 | 
			
		||||
  if (!id) return error('No id specified.');
 | 
			
		||||
 | 
			
		||||
  return knex(reports).where('id', id).first();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function add(data) {
 | 
			
		||||
  if (!data.type || !data.payload) {
 | 
			
		||||
    return error("Required parameters aren't specified.");
 | 
			
		||||
  }
 | 
			
		||||
  if (data.type !== 'ACTIONS' && data.type !== 'STATE') {
 | 
			
		||||
    return error('Type ' + data.type + ' is not supported yet.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var reportId = uuidV4();
 | 
			
		||||
  var report = {
 | 
			
		||||
    id: reportId,
 | 
			
		||||
    type: data.type,
 | 
			
		||||
    title:
 | 
			
		||||
      data.title || (data.exception && data.exception.message) || data.action,
 | 
			
		||||
    description: data.description,
 | 
			
		||||
    action: data.action,
 | 
			
		||||
    payload: data.payload,
 | 
			
		||||
    preloadedState: data.preloadedState,
 | 
			
		||||
    screenshot: data.screenshot,
 | 
			
		||||
    version: data.version,
 | 
			
		||||
    userAgent: data.userAgent,
 | 
			
		||||
    user: data.user,
 | 
			
		||||
    userId: typeof data.user === 'object' ? data.user.id : data.user,
 | 
			
		||||
    instanceId: data.instanceId,
 | 
			
		||||
    meta: data.meta,
 | 
			
		||||
    exception: composeException(data.exception),
 | 
			
		||||
    added: new Date().toISOString(),
 | 
			
		||||
  };
 | 
			
		||||
  if (data.appId) report.appId = data.appId; // TODO check if the id exists and we have access to link it
 | 
			
		||||
  /*
 | 
			
		||||
  var payload = {
 | 
			
		||||
    id: uuid.v4(),
 | 
			
		||||
    reportId: reportId,
 | 
			
		||||
    state: data.payload
 | 
			
		||||
  };
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  return knex
 | 
			
		||||
    .insert(report)
 | 
			
		||||
    .into(reports)
 | 
			
		||||
    .then(function () {
 | 
			
		||||
      return byBaseFields(report);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function byBaseFields(data) {
 | 
			
		||||
  return pick(data, baseFields);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createStore(options) {
 | 
			
		||||
  knex = connector(options);
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    list: list,
 | 
			
		||||
    listAll: listAll,
 | 
			
		||||
    get: get,
 | 
			
		||||
    add: add,
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function composeException(exception) {
 | 
			
		||||
  var message = '';
 | 
			
		||||
 | 
			
		||||
  if (exception) {
 | 
			
		||||
    message = 'Exception thrown: ';
 | 
			
		||||
    if (exception.message) message += exception.message;
 | 
			
		||||
    if (exception.stack) message += '\n' + exception.stack;
 | 
			
		||||
  }
 | 
			
		||||
  return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = createStore;
 | 
			
		||||
							
								
								
									
										164
									
								
								packages/redux-devtools-cli/src/store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								packages/redux-devtools-cli/src/store.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,164 @@
 | 
			
		|||
import { v4 as uuidV4 } from 'uuid';
 | 
			
		||||
import pick from 'lodash/pick';
 | 
			
		||||
import { SCServer } from 'socketcluster-server';
 | 
			
		||||
import knexModule from 'knex';
 | 
			
		||||
import connector from './db/connector';
 | 
			
		||||
 | 
			
		||||
const reports = 'remotedev_reports';
 | 
			
		||||
// var payloads = 'remotedev_payloads';
 | 
			
		||||
let knex: knexModule;
 | 
			
		||||
 | 
			
		||||
const baseFields = ['id', 'title', 'added'];
 | 
			
		||||
 | 
			
		||||
function error(msg: string): Promise<{ error: string }> {
 | 
			
		||||
  return new Promise(function (resolve) {
 | 
			
		||||
    return resolve({ error: msg });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ReportType = 'STATE' | 'ACTION' | 'STATES' | 'ACTIONS';
 | 
			
		||||
 | 
			
		||||
interface Report {
 | 
			
		||||
  id: string;
 | 
			
		||||
  type: ReportType | null;
 | 
			
		||||
  title: string | null;
 | 
			
		||||
  description: string | null;
 | 
			
		||||
  action: string | null;
 | 
			
		||||
  payload: string;
 | 
			
		||||
  preloadedState: string | null;
 | 
			
		||||
  screenshot: string | null;
 | 
			
		||||
  userAgent: string | null;
 | 
			
		||||
  version: string | null;
 | 
			
		||||
  userId: string | null;
 | 
			
		||||
  user: string | null;
 | 
			
		||||
  meta: string | null;
 | 
			
		||||
  exception: string | null;
 | 
			
		||||
  instanceId: string | null;
 | 
			
		||||
  added: string | null;
 | 
			
		||||
  appId?: string | null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ReportBaseFields {
 | 
			
		||||
  id: string;
 | 
			
		||||
  title: string | null;
 | 
			
		||||
  added: string | null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function list(query?: unknown, fields?: string[]): Promise<ReportBaseFields[]> {
 | 
			
		||||
  const r = knex.select(fields || baseFields).from(reports);
 | 
			
		||||
  if (query) return r.where(query);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function listAll(query: unknown): Promise<Report[]> {
 | 
			
		||||
  const r = knex.select().from(reports);
 | 
			
		||||
  if (query) return r.where(query);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get(id: string): Promise<Report | { error: string }> {
 | 
			
		||||
  if (!id) return error('No id specified.');
 | 
			
		||||
 | 
			
		||||
  return knex(reports).where('id', id).first();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface AddData {
 | 
			
		||||
  type: ReportType | null;
 | 
			
		||||
  title: string | null;
 | 
			
		||||
  description: string | null;
 | 
			
		||||
  action: string | null;
 | 
			
		||||
  payload: string;
 | 
			
		||||
  preloadedState: string | null;
 | 
			
		||||
  screenshot: string | null;
 | 
			
		||||
  version: string | null;
 | 
			
		||||
  userAgent: string | null;
 | 
			
		||||
  userId: string | null;
 | 
			
		||||
  user: { id: string } | string | null;
 | 
			
		||||
  instanceId: string | null;
 | 
			
		||||
  meta: string | null;
 | 
			
		||||
  exception?: Error;
 | 
			
		||||
  appId?: string | null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function add(data: AddData): Promise<ReportBaseFields | { error: string }> {
 | 
			
		||||
  if (!data.type || !data.payload) {
 | 
			
		||||
    return error("Required parameters aren't specified.");
 | 
			
		||||
  }
 | 
			
		||||
  if (data.type !== 'ACTIONS' && data.type !== 'STATE') {
 | 
			
		||||
    return error('Type ' + data.type + ' is not supported yet.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const reportId = uuidV4();
 | 
			
		||||
  const report: Report = {
 | 
			
		||||
    id: reportId,
 | 
			
		||||
    type: data.type,
 | 
			
		||||
    title:
 | 
			
		||||
      data.title || (data.exception && data.exception.message) || data.action,
 | 
			
		||||
    description: data.description,
 | 
			
		||||
    action: data.action,
 | 
			
		||||
    payload: data.payload,
 | 
			
		||||
    preloadedState: data.preloadedState,
 | 
			
		||||
    screenshot: data.screenshot,
 | 
			
		||||
    version: data.version,
 | 
			
		||||
    userAgent: data.userAgent,
 | 
			
		||||
    user: data.user as string,
 | 
			
		||||
    userId:
 | 
			
		||||
      typeof data.user === 'object'
 | 
			
		||||
        ? (data.user as { id: string }).id
 | 
			
		||||
        : data.user,
 | 
			
		||||
    instanceId: data.instanceId,
 | 
			
		||||
    meta: data.meta,
 | 
			
		||||
    exception: composeException(data.exception),
 | 
			
		||||
    added: new Date().toISOString(),
 | 
			
		||||
  };
 | 
			
		||||
  if (data.appId) report.appId = data.appId; // TODO check if the id exists and we have access to link it
 | 
			
		||||
  /*
 | 
			
		||||
  var payload = {
 | 
			
		||||
    id: uuid.v4(),
 | 
			
		||||
    reportId: reportId,
 | 
			
		||||
    state: data.payload
 | 
			
		||||
  };
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  return knex
 | 
			
		||||
    .insert(report)
 | 
			
		||||
    .into(reports)
 | 
			
		||||
    .then(function () {
 | 
			
		||||
      return byBaseFields(report);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function byBaseFields(data: Report): ReportBaseFields {
 | 
			
		||||
  return pick(data, baseFields) as ReportBaseFields;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Store {
 | 
			
		||||
  list: (query?: unknown, fields?: string[]) => Promise<ReportBaseFields[]>;
 | 
			
		||||
  listAll: (query?: unknown) => Promise<Report[]>;
 | 
			
		||||
  get: (id: string) => Promise<Report | { error: string }>;
 | 
			
		||||
  add: (data: AddData) => Promise<ReportBaseFields | { error: string }>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createStore(options: SCServer.SCServerOptions): Store {
 | 
			
		||||
  knex = connector(options);
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    list: list,
 | 
			
		||||
    listAll: listAll,
 | 
			
		||||
    get: get,
 | 
			
		||||
    add: add,
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function composeException(exception: Error | undefined) {
 | 
			
		||||
  let message = '';
 | 
			
		||||
 | 
			
		||||
  if (exception) {
 | 
			
		||||
    message = 'Exception thrown: ';
 | 
			
		||||
    if (exception.message) message += exception.message;
 | 
			
		||||
    if (exception.stack) message += '\n' + exception.stack;
 | 
			
		||||
  }
 | 
			
		||||
  return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default createStore;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
var fs = require('fs');
 | 
			
		||||
 | 
			
		||||
module.exports = function (name, require) {
 | 
			
		||||
  return fs.readFileSync(require.resolve(name)).toString();
 | 
			
		||||
  // return GraphQL.buildSchema(schema);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,23 +1,24 @@
 | 
			
		|||
var SCWorker = require('socketcluster/scworker');
 | 
			
		||||
var express = require('express');
 | 
			
		||||
var app = express();
 | 
			
		||||
var routes = require('./routes');
 | 
			
		||||
var createStore = require('./store');
 | 
			
		||||
import SCWorker from 'socketcluster/scworker';
 | 
			
		||||
import express from 'express';
 | 
			
		||||
import routes from './routes';
 | 
			
		||||
import createStore from './store';
 | 
			
		||||
 | 
			
		||||
const app = express();
 | 
			
		||||
 | 
			
		||||
class Worker extends SCWorker {
 | 
			
		||||
  run() {
 | 
			
		||||
    var httpServer = this.httpServer;
 | 
			
		||||
    var scServer = this.scServer;
 | 
			
		||||
    var options = this.options;
 | 
			
		||||
    var store = createStore(options);
 | 
			
		||||
    const httpServer = this.httpServer;
 | 
			
		||||
    const scServer = this.scServer;
 | 
			
		||||
    const options = this.options;
 | 
			
		||||
    const store = createStore(options);
 | 
			
		||||
 | 
			
		||||
    httpServer.on('request', app);
 | 
			
		||||
 | 
			
		||||
    app.use(routes(options, store, scServer));
 | 
			
		||||
 | 
			
		||||
    scServer.addMiddleware(scServer.MIDDLEWARE_EMIT, function (req, next) {
 | 
			
		||||
      var channel = req.event;
 | 
			
		||||
      var data = req.data;
 | 
			
		||||
      const channel = req.event;
 | 
			
		||||
      const data = req.data;
 | 
			
		||||
      if (
 | 
			
		||||
        channel.substr(0, 3) === 'sc-' ||
 | 
			
		||||
        channel === 'respond' ||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +37,7 @@ class Worker extends SCWorker {
 | 
			
		|||
        store
 | 
			
		||||
          .list()
 | 
			
		||||
          .then(function (data) {
 | 
			
		||||
            req.socket.emit(req.channel, { type: 'list', data: data });
 | 
			
		||||
            req.socket.emit(req.channel!, { type: 'list', data: data });
 | 
			
		||||
          })
 | 
			
		||||
          .catch(function (error) {
 | 
			
		||||
            console.error(error); // eslint-disable-line no-console
 | 
			
		||||
| 
						 | 
				
			
			@ -45,8 +46,8 @@ class Worker extends SCWorker {
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    scServer.on('connection', function (socket) {
 | 
			
		||||
      var channelToWatch, channelToEmit;
 | 
			
		||||
      socket.on('login', function (credentials, respond) {
 | 
			
		||||
      let channelToWatch: string, channelToEmit: string;
 | 
			
		||||
      socket.on('login', function (this: Worker, credentials, respond) {
 | 
			
		||||
        if (credentials === 'master') {
 | 
			
		||||
          channelToWatch = 'respond';
 | 
			
		||||
          channelToEmit = 'log';
 | 
			
		||||
| 
						 | 
				
			
			@ -69,8 +70,8 @@ class Worker extends SCWorker {
 | 
			
		|||
            console.error(error); // eslint-disable-line no-console
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
      socket.on('disconnect', function () {
 | 
			
		||||
        var channel = this.exchange.channel('sc-' + socket.id);
 | 
			
		||||
      socket.on('disconnect', function (this: Worker) {
 | 
			
		||||
        const channel = this.exchange.channel('sc-' + socket.id);
 | 
			
		||||
        channel.unsubscribe();
 | 
			
		||||
        channel.destroy();
 | 
			
		||||
        scServer.exchange.publish(channelToEmit, {
 | 
			
		||||
| 
						 | 
				
			
			@ -1,199 +0,0 @@
 | 
			
		|||
var childProcess = require('child_process');
 | 
			
		||||
var request = require('supertest');
 | 
			
		||||
var scClient = require('socketcluster-client');
 | 
			
		||||
 | 
			
		||||
describe('Server', function () {
 | 
			
		||||
  var scServer;
 | 
			
		||||
  beforeAll(function (done) {
 | 
			
		||||
    scServer = childProcess.fork(__dirname + '/../bin/redux-devtools.js');
 | 
			
		||||
    setTimeout(done, 3000);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  afterAll(function () {
 | 
			
		||||
    if (scServer) {
 | 
			
		||||
      scServer.kill();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Express backend', function () {
 | 
			
		||||
    it('loads main page', function (done) {
 | 
			
		||||
      request('http://localhost:8000')
 | 
			
		||||
        .get('/')
 | 
			
		||||
        .expect('Content-Type', /text\/html/)
 | 
			
		||||
        .expect(200)
 | 
			
		||||
        .then(function (res) {
 | 
			
		||||
          expect(res.text).toMatch(/<title>Redux DevTools<\/title>/);
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('resolves an inexistent url', function (done) {
 | 
			
		||||
      request('http://localhost:8000/jreerfr/123')
 | 
			
		||||
        .get('/')
 | 
			
		||||
        .expect('Content-Type', /text\/html/)
 | 
			
		||||
        .expect(200, done);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Realtime monitoring', function () {
 | 
			
		||||
    var socket, socket2, channel;
 | 
			
		||||
    beforeAll(function () {
 | 
			
		||||
      socket = scClient.connect({ hostname: 'localhost', port: 8000 });
 | 
			
		||||
      socket.connect();
 | 
			
		||||
      socket.on('error', function (error) {
 | 
			
		||||
        console.error('Socket1 error', error); // eslint-disable-line no-console
 | 
			
		||||
      });
 | 
			
		||||
      socket2 = scClient.connect({ hostname: 'localhost', port: 8000 });
 | 
			
		||||
      socket2.connect();
 | 
			
		||||
      socket.on('error', function (error) {
 | 
			
		||||
        console.error('Socket2 error', error); // eslint-disable-line no-console
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterAll(function () {
 | 
			
		||||
      socket.disconnect();
 | 
			
		||||
      socket2.disconnect();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should connect', function (done) {
 | 
			
		||||
      socket.on('connect', function (status) {
 | 
			
		||||
        expect(status.id).toBeTruthy();
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should login', function () {
 | 
			
		||||
      socket.emit('login', 'master', function (error, channelName) {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          /* eslint-disable-next-line no-console */
 | 
			
		||||
          console.log(error);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        expect(channelName).toBe('respond');
 | 
			
		||||
        channel = socket.subscribe(channelName);
 | 
			
		||||
        expect(channel.SUBSCRIBED).toBe('subscribed');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should send message', function (done) {
 | 
			
		||||
      var data = {
 | 
			
		||||
        type: 'ACTION',
 | 
			
		||||
        payload: {
 | 
			
		||||
          todos: 'do some',
 | 
			
		||||
        },
 | 
			
		||||
        action: {
 | 
			
		||||
          timestamp: 1483349708506,
 | 
			
		||||
          action: {
 | 
			
		||||
            type: 'ADD_TODO',
 | 
			
		||||
            text: 'hggg',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        instanceId: 'tAmA7H5fclyWhvizAAAi',
 | 
			
		||||
        name: 'LoggerInstance',
 | 
			
		||||
        id: 'tAmA7H5fclyWhvizAAAi',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      socket2.emit('login', '', function (error, channelName) {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          /* eslint-disable-next-line no-console */
 | 
			
		||||
          console.log(error);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        expect(channelName).toBe('log');
 | 
			
		||||
        var channel2 = socket2.subscribe(channelName);
 | 
			
		||||
        expect(channel2.SUBSCRIBED).toBe('subscribed');
 | 
			
		||||
        channel2.on('subscribe', function () {
 | 
			
		||||
          channel2.watch(function (message) {
 | 
			
		||||
            expect(message).toEqual(data);
 | 
			
		||||
            done();
 | 
			
		||||
          });
 | 
			
		||||
          socket.emit(channelName, data);
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('REST backend', function () {
 | 
			
		||||
    var id;
 | 
			
		||||
    var report = {
 | 
			
		||||
      type: 'ACTIONS',
 | 
			
		||||
      title: 'Test report',
 | 
			
		||||
      description: 'Test body report',
 | 
			
		||||
      action: 'SOME_FINAL_ACTION',
 | 
			
		||||
      payload: '[{"type":"ADD_TODO","text":"hi"},{"type":"SOME_FINAL_ACTION"}]',
 | 
			
		||||
      preloadedState:
 | 
			
		||||
        '{"todos":[{"text":"Use Redux","completed":false,"id":0}]}',
 | 
			
		||||
      userAgent:
 | 
			
		||||
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) ' +
 | 
			
		||||
        'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36',
 | 
			
		||||
    };
 | 
			
		||||
    it('should add a report', function (done) {
 | 
			
		||||
      request('http://localhost:8000')
 | 
			
		||||
        .post('/')
 | 
			
		||||
        .send(report)
 | 
			
		||||
        .set('Accept', 'application/json')
 | 
			
		||||
        .expect('Content-Type', /application\/json/)
 | 
			
		||||
        .expect(200)
 | 
			
		||||
        .then(function (res) {
 | 
			
		||||
          id = res.body.id;
 | 
			
		||||
          expect(id).toBeTruthy();
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should get the report', function (done) {
 | 
			
		||||
      request('http://localhost:8000')
 | 
			
		||||
        .post('/')
 | 
			
		||||
        .send({
 | 
			
		||||
          op: 'get',
 | 
			
		||||
          id: id,
 | 
			
		||||
        })
 | 
			
		||||
        .set('Accept', 'application/json')
 | 
			
		||||
        .expect('Content-Type', /application\/json/)
 | 
			
		||||
        .expect(200)
 | 
			
		||||
        .then(function (res) {
 | 
			
		||||
          expect.objectContaining(res.body, report);
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should list reports', function (done) {
 | 
			
		||||
      request('http://localhost:8000')
 | 
			
		||||
        .post('/')
 | 
			
		||||
        .send({
 | 
			
		||||
          op: 'list',
 | 
			
		||||
        })
 | 
			
		||||
        .set('Accept', 'application/json')
 | 
			
		||||
        .expect('Content-Type', /application\/json/)
 | 
			
		||||
        .expect(200)
 | 
			
		||||
        .then(function (res) {
 | 
			
		||||
          expect(res.body.length).toBe(1);
 | 
			
		||||
          expect(res.body[0].id).toBe(id);
 | 
			
		||||
          expect(res.body[0].title).toBe('Test report');
 | 
			
		||||
          expect(res.body[0].added).toBeTruthy();
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('GraphQL backend', function () {
 | 
			
		||||
    it('should get the report', function (done) {
 | 
			
		||||
      request('http://localhost:8000')
 | 
			
		||||
        .post('/graphql')
 | 
			
		||||
        .send({
 | 
			
		||||
          query: '{ reports { id, type, title } }',
 | 
			
		||||
        })
 | 
			
		||||
        .set('Accept', 'application/json')
 | 
			
		||||
        .expect('Content-Type', /application\/json/)
 | 
			
		||||
        .expect(200)
 | 
			
		||||
        .then(function (res) {
 | 
			
		||||
          var reports = res.body.data.reports;
 | 
			
		||||
          expect(reports.length).toBe(1);
 | 
			
		||||
          expect(reports[0].id).toBeTruthy();
 | 
			
		||||
          expect(reports[0].title).toBe('Test report');
 | 
			
		||||
          expect(reports[0].type).toBe('ACTIONS');
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										241
									
								
								packages/redux-devtools-cli/test/integration.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								packages/redux-devtools-cli/test/integration.spec.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,241 @@
 | 
			
		|||
import childProcess from 'child_process';
 | 
			
		||||
import request from 'supertest';
 | 
			
		||||
import scClient from 'socketcluster-client';
 | 
			
		||||
 | 
			
		||||
describe('Server', function () {
 | 
			
		||||
  let scServer: childProcess.ChildProcess;
 | 
			
		||||
  beforeAll(function (done) {
 | 
			
		||||
    scServer = childProcess.fork(__dirname + '/../bin/redux-devtools.js');
 | 
			
		||||
    setTimeout(done, 3000);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  afterAll(function () {
 | 
			
		||||
    if (scServer) {
 | 
			
		||||
      scServer.kill();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Express backend', function () {
 | 
			
		||||
    it('loads main page', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
        request('http://localhost:8000')
 | 
			
		||||
          .get('/')
 | 
			
		||||
          .expect('Content-Type', /text\/html/)
 | 
			
		||||
          .expect(200)
 | 
			
		||||
          .then(function (res: { text: string }) {
 | 
			
		||||
            expect(res.text).toMatch(/<title>Redux DevTools<\/title>/);
 | 
			
		||||
            done();
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('resolves an inexistent url', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
        request('http://localhost:8000/jreerfr/123')
 | 
			
		||||
          .get('/')
 | 
			
		||||
          .expect('Content-Type', /text\/html/)
 | 
			
		||||
          .expect(200, done);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Realtime monitoring', function () {
 | 
			
		||||
    let socket: scClient.SCClientSocket,
 | 
			
		||||
      socket2: scClient.SCClientSocket,
 | 
			
		||||
      channel;
 | 
			
		||||
    beforeAll(function () {
 | 
			
		||||
      socket = scClient.connect({ hostname: 'localhost', port: 8000 });
 | 
			
		||||
      socket.connect();
 | 
			
		||||
      socket.on('error', function (error) {
 | 
			
		||||
        console.error('Socket1 error', error); // eslint-disable-line no-console
 | 
			
		||||
      });
 | 
			
		||||
      socket2 = scClient.connect({ hostname: 'localhost', port: 8000 });
 | 
			
		||||
      socket2.connect();
 | 
			
		||||
      socket.on('error', function (error) {
 | 
			
		||||
        console.error('Socket2 error', error); // eslint-disable-line no-console
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterAll(function () {
 | 
			
		||||
      socket.disconnect();
 | 
			
		||||
      socket2.disconnect();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should connect', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        socket.on('connect', function (status) {
 | 
			
		||||
          expect(status.id).toBeTruthy();
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should login', function () {
 | 
			
		||||
      socket.emit('login', 'master', function (
 | 
			
		||||
        error: Error | undefined,
 | 
			
		||||
        channelName: string
 | 
			
		||||
      ) {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          /* eslint-disable-next-line no-console */
 | 
			
		||||
          console.log(error);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        expect(channelName).toBe('respond');
 | 
			
		||||
        channel = socket.subscribe(channelName);
 | 
			
		||||
        expect(channel.SUBSCRIBED).toBe('subscribed');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should send message', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        const data = {
 | 
			
		||||
          type: 'ACTION',
 | 
			
		||||
          payload: {
 | 
			
		||||
            todos: 'do some',
 | 
			
		||||
          },
 | 
			
		||||
          action: {
 | 
			
		||||
            timestamp: 1483349708506,
 | 
			
		||||
            action: {
 | 
			
		||||
              type: 'ADD_TODO',
 | 
			
		||||
              text: 'hggg',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          instanceId: 'tAmA7H5fclyWhvizAAAi',
 | 
			
		||||
          name: 'LoggerInstance',
 | 
			
		||||
          id: 'tAmA7H5fclyWhvizAAAi',
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        socket2.emit('login', '', function (
 | 
			
		||||
          error: Error | undefined,
 | 
			
		||||
          channelName: string
 | 
			
		||||
        ) {
 | 
			
		||||
          if (error) {
 | 
			
		||||
            /* eslint-disable-next-line no-console */
 | 
			
		||||
            console.log(error);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          expect(channelName).toBe('log');
 | 
			
		||||
          const channel2 = socket2.subscribe(channelName);
 | 
			
		||||
          expect(channel2.SUBSCRIBED).toBe('subscribed');
 | 
			
		||||
          channel2.on('subscribe', function () {
 | 
			
		||||
            channel2.watch(function (message) {
 | 
			
		||||
              expect(message).toEqual(data);
 | 
			
		||||
              done();
 | 
			
		||||
            });
 | 
			
		||||
            socket.emit(channelName, data);
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('REST backend', function () {
 | 
			
		||||
    let id: string;
 | 
			
		||||
    const report = {
 | 
			
		||||
      type: 'ACTIONS',
 | 
			
		||||
      title: 'Test report',
 | 
			
		||||
      description: 'Test body report',
 | 
			
		||||
      action: 'SOME_FINAL_ACTION',
 | 
			
		||||
      payload: '[{"type":"ADD_TODO","text":"hi"},{"type":"SOME_FINAL_ACTION"}]',
 | 
			
		||||
      preloadedState:
 | 
			
		||||
        '{"todos":[{"text":"Use Redux","completed":false,"id":0}]}',
 | 
			
		||||
      userAgent:
 | 
			
		||||
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) ' +
 | 
			
		||||
        'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36',
 | 
			
		||||
    };
 | 
			
		||||
    it('should add a report', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
        request('http://localhost:8000')
 | 
			
		||||
          .post('/')
 | 
			
		||||
          .send(report)
 | 
			
		||||
          .set('Accept', 'application/json')
 | 
			
		||||
          .expect('Content-Type', /application\/json/)
 | 
			
		||||
          .expect(200)
 | 
			
		||||
          .then(function (res: { body: { id: string } }) {
 | 
			
		||||
            id = res.body.id;
 | 
			
		||||
            expect(id).toBeTruthy();
 | 
			
		||||
            done();
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should get the report', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
        request('http://localhost:8000')
 | 
			
		||||
          .post('/')
 | 
			
		||||
          .send({
 | 
			
		||||
            op: 'get',
 | 
			
		||||
            id: id,
 | 
			
		||||
          })
 | 
			
		||||
          .set('Accept', 'application/json')
 | 
			
		||||
          .expect('Content-Type', /application\/json/)
 | 
			
		||||
          .expect(200)
 | 
			
		||||
          .then(function (res: { body: unknown }) {
 | 
			
		||||
            expect(res.body).toMatchObject(report);
 | 
			
		||||
            done();
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should list reports', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
        request('http://localhost:8000')
 | 
			
		||||
          .post('/')
 | 
			
		||||
          .send({
 | 
			
		||||
            op: 'list',
 | 
			
		||||
          })
 | 
			
		||||
          .set('Accept', 'application/json')
 | 
			
		||||
          .expect('Content-Type', /application\/json/)
 | 
			
		||||
          .expect(200)
 | 
			
		||||
          .then(function (res: {
 | 
			
		||||
            body: { id: string; title: string | null; added: string | null }[];
 | 
			
		||||
          }) {
 | 
			
		||||
            expect(res.body).toHaveLength(1);
 | 
			
		||||
            expect(res.body[0].id).toBe(id);
 | 
			
		||||
            expect(res.body[0].title).toBe('Test report');
 | 
			
		||||
            expect(res.body[0].added).toBeTruthy();
 | 
			
		||||
            done();
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('GraphQL backend', function () {
 | 
			
		||||
    it('should get the report', function () {
 | 
			
		||||
      return new Promise((done) => {
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | 
			
		||||
        request('http://localhost:8000')
 | 
			
		||||
          .post('/graphql')
 | 
			
		||||
          .send({
 | 
			
		||||
            query: '{ reports { id, type, title } }',
 | 
			
		||||
          })
 | 
			
		||||
          .set('Accept', 'application/json')
 | 
			
		||||
          .expect('Content-Type', /application\/json/)
 | 
			
		||||
          .expect(200)
 | 
			
		||||
          .then(function (res: {
 | 
			
		||||
            body: {
 | 
			
		||||
              data: {
 | 
			
		||||
                reports: {
 | 
			
		||||
                  id: string;
 | 
			
		||||
                  title: string | null;
 | 
			
		||||
                  type: string | null;
 | 
			
		||||
                }[];
 | 
			
		||||
              };
 | 
			
		||||
            };
 | 
			
		||||
          }) {
 | 
			
		||||
            const reports = res.body.data.reports;
 | 
			
		||||
            expect(reports).toHaveLength(1);
 | 
			
		||||
            expect(reports[0].id).toBeTruthy();
 | 
			
		||||
            expect(reports[0].title).toBe('Test report');
 | 
			
		||||
            expect(reports[0].type).toBe('ACTIONS');
 | 
			
		||||
            done();
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/redux-devtools-cli/test/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/redux-devtools-cli/test/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
{
 | 
			
		||||
  "extends": "../../../tsconfig.base.json",
 | 
			
		||||
  "include": ["../src", "."]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/redux-devtools-cli/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/redux-devtools-cli/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
{
 | 
			
		||||
  "extends": "../../tsconfig.base.json",
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "outDir": "dist"
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["src"]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								yarn.lock
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -3493,6 +3493,11 @@
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.3.tgz#0aa116701955c2faa0717fc69cd1596095e49d96"
 | 
			
		||||
  integrity sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==
 | 
			
		||||
 | 
			
		||||
"@types/cookiejar@*":
 | 
			
		||||
  version "2.1.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8"
 | 
			
		||||
  integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==
 | 
			
		||||
 | 
			
		||||
"@types/cookies@*":
 | 
			
		||||
  version "0.7.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.7.4.tgz#26dedf791701abc0e36b5b79a5722f40e455f87b"
 | 
			
		||||
| 
						 | 
				
			
			@ -3510,6 +3515,13 @@
 | 
			
		|||
  dependencies:
 | 
			
		||||
    "@types/express" "*"
 | 
			
		||||
 | 
			
		||||
"@types/cross-spawn@^6.0.2":
 | 
			
		||||
  version "6.0.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.2.tgz#168309de311cd30a2b8ae720de6475c2fbf33ac7"
 | 
			
		||||
  integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/node" "*"
 | 
			
		||||
 | 
			
		||||
"@types/d3@^3.5.43":
 | 
			
		||||
  version "3.5.43"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/d3/-/d3-3.5.43.tgz#e9b4992817e0b6c5efaa7d6e5bb2cee4d73eab58"
 | 
			
		||||
| 
						 | 
				
			
			@ -3859,6 +3871,13 @@
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6"
 | 
			
		||||
  integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=
 | 
			
		||||
 | 
			
		||||
"@types/morgan@^1.9.1":
 | 
			
		||||
  version "1.9.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.9.1.tgz#6457872df95647c1dbc6b3741e8146b71ece74bf"
 | 
			
		||||
  integrity sha512-2j5IKrgJpEP6xw/uiVb2Xfga0W0sSVD9JP9t7EZLvpBENdB0OKgcnoKS8IsjNeNnZ/86robdZ61Orl0QCFGOXg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/node" "*"
 | 
			
		||||
 | 
			
		||||
"@types/ncom@*":
 | 
			
		||||
  version "1.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/ncom/-/ncom-1.0.0.tgz#8e33d06fc4914c941ba40ceca042081b947ba699"
 | 
			
		||||
| 
						 | 
				
			
			@ -4116,6 +4135,11 @@
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/@types/sc-errors/-/sc-errors-1.4.0.tgz#dba1309b695ee8aafc3f574dfedfe4f3c5153419"
 | 
			
		||||
  integrity sha512-WfBEiw/SVja1ZvJRdt37dOJFxp2llV35n9cPiDCDsFRSvTTYlO4iMFg+NyeEhiWBk1O4bvmyYpAEYzJx1DbHHQ==
 | 
			
		||||
 | 
			
		||||
"@types/semver@^7.3.4":
 | 
			
		||||
  version "7.3.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
 | 
			
		||||
  integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==
 | 
			
		||||
 | 
			
		||||
"@types/serve-static@*":
 | 
			
		||||
  version "1.13.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53"
 | 
			
		||||
| 
						 | 
				
			
			@ -4186,6 +4210,21 @@
 | 
			
		|||
    "@types/react-native" "*"
 | 
			
		||||
    csstype "^3.0.2"
 | 
			
		||||
 | 
			
		||||
"@types/superagent@*":
 | 
			
		||||
  version "4.1.10"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-4.1.10.tgz#5e2cc721edf58f64fe9b819f326ee74803adee86"
 | 
			
		||||
  integrity sha512-xAgkb2CMWUMCyVc/3+7iQfOEBE75NvuZeezvmixbUw3nmENf2tCnQkW5yQLTYqvXUQ+R6EXxdqKKbal2zM5V/g==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/cookiejar" "*"
 | 
			
		||||
    "@types/node" "*"
 | 
			
		||||
 | 
			
		||||
"@types/supertest@^2.0.10":
 | 
			
		||||
  version "2.0.10"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.10.tgz#630d79b4d82c73e043e43ff777a9ca98d457cab7"
 | 
			
		||||
  integrity sha512-Xt8TbEyZTnD5Xulw95GLMOkmjGICrOQyJ2jqgkSjAUR3mm7pAIzSR0NFBaMcwlzVvlpCjNwbATcWWwjNiZiFrQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/superagent" "*"
 | 
			
		||||
 | 
			
		||||
"@types/tapable@*", "@types/tapable@^1.0.5":
 | 
			
		||||
  version "1.0.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74"
 | 
			
		||||
| 
						 | 
				
			
			@ -4210,6 +4249,11 @@
 | 
			
		|||
  resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
 | 
			
		||||
  integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
 | 
			
		||||
 | 
			
		||||
"@types/uuid@^8.3.0":
 | 
			
		||||
  version "8.3.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
 | 
			
		||||
  integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==
 | 
			
		||||
 | 
			
		||||
"@types/warning@^3.0.0":
 | 
			
		||||
  version "3.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52"
 | 
			
		||||
| 
						 | 
				
			
			@ -9656,6 +9700,13 @@ graphql-upload@^8.0.2:
 | 
			
		|||
    http-errors "^1.7.3"
 | 
			
		||||
    object-path "^0.11.4"
 | 
			
		||||
 | 
			
		||||
graphql@^14.7.0:
 | 
			
		||||
  version "14.7.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.7.0.tgz#7fa79a80a69be4a31c27dda824dc04dac2035a72"
 | 
			
		||||
  integrity sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    iterall "^1.2.2"
 | 
			
		||||
 | 
			
		||||
graphql@^15.3.0:
 | 
			
		||||
  version "15.3.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.3.0.tgz#3ad2b0caab0d110e3be4a5a9b2aa281e362b5278"
 | 
			
		||||
| 
						 | 
				
			
			@ -11028,7 +11079,7 @@ istanbul-reports@^3.0.2:
 | 
			
		|||
    html-escaper "^2.0.0"
 | 
			
		||||
    istanbul-lib-report "^3.0.0"
 | 
			
		||||
 | 
			
		||||
iterall@^1.1.3, iterall@^1.2.1:
 | 
			
		||||
iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2:
 | 
			
		||||
  version "1.3.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea"
 | 
			
		||||
  integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==
 | 
			
		||||
| 
						 | 
				
			
			@ -13074,6 +13125,11 @@ ncom@^1.0.2:
 | 
			
		|||
  dependencies:
 | 
			
		||||
    sc-formatter "~3.0.1"
 | 
			
		||||
 | 
			
		||||
ncp@^2.0.0:
 | 
			
		||||
  version "2.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
 | 
			
		||||
  integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=
 | 
			
		||||
 | 
			
		||||
nearley@^2.7.10:
 | 
			
		||||
  version "2.19.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.19.5.tgz#6be78e4942eeb9a043b17c563413111d4ad849b7"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user