{"id":24493058,"url":"https://github.com/open-node/func-delegate","last_synced_at":"2025-04-14T01:40:38.139Z","repository":{"id":57242882,"uuid":"65444663","full_name":"open-node/func-delegate","owner":"open-node","description":null,"archived":false,"fork":false,"pushed_at":"2020-07-21T12:34:51.000Z","size":16,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T15:52:14.958Z","etag":null,"topics":["argument-checks","argument-parser","argument-schemas","functional-programming"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/open-node.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-11T06:32:01.000Z","updated_at":"2020-01-21T10:51:18.000Z","dependencies_parsed_at":"2022-09-15T00:50:40.918Z","dependency_job_id":null,"html_url":"https://github.com/open-node/func-delegate","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-node%2Ffunc-delegate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-node%2Ffunc-delegate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-node%2Ffunc-delegate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-node%2Ffunc-delegate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/open-node","download_url":"https://codeload.github.com/open-node/func-delegate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248761380,"owners_count":21157547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argument-checks","argument-parser","argument-schemas","functional-programming"],"created_at":"2025-01-21T19:19:00.625Z","updated_at":"2025-04-14T01:40:38.118Z","avatar_url":"https://github.com/open-node.png","language":"JavaScript","readme":"# func-deleglate\n\nFunction arguments validate and call chainning\n\n[![Build status](https://api.travis-ci.org/open-node/func-delegate.svg?branch=master)](https://travis-ci.org/open-node/func-delegate)\n[![codecov](https://codecov.io/gh/open-node/func-delegate/branch/master/graph/badge.svg)](https://codecov.io/gh/open-node/func-delegate)\n\n## Usage\n```bash\nnpm install func-delegate --save\n```\n\n```js\ndescribe(\"func-delegate\", function() {\n  describe(\"#normal-only-type\", function() {\n    var add = function(a, b) { return a + b; };\n    add = delegate(add, [{\n      name: 'num1',\n      type: Number\n    }, {\n      name: 'num2',\n      type: Number\n    }]);\n    it(\"Type assert\", function(done) {\n      assert.ok(add instanceof Function, '处理后的仍然是一个函数');\n      assert.ok(add.num1 instanceof Function, '接收参数的函数 num1');\n      assert.ok(add.num2 instanceof Function, '接收参数的函数 num2');\n      done();\n    });\n\n    it(\"exec assert\", function(done) {\n      assert.equal(3, add(1, 2), '正常执行');\n      assert.equal(3, add.num1(1).num2(2).exec(), '链式调用');\n      done();\n    });\n\n    it(\"Exception assert\", function(done) {\n      assert.throws(function() {\n        add(1, '2');\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `num2` type must be `Number`';\n      }, 'Num2 is string');\n\n      assert.throws(function() {\n        add.num2('2').num1(1).exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `num2` type must be `Number`';\n      }, '链式调用 num2 is string')\n\n      assert.throws(function() {\n        add.num1(1).num2('2').exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `num2` type must be `Number`';\n      }, '链式调用 num2 是 string, 顺序无关')\n      done();\n    });\n  });\n\n  describe(\"#validate allowNull\", function() {\n    var add = function(a, b, sqrt) {\n      var sum = a + b;\n      if (sqrt === true) {\n        return Math.sqrt(sum);\n      } else {\n        return sum;\n      }\n    };\n    add = delegate(add, [{\n      name: 'num1',\n      type: Number\n    }, {\n      name: 'num2',\n      type: Number\n    }, {\n      name: 'sqrt',\n      type: Boolean,\n      allowNull: true\n    }]);\n    it(\"type assert\", function(done) {\n      assert.ok(add instanceof Function, '处理后的仍然是一个函数');\n      assert.ok(add.num1 instanceof Function, 'num1 是接收参数的函数');\n      assert.ok(add.num2 instanceof Function, 'num2 是接收参数的函数');\n      assert.ok(add.sqrt instanceof Function, 'sqrt 是接收参数的函数');\n      done();\n    });\n\n    it(\"exec assert\", function(done) {\n      assert.equal(3, add(1, 2), '普通调用，缺失 sqrt 参数');\n      assert.equal(16, add.num1(7).num2(9).exec(), '链式执行缺失 sqrt 参数');\n      assert.equal(4, add.num1(7).num2(9).sqrt(true).exec(), '链式执行 sqrt true');\n      assert.equal(16, add.num1(7).num2(9).sqrt(false).exec(), 'sqrt false');\n      assert.equal(16, add.sqrt(false).num1(7).num2(9).exec(), '顺序无关');\n      done();\n    });\n\n    it(\"Exception assert\", function(done) {\n      assert.throws(function() {\n        add(1, '2');\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `num2` type must be `Number`';\n      });\n\n      assert.throws(function() {\n        add.num2('2').num1(1).exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `num2` type must be `Number`';\n      })\n\n      assert.throws(function() {\n        add.num1(1).num2('2').exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `num2` type must be `Number`';\n      })\n\n      assert.throws(function() {\n        add.num1(1).num2(2).sqrt('hello').exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `sqrt` type must be `Boolean`';\n      })\n      done();\n    });\n  });\n\n  describe(\"#validate rule and defaultValue\", function() {\n    var person = function(name, email, age) {\n      return {\n        name: name,\n        email: email,\n        age: age\n      };\n    };\n    person = delegate(person, [{\n      name: 'Name',\n      type: String,\n      validate: {\n        matches: /^赵/,\n        length: function(v) {\n          return v.length \u003e 1 \u0026\u0026 v.length \u003c 4;\n        }\n      },\n      message: 'Name must be a string, start with `赵`, lenght gt 1 and lt 4'\n    }, {\n      name: 'email',\n      type: String,\n      validate: {\n        isEmail: true\n      }\n    }, {\n      name: 'age',\n      type: Number,\n      defaultValue: 18,\n      allowNull: true,\n      validate: {\n        max: 200\n      },\n      message: \"Age must be a number, max value is 200, default is 18\"\n    }]);\n    it(\"Type assert\", function(done) {\n      assert.ok(person instanceof Function, '处理后的仍然是一个函数');\n      assert.ok(person.Name instanceof Function, 'Name');\n      assert.ok(person.email instanceof Function, 'email');\n      assert.ok(person.age instanceof Function, 'age');\n      done()\n    });\n\n    it(\"exec assert\", function(done) {\n      assert.deepEqual({\n        email: '13740080@qq.com',\n        name: '赵雄飞',\n        age: 18\n      }, person('赵雄飞', '13740080@qq.com'));\n      assert.deepEqual({\n        email: '13740080@qq.com',\n        name: '赵雄飞',\n        age: 18\n      }, person.Name('赵雄飞').email('13740080@qq.com').exec());\n      assert.deepEqual({\n        email: '13740080@qq.com',\n        name: '赵雄飞',\n        age: 36\n      }, person.Name('赵雄飞').email('13740080@qq.com').age(36).exec());\n      done()\n    });\n\n    it(\"Exception assert\", function(done) {\n      assert.throws(function() {\n        person('王方', '223251686@qq.com')\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Name must be a string, start with `赵`, lenght gt 1 and lt 4'\n      });\n\n      assert.throws(function() {\n        person('赵导耳机', '223251686@qq.com')\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Name must be a string, start with `赵`, lenght gt 1 and lt 4'\n      });\n\n      assert.throws(function() {\n        person.Name('王方').email('223251686@qq.com').exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Name must be a string, start with `赵`, lenght gt 1 and lt 4'\n      })\n\n      assert.throws(function() {\n        person.Name('赵星梦').email('223251686').exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === '`email` validate failure: isEmail'\n      })\n\n      done();\n    });\n  });\n\n  describe(\"#iterator validate\", function() {\n    var lib = function(books) {\n      return {\n        books: books,\n        size: books.length\n      };\n    };\n    lib = delegate(lib, [{\n      name: 'books',\n      type: Array,\n      iterator: {\n        name: {\n          type: String,\n          allowNull: false,\n          validate: {\n            length: [1, 20]\n          },\n          message: '书名必填是字符串，长度为 1 - 20'\n        },\n        price: {\n          type: Number,\n          allowNull: true,\n          validate: {\n            max: 300,\n            min: 10\n          },\n          message: '价格选填，数字类型，最大 300， 最小 10'\n        }\n      }\n    }]);\n    it(\"Type assert\", function(done) {\n      assert.ok(lib instanceof Function, '处理后的仍然是一个函数');\n      assert.ok(lib.books instanceof Function, 'books 是接收参数的函数');\n      assert.ok(lib.exec instanceof Function, 'exec 是执行函数');\n      done()\n    });\n\n    it(\"exec assert\", function(done) {\n      assert.deepEqual({\n        books: [{\n          name: 'JavaScript 权威指南',\n          price: 35.26\n        }, {\n          name: 'MySQL 性能优化'\n        }],\n        size: 2\n      }, lib([{name: 'JavaScript 权威指南', price: 35.26}, {name: 'MySQL 性能优化'}]))\n      assert.deepEqual({\n        books: [{\n          name: 'JavaScript 权威指南',\n          price: 35.26\n        }, {\n          name: 'MySQL 性能优化'\n        }],\n        size: 2\n      }, lib.books([{name: 'JavaScript 权威指南', price: 35.26}, {name: 'MySQL 性能优化'}]).exec());\n      done()\n    });\n\n    it(\"Exception assert\", function(done) {\n      assert.throws(function() {\n        lib('hello world');\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === 'Argument `books` type must be `Array`'\n      }, '参数类型错误');\n\n      assert.throws(function() {\n        lib([{name: []}]);\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === '书名必填是字符串，长度为 1 - 20'\n      }, 'iterator 里类型错误');\n\n      assert.throws(function() {\n        lib.books([{name: 'Hello world', price: 'Redstone'}]).exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === '价格选填，数字类型，最大 300， 最小 10'\n      }, 'iterator 价格类型不对');\n\n      assert.throws(function() {\n        lib.books([{name: 'Hello world', price: 500}]).exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === '价格选填，数字类型，最大 300， 最小 10'\n      }, 'iterator 价格类型不对');\n\n      assert.throws(function() {\n        lib.books([{name: 'Hello world', price: 5}]).exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === '价格选填，数字类型，最大 300， 最小 10'\n      }, 'iterator 价格类型不对');\n\n      assert.throws(function() {\n        lib.books([{name: 'Hello world'}, {name: []}]).exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === '书名必填是字符串，长度为 1 - 20'\n      }, 'iterator 时某些数据的类型不正确');\n\n      assert.throws(function() {\n        lib.books([{name: 'Hello world Hello world Hello world Hello world'}]).exec();\n      }, function(err) {\n        return (err instanceof Error) \u0026\u0026 err.message === '书名必填是字符串，长度为 1 - 20'\n      }, 'iterator 内书名超出长度');\n\n      done();\n    });\n  });\n});\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-node%2Ffunc-delegate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopen-node%2Ffunc-delegate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-node%2Ffunc-delegate/lists"}