Mold

Packhouse Mold

TypeScript

Mold的出現主要是因為JavaScript沒有Interface、Type等Struct的功能,這在運行過程時容易遇到非預期的錯誤。

TypeScript是一個解決方案,以下是使用時呈現的方式:

// Basic function
function sum(v1: number, v2: number): number {
    return v1 + v2
}

// Interface based
interface Person {
    firstName: string
    lastName: string
}

function greeter(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName
}

TypeScript的限制在編譯後就失去了功能,意味著今天在與客戶端交流時仍難以避免資料型態的意外。

How To Use

Mold不能被外部所引用,最直接的使用方法是宣告在Tool的Request內。

const tools = {
    demo: {
        request: ['string', 'number'],
        handler: self => self.success()
    }
}

在執行時能便會附加檢查功能:

packhouse.tool('group/demo').action('123', '456', error => {
    console.log(error.message) // Parameter 1 not a number(456).
})

Expression

Mold可以藉由|符號加入參數,協助開發者應付特殊狀況。

const tools = {
    demo: {
        request: ['number|min:50'],
        handler: self => self.success()
    }
}

Casting

能夠使用self.castingHandler中做轉換。

const tools = {
    demo: {
        handler(self, value) {
            try {
                let newValue = self.casting('number|min:50', value)
                self.success(newValue)
            } catch(e) {
                self.error(e)
            }
        }
    }
}

Null

在Request中宣告null可以忽略驗證欄位。

const tools = {
    demo: {
        request: [null, 'number'],
        handler: self => self.success()
    }
}

Optional

在名稱後加入?符號可以使該參數為nullundefined的時候忽略驗證。

const tools = {
    demo: {
        request: ['number?|min:50'],
        handler: self => self.success()
    }
}

Custom Define Mold

Mold可以同時具有檢查與轉換的功能,呈現的方式如下:

Mold不允許非同步運算。

const molds = {
    int(value) {
        if (typeof value === 'number') {
            return Math.floor(value)
        } else {
            throw new Error('Value not a number.')
        }
    }
}

第二個參數為context,能夠做更進階的應用:

const molds = {
    int(value, { index, utils, extras }) {
        if (extras.positive === true && value >= 0) {
            throw new Error(`Params ${index} must positive.`)
        }
        if (extras.min && Number(extras.min) > value) {
            throw new Error(`Params ${index} less than ${extras.min}.`)
        }
        if (typeof value === 'number') {
            return Math.floor(value)
        } else {
            throw new Error(`Params ${index} not a number.`)
        }
    }
}

const tool = {
    demo: {
        request: ['int|min:50|positive'],
        handler: (self, value) => self.success(value)
    }
}

Verify Expression

基於utils.verify的格式,有更好的結構表達與文件生產。

const molds = {
    person: {
        firstName: [true, ['string']],
        lastName: [true, ['string']]
    }
}

const tools = {
    demo: {
        request: ['person'],
        handler: (self, person) => self.success()
    }
}

let person: {
    firstName: 'green',
    lastName: null
}

// ... 省略註冊行為

packhouse.tool('group/demo').action(person, error => {
    // Parameter 0 verification error, Key(lastName) is required.
    console.log(error)
})

Core Molds

不是每個Mold都要重新定義,系統本身提供了許多常用的型態:

type

使用utils.getType作驗證。

  • { string } is - 目標type,一定需要該參數

['type|is:string']

number

參數必須為數字。

  • min - 數字必須高於指定數字

  • max - 數字必須低於指定數字

  • int - 數字轉換成整數

['number|min:0|max:50|int']

boolean

參數必須為truefalse

string

參數必須為字串。

  • is - 指定字串內容,可以用,分割多個對象。

['string|is: red, green, blue']

array

參數必須為陣列。

buffer

參數必須為Buffer

object

參數必須為Object

function

參數必須為Function

date

參數必須為new Date支援的時間格式。

required

參數為必填。

如果你這樣寫required?,會無效。

Create Self Core Mold

開發人員可以自定義系統Mold,這樣就能夠在所有場合使用自定義Mold。

我們不建議個別自定義系統Mold,若有需要請參考Merger章節來管理Mold。

當系統Mold與Group Mold有相同名稱時,Group Mold優先。

let packhouse = new Packhouse()
packhouse.addMold('int', value => parseInt(value))

const tools = {
    demo: {
        request: ['int'],
        handler: self => self.success()
    }
}

Last updated