🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

aperture

Package Overview
Dependencies
Maintainers
3
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aperture - npm Package Compare versions

Comparing version

to
2.0.0

LICENSE.md

111

index.js

@@ -1,9 +0,104 @@

module.exports = {
bulk: require('./commands/bulk')
, open: require('./commands/open')
, link: require('./commands/link')
, list: require('./commands/list')
, purge: require('./commands/purge')
, config: require('./commands/config')
, expand: require('./commands/expand')
const path = require('path');
const execa = require('execa');
const tmp = require('tmp');
// TODO: log in production with proces.env.DEBUG_APERTURE
function log(...msgs) {
if (process.env.DEBUG) {
console.log(...msgs);
}
}
class Aperture {
getAudioSources() {
return execa(path.join(__dirname, 'swift', 'main'), ['list-audio-devices']).then(result => {
return JSON.parse(result.stdout);
});
}
// resolves if the recording started successfully
// rejects if the recording didn't started after 5 seconds or if some error
// occurs during the recording session
startRecording({
fps = 30,
cropArea = 'none', // can be 'none' or {x, y, width, height} – TODO: document this
showCursor = true,
highlightClicks = false,
displayId = 'main',
audioSourceId = 'none' // one of the `id`s from getAudioSources()
} = {}) {
return new Promise((resolve, reject) => {
this.tmpPath = tmp.tmpNameSync({postfix: '.mp4'});
if (typeof cropArea === 'object') { // TODO validate this
cropArea = `${cropArea.x}:${cropArea.y}:${cropArea.width}:${cropArea.height}`;
}
const recorderOpts = [this.tmpPath, fps, cropArea, showCursor, highlightClicks, displayId, audioSourceId];
this.recorder = execa(path.join(__dirname, 'swift', 'main'), recorderOpts);
const timeout = setTimeout(() => {
const err = new Error('unnable to start the recorder after 5 seconds');
err.code = 'RECORDER_TIMEOUT';
this.recorder.kill();
reject(err);
}, 5000);
this.recorder.stdout.on('data', data => {
data = data.toString();
log(data);
if (data.replace(/\n|\s/gm, '') === 'R') {
// `R` is printed by Swift when the recording **actually** starts
clearTimeout(timeout);
resolve(this.tmpPath);
}
});
this.recorder.on('error', reject); // TODO handle this;
this.recorder.on('exit', code => {
clearTimeout(timeout);
let err;
if (code === 0) {
return; // we're good
} else if (code === 1) {
err = new Error('malformed arguments'); // TODO
} else if (code === 2) {
err = new Error('invalid coordinates'); // TODO
} else {
err = new Error('unknown error'); // TODO
}
reject(err);
});
});
}
stopRecording() {
return new Promise((resolve, reject) => {
if (this.recorder === undefined) {
reject('call `startRecording` first');
}
this.recorder.on('exit', code => {
// at this point the movie file has been fully written to the file system
if (code === 0) {
delete this.recorder;
resolve(this.tmpPath);
// TODO: this file is deleted when the program exits
// maybe we should add a note about this on the docs or implement a workaround
delete this.tmpPath;
} else {
reject(code); // TODO
}
});
this.recorder.kill();
});
}
}
module.exports = () => new Aperture();

70

package.json
{
"name": "aperture",
"version": "1.1.1",
"description": "Local dependencies helper",
"main": "index.js",
"version": "2.0.0",
"description": "Record the screen on macOS",
"license": "MIT",
"repository": "wulkano/aperture",
"author": "Matheus Fernandes <npm@matheus.top> (https://matheus.top)",
"scripts": {
"test": "tape test/*.js | tap-spec"
"test": "xo",
"build": "cd swift && xcodebuild && mv build/release/aperture main && rm -r build",
"prepublish": "npm run build"
},
"bin": {
"aperture": "./aperture.js"
},
"author": "Hugh Kennedy <hughskennedy@gmail.com> (http://hughsk.io/)",
"contributors": [
"Tim Oxley"
],
"dependencies": {
"flatten": "0.0.1",
"once": "~1.3.0",
"uniq": "0.0.2",
"map-async": "~0.1.1",
"rimraf": "~2.2.6",
"mkdirp": "~0.3.5",
"optimist": "~0.6.0",
"readdirp": "~0.3.3",
"through2": "~0.4.1",
"globs": "~0.1.1",
"findup": "~0.1.3",
"async-series": "0.0.1",
"pluck": "0.0.4",
"chalk": "~0.4.0",
"semver": "^2.2.1",
"npm-stats": "^0.3.0",
"map-limit": "0.0.0"
"execa": "^0.5.0",
"tmp": "0.0.31"
},
"devDependencies": {
"directory-copy": "~0.1.0",
"quick-tmp": "0.0.0",
"tap-spec": "^0.2.0",
"tape": "~2.4.0"
"xo": "^0.17.0"
},
"directories": {
"test": "test"
},
"repository": {
"type": "git",
"url": "git://github.com/requireio/aperture.git"
},
"keywords": [
"npm",
"link",
"require",
"development",
"dev",
"install",
"dependency"
"files": [
"index.js",
"swift/main"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/requireio/aperture/issues"
},
"homepage": "https://github.com/requireio/aperture"
"xo": {
"space": true,
"esnext": true
}
}

@@ -1,203 +0,123 @@

# aperture #
<p>
<h1 align="center">aperture</h1>
<h3 align="center">A library for screen recording </h3>
<p align="center"><a href="https://github.com/sindresorhus/xo"><img src="https://img.shields.io/badge/code_style-XO-5ed9c7.svg" alt="XO code style"></a></p>
</p>
Command-line tool to help with managing largeish amounts of local dependencies
in `node_modules` for a single project.
## Install
## Usage ##
``` bash
npm install -g aperture
```
npm install aperture
```
Usage:
aperture <command> [options]
Commands:
open links, installs and purges your dependencies for fresh projects.
link Sets up the local links in the target directory.
list Lists the modules configured to be linked.
bulk Runs a shell command from each linked module.
install Intelligently install your node dependencies for local development.
config Print out the current config being used.
expand Expand any globs present in `aperture.sources`.
purge Permanently removes any module duplicates which should
be linked in the tree.
## Usage
```javascript
const aperture = require('aperture')();
Options:
-b, --bail Exit early on reaching an error during "aperture bulk".
-v, --version Output the current version and exit
-d, --cwd Target a different directory for this command.
Default: current directory
```
const cropArea = {x: 100, y: 100, width: 500, height: 500};
### package.json ###
aperture.startRecording({fps: 30, cropArea})
.then(filePath => setTimeout(stopRecording, 3000));
Configuration is added to a `package.json` file at the root of your project,
e.g.:
function stopRecording() {
aperture.stopRecording()
.then(console.log); //=> /var/folders/r9/65knbqts47x3yg055cd739qh0000gn/T/tmp-15694AAzbYX1vzi2X.mp4
}
``` json
{
"aperture": {
"sources": [
"utils/custom-element",
"utils/ajax-data",
"features/*"
]
}
}
```
Where `aperture.sources` should be an array of package directories – globs are
supported too.
## API
### aperture init ###
### instance = aperture()
Provided the configuration has been set up correctly, you can run
this command to set up the dependencies for a fresh project. Essentially,
it's the equivalent of this:
### instance.startRecording([options])
``` bash
aperture link &&
aperture bulk -- npm install --color=always &&
aperture purge
```
Returns a promise for the path to the screen recording file.
But is none-the-less included for convenience. For more flexibility and faster
updates after the initial setup, the commands that follow are likely to be
useful.
### instance.stopRecording()
### aperture link ###
Returns a promise for the path to the screen recording file.
Now, to symlink these directories to the top-level, just run this for your
project's root:
### instance.getAudioSources()
``` bash
aperture link
Get a list of audio sources.
Example:
```js
[{
id: 'AppleHDAEngineInput:1B,0,1,0:1',
name: 'Built-in Microphone'
}]
```
### aperture bulk ###
#### options
If you've just cloned the project repo, you probably don't want to visit
each local dependency to get `npm install` or any other setup commands running.
This is easily fixed with `aperture bulk`, which runs your chosen command from
each source's directory:
##### fps
``` bash
# Install dependencies for all of the local modules
# defined in "aperture.sources"
aperture bulk npm install
Type: `number`<br>
Default: `30`
# Remove the currently installed node_modules
# folder for each local module. Note the use of --
# to allow for the -rf flags.
aperture bulk -- rm -rf node_modules
```
Number of frames per seconds.
By default, each script will run whether or not the previous one executed
successfully. You can change this behavior using the `--bail` flag:
##### cropArea
``` bash
$ aperture bulk --bail -- bash -c 'echo hello && exit 1'
hello
Type: `Object` `string`<br>
Default: `'none'`
Error: Invalid exit code: 1
```
Record only an area of the screen. Accepts an object with `x`, `y`, `width`, `height` properties.
### aperture install ###
##### showCursor
In practice, `aperture bulk npm install` works, but can take *a long time*
when projects share a lot of common dependencies. The `install` command is
a little smarter about this, and will install each linked module's dependencies
for you in a way that minimises duplicate packages.
Type: `boolean`<br>
Default: `true`
Essentially, aperture will build a list of the dependencies required for each
project and their expected version. For each dependency:
Show the cursor in the screen recording.
* Check if all of the versions are compatible, and if so install them once
in the root directory, alongside your linked modules.
* Otherwise, install that module as normal.
##### highlightClicks
This can result in significant speedups (and a smaller `node_modules` folder)
for installs when working on larger projects.
Type: `boolean`<br>
Default: `false`
### aperture purge ###
Highlight cursor clicks in the screen recording.
The last remaining thing to do is remove any other dependencies or symlinks
hidden in the tree that might conflict with your new top-level ones:
##### displayId
``` bash
aperture purge
```
Type: `string`<br>
Default: `main`
*Use the above command with caution!* It will `rm -rf` any conflicting
packages it finds along the way, and while the effects won't leave the project
directory you should make sure all your changes have been checked in properly.
Display to record.
After that, it should be set up, and you just need to run `aperture link`
every time a new dependency has been added.
##### audioSourceId
### aperture expand ###
Type: `Object` `string`<br>
Default: `'none'`
Glob patterns work well for early development, but once a project starts to
solidify it can be useful to return to explicit dependencies, much like
the `dependencies` field is always explicit.
Audio source to include in the screen recording. Should be one of the `id`'s from `instance.getAudioSources()`.
When you're ready, simply run `aperture expand` to convert your glob patterns
into explicit module paths. As an example, the following:
``` json
{
"name": "my-app",
"aperture": {
"sources": ["utils-*/*"]
}
}
```
## Why
Might become something like this:
`aperture` was built to fulfill the needs of [Kap](https://github.com/wulkano/kap), providing a JavaScript interface to the **best** available method for recording the screen.
That's why it's currently a wrapper for a [Swift script](https://github.com/wulkano/aperture/blob/master/swift/aperture/main.swift) that records the screen using the [AVFoundation framework](https://developer.apple.com/av-foundation/).
``` json
{
"name": "my-app",
"aperture": {
"sources": [
"utils-1/module-a",
"utils-1/module-c",
"utils-2/module-b",
"utils-2/module-d"
]
}
}
```
#### But you can use `ffmpeg -f avfoundation...`
### aperture list ###
Yes, we can, but the performance is terrible:
You can list all of the module directories that should be linked locally using
this command:
#### Recording the entire screen with `ffmpeg -f avfoundation -i 1 -y test.mp4`:
``` bash
$ aperture list
/Users/hughsk/myproject/features/config
/Users/hughsk/myproject/features/credentials
/Users/hughsk/myproject/features/progress
/Users/hughsk/myproject/utils/ajax-data
/Users/hughsk/myproject/utils/custom-element
/Users/hughsk/myproject/utils/polyfill-webcomponents
/Users/hughsk/myproject/utils/render-template
```
![ffmpeg](https://cloud.githubusercontent.com/assets/4721750/19214740/f823d4b6-8d60-11e6-8af3-4726146ef29a.jpg)
### aperture config ###
#### Recording the entire screen with `aperture`:
Quickly print out the project's current config using this command:
![aperture](https://cloud.githubusercontent.com/assets/4721750/19214743/11f4aaaa-8d61-11e6-9822-4e83bcdfab24.jpg)
``` bash
$ aperture config
{
"sources": [
"utils/*",
"features/*"
]
}
```
## Linux and Windows
We want to bring `aperture` to Linux and Windows, but we don't have time and resources for such tasks (we're Mac users), so **any help is more than welcome**. We just want to enforce two things: **performance** and **quality** – it doesn't matter how (`ffmpeg`, custom built native lib, etc) they are achieved.
## Upcoming
`aperture` is in its early days. We're working on adding more features, such as *export to GIF*, compression options, support for multiple displays, support for audio and much more. Check out our [`aperture`](https://github.com/wulkano/kap/issues?q=is%3Aissue+is%3Aopen+label%3Aaperture) issues on **Kap** to learn more.