From 60ef88b2ac8f065f78564ff97ada6296e1517c92 Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Mon, 2 Mar 2020 11:13:44 -0800 Subject: [PATCH 1/4] test: plugin function with empty object return --- test.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/test.ts b/test.ts index 1bcc948..1b27720 100644 --- a/test.ts +++ b/test.ts @@ -4,16 +4,19 @@ const fooPlugin = (test: Base) => { console.log("plugin evalutes"); return { - foo: () => "foo" + foo: () => "foo", }; }; const barPlugin = (test: Base) => { console.log("plugin evalutes"); return { - bar: () => "bar" + bar: () => "bar", }; }; +const pluginWithEmptyObjectReturn = (test: Base) => { + return {}; +}; describe("Base", () => { it(".plugin(fooPlugin)", () => { @@ -21,8 +24,18 @@ describe("Base", () => { const fooTest = new FooTest(); expect(fooTest.foo()).toEqual("foo"); }); - it(".plugin([fooPlugin, barPlugin])", () => { - const FooBarTest = Base.plugin([fooPlugin, barPlugin]); + it(".plugin(fooPlugin, barPlugin)", () => { + const FooBarTest = Base.plugin(fooPlugin, barPlugin); + const fooBarTest = new FooBarTest(); + expect(fooBarTest.foo()).toEqual("foo"); + expect(fooBarTest.bar()).toEqual("bar"); + }); + it(".plugin(fooPlugin, barPlugin, pluginWithVoidReturn)", () => { + const FooBarTest = Base.plugin( + fooPlugin, + barPlugin, + pluginWithEmptyObjectReturn + ); const fooBarTest = new FooBarTest(); expect(fooBarTest.foo()).toEqual("foo"); expect(fooBarTest.bar()).toEqual("bar"); @@ -43,10 +56,10 @@ describe("Base", () => { it(".plugin().defaults()", () => { const BaseWithPluginAndDefaults = Base.plugin(fooPlugin).defaults({ - baz: "daz" + baz: "daz", }); const BaseWithDefaultsAndPlugin = Base.defaults({ - baz: "daz" + baz: "daz", }).plugin(fooPlugin); const instance1 = new BaseWithPluginAndDefaults(); From 065a6b3d6d1353764acb5d1a80d860d00aa837ac Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Mon, 11 Jan 2021 09:26:31 -0800 Subject: [PATCH 2/4] docs(README): `.plugin([plugin1, plugin2])` is now `.plugin(plugin1, plugin2)` --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f1b4746..f215802 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ import { Base } from "javascript-plugin-architecture-with-typescript-definitions function myFooPlugin(instance: Base) { return { - foo: () => "foo" + foo: () => "foo", }; } function myBarPlugin(instance: Base) { return { - bar: () => "bar" + bar: () => "bar", }; } @@ -29,7 +29,7 @@ const FooTest = Base.plugin(myFooPlugin); const fooTest = new FooTest(); fooTest.foo(); // has full TypeScript intellisense -const FooBarTest = Base.plugin([myFooPlugin, myBarPlugin]); +const FooBarTest = Base.plugin(myFooPlugin, myBarPlugin); const fooBarTest = new FooBarTest(); fooBarTest.foo(); // has full TypeScript intellisense fooBarTest.bar(); // has full TypeScript intellisense From 9eef5a09f1285b12e668c40a906009d3ceafd35a Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Mon, 11 Jan 2021 09:27:38 -0800 Subject: [PATCH 3/4] fix: support plugins that return an empty object BREAKING CHANGE: `.plugin([plugin1, plugin2])` is now `.plugin(plugin1, plugin2)` --- src/index.ts | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 87e9afb..04c829a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,9 +13,9 @@ type Constructor = new (...args: any[]) => T; * @author https://stackoverflow.com/users/2887218/jcalz * @see https://stackoverflow.com/a/50375286/10325032 */ -type UnionToIntersection = (Union extends any - ? (argument: Union) => void - : never) extends (argument: infer Intersection) => void // tslint:disable-line: no-unused +type UnionToIntersection = ( + Union extends any ? (argument: Union) => void : never +) extends (argument: infer Intersection) => void // tslint:disable-line: no-unused ? Intersection : never; @@ -31,16 +31,25 @@ export class Base { static plugins: TestPlugin[] = []; static plugin< S extends Constructor & { plugins: any[] }, - T extends TestPlugin | TestPlugin[] - >(this: S, plugin: T) { + T1 extends TestPlugin, + T2 extends TestPlugin[] + >(this: S, plugin: T1, ...p2: T2) { const currentPlugins = this.plugins; + let newPlugins: (TestPlugin | undefined)[] = [ + ...(plugin instanceof Array + ? (plugin as TestPlugin[]) + : [plugin as TestPlugin]), + ...p2, + ]; const BaseWithPlugins = class extends this { - static plugins = currentPlugins.concat(plugin); + static plugins = currentPlugins.concat( + newPlugins.filter((plugin) => !currentPlugins.includes(plugin)) + ); }; - type Extension = ReturnTypeOf; - return BaseWithPlugins as typeof BaseWithPlugins & Constructor; + return BaseWithPlugins as typeof BaseWithPlugins & + Constructor & ReturnTypeOf>>; } static defaults>(this: S, defaults: Options) { @@ -59,7 +68,7 @@ export class Base { // apply plugins // https://stackoverflow.com/a/16345172 const classConstructor = this.constructor as typeof Base; - classConstructor.plugins.forEach(plugin => { + classConstructor.plugins.forEach((plugin) => { Object.assign(this, plugin(this, options)); }); } From bc129bf3d15de4ec5305efe3605b884e3ba729bf Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Mon, 11 Jan 2021 09:28:56 -0800 Subject: [PATCH 4/4] ci: update to latest `actions/{checkout,setup-node}` --- .github/workflows/build.yml | 6 ++---- .github/workflows/release.yml | 6 ++---- .github/workflows/test.yml | 6 ++---- src/index.ts | 8 +++----- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d89c34a..e0b1c40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,9 +11,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions/setup-node@v1 - with: - node-version: 12 + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 - run: npm ci - run: npm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f754749..cf03049 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,10 +9,8 @@ jobs: name: release runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions/setup-node@v1 - with: - node-version: "12.x" + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 - run: npm ci - run: npm run build - run: npx semantic-release diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 978be68..c02e6a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,9 +11,7 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions/setup-node@v1 - with: - node-version: 12 + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 - run: npm ci - run: npm test diff --git a/src/index.ts b/src/index.ts index 04c829a..5d2ca9a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,13 +33,11 @@ export class Base { S extends Constructor & { plugins: any[] }, T1 extends TestPlugin, T2 extends TestPlugin[] - >(this: S, plugin: T1, ...p2: T2) { + >(this: S, plugin1: T1, ...additionalPlugins: T2) { const currentPlugins = this.plugins; let newPlugins: (TestPlugin | undefined)[] = [ - ...(plugin instanceof Array - ? (plugin as TestPlugin[]) - : [plugin as TestPlugin]), - ...p2, + plugin1, + ...additionalPlugins, ]; const BaseWithPlugins = class extends this {