typeomatica 0.2.7 → 0.2.8

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/lib/errors.d.ts CHANGED
@@ -3,4 +3,5 @@ export declare const ErrorsNames: {
3
3
  ACCESS_DENIED: string;
4
4
  MISSING_PROP: string;
5
5
  RIP_FUNCTIONS: string;
6
+ FORBIDDEN_RE: string;
6
7
  };
package/lib/errors.js CHANGED
@@ -5,5 +5,6 @@ exports.ErrorsNames = {
5
5
  TYPE_MISMATCH: 'Type Mismatch',
6
6
  ACCESS_DENIED: 'Value Access Denied',
7
7
  MISSING_PROP: 'Attempt to Access to Undefined Prop',
8
- RIP_FUNCTIONS: 'Functions are Restricted'
8
+ RIP_FUNCTIONS: 'Functions are Restricted',
9
+ FORBIDDEN_RE: 'Re-Assirnment is Forbidden'
9
10
  };
package/lib/fields.d.ts CHANGED
@@ -1,2 +1,11 @@
1
1
  export declare const SymbolInitialValue: unique symbol;
2
- export declare const FieldConstructor: ObjectConstructor;
2
+ interface FieldDefinition {
3
+ [SymbolInitialValue]: unknown;
4
+ }
5
+ export declare class FieldConstructor implements FieldDefinition {
6
+ [SymbolInitialValue]: unknown;
7
+ get get(): (this: FieldDefinition) => unknown;
8
+ get set(): () => never;
9
+ constructor(value: unknown);
10
+ }
11
+ export {};
package/lib/fields.js CHANGED
@@ -2,8 +2,23 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FieldConstructor = exports.SymbolInitialValue = void 0;
4
4
  exports.SymbolInitialValue = Symbol('Initial Value');
5
- exports.FieldConstructor = function (value) {
6
- this[exports.SymbolInitialValue] = value;
7
- };
8
- Object.freeze(exports.FieldConstructor.prototype);
9
- Object.seal(exports.FieldConstructor.prototype);
5
+ const errors_1 = require("./errors");
6
+ class FieldConstructor {
7
+ constructor(value) {
8
+ this[exports.SymbolInitialValue] = value;
9
+ }
10
+ get get() {
11
+ const self = this;
12
+ return function () {
13
+ return self[exports.SymbolInitialValue];
14
+ };
15
+ }
16
+ get set() {
17
+ return function () {
18
+ throw new TypeError(errors_1.ErrorsNames.FORBIDDEN_RE);
19
+ };
20
+ }
21
+ }
22
+ exports.FieldConstructor = FieldConstructor;
23
+ Object.freeze(FieldConstructor.prototype);
24
+ Object.seal(FieldConstructor.prototype);
package/lib/index.js CHANGED
@@ -42,11 +42,18 @@ const createProperty = (propName, initialValue, receiver) => {
42
42
  const descriptor = (isObject && (value instanceof fields_1.FieldConstructor)) ?
43
43
  value
44
44
  : Object.assign({ enumerable: true }, resolver[type](value, receiver));
45
- const result = Reflect.defineProperty(receiver, propName, descriptor);
46
- return result;
45
+ try {
46
+ const result = Reflect.defineProperty(receiver, propName, descriptor);
47
+ return result;
48
+ }
49
+ catch (error) {
50
+ throw error;
51
+ }
47
52
  };
53
+ const props2skip = new Set([Symbol.toStringTag, Symbol.iterator]);
48
54
  const util = require('util');
49
- const props2skip = new Set([util.inspect.custom, Symbol.toStringTag, Symbol.iterator]);
55
+ const hasNodeInspect = (util && util.inspect && util.inspect.custom);
56
+ hasNodeInspect && (props2skip.add(util.inspect.custom));
50
57
  const handlers = {
51
58
  get(target, prop, receiver) {
52
59
  const result = Reflect.get(target, prop, receiver);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typeomatica",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "type logic against javascript metaprogramming",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
package/src/errors.ts CHANGED
@@ -4,5 +4,6 @@ export const ErrorsNames = {
4
4
  TYPE_MISMATCH: 'Type Mismatch',
5
5
  ACCESS_DENIED: 'Value Access Denied',
6
6
  MISSING_PROP: 'Attempt to Access to Undefined Prop',
7
- RIP_FUNCTIONS: 'Functions are Restricted'
7
+ RIP_FUNCTIONS: 'Functions are Restricted',
8
+ FORBIDDEN_RE: 'Re-Assirnment is Forbidden'
8
9
  };
package/src/fields.ts CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  export const SymbolInitialValue = Symbol('Initial Value');
4
4
 
5
+ import { ErrorsNames } from './errors'
6
+
5
7
  interface FieldDefinition {
6
8
  [SymbolInitialValue]: unknown
7
9
  // get?: unknown
@@ -11,9 +13,27 @@ interface FieldDefinition {
11
13
  // writable: boolean
12
14
  }
13
15
 
14
- export const FieldConstructor = function (this: FieldDefinition, value: unknown) {
15
- this[SymbolInitialValue] = value;
16
- } as ObjectConstructor;
16
+ // export const FieldConstructor = function (this: FieldDefinition, value: unknown) {
17
+ // this[SymbolInitialValue] = value;
18
+ // } as ObjectConstructor;
19
+
20
+ export class FieldConstructor implements FieldDefinition {
21
+ [SymbolInitialValue]: unknown
22
+ public get get () {
23
+ const self = this;
24
+ return function (this: FieldDefinition) {
25
+ return self[SymbolInitialValue];
26
+ }
27
+ }
28
+ public get set () {
29
+ return function () {
30
+ throw new TypeError(ErrorsNames.FORBIDDEN_RE);
31
+ }
32
+ }
33
+ constructor (value: unknown) {
34
+ this[SymbolInitialValue] = value;
35
+ }
36
+ }
17
37
 
18
38
  // Object.assign(FieldConstructor.prototype, {
19
39
  // configurable: false,
package/src/index.ts CHANGED
@@ -80,13 +80,20 @@ const createProperty = (propName: string, initialValue: unknown, receiver: objec
80
80
  // debugger;
81
81
  // }
82
82
 
83
- const result = Reflect.defineProperty(receiver, propName, descriptor);
84
- return result;
83
+ try {
84
+ const result = Reflect.defineProperty(receiver, propName, descriptor);
85
+ return result;
86
+ } catch (error) {
87
+ // debugger;
88
+ throw error;
89
+ }
85
90
 
86
91
  };
87
92
 
93
+ const props2skip = new Set([Symbol.toStringTag, Symbol.iterator]);
88
94
  const util = require('util');
89
- const props2skip = new Set([util.inspect.custom, Symbol.toStringTag, Symbol.iterator]);
95
+ const hasNodeInspect = (util && util.inspect && util.inspect.custom);
96
+ hasNodeInspect && (props2skip.add(util.inspect.custom));
90
97
 
91
98
  const handlers = {
92
99
  get(target: object, prop: string | symbol, receiver: object) {
@@ -103,6 +110,7 @@ const handlers = {
103
110
  }, {}));
104
111
  }
105
112
  }
113
+ // @ts-ignore
106
114
  if (props2skip.has(prop)) {
107
115
  return undefined;
108
116
  }
package/test/index.ts CHANGED
@@ -72,37 +72,83 @@ const extendedSetInstance = new ExtendedSet;
72
72
  const MUTATION_VALUE = -2;
73
73
 
74
74
 
75
- class MyFieldConstructor extends FieldConstructor {
75
+ class MyFieldConstructorNoRe extends FieldConstructor {
76
+ _value: string
76
77
  constructor(value: string) {
77
78
  super(value);
78
79
  Reflect.defineProperty(this, 'enumerable', {
79
80
  value: true
80
81
  });
82
+ this._value = value;
83
+ }
84
+ }
85
+ class MyFieldConstructorReGet extends MyFieldConstructorNoRe {
86
+ constructor(value: string) {
87
+ super(value);
88
+ const self = this;
89
+ Reflect.defineProperty(this, 'enumerable', {
90
+ value: true
91
+ });
81
92
  Reflect.defineProperty(this, 'get', {
82
- get () {
93
+ get() {
83
94
  return function () {
84
- return value;
95
+ return self._value;
85
96
  }
86
- }
97
+ },
98
+ enumerable: true
99
+ });
100
+ }
101
+ }
102
+ class MyFieldConstructorReSet extends MyFieldConstructorNoRe {
103
+ constructor(value: string) {
104
+ super(value);
105
+ const self = this;
106
+ Reflect.defineProperty(this, 'enumerable', {
107
+ value: true
87
108
  });
88
109
  Reflect.defineProperty(this, 'set', {
89
- get () {
90
- return function (_value: string) {
91
- value = _value;
110
+ get() {
111
+ return function (value: string) {
112
+ self._value = value;
92
113
  }
93
114
  },
94
115
  enumerable: true
95
116
  });
96
117
  }
97
118
  }
119
+ class MyFieldConstructor extends MyFieldConstructorReGet {
120
+ constructor(value: string) {
121
+ super(value);
122
+ const self = this;
123
+ Reflect.defineProperty(this, 'enumerable', {
124
+ value: true
125
+ });
126
+ Reflect.defineProperty(this, 'set', {
127
+ get() {
128
+ return function (value: string) {
129
+ self._value = value;
130
+ }
131
+ },
132
+ enumerable: true
133
+ });
134
+ }
135
+ }
136
+
137
+ const myField = new MyFieldConstructor('initial value');
138
+ const myFieldReGet = new MyFieldConstructorReGet('initial value for get check');
139
+ const myFieldReSet = new MyFieldConstructorReSet('initial value for set check');
98
140
 
99
- const myField = new MyFieldConstructor('zzz');
100
- class MadeFieldClass extends BaseClass { myField = myField };
101
- class SecondMadeFieldClass extends BaseClass { myField = myField };
141
+ class MadeFieldClass extends BaseClass { myField = myField as unknown | string };
142
+ class SecondMadeFieldClass extends BaseClass { myField = myField as unknown | string };
102
143
  const madeFieldInstance = new MadeFieldClass;
103
144
  const secondMadeFieldInstance = new MadeFieldClass;
104
145
  const thirdMadeFieldInstance = new SecondMadeFieldClass;
105
146
 
147
+ class MadeReGet extends BaseClass { myField = myFieldReGet as unknown | string }
148
+ class MadeReSet extends BaseClass { myField = myFieldReSet as unknown | string }
149
+ const madeReGet = new MadeReGet;
150
+ const madeReSet = new MadeReSet;
151
+
106
152
  describe('props tests', () => {
107
153
 
108
154
  test('base instance has props', () => {
@@ -172,12 +218,45 @@ describe('props tests', () => {
172
218
  });
173
219
 
174
220
  test('correct custom field creation', () => {
175
- expect(madeFieldInstance.myField).toEqual('zzz');
221
+ expect(madeFieldInstance.myField).toEqual('initial value');
176
222
  });
223
+
177
224
  test('correct custom field assignment', () => {
178
- madeFieldInstance.myField = 123;
179
- expect(secondMadeFieldInstance.myField).toEqual(123);
180
- expect(thirdMadeFieldInstance.myField).toEqual(123);
225
+ madeFieldInstance.myField = 'replaced';
226
+ expect(secondMadeFieldInstance.myField).toEqual('replaced');
227
+ expect(thirdMadeFieldInstance.myField).toEqual('replaced');
228
+ });
229
+
230
+ test('correct custom field no-re-assignment', () => {
231
+ expect(madeReGet.myField).toEqual('initial value for get check');
232
+ expect(() => {
233
+
234
+ madeReGet.myField = 'replaced';
235
+
236
+ }).toThrow(new TypeError('Re-Assirnment is Forbidden'));
237
+ });
238
+
239
+ test('correct custom field setter only', () => {
240
+ madeReSet.myField = 'replaced';
241
+ expect(madeReSet.myField).toEqual('initial value for set check');
242
+ });
243
+
244
+ test('takes error on wrong field definition', () => {
245
+ expect(() => {
246
+ class WrongFieldConstructor extends FieldConstructor {
247
+ value: number
248
+ constructor(value: number) {
249
+ super(value)
250
+ this.value = value;
251
+ }
252
+ }
253
+ const wrongField = new WrongFieldConstructor(123);
254
+ class WithWrongField extends BaseClass {
255
+ erroredField = wrongField
256
+ }
257
+ new WithWrongField;
258
+
259
+ }).toThrow();
181
260
  });
182
261
 
183
262
  test('correct custom missing prop search creation', () => {
@@ -188,6 +267,10 @@ describe('props tests', () => {
188
267
  const util = require('util');
189
268
  // @ts-ignore
190
269
  expect(madeFieldInstance[util.inspect.custom]).toEqual(undefined);
270
+ // @ts-ignore
271
+ const inspected = util.inspect(madeFieldInstance);
272
+ const expected = 'MadeFieldClass { myField: [Getter/Setter] }';
273
+ expect(expected).toEqual(expected);
191
274
  });
192
275
 
193
276
  test('wrong assignment to objects', () => {