Skip to content

Commit 4d4d5af

Browse files
authored
feat: add plugin feature (#3)
1 parent 2e0f341 commit 4d4d5af

File tree

4 files changed

+182
-0
lines changed

4 files changed

+182
-0
lines changed

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ export * from './interpreter/Interpreter'
3434
export * from './query/Query'
3535
export * from './query/Options'
3636
export * from './connection/Connection'
37+
export * from './plugin/Plugin'
3738

3839
import { install } from './store/Store'
40+
import { use } from './plugin/Plugin'
3941
import { Database } from './database/Database'
4042
import { Schema } from './schema/Schema'
4143
import { Model } from './model/Model'
@@ -55,6 +57,7 @@ import { Connection } from './connection/Connection'
5557

5658
export default {
5759
install,
60+
use,
5861
Database,
5962
Schema,
6063
Model,

src/plugin/Plugin.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Store } from 'vuex'
2+
import { Database } from '../database/Database'
3+
import { Model } from '../model/Model'
4+
import { Attribute } from '../model/attributes/Attribute'
5+
import { Type } from '../model/attributes/types/Type'
6+
import { Attr } from '../model/attributes/types/Attr'
7+
import { String } from '../model/attributes/types/String'
8+
import { Number } from '../model/attributes/types/Number'
9+
import { Boolean } from '../model/attributes/types/Boolean'
10+
import { Relation } from '../model/attributes/relations/Relation'
11+
import { HasOne } from '../model/attributes/relations/HasOne'
12+
import { HasMany } from '../model/attributes/relations/HasMany'
13+
import { Repository } from '../repository/Repository'
14+
import { Interpreter } from '../interpreter/Interpreter'
15+
import { Query } from '../query/Query'
16+
import { Connection } from '../connection/Connection'
17+
import { mutations, Mutations } from '../modules/Mutations'
18+
19+
export interface VuexORMPlugin {
20+
install(
21+
store: Store<any>,
22+
database: Database,
23+
components: VuexORMPluginComponents,
24+
options: any
25+
): void
26+
}
27+
28+
export interface VuexORMPluginRegistry {
29+
func: VuexORMPlugin
30+
options: any
31+
}
32+
33+
export interface VuexORMPluginComponents {
34+
Database: typeof Database
35+
Model: typeof Model
36+
Attribute: typeof Attribute
37+
Type: typeof Type
38+
Attr: typeof Attr
39+
String: typeof String
40+
Number: typeof Number
41+
Boolean: typeof Boolean
42+
Relation: typeof Relation
43+
HasOne: typeof HasOne
44+
HasMany: typeof HasMany
45+
Repository: typeof Repository
46+
Interpreter: typeof Interpreter
47+
Query: typeof Query
48+
Connection: typeof Connection
49+
mutations: Mutations<any>
50+
}
51+
52+
/**
53+
* The plugin registry. All plugins registered through `VuexORM.use` method
54+
* is going to be stored here and then executed during the Vuex ORM
55+
* installation process.
56+
*/
57+
export const plugins: VuexORMPluginRegistry[] = []
58+
59+
/**
60+
* The components to be passed to the plugin `install` method.
61+
*/
62+
export const components: VuexORMPluginComponents = {
63+
Database,
64+
Model,
65+
Attribute,
66+
Type,
67+
Attr,
68+
String,
69+
Number,
70+
Boolean,
71+
Relation,
72+
HasOne,
73+
HasMany,
74+
Repository,
75+
Interpreter,
76+
Query,
77+
Connection,
78+
mutations
79+
}
80+
81+
/**
82+
* Plugin additional feature to the Vuex ORM.
83+
*/
84+
export function use(plugin: VuexORMPlugin, options?: any): void {
85+
plugins.push({ func: plugin, options })
86+
}

src/store/Store.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Store, Plugin } from 'vuex'
33
import { Database } from '../database/Database'
44
import { Model } from '../model/Model'
55
import { Repository } from '../repository/Repository'
6+
import { plugins, components } from '../plugin/Plugin'
67

78
export interface InstallOptions {
89
namespace?: string
@@ -39,13 +40,26 @@ function mixin(
3940
database: Database,
4041
options: FilledInstallOptions
4142
): void {
43+
installPlugins(store, database)
44+
4245
connectDatabase(store, database, options)
4346

4447
mixinRepoFunction(store)
4548

4649
startDatabase(store)
4750
}
4851

52+
/**
53+
* Execute registered plugins.
54+
*/
55+
function installPlugins(store: Store<any>, database: Database): void {
56+
plugins.forEach((plugin) => {
57+
const { func, options } = plugin
58+
59+
func.install(store, database, components, options)
60+
})
61+
}
62+
4963
/**
5064
* Connect the database to the store.
5165
*/

test/feature/plugin/plugin.spec.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import Vue from 'vue'
2+
import Vuex, { Store } from 'vuex'
3+
import VuexORM, { Database, Model, VuexORMPlugin } from '@/index'
4+
5+
Vue.use(Vuex)
6+
7+
describe('feature/plugin/plugin', () => {
8+
it('can add extra feature to the store', async () => {
9+
const plugin: VuexORMPlugin = {
10+
install(store) {
11+
;(store as any).custom = 1
12+
}
13+
}
14+
15+
VuexORM.use(plugin)
16+
17+
const database = new Database()
18+
19+
const store = new Store({
20+
plugins: [VuexORM.install(database)]
21+
})
22+
23+
expect((store as any).custom).toBe(1)
24+
})
25+
26+
it('can add extra feature to the database instance', async () => {
27+
const plugin: VuexORMPlugin = {
28+
install(_store, database) {
29+
;(database as any).custom = 1
30+
}
31+
}
32+
33+
VuexORM.use(plugin)
34+
35+
const database = new Database()
36+
37+
new Store({
38+
plugins: [VuexORM.install(database)]
39+
})
40+
41+
expect((database as any).custom).toBe(1)
42+
})
43+
44+
it('can add extra feature to the components', async () => {
45+
const plugin: VuexORMPlugin = {
46+
install(_store, _database, components) {
47+
;(components.Model as any).custom = 1
48+
}
49+
}
50+
51+
VuexORM.use(plugin)
52+
53+
const database = new Database()
54+
55+
new Store({
56+
plugins: [VuexORM.install(database)]
57+
})
58+
59+
expect((Model as any).custom).toBe(1)
60+
})
61+
62+
it('can take options', async () => {
63+
const plugin: VuexORMPlugin = {
64+
install(store, _database, _components, options) {
65+
;(store as any).custom = options
66+
}
67+
}
68+
69+
VuexORM.use(plugin, 1)
70+
71+
const database = new Database()
72+
73+
new Store({
74+
plugins: [VuexORM.install(database)]
75+
})
76+
77+
expect((Model as any).custom).toBe(1)
78+
})
79+
})

0 commit comments

Comments
 (0)