From a615b3a2c8c03d6866b5dde2d6bb6858f5c50a3f Mon Sep 17 00:00:00 2001 From: Samuel Bodin <1637651+bodinsamuel@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:32:15 +0200 Subject: [PATCH] feat: detect languages, payload is now mergeable --- src/analyser/index.test.ts | 22 + src/analyser/index.ts | 5 +- src/common/languages.ts | 4455 +++++++++++++++++++++++++++++++++++ src/common/techs.ts | 8 + src/payload/index.ts | 78 +- src/rules/docker/service.ts | 23 +- src/rules/nodejs/service.ts | 17 +- src/types/index.ts | 4 + src/types/techs.ts | 3 + 9 files changed, 4586 insertions(+), 29 deletions(-) create mode 100644 src/common/languages.ts diff --git a/src/analyser/index.test.ts b/src/analyser/index.test.ts index 54d3ec83..0d7ab7d4 100644 --- a/src/analyser/index.test.ts +++ b/src/analyser/index.test.ts @@ -16,6 +16,9 @@ describe('techAnalyser', () => { }); expect(res.toJson()).toStrictEqual({ + name: 'main', + path: '/', + tech: null, services: [ { edges: [], @@ -61,12 +64,31 @@ describe('techAnalyser', () => { 'docker', 'stylelint', 'nodejs', + 'javascript', 'fastify', 'prisma', 'react', 'vite', + 'html', + 'scss', + 'css', + 'shell', 'terraform', ], + languages: { + CSS: 1, + HCL: 31, + HTML: 2, + JSON: 17, + JavaScript: 4, + Markdown: 2, + Prisma: 1, + SCSS: 80, + Shell: 3, + TypeScript: 427, + XML: 1, + YAML: 2, + }, }); }); }); diff --git a/src/analyser/index.ts b/src/analyser/index.ts index face47e2..da561610 100644 --- a/src/analyser/index.ts +++ b/src/analyser/index.ts @@ -23,7 +23,7 @@ async function recursive( continue; } - res.forEach((service) => pl.addService(service)); + pl.merge(res); } // Detect Tech @@ -39,6 +39,7 @@ async function recursive( // Recursively dive in folders for (const file of files) { if (file.type === 'file') { + pl.detectLang(file.name); continue; } if (IGNORED_DIVE_PATHS.includes(file.name)) { @@ -53,7 +54,7 @@ export async function techAnalyser( opts: TechAnalyserOptions ): Promise { const provider = opts.provider; - const pl = new Payload(); + const pl = new Payload('main', '/'); await recursive(provider, pl, '/'); diff --git a/src/common/languages.ts b/src/common/languages.ts new file mode 100644 index 00000000..42c04c93 --- /dev/null +++ b/src/common/languages.ts @@ -0,0 +1,4455 @@ +type ListItem = { + extensions: string[]; + group: string | null; + name: string; + type: 'data' | 'markup' | 'programming' | 'prose'; +}; + +// Source: https://github.com/github/linguist/blob/5a0c74277548122267d84283910abd5e0b89380e/lib/linguist/languages.yml#L1528 +export const rawList: ListItem[] = [ + { + extensions: ['.bsl', '.os'], + group: null, + name: '1C Enterprise', + type: 'programming', + }, + { + extensions: ['.2da'], + group: null, + name: '2-Dimensional Array', + type: 'data', + }, + { + extensions: ['.4dm'], + group: null, + name: '4D', + type: 'programming', + }, + { + extensions: ['.abap'], + group: null, + name: 'ABAP', + type: 'programming', + }, + { + extensions: ['.asddls'], + group: null, + name: 'ABAP CDS', + type: 'programming', + }, + { + extensions: ['.abnf'], + group: null, + name: 'ABNF', + type: 'data', + }, + { + extensions: ['.asc', '.ash'], + group: null, + name: 'AGS Script', + type: 'programming', + }, + { + extensions: ['.aidl'], + group: null, + name: 'AIDL', + type: 'programming', + }, + { + extensions: ['.al'], + group: null, + name: 'AL', + type: 'programming', + }, + { + extensions: ['.ampl', '.mod'], + group: null, + name: 'AMPL', + type: 'programming', + }, + { + extensions: ['.g4'], + group: null, + name: 'ANTLR', + type: 'programming', + }, + { + extensions: ['.apib'], + group: null, + name: 'API Blueprint', + type: 'markup', + }, + { + extensions: ['.apl', '.dyalog'], + group: null, + name: 'APL', + type: 'programming', + }, + { + extensions: ['.asl', '.dsl'], + group: null, + name: 'ASL', + type: 'programming', + }, + { + extensions: ['.asn', '.asn1'], + group: null, + name: 'ASN.1', + type: 'data', + }, + { + extensions: ['.asax', '.ascx', '.ashx', '.asmx', '.aspx', '.axd'], + group: null, + name: 'ASP.NET', + type: 'programming', + }, + { + extensions: ['.dats', '.hats', '.sats'], + group: null, + name: 'ATS', + type: 'programming', + }, + { + extensions: ['.as'], + group: null, + name: 'ActionScript', + type: 'programming', + }, + { + extensions: ['.adb', '.ada', '.ads'], + group: null, + name: 'Ada', + type: 'programming', + }, + { + extensions: ['.txt'], + group: null, + name: 'Adblock Filter List', + type: 'data', + }, + { + extensions: ['.afm'], + group: null, + name: 'Adobe Font Metrics', + type: 'data', + }, + { + extensions: ['.agda'], + group: null, + name: 'Agda', + type: 'programming', + }, + { + extensions: ['.als'], + group: null, + name: 'Alloy', + type: 'programming', + }, + { + extensions: ['.OutJob', '.PcbDoc', '.PrjPCB', '.SchDoc'], + group: null, + name: 'Altium Designer', + type: 'data', + }, + { + extensions: ['.as', '.angelscript'], + group: null, + name: 'AngelScript', + type: 'programming', + }, + { + extensions: ['.antlers.html', '.antlers.php', '.antlers.xml'], + group: null, + name: 'Antlers', + type: 'markup', + }, + { + extensions: ['.apacheconf', '.vhost'], + group: null, + name: 'ApacheConf', + type: 'data', + }, + { + extensions: ['.cls'], + group: null, + name: 'Apex', + type: 'programming', + }, + { + extensions: ['.agc'], + group: 'Assembly', + name: 'Apollo Guidance Computer', + type: 'programming', + }, + { + extensions: ['.applescript', '.scpt'], + group: null, + name: 'AppleScript', + type: 'programming', + }, + { + extensions: ['.arc'], + group: null, + name: 'Arc', + type: 'programming', + }, + { + extensions: ['.asciidoc', '.adoc', '.asc'], + group: null, + name: 'AsciiDoc', + type: 'prose', + }, + { + extensions: ['.aj'], + group: null, + name: 'AspectJ', + type: 'programming', + }, + { + extensions: ['.asm', '.a51', '.i', '.inc', '.nas', '.nasm'], + group: null, + name: 'Assembly', + type: 'programming', + }, + { + extensions: ['.astro'], + group: null, + name: 'Astro', + type: 'markup', + }, + { + extensions: ['.asy'], + group: null, + name: 'Asymptote', + type: 'programming', + }, + { + extensions: ['.aug'], + group: null, + name: 'Augeas', + type: 'programming', + }, + { + extensions: ['.ahk', '.ahkl'], + group: null, + name: 'AutoHotkey', + type: 'programming', + }, + { + extensions: ['.au3'], + group: null, + name: 'AutoIt', + type: 'programming', + }, + { + extensions: ['.avdl'], + group: null, + name: 'Avro IDL', + type: 'data', + }, + { + extensions: ['.awk', '.auk', '.gawk', '.mawk', '.nawk'], + group: null, + name: 'Awk', + type: 'programming', + }, + { + extensions: ['.bas'], + group: null, + name: 'BASIC', + type: 'programming', + }, + { + extensions: ['.bal'], + group: null, + name: 'Ballerina', + type: 'programming', + }, + { + extensions: ['.bat', '.cmd'], + group: null, + name: 'Batchfile', + type: 'programming', + }, + { + extensions: ['.bf'], + group: null, + name: 'Beef', + type: 'programming', + }, + { + extensions: ['.befunge', '.bf'], + group: null, + name: 'Befunge', + type: 'programming', + }, + { + extensions: ['.be'], + group: null, + name: 'Berry', + type: 'programming', + }, + { + extensions: ['.bib', '.bibtex'], + group: 'TeX', + name: 'BibTeX', + type: 'markup', + }, + { + extensions: ['.bicep'], + group: null, + name: 'Bicep', + type: 'programming', + }, + { + extensions: ['.bs'], + group: null, + name: 'Bikeshed', + type: 'markup', + }, + { + extensions: ['.bison'], + group: 'Yacc', + name: 'Bison', + type: 'programming', + }, + { + extensions: ['.bb'], + group: null, + name: 'BitBake', + type: 'programming', + }, + { + extensions: ['.blade', '.blade.php'], + group: null, + name: 'Blade', + type: 'markup', + }, + { + extensions: ['.bb', '.decls'], + group: null, + name: 'BlitzBasic', + type: 'programming', + }, + { + extensions: ['.bmx'], + group: null, + name: 'BlitzMax', + type: 'programming', + }, + { + extensions: ['.bsv'], + group: null, + name: 'Bluespec', + type: 'programming', + }, + { + extensions: ['.boo'], + group: null, + name: 'Boo', + type: 'programming', + }, + { + extensions: ['.bpl'], + group: null, + name: 'Boogie', + type: 'programming', + }, + { + extensions: ['.b', '.bf'], + group: null, + name: 'Brainfuck', + type: 'programming', + }, + { + extensions: ['.bs'], + group: null, + name: 'BrighterScript', + type: 'programming', + }, + { + extensions: ['.brs'], + group: null, + name: 'Brightscript', + type: 'programming', + }, + { + extensions: ['.c', '.cats', '.h', '.idc'], + group: null, + name: 'C', + type: 'programming', + }, + { + extensions: ['.cs', '.cake', '.csx', '.linq'], + group: null, + name: 'C#', + type: 'programming', + }, + { + extensions: [ + '.cpp', + '.c++', + '.cc', + '.cp', + '.cppm', + '.cxx', + '.h', + '.h++', + '.hh', + '.hpp', + '.hxx', + '.inc', + '.inl', + '.ino', + '.ipp', + '.ixx', + '.re', + '.tcc', + '.tpp', + ], + group: null, + name: 'C++', + type: 'programming', + }, + { + extensions: ['.c-objdump'], + group: null, + name: 'C-ObjDump', + type: 'data', + }, + { + extensions: ['.chs'], + group: 'Haskell', + name: 'C2hs Haskell', + type: 'programming', + }, + { + extensions: ['.cds'], + group: null, + name: 'CAP CDS', + type: 'programming', + }, + { + extensions: ['.cil'], + group: null, + name: 'CIL', + type: 'data', + }, + { + extensions: ['.clp'], + group: null, + name: 'CLIPS', + type: 'programming', + }, + { + extensions: ['.cmake', '.cmake.in'], + group: null, + name: 'CMake', + type: 'programming', + }, + { + extensions: ['.cob', '.cbl', '.ccp', '.cobol', '.cpy'], + group: null, + name: 'COBOL', + type: 'programming', + }, + { + extensions: ['.dae'], + group: null, + name: 'COLLADA', + type: 'data', + }, + { + extensions: ['.cson'], + group: null, + name: 'CSON', + type: 'data', + }, + { + extensions: ['.css'], + group: null, + name: 'CSS', + type: 'markup', + }, + { + extensions: ['.csv'], + group: null, + name: 'CSV', + type: 'data', + }, + { + extensions: ['.cue'], + group: null, + name: 'CUE', + type: 'programming', + }, + { + extensions: ['.w'], + group: null, + name: 'CWeb', + type: 'programming', + }, + { + extensions: ['.cabal'], + group: null, + name: 'Cabal Config', + type: 'data', + }, + { + extensions: ['.cdc'], + group: null, + name: 'Cadence', + type: 'programming', + }, + { + extensions: ['.cairo'], + group: null, + name: 'Cairo', + type: 'programming', + }, + { + extensions: ['.mligo'], + group: 'LigoLANG', + name: 'CameLIGO', + type: 'programming', + }, + { + extensions: ['.capnp'], + group: null, + name: "Cap'n Proto", + type: 'programming', + }, + { + extensions: ['.mss'], + group: null, + name: 'CartoCSS', + type: 'programming', + }, + { + extensions: ['.ceylon'], + group: null, + name: 'Ceylon', + type: 'programming', + }, + { + extensions: ['.chpl'], + group: null, + name: 'Chapel', + type: 'programming', + }, + { + extensions: ['.ch'], + group: null, + name: 'Charity', + type: 'programming', + }, + { + extensions: [ + '.crc32', + '.md2', + '.md4', + '.md5', + '.sha1', + '.sha2', + '.sha224', + '.sha256', + '.sha256sum', + '.sha3', + '.sha384', + '.sha512', + ], + group: null, + name: 'Checksums', + type: 'data', + }, + { + extensions: ['.ck'], + group: null, + name: 'ChucK', + type: 'programming', + }, + { + extensions: ['.circom'], + group: null, + name: 'Circom', + type: 'programming', + }, + { + extensions: ['.cirru'], + group: null, + name: 'Cirru', + type: 'programming', + }, + { + extensions: ['.clw'], + group: null, + name: 'Clarion', + type: 'programming', + }, + { + extensions: ['.clar'], + group: null, + name: 'Clarity', + type: 'programming', + }, + { + extensions: ['.asp'], + group: null, + name: 'Classic ASP', + type: 'programming', + }, + { + extensions: ['.icl', '.dcl'], + group: null, + name: 'Clean', + type: 'programming', + }, + { + extensions: ['.click'], + group: null, + name: 'Click', + type: 'programming', + }, + { + extensions: [ + '.clj', + '.bb', + '.boot', + '.cl2', + '.cljc', + '.cljs', + '.cljs.hl', + '.cljscm', + '.cljx', + '.hic', + ], + group: null, + name: 'Clojure', + type: 'programming', + }, + { + extensions: ['.soy'], + group: null, + name: 'Closure Templates', + type: 'markup', + }, + { + extensions: ['.conllu', '.conll'], + group: null, + name: 'CoNLL-U', + type: 'data', + }, + { + extensions: ['.ql', '.qll'], + group: null, + name: 'CodeQL', + type: 'programming', + }, + { + extensions: ['.coffee', '._coffee', '.cake', '.cjsx', '.iced'], + group: null, + name: 'CoffeeScript', + type: 'programming', + }, + { + extensions: ['.cfm', '.cfml'], + group: null, + name: 'ColdFusion', + type: 'programming', + }, + { + extensions: ['.cfc'], + group: 'ColdFusion', + name: 'ColdFusion CFC', + type: 'programming', + }, + { + extensions: [ + '.lisp', + '.asd', + '.cl', + '.l', + '.lsp', + '.ny', + '.podsl', + '.sexp', + ], + group: null, + name: 'Common Lisp', + type: 'programming', + }, + { + extensions: ['.cwl'], + group: null, + name: 'Common Workflow Language', + type: 'programming', + }, + { + extensions: ['.cp', '.cps'], + group: null, + name: 'Component Pascal', + type: 'programming', + }, + { + extensions: ['.cl'], + group: null, + name: 'Cool', + type: 'programming', + }, + { + extensions: ['.coq', '.v'], + group: null, + name: 'Coq', + type: 'programming', + }, + { + extensions: [ + '.cppobjdump', + '.c++-objdump', + '.c++objdump', + '.cpp-objdump', + '.cxx-objdump', + ], + group: null, + name: 'Cpp-ObjDump', + type: 'data', + }, + { + extensions: ['.creole'], + group: null, + name: 'Creole', + type: 'prose', + }, + { + extensions: ['.cr'], + group: null, + name: 'Crystal', + type: 'programming', + }, + { + extensions: ['.orc', '.udo'], + group: null, + name: 'Csound', + type: 'programming', + }, + { + extensions: ['.csd'], + group: null, + name: 'Csound Document', + type: 'programming', + }, + { + extensions: ['.sco'], + group: null, + name: 'Csound Score', + type: 'programming', + }, + { + extensions: ['.cu', '.cuh'], + group: null, + name: 'Cuda', + type: 'programming', + }, + { + extensions: ['.cue'], + group: null, + name: 'Cue Sheet', + type: 'data', + }, + { + extensions: ['.curry'], + group: null, + name: 'Curry', + type: 'programming', + }, + { + extensions: ['.cy'], + group: null, + name: 'Cycript', + type: 'programming', + }, + { + extensions: ['.cyp', '.cypher'], + group: null, + name: 'Cypher', + type: 'programming', + }, + { + extensions: ['.pyx', '.pxd', '.pxi'], + group: null, + name: 'Cython', + type: 'programming', + }, + { + extensions: ['.d', '.di'], + group: null, + name: 'D', + type: 'programming', + }, + { + extensions: ['.d-objdump'], + group: null, + name: 'D-ObjDump', + type: 'data', + }, + { + extensions: ['.com'], + group: null, + name: 'DIGITAL Command Language', + type: 'programming', + }, + { + extensions: ['.dm'], + group: null, + name: 'DM', + type: 'programming', + }, + { + extensions: ['.zone', '.arpa'], + group: null, + name: 'DNS Zone', + type: 'data', + }, + { + extensions: ['.d'], + group: null, + name: 'DTrace', + type: 'programming', + }, + { + extensions: ['.dfy'], + group: null, + name: 'Dafny', + type: 'programming', + }, + { + extensions: ['.darcspatch', '.dpatch'], + group: null, + name: 'Darcs Patch', + type: 'data', + }, + { + extensions: ['.dart'], + group: null, + name: 'Dart', + type: 'programming', + }, + { + extensions: ['.dwl'], + group: null, + name: 'DataWeave', + type: 'programming', + }, + { + extensions: ['.dsc'], + group: null, + name: 'Debian Package Control File', + type: 'data', + }, + { + extensions: ['.dsc'], + group: null, + name: 'DenizenScript', + type: 'programming', + }, + { + extensions: ['.dhall'], + group: null, + name: 'Dhall', + type: 'programming', + }, + { + extensions: ['.diff', '.patch'], + group: null, + name: 'Diff', + type: 'data', + }, + { + extensions: ['.x'], + group: null, + name: 'DirectX 3D File', + type: 'data', + }, + { + extensions: ['.dockerfile'], + group: null, + name: 'Dockerfile', + type: 'programming', + }, + { + extensions: ['.djs'], + group: null, + name: 'Dogescript', + type: 'programming', + }, + { + extensions: ['.env'], + group: null, + name: 'Dotenv', + type: 'data', + }, + { + extensions: ['.dylan', '.dyl', '.intr', '.lid'], + group: null, + name: 'Dylan', + type: 'programming', + }, + { + extensions: ['.e'], + group: null, + name: 'E', + type: 'programming', + }, + { + extensions: ['.eml', '.mbox'], + group: null, + name: 'E-mail', + type: 'data', + }, + { + extensions: ['.ebnf'], + group: null, + name: 'EBNF', + type: 'data', + }, + { + extensions: ['.ecl', '.eclxml'], + group: null, + name: 'ECL', + type: 'programming', + }, + { + extensions: ['.ecl'], + group: 'prolog', + name: 'ECLiPSe', + type: 'programming', + }, + { + extensions: ['.ejs', '.ect', '.ejs.t', '.jst'], + group: null, + name: 'EJS', + type: 'markup', + }, + { + extensions: ['.eq'], + group: null, + name: 'EQ', + type: 'programming', + }, + { + extensions: ['.sch', '.brd'], + group: null, + name: 'Eagle', + type: 'data', + }, + { + extensions: ['.eb'], + group: 'Python', + name: 'Easybuild', + type: 'data', + }, + { + extensions: ['.epj'], + group: 'JavaScript', + name: 'Ecere Projects', + type: 'data', + }, + { + extensions: ['.html'], + group: 'HTML', + name: 'Ecmarkup', + type: 'markup', + }, + { + extensions: ['.editorconfig'], + group: 'INI', + name: 'EditorConfig', + type: 'data', + }, + { + extensions: ['.edc'], + group: null, + name: 'Edje Data Collection', + type: 'data', + }, + { + extensions: ['.e'], + group: null, + name: 'Eiffel', + type: 'programming', + }, + { + extensions: ['.ex', '.exs'], + group: null, + name: 'Elixir', + type: 'programming', + }, + { + extensions: ['.elm'], + group: null, + name: 'Elm', + type: 'programming', + }, + { + extensions: ['.elv'], + group: null, + name: 'Elvish', + type: 'programming', + }, + { + extensions: ['.el', '.emacs', '.emacs.desktop'], + group: null, + name: 'Emacs Lisp', + type: 'programming', + }, + { + extensions: ['.em', '.emberscript'], + group: null, + name: 'EmberScript', + type: 'programming', + }, + { + extensions: [ + '.erl', + '.app', + '.app.src', + '.es', + '.escript', + '.hrl', + '.xrl', + '.yrl', + ], + group: null, + name: 'Erlang', + type: 'programming', + }, + { + extensions: ['.e', '.ex'], + group: null, + name: 'Euphoria', + type: 'programming', + }, + { + extensions: ['.fs', '.fsi', '.fsx'], + group: null, + name: 'F#', + type: 'programming', + }, + { + extensions: ['.fst', '.fsti'], + group: null, + name: 'F*', + type: 'programming', + }, + { + extensions: ['.flf'], + group: null, + name: 'FIGlet Font', + type: 'data', + }, + { + extensions: ['.fx', '.flux'], + group: null, + name: 'FLUX', + type: 'programming', + }, + { + extensions: ['.factor'], + group: null, + name: 'Factor', + type: 'programming', + }, + { + extensions: ['.fy', '.fancypack'], + group: null, + name: 'Fancy', + type: 'programming', + }, + { + extensions: ['.fan'], + group: null, + name: 'Fantom', + type: 'programming', + }, + { + extensions: ['.dsp'], + group: null, + name: 'Faust', + type: 'programming', + }, + { + extensions: ['.fnl'], + group: null, + name: 'Fennel', + type: 'programming', + }, + { + extensions: ['.f'], + group: null, + name: 'Filebench WML', + type: 'programming', + }, + { + extensions: ['.fs'], + group: 'RenderScript', + name: 'Filterscript', + type: 'programming', + }, + { + extensions: ['.ftl'], + group: null, + name: 'Fluent', + type: 'programming', + }, + { + extensions: ['.for', '.eam.fs'], + group: null, + name: 'Formatted', + type: 'data', + }, + { + extensions: ['.fth', '.4th', '.f', '.for', '.forth', '.fr', '.frt', '.fs'], + group: null, + name: 'Forth', + type: 'programming', + }, + { + extensions: ['.f', '.f77', '.for', '.fpp'], + group: 'Fortran', + name: 'Fortran', + type: 'programming', + }, + { + extensions: ['.f90', '.f03', '.f08', '.f95'], + group: 'Fortran', + name: 'Fortran Free Form', + type: 'programming', + }, + { + extensions: ['.bi', '.bas'], + group: null, + name: 'FreeBasic', + type: 'programming', + }, + { + extensions: ['.ftl'], + group: null, + name: 'FreeMarker', + type: 'programming', + }, + { + extensions: ['.fr'], + group: null, + name: 'Frege', + type: 'programming', + }, + { + extensions: ['.fut'], + group: null, + name: 'Futhark', + type: 'programming', + }, + { + extensions: ['.g', '.cnc', '.gco', '.gcode'], + group: null, + name: 'G-code', + type: 'programming', + }, + { + extensions: ['.gaml'], + group: null, + name: 'GAML', + type: 'programming', + }, + { + extensions: ['.gms'], + group: null, + name: 'GAMS', + type: 'programming', + }, + { + extensions: ['.g', '.gap', '.gd', '.gi', '.tst'], + group: null, + name: 'GAP', + type: 'programming', + }, + { + extensions: ['.gdb', '.gdbinit'], + group: null, + name: 'GDB', + type: 'programming', + }, + { + extensions: ['.gd'], + group: null, + name: 'GDScript', + type: 'programming', + }, + { + extensions: ['.ged'], + group: null, + name: 'GEDCOM', + type: 'data', + }, + { + extensions: [ + '.glsl', + '.fp', + '.frag', + '.frg', + '.fs', + '.fsh', + '.fshader', + '.geo', + '.geom', + '.glslf', + '.glslv', + '.gs', + '.gshader', + '.rchit', + '.rmiss', + '.shader', + '.tesc', + '.tese', + '.vert', + '.vrx', + '.vsh', + '.vshader', + ], + group: null, + name: 'GLSL', + type: 'programming', + }, + { + extensions: ['.gn', '.gni'], + group: null, + name: 'GN', + type: 'data', + }, + { + extensions: ['.gsc', '.csc', '.gsh'], + group: null, + name: 'GSC', + type: 'programming', + }, + { + extensions: ['.gml'], + group: null, + name: 'Game Maker Language', + type: 'programming', + }, + { + extensions: ['.gmi'], + group: null, + name: 'Gemini', + type: 'prose', + }, + { + extensions: ['.4gl'], + group: null, + name: 'Genero', + type: 'programming', + }, + { + extensions: ['.per'], + group: null, + name: 'Genero Forms', + type: 'markup', + }, + { + extensions: ['.gs'], + group: null, + name: 'Genie', + type: 'programming', + }, + { + extensions: ['.kid'], + group: null, + name: 'Genshi', + type: 'programming', + }, + { + extensions: ['.ebuild'], + group: 'Shell', + name: 'Gentoo Ebuild', + type: 'programming', + }, + { + extensions: ['.eclass'], + group: 'Shell', + name: 'Gentoo Eclass', + type: 'programming', + }, + { + extensions: [ + '.gbr', + '.cmp', + '.gbl', + '.gbo', + '.gbp', + '.gbs', + '.gko', + '.gml', + '.gpb', + '.gpt', + '.gtl', + '.gto', + '.gtp', + '.gts', + '.ncl', + '.sol', + ], + group: null, + name: 'Gerber Image', + type: 'data', + }, + { + extensions: ['.po', '.pot'], + group: null, + name: 'Gettext Catalog', + type: 'prose', + }, + { + extensions: ['.feature', '.story'], + group: null, + name: 'Gherkin', + type: 'programming', + }, + { + extensions: ['.gitconfig'], + group: 'INI', + name: 'Git Config', + type: 'data', + }, + { + extensions: ['.gleam'], + group: null, + name: 'Gleam', + type: 'programming', + }, + { + extensions: ['.glf'], + group: null, + name: 'Glyph', + type: 'programming', + }, + { + extensions: ['.bdf'], + group: null, + name: 'Glyph Bitmap Distribution Format', + type: 'data', + }, + { + extensions: ['.gp', '.gnu', '.gnuplot', '.p', '.plot', '.plt'], + group: null, + name: 'Gnuplot', + type: 'programming', + }, + { + extensions: ['.go'], + group: null, + name: 'Go', + type: 'programming', + }, + { + extensions: ['.gdnlib', '.gdns', '.tres', '.tscn'], + group: null, + name: 'Godot Resource', + type: 'data', + }, + { + extensions: ['.golo'], + group: null, + name: 'Golo', + type: 'programming', + }, + { + extensions: ['.gs', '.gst', '.gsx', '.vark'], + group: null, + name: 'Gosu', + type: 'programming', + }, + { + extensions: ['.grace'], + group: null, + name: 'Grace', + type: 'programming', + }, + { + extensions: ['.gradle'], + group: null, + name: 'Gradle', + type: 'data', + }, + { + extensions: ['.gf'], + group: null, + name: 'Grammatical Framework', + type: 'programming', + }, + { + extensions: ['.gml'], + group: null, + name: 'Graph Modeling Language', + type: 'data', + }, + { + extensions: ['.graphql', '.gql', '.graphqls'], + group: null, + name: 'GraphQL', + type: 'data', + }, + { + extensions: ['.dot', '.gv'], + group: null, + name: 'Graphviz (DOT)', + type: 'data', + }, + { + extensions: ['.groovy', '.grt', '.gtpl', '.gvy'], + group: null, + name: 'Groovy', + type: 'programming', + }, + { + extensions: ['.gsp'], + group: 'Groovy', + name: 'Groovy Server Pages', + type: 'programming', + }, + { + extensions: ['.cfg'], + group: null, + name: 'HAProxy', + type: 'data', + }, + { + extensions: ['.hcl', '.nomad', '.tf', '.tfvars', '.workflow'], + group: null, + name: 'HCL', + type: 'programming', + }, + { + extensions: ['.hlsl', '.cginc', '.fx', '.fxh', '.hlsli'], + group: null, + name: 'HLSL', + type: 'programming', + }, + { + extensions: ['.hocon'], + group: null, + name: 'HOCON', + type: 'data', + }, + { + extensions: ['.html', '.hta', '.htm', '.html.hl', '.inc', '.xht', '.xhtml'], + group: null, + name: 'HTML', + type: 'markup', + }, + { + extensions: ['.ecr'], + group: 'HTML', + name: 'HTML+ECR', + type: 'markup', + }, + { + extensions: ['.eex', '.html.heex', '.html.leex'], + group: 'HTML', + name: 'HTML+EEX', + type: 'markup', + }, + { + extensions: ['.erb', '.erb.deface', '.rhtml'], + group: 'HTML', + name: 'HTML+ERB', + type: 'markup', + }, + { + extensions: ['.phtml'], + group: 'HTML', + name: 'HTML+PHP', + type: 'markup', + }, + { + extensions: ['.cshtml', '.razor'], + group: 'HTML', + name: 'HTML+Razor', + type: 'markup', + }, + { + extensions: ['.http'], + group: null, + name: 'HTTP', + type: 'data', + }, + { + extensions: ['.hxml'], + group: null, + name: 'HXML', + type: 'data', + }, + { + extensions: ['.hack', '.hh', '.hhi', '.php'], + group: null, + name: 'Hack', + type: 'programming', + }, + { + extensions: ['.haml', '.haml.deface'], + group: null, + name: 'Haml', + type: 'markup', + }, + { + extensions: ['.handlebars', '.hbs'], + group: null, + name: 'Handlebars', + type: 'markup', + }, + { + extensions: ['.hb'], + group: null, + name: 'Harbour', + type: 'programming', + }, + { + extensions: ['.hs', '.hs-boot', '.hsc'], + group: null, + name: 'Haskell', + type: 'programming', + }, + { + extensions: ['.hx', '.hxsl'], + group: null, + name: 'Haxe', + type: 'programming', + }, + { + extensions: ['.q', '.hql'], + group: null, + name: 'HiveQL', + type: 'programming', + }, + { + extensions: ['.hc'], + group: null, + name: 'HolyC', + type: 'programming', + }, + { + extensions: ['.hy'], + group: null, + name: 'Hy', + type: 'programming', + }, + { + extensions: ['.bf'], + group: null, + name: 'HyPhy', + type: 'programming', + }, + { + extensions: ['.pro', '.dlm'], + group: null, + name: 'IDL', + type: 'programming', + }, + { + extensions: ['.ipf'], + group: null, + name: 'IGOR Pro', + type: 'programming', + }, + { + extensions: [ + '.ini', + '.cfg', + '.cnf', + '.dof', + '.lektorproject', + '.prefs', + '.pro', + '.properties', + '.url', + ], + group: null, + name: 'INI', + type: 'data', + }, + { + extensions: ['.irclog', '.weechatlog'], + group: null, + name: 'IRC log', + type: 'data', + }, + { + extensions: ['.idr', '.lidr'], + group: null, + name: 'Idris', + type: 'programming', + }, + { + extensions: ['.gitignore'], + group: 'INI', + name: 'Ignore List', + type: 'data', + }, + { + extensions: ['.ijm'], + group: null, + name: 'ImageJ Macro', + type: 'programming', + }, + { + extensions: ['.imba'], + group: null, + name: 'Imba', + type: 'programming', + }, + { + extensions: ['.ni', '.i7x'], + group: null, + name: 'Inform 7', + type: 'programming', + }, + { + extensions: ['.ink'], + group: null, + name: 'Ink', + type: 'programming', + }, + { + extensions: ['.iss', '.isl'], + group: null, + name: 'Inno Setup', + type: 'programming', + }, + { + extensions: ['.io'], + group: null, + name: 'Io', + type: 'programming', + }, + { + extensions: ['.ik'], + group: null, + name: 'Ioke', + type: 'programming', + }, + { + extensions: ['.thy'], + group: null, + name: 'Isabelle', + type: 'programming', + }, + { + extensions: ['.ijs'], + group: null, + name: 'J', + type: 'programming', + }, + { + extensions: ['.jcl'], + group: null, + name: 'JCL', + type: 'programming', + }, + { + extensions: ['.flex', '.jflex'], + group: 'Lex', + name: 'JFlex', + type: 'programming', + }, + { + extensions: [ + '.json', + '.4DForm', + '.4DProject', + '.avsc', + '.geojson', + '.gltf', + '.har', + '.ice', + '.JSON-tmLanguage', + '.jsonl', + '.mcmeta', + '.tfstate', + '.tfstate.backup', + '.topojson', + '.webapp', + '.webmanifest', + '.yy', + '.yyp', + ], + group: null, + name: 'JSON', + type: 'data', + }, + { + extensions: [ + '.jsonc', + '.code-snippets', + '.sublime-build', + '.sublime-commands', + '.sublime-completions', + '.sublime-keymap', + '.sublime-macro', + '.sublime-menu', + '.sublime-mousemap', + '.sublime-project', + '.sublime-settings', + '.sublime-theme', + '.sublime-workspace', + '.sublime_metrics', + '.sublime_session', + ], + group: 'JSON', + name: 'JSON with Comments', + type: 'data', + }, + { + extensions: ['.json5'], + group: null, + name: 'JSON5', + type: 'data', + }, + { + extensions: ['.jsonld'], + group: null, + name: 'JSONLD', + type: 'data', + }, + { + extensions: ['.jq'], + group: null, + name: 'JSONiq', + type: 'programming', + }, + { + extensions: ['.janet'], + group: null, + name: 'Janet', + type: 'programming', + }, + { + extensions: ['.j'], + group: null, + name: 'Jasmin', + type: 'programming', + }, + { + extensions: ['.java', '.jav', '.jsh'], + group: null, + name: 'Java', + type: 'programming', + }, + { + extensions: ['.properties'], + group: null, + name: 'Java Properties', + type: 'data', + }, + { + extensions: ['.jsp', '.tag'], + group: 'Java', + name: 'Java Server Pages', + type: 'programming', + }, + { + extensions: [ + '.js', + '._js', + '.bones', + '.cjs', + '.es', + '.es6', + '.frag', + '.gs', + '.jake', + '.javascript', + '.jsb', + '.jscad', + '.jsfl', + '.jslib', + '.jsm', + '.jspre', + '.jss', + '.jsx', + '.mjs', + '.njs', + '.pac', + '.sjs', + '.ssjs', + '.xsjs', + '.xsjslib', + ], + group: null, + name: 'JavaScript', + type: 'programming', + }, + { + extensions: ['.js.erb'], + group: 'JavaScript', + name: 'JavaScript+ERB', + type: 'programming', + }, + { + extensions: ['.snap'], + group: null, + name: 'Jest Snapshot', + type: 'data', + }, + { + extensions: ['.mps', '.mpl', '.msd'], + group: null, + name: 'JetBrains MPS', + type: 'programming', + }, + { + extensions: ['.jinja', '.j2', '.jinja2'], + group: null, + name: 'Jinja', + type: 'markup', + }, + { + extensions: ['.jison'], + group: 'Yacc', + name: 'Jison', + type: 'programming', + }, + { + extensions: ['.jisonlex'], + group: 'Lex', + name: 'Jison Lex', + type: 'programming', + }, + { + extensions: ['.ol', '.iol'], + group: null, + name: 'Jolie', + type: 'programming', + }, + { + extensions: ['.jsonnet', '.libsonnet'], + group: null, + name: 'Jsonnet', + type: 'programming', + }, + { + extensions: ['.jl'], + group: null, + name: 'Julia', + type: 'programming', + }, + { + extensions: ['.ipynb'], + group: null, + name: 'Jupyter Notebook', + type: 'markup', + }, + { + extensions: ['.krl'], + group: null, + name: 'KRL', + type: 'programming', + }, + { + extensions: ['.ksy'], + group: null, + name: 'Kaitai Struct', + type: 'programming', + }, + { + extensions: ['.kak'], + group: null, + name: 'KakouneScript', + type: 'programming', + }, + { + extensions: ['.ks'], + group: null, + name: 'KerboScript', + type: 'programming', + }, + { + extensions: ['.kicad_pcb', '.kicad_mod', '.kicad_wks'], + group: null, + name: 'KiCad Layout', + type: 'data', + }, + { + extensions: ['.brd'], + group: null, + name: 'KiCad Legacy Layout', + type: 'data', + }, + { + extensions: ['.kicad_sch', '.sch'], + group: null, + name: 'KiCad Schematic', + type: 'data', + }, + { + extensions: ['.ks'], + group: null, + name: 'Kickstart', + type: 'data', + }, + { + extensions: ['.kit'], + group: null, + name: 'Kit', + type: 'markup', + }, + { + extensions: ['.kt', '.ktm', '.kts'], + group: null, + name: 'Kotlin', + type: 'programming', + }, + { + extensions: ['.csl', '.kql'], + group: null, + name: 'Kusto', + type: 'data', + }, + { + extensions: ['.lfe'], + group: null, + name: 'LFE', + type: 'programming', + }, + { + extensions: ['.ll'], + group: null, + name: 'LLVM', + type: 'programming', + }, + { + extensions: ['.lol'], + group: null, + name: 'LOLCODE', + type: 'programming', + }, + { + extensions: ['.lsl', '.lslp'], + group: null, + name: 'LSL', + type: 'programming', + }, + { + extensions: ['.asy'], + group: null, + name: 'LTspice Symbol', + type: 'data', + }, + { + extensions: ['.lvproj', '.lvclass', '.lvlib'], + group: null, + name: 'LabVIEW', + type: 'programming', + }, + { + extensions: ['.lark'], + group: null, + name: 'Lark', + type: 'data', + }, + { + extensions: ['.lasso', '.las', '.lasso8', '.lasso9'], + group: null, + name: 'Lasso', + type: 'programming', + }, + { + extensions: ['.latte'], + group: null, + name: 'Latte', + type: 'markup', + }, + { + extensions: ['.lean', '.hlean'], + group: null, + name: 'Lean', + type: 'programming', + }, + { + extensions: ['.less'], + group: null, + name: 'Less', + type: 'markup', + }, + { + extensions: ['.l', '.lex'], + group: null, + name: 'Lex', + type: 'programming', + }, + { + extensions: ['.ligo'], + group: 'LigoLANG', + name: 'LigoLANG', + type: 'programming', + }, + { + extensions: ['.ly', '.ily'], + group: null, + name: 'LilyPond', + type: 'programming', + }, + { + extensions: ['.b', '.m'], + group: null, + name: 'Limbo', + type: 'programming', + }, + { + extensions: ['.ld', '.lds', '.x'], + group: null, + name: 'Linker Script', + type: 'data', + }, + { + extensions: ['.mod'], + group: null, + name: 'Linux Kernel Module', + type: 'data', + }, + { + extensions: ['.liquid'], + group: null, + name: 'Liquid', + type: 'markup', + }, + { + extensions: ['.lagda'], + group: 'Agda', + name: 'Literate Agda', + type: 'programming', + }, + { + extensions: ['.litcoffee', '.coffee.md'], + group: 'CoffeeScript', + name: 'Literate CoffeeScript', + type: 'programming', + }, + { + extensions: ['.lhs'], + group: 'Haskell', + name: 'Literate Haskell', + type: 'programming', + }, + { + extensions: ['.ls', '._ls'], + group: null, + name: 'LiveScript', + type: 'programming', + }, + { + extensions: ['.xm', '.x', '.xi'], + group: null, + name: 'Logos', + type: 'programming', + }, + { + extensions: ['.lgt', '.logtalk'], + group: null, + name: 'Logtalk', + type: 'programming', + }, + { + extensions: ['.lookml', '.model.lkml', '.view.lkml'], + group: null, + name: 'LookML', + type: 'programming', + }, + { + extensions: ['.ls'], + group: null, + name: 'LoomScript', + type: 'programming', + }, + { + extensions: [ + '.lua', + '.fcgi', + '.nse', + '.p8', + '.pd_lua', + '.rbxs', + '.rockspec', + '.wlua', + ], + group: null, + name: 'Lua', + type: 'programming', + }, + { + extensions: ['.mumps', '.m'], + group: null, + name: 'M', + type: 'programming', + }, + { + extensions: ['.m4', '.mc'], + group: null, + name: 'M4', + type: 'programming', + }, + { + extensions: ['.m4'], + group: 'M4', + name: 'M4Sugar', + type: 'programming', + }, + { + extensions: ['.matlab', '.m'], + group: null, + name: 'MATLAB', + type: 'programming', + }, + { + extensions: ['.ms', '.mcr'], + group: null, + name: 'MAXScript', + type: 'programming', + }, + { + extensions: ['.mlir'], + group: null, + name: 'MLIR', + type: 'programming', + }, + { + extensions: ['.mq4', '.mqh'], + group: null, + name: 'MQL4', + type: 'programming', + }, + { + extensions: ['.mq5', '.mqh'], + group: null, + name: 'MQL5', + type: 'programming', + }, + { + extensions: ['.mtml'], + group: null, + name: 'MTML', + type: 'markup', + }, + { + extensions: ['.muf', '.m'], + group: 'Forth', + name: 'MUF', + type: 'programming', + }, + { + extensions: ['.m2'], + group: null, + name: 'Macaulay2', + type: 'programming', + }, + { + extensions: ['.mak', '.d', '.make', '.makefile', '.mk', '.mkfile'], + group: null, + name: 'Makefile', + type: 'programming', + }, + { + extensions: ['.mako', '.mao'], + group: null, + name: 'Mako', + type: 'programming', + }, + { + extensions: [ + '.md', + '.livemd', + '.markdown', + '.mdown', + '.mdwn', + '.mdx', + '.mkd', + '.mkdn', + '.mkdown', + '.ronn', + '.scd', + '.workbook', + ], + group: null, + name: 'Markdown', + type: 'prose', + }, + { + extensions: ['.marko'], + group: null, + name: 'Marko', + type: 'markup', + }, + { + extensions: ['.mask'], + group: null, + name: 'Mask', + type: 'markup', + }, + { + extensions: [ + '.mathematica', + '.cdf', + '.m', + '.ma', + '.mt', + '.nb', + '.nbp', + '.wl', + '.wlt', + ], + group: null, + name: 'Mathematica', + type: 'programming', + }, + { + extensions: ['.maxpat', '.maxhelp', '.maxproj', '.mxt', '.pat'], + group: null, + name: 'Max', + type: 'programming', + }, + { + extensions: ['.m', '.moo'], + group: null, + name: 'Mercury', + type: 'programming', + }, + { + extensions: ['.mmd', '.mermaid'], + group: null, + name: 'Mermaid', + type: 'markup', + }, + { + extensions: ['.metal'], + group: null, + name: 'Metal', + type: 'programming', + }, + { + extensions: ['.dsp'], + group: null, + name: 'Microsoft Developer Studio Project', + type: 'data', + }, + { + extensions: ['.sln'], + group: null, + name: 'Microsoft Visual Studio Solution', + type: 'data', + }, + { + extensions: ['.minid'], + group: null, + name: 'MiniD', + type: 'programming', + }, + { + extensions: ['.mint'], + group: null, + name: 'Mint', + type: 'programming', + }, + { + extensions: ['.druby', '.duby', '.mirah'], + group: null, + name: 'Mirah', + type: 'programming', + }, + { + extensions: ['.mo'], + group: null, + name: 'Modelica', + type: 'programming', + }, + { + extensions: ['.mod'], + group: null, + name: 'Modula-2', + type: 'programming', + }, + { + extensions: ['.i3', '.ig', '.m3', '.mg'], + group: null, + name: 'Modula-3', + type: 'programming', + }, + { + extensions: ['.mms', '.mmk'], + group: null, + name: 'Module Management System', + type: 'programming', + }, + { + extensions: ['.monkey', '.monkey2'], + group: null, + name: 'Monkey', + type: 'programming', + }, + { + extensions: ['.mc'], + group: null, + name: 'Monkey C', + type: 'programming', + }, + { + extensions: ['.moo'], + group: null, + name: 'Moocode', + type: 'programming', + }, + { + extensions: ['.moon'], + group: null, + name: 'MoonScript', + type: 'programming', + }, + { + extensions: ['.mo'], + group: null, + name: 'Motoko', + type: 'programming', + }, + { + extensions: ['.asm', '.i', '.inc', '.s', '.x68'], + group: 'Assembly', + name: 'Motorola 68K Assembly', + type: 'programming', + }, + { + extensions: ['.move'], + group: null, + name: 'Move', + type: 'programming', + }, + { + extensions: ['.muse'], + group: null, + name: 'Muse', + type: 'prose', + }, + { + extensions: ['.mustache'], + group: null, + name: 'Mustache', + type: 'markup', + }, + { + extensions: ['.myt'], + group: null, + name: 'Myghty', + type: 'programming', + }, + { + extensions: ['.nasl', '.inc'], + group: null, + name: 'NASL', + type: 'programming', + }, + { + extensions: ['.ncl'], + group: null, + name: 'NCL', + type: 'programming', + }, + { + extensions: ['.neon'], + group: null, + name: 'NEON', + type: 'data', + }, + { + extensions: ['.nl'], + group: null, + name: 'NL', + type: 'data', + }, + { + extensions: ['.nsi', '.nsh'], + group: null, + name: 'NSIS', + type: 'programming', + }, + { + extensions: ['.nss'], + group: null, + name: 'NWScript', + type: 'programming', + }, + { + extensions: ['.nas'], + group: null, + name: 'Nasal', + type: 'programming', + }, + { + extensions: ['.ne', '.nearley'], + group: null, + name: 'Nearley', + type: 'programming', + }, + { + extensions: ['.n'], + group: null, + name: 'Nemerle', + type: 'programming', + }, + { + extensions: ['.axs', '.axi'], + group: null, + name: 'NetLinx', + type: 'programming', + }, + { + extensions: ['.axs.erb', '.axi.erb'], + group: null, + name: 'NetLinx+ERB', + type: 'programming', + }, + { + extensions: ['.nlogo'], + group: null, + name: 'NetLogo', + type: 'programming', + }, + { + extensions: ['.nl', '.lisp', '.lsp'], + group: null, + name: 'NewLisp', + type: 'programming', + }, + { + extensions: ['.nf'], + group: null, + name: 'Nextflow', + type: 'programming', + }, + { + extensions: ['.nginx', '.nginxconf', '.vhost'], + group: null, + name: 'Nginx', + type: 'data', + }, + { + extensions: ['.nim', '.nim.cfg', '.nimble', '.nimrod', '.nims'], + group: null, + name: 'Nim', + type: 'programming', + }, + { + extensions: ['.ninja'], + group: null, + name: 'Ninja', + type: 'data', + }, + { + extensions: ['.nit'], + group: null, + name: 'Nit', + type: 'programming', + }, + { + extensions: ['.nix'], + group: null, + name: 'Nix', + type: 'programming', + }, + { + extensions: ['.nu'], + group: null, + name: 'Nu', + type: 'programming', + }, + { + extensions: ['.numpy', '.numpyw', '.numsc'], + group: 'Python', + name: 'NumPy', + type: 'programming', + }, + { + extensions: ['.njk'], + group: null, + name: 'Nunjucks', + type: 'markup', + }, + { + extensions: ['.json'], + group: 'OpenAPI Specification v2', + name: 'OASv2-json', + type: 'data', + }, + { + extensions: ['.json'], + group: 'OpenAPI Specification v3', + name: 'OASv3-json', + type: 'data', + }, + { + extensions: ['.ml', '.eliom', '.eliomi', '.ml4', '.mli', '.mll', '.mly'], + group: null, + name: 'OCaml', + type: 'programming', + }, + { + extensions: ['.objdump'], + group: null, + name: 'ObjDump', + type: 'data', + }, + { + extensions: ['.odin'], + group: null, + name: 'Object Data Instance Notation', + type: 'data', + }, + { + extensions: ['.cls'], + group: null, + name: 'ObjectScript', + type: 'programming', + }, + { + extensions: ['.m', '.h'], + group: null, + name: 'Objective-C', + type: 'programming', + }, + { + extensions: ['.mm'], + group: null, + name: 'Objective-C++', + type: 'programming', + }, + { + extensions: ['.j', '.sj'], + group: null, + name: 'Objective-J', + type: 'programming', + }, + { + extensions: ['.odin'], + group: null, + name: 'Odin', + type: 'programming', + }, + { + extensions: ['.omgrofl'], + group: null, + name: 'Omgrofl', + type: 'programming', + }, + { + extensions: ['.opa'], + group: null, + name: 'Opa', + type: 'programming', + }, + { + extensions: ['.opal'], + group: null, + name: 'Opal', + type: 'programming', + }, + { + extensions: ['.rego'], + group: null, + name: 'Open Policy Agent', + type: 'programming', + }, + { + extensions: ['.cl', '.opencl'], + group: 'C', + name: 'OpenCL', + type: 'programming', + }, + { + extensions: ['.p', '.cls', '.w'], + group: null, + name: 'OpenEdge ABL', + type: 'programming', + }, + { + extensions: ['.qasm'], + group: null, + name: 'OpenQASM', + type: 'programming', + }, + { + extensions: ['.scad'], + group: null, + name: 'OpenSCAD', + type: 'programming', + }, + { + extensions: ['.plist', '.glyphs'], + group: null, + name: 'OpenStep Property List', + type: 'data', + }, + { + extensions: ['.fea'], + group: null, + name: 'OpenType Feature File', + type: 'data', + }, + { + extensions: ['.org'], + group: null, + name: 'Org', + type: 'prose', + }, + { + extensions: ['.ox', '.oxh', '.oxo'], + group: null, + name: 'Ox', + type: 'programming', + }, + { + extensions: ['.oxygene'], + group: null, + name: 'Oxygene', + type: 'programming', + }, + { + extensions: ['.oz'], + group: null, + name: 'Oz', + type: 'programming', + }, + { + extensions: ['.p4'], + group: null, + name: 'P4', + type: 'programming', + }, + { + extensions: ['.pddl'], + group: null, + name: 'PDDL', + type: 'programming', + }, + { + extensions: ['.pegjs'], + group: null, + name: 'PEG.js', + type: 'programming', + }, + { + extensions: [ + '.php', + '.aw', + '.ctp', + '.fcgi', + '.inc', + '.php3', + '.php4', + '.php5', + '.phps', + '.phpt', + ], + group: null, + name: 'PHP', + type: 'programming', + }, + { + extensions: [ + '.pls', + '.bdy', + '.ddl', + '.fnc', + '.pck', + '.pkb', + '.pks', + '.plb', + '.plsql', + '.prc', + '.spc', + '.sql', + '.tpb', + '.tps', + '.trg', + '.vw', + ], + group: null, + name: 'PLSQL', + type: 'programming', + }, + { + extensions: ['.pgsql', '.sql'], + group: null, + name: 'PLpgSQL', + type: 'programming', + }, + { + extensions: ['.pov', '.inc'], + group: null, + name: 'POV-Ray SDL', + type: 'programming', + }, + { + extensions: ['.pan'], + group: null, + name: 'Pan', + type: 'programming', + }, + { + extensions: ['.psc'], + group: null, + name: 'Papyrus', + type: 'programming', + }, + { + extensions: ['.parrot'], + group: null, + name: 'Parrot', + type: 'programming', + }, + { + extensions: ['.pasm'], + group: 'Parrot', + name: 'Parrot Assembly', + type: 'programming', + }, + { + extensions: ['.pir'], + group: 'Parrot', + name: 'Parrot Internal Representation', + type: 'programming', + }, + { + extensions: ['.pas', '.dfm', '.dpr', '.inc', '.lpr', '.pascal', '.pp'], + group: null, + name: 'Pascal', + type: 'programming', + }, + { + extensions: ['.pwn', '.inc', '.sma'], + group: null, + name: 'Pawn', + type: 'programming', + }, + { + extensions: ['.pep'], + group: null, + name: 'Pep8', + type: 'programming', + }, + { + extensions: [ + '.pl', + '.al', + '.cgi', + '.fcgi', + '.perl', + '.ph', + '.plx', + '.pm', + '.psgi', + '.t', + ], + group: null, + name: 'Perl', + type: 'programming', + }, + { + extensions: ['.pic', '.chem'], + group: 'Roff', + name: 'Pic', + type: 'markup', + }, + { + extensions: ['.pkl'], + group: null, + name: 'Pickle', + type: 'data', + }, + { + extensions: ['.l'], + group: null, + name: 'PicoLisp', + type: 'programming', + }, + { + extensions: ['.pig'], + group: null, + name: 'PigLatin', + type: 'programming', + }, + { + extensions: ['.pike', '.pmod'], + group: null, + name: 'Pike', + type: 'programming', + }, + { + extensions: ['.puml', '.iuml', '.plantuml'], + group: null, + name: 'PlantUML', + type: 'data', + }, + { + extensions: ['.pod'], + group: null, + name: 'Pod', + type: 'prose', + }, + { + extensions: ['.pod', '.pod6'], + group: null, + name: 'Pod 6', + type: 'prose', + }, + { + extensions: ['.pogo'], + group: null, + name: 'PogoScript', + type: 'programming', + }, + { + extensions: ['.polar'], + group: null, + name: 'Polar', + type: 'programming', + }, + { + extensions: ['.pony'], + group: null, + name: 'Pony', + type: 'programming', + }, + { + extensions: ['.por'], + group: null, + name: 'Portugol', + type: 'programming', + }, + { + extensions: ['.pcss', '.postcss'], + group: 'CSS', + name: 'PostCSS', + type: 'markup', + }, + { + extensions: ['.ps', '.eps', '.epsi', '.pfa'], + group: null, + name: 'PostScript', + type: 'markup', + }, + { + extensions: ['.pbt', '.sra', '.sru', '.srw'], + group: null, + name: 'PowerBuilder', + type: 'programming', + }, + { + extensions: ['.ps1', '.psd1', '.psm1'], + group: null, + name: 'PowerShell', + type: 'programming', + }, + { + extensions: ['.prisma'], + group: null, + name: 'Prisma', + type: 'data', + }, + { + extensions: ['.pde'], + group: null, + name: 'Processing', + type: 'programming', + }, + { + extensions: ['.pro'], + group: null, + name: 'Proguard', + type: 'data', + }, + { + extensions: ['.pl', '.plt', '.pro', '.prolog', '.yap'], + group: null, + name: 'Prolog', + type: 'programming', + }, + { + extensions: ['.pml'], + group: null, + name: 'Promela', + type: 'programming', + }, + { + extensions: ['.spin'], + group: null, + name: 'Propeller Spin', + type: 'programming', + }, + { + extensions: ['.proto'], + group: null, + name: 'Protocol Buffer', + type: 'data', + }, + { + extensions: ['.textproto', '.pbt', '.pbtxt'], + group: null, + name: 'Protocol Buffer Text Format', + type: 'data', + }, + { + extensions: ['.asc', '.pub'], + group: null, + name: 'Public Key', + type: 'data', + }, + { + extensions: ['.jade', '.pug'], + group: null, + name: 'Pug', + type: 'markup', + }, + { + extensions: ['.pp'], + group: null, + name: 'Puppet', + type: 'programming', + }, + { + extensions: ['.pd'], + group: null, + name: 'Pure Data', + type: 'data', + }, + { + extensions: ['.pb', '.pbi'], + group: null, + name: 'PureBasic', + type: 'programming', + }, + { + extensions: ['.purs'], + group: null, + name: 'PureScript', + type: 'programming', + }, + { + extensions: ['.arr'], + group: null, + name: 'Pyret', + type: 'programming', + }, + { + extensions: [ + '.py', + '.cgi', + '.fcgi', + '.gyp', + '.gypi', + '.lmi', + '.py3', + '.pyde', + '.pyi', + '.pyp', + '.pyt', + '.pyw', + '.rpy', + '.spec', + '.tac', + '.wsgi', + '.xpy', + ], + group: null, + name: 'Python', + type: 'programming', + }, + { + extensions: ['.pytb'], + group: 'Python', + name: 'Python traceback', + type: 'data', + }, + { + extensions: ['.qs'], + group: null, + name: 'Q#', + type: 'programming', + }, + { + extensions: ['.qml', '.qbs'], + group: null, + name: 'QML', + type: 'programming', + }, + { + extensions: ['.pro', '.pri'], + group: null, + name: 'QMake', + type: 'programming', + }, + { + extensions: ['.qs'], + group: null, + name: 'Qt Script', + type: 'programming', + }, + { + extensions: ['.r', '.rd', '.rsx'], + group: null, + name: 'R', + type: 'programming', + }, + { + extensions: ['.raml'], + group: null, + name: 'RAML', + type: 'markup', + }, + { + extensions: ['.rdoc'], + group: null, + name: 'RDoc', + type: 'prose', + }, + { + extensions: [ + '.rbbas', + '.rbfrm', + '.rbmnu', + '.rbres', + '.rbtbar', + '.rbuistate', + ], + group: null, + name: 'REALbasic', + type: 'programming', + }, + { + extensions: ['.rexx', '.pprx', '.rex'], + group: null, + name: 'REXX', + type: 'programming', + }, + { + extensions: ['.qmd', '.rmd'], + group: null, + name: 'RMarkdown', + type: 'prose', + }, + { + extensions: ['.x'], + group: null, + name: 'RPC', + type: 'programming', + }, + { + extensions: ['.rpgle', '.sqlrpgle'], + group: null, + name: 'RPGLE', + type: 'programming', + }, + { + extensions: ['.spec'], + group: null, + name: 'RPM Spec', + type: 'data', + }, + { + extensions: ['.rnh', '.rno'], + group: null, + name: 'RUNOFF', + type: 'markup', + }, + { + extensions: ['.rkt', '.rktd', '.rktl', '.scrbl'], + group: null, + name: 'Racket', + type: 'programming', + }, + { + extensions: ['.rl'], + group: null, + name: 'Ragel', + type: 'programming', + }, + { + extensions: [ + '.6pl', + '.6pm', + '.nqp', + '.p6', + '.p6l', + '.p6m', + '.pl', + '.pl6', + '.pm', + '.pm6', + '.raku', + '.rakumod', + '.t', + ], + group: null, + name: 'Raku', + type: 'programming', + }, + { + extensions: ['.rsc'], + group: null, + name: 'Rascal', + type: 'programming', + }, + { + extensions: ['.raw'], + group: null, + name: 'Raw token data', + type: 'data', + }, + { + extensions: ['.res'], + group: null, + name: 'ReScript', + type: 'programming', + }, + { + extensions: ['.re', '.rei'], + group: null, + name: 'Reason', + type: 'programming', + }, + { + extensions: ['.religo'], + group: 'LigoLANG', + name: 'ReasonLIGO', + type: 'programming', + }, + { + extensions: ['.reb', '.r', '.r2', '.r3', '.rebol'], + group: null, + name: 'Rebol', + type: 'programming', + }, + { + extensions: ['.red', '.reds'], + group: null, + name: 'Red', + type: 'programming', + }, + { + extensions: ['.cw'], + group: null, + name: 'Redcode', + type: 'programming', + }, + { + extensions: ['.regexp', '.regex'], + group: null, + name: 'Regular Expression', + type: 'data', + }, + { + extensions: ['.rpy'], + group: null, + name: "Ren'Py", + type: 'programming', + }, + { + extensions: ['.rs', '.rsh'], + group: null, + name: 'RenderScript', + type: 'programming', + }, + { + extensions: ['.rtf'], + group: null, + name: 'Rich Text Format', + type: 'markup', + }, + { + extensions: ['.ring'], + group: null, + name: 'Ring', + type: 'programming', + }, + { + extensions: ['.riot'], + group: null, + name: 'Riot', + type: 'markup', + }, + { + extensions: ['.robot'], + group: null, + name: 'RobotFramework', + type: 'programming', + }, + { + extensions: [ + '.roff', + '.1', + '.1in', + '.1m', + '.1x', + '.2', + '.3', + '.3in', + '.3m', + '.3p', + '.3pm', + '.3qt', + '.3x', + '.4', + '.5', + '.6', + '.7', + '.8', + '.9', + '.l', + '.man', + '.mdoc', + '.me', + '.ms', + '.n', + '.nr', + '.rno', + '.tmac', + ], + group: null, + name: 'Roff', + type: 'markup', + }, + { + extensions: [ + '.1', + '.1in', + '.1m', + '.1x', + '.2', + '.3', + '.3in', + '.3m', + '.3p', + '.3pm', + '.3qt', + '.3x', + '.4', + '.5', + '.6', + '.7', + '.8', + '.9', + '.man', + '.mdoc', + ], + group: 'Roff', + name: 'Roff Manpage', + type: 'markup', + }, + { + extensions: ['.rg'], + group: null, + name: 'Rouge', + type: 'programming', + }, + { + extensions: ['.rsc'], + group: null, + name: 'RouterOS Script', + type: 'programming', + }, + { + extensions: [ + '.rb', + '.builder', + '.eye', + '.fcgi', + '.gemspec', + '.god', + '.jbuilder', + '.mspec', + '.pluginspec', + '.podspec', + '.prawn', + '.rabl', + '.rake', + '.rbi', + '.rbuild', + '.rbw', + '.rbx', + '.ru', + '.ruby', + '.spec', + '.thor', + '.watchr', + ], + group: null, + name: 'Ruby', + type: 'programming', + }, + { + extensions: ['.rs', '.rs.in'], + group: null, + name: 'Rust', + type: 'programming', + }, + { + extensions: ['.sas'], + group: null, + name: 'SAS', + type: 'programming', + }, + { + extensions: ['.scss'], + group: null, + name: 'SCSS', + type: 'markup', + }, + { + extensions: ['.te'], + group: null, + name: 'SELinux Policy', + type: 'data', + }, + { + extensions: ['.smt2', '.smt'], + group: null, + name: 'SMT', + type: 'programming', + }, + { + extensions: ['.sparql', '.rq'], + group: null, + name: 'SPARQL', + type: 'data', + }, + { + extensions: ['.sqf', '.hqf'], + group: null, + name: 'SQF', + type: 'programming', + }, + { + extensions: [ + '.sql', + '.cql', + '.ddl', + '.inc', + '.mysql', + '.prc', + '.tab', + '.udf', + '.viw', + ], + group: null, + name: 'SQL', + type: 'data', + }, + { + extensions: ['.sql', '.db2'], + group: null, + name: 'SQLPL', + type: 'programming', + }, + { + extensions: ['.srt'], + group: null, + name: 'SRecode Template', + type: 'markup', + }, + { + extensions: ['.star'], + group: null, + name: 'STAR', + type: 'data', + }, + { + extensions: ['.stl'], + group: null, + name: 'STL', + type: 'data', + }, + { + extensions: ['.ston'], + group: 'Smalltalk', + name: 'STON', + type: 'data', + }, + { + extensions: ['.svg'], + group: null, + name: 'SVG', + type: 'data', + }, + { + extensions: ['.i'], + group: null, + name: 'SWIG', + type: 'programming', + }, + { + extensions: ['.sage', '.sagews'], + group: null, + name: 'Sage', + type: 'programming', + }, + { + extensions: ['.sls'], + group: null, + name: 'SaltStack', + type: 'programming', + }, + { + extensions: ['.sass'], + group: null, + name: 'Sass', + type: 'markup', + }, + { + extensions: ['.scala', '.kojo', '.sbt', '.sc'], + group: null, + name: 'Scala', + type: 'programming', + }, + { + extensions: ['.scaml'], + group: null, + name: 'Scaml', + type: 'markup', + }, + { + extensions: ['.scenic'], + group: null, + name: 'Scenic', + type: 'programming', + }, + { + extensions: ['.scm', '.sch', '.sld', '.sls', '.sps', '.ss'], + group: null, + name: 'Scheme', + type: 'programming', + }, + { + extensions: ['.sci', '.sce', '.tst'], + group: null, + name: 'Scilab', + type: 'programming', + }, + { + extensions: ['.self'], + group: null, + name: 'Self', + type: 'programming', + }, + { + extensions: ['.shader'], + group: null, + name: 'ShaderLab', + type: 'programming', + }, + { + extensions: [ + '.sh', + '.bash', + '.bats', + '.cgi', + '.command', + '.fcgi', + '.ksh', + '.sh.in', + '.tmux', + '.tool', + '.zsh', + '.zsh-theme', + ], + group: null, + name: 'Shell', + type: 'programming', + }, + { + extensions: ['.sh-session'], + group: null, + name: 'ShellSession', + type: 'programming', + }, + { + extensions: ['.shen'], + group: null, + name: 'Shen', + type: 'programming', + }, + { + extensions: ['.sieve'], + group: null, + name: 'Sieve', + type: 'programming', + }, + { + extensions: ['.sfv'], + group: 'Checksums', + name: 'Simple File Verification', + type: 'data', + }, + { + extensions: ['.sl'], + group: null, + name: 'Slash', + type: 'programming', + }, + { + extensions: ['.ice'], + group: null, + name: 'Slice', + type: 'programming', + }, + { + extensions: ['.slim'], + group: null, + name: 'Slim', + type: 'markup', + }, + { + extensions: ['.cocci'], + group: null, + name: 'SmPL', + type: 'programming', + }, + { + extensions: ['.smali'], + group: null, + name: 'Smali', + type: 'programming', + }, + { + extensions: ['.st', '.cs'], + group: null, + name: 'Smalltalk', + type: 'programming', + }, + { + extensions: ['.tpl'], + group: null, + name: 'Smarty', + type: 'programming', + }, + { + extensions: ['.smithy'], + group: null, + name: 'Smithy', + type: 'programming', + }, + { + extensions: ['.smk', '.snakefile'], + group: 'Python', + name: 'Snakemake', + type: 'programming', + }, + { + extensions: ['.sol'], + group: null, + name: 'Solidity', + type: 'programming', + }, + { + extensions: ['.sp', '.inc'], + group: null, + name: 'SourcePawn', + type: 'programming', + }, + { + extensions: ['.sfd'], + group: null, + name: 'Spline Font Database', + type: 'data', + }, + { + extensions: ['.nut'], + group: null, + name: 'Squirrel', + type: 'programming', + }, + { + extensions: ['.stan'], + group: null, + name: 'Stan', + type: 'programming', + }, + { + extensions: ['.ml', '.fun', '.sig', '.sml'], + group: null, + name: 'Standard ML', + type: 'programming', + }, + { + extensions: ['.bzl', '.star'], + group: null, + name: 'Starlark', + type: 'programming', + }, + { + extensions: ['.do', '.ado', '.doh', '.ihlp', '.mata', '.matah', '.sthlp'], + group: null, + name: 'Stata', + type: 'programming', + }, + { + extensions: ['.st'], + group: null, + name: 'StringTemplate', + type: 'markup', + }, + { + extensions: ['.styl'], + group: null, + name: 'Stylus', + type: 'markup', + }, + { + extensions: ['.srt'], + group: null, + name: 'SubRip Text', + type: 'data', + }, + { + extensions: ['.sss'], + group: null, + name: 'SugarSS', + type: 'markup', + }, + { + extensions: ['.sc', '.scd'], + group: null, + name: 'SuperCollider', + type: 'programming', + }, + { + extensions: ['.svelte'], + group: null, + name: 'Svelte', + type: 'markup', + }, + { + extensions: ['.sw'], + group: null, + name: 'Sway', + type: 'programming', + }, + { + extensions: ['.swift'], + group: null, + name: 'Swift', + type: 'programming', + }, + { + extensions: ['.sv', '.svh', '.vh'], + group: null, + name: 'SystemVerilog', + type: 'programming', + }, + { + extensions: ['.8xp', '.8xk', '.8xk.txt', '.8xp.txt'], + group: null, + name: 'TI Program', + type: 'programming', + }, + { + extensions: ['.tla'], + group: null, + name: 'TLA', + type: 'programming', + }, + { + extensions: ['.toml'], + group: null, + name: 'TOML', + type: 'data', + }, + { + extensions: ['.sql'], + group: null, + name: 'TSQL', + type: 'programming', + }, + { + extensions: ['.tsv'], + group: null, + name: 'TSV', + type: 'data', + }, + { + extensions: ['.tsx'], + group: 'TypeScript', + name: 'TSX', + type: 'programming', + }, + { + extensions: ['.txl'], + group: null, + name: 'TXL', + type: 'programming', + }, + { + extensions: ['.talon'], + group: null, + name: 'Talon', + type: 'programming', + }, + { + extensions: ['.tcl', '.adp', '.sdc', '.tcl.in', '.tm', '.xdc'], + group: null, + name: 'Tcl', + type: 'programming', + }, + { + extensions: ['.tcsh', '.csh'], + group: 'Shell', + name: 'Tcsh', + type: 'programming', + }, + { + extensions: [ + '.tex', + '.aux', + '.bbx', + '.cbx', + '.cls', + '.dtx', + '.ins', + '.lbx', + '.ltx', + '.mkii', + '.mkiv', + '.mkvi', + '.sty', + '.toc', + ], + group: null, + name: 'TeX', + type: 'markup', + }, + { + extensions: ['.tea'], + group: null, + name: 'Tea', + type: 'markup', + }, + { + extensions: ['.t'], + group: null, + name: 'Terra', + type: 'programming', + }, + { + extensions: ['.texinfo', '.texi', '.txi'], + group: null, + name: 'Texinfo', + type: 'prose', + }, + { + extensions: ['.txt', '.fr', '.nb', '.ncl', '.no'], + group: null, + name: 'Text', + type: 'prose', + }, + { + extensions: ['.textile'], + group: null, + name: 'Textile', + type: 'prose', + }, + { + extensions: ['.thrift'], + group: null, + name: 'Thrift', + type: 'programming', + }, + { + extensions: ['.t', '.tu'], + group: null, + name: 'Turing', + type: 'programming', + }, + { + extensions: ['.ttl'], + group: null, + name: 'Turtle', + type: 'data', + }, + { + extensions: ['.twig'], + group: null, + name: 'Twig', + type: 'markup', + }, + { + extensions: ['.tl'], + group: null, + name: 'Type Language', + type: 'data', + }, + { + extensions: ['.ts', '.cts', '.mts'], + group: null, + name: 'TypeScript', + type: 'programming', + }, + { + extensions: ['.upc'], + group: 'C', + name: 'Unified Parallel C', + type: 'programming', + }, + { + extensions: [ + '.anim', + '.asset', + '.mask', + '.mat', + '.meta', + '.prefab', + '.unity', + ], + group: null, + name: 'Unity3D Asset', + type: 'data', + }, + { + extensions: ['.s', '.ms'], + group: 'Assembly', + name: 'Unix Assembly', + type: 'programming', + }, + { + extensions: ['.uno'], + group: null, + name: 'Uno', + type: 'programming', + }, + { + extensions: ['.uc'], + group: null, + name: 'UnrealScript', + type: 'programming', + }, + { + extensions: ['.ur', '.urs'], + group: null, + name: 'UrWeb', + type: 'programming', + }, + { + extensions: ['.v'], + group: null, + name: 'V', + type: 'programming', + }, + { + extensions: ['.bas', '.cls', '.frm', '.vba'], + group: null, + name: 'VBA', + type: 'programming', + }, + { + extensions: ['.vbs'], + group: null, + name: 'VBScript', + type: 'programming', + }, + { + extensions: ['.vcl'], + group: null, + name: 'VCL', + type: 'programming', + }, + { + extensions: [ + '.vhdl', + '.vhd', + '.vhf', + '.vhi', + '.vho', + '.vhs', + '.vht', + '.vhw', + ], + group: null, + name: 'VHDL', + type: 'programming', + }, + { + extensions: ['.vala', '.vapi'], + group: null, + name: 'Vala', + type: 'programming', + }, + { + extensions: ['.vdf'], + group: null, + name: 'Valve Data Format', + type: 'data', + }, + { + extensions: ['.vtl'], + group: null, + name: 'Velocity Template Language', + type: 'markup', + }, + { + extensions: ['.v', '.veo'], + group: null, + name: 'Verilog', + type: 'programming', + }, + { + extensions: ['.txt'], + group: null, + name: 'Vim Help File', + type: 'prose', + }, + { + extensions: ['.vim', '.vba', '.vimrc', '.vmb'], + group: null, + name: 'Vim Script', + type: 'programming', + }, + { + extensions: ['.snip', '.snippet', '.snippets'], + group: null, + name: 'Vim Snippet', + type: 'markup', + }, + { + extensions: ['.vb', '.vbhtml'], + group: null, + name: 'Visual Basic .NET', + type: 'programming', + }, + { + extensions: ['.cls', '.ctl', '.Dsr', '.frm'], + group: null, + name: 'Visual Basic 6.0', + type: 'programming', + }, + { + extensions: ['.volt'], + group: null, + name: 'Volt', + type: 'programming', + }, + { + extensions: ['.vue'], + group: null, + name: 'Vue', + type: 'markup', + }, + { + extensions: ['.vy'], + group: null, + name: 'Vyper', + type: 'programming', + }, + { + extensions: ['.mtl'], + group: null, + name: 'Wavefront Material', + type: 'data', + }, + { + extensions: ['.obj'], + group: null, + name: 'Wavefront Object', + type: 'data', + }, + { + extensions: ['.owl'], + group: null, + name: 'Web Ontology Language', + type: 'data', + }, + { + extensions: ['.wast', '.wat'], + group: null, + name: 'WebAssembly', + type: 'programming', + }, + { + extensions: ['.webidl'], + group: null, + name: 'WebIDL', + type: 'programming', + }, + { + extensions: ['.vtt'], + group: null, + name: 'WebVTT', + type: 'data', + }, + { + extensions: ['.whiley'], + group: null, + name: 'Whiley', + type: 'programming', + }, + { + extensions: ['.mediawiki', '.wiki', '.wikitext'], + group: null, + name: 'Wikitext', + type: 'prose', + }, + { + extensions: ['.mc'], + group: null, + name: 'Win32 Message File', + type: 'data', + }, + { + extensions: ['.reg'], + group: null, + name: 'Windows Registry Entries', + type: 'data', + }, + { + extensions: ['.ws'], + group: null, + name: 'Witcher Script', + type: 'programming', + }, + { + extensions: ['.wlk'], + group: null, + name: 'Wollok', + type: 'programming', + }, + { + extensions: ['.toc'], + group: null, + name: 'World of Warcraft Addon Data', + type: 'data', + }, + { + extensions: ['.wren'], + group: null, + name: 'Wren', + type: 'programming', + }, + { + extensions: ['.xbm'], + group: 'C', + name: 'X BitMap', + type: 'data', + }, + { + extensions: ['.xpm', '.pm'], + group: 'C', + name: 'X PixMap', + type: 'data', + }, + { + extensions: ['.x10'], + group: null, + name: 'X10', + type: 'programming', + }, + { + extensions: ['.xc'], + group: null, + name: 'XC', + type: 'programming', + }, + { + extensions: [ + '.xml', + '.adml', + '.admx', + '.ant', + '.axaml', + '.axml', + '.builds', + '.ccproj', + '.ccxml', + '.clixml', + '.cproject', + '.cscfg', + '.csdef', + '.csl', + '.csproj', + '.ct', + '.depproj', + '.dita', + '.ditamap', + '.ditaval', + '.dll.config', + '.dotsettings', + '.filters', + '.fsproj', + '.fxml', + '.glade', + '.gml', + '.gmx', + '.grxml', + '.gst', + '.hzp', + '.iml', + '.ivy', + '.jelly', + '.jsproj', + '.kml', + '.launch', + '.mdpolicy', + '.mjml', + '.mm', + '.mod', + '.mxml', + '.natvis', + '.ncl', + '.ndproj', + '.nproj', + '.nuspec', + '.odd', + '.osm', + '.pkgproj', + '.pluginspec', + '.proj', + '.props', + '.ps1xml', + '.psc1', + '.pt', + '.qhelp', + '.rdf', + '.res', + '.resx', + '.rs', + '.rss', + '.sch', + '.scxml', + '.sfproj', + '.shproj', + '.srdf', + '.storyboard', + '.sublime-snippet', + '.sw', + '.targets', + '.tml', + '.ts', + '.tsx', + '.ui', + '.urdf', + '.ux', + '.vbproj', + '.vcxproj', + '.vsixmanifest', + '.vssettings', + '.vstemplate', + '.vxml', + '.wixproj', + '.workflow', + '.wsdl', + '.wsf', + '.wxi', + '.wxl', + '.wxs', + '.x3d', + '.xacro', + '.xaml', + '.xib', + '.xlf', + '.xliff', + '.xmi', + '.xml.dist', + '.xmp', + '.xproj', + '.xsd', + '.xspec', + '.xul', + '.zcml', + ], + group: null, + name: 'XML', + type: 'data', + }, + { + extensions: [ + '.plist', + '.stTheme', + '.tmCommand', + '.tmLanguage', + '.tmPreferences', + '.tmSnippet', + '.tmTheme', + ], + group: 'XML', + name: 'XML Property List', + type: 'data', + }, + { + extensions: ['.xsp-config', '.xsp.metadata'], + group: null, + name: 'XPages', + type: 'data', + }, + { + extensions: ['.xpl', '.xproc'], + group: null, + name: 'XProc', + type: 'programming', + }, + { + extensions: ['.xquery', '.xq', '.xql', '.xqm', '.xqy'], + group: null, + name: 'XQuery', + type: 'programming', + }, + { + extensions: ['.xs'], + group: null, + name: 'XS', + type: 'programming', + }, + { + extensions: ['.xslt', '.xsl'], + group: null, + name: 'XSLT', + type: 'programming', + }, + { + extensions: [ + '.xojo_code', + '.xojo_menu', + '.xojo_report', + '.xojo_script', + '.xojo_toolbar', + '.xojo_window', + ], + group: null, + name: 'Xojo', + type: 'programming', + }, + { + extensions: ['.xsh'], + group: null, + name: 'Xonsh', + type: 'programming', + }, + { + extensions: ['.xtend'], + group: null, + name: 'Xtend', + type: 'programming', + }, + { + extensions: [ + '.yml', + '.mir', + '.reek', + '.rviz', + '.sublime-syntax', + '.syntax', + '.yaml', + '.yaml-tmlanguage', + '.yaml.sed', + '.yml.mysql', + ], + group: null, + name: 'YAML', + type: 'data', + }, + { + extensions: ['.yang'], + group: null, + name: 'YANG', + type: 'data', + }, + { + extensions: ['.yar', '.yara'], + group: null, + name: 'YARA', + type: 'programming', + }, + { + extensions: ['.yasnippet'], + group: null, + name: 'YASnippet', + type: 'markup', + }, + { + extensions: ['.y', '.yacc', '.yy'], + group: null, + name: 'Yacc', + type: 'programming', + }, + { + extensions: ['.yul'], + group: null, + name: 'Yul', + type: 'programming', + }, + { + extensions: ['.zap', '.xzap'], + group: null, + name: 'ZAP', + type: 'programming', + }, + { + extensions: ['.zil', '.mud'], + group: null, + name: 'ZIL', + type: 'programming', + }, + { + extensions: ['.zeek', '.bro'], + group: null, + name: 'Zeek', + type: 'programming', + }, + { + extensions: ['.zs'], + group: null, + name: 'ZenScript', + type: 'programming', + }, + { + extensions: ['.zep'], + group: null, + name: 'Zephir', + type: 'programming', + }, + { + extensions: ['.zig'], + group: null, + name: 'Zig', + type: 'programming', + }, + { + extensions: ['.zimpl', '.zmpl', '.zpl'], + group: null, + name: 'Zimpl', + type: 'programming', + }, + { + extensions: ['.desktop', '.desktop.in', '.service'], + group: null, + name: 'desktop', + type: 'data', + }, + { + extensions: ['.dircolors'], + group: null, + name: 'dircolors', + type: 'data', + }, + { + extensions: ['.ec', '.eh'], + group: null, + name: 'eC', + type: 'programming', + }, + { + extensions: ['.edn'], + group: null, + name: 'edn', + type: 'data', + }, + { + extensions: ['.fish'], + group: 'Shell', + name: 'fish', + type: 'programming', + }, + { + extensions: ['.hoon'], + group: null, + name: 'hoon', + type: 'programming', + }, + { + extensions: ['.jq'], + group: null, + name: 'jq', + type: 'programming', + }, + { + extensions: ['.kv'], + group: null, + name: 'kvlang', + type: 'markup', + }, + { + extensions: ['.mrc'], + group: null, + name: 'mIRC Script', + type: 'programming', + }, + { + extensions: ['.mcfunction'], + group: null, + name: 'mcfunction', + type: 'programming', + }, + { + extensions: ['.mu'], + group: null, + name: 'mupad', + type: 'programming', + }, + { + extensions: ['.nanorc'], + group: 'INI', + name: 'nanorc', + type: 'data', + }, + { + extensions: ['.nc'], + group: null, + name: 'nesC', + type: 'programming', + }, + { + extensions: ['.ooc'], + group: null, + name: 'ooc', + type: 'programming', + }, + { + extensions: ['.q'], + group: null, + name: 'q', + type: 'programming', + }, + { + extensions: ['.rst', '.rest', '.rest.txt', '.rst.txt'], + group: null, + name: 'reStructuredText', + type: 'prose', + }, + { + extensions: ['.sed'], + group: null, + name: 'sed', + type: 'programming', + }, + { + extensions: ['.wdl'], + group: null, + name: 'wdl', + type: 'programming', + }, + { + extensions: ['.wisp'], + group: null, + name: 'wisp', + type: 'programming', + }, + { + extensions: ['.prg', '.ch', '.prw'], + group: null, + name: 'xBase', + type: 'programming', + }, +]; + +export const languages = rawList.filter((l) => l.type === 'programming'); +export const others = rawList.filter((l) => l.type !== 'programming'); diff --git a/src/common/techs.ts b/src/common/techs.ts index 1900a670..6c824f1c 100644 --- a/src/common/techs.ts +++ b/src/common/techs.ts @@ -36,6 +36,7 @@ export const list: TechItem[] = [ { key: 'html', name: 'HTML', type: 'language' }, { key: 'influxdb', name: 'Influxdb', type: 'db' }, { key: 'java', name: 'Java', type: 'language' }, + { key: 'javascript', name: 'JavaScript', type: 'language' }, { key: 'jest', name: 'Jest', type: 'tool' }, { key: 'jira', name: 'Jira', type: 'sass' }, { key: 'koa', name: 'Koa', type: 'tool' }, @@ -69,6 +70,8 @@ export const list: TechItem[] = [ { key: 'redis', name: 'Redis', type: 'db' }, { key: 'ruby', name: 'Ruby', type: 'language' }, { key: 'rust', name: 'Rust', type: 'language' }, + { key: 'scss', name: 'SCSS', type: 'language' }, + { key: 'shell', name: 'Shell', type: 'language' }, { key: 'sentry', name: 'Sentry', type: 'sass' }, { key: 'slack', name: 'Slack', type: 'sass' }, { key: 'sequelize', name: 'Sequelize', type: 'tool' }, @@ -94,3 +97,8 @@ export const listIndexed: Record = {} as any; Object.values(list).forEach((v) => { listIndexed[v.key] = v; }); + +export const nameToKey: Record = {} as any; +Object.values(list).forEach((v) => { + nameToKey[v.name] = v.key; +}); diff --git a/src/payload/index.ts b/src/payload/index.ts index 7c1a6540..b2044462 100644 --- a/src/payload/index.ts +++ b/src/payload/index.ts @@ -1,16 +1,32 @@ -import type { Service, TechAnalyser } from '../types'; +import path from 'node:path'; + +import { languages, others } from '../common/languages'; +import { nameToKey } from '../common/techs'; +import type { GraphEdge, TechAnalyser } from '../types'; import type { AllowedKeys } from '../types/techs'; export class Payload { - private services: Service[]; + public languages: Record; + + private name: string; + private path: string; + private edges: GraphEdge[]; + private tech: AllowedKeys | null; + private services: Payload[]; private techs: Set; - constructor() { + constructor(name: string, folderPath: string, tech?: AllowedKeys | null) { + this.name = name; + this.path = folderPath; + this.tech = tech || null; + this.edges = []; + this.services = []; this.techs = new Set(); + this.languages = {}; } - addService(service: Service) { + addService(service: Payload) { const exist = this.services.find((s) => s.name === service.name); if (exist) { // TODO: merge @@ -27,12 +43,51 @@ export class Payload { } } - addTech(tech: AllowedKeys) { + addTech(tech: AllowedKeys | AllowedKeys[]) { + if (Array.isArray(tech)) { + tech.forEach((t) => this.techs.add(t)); + return; + } + this.techs.add(tech); } + detectLang(filename: string) { + const ext = path.extname(filename); + + for (const lang of languages) { + if (!lang.extensions.includes(ext)) { + continue; + } + + this.addLang(lang.group || lang.name); + return; + } + + for (const lang of others) { + if (!lang.extensions.includes(ext)) { + continue; + } + + this.addLang(lang.group || lang.name); + return; + } + } + + merge(pl: Payload) { + this.addTech([...pl.techs]); + pl.services.forEach((service) => this.addService(service)); + + if (pl.name !== 'virtual') { + this.addService(pl); + } + } + toJson(): TechAnalyser { return { + name: this.name, + path: this.path, + tech: this.tech, services: this.services.map((service) => { return { name: service.name, @@ -43,6 +98,19 @@ export class Payload { }; }), techs: [...this.techs], + languages: this.languages, }; } + + private addLang(name: string) { + if (!this.languages[name]) { + this.languages[name] = 0; + } + + this.languages[name] += 1; + + if (name in nameToKey) { + this.addTech(nameToKey[name]); + } + } } diff --git a/src/rules/docker/service.ts b/src/rules/docker/service.ts index e7eb735b..24e0a6a4 100644 --- a/src/rules/docker/service.ts +++ b/src/rules/docker/service.ts @@ -1,7 +1,7 @@ import { parse } from 'yaml'; +import { Payload } from '../../payload'; import type { BaseProvider, ProviderFile } from '../../provider/base'; -import type { RuleServiceReturn, Service } from '../../types'; import { detectImages } from './images'; @@ -15,7 +15,7 @@ interface DockerComposeService { export async function detectDockerServices( files: ProviderFile[], provider: BaseProvider -): Promise { +): Promise { for (const file of files) { if (!FILES.includes(file.name)) { continue; @@ -31,20 +31,21 @@ export async function detectDockerServices( return false; } - const services: Service[] = []; + const pl = new Payload('virtual', file.fp); + for (const [name, service] of Object.entries( parsed.services )) { - services.push({ - name: service.container_name || name, - path: file.fp, - tech: service.image ? detectImages(service.image) : null, - techs: new Set(), - edges: [], - }); + pl.addService( + new Payload( + service.container_name || name, + file.fp, + service.image ? detectImages(service.image) : null + ) + ); } - return services; + return pl; } return false; diff --git a/src/rules/nodejs/service.ts b/src/rules/nodejs/service.ts index 44684353..a625ce0f 100644 --- a/src/rules/nodejs/service.ts +++ b/src/rules/nodejs/service.ts @@ -2,8 +2,8 @@ import path from 'node:path'; import type { FullVersion } from 'package-json'; +import { Payload } from '../../payload'; import type { BaseProvider, ProviderFile } from '../../provider/base'; -import type { RuleServiceReturn } from '../../types'; import { detectDependencies } from './dependencies'; @@ -12,7 +12,7 @@ const FILES = ['package.json']; export async function detectNodeService( files: ProviderFile[], provider: BaseProvider -): Promise { +): Promise { for (const file of files) { if (!FILES.includes(file.name)) { continue; @@ -36,15 +36,10 @@ export async function detectNodeService( const techs = detectDependencies(json); - return [ - { - name: json.name, - path: path.dirname(file.fp), - edges: [], - tech: null, - techs, - }, - ]; + const pl = new Payload(json.name, path.dirname(file.fp)); + pl.addTech([...techs]); + + return pl; } return false; diff --git a/src/types/index.ts b/src/types/index.ts index e8f0b111..77595f5e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -24,6 +24,10 @@ export interface Service { export type ServiceJson = Modify; export interface TechAnalyser { + name: string; + path: string; + tech: AllowedKeys | null; techs: AllowedKeys[]; services: ServiceJson[]; + languages: Record; } diff --git a/src/types/techs.ts b/src/types/techs.ts index 4d108306..e8d965eb 100644 --- a/src/types/techs.ts +++ b/src/types/techs.ts @@ -42,6 +42,7 @@ export type AllowedKeys = | 'httpd' | 'influxdb' | 'java' + | 'javascript' | 'jest' | 'jira' | 'koa' @@ -75,8 +76,10 @@ export type AllowedKeys = | 'redis' | 'ruby' | 'rust' + | 'scss' | 'sentry' | 'sequelize' + | 'shell' | 'slack' | 'socketio' | 'sqreen'