mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-02-07 15:10:45 +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