@based/schema 4.1.0 → 5.0.0-alpha.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 (123) hide show
  1. package/README.md +152 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +2 -0
  4. package/dist/lang.d.ts +152 -0
  5. package/dist/lang.js +149 -0
  6. package/dist/mermaid.d.ts +3 -0
  7. package/dist/mermaid.js +24 -0
  8. package/dist/parse/assert.d.ts +1 -1
  9. package/dist/parse/assert.js +2 -2
  10. package/dist/parse/errors.d.ts +2 -0
  11. package/dist/parse/errors.js +2 -0
  12. package/dist/parse/index.d.ts +5 -4
  13. package/dist/parse/index.js +43 -41
  14. package/dist/parse/props.js +160 -68
  15. package/dist/parse/utils.d.ts +2 -2
  16. package/dist/parse/utils.js +11 -2
  17. package/dist/types.d.ts +66 -23
  18. package/dist/types.js +93 -0
  19. package/package.json +4 -3
  20. package/dist/parsePayload/index.d.ts +0 -3
  21. package/dist/parsePayload/index.js +0 -2
  22. package/dist/parseSchema/assert.d.ts +0 -6
  23. package/dist/parseSchema/assert.js +0 -27
  24. package/dist/parseSchema/errors.d.ts +0 -19
  25. package/dist/parseSchema/errors.js +0 -19
  26. package/dist/parseSchema/index.d.ts +0 -20
  27. package/dist/parseSchema/index.js +0 -132
  28. package/dist/parseSchema/props.d.ts +0 -7
  29. package/dist/parseSchema/props.js +0 -256
  30. package/dist/parseSchema/utils.d.ts +0 -3
  31. package/dist/parseSchema/utils.js +0 -29
  32. package/dist/src/compat/index.d.ts +0 -6
  33. package/dist/src/compat/index.js +0 -217
  34. package/dist/src/compat/oldSchemaType.d.ts +0 -93
  35. package/dist/src/compat/oldSchemaType.js +0 -2
  36. package/dist/src/display/index.d.ts +0 -2
  37. package/dist/src/display/index.js +0 -16
  38. package/dist/src/display/number.d.ts +0 -4
  39. package/dist/src/display/number.js +0 -97
  40. package/dist/src/display/string.d.ts +0 -5
  41. package/dist/src/display/string.js +0 -26
  42. package/dist/src/display/timestamp.d.ts +0 -5
  43. package/dist/src/display/timestamp.js +0 -134
  44. package/dist/src/error.d.ts +0 -21
  45. package/dist/src/error.js +0 -23
  46. package/dist/src/index.d.ts +0 -6
  47. package/dist/src/index.js +0 -7
  48. package/dist/src/languages.d.ts +0 -188
  49. package/dist/src/languages.js +0 -188
  50. package/dist/src/set/fields/array.d.ts +0 -2
  51. package/dist/src/set/fields/array.js +0 -119
  52. package/dist/src/set/fields/index.d.ts +0 -3
  53. package/dist/src/set/fields/index.js +0 -85
  54. package/dist/src/set/fields/number.d.ts +0 -4
  55. package/dist/src/set/fields/number.js +0 -123
  56. package/dist/src/set/fields/object.d.ts +0 -3
  57. package/dist/src/set/fields/object.js +0 -28
  58. package/dist/src/set/fields/references.d.ts +0 -3
  59. package/dist/src/set/fields/references.js +0 -136
  60. package/dist/src/set/fields/set.d.ts +0 -2
  61. package/dist/src/set/fields/set.js +0 -59
  62. package/dist/src/set/fields/string.d.ts +0 -3
  63. package/dist/src/set/fields/string.js +0 -289
  64. package/dist/src/set/index.d.ts +0 -3
  65. package/dist/src/set/index.js +0 -205
  66. package/dist/src/set/isValidId.d.ts +0 -2
  67. package/dist/src/set/isValidId.js +0 -17
  68. package/dist/src/types.d.ts +0 -205
  69. package/dist/src/types.js +0 -113
  70. package/dist/src/updateSchema.d.ts +0 -2
  71. package/dist/src/updateSchema.js +0 -12
  72. package/dist/src/validateSchema/basedSchemaTypeValidator.d.ts +0 -3
  73. package/dist/src/validateSchema/basedSchemaTypeValidator.js +0 -45
  74. package/dist/src/validateSchema/fieldValidators.d.ts +0 -27
  75. package/dist/src/validateSchema/fieldValidators.js +0 -360
  76. package/dist/src/validateSchema/index.d.ts +0 -17
  77. package/dist/src/validateSchema/index.js +0 -109
  78. package/dist/src/validateSchema/utils.d.ts +0 -25
  79. package/dist/src/validateSchema/utils.js +0 -61
  80. package/dist/src/walker/args.d.ts +0 -36
  81. package/dist/src/walker/args.js +0 -158
  82. package/dist/src/walker/index.d.ts +0 -6
  83. package/dist/src/walker/index.js +0 -31
  84. package/dist/src/walker/parse.d.ts +0 -3
  85. package/dist/src/walker/parse.js +0 -182
  86. package/dist/src/walker/types.d.ts +0 -45
  87. package/dist/src/walker/types.js +0 -7
  88. package/dist/test/array.d.ts +0 -1
  89. package/dist/test/array.js +0 -342
  90. package/dist/test/compat.d.ts +0 -1
  91. package/dist/test/compat.js +0 -97
  92. package/dist/test/data/newSchemas.d.ts +0 -2
  93. package/dist/test/data/newSchemas.js +0 -489
  94. package/dist/test/data/oldSchemas.d.ts +0 -2
  95. package/dist/test/data/oldSchemas.js +0 -5058
  96. package/dist/test/display.d.ts +0 -1
  97. package/dist/test/display.js +0 -103
  98. package/dist/test/json.d.ts +0 -1
  99. package/dist/test/json.js +0 -40
  100. package/dist/test/number.d.ts +0 -1
  101. package/dist/test/number.js +0 -374
  102. package/dist/test/reference.d.ts +0 -1
  103. package/dist/test/reference.js +0 -188
  104. package/dist/test/rest.d.ts +0 -1
  105. package/dist/test/rest.js +0 -168
  106. package/dist/test/set.d.ts +0 -1
  107. package/dist/test/set.js +0 -95
  108. package/dist/test/string.d.ts +0 -1
  109. package/dist/test/string.js +0 -120
  110. package/dist/test/text.d.ts +0 -1
  111. package/dist/test/text.js +0 -324
  112. package/dist/test/utils/index.d.ts +0 -11
  113. package/dist/test/utils/index.js +0 -17
  114. package/dist/test/validateSchema/basic.d.ts +0 -1
  115. package/dist/test/validateSchema/basic.js +0 -94
  116. package/dist/test/validateSchema/fields.d.ts +0 -1
  117. package/dist/test/validateSchema/fields.js +0 -436
  118. package/dist/test/validateSchema/languages.d.ts +0 -1
  119. package/dist/test/validateSchema/languages.js +0 -124
  120. package/dist/test/validateSchema/realWorld.d.ts +0 -1
  121. package/dist/test/validateSchema/realWorld.js +0 -13
  122. package/dist/test/walker.d.ts +0 -1
  123. package/dist/test/walker.js +0 -289
@@ -1,4 +1,4 @@
1
- import { INVALID_VALUE, UNKNOWN_PROP } from './errors.js';
1
+ import { INVALID_KEY, INVALID_VALUE, UNKNOWN_PROP } from './errors.js';
2
2
  import { getPropType } from './utils.js';
3
3
  import propParsers from './props.js';
4
4
  import pc from 'picocolors';
@@ -8,33 +8,55 @@ export class SchemaParser {
8
8
  constructor(schema) {
9
9
  this.schema = schema;
10
10
  }
11
+ isItems;
11
12
  inQuery;
12
13
  schema;
13
14
  type;
14
- parseType(type) {
15
- expectObject(type);
16
- this.parseProps(type.props, type);
17
- }
15
+ path = [];
16
+ lvl = 0;
18
17
  parseTypes() {
18
+ this.path[this.lvl++] = 'types';
19
19
  const { types } = this.schema;
20
20
  expectObject(types);
21
21
  for (const type in types) {
22
- this.parseType(types[type]);
22
+ this.lvl++;
23
+ if (type[0] === '_') {
24
+ throw new Error(INVALID_KEY);
25
+ }
26
+ this.path[this.lvl] = type;
27
+ expectObject(types[type]);
28
+ if (!('props' in types[type])) {
29
+ types[type] = { props: types[type] };
30
+ }
31
+ this.lvl--;
32
+ }
33
+ for (const type in types) {
34
+ this.path[this.lvl++] = type;
35
+ this.parseProps(types[type].props, types[type]);
36
+ this.lvl--;
23
37
  }
38
+ this.lvl--;
24
39
  }
25
40
  parseProps(props, schemaType = null) {
41
+ this.path[this.lvl++] = 'props';
26
42
  expectObject(props);
27
43
  this.type = schemaType;
28
44
  for (const key in props) {
45
+ if (key[0] === '_') {
46
+ throw new Error(INVALID_KEY);
47
+ }
29
48
  const prop = props[key];
30
- const type = getPropType(prop);
49
+ const type = getPropType(prop, props, key);
50
+ this.path[this.lvl++] = key;
31
51
  if (type in propParsers) {
32
52
  propParsers[type](prop, this);
33
53
  }
34
54
  else {
35
55
  throw Error(INVALID_VALUE);
36
56
  }
57
+ this.lvl--;
37
58
  }
59
+ this.lvl--;
38
60
  }
39
61
  parseLocales() {
40
62
  const { locales } = this.schema;
@@ -60,17 +82,18 @@ export class SchemaParser {
60
82
  }
61
83
  parse() {
62
84
  expectObject(this.schema);
85
+ // always do types first because it removes props shorthand
86
+ if ('types' in this.schema) {
87
+ this.parseTypes();
88
+ }
63
89
  for (const key in this.schema) {
64
- if (key === 'types') {
65
- this.parseTypes();
66
- }
67
- else if (key === 'props') {
90
+ if (key === 'props') {
68
91
  this.parseProps(this.schema.props);
69
92
  }
70
93
  else if (key === 'locales') {
71
94
  this.parseLocales();
72
95
  }
73
- else {
96
+ else if (key !== 'types') {
74
97
  throw Error(UNKNOWN_PROP);
75
98
  }
76
99
  }
@@ -83,7 +106,7 @@ export const print = (schema, path) => {
83
106
  const v = obj[key];
84
107
  const padding = ' '.repeat(lvl);
85
108
  const prefix = key === Object.keys(obj)[0] ? '' : `${padding}...\n`;
86
- if (lvl === depth) {
109
+ if (lvl === depth && lvl !== 0) {
87
110
  const err = key in obj
88
111
  ? `${key}: ${typeof v === 'object' && v !== null && !Array.isArray(v) ? `{..}` : JSON.stringify(v)}`
89
112
  : key;
@@ -94,39 +117,18 @@ export const print = (schema, path) => {
94
117
  });
95
118
  return lines.join('\n');
96
119
  };
97
- export const debug = (schema) => {
98
- let curr;
99
- const proxy = (obj, path = []) => {
100
- const copy = {};
101
- return new Proxy(obj, {
102
- get(_, key) {
103
- const v = obj[key];
104
- curr = [...path, key];
105
- if (typeof v !== 'object' || v === null) {
106
- return v;
107
- }
108
- copy[key] ??= proxy(obj[key], curr);
109
- return copy[key];
110
- },
111
- });
112
- };
113
- const parser = new SchemaParser(proxy(schema));
114
- try {
115
- parser.parse();
116
- }
117
- catch (e) {
118
- e.message += '\n\n' + print(schema, curr) + '\n';
119
- e.cause = curr;
120
- throw e;
121
- }
122
- };
123
120
  export const parse = (schema) => {
121
+ const parser = new SchemaParser(schema);
124
122
  try {
125
- new SchemaParser(schema).parse();
123
+ parser.parse();
124
+ // @ts-ignore
126
125
  return { schema };
127
126
  }
128
127
  catch (e) {
129
- debug(schema);
128
+ const cause = parser.path.slice(0, Math.min(4, parser.lvl) + 1);
129
+ e.message += '\n\n' + print(schema, cause) + '\n';
130
+ e.cause = cause;
131
+ throw e;
130
132
  }
131
133
  };
132
134
  //# sourceMappingURL=index.js.map
@@ -1,10 +1,20 @@
1
+ import { stringFormats, dateDisplays, numberDisplays, } from '../types.js';
1
2
  import { expectBoolean, expectFunction, expectObject, expectString, expectNumber, } from './assert.js';
2
- import { EXPECTED_ARR, EXPECTED_DATE, EXPECTED_OBJ, EXPECTED_PRIMITIVE, EXPECTED_VALUE_IN_ENUM, INVALID_VALUE, MIN_MAX, OUT_OF_RANGE, TEXT_REQUIRES_LOCALES, TYPE_MISMATCH, UNKNOWN_PROP, } from './errors.js';
3
+ import { EXPECTED_ARR, EXPECTED_DATE, EXPECTED_OBJ, EXPECTED_PRIMITIVE, EXPECTED_VALUE_IN_ENUM, INVALID_VALUE, MIN_MAX, MISSING_TYPE, OUT_OF_RANGE, TEXT_REQUIRES_LOCALES, TYPE_MISMATCH, UNKNOWN_PROP, NOT_ALLOWED_IN_ITEMS, } from './errors.js';
3
4
  import { getPropType } from './utils.js';
5
+ let stringFormatsSet;
6
+ let numberDisplaysSet;
7
+ let dateDisplaysSet;
4
8
  const STUB = {};
5
9
  const shared = {
6
10
  type() { },
7
- required(val) {
11
+ role(val) {
12
+ expectString(val);
13
+ },
14
+ required(val, _prop, ctx) {
15
+ if (ctx.isItems) {
16
+ throw new Error(NOT_ALLOWED_IN_ITEMS);
17
+ }
8
18
  expectBoolean(val);
9
19
  },
10
20
  query(val) {
@@ -28,6 +38,10 @@ const shared = {
28
38
  throw Error(TYPE_MISMATCH);
29
39
  }
30
40
  },
41
+ title(val) { },
42
+ description(val) { },
43
+ readOnly(val) { },
44
+ examples(val) { },
31
45
  };
32
46
  function propParser(required, optional, allowShorthand) {
33
47
  return (prop, ctx) => {
@@ -46,15 +60,21 @@ function propParser(required, optional, allowShorthand) {
46
60
  throw Error(EXPECTED_OBJ);
47
61
  }
48
62
  for (const key in required) {
49
- required[key](prop[key], prop, ctx);
63
+ ctx.path[ctx.lvl] = key;
64
+ const changed = required[key](prop[key], prop, ctx);
65
+ if (changed !== undefined) {
66
+ prop[key] = changed;
67
+ }
50
68
  }
51
69
  for (const key in prop) {
70
+ ctx.path[ctx.lvl] = key;
52
71
  const val = prop[key];
72
+ let changed;
53
73
  if (key in optional) {
54
- optional[key](val, prop, ctx);
74
+ changed = optional[key](val, prop, ctx);
55
75
  }
56
76
  else if (key in shared) {
57
- shared[key](val, prop, ctx);
77
+ changed = shared[key](val, prop, ctx);
58
78
  }
59
79
  else if (!(key in required)) {
60
80
  if (key[0] === '$' && 'ref' in prop) {
@@ -64,15 +84,13 @@ function propParser(required, optional, allowShorthand) {
64
84
  throw Error(UNKNOWN_PROP);
65
85
  }
66
86
  }
87
+ if (changed !== undefined) {
88
+ prop[key] = changed;
89
+ }
67
90
  }
68
91
  };
69
92
  }
70
93
  const p = {};
71
- p.alias = propParser(STUB, {
72
- default(val) {
73
- expectString(val);
74
- },
75
- }, 0);
76
94
  p.boolean = propParser(STUB, {
77
95
  default(val) {
78
96
  expectBoolean(val);
@@ -100,6 +118,11 @@ p.enum = propParser({
100
118
  },
101
119
  }, 1);
102
120
  const numberOpts = {
121
+ display(val) {
122
+ expectString(val);
123
+ numberDisplaysSet ??= new Set(numberDisplays);
124
+ numberDisplaysSet.has(val);
125
+ },
103
126
  min(val) {
104
127
  expectNumber(val);
105
128
  },
@@ -144,63 +167,6 @@ p.object = propParser({
144
167
  console.warn('TODO object default value');
145
168
  },
146
169
  });
147
- p.reference = propParser({
148
- ref(ref, _prop, { schema }) {
149
- schema.types[ref].props;
150
- },
151
- prop(propKey, prop, { schema, type, inQuery }) {
152
- const propAllowed = type && !inQuery;
153
- if (propAllowed) {
154
- expectString(propKey);
155
- const propPath = propKey.split('.');
156
- let targetProp = schema.types[prop.ref];
157
- for (const key of propPath) {
158
- targetProp = targetProp.props[key];
159
- }
160
- if ('items' in targetProp) {
161
- targetProp = targetProp.items;
162
- }
163
- if ('ref' in targetProp && 'prop' in targetProp) {
164
- const inversePath = targetProp.prop.split('.');
165
- let inverseProp = schema.types[targetProp.ref];
166
- for (const key of inversePath) {
167
- inverseProp = inverseProp.props[key];
168
- }
169
- if ('items' in inverseProp) {
170
- inverseProp = inverseProp.items;
171
- }
172
- if (inverseProp === prop) {
173
- return;
174
- }
175
- }
176
- throw Error(INVALID_VALUE);
177
- }
178
- if (propKey !== undefined) {
179
- throw Error('ref prop not supported on root or edge p');
180
- }
181
- },
182
- }, {
183
- default(val) {
184
- expectString(val);
185
- },
186
- edge(val, prop, ctx, key) {
187
- const edgeAllowed = ctx.type && !ctx.inQuery;
188
- if (edgeAllowed) {
189
- let t = ctx.schema.types[prop.ref].props[prop.prop];
190
- t = t.items || t;
191
- if (t[key]) {
192
- throw Error('Edge can not be defined on both props');
193
- }
194
- const edgePropType = getPropType(val);
195
- const inType = ctx.type;
196
- ctx.type = null;
197
- p[edgePropType](val, ctx);
198
- ctx.type = inType;
199
- return;
200
- }
201
- throw Error('ref edge not supported on root or edge p');
202
- },
203
- });
204
170
  p.set = propParser({
205
171
  items(items, prop, ctx) {
206
172
  expectObject(items);
@@ -210,8 +176,10 @@ p.set = propParser({
210
176
  itemsType === 'timestamp' ||
211
177
  itemsType === 'boolean') {
212
178
  ctx.inQuery = 'query' in prop;
179
+ ctx.isItems = true;
213
180
  p[itemsType](items, ctx);
214
181
  ctx.inQuery = false;
182
+ ctx.isItems = false;
215
183
  }
216
184
  else {
217
185
  throw new Error(INVALID_VALUE);
@@ -231,8 +199,10 @@ p.references = propParser({
231
199
  const itemsType = getPropType(items);
232
200
  if (itemsType === 'reference') {
233
201
  ctx.inQuery = 'query' in prop;
202
+ ctx.isItems = true;
234
203
  p[itemsType](items, ctx);
235
204
  ctx.inQuery = false;
205
+ ctx.isItems = false;
236
206
  }
237
207
  else {
238
208
  throw new Error(INVALID_VALUE);
@@ -246,13 +216,34 @@ p.references = propParser({
246
216
  // }
247
217
  },
248
218
  });
249
- p.string = propParser(STUB, {
219
+ const binaryOpts = {
250
220
  default(val) {
251
221
  expectString(val);
252
222
  },
223
+ format(val) {
224
+ expectString(val);
225
+ stringFormatsSet ??= new Set(stringFormats);
226
+ stringFormatsSet.has(val);
227
+ },
228
+ mime(val) {
229
+ if (Array.isArray(val)) {
230
+ val.forEach(expectString);
231
+ }
232
+ else {
233
+ expectString(val);
234
+ }
235
+ },
253
236
  maxBytes(val) {
254
237
  expectNumber(val);
255
238
  },
239
+ compression(val) {
240
+ // return the actualy string!
241
+ return val;
242
+ },
243
+ };
244
+ p.binary = propParser(STUB, binaryOpts, 0);
245
+ p.string = propParser(STUB, {
246
+ ...binaryOpts,
256
247
  min(val) {
257
248
  expectNumber(val);
258
249
  },
@@ -275,6 +266,11 @@ p.text = propParser({
275
266
  },
276
267
  }, 0);
277
268
  p.timestamp = propParser(STUB, {
269
+ display(val) {
270
+ expectString(val);
271
+ dateDisplaysSet ??= new Set(dateDisplays);
272
+ dateDisplaysSet.has(val);
273
+ },
278
274
  default(val) {
279
275
  if (typeof val !== 'number' && !(val instanceof Date)) {
280
276
  throw Error(EXPECTED_DATE);
@@ -286,5 +282,101 @@ p.timestamp = propParser(STUB, {
286
282
  }
287
283
  },
288
284
  }, 0);
285
+ p.reference = propParser({
286
+ ref(ref, _prop, { schema }) {
287
+ if (!schema.types[ref]?.props) {
288
+ throw Error(MISSING_TYPE);
289
+ }
290
+ },
291
+ prop(propKey, prop, { schema, type, inQuery, path }) {
292
+ const propAllowed = type && !inQuery;
293
+ if (propAllowed) {
294
+ expectString(propKey);
295
+ const propPath = propKey.split('.');
296
+ let targetProp = schema.types[prop.ref];
297
+ expectObject(targetProp, 'expected type');
298
+ let create;
299
+ for (const key of propPath) {
300
+ if (!targetProp.props[key]) {
301
+ create = true;
302
+ targetProp.props[key] = {};
303
+ }
304
+ targetProp = targetProp.props[key];
305
+ }
306
+ if (create) {
307
+ const ref = path[1];
308
+ let prop = '';
309
+ for (let i = 3; i < path.length - 1; i += 2) {
310
+ prop += prop ? `.${path[i]}` : path[i];
311
+ }
312
+ targetProp.readOnly = true;
313
+ targetProp.items = {
314
+ ref,
315
+ prop,
316
+ };
317
+ }
318
+ if ('items' in targetProp) {
319
+ targetProp = targetProp.items;
320
+ }
321
+ if ('ref' in targetProp && 'prop' in targetProp) {
322
+ const inversePath = targetProp.prop.split('.');
323
+ let inverseProp = schema.types[targetProp.ref];
324
+ for (const key of inversePath) {
325
+ inverseProp = inverseProp.props[key];
326
+ }
327
+ if (inverseProp && 'items' in inverseProp) {
328
+ inverseProp = inverseProp.items;
329
+ }
330
+ if (prop === inverseProp) {
331
+ return;
332
+ }
333
+ }
334
+ throw Error('expected inverse property');
335
+ }
336
+ if (propKey !== undefined) {
337
+ throw Error('ref prop not supported on root or edge p');
338
+ }
339
+ },
340
+ }, {
341
+ mime: binaryOpts.mime,
342
+ default(val) {
343
+ expectString(val);
344
+ },
345
+ edge(val, prop, ctx, key) {
346
+ const edgeAllowed = ctx.type && !ctx.inQuery;
347
+ if (edgeAllowed) {
348
+ let t = ctx.schema.types[prop.ref].props[prop.prop];
349
+ t = t.items || t;
350
+ if (t[key] && t !== prop) {
351
+ throw Error('Edge can not be defined on both props');
352
+ }
353
+ const edgePropType = getPropType(val);
354
+ const inType = ctx.type;
355
+ ctx.type = null;
356
+ p[edgePropType](val, ctx);
357
+ ctx.type = inType;
358
+ return;
359
+ }
360
+ throw Error('ref edge not supported on root or edge property');
361
+ },
362
+ dependent(val, prop, ctx, key) {
363
+ expectBoolean(val);
364
+ const dependentAllowed = ctx.type && !ctx.inQuery;
365
+ if (!dependentAllowed) {
366
+ throw Error('ref dependency not supported on root or edge property');
367
+ }
368
+ },
369
+ });
370
+ p.alias = propParser(STUB, {
371
+ default(val) {
372
+ expectString(val);
373
+ },
374
+ format: binaryOpts.format,
375
+ }, 0);
376
+ p.hll = propParser(STUB, {
377
+ default(val) {
378
+ expectNumber(val);
379
+ },
380
+ }, 0);
289
381
  export default p;
290
382
  //# sourceMappingURL=props.js.map
@@ -1,3 +1,3 @@
1
- import { SchemaAnyProp, SchemaPropTypes } from '../types.js';
2
- export declare const getPropType: (prop: SchemaAnyProp) => SchemaPropTypes;
1
+ import { SchemaAnyProp, SchemaProps, SchemaPropTypes } from '../types.js';
2
+ export declare const getPropType: (prop: SchemaAnyProp, props?: SchemaProps, key?: string) => SchemaPropTypes;
3
3
  //# sourceMappingURL=utils.d.ts.map
@@ -1,6 +1,9 @@
1
1
  import { INVALID_TYPE, MISSING_TYPE } from './errors.js';
2
- export const getPropType = (prop) => {
2
+ export const getPropType = (prop, props, key) => {
3
3
  if (typeof prop === 'string') {
4
+ if (props) {
5
+ props[key] = { type: prop };
6
+ }
4
7
  return prop;
5
8
  }
6
9
  if ('type' in prop) {
@@ -21,7 +24,13 @@ export const getPropType = (prop) => {
21
24
  if ('props' in prop) {
22
25
  return 'object';
23
26
  }
24
- if ('enum' in prop || Array.isArray(prop)) {
27
+ if ('enum' in prop) {
28
+ return 'enum';
29
+ }
30
+ if (Array.isArray(prop)) {
31
+ if (props) {
32
+ props[key] = { enum: prop };
33
+ }
25
34
  return 'enum';
26
35
  }
27
36
  throw Error(MISSING_TYPE);
package/dist/types.d.ts CHANGED
@@ -1,4 +1,15 @@
1
+ import { LangName } from './lang.js';
2
+ type Role = 'title' | 'source' | 'media' | string;
3
+ export declare const numberDisplays: readonly ["short", "human", "ratio", "bytes", "euro", "dollar", "pound", "meter"];
4
+ export declare const dateDisplays: readonly ["date", "date-time", "date-time-text", "date-time-human", "time", "time-precise"];
5
+ export declare const stringFormats: readonly ["alpha", "alphaLocales", "alphanumeric", "alphanumericLocales", "ascii", "base32", "base58", "base64", "BIC", "btcAddress", "clike", "code", "creditCard", "css", "currency", "dataURI", "EAN", "email", "ethereumAddress", "FQDN", "hexadecimal", "hexColor", "HSL", "html", "IBAN", "identityCard", "IMEI", "IP", "IPRange", "ISBN", "ISIN", "ISO31661Alpha2", "ISO31661Alpha3", "ISO4217", "ISO6391", "ISO8601", "ISRC", "ISSN", "javascript", "json", "JWT", "latLong", "licensePlate", "lowercase", "luhnNumber", "MACAddress", "magnetURI", "markdown", "MD5", "mimeType", "mobilePhone", "mobilePhoneLocales", "octal", "passportNumber", "port", "postalCode", "postalCodeLocales", "python", "RFC3339", "rgbColor", "rust", "semVer", "slug", "strongPassword", "surrogatePair", "taxID", "typescript", "uppercase", "URL", "UUID", "VAT", "multiline"];
6
+ type DateDisplay = (typeof dateDisplays)[number];
7
+ type NumberDisplay = (typeof numberDisplays)[number] | `round-${number}`;
8
+ type StringFormat = (typeof stringFormats)[number];
9
+ type MimeString = 'text/html' | 'text/plain' | 'text/markdown' | 'image/png' | 'image/jpeg' | 'video/mp4' | 'video/quicktime' | 'image/*' | 'video/*' | 'audio/*' | '*/*' | `${string}/${string}`;
10
+ type Mime = MimeString | MimeString[];
1
11
  type Letter = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
12
+ type AllowedKey = `${Letter}${string}`;
2
13
  type QueryFn = Function;
3
14
  type PropValues = {
4
15
  type?: string;
@@ -6,19 +17,25 @@ type PropValues = {
6
17
  };
7
18
  type Prop<V extends PropValues> = {
8
19
  required?: boolean;
9
- label?: Record<string, string>;
10
- description?: Record<string, string>;
20
+ title?: string | Record<string, string>;
21
+ description?: string | Record<string, string>;
11
22
  path?: string;
12
23
  query?: QueryFn;
24
+ role?: Role;
25
+ readOnly?: boolean;
26
+ examples?: string[];
13
27
  } & V;
14
28
  type EnumItem = string | number | boolean;
29
+ type NeverInItems = {
30
+ required?: never;
31
+ };
15
32
  export type SchemaReferences = Prop<{
16
33
  type?: 'references';
17
- items: SchemaReference;
34
+ items: SchemaReference & NeverInItems;
18
35
  }>;
19
36
  export type SchemaReferencesOneWay = Prop<{
20
37
  type?: 'references';
21
- items: SchemaReferenceOneWay;
38
+ items: SchemaReferenceOneWay & NeverInItems;
22
39
  }>;
23
40
  export type SchemaText = Prop<{
24
41
  type: 'text';
@@ -31,6 +48,7 @@ export type SchemaNumber = Prop<{
31
48
  min?: number;
32
49
  max?: number;
33
50
  step?: number | 'any';
51
+ display?: NumberDisplay;
34
52
  }>;
35
53
  export type SchemaString = Prop<{
36
54
  type: 'string';
@@ -38,31 +56,44 @@ export type SchemaString = Prop<{
38
56
  maxBytes?: number;
39
57
  max?: number;
40
58
  min?: number;
59
+ mime?: Mime;
60
+ format?: StringFormat;
61
+ compression?: 'none' | 'deflate';
41
62
  }>;
42
63
  export type SchemaBinary = Prop<{
43
64
  type: 'binary';
44
65
  default?: ArrayBuffer;
45
66
  maxBytes?: number;
67
+ mime?: Mime;
68
+ format?: StringFormat;
46
69
  }>;
47
70
  export type SchemaBoolean = Prop<{
48
71
  type: 'boolean';
49
72
  default?: boolean;
50
73
  }>;
74
+ export type SchemaHll = Prop<{
75
+ type: 'hll';
76
+ default?: number;
77
+ }>;
51
78
  export type SchemaTimestamp = Prop<{
52
79
  type: 'timestamp';
53
80
  default?: number | Date;
54
81
  on?: 'create' | 'update';
82
+ display?: DateDisplay;
55
83
  }>;
56
84
  export type SchemaReferenceOneWay = Prop<{
57
85
  type?: 'reference';
58
86
  default?: string;
59
87
  ref: string;
88
+ mime?: Mime;
60
89
  }>;
61
90
  export type SchemaReference = Prop<{
62
91
  type?: 'reference';
63
92
  default?: string;
64
93
  ref: string;
65
94
  prop: string;
95
+ dependent?: boolean;
96
+ mime?: Mime;
66
97
  }> & Record<`$${string}`, SchemaPropOneWay>;
67
98
  export type SchemaObject = Prop<{
68
99
  type?: 'object';
@@ -83,43 +114,54 @@ export type SchemaEnum = Prop<{
83
114
  default?: EnumItem;
84
115
  enum: EnumItem[];
85
116
  }>;
86
- export type SchemaAlias = SchemaString & {
117
+ export type SchemaAlias = Omit<SchemaString, 'type'> & {
87
118
  type: 'alias';
88
119
  };
89
- export type SchemaPropShorthand = 'timestamp' | 'boolean' | 'string' | 'alias' | 'text' | NumberType | EnumItem[];
90
- type SetItems = SchemaPropShorthand | SchemaTimestamp | SchemaBoolean | SchemaNumber | SchemaString | SchemaEnum;
120
+ export type SchemaPropShorthand = 'timestamp' | 'binary' | 'boolean' | 'string' | 'alias' | 'text' | 'hll' | NumberType | EnumItem[];
121
+ type SetItems<isStrict = false> = SchemaTimestamp | SchemaBoolean | SchemaNumber | SchemaString | SchemaEnum | (isStrict extends true ? never : 'timestamp' | 'binary' | 'boolean' | 'string' | NumberType | EnumItem[]);
91
122
  export type SchemaSet<ItemsType extends SetItems = SetItems> = Prop<{
92
123
  type?: 'set';
93
124
  default?: ItemsType extends {
94
125
  default: any;
95
126
  } ? ItemsType['default'][] : undefined;
96
- items: ItemsType;
127
+ items: ItemsType & NeverInItems;
97
128
  }>;
98
- type NonRefSchemaProps = SchemaPropShorthand | SchemaTimestamp | SchemaBoolean | SchemaNumber | SchemaString | SchemaAlias | SchemaText | SchemaEnum | SchemaSet;
99
- export type SchemaProp = SchemaReferencesWithQuery | SchemaReferenceWithQuery | NonRefSchemaProps | SchemaReferences | SchemaReference | SchemaObject | SchemaBinary;
100
- export type SchemaPropOneWay = SchemaReferencesOneWay | SchemaReferenceOneWay | SchemaObjectOneWay | NonRefSchemaProps;
129
+ type NonRefSchemaProps<isStrict = false> = SchemaTimestamp | SchemaBoolean | SchemaNumber | SchemaString | SchemaAlias | SchemaText | SchemaEnum | SchemaBinary | SchemaHll | (isStrict extends true ? SchemaSet<SetItems<true>> : SchemaPropShorthand | SchemaSet);
130
+ export type SchemaProp<isStrict = false> = SchemaReferencesWithQuery | SchemaReferenceWithQuery | NonRefSchemaProps<isStrict> | SchemaReferences | SchemaReference | SchemaObject | SchemaBinary;
131
+ export type SchemaPropOneWay<isStrict = false> = SchemaReferencesOneWay | SchemaReferenceOneWay | SchemaObjectOneWay | NonRefSchemaProps<isStrict>;
101
132
  export type SchemaAnyProp = SchemaPropOneWay | SchemaProp;
102
133
  export type SchemaHook = string | Function;
103
- export type SchemaProps = Record<string, SchemaProp>;
104
- export type SchemaType = {
134
+ export type SchemaProps<isStrict = false> = Record<AllowedKey, SchemaProp<isStrict>> & {
135
+ id?: never;
136
+ };
137
+ type GenericSchemaType<isStrict = false> = {
105
138
  hooks?: {
106
139
  create?: SchemaHook;
107
140
  update?: SchemaHook;
108
141
  delete?: SchemaHook;
109
142
  };
110
143
  id?: number;
111
- props: SchemaProps;
144
+ props: SchemaProps<isStrict>;
145
+ };
146
+ export type StrictSchemaType = GenericSchemaType<true>;
147
+ export type SchemaType<isStrict = false> = isStrict extends true ? StrictSchemaType : StrictSchemaType | GenericSchemaType<false> | (SchemaProps & {
148
+ props?: never;
149
+ });
150
+ export type SchemaTypeName = AllowedKey;
151
+ export type SchemaTypes<isStrict = false> = Record<SchemaTypeName, SchemaType<isStrict>>;
152
+ export type SchemaPropsOneWay<isStrict = false> = Record<AllowedKey, SchemaPropOneWay<isStrict>> & {
153
+ id?: never;
112
154
  };
113
- export type SchemaTypes = Record<string, SchemaType>;
114
- export type SchemaPropsOneWay = Record<`${Letter}${string}`, SchemaPropOneWay>;
115
- export type Schema = {
116
- types?: SchemaTypes;
117
- props?: SchemaPropsOneWay;
118
- locales?: SchemaLocales;
155
+ type GenericSchema<isStrict = false> = {
156
+ types?: SchemaTypes<isStrict>;
157
+ props?: SchemaPropsOneWay<isStrict>;
158
+ locales?: Partial<SchemaLocales>;
119
159
  };
120
- export type SchemaLocales = Record<string, {
160
+ export type StrictSchema = GenericSchema<true>;
161
+ export type Schema = GenericSchema<false> | StrictSchema;
162
+ export type SchemaLocales = Record<LangName, {
121
163
  required?: boolean;
122
- fallback?: string[];
164
+ fallback?: LangName[];
123
165
  }>;
124
166
  export type SchemaPropTypeMap = {
125
167
  references: SchemaReferences;
@@ -133,8 +175,9 @@ export type SchemaPropTypeMap = {
133
175
  text: SchemaText;
134
176
  set: SchemaSet;
135
177
  binary: SchemaBinary;
178
+ hll: SchemaHll;
136
179
  } & Record<NumberType, SchemaNumber>;
137
180
  export type SchemaPropTypes = keyof SchemaPropTypeMap;
138
- export declare const isPropType: <T extends "string" | "boolean" | "object" | "references" | "timestamp" | "alias" | "text" | NumberType | "binary" | "reference" | "enum" | "set">(type: T, prop: SchemaProp) => prop is SchemaPropTypeMap[T];
181
+ export declare const isPropType: <T extends SchemaPropTypes>(type: T, prop: SchemaProp) => prop is SchemaPropTypeMap[T];
139
182
  export {};
140
183
  //# sourceMappingURL=types.d.ts.map