kodzero-schema-parser 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.
- package/dist/KodzeroToValidnoParser.d.ts +46 -0
- package/dist/KodzeroToValidnoParser.d.ts.map +1 -0
- package/dist/KodzeroToValidnoParser.js +306 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/kz-schema-factory/FieldValidator.d.ts +18 -0
- package/dist/kz-schema-factory/FieldValidator.d.ts.map +1 -0
- package/dist/kz-schema-factory/FieldValidator.js +153 -0
- package/dist/kz-schema-factory/SchemaFactory.d.ts +46 -0
- package/dist/kz-schema-factory/SchemaFactory.d.ts.map +1 -0
- package/dist/kz-schema-factory/SchemaFactory.js +115 -0
- package/dist/kz-schema-factory/fields-to-types/number.d.ts +12 -0
- package/dist/kz-schema-factory/fields-to-types/number.d.ts.map +1 -0
- package/dist/kz-schema-factory/fields-to-types/number.js +41 -0
- package/dist/kz-schema-factory/fields-to-types/select.d.ts +12 -0
- package/dist/kz-schema-factory/fields-to-types/select.d.ts.map +1 -0
- package/dist/kz-schema-factory/fields-to-types/select.js +44 -0
- package/dist/kz-schema-factory/fields-to-types/string.d.ts +12 -0
- package/dist/kz-schema-factory/fields-to-types/string.d.ts.map +1 -0
- package/dist/kz-schema-factory/fields-to-types/string.js +47 -0
- package/dist/kz-schema-factory/fields-to-types/url.d.ts +12 -0
- package/dist/kz-schema-factory/fields-to-types/url.d.ts.map +1 -0
- package/dist/kz-schema-factory/fields-to-types/url.js +45 -0
- package/dist/kz-schema-factory/types-constructors/autofieldCreatedAt.d.ts +4 -0
- package/dist/kz-schema-factory/types-constructors/autofieldCreatedAt.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/autofieldCreatedAt.js +15 -0
- package/dist/kz-schema-factory/types-constructors/autofieldId.d.ts +4 -0
- package/dist/kz-schema-factory/types-constructors/autofieldId.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/autofieldId.js +16 -0
- package/dist/kz-schema-factory/types-constructors/autofieldUpdatedAt.d.ts +4 -0
- package/dist/kz-schema-factory/types-constructors/autofieldUpdatedAt.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/autofieldUpdatedAt.js +15 -0
- package/dist/kz-schema-factory/types-constructors/boolean.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/boolean.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/boolean.js +30 -0
- package/dist/kz-schema-factory/types-constructors/date.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/date.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/date.js +43 -0
- package/dist/kz-schema-factory/types-constructors/email.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/email.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/email.js +45 -0
- package/dist/kz-schema-factory/types-constructors/json.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/json.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/json.js +39 -0
- package/dist/kz-schema-factory/types-constructors/number.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/number.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/number.js +41 -0
- package/dist/kz-schema-factory/types-constructors/select.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/select.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/select.js +44 -0
- package/dist/kz-schema-factory/types-constructors/string.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/string.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/string.js +47 -0
- package/dist/kz-schema-factory/types-constructors/url.d.ts +12 -0
- package/dist/kz-schema-factory/types-constructors/url.d.ts.map +1 -0
- package/dist/kz-schema-factory/types-constructors/url.js +45 -0
- package/dist/kz-schema-factory/types.d.ts +60 -0
- package/dist/kz-schema-factory/types.d.ts.map +1 -0
- package/dist/kz-schema-factory/types.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/table-fields.d.ts +7 -0
- package/dist/types/table-fields.d.ts.map +1 -0
- package/dist/types/table-fields.js +1 -0
- package/dist/types/table-types-specs.d.ts +39 -0
- package/dist/types/table-types-specs.d.ts.map +1 -0
- package/dist/types/table-types-specs.js +1 -0
- package/dist/utils/generate-secret.d.ts +3 -0
- package/dist/utils/generate-secret.d.ts.map +1 -0
- package/dist/utils/generate-secret.js +9 -0
- package/dist/utils/is-valid-json.d.ts +3 -0
- package/dist/utils/is-valid-json.d.ts.map +1 -0
- package/dist/utils/is-valid-json.js +16 -0
- package/dist/utils/validate-input.d.ts +4 -0
- package/dist/utils/validate-input.d.ts.map +1 -0
- package/dist/utils/validate-input.js +7 -0
- package/package.json +53 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { TableField, TableFieldAny } from './kz-schema-factory/types.js';
|
|
2
|
+
import type TableFieldString from './kz-schema-factory/types-constructors/string.js';
|
|
3
|
+
import type TableFieldNumber from './kz-schema-factory/types-constructors/number.js';
|
|
4
|
+
import type TableFieldBoolean from './kz-schema-factory/types-constructors/boolean.js';
|
|
5
|
+
import type TableFieldDate from './kz-schema-factory/types-constructors/date.js';
|
|
6
|
+
import type TableFieldJson from './kz-schema-factory/types-constructors/json.js';
|
|
7
|
+
import type TableFieldEmail from './kz-schema-factory/types-constructors/email.js';
|
|
8
|
+
import type TableFieldUrl from './kz-schema-factory/types-constructors/url.js';
|
|
9
|
+
import type TableFieldSelect from './kz-schema-factory/types-constructors/select.js';
|
|
10
|
+
declare class KodzeroToValidnoParser {
|
|
11
|
+
static parseString(field: TableField<TableFieldString>): {
|
|
12
|
+
type: StringConstructor;
|
|
13
|
+
rules?: Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
static parseNumber(field: TableField<TableFieldNumber>): {
|
|
16
|
+
type: NumberConstructor;
|
|
17
|
+
rules?: Record<string, unknown>;
|
|
18
|
+
};
|
|
19
|
+
static parseBoolean(field: TableField<TableFieldBoolean>): {
|
|
20
|
+
type: BooleanConstructor;
|
|
21
|
+
rules?: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
static parseDate(field: TableField<TableFieldDate>): {
|
|
24
|
+
type: DateConstructor;
|
|
25
|
+
rules?: Record<string, unknown>;
|
|
26
|
+
};
|
|
27
|
+
static parseJson(field: TableField<TableFieldJson>): {
|
|
28
|
+
type: StringConstructor;
|
|
29
|
+
rules: Record<string, unknown>;
|
|
30
|
+
};
|
|
31
|
+
static parseEmail(field: TableField<TableFieldEmail>): {
|
|
32
|
+
type: StringConstructor;
|
|
33
|
+
rules?: Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
static parseUrl(field: TableField<TableFieldUrl>): {
|
|
36
|
+
type: StringConstructor;
|
|
37
|
+
rules?: Record<string, unknown>;
|
|
38
|
+
};
|
|
39
|
+
static parseSelect(field: TableField<TableFieldSelect>): {
|
|
40
|
+
type: StringConstructor | ArrayConstructor;
|
|
41
|
+
rules?: Record<string, unknown>;
|
|
42
|
+
};
|
|
43
|
+
static parseSchema(schemaDb: TableField<TableFieldAny>[]): unknown;
|
|
44
|
+
}
|
|
45
|
+
export default KodzeroToValidnoParser;
|
|
46
|
+
//# sourceMappingURL=KodzeroToValidnoParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KodzeroToValidnoParser.d.ts","sourceRoot":"","sources":["../src/KodzeroToValidnoParser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC7E,OAAO,KAAK,gBAAgB,MAAM,kDAAkD,CAAA;AACpF,OAAO,KAAK,gBAAgB,MAAM,kDAAkD,CAAA;AACpF,OAAO,KAAK,iBAAiB,MAAM,mDAAmD,CAAA;AACtF,OAAO,KAAK,cAAc,MAAM,gDAAgD,CAAA;AAChF,OAAO,KAAK,cAAc,MAAM,gDAAgD,CAAA;AAChF,OAAO,KAAK,eAAe,MAAM,iDAAiD,CAAA;AAClF,OAAO,KAAK,aAAa,MAAM,+CAA+C,CAAA;AAC9E,OAAO,KAAK,gBAAgB,MAAM,kDAAkD,CAAA;AAIpF,cAAM,sBAAsB;IAC1B,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC;cAC9B,iBAAiB;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAkC1E,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC;cAC9B,iBAAiB;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IA6B1E,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC;cAChC,kBAAkB;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAmB3E,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC;cAC1B,eAAe;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAkDxE,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC;cAC1B,iBAAiB;eAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAuBzE,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC;cAC5B,iBAAiB;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAyE1E,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC;cACxB,iBAAiB;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAuE1E,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC;cAC9B,iBAAiB,GAAG,gBAAgB;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IA6C7F,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,aAAa,CAAC,EAAE,GAAG,OAAO;CA0CnE;AAED,eAAe,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { validations } from 'validno';
|
|
2
|
+
import isValidJSON from './utils/is-valid-json.js';
|
|
3
|
+
const defaultKeys = ['_id', 'createdAt', 'updatedAt'];
|
|
4
|
+
class KodzeroToValidnoParser {
|
|
5
|
+
static parseString(field) {
|
|
6
|
+
const output = { type: String };
|
|
7
|
+
const specs = {
|
|
8
|
+
lengthMax: field.item.specs.lengthMax !== null,
|
|
9
|
+
lengthMin: field.item.specs.lengthMin !== null,
|
|
10
|
+
pattern: field.item.specs.pattern !== null,
|
|
11
|
+
mayBeEmpty: field.item.specs.mayBeEmpty === false,
|
|
12
|
+
};
|
|
13
|
+
const hasSpecs = Object.values(specs).some((v) => v === true);
|
|
14
|
+
if (hasSpecs) {
|
|
15
|
+
output.rules = {};
|
|
16
|
+
if (specs.lengthMax) {
|
|
17
|
+
output.rules.maxlength = field.item.specs.lengthMax;
|
|
18
|
+
}
|
|
19
|
+
if (specs.lengthMin) {
|
|
20
|
+
output.rules.minlength = field.item.specs.lengthMin;
|
|
21
|
+
}
|
|
22
|
+
if (specs.pattern && typeof field.item.specs.pattern === 'string') {
|
|
23
|
+
output.rules.regex = new RegExp(field.item.specs.pattern);
|
|
24
|
+
}
|
|
25
|
+
if (specs.mayBeEmpty) {
|
|
26
|
+
output.rules.lengthNot = 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return output;
|
|
30
|
+
}
|
|
31
|
+
static parseNumber(field) {
|
|
32
|
+
const output = { type: Number };
|
|
33
|
+
const specs = {
|
|
34
|
+
min: field.item.specs.min !== null,
|
|
35
|
+
max: field.item.specs.max !== null,
|
|
36
|
+
mayBeEmpty: field.item.specs.mayBeEmpty === false,
|
|
37
|
+
};
|
|
38
|
+
const hasSpecs = Object.values(specs).some((v) => v === true);
|
|
39
|
+
if (hasSpecs) {
|
|
40
|
+
output.rules = {};
|
|
41
|
+
if (specs.min) {
|
|
42
|
+
output.rules.min = field.item.specs.min;
|
|
43
|
+
}
|
|
44
|
+
if (specs.max) {
|
|
45
|
+
output.rules.max = field.item.specs.max;
|
|
46
|
+
}
|
|
47
|
+
if (specs.mayBeEmpty) {
|
|
48
|
+
output.rules.isNot = 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return output;
|
|
52
|
+
}
|
|
53
|
+
static parseBoolean(field) {
|
|
54
|
+
const output = { type: Boolean };
|
|
55
|
+
const specs = {
|
|
56
|
+
onlyTrue: field.item.specs.onlyTrue === true,
|
|
57
|
+
};
|
|
58
|
+
const hasSpecs = Object.values(specs).some((v) => v === true);
|
|
59
|
+
if (hasSpecs) {
|
|
60
|
+
output.rules = {};
|
|
61
|
+
if (specs.onlyTrue) {
|
|
62
|
+
output.rules.is = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return output;
|
|
66
|
+
}
|
|
67
|
+
static parseDate(field) {
|
|
68
|
+
const output = { type: Date };
|
|
69
|
+
const specs = {
|
|
70
|
+
min: field.item.specs.min !== null,
|
|
71
|
+
max: field.item.specs.max !== null,
|
|
72
|
+
mayBeEmpty: field.item.specs.mayBeEmpty === false,
|
|
73
|
+
};
|
|
74
|
+
const hasSpecs = Object.values(specs).some((v) => v === true);
|
|
75
|
+
if (hasSpecs) {
|
|
76
|
+
output.rules = {};
|
|
77
|
+
if (specs.mayBeEmpty) {
|
|
78
|
+
output.rules.isNot = null;
|
|
79
|
+
}
|
|
80
|
+
if (specs.min || specs.max) {
|
|
81
|
+
output.rules.custom = (value, {}) => {
|
|
82
|
+
const checks = { min: true, max: true };
|
|
83
|
+
const dateValue = new Date(value).getTime();
|
|
84
|
+
if (specs.min) {
|
|
85
|
+
const minDate = new Date(field.item.specs.min).getTime();
|
|
86
|
+
if (dateValue < minDate) {
|
|
87
|
+
checks.min = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (specs.max) {
|
|
91
|
+
const maxDate = new Date(field.item.specs.max).getTime();
|
|
92
|
+
if (dateValue > maxDate) {
|
|
93
|
+
checks.max = false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const passed = Object.values(checks).every((v) => v === true);
|
|
97
|
+
return {
|
|
98
|
+
result: passed,
|
|
99
|
+
details: passed ? '' : 'Date is out of allowed range',
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return output;
|
|
105
|
+
}
|
|
106
|
+
static parseJson(field) {
|
|
107
|
+
const output = {
|
|
108
|
+
type: String,
|
|
109
|
+
rules: {},
|
|
110
|
+
};
|
|
111
|
+
const specs = {
|
|
112
|
+
mayBeEmpty: field.item.specs.mayBeEmpty === false,
|
|
113
|
+
};
|
|
114
|
+
if (specs.mayBeEmpty) {
|
|
115
|
+
output.rules.isNot = '';
|
|
116
|
+
}
|
|
117
|
+
output.rules.custom = (value, {}) => {
|
|
118
|
+
return {
|
|
119
|
+
result: isValidJSON(value),
|
|
120
|
+
details: isValidJSON(value) ? '' : 'Invalid JSON format',
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
return output;
|
|
124
|
+
}
|
|
125
|
+
static parseEmail(field) {
|
|
126
|
+
const output = { type: String };
|
|
127
|
+
const hasSpecs = {
|
|
128
|
+
allowedDomains: Array.isArray(field.item.specs.allowedDomains) &&
|
|
129
|
+
field.item.specs.allowedDomains.length > 0,
|
|
130
|
+
exceptDomains: Array.isArray(field.item.specs.exceptDomains) && field.item.specs.exceptDomains.length > 0,
|
|
131
|
+
mayBeEmpty: field.item.specs.mayBeEmpty === false,
|
|
132
|
+
};
|
|
133
|
+
output.rules = {};
|
|
134
|
+
if (hasSpecs.mayBeEmpty) {
|
|
135
|
+
output.rules.isNot = '';
|
|
136
|
+
}
|
|
137
|
+
if (hasSpecs.allowedDomains || hasSpecs.exceptDomains || !hasSpecs.mayBeEmpty) {
|
|
138
|
+
output.rules.custom = (value, {}) => {
|
|
139
|
+
if (field.item.specs.mayBeEmpty === true && value === '') {
|
|
140
|
+
return {
|
|
141
|
+
result: true,
|
|
142
|
+
details: '',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (field.item.specs.mayBeEmpty && typeof value === 'string' && value.trim() === '') {
|
|
146
|
+
return {
|
|
147
|
+
result: true,
|
|
148
|
+
details: '',
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const emailParts = value.split('@');
|
|
152
|
+
const formatCheck = validations.isEmail(value);
|
|
153
|
+
if (!formatCheck) {
|
|
154
|
+
return {
|
|
155
|
+
result: false,
|
|
156
|
+
details: 'Invalid email format',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const domain = emailParts[1].toLowerCase();
|
|
160
|
+
let allowed = true;
|
|
161
|
+
if (hasSpecs.allowedDomains) {
|
|
162
|
+
const allowedDomainsLower = field.item.specs.allowedDomains.map((d) => d.toLowerCase());
|
|
163
|
+
if (!allowedDomainsLower.includes(domain)) {
|
|
164
|
+
allowed = false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (hasSpecs.exceptDomains) {
|
|
168
|
+
const exceptDomainsLower = field.item.specs.exceptDomains.map((d) => d.toLowerCase());
|
|
169
|
+
if (exceptDomainsLower.includes(domain)) {
|
|
170
|
+
allowed = false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
result: allowed,
|
|
175
|
+
details: allowed ? '' : 'Email domain is not allowed',
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return output;
|
|
180
|
+
}
|
|
181
|
+
static parseUrl(field) {
|
|
182
|
+
const output = { type: String };
|
|
183
|
+
const specs = {
|
|
184
|
+
allowedDomains: Array.isArray(field.item.specs.allowedDomains) &&
|
|
185
|
+
field.item.specs.allowedDomains.length > 0,
|
|
186
|
+
exceptDomains: Array.isArray(field.item.specs.exceptDomains) && field.item.specs.exceptDomains.length > 0,
|
|
187
|
+
mayBeEmpty: field.item.specs.mayBeEmpty === false,
|
|
188
|
+
};
|
|
189
|
+
const hasSpecs = Object.values(specs).some((v) => v === true);
|
|
190
|
+
if (hasSpecs) {
|
|
191
|
+
output.rules = {};
|
|
192
|
+
if (specs.mayBeEmpty) {
|
|
193
|
+
output.rules.isNot = '';
|
|
194
|
+
}
|
|
195
|
+
if (specs.allowedDomains || specs.exceptDomains) {
|
|
196
|
+
output.rules.custom = (value, {}) => {
|
|
197
|
+
if (field.item.specs.mayBeEmpty && typeof value === 'string' && value.trim() === '') {
|
|
198
|
+
return {
|
|
199
|
+
result: true,
|
|
200
|
+
details: '',
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const urlPattern = /^(https?:\/\/)?(www\.)?([^\/]+)/i;
|
|
204
|
+
const match = value.match(urlPattern);
|
|
205
|
+
if (!match || match.length < 3) {
|
|
206
|
+
return {
|
|
207
|
+
result: false,
|
|
208
|
+
details: 'Invalid URL format',
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const domain = match[3].toLowerCase();
|
|
212
|
+
let allowed = true;
|
|
213
|
+
if (specs.allowedDomains) {
|
|
214
|
+
const allowedDomainsLower = field.item.specs.allowedDomains.map((d) => d.toLowerCase());
|
|
215
|
+
if (!allowedDomainsLower.includes(domain)) {
|
|
216
|
+
allowed = false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (specs.exceptDomains) {
|
|
220
|
+
const exceptDomainsLower = field.item.specs.exceptDomains.map((d) => d.toLowerCase());
|
|
221
|
+
if (exceptDomainsLower.includes(domain)) {
|
|
222
|
+
allowed = false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
result: allowed,
|
|
227
|
+
details: allowed ? '' : 'URL domain is not allowed',
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return output;
|
|
233
|
+
}
|
|
234
|
+
static parseSelect(field) {
|
|
235
|
+
const output = {
|
|
236
|
+
type: String,
|
|
237
|
+
};
|
|
238
|
+
const specs = {
|
|
239
|
+
mayBeEmpty: field.item.specs.mayBeEmpty === false,
|
|
240
|
+
};
|
|
241
|
+
output.rules = {};
|
|
242
|
+
if (specs.mayBeEmpty) {
|
|
243
|
+
output.rules.isNot = '';
|
|
244
|
+
}
|
|
245
|
+
if (field.item.specs.multiple) {
|
|
246
|
+
output.type = Array;
|
|
247
|
+
output.rules.eachType = String;
|
|
248
|
+
if (Array.isArray(field.item.specs.allowedValues) &&
|
|
249
|
+
field.item.specs.allowedValues.length > 0) {
|
|
250
|
+
output.rules.enum = field.item.specs.allowedValues;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
if (Array.isArray(field.item.specs.allowedValues) &&
|
|
255
|
+
field.item.specs.allowedValues.length > 0) {
|
|
256
|
+
output.rules.enum = field.item.specs.allowedValues;
|
|
257
|
+
}
|
|
258
|
+
if (field.item.specs.mayBeEmpty === true) {
|
|
259
|
+
if (!output.rules.enum) {
|
|
260
|
+
output.rules.enum = [];
|
|
261
|
+
}
|
|
262
|
+
;
|
|
263
|
+
output.rules.enum.push('');
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return output;
|
|
267
|
+
}
|
|
268
|
+
static parseSchema(schemaDb) {
|
|
269
|
+
const schema = {};
|
|
270
|
+
const schemaFiltered = schemaDb.filter((field) => field.item.key && !defaultKeys.includes(field.item.key));
|
|
271
|
+
for (const field of schemaFiltered) {
|
|
272
|
+
const key = field.item.key;
|
|
273
|
+
const type = field.item.type;
|
|
274
|
+
switch (type) {
|
|
275
|
+
case 'string':
|
|
276
|
+
schema[key] = KodzeroToValidnoParser.parseString(field);
|
|
277
|
+
break;
|
|
278
|
+
case 'number':
|
|
279
|
+
schema[key] = KodzeroToValidnoParser.parseNumber(field);
|
|
280
|
+
break;
|
|
281
|
+
case 'boolean':
|
|
282
|
+
schema[key] = KodzeroToValidnoParser.parseBoolean(field);
|
|
283
|
+
break;
|
|
284
|
+
case 'date':
|
|
285
|
+
schema[key] = KodzeroToValidnoParser.parseDate(field);
|
|
286
|
+
break;
|
|
287
|
+
case 'json':
|
|
288
|
+
schema[key] = KodzeroToValidnoParser.parseJson(field);
|
|
289
|
+
break;
|
|
290
|
+
case 'email':
|
|
291
|
+
schema[key] = KodzeroToValidnoParser.parseEmail(field);
|
|
292
|
+
break;
|
|
293
|
+
case 'url':
|
|
294
|
+
schema[key] = KodzeroToValidnoParser.parseUrl(field);
|
|
295
|
+
break;
|
|
296
|
+
case 'select':
|
|
297
|
+
schema[key] = KodzeroToValidnoParser.parseSelect(field);
|
|
298
|
+
break;
|
|
299
|
+
default:
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return schema;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
export default KodzeroToValidnoParser;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,MAAM,6BAA6B,CAAC;AAEjE,eAAe,sBAAsB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TableField, TableFieldAny } from "./types.js";
|
|
2
|
+
declare class FieldValidator {
|
|
3
|
+
constructor();
|
|
4
|
+
static validateString(input: Record<string, any>): import("validno").ValidnoResult;
|
|
5
|
+
static validateBoolean(input: Record<string, any>): import("validno").ValidnoResult;
|
|
6
|
+
static validateDate(input: Record<string, any>): import("validno").ValidnoResult;
|
|
7
|
+
static validateEmail(input: Record<string, any>): import("validno").ValidnoResult;
|
|
8
|
+
static validateJson(input: Record<string, any>): import("validno").ValidnoResult;
|
|
9
|
+
static validateNumber(input: Record<string, any>): import("validno").ValidnoResult;
|
|
10
|
+
static validateSelect(input: Record<string, any>): import("validno").ValidnoResult;
|
|
11
|
+
static validateUrl(input: Record<string, any>): import("validno").ValidnoResult;
|
|
12
|
+
static validateBase(input: Record<string, any>): import("validno").ValidnoResult;
|
|
13
|
+
static validateWrapper(input: Record<string, any>): import("validno").ValidnoResult;
|
|
14
|
+
static validateSpecsAuto(type: string, specs: Record<string, any>): import("validno").ValidnoResult;
|
|
15
|
+
static validateAllFields(fields: TableField<TableFieldAny>[]): boolean;
|
|
16
|
+
}
|
|
17
|
+
export default FieldValidator;
|
|
18
|
+
//# sourceMappingURL=FieldValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldValidator.d.ts","sourceRoot":"","sources":["../../src/kz-schema-factory/FieldValidator.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA2FvD,cAAM,cAAc;;IAGhB,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIhD,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIjD,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI9C,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI/C,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI9C,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIhD,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIhD,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI7C,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI9C,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIjD,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAuBjE,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,EAAE;CAgB/D;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import Schema from "validno";
|
|
2
|
+
import { booleanSpecsSchema } from "./types-constructors/boolean.js";
|
|
3
|
+
import { dateSpecsSchema } from "./types-constructors/date.js";
|
|
4
|
+
import { emailSpecsSchema } from "./types-constructors/email.js";
|
|
5
|
+
import { stringSpecsSchema } from "./types-constructors/string.js";
|
|
6
|
+
import { jsonSpecsSchema } from "./types-constructors/json.js";
|
|
7
|
+
import { numberSpecsSchema } from "./types-constructors/number.js";
|
|
8
|
+
import { selectSpecsSchema } from "./types-constructors/select.js";
|
|
9
|
+
import { urlSpecsSchema } from "./types-constructors/url.js";
|
|
10
|
+
const Checks = {
|
|
11
|
+
'ok': {
|
|
12
|
+
description: 'Summary of validations',
|
|
13
|
+
error: 'Field is invalid'
|
|
14
|
+
},
|
|
15
|
+
'unique': {
|
|
16
|
+
description: 'Enserues that key name is unique across the schema',
|
|
17
|
+
error: 'Field key is not unique'
|
|
18
|
+
},
|
|
19
|
+
'wrapper': {
|
|
20
|
+
description: 'Validates field wrapper',
|
|
21
|
+
error: 'Field wrapper failed validation'
|
|
22
|
+
},
|
|
23
|
+
'base': {
|
|
24
|
+
description: 'Validates base field parameters',
|
|
25
|
+
error: 'Base settings failed validation'
|
|
26
|
+
},
|
|
27
|
+
'specs': {
|
|
28
|
+
description: 'Validates type-specific field parameters',
|
|
29
|
+
error: 'Specifications failed validation'
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const getCheckErrorText = (checkId) => {
|
|
33
|
+
return Checks[checkId].error;
|
|
34
|
+
};
|
|
35
|
+
const baseSchema = new Schema({
|
|
36
|
+
key: { type: String },
|
|
37
|
+
type: { type: String },
|
|
38
|
+
title: { type: String },
|
|
39
|
+
});
|
|
40
|
+
const wrapperSchema = new Schema({
|
|
41
|
+
id: { type: String },
|
|
42
|
+
order: { type: Number },
|
|
43
|
+
isAuto: { type: Boolean, required: false },
|
|
44
|
+
item: { type: Object },
|
|
45
|
+
});
|
|
46
|
+
const handleKey = (field, allKeys) => {
|
|
47
|
+
const output = {};
|
|
48
|
+
const keyName = field.item.key;
|
|
49
|
+
const isUnique = allKeys.filter(k => k === keyName).length === 1;
|
|
50
|
+
const wrapperResult = FieldValidator.validateWrapper(field);
|
|
51
|
+
const baseResult = FieldValidator.validateBase(field.item);
|
|
52
|
+
const specsResult = FieldValidator.validateSpecsAuto(field.item.type, field.item.specs);
|
|
53
|
+
output['unique'] = isUnique;
|
|
54
|
+
output['wrapper'] = wrapperResult.ok || false;
|
|
55
|
+
output['base'] = baseResult.ok || false;
|
|
56
|
+
output['specs'] = specsResult.ok || false;
|
|
57
|
+
output['ok'] = [
|
|
58
|
+
isUnique,
|
|
59
|
+
wrapperResult.ok,
|
|
60
|
+
baseResult.ok,
|
|
61
|
+
specsResult.ok
|
|
62
|
+
].every(el => el === true);
|
|
63
|
+
return output;
|
|
64
|
+
};
|
|
65
|
+
const getFinalResult = (results) => {
|
|
66
|
+
const errors = {};
|
|
67
|
+
let errorsString = '';
|
|
68
|
+
for (const [key, result] of Object.entries(results)) {
|
|
69
|
+
if (!result.ok) {
|
|
70
|
+
const failed = Object.entries(result)
|
|
71
|
+
.filter(([k, v]) => k !== 'ok' && v === false)
|
|
72
|
+
.map(([k]) => getCheckErrorText(k));
|
|
73
|
+
if (failed.length) {
|
|
74
|
+
errors[key] = failed;
|
|
75
|
+
errorsString += `"${key}": ${failed.join(',')};`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const finalResult = {
|
|
80
|
+
ok: !Object.keys(errors).length,
|
|
81
|
+
errors,
|
|
82
|
+
errorsString
|
|
83
|
+
};
|
|
84
|
+
return finalResult;
|
|
85
|
+
};
|
|
86
|
+
class FieldValidator {
|
|
87
|
+
constructor() { }
|
|
88
|
+
static validateString(input) {
|
|
89
|
+
return stringSpecsSchema.validate(input);
|
|
90
|
+
}
|
|
91
|
+
static validateBoolean(input) {
|
|
92
|
+
return booleanSpecsSchema.validate(input);
|
|
93
|
+
}
|
|
94
|
+
static validateDate(input) {
|
|
95
|
+
return dateSpecsSchema.validate(input);
|
|
96
|
+
}
|
|
97
|
+
static validateEmail(input) {
|
|
98
|
+
return emailSpecsSchema.validate(input);
|
|
99
|
+
}
|
|
100
|
+
static validateJson(input) {
|
|
101
|
+
return jsonSpecsSchema.validate(input);
|
|
102
|
+
}
|
|
103
|
+
static validateNumber(input) {
|
|
104
|
+
return numberSpecsSchema.validate(input);
|
|
105
|
+
}
|
|
106
|
+
static validateSelect(input) {
|
|
107
|
+
return selectSpecsSchema.validate(input);
|
|
108
|
+
}
|
|
109
|
+
static validateUrl(input) {
|
|
110
|
+
return urlSpecsSchema.validate(input);
|
|
111
|
+
}
|
|
112
|
+
static validateBase(input) {
|
|
113
|
+
return baseSchema.validate(input);
|
|
114
|
+
}
|
|
115
|
+
static validateWrapper(input) {
|
|
116
|
+
return wrapperSchema.validate(input);
|
|
117
|
+
}
|
|
118
|
+
static validateSpecsAuto(type, specs) {
|
|
119
|
+
switch (String(type)) {
|
|
120
|
+
case 'string':
|
|
121
|
+
return this.validateString(specs);
|
|
122
|
+
case 'boolean':
|
|
123
|
+
return this.validateBoolean(specs);
|
|
124
|
+
case 'date':
|
|
125
|
+
return this.validateDate(specs);
|
|
126
|
+
case 'email':
|
|
127
|
+
return this.validateEmail(specs);
|
|
128
|
+
case 'json':
|
|
129
|
+
return this.validateJson(specs);
|
|
130
|
+
case 'number':
|
|
131
|
+
return this.validateNumber(specs);
|
|
132
|
+
case 'select':
|
|
133
|
+
return this.validateSelect(specs);
|
|
134
|
+
case 'url':
|
|
135
|
+
return this.validateUrl(specs);
|
|
136
|
+
default:
|
|
137
|
+
throw new Error(`Unknown field type: ${type}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
static validateAllFields(fields) {
|
|
141
|
+
const results = {};
|
|
142
|
+
const allKeys = fields.map((field) => field.item.key);
|
|
143
|
+
fields.forEach((field) => results[field.item.key] = handleKey(field, allKeys));
|
|
144
|
+
const finalResult = getFinalResult(results);
|
|
145
|
+
if (!finalResult.ok) {
|
|
146
|
+
const err = new Error(`Schema validation failed. ${finalResult.errorsString}`);
|
|
147
|
+
err.code = 400;
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export default FieldValidator;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import TableFieldBoolean from './types-constructors/boolean.js';
|
|
2
|
+
import TableFieldDate from './types-constructors/date.js';
|
|
3
|
+
import TableFieldEmail from './types-constructors/email.js';
|
|
4
|
+
import TableFieldJson from './types-constructors/json.js';
|
|
5
|
+
import TableFieldNumber from './types-constructors/number.js';
|
|
6
|
+
import TableFieldSelect from './types-constructors/select.js';
|
|
7
|
+
import TableFieldString from './types-constructors/string.js';
|
|
8
|
+
import TableFieldUrl from './types-constructors/url.js';
|
|
9
|
+
import type { BooleanSpecs, DateSpecs, EmailSpecs, JsonSpecs, NumberSpecs, SelectSpecs, StringSpecs, UrlSpecs } from './types.js';
|
|
10
|
+
export type TableFieldAny = TableFieldBoolean | TableFieldDate | TableFieldEmail | TableFieldJson | TableFieldNumber | TableFieldSelect | TableFieldString | TableFieldUrl;
|
|
11
|
+
type IndexItem = {
|
|
12
|
+
key: string;
|
|
13
|
+
isUnique: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type TableField<T> = {
|
|
16
|
+
id: string;
|
|
17
|
+
order: number;
|
|
18
|
+
isAuto?: boolean;
|
|
19
|
+
item: T;
|
|
20
|
+
};
|
|
21
|
+
declare class CollectionConfig {
|
|
22
|
+
items: TableField<TableFieldAny>[];
|
|
23
|
+
totalQty: number;
|
|
24
|
+
indexes: Array<IndexItem>;
|
|
25
|
+
constructor(items?: TableField<TableFieldAny>[]);
|
|
26
|
+
add(item: TableFieldAny): void;
|
|
27
|
+
copyById(id: string): void;
|
|
28
|
+
remove(order: number): void;
|
|
29
|
+
removeById(id: string): void;
|
|
30
|
+
updateNameById(id: string, name: string): void;
|
|
31
|
+
updateSpecsById(id: string, newSpecs: TableFieldAny['specs']): void;
|
|
32
|
+
move(from: number, to: number): void;
|
|
33
|
+
}
|
|
34
|
+
export declare class TableFieldCreator {
|
|
35
|
+
static create(key: string, type: string, settings?: unknown): TableFieldBoolean | TableFieldDate | TableFieldEmail | TableFieldJson | TableFieldNumber | TableFieldSelect | TableFieldString | TableFieldUrl;
|
|
36
|
+
static createBoolean(key: string, settings: Partial<BooleanSpecs>): TableFieldBoolean;
|
|
37
|
+
static createString(key: string, settings?: Partial<StringSpecs>): TableFieldString;
|
|
38
|
+
static createNumber(key: string, settings?: Partial<NumberSpecs>): TableFieldNumber;
|
|
39
|
+
static createDate(key: string, settings?: Partial<DateSpecs>): TableFieldDate;
|
|
40
|
+
static createEmail(key: string, settings?: Partial<EmailSpecs>): TableFieldEmail;
|
|
41
|
+
static createJson(key: string, settings?: Partial<JsonSpecs>): TableFieldJson;
|
|
42
|
+
static createSelect(key: string, settings?: Partial<SelectSpecs>): TableFieldSelect;
|
|
43
|
+
static createUrl(key: string, settings?: Partial<UrlSpecs>): TableFieldUrl;
|
|
44
|
+
}
|
|
45
|
+
export default CollectionConfig;
|
|
46
|
+
//# sourceMappingURL=SchemaFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaFactory.d.ts","sourceRoot":"","sources":["../../src/kz-schema-factory/SchemaFactory.ts"],"names":[],"mappings":"AACA,OAAO,iBAAiB,MAAM,iCAAiC,CAAA;AAC/D,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,OAAO,eAAe,MAAM,+BAA+B,CAAA;AAC3D,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,OAAO,gBAAgB,MAAM,gCAAgC,CAAA;AAC7D,OAAO,gBAAgB,MAAM,gCAAgC,CAAA;AAC7D,OAAO,gBAAgB,MAAM,gCAAgC,CAAA;AAC7D,OAAO,aAAa,MAAM,6BAA6B,CAAA;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,WAAW,EACX,QAAQ,EACT,MAAM,YAAY,CAAA;AAGnB,MAAM,MAAM,aAAa,GACrB,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,aAAa,CAAA;AAEjB,KAAK,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAA;AAEnD,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,CAAC,CAAA;CACR,CAAA;AAED,cAAM,gBAAgB;IACpB,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,EAAE,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;gBAEb,KAAK,GAAE,UAAU,CAAC,aAAa,CAAC,EAAO;IAMnD,GAAG,CAAC,IAAI,EAAE,aAAa;IAOvB,QAAQ,CAAC,EAAE,EAAE,MAAM;IAcnB,MAAM,CAAC,KAAK,EAAE,MAAM;IAKpB,UAAU,CAAC,EAAE,EAAE,MAAM;IAKrB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAKvC,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC;IAK5D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAuB9B;AAED,qBAAa,iBAAiB;IAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAY;IAuB/D,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC;IAIjE,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,CAAC,WAAW,CAAM;IAIpE,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,CAAC,WAAW,CAAM;IAIpE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,CAAC,SAAS,CAAM;IAIhE,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,CAAC,UAAU,CAAM;IAIlE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,CAAC,SAAS,CAAM;IAIhE,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,CAAC,WAAW,CAAM;IAIpE,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAO,CAAC,QAAQ,CAAM;CAG/D;AAED,eAAe,gBAAgB,CAAA"}
|