{"id":16146544,"url":"https://github.com/voxpelli/node-micropub-express","last_synced_at":"2025-04-09T15:04:20.081Z","repository":{"id":34400476,"uuid":"38328530","full_name":"voxpelli/node-micropub-express","owner":"voxpelli","description":"Provides a Micropub route for Express 4.x","archived":false,"fork":false,"pushed_at":"2025-04-01T15:05:39.000Z","size":145,"stargazers_count":37,"open_issues_count":23,"forks_count":12,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-09T15:03:00.531Z","etag":null,"topics":["api","express","indieweb","micropub","node-js"],"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/voxpelli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["voxpelli"]}},"created_at":"2015-06-30T19:22:51.000Z","updated_at":"2024-02-22T23:33:46.000Z","dependencies_parsed_at":"2023-12-26T02:26:21.682Z","dependency_job_id":"2d9c2325-4545-449e-af83-22f0b8a65f3b","html_url":"https://github.com/voxpelli/node-micropub-express","commit_stats":{"total_commits":189,"total_committers":4,"mean_commits":47.25,"dds":"0.29100529100529104","last_synced_commit":"06d6a793c8292308b5e1411bd38157943abacb53"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Fnode-micropub-express","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Fnode-micropub-express/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Fnode-micropub-express/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Fnode-micropub-express/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voxpelli","download_url":"https://codeload.github.com/voxpelli/node-micropub-express/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248055275,"owners_count":21040156,"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":["api","express","indieweb","micropub","node-js"],"created_at":"2024-10-10T00:20:30.099Z","updated_at":"2025-04-09T15:04:20.047Z","avatar_url":"https://github.com/voxpelli.png","language":"JavaScript","funding_links":["https://github.com/sponsors/voxpelli"],"categories":[],"sub_categories":[],"readme":"# Micropub Express\n\n[![Build Status](https://travis-ci.org/voxpelli/node-micropub-express.svg?branch=master)](https://travis-ci.org/voxpelli/node-micropub-express)\n[![Coverage Status](https://coveralls.io/repos/voxpelli/node-micropub-express/badge.svg)](https://coveralls.io/r/voxpelli/node-micropub-express)\n[![dependencies Status](https://david-dm.org/voxpelli/node-micropub-express/status.svg)](https://david-dm.org/voxpelli/node-micropub-express)\n[![Known Vulnerabilities](https://snyk.io/test/github/voxpelli/node-micropub-express/badge.svg?targetFile=package.json)](https://snyk.io/test/github/voxpelli/node-micropub-express?targetFile=package.json)\n[![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat)](https://github.com/Flet/semistandard)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fvoxpelli%2Fnode-micropub-express.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvoxpelli%2Fnode-micropub-express?ref=badge_shield)\n\nProvides a Micropub route for Express 4.x\n\n## Requirements\n\nNode.js requirement is set in `package.json` (Use eg. [installed-check](https://github.com/voxpelli/node-installed-check) to validate that it complies with your requirements)\n\n## Installation\n\n```bash\nnpm install micropub-express --save\n```\n\n## Current status\n\n**Early alpha**\n\nSupported:\n\n* Creation of content based items and creation of likes\n\nThe rest of the CRUD-operations + other more complex operations are yet to be built and the API might change to adopt to the requirements of those. Versioning will stick to Semantic Versioning to clearly communicate such breaking changes.\n\n## Usage\n\n```javascript\nvar micropub = require('micropub-express');\n\n// Attach the micropub endpoint to \"/micropub\" or wherever else you want\napp.use('/micropub', micropub({\n\n  // Specify what endpoint you want to verify a token with and what the expected identity returned is\n  tokenReference: {\n    me: 'http://example.com/',\n    endpoint: 'https://tokens.indieauth.com/token',\n  },\n\n  // And lastly: Do something with the created micropub document\n  handler: function (micropubDocument, req) {\n    // Do something with the micropubDocument and return a Promise to communicate status of the handling\n    return Promise.resolve().then(function () {\n      return { url: 'http://example.com/url/to/new/post' };\n    });\n  }\n\n}));\n```\n\n## Advanced Usage\n\n```javascript\nvar express = require('express');\nvar micropub = require('micropub-express');\n\nvar app = express();\n\n// Do some Express magic to support multiple Micropub endpoints in the same application\napp.param('targetsite', function (req, res, next, id) {\n  // Resolve a token reference from the \"targetsite\" id and return 404 if you find no match\n  if (id === 'example.com') {\n    req.targetsite = {\n      me: 'http://example.com/',\n      endpoint: 'https://tokens.indieauth.com/token',\n    };\n    next();\n  } else {\n    res.sendStatus(404);\n  }\n});\n\napp.use('/micropub/:targetsite', micropub({\n  logger: logger,          // a logger object that uses the same API as the bunyan module\n  userAgent: 'my-app/1.0', // a user-agent that will be prepended to the module's own user-agent to indicate\n                           // to IndieAuth endpoints who it is that makes the verification requests\n  tokenReference: function (req) {\n    // Find the token reference we added to the request object before and return it\n    return req.targetsite;\n  },\n  // And lastly: Do something with the created micropub document\n  handler: function (micropubDocument, req) {\n    // Do something with the micropubDocument and return a Promise to communicate status of the handling\n    return Promise.resolve().then(function () {\n      return { url: 'http://example.com/url/to/new/post' };\n    });\n  }\n}));\n\n// Start the Express server on a port, like port 3000!\napp.listen(3000);\n```\n\n## Options\n\n* **tokenReference** – *required* – either an object with two keys, `me` and `endpoint`, or a function that receives the request object and returns an object with those two keys. The `me` key signify what identity it is that's expected for a succesful authorization and the `endpoint` key indicates what endpoint the token should be verified with. Can also be or return an array of multiple references.\n* **handler** – *required* – the function that will be called with the handled micropub document and the request object. It's this functions responsibility to actually act on the received data and do something with it. Should return a `Promise` resolving to an object with a `url` key containing the url of the created item to indicate success. If the `Promise` is rejected or the `url` key is missing or falsy in the resolved `Promise`, then a `400` error will be returned to indicate failure.\n* **userAgent** – *recommended* – a user-agent *string* like `your-app-name/1.2.3 (http://app.example.com/)` that gets prepended to the user-agent of `micropub-express` itself when verifying received tokens against an endpoint\n* **queryHandler** – *optional* – a function that will be called whenever a `?q=` query is made to the Micropub endpoint. It's this functions responsibility to execute the query and respond with the relevant data. Should return a `Promise` resolving to an object containing the query result. Keys on the object should _not_ include any `[]`, those will be added in the encoded result where relevant. If the `Promise` resolves to something falsy, then a `400` error will be returned to indicate that the query type is unsupported. If the `Promise` is rejected, then a `400` error will be returned to indicate failure.\n* **logger** – *optional* – a [bunyan](https://github.com/trentm/node-bunyan) compatible logger, like bunyan itself or some other module. Defaults to [bunyan-duckling](https://github.com/bloglovin/node-bunyan-duckling) which logs with `console.log()` and `console.error()`\n\n## Format of `micropubDocument`\n\nThe format closely matches the [JSON-representation](http://indiewebcamp.com/Micropub#JSON_Syntax) of Micropub.\n\nIt contains three top level keys:\n\n* **type** – an array containing the type that is that's going to be created. Eg. `['h-entry']`\n* **properties** – an object containing all of the microformat properties of the document as arrays containing strings. Eg. `content: ['foobar']`\n* **mp** – an object containing all of the micropub directives as arrays containing string. Eg. `'syndicate-to': ['http://twitter.com/example']` for an `'mp-syndicate-to'` directive.\n* **files** – an object that can contain three keys, `audio`, `video`, `photo`, which in turn contains arrays of objects with a `filename` and a `buffer` key with the name and content of the files.\n\nFull example:\n\n```javascript\n{\n  type: ['h-entry'],\n  properties: {\n    content: ['hello world'],\n  },\n  mp: {\n    'syndicate-to': ['http://twitter.com/example'],\n  },\n  files: {\n    photo: [\n      {\n        filename: 'example.jpg',\n        buffer: new Buffer() // A Node.js buffer with the content of the file.\n      }\n    ]\n  }\n}\n```\n\n## Other useful modules\n\n* [format-microformat](https://github.com/voxpelli/node-format-microformat) – a module that takes a `micropubDocument` as its input and then formats filenames, URL:s and file content from that data so one gets some standard data which one then can publish elsewhere – like to a Jekyll blog or something.\n* [github-publish](https://github.com/voxpelli/node-github-publish) – a module that takes a filename and content and publishes that to a GitHub repository. A useful place to send the formatted data that comes out of `format-microformat` if one wants to add it to a GitHub hosted Jekyll blog of some kind, like eg. [GitHub Pages](https://pages.github.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpelli%2Fnode-micropub-express","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoxpelli%2Fnode-micropub-express","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpelli%2Fnode-micropub-express/lists"}