‘liusuyi’
2023-10-21 94023628bd9c5e6bf724c37371a19b60d338b291
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
'use strict';
 
const Hoek = require('@hapi/hoek');
 
const Any = require('../any');
 
 
const internals = {};
 
 
internals.Lazy = class extends Any {
 
    constructor() {
 
        super();
        this._type = 'lazy';
        this._flags.once = true;
        this._cache = null;
    }
 
    _init(fn, options) {
 
        return this.set(fn, options);
    }
 
    _base(value, state, options) {
 
        let schema;
        if (this._cache) {
            schema = this._cache;
        }
        else {
            const result = { value };
            const lazy = this._flags.lazy;
 
            if (!lazy) {
                result.errors = this.createError('lazy.base', null, state, options);
                return result;
            }
 
            schema = lazy();
 
            if (!(schema instanceof Any)) {
                result.errors = this.createError('lazy.schema', { schema }, state, options);
                return result;
            }
 
            if (this._flags.once) {
                this._cache = schema;
            }
        }
 
        return schema._validate(value, state, options);
    }
 
    set(fn, options) {
 
        Hoek.assert(typeof fn === 'function', 'You must provide a function as first argument');
        Hoek.assert(options === undefined || (options && typeof options === 'object' && !Array.isArray(options)), `Options must be an object`);
 
        if (options) {
            const unknownOptions = Object.keys(options).filter((key) => !['once'].includes(key));
            Hoek.assert(unknownOptions.length === 0, `Options contain unknown keys: ${unknownOptions}`);
            Hoek.assert(options.once === undefined || typeof options.once === 'boolean', 'Option "once" must be a boolean');
        }
 
        const obj = this.clone();
        obj._flags.lazy = fn;
 
        if (options && options.once !== obj._flags.once) {
            obj._flags.once = options.once;
        }
 
        return obj;
    }
 
};
 
module.exports = new internals.Lazy();