From a2874ee2353de83ef5f6c3c7c0ba98b74c491b55 Mon Sep 17 00:00:00 2001
From: Antonio Leon
Date: Tue, 9 Jun 2020 00:01:58 +0200
Subject: [PATCH 01/48] Add in memory version of command bus not handling
commands
---
src/Contexts/Shared/domain/Command.ts | 7 ++++++
src/Contexts/Shared/domain/CommandBus.ts | 5 ++++
.../CommandBus/InMemoryCommandBus.ts | 9 +++++++
.../CommandBus/NoHandlerForMessageError.ts | 7 ++++++
.../CommandBus/InMemoryCommandBus.test.ts | 24 +++++++++++++++++++
5 files changed, 52 insertions(+)
create mode 100644 src/Contexts/Shared/domain/Command.ts
create mode 100644 src/Contexts/Shared/domain/CommandBus.ts
create mode 100644 src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
create mode 100644 src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
create mode 100644 tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
diff --git a/src/Contexts/Shared/domain/Command.ts b/src/Contexts/Shared/domain/Command.ts
new file mode 100644
index 0000000..c88751b
--- /dev/null
+++ b/src/Contexts/Shared/domain/Command.ts
@@ -0,0 +1,7 @@
+export abstract class Command {
+ readonly commandName: string;
+
+ constructor(commandName: string) {
+ this.commandName = commandName;
+ }
+}
\ No newline at end of file
diff --git a/src/Contexts/Shared/domain/CommandBus.ts b/src/Contexts/Shared/domain/CommandBus.ts
new file mode 100644
index 0000000..82e8096
--- /dev/null
+++ b/src/Contexts/Shared/domain/CommandBus.ts
@@ -0,0 +1,5 @@
+import { Command } from './Command';
+
+export interface CommandBus {
+ dispatch(command: Command): void;
+}
\ No newline at end of file
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
new file mode 100644
index 0000000..35d84b9
--- /dev/null
+++ b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
@@ -0,0 +1,9 @@
+import { CommandBus } from './../../domain/CommandBus';
+import { Command } from '../../domain/Command';
+import { NoHandlerForMessageError } from './NoHandlerForMessageError';
+
+export class InMemoryCommandBus implements CommandBus {
+ dispatch(command: Command): void {
+ throw new NoHandlerForMessageError(command);
+ }
+}
\ No newline at end of file
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts b/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
new file mode 100644
index 0000000..76f34b7
--- /dev/null
+++ b/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
@@ -0,0 +1,7 @@
+import { Command } from '../../domain/Command';
+
+export class NoHandlerForMessageError extends Error {
+ constructor(command: Command) {
+ super(`There is not handler for command of type ${command.commandName}`);
+ }
+}
\ No newline at end of file
diff --git a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
new file mode 100644
index 0000000..9a8a25e
--- /dev/null
+++ b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
@@ -0,0 +1,24 @@
+import { InMemoryCommandBus } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus';
+import { Command } from '../../../../../src/Contexts/Shared/domain/Command';
+import { NoHandlerForMessageError } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError';
+
+class UnhandledCommand extends Command {
+ constructor() {
+ super('UnhandledCommandName');
+ }
+}
+
+describe('InMemoryCommandBus', () => {
+ it('throws an error if dispatches a command without handler', (done) => {
+ const unhandledCommand = new UnhandledCommand();
+ const commandBus = new InMemoryCommandBus();
+
+ try {
+ commandBus.dispatch(unhandledCommand);
+ } catch (error) {
+ expect(error).toBeInstanceOf(NoHandlerForMessageError);
+ expect(error.message).toBe('There is not handler for command of type UnhandledCommandName');
+ done();
+ }
+ });
+});
From 762b037c131258fcf623981d935eeefe7d9149f5 Mon Sep 17 00:00:00 2001
From: Antonio Leon
Date: Wed, 10 Jun 2020 17:27:28 +0200
Subject: [PATCH 02/48] WIP
---
src/Contexts/Shared/domain/Command.ts | 6 +---
src/Contexts/Shared/domain/CommandHandler.ts | 7 ++++
.../CommandBus/InMemoryCommandBus.ts | 36 +++++++++++++++++--
.../CommandBus/InMemoryCommandBus.test.ts | 27 ++++++++++++--
4 files changed, 66 insertions(+), 10 deletions(-)
create mode 100644 src/Contexts/Shared/domain/CommandHandler.ts
diff --git a/src/Contexts/Shared/domain/Command.ts b/src/Contexts/Shared/domain/Command.ts
index c88751b..f2c1ef2 100644
--- a/src/Contexts/Shared/domain/Command.ts
+++ b/src/Contexts/Shared/domain/Command.ts
@@ -1,7 +1,3 @@
export abstract class Command {
- readonly commandName: string;
-
- constructor(commandName: string) {
- this.commandName = commandName;
- }
+ static COMMAND_NAME: string;
}
\ No newline at end of file
diff --git a/src/Contexts/Shared/domain/CommandHandler.ts b/src/Contexts/Shared/domain/CommandHandler.ts
new file mode 100644
index 0000000..4296bd7
--- /dev/null
+++ b/src/Contexts/Shared/domain/CommandHandler.ts
@@ -0,0 +1,7 @@
+import { Command } from "./Command";
+
+export interface CommandHandler {
+ subscribedTo(): T;
+
+ handle(command: T): void;
+}
\ No newline at end of file
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
index 35d84b9..349e2be 100644
--- a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
+++ b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
@@ -1,9 +1,41 @@
import { CommandBus } from './../../domain/CommandBus';
import { Command } from '../../domain/Command';
import { NoHandlerForMessageError } from './NoHandlerForMessageError';
+import { CommandHandler } from '../../domain/CommandHandler';
+
+export class CommandHandlersInformation {
+ private commandHandlersMap: Map>;
+
+ constructor(commandHandlers: Array>) {
+ this.commandHandlersMap = this.formatHandlers(commandHandlers);
+ }
+
+ private formatHandlers(commandHandlers: Array>) {
+ const handlersMap = new Map();
+
+ commandHandlers.forEach(commandHandler => {
+ handlersMap.set(commandHandler.subscribedTo(), commandHandler);
+ });
+
+ return handlersMap;
+ }
+
+ public getHandler(command: Command) {
+ return this.commandHandlersMap.get(command.constructor.name);
+ }
+}
export class InMemoryCommandBus implements CommandBus {
+ constructor(private commandHandlersInformation: CommandHandlersInformation) {
+ }
+
dispatch(command: Command): void {
- throw new NoHandlerForMessageError(command);
+ const handler = this.commandHandlersInformation.getHandler(command);
+
+ if (!handler) {
+ throw new NoHandlerForMessageError(command);
+ }
+
+ handler.handle(command);
}
-}
\ No newline at end of file
+}
diff --git a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
index 9a8a25e..bf55669 100644
--- a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
+++ b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
@@ -3,9 +3,19 @@ import { Command } from '../../../../../src/Contexts/Shared/domain/Command';
import { NoHandlerForMessageError } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError';
class UnhandledCommand extends Command {
- constructor() {
- super('UnhandledCommandName');
- }
+ static COMMAND_NAME = 'unhandled.command';
+}
+
+class HandledCommand extends Command {
+ static COMMAND_NAME = 'handled.command';
+}
+
+interface CommandHandler {
+ handle(command: Command): void;
+}
+
+class MyCommandHandler implements CommandHandler {
+ handle(command: HandledCommand): void {}
}
describe('InMemoryCommandBus', () => {
@@ -21,4 +31,15 @@ describe('InMemoryCommandBus', () => {
done();
}
});
+
+ it('accepts a command with handler', done => {
+ const handledCommand = new HandledCommand();
+ const myCommandHandler = new MyCommandHandler();
+ const commandBus = new InMemoryCommandBus([myCommandHandler]);
+
+ try {
+ commandBus.dispatch(handledCommand);
+ done();
+ } catch (error) { }
+ });
});
From 71a896f8d1fcea6ae63b789a11f87eadce2b1d31 Mon Sep 17 00:00:00 2001
From: rsaladocid
Date: Wed, 10 Jun 2020 18:05:56 +0200
Subject: [PATCH 03/48] wip: subscribe to symbol
---
src/Contexts/Shared/domain/Command.ts | 4 +--
src/Contexts/Shared/domain/CommandHandler.ts | 9 +++---
.../CommandBus/CommandHandlersInformation.ts | 24 ++++++++++++++
.../CommandBus/InMemoryCommandBus.ts | 31 +++----------------
.../CommandBus/NoHandlerForMessageError.ts | 4 +--
.../CommandBus/InMemoryCommandBus.test.ts | 24 ++++++++------
6 files changed, 49 insertions(+), 47 deletions(-)
create mode 100644 src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts
diff --git a/src/Contexts/Shared/domain/Command.ts b/src/Contexts/Shared/domain/Command.ts
index f2c1ef2..9074445 100644
--- a/src/Contexts/Shared/domain/Command.ts
+++ b/src/Contexts/Shared/domain/Command.ts
@@ -1,3 +1 @@
-export abstract class Command {
- static COMMAND_NAME: string;
-}
\ No newline at end of file
+export abstract class Command {}
diff --git a/src/Contexts/Shared/domain/CommandHandler.ts b/src/Contexts/Shared/domain/CommandHandler.ts
index 4296bd7..87d1c94 100644
--- a/src/Contexts/Shared/domain/CommandHandler.ts
+++ b/src/Contexts/Shared/domain/CommandHandler.ts
@@ -1,7 +1,6 @@
-import { Command } from "./Command";
+import { Command } from './Command';
export interface CommandHandler {
- subscribedTo(): T;
-
- handle(command: T): void;
-}
\ No newline at end of file
+ subscribedTo(): T;
+ handle(command: T): void;
+}
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts b/src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts
new file mode 100644
index 0000000..531c872
--- /dev/null
+++ b/src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts
@@ -0,0 +1,24 @@
+import { Command } from '../../domain/Command';
+import { CommandHandler } from '../../domain/CommandHandler';
+
+export class CommandHandlersInformation {
+ private commandHandlersMap: Map>;
+
+ constructor(commandHandlers: Array>) {
+ this.commandHandlersMap = this.formatHandlers(commandHandlers);
+ }
+
+ private formatHandlers(commandHandlers: Array>): Map> {
+ const handlersMap = new Map();
+
+ commandHandlers.forEach(commandHandler => {
+ handlersMap.set(commandHandler.subscribedTo(), commandHandler);
+ });
+
+ return handlersMap;
+ }
+
+ public getCommandHandler(command: Command): CommandHandler | undefined {
+ return this.commandHandlersMap.get(command.constructor);
+ }
+}
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
index 349e2be..fc91594 100644
--- a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
+++ b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
@@ -1,36 +1,13 @@
-import { CommandBus } from './../../domain/CommandBus';
import { Command } from '../../domain/Command';
+import { CommandBus } from './../../domain/CommandBus';
+import { CommandHandlersInformation } from './CommandHandlersInformation';
import { NoHandlerForMessageError } from './NoHandlerForMessageError';
-import { CommandHandler } from '../../domain/CommandHandler';
-
-export class CommandHandlersInformation {
- private commandHandlersMap: Map>;
-
- constructor(commandHandlers: Array>) {
- this.commandHandlersMap = this.formatHandlers(commandHandlers);
- }
-
- private formatHandlers(commandHandlers: Array>) {
- const handlersMap = new Map();
-
- commandHandlers.forEach(commandHandler => {
- handlersMap.set(commandHandler.subscribedTo(), commandHandler);
- });
-
- return handlersMap;
- }
-
- public getHandler(command: Command) {
- return this.commandHandlersMap.get(command.constructor.name);
- }
-}
export class InMemoryCommandBus implements CommandBus {
- constructor(private commandHandlersInformation: CommandHandlersInformation) {
- }
+ constructor(private commandHandlersInformation: CommandHandlersInformation) {}
dispatch(command: Command): void {
- const handler = this.commandHandlersInformation.getHandler(command);
+ const handler = this.commandHandlersInformation.getCommandHandler(command);
if (!handler) {
throw new NoHandlerForMessageError(command);
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts b/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
index 76f34b7..4a3d932 100644
--- a/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
+++ b/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
@@ -2,6 +2,6 @@ import { Command } from '../../domain/Command';
export class NoHandlerForMessageError extends Error {
constructor(command: Command) {
- super(`There is not handler for command of type ${command.commandName}`);
+ super(`There is not handler for command of type ${command.constructor.name}`);
}
-}
\ No newline at end of file
+}
diff --git a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
index bf55669..2adc25f 100644
--- a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
+++ b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
@@ -1,5 +1,7 @@
-import { InMemoryCommandBus } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus';
import { Command } from '../../../../../src/Contexts/Shared/domain/Command';
+import { CommandHandler } from '../../../../../src/Contexts/Shared/domain/CommandHandler';
+import { CommandHandlersInformation } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation';
+import { InMemoryCommandBus } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus';
import { NoHandlerForMessageError } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError';
class UnhandledCommand extends Command {
@@ -10,24 +12,25 @@ class HandledCommand extends Command {
static COMMAND_NAME = 'handled.command';
}
-interface CommandHandler {
- handle(command: Command): void;
-}
+class MyCommandHandler implements CommandHandler {
+ subscribedTo(): HandledCommand {
+ return HandledCommand;
+ }
-class MyCommandHandler implements CommandHandler {
handle(command: HandledCommand): void {}
}
describe('InMemoryCommandBus', () => {
- it('throws an error if dispatches a command without handler', (done) => {
+ it('throws an error if dispatches a command without handler', done => {
const unhandledCommand = new UnhandledCommand();
- const commandBus = new InMemoryCommandBus();
+ const commandHandlersInformation = new CommandHandlersInformation([]);
+ const commandBus = new InMemoryCommandBus(commandHandlersInformation);
try {
commandBus.dispatch(unhandledCommand);
} catch (error) {
expect(error).toBeInstanceOf(NoHandlerForMessageError);
- expect(error.message).toBe('There is not handler for command of type UnhandledCommandName');
+ expect(error.message).toBe('There is not handler for command of type UnhandledCommand');
done();
}
});
@@ -35,11 +38,12 @@ describe('InMemoryCommandBus', () => {
it('accepts a command with handler', done => {
const handledCommand = new HandledCommand();
const myCommandHandler = new MyCommandHandler();
- const commandBus = new InMemoryCommandBus([myCommandHandler]);
+ const commandHandlersInformation = new CommandHandlersInformation([myCommandHandler]);
+ const commandBus = new InMemoryCommandBus(commandHandlersInformation);
try {
commandBus.dispatch(handledCommand);
done();
- } catch (error) { }
+ } catch (error) {}
});
});
From 2d3309cad85198ca0e1b67298d2d9c38ede42673 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Thu, 11 Jun 2020 19:41:18 +0200
Subject: [PATCH 04/48] Add frontend backoffice skeleton
---
package-lock.json | 84 +++++++++++--------
package.json | 3 +
src/apps/backoffice/frontend/app.ts | 24 ++++++
src/apps/backoffice/frontend/config/config.ts | 14 ++++
.../backoffice/frontend/config/default.json | 1 +
.../dependency-injection/application.yaml | 7 ++
.../dependency-injection/application_dev.yaml | 2 +
.../application_production.yaml | 2 +
.../application_staging.yaml | 2 +
.../application_test.yaml | 2 +
.../config/dependency-injection/index.ts | 9 ++
.../backoffice/frontend/config/staging.json | 1 +
src/apps/backoffice/frontend/config/test.json | 1 +
.../frontend/controllers/HomeGetController.ts | 7 ++
.../backoffice/frontend/routes/home.route.ts | 8 ++
src/apps/backoffice/frontend/routes/index.ts | 12 +++
src/apps/backoffice/frontend/server.ts | 22 +++++
src/apps/backoffice/frontend/views/index.ejs | 1 +
18 files changed, 165 insertions(+), 37 deletions(-)
create mode 100644 src/apps/backoffice/frontend/app.ts
create mode 100644 src/apps/backoffice/frontend/config/config.ts
create mode 100644 src/apps/backoffice/frontend/config/default.json
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/application.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/application_dev.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/application_production.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/application_staging.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/application_test.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/index.ts
create mode 100644 src/apps/backoffice/frontend/config/staging.json
create mode 100644 src/apps/backoffice/frontend/config/test.json
create mode 100644 src/apps/backoffice/frontend/controllers/HomeGetController.ts
create mode 100644 src/apps/backoffice/frontend/routes/home.route.ts
create mode 100644 src/apps/backoffice/frontend/routes/index.ts
create mode 100644 src/apps/backoffice/frontend/server.ts
create mode 100644 src/apps/backoffice/frontend/views/index.ejs
diff --git a/package-lock.json b/package-lock.json
index cd2c9a2..3b25a29 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -815,7 +815,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -1402,7 +1401,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -2181,6 +2179,14 @@
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
+ "ejs": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz",
+ "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==",
+ "requires": {
+ "jake": "^10.6.1"
+ }
+ },
"elegant-spinner": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
@@ -2316,8 +2322,7 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"escodegen": {
"version": "1.12.0",
@@ -2692,6 +2697,14 @@
"through2": "^2.0.1"
}
},
+ "filelist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz",
+ "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==",
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
"filewatcher": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz",
@@ -2847,8 +2860,7 @@
"version": "2.1.1",
"resolved": false,
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -2872,15 +2884,13 @@
"version": "1.0.0",
"resolved": false,
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": false,
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2897,22 +2907,19 @@
"version": "1.1.0",
"resolved": false,
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": false,
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"resolved": false,
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -3043,8 +3050,7 @@
"version": "2.0.3",
"resolved": false,
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -3058,7 +3064,6 @@
"resolved": false,
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -3075,7 +3080,6 @@
"resolved": false,
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -3084,15 +3088,13 @@
"version": "0.0.8",
"resolved": false,
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"resolved": false,
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -3113,7 +3115,6 @@
"resolved": false,
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -3202,8 +3203,7 @@
"version": "1.0.1",
"resolved": false,
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -3217,7 +3217,6 @@
"resolved": false,
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3313,8 +3312,7 @@
"version": "5.1.2",
"resolved": false,
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3356,7 +3354,6 @@
"resolved": false,
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3378,7 +3375,6 @@
"resolved": false,
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3427,15 +3423,13 @@
"version": "1.0.2",
"resolved": false,
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"resolved": false,
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -3632,8 +3626,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-glob": {
"version": "0.1.1",
@@ -4321,6 +4314,24 @@
"handlebars": "^4.1.2"
}
},
+ "jake": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
+ "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+ "requires": {
+ "async": "0.9.x",
+ "chalk": "^2.4.2",
+ "filelist": "^1.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
+ }
+ }
+ },
"jest": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz",
@@ -7674,7 +7685,6 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
"requires": {
"has-flag": "^3.0.0"
}
diff --git a/package.json b/package.json
index 556e522..20b819c 100644
--- a/package.json
+++ b/package.json
@@ -8,10 +8,12 @@
},
"scripts": {
"dev": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules --inspect=0.0.0.0:9267 ./src/apps/mooc_backend/server.ts",
+ "dev:backoffice:frontend": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules --inspect=0.0.0.0:9267 ./src/apps/backoffice/frontend/server.ts",
"test": "npm run test:unit && npm run test:features",
"test:unit": "NODE_ENV=test jest",
"test:features": "NODE_ENV=test cucumber-js -p default",
"start": "NODE_ENV=production node dist/src/apps/mooc_backend/server",
+ "start:backoffice:frontend": "NODE_ENV=production node dist/src/apps/backoffice/frontend/server",
"build": "npm run build:clean && npm run build:tsc && npm run build:di",
"build:tsc": "tsc -p tsconfig.prod.json",
"build:di": "copy 'src/**/*.yaml' dist/src",
@@ -34,6 +36,7 @@
"compression": "^1.7.4",
"convict": "^5.1.0",
"copy": "^0.3.2",
+ "ejs": "^3.1.3",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"glob": "^7.1.6",
diff --git a/src/apps/backoffice/frontend/app.ts b/src/apps/backoffice/frontend/app.ts
new file mode 100644
index 0000000..2e67d71
--- /dev/null
+++ b/src/apps/backoffice/frontend/app.ts
@@ -0,0 +1,24 @@
+import bodyParser from 'body-parser';
+import express from 'express';
+import helmet from 'helmet';
+import compress from 'compression';
+import { registerRoutes } from './routes';
+import path from 'path';
+
+const app: express.Express = express();
+
+app.set('port', process.env.PORT || 8032);
+app.set('view engine', 'ejs');
+app.set('views', path.join(__dirname, '/views'));
+
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: true }));
+app.use(helmet.xssFilter());
+app.use(helmet.noSniff());
+app.use(helmet.hidePoweredBy());
+app.use(helmet.frameguard({ action: 'deny' }));
+app.use(compress());
+
+registerRoutes(app);
+
+export default app;
diff --git a/src/apps/backoffice/frontend/config/config.ts b/src/apps/backoffice/frontend/config/config.ts
new file mode 100644
index 0000000..4405a32
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/config.ts
@@ -0,0 +1,14 @@
+import convict from 'convict';
+
+const convictConfig = convict({
+ env: {
+ doc: 'The application environment.',
+ format: ['production', 'development', 'staging', 'test'],
+ default: 'default',
+ env: 'NODE_ENV'
+ }
+});
+
+convictConfig.loadFile([__dirname + '/default.json', __dirname + '/' + convictConfig.get('env') + '.json']);
+
+export default convictConfig;
diff --git a/src/apps/backoffice/frontend/config/default.json b/src/apps/backoffice/frontend/config/default.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/default.json
@@ -0,0 +1 @@
+{}
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
new file mode 100644
index 0000000..22d0a1d
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
@@ -0,0 +1,7 @@
+services:
+ Contexts.shared.Logger:
+ class: ../../../../../Contexts/Shared/infrastructure/WinstonLogger
+ arguments: []
+
+ Apps.Backoffice.Frontend.controllers.HomeGetController:
+ class: ../../controllers/HomeGetController
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application_dev.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application_dev.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application_dev.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application_production.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application_production.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application_production.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application_staging.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application_staging.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application_staging.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application_test.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application_test.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application_test.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/index.ts b/src/apps/backoffice/frontend/config/dependency-injection/index.ts
new file mode 100644
index 0000000..27d2a35
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/index.ts
@@ -0,0 +1,9 @@
+import { ContainerBuilder, YamlFileLoader } from 'node-dependency-injection';
+
+const container = new ContainerBuilder();
+const loader = new YamlFileLoader(container);
+const env = process.env.NODE_ENV || 'dev';
+
+loader.load(`${__dirname}/application_${env}.yaml`);
+
+export default container;
diff --git a/src/apps/backoffice/frontend/config/staging.json b/src/apps/backoffice/frontend/config/staging.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/staging.json
@@ -0,0 +1 @@
+{}
diff --git a/src/apps/backoffice/frontend/config/test.json b/src/apps/backoffice/frontend/config/test.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/test.json
@@ -0,0 +1 @@
+{}
diff --git a/src/apps/backoffice/frontend/controllers/HomeGetController.ts b/src/apps/backoffice/frontend/controllers/HomeGetController.ts
new file mode 100644
index 0000000..af580c3
--- /dev/null
+++ b/src/apps/backoffice/frontend/controllers/HomeGetController.ts
@@ -0,0 +1,7 @@
+import { Request, Response } from 'express';
+
+export class HomeGetController {
+ run(req: Request, res: Response) {
+ res.render('index', { foo: 'FOO' });
+ }
+}
diff --git a/src/apps/backoffice/frontend/routes/home.route.ts b/src/apps/backoffice/frontend/routes/home.route.ts
new file mode 100644
index 0000000..6eacd33
--- /dev/null
+++ b/src/apps/backoffice/frontend/routes/home.route.ts
@@ -0,0 +1,8 @@
+import { Express } from 'express';
+import container from '../config/dependency-injection';
+import { HomeGetController } from '../controllers/HomeGetController';
+
+export const register = (app: Express) => {
+ const controller: HomeGetController = container.get('Apps.Backoffice.Frontend.controllers.HomeGetController');
+ app.get('/', controller.run.bind(controller));
+};
diff --git a/src/apps/backoffice/frontend/routes/index.ts b/src/apps/backoffice/frontend/routes/index.ts
new file mode 100644
index 0000000..56b36c7
--- /dev/null
+++ b/src/apps/backoffice/frontend/routes/index.ts
@@ -0,0 +1,12 @@
+import { Express } from 'express';
+import glob from 'glob';
+
+export function registerRoutes(app: Express) {
+ const routes = glob.sync(__dirname + '/**/*.route.*');
+ routes.map(route => register(route, app));
+}
+
+function register(routePath: string, app: Express) {
+ const route = require(routePath);
+ route.register(app);
+}
diff --git a/src/apps/backoffice/frontend/server.ts b/src/apps/backoffice/frontend/server.ts
new file mode 100644
index 0000000..76b7b0a
--- /dev/null
+++ b/src/apps/backoffice/frontend/server.ts
@@ -0,0 +1,22 @@
+import errorHandler from 'errorhandler';
+import app from './app';
+import container from './config/dependency-injection';
+
+/**
+ * Error Handler. Provides full stack - remove for production
+ */
+app.use(errorHandler());
+
+/**
+ * Start Express server.
+ */
+const server = app.listen(app.get('port'), () => {
+ const winstonLogger = container.get('Contexts.shared.Logger');
+
+ winstonLogger.info(
+ ` Backoffice frontend is running at http://localhost:${app.get('port')} in ${app.get('env')} mode`
+ );
+ console.log(' Press CTRL-C to stop\n');
+});
+
+export default server;
diff --git a/src/apps/backoffice/frontend/views/index.ejs b/src/apps/backoffice/frontend/views/index.ejs
new file mode 100644
index 0000000..e965047
--- /dev/null
+++ b/src/apps/backoffice/frontend/views/index.ejs
@@ -0,0 +1 @@
+Hello
From 795e8d629473494eb946b7d50c3705533f0428e3 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Thu, 11 Jun 2020 20:21:46 +0200
Subject: [PATCH 05/48] Added home partially
---
package-lock.json | 200 ++++++++++++++----
package.json | 3 +-
src/apps/backoffice/frontend/app.ts | 12 +-
.../frontend/controllers/HomeGetController.ts | 5 +-
.../frontend/public/images/logo.png | Bin 0 -> 4186 bytes
.../backoffice/frontend/templates/master.html | 34 +++
.../frontend/templates/pages/home.html | 7 +
.../frontend/templates/partials/footer.html | 7 +
.../frontend/templates/partials/header.html | 28 +++
src/apps/backoffice/frontend/views/index.ejs | 1 -
10 files changed, 256 insertions(+), 41 deletions(-)
create mode 100644 src/apps/backoffice/frontend/public/images/logo.png
create mode 100644 src/apps/backoffice/frontend/templates/master.html
create mode 100644 src/apps/backoffice/frontend/templates/pages/home.html
create mode 100644 src/apps/backoffice/frontend/templates/partials/footer.html
create mode 100644 src/apps/backoffice/frontend/templates/partials/header.html
delete mode 100644 src/apps/backoffice/frontend/views/index.ejs
diff --git a/package-lock.json b/package-lock.json
index 3b25a29..5aa7ea8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -655,6 +655,12 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.1.tgz",
"integrity": "sha512-hx6zWtudh3Arsbl3cXay+JnkvVgCKzCWKv42C9J01N2T2np4h8w5X8u6Tpz5mj38kE3M9FM0Pazx8vKFFMnjLQ=="
},
+ "@types/nunjucks": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.1.3.tgz",
+ "integrity": "sha512-42IiIIBdoB7ZDwCVhCWYT4fMCj+4TeacuVgh7xyT2du5EhkpA+OFeeDdYTFCUt1MrHb8Aw7ZqFvr8s1bwP9l8w==",
+ "dev": true
+ },
"@types/range-parser": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
@@ -734,6 +740,11 @@
"integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==",
"dev": true
},
+ "a-sync-waterfall": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
+ "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA=="
+ },
"abab": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz",
@@ -815,6 +826,7 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -920,6 +932,11 @@
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true
},
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
@@ -1144,6 +1161,12 @@
"integrity": "sha1-Qpzuu/pffpNueNc/vcfacWKyDiA=",
"dev": true
},
+ "binary-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+ "optional": true
+ },
"bl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
@@ -1401,12 +1424,107 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
+ "chokidar": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+ "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+ "optional": true,
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.1.2",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.4.0"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "optional": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "optional": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "optional": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "fsevents": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "optional": true
+ },
+ "glob-parent": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+ "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+ "optional": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "optional": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "optional": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
"ci-info": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -2179,14 +2297,6 @@
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
- "ejs": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz",
- "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==",
- "requires": {
- "jake": "^10.6.1"
- }
- },
"elegant-spinner": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
@@ -2322,7 +2432,8 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
},
"escodegen": {
"version": "1.12.0",
@@ -2697,14 +2808,6 @@
"through2": "^2.0.1"
}
},
- "filelist": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz",
- "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==",
- "requires": {
- "minimatch": "^3.0.4"
- }
- },
"filewatcher": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz",
@@ -3626,7 +3729,8 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
},
"has-glob": {
"version": "0.1.1",
@@ -3944,6 +4048,15 @@
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
"dev": true
},
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "optional": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -4314,24 +4427,6 @@
"handlebars": "^4.1.2"
}
},
- "jake": {
- "version": "10.8.2",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
- "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
- "requires": {
- "async": "0.9.x",
- "chalk": "^2.4.2",
- "filelist": "^1.0.1",
- "minimatch": "^3.0.4"
- },
- "dependencies": {
- "async": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
- "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
- }
- }
- },
"jest": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz",
@@ -6093,6 +6188,24 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
+ "nunjucks": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.1.tgz",
+ "integrity": "sha512-LYlVuC1ZNSalQQkLNNPvcgPt2M9FTY9bs39mTCuFXtqh7jWbYzhDlmz2M6onPiXEhdZo+b9anRhc+uBGuJZ2bQ==",
+ "requires": {
+ "a-sync-waterfall": "^1.0.0",
+ "asap": "^2.0.3",
+ "chokidar": "^3.3.0",
+ "commander": "^3.0.2"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
+ "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow=="
+ }
+ }
+ },
"nwsapi": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz",
@@ -6397,6 +6510,11 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
"dev": true
},
+ "picomatch": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
+ },
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
@@ -6622,6 +6740,15 @@
"util-deprecate": "~1.0.1"
}
},
+ "readdirp": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+ "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+ "optional": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
"realpath-native": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz",
@@ -7685,6 +7812,7 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
"requires": {
"has-flag": "^3.0.0"
}
diff --git a/package.json b/package.json
index 20b819c..919d2a3 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,6 @@
"compression": "^1.7.4",
"convict": "^5.1.0",
"copy": "^0.3.2",
- "ejs": "^3.1.3",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"glob": "^7.1.6",
@@ -45,6 +44,7 @@
"mandrill-api": "^1.0.45",
"mongodb": "^3.5.2",
"node-dependency-injection": "^2.4.2",
+ "nunjucks": "^3.2.1",
"ts-node": "^8.3.0",
"typescript": "^3.7.2",
"uuid": "^3.3.3",
@@ -56,6 +56,7 @@
"@types/cucumber": "^4.0.7",
"@types/faker": "^4.1.5",
"@types/jest": "^24.0.18",
+ "@types/nunjucks": "^3.1.3",
"@types/supertest": "^2.0.8",
"cucumber": "^6.0.5",
"faker": "^4.1.0",
diff --git a/src/apps/backoffice/frontend/app.ts b/src/apps/backoffice/frontend/app.ts
index 2e67d71..1fb376c 100644
--- a/src/apps/backoffice/frontend/app.ts
+++ b/src/apps/backoffice/frontend/app.ts
@@ -4,13 +4,21 @@ import helmet from 'helmet';
import compress from 'compression';
import { registerRoutes } from './routes';
import path from 'path';
+import nunjucks from 'nunjucks';
const app: express.Express = express();
app.set('port', process.env.PORT || 8032);
-app.set('view engine', 'ejs');
-app.set('views', path.join(__dirname, '/views'));
+// Templates
+app.set('view engine', 'html');
+nunjucks.configure(path.join(__dirname, '/templates'), {
+ autoescape: true,
+ express: app,
+ watch: true
+});
+
+app.use(express.static(path.join(__dirname, '/public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(helmet.xssFilter());
diff --git a/src/apps/backoffice/frontend/controllers/HomeGetController.ts b/src/apps/backoffice/frontend/controllers/HomeGetController.ts
index af580c3..163d665 100644
--- a/src/apps/backoffice/frontend/controllers/HomeGetController.ts
+++ b/src/apps/backoffice/frontend/controllers/HomeGetController.ts
@@ -2,6 +2,9 @@ import { Request, Response } from 'express';
export class HomeGetController {
run(req: Request, res: Response) {
- res.render('index', { foo: 'FOO' });
+ res.render('pages/home', {
+ title: 'Welcome',
+ description: 'CodelyTV - Backoffice'
+ });
}
}
diff --git a/src/apps/backoffice/frontend/public/images/logo.png b/src/apps/backoffice/frontend/public/images/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..759395922beee82928cbb06c3bfe0d415ceb70f5
GIT binary patch
literal 4186
zcmV-g5T);lP){7FPXRCwC#T~CM{Ss8z`EP{BL2`GA4
z?PA0|NG~bLE(oIOVD>08i@M&N$t6(~(u;>(5H>yP!37~56k&5o=cMc^+X3~GNV>gv
z*d3{62lte*hFt_tnFhs!i}Cx$uhz0s_5RiOs%j?R2anFAtLwdb^}gTxec$`u_f{S}
zc%Vc?L`05*JSJTrA|fJyB_bjsB7h|#A|ik#A|fIpfF&X#BEln&yIlOtdsoiD$N9p4
z-+$|qKe*m>!=HZl
zp?#^(ePorrSy{2^a004Vp`5A04*;#*rWy@kh3$B&;%jWjC0pR)0Ib5`R~(9PjDaeG
z4+N*x!dFY^i?t54ZwMb(OTM}Z?b~h(ut3MK-)2yH4R^@_lo<5)kaVl6e^7Sdx)HN3
zW1o*p#tX_E^myRJu%IJP!N+YVr!<$HYPgei^&yzO2JL@x3ilWh=$%xFH8Xh^^aK)OjdEn63DFD>C!c06J&?FrBelLJk
zE>laeniH_iN)#8BW7Fb3Lna2<219gkALvU^Q{QFZ^bt^l?bX9SC1)R
zCC8|%2Reqr6x11NrBFu(4gjo7WT6q0@J~>lgz`QN>TB?M1r+!n9UTlhKf>Gxta37~
zFb$VB3PXUfNdq>j@G)c#SFCGV$C*zi)V86%tnH?HW)AhnROdid?<6>&db8)WQPL_U
zTUPy^`k)AO&if+w_V)7oDn9^)e!uSnF2R8pK@Zr_foAe{W?00odNnMY#sKTdTwULT
z@>LiJ-+`C@yAA@@M%@l|0IXX!3P+&=BV`v@*rRe3Sr5NOU)#_n){B4<>$3@xU8TBA
zZLz^ZC*-rT^JeAo@AX`65Y
zmO+0Oz^<&wKpQ?R?C{^hOaCR5Pjtwn(G8vh7@)NV1O5I5G%KN;g1a8Pot7SDAS}R}rl6edt#H=2bzWzJRqJ5G3$n
zFm25rU{LjI-s^tNc1I1(TsFR=nc|JGU)2p70*)Jj9x2h(Ib#OM(-pI|&%3PxhlOop
zz#NPe??Qy`Inei%gnn-xX5rBAj-5h!9y1{N`4YtsvC;VpPf3;5S
zuR9ZR`vz=meH*YkAU}w0jMJ8eX-pm3w@_}G7peyS!~(3)&$p8+*DL^I=)#^grhdf0
zVxk&=;CjCW=OCoj##$@e#IAIJgj;Z&`r+{skjk=(B2Zl{`OWKr6!k+;z7OSjP^@pm
zK>EGo@3CD!F8tqZcpl7#dX!zlkkqd!-++!?p<-P&fD{7SLymf4Eco4q!R(!sn1Vge
zIwKmmLruMD$#a@O8G&h}@$U^(^=^b!+EhNXn2dA^$q{5aUqS!hGO&6Hls@$4=g%O};0hO%kJ|o-+VxV&R~PAdUNo3QRkCbwuiv(AHo`$t
z%3Oe$MmAK4`+8Ge;8ENWF2^bPb2BWJJW8JhXn{-bXXSNetGAzK%80tOfYDj~_
zv&J>q6>cF)IRNWag?|Xa>Xn8R7jxEp6Uv`q@O;Suv|b_5x^MYhp{TpB?`liK1Z=|-
zh7NT`8m6;wNEvL+V4zOj{>mNOSU1O2Ti28~5fhVPi~I*mVa;Gdhj3feSt%SD*p=6Q
zN88moRQB_fF1bnhn88FUGiQA=q;??+S~shYY-6b$+2Fu1;6gB%O^!kA5USzxZX+hP
zeVP$mOwSv_3h;8gQ|e=#-i~}D^2-3L%H%`8*6oG?>wPG{a=89ARh?;c-*YfDWe)0=
z(I*YpiHbR8P|U;uB&Uwa3`dsl%;((>>P}u1-Of3tw1DMfUYUgMx%6n0?%f>J$tF<-
zSZGo`3*}OYlAi$MhE%lVG#eql3iiD)=NO@5siZ1f*zBvBm~<@7zcLRuwteTZM#ZGaHY9Y2I{6D
z)3N15Fs}kc#S=SK`KOj~lAKq^Khv1Sy8Iuq{tEd4O~y^ub#C^4TS$A0Bv+boPZCudu7
zTO_uiY;mx}sBU9yobLA<(AmF2`5FwiuXuu0opwhp4Fp>yabVKDr9TYm1?oQxG%Y)U$Y&ymnAkRFcGI{9sMHb*XMRlV%4Du@bF`<;6v=ob@+BB#
ze{2~vgRT(fqQMi*DwuAyE_JBOg;CU2Ob=6*^XxrrC$41b4)O3Y?`p?R?d|Oim?uHq
za~yD;#H?dS7Vl1H?%m{C#cTtx{t4xWP<{df?O&>WSqlYN1Xf9=)bKY(p-)Oe2Dr=z
z7e>KRr*(aX)ywCo-Y8efkYYR@Bfb};h
zAE$rgs^hm{u-sF}Lk2a?!byRF;8OesDDMH8FsXrgZ~|6h$##-J^=T&t>I-h=^H~Mu
z$R1G%l>L668?c&iTO@`FpM48Xn}Br=%9o++cQnhW39x+G)ldTpJyo(1xq?w}w0G$c
zl$kOpQdxbKeHriwFs_L}2SQvxsgs^3m^1-cDBBu#HRfzcaHl&A#&@9ntixcXo1xAc
z!XB!?3SZz=%_U3nzbK#kYs}9LOY>~Nq?l0~N`(CjuZ0Yuf4!Qkna?F=`5KU>ru8ktCQGRh#GQ52L@zi7HdZ=Ed&uKMvU~Vn|>cU`B
zP5Z4gFBCGPBJ;S5eO{7jG-75YS?1QtwxYA0a=0JYq^Ma23$`~lJgi2F@wxJ9SxuM3IfwL?IQ=$o`sS{b{
z#FVMQV^gtCSrKp&-HNE;P}<9M|FNYBIx{Gy&Xj+H`fg4jl`$$C-xv3moJE6r;+o1j
z$l<_`JYXRZ(CIR!{OKQ@4x>?alPoJ((?SC{TV#$*3rfF6N@>bYI;xrhHNKH8ViHqT
zzP%<=jtLJDB;cOQ3dP2DBm~Y=Vt^^twdODx*eJRwY-3`nn9d;@{eFMuF=o1Qo}x=#
z7$iCk(Fh;FI!_yokG8!${qD>A(764kfd=ZutvIKkE%+zyBRpT@c0&(^@Bynqg@f5-
zMy@Kq11az<#j(aryd0oT9fO%_?zu|sx$IHpLOr~I5qX+rQv&%O^ZWPR!O?|GBCd6f
zLN&t1hgFut9S@GUP30bd$9jVur>MTSa&36kvfY&|OEE>_dVp1yK8Bm#FO)tj=UC}e
zhlEhfVSqZ1SZj&N?3Ig(?z0)7ozCFWQqsOsaoARKi(?B;9l+YPxTaCSvaD~{<%Sf@
z`CNd3ioTA>V(EUHvF?Q`->Q;--ZYS(VbtKnP};YiN&E8cOvv2koJ6?I!KN9Ovh0sx
z$Oaez>&+*2kf~f($4jnLyIoD0DGic2)60Dh?m4iDfnrh;1UyVL99!0j%fHB@QV40rbT8Kn~d9m_g
zLC0L8G&AR^D5#s(I1*AQvj2?<$j(e1|`Zva+&bye7AS
zIWC#KQ8|wGxVeIbjZoM^RHA$dDb0+zzBu=+c{$A0nK0LxJ>Q_II=Q3(Sg5d9%C778
z`zt>8uLvAH%+B+(8NZxDIj_nXY~m9n>WV)CSPj2$k&`6_z{1I+EZkuMfE7z`HDnTs
zh&)PSnG)##1i)%dRmWz{q*n#7L`1lOD)U=reww+m->Rfr9TULfvWUba6q8Wo2&~Yd
zT(-z@PUj~?{h@??cPlQzQ=TK~VIGmq&msa=|6P@>T9KVns-Uvpt&yYsuIBa=>0x15
z!mvcR0n3zO17occ^}kpoWL2h3&%&+*umrF~f`C@4`1cQ<^W5+(A||1Th*r3_lw1(7
z62KA>2_m#*=mNv7mIPK4=~V$N5s{Ffg&S$wZaWoJ^%m!07*qoM6N<$g25l>LjV8(
literal 0
HcmV?d00001
diff --git a/src/apps/backoffice/frontend/templates/master.html b/src/apps/backoffice/frontend/templates/master.html
new file mode 100644
index 0000000..fd1e760
--- /dev/null
+++ b/src/apps/backoffice/frontend/templates/master.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+ {{title}}
+ {{description}}
+
+
+ {% include 'partials/header.html' %}
+
+ {% if flash.message %}
+
+
+
{{ flash.message }}
+
+ {% endif %}
+
+
+
{% block page_title %}{% endblock %}
+ {% block main %}{% endblock %}
+
+
+
+
+ {% include 'partials/footer.html' %}
+
+
diff --git a/src/apps/backoffice/frontend/templates/pages/home.html b/src/apps/backoffice/frontend/templates/pages/home.html
new file mode 100644
index 0000000..30a2e95
--- /dev/null
+++ b/src/apps/backoffice/frontend/templates/pages/home.html
@@ -0,0 +1,7 @@
+{% extends '../master.html' %}
+
+{% block page_title %}HOME{% endblock %}
+
+{% block main %}
+ HOLIII HOME
+{% endblock %}
diff --git a/src/apps/backoffice/frontend/templates/partials/footer.html b/src/apps/backoffice/frontend/templates/partials/footer.html
new file mode 100644
index 0000000..1c7693f
--- /dev/null
+++ b/src/apps/backoffice/frontend/templates/partials/footer.html
@@ -0,0 +1,7 @@
+
diff --git a/src/apps/backoffice/frontend/templates/partials/header.html b/src/apps/backoffice/frontend/templates/partials/header.html
new file mode 100644
index 0000000..30fe251
--- /dev/null
+++ b/src/apps/backoffice/frontend/templates/partials/header.html
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/apps/backoffice/frontend/views/index.ejs b/src/apps/backoffice/frontend/views/index.ejs
deleted file mode 100644
index e965047..0000000
--- a/src/apps/backoffice/frontend/views/index.ejs
+++ /dev/null
@@ -1 +0,0 @@
-Hello
From 3c9c97f9106e91ef30285d399fb35bdcec4bed81 Mon Sep 17 00:00:00 2001
From: rsaladocid
Date: Fri, 12 Jun 2020 16:10:18 +0200
Subject: [PATCH 06/48] Refactor command handlers information
---
.../Shared/domain/CommandNotRegisteredError.ts | 7 +++++++
.../CommandBus/CommandHandlersInformation.ts | 11 +++++++++--
.../infrastructure/CommandBus/InMemoryCommandBus.ts | 7 +------
.../CommandBus/NoHandlerForMessageError.ts | 7 -------
.../CommandBus/InMemoryCommandBus.test.ts | 6 +++---
5 files changed, 20 insertions(+), 18 deletions(-)
create mode 100644 src/Contexts/Shared/domain/CommandNotRegisteredError.ts
delete mode 100644 src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
diff --git a/src/Contexts/Shared/domain/CommandNotRegisteredError.ts b/src/Contexts/Shared/domain/CommandNotRegisteredError.ts
new file mode 100644
index 0000000..1da7052
--- /dev/null
+++ b/src/Contexts/Shared/domain/CommandNotRegisteredError.ts
@@ -0,0 +1,7 @@
+import { Command } from './Command';
+
+export class CommandNotRegisteredError extends Error {
+ constructor(command: Command) {
+ super(`The command <${command.constructor.name}> hasn't a command handler associated`);
+ }
+}
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts b/src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts
index 531c872..d157ed6 100644
--- a/src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts
+++ b/src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation.ts
@@ -1,5 +1,6 @@
import { Command } from '../../domain/Command';
import { CommandHandler } from '../../domain/CommandHandler';
+import { CommandNotRegisteredError } from '../../domain/CommandNotRegisteredError';
export class CommandHandlersInformation {
private commandHandlersMap: Map>;
@@ -18,7 +19,13 @@ export class CommandHandlersInformation {
return handlersMap;
}
- public getCommandHandler(command: Command): CommandHandler | undefined {
- return this.commandHandlersMap.get(command.constructor);
+ public search(command: Command): CommandHandler {
+ const commandHandler = this.commandHandlersMap.get(command.constructor);
+
+ if (!commandHandler) {
+ throw new CommandNotRegisteredError(command);
+ }
+
+ return commandHandler;
}
}
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
index fc91594..949000a 100644
--- a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
+++ b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
@@ -1,17 +1,12 @@
import { Command } from '../../domain/Command';
import { CommandBus } from './../../domain/CommandBus';
import { CommandHandlersInformation } from './CommandHandlersInformation';
-import { NoHandlerForMessageError } from './NoHandlerForMessageError';
export class InMemoryCommandBus implements CommandBus {
constructor(private commandHandlersInformation: CommandHandlersInformation) {}
dispatch(command: Command): void {
- const handler = this.commandHandlersInformation.getCommandHandler(command);
-
- if (!handler) {
- throw new NoHandlerForMessageError(command);
- }
+ const handler = this.commandHandlersInformation.search(command);
handler.handle(command);
}
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts b/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
deleted file mode 100644
index 4a3d932..0000000
--- a/src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Command } from '../../domain/Command';
-
-export class NoHandlerForMessageError extends Error {
- constructor(command: Command) {
- super(`There is not handler for command of type ${command.constructor.name}`);
- }
-}
diff --git a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
index 2adc25f..1de8598 100644
--- a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
+++ b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
@@ -1,8 +1,8 @@
import { Command } from '../../../../../src/Contexts/Shared/domain/Command';
import { CommandHandler } from '../../../../../src/Contexts/Shared/domain/CommandHandler';
+import { CommandNotRegisteredError } from '../../../../../src/Contexts/Shared/domain/CommandNotRegisteredError';
import { CommandHandlersInformation } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation';
import { InMemoryCommandBus } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus';
-import { NoHandlerForMessageError } from '../../../../../src/Contexts/Shared/infrastructure/CommandBus/NoHandlerForMessageError';
class UnhandledCommand extends Command {
static COMMAND_NAME = 'unhandled.command';
@@ -29,8 +29,8 @@ describe('InMemoryCommandBus', () => {
try {
commandBus.dispatch(unhandledCommand);
} catch (error) {
- expect(error).toBeInstanceOf(NoHandlerForMessageError);
- expect(error.message).toBe('There is not handler for command of type UnhandledCommand');
+ expect(error).toBeInstanceOf(CommandNotRegisteredError);
+ expect(error.message).toBe(`The command hasn't a command handler associated`);
done();
}
});
From 784ab218b3f90212f34031b62da3e36e12b8211a Mon Sep 17 00:00:00 2001
From: Antonio Leon
Date: Fri, 12 Jun 2020 17:29:01 +0200
Subject: [PATCH 07/48] Command handler to create course
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Rubén Salado
Co-authored-by: Iván Portillo
---
.../Mooc/Courses/application/CourseCreator.ts | 14 ++++++++----
.../application/CreateCourseCommand.ts | 20 +++++++++++++++++
.../application/CreateCourseCommandHandler.ts | 22 +++++++++++++++++++
src/Contexts/Shared/domain/CommandBus.ts | 2 +-
src/Contexts/Shared/domain/CommandHandler.ts | 4 ++--
.../CommandBus/InMemoryCommandBus.ts | 4 ++--
.../Courses/application.yaml | 6 +++++
.../Shared/application.yaml | 8 +++++++
.../apps/application.yaml | 2 +-
.../controllers/CoursePutController.ts | 8 ++++---
10 files changed, 77 insertions(+), 13 deletions(-)
create mode 100644 src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts
create mode 100644 src/Contexts/Mooc/Courses/application/CreateCourseCommandHandler.ts
diff --git a/src/Contexts/Mooc/Courses/application/CourseCreator.ts b/src/Contexts/Mooc/Courses/application/CourseCreator.ts
index 67acc99..0880cdf 100644
--- a/src/Contexts/Mooc/Courses/application/CourseCreator.ts
+++ b/src/Contexts/Mooc/Courses/application/CourseCreator.ts
@@ -6,6 +6,12 @@ import { CourseName } from '../domain/CourseName';
import { CourseDuration } from '../domain/CourseDuration';
import { EventBus } from '../../../Shared/domain/EventBus';
+type Params = {
+ courseId: CourseId;
+ courseName: CourseName;
+ courseDuration: CourseDuration;
+};
+
export class CourseCreator {
private repository: CourseRepository;
private eventBus: EventBus;
@@ -15,11 +21,11 @@ export class CourseCreator {
this.eventBus = eventBus;
}
- async run(request: CreateCourseRequest): Promise {
+ async run({ courseId, courseName, courseDuration }: Params): Promise {
const course = Course.create(
- new CourseId(request.id),
- new CourseName(request.name),
- new CourseDuration(request.duration)
+ courseId,
+ courseName,
+ courseDuration
);
await this.repository.save(course);
diff --git a/src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts b/src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts
new file mode 100644
index 0000000..199f777
--- /dev/null
+++ b/src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts
@@ -0,0 +1,20 @@
+import { Command } from '../../../Shared/domain/Command';
+
+type Params = {
+ id: string;
+ name: string;
+ duration: string;
+};
+
+export class CreateCourseCommand extends Command {
+ id: string;
+ name: string;
+ duration: string;
+
+ constructor({ id, name, duration }: Params) {
+ super();
+ this.id = id;
+ this.name = name;
+ this.duration = duration;
+ }
+}
\ No newline at end of file
diff --git a/src/Contexts/Mooc/Courses/application/CreateCourseCommandHandler.ts b/src/Contexts/Mooc/Courses/application/CreateCourseCommandHandler.ts
new file mode 100644
index 0000000..2c8c60e
--- /dev/null
+++ b/src/Contexts/Mooc/Courses/application/CreateCourseCommandHandler.ts
@@ -0,0 +1,22 @@
+import { CreateCourseCommand } from './CreateCourseCommand';
+import { CommandHandler } from '../../../Shared/domain/CommandHandler';
+import { CourseCreator } from './CourseCreator';
+import { Command } from '../../../Shared/domain/Command';
+import { CourseId } from '../../Shared/domain/Courses/CourseId';
+import { CourseName } from '../domain/CourseName';
+import { CourseDuration } from '../domain/CourseDuration';
+
+export class CreateCourseCommandHandler implements CommandHandler {
+ constructor(private courseCreator: CourseCreator) {}
+
+ subscribedTo(): Command {
+ return CreateCourseCommand;
+ }
+
+ async handle(command: CreateCourseCommand): Promise {
+ const courseId = new CourseId(command.id);
+ const courseName = new CourseName(command.name);
+ const courseDuration = new CourseDuration(command.duration);
+ await this.courseCreator.run({ courseId, courseName, courseDuration });
+ }
+}
diff --git a/src/Contexts/Shared/domain/CommandBus.ts b/src/Contexts/Shared/domain/CommandBus.ts
index 82e8096..a4aebbc 100644
--- a/src/Contexts/Shared/domain/CommandBus.ts
+++ b/src/Contexts/Shared/domain/CommandBus.ts
@@ -1,5 +1,5 @@
import { Command } from './Command';
export interface CommandBus {
- dispatch(command: Command): void;
+ dispatch(command: Command): Promise;
}
\ No newline at end of file
diff --git a/src/Contexts/Shared/domain/CommandHandler.ts b/src/Contexts/Shared/domain/CommandHandler.ts
index 87d1c94..65be088 100644
--- a/src/Contexts/Shared/domain/CommandHandler.ts
+++ b/src/Contexts/Shared/domain/CommandHandler.ts
@@ -1,6 +1,6 @@
import { Command } from './Command';
export interface CommandHandler {
- subscribedTo(): T;
- handle(command: T): void;
+ subscribedTo(): Command;
+ handle(command: T): Promise;
}
diff --git a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
index 949000a..011bdb2 100644
--- a/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
+++ b/src/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.ts
@@ -5,9 +5,9 @@ import { CommandHandlersInformation } from './CommandHandlersInformation';
export class InMemoryCommandBus implements CommandBus {
constructor(private commandHandlersInformation: CommandHandlersInformation) {}
- dispatch(command: Command): void {
+ async dispatch(command: Command): Promise {
const handler = this.commandHandlersInformation.search(command);
- handler.handle(command);
+ await handler.handle(command);
}
}
diff --git a/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml b/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml
index c4abfad..8acb39e 100644
--- a/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml
@@ -7,3 +7,9 @@ services:
Mooc.courses.CourseCreator:
class: ../../../../../Contexts/Mooc/Courses/application/CourseCreator
arguments: ['@Mooc.courses.CourseRepository', '@Mooc.shared.EventBus']
+
+ Mooc.courses.CreateCourseCommandHandler:
+ class: ../../../../../Contexts/Mooc/Courses/application/CreateCourseCommandHandler
+ arguments: ['@Mooc.courses.CourseCreator']
+ tags:
+ - { name: 'commandHandler' }
\ No newline at end of file
diff --git a/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml b/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
index 62137a3..51165b3 100644
--- a/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
@@ -13,6 +13,14 @@ services:
class: ../../../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus
arguments: []
+ Mooc.shared.CommandHandlersInformation:
+ class: ../../../../../Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation
+ arguments: ['!tagged commandHandler']
+
+ Mooc.shared.CommandBus:
+ class: ../../../../../Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus
+ arguments: ['@Mooc.shared.CommandHandlersInformation']
+
Mooc.shared.EventBus.DomainEventMapping:
class: ../../../../../Contexts/Shared/infrastructure/EventBus/DomainEventMapping
arguments: ['!tagged domainEventSubscriber']
diff --git a/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml b/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
index 308a6f9..3e4dff9 100644
--- a/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
@@ -2,7 +2,7 @@ services:
Apps.mooc.controllers.CoursePutController:
class: ../../../controllers/CoursePutController
- arguments: ["@Mooc.courses.CourseCreator"]
+ arguments: ["@Mooc.shared.CommandBus"]
Apps.mooc.controllers.StatusGetController:
class: ../../../controllers/StatusGetController
diff --git a/src/apps/mooc_backend/controllers/CoursePutController.ts b/src/apps/mooc_backend/controllers/CoursePutController.ts
index 4b1724e..1863ab7 100644
--- a/src/apps/mooc_backend/controllers/CoursePutController.ts
+++ b/src/apps/mooc_backend/controllers/CoursePutController.ts
@@ -1,19 +1,21 @@
import { Request, Response } from 'express';
-import { CourseCreator } from '../../../Contexts/Mooc/Courses/application/CourseCreator';
import httpStatus from 'http-status';
import { Controller } from './Controller';
import { CourseAlreadyExists } from '../../../Contexts/Mooc/Courses/domain/CourseAlreadyExists';
+import { CommandBus } from '../../../Contexts/Shared/domain/CommandBus';
+import { CreateCourseCommand } from '../../../Contexts/Mooc/Courses/application/CreateCourseCommand';
export class CoursePutController implements Controller {
- constructor(private courseCreator: CourseCreator) {}
+ constructor(private commandBus: CommandBus) {}
async run(req: Request, res: Response) {
const id: string = req.params.id;
const name: string = req.body.name;
const duration: string = req.body.duration;
+ const createCourseCommand = new CreateCourseCommand({ id, name, duration });
try {
- await this.courseCreator.run({ id, name, duration });
+ await this.commandBus.dispatch(createCourseCommand);
} catch (error) {
if (error instanceof CourseAlreadyExists) {
res.status(httpStatus.BAD_REQUEST).send(error.message);
From ba63a67761a551282ed59e736850356b4a1043f1 Mon Sep 17 00:00:00 2001
From: Fran Ortiz
Date: Sun, 14 Jun 2020 12:29:00 +0200
Subject: [PATCH 08/48] Makefile: Add support to start backoffice frontend
application
---
Makefile | 14 ++++++++++----
docker-compose.yml | 29 +++++++++++++++++++++--------
package.json | 2 +-
3 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/Makefile b/Makefile
index 23f0fa4..d8c05ad 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
-.PHONY = default deps build test start clean start-database
+.PHONY = default deps build test start-mooc-backend clean start-database start-backoffice-frontend
IMAGE_NAME := codelytv/typescript-ddd-skeleton
SERVICE_NAME := app
+MOOC_APP_NAME := mooc
+BACKOFFICE_APP_NAME := backoffice
# Test if the dependencies we need to run this Makefile are installed
DOCKER := $(shell command -v docker)
@@ -26,9 +28,13 @@ build:
test: build
docker-compose run --rm $(SERVICE_NAME) bash -c 'npm run build && npm run test'
-# Start the application
-start: build
- docker-compose up $(SERVICE_NAME) && docker-compose down
+# Start mooc backend app
+start-mooc-backend: build
+ docker-compose up $(MOOC_APP_NAME)-backend && docker-compose down
+
+# Start backoffice frontend app
+start-backoffice-frontend: build
+ docker-compose up $(BACKOFFICE_APP_NAME)-frontend && docker-compose down
# Clean containers
clean:
diff --git a/docker-compose.yml b/docker-compose.yml
index f23e67e..11634f0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,18 +1,31 @@
version: '3.8'
+x-app-service: &default-app
+ build: .
+ command: ''
+ environment:
+ - MONGO_URL=mongodb://mongo:27017/dev
+ depends_on:
+ - mongo
+ volumes:
+ - .:/code
+ - node_modules:/code/node_modules
+
services:
app:
- build: .
+ <<: *default-app
+
+ mooc-backend:
+ <<: *default-app
command: bash -c "npm run build && npm run start"
ports:
- 3000:3000
- environment:
- - MONGO_URL=mongodb://mongo:27017/dev
- depends_on:
- - mongo
- volumes:
- - .:/code
- - node_modules:/code/node_modules
+
+ backoffice-frontend:
+ <<: *default-app
+ command: bash -c "npm run build && npm run start:backoffice:frontend"
+ ports:
+ - 8032:8032
mongo:
image: mongo:3.4.6
diff --git a/package.json b/package.json
index b897276..f6edd9e 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,7 @@
"start:backoffice:frontend": "NODE_ENV=production node dist/src/apps/backoffice/frontend/server",
"build": "npm run build:clean && npm run build:tsc && npm run build:di",
"build:tsc": "tsc -p tsconfig.prod.json",
- "build:di": "copy 'src/**/*.{json,yaml}' dist/src",
+ "build:di": "copy 'src/**/*.{json,yaml,html,png}' dist/src",
"build:clean": "rm -r dist; exit 0"
},
"dependencies": {
From 2543df4202d570d3edadf907d601ed2873de8912 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1n=20Portillo?=
Date: Thu, 18 Jun 2020 17:26:56 +0200
Subject: [PATCH 09/48] Refactor CourseCreator test to use command handler
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: aliondev
Co-authored-by: Rubén Salado
---
.../Courses/application/CourseCreator.test.ts | 16 ++++++++--------
.../application/CreateCourseCommandMother.ts | 14 ++++++++++++++
.../application/CreateCourseRequestMother.ts | 17 -----------------
.../Contexts/Mooc/Courses/domain/Course.test.ts | 12 ++++++------
.../Mooc/Courses/domain/CourseMother.ts | 9 +++++----
5 files changed, 33 insertions(+), 35 deletions(-)
create mode 100644 tests/Contexts/Mooc/Courses/application/CreateCourseCommandMother.ts
delete mode 100644 tests/Contexts/Mooc/Courses/application/CreateCourseRequestMother.ts
diff --git a/tests/Contexts/Mooc/Courses/application/CourseCreator.test.ts b/tests/Contexts/Mooc/Courses/application/CourseCreator.test.ts
index 3609c2c..a406009 100644
--- a/tests/Contexts/Mooc/Courses/application/CourseCreator.test.ts
+++ b/tests/Contexts/Mooc/Courses/application/CourseCreator.test.ts
@@ -1,25 +1,25 @@
import { CourseCreator } from '../../../../../src/Contexts/Mooc/Courses/application/CourseCreator';
import { CourseMother } from '../domain/CourseMother';
import { CourseRepositoryMock } from '../__mocks__/CourseRepositoryMock';
-import { CreateCourseRequestMother } from './CreateCourseRequestMother';
+import { CreateCourseCommandMother } from './CreateCourseCommandMother';
import EventBusMock from '../__mocks__/EventBusMock';
+import { CreateCourseCommandHandler } from '../../../../../src/Contexts/Mooc/Courses/application/CreateCourseCommandHandler';
let repository: CourseRepositoryMock;
-let creator: CourseCreator;
+let handler: CreateCourseCommandHandler;
const eventBus = new EventBusMock();
beforeEach(() => {
repository = new CourseRepositoryMock();
- creator = new CourseCreator(repository, eventBus);
+ const creator = new CourseCreator(repository, eventBus);
+ handler = new CreateCourseCommandHandler(creator);
});
it('should create a valid course', async () => {
- const request = CreateCourseRequestMother.random();
-
- const course = CourseMother.fromRequest(request);
-
- await creator.run(request);
+ const command = CreateCourseCommandMother.random();
+ await handler.handle(command);
+ const course = CourseMother.fromCommand(command);
repository.assertLastSavedCourseIs(course);
});
diff --git a/tests/Contexts/Mooc/Courses/application/CreateCourseCommandMother.ts b/tests/Contexts/Mooc/Courses/application/CreateCourseCommandMother.ts
new file mode 100644
index 0000000..02b796d
--- /dev/null
+++ b/tests/Contexts/Mooc/Courses/application/CreateCourseCommandMother.ts
@@ -0,0 +1,14 @@
+import { CourseDurationMother } from '../domain/CourseDurationMother';
+import { CourseIdMother } from '../../Shared/domain/Courses/CourseIdMother';
+import { CourseNameMother } from '../domain/CourseNameMother';
+import { CreateCourseCommand } from '../../../../../src/Contexts/Mooc/Courses/application/CreateCourseCommand';
+
+export class CreateCourseCommandMother {
+ static create(id: string, name: string, duration: string): CreateCourseCommand {
+ return new CreateCourseCommand({ id, name, duration });
+ }
+
+ static random(): CreateCourseCommand {
+ return this.create(CourseIdMother.random().value, CourseNameMother.random().value, CourseDurationMother.random().value);
+ }
+}
diff --git a/tests/Contexts/Mooc/Courses/application/CreateCourseRequestMother.ts b/tests/Contexts/Mooc/Courses/application/CreateCourseRequestMother.ts
deleted file mode 100644
index d780d22..0000000
--- a/tests/Contexts/Mooc/Courses/application/CreateCourseRequestMother.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { CreateCourseRequest } from '../../../../../src/Contexts/Mooc/Courses/application/CreateCourseRequest';
-import { CourseDuration } from '../../../../../src/Contexts/Mooc/Courses/domain/CourseDuration';
-import { CourseId } from '../../../../../src/Contexts/Mooc/Shared/domain/Courses/CourseId';
-import { CourseName } from '../../../../../src/Contexts/Mooc/Courses/domain/CourseName';
-import { CourseDurationMother } from '../domain/CourseDurationMother';
-import { CourseIdMother } from '../../Shared/domain/Courses/CourseIdMother';
-import { CourseNameMother } from '../domain/CourseNameMother';
-
-export class CreateCourseRequestMother {
- static create(id: CourseId, name: CourseName, duration: CourseDuration): CreateCourseRequest {
- return { id: id.value, name: name.value, duration: duration.value };
- }
-
- static random(): CreateCourseRequest {
- return this.create(CourseIdMother.random(), CourseNameMother.random(), CourseDurationMother.random());
- }
-}
diff --git a/tests/Contexts/Mooc/Courses/domain/Course.test.ts b/tests/Contexts/Mooc/Courses/domain/Course.test.ts
index f6f65fd..cdd67c1 100644
--- a/tests/Contexts/Mooc/Courses/domain/Course.test.ts
+++ b/tests/Contexts/Mooc/Courses/domain/Course.test.ts
@@ -1,4 +1,4 @@
-import { CreateCourseRequestMother } from '../application/CreateCourseRequestMother';
+import { CreateCourseCommandMother } from '../application/CreateCourseCommandMother';
import { CourseMother } from './CourseMother';
import { Course } from '../../../../../src/Contexts/Mooc/Courses/domain/Course';
import { CourseIdMother } from '../../Shared/domain/Courses/CourseIdMother';
@@ -8,13 +8,13 @@ import { CourseDurationMother } from './CourseDurationMother';
describe('Course', () => {
it('should return a new course instance', () => {
- const request = CreateCourseRequestMother.random();
+ const command = CreateCourseCommandMother.random();
- const course = CourseMother.fromRequest(request);
+ const course = CourseMother.fromCommand(command);
- expect(course.id.value).toBe(request.id);
- expect(course.name.value).toBe(request.name);
- expect(course.duration.value).toBe(request.duration);
+ expect(course.id.value).toBe(command.id);
+ expect(course.name.value).toBe(command.name);
+ expect(course.duration.value).toBe(command.duration);
});
it('should record a CourseCreatedDomainEvent after its creation', () => {
diff --git a/tests/Contexts/Mooc/Courses/domain/CourseMother.ts b/tests/Contexts/Mooc/Courses/domain/CourseMother.ts
index 5d53285..4c388be 100644
--- a/tests/Contexts/Mooc/Courses/domain/CourseMother.ts
+++ b/tests/Contexts/Mooc/Courses/domain/CourseMother.ts
@@ -6,17 +6,18 @@ import { CreateCourseRequest } from '../../../../../src/Contexts/Mooc/Courses/ap
import { CourseIdMother } from '../../Shared/domain/Courses/CourseIdMother';
import { CourseNameMother } from './CourseNameMother';
import { CourseDurationMother } from './CourseDurationMother';
+import { CreateCourseCommand } from '../../../../../src/Contexts/Mooc/Courses/application/CreateCourseCommand';
export class CourseMother {
static create(id: CourseId, name: CourseName, duration: CourseDuration): Course {
return new Course(id, name, duration);
}
- static fromRequest(request: CreateCourseRequest): Course {
+ static fromCommand(command: CreateCourseCommand): Course {
return this.create(
- CourseIdMother.create(request.id),
- CourseNameMother.create(request.name),
- CourseDurationMother.create(request.duration)
+ CourseIdMother.create(command.id),
+ CourseNameMother.create(command.name),
+ CourseDurationMother.create(command.duration)
);
}
From 3ad53bc9ee22cff6bfbcce52b5351c2b5df89e25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1n=20Portillo?=
Date: Thu, 18 Jun 2020 17:36:58 +0200
Subject: [PATCH 10/48] Fix InMemoryCommandBus test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: aliondev
Co-authored-by: Rubén Salado
---
.../CommandBus/InMemoryCommandBus.test.ts | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
index 1de8598..141bfa3 100644
--- a/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
+++ b/tests/Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus.test.ts
@@ -17,33 +17,33 @@ class MyCommandHandler implements CommandHandler {
return HandledCommand;
}
- handle(command: HandledCommand): void {}
+ async handle(command: HandledCommand): Promise {}
}
describe('InMemoryCommandBus', () => {
- it('throws an error if dispatches a command without handler', done => {
+ it('throws an error if dispatches a command without handler', async () => {
const unhandledCommand = new UnhandledCommand();
const commandHandlersInformation = new CommandHandlersInformation([]);
const commandBus = new InMemoryCommandBus(commandHandlersInformation);
+ let exception = null;
+
try {
- commandBus.dispatch(unhandledCommand);
+ await commandBus.dispatch(unhandledCommand);
} catch (error) {
- expect(error).toBeInstanceOf(CommandNotRegisteredError);
- expect(error.message).toBe(`The command hasn't a command handler associated`);
- done();
+ exception = error;
}
+
+ expect(exception).toBeInstanceOf(CommandNotRegisteredError);
+ expect(exception.message).toBe(`The command hasn't a command handler associated`);
});
- it('accepts a command with handler', done => {
+ it('accepts a command with handler', async () => {
const handledCommand = new HandledCommand();
const myCommandHandler = new MyCommandHandler();
const commandHandlersInformation = new CommandHandlersInformation([myCommandHandler]);
const commandBus = new InMemoryCommandBus(commandHandlersInformation);
- try {
- commandBus.dispatch(handledCommand);
- done();
- } catch (error) {}
+ await commandBus.dispatch(handledCommand);
});
});
From a69946dbf1d96990cb6f3724fdf5afc662118f72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1n=20Portillo?=
Date: Thu, 18 Jun 2020 18:26:46 +0200
Subject: [PATCH 11/48] Add query bus (WIP)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: aliondev
Co-authored-by: Rubén Salado
---
src/Contexts/Shared/domain/Query.ts | 1 +
src/Contexts/Shared/domain/QueryBus.ts | 5 ++
src/Contexts/Shared/domain/QueryHandler.ts | 7 +++
.../Shared/domain/QueryNotRegisteredError.ts | 7 +++
src/Contexts/Shared/domain/Response.ts | 1 +
.../QueryBus/QueryHandlersInformation.ts | 32 ++++++++++++
.../CoursesCounterGetController.ts | 3 ++
.../QueryBus/InMemoryQueryBus.test.ts | 49 +++++++++++++++++++
8 files changed, 105 insertions(+)
create mode 100644 src/Contexts/Shared/domain/Query.ts
create mode 100644 src/Contexts/Shared/domain/QueryBus.ts
create mode 100644 src/Contexts/Shared/domain/QueryHandler.ts
create mode 100644 src/Contexts/Shared/domain/QueryNotRegisteredError.ts
create mode 100644 src/Contexts/Shared/domain/Response.ts
create mode 100644 src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts
create mode 100644 tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts
diff --git a/src/Contexts/Shared/domain/Query.ts b/src/Contexts/Shared/domain/Query.ts
new file mode 100644
index 0000000..1acca03
--- /dev/null
+++ b/src/Contexts/Shared/domain/Query.ts
@@ -0,0 +1 @@
+export abstract class Query {}
diff --git a/src/Contexts/Shared/domain/QueryBus.ts b/src/Contexts/Shared/domain/QueryBus.ts
new file mode 100644
index 0000000..54b7b57
--- /dev/null
+++ b/src/Contexts/Shared/domain/QueryBus.ts
@@ -0,0 +1,5 @@
+import { Query } from './Query';
+
+export interface QueryBus {
+ ask(query: Query): Promise;
+}
\ No newline at end of file
diff --git a/src/Contexts/Shared/domain/QueryHandler.ts b/src/Contexts/Shared/domain/QueryHandler.ts
new file mode 100644
index 0000000..49574f8
--- /dev/null
+++ b/src/Contexts/Shared/domain/QueryHandler.ts
@@ -0,0 +1,7 @@
+import { Query } from './Query';
+import { Response } from './Response';
+
+export interface QueryHandler {
+ subscribedTo(): Query;
+ handle(query: T): Promise;
+}
diff --git a/src/Contexts/Shared/domain/QueryNotRegisteredError.ts b/src/Contexts/Shared/domain/QueryNotRegisteredError.ts
new file mode 100644
index 0000000..aa26fc4
--- /dev/null
+++ b/src/Contexts/Shared/domain/QueryNotRegisteredError.ts
@@ -0,0 +1,7 @@
+import { Query } from './Query';
+
+export class QueryNotRegisteredError extends Error {
+ constructor(query: Query) {
+ super(`The query <${query.constructor.name}> hasn't a query handler associated`);
+ }
+}
diff --git a/src/Contexts/Shared/domain/Response.ts b/src/Contexts/Shared/domain/Response.ts
new file mode 100644
index 0000000..c1db157
--- /dev/null
+++ b/src/Contexts/Shared/domain/Response.ts
@@ -0,0 +1 @@
+export interface Response {}
\ No newline at end of file
diff --git a/src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts b/src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts
new file mode 100644
index 0000000..e751eca
--- /dev/null
+++ b/src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts
@@ -0,0 +1,32 @@
+import { Query } from '../../domain/Query';
+import { QueryHandler } from '../../domain/QueryHandler';
+import { Response } from '../../domain/Response';
+import { QueryNotRegisteredError } from '../../domain/QueryNotRegisteredError';
+
+export class QueryHandlersInformation {
+ private queryHandlersMap: Map>;
+
+ constructor(queryHandlers: Array>) {
+ this.queryHandlersMap = this.formatHandlers(queryHandlers);
+ }
+
+ private formatHandlers(queryHandlers: Array>): Map> {
+ const handlersMap = new Map();
+
+ queryHandlers.forEach(queryHandler => {
+ handlersMap.set(queryHandler.subscribedTo(), queryHandler);
+ });
+
+ return handlersMap;
+ }
+
+ public search(query: Query): QueryHandler {
+ const queryHandler = this.queryHandlersMap.get(query.constructor);
+
+ if (!queryHandler) {
+ throw new QueryNotRegisteredError(query);
+ }
+
+ return queryHandler;
+ }
+}
diff --git a/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts b/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts
index 088faeb..175364b 100644
--- a/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts
+++ b/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts
@@ -8,6 +8,9 @@ export class CoursesCounterGetController implements Controller {
constructor(private coursesCounterFinder: CoursesCounterFinder) {}
async run(req: Request, res: Response): Promise {
try {
+ const query = new FindCourseCounterQuery();
+ const count = await this.queryBus.query(query);
+
const counter = await this.coursesCounterFinder.run();
res.status(httpStatus.OK).send(counter);
} catch (e) {
diff --git a/tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts b/tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts
new file mode 100644
index 0000000..eb96306
--- /dev/null
+++ b/tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts
@@ -0,0 +1,49 @@
+import { Query } from '../../../../../src/Contexts/Shared/domain/Query';
+import { QueryHandlersInformation } from '../../../../../src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation';
+import { QueryNotRegisteredError } from '../../../../../src/Contexts/Shared/domain/QueryNotRegisteredError';
+import { QueryHandler } from '../../../../../src/Contexts/Shared/domain/QueryHandler';
+import { Response } from '../../../../../src/Contexts/Shared/domain/Response';
+
+class UnhandledQuery extends Query {
+ static QUERY_NAME = 'unhandled.query';
+}
+
+class HandledQuery extends Query {
+ static QUERY_NAME = 'handled.query';
+}
+
+class MyQueryHandler implements QueryHandler {
+ subscribedTo(): HandledQuery {
+ return HandledQuery;
+ }
+
+ async handle(query: HandledQuery): Promise {return {};}
+}
+
+describe('InMemoryQueryBus', () => {
+ it('throws an error if dispatches a query without handler', async () => {
+ const unhandledQuery = new UnhandledQuery();
+ const queryHandlersInformation = new QueryHandlersInformation([]);
+ const queryBus = new InMemoryQueryBus(queryHandlersInformation);
+
+ let exception = null;
+
+ try {
+ await queryBus.ask(unhandledQuery);
+ } catch (error) {
+ exception = error;
+ }
+
+ expect(exception).toBeInstanceOf(QueryNotRegisteredError);
+ expect(exception.message).toBe(`The query hasn't a query handler associated`);
+ });
+
+ it('accepts a query with handler', async () => {
+ const handledQuery = new HandledQuery();
+ const myQueryHandler = new MyQueryHandler();
+ const queryHandlersInformation = new QueryHandlersInformation([myQueryHandler]);
+ const queryBus = new InMemoryQueryBus(queryHandlersInformation);
+
+ await queryBus.ask(handledQuery);
+ });
+});
From 420be6e73190e1a20a0934cef1a1fa7fe22a4f92 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 19 Jun 2020 18:06:07 +0200
Subject: [PATCH 12/48] Added courses template
Co-authored-by: Francisco Ortiz
---
package.json | 2 +-
.../controllers/CoursesGetController.ts | 17 +++++++++++++++++
.../backoffice/frontend/routes/courses.route.ts | 8 ++++++++
.../frontend/templates/pages/courses.html | 17 +++++++++++++++++
src/apps/mooc_backend/config/dev.json | 1 +
5 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 src/apps/backoffice/frontend/controllers/CoursesGetController.ts
create mode 100644 src/apps/backoffice/frontend/routes/courses.route.ts
create mode 100644 src/apps/backoffice/frontend/templates/pages/courses.html
create mode 100644 src/apps/mooc_backend/config/dev.json
diff --git a/package.json b/package.json
index f6edd9e..4547d92 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
},
"scripts": {
"dev": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules --inspect=0.0.0.0:9267 ./src/apps/mooc_backend/server.ts",
- "dev:backoffice:frontend": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules --inspect=0.0.0.0:9267 ./src/apps/backoffice/frontend/server.ts",
+ "dev:backoffice:frontend": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules ./src/apps/backoffice/frontend/server.ts",
"test": "npm run test:unit && npm run test:features",
"test:unit": "NODE_ENV=test jest",
"test:features": "NODE_ENV=test cucumber-js -p default",
diff --git a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
new file mode 100644
index 0000000..60d20e1
--- /dev/null
+++ b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
@@ -0,0 +1,17 @@
+import { Request, Response } from 'express';
+import { CoursesCounterFinder } from '../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder';
+
+export class CoursesGetController {
+ constructor(private coursesCounterFinder: CoursesCounterFinder) {}
+
+ async run(req: Request, res: Response) {
+ // const courses = await this.coursesCounterFinder.run();
+
+ res.render('pages/courses', {
+ title: 'Welcome',
+ description: 'CodelyTV - Backoffice',
+ courses_counter: 0,
+ new_course_id: 'xxxx'
+ });
+ }
+}
diff --git a/src/apps/backoffice/frontend/routes/courses.route.ts b/src/apps/backoffice/frontend/routes/courses.route.ts
new file mode 100644
index 0000000..23f7303
--- /dev/null
+++ b/src/apps/backoffice/frontend/routes/courses.route.ts
@@ -0,0 +1,8 @@
+import { Express } from 'express';
+import container from '../config/dependency-injection';
+import { CoursesGetController } from '../controllers/CoursesGetController';
+
+export const register = (app: Express) => {
+ const controller: CoursesGetController = container.get('Apps.Backoffice.Frontend.controllers.CoursesGetController');
+ app.get('/courses', controller.run.bind(controller));
+};
diff --git a/src/apps/backoffice/frontend/templates/pages/courses.html b/src/apps/backoffice/frontend/templates/pages/courses.html
new file mode 100644
index 0000000..a96ab2f
--- /dev/null
+++ b/src/apps/backoffice/frontend/templates/pages/courses.html
@@ -0,0 +1,17 @@
+{% extends '../master.html' %}
+
+{% block page_title %}Cursos{% endblock %}
+
+{% block main %}
+
+

+
+
Cursos
+
+ Actualmente CodelyTV Pro cuenta con {{ courses_counter }} cursos.
+
+
+
+
+
+{% endblock %}
diff --git a/src/apps/mooc_backend/config/dev.json b/src/apps/mooc_backend/config/dev.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/apps/mooc_backend/config/dev.json
@@ -0,0 +1 @@
+{}
From 4d254a186668c072faae05116ca63d586d06f140 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Mon, 22 Jun 2020 16:56:58 +0200
Subject: [PATCH 13/48] WIP
---
.../config/dependency-injection/application.yaml | 7 +++++++
.../frontend/controllers/CoursesGetController.ts | 10 ++++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
index 22d0a1d..425cffa 100644
--- a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
@@ -1,3 +1,6 @@
+// TODO:
+Instance CoursesCounterFinder application servicer
+
services:
Contexts.shared.Logger:
class: ../../../../../Contexts/Shared/infrastructure/WinstonLogger
@@ -5,3 +8,7 @@ services:
Apps.Backoffice.Frontend.controllers.HomeGetController:
class: ../../controllers/HomeGetController
+
+ Apps.Backoffice.Frontend.controllers.CoursesGetController:
+ class: ../../controllers/CoursesGetController
+ arguments: ['@Mooc.coursesCounter.CoursesCounterFinder']
diff --git a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
index 60d20e1..8200eea 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
@@ -5,12 +5,18 @@ export class CoursesGetController {
constructor(private coursesCounterFinder: CoursesCounterFinder) {}
async run(req: Request, res: Response) {
- // const courses = await this.coursesCounterFinder.run();
+ let coursesNumber;
+ try {
+ const courses = await this.coursesCounterFinder.run();
+ coursesNumber = courses.total;
+ } catch (error) {
+ coursesNumber = 0;
+ }
res.render('pages/courses', {
title: 'Welcome',
description: 'CodelyTV - Backoffice',
- courses_counter: 0,
+ courses_counter: coursesNumber,
new_course_id: 'xxxx'
});
}
From 69f44d604f5d6cfdfb69ad9582689783b924d28c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1n=20Portillo?=
Date: Wed, 24 Jun 2020 17:22:23 +0200
Subject: [PATCH 14/48] Implement InMemoryQueryBus
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Rubén Salado
Co-authored-by: aliondev
---
src/Contexts/Shared/domain/QueryBus.ts | 3 ++-
src/Contexts/Shared/domain/QueryHandler.ts | 4 ++--
.../infrastructure/QueryBus/InMemoryQueryBus.ts | 14 ++++++++++++++
.../QueryBus/InMemoryQueryBus.test.ts | 3 ++-
4 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 src/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.ts
diff --git a/src/Contexts/Shared/domain/QueryBus.ts b/src/Contexts/Shared/domain/QueryBus.ts
index 54b7b57..2a04f03 100644
--- a/src/Contexts/Shared/domain/QueryBus.ts
+++ b/src/Contexts/Shared/domain/QueryBus.ts
@@ -1,5 +1,6 @@
import { Query } from './Query';
+import { Response } from './Response';
export interface QueryBus {
- ask(query: Query): Promise;
+ ask(query: Query): Promise;
}
\ No newline at end of file
diff --git a/src/Contexts/Shared/domain/QueryHandler.ts b/src/Contexts/Shared/domain/QueryHandler.ts
index 49574f8..a988d70 100644
--- a/src/Contexts/Shared/domain/QueryHandler.ts
+++ b/src/Contexts/Shared/domain/QueryHandler.ts
@@ -1,7 +1,7 @@
import { Query } from './Query';
import { Response } from './Response';
-export interface QueryHandler {
+export interface QueryHandler {
subscribedTo(): Query;
- handle(query: T): Promise;
+ handle(query: Q): Promise;
}
diff --git a/src/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.ts b/src/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.ts
new file mode 100644
index 0000000..ad7cbe6
--- /dev/null
+++ b/src/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.ts
@@ -0,0 +1,14 @@
+import { Query } from '../../domain/Query';
+import { Response } from '../../domain/Response';
+import { QueryBus } from './../../domain/QueryBus';
+import { QueryHandlersInformation } from './QueryHandlersInformation';
+
+export class InMemoryQueryBus implements QueryBus {
+ constructor(private queryHandlersInformation: QueryHandlersInformation) {}
+
+ async ask(query: Query): Promise {
+ const handler = this.queryHandlersInformation.search(query);
+
+ return handler.handle(query) as Promise;
+ }
+}
diff --git a/tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts b/tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts
index eb96306..829e1c5 100644
--- a/tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts
+++ b/tests/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus.test.ts
@@ -3,6 +3,7 @@ import { QueryHandlersInformation } from '../../../../../src/Contexts/Shared/inf
import { QueryNotRegisteredError } from '../../../../../src/Contexts/Shared/domain/QueryNotRegisteredError';
import { QueryHandler } from '../../../../../src/Contexts/Shared/domain/QueryHandler';
import { Response } from '../../../../../src/Contexts/Shared/domain/Response';
+import { InMemoryQueryBus } from '../../../../../src/Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus';
class UnhandledQuery extends Query {
static QUERY_NAME = 'unhandled.query';
@@ -35,7 +36,7 @@ describe('InMemoryQueryBus', () => {
}
expect(exception).toBeInstanceOf(QueryNotRegisteredError);
- expect(exception.message).toBe(`The query hasn't a query handler associated`);
+ expect(exception.message).toBe(`The query hasn't a query handler associated`);
});
it('accepts a query with handler', async () => {
From d6b7729e96f7ef64681101151e794f38913ed9d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1n=20Portillo?=
Date: Wed, 24 Jun 2020 17:54:52 +0200
Subject: [PATCH 15/48] Refactor FindCourseCounter to use query bus
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Rubén Salado
Co-authored-by: aliondev
---
.../application/Find/CoursesCounterFinder.ts | 4 +--
.../Find/FindCoursesCounterQuery.ts | 3 +++
.../Find/FindCoursesCounterQueryHandler.ts | 17 +++++++++++++
...ponse.ts => FindCoursesCounterResponse.ts} | 2 +-
.../CoursesCounter/application.yaml | 7 +++++-
.../Shared/application.yaml | 8 ++++++
.../apps/application.yaml | 2 +-
.../CoursesCounterGetController.ts | 13 +++++-----
.../__mocks__/CoursesCounterRepositoryMock.ts | 1 -
... => FindCourseCounterQueryHandler.test.ts} | 25 +++++++++++++------
.../domain/CoursesCounterResponseMother.ts | 4 +--
11 files changed, 64 insertions(+), 22 deletions(-)
create mode 100644 src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts
create mode 100644 src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts
rename src/Contexts/Mooc/CoursesCounter/application/Find/{CoursesCounterResponse.ts => FindCoursesCounterResponse.ts} (67%)
rename tests/Contexts/Mooc/CoursesCounter/application/Find/{CoursesCounterFinder.test.ts => FindCourseCounterQueryHandler.test.ts} (55%)
diff --git a/src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder.ts b/src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder.ts
index 6f95bcb..445fde7 100644
--- a/src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder.ts
+++ b/src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder.ts
@@ -1,6 +1,6 @@
import { CoursesCounterRepository } from '../../domain/CoursesCounterRepository';
import { CoursesCounterNotExist } from '../../domain/CoursesCounterNotExist';
-import { CoursesCounterResponse } from './CoursesCounterResponse';
+import { FindCoursesCounterResponse } from './FindCoursesCounterResponse';
export class CoursesCounterFinder {
constructor(private repository: CoursesCounterRepository) {}
@@ -11,6 +11,6 @@ export class CoursesCounterFinder {
throw new CoursesCounterNotExist();
}
- return new CoursesCounterResponse(counter.total.value);
+ return new FindCoursesCounterResponse(counter.total.value);
}
}
diff --git a/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts
new file mode 100644
index 0000000..312dd47
--- /dev/null
+++ b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts
@@ -0,0 +1,3 @@
+import { Query } from "../../../../Shared/domain/Query";
+
+export class FindCoursesCounterQuery implements Query {}
\ No newline at end of file
diff --git a/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts
new file mode 100644
index 0000000..c8e85ab
--- /dev/null
+++ b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts
@@ -0,0 +1,17 @@
+import { QueryHandler } from "../../../../Shared/domain/QueryHandler";
+import { FindCoursesCounterQuery } from "./FindCoursesCounterQuery";
+import { FindCoursesCounterResponse } from "./FindCoursesCounterResponse";
+import { Query } from "../../../../Shared/domain/Query";
+import { CoursesCounterFinder } from "./CoursesCounterFinder";
+
+export class FindCoursesCounterQueryHandler implements QueryHandler {
+ constructor(private finder: CoursesCounterFinder) {}
+
+ subscribedTo(): Query {
+ return FindCoursesCounterQuery;
+ }
+ handle(_query: FindCoursesCounterQuery): Promise {
+ return this.finder.run();
+ }
+
+}
\ No newline at end of file
diff --git a/src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterResponse.ts b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterResponse.ts
similarity index 67%
rename from src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterResponse.ts
rename to src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterResponse.ts
index af89a06..fa5bab2 100644
--- a/src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterResponse.ts
+++ b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterResponse.ts
@@ -1,4 +1,4 @@
-export class CoursesCounterResponse {
+export class FindCoursesCounterResponse {
readonly total: number;
constructor(total: number) {
diff --git a/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml b/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
index 8314388..493864c 100644
--- a/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
@@ -1,5 +1,4 @@
services:
-
Mooc.coursesCounter.CoursesCounterRepository:
class: ../../../../../Contexts/Mooc/CoursesCounter/infrastructure/persistence/mongo/MongoCoursesCounterRepository
arguments: ["@Mooc.shared.ConnectionManager"]
@@ -21,4 +20,10 @@ services:
class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder
arguments: ["@Mooc.coursesCounter.CoursesCounterRepository"]
+
+ Mooc.coursesCounter.FindCoursesCounterQueryHandler:
+ class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler
+ arguments: ["@Mooc.coursesCounter.CoursesCounterFinder"]
+ tags:
+ - { name: 'queryHandler' }
diff --git a/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml b/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
index 51165b3..624a233 100644
--- a/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
@@ -28,3 +28,11 @@ services:
Mooc.shared.EventBus.DomainEventJsonDeserializer:
class: ../../../../../Contexts/Shared/infrastructure/EventBus/DomainEventJsonDeserializer
arguments: ['@Mooc.shared.EventBus.DomainEventMapping']
+
+ Mooc.shared.QueryHandlersInformation:
+ class: ../../../../../Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation
+ arguments: ['!tagged queryHandler']
+
+ Mooc.shared.QueryBus:
+ class: ../../../../../Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus
+ arguments: ['@Mooc.shared.QueryHandlersInformation']
diff --git a/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml b/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
index 3e4dff9..131ee62 100644
--- a/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
@@ -10,4 +10,4 @@ services:
Apps.mooc.controllers.CoursesCounterGetController:
class: ../../../controllers/CoursesCounterGetController
- arguments: ["@Mooc.coursesCounter.CoursesCounterFinder"]
+ arguments: ["@Mooc.shared.QueryBus"]
diff --git a/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts b/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts
index 175364b..9f97752 100644
--- a/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts
+++ b/src/apps/mooc_backend/controllers/CoursesCounterGetController.ts
@@ -1,18 +1,19 @@
import { Controller } from './Controller';
import { Request, Response } from 'express';
-import { CoursesCounterFinder } from '../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder';
import httpStatus = require('http-status');
import { CoursesCounterNotExist } from '../../../Contexts/Mooc/CoursesCounter/domain/CoursesCounterNotExist';
+import { FindCoursesCounterQuery } from '../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery';
+import { QueryBus } from '../../../Contexts/Shared/domain/QueryBus';
+import { FindCoursesCounterResponse } from '../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterResponse';
export class CoursesCounterGetController implements Controller {
- constructor(private coursesCounterFinder: CoursesCounterFinder) {}
+ constructor(private queryBus: QueryBus) {}
async run(req: Request, res: Response): Promise {
try {
- const query = new FindCourseCounterQuery();
- const count = await this.queryBus.query(query);
+ const query = new FindCoursesCounterQuery();
+ const count = await this.queryBus.ask(query);
- const counter = await this.coursesCounterFinder.run();
- res.status(httpStatus.OK).send(counter);
+ res.status(httpStatus.OK).send(count);
} catch (e) {
if (e instanceof CoursesCounterNotExist) {
res.status(httpStatus.NOT_FOUND).send();
diff --git a/tests/Contexts/Mooc/CoursesCounter/__mocks__/CoursesCounterRepositoryMock.ts b/tests/Contexts/Mooc/CoursesCounter/__mocks__/CoursesCounterRepositoryMock.ts
index cd88fe5..15bf9a0 100644
--- a/tests/Contexts/Mooc/CoursesCounter/__mocks__/CoursesCounterRepositoryMock.ts
+++ b/tests/Contexts/Mooc/CoursesCounter/__mocks__/CoursesCounterRepositoryMock.ts
@@ -1,7 +1,6 @@
import { CoursesCounterRepository } from '../../../../../src/Contexts/Mooc/CoursesCounter/domain/CoursesCounterRepository';
import { CoursesCounter } from '../../../../../src/Contexts/Mooc/CoursesCounter/domain/CoursesCounter';
import { Nullable } from '../../../../../src/Contexts/Shared/domain/Nullable';
-import { CourseId } from '../../../../../src/Contexts/Mooc/Shared/domain/Courses/CourseId';
export class CoursesCounterRepositoryMock implements CoursesCounterRepository {
private mockSave = jest.fn();
diff --git a/tests/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder.test.ts b/tests/Contexts/Mooc/CoursesCounter/application/Find/FindCourseCounterQueryHandler.test.ts
similarity index 55%
rename from tests/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder.test.ts
rename to tests/Contexts/Mooc/CoursesCounter/application/Find/FindCourseCounterQueryHandler.test.ts
index a52fd9a..260fa00 100644
--- a/tests/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder.test.ts
+++ b/tests/Contexts/Mooc/CoursesCounter/application/Find/FindCourseCounterQueryHandler.test.ts
@@ -3,28 +3,37 @@ import { CoursesCounterMother } from '../../domain/CoursesCounterMother';
import { CoursesCounterRepositoryMock } from '../../__mocks__/CoursesCounterRepositoryMock';
import { CoursesCounterResponseMother } from '../../domain/CoursesCounterResponseMother';
import { CoursesCounterNotExist } from '../../../../../../src/Contexts/Mooc/CoursesCounter/domain/CoursesCounterNotExist';
+import { FindCoursesCounterQueryHandler } from '../../../../../../src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler';
+import { FindCoursesCounterQuery } from '../../../../../../src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery';
-describe('CoursesCounter Finder', () => {
- let finder: CoursesCounterFinder;
+describe('FindCourseCounter QueryHandler', () => {
let repository: CoursesCounterRepositoryMock;
beforeEach(() => {
repository = new CoursesCounterRepositoryMock();
- finder = new CoursesCounterFinder(repository);
});
+
it('should find an existing courses counter', async () => {
const counter = CoursesCounterMother.random();
- const expected = CoursesCounterResponseMother.create(counter.total);
repository.returnOnSearch(counter);
- const actual = await finder.run();
-
+ const handler = new FindCoursesCounterQueryHandler(new CoursesCounterFinder(repository));
+
+ const query = new FindCoursesCounterQuery();
+ const response = await handler.handle(query);
+
repository.assertSearch();
- expect(expected).toEqual(actual);
+
+ const expected = CoursesCounterResponseMother.create(counter.total);
+ expect(expected).toEqual(response);
});
it('should throw an exception when courses counter does not exists', async () => {
- await expect(finder.run()).rejects.toBeInstanceOf(CoursesCounterNotExist);
+ const handler = new FindCoursesCounterQueryHandler(new CoursesCounterFinder(repository));
+
+ const query = new FindCoursesCounterQuery();
+
+ await expect(handler.handle(query)).rejects.toBeInstanceOf(CoursesCounterNotExist);
});
});
diff --git a/tests/Contexts/Mooc/CoursesCounter/domain/CoursesCounterResponseMother.ts b/tests/Contexts/Mooc/CoursesCounter/domain/CoursesCounterResponseMother.ts
index d383200..677b388 100644
--- a/tests/Contexts/Mooc/CoursesCounter/domain/CoursesCounterResponseMother.ts
+++ b/tests/Contexts/Mooc/CoursesCounter/domain/CoursesCounterResponseMother.ts
@@ -1,8 +1,8 @@
import { CoursesCounterTotal } from '../../../../../src/Contexts/Mooc/CoursesCounter/domain/CoursesCounterTotal';
-import { CoursesCounterResponse } from '../../../../../src/Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterResponse';
+import { FindCoursesCounterResponse } from '../../../../../src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterResponse';
export class CoursesCounterResponseMother {
static create(total: CoursesCounterTotal) {
- return new CoursesCounterResponse(total.value);
+ return new FindCoursesCounterResponse(total.value);
}
}
From 68da68f07fad1e117a1e0672d17be439f83b5edd Mon Sep 17 00:00:00 2001
From: Fran Ortiz
Date: Fri, 3 Jul 2020 17:17:56 +0200
Subject: [PATCH 16/48] Use localhost as default mongo host
---
src/apps/mooc_backend/config/config.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/apps/mooc_backend/config/config.ts b/src/apps/mooc_backend/config/config.ts
index 11b1dba..b679f61 100644
--- a/src/apps/mooc_backend/config/config.ts
+++ b/src/apps/mooc_backend/config/config.ts
@@ -12,7 +12,7 @@ const convictConfig = convict({
doc: 'The Mongo connection URL',
format: String,
env: 'MONGO_URL',
- default: 'mongodb://mongo:27017/dev'
+ default: 'mongodb://localhost:27017/dev'
}
}
});
From b5e43ff03988adb39be9ad3e41821541e6aec049 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 3 Jul 2020 16:09:30 +0200
Subject: [PATCH 17/48] Instantitate CoursesCounterFinder for backoffice
frontend
---
src/apps/backoffice/frontend/config/config.ts | 8 ++++++++
.../dependency-injection/application.yaml | 17 ++++++++++++++---
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/src/apps/backoffice/frontend/config/config.ts b/src/apps/backoffice/frontend/config/config.ts
index 4405a32..11b1dba 100644
--- a/src/apps/backoffice/frontend/config/config.ts
+++ b/src/apps/backoffice/frontend/config/config.ts
@@ -6,6 +6,14 @@ const convictConfig = convict({
format: ['production', 'development', 'staging', 'test'],
default: 'default',
env: 'NODE_ENV'
+ },
+ mongo: {
+ url: {
+ doc: 'The Mongo connection URL',
+ format: String,
+ env: 'MONGO_URL',
+ default: 'mongodb://mongo:27017/dev'
+ }
}
});
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
index 425cffa..c43a05a 100644
--- a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
@@ -1,6 +1,3 @@
-// TODO:
-Instance CoursesCounterFinder application servicer
-
services:
Contexts.shared.Logger:
class: ../../../../../Contexts/Shared/infrastructure/WinstonLogger
@@ -9,6 +6,20 @@ services:
Apps.Backoffice.Frontend.controllers.HomeGetController:
class: ../../controllers/HomeGetController
+ Mooc.coursesCounter.CoursesCounterFinder:
+ class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder
+ arguments: ["@Mooc.coursesCounter.CoursesCounterRepository"]
+
+ Mooc.coursesCounter.CoursesCounterRepository:
+ class: ../../../../../Contexts/Mooc/CoursesCounter/infrastructure/persistence/mongo/MongoCoursesCounterRepository
+ arguments: ["@Mooc.shared.ConnectionManager"]
+
+ Mooc.shared.ConnectionManager:
+ factory:
+ class: ../../../../../Contexts/Shared/infrastructure/persistence/mongo/MongoClientFactory
+ method: 'createClient'
+ arguments: ['mooc']
+
Apps.Backoffice.Frontend.controllers.CoursesGetController:
class: ../../controllers/CoursesGetController
arguments: ['@Mooc.coursesCounter.CoursesCounterFinder']
From cbeeead263c524c01898ee4ebd9e173f9b76a3b1 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 3 Jul 2020 16:44:31 +0200
Subject: [PATCH 18/48] Delete collections after all tests
---
.../features/step_definitions/controller.steps.ts | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tests/apps/mooc_backend/features/step_definitions/controller.steps.ts b/tests/apps/mooc_backend/features/step_definitions/controller.steps.ts
index 00e2757..a70221f 100644
--- a/tests/apps/mooc_backend/features/step_definitions/controller.steps.ts
+++ b/tests/apps/mooc_backend/features/step_definitions/controller.steps.ts
@@ -13,9 +13,7 @@ Given('I send a GET request to {string}', (route: string) => {
});
Given('I send a PUT request to {string} with body:', (route: string, body: string) => {
- _request = request(app)
- .put(route)
- .send(JSON.parse(body));
+ _request = request(app).put(route).send(JSON.parse(body));
});
Then('the response status code should be {int}', async (status: number) => {
@@ -37,5 +35,6 @@ Before(async () => {
AfterAll(async () => {
const environmentArranger: Promise = container.get('Mooc.EnvironmentArranger');
+ await (await environmentArranger).arrange();
await (await environmentArranger).close();
});
From 297eb3dae9d478eb2304145decb571c9beffb5ad Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 3 Jul 2020 16:51:58 +0200
Subject: [PATCH 19/48] Eliminate 0 case from controller
---
.../frontend/controllers/CoursesGetController.ts | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
index 8200eea..60332ba 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
@@ -5,18 +5,12 @@ export class CoursesGetController {
constructor(private coursesCounterFinder: CoursesCounterFinder) {}
async run(req: Request, res: Response) {
- let coursesNumber;
- try {
- const courses = await this.coursesCounterFinder.run();
- coursesNumber = courses.total;
- } catch (error) {
- coursesNumber = 0;
- }
+ const courses = await this.coursesCounterFinder.run();
res.render('pages/courses', {
title: 'Welcome',
description: 'CodelyTV - Backoffice',
- courses_counter: coursesNumber,
+ courses_counter: courses.total,
new_course_id: 'xxxx'
});
}
From c4d63edcb61f1cf9d24c3f29668c9006bedfd009 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Sun, 5 Jul 2020 08:52:44 +0200
Subject: [PATCH 20/48] Add courses folder in pages
---
.../backoffice/frontend/controllers/CoursesGetController.ts | 2 +-
.../frontend/templates/pages/{ => courses}/courses.html | 3 ++-
.../templates/pages/courses/partials/new_course_form.html | 1 +
src/apps/backoffice/frontend/templates/pages/home.html | 2 +-
4 files changed, 5 insertions(+), 3 deletions(-)
rename src/apps/backoffice/frontend/templates/pages/{ => courses}/courses.html (86%)
create mode 100644 src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
diff --git a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
index 60332ba..953da5a 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
@@ -7,7 +7,7 @@ export class CoursesGetController {
async run(req: Request, res: Response) {
const courses = await this.coursesCounterFinder.run();
- res.render('pages/courses', {
+ res.render('pages/courses/courses', {
title: 'Welcome',
description: 'CodelyTV - Backoffice',
courses_counter: courses.total,
diff --git a/src/apps/backoffice/frontend/templates/pages/courses.html b/src/apps/backoffice/frontend/templates/pages/courses/courses.html
similarity index 86%
rename from src/apps/backoffice/frontend/templates/pages/courses.html
rename to src/apps/backoffice/frontend/templates/pages/courses/courses.html
index a96ab2f..b954147 100644
--- a/src/apps/backoffice/frontend/templates/pages/courses.html
+++ b/src/apps/backoffice/frontend/templates/pages/courses/courses.html
@@ -1,4 +1,4 @@
-{% extends '../master.html' %}
+{% extends 'master.html' %}
{% block page_title %}Cursos{% endblock %}
@@ -12,6 +12,7 @@
+ {% include 'pages/courses/partials/new_course_form.html' %}
{% endblock %}
diff --git a/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html b/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
@@ -0,0 +1 @@
+hello
diff --git a/src/apps/backoffice/frontend/templates/pages/home.html b/src/apps/backoffice/frontend/templates/pages/home.html
index 30a2e95..aad6614 100644
--- a/src/apps/backoffice/frontend/templates/pages/home.html
+++ b/src/apps/backoffice/frontend/templates/pages/home.html
@@ -1,4 +1,4 @@
-{% extends '../master.html' %}
+{% extends 'master.html' %}
{% block page_title %}HOME{% endblock %}
From 17f757f6f5806445e17c75c0f8eedfb508efacaf Mon Sep 17 00:00:00 2001
From: David Matas
Date: Sun, 5 Jul 2020 21:42:34 +0200
Subject: [PATCH 21/48] Add create course form
---
package-lock.json | 91 ++++++++++++++++++-
package.json | 8 +-
src/apps/backoffice/frontend/app.ts | 15 +++
.../dependency-injection/application.yaml | 16 ++++
.../controllers/CoursesGetController.ts | 4 +-
.../controllers/CoursesPostController.ts | 20 ++++
.../frontend/routes/courses.route.ts | 12 ++-
.../courses/partials/new_course_form.html | 49 +++++++++-
8 files changed, 209 insertions(+), 6 deletions(-)
create mode 100644 src/apps/backoffice/frontend/controllers/CoursesPostController.ts
diff --git a/package-lock.json b/package-lock.json
index d7aa252..496e635 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -901,6 +901,15 @@
"@types/node": "*"
}
},
+ "@types/connect-flash": {
+ "version": "0.0.35",
+ "resolved": "https://registry.npmjs.org/@types/connect-flash/-/connect-flash-0.0.35.tgz",
+ "integrity": "sha512-pwEiJI1gYhH+s6x4+st/TBgf1CPuATADPJi1+2It4Gnckw1pVVdKycRNDyoHwkZGCb/J38vEdOrxnZ4FsOlvWg==",
+ "dev": true,
+ "requires": {
+ "@types/express": "*"
+ }
+ },
"@types/convict": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/@types/convict/-/convict-5.2.1.tgz",
@@ -909,6 +918,25 @@
"@types/node": "*"
}
},
+ "@types/cookie-parser": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.2.tgz",
+ "integrity": "sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==",
+ "dev": true,
+ "requires": {
+ "@types/express": "*"
+ }
+ },
+ "@types/cookie-session": {
+ "version": "2.0.41",
+ "resolved": "https://registry.npmjs.org/@types/cookie-session/-/cookie-session-2.0.41.tgz",
+ "integrity": "sha512-Ytd7zWY3WvC7TP9rKVjlnYHus8Hq+lJuioHOtKJ7dXg2Nt+O+9UpelygYy5Eb67QQN92HPO5qEG0vnmAlqRLLw==",
+ "dev": true,
+ "requires": {
+ "@types/express": "*",
+ "@types/keygrip": "*"
+ }
+ },
"@types/cookiejar": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.1.tgz",
@@ -1023,6 +1051,12 @@
"pretty-format": "^25.2.1"
}
},
+ "@types/keygrip": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
+ "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
+ "dev": true
+ },
"@types/mime": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.2.tgz",
@@ -1828,12 +1862,14 @@
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "optional": true
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "optional": true,
"requires": {
"is-extglob": "^2.1.1"
}
@@ -2126,6 +2162,11 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
+ "connect-flash": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz",
+ "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA="
+ },
"console.table": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz",
@@ -2175,6 +2216,25 @@
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
},
+ "cookie-parser": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
+ "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
+ "requires": {
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6"
+ }
+ },
+ "cookie-session": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-1.4.0.tgz",
+ "integrity": "sha512-0hhwD+BUIwMXQraiZP/J7VP2YFzqo6g4WqZlWHtEHQ22t0MeZZrNBSCxC1zcaLAs8ApT3BzAKizx9gW/AP9vNA==",
+ "requires": {
+ "cookies": "0.8.0",
+ "debug": "2.6.9",
+ "on-headers": "~1.0.2"
+ }
+ },
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
@@ -2186,6 +2246,22 @@
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
"dev": true
},
+ "cookies": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
+ "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==",
+ "requires": {
+ "depd": "~2.0.0",
+ "keygrip": "~1.1.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ }
+ }
+ },
"copy": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/copy/-/copy-0.3.2.tgz",
@@ -5043,6 +5119,14 @@
}
}
},
+ "keygrip": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
+ "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
+ "requires": {
+ "tsscmp": "1.0.6"
+ }
+ },
"kind-of": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
@@ -8180,6 +8264,11 @@
}
}
},
+ "tsscmp": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
+ "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA=="
+ },
"tsutils": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
diff --git a/package.json b/package.json
index 4547d92..3391bc7 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,10 @@
"body-parser": "^1.19.0",
"bson": "^4.0.4",
"compression": "^1.7.4",
+ "connect-flash": "^0.1.1",
"convict": "^6.0.0",
+ "cookie-parser": "^1.4.5",
+ "cookie-session": "^1.4.0",
"copy": "^0.3.2",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
@@ -56,11 +59,14 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@types/nunjucks": "^3.1.3",
"@types/aws-lambda": "^8.10.51",
+ "@types/connect-flash": "0.0.35",
+ "@types/cookie-parser": "^1.4.2",
+ "@types/cookie-session": "^2.0.41",
"@types/cucumber": "^6.0.1",
"@types/faker": "^4.1.12",
"@types/jest": "^25.2.3",
+ "@types/nunjucks": "^3.1.3",
"@types/supertest": "^2.0.9",
"cucumber": "^6.0.5",
"faker": "^4.1.0",
diff --git a/src/apps/backoffice/frontend/app.ts b/src/apps/backoffice/frontend/app.ts
index 1fb376c..e306c85 100644
--- a/src/apps/backoffice/frontend/app.ts
+++ b/src/apps/backoffice/frontend/app.ts
@@ -4,12 +4,27 @@ import helmet from 'helmet';
import compress from 'compression';
import { registerRoutes } from './routes';
import path from 'path';
+import cookieSession from 'cookie-session';
+import cookieParser from 'cookie-parser';
+import flash from 'connect-flash';
import nunjucks from 'nunjucks';
const app: express.Express = express();
app.set('port', process.env.PORT || 8032);
+app.use(cookieParser());
+app.use(
+ cookieSession({
+ name: 'Backoffice Frontend Codely session',
+ keys: ['Codely'],
+
+ // Cookie Options
+ maxAge: 24 * 60 * 60 * 1000 // 24 hours
+ })
+);
+app.use(flash());
+
// Templates
app.set('view engine', 'html');
nunjucks.configure(path.join(__dirname, '/templates'), {
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
index c43a05a..510476e 100644
--- a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
@@ -20,6 +20,22 @@ services:
method: 'createClient'
arguments: ['mooc']
+ Mooc.courses.CourseRepository:
+ class: ../../../../../Contexts/Mooc/Courses/infrastructure/persistence/MongoCourseRepository
+ arguments: ['@Mooc.shared.ConnectionManager']
+
+ Mooc.shared.EventBus:
+ class: ../../../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus
+ arguments: []
+
+ Mooc.courses.CourseCreator:
+ class: ../../../../../Contexts/Mooc/Courses/application/CourseCreator
+ arguments: ['@Mooc.courses.CourseRepository', '@Mooc.shared.EventBus']
+
Apps.Backoffice.Frontend.controllers.CoursesGetController:
class: ../../controllers/CoursesGetController
arguments: ['@Mooc.coursesCounter.CoursesCounterFinder']
+
+ Apps.Backoffice.Frontend.controllers.CoursesPostController:
+ class: ../../controllers/CoursesPostController
+ arguments: ['@Mooc.courses.CourseCreator']
diff --git a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
index 953da5a..8cd931d 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
@@ -1,5 +1,6 @@
import { Request, Response } from 'express';
import { CoursesCounterFinder } from '../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder';
+import { Uuid } from '../../../../Contexts/Shared/domain/value-object/Uuid';
export class CoursesGetController {
constructor(private coursesCounterFinder: CoursesCounterFinder) {}
@@ -11,7 +12,8 @@ export class CoursesGetController {
title: 'Welcome',
description: 'CodelyTV - Backoffice',
courses_counter: courses.total,
- new_course_id: 'xxxx'
+ new_course_id: Uuid.random(),
+ flash: req.flash()
});
}
}
diff --git a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
new file mode 100644
index 0000000..d7c630b
--- /dev/null
+++ b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
@@ -0,0 +1,20 @@
+import { Request, Response } from 'express';
+import { CreateCourseRequest } from '../../../../Contexts/Mooc/Courses/application/CreateCourseRequest';
+import { CourseCreator } from '../../../../Contexts/Mooc/Courses/application/CourseCreator';
+
+export class CoursesPostController {
+ constructor(private courseCreator: CourseCreator) {}
+
+ async run(req: Request, res: Response) {
+ // TODO: validation
+ // req.flash('errors.id', 'Flash Message Added');
+
+ await this.createCourse(req, res);
+ }
+
+ private async createCourse(req: Request, res: Response) {
+ await this.courseCreator.run({ id: req.body.id, name: req.body.name, duration: req.body.duration });
+ req.flash('message', `Felicidades, el curso ${req.body.name} ha sido creado!`);
+ res.redirect('/courses');
+ }
+}
diff --git a/src/apps/backoffice/frontend/routes/courses.route.ts b/src/apps/backoffice/frontend/routes/courses.route.ts
index 23f7303..1bf8aa9 100644
--- a/src/apps/backoffice/frontend/routes/courses.route.ts
+++ b/src/apps/backoffice/frontend/routes/courses.route.ts
@@ -1,8 +1,16 @@
import { Express } from 'express';
import container from '../config/dependency-injection';
import { CoursesGetController } from '../controllers/CoursesGetController';
+import { CoursesPostController } from '../controllers/CoursesPostController';
export const register = (app: Express) => {
- const controller: CoursesGetController = container.get('Apps.Backoffice.Frontend.controllers.CoursesGetController');
- app.get('/courses', controller.run.bind(controller));
+ const coursesGetController: CoursesGetController = container.get(
+ 'Apps.Backoffice.Frontend.controllers.CoursesGetController'
+ );
+ const coursesPostController: CoursesPostController = container.get(
+ 'Apps.Backoffice.Frontend.controllers.CoursesPostController'
+ );
+
+ app.get('/courses', coursesGetController.run.bind(coursesGetController));
+ app.post('/courses', coursesPostController.run.bind(coursesPostController));
};
diff --git a/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html b/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
index ce01362..e151e98 100644
--- a/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
+++ b/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
@@ -1 +1,48 @@
-hello
+
From 3f8ca2ad6742ad63a27819041d38703ec33db9c7 Mon Sep 17 00:00:00 2001
From: Fran Ortiz
Date: Tue, 7 Jul 2020 19:36:25 +0200
Subject: [PATCH 22/48] Use localhost as mongo host by default
---
src/apps/backoffice/frontend/config/config.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/apps/backoffice/frontend/config/config.ts b/src/apps/backoffice/frontend/config/config.ts
index 11b1dba..b679f61 100644
--- a/src/apps/backoffice/frontend/config/config.ts
+++ b/src/apps/backoffice/frontend/config/config.ts
@@ -12,7 +12,7 @@ const convictConfig = convict({
doc: 'The Mongo connection URL',
format: String,
env: 'MONGO_URL',
- default: 'mongodb://mongo:27017/dev'
+ default: 'mongodb://localhost:27017/dev'
}
}
});
From bda1674b0414e04f7411c5b69884fe820eca25f8 Mon Sep 17 00:00:00 2001
From: Fran Ortiz
Date: Fri, 10 Jul 2020 16:13:00 +0200
Subject: [PATCH 23/48] Add courses navigation
---
src/apps/backoffice/frontend/templates/partials/header.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/apps/backoffice/frontend/templates/partials/header.html b/src/apps/backoffice/frontend/templates/partials/header.html
index 30fe251..1fccf60 100644
--- a/src/apps/backoffice/frontend/templates/partials/header.html
+++ b/src/apps/backoffice/frontend/templates/partials/header.html
@@ -11,7 +11,7 @@
class="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-white mr-4">
Usuarios
-
Cursos
From 80cb15f8a2806b421d962928f206d182208298be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1n=20Portillo?=
Date: Fri, 10 Jul 2020 17:52:43 +0200
Subject: [PATCH 24/48] Add lint step and activate eoline lint rule
---
.github/workflows/nodejs.yml | 1 +
package.json | 1 +
tslint.json | 2 +-
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
index c148dee..82a6447 100644
--- a/.github/workflows/nodejs.yml
+++ b/.github/workflows/nodejs.yml
@@ -25,6 +25,7 @@ jobs:
run: |
npm install
npm run build --if-present
+ npm run lint
npm test
env:
CI: true
diff --git a/package.json b/package.json
index 59a19f4..45a50f1 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"test": "npm run test:unit && npm run test:features",
"test:unit": "NODE_ENV=test jest",
"test:features": "NODE_ENV=test cucumber-js -p default",
+ "lint": "tslint src/**/*.ts{,x}",
"start": "NODE_ENV=production node dist/src/apps/mooc_backend/server",
"build": "npm run build:clean && npm run build:tsc && npm run build:di",
"build:tsc": "tsc -p tsconfig.prod.json",
diff --git a/tslint.json b/tslint.json
index b29bf01..7f72323 100644
--- a/tslint.json
+++ b/tslint.json
@@ -4,7 +4,7 @@
"rules": {
"adjacent-overload-signatures": true,
"curly": true,
- "eofline": false,
+ "eofline": true,
"align": [true, "parameters"],
"class-name": true,
"indent": [true, "spaces"],
From 9c16582103d398592a43e08ea25afb5396d599d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Iv=C3=A1n=20Portillo?=
Date: Fri, 10 Jul 2020 17:56:54 +0200
Subject: [PATCH 25/48] Fix linter issues
---
.../application/CreateCourseCommand.ts | 2 +-
.../Find/FindCoursesCounterQuery.ts | 4 +--
.../Find/FindCoursesCounterQueryHandler.ts | 30 +++++++++----------
src/Contexts/Shared/domain/CommandBus.ts | 2 +-
src/Contexts/Shared/domain/QueryBus.ts | 2 +-
src/Contexts/Shared/domain/Response.ts | 2 +-
.../QueryBus/QueryHandlersInformation.ts | 4 ++-
tslint.json | 2 +-
8 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts b/src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts
index 199f777..884cf7d 100644
--- a/src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts
+++ b/src/Contexts/Mooc/Courses/application/CreateCourseCommand.ts
@@ -17,4 +17,4 @@ export class CreateCourseCommand extends Command {
this.name = name;
this.duration = duration;
}
-}
\ No newline at end of file
+}
diff --git a/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts
index 312dd47..bdbf087 100644
--- a/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts
+++ b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery.ts
@@ -1,3 +1,3 @@
-import { Query } from "../../../../Shared/domain/Query";
+import { Query } from '../../../../Shared/domain/Query';
-export class FindCoursesCounterQuery implements Query {}
\ No newline at end of file
+export class FindCoursesCounterQuery implements Query {}
diff --git a/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts
index c8e85ab..b456d6f 100644
--- a/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts
+++ b/src/Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler.ts
@@ -1,17 +1,17 @@
-import { QueryHandler } from "../../../../Shared/domain/QueryHandler";
-import { FindCoursesCounterQuery } from "./FindCoursesCounterQuery";
-import { FindCoursesCounterResponse } from "./FindCoursesCounterResponse";
-import { Query } from "../../../../Shared/domain/Query";
-import { CoursesCounterFinder } from "./CoursesCounterFinder";
+import { QueryHandler } from '../../../../Shared/domain/QueryHandler';
+import { FindCoursesCounterQuery } from './FindCoursesCounterQuery';
+import { FindCoursesCounterResponse } from './FindCoursesCounterResponse';
+import { Query } from '../../../../Shared/domain/Query';
+import { CoursesCounterFinder } from './CoursesCounterFinder';
-export class FindCoursesCounterQueryHandler implements QueryHandler {
- constructor(private finder: CoursesCounterFinder) {}
+export class FindCoursesCounterQueryHandler
+ implements QueryHandler {
+ constructor(private finder: CoursesCounterFinder) {}
- subscribedTo(): Query {
- return FindCoursesCounterQuery;
- }
- handle(_query: FindCoursesCounterQuery): Promise {
- return this.finder.run();
- }
-
-}
\ No newline at end of file
+ subscribedTo(): Query {
+ return FindCoursesCounterQuery;
+ }
+ handle(_query: FindCoursesCounterQuery): Promise {
+ return this.finder.run();
+ }
+}
diff --git a/src/Contexts/Shared/domain/CommandBus.ts b/src/Contexts/Shared/domain/CommandBus.ts
index a4aebbc..ac32da3 100644
--- a/src/Contexts/Shared/domain/CommandBus.ts
+++ b/src/Contexts/Shared/domain/CommandBus.ts
@@ -2,4 +2,4 @@ import { Command } from './Command';
export interface CommandBus {
dispatch(command: Command): Promise;
-}
\ No newline at end of file
+}
diff --git a/src/Contexts/Shared/domain/QueryBus.ts b/src/Contexts/Shared/domain/QueryBus.ts
index 2a04f03..38c5b49 100644
--- a/src/Contexts/Shared/domain/QueryBus.ts
+++ b/src/Contexts/Shared/domain/QueryBus.ts
@@ -3,4 +3,4 @@ import { Response } from './Response';
export interface QueryBus {
ask(query: Query): Promise;
-}
\ No newline at end of file
+}
diff --git a/src/Contexts/Shared/domain/Response.ts b/src/Contexts/Shared/domain/Response.ts
index c1db157..158c809 100644
--- a/src/Contexts/Shared/domain/Response.ts
+++ b/src/Contexts/Shared/domain/Response.ts
@@ -1 +1 @@
-export interface Response {}
\ No newline at end of file
+export interface Response {}
diff --git a/src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts b/src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts
index e751eca..dd34e48 100644
--- a/src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts
+++ b/src/Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation.ts
@@ -10,7 +10,9 @@ export class QueryHandlersInformation {
this.queryHandlersMap = this.formatHandlers(queryHandlers);
}
- private formatHandlers(queryHandlers: Array>): Map> {
+ private formatHandlers(
+ queryHandlers: Array>
+ ): Map> {
const handlersMap = new Map();
queryHandlers.forEach(queryHandler => {
diff --git a/tslint.json b/tslint.json
index 7f72323..b43960e 100644
--- a/tslint.json
+++ b/tslint.json
@@ -26,7 +26,7 @@
"no-bitwise": true,
"no-debugger": true,
"prefer-const": true,
- "no-empty-interface": true,
+ "no-empty-interface": false,
"no-string-throw": true,
"unified-signatures": true,
"space-before-function-paren": [
From fced599e646c50831f0786b0ca7fd8d0d45bc305 Mon Sep 17 00:00:00 2001
From: Fran Ortiz
Date: Sat, 11 Jul 2020 12:10:46 +0200
Subject: [PATCH 26/48] Fix build
---
.../frontend/controllers/CoursesPostController.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
index d7c630b..f3274ff 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
@@ -13,7 +13,11 @@ export class CoursesPostController {
}
private async createCourse(req: Request, res: Response) {
- await this.courseCreator.run({ id: req.body.id, name: req.body.name, duration: req.body.duration });
+ await this.courseCreator.run({
+ courseId: req.body.id,
+ courseName: req.body.name,
+ courseDuration: req.body.duration
+ });
req.flash('message', `Felicidades, el curso ${req.body.name} ha sido creado!`);
res.redirect('/courses');
}
From 331b8dc35d126f5125833418370d4a25e5477794 Mon Sep 17 00:00:00 2001
From: Fran Ortiz
Date: Sat, 11 Jul 2020 12:33:37 +0200
Subject: [PATCH 27/48] Use command and query bus in backoffice frontend app
---
.../dependency-injection/application.yaml | 34 +++++++++++++++++--
.../controllers/CoursesGetController.ts | 8 +++--
.../controllers/CoursesPostController.ts | 16 +++++----
.../CoursesCounter/application.yaml | 2 --
4 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
index 510476e..16fcec8 100644
--- a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
@@ -8,11 +8,11 @@ services:
Mooc.coursesCounter.CoursesCounterFinder:
class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder
- arguments: ["@Mooc.coursesCounter.CoursesCounterRepository"]
+ arguments: ['@Mooc.coursesCounter.CoursesCounterRepository']
Mooc.coursesCounter.CoursesCounterRepository:
class: ../../../../../Contexts/Mooc/CoursesCounter/infrastructure/persistence/mongo/MongoCoursesCounterRepository
- arguments: ["@Mooc.shared.ConnectionManager"]
+ arguments: ['@Mooc.shared.ConnectionManager']
Mooc.shared.ConnectionManager:
factory:
@@ -34,8 +34,36 @@ services:
Apps.Backoffice.Frontend.controllers.CoursesGetController:
class: ../../controllers/CoursesGetController
- arguments: ['@Mooc.coursesCounter.CoursesCounterFinder']
+ arguments: ['@Mooc.shared.QueryBus']
Apps.Backoffice.Frontend.controllers.CoursesPostController:
class: ../../controllers/CoursesPostController
+ arguments: ['@Mooc.shared.CommandBus']
+
+ Mooc.coursesCounter.FindCoursesCounterQueryHandler:
+ class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler
+ arguments: ['@Mooc.coursesCounter.CoursesCounterFinder']
+ tags:
+ - { name: 'queryHandler' }
+
+ Mooc.courses.CreateCourseCommandHandler:
+ class: ../../../../../Contexts/Mooc/Courses/application/CreateCourseCommandHandler
arguments: ['@Mooc.courses.CourseCreator']
+ tags:
+ - { name: 'commandHandler' }
+
+ Mooc.shared.QueryBus:
+ class: ../../../../../Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus
+ arguments: ['@Mooc.shared.QueryHandlersInformation']
+
+ Mooc.shared.CommandBus:
+ class: ../../../../../Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus
+ arguments: ['@Mooc.shared.CommandHandlersInformation']
+
+ Mooc.shared.QueryHandlersInformation:
+ class: ../../../../../Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation
+ arguments: ['!tagged queryHandler']
+
+ Mooc.shared.CommandHandlersInformation:
+ class: ../../../../../Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation
+ arguments: ['!tagged commandHandler']
diff --git a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
index 8cd931d..0900f3d 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
@@ -1,12 +1,14 @@
import { Request, Response } from 'express';
-import { CoursesCounterFinder } from '../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder';
import { Uuid } from '../../../../Contexts/Shared/domain/value-object/Uuid';
+import { QueryBus } from '../../../../Contexts/Shared/domain/QueryBus';
+import { FindCoursesCounterResponse } from '../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterResponse';
+import { FindCoursesCounterQuery } from '../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery';
export class CoursesGetController {
- constructor(private coursesCounterFinder: CoursesCounterFinder) {}
+ constructor(private queryBus: QueryBus) {}
async run(req: Request, res: Response) {
- const courses = await this.coursesCounterFinder.run();
+ const courses = await this.queryBus.ask(new FindCoursesCounterQuery());
res.render('pages/courses/courses', {
title: 'Welcome',
diff --git a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
index f3274ff..f99a1bb 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
@@ -1,9 +1,9 @@
import { Request, Response } from 'express';
-import { CreateCourseRequest } from '../../../../Contexts/Mooc/Courses/application/CreateCourseRequest';
-import { CourseCreator } from '../../../../Contexts/Mooc/Courses/application/CourseCreator';
+import { CommandBus } from '../../../../Contexts/Shared/domain/CommandBus';
+import { CreateCourseCommand } from '../../../../Contexts/Mooc/Courses/application/CreateCourseCommand';
export class CoursesPostController {
- constructor(private courseCreator: CourseCreator) {}
+ constructor(private commandBus: CommandBus) {}
async run(req: Request, res: Response) {
// TODO: validation
@@ -13,11 +13,13 @@ export class CoursesPostController {
}
private async createCourse(req: Request, res: Response) {
- await this.courseCreator.run({
- courseId: req.body.id,
- courseName: req.body.name,
- courseDuration: req.body.duration
+ const createCourseCommand = new CreateCourseCommand({
+ id: req.body.id,
+ name: req.body.name,
+ duration: req.body.duration
});
+ await this.commandBus.dispatch(createCourseCommand);
+
req.flash('message', `Felicidades, el curso ${req.body.name} ha sido creado!`);
res.redirect('/courses');
}
diff --git a/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml b/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
index 493864c..d4457d9 100644
--- a/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
@@ -20,10 +20,8 @@ services:
class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder
arguments: ["@Mooc.coursesCounter.CoursesCounterRepository"]
-
Mooc.coursesCounter.FindCoursesCounterQueryHandler:
class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler
arguments: ["@Mooc.coursesCounter.CoursesCounterFinder"]
tags:
- { name: 'queryHandler' }
-
From ab59e53b9390127564887b05af523f0daebb2543 Mon Sep 17 00:00:00 2001
From: Fernando Vilas Maciel
Date: Tue, 14 Jul 2020 16:07:27 +0200
Subject: [PATCH 28/48] Initialize CouserCounter collection if it's empty
---
src/apps/backoffice/frontend/config/config.ts | 2 +-
src/apps/backoffice/frontend/config/test.json | 6 +++++-
src/apps/backoffice/frontend/seed.ts | 18 ++++++++++++++++++
src/apps/backoffice/frontend/server.ts | 5 ++++-
src/apps/mooc_backend/config/config.ts | 2 +-
src/apps/mooc_backend/config/test.json | 2 +-
6 files changed, 30 insertions(+), 5 deletions(-)
create mode 100644 src/apps/backoffice/frontend/seed.ts
diff --git a/src/apps/backoffice/frontend/config/config.ts b/src/apps/backoffice/frontend/config/config.ts
index b679f61..de28f95 100644
--- a/src/apps/backoffice/frontend/config/config.ts
+++ b/src/apps/backoffice/frontend/config/config.ts
@@ -12,7 +12,7 @@ const convictConfig = convict({
doc: 'The Mongo connection URL',
format: String,
env: 'MONGO_URL',
- default: 'mongodb://localhost:27017/dev'
+ default: 'mongodb://localhost:27017/backoffice-frontend-dev'
}
}
});
diff --git a/src/apps/backoffice/frontend/config/test.json b/src/apps/backoffice/frontend/config/test.json
index 0967ef4..6a0d2f4 100644
--- a/src/apps/backoffice/frontend/config/test.json
+++ b/src/apps/backoffice/frontend/config/test.json
@@ -1 +1,5 @@
-{}
+{
+ "mongo": {
+ "url": "mongodb://localhost:27017/backoffice-frontend-test"
+ }
+}
diff --git a/src/apps/backoffice/frontend/seed.ts b/src/apps/backoffice/frontend/seed.ts
new file mode 100644
index 0000000..a1abc60
--- /dev/null
+++ b/src/apps/backoffice/frontend/seed.ts
@@ -0,0 +1,18 @@
+import { CoursesCounterRepository } from '../../../Contexts/Mooc/CoursesCounter/domain/CoursesCounterRepository';
+import { CoursesCounter } from '../../../Contexts/Mooc/CoursesCounter/domain/CoursesCounter';
+import { CoursesCounterId } from '../../../Contexts/Mooc/CoursesCounter/domain/CoursesCounterId';
+import container from './config/dependency-injection';
+
+export async function seed() {
+ const repository: CoursesCounterRepository = container.get('Mooc.coursesCounter.CoursesCounterRepository');
+ const logger = container.get('Contexts.shared.Logger');
+
+ const alreadyExists = await repository.search();
+ const isTestEnvironment = process.env.NODE_ENV === 'test';
+
+ if (!alreadyExists && !isTestEnvironment) {
+ logger.info('[Seed] Initializing CourseCounter');
+ const courseCounter = CoursesCounter.initialize(CoursesCounterId.random());
+ await repository.save(courseCounter);
+ }
+}
diff --git a/src/apps/backoffice/frontend/server.ts b/src/apps/backoffice/frontend/server.ts
index 76b7b0a..576a1c5 100644
--- a/src/apps/backoffice/frontend/server.ts
+++ b/src/apps/backoffice/frontend/server.ts
@@ -1,6 +1,7 @@
import errorHandler from 'errorhandler';
import app from './app';
import container from './config/dependency-injection';
+import { seed } from './seed';
/**
* Error Handler. Provides full stack - remove for production
@@ -10,9 +11,11 @@ app.use(errorHandler());
/**
* Start Express server.
*/
-const server = app.listen(app.get('port'), () => {
+const server = app.listen(app.get('port'), async () => {
const winstonLogger = container.get('Contexts.shared.Logger');
+ await seed();
+
winstonLogger.info(
` Backoffice frontend is running at http://localhost:${app.get('port')} in ${app.get('env')} mode`
);
diff --git a/src/apps/mooc_backend/config/config.ts b/src/apps/mooc_backend/config/config.ts
index b679f61..bd561bb 100644
--- a/src/apps/mooc_backend/config/config.ts
+++ b/src/apps/mooc_backend/config/config.ts
@@ -12,7 +12,7 @@ const convictConfig = convict({
doc: 'The Mongo connection URL',
format: String,
env: 'MONGO_URL',
- default: 'mongodb://localhost:27017/dev'
+ default: 'mongodb://localhost:27017/mooc-backend-dev'
}
}
});
diff --git a/src/apps/mooc_backend/config/test.json b/src/apps/mooc_backend/config/test.json
index fcef01b..c18fdd4 100644
--- a/src/apps/mooc_backend/config/test.json
+++ b/src/apps/mooc_backend/config/test.json
@@ -1,3 +1,3 @@
{
- "mongo": { "url": "mongodb://localhost:27017/test" }
+ "mongo": { "url": "mongodb://localhost:27017/mooc-backend-test" }
}
From 8c010529019a28dde3ffcdc1034566273aa6af7d Mon Sep 17 00:00:00 2001
From: Antonio Leon
Date: Fri, 4 Sep 2020 17:30:35 +0200
Subject: [PATCH 29/48] Add notifications module with application service and
domain event subscriber
---
.../SendWelcomeUserEmail.ts | 17 +++++
.../SendWelcomeUserEmailOnUserRegistered.ts | 18 +++++
.../Mooc/Notifications/domain/Email.ts | 37 +++++++++++
.../Mooc/Notifications/domain/EmailAddress.ts | 3 +
.../Mooc/Notifications/domain/EmailId.ts | 3 +
.../Mooc/Notifications/domain/EmailSender.ts | 5 ++
.../domain/UserRegisteredDomainEvent.ts | 37 +++++++++++
.../Notifications/domain/WelcomeUserEmail.ts | 13 ++++
.../domain/WelcomeUserEmailError.ts | 7 ++
.../__mocks__/EmailSenderMock.ts | 22 +++++++
...ndWelcomeUserEmailOnUserRegistered.test.ts | 66 +++++++++++++++++++
11 files changed, 228 insertions(+)
create mode 100644 src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts
create mode 100644 src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts
create mode 100644 src/Contexts/Mooc/Notifications/domain/Email.ts
create mode 100644 src/Contexts/Mooc/Notifications/domain/EmailAddress.ts
create mode 100644 src/Contexts/Mooc/Notifications/domain/EmailId.ts
create mode 100644 src/Contexts/Mooc/Notifications/domain/EmailSender.ts
create mode 100644 src/Contexts/Mooc/Notifications/domain/UserRegisteredDomainEvent.ts
create mode 100644 src/Contexts/Mooc/Notifications/domain/WelcomeUserEmail.ts
create mode 100644 src/Contexts/Mooc/Notifications/domain/WelcomeUserEmailError.ts
create mode 100644 tests/Contexts/Mooc/Notifications/__mocks__/EmailSenderMock.ts
create mode 100644 tests/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.test.ts
diff --git a/src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts b/src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts
new file mode 100644
index 0000000..140e081
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts
@@ -0,0 +1,17 @@
+import { EmailSender } from '../../domain/EmailSender';
+import { EmailAddress } from '../../domain/EmailAddress';
+import { WelcomeUserEmail } from '../../domain/WelcomeUserEmail';
+import { WelcomeUserEmailError } from '../../domain/WelcomeUserEmailError';
+
+export default class SendWelcomeUserEmail {
+ constructor(private emailSender: EmailSender) {}
+
+ async run(userEmailAddress: EmailAddress): Promise {
+ const welcomeUserEmail = new WelcomeUserEmail(userEmailAddress);
+ try {
+ await this.emailSender.send(welcomeUserEmail);
+ } catch (error) {
+ throw new WelcomeUserEmailError(userEmailAddress);
+ }
+ }
+}
diff --git a/src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts b/src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts
new file mode 100644
index 0000000..785e76b
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts
@@ -0,0 +1,18 @@
+import { DomainEventSubscriber } from '../../../../Shared/domain/DomainEventSubscriber';
+import { UserRegisteredDomainEvent } from '../../domain/UserRegisteredDomainEvent';
+import { DomainEventClass } from '../../../../Shared/domain/DomainEvent';
+import SendWelcomeUserEmail from './SendWelcomeUserEmail';
+import { EmailAddress } from '../../domain/EmailAddress';
+
+export default class SendWelcomeUserEmailOnUserRegistered implements DomainEventSubscriber {
+ constructor(private sendWelcomeUserEmail: SendWelcomeUserEmail) {}
+
+ subscribedTo(): DomainEventClass[] {
+ return [UserRegisteredDomainEvent];
+ }
+
+ async on(domainEvent: UserRegisteredDomainEvent): Promise {
+ const userEmailAddress = new EmailAddress(domainEvent.userEmailAddress);
+ await this.sendWelcomeUserEmail.run(userEmailAddress);
+ }
+}
diff --git a/src/Contexts/Mooc/Notifications/domain/Email.ts b/src/Contexts/Mooc/Notifications/domain/Email.ts
new file mode 100644
index 0000000..673dc3c
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/domain/Email.ts
@@ -0,0 +1,37 @@
+import { EmailAddress } from './EmailAddress';
+import { EmailId } from './EmailId';
+import { Uuid } from '../../../Shared/domain/value-object/Uuid';
+
+type ConstructorParams = {
+ id?: EmailId;
+ from: EmailAddress;
+ to: EmailAddress;
+ subject: string;
+ body: string;
+};
+
+export class Email {
+ readonly id: EmailId;
+ readonly from: EmailAddress;
+ readonly to: EmailAddress;
+ readonly subject: string;
+ readonly body: string;
+
+ constructor(params: ConstructorParams) {
+ this.id = params.id || new EmailId(Uuid.random().value);
+ this.from = params.from;
+ this.to = params.to;
+ this.subject = params.subject;
+ this.body = params.body;
+ }
+
+ equals(otherEmail: Email): boolean {
+ return (
+ this.id.value === otherEmail.id.value &&
+ this.from.value === otherEmail.from.value &&
+ this.to.value === otherEmail.to.value &&
+ this.subject === otherEmail.subject &&
+ this.body === otherEmail.body
+ );
+ }
+}
diff --git a/src/Contexts/Mooc/Notifications/domain/EmailAddress.ts b/src/Contexts/Mooc/Notifications/domain/EmailAddress.ts
new file mode 100644
index 0000000..f014743
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/domain/EmailAddress.ts
@@ -0,0 +1,3 @@
+import { StringValueObject } from '../../../Shared/domain/value-object/StringValueObject';
+
+export class EmailAddress extends StringValueObject {}
diff --git a/src/Contexts/Mooc/Notifications/domain/EmailId.ts b/src/Contexts/Mooc/Notifications/domain/EmailId.ts
new file mode 100644
index 0000000..3ba583c
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/domain/EmailId.ts
@@ -0,0 +1,3 @@
+import { Uuid } from '../../../Shared/domain/value-object/Uuid';
+
+export class EmailId extends Uuid {}
diff --git a/src/Contexts/Mooc/Notifications/domain/EmailSender.ts b/src/Contexts/Mooc/Notifications/domain/EmailSender.ts
new file mode 100644
index 0000000..5a96e50
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/domain/EmailSender.ts
@@ -0,0 +1,5 @@
+import { Email } from './Email';
+
+export interface EmailSender {
+ send(email: Email): Promise;
+}
diff --git a/src/Contexts/Mooc/Notifications/domain/UserRegisteredDomainEvent.ts b/src/Contexts/Mooc/Notifications/domain/UserRegisteredDomainEvent.ts
new file mode 100644
index 0000000..e23cd4e
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/domain/UserRegisteredDomainEvent.ts
@@ -0,0 +1,37 @@
+import { DomainEvent } from '../../../Shared/domain/DomainEvent';
+
+type UserRegisteredDomainEventBody = { userEmailAddress: string };
+
+export class UserRegisteredDomainEvent extends DomainEvent {
+ static readonly EVENT_NAME = 'user.registered';
+ readonly userEmailAddress: string;
+
+ constructor(data: {
+ id: string;
+ userEmailAddress: string;
+ eventId?: string;
+ occurredOn?: Date;
+ }) {
+ const { id, eventId, occurredOn, userEmailAddress } = data;
+ super(UserRegisteredDomainEvent.EVENT_NAME, id, eventId, occurredOn);
+ this.userEmailAddress = userEmailAddress;
+ }
+
+ toPrimitive(): Object {
+ return { userEmailAddress: this.userEmailAddress };
+ }
+
+ static fromPrimitives(
+ aggregateId: string,
+ body: UserRegisteredDomainEventBody,
+ eventId: string,
+ occurredOn: Date
+ ): DomainEvent {
+ return new UserRegisteredDomainEvent({
+ id: aggregateId,
+ userEmailAddress: body.userEmailAddress,
+ eventId,
+ occurredOn
+ });
+ }
+}
diff --git a/src/Contexts/Mooc/Notifications/domain/WelcomeUserEmail.ts b/src/Contexts/Mooc/Notifications/domain/WelcomeUserEmail.ts
new file mode 100644
index 0000000..22a2fd9
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/domain/WelcomeUserEmail.ts
@@ -0,0 +1,13 @@
+import { Email } from './Email';
+import { EmailAddress } from './EmailAddress';
+
+export class WelcomeUserEmail extends Email {
+ constructor(to: EmailAddress) {
+ super({
+ from: new EmailAddress('welcome@foo.com'),
+ to,
+ subject: 'Welcome',
+ body: 'Welcome to our platform'
+ });
+ }
+}
diff --git a/src/Contexts/Mooc/Notifications/domain/WelcomeUserEmailError.ts b/src/Contexts/Mooc/Notifications/domain/WelcomeUserEmailError.ts
new file mode 100644
index 0000000..ef6eddc
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/domain/WelcomeUserEmailError.ts
@@ -0,0 +1,7 @@
+import { EmailAddress } from './EmailAddress';
+
+export class WelcomeUserEmailError extends Error {
+ constructor(userEmailAddress: EmailAddress) {
+ super(`Error sending WelcomeUser email to ${userEmailAddress.value}`);
+ }
+}
diff --git a/tests/Contexts/Mooc/Notifications/__mocks__/EmailSenderMock.ts b/tests/Contexts/Mooc/Notifications/__mocks__/EmailSenderMock.ts
new file mode 100644
index 0000000..083d204
--- /dev/null
+++ b/tests/Contexts/Mooc/Notifications/__mocks__/EmailSenderMock.ts
@@ -0,0 +1,22 @@
+import { EmailSender } from '../../../../../src/Contexts/Mooc/Notifications/domain/EmailSender';
+import { Email } from '../../../../../src/Contexts/Mooc/Notifications/domain/Email';
+
+export class EmailSenderMock implements EmailSender {
+ private sendSpy = jest.fn();
+
+ async send(email: Email): Promise {
+ this.sendSpy(email);
+ }
+
+ assertSentTimes(times: number): void {
+ expect(this.sendSpy.mock.calls.length).toBe(times);
+ }
+
+ lastEmailSent(): Email {
+ const sendCalls = this.sendSpy.mock.calls;
+ const lastSendCall = sendCalls[sendCalls.length - 1] || [];
+ const lastEmailSent = lastSendCall[0] as Email;
+
+ return lastEmailSent;
+ }
+}
diff --git a/tests/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.test.ts b/tests/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.test.ts
new file mode 100644
index 0000000..1755526
--- /dev/null
+++ b/tests/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.test.ts
@@ -0,0 +1,66 @@
+import faker from 'faker';
+import { Email } from '../../../../../../src/Contexts/Mooc/Notifications/domain/Email';
+import { EmailAddress } from '../../../../../../src/Contexts/Mooc/Notifications/domain/EmailAddress';
+import { EmailSender } from '../../../../../../src/Contexts/Mooc/Notifications/domain/EmailSender';
+import { EmailSenderMock } from '../../__mocks__/EmailSenderMock';
+import SendWelcomeUserEmail from '../../../../../../src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmail';
+import SendWelcomeUserEmailOnUserRegistered from '../../../../../../src/Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered';
+import { UserRegisteredDomainEvent } from '../../../../../../src/Contexts/Mooc/Notifications/domain/UserRegisteredDomainEvent';
+import { UuidMother } from '../../../../../Contexts/Shared/domain/UuidMother';
+import { WelcomeUserEmail } from '../../../../../../src/Contexts/Mooc/Notifications/domain/WelcomeUserEmail';
+import { WelcomeUserEmailError } from '../../../../../../src/Contexts/Mooc/Notifications/domain/WelcomeUserEmailError';
+
+describe('SendWelcomeUserEmailOnUserRegistered event handler', () => {
+ it('sends a welcome email to the user', async () => {
+ const emailSenderMock = new EmailSenderMock();
+ const sendWelcomeUserEmail = new SendWelcomeUserEmail(emailSenderMock);
+ const sendWelcomeUserEmailOnUserRegistered = new SendWelcomeUserEmailOnUserRegistered(sendWelcomeUserEmail);
+ const userEmailAddress = anEmailAddress();
+ const domainEvent = aDomainEventWithEmailAddress(userEmailAddress);
+
+ await sendWelcomeUserEmailOnUserRegistered.on(domainEvent);
+
+ const lastEmailSent = emailSenderMock.lastEmailSent();
+ emailSenderMock.assertSentTimes(1);
+ expect(lastEmailSent).toBeInstanceOf(WelcomeUserEmail);
+ expect(lastEmailSent.to).toEqual(userEmailAddress);
+ });
+
+ it('throws a WelcomeUserEmailError if the emailSender fails', async () => {
+ const failingEmailSender = aFailingEmailSender();
+ const sendWelcomeUserEmail = new SendWelcomeUserEmail(failingEmailSender);
+ const sendWelcomeUserEmailOnUserRegistered = new SendWelcomeUserEmailOnUserRegistered(sendWelcomeUserEmail);
+
+ const domainEvent = aDomainEventWithEmailAddress(anEmailAddress());
+ let error;
+
+ try {
+ await sendWelcomeUserEmailOnUserRegistered.on(domainEvent);
+ } catch (e) {
+ error = e;
+ }
+
+ expect(error).toBeDefined();
+ expect(error).toBeInstanceOf(WelcomeUserEmailError);
+ expect(error.message).toBe(`Error sending WelcomeUser email to ${domainEvent.userEmailAddress}`);
+ });
+});
+
+function aFailingEmailSender() {
+ return {
+ async send(email: Email) {
+ throw new Error('some error');
+ }
+ } as EmailSender;
+}
+
+function anEmailAddress(): EmailAddress {
+ return new EmailAddress(faker.internet.email());
+}
+
+function aDomainEventWithEmailAddress(emailAddress: EmailAddress) {
+ return new UserRegisteredDomainEvent({
+ id: UuidMother.random(),
+ userEmailAddress: emailAddress.value
+ });
+}
From d164cc1f4c57185ec4da736e26f5d5905d021f90 Mon Sep 17 00:00:00 2001
From: Antonio Leon
Date: Fri, 4 Sep 2020 17:41:36 +0200
Subject: [PATCH 30/48] Add DI and fake email sender
---
.../infrastructure/FakeEmailSender.ts | 8 ++++++++
.../Notifications/application.yaml | 14 ++++++++++++++
.../config/dependency-injection/application.yaml | 1 +
3 files changed, 23 insertions(+)
create mode 100644 src/Contexts/Mooc/Notifications/infrastructure/FakeEmailSender.ts
create mode 100644 src/apps/mooc_backend/config/dependency-injection/Notifications/application.yaml
diff --git a/src/Contexts/Mooc/Notifications/infrastructure/FakeEmailSender.ts b/src/Contexts/Mooc/Notifications/infrastructure/FakeEmailSender.ts
new file mode 100644
index 0000000..e148b9f
--- /dev/null
+++ b/src/Contexts/Mooc/Notifications/infrastructure/FakeEmailSender.ts
@@ -0,0 +1,8 @@
+import { EmailSender } from '../domain/EmailSender';
+import { Email } from '../domain/Email';
+
+export default class FakeEmailSender implements EmailSender {
+ async send(email: Email): Promise {
+ // do nothing
+ }
+}
diff --git a/src/apps/mooc_backend/config/dependency-injection/Notifications/application.yaml b/src/apps/mooc_backend/config/dependency-injection/Notifications/application.yaml
new file mode 100644
index 0000000..ec4ae95
--- /dev/null
+++ b/src/apps/mooc_backend/config/dependency-injection/Notifications/application.yaml
@@ -0,0 +1,14 @@
+services:
+ Mooc.notifications.EmailSender:
+ class: ../../../../../Contexts/Mooc/Notifications/infrastructure/FakeEmailSender
+ arguments: []
+
+ Mooc.notifications.SendWelcomeUserEmail:
+ class: ../../../../../Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmail
+ arguments: ["@Mooc.notifications.EmailSender"]
+
+ Mooc.notifications.SendWelcomeUserEmailOnUserRegistered:
+ class: ../../../../../Contexts/Mooc/Notifications/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered
+ arguments: ["@Mooc.notifications.SendWelcomeUserEmail"]
+ tags:
+ - { name: 'domainEventSubscriber' }
\ No newline at end of file
diff --git a/src/apps/mooc_backend/config/dependency-injection/application.yaml b/src/apps/mooc_backend/config/dependency-injection/application.yaml
index 1bd153d..ba8eb1f 100644
--- a/src/apps/mooc_backend/config/dependency-injection/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/application.yaml
@@ -2,4 +2,5 @@ imports:
- { resource: ./Shared/application.yaml }
- { resource: ./Courses/application.yaml }
- { resource: ./CoursesCounter/application.yaml }
+ - { resource: ./Notifications/application.yaml }
- { resource: ./apps/application.yaml }
From 0a26b7d9b7df73cb7e12755dd56c66c8746c9099 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Tue, 15 Sep 2020 20:52:09 +0200
Subject: [PATCH 31/48] Validate courses request
---
package-lock.json | 21 +++++++
package.json | 1 +
.../controllers/CoursesGetController.ts | 12 ++--
.../controllers/CoursesPostController.ts | 30 ++++++---
.../frontend/controllers/WebController.ts | 61 +++++++++++++++++++
.../frontend/routes/courses.route.ts | 2 +-
.../courses/partials/new_course_form.html | 6 +-
7 files changed, 116 insertions(+), 17 deletions(-)
create mode 100644 src/apps/backoffice/frontend/controllers/WebController.ts
diff --git a/package-lock.json b/package-lock.json
index 496e635..f220c86 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2961,6 +2961,22 @@
"vary": "~1.1.2"
}
},
+ "express-validator": {
+ "version": "6.6.1",
+ "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.6.1.tgz",
+ "integrity": "sha512-+MrZKJ3eGYXkNF9p9Zf7MS7NkPJFg9MDYATU5c80Cf4F62JdLBIjWxy6481tRC0y1NnC9cgOw8FuN364bWaGhA==",
+ "requires": {
+ "lodash": "^4.17.19",
+ "validator": "^13.1.1"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+ }
+ }
+ },
"ext": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
@@ -8493,6 +8509,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "validator": {
+ "version": "13.1.1",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.1.1.tgz",
+ "integrity": "sha512-8GfPiwzzRoWTg7OV1zva1KvrSemuMkv07MA9TTl91hfhe+wKrsrgVN4H2QSFd/U/FhiU3iWPYVgvbsOGwhyFWw=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/package.json b/package.json
index d3456e2..9a9d490 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
"copy": "^0.3.2",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
+ "express-validator": "^6.6.1",
"glob": "^7.1.6",
"helmet": "^3.22.0",
"http-status": "^1.4.2",
diff --git a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
index 0900f3d..1c56d5c 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesGetController.ts
@@ -3,19 +3,21 @@ import { Uuid } from '../../../../Contexts/Shared/domain/value-object/Uuid';
import { QueryBus } from '../../../../Contexts/Shared/domain/QueryBus';
import { FindCoursesCounterResponse } from '../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterResponse';
import { FindCoursesCounterQuery } from '../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQuery';
+import { WebController } from './WebController';
-export class CoursesGetController {
- constructor(private queryBus: QueryBus) {}
+export class CoursesGetController extends WebController {
+ constructor(private queryBus: QueryBus) {
+ super();
+ }
async run(req: Request, res: Response) {
const courses = await this.queryBus.ask(new FindCoursesCounterQuery());
- res.render('pages/courses/courses', {
+ this.render(req, res, 'pages/courses/courses', {
title: 'Welcome',
description: 'CodelyTV - Backoffice',
courses_counter: courses.total,
- new_course_id: Uuid.random(),
- flash: req.flash()
+ id: Uuid.random().value
});
}
}
diff --git a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
index f99a1bb..f7cd3ff 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
@@ -1,15 +1,29 @@
import { Request, Response } from 'express';
import { CommandBus } from '../../../../Contexts/Shared/domain/CommandBus';
import { CreateCourseCommand } from '../../../../Contexts/Mooc/Courses/application/CreateCourseCommand';
+import { body, ValidationChain } from 'express-validator';
+import { WebController } from './WebController';
-export class CoursesPostController {
- constructor(private commandBus: CommandBus) {}
+export class CoursesPostController extends WebController {
+ constructor(private commandBus: CommandBus) {
+ super();
+ }
- async run(req: Request, res: Response) {
- // TODO: validation
- // req.flash('errors.id', 'Flash Message Added');
+ static validator(): ValidationChain[] {
+ return [
+ body('id').isUUID(),
+ body('name').isLength({ min: 1, max: 255 }),
+ body('duration').isLength({ min: 4, max: 100 })
+ ];
+ }
- await this.createCourse(req, res);
+ async run(req: Request, res: Response) {
+ const errors = this.validateRequest(req);
+ if (errors.length === 0) {
+ await this.createCourse(req, res);
+ } else {
+ this.redirectWithErrors(req, res, errors);
+ }
}
private async createCourse(req: Request, res: Response) {
@@ -18,9 +32,9 @@ export class CoursesPostController {
name: req.body.name,
duration: req.body.duration
});
+
await this.commandBus.dispatch(createCourseCommand);
- req.flash('message', `Felicidades, el curso ${req.body.name} ha sido creado!`);
- res.redirect('/courses');
+ this.redirectWithMessage(req, res, '/courses', `Felicidades, el curso ${req.body.name} ha sido creado!`);
}
}
diff --git a/src/apps/backoffice/frontend/controllers/WebController.ts b/src/apps/backoffice/frontend/controllers/WebController.ts
new file mode 100644
index 0000000..ae64abb
--- /dev/null
+++ b/src/apps/backoffice/frontend/controllers/WebController.ts
@@ -0,0 +1,61 @@
+import { Request, Response } from 'express';
+import { validationResult, ValidationError, matchedData } from 'express-validator';
+
+export abstract class WebController {
+ protected validateRequest(req: Request): Array {
+ const errors = validationResult(req);
+ return errors.array();
+ }
+
+ private setFlashMessage(req: Request, message: { key: string; value: string }) {
+ req.flash(message.key, message.value);
+ }
+
+ protected redirectWithErrors(req: Request, res: Response, errors: ValidationError[]) {
+ const validFields = this.getValidFields(req);
+
+ errors.forEach(e => {
+ this.setFlashMessage(req, { key: `errors.${e.param}`, value: e.msg });
+ });
+
+ validFields.forEach(field => {
+ this.setFlashMessage(req, { key: `inputs.${field.param}`, value: field.value });
+ });
+
+ res.redirect(req.originalUrl);
+ }
+
+ protected redirectWithMessage(req: Request, res: Response, route: string, message: string) {
+ this.setFlashMessage(req, { key: 'message', value: message });
+ res.redirect(route);
+ }
+
+ private getValidFields(req: Request): Array<{ value: any; param: string }> {
+ const validData = matchedData(req, { onlyValidData: false });
+ return Object.keys(validData).map(key => ({
+ param: key,
+ value: validData[key]
+ }));
+ }
+
+ protected render(req: Request, res: Response, template: string, data: { [key: string]: any }) {
+ const flash = this.feedFlash(req, data);
+ res.render('pages/courses/courses', {
+ ...data,
+ ...flash
+ });
+ }
+
+ private feedFlash(req: Request, data: { [key: string]: any }) {
+ const rawFlash = req.flash();
+ const flashResponse = Object.keys(data).reduce((flash, key) => {
+ flash[`inputs.${key}`] = flash[`inputs.${key}`] || data[key];
+ return flash;
+ }, rawFlash);
+ return {
+ flash: flashResponse
+ };
+ }
+
+ abstract run(req: Request, res: Response): Promise;
+}
diff --git a/src/apps/backoffice/frontend/routes/courses.route.ts b/src/apps/backoffice/frontend/routes/courses.route.ts
index 1bf8aa9..c936658 100644
--- a/src/apps/backoffice/frontend/routes/courses.route.ts
+++ b/src/apps/backoffice/frontend/routes/courses.route.ts
@@ -12,5 +12,5 @@ export const register = (app: Express) => {
);
app.get('/courses', coursesGetController.run.bind(coursesGetController));
- app.post('/courses', coursesPostController.run.bind(coursesPostController));
+ app.post('/courses', CoursesPostController.validator(), coursesPostController.run.bind(coursesPostController));
};
diff --git a/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html b/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
index e151e98..167a3fd 100644
--- a/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
+++ b/src/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html
@@ -7,7 +7,7 @@
+ value="{{flash['inputs.id']}}">
{% if flash['errors.id'] %}
{{ flash['errors.id'] }}
@@ -21,7 +21,7 @@
+ value="{{flash['inputs.name']}}">
{% if flash['errors.name'] %}
{{ flash['errors.name'] }}
@@ -33,7 +33,7 @@
+ value="{{flash['inputs.duration']}}">
{% if flash['errors.duration'] %}
{{ flash['errors.duration'] }}
{% endif %}
From c38834663cc21aef467cd3c935ba25cc31efd584 Mon Sep 17 00:00:00 2001
From: Fran Ortiz
Date: Wed, 16 Sep 2020 17:33:25 +0200
Subject: [PATCH 32/48] Add increment courses counter subscriber to backoffice
frontend
---
.../infrastructure/EventBus/EventEmitterBus.ts | 2 +-
src/apps/backoffice/frontend/app.ts | 2 ++
.../config/dependency-injection/application.yaml | 13 +++++++++++++
src/apps/backoffice/frontend/subscribers.ts | 14 ++++++++++++++
4 files changed, 30 insertions(+), 1 deletion(-)
create mode 100644 src/apps/backoffice/frontend/subscribers.ts
diff --git a/src/Contexts/Shared/infrastructure/EventBus/EventEmitterBus.ts b/src/Contexts/Shared/infrastructure/EventBus/EventEmitterBus.ts
index 4cf309f..d528909 100644
--- a/src/Contexts/Shared/infrastructure/EventBus/EventEmitterBus.ts
+++ b/src/Contexts/Shared/infrastructure/EventBus/EventEmitterBus.ts
@@ -17,7 +17,7 @@ export class EventEmitterBus extends EventEmitter {
private registerSubscriber(subscriber: DomainEventSubscriber) {
subscriber.subscribedTo().map(event => {
- this.on(event.EVENT_NAME, subscriber.on);
+ this.on(event.EVENT_NAME, subscriber.on.bind(subscriber));
});
}
diff --git a/src/apps/backoffice/frontend/app.ts b/src/apps/backoffice/frontend/app.ts
index e306c85..5004021 100644
--- a/src/apps/backoffice/frontend/app.ts
+++ b/src/apps/backoffice/frontend/app.ts
@@ -8,6 +8,7 @@ import cookieSession from 'cookie-session';
import cookieParser from 'cookie-parser';
import flash from 'connect-flash';
import nunjucks from 'nunjucks';
+import { registerSubscribers } from './subscribers';
const app: express.Express = express();
@@ -43,5 +44,6 @@ app.use(helmet.frameguard({ action: 'deny' }));
app.use(compress());
registerRoutes(app);
+registerSubscribers();
export default app;
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
index 16fcec8..960ee96 100644
--- a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
@@ -46,6 +46,19 @@ services:
tags:
- { name: 'queryHandler' }
+ Mooc.coursesCounter.CoursesCounterIncrementer:
+ class: ../../../../../Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer
+ arguments: [
+ "@Mooc.coursesCounter.CoursesCounterRepository",
+ "@Mooc.shared.EventBus"
+ ]
+
+ Mooc.coursesCounter.IncrementCoursesCounterOnCourseCreated:
+ class: ../../../../../Contexts/Mooc/CoursesCounter/application/Increment/IncrementCoursesCounterOnCourseCreated
+ arguments: ["@Mooc.coursesCounter.CoursesCounterIncrementer"]
+ tags:
+ - { name: 'domainEventSubscriber' }
+
Mooc.courses.CreateCourseCommandHandler:
class: ../../../../../Contexts/Mooc/Courses/application/CreateCourseCommandHandler
arguments: ['@Mooc.courses.CourseCreator']
diff --git a/src/apps/backoffice/frontend/subscribers.ts b/src/apps/backoffice/frontend/subscribers.ts
new file mode 100644
index 0000000..4c723a7
--- /dev/null
+++ b/src/apps/backoffice/frontend/subscribers.ts
@@ -0,0 +1,14 @@
+import container from './config/dependency-injection';
+import { InMemoryAsyncEventBus } from '../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus';
+import { Definition } from 'node-dependency-injection';
+import { DomainEventSubscriber } from '../../../Contexts/Shared/domain/DomainEventSubscriber';
+import { DomainEvent } from '../../../Contexts/Shared/domain/DomainEvent';
+
+export function registerSubscribers() {
+ const eventBus = container.get('Mooc.shared.EventBus') as InMemoryAsyncEventBus;
+ const subscriberDefinitions = container.findTaggedServiceIds('domainEventSubscriber') as Map;
+ const subscribers: Array> = [];
+
+ subscriberDefinitions.forEach((value: any, key: any) => subscribers.push(container.get(key)));
+ eventBus.addSubscribers(subscribers);
+}
From 8a6455e993148cb85de60ceae5fb71bc81cc2fef Mon Sep 17 00:00:00 2001
From: Fernando Vilas Maciel
Date: Wed, 16 Sep 2020 18:09:22 +0200
Subject: [PATCH 33/48] Bump required nodejs version to 12.x
---
.nvmrc | 1 +
package.json | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 .nvmrc
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..83f2a92
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+v12.18.3
diff --git a/package.json b/package.json
index 9a9d490..47c7fa2 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
},
"license": "",
"engines": {
- "node": ">=10.15.0",
+ "node": ">=12.0.0",
"npm": ">=6.7.0"
},
"scripts": {
From aae93bab45357c804dfd09758efb7afca761fe4f Mon Sep 17 00:00:00 2001
From: Fernando Vilas Maciel
Date: Wed, 16 Sep 2020 18:10:10 +0200
Subject: [PATCH 34/48] Refactor backoffice fronted dependency inyection
---
package-lock.json | 34 ++++++--
package.json | 2 +-
.../Courses/application.yaml | 14 +++
.../CoursesCounter/application.yaml | 24 +++++
.../Shared/application.yaml | 30 +++++++
.../dependency-injection/application.yaml | 87 ++-----------------
.../apps/application.yaml | 11 +++
src/apps/backoffice/frontend/seed.ts | 2 +-
src/apps/backoffice/frontend/server.ts | 2 +-
src/apps/backoffice/frontend/subscribers.ts | 2 +-
.../Courses/application.yaml | 6 +-
.../CoursesCounter/application.yaml | 4 +-
.../Shared/application.yaml | 24 ++---
.../application_test.yaml | 4 +-
.../apps/application.yaml | 4 +-
src/apps/mooc_backend/server.ts | 2 +-
src/apps/mooc_backend/subscribers.ts | 2 +-
.../step_definitions/evenBus.steps.ts | 4 +-
18 files changed, 141 insertions(+), 117 deletions(-)
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/Courses/application.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/CoursesCounter/application.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml
create mode 100644 src/apps/backoffice/frontend/config/dependency-injection/apps/application.yaml
diff --git a/package-lock.json b/package-lock.json
index f220c86..7ef54e9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1823,6 +1823,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
"integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
+ "dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -5031,6 +5032,7 @@
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -5920,15 +5922,35 @@
"integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
},
"node-dependency-injection": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/node-dependency-injection/-/node-dependency-injection-2.6.3.tgz",
- "integrity": "sha512-dUDqVaV6DjZb5dXPkkrC2E1YGf5U7r0y/ZRMak5dz/Rhr8B2j5Gcvcn9XazLnd422WECPcAJbVhwmt52xKlhQw==",
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/node-dependency-injection/-/node-dependency-injection-2.6.8.tgz",
+ "integrity": "sha512-IYHPG2b5sH5Wh+xB2YGYD1UtjmmVgjrMvOTXEhQcifFKCcJwDu5Op5jVafCZ0iBw1VjiLpnU1m8lormamZCsIw==",
"requires": {
- "chalk": "^4.0.0",
- "commander": "^5.0.0",
+ "chalk": "^4.1.0",
+ "commander": "^5.1.0",
"console.table": "^0.10.0",
"fs": "^0.0.2",
- "js-yaml": "^3.13.1"
+ "js-yaml": "^3.14.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "js-yaml": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
+ "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ }
}
},
"node-int64": {
diff --git a/package.json b/package.json
index 47c7fa2..fda7251 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
"http-status": "^1.4.2",
"mandrill-api": "^1.0.45",
"mongodb": "^3.5.7",
- "node-dependency-injection": "^2.6.3",
+ "node-dependency-injection": "^2.6.8",
"nunjucks": "^3.2.1",
"ts-node": "^8.10.1",
"typescript": "^3.9.2",
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/Courses/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/Courses/application.yaml
new file mode 100644
index 0000000..40fddc3
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/Courses/application.yaml
@@ -0,0 +1,14 @@
+services:
+ Mooc.courses.CourseRepository:
+ class: ../../../../../../Contexts/Mooc/Courses/infrastructure/persistence/MongoCourseRepository
+ arguments: ['@Shared.ConnectionManager']
+
+ Mooc.courses.CourseCreator:
+ class: ../../../../../../Contexts/Mooc/Courses/application/CourseCreator
+ arguments: ['@Mooc.courses.CourseRepository', '@Shared.EventBus']
+
+ Mooc.courses.CreateCourseCommandHandler:
+ class: ../../../../../../Contexts/Mooc/Courses/application/CreateCourseCommandHandler
+ arguments: ['@Mooc.courses.CourseCreator']
+ tags:
+ - { name: 'commandHandler' }
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/CoursesCounter/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/CoursesCounter/application.yaml
new file mode 100644
index 0000000..3f1f0ba
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/CoursesCounter/application.yaml
@@ -0,0 +1,24 @@
+services:
+ Mooc.coursesCounter.CoursesCounterFinder:
+ class: ../../../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder
+ arguments: ['@Mooc.coursesCounter.CoursesCounterRepository']
+
+ Mooc.coursesCounter.CoursesCounterRepository:
+ class: ../../../../../../Contexts/Mooc/CoursesCounter/infrastructure/persistence/mongo/MongoCoursesCounterRepository
+ arguments: ['@Shared.ConnectionManager']
+
+ Mooc.coursesCounter.FindCoursesCounterQueryHandler:
+ class: ../../../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler
+ arguments: ['@Mooc.coursesCounter.CoursesCounterFinder']
+ tags:
+ - { name: 'queryHandler' }
+
+ Mooc.coursesCounter.CoursesCounterIncrementer:
+ class: ../../../../../../Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer
+ arguments: ['@Mooc.coursesCounter.CoursesCounterRepository', '@Shared.EventBus']
+
+ Mooc.coursesCounter.IncrementCoursesCounterOnCourseCreated:
+ class: ../../../../../../Contexts/Mooc/CoursesCounter/application/Increment/IncrementCoursesCounterOnCourseCreated
+ arguments: ['@Mooc.coursesCounter.CoursesCounterIncrementer']
+ tags:
+ - { name: 'domainEventSubscriber' }
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml
new file mode 100644
index 0000000..813e2c5
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml
@@ -0,0 +1,30 @@
+services:
+ Shared.Logger:
+ class: ../../../../../../Contexts/Shared/infrastructure/WinstonLogger
+ arguments: []
+
+ Shared.ConnectionManager:
+ factory:
+ class: ../../../../../../Contexts/Shared/infrastructure/persistence/mongo/MongoClientFactory
+ method: 'createClient'
+ arguments: ['mooc']
+
+ Shared.EventBus:
+ class: ../../../../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus
+ arguments: []
+
+ Shared.QueryBus:
+ class: ../../../../../../Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus
+ arguments: ['@Shared.QueryHandlersInformation']
+
+ Shared.CommandBus:
+ class: ../../../../../../Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus
+ arguments: ['@Shared.CommandHandlersInformation']
+
+ Shared.QueryHandlersInformation:
+ class: ../../../../../../Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation
+ arguments: ['!tagged queryHandler']
+
+ Shared.CommandHandlersInformation:
+ class: ../../../../../../Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation
+ arguments: ['!tagged commandHandler']
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
index 960ee96..3bd1a26 100644
--- a/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
+++ b/src/apps/backoffice/frontend/config/dependency-injection/application.yaml
@@ -1,82 +1,5 @@
-services:
- Contexts.shared.Logger:
- class: ../../../../../Contexts/Shared/infrastructure/WinstonLogger
- arguments: []
-
- Apps.Backoffice.Frontend.controllers.HomeGetController:
- class: ../../controllers/HomeGetController
-
- Mooc.coursesCounter.CoursesCounterFinder:
- class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/CoursesCounterFinder
- arguments: ['@Mooc.coursesCounter.CoursesCounterRepository']
-
- Mooc.coursesCounter.CoursesCounterRepository:
- class: ../../../../../Contexts/Mooc/CoursesCounter/infrastructure/persistence/mongo/MongoCoursesCounterRepository
- arguments: ['@Mooc.shared.ConnectionManager']
-
- Mooc.shared.ConnectionManager:
- factory:
- class: ../../../../../Contexts/Shared/infrastructure/persistence/mongo/MongoClientFactory
- method: 'createClient'
- arguments: ['mooc']
-
- Mooc.courses.CourseRepository:
- class: ../../../../../Contexts/Mooc/Courses/infrastructure/persistence/MongoCourseRepository
- arguments: ['@Mooc.shared.ConnectionManager']
-
- Mooc.shared.EventBus:
- class: ../../../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus
- arguments: []
-
- Mooc.courses.CourseCreator:
- class: ../../../../../Contexts/Mooc/Courses/application/CourseCreator
- arguments: ['@Mooc.courses.CourseRepository', '@Mooc.shared.EventBus']
-
- Apps.Backoffice.Frontend.controllers.CoursesGetController:
- class: ../../controllers/CoursesGetController
- arguments: ['@Mooc.shared.QueryBus']
-
- Apps.Backoffice.Frontend.controllers.CoursesPostController:
- class: ../../controllers/CoursesPostController
- arguments: ['@Mooc.shared.CommandBus']
-
- Mooc.coursesCounter.FindCoursesCounterQueryHandler:
- class: ../../../../../Contexts/Mooc/CoursesCounter/application/Find/FindCoursesCounterQueryHandler
- arguments: ['@Mooc.coursesCounter.CoursesCounterFinder']
- tags:
- - { name: 'queryHandler' }
-
- Mooc.coursesCounter.CoursesCounterIncrementer:
- class: ../../../../../Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer
- arguments: [
- "@Mooc.coursesCounter.CoursesCounterRepository",
- "@Mooc.shared.EventBus"
- ]
-
- Mooc.coursesCounter.IncrementCoursesCounterOnCourseCreated:
- class: ../../../../../Contexts/Mooc/CoursesCounter/application/Increment/IncrementCoursesCounterOnCourseCreated
- arguments: ["@Mooc.coursesCounter.CoursesCounterIncrementer"]
- tags:
- - { name: 'domainEventSubscriber' }
-
- Mooc.courses.CreateCourseCommandHandler:
- class: ../../../../../Contexts/Mooc/Courses/application/CreateCourseCommandHandler
- arguments: ['@Mooc.courses.CourseCreator']
- tags:
- - { name: 'commandHandler' }
-
- Mooc.shared.QueryBus:
- class: ../../../../../Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus
- arguments: ['@Mooc.shared.QueryHandlersInformation']
-
- Mooc.shared.CommandBus:
- class: ../../../../../Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus
- arguments: ['@Mooc.shared.CommandHandlersInformation']
-
- Mooc.shared.QueryHandlersInformation:
- class: ../../../../../Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation
- arguments: ['!tagged queryHandler']
-
- Mooc.shared.CommandHandlersInformation:
- class: ../../../../../Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation
- arguments: ['!tagged commandHandler']
+imports:
+ - { resource: ./apps/application.yaml }
+ - { resource: ./Shared/application.yaml }
+ - { resource: ./CoursesCounter/application.yaml }
+ - { resource: ./Courses/application.yaml }
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/apps/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/apps/application.yaml
new file mode 100644
index 0000000..3a37a59
--- /dev/null
+++ b/src/apps/backoffice/frontend/config/dependency-injection/apps/application.yaml
@@ -0,0 +1,11 @@
+services:
+ Apps.Backoffice.Frontend.controllers.HomeGetController:
+ class: ../../../controllers/HomeGetController
+
+ Apps.Backoffice.Frontend.controllers.CoursesGetController:
+ class: ../../../controllers/CoursesGetController
+ arguments: ['@Shared.QueryBus']
+
+ Apps.Backoffice.Frontend.controllers.CoursesPostController:
+ class: ../../../controllers/CoursesPostController
+ arguments: ['@Shared.CommandBus']
diff --git a/src/apps/backoffice/frontend/seed.ts b/src/apps/backoffice/frontend/seed.ts
index a1abc60..03f871f 100644
--- a/src/apps/backoffice/frontend/seed.ts
+++ b/src/apps/backoffice/frontend/seed.ts
@@ -5,7 +5,7 @@ import container from './config/dependency-injection';
export async function seed() {
const repository: CoursesCounterRepository = container.get('Mooc.coursesCounter.CoursesCounterRepository');
- const logger = container.get('Contexts.shared.Logger');
+ const logger = container.get('Shared.Logger');
const alreadyExists = await repository.search();
const isTestEnvironment = process.env.NODE_ENV === 'test';
diff --git a/src/apps/backoffice/frontend/server.ts b/src/apps/backoffice/frontend/server.ts
index 576a1c5..f79e1c0 100644
--- a/src/apps/backoffice/frontend/server.ts
+++ b/src/apps/backoffice/frontend/server.ts
@@ -12,7 +12,7 @@ app.use(errorHandler());
* Start Express server.
*/
const server = app.listen(app.get('port'), async () => {
- const winstonLogger = container.get('Contexts.shared.Logger');
+ const winstonLogger = container.get('Shared.Logger');
await seed();
diff --git a/src/apps/backoffice/frontend/subscribers.ts b/src/apps/backoffice/frontend/subscribers.ts
index 4c723a7..16cbe51 100644
--- a/src/apps/backoffice/frontend/subscribers.ts
+++ b/src/apps/backoffice/frontend/subscribers.ts
@@ -5,7 +5,7 @@ import { DomainEventSubscriber } from '../../../Contexts/Shared/domain/DomainEve
import { DomainEvent } from '../../../Contexts/Shared/domain/DomainEvent';
export function registerSubscribers() {
- const eventBus = container.get('Mooc.shared.EventBus') as InMemoryAsyncEventBus;
+ const eventBus = container.get('Shared.EventBus') as InMemoryAsyncEventBus;
const subscriberDefinitions = container.findTaggedServiceIds('domainEventSubscriber') as Map;
const subscribers: Array> = [];
diff --git a/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml b/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml
index 8acb39e..b0ab7c8 100644
--- a/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/Courses/application.yaml
@@ -2,14 +2,14 @@ services:
Mooc.courses.CourseRepository:
class: ../../../../../Contexts/Mooc/Courses/infrastructure/persistence/MongoCourseRepository
- arguments: ['@Mooc.shared.ConnectionManager']
+ arguments: ['@Shared.ConnectionManager']
Mooc.courses.CourseCreator:
class: ../../../../../Contexts/Mooc/Courses/application/CourseCreator
- arguments: ['@Mooc.courses.CourseRepository', '@Mooc.shared.EventBus']
+ arguments: ['@Mooc.courses.CourseRepository', '@Shared.EventBus']
Mooc.courses.CreateCourseCommandHandler:
class: ../../../../../Contexts/Mooc/Courses/application/CreateCourseCommandHandler
arguments: ['@Mooc.courses.CourseCreator']
tags:
- - { name: 'commandHandler' }
\ No newline at end of file
+ - { name: 'commandHandler' }
diff --git a/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml b/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
index d4457d9..6501720 100644
--- a/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/CoursesCounter/application.yaml
@@ -1,13 +1,13 @@
services:
Mooc.coursesCounter.CoursesCounterRepository:
class: ../../../../../Contexts/Mooc/CoursesCounter/infrastructure/persistence/mongo/MongoCoursesCounterRepository
- arguments: ["@Mooc.shared.ConnectionManager"]
+ arguments: ["@Shared.ConnectionManager"]
Mooc.coursesCounter.CoursesCounterIncrementer:
class: ../../../../../Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer
arguments: [
"@Mooc.coursesCounter.CoursesCounterRepository",
- "@Mooc.shared.EventBus"
+ "@Shared.EventBus"
]
Mooc.coursesCounter.IncrementCoursesCounterOnCourseCreated:
diff --git a/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml b/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
index 624a233..b3f8a05 100644
--- a/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/Shared/application.yaml
@@ -1,38 +1,38 @@
services:
- Mooc.shared.ConnectionManager:
+ Shared.ConnectionManager:
factory:
class: ../../../../../Contexts/Shared/infrastructure/persistence/mongo/MongoClientFactory
method: 'createClient'
arguments: ['mooc']
- Mooc.shared.Logger:
+ Shared.Logger:
class: ../../../../../Contexts/Shared/infrastructure/WinstonLogger
arguments: []
- Mooc.shared.EventBus:
+ Shared.EventBus:
class: ../../../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus
arguments: []
- Mooc.shared.CommandHandlersInformation:
+ Shared.CommandHandlersInformation:
class: ../../../../../Contexts/Shared/infrastructure/CommandBus/CommandHandlersInformation
arguments: ['!tagged commandHandler']
- Mooc.shared.CommandBus:
+ Shared.CommandBus:
class: ../../../../../Contexts/Shared/infrastructure/CommandBus/InMemoryCommandBus
- arguments: ['@Mooc.shared.CommandHandlersInformation']
+ arguments: ['@Shared.CommandHandlersInformation']
- Mooc.shared.EventBus.DomainEventMapping:
+ Shared.EventBus.DomainEventMapping:
class: ../../../../../Contexts/Shared/infrastructure/EventBus/DomainEventMapping
arguments: ['!tagged domainEventSubscriber']
- Mooc.shared.EventBus.DomainEventJsonDeserializer:
+ Shared.EventBus.DomainEventJsonDeserializer:
class: ../../../../../Contexts/Shared/infrastructure/EventBus/DomainEventJsonDeserializer
- arguments: ['@Mooc.shared.EventBus.DomainEventMapping']
+ arguments: ['@Shared.EventBus.DomainEventMapping']
- Mooc.shared.QueryHandlersInformation:
+ Shared.QueryHandlersInformation:
class: ../../../../../Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation
arguments: ['!tagged queryHandler']
- Mooc.shared.QueryBus:
+ Shared.QueryBus:
class: ../../../../../Contexts/Shared/infrastructure/QueryBus/InMemoryQueryBus
- arguments: ['@Mooc.shared.QueryHandlersInformation']
+ arguments: ['@Shared.QueryHandlersInformation']
diff --git a/src/apps/mooc_backend/config/dependency-injection/application_test.yaml b/src/apps/mooc_backend/config/dependency-injection/application_test.yaml
index ad69269..7b87ced 100644
--- a/src/apps/mooc_backend/config/dependency-injection/application_test.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/application_test.yaml
@@ -4,8 +4,8 @@ imports:
services:
Mooc.EnvironmentArranger:
class: ../../../../../tests/Contexts/Shared/infrastructure/mongo/MongoEnvironmentArranger
- arguments: ['@Mooc.shared.ConnectionManager']
+ arguments: ['@Shared.ConnectionManager']
- Mooc.shared.EventBus:
+ Shared.EventBus:
class: ../../../../Contexts/Shared/infrastructure/EventBus/InMemorySyncEventBus
arguments: []
diff --git a/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml b/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
index 131ee62..05e0acd 100644
--- a/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
+++ b/src/apps/mooc_backend/config/dependency-injection/apps/application.yaml
@@ -2,7 +2,7 @@ services:
Apps.mooc.controllers.CoursePutController:
class: ../../../controllers/CoursePutController
- arguments: ["@Mooc.shared.CommandBus"]
+ arguments: ["@Shared.CommandBus"]
Apps.mooc.controllers.StatusGetController:
class: ../../../controllers/StatusGetController
@@ -10,4 +10,4 @@ services:
Apps.mooc.controllers.CoursesCounterGetController:
class: ../../../controllers/CoursesCounterGetController
- arguments: ["@Mooc.shared.QueryBus"]
+ arguments: ["@Shared.QueryBus"]
diff --git a/src/apps/mooc_backend/server.ts b/src/apps/mooc_backend/server.ts
index e980480..fc072a8 100644
--- a/src/apps/mooc_backend/server.ts
+++ b/src/apps/mooc_backend/server.ts
@@ -12,7 +12,7 @@ app.use(errorHandler());
*/
const server = app.listen(app.get('port'), () => {
// tslint:disable: no-console
- const logger = container.get('Mooc.shared.Logger');
+ const logger = container.get('Shared.Logger');
logger.info(` App is running at http://localhost:${app.get('port')} in ${app.get('env')} mode`);
console.log(' Press CTRL-C to stop\n');
diff --git a/src/apps/mooc_backend/subscribers.ts b/src/apps/mooc_backend/subscribers.ts
index 290fcf3..6a7667c 100644
--- a/src/apps/mooc_backend/subscribers.ts
+++ b/src/apps/mooc_backend/subscribers.ts
@@ -5,7 +5,7 @@ import { DomainEventSubscriber } from '../../Contexts/Shared/domain/DomainEventS
import { DomainEvent } from '../../Contexts/Shared/domain/DomainEvent';
export function registerSubscribers() {
- const eventBus = container.get('Mooc.shared.EventBus') as InMemoryAsyncEventBus;
+ const eventBus = container.get('Shared.EventBus') as InMemoryAsyncEventBus;
const subscriberDefinitions = container.findTaggedServiceIds('domainEventSubscriber') as Map;
const subscribers: Array> = [];
diff --git a/tests/apps/mooc_backend/features/step_definitions/evenBus.steps.ts b/tests/apps/mooc_backend/features/step_definitions/evenBus.steps.ts
index 751ff59..22d10bb 100644
--- a/tests/apps/mooc_backend/features/step_definitions/evenBus.steps.ts
+++ b/tests/apps/mooc_backend/features/step_definitions/evenBus.steps.ts
@@ -3,8 +3,8 @@ import container from '../../../../../src/apps/mooc_backend/config/dependency-in
import { EventBus } from '../../../../../src/Contexts/Shared/domain/EventBus';
import { DomainEventJsonDeserializer } from '../../../../../src/Contexts/Shared/infrastructure/EventBus/DomainEventJsonDeserializer';
-const eventBus = container.get('Mooc.shared.EventBus') as EventBus;
-const deserializer = container.get('Mooc.shared.EventBus.DomainEventJsonDeserializer') as DomainEventJsonDeserializer;
+const eventBus = container.get('Shared.EventBus') as EventBus;
+const deserializer = container.get('Shared.EventBus.DomainEventJsonDeserializer') as DomainEventJsonDeserializer;
Given('I send an event to the event bus:', async (event: any) => {
const domainEvent = deserializer.deserialize(event);
From 2bdb81f930982c3af9d6aae22510e9929a9065f5 Mon Sep 17 00:00:00 2001
From: Fernando Vilas Maciel
Date: Wed, 16 Sep 2020 18:33:13 +0200
Subject: [PATCH 35/48] Update dependencies
---
package-lock.json | 2882 ++++++++++++++++++++++++++-------------------
package.json | 52 +-
2 files changed, 1698 insertions(+), 1236 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7ef54e9..8b6ac16 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,33 +5,33 @@
"requires": true,
"dependencies": {
"@babel/code-frame": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
- "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.8.3"
+ "@babel/highlight": "^7.10.4"
}
},
"@babel/core": {
- "version": "7.9.6",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz",
- "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.8.3",
- "@babel/generator": "^7.9.6",
- "@babel/helper-module-transforms": "^7.9.0",
- "@babel/helpers": "^7.9.6",
- "@babel/parser": "^7.9.6",
- "@babel/template": "^7.8.6",
- "@babel/traverse": "^7.9.6",
- "@babel/types": "^7.9.6",
+ "version": "7.11.6",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz",
+ "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.11.6",
+ "@babel/helper-module-transforms": "^7.11.0",
+ "@babel/helpers": "^7.10.4",
+ "@babel/parser": "^7.11.5",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.11.5",
+ "@babel/types": "^7.11.5",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.1",
"json5": "^2.1.2",
- "lodash": "^4.17.13",
+ "lodash": "^4.17.19",
"resolve": "^1.3.2",
"semver": "^5.4.1",
"source-map": "^0.5.0"
@@ -46,6 +46,12 @@
"ms": "^2.1.1"
}
},
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -61,14 +67,13 @@
}
},
"@babel/generator": {
- "version": "7.9.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
- "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
+ "version": "7.11.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz",
+ "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==",
"dev": true,
"requires": {
- "@babel/types": "^7.9.6",
+ "@babel/types": "^7.11.5",
"jsesc": "^2.5.1",
- "lodash": "^4.17.13",
"source-map": "^0.5.0"
},
"dependencies": {
@@ -81,128 +86,136 @@
}
},
"@babel/helper-function-name": {
- "version": "7.9.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
- "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+ "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.8.3",
- "@babel/template": "^7.8.3",
- "@babel/types": "^7.9.5"
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
- "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+ "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
"dev": true,
"requires": {
- "@babel/types": "^7.8.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-member-expression-to-functions": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz",
- "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz",
+ "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==",
"dev": true,
"requires": {
- "@babel/types": "^7.8.3"
+ "@babel/types": "^7.11.0"
}
},
"@babel/helper-module-imports": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz",
- "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz",
+ "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==",
"dev": true,
"requires": {
- "@babel/types": "^7.8.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-module-transforms": {
- "version": "7.9.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz",
- "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==",
- "dev": true,
- "requires": {
- "@babel/helper-module-imports": "^7.8.3",
- "@babel/helper-replace-supers": "^7.8.6",
- "@babel/helper-simple-access": "^7.8.3",
- "@babel/helper-split-export-declaration": "^7.8.3",
- "@babel/template": "^7.8.6",
- "@babel/types": "^7.9.0",
- "lodash": "^4.17.13"
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz",
+ "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.10.4",
+ "@babel/helper-simple-access": "^7.10.4",
+ "@babel/helper-split-export-declaration": "^7.11.0",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.11.0",
+ "lodash": "^4.17.19"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ }
}
},
"@babel/helper-optimise-call-expression": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz",
- "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz",
+ "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==",
"dev": true,
"requires": {
- "@babel/types": "^7.8.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-plugin-utils": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
- "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
"dev": true
},
"@babel/helper-replace-supers": {
- "version": "7.9.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz",
- "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz",
+ "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==",
"dev": true,
"requires": {
- "@babel/helper-member-expression-to-functions": "^7.8.3",
- "@babel/helper-optimise-call-expression": "^7.8.3",
- "@babel/traverse": "^7.9.6",
- "@babel/types": "^7.9.6"
+ "@babel/helper-member-expression-to-functions": "^7.10.4",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-simple-access": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz",
- "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz",
+ "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==",
"dev": true,
"requires": {
- "@babel/template": "^7.8.3",
- "@babel/types": "^7.8.3"
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
- "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+ "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
"dev": true,
"requires": {
- "@babel/types": "^7.8.3"
+ "@babel/types": "^7.11.0"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.9.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
- "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
"dev": true
},
"@babel/helpers": {
- "version": "7.9.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz",
- "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz",
+ "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==",
"dev": true,
"requires": {
- "@babel/template": "^7.8.3",
- "@babel/traverse": "^7.9.6",
- "@babel/types": "^7.9.6"
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/highlight": {
- "version": "7.9.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
- "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.9.0",
+ "@babel/helper-validator-identifier": "^7.10.4",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
},
@@ -266,9 +279,9 @@
}
},
"@babel/parser": {
- "version": "7.9.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
- "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
+ "version": "7.11.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz",
+ "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==",
"dev": true
},
"@babel/plugin-syntax-async-generators": {
@@ -290,12 +303,21 @@
}
},
"@babel/plugin-syntax-class-properties": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz",
- "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz",
+ "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-json-strings": {
@@ -308,12 +330,12 @@
}
},
"@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz",
- "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-nullish-coalescing-operator": {
@@ -326,12 +348,12 @@
}
},
"@babel/plugin-syntax-numeric-separator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz",
- "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-object-rest-spread": {
@@ -372,31 +394,31 @@
}
},
"@babel/template": {
- "version": "7.8.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
- "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+ "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.8.3",
- "@babel/parser": "^7.8.6",
- "@babel/types": "^7.8.6"
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/traverse": {
- "version": "7.9.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
- "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
+ "version": "7.11.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz",
+ "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.8.3",
- "@babel/generator": "^7.9.6",
- "@babel/helper-function-name": "^7.9.5",
- "@babel/helper-split-export-declaration": "^7.8.3",
- "@babel/parser": "^7.9.6",
- "@babel/types": "^7.9.6",
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.11.5",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-split-export-declaration": "^7.11.0",
+ "@babel/parser": "^7.11.5",
+ "@babel/types": "^7.11.5",
"debug": "^4.1.0",
"globals": "^11.1.0",
- "lodash": "^4.17.13"
+ "lodash": "^4.17.19"
},
"dependencies": {
"debug": {
@@ -408,6 +430,12 @@
"ms": "^2.1.1"
}
},
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -417,14 +445,22 @@
}
},
"@babel/types": {
- "version": "7.9.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
- "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+ "version": "7.11.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz",
+ "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.9.5",
- "lodash": "^4.17.13",
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
"to-fast-properties": "^2.0.0"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ }
}
},
"@bcoe/v8-coverage": {
@@ -443,14 +479,25 @@
"minimist": "^1.2.0"
}
},
+ "@dabh/diagnostics": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz",
+ "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==",
+ "requires": {
+ "colorspace": "1.1.x",
+ "enabled": "2.0.x",
+ "kuler": "^2.0.0"
+ }
+ },
"@istanbuljs/load-nyc-config": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
- "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
"dev": true,
"requires": {
"camelcase": "^5.3.1",
"find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
"js-yaml": "^3.13.1",
"resolve-from": "^5.0.0"
},
@@ -470,60 +517,82 @@
"dev": true
},
"@jest/console": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz",
- "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.3.0.tgz",
+ "integrity": "sha512-/5Pn6sJev0nPUcAdpJHMVIsA8sKizL2ZkcKPE5+dJrCccks7tcM7c9wbgHudBJbxXLoTbqsHkG1Dofoem4F09w==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
"chalk": "^4.0.0",
- "jest-message-util": "^26.0.1",
- "jest-util": "^26.0.1",
+ "jest-message-util": "^26.3.0",
+ "jest-util": "^26.3.0",
"slash": "^3.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"@jest/core": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz",
- "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.4.2.tgz",
+ "integrity": "sha512-sDva7YkeNprxJfepOctzS8cAk9TOekldh+5FhVuXS40+94SHbiicRO1VV2tSoRtgIo+POs/Cdyf8p76vPTd6dg==",
"dev": true,
"requires": {
- "@jest/console": "^26.0.1",
- "@jest/reporters": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/console": "^26.3.0",
+ "@jest/reporters": "^26.4.1",
+ "@jest/test-result": "^26.3.0",
+ "@jest/transform": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-changed-files": "^26.0.1",
- "jest-config": "^26.0.1",
- "jest-haste-map": "^26.0.1",
- "jest-message-util": "^26.0.1",
+ "jest-changed-files": "^26.3.0",
+ "jest-config": "^26.4.2",
+ "jest-haste-map": "^26.3.0",
+ "jest-message-util": "^26.3.0",
"jest-regex-util": "^26.0.0",
- "jest-resolve": "^26.0.1",
- "jest-resolve-dependencies": "^26.0.1",
- "jest-runner": "^26.0.1",
- "jest-runtime": "^26.0.1",
- "jest-snapshot": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
- "jest-watcher": "^26.0.1",
+ "jest-resolve": "^26.4.0",
+ "jest-resolve-dependencies": "^26.4.2",
+ "jest-runner": "^26.4.2",
+ "jest-runtime": "^26.4.2",
+ "jest-snapshot": "^26.4.2",
+ "jest-util": "^26.3.0",
+ "jest-validate": "^26.4.2",
+ "jest-watcher": "^26.3.0",
"micromatch": "^4.0.2",
"p-each-series": "^2.1.0",
"rimraf": "^3.0.0",
@@ -532,17 +601,37 @@
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
@@ -555,133 +644,215 @@
}
},
"@jest/environment": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz",
- "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz",
+ "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==",
"dev": true,
"requires": {
- "@jest/fake-timers": "^26.0.1",
- "@jest/types": "^26.0.1",
- "jest-mock": "^26.0.1"
+ "@jest/fake-timers": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
+ "jest-mock": "^26.3.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"@jest/fake-timers": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz",
- "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz",
+ "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"@sinonjs/fake-timers": "^6.0.1",
- "jest-message-util": "^26.0.1",
- "jest-mock": "^26.0.1",
- "jest-util": "^26.0.1"
+ "@types/node": "*",
+ "jest-message-util": "^26.3.0",
+ "jest-mock": "^26.3.0",
+ "jest-util": "^26.3.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"@jest/globals": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz",
- "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.4.2.tgz",
+ "integrity": "sha512-Ot5ouAlehhHLRhc+sDz2/9bmNv9p5ZWZ9LE1pXGGTCXBasmi5jnYjlgYcYt03FBwLmZXCZ7GrL29c33/XRQiow==",
"dev": true,
"requires": {
- "@jest/environment": "^26.0.1",
- "@jest/types": "^26.0.1",
- "expect": "^26.0.1"
+ "@jest/environment": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "expect": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"@jest/reporters": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz",
- "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==",
+ "version": "26.4.1",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.4.1.tgz",
+ "integrity": "sha512-aROTkCLU8++yiRGVxLsuDmZsQEKO6LprlrxtAuzvtpbIFl3eIjgIf3EUxDKgomkS25R9ZzwGEdB5weCcBZlrpQ==",
"dev": true,
"requires": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/console": "^26.3.0",
+ "@jest/test-result": "^26.3.0",
+ "@jest/transform": "^26.3.0",
+ "@jest/types": "^26.3.0",
"chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
"exit": "^0.1.2",
"glob": "^7.1.2",
"graceful-fs": "^4.2.4",
"istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^4.0.0",
+ "istanbul-lib-instrument": "^4.0.3",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.0",
"istanbul-reports": "^3.0.2",
- "jest-haste-map": "^26.0.1",
- "jest-resolve": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-worker": "^26.0.0",
- "node-notifier": "^7.0.0",
+ "jest-haste-map": "^26.3.0",
+ "jest-resolve": "^26.4.0",
+ "jest-util": "^26.3.0",
+ "jest-worker": "^26.3.0",
+ "node-notifier": "^8.0.0",
"slash": "^3.0.0",
"source-map": "^0.6.0",
"string-length": "^4.0.1",
"terminal-link": "^2.0.0",
- "v8-to-istanbul": "^4.1.3"
+ "v8-to-istanbul": "^5.0.1"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"@jest/source-map": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz",
- "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.3.0.tgz",
+ "integrity": "sha512-hWX5IHmMDWe1kyrKl7IhFwqOuAreIwHhbe44+XH2ZRHjrKIh0LO5eLQ/vxHFeAfRwJapmxuqlGAEYLadDq6ZGQ==",
"dev": true,
"requires": {
"callsites": "^3.0.0",
@@ -690,60 +861,80 @@
}
},
"@jest/test-result": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz",
- "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz",
+ "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==",
"dev": true,
"requires": {
- "@jest/console": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/console": "^26.3.0",
+ "@jest/types": "^26.3.0",
"@types/istanbul-lib-coverage": "^2.0.0",
"collect-v8-coverage": "^1.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"@jest/test-sequencer": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz",
- "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.4.2.tgz",
+ "integrity": "sha512-83DRD8N3M0tOhz9h0bn6Kl6dSp+US6DazuVF8J9m21WAp5x7CqSMaNycMP0aemC/SH/pDQQddbsfHRTBXVUgog==",
"dev": true,
"requires": {
- "@jest/test-result": "^26.0.1",
+ "@jest/test-result": "^26.3.0",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^26.0.1",
- "jest-runner": "^26.0.1",
- "jest-runtime": "^26.0.1"
+ "jest-haste-map": "^26.3.0",
+ "jest-runner": "^26.4.2",
+ "jest-runtime": "^26.4.2"
}
},
"@jest/transform": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz",
- "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.3.0.tgz",
+ "integrity": "sha512-Isj6NB68QorGoFWvcOjlUhpkT56PqNIsXKR7XfvoDlCANn/IANlh8DrKAA2l2JKC3yWSMH5wS0GwuQM20w3b2A==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"babel-plugin-istanbul": "^6.0.0",
"chalk": "^4.0.0",
"convert-source-map": "^1.4.0",
"fast-json-stable-stringify": "^2.0.0",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^26.0.1",
+ "jest-haste-map": "^26.3.0",
"jest-regex-util": "^26.0.0",
- "jest-util": "^26.0.1",
+ "jest-util": "^26.3.0",
"micromatch": "^4.0.2",
"pirates": "^4.0.1",
"slash": "^3.0.0",
@@ -752,16 +943,36 @@
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
@@ -775,33 +986,12 @@
"@types/istanbul-reports": "^1.1.1",
"@types/yargs": "^15.0.0",
"chalk": "^3.0.0"
- },
- "dependencies": {
- "chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- }
- }
- },
- "@samverschueren/stream-to-observable": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz",
- "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==",
- "dev": true,
- "requires": {
- "any-observable": "^0.3.0"
}
},
"@sinonjs/commons": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz",
- "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==",
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
+ "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==",
"dev": true,
"requires": {
"type-detect": "4.0.8"
@@ -817,15 +1007,15 @@
}
},
"@types/aws-lambda": {
- "version": "8.10.51",
- "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.51.tgz",
- "integrity": "sha512-XK7RerpXj4r+IO0r7qIeNqUSU6L4qhPMwNhISxozJJiUX/jdXj9WYzTShRVisEcUQHXgJ4TTBqTArM8f9Mjb8g==",
+ "version": "8.10.62",
+ "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.62.tgz",
+ "integrity": "sha512-43XhJY5jvyH03U0cRsSqeHWhvmGZNoLzTPSAZ3JAqgG9p20uw+Sx9Auk5OAefJajd9ZcfjDJ/9lJ2BiBxfKJRw==",
"dev": true
},
"@types/babel__core": {
- "version": "7.1.7",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz",
- "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==",
+ "version": "7.1.9",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz",
+ "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==",
"dev": true,
"requires": {
"@babel/parser": "^7.1.0",
@@ -855,9 +1045,9 @@
}
},
"@types/babel__traverse": {
- "version": "7.0.11",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz",
- "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==",
+ "version": "7.0.14",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.14.tgz",
+ "integrity": "sha512-8w9szzKs14ZtBVuP6Wn7nMLRJ0D6dfB0VEBEyRgxrZ/Ln49aNMykrghM2FaNn4FJRzNppCSa0Rv9pBRM5Xc3wg==",
"dev": true,
"requires": {
"@babel/types": "^7.3.0"
@@ -957,15 +1147,10 @@
"@types/express": "*"
}
},
- "@types/events": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
- "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
- },
"@types/express": {
- "version": "4.17.6",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.6.tgz",
- "integrity": "sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w==",
+ "version": "4.17.8",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.8.tgz",
+ "integrity": "sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ==",
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "*",
@@ -974,9 +1159,9 @@
}
},
"@types/express-serve-static-core": {
- "version": "4.17.7",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.7.tgz",
- "integrity": "sha512-EMgTj/DF9qpgLXyc+Btimg+XoH7A2liE8uKul8qSmMTHCeNYzydDKFdsJskDvw42UsesCnhO63dO0Grbj8J4Dw==",
+ "version": "4.17.12",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.12.tgz",
+ "integrity": "sha512-EaEdY+Dty1jEU7U6J4CUWwxL+hyEGMkO5jan5gplfegUgCUsIUWqXxqw47uGjimeT4Qgkz/XUfwoau08+fgvKA==",
"requires": {
"@types/node": "*",
"@types/qs": "*",
@@ -984,17 +1169,16 @@
}
},
"@types/faker": {
- "version": "4.1.12",
- "resolved": "https://registry.npmjs.org/@types/faker/-/faker-4.1.12.tgz",
- "integrity": "sha512-0MEyzJrLLs1WaOCx9ULK6FzdCSj2EuxdSP9kvuxxdBEGujZYUOZ4vkPXdgu3dhyg/pOdn7VCatelYX7k0YShlA==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.0.tgz",
+ "integrity": "sha512-7iK+rNvtSmG3FcAgI67BphmQVzBPkI6SCjJqR/SXxGr6tDUoMovkhGYIxNICEfy/trTgiGQL2v1tKPuFEXIrQg==",
"dev": true
},
"@types/glob": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
- "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
"requires": {
- "@types/events": "*",
"@types/minimatch": "*",
"@types/node": "*"
}
@@ -1009,17 +1193,17 @@
}
},
"@types/helmet": {
- "version": "0.0.47",
- "resolved": "https://registry.npmjs.org/@types/helmet/-/helmet-0.0.47.tgz",
- "integrity": "sha512-TcHA/djjdUtrMtq/QAayVLrsgjNNZ1Uhtz0KhfH01mrmjH44E54DA1A0HNbwW0H/NBFqV+tGMo85ACuEhMXcdg==",
+ "version": "0.0.48",
+ "resolved": "https://registry.npmjs.org/@types/helmet/-/helmet-0.0.48.tgz",
+ "integrity": "sha512-C7MpnvSDrunS1q2Oy1VWCY7CDWHozqSnM8P4tFeRTuzwqni+PYOjEredwcqWG+kLpYcgLsgcY3orHB54gbx2Jw==",
"requires": {
"@types/express": "*"
}
},
"@types/istanbul-lib-coverage": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz",
- "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
+ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==",
"dev": true
},
"@types/istanbul-lib-report": {
@@ -1042,9 +1226,9 @@
}
},
"@types/jest": {
- "version": "25.2.3",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz",
- "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==",
+ "version": "26.0.14",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.14.tgz",
+ "integrity": "sha512-Hz5q8Vu0D288x3iWXePSn53W7hAjP0H7EQ6QvDO9c7t46mR0lNOLlfuwQ+JkVxuhygHzlzPX+0jKdA3ZgSh+Vg==",
"dev": true,
"requires": {
"jest-diff": "^25.2.1",
@@ -1058,9 +1242,9 @@
"dev": true
},
"@types/mime": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.2.tgz",
- "integrity": "sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q=="
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
+ "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q=="
},
"@types/minimatch": {
"version": "3.0.3",
@@ -1068,18 +1252,18 @@
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
},
"@types/mongodb": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.5.18.tgz",
- "integrity": "sha512-fEmnRmwXt4pEFhqWB/ZlyNaDhLfQv5GALaZAlH9Pb0kEttvsCr66umJ9pfBEEP3ks1hjlwAuMtqk/+DyZDLAXQ==",
+ "version": "3.5.27",
+ "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.5.27.tgz",
+ "integrity": "sha512-1jxKDgdfJEOO9zp+lv43p8jOqRs02xPrdUTzAZIVK9tVEySfCEmktL2jEu9A3wOBEOs18yKzpVIKUh8b8ALk3w==",
"requires": {
"@types/bson": "*",
"@types/node": "*"
}
},
"@types/node": {
- "version": "14.0.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.3.tgz",
- "integrity": "sha512-a8TR2N5VEJCL9HEJrAfwv3UI1bZq50HydowDDVV6pfnY7ZwG5Pjii+nSDhrDtGW3XKMoVKOgG8zS/Kv5j399uA=="
+ "version": "14.10.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.10.2.tgz",
+ "integrity": "sha512-IzMhbDYCpv26pC2wboJ4MMOa9GKtjplXfcAqrMeNJpUUwpM/2ATt2w1JPUXwS6spu856TvKZL2AOmeU2rAxskw=="
},
"@types/normalize-package-data": {
"version": "2.4.0",
@@ -1100,15 +1284,15 @@
"dev": true
},
"@types/prettier": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.0.tgz",
- "integrity": "sha512-/rM+sWiuOZ5dvuVzV37sUuklsbg+JPOP8d+nNFlo2ZtfpzPiPvh1/gc8liWOLBqe+sR+ZM7guPaIcTt6UZTo7Q==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.1.tgz",
+ "integrity": "sha512-2zs+O+UkDsJ1Vcp667pd3f8xearMdopz/z54i99wtRDI5KLmngk7vlrYZD0ZjKHaROR03EznlBbVY9PfAEyJIQ==",
"dev": true
},
"@types/qs": {
- "version": "6.9.3",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.3.tgz",
- "integrity": "sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA=="
+ "version": "6.9.4",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.4.tgz",
+ "integrity": "sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ=="
},
"@types/range-parser": {
"version": "1.2.3",
@@ -1116,9 +1300,9 @@
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
},
"@types/serve-static": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.4.tgz",
- "integrity": "sha512-jTDt0o/YbpNwZbQmE/+2e+lfjJEJJR0I3OFaKQKPWkASkCoW3i6fsUnqudSMcNAfbtmADGu8f4MV4q+GqULmug==",
+ "version": "1.13.5",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.5.tgz",
+ "integrity": "sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ==",
"requires": {
"@types/express-serve-static-core": "*",
"@types/mime": "*"
@@ -1143,9 +1327,9 @@
"dev": true
},
"@types/superagent": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.7.tgz",
- "integrity": "sha512-JSwNPgRYjIC4pIeOqLwWwfGj6iP1n5NE6kNBEbGx2V8H78xCPwx7QpNp9plaI30+W3cFEzJO7BIIsXE+dbtaGg==",
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.10.tgz",
+ "integrity": "sha512-xAgkb2CMWUMCyVc/3+7iQfOEBE75NvuZeezvmixbUw3nmENf2tCnQkW5yQLTYqvXUQ+R6EXxdqKKbal2zM5V/g==",
"dev": true,
"requires": {
"@types/cookiejar": "*",
@@ -1153,18 +1337,18 @@
}
},
"@types/supertest": {
- "version": "2.0.9",
- "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.9.tgz",
- "integrity": "sha512-0BTpWWWAO1+uXaP/oA0KW1eOZv4hc0knhrWowV06Gwwz3kqQxNO98fUFM2e15T+PdPRmOouNFrYvaBgdojPJ3g==",
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.10.tgz",
+ "integrity": "sha512-Xt8TbEyZTnD5Xulw95GLMOkmjGICrOQyJ2jqgkSjAUR3mm7pAIzSR0NFBaMcwlzVvlpCjNwbATcWWwjNiZiFrQ==",
"dev": true,
"requires": {
"@types/superagent": "*"
}
},
"@types/uuid": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.0.0.tgz",
- "integrity": "sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw=="
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ=="
},
"@types/uuid-validate": {
"version": "0.0.1",
@@ -1192,9 +1376,9 @@
"integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA=="
},
"abab": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
- "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
"dev": true
},
"accepts": {
@@ -1207,9 +1391,9 @@
}
},
"acorn": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
- "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
+ "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
"dev": true
},
"acorn-globals": {
@@ -1223,15 +1407,15 @@
}
},
"acorn-walk": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz",
- "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
"dev": true
},
"aggregate-error": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
- "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
"dev": true,
"requires": {
"clean-stack": "^2.0.0",
@@ -1239,9 +1423,9 @@
}
},
"ajv": {
- "version": "6.12.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
- "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
+ "version": "6.12.5",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
+ "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@@ -1251,9 +1435,9 @@
}
},
"ansi-colors": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
- "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
"ansi-escapes": {
@@ -1301,12 +1485,6 @@
"resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768="
},
- "any-observable": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
- "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
- "dev": true
- },
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
@@ -1413,12 +1591,9 @@
"dev": true
},
"async": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
- "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
- "requires": {
- "lodash": "^4.17.14"
- }
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
+ "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
},
"async-array-reduce": {
"version": "0.2.1",
@@ -1449,38 +1624,58 @@
"dev": true
},
"aws4": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
- "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz",
+ "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
"dev": true
},
"babel-jest": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz",
- "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.3.0.tgz",
+ "integrity": "sha512-sxPnQGEyHAOPF8NcUsD0g7hDCnvLL2XyblRBcgrzTWBB/mAIpWow3n1bEL+VghnnZfreLhFSBsFluRoK2tRK4g==",
"dev": true,
"requires": {
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/transform": "^26.3.0",
+ "@jest/types": "^26.3.0",
"@types/babel__core": "^7.1.7",
"babel-plugin-istanbul": "^6.0.0",
- "babel-preset-jest": "^26.0.0",
+ "babel-preset-jest": "^26.3.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"slash": "^3.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
@@ -1498,25 +1693,27 @@
}
},
"babel-plugin-jest-hoist": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz",
- "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==",
+ "version": "26.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz",
+ "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==",
"dev": true,
"requires": {
"@babel/template": "^7.3.3",
"@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.0.0",
"@types/babel__traverse": "^7.0.6"
}
},
"babel-preset-current-node-syntax": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz",
- "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==",
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz",
+ "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==",
"dev": true,
"requires": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-bigint": "^7.8.3",
"@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
"@babel/plugin-syntax-json-strings": "^7.8.3",
"@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
@@ -1527,13 +1724,13 @@
}
},
"babel-preset-jest": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz",
- "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.3.0.tgz",
+ "integrity": "sha512-5WPdf7nyYi2/eRxCbVrE1kKCWxgWY4RsPEbdJWFm7QsesFGqjdkyLeu1zRkwM1cxK6EPIlNd6d2AxLk7J+t4pw==",
"dev": true,
"requires": {
- "babel-plugin-jest-hoist": "^26.0.0",
- "babel-preset-current-node-syntax": "^0.1.2"
+ "babel-plugin-jest-hoist": "^26.2.0",
+ "babel-preset-current-node-syntax": "^0.1.3"
}
},
"balanced-match": {
@@ -1629,15 +1826,14 @@
"dev": true
},
"binary-extensions": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
- "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
- "optional": true
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ=="
},
"bl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
- "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
+ "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==",
"requires": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
@@ -1665,11 +1861,6 @@
"type-is": "~1.6.17"
}
},
- "bowser": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz",
- "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA=="
- },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1712,9 +1903,9 @@
}
},
"bson": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-4.0.4.tgz",
- "integrity": "sha512-Ioi3TD0/1V3aI8+hPfC56TetYmzfq2H07jJa9A1lKTxWsFtHtYdLMGMXjtGEg9v0f72NSM07diRQEUNYhLupIA==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-4.1.0.tgz",
+ "integrity": "sha512-xwNzRRsK2xmHvHuPESi0zVfgsm4edO47WdulNaShTriunNUMRDOAlKwpJc8zpkOXczIzbxUD7kFzhUGVYoZLDw==",
"requires": {
"buffer": "^5.1.0",
"long": "^4.0.0"
@@ -1799,11 +1990,6 @@
}
}
},
- "camelize": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
- "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
- },
"capture-exit": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
@@ -1820,9 +2006,9 @@
"dev": true
},
"chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -1836,10 +2022,9 @@
"dev": true
},
"chokidar": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
- "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
- "optional": true,
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
+ "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==",
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
@@ -1855,7 +2040,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
- "optional": true,
"requires": {
"is-glob": "^4.0.1"
}
@@ -1863,14 +2047,12 @@
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "optional": true
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
- "optional": true,
"requires": {
"is-extglob": "^2.1.1"
}
@@ -2084,11 +2266,6 @@
"simple-swizzle": "^0.2.2"
}
},
- "colornames": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
- "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y="
- },
"colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
@@ -2184,11 +2361,6 @@
"safe-buffer": "5.1.2"
}
},
- "content-security-policy-builder": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz",
- "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ=="
- },
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
@@ -2302,16 +2474,16 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cosmiconfig": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
- "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
+ "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
"dev": true,
"requires": {
"@types/parse-json": "^4.0.0",
- "import-fresh": "^3.1.0",
+ "import-fresh": "^3.2.1",
"parse-json": "^5.0.0",
"path-type": "^4.0.0",
- "yaml": "^1.7.2"
+ "yaml": "^1.10.0"
}
},
"cross-spawn": {
@@ -2443,11 +2615,6 @@
"assert-plus": "^1.0.0"
}
},
- "dasherize": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
- "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
- },
"data-urls": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
@@ -2469,12 +2636,6 @@
"meow": "^3.3.0"
}
},
- "debounce": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz",
- "integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==",
- "dev": true
- },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -2522,6 +2683,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+ "optional": true,
"requires": {
"clone": "^1.0.2"
}
@@ -2561,16 +2723,6 @@
"integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
"dev": true
},
- "diagnostics": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
- "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
- "requires": {
- "colorspace": "1.1.x",
- "enabled": "1.0.x",
- "kuler": "1.0.x"
- }
- },
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -2582,11 +2734,6 @@
"integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==",
"dev": true
},
- "dns-prefetch-control": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz",
- "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q=="
- },
"doctrine": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz",
@@ -2628,11 +2775,6 @@
}
}
},
- "dont-sniff-mimetype": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz",
- "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug=="
- },
"duration": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz",
@@ -2675,10 +2817,10 @@
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
- "elegant-spinner": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-2.0.0.tgz",
- "integrity": "sha512-5YRYHhvhYzV/FC4AiMdeSIg3jAYGq9xFvbhZMpPlJoBsfYgrw2DSCYeXfat6tYBu45PWiyRr3+flaCPPmviPaA==",
+ "emittery": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz",
+ "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==",
"dev": true
},
"emoji-regex": {
@@ -2688,12 +2830,9 @@
"dev": true
},
"enabled": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
- "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
- "requires": {
- "env-variable": "0.0.x"
- }
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
+ "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
},
"encodeurl": {
"version": "1.0.2",
@@ -2710,19 +2849,14 @@
}
},
"enquirer": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz",
- "integrity": "sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA==",
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true,
"requires": {
- "ansi-colors": "^3.2.1"
+ "ansi-colors": "^4.1.1"
}
},
- "env-variable": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz",
- "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg=="
- },
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -2802,9 +2936,9 @@
"dev": true
},
"escodegen": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz",
- "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==",
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
+ "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
"dev": true,
"requires": {
"esprima": "^4.0.1",
@@ -2855,6 +2989,14 @@
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
+ },
+ "dependencies": {
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ }
}
},
"exit": {
@@ -2887,44 +3029,59 @@
}
},
"expect": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz",
- "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz",
+ "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-styles": "^4.0.0",
- "jest-get-type": "^26.0.0",
- "jest-matcher-utils": "^26.0.1",
- "jest-message-util": "^26.0.1",
+ "jest-get-type": "^26.3.0",
+ "jest-matcher-utils": "^26.4.2",
+ "jest-message-util": "^26.3.0",
"jest-regex-util": "^26.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
}
}
},
- "expect-ct": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz",
- "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g=="
- },
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
@@ -3078,15 +3235,15 @@
"dev": true
},
"faker": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz",
- "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/faker/-/faker-5.1.0.tgz",
+ "integrity": "sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw==",
"dev": true
},
"fast-deep-equal": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
- "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-json-stable-stringify": {
@@ -3115,15 +3272,10 @@
"bser": "2.1.1"
}
},
- "feature-policy": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz",
- "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ=="
- },
"fecha": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
- "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz",
+ "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg=="
},
"figures": {
"version": "3.2.0",
@@ -3172,15 +3324,6 @@
"through2": "^2.0.1"
}
},
- "filewatcher": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz",
- "integrity": "sha1-9KGVc1Xdr0Q8zXiolfPVXiPIoDQ=",
- "dev": true,
- "requires": {
- "debounce": "^1.0.0"
- }
- },
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -3222,6 +3365,11 @@
"semver-regex": "^2.0.0"
}
},
+ "fn.name": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
+ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
+ },
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -3265,11 +3413,6 @@
"map-cache": "^0.2.2"
}
},
- "frameguard": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz",
- "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g=="
- },
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -3314,6 +3457,12 @@
"integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
"dev": true
},
+ "get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true
+ },
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
@@ -3406,7 +3555,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"har-schema": {
"version": "2.0.0",
@@ -3415,12 +3565,12 @@
"dev": true
},
"har-validator": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
- "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"dev": true,
"requires": {
- "ajv": "^6.5.5",
+ "ajv": "^6.12.3",
"har-schema": "^2.0.0"
}
},
@@ -3498,54 +3648,9 @@
}
},
"helmet": {
- "version": "3.22.0",
- "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.22.0.tgz",
- "integrity": "sha512-Xrqicn2nm1ZIUxP3YGuTBmbDL04neKsIT583Sjh0FkiwKDXYCMUqGqC88w3NUvVXtA75JyR2Jn6jw6ZEMOD+ZA==",
- "requires": {
- "depd": "2.0.0",
- "dns-prefetch-control": "0.2.0",
- "dont-sniff-mimetype": "1.1.0",
- "expect-ct": "0.2.0",
- "feature-policy": "0.3.0",
- "frameguard": "3.1.0",
- "helmet-crossdomain": "0.4.0",
- "helmet-csp": "2.10.0",
- "hide-powered-by": "1.1.0",
- "hpkp": "2.0.0",
- "hsts": "2.2.0",
- "ienoopen": "1.1.0",
- "nocache": "2.1.0",
- "referrer-policy": "1.2.0",
- "x-xss-protection": "1.3.0"
- },
- "dependencies": {
- "depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
- }
- }
- },
- "helmet-crossdomain": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz",
- "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA=="
- },
- "helmet-csp": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.10.0.tgz",
- "integrity": "sha512-Rz953ZNEFk8sT2XvewXkYN0Ho4GEZdjAZy4stjiEQV3eN7GDxg1QKmYggH7otDyIA7uGA6XnUMVSgeJwbR5X+w==",
- "requires": {
- "bowser": "2.9.0",
- "camelize": "1.0.0",
- "content-security-policy-builder": "2.1.0",
- "dasherize": "2.0.0"
- }
- },
- "hide-powered-by": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz",
- "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg=="
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.1.1.tgz",
+ "integrity": "sha512-Avg4XxSBrehD94mkRwEljnO+6RZx7AGfk8Wa6K1nxaU+hbXlFOhlOIMgPfFqOYQB/dBCsTpootTGuiOG+CHiQA=="
},
"homedir-polyfill": {
"version": "1.0.3",
@@ -3561,26 +3666,6 @@
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
"dev": true
},
- "hpkp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz",
- "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI="
- },
- "hsts": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz",
- "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==",
- "requires": {
- "depd": "2.0.0"
- },
- "dependencies": {
- "depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
- }
- }
- },
"html-encoding-sniffer": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
@@ -3631,21 +3716,33 @@
"dev": true
},
"husky": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz",
- "integrity": "sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz",
+ "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"ci-info": "^2.0.0",
"compare-versions": "^3.6.0",
- "cosmiconfig": "^6.0.0",
+ "cosmiconfig": "^7.0.0",
"find-versions": "^3.2.0",
"opencollective-postinstall": "^2.0.2",
"pkg-dir": "^4.2.0",
"please-upgrade-node": "^3.2.0",
"slash": "^3.0.0",
"which-pm-runs": "^1.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ }
}
},
"iconv-lite": {
@@ -3661,11 +3758,6 @@
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
},
- "ienoopen": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz",
- "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ=="
- },
"import-fresh": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
@@ -3772,7 +3864,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "optional": true,
"requires": {
"binary-extensions": "^2.0.0"
}
@@ -3820,9 +3911,9 @@
}
},
"is-docker": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz",
- "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz",
+ "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==",
"dev": true,
"optional": true
},
@@ -3917,9 +4008,9 @@
}
},
"is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
},
"is-typedarray": {
"version": "1.0.0",
@@ -4060,45 +4151,65 @@
}
},
"jest": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz",
- "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-26.4.2.tgz",
+ "integrity": "sha512-LLCjPrUh98Ik8CzW8LLVnSCfLaiY+wbK53U7VxnFSX7Q+kWC4noVeDvGWIFw0Amfq1lq2VfGm7YHWSLBV62MJw==",
"dev": true,
"requires": {
- "@jest/core": "^26.0.1",
+ "@jest/core": "^26.4.2",
"import-local": "^3.0.2",
- "jest-cli": "^26.0.1"
+ "jest-cli": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"jest-cli": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz",
- "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.4.2.tgz",
+ "integrity": "sha512-zb+lGd/SfrPvoRSC/0LWdaWCnscXc1mGYW//NP4/tmBvRPT3VntZ2jtKUONsRi59zc5JqmsSajA9ewJKFYp8Cw==",
"dev": true,
"requires": {
- "@jest/core": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/core": "^26.4.2",
+ "@jest/test-result": "^26.3.0",
+ "@jest/types": "^26.3.0",
"chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
"import-local": "^3.0.2",
"is-ci": "^2.0.0",
- "jest-config": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
+ "jest-config": "^26.4.2",
+ "jest-util": "^26.3.0",
+ "jest-validate": "^26.4.2",
"prompts": "^2.0.1",
"yargs": "^15.3.1"
}
@@ -4106,32 +4217,52 @@
}
},
"jest-changed-files": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz",
- "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.3.0.tgz",
+ "integrity": "sha512-1C4R4nijgPltX6fugKxM4oQ18zimS7LqQ+zTTY8lMCMFPrxqBFb7KJH0Z2fRQJvw2Slbaipsqq7s1mgX5Iot+g==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"execa": "^4.0.0",
"throat": "^5.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"cross-spawn": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
- "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
@@ -4140,9 +4271,9 @@
}
},
"execa": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.1.tgz",
- "integrity": "sha512-SCjM/zlBdOK8Q5TIjOn6iEHZaPHFsMoTxXQ2nvUvtPnuohz3H2dIozSg+etNR98dGoYUp2ENSKLL/XaMmbxVgw==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
+ "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.0",
@@ -4157,20 +4288,14 @@
}
},
"get-stream": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
- "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
- "is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
- "dev": true
- },
"npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -4213,56 +4338,76 @@
}
},
"jest-config": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz",
- "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.4.2.tgz",
+ "integrity": "sha512-QBf7YGLuToiM8PmTnJEdRxyYy3mHWLh24LJZKVdXZ2PNdizSe1B/E8bVm+HYcjbEzGuVXDv/di+EzdO/6Gq80A==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/test-sequencer": "^26.0.1",
- "@jest/types": "^26.0.1",
- "babel-jest": "^26.0.1",
+ "@jest/test-sequencer": "^26.4.2",
+ "@jest/types": "^26.3.0",
+ "babel-jest": "^26.3.0",
"chalk": "^4.0.0",
"deepmerge": "^4.2.2",
"glob": "^7.1.1",
"graceful-fs": "^4.2.4",
- "jest-environment-jsdom": "^26.0.1",
- "jest-environment-node": "^26.0.1",
- "jest-get-type": "^26.0.0",
- "jest-jasmine2": "^26.0.1",
+ "jest-environment-jsdom": "^26.3.0",
+ "jest-environment-node": "^26.3.0",
+ "jest-get-type": "^26.3.0",
+ "jest-jasmine2": "^26.4.2",
"jest-regex-util": "^26.0.0",
- "jest-resolve": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
+ "jest-resolve": "^26.4.0",
+ "jest-util": "^26.3.0",
+ "jest-validate": "^26.4.2",
"micromatch": "^4.0.2",
- "pretty-format": "^26.0.1"
+ "pretty-format": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
},
"pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
+ "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
@@ -4280,18 +4425,6 @@
"diff-sequences": "^25.2.6",
"jest-get-type": "^25.2.6",
"pretty-format": "^25.5.0"
- },
- "dependencies": {
- "chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- }
}
},
"jest-docblock": {
@@ -4304,43 +4437,63 @@
}
},
"jest-each": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz",
- "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.4.2.tgz",
+ "integrity": "sha512-p15rt8r8cUcRY0Mvo1fpkOGYm7iI8S6ySxgIdfh3oOIv+gHwrHTy5VWCGOecWUhDsit4Nz8avJWdT07WLpbwDA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"chalk": "^4.0.0",
- "jest-get-type": "^26.0.0",
- "jest-util": "^26.0.1",
- "pretty-format": "^26.0.1"
+ "jest-get-type": "^26.3.0",
+ "jest-util": "^26.3.0",
+ "pretty-format": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
},
"pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
+ "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
@@ -4349,57 +4502,99 @@
}
},
"jest-environment-jsdom": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz",
- "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.3.0.tgz",
+ "integrity": "sha512-zra8He2btIMJkAzvLaiZ9QwEPGEetbxqmjEBQwhH3CA+Hhhu0jSiEJxnJMbX28TGUvPLxBt/zyaTLrOPF4yMJA==",
"dev": true,
"requires": {
- "@jest/environment": "^26.0.1",
- "@jest/fake-timers": "^26.0.1",
- "@jest/types": "^26.0.1",
- "jest-mock": "^26.0.1",
- "jest-util": "^26.0.1",
+ "@jest/environment": "^26.3.0",
+ "@jest/fake-timers": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
+ "jest-mock": "^26.3.0",
+ "jest-util": "^26.3.0",
"jsdom": "^16.2.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-environment-node": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz",
- "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.3.0.tgz",
+ "integrity": "sha512-c9BvYoo+FGcMj5FunbBgtBnbR5qk3uky8PKyRVpSfe2/8+LrNQMiXX53z6q2kY+j15SkjQCOSL/6LHnCPLVHNw==",
"dev": true,
"requires": {
- "@jest/environment": "^26.0.1",
- "@jest/fake-timers": "^26.0.1",
- "@jest/types": "^26.0.1",
- "jest-mock": "^26.0.1",
- "jest-util": "^26.0.1"
+ "@jest/environment": "^26.3.0",
+ "@jest/fake-timers": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
+ "jest-mock": "^26.3.0",
+ "jest-util": "^26.3.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
@@ -4410,93 +4605,126 @@
"dev": true
},
"jest-haste-map": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz",
- "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.3.0.tgz",
+ "integrity": "sha512-DHWBpTJgJhLLGwE5Z1ZaqLTYqeODQIZpby0zMBsCU9iRFHYyhklYqP4EiG73j5dkbaAdSZhgB938mL51Q5LeZA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"@types/graceful-fs": "^4.1.2",
+ "@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
"fsevents": "^2.1.2",
"graceful-fs": "^4.2.4",
- "jest-serializer": "^26.0.0",
- "jest-util": "^26.0.1",
- "jest-worker": "^26.0.0",
+ "jest-regex-util": "^26.0.0",
+ "jest-serializer": "^26.3.0",
+ "jest-util": "^26.3.0",
+ "jest-worker": "^26.3.0",
"micromatch": "^4.0.2",
"sane": "^4.0.3",
- "walker": "^1.0.7",
- "which": "^2.0.2"
+ "walker": "^1.0.7"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
"dev": true,
"requires": {
- "isexe": "^2.0.0"
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
}
}
}
},
"jest-jasmine2": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz",
- "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.4.2.tgz",
+ "integrity": "sha512-z7H4EpCldHN1J8fNgsja58QftxBSL+JcwZmaXIvV9WKIM+x49F4GLHu/+BQh2kzRKHAgaN/E82od+8rTOBPyPA==",
"dev": true,
"requires": {
"@babel/traverse": "^7.1.0",
- "@jest/environment": "^26.0.1",
- "@jest/source-map": "^26.0.0",
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/environment": "^26.3.0",
+ "@jest/source-map": "^26.3.0",
+ "@jest/test-result": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
- "expect": "^26.0.1",
+ "expect": "^26.4.2",
"is-generator-fn": "^2.0.0",
- "jest-each": "^26.0.1",
- "jest-matcher-utils": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-runtime": "^26.0.1",
- "jest-snapshot": "^26.0.1",
- "jest-util": "^26.0.1",
- "pretty-format": "^26.0.1",
+ "jest-each": "^26.4.2",
+ "jest-matcher-utils": "^26.4.2",
+ "jest-message-util": "^26.3.0",
+ "jest-runtime": "^26.4.2",
+ "jest-snapshot": "^26.4.2",
+ "jest-util": "^26.3.0",
+ "pretty-format": "^26.4.2",
"throat": "^5.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
+ "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
@@ -4505,40 +4733,60 @@
}
},
"jest-leak-detector": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz",
- "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.4.2.tgz",
+ "integrity": "sha512-akzGcxwxtE+9ZJZRW+M2o+nTNnmQZxrHJxX/HjgDaU5+PLmY1qnQPnMjgADPGCRPhB+Yawe1iij0REe+k/aHoA==",
"dev": true,
"requires": {
- "jest-get-type": "^26.0.0",
- "pretty-format": "^26.0.1"
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
},
"pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
+ "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
@@ -4547,60 +4795,80 @@
}
},
"jest-matcher-utils": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz",
- "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.2.tgz",
+ "integrity": "sha512-KcbNqWfWUG24R7tu9WcAOKKdiXiXCbMvQYT6iodZ9k1f7065k0keUOW6XpJMMvah+hTfqkhJhRXmA3r3zMAg0Q==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
- "jest-diff": "^26.0.1",
- "jest-get-type": "^26.0.0",
- "pretty-format": "^26.0.1"
+ "jest-diff": "^26.4.2",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"diff-sequences": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz",
- "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz",
+ "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==",
"dev": true
},
"jest-diff": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz",
- "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz",
+ "integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
- "diff-sequences": "^26.0.0",
- "jest-get-type": "^26.0.0",
- "pretty-format": "^26.0.1"
+ "diff-sequences": "^26.3.0",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.4.2"
}
},
"jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
},
"pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
+ "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
@@ -4609,13 +4877,13 @@
}
},
"jest-message-util": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz",
- "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz",
+ "integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"@types/stack-utils": "^1.0.1",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
@@ -4625,46 +4893,87 @@
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-mock": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz",
- "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.3.0.tgz",
+ "integrity": "sha512-PeaRrg8Dc6mnS35gOo/CbZovoDPKAeB1FICZiuagAgGvbWdNNyjQjkOaGUa/3N3JtpQ/Mh9P4A2D4Fv51NnP8Q==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1"
+ "@jest/types": "^26.3.0",
+ "@types/node": "*"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-pnp-resolver": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz",
- "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
+ "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
"dev": true
},
"jest-regex-util": {
@@ -4674,224 +4983,326 @@
"dev": true
},
"jest-resolve": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz",
- "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==",
+ "version": "26.4.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.4.0.tgz",
+ "integrity": "sha512-bn/JoZTEXRSlEx3+SfgZcJAVuTMOksYq9xe9O6s4Ekg84aKBObEaVXKOEilULRqviSLAYJldnoWV9c07kwtiCg==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
- "jest-pnp-resolver": "^1.2.1",
- "jest-util": "^26.0.1",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^26.3.0",
"read-pkg-up": "^7.0.1",
"resolve": "^1.17.0",
"slash": "^3.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-resolve-dependencies": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz",
- "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.4.2.tgz",
+ "integrity": "sha512-ADHaOwqEcVc71uTfySzSowA/RdxUpCxhxa2FNLiin9vWLB1uLPad3we+JSSROq5+SrL9iYPdZZF8bdKM7XABTQ==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"jest-regex-util": "^26.0.0",
- "jest-snapshot": "^26.0.1"
+ "jest-snapshot": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
- "@types/yargs": "^15.0.0",
- "chalk": "^4.0.0"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
}
}
}
},
"jest-runner": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz",
- "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.4.2.tgz",
+ "integrity": "sha512-FgjDHeVknDjw1gRAYaoUoShe1K3XUuFMkIaXbdhEys+1O4bEJS8Avmn4lBwoMfL8O5oFTdWYKcf3tEJyyYyk8g==",
"dev": true,
"requires": {
- "@jest/console": "^26.0.1",
- "@jest/environment": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/console": "^26.3.0",
+ "@jest/environment": "^26.3.0",
+ "@jest/test-result": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
"chalk": "^4.0.0",
+ "emittery": "^0.7.1",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-config": "^26.0.1",
+ "jest-config": "^26.4.2",
"jest-docblock": "^26.0.0",
- "jest-haste-map": "^26.0.1",
- "jest-jasmine2": "^26.0.1",
- "jest-leak-detector": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-resolve": "^26.0.1",
- "jest-runtime": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-worker": "^26.0.0",
+ "jest-haste-map": "^26.3.0",
+ "jest-leak-detector": "^26.4.2",
+ "jest-message-util": "^26.3.0",
+ "jest-resolve": "^26.4.0",
+ "jest-runtime": "^26.4.2",
+ "jest-util": "^26.3.0",
+ "jest-worker": "^26.3.0",
"source-map-support": "^0.5.6",
"throat": "^5.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-runtime": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz",
- "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==",
- "dev": true,
- "requires": {
- "@jest/console": "^26.0.1",
- "@jest/environment": "^26.0.1",
- "@jest/fake-timers": "^26.0.1",
- "@jest/globals": "^26.0.1",
- "@jest/source-map": "^26.0.0",
- "@jest/test-result": "^26.0.1",
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.4.2.tgz",
+ "integrity": "sha512-4Pe7Uk5a80FnbHwSOk7ojNCJvz3Ks2CNQWT5Z7MJo4tX0jb3V/LThKvD9tKPNVNyeMH98J/nzGlcwc00R2dSHQ==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^26.3.0",
+ "@jest/environment": "^26.3.0",
+ "@jest/fake-timers": "^26.3.0",
+ "@jest/globals": "^26.4.2",
+ "@jest/source-map": "^26.3.0",
+ "@jest/test-result": "^26.3.0",
+ "@jest/transform": "^26.3.0",
+ "@jest/types": "^26.3.0",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
"exit": "^0.1.2",
"glob": "^7.1.3",
"graceful-fs": "^4.2.4",
- "jest-config": "^26.0.1",
- "jest-haste-map": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-mock": "^26.0.1",
+ "jest-config": "^26.4.2",
+ "jest-haste-map": "^26.3.0",
+ "jest-message-util": "^26.3.0",
+ "jest-mock": "^26.3.0",
"jest-regex-util": "^26.0.0",
- "jest-resolve": "^26.0.1",
- "jest-snapshot": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
+ "jest-resolve": "^26.4.0",
+ "jest-snapshot": "^26.4.2",
+ "jest-util": "^26.3.0",
+ "jest-validate": "^26.4.2",
"slash": "^3.0.0",
"strip-bom": "^4.0.0",
"yargs": "^15.3.1"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-serializer": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz",
- "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.3.0.tgz",
+ "integrity": "sha512-IDRBQBLPlKa4flg77fqg0n/pH87tcRKwe8zxOVTWISxGpPHYkRZ1dXKyh04JOja7gppc60+soKVZ791mruVdow==",
"dev": true,
"requires": {
+ "@types/node": "*",
"graceful-fs": "^4.2.4"
}
},
"jest-snapshot": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz",
- "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.4.2.tgz",
+ "integrity": "sha512-N6Uub8FccKlf5SBFnL2Ri/xofbaA68Cc3MGjP/NuwgnsvWh+9hLIR/DhrxbSiKXMY9vUW5dI6EW1eHaDHqe9sg==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0",
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"@types/prettier": "^2.0.0",
"chalk": "^4.0.0",
- "expect": "^26.0.1",
+ "expect": "^26.4.2",
"graceful-fs": "^4.2.4",
- "jest-diff": "^26.0.1",
- "jest-get-type": "^26.0.0",
- "jest-matcher-utils": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-resolve": "^26.0.1",
- "make-dir": "^3.0.0",
+ "jest-diff": "^26.4.2",
+ "jest-get-type": "^26.3.0",
+ "jest-haste-map": "^26.3.0",
+ "jest-matcher-utils": "^26.4.2",
+ "jest-message-util": "^26.3.0",
+ "jest-resolve": "^26.4.0",
"natural-compare": "^1.4.0",
- "pretty-format": "^26.0.1",
+ "pretty-format": "^26.4.2",
"semver": "^7.3.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"diff-sequences": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz",
- "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz",
+ "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==",
"dev": true
},
"jest-diff": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz",
- "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz",
+ "integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
- "diff-sequences": "^26.0.0",
- "jest-get-type": "^26.0.0",
- "pretty-format": "^26.0.1"
+ "diff-sequences": "^26.3.0",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.4.2"
}
},
"jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
},
"pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
+ "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
@@ -4906,77 +5317,118 @@
}
},
"jest-util": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz",
- "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz",
+ "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"is-ci": "^2.0.0",
- "make-dir": "^3.0.0"
+ "micromatch": "^4.0.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-validate": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz",
- "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.4.2.tgz",
+ "integrity": "sha512-blft+xDX7XXghfhY0mrsBCYhX365n8K5wNDC4XAcNKqqjEzsRUSXP44m6PL0QJEW2crxQFLLztVnJ4j7oPlQrQ==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"camelcase": "^6.0.0",
"chalk": "^4.0.0",
- "jest-get-type": "^26.0.0",
+ "jest-get-type": "^26.3.0",
"leven": "^3.1.0",
- "pretty-format": "^26.0.1"
+ "pretty-format": "^26.4.2"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
},
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
"camelcase": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz",
"integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==",
"dev": true
},
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
"jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
},
"pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
+ "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"dev": true,
"requires": {
- "@jest/types": "^26.0.1",
+ "@jest/types": "^26.3.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
@@ -4985,39 +5437,61 @@
}
},
"jest-watcher": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz",
- "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.3.0.tgz",
+ "integrity": "sha512-XnLdKmyCGJ3VoF6G/p5ohbJ04q/vv5aH9ENI+i6BL0uu9WWB6Z7Z2lhQQk0d2AVZcRGp1yW+/TsoToMhBFPRdQ==",
"dev": true,
"requires": {
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/test-result": "^26.3.0",
+ "@jest/types": "^26.3.0",
+ "@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
- "jest-util": "^26.0.1",
+ "jest-util": "^26.3.0",
"string-length": "^4.0.1"
},
"dependencies": {
"@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
+ "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
"chalk": "^4.0.0"
}
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+ "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
}
}
},
"jest-worker": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz",
- "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz",
+ "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==",
"dev": true,
"requires": {
+ "@types/node": "*",
"merge-stream": "^2.0.0",
"supports-color": "^7.0.0"
}
@@ -5029,9 +5503,9 @@
"dev": true
},
"js-yaml": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
- "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
+ "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
@@ -5045,9 +5519,9 @@
"dev": true
},
"jsdom": {
- "version": "16.2.2",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz",
- "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==",
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz",
+ "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==",
"dev": true,
"requires": {
"abab": "^2.0.3",
@@ -5070,7 +5544,7 @@
"tough-cookie": "^3.0.1",
"w3c-hr-time": "^1.0.2",
"w3c-xmlserializer": "^2.0.0",
- "webidl-conversions": "^6.0.0",
+ "webidl-conversions": "^6.1.0",
"whatwg-encoding": "^1.0.5",
"whatwg-mimetype": "^2.3.0",
"whatwg-url": "^8.0.0",
@@ -5084,10 +5558,10 @@
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
"dev": true
},
- "json-parse-better-errors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true
},
"json-schema": {
@@ -5166,12 +5640,9 @@
}
},
"kuler": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz",
- "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==",
- "requires": {
- "colornames": "^1.1.1"
- }
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
+ "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
},
"lazy-cache": {
"version": "2.0.2",
@@ -5204,18 +5675,20 @@
"dev": true
},
"lint-staged": {
- "version": "10.2.4",
- "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.2.4.tgz",
- "integrity": "sha512-doTMGKXQAT34c3S3gwDrTnXmCZp/z1/92D8suPqqh755sKPT18ew1NoPNHxJdrvv1D4WrJ7CEnx79Ns3EdEFbg==",
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.4.0.tgz",
+ "integrity": "sha512-uaiX4U5yERUSiIEQc329vhCTDDwUcSvKdRLsNomkYLRzijk3v8V9GWm2Nz0RMVB87VcuzLvtgy6OsjoH++QHIg==",
"dev": true,
"requires": {
- "chalk": "^4.0.0",
- "commander": "^5.1.0",
- "cosmiconfig": "^6.0.0",
+ "chalk": "^4.1.0",
+ "cli-truncate": "^2.1.0",
+ "commander": "^6.0.0",
+ "cosmiconfig": "^7.0.0",
"debug": "^4.1.1",
"dedent": "^0.7.0",
- "execa": "^4.0.1",
- "listr2": "^2.0.2",
+ "enquirer": "^2.3.6",
+ "execa": "^4.0.3",
+ "listr2": "^2.6.0",
"log-symbols": "^4.0.0",
"micromatch": "^4.0.2",
"normalize-path": "^3.0.0",
@@ -5224,10 +5697,26 @@
"stringify-object": "^3.3.0"
},
"dependencies": {
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "commander": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz",
+ "integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==",
+ "dev": true
+ },
"cross-spawn": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
- "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
@@ -5245,9 +5734,9 @@
}
},
"execa": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.1.tgz",
- "integrity": "sha512-SCjM/zlBdOK8Q5TIjOn6iEHZaPHFsMoTxXQ2nvUvtPnuohz3H2dIozSg+etNR98dGoYUp2ENSKLL/XaMmbxVgw==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
+ "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.0",
@@ -5262,20 +5751,14 @@
}
},
"get-stream": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
- "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
- "is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
- "dev": true
- },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -5324,25 +5807,31 @@
}
},
"listr2": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/listr2/-/listr2-2.0.3.tgz",
- "integrity": "sha512-2dKxql0jPuiAyMLYUkzzvoDroenO+aiecNnNfjn+S4jK5P9uuHKN55u4eVX8Czb9JsgAjGx7yPQYMIEzHMmKSA==",
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-2.6.2.tgz",
+ "integrity": "sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA==",
"dev": true,
"requires": {
- "@samverschueren/stream-to-observable": "^0.3.0",
- "chalk": "^4.0.0",
- "cli-cursor": "^3.1.0",
+ "chalk": "^4.1.0",
"cli-truncate": "^2.1.0",
- "elegant-spinner": "^2.0.0",
- "enquirer": "^2.3.5",
"figures": "^3.2.0",
"indent-string": "^4.0.0",
"log-update": "^4.0.0",
- "nanoid": "^3.1.9",
"p-map": "^4.0.0",
- "pad": "^3.2.0",
- "rxjs": "^6.5.5",
+ "rxjs": "^6.6.2",
"through": "^2.3.8"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ }
}
},
"load-json-file": {
@@ -5390,7 +5879,8 @@
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
- "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+ "dev": true
},
"lodash.clonedeep": {
"version": "4.5.0",
@@ -5425,6 +5915,18 @@
"dev": true,
"requires": {
"chalk": "^4.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ }
}
},
"log-update": {
@@ -5459,13 +5961,13 @@
}
},
"logform": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz",
- "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz",
+ "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==",
"requires": {
"colors": "^1.2.1",
"fast-safe-stringify": "^2.0.4",
- "fecha": "^2.3.3",
+ "fecha": "^4.2.0",
"ms": "^2.1.1",
"triple-beam": "^1.3.0"
},
@@ -5746,11 +6248,11 @@
}
},
"mongodb": {
- "version": "3.5.7",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.7.tgz",
- "integrity": "sha512-lMtleRT+vIgY/JhhTn1nyGwnSMmJkJELp+4ZbrjctrnBxuLbj6rmLuJFz8W2xUzUqWmqoyVxJLYuC58ZKpcTYQ==",
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz",
+ "integrity": "sha512-sSZOb04w3HcnrrXC82NEh/YGCmBuRgR+C1hZgmmv4L6dBz4BkRse6Y8/q/neXer9i95fKUBbFi4KgeceXmbsOA==",
"requires": {
- "bl": "^2.2.0",
+ "bl": "^2.2.1",
"bson": "^1.1.4",
"denque": "^1.4.1",
"require_optional": "^1.0.1",
@@ -5759,9 +6261,9 @@
},
"dependencies": {
"bson": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
- "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q=="
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz",
+ "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg=="
}
}
},
@@ -5781,12 +6283,6 @@
"thenify-all": "^1.0.0"
}
},
- "nanoid": {
- "version": "3.1.9",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.9.tgz",
- "integrity": "sha512-fFiXlFo4Wkuei3i6w9SQI6yuzGRTGi8Z2zZKZpUxv/bQlBi4jtbVPBSNFZHQA9PNjofWqtIa8p+pnsc0kgZrhQ==",
- "dev": true
- },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -5916,11 +6412,6 @@
"lower-case": "^1.1.1"
}
},
- "nocache": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
- "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
- },
"node-dependency-injection": {
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/node-dependency-injection/-/node-dependency-injection-2.6.8.tgz",
@@ -5966,17 +6457,17 @@
"dev": true
},
"node-notifier": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.0.tgz",
- "integrity": "sha512-y8ThJESxsHcak81PGpzWwQKxzk+5YtP3IxR8AYdpXQ1IB6FmcVzFdZXrkPin49F/DKUCfeeiziB8ptY9npzGuA==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz",
+ "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==",
"dev": true,
"optional": true,
"requires": {
"growly": "^1.3.0",
- "is-wsl": "^2.1.1",
- "semver": "^7.2.1",
+ "is-wsl": "^2.2.0",
+ "semver": "^7.3.2",
"shellwords": "^0.1.1",
- "uuid": "^7.0.3",
+ "uuid": "^8.3.0",
"which": "^2.0.2"
},
"dependencies": {
@@ -5987,13 +6478,6 @@
"dev": true,
"optional": true
},
- "uuid": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
- "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
- "dev": true,
- "optional": true
- },
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -6033,21 +6517,14 @@
}
},
"nunjucks": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.1.tgz",
- "integrity": "sha512-LYlVuC1ZNSalQQkLNNPvcgPt2M9FTY9bs39mTCuFXtqh7jWbYzhDlmz2M6onPiXEhdZo+b9anRhc+uBGuJZ2bQ==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.2.tgz",
+ "integrity": "sha512-KUi85OoF2NMygwODAy28Lh9qHmq5hO3rBlbkYoC8v377h4l8Pt5qFjILl0LWpMbOrZ18CzfVVUvIHUIrtED3sA==",
"requires": {
"a-sync-waterfall": "^1.0.0",
"asap": "^2.0.3",
"chokidar": "^3.3.0",
- "commander": "^3.0.2"
- },
- "dependencies": {
- "commander": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
- "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow=="
- }
+ "commander": "^5.1.0"
}
},
"nwsapi": {
@@ -6146,23 +6623,26 @@
}
},
"one-time": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
- "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
+ "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+ "requires": {
+ "fn.name": "1.x.x"
+ }
},
"onetime": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
- "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"requires": {
"mimic-fn": "^2.1.0"
}
},
"opencollective-postinstall": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
- "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
+ "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
"dev": true
},
"optionator": {
@@ -6229,15 +6709,6 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
- "pad": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/pad/-/pad-3.2.0.tgz",
- "integrity": "sha512-2u0TrjcGbOjBTJpyewEl4hBO3OeX5wWue7eIFPzQTg6wFSvoaHcBTTUY5m+n0hd04gmTCPuY0kCpVIVuw5etwg==",
- "dev": true,
- "requires": {
- "wcwidth": "^1.0.1"
- }
- },
"pad-right": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz",
@@ -6257,14 +6728,14 @@
}
},
"parse-json": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
- "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
+ "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1",
+ "json-parse-even-better-errors": "^2.3.0",
"lines-and-columns": "^1.1.6"
}
},
@@ -6396,9 +6867,9 @@
"dev": true
},
"prettier": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz",
- "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
+ "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
"dev": true
},
"pretty-format": {
@@ -6549,7 +7020,6 @@
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
"integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
- "optional": true,
"requires": {
"picomatch": "^2.2.1"
}
@@ -6575,11 +7045,6 @@
}
}
},
- "referrer-policy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
- "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
- },
"regenerator-runtime": {
"version": "0.13.5",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
@@ -6702,21 +7167,29 @@
}
},
"request-promise-core": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
- "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+ "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
"dev": true,
"requires": {
- "lodash": "^4.17.15"
+ "lodash": "^4.17.19"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ }
}
},
"request-promise-native": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
- "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+ "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
"dev": true,
"requires": {
- "request-promise-core": "1.1.3",
+ "request-promise-core": "1.1.4",
"stealthy-require": "^1.1.1",
"tough-cookie": "^2.3.3"
},
@@ -6832,9 +7305,9 @@
"dev": true
},
"rxjs": {
- "version": "6.5.5",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
- "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
+ "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
@@ -7210,7 +7683,8 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
- "dev": true
+ "dev": true,
+ "optional": true
},
"signal-exit": {
"version": "3.0.3",
@@ -7407,9 +7881,9 @@
}
},
"spdx-correct": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
- "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
"dev": true,
"requires": {
"spdx-expression-parse": "^3.0.0",
@@ -8064,18 +8538,19 @@
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
},
"ts-jest": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.0.0.tgz",
- "integrity": "sha512-eBpWH65mGgzobuw7UZy+uPP9lwu+tPp60o324ASRX4Ijg8UC5dl2zcge4kkmqr2Zeuk9FwIjvCTOPuNMEyGWWw==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz",
+ "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==",
"dev": true,
"requires": {
+ "@types/jest": "26.x",
"bs-logger": "0.x",
"buffer-from": "1.x",
"fast-json-stable-stringify": "2.x",
+ "jest-util": "26.x",
"json5": "2.x",
"lodash.memoize": "4.x",
"make-error": "1.x",
- "micromatch": "4.x",
"mkdirp": "1.x",
"semver": "7.x",
"yargs-parser": "18.x"
@@ -8096,9 +8571,9 @@
}
},
"ts-node": {
- "version": "8.10.1",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.1.tgz",
- "integrity": "sha512-bdNz1L4ekHiJul6SHtZWs1ujEKERJnHs4HxN7rjTyyVOFf3HaJ6sLqe6aPG62XTzAB/63pKRh5jTSWL0D7bsvw==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
+ "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
"requires": {
"arg": "^4.1.0",
"diff": "^4.0.1",
@@ -8108,44 +8583,30 @@
}
},
"ts-node-dev": {
- "version": "1.0.0-pre.44",
- "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.0.0-pre.44.tgz",
- "integrity": "sha512-M5ZwvB6FU3jtc70i5lFth86/6Qj5XR5nMMBwVxZF4cZhpO7XcbWw6tbNiJo22Zx0KfjEj9py5DANhwLOkPPufw==",
+ "version": "1.0.0-pre.62",
+ "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.0.0-pre.62.tgz",
+ "integrity": "sha512-hfsEuCqUZOVnZ86l7A3icxD1nFt1HEmLVbx4YOHCkrbSHPBNWcw+IczAPZo3zz7YiOm9vs0xG6OENNrkgm89tQ==",
"dev": true,
"requires": {
+ "chokidar": "^3.4.0",
"dateformat": "~1.0.4-1.2.3",
"dynamic-dedupe": "^0.3.0",
- "filewatcher": "~3.0.0",
- "minimist": "^1.1.3",
- "mkdirp": "^0.5.1",
- "node-notifier": "^5.4.0",
+ "minimist": "^1.2.5",
+ "mkdirp": "^1.0.4",
"resolve": "^1.0.0",
"rimraf": "^2.6.1",
"source-map-support": "^0.5.12",
- "tree-kill": "^1.2.1",
- "ts-node": "*",
+ "tree-kill": "^1.2.2",
+ "ts-node": "^8.10.2",
"tsconfig": "^7.0.0"
},
"dependencies": {
- "is-wsl": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
- "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true
},
- "node-notifier": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz",
- "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==",
- "dev": true,
- "requires": {
- "growly": "^1.3.0",
- "is-wsl": "^1.1.0",
- "semver": "^5.5.0",
- "shellwords": "^0.1.1",
- "which": "^1.3.0"
- }
- },
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@@ -8154,6 +8615,19 @@
"requires": {
"glob": "^7.1.3"
}
+ },
+ "ts-node": {
+ "version": "8.10.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
+ "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
+ "dev": true,
+ "requires": {
+ "arg": "^4.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "source-map-support": "^0.5.17",
+ "yn": "3.1.1"
+ }
}
}
},
@@ -8184,9 +8658,9 @@
"dev": true
},
"tslint": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.2.tgz",
- "integrity": "sha512-UyNrLdK3E0fQG/xWNqAFAC5ugtFyPO4JJR1KyyfQAyzR8W0fTRrC91A8Wej4BntFzcvETdCSDa/4PnNYJQLYiA==",
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
+ "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@@ -8200,7 +8674,7 @@
"mkdirp": "^0.5.3",
"resolve": "^1.3.2",
"semver": "^5.3.0",
- "tslib": "^1.10.0",
+ "tslib": "^1.13.0",
"tsutils": "^2.29.0"
},
"dependencies": {
@@ -8377,9 +8851,9 @@
}
},
"typescript": {
- "version": "3.9.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz",
- "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw=="
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz",
+ "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ=="
},
"unc-path-regex": {
"version": "0.1.2",
@@ -8456,9 +8930,9 @@
"dev": true
},
"uri-js": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
- "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+ "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
@@ -8493,9 +8967,9 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz",
- "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw=="
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
},
"uuid-validate": {
"version": "0.0.3",
@@ -8503,9 +8977,9 @@
"integrity": "sha512-Fykw5U4eZESbq739BeLvEBFRuJODfrlmjx5eJux7W817LjRaq4b7/i4t2zxQmhcX+fAj4nMfRdTzO4tmwLKn0w=="
},
"v8-to-istanbul": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz",
- "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-5.0.1.tgz",
+ "integrity": "sha512-mbDNjuDajqYe3TXFk5qxcQy8L1msXNE37WTlLoqqpBfRsimbNcrlhQlDPntmECEcUvdC+AQ8CyMMf6EUx1r74Q==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.1",
@@ -8593,6 +9067,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+ "optional": true,
"requires": {
"defaults": "^1.0.3"
}
@@ -8619,22 +9094,14 @@
"dev": true
},
"whatwg-url": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz",
- "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==",
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.2.2.tgz",
+ "integrity": "sha512-PcVnO6NiewhkmzV0qn7A+UZ9Xx4maNTI+O+TShmfE4pqjoCMwUMjkvoNhNHPTvgR7QH9Xt3R13iHuWy2sToFxQ==",
"dev": true,
"requires": {
"lodash.sortby": "^4.7.0",
"tr46": "^2.0.2",
- "webidl-conversions": "^5.0.0"
- },
- "dependencies": {
- "webidl-conversions": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
- "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
- "dev": true
- }
+ "webidl-conversions": "^6.1.0"
}
},
"which": {
@@ -8658,19 +9125,19 @@
"dev": true
},
"winston": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz",
- "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz",
+ "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==",
"requires": {
- "async": "^2.6.1",
- "diagnostics": "^1.1.1",
- "is-stream": "^1.1.0",
- "logform": "^2.1.1",
- "one-time": "0.0.4",
- "readable-stream": "^3.1.1",
+ "@dabh/diagnostics": "^2.0.2",
+ "async": "^3.1.0",
+ "is-stream": "^2.0.0",
+ "logform": "^2.2.0",
+ "one-time": "^1.0.0",
+ "readable-stream": "^3.4.0",
"stack-trace": "0.0.x",
"triple-beam": "^1.3.0",
- "winston-transport": "^4.3.0"
+ "winston-transport": "^4.4.0"
},
"dependencies": {
"readable-stream": {
@@ -8686,11 +9153,11 @@
}
},
"winston-transport": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz",
- "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz",
+ "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==",
"requires": {
- "readable-stream": "^2.3.6",
+ "readable-stream": "^2.3.7",
"triple-beam": "^1.2.0"
}
},
@@ -8757,16 +9224,11 @@
}
},
"ws": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
- "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==",
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
+ "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==",
"dev": true
},
- "x-xss-protection": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz",
- "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg=="
- },
"xml-name-validator": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
@@ -8806,9 +9268,9 @@
"dev": true
},
"yargs": {
- "version": "15.3.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
- "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"dev": true,
"requires": {
"cliui": "^6.0.0",
@@ -8821,7 +9283,7 @@
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
- "yargs-parser": "^18.1.1"
+ "yargs-parser": "^18.1.2"
},
"dependencies": {
"is-fullwidth-code-point": {
diff --git a/package.json b/package.json
index fda7251..4815d67 100644
--- a/package.json
+++ b/package.json
@@ -29,15 +29,15 @@
"@types/compression": "^1.7.0",
"@types/convict": "^5.2.1",
"@types/errorhandler": "1.5.0",
- "@types/express": "^4.17.6",
- "@types/glob": "^7.1.1",
- "@types/helmet": "0.0.47",
- "@types/mongodb": "^3.5.18",
- "@types/node": "^14.0.3",
- "@types/uuid": "^8.0.0",
+ "@types/express": "^4.17.8",
+ "@types/glob": "^7.1.3",
+ "@types/helmet": "0.0.48",
+ "@types/mongodb": "^3.5.27",
+ "@types/node": "^14.10.2",
+ "@types/uuid": "^8.3.0",
"@types/uuid-validate": "0.0.1",
"body-parser": "^1.19.0",
- "bson": "^4.0.4",
+ "bson": "^4.1.0",
"compression": "^1.7.4",
"connect-flash": "^0.1.1",
"convict": "^6.0.0",
@@ -48,38 +48,38 @@
"express": "^4.17.1",
"express-validator": "^6.6.1",
"glob": "^7.1.6",
- "helmet": "^3.22.0",
+ "helmet": "^4.1.1",
"http-status": "^1.4.2",
"mandrill-api": "^1.0.45",
- "mongodb": "^3.5.7",
+ "mongodb": "^3.6.2",
"node-dependency-injection": "^2.6.8",
- "nunjucks": "^3.2.1",
- "ts-node": "^8.10.1",
- "typescript": "^3.9.2",
- "uuid": "^8.0.0",
+ "nunjucks": "^3.2.2",
+ "ts-node": "^9.0.0",
+ "typescript": "^4.0.2",
+ "uuid": "^8.3.0",
"uuid-validate": "0.0.3",
- "winston": "^3.2.1"
+ "winston": "^3.3.3"
},
"devDependencies": {
- "@types/aws-lambda": "^8.10.51",
+ "@types/aws-lambda": "^8.10.62",
"@types/connect-flash": "0.0.35",
"@types/cookie-parser": "^1.4.2",
"@types/cookie-session": "^2.0.41",
"@types/cucumber": "^6.0.1",
- "@types/faker": "^4.1.12",
- "@types/jest": "^25.2.3",
+ "@types/faker": "^5.1.0",
+ "@types/jest": "^26.0.14",
"@types/nunjucks": "^3.1.3",
- "@types/supertest": "^2.0.9",
+ "@types/supertest": "^2.0.10",
"cucumber": "^6.0.5",
- "faker": "^4.1.0",
- "husky": "^4.2.5",
- "jest": "^26.0.1",
- "lint-staged": "10.2.4",
- "prettier": "^2.0.5",
+ "faker": "^5.1.0",
+ "husky": "^4.3.0",
+ "jest": "^26.4.2",
+ "lint-staged": "10.4.0",
+ "prettier": "^2.1.2",
"supertest": "^4.0.2",
- "ts-jest": "^26.0.0",
- "ts-node-dev": "^1.0.0-pre.44",
- "tslint": "^6.1.2",
+ "ts-jest": "^26.3.0",
+ "ts-node-dev": "^1.0.0-pre.62",
+ "tslint": "^6.1.3",
"tslint-config-prettier": "~1.18.0",
"tslint-eslint-rules": "^5.4.0"
},
From 972a6186cde60c5eb5dcccbca54b418d556138e3 Mon Sep 17 00:00:00 2001
From: Antonio Leon
Date: Wed, 16 Sep 2020 23:37:44 +0200
Subject: [PATCH 36/48] Create Retention BC from the notifications module of
the Mooc BC
---
.../SendWelcomeUserEmail.ts | 17 +++++++++
.../SendWelcomeUserEmailOnUserRegistered.ts | 18 +++++++++
.../Retention/Campaign/domain/Email.ts | 37 +++++++++++++++++++
.../Retention/Campaign/domain/EmailAddress.ts | 3 ++
.../Retention/Campaign/domain/EmailId.ts | 3 ++
.../Retention/Campaign/domain/EmailSender.ts | 5 +++
.../domain/UserRegisteredDomainEvent.ts | 32 ++++++++++++++++
.../Campaign/domain/WelcomeUserEmail.ts | 13 +++++++
.../Campaign/domain/WelcomeUserEmailError.ts | 7 ++++
.../infrastructure/FakeEmailSender.ts | 8 ++++
src/apps/retention/app.ts | 3 ++
.../Campaign/application.yaml | 14 +++++++
.../dependency-injection/Campaign/config.ts | 23 ++++++++++++
.../Campaign/default.json | 1 +
.../dependency-injection/Campaign/dev.json | 1 +
.../Campaign/production.json | 1 +
.../Campaign/staging.json | 1 +
.../dependency-injection/Campaign/test.json | 3 ++
.../dependency-injection/application.yaml | 2 +
.../dependency-injection/application_dev.yaml | 2 +
.../application_production.yaml | 2 +
.../application_staging.yaml | 2 +
.../application_test.yaml | 2 +
.../config/dependency-injection/index.ts | 9 +++++
src/apps/retention/subscribers.ts | 14 +++++++
25 files changed, 223 insertions(+)
create mode 100644 src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts
create mode 100644 src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts
create mode 100644 src/Contexts/Retention/Campaign/domain/Email.ts
create mode 100644 src/Contexts/Retention/Campaign/domain/EmailAddress.ts
create mode 100644 src/Contexts/Retention/Campaign/domain/EmailId.ts
create mode 100644 src/Contexts/Retention/Campaign/domain/EmailSender.ts
create mode 100644 src/Contexts/Retention/Campaign/domain/UserRegisteredDomainEvent.ts
create mode 100644 src/Contexts/Retention/Campaign/domain/WelcomeUserEmail.ts
create mode 100644 src/Contexts/Retention/Campaign/domain/WelcomeUserEmailError.ts
create mode 100644 src/Contexts/Retention/Campaign/infrastructure/FakeEmailSender.ts
create mode 100644 src/apps/retention/app.ts
create mode 100644 src/apps/retention/config/dependency-injection/Campaign/application.yaml
create mode 100644 src/apps/retention/config/dependency-injection/Campaign/config.ts
create mode 100644 src/apps/retention/config/dependency-injection/Campaign/default.json
create mode 100644 src/apps/retention/config/dependency-injection/Campaign/dev.json
create mode 100644 src/apps/retention/config/dependency-injection/Campaign/production.json
create mode 100644 src/apps/retention/config/dependency-injection/Campaign/staging.json
create mode 100644 src/apps/retention/config/dependency-injection/Campaign/test.json
create mode 100644 src/apps/retention/config/dependency-injection/application.yaml
create mode 100644 src/apps/retention/config/dependency-injection/application_dev.yaml
create mode 100644 src/apps/retention/config/dependency-injection/application_production.yaml
create mode 100644 src/apps/retention/config/dependency-injection/application_staging.yaml
create mode 100644 src/apps/retention/config/dependency-injection/application_test.yaml
create mode 100644 src/apps/retention/config/dependency-injection/index.ts
create mode 100644 src/apps/retention/subscribers.ts
diff --git a/src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts b/src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts
new file mode 100644
index 0000000..140e081
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmail.ts
@@ -0,0 +1,17 @@
+import { EmailSender } from '../../domain/EmailSender';
+import { EmailAddress } from '../../domain/EmailAddress';
+import { WelcomeUserEmail } from '../../domain/WelcomeUserEmail';
+import { WelcomeUserEmailError } from '../../domain/WelcomeUserEmailError';
+
+export default class SendWelcomeUserEmail {
+ constructor(private emailSender: EmailSender) {}
+
+ async run(userEmailAddress: EmailAddress): Promise {
+ const welcomeUserEmail = new WelcomeUserEmail(userEmailAddress);
+ try {
+ await this.emailSender.send(welcomeUserEmail);
+ } catch (error) {
+ throw new WelcomeUserEmailError(userEmailAddress);
+ }
+ }
+}
diff --git a/src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts b/src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts
new file mode 100644
index 0000000..785e76b
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered.ts
@@ -0,0 +1,18 @@
+import { DomainEventSubscriber } from '../../../../Shared/domain/DomainEventSubscriber';
+import { UserRegisteredDomainEvent } from '../../domain/UserRegisteredDomainEvent';
+import { DomainEventClass } from '../../../../Shared/domain/DomainEvent';
+import SendWelcomeUserEmail from './SendWelcomeUserEmail';
+import { EmailAddress } from '../../domain/EmailAddress';
+
+export default class SendWelcomeUserEmailOnUserRegistered implements DomainEventSubscriber {
+ constructor(private sendWelcomeUserEmail: SendWelcomeUserEmail) {}
+
+ subscribedTo(): DomainEventClass[] {
+ return [UserRegisteredDomainEvent];
+ }
+
+ async on(domainEvent: UserRegisteredDomainEvent): Promise {
+ const userEmailAddress = new EmailAddress(domainEvent.userEmailAddress);
+ await this.sendWelcomeUserEmail.run(userEmailAddress);
+ }
+}
diff --git a/src/Contexts/Retention/Campaign/domain/Email.ts b/src/Contexts/Retention/Campaign/domain/Email.ts
new file mode 100644
index 0000000..673dc3c
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/domain/Email.ts
@@ -0,0 +1,37 @@
+import { EmailAddress } from './EmailAddress';
+import { EmailId } from './EmailId';
+import { Uuid } from '../../../Shared/domain/value-object/Uuid';
+
+type ConstructorParams = {
+ id?: EmailId;
+ from: EmailAddress;
+ to: EmailAddress;
+ subject: string;
+ body: string;
+};
+
+export class Email {
+ readonly id: EmailId;
+ readonly from: EmailAddress;
+ readonly to: EmailAddress;
+ readonly subject: string;
+ readonly body: string;
+
+ constructor(params: ConstructorParams) {
+ this.id = params.id || new EmailId(Uuid.random().value);
+ this.from = params.from;
+ this.to = params.to;
+ this.subject = params.subject;
+ this.body = params.body;
+ }
+
+ equals(otherEmail: Email): boolean {
+ return (
+ this.id.value === otherEmail.id.value &&
+ this.from.value === otherEmail.from.value &&
+ this.to.value === otherEmail.to.value &&
+ this.subject === otherEmail.subject &&
+ this.body === otherEmail.body
+ );
+ }
+}
diff --git a/src/Contexts/Retention/Campaign/domain/EmailAddress.ts b/src/Contexts/Retention/Campaign/domain/EmailAddress.ts
new file mode 100644
index 0000000..f014743
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/domain/EmailAddress.ts
@@ -0,0 +1,3 @@
+import { StringValueObject } from '../../../Shared/domain/value-object/StringValueObject';
+
+export class EmailAddress extends StringValueObject {}
diff --git a/src/Contexts/Retention/Campaign/domain/EmailId.ts b/src/Contexts/Retention/Campaign/domain/EmailId.ts
new file mode 100644
index 0000000..3ba583c
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/domain/EmailId.ts
@@ -0,0 +1,3 @@
+import { Uuid } from '../../../Shared/domain/value-object/Uuid';
+
+export class EmailId extends Uuid {}
diff --git a/src/Contexts/Retention/Campaign/domain/EmailSender.ts b/src/Contexts/Retention/Campaign/domain/EmailSender.ts
new file mode 100644
index 0000000..5a96e50
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/domain/EmailSender.ts
@@ -0,0 +1,5 @@
+import { Email } from './Email';
+
+export interface EmailSender {
+ send(email: Email): Promise;
+}
diff --git a/src/Contexts/Retention/Campaign/domain/UserRegisteredDomainEvent.ts b/src/Contexts/Retention/Campaign/domain/UserRegisteredDomainEvent.ts
new file mode 100644
index 0000000..e45a2a0
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/domain/UserRegisteredDomainEvent.ts
@@ -0,0 +1,32 @@
+import { DomainEvent } from '../../../Shared/domain/DomainEvent';
+
+type UserRegisteredDomainEventBody = { userEmailAddress: string };
+
+export class UserRegisteredDomainEvent extends DomainEvent {
+ static readonly EVENT_NAME = 'user.registered';
+ readonly userEmailAddress: string;
+
+ constructor(data: { id: string; userEmailAddress: string; eventId?: string; occurredOn?: Date }) {
+ const { id, eventId, occurredOn, userEmailAddress } = data;
+ super(UserRegisteredDomainEvent.EVENT_NAME, id, eventId, occurredOn);
+ this.userEmailAddress = userEmailAddress;
+ }
+
+ toPrimitive(): Object {
+ return { userEmailAddress: this.userEmailAddress };
+ }
+
+ static fromPrimitives(
+ aggregateId: string,
+ body: UserRegisteredDomainEventBody,
+ eventId: string,
+ occurredOn: Date
+ ): DomainEvent {
+ return new UserRegisteredDomainEvent({
+ id: aggregateId,
+ userEmailAddress: body.userEmailAddress,
+ eventId,
+ occurredOn
+ });
+ }
+}
diff --git a/src/Contexts/Retention/Campaign/domain/WelcomeUserEmail.ts b/src/Contexts/Retention/Campaign/domain/WelcomeUserEmail.ts
new file mode 100644
index 0000000..22a2fd9
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/domain/WelcomeUserEmail.ts
@@ -0,0 +1,13 @@
+import { Email } from './Email';
+import { EmailAddress } from './EmailAddress';
+
+export class WelcomeUserEmail extends Email {
+ constructor(to: EmailAddress) {
+ super({
+ from: new EmailAddress('welcome@foo.com'),
+ to,
+ subject: 'Welcome',
+ body: 'Welcome to our platform'
+ });
+ }
+}
diff --git a/src/Contexts/Retention/Campaign/domain/WelcomeUserEmailError.ts b/src/Contexts/Retention/Campaign/domain/WelcomeUserEmailError.ts
new file mode 100644
index 0000000..ef6eddc
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/domain/WelcomeUserEmailError.ts
@@ -0,0 +1,7 @@
+import { EmailAddress } from './EmailAddress';
+
+export class WelcomeUserEmailError extends Error {
+ constructor(userEmailAddress: EmailAddress) {
+ super(`Error sending WelcomeUser email to ${userEmailAddress.value}`);
+ }
+}
diff --git a/src/Contexts/Retention/Campaign/infrastructure/FakeEmailSender.ts b/src/Contexts/Retention/Campaign/infrastructure/FakeEmailSender.ts
new file mode 100644
index 0000000..e148b9f
--- /dev/null
+++ b/src/Contexts/Retention/Campaign/infrastructure/FakeEmailSender.ts
@@ -0,0 +1,8 @@
+import { EmailSender } from '../domain/EmailSender';
+import { Email } from '../domain/Email';
+
+export default class FakeEmailSender implements EmailSender {
+ async send(email: Email): Promise {
+ // do nothing
+ }
+}
diff --git a/src/apps/retention/app.ts b/src/apps/retention/app.ts
new file mode 100644
index 0000000..c02a5a7
--- /dev/null
+++ b/src/apps/retention/app.ts
@@ -0,0 +1,3 @@
+import { registerSubscribers } from './subscribers';
+
+registerSubscribers();
diff --git a/src/apps/retention/config/dependency-injection/Campaign/application.yaml b/src/apps/retention/config/dependency-injection/Campaign/application.yaml
new file mode 100644
index 0000000..c6d6832
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/Campaign/application.yaml
@@ -0,0 +1,14 @@
+services:
+ Retention.campaign.EmailSender:
+ class: ../../../../../Contexts/Retention/Campaign/infrastructure/FakeEmailSender
+ arguments: []
+
+ Retention.campaign.SendWelcomeUserEmail:
+ class: ../../../../../Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmail
+ arguments: ["@Retention.campaign.EmailSender"]
+
+ Retention.campaign.SendWelcomeUserEmailOnUserRegistered:
+ class: ../../../../../Contexts/Retention/Campaign/application/SendWelcomeUserEmail/SendWelcomeUserEmailOnUserRegistered
+ arguments: ["@Retention.campaign.SendWelcomeUserEmail"]
+ tags:
+ - { name: 'domainEventSubscriber' }
\ No newline at end of file
diff --git a/src/apps/retention/config/dependency-injection/Campaign/config.ts b/src/apps/retention/config/dependency-injection/Campaign/config.ts
new file mode 100644
index 0000000..5d5092c
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/Campaign/config.ts
@@ -0,0 +1,23 @@
+import convict from 'convict';
+
+// We Keep same Mongo connection URL but create a new config so it can be migrated easily
+const convictConfig = convict({
+ env: {
+ doc: 'The application environment.',
+ format: ['production', 'development', 'staging', 'test'],
+ default: 'default',
+ env: 'NODE_ENV'
+ },
+ mongo: {
+ url: {
+ doc: 'The Mongo connection URL',
+ format: String,
+ env: 'MONGO_URL',
+ default: 'mongodb://localhost:27017/mooc-backend-dev'
+ }
+ }
+});
+
+convictConfig.loadFile([__dirname + '/default.json', __dirname + '/' + convictConfig.get('env') + '.json']);
+
+export default convictConfig;
diff --git a/src/apps/retention/config/dependency-injection/Campaign/default.json b/src/apps/retention/config/dependency-injection/Campaign/default.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/Campaign/default.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/apps/retention/config/dependency-injection/Campaign/dev.json b/src/apps/retention/config/dependency-injection/Campaign/dev.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/Campaign/dev.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/apps/retention/config/dependency-injection/Campaign/production.json b/src/apps/retention/config/dependency-injection/Campaign/production.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/Campaign/production.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/apps/retention/config/dependency-injection/Campaign/staging.json b/src/apps/retention/config/dependency-injection/Campaign/staging.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/Campaign/staging.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/apps/retention/config/dependency-injection/Campaign/test.json b/src/apps/retention/config/dependency-injection/Campaign/test.json
new file mode 100644
index 0000000..d5e154f
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/Campaign/test.json
@@ -0,0 +1,3 @@
+{
+ "mongo": { "url": "mongodb://localhost:27017/mooc-backend-test" }
+ }
diff --git a/src/apps/retention/config/dependency-injection/application.yaml b/src/apps/retention/config/dependency-injection/application.yaml
new file mode 100644
index 0000000..81d141c
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/application.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./Campaign/application.yaml }
\ No newline at end of file
diff --git a/src/apps/retention/config/dependency-injection/application_dev.yaml b/src/apps/retention/config/dependency-injection/application_dev.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/application_dev.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/retention/config/dependency-injection/application_production.yaml b/src/apps/retention/config/dependency-injection/application_production.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/application_production.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/retention/config/dependency-injection/application_staging.yaml b/src/apps/retention/config/dependency-injection/application_staging.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/application_staging.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/retention/config/dependency-injection/application_test.yaml b/src/apps/retention/config/dependency-injection/application_test.yaml
new file mode 100644
index 0000000..287933e
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/application_test.yaml
@@ -0,0 +1,2 @@
+imports:
+ - { resource: ./application.yaml }
diff --git a/src/apps/retention/config/dependency-injection/index.ts b/src/apps/retention/config/dependency-injection/index.ts
new file mode 100644
index 0000000..27d2a35
--- /dev/null
+++ b/src/apps/retention/config/dependency-injection/index.ts
@@ -0,0 +1,9 @@
+import { ContainerBuilder, YamlFileLoader } from 'node-dependency-injection';
+
+const container = new ContainerBuilder();
+const loader = new YamlFileLoader(container);
+const env = process.env.NODE_ENV || 'dev';
+
+loader.load(`${__dirname}/application_${env}.yaml`);
+
+export default container;
diff --git a/src/apps/retention/subscribers.ts b/src/apps/retention/subscribers.ts
new file mode 100644
index 0000000..6a7667c
--- /dev/null
+++ b/src/apps/retention/subscribers.ts
@@ -0,0 +1,14 @@
+import container from './config/dependency-injection';
+import { InMemoryAsyncEventBus } from '../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus';
+import { Definition } from 'node-dependency-injection';
+import { DomainEventSubscriber } from '../../Contexts/Shared/domain/DomainEventSubscriber';
+import { DomainEvent } from '../../Contexts/Shared/domain/DomainEvent';
+
+export function registerSubscribers() {
+ const eventBus = container.get('Shared.EventBus') as InMemoryAsyncEventBus;
+ const subscriberDefinitions = container.findTaggedServiceIds('domainEventSubscriber') as Map;
+ const subscribers: Array> = [];
+
+ subscriberDefinitions.forEach((value: any, key: any) => subscribers.push(container.get(key)));
+ eventBus.addSubscribers(subscribers);
+}
From 5ef7312f753ebd9ccd755ca6fea2546e2b8cd7c6 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 18 Sep 2020 17:16:14 +0200
Subject: [PATCH 37/48] Course e2e test
---
cypress.json | 3 +
cypress/fixtures/example.json | 5 +
.../integration/backoffice/courses.spec.ts | 14 +
cypress/plugins/index.js | 21 +
cypress/support/commands.js | 25 +
cypress/support/index.js | 20 +
package-lock.json | 1288 +++++++++++++++--
package.json | 5 +-
src/apps/backoffice/frontend/seed.ts | 2 +-
9 files changed, 1287 insertions(+), 96 deletions(-)
create mode 100644 cypress.json
create mode 100644 cypress/fixtures/example.json
create mode 100644 cypress/integration/backoffice/courses.spec.ts
create mode 100644 cypress/plugins/index.js
create mode 100644 cypress/support/commands.js
create mode 100644 cypress/support/index.js
diff --git a/cypress.json b/cypress.json
new file mode 100644
index 0000000..0f0f794
--- /dev/null
+++ b/cypress.json
@@ -0,0 +1,3 @@
+{
+ "video": false
+}
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
new file mode 100644
index 0000000..da18d93
--- /dev/null
+++ b/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
\ No newline at end of file
diff --git a/cypress/integration/backoffice/courses.spec.ts b/cypress/integration/backoffice/courses.spec.ts
new file mode 100644
index 0000000..887fc28
--- /dev/null
+++ b/cypress/integration/backoffice/courses.spec.ts
@@ -0,0 +1,14 @@
+describe('Courses', () => {
+
+ it('can create a course', () => {
+ const courseName = 'New course';
+ cy.visit('http://localhost:8032/courses');
+
+ cy.get('input[name="name"]').type(courseName);
+ cy.get('input[name="duration"]').type('8 days');
+ cy.get('form').submit();
+
+ cy.get('div[role="alert"]').contains(`Felicidades, el curso ${courseName} ha sido creado!`);
+ // cy.contains('Actualmente CodelyTV Pro cuenta con 10 curso');
+ });
+});
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
new file mode 100644
index 0000000..aa9918d
--- /dev/null
+++ b/cypress/plugins/index.js
@@ -0,0 +1,21 @@
+///
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+
+/**
+ * @type {Cypress.PluginConfig}
+ */
+module.exports = (on, config) => {
+ // `on` is used to hook into various events Cypress emits
+ // `config` is the resolved Cypress config
+}
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
new file mode 100644
index 0000000..ca4d256
--- /dev/null
+++ b/cypress/support/commands.js
@@ -0,0 +1,25 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add("login", (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
diff --git a/cypress/support/index.js b/cypress/support/index.js
new file mode 100644
index 0000000..d68db96
--- /dev/null
+++ b/cypress/support/index.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/package-lock.json b/package-lock.json
index 8b6ac16..c6af7e9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -479,6 +479,180 @@
"minimist": "^1.2.0"
}
},
+ "@cypress/listr-verbose-renderer": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz",
+ "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "cli-cursor": "^1.0.2",
+ "date-fns": "^1.27.2",
+ "figures": "^1.7.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "cli-cursor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^1.0.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "onetime": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+ "dev": true,
+ "requires": {
+ "exit-hook": "^1.0.0",
+ "onetime": "^1.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "@cypress/request": {
+ "version": "2.88.5",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz",
+ "integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ },
+ "dependencies": {
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "dev": true
+ }
+ }
+ },
+ "@cypress/xvfb": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
+ "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0",
+ "lodash.once": "^4.1.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
"@dabh/diagnostics": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz",
@@ -988,6 +1162,15 @@
"chalk": "^3.0.0"
}
},
+ "@samverschueren/stream-to-observable": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz",
+ "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==",
+ "dev": true,
+ "requires": {
+ "any-observable": "^0.3.0"
+ }
+ },
"@sinonjs/commons": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
@@ -1308,6 +1491,18 @@
"@types/mime": "*"
}
},
+ "@types/sinonjs__fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz",
+ "integrity": "sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==",
+ "dev": true
+ },
+ "@types/sizzle": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
+ "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==",
+ "dev": true
+ },
"@types/stack-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
@@ -1485,6 +1680,12 @@
"resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768="
},
+ "any-observable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
+ "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
+ "dev": true
+ },
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
@@ -1500,6 +1701,12 @@
"picomatch": "^2.0.4"
}
},
+ "arch": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz",
+ "integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==",
+ "dev": true
+ },
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -1611,6 +1818,12 @@
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true
},
+ "at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true
+ },
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
@@ -1839,6 +2052,12 @@
"safe-buffer": "^5.1.1"
}
},
+ "blob-util": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz",
+ "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==",
+ "dev": true
+ },
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -1920,6 +2139,12 @@
"ieee754": "^1.1.4"
}
},
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "dev": true
+ },
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -1961,6 +2186,12 @@
}
}
},
+ "cachedir": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
+ "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
+ "dev": true
+ },
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -2021,6 +2252,12 @@
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
"dev": true
},
+ "check-more-types": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
+ "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=",
+ "dev": true
+ },
"chokidar": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
@@ -2204,6 +2441,12 @@
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
"dev": true
},
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
"collect-v8-coverage": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
@@ -2294,6 +2537,12 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="
},
+ "common-tags": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
+ "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==",
+ "dev": true
+ },
"compare-versions": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
@@ -2340,6 +2589,18 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
"connect-flash": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz",
@@ -2563,39 +2824,237 @@
"integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==",
"dev": true
},
- "is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
- "dev": true
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true
+ }
+ }
+ },
+ "cucumber-expressions": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/cucumber-expressions/-/cucumber-expressions-8.3.0.tgz",
+ "integrity": "sha512-cP2ya0EiorwXBC7Ll7Cj7NELYbasNv9Ty42L4u7sso9KruWemWG1ZiTq4PMqir3SNDSrbykoqI5wZgMbLEDjLQ==",
+ "dev": true,
+ "requires": {
+ "becke-ch--regex--s0-0-v1--base--pl--lib": "^1.4.0",
+ "xregexp": "^4.2.4"
+ }
+ },
+ "cucumber-tag-expressions": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/cucumber-tag-expressions/-/cucumber-tag-expressions-2.0.3.tgz",
+ "integrity": "sha512-+x5j1IfZrBtbvYHuoUX0rl4nUGxaey6Do9sM0CABmZfDCcWXuuRm1fQeCaklIYQgOFHQ6xOHvDSdkMHHpni6tQ==",
+ "dev": true
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "cypress": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-5.2.0.tgz",
+ "integrity": "sha512-9S2spcrpIXrQ+CQIKHsjRoLQyRc2ehB06clJXPXXp1zyOL/uZMM3Qc20ipNki4CcNwY0nBTQZffPbRpODeGYQg==",
+ "dev": true,
+ "requires": {
+ "@cypress/listr-verbose-renderer": "^0.4.1",
+ "@cypress/request": "^2.88.5",
+ "@cypress/xvfb": "^1.2.4",
+ "@types/sinonjs__fake-timers": "^6.0.1",
+ "@types/sizzle": "^2.3.2",
+ "arch": "^2.1.2",
+ "blob-util": "2.0.2",
+ "bluebird": "^3.7.2",
+ "cachedir": "^2.3.0",
+ "chalk": "^4.1.0",
+ "check-more-types": "^2.24.0",
+ "cli-table3": "~0.6.0",
+ "commander": "^4.1.1",
+ "common-tags": "^1.8.0",
+ "debug": "^4.1.1",
+ "eventemitter2": "^6.4.2",
+ "execa": "^4.0.2",
+ "executable": "^4.1.1",
+ "extract-zip": "^1.7.0",
+ "fs-extra": "^9.0.1",
+ "getos": "^3.2.1",
+ "is-ci": "^2.0.0",
+ "is-installed-globally": "^0.3.2",
+ "lazy-ass": "^1.6.0",
+ "listr": "^0.14.3",
+ "lodash": "^4.17.19",
+ "log-symbols": "^4.0.0",
+ "minimist": "^1.2.5",
+ "moment": "^2.27.0",
+ "ospath": "^1.2.2",
+ "pretty-bytes": "^5.3.0",
+ "ramda": "~0.26.1",
+ "request-progress": "^3.0.0",
+ "supports-color": "^7.1.0",
+ "tmp": "~0.2.1",
+ "untildify": "^4.0.0",
+ "url": "^0.11.0",
+ "yauzl": "^2.10.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cli-table3": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz",
+ "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==",
+ "dev": true,
+ "requires": {
+ "colors": "^1.1.2",
+ "object-assign": "^4.1.0",
+ "string-width": "^4.2.0"
+ }
+ },
+ "commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "execa": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
+ "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
}
}
},
- "cucumber-expressions": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/cucumber-expressions/-/cucumber-expressions-8.3.0.tgz",
- "integrity": "sha512-cP2ya0EiorwXBC7Ll7Cj7NELYbasNv9Ty42L4u7sso9KruWemWG1ZiTq4PMqir3SNDSrbykoqI5wZgMbLEDjLQ==",
- "dev": true,
- "requires": {
- "becke-ch--regex--s0-0-v1--base--pl--lib": "^1.4.0",
- "xregexp": "^4.2.4"
- }
- },
- "cucumber-tag-expressions": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/cucumber-tag-expressions/-/cucumber-tag-expressions-2.0.3.tgz",
- "integrity": "sha512-+x5j1IfZrBtbvYHuoUX0rl4nUGxaey6Do9sM0CABmZfDCcWXuuRm1fQeCaklIYQgOFHQ6xOHvDSdkMHHpni6tQ==",
- "dev": true
- },
- "currently-unhandled": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
- "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
- "dev": true,
- "requires": {
- "array-find-index": "^1.0.1"
- }
- },
"d": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
@@ -2626,6 +3085,12 @@
"whatwg-url": "^8.0.0"
}
},
+ "date-fns": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
+ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
+ "dev": true
+ },
"dateformat": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
@@ -2817,6 +3282,12 @@
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
+ "elegant-spinner": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
+ "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
+ "dev": true
+ },
"emittery": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz",
@@ -2970,6 +3441,12 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
+ "eventemitter2": {
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.3.tgz",
+ "integrity": "sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==",
+ "dev": true
+ },
"exec-sh": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
@@ -2999,12 +3476,27 @@
}
}
},
+ "executable": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
+ "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
+ "dev": true,
+ "requires": {
+ "pify": "^2.2.0"
+ }
+ },
"exit": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
"dev": true
},
+ "exit-hook": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+ "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
+ "dev": true
+ },
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -3228,6 +3720,18 @@
}
}
},
+ "extract-zip": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
+ "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.6.2",
+ "debug": "^2.6.9",
+ "mkdirp": "^0.5.4",
+ "yauzl": "^2.10.0"
+ }
+ },
"extsprintf": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz",
@@ -3272,6 +3776,15 @@
"bser": "2.1.1"
}
},
+ "fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
"fecha": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz",
@@ -3428,6 +3941,18 @@
"resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
"integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0="
},
+ "fs-extra": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
+ "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
+ "dev": true,
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^1.0.0"
+ }
+ },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -3484,6 +4009,15 @@
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
"dev": true
},
+ "getos": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz",
+ "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==",
+ "dev": true,
+ "requires": {
+ "async": "^3.2.0"
+ }
+ },
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -3520,6 +4054,15 @@
"is-glob": "^2.0.0"
}
},
+ "global-dirs": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
+ "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.5"
+ }
+ },
"global-modules": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz",
@@ -3574,6 +4117,23 @@
"har-schema": "^2.0.0"
}
},
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ }
+ }
+ },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3959,6 +4519,16 @@
"is-extglob": "^1.0.0"
}
},
+ "is-installed-globally": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
+ "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
+ "dev": true,
+ "requires": {
+ "global-dirs": "^2.0.1",
+ "is-path-inside": "^3.0.1"
+ }
+ },
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -3970,6 +4540,21 @@
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
+ "is-observable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
+ "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==",
+ "dev": true,
+ "requires": {
+ "symbol-observable": "^1.1.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+ "dev": true
+ },
"is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -3993,6 +4578,12 @@
"integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=",
"dev": true
},
+ "is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+ "dev": true
+ },
"is-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
@@ -5591,6 +6182,16 @@
"minimist": "^1.2.5"
}
},
+ "jsonfile": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
+ "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^1.0.0"
+ }
+ },
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -5644,6 +6245,12 @@
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
},
+ "lazy-ass": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz",
+ "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=",
+ "dev": true
+ },
"lazy-cache": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
@@ -5698,110 +6305,479 @@
},
"dependencies": {
"chalk": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
- "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "commander": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz",
+ "integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "execa": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
+ "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "listr": {
+ "version": "0.14.3",
+ "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz",
+ "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==",
+ "dev": true,
+ "requires": {
+ "@samverschueren/stream-to-observable": "^0.3.0",
+ "is-observable": "^1.1.0",
+ "is-promise": "^2.1.0",
+ "is-stream": "^1.1.0",
+ "listr-silent-renderer": "^1.1.1",
+ "listr-update-renderer": "^0.5.0",
+ "listr-verbose-renderer": "^0.5.0",
+ "p-map": "^2.0.0",
+ "rxjs": "^6.3.3"
+ },
+ "dependencies": {
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true
+ }
+ }
+ },
+ "listr-silent-renderer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
+ "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
+ "dev": true
+ },
+ "listr-update-renderer": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz",
+ "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "cli-truncate": "^0.2.1",
+ "elegant-spinner": "^1.0.1",
+ "figures": "^1.7.0",
+ "indent-string": "^3.0.0",
+ "log-symbols": "^1.0.2",
+ "log-update": "^2.3.0",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
}
},
- "commander": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz",
- "integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==",
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "cli-truncate": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
+ "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
+ "dev": true,
+ "requires": {
+ "slice-ansi": "0.0.4",
+ "string-width": "^1.0.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
- "cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"dev": true,
"requires": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
}
},
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
- "ms": "^2.1.1"
+ "number-is-nan": "^1.0.0"
}
},
- "execa": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
- "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
+ "log-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
"dev": true,
"requires": {
- "cross-spawn": "^7.0.0",
- "get-stream": "^5.0.0",
- "human-signals": "^1.1.1",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.0",
- "onetime": "^5.1.0",
- "signal-exit": "^3.0.2",
- "strip-final-newline": "^2.0.0"
+ "chalk": "^1.0.0"
}
},
- "get-stream": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
- "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "log-update": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz",
+ "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=",
"dev": true,
"requires": {
- "pump": "^3.0.0"
+ "ansi-escapes": "^3.0.0",
+ "cli-cursor": "^2.0.0",
+ "wrap-ansi": "^3.0.1"
}
},
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
"dev": true
},
- "npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"dev": true,
"requires": {
- "path-key": "^3.0.0"
+ "mimic-fn": "^1.0.0"
}
},
- "path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
"dev": true
},
- "shebang-command": {
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
+ "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=",
"dev": true,
"requires": {
- "shebang-regex": "^3.0.0"
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ }
+ }
+ },
+ "listr-verbose-renderer": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz",
+ "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "cli-cursor": "^2.1.0",
+ "date-fns": "^1.27.2",
+ "figures": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
}
},
- "shebang-regex": {
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "has-flag": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"dev": true,
"requires": {
- "isexe": "^2.0.0"
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
}
}
}
@@ -5893,6 +6869,12 @@
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
"dev": true
},
+ "lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=",
+ "dev": true
+ },
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -6247,6 +7229,12 @@
"minimist": "^1.2.5"
}
},
+ "moment": {
+ "version": "2.28.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.28.0.tgz",
+ "integrity": "sha512-Z5KOjYmnHyd/ukynmFd/WwyXHd7L4J9vTI/nn5Ap9AVUgaAE15VvQ9MOGmJJygEUklupqIrFnor/tjTwRU+tQw==",
+ "dev": true
+ },
"mongodb": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz",
@@ -6516,6 +7504,12 @@
"path-key": "^2.0.0"
}
},
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
"nunjucks": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.2.tgz",
@@ -6664,6 +7658,12 @@
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
+ "ospath": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz",
+ "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=",
+ "dev": true
+ },
"p-each-series": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz",
@@ -6795,6 +7795,12 @@
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true
},
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -6872,6 +7878,12 @@
"integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
"dev": true
},
+ "pretty-bytes": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz",
+ "integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==",
+ "dev": true
+ },
"pretty-format": {
"version": "25.5.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
@@ -6941,6 +7953,18 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
},
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "ramda": {
+ "version": "0.26.1",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz",
+ "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==",
+ "dev": true
+ },
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -7166,6 +8190,15 @@
}
}
},
+ "request-progress": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
+ "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=",
+ "dev": true,
+ "requires": {
+ "throttleit": "^1.0.0"
+ }
+ },
"request-promise-core": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
@@ -8237,6 +9270,12 @@
"supports-color": "^7.0.0"
}
},
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
+ "dev": true
+ },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -8293,6 +9332,12 @@
"integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
"dev": true
},
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+ "dev": true
+ },
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -8318,6 +9363,15 @@
"upper-case": "^1.0.3"
}
},
+ "tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "requires": {
+ "rimraf": "^3.0.0"
+ }
+ },
"tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -8841,6 +9895,12 @@
"mime-types": "~2.1.24"
}
},
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
"typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
@@ -8872,6 +9932,12 @@
"set-value": "^2.0.1"
}
},
+ "universalify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
+ "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
+ "dev": true
+ },
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -8923,6 +9989,12 @@
}
}
},
+ "untildify": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
+ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
+ "dev": true
+ },
"upper-case": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
@@ -8944,6 +10016,24 @@
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
"dev": true
},
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -9323,6 +10413,16 @@
"decamelize": "^1.2.0"
}
},
+ "yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+ "dev": true,
+ "requires": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
diff --git a/package.json b/package.json
index 4815d67..e8875ce 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,9 @@
"build": "npm run build:clean && npm run build:tsc && npm run build:di",
"build:tsc": "tsc -p tsconfig.prod.json",
"build:di": "copy 'src/**/*.{json,yaml,html,png}' dist/src",
- "build:clean": "rm -r dist; exit 0"
+ "build:clean": "rm -r dist; exit 0",
+ "cypress:open": "NODE_ENV=test cypress open",
+ "cypress:run": "NODE_ENV=test cypress run"
},
"dependencies": {
"@types/bson": "^4.0.2",
@@ -71,6 +73,7 @@
"@types/nunjucks": "^3.1.3",
"@types/supertest": "^2.0.10",
"cucumber": "^6.0.5",
+ "cypress": "^5.2.0",
"faker": "^5.1.0",
"husky": "^4.3.0",
"jest": "^26.4.2",
diff --git a/src/apps/backoffice/frontend/seed.ts b/src/apps/backoffice/frontend/seed.ts
index 03f871f..09df2a1 100644
--- a/src/apps/backoffice/frontend/seed.ts
+++ b/src/apps/backoffice/frontend/seed.ts
@@ -10,7 +10,7 @@ export async function seed() {
const alreadyExists = await repository.search();
const isTestEnvironment = process.env.NODE_ENV === 'test';
- if (!alreadyExists && !isTestEnvironment) {
+ if (!alreadyExists) {
logger.info('[Seed] Initializing CourseCounter');
const courseCounter = CoursesCounter.initialize(CoursesCounterId.random());
await repository.save(courseCounter);
From 9ee5023f30785fc9b24adb2a969a19ed5ef9e0f7 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 18 Sep 2020 17:39:37 +0200
Subject: [PATCH 38/48] Add default baseUrl
---
cypress.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/cypress.json b/cypress.json
index 0f0f794..0163845 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,3 +1,4 @@
{
- "video": false
+ "baseUrl": "http://localhost:8032",
+ "video": false
}
From 7be2cbbe044a67b7fdb96deb48ab2b4fcfdae0f5 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Sat, 19 Sep 2020 15:12:58 +0200
Subject: [PATCH 39/48] Add cypress plugin to clean/seed database
---
.../integration/backoffice/courses.spec.ts | 26 ++++++++++++++-----
cypress/plugins/index.js | 21 ---------------
cypress/plugins/index.ts | 15 +++++++++++
cypress/tsconfig.json | 11 ++++++++
.../controllers/CoursesPostController.ts | 2 +-
5 files changed, 46 insertions(+), 29 deletions(-)
delete mode 100644 cypress/plugins/index.js
create mode 100644 cypress/plugins/index.ts
create mode 100644 cypress/tsconfig.json
diff --git a/cypress/integration/backoffice/courses.spec.ts b/cypress/integration/backoffice/courses.spec.ts
index 887fc28..c7fc9b1 100644
--- a/cypress/integration/backoffice/courses.spec.ts
+++ b/cypress/integration/backoffice/courses.spec.ts
@@ -1,14 +1,26 @@
+import faker from 'faker';
+
describe('Courses', () => {
- it('can create a course', () => {
- const courseName = 'New course';
+ beforeEach(() => {
+ cy.task('reset:db');
+ });
+
+ it('can create courses', () => {
cy.visit('http://localhost:8032/courses');
- cy.get('input[name="name"]').type(courseName);
- cy.get('input[name="duration"]').type('8 days');
- cy.get('form').submit();
+ cy.contains('Actualmente CodelyTV Pro cuenta con 0 cursos.');
+
+ let i = 0;
+ while (i <= 5) {
+ i++;
+ const courseName = faker.lorem.sentence(2);
+ cy.get('input[name="name"]').type(courseName);
+ cy.get('input[name="duration"]').type('8 days');
+ cy.get('form').submit();
- cy.get('div[role="alert"]').contains(`Felicidades, el curso ${courseName} ha sido creado!`);
- // cy.contains('Actualmente CodelyTV Pro cuenta con 10 curso');
+ cy.get('div[role="alert"]').contains(`Felicidades, el curso ${courseName} ha sido creado!`);
+ cy.contains(`Actualmente CodelyTV Pro cuenta con ${i} cursos.`);
+ }
});
});
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
deleted file mode 100644
index aa9918d..0000000
--- a/cypress/plugins/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-///
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
-
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
-
-/**
- * @type {Cypress.PluginConfig}
- */
-module.exports = (on, config) => {
- // `on` is used to hook into various events Cypress emits
- // `config` is the resolved Cypress config
-}
diff --git a/cypress/plugins/index.ts b/cypress/plugins/index.ts
new file mode 100644
index 0000000..a40e856
--- /dev/null
+++ b/cypress/plugins/index.ts
@@ -0,0 +1,15 @@
+import container from '../../src/apps/mooc_backend/config/dependency-injection';
+import { EnvironmentArranger } from '../../tests/Contexts/Shared/infrastructure/arranger/EnvironmentArranger';
+import {seed} from '../../src/apps/backoffice/frontend/seed';
+
+const environmentArranger: Promise = container.get('Mooc.EnvironmentArranger');
+
+export default (on: Cypress.PluginEvents, config: Cypress.PluginConfig) => {
+ on('task', {
+ async 'reset:db'() {
+ await (await environmentArranger).arrange();
+ await seed();
+ return null;
+ }
+ });
+};
diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json
new file mode 100644
index 0000000..f507fd4
--- /dev/null
+++ b/cypress/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "lib": ["es2015", "dom"],
+ "types": ["cypress"]
+ },
+ "include": [
+ "**/*.ts"
+ ]
+}
+
diff --git a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
index f7cd3ff..efa1c49 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
@@ -12,7 +12,7 @@ export class CoursesPostController extends WebController {
static validator(): ValidationChain[] {
return [
body('id').isUUID(),
- body('name').isLength({ min: 1, max: 255 }),
+ body('name').isLength({ min: 1, max: 30 }),
body('duration').isLength({ min: 4, max: 100 })
];
}
From e98713d37574bd23f8dcb9b4075fc27895bd4ea1 Mon Sep 17 00:00:00 2001
From: Fernando Vilas Maciel
Date: Mon, 21 Sep 2020 09:30:38 +0200
Subject: [PATCH 40/48] Add script for launching the server before the cypress
run
---
.gitignore | 1 +
.../integration/backoffice/courses.spec.ts | 2 +-
cypress/plugins/index.ts | 2 +-
cypress/start.ts | 37 +++++++++++++++++++
package.json | 2 +-
5 files changed, 41 insertions(+), 3 deletions(-)
create mode 100644 cypress/start.ts
diff --git a/.gitignore b/.gitignore
index aab2965..6bb7f1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ dist/
logs/
src/Contexts/Mooc/Courses/infrastructure/persistence/courses.*
data
+test-results.xml
diff --git a/cypress/integration/backoffice/courses.spec.ts b/cypress/integration/backoffice/courses.spec.ts
index c7fc9b1..4008e8e 100644
--- a/cypress/integration/backoffice/courses.spec.ts
+++ b/cypress/integration/backoffice/courses.spec.ts
@@ -20,7 +20,7 @@ describe('Courses', () => {
cy.get('form').submit();
cy.get('div[role="alert"]').contains(`Felicidades, el curso ${courseName} ha sido creado!`);
- cy.contains(`Actualmente CodelyTV Pro cuenta con ${i} cursos.`);
+ // cy.contains(`Actualmente CodelyTV Pro cuenta con ${i} cursos.`);
}
});
});
diff --git a/cypress/plugins/index.ts b/cypress/plugins/index.ts
index a40e856..7274878 100644
--- a/cypress/plugins/index.ts
+++ b/cypress/plugins/index.ts
@@ -1,6 +1,6 @@
import container from '../../src/apps/mooc_backend/config/dependency-injection';
import { EnvironmentArranger } from '../../tests/Contexts/Shared/infrastructure/arranger/EnvironmentArranger';
-import {seed} from '../../src/apps/backoffice/frontend/seed';
+import { seed } from '../../src/apps/backoffice/frontend/seed';
const environmentArranger: Promise = container.get('Mooc.EnvironmentArranger');
diff --git a/cypress/start.ts b/cypress/start.ts
new file mode 100644
index 0000000..7cc7227
--- /dev/null
+++ b/cypress/start.ts
@@ -0,0 +1,37 @@
+import app from '../src/apps/backoffice/frontend/app';
+import cypress from 'cypress';
+import { Server } from 'http';
+
+async function run() {
+ const server = await startServer();
+ await runCypress();
+ server.close(() => {
+ process.exit(0);
+ });
+}
+
+async function startServer(): Promise {
+ let server: Server;
+
+ return new Promise((resolve, reject) => {
+ server = app.listen(app.get('port'), async () => {
+ console.log(` Backoffice frontend is running at http://localhost:${app.get('port')} in ${app.get('env')} mode`);
+ console.log(' Press CTRL-C to stop\n');
+ resolve(server);
+ });
+ });
+}
+
+async function runCypress() {
+ return cypress.run({
+ reporter: 'junit',
+ browser: 'chrome',
+ headless: true,
+ config: {
+ baseUrl: `http://localhost:${app.get('port')}`,
+ video: false
+ }
+ });
+}
+
+run();
diff --git a/package.json b/package.json
index e8875ce..02ec8ed 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
"build:di": "copy 'src/**/*.{json,yaml,html,png}' dist/src",
"build:clean": "rm -r dist; exit 0",
"cypress:open": "NODE_ENV=test cypress open",
- "cypress:run": "NODE_ENV=test cypress run"
+ "cypress:run": "NODE_ENV=test ts-node cypress/start"
},
"dependencies": {
"@types/bson": "^4.0.2",
From 11d0d5637fbd1ebea2982f51eb7059f65a691f38 Mon Sep 17 00:00:00 2001
From: Fernando Vilas Maciel
Date: Fri, 25 Sep 2020 16:05:20 +0200
Subject: [PATCH 41/48] Fix asynchronous test at the cypress backoffice tests
Co-authored-by: David Matas
---
cypress.json | 5 +++--
cypress/integration/backoffice/courses.spec.ts | 2 +-
cypress/start.ts | 3 ++-
src/Contexts/Mooc/Courses/application/CourseCreator.ts | 2 +-
.../application/Increment/CoursesCounterIncrementer.ts | 2 +-
.../config/dependency-injection/Shared/application.yaml | 2 +-
6 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/cypress.json b/cypress.json
index 0163845..68d2c3f 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,4 +1,5 @@
{
- "baseUrl": "http://localhost:8032",
- "video": false
+ "video": false,
+ "screenshotOnRunFailure": false
+
}
diff --git a/cypress/integration/backoffice/courses.spec.ts b/cypress/integration/backoffice/courses.spec.ts
index 4008e8e..c7fc9b1 100644
--- a/cypress/integration/backoffice/courses.spec.ts
+++ b/cypress/integration/backoffice/courses.spec.ts
@@ -20,7 +20,7 @@ describe('Courses', () => {
cy.get('form').submit();
cy.get('div[role="alert"]').contains(`Felicidades, el curso ${courseName} ha sido creado!`);
- // cy.contains(`Actualmente CodelyTV Pro cuenta con ${i} cursos.`);
+ cy.contains(`Actualmente CodelyTV Pro cuenta con ${i} cursos.`);
}
});
});
diff --git a/cypress/start.ts b/cypress/start.ts
index 7cc7227..479433e 100644
--- a/cypress/start.ts
+++ b/cypress/start.ts
@@ -1,6 +1,7 @@
import app from '../src/apps/backoffice/frontend/app';
import cypress from 'cypress';
import { Server } from 'http';
+import cypressConfig from '../cypress.json';
async function run() {
const server = await startServer();
@@ -28,8 +29,8 @@ async function runCypress() {
browser: 'chrome',
headless: true,
config: {
+ ...cypressConfig,
baseUrl: `http://localhost:${app.get('port')}`,
- video: false
}
});
}
diff --git a/src/Contexts/Mooc/Courses/application/CourseCreator.ts b/src/Contexts/Mooc/Courses/application/CourseCreator.ts
index 0880cdf..db2b81b 100644
--- a/src/Contexts/Mooc/Courses/application/CourseCreator.ts
+++ b/src/Contexts/Mooc/Courses/application/CourseCreator.ts
@@ -29,6 +29,6 @@ export class CourseCreator {
);
await this.repository.save(course);
- this.eventBus.publish(course.pullDomainEvents());
+ await this.eventBus.publish(course.pullDomainEvents());
}
}
diff --git a/src/Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer.ts b/src/Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer.ts
index 957b051..8b4ce66 100644
--- a/src/Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer.ts
+++ b/src/Contexts/Mooc/CoursesCounter/application/Increment/CoursesCounterIncrementer.ts
@@ -14,7 +14,7 @@ export class CoursesCounterIncrementer {
counter.increment(courseId);
await this.repository.save(counter);
- this.bus.publish(counter.pullDomainEvents());
+ await this.bus.publish(counter.pullDomainEvents());
}
}
diff --git a/src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml b/src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml
index 813e2c5..043d1ed 100644
--- a/src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml
+++ b/src/apps/backoffice/frontend/config/dependency-injection/Shared/application.yaml
@@ -10,7 +10,7 @@ services:
arguments: ['mooc']
Shared.EventBus:
- class: ../../../../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus
+ class: ../../../../../../Contexts/Shared/infrastructure/EventBus/InMemorySyncEventBus
arguments: []
Shared.QueryBus:
From 202d49c909a5244d32bc03d88d6708f233dfe9a2 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 2 Oct 2020 20:13:14 +0200
Subject: [PATCH 42/48] Cypress root modification
---
cypress.json | 7 +++-
cypress/start.ts | 38 -------------------
package.json | 6 +--
.../features/courses/create_course.cypress.ts | 1 -
.../utils/cypress}/fixtures/example.json | 0
tests/utils/cypress/open.ts | 16 ++++++++
.../utils/cypress}/plugins/index.ts | 6 +--
tests/utils/cypress/run.ts | 26 +++++++++++++
.../utils/cypress/startBackofficeFrontend.ts | 14 +++++++
.../utils/cypress}/tsconfig.json | 6 +--
10 files changed, 69 insertions(+), 51 deletions(-)
delete mode 100644 cypress/start.ts
rename cypress/integration/backoffice/courses.spec.ts => tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts (99%)
rename {cypress => tests/utils/cypress}/fixtures/example.json (100%)
create mode 100644 tests/utils/cypress/open.ts
rename {cypress => tests/utils/cypress}/plugins/index.ts (55%)
create mode 100644 tests/utils/cypress/run.ts
create mode 100644 tests/utils/cypress/startBackofficeFrontend.ts
rename {cypress => tests/utils/cypress}/tsconfig.json (57%)
diff --git a/cypress.json b/cypress.json
index 68d2c3f..3cf53f8 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,5 +1,8 @@
{
"video": false,
- "screenshotOnRunFailure": false
-
+ "screenshotOnRunFailure": false,
+ "testFiles": "**/*.cypress.*",
+ "integrationFolder": "tests/apps",
+ "fixturesFolder": "tests/utils/cypress/fixtures",
+ "pluginsFile": "tests/utils/cypress/plugins/index.ts"
}
diff --git a/cypress/start.ts b/cypress/start.ts
deleted file mode 100644
index 479433e..0000000
--- a/cypress/start.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import app from '../src/apps/backoffice/frontend/app';
-import cypress from 'cypress';
-import { Server } from 'http';
-import cypressConfig from '../cypress.json';
-
-async function run() {
- const server = await startServer();
- await runCypress();
- server.close(() => {
- process.exit(0);
- });
-}
-
-async function startServer(): Promise {
- let server: Server;
-
- return new Promise((resolve, reject) => {
- server = app.listen(app.get('port'), async () => {
- console.log(` Backoffice frontend is running at http://localhost:${app.get('port')} in ${app.get('env')} mode`);
- console.log(' Press CTRL-C to stop\n');
- resolve(server);
- });
- });
-}
-
-async function runCypress() {
- return cypress.run({
- reporter: 'junit',
- browser: 'chrome',
- headless: true,
- config: {
- ...cypressConfig,
- baseUrl: `http://localhost:${app.get('port')}`,
- }
- });
-}
-
-run();
diff --git a/package.json b/package.json
index 02ec8ed..bfcd977 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"scripts": {
"dev": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules --inspect=0.0.0.0:9267 ./src/apps/mooc_backend/server.ts",
"dev:backoffice:frontend": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules ./src/apps/backoffice/frontend/server.ts",
- "test": "npm run test:unit && npm run test:features",
+ "test": "npm run test:unit && npm run test:features && npm run cypress:run",
"test:unit": "NODE_ENV=test jest",
"test:features": "NODE_ENV=test cucumber-js -p default",
"lint": "tslint src/**/*.ts{,x}",
@@ -23,8 +23,8 @@
"build:tsc": "tsc -p tsconfig.prod.json",
"build:di": "copy 'src/**/*.{json,yaml,html,png}' dist/src",
"build:clean": "rm -r dist; exit 0",
- "cypress:open": "NODE_ENV=test cypress open",
- "cypress:run": "NODE_ENV=test ts-node cypress/start"
+ "cypress:open": "NODE_ENV=test ts-node tests/utils/cypress/open",
+ "cypress:run": "NODE_ENV=test ts-node tests/utils/cypress/run"
},
"dependencies": {
"@types/bson": "^4.0.2",
diff --git a/cypress/integration/backoffice/courses.spec.ts b/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
similarity index 99%
rename from cypress/integration/backoffice/courses.spec.ts
rename to tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
index c7fc9b1..0c1b8b1 100644
--- a/cypress/integration/backoffice/courses.spec.ts
+++ b/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
@@ -1,7 +1,6 @@
import faker from 'faker';
describe('Courses', () => {
-
beforeEach(() => {
cy.task('reset:db');
});
diff --git a/cypress/fixtures/example.json b/tests/utils/cypress/fixtures/example.json
similarity index 100%
rename from cypress/fixtures/example.json
rename to tests/utils/cypress/fixtures/example.json
diff --git a/tests/utils/cypress/open.ts b/tests/utils/cypress/open.ts
new file mode 100644
index 0000000..5a17c51
--- /dev/null
+++ b/tests/utils/cypress/open.ts
@@ -0,0 +1,16 @@
+import cypress from 'cypress';
+import { startBackofficeFrontend } from './startBackofficeFrontend';
+
+async function open() {
+ const server = await startBackofficeFrontend();
+ await openCypress();
+ server.close(() => {
+ process.exit(0);
+ });
+}
+
+async function openCypress() {
+ return cypress.open();
+}
+
+open();
diff --git a/cypress/plugins/index.ts b/tests/utils/cypress/plugins/index.ts
similarity index 55%
rename from cypress/plugins/index.ts
rename to tests/utils/cypress/plugins/index.ts
index 7274878..ebfeb08 100644
--- a/cypress/plugins/index.ts
+++ b/tests/utils/cypress/plugins/index.ts
@@ -1,6 +1,6 @@
-import container from '../../src/apps/mooc_backend/config/dependency-injection';
-import { EnvironmentArranger } from '../../tests/Contexts/Shared/infrastructure/arranger/EnvironmentArranger';
-import { seed } from '../../src/apps/backoffice/frontend/seed';
+import container from '../../../../src/apps/mooc_backend/config/dependency-injection';
+import { EnvironmentArranger } from '../../../Contexts/Shared/infrastructure/arranger/EnvironmentArranger';
+import { seed } from '../../../../src/apps/backoffice/frontend/seed';
const environmentArranger: Promise = container.get('Mooc.EnvironmentArranger');
diff --git a/tests/utils/cypress/run.ts b/tests/utils/cypress/run.ts
new file mode 100644
index 0000000..e4e2862
--- /dev/null
+++ b/tests/utils/cypress/run.ts
@@ -0,0 +1,26 @@
+import app from '../../../src/apps/backoffice/frontend/app';
+import cypress from 'cypress';
+import cypressConfig from '../../../cypress.json';
+import { startBackofficeFrontend } from './startBackofficeFrontend';
+
+async function run() {
+ const server = await startBackofficeFrontend();
+ await runCypress();
+ server.close(() => {
+ process.exit(0);
+ });
+}
+
+async function runCypress() {
+ return cypress.run({
+ reporter: 'junit',
+ browser: 'chrome',
+ headless: true,
+ config: {
+ ...cypressConfig,
+ baseUrl: `http://localhost:${app.get('port')}`
+ }
+ });
+}
+
+run();
diff --git a/tests/utils/cypress/startBackofficeFrontend.ts b/tests/utils/cypress/startBackofficeFrontend.ts
new file mode 100644
index 0000000..5fa1f6b
--- /dev/null
+++ b/tests/utils/cypress/startBackofficeFrontend.ts
@@ -0,0 +1,14 @@
+import app from '../../../src/apps/backoffice/frontend/app';
+import { Server } from 'http';
+
+export async function startBackofficeFrontend(): Promise {
+ let server: Server;
+
+ return new Promise((resolve, reject) => {
+ server = app.listen(app.get('port'), async () => {
+ console.log(` Backoffice frontend is running at http://localhost:${app.get('port')} in ${app.get('env')} mode`);
+ console.log(' Press CTRL-C to stop\n');
+ resolve(server);
+ });
+ });
+}
diff --git a/cypress/tsconfig.json b/tests/utils/cypress/tsconfig.json
similarity index 57%
rename from cypress/tsconfig.json
rename to tests/utils/cypress/tsconfig.json
index f507fd4..cf8c499 100644
--- a/cypress/tsconfig.json
+++ b/tests/utils/cypress/tsconfig.json
@@ -1,11 +1,9 @@
{
- "extends": "../tsconfig.json",
+ "extends": "../../../tsconfig.json",
"compilerOptions": {
"lib": ["es2015", "dom"],
"types": ["cypress"]
},
- "include": [
- "**/*.ts"
- ]
+ "include": ["**/*.ts"]
}
From da23a4b0f16a6cc5885f8801827cea282dec0d52 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 2 Oct 2020 20:13:39 +0200
Subject: [PATCH 43/48] Avoid Cypress/Jest types colision
---
tsconfig.json | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tsconfig.json b/tsconfig.json
index eb52c0a..c91bb5a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,10 +13,7 @@
"outDir": "./dist"
},
"include": [
- "src/**/**.ts",
- "tests/**/**.ts",
- "package*.json",
- "project*.json"
+ "src/**/**.ts"
],
"exclude": ["node_modules"]
}
From bc7dee7cbed2f9d9847a007306a90381f205ae0a Mon Sep 17 00:00:00 2001
From: David Matas
Date: Fri, 2 Oct 2020 21:11:07 +0200
Subject: [PATCH 44/48] Fine tune
---
cypress/support/commands.js | 25 -------------------
cypress/support/index.js | 20 ---------------
.../features/courses/create_course.cypress.ts | 2 +-
tests/{utils/cypress => }/tsconfig.json | 2 +-
tests/utils/cypress/open.ts | 8 +++++-
tests/utils/cypress/run.ts | 1 +
6 files changed, 10 insertions(+), 48 deletions(-)
delete mode 100644 cypress/support/commands.js
delete mode 100644 cypress/support/index.js
rename tests/{utils/cypress => }/tsconfig.json (74%)
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
deleted file mode 100644
index ca4d256..0000000
--- a/cypress/support/commands.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// ***********************************************
-// This example commands.js shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add("login", (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
diff --git a/cypress/support/index.js b/cypress/support/index.js
deleted file mode 100644
index d68db96..0000000
--- a/cypress/support/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// ***********************************************************
-// This example support/index.js is processed and
-// loaded automatically before your test files.
-//
-// This is a great place to put global configuration and
-// behavior that modifies Cypress.
-//
-// You can change the location of this file or turn off
-// automatically serving support files with the
-// 'supportFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/configuration
-// ***********************************************************
-
-// Import commands.js using ES2015 syntax:
-import './commands'
-
-// Alternatively you can use CommonJS syntax:
-// require('./commands')
diff --git a/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts b/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
index 0c1b8b1..f8a8a3c 100644
--- a/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
+++ b/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
@@ -6,7 +6,7 @@ describe('Courses', () => {
});
it('can create courses', () => {
- cy.visit('http://localhost:8032/courses');
+ cy.visit('courses');
cy.contains('Actualmente CodelyTV Pro cuenta con 0 cursos.');
diff --git a/tests/utils/cypress/tsconfig.json b/tests/tsconfig.json
similarity index 74%
rename from tests/utils/cypress/tsconfig.json
rename to tests/tsconfig.json
index cf8c499..4392b35 100644
--- a/tests/utils/cypress/tsconfig.json
+++ b/tests/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.json",
+ "extends": "../tsconfig.json",
"compilerOptions": {
"lib": ["es2015", "dom"],
"types": ["cypress"]
diff --git a/tests/utils/cypress/open.ts b/tests/utils/cypress/open.ts
index 5a17c51..c81c28d 100644
--- a/tests/utils/cypress/open.ts
+++ b/tests/utils/cypress/open.ts
@@ -1,5 +1,6 @@
import cypress from 'cypress';
import { startBackofficeFrontend } from './startBackofficeFrontend';
+import app from '../../../src/apps/backoffice/frontend/app';
async function open() {
const server = await startBackofficeFrontend();
@@ -10,7 +11,12 @@ async function open() {
}
async function openCypress() {
- return cypress.open();
+ return cypress.open({
+ config: {
+ supportFile: false,
+ baseUrl: `http://localhost:${app.get('port')}`
+ }
+ });
}
open();
diff --git a/tests/utils/cypress/run.ts b/tests/utils/cypress/run.ts
index e4e2862..4544ad8 100644
--- a/tests/utils/cypress/run.ts
+++ b/tests/utils/cypress/run.ts
@@ -18,6 +18,7 @@ async function runCypress() {
headless: true,
config: {
...cypressConfig,
+ supportFile: false,
baseUrl: `http://localhost:${app.get('port')}`
}
});
From fc97497b923c0578c956ab3562782c5bf243dac9 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Sun, 18 Oct 2020 11:40:23 +0200
Subject: [PATCH 45/48] Move specific TS config for cypress to app folder tests
---
tests/{ => apps}/tsconfig.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename tests/{ => apps}/tsconfig.json (75%)
diff --git a/tests/tsconfig.json b/tests/apps/tsconfig.json
similarity index 75%
rename from tests/tsconfig.json
rename to tests/apps/tsconfig.json
index 4392b35..48ceea6 100644
--- a/tests/tsconfig.json
+++ b/tests/apps/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../tsconfig.json",
+ "extends": "../../tsconfig.json",
"compilerOptions": {
"lib": ["es2015", "dom"],
"types": ["cypress"]
From 5bd79e37eb12744cadbc5652a450250b3fb7bf09 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Sun, 18 Oct 2020 17:12:02 +0200
Subject: [PATCH 46/48] Include more e2e tests
---
package-lock.json | 6 +-
package.json | 2 +-
.../controllers/CoursesPostController.ts | 6 +-
.../frontend/controllers/WebController.ts | 2 +-
.../features/courses/create_course.cypress.ts | 115 +++++++++++++++++-
5 files changed, 119 insertions(+), 12 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index c6af7e9..0b53e94 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1352,9 +1352,9 @@
}
},
"@types/faker": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.0.tgz",
- "integrity": "sha512-7iK+rNvtSmG3FcAgI67BphmQVzBPkI6SCjJqR/SXxGr6tDUoMovkhGYIxNICEfy/trTgiGQL2v1tKPuFEXIrQg==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.2.tgz",
+ "integrity": "sha512-a3FADSHjjinczCwr7tTejoMZzbSS5vi70VCyns4C1idxJrDSRGZCQG0s27YppXLcoWrBOkwBbBsZ9vDRDpQK7A==",
"dev": true
},
"@types/glob": {
diff --git a/package.json b/package.json
index bfcd977..ff3c9df 100644
--- a/package.json
+++ b/package.json
@@ -68,7 +68,7 @@
"@types/cookie-parser": "^1.4.2",
"@types/cookie-session": "^2.0.41",
"@types/cucumber": "^6.0.1",
- "@types/faker": "^5.1.0",
+ "@types/faker": "^5.1.2",
"@types/jest": "^26.0.14",
"@types/nunjucks": "^3.1.3",
"@types/supertest": "^2.0.10",
diff --git a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
index efa1c49..204c996 100644
--- a/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
+++ b/src/apps/backoffice/frontend/controllers/CoursesPostController.ts
@@ -11,9 +11,9 @@ export class CoursesPostController extends WebController {
static validator(): ValidationChain[] {
return [
- body('id').isUUID(),
- body('name').isLength({ min: 1, max: 30 }),
- body('duration').isLength({ min: 4, max: 100 })
+ body('id').isUUID().withMessage('Invalid course id'),
+ body('name').isLength({ min: 1, max: 30 }).withMessage('Invalid name'),
+ body('duration').isLength({ min: 4, max: 100 }).withMessage('Invalid duration')
];
}
diff --git a/src/apps/backoffice/frontend/controllers/WebController.ts b/src/apps/backoffice/frontend/controllers/WebController.ts
index ae64abb..5ba63be 100644
--- a/src/apps/backoffice/frontend/controllers/WebController.ts
+++ b/src/apps/backoffice/frontend/controllers/WebController.ts
@@ -40,7 +40,7 @@ export abstract class WebController {
protected render(req: Request, res: Response, template: string, data: { [key: string]: any }) {
const flash = this.feedFlash(req, data);
- res.render('pages/courses/courses', {
+ res.render(template, {
...data,
...flash
});
diff --git a/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts b/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
index f8a8a3c..65ecd0e 100644
--- a/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
+++ b/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
@@ -1,19 +1,21 @@
import faker from 'faker';
describe('Courses', () => {
- beforeEach(() => {
+ before(() => {
cy.task('reset:db');
});
- it('can create courses', () => {
+ beforeEach(() => {
cy.visit('courses');
+ });
+ it('can create courses', () => {
cy.contains('Actualmente CodelyTV Pro cuenta con 0 cursos.');
let i = 0;
- while (i <= 5) {
+ while (i <= 3) {
i++;
- const courseName = faker.lorem.sentence(2);
+ const courseName = faker.random.words(1);
cy.get('input[name="name"]').type(courseName);
cy.get('input[name="duration"]').type('8 days');
cy.get('form').submit();
@@ -22,4 +24,109 @@ describe('Courses', () => {
cy.contains(`Actualmente CodelyTV Pro cuenta con ${i} cursos.`);
}
});
+
+ describe('Course id field', () => {
+ it('has value by default', () => {
+ cy.get('input[name="id"]').invoke('val').should('not.be.empty');
+ });
+
+ it('has flash messages when is invalid', () => {
+ cy.get('input[name="id"]').clear().type('invalid course id');
+ cy.get('form').submit();
+
+ cy.get('input[name="id"] + p').contains('Invalid course id');
+ });
+
+ it('maintain the value introduced by the user when invalid', () => {
+ cy.get('input[name="id"]').clear().type('invalid course id');
+ cy.get('form').submit();
+
+ cy.get('input[name="id"]').should('have.value', 'invalid course id');
+ });
+
+ it('maintain the value introduced by the user when valid', () => {
+ const uuid = faker.random.uuid();
+
+ cy.get('input[name="id"]').clear().type(uuid);
+ cy.get('form').submit();
+
+ cy.get('input[name="id"]').should('have.value', uuid);
+ });
+ });
+
+ describe('Name field', () => {
+ it('has flash messages when is empty', () => {
+ cy.get('form').submit();
+
+ cy.get('input[name="name"] + p').contains('Invalid name');
+ });
+
+ it('has flash messages when is longer than 30 character', () => {
+ cy.get('input[name="name"]').type(faker.random.alphaNumeric(31));
+
+ cy.get('form').submit();
+
+ cy.get('input[name="name"] + p').contains('Invalid name');
+ });
+
+ it('maintain the value introduced by the user when invalid', () => {
+ const invalidCourseName = faker.random.alphaNumeric(3);
+
+ cy.get('input[name="name"]').clear().type(invalidCourseName);
+ cy.get('form').submit();
+
+ cy.get('input[name="name"]').should('have.value', invalidCourseName);
+ });
+
+ it('maintain the value introduced by the user when valid', () => {
+ const validCourseName = faker.random.alphaNumeric(1);
+
+ cy.get('input[name="name"]').clear().type(validCourseName);
+ cy.get('form').submit();
+
+ cy.get('input[name="name"]').should('have.value', validCourseName);
+ });
+ });
+
+ describe('Duration field', () => {
+ it('has flash messages when is empty', () => {
+ cy.get('form').submit();
+
+ cy.get('input[name="duration"] + p').contains('Invalid duration');
+ });
+
+ it('has flash messages when is shorter than 4 character', () => {
+ cy.get('input[name="duration"]').type(faker.random.alphaNumeric(3));
+
+ cy.get('form').submit();
+
+ cy.get('input[name="duration"] + p').contains('Invalid duration');
+ });
+
+ it('has flash messages when is longer than 100 character', () => {
+ cy.get('input[name="duration"]').type(faker.random.alphaNumeric(101));
+
+ cy.get('form').submit();
+
+ cy.get('input[name="duration"] + p').contains('Invalid duration');
+ });
+
+ it('maintain the value introduced by the user when invalid', () => {
+ const invalidCourseDuration = faker.random.alphaNumeric(101);
+
+ cy.get('input[name="duration"]').clear().type(invalidCourseDuration);
+ cy.get('form').submit();
+
+ cy.get('input[name="duration"]').should('have.value', invalidCourseDuration);
+ });
+
+ it('maintain the value introduced by the user when valid', () => {
+ const validCourseDuration = faker.random.alphaNumeric(5);
+
+ cy.get('input[name="duration"]').clear().type(validCourseDuration);
+ cy.get('form').submit();
+
+ cy.get('input[name="duration"]').should('have.value', validCourseDuration);
+ });
+ });
});
From 9f907316423f98eb30a62529b847d9c67e2ebf04 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Thu, 22 Oct 2020 12:45:06 +0200
Subject: [PATCH 47/48] Change folder names
---
.../frontend}/features/courses/create_course.cypress.ts | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename tests/apps/{backoffice_frontend => backoffice/frontend}/features/courses/create_course.cypress.ts (100%)
diff --git a/tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts b/tests/apps/backoffice/frontend/features/courses/create_course.cypress.ts
similarity index 100%
rename from tests/apps/backoffice_frontend/features/courses/create_course.cypress.ts
rename to tests/apps/backoffice/frontend/features/courses/create_course.cypress.ts
From 6d27b8e8320f9331a2d739d3eeb457ae859610c7 Mon Sep 17 00:00:00 2001
From: David Matas
Date: Sat, 21 Nov 2020 13:57:25 +0100
Subject: [PATCH 48/48] Remove unneded file
---
.../persistence/FileCourseRepository.ts | 28 -------------------
1 file changed, 28 deletions(-)
delete mode 100644 src/Contexts/Mooc/Courses/infrastructure/persistence/FileCourseRepository.ts
diff --git a/src/Contexts/Mooc/Courses/infrastructure/persistence/FileCourseRepository.ts b/src/Contexts/Mooc/Courses/infrastructure/persistence/FileCourseRepository.ts
deleted file mode 100644
index 499baf3..0000000
--- a/src/Contexts/Mooc/Courses/infrastructure/persistence/FileCourseRepository.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { CourseRepository } from '../../domain/CourseRepository';
-import { Course } from '../../domain/Course';
-import fs from 'fs';
-import BSON from 'bson';
-import { Nullable } from '../../../../Shared/domain/Nullable';
-import { CourseId } from '../../../Shared/domain/Courses/CourseId';
-
-export class FileCourseRepository implements CourseRepository {
- private FILE_PATH = `${__dirname}/courses`;
-
- async save(course: Course): Promise {
- const filePath = this.filePath(course.id.value);
- const data = BSON.serialize(course);
-
- return fs.writeFileSync(filePath, data);
- }
-
- async search(id: CourseId): Promise> {
- const filePath = this.filePath(id.value);
- const exists = fs.existsSync(filePath);
-
- return exists ? BSON.deserialize(fs.readFileSync(this.filePath(id.value))) : null;
- }
-
- private filePath(id: string): string {
- return `${this.FILE_PATH}.${id}.repo`;
- }
-}