-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
160 lines (137 loc) · 4.55 KB
/
index.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import { Schema, model, connect } from 'mongoose';
import mongoose from 'mongoose';
/*
TODO:
- Generate Schema file from css
- generate css from schema file
REFERENCES:
+U/! = unique
+R/* = required
+I/# = index
(0,999) = min,max
['adam','eve'] = enum
EXAMPLE:
let Models = models({
Computer : [
"name|String|!|*|#|(3,16)", // ! = unique, * = required, # = index, (3,16) = minlength,maxlength
"price|Number|+U|+R|+I", // same as above, +U = unique, +R = required, +I = index
"madeIn=India|String|ref:CountryNames", // ref:CountryNames = reference to another model
"dateOfPurchase|Date|*", // Date = Date , * = required
"color|String|['red','blue','green']", // ['red','blue','green'] = enum
"inStock|Boolean|!|#", // ! = unique, # = index
"storageTemperature|Number|(-10,60)", // (0,) = min no upper limit
"globalStockQty|Number|(0,)", // (0,) = min, no upper limit // (,100) = no lower limit
]
})
*/
// sample : username|String|*|!|#|(5,10)|ref:OtherCollection
// sample : username|String|+U|+R|+I|(5,10)|ref:OtherCollection
// enum sample : username|String|+U|+R|+I|(5,10)|['adam','eve']
// nested+default sample css : person.role=admin|String|+U|+R|+I|(5,10)|['adam','eve']
export function parser(css) {
if (css === '' || css === null || css === undefined) {
return null;
}
// if css is array, parse each element
if (css.constructor === Array) {
return css.map((x) => parser(x));
}
var fields = css.split('|'), //filter falsy or empty
Name = fields[0].trim(),
Type = Schema.Types[fields[1].trim()] || Schema.Types.String,
Modifiers = fields.slice(2),
options = {};
let hasDefault = Name.match(/=/); // scan default in name
let hasRef = Modifiers.find((x) => x.match(/^ref:/)); // scan ref
let hasRange = Modifiers.find((x) => x.match(/^\(/)); // scan ranges
let hasEnum = Modifiers.find((x) => x.match(/^\[/)); // scan enums
if (Modifiers.includes('*') || Modifiers.includes('+R')) {
options.required = true;
}
if (Modifiers.includes('#') || Modifiers.includes('+I')) {
options.index = true;
}
if (Modifiers.includes('!') || Modifiers.includes('+U')) {
options.unique = true;
}
if (hasDefault) {
let [name, defaultValue] = Name.split('=');
Name = name;
options.default = defaultValue;
}
if (hasRef) {
let ref = hasRef.replace('ref:', '');
options.ref = ref;
Type = Schema.Types.ObjectId;
return {
[Name]: {
type: Type,
ref: ref,
},
};
}
if (hasRange) {
let [min, max] = hasRange.replace('(', '').replace(')', '').split(',');
min = min.includes('.') ? parseFloat(min) : parseInt(min);
max = max.includes('.') ? parseFloat(max) : parseInt(max);
if (fields[1] === 'Number') {
min ? (options.min = min) : null;
max ? (options.max = max) : null;
} else {
min ? (options.minlength = min) : null;
max ? (options.maxlength = max) : null;
}
// console.log('range', min, max);
}
if (hasEnum) {
options.enum = eval(hasEnum);
}
return {
[Name]: {
type: Type,
...options,
},
};
}
export function schema(css) {
let parsed = parser(css);
let preSchema = {};
parsed.forEach((x) => {
preSchema = { ...preSchema, ...x };
});
return new Schema(preSchema);
}
export let models = (modeldict) => {
let _models = {};
for (let m in modeldict) {
_models[m] = model(m, schema(modeldict[m]));
}
return _models;
};
async function main() {
await connect('mongodb://localhost:27017/test', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// give a simple test for employee schema
let Models = models({
Employee: [
'name|String|!|*|#|(3,)', // ! = unique, * = required, # = index, (3,16) = minlength,maxlength
'age|Number', // same as above, +U = unique, +R = required, +I = index
'gender|String|["male","female"]', // ['red','blue','green'] = enum
'salary|Number|(0,)', // (0,) = min, no upper limit // (,)]})
],
});
console.log(Models);
// add one to database
let employee = new Models.Employee({
name: 'ashil Does 2',
age: 25,
gender: 'male',
salary: 12,
});
// console.log(employee);
employee.save();
console.log(await Models.Employee.find({}));
console.log('ashiled');
}