{"id":13583586,"url":"https://github.com/ehmicky/unix-permissions","last_synced_at":"2025-04-06T23:16:05.527Z","repository":{"id":40571998,"uuid":"162268250","full_name":"ehmicky/unix-permissions","owner":"ehmicky","description":"Swiss Army knife for Unix permissions","archived":false,"fork":false,"pushed_at":"2025-03-17T02:46:08.000Z","size":13695,"stargazers_count":140,"open_issues_count":0,"forks_count":5,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-25T09:18:13.408Z","etag":null,"topics":["access-control","acl","chmod","cli","javascript","library","nodejs","octal","permissions","posix","setgid","setuid","shell","stat","sticky","symbolic","terminal","typescript","umask","unix"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ehmicky.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2018-12-18T10:06:09.000Z","updated_at":"2025-03-17T02:46:12.000Z","dependencies_parsed_at":"2024-01-03T04:14:35.122Z","dependency_job_id":"885890a0-a4b4-4fa9-a44a-9b3781dab8a7","html_url":"https://github.com/ehmicky/unix-permissions","commit_stats":{"total_commits":1779,"total_committers":3,"mean_commits":593.0,"dds":0.00393479482855541,"last_synced_commit":"c5ad56dbb51e4dfa566572bbb68317f05802de3f"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ehmicky%2Funix-permissions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ehmicky%2Funix-permissions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ehmicky%2Funix-permissions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ehmicky%2Funix-permissions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ehmicky","download_url":"https://codeload.github.com/ehmicky/unix-permissions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247563935,"owners_count":20958971,"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":["access-control","acl","chmod","cli","javascript","library","nodejs","octal","permissions","posix","setgid","setuid","shell","stat","sticky","symbolic","terminal","typescript","umask","unix"],"created_at":"2024-08-01T15:03:36.486Z","updated_at":"2025-04-06T23:16:05.492Z","avatar_url":"https://github.com/ehmicky.png","language":"JavaScript","funding_links":[],"categories":["Files and Directories","JavaScript","\u003ca name=\"file-handling\"\u003e\u003c/a\u003eFile and file system handling"],"sub_categories":["Files"],"readme":"\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/ehmicky/design/main/unix-permissions/unix-permissions_dark.png\"/\u003e\n  \u003cimg alt=\"unix-permissions logo\" src=\"https://raw.githubusercontent.com/ehmicky/design/main/unix-permissions/unix-permissions.png\" width=\"500\"/\u003e\n\u003c/picture\u003e\n\n[![Node](https://img.shields.io/badge/-Node.js-808080?logo=node.js\u0026colorA=404040\u0026logoColor=66cc33)](https://www.npmjs.com/package/unix-permissions)\n[![Browsers](https://img.shields.io/badge/-Browsers-808080?logo=firefox\u0026colorA=404040)](https://unpkg.com/unix-permissions?module)\n[![TypeScript](https://img.shields.io/badge/-Typed-808080?logo=typescript\u0026colorA=404040\u0026logoColor=0096ff)](/src/main.d.ts)\n[![Codecov](https://img.shields.io/badge/-Tested%20100%25-808080?logo=codecov\u0026colorA=404040)](https://codecov.io/gh/ehmicky/unix-permissions)\n[![Minified size](https://img.shields.io/bundlephobia/minzip/unix-permissions?label\u0026colorA=404040\u0026colorB=808080\u0026logo=webpack)](https://bundlephobia.com/package/unix-permissions)\n[![Mastodon](https://img.shields.io/badge/-Mastodon-808080.svg?logo=mastodon\u0026colorA=404040\u0026logoColor=9590F9)](https://fosstodon.org/@ehmicky)\n[![Medium](https://img.shields.io/badge/-Medium-808080.svg?logo=medium\u0026colorA=404040)](https://medium.com/@ehmicky)\n\nSwiss Army knife for Unix permissions.\n\n[Unix file permissions](https://en.wikipedia.org/wiki/File_system_permissions)\ncan take many [shapes](#permission-types): [symbolic](docs/types.md#symbolic)\n(`ug+rw`), [octal](docs/types.md#octal) (`660`) or a\n[list of characters](docs/types.md#stat) (`drw-rw----`). This library enables\nusing any of [these](#permission-types) (instead of being limited to a single\none) with any [Node.js](#examples) or [CLI command](#examples).\n\nThis library can also perform operations on Unix permissions such as:\n\n- [testing](docs/API.md#containpermission-permissions),\n  [setting](docs/API.md#setpermission-permissions) and\n  [unsetting](docs/API.md#notpermission). Using bitwise operations (`|`, `\u0026`,\n  `^`, `~`) can be tedious and error-prone otherwise.\n- [validating](docs/API.md#normalizepermission) syntax.\n- [normalizing](docs/API.md#normalizepermission). For example `u+r,u+w` can be\n  shortened to `u+rw`.\n- [inverting](docs/API.md#invertpermission). For example a\n  [`umask`](https://linux.die.net/man/2/umask) of `117` means new files will be\n  created with `661` permissions.\n- checking the [minimal](docs/API.md#minpermissions) or\n  [maximal](docs/API.md#maxpermissions) permissions among a list of them. This\n  can be useful to aggregate all the permissions of several files, e.g. during a\n  directory recursion.\n\nPermissions are manipulated as strings, not as file paths. This means you must\nuse other utilities (such as [`chmod`](https://linux.die.net/man/1/chmod) or\n[`stat`](https://linux.die.net/man/2/stat)) to get and set file permissions\nusing those strings.\n\n# Examples\n\nIn JavaScript:\n\n\u003c!-- eslint-disable n/no-sync --\u003e\n\n```js\nimport { convert } from 'unix-permissions'\n\n// Retrieve a file's permission as an object like\n// `{ user: { write: false, read: true, ... }, ... }` instead of a number\nconvert.object(fs.statSync('/etc/passwd').mode)\n\n// Set a file's permission using `symbolic` notation instead of a number\nfs.chmod('/etc/passwd', convert.number('a=r'))\n\n// Set a file's permission using `symbolic` notation instead of a number\nfs.writeFile('/my/file', content, { mode: convert.number('a=r') })\n\n// Disallow executing new files using `umask`\nprocess.umask(convert.number(invert('a-x')))\n\n// If your library takes Unix permissions as input, using\n// `unix-permissions` under the hood lets your users choose their\n// favorite Unix permissions type.\nmyLibrary.method({ mode: 'a-wx' })\nmyLibrary.method({ mode: '444' })\n```\n\nOn the command line:\n\n```bash\n$ stat -c \"%a\" /etc/passwd\n644\n\n$ unix-permissions convert.symbolic \"$(stat -c \"%a\" /etc/passwd)\"\nu=rw,go=r\n```\n\n# Install\n\n```bash\nnpm install unix-permissions\n```\n\nThis package works in both Node.js \u003e=18.18.0 and\n[browsers](https://raw.githubusercontent.com/ehmicky/dev-tasks/main/src/browserslist).\n\nThis is an ES module. It must be loaded using\n[an `import` or `import()` statement](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c),\nnot `require()`. If TypeScript is used, it must be configured to\n[output ES modules](https://www.typescriptlang.org/docs/handbook/esm-node.html),\nnot CommonJS.\n\n# Usage (JavaScript)\n\n```js\nimport { convert } from 'unix-permissions'\n\n// `permission` will be set to `rw-rw----`\nconst permission = convert.stat('660')\n```\n\nSeveral methods other than `convert` are available but they mostly follow the\nsame pattern. Permission strings are passed as input and returned as output.\n\n# Usage (CLI)\n\n```bash\n$ unix-permissions convert.stat 660\nrw-rw----\n```\n\nThe same methods as in JavaScript are available. Exit code will be `1` if an\nerror occurred, e.g. if the permission syntax is invalid.\n\n# Permission types\n\nYou can use any of the following permission types as input. You can also\n[`convert()`](docs/API.md#convertoctalnumberstatsymbolicobjectpermission)\nbetween them:\n\n- [`octal`](docs/types.md#octal) strings like `\"422\"`\n- decimal [`number`](docs/types.md#number) like `274`\n- [`stat`](docs/types.md#stat) like `rw-rw-r--`\n- [`symbolic`](docs/types.md#symbolic) like `a+rw`\n- [`object`](docs/types.md#object) like\n  `{ user: { read: true, write: false, execute: false }, group: { write: false }, others: { write: false } }`\n\nSpecial permissions ([setuid](https://en.wikipedia.org/wiki/Setuid),\n[setgid](https://en.wikipedia.org/wiki/Setuid),\n[sticky](https://en.wikipedia.org/wiki/Sticky_bit)) can be used.\n\nPlease see the [types full documentation](docs/types.md).\n\n# Methods\n\n## convert.octal|number|stat|symbolic|object(permission)\n\nConverts `permission` to another type.\\\n[Full documentation](docs/API.md#convertoctalnumberstatsymbolicobjectpermission).\n\n## type(permission)\n\nReturns the `permission`'s type or `invalid`.\\\n[Full documentation](docs/API.md#typepermission).\n\n## normalize(permission)\n\nNormalizes a `permission` to its canonical shape. Throw if `permission` is\ninvalid.\\\n[Full documentation](docs/API.md#normalizepermission).\n\n## positive(permission)\n\nRemoves all negative permissions.\\\n[Full documentation](docs/API.md#positivepermission).\n\n## contain(permission, permissions...)\n\nTests whether `permission` includes `permissions`.\\\n[Full documentation](docs/API.md#containpermission-permissions).\n\n## equal(permission, permissions...)\n\nTests whether `permission` equals exactly `permissions`.\\\n[Full documentation](docs/API.md#equalpermission-permissions).\n\n## set(permission, permissions...)\n\nSets `permissions` on `permission`. This is useful to avoid error-prone bitwise\noperations (`|`, `\u0026`, `^`, `~`).\\\n[Full documentation](docs/API.md#setpermission-permissions).\n\n## not(permission)\n\nInverts `permission` including special permissions. This can be used in\ncombination with `set()` to unset `permissions` instead of setting them.\\\n[Full documentation](docs/API.md#notpermission).\n\n## invert(permission)\n\nInverts `permission` and removes special permissions.\\\n[Full documentation](docs/API.md#invertpermission).\n\n## min(permissions...)\n\nRetrieves the lowest permissions among all arguments.\\\n[Full documentation](docs/API.md#minpermissions).\n\n## max(permissions...)\n\nRetrieves the highest permissions among all arguments.\\\n[Full documentation](docs/API.md#maxpermissions).\n\n# Support\n\nFor any question, _don't hesitate_ to [submit an issue on GitHub](../../issues).\n\nEveryone is welcome regardless of personal background. We enforce a\n[Code of conduct](CODE_OF_CONDUCT.md) in order to promote a positive and\ninclusive environment.\n\n# Contributing\n\nThis project was made with ❤️. The simplest way to give back is by starring and\nsharing it online.\n\nIf the documentation is unclear or has a typo, please click on the page's `Edit`\nbutton (pencil icon) and suggest a correction.\n\nIf you would like to help us fix a bug or add a new feature, please check our\n[guidelines](CONTRIBUTING.md). Pull requests are welcome!\n\n\u003c!-- Thanks go to our wonderful contributors: --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START --\u003e\n\u003c!-- prettier-ignore --\u003e\n\u003c!--\n\u003ctable\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ca href=\"https://fosstodon.org/@ehmicky\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/8136211?v=4\" width=\"100px;\" alt=\"ehmicky\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eehmicky\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/ehmicky/unix-permissions/commits?author=ehmicky\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#design-ehmicky\" title=\"Design\"\u003e🎨\u003c/a\u003e \u003ca href=\"#ideas-ehmicky\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"https://github.com/ehmicky/unix-permissions/commits?author=ehmicky\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n--\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fehmicky%2Funix-permissions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fehmicky%2Funix-permissions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fehmicky%2Funix-permissions/lists"}