UNPKG

6.92 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const fs = require("fs");
5const os = require("os");
6const path = require("path");
7const Token = require("./token");
8let _debug;
9function debug(...args) {
10 try {
11 if (process.env.NETRC_PARSER_DEBUG !== '1')
12 return;
13 if (!_debug)
14 _debug = require('debug')('netrc-parser');
15 _debug(...args);
16 }
17 catch (err) { }
18}
19const stdio = [0, null, 2];
20/**
21 * parses a netrc file
22 */
23class Netrc extends Token.Base {
24 /**
25 * generates or parses a netrc file
26 * @example
27 * const {Netrc} = require('netrc-parser')
28 * const netrc = new Netrc()
29 * netrc.machines['api.heroku.com'].password // get auth token from ~/.netrc
30 */
31 constructor(file) {
32 super();
33 this._file = file;
34 }
35 get file() {
36 return this._file;
37 }
38 get machines() {
39 return this._machines;
40 }
41 get default() {
42 return this._tokens.find(t => t.type === 'default');
43 }
44 set default(v) {
45 let idx = this._tokens.findIndex(t => t.type === 'default');
46 if (idx !== -1 && !v)
47 this._tokens.splice(idx, 1);
48 else {
49 let newMachine = new Token.DefaultMachine(Object.assign({}, v, { post: '\n' }));
50 if (idx !== -1 && v)
51 this._tokens[idx] = newMachine;
52 else if (v)
53 this._tokens.push(newMachine);
54 }
55 }
56 load() {
57 return tslib_1.__awaiter(this, void 0, void 0, function* () {
58 if (!this._file)
59 this._file = yield this.defaultFile();
60 this.parse(yield this.readFile());
61 });
62 }
63 loadSync() {
64 if (!this._file)
65 this._file = this.defaultFile();
66 this.parse(this.readFileSync());
67 }
68 /**
69 * save the current home netrc with any changes
70 * @example
71 * const Netrc = require('netrc-parser')
72 * const netrc = new Netrc()
73 * await netrc.load()
74 * netrc.machines['api.heroku.com'].password = 'newpassword'
75 * netrc.save()
76 */
77 save() {
78 return this.write(this.content);
79 }
80 /**
81 * save the current home netrc with any changes
82 * @example
83 * const Netrc = require('netrc-parser')
84 * const netrc = new Netrc()
85 * netrc.loadSync()
86 * netrc.machines['api.heroku.com'].password = 'newpassword'
87 * netrc.saveSync()
88 */
89 saveSync() {
90 this.writeSync(this.content);
91 }
92 get gpgEncryptArgs() {
93 const args = ['-a', '--batch', '--default-recipient-self', '-e'];
94 debug('running gpg with args %o', args);
95 return args;
96 }
97 write(body) {
98 return tslib_1.__awaiter(this, void 0, void 0, function* () {
99 if (this.file.endsWith('.gpg')) {
100 const execa = require('execa');
101 const { stdout, code } = yield execa('gpg', this.gpgEncryptArgs, { input: body, stdio: [null, null, 2] });
102 if (code)
103 throw new Error(`gpg exited with code ${code}`);
104 body = stdout;
105 }
106 return new Promise((resolve, reject) => {
107 fs.writeFile(this.file, body, { mode: 0o600 }, err => (err ? reject(err) : resolve()));
108 });
109 });
110 }
111 writeSync(body) {
112 if (this.file.endsWith('.gpg')) {
113 const execa = require('execa');
114 const { stdout, code } = execa.sync('gpg', this.gpgEncryptArgs, { input: body, stdio: [null, null, 2] });
115 if (code)
116 throw new Error(`gpg exited with code ${status}`);
117 body = stdout;
118 }
119 fs.writeFileSync(this.file, body, { mode: 0o600 });
120 }
121 parse(body) {
122 let lex = require('./lex').default;
123 const tokens = lex(body);
124 let cur = this;
125 for (let token of tokens) {
126 switch (token.type) {
127 case 'default':
128 cur = new Token.DefaultMachine(token);
129 this.addToken(cur);
130 break;
131 case 'machine':
132 cur = new Token.Machine(token);
133 this.addToken(cur);
134 break;
135 case 'newline':
136 cur = this;
137 cur.addToken(token);
138 break;
139 default:
140 cur.addToken(token);
141 }
142 }
143 this._machines = Token.machinesProxy(this._tokens);
144 }
145 get gpgDecryptArgs() {
146 const args = ['--batch', '--quiet', '--decrypt', this.file];
147 debug('running gpg with args %o', args);
148 return args;
149 }
150 readFile() {
151 return tslib_1.__awaiter(this, void 0, void 0, function* () {
152 const decryptFile = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
153 const execa = require('execa');
154 const { code, stdout } = yield execa('gpg', this.gpgDecryptArgs, { stdio });
155 if (code !== 0)
156 throw new Error(`gpg exited with code ${code}`);
157 return stdout;
158 });
159 if (path.extname(this.file) === '.gpg')
160 return yield decryptFile();
161 else {
162 return new Promise((resolve, reject) => {
163 fs.readFile(this.file, { encoding: 'utf8' }, (err, data) => {
164 if (err && err.code !== 'ENOENT')
165 reject(err);
166 resolve(data || '');
167 });
168 });
169 }
170 });
171 }
172 readFileSync() {
173 const decryptFile = () => {
174 const execa = require('execa');
175 const { stdout, status } = execa.sync('gpg', this.gpgDecryptArgs, { stdio });
176 if (status)
177 throw new Error(`gpg exited with code ${status}`);
178 return stdout;
179 };
180 if (path.extname(this.file) === '.gpg')
181 return decryptFile();
182 else {
183 try {
184 return fs.readFileSync(this.file, 'utf8');
185 }
186 catch (err) {
187 if (err.code !== 'ENOENT')
188 throw err;
189 return '';
190 }
191 }
192 }
193 get homedir() {
194 return ((os.platform() === 'win32' &&
195 (process.env.HOME ||
196 (process.env.HOMEDRIVE && process.env.HOMEPATH && path.join(process.env.HOMEDRIVE, process.env.HOMEPATH)) ||
197 process.env.USERPROFILE)) ||
198 os.homedir() ||
199 os.tmpdir());
200 }
201 defaultFile() {
202 let file = path.join(this.homedir, os.platform() === 'win32' ? '_netrc' : '.netrc');
203 return fs.existsSync(file + '.gpg') ? (file += '.gpg') : file;
204 }
205}
206exports.Netrc = Netrc;
207exports.default = new Netrc();