File manager - Edit - /home2/zetasolve/speedfood.zetasolve.agency/wp-admin/node_modules.zip
Back
PK ���\��b� env-paths/index.d.tsnu �[��� declare namespace envPaths { export interface Options { /** __Don't use this option unless you really have to!__ Suffix appended to the project name to avoid name conflicts with native apps. Pass an empty string to disable it. @default 'nodejs' */ readonly suffix?: string; } export interface Paths { /** Directory for data files. Example locations (with the default `nodejs` suffix): - macOS: `~/Library/Application Support/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Data` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Data`) - Linux: `~/.local/share/MyApp-nodejs` (or `$XDG_DATA_HOME/MyApp-nodejs`) */ readonly data: string; /** Directory for data files. Example locations (with the default `nodejs` suffix): - macOS: `~/Library/Preferences/MyApp-nodejs` - Windows: `%APPDATA%\MyApp-nodejs\Config` (for example, `C:\Users\USERNAME\AppData\Roaming\MyApp-nodejs\Config`) - Linux: `~/.config/MyApp-nodejs` (or `$XDG_CONFIG_HOME/MyApp-nodejs`) */ readonly config: string; /** Directory for non-essential data files. Example locations (with the default `nodejs` suffix): - macOS: `~/Library/Caches/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Cache` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Cache`) - Linux: `~/.cache/MyApp-nodejs` (or `$XDG_CACHE_HOME/MyApp-nodejs`) */ readonly cache: string; /** Directory for log files. Example locations (with the default `nodejs` suffix): - macOS: `~/Library/Logs/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Log` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Log`) - Linux: `~/.local/state/MyApp-nodejs` (or `$XDG_STATE_HOME/MyApp-nodejs`) */ readonly log: string; /** Directory for temporary files. Example locations (with the default `nodejs` suffix): - macOS: `/var/folders/jf/f2twvvvs5jl_m49tf034ffpw0000gn/T/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\Temp\MyApp-nodejs` (for example, `C:\Users\USERNAME\AppData\Local\Temp\MyApp-nodejs`) - Linux: `/tmp/USERNAME/MyApp-nodejs` */ readonly temp: string; } } declare const envPaths: { /** Get paths for storing things like data, config, cache, etc. Note: It only generates the path strings. It doesn't create the directories for you. You could use [`make-dir`](https://github.com/sindresorhus/make-dir) to create the directories. @param name - Name of your project. Used to generate the paths. @returns The paths to use for your project on current OS. @example ``` import envPaths = require('env-paths'); const paths = envPaths('MyApp'); paths.data; //=> '/home/sindresorhus/.local/share/MyApp-nodejs' paths.config //=> '/home/sindresorhus/.config/MyApp-nodejs' ``` */ (name: string, options?: envPaths.Options): envPaths.Paths; // TODO: Remove this for the next major release, refactor the whole definition to: // declare function envPaths(name: string, options?: envPaths.Options): envPaths.Paths; // export = envPaths; default: typeof envPaths; }; export = envPaths; PK ���\s��7 7 env-paths/readme.mdnu �[��� # env-paths > Get paths for storing things like data, config, cache, etc Uses the correct OS-specific paths. Most developers get this wrong. ## Install ``` $ npm install env-paths ``` ## Usage ```js const envPaths = require('env-paths'); const paths = envPaths('MyApp'); paths.data; //=> '/home/sindresorhus/.local/share/MyApp-nodejs' paths.config //=> '/home/sindresorhus/.config/MyApp-nodejs' ``` ## API ### paths = envPaths(name, options?) Note: It only generates the path strings. It doesn't create the directories for you. You could use [`make-dir`](https://github.com/sindresorhus/make-dir) to create the directories. #### name Type: `string` Name of your project. Used to generate the paths. #### options Type: `object` ##### suffix Type: `string`<br> Default: `'nodejs'` **Don't use this option unless you really have to!**<br> Suffix appended to the project name to avoid name conflicts with native apps. Pass an empty string to disable it. ### paths.data Directory for data files. Example locations (with the default `nodejs` [suffix](#suffix)): - macOS: `~/Library/Application Support/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Data` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Data`) - Linux: `~/.local/share/MyApp-nodejs` (or `$XDG_DATA_HOME/MyApp-nodejs`) ### paths.config Directory for config files. Example locations (with the default `nodejs` [suffix](#suffix)): - macOS: `~/Library/Preferences/MyApp-nodejs` - Windows: `%APPDATA%\MyApp-nodejs\Config` (for example, `C:\Users\USERNAME\AppData\Roaming\MyApp-nodejs\Config`) - Linux: `~/.config/MyApp-nodejs` (or `$XDG_CONFIG_HOME/MyApp-nodejs`) ### paths.cache Directory for non-essential data files. Example locations (with the default `nodejs` [suffix](#suffix)): - macOS: `~/Library/Caches/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Cache` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Cache`) - Linux: `~/.cache/MyApp-nodejs` (or `$XDG_CACHE_HOME/MyApp-nodejs`) ### paths.log Directory for log files. Example locations (with the default `nodejs` [suffix](#suffix)): - macOS: `~/Library/Logs/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Log` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Log`) - Linux: `~/.local/state/MyApp-nodejs` (or `$XDG_STATE_HOME/MyApp-nodejs`) ### paths.temp Directory for temporary files. Example locations (with the default `nodejs` [suffix](#suffix)): - macOS: `/var/folders/jf/f2twvvvs5jl_m49tf034ffpw0000gn/T/MyApp-nodejs` - Windows: `%LOCALAPPDATA%\Temp\MyApp-nodejs` (for example, `C:\Users\USERNAME\AppData\Local\Temp\MyApp-nodejs`) - Linux: `/tmp/USERNAME/MyApp-nodejs` --- <div align="center"> <b> <a href="https://tidelift.com/subscription/pkg/npm-env-paths?utm_source=npm-env-paths&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> </b> <br> <sub> Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. </sub> </div> PK ���\�E�}U U env-paths/licensenu �[��� MIT License Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK ���\%� � env-paths/package.jsonnu �[��� { "name": "env-paths", "version": "2.2.1", "description": "Get paths for storing things like data, config, cache, etc", "license": "MIT", "repository": "sindresorhus/env-paths", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", "url": "sindresorhus.com" }, "engines": { "node": ">=6" }, "scripts": { "test": "xo && ava && tsd" }, "files": [ "index.js", "index.d.ts" ], "keywords": [ "common", "user", "paths", "env", "environment", "directory", "dir", "appdir", "path", "data", "config", "cache", "logs", "temp", "linux", "unix" ], "devDependencies": { "ava": "^1.4.1", "tsd": "^0.7.1", "xo": "^0.24.0" } } PK ���\�z74k k env-paths/index.jsnu �[��� 'use strict'; const path = require('path'); const os = require('os'); const homedir = os.homedir(); const tmpdir = os.tmpdir(); const {env} = process; const macos = name => { const library = path.join(homedir, 'Library'); return { data: path.join(library, 'Application Support', name), config: path.join(library, 'Preferences', name), cache: path.join(library, 'Caches', name), log: path.join(library, 'Logs', name), temp: path.join(tmpdir, name) }; }; const windows = name => { const appData = env.APPDATA || path.join(homedir, 'AppData', 'Roaming'); const localAppData = env.LOCALAPPDATA || path.join(homedir, 'AppData', 'Local'); return { // Data/config/cache/log are invented by me as Windows isn't opinionated about this data: path.join(localAppData, name, 'Data'), config: path.join(appData, name, 'Config'), cache: path.join(localAppData, name, 'Cache'), log: path.join(localAppData, name, 'Log'), temp: path.join(tmpdir, name) }; }; // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html const linux = name => { const username = path.basename(homedir); return { data: path.join(env.XDG_DATA_HOME || path.join(homedir, '.local', 'share'), name), config: path.join(env.XDG_CONFIG_HOME || path.join(homedir, '.config'), name), cache: path.join(env.XDG_CACHE_HOME || path.join(homedir, '.cache'), name), // https://wiki.debian.org/XDGBaseDirectorySpecification#state log: path.join(env.XDG_STATE_HOME || path.join(homedir, '.local', 'state'), name), temp: path.join(tmpdir, username, name) }; }; const envPaths = (name, options) => { if (typeof name !== 'string') { throw new TypeError(`Expected string, got ${typeof name}`); } options = Object.assign({suffix: 'nodejs'}, options); if (options.suffix) { // Add suffix to prevent possible conflict with native apps name += `-${options.suffix}`; } if (process.platform === 'darwin') { return macos(name); } if (process.platform === 'win32') { return windows(name); } return linux(name); }; module.exports = envPaths; // TODO: Remove this for the next major release module.exports.default = envPaths; PK ���\�3[�� � 0 https-proxy-agent/dist/parse-proxy-response.d.tsnu �[��� /// <reference types="node" /> import { Readable } from 'stream'; export interface ProxyResponse { statusCode: number; buffered: Buffer; } export default function parseProxyResponse(socket: Readable): Promise<ProxyResponse>; PK ���\���f f ! https-proxy-agent/dist/agent.d.tsnu �[��� /// <reference types="node" /> import net from 'net'; import { Agent, ClientRequest, RequestOptions } from 'agent-base'; import { HttpsProxyAgentOptions } from '.'; /** * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. * * Outgoing HTTP requests are first tunneled through the proxy server using the * `CONNECT` HTTP request method to establish a connection to the proxy server, * and then the proxy server connects to the destination target and issues the * HTTP request from the proxy server. * * `https:` requests have their socket connection upgraded to TLS once * the connection to the proxy server has been established. * * @api public */ export default class HttpsProxyAgent extends Agent { private secureProxy; private proxy; constructor(_opts: string | HttpsProxyAgentOptions); /** * Called when the node-core HTTP client library is creating a * new HTTP request. * * @api protected */ callback(req: ClientRequest, opts: RequestOptions): Promise<net.Socket>; } PK ���\D^�p p 2 https-proxy-agent/dist/parse-proxy-response.js.mapnu �[��� {"version":3,"file":"parse-proxy-response.js","sourceRoot":"","sources":["../src/parse-proxy-response.ts"],"names":[],"mappings":";;;;;AAAA,kDAAgC;AAGhC,MAAM,KAAK,GAAG,eAAW,CAAC,wCAAwC,CAAC,CAAC;AAOpE,SAAwB,kBAAkB,CACzC,MAAgB;IAEhB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,+EAA+E;QAC/E,gFAAgF;QAChF,8EAA8E;QAC9E,8BAA8B;QAC9B,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,SAAS,IAAI;YACZ,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC;gBAAE,MAAM,CAAC,CAAC,CAAC,CAAC;;gBACZ,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QAED,SAAS,OAAO;YACf,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,SAAS,OAAO,CAAC,GAAW;YAC3B,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;QACpC,CAAC;QAED,SAAS,KAAK;YACb,KAAK,CAAC,OAAO,CAAC,CAAC;QAChB,CAAC;QAED,SAAS,OAAO,CAAC,GAAU;YAC1B,OAAO,EAAE,CAAC;YACV,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC;QACb,CAAC;QAED,SAAS,MAAM,CAAC,CAAS;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,aAAa,IAAI,CAAC,CAAC,MAAM,CAAC;YAE1B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACvD,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAElD,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE;gBACxB,iBAAiB;gBACjB,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBACtD,IAAI,EAAE,CAAC;gBACP,OAAO;aACP;YAED,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAClC,OAAO,EACP,CAAC,EACD,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CACxB,CAAC;YACF,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,KAAK,CAAC,+BAA+B,EAAE,SAAS,CAAC,CAAC;YAClD,OAAO,CAAC;gBACP,UAAU;gBACV,QAAQ;aACR,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAExB,IAAI,EAAE,CAAC;IACR,CAAC,CAAC,CAAC;AACJ,CAAC;AAvED,qCAuEC"}PK ���\^|�C� � ! https-proxy-agent/dist/index.d.tsnu �[��� /// <reference types="node" /> import net from 'net'; import tls from 'tls'; import { Url } from 'url'; import { AgentOptions } from 'agent-base'; import { OutgoingHttpHeaders } from 'http'; import _HttpsProxyAgent from './agent'; declare function createHttpsProxyAgent(opts: string | createHttpsProxyAgent.HttpsProxyAgentOptions): _HttpsProxyAgent; declare namespace createHttpsProxyAgent { interface BaseHttpsProxyAgentOptions { headers?: OutgoingHttpHeaders; secureProxy?: boolean; host?: string | null; path?: string | null; port?: string | number | null; } export interface HttpsProxyAgentOptions extends AgentOptions, BaseHttpsProxyAgentOptions, Partial<Omit<Url & net.NetConnectOpts & tls.ConnectionOptions, keyof BaseHttpsProxyAgentOptions>> { } export type HttpsProxyAgent = _HttpsProxyAgent; export const HttpsProxyAgent: typeof _HttpsProxyAgent; export {}; } export = createHttpsProxyAgent; PK ���\�{�j j # https-proxy-agent/dist/index.js.mapnu �[��� {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAKA,oDAAuC;AAEvC,SAAS,qBAAqB,CAC7B,IAA2D;IAE3D,OAAO,IAAI,eAAgB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,WAAU,qBAAqB;IAoBjB,qCAAe,GAAG,eAAgB,CAAC;IAEhD,qBAAqB,CAAC,SAAS,GAAG,eAAgB,CAAC,SAAS,CAAC;AAC9D,CAAC,EAvBS,qBAAqB,KAArB,qBAAqB,QAuB9B;AAED,iBAAS,qBAAqB,CAAC"}PK ���\��}9� � . https-proxy-agent/dist/parse-proxy-response.jsnu �[��� "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const debug = debug_1.default('https-proxy-agent:parse-proxy-response'); function parseProxyResponse(socket) { return new Promise((resolve, reject) => { // we need to buffer any HTTP traffic that happens with the proxy before we get // the CONNECT response, so that if the response is anything other than an "200" // response code, then we can re-play the "data" events on the socket once the // HTTP parser is hooked up... let buffersLength = 0; const buffers = []; function read() { const b = socket.read(); if (b) ondata(b); else socket.once('readable', read); } function cleanup() { socket.removeListener('end', onend); socket.removeListener('error', onerror); socket.removeListener('close', onclose); socket.removeListener('readable', read); } function onclose(err) { debug('onclose had error %o', err); } function onend() { debug('onend'); } function onerror(err) { cleanup(); debug('onerror %o', err); reject(err); } function ondata(b) { buffers.push(b); buffersLength += b.length; const buffered = Buffer.concat(buffers, buffersLength); const endOfHeaders = buffered.indexOf('\r\n\r\n'); if (endOfHeaders === -1) { // keep buffering debug('have not received end of HTTP headers yet...'); read(); return; } const firstLine = buffered.toString('ascii', 0, buffered.indexOf('\r\n')); const statusCode = +firstLine.split(' ')[1]; debug('got proxy server response: %o', firstLine); resolve({ statusCode, buffered }); } socket.on('error', onerror); socket.on('close', onclose); socket.on('end', onend); read(); }); } exports.default = parseProxyResponse; //# sourceMappingURL=parse-proxy-response.js.mapPK ���\��� # https-proxy-agent/dist/agent.js.mapnu �[��� {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,8CAAsB;AACtB,8CAAsB;AACtB,8CAAsB;AACtB,oDAA4B;AAC5B,kDAAgC;AAEhC,2CAAkE;AAElE,kFAAwD;AAExD,MAAM,KAAK,GAAG,eAAW,CAAC,yBAAyB,CAAC,CAAC;AAErD;;;;;;;;;;;;;GAaG;AACH,MAAqB,eAAgB,SAAQ,kBAAK;IAIjD,YAAY,KAAsC;QACjD,IAAI,IAA4B,CAAC;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC9B,IAAI,GAAG,aAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SACxB;aAAM;YACN,IAAI,GAAG,KAAK,CAAC;SACb;QACD,IAAI,CAAC,IAAI,EAAE;YACV,MAAM,IAAI,KAAK,CACd,8DAA8D,CAC9D,CAAC;SACF;QACD,KAAK,CAAC,2CAA2C,EAAE,IAAI,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,CAAC;QAEZ,MAAM,KAAK,qBAAgC,IAAI,CAAE,CAAC;QAElD,wDAAwD;QACxD,uBAAuB;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE/D,+DAA+D;QAC/D,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC;QAC1C,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;YACnC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;SACtC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;YAC9B,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;SACzC;QAED,sCAAsC;QACtC,sEAAsE;QACtE,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,eAAe,IAAI,KAAK,CAAC,EAAE;YACpD,KAAK,CAAC,aAAa,GAAG,CAAC,UAAU,CAAC,CAAC;SACnC;QAED,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;YAC7B,kEAAkE;YAClE,8DAA8D;YAC9D,iEAAiE;YACjE,8BAA8B;YAC9B,OAAO,KAAK,CAAC,IAAI,CAAC;YAClB,OAAO,KAAK,CAAC,QAAQ,CAAC;SACtB;QAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACG,QAAQ,CACb,GAAkB,EAClB,IAAoB;;YAEpB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;YAEpC,kDAAkD;YAClD,IAAI,MAAkB,CAAC;YACvB,IAAI,WAAW,EAAE;gBAChB,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;gBAC1C,MAAM,GAAG,aAAG,CAAC,OAAO,CAAC,KAA8B,CAAC,CAAC;aACrD;iBAAM;gBACN,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;gBAC1C,MAAM,GAAG,aAAG,CAAC,OAAO,CAAC,KAA2B,CAAC,CAAC;aAClD;YAED,MAAM,OAAO,qBAA6B,KAAK,CAAC,OAAO,CAAE,CAAC;YAC1D,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7C,IAAI,OAAO,GAAG,WAAW,QAAQ,eAAe,CAAC;YAEjD,wDAAwD;YACxD,IAAI,KAAK,CAAC,IAAI,EAAE;gBACf,OAAO,CAAC,qBAAqB,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACpD,KAAK,CAAC,IAAI,CACV,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;aACvB;YAED,iDAAiD;YACjD,0CAA0C;YAC1C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;YAC1C,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE;gBACzC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;aACnB;YACD,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YAEpB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;YAC7B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBACxC,OAAO,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;aAC3C;YAED,MAAM,oBAAoB,GAAG,8BAAkB,CAAC,MAAM,CAAC,CAAC;YAExD,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC;YAE/B,MAAM,EACL,UAAU,EACV,QAAQ,EACR,GAAG,MAAM,oBAAoB,CAAC;YAE/B,IAAI,UAAU,KAAK,GAAG,EAAE;gBACvB,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAE3B,IAAI,IAAI,CAAC,cAAc,EAAE;oBACxB,sDAAsD;oBACtD,8CAA8C;oBAC9C,KAAK,CAAC,oCAAoC,CAAC,CAAC;oBAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC;oBAChD,OAAO,aAAG,CAAC,OAAO,iCACd,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,KACjD,MAAM;wBACN,UAAU,IACT,CAAC;iBACH;gBAED,OAAO,MAAM,CAAC;aACd;YAED,oEAAoE;YACpE,kEAAkE;YAClE,iEAAiE;YACjE,qBAAqB;YAErB,iEAAiE;YACjE,0DAA0D;YAC1D,oEAAoE;YACpE,mBAAmB;YACnB,EAAE;YACF,4CAA4C;YAC5C,MAAM,CAAC,OAAO,EAAE,CAAC;YAEjB,MAAM,UAAU,GAAG,IAAI,aAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YACvD,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC;YAE3B,oEAAoE;YACpE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAa,EAAE,EAAE;gBACpC,KAAK,CAAC,2CAA2C,CAAC,CAAC;gBACnD,gBAAM,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBAEpC,gEAAgE;gBAChE,8DAA8D;gBAC9D,YAAY;gBACZ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACjB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,OAAO,UAAU,CAAC;QACnB,CAAC;KAAA;CACD;AA3JD,kCA2JC;AAED,SAAS,MAAM,CAAC,MAAkC;IACjD,MAAM,CAAC,MAAM,EAAE,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,MAAe;IACnD,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,OAAO,CAAC,QAAwB;IACxC,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3E,CAAC;AAED,SAAS,IAAI,CACZ,GAAM,EACN,GAAG,IAAO;IAIV,MAAM,GAAG,GAAG,EAEX,CAAC;IACF,IAAI,GAAqB,CAAC;IAC1B,KAAK,GAAG,IAAI,GAAG,EAAE;QAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;SACpB;KACD;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}PK ���\��C C https-proxy-agent/dist/index.jsnu �[��� "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; const agent_1 = __importDefault(require("./agent")); function createHttpsProxyAgent(opts) { return new agent_1.default(opts); } (function (createHttpsProxyAgent) { createHttpsProxyAgent.HttpsProxyAgent = agent_1.default; createHttpsProxyAgent.prototype = agent_1.default.prototype; })(createHttpsProxyAgent || (createHttpsProxyAgent = {})); module.exports = createHttpsProxyAgent; //# sourceMappingURL=index.js.mapPK ���\���� � https-proxy-agent/dist/agent.jsnu �[��� "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const net_1 = __importDefault(require("net")); const tls_1 = __importDefault(require("tls")); const url_1 = __importDefault(require("url")); const assert_1 = __importDefault(require("assert")); const debug_1 = __importDefault(require("debug")); const agent_base_1 = require("agent-base"); const parse_proxy_response_1 = __importDefault(require("./parse-proxy-response")); const debug = debug_1.default('https-proxy-agent:agent'); /** * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. * * Outgoing HTTP requests are first tunneled through the proxy server using the * `CONNECT` HTTP request method to establish a connection to the proxy server, * and then the proxy server connects to the destination target and issues the * HTTP request from the proxy server. * * `https:` requests have their socket connection upgraded to TLS once * the connection to the proxy server has been established. * * @api public */ class HttpsProxyAgent extends agent_base_1.Agent { constructor(_opts) { let opts; if (typeof _opts === 'string') { opts = url_1.default.parse(_opts); } else { opts = _opts; } if (!opts) { throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!'); } debug('creating new HttpsProxyAgent instance: %o', opts); super(opts); const proxy = Object.assign({}, opts); // If `true`, then connect to the proxy server over TLS. // Defaults to `false`. this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol); // Prefer `hostname` over `host`, and set the `port` if needed. proxy.host = proxy.hostname || proxy.host; if (typeof proxy.port === 'string') { proxy.port = parseInt(proxy.port, 10); } if (!proxy.port && proxy.host) { proxy.port = this.secureProxy ? 443 : 80; } // ALPN is supported by Node.js >= v5. // attempt to negotiate http/1.1 for proxy servers that support http/2 if (this.secureProxy && !('ALPNProtocols' in proxy)) { proxy.ALPNProtocols = ['http 1.1']; } if (proxy.host && proxy.path) { // If both a `host` and `path` are specified then it's most likely // the result of a `url.parse()` call... we need to remove the // `path` portion so that `net.connect()` doesn't attempt to open // that as a Unix socket file. delete proxy.path; delete proxy.pathname; } this.proxy = proxy; } /** * Called when the node-core HTTP client library is creating a * new HTTP request. * * @api protected */ callback(req, opts) { return __awaiter(this, void 0, void 0, function* () { const { proxy, secureProxy } = this; // Create a socket connection to the proxy server. let socket; if (secureProxy) { debug('Creating `tls.Socket`: %o', proxy); socket = tls_1.default.connect(proxy); } else { debug('Creating `net.Socket`: %o', proxy); socket = net_1.default.connect(proxy); } const headers = Object.assign({}, proxy.headers); const hostname = `${opts.host}:${opts.port}`; let payload = `CONNECT ${hostname} HTTP/1.1\r\n`; // Inject the `Proxy-Authorization` header if necessary. if (proxy.auth) { headers['Proxy-Authorization'] = `Basic ${Buffer.from(proxy.auth).toString('base64')}`; } // The `Host` header should only include the port // number when it is not the default port. let { host, port, secureEndpoint } = opts; if (!isDefaultPort(port, secureEndpoint)) { host += `:${port}`; } headers.Host = host; headers.Connection = 'close'; for (const name of Object.keys(headers)) { payload += `${name}: ${headers[name]}\r\n`; } const proxyResponsePromise = parse_proxy_response_1.default(socket); socket.write(`${payload}\r\n`); const { statusCode, buffered } = yield proxyResponsePromise; if (statusCode === 200) { req.once('socket', resume); if (opts.secureEndpoint) { // The proxy is connecting to a TLS server, so upgrade // this socket connection to a TLS connection. debug('Upgrading socket connection to TLS'); const servername = opts.servername || opts.host; return tls_1.default.connect(Object.assign(Object.assign({}, omit(opts, 'host', 'hostname', 'path', 'port')), { socket, servername })); } return socket; } // Some other status code that's not 200... need to re-play the HTTP // header "data" events onto the socket once the HTTP machinery is // attached so that the node core `http` can parse and handle the // error status code. // Close the original socket, and a new "fake" socket is returned // instead, so that the proxy doesn't get the HTTP request // written to it (which may contain `Authorization` headers or other // sensitive data). // // See: https://hackerone.com/reports/541502 socket.destroy(); const fakeSocket = new net_1.default.Socket({ writable: false }); fakeSocket.readable = true; // Need to wait for the "socket" event to re-play the "data" events. req.once('socket', (s) => { debug('replaying proxy buffer for failed request'); assert_1.default(s.listenerCount('data') > 0); // Replay the "buffered" Buffer onto the fake `socket`, since at // this point the HTTP module machinery has been hooked up for // the user. s.push(buffered); s.push(null); }); return fakeSocket; }); } } exports.default = HttpsProxyAgent; function resume(socket) { socket.resume(); } function isDefaultPort(port, secure) { return Boolean((!secure && port === 80) || (secure && port === 443)); } function isHTTPS(protocol) { return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false; } function omit(obj, ...keys) { const ret = {}; let key; for (key in obj) { if (!keys.includes(key)) { ret[key] = obj[key]; } } return ret; } //# sourceMappingURL=agent.js.mapPK ���\zGL � � https-proxy-agent/README.mdnu �[��� https-proxy-agent ================ ### An HTTP(s) proxy `http.Agent` implementation for HTTPS [](https://github.com/TooTallNate/node-https-proxy-agent/actions?workflow=Node+CI) This module provides an `http.Agent` implementation that connects to a specified HTTP or HTTPS proxy server, and can be used with the built-in `https` module. Specifically, this `Agent` implementation connects to an intermediary "proxy" server and issues the [CONNECT HTTP method][CONNECT], which tells the proxy to open a direct TCP connection to the destination server. Since this agent implements the CONNECT HTTP method, it also works with other protocols that use this method when connecting over proxies (i.e. WebSockets). See the "Examples" section below for more. Installation ------------ Install with `npm`: ``` bash $ npm install https-proxy-agent ``` Examples -------- #### `https` module example ``` js var url = require('url'); var https = require('https'); var HttpsProxyAgent = require('https-proxy-agent'); // HTTP/HTTPS proxy to connect to var proxy = process.env.http_proxy || 'http://168.63.76.32:3128'; console.log('using proxy server %j', proxy); // HTTPS endpoint for the proxy to connect to var endpoint = process.argv[2] || 'https://graph.facebook.com/tootallnate'; console.log('attempting to GET %j', endpoint); var options = url.parse(endpoint); // create an instance of the `HttpsProxyAgent` class with the proxy server information var agent = new HttpsProxyAgent(proxy); options.agent = agent; https.get(options, function (res) { console.log('"response" event!', res.headers); res.pipe(process.stdout); }); ``` #### `ws` WebSocket connection example ``` js var url = require('url'); var WebSocket = require('ws'); var HttpsProxyAgent = require('https-proxy-agent'); // HTTP/HTTPS proxy to connect to var proxy = process.env.http_proxy || 'http://168.63.76.32:3128'; console.log('using proxy server %j', proxy); // WebSocket endpoint for the proxy to connect to var endpoint = process.argv[2] || 'ws://echo.websocket.org'; var parsed = url.parse(endpoint); console.log('attempting to connect to WebSocket %j', endpoint); // create an instance of the `HttpsProxyAgent` class with the proxy server information var options = url.parse(proxy); var agent = new HttpsProxyAgent(options); // finally, initiate the WebSocket connection var socket = new WebSocket(endpoint, { agent: agent }); socket.on('open', function () { console.log('"open" event!'); socket.send('hello world'); }); socket.on('message', function (data, flags) { console.log('"message" event! %j %j', data, flags); socket.close(); }); ``` API --- ### new HttpsProxyAgent(Object options) The `HttpsProxyAgent` class implements an `http.Agent` subclass that connects to the specified "HTTP(s) proxy server" in order to proxy HTTPS and/or WebSocket requests. This is achieved by using the [HTTP `CONNECT` method][CONNECT]. The `options` argument may either be a string URI of the proxy server to use, or an "options" object with more specific properties: * `host` - String - Proxy host to connect to (may use `hostname` as well). Required. * `port` - Number - Proxy port to connect to. Required. * `protocol` - String - If `https:`, then use TLS to connect to the proxy. * `headers` - Object - Additional HTTP headers to be sent on the HTTP CONNECT method. * Any other options given are passed to the `net.connect()`/`tls.connect()` functions. License ------- (The MIT License) Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. [CONNECT]: http://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_Tunneling PK ���\r�ϒcV cV . https-proxy-agent/node_modules/debug/README.mdnu �[��� # debug [](#backers) [](#sponsors) <img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png"> A tiny JavaScript debugging utility modelled after Node.js core's debugging technique. Works in Node.js and web browsers. ## Installation ```bash $ npm install debug ``` ## Usage `debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole. Example [_app.js_](./examples/node/app.js): ```js var debug = require('debug')('http') , http = require('http') , name = 'My App'; // fake app debug('booting %o', name); http.createServer(function(req, res){ debug(req.method + ' ' + req.url); res.end('hello\n'); }).listen(3000, function(){ debug('listening'); }); // fake worker of some kind require('./worker'); ``` Example [_worker.js_](./examples/node/worker.js): ```js var a = require('debug')('worker:a') , b = require('debug')('worker:b'); function work() { a('doing lots of uninteresting work'); setTimeout(work, Math.random() * 1000); } work(); function workb() { b('doing some work'); setTimeout(workb, Math.random() * 2000); } workb(); ``` The `DEBUG` environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: <img width="647" alt="screen shot 2017-08-08 at 12 53 04 pm" src="https://user-images.githubusercontent.com/71256/29091703-a6302cdc-7c38-11e7-8304-7c0b3bc600cd.png"> <img width="647" alt="screen shot 2017-08-08 at 12 53 38 pm" src="https://user-images.githubusercontent.com/71256/29091700-a62a6888-7c38-11e7-800b-db911291ca2b.png"> <img width="647" alt="screen shot 2017-08-08 at 12 53 25 pm" src="https://user-images.githubusercontent.com/71256/29091701-a62ea114-7c38-11e7-826a-2692bedca740.png"> #### Windows command prompt notes ##### CMD On Windows the environment variable is set using the `set` command. ```cmd set DEBUG=*,-not_this ``` Example: ```cmd set DEBUG=* & node app.js ``` ##### PowerShell (VS Code default) PowerShell uses different syntax to set environment variables. ```cmd $env:DEBUG = "*,-not_this" ``` Example: ```cmd $env:DEBUG='app';node app.js ``` Then, run the program to be debugged as usual. npm script example: ```js "windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js", ``` ## Namespace Colors Every debug instance has a color generated for it based on its namespace name. This helps when visually parsing the debug output to identify which debug instance a debug line belongs to. #### Node.js In Node.js, colors are enabled when stderr is a TTY. You also _should_ install the [`supports-color`](https://npmjs.org/supports-color) module alongside debug, otherwise debug will only use a small handful of basic colors. <img width="521" src="https://user-images.githubusercontent.com/71256/29092181-47f6a9e6-7c3a-11e7-9a14-1928d8a711cd.png"> #### Web Browser Colors are also enabled on "Web Inspectors" that understand the `%c` formatting option. These are WebKit web inspectors, Firefox ([since version 31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/)) and the Firebug plugin for Firefox (any version). <img width="524" src="https://user-images.githubusercontent.com/71256/29092033-b65f9f2e-7c39-11e7-8e32-f6f0d8e865c1.png"> ## Millisecond diff When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. <img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png"> When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below: <img width="647" src="https://user-images.githubusercontent.com/71256/29091956-6bd78372-7c39-11e7-8c55-c948396d6edd.png"> ## Conventions If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output. ## Wildcards The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:". ## Environment Variables When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: | Name | Purpose | |-----------|-------------------------------------------------| | `DEBUG` | Enables/disables specific debugging namespaces. | | `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). | | `DEBUG_COLORS`| Whether or not to use colors in the debug output. | | `DEBUG_DEPTH` | Object inspection depth. | | `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | __Note:__ The environment variables beginning with `DEBUG_` end up being converted into an Options object that gets used with `%o`/`%O` formatters. See the Node.js documentation for [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) for the complete list. ## Formatters Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters: | Formatter | Representation | |-----------|----------------| | `%O` | Pretty-print an Object on multiple lines. | | `%o` | Pretty-print an Object all on a single line. | | `%s` | String. | | `%d` | Number (both integer and float). | | `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. | | `%%` | Single percent sign ('%'). This does not consume an argument. | ### Custom formatters You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like: ```js const createDebug = require('debug') createDebug.formatters.h = (v) => { return v.toString('hex') } // …elsewhere const debug = createDebug('foo') debug('this is hex: %h', new Buffer('hello world')) // foo this is hex: 68656c6c6f20776f726c6421 +0ms ``` ## Browser Support You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify), or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest), if you don't want to build it yourself. Debug's enable state is currently persisted by `localStorage`. Consider the situation shown below where you have `worker:a` and `worker:b`, and wish to debug both. You can enable this using `localStorage.debug`: ```js localStorage.debug = 'worker:*' ``` And then refresh the page. ```js a = debug('worker:a'); b = debug('worker:b'); setInterval(function(){ a('doing some work'); }, 1000); setInterval(function(){ b('doing some work'); }, 1200); ``` In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_. <img width="647" src="https://user-images.githubusercontent.com/7143133/152083257-29034707-c42c-4959-8add-3cee850e6fcf.png"> ## Output streams By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method: Example [_stdout.js_](./examples/node/stdout.js): ```js var debug = require('debug'); var error = debug('app:error'); // by default stderr is used error('goes to stderr!'); var log = debug('app:log'); // set this namespace to log via console.log log.log = console.log.bind(console); // don't forget to bind to console! log('goes to stdout'); error('still goes to stderr!'); // set all output to go via console.info // overrides all per-namespace log settings debug.log = console.info.bind(console); error('now goes to stdout via console.info'); log('still goes to stdout, but via console.info now'); ``` ## Extend You can simply extend debugger ```js const log = require('debug')('auth'); //creates new debug instance with extended namespace const logSign = log.extend('sign'); const logLogin = log.extend('login'); log('hello'); // auth hello logSign('hello'); //auth:sign hello logLogin('hello'); //auth:login hello ``` ## Set dynamically You can also enable debug dynamically by calling the `enable()` method : ```js let debug = require('debug'); console.log(1, debug.enabled('test')); debug.enable('test'); console.log(2, debug.enabled('test')); debug.disable(); console.log(3, debug.enabled('test')); ``` print : ``` 1 false 2 true 3 false ``` Usage : `enable(namespaces)` `namespaces` can include modes separated by a colon and wildcards. Note that calling `enable()` completely overrides previously set DEBUG variable : ``` $ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))' => false ``` `disable()` Will disable all namespaces. The functions returns the namespaces currently enabled (and skipped). This can be useful if you want to disable debugging temporarily without knowing what was enabled to begin with. For example: ```js let debug = require('debug'); debug.enable('foo:*,-foo:bar'); let namespaces = debug.disable(); debug.enable(namespaces); ``` Note: There is no guarantee that the string will be identical to the initial enable string, but semantically they will be identical. ## Checking whether a debug target is enabled After you've created a debug instance, you can determine whether or not it is enabled by checking the `enabled` property: ```javascript const debug = require('debug')('http'); if (debug.enabled) { // do stuff... } ``` You can also manually toggle this property to force the debug instance to be enabled or disabled. ## Usage in child processes Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process. For example: ```javascript worker = fork(WORKER_WRAP_PATH, [workerPath], { stdio: [ /* stdin: */ 0, /* stdout: */ 'pipe', /* stderr: */ 'pipe', 'ipc', ], env: Object.assign({}, process.env, { DEBUG_COLORS: 1 // without this settings, colors won't be shown }), }); worker.stderr.pipe(process.stderr, { end: false }); ``` ## Authors - TJ Holowaychuk - Nathan Rajlich - Andrew Rhyne - Josh Junon ## Backers Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)] <a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a> <a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a> ## Sponsors Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)] <a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a> <a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a> ## License (The MIT License) Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca> Copyright (c) 2018-2021 Josh Junon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK ���\4Jtx x 0 https-proxy-agent/node_modules/debug/src/node.jsnu �[��� /** * Module dependencies. */ const tty = require('tty'); const util = require('util'); /** * This is the Node.js implementation of `debug()`. */ exports.init = init; exports.log = log; exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.destroy = util.deprecate( () => {}, 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' ); /** * Colors. */ exports.colors = [6, 2, 3, 4, 5, 1]; try { // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) // eslint-disable-next-line import/no-extraneous-dependencies const supportsColor = require('supports-color'); if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { exports.colors = [ 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 214, 215, 220, 221 ]; } } catch (error) { // Swallow - we only care if `supports-color` is available; it doesn't have to be. } /** * Build up the default `inspectOpts` object from the environment variables. * * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js */ exports.inspectOpts = Object.keys(process.env).filter(key => { return /^debug_/i.test(key); }).reduce((obj, key) => { // Camel-case const prop = key .substring(6) .toLowerCase() .replace(/_([a-z])/g, (_, k) => { return k.toUpperCase(); }); // Coerce string value into JS value let val = process.env[key]; if (/^(yes|on|true|enabled)$/i.test(val)) { val = true; } else if (/^(no|off|false|disabled)$/i.test(val)) { val = false; } else if (val === 'null') { val = null; } else { val = Number(val); } obj[prop] = val; return obj; }, {}); /** * Is stdout a TTY? Colored output is enabled when `true`. */ function useColors() { return 'colors' in exports.inspectOpts ? Boolean(exports.inspectOpts.colors) : tty.isatty(process.stderr.fd); } /** * Adds ANSI color escape codes if enabled. * * @api public */ function formatArgs(args) { const {namespace: name, useColors} = this; if (useColors) { const c = this.color; const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); const prefix = ` ${colorCode};1m${name} \u001B[0m`; args[0] = prefix + args[0].split('\n').join('\n' + prefix); args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); } else { args[0] = getDate() + name + ' ' + args[0]; } } function getDate() { if (exports.inspectOpts.hideDate) { return ''; } return new Date().toISOString() + ' '; } /** * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr. */ function log(...args) { return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n'); } /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { if (namespaces) { process.env.DEBUG = namespaces; } else { // If you set a process.env field to null or undefined, it gets cast to the // string 'null' or 'undefined'. Just delete instead. delete process.env.DEBUG; } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { return process.env.DEBUG; } /** * Init logic for `debug` instances. * * Create a new `inspectOpts` object in case `useColors` is set * differently for a particular `debug` instance. */ function init(debug) { debug.inspectOpts = {}; const keys = Object.keys(exports.inspectOpts); for (let i = 0; i < keys.length; i++) { debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; } } module.exports = require('./common')(exports); const {formatters} = module.exports; /** * Map %o to `util.inspect()`, all on a single line. */ formatters.o = function (v) { this.inspectOpts.colors = this.useColors; return util.inspect(v, this.inspectOpts) .split('\n') .map(str => str.trim()) .join(' '); }; /** * Map %O to `util.inspect()`, allowing multiple lines if needed. */ formatters.O = function (v) { this.inspectOpts.colors = this.useColors; return util.inspect(v, this.inspectOpts); }; PK ���\`�*� � 3 https-proxy-agent/node_modules/debug/src/browser.jsnu �[��� /* eslint-env browser */ /** * This is the web browser implementation of `debug()`. */ exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); exports.destroy = (() => { let warned = false; return () => { if (!warned) { warned = true; console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } }; })(); /** * Colors. */ exports.colors = [ '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' ]; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ // eslint-disable-next-line complexity function useColors() { // NB: In an Electron preload script, document will be defined but not fully // initialized. Since we know we're in Chrome, we'll just detect this case // explicitly if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { return true; } // Internet Explorer and Edge do not support colors. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } let m; // Is webkit? http://stackoverflow.com/a/16459606/376773 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 // eslint-disable-next-line no-return-assign return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || // Is firebug? http://stackoverflow.com/a/398120/376773 (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || // Is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) || // Double check webkit in userAgent just in case we are in a worker (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } /** * Colorize log arguments if enabled. * * @api public */ function formatArgs(args) { args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); if (!this.useColors) { return; } const c = 'color: ' + this.color; args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to // figure out the correct index to insert the CSS into let index = 0; let lastC = 0; args[0].replace(/%[a-zA-Z%]/g, match => { if (match === '%%') { return; } index++; if (match === '%c') { // We only are interested in the *last* %c // (the user may have provided their own) lastC = index; } }); args.splice(lastC, 0, c); } /** * Invokes `console.debug()` when available. * No-op when `console.debug` is not a "function". * If `console.debug` is not available, falls back * to `console.log`. * * @api public */ exports.log = console.debug || console.log || (() => {}); /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (namespaces) { exports.storage.setItem('debug', namespaces); } else { exports.storage.removeItem('debug'); } } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { let r; try { r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ; } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } // If debug isn't set in LS, and we're in Electron, try to load $DEBUG if (!r && typeof process !== 'undefined' && 'env' in process) { r = process.env.DEBUG; } return r; } /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage() { try { // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context // The Browser also has localStorage in the global context. return localStorage; } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } } module.exports = require('./common')(exports); const {formatters} = module.exports; /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ formatters.j = function (v) { try { return JSON.stringify(v); } catch (error) { return '[UnexpectedJSONParseError]: ' + error.message; } }; PK ���\N<x{: : 1 https-proxy-agent/node_modules/debug/src/index.jsnu �[��� /** * Detect Electron renderer / nwjs process, which is node, but we should * treat as a browser. */ if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { module.exports = require('./browser.js'); } else { module.exports = require('./node.js'); } PK ���\���� 2 https-proxy-agent/node_modules/debug/src/common.jsnu �[��� /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. */ function setup(env) { createDebug.debug = createDebug; createDebug.default = createDebug; createDebug.coerce = coerce; createDebug.disable = disable; createDebug.enable = enable; createDebug.enabled = enabled; createDebug.humanize = require('ms'); createDebug.destroy = destroy; Object.keys(env).forEach(key => { createDebug[key] = env[key]; }); /** * The currently active debug mode names, and names to skip. */ createDebug.names = []; createDebug.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ createDebug.formatters = {}; /** * Selects a color for a debug namespace * @param {String} namespace The namespace string for the debug instance to be colored * @return {Number|String} An ANSI color code for the given namespace * @api private */ function selectColor(namespace) { let hash = 0; for (let i = 0; i < namespace.length; i++) { hash = ((hash << 5) - hash) + namespace.charCodeAt(i); hash |= 0; // Convert to 32bit integer } return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; } createDebug.selectColor = selectColor; /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function createDebug(namespace) { let prevTime; let enableOverride = null; let namespacesCache; let enabledCache; function debug(...args) { // Disabled? if (!debug.enabled) { return; } const self = debug; // Set `diff` timestamp const curr = Number(new Date()); const ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; args[0] = createDebug.coerce(args[0]); if (typeof args[0] !== 'string') { // Anything else let's inspect with %O args.unshift('%O'); } // Apply any `formatters` transformations let index = 0; args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { // If we encounter an escaped % then don't increase the array index if (match === '%%') { return '%'; } index++; const formatter = createDebug.formatters[format]; if (typeof formatter === 'function') { const val = args[index]; match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` args.splice(index, 1); index--; } return match; }); // Apply env-specific formatting (colors, etc.) createDebug.formatArgs.call(self, args); const logFn = self.log || createDebug.log; logFn.apply(self, args); } debug.namespace = namespace; debug.useColors = createDebug.useColors(); debug.color = createDebug.selectColor(namespace); debug.extend = extend; debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. Object.defineProperty(debug, 'enabled', { enumerable: true, configurable: false, get: () => { if (enableOverride !== null) { return enableOverride; } if (namespacesCache !== createDebug.namespaces) { namespacesCache = createDebug.namespaces; enabledCache = createDebug.enabled(namespace); } return enabledCache; }, set: v => { enableOverride = v; } }); // Env-specific initialization logic for debug instances if (typeof createDebug.init === 'function') { createDebug.init(debug); } return debug; } function extend(namespace, delimiter) { const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); newDebug.log = this.log; return newDebug; } /** * Enables a debug mode by namespaces. This can include modes * separated by a colon and wildcards. * * @param {String} namespaces * @api public */ function enable(namespaces) { createDebug.save(namespaces); createDebug.namespaces = namespaces; createDebug.names = []; createDebug.skips = []; const split = (typeof namespaces === 'string' ? namespaces : '') .trim() .replace(/\s+/g, ',') .split(',') .filter(Boolean); for (const ns of split) { if (ns[0] === '-') { createDebug.skips.push(ns.slice(1)); } else { createDebug.names.push(ns); } } } /** * Checks if the given string matches a namespace template, honoring * asterisks as wildcards. * * @param {String} search * @param {String} template * @return {Boolean} */ function matchesTemplate(search, template) { let searchIndex = 0; let templateIndex = 0; let starIndex = -1; let matchIndex = 0; while (searchIndex < search.length) { if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) { // Match character or proceed with wildcard if (template[templateIndex] === '*') { starIndex = templateIndex; matchIndex = searchIndex; templateIndex++; // Skip the '*' } else { searchIndex++; templateIndex++; } } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition // Backtrack to the last '*' and try to match more characters templateIndex = starIndex + 1; matchIndex++; searchIndex = matchIndex; } else { return false; // No match } } // Handle trailing '*' in template while (templateIndex < template.length && template[templateIndex] === '*') { templateIndex++; } return templateIndex === template.length; } /** * Disable debug output. * * @return {String} namespaces * @api public */ function disable() { const namespaces = [ ...createDebug.names, ...createDebug.skips.map(namespace => '-' + namespace) ].join(','); createDebug.enable(''); return namespaces; } /** * Returns true if the given mode name is enabled, false otherwise. * * @param {String} name * @return {Boolean} * @api public */ function enabled(name) { for (const skip of createDebug.skips) { if (matchesTemplate(name, skip)) { return false; } } for (const ns of createDebug.names) { if (matchesTemplate(name, ns)) { return true; } } return false; } /** * Coerce `val`. * * @param {Mixed} val * @return {Mixed} * @api private */ function coerce(val) { if (val instanceof Error) { return val.stack || val.message; } return val; } /** * XXX DO NOT USE. This is a temporary stub function. * XXX It WILL be removed in the next major release. */ function destroy() { console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } createDebug.enable(createDebug.load()); return createDebug; } module.exports = setup; PK ���\�E�� � 1 https-proxy-agent/node_modules/debug/package.jsonnu �[��� { "name": "debug", "version": "4.4.3", "repository": { "type": "git", "url": "git://github.com/debug-js/debug.git" }, "description": "Lightweight debugging utility for Node.js and the browser", "keywords": [ "debug", "log", "debugger" ], "files": [ "src", "LICENSE", "README.md" ], "author": "Josh Junon (https://github.com/qix-)", "contributors": [ "TJ Holowaychuk <tj@vision-media.ca>", "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)", "Andrew Rhyne <rhyneandrew@gmail.com>" ], "license": "MIT", "scripts": { "lint": "xo", "test": "npm run test:node && npm run test:browser && npm run lint", "test:node": "mocha test.js test.node.js", "test:browser": "karma start --single-run", "test:coverage": "cat ./coverage/lcov.info | coveralls" }, "dependencies": { "ms": "^2.1.3" }, "devDependencies": { "brfs": "^2.0.1", "browserify": "^16.2.3", "coveralls": "^3.0.2", "karma": "^3.1.4", "karma-browserify": "^6.0.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0", "mocha": "^5.2.0", "mocha-lcov-reporter": "^1.2.0", "sinon": "^14.0.0", "xo": "^0.23.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } }, "main": "./src/index.js", "browser": "./src/browser.js", "engines": { "node": ">=6.0" }, "xo": { "rules": { "import/extensions": "off" } } } PK ���\�ߟ�s s , https-proxy-agent/node_modules/debug/LICENSEnu �[��� (The MIT License) Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca> Copyright (c) 2018-2021 Josh Junon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK ���\j�,�7 7 , https-proxy-agent/node_modules/ms/license.mdnu �[��� The MIT License (MIT) Copyright (c) 2020 Vercel, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK ���\Z�4�^ ^ + https-proxy-agent/node_modules/ms/readme.mdnu �[��� # ms  Use this package to easily convert various time formats to milliseconds. ## Examples ```js ms('2 days') // 172800000 ms('1d') // 86400000 ms('10h') // 36000000 ms('2.5 hrs') // 9000000 ms('2h') // 7200000 ms('1m') // 60000 ms('5s') // 5000 ms('1y') // 31557600000 ms('100') // 100 ms('-3 days') // -259200000 ms('-1h') // -3600000 ms('-200') // -200 ``` ### Convert from Milliseconds ```js ms(60000) // "1m" ms(2 * 60000) // "2m" ms(-3 * 60000) // "-3m" ms(ms('10 hours')) // "10h" ``` ### Time Format Written-Out ```js ms(60000, { long: true }) // "1 minute" ms(2 * 60000, { long: true }) // "2 minutes" ms(-3 * 60000, { long: true }) // "-3 minutes" ms(ms('10 hours'), { long: true }) // "10 hours" ``` ## Features - Works both in [Node.js](https://nodejs.org) and in the browser - If a number is supplied to `ms`, a string with a unit is returned - If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`) - If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned ## Related Packages - [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time. ## Caught a Bug? 1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device 2. Link the package to the global module directory: `npm link` 3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms! As always, you can run the tests using: `npm test` PK ���\��V�� � . https-proxy-agent/node_modules/ms/package.jsonnu �[��� { "name": "ms", "version": "2.1.3", "description": "Tiny millisecond conversion utility", "repository": "vercel/ms", "main": "./index", "files": [ "index.js" ], "scripts": { "precommit": "lint-staged", "lint": "eslint lib/* bin/*", "test": "mocha tests.js" }, "eslintConfig": { "extends": "eslint:recommended", "env": { "node": true, "es6": true } }, "lint-staged": { "*.js": [ "npm run lint", "prettier --single-quote --write", "git add" ] }, "license": "MIT", "devDependencies": { "eslint": "4.18.2", "expect.js": "0.3.1", "husky": "0.14.3", "lint-staged": "5.0.0", "mocha": "4.0.1", "prettier": "2.0.5" } } PK ���\�"L� � * https-proxy-agent/node_modules/ms/index.jsnu �[��� /** * Helpers. */ var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ module.exports = function (val, options) { options = options || {}; var type = typeof val; if (type === 'string' && val.length > 0) { return parse(val); } else if (type === 'number' && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error( 'val is not a non-empty string or a valid number. val=' + JSON.stringify(val) ); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = String(str); if (str.length > 100) { return; } var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( str ); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'weeks': case 'week': case 'w': return n * w; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; default: return undefined; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + 'd'; } if (msAbs >= h) { return Math.round(ms / h) + 'h'; } if (msAbs >= m) { return Math.round(ms / m) + 'm'; } if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, 'day'); } if (msAbs >= h) { return plural(ms, msAbs, h, 'hour'); } if (msAbs >= m) { return plural(ms, msAbs, m, 'minute'); } if (msAbs >= s) { return plural(ms, msAbs, s, 'second'); } return ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } PK ���\��$�} } https-proxy-agent/package.jsonnu �[��� { "name": "https-proxy-agent", "version": "5.0.1", "description": "An HTTP(s) proxy `http.Agent` implementation for HTTPS", "main": "dist/index", "types": "dist/index", "files": [ "dist" ], "scripts": { "prebuild": "rimraf dist", "build": "tsc", "test": "mocha --reporter spec", "test-lint": "eslint src --ext .js,.ts", "prepublishOnly": "npm run build" }, "repository": { "type": "git", "url": "git://github.com/TooTallNate/node-https-proxy-agent.git" }, "keywords": [ "https", "proxy", "endpoint", "agent" ], "author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)", "license": "MIT", "bugs": { "url": "https://github.com/TooTallNate/node-https-proxy-agent/issues" }, "dependencies": { "agent-base": "6", "debug": "4" }, "devDependencies": { "@types/debug": "4", "@types/node": "^12.12.11", "@typescript-eslint/eslint-plugin": "1.6.0", "@typescript-eslint/parser": "1.1.0", "eslint": "5.16.0", "eslint-config-airbnb": "17.1.0", "eslint-config-prettier": "4.1.0", "eslint-import-resolver-typescript": "1.1.1", "eslint-plugin-import": "2.16.0", "eslint-plugin-jsx-a11y": "6.2.1", "eslint-plugin-react": "7.12.4", "mocha": "^6.2.2", "proxy": "1", "rimraf": "^3.0.0", "typescript": "^3.5.3" }, "engines": { "node": ">= 6" } } PK ���\�ݏ��- �- cookie/README.mdnu �[��� # cookie [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Node.js Version][node-image]][node-url] [![Build Status][ci-image]][ci-url] [![Coverage Status][coveralls-image]][coveralls-url] Basic HTTP cookie parser and serializer for HTTP servers. ## Installation This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/). Installation is done using the [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): ```sh $ npm install cookie ``` ## API ```js var cookie = require('cookie'); ``` ### cookie.parse(str, options) Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs. The `str` argument is the string representing a `Cookie` header value and `options` is an optional object containing additional parsing options. ```js var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2'); // { foo: 'bar', equation: 'E=mc^2' } ``` #### Options `cookie.parse` accepts these properties in the options object. ##### decode Specifies a function that will be used to decode a cookie's value. Since the value of a cookie has a limited character set (and must be a simple string), this function can be used to decode a previously-encoded cookie value into a JavaScript string or other object. The default function is the global `decodeURIComponent`, which will decode any URL-encoded sequences into their byte representations. **note** if an error is thrown from this function, the original, non-decoded cookie value will be returned as the cookie's value. ### cookie.serialize(name, value, options) Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the name for the cookie, the `value` argument is the value to set the cookie to, and the `options` argument is an optional object containing additional serialization options. ```js var setCookie = cookie.serialize('foo', 'bar'); // foo=bar ``` #### Options `cookie.serialize` accepts these properties in the options object. ##### domain Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6265-5.2.3]. By default, no domain is set, and most clients will consider the cookie to apply to only the current domain. ##### encode Specifies a function that will be used to encode a cookie's value. Since value of a cookie has a limited character set (and must be a simple string), this function can be used to encode a value into a string suited for a cookie's value. The default function is the global `encodeURIComponent`, which will encode a JavaScript string into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range. ##### expires Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6265-5.2.1]. By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and will delete it on a condition like exiting a web browser application. **note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, so if both are set, they should point to the same date and time. ##### httpOnly Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6265-5.2.6]. When truthy, the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set. **note** be careful when setting this to `true`, as compliant clients will not allow client-side JavaScript to see the cookie in `document.cookie`. ##### maxAge Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6265-5.2.2]. The given number will be converted to an integer by rounding down. By default, no maximum age is set. **note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, so if both are set, they should point to the same date and time. ##### partitioned Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies) attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not. By default, the `Partitioned` attribute is not set. **note** This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it. More information about can be found in [the proposal](https://github.com/privacycg/CHIPS). ##### path Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path is considered the ["default path"][rfc-6265-5.1.4]. ##### priority Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. - `'low'` will set the `Priority` attribute to `Low`. - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set. - `'high'` will set the `Priority` attribute to `High`. More information about the different priority levels can be found in [the specification][rfc-west-cookie-priority-00-4.1]. **note** This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it. ##### sameSite Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][rfc-6265bis-09-5.4.7]. - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. - `false` will not set the `SameSite` attribute. - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie. - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. More information about the different enforcement levels can be found in [the specification][rfc-6265bis-09-5.4.7]. **note** This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it. ##### secure Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6265-5.2.5]. When truthy, the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set. **note** be careful when setting this to `true`, as compliant clients will not send the cookie back to the server in the future if the browser does not have an HTTPS connection. ## Example The following example uses this module in conjunction with the Node.js core HTTP server to prompt a user for their name and display it back on future visits. ```js var cookie = require('cookie'); var escapeHtml = require('escape-html'); var http = require('http'); var url = require('url'); function onRequest(req, res) { // Parse the query string var query = url.parse(req.url, true, true).query; if (query && query.name) { // Set a new cookie with the name res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), { httpOnly: true, maxAge: 60 * 60 * 24 * 7 // 1 week })); // Redirect back after setting cookie res.statusCode = 302; res.setHeader('Location', req.headers.referer || '/'); res.end(); return; } // Parse the cookies on the request var cookies = cookie.parse(req.headers.cookie || ''); // Get the visitor name set in the cookie var name = cookies.name; res.setHeader('Content-Type', 'text/html; charset=UTF-8'); if (name) { res.write('<p>Welcome back, <b>' + escapeHtml(name) + '</b>!</p>'); } else { res.write('<p>Hello, new visitor!</p>'); } res.write('<form method="GET">'); res.write('<input placeholder="enter your name" name="name"> <input type="submit" value="Set Name">'); res.end('</form>'); } http.createServer(onRequest).listen(3000); ``` ## Testing ```sh $ npm test ``` ## Benchmark ``` $ npm run bench > cookie@0.5.0 bench > node benchmark/index.js node@18.18.2 acorn@8.10.0 ada@2.6.0 ares@1.19.1 brotli@1.0.9 cldr@43.1 icu@73.2 llhttp@6.0.11 modules@108 napi@9 nghttp2@1.57.0 nghttp3@0.7.0 ngtcp2@0.8.1 openssl@3.0.10+quic simdutf@3.2.14 tz@2023c undici@5.26.3 unicode@15.0 uv@1.44.2 uvwasi@0.0.18 v8@10.2.154.26-node.26 zlib@1.2.13.1-motley > node benchmark/parse-top.js cookie.parse - top sites 14 tests completed. parse accounts.google.com x 2,588,913 ops/sec ±0.74% (186 runs sampled) parse apple.com x 2,370,002 ops/sec ±0.69% (186 runs sampled) parse cloudflare.com x 2,213,102 ops/sec ±0.88% (188 runs sampled) parse docs.google.com x 2,194,157 ops/sec ±1.03% (184 runs sampled) parse drive.google.com x 2,265,084 ops/sec ±0.79% (187 runs sampled) parse en.wikipedia.org x 457,099 ops/sec ±0.81% (186 runs sampled) parse linkedin.com x 504,407 ops/sec ±0.89% (186 runs sampled) parse maps.google.com x 1,230,959 ops/sec ±0.98% (186 runs sampled) parse microsoft.com x 926,294 ops/sec ±0.88% (184 runs sampled) parse play.google.com x 2,311,338 ops/sec ±0.83% (185 runs sampled) parse support.google.com x 1,508,850 ops/sec ±0.86% (186 runs sampled) parse www.google.com x 1,022,582 ops/sec ±1.32% (182 runs sampled) parse youtu.be x 332,136 ops/sec ±1.02% (185 runs sampled) parse youtube.com x 323,833 ops/sec ±0.77% (183 runs sampled) > node benchmark/parse.js cookie.parse - generic 6 tests completed. simple x 3,214,032 ops/sec ±1.61% (183 runs sampled) decode x 587,237 ops/sec ±1.16% (187 runs sampled) unquote x 2,954,618 ops/sec ±1.35% (183 runs sampled) duplicates x 857,008 ops/sec ±0.89% (187 runs sampled) 10 cookies x 292,133 ops/sec ±0.89% (187 runs sampled) 100 cookies x 22,610 ops/sec ±0.68% (187 runs sampled) ``` ## References - [RFC 6265: HTTP State Management Mechanism][rfc-6265] - [Same-site Cookies][rfc-6265bis-09-5.4.7] [rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/ [rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 [rfc-6265bis-09-5.4.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-09#section-5.4.7 [rfc-6265]: https://tools.ietf.org/html/rfc6265 [rfc-6265-5.1.4]: https://tools.ietf.org/html/rfc6265#section-5.1.4 [rfc-6265-5.2.1]: https://tools.ietf.org/html/rfc6265#section-5.2.1 [rfc-6265-5.2.2]: https://tools.ietf.org/html/rfc6265#section-5.2.2 [rfc-6265-5.2.3]: https://tools.ietf.org/html/rfc6265#section-5.2.3 [rfc-6265-5.2.4]: https://tools.ietf.org/html/rfc6265#section-5.2.4 [rfc-6265-5.2.5]: https://tools.ietf.org/html/rfc6265#section-5.2.5 [rfc-6265-5.2.6]: https://tools.ietf.org/html/rfc6265#section-5.2.6 [rfc-6265-5.3]: https://tools.ietf.org/html/rfc6265#section-5.3 ## License [MIT](LICENSE) [ci-image]: https://badgen.net/github/checks/jshttp/cookie/master?label=ci [ci-url]: https://github.com/jshttp/cookie/actions/workflows/ci.yml [coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/cookie/master [coveralls-url]: https://coveralls.io/r/jshttp/cookie?branch=master [node-image]: https://badgen.net/npm/node/cookie [node-url]: https://nodejs.org/en/download [npm-downloads-image]: https://badgen.net/npm/dm/cookie [npm-url]: https://npmjs.org/package/cookie [npm-version-image]: https://badgen.net/npm/v/cookie PK ���\^4"}� � cookie/SECURITY.mdnu �[��� # Security Policies and Procedures ## Reporting a Bug The `cookie` team and community take all security bugs seriously. Thank you for improving the security of the project. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions. Report security bugs by emailing the current owner(s) of `cookie`. This information can be found in the npm registry using the command `npm owner ls cookie`. If unsure or unable to get the information from the above, open an issue in the [project issue tracker](https://github.com/jshttp/cookie/issues) asking for the current contact information. To ensure the timely response to your report, please ensure that the entirety of the report is contained within the email body and not solely behind a web link or an attachment. At least one owner will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the owners will endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. PK ���\�D D cookie/package.jsonnu �[��� { "name": "cookie", "description": "HTTP server cookie parsing and serialization", "version": "0.7.2", "author": "Roman Shtylman <shtylman@gmail.com>", "contributors": [ "Douglas Christopher Wilson <doug@somethingdoug.com>" ], "license": "MIT", "keywords": [ "cookie", "cookies" ], "repository": "jshttp/cookie", "devDependencies": { "beautify-benchmark": "0.2.4", "benchmark": "2.1.4", "eslint": "8.53.0", "eslint-plugin-markdown": "3.0.1", "mocha": "10.2.0", "nyc": "15.1.0", "safe-buffer": "5.2.1", "top-sites": "1.1.194" }, "files": [ "HISTORY.md", "LICENSE", "README.md", "SECURITY.md", "index.js" ], "main": "index.js", "engines": { "node": ">= 0.6" }, "scripts": { "bench": "node benchmark/index.js", "lint": "eslint .", "test": "mocha --reporter spec --bail --check-leaks test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc --reporter=html --reporter=text npm test", "update-bench": "node scripts/update-benchmark.js" } } PK ���\�Jq� � cookie/LICENSEnu �[��� (The MIT License) Copyright (c) 2012-2014 Roman Shtylman <shtylman@gmail.com> Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK ���\?(��� � cookie/index.jsnu �[��� /*! * cookie * Copyright(c) 2012-2014 Roman Shtylman * Copyright(c) 2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict'; /** * Module exports. * @public */ exports.parse = parse; exports.serialize = serialize; /** * Module variables. * @private */ var __toString = Object.prototype.toString var __hasOwnProperty = Object.prototype.hasOwnProperty /** * RegExp to match cookie-name in RFC 6265 sec 4.1.1 * This refers out to the obsoleted definition of token in RFC 2616 sec 2.2 * which has been replaced by the token definition in RFC 7230 appendix B. * * cookie-name = token * token = 1*tchar * tchar = "!" / "#" / "$" / "%" / "&" / "'" / * "*" / "+" / "-" / "." / "^" / "_" / * "`" / "|" / "~" / DIGIT / ALPHA */ var cookieNameRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; /** * RegExp to match cookie-value in RFC 6265 sec 4.1.1 * * cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E * ; US-ASCII characters excluding CTLs, * ; whitespace DQUOTE, comma, semicolon, * ; and backslash */ var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/; /** * RegExp to match domain-value in RFC 6265 sec 4.1.1 * * domain-value = <subdomain> * ; defined in [RFC1034], Section 3.5, as * ; enhanced by [RFC1123], Section 2.1 * <subdomain> = <label> | <subdomain> "." <label> * <label> = <let-dig> [ [ <ldh-str> ] <let-dig> ] * Labels must be 63 characters or less. * 'let-dig' not 'letter' in the first char, per RFC1123 * <ldh-str> = <let-dig-hyp> | <let-dig-hyp> <ldh-str> * <let-dig-hyp> = <let-dig> | "-" * <let-dig> = <letter> | <digit> * <letter> = any one of the 52 alphabetic characters A through Z in * upper case and a through z in lower case * <digit> = any one of the ten digits 0 through 9 * * Keep support for leading dot: https://github.com/jshttp/cookie/issues/173 * * > (Note that a leading %x2E ("."), if present, is ignored even though that * character is not permitted, but a trailing %x2E ("."), if present, will * cause the user agent to ignore the attribute.) */ var domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i; /** * RegExp to match path-value in RFC 6265 sec 4.1.1 * * path-value = <any CHAR except CTLs or ";"> * CHAR = %x01-7F * ; defined in RFC 5234 appendix B.1 */ var pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/; /** * Parse a cookie header. * * Parse the given cookie header string into an object * The object has the various cookies as keys(names) => values * * @param {string} str * @param {object} [opt] * @return {object} * @public */ function parse(str, opt) { if (typeof str !== 'string') { throw new TypeError('argument str must be a string'); } var obj = {}; var len = str.length; // RFC 6265 sec 4.1.1, RFC 2616 2.2 defines a cookie name consists of one char minimum, plus '='. if (len < 2) return obj; var dec = (opt && opt.decode) || decode; var index = 0; var eqIdx = 0; var endIdx = 0; do { eqIdx = str.indexOf('=', index); if (eqIdx === -1) break; // No more cookie pairs. endIdx = str.indexOf(';', index); if (endIdx === -1) { endIdx = len; } else if (eqIdx > endIdx) { // backtrack on prior semicolon index = str.lastIndexOf(';', eqIdx - 1) + 1; continue; } var keyStartIdx = startIndex(str, index, eqIdx); var keyEndIdx = endIndex(str, eqIdx, keyStartIdx); var key = str.slice(keyStartIdx, keyEndIdx); // only assign once if (!__hasOwnProperty.call(obj, key)) { var valStartIdx = startIndex(str, eqIdx + 1, endIdx); var valEndIdx = endIndex(str, endIdx, valStartIdx); if (str.charCodeAt(valStartIdx) === 0x22 /* " */ && str.charCodeAt(valEndIdx - 1) === 0x22 /* " */) { valStartIdx++; valEndIdx--; } var val = str.slice(valStartIdx, valEndIdx); obj[key] = tryDecode(val, dec); } index = endIdx + 1 } while (index < len); return obj; } function startIndex(str, index, max) { do { var code = str.charCodeAt(index); if (code !== 0x20 /* */ && code !== 0x09 /* \t */) return index; } while (++index < max); return max; } function endIndex(str, index, min) { while (index > min) { var code = str.charCodeAt(--index); if (code !== 0x20 /* */ && code !== 0x09 /* \t */) return index + 1; } return min; } /** * Serialize data into a cookie header. * * Serialize a name value pair into a cookie string suitable for * http headers. An optional options object specifies cookie parameters. * * serialize('foo', 'bar', { httpOnly: true }) * => "foo=bar; httpOnly" * * @param {string} name * @param {string} val * @param {object} [opt] * @return {string} * @public */ function serialize(name, val, opt) { var enc = (opt && opt.encode) || encodeURIComponent; if (typeof enc !== 'function') { throw new TypeError('option encode is invalid'); } if (!cookieNameRegExp.test(name)) { throw new TypeError('argument name is invalid'); } var value = enc(val); if (!cookieValueRegExp.test(value)) { throw new TypeError('argument val is invalid'); } var str = name + '=' + value; if (!opt) return str; if (null != opt.maxAge) { var maxAge = Math.floor(opt.maxAge); if (!isFinite(maxAge)) { throw new TypeError('option maxAge is invalid') } str += '; Max-Age=' + maxAge; } if (opt.domain) { if (!domainValueRegExp.test(opt.domain)) { throw new TypeError('option domain is invalid'); } str += '; Domain=' + opt.domain; } if (opt.path) { if (!pathValueRegExp.test(opt.path)) { throw new TypeError('option path is invalid'); } str += '; Path=' + opt.path; } if (opt.expires) { var expires = opt.expires if (!isDate(expires) || isNaN(expires.valueOf())) { throw new TypeError('option expires is invalid'); } str += '; Expires=' + expires.toUTCString() } if (opt.httpOnly) { str += '; HttpOnly'; } if (opt.secure) { str += '; Secure'; } if (opt.partitioned) { str += '; Partitioned' } if (opt.priority) { var priority = typeof opt.priority === 'string' ? opt.priority.toLowerCase() : opt.priority; switch (priority) { case 'low': str += '; Priority=Low' break case 'medium': str += '; Priority=Medium' break case 'high': str += '; Priority=High' break default: throw new TypeError('option priority is invalid') } } if (opt.sameSite) { var sameSite = typeof opt.sameSite === 'string' ? opt.sameSite.toLowerCase() : opt.sameSite; switch (sameSite) { case true: str += '; SameSite=Strict'; break; case 'lax': str += '; SameSite=Lax'; break; case 'strict': str += '; SameSite=Strict'; break; case 'none': str += '; SameSite=None'; break; default: throw new TypeError('option sameSite is invalid'); } } return str; } /** * URL-decode string value. Optimized to skip native call when no %. * * @param {string} str * @returns {string} */ function decode (str) { return str.indexOf('%') !== -1 ? decodeURIComponent(str) : str } /** * Determine if value is a Date. * * @param {*} val * @private */ function isDate (val) { return __toString.call(val) === '[object Date]'; } /** * Try decoding a string using a decoding function. * * @param {string} str * @param {function} decode * @private */ function tryDecode(str, decode) { try { return decode(str); } catch (e) { return str; } } PK ���\ʖ�Y Y inherits/README.mdnu �[��� Browser-friendly inheritance fully compatible with standard node.js [inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). This package exports standard `inherits` from node.js `util` module in node environment, but also provides alternative browser-friendly implementation through [browser field](https://gist.github.com/shtylman/4339901). Alternative implementation is a literal copy of standard one located in standalone module to avoid requiring of `util`. It also has a shim for old browsers with no `Object.create` support. While keeping you sure you are using standard `inherits` implementation in node.js environment, it allows bundlers such as [browserify](https://github.com/substack/node-browserify) to not include full `util` package to your client code if all you need is just `inherits` function. It worth, because browser shim for `util` package is large and `inherits` is often the single function you need from it. It's recommended to use this package instead of `require('util').inherits` for any code that has chances to be used not only in node.js but in browser too. ## usage ```js var inherits = require('inherits'); // then use exactly as the standard one ``` ## note on version ~1.0 Version ~1.0 had completely different motivation and is not compatible neither with 2.0 nor with standard node.js `inherits`. If you are using version ~1.0 and planning to switch to ~2.0, be careful: * new version uses `super_` instead of `super` for referencing superclass * new version overwrites current prototype while old one preserves any existing fields on it PK ���\Cy�� � inherits/inherits.jsnu �[��� try { var util = require('util'); /* istanbul ignore next */ if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ module.exports = require('./inherits_browser.js'); } PK ���\ s�E E inherits/package.jsonnu �[��� { "name": "inherits", "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", "version": "2.0.4", "keywords": [ "inheritance", "class", "klass", "oop", "object-oriented", "inherits", "browser", "browserify" ], "main": "./inherits.js", "browser": "./inherits_browser.js", "repository": "git://github.com/isaacs/inherits", "license": "ISC", "scripts": { "test": "tap" }, "devDependencies": { "tap": "^14.2.4" }, "files": [ "inherits.js", "inherits_browser.js" ] } PK ���\(��� � inherits/LICENSEnu �[��� The ISC License Copyright (c) Isaac Z. Schlueter Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. PK ���\�ٹ�� � inherits/inherits_browser.jsnu �[��� if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }) } }; } else { // old school shim for old browsers module.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } } PK ���\�"�{ vary/HISTORY.mdnu �[��� 1.1.2 / 2017-09-23 ================== * perf: improve header token parsing speed 1.1.1 / 2017-03-20 ================== * perf: hoist regular expression 1.1.0 / 2015-09-29 ================== * Only accept valid field names in the `field` argument - Ensures the resulting string is a valid HTTP header value 1.0.1 / 2015-07-08 ================== * Fix setting empty header from empty `field` * perf: enable strict mode * perf: remove argument reassignments 1.0.0 / 2014-08-10 ================== * Accept valid `Vary` header string as `field` * Add `vary.append` for low-level string manipulation * Move to `jshttp` orgainzation 0.1.0 / 2014-06-05 ================== * Support array of fields to set 0.0.0 / 2014-06-04 ================== * Initial release PK ���\�Bb�� � vary/README.mdnu �[��� # vary [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Node.js Version][node-version-image]][node-version-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] Manipulate the HTTP Vary header ## Installation This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/). Installation is done using the [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): ```sh $ npm install vary ``` ## API <!-- eslint-disable no-unused-vars --> ```js var vary = require('vary') ``` ### vary(res, field) Adds the given header `field` to the `Vary` response header of `res`. This can be a string of a single field, a string of a valid `Vary` header, or an array of multiple fields. This will append the header if not already listed, otherwise leaves it listed in the current location. <!-- eslint-disable no-undef --> ```js // Append "Origin" to the Vary header of the response vary(res, 'Origin') ``` ### vary.append(header, field) Adds the given header `field` to the `Vary` response header string `header`. This can be a string of a single field, a string of a valid `Vary` header, or an array of multiple fields. This will append the header if not already listed, otherwise leaves it listed in the current location. The new header string is returned. <!-- eslint-disable no-undef --> ```js // Get header string appending "Origin" to "Accept, User-Agent" vary.append('Accept, User-Agent', 'Origin') ``` ## Examples ### Updating the Vary header when content is based on it ```js var http = require('http') var vary = require('vary') http.createServer(function onRequest (req, res) { // about to user-agent sniff vary(res, 'User-Agent') var ua = req.headers['user-agent'] || '' var isMobile = /mobi|android|touch|mini/i.test(ua) // serve site, depending on isMobile res.setHeader('Content-Type', 'text/html') res.end('You are (probably) ' + (isMobile ? '' : 'not ') + 'a mobile user') }) ``` ## Testing ```sh $ npm test ``` ## License [MIT](LICENSE) [npm-image]: https://img.shields.io/npm/v/vary.svg [npm-url]: https://npmjs.org/package/vary [node-version-image]: https://img.shields.io/node/v/vary.svg [node-version-url]: https://nodejs.org/en/download [travis-image]: https://img.shields.io/travis/jshttp/vary/master.svg [travis-url]: https://travis-ci.org/jshttp/vary [coveralls-image]: https://img.shields.io/coveralls/jshttp/vary/master.svg [coveralls-url]: https://coveralls.io/r/jshttp/vary [downloads-image]: https://img.shields.io/npm/dm/vary.svg [downloads-url]: https://npmjs.org/package/vary PK ���\3�Ƒ� � vary/package.jsonnu �[��� { "name": "vary", "description": "Manipulate the HTTP Vary header", "version": "1.1.2", "author": "Douglas Christopher Wilson <doug@somethingdoug.com>", "license": "MIT", "keywords": [ "http", "res", "vary" ], "repository": "jshttp/vary", "devDependencies": { "beautify-benchmark": "0.2.4", "benchmark": "2.1.4", "eslint": "3.19.0", "eslint-config-standard": "10.2.1", "eslint-plugin-import": "2.7.0", "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "5.1.1", "eslint-plugin-promise": "3.5.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" }, "files": [ "HISTORY.md", "LICENSE", "README.md", "index.js" ], "engines": { "node": ">= 0.8" }, "scripts": { "bench": "node benchmark/index.js", "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --reporter spec --bail --check-leaks test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" } } PK ���\���F F vary/LICENSEnu �[��� (The MIT License) Copyright (c) 2014-2017 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK ���\b,jr r vary/index.jsnu �[��� /*! * vary * Copyright(c) 2014-2017 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module exports. */ module.exports = vary module.exports.append = append /** * RegExp to match field-name in RFC 7230 sec 3.2 * * field-name = token * token = 1*tchar * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" * / DIGIT / ALPHA * ; any VCHAR, except delimiters */ var FIELD_NAME_REGEXP = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/ /** * Append a field to a vary header. * * @param {String} header * @param {String|Array} field * @return {String} * @public */ function append (header, field) { if (typeof header !== 'string') { throw new TypeError('header argument is required') } if (!field) { throw new TypeError('field argument is required') } // get fields array var fields = !Array.isArray(field) ? parse(String(field)) : field // assert on invalid field names for (var j = 0; j < fields.length; j++) { if (!FIELD_NAME_REGEXP.test(fields[j])) { throw new TypeError('field argument contains an invalid header name') } } // existing, unspecified vary if (header === '*') { return header } // enumerate current values var val = header var vals = parse(header.toLowerCase()) // unspecified vary if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) { return '*' } for (var i = 0; i < fields.length; i++) { var fld = fields[i].toLowerCase() // append value (case-preserving) if (vals.indexOf(fld) === -1) { vals.push(fld) val = val ? val + ', ' + fields[i] : fields[i] } } return val } /** * Parse a vary header into an array. * * @param {String} header * @return {Array} * @private */ function parse (header) { var end = 0 var list = [] var start = 0 // gather tokens for (var i = 0, len = header.length; i < len; i++) { switch (header.charCodeAt(i)) { case 0x20: /* */ if (start === end) { start = end = i + 1 } break case 0x2c: /* , */ list.push(header.substring(start, end)) start = end = i + 1 break default: end = i + 1 break } } // final token list.push(header.substring(start, end)) return list } /** * Mark that a request is varied on a header field. * * @param {Object} res * @param {String|Array} field * @public */ function vary (res, field) { if (!res || !res.getHeader || !res.setHeader) { // quack quack throw new TypeError('res argument is required') } // get existing header var val = res.getHeader('Vary') || '' var header = Array.isArray(val) ? val.join(', ') : String(val) // set new header if ((val = append(header, field))) { res.setHeader('Vary', val) } } PK ���\撱UH H which/README.mdnu �[��� # which Like the unix `which` utility. Finds the first instance of a specified executable in the PATH environment variable. Does not cache the results, so `hash -r` is not needed when the PATH changes. ## USAGE ```javascript var which = require('which') // async usage which('node', function (er, resolvedPath) { // er is returned if no "node" is found on the PATH // if it is found, then the absolute path to the exec is returned }) // or promise which('node').then(resolvedPath => { ... }).catch(er => { ... not found ... }) // sync usage // throws if not found var resolved = which.sync('node') // if nothrow option is used, returns null if not found resolved = which.sync('node', {nothrow: true}) // Pass options to override the PATH and PATHEXT environment vars. which('node', { path: someOtherPath }, function (er, resolved) { if (er) throw er console.log('found at %j', resolved) }) ``` ## CLI USAGE Same as the BSD `which(1)` binary. ``` usage: which [-as] program ... ``` ## OPTIONS You may pass an options object as the second argument. - `path`: Use instead of the `PATH` environment variable. - `pathExt`: Use instead of the `PATHEXT` environment variable. - `all`: Return all matches, instead of just the first one. Note that this means the function returns an array of strings instead of a single string. PK ���\Fڧ� � which/bin/node-whichnu �[��� #!/usr/bin/env node var which = require("../") if (process.argv.length < 3) usage() function usage () { console.error('usage: which [-as] program ...') process.exit(1) } var all = false var silent = false var dashdash = false var args = process.argv.slice(2).filter(function (arg) { if (dashdash || !/^-/.test(arg)) return true if (arg === '--') { dashdash = true return false } var flags = arg.substr(1).split('') for (var f = 0; f < flags.length; f++) { var flag = flags[f] switch (flag) { case 's': silent = true break case 'a': all = true break default: console.error('which: illegal option -- ' + flag) usage() } } return false }) process.exit(args.reduce(function (pv, current) { try { var f = which.sync(current, { all: all }) if (all) f = f.join('\n') if (!silent) console.log(f) return pv; } catch (e) { return 1; } }, 0)) PK ���\E?3�k k which/CHANGELOG.mdnu �[��� # Changes ## 2.0.2 * Rename bin to `node-which` ## 2.0.1 * generate changelog and publish on version bump * enforce 100% test coverage * Promise interface ## 2.0.0 * Parallel tests, modern JavaScript, and drop support for node < 8 ## 1.3.1 * update deps * update travis ## v1.3.0 * Add nothrow option to which.sync * update tap ## v1.2.14 * appveyor: drop node 5 and 0.x * travis-ci: add node 6, drop 0.x ## v1.2.13 * test: Pass missing option to pass on windows * update tap * update isexe to 2.0.0 * neveragain.tech pledge request ## v1.2.12 * Removed unused require ## v1.2.11 * Prevent changelog script from being included in package ## v1.2.10 * Use env.PATH only, not env.Path ## v1.2.9 * fix for paths starting with ../ * Remove unused `is-absolute` module ## v1.2.8 * bullet items in changelog that contain (but don't start with) # ## v1.2.7 * strip 'update changelog' changelog entries out of changelog ## v1.2.6 * make the changelog bulleted ## v1.2.5 * make a changelog, and keep it up to date * don't include tests in package * Properly handle relative-path executables * appveyor * Attach error code to Not Found error * Make tests pass on Windows ## v1.2.4 * Fix typo ## v1.2.3 * update isexe, fix regression in pathExt handling ## v1.2.2 * update deps, use isexe module, test windows ## v1.2.1 * Sometimes windows PATH entries are quoted * Fixed a bug in the check for group and user mode bits. This bug was introduced during refactoring for supporting strict mode. * doc cli ## v1.2.0 * Add support for opt.all and -as cli flags * test the bin * update travis * Allow checking for multiple programs in bin/which * tap 2 ## v1.1.2 * travis * Refactored and fixed undefined error on Windows * Support strict mode ## v1.1.1 * test +g exes against secondary groups, if available * Use windows exe semantics on cygwin & msys * cwd should be first in path on win32, not last * Handle lower-case 'env.Path' on Windows * Update docs * use single-quotes ## v1.1.0 * Add tests, depend on is-absolute ## v1.0.9 * which.js: root is allowed to execute files owned by anyone ## v1.0.8 * don't use graceful-fs ## v1.0.7 * add license to package.json ## v1.0.6 * isc license ## 1.0.5 * Awful typo ## 1.0.4 * Test for path absoluteness properly * win: Allow '' as a pathext if cmd has a . in it ## 1.0.3 * Remove references to execPath * Make `which.sync()` work on Windows by honoring the PATHEXT variable. * Make `isExe()` always return true on Windows. * MIT ## 1.0.2 * Only files can be exes ## 1.0.1 * Respect the PATHEXT env for win32 support * should 0755 the bin * binary * guts * package * 1st PK ���\��r-[ [ which/which.jsnu �[��� const isWindows = process.platform === 'win32' || process.env.OSTYPE === 'cygwin' || process.env.OSTYPE === 'msys' const path = require('path') const COLON = isWindows ? ';' : ':' const isexe = require('isexe') const getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) const getPathInfo = (cmd, opt) => { const colon = opt.colon || COLON // If it has a slash, then we don't bother searching the pathenv. // just check the file itself, and that's it. const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] : ( [ // windows always checks the cwd first ...(isWindows ? [process.cwd()] : []), ...(opt.path || process.env.PATH || /* istanbul ignore next: very unusual */ '').split(colon), ] ) const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' : '' const pathExt = isWindows ? pathExtExe.split(colon) : [''] if (isWindows) { if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') pathExt.unshift('') } return { pathEnv, pathExt, pathExtExe, } } const which = (cmd, opt, cb) => { if (typeof opt === 'function') { cb = opt opt = {} } if (!opt) opt = {} const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) const found = [] const step = i => new Promise((resolve, reject) => { if (i === pathEnv.length) return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd)) const ppRaw = pathEnv[i] const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw const pCmd = path.join(pathPart, cmd) const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd resolve(subStep(p, i, 0)) }) const subStep = (p, i, ii) => new Promise((resolve, reject) => { if (ii === pathExt.length) return resolve(step(i + 1)) const ext = pathExt[ii] isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { if (!er && is) { if (opt.all) found.push(p + ext) else return resolve(p + ext) } return resolve(subStep(p, i, ii + 1)) }) }) return cb ? step(0).then(res => cb(null, res), cb) : step(0) } const whichSync = (cmd, opt) => { opt = opt || {} const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) const found = [] for (let i = 0; i < pathEnv.length; i ++) { const ppRaw = pathEnv[i] const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw const pCmd = path.join(pathPart, cmd) const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd for (let j = 0; j < pathExt.length; j ++) { const cur = p + pathExt[j] try { const is = isexe.sync(cur, { pathExt: pathExtExe }) if (is) { if (opt.all) found.push(cur) else return cur } } catch (ex) {} } } if (opt.all && found.length) return found if (opt.nothrow) return null throw getNotFoundError(cmd) } module.exports = which which.sync = whichSync PK ���\�1xl which/package.jsonnu �[��� { "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", "name": "which", "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.", "version": "2.0.2", "repository": { "type": "git", "url": "git://github.com/isaacs/node-which.git" }, "main": "which.js", "bin": { "node-which": "./bin/node-which" }, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "devDependencies": { "mkdirp": "^0.5.0", "rimraf": "^2.6.2", "tap": "^14.6.9" }, "scripts": { "test": "tap", "preversion": "npm test", "postversion": "npm publish", "prepublish": "npm run changelog", "prechangelog": "bash gen-changelog.sh", "changelog": "git add CHANGELOG.md", "postchangelog": "git commit -m 'update changelog - '${npm_package_version}", "postpublish": "git push origin --follow-tags" }, "files": [ "which.js", "bin/node-which" ], "tap": { "check-coverage": true }, "engines": { "node": ">= 8" } } PK ���\�aGW� � which/LICENSEnu �[��� The ISC License Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. PK ���\��7� � wrappy/README.mdnu �[��� # wrappy Callback wrapping utility ## USAGE ```javascript var wrappy = require("wrappy") // var wrapper = wrappy(wrapperFunction) // make sure a cb is called only once // See also: http://npm.im/once for this specific use case var once = wrappy(function (cb) { var called = false return function () { if (called) return called = true return cb.apply(this, arguments) } }) function printBoo () { console.log('boo') } // has some rando property printBoo.iAmBooPrinter = true var onlyPrintOnce = once(printBoo) onlyPrintOnce() // prints 'boo' onlyPrintOnce() // does nothing // random property is retained! assert.equal(onlyPrintOnce.iAmBooPrinter, true) ``` PK ���\86'&� � wrappy/wrappy.jsnu �[��� // Returns a wrapper function that returns a wrapped callback // The wrapper function should do some stuff, and return a // presumably different callback function. // This makes sure that own properties are retained, so that // decorations and such are not lost along the way. module.exports = wrappy function wrappy (fn, cb) { if (fn && cb) return wrappy(fn)(cb) if (typeof fn !== 'function') throw new TypeError('need wrapper function') Object.keys(fn).forEach(function (k) { wrapper[k] = fn[k] }) return wrapper function wrapper() { var args = new Array(arguments.length) for (var i = 0; i < args.length; i++) { args[i] = arguments[i] } var ret = fn.apply(this, args) var cb = args[args.length-1] if (typeof ret === 'function' && ret !== cb) { Object.keys(cb).forEach(function (k) { ret[k] = cb[k] }) } return ret } } PK ���\_ot^ ^ wrappy/package.jsonnu �[��� { "name": "wrappy", "version": "1.0.2", "description": "Callback wrapping utility", "main": "wrappy.js", "files": [ "wrappy.js" ], "directories": { "test": "test" }, "dependencies": {}, "devDependencies": { "tap": "^2.3.1" }, "scripts": { "test": "tap --coverage test/*.js" }, "repository": { "type": "git", "url": "https://github.com/npm/wrappy" }, "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", "license": "ISC", "bugs": { "url": "https://github.com/npm/wrappy/issues" }, "homepage": "https://github.com/npm/wrappy" } PK ���\�aGW� � wrappy/LICENSEnu �[��� The ISC License Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. PK ���\*�_� err-code/.eslintrc.jsonnu �[��� { "root": true, "extends": [ "@satazor/eslint-config/es6", "@satazor/eslint-config/addons/node" ] }PK ���\E��t+ + err-code/.travis.ymlnu �[��� language: node_js node_js: - "4" - "6" PK ���\A�O�M M err-code/bower.jsonnu �[��� { "name": "err-code", "version": "1.1.1", "description": "Create new error instances with a code and additional properties", "main": "index.umd.js", "homepage": "https://github.com/IndigoUnited/js-err-code", "authors": [ "IndigoUnited <hello@indigounited.com> (http://indigounited.com)" ], "moduleType": [ "amd", "globals", "node" ], "keywords": [ "error", "err", "code", "properties", "property" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ] } PK ���\���� � err-code/README.mdnu �[��� # err-code [![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url] [![Greenkeeper badge][greenkeeper-image]][greenkeeper-url] [npm-url]:https://npmjs.org/package/err-code [downloads-image]:http://img.shields.io/npm/dm/err-code.svg [npm-image]:http://img.shields.io/npm/v/err-code.svg [travis-url]:https://travis-ci.org/IndigoUnited/js-err-code [travis-image]:http://img.shields.io/travis/IndigoUnited/js-err-code/master.svg [david-dm-url]:https://david-dm.org/IndigoUnited/js-err-code [david-dm-image]:https://img.shields.io/david/IndigoUnited/js-err-code.svg [david-dm-dev-url]:https://david-dm.org/IndigoUnited/js-err-code?type=dev [david-dm-dev-image]:https://img.shields.io/david/dev/IndigoUnited/js-err-code.svg [greenkeeper-image]:https://badges.greenkeeper.io/IndigoUnited/js-err-code.svg [greenkeeper-url]:https://greenkeeper.io/ Create new error instances with a code and additional properties. ## Installation ```console $ npm install err-code // or $ bower install err-code ``` The browser file is named index.umd.js which supports CommonJS, AMD and globals (errCode). ## Why I find myself doing this repeatedly: ```js var err = new Error('My message'); err.code = 'SOMECODE'; err.detail = 'Additional information about the error'; throw err; ``` ## Usage Simple usage. ```js var errcode = require('err-code'); // fill error with message + code throw errcode(new Error('My message'), 'ESOMECODE'); // fill error with message + code + props throw errcode(new Error('My message'), 'ESOMECODE', { detail: 'Additional information about the error' }); // fill error with message + props throw errcode(new Error('My message'), { detail: 'Additional information about the error' }); ``` ## Pre-existing fields If the passed `Error` already has a `.code` field, or fields specified in the third argument to `errcode` they will be overwritten, unless the fields are read only or otherwise throw during assignment in which case a new object will be created that shares a prototype chain with the original `Error`. The `.stack` and `.message` properties will be carried over from the original error and `.code` or any passed properties will be set on it. ## Tests `$ npm test` ## License Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). PK ���\!S� err-code/index.umd.jsnu �[��� (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.errCode = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 'use strict'; function assign(obj, props) { for (const key in props) { Object.defineProperty(obj, key, { value: props[key], enumerable: true, configurable: true, }); } return obj; } function createError(err, code, props) { if (!err || typeof err === 'string') { throw new TypeError('Please pass an Error to err-code'); } if (!props) { props = {}; } if (typeof code === 'object') { props = code; code = undefined; } if (code != null) { props.code = code; } try { return assign(err, props); } catch (_) { props.message = err.message; props.stack = err.stack; const ErrClass = function () {}; ErrClass.prototype = Object.create(Object.getPrototypeOf(err)); return assign(new ErrClass(), props); } } module.exports = createError; },{}]},{},[1])(1) }); PK ���\�;��� � err-code/.editorconfignu �[��� root = true [*] indent_style = space indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [package.json] indent_size = 2 PK ���\&�}E, , err-code/test/.eslintrc.jsonnu �[��� { "env": { "mocha": true } }PK ���\��U�b b err-code/test/test.jsnu �[��� 'use strict'; const errcode = require('../index'); const expect = require('expect.js'); describe('errcode', () => { describe('string as first argument', () => { it('should throw an error', () => { expect(() => { errcode('my message'); }).to.throwError((err) => { expect(err).to.be.a(TypeError); }); }); }); describe('error as first argument', () => { it('should accept an error and do nothing', () => { const myErr = new Error('my message'); const err = errcode(myErr); expect(err).to.be(myErr); expect(err.hasOwnProperty(err.code)).to.be(false); }); it('should accept an error and add a code', () => { const myErr = new Error('my message'); const err = errcode(myErr, 'ESOME'); expect(err).to.be(myErr); expect(err.code).to.be('ESOME'); }); it('should accept an error object and add code & properties', () => { const myErr = new Error('my message'); const err = errcode(myErr, 'ESOME', { foo: 'bar', bar: 'foo' }); expect(err).to.be.an(Error); expect(err.code).to.be('ESOME'); expect(err.foo).to.be('bar'); expect(err.bar).to.be('foo'); }); it('should create an error object without code but with properties', () => { const myErr = new Error('my message'); const err = errcode(myErr, { foo: 'bar', bar: 'foo' }); expect(err).to.be.an(Error); expect(err.code).to.be(undefined); expect(err.foo).to.be('bar'); expect(err.bar).to.be('foo'); }); it('should set a non-writable field', () => { const myErr = new Error('my message'); Object.defineProperty(myErr, 'code', { value: 'derp', writable: false, }); const err = errcode(myErr, 'ERR_WAT'); expect(err).to.be.an(Error); expect(err.stack).to.equal(myErr.stack); expect(err.code).to.be('ERR_WAT'); }); it('should add a code to frozen object', () => { const myErr = new Error('my message'); const err = errcode(Object.freeze(myErr), 'ERR_WAT'); expect(err).to.be.an(Error); expect(err.stack).to.equal(myErr.stack); expect(err.code).to.be('ERR_WAT'); }); it('should to set a field that throws at assignment time', () => { const myErr = new Error('my message'); Object.defineProperty(myErr, 'code', { enumerable: true, set() { throw new Error('Nope!'); }, get() { return 'derp'; }, }); const err = errcode(myErr, 'ERR_WAT'); expect(err).to.be.an(Error); expect(err.stack).to.equal(myErr.stack); expect(err.code).to.be('ERR_WAT'); }); it('should retain error type', () => { const myErr = new TypeError('my message'); Object.defineProperty(myErr, 'code', { value: 'derp', writable: false, }); const err = errcode(myErr, 'ERR_WAT'); expect(err).to.be.a(TypeError); expect(err.stack).to.equal(myErr.stack); expect(err.code).to.be('ERR_WAT'); }); it('should add a code to a class that extends Error', () => { class CustomError extends Error { set code(val) { throw new Error('Nope!'); } } const myErr = new CustomError('my message'); Object.defineProperty(myErr, 'code', { value: 'derp', writable: false, configurable: false, }); const err = errcode(myErr, 'ERR_WAT'); expect(err).to.be.a(CustomError); expect(err.stack).to.equal(myErr.stack); expect(err.code).to.be('ERR_WAT'); // original prototype chain should be intact expect(() => { const otherErr = new CustomError('my message'); otherErr.code = 'derp'; }).to.throwError(); }); it('should support errors that are not Errors', () => { const err = errcode({ message: 'Oh noes!', }, 'ERR_WAT'); expect(err.message).to.be('Oh noes!'); expect(err.code).to.be('ERR_WAT'); }); }); describe('falsy first arguments', () => { it('should not allow passing null as the first argument', () => { expect(() => { errcode(null); }).to.throwError((err) => { expect(err).to.be.a(TypeError); }); }); it('should not allow passing undefined as the first argument', () => { expect(() => { errcode(undefined); }).to.throwError((err) => { expect(err).to.be.a(TypeError); }); }); }); }); PK ���\���L L err-code/package.jsonnu �[��� { "name": "err-code", "version": "2.0.3", "description": "Create an error with a code", "main": "index.js", "scripts": { "lint": "eslint '{*.js,test/**/*.js}' --ignore-pattern *.umd.js", "test": "mocha --bail", "browserify": "browserify -s err-code index.js > index.umd.js" }, "bugs": { "url": "https://github.com/IndigoUnited/js-err-code/issues/" }, "repository": { "type": "git", "url": "git://github.com/IndigoUnited/js-err-code.git" }, "keywords": [ "error", "err", "code", "properties", "property" ], "author": "IndigoUnited <hello@indigounited.com> (http://indigounited.com)", "license": "MIT", "devDependencies": { "@satazor/eslint-config": "^3.0.0", "browserify": "^16.5.1", "eslint": "^7.2.0", "expect.js": "^0.3.1", "mocha": "^8.0.1" } } PK ���\�`.� � err-code/index.jsnu �[��� 'use strict'; function assign(obj, props) { for (const key in props) { Object.defineProperty(obj, key, { value: props[key], enumerable: true, configurable: true, }); } return obj; } function createError(err, code, props) { if (!err || typeof err === 'string') { throw new TypeError('Please pass an Error to err-code'); } if (!props) { props = {}; } if (typeof code === 'object') { props = code; code = undefined; } if (code != null) { props.code = code; } try { return assign(err, props); } catch (_) { props.message = err.message; props.stack = err.stack; const ErrClass = function () {}; ErrClass.prototype = Object.create(Object.getPrototypeOf(err)); return assign(new ErrClass(), props); } } module.exports = createError; PK ���\+� : content-type/HISTORY.mdnu �[��� 1.0.5 / 2023-01-29 ================== * perf: skip value escaping when unnecessary 1.0.4 / 2017-09-11 ================== * perf: skip parameter parsing when no parameters 1.0.3 / 2017-09-10 ================== * perf: remove argument reassignment 1.0.2 / 2016-05-09 ================== * perf: enable strict mode 1.0.1 / 2015-02-13 ================== * Improve missing `Content-Type` header error message 1.0.0 / 2015-02-01 ================== * Initial implementation, derived from `media-typer@0.3.0` PK ���\�I(� � content-type/README.mdnu �[��� # content-type [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Node.js Version][node-image]][node-url] [![Build Status][ci-image]][ci-url] [![Coverage Status][coveralls-image]][coveralls-url] Create and parse HTTP Content-Type header according to RFC 7231 ## Installation ```sh $ npm install content-type ``` ## API ```js var contentType = require('content-type') ``` ### contentType.parse(string) ```js var obj = contentType.parse('image/svg+xml; charset=utf-8') ``` Parse a `Content-Type` header. This will return an object with the following properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`): - `type`: The media type (the type and subtype, always lower case). Example: `'image/svg+xml'` - `parameters`: An object of the parameters in the media type (name of parameter always lower case). Example: `{charset: 'utf-8'}` Throws a `TypeError` if the string is missing or invalid. ### contentType.parse(req) ```js var obj = contentType.parse(req) ``` Parse the `Content-Type` header from the given `req`. Short-cut for `contentType.parse(req.headers['content-type'])`. Throws a `TypeError` if the `Content-Type` header is missing or invalid. ### contentType.parse(res) ```js var obj = contentType.parse(res) ``` Parse the `Content-Type` header set on the given `res`. Short-cut for `contentType.parse(res.getHeader('content-type'))`. Throws a `TypeError` if the `Content-Type` header is missing or invalid. ### contentType.format(obj) ```js var str = contentType.format({ type: 'image/svg+xml', parameters: { charset: 'utf-8' } }) ``` Format an object into a `Content-Type` header. This will return a string of the content type for the given object with the following properties (examples are shown that produce the string `'image/svg+xml; charset=utf-8'`): - `type`: The media type (will be lower-cased). Example: `'image/svg+xml'` - `parameters`: An object of the parameters in the media type (name of the parameter will be lower-cased). Example: `{charset: 'utf-8'}` Throws a `TypeError` if the object contains an invalid type or parameter names. ## License [MIT](LICENSE) [ci-image]: https://badgen.net/github/checks/jshttp/content-type/master?label=ci [ci-url]: https://github.com/jshttp/content-type/actions/workflows/ci.yml [coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/content-type/master [coveralls-url]: https://coveralls.io/r/jshttp/content-type?branch=master [node-image]: https://badgen.net/npm/node/content-type [node-url]: https://nodejs.org/en/download [npm-downloads-image]: https://badgen.net/npm/dm/content-type [npm-url]: https://npmjs.org/package/content-type [npm-version-image]: https://badgen.net/npm/v/content-type PK ���\R�v3 3 content-type/package.jsonnu �[��� { "name": "content-type", "description": "Create and parse HTTP Content-Type header", "version": "1.0.5", "author": "Douglas Christopher Wilson <doug@somethingdoug.com>", "license": "MIT", "keywords": [ "content-type", "http", "req", "res", "rfc7231" ], "repository": "jshttp/content-type", "devDependencies": { "deep-equal": "1.0.1", "eslint": "8.32.0", "eslint-config-standard": "15.0.1", "eslint-plugin-import": "2.27.5", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "6.1.1", "eslint-plugin-standard": "4.1.0", "mocha": "10.2.0", "nyc": "15.1.0" }, "files": [ "LICENSE", "HISTORY.md", "README.md", "index.js" ], "engines": { "node": ">= 0.6" }, "scripts": { "lint": "eslint .", "test": "mocha --reporter spec --check-leaks --bail test/", "test-ci": "nyc --reporter=lcovonly --reporter=text npm test", "test-cov": "nyc --reporter=html --reporter=text npm test", "version": "node scripts/version-history.js && git add HISTORY.md" } } PK ���\q4��A A content-type/LICENSEnu �[��� (The MIT License) Copyright (c) 2015 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK ���\���� � content-type/index.jsnu �[��� /*! * content-type * Copyright(c) 2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 * * parameter = token "=" ( token / quoted-string ) * token = 1*tchar * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" * / DIGIT / ALPHA * ; any VCHAR, except delimiters * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text * obs-text = %x80-FF * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) */ var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g // eslint-disable-line no-control-regex var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/ // eslint-disable-line no-control-regex var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ /** * RegExp to match quoted-pair in RFC 7230 sec 3.2.6 * * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) * obs-text = %x80-FF */ var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g // eslint-disable-line no-control-regex /** * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 */ var QUOTE_REGEXP = /([\\"])/g /** * RegExp to match type in RFC 7231 sec 3.1.1.1 * * media-type = type "/" subtype * type = token * subtype = token */ var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ /** * Module exports. * @public */ exports.format = format exports.parse = parse /** * Format object to media type. * * @param {object} obj * @return {string} * @public */ function format (obj) { if (!obj || typeof obj !== 'object') { throw new TypeError('argument obj is required') } var parameters = obj.parameters var type = obj.type if (!type || !TYPE_REGEXP.test(type)) { throw new TypeError('invalid type') } var string = type // append parameters if (parameters && typeof parameters === 'object') { var param var params = Object.keys(parameters).sort() for (var i = 0; i < params.length; i++) { param = params[i] if (!TOKEN_REGEXP.test(param)) { throw new TypeError('invalid parameter name') } string += '; ' + param + '=' + qstring(parameters[param]) } } return string } /** * Parse media type to object. * * @param {string|object} string * @return {Object} * @public */ function parse (string) { if (!string) { throw new TypeError('argument string is required') } // support req/res-like objects as argument var header = typeof string === 'object' ? getcontenttype(string) : string if (typeof header !== 'string') { throw new TypeError('argument string is required to be a string') } var index = header.indexOf(';') var type = index !== -1 ? header.slice(0, index).trim() : header.trim() if (!TYPE_REGEXP.test(type)) { throw new TypeError('invalid media type') } var obj = new ContentType(type.toLowerCase()) // parse parameters if (index !== -1) { var key var match var value PARAM_REGEXP.lastIndex = index while ((match = PARAM_REGEXP.exec(header))) { if (match.index !== index) { throw new TypeError('invalid parameter format') } index += match[0].length key = match[1].toLowerCase() value = match[2] if (value.charCodeAt(0) === 0x22 /* " */) { // remove quotes value = value.slice(1, -1) // remove escapes if (value.indexOf('\\') !== -1) { value = value.replace(QESC_REGEXP, '$1') } } obj.parameters[key] = value } if (index !== header.length) { throw new TypeError('invalid parameter format') } } return obj } /** * Get content-type from req/res objects. * * @param {object} * @return {Object} * @private */ function getcontenttype (obj) { var header if (typeof obj.getHeader === 'function') { // res-like header = obj.getHeader('content-type') } else if (typeof obj.headers === 'object') { // req-like header = obj.headers && obj.headers['content-type'] } if (typeof header !== 'string') { throw new TypeError('content-type header is missing from object') } return header } /** * Quote a string if necessary. * * @param {string} val * @return {string} * @private */ function qstring (val) { var str = String(val) // no need to quote tokens if (TOKEN_REGEXP.test(str)) { return str } if (str.length > 0 && !TEXT_REGEXP.test(str)) { throw new TypeError('invalid parameter value') } return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' } /** * Class to represent a content type. * @private */ function ContentType (type) { this.parameters = Object.create(null) this.type = type } PK ���\$n/��? �? tar/lib/parse.jsnu �[��� 'use strict' // this[BUFFER] is the remainder of a chunk if we're waiting for // the full 512 bytes of a header to come in. We will Buffer.concat() // it to the next write(), which is a mem copy, but a small one. // // this[QUEUE] is a Yallist of entries that haven't been emitted // yet this can only get filled up if the user keeps write()ing after // a write() returns false, or does a write() with more than one entry // // We don't buffer chunks, we always parse them and either create an // entry, or push it into the active entry. The ReadEntry class knows // to throw data away if .ignore=true // // Shift entry off the buffer when it emits 'end', and emit 'entry' for // the next one in the list. // // At any time, we're pushing body chunks into the entry at WRITEENTRY, // and waiting for 'end' on the entry at READENTRY // // ignored entries get .resume() called on them straight away const warner = require('./warn-mixin.js') const Header = require('./header.js') const EE = require('events') const Yallist = require('yallist') const maxMetaEntrySize = 1024 * 1024 const Entry = require('./read-entry.js') const Pax = require('./pax.js') const zlib = require('minizlib') const { nextTick } = require('process') const gzipHeader = Buffer.from([0x1f, 0x8b]) const STATE = Symbol('state') const WRITEENTRY = Symbol('writeEntry') const READENTRY = Symbol('readEntry') const NEXTENTRY = Symbol('nextEntry') const PROCESSENTRY = Symbol('processEntry') const EX = Symbol('extendedHeader') const GEX = Symbol('globalExtendedHeader') const META = Symbol('meta') const EMITMETA = Symbol('emitMeta') const BUFFER = Symbol('buffer') const QUEUE = Symbol('queue') const ENDED = Symbol('ended') const EMITTEDEND = Symbol('emittedEnd') const EMIT = Symbol('emit') const UNZIP = Symbol('unzip') const CONSUMECHUNK = Symbol('consumeChunk') const CONSUMECHUNKSUB = Symbol('consumeChunkSub') const CONSUMEBODY = Symbol('consumeBody') const CONSUMEMETA = Symbol('consumeMeta') const CONSUMEHEADER = Symbol('consumeHeader') const CONSUMING = Symbol('consuming') const BUFFERCONCAT = Symbol('bufferConcat') const MAYBEEND = Symbol('maybeEnd') const WRITING = Symbol('writing') const ABORTED = Symbol('aborted') const DONE = Symbol('onDone') const SAW_VALID_ENTRY = Symbol('sawValidEntry') const SAW_NULL_BLOCK = Symbol('sawNullBlock') const SAW_EOF = Symbol('sawEOF') const CLOSESTREAM = Symbol('closeStream') const noop = _ => true module.exports = warner(class Parser extends EE { constructor (opt) { opt = opt || {} super(opt) this.file = opt.file || '' // set to boolean false when an entry starts. 1024 bytes of \0 // is technically a valid tarball, albeit a boring one. this[SAW_VALID_ENTRY] = null // these BADARCHIVE errors can't be detected early. listen on DONE. this.on(DONE, _ => { if (this[STATE] === 'begin' || this[SAW_VALID_ENTRY] === false) { // either less than 1 block of data, or all entries were invalid. // Either way, probably not even a tarball. this.warn('TAR_BAD_ARCHIVE', 'Unrecognized archive format') } }) if (opt.ondone) { this.on(DONE, opt.ondone) } else { this.on(DONE, _ => { this.emit('prefinish') this.emit('finish') this.emit('end') }) } this.strict = !!opt.strict this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize this.filter = typeof opt.filter === 'function' ? opt.filter : noop // Unlike gzip, brotli doesn't have any magic bytes to identify it // Users need to explicitly tell us they're extracting a brotli file // Or we infer from the file extension const isTBR = (opt.file && ( opt.file.endsWith('.tar.br') || opt.file.endsWith('.tbr'))) // if it's a tbr file it MIGHT be brotli, but we don't know until // we look at it and verify it's not a valid tar file. this.brotli = !opt.gzip && opt.brotli !== undefined ? opt.brotli : isTBR ? undefined : false // have to set this so that streams are ok piping into it this.writable = true this.readable = false this[QUEUE] = new Yallist() this[BUFFER] = null this[READENTRY] = null this[WRITEENTRY] = null this[STATE] = 'begin' this[META] = '' this[EX] = null this[GEX] = null this[ENDED] = false this[UNZIP] = null this[ABORTED] = false this[SAW_NULL_BLOCK] = false this[SAW_EOF] = false this.on('end', () => this[CLOSESTREAM]()) if (typeof opt.onwarn === 'function') { this.on('warn', opt.onwarn) } if (typeof opt.onentry === 'function') { this.on('entry', opt.onentry) } } [CONSUMEHEADER] (chunk, position) { if (this[SAW_VALID_ENTRY] === null) { this[SAW_VALID_ENTRY] = false } let header try { header = new Header(chunk, position, this[EX], this[GEX]) } catch (er) { return this.warn('TAR_ENTRY_INVALID', er) } if (header.nullBlock) { if (this[SAW_NULL_BLOCK]) { this[SAW_EOF] = true // ending an archive with no entries. pointless, but legal. if (this[STATE] === 'begin') { this[STATE] = 'header' } this[EMIT]('eof') } else { this[SAW_NULL_BLOCK] = true this[EMIT]('nullBlock') } } else { this[SAW_NULL_BLOCK] = false if (!header.cksumValid) { this.warn('TAR_ENTRY_INVALID', 'checksum failure', { header }) } else if (!header.path) { this.warn('TAR_ENTRY_INVALID', 'path is required', { header }) } else { const type = header.type if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) { this.warn('TAR_ENTRY_INVALID', 'linkpath required', { header }) } else if (!/^(Symbolic)?Link$/.test(type) && header.linkpath) { this.warn('TAR_ENTRY_INVALID', 'linkpath forbidden', { header }) } else { const entry = this[WRITEENTRY] = new Entry(header, this[EX], this[GEX]) // we do this for meta & ignored entries as well, because they // are still valid tar, or else we wouldn't know to ignore them if (!this[SAW_VALID_ENTRY]) { if (entry.remain) { // this might be the one! const onend = () => { if (!entry.invalid) { this[SAW_VALID_ENTRY] = true } } entry.on('end', onend) } else { this[SAW_VALID_ENTRY] = true } } if (entry.meta) { if (entry.size > this.maxMetaEntrySize) { entry.ignore = true this[EMIT]('ignoredEntry', entry) this[STATE] = 'ignore' entry.resume() } else if (entry.size > 0) { this[META] = '' entry.on('data', c => this[META] += c) this[STATE] = 'meta' } } else { this[EX] = null entry.ignore = entry.ignore || !this.filter(entry.path, entry) if (entry.ignore) { // probably valid, just not something we care about this[EMIT]('ignoredEntry', entry) this[STATE] = entry.remain ? 'ignore' : 'header' entry.resume() } else { if (entry.remain) { this[STATE] = 'body' } else { this[STATE] = 'header' entry.end() } if (!this[READENTRY]) { this[QUEUE].push(entry) this[NEXTENTRY]() } else { this[QUEUE].push(entry) } } } } } } } [CLOSESTREAM] () { nextTick(() => this.emit('close')) } [PROCESSENTRY] (entry) { let go = true if (!entry) { this[READENTRY] = null go = false } else if (Array.isArray(entry)) { this.emit.apply(this, entry) } else { this[READENTRY] = entry this.emit('entry', entry) if (!entry.emittedEnd) { entry.on('end', _ => this[NEXTENTRY]()) go = false } } return go } [NEXTENTRY] () { do {} while (this[PROCESSENTRY](this[QUEUE].shift())) if (!this[QUEUE].length) { // At this point, there's nothing in the queue, but we may have an // entry which is being consumed (readEntry). // If we don't, then we definitely can handle more data. // If we do, and either it's flowing, or it has never had any data // written to it, then it needs more. // The only other possibility is that it has returned false from a // write() call, so we wait for the next drain to continue. const re = this[READENTRY] const drainNow = !re || re.flowing || re.size === re.remain if (drainNow) { if (!this[WRITING]) { this.emit('drain') } } else { re.once('drain', _ => this.emit('drain')) } } } [CONSUMEBODY] (chunk, position) { // write up to but no more than writeEntry.blockRemain const entry = this[WRITEENTRY] const br = entry.blockRemain const c = (br >= chunk.length && position === 0) ? chunk : chunk.slice(position, position + br) entry.write(c) if (!entry.blockRemain) { this[STATE] = 'header' this[WRITEENTRY] = null entry.end() } return c.length } [CONSUMEMETA] (chunk, position) { const entry = this[WRITEENTRY] const ret = this[CONSUMEBODY](chunk, position) // if we finished, then the entry is reset if (!this[WRITEENTRY]) { this[EMITMETA](entry) } return ret } [EMIT] (ev, data, extra) { if (!this[QUEUE].length && !this[READENTRY]) { this.emit(ev, data, extra) } else { this[QUEUE].push([ev, data, extra]) } } [EMITMETA] (entry) { this[EMIT]('meta', this[META]) switch (entry.type) { case 'ExtendedHeader': case 'OldExtendedHeader': this[EX] = Pax.parse(this[META], this[EX], false) break case 'GlobalExtendedHeader': this[GEX] = Pax.parse(this[META], this[GEX], true) break case 'NextFileHasLongPath': case 'OldGnuLongPath': this[EX] = this[EX] || Object.create(null) this[EX].path = this[META].replace(/\0.*/, '') break case 'NextFileHasLongLinkpath': this[EX] = this[EX] || Object.create(null) this[EX].linkpath = this[META].replace(/\0.*/, '') break /* istanbul ignore next */ default: throw new Error('unknown meta: ' + entry.type) } } abort (error) { this[ABORTED] = true this.emit('abort', error) // always throws, even in non-strict mode this.warn('TAR_ABORT', error, { recoverable: false }) } write (chunk) { if (this[ABORTED]) { return } // first write, might be gzipped const needSniff = this[UNZIP] === null || this.brotli === undefined && this[UNZIP] === false if (needSniff && chunk) { if (this[BUFFER]) { chunk = Buffer.concat([this[BUFFER], chunk]) this[BUFFER] = null } if (chunk.length < gzipHeader.length) { this[BUFFER] = chunk return true } // look for gzip header for (let i = 0; this[UNZIP] === null && i < gzipHeader.length; i++) { if (chunk[i] !== gzipHeader[i]) { this[UNZIP] = false } } const maybeBrotli = this.brotli === undefined if (this[UNZIP] === false && maybeBrotli) { // read the first header to see if it's a valid tar file. If so, // we can safely assume that it's not actually brotli, despite the // .tbr or .tar.br file extension. // if we ended before getting a full chunk, yes, def brotli if (chunk.length < 512) { if (this[ENDED]) { this.brotli = true } else { this[BUFFER] = chunk return true } } else { // if it's tar, it's pretty reliably not brotli, chances of // that happening are astronomical. try { new Header(chunk.slice(0, 512)) this.brotli = false } catch (_) { this.brotli = true } } } if (this[UNZIP] === null || (this[UNZIP] === false && this.brotli)) { const ended = this[ENDED] this[ENDED] = false this[UNZIP] = this[UNZIP] === null ? new zlib.Unzip() : new zlib.BrotliDecompress() this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)) this[UNZIP].on('error', er => this.abort(er)) this[UNZIP].on('end', _ => { this[ENDED] = true this[CONSUMECHUNK]() }) this[WRITING] = true const ret = this[UNZIP][ended ? 'end' : 'write'](chunk) this[WRITING] = false return ret } } this[WRITING] = true if (this[UNZIP]) { this[UNZIP].write(chunk) } else { this[CONSUMECHUNK](chunk) } this[WRITING] = false // return false if there's a queue, or if the current entry isn't flowing const ret = this[QUEUE].length ? false : this[READENTRY] ? this[READENTRY].flowing : true // if we have no queue, then that means a clogged READENTRY if (!ret && !this[QUEUE].length) { this[READENTRY].once('drain', _ => this.emit('drain')) } return ret } [BUFFERCONCAT] (c) { if (c && !this[ABORTED]) { this[BUFFER] = this[BUFFER] ? Buffer.concat([this[BUFFER], c]) : c } } [MAYBEEND] () { if (this[ENDED] && !this[EMITTEDEND] && !this[ABORTED] && !this[CONSUMING]) { this[EMITTEDEND] = true const entry = this[WRITEENTRY] if (entry && entry.blockRemain) { // truncated, likely a damaged file const have = this[BUFFER] ? this[BUFFER].length : 0 this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${ entry.blockRemain} more bytes, only ${have} available)`, { entry }) if (this[BUFFER]) { entry.write(this[BUFFER]) } entry.end() } this[EMIT](DONE) } } [CONSUMECHUNK] (chunk) { if (this[CONSUMING]) { this[BUFFERCONCAT](chunk) } else if (!chunk && !this[BUFFER]) { this[MAYBEEND]() } else { this[CONSUMING] = true if (this[BUFFER]) { this[BUFFERCONCAT](chunk) const c = this[BUFFER] this[BUFFER] = null this[CONSUMECHUNKSUB](c) } else { this[CONSUMECHUNKSUB](chunk) } while (this[BUFFER] && this[BUFFER].length >= 512 && !this[ABORTED] && !this[SAW_EOF]) { const c = this[BUFFER] this[BUFFER] = null this[CONSUMECHUNKSUB](c) } this[CONSUMING] = false } if (!this[BUFFER] || this[ENDED]) { this[MAYBEEND]() } } [CONSUMECHUNKSUB] (chunk) { // we know that we are in CONSUMING mode, so anything written goes into // the buffer. Advance the position and put any remainder in the buffer. let position = 0 const length = chunk.length while (position + 512 <= length && !this[ABORTED] && !this[SAW_EOF]) { switch (this[STATE]) { case 'begin': case 'header': this[CONSUMEHEADER](chunk, position) position += 512 break case 'ignore': case 'body': position += this[CONSUMEBODY](chunk, position) break case 'meta': position += this[CONSUMEMETA](chunk, position) break /* istanbul ignore next */ default: throw new Error('invalid state: ' + this[STATE]) } } if (position < length) { if (this[BUFFER]) { this[BUFFER] = Buffer.concat([chunk.slice(position), this[BUFFER]]) } else { this[BUFFER] = chunk.slice(position) } } } end (chunk) { if (!this[ABORTED]) { if (this[UNZIP]) { this[UNZIP].end(chunk) } else { this[ENDED] = true if (this.brotli === undefined) chunk = chunk || Buffer.alloc(0) this.write(chunk) } } } }) PK ���\���; �; tar/lib/write-entry.jsnu �[��� 'use strict' const { Minipass } = require('minipass') const Pax = require('./pax.js') const Header = require('./header.js') const fs = require('fs') const path = require('path') const normPath = require('./normalize-windows-path.js') const stripSlash = require('./strip-trailing-slashes.js') const prefixPath = (path, prefix) => { if (!prefix) { return normPath(path) } path = normPath(path).replace(/^\.(\/|$)/, '') return stripSlash(prefix) + '/' + path } const maxReadSize = 16 * 1024 * 1024 const PROCESS = Symbol('process') const FILE = Symbol('file') const DIRECTORY = Symbol('directory') const SYMLINK = Symbol('symlink') const HARDLINK = Symbol('hardlink') const HEADER = Symbol('header') const READ = Symbol('read') const LSTAT = Symbol('lstat') const ONLSTAT = Symbol('onlstat') const ONREAD = Symbol('onread') const ONREADLINK = Symbol('onreadlink') const OPENFILE = Symbol('openfile') const ONOPENFILE = Symbol('onopenfile') const CLOSE = Symbol('close') const MODE = Symbol('mode') const AWAITDRAIN = Symbol('awaitDrain') const ONDRAIN = Symbol('ondrain') const PREFIX = Symbol('prefix') const HAD_ERROR = Symbol('hadError') const warner = require('./warn-mixin.js') const winchars = require('./winchars.js') const stripAbsolutePath = require('./strip-absolute-path.js') const modeFix = require('./mode-fix.js') const WriteEntry = warner(class WriteEntry extends Minipass { constructor (p, opt) { opt = opt || {} super(opt) if (typeof p !== 'string') { throw new TypeError('path is required') } this.path = normPath(p) // suppress atime, ctime, uid, gid, uname, gname this.portable = !!opt.portable // until node has builtin pwnam functions, this'll have to do this.myuid = process.getuid && process.getuid() || 0 this.myuser = process.env.USER || '' this.maxReadSize = opt.maxReadSize || maxReadSize this.linkCache = opt.linkCache || new Map() this.statCache = opt.statCache || new Map() this.preservePaths = !!opt.preservePaths this.cwd = normPath(opt.cwd || process.cwd()) this.strict = !!opt.strict this.noPax = !!opt.noPax this.noMtime = !!opt.noMtime this.mtime = opt.mtime || null this.prefix = opt.prefix ? normPath(opt.prefix) : null this.fd = null this.blockLen = null this.blockRemain = null this.buf = null this.offset = null this.length = null this.pos = null this.remain = null if (typeof opt.onwarn === 'function') { this.on('warn', opt.onwarn) } let pathWarn = false if (!this.preservePaths) { const [root, stripped] = stripAbsolutePath(this.path) if (root) { this.path = stripped pathWarn = root } } this.win32 = !!opt.win32 || process.platform === 'win32' if (this.win32) { // force the \ to / normalization, since we might not *actually* // be on windows, but want \ to be considered a path separator. this.path = winchars.decode(this.path.replace(/\\/g, '/')) p = p.replace(/\\/g, '/') } this.absolute = normPath(opt.absolute || path.resolve(this.cwd, p)) if (this.path === '') { this.path = './' } if (pathWarn) { this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { entry: this, path: pathWarn + this.path, }) } if (this.statCache.has(this.absolute)) { this[ONLSTAT](this.statCache.get(this.absolute)) } else { this[LSTAT]() } } emit (ev, ...data) { if (ev === 'error') { this[HAD_ERROR] = true } return super.emit(ev, ...data) } [LSTAT] () { fs.lstat(this.absolute, (er, stat) => { if (er) { return this.emit('error', er) } this[ONLSTAT](stat) }) } [ONLSTAT] (stat) { this.statCache.set(this.absolute, stat) this.stat = stat if (!stat.isFile()) { stat.size = 0 } this.type = getType(stat) this.emit('stat', stat) this[PROCESS]() } [PROCESS] () { switch (this.type) { case 'File': return this[FILE]() case 'Directory': return this[DIRECTORY]() case 'SymbolicLink': return this[SYMLINK]() // unsupported types are ignored. default: return this.end() } } [MODE] (mode) { return modeFix(mode, this.type === 'Directory', this.portable) } [PREFIX] (path) { return prefixPath(path, this.prefix) } [HEADER] () { if (this.type === 'Directory' && this.portable) { this.noMtime = true } this.header = new Header({ path: this[PREFIX](this.path), // only apply the prefix to hard links. linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) : this.linkpath, // only the permissions and setuid/setgid/sticky bitflags // not the higher-order bits that specify file type mode: this[MODE](this.stat.mode), uid: this.portable ? null : this.stat.uid, gid: this.portable ? null : this.stat.gid, size: this.stat.size, mtime: this.noMtime ? null : this.mtime || this.stat.mtime, type: this.type, uname: this.portable ? null : this.stat.uid === this.myuid ? this.myuser : '', atime: this.portable ? null : this.stat.atime, ctime: this.portable ? null : this.stat.ctime, }) if (this.header.encode() && !this.noPax) { super.write(new Pax({ atime: this.portable ? null : this.header.atime, ctime: this.portable ? null : this.header.ctime, gid: this.portable ? null : this.header.gid, mtime: this.noMtime ? null : this.mtime || this.header.mtime, path: this[PREFIX](this.path), linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) : this.linkpath, size: this.header.size, uid: this.portable ? null : this.header.uid, uname: this.portable ? null : this.header.uname, dev: this.portable ? null : this.stat.dev, ino: this.portable ? null : this.stat.ino, nlink: this.portable ? null : this.stat.nlink, }).encode()) } super.write(this.header.block) } [DIRECTORY] () { if (this.path.slice(-1) !== '/') { this.path += '/' } this.stat.size = 0 this[HEADER]() this.end() } [SYMLINK] () { fs.readlink(this.absolute, (er, linkpath) => { if (er) { return this.emit('error', er) } this[ONREADLINK](linkpath) }) } [ONREADLINK] (linkpath) { this.linkpath = normPath(linkpath) this[HEADER]() this.end() } [HARDLINK] (linkpath) { this.type = 'Link' this.linkpath = normPath(path.relative(this.cwd, linkpath)) this.stat.size = 0 this[HEADER]() this.end() } [FILE] () { if (this.stat.nlink > 1) { const linkKey = this.stat.dev + ':' + this.stat.ino if (this.linkCache.has(linkKey)) { const linkpath = this.linkCache.get(linkKey) if (linkpath.indexOf(this.cwd) === 0) { return this[HARDLINK](linkpath) } } this.linkCache.set(linkKey, this.absolute) } this[HEADER]() if (this.stat.size === 0) { return this.end() } this[OPENFILE]() } [OPENFILE] () { fs.open(this.absolute, 'r', (er, fd) => { if (er) { return this.emit('error', er) } this[ONOPENFILE](fd) }) } [ONOPENFILE] (fd) { this.fd = fd if (this[HAD_ERROR]) { return this[CLOSE]() } this.blockLen = 512 * Math.ceil(this.stat.size / 512) this.blockRemain = this.blockLen const bufLen = Math.min(this.blockLen, this.maxReadSize) this.buf = Buffer.allocUnsafe(bufLen) this.offset = 0 this.pos = 0 this.remain = this.stat.size this.length = this.buf.length this[READ]() } [READ] () { const { fd, buf, offset, length, pos } = this fs.read(fd, buf, offset, length, pos, (er, bytesRead) => { if (er) { // ignoring the error from close(2) is a bad practice, but at // this point we already have an error, don't need another one return this[CLOSE](() => this.emit('error', er)) } this[ONREAD](bytesRead) }) } [CLOSE] (cb) { fs.close(this.fd, cb) } [ONREAD] (bytesRead) { if (bytesRead <= 0 && this.remain > 0) { const er = new Error('encountered unexpected EOF') er.path = this.absolute er.syscall = 'read' er.code = 'EOF' return this[CLOSE](() => this.emit('error', er)) } if (bytesRead > this.remain) { const er = new Error('did not encounter expected EOF') er.path = this.absolute er.syscall = 'read' er.code = 'EOF' return this[CLOSE](() => this.emit('error', er)) } // null out the rest of the buffer, if we could fit the block padding // at the end of this loop, we've incremented bytesRead and this.remain // to be incremented up to the blockRemain level, as if we had expected // to get a null-padded file, and read it until the end. then we will // decrement both remain and blockRemain by bytesRead, and know that we // reached the expected EOF, without any null buffer to append. if (bytesRead === this.remain) { for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) { this.buf[i + this.offset] = 0 bytesRead++ this.remain++ } } const writeBuf = this.offset === 0 && bytesRead === this.buf.length ? this.buf : this.buf.slice(this.offset, this.offset + bytesRead) const flushed = this.write(writeBuf) if (!flushed) { this[AWAITDRAIN](() => this[ONDRAIN]()) } else { this[ONDRAIN]() } } [AWAITDRAIN] (cb) { this.once('drain', cb) } write (writeBuf) { if (this.blockRemain < writeBuf.length) { const er = new Error('writing more data than expected') er.path = this.absolute return this.emit('error', er) } this.remain -= writeBuf.length this.blockRemain -= writeBuf.length this.pos += writeBuf.length this.offset += writeBuf.length return super.write(writeBuf) } [ONDRAIN] () { if (!this.remain) { if (this.blockRemain) { super.write(Buffer.alloc(this.blockRemain)) } return this[CLOSE](er => er ? this.emit('error', er) : this.end()) } if (this.offset >= this.length) { // if we only have a smaller bit left to read, alloc a smaller buffer // otherwise, keep it the same length it was before. this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length)) this.offset = 0 } this.length = this.buf.length - this.offset this[READ]() } }) class WriteEntrySync extends WriteEntry { [LSTAT] () { this[ONLSTAT](fs.lstatSync(this.absolute)) } [SYMLINK] () { this[ONREADLINK](fs.readlinkSync(this.absolute)) } [OPENFILE] () { this[ONOPENFILE](fs.openSync(this.absolute, 'r')) } [READ] () { let threw = true try { const { fd, buf, offset, length, pos } = this const bytesRead = fs.readSync(fd, buf, offset, length, pos) this[ONREAD](bytesRead) threw = false } finally { // ignoring the error from close(2) is a bad practice, but at // this point we already have an error, don't need another one if (threw) { try { this[CLOSE](() => {}) } catch (er) {} } } } [AWAITDRAIN] (cb) { cb() } [CLOSE] (cb) { fs.closeSync(this.fd) cb() } } const WriteEntryTar = warner(class WriteEntryTar extends Minipass { constructor (readEntry, opt) { opt = opt || {} super(opt) this.preservePaths = !!opt.preservePaths this.portable = !!opt.portable this.strict = !!opt.strict this.noPax = !!opt.noPax this.noMtime = !!opt.noMtime this.readEntry = readEntry this.type = readEntry.type if (this.type === 'Directory' && this.portable) { this.noMtime = true } this.prefix = opt.prefix || null this.path = normPath(readEntry.path) this.mode = this[MODE](readEntry.mode) this.uid = this.portable ? null : readEntry.uid this.gid = this.portable ? null : readEntry.gid this.uname = this.portable ? null : readEntry.uname this.gname = this.portable ? null : readEntry.gname this.size = readEntry.size this.mtime = this.noMtime ? null : opt.mtime || readEntry.mtime this.atime = this.portable ? null : readEntry.atime this.ctime = this.portable ? null : readEntry.ctime this.linkpath = normPath(readEntry.linkpath) if (typeof opt.onwarn === 'function') { this.on('warn', opt.onwarn) } let pathWarn = false if (!this.preservePaths) { const [root, stripped] = stripAbsolutePath(this.path) if (root) { this.path = stripped pathWarn = root } } this.remain = readEntry.size this.blockRemain = readEntry.startBlockSize this.header = new Header({ path: this[PREFIX](this.path), linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) : this.linkpath, // only the permissions and setuid/setgid/sticky bitflags // not the higher-order bits that specify file type mode: this.mode, uid: this.portable ? null : this.uid, gid: this.portable ? null : this.gid, size: this.size, mtime: this.noMtime ? null : this.mtime, type: this.type, uname: this.portable ? null : this.uname, atime: this.portable ? null : this.atime, ctime: this.portable ? null : this.ctime, }) if (pathWarn) { this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { entry: this, path: pathWarn + this.path, }) } if (this.header.encode() && !this.noPax) { super.write(new Pax({ atime: this.portable ? null : this.atime, ctime: this.portable ? null : this.ctime, gid: this.portable ? null : this.gid, mtime: this.noMtime ? null : this.mtime, path: this[PREFIX](this.path), linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) : this.linkpath, size: this.size, uid: this.portable ? null : this.uid, uname: this.portable ? null : this.uname, dev: this.portable ? null : this.readEntry.dev, ino: this.portable ? null : this.readEntry.ino, nlink: this.portable ? null : this.readEntry.nlink, }).encode()) } super.write(this.header.block) readEntry.pipe(this) } [PREFIX] (path) { return prefixPath(path, this.prefix) } [MODE] (mode) { return modeFix(mode, this.type === 'Directory', this.portable) } write (data) { const writeLen = data.length if (writeLen > this.blockRemain) { throw new Error('writing more to entry than is appropriate') } this.blockRemain -= writeLen return super.write(data) } end () { if (this.blockRemain) { super.write(Buffer.alloc(this.blockRemain)) } return super.end() } }) WriteEntry.Sync = WriteEntrySync WriteEntry.Tar = WriteEntryTar const getType = stat => stat.isFile() ? 'File' : stat.isDirectory() ? 'Directory' : stat.isSymbolicLink() ? 'SymbolicLink' : 'Unsupported' module.exports = WriteEntry PK ���\�n]�� � tar/lib/pax.jsnu �[��� 'use strict' const Header = require('./header.js') const path = require('path') class Pax { constructor (obj, global) { this.atime = obj.atime || null this.charset = obj.charset || null this.comment = obj.comment || null this.ctime = obj.ctime || null this.gid = obj.gid || null this.gname = obj.gname || null this.linkpath = obj.linkpath || null this.mtime = obj.mtime || null this.path = obj.path || null this.size = obj.size || null this.uid = obj.uid || null this.uname = obj.uname || null this.dev = obj.dev || null this.ino = obj.ino || null this.nlink = obj.nlink || null this.global = global || false } encode () { const body = this.encodeBody() if (body === '') { return null } const bodyLen = Buffer.byteLength(body) // round up to 512 bytes // add 512 for header const bufLen = 512 * Math.ceil(1 + bodyLen / 512) const buf = Buffer.allocUnsafe(bufLen) // 0-fill the header section, it might not hit every field for (let i = 0; i < 512; i++) { buf[i] = 0 } new Header({ // XXX split the path // then the path should be PaxHeader + basename, but less than 99, // prepend with the dirname path: ('PaxHeader/' + path.basename(this.path)).slice(0, 99), mode: this.mode || 0o644, uid: this.uid || null, gid: this.gid || null, size: bodyLen, mtime: this.mtime || null, type: this.global ? 'GlobalExtendedHeader' : 'ExtendedHeader', linkpath: '', uname: this.uname || '', gname: this.gname || '', devmaj: 0, devmin: 0, atime: this.atime || null, ctime: this.ctime || null, }).encode(buf) buf.write(body, 512, bodyLen, 'utf8') // null pad after the body for (let i = bodyLen + 512; i < buf.length; i++) { buf[i] = 0 } return buf } encodeBody () { return ( this.encodeField('path') + this.encodeField('ctime') + this.encodeField('atime') + this.encodeField('dev') + this.encodeField('ino') + this.encodeField('nlink') + this.encodeField('charset') + this.encodeField('comment') + this.encodeField('gid') + this.encodeField('gname') + this.encodeField('linkpath') + this.encodeField('mtime') + this.encodeField('size') + this.encodeField('uid') + this.encodeField('uname') ) } encodeField (field) { if (this[field] === null || this[field] === undefined) { return '' } const v = this[field] instanceof Date ? this[field].getTime() / 1000 : this[field] const s = ' ' + (field === 'dev' || field === 'ino' || field === 'nlink' ? 'SCHILY.' : '') + field + '=' + v + '\n' const byteLen = Buffer.byteLength(s) // the digits includes the length of the digits in ascii base-10 // so if it's 9 characters, then adding 1 for the 9 makes it 10 // which makes it 11 chars. let digits = Math.floor(Math.log(byteLen) / Math.log(10)) + 1 if (byteLen + digits >= Math.pow(10, digits)) { digits += 1 } const len = digits + byteLen return len + s } } Pax.parse = (string, ex, g) => new Pax(merge(parseKV(string), ex), g) const merge = (a, b) => b ? Object.keys(a).reduce((s, k) => (s[k] = a[k], s), b) : a const parseKV = string => string .replace(/\n$/, '') .split('\n') .reduce(parseKVLine, Object.create(null)) const parseKVLine = (set, line) => { const n = parseInt(line, 10) // XXX Values with \n in them will fail this. // Refactor to not be a naive line-by-line parse. if (n !== Buffer.byteLength(line) + 1) { return set } line = line.slice((n + ' ').length) const kv = line.split('=') const k = kv.shift().replace(/^SCHILY\.(dev|ino|nlink)/, '$1') if (!k) { return set } const v = kv.join('=') set[k] = /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ? new Date(v * 1000) : /^[0-9]+$/.test(v) ? +v : v return set } module.exports = Pax PK ���\���$$ $ tar/lib/extract.jsnu �[��� 'use strict' // tar -x const hlo = require('./high-level-opt.js') const Unpack = require('./unpack.js') const fs = require('fs') const fsm = require('fs-minipass') const path = require('path') const stripSlash = require('./strip-trailing-slashes.js') module.exports = (opt_, files, cb) => { if (typeof opt_ === 'function') { cb = opt_, files = null, opt_ = {} } else if (Array.isArray(opt_)) { files = opt_, opt_ = {} } if (typeof files === 'function') { cb = files, files = null } if (!files) { files = [] } else { files = Array.from(files) } const opt = hlo(opt_) if (opt.sync && typeof cb === 'function') { throw new TypeError('callback not supported for sync tar functions') } if (!opt.file && typeof cb === 'function') { throw new TypeError('callback only supported with file option') } if (files.length) { filesFilter(opt, files) } return opt.file && opt.sync ? extractFileSync(opt) : opt.file ? extractFile(opt, cb) : opt.sync ? extractSync(opt) : extract(opt) } // construct a filter that limits the file entries listed // include child entries if a dir is included const filesFilter = (opt, files) => { const map = new Map(files.map(f => [stripSlash(f), true])) const filter = opt.filter const mapHas = (file, r) => { const root = r || path.parse(file).root || '.' const ret = file === root ? false : map.has(file) ? map.get(file) : mapHas(path.dirname(file), root) map.set(file, ret) return ret } opt.filter = filter ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file)) : file => mapHas(stripSlash(file)) } const extractFileSync = opt => { const u = new Unpack.Sync(opt) const file = opt.file const stat = fs.statSync(file) // This trades a zero-byte read() syscall for a stat // However, it will usually result in less memory allocation const readSize = opt.maxReadSize || 16 * 1024 * 1024 const stream = new fsm.ReadStreamSync(file, { readSize: readSize, size: stat.size, }) stream.pipe(u) } const extractFile = (opt, cb) => { const u = new Unpack(opt) const readSize = opt.maxReadSize || 16 * 1024 * 1024 const file = opt.file const p = new Promise((resolve, reject) => { u.on('error', reject) u.on('close', resolve) // This trades a zero-byte read() syscall for a stat // However, it will usually result in less memory allocation fs.stat(file, (er, stat) => { if (er) { reject(er) } else { const stream = new fsm.ReadStream(file, { readSize: readSize, size: stat.size, }) stream.on('error', reject) stream.pipe(u) } }) }) return cb ? p.then(cb, cb) : p } const extractSync = opt => new Unpack.Sync(opt) const extract = opt => new Unpack(opt) PK ���\�� � ! tar/lib/normalize-windows-path.jsnu �[��� // on windows, either \ or / are valid directory separators. // on unix, \ is a valid character in filenames. // so, on windows, and only on windows, we replace all \ chars with /, // so that we can use / as our one and only directory separator char. const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform module.exports = platform !== 'win32' ? p => p : p => p && p.replace(/\\/g, '/') PK ���\�$H H tar/lib/types.jsnu �[��� 'use strict' // map types from key to human-friendly name exports.name = new Map([ ['0', 'File'], // same as File ['', 'OldFile'], ['1', 'Link'], ['2', 'SymbolicLink'], // Devices and FIFOs aren't fully supported // they are parsed, but skipped when unpacking ['3', 'CharacterDevice'], ['4', 'BlockDevice'], ['5', 'Directory'], ['6', 'FIFO'], // same as File ['7', 'ContiguousFile'], // pax headers ['g', 'GlobalExtendedHeader'], ['x', 'ExtendedHeader'], // vendor-specific stuff // skip ['A', 'SolarisACL'], // like 5, but with data, which should be skipped ['D', 'GNUDumpDir'], // metadata only, skip ['I', 'Inode'], // data = link path of next file ['K', 'NextFileHasLongLinkpath'], // data = path of next file ['L', 'NextFileHasLongPath'], // skip ['M', 'ContinuationFile'], // like L ['N', 'OldGnuLongPath'], // skip ['S', 'SparseFile'], // skip ['V', 'TapeVolumeHeader'], // like x ['X', 'OldExtendedHeader'], ]) // map the other direction exports.code = new Map(Array.from(exports.name).map(kv => [kv[1], kv[0]])) PK ���\��'� � ! tar/lib/strip-trailing-slashes.jsnu �[��� // warning: extremely hot code path. // This has been meticulously optimized for use // within npm install on large package trees. // Do not edit without careful benchmarking. module.exports = str => { let i = str.length - 1 let slashesStart = -1 while (i > -1 && str.charAt(i) === '/') { slashesStart = i i-- } return slashesStart === -1 ? str : str.slice(0, slashesStart) } PK ���\��[ [ tar/lib/create.jsnu �[��� 'use strict' // tar -c const hlo = require('./high-level-opt.js') const Pack = require('./pack.js') const fsm = require('fs-minipass') const t = require('./list.js') const path = require('path') module.exports = (opt_, files, cb) => { if (typeof files === 'function') { cb = files } if (Array.isArray(opt_)) { files = opt_, opt_ = {} } if (!files || !Array.isArray(files) || !files.length) { throw new TypeError('no files or directories specified') } files = Array.from(files) const opt = hlo(opt_) if (opt.sync && typeof cb === 'function') { throw new TypeError('callback not supported for sync tar functions') } if (!opt.file && typeof cb === 'function') { throw new TypeError('callback only supported with file option') } return opt.file && opt.sync ? createFileSync(opt, files) : opt.file ? createFile(opt, files, cb) : opt.sync ? createSync(opt, files) : create(opt, files) } const createFileSync = (opt, files) => { const p = new Pack.Sync(opt) const stream = new fsm.WriteStreamSync(opt.file, { mode: opt.mode || 0o666, }) p.pipe(stream) addFilesSync(p, files) } const createFile = (opt, files, cb) => { const p = new Pack(opt) const stream = new fsm.WriteStream(opt.file, { mode: opt.mode || 0o666, }) p.pipe(stream) const promise = new Promise((res, rej) => { stream.on('error', rej) stream.on('close', res) p.on('error', rej) }) addFilesAsync(p, files) return cb ? promise.then(cb, cb) : promise } const addFilesSync = (p, files) => { files.forEach(file => { if (file.charAt(0) === '@') { t({ file: path.resolve(p.cwd, file.slice(1)), sync: true, noResume: true, onentry: entry => p.add(entry), }) } else { p.add(file) } }) p.end() } const addFilesAsync = (p, files) => { while (files.length) { const file = files.shift() if (file.charAt(0) === '@') { return t({ file: path.resolve(p.cwd, file.slice(1)), noResume: true, onentry: entry => p.add(entry), }).then(_ => addFilesAsync(p, files)) } else { p.add(file) } } p.end() } const createSync = (opt, files) => { const p = new Pack.Sync(opt) addFilesSync(p, files) return p } const create = (opt, files) => { const p = new Pack(opt) addFilesAsync(p, files) return p } PK ���\ʊ� � tar/lib/high-level-opt.jsnu �[��� 'use strict' // turn tar(1) style args like `C` into the more verbose things like `cwd` const argmap = new Map([ ['C', 'cwd'], ['f', 'file'], ['z', 'gzip'], ['P', 'preservePaths'], ['U', 'unlink'], ['strip-components', 'strip'], ['stripComponents', 'strip'], ['keep-newer', 'newer'], ['keepNewer', 'newer'], ['keep-newer-files', 'newer'], ['keepNewerFiles', 'newer'], ['k', 'keep'], ['keep-existing', 'keep'], ['keepExisting', 'keep'], ['m', 'noMtime'], ['no-mtime', 'noMtime'], ['p', 'preserveOwner'], ['L', 'follow'], ['h', 'follow'], ]) module.exports = opt => opt ? Object.keys(opt).map(k => [ argmap.has(k) ? argmap.get(k) : k, opt[k], ]).reduce((set, kv) => (set[kv[0]] = kv[1], set), Object.create(null)) : {} PK ���\��J� � tar/lib/replace.jsnu �[��� 'use strict' // tar -r const hlo = require('./high-level-opt.js') const Pack = require('./pack.js') const fs = require('fs') const fsm = require('fs-minipass') const t = require('./list.js') const path = require('path') // starting at the head of the file, read a Header // If the checksum is invalid, that's our position to start writing // If it is, jump forward by the specified size (round up to 512) // and try again. // Write the new Pack stream starting there. const Header = require('./header.js') module.exports = (opt_, files, cb) => { const opt = hlo(opt_) if (!opt.file) { throw new TypeError('file is required') } if (opt.gzip || opt.brotli || opt.file.endsWith('.br') || opt.file.endsWith('.tbr')) { throw new TypeError('cannot append to compressed archives') } if (!files || !Array.isArray(files) || !files.length) { throw new TypeError('no files or directories specified') } files = Array.from(files) return opt.sync ? replaceSync(opt, files) : replace(opt, files, cb) } const replaceSync = (opt, files) => { const p = new Pack.Sync(opt) let threw = true let fd let position try { try { fd = fs.openSync(opt.file, 'r+') } catch (er) { if (er.code === 'ENOENT') { fd = fs.openSync(opt.file, 'w+') } else { throw er } } const st = fs.fstatSync(fd) const headBuf = Buffer.alloc(512) POSITION: for (position = 0; position < st.size; position += 512) { for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) { bytes = fs.readSync( fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos ) if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) { throw new Error('cannot append to compressed archives') } if (!bytes) { break POSITION } } const h = new Header(headBuf) if (!h.cksumValid) { break } const entryBlockSize = 512 * Math.ceil(h.size / 512) if (position + entryBlockSize + 512 > st.size) { break } // the 512 for the header we just parsed will be added as well // also jump ahead all the blocks for the body position += entryBlockSize if (opt.mtimeCache) { opt.mtimeCache.set(h.path, h.mtime) } } threw = false streamSync(opt, p, position, fd, files) } finally { if (threw) { try { fs.closeSync(fd) } catch (er) {} } } } const streamSync = (opt, p, position, fd, files) => { const stream = new fsm.WriteStreamSync(opt.file, { fd: fd, start: position, }) p.pipe(stream) addFilesSync(p, files) } const replace = (opt, files, cb) => { files = Array.from(files) const p = new Pack(opt) const getPos = (fd, size, cb_) => { const cb = (er, pos) => { if (er) { fs.close(fd, _ => cb_(er)) } else { cb_(null, pos) } } let position = 0 if (size === 0) { return cb(null, 0) } let bufPos = 0 const headBuf = Buffer.alloc(512) const onread = (er, bytes) => { if (er) { return cb(er) } bufPos += bytes if (bufPos < 512 && bytes) { return fs.read( fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos, onread ) } if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) { return cb(new Error('cannot append to compressed archives')) } // truncated header if (bufPos < 512) { return cb(null, position) } const h = new Header(headBuf) if (!h.cksumValid) { return cb(null, position) } const entryBlockSize = 512 * Math.ceil(h.size / 512) if (position + entryBlockSize + 512 > size) { return cb(null, position) } position += entryBlockSize + 512 if (position >= size) { return cb(null, position) } if (opt.mtimeCache) { opt.mtimeCache.set(h.path, h.mtime) } bufPos = 0 fs.read(fd, headBuf, 0, 512, position, onread) } fs.read(fd, headBuf, 0, 512, position, onread) } const promise = new Promise((resolve, reject) => { p.on('error', reject) let flag = 'r+' const onopen = (er, fd) => { if (er && er.code === 'ENOENT' && flag === 'r+') { flag = 'w+' return fs.open(opt.file, flag, onopen) } if (er) { return reject(er) } fs.fstat(fd, (er, st) => { if (er) { return fs.close(fd, () => reject(er)) } getPos(fd, st.size, (er, position) => { if (er) { return reject(er) } const stream = new fsm.WriteStream(opt.file, { fd: fd, start: position, }) p.pipe(stream) stream.on('error', reject) stream.on('close', resolve) addFilesAsync(p, files) }) }) } fs.open(opt.file, flag, onopen) }) return cb ? promise.then(cb, cb) : promise } const addFilesSync = (p, files) => { files.forEach(file => { if (file.charAt(0) === '@') { t({ file: path.resolve(p.cwd, file.slice(1)), sync: true, noResume: true, onentry: entry => p.add(entry), }) } else { p.add(file) } }) p.end() } const addFilesAsync = (p, files) => { while (files.length) { const file = files.shift() if (file.charAt(0) === '@') { return t({ file: path.resolve(p.cwd, file.slice(1)), noResume: true, onentry: entry => p.add(entry), }).then(_ => addFilesAsync(p, files)) } else { p.add(file) } } p.end() } PK ���\�(�� tar/lib/winchars.jsnu �[��� 'use strict' // When writing files on Windows, translate the characters to their // 0xf000 higher-encoded versions. const raw = [ '|', '<', '>', '?', ':', ] const win = raw.map(char => String.fromCharCode(0xf000 + char.charCodeAt(0))) const toWin = new Map(raw.map((char, i) => [char, win[i]])) const toRaw = new Map(win.map((char, i) => [char, raw[i]])) module.exports = { encode: s => raw.reduce((s, c) => s.split(c).join(toWin.get(c)), s), decode: s => win.reduce((s, c) => s.split(c).join(toRaw.get(c)), s), } PK ���\��� � tar/lib/large-numbers.jsnu �[��� 'use strict' // Tar can encode large and negative numbers using a leading byte of // 0xff for negative, and 0x80 for positive. const encode = (num, buf) => { if (!Number.isSafeInteger(num)) { // The number is so large that javascript cannot represent it with integer // precision. throw Error('cannot encode number outside of javascript safe integer range') } else if (num < 0) { encodeNegative(num, buf) } else { encodePositive(num, buf) } return buf } const encodePositive = (num, buf) => { buf[0] = 0x80 for (var i = buf.length; i > 1; i--) { buf[i - 1] = num & 0xff num = Math.floor(num / 0x100) } } const encodeNegative = (num, buf) => { buf[0] = 0xff var flipped = false num = num * -1 for (var i = buf.length; i > 1; i--) { var byte = num & 0xff num = Math.floor(num / 0x100) if (flipped) { buf[i - 1] = onesComp(byte) } else if (byte === 0) { buf[i - 1] = 0 } else { flipped = true buf[i - 1] = twosComp(byte) } } } const parse = (buf) => { const pre = buf[0] const value = pre === 0x80 ? pos(buf.slice(1, buf.length)) : pre === 0xff ? twos(buf) : null if (value === null) { throw Error('invalid base256 encoding') } if (!Number.isSafeInteger(value)) { // The number is so large that javascript cannot represent it with integer // precision. throw Error('parsed number outside of javascript safe integer range') } return value } const twos = (buf) => { var len = buf.length var sum = 0 var flipped = false for (var i = len - 1; i > -1; i--) { var byte = buf[i] var f if (flipped) { f = onesComp(byte) } else if (byte === 0) { f = byte } else { flipped = true f = twosComp(byte) } if (f !== 0) { sum -= f * Math.pow(256, len - i - 1) } } return sum } const pos = (buf) => { var len = buf.length var sum = 0 for (var i = len - 1; i > -1; i--) { var byte = buf[i] if (byte !== 0) { sum += byte * Math.pow(256, len - i - 1) } } return sum } const onesComp = byte => (0xff ^ byte) & 0xff const twosComp = byte => ((0xff ^ byte) + 1) & 0xff module.exports = { encode, parse, } PK ���\�:�: : tar/lib/path-reservations.jsnu �[��� // A path exclusive reservation system // reserve([list, of, paths], fn) // When the fn is first in line for all its paths, it // is called with a cb that clears the reservation. // // Used by async unpack to avoid clobbering paths in use, // while still allowing maximal safe parallelization. const assert = require('assert') const normalize = require('./normalize-unicode.js') const stripSlashes = require('./strip-trailing-slashes.js') const { join } = require('path') const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform const isWindows = platform === 'win32' module.exports = () => { // path => [function or Set] // A Set object means a directory reservation // A fn is a direct reservation on that path const queues = new Map() // fn => {paths:[path,...], dirs:[path, ...]} const reservations = new Map() // return a set of parent dirs for a given path // '/a/b/c/d' -> ['/', '/a', '/a/b', '/a/b/c', '/a/b/c/d'] const getDirs = path => { const dirs = path.split('/').slice(0, -1).reduce((set, path) => { if (set.length) { path = join(set[set.length - 1], path) } set.push(path || '/') return set }, []) return dirs } // functions currently running const running = new Set() // return the queues for each path the function cares about // fn => {paths, dirs} const getQueues = fn => { const res = reservations.get(fn) /* istanbul ignore if - unpossible */ if (!res) { throw new Error('function does not have any path reservations') } return { paths: res.paths.map(path => queues.get(path)), dirs: [...res.dirs].map(path => queues.get(path)), } } // check if fn is first in line for all its paths, and is // included in the first set for all its dir queues const check = fn => { const { paths, dirs } = getQueues(fn) return paths.every(q => q[0] === fn) && dirs.every(q => q[0] instanceof Set && q[0].has(fn)) } // run the function if it's first in line and not already running const run = fn => { if (running.has(fn) || !check(fn)) { return false } running.add(fn) fn(() => clear(fn)) return true } const clear = fn => { if (!running.has(fn)) { return false } const { paths, dirs } = reservations.get(fn) const next = new Set() paths.forEach(path => { const q = queues.get(path) assert.equal(q[0], fn) if (q.length === 1) { queues.delete(path) } else { q.shift() if (typeof q[0] === 'function') { next.add(q[0]) } else { q[0].forEach(fn => next.add(fn)) } } }) dirs.forEach(dir => { const q = queues.get(dir) assert(q[0] instanceof Set) if (q[0].size === 1 && q.length === 1) { queues.delete(dir) } else if (q[0].size === 1) { q.shift() // must be a function or else the Set would've been reused next.add(q[0]) } else { q[0].delete(fn) } }) running.delete(fn) next.forEach(fn => run(fn)) return true } const reserve = (paths, fn) => { // collide on matches across case and unicode normalization // On windows, thanks to the magic of 8.3 shortnames, it is fundamentally // impossible to determine whether two paths refer to the same thing on // disk, without asking the kernel for a shortname. // So, we just pretend that every path matches every other path here, // effectively removing all parallelization on windows. paths = isWindows ? ['win32 parallelization disabled'] : paths.map(p => { // don't need normPath, because we skip this entirely for windows return stripSlashes(join(normalize(p))).toLowerCase() }) const dirs = new Set( paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b)) ) reservations.set(fn, { dirs, paths }) paths.forEach(path => { const q = queues.get(path) if (!q) { queues.set(path, [fn]) } else { q.push(fn) } }) dirs.forEach(dir => { const q = queues.get(dir) if (!q) { queues.set(dir, [new Set([fn])]) } else if (q[q.length - 1] instanceof Set) { q[q.length - 1].add(fn) } else { q.push(new Set([fn])) } }) return run(fn) } return { check, reserve } } PK ���\�}Q�m m tar/lib/mkdir.jsnu �[��� 'use strict' // wrapper around mkdirp for tar's needs. // TODO: This should probably be a class, not functionally // passing around state in a gazillion args. const mkdirp = require('mkdirp') const fs = require('fs') const path = require('path') const chownr = require('chownr') const normPath = require('./normalize-windows-path.js') class SymlinkError extends Error { constructor (symlink, path) { super('Cannot extract through symbolic link') this.path = path this.symlink = symlink } get name () { return 'SylinkError' } } class CwdError extends Error { constructor (path, code) { super(code + ': Cannot cd into \'' + path + '\'') this.path = path this.code = code } get name () { return 'CwdError' } } const cGet = (cache, key) => cache.get(normPath(key)) const cSet = (cache, key, val) => cache.set(normPath(key), val) const checkCwd = (dir, cb) => { fs.stat(dir, (er, st) => { if (er || !st.isDirectory()) { er = new CwdError(dir, er && er.code || 'ENOTDIR') } cb(er) }) } module.exports = (dir, opt, cb) => { dir = normPath(dir) // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask const mode = opt.mode | 0o0700 const needChmod = (mode & umask) !== 0 const uid = opt.uid const gid = opt.gid const doChown = typeof uid === 'number' && typeof gid === 'number' && (uid !== opt.processUid || gid !== opt.processGid) const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache const cwd = normPath(opt.cwd) const done = (er, created) => { if (er) { cb(er) } else { cSet(cache, dir, true) if (created && doChown) { chownr(created, uid, gid, er => done(er)) } else if (needChmod) { fs.chmod(dir, mode, cb) } else { cb() } } } if (cache && cGet(cache, dir) === true) { return done() } if (dir === cwd) { return checkCwd(dir, done) } if (preserve) { return mkdirp(dir, { mode }).then(made => done(null, made), done) } const sub = normPath(path.relative(cwd, dir)) const parts = sub.split('/') mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done) } const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => { if (!parts.length) { return cb(null, created) } const p = parts.shift() const part = normPath(path.resolve(base + '/' + p)) if (cGet(cache, part)) { return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) } fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) } const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { if (er) { fs.lstat(part, (statEr, st) => { if (statEr) { statEr.path = statEr.path && normPath(statEr.path) cb(statEr) } else if (st.isDirectory()) { mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) } else if (unlink) { fs.unlink(part, er => { if (er) { return cb(er) } fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) }) } else if (st.isSymbolicLink()) { return cb(new SymlinkError(part, part + '/' + parts.join('/'))) } else { cb(er) } }) } else { created = created || part mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) } } const checkCwdSync = dir => { let ok = false let code = 'ENOTDIR' try { ok = fs.statSync(dir).isDirectory() } catch (er) { code = er.code } finally { if (!ok) { throw new CwdError(dir, code) } } } module.exports.sync = (dir, opt) => { dir = normPath(dir) // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask const mode = opt.mode | 0o0700 const needChmod = (mode & umask) !== 0 const uid = opt.uid const gid = opt.gid const doChown = typeof uid === 'number' && typeof gid === 'number' && (uid !== opt.processUid || gid !== opt.processGid) const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache const cwd = normPath(opt.cwd) const done = (created) => { cSet(cache, dir, true) if (created && doChown) { chownr.sync(created, uid, gid) } if (needChmod) { fs.chmodSync(dir, mode) } } if (cache && cGet(cache, dir) === true) { return done() } if (dir === cwd) { checkCwdSync(cwd) return done() } if (preserve) { return done(mkdirp.sync(dir, mode)) } const sub = normPath(path.relative(cwd, dir)) const parts = sub.split('/') let created = null for (let p = parts.shift(), part = cwd; p && (part += '/' + p); p = parts.shift()) { part = normPath(path.resolve(part)) if (cGet(cache, part)) { continue } try { fs.mkdirSync(part, mode) created = created || part cSet(cache, part, true) } catch (er) { const st = fs.lstatSync(part) if (st.isDirectory()) { cSet(cache, part, true) continue } else if (unlink) { fs.unlinkSync(part) fs.mkdirSync(part, mode) created = created || part cSet(cache, part, true) continue } else if (st.isSymbolicLink()) { return new SymlinkError(part, part + '/' + parts.join('/')) } } } return done(created) } PK ���\���� � tar/lib/warn-mixin.jsnu �[��� 'use strict' module.exports = Base => class extends Base { warn (code, message, data = {}) { if (this.file) { data.file = this.file } if (this.cwd) { data.cwd = this.cwd } data.code = message instanceof Error && message.code || code data.tarCode = code if (!this.strict && data.recoverable !== false) { if (message instanceof Error) { data = Object.assign(message, data) message = message.message } this.emit('warn', data.tarCode, message, data) } else if (message instanceof Error) { this.emit('error', Object.assign(message, data)) } else { this.emit('error', Object.assign(new Error(`${code}: ${message}`), data)) } } } PK ���\ ��T� � tar/lib/strip-absolute-path.jsnu �[��� // unix absolute paths are also absolute on win32, so we use this for both const { isAbsolute, parse } = require('path').win32 // returns [root, stripped] // Note that windows will think that //x/y/z/a has a "root" of //x/y, and in // those cases, we want to sanitize it to x/y/z/a, not z/a, so we strip / // explicitly if it's the first character. // drive-specific relative paths on Windows get their root stripped off even // though they are not absolute, so `c:../foo` becomes ['c:', '../foo'] module.exports = path => { let r = '' let parsed = parse(path) while (isAbsolute(path) || parsed.root) { // windows will think that //x/y/z has a "root" of //x/y/ // but strip the //?/C:/ off of //?/C:/path const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? '/' : parsed.root path = path.slice(root.length) r += root parsed = parse(path) } return [r, path] } PK ���\87�� � tar/lib/normalize-unicode.jsnu �[��� // warning: extremely hot code path. // This has been meticulously optimized for use // within npm install on large package trees. // Do not edit without careful benchmarking. const normalizeCache = Object.create(null) const { hasOwnProperty } = Object.prototype module.exports = s => { if (!hasOwnProperty.call(normalizeCache, s)) { normalizeCache[s] = s.normalize('NFD') } return normalizeCache[s] } PK ���\d�k� � tar/lib/list.jsnu �[��� 'use strict' // XXX: This shares a lot in common with extract.js // maybe some DRY opportunity here? // tar -t const hlo = require('./high-level-opt.js') const Parser = require('./parse.js') const fs = require('fs') const fsm = require('fs-minipass') const path = require('path') const stripSlash = require('./strip-trailing-slashes.js') module.exports = (opt_, files, cb) => { if (typeof opt_ === 'function') { cb = opt_, files = null, opt_ = {} } else if (Array.isArray(opt_)) { files = opt_, opt_ = {} } if (typeof files === 'function') { cb = files, files = null } if (!files) { files = [] } else { files = Array.from(files) } const opt = hlo(opt_) if (opt.sync && typeof cb === 'function') { throw new TypeError('callback not supported for sync tar functions') } if (!opt.file && typeof cb === 'function') { throw new TypeError('callback only supported with file option') } if (files.length) { filesFilter(opt, files) } if (!opt.noResume) { onentryFunction(opt) } return opt.file && opt.sync ? listFileSync(opt) : opt.file ? listFile(opt, cb) : list(opt) } const onentryFunction = opt => { const onentry = opt.onentry opt.onentry = onentry ? e => { onentry(e) e.resume() } : e => e.resume() } // construct a filter that limits the file entries listed // include child entries if a dir is included const filesFilter = (opt, files) => { const map = new Map(files.map(f => [stripSlash(f), true])) const filter = opt.filter const mapHas = (file, r) => { const root = r || path.parse(file).root || '.' const ret = file === root ? false : map.has(file) ? map.get(file) : mapHas(path.dirname(file), root) map.set(file, ret) return ret } opt.filter = filter ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file)) : file => mapHas(stripSlash(file)) } const listFileSync = opt => { const p = list(opt) const file = opt.file let threw = true let fd try { const stat = fs.statSync(file) const readSize = opt.maxReadSize || 16 * 1024 * 1024 if (stat.size < readSize) { p.end(fs.readFileSync(file)) } else { let pos = 0 const buf = Buffer.allocUnsafe(readSize) fd = fs.openSync(file, 'r') while (pos < stat.size) { const bytesRead = fs.readSync(fd, buf, 0, readSize, pos) pos += bytesRead p.write(buf.slice(0, bytesRead)) } p.end() } threw = false } finally { if (threw && fd) { try { fs.closeSync(fd) } catch (er) {} } } } const listFile = (opt, cb) => { const parse = new Parser(opt) const readSize = opt.maxReadSize || 16 * 1024 * 1024 const file = opt.file const p = new Promise((resolve, reject) => { parse.on('error', reject) parse.on('end', resolve) fs.stat(file, (er, stat) => { if (er) { reject(er) } else { const stream = new fsm.ReadStream(file, { readSize: readSize, size: stat.size, }) stream.on('error', reject) stream.pipe(parse) } }) }) return cb ? p.then(cb, cb) : p } const list = opt => new Parser(opt) PK ���\�dnI� � tar/lib/get-write-flag.jsnu �[��� // Get the appropriate flag to use for creating files // We use fmap on Windows platforms for files less than // 512kb. This is a fairly low limit, but avoids making // things slower in some cases. Since most of what this // library is used for is extracting tarballs of many // relatively small files in npm packages and the like, // it can be a big boost on Windows platforms. // Only supported in Node v12.9.0 and above. const platform = process.env.__FAKE_PLATFORM__ || process.platform const isWindows = platform === 'win32' const fs = global.__FAKE_TESTING_FS__ || require('fs') /* istanbul ignore next */ const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP = 0 } = fs.constants const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP const fMapLimit = 512 * 1024 const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY module.exports = !fMapEnabled ? () => 'w' : size => size < fMapLimit ? fMapFlag : 'w' PK ���\~^� � tar/lib/update.jsnu �[��� 'use strict' // tar -u const hlo = require('./high-level-opt.js') const r = require('./replace.js') // just call tar.r with the filter and mtimeCache module.exports = (opt_, files, cb) => { const opt = hlo(opt_) if (!opt.file) { throw new TypeError('file is required') } if (opt.gzip || opt.brotli || opt.file.endsWith('.br') || opt.file.endsWith('.tbr')) { throw new TypeError('cannot append to compressed archives') } if (!files || !Array.isArray(files) || !files.length) { throw new TypeError('no files or directories specified') } files = Array.from(files) mtimeFilter(opt) return r(opt, files, cb) } const mtimeFilter = opt => { const filter = opt.filter if (!opt.mtimeCache) { opt.mtimeCache = new Map() } opt.filter = filter ? (path, stat) => filter(path, stat) && !(opt.mtimeCache.get(path) > stat.mtime) : (path, stat) => !(opt.mtimeCache.get(path) > stat.mtime) } PK ���\�n|@�d �d tar/lib/unpack.jsnu �[��� 'use strict' // the PEND/UNPEND stuff tracks whether we're ready to emit end/close yet. // but the path reservations are required to avoid race conditions where // parallelized unpack ops may mess with one another, due to dependencies // (like a Link depending on its target) or destructive operations (like // clobbering an fs object to create one of a different type.) const assert = require('assert') const Parser = require('./parse.js') const fs = require('fs') const fsm = require('fs-minipass') const path = require('path') const mkdir = require('./mkdir.js') const wc = require('./winchars.js') const pathReservations = require('./path-reservations.js') const stripAbsolutePath = require('./strip-absolute-path.js') const normPath = require('./normalize-windows-path.js') const stripSlash = require('./strip-trailing-slashes.js') const normalize = require('./normalize-unicode.js') const ONENTRY = Symbol('onEntry') const CHECKFS = Symbol('checkFs') const CHECKFS2 = Symbol('checkFs2') const PRUNECACHE = Symbol('pruneCache') const ISREUSABLE = Symbol('isReusable') const MAKEFS = Symbol('makeFs') const FILE = Symbol('file') const DIRECTORY = Symbol('directory') const LINK = Symbol('link') const SYMLINK = Symbol('symlink') const HARDLINK = Symbol('hardlink') const UNSUPPORTED = Symbol('unsupported') const CHECKPATH = Symbol('checkPath') const MKDIR = Symbol('mkdir') const ONERROR = Symbol('onError') const PENDING = Symbol('pending') const PEND = Symbol('pend') const UNPEND = Symbol('unpend') const ENDED = Symbol('ended') const MAYBECLOSE = Symbol('maybeClose') const SKIP = Symbol('skip') const DOCHOWN = Symbol('doChown') const UID = Symbol('uid') const GID = Symbol('gid') const CHECKED_CWD = Symbol('checkedCwd') const crypto = require('crypto') const getFlag = require('./get-write-flag.js') const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform const isWindows = platform === 'win32' const DEFAULT_MAX_DEPTH = 1024 // Unlinks on Windows are not atomic. // // This means that if you have a file entry, followed by another // file entry with an identical name, and you cannot re-use the file // (because it's a hardlink, or because unlink:true is set, or it's // Windows, which does not have useful nlink values), then the unlink // will be committed to the disk AFTER the new file has been written // over the old one, deleting the new file. // // To work around this, on Windows systems, we rename the file and then // delete the renamed file. It's a sloppy kludge, but frankly, I do not // know of a better way to do this, given windows' non-atomic unlink // semantics. // // See: https://github.com/npm/node-tar/issues/183 /* istanbul ignore next */ const unlinkFile = (path, cb) => { if (!isWindows) { return fs.unlink(path, cb) } const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') fs.rename(path, name, er => { if (er) { return cb(er) } fs.unlink(name, cb) }) } /* istanbul ignore next */ const unlinkFileSync = path => { if (!isWindows) { return fs.unlinkSync(path) } const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') fs.renameSync(path, name) fs.unlinkSync(name) } // this.gid, entry.gid, this.processUid const uint32 = (a, b, c) => a === a >>> 0 ? a : b === b >>> 0 ? b : c // clear the cache if it's a case-insensitive unicode-squashing match. // we can't know if the current file system is case-sensitive or supports // unicode fully, so we check for similarity on the maximally compatible // representation. Err on the side of pruning, since all it's doing is // preventing lstats, and it's not the end of the world if we get a false // positive. // Note that on windows, we always drop the entire cache whenever a // symbolic link is encountered, because 8.3 filenames are impossible // to reason about, and collisions are hazards rather than just failures. const cacheKeyNormalize = path => stripSlash(normPath(normalize(path))) .toLowerCase() const pruneCache = (cache, abs) => { abs = cacheKeyNormalize(abs) for (const path of cache.keys()) { const pnorm = cacheKeyNormalize(path) if (pnorm === abs || pnorm.indexOf(abs + '/') === 0) { cache.delete(path) } } } const dropCache = cache => { for (const key of cache.keys()) { cache.delete(key) } } class Unpack extends Parser { constructor (opt) { if (!opt) { opt = {} } opt.ondone = _ => { this[ENDED] = true this[MAYBECLOSE]() } super(opt) this[CHECKED_CWD] = false this.reservations = pathReservations() this.transform = typeof opt.transform === 'function' ? opt.transform : null this.writable = true this.readable = false this[PENDING] = 0 this[ENDED] = false this.dirCache = opt.dirCache || new Map() if (typeof opt.uid === 'number' || typeof opt.gid === 'number') { // need both or neither if (typeof opt.uid !== 'number' || typeof opt.gid !== 'number') { throw new TypeError('cannot set owner without number uid and gid') } if (opt.preserveOwner) { throw new TypeError( 'cannot preserve owner in archive and also set owner explicitly') } this.uid = opt.uid this.gid = opt.gid this.setOwner = true } else { this.uid = null this.gid = null this.setOwner = false } // default true for root if (opt.preserveOwner === undefined && typeof opt.uid !== 'number') { this.preserveOwner = process.getuid && process.getuid() === 0 } else { this.preserveOwner = !!opt.preserveOwner } this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? process.getuid() : null this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? process.getgid() : null // prevent excessively deep nesting of subfolders // set to `Infinity` to remove this restriction this.maxDepth = typeof opt.maxDepth === 'number' ? opt.maxDepth : DEFAULT_MAX_DEPTH // mostly just for testing, but useful in some cases. // Forcibly trigger a chown on every entry, no matter what this.forceChown = opt.forceChown === true // turn ><?| in filenames into 0xf000-higher encoded forms this.win32 = !!opt.win32 || isWindows // do not unpack over files that are newer than what's in the archive this.newer = !!opt.newer // do not unpack over ANY files this.keep = !!opt.keep // do not set mtime/atime of extracted entries this.noMtime = !!opt.noMtime // allow .., absolute path entries, and unpacking through symlinks // without this, warn and skip .., relativize absolutes, and error // on symlinks in extraction path this.preservePaths = !!opt.preservePaths // unlink files and links before writing. This breaks existing hard // links, and removes symlink directories rather than erroring this.unlink = !!opt.unlink this.cwd = normPath(path.resolve(opt.cwd || process.cwd())) this.strip = +opt.strip || 0 // if we're not chmodding, then we don't need the process umask this.processUmask = opt.noChmod ? 0 : process.umask() this.umask = typeof opt.umask === 'number' ? opt.umask : this.processUmask // default mode for dirs created as parents this.dmode = opt.dmode || (0o0777 & (~this.umask)) this.fmode = opt.fmode || (0o0666 & (~this.umask)) this.on('entry', entry => this[ONENTRY](entry)) } // a bad or damaged archive is a warning for Parser, but an error // when extracting. Mark those errors as unrecoverable, because // the Unpack contract cannot be met. warn (code, msg, data = {}) { if (code === 'TAR_BAD_ARCHIVE' || code === 'TAR_ABORT') { data.recoverable = false } return super.warn(code, msg, data) } [MAYBECLOSE] () { if (this[ENDED] && this[PENDING] === 0) { this.emit('prefinish') this.emit('finish') this.emit('end') } } [CHECKPATH] (entry) { const p = normPath(entry.path) const parts = p.split('/') if (this.strip) { if (parts.length < this.strip) { return false } if (entry.type === 'Link') { const linkparts = normPath(entry.linkpath).split('/') if (linkparts.length >= this.strip) { entry.linkpath = linkparts.slice(this.strip).join('/') } else { return false } } parts.splice(0, this.strip) entry.path = parts.join('/') } if (isFinite(this.maxDepth) && parts.length > this.maxDepth) { this.warn('TAR_ENTRY_ERROR', 'path excessively deep', { entry, path: p, depth: parts.length, maxDepth: this.maxDepth, }) return false } if (!this.preservePaths) { if (parts.includes('..') || isWindows && /^[a-z]:\.\.$/i.test(parts[0])) { this.warn('TAR_ENTRY_ERROR', `path contains '..'`, { entry, path: p, }) return false } // strip off the root const [root, stripped] = stripAbsolutePath(p) if (root) { entry.path = stripped this.warn('TAR_ENTRY_INFO', `stripping ${root} from absolute path`, { entry, path: p, }) } } if (path.isAbsolute(entry.path)) { entry.absolute = normPath(path.resolve(entry.path)) } else { entry.absolute = normPath(path.resolve(this.cwd, entry.path)) } // if we somehow ended up with a path that escapes the cwd, and we are // not in preservePaths mode, then something is fishy! This should have // been prevented above, so ignore this for coverage. /* istanbul ignore if - defense in depth */ if (!this.preservePaths && entry.absolute.indexOf(this.cwd + '/') !== 0 && entry.absolute !== this.cwd) { this.warn('TAR_ENTRY_ERROR', 'path escaped extraction target', { entry, path: normPath(entry.path), resolvedPath: entry.absolute, cwd: this.cwd, }) return false } // an archive can set properties on the extraction directory, but it // may not replace the cwd with a different kind of thing entirely. if (entry.absolute === this.cwd && entry.type !== 'Directory' && entry.type !== 'GNUDumpDir') { return false } // only encode : chars that aren't drive letter indicators if (this.win32) { const { root: aRoot } = path.win32.parse(entry.absolute) entry.absolute = aRoot + wc.encode(entry.absolute.slice(aRoot.length)) const { root: pRoot } = path.win32.parse(entry.path) entry.path = pRoot + wc.encode(entry.path.slice(pRoot.length)) } return true } [ONENTRY] (entry) { if (!this[CHECKPATH](entry)) { return entry.resume() } assert.equal(typeof entry.absolute, 'string') switch (entry.type) { case 'Directory': case 'GNUDumpDir': if (entry.mode) { entry.mode = entry.mode | 0o700 } // eslint-disable-next-line no-fallthrough case 'File': case 'OldFile': case 'ContiguousFile': case 'Link': case 'SymbolicLink': return this[CHECKFS](entry) case 'CharacterDevice': case 'BlockDevice': case 'FIFO': default: return this[UNSUPPORTED](entry) } } [ONERROR] (er, entry) { // Cwd has to exist, or else nothing works. That's serious. // Other errors are warnings, which raise the error in strict // mode, but otherwise continue on. if (er.name === 'CwdError') { this.emit('error', er) } else { this.warn('TAR_ENTRY_ERROR', er, { entry }) this[UNPEND]() entry.resume() } } [MKDIR] (dir, mode, cb) { mkdir(normPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, processGid: this.processGid, umask: this.processUmask, preserve: this.preservePaths, unlink: this.unlink, cache: this.dirCache, cwd: this.cwd, mode: mode, noChmod: this.noChmod, }, cb) } [DOCHOWN] (entry) { // in preserve owner mode, chown if the entry doesn't match process // in set owner mode, chown if setting doesn't match process return this.forceChown || this.preserveOwner && (typeof entry.uid === 'number' && entry.uid !== this.processUid || typeof entry.gid === 'number' && entry.gid !== this.processGid) || (typeof this.uid === 'number' && this.uid !== this.processUid || typeof this.gid === 'number' && this.gid !== this.processGid) } [UID] (entry) { return uint32(this.uid, entry.uid, this.processUid) } [GID] (entry) { return uint32(this.gid, entry.gid, this.processGid) } [FILE] (entry, fullyDone) { const mode = entry.mode & 0o7777 || this.fmode const stream = new fsm.WriteStream(entry.absolute, { flags: getFlag(entry.size), mode: mode, autoClose: false, }) stream.on('error', er => { if (stream.fd) { fs.close(stream.fd, () => {}) } // flush all the data out so that we aren't left hanging // if the error wasn't actually fatal. otherwise the parse // is blocked, and we never proceed. stream.write = () => true this[ONERROR](er, entry) fullyDone() }) let actions = 1 const done = er => { if (er) { /* istanbul ignore else - we should always have a fd by now */ if (stream.fd) { fs.close(stream.fd, () => {}) } this[ONERROR](er, entry) fullyDone() return } if (--actions === 0) { fs.close(stream.fd, er => { if (er) { this[ONERROR](er, entry) } else { this[UNPEND]() } fullyDone() }) } } stream.on('finish', _ => { // if futimes fails, try utimes // if utimes fails, fail with the original error // same for fchown/chown const abs = entry.absolute const fd = stream.fd if (entry.mtime && !this.noMtime) { actions++ const atime = entry.atime || new Date() const mtime = entry.mtime fs.futimes(fd, atime, mtime, er => er ? fs.utimes(abs, atime, mtime, er2 => done(er2 && er)) : done()) } if (this[DOCHOWN](entry)) { actions++ const uid = this[UID](entry) const gid = this[GID](entry) fs.fchown(fd, uid, gid, er => er ? fs.chown(abs, uid, gid, er2 => done(er2 && er)) : done()) } done() }) const tx = this.transform ? this.transform(entry) || entry : entry if (tx !== entry) { tx.on('error', er => { this[ONERROR](er, entry) fullyDone() }) entry.pipe(tx) } tx.pipe(stream) } [DIRECTORY] (entry, fullyDone) { const mode = entry.mode & 0o7777 || this.dmode this[MKDIR](entry.absolute, mode, er => { if (er) { this[ONERROR](er, entry) fullyDone() return } let actions = 1 const done = _ => { if (--actions === 0) { fullyDone() this[UNPEND]() entry.resume() } } if (entry.mtime && !this.noMtime) { actions++ fs.utimes(entry.absolute, entry.atime || new Date(), entry.mtime, done) } if (this[DOCHOWN](entry)) { actions++ fs.chown(entry.absolute, this[UID](entry), this[GID](entry), done) } done() }) } [UNSUPPORTED] (entry) { entry.unsupported = true this.warn('TAR_ENTRY_UNSUPPORTED', `unsupported entry type: ${entry.type}`, { entry }) entry.resume() } [SYMLINK] (entry, done) { this[LINK](entry, entry.linkpath, 'symlink', done) } [HARDLINK] (entry, done) { const linkpath = normPath(path.resolve(this.cwd, entry.linkpath)) this[LINK](entry, linkpath, 'link', done) } [PEND] () { this[PENDING]++ } [UNPEND] () { this[PENDING]-- this[MAYBECLOSE]() } [SKIP] (entry) { this[UNPEND]() entry.resume() } // Check if we can reuse an existing filesystem entry safely and // overwrite it, rather than unlinking and recreating // Windows doesn't report a useful nlink, so we just never reuse entries [ISREUSABLE] (entry, st) { return entry.type === 'File' && !this.unlink && st.isFile() && st.nlink <= 1 && !isWindows } // check if a thing is there, and if so, try to clobber it [CHECKFS] (entry) { this[PEND]() const paths = [entry.path] if (entry.linkpath) { paths.push(entry.linkpath) } this.reservations.reserve(paths, done => this[CHECKFS2](entry, done)) } [PRUNECACHE] (entry) { // if we are not creating a directory, and the path is in the dirCache, // then that means we are about to delete the directory we created // previously, and it is no longer going to be a directory, and neither // is any of its children. // If a symbolic link is encountered, all bets are off. There is no // reasonable way to sanitize the cache in such a way we will be able to // avoid having filesystem collisions. If this happens with a non-symlink // entry, it'll just fail to unpack, but a symlink to a directory, using an // 8.3 shortname or certain unicode attacks, can evade detection and lead // to arbitrary writes to anywhere on the system. if (entry.type === 'SymbolicLink') { dropCache(this.dirCache) } else if (entry.type !== 'Directory') { pruneCache(this.dirCache, entry.absolute) } } [CHECKFS2] (entry, fullyDone) { this[PRUNECACHE](entry) const done = er => { this[PRUNECACHE](entry) fullyDone(er) } const checkCwd = () => { this[MKDIR](this.cwd, this.dmode, er => { if (er) { this[ONERROR](er, entry) done() return } this[CHECKED_CWD] = true start() }) } const start = () => { if (entry.absolute !== this.cwd) { const parent = normPath(path.dirname(entry.absolute)) if (parent !== this.cwd) { return this[MKDIR](parent, this.dmode, er => { if (er) { this[ONERROR](er, entry) done() return } afterMakeParent() }) } } afterMakeParent() } const afterMakeParent = () => { fs.lstat(entry.absolute, (lstatEr, st) => { if (st && (this.keep || this.newer && st.mtime > entry.mtime)) { this[SKIP](entry) done() return } if (lstatEr || this[ISREUSABLE](entry, st)) { return this[MAKEFS](null, entry, done) } if (st.isDirectory()) { if (entry.type === 'Directory') { const needChmod = !this.noChmod && entry.mode && (st.mode & 0o7777) !== entry.mode const afterChmod = er => this[MAKEFS](er, entry, done) if (!needChmod) { return afterChmod() } return fs.chmod(entry.absolute, entry.mode, afterChmod) } // Not a dir entry, have to remove it. // NB: the only way to end up with an entry that is the cwd // itself, in such a way that == does not detect, is a // tricky windows absolute path with UNC or 8.3 parts (and // preservePaths:true, or else it will have been stripped). // In that case, the user has opted out of path protections // explicitly, so if they blow away the cwd, c'est la vie. if (entry.absolute !== this.cwd) { return fs.rmdir(entry.absolute, er => this[MAKEFS](er, entry, done)) } } // not a dir, and not reusable // don't remove if the cwd, we want that error if (entry.absolute === this.cwd) { return this[MAKEFS](null, entry, done) } unlinkFile(entry.absolute, er => this[MAKEFS](er, entry, done)) }) } if (this[CHECKED_CWD]) { start() } else { checkCwd() } } [MAKEFS] (er, entry, done) { if (er) { this[ONERROR](er, entry) done() return } switch (entry.type) { case 'File': case 'OldFile': case 'ContiguousFile': return this[FILE](entry, done) case 'Link': return this[HARDLINK](entry, done) case 'SymbolicLink': return this[SYMLINK](entry, done) case 'Directory': case 'GNUDumpDir': return this[DIRECTORY](entry, done) } } [LINK] (entry, linkpath, link, done) { // XXX: get the type ('symlink' or 'junction') for windows fs[link](linkpath, entry.absolute, er => { if (er) { this[ONERROR](er, entry) } else { this[UNPEND]() entry.resume() } done() }) } } const callSync = fn => { try { return [null, fn()] } catch (er) { return [er, null] } } class UnpackSync extends Unpack { [MAKEFS] (er, entry) { return super[MAKEFS](er, entry, () => {}) } [CHECKFS] (entry) { this[PRUNECACHE](entry) if (!this[CHECKED_CWD]) { const er = this[MKDIR](this.cwd, this.dmode) if (er) { return this[ONERROR](er, entry) } this[CHECKED_CWD] = true } // don't bother to make the parent if the current entry is the cwd, // we've already checked it. if (entry.absolute !== this.cwd) { const parent = normPath(path.dirname(entry.absolute)) if (parent !== this.cwd) { const mkParent = this[MKDIR](parent, this.dmode) if (mkParent) { return this[ONERROR](mkParent, entry) } } } const [lstatEr, st] = callSync(() => fs.lstatSync(entry.absolute)) if (st && (this.keep || this.newer && st.mtime > entry.mtime)) { return this[SKIP](entry) } if (lstatEr || this[ISREUSABLE](entry, st)) { return this[MAKEFS](null, entry) } if (st.isDirectory()) { if (entry.type === 'Directory') { const needChmod = !this.noChmod && entry.mode && (st.mode & 0o7777) !== entry.mode const [er] = needChmod ? callSync(() => { fs.chmodSync(entry.absolute, entry.mode) }) : [] return this[MAKEFS](er, entry) } // not a dir entry, have to remove it const [er] = callSync(() => fs.rmdirSync(entry.absolute)) this[MAKEFS](er, entry) } // not a dir, and not reusable. // don't remove if it's the cwd, since we want that error. const [er] = entry.absolute === this.cwd ? [] : callSync(() => unlinkFileSync(entry.absolute)) this[MAKEFS](er, entry) } [FILE] (entry, done) { const mode = entry.mode & 0o7777 || this.fmode const oner = er => { let closeError try { fs.closeSync(fd) } catch (e) { closeError = e } if (er || closeError) { this[ONERROR](er || closeError, entry) } done() } let fd try { fd = fs.openSync(entry.absolute, getFlag(entry.size), mode) } catch (er) { return oner(er) } const tx = this.transform ? this.transform(entry) || entry : entry if (tx !== entry) { tx.on('error', er => this[ONERROR](er, entry)) entry.pipe(tx) } tx.on('data', chunk => { try { fs.writeSync(fd, chunk, 0, chunk.length) } catch (er) { oner(er) } }) tx.on('end', _ => { let er = null // try both, falling futimes back to utimes // if either fails, handle the first error if (entry.mtime && !this.noMtime) { const atime = entry.atime || new Date() const mtime = entry.mtime try { fs.futimesSync(fd, atime, mtime) } catch (futimeser) { try { fs.utimesSync(entry.absolute, atime, mtime) } catch (utimeser) { er = futimeser } } } if (this[DOCHOWN](entry)) { const uid = this[UID](entry) const gid = this[GID](entry) try { fs.fchownSync(fd, uid, gid) } catch (fchowner) { try { fs.chownSync(entry.absolute, uid, gid) } catch (chowner) { er = er || fchowner } } } oner(er) }) } [DIRECTORY] (entry, done) { const mode = entry.mode & 0o7777 || this.dmode const er = this[MKDIR](entry.absolute, mode) if (er) { this[ONERROR](er, entry) done() return } if (entry.mtime && !this.noMtime) { try { fs.utimesSync(entry.absolute, entry.atime || new Date(), entry.mtime) } catch (er) {} } if (this[DOCHOWN](entry)) { try { fs.chownSync(entry.absolute, this[UID](entry), this[GID](entry)) } catch (er) {} } done() entry.resume() } [MKDIR] (dir, mode) { try { return mkdir.sync(normPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, processGid: this.processGid, umask: this.processUmask, preserve: this.preservePaths, unlink: this.unlink, cache: this.dirCache, cwd: this.cwd, mode: mode, }) } catch (er) { return er } } [LINK] (entry, linkpath, link, done) { try { fs[link + 'Sync'](linkpath, entry.absolute) done() entry.resume() } catch (er) { return this[ONERROR](er, entry) } } } Unpack.Sync = UnpackSync module.exports = Unpack PK ���\�`�ĉ � tar/lib/mode-fix.jsnu �[��� 'use strict' module.exports = (mode, isDir, portable) => { mode &= 0o7777 // in portable mode, use the minimum reasonable umask // if this system creates files with 0o664 by default // (as some linux distros do), then we'll write the // archive with 0o644 instead. Also, don't ever create // a file that is not readable/writable by the owner. if (portable) { mode = (mode | 0o600) & ~0o22 } // if dirs are readable, then they should be listable if (isDir) { if (mode & 0o400) { mode |= 0o100 } if (mode & 0o40) { mode |= 0o10 } if (mode & 0o4) { mode |= 0o1 } } return mode } PK ���\9uRZ tar/lib/read-entry.jsnu �[��� 'use strict' const { Minipass } = require('minipass') const normPath = require('./normalize-windows-path.js') const SLURP = Symbol('slurp') module.exports = class ReadEntry extends Minipass { constructor (header, ex, gex) { super() // read entries always start life paused. this is to avoid the // situation where Minipass's auto-ending empty streams results // in an entry ending before we're ready for it. this.pause() this.extended = ex this.globalExtended = gex this.header = header this.startBlockSize = 512 * Math.ceil(header.size / 512) this.blockRemain = this.startBlockSize this.remain = header.size this.type = header.type this.meta = false this.ignore = false switch (this.type) { case 'File': case 'OldFile': case 'Link': case 'SymbolicLink': case 'CharacterDevice': case 'BlockDevice': case 'Directory': case 'FIFO': case 'ContiguousFile': case 'GNUDumpDir': break case 'NextFileHasLongLinkpath': case 'NextFileHasLongPath': case 'OldGnuLongPath': case 'GlobalExtendedHeader': case 'ExtendedHeader': case 'OldExtendedHeader': this.meta = true break // NOTE: gnutar and bsdtar treat unrecognized types as 'File' // it may be worth doing the same, but with a warning. default: this.ignore = true } this.path = normPath(header.path) this.mode = header.mode if (this.mode) { this.mode = this.mode & 0o7777 } this.uid = header.uid this.gid = header.gid this.uname = header.uname this.gname = header.gname this.size = header.size this.mtime = header.mtime this.atime = header.atime this.ctime = header.ctime this.linkpath = normPath(header.linkpath) this.uname = header.uname this.gname = header.gname if (ex) { this[SLURP](ex) } if (gex) { this[SLURP](gex, true) } } write (data) { const writeLen = data.length if (writeLen > this.blockRemain) { throw new Error('writing more to entry than is appropriate') } const r = this.remain const br = this.blockRemain this.remain = Math.max(0, r - writeLen) this.blockRemain = Math.max(0, br - writeLen) if (this.ignore) { return true } if (r >= writeLen) { return super.write(data) } // r < writeLen return super.write(data.slice(0, r)) } [SLURP] (ex, global) { for (const k in ex) { // we slurp in everything except for the path attribute in // a global extended header, because that's weird. if (ex[k] !== null && ex[k] !== undefined && !(global && k === 'path')) { this[k] = k === 'path' || k === 'linkpath' ? normPath(ex[k]) : ex[k] } } } } PK ���\��z�%'