UNPKG

7.03 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 // prune the .netrc file if it is only whitespace
123 if (body.trim() === '')
124 body = '';
125 let lex = require('./lex').default;
126 const tokens = lex(body);
127 let cur = this;
128 for (let token of tokens) {
129 switch (token.type) {
130 case 'default':
131 cur = new Token.DefaultMachine(token);
132 this.addToken(cur);
133 break;
134 case 'machine':
135 cur = new Token.Machine(token);
136 this.addToken(cur);
137 break;
138 case 'newline':
139 cur = this;
140 cur.addToken(token);
141 break;
142 default:
143 cur.addToken(token);
144 }
145 }
146 this._machines = Token.machinesProxy(this._tokens);
147 }
148 get gpgDecryptArgs() {
149 const args = ['--batch', '--quiet', '--decrypt', this.file];
150 debug('running gpg with args %o', args);
151 return args;
152 }
153 readFile() {
154 return tslib_1.__awaiter(this, void 0, void 0, function* () {
155 const decryptFile = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
156 const execa = require('execa');
157 const { code, stdout } = yield execa('gpg', this.gpgDecryptArgs, { stdio });
158 if (code !== 0)
159 throw new Error(`gpg exited with code ${code}`);
160 return stdout;
161 });
162 if (path.extname(this.file) === '.gpg')
163 return yield decryptFile();
164 else {
165 return new Promise((resolve, reject) => {
166 fs.readFile(this.file, { encoding: 'utf8' }, (err, data) => {
167 if (err && err.code !== 'ENOENT')
168 reject(err);
169 resolve(data || '');
170 });
171 });
172 }
173 });
174 }
175 readFileSync() {
176 const decryptFile = () => {
177 const execa = require('execa');
178 const { stdout, status } = execa.sync('gpg', this.gpgDecryptArgs, { stdio });
179 if (status)
180 throw new Error(`gpg exited with code ${status}`);
181 return stdout;
182 };
183 if (path.extname(this.file) === '.gpg')
184 return decryptFile();
185 else {
186 try {
187 return fs.readFileSync(this.file, 'utf8');
188 }
189 catch (err) {
190 if (err.code !== 'ENOENT')
191 throw err;
192 return '';
193 }
194 }
195 }
196 get homedir() {
197 return ((os.platform() === 'win32' &&
198 (process.env.HOME ||
199 (process.env.HOMEDRIVE && process.env.HOMEPATH && path.join(process.env.HOMEDRIVE, process.env.HOMEPATH)) ||
200 process.env.USERPROFILE)) ||
201 os.homedir() ||
202 os.tmpdir());
203 }
204 defaultFile() {
205 let file = path.join(this.homedir, os.platform() === 'win32' ? '_netrc' : '.netrc');
206 return fs.existsSync(file + '.gpg') ? (file += '.gpg') : file;
207 }
208}
209exports.Netrc = Netrc;
210exports.default = new Netrc();