From ed135c8b66e529fef76121c7f4a73f23e7d25fb1 Mon Sep 17 00:00:00 2001 From: azu Date: Sun, 6 May 2018 22:27:55 +0900 Subject: [PATCH] fix(Entity): receive Props instead of id BREAKING CHANGE: This change require props object always on Entity https://github.com/almin/ddd-base/issues/4 --- package.json | 12 ++-- src/Entity.ts | 22 ++++-- src/EntityLike.ts | 19 +++++ src/immutable/ImmutableEntity.ts | 41 +++++++++++ src/immutable/ImmutableValueObject.ts | 15 ++++ src/repository/NonNullableRepository.ts | 28 ++++---- src/repository/NullableRepository.ts | 20 +++--- src/repository/RepositoryCore.ts | 37 +++++----- src/repository/RepositoryEventEmitter.ts | 3 +- test/Entitiy-test.ts | 32 ++++++--- test/RepositoryCore-test.ts | 88 ++++++++++++++++-------- test/Serializer-test.ts | 19 ++--- yarn.lock | 66 ++++++++++-------- 13 files changed, 270 insertions(+), 132 deletions(-) create mode 100644 src/EntityLike.ts create mode 100644 src/immutable/ImmutableEntity.ts create mode 100644 src/immutable/ImmutableValueObject.ts diff --git a/package.json b/package.json index de891d3..f2642e0 100644 --- a/package.json +++ b/package.json @@ -47,14 +47,14 @@ "devDependencies": { "@types/mocha": "^2.2.48", "@types/node": "^9.4.6", - "cross-env": "^5.1.3", + "cross-env": "^5.1.4", "husky": "^0.14.3", "lerna": "^2.9.0", - "lint-staged": "^7.0.0", - "mocha": "^5.0.4", - "prettier": "1.11.1", - "ts-node": "^5.0.1", - "typescript": "^2.7.2" + "lint-staged": "^7.0.5", + "mocha": "^5.1.1", + "prettier": "1.12.1", + "ts-node": "^6.0.2", + "typescript": "^2.8.3" }, "dependencies": { "map-like": "^2.0.0", diff --git a/src/Entity.ts b/src/Entity.ts index 3b2be90..fd87a73 100644 --- a/src/Entity.ts +++ b/src/Entity.ts @@ -1,23 +1,31 @@ // MIT © 2017 azu import { Identifier } from "./Identifier"; +import { EntityLike, EntityLikeProps } from "./EntityLike"; -export abstract class Entity> { - public readonly id: Id; +export const isEntity = (v: any): v is Entity => { + return v instanceof Entity; +}; - constructor(id: Id) { - this.id = id; +export class Entity>> implements EntityLike { + props: Props; + + constructor(props: Props) { + this.props = props; } - /** + /* * Check equality by identifier */ - equals(object?: Entity): boolean { + equals(object?: Entity): boolean { if (object == null || object == undefined) { return false; } if (this === object) { return true; } - return this.id.equals(object.id); + if (!isEntity(object)) { + return false; + } + return this.props.id.equals(object.props.id); } } diff --git a/src/EntityLike.ts b/src/EntityLike.ts new file mode 100644 index 0000000..48e6fab --- /dev/null +++ b/src/EntityLike.ts @@ -0,0 +1,19 @@ +import { ImmutableEntity } from "./immutable/ImmutableEntity"; +import { Identifier } from "./Identifier"; + +export const isEntityLike = (entity: any): entity is EntityLike => { + if (!entity) { + return false; + } + return entity instanceof ImmutableEntity; +}; + +export interface EntityLikeProps> { + id: Id; +} + +export interface EntityLike>> { + props: Props; + + equals(object?: EntityLike): boolean; +} diff --git a/src/immutable/ImmutableEntity.ts b/src/immutable/ImmutableEntity.ts new file mode 100644 index 0000000..f3bcc42 --- /dev/null +++ b/src/immutable/ImmutableEntity.ts @@ -0,0 +1,41 @@ +// MIT © 2017 azu +import { Identifier } from "../Identifier"; +import { EntityLike, EntityLikeProps } from "../EntityLike"; + +export const isImmutableEntity = (entity: any): entity is ImmutableEntity<{ id: Identifier }> => { + if (!entity) { + return false; + } + return entity instanceof ImmutableEntity; +}; + +/** + * ImmutableEntity is readonly Entity. + * It is created with Props and It has `props` property. + * This entity has received through constructor. + * + * @see https://www.quora.com/Why-did-React-use-props-as-an-abbreviation-for-property-properties + */ +export class ImmutableEntity>> implements EntityLike { + props: Readonly; + + constructor(props: Props) { + this.props = Object.freeze(props); + } + + /* + * Check equality by identifier + */ + equals(object?: ImmutableEntity): boolean { + if (object == null || object == undefined) { + return false; + } + if (this === object) { + return true; + } + if (!isImmutableEntity(object)) { + return false; + } + return this.props.id.equals(object.props.id); + } +} diff --git a/src/immutable/ImmutableValueObject.ts b/src/immutable/ImmutableValueObject.ts new file mode 100644 index 0000000..47b7f81 --- /dev/null +++ b/src/immutable/ImmutableValueObject.ts @@ -0,0 +1,15 @@ +import { shallowEqual } from "shallow-equal-object"; + +export class ImmutableValueObject { + props: Readonly; + constructor(props: Props) { + this.props = Object.freeze(props); + } + /** + * Check equality by shallow equals of properties. + * It can be override. + */ + equals(object?: ImmutableValueObject<{}>): boolean { + return shallowEqual(this, object); + } +} diff --git a/src/repository/NonNullableRepository.ts b/src/repository/NonNullableRepository.ts index 1cd88a1..aea43a8 100644 --- a/src/repository/NonNullableRepository.ts +++ b/src/repository/NonNullableRepository.ts @@ -1,45 +1,49 @@ // MIT © 2017 azu -import { Entity } from "../Entity"; import { RepositoryCore } from "./RepositoryCore"; import { MapLike } from "map-like"; import { RepositoryEventEmitter } from "./RepositoryEventEmitter"; +import { EntityLike } from "../EntityLike"; /** * NonNullableRepository has initial value. * In other words, NonNullableRepository#get always return a value. */ -export class NonNullableRepository> { - private core: RepositoryCore; +export class NonNullableRepository< + Entity extends EntityLike, + Props extends Entity["props"], + Id extends Props["id"] +> { + private core: RepositoryCore; - constructor(protected initialEntity: T) { - this.core = new RepositoryCore(new MapLike()); + constructor(protected initialEntity: Entity) { + this.core = new RepositoryCore(new MapLike()); } - get map(): MapLike { + get map(): MapLike { return this.core.map; } - get events(): RepositoryEventEmitter { + get events(): RepositoryEventEmitter { return this.core.events; } - get(): T { + get(): Entity { return this.core.getLastSaved() || this.initialEntity; } - getAll(): T[] { + getAll(): Entity[] { return this.core.getAll(); } - findById(entityId?: T["id"]): T | undefined { + findById(entityId?: Id): Entity | undefined { return this.core.findById(entityId); } - save(entity: T): void { + save(entity: Entity): void { this.core.save(entity); } - delete(entity: T) { + delete(entity: Entity) { this.core.delete(entity); } diff --git a/src/repository/NullableRepository.ts b/src/repository/NullableRepository.ts index 9885513..9934b71 100644 --- a/src/repository/NullableRepository.ts +++ b/src/repository/NullableRepository.ts @@ -1,45 +1,45 @@ // MIT © 2017 azu -import { Entity } from "../Entity"; import { RepositoryCore } from "./RepositoryCore"; import { MapLike } from "map-like"; import { RepositoryEventEmitter } from "./RepositoryEventEmitter"; +import { EntityLike } from "../EntityLike"; /** * NullableRepository has not initial value. * In other word, NullableRepository#get may return undefined. */ -export class NullableRepository> { - private core: RepositoryCore; +export class NullableRepository, Props extends Entity["props"], Id extends Props["id"]> { + private core: RepositoryCore; constructor() { this.core = new RepositoryCore(new MapLike()); } - get map(): MapLike { + get map(): MapLike { return this.core.map; } - get events(): RepositoryEventEmitter { + get events(): RepositoryEventEmitter { return this.core.events; } - get(): T | undefined { + get(): Entity | undefined { return this.core.getLastSaved(); } - getAll(): T[] { + getAll(): Entity[] { return this.core.getAll(); } - findById(entityId?: T["id"]): T | undefined { + findById(entityId?: Id): Entity | undefined { return this.core.findById(entityId); } - save(entity: T): void { + save(entity: Entity): void { this.core.save(entity); } - delete(entity: T) { + delete(entity: Entity) { this.core.delete(entity); } diff --git a/src/repository/RepositoryCore.ts b/src/repository/RepositoryCore.ts index 1d54ebb..a62d033 100644 --- a/src/repository/RepositoryCore.ts +++ b/src/repository/RepositoryCore.ts @@ -1,20 +1,23 @@ // MIT © 2017 azu -import { Entity } from "../Entity"; import { MapLike } from "map-like"; -import { Identifier } from "../Identifier"; import { RepositoryDeletedEvent, RepositoryEventEmitter, RepositorySavedEvent } from "./RepositoryEventEmitter"; +import { EntityLike } from "../EntityLike"; /** * Repository Core implementation */ -export class RepositoryCore, P extends Entity> { - public readonly map: MapLike; - public readonly events: RepositoryEventEmitter

; - private lastUsed: P | undefined; +export class RepositoryCore< + Entity extends EntityLike, + Props extends Entity["props"] = Entity["props"], + Id extends Props["id"] = Props["id"] +> { + public readonly map: MapLike; + public readonly events: RepositoryEventEmitter; + private lastUsed: Entity | undefined; - constructor(map: MapLike) { + constructor(map: MapLike) { this.map = map; - this.events = new RepositoryEventEmitter

(); + this.events = new RepositoryEventEmitter(); } /** @@ -22,7 +25,7 @@ export class RepositoryCore, P extends Entity> { * This is useful on client-side implementation. * Because, client-side often access-user is a single user. */ - getLastSaved(): P | undefined { + getLastSaved(): Entity | undefined { return this.lastUsed; } @@ -30,7 +33,7 @@ export class RepositoryCore, P extends Entity> { * Find a entity by `entityIdentifier` that is instance of Identifier class. * Return `undefined` if not found entity. */ - findById(entityIdentifier?: T): P | undefined { + findById(entityIdentifier?: Id): Entity | undefined { if (!entityIdentifier) { return; } @@ -40,31 +43,31 @@ export class RepositoryCore, P extends Entity> { /** * Find all entity that `predicate(entity)` return true */ - findAll(predicate: (entity: P) => boolean): P[] { + findAll(predicate: (entity: Entity) => boolean): Entity[] { return this.map.values().filter(predicate); } /** * Get all entities */ - getAll(): P[] { + getAll(): Entity[] { return this.map.values(); } /** * Save entity to the repository. */ - save(entity: P): void { + save(entity: Entity): void { this.lastUsed = entity; - this.map.set(String(entity.id.toValue()), entity); + this.map.set(String(entity.props.id.toValue()), entity); this.events.emit(new RepositorySavedEvent(entity)); } /** * Delete entity from the repository. */ - delete(entity: P) { - this.map.delete(String(entity.id.toValue())); + delete(entity: Entity) { + this.map.delete(String(entity.props.id.toValue())); if (this.lastUsed === entity) { delete this.lastUsed; } @@ -74,7 +77,7 @@ export class RepositoryCore, P extends Entity> { /** * Delete entity by `entityIdentifier` that is instance of Identifier class. */ - deleteById(entityIdentifier?: T) { + deleteById(entityIdentifier?: Id) { if (!entityIdentifier) { return; } diff --git a/src/repository/RepositoryEventEmitter.ts b/src/repository/RepositoryEventEmitter.ts index 6ad1154..fe772c0 100644 --- a/src/repository/RepositoryEventEmitter.ts +++ b/src/repository/RepositoryEventEmitter.ts @@ -1,6 +1,7 @@ // MIT © 2017 azu import { EventEmitter } from "events"; import { Entity } from "../Entity"; +import { EntityLike } from "../EntityLike"; const SAVE = "SAVE"; const DELETE = "DELETE"; @@ -19,7 +20,7 @@ export class RepositoryDeletedEvent { export type RepositoryEvents> = RepositorySavedEvent | RepositoryDeletedEvent; -export class RepositoryEventEmitter> { +export class RepositoryEventEmitter> { private eventEmitter: EventEmitter; constructor() { diff --git a/test/Entitiy-test.ts b/test/Entitiy-test.ts index 9c44f5e..09d6659 100644 --- a/test/Entitiy-test.ts +++ b/test/Entitiy-test.ts @@ -6,35 +6,47 @@ import * as assert from "assert"; // Entity A class AIdentifier extends Identifier {} -class AEntity extends Entity {} +interface AProps { + id: AIdentifier; +} + +class AEntity extends Entity {} // Entity B class BIdentifier extends Identifier {} -class BEntity extends Entity {} +interface BProps { + id: BIdentifier; +} + +class BEntity extends Entity {} describe("Entity", () => { describe("id", () => { it("should return id", () => { const aIdentifier = new AIdentifier("a-id"); - const a1 = new AEntity(aIdentifier); - assert.strictEqual(a1.id, aIdentifier); + const a1 = new AEntity({ + id: aIdentifier + }); + assert.strictEqual(a1.props.id, aIdentifier); }); }); describe("#equals", () => { it("when has same id, should return true", () => { - const a1 = new AEntity(new AIdentifier("a-id")); - const a2 = new AEntity(new AIdentifier("a-id")); + const a1 = new AEntity({ id: new AIdentifier("a-id") }); + const a2 = new AEntity({ id: new AIdentifier("a-id") }); assert.ok(a1.equals(a2), "a1 === a2"); }); it("when has not same id, should return false", () => { - const a1 = new AEntity(new AIdentifier("a1-id")); - const a2 = new AEntity(new AIdentifier("a2-id")); + const a1 = new AEntity({ id: new AIdentifier("a1-id") }); + const a2 = new AEntity({ id: new AIdentifier("a2-id") }); assert.ok(!a1.equals(a2), "a1 !== a2"); }); it("A is not B", () => { - const a = new AEntity(new AIdentifier("1")); - const b = new BEntity(new BIdentifier("1")); + const a = new AEntity({ id: new AIdentifier("1") }); + const b = new BEntity({ + id: new BIdentifier("1") + }); assert.ok(!a.equals(b), "A is not B"); }); }); diff --git a/test/RepositoryCore-test.ts b/test/RepositoryCore-test.ts index aab8a89..29c999f 100644 --- a/test/RepositoryCore-test.ts +++ b/test/RepositoryCore-test.ts @@ -8,15 +8,21 @@ import { RepositoryDeletedEvent, RepositorySavedEvent } from "../src/repository/ class AIdentifier extends Identifier {} -class AEntity extends Entity {} +interface AEntityProps { + id: AIdentifier; +} + +class AEntity extends Entity {} describe("RepositoryCore", () => { describe("getLastSave", () => { it("should return lastSaved entity", () => { - const repository = new RepositoryCore(new MapLike()); + const repository = new RepositoryCore(new MapLike()); assert.strictEqual(repository.getLastSaved(), undefined, "return null by default"); // save entity - const entity = new AEntity(new AIdentifier("a")); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); assert.strictEqual(repository.getLastSaved(), entity, "return entity that is saved at last"); // delete @@ -26,23 +32,29 @@ describe("RepositoryCore", () => { }); describe("findById", () => { it("should return entity", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); // hit same id - assert.strictEqual(repository.findById(entity.id), entity); + assert.strictEqual(repository.findById(entity.props.id), entity); }); it("when not found, should return undefined", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); // hit same id - assert.strictEqual(repository.findById(entity.id), undefined); + assert.strictEqual(repository.findById(entity.props.id), undefined); }); }); describe("findAll", () => { it("predicate receive entity", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); repository.findAll(entity => { assert.ok(entity instanceof AEntity); @@ -50,54 +62,66 @@ describe("RepositoryCore", () => { }); }); it("should return entities", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); assert.deepStrictEqual(repository.findAll(() => true), [entity]); }); it("when not found, should return empty array", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); assert.deepStrictEqual(repository.findAll(() => false), []); }); }); describe("getAll", () => { it("should return all entity", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); assert.deepStrictEqual(repository.getAll(), [entity]); }); }); describe("delete", () => { it("delete entity, it to be not found", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); // delete repository.delete(entity); // not found - assert.strictEqual(repository.findById(entity.id), undefined); + assert.strictEqual(repository.findById(entity.props.id), undefined); }); }); describe("deleteById", () => { it("should delete by id", () => { it("delete entity, it to be not found", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); // delete - repository.deleteById(entity.id); + repository.deleteById(entity.props.id); // not found - assert.strictEqual(repository.findById(entity.id), undefined); + assert.strictEqual(repository.findById(entity.props.id), undefined); }); }); }); describe("clear", () => { it("should clear all entity", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); repository.save(entity); repository.save(entity); repository.save(entity); @@ -108,8 +132,10 @@ describe("RepositoryCore", () => { }); describe("events", () => { it("should emit Events", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); let count = 0; repository.events.onSave(event => { count++; @@ -126,8 +152,10 @@ describe("RepositoryCore", () => { assert.strictEqual(count, 2); }); it("onChange is emitted when some is changed", () => { - const repository = new RepositoryCore(new MapLike()); - const entity = new AEntity(new AIdentifier("a")); + const repository = new RepositoryCore(new MapLike()); + const entity = new AEntity({ + id: new AIdentifier("a") + }); let count = 0; repository.events.onChange(_ => { count++; diff --git a/test/Serializer-test.ts b/test/Serializer-test.ts index 59346b9..3c2ffa0 100644 --- a/test/Serializer-test.ts +++ b/test/Serializer-test.ts @@ -6,27 +6,22 @@ describe("Serializer", () => { // Entity A class AIdentifier extends Identifier {} - interface AEntityArgs { + interface AProps { id: AIdentifier; a: number; b: string; } - class AEntity extends Entity { - private a: number; - private b: string; - - constructor(args: AEntityArgs) { - super(args.id); - this.a = args.a; - this.b = args.b; + class AEntity extends Entity { + constructor(args: AProps) { + super(args); } toJSON(): AEntityJSON { return { - id: this.id.toValue(), - a: this.a, - b: this.b + id: this.props.id.toValue(), + a: this.props.a, + b: this.props.b }; } } diff --git a/yarn.lock b/yarn.lock index 1121942..17450f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -722,9 +722,9 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" -cross-env@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.1.3.tgz#f8ae18faac87692b0a8b4d2f7000d4ec3a85dfd7" +cross-env@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.1.4.tgz#f61c14291f7cc653bb86457002ea80a04699d022" dependencies: cross-spawn "^5.1.0" is-windows "^1.0.0" @@ -2035,9 +2035,9 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lint-staged@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.0.0.tgz#57926c63201e7bd38ca0576d74391efa699b4a9d" +lint-staged@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.0.5.tgz#1ed04c4bb2013579a3d4df4dfe0f2ea1cd988fad" dependencies: app-root-path "^2.0.1" chalk "^2.3.1" @@ -2057,8 +2057,9 @@ lint-staged@^7.0.0: p-map "^1.1.1" path-is-inside "^1.0.2" pify "^3.0.0" - please-upgrade-node "^3.0.1" - staged-git-files "1.1.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.1" + string-argv "^0.0.2" stringify-object "^3.2.2" listr-silent-renderer@^1.1.1: @@ -2331,7 +2332,7 @@ mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" -minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -2373,9 +2374,9 @@ mkdirp@0.5.1, mkdirp@^0.5.1, mkdirp@~0.5.0: dependencies: minimist "0.0.8" -mocha@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.4.tgz#6b7aa328472da1088e69d47e75925fd3a3bb63c6" +mocha@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.1.1.tgz#b774c75609dac05eb48f4d9ba1d827b97fde8a7b" dependencies: browser-stdout "1.3.1" commander "2.11.0" @@ -2385,6 +2386,7 @@ mocha@^5.0.4: glob "7.1.2" growl "1.10.3" he "1.1.1" + minimatch "3.0.4" mkdirp "0.5.1" supports-color "4.4.0" @@ -2700,9 +2702,11 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" -please-upgrade-node@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.1.tgz#0a681f2c18915e5433a5ca2cd94e0b8206a782db" +please-upgrade-node@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.2.tgz#7b9eaeca35aa4a43d6ebdfd10616c042f9a83acc" + dependencies: + semver-compare "^1.0.0" pn@^1.1.0: version "1.1.0" @@ -2724,9 +2728,9 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" +prettier@1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325" pretty-format@^22.4.0: version "22.4.0" @@ -3027,6 +3031,10 @@ sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + "semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -3216,9 +3224,9 @@ stack-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" -staged-git-files@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.0.tgz#1a9bb131c1885601023c7aaddd3d54c22142c526" +staged-git-files@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.1.tgz#37c2218ef0d6d26178b1310719309a16a59f8f7b" static-extend@^0.1.1: version "0.1.2" @@ -3237,6 +3245,10 @@ stream-to-observable@^0.2.0: dependencies: any-observable "^0.2.0" +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -3447,9 +3459,9 @@ trim-off-newlines@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" -ts-node@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-5.0.1.tgz#78e5d1cb3f704de1b641e43b76be2d4094f06f81" +ts-node@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-6.0.2.tgz#e132d530e53173bc6a8c21ea65f64d8b47bc573e" dependencies: arrify "^1.0.0" chalk "^2.3.0" @@ -3480,9 +3492,9 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" +typescript@^2.8.3: + version "2.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.3.tgz#5d817f9b6f31bb871835f4edf0089f21abe6c170" uglify-js@^2.6: version "2.8.29"