{"id":13651085,"url":"https://github.com/designtesbrot/moleculer-sharp","last_synced_at":"2025-04-22T22:30:30.062Z","repository":{"id":33793688,"uuid":"162426931","full_name":"designtesbrot/moleculer-sharp","owner":"designtesbrot","description":"🖼️ A Moleculer Service for Image Manipulation using sharp 🖼️","archived":false,"fork":false,"pushed_at":"2022-12-03T21:02:59.000Z","size":925,"stargazers_count":12,"open_issues_count":11,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-29T20:56:28.746Z","etag":null,"topics":["image-processing","moleculer","moleculerjs","sharp"],"latest_commit_sha":null,"homepage":"","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/designtesbrot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2018-12-19T11:19:31.000Z","updated_at":"2023-03-29T14:54:12.000Z","dependencies_parsed_at":"2023-01-15T02:45:37.429Z","dependency_job_id":null,"html_url":"https://github.com/designtesbrot/moleculer-sharp","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/designtesbrot%2Fmoleculer-sharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/designtesbrot%2Fmoleculer-sharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/designtesbrot%2Fmoleculer-sharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/designtesbrot%2Fmoleculer-sharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/designtesbrot","download_url":"https://codeload.github.com/designtesbrot/moleculer-sharp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249487742,"owners_count":21280447,"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":["image-processing","moleculer","moleculerjs","sharp"],"created_at":"2024-08-02T02:00:44.919Z","updated_at":"2025-04-22T22:30:29.589Z","avatar_url":"https://github.com/designtesbrot.png","language":"JavaScript","funding_links":[],"categories":["Services","JavaScript"],"sub_categories":["Others"],"readme":"[![Moleculer logo](http://moleculer.services/images/banner.png)](https://github.com/moleculerjs/moleculer)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fdesigntesbrot%2Fmoleculer-sharp.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fdesigntesbrot%2Fmoleculer-sharp?ref=badge_shield)\n\n[![Build Status](https://travis-ci.com/designtesbrot/moleculer-sharp.svg?branch=master)](https://travis-ci.com/designtesbrot/moleculer-sharp)\n[![Coverage Status](https://coveralls.io/repos/github/designtesbrot/moleculer-sharp/badge.svg?branch=master)](https://coveralls.io/github/designtesbrot/moleculer-sharp?branch=master)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/7f8245b6a42249a7b3f5de62d88a9ef4)](https://www.codacy.com/app/designtesbrot/moleculer-sharp?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=designtesbrot/moleculer-sharp\u0026amp;utm_campaign=Badge_Grade)\n[![Maintainability](https://api.codeclimate.com/v1/badges/92a1e223f18762feb513/maintainability)](https://codeclimate.com/github/designtesbrot/moleculer-sharp/maintainability)\n[![Known Vulnerabilities](https://snyk.io/test/github/designtesbrot/moleculer-sharp/badge.svg)](https://snyk.io/test/github/designtesbrot/moleculer-sharp)\n[![npm version](https://badge.fury.io/js/moleculer-sharp.svg)](https://badge.fury.io/js/moleculer-sharp)\n[![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/33de085edc9d85004add)\n\n# Image Manipulation Service for the Moleculer framework\n\nThis Services provides actions for manipulating images using the super fast [Sharp](http://sharp.pixelplumbing.com/en/stable/) module. It \nutilizes the file streaming capabilities of the moleculer framework\n\n## Features\n\nThe following List details which features are implemented\n\n- Obtain Metadata of an image at a path, being streamed or available via http(s)\n- Obtain Channel Statistics of an image at a path, being streamed or available via http(s)\n- Process an image with all manipulation and transformation methods available in Sharp (such as rotation, flip, convert, resize etc) \n\n## Install\n\nThis package is available in the npm-registry. In order to use it simply install it with yarn (or npm):\n\n```bash\nyarn add moleculer-sharp\n```\n\n## Usage\n\nTo make use of this Service, simply require it and create a new service:\n\n```js\nconst fs = require(\"fs\");\nlet { ServiceBroker } = require(\"moleculer\");\nlet SharpService = require(\"moleculer-sharp\");\n\nlet broker = new ServiceBroker({ logger: console });\n\n// Create a service\nbroker.createService({\n    mixins: SharpService,\n});\n\n// Start server\nbroker.start()\n    .then(() =\u003e broker.call('sharp.metadata',{url: 'https://pics.me.me/welcome-to-the-internet-ill-be-your-guide-28274277.png'}))\n    .then(() =\u003e broker.call('sharp.stats',{url: 'https://pics.me.me/welcome-to-the-internet-ill-be-your-guide-28274277.png'}))\n    .then(() =\u003e \n        broker.call('sharp.process',{url: 'https://pics.me.me/welcome-to-the-internet-ill-be-your-guide-28274277.png'}, {meta:\n            steps: [\n                [\"resize\", 200],\n                [\"rotate\", 30, {\"background\": {\"r\": 0, \"g\": 0, \"b\": 0, \"alpha\": 0}}],\n                \"jpeg\"\n            ]\n        }));\n```\n\nFor a more indepth example checkout out the `examples folder`. It includes a docker-compose file, running `docker-compose up` will boot a broker with a sharp service\nand an API Gateway to invoke the actions of the sharp service. This project includes a [published postman collection](https://app.getpostman.com/run-collection/33de085edc9d85004add) enabling you to quickly explore the service in your local environment.\n\n## Settings\n\n\u003c!-- AUTO-CONTENT-START:SETTINGS --\u003e\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n*No settings.*\n\n\u003c!-- AUTO-CONTENT-END:SETTINGS --\u003e\n\n\u003c!-- AUTO-CONTENT-TEMPLATE:SETTINGS\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n{{#each this}}\n| `{{name}}` | {{type}} | {{defaultValue}} | {{description}} |\n{{/each}}\n{{^this}}\n*No settings.*\n{{/this}}\n\n--\u003e\n\n## Actions\n\n\u003c!-- AUTO-CONTENT-START:ACTIONS --\u003e\n## `metadata` \n\nFast access to (uncached) image metadata without decoding any compressed image data.\n\n```js\nbroker.call('sharp.metadata',{url: 'https://pics.me.me/welcome-to-the-internet-ill-be-your-guide-28274277.png'})\n```\n\n### Parameters\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n| `params` | `String`, `ReadableStream`, `Object` | **required** | the image to acquire metadata for, can be a path, a stream or an object. If a **path** is given, this action will try to acquire a readable stream for the path. If an **object** is given, a http(s) stream will be acquired and the response body will be subject. For the location of the request, the url property will be used, while all other properties will be used as [node-fetch-options](https://www.npmjs.com/package/node-fetch#fetch-options) |\n\n### Results\n**Type:** `PromiseLike.\u003c(Object|Error)\u003e`\n\n\n\n\n## `stats` \n\nGather stats of an image\n\n```js\nbroker.call('sharp.stats',{url: 'https://pics.me.me/welcome-to-the-internet-ill-be-your-guide-28274277.png'})\n```\n\n### Parameters\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n| `params` | `String`, `ReadableStream`, `Object` | **required** | the image to acquire stats for, can be a path, a stream or an object. If a **path** is given, this action will try to acquire a readable stream for the path. If an **object** is given, a http(s) stream will be acquired and the response body will be subject. For the location of the request, the url property will be used, while all other properties will be used as [node-fetch-options](https://www.npmjs.com/package/node-fetch#fetch-options) |\n\n### Results\n**Type:** `PromiseLike.\u003c(Object|Error)\u003e`\n\n\n\n\n## `process` \n\nProcesses an image. The action parameter indicates which image to process. The actual processing instructions\nhave to be provided via the `meta.steps` property of the call. Any operation that is listed on the\n[Sharp Documentation](http://sharp.pixelplumbing.com/en/stable/) can be included as a step instruction. Here is an example:\n\n```js\nbroker.call('sharp.process',{url: 'https://pics.me.me/welcome-to-the-internet-ill-be-your-guide-28274277.png'}, {meta:\n    steps: [\n        [\"resize\", 200],\n     [\"rotate\", 30, {\"background\": {\"r\": 0, \"g\": 0, \"b\": 0, \"alpha\": 0}}],\n     \"jpeg\"\n    ]\n})\n```\n\nIf your last step instructions is a `toFile` instructions, the transformation output will be written to disk, and the\naction will respond with meta information about the image. In any other case the action will respond with a readable\nstream for your to further process.\n\n### Parameters\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n| `params` | `String`, `ReadableStream`, `Object` | **required** | the image to process, can be a path, a stream or an object. If a **path** is given, this action will try to acquire a readable stream for the path. If an **object** is given, a http(s) stream will be acquired and the response body will be subject. For the location of the request, the url property will be used, while all other properties will be used as [node-fetch-options](https://www.npmjs.com/package/node-fetch#fetch-options) |\n\n### Results\n**Type:** `PromiseLike.\u003c(undefined|Error)\u003e`\n\n\n\n\n\u003c!-- AUTO-CONTENT-END:ACTIONS --\u003e\n\n\u003c!-- AUTO-CONTENT-TEMPLATE:ACTIONS\n{{#each this}}\n## `{{name}}` {{#each badges}}{{this}} {{/each}}\n{{#since}}\n_\u003csup\u003eSince: {{this}}\u003c/sup\u003e_\n{{/since}}\n\n{{description}}\n\n### Parameters\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n{{#each params}}\n| `{{name}}` | {{type}} | {{defaultValue}} | {{description}} |\n{{/each}}\n{{^params}}\n*No input parameters.*\n{{/params}}\n\n{{#returns}}\n### Results\n**Type:** {{type}}\n\n{{description}}\n{{/returns}}\n\n{{#hasExamples}}\n### Examples\n{{#each examples}}\n{{this}}\n{{/each}}\n{{/hasExamples}}\n\n{{/each}}\n--\u003e\n\n# Methods\n\n\u003c!-- AUTO-CONTENT-START:METHODS --\u003e\n## `acquireReadStream` \n\nAcquire a readable stream from a given source\n\n### Parameters\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n| `source` | `String`, `ReadableStream`, `Object` | **required** | can be a path, a stream or an object. If a **path** is given, this action will try to acquire a readable stream for the path. If an **object** is given, a http(s) stream will be acquired for the response body. For the location of the request, the url property will be used, while all other properties will be used as [node-fetch-options](https://www.npmjs.com/package/node-fetch#fetch-options) |\n\n### Results\n**Type:** `PromiseLike.\u003c(Stream|SharpStreamAcquisitionError|Error)\u003e`\n\n\n\n\n## `bufferStream` \n\nFeed a Stream into a Buffer\n\n### Parameters\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n| `stream` | `ReadableStream` | **required** |  |\n\n### Results\n**Type:** `PromiseLike.\u003c(Buffer|Error)\u003e`\n\n\n\n\n\u003c!-- AUTO-CONTENT-END:METHODS --\u003e\n\n\u003c!-- AUTO-CONTENT-TEMPLATE:METHODS\n{{#each this}}\n## `{{name}}` {{#each badges}}{{this}} {{/each}}\n{{#since}}\n_\u003csup\u003eSince: {{this}}\u003c/sup\u003e_\n{{/since}}\n\n{{description}}\n\n### Parameters\n| Property | Type | Default | Description |\n| -------- | ---- | ------- | ----------- |\n{{#each params}}\n| `{{name}}` | {{type}} | {{defaultValue}} | {{description}} |\n{{/each}}\n{{^params}}\n*No input parameters.*\n{{/params}}\n\n{{#returns}}\n### Results\n**Type:** {{type}}\n\n{{description}}\n{{/returns}}\n\n{{#hasExamples}}\n### Examples\n{{#each examples}}\n{{this}}\n{{/each}}\n{{/hasExamples}}\n\n{{/each}}\n--\u003e\n\n## Test\n```\n$ docker-compose exec package yarn test\n```\n\nIn development with watching\n\n```\n$ docker-compose up\n```\n\n## License\nmoleculer-sharp is available under the [MIT license](https://tldrlegal.com/license/mit-license).\n\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fdesigntesbrot%2Fmoleculer-sharp.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fdesigntesbrot%2Fmoleculer-sharp?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesigntesbrot%2Fmoleculer-sharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdesigntesbrot%2Fmoleculer-sharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesigntesbrot%2Fmoleculer-sharp/lists"}