architex-js 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/exceptions/index.js +24 -0
- package/src/mixins/MixinBuilder.js +65 -0
- package/src/mixins/index.js +1 -0
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error for abstract methods that are not implemented in a subclass.
|
|
3
|
+
*/
|
|
4
|
+
class AbstractMethodNotImplementedException extends Error {
|
|
5
|
+
constructor(msg = "method must be implemented") {
|
|
6
|
+
super(msg);
|
|
7
|
+
this.name = "AbstractMethodNotImplementedException";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Custom error for attempting to instantiate an abstract class.
|
|
13
|
+
*/
|
|
14
|
+
class InstantiatedAbstractClassException extends Error {
|
|
15
|
+
constructor(msg = "Class is of abstract type and can't be instantiated") {
|
|
16
|
+
super(msg);
|
|
17
|
+
this.name = "InstantiatedAbstractClassException";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
AbstractMethodNotImplementedException,
|
|
23
|
+
InstantiatedAbstractClassException
|
|
24
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class is responsible for building the final prototype from a group of mixins
|
|
3
|
+
*/
|
|
4
|
+
class MixinBuilder {
|
|
5
|
+
/**
|
|
6
|
+
* Builds the final object or prototype that will inherit into the concrete class
|
|
7
|
+
* @param {...any} mixins classes that will inherit in the final class
|
|
8
|
+
* @returns returns the final class that will inherit in the final context
|
|
9
|
+
*/
|
|
10
|
+
static with(...mixins) {
|
|
11
|
+
return mixins.reduce((BaseClass, mixin) => {
|
|
12
|
+
if (
|
|
13
|
+
typeof mixin === "function" &&
|
|
14
|
+
/^class\s/.test(Function.prototype.toString.call(mixin))
|
|
15
|
+
) {
|
|
16
|
+
// create an intermediate class that extends the BaseClass and applies the mixin
|
|
17
|
+
const MixedClass = class extends BaseClass {
|
|
18
|
+
constructor(...args) {
|
|
19
|
+
super(...args);
|
|
20
|
+
const mixinInstance = new mixin(...args);
|
|
21
|
+
|
|
22
|
+
// copies properties and instance methods of the mixin
|
|
23
|
+
Object.getOwnPropertyNames(mixinInstance).forEach(
|
|
24
|
+
(name) => {
|
|
25
|
+
if (!this.hasOwnProperty(name)) {
|
|
26
|
+
this[name] = mixinInstance[name];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// add static members from mixin class to the resulting class
|
|
34
|
+
Object.getOwnPropertyNames(mixin).forEach((name) => {
|
|
35
|
+
if (
|
|
36
|
+
name !== "prototype" &&
|
|
37
|
+
name !== "length" &&
|
|
38
|
+
name !== "name"
|
|
39
|
+
) {
|
|
40
|
+
MixedClass[name] = mixin[name];
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// add the mixin prototype to the MixedClass prototype chain
|
|
45
|
+
Object.setPrototypeOf(
|
|
46
|
+
MixedClass.prototype,
|
|
47
|
+
new Proxy(mixin.prototype, {
|
|
48
|
+
get(target, prop, receiver) {
|
|
49
|
+
return (
|
|
50
|
+
Reflect.get(target, prop, receiver) ||
|
|
51
|
+
Reflect.get(BaseClass.prototype, prop, receiver)
|
|
52
|
+
);
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return MixedClass;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return mixin(BaseClass);
|
|
61
|
+
}, class { });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { MixinBuilder };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./MixinBuilder.js";
|