Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ashur/nova-npm-executable
Helper for managing external NPM module executables in Nova extensions
https://github.com/ashur/nova-npm-executable
nova nova-extension
Last synced: 25 days ago
JSON representation
Helper for managing external NPM module executables in Nova extensions
- Host: GitHub
- URL: https://github.com/ashur/nova-npm-executable
- Owner: ashur
- Created: 2021-12-10T17:09:16.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2021-12-10T17:20:03.000Z (about 3 years ago)
- Last Synced: 2025-01-19T21:50:59.513Z (about 1 month ago)
- Topics: nova, nova-extension
- Language: JavaScript
- Homepage:
- Size: 68.4 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# nova-npm-executable
If your [Nova][nova] extension relies on an NPM package's executable, it's a good idea to provide a fallback or default installation.
Users of your extension might already have the package installed globally or as a dependency of a given project. If so, your extension can prefer those locations automatically. However, if the user doesn't have the package installed, providing a fallback instance is a helpful way of letting them get started without having to install tools on the command line.
**nova-npm-executable** provides a helper class to make offering this functionality easier:
- Install the fallback package inside the Nova extension bundle
- Instantiate a `Process` instance constructed with options that are ideal for running the executable in the user's environment## Installation
```
npm install --save nova-npm-executable
```> See [Using NPM Packages in Nova Extensions](https://www.notion.so/panic/Using-NPM-Packages-in-Nova-Extensions-325de853aba647839f1dc7a8d77bbac4) for information on structuring your project and using a module bundler to include the **nova-npm-executable** API in your extension.
## Defining Extension Dependencies
In addition to your project's top-level `package.json`, your extension bundle should also include its own `package.json` file. Use this to define the package or packages whose CLI executables you wish to install as a fallback.
For example, if you are building a JSONLint extension that relies on the [`jsonlint`](https://www.npmjs.com/package/jsonlint) executable:
```shell
cd nova-jsonlint/JSONLint.novaextension
npm install --save jsonlint
```> ⚠️ `NPMExecutable.install` will only install packages defined in `dependencies`, not from `devDependencies`.
## Usage
```javascript
const {NPMExecutable} = require( "nova-npm-executable" );
```### Examples
Check whether the fallback dependency has been installed inside the extension bundle, and install it if not:
```javascript
class JSONLint
{
constructor()
{
this.jsonlint = new NPMDependency( "jsonlint" );
if( !this.jsonlint.isInstalled )
{
this.jsonlint.install()
.catch( error =>
{
console.error( error );
});
}
```## API
### constructor(binName)
- `{string} binName` - The name of the executable found in `node_modules/.bin`
Example:
```javascript
let jsonlint = new NPMExecutable("jsonlint");
```### install()
Install NPM dependencies defined in the `package.json` file located inside your extension bundle.
> See [Defining Extension Dependencies](#defining-extension-dependencies) for more information.
↩️ Returns `Promise`, which resolves or rejects depending on the success of installation
### isInstalled
Whether the package has already been installed inside the extension bundle.
↩️ Returns `boolean`
### process(options)
- `{Object} options`
- `{[string]} [options.args]`
- `{string} [options.cwd]`
- `{Object} [options.env]`
- `{string|boolean} [options.shell]`
- `{[string]} [options.stdio]`Helper function for instantiating `Process` object with options needed to run the module executable using `npx`.
In addition to constructing `Process` arguments as `["npx",""]`, `process()` automatically augments the user's `$PATH` to create a preferential cascade of possible executable locations:
1. Current Workspace
1. Global Installation
1. Extension Bundle> 💡 If the user is working in a project, for example, which defines a specific version of your extension's executable, that installation will be preferred, followed by any version they may have installed globally via `npm install -g`, followed finally by your extension's fallback.
Example:
```javascript
/**
* Write a string to the JSONLint process's STDIN. Equivalent to running
* `echo | npx jsonlint -c` on the command line.
*
* @param {String} string
* @param {String} fileURI
* @return {Promise}
*/
async lint( string, fileURI )
{
try
{
let process = await this.jsonlint.process( { args: ["-c"] } );let output = "";
process.onStdout( line => output += line.trimRight() );
process.onStderr( line => output += line.trimRight() );
process.onDidExit( status =>
{
let results = status === 0 ? [] : this.parseOutput( output );
this.report( results, fileURI );
});process.start();
let writer = process.stdin.getWriter();
writer.write( string );
writer.close();
```↩️ Returns `Promise`, which resolves with an pre-instantiated `Process` object.
[api]: ./docs/README.md
[jsonlint]: https://www.npmjs.com/package/jsonlint
[nova]: https://panic.com/nova