Initial commit: Developer Tools MVP with visual editor

- Complete React app with 7 developer tools
- JSON Tool with visual structured editor
- Serialize Tool with visual structured editor
- URL, Base64, CSV/JSON, Beautifier, Diff tools
- Responsive navigation with dropdown menu
- Dark/light mode toggle
- Mobile-responsive design with sticky header
- All tools working with copy/paste functionality
This commit is contained in:
dwindown
2025-08-02 09:31:26 +07:00
commit 7f2dd5260f
45657 changed files with 4730486 additions and 0 deletions

19
node_modules/editorconfig/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright © 2012 EditorConfig Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

255
node_modules/editorconfig/README.md generated vendored Normal file
View File

@@ -0,0 +1,255 @@
# EditorConfig JavaScript Core
[![Tests](https://github.com/editorconfig/editorconfig-core-js/actions/workflows/node.js.yml/badge.svg)](https://github.com/editorconfig/editorconfig-core-js/actions/workflows/node.js.yml)
[![Coverage Status](https://coveralls.io/repos/github/editorconfig/editorconfig-core-js/badge.svg?branch=master)](https://coveralls.io/github/editorconfig/editorconfig-core-js?branch=master)
The EditorConfig JavaScript core will provide the same functionality as the
[EditorConfig C Core][] and [EditorConfig Python Core][].
## Installation
You need [node][] to use this package.
To install the package locally:
```bash
$ npm install editorconfig
```
To install the package system-wide:
```bash
$ npm install -g editorconfig
```
## Usage
### Options
Most of the API takes an `options` object, which has the following defaults:
```js
{
config: '.editorconfig',
version: pkg.version,
root: '/',
files: undefined,
cache: undefined,
};
```
<dl>
<dt>config</dt>
<dd>The name of the config file to look for in the current and every parent
directory.</dd>
<dt>version</dt>
<dd>Which editorconfig spec version to use. Earlier versions had different
defaults.</dd>
<dt>root</dt>
<dd>What directory to stop processing in, even if we haven't found a file
containing root=true. Defaults to the root of the filesystem containing
`process.cwd()`.</dd>
<dt>files</dt>
<dd>Pass in an empty array, which will be filled with one object for each
config file processed. The objects will have the shape
`{filename: "[DIRECTORY]/.editorconfig", glob: "*"}`</dd>
<dt>cache</dt>
<dd>If you are going to process more than one file in the same project, pass
in a cache object. It must have `get(string): object|undefined` and
`set(string, object)` methods, like a JavaScript Map. A long-running
process might want to consider that this cache might grow over time,
and that the config files might change over time. However, we leave any
complexity of that nature to the caller, since there are so many different
approaches that might be taken based on latency, memory, and CPU trade-offs.
Note that some of the objects in the cache will be for files that did not
exist. Those objects will have a `notfound: true` property. All of the
objects will have a `name: string` property that contains the
fully-qualified file name of the config file and a `root: boolean` property
that describes if the config file had a `root=true` at the top. Any other
properties in the objects should be treated as opaque.</dd>
</dl>
### in Node.js:
#### parse(filePath[, options])
Search for `.editorconfig` files starting from the current directory to the
root directory. Combine all of the sections whose section names match
filePath into a single object.
Example:
```js
const editorconfig = require('editorconfig');
const path = require('path');
const filePath = path.join(__dirname, 'sample.js');
(async () => {
console.log(await editorconfig.parse(filePath, {files: []}));
})();
/*
{
indent_style: 'space',
indent_size: 2,
end_of_line: 'lf',
charset: 'utf-8',
trim_trailing_whitespace: true,
insert_final_newline: true,
tab_width: 2
};
assert.deepEqual(files, [
{ fileName: '[DIRECTORY]/.editorconfig', glob: '*' },
{ fileName: '[DIRECTORY]/.editorconfig', glob: '*.js' }
])
*/
```
#### parseSync(filePath[, options])
Synchronous version of `editorconfig.parse()`.
#### parseBuffer(fileContent)
The `parse()` function above uses `parseBuffer()` under the hood. If you have
the contents of a config file, and want to see what is being processed for
just that file rather than the full directory hierarchy, this might be useful.
#### parseString(fileContent)
This is a thin wrapper around `parseBuffer()` for backward-compatibility.
Prefer `parseBuffer()` to avoid an unnecessary UTF8-to-UTF16-to-UTF8
conversion. Deprecated.
#### parseFromFiles(filePath, configs[, options])
Low-level interface, which exists only for backward-compatibility. Deprecated.
Example:
```js
const editorconfig = require('editorconfig');
const fs = require('fs');
const path = require('path');
const configPath = path.join(__dirname, '.editorconfig');
const configs = [
{
name: configPath,
contents: fs.readFileSync(configPath, 'utf8')
}
];
const filePath = path.join(__dirname, '/sample.js');
(async () => {
console.log(await editorconfig.parseFromFiles(filePath, Promise.resolve(configs)))
})();
/*
{
indent_style: 'space',
indent_size: 2,
end_of_line: 'lf',
charset: 'utf-8',
trim_trailing_whitespace: true,
insert_final_newline: true,
tab_width: 2
};
*/
```
#### parseFromFilesSync(filePath, configs[, options])
Synchronous version of `editorconfig.parseFromFiles()`. Deprecated.
### in Command Line
```bash
$ ./bin/editorconfig
Usage: editorconfig [options] <FILEPATH...>
Arguments:
FILEPATH Files to find configuration for. Can be a hyphen (-) if you
want path(s) to be read from stdin.
Options:
-v, --version Display version information from the package
-f <path> Specify conf filename other than '.editorconfig'
-b <version> Specify version (used by devs to test compatibility)
--files Output file names that contributed to the configuration,
rather than the configuation itself
-h, --help display help for command
```
Example:
```bash
$ ./bin/editorconfig /home/zoidberg/humans/anatomy.md
charset=utf-8
insert_final_newline=true
end_of_line=lf
tab_width=8
trim_trailing_whitespace=sometimes
```
```bash
$ ./bin/editorconfig --files /home/zoidberg/humans/anatomy.md
/home/zoidberg/.editorconfig [*]
/home/zoidberg/.editorconfig [*.md]
/home/zoidberg/humans/.editorconfig [*]
```
## Development
To install dependencies for this package run this in the package directory:
```bash
$ npm install
```
Next, run the following commands:
```bash
$ npm run build
$ npm link
```
The global editorconfig will now point to the files in your development
repository instead of a globally-installed version from npm. You can now use
editorconfig directly to test your changes.
If you ever update from the central repository and there are errors, it might
be because you are missing some dependencies. If that happens, just run npm
link again to get the latest dependencies.
To test the command line interface:
```bash
$ editorconfig <filepath>
```
# Testing
[CMake][] must be installed to run the tests.
To run the tests:
```bash
$ npm test
```
To run the tests with increased verbosity (for debugging test failures):
```bash
$ npm run ci
```
[EditorConfig C Core]: https://github.com/editorconfig/editorconfig-core
[EditorConfig Python Core]: https://github.com/editorconfig/editorconfig-core-py
[node]: http://nodejs.org/
[cmake]: http://www.cmake.org

6
node_modules/editorconfig/bin/editorconfig generated vendored Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env node
var cli = require('../lib/cli')
cli.default(process.argv).catch(e => {
console.error(e)
process.exit(1)
})

14
node_modules/editorconfig/lib/cli.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
import { type OutputConfiguration } from 'commander';
import * as editorconfig from './';
/**
* Command line interface for editorconfig. Pulled out into a separate module
* to make it easier to test.
*
* @param args Usually process.argv. Note that the first two parameters are
* usually 'node' and 'editorconfig'
* @param testing If testing, you may pass in a Commander OutputConfiguration
* so that you can capture stdout and stderror. If `testing` is provided,
* this routine will throw an error instead of calling `process.exit`.
* @returns An array of combined properties, one for each file argument.
*/
export default function cli(args: string[], testing?: OutputConfiguration): Promise<editorconfig.Props[]>;

109
node_modules/editorconfig/lib/cli.js generated vendored Normal file
View File

@@ -0,0 +1,109 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = require("commander");
const editorconfig = __importStar(require("./"));
const package_json_1 = __importDefault(require("../package.json"));
/**
* Default output routine, goes to stdout.
*
* @param s String to output
*/
function writeStdOut(s) {
process.stdout.write(s);
}
/**
* Command line interface for editorconfig. Pulled out into a separate module
* to make it easier to test.
*
* @param args Usually process.argv. Note that the first two parameters are
* usually 'node' and 'editorconfig'
* @param testing If testing, you may pass in a Commander OutputConfiguration
* so that you can capture stdout and stderror. If `testing` is provided,
* this routine will throw an error instead of calling `process.exit`.
* @returns An array of combined properties, one for each file argument.
*/
async function cli(args, testing) {
const program = new commander_1.Command();
let writeOut = writeStdOut;
if (testing) {
if (testing.writeOut) {
// eslint-disable-next-line @typescript-eslint/unbound-method
writeOut = testing.writeOut;
}
program.configureOutput(testing);
program.exitOverride();
}
program.version('EditorConfig Node.js Core Version ' + package_json_1.default.version, '-v, --version', 'Display version information')
.showHelpAfterError()
.argument('<FILEPATH...>', 'Files to find configuration for. Can be a hyphen (-) if you want path(s) to be read from stdin.')
.option('-f <path>', 'Specify conf filename other than \'.editorconfig\'')
.option('-b <version>', 'Specify version (used by devs to test compatibility)')
.option('--files', 'Output file names that contributed to the configuration, rather than the configuation itself')
.parse(args);
const files = program.args;
const opts = program.opts();
const cache = new Map();
const visited = opts.files ?
files.map(() => []) :
undefined;
// Process sequentially so caching works
async function processAll() {
const p = [];
let i = 0;
for (const filePath of files) {
p.push(await editorconfig.parse(filePath, {
config: opts.f,
version: opts.b,
files: visited ? visited[i++] : undefined,
cache,
}));
}
return p;
}
return await processAll().then((parsed) => {
const header = parsed.length > 1;
parsed.forEach((props, i) => {
if (header) {
writeOut(`[${files[i]}]\n`);
}
if (visited) {
for (const v of visited[i]) {
writeOut(`${v.fileName} [${v.glob}]\n`);
}
}
else {
for (const [key, value] of Object.entries(props)) {
writeOut(`${key}=${String(value)}\n`);
}
}
});
return parsed;
});
}
exports.default = cli;

105
node_modules/editorconfig/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,105 @@
/// <reference types="node" />
import { Minimatch } from 'minimatch';
export interface KnownProps {
end_of_line?: 'lf' | 'crlf' | 'unset';
indent_style?: 'tab' | 'space' | 'unset';
indent_size?: number | 'tab' | 'unset';
insert_final_newline?: true | false | 'unset';
tab_width?: number | 'unset';
trim_trailing_whitespace?: true | false | 'unset';
charset?: string | 'unset';
}
interface UnknownMap {
[index: string]: unknown;
}
export type Props = KnownProps & UnknownMap;
export interface ECFile {
name: string;
contents?: Buffer;
}
type SectionGlob = Minimatch | null;
type GlobbedProps = [SectionName, Props, SectionGlob][];
export interface ProcessedFileConfig {
root: boolean;
name: string;
config: GlobbedProps;
notfound?: true;
}
export interface Visited {
fileName: string;
glob: string;
}
export interface Cache {
get(path: string): ProcessedFileConfig | undefined;
set(path: string, config: ProcessedFileConfig): this;
}
export interface ParseOptions {
config?: string;
version?: string;
root?: string;
files?: Visited[];
cache?: Cache;
}
export type SectionName = string | null;
export interface SectionBody {
[key: string]: string;
}
export type ParseStringResult = [SectionName, SectionBody][];
/**
* Parse a buffer using the faster one-ini WASM approach into something
* relatively easy to deal with in JS.
*
* @param data UTF8-encoded bytes.
* @returns Parsed contents. Will be truncated if there was a parse error.
*/
export declare function parseBuffer(data: Buffer): ParseStringResult;
/**
* Parses a string. If possible, you should always use ParseBuffer instead,
* since this function does a UTF16-to-UTF8 conversion first.
*
* @param data String to parse.
* @returns Parsed contents. Will be truncated if there was a parse error.
* @deprecated Use {@link ParseBuffer} instead.
*/
export declare function parseString(data: string): ParseStringResult;
/**
* Low-level interface, which exists only for backward-compatibility.
* Deprecated.
*
* @param filepath The name of the target file, relative to process.cwd().
* @param files A promise for a list of objects describing the files.
* @param options All options
* @returns The properties found for filepath
* @deprecated
*/
export declare function parseFromFiles(filepath: string, files: Promise<ECFile[]>, options?: ParseOptions): Promise<Props>;
/**
* Low-level interface, which exists only for backward-compatibility.
* Deprecated.
*
* @param filepath The name of the target file, relative to process.cwd().
* @param files A list of objects describing the files.
* @param options All options
* @returns The properties found for filepath
* @deprecated
*/
export declare function parseFromFilesSync(filepath: string, files: ECFile[], options?: ParseOptions): Props;
/**
* Find all of the properties from matching sections in config files in the
* same directory or toward the root of the filesystem.
*
* @param filepath The target file name, relative to process.cwd().
* @param options All options
* @returns Combined properties for the target file
*/
export declare function parse(filepath: string, options?: ParseOptions): Promise<Props>;
/**
* Find all of the properties from matching sections in config files in the
* same directory or toward the root of the filesystem. Synchronous.
*
* @param filepath The target file name, relative to process.cwd().
* @param options All options
* @returns Combined properties for the target file
*/
export declare function parseSync(filepath: string, options?: ParseOptions): Props;
export {};

460
node_modules/editorconfig/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,460 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseSync = exports.parse = exports.parseFromFilesSync = exports.parseFromFiles = exports.parseString = exports.parseBuffer = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const semver = __importStar(require("semver"));
const minimatch_1 = require("minimatch");
const wasm_1 = require("@one-ini/wasm");
// @ts-ignore So we can set the rootDir to be 'lib', without processing
// package.json
const package_json_1 = __importDefault(require("../package.json"));
const escapedSep = new RegExp(path.sep.replace(/\\/g, '\\\\'), 'g');
const matchOptions = { matchBase: true, dot: true, noext: true };
// These are specified by the editorconfig script
/* eslint-disable @typescript-eslint/naming-convention */
const knownProps = {
end_of_line: true,
indent_style: true,
indent_size: true,
insert_final_newline: true,
trim_trailing_whitespace: true,
charset: true,
};
/**
* Parse a buffer using the faster one-ini WASM approach into something
* relatively easy to deal with in JS.
*
* @param data UTF8-encoded bytes.
* @returns Parsed contents. Will be truncated if there was a parse error.
*/
function parseBuffer(data) {
const parsed = (0, wasm_1.parse_to_uint32array)(data);
let cur = {};
const res = [[null, cur]];
let key = null;
for (let i = 0; i < parsed.length; i += 3) {
switch (parsed[i]) {
case wasm_1.TokenTypes.Section: {
cur = {};
res.push([
data.toString('utf8', parsed[i + 1], parsed[i + 2]),
cur,
]);
break;
}
case wasm_1.TokenTypes.Key:
key = data.toString('utf8', parsed[i + 1], parsed[i + 2]);
break;
case wasm_1.TokenTypes.Value: {
cur[key] = data.toString('utf8', parsed[i + 1], parsed[i + 2]);
break;
}
default: // Comments, etc.
break;
}
}
return res;
}
exports.parseBuffer = parseBuffer;
/**
* Parses a string. If possible, you should always use ParseBuffer instead,
* since this function does a UTF16-to-UTF8 conversion first.
*
* @param data String to parse.
* @returns Parsed contents. Will be truncated if there was a parse error.
* @deprecated Use {@link ParseBuffer} instead.
*/
function parseString(data) {
return parseBuffer(Buffer.from(data));
}
exports.parseString = parseString;
/**
* Gets a list of *potential* filenames based on the path of the target
* filename.
*
* @param filepath File we are asking about.
* @param options Config file name and root directory
* @returns List of potential fully-qualified filenames that might have configs.
*/
function getConfigFileNames(filepath, options) {
const paths = [];
do {
filepath = path.dirname(filepath);
paths.push(path.join(filepath, options.config));
} while (filepath !== options.root);
return paths;
}
/**
* Take a combined config for the target file, and tweak it slightly based on
* which editorconfig version's rules we are using.
*
* @param matches Combined config.
* @param version Editorconfig version to enforce.
* @returns The passed-in matches object, modified in place.
*/
function processMatches(matches, version) {
// Set indent_size to 'tab' if indent_size is unspecified and
// indent_style is set to 'tab'.
if ('indent_style' in matches
&& matches.indent_style === 'tab'
&& !('indent_size' in matches)
&& semver.gte(version, '0.10.0')) {
matches.indent_size = 'tab';
}
// Set tab_width to indent_size if indent_size is specified and
// tab_width is unspecified
if ('indent_size' in matches
&& !('tab_width' in matches)
&& matches.indent_size !== 'tab') {
matches.tab_width = matches.indent_size;
}
// Set indent_size to tab_width if indent_size is 'tab'
if ('indent_size' in matches
&& 'tab_width' in matches
&& matches.indent_size === 'tab') {
matches.indent_size = matches.tab_width;
}
return matches;
}
function buildFullGlob(pathPrefix, glob) {
switch (glob.indexOf('/')) {
case -1:
glob = '**/' + glob;
break;
case 0:
glob = glob.substring(1);
break;
default:
break;
}
// braces_escaped_backslash2
// backslash_not_on_windows
glob = glob.replace(/\\\\/g, '\\\\\\\\');
// star_star_over_separator{1,3,5,6,9,15}
glob = glob.replace(/\*\*/g, '{*,**/**/**}');
// NOT path.join. Must stay in forward slashes.
return new minimatch_1.Minimatch(`${pathPrefix}/${glob}`, matchOptions);
}
/**
* Normalize the properties read from a config file so that their key names
* are lowercased for the known properties, and their values are parsed into
* the correct JS types if possible.
*
* @param options
* @returns
*/
function normalizeProps(options) {
const props = {};
for (const key in options) {
if (options.hasOwnProperty(key)) {
const value = options[key];
const key2 = key.toLowerCase();
let value2 = value;
// @ts-ignore -- Fix types here
if (knownProps[key2]) {
// All of the values for the known props are lowercase.
value2 = String(value).toLowerCase();
}
try {
value2 = JSON.parse(String(value));
}
catch (e) { }
if (typeof value2 === 'undefined' || value2 === null) {
// null and undefined are values specific to JSON (no special meaning
// in editorconfig) & should just be returned as regular strings.
value2 = String(value);
}
// @ts-ignore -- Fix types here
props[key2] = value2;
}
}
return props;
}
/**
* Take the contents of a config file, and prepare it for use. If a cache is
* provided, the result will be stored there. As such, all of the higher-CPU
* work that is per-file should be done here.
*
* @param filepath The fully-qualified path of the file.
* @param contents The contents as read from that file.
* @param options Access to the cache.
* @returns Processed file with globs pre-computed.
*/
function processFileContents(filepath, contents, options) {
let res;
if (!contents) {
// Negative cache
res = {
root: false,
notfound: true,
name: filepath,
config: [[null, {}, null]],
};
}
else {
let pathPrefix = path.dirname(filepath);
if (path.sep !== '/') {
// Windows-only
pathPrefix = pathPrefix.replace(escapedSep, '/');
}
// After Windows path backslash's are turned into slashes, so that
// the backslashes we add here aren't turned into forward slashes:
// All of these characters are special to minimatch, but can be
// forced into path names on many file systems. Escape them. Note
// that these are in the order of the case statement in minimatch.
pathPrefix = pathPrefix.replace(/[?*+@!()|[\]{}]/g, '\\$&');
// I can't think of a way for this to happen in the filesystems I've
// seen (because of the path.dirname above), but let's be thorough.
pathPrefix = pathPrefix.replace(/^#/, '\\#');
const globbed = parseBuffer(contents).map(([name, body]) => [
name,
normalizeProps(body),
name ? buildFullGlob(pathPrefix, name) : null,
]);
res = {
root: !!globbed[0][1].root,
name: filepath,
config: globbed,
};
}
if (options.cache) {
options.cache.set(filepath, res);
}
return res;
}
/**
* Get a file from the cache, or read its contents from disk, process, and
* insert into the cache (if configured).
*
* @param filepath The fully-qualified path of the config file.
* @param options Access to the cache, if configured.
* @returns The processed file, or undefined if there was an error reading it.
*/
async function getConfig(filepath, options) {
if (options.cache) {
const cached = options.cache.get(filepath);
if (cached) {
return cached;
}
}
const contents = await new Promise(resolve => {
fs.readFile(filepath, (_, buf) => {
// Ignore errors. contents will be undefined
// Perhaps only file-not-found should be ignored?
resolve(buf);
});
});
return processFileContents(filepath, contents, options);
}
/**
* Get a file from the cache, or read its contents from disk, process, and
* insert into the cache (if configured). Synchronous.
*
* @param filepath The fully-qualified path of the config file.
* @param options Access to the cache, if configured.
* @returns The processed file, or undefined if there was an error reading it.
*/
function getConfigSync(filepath, options) {
if (options.cache) {
const cached = options.cache.get(filepath);
if (cached) {
return cached;
}
}
let contents;
try {
contents = fs.readFileSync(filepath);
}
catch (_) {
// Ignore errors
// Perhaps only file-not-found should be ignored
}
return processFileContents(filepath, contents, options);
}
/**
* Get all of the possibly-existing config files, stopping when one is marked
* root=true.
*
* @param files List of potential files
* @param options Access to cache if configured
* @returns List of processed configs for existing files
*/
async function getAllConfigs(files, options) {
const configs = [];
for (const file of files) {
const config = await getConfig(file, options);
if (!config.notfound) {
configs.push(config);
if (config.root) {
break;
}
}
}
return configs;
}
/**
* Get all of the possibly-existing config files, stopping when one is marked
* root=true. Synchronous.
*
* @param files List of potential files
* @param options Access to cache if configured
* @returns List of processed configs for existing files
*/
function getAllConfigsSync(files, options) {
const configs = [];
for (const file of files) {
const config = getConfigSync(file, options);
if (!config.notfound) {
configs.push(config);
if (config.root) {
break;
}
}
}
return configs;
}
/**
* Normalize the options passed in to the publicly-visible functions.
*
* @param filepath The name of the target file, relative to process.cwd().
* @param options Potentially-incomplete options.
* @returns The fully-qualified target file name and the normalized options.
*/
function opts(filepath, options = {}) {
const resolvedFilePath = path.resolve(filepath);
return [
resolvedFilePath,
{
config: options.config || '.editorconfig',
version: options.version || package_json_1.default.version,
root: path.resolve(options.root || path.parse(resolvedFilePath).root),
files: options.files,
cache: options.cache,
},
];
}
/**
* Low-level interface, which exists only for backward-compatibility.
* Deprecated.
*
* @param filepath The name of the target file, relative to process.cwd().
* @param files A promise for a list of objects describing the files.
* @param options All options
* @returns The properties found for filepath
* @deprecated
*/
async function parseFromFiles(filepath, files, options = {}) {
return parseFromFilesSync(filepath, await files, options);
}
exports.parseFromFiles = parseFromFiles;
/**
* Low-level interface, which exists only for backward-compatibility.
* Deprecated.
*
* @param filepath The name of the target file, relative to process.cwd().
* @param files A list of objects describing the files.
* @param options All options
* @returns The properties found for filepath
* @deprecated
*/
function parseFromFilesSync(filepath, files, options = {}) {
const [resolvedFilePath, processedOptions] = opts(filepath, options);
const configs = [];
for (const ecf of files) {
let cfg;
if (!options.cache || !(cfg = options.cache.get(ecf.name))) { // Single "="!
cfg = processFileContents(ecf.name, ecf.contents, processedOptions);
}
if (!cfg.notfound) {
configs.push(cfg);
}
if (cfg.root) {
break;
}
}
return combine(resolvedFilePath, configs, processedOptions);
}
exports.parseFromFilesSync = parseFromFilesSync;
/**
* Combine the pre-parsed results of all matching config file sections, in
* order.
*
* @param filepath The target file path
* @param configs All of the found config files, up to the root
* @param options Adds to `options.files` if it exists
* @returns Combined properties
*/
function combine(filepath, configs, options) {
const ret = configs.reverse().reduce((props, processed) => {
for (const [name, body, glob] of processed.config) {
if (glob && glob.match(filepath)) {
Object.assign(props, body);
if (options.files) {
options.files.push({
fileName: processed.name,
glob: name,
});
}
}
}
return props;
}, {});
return processMatches(ret, options.version);
}
/**
* Find all of the properties from matching sections in config files in the
* same directory or toward the root of the filesystem.
*
* @param filepath The target file name, relative to process.cwd().
* @param options All options
* @returns Combined properties for the target file
*/
async function parse(filepath, options = {}) {
const [resolvedFilePath, processedOptions] = opts(filepath, options);
const filepaths = getConfigFileNames(resolvedFilePath, processedOptions);
const configs = await getAllConfigs(filepaths, processedOptions);
return combine(resolvedFilePath, configs, processedOptions);
}
exports.parse = parse;
/**
* Find all of the properties from matching sections in config files in the
* same directory or toward the root of the filesystem. Synchronous.
*
* @param filepath The target file name, relative to process.cwd().
* @param options All options
* @returns Combined properties for the target file
*/
function parseSync(filepath, options = {}) {
const [resolvedFilePath, processedOptions] = opts(filepath, options);
const filepaths = getConfigFileNames(resolvedFilePath, processedOptions);
const configs = getAllConfigsSync(filepaths, processedOptions);
return combine(resolvedFilePath, configs, processedOptions);
}
exports.parseSync = parseSync;

65
node_modules/editorconfig/package.json generated vendored Normal file
View File

@@ -0,0 +1,65 @@
{
"name": "editorconfig",
"version": "1.0.4",
"description": "EditorConfig File Locator and Interpreter for Node.js",
"keywords": [
"editorconfig",
"core"
],
"main": "./lib/index.js",
"contributors": [
"Hong Xu (topbug.net)",
"Jed Mao (https://github.com/jedmao/)",
"Trey Hunner (http://treyhunner.com)",
"Joe Hildebrand (https://github.com/hildjj/)"
],
"directories": {
"bin": "./bin",
"lib": "./lib"
},
"scripts": {
"clean": "rimraf lib cmake_install.cmake CTestTestfile.cmake Makefile",
"prebuild": "npm run clean",
"build": "cmake . && tsc",
"pretest": "npm run build && npm run lint",
"test": "npm run test:all",
"test:all": "mocha && ctest . --preset Test",
"precoverage": "npm run build -- --inlineSourceMap",
"coverage": "c8 npm run test:all",
"postcoverage": "npm run build",
"ci": "npm run coverage -- -- -VV --output-on-failure",
"lint": "eslint . --ext ts",
"prepub": "npm run lint && npm run build",
"pub": "npm publish"
},
"repository": {
"type": "git",
"url": "git://github.com/editorconfig/editorconfig-core-js.git"
},
"bugs": "https://github.com/editorconfig/editorconfig-core-js/issues",
"author": "EditorConfig Team",
"license": "MIT",
"dependencies": {
"@one-ini/wasm": "0.1.1",
"commander": "^10.0.0",
"minimatch": "9.0.1",
"semver": "^7.5.3"
},
"devDependencies": {
"@types/mocha": "^10.0.1",
"@types/node": "^20.3.1",
"@types/semver": "^7.5.0",
"@typescript-eslint/eslint-plugin": "5.60.0",
"@typescript-eslint/parser": "5.60.0",
"c8": "8.0.0",
"eslint": "8.43.0",
"eslint-plugin-jsdoc": "46.2.6",
"mocha": "^10.2.0",
"rimraf": "^5.0.1",
"should": "^13.2.3",
"typescript": "^5.1.3"
},
"engines": {
"node": ">=14"
}
}