linguist-js 2.9.0 → 2.9.1

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.
Files changed (38) hide show
  1. package/dist/cli.js +7 -0
  2. package/dist/helpers/convert-pcre.js +1 -1
  3. package/dist/helpers/load-data.js +2 -3
  4. package/dist/helpers/parse-gitattributes.js +1 -1
  5. package/dist/helpers/parse-gitignore.js +1 -1
  6. package/dist/helpers/read-file.js +1 -1
  7. package/dist/helpers/walk-tree.js +1 -1
  8. package/dist/index.js +1 -1
  9. package/ext/generated.rb +1 -1
  10. package/ext/heuristics.yml +45 -14
  11. package/ext/languages.yml +42 -3
  12. package/license.md +1 -1
  13. package/package.json +2 -2
  14. package/dist/package.json +0 -56
  15. package/dist/src/cli.d.ts +0 -1
  16. package/dist/src/cli.js +0 -146
  17. package/dist/src/helpers/convert-pcre.d.ts +0 -2
  18. package/dist/src/helpers/convert-pcre.js +0 -38
  19. package/dist/src/helpers/load-data.d.ts +0 -4
  20. package/dist/src/helpers/load-data.js +0 -37
  21. package/dist/src/helpers/norm-path.d.ts +0 -2
  22. package/dist/src/helpers/norm-path.js +0 -15
  23. package/dist/src/helpers/parse-gitattributes.d.ts +0 -17
  24. package/dist/src/helpers/parse-gitattributes.js +0 -37
  25. package/dist/src/helpers/parse-gitignore.d.ts +0 -1
  26. package/dist/src/helpers/parse-gitignore.js +0 -12
  27. package/dist/src/helpers/read-file.d.ts +0 -5
  28. package/dist/src/helpers/read-file.js +0 -23
  29. package/dist/src/helpers/walk-tree.d.ts +0 -20
  30. package/dist/src/helpers/walk-tree.js +0 -85
  31. package/dist/src/index.d.ts +0 -4
  32. package/dist/src/index.js +0 -485
  33. package/dist/src/schema.d.ts +0 -37
  34. package/dist/src/schema.js +0 -2
  35. package/dist/src/types.d.ts +0 -74
  36. package/dist/src/types.js +0 -2
  37. package/dist/version.d.ts +0 -2
  38. package/dist/version.js +0 -4
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = pcre;
4
- /** Convert a PCRE regex into JS. */
5
- function pcre(regex) {
6
- let finalRegex = regex;
7
- const replace = (search, replace) => finalRegex = finalRegex.replace(search, replace);
8
- const finalFlags = new Set();
9
- // Convert inline flag declarations
10
- const inlineMatches = regex.matchAll(/\?(-)?([a-z]):/g);
11
- const startMatches = regex.matchAll(/\(\?(-)?([a-z]+)\)/g);
12
- for (const [match, isNegative, flags] of [...inlineMatches, ...startMatches]) {
13
- replace(match, '');
14
- const func = (flag) => isNegative ? finalFlags.delete(flag) : finalFlags.add(flag);
15
- [...flags].forEach(func);
16
- }
17
- // Remove PCRE-only syntax
18
- replace(/([*+]){2}/g, '$1');
19
- replace(/\(\?>/g, '(?:');
20
- // Remove start/end-of-file markers
21
- if (/\\[AZ]/.test(finalRegex)) {
22
- replace(/\\A/g, '^');
23
- replace(/\\Z/g, '$');
24
- finalFlags.delete('m');
25
- }
26
- else {
27
- finalFlags.add('m');
28
- }
29
- // Reformat free-spacing mode
30
- if (finalFlags.has('x')) {
31
- finalFlags.delete('x');
32
- replace(/#.+/g, '');
33
- replace(/^\s+|\s+$|\n/gm, '');
34
- replace(/\s+/g, ' ');
35
- }
36
- // Return final regex
37
- return RegExp(finalRegex, [...finalFlags].join(''));
38
- }
@@ -1,4 +0,0 @@
1
- /** Nukes unused `generated.rb` file content. */
2
- export declare function parseGeneratedDataFile(fileContent: string): Promise<string[]>;
3
- /** Load a data file from github-linguist. */
4
- export default function loadFile(file: string, offline?: boolean): Promise<string>;
@@ -1,37 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.parseGeneratedDataFile = parseGeneratedDataFile;
7
- exports.default = loadFile;
8
- const node_fs_1 = __importDefault(require("node:fs"));
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const cross_fetch_1 = __importDefault(require("cross-fetch"));
11
- const node_cache_1 = __importDefault(require("node-cache"));
12
- const cache = new node_cache_1.default({});
13
- async function loadWebFile(file) {
14
- // Return cache if it exists
15
- const cachedContent = cache.get(file);
16
- if (cachedContent)
17
- return cachedContent;
18
- // Otherwise cache the request
19
- const dataUrl = (file) => `https://raw.githubusercontent.com/github/linguist/HEAD/lib/linguist/${file}`;
20
- // Load file content, falling back to the local file if the request fails
21
- const fileContent = await (0, cross_fetch_1.default)(dataUrl(file)).then(data => data.text()).catch(async () => await loadLocalFile(file));
22
- cache.set(file, fileContent);
23
- return fileContent;
24
- }
25
- async function loadLocalFile(file) {
26
- const filePath = node_path_1.default.resolve(__dirname, '../../ext', file);
27
- return node_fs_1.default.promises.readFile(filePath).then(buffer => buffer.toString());
28
- }
29
- /** Nukes unused `generated.rb` file content. */
30
- async function parseGeneratedDataFile(fileContent) {
31
- var _a;
32
- return [...(_a = fileContent.match(/(?<=name\.match\(\/).+?(?=(?<!\\)\/)/gm)) !== null && _a !== void 0 ? _a : []];
33
- }
34
- /** Load a data file from github-linguist. */
35
- async function loadFile(file, offline = false) {
36
- return offline ? loadLocalFile(file) : loadWebFile(file);
37
- }
@@ -1,2 +0,0 @@
1
- export declare const normPath: (...inputPaths: string[]) => string;
2
- export declare const normAbsPath: (...inputPaths: string[]) => string;
@@ -1,15 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.normAbsPath = exports.normPath = void 0;
7
- const node_path_1 = __importDefault(require("node:path"));
8
- const normPath = function normalisedPath(...inputPaths) {
9
- return node_path_1.default.join(...inputPaths).replace(/\\/g, '/');
10
- };
11
- exports.normPath = normPath;
12
- const normAbsPath = function normalisedAbsolutePath(...inputPaths) {
13
- return node_path_1.default.resolve(...inputPaths).replace(/\\/g, '/');
14
- };
15
- exports.normAbsPath = normAbsPath;
@@ -1,17 +0,0 @@
1
- import * as T from '../types';
2
- export type FlagAttributes = {
3
- 'vendored': boolean | null;
4
- 'generated': boolean | null;
5
- 'documentation': boolean | null;
6
- 'detectable': boolean | null;
7
- 'binary': boolean | null;
8
- 'language': T.LanguageResult;
9
- };
10
- export type ParsedGitattributes = Array<{
11
- glob: T.FileGlob;
12
- attrs: FlagAttributes;
13
- }>;
14
- /**
15
- * Parses a gitattributes file.
16
- */
17
- export default function parseAttributes(content: string, folderRoot?: string): ParsedGitattributes;
@@ -1,37 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = parseAttributes;
4
- const norm_path_1 = require("./norm-path");
5
- /**
6
- * Parses a gitattributes file.
7
- */
8
- function parseAttributes(content, folderRoot = '.') {
9
- var _a, _b;
10
- const output = [];
11
- for (const rawLine of content.split('\n')) {
12
- const line = rawLine.replace(/#.*/, '').trim();
13
- if (!line)
14
- continue;
15
- const parts = line.split(/\s+/g);
16
- const fileGlob = parts[0];
17
- const relFileGlob = (0, norm_path_1.normPath)(folderRoot, fileGlob);
18
- const attrParts = parts.slice(1);
19
- const isTrue = (str) => !str.startsWith('-') && !str.endsWith('=false');
20
- const isFalse = (str) => str.startsWith('-') || str.endsWith('=false');
21
- const trueParts = (str) => attrParts.filter(part => part.includes(str) && isTrue(part));
22
- const falseParts = (str) => attrParts.filter(part => part.includes(str) && isFalse(part));
23
- const hasTrueParts = (str) => trueParts(str).length > 0;
24
- const hasFalseParts = (str) => falseParts(str).length > 0;
25
- const boolOrNullVal = (str) => hasTrueParts(str) ? true : hasFalseParts(str) ? false : null;
26
- const attrs = {
27
- 'generated': boolOrNullVal('linguist-generated'),
28
- 'vendored': boolOrNullVal('linguist-vendored'),
29
- 'documentation': boolOrNullVal('linguist-documentation'),
30
- 'detectable': boolOrNullVal('linguist-detectable'),
31
- 'binary': hasTrueParts('binary') || hasFalseParts('text') ? true : hasFalseParts('binary') || hasTrueParts('text') ? false : null,
32
- 'language': (_b = (_a = trueParts('linguist-language').at(-1)) === null || _a === void 0 ? void 0 : _a.split('=')[1]) !== null && _b !== void 0 ? _b : null,
33
- };
34
- output.push({ glob: relFileGlob, attrs });
35
- }
36
- return output;
37
- }
@@ -1 +0,0 @@
1
- export default function parseGitignore(content: string): string[];
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = parseGitignore;
4
- function parseGitignore(content) {
5
- const readableData = content
6
- // Remove comments unless escaped
7
- .replace(/(?<!\\)#.+/g, '')
8
- // Remove whitespace unless escaped
9
- .replace(/(?:(?<!\\)\s)+$/g, '');
10
- const arrayData = readableData.split(/\r?\n/).filter(data => data);
11
- return arrayData;
12
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Read part of a file on disc.
3
- * @throws 'EPERM' if the file is not readable.
4
- */
5
- export default function readFileChunk(filename: string, onlyFirstLine?: boolean): Promise<string>;
@@ -1,23 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.default = readFileChunk;
7
- const node_fs_1 = __importDefault(require("node:fs"));
8
- /**
9
- * Read part of a file on disc.
10
- * @throws 'EPERM' if the file is not readable.
11
- */
12
- async function readFileChunk(filename, onlyFirstLine = false) {
13
- const chunkSize = 100;
14
- const stream = node_fs_1.default.createReadStream(filename, { highWaterMark: chunkSize });
15
- let content = '';
16
- for await (const data of stream) { // may throw
17
- content += data.toString();
18
- if (onlyFirstLine && content.includes('\n')) {
19
- return content.split(/\r?\n/)[0];
20
- }
21
- }
22
- return content;
23
- }
@@ -1,20 +0,0 @@
1
- import { Ignore } from 'ignore';
2
- interface WalkInput {
3
- /** Whether this is walking the tree from the root */
4
- init: boolean;
5
- /** The common root absolute path of all folders being checked */
6
- commonRoot: string;
7
- /** The absolute path that each folder is relative to */
8
- folderRoots: string[];
9
- /** The absolute path of folders being checked */
10
- folders: string[];
11
- /** An instantiated Ignore object listing ignored files */
12
- ignored: Ignore;
13
- }
14
- interface WalkOutput {
15
- files: string[];
16
- folders: string[];
17
- }
18
- /** Generate list of files in a directory. */
19
- export default function walk(data: WalkInput): WalkOutput;
20
- export {};
@@ -1,85 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.default = walk;
7
- const node_fs_1 = __importDefault(require("node:fs"));
8
- const node_path_1 = __importDefault(require("node:path"));
9
- const parse_gitignore_1 = __importDefault(require("./parse-gitignore"));
10
- const norm_path_1 = require("./norm-path");
11
- let allFiles;
12
- let allFolders;
13
- ;
14
- ;
15
- /** Generate list of files in a directory. */
16
- function walk(data) {
17
- const { init, commonRoot, folderRoots, folders, ignored } = data;
18
- // Initialise files and folders lists
19
- if (init) {
20
- allFiles = new Set();
21
- allFolders = new Set();
22
- }
23
- // Walk tree of a folder
24
- if (folders.length === 1) {
25
- const folder = folders[0];
26
- const localRoot = folderRoots[0].replace(commonRoot, '').replace(/^\//, '');
27
- // Get list of files and folders inside this folder
28
- const files = node_fs_1.default.readdirSync(folder).map(file => {
29
- // Create path relative to root
30
- const base = (0, norm_path_1.normAbsPath)(folder, file).replace(commonRoot, '.');
31
- // Add trailing slash to mark directories
32
- const isDir = node_fs_1.default.lstatSync(node_path_1.default.resolve(commonRoot, base)).isDirectory();
33
- return isDir ? `${base}/` : base;
34
- });
35
- // Read and apply gitignores
36
- const gitignoreFilename = (0, norm_path_1.normPath)(folder, '.gitignore');
37
- if (node_fs_1.default.existsSync(gitignoreFilename)) {
38
- const gitignoreContents = node_fs_1.default.readFileSync(gitignoreFilename, 'utf-8');
39
- const ignoredPaths = (0, parse_gitignore_1.default)(gitignoreContents);
40
- ignored.add(ignoredPaths);
41
- }
42
- // Add gitattributes if present
43
- const gitattributesPath = (0, norm_path_1.normPath)(folder, '.gitattributes');
44
- if (node_fs_1.default.existsSync(gitattributesPath)) {
45
- allFiles.add(gitattributesPath);
46
- }
47
- // Loop through files and folders
48
- for (const file of files) {
49
- // Create absolute path for disc operations
50
- const path = (0, norm_path_1.normAbsPath)(commonRoot, file);
51
- const localPath = localRoot ? file.replace(`./${localRoot}/`, '') : file.replace('./', '');
52
- // Skip if nonexistant
53
- const nonExistant = !node_fs_1.default.existsSync(path);
54
- if (nonExistant)
55
- continue;
56
- // Skip if marked in gitignore
57
- const isIgnored = ignored.test(localPath).ignored;
58
- if (isIgnored)
59
- continue;
60
- // Add absolute folder path to list
61
- allFolders.add((0, norm_path_1.normAbsPath)(folder));
62
- // Check if this is a folder or file
63
- if (file.endsWith('/')) {
64
- // Recurse into subfolders
65
- allFolders.add(path);
66
- walk({ init: false, commonRoot, folderRoots, folders: [path], ignored });
67
- }
68
- else {
69
- // Add file path to list
70
- allFiles.add(path);
71
- }
72
- }
73
- }
74
- // Recurse into all folders
75
- else {
76
- for (const i in folders) {
77
- walk({ init: false, commonRoot, folderRoots: [folderRoots[i]], folders: [folders[i]], ignored });
78
- }
79
- }
80
- // Return absolute files and folders lists
81
- return {
82
- files: [...allFiles].map(file => file.replace(/^\./, commonRoot)),
83
- folders: [...allFolders],
84
- };
85
- }
@@ -1,4 +0,0 @@
1
- import * as T from './types';
2
- declare function analyse(path?: string, opts?: T.Options): Promise<T.Results>;
3
- declare function analyse(paths?: string[], opts?: T.Options): Promise<T.Results>;
4
- export default analyse;