@amodx/schemas 0.0.1

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.
Files changed (37) hide show
  1. package/Inputs/DefaultInputs.d.ts +201 -0
  2. package/Inputs/DefaultInputs.js +376 -0
  3. package/Inputs/PropertyInput.d.ts +46 -0
  4. package/Inputs/PropertyInput.js +35 -0
  5. package/Inputs/PropertyInputRegister.d.ts +7 -0
  6. package/Inputs/PropertyInputRegister.js +13 -0
  7. package/Properties/ObjectPath.d.ts +17 -0
  8. package/Properties/ObjectPath.js +33 -0
  9. package/Properties/Property.d.ts +24 -0
  10. package/Properties/Property.js +38 -0
  11. package/Properties/PropertyCondition.d.ts +11 -0
  12. package/Properties/PropertyCondition.js +37 -0
  13. package/Properties/PropertyConditionAction.d.ts +11 -0
  14. package/Properties/PropertyConditionAction.js +38 -0
  15. package/Properties.d.ts +44 -0
  16. package/Properties.js +239 -0
  17. package/Schema.d.ts +22 -0
  18. package/Schema.js +99 -0
  19. package/Schemas/BinaryObjectSchema.d.ts +3 -0
  20. package/Schemas/BinaryObjectSchema.js +3 -0
  21. package/Schemas/ObjectSchema.d.ts +17 -0
  22. package/Schemas/ObjectSchema.js +103 -0
  23. package/Schemas/ObjectSchemaInstance.d.ts +10 -0
  24. package/Schemas/ObjectSchemaInstance.js +14 -0
  25. package/Schemas/SchemaNode.d.ts +62 -0
  26. package/Schemas/SchemaNode.js +172 -0
  27. package/Validation/ObjectPropertyValidator.d.ts +7 -0
  28. package/Validation/ObjectPropertyValidator.js +9 -0
  29. package/Validation/ObjectPropertyValidatorRegister.d.ts +7 -0
  30. package/Validation/ObjectPropertyValidatorRegister.js +13 -0
  31. package/Validation/ObjectValidation.types.d.ts +13 -0
  32. package/Validation/ObjectValidation.types.js +1 -0
  33. package/Validation/index.d.ts +3 -0
  34. package/Validation/index.js +3 -0
  35. package/index.d.ts +8 -0
  36. package/index.js +8 -0
  37. package/package.json +27 -0
@@ -0,0 +1,103 @@
1
+ import { SchemaNode } from "./SchemaNode";
2
+ import { Property } from "../Properties/Property";
3
+ export class ObjectSchema {
4
+ __schema;
5
+ __root = new SchemaNode(Property.Create({ id: "__root__" }), {});
6
+ constructor(__schema) {
7
+ this.__schema = __schema;
8
+ }
9
+ init() {
10
+ this.traverse((_) => {
11
+ _.property.initialize && _.property.initialize(_);
12
+ _.init(this);
13
+ });
14
+ this.evaluate();
15
+ this.validate();
16
+ return this;
17
+ }
18
+ evaluate() {
19
+ this.traverse((_) => {
20
+ _.observers.evaluate.notify();
21
+ });
22
+ }
23
+ validate() {
24
+ this.traverse((_) => {
25
+ _.observers.evaluate.notify();
26
+ });
27
+ }
28
+ traverse(run) {
29
+ const traverse = (parent) => {
30
+ if (!parent.children)
31
+ return;
32
+ for (const node of parent.children) {
33
+ run(node);
34
+ if (node.property.children && node.property.children.length) {
35
+ traverse(node);
36
+ }
37
+ }
38
+ };
39
+ traverse(this.__root);
40
+ }
41
+ getRoot() {
42
+ return this.__root;
43
+ }
44
+ clone() {
45
+ return this.__schema
46
+ .instantiate()
47
+ .getSchema();
48
+ }
49
+ getNode(path) {
50
+ let finalNode = null;
51
+ const traverse = (node, path) => {
52
+ if (!node.children)
53
+ return;
54
+ for (const child of node.children) {
55
+ if (child.property.id == path[0]) {
56
+ if (child.property.children && child.property.children.length) {
57
+ path.shift();
58
+ traverse(child, path);
59
+ return;
60
+ }
61
+ finalNode = child;
62
+ }
63
+ }
64
+ };
65
+ traverse(this.getRoot(), [...path.path]);
66
+ return finalNode;
67
+ }
68
+ store() {
69
+ const rootObject = {};
70
+ const traverse = (schemaNode, parentObject) => {
71
+ if (!schemaNode.children)
72
+ return;
73
+ for (const node of schemaNode.children) {
74
+ if (node.children && node.children.length) {
75
+ const parent = {};
76
+ traverse(node, parent);
77
+ parentObject[node.property.id] = parent;
78
+ continue;
79
+ }
80
+ parentObject[node.property.id] = node.store();
81
+ }
82
+ };
83
+ traverse(this.getRoot(), rootObject);
84
+ return rootObject;
85
+ }
86
+ loadIn(data) {
87
+ const traverse = (schemaNode, parentObject) => {
88
+ if (!schemaNode.children)
89
+ return;
90
+ for (const node of schemaNode.children) {
91
+ if (node.property.id in parentObject) {
92
+ if (node.children && node.children.length) {
93
+ traverse(node, parentObject[node.property.id]);
94
+ }
95
+ else {
96
+ node.loadIn(parentObject[node.property.id]);
97
+ }
98
+ }
99
+ }
100
+ };
101
+ traverse(this.getRoot(), data);
102
+ }
103
+ }
@@ -0,0 +1,10 @@
1
+ import { Schema } from "../Schema";
2
+ import { ObjectSchema } from "./ObjectSchema";
3
+ export declare class ObjectSchemaInstanceBase {
4
+ private readonly __schema;
5
+ private readonly __objectSchema;
6
+ constructor(__schema: Schema, __objectSchema: ObjectSchema);
7
+ getSchema(): ObjectSchema<{}>;
8
+ toJSON(): {};
9
+ }
10
+ export type ObjectSchemaInstance<T extends object = {}> = ObjectSchemaInstanceBase & T;
@@ -0,0 +1,14 @@
1
+ export class ObjectSchemaInstanceBase {
2
+ __schema;
3
+ __objectSchema;
4
+ constructor(__schema, __objectSchema) {
5
+ this.__schema = __schema;
6
+ this.__objectSchema = __objectSchema;
7
+ }
8
+ getSchema() {
9
+ return this.__objectSchema;
10
+ }
11
+ toJSON() {
12
+ return this.__objectSchema.store();
13
+ }
14
+ }
@@ -0,0 +1,62 @@
1
+ import { Property } from "../Properties/Property";
2
+ import { PropertyInputBase } from "../Inputs/PropertyInput";
3
+ import { Observable } from "@amodx/core/Observers/index";
4
+ import { Pipeline } from "@amodx/core/Pipelines";
5
+ import { PropertyConditionAction } from "../Properties/PropertyConditionAction";
6
+ import { ObjectSchema } from "./ObjectSchema";
7
+ import { ObjectPropertyValidatorResponse } from "../Validation";
8
+ export declare class TemplateNode {
9
+ property: Property;
10
+ constructor(property: Property);
11
+ children: TemplateNode[];
12
+ }
13
+ declare class SchemaNodeObservers<Value = any, Input extends PropertyInputBase<any, any> = any> {
14
+ stateUpdated: Observable<SchemaNode<Value, Input>>;
15
+ updated: Observable<SchemaNode<Value, Input>>;
16
+ loadedIn: Observable<SchemaNode<Value, Input>>;
17
+ updatedOrLoadedIn: Observable<SchemaNode<Value, Input>>;
18
+ evaluate: Observable<void>;
19
+ validate: Observable<void>;
20
+ }
21
+ declare class SchemaNodePipelines<Value = any, Input extends PropertyInputBase<any, any> = any> {
22
+ onStore: Pipeline<Property<Value, Input["data"]>>;
23
+ updated: Pipeline<{
24
+ newValue: any;
25
+ node: SchemaNode<Value, Input>;
26
+ }>;
27
+ loadedIn: Pipeline<{
28
+ value: any;
29
+ node: SchemaNode<Value, Input>;
30
+ }>;
31
+ }
32
+ export declare class SchemaNode<Value = any, Input extends PropertyInputBase<any, any> = any> {
33
+ property: Property<Value, Input["data"]>;
34
+ root: any;
35
+ children: SchemaNode[] | null;
36
+ conditions: PropertyConditionAction[];
37
+ input: Input | null;
38
+ observers: SchemaNodeObservers<Value, Input>;
39
+ pipelines: SchemaNodePipelines<Value, Input>;
40
+ validatorResponse: ObjectPropertyValidatorResponse;
41
+ constructor(property: Property<Value, Input["data"]>, root: any);
42
+ private proxy;
43
+ enableProxy(get: () => Value, set: (value: Value) => Value): void;
44
+ disableProxy(): void;
45
+ private getValue;
46
+ private setValue;
47
+ init(schema: ObjectSchema): void;
48
+ evaluateConditions(): void;
49
+ validate(): void;
50
+ isValid(): boolean;
51
+ isEnabled(): boolean;
52
+ setEnabled(enabled: boolean): void;
53
+ isLocked(): boolean;
54
+ setLocked(locked: boolean): void;
55
+ store(): Value;
56
+ loadIn(value: any): void;
57
+ get(): Value;
58
+ update(newValue: any): void;
59
+ forEach(run: (node: SchemaNode) => void): void;
60
+ map<T>(map: (node: SchemaNode) => T): T[];
61
+ }
62
+ export {};
@@ -0,0 +1,172 @@
1
+ import { Property } from "../Properties/Property";
2
+ import { PropertyInputRegister } from "../Inputs/PropertyInputRegister";
3
+ import { Observable } from "@amodx/core/Observers/index";
4
+ import { Pipeline } from "@amodx/core/Pipelines";
5
+ import { ObjectPropertyValidatorRegister, } from "../Validation";
6
+ export class TemplateNode {
7
+ property;
8
+ constructor(property) {
9
+ this.property = property;
10
+ }
11
+ children;
12
+ }
13
+ class SchemaNodeObservers {
14
+ stateUpdated = new Observable();
15
+ updated = new Observable();
16
+ loadedIn = new Observable();
17
+ updatedOrLoadedIn = new Observable();
18
+ evaluate = new Observable();
19
+ validate = new Observable();
20
+ }
21
+ class SchemaNodePipelines {
22
+ onStore = new Pipeline();
23
+ updated = new Pipeline();
24
+ loadedIn = new Pipeline();
25
+ }
26
+ class SchemaNodeProxy {
27
+ get;
28
+ set;
29
+ constructor(get, set) {
30
+ this.get = get;
31
+ this.set = set;
32
+ }
33
+ }
34
+ export class SchemaNode {
35
+ property;
36
+ root;
37
+ children = null;
38
+ conditions = [];
39
+ input;
40
+ observers = new SchemaNodeObservers();
41
+ pipelines = new SchemaNodePipelines();
42
+ validatorResponse;
43
+ constructor(property, root) {
44
+ this.property = property;
45
+ this.root = root;
46
+ if (property.input) {
47
+ const inputClass = PropertyInputRegister.getProperty(property.input.type);
48
+ this.input = new inputClass(property.input, this);
49
+ }
50
+ }
51
+ proxy = null;
52
+ enableProxy(get, set) {
53
+ this.proxy = new SchemaNodeProxy(get, set);
54
+ }
55
+ disableProxy() {
56
+ this.proxy = null;
57
+ }
58
+ getValue() {
59
+ if (!this.proxy)
60
+ return this.property.value;
61
+ return this.proxy.get();
62
+ }
63
+ setValue(value) {
64
+ if (!this.proxy)
65
+ return (this.property.value = value);
66
+ return this.proxy.set(value);
67
+ }
68
+ init(schema) {
69
+ const property = this.property;
70
+ if (property.conditions && property.conditions.length) {
71
+ for (const action of property.conditions) {
72
+ for (const condition of action.conditions) {
73
+ const otherNode = schema.getNode(condition.path);
74
+ otherNode.observers.updatedOrLoadedIn.subscribe(this, () => {
75
+ action.evaluate(otherNode.get(), this);
76
+ });
77
+ this.observers.evaluate.subscribe(this, () => {
78
+ action.evaluate(otherNode.get(), this);
79
+ });
80
+ }
81
+ this.conditions.push(action);
82
+ }
83
+ }
84
+ if (property.input?.validator) {
85
+ const validator = ObjectPropertyValidatorRegister.getValidator(property.input.validator);
86
+ this.observers.updatedOrLoadedIn.subscribe(this, () => {
87
+ const response = validator.validate(this.get(), this);
88
+ this.validatorResponse = response;
89
+ if (response.success) {
90
+ if (!property.state.valid) {
91
+ property.state.valid = true;
92
+ this.observers.stateUpdated.notify(this);
93
+ }
94
+ }
95
+ else {
96
+ if (property.state.valid) {
97
+ property.state.valid = false;
98
+ this.observers.stateUpdated.notify(this);
99
+ }
100
+ }
101
+ });
102
+ }
103
+ }
104
+ evaluateConditions() {
105
+ this.observers.evaluate.notify();
106
+ }
107
+ validate() {
108
+ this.observers.validate.notify();
109
+ }
110
+ isValid() {
111
+ return this.property.state.valid;
112
+ }
113
+ isEnabled() {
114
+ return this.property.state.enabled;
115
+ }
116
+ setEnabled(enabled) {
117
+ this.property.state.enabled = enabled;
118
+ this.observers.stateUpdated.notify(this);
119
+ }
120
+ isLocked() {
121
+ return this.property.state.locked;
122
+ }
123
+ setLocked(locked) {
124
+ this.property.state.locked = locked;
125
+ this.observers.stateUpdated.notify(this);
126
+ }
127
+ store() {
128
+ return this.pipelines.onStore.pipe(Property.Create(this.property)).value;
129
+ }
130
+ loadIn(value) {
131
+ this.setValue(this.pipelines.loadedIn.pipe({
132
+ node: this,
133
+ value,
134
+ }).value);
135
+ this.observers.loadedIn.notify(this);
136
+ this.observers.updatedOrLoadedIn.notify(this);
137
+ }
138
+ get() {
139
+ return this.getValue();
140
+ }
141
+ update(newValue) {
142
+ const oldValue = this.getValue();
143
+ this.setValue(this.pipelines.updated.pipe({
144
+ node: this,
145
+ newValue,
146
+ }).newValue);
147
+ const newFinalValue = this.getValue();
148
+ if (this.input) {
149
+ if (!this.input.compare(oldValue, newFinalValue)) {
150
+ this.observers.updated.notify(this);
151
+ this.observers.updatedOrLoadedIn.notify(this);
152
+ }
153
+ return;
154
+ }
155
+ if (oldValue != newFinalValue) {
156
+ this.observers.updated.notify(this);
157
+ this.observers.updatedOrLoadedIn.notify(this);
158
+ }
159
+ }
160
+ forEach(run) {
161
+ if (!this.children)
162
+ return;
163
+ for (const child of this.children) {
164
+ run(child);
165
+ }
166
+ }
167
+ map(map) {
168
+ const data = [];
169
+ this.forEach((_) => data.push(map(_)));
170
+ return data;
171
+ }
172
+ }
@@ -0,0 +1,7 @@
1
+ import { SchemaNode } from "../Schemas/SchemaNode";
2
+ import type { ObjectPropertyValidatorData, ObjectPropertyValidatorResponse } from "./ObjectValidation.types";
3
+ export declare class ObjectPropertyValidator {
4
+ data: ObjectPropertyValidatorData;
5
+ constructor(data: ObjectPropertyValidatorData);
6
+ validate(value: unknown, data: SchemaNode): ObjectPropertyValidatorResponse;
7
+ }
@@ -0,0 +1,9 @@
1
+ export class ObjectPropertyValidator {
2
+ data;
3
+ constructor(data) {
4
+ this.data = data;
5
+ }
6
+ validate(value, data) {
7
+ return this.data.validate(value, data);
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ import type { ObjectPropertyValidatorData } from "./ObjectValidation.types.js";
2
+ import { ObjectPropertyValidator } from "./ObjectPropertyValidator.js";
3
+ export declare class ObjectPropertyValidatorRegister {
4
+ static _validators: Map<string, ObjectPropertyValidator>;
5
+ static registerValidators(validators: ObjectPropertyValidatorData[]): void;
6
+ static getValidator(id: string): ObjectPropertyValidator;
7
+ }
@@ -0,0 +1,13 @@
1
+ import { ObjectPropertyValidator } from "./ObjectPropertyValidator.js";
2
+ export class ObjectPropertyValidatorRegister {
3
+ static _validators = new Map();
4
+ static registerValidators(validators) {
5
+ validators.forEach((data) => this._validators.set(data.id, new ObjectPropertyValidator(data)));
6
+ }
7
+ static getValidator(id) {
8
+ const validator = this._validators.get(id);
9
+ if (!validator)
10
+ throw new Error(`Validator with ${id} does not exist`);
11
+ return validator;
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ import { SchemaNode } from "../Schemas/SchemaNode";
2
+ export type ObjectPropertyValidatorError = {
3
+ id: string;
4
+ errorMessage: string;
5
+ };
6
+ export type ObjectPropertyValidatorResponse = {
7
+ success: boolean;
8
+ errors?: ObjectPropertyValidatorError[];
9
+ };
10
+ export type ObjectPropertyValidatorData = {
11
+ id: string;
12
+ validate(value: unknown, node: SchemaNode): ObjectPropertyValidatorResponse;
13
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from "./ObjectPropertyValidator";
2
+ export * from "./ObjectPropertyValidatorRegister";
3
+ export * from "./ObjectValidation.types";
@@ -0,0 +1,3 @@
1
+ export * from "./ObjectPropertyValidator";
2
+ export * from "./ObjectPropertyValidatorRegister";
3
+ export * from "./ObjectValidation.types";
package/index.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./Schema";
2
+ export * from "./Inputs/DefaultInputs";
3
+ export * from "./Properties/Property";
4
+ export * from "./Properties";
5
+ export * from "./Schemas/ObjectSchema";
6
+ export * from "./Schemas/BinaryObjectSchema";
7
+ export * from "./Schemas/ObjectSchemaInstance";
8
+ export * from "./Properties/ObjectPath";
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./Schema";
2
+ export * from "./Inputs/DefaultInputs";
3
+ export * from "./Properties/Property";
4
+ export * from "./Properties";
5
+ export * from "./Schemas/ObjectSchema";
6
+ export * from "./Schemas/BinaryObjectSchema";
7
+ export * from "./Schemas/ObjectSchemaInstance";
8
+ export * from "./Properties/ObjectPath";
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@amodx/schemas",
3
+ "version": "0.0.01",
4
+ "module": "index.js",
5
+ "types": "index.d.ts",
6
+ "type": "module",
7
+ "description": "Tool for object schemas.",
8
+ "keywords": [],
9
+ "scripts": {
10
+ "build": "mkdir -p dist && rm -rf dist/* && cp package.json dist/package.json && cd ./src && npx tsc",
11
+ "compile": "cd ./src && npx tsc --watch"
12
+ },
13
+ "repository": {
14
+ "url": "git+https://github.com/Amodx/Libraries.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/Amodx/Libraries/issues"
18
+ },
19
+ "homepage": "https://github.com/Amodx/Libraries",
20
+ "author": "Amodx",
21
+ "license": "MIT",
22
+ "devDependencies": {},
23
+ "main": "index.js",
24
+ "publishConfig": {
25
+ "access": "public"
26
+ }
27
+ }