import path from "path";
const PROTOBUF_EXTENSIONS = [
".py",
".java",
".h",
".cc",
".cpp",
".m",
".rb",
".php",
];
const HAXE_EXTENSIONS = [
".js",
".py",
".lua",
".cpp",
".h",
".java",
".cs",
".php",
];
const APACHE_THRIFT_EXTENSIONS = [
".rb",
".py",
".go",
".js",
".m",
".java",
".h",
".cc",
".cpp",
".php",
];
export default class Generated {
private name: string;
private extname: string;
private lines: string[];
private _data: Buffer | null;
constructor(name: string, data: Buffer | null) {
this.name = name;
this.extname = path.extname(name);
this.lines = data === null ? [] : data.toString().split("\n");
this._data = data;
}
isXcodeFile(): boolean {
return [".nib", ".xcworkspacedata", ".xcuserstate"].includes(this.extname);
}
isIntellijFile(): boolean {
return /(?:^|\/)\.idea\//.test(this.name);
}
isCocoapods(): boolean {
return /(^Pods|\/Pods)\//.test(this.name);
}
isCarthageBuild(): boolean {
return /(^|\/)Carthage\/Build\//.test(this.name);
}
isMaybeMinified(): boolean {
return [".js", ".css"].includes(this.extname.toLowerCase());
}
isMinifiedFiles(): boolean {
if (this.isMaybeMinified() && this.lines.length > 0) {
let chars = 0;
this.lines.forEach((line) => {
chars += line.length;
});
return Math.round(chars / this.lines.length) > 110;
}
return false;
}
hasSourceMap(): boolean {
if (!this.isMaybeMinified()) {
return false;
}
return this.lines
.slice(-2)
.some((line) =>
/^\/[*/][#@] source(?:Mapping)?URL|sourceURL=/.test(line)
);
}
isSourceMap(): boolean {
if (this.extname.toLowerCase() !== ".map") {
return false;
}
return (
/(\.css|\.js)\.map$/i.test(this.name) || // Name convention
/^{"version":\d+,/.test(this.lines[0]) || // Revision 2 and later begin with the version number
/^\/\*\* Begin line maps\. \*\*\/{/.test(this.lines[0])
); // Revision 1 begins with a magic comment
}
isCompiledCoffeescript(): boolean {
if (this.extname !== ".js") {
return false;
}
// CoffeeScript generated by > 1.2 include a comment on the first line
if (/^\/\/ Generated by /.test(this.lines[0])) {
return true;
}
if (
this.lines[0] === "(function() {" &&
this.lines[this.lines.length - 2] === "}).call(this);" &&
this.lines[this.lines.length - 1] === ""
) {
let score = 0;
this.lines.forEach((line) => {
if (/var /.test(line)) {
score +=
1 * (line.match(/(_fn|_i|_len|_ref|_results)/g) || []).length;
score +=
3 *
(
line.match(/(__bind|__extends|__hasProp|__indexOf|__slice)/g) ||
[]
).length;
}
});
return score >= 3;
}
return false;
}
isGeneratedNetDocfile(): boolean {
if (this.extname.toLowerCase() !== ".xml") {
return false;
}
if (this.lines.length <= 3) {
return false;
}
return (
this.lines[1].includes("") &&
this.lines[2].includes("") &&
this.lines[this.lines.length - 2].includes("")
);
}
isGeneratedNetDesignerFile(): boolean {
return /\.designer\.(cs|vb)$/i.test(this.name);
}
isGeneratedNetSpecflowFeatureFile(): boolean {
return /\.feature\.cs$/i.test(this.name);
}
isGeneratedParser(): boolean {
if (this.extname !== ".js") {
return false;
}
return /^(?:[^/]|\/[^*])*\/\*(?:[^*]|\*[^/])*Generated by PEG.js/.test(
this.lines.slice(0, 4).join("")
);
}
isGeneratedPostscript(): boolean {
if (![".ps", ".eps", ".pfa"].includes(this.extname)) {
return false;
}
if (
this._data &&
/(\n|\r\n|\r)\s*(?:currentfile eexec\s+|\/sfnts\s+\[\1<)[0-9A-Fa-f]{8,}\1/.test(
this._data.toString()
)
) {
return true;
}
let creator: string | undefined;
for (let i = 0; i < 10; i++) {
const line = this.lines[i];
if (/^%%Creator: /.test(line)) {
creator = line.replace(/^%%Creator: /, "");
break;
}
}
if (!creator) {
return false;
}
if (
/[0-9]|draw|mpage|ImageMagick|inkscape|MATLAB/.test(creator) ||
/PCBNEW|pnmtops|\(Unknown\)|Serif Affinity|Filterimage -tops/.test(
creator
)
) {
return true;
}
if (creator.includes("EAGLE")) {
for (let i = 0; i < 5; i++) {
if (this.lines[i].match(/^%%Title: EAGLE Drawing /)) {
return true;
}
}
}
return false;
}
isNodeModules(): boolean {
return /node_modules\//.test(this.name);
}
isGoVendor(): boolean {
return /vendor\/((?!-)[-0-9A-Za-z]+(? /^\/\/ Code generated .*/.test(line));
}
isGeneratedProtocolBufferFromGo(): boolean {
if (this.extname !== ".proto" || this.lines.length <= 1) {
return false;
}
return this.lines
.slice(0, 20)
.some((line) =>
line.includes("This file was autogenerated by go-to-protobuf")
);
}
isGeneratedProtocolBuffer(): boolean {
if (!PROTOBUF_EXTENSIONS.includes(this.extname) || this.lines.length <= 1) {
return false;
}
return this.lines
.slice(0, 3)
.some((line) =>
line.includes(
"Generated by the protocol buffer compiler. DO NOT EDIT!"
)
);
}
isGeneratedJavascriptProtocolBuffer(): boolean {
if (this.extname !== ".js" || this.lines.length <= 6) {
return false;
}
return this.lines[5].includes("GENERATED CODE -- DO NOT EDIT!");
}
isNpmShrinkwrapOrPackageLock(): boolean {
return (
/npm-shrinkwrap\.json/.test(this.name) ||
/package-lock\.json/.test(this.name)
);
}
isGeneratedTypescriptProtocolBuffer(): boolean {
if (this.extname !== ".ts" || this.lines.length <= 4) {
return false;
}
return this.lines[0].includes(
"Code generated by protoc-gen-ts_proto. DO NOT EDIT."
);
}
isGeneratedApacheThrift(): boolean {
if (!APACHE_THRIFT_EXTENSIONS.includes(this.extname)) {
return false;
}
return this.lines
.slice(0, 6)
.some((line) => line.includes("Autogenerated by Thrift Compiler"));
}
isGeneratedJniHeader(): boolean {
if (this.extname !== ".h" || this.lines.length <= 2) {
return false;
}
return (
this.lines[0].includes(
"/* DO NOT EDIT THIS FILE - it is machine generated */"
) && this.lines[1].includes("#include ")
);
}
isPdmLock(): boolean {
return /pdm\.lock/.test(this.name);
}
isPixiLock(): boolean {
return /pixi\.lock/.test(this.name);
}
isDenoLock(): boolean {
return /deno\.lock/.test(this.name);
}
isPnpmLock(): boolean {
return /pnpm-lock\.yaml/.test(this.name);
}
isGeneratedYarnPlugnplay(): boolean {
return /(^|\/)\.pnp\..*$/.test(this.name);
}
isGodeps(): boolean {
return /Godeps\//.test(this.name);
}
isComposerLock(): boolean {
return /composer\.lock/.test(this.name);
}
isGeneratedByZephir(): boolean {
return /.\.zep\.(c|h|php)$/.test(this.name);
}
isCargoLock(): boolean {
return /Cargo\.lock/.test(this.name);
}
isCargoOrig(): boolean {
return /Cargo\.toml\.orig/.test(this.name);
}
isFlakeLock(): boolean {
return /(^|\/)flake\.lock$/.test(this.name);
}
isBazelLock(): boolean {
return /(^|\/)MODULE\.bazel\.lock$/.test(this.name);
}
isVcrCassette(): boolean {
if (this.extname !== ".yml" || this.lines.length <= 2) {
return false;
}
return this.lines[this.lines.length - 2].includes("recorded_with: VCR");
}
isGeneratedAntlr(): boolean {
if (this.extname !== ".g" || this.lines.length <= 2) {
return false;
}
return this.lines[1].includes("generated by Xtest");
}
isCompiledCythonFile(): boolean {
if (![".c", ".cpp"].includes(this.extname) || this.lines.length <= 1) {
return false;
}
return this.lines[0].includes("Generated by Cython");
}
isPipenvLock(): boolean {
return /Pipfile\.lock/.test(this.name);
}
isTerraformLock(): boolean {
return /(?:^|\/)\.terraform\.lock\.hcl$/.test(this.name);
}
isGeneratedModule(): boolean {
if (this.extname !== ".mod" || this.lines.length <= 1) {
return false;
}
return (
this.lines[0].includes("PCBNEW-LibModule-V") ||
this.lines[0].includes("GFORTRAN module version '")
);
}
isGeneratedUnity3dMeta(): boolean {
if (this.extname !== ".meta" || this.lines.length <= 1) {
return false;
}
return this.lines[0].includes("fileFormatVersion: ");
}
isGeneratedRacc(): boolean {
if (this.extname !== ".rb" || this.lines.length <= 2) {
return false;
}
return this.lines[2].startsWith(
"# This file is automatically generated by Racc"
);
}
isGeneratedJflex(): boolean {
if (this.extname !== ".java" || this.lines.length <= 1) {
return false;
}
return this.lines[0].startsWith(
"/* The following code was generated by JFlex "
);
}
isGeneratedGrammarkit(): boolean {
if (this.extname !== ".java" || this.lines.length <= 1) {
return false;
}
return this.lines[0].startsWith(
"// This is a generated file. Not intended for manual editing."
);
}
isGeneratedRoxygen2(): boolean {
if (this.extname !== ".Rd" || this.lines.length <= 1) {
return false;
}
return this.lines[0].includes(
"% Generated by roxygen2: do not edit by hand"
);
}
isGeneratedJison(): boolean {
if (this.extname !== ".js" || this.lines.length <= 1) {
return false;
}
return (
this.lines[0].startsWith("/* parser generated by jison ") ||
this.lines[0].startsWith("/* generated by jison-lex ")
);
}
isGeneratedGrpcCpp(): boolean {
if (
![".cpp", ".hpp", ".h", ".cc"].includes(this.extname) ||
this.lines.length <= 1
) {
return false;
}
return this.lines[0].startsWith("// Generated by the gRPC");
}
isGeneratedDart(): boolean {
if (this.extname !== ".dart" || this.lines.length <= 1) {
return false;
}
return /generated code\W{2,3}do not modify/i.test(this.lines[0]);
}
isGeneratedPerlPpportHeader(): boolean {
if (!this.name.match(/ppport\.h$/) || this.lines.length <= 10) {
return false;
}
return this.lines[8].includes("Automatically created by Devel::PPPort");
}
isGeneratedGraphqlRelay(): boolean {
return /__generated__\//.test(this.name);
}
isGeneratedGamemakerStudio(): boolean {
if (![".yy", ".yyp"].includes(this.extname) || this.lines.length <= 3) {
return false;
}
return (
/^\s*[{[]/.test(this.lines.slice(0, 3).join("")) ||
/^\d\.\d\.\d.+\|\{/.test(this.lines[0])
);
}
isGeneratedGimp(): boolean {
if (![".c", ".h"].includes(this.extname) || this.lines.length === 0) {
return false;
}
return (
/^\/\* GIMP [a-zA-Z0-9\- ]+ C-Source image dump \(.+?\.c\) \*\//.test(
this.lines[0]
) ||
/^\/\* {2}GIMP header image file format \([a-zA-Z0-9\- ]+\): .+?\.h {2}\*\//.test(
this.lines[0]
)
);
}
isGeneratedVisualstudio6(): boolean {
if (this.extname.toLowerCase() !== ".dsp") {
return false;
}
return this.lines
.slice(0, 3)
.some((line) =>
line.includes("# Microsoft Developer Studio Generated Build File")
);
}
isGeneratedHaxe(): boolean {
if (!HAXE_EXTENSIONS.includes(this.extname)) {
return false;
}
return this.lines
.slice(0, 3)
.some((line) => line.includes("Generated by Haxe"));
}
private extractHtmlMeta(metaTag: string): { [key: string]: string } {
const attrs: { [key: string]: string } = {};
const matches = metaTag.matchAll(
/(\w+[-\w]*)\s*=\s*(?:["']([^"']*)["']|(\S+))/g
);
for (const match of matches) {
const value = match[2] || match[3];
attrs[match[1].toLowerCase()] = value.trim();
}
return attrs;
}
isGeneratedHtml(): boolean {
if (
![".html", ".htm", ".xhtml"].includes(this.extname.toLowerCase()) ||
this.lines.length <= 1
) {
return false;
}
// Pkgdown
if (
this.lines
.slice(0, 2)
.some((line) =>
line.includes("")
)
) {
return true;
}
// Mandoc
if (
this.lines.length > 2 &&
this.lines[2].startsWith("/i.test(line)
)
) {
return true;
}
// HTML meta generator tag
const htmlContent = this.lines.slice(0, 31).join(" ");
const metaTags = htmlContent.match(/]+)>/gi);
if (!metaTags) return false;
return metaTags.some((tag) => {
const attrs = this.extractHtmlMeta(tag);
if (attrs["name"]?.toLowerCase() !== "generator") return false;
return [attrs["content"], attrs["value"]].some(
(cv) =>
cv &&
/^(org\s+mode|j?latex2html|groff|makeinfo|texi2html|ronn)\b/i.test(cv)
);
});
}
isGeneratedJooq(): boolean {
if (this.extname.toLowerCase() !== ".java") {
return false;
}
return this.lines
.slice(0, 2)
.some((line) => line.includes("This file is generated by jOOQ."));
}
isGeneratedPascalTlb(): boolean {
return /_tlb\.pas$/i.test(this.name);
}
isHtmlcov(): boolean {
return /(?:^|\/)htmlcov\//.test(this.name);
}
isGeneratedSqlxQuery(): boolean {
return /(?:^|.*\/)\.sqlx\/query-.+\.json$/.test(this.name);
}
/**
* Checks if a file is generated by examining various characteristics.
* This includes checking for:
* - Build artifacts (Xcode, IntelliJ, etc.)
* - Package manager files (npm, yarn, cargo, etc.)
* - Minified/compiled files (JavaScript, CoffeeScript, etc.)
* - Generated code (Protocol Buffers, Thrift, etc.)
* - Documentation (HTML, Doxygen, etc.)
* - Source maps and debug files
* - Various framework-specific generated files
*
* @returns {boolean} Returns true if the file is determined to be generated, false otherwise
*/
isGenerated(): boolean {
return (
this.isXcodeFile() ||
this.isIntellijFile() ||
this.isCocoapods() ||
this.isCarthageBuild() ||
this.isMinifiedFiles() ||
this.hasSourceMap() ||
this.isSourceMap() ||
this.isCompiledCoffeescript() ||
this.isGeneratedNetDocfile() ||
this.isGeneratedNetDesignerFile() ||
this.isGeneratedNetSpecflowFeatureFile() ||
this.isGeneratedParser() ||
this.isGeneratedPostscript() ||
this.isNodeModules() ||
this.isGoVendor() ||
this.isGoLock() ||
this.isPoetryLock() ||
this.isUVLock() ||
this.isEsyLock() ||
this.isGeneratedGo() ||
this.isGeneratedProtocolBufferFromGo() ||
this.isGeneratedProtocolBuffer() ||
this.isGeneratedJavascriptProtocolBuffer() ||
this.isNpmShrinkwrapOrPackageLock() ||
this.isGeneratedTypescriptProtocolBuffer() ||
this.isGeneratedApacheThrift() ||
this.isGeneratedJniHeader() ||
this.isPdmLock() ||
this.isPixiLock() ||
this.isDenoLock() ||
this.isPnpmLock() ||
this.isGeneratedYarnPlugnplay() ||
this.isGodeps() ||
this.isComposerLock() ||
this.isGeneratedByZephir() ||
this.isCargoLock() ||
this.isCargoOrig() ||
this.isFlakeLock() ||
this.isBazelLock() ||
this.isVcrCassette() ||
this.isGeneratedAntlr() ||
this.isCompiledCythonFile() ||
this.isPipenvLock() ||
this.isTerraformLock() ||
this.isGeneratedModule() ||
this.isGeneratedUnity3dMeta() ||
this.isGeneratedRacc() ||
this.isGeneratedJflex() ||
this.isGeneratedGrammarkit() ||
this.isGeneratedRoxygen2() ||
this.isGeneratedJison() ||
this.isGeneratedGrpcCpp() ||
this.isGeneratedDart() ||
this.isGeneratedPerlPpportHeader() ||
this.isGeneratedGraphqlRelay() ||
this.isGeneratedGamemakerStudio() ||
this.isGeneratedGimp() ||
this.isGeneratedVisualstudio6() ||
this.isGeneratedHaxe() ||
this.isGeneratedHtml() ||
this.isGeneratedJooq() ||
this.isGeneratedPascalTlb() ||
this.isHtmlcov() ||
this.isGeneratedSqlxQuery()
);
}
}