-
Notifications
You must be signed in to change notification settings - Fork 93
/
context_loader.js
74 lines (62 loc) · 1.69 KB
/
context_loader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
'use strict';
const assert = require('assert');
const is = require('is-type-of');
const Loader = require('./loader');
const classLoader = Symbol('classLoader');
const EXPORTS = Loader.EXPORTS;
class ClassLoader {
constructor(options) {
assert(options.ctx, 'options.ctx is required');
const properties = options.properties;
this._cache = new Map();
this._ctx = options.ctx;
for (const property in properties) {
this.defineProperty(property, properties[property]);
}
}
defineProperty(property, values) {
Object.defineProperty(this, property, {
get() {
if (!this._cache.has(property)) {
this._cache.set(property, getInstance(values, this._ctx));
}
return this._cache.get(property);
},
});
}
}
class ContextLoader extends Loader {
constructor(options) {
assert(options.field, 'options.field is required');
assert(options.inject, 'options.inject is required');
const target = options.target = {};
if (options.fieldClass) {
options.inject[options.fieldClass] = target;
}
super(options);
const app = this.options.inject;
Object.defineProperty(app.context, options.field, {
get() {
if (!this[classLoader]) {
this[classLoader] = getInstance(target, this);
}
return this[classLoader];
},
});
}
}
module.exports = ContextLoader;
function getInstance(values, ctx) {
const Class = values[EXPORTS] ? values : null;
let instance;
if (Class) {
if (is.class(Class)) {
instance = new Class(ctx);
} else {
instance = Class;
}
} else {
instance = new ClassLoader({ ctx, properties: values });
}
return instance;
}