0dfdba396d74ccf88acc93ae3939f2e5b2518b814ac9a0f88ccdb1d8b97c5ed509e8e84aeb268d1ac960661f4ae3de24265110f0e6feb5049697a0f42b421d-exec 1.9 KB

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