mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 13:53:09 +02:00
wip
This commit is contained in:
parent
789deecfe9
commit
2fee8fbba3
2 changed files with 64 additions and 147 deletions
|
@ -27,11 +27,11 @@ module.exports = (params, user, app) =>
|
||||||
new Promise(async (res, rej) =>
|
new Promise(async (res, rej) =>
|
||||||
{
|
{
|
||||||
// Get 'text' parameter
|
// Get 'text' parameter
|
||||||
const [text, textErr] = it(params.text).must.be.a.string().validate(isValidText).get();
|
const [text, textErr] = it(params.text).must.be.a.string().validate(isValidText).qed();
|
||||||
if (textErr) return rej('invalid text');
|
if (textErr) return rej('invalid text');
|
||||||
|
|
||||||
// Get 'media_ids' parameter
|
// Get 'media_ids' parameter
|
||||||
const [mediaIds, mediaIdsErr] = it(params.media_ids).must.be.an.array().unique().range(1, 4).get();
|
const [mediaIds, mediaIdsErr] = it(params.media_ids).must.be.an.array().unique().range(1, 4).qed();
|
||||||
if (mediaIdsErr) return rej('invalid media_ids');
|
if (mediaIdsErr) return rej('invalid media_ids');
|
||||||
|
|
||||||
let files = [];
|
let files = [];
|
||||||
|
@ -40,7 +40,7 @@ module.exports = (params, user, app) =>
|
||||||
// forEach だと途中でエラーなどがあっても return できないので
|
// forEach だと途中でエラーなどがあっても return できないので
|
||||||
// 敢えて for を使っています。
|
// 敢えて for を使っています。
|
||||||
for (let i = 0; i < mediaIds.length; i++) {
|
for (let i = 0; i < mediaIds.length; i++) {
|
||||||
const [mediaId, mediaIdErr] = it(mediaIds[i]).must.be.an.id().required().get();
|
const [mediaId, mediaIdErr] = it(mediaIds[i]).must.be.an.id().required().qed();
|
||||||
if (mediaIdErr) return rej('invalid media id');
|
if (mediaIdErr) return rej('invalid media id');
|
||||||
|
|
||||||
// Fetch file
|
// Fetch file
|
||||||
|
@ -63,7 +63,7 @@ module.exports = (params, user, app) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get 'repost_id' parameter
|
// Get 'repost_id' parameter
|
||||||
const [repostId, repostIdErr] = it(params.repost_id).must.be.an.id().get();
|
const [repostId, repostIdErr] = it(params.repost_id).must.be.an.id().qed();
|
||||||
if (repostIdErr) return rej('invalid repost_id');
|
if (repostIdErr) return rej('invalid repost_id');
|
||||||
|
|
||||||
let repost = null;
|
let repost = null;
|
||||||
|
|
203
src/api/it.ts
203
src/api/it.ts
|
@ -2,16 +2,16 @@ import * as mongo from 'mongodb';
|
||||||
import hasDuplicates from '../common/has-duplicates';
|
import hasDuplicates from '../common/has-duplicates';
|
||||||
|
|
||||||
type Validator<T> = (value: T) => boolean | Error;
|
type Validator<T> = (value: T) => boolean | Error;
|
||||||
type Modifier<T> = (value: T) => T;
|
|
||||||
|
|
||||||
interface Factory {
|
interface Factory {
|
||||||
get: () => [any, Error];
|
/**
|
||||||
|
* qedはQ.E.D.でもあり'QueryENd'の略でもある
|
||||||
|
*/
|
||||||
|
qed: () => [any, Error];
|
||||||
|
|
||||||
required: () => Factory;
|
required: () => Factory;
|
||||||
|
|
||||||
validate: (validator: Validator<any>) => Factory;
|
validate: (validator: Validator<any>) => Factory;
|
||||||
|
|
||||||
modify: (modifier: Modifier<any>) => Factory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FactoryCore implements Factory {
|
class FactoryCore implements Factory {
|
||||||
|
@ -36,7 +36,7 @@ class FactoryCore implements Factory {
|
||||||
/**
|
/**
|
||||||
* このインスタンスの値およびエラーを取得します
|
* このインスタンスの値およびエラーを取得します
|
||||||
*/
|
*/
|
||||||
get(): [any, Error] {
|
qed(): [any, Error] {
|
||||||
return [this.value, this.error];
|
return [this.value, this.error];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,16 +55,6 @@ class FactoryCore implements Factory {
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(modifier: Modifier<any>) {
|
|
||||||
if (this.error || this.value === null) return this;
|
|
||||||
try {
|
|
||||||
this.value = modifier(this.value);
|
|
||||||
} catch (e) {
|
|
||||||
this.error = e;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BooleanFactory extends FactoryCore {
|
class BooleanFactory extends FactoryCore {
|
||||||
|
@ -92,8 +82,8 @@ class BooleanFactory extends FactoryCore {
|
||||||
/**
|
/**
|
||||||
* このインスタンスの値およびエラーを取得します
|
* このインスタンスの値およびエラーを取得します
|
||||||
*/
|
*/
|
||||||
get(): [boolean, Error] {
|
qed(): [boolean, Error] {
|
||||||
return super.get();
|
return super.qed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,10 +94,6 @@ class BooleanFactory extends FactoryCore {
|
||||||
validate(validator: Validator<boolean>) {
|
validate(validator: Validator<boolean>) {
|
||||||
return super.validate(validator);
|
return super.validate(validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(modifier: Modifier<boolean>) {
|
|
||||||
return super.modify(modifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumberFactory extends FactoryCore {
|
class NumberFactory extends FactoryCore {
|
||||||
|
@ -148,8 +134,8 @@ class NumberFactory extends FactoryCore {
|
||||||
/**
|
/**
|
||||||
* このインスタンスの値およびエラーを取得します
|
* このインスタンスの値およびエラーを取得します
|
||||||
*/
|
*/
|
||||||
get(): [number, Error] {
|
qed(): [number, Error] {
|
||||||
return super.get();
|
return super.qed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,10 +146,6 @@ class NumberFactory extends FactoryCore {
|
||||||
validate(validator: Validator<number>) {
|
validate(validator: Validator<number>) {
|
||||||
return super.validate(validator);
|
return super.validate(validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(modifier: Modifier<number>) {
|
|
||||||
return super.modify(modifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringFactory extends FactoryCore {
|
class StringFactory extends FactoryCore {
|
||||||
|
@ -210,8 +192,8 @@ class StringFactory extends FactoryCore {
|
||||||
/**
|
/**
|
||||||
* このインスタンスの値およびエラーを取得します
|
* このインスタンスの値およびエラーを取得します
|
||||||
*/
|
*/
|
||||||
get(): [string, Error] {
|
qed(): [string, Error] {
|
||||||
return super.get();
|
return super.qed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -222,10 +204,6 @@ class StringFactory extends FactoryCore {
|
||||||
validate(validator: Validator<string>) {
|
validate(validator: Validator<string>) {
|
||||||
return super.validate(validator);
|
return super.validate(validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(modifier: Modifier<string>) {
|
|
||||||
return super.modify(modifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArrayFactory extends FactoryCore {
|
class ArrayFactory extends FactoryCore {
|
||||||
|
@ -277,8 +255,8 @@ class ArrayFactory extends FactoryCore {
|
||||||
/**
|
/**
|
||||||
* このインスタンスの値およびエラーを取得します
|
* このインスタンスの値およびエラーを取得します
|
||||||
*/
|
*/
|
||||||
get(): [any[], Error] {
|
qed(): [any[], Error] {
|
||||||
return super.get();
|
return super.qed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,10 +267,6 @@ class ArrayFactory extends FactoryCore {
|
||||||
validate(validator: Validator<any[]>) {
|
validate(validator: Validator<any[]>) {
|
||||||
return super.validate(validator);
|
return super.validate(validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(modifier: Modifier<any[]>) {
|
|
||||||
return super.modify(modifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class IdFactory extends FactoryCore {
|
class IdFactory extends FactoryCore {
|
||||||
|
@ -320,8 +294,8 @@ class IdFactory extends FactoryCore {
|
||||||
/**
|
/**
|
||||||
* このインスタンスの値およびエラーを取得します
|
* このインスタンスの値およびエラーを取得します
|
||||||
*/
|
*/
|
||||||
get(): [any[], Error] {
|
qed(): [any[], Error] {
|
||||||
return super.get();
|
return super.qed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -332,10 +306,6 @@ class IdFactory extends FactoryCore {
|
||||||
validate(validator: Validator<any[]>) {
|
validate(validator: Validator<any[]>) {
|
||||||
return super.validate(validator);
|
return super.validate(validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(modifier: Modifier<any[]>) {
|
|
||||||
return super.modify(modifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ObjectFactory extends FactoryCore {
|
class ObjectFactory extends FactoryCore {
|
||||||
|
@ -363,8 +333,8 @@ class ObjectFactory extends FactoryCore {
|
||||||
/**
|
/**
|
||||||
* このインスタンスの値およびエラーを取得します
|
* このインスタンスの値およびエラーを取得します
|
||||||
*/
|
*/
|
||||||
get(): [any, Error] {
|
qed(): [any, Error] {
|
||||||
return super.get();
|
return super.qed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -375,13 +345,9 @@ class ObjectFactory extends FactoryCore {
|
||||||
validate(validator: Validator<any>) {
|
validate(validator: Validator<any>) {
|
||||||
return super.validate(validator);
|
return super.validate(validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(modifier: Modifier<any>) {
|
|
||||||
return super.modify(modifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MustBe = {
|
type It = {
|
||||||
must: {
|
must: {
|
||||||
be: {
|
be: {
|
||||||
a: {
|
a: {
|
||||||
|
@ -396,9 +362,17 @@ type MustBe = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
expect: {
|
||||||
|
string: () => StringFactory;
|
||||||
|
number: () => NumberFactory;
|
||||||
|
boolean: () => BooleanFactory;
|
||||||
|
id: () => IdFactory;
|
||||||
|
array: () => ArrayFactory;
|
||||||
|
object: () => ObjectFactory;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mustBe = (value: any) => ({
|
const it = (value: any) => ({
|
||||||
must: {
|
must: {
|
||||||
be: {
|
be: {
|
||||||
a: {
|
a: {
|
||||||
|
@ -412,107 +386,50 @@ const mustBe = (value: any) => ({
|
||||||
object: () => new ObjectFactory(value)
|
object: () => new ObjectFactory(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
expect: {
|
||||||
|
string: () => new StringFactory(value),
|
||||||
|
number: () => new NumberFactory(value),
|
||||||
|
boolean: () => new BooleanFactory(value),
|
||||||
|
id: () => new IdFactory(value),
|
||||||
|
array: () => new ArrayFactory(value),
|
||||||
|
object: () => new ObjectFactory(value)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
type Type = 'id' | 'string' | 'number' | 'boolean' | 'array' | 'set' | 'object';
|
type Type = 'id' | 'string' | 'number' | 'boolean' | 'array' | 'set' | 'object';
|
||||||
type Pipe<T> = (x: T) => T | boolean | Error;
|
|
||||||
|
|
||||||
function validate(value: any, type: 'id', isRequired?: boolean, pipe?: Pipe<mongo.ObjectID> | Pipe<mongo.ObjectID>[]): [mongo.ObjectID, Error];
|
function x(value: any): It;
|
||||||
function validate(value: any, type: 'string', isRequired?: boolean, pipe?: Pipe<string> | Pipe<string>[]): [string, Error];
|
function x(value: any, type: 'id', isRequired?: boolean, validator?: Validator<mongo.ObjectID> | Validator<mongo.ObjectID>[]): [mongo.ObjectID, Error];
|
||||||
function validate(value: any, type: 'number', isRequired?: boolean, pipe?: Pipe<number> | Pipe<number>[]): [number, Error];
|
function x(value: any, type: 'string', isRequired?: boolean, validator?: Validator<string> | Validator<string>[]): [string, Error];
|
||||||
function validate(value: any, type: 'boolean', isRequired?: boolean): [boolean, Error];
|
function x(value: any, type: 'number', isRequired?: boolean, validator?: Validator<number> | Validator<number>[]): [number, Error];
|
||||||
function validate(value: any, type: 'array', isRequired?: boolean, pipe?: Pipe<any[]> | Pipe<any[]>[]): [any[], Error];
|
function x(value: any, type: 'boolean', isRequired?: boolean): [boolean, Error];
|
||||||
function validate(value: any, type: 'set', isRequired?: boolean, pipe?: Pipe<any[]> | Pipe<any[]>[]): [any[], Error];
|
function x(value: any, type: 'array', isRequired?: boolean, validator?: Validator<any[]> | Validator<any[]>[]): [any[], Error];
|
||||||
function validate(value: any, type: 'object', isRequired?: boolean, pipe?: Pipe<any> | Pipe<any>[]): [any, Error];
|
function x(value: any, type: 'set', isRequired?: boolean, validator?: Validator<any[]> | Validator<any[]>[]): [any[], Error];
|
||||||
function validate(value: any, type: Type, isRequired?: boolean, pipe?: Pipe<any> | Pipe<any>[]): [any, Error] {
|
function x(value: any, type: 'object', isRequired?: boolean, validator?: Validator<any> | Validator<any>[]): [any, Error];
|
||||||
if (value === undefined || value === null) {
|
function x(value: any, type?: Type, isRequired?: boolean, validator?: Validator<any> | Validator<any>[]): any {
|
||||||
if (isRequired) {
|
if (typeof type === 'undefined') return it(value);
|
||||||
return [null, new Error('is-required')]
|
|
||||||
} else {
|
let factory: Factory = null;
|
||||||
return [null, null]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'id':
|
case 'id': factory = it(value).expect.id(); break;
|
||||||
if (typeof value != 'string' || !mongo.ObjectID.isValid(value)) {
|
case 'string': factory = it(value).expect.string(); break;
|
||||||
return [null, new Error('incorrect-id')];
|
case 'number': factory = it(value).expect.number(); break;
|
||||||
}
|
case 'boolean': factory = it(value).expect.boolean(); break;
|
||||||
break;
|
case 'array': factory = it(value).expect.array(); break;
|
||||||
|
case 'set': factory = it(value).expect.array().unique(); break;
|
||||||
case 'string':
|
case 'object': factory = it(value).expect.object(); break;
|
||||||
if (typeof value != 'string') {
|
|
||||||
return [null, new Error('must-be-a-string')];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'number':
|
|
||||||
if (!Number.isFinite(value)) {
|
|
||||||
return [null, new Error('must-be-a-number')];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'boolean':
|
|
||||||
if (typeof value != 'boolean') {
|
|
||||||
return [null, new Error('must-be-a-boolean')];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'array':
|
|
||||||
if (!Array.isArray(value)) {
|
|
||||||
return [null, new Error('must-be-an-array')];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'set':
|
|
||||||
if (!Array.isArray(value)) {
|
|
||||||
return [null, new Error('must-be-an-array')];
|
|
||||||
} else if (hasDuplicates(value)) {
|
|
||||||
return [null, new Error('duplicated-contents')];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'object':
|
|
||||||
if (typeof value != 'object') {
|
|
||||||
return [null, new Error('must-be-an-object')];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == 'id') value = new mongo.ObjectID(value);
|
if (isRequired) factory = factory.required();
|
||||||
|
|
||||||
if (pipe) {
|
if (validator) {
|
||||||
const pipes = Array.isArray(pipe) ? pipe : [pipe];
|
(Array.isArray(validator) ? validator : [validator])
|
||||||
for (let i = 0; i < pipes.length; i++) {
|
.forEach(v => factory = factory.validate(v));
|
||||||
const result = pipes[i](value);
|
|
||||||
if (result === false) {
|
|
||||||
return [null, new Error('invalid-format')];
|
|
||||||
} else if (result instanceof Error) {
|
|
||||||
return [null, result];
|
|
||||||
} else if (result !== true) {
|
|
||||||
value = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [value, null];
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
function it(value: any): MustBe;
|
export default x;
|
||||||
function it(value: any, type: 'id', isRequired?: boolean, pipe?: Pipe<mongo.ObjectID> | Pipe<mongo.ObjectID>[]): [mongo.ObjectID, Error];
|
|
||||||
function it(value: any, type: 'string', isRequired?: boolean, pipe?: Pipe<string> | Pipe<string>[]): [string, Error];
|
|
||||||
function it(value: any, type: 'number', isRequired?: boolean, pipe?: Pipe<number> | Pipe<number>[]): [number, Error];
|
|
||||||
function it(value: any, type: 'boolean', isRequired?: boolean): [boolean, Error];
|
|
||||||
function it(value: any, type: 'array', isRequired?: boolean, pipe?: Pipe<any[]> | Pipe<any[]>[]): [any[], Error];
|
|
||||||
function it(value: any, type: 'set', isRequired?: boolean, pipe?: Pipe<any[]> | Pipe<any[]>[]): [any[], Error];
|
|
||||||
function it(value: any, type: 'object', isRequired?: boolean, pipe?: Pipe<any> | Pipe<any>[]): [any, Error];
|
|
||||||
function it(value: any, type?: any, isRequired?: boolean, pipe?: Pipe<any> | Pipe<any>[]): any {
|
|
||||||
if (typeof type === 'undefined') {
|
|
||||||
return mustBe(value);
|
|
||||||
} else {
|
|
||||||
return validate(value, type, isRequired, pipe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default it;
|
|
||||||
|
|
Loading…
Reference in a new issue