├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── index.js ├── lib └── public │ └── view-source-assets │ ├── explorer.js │ ├── file-text.svg │ ├── folder-plus.svg │ ├── folder.svg │ ├── prism.css │ └── prism.js ├── package.json ├── test └── server.js ├── view-source.png └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | node_modules 3 | *.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Krasimir Tsonev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | # view-source 4 | 5 | An Express.js add-on to render source code. Use it if you need to show source code of a project over the web. 6 | 7 | ## Usage 8 | 9 | Install it via `npm i view-source` (or `yarn add view-source`). Then the following: 10 | 11 | ```js 12 | const express = require('express'); 13 | const { viewSource } = require('view-source'); 14 | 15 | const app = express(); 16 | 17 | viewSource({ 18 | appTitle: 'My App Name', 19 | app, 20 | route: '/code', 21 | source: __dirname + '/../' 22 | }); 23 | ``` 24 | 25 | Where `route` is the path from which you'll access the viewer and `source` is the actual physical place where the files are located. 26 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const express = require('express'); 4 | 5 | const defaultAppTitle = 'App'; 6 | 7 | function viewSource({ app, route, source, appTitle }) { 8 | app.use(express.static(__dirname + '/lib/public', { maxAge: 604800000 })); 9 | app.use(path.join('/' + route, '@'), express.static(path.normalize(source), { maxAge: 604800000 })); 10 | 11 | const ROOT_DIR = path.normalize(source); 12 | 13 | function buildTree() { 14 | const root = { 15 | name: appTitle || defaultAppTitle, 16 | path: path.normalize(route), 17 | type: 'directory', 18 | children: [] 19 | }; 20 | 21 | function traverseDirectory(dirPath, parentNode) { 22 | const files = fs.readdirSync(dirPath); 23 | 24 | files.forEach(file => { 25 | const filePath = path.join(dirPath, file); 26 | const stats = fs.statSync(filePath); 27 | const node = { 28 | name: file, 29 | path: filePath.replace(ROOT_DIR, ''), 30 | type: stats.isDirectory() ? 'directory' : 'file', 31 | children: [] 32 | }; 33 | 34 | if (stats.isDirectory()) { 35 | traverseDirectory(filePath, node); 36 | } 37 | 38 | parentNode.children.push(node); 39 | }); 40 | } 41 | 42 | traverseDirectory(ROOT_DIR, root); 43 | 44 | return root; 45 | } 46 | 47 | const content = buildTree(route, path.normalize(source)); 48 | 49 | app.get(route, (req, res) => { 50 | res.setHeader("Content-Type", "text/html"); 51 | res.send(page( 52 | ` 53 | 58 | 59 | `, 60 | ` 61 |
${encodeHTMLTags(code)}
30 | `;
31 | setTimeout(() => Prism.highlightAll(), 10);
32 | }
33 | function renderPath(text) {
34 | document.querySelector('#path').innerHTML = '⇢ ' + text;
35 | }
36 | function findItem(treeItem, itemPath) {
37 | if (treeItem.path === itemPath) {
38 | return treeItem;
39 | } else {
40 | for (let i = 0; i < (treeItem.children || []).length; i++) {
41 | const item = findItem(treeItem.children[i], itemPath);
42 | if (item) {
43 | return item;
44 | }
45 | }
46 | }
47 | }
48 | function encodeHTMLTags(code) {
49 | return code.replace(//g, '>');
50 | }
51 | window.changeOpenFlag = (itemPath, value) => {
52 | const item = findItem(tree, itemPath);
53 | if (item) {
54 | item.open = value;
55 | } else {
56 | console.error(`Item ${itemPath} not found!`);
57 | }
58 | renderTree();
59 | }
60 | window.openFile = async (itemPath) => {
61 | const ext = itemPath.split('.').pop().toLowerCase();
62 | renderPath(itemPath);
63 | renderCode(`Loading ${itemPath} ...`, ext);
64 | const res = await fetch((ROUTE + itemPath).replace(/\/\//g, '/'));
65 | const code = await res.text();
66 | renderCode(code, ext);
67 | }
68 |
69 | tree.open = true;
70 | renderTree();
71 | renderCode(`// ${NAME} project`)
72 | });
--------------------------------------------------------------------------------
/lib/public/view-source-assets/file-text.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/public/view-source-assets/folder-plus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/public/view-source-assets/folder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/public/view-source-assets/prism.css:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.29.0
2 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+armasm+arturo+asciidoc+aspnet+asm6502+asmatmel+autohotkey+autoit+avisynth+avro-idl+awk+bash+basic+batch+bbcode+bbj+bicep+birb+bison+bnf+bqn+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+cilkc+cilkcpp+clojure+cmake+cobol+coffeescript+concurnas+csp+cooklang+coq+crystal+css-extras+csv+cue+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gap+gcode+gdscript+gedcom+gettext+gherkin+git+glsl+gn+linker-script+go+go-module+gradle+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+hoon+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keepalived+keyman+kotlin+kumir+kusto+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+magma+makefile+markdown+markup-templating+mata+matlab+maxscript+mel+mermaid+metafont+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+odin+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plant-uml+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+cshtml+jsx+tsx+reason+regex+rego+renpy+rescript+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+stata+iecst+stylus+supercollider+swift+systemd+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+tremor+turtle+twig+typescript+typoscript+unrealscript+uorazor+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+web-idl+wgsl+wiki+wolfram+wren+xeora+xml-doc+xojo+xquery+yaml+yang+zig */
3 | code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "view-source",
3 | "version": "0.3.2",
4 | "description": "An Express.js middleware/handler to render source code",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "node ./test/server.js"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/krasimir/view-source.git"
12 | },
13 | "keywords": [
14 | "express",
15 | "view",
16 | "source"
17 | ],
18 | "author": "Krasimir Tsonev",
19 | "license": "MIT",
20 | "bugs": {
21 | "url": "https://github.com/krasimir/view-source/issues"
22 | },
23 | "homepage": "https://github.com/krasimir/view-source#readme",
24 | "dependencies": {
25 | "express": "4.18.2"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const { viewSource } = require('../index');
3 |
4 | const app = express();
5 |
6 | viewSource({
7 | app,
8 | route: '/code',
9 | source: __dirname + '/../'
10 | });
11 |
12 | app.get('*', (req, res) => {
13 | res.send('view-source');
14 | });
15 |
16 | const port = process.env.PORT || 8080;
17 | app.listen(port, () => {
18 | console.log(`Listening on port ${port}`);
19 | });
--------------------------------------------------------------------------------
/view-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krasimir/view-source/1716c357f6b1e5b6fc7b249fd2a1abe93548d66a/view-source.png
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | accepts@~1.3.8:
6 | version "1.3.8"
7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
8 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
9 | dependencies:
10 | mime-types "~2.1.34"
11 | negotiator "0.6.3"
12 |
13 | array-flatten@1.1.1:
14 | version "1.1.1"
15 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
16 | integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
17 |
18 | body-parser@1.20.1:
19 | version "1.20.1"
20 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
21 | integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
22 | dependencies:
23 | bytes "3.1.2"
24 | content-type "~1.0.4"
25 | debug "2.6.9"
26 | depd "2.0.0"
27 | destroy "1.2.0"
28 | http-errors "2.0.0"
29 | iconv-lite "0.4.24"
30 | on-finished "2.4.1"
31 | qs "6.11.0"
32 | raw-body "2.5.1"
33 | type-is "~1.6.18"
34 | unpipe "1.0.0"
35 |
36 | bytes@3.1.2:
37 | version "3.1.2"
38 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
39 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
40 |
41 | call-bind@^1.0.0:
42 | version "1.0.2"
43 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
44 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
45 | dependencies:
46 | function-bind "^1.1.1"
47 | get-intrinsic "^1.0.2"
48 |
49 | content-disposition@0.5.4:
50 | version "0.5.4"
51 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
52 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
53 | dependencies:
54 | safe-buffer "5.2.1"
55 |
56 | content-type@~1.0.4:
57 | version "1.0.5"
58 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
59 | integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
60 |
61 | cookie-signature@1.0.6:
62 | version "1.0.6"
63 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
64 | integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
65 |
66 | cookie@0.5.0:
67 | version "0.5.0"
68 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
69 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
70 |
71 | debug@2.6.9:
72 | version "2.6.9"
73 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
74 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
75 | dependencies:
76 | ms "2.0.0"
77 |
78 | depd@2.0.0:
79 | version "2.0.0"
80 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
81 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
82 |
83 | destroy@1.2.0:
84 | version "1.2.0"
85 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
86 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
87 |
88 | ee-first@1.1.1:
89 | version "1.1.1"
90 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
91 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
92 |
93 | encodeurl@~1.0.2:
94 | version "1.0.2"
95 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
96 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
97 |
98 | escape-html@~1.0.3:
99 | version "1.0.3"
100 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
101 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
102 |
103 | etag@~1.8.1:
104 | version "1.8.1"
105 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
106 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
107 |
108 | express@4.18.2:
109 | version "4.18.2"
110 | resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
111 | integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
112 | dependencies:
113 | accepts "~1.3.8"
114 | array-flatten "1.1.1"
115 | body-parser "1.20.1"
116 | content-disposition "0.5.4"
117 | content-type "~1.0.4"
118 | cookie "0.5.0"
119 | cookie-signature "1.0.6"
120 | debug "2.6.9"
121 | depd "2.0.0"
122 | encodeurl "~1.0.2"
123 | escape-html "~1.0.3"
124 | etag "~1.8.1"
125 | finalhandler "1.2.0"
126 | fresh "0.5.2"
127 | http-errors "2.0.0"
128 | merge-descriptors "1.0.1"
129 | methods "~1.1.2"
130 | on-finished "2.4.1"
131 | parseurl "~1.3.3"
132 | path-to-regexp "0.1.7"
133 | proxy-addr "~2.0.7"
134 | qs "6.11.0"
135 | range-parser "~1.2.1"
136 | safe-buffer "5.2.1"
137 | send "0.18.0"
138 | serve-static "1.15.0"
139 | setprototypeof "1.2.0"
140 | statuses "2.0.1"
141 | type-is "~1.6.18"
142 | utils-merge "1.0.1"
143 | vary "~1.1.2"
144 |
145 | finalhandler@1.2.0:
146 | version "1.2.0"
147 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
148 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
149 | dependencies:
150 | debug "2.6.9"
151 | encodeurl "~1.0.2"
152 | escape-html "~1.0.3"
153 | on-finished "2.4.1"
154 | parseurl "~1.3.3"
155 | statuses "2.0.1"
156 | unpipe "~1.0.0"
157 |
158 | forwarded@0.2.0:
159 | version "0.2.0"
160 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
161 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
162 |
163 | fresh@0.5.2:
164 | version "0.5.2"
165 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
166 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
167 |
168 | function-bind@^1.1.1:
169 | version "1.1.1"
170 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
171 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
172 |
173 | get-intrinsic@^1.0.2:
174 | version "1.2.1"
175 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82"
176 | integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==
177 | dependencies:
178 | function-bind "^1.1.1"
179 | has "^1.0.3"
180 | has-proto "^1.0.1"
181 | has-symbols "^1.0.3"
182 |
183 | has-proto@^1.0.1:
184 | version "1.0.1"
185 | resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
186 | integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
187 |
188 | has-symbols@^1.0.3:
189 | version "1.0.3"
190 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
191 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
192 |
193 | has@^1.0.3:
194 | version "1.0.3"
195 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
196 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
197 | dependencies:
198 | function-bind "^1.1.1"
199 |
200 | http-errors@2.0.0:
201 | version "2.0.0"
202 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
203 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
204 | dependencies:
205 | depd "2.0.0"
206 | inherits "2.0.4"
207 | setprototypeof "1.2.0"
208 | statuses "2.0.1"
209 | toidentifier "1.0.1"
210 |
211 | iconv-lite@0.4.24:
212 | version "0.4.24"
213 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
214 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
215 | dependencies:
216 | safer-buffer ">= 2.1.2 < 3"
217 |
218 | inherits@2.0.4:
219 | version "2.0.4"
220 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
221 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
222 |
223 | ipaddr.js@1.9.1:
224 | version "1.9.1"
225 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
226 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
227 |
228 | media-typer@0.3.0:
229 | version "0.3.0"
230 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
231 | integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
232 |
233 | merge-descriptors@1.0.1:
234 | version "1.0.1"
235 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
236 | integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
237 |
238 | methods@~1.1.2:
239 | version "1.1.2"
240 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
241 | integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
242 |
243 | mime-db@1.52.0:
244 | version "1.52.0"
245 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
246 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
247 |
248 | mime-types@~2.1.24, mime-types@~2.1.34:
249 | version "2.1.35"
250 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
251 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
252 | dependencies:
253 | mime-db "1.52.0"
254 |
255 | mime@1.6.0:
256 | version "1.6.0"
257 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
258 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
259 |
260 | ms@2.0.0:
261 | version "2.0.0"
262 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
263 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
264 |
265 | ms@2.1.3:
266 | version "2.1.3"
267 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
268 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
269 |
270 | negotiator@0.6.3:
271 | version "0.6.3"
272 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
273 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
274 |
275 | object-inspect@^1.9.0:
276 | version "1.12.3"
277 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9"
278 | integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
279 |
280 | on-finished@2.4.1:
281 | version "2.4.1"
282 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
283 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
284 | dependencies:
285 | ee-first "1.1.1"
286 |
287 | parseurl@~1.3.3:
288 | version "1.3.3"
289 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
290 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
291 |
292 | path-to-regexp@0.1.7:
293 | version "0.1.7"
294 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
295 | integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
296 |
297 | proxy-addr@~2.0.7:
298 | version "2.0.7"
299 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
300 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
301 | dependencies:
302 | forwarded "0.2.0"
303 | ipaddr.js "1.9.1"
304 |
305 | qs@6.11.0:
306 | version "6.11.0"
307 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
308 | integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
309 | dependencies:
310 | side-channel "^1.0.4"
311 |
312 | range-parser@~1.2.1:
313 | version "1.2.1"
314 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
315 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
316 |
317 | raw-body@2.5.1:
318 | version "2.5.1"
319 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
320 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
321 | dependencies:
322 | bytes "3.1.2"
323 | http-errors "2.0.0"
324 | iconv-lite "0.4.24"
325 | unpipe "1.0.0"
326 |
327 | safe-buffer@5.2.1:
328 | version "5.2.1"
329 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
330 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
331 |
332 | "safer-buffer@>= 2.1.2 < 3":
333 | version "2.1.2"
334 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
335 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
336 |
337 | send@0.18.0:
338 | version "0.18.0"
339 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
340 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
341 | dependencies:
342 | debug "2.6.9"
343 | depd "2.0.0"
344 | destroy "1.2.0"
345 | encodeurl "~1.0.2"
346 | escape-html "~1.0.3"
347 | etag "~1.8.1"
348 | fresh "0.5.2"
349 | http-errors "2.0.0"
350 | mime "1.6.0"
351 | ms "2.1.3"
352 | on-finished "2.4.1"
353 | range-parser "~1.2.1"
354 | statuses "2.0.1"
355 |
356 | serve-static@1.15.0:
357 | version "1.15.0"
358 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
359 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
360 | dependencies:
361 | encodeurl "~1.0.2"
362 | escape-html "~1.0.3"
363 | parseurl "~1.3.3"
364 | send "0.18.0"
365 |
366 | setprototypeof@1.2.0:
367 | version "1.2.0"
368 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
369 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
370 |
371 | side-channel@^1.0.4:
372 | version "1.0.4"
373 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
374 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
375 | dependencies:
376 | call-bind "^1.0.0"
377 | get-intrinsic "^1.0.2"
378 | object-inspect "^1.9.0"
379 |
380 | statuses@2.0.1:
381 | version "2.0.1"
382 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
383 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
384 |
385 | toidentifier@1.0.1:
386 | version "1.0.1"
387 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
388 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
389 |
390 | type-is@~1.6.18:
391 | version "1.6.18"
392 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
393 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
394 | dependencies:
395 | media-typer "0.3.0"
396 | mime-types "~2.1.24"
397 |
398 | unpipe@1.0.0, unpipe@~1.0.0:
399 | version "1.0.0"
400 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
401 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
402 |
403 | utils-merge@1.0.1:
404 | version "1.0.1"
405 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
406 | integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
407 |
408 | vary@~1.1.2:
409 | version "1.1.2"
410 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
411 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
412 |
--------------------------------------------------------------------------------