mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 21:11:30 +08:00 
			
		
		
		
	Add first draft (untested).
This commit is contained in:
		
							parent
							
								
									9a3d218c6e
								
							
						
					
					
						commit
						9422491a44
					
				| @ -9,7 +9,10 @@ | ||||
|     "build-watch": "npx tsc -w" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/node": "^11.10.5", | ||||
|     "@types/express": "^4.16.1", | ||||
|     "typescript": "^3.3.3333" | ||||
|   }, | ||||
|   "peerDependencies": { | ||||
|     "express": "^4.16.4" | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										105
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								src/index.ts
									
									
									
									
									
								
							| @ -1,2 +1,103 @@ | ||||
| import { Request } from "node"; | ||||
| export function handler(req: Request) {} | ||||
| import { Request, Response } from "express"; | ||||
| import { parseRangeHeader, RangeParserError, Range } from "./parseRangeHeader"; | ||||
| import { Stream } from "stream"; | ||||
| 
 | ||||
| /** | ||||
|  * @type {function (Request): Promise<Content>} | ||||
|  */ | ||||
| export type ContentProvider = (req: Request) => Promise<Content>; | ||||
| 
 | ||||
| export class ContentDoesNotExistError extends Error {} | ||||
| 
 | ||||
| export interface Logger { | ||||
|   debug(message: string, extra?: any): void; | ||||
| } | ||||
| 
 | ||||
| export type Content = { | ||||
|   /** | ||||
|    * Returns a readable stream based on the provided range (optional). | ||||
|    * @param {Range} range The start-end range of stream data. | ||||
|    * @returns {Stream} A readable stream | ||||
|    */ | ||||
|   getStream(range?: Range): Stream; | ||||
|   /** | ||||
|    * Total size of the content | ||||
|    */ | ||||
|   readonly totalSize: number; | ||||
|   /** | ||||
|    * Mime type to be sent in Content-Type header | ||||
|    */ | ||||
|   readonly mimeType: string; | ||||
|   /** | ||||
|    * File name to be sent in Content-Disposition header | ||||
|    */ | ||||
|   readonly fileName: string; | ||||
| }; | ||||
| 
 | ||||
| const getHeader = (name: string, req: Request) => req.headers[name]; | ||||
| const getRangeHeader = getHeader.bind(null, "range"); | ||||
| const setHeader = (name: string, value: string, res: Response) => res.setHeader(name, value); | ||||
| const setContentTypeHeader = setHeader.bind(null, "Content-Type"); | ||||
| const setContentLengthHeader = setHeader.bind(null, "Content-Length"); | ||||
| const setAcceptRangesHeader = setHeader.bind(null, "Accept-Ranges", "bytes"); | ||||
| const setContentRangeHeader = (range: Range | null, size: number, res: Response) => | ||||
|   setHeader("Content-Range", `bytes ${range ? `${range.start}-${range.end}` : "*"}/${size}`, res); | ||||
| const setContentDispositionHeader = (fileName: string, res: Response) => | ||||
|   setHeader("Content-Disposition", `attachment; filename="${fileName}"`, res); | ||||
| const setCacheControlHeaderNoCache = setHeader.bind(null, "Cache-Control", "no-cache"); | ||||
| 
 | ||||
| export function create(contentProvider: ContentProvider, logger: Logger) { | ||||
|   return async function handler(req: Request, res: Response) { | ||||
|     let content; | ||||
|     try { | ||||
|       content = await contentProvider(req); | ||||
|     } catch (error) { | ||||
|       logger.debug("ContentProvider threw exception: ", error); | ||||
|       if (error instanceof ContentDoesNotExistError) { | ||||
|         return res.status(400).send(error.message); | ||||
|       } | ||||
| 
 | ||||
|       return res.sendStatus(500); | ||||
|     } | ||||
| 
 | ||||
|     let { getStream, mimeType, fileName, totalSize } = content; | ||||
| 
 | ||||
|     const rangeHeader = getRangeHeader(req); | ||||
|     let range; | ||||
|     try { | ||||
|       range = parseRangeHeader(rangeHeader, totalSize); | ||||
|     } catch (error) { | ||||
|       logger.debug(`parseRangeHeader error: `, error); | ||||
|       if (error instanceof RangeParserError) { | ||||
|         setContentRangeHeader(null, totalSize, res); | ||||
| 
 | ||||
|         return res | ||||
|           .send(error.message) | ||||
|           .status(416) | ||||
|           .end(); | ||||
|       } | ||||
| 
 | ||||
|       return res.sendStatus(500); | ||||
|     } | ||||
| 
 | ||||
|     let { start, end } = range; | ||||
| 
 | ||||
|     setContentTypeHeader(mimeType, res); | ||||
|     setContentDispositionHeader(fileName, res); | ||||
|     setAcceptRangesHeader(res); | ||||
| 
 | ||||
|     // If range is not specified, or the file is empty, return the full stream
 | ||||
|     if (range === null) { | ||||
|       setContentLengthHeader(totalSize, res); | ||||
|       return getStream().pipe(res); | ||||
|     } | ||||
| 
 | ||||
|     setContentRangeHeader(range, totalSize, res); | ||||
|     setContentLengthHeader(start === end ? 0 : end - start + 1); | ||||
|     setCacheControlHeaderNoCache(res); | ||||
| 
 | ||||
|     // Return 206 Partial Content status
 | ||||
|     res.status(206); | ||||
|     getStream(range).pipe(res); | ||||
|   }; | ||||
| } | ||||
|  | ||||
							
								
								
									
										57
									
								
								src/parseRangeHeader.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/parseRangeHeader.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| export type Range = { | ||||
|   start: number; | ||||
|   end: number; | ||||
| }; | ||||
| 
 | ||||
| const rangeRegEx = /bytes=([0-9]*)-([0-9]*)/; | ||||
| 
 | ||||
| export class RangeParserError extends Error { | ||||
|   constructor(start: any, end: any) { | ||||
|     super(`Invalid start and end values: ${start}-${end}.`); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function parseRangeHeader(range: string, totalSize: number): Range | null { | ||||
|   // 1. If range is not specified or the file is empty, return null.
 | ||||
|   if (range === null || range.length === 0 || totalSize === 0) { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   const [startValue, endValue] = range.split(rangeRegEx); | ||||
|   let start = Number.parseInt(startValue); | ||||
|   let end = Number.parseInt(endValue); | ||||
| 
 | ||||
|   // 2. Parse start and end values and ensure they are within limits.
 | ||||
|   // 2.1. start: >= 0.
 | ||||
|   // 2.2. end: >= 0, <= totalSize - 1
 | ||||
| 
 | ||||
|   let result = { | ||||
|     start: Number.isNaN(start) ? 0 : Math.max(start, 0), | ||||
|     end: Number.isNaN(end) ? totalSize - 1 : Math.min(Math.max(end, 0), totalSize - 1) | ||||
|   }; | ||||
| 
 | ||||
|   // 3.1. If end is not provided, set end to the last byte (totalSize - 1).
 | ||||
|   if (!Number.isNaN(start) && Number.isNaN(end)) { | ||||
|     result.start = start; | ||||
|     result.end = totalSize - 1; | ||||
| 
 | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   // 3.2. If start is not provided, set it to the offset of last "end" bytes from the end of the file.
 | ||||
|   //      And set end to the last byte.
 | ||||
|   //      This way we return the last "end" bytes.
 | ||||
|   if (Number.isNaN(start) && !Number.isNaN(end)) { | ||||
|     result.start = totalSize - end; | ||||
|     result.end = totalSize - 1; | ||||
| 
 | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   // 4. Handle invalid ranges.
 | ||||
|   if (start > end) { | ||||
|     throw new RangeParserError(start, end); | ||||
|   } | ||||
| 
 | ||||
|   return result; | ||||
| } | ||||
| @ -1,21 +1,17 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|       "module": "commonjs", | ||||
|       "esModuleInterop": true, | ||||
|       "target": "es6", | ||||
|       "noImplicitAny": true, | ||||
|       "moduleResolution": "node", | ||||
|       "sourceMap": true, | ||||
|       "outDir": "dist", | ||||
|       "baseUrl": ".", | ||||
|       "paths": { | ||||
|           "*": [ | ||||
|               "node_modules/*", | ||||
|               "src/types/*" | ||||
|           ] | ||||
|       } | ||||
|     "module": "commonjs", | ||||
|     "esModuleInterop": true, | ||||
|     "target": "es6", | ||||
|     "noImplicitAny": true, | ||||
|     "moduleResolution": "node", | ||||
|     "sourceMap": true, | ||||
|     "outDir": "dist", | ||||
|     "declaration": true, | ||||
|     "baseUrl": "src", | ||||
|     "paths": { | ||||
|       "*": ["../node_modules/*", "./types/*"] | ||||
|     } | ||||
|   }, | ||||
|   "include": [ | ||||
|       "src/**/*" | ||||
|   ] | ||||
|   "include": ["src/**/*"] | ||||
| } | ||||
							
								
								
									
										393
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										393
									
								
								yarn.lock
									
									
									
									
									
								
							| @ -2,12 +2,403 @@ | ||||
| # yarn lockfile v1 | ||||
| 
 | ||||
| 
 | ||||
| "@types/node@^11.10.5": | ||||
| "@types/body-parser@*": | ||||
|   version "1.17.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" | ||||
|   integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w== | ||||
|   dependencies: | ||||
|     "@types/connect" "*" | ||||
|     "@types/node" "*" | ||||
| 
 | ||||
| "@types/connect@*": | ||||
|   version "3.4.32" | ||||
|   resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" | ||||
|   integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== | ||||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
| 
 | ||||
| "@types/express-serve-static-core@*": | ||||
|   version "4.16.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.1.tgz#35df7b302299a4ab138a643617bd44078e74d44e" | ||||
|   integrity sha512-QgbIMRU1EVRry5cIu1ORCQP4flSYqLM1lS5LYyGWfKnFT3E58f0gKto7BR13clBFVrVZ0G0rbLZ1hUpSkgQQOA== | ||||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
|     "@types/range-parser" "*" | ||||
| 
 | ||||
| "@types/express@^4.16.1": | ||||
|   version "4.16.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.1.tgz#d756bd1a85c34d87eaf44c888bad27ba8a4b7cf0" | ||||
|   integrity sha512-V0clmJow23WeyblmACoxbHBu2JKlE5TiIme6Lem14FnPW9gsttyHtk6wq7njcdIWH1njAaFgR8gW09lgY98gQg== | ||||
|   dependencies: | ||||
|     "@types/body-parser" "*" | ||||
|     "@types/express-serve-static-core" "*" | ||||
|     "@types/serve-static" "*" | ||||
| 
 | ||||
| "@types/mime@*": | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" | ||||
|   integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== | ||||
| 
 | ||||
| "@types/node@*": | ||||
|   version "11.10.5" | ||||
|   resolved "https://registry.yarnpkg.com/@types/node/-/node-11.10.5.tgz#fbaca34086bdc118011e1f05c47688d432f2d571" | ||||
|   integrity sha512-DuIRlQbX4K+d5I+GMnv+UfnGh+ist0RdlvOp+JZ7ePJ6KQONCFQv/gKYSU1ZzbVdFSUCKZOltjmpFAGGv5MdYA== | ||||
| 
 | ||||
| "@types/range-parser@*": | ||||
|   version "1.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" | ||||
|   integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== | ||||
| 
 | ||||
| "@types/serve-static@*": | ||||
|   version "1.13.2" | ||||
|   resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" | ||||
|   integrity sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q== | ||||
|   dependencies: | ||||
|     "@types/express-serve-static-core" "*" | ||||
|     "@types/mime" "*" | ||||
| 
 | ||||
| accepts@~1.3.5: | ||||
|   version "1.3.5" | ||||
|   resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" | ||||
|   integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= | ||||
|   dependencies: | ||||
|     mime-types "~2.1.18" | ||||
|     negotiator "0.6.1" | ||||
| 
 | ||||
| array-flatten@1.1.1: | ||||
|   version "1.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" | ||||
|   integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= | ||||
| 
 | ||||
| body-parser@1.18.3: | ||||
|   version "1.18.3" | ||||
|   resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" | ||||
|   integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= | ||||
|   dependencies: | ||||
|     bytes "3.0.0" | ||||
|     content-type "~1.0.4" | ||||
|     debug "2.6.9" | ||||
|     depd "~1.1.2" | ||||
|     http-errors "~1.6.3" | ||||
|     iconv-lite "0.4.23" | ||||
|     on-finished "~2.3.0" | ||||
|     qs "6.5.2" | ||||
|     raw-body "2.3.3" | ||||
|     type-is "~1.6.16" | ||||
| 
 | ||||
| bytes@3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" | ||||
|   integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= | ||||
| 
 | ||||
| content-disposition@0.5.2: | ||||
|   version "0.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" | ||||
|   integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= | ||||
| 
 | ||||
| content-type@~1.0.4: | ||||
|   version "1.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" | ||||
|   integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== | ||||
| 
 | ||||
| cookie-signature@1.0.6: | ||||
|   version "1.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" | ||||
|   integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= | ||||
| 
 | ||||
| cookie@0.3.1: | ||||
|   version "0.3.1" | ||||
|   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" | ||||
|   integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= | ||||
| 
 | ||||
| debug@2.6.9: | ||||
|   version "2.6.9" | ||||
|   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" | ||||
|   integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== | ||||
|   dependencies: | ||||
|     ms "2.0.0" | ||||
| 
 | ||||
| depd@~1.1.2: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" | ||||
|   integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= | ||||
| 
 | ||||
| destroy@~1.0.4: | ||||
|   version "1.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" | ||||
|   integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= | ||||
| 
 | ||||
| ee-first@1.1.1: | ||||
|   version "1.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" | ||||
|   integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= | ||||
| 
 | ||||
| encodeurl@~1.0.2: | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" | ||||
|   integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= | ||||
| 
 | ||||
| escape-html@~1.0.3: | ||||
|   version "1.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" | ||||
|   integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= | ||||
| 
 | ||||
| etag@~1.8.1: | ||||
|   version "1.8.1" | ||||
|   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" | ||||
|   integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= | ||||
| 
 | ||||
| express@^4.16.4: | ||||
|   version "4.16.4" | ||||
|   resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" | ||||
|   integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== | ||||
|   dependencies: | ||||
|     accepts "~1.3.5" | ||||
|     array-flatten "1.1.1" | ||||
|     body-parser "1.18.3" | ||||
|     content-disposition "0.5.2" | ||||
|     content-type "~1.0.4" | ||||
|     cookie "0.3.1" | ||||
|     cookie-signature "1.0.6" | ||||
|     debug "2.6.9" | ||||
|     depd "~1.1.2" | ||||
|     encodeurl "~1.0.2" | ||||
|     escape-html "~1.0.3" | ||||
|     etag "~1.8.1" | ||||
|     finalhandler "1.1.1" | ||||
|     fresh "0.5.2" | ||||
|     merge-descriptors "1.0.1" | ||||
|     methods "~1.1.2" | ||||
|     on-finished "~2.3.0" | ||||
|     parseurl "~1.3.2" | ||||
|     path-to-regexp "0.1.7" | ||||
|     proxy-addr "~2.0.4" | ||||
|     qs "6.5.2" | ||||
|     range-parser "~1.2.0" | ||||
|     safe-buffer "5.1.2" | ||||
|     send "0.16.2" | ||||
|     serve-static "1.13.2" | ||||
|     setprototypeof "1.1.0" | ||||
|     statuses "~1.4.0" | ||||
|     type-is "~1.6.16" | ||||
|     utils-merge "1.0.1" | ||||
|     vary "~1.1.2" | ||||
| 
 | ||||
| finalhandler@1.1.1: | ||||
|   version "1.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" | ||||
|   integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== | ||||
|   dependencies: | ||||
|     debug "2.6.9" | ||||
|     encodeurl "~1.0.2" | ||||
|     escape-html "~1.0.3" | ||||
|     on-finished "~2.3.0" | ||||
|     parseurl "~1.3.2" | ||||
|     statuses "~1.4.0" | ||||
|     unpipe "~1.0.0" | ||||
| 
 | ||||
| forwarded@~0.1.2: | ||||
|   version "0.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" | ||||
|   integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= | ||||
| 
 | ||||
| fresh@0.5.2: | ||||
|   version "0.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" | ||||
|   integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= | ||||
| 
 | ||||
| http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: | ||||
|   version "1.6.3" | ||||
|   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" | ||||
|   integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= | ||||
|   dependencies: | ||||
|     depd "~1.1.2" | ||||
|     inherits "2.0.3" | ||||
|     setprototypeof "1.1.0" | ||||
|     statuses ">= 1.4.0 < 2" | ||||
| 
 | ||||
| iconv-lite@0.4.23: | ||||
|   version "0.4.23" | ||||
|   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" | ||||
|   integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== | ||||
|   dependencies: | ||||
|     safer-buffer ">= 2.1.2 < 3" | ||||
| 
 | ||||
| inherits@2.0.3: | ||||
|   version "2.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" | ||||
|   integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= | ||||
| 
 | ||||
| ipaddr.js@1.8.0: | ||||
|   version "1.8.0" | ||||
|   resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" | ||||
|   integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= | ||||
| 
 | ||||
| media-typer@0.3.0: | ||||
|   version "0.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" | ||||
|   integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= | ||||
| 
 | ||||
| merge-descriptors@1.0.1: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" | ||||
|   integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= | ||||
| 
 | ||||
| methods@~1.1.2: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" | ||||
|   integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= | ||||
| 
 | ||||
| mime-db@~1.38.0: | ||||
|   version "1.38.0" | ||||
|   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" | ||||
|   integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== | ||||
| 
 | ||||
| mime-types@~2.1.18: | ||||
|   version "2.1.22" | ||||
|   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd" | ||||
|   integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog== | ||||
|   dependencies: | ||||
|     mime-db "~1.38.0" | ||||
| 
 | ||||
| mime@1.4.1: | ||||
|   version "1.4.1" | ||||
|   resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" | ||||
|   integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== | ||||
| 
 | ||||
| ms@2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" | ||||
|   integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= | ||||
| 
 | ||||
| negotiator@0.6.1: | ||||
|   version "0.6.1" | ||||
|   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" | ||||
|   integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= | ||||
| 
 | ||||
| on-finished@~2.3.0: | ||||
|   version "2.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" | ||||
|   integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= | ||||
|   dependencies: | ||||
|     ee-first "1.1.1" | ||||
| 
 | ||||
| parseurl@~1.3.2: | ||||
|   version "1.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" | ||||
|   integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= | ||||
| 
 | ||||
| path-to-regexp@0.1.7: | ||||
|   version "0.1.7" | ||||
|   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" | ||||
|   integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= | ||||
| 
 | ||||
| proxy-addr@~2.0.4: | ||||
|   version "2.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" | ||||
|   integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== | ||||
|   dependencies: | ||||
|     forwarded "~0.1.2" | ||||
|     ipaddr.js "1.8.0" | ||||
| 
 | ||||
| qs@6.5.2: | ||||
|   version "6.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" | ||||
|   integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== | ||||
| 
 | ||||
| range-parser@~1.2.0: | ||||
|   version "1.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" | ||||
|   integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= | ||||
| 
 | ||||
| raw-body@2.3.3: | ||||
|   version "2.3.3" | ||||
|   resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" | ||||
|   integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== | ||||
|   dependencies: | ||||
|     bytes "3.0.0" | ||||
|     http-errors "1.6.3" | ||||
|     iconv-lite "0.4.23" | ||||
|     unpipe "1.0.0" | ||||
| 
 | ||||
| safe-buffer@5.1.2: | ||||
|   version "5.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" | ||||
|   integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== | ||||
| 
 | ||||
| "safer-buffer@>= 2.1.2 < 3": | ||||
|   version "2.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" | ||||
|   integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== | ||||
| 
 | ||||
| send@0.16.2: | ||||
|   version "0.16.2" | ||||
|   resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" | ||||
|   integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== | ||||
|   dependencies: | ||||
|     debug "2.6.9" | ||||
|     depd "~1.1.2" | ||||
|     destroy "~1.0.4" | ||||
|     encodeurl "~1.0.2" | ||||
|     escape-html "~1.0.3" | ||||
|     etag "~1.8.1" | ||||
|     fresh "0.5.2" | ||||
|     http-errors "~1.6.2" | ||||
|     mime "1.4.1" | ||||
|     ms "2.0.0" | ||||
|     on-finished "~2.3.0" | ||||
|     range-parser "~1.2.0" | ||||
|     statuses "~1.4.0" | ||||
| 
 | ||||
| serve-static@1.13.2: | ||||
|   version "1.13.2" | ||||
|   resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" | ||||
|   integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== | ||||
|   dependencies: | ||||
|     encodeurl "~1.0.2" | ||||
|     escape-html "~1.0.3" | ||||
|     parseurl "~1.3.2" | ||||
|     send "0.16.2" | ||||
| 
 | ||||
| setprototypeof@1.1.0: | ||||
|   version "1.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" | ||||
|   integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== | ||||
| 
 | ||||
| "statuses@>= 1.4.0 < 2": | ||||
|   version "1.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" | ||||
|   integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= | ||||
| 
 | ||||
| statuses@~1.4.0: | ||||
|   version "1.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" | ||||
|   integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== | ||||
| 
 | ||||
| type-is@~1.6.16: | ||||
|   version "1.6.16" | ||||
|   resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" | ||||
|   integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== | ||||
|   dependencies: | ||||
|     media-typer "0.3.0" | ||||
|     mime-types "~2.1.18" | ||||
| 
 | ||||
| typescript@^3.3.3333: | ||||
|   version "3.3.3333" | ||||
|   resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.3333.tgz#171b2c5af66c59e9431199117a3bcadc66fdcfd6" | ||||
|   integrity sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw== | ||||
| 
 | ||||
| unpipe@1.0.0, unpipe@~1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" | ||||
|   integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= | ||||
| 
 | ||||
| utils-merge@1.0.1: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" | ||||
|   integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= | ||||
| 
 | ||||
| vary@~1.1.2: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" | ||||
|   integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SukantGujar
						SukantGujar