{"id":19646174,"url":"https://github.com/yoctol/bookshelf-plugin","last_synced_at":"2026-06-08T22:31:41.513Z","repository":{"id":38426059,"uuid":"152061411","full_name":"Yoctol/bookshelf-plugin","owner":"Yoctol","description":"Yoctol specific plugins for Bookshelf","archived":false,"fork":false,"pushed_at":"2023-01-11T03:25:44.000Z","size":1037,"stargazers_count":2,"open_issues_count":15,"forks_count":1,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-02-27T00:16:16.651Z","etag":null,"topics":[],"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/Yoctol.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":"2018-10-08T10:26:58.000Z","updated_at":"2021-07-01T10:27:13.000Z","dependencies_parsed_at":"2023-02-09T00:45:14.522Z","dependency_job_id":null,"html_url":"https://github.com/Yoctol/bookshelf-plugin","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/Yoctol/bookshelf-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yoctol%2Fbookshelf-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yoctol%2Fbookshelf-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yoctol%2Fbookshelf-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yoctol%2Fbookshelf-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Yoctol","download_url":"https://codeload.github.com/Yoctol/bookshelf-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yoctol%2Fbookshelf-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34083848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-11-11T14:37:11.029Z","updated_at":"2026-06-08T22:31:41.494Z","avatar_url":"https://github.com/Yoctol.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bookshelf-plugin\n\n[![npm](https://img.shields.io/npm/v/@yoctol/bookshelf-plugin.svg)](https://www.npmjs.com/package/@yoctol/bookshelf-plugin)\n\n## Install\n\n```sh\nnpm install @yoctol/bookshelf-plugin\n```\n\n## Usage\n\n```js\nconst plugin = require('@yoctol/bookshelf-plugin');\n\nbookshelf.plugin(plugin);\n```\n\n## Include plugins\n\n- [case-converter](https://github.com/bookshelf/case-converter-plugin)\n- [virtuals](https://github.com/bookshelf/virtuals-plugin)\n- [modelbase](https://github.com/bsiddiqui/bookshelf-modelbase)\n- [json-columns](https://github.com/seegno/bookshelf-json-columns)\n- touch\n- soft-delete\n- accessible-attributes\n- encrypt-columns\n\nYou can pass `caseConverter: false` option to disable `case-converter`:\n\n```js\nconst plugin = require('@yoctol/bookshelf-plugin');\n\nbookshelf.plugin(plugin, { caseConverter: false });\n```\n\n### touch\n\n```js\nconst Project = bookshelf.Model.extend({\n  tableName: 'projects',\n  touches: ['user'],\n\n  user() {\n    return this.belongsTo(User);\n  },\n});\n```\n\n```js\nproject.touch();\n```\n\nYou can use `touchMethod` option to avoid naming conflict when it happened:\n\n```js\nconst plugin = require('@yoctol/bookshelf-plugin');\n\nbookshelf.plugin(plugin, { touchMethod: 'touchModel' });\n```\n\nYou can use `timestamps` option to overwrite the timestamps key:\n\n```js\nconst plugin = require('@yoctol/bookshelf-plugin');\n\nbookshelf.plugin(plugin, { timestamps: ['created_at', 'updated_at'] });\n```\n\n### soft-delete\n\n```js\nconst User = bookshelf.Model.extend({\n  tableName: 'users',\n\n  softDelete: true,\n  dependents: ['projects'],\n\n  projects() {\n    return this.hasMany(Project);\n  },\n});\n```\n\n```js\n// This will update deleted_at and cascade delete dependents\nuser.destroy();\n```\n\n### accessible-attributes\n\n```js\nconst User = bookshelf.Model.extend({\n  tableName: 'users',\n\n  attrs: ['name', 'type', 'age'],\n});\n```\n\n```js\nuser.name; // Same as user.get('name');\nuser.type; // Same as user.get('type');\nuser.age; // Same as user.get('age');\n```\n\nYou can also overwrite attr on Model.\n\n```js\nbookshelf.Model = bookshelf.Model.extend({\n  constructor(...args) {\n    proto.constructor.apply(this, args);\n\n    Object.defineProperty(this, 'custom', {\n      get: () =\u003e 'custom-value',\n      set: (value, key) =\u003e this.set(key, value),\n    });\n  },\n});\n```\n\n### encrypt-columns\n\nUse `encryptColumns` options to enable `encrypt-columns` plugin.  \nThe idea of this plugin mainly comes from [`bookshelf-encrypt-columns`](https://github.com/scoutforpets/bookshelf-encrypt-columns/)\n\n```js\nconst plugin = require('@yoctol/bookshelf-plugin');\n\nbookshelf.plugin(plugin, {\n  encryptColumns: {\n    algorithm: 'aes-256-cbc', // default to 'aes-256-cbc'\n    ivLength: 16, // IV length for the selected algorithm\n    key: '\u003cYOUR_KEY\u003e',\n  },\n});\n```\n\nThis plugin will automatically encrypt when save to database and decrypt on query from database.\n\n```js\nconst User = bookshelf.Model.extend({\n  tableName: 'users',\n  encryptedCoulmns: ['secret'],\n});\n```\n\n## Migration guide from 0.6.x to 1.0.0\n\n### withRefresh\n\n#### before\n\n```js\nuser.save(null, { withRefresh: true });\nuser.save({ key: value }, { withRefresh: true });\nuser.save(key, value, { withRefresh: true });\n```\n\n#### after\n\n```js\nuser.save(null);\nuser.save({ key: value });\nuser.save(key, value);\n```\n\n#### before\n\n```js\nuser.save(null);\nuser.save({ key: value });\nuser.save(key, value);\n```\n\n#### after\n\n```js\nuser.save(null, { autoRefresh: false });\nuser.save({ key: value }, { autoRefresh: false });\nuser.save(key, value, { autoRefresh: false });\n```\n\n- `autoRefresh` is supported by bookshelf, and its default is `true`\n- You should also take a look for bookshelf migration guide https://github.com/bookshelf/bookshelf/wiki/Migrating-from-0.15.1-to-1.0.0\n\n## License\n\nMIT © [Yoctol](https://github.com/Yoctol/bookshelf-plugin)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoctol%2Fbookshelf-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyoctol%2Fbookshelf-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoctol%2Fbookshelf-plugin/lists"}