editorconfig 0.14.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ ## 0.15.0
2
+ - Convert source code into TypeScript. Generated type definitions are now provided.
3
+ - Remove dependency on Bluebird.
4
+ - **Breaking**: Node v4 no longer supported.
package/bin/editorconfig CHANGED
@@ -1,42 +1,3 @@
1
1
  #!/usr/bin/env node
2
-
3
- var path = require("path");
4
- var program = require("commander");
5
- var Promise = require("bluebird");
6
-
7
- var editorconfig = require("../editorconfig");
8
- var package = require("../package.json");
9
-
10
- program.version("EditorConfig Node.js Core Version " + package.version);
11
-
12
- program
13
- .usage([
14
- "[OPTIONS] FILEPATH1 [FILEPATH2 FILEPATH3 ...]",
15
- program._version,
16
- "FILEPATH can be a hyphen (-) if you want path(s) to be read from stdin."
17
- ].join("\n\n "))
18
- .option("-f <path>", "Specify conf filename other than \".editorconfig\"")
19
- .option("-b <version>", "Specify version (used by devs to test compatibility)")
20
- .option("-v, --version", "Display version information")
21
- .parse(process.argv);
22
-
23
- // Throw away the native -V flag in lieu of the one we've manually specified
24
- // to adhere to testing requirements
25
- program.options.shift();
26
-
27
- var files = program.args;
28
-
29
- if (!files.length) {
30
- program.help();
31
- }
32
-
33
- Promise.map(files, function(filePath) {
34
- return editorconfig.parse(filePath, {config: program.F, version: program.B});
35
- }).each(function(parsed, i, length) {
36
- if (length > 1) {
37
- console.log("[%s]", files[i]);
38
- }
39
- Object.keys(parsed).forEach(function(key) {
40
- console.log(key + "=" + parsed[key]);
41
- });
42
- });
2
+ var cli = require('../cli')
3
+ cli.default(process.argv)
package/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export default function cli(args: string[]): void;
package/cli.js ADDED
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // tslint:disable:no-console
4
+ var program = require("commander");
5
+ var editorconfig = require("./");
6
+ // tslint:disable-next-line:no-var-requires
7
+ var pkg = require('./package.json');
8
+ function cli(args) {
9
+ program.version('EditorConfig Node.js Core Version ' + pkg.version);
10
+ program
11
+ .usage([
12
+ '[OPTIONS] FILEPATH1 [FILEPATH2 FILEPATH3 ...]',
13
+ program._version,
14
+ 'FILEPATH can be a hyphen (-) if you want path(s) to be read from stdin.',
15
+ ].join('\n\n '))
16
+ .option('-f <path>', 'Specify conf filename other than \'.editorconfig\'')
17
+ .option('-b <version>', 'Specify version (used by devs to test compatibility)')
18
+ .option('-v, --version', 'Display version information')
19
+ .parse(args);
20
+ // Throw away the native -V flag in lieu of the one we've manually specified
21
+ // to adhere to testing requirements
22
+ program.options.shift();
23
+ var files = program.args;
24
+ if (!files.length) {
25
+ program.help();
26
+ }
27
+ files
28
+ .map(function (filePath) { return editorconfig.parse(filePath, {
29
+ config: program.F,
30
+ version: program.B,
31
+ }); })
32
+ .forEach(function (parsing, i, _a) {
33
+ var length = _a.length;
34
+ parsing.then(function (parsed) {
35
+ if (length > 1) {
36
+ console.log("[" + files[i] + "]");
37
+ }
38
+ Object.keys(parsed).forEach(function (key) {
39
+ console.log(key + "=" + parsed[key]);
40
+ });
41
+ });
42
+ });
43
+ }
44
+ exports.default = cli;
package/index.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ /// <reference types="node" />
2
+ import { parseString, ParseStringResult } from './lib/ini';
3
+ export { parseString };
4
+ export interface KnownProps {
5
+ end_of_line?: 'lf' | 'crlf' | 'unset';
6
+ indent_style?: 'tab' | 'space' | 'unset';
7
+ indent_size?: number | 'tab' | 'unset';
8
+ insert_final_newline?: true | false | 'unset';
9
+ tab_width?: number | 'unset';
10
+ trim_trailing_whitespace?: true | false | 'unset';
11
+ charset?: string | 'unset';
12
+ }
13
+ export interface ECFile {
14
+ name: string;
15
+ contents: string | Buffer;
16
+ }
17
+ export interface FileConfig {
18
+ name: string;
19
+ contents: ParseStringResult;
20
+ }
21
+ export interface ParseOptions {
22
+ config?: string;
23
+ version?: string;
24
+ root?: string;
25
+ }
26
+ export declare function parseFromFiles(filepath: string, files: Promise<ECFile[]>, options?: ParseOptions): Promise<KnownProps>;
27
+ export declare function parseFromFilesSync(filepath: string, files: ECFile[], options?: ParseOptions): KnownProps;
28
+ export declare function parse(_filepath: string, _options?: ParseOptions): Promise<KnownProps>;
29
+ export declare function parseSync(_filepath: string, _options?: ParseOptions): KnownProps;
package/index.js ADDED
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (_) try {
17
+ if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [0, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ var fs = require("fs");
39
+ var path = require("path");
40
+ var semver = require("semver");
41
+ var minimatch = require("./lib/fnmatch");
42
+ var ini_1 = require("./lib/ini");
43
+ exports.parseString = ini_1.parseString;
44
+ // tslint:disable-next-line:no-var-requires
45
+ var pkg = require('./package.json');
46
+ var knownProps = {
47
+ end_of_line: true,
48
+ indent_style: true,
49
+ indent_size: true,
50
+ insert_final_newline: true,
51
+ trim_trailing_whitespace: true,
52
+ charset: true,
53
+ };
54
+ function fnmatch(filepath, glob) {
55
+ var matchOptions = { matchBase: true, dot: true, noext: true };
56
+ glob = glob.replace(/\*\*/g, '{*,**/**/**}');
57
+ return minimatch(filepath, glob, matchOptions);
58
+ }
59
+ function getConfigFileNames(filepath, options) {
60
+ var paths = [];
61
+ do {
62
+ filepath = path.dirname(filepath);
63
+ paths.push(path.join(filepath, options.config));
64
+ } while (filepath !== options.root);
65
+ return paths;
66
+ }
67
+ function processMatches(matches, version) {
68
+ // Set indent_size to 'tab' if indent_size is unspecified and
69
+ // indent_style is set to 'tab'.
70
+ if ('indent_style' in matches
71
+ && matches.indent_style === 'tab'
72
+ && !('indent_size' in matches)
73
+ && semver.gte(version, '0.10.0')) {
74
+ matches.indent_size = 'tab';
75
+ }
76
+ // Set tab_width to indent_size if indent_size is specified and
77
+ // tab_width is unspecified
78
+ if ('indent_size' in matches
79
+ && !('tab_width' in matches)
80
+ && matches.indent_size !== 'tab') {
81
+ matches.tab_width = matches.indent_size;
82
+ }
83
+ // Set indent_size to tab_width if indent_size is 'tab'
84
+ if ('indent_size' in matches
85
+ && 'tab_width' in matches
86
+ && matches.indent_size === 'tab') {
87
+ matches.indent_size = matches.tab_width;
88
+ }
89
+ return matches;
90
+ }
91
+ function processOptions(options, filepath) {
92
+ if (options === void 0) { options = {}; }
93
+ return {
94
+ config: options.config || '.editorconfig',
95
+ version: options.version || pkg.version,
96
+ root: path.resolve(options.root || path.parse(filepath).root),
97
+ };
98
+ }
99
+ function buildFullGlob(pathPrefix, glob) {
100
+ switch (glob.indexOf('/')) {
101
+ case -1:
102
+ glob = '**/' + glob;
103
+ break;
104
+ case 0:
105
+ glob = glob.substring(1);
106
+ break;
107
+ default:
108
+ break;
109
+ }
110
+ return path.join(pathPrefix, glob);
111
+ }
112
+ function extendProps(props, options) {
113
+ if (props === void 0) { props = {}; }
114
+ if (options === void 0) { options = {}; }
115
+ for (var key in options) {
116
+ if (options.hasOwnProperty(key)) {
117
+ var value = options[key];
118
+ var key2 = key.toLowerCase();
119
+ var value2 = value;
120
+ if (knownProps[key2]) {
121
+ value2 = value.toLowerCase();
122
+ }
123
+ try {
124
+ value2 = JSON.parse(value);
125
+ }
126
+ catch (e) { }
127
+ if (typeof value === 'undefined' || value === null) {
128
+ // null and undefined are values specific to JSON (no special meaning
129
+ // in editorconfig) & should just be returned as regular strings.
130
+ value2 = String(value);
131
+ }
132
+ props[key2] = value2;
133
+ }
134
+ }
135
+ return props;
136
+ }
137
+ function parseFromConfigs(configs, filepath, options) {
138
+ return processMatches(configs
139
+ .reverse()
140
+ .reduce(function (matches, file) {
141
+ var pathPrefix = path.dirname(file.name);
142
+ file.contents.forEach(function (section) {
143
+ var glob = section[0];
144
+ var options2 = section[1];
145
+ if (!glob) {
146
+ return;
147
+ }
148
+ var fullGlob = buildFullGlob(pathPrefix, glob);
149
+ if (!fnmatch(filepath, fullGlob)) {
150
+ return;
151
+ }
152
+ matches = extendProps(matches, options2);
153
+ });
154
+ return matches;
155
+ }, {}), options.version);
156
+ }
157
+ function getConfigsForFiles(files) {
158
+ var configs = [];
159
+ for (var i in files) {
160
+ if (files.hasOwnProperty(i)) {
161
+ var file = files[i];
162
+ var contents = ini_1.parseString(file.contents);
163
+ configs.push({
164
+ name: file.name,
165
+ contents: contents,
166
+ });
167
+ if ((contents[0][1].root || '').toLowerCase() === 'true') {
168
+ break;
169
+ }
170
+ }
171
+ }
172
+ return configs;
173
+ }
174
+ function readConfigFiles(filepaths) {
175
+ return __awaiter(this, void 0, void 0, function () {
176
+ return __generator(this, function (_a) {
177
+ return [2 /*return*/, Promise.all(filepaths.map(function (name) { return new Promise(function (resolve) {
178
+ fs.readFile(name, 'utf8', function (err, data) {
179
+ resolve({
180
+ name: name,
181
+ contents: err ? '' : data,
182
+ });
183
+ });
184
+ }); }))];
185
+ });
186
+ });
187
+ }
188
+ function readConfigFilesSync(filepaths) {
189
+ var files = [];
190
+ var file;
191
+ filepaths.forEach(function (filepath) {
192
+ try {
193
+ file = fs.readFileSync(filepath, 'utf8');
194
+ }
195
+ catch (e) {
196
+ file = '';
197
+ }
198
+ files.push({
199
+ name: filepath,
200
+ contents: file,
201
+ });
202
+ });
203
+ return files;
204
+ }
205
+ function opts(filepath, options) {
206
+ if (options === void 0) { options = {}; }
207
+ var resolvedFilePath = path.resolve(filepath);
208
+ return [
209
+ resolvedFilePath,
210
+ processOptions(options, resolvedFilePath),
211
+ ];
212
+ }
213
+ function parseFromFiles(filepath, files, options) {
214
+ if (options === void 0) { options = {}; }
215
+ return __awaiter(this, void 0, void 0, function () {
216
+ var _a, resolvedFilePath, processedOptions;
217
+ return __generator(this, function (_b) {
218
+ _a = opts(filepath, options), resolvedFilePath = _a[0], processedOptions = _a[1];
219
+ return [2 /*return*/, files.then(getConfigsForFiles)
220
+ .then(function (configs) { return parseFromConfigs(configs, resolvedFilePath, processedOptions); })];
221
+ });
222
+ });
223
+ }
224
+ exports.parseFromFiles = parseFromFiles;
225
+ function parseFromFilesSync(filepath, files, options) {
226
+ if (options === void 0) { options = {}; }
227
+ var _a = opts(filepath, options), resolvedFilePath = _a[0], processedOptions = _a[1];
228
+ return parseFromConfigs(getConfigsForFiles(files), resolvedFilePath, processedOptions);
229
+ }
230
+ exports.parseFromFilesSync = parseFromFilesSync;
231
+ function parse(_filepath, _options) {
232
+ if (_options === void 0) { _options = {}; }
233
+ return __awaiter(this, void 0, void 0, function () {
234
+ var _a, resolvedFilePath, processedOptions, filepaths;
235
+ return __generator(this, function (_b) {
236
+ _a = opts(_filepath, _options), resolvedFilePath = _a[0], processedOptions = _a[1];
237
+ filepaths = getConfigFileNames(resolvedFilePath, processedOptions);
238
+ return [2 /*return*/, readConfigFiles(filepaths)
239
+ .then(getConfigsForFiles)
240
+ .then(function (configs) { return parseFromConfigs(configs, resolvedFilePath, processedOptions); })];
241
+ });
242
+ });
243
+ }
244
+ exports.parse = parse;
245
+ function parseSync(_filepath, _options) {
246
+ if (_options === void 0) { _options = {}; }
247
+ var _a = opts(_filepath, _options), resolvedFilePath = _a[0], processedOptions = _a[1];
248
+ var filepaths = getConfigFileNames(resolvedFilePath, processedOptions);
249
+ var files = readConfigFilesSync(filepaths);
250
+ return parseFromConfigs(getConfigsForFiles(files), resolvedFilePath, processedOptions);
251
+ }
252
+ exports.parseSync = parseSync;
@@ -0,0 +1,214 @@
1
+ // Type definitions for Minimatch 3.0
2
+ // Project: https://github.com/isaacs/minimatch
3
+ // Definitions by: vvakame <https://github.com/vvakame>
4
+ // Shant Marouti <https://github.com/shantmarouti>
5
+ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
6
+
7
+ /**
8
+ * Tests a path against the pattern using the options.
9
+ */
10
+ declare function M(target: string, pattern: string, options?: M.IOptions): boolean;
11
+
12
+ declare namespace M {
13
+ /**
14
+ * Match against the list of files, in the style of fnmatch or glob.
15
+ * If nothing is matched, and options.nonull is set,
16
+ * then return a list containing the pattern itself.
17
+ */
18
+ function match(list: string[], pattern: string, options?: IOptions): string[];
19
+
20
+ /**
21
+ * Returns a function that tests its supplied argument, suitable for use with Array.filter
22
+ */
23
+ function filter(pattern: string, options?: IOptions): (element: string, indexed: number, array: string[]) => boolean;
24
+
25
+ /**
26
+ * Make a regular expression object from the pattern.
27
+ */
28
+ function makeRe(pattern: string, options?: IOptions): RegExp;
29
+
30
+ var Minimatch: IMinimatchStatic;
31
+
32
+ interface IOptions {
33
+ /**
34
+ * Dump a ton of stuff to stderr.
35
+ *
36
+ * @default false
37
+ */
38
+ debug?: boolean;
39
+
40
+ /**
41
+ * Do not expand {a,b} and {1..3} brace sets.
42
+ *
43
+ * @default false
44
+ */
45
+ nobrace?: boolean;
46
+
47
+ /**
48
+ * Disable ** matching against multiple folder names.
49
+ *
50
+ * @default false
51
+ */
52
+ noglobstar?: boolean;
53
+
54
+ /**
55
+ * Allow patterns to match filenames starting with a period,
56
+ * even if the pattern does not explicitly have a period in that spot.
57
+ *
58
+ * @default false
59
+ */
60
+ dot?: boolean;
61
+
62
+ /**
63
+ * Disable "extglob" style patterns like +(a|b).
64
+ *
65
+ * @default false
66
+ */
67
+ noext?: boolean;
68
+
69
+ /**
70
+ * Perform a case-insensitive match.
71
+ *
72
+ * @default false
73
+ */
74
+ nocase?: boolean;
75
+
76
+ /**
77
+ * When a match is not found by minimatch.match,
78
+ * return a list containing the pattern itself if this option is set.
79
+ * Otherwise, an empty list is returned if there are no matches.
80
+ *
81
+ * @default false
82
+ */
83
+ nonull?: boolean;
84
+
85
+ /**
86
+ * If set, then patterns without slashes will be matched against
87
+ * the basename of the path if it contains slashes.
88
+ *
89
+ * @default false
90
+ */
91
+ matchBase?: boolean;
92
+
93
+ /**
94
+ * Suppress the behavior of treating #
95
+ * at the start of a pattern as a comment.
96
+ *
97
+ * @default false
98
+ */
99
+ nocomment?: boolean;
100
+
101
+ /**
102
+ * Suppress the behavior of treating a leading ! character as negation.
103
+ *
104
+ * @default false
105
+ */
106
+ nonegate?: boolean;
107
+
108
+ /**
109
+ * Returns from negate expressions the same as if they were not negated.
110
+ * (Ie, true on a hit, false on a miss.)
111
+ *
112
+ * @default false
113
+ */
114
+ flipNegate?: boolean;
115
+ }
116
+
117
+ interface IMinimatchStatic {
118
+ new(pattern: string, options?: IOptions): IMinimatch;
119
+ prototype: IMinimatch;
120
+ }
121
+
122
+ interface IMinimatch {
123
+ /**
124
+ * The original pattern the minimatch object represents.
125
+ */
126
+ pattern: string;
127
+
128
+ /**
129
+ * The options supplied to the constructor.
130
+ */
131
+ options: IOptions;
132
+
133
+ /**
134
+ * A 2-dimensional array of regexp or string expressions.
135
+ */
136
+ set: any[][]; // (RegExp | string)[][]
137
+
138
+ /**
139
+ * A single regular expression expressing the entire pattern.
140
+ * Created by the makeRe method.
141
+ */
142
+ regexp: RegExp;
143
+
144
+ /**
145
+ * True if the pattern is negated.
146
+ */
147
+ negate: boolean;
148
+
149
+ /**
150
+ * True if the pattern is a comment.
151
+ */
152
+ comment: boolean;
153
+
154
+ /**
155
+ * True if the pattern is ""
156
+ */
157
+ empty: boolean;
158
+
159
+ /**
160
+ * Generate the regexp member if necessary, and return it.
161
+ * Will return false if the pattern is invalid.
162
+ */
163
+ makeRe(): RegExp; // regexp or boolean
164
+
165
+ /**
166
+ * Return true if the filename matches the pattern, or false otherwise.
167
+ */
168
+ match(fname: string): boolean;
169
+
170
+ /**
171
+ * Take a /-split filename, and match it against a single row in the regExpSet.
172
+ * This method is mainly for internal use, but is exposed so that it can be used
173
+ * by a glob-walker that needs to avoid excessive filesystem calls.
174
+ */
175
+ matchOne(files: string[], pattern: string[], partial: boolean): boolean;
176
+
177
+ /**
178
+ * Deprecated. For internal use.
179
+ *
180
+ * @private
181
+ */
182
+ debug(): void;
183
+
184
+ /**
185
+ * Deprecated. For internal use.
186
+ *
187
+ * @private
188
+ */
189
+ make(): void;
190
+
191
+ /**
192
+ * Deprecated. For internal use.
193
+ *
194
+ * @private
195
+ */
196
+ parseNegate(): void;
197
+
198
+ /**
199
+ * Deprecated. For internal use.
200
+ *
201
+ * @private
202
+ */
203
+ braceExpand(pattern: string, options: IOptions): void;
204
+
205
+ /**
206
+ * Deprecated. For internal use.
207
+ *
208
+ * @private
209
+ */
210
+ parse(pattern: string, isSub?: boolean): void;
211
+ }
212
+ }
213
+
214
+ export = M;
package/lib/ini.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ import { URL } from 'url';
3
+ /**
4
+ * Parses an .ini file
5
+ * @param file The location of the .ini file
6
+ */
7
+ export declare function parse(file: string | number | Buffer | URL): Promise<[string | null, SectionBody][]>;
8
+ export declare function parseSync(file: string | number | Buffer | URL): [string | null, SectionBody][];
9
+ export declare type SectionName = string | null;
10
+ export interface SectionBody {
11
+ [key: string]: string;
12
+ }
13
+ export declare type ParseStringResult = Array<[SectionName, SectionBody]>;
14
+ export declare function parseString(data: string): ParseStringResult;
package/lib/ini.js CHANGED
@@ -1,63 +1,99 @@
1
- // Based on iniparser by shockie <https://npmjs.org/package/iniparser>
2
-
3
- /*
4
- * get the file handler
5
- */
6
- var fs = require('fs');
7
-
8
- /*
9
- * define the possible values:
10
- * section: [section]
11
- * param: key=value
12
- * comment: ;this is a comment
13
- */
14
- var regex = {
15
- section: /^\s*\[(([^#;]|\\#|\\;)+)\]\s*([#;].*)?$/,
16
- param: /^\s*([\w\.\-\_]+)\s*[=:]\s*(.*?)\s*([#;].*)?$/,
17
- comment: /^\s*[#;].*$/
18
- };
19
-
20
- /*
21
- * parses a .ini file
22
- * @param: {String} file, the location of the .ini file
23
- * @param: {Function} callback, the function that will be called when parsing is done
24
- * @return: none
25
- */
26
- exports.parse = function (file, callback) {
27
- if (!callback) {
28
- return;
29
- }
30
- fs.readFile(file, 'utf8', function (err, data) {
31
- if (err) {
32
- callback(err);
33
- } else {
34
- callback(null, parse(data));
35
- }
36
- });
37
- };
38
-
39
- exports.parseSync = function (file) {
40
- return parse(fs.readFileSync(file, 'utf8'));
41
- };
42
-
43
- exports.parseString = function (data) {
44
- var sectionBody = {};
45
- var sectionName = null;
46
- var value = [[sectionName, sectionBody]];
47
- var lines = data.split(/\r\n|\r|\n/);
48
- lines.forEach(function (line) {
49
- var match;
50
- if (regex.comment.test(line)) {
51
- return;
52
- } else if (regex.param.test(line)) {
53
- match = line.match(regex.param);
54
- sectionBody[match[1]] = match[2];
55
- } else if (regex.section.test(line)) {
56
- match = line.match(regex.section);
57
- sectionName = match[1];
58
- sectionBody = {};
59
- value.push([sectionName, sectionBody]);
60
- }
61
- });
62
- return value;
63
- };
1
+ "use strict";
2
+ // Based on iniparser by shockie <https://npmjs.org/package/iniparser>
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [0, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var fs = require("fs");
40
+ /**
41
+ * define the possible values:
42
+ * section: [section]
43
+ * param: key=value
44
+ * comment: ;this is a comment
45
+ */
46
+ var regex = {
47
+ section: /^\s*\[(([^#;]|\\#|\\;)+)\]\s*([#;].*)?$/,
48
+ param: /^\s*([\w\.\-\_]+)\s*[=:]\s*(.*?)\s*([#;].*)?$/,
49
+ comment: /^\s*[#;].*$/,
50
+ };
51
+ /**
52
+ * Parses an .ini file
53
+ * @param file The location of the .ini file
54
+ */
55
+ function parse(file) {
56
+ return __awaiter(this, void 0, void 0, function () {
57
+ return __generator(this, function (_a) {
58
+ return [2 /*return*/, new Promise(function (resolve, reject) {
59
+ fs.readFile(file, 'utf8', function (err, data) {
60
+ if (err) {
61
+ reject(err);
62
+ return;
63
+ }
64
+ resolve(parseString(data));
65
+ });
66
+ })];
67
+ });
68
+ });
69
+ }
70
+ exports.parse = parse;
71
+ function parseSync(file) {
72
+ return parseString(fs.readFileSync(file, 'utf8'));
73
+ }
74
+ exports.parseSync = parseSync;
75
+ function parseString(data) {
76
+ var sectionBody = {};
77
+ var sectionName = null;
78
+ var value = [[sectionName, sectionBody]];
79
+ var lines = data.split(/\r\n|\r|\n/);
80
+ lines.forEach(function (line) {
81
+ var match;
82
+ if (regex.comment.test(line)) {
83
+ return;
84
+ }
85
+ if (regex.param.test(line)) {
86
+ match = line.match(regex.param);
87
+ sectionBody[match[1]] =
88
+ match[2];
89
+ }
90
+ else if (regex.section.test(line)) {
91
+ match = line.match(regex.section);
92
+ sectionName = match[1];
93
+ sectionBody = {};
94
+ value.push([sectionName, sectionBody]);
95
+ }
96
+ });
97
+ return value;
98
+ }
99
+ exports.parseString = parseString;
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "editorconfig",
3
- "version": "0.14.2",
3
+ "version": "0.15.0",
4
4
  "description": "EditorConfig File Locator and Interpreter for Node.js",
5
5
  "keywords": [
6
6
  "editorconfig",
7
7
  "core"
8
8
  ],
9
- "main": "editorconfig.js",
9
+ "main": "index.js",
10
10
  "bin": {
11
11
  "editorconfig": "bin/editorconfig"
12
12
  },
@@ -20,10 +20,19 @@
20
20
  "lib": "./lib"
21
21
  },
22
22
  "scripts": {
23
- "pretest": "cmake .",
24
- "test": "npm run lint && ctest .",
25
- "test-verbose": "npm run lint && ctest -VV --output-on-failure .",
26
- "lint": "eclint check --indent_size ignore editorconfig.js README.md \"bin/**\" \"lib/**\""
23
+ "clean": "rimraf dist",
24
+ "prebuild": "npm run clean",
25
+ "build": "tsc",
26
+ "pretest": "npm run lint && npm run build && npm run copy && cmake .",
27
+ "test": "ctest .",
28
+ "pretest:ci": "npm run pretest",
29
+ "test:ci": "ctest -VV --output-on-failure .",
30
+ "lint": "npm run eclint && npm run tslint",
31
+ "eclint": "eclint check --indent_size ignore \"src/**\"",
32
+ "tslint": "tslint --project tslint.json",
33
+ "copy": "cpy package.json .npmignore LICENSE README.md CHANGELOG.md dist && cpy src/bin/* dist/bin && cpy src/lib/fnmatch*.* dist/lib",
34
+ "prepub": "npm run lint && npm run build && npm run copy",
35
+ "pub": "npm publish ./dist"
27
36
  },
28
37
  "repository": {
29
38
  "type": "git",
@@ -33,15 +42,21 @@
33
42
  "author": "EditorConfig Team",
34
43
  "license": "MIT",
35
44
  "dependencies": {
36
- "bluebird": "^3.0.5",
37
- "commander": "^2.9.0",
38
- "lru-cache": "^3.2.0",
39
- "semver": "^5.1.0",
45
+ "@types/commander": "^2.11.0",
46
+ "@types/semver": "^5.4.0",
47
+ "commander": "^2.11.0",
48
+ "lru-cache": "^4.1.1",
49
+ "semver": "^5.4.1",
40
50
  "sigmund": "^1.0.1"
41
51
  },
42
52
  "devDependencies": {
43
- "eclint": "^1.1.5",
44
- "mocha": "^2.3.4",
45
- "should": "^7.1.1"
53
+ "@types/mocha": "^2.2.43",
54
+ "cpy-cli": "^1.0.1",
55
+ "eclint": "^2.4.3",
56
+ "mocha": "^4.0.1",
57
+ "rimraf": "^2.6.2",
58
+ "should": "^13.1.2",
59
+ "tslint": "^5.7.0",
60
+ "typescript": "^2.5.3"
46
61
  }
47
62
  }
package/.gitmodules DELETED
@@ -1,3 +0,0 @@
1
- [submodule "tests"]
2
- path = tests
3
- url = git://github.com/editorconfig/editorconfig-core-test.git
@@ -1,50 +0,0 @@
1
- # Install script for directory: C:/Users/jedma/Documents/GitHub/editorconfig-core-js
2
-
3
- # Set the install prefix
4
- if(NOT DEFINED CMAKE_INSTALL_PREFIX)
5
- set(CMAKE_INSTALL_PREFIX "C:/Program Files (x86)/editorconfig-core-js")
6
- endif()
7
- string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
8
-
9
- # Set the install configuration name.
10
- if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
11
- if(BUILD_TYPE)
12
- string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
13
- CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
14
- else()
15
- set(CMAKE_INSTALL_CONFIG_NAME "")
16
- endif()
17
- message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
18
- endif()
19
-
20
- # Set the component getting installed.
21
- if(NOT CMAKE_INSTALL_COMPONENT)
22
- if(COMPONENT)
23
- message(STATUS "Install component: \"${COMPONENT}\"")
24
- set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
25
- else()
26
- set(CMAKE_INSTALL_COMPONENT)
27
- endif()
28
- endif()
29
-
30
- # Is this installation the result of a crosscompile?
31
- if(NOT DEFINED CMAKE_CROSSCOMPILING)
32
- set(CMAKE_CROSSCOMPILING "FALSE")
33
- endif()
34
-
35
- if(NOT CMAKE_INSTALL_LOCAL_ONLY)
36
- # Include the install script for each subdirectory.
37
- include("C:/Users/jedma/Documents/GitHub/editorconfig-core-js/tests/cmake_install.cmake")
38
-
39
- endif()
40
-
41
- if(CMAKE_INSTALL_COMPONENT)
42
- set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
43
- else()
44
- set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
45
- endif()
46
-
47
- string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
48
- "${CMAKE_INSTALL_MANIFEST_FILES}")
49
- file(WRITE "C:/Users/jedma/Documents/GitHub/editorconfig-core-js/${CMAKE_INSTALL_MANIFEST}"
50
- "${CMAKE_INSTALL_MANIFEST_CONTENT}")
package/editorconfig.js DELETED
@@ -1,239 +0,0 @@
1
- var Promise = require('bluebird');
2
- var fs = require('fs');
3
- var os = require('os');
4
- var path = require('path');
5
- var semver = require('semver');
6
- var util = require('util');
7
- var whenReadFile = Promise.promisify(fs.readFile);
8
-
9
- var iniparser = require('./lib/ini');
10
- var minimatch = require('./lib/fnmatch');
11
- var pkg = require('./package.json');
12
-
13
- var knownProps = [
14
- 'end_of_line',
15
- 'indent_style',
16
- 'indent_size',
17
- 'insert_final_newline',
18
- 'trim_trailing_whitespace',
19
- 'charset'
20
- ].reduce(function (set, prop) {
21
- set[prop] = true;
22
- return set;
23
- }, {});
24
-
25
- function fnmatch(filepath, glob) {
26
- var matchOptions = {matchBase: true, dot: true, noext: true};
27
- glob = glob.replace(/\*\*/g, '{*,**/**/**}');
28
- return minimatch(filepath, glob, matchOptions);
29
- }
30
-
31
- function getConfigFileNames(filepath, options) {
32
- var paths = [];
33
- do {
34
- filepath = path.dirname(filepath);
35
- paths.push(path.join(filepath, options.config));
36
- } while (filepath !== options.root);
37
- return paths;
38
- }
39
-
40
- function getFilepathRoot(filepath) {
41
- if (path.parse !== undefined) {
42
- // Node.js >= 0.11.15
43
- return path.parse(filepath).root;
44
- }
45
- if (os.platform() === 'win32') {
46
- return path.resolve(filepath).match(/^(\\\\[^\\]+\\)?[^\\]+\\/)[0];
47
- }
48
- return '/';
49
- }
50
-
51
- function processMatches(matches, version) {
52
- // Set indent_size to "tab" if indent_size is unspecified and
53
- // indent_style is set to "tab".
54
- if ("indent_style" in matches && matches.indent_style === "tab" &&
55
- !("indent_size" in matches) && semver.gte(version, "0.10.0")) {
56
- matches.indent_size = "tab";
57
- }
58
-
59
- // Set tab_width to indent_size if indent_size is specified and
60
- // tab_width is unspecified
61
- if ("indent_size" in matches && !("tab_width" in matches) &&
62
- matches.indent_size !== "tab")
63
- matches.tab_width = matches.indent_size;
64
-
65
- // Set indent_size to tab_width if indent_size is "tab"
66
- if("indent_size" in matches && "tab_width" in matches &&
67
- matches.indent_size === "tab")
68
- matches.indent_size = matches.tab_width;
69
-
70
- return matches;
71
- }
72
-
73
- function processOptions(options, filepath) {
74
- options = options || {};
75
- return {
76
- config: options.config || '.editorconfig',
77
- version: options.version || pkg.version,
78
- root: path.resolve(options.root || getFilepathRoot(filepath))
79
- };
80
- }
81
-
82
- function buildFullGlob(pathPrefix, glob) {
83
- switch (glob.indexOf('/')) {
84
- case -1: glob = "**/" + glob; break;
85
- case 0: glob = glob.substring(1); break;
86
- }
87
- return path.join(pathPrefix, glob);
88
- }
89
-
90
- function extendProps(props, options) {
91
- for (var key in options) {
92
- var value = options[key];
93
- key = key.toLowerCase();
94
- if (knownProps[key]) {
95
- value = value.toLowerCase();
96
- }
97
- try {
98
- value = JSON.parse(value);
99
- } catch(e) {}
100
- if (typeof value === 'undefined' || value === null) {
101
- // null and undefined are values specific to JSON (no special meaning
102
- // in editorconfig) & should just be returned as regular strings.
103
- value = String(value);
104
- }
105
- props[key] = value;
106
- }
107
- return props;
108
- }
109
-
110
- function parseFromFiles(filepath, files, options) {
111
- return getConfigsForFiles(files).then(function (configs) {
112
- return configs.reverse();
113
- }).reduce(function (matches, file) {
114
- var pathPrefix = path.dirname(file.name);
115
- file.contents.forEach(function (section) {
116
- var glob = section[0], options = section[1];
117
- if (!glob) return;
118
- var fullGlob = buildFullGlob(pathPrefix, glob);
119
- if (!fnmatch(filepath, fullGlob)) return;
120
- matches = extendProps(matches, options);
121
- });
122
- return matches;
123
- }, {}).then(function (matches) {
124
- return processMatches(matches, options.version);
125
- });
126
- }
127
-
128
- function parseFromFilesSync(filepath, files, options) {
129
- var configs = getConfigsForFilesSync(files);
130
- configs.reverse();
131
- var matches = {};
132
- configs.forEach(function(config) {
133
- var pathPrefix = path.dirname(config.name);
134
- config.contents.forEach(function(section) {
135
- var glob = section[0], options = section[1];
136
- if (!glob) return;
137
- var fullGlob = buildFullGlob(pathPrefix, glob);
138
- if (!fnmatch(filepath, fullGlob)) return;
139
- matches = extendProps(matches, options);
140
- });
141
- });
142
- return processMatches(matches, options.version);
143
- }
144
-
145
- function StopReduce(array) {
146
- this.array = array;
147
- }
148
-
149
- StopReduce.prototype = Object.create(Error.prototype);
150
-
151
- function getConfigsForFiles(files) {
152
- return Promise.reduce(files, function (configs, file) {
153
- var contents = iniparser.parseString(file.contents);
154
- configs.push({
155
- name: file.name,
156
- contents: contents
157
- });
158
- if ((contents[0][1].root || '').toLowerCase() === 'true') {
159
- return Promise.reject(new StopReduce(configs));
160
- }
161
- return configs;
162
- }, []).catch(StopReduce, function (stop) {
163
- return stop.array;
164
- });
165
- }
166
-
167
- function getConfigsForFilesSync(files) {
168
- var configs = [];
169
- for (var i in files) {
170
- var file = files[i];
171
- var contents = iniparser.parseString(file.contents);
172
- configs.push({
173
- name: file.name,
174
- contents: contents
175
- });
176
- if ((contents[0][1].root || '').toLowerCase() === 'true') {
177
- break;
178
- }
179
- };
180
- return configs;
181
- }
182
-
183
- function readConfigFiles(filepaths) {
184
- return Promise.map(filepaths, function (path) {
185
- return whenReadFile(path, 'utf-8').catch(function () {
186
- return '';
187
- }).then(function (contents) {
188
- return {name: path, contents: contents};
189
- });
190
- });
191
- }
192
-
193
- function readConfigFilesSync(filepaths) {
194
- var files = [];
195
- var file;
196
- filepaths.forEach(function(filepath) {
197
- try {
198
- file = fs.readFileSync(filepath, 'utf8');
199
- } catch (e) {
200
- file = '';
201
- }
202
- files.push({name: filepath, contents: file});
203
- });
204
- return files;
205
- }
206
-
207
- module.exports.parseFromFiles = function (filepath, files, options) {
208
- return new Promise (function (resolve, reject) {
209
- filepath = path.resolve(filepath);
210
- options = processOptions(options, filepath);
211
- resolve(parseFromFiles(filepath, files, options));
212
- });
213
- };
214
-
215
- module.exports.parseFromFilesSync = function (filepath, files, options) {
216
- filepath = path.resolve(filepath);
217
- options = processOptions(options, filepath);
218
- return parseFromFilesSync(filepath, files, options);
219
- };
220
-
221
- module.exports.parse = function (filepath, options) {
222
- return new Promise (function (resolve, reject) {
223
- filepath = path.resolve(filepath);
224
- options = processOptions(options, filepath);
225
- var filepaths = getConfigFileNames(filepath, options);
226
- var files = readConfigFiles(filepaths);
227
- resolve(parseFromFiles(filepath, files, options));
228
- });
229
- };
230
-
231
- module.exports.parseSync = function (filepath, options) {
232
- filepath = path.resolve(filepath);
233
- options = processOptions(options, filepath);
234
- var filepaths = getConfigFileNames(filepath, options);
235
- var files = readConfigFilesSync(filepaths);
236
- return parseFromFilesSync(filepath, files, options);
237
- };
238
-
239
- module.exports.parseString = iniparser.parseString;