@based/schema 2.7.1 → 3.0.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.
Files changed (62) hide show
  1. package/dist/display/index.d.ts +2 -0
  2. package/dist/display/index.js +26 -0
  3. package/dist/display/number.d.ts +3 -0
  4. package/dist/display/number.js +89 -0
  5. package/dist/display/string.d.ts +3 -0
  6. package/dist/display/string.js +23 -0
  7. package/dist/display/timestamp.d.ts +3 -0
  8. package/dist/display/timestamp.js +127 -0
  9. package/dist/error.d.ts +19 -0
  10. package/dist/error.js +24 -0
  11. package/dist/index.d.ts +5 -0
  12. package/dist/index.js +22 -0
  13. package/dist/languages.d.ts +187 -0
  14. package/dist/languages.js +190 -0
  15. package/dist/set/fields/array.d.ts +2 -0
  16. package/dist/set/fields/array.js +123 -0
  17. package/dist/set/fields/index.d.ts +3 -0
  18. package/dist/set/fields/index.js +74 -0
  19. package/dist/set/fields/number.d.ts +4 -0
  20. package/dist/set/fields/number.js +129 -0
  21. package/dist/set/fields/object.d.ts +3 -0
  22. package/dist/set/fields/object.js +33 -0
  23. package/dist/set/fields/references.d.ts +3 -0
  24. package/dist/set/fields/references.js +128 -0
  25. package/dist/set/fields/set.d.ts +2 -0
  26. package/dist/set/fields/set.js +63 -0
  27. package/dist/set/fields/string.d.ts +3 -0
  28. package/dist/set/fields/string.js +284 -0
  29. package/dist/set/index.d.ts +3 -0
  30. package/dist/set/index.js +183 -0
  31. package/dist/set/isValidId.d.ts +2 -0
  32. package/dist/set/isValidId.js +21 -0
  33. package/dist/set/types.d.ts +0 -0
  34. package/dist/set/types.js +1 -0
  35. package/dist/src/compat/index.d.ts +6 -2
  36. package/dist/src/compat/index.js +202 -2
  37. package/dist/src/compat/newToOld.js +6 -7
  38. package/dist/src/compat/oldSchemaType.d.ts +28 -4
  39. package/dist/src/set/fields/array.js +4 -4
  40. package/dist/src/types.d.ts +1 -1
  41. package/dist/src/validateSchema/fieldValidators.js +1 -1
  42. package/dist/test/array.js +4 -4
  43. package/dist/test/compat.js +29 -5
  44. package/dist/test/data/newSchemas.js +5 -9
  45. package/dist/test/rest.js +1 -1
  46. package/dist/test/validateSchema/fields.js +5 -5
  47. package/dist/test/walker.js +2 -2
  48. package/dist/types.d.ts +205 -0
  49. package/dist/types.js +27 -0
  50. package/dist/updateSchema.d.ts +2 -0
  51. package/dist/updateSchema.js +16 -0
  52. package/dist/validateSchema.d.ts +4 -0
  53. package/dist/validateSchema.js +41 -0
  54. package/dist/walker/args.d.ts +36 -0
  55. package/dist/walker/args.js +162 -0
  56. package/dist/walker/index.d.ts +6 -0
  57. package/dist/walker/index.js +49 -0
  58. package/dist/walker/parse.d.ts +3 -0
  59. package/dist/walker/parse.js +186 -0
  60. package/dist/walker/types.d.ts +45 -0
  61. package/dist/walker/types.js +10 -0
  62. package/package.json +1 -1
@@ -1,3 +1,203 @@
1
- export * from './newToOld.js';
2
- export * from './oldToNew.js';
1
+ const oldToNewType = {
2
+ id: { type: 'string', format: 'basedId' },
3
+ int: { type: 'integer' },
4
+ url: { type: 'string', format: 'URL' },
5
+ email: { type: 'string', format: 'email' },
6
+ float: { type: 'number' },
7
+ phone: { type: 'string', format: 'mobilePhone' },
8
+ digest: { type: 'string', format: 'strongPassword' },
9
+ };
10
+ const newToOldType = {
11
+ mobilePhone: { type: 'phone' },
12
+ basedId: { type: 'id' },
13
+ integer: { type: 'int' },
14
+ URL: { type: 'url' },
15
+ email: { type: 'email' },
16
+ strongPassword: { type: 'digest' },
17
+ };
18
+ const convertNewToOldMeta = (props) => {
19
+ let meta;
20
+ for (const i in props) {
21
+ if (i[0] !== '$') {
22
+ const v = props[i];
23
+ meta ??= {};
24
+ if (i === 'display' && v === 'bytes') {
25
+ meta.format = v;
26
+ }
27
+ else if (i === 'title') {
28
+ meta.name = v;
29
+ }
30
+ else {
31
+ meta[i] = v;
32
+ }
33
+ }
34
+ }
35
+ return meta;
36
+ };
37
+ const convertOldToNewMeta = (props) => {
38
+ const meta = {};
39
+ for (const i in props) {
40
+ const v = props[i];
41
+ if (i === 'format' && v === 'bytes') {
42
+ meta.display = 'bytes';
43
+ }
44
+ else if (i === 'name') {
45
+ meta.title = v;
46
+ }
47
+ else {
48
+ meta[i] = v;
49
+ }
50
+ }
51
+ return meta;
52
+ };
53
+ const convertNewFieldToOldField = (newField) => {
54
+ // @ts-ignore
55
+ const { type, properties, values, items, ...props } = newField;
56
+ const meta = convertNewToOldMeta(props);
57
+ // @ts-ignore
58
+ const overwrite = newToOldType[type] || newToOldType[props.format];
59
+ const oldField = overwrite
60
+ ? { ...overwrite }
61
+ : {
62
+ type,
63
+ };
64
+ if (meta) {
65
+ oldField.meta = meta;
66
+ }
67
+ if (properties) {
68
+ // @ts-ignore
69
+ oldField.properties = {};
70
+ for (const key in properties) {
71
+ // @ts-ignore
72
+ oldField.properties[key] = convertNewFieldToOldField(properties[key]);
73
+ }
74
+ }
75
+ if (values) {
76
+ // @ts-ignore
77
+ oldField.values = convertNewFieldToOldField(values);
78
+ }
79
+ if (items) {
80
+ // @ts-ignore
81
+ oldField.items = convertNewFieldToOldField(items);
82
+ }
83
+ return oldField;
84
+ };
85
+ const convertNewTypeToOldType = (newType) => {
86
+ const { prefix, fields, ...props } = newType;
87
+ const oldType = {};
88
+ const meta = convertNewToOldMeta(props);
89
+ if (prefix) {
90
+ oldType.prefix = prefix;
91
+ }
92
+ if (meta) {
93
+ oldType.meta = meta;
94
+ }
95
+ if (fields) {
96
+ oldType.fields = {};
97
+ for (const key in fields) {
98
+ // @ts-ignore
99
+ oldType.fields[key] = convertNewFieldToOldField(fields[key]);
100
+ }
101
+ }
102
+ return oldType;
103
+ };
104
+ export const convertNewToOld = (newSchema) => {
105
+ const { root, types, language, translations, prefixToTypeMapping } = newSchema;
106
+ const oldSchema = {};
107
+ if (prefixToTypeMapping) {
108
+ oldSchema.prefixToTypeMapping = prefixToTypeMapping;
109
+ }
110
+ if (language) {
111
+ oldSchema.languages = [language];
112
+ }
113
+ if (translations) {
114
+ oldSchema.languages ??= [];
115
+ oldSchema.languages.push(...translations);
116
+ }
117
+ if (root) {
118
+ oldSchema.rootType = convertNewTypeToOldType(root);
119
+ }
120
+ if (types) {
121
+ oldSchema.types = {};
122
+ for (const key in types) {
123
+ oldSchema.types[key] = convertNewTypeToOldType(types[key]);
124
+ }
125
+ }
126
+ return oldSchema;
127
+ };
128
+ const convertOldFieldToNewField = (oldField) => {
129
+ // @ts-ignore
130
+ const { type, properties, values, items, meta = {} } = oldField;
131
+ const overwrite = oldToNewType[type] || oldToNewType[meta.format];
132
+ const newField = overwrite
133
+ ? {
134
+ ...overwrite,
135
+ ...convertOldToNewMeta(meta),
136
+ }
137
+ : {
138
+ type,
139
+ ...convertOldToNewMeta(meta),
140
+ };
141
+ if (properties) {
142
+ // @ts-ignore
143
+ newField.properties = {};
144
+ for (const key in properties) {
145
+ // @ts-ignore
146
+ newField.properties[key] = convertOldFieldToNewField(properties[key]);
147
+ }
148
+ }
149
+ if (values) {
150
+ // @ts-ignore
151
+ newField.values = convertOldFieldToNewField(values);
152
+ }
153
+ if (items) {
154
+ // @ts-ignore
155
+ newField.items = convertOldFieldToNewField(items);
156
+ }
157
+ return newField;
158
+ };
159
+ const convertOldTypeToNewType = (oldType) => {
160
+ const { prefix, fields, meta } = oldType;
161
+ const newType = {
162
+ fields: {},
163
+ };
164
+ if (prefix) {
165
+ newType.prefix = prefix;
166
+ }
167
+ if (meta) {
168
+ Object.assign(newType, convertOldToNewMeta(meta));
169
+ }
170
+ if (fields) {
171
+ for (const key in fields) {
172
+ newType.fields[key] = convertOldFieldToNewField(fields[key]);
173
+ }
174
+ }
175
+ return newType;
176
+ };
177
+ export const convertOldToNew = (oldSchema) => {
178
+ const { rootType, types, languages, prefixToTypeMapping } = oldSchema;
179
+ const newSchema = {};
180
+ if (prefixToTypeMapping) {
181
+ newSchema.prefixToTypeMapping = prefixToTypeMapping;
182
+ }
183
+ if (languages?.length) {
184
+ // @ts-ignore
185
+ newSchema.language = languages[0];
186
+ const translations = languages.slice(1);
187
+ if (translations.length) {
188
+ // @ts-ignore
189
+ newSchema.translations = translations;
190
+ }
191
+ }
192
+ if (rootType) {
193
+ newSchema.root = convertOldTypeToNewType(rootType);
194
+ }
195
+ if (types) {
196
+ newSchema.types = {};
197
+ for (const key in types) {
198
+ newSchema.types[key] = convertOldTypeToNewType(types[key]);
199
+ }
200
+ }
201
+ return newSchema;
202
+ };
3
203
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,3 @@
1
- // import { BasedSchema } from '../types.js'
2
- // import { BasedOldSchema } from './oldSchemaType.js'
3
1
  const metaChecker = (field) => {
4
2
  return (field === 'validation' ||
5
3
  // field === 'format' ||
@@ -35,9 +33,6 @@ const metaChecker = (field) => {
35
33
  field === '$delete' ||
36
34
  field === 'display');
37
35
  };
38
- const excludedFields = (field) => {
39
- return field === 'language' || field === 'translations' || field === '$defs';
40
- };
41
36
  const DEFAULT_FIELDS = {
42
37
  // id: { type: 'string' },
43
38
  // createdAt: { type: 'timestamp' },
@@ -180,9 +175,11 @@ const migrateTypes = (oldSchema) => {
180
175
  const type = oldSchema.types[key];
181
176
  result.types[key] = {
182
177
  ...metaParser(type),
183
- prefix: type.prefix,
184
178
  fields: migrateFields(type.fields),
185
179
  };
180
+ if (type.prefix) {
181
+ result.types[key].prefix = type.prefix;
182
+ }
186
183
  }
187
184
  }
188
185
  return result;
@@ -204,7 +201,9 @@ const convertRoot = (schema) => {
204
201
  };
205
202
  export const convertNewToOld = (schema) => {
206
203
  const tmpSchema = migrateTypes(schema);
207
- tmpSchema.prefixToTypeMapping = schema.prefixToTypeMapping;
204
+ if (schema.prefixToTypeMapping) {
205
+ tmpSchema.prefixToTypeMapping = schema.prefixToTypeMapping;
206
+ }
208
207
  tmpSchema.languages = [];
209
208
  if (schema.language) {
210
209
  tmpSchema.languages.push(schema.language);
@@ -1,5 +1,5 @@
1
1
  type FieldType = 'float' | 'boolean' | 'number' | 'int' | 'string' | 'text' | 'id' | 'digest' | 'url' | 'email' | 'phone' | 'geo' | 'type' | 'timestamp';
2
- type FieldSchemaObject = {
2
+ export type FieldSchemaObject = {
3
3
  type: 'object';
4
4
  properties: {
5
5
  [key: string]: FieldSchema;
@@ -34,13 +34,37 @@ type FieldSchemaOther = {
34
34
  meta?: any;
35
35
  timeseries?: boolean;
36
36
  };
37
- type FieldSchemaArrayLike = {
37
+ export type FieldSchemaArrayLike = {
38
38
  type: 'set' | 'array';
39
39
  items: FieldSchema;
40
40
  meta?: any;
41
41
  timeseries?: boolean;
42
42
  };
43
- type FieldSchema = FieldSchemaObject | FieldSchemaRecord | FieldSchemaArrayLike | FieldSchemaJson | FieldSchemaReferences | FieldSchemaOther;
43
+ export type FieldSchema = FieldSchemaObject | FieldSchemaRecord | FieldSchemaArrayLike | FieldSchemaJson | FieldSchemaReferences | FieldSchemaOther;
44
+ type FieldInputSchemaArrayLike = {
45
+ type: 'set' | 'array';
46
+ items: FieldInputSchema;
47
+ meta?: any;
48
+ timeseries?: boolean;
49
+ };
50
+ type FieldInputSchemaRecord = {
51
+ type: 'record';
52
+ values: FieldInputSchema;
53
+ meta?: any;
54
+ timeseries?: boolean;
55
+ };
56
+ export type FieldInputSchemaObject = {
57
+ type: 'object';
58
+ properties: {
59
+ [key: string]: FieldInputSchema;
60
+ };
61
+ meta?: any;
62
+ timeseries?: boolean;
63
+ };
64
+ type FieldInputSchema = FieldSchema | FieldInputSchemaArrayLike | FieldInputSchemaRecord | FieldInputSchemaObject | DeleteField;
65
+ type DeleteField = {
66
+ $delete: boolean;
67
+ };
44
68
  type Fields = Record<string, FieldSchema>;
45
69
  type HierarchySchema = false | {
46
70
  [key: string]: false | {
@@ -49,7 +73,7 @@ type HierarchySchema = false | {
49
73
  includeAncestryWith: string[];
50
74
  };
51
75
  };
52
- type TypeSchema = {
76
+ export type TypeSchema = {
53
77
  prefix?: string;
54
78
  hierarchy?: HierarchySchema;
55
79
  fields?: Fields;
@@ -20,13 +20,13 @@ const parseArray = async (args, value, idx = 0) => {
20
20
  const fromValue = Array.isArray(value) ? value : [value];
21
21
  const q = [];
22
22
  const arr = new Array(fromValue.length);
23
- const collectNested = ['object', 'record', 'text'].includes(args.fieldSchema.values.type);
23
+ const collectNested = ['object', 'record', 'text'].includes(args.fieldSchema.items.type);
24
24
  const collected = [];
25
25
  for (let i = 0; i < fromValue.length; i++) {
26
26
  q.push(args.parse({
27
27
  key: i + idx,
28
28
  value: fromValue[i],
29
- fieldSchema: args.fieldSchema.values,
29
+ fieldSchema: args.fieldSchema.items,
30
30
  collect: (nArgs) => {
31
31
  const p = nArgs.path.slice(args.path.length);
32
32
  // @ts-ignore
@@ -77,7 +77,7 @@ const operations = {
77
77
  await args.parse({
78
78
  key: value.$assign.$idx,
79
79
  value: value.$assign.$value,
80
- fieldSchema: args.fieldSchema.values,
80
+ fieldSchema: args.fieldSchema.items,
81
81
  });
82
82
  },
83
83
  };
@@ -95,7 +95,7 @@ export const array = async (args) => {
95
95
  q.push(args.parse({
96
96
  key: i,
97
97
  value: args.value[i],
98
- fieldSchema: args.fieldSchema.values,
98
+ fieldSchema: args.fieldSchema.items,
99
99
  }));
100
100
  }
101
101
  await Promise.all(q);
@@ -114,7 +114,7 @@ export type BasedSchemaFieldRecord = {
114
114
  } & BasedSchemaFieldShared;
115
115
  export type BasedSchemaFieldArray = {
116
116
  type: 'array';
117
- values: BasedSchemaField;
117
+ items: BasedSchemaField;
118
118
  } & BasedSchemaFieldShared;
119
119
  export type BasedSchemaFieldSet = {
120
120
  type: 'set';
@@ -321,7 +321,7 @@ export const basedSchemaFieldRecordValidator = {
321
321
  };
322
322
  export const basedSchemaFieldArrayValidator = {
323
323
  ...basedSchemaFieldSharedValidator,
324
- values: {
324
+ items: {
325
325
  validator: mustBeField,
326
326
  },
327
327
  };
@@ -8,13 +8,13 @@ const schema = {
8
8
  fields: {
9
9
  arrNum: {
10
10
  type: 'array',
11
- values: {
11
+ items: {
12
12
  type: 'number',
13
13
  },
14
14
  },
15
15
  objArray: {
16
16
  type: 'array',
17
- values: {
17
+ items: {
18
18
  type: 'object',
19
19
  properties: {
20
20
  snurp: {
@@ -25,13 +25,13 @@ const schema = {
25
25
  },
26
26
  arrStr: {
27
27
  type: 'array',
28
- values: {
28
+ items: {
29
29
  type: 'string',
30
30
  },
31
31
  },
32
32
  intarray: {
33
33
  type: 'array',
34
- values: {
34
+ items: {
35
35
  type: 'integer',
36
36
  },
37
37
  },
@@ -1,25 +1,49 @@
1
1
  import test from 'ava';
2
- // TODO: maybe nice to use for validate import { newSchemas } from './data/newSchemas.js'
3
2
  import { newSchemas } from './data/newSchemas.js';
4
3
  import { oldSchemas } from './data/oldSchemas.js';
5
4
  import { convertNewToOld, convertOldToNew, validateSchema, } from '../src/index.js';
5
+ const addStandardMetaToOld = (obj) => {
6
+ if (obj && typeof obj === 'object') {
7
+ if (obj.type === 'id') {
8
+ obj.meta ??= {};
9
+ obj.meta.format = 'basedId';
10
+ }
11
+ else if (obj.type === 'email') {
12
+ obj.meta ??= {};
13
+ obj.meta.format = 'email';
14
+ }
15
+ else if (obj.type === 'digest') {
16
+ obj.meta ??= {};
17
+ obj.meta.format = 'strongPassword';
18
+ }
19
+ else if (obj.type === 'url') {
20
+ obj.meta ??= {};
21
+ obj.meta.format = 'URL';
22
+ }
23
+ else if (obj.type === 'phone') {
24
+ obj.meta ??= {};
25
+ obj.meta.format = 'mobilePhone';
26
+ }
27
+ for (const i in obj) {
28
+ addStandardMetaToOld(obj[i]);
29
+ }
30
+ }
31
+ };
6
32
  test('old schema compat mode', async (t) => {
7
33
  for (let i = 0; i < oldSchemas.length - 1; i++) {
8
- // for (let i = 0; i < 1; i++) {
9
34
  const oldSchema = oldSchemas[i];
10
35
  const newSchema = convertOldToNew(oldSchema);
11
36
  const validation = await validateSchema(newSchema);
12
37
  t.true(validation.valid);
38
+ addStandardMetaToOld(oldSchema);
13
39
  t.deepEqual(oldSchema, convertNewToOld(newSchema), `Schema conversion oldSchemas index ${i}`);
14
40
  }
15
41
  });
16
- test.failing('new schema compat mode', async (t) => {
42
+ test('new schema compat mode', async (t) => {
17
43
  for (let i = 0; i < newSchemas.length - 1; i++) {
18
- // for (let i = 0; i < 1; i++) {
19
44
  const newSchema = newSchemas[i];
20
45
  const validation = await validateSchema(newSchema);
21
46
  const oldSchema = convertNewToOld(newSchema);
22
- console.dir(validation, { depth: null });
23
47
  t.true(validation.valid);
24
48
  t.deepEqual(newSchema, convertOldToNew(oldSchema), `Schema conversion newSchemas index ${i}`);
25
49
  }
@@ -251,9 +251,9 @@ export const newSchemas = [
251
251
  type: 'timestamp',
252
252
  readOnly: true,
253
253
  },
254
- enum: {
255
- enum: ['tony', 'jim'],
256
- },
254
+ // enum: {
255
+ // enum: ['tony', 'jim'],
256
+ // },
257
257
  setOfNumbers: {
258
258
  type: 'set',
259
259
  items: {
@@ -284,7 +284,7 @@ export const newSchemas = [
284
284
  properties: {
285
285
  bla: {
286
286
  type: 'array',
287
- values: {
287
+ items: {
288
288
  type: 'object',
289
289
  properties: {
290
290
  snux: {
@@ -309,7 +309,6 @@ export const newSchemas = [
309
309
  },
310
310
  },
311
311
  },
312
- $defs: {},
313
312
  language: 'en',
314
313
  translations: ['de', 'nl', 'ro', 'za', 'ae'],
315
314
  root: {
@@ -347,9 +346,7 @@ export const newSchemas = [
347
346
  },
348
347
  },
349
348
  },
350
- $defs: {},
351
349
  language: 'en',
352
- translations: [],
353
350
  root: {
354
351
  fields: {},
355
352
  },
@@ -361,7 +358,6 @@ export const newSchemas = [
361
358
  {
362
359
  language: 'en',
363
360
  translations: ['nl'],
364
- $defs: {},
365
361
  prefixToTypeMapping: {},
366
362
  root: {
367
363
  fields: {},
@@ -480,7 +476,7 @@ export const newSchemas = [
480
476
  bidirectional: { fromField: 'usedIn' },
481
477
  },
482
478
  hits: { type: 'number' }, // get a bit more going here maybe? what does this mean
483
- membership: { enum: ['Need membership', 'Free'] },
479
+ // membership: { enum: ['Need membership', 'Free'] },
484
480
  location: { type: 'text' }, // or string its just city name or smth
485
481
  bio: { type: 'text', format: 'json' }, //has a href and stuff so aarich text
486
482
  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.',
package/dist/test/rest.js CHANGED
@@ -46,7 +46,7 @@ const schema = {
46
46
  properties: {
47
47
  bla: {
48
48
  type: 'array',
49
- values: {
49
+ items: {
50
50
  type: 'object',
51
51
  properties: {
52
52
  snux: {
@@ -319,7 +319,7 @@ test('arrays', async (t) => {
319
319
  fields: {
320
320
  arrayField: {
321
321
  type: 'array',
322
- values: {
322
+ items: {
323
323
  type: 'string',
324
324
  },
325
325
  },
@@ -333,13 +333,13 @@ test('arrays', async (t) => {
333
333
  fields: {
334
334
  arrayField: {
335
335
  type: 'array',
336
- values: {
336
+ items: {
337
337
  type: 'object',
338
338
  properties: {
339
339
  aWrongObjectField: {
340
340
  type: 'object',
341
341
  // @ts-ignore
342
- values: { type: 'string' },
342
+ items: { type: 'string' },
343
343
  },
344
344
  },
345
345
  },
@@ -354,10 +354,10 @@ test('arrays', async (t) => {
354
354
  'root',
355
355
  'fields',
356
356
  'arrayField',
357
- 'values',
357
+ 'items',
358
358
  'properties',
359
359
  'aWrongObjectField',
360
- 'values',
360
+ 'items',
361
361
  ],
362
362
  },
363
363
  ],
@@ -45,7 +45,7 @@ const schema = {
45
45
  },
46
46
  intarray: {
47
47
  type: 'array',
48
- values: {
48
+ items: {
49
49
  type: 'integer',
50
50
  },
51
51
  },
@@ -82,7 +82,7 @@ const schema = {
82
82
  properties: {
83
83
  bla: {
84
84
  type: 'array',
85
- values: {
85
+ items: {
86
86
  type: 'object',
87
87
  properties: {
88
88
  snux: {