@based/schema 2.5.3 → 2.6.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/dist/src/compat/index.d.ts +2 -0
- package/dist/src/compat/index.js +3 -0
- package/dist/src/compat/newToOld.d.ts +3 -0
- package/dist/src/compat/newToOld.js +76 -0
- package/dist/src/compat/oldSchemaType.d.ts +69 -0
- package/dist/src/compat/oldSchemaType.js +2 -0
- package/dist/src/compat/oldToNew.d.ts +3 -0
- package/dist/src/compat/oldToNew.js +35 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/test/compat.d.ts +1 -0
- package/dist/test/compat.js +11 -0
- package/dist/test/data/newSchemas.d.ts +2 -0
- package/dist/test/data/newSchemas.js +254 -0
- package/dist/test/data/oldSchemas.d.ts +2 -0
- package/dist/test/data/oldSchemas.js +5058 -0
- package/package.json +4 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const metaChecker = (field) => {
|
|
2
|
+
return (field === 'validation' ||
|
|
3
|
+
field === 'format' ||
|
|
4
|
+
field === 'index' ||
|
|
5
|
+
field === 'description' ||
|
|
6
|
+
field === 'title' ||
|
|
7
|
+
field === 'examples' ||
|
|
8
|
+
field === 'ui' ||
|
|
9
|
+
field === 'isRequired' ||
|
|
10
|
+
field === 'title' ||
|
|
11
|
+
field === 'description' ||
|
|
12
|
+
field === 'index' ||
|
|
13
|
+
field === 'readOnly' ||
|
|
14
|
+
field === 'writeOnly' ||
|
|
15
|
+
field === '$comment' ||
|
|
16
|
+
field === 'examples' ||
|
|
17
|
+
field === 'default' ||
|
|
18
|
+
field === 'customValidator' ||
|
|
19
|
+
field === 'value' ||
|
|
20
|
+
field === 'path' ||
|
|
21
|
+
field === 'target' ||
|
|
22
|
+
field === 'minLength' ||
|
|
23
|
+
field === 'maxLength' ||
|
|
24
|
+
field === 'contentMediaEncoding' ||
|
|
25
|
+
field === 'pattern' ||
|
|
26
|
+
field === 'display' ||
|
|
27
|
+
field === 'multiline' ||
|
|
28
|
+
field === 'multipleOf' ||
|
|
29
|
+
field === 'minimum' ||
|
|
30
|
+
field === 'maximum' ||
|
|
31
|
+
field === 'exclusiveMaximum' ||
|
|
32
|
+
field === 'exclusiveMinimum' ||
|
|
33
|
+
field === '$delete');
|
|
34
|
+
};
|
|
35
|
+
const excludedFields = (field) => {
|
|
36
|
+
return field === 'language' || field === 'translations' || field === '$defs';
|
|
37
|
+
};
|
|
38
|
+
export const convertNewToOld = (schema) => {
|
|
39
|
+
const tmpSchema = {};
|
|
40
|
+
const walker = (target, source) => {
|
|
41
|
+
for (const i in source) {
|
|
42
|
+
if (source[i] && typeof source[i] === 'object' && i in target === false) {
|
|
43
|
+
target[i] = source[i].length ? [] : {};
|
|
44
|
+
walker(target[i], source[i]);
|
|
45
|
+
}
|
|
46
|
+
else if (!metaChecker(i)) {
|
|
47
|
+
target[i] = source[i];
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
target.meta = {};
|
|
51
|
+
for (const i in source) {
|
|
52
|
+
if (metaChecker(i) && typeof source[i] !== 'object') {
|
|
53
|
+
if (i === 'title') {
|
|
54
|
+
target.meta = { ...target.meta, name: source[i] };
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
target.meta = { ...target.meta, [i]: source[i] };
|
|
58
|
+
}
|
|
59
|
+
delete source[i];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
walker(tmpSchema, schema);
|
|
66
|
+
if ((tmpSchema.meta = {}))
|
|
67
|
+
delete tmpSchema.meta;
|
|
68
|
+
for (const i in tmpSchema) {
|
|
69
|
+
if (excludedFields(i)) {
|
|
70
|
+
delete tmpSchema[i];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
tmpSchema.languages = [schema.language, ...schema?.translations];
|
|
74
|
+
return tmpSchema;
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=newToOld.js.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
type FieldType = 'float' | 'boolean' | 'number' | 'int' | 'string' | 'text' | 'id' | 'digest' | 'url' | 'email' | 'phone' | 'geo' | 'type' | 'timestamp';
|
|
2
|
+
type FieldSchemaObject = {
|
|
3
|
+
type: 'object';
|
|
4
|
+
properties: {
|
|
5
|
+
[key: string]: FieldSchema;
|
|
6
|
+
};
|
|
7
|
+
meta?: any;
|
|
8
|
+
timeseries?: boolean;
|
|
9
|
+
};
|
|
10
|
+
type FieldSchemaJson = {
|
|
11
|
+
type: 'json';
|
|
12
|
+
properties?: {
|
|
13
|
+
[key: string]: FieldSchema;
|
|
14
|
+
};
|
|
15
|
+
meta?: any;
|
|
16
|
+
timeseries?: boolean;
|
|
17
|
+
};
|
|
18
|
+
type FieldSchemaRecord = {
|
|
19
|
+
type: 'record';
|
|
20
|
+
values: FieldSchema;
|
|
21
|
+
meta?: any;
|
|
22
|
+
timeseries?: boolean;
|
|
23
|
+
};
|
|
24
|
+
type FieldSchemaReferences = {
|
|
25
|
+
type: 'reference' | 'references';
|
|
26
|
+
bidirectional?: {
|
|
27
|
+
fromField: string;
|
|
28
|
+
};
|
|
29
|
+
meta?: any;
|
|
30
|
+
timeseries?: boolean;
|
|
31
|
+
};
|
|
32
|
+
type FieldSchemaOther = {
|
|
33
|
+
type: FieldType;
|
|
34
|
+
meta?: any;
|
|
35
|
+
timeseries?: boolean;
|
|
36
|
+
};
|
|
37
|
+
type FieldSchemaArrayLike = {
|
|
38
|
+
type: 'set' | 'array';
|
|
39
|
+
items: FieldSchema;
|
|
40
|
+
meta?: any;
|
|
41
|
+
timeseries?: boolean;
|
|
42
|
+
};
|
|
43
|
+
type FieldSchema = FieldSchemaObject | FieldSchemaRecord | FieldSchemaArrayLike | FieldSchemaJson | FieldSchemaReferences | FieldSchemaOther;
|
|
44
|
+
type Fields = Record<string, FieldSchema>;
|
|
45
|
+
type HierarchySchema = false | {
|
|
46
|
+
[key: string]: false | {
|
|
47
|
+
excludeAncestryWith: string[];
|
|
48
|
+
} | {
|
|
49
|
+
includeAncestryWith: string[];
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
type TypeSchema = {
|
|
53
|
+
prefix?: string;
|
|
54
|
+
hierarchy?: HierarchySchema;
|
|
55
|
+
fields?: Fields;
|
|
56
|
+
meta?: any;
|
|
57
|
+
};
|
|
58
|
+
type Types = {
|
|
59
|
+
[key: string]: TypeSchema;
|
|
60
|
+
};
|
|
61
|
+
export type BasedOldSchema = {
|
|
62
|
+
sha?: string;
|
|
63
|
+
languages?: string[];
|
|
64
|
+
types: Types;
|
|
65
|
+
rootType?: Pick<TypeSchema, 'fields' | 'prefix' | 'meta'>;
|
|
66
|
+
idSeedCounter?: number;
|
|
67
|
+
prefixToTypeMapping?: Record<string, string>;
|
|
68
|
+
};
|
|
69
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const convertOldToNew = (oldSchema) => {
|
|
2
|
+
const tempSchema = {};
|
|
3
|
+
const walker = (source, target) => {
|
|
4
|
+
for (const i in source) {
|
|
5
|
+
if (i === 'languages' && source[i].length) {
|
|
6
|
+
target.language = source[i][0];
|
|
7
|
+
target.translations = source[i].filter((_, i) => i !== 0);
|
|
8
|
+
}
|
|
9
|
+
else if (typeof source[i] === 'object' && i in target === false) {
|
|
10
|
+
if (i === 'meta' &&
|
|
11
|
+
!Object.keys(source[i]).includes('properties' || 'type')) {
|
|
12
|
+
for (const j in source[i]) {
|
|
13
|
+
if (j === 'name') {
|
|
14
|
+
target.title = source[i][j];
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
target[j] = source[i][j];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
target[i] = source[i].length ? [] : {};
|
|
23
|
+
walker(source[i], target[i]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (i !== 'meta') {
|
|
27
|
+
target[i] = source[i];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
walker(oldSchema, tempSchema);
|
|
32
|
+
tempSchema.$defs = {};
|
|
33
|
+
return tempSchema;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=oldToNew.js.map
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
// TODO: maybe nice to use for validate import { newSchemas } from './data/newSchemas.js'
|
|
3
|
+
import { oldSchemas } from './data/oldSchemas.js';
|
|
4
|
+
import { convertNewToOld, convertOldToNew } from '../src/index.js';
|
|
5
|
+
test('old schema compat mode', async (t) => {
|
|
6
|
+
for (let i = 0; i < oldSchemas.length; i++) {
|
|
7
|
+
const oldSchema = oldSchemas[i];
|
|
8
|
+
t.deepEqual(convertNewToOld(convertOldToNew(oldSchema)), oldSchema, `Schema conversion oldSchemas index ${i}`);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=compat.js.map
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
export const newSchemas = [
|
|
2
|
+
{
|
|
3
|
+
types: {
|
|
4
|
+
thing: {
|
|
5
|
+
prefix: 'ti',
|
|
6
|
+
fields: {
|
|
7
|
+
priority: { type: 'number' },
|
|
8
|
+
something: { type: 'string', format: 'strongPassword' },
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
bla: {
|
|
12
|
+
prefix: 'bl',
|
|
13
|
+
fields: {
|
|
14
|
+
enum: {
|
|
15
|
+
enum: ['tony', 'jim'],
|
|
16
|
+
},
|
|
17
|
+
setOfNumbers: {
|
|
18
|
+
type: 'set',
|
|
19
|
+
items: {
|
|
20
|
+
type: 'number',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
object: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
flap: { type: 'boolean' },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
flap: {
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
},
|
|
32
|
+
x: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: {
|
|
35
|
+
flap: {
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
record: {
|
|
41
|
+
type: 'record',
|
|
42
|
+
values: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
bla: {
|
|
46
|
+
type: 'array',
|
|
47
|
+
values: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
snux: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
x: {
|
|
54
|
+
type: 'number',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
flap: { type: 'number' },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
bla: {
|
|
66
|
+
type: 'set',
|
|
67
|
+
items: { type: 'string', minLength: 3, maxLength: 6 },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
$defs: {},
|
|
73
|
+
language: 'en',
|
|
74
|
+
translations: ['de', 'nl', 'ro', 'za', 'ae'],
|
|
75
|
+
root: {
|
|
76
|
+
fields: {},
|
|
77
|
+
},
|
|
78
|
+
prefixToTypeMapping: {
|
|
79
|
+
bl: 'bla',
|
|
80
|
+
ti: 'thing',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
types: {
|
|
85
|
+
thing: {
|
|
86
|
+
prefix: 'ti',
|
|
87
|
+
fields: {
|
|
88
|
+
dateHuman: { type: 'timestamp', display: 'human' },
|
|
89
|
+
dateTime: { type: 'timestamp', display: 'date-time' },
|
|
90
|
+
dateTimeText: { type: 'timestamp', display: 'date-time-text' },
|
|
91
|
+
time: { type: 'timestamp', display: 'time' },
|
|
92
|
+
timePrecise: { type: 'timestamp', display: 'time-precise' },
|
|
93
|
+
capitalize: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
display: 'capitalize',
|
|
96
|
+
format: 'lowercase',
|
|
97
|
+
},
|
|
98
|
+
upperCase: { type: 'string', display: 'uppercase' },
|
|
99
|
+
lowerCase: { type: 'string', display: 'lowercase' },
|
|
100
|
+
euros: { type: 'number', display: 'euro' },
|
|
101
|
+
dollars: { type: 'number', display: 'dollar' },
|
|
102
|
+
pounds: { type: 'number', display: 'pound' },
|
|
103
|
+
bytes: { type: 'number', display: 'bytes' },
|
|
104
|
+
humanNumber: { type: 'number', display: 'human' },
|
|
105
|
+
ratio: { type: 'number', display: 'ratio' },
|
|
106
|
+
short: { type: 'number', display: 'short' },
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
$defs: {},
|
|
111
|
+
language: 'en',
|
|
112
|
+
root: {
|
|
113
|
+
fields: {},
|
|
114
|
+
},
|
|
115
|
+
prefixToTypeMapping: {
|
|
116
|
+
bl: 'bla',
|
|
117
|
+
ti: 'thing',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
language: 'en',
|
|
122
|
+
translations: ['nl'],
|
|
123
|
+
$defs: {},
|
|
124
|
+
prefixToTypeMapping: {},
|
|
125
|
+
root: {
|
|
126
|
+
fields: {},
|
|
127
|
+
},
|
|
128
|
+
types: {
|
|
129
|
+
file: {
|
|
130
|
+
prefix: 'fi',
|
|
131
|
+
fields: {
|
|
132
|
+
usedIn: {
|
|
133
|
+
type: 'references',
|
|
134
|
+
bidirectional: { fromField: 'img' },
|
|
135
|
+
},
|
|
136
|
+
caption: {
|
|
137
|
+
// needs translation?
|
|
138
|
+
type: 'text',
|
|
139
|
+
description: 'Caption for seo',
|
|
140
|
+
title: 'Caption',
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
user: {
|
|
145
|
+
prefix: 'us',
|
|
146
|
+
fields: {
|
|
147
|
+
firstName: { type: 'string' },
|
|
148
|
+
lastName: { type: 'string' },
|
|
149
|
+
email: { type: 'string', format: 'email' },
|
|
150
|
+
company: { type: 'reference' },
|
|
151
|
+
newsletter: { type: 'integer' },
|
|
152
|
+
ip: { type: 'string' },
|
|
153
|
+
seen: { type: 'timestamp' },
|
|
154
|
+
charges: {
|
|
155
|
+
type: 'references',
|
|
156
|
+
bidirectional: { fromField: 'user' },
|
|
157
|
+
allowedTypes: ['charge'],
|
|
158
|
+
},
|
|
159
|
+
articles: {
|
|
160
|
+
type: 'references',
|
|
161
|
+
bidirectional: { fromField: 'contributors' },
|
|
162
|
+
allowedTypes: ['article'],
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
charge: {
|
|
167
|
+
fields: {
|
|
168
|
+
// does this have a user?
|
|
169
|
+
user: {
|
|
170
|
+
type: 'reference',
|
|
171
|
+
bidirectional: { fromField: 'charges' },
|
|
172
|
+
allowedTypes: ['user'],
|
|
173
|
+
},
|
|
174
|
+
token: { type: 'string' },
|
|
175
|
+
description: { type: 'string' },
|
|
176
|
+
amount: { type: 'number' },
|
|
177
|
+
stripeId: { type: 'string' },
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
category: {
|
|
181
|
+
fields: {
|
|
182
|
+
title: { type: 'text' },
|
|
183
|
+
children: {
|
|
184
|
+
type: 'references',
|
|
185
|
+
allowedTypes: ['article'],
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
section: {
|
|
190
|
+
fields: {
|
|
191
|
+
title: { type: 'text' },
|
|
192
|
+
membership: { type: 'number' },
|
|
193
|
+
membershipFreeDays: { type: 'number' },
|
|
194
|
+
hidden: { type: 'boolean' },
|
|
195
|
+
metaDescription: { type: 'text' },
|
|
196
|
+
// meta_keywords: { type: 'array', values: { type: 'string' } },
|
|
197
|
+
children: {
|
|
198
|
+
type: 'references',
|
|
199
|
+
allowedTypes: ['article', 'category'],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
article: {
|
|
204
|
+
prefix: 'ar',
|
|
205
|
+
fields: {
|
|
206
|
+
contributors: {
|
|
207
|
+
title: 'Writers',
|
|
208
|
+
description: 'Writers or people involved with the article.',
|
|
209
|
+
type: 'references',
|
|
210
|
+
allowedTypes: ['user'],
|
|
211
|
+
bidirectional: {
|
|
212
|
+
fromField: 'articles',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
contributorsText: {
|
|
216
|
+
title: 'Contributors text',
|
|
217
|
+
description: 'Gets auto generated based on contributors, fill it in to override.',
|
|
218
|
+
examples: ['Peter Teffer, graphics by Kashyap Raibagi (EDJNET)'],
|
|
219
|
+
type: 'text',
|
|
220
|
+
},
|
|
221
|
+
headline: {
|
|
222
|
+
title: 'Headline',
|
|
223
|
+
description: 'Displayed on pages, also used as meta title for seo.',
|
|
224
|
+
type: 'text',
|
|
225
|
+
},
|
|
226
|
+
publishDate: {
|
|
227
|
+
title: 'Publish date',
|
|
228
|
+
description: 'Any time you want the article to show on the website',
|
|
229
|
+
type: 'timestamp',
|
|
230
|
+
},
|
|
231
|
+
archived: {
|
|
232
|
+
title: 'Archived',
|
|
233
|
+
description: 'Archived articles will not show up on the website or be available outside of the cms',
|
|
234
|
+
type: 'boolean',
|
|
235
|
+
},
|
|
236
|
+
img: {
|
|
237
|
+
type: 'reference',
|
|
238
|
+
allowedTypes: ['file'],
|
|
239
|
+
bidirectional: { fromField: 'usedIn' },
|
|
240
|
+
},
|
|
241
|
+
hits: { type: 'number' }, // get a bit more going here maybe? what does this mean
|
|
242
|
+
membership: { enum: ['Need membership', 'Free'] },
|
|
243
|
+
location: { type: 'text' }, // or string its just city name or smth
|
|
244
|
+
bio: { type: 'text', format: 'json' }, //has a href and stuff so aarich text
|
|
245
|
+
tweet: { type: 'string' }, // ask if it needs translation // 'The 2009 allocation of solar subsidies in Solvakia "was rigged," say a US cable. PM Fico denies it.',
|
|
246
|
+
notes: { type: 'string' },
|
|
247
|
+
abstract: { type: 'text' },
|
|
248
|
+
body: { type: 'text', format: 'json' }, // will add rich text
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
];
|
|
254
|
+
//# sourceMappingURL=newSchemas.js.map
|