Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

netrc-parser

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

netrc-parser - npm Package Compare versions

Comparing version 2.0.6 to 3.0.0

lib/lex.d.ts

433

lib/netrc.js

@@ -1,252 +0,209 @@

const fs = require('fs');
const os = require('os');
const path = require('path');
const Lexer = require('lex');
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fs = require("fs-extra");
const os = require("os");
const path = require("path");
const execa = require("execa");
const lex_1 = require("./lex");
const Token = require("./token");
let _debug;
function debug(...args) {
try {
if (!_debug) _debug = require('debug')('netrc-parser');
_debug(...args);
} catch (err) {}
}
function findIndex(arr, fn) {
for (let i = 0; i < arr.length; i++) {
if (fn(arr[i])) return i;
}
return -1;
}
function readFile(file) {
function decryptFile(file) {
const { spawnSync } = require('child_process');
const args = ['--batch', '--quiet', '--decrypt', file];
debug('running gpg with args %o', args);
const { stdout, status } = spawnSync('gpg', args, { stdio: [0, null, 2], encoding: 'utf8' });
if (status !== 0) throw new Error(`gpg exited with code ${status}`);
return stdout;
}
if (path.extname(file) === '.gpg') return addTrailingNewline(decryptFile(file));else {
try {
return addTrailingNewline(fs.readFileSync(file, 'utf8'));
} catch (err) {
if (err.code !== 'ENOENT') throw err;
return '';
if (process.env.NETRC_PARSER_DEBUG !== '1')
return;
if (!_debug)
_debug = require('debug')('netrc-parser');
_debug(...args);
}
}
catch (err) { }
}
function lex(body) {
let tokens = [];
let lexer = new Lexer(char => {
throw new Error(`Unexpected character during netrc parsing at character ${char}:
${body}`);
});
lexer.addRule(/\s+/, content => {
tokens.push({ type: 'whitespace', content });
}, [0, 1]);
lexer.addRule(/#.*/, content => {
tokens.push({ type: 'comment', content });
}, [0, 1]);
lexer.addRule(/macdef/g, function (content) {
this.state = 3;
tokens.push({ type: 'macdef', content });
}, [0, 1, 3]);
lexer.addRule(/machine +(\S+)/, function (content, value) {
this.state = 1;
tokens.push({ type: 'machine', content, value });
}, [0, 1, 3]);
lexer.addRule(/[\s\S\n]/, function (content) {
tokens[tokens.length - 1].content += content;
}, [3]);
lexer.addRule(/([a-zA-Z]+) +(\S+)/, (content, name, value) => {
tokens.push({ type: 'prop', name, value });
}, [1]);
lexer.addRule(/default/, function (content) {
this.state = 1;
tokens.push({ type: 'default', content });
}, [0]);
lexer.setInput(body).lex();
return tokens;
}
function machineProxy(machine) {
const props = () => machine._tokens.filter(t => t.type === 'prop');
const loadProps = () => props().forEach(prop => {
machine[prop.name] = prop.value;
});
loadProps();
return new Proxy(machine, {
set: (machine, name, value) => {
if (name === '_tokens') {
machine._tokens = value;
loadProps();
return true;
}
machine[name] = value;
let prop = props().find(p => p.name === name);
if (prop) prop.value = value;else {
let lastPropIdx = findIndex(machine._tokens, t => t.type === 'prop');
let whitespace = lastPropIdx === -1 ? { type: 'whitespace', content: '\n ' } : machine._tokens[lastPropIdx - 1];
machine._tokens.splice(lastPropIdx, 0, whitespace); // insert whitespace
machine._tokens.splice(lastPropIdx, 0, { type: 'prop', name, value });
}
return true;
}
});
}
function machinesProxy(content) {
function addNewMachine(host) {
let machine = machineProxy({
type: 'machine',
value: host,
_tokens: [{ type: 'machine', value: host, content: `machine ${host}` }, { type: 'whitespace', content: '\n' }]
});
content.push(machine);
return machine;
}
return new Proxy({}, {
get: (machines, host) => {
if (typeof host !== 'string') return machines[host];
if (!machines[host]) machines[host] = addNewMachine(host);
return machines[host];
},
set: (machines, host, value) => {
if (!machines[host]) machines[host] = addNewMachine(host);
machines[host] = machineProxy(value);
return true;
},
deleteProperty: (machines, host) => {
if (!machines[host]) return false;
delete machines[host];
for (let i = 0; i < content.length; i++) {
if (content[i].type === 'machine' && content[i].value === host) {
content.splice(i, 1);
}
}
return true;
}
});
}
function addTrailingNewline(s) {
if (s.endsWith('\n')) return s;
return s + '\n';
}
function homedir() {
return os.platform() === 'win32' && (process.env.HOME || process.env.HOMEDRIVE && process.env.HOMEPATH && path.join(process.env.HOMEDRIVE, process.env.HOMEPATH) || process.env.USERPROFILE) || os.homedir() || os.tmpdir();
}
const stdio = [0, null, 2];
/**
* parses a netrc file
*/
class Netrc {
/**
* generates or parses a netrc file
* @example
* const Netrc = require('netrc-parser')
* const netrc = new Netrc()
* netrc.machines['api.heroku.com'].password // get auth token from ~/.netrc
*/
constructor(file) {
if (!file) {
file = path.join(homedir(), os.platform() === 'win32' ? '_netrc' : '.netrc');
if (fs.existsSync(file + '.gpg')) file += '.gpg';
class Netrc extends Token.Base {
/**
* generates or parses a netrc file
* @example
* const {Netrc} = require('netrc-parser')
* const netrc = new Netrc()
* netrc.machines['api.heroku.com'].password // get auth token from ~/.netrc
*/
constructor(file) {
super();
this._file = file;
}
this._tokens = [];
this.file = file;
this.machines = machinesProxy(this._tokens);
this._parse();
}
/**
* save the current home netrc with any changes
* @example
* const Netrc = require('netrc-parser')
* const netrc = new Netrc()
* netrc.machines['api.heroku.com'].password = 'newpassword'
* netrc.save()
*/
save() {
let body = this._tokens.map(t => {
switch (t.type) {
case 'default':
case 'machine':
let tokens = t._tokens || [];
return tokens.map(t => {
switch (t.type) {
case 'prop':
return `${t.name} ${t.value}`;
case 'machine':
case 'default':
case 'comment':
case 'whitespace':
return t.content;
get file() {
return this._file;
}
get machines() {
return this._machines;
}
get default() {
return this._tokens.find(t => t.type === 'default');
}
set default(v) {
let idx = this._tokens.findIndex(t => t.type === 'default');
if (idx !== -1 && !v)
this._tokens.splice(idx, 1);
else {
let newMachine = new Token.DefaultMachine(Object.assign({}, v, { post: '\n' }));
if (idx !== -1 && v)
this._tokens[idx] = newMachine;
else if (v)
this._tokens.push(newMachine);
}
}
load() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!this._file)
this._file = yield this.defaultFile();
this.parse(yield this.readFile());
});
}
loadSync() {
if (!this._file)
this._file = this.defaultFileSync();
this.parse(this.readFileSync());
}
/**
* save the current home netrc with any changes
* @example
* const Netrc = require('netrc-parser')
* const netrc = new Netrc()
* await netrc.load()
* netrc.machines['api.heroku.com'].password = 'newpassword'
* netrc.save()
*/
save() {
return this.write(this.content);
}
/**
* save the current home netrc with any changes
* @example
* const Netrc = require('netrc-parser')
* const netrc = new Netrc()
* netrc.loadSync()
* netrc.machines['api.heroku.com'].password = 'newpassword'
* netrc.saveSync()
*/
saveSync() {
this.writeSync(this.content);
}
get gpgEncryptArgs() {
const args = ['-a', '--batch', '--default-recipient-self', '-e'];
debug('running gpg with args %o', args);
return args;
}
write(body) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.file.endsWith('.gpg')) {
const { stdout, code } = yield execa('gpg', this.gpgEncryptArgs, { input: body, stdio: [null, null, 2] });
if (code !== 0)
throw new Error(`gpg exited with code ${code}`);
body = stdout;
}
}).join('');
case 'macdef':
case 'comment':
case 'whitespace':
return t.content;
}
}).join('');
this._write(body);
}
_write(body) {
if (this.file.endsWith('.gpg')) {
const { spawnSync } = require('child_process');
const args = ['-a', '--batch', '--default-recipient-self', '-e'];
debug('running gpg with args %o', args);
const { stdout, status } = spawnSync('gpg', args, {
input: body,
stdio: [null, 'pipe', 2],
encoding: 'utf8'
});
if (status !== 0) throw new Error(`gpg exited with code ${status}`);
body = stdout;
yield fs.writeFile(this.file, body, { mode: 0o600 });
});
}
fs.writeFileSync(this.file, body, { mode: 0o600 });
}
_parse() {
let tokens = lex(readFile(this.file));
for (let i = 0; i < tokens.length; i++) {
let getMachineTokens = () => {
let machineTokens = [];
while (1) {
machineTokens.push(tokens[i]);
let next = tokens[i + 1];
if (!next || ['machine', 'default', 'macdef'].includes(next.type) || next.type === 'default') break;
i++;
writeSync(body) {
if (this.file.endsWith('.gpg')) {
const { stdout, status } = execa.sync('gpg', this.gpgEncryptArgs, { input: body, stdio: [null, null, 2] });
if (status !== 0)
throw new Error(`gpg exited with code ${status}`);
body = stdout;
}
return machineTokens;
};
switch (tokens[i].type) {
case 'macdef':
this._tokens.push(...getMachineTokens());
break;
case 'default':
this.default = machineProxy({ type: 'default', _tokens: getMachineTokens() });
this._tokens.push(this.default);
break;
case 'machine':
let host = tokens[i].value;
this.machines[host]._tokens = getMachineTokens();
break;
default:
this._tokens.push(tokens[i]);
}
fs.writeFileSync(this.file, body, { mode: 0o600 });
}
}
parse(body) {
const tokens = lex_1.default(body);
let cur = this;
for (let token of tokens) {
switch (token.type) {
case 'default':
cur = new Token.DefaultMachine(token);
this.addToken(cur);
break;
case 'machine':
cur = new Token.Machine(token);
this.addToken(cur);
break;
case 'newline':
cur = this;
cur.addToken(token);
break;
default:
cur.addToken(token);
}
}
this._machines = Token.machinesProxy(this._tokens);
}
get gpgDecryptArgs() {
const args = ['--batch', '--quiet', '--decrypt', this.file];
debug('running gpg with args %o', args);
return args;
}
readFile() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const decryptFile = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const { code, stdout } = yield execa('gpg', this.gpgDecryptArgs, { stdio });
if (code !== 0)
throw new Error(`gpg exited with code ${code}`);
return stdout;
});
if (path.extname(this.file) === '.gpg')
return yield decryptFile();
else {
try {
return yield fs.readFile(this.file, 'utf8');
}
catch (err) {
if (err.code !== 'ENOENT')
throw err;
return '';
}
}
});
}
readFileSync() {
const decryptFile = () => {
const { stdout, status } = execa.sync('gpg', this.gpgDecryptArgs, { stdio });
if (status !== 0)
throw new Error(`gpg exited with code ${status}`);
return stdout;
};
if (path.extname(this.file) === '.gpg')
return decryptFile();
else {
try {
return fs.readFileSync(this.file, 'utf8');
}
catch (err) {
if (err.code !== 'ENOENT')
throw err;
return '';
}
}
}
get homedir() {
return ((os.platform() === 'win32' &&
(process.env.HOME ||
(process.env.HOMEDRIVE && process.env.HOMEPATH && path.join(process.env.HOMEDRIVE, process.env.HOMEPATH)) ||
process.env.USERPROFILE)) ||
os.homedir() ||
os.tmpdir());
}
defaultFileSync() {
let file = path.join(this.homedir, os.platform() === 'win32' ? '_netrc' : '.netrc');
return fs.pathExistsSync(file + '.gpg') ? (file += '.gpg') : file;
}
defaultFile() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
let file = path.join(this.homedir, os.platform() === 'win32' ? '_netrc' : '.netrc');
return (yield fs.pathExists(file + '.gpg')) ? (file += '.gpg') : file;
});
}
}
module.exports = Netrc;
exports.Netrc = Netrc;
exports.default = Netrc;
{
"name": "netrc-parser",
"description": "netrc parser",
"version": "2.0.6",
"version": "3.0.0",
"author": "Jeff Dickey (@jdxcode)",
"bugs": "https://github.com/jdxcode/node-netrc-parser/issues",
"dependencies": {
"graceful-fs": "^4.1.11",
"lex": "^1.7.9"
},
"devDependencies": {
"babel-cli": "6.24.1",
"babel-eslint": "7.1.1",
"babel-plugin-transform-flow-strip-types": "6.22.0",
"@heroku-cli/tslint": "^1.1.2",
"@types/execa": "^0.8.1",
"@types/fs-extra": "^5.0.0",
"@types/graceful-fs": "^4.1.2",
"@types/jest": "^22.0.1",
"debug": "^3.1.0",
"documentation": "4.0.0-beta.18",
"flow-bin": "0.41.0",
"flow-copy-source": "1.1.0",
"fs-extra": "2.0.0",
"jest": "19.0.2",
"jest-junit": "1.3.0",
"rimraf": "2.6.1",
"standard": "9.0.1"
"fs-extra": "5.0.0",
"jest": "22.0.4",
"prettier": "^1.9.2",
"ts-jest": "^22.0.1",
"tslint": "^5.8.0",
"typescript": "^2.6.2"
},

@@ -35,18 +36,8 @@ "files": [

"scripts": {
"build": "babel src -d lib --ignore '*.test.js'",
"clean": "rimraf lib",
"copy-flow": "flow-copy-source -v -i '**/*.test.js' src lib",
"doc": "documentation readme --github -s API src/netrc.js",
"prepare": "npm run clean && npm run build && npm run copy-flow",
"test": "jest && flow && standard",
"version": "npm run doc && git add README.md",
"watch": "babel --watch src -d lib --ignore '*.test.js'"
"posttest": "prettier -l src/**/*.ts",
"prepare": "tsc",
"pretest": "tsc",
"test": "jest"
},
"standard": {
"parser": "babel-eslint",
"ignore": [
"lib",
"flow-typed"
]
}
"types": "lib/netrc.d.ts"
}
# netrc-parser
[![CircleCI](https://circleci.com/gh/dickeyxxx/node-netrc-parser.svg?style=svg)](https://circleci.com/gh/dickeyxxx/node-netrc-parser)
[![codecov](https://codecov.io/gh/dickeyxxx/node-netrc-parser/branch/master/graph/badge.svg)](https://codecov.io/gh/dickeyxxx/node-netrc-parser)
[![CircleCI](https://circleci.com/gh/jdxcode/node-netrc-parser/tree/master.svg?style=svg)](https://circleci.com/gh/jdxcode/node-netrc-parser/tree/master)
[![codecov](https://codecov.io/gh/jdxcode/node-netrc-parser/branch/master/graph/badge.svg)](https://codecov.io/gh/jdxcode/node-netrc-parser)
# API
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
## Netrc
[src/netrc.js:211-318](https://github.com/jdxcode/node-netrc-parser/blob/cfbdbb9020ee87a353f88ea423a36375e79da2e0/src/netrc.js#L211-L318 "Source code on GitHub")
parses a netrc file
### constructor
[src/netrc.js:219-228](https://github.com/jdxcode/node-netrc-parser/blob/cfbdbb9020ee87a353f88ea423a36375e79da2e0/src/netrc.js#L219-L228 "Source code on GitHub")
generates or parses a netrc file
**Parameters**
- `file` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
**Examples**
```javascript
const Netrc = require('netrc-parser')
const {Netrc} = require('netrc-parser')
const netrc = new Netrc()
netrc.loadSync() // or netrc.load() for async
netrc.machines['api.heroku.com'].password // get auth token from ~/.netrc
netrc.saveSync() // or netrc.save() for async
```
### save
[src/netrc.js:243-267](https://github.com/jdxcode/node-netrc-parser/blob/cfbdbb9020ee87a353f88ea423a36375e79da2e0/src/netrc.js#L243-L267 "Source code on GitHub")
save the current home netrc with any changes
**Examples**
```javascript
const Netrc = require('netrc-parser')
const netrc = new Netrc()
netrc.machines['api.heroku.com'].password = 'newpassword'
netrc.save()
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc