@feathersjs/schema 0.0.1-alpha.4 → 5.0.0-pre.15

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/src/core.ts DELETED
@@ -1,133 +0,0 @@
1
- import Joi from '@hapi/joi';
2
-
3
- export const Type = Joi;
4
-
5
- export const typeMap = new WeakMap<any, any>();
6
- export const nameMap: { [key: string]: Schema } = {};
7
-
8
- export let id = 0;
9
-
10
- typeMap.set(String, Joi.string());
11
- typeMap.set(Number, Joi.number());
12
- typeMap.set(Boolean, Joi.boolean());
13
-
14
- export type SchemaTypes = Schema|string|Joi.AnySchema|typeof String|typeof Number|typeof Boolean;
15
- // tslint:disable-next-line:ban-types
16
- export type SchemaPropertyType = SchemaTypes|SchemaTypes[]|Function;
17
-
18
- export interface SchemaPropertyDefinition {
19
- type: SchemaPropertyType;
20
- [key: string]: any;
21
- }
22
-
23
- export interface SchemaMeta {
24
- name: string;
25
- [key: string]: any;
26
- }
27
-
28
- export interface SchemaProperties {
29
- [key: string]: SchemaPropertyDefinition;
30
- }
31
-
32
- export const validatorFromType = (type: Schema|SchemaPropertyType|(() => Joi.AnySchema)): Joi.AnySchema => {
33
- const value = typeMap.get(type) || type;
34
-
35
- if (Array.isArray(value) && value.length === 1) {
36
- const [ arrayValue ] = value;
37
-
38
- return Joi.array().items(validatorFromType(arrayValue));
39
- }
40
-
41
- const valueSchema = value instanceof Schema ? value : getSchema(value);
42
-
43
- if (valueSchema !== null) {
44
- return valueSchema.validator;
45
- }
46
-
47
- return value;
48
- };
49
-
50
- export function getValidator (properties: SchemaProperties) {
51
- const validators: Joi.SchemaMap = Object.keys(properties).reduce((current, key) => {
52
- const { type } = properties[key];
53
-
54
- return {
55
- ...current,
56
- [key]: validatorFromType(type)
57
- };
58
- }, {});
59
-
60
- return Joi.object(validators);
61
- }
62
-
63
- export class Schema {
64
- meta: SchemaMeta;
65
- properties: SchemaProperties;
66
- validator: Joi.ObjectSchema;
67
-
68
- constructor (schemaMeta: Partial<SchemaMeta>, schemaProperties: SchemaProperties) {
69
- this.properties = {};
70
- this.meta = {
71
- name: `schema-${++id}`
72
- };
73
-
74
- this.addMetadata(schemaMeta);
75
- this.addProperties(schemaProperties);
76
- }
77
-
78
- async validate (value: any, options?: Joi.AsyncValidationOptions) {
79
- return this.validator.validateAsync(value, options);
80
- }
81
-
82
- addProperties (schemaProperties: SchemaProperties) {
83
- this.properties = Object.assign(this.properties, schemaProperties);
84
- this.validator = getValidator(this.properties);
85
-
86
- return this;
87
- }
88
-
89
- addMetadata (schemaMeta: Partial<SchemaMeta>) {
90
- const oldName = this.meta.name;
91
-
92
- this.meta = Object.assign(this.meta, schemaMeta);
93
-
94
- delete nameMap[oldName];
95
- nameMap[this.meta.name] = this;
96
-
97
- return this;
98
- }
99
- }
100
-
101
- export function setSchema (schema: Schema, target: any) {
102
- typeMap.set(target !== null ? target : schema, schema);
103
-
104
- return schema;
105
- }
106
-
107
- export function getSchema (target: any): Schema|null {
108
- if (target instanceof Schema) {
109
- return target;
110
- }
111
-
112
- if (typeof target === 'string') {
113
- return nameMap[target] || null;
114
- }
115
-
116
- if (!target) {
117
- return null;
118
- }
119
-
120
- let p = target;
121
-
122
- do {
123
- const schema = typeMap.get(p);
124
-
125
- if (schema !== undefined) {
126
- return schema;
127
- }
128
-
129
- p = p.prototype;
130
- } while (!!p);
131
-
132
- return null;
133
- }
package/src/decorator.ts DELETED
@@ -1,40 +0,0 @@
1
- import 'reflect-metadata';
2
- import Joi, { AnySchema } from '@hapi/joi';
3
- import { getSchema, schema, SchemaPropertyDefinition, validatorFromType } from './index';
4
- import { SchemaMeta } from './core';
5
-
6
- export type TypeInitializer<T> = (type: T) => T;
7
-
8
- export function propertyDecorator<T extends AnySchema = Joi.AnySchema> (
9
- definition: Partial<SchemaPropertyDefinition>|TypeInitializer<T> = {},
10
- propDef: Partial<SchemaPropertyDefinition> = {}
11
- ) {
12
- return (target: any, propertyName: string) => {
13
- const type = Reflect.getMetadata('design:type', target, propertyName);
14
- const targetSchema = getSchema(target) || schema(target, {}, {});
15
-
16
- if (typeof definition === 'function') {
17
- targetSchema.addProperties({
18
- [propertyName]: {
19
- type: definition(validatorFromType(type) as T),
20
- ...propDef
21
- }
22
- });
23
- } else {
24
- targetSchema.addProperties({
25
- [propertyName]: {
26
- type,
27
- ...definition
28
- }
29
- });
30
- }
31
- };
32
- }
33
-
34
- export function schemaDecorator (definition: Partial<SchemaMeta>) {
35
- return (target: any) => {
36
- const targetSchema = getSchema(target) || schema(target, {}, {});
37
-
38
- targetSchema.addMetadata(definition);
39
- };
40
- }
package/src/resolve.ts DELETED
@@ -1,33 +0,0 @@
1
- import { getSchema } from './core';
2
-
3
- export async function resolve<T = any> (source: T, schemaTarget: any, context: any, path: any[] = []): Promise<T|T[]> {
4
- if (Array.isArray(source)) {
5
- return Promise.all(source.map((current: any) => resolve(current, schemaTarget, context, path)));
6
- }
7
-
8
- const isArray = Array.isArray(schemaTarget);
9
- const schema = getSchema(isArray ? schemaTarget[0] : schemaTarget);
10
- const { properties } = schema;
11
- const resolveKeys = Object.keys(properties).filter(key =>
12
- typeof properties[key].resolve === 'function' && !path.includes(properties[key])
13
- );
14
-
15
- if (resolveKeys.length) {
16
- const entities: any[] = await Promise.all(resolveKeys.map(async key => {
17
- const property = properties[key];
18
- const { resolve: resolver, type } = property;
19
- const entity = await resolver(source, context);
20
-
21
- return resolve(entity, type, context, path.concat(property));
22
- }));
23
-
24
- return resolveKeys.reduce((result, key, index) => {
25
- return {
26
- ...result,
27
- [key]: entities[index]
28
- };
29
- }, source);
30
- }
31
-
32
- return source;
33
- }