Awesome
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ehmicky/design/main/unix-permissions/unix-permissions_dark.png"/> <img alt="unix-permissions logo" src="https://raw.githubusercontent.com/ehmicky/design/main/unix-permissions/unix-permissions.png" width="500"/> </picture>Swiss Army knife for Unix permissions.
Unix file permissions
can take many shapes: symbolic
(ug+rw
), octal (660
) or a
list of characters (drw-rw----
). This library enables
using any of these (instead of being limited to a single
one) with any Node.js or CLI command.
This library can also perform operations on Unix permissions such as:
- testing,
setting and
unsetting. Using bitwise operations (
|
,&
,^
,~
) can be tedious and error-prone otherwise. - validating syntax.
- normalizing. For example
u+r,u+w
can be shortened tou+rw
. - inverting. For example a
umask
of117
means new files will be created with661
permissions. - checking the minimal or maximal permissions among a list of them. This can be useful to aggregate all the permissions of several files, e.g. during a directory recursion.
Permissions are manipulated as strings, not as file paths. This means you must
use other utilities (such as chmod
or
stat
) to get and set file permissions
using those strings.
Hire me
Please reach out if you're looking for a Node.js API or CLI engineer (11 years of experience). Most recently I have been Netlify Build's and Netlify Plugins' technical lead for 2.5 years. I am available for full-time remote positions.
Examples
In JavaScript:
<!-- eslint-disable n/no-sync -->import { convert } from 'unix-permissions'
// Retrieve a file's permission as an object like
// `{ user: { write: false, read: true, ... }, ... }` instead of a number
convert.object(fs.statSync('/etc/passwd').mode)
// Set a file's permission using `symbolic` notation instead of a number
fs.chmod('/etc/passwd', convert.number('a=r'))
// Set a file's permission using `symbolic` notation instead of a number
fs.writeFile('/my/file', content, { mode: convert.number('a=r') })
// Disallow executing new files using `umask`
process.umask(convert.number(invert('a-x')))
// If your library takes Unix permissions as input, using
// `unix-permissions` under the hood lets your users choose their
// favorite Unix permissions type.
myLibrary.method({ mode: 'a-wx' })
myLibrary.method({ mode: '444' })
On the command line:
$ stat -c "%a" /etc/passwd
644
$ unix-permissions convert.symbolic "$(stat -c "%a" /etc/passwd)"
u=rw,go=r
Install
npm install unix-permissions
This package works in both Node.js >=18.18.0 and browsers.
This is an ES module. It must be loaded using
an import
or import()
statement,
not require()
. If TypeScript is used, it must be configured to
output ES modules,
not CommonJS.
Usage (JavaScript)
import { convert } from 'unix-permissions'
// `permission` will be set to `rw-rw----`
const permission = convert.stat('660')
Several methods other than convert
are available but they mostly follow the
same pattern. Permission strings are passed as input and returned as output.
Usage (CLI)
$ unix-permissions convert.stat 660
rw-rw----
The same methods as in JavaScript are available. Exit code will be 1
if an
error occurred, e.g. if the permission syntax is invalid.
Permission types
You can use any of the following permission types as input. You can also
convert()
between them:
octal
strings like"422"
- decimal
number
like274
stat
likerw-rw-r--
symbolic
likea+rw
object
like{ user: { read: true, write: false, execute: false }, group: { write: false }, others: { write: false } }
Special permissions (setuid, setgid, sticky) can be used.
Please see the types full documentation.
Methods
convert.octal|number|stat|symbolic|object(permission)
Converts permission
to another type.
Full documentation.
type(permission)
Returns the permission
's type or invalid
.
Full documentation.
normalize(permission)
Normalizes a permission
to its canonical shape. Throw if permission
is
invalid.
Full documentation.
positive(permission)
Removes all negative permissions.
Full documentation.
contain(permission, permissions...)
Tests whether permission
includes permissions
.
Full documentation.
equal(permission, permissions...)
Tests whether permission
equals exactly permissions
.
Full documentation.
set(permission, permissions...)
Sets permissions
on permission
. This is useful to avoid error-prone bitwise
operations (|
, &
, ^
, ~
).
Full documentation.
not(permission)
Inverts permission
including special permissions. This can be used in
combination with set()
to unset permissions
instead of setting them.
Full documentation.
invert(permission)
Inverts permission
and removes special permissions.
Full documentation.
min(permissions...)
Retrieves the lowest permissions among all arguments.
Full documentation.
max(permissions...)
Retrieves the highest permissions among all arguments.
Full documentation.
Support
For any question, don't hesitate to submit an issue on GitHub.
Everyone is welcome regardless of personal background. We enforce a Code of conduct in order to promote a positive and inclusive environment.
Contributing
This project was made with ❤️. The simplest way to give back is by starring and sharing it online.
If the documentation is unclear or has a typo, please click on the page's Edit
button (pencil icon) and suggest a correction.
If you would like to help us fix a bug or add a new feature, please check our guidelines. Pull requests are welcome!
<!-- Thanks go to our wonderful contributors: --> <!-- ALL-CONTRIBUTORS-LIST:START --> <!-- prettier-ignore --> <!-- <table><tr><td align="center"><a href="https://fosstodon.org/@ehmicky"><img src="https://avatars2.githubusercontent.com/u/8136211?v=4" width="100px;" alt="ehmicky"/><br /><sub><b>ehmicky</b></sub></a><br /><a href="https://github.com/ehmicky/unix-permissions/commits?author=ehmicky" title="Code">💻</a> <a href="#design-ehmicky" title="Design">🎨</a> <a href="#ideas-ehmicky" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/ehmicky/unix-permissions/commits?author=ehmicky" title="Documentation">📖</a></td></tr></table> --> <!-- ALL-CONTRIBUTORS-LIST:END -->