{"id":22788964,"url":"https://github.com/ripeworks/async-interactor","last_synced_at":"2025-03-30T16:23:21.040Z","repository":{"id":57185639,"uuid":"88907895","full_name":"ripeworks/async-interactor","owner":"ripeworks","description":"Interactor pattern using async/await","archived":false,"fork":false,"pushed_at":"2017-05-04T20:46:55.000Z","size":47,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-06T21:41:51.063Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ripeworks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-20T20:31:08.000Z","updated_at":"2017-05-07T14:54:26.000Z","dependencies_parsed_at":"2022-09-06T04:11:23.081Z","dependency_job_id":null,"html_url":"https://github.com/ripeworks/async-interactor","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ripeworks%2Fasync-interactor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ripeworks%2Fasync-interactor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ripeworks%2Fasync-interactor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ripeworks%2Fasync-interactor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ripeworks","download_url":"https://codeload.github.com/ripeworks/async-interactor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246344248,"owners_count":20762167,"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":[],"created_at":"2024-12-12T01:39:15.065Z","updated_at":"2025-03-30T16:23:21.020Z","avatar_url":"https://github.com/ripeworks.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003easync interactor\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/collectiveidea/interactor\"\u003eInteractor\u003c/a\u003e pattern for node.js/browser using async/await\n\u003c/div\u003e\n\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://badge.fury.io/js/async-interactor\"\u003e\u003cimg src=\"https://badge.fury.io/js/async-interactor.svg\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n## Getting Started\n\n```sh\n$ npm install --save async-interactor\n```\n\n_NOTE: async/await support required from node 7.6.0+ or something like [async-to-gen](https://github.com/leebyron/async-to-gen)_\n\n## Usage\n\n```js\nimport Interactor from 'async-interactor'\n\nclass AuthenticateUser extends Interactor {\n  async call () {\n    const {username, password} = this.context\n\n    const user = await db.where({username, password}).find()\n\n    if (!user) {\n      this.fail('User not found')\n    }\n\n    this.context.user = user\n  }\n}\n\n// example route handler\napp.post('/login', async (req, res) =\u003e {\n  const result = await AuthenticateUser.call(req.params)\n  if (result.success) {\n    res.send({success: true, user: result.user})\n  }\n})\n```\n\n## Organizers\n\n```js\nimport Interactor from 'async-interactor'\n\nclass AddSubscription extends Interactor {\n  // return Array of interactors\n  organize () {\n    return [AuthenticateUser, FinalizePayment]\n  }\n}\n\napp.post('/buy', async (req, res) =\u003e {\n  const result = await AddSubscription.call(req.params)\n})\n```\n\n## Errors\n\nBy default any errors thrown inside of an interactor are swallowed and return in the result of the interactor. This allows you to check the result of the interactor after it runs, regardless of a success or failure. There is a `throwOnError` option available if you don't want this default behavior.\n\n```js\nclass ThisWillThrow extends Interactor {\n  throwOnError = true\n\n  async call () {\n    throw new Error('Boom')\n  }\n}\n\nconst result = await ThisWillThrow.call({})\nconsole.log(result) // \u003c- this never runs because the error is `thrown`\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fripeworks%2Fasync-interactor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fripeworks%2Fasync-interactor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fripeworks%2Fasync-interactor/lists"}