# Utils

&#x20;Utils是Packhouse內部的函數組，有許多功能都來自於Utils的建構，包括[Tool ID](/the-instance/utils.md#generateid)、[Mold Verify](/the-instance/utils.md#verify)等。

{% hint style="info" %}
所有的Utils是指向同一個對象，意味著你可以藉由Utils物件進行拓展，但我們不建議這麼做，良好的拓展方法請參照[Plugins](/the-instance/plugin.md)。
{% endhint %}

## How To Use

#### Core

```javascript
const Packhouse = require('packhouse')
const packhouse = new Packhouse()

packhosue.utils === Packhouse.utils // true
```

#### Tool

```javascript
const tool = {
    myTool: {
        install({ store, utils }) {
            store.id = utils.generateId()
            store.uuid = utils.generateId
        },
        handler(self) {
            console.log(self.store.id)
            console.log(self.store.uuid())
        }
    }
}
```

#### Mold

```javascript
const molds = {
    uuid(value, { utils }) {
        return utils.generateId()
    }
}
```

## Methods

#### **getType**

能比`typeof`獲取更多的型態，沒在下列名單內的揭回傳`typeof`的型態：

```javascript
packhouse.utils.getType([]) // array
packhouse.utils.getType(NaN) // NaN
packhouse.utils.getType(null) // empty
packhouse.utils.getType(undefined) // empty
packhouse.utils.getType(/test/) // regexp
packhouse.utils.getType(new Promise(() => {})) // promise
packhouse.utils.getType(Buffer.from('123')) // buffer
packhouse.utils.getType(new Error()) // error
```

#### **verify**

一個簡單的驗證方法，並回傳新的物件。

{% hint style="info" %}
`verify`與`mold`是分離的系統，無法使用`mold`表達示。
{% endhint %}

> `verify`驗證的`type`對象是多個型態，而支援的類型請參閱[getType](/the-instance/utils.md#gettype)。

```javascript
let options = {
    a: 5,
    b: []
}

let data = packhouse.utils.verify(options, {
    // [required, allow types, default value]
    a: [true, ['number']],
    b: [true, ['array']],
    c: [false, ['number'], 0]
})

console.log(data.a) // 5
console.log(data.c) // 0
```

#### **generateId**

仿`uuid`建立，回傳一個隨機`uuid`，但這並不是標準的`uuid`演算法。

```javascript
console.log(typeof packhouse.utils.generateId()) // string
```

但這不代表你無法使用[uuid](https://www.npmjs.com/package/uuid)演算法：

```javascript
let uuid = require('uuid/v4')
let packhouse = require('packhouse')

packhouse.utils.generateId = uuid
```

#### **peel**

針對物件深度取值，可以參考[可選鍊](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/%E5%8F%AF%E9%80%89%E9%93%BE)。

```javascript
let a = {
    b: {
        c: {
            d: 5
        }
    }
}
console.log(packhouse.utils.peel(a, 'b.c.d')) // 5
console.log(packhouse.utils.peel(a, 'b.c.e')) // undefined
```

#### loader

返回一個Promise，第一次執行後會執行程序，但後續的呼叫皆回傳第一次呼叫的結果。

`loader`的存在目的很簡單，在Tool Install的週期時，有時會存在需非同步請求才能獲得的資料，但該週期又不支援非同步運算，因此你可以藉由`loader`進行包裹來達成初步的Cache。

> 更進階的快取應用可以參照[Order](/plugins/order.md)。

```javascript
let loader = packhouse.utils.loader((resolve, reject) => {
    setTimeout(() => {
        resolve('hello')
    }, 1000)
})

loader().then(result => {
    // 等待一秒才執行
    console.log(result) // hello
    loader().then(result => {
        // 不需等待
        console.log(result) // hello
    })
})
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://packhouse-doc.metalsheep.com/the-instance/utils.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
