@based/schema 3.1.0 → 4.1.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 (41) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +3 -0
  3. package/dist/parse/assert.d.ts +7 -0
  4. package/dist/parse/assert.js +33 -0
  5. package/dist/parse/errors.d.ts +19 -0
  6. package/dist/parse/errors.js +19 -0
  7. package/dist/parse/index.d.ts +20 -0
  8. package/dist/parse/index.js +132 -0
  9. package/dist/parse/props.d.ts +7 -0
  10. package/dist/parse/props.js +290 -0
  11. package/dist/parse/utils.d.ts +3 -0
  12. package/dist/parse/utils.js +29 -0
  13. package/dist/parsePayload/index.d.ts +3 -0
  14. package/dist/parsePayload/index.js +2 -0
  15. package/dist/parseSchema/assert.d.ts +6 -0
  16. package/dist/parseSchema/assert.js +27 -0
  17. package/dist/parseSchema/errors.d.ts +19 -0
  18. package/dist/parseSchema/errors.js +19 -0
  19. package/dist/parseSchema/index.d.ts +20 -0
  20. package/dist/parseSchema/index.js +132 -0
  21. package/dist/parseSchema/props.d.ts +7 -0
  22. package/dist/parseSchema/props.js +256 -0
  23. package/dist/parseSchema/utils.d.ts +3 -0
  24. package/dist/parseSchema/utils.js +29 -0
  25. package/dist/src/compat/index.js +12 -4
  26. package/dist/src/set/fields/references.js +43 -30
  27. package/dist/src/types.d.ts +5 -13
  28. package/dist/src/types.js +14 -0
  29. package/dist/src/validateSchema/fieldValidators.js +4 -4
  30. package/dist/test/compat.js +26 -1
  31. package/dist/test/data/newSchemas.js +19 -21
  32. package/dist/test/reference.js +4 -2
  33. package/dist/test/walker.js +2 -2
  34. package/dist/types.d.ts +140 -0
  35. package/dist/types.js +5 -0
  36. package/package.json +14 -25
  37. package/README.md +0 -21
  38. package/dist/src/compat/newToOld.d.ts +0 -3
  39. package/dist/src/compat/newToOld.js +0 -76
  40. package/dist/src/compat/oldToNew.d.ts +0 -3
  41. package/dist/src/compat/oldToNew.js +0 -35
@@ -45,11 +45,36 @@ test('refTypes', async (t) => {
45
45
  },
46
46
  });
47
47
  // @ts-ignore
48
- t.is(newSchema.types.youzi.fields.image.allowedTypes[0], 'youzi');
48
+ t.is(newSchema.types.youzi.fields.image.allowedType, 'youzi');
49
49
  const oldSchema = convertNewToOld(newSchema);
50
50
  // @ts-ignore
51
51
  t.is(oldSchema.types.youzi.fields.image.meta.refTypes[0], 'youzi');
52
52
  });
53
+ test('bidirectional', async (t) => {
54
+ const newSchema = convertOldToNew({
55
+ types: {
56
+ youzi: {
57
+ fields: {
58
+ image: {
59
+ type: 'reference',
60
+ bidirectional: {
61
+ fromField: 'success',
62
+ },
63
+ meta: {
64
+ refTypes: ['youzi'],
65
+ },
66
+ },
67
+ },
68
+ },
69
+ },
70
+ });
71
+ console.log(newSchema.types.youzi.fields.image);
72
+ // @ts-ignore
73
+ t.is(newSchema.types.youzi.fields.image.bidirectional.fromField, 'success');
74
+ const oldSchema = convertNewToOld(newSchema);
75
+ // @ts-ignore
76
+ t.is(oldSchema.types.youzi.fields.image.bidirectional.fromField, 'success');
77
+ });
53
78
  test('old schema compat mode', async (t) => {
54
79
  for (let i = 0; i < oldSchemas.length - 1; i++) {
55
80
  const oldSchema = oldSchemas[i];
@@ -65,7 +65,7 @@ const testSchema = {
65
65
  },
66
66
  winner: {
67
67
  type: 'reference',
68
- allowedTypes: ['contestant'],
68
+ allowedType: 'contestant',
69
69
  },
70
70
  countries: {
71
71
  type: 'references',
@@ -87,7 +87,7 @@ const testSchema = {
87
87
  },
88
88
  image: {
89
89
  type: 'reference',
90
- allowedTypes: ['file'],
90
+ allowedType: 'file',
91
91
  },
92
92
  startTime: {
93
93
  type: 'timestamp',
@@ -99,11 +99,11 @@ const testSchema = {
99
99
  },
100
100
  producer: {
101
101
  type: 'reference',
102
- allowedTypes: ['broadcaster'],
102
+ allowedType: 'broadcaster',
103
103
  },
104
104
  distributors: {
105
105
  type: 'references',
106
- allowedTypes: ['broadcaster'],
106
+ allowedType: 'broadcaster',
107
107
  },
108
108
  },
109
109
  },
@@ -141,7 +141,7 @@ const testSchema = {
141
141
  },
142
142
  image: {
143
143
  type: 'reference',
144
- allowedTypes: ['file'],
144
+ allowedType: 'file',
145
145
  },
146
146
  content: {
147
147
  type: 'text',
@@ -162,7 +162,7 @@ const testSchema = {
162
162
  },
163
163
  image: {
164
164
  type: 'reference',
165
- allowedTypes: ['file'],
165
+ allowedType: 'file',
166
166
  },
167
167
  },
168
168
  },
@@ -368,7 +368,7 @@ export const newSchemas = [
368
368
  fields: {
369
369
  usedIn: {
370
370
  type: 'references',
371
- bidirectional: { fromField: 'img' },
371
+ inverseProperty: 'img',
372
372
  },
373
373
  caption: {
374
374
  // needs translation?
@@ -390,13 +390,13 @@ export const newSchemas = [
390
390
  seen: { type: 'timestamp' },
391
391
  charges: {
392
392
  type: 'references',
393
- bidirectional: { fromField: 'user' },
394
- allowedTypes: ['charge'],
393
+ inverseProperty: 'user',
394
+ allowedType: 'charge',
395
395
  },
396
396
  articles: {
397
397
  type: 'references',
398
- bidirectional: { fromField: 'contributors' },
399
- allowedTypes: ['article'],
398
+ inverseProperty: 'contributors',
399
+ allowedType: 'article',
400
400
  },
401
401
  },
402
402
  },
@@ -405,8 +405,8 @@ export const newSchemas = [
405
405
  // does this have a user?
406
406
  user: {
407
407
  type: 'reference',
408
- bidirectional: { fromField: 'charges' },
409
- allowedTypes: ['user'],
408
+ inverseProperty: 'charges',
409
+ allowedType: 'user',
410
410
  },
411
411
  token: { type: 'string' },
412
412
  description: { type: 'string' },
@@ -419,7 +419,7 @@ export const newSchemas = [
419
419
  title: { type: 'text' },
420
420
  children: {
421
421
  type: 'references',
422
- allowedTypes: ['article'],
422
+ allowedType: 'article',
423
423
  },
424
424
  },
425
425
  },
@@ -433,7 +433,7 @@ export const newSchemas = [
433
433
  // meta_keywords: { type: 'array', values: { type: 'string' } },
434
434
  children: {
435
435
  type: 'references',
436
- allowedTypes: ['article', 'category'],
436
+ allowedType: 'article' // FIXME Can't have both 'category'],
437
437
  },
438
438
  },
439
439
  },
@@ -444,10 +444,8 @@ export const newSchemas = [
444
444
  title: 'Writers',
445
445
  description: 'Writers or people involved with the article.',
446
446
  type: 'references',
447
- allowedTypes: ['user'],
448
- bidirectional: {
449
- fromField: 'articles',
450
- },
447
+ allowedType: 'user',
448
+ inverseProperty: 'articles',
451
449
  },
452
450
  contributorsText: {
453
451
  title: 'Contributors text',
@@ -472,8 +470,8 @@ export const newSchemas = [
472
470
  },
473
471
  img: {
474
472
  type: 'reference',
475
- allowedTypes: ['file'],
476
- bidirectional: { fromField: 'usedIn' },
473
+ allowedType: 'file',
474
+ inverseProperty: 'usedIn',
477
475
  },
478
476
  hits: { type: 'number' }, // get a bit more going here maybe? what does this mean
479
477
  // membership: { enum: ['Need membership', 'Free'] },
@@ -15,17 +15,19 @@ const schema = {
15
15
  fields: {
16
16
  ref: {
17
17
  type: 'reference',
18
+ allowedType: 'bla',
18
19
  },
19
20
  children: {
20
21
  type: 'references',
22
+ allowedType: 'bla',
21
23
  },
22
24
  referencesToThings: {
23
25
  type: 'references',
24
- allowedTypes: ['thing'],
26
+ allowedType: 'thing',
25
27
  },
26
28
  referenceToThing: {
27
29
  type: 'reference',
28
- allowedTypes: ['thing'],
30
+ allowedType: 'thing',
29
31
  },
30
32
  },
31
33
  },
@@ -14,11 +14,11 @@ const schema = {
14
14
  fields: {
15
15
  referencesToThings: {
16
16
  type: 'references',
17
- allowedTypes: ['thing'],
17
+ allowedType: 'thing',
18
18
  },
19
19
  referenceToThing: {
20
20
  type: 'reference',
21
- allowedTypes: ['thing'],
21
+ allowedType: 'thing',
22
22
  },
23
23
  enum: {
24
24
  enum: ['tony', 'jim'],
@@ -0,0 +1,140 @@
1
+ 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';
2
+ type QueryFn = Function;
3
+ type PropValues = {
4
+ type?: string;
5
+ default?: any;
6
+ };
7
+ type Prop<V extends PropValues> = {
8
+ required?: boolean;
9
+ label?: Record<string, string>;
10
+ description?: Record<string, string>;
11
+ path?: string;
12
+ query?: QueryFn;
13
+ } & V;
14
+ type EnumItem = string | number | boolean;
15
+ export type SchemaReferences = Prop<{
16
+ type?: 'references';
17
+ items: SchemaReference;
18
+ }>;
19
+ export type SchemaReferencesOneWay = Prop<{
20
+ type?: 'references';
21
+ items: SchemaReferenceOneWay;
22
+ }>;
23
+ export type SchemaText = Prop<{
24
+ type: 'text';
25
+ default?: Record<string, string>;
26
+ }>;
27
+ type NumberType = 'number' | 'int8' | 'uint8' | 'int16' | 'uint16' | 'int32' | 'uint32';
28
+ export type SchemaNumber = Prop<{
29
+ type: NumberType;
30
+ default?: number;
31
+ min?: number;
32
+ max?: number;
33
+ step?: number | 'any';
34
+ }>;
35
+ export type SchemaString = Prop<{
36
+ type: 'string';
37
+ default?: string;
38
+ maxBytes?: number;
39
+ max?: number;
40
+ min?: number;
41
+ }>;
42
+ export type SchemaBinary = Prop<{
43
+ type: 'binary';
44
+ default?: ArrayBuffer;
45
+ maxBytes?: number;
46
+ }>;
47
+ export type SchemaBoolean = Prop<{
48
+ type: 'boolean';
49
+ default?: boolean;
50
+ }>;
51
+ export type SchemaTimestamp = Prop<{
52
+ type: 'timestamp';
53
+ default?: number | Date;
54
+ on?: 'create' | 'update';
55
+ }>;
56
+ export type SchemaReferenceOneWay = Prop<{
57
+ type?: 'reference';
58
+ default?: string;
59
+ ref: string;
60
+ }>;
61
+ export type SchemaReference = Prop<{
62
+ type?: 'reference';
63
+ default?: string;
64
+ ref: string;
65
+ prop: string;
66
+ }> & Record<`$${string}`, SchemaPropOneWay>;
67
+ export type SchemaObject = Prop<{
68
+ type?: 'object';
69
+ props: SchemaProps;
70
+ }>;
71
+ export type SchemaObjectOneWay = Prop<{
72
+ type?: 'object';
73
+ props: SchemaPropsOneWay;
74
+ }>;
75
+ export type SchemaReferenceWithQuery = SchemaReferenceOneWay & {
76
+ query: QueryFn;
77
+ };
78
+ export type SchemaReferencesWithQuery = SchemaReferencesOneWay & {
79
+ query: QueryFn;
80
+ };
81
+ export type SchemaEnum = Prop<{
82
+ type?: 'enum';
83
+ default?: EnumItem;
84
+ enum: EnumItem[];
85
+ }>;
86
+ export type SchemaAlias = SchemaString & {
87
+ type: 'alias';
88
+ };
89
+ export type SchemaPropShorthand = 'timestamp' | 'boolean' | 'string' | 'alias' | 'text' | NumberType | EnumItem[];
90
+ type SetItems = SchemaPropShorthand | SchemaTimestamp | SchemaBoolean | SchemaNumber | SchemaString | SchemaEnum;
91
+ export type SchemaSet<ItemsType extends SetItems = SetItems> = Prop<{
92
+ type?: 'set';
93
+ default?: ItemsType extends {
94
+ default: any;
95
+ } ? ItemsType['default'][] : undefined;
96
+ items: ItemsType;
97
+ }>;
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;
101
+ export type SchemaAnyProp = SchemaPropOneWay | SchemaProp;
102
+ export type SchemaHook = string | Function;
103
+ export type SchemaProps = Record<string, SchemaProp>;
104
+ export type SchemaType = {
105
+ hooks?: {
106
+ create?: SchemaHook;
107
+ update?: SchemaHook;
108
+ delete?: SchemaHook;
109
+ };
110
+ id?: number;
111
+ props: SchemaProps;
112
+ };
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;
119
+ };
120
+ export type SchemaLocales = Record<string, {
121
+ required?: boolean;
122
+ fallback?: string[];
123
+ }>;
124
+ export type SchemaPropTypeMap = {
125
+ references: SchemaReferences;
126
+ timestamp: SchemaTimestamp;
127
+ reference: SchemaReference;
128
+ boolean: SchemaBoolean;
129
+ string: SchemaString;
130
+ object: SchemaObject;
131
+ alias: SchemaAlias;
132
+ enum: SchemaEnum;
133
+ text: SchemaText;
134
+ set: SchemaSet;
135
+ binary: SchemaBinary;
136
+ } & Record<NumberType, SchemaNumber>;
137
+ 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];
139
+ export {};
140
+ //# sourceMappingURL=types.d.ts.map
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ import { getPropType } from './parse/utils.js';
2
+ export const isPropType = (type, prop) => {
3
+ return getPropType(prop) === type;
4
+ };
5
+ //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,41 +1,30 @@
1
1
  {
2
2
  "name": "@based/schema",
3
- "version": "3.1.0",
3
+ "version": "4.1.0",
4
4
  "license": "MIT",
5
- "main": "dist/src/index.js",
5
+ "main": "dist/index.js",
6
6
  "files": [
7
7
  "dist",
8
8
  "README.md",
9
9
  "package.json",
10
- "!dist/**/*.js.map"
10
+ "!dist/**/*.map"
11
11
  ],
12
12
  "scripts": {
13
- "build": "npx tsc",
14
- "watch": "npx tsc --watch",
15
- "clean": "rimraf {.turbo,dist,node_modules}",
16
- "test": "ava --color --timeout 3m --verbose",
17
- "test-ci": "ava --color --concurrency 1 --timeout 3m"
13
+ "build": "tsc",
14
+ "watch": "tsc --watch",
15
+ "test": "tsc && tsc test/*.ts --noEmit && tsx --test test/*.ts"
18
16
  },
17
+ "prettier": "@saulx/prettier-config",
19
18
  "sideEffects": false,
20
19
  "type": "module",
21
- "dependencies": {
22
- "validator": "^13.9.0",
23
- "@saulx/hash": "^2.0.0",
24
- "@saulx/utils": "^3.5.0"
25
- },
26
- "ava": {
27
- "timeout": "2m",
28
- "files": [
29
- "./dist/test/*.js",
30
- "./dist/test/validateSchema/*.js"
31
- ]
32
- },
33
20
  "devDependencies": {
34
- "type-fest": "^3.12.0",
21
+ "@saulx/prettier-config": "2.0.0",
35
22
  "@saulx/tsconfig": "^1.1.0",
36
- "ts-node": "10.9.1",
37
- "typescript": "^5.1.6",
38
- "rimraf": "^3.0.2",
39
- "ava": "6.1.1"
23
+ "@types/node": "22.5.3",
24
+ "tsx": "^4.19.0",
25
+ "typescript": "^5.1.6"
26
+ },
27
+ "dependencies": {
28
+ "picocolors": "^1.1.0"
40
29
  }
41
30
  }
package/README.md DELETED
@@ -1,21 +0,0 @@
1
- # @based/functions
2
-
3
- To be used with based cloud functions, adds types and utilities.
4
-
5
- - Example based function
6
-
7
- ```typescript
8
- import { BasedFunction } from '@based/functions'
9
-
10
- const submitVote: BasedFunction<
11
- { target: number },
12
- 'ok' | 'not-ok'
13
- > = async (based, { target }) => {
14
- if (target > 10) {
15
- return 'ok'
16
- }
17
- return 'not-ok'
18
- }
19
-
20
- export default submitVote
21
- ```
@@ -1,3 +0,0 @@
1
- import { BasedSchema } from '../types.js';
2
- import { BasedOldSchema } from './oldSchemaType.js';
3
- export declare const convertNewToOld: (schema: BasedSchema) => Partial<BasedOldSchema>;
@@ -1,76 +0,0 @@
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
@@ -1,3 +0,0 @@
1
- import { BasedSchema } from '../types.js';
2
- import { BasedOldSchema } from './oldSchemaType.js';
3
- export declare const convertOldToNew: (oldSchema: BasedOldSchema) => BasedSchema;
@@ -1,35 +0,0 @@
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