avancement planning
This commit is contained in:
+2
-2
@@ -10,7 +10,7 @@ const Pipeline = require('minipass-pipeline')
|
||||
const Flush = require('minipass-flush')
|
||||
const path = require('path')
|
||||
const ssri = require('ssri')
|
||||
const uniqueFilename = require('unique-filename')
|
||||
const { tmpName } = require('../util/tmp')
|
||||
const fsm = require('fs-minipass')
|
||||
|
||||
module.exports = write
|
||||
@@ -152,7 +152,7 @@ async function pipeToTmp (inputStream, cache, tmpTarget, opts) {
|
||||
}
|
||||
|
||||
async function makeTmp (cache, opts) {
|
||||
const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix)
|
||||
const tmpTarget = tmpName(cache, opts.tmpPrefix)
|
||||
await fs.mkdir(path.dirname(tmpTarget), { recursive: true })
|
||||
return {
|
||||
target: tmpTarget,
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ const {
|
||||
const { Minipass } = require('minipass')
|
||||
const path = require('path')
|
||||
const ssri = require('ssri')
|
||||
const uniqueFilename = require('unique-filename')
|
||||
const { tmpName } = require('./util/tmp')
|
||||
|
||||
const contentPath = require('./content/path')
|
||||
const hashToSegments = require('./util/hash-to-segments')
|
||||
@@ -69,7 +69,7 @@ async function compact (cache, key, matchFn, opts = {}) {
|
||||
}).join('\n')
|
||||
|
||||
const setup = async () => {
|
||||
const target = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix)
|
||||
const target = tmpName(cache, opts.tmpPrefix)
|
||||
await mkdir(path.dirname(target), { recursive: true })
|
||||
return {
|
||||
target,
|
||||
|
||||
+6
@@ -1,11 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
const crypto = require('crypto')
|
||||
const { withTempDir } = require('@npmcli/fs')
|
||||
const fs = require('fs/promises')
|
||||
const path = require('path')
|
||||
|
||||
module.exports.mkdir = mktmpdir
|
||||
|
||||
module.exports.tmpName = function tmpName (cache, tmpPrefix) {
|
||||
const id = crypto.randomUUID()
|
||||
return path.join(cache, 'tmp', tmpPrefix ? `${tmpPrefix}-${id}` : id)
|
||||
}
|
||||
|
||||
async function mktmpdir (cache, opts = {}) {
|
||||
const { tmpPrefix } = opts
|
||||
const tmpDir = path.join(cache, 'tmp')
|
||||
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
All packages under `src/` are licensed according to the terms in
|
||||
their respective `LICENSE` or `LICENSE.md` files.
|
||||
|
||||
The remainder of this project is licensed under the Blue Oak
|
||||
Model License, as follows:
|
||||
|
||||
-----
|
||||
|
||||
# Blue Oak Model License
|
||||
|
||||
Version 1.0.0
|
||||
|
||||
## Purpose
|
||||
|
||||
This license gives everyone as much permission to work with
|
||||
this software as possible, while protecting contributors
|
||||
from liability.
|
||||
|
||||
## Acceptance
|
||||
|
||||
In order to receive this license, you must agree to its
|
||||
rules. The rules of this license are both obligations
|
||||
under that agreement and conditions to your license.
|
||||
You must not do anything with this software that triggers
|
||||
a rule that you cannot or will not follow.
|
||||
|
||||
## Copyright
|
||||
|
||||
Each contributor licenses you to do everything with this
|
||||
software that would otherwise infringe that contributor's
|
||||
copyright in it.
|
||||
|
||||
## Notices
|
||||
|
||||
You must ensure that everyone who gets a copy of
|
||||
any part of this software from you, with or without
|
||||
changes, also gets the text of this license or a link to
|
||||
<https://blueoakcouncil.org/license/1.0.0>.
|
||||
|
||||
## Excuse
|
||||
|
||||
If anyone notifies you in writing that you have not
|
||||
complied with [Notices](#notices), you can keep your
|
||||
license by taking all practical steps to comply within 30
|
||||
days after the notice. If you do not do so, your license
|
||||
ends immediately.
|
||||
|
||||
## Patent
|
||||
|
||||
Each contributor licenses you to do everything with this
|
||||
software that would otherwise infringe any patent claims
|
||||
they can license or become able to license.
|
||||
|
||||
## Reliability
|
||||
|
||||
No contributor can revoke this license.
|
||||
|
||||
## No Liability
|
||||
|
||||
***As far as the law allows, this software comes as is,
|
||||
without any warranty or condition, and no contributor
|
||||
will be liable to anyone for any damages related to this
|
||||
software or this license, under any kind of legal claim.***
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
Like `chown -R`.
|
||||
|
||||
Takes the same arguments as `fs.chown()`
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export declare const chownr: (p: string, uid: number, gid: number, cb: (er?: unknown) => any) => void;
|
||||
export declare const chownrSync: (p: string, uid: number, gid: number) => void;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,MAAM,MACd,MAAM,OACJ,MAAM,OACN,MAAM,YACD,OAAO,KAAK,GAAG,SA0B1B,CAAA;AAcD,eAAO,MAAM,UAAU,MAAO,MAAM,OAAO,MAAM,OAAO,MAAM,SAiB7D,CAAA"}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.chownrSync = exports.chownr = void 0;
|
||||
const node_fs_1 = __importDefault(require("node:fs"));
|
||||
const node_path_1 = __importDefault(require("node:path"));
|
||||
const lchownSync = (path, uid, gid) => {
|
||||
try {
|
||||
return node_fs_1.default.lchownSync(path, uid, gid);
|
||||
}
|
||||
catch (er) {
|
||||
if (er?.code !== 'ENOENT')
|
||||
throw er;
|
||||
}
|
||||
};
|
||||
const chown = (cpath, uid, gid, cb) => {
|
||||
node_fs_1.default.lchown(cpath, uid, gid, er => {
|
||||
// Skip ENOENT error
|
||||
cb(er && er?.code !== 'ENOENT' ? er : null);
|
||||
});
|
||||
};
|
||||
const chownrKid = (p, child, uid, gid, cb) => {
|
||||
if (child.isDirectory()) {
|
||||
(0, exports.chownr)(node_path_1.default.resolve(p, child.name), uid, gid, (er) => {
|
||||
if (er)
|
||||
return cb(er);
|
||||
const cpath = node_path_1.default.resolve(p, child.name);
|
||||
chown(cpath, uid, gid, cb);
|
||||
});
|
||||
}
|
||||
else {
|
||||
const cpath = node_path_1.default.resolve(p, child.name);
|
||||
chown(cpath, uid, gid, cb);
|
||||
}
|
||||
};
|
||||
const chownr = (p, uid, gid, cb) => {
|
||||
node_fs_1.default.readdir(p, { withFileTypes: true }, (er, children) => {
|
||||
// any error other than ENOTDIR or ENOTSUP means it's not readable,
|
||||
// or doesn't exist. give up.
|
||||
if (er) {
|
||||
if (er.code === 'ENOENT')
|
||||
return cb();
|
||||
else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
|
||||
return cb(er);
|
||||
}
|
||||
if (er || !children.length)
|
||||
return chown(p, uid, gid, cb);
|
||||
let len = children.length;
|
||||
let errState = null;
|
||||
const then = (er) => {
|
||||
/* c8 ignore start */
|
||||
if (errState)
|
||||
return;
|
||||
/* c8 ignore stop */
|
||||
if (er)
|
||||
return cb((errState = er));
|
||||
if (--len === 0)
|
||||
return chown(p, uid, gid, cb);
|
||||
};
|
||||
for (const child of children) {
|
||||
chownrKid(p, child, uid, gid, then);
|
||||
}
|
||||
});
|
||||
};
|
||||
exports.chownr = chownr;
|
||||
const chownrKidSync = (p, child, uid, gid) => {
|
||||
if (child.isDirectory())
|
||||
(0, exports.chownrSync)(node_path_1.default.resolve(p, child.name), uid, gid);
|
||||
lchownSync(node_path_1.default.resolve(p, child.name), uid, gid);
|
||||
};
|
||||
const chownrSync = (p, uid, gid) => {
|
||||
let children;
|
||||
try {
|
||||
children = node_fs_1.default.readdirSync(p, { withFileTypes: true });
|
||||
}
|
||||
catch (er) {
|
||||
const e = er;
|
||||
if (e?.code === 'ENOENT')
|
||||
return;
|
||||
else if (e?.code === 'ENOTDIR' || e?.code === 'ENOTSUP')
|
||||
return lchownSync(p, uid, gid);
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
for (const child of children) {
|
||||
chownrKidSync(p, child, uid, gid);
|
||||
}
|
||||
return lchownSync(p, uid, gid);
|
||||
};
|
||||
exports.chownrSync = chownrSync;
|
||||
//# sourceMappingURL=index.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-3
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export declare const chownr: (p: string, uid: number, gid: number, cb: (er?: unknown) => any) => void;
|
||||
export declare const chownrSync: (p: string, uid: number, gid: number) => void;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,MAAM,MACd,MAAM,OACJ,MAAM,OACN,MAAM,YACD,OAAO,KAAK,GAAG,SA0B1B,CAAA;AAcD,eAAO,MAAM,UAAU,MAAO,MAAM,OAAO,MAAM,OAAO,MAAM,SAiB7D,CAAA"}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
const lchownSync = (path, uid, gid) => {
|
||||
try {
|
||||
return fs.lchownSync(path, uid, gid);
|
||||
}
|
||||
catch (er) {
|
||||
if (er?.code !== 'ENOENT')
|
||||
throw er;
|
||||
}
|
||||
};
|
||||
const chown = (cpath, uid, gid, cb) => {
|
||||
fs.lchown(cpath, uid, gid, er => {
|
||||
// Skip ENOENT error
|
||||
cb(er && er?.code !== 'ENOENT' ? er : null);
|
||||
});
|
||||
};
|
||||
const chownrKid = (p, child, uid, gid, cb) => {
|
||||
if (child.isDirectory()) {
|
||||
chownr(path.resolve(p, child.name), uid, gid, (er) => {
|
||||
if (er)
|
||||
return cb(er);
|
||||
const cpath = path.resolve(p, child.name);
|
||||
chown(cpath, uid, gid, cb);
|
||||
});
|
||||
}
|
||||
else {
|
||||
const cpath = path.resolve(p, child.name);
|
||||
chown(cpath, uid, gid, cb);
|
||||
}
|
||||
};
|
||||
export const chownr = (p, uid, gid, cb) => {
|
||||
fs.readdir(p, { withFileTypes: true }, (er, children) => {
|
||||
// any error other than ENOTDIR or ENOTSUP means it's not readable,
|
||||
// or doesn't exist. give up.
|
||||
if (er) {
|
||||
if (er.code === 'ENOENT')
|
||||
return cb();
|
||||
else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
|
||||
return cb(er);
|
||||
}
|
||||
if (er || !children.length)
|
||||
return chown(p, uid, gid, cb);
|
||||
let len = children.length;
|
||||
let errState = null;
|
||||
const then = (er) => {
|
||||
/* c8 ignore start */
|
||||
if (errState)
|
||||
return;
|
||||
/* c8 ignore stop */
|
||||
if (er)
|
||||
return cb((errState = er));
|
||||
if (--len === 0)
|
||||
return chown(p, uid, gid, cb);
|
||||
};
|
||||
for (const child of children) {
|
||||
chownrKid(p, child, uid, gid, then);
|
||||
}
|
||||
});
|
||||
};
|
||||
const chownrKidSync = (p, child, uid, gid) => {
|
||||
if (child.isDirectory())
|
||||
chownrSync(path.resolve(p, child.name), uid, gid);
|
||||
lchownSync(path.resolve(p, child.name), uid, gid);
|
||||
};
|
||||
export const chownrSync = (p, uid, gid) => {
|
||||
let children;
|
||||
try {
|
||||
children = fs.readdirSync(p, { withFileTypes: true });
|
||||
}
|
||||
catch (er) {
|
||||
const e = er;
|
||||
if (e?.code === 'ENOENT')
|
||||
return;
|
||||
else if (e?.code === 'ENOTDIR' || e?.code === 'ENOTSUP')
|
||||
return lchownSync(p, uid, gid);
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
for (const child of children) {
|
||||
chownrKidSync(p, child, uid, gid);
|
||||
}
|
||||
return lchownSync(p, uid, gid);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-3
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
{
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||
"name": "chownr",
|
||||
"description": "like `chown -R`",
|
||||
"version": "3.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/chownr.git"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.12.5",
|
||||
"mkdirp": "^3.0.1",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "^5.0.5",
|
||||
"tap": "^18.7.2",
|
||||
"tshy": "^1.13.1",
|
||||
"typedoc": "^0.25.12"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "tshy",
|
||||
"pretest": "npm run prepare",
|
||||
"test": "tap",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"prepublishOnly": "git push origin --follow-tags",
|
||||
"format": "prettier --write . --loglevel warn",
|
||||
"typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts"
|
||||
},
|
||||
"license": "BlueOak-1.0.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"tshy": {
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts"
|
||||
}
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"type": "module",
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
"printWidth": 75,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": false,
|
||||
"bracketSameLine": true,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) 2010-2023 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.
|
||||
+155
-17
@@ -57,10 +57,17 @@ const options = {
|
||||
|
||||
// for use when you need to clean up something when objects
|
||||
// are evicted from the cache
|
||||
dispose: (value, key) => {
|
||||
dispose: (value, key, reason) => {
|
||||
freeFromMemoryOrWhatever(value)
|
||||
},
|
||||
|
||||
// for use when you need to know that an item is being inserted
|
||||
// note that this does NOT allow you to prevent the insertion,
|
||||
// it just allows you to know about it.
|
||||
onInsert: (value, key, reason) => {
|
||||
logInsertionOrWhatever(key, value)
|
||||
},
|
||||
|
||||
// how long to live in ms
|
||||
ttl: 1000 * 60 * 5,
|
||||
|
||||
@@ -72,11 +79,7 @@ const options = {
|
||||
|
||||
// async method to use for cache.fetch(), for
|
||||
// stale-while-revalidate type of behavior
|
||||
fetchMethod: async (
|
||||
key,
|
||||
staleValue,
|
||||
{ options, signal, context }
|
||||
) => {},
|
||||
fetchMethod: async (key, staleValue, { options, signal, context }) => {},
|
||||
}
|
||||
|
||||
const cache = new LRUCache(options)
|
||||
@@ -154,7 +157,7 @@ const cache = {
|
||||
}
|
||||
cache.timers.set(
|
||||
k,
|
||||
setTimeout(() => cache.delete(k), ttl)
|
||||
setTimeout(() => cache.delete(k), ttl),
|
||||
)
|
||||
cache.data.set(k, v)
|
||||
},
|
||||
@@ -212,9 +215,95 @@ const myGet = (key, value) => {
|
||||
}
|
||||
```
|
||||
|
||||
## Tracing and Observability
|
||||
|
||||
Most methods can accept a `status` option, which is an
|
||||
[`LRUCache.Status`](https://isaacs.github.io/node-lru-cache/interfaces/LRUCache.LRUCache.Status.html)
|
||||
object that will be decorated along the operation with
|
||||
indications about what was done and why.
|
||||
|
||||
Additionally, this library is instrumented using the
|
||||
[`node:diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html)
|
||||
module on Node and other platforms that support it. In order to
|
||||
get diagnostics metrics, listen on the
|
||||
`channel('lru-cache:metrics')`. To get Tracing Channel traces,
|
||||
subscribe to the `tracingChannel('lru-cache')`. The
|
||||
[`LRUCache.Status`](https://isaacs.github.io/node-lru-cache/interfaces/LRUCache.LRUCache.Status.html)
|
||||
objects will be provided as the message context to those channel
|
||||
listeners.
|
||||
|
||||
For example, you could do the following to get comprehensive
|
||||
information about every LRUCache instance in your application:
|
||||
|
||||
```ts
|
||||
import { tracingChannel, subscribe } from 'node:diagnostics_channel'
|
||||
|
||||
subscribe('lru-cache:metrics', (message, name) => {
|
||||
// name will always be 'lru-cache:metrics'
|
||||
// message will be the LRUCache.Status object for whatever
|
||||
// synchronous operation was performed.
|
||||
console.error('LRUCache Metrics', message)
|
||||
})
|
||||
|
||||
tracingChannel('lru-cache').subscribe({
|
||||
start: status => {
|
||||
// a traced operation is starting
|
||||
},
|
||||
asyncStart: status => {
|
||||
// an async traced operation is starting
|
||||
},
|
||||
asyncEnd: status => {
|
||||
// an async traced operation is ending
|
||||
}
|
||||
error: status => {
|
||||
// a traced operation failed
|
||||
},
|
||||
end: status => {
|
||||
// a traced operation is complete
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
The async `cache.fetch()` and `cache.forceFetch` methods are
|
||||
covered by `tracingChannels`. All the other operations are
|
||||
covered by the `lru-cache:metrics` channel, because they are
|
||||
strictly synchronous, and thus don't have an asynchronous
|
||||
lifecycle to track.
|
||||
|
||||
Note that using `status` objects or using
|
||||
`node:diagnostics_channel` listeners _will_ impose a modest
|
||||
performance penalty. Creating data objects is not ever free; do
|
||||
not believe anyone who tells you otherwise. But it is as small as
|
||||
possible.
|
||||
|
||||
### Platform Compatibility Caveat
|
||||
|
||||
Not all platforms support the `node:diagnostics_channel` module.
|
||||
Currently, this is only available in Node, Bun, and Deno, and
|
||||
some edge computing platforms that provide a Node compatibility
|
||||
layer.
|
||||
|
||||
To work around this, if you are loading in a non-Node
|
||||
environment, the package.json exports will direct your module
|
||||
loader to pull in a version that starts out with a dummy
|
||||
implementation, then does a conditional dynamic `import` of the
|
||||
`node:diagnostics_channel` module, and then swaps out those
|
||||
dummy objects with the real thing if it succeeds. This means that
|
||||
cache metrics and tracing channels started in the first load-time
|
||||
tick of your application will _not_ be covered, except in
|
||||
environments that load using the `require` import
|
||||
condition, or both the `node` and `esm` import conditions
|
||||
together.
|
||||
|
||||
Top-level await _could_ be used to remove this caveat, but that
|
||||
feature is dead on arrival, unfortunately. See
|
||||
[#397](https://github.com/isaacs/node-lru-cache/issues/397) and
|
||||
[#398](https://github.com/isaacs/node-lru-cache/issues/398) for
|
||||
more details.
|
||||
|
||||
## Performance
|
||||
|
||||
As of January 2022, version 7 of this library is one of the most
|
||||
As of April 2026, version 11 of this library is one of the most
|
||||
performant LRU cache implementations in JavaScript.
|
||||
|
||||
Benchmarks can be extremely difficult to get right. In
|
||||
@@ -269,9 +358,9 @@ If performance matters to you:
|
||||
LRUCache](https://yomguithereal.github.io/mnemonist/lru-cache)
|
||||
which uses an Object as its data store.
|
||||
|
||||
2. Failing that, if at all possible, use short non-numeric
|
||||
strings (ie, less than 256 characters) as your keys, and use
|
||||
[mnemonist's
|
||||
2. Failing that, if you can use short non-numeric strings (ie,
|
||||
less than 256 characters) as your keys, and you do not need
|
||||
any of the other features of this library, use [mnemonist's
|
||||
LRUCache](https://yomguithereal.github.io/mnemonist/lru-cache).
|
||||
|
||||
3. If the types of your keys will be anything else, especially
|
||||
@@ -283,14 +372,63 @@ If performance matters to you:
|
||||
(like asynchronous fetching, a variety of TTL staleness
|
||||
options, and so on), then [mnemonist's
|
||||
LRUMap](https://yomguithereal.github.io/mnemonist/lru-map) is
|
||||
a very good option, and just slightly faster than this module
|
||||
(since it does considerably less).
|
||||
also a very good option, and just slightly faster than this
|
||||
module (since it does considerably less).
|
||||
|
||||
4. Do not use a `dispose` function, size tracking, or especially
|
||||
ttl behavior, unless absolutely needed. These features are
|
||||
convenient, and necessary in some use cases, and every attempt
|
||||
has been made to make the performance impact minimal, but it
|
||||
isn't nothing.
|
||||
ttl behavior or observability features, unless absolutely
|
||||
needed. These features are convenient, and necessary in some
|
||||
use cases, and every attempt has been made to make the
|
||||
performance impact minimal, but it isn't nothing.
|
||||
|
||||
## Testing
|
||||
|
||||
When writing tests that involve TTL-related functionality, note
|
||||
that this module creates an internal reference to the global
|
||||
`performance` or `Date` objects at import time. If you import it
|
||||
statically at the top level, those references cannot be mocked or
|
||||
overridden in your test environment.
|
||||
|
||||
To avoid this, dynamically import the package within your tests
|
||||
so that the references are captured after your mocks are applied.
|
||||
For example:
|
||||
|
||||
```ts
|
||||
// ❌ Not recommended
|
||||
import { LRUCache } from 'lru-cache'
|
||||
// mocking timers, e.g. jest.useFakeTimers()
|
||||
|
||||
// ✅ Recommended for TTL tests
|
||||
// mocking timers, e.g. jest.useFakeTimers()
|
||||
const { LRUCache } = await import('lru-cache')
|
||||
```
|
||||
|
||||
This ensures that your mocked timers or time sources are
|
||||
respected when testing TTL behavior.
|
||||
|
||||
Additionally, you can pass in a `perf` option when creating your
|
||||
LRUCache instance. This option accepts any object with a `now`
|
||||
method that returns a number.
|
||||
|
||||
For example, this would be a very bare-bones time-mocking system
|
||||
you could use in your tests, without any particular test
|
||||
framework:
|
||||
|
||||
```ts
|
||||
import { LRUCache } from 'lru-cache'
|
||||
|
||||
let myClockTime = 0
|
||||
|
||||
const cache = new LRUCache<string>({
|
||||
max: 10,
|
||||
ttl: 1000,
|
||||
perf: {
|
||||
now: () => myClockTime,
|
||||
},
|
||||
})
|
||||
|
||||
// run tests, updating myClockTime as needed
|
||||
```
|
||||
|
||||
## Breaking Changes in Version 7
|
||||
|
||||
|
||||
+156
-33
@@ -1,6 +1,8 @@
|
||||
/**
|
||||
* @module LRUCache
|
||||
*/
|
||||
import type { Perf } from './perf.js';
|
||||
export type { Perf } from './perf.js';
|
||||
declare const TYPE: unique symbol;
|
||||
export type PosInt = number & {
|
||||
[TYPE]: 'Positive Integer';
|
||||
@@ -75,6 +77,20 @@ export declare namespace LRUCache {
|
||||
* {@link OptionsBase.disposeAfter} options.
|
||||
*/
|
||||
type Disposer<K, V> = (value: V, key: K, reason: DisposeReason) => void;
|
||||
/**
|
||||
* The reason why an item was added to the cache, passed
|
||||
* to the {@link Inserter} methods.
|
||||
*
|
||||
* - `add`: the item was not found in the cache, and was added
|
||||
* - `update`: the item was in the cache, with the same value provided
|
||||
* - `replace`: the item was in the cache, and replaced
|
||||
*/
|
||||
type InsertReason = 'add' | 'update' | 'replace';
|
||||
/**
|
||||
* A method called upon item insertion, passed as the
|
||||
* {@link OptionsBase.insert}
|
||||
*/
|
||||
type Inserter<K, V> = (value: V, key: K, reason: InsertReason) => void;
|
||||
/**
|
||||
* A function that returns the effective calculated size
|
||||
* of an entry in the cache.
|
||||
@@ -102,8 +118,16 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* The `status` option should be a plain JavaScript object. The following
|
||||
* fields will be set on it appropriately, depending on the situation.
|
||||
*
|
||||
* These objects are also the context objects passed to listeners on the
|
||||
* `lru-cache:metrics` diagnostic channel, and the `lru-cache` tracing
|
||||
* channels, in platforms that support them.
|
||||
*/
|
||||
interface Status<V> {
|
||||
interface Status<K, V, FC = unknown> {
|
||||
/**
|
||||
* The operation being performed
|
||||
*/
|
||||
op?: 'get' | 'set' | 'memo' | 'fetch' | 'delete' | 'has' | 'peek';
|
||||
/**
|
||||
* The status of a set() operation.
|
||||
*
|
||||
@@ -112,7 +136,37 @@ export declare namespace LRUCache {
|
||||
* - replace: the item was in the cache, and replaced
|
||||
* - miss: the item was not added to the cache for some reason
|
||||
*/
|
||||
set?: 'add' | 'update' | 'replace' | 'miss';
|
||||
set?: 'add' | 'update' | 'replace' | 'miss' | 'deleted';
|
||||
/**
|
||||
* The status of a delete() operation.
|
||||
*/
|
||||
delete?: LRUCache.DisposeReason;
|
||||
/**
|
||||
* The result of a peek() operation
|
||||
*
|
||||
* - hit: the item was found and returned
|
||||
* - stale: the item is in the cache, but past its ttl and not returned
|
||||
* - miss: item not in the cache
|
||||
*/
|
||||
peek?: 'hit' | 'miss' | 'stale';
|
||||
/**
|
||||
* The status of a memo() operation.
|
||||
*
|
||||
* - 'hit': the item was found in the cache and returned
|
||||
* - 'miss': the `memoMethod` function was called
|
||||
*/
|
||||
memo?: 'hit' | 'miss';
|
||||
/**
|
||||
* The `context` option provided to a memo or fetch operation
|
||||
*
|
||||
* In practice, of course, this will be the same type as the `FC`
|
||||
* fetch context param used to instantiate the LRUCache, but the
|
||||
* convolutions of threading that through would get quite complicated,
|
||||
* and preclude forcing/forbidding the passing of a `context` param
|
||||
* where it is/isn't expected, which is more valuable for error
|
||||
* prevention.
|
||||
*/
|
||||
context?: unknown;
|
||||
/**
|
||||
* the ttl stored for the item, or undefined if ttls are not used.
|
||||
*/
|
||||
@@ -143,8 +197,15 @@ export declare namespace LRUCache {
|
||||
*/
|
||||
maxEntrySizeExceeded?: true;
|
||||
/**
|
||||
* The old value, specified in the case of `set:'update'` or
|
||||
* `set:'replace'`
|
||||
* The key that was set or retrieved
|
||||
*/
|
||||
key?: K;
|
||||
/**
|
||||
* The value that was set
|
||||
*/
|
||||
value?: V;
|
||||
/**
|
||||
* The old value, specified in the case of `set:'replace'`
|
||||
*/
|
||||
oldValue?: V;
|
||||
/**
|
||||
@@ -170,6 +231,10 @@ export declare namespace LRUCache {
|
||||
* {@link FetchOptions.forceRefresh} was specified.
|
||||
*/
|
||||
fetch?: 'get' | 'inflight' | 'miss' | 'hit' | 'stale' | 'refresh';
|
||||
/**
|
||||
* `forceRefresh` option was used for either a fetch or memo operation
|
||||
*/
|
||||
forceRefresh?: boolean;
|
||||
/**
|
||||
* The {@link OptionsBase.fetchMethod} was called
|
||||
*/
|
||||
@@ -191,7 +256,7 @@ export declare namespace LRUCache {
|
||||
fetchAborted?: true;
|
||||
/**
|
||||
* The abort signal received was ignored, and the fetch was allowed to
|
||||
* continue.
|
||||
* continue in the background.
|
||||
*/
|
||||
fetchAbortIgnored?: true;
|
||||
/**
|
||||
@@ -207,15 +272,27 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* - fetching: The item is currently being fetched. If a previous value
|
||||
* is present and allowed, that will be returned.
|
||||
* - stale: The item is in the cache, and is stale.
|
||||
* - stale: The item is in the cache, and is stale. If it was returned,
|
||||
* then the `returnedStale` flag will be set.
|
||||
* - stale-fetching: The value is being fetched in the background, but is
|
||||
* currently stale. If the stale value was returned, then the
|
||||
* `returnedStale` flag will be set.
|
||||
* - hit: the item is in the cache
|
||||
* - miss: the item is not in the cache
|
||||
*/
|
||||
get?: 'stale' | 'hit' | 'miss';
|
||||
get?: 'stale' | 'hit' | 'miss' | 'fetching' | 'stale-fetching';
|
||||
/**
|
||||
* A fetch or get operation returned a stale value.
|
||||
*/
|
||||
returnedStale?: true;
|
||||
/**
|
||||
* A tracingChannel trace was started for this operation
|
||||
*/
|
||||
trace?: boolean;
|
||||
/**
|
||||
* A reference to the cache instance associated with this operation
|
||||
*/
|
||||
cache?: LRUCache<K & {}, V & {}, FC>;
|
||||
}
|
||||
/**
|
||||
* options which override the options set in the LRUCache constructor
|
||||
@@ -233,7 +310,7 @@ export declare namespace LRUCache {
|
||||
* the fetchMethod is called.
|
||||
*/
|
||||
interface FetcherFetchOptions<K, V, FC = unknown> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet' | 'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL' | 'noDeleteOnFetchRejection' | 'allowStaleOnFetchRejection' | 'ignoreFetchAbort' | 'allowStaleOnFetchAbort'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
size?: Size;
|
||||
}
|
||||
/**
|
||||
@@ -255,7 +332,7 @@ export declare namespace LRUCache {
|
||||
*/
|
||||
context?: FC;
|
||||
signal?: AbortSignal;
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options provided to {@link LRUCache#fetch} when the FC type is something
|
||||
@@ -268,7 +345,7 @@ export declare namespace LRUCache {
|
||||
* Options provided to {@link LRUCache#fetch} when the FC type is
|
||||
* `undefined` or `void`
|
||||
*/
|
||||
interface FetchOptionsNoContext<K, V> extends FetchOptions<K, V, undefined> {
|
||||
interface FetchOptionsNoContext<K, V, FC extends undefined | void = undefined> extends FetchOptions<K, V, FC> {
|
||||
context?: undefined;
|
||||
}
|
||||
interface MemoOptions<K, V, FC = unknown> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet' | 'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL' | 'noDeleteOnFetchRejection' | 'allowStaleOnFetchRejection' | 'ignoreFetchAbort' | 'allowStaleOnFetchAbort'> {
|
||||
@@ -286,7 +363,7 @@ export declare namespace LRUCache {
|
||||
* be required.
|
||||
*/
|
||||
context?: FC;
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options provided to {@link LRUCache#memo} when the FC type is something
|
||||
@@ -299,7 +376,7 @@ export declare namespace LRUCache {
|
||||
* Options provided to {@link LRUCache#memo} when the FC type is
|
||||
* `undefined` or `void`
|
||||
*/
|
||||
interface MemoOptionsNoContext<K, V> extends MemoOptions<K, V, undefined> {
|
||||
interface MemoOptionsNoContext<K, V, FC extends undefined | void = undefined> extends MemoOptions<K, V, FC> {
|
||||
context?: undefined;
|
||||
}
|
||||
/**
|
||||
@@ -320,7 +397,7 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* This is the union of {@link GetOptions} and {@link SetOptions}, plus
|
||||
* {@link MemoOptions.forceRefresh}, and
|
||||
* {@link MemoerOptions.context}
|
||||
* {@link MemoOptions.context}
|
||||
*
|
||||
* Any of these may be modified in the {@link OptionsBase.memoMethod}
|
||||
* function, but the {@link GetOptions} fields will of course have no
|
||||
@@ -328,7 +405,7 @@ export declare namespace LRUCache {
|
||||
* the memoMethod is called.
|
||||
*/
|
||||
interface MemoizerMemoOptions<K, V, FC = unknown> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet' | 'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
size?: Size;
|
||||
start?: Milliseconds;
|
||||
}
|
||||
@@ -336,18 +413,19 @@ export declare namespace LRUCache {
|
||||
* Options that may be passed to the {@link LRUCache#has} method.
|
||||
*/
|
||||
interface HasOptions<K, V, FC> extends Pick<OptionsBase<K, V, FC>, 'updateAgeOnHas'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options that may be passed to the {@link LRUCache#get} method.
|
||||
*/
|
||||
interface GetOptions<K, V, FC> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options that may be passed to the {@link LRUCache#peek} method.
|
||||
*/
|
||||
interface PeekOptions<K, V, FC> extends Pick<OptionsBase<K, V, FC>, 'allowStale'> {
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options that may be passed to the {@link LRUCache#set} method.
|
||||
@@ -368,7 +446,7 @@ export declare namespace LRUCache {
|
||||
* method is in use.
|
||||
*/
|
||||
start?: Milliseconds;
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* The type signature for the {@link OptionsBase.fetchMethod} option.
|
||||
@@ -555,6 +633,17 @@ export declare namespace LRUCache {
|
||||
* `cache.clear()`, or `cache.set(key, undefined)`.
|
||||
*/
|
||||
dispose?: Disposer<K, V>;
|
||||
/**
|
||||
* Function that is called when new items are inserted into the cache,
|
||||
* as `onInsert(value, key, reason)`.
|
||||
*
|
||||
* This can be useful if you need to perform actions when an item is
|
||||
* added, such as logging or tracking insertions.
|
||||
*
|
||||
* Unlike some other options, this may _not_ be overridden by passing
|
||||
* an option to `set()`, for performance and consistency reasons.
|
||||
*/
|
||||
onInsert?: Inserter<K, V>;
|
||||
/**
|
||||
* The same as {@link OptionsBase.dispose}, but called *after* the entry
|
||||
* is completely removed and the cache is once again in a clean state.
|
||||
@@ -610,6 +699,20 @@ export declare namespace LRUCache {
|
||||
* though for most cases, only minimally.
|
||||
*/
|
||||
maxSize?: Size;
|
||||
/**
|
||||
* The effective size for background fetch promises.
|
||||
*
|
||||
* This has no effect unless `maxSize` and `sizeCalculation` are used,
|
||||
* and a {@link LRUCache.OptionsBase.fetchMethod} is provided to
|
||||
* support {@link LRUCache#fetch}.
|
||||
*
|
||||
* If a stale value is present in the cache, then the effective size of
|
||||
* the background fetch is the size of the stale item it will eventually
|
||||
* replace. If not, then this value is used as its effective size.
|
||||
*
|
||||
* @default 1
|
||||
*/
|
||||
backgroundFetchSize?: number;
|
||||
/**
|
||||
* The maximum allowed size for any single item in the cache.
|
||||
*
|
||||
@@ -796,6 +899,15 @@ export declare namespace LRUCache {
|
||||
* call to {@link LRUCache#fetch}.
|
||||
*/
|
||||
ignoreFetchAbort?: boolean;
|
||||
/**
|
||||
* In some cases, you may want to swap out the performance/Date object
|
||||
* used for TTL tracking. This should almost certainly NOT be done in
|
||||
* production environments!
|
||||
*
|
||||
* This value defaults to `global.performance` if it has a `now()` method,
|
||||
* or the `global.Date` object otherwise.
|
||||
*/
|
||||
perf?: Perf;
|
||||
}
|
||||
interface OptionsMaxLimit<K, V, FC> extends OptionsBase<K, V, FC> {
|
||||
max: Count;
|
||||
@@ -837,8 +949,12 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* Changing any of these will alter the defaults for subsequent method calls.
|
||||
*/
|
||||
export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implements Map<K, V> {
|
||||
export declare class LRUCache<K extends {}, V extends {}, FC = unknown> {
|
||||
#private;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.perf}
|
||||
*/
|
||||
get perf(): Perf;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.ttl}
|
||||
*/
|
||||
@@ -899,6 +1015,8 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* {@link LRUCache.OptionsBase.ignoreFetchAbort}
|
||||
*/
|
||||
ignoreFetchAbort: boolean;
|
||||
/** {@link LRUCache.OptionsBase.backgroundFetchSize} */
|
||||
backgroundFetchSize: number;
|
||||
/**
|
||||
* Do not call this method unless you need to inspect the
|
||||
* inner workings of the cache. If anything returned by this
|
||||
@@ -911,6 +1029,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
static unsafeExposeInternals<K extends {}, V extends {}, FC extends unknown = unknown>(c: LRUCache<K, V, FC>): {
|
||||
starts: ZeroArray | undefined;
|
||||
ttls: ZeroArray | undefined;
|
||||
autopurgeTimers: (NodeJS.Timeout | undefined)[] | undefined;
|
||||
sizes: ZeroArray | undefined;
|
||||
keyMap: Map<K, number>;
|
||||
keyList: (K | undefined)[];
|
||||
@@ -920,8 +1039,8 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
readonly head: Index;
|
||||
readonly tail: Index;
|
||||
free: StackLike;
|
||||
isBackgroundFetch: (p: any) => boolean;
|
||||
backgroundFetch: (k: K, index: number | undefined, options: LRUCache.FetchOptions<K, V, FC>, context: any) => BackgroundFetch<V>;
|
||||
isBackgroundFetch: (p: unknown) => p is BackgroundFetch<V>;
|
||||
backgroundFetch: (k: K, index: number | undefined, options: LRUCache.FetchOptions<K, V, FC>, context: unknown) => BackgroundFetch<V>;
|
||||
moveToTail: (index: number) => void;
|
||||
indexes: (options?: {
|
||||
allowStale: boolean;
|
||||
@@ -956,6 +1075,10 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* {@link LRUCache.OptionsBase.dispose} (read-only)
|
||||
*/
|
||||
get dispose(): LRUCache.Disposer<K, V> | undefined;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.onInsert} (read-only)
|
||||
*/
|
||||
get onInsert(): LRUCache.Inserter<K, V> | undefined;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.disposeAfter} (read-only)
|
||||
*/
|
||||
@@ -977,7 +1100,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* Return a generator yielding `[key, value]` pairs,
|
||||
* in order from least recently used to most recently used.
|
||||
*/
|
||||
rentries(): Generator<(K | V | BackgroundFetch<V> | undefined)[], void, unknown>;
|
||||
rentries(): Generator<(K | V)[], void, unknown>;
|
||||
/**
|
||||
* Return a generator yielding the keys in the cache,
|
||||
* in order from most recently used to least recently used.
|
||||
@@ -1001,7 +1124,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* Return a generator yielding the values in the cache,
|
||||
* in order from least recently used to most recently used.
|
||||
*/
|
||||
rvalues(): Generator<V | BackgroundFetch<V> | undefined, void, unknown>;
|
||||
rvalues(): Generator<V | undefined, void, unknown>;
|
||||
/**
|
||||
* Iterating over the cache itself yields the same results as
|
||||
* {@link LRUCache.entries}
|
||||
@@ -1029,12 +1152,12 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
*
|
||||
* Does not update age or recenty of use, or iterate over stale values.
|
||||
*/
|
||||
forEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any, thisp?: any): void;
|
||||
forEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => unknown, thisp?: unknown): void;
|
||||
/**
|
||||
* The same as {@link LRUCache.forEach} but items are iterated over in
|
||||
* reverse order. (ie, less recently used items are iterated over first.)
|
||||
*/
|
||||
rforEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any, thisp?: any): void;
|
||||
rforEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => unknown, thisp?: unknown): void;
|
||||
/**
|
||||
* Delete any stale entries. Returns true if anything was removed,
|
||||
* false otherwise.
|
||||
@@ -1055,7 +1178,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
info(key: K): LRUCache.Entry<V> | undefined;
|
||||
/**
|
||||
* Return an array of [key, {@link LRUCache.Entry}] tuples which can be
|
||||
* passed to {@link LRLUCache#load}.
|
||||
* passed to {@link LRUCache#load}.
|
||||
*
|
||||
* The `start` fields are calculated relative to a portable `Date.now()`
|
||||
* timestamp, even if `performance.now()` is available.
|
||||
@@ -1107,7 +1230,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* If the value is `undefined`, then this is an alias for
|
||||
* `cache.delete(key)`. `undefined` is never stored in the cache.
|
||||
*/
|
||||
set(k: K, v: V | BackgroundFetch<V> | undefined, setOptions?: LRUCache.SetOptions<K, V, FC>): this;
|
||||
set(k: K, v: V | undefined, setOptions?: LRUCache.SetOptions<K, V, FC>): this;
|
||||
/**
|
||||
* Evict the least recently used item, returning its value or
|
||||
* `undefined` if cache is empty.
|
||||
@@ -1223,23 +1346,23 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* the same time, because they're both waiting on the same
|
||||
* underlying fetchMethod response.
|
||||
*/
|
||||
fetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<undefined | V>;
|
||||
fetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : never): Promise<undefined | V>;
|
||||
fetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<undefined | V>;
|
||||
fetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : never): Promise<undefined | V>;
|
||||
/**
|
||||
* In some cases, `cache.fetch()` may resolve to `undefined`, either because
|
||||
* a {@link LRUCache.OptionsBase#fetchMethod} was not provided (turning
|
||||
* `cache.fetch(k)` into just an async wrapper around `cache.get(k)`) or
|
||||
* because `ignoreFetchAbort` was specified (either to the constructor or
|
||||
* in the {@link LRUCache.FetchOptions}). Also, the
|
||||
* {@link OptionsBase.fetchMethod} may return `undefined` or `void`, making
|
||||
* {@link LRUCache.OptionsBase.fetchMethod} may return `undefined` or `void`, making
|
||||
* the test even more complicated.
|
||||
*
|
||||
* Because inferring the cases where `undefined` might be returned are so
|
||||
* cumbersome, but testing for `undefined` can also be annoying, this method
|
||||
* can be used, which will reject if `this.fetch()` resolves to undefined.
|
||||
*/
|
||||
forceFetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<V>;
|
||||
forceFetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : never): Promise<V>;
|
||||
forceFetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<V>;
|
||||
forceFetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : never): Promise<V>;
|
||||
/**
|
||||
* If the key is found in the cache, then this is equivalent to
|
||||
* {@link LRUCache#get}. If not, in the cache, then calculate the value using
|
||||
@@ -1254,8 +1377,8 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* relevant in the course of fetching the data. It is only relevant for the
|
||||
* course of a single `memo()` operation, and discarded afterwards.
|
||||
*/
|
||||
memo(k: K, memoOptions: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V> : LRUCache.MemoOptionsWithContext<K, V, FC>): V;
|
||||
memo(k: unknown extends FC ? K : FC extends undefined | void ? K : never, memoOptions?: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V> : never): V;
|
||||
memo(k: K, memoOptions: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V, FC> : LRUCache.MemoOptionsWithContext<K, V, FC>): V;
|
||||
memo(k: unknown extends FC ? K : FC extends undefined | void ? K : never, memoOptions?: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V, FC> : never): V;
|
||||
/**
|
||||
* Return a value from the cache. Will update the recency of the cache
|
||||
* entry found.
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+425
-245
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+156
-33
@@ -1,6 +1,8 @@
|
||||
/**
|
||||
* @module LRUCache
|
||||
*/
|
||||
import type { Perf } from './perf.js';
|
||||
export type { Perf } from './perf.js';
|
||||
declare const TYPE: unique symbol;
|
||||
export type PosInt = number & {
|
||||
[TYPE]: 'Positive Integer';
|
||||
@@ -75,6 +77,20 @@ export declare namespace LRUCache {
|
||||
* {@link OptionsBase.disposeAfter} options.
|
||||
*/
|
||||
type Disposer<K, V> = (value: V, key: K, reason: DisposeReason) => void;
|
||||
/**
|
||||
* The reason why an item was added to the cache, passed
|
||||
* to the {@link Inserter} methods.
|
||||
*
|
||||
* - `add`: the item was not found in the cache, and was added
|
||||
* - `update`: the item was in the cache, with the same value provided
|
||||
* - `replace`: the item was in the cache, and replaced
|
||||
*/
|
||||
type InsertReason = 'add' | 'update' | 'replace';
|
||||
/**
|
||||
* A method called upon item insertion, passed as the
|
||||
* {@link OptionsBase.insert}
|
||||
*/
|
||||
type Inserter<K, V> = (value: V, key: K, reason: InsertReason) => void;
|
||||
/**
|
||||
* A function that returns the effective calculated size
|
||||
* of an entry in the cache.
|
||||
@@ -102,8 +118,16 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* The `status` option should be a plain JavaScript object. The following
|
||||
* fields will be set on it appropriately, depending on the situation.
|
||||
*
|
||||
* These objects are also the context objects passed to listeners on the
|
||||
* `lru-cache:metrics` diagnostic channel, and the `lru-cache` tracing
|
||||
* channels, in platforms that support them.
|
||||
*/
|
||||
interface Status<V> {
|
||||
interface Status<K, V, FC = unknown> {
|
||||
/**
|
||||
* The operation being performed
|
||||
*/
|
||||
op?: 'get' | 'set' | 'memo' | 'fetch' | 'delete' | 'has' | 'peek';
|
||||
/**
|
||||
* The status of a set() operation.
|
||||
*
|
||||
@@ -112,7 +136,37 @@ export declare namespace LRUCache {
|
||||
* - replace: the item was in the cache, and replaced
|
||||
* - miss: the item was not added to the cache for some reason
|
||||
*/
|
||||
set?: 'add' | 'update' | 'replace' | 'miss';
|
||||
set?: 'add' | 'update' | 'replace' | 'miss' | 'deleted';
|
||||
/**
|
||||
* The status of a delete() operation.
|
||||
*/
|
||||
delete?: LRUCache.DisposeReason;
|
||||
/**
|
||||
* The result of a peek() operation
|
||||
*
|
||||
* - hit: the item was found and returned
|
||||
* - stale: the item is in the cache, but past its ttl and not returned
|
||||
* - miss: item not in the cache
|
||||
*/
|
||||
peek?: 'hit' | 'miss' | 'stale';
|
||||
/**
|
||||
* The status of a memo() operation.
|
||||
*
|
||||
* - 'hit': the item was found in the cache and returned
|
||||
* - 'miss': the `memoMethod` function was called
|
||||
*/
|
||||
memo?: 'hit' | 'miss';
|
||||
/**
|
||||
* The `context` option provided to a memo or fetch operation
|
||||
*
|
||||
* In practice, of course, this will be the same type as the `FC`
|
||||
* fetch context param used to instantiate the LRUCache, but the
|
||||
* convolutions of threading that through would get quite complicated,
|
||||
* and preclude forcing/forbidding the passing of a `context` param
|
||||
* where it is/isn't expected, which is more valuable for error
|
||||
* prevention.
|
||||
*/
|
||||
context?: unknown;
|
||||
/**
|
||||
* the ttl stored for the item, or undefined if ttls are not used.
|
||||
*/
|
||||
@@ -143,8 +197,15 @@ export declare namespace LRUCache {
|
||||
*/
|
||||
maxEntrySizeExceeded?: true;
|
||||
/**
|
||||
* The old value, specified in the case of `set:'update'` or
|
||||
* `set:'replace'`
|
||||
* The key that was set or retrieved
|
||||
*/
|
||||
key?: K;
|
||||
/**
|
||||
* The value that was set
|
||||
*/
|
||||
value?: V;
|
||||
/**
|
||||
* The old value, specified in the case of `set:'replace'`
|
||||
*/
|
||||
oldValue?: V;
|
||||
/**
|
||||
@@ -170,6 +231,10 @@ export declare namespace LRUCache {
|
||||
* {@link FetchOptions.forceRefresh} was specified.
|
||||
*/
|
||||
fetch?: 'get' | 'inflight' | 'miss' | 'hit' | 'stale' | 'refresh';
|
||||
/**
|
||||
* `forceRefresh` option was used for either a fetch or memo operation
|
||||
*/
|
||||
forceRefresh?: boolean;
|
||||
/**
|
||||
* The {@link OptionsBase.fetchMethod} was called
|
||||
*/
|
||||
@@ -191,7 +256,7 @@ export declare namespace LRUCache {
|
||||
fetchAborted?: true;
|
||||
/**
|
||||
* The abort signal received was ignored, and the fetch was allowed to
|
||||
* continue.
|
||||
* continue in the background.
|
||||
*/
|
||||
fetchAbortIgnored?: true;
|
||||
/**
|
||||
@@ -207,15 +272,27 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* - fetching: The item is currently being fetched. If a previous value
|
||||
* is present and allowed, that will be returned.
|
||||
* - stale: The item is in the cache, and is stale.
|
||||
* - stale: The item is in the cache, and is stale. If it was returned,
|
||||
* then the `returnedStale` flag will be set.
|
||||
* - stale-fetching: The value is being fetched in the background, but is
|
||||
* currently stale. If the stale value was returned, then the
|
||||
* `returnedStale` flag will be set.
|
||||
* - hit: the item is in the cache
|
||||
* - miss: the item is not in the cache
|
||||
*/
|
||||
get?: 'stale' | 'hit' | 'miss';
|
||||
get?: 'stale' | 'hit' | 'miss' | 'fetching' | 'stale-fetching';
|
||||
/**
|
||||
* A fetch or get operation returned a stale value.
|
||||
*/
|
||||
returnedStale?: true;
|
||||
/**
|
||||
* A tracingChannel trace was started for this operation
|
||||
*/
|
||||
trace?: boolean;
|
||||
/**
|
||||
* A reference to the cache instance associated with this operation
|
||||
*/
|
||||
cache?: LRUCache<K & {}, V & {}, FC>;
|
||||
}
|
||||
/**
|
||||
* options which override the options set in the LRUCache constructor
|
||||
@@ -233,7 +310,7 @@ export declare namespace LRUCache {
|
||||
* the fetchMethod is called.
|
||||
*/
|
||||
interface FetcherFetchOptions<K, V, FC = unknown> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet' | 'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL' | 'noDeleteOnFetchRejection' | 'allowStaleOnFetchRejection' | 'ignoreFetchAbort' | 'allowStaleOnFetchAbort'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
size?: Size;
|
||||
}
|
||||
/**
|
||||
@@ -255,7 +332,7 @@ export declare namespace LRUCache {
|
||||
*/
|
||||
context?: FC;
|
||||
signal?: AbortSignal;
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options provided to {@link LRUCache#fetch} when the FC type is something
|
||||
@@ -268,7 +345,7 @@ export declare namespace LRUCache {
|
||||
* Options provided to {@link LRUCache#fetch} when the FC type is
|
||||
* `undefined` or `void`
|
||||
*/
|
||||
interface FetchOptionsNoContext<K, V> extends FetchOptions<K, V, undefined> {
|
||||
interface FetchOptionsNoContext<K, V, FC extends undefined | void = undefined> extends FetchOptions<K, V, FC> {
|
||||
context?: undefined;
|
||||
}
|
||||
interface MemoOptions<K, V, FC = unknown> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet' | 'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL' | 'noDeleteOnFetchRejection' | 'allowStaleOnFetchRejection' | 'ignoreFetchAbort' | 'allowStaleOnFetchAbort'> {
|
||||
@@ -286,7 +363,7 @@ export declare namespace LRUCache {
|
||||
* be required.
|
||||
*/
|
||||
context?: FC;
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options provided to {@link LRUCache#memo} when the FC type is something
|
||||
@@ -299,7 +376,7 @@ export declare namespace LRUCache {
|
||||
* Options provided to {@link LRUCache#memo} when the FC type is
|
||||
* `undefined` or `void`
|
||||
*/
|
||||
interface MemoOptionsNoContext<K, V> extends MemoOptions<K, V, undefined> {
|
||||
interface MemoOptionsNoContext<K, V, FC extends undefined | void = undefined> extends MemoOptions<K, V, FC> {
|
||||
context?: undefined;
|
||||
}
|
||||
/**
|
||||
@@ -320,7 +397,7 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* This is the union of {@link GetOptions} and {@link SetOptions}, plus
|
||||
* {@link MemoOptions.forceRefresh}, and
|
||||
* {@link MemoerOptions.context}
|
||||
* {@link MemoOptions.context}
|
||||
*
|
||||
* Any of these may be modified in the {@link OptionsBase.memoMethod}
|
||||
* function, but the {@link GetOptions} fields will of course have no
|
||||
@@ -328,7 +405,7 @@ export declare namespace LRUCache {
|
||||
* the memoMethod is called.
|
||||
*/
|
||||
interface MemoizerMemoOptions<K, V, FC = unknown> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet' | 'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
size?: Size;
|
||||
start?: Milliseconds;
|
||||
}
|
||||
@@ -336,18 +413,19 @@ export declare namespace LRUCache {
|
||||
* Options that may be passed to the {@link LRUCache#has} method.
|
||||
*/
|
||||
interface HasOptions<K, V, FC> extends Pick<OptionsBase<K, V, FC>, 'updateAgeOnHas'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options that may be passed to the {@link LRUCache#get} method.
|
||||
*/
|
||||
interface GetOptions<K, V, FC> extends Pick<OptionsBase<K, V, FC>, 'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet'> {
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options that may be passed to the {@link LRUCache#peek} method.
|
||||
*/
|
||||
interface PeekOptions<K, V, FC> extends Pick<OptionsBase<K, V, FC>, 'allowStale'> {
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* Options that may be passed to the {@link LRUCache#set} method.
|
||||
@@ -368,7 +446,7 @@ export declare namespace LRUCache {
|
||||
* method is in use.
|
||||
*/
|
||||
start?: Milliseconds;
|
||||
status?: Status<V>;
|
||||
status?: Status<K, V, FC>;
|
||||
}
|
||||
/**
|
||||
* The type signature for the {@link OptionsBase.fetchMethod} option.
|
||||
@@ -555,6 +633,17 @@ export declare namespace LRUCache {
|
||||
* `cache.clear()`, or `cache.set(key, undefined)`.
|
||||
*/
|
||||
dispose?: Disposer<K, V>;
|
||||
/**
|
||||
* Function that is called when new items are inserted into the cache,
|
||||
* as `onInsert(value, key, reason)`.
|
||||
*
|
||||
* This can be useful if you need to perform actions when an item is
|
||||
* added, such as logging or tracking insertions.
|
||||
*
|
||||
* Unlike some other options, this may _not_ be overridden by passing
|
||||
* an option to `set()`, for performance and consistency reasons.
|
||||
*/
|
||||
onInsert?: Inserter<K, V>;
|
||||
/**
|
||||
* The same as {@link OptionsBase.dispose}, but called *after* the entry
|
||||
* is completely removed and the cache is once again in a clean state.
|
||||
@@ -610,6 +699,20 @@ export declare namespace LRUCache {
|
||||
* though for most cases, only minimally.
|
||||
*/
|
||||
maxSize?: Size;
|
||||
/**
|
||||
* The effective size for background fetch promises.
|
||||
*
|
||||
* This has no effect unless `maxSize` and `sizeCalculation` are used,
|
||||
* and a {@link LRUCache.OptionsBase.fetchMethod} is provided to
|
||||
* support {@link LRUCache#fetch}.
|
||||
*
|
||||
* If a stale value is present in the cache, then the effective size of
|
||||
* the background fetch is the size of the stale item it will eventually
|
||||
* replace. If not, then this value is used as its effective size.
|
||||
*
|
||||
* @default 1
|
||||
*/
|
||||
backgroundFetchSize?: number;
|
||||
/**
|
||||
* The maximum allowed size for any single item in the cache.
|
||||
*
|
||||
@@ -796,6 +899,15 @@ export declare namespace LRUCache {
|
||||
* call to {@link LRUCache#fetch}.
|
||||
*/
|
||||
ignoreFetchAbort?: boolean;
|
||||
/**
|
||||
* In some cases, you may want to swap out the performance/Date object
|
||||
* used for TTL tracking. This should almost certainly NOT be done in
|
||||
* production environments!
|
||||
*
|
||||
* This value defaults to `global.performance` if it has a `now()` method,
|
||||
* or the `global.Date` object otherwise.
|
||||
*/
|
||||
perf?: Perf;
|
||||
}
|
||||
interface OptionsMaxLimit<K, V, FC> extends OptionsBase<K, V, FC> {
|
||||
max: Count;
|
||||
@@ -837,8 +949,12 @@ export declare namespace LRUCache {
|
||||
*
|
||||
* Changing any of these will alter the defaults for subsequent method calls.
|
||||
*/
|
||||
export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implements Map<K, V> {
|
||||
export declare class LRUCache<K extends {}, V extends {}, FC = unknown> {
|
||||
#private;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.perf}
|
||||
*/
|
||||
get perf(): Perf;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.ttl}
|
||||
*/
|
||||
@@ -899,6 +1015,8 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* {@link LRUCache.OptionsBase.ignoreFetchAbort}
|
||||
*/
|
||||
ignoreFetchAbort: boolean;
|
||||
/** {@link LRUCache.OptionsBase.backgroundFetchSize} */
|
||||
backgroundFetchSize: number;
|
||||
/**
|
||||
* Do not call this method unless you need to inspect the
|
||||
* inner workings of the cache. If anything returned by this
|
||||
@@ -911,6 +1029,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
static unsafeExposeInternals<K extends {}, V extends {}, FC extends unknown = unknown>(c: LRUCache<K, V, FC>): {
|
||||
starts: ZeroArray | undefined;
|
||||
ttls: ZeroArray | undefined;
|
||||
autopurgeTimers: (NodeJS.Timeout | undefined)[] | undefined;
|
||||
sizes: ZeroArray | undefined;
|
||||
keyMap: Map<K, number>;
|
||||
keyList: (K | undefined)[];
|
||||
@@ -920,8 +1039,8 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
readonly head: Index;
|
||||
readonly tail: Index;
|
||||
free: StackLike;
|
||||
isBackgroundFetch: (p: any) => boolean;
|
||||
backgroundFetch: (k: K, index: number | undefined, options: LRUCache.FetchOptions<K, V, FC>, context: any) => BackgroundFetch<V>;
|
||||
isBackgroundFetch: (p: unknown) => p is BackgroundFetch<V>;
|
||||
backgroundFetch: (k: K, index: number | undefined, options: LRUCache.FetchOptions<K, V, FC>, context: unknown) => BackgroundFetch<V>;
|
||||
moveToTail: (index: number) => void;
|
||||
indexes: (options?: {
|
||||
allowStale: boolean;
|
||||
@@ -956,6 +1075,10 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* {@link LRUCache.OptionsBase.dispose} (read-only)
|
||||
*/
|
||||
get dispose(): LRUCache.Disposer<K, V> | undefined;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.onInsert} (read-only)
|
||||
*/
|
||||
get onInsert(): LRUCache.Inserter<K, V> | undefined;
|
||||
/**
|
||||
* {@link LRUCache.OptionsBase.disposeAfter} (read-only)
|
||||
*/
|
||||
@@ -977,7 +1100,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* Return a generator yielding `[key, value]` pairs,
|
||||
* in order from least recently used to most recently used.
|
||||
*/
|
||||
rentries(): Generator<(K | V | BackgroundFetch<V> | undefined)[], void, unknown>;
|
||||
rentries(): Generator<(K | V)[], void, unknown>;
|
||||
/**
|
||||
* Return a generator yielding the keys in the cache,
|
||||
* in order from most recently used to least recently used.
|
||||
@@ -1001,7 +1124,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* Return a generator yielding the values in the cache,
|
||||
* in order from least recently used to most recently used.
|
||||
*/
|
||||
rvalues(): Generator<V | BackgroundFetch<V> | undefined, void, unknown>;
|
||||
rvalues(): Generator<V | undefined, void, unknown>;
|
||||
/**
|
||||
* Iterating over the cache itself yields the same results as
|
||||
* {@link LRUCache.entries}
|
||||
@@ -1029,12 +1152,12 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
*
|
||||
* Does not update age or recenty of use, or iterate over stale values.
|
||||
*/
|
||||
forEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any, thisp?: any): void;
|
||||
forEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => unknown, thisp?: unknown): void;
|
||||
/**
|
||||
* The same as {@link LRUCache.forEach} but items are iterated over in
|
||||
* reverse order. (ie, less recently used items are iterated over first.)
|
||||
*/
|
||||
rforEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any, thisp?: any): void;
|
||||
rforEach(fn: (v: V, k: K, self: LRUCache<K, V, FC>) => unknown, thisp?: unknown): void;
|
||||
/**
|
||||
* Delete any stale entries. Returns true if anything was removed,
|
||||
* false otherwise.
|
||||
@@ -1055,7 +1178,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
info(key: K): LRUCache.Entry<V> | undefined;
|
||||
/**
|
||||
* Return an array of [key, {@link LRUCache.Entry}] tuples which can be
|
||||
* passed to {@link LRLUCache#load}.
|
||||
* passed to {@link LRUCache#load}.
|
||||
*
|
||||
* The `start` fields are calculated relative to a portable `Date.now()`
|
||||
* timestamp, even if `performance.now()` is available.
|
||||
@@ -1107,7 +1230,7 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* If the value is `undefined`, then this is an alias for
|
||||
* `cache.delete(key)`. `undefined` is never stored in the cache.
|
||||
*/
|
||||
set(k: K, v: V | BackgroundFetch<V> | undefined, setOptions?: LRUCache.SetOptions<K, V, FC>): this;
|
||||
set(k: K, v: V | undefined, setOptions?: LRUCache.SetOptions<K, V, FC>): this;
|
||||
/**
|
||||
* Evict the least recently used item, returning its value or
|
||||
* `undefined` if cache is empty.
|
||||
@@ -1223,23 +1346,23 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* the same time, because they're both waiting on the same
|
||||
* underlying fetchMethod response.
|
||||
*/
|
||||
fetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<undefined | V>;
|
||||
fetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : never): Promise<undefined | V>;
|
||||
fetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<undefined | V>;
|
||||
fetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : never): Promise<undefined | V>;
|
||||
/**
|
||||
* In some cases, `cache.fetch()` may resolve to `undefined`, either because
|
||||
* a {@link LRUCache.OptionsBase#fetchMethod} was not provided (turning
|
||||
* `cache.fetch(k)` into just an async wrapper around `cache.get(k)`) or
|
||||
* because `ignoreFetchAbort` was specified (either to the constructor or
|
||||
* in the {@link LRUCache.FetchOptions}). Also, the
|
||||
* {@link OptionsBase.fetchMethod} may return `undefined` or `void`, making
|
||||
* {@link LRUCache.OptionsBase.fetchMethod} may return `undefined` or `void`, making
|
||||
* the test even more complicated.
|
||||
*
|
||||
* Because inferring the cases where `undefined` might be returned are so
|
||||
* cumbersome, but testing for `undefined` can also be annoying, this method
|
||||
* can be used, which will reject if `this.fetch()` resolves to undefined.
|
||||
*/
|
||||
forceFetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<V>;
|
||||
forceFetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V> : never): Promise<V>;
|
||||
forceFetch(k: K, fetchOptions: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : LRUCache.FetchOptionsWithContext<K, V, FC>): Promise<V>;
|
||||
forceFetch(k: unknown extends FC ? K : FC extends undefined | void ? K : never, fetchOptions?: unknown extends FC ? LRUCache.FetchOptions<K, V, FC> : FC extends undefined | void ? LRUCache.FetchOptionsNoContext<K, V, FC> : never): Promise<V>;
|
||||
/**
|
||||
* If the key is found in the cache, then this is equivalent to
|
||||
* {@link LRUCache#get}. If not, in the cache, then calculate the value using
|
||||
@@ -1254,8 +1377,8 @@ export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implemen
|
||||
* relevant in the course of fetching the data. It is only relevant for the
|
||||
* course of a single `memo()` operation, and discarded afterwards.
|
||||
*/
|
||||
memo(k: K, memoOptions: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V> : LRUCache.MemoOptionsWithContext<K, V, FC>): V;
|
||||
memo(k: unknown extends FC ? K : FC extends undefined | void ? K : never, memoOptions?: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V> : never): V;
|
||||
memo(k: K, memoOptions: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V, FC> : LRUCache.MemoOptionsWithContext<K, V, FC>): V;
|
||||
memo(k: unknown extends FC ? K : FC extends undefined | void ? K : never, memoOptions?: unknown extends FC ? LRUCache.MemoOptions<K, V, FC> : FC extends undefined | void ? LRUCache.MemoOptionsNoContext<K, V, FC> : never): V;
|
||||
/**
|
||||
* Return a value from the cache. Will update the recency of the cache
|
||||
* entry found.
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+425
-245
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+82
-44
@@ -1,10 +1,7 @@
|
||||
{
|
||||
"name": "lru-cache",
|
||||
"publishConfig": {
|
||||
"tag": "legacy-v10"
|
||||
},
|
||||
"description": "A cache object that deletes the least-recently-used items.",
|
||||
"version": "10.4.3",
|
||||
"version": "11.5.0",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me>",
|
||||
"keywords": [
|
||||
"mru",
|
||||
@@ -14,7 +11,7 @@
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"build": "npm run prepare",
|
||||
"prepare": "tshy && bash fixup.sh",
|
||||
"prepare": "tshy && bash scripts/build.sh",
|
||||
"pretest": "npm run prepare",
|
||||
"presnap": "npm run prepare",
|
||||
"test": "tap",
|
||||
@@ -28,89 +25,130 @@
|
||||
"prebenchmark": "npm run prepare",
|
||||
"benchmark": "make -C benchmark",
|
||||
"preprofile": "npm run prepare",
|
||||
"profile": "make -C benchmark profile"
|
||||
"profile": "make -C benchmark profile",
|
||||
"lint": "oxlint --fix src test",
|
||||
"postsnap": "npm run lint",
|
||||
"postlint": "npm run format"
|
||||
},
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"main": "./dist/commonjs/index.min.js",
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"tshy": {
|
||||
"esmDialects": [
|
||||
"browser",
|
||||
"node"
|
||||
],
|
||||
"commonjsDialects": [
|
||||
"browser",
|
||||
"node"
|
||||
],
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./min": {
|
||||
"./raw": "./src/index.ts",
|
||||
".": {
|
||||
"import": {
|
||||
"browser": {
|
||||
"types": "./dist/esm/browser/index.d.ts",
|
||||
"default": "./dist/esm/browser/index.min.js"
|
||||
},
|
||||
"node": {
|
||||
"types": "./dist/esm/node/index.d.ts",
|
||||
"default": "./dist/esm/node/index.min.js"
|
||||
},
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.min.js"
|
||||
},
|
||||
"require": {
|
||||
"browser": {
|
||||
"types": "./dist/commonjs/browser/index.d.ts",
|
||||
"default": "./dist/commonjs/browser/index.min.js"
|
||||
},
|
||||
"node": {
|
||||
"types": "./dist/commonjs/node/index.d.ts",
|
||||
"default": "./dist/commonjs/node/index.min.js"
|
||||
},
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.min.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selfLink": false
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/node-lru-cache.git"
|
||||
"url": "git+ssh://git@github.com/isaacs/node-lru-cache.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/tap": "^15.0.6",
|
||||
"benchmark": "^2.1.4",
|
||||
"esbuild": "^0.17.11",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"esbuild": "^0.28.0",
|
||||
"marked": "^4.2.12",
|
||||
"mkdirp": "^2.1.5",
|
||||
"prettier": "^2.6.2",
|
||||
"tap": "^20.0.3",
|
||||
"tshy": "^2.0.0",
|
||||
"tslib": "^2.4.0",
|
||||
"typedoc": "^0.25.3",
|
||||
"typescript": "^5.2.2"
|
||||
"mkdirp": "^3.0.1",
|
||||
"oxlint": "^1.65.0",
|
||||
"oxlint-tsgolint": "^0.22.1",
|
||||
"prettier": "^3.8.3",
|
||||
"tap": "^21.7.4",
|
||||
"tshy": "^4.1.2",
|
||||
"typedoc": "^0.28.19"
|
||||
},
|
||||
"license": "ISC",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
"printWidth": 70,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": false,
|
||||
"bracketSameLine": true,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf"
|
||||
},
|
||||
"tap": {
|
||||
"node-arg": [
|
||||
"--expose-gc"
|
||||
],
|
||||
"plugin": [
|
||||
"@tapjs/clock"
|
||||
]
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"./raw": {
|
||||
"import": {
|
||||
"browser": {
|
||||
"types": "./dist/esm/browser/index.d.ts",
|
||||
"default": "./dist/esm/browser/index.js"
|
||||
},
|
||||
"node": {
|
||||
"types": "./dist/esm/node/index.d.ts",
|
||||
"default": "./dist/esm/node/index.js"
|
||||
},
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"browser": {
|
||||
"types": "./dist/commonjs/browser/index.d.ts",
|
||||
"default": "./dist/commonjs/browser/index.js"
|
||||
},
|
||||
"node": {
|
||||
"types": "./dist/commonjs/node/index.d.ts",
|
||||
"default": "./dist/commonjs/node/index.js"
|
||||
},
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.js"
|
||||
}
|
||||
},
|
||||
"./min": {
|
||||
".": {
|
||||
"import": {
|
||||
"browser": {
|
||||
"types": "./dist/esm/browser/index.d.ts",
|
||||
"default": "./dist/esm/browser/index.min.js"
|
||||
},
|
||||
"node": {
|
||||
"types": "./dist/esm/node/index.d.ts",
|
||||
"default": "./dist/esm/node/index.min.js"
|
||||
},
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.min.js"
|
||||
},
|
||||
"require": {
|
||||
"browser": {
|
||||
"types": "./dist/commonjs/browser/index.d.ts",
|
||||
"default": "./dist/commonjs/browser/index.min.js"
|
||||
},
|
||||
"node": {
|
||||
"types": "./dist/commonjs/node/index.d.ts",
|
||||
"default": "./dist/commonjs/node/index.min.js"
|
||||
},
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.min.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
"module": "./dist/esm/index.js"
|
||||
"module": "./dist/esm/index.min.js"
|
||||
}
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
# Blue Oak Model License
|
||||
|
||||
Version 1.0.0
|
||||
|
||||
## Purpose
|
||||
|
||||
This license gives everyone as much permission to work with
|
||||
this software as possible, while protecting contributors
|
||||
from liability.
|
||||
|
||||
## Acceptance
|
||||
|
||||
In order to receive this license, you must agree to its
|
||||
rules. The rules of this license are both obligations
|
||||
under that agreement and conditions to your license.
|
||||
You must not do anything with this software that triggers
|
||||
a rule that you cannot or will not follow.
|
||||
|
||||
## Copyright
|
||||
|
||||
Each contributor licenses you to do everything with this
|
||||
software that would otherwise infringe that contributor's
|
||||
copyright in it.
|
||||
|
||||
## Notices
|
||||
|
||||
You must ensure that everyone who gets a copy of
|
||||
any part of this software from you, with or without
|
||||
changes, also gets the text of this license or a link to
|
||||
<https://blueoakcouncil.org/license/1.0.0>.
|
||||
|
||||
## Excuse
|
||||
|
||||
If anyone notifies you in writing that you have not
|
||||
complied with [Notices](#notices), you can keep your
|
||||
license by taking all practical steps to comply within 30
|
||||
days after the notice. If you do not do so, your license
|
||||
ends immediately.
|
||||
|
||||
## Patent
|
||||
|
||||
Each contributor licenses you to do everything with this
|
||||
software that would otherwise infringe any patent claims
|
||||
they can license or become able to license.
|
||||
|
||||
## Reliability
|
||||
|
||||
No contributor can revoke this license.
|
||||
|
||||
## No Liability
|
||||
|
||||
***As far as the law allows, this software comes as is,
|
||||
without any warranty or condition, and no contributor
|
||||
will be liable to anyone for any damages related to this
|
||||
software or this license, under any kind of legal claim.***
|
||||
-1145
File diff suppressed because it is too large
Load Diff
-3
@@ -1,3 +0,0 @@
|
||||
import { Pack, PackSync } from './pack.js';
|
||||
export declare const create: import("./make-command.js").TarCommand<Pack, PackSync>;
|
||||
//# sourceMappingURL=create.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/create.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AA8E1C,eAAO,MAAM,MAAM,wDAUlB,CAAA"}
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.create = void 0;
|
||||
const fs_minipass_1 = require("@isaacs/fs-minipass");
|
||||
const node_path_1 = __importDefault(require("node:path"));
|
||||
const list_js_1 = require("./list.js");
|
||||
const make_command_js_1 = require("./make-command.js");
|
||||
const pack_js_1 = require("./pack.js");
|
||||
const createFileSync = (opt, files) => {
|
||||
const p = new pack_js_1.PackSync(opt);
|
||||
const stream = new fs_minipass_1.WriteStreamSync(opt.file, {
|
||||
mode: opt.mode || 0o666,
|
||||
});
|
||||
p.pipe(stream);
|
||||
addFilesSync(p, files);
|
||||
};
|
||||
const createFile = (opt, files) => {
|
||||
const p = new pack_js_1.Pack(opt);
|
||||
const stream = new fs_minipass_1.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 promise;
|
||||
};
|
||||
const addFilesSync = (p, files) => {
|
||||
files.forEach(file => {
|
||||
if (file.charAt(0) === '@') {
|
||||
(0, list_js_1.list)({
|
||||
file: node_path_1.default.resolve(p.cwd, file.slice(1)),
|
||||
sync: true,
|
||||
noResume: true,
|
||||
onReadEntry: entry => p.add(entry),
|
||||
});
|
||||
}
|
||||
else {
|
||||
p.add(file);
|
||||
}
|
||||
});
|
||||
p.end();
|
||||
};
|
||||
const addFilesAsync = async (p, files) => {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = String(files[i]);
|
||||
if (file.charAt(0) === '@') {
|
||||
await (0, list_js_1.list)({
|
||||
file: node_path_1.default.resolve(String(p.cwd), file.slice(1)),
|
||||
noResume: true,
|
||||
onReadEntry: entry => {
|
||||
p.add(entry);
|
||||
},
|
||||
});
|
||||
}
|
||||
else {
|
||||
p.add(file);
|
||||
}
|
||||
}
|
||||
p.end();
|
||||
};
|
||||
const createSync = (opt, files) => {
|
||||
const p = new pack_js_1.PackSync(opt);
|
||||
addFilesSync(p, files);
|
||||
return p;
|
||||
};
|
||||
const createAsync = (opt, files) => {
|
||||
const p = new pack_js_1.Pack(opt);
|
||||
addFilesAsync(p, files);
|
||||
return p;
|
||||
};
|
||||
exports.create = (0, make_command_js_1.makeCommand)(createFileSync, createFile, createSync, createAsync, (_opt, files) => {
|
||||
if (!files?.length) {
|
||||
throw new TypeError('no paths specified to add to archive');
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=create.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-8
@@ -1,8 +0,0 @@
|
||||
export declare class CwdError extends Error {
|
||||
path: string;
|
||||
code: string;
|
||||
syscall: 'chdir';
|
||||
constructor(path: string, code: string);
|
||||
get name(): string;
|
||||
}
|
||||
//# sourceMappingURL=cwd-error.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"cwd-error.d.ts","sourceRoot":"","sources":["../../src/cwd-error.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAU;gBAEd,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAMtC,IAAI,IAAI,WAEP;CACF"}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CwdError = void 0;
|
||||
class CwdError extends Error {
|
||||
path;
|
||||
code;
|
||||
syscall = 'chdir';
|
||||
constructor(path, code) {
|
||||
super(`${code}: Cannot cd into '${path}'`);
|
||||
this.path = path;
|
||||
this.code = code;
|
||||
}
|
||||
get name() {
|
||||
return 'CwdError';
|
||||
}
|
||||
}
|
||||
exports.CwdError = CwdError;
|
||||
//# sourceMappingURL=cwd-error.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"cwd-error.js","sourceRoot":"","sources":["../../src/cwd-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,CAAQ;IACZ,IAAI,CAAQ;IACZ,OAAO,GAAY,OAAO,CAAA;IAE1B,YAAY,IAAY,EAAE,IAAY;QACpC,KAAK,CAAC,GAAG,IAAI,qBAAqB,IAAI,GAAG,CAAC,CAAA;QAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,UAAU,CAAA;IACnB,CAAC;CACF;AAdD,4BAcC","sourcesContent":["export class CwdError extends Error {\n path: string\n code: string\n syscall: 'chdir' = 'chdir'\n\n constructor(path: string, code: string) {\n super(`${code}: Cannot cd into '${path}'`)\n this.path = path\n this.code = code\n }\n\n get name() {\n return 'CwdError'\n }\n}\n"]}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
import { Unpack, UnpackSync } from './unpack.js';
|
||||
export declare const extract: import("./make-command.js").TarCommand<Unpack, UnpackSync>;
|
||||
//# sourceMappingURL=extract.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/extract.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AA2ChD,eAAO,MAAM,OAAO,4DAQnB,CAAA"}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.extract = void 0;
|
||||
// tar -x
|
||||
const fsm = __importStar(require("@isaacs/fs-minipass"));
|
||||
const node_fs_1 = __importDefault(require("node:fs"));
|
||||
const list_js_1 = require("./list.js");
|
||||
const make_command_js_1 = require("./make-command.js");
|
||||
const unpack_js_1 = require("./unpack.js");
|
||||
const extractFileSync = (opt) => {
|
||||
const u = new unpack_js_1.UnpackSync(opt);
|
||||
const file = opt.file;
|
||||
const stat = node_fs_1.default.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, _) => {
|
||||
const u = new unpack_js_1.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
|
||||
node_fs_1.default.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 p;
|
||||
};
|
||||
exports.extract = (0, make_command_js_1.makeCommand)(extractFileSync, extractFile, opt => new unpack_js_1.UnpackSync(opt), opt => new unpack_js_1.Unpack(opt), (opt, files) => {
|
||||
if (files?.length)
|
||||
(0, list_js_1.filesFilter)(opt, files);
|
||||
});
|
||||
//# sourceMappingURL=extract.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/extract.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS;AACT,yDAA0C;AAC1C,sDAAwB;AACxB,uCAAuC;AACvC,uDAA+C;AAE/C,2CAAgD;AAEhD,MAAM,eAAe,GAAG,CAAC,GAAuB,EAAE,EAAE;IAClD,MAAM,CAAC,GAAG,IAAI,sBAAU,CAAC,GAAG,CAAC,CAAA;IAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,MAAM,IAAI,GAAG,iBAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC9B,oDAAoD;IACpD,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;QAC1C,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAA;IACF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,GAAmB,EAAE,CAAY,EAAE,EAAE;IACxD,MAAM,CAAC,GAAG,IAAI,kBAAM,CAAC,GAAG,CAAC,CAAA;IACzB,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;IAEpD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,MAAM,CAAC,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC9C,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QACrB,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAEtB,oDAAoD;QACpD,4DAA4D;QAC5D,iBAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE;YACzB,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,CAAC,EAAE,CAAC,CAAA;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;oBACtC,QAAQ,EAAE,QAAQ;oBAClB,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAA;gBACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBAC1B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAChB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,CAAA;AACV,CAAC,CAAA;AAEY,QAAA,OAAO,GAAG,IAAA,6BAAW,EAChC,eAAe,EACf,WAAW,EACX,GAAG,CAAC,EAAE,CAAC,IAAI,sBAAU,CAAC,GAAG,CAAC,EAC1B,GAAG,CAAC,EAAE,CAAC,IAAI,kBAAM,CAAC,GAAG,CAAC,EACtB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IACb,IAAI,KAAK,EAAE,MAAM;QAAE,IAAA,qBAAW,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AAC5C,CAAC,CACF,CAAA","sourcesContent":["// tar -x\nimport * as fsm from '@isaacs/fs-minipass'\nimport fs from 'node:fs'\nimport { filesFilter } from './list.js'\nimport { makeCommand } from './make-command.js'\nimport { TarOptionsFile, TarOptionsSyncFile } from './options.js'\nimport { Unpack, UnpackSync } from './unpack.js'\n\nconst extractFileSync = (opt: TarOptionsSyncFile) => {\n const u = new UnpackSync(opt)\n const file = opt.file\n const stat = fs.statSync(file)\n // This trades a zero-byte read() syscall for a stat\n // However, it will usually result in less memory allocation\n const readSize = opt.maxReadSize || 16 * 1024 * 1024\n const stream = new fsm.ReadStreamSync(file, {\n readSize: readSize,\n size: stat.size,\n })\n stream.pipe(u)\n}\n\nconst extractFile = (opt: TarOptionsFile, _?: string[]) => {\n const u = new Unpack(opt)\n const readSize = opt.maxReadSize || 16 * 1024 * 1024\n\n const file = opt.file\n const p = new Promise<void>((resolve, reject) => {\n u.on('error', reject)\n u.on('close', resolve)\n\n // This trades a zero-byte read() syscall for a stat\n // However, it will usually result in less memory allocation\n fs.stat(file, (er, stat) => {\n if (er) {\n reject(er)\n } else {\n const stream = new fsm.ReadStream(file, {\n readSize: readSize,\n size: stat.size,\n })\n stream.on('error', reject)\n stream.pipe(u)\n }\n })\n })\n return p\n}\n\nexport const extract = makeCommand<Unpack, UnpackSync>(\n extractFileSync,\n extractFile,\n opt => new UnpackSync(opt),\n opt => new Unpack(opt),\n (opt, files) => {\n if (files?.length) filesFilter(opt, files)\n },\n)\n"]}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
export declare const getWriteFlag: (() => string) | ((size: number) => number | "w");
|
||||
//# sourceMappingURL=get-write-flag.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"get-write-flag.d.ts","sourceRoot":"","sources":["../../src/get-write-flag.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,YAAY,2BAGd,MAAM,kBAAwC,CAAA"}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
"use strict";
|
||||
// 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.
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getWriteFlag = void 0;
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const platform = process.env.__FAKE_PLATFORM__ || process.platform;
|
||||
const isWindows = platform === 'win32';
|
||||
/* c8 ignore start */
|
||||
const { O_CREAT, O_TRUNC, O_WRONLY } = fs_1.default.constants;
|
||||
const UV_FS_O_FILEMAP = Number(process.env.__FAKE_FS_O_FILENAME__) ||
|
||||
fs_1.default.constants.UV_FS_O_FILEMAP ||
|
||||
0;
|
||||
/* c8 ignore stop */
|
||||
const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP;
|
||||
const fMapLimit = 512 * 1024;
|
||||
const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY;
|
||||
exports.getWriteFlag = !fMapEnabled ?
|
||||
() => 'w'
|
||||
: (size) => (size < fMapLimit ? fMapFlag : 'w');
|
||||
//# sourceMappingURL=get-write-flag.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"get-write-flag.js","sourceRoot":"","sources":["../../src/get-write-flag.ts"],"names":[],"mappings":";AAAA,qDAAqD;AACrD,uDAAuD;AACvD,wDAAwD;AACxD,wDAAwD;AACxD,qDAAqD;AACrD,uDAAuD;AACvD,8CAA8C;;;;;;AAE9C,4CAAmB;AAEnB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,QAAQ,CAAA;AAClE,MAAM,SAAS,GAAG,QAAQ,KAAK,OAAO,CAAA;AAEtC,qBAAqB;AACrB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,YAAE,CAAC,SAAS,CAAA;AACnD,MAAM,eAAe,GACnB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAC1C,YAAE,CAAC,SAAS,CAAC,eAAe;IAC5B,CAAC,CAAA;AACH,oBAAoB;AAEpB,MAAM,WAAW,GAAG,SAAS,IAAI,CAAC,CAAC,eAAe,CAAA;AAClD,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,CAAA;AAC5B,MAAM,QAAQ,GAAG,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;AAClD,QAAA,YAAY,GACvB,CAAC,WAAW,CAAC,CAAC;IACZ,GAAG,EAAE,CAAC,GAAG;IACX,CAAC,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA","sourcesContent":["// Get the appropriate flag to use for creating files\n// We use fmap on Windows platforms for files less than\n// 512kb. This is a fairly low limit, but avoids making\n// things slower in some cases. Since most of what this\n// library is used for is extracting tarballs of many\n// relatively small files in npm packages and the like,\n// it can be a big boost on Windows platforms.\n\nimport fs from 'fs'\n\nconst platform = process.env.__FAKE_PLATFORM__ || process.platform\nconst isWindows = platform === 'win32'\n\n/* c8 ignore start */\nconst { O_CREAT, O_TRUNC, O_WRONLY } = fs.constants\nconst UV_FS_O_FILEMAP =\n Number(process.env.__FAKE_FS_O_FILENAME__) ||\n fs.constants.UV_FS_O_FILEMAP ||\n 0\n/* c8 ignore stop */\n\nconst fMapEnabled = isWindows && !!UV_FS_O_FILEMAP\nconst fMapLimit = 512 * 1024\nconst fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY\nexport const getWriteFlag =\n !fMapEnabled ?\n () => 'w'\n : (size: number) => (size < fMapLimit ? fMapFlag : 'w')\n"]}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import type { EntryTypeCode, EntryTypeName } from './types.js';
|
||||
export type HeaderData = {
|
||||
path?: string;
|
||||
mode?: number;
|
||||
uid?: number;
|
||||
gid?: number;
|
||||
size?: number;
|
||||
cksum?: number;
|
||||
type?: EntryTypeName | 'Unsupported';
|
||||
linkpath?: string;
|
||||
uname?: string;
|
||||
gname?: string;
|
||||
devmaj?: number;
|
||||
devmin?: number;
|
||||
atime?: Date;
|
||||
ctime?: Date;
|
||||
mtime?: Date;
|
||||
charset?: string;
|
||||
comment?: string;
|
||||
dev?: number;
|
||||
ino?: number;
|
||||
nlink?: number;
|
||||
};
|
||||
export declare class Header implements HeaderData {
|
||||
#private;
|
||||
cksumValid: boolean;
|
||||
needPax: boolean;
|
||||
nullBlock: boolean;
|
||||
block?: Buffer;
|
||||
path?: string;
|
||||
mode?: number;
|
||||
uid?: number;
|
||||
gid?: number;
|
||||
size?: number;
|
||||
cksum?: number;
|
||||
linkpath?: string;
|
||||
uname?: string;
|
||||
gname?: string;
|
||||
devmaj: number;
|
||||
devmin: number;
|
||||
atime?: Date;
|
||||
ctime?: Date;
|
||||
mtime?: Date;
|
||||
charset?: string;
|
||||
comment?: string;
|
||||
constructor(data?: Buffer | HeaderData, off?: number, ex?: HeaderData, gex?: HeaderData);
|
||||
decode(buf: Buffer, off: number, ex?: HeaderData, gex?: HeaderData): void;
|
||||
encode(buf?: Buffer, off?: number): boolean;
|
||||
get type(): EntryTypeName;
|
||||
get typeKey(): EntryTypeCode | 'Unsupported';
|
||||
set type(type: EntryTypeCode | EntryTypeName | 'Unsupported');
|
||||
}
|
||||
//# sourceMappingURL=header.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../src/header.ts"],"names":[],"mappings":";;AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG9D,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,aAAa,GAAG,aAAa,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IAIZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,qBAAa,MAAO,YAAW,UAAU;;IACvC,UAAU,EAAE,OAAO,CAAQ;IAC3B,OAAO,EAAE,OAAO,CAAQ;IACxB,SAAS,EAAE,OAAO,CAAQ;IAE1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAI;IAClB,MAAM,EAAE,MAAM,CAAI;IAClB,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IAEZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;gBAGd,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,EAC1B,GAAG,GAAE,MAAU,EACf,EAAE,CAAC,EAAE,UAAU,EACf,GAAG,CAAC,EAAE,UAAU;IASlB,MAAM,CACJ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,EAAE,CAAC,EAAE,UAAU,EACf,GAAG,CAAC,EAAE,UAAU;IA+GlB,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAU;IAwEpC,IAAI,IAAI,IAAI,aAAa,CAKxB;IAED,IAAI,OAAO,IAAI,aAAa,GAAG,aAAa,CAE3C;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,aAAa,EAS3D;CACF"}
|
||||
-315
@@ -1,315 +0,0 @@
|
||||
"use strict";
|
||||
// parse a 512-byte header block to a data object, or vice-versa
|
||||
// encode returns `true` if a pax extended header is needed, because
|
||||
// the data could not be faithfully encoded in a simple header.
|
||||
// (Also, check header.needPax to see if it needs a pax header.)
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Header = void 0;
|
||||
const node_path_1 = require("node:path");
|
||||
const large = __importStar(require("./large-numbers.js"));
|
||||
const types = __importStar(require("./types.js"));
|
||||
class Header {
|
||||
cksumValid = false;
|
||||
needPax = false;
|
||||
nullBlock = false;
|
||||
block;
|
||||
path;
|
||||
mode;
|
||||
uid;
|
||||
gid;
|
||||
size;
|
||||
cksum;
|
||||
#type = 'Unsupported';
|
||||
linkpath;
|
||||
uname;
|
||||
gname;
|
||||
devmaj = 0;
|
||||
devmin = 0;
|
||||
atime;
|
||||
ctime;
|
||||
mtime;
|
||||
charset;
|
||||
comment;
|
||||
constructor(data, off = 0, ex, gex) {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
this.decode(data, off || 0, ex, gex);
|
||||
}
|
||||
else if (data) {
|
||||
this.#slurp(data);
|
||||
}
|
||||
}
|
||||
decode(buf, off, ex, gex) {
|
||||
if (!off) {
|
||||
off = 0;
|
||||
}
|
||||
if (!buf || !(buf.length >= off + 512)) {
|
||||
throw new Error('need 512 bytes for header');
|
||||
}
|
||||
this.path = ex?.path ?? decString(buf, off, 100);
|
||||
this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8);
|
||||
this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8);
|
||||
this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8);
|
||||
this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12);
|
||||
this.mtime =
|
||||
ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12);
|
||||
this.cksum = decNumber(buf, off + 148, 12);
|
||||
// if we have extended or global extended headers, apply them now
|
||||
// See https://github.com/npm/node-tar/pull/187
|
||||
// Apply global before local, so it overrides
|
||||
if (gex)
|
||||
this.#slurp(gex, true);
|
||||
if (ex)
|
||||
this.#slurp(ex);
|
||||
// old tar versions marked dirs as a file with a trailing /
|
||||
const t = decString(buf, off + 156, 1);
|
||||
if (types.isCode(t)) {
|
||||
this.#type = t || '0';
|
||||
}
|
||||
if (this.#type === '0' && this.path.slice(-1) === '/') {
|
||||
this.#type = '5';
|
||||
}
|
||||
// tar implementations sometimes incorrectly put the stat(dir).size
|
||||
// as the size in the tarball, even though Directory entries are
|
||||
// not able to have any body at all. In the very rare chance that
|
||||
// it actually DOES have a body, we weren't going to do anything with
|
||||
// it anyway, and it'll just be a warning about an invalid header.
|
||||
if (this.#type === '5') {
|
||||
this.size = 0;
|
||||
}
|
||||
this.linkpath = decString(buf, off + 157, 100);
|
||||
if (buf.subarray(off + 257, off + 265).toString() ===
|
||||
'ustar\u000000') {
|
||||
/* c8 ignore start */
|
||||
this.uname =
|
||||
ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32);
|
||||
this.gname =
|
||||
ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32);
|
||||
this.devmaj =
|
||||
ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0;
|
||||
this.devmin =
|
||||
ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0;
|
||||
/* c8 ignore stop */
|
||||
if (buf[off + 475] !== 0) {
|
||||
// definitely a prefix, definitely >130 chars.
|
||||
const prefix = decString(buf, off + 345, 155);
|
||||
this.path = prefix + '/' + this.path;
|
||||
}
|
||||
else {
|
||||
const prefix = decString(buf, off + 345, 130);
|
||||
if (prefix) {
|
||||
this.path = prefix + '/' + this.path;
|
||||
}
|
||||
/* c8 ignore start */
|
||||
this.atime =
|
||||
ex?.atime ?? gex?.atime ?? decDate(buf, off + 476, 12);
|
||||
this.ctime =
|
||||
ex?.ctime ?? gex?.ctime ?? decDate(buf, off + 488, 12);
|
||||
/* c8 ignore stop */
|
||||
}
|
||||
}
|
||||
let sum = 8 * 0x20;
|
||||
for (let i = off; i < off + 148; i++) {
|
||||
sum += buf[i];
|
||||
}
|
||||
for (let i = off + 156; i < off + 512; i++) {
|
||||
sum += buf[i];
|
||||
}
|
||||
this.cksumValid = sum === this.cksum;
|
||||
if (this.cksum === undefined && sum === 8 * 0x20) {
|
||||
this.nullBlock = true;
|
||||
}
|
||||
}
|
||||
#slurp(ex, gex = false) {
|
||||
Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => {
|
||||
// we slurp in everything except for the path attribute in
|
||||
// a global extended header, because that's weird. Also, any
|
||||
// null/undefined values are ignored.
|
||||
return !(v === null ||
|
||||
v === undefined ||
|
||||
(k === 'path' && gex) ||
|
||||
(k === 'linkpath' && gex) ||
|
||||
k === 'global');
|
||||
})));
|
||||
}
|
||||
encode(buf, off = 0) {
|
||||
if (!buf) {
|
||||
buf = this.block = Buffer.alloc(512);
|
||||
}
|
||||
if (this.#type === 'Unsupported') {
|
||||
this.#type = '0';
|
||||
}
|
||||
if (!(buf.length >= off + 512)) {
|
||||
throw new Error('need 512 bytes for header');
|
||||
}
|
||||
const prefixSize = this.ctime || this.atime ? 130 : 155;
|
||||
const split = splitPrefix(this.path || '', prefixSize);
|
||||
const path = split[0];
|
||||
const prefix = split[1];
|
||||
this.needPax = !!split[2];
|
||||
this.needPax = encString(buf, off, 100, path) || this.needPax;
|
||||
this.needPax =
|
||||
encNumber(buf, off + 100, 8, this.mode) || this.needPax;
|
||||
this.needPax =
|
||||
encNumber(buf, off + 108, 8, this.uid) || this.needPax;
|
||||
this.needPax =
|
||||
encNumber(buf, off + 116, 8, this.gid) || this.needPax;
|
||||
this.needPax =
|
||||
encNumber(buf, off + 124, 12, this.size) || this.needPax;
|
||||
this.needPax =
|
||||
encDate(buf, off + 136, 12, this.mtime) || this.needPax;
|
||||
buf[off + 156] = this.#type.charCodeAt(0);
|
||||
this.needPax =
|
||||
encString(buf, off + 157, 100, this.linkpath) || this.needPax;
|
||||
buf.write('ustar\u000000', off + 257, 8);
|
||||
this.needPax =
|
||||
encString(buf, off + 265, 32, this.uname) || this.needPax;
|
||||
this.needPax =
|
||||
encString(buf, off + 297, 32, this.gname) || this.needPax;
|
||||
this.needPax =
|
||||
encNumber(buf, off + 329, 8, this.devmaj) || this.needPax;
|
||||
this.needPax =
|
||||
encNumber(buf, off + 337, 8, this.devmin) || this.needPax;
|
||||
this.needPax =
|
||||
encString(buf, off + 345, prefixSize, prefix) || this.needPax;
|
||||
if (buf[off + 475] !== 0) {
|
||||
this.needPax =
|
||||
encString(buf, off + 345, 155, prefix) || this.needPax;
|
||||
}
|
||||
else {
|
||||
this.needPax =
|
||||
encString(buf, off + 345, 130, prefix) || this.needPax;
|
||||
this.needPax =
|
||||
encDate(buf, off + 476, 12, this.atime) || this.needPax;
|
||||
this.needPax =
|
||||
encDate(buf, off + 488, 12, this.ctime) || this.needPax;
|
||||
}
|
||||
let sum = 8 * 0x20;
|
||||
for (let i = off; i < off + 148; i++) {
|
||||
sum += buf[i];
|
||||
}
|
||||
for (let i = off + 156; i < off + 512; i++) {
|
||||
sum += buf[i];
|
||||
}
|
||||
this.cksum = sum;
|
||||
encNumber(buf, off + 148, 8, this.cksum);
|
||||
this.cksumValid = true;
|
||||
return this.needPax;
|
||||
}
|
||||
get type() {
|
||||
return (this.#type === 'Unsupported' ?
|
||||
this.#type
|
||||
: types.name.get(this.#type));
|
||||
}
|
||||
get typeKey() {
|
||||
return this.#type;
|
||||
}
|
||||
set type(type) {
|
||||
const c = String(types.code.get(type));
|
||||
if (types.isCode(c) || c === 'Unsupported') {
|
||||
this.#type = c;
|
||||
}
|
||||
else if (types.isCode(type)) {
|
||||
this.#type = type;
|
||||
}
|
||||
else {
|
||||
throw new TypeError('invalid entry type: ' + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Header = Header;
|
||||
const splitPrefix = (p, prefixSize) => {
|
||||
const pathSize = 100;
|
||||
let pp = p;
|
||||
let prefix = '';
|
||||
let ret = undefined;
|
||||
const root = node_path_1.posix.parse(p).root || '.';
|
||||
if (Buffer.byteLength(pp) < pathSize) {
|
||||
ret = [pp, prefix, false];
|
||||
}
|
||||
else {
|
||||
// first set prefix to the dir, and path to the base
|
||||
prefix = node_path_1.posix.dirname(pp);
|
||||
pp = node_path_1.posix.basename(pp);
|
||||
do {
|
||||
if (Buffer.byteLength(pp) <= pathSize &&
|
||||
Buffer.byteLength(prefix) <= prefixSize) {
|
||||
// both fit!
|
||||
ret = [pp, prefix, false];
|
||||
}
|
||||
else if (Buffer.byteLength(pp) > pathSize &&
|
||||
Buffer.byteLength(prefix) <= prefixSize) {
|
||||
// prefix fits in prefix, but path doesn't fit in path
|
||||
ret = [pp.slice(0, pathSize - 1), prefix, true];
|
||||
}
|
||||
else {
|
||||
// make path take a bit from prefix
|
||||
pp = node_path_1.posix.join(node_path_1.posix.basename(prefix), pp);
|
||||
prefix = node_path_1.posix.dirname(prefix);
|
||||
}
|
||||
} while (prefix !== root && ret === undefined);
|
||||
// at this point, found no resolution, just truncate
|
||||
if (!ret) {
|
||||
ret = [p.slice(0, pathSize - 1), '', true];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
const decString = (buf, off, size) => buf
|
||||
.subarray(off, off + size)
|
||||
.toString('utf8')
|
||||
.replace(/\0.*/, '');
|
||||
const decDate = (buf, off, size) => numToDate(decNumber(buf, off, size));
|
||||
const numToDate = (num) => num === undefined ? undefined : new Date(num * 1000);
|
||||
const decNumber = (buf, off, size) => Number(buf[off]) & 0x80 ?
|
||||
large.parse(buf.subarray(off, off + size))
|
||||
: decSmallNumber(buf, off, size);
|
||||
const nanUndef = (value) => (isNaN(value) ? undefined : value);
|
||||
const decSmallNumber = (buf, off, size) => nanUndef(parseInt(buf
|
||||
.subarray(off, off + size)
|
||||
.toString('utf8')
|
||||
.replace(/\0.*$/, '')
|
||||
.trim(), 8));
|
||||
// the maximum encodable as a null-terminated octal, by field size
|
||||
const MAXNUM = {
|
||||
12: 0o77777777777,
|
||||
8: 0o7777777,
|
||||
};
|
||||
const encNumber = (buf, off, size, num) => num === undefined ? false
|
||||
: num > MAXNUM[size] || num < 0 ?
|
||||
(large.encode(num, buf.subarray(off, off + size)), true)
|
||||
: (encSmallNumber(buf, off, size, num), false);
|
||||
const encSmallNumber = (buf, off, size, num) => buf.write(octalString(num, size), off, size, 'ascii');
|
||||
const octalString = (num, size) => padOctal(Math.floor(num).toString(8), size);
|
||||
const padOctal = (str, size) => (str.length === size - 1 ?
|
||||
str
|
||||
: new Array(size - str.length - 1).join('0') + str + ' ') + '\0';
|
||||
const encDate = (buf, off, size, date) => date === undefined ? false : (encNumber(buf, off, size, date.getTime() / 1000));
|
||||
// enough to fill the longest string we've got
|
||||
const NULLS = new Array(156).join('\0');
|
||||
// pad with nulls, return true if it's longer or non-ascii
|
||||
const encString = (buf, off, size, str) => str === undefined ? false : ((buf.write(str + NULLS, off, size, 'utf8'),
|
||||
str.length !== Buffer.byteLength(str) || str.length > size));
|
||||
//# sourceMappingURL=header.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-20
@@ -1,20 +0,0 @@
|
||||
export { type TarOptionsWithAliasesAsync, type TarOptionsWithAliasesAsyncFile, type TarOptionsWithAliasesAsyncNoFile, type TarOptionsWithAliasesSyncNoFile, type TarOptionsWithAliases, type TarOptionsWithAliasesFile, type TarOptionsWithAliasesSync, type TarOptionsWithAliasesSyncFile, } from './options.js';
|
||||
export * from './create.js';
|
||||
export { create as c } from './create.js';
|
||||
export * from './extract.js';
|
||||
export { extract as x } from './extract.js';
|
||||
export * from './header.js';
|
||||
export * from './list.js';
|
||||
export { list as t } from './list.js';
|
||||
export * from './pack.js';
|
||||
export * from './parse.js';
|
||||
export * from './pax.js';
|
||||
export * from './read-entry.js';
|
||||
export * from './replace.js';
|
||||
export { replace as r } from './replace.js';
|
||||
export * as types from './types.js';
|
||||
export * from './unpack.js';
|
||||
export * from './update.js';
|
||||
export { update as u } from './update.js';
|
||||
export * from './write-entry.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,EACpC,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,GACnC,MAAM,cAAc,CAAA;AAErB,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,aAAa,CAAA;AACzC,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,cAAc,CAAA;AAC3C,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,WAAW,CAAA;AAErC,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,aAAa,CAAA;AACzC,cAAc,kBAAkB,CAAA"}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.u = exports.types = exports.r = exports.t = exports.x = exports.c = void 0;
|
||||
__exportStar(require("./create.js"), exports);
|
||||
var create_js_1 = require("./create.js");
|
||||
Object.defineProperty(exports, "c", { enumerable: true, get: function () { return create_js_1.create; } });
|
||||
__exportStar(require("./extract.js"), exports);
|
||||
var extract_js_1 = require("./extract.js");
|
||||
Object.defineProperty(exports, "x", { enumerable: true, get: function () { return extract_js_1.extract; } });
|
||||
__exportStar(require("./header.js"), exports);
|
||||
__exportStar(require("./list.js"), exports);
|
||||
var list_js_1 = require("./list.js");
|
||||
Object.defineProperty(exports, "t", { enumerable: true, get: function () { return list_js_1.list; } });
|
||||
// classes
|
||||
__exportStar(require("./pack.js"), exports);
|
||||
__exportStar(require("./parse.js"), exports);
|
||||
__exportStar(require("./pax.js"), exports);
|
||||
__exportStar(require("./read-entry.js"), exports);
|
||||
__exportStar(require("./replace.js"), exports);
|
||||
var replace_js_1 = require("./replace.js");
|
||||
Object.defineProperty(exports, "r", { enumerable: true, get: function () { return replace_js_1.replace; } });
|
||||
exports.types = __importStar(require("./types.js"));
|
||||
__exportStar(require("./unpack.js"), exports);
|
||||
__exportStar(require("./update.js"), exports);
|
||||
var update_js_1 = require("./update.js");
|
||||
Object.defineProperty(exports, "u", { enumerable: true, get: function () { return update_js_1.update; } });
|
||||
__exportStar(require("./write-entry.js"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,8CAA2B;AAC3B,yCAAyC;AAAhC,8FAAA,MAAM,OAAK;AACpB,+CAA4B;AAC5B,2CAA2C;AAAlC,+FAAA,OAAO,OAAK;AACrB,8CAA2B;AAC3B,4CAAyB;AACzB,qCAAqC;AAA5B,4FAAA,IAAI,OAAK;AAClB,UAAU;AACV,4CAAyB;AACzB,6CAA0B;AAC1B,2CAAwB;AACxB,kDAA+B;AAC/B,+CAA4B;AAC5B,2CAA2C;AAAlC,+FAAA,OAAO,OAAK;AACrB,oDAAmC;AACnC,8CAA2B;AAC3B,8CAA2B;AAC3B,yCAAyC;AAAhC,8FAAA,MAAM,OAAK;AACpB,mDAAgC","sourcesContent":["export {\n type TarOptionsWithAliasesAsync,\n type TarOptionsWithAliasesAsyncFile,\n type TarOptionsWithAliasesAsyncNoFile,\n type TarOptionsWithAliasesSyncNoFile,\n type TarOptionsWithAliases,\n type TarOptionsWithAliasesFile,\n type TarOptionsWithAliasesSync,\n type TarOptionsWithAliasesSyncFile,\n} from './options.js'\n\nexport * from './create.js'\nexport { create as c } from './create.js'\nexport * from './extract.js'\nexport { extract as x } from './extract.js'\nexport * from './header.js'\nexport * from './list.js'\nexport { list as t } from './list.js'\n// classes\nexport * from './pack.js'\nexport * from './parse.js'\nexport * from './pax.js'\nexport * from './read-entry.js'\nexport * from './replace.js'\nexport { replace as r } from './replace.js'\nexport * as types from './types.js'\nexport * from './unpack.js'\nexport * from './update.js'\nexport { update as u } from './update.js'\nexport * from './write-entry.js'\n"]}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
export declare const encode: (num: number, buf: Buffer) => Buffer;
|
||||
export declare const parse: (buf: Buffer) => number;
|
||||
//# sourceMappingURL=large-numbers.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"large-numbers.d.ts","sourceRoot":"","sources":["../../src/large-numbers.ts"],"names":[],"mappings":";;AAGA,eAAO,MAAM,MAAM,QAAS,MAAM,OAAO,MAAM,WAa9C,CAAA;AA6BD,eAAO,MAAM,KAAK,QAAS,MAAM,WAmBhC,CAAA"}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
"use strict";
|
||||
// Tar can encode large and negative numbers using a leading byte of
|
||||
// 0xff for negative, and 0x80 for positive.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parse = exports.encode = void 0;
|
||||
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;
|
||||
};
|
||||
exports.encode = encode;
|
||||
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.subarray(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;
|
||||
};
|
||||
exports.parse = parse;
|
||||
const twos = (buf) => {
|
||||
var len = buf.length;
|
||||
var sum = 0;
|
||||
var flipped = false;
|
||||
for (var i = len - 1; i > -1; i--) {
|
||||
var byte = Number(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 = Number(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;
|
||||
//# sourceMappingURL=large-numbers.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-7
@@ -1,7 +0,0 @@
|
||||
import { TarOptions } from './options.js';
|
||||
import { Parser } from './parse.js';
|
||||
export declare const filesFilter: (opt: TarOptions, files: string[]) => void;
|
||||
export declare const list: import("./make-command.js").TarCommand<Parser, Parser & {
|
||||
sync: true;
|
||||
}>;
|
||||
//# sourceMappingURL=list.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/list.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,UAAU,EAGX,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAgBnC,eAAO,MAAM,WAAW,QAAS,UAAU,SAAS,MAAM,EAAE,SA4B3D,CAAA;AA+DD,eAAO,MAAM,IAAI;UAG4B,IAAI;EAMhD,CAAA"}
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.list = exports.filesFilter = void 0;
|
||||
// tar -t
|
||||
const fsm = __importStar(require("@isaacs/fs-minipass"));
|
||||
const node_fs_1 = __importDefault(require("node:fs"));
|
||||
const path_1 = require("path");
|
||||
const make_command_js_1 = require("./make-command.js");
|
||||
const parse_js_1 = require("./parse.js");
|
||||
const strip_trailing_slashes_js_1 = require("./strip-trailing-slashes.js");
|
||||
const onReadEntryFunction = (opt) => {
|
||||
const onReadEntry = opt.onReadEntry;
|
||||
opt.onReadEntry =
|
||||
onReadEntry ?
|
||||
e => {
|
||||
onReadEntry(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 => [(0, strip_trailing_slashes_js_1.stripTrailingSlashes)(f), true]));
|
||||
const filter = opt.filter;
|
||||
const mapHas = (file, r = '') => {
|
||||
const root = r || (0, path_1.parse)(file).root || '.';
|
||||
let ret;
|
||||
if (file === root)
|
||||
ret = false;
|
||||
else {
|
||||
const m = map.get(file);
|
||||
if (m !== undefined) {
|
||||
ret = m;
|
||||
}
|
||||
else {
|
||||
ret = mapHas((0, path_1.dirname)(file), root);
|
||||
}
|
||||
}
|
||||
map.set(file, ret);
|
||||
return ret;
|
||||
};
|
||||
opt.filter =
|
||||
filter ?
|
||||
(file, entry) => filter(file, entry) && mapHas((0, strip_trailing_slashes_js_1.stripTrailingSlashes)(file))
|
||||
: file => mapHas((0, strip_trailing_slashes_js_1.stripTrailingSlashes)(file));
|
||||
};
|
||||
exports.filesFilter = filesFilter;
|
||||
const listFileSync = (opt) => {
|
||||
const p = new parse_js_1.Parser(opt);
|
||||
const file = opt.file;
|
||||
let fd;
|
||||
try {
|
||||
fd = node_fs_1.default.openSync(file, 'r');
|
||||
const stat = node_fs_1.default.fstatSync(fd);
|
||||
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
||||
if (stat.size < readSize) {
|
||||
const buf = Buffer.allocUnsafe(stat.size);
|
||||
const read = node_fs_1.default.readSync(fd, buf, 0, stat.size, 0);
|
||||
p.end(read === buf.byteLength ? buf : buf.subarray(0, read));
|
||||
}
|
||||
else {
|
||||
let pos = 0;
|
||||
const buf = Buffer.allocUnsafe(readSize);
|
||||
while (pos < stat.size) {
|
||||
const bytesRead = node_fs_1.default.readSync(fd, buf, 0, readSize, pos);
|
||||
if (bytesRead === 0)
|
||||
break;
|
||||
pos += bytesRead;
|
||||
p.write(buf.subarray(0, bytesRead));
|
||||
}
|
||||
p.end();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (typeof fd === 'number') {
|
||||
try {
|
||||
node_fs_1.default.closeSync(fd);
|
||||
/* c8 ignore next */
|
||||
}
|
||||
catch (er) { }
|
||||
}
|
||||
}
|
||||
};
|
||||
const listFile = (opt, _files) => {
|
||||
const parse = new parse_js_1.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);
|
||||
node_fs_1.default.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 p;
|
||||
};
|
||||
exports.list = (0, make_command_js_1.makeCommand)(listFileSync, listFile, opt => new parse_js_1.Parser(opt), opt => new parse_js_1.Parser(opt), (opt, files) => {
|
||||
if (files?.length)
|
||||
(0, exports.filesFilter)(opt, files);
|
||||
if (!opt.noResume)
|
||||
onReadEntryFunction(opt);
|
||||
});
|
||||
//# sourceMappingURL=list.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-49
@@ -1,49 +0,0 @@
|
||||
import { TarOptions, TarOptionsAsyncFile, TarOptionsAsyncNoFile, TarOptionsSyncFile, TarOptionsSyncNoFile, TarOptionsWithAliases, TarOptionsWithAliasesAsync, TarOptionsWithAliasesAsyncFile, TarOptionsWithAliasesAsyncNoFile, TarOptionsWithAliasesFile, TarOptionsWithAliasesNoFile, TarOptionsWithAliasesSync, TarOptionsWithAliasesSyncFile, TarOptionsWithAliasesSyncNoFile } from './options.js';
|
||||
export type CB = (er?: Error) => any;
|
||||
export type TarCommand<AsyncClass, SyncClass extends {
|
||||
sync: true;
|
||||
}> = {
|
||||
(): AsyncClass;
|
||||
(opt: TarOptionsWithAliasesAsyncNoFile): AsyncClass;
|
||||
(entries: string[]): AsyncClass;
|
||||
(opt: TarOptionsWithAliasesAsyncNoFile, entries: string[]): AsyncClass;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliasesSyncNoFile): SyncClass;
|
||||
(opt: TarOptionsWithAliasesSyncNoFile, entries: string[]): SyncClass;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliasesAsyncFile): Promise<void>;
|
||||
(opt: TarOptionsWithAliasesAsyncFile, entries: string[]): Promise<void>;
|
||||
(opt: TarOptionsWithAliasesAsyncFile, cb: CB): Promise<void>;
|
||||
(opt: TarOptionsWithAliasesAsyncFile, entries: string[], cb: CB): Promise<void>;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliasesSyncFile): void;
|
||||
(opt: TarOptionsWithAliasesSyncFile, entries: string[]): void;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliasesSync): typeof opt extends (TarOptionsWithAliasesFile) ? void : typeof opt extends TarOptionsWithAliasesNoFile ? SyncClass : void | SyncClass;
|
||||
(opt: TarOptionsWithAliasesSync, entries: string[]): typeof opt extends TarOptionsWithAliasesFile ? void : typeof opt extends TarOptionsWithAliasesNoFile ? SyncClass : void | SyncClass;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliasesAsync): typeof opt extends (TarOptionsWithAliasesFile) ? Promise<void> : typeof opt extends TarOptionsWithAliasesNoFile ? AsyncClass : Promise<void> | AsyncClass;
|
||||
(opt: TarOptionsWithAliasesAsync, entries: string[]): typeof opt extends TarOptionsWithAliasesFile ? Promise<void> : typeof opt extends TarOptionsWithAliasesNoFile ? AsyncClass : Promise<void> | AsyncClass;
|
||||
(opt: TarOptionsWithAliasesAsync, cb: CB): Promise<void>;
|
||||
(opt: TarOptionsWithAliasesAsync, entries: string[], cb: CB): typeof opt extends TarOptionsWithAliasesFile ? Promise<void> : typeof opt extends TarOptionsWithAliasesNoFile ? never : Promise<void>;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliasesFile): Promise<void> | void;
|
||||
(opt: TarOptionsWithAliasesFile, entries: string[]): typeof opt extends TarOptionsWithAliasesSync ? void : typeof opt extends TarOptionsWithAliasesAsync ? Promise<void> : Promise<void> | void;
|
||||
(opt: TarOptionsWithAliasesFile, cb: CB): Promise<void>;
|
||||
(opt: TarOptionsWithAliasesFile, entries: string[], cb: CB): typeof opt extends TarOptionsWithAliasesSync ? never : typeof opt extends TarOptionsWithAliasesAsync ? Promise<void> : Promise<void>;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliasesNoFile): typeof opt extends (TarOptionsWithAliasesSync) ? SyncClass : typeof opt extends TarOptionsWithAliasesAsync ? AsyncClass : SyncClass | AsyncClass;
|
||||
(opt: TarOptionsWithAliasesNoFile, entries: string[]): typeof opt extends TarOptionsWithAliasesSync ? SyncClass : typeof opt extends TarOptionsWithAliasesAsync ? AsyncClass : SyncClass | AsyncClass;
|
||||
} & {
|
||||
(opt: TarOptionsWithAliases): typeof opt extends (TarOptionsWithAliasesFile) ? typeof opt extends TarOptionsWithAliasesSync ? void : typeof opt extends TarOptionsWithAliasesAsync ? Promise<void> : void | Promise<void> : typeof opt extends TarOptionsWithAliasesNoFile ? typeof opt extends TarOptionsWithAliasesSync ? SyncClass : typeof opt extends TarOptionsWithAliasesAsync ? AsyncClass : SyncClass | AsyncClass : typeof opt extends TarOptionsWithAliasesSync ? SyncClass | void : typeof opt extends TarOptionsWithAliasesAsync ? AsyncClass | Promise<void> : SyncClass | void | AsyncClass | Promise<void>;
|
||||
} & {
|
||||
syncFile: (opt: TarOptionsSyncFile, entries: string[]) => void;
|
||||
asyncFile: (opt: TarOptionsAsyncFile, entries: string[], cb?: CB) => Promise<void>;
|
||||
syncNoFile: (opt: TarOptionsSyncNoFile, entries: string[]) => SyncClass;
|
||||
asyncNoFile: (opt: TarOptionsAsyncNoFile, entries: string[]) => AsyncClass;
|
||||
validate?: (opt: TarOptions, entries?: string[]) => void;
|
||||
};
|
||||
export declare const makeCommand: <AsyncClass, SyncClass extends {
|
||||
sync: true;
|
||||
}>(syncFile: (opt: TarOptionsSyncFile, entries: string[]) => void, asyncFile: (opt: TarOptionsAsyncFile, entries: string[], cb?: CB) => Promise<void>, syncNoFile: (opt: TarOptionsSyncNoFile, entries: string[]) => SyncClass, asyncNoFile: (opt: TarOptionsAsyncNoFile, entries: string[]) => AsyncClass, validate?: (opt: TarOptions, entries?: string[]) => void) => TarCommand<AsyncClass, SyncClass>;
|
||||
//# sourceMappingURL=make-command.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"make-command.d.ts","sourceRoot":"","sources":["../../src/make-command.ts"],"names":[],"mappings":"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"}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.makeCommand = void 0;
|
||||
const options_js_1 = require("./options.js");
|
||||
const makeCommand = (syncFile, asyncFile, syncNoFile, asyncNoFile, validate) => {
|
||||
return Object.assign((opt_ = [], entries, cb) => {
|
||||
if (Array.isArray(opt_)) {
|
||||
entries = opt_;
|
||||
opt_ = {};
|
||||
}
|
||||
if (typeof entries === 'function') {
|
||||
cb = entries;
|
||||
entries = undefined;
|
||||
}
|
||||
if (!entries) {
|
||||
entries = [];
|
||||
}
|
||||
else {
|
||||
entries = Array.from(entries);
|
||||
}
|
||||
const opt = (0, options_js_1.dealias)(opt_);
|
||||
validate?.(opt, entries);
|
||||
if ((0, options_js_1.isSyncFile)(opt)) {
|
||||
if (typeof cb === 'function') {
|
||||
throw new TypeError('callback not supported for sync tar functions');
|
||||
}
|
||||
return syncFile(opt, entries);
|
||||
}
|
||||
else if ((0, options_js_1.isAsyncFile)(opt)) {
|
||||
const p = asyncFile(opt, entries);
|
||||
// weirdness to make TS happy
|
||||
const c = cb ? cb : undefined;
|
||||
return c ? p.then(() => c(), c) : p;
|
||||
}
|
||||
else if ((0, options_js_1.isSyncNoFile)(opt)) {
|
||||
if (typeof cb === 'function') {
|
||||
throw new TypeError('callback not supported for sync tar functions');
|
||||
}
|
||||
return syncNoFile(opt, entries);
|
||||
}
|
||||
else if ((0, options_js_1.isAsyncNoFile)(opt)) {
|
||||
if (typeof cb === 'function') {
|
||||
throw new TypeError('callback only supported with file option');
|
||||
}
|
||||
return asyncNoFile(opt, entries);
|
||||
/* c8 ignore start */
|
||||
}
|
||||
else {
|
||||
throw new Error('impossible options??');
|
||||
}
|
||||
/* c8 ignore stop */
|
||||
}, {
|
||||
syncFile,
|
||||
asyncFile,
|
||||
syncNoFile,
|
||||
asyncNoFile,
|
||||
validate,
|
||||
});
|
||||
};
|
||||
exports.makeCommand = makeCommand;
|
||||
//# sourceMappingURL=make-command.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-26
@@ -1,26 +0,0 @@
|
||||
/// <reference types="node" />
|
||||
import { CwdError } from './cwd-error.js';
|
||||
import { SymlinkError } from './symlink-error.js';
|
||||
export type MkdirOptions = {
|
||||
uid?: number;
|
||||
gid?: number;
|
||||
processUid?: number;
|
||||
processGid?: number;
|
||||
umask?: number;
|
||||
preserve: boolean;
|
||||
unlink: boolean;
|
||||
cwd: string;
|
||||
mode: number;
|
||||
};
|
||||
export type MkdirError = NodeJS.ErrnoException | CwdError | SymlinkError;
|
||||
/**
|
||||
* Wrapper around fs/promises.mkdir for tar's needs.
|
||||
*
|
||||
* The main purpose is to avoid creating directories if we know that
|
||||
* they already exist (and track which ones exist for this purpose),
|
||||
* and prevent entries from being extracted into symlinked folders,
|
||||
* if `preservePaths` is not set.
|
||||
*/
|
||||
export declare const mkdir: (dir: string, opt: MkdirOptions, cb: (er?: null | MkdirError, made?: string) => void) => void | Promise<void>;
|
||||
export declare const mkdirSync: (dir: string, opt: MkdirOptions) => void | SymlinkError;
|
||||
//# sourceMappingURL=mkdir.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"mkdir.d.ts","sourceRoot":"","sources":["../../src/mkdir.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,UAAU,GAClB,MAAM,CAAC,cAAc,GACrB,QAAQ,GACR,YAAY,CAAA;AAiBhB;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,QACX,MAAM,OACN,YAAY,MACb,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,yBAoDpD,CAAA;AAiFD,eAAO,MAAM,SAAS,QAAS,MAAM,OAAO,YAAY,wBAqEvD,CAAA"}
|
||||
-188
@@ -1,188 +0,0 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mkdirSync = exports.mkdir = void 0;
|
||||
const chownr_1 = require("chownr");
|
||||
const node_fs_1 = __importDefault(require("node:fs"));
|
||||
const promises_1 = __importDefault(require("node:fs/promises"));
|
||||
const node_path_1 = __importDefault(require("node:path"));
|
||||
const cwd_error_js_1 = require("./cwd-error.js");
|
||||
const normalize_windows_path_js_1 = require("./normalize-windows-path.js");
|
||||
const symlink_error_js_1 = require("./symlink-error.js");
|
||||
const checkCwd = (dir, cb) => {
|
||||
node_fs_1.default.stat(dir, (er, st) => {
|
||||
if (er || !st.isDirectory()) {
|
||||
er = new cwd_error_js_1.CwdError(dir, er?.code || 'ENOTDIR');
|
||||
}
|
||||
cb(er);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Wrapper around fs/promises.mkdir for tar's needs.
|
||||
*
|
||||
* The main purpose is to avoid creating directories if we know that
|
||||
* they already exist (and track which ones exist for this purpose),
|
||||
* and prevent entries from being extracted into symlinked folders,
|
||||
* if `preservePaths` is not set.
|
||||
*/
|
||||
const mkdir = (dir, opt, cb) => {
|
||||
dir = (0, normalize_windows_path_js_1.normalizeWindowsPath)(dir);
|
||||
// if there's any overlap between mask and mode,
|
||||
// then we'll need an explicit chmod
|
||||
/* c8 ignore next */
|
||||
const umask = opt.umask ?? 0o22;
|
||||
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 cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd);
|
||||
const done = (er, created) => {
|
||||
if (er) {
|
||||
cb(er);
|
||||
}
|
||||
else {
|
||||
if (created && doChown) {
|
||||
(0, chownr_1.chownr)(created, uid, gid, er => done(er));
|
||||
}
|
||||
else if (needChmod) {
|
||||
node_fs_1.default.chmod(dir, mode, cb);
|
||||
}
|
||||
else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (dir === cwd) {
|
||||
return checkCwd(dir, done);
|
||||
}
|
||||
if (preserve) {
|
||||
return promises_1.default.mkdir(dir, { mode, recursive: true }).then(made => done(null, made ?? undefined), // oh, ts
|
||||
done);
|
||||
}
|
||||
const sub = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.relative(cwd, dir));
|
||||
const parts = sub.split('/');
|
||||
mkdir_(cwd, parts, mode, unlink, cwd, undefined, done);
|
||||
};
|
||||
exports.mkdir = mkdir;
|
||||
const mkdir_ = (base, parts, mode, unlink, cwd, created, cb) => {
|
||||
if (!parts.length) {
|
||||
return cb(null, created);
|
||||
}
|
||||
const p = parts.shift();
|
||||
const part = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(base + '/' + p));
|
||||
node_fs_1.default.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb));
|
||||
};
|
||||
const onmkdir = (part, parts, mode, unlink, cwd, created, cb) => (er) => {
|
||||
if (er) {
|
||||
node_fs_1.default.lstat(part, (statEr, st) => {
|
||||
if (statEr) {
|
||||
statEr.path =
|
||||
statEr.path && (0, normalize_windows_path_js_1.normalizeWindowsPath)(statEr.path);
|
||||
cb(statEr);
|
||||
}
|
||||
else if (st.isDirectory()) {
|
||||
mkdir_(part, parts, mode, unlink, cwd, created, cb);
|
||||
}
|
||||
else if (unlink) {
|
||||
node_fs_1.default.unlink(part, er => {
|
||||
if (er) {
|
||||
return cb(er);
|
||||
}
|
||||
node_fs_1.default.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb));
|
||||
});
|
||||
}
|
||||
else if (st.isSymbolicLink()) {
|
||||
return cb(new symlink_error_js_1.SymlinkError(part, part + '/' + parts.join('/')));
|
||||
}
|
||||
else {
|
||||
cb(er);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
created = created || part;
|
||||
mkdir_(part, parts, mode, unlink, cwd, created, cb);
|
||||
}
|
||||
};
|
||||
const checkCwdSync = (dir) => {
|
||||
let ok = false;
|
||||
let code = undefined;
|
||||
try {
|
||||
ok = node_fs_1.default.statSync(dir).isDirectory();
|
||||
}
|
||||
catch (er) {
|
||||
code = er?.code;
|
||||
}
|
||||
finally {
|
||||
if (!ok) {
|
||||
throw new cwd_error_js_1.CwdError(dir, code ?? 'ENOTDIR');
|
||||
}
|
||||
}
|
||||
};
|
||||
const mkdirSync = (dir, opt) => {
|
||||
dir = (0, normalize_windows_path_js_1.normalizeWindowsPath)(dir);
|
||||
// if there's any overlap between mask and mode,
|
||||
// then we'll need an explicit chmod
|
||||
/* c8 ignore next */
|
||||
const umask = opt.umask ?? 0o22;
|
||||
const mode = opt.mode | 0o700;
|
||||
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 cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd);
|
||||
const done = (created) => {
|
||||
if (created && doChown) {
|
||||
(0, chownr_1.chownrSync)(created, uid, gid);
|
||||
}
|
||||
if (needChmod) {
|
||||
node_fs_1.default.chmodSync(dir, mode);
|
||||
}
|
||||
};
|
||||
if (dir === cwd) {
|
||||
checkCwdSync(cwd);
|
||||
return done();
|
||||
}
|
||||
if (preserve) {
|
||||
return done(node_fs_1.default.mkdirSync(dir, { mode, recursive: true }) ?? undefined);
|
||||
}
|
||||
const sub = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.relative(cwd, dir));
|
||||
const parts = sub.split('/');
|
||||
let created = undefined;
|
||||
for (let p = parts.shift(), part = cwd; p && (part += '/' + p); p = parts.shift()) {
|
||||
part = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(part));
|
||||
try {
|
||||
node_fs_1.default.mkdirSync(part, mode);
|
||||
created = created || part;
|
||||
}
|
||||
catch (er) {
|
||||
const st = node_fs_1.default.lstatSync(part);
|
||||
if (st.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
else if (unlink) {
|
||||
node_fs_1.default.unlinkSync(part);
|
||||
node_fs_1.default.mkdirSync(part, mode);
|
||||
created = created || part;
|
||||
continue;
|
||||
}
|
||||
else if (st.isSymbolicLink()) {
|
||||
return new symlink_error_js_1.SymlinkError(part, part + '/' + parts.join('/'));
|
||||
}
|
||||
}
|
||||
}
|
||||
return done(created);
|
||||
};
|
||||
exports.mkdirSync = mkdirSync;
|
||||
//# sourceMappingURL=mkdir.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-2
@@ -1,2 +0,0 @@
|
||||
export declare const modeFix: (mode: number, isDir: boolean, portable: boolean) => number;
|
||||
//# sourceMappingURL=mode-fix.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"mode-fix.d.ts","sourceRoot":"","sources":["../../src/mode-fix.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,SACZ,MAAM,SACL,OAAO,YACJ,OAAO,WA0BlB,CAAA"}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.modeFix = void 0;
|
||||
const modeFix = (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;
|
||||
};
|
||||
exports.modeFix = modeFix;
|
||||
//# sourceMappingURL=mode-fix.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"mode-fix.js","sourceRoot":"","sources":["../../src/mode-fix.ts"],"names":[],"mappings":";;;AAAO,MAAM,OAAO,GAAG,CACrB,IAAY,EACZ,KAAc,EACd,QAAiB,EACjB,EAAE;IACF,IAAI,IAAI,MAAM,CAAA;IAEd,qDAAqD;IACrD,qDAAqD;IACrD,mDAAmD;IACnD,uDAAuD;IACvD,qDAAqD;IACrD,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAA;IAC/B,CAAC;IAED,qDAAqD;IACrD,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;YACjB,IAAI,IAAI,KAAK,CAAA;QACf,CAAC;QACD,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;YAChB,IAAI,IAAI,IAAI,CAAA;QACd,CAAC;QACD,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC;YACf,IAAI,IAAI,GAAG,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AA7BY,QAAA,OAAO,WA6BnB","sourcesContent":["export const modeFix = (\n mode: number,\n isDir: boolean,\n portable: boolean,\n) => {\n mode &= 0o7777\n\n // in portable mode, use the minimum reasonable umask\n // if this system creates files with 0o664 by default\n // (as some linux distros do), then we'll write the\n // archive with 0o644 instead. Also, don't ever create\n // a file that is not readable/writable by the owner.\n if (portable) {\n mode = (mode | 0o600) & ~0o22\n }\n\n // if dirs are readable, then they should be listable\n if (isDir) {\n if (mode & 0o400) {\n mode |= 0o100\n }\n if (mode & 0o40) {\n mode |= 0o10\n }\n if (mode & 0o4) {\n mode |= 0o1\n }\n }\n return mode\n}\n"]}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
export declare const normalizeUnicode: (s: string) => string;
|
||||
//# sourceMappingURL=normalize-unicode.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"normalize-unicode.d.ts","sourceRoot":"","sources":["../../src/normalize-unicode.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,gBAAgB,MAAO,MAAM,KAAG,MAqB5C,CAAA"}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.normalizeUnicode = void 0;
|
||||
// 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);
|
||||
// Limit the size of this. Very low-sophistication LRU cache
|
||||
const MAX = 10000;
|
||||
const cache = new Set();
|
||||
const normalizeUnicode = (s) => {
|
||||
if (!cache.has(s)) {
|
||||
normalizeCache[s] = s.normalize('NFD');
|
||||
}
|
||||
else {
|
||||
cache.delete(s);
|
||||
}
|
||||
cache.add(s);
|
||||
const ret = normalizeCache[s];
|
||||
let i = cache.size - MAX;
|
||||
// only prune when we're 10% over the max
|
||||
if (i > MAX / 10) {
|
||||
for (const s of cache) {
|
||||
cache.delete(s);
|
||||
delete normalizeCache[s];
|
||||
if (--i <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
exports.normalizeUnicode = normalizeUnicode;
|
||||
//# sourceMappingURL=normalize-unicode.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"normalize-unicode.js","sourceRoot":"","sources":["../../src/normalize-unicode.ts"],"names":[],"mappings":";;;AAAA,oCAAoC;AACpC,+CAA+C;AAC/C,6CAA6C;AAC7C,4CAA4C;AAC5C,MAAM,cAAc,GAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AAElE,4DAA4D;AAC5D,MAAM,GAAG,GAAG,KAAK,CAAA;AACjB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;AACxB,MAAM,gBAAgB,GAAG,CAAC,CAAS,EAAU,EAAE;IACpD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IACxC,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAEZ,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAW,CAAA;IAEvC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,CAAA;IACxB,yCAAyC;IACzC,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACf,OAAO,cAAc,CAAC,CAAC,CAAC,CAAA;YACxB,IAAI,EAAE,CAAC,IAAI,CAAC;gBAAE,MAAK;QACrB,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AArBY,QAAA,gBAAgB,oBAqB5B","sourcesContent":["// warning: extremely hot code path.\n// This has been meticulously optimized for use\n// within npm install on large package trees.\n// Do not edit without careful benchmarking.\nconst normalizeCache: Record<string, string> = Object.create(null)\n\n// Limit the size of this. Very low-sophistication LRU cache\nconst MAX = 10000\nconst cache = new Set<string>()\nexport const normalizeUnicode = (s: string): string => {\n if (!cache.has(s)) {\n normalizeCache[s] = s.normalize('NFD')\n } else {\n cache.delete(s)\n }\n cache.add(s)\n\n const ret = normalizeCache[s] as string\n\n let i = cache.size - MAX\n // only prune when we're 10% over the max\n if (i > MAX / 10) {\n for (const s of cache) {\n cache.delete(s)\n delete normalizeCache[s]\n if (--i <= 0) break\n }\n }\n\n return ret\n}\n"]}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
export declare const normalizeWindowsPath: (p: string) => string;
|
||||
//# sourceMappingURL=normalize-windows-path.d.ts.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"normalize-windows-path.d.ts","sourceRoot":"","sources":["../../src/normalize-windows-path.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,oBAAoB,MAEzB,MAAM,WAC+B,CAAA"}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
"use strict";
|
||||
// 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.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.normalizeWindowsPath = void 0;
|
||||
const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
|
||||
exports.normalizeWindowsPath = platform !== 'win32' ?
|
||||
(p) => p
|
||||
: (p) => p && p.replace(/\\/g, '/');
|
||||
//# sourceMappingURL=normalize-windows-path.js.map
|
||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"normalize-windows-path.js","sourceRoot":"","sources":["../../src/normalize-windows-path.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,gDAAgD;AAChD,sEAAsE;AACtE,qEAAqE;;;AAErE,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,OAAO,CAAC,QAAQ,CAAA;AAE9C,QAAA,oBAAoB,GAC/B,QAAQ,KAAK,OAAO,CAAC,CAAC;IACpB,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA","sourcesContent":["// on windows, either \\ or / are valid directory separators.\n// on unix, \\ is a valid character in filenames.\n// so, on windows, and only on windows, we replace all \\ chars with /,\n// so that we can use / as our one and only directory separator char.\n\nconst platform =\n process.env.TESTING_TAR_FAKE_PLATFORM || process.platform\n\nexport const normalizeWindowsPath =\n platform !== 'win32' ?\n (p: string) => p\n : (p: string) => p && p.replace(/\\\\/g, '/')\n"]}
|
||||
-621
@@ -1,621 +0,0 @@
|
||||
/// <reference types="node" />
|
||||
import { type GzipOptions, type ZlibOptions } from 'minizlib';
|
||||
import { type Stats } from 'node:fs';
|
||||
import { type ReadEntry } from './read-entry.js';
|
||||
import { type WarnData } from './warn-method.js';
|
||||
import { WriteEntry } from './write-entry.js';
|
||||
/**
|
||||
* The options that can be provided to tar commands.
|
||||
*
|
||||
* Note that some of these are only relevant for certain commands, since
|
||||
* they are specific to reading or writing.
|
||||
*
|
||||
* Aliases are provided in the {@link TarOptionsWithAliases} type.
|
||||
*/
|
||||
export interface TarOptions {
|
||||
/**
|
||||
* Perform all I/O operations synchronously. If the stream is ended
|
||||
* immediately, then it will be processed entirely synchronously.
|
||||
*/
|
||||
sync?: boolean;
|
||||
/**
|
||||
* The tar file to be read and/or written. When this is set, a stream
|
||||
* is not returned. Asynchronous commands will return a promise indicating
|
||||
* when the operation is completed, and synchronous commands will return
|
||||
* immediately.
|
||||
*/
|
||||
file?: string;
|
||||
/**
|
||||
* Treat warnings as crash-worthy errors. Defaults false.
|
||||
*/
|
||||
strict?: boolean;
|
||||
/**
|
||||
* The effective current working directory for this tar command
|
||||
*/
|
||||
cwd?: string;
|
||||
/**
|
||||
* When creating a tar archive, this can be used to compress it as well.
|
||||
* Set to `true` to use the default gzip options, or customize them as
|
||||
* needed.
|
||||
*
|
||||
* When reading, if this is unset, then the compression status will be
|
||||
* inferred from the archive data. This is generally best, unless you are
|
||||
* sure of the compression settings in use to create the archive, and want to
|
||||
* fail if the archive doesn't match expectations.
|
||||
*/
|
||||
gzip?: boolean | GzipOptions;
|
||||
/**
|
||||
* When creating archives, preserve absolute and `..` paths in the archive,
|
||||
* rather than sanitizing them under the cwd.
|
||||
*
|
||||
* When extracting, allow absolute paths, paths containing `..`, and
|
||||
* extracting through symbolic links. By default, the root `/` is stripped
|
||||
* from absolute paths (eg, turning `/x/y/z` into `x/y/z`), paths containing
|
||||
* `..` are not extracted, and any file whose location would be modified by a
|
||||
* symbolic link is not extracted.
|
||||
*
|
||||
* **WARNING** This is almost always unsafe, and must NEVER be used on
|
||||
* archives from untrusted sources, such as user input, and every entry must
|
||||
* be validated to ensure it is safe to write. Even if the input is not
|
||||
* malicious, mistakes can cause a lot of damage!
|
||||
*/
|
||||
preservePaths?: boolean;
|
||||
/**
|
||||
* When extracting, do not set the `mtime` value for extracted entries to
|
||||
* match the `mtime` in the archive.
|
||||
*
|
||||
* When creating archives, do not store the `mtime` value in the entry. Note
|
||||
* that this prevents properly using other mtime-based features (such as
|
||||
* `tar.update` or the `newer` option) with the resulting archive.
|
||||
*/
|
||||
noMtime?: boolean;
|
||||
/**
|
||||
* Set to `true` or an object with settings for `zlib.BrotliCompress()` to
|
||||
* create a brotli-compressed archive
|
||||
*
|
||||
* When extracting, this will cause the archive to be treated as a
|
||||
* brotli-compressed file if set to `true` or a ZlibOptions object.
|
||||
*
|
||||
* If set `false`, then brotli options will not be used.
|
||||
*
|
||||
* If this, the `gzip`, and `zstd` options are left `undefined`, then tar
|
||||
* will attempt to infer the brotli compression status, but can only do so
|
||||
* based on the filename. If the filename ends in `.tbr` or `.tar.br`, and
|
||||
* the first 512 bytes are not a valid tar header, then brotli decompression
|
||||
* will be attempted.
|
||||
*/
|
||||
brotli?: boolean | ZlibOptions;
|
||||
/**
|
||||
* Set to `true` or an object with settings for `zstd.compress()` to
|
||||
* create a zstd-compressed archive
|
||||
*
|
||||
* When extracting, this will cause the archive to be treated as a
|
||||
* zstd-compressed file if set to `true` or a ZlibOptions object.
|
||||
*
|
||||
* If set `false`, then zstd options will not be used.
|
||||
*
|
||||
* If this, the `gzip`, and `brotli` options are left `undefined`, then tar
|
||||
* will attempt to infer the zstd compression status, but can only do so
|
||||
* based on the filename. If the filename ends in `.tzst` or `.tar.zst`, and
|
||||
* the first 512 bytes are not a valid tar header, then zstd decompression
|
||||
* will be attempted.
|
||||
*/
|
||||
zstd?: boolean | ZlibOptions;
|
||||
/**
|
||||
* A function that is called with `(path, stat)` when creating an archive, or
|
||||
* `(path, entry)` when extracting. Return true to process the file/entry, or
|
||||
* false to exclude it.
|
||||
*/
|
||||
filter?: (path: string, entry: Stats | ReadEntry) => boolean;
|
||||
/**
|
||||
* A function that gets called for any warning encountered.
|
||||
*
|
||||
* Note: if `strict` is set, then the warning will throw, and this method
|
||||
* will not be called.
|
||||
*/
|
||||
onwarn?: (code: string, message: string, data: WarnData) => any;
|
||||
/**
|
||||
* When extracting, unlink files before creating them. Without this option,
|
||||
* tar overwrites existing files, which preserves existing hardlinks. With
|
||||
* this option, existing hardlinks will be broken, as will any symlink that
|
||||
* would affect the location of an extracted file.
|
||||
*/
|
||||
unlink?: boolean;
|
||||
/**
|
||||
* When extracting, strip the specified number of path portions from the
|
||||
* entry path. For example, with `{strip: 2}`, the entry `a/b/c/d` would be
|
||||
* extracted to `{cwd}/c/d`.
|
||||
*
|
||||
* Any entry whose entire path is stripped will be excluded.
|
||||
*/
|
||||
strip?: number;
|
||||
/**
|
||||
* When extracting, keep the existing file on disk if it's newer than the
|
||||
* file in the archive.
|
||||
*/
|
||||
newer?: boolean;
|
||||
/**
|
||||
* When extracting, do not overwrite existing files at all.
|
||||
*/
|
||||
keep?: boolean;
|
||||
/**
|
||||
* When extracting, set the `uid` and `gid` of extracted entries to the `uid`
|
||||
* and `gid` fields in the archive. Defaults to true when run as root, and
|
||||
* false otherwise.
|
||||
*
|
||||
* If false, then files and directories will be set with the owner and group
|
||||
* of the user running the process. This is similar to `-p` in `tar(1)`, but
|
||||
* ACLs and other system-specific data is never unpacked in this
|
||||
* implementation, and modes are set by default already.
|
||||
*/
|
||||
preserveOwner?: boolean;
|
||||
/**
|
||||
* The maximum depth of subfolders to extract into. This defaults to 1024.
|
||||
* Anything deeper than the limit will raise a warning and skip the entry.
|
||||
* Set to `Infinity` to remove the limitation.
|
||||
*/
|
||||
maxDepth?: number;
|
||||
/**
|
||||
* When extracting, force all created files and directories, and all
|
||||
* implicitly created directories, to be owned by the specified user id,
|
||||
* regardless of the `uid` field in the archive.
|
||||
*
|
||||
* Cannot be used along with `preserveOwner`. Requires also setting the `gid`
|
||||
* option.
|
||||
*/
|
||||
uid?: number;
|
||||
/**
|
||||
* When extracting, force all created files and directories, and all
|
||||
* implicitly created directories, to be owned by the specified group id,
|
||||
* regardless of the `gid` field in the archive.
|
||||
*
|
||||
* Cannot be used along with `preserveOwner`. Requires also setting the `uid`
|
||||
* option.
|
||||
*/
|
||||
gid?: number;
|
||||
/**
|
||||
* When extracting, provide a function that takes an `entry` object, and
|
||||
* returns a stream, or any falsey value. If a stream is provided, then that
|
||||
* stream's data will be written instead of the contents of the archive
|
||||
* entry. If a falsey value is provided, then the entry is written to disk as
|
||||
* normal.
|
||||
*
|
||||
* To exclude items from extraction, use the `filter` option.
|
||||
*
|
||||
* Note that using an asynchronous stream type with the `transform` option
|
||||
* will cause undefined behavior in synchronous extractions.
|
||||
* [MiniPass](http://npm.im/minipass)-based streams are designed for this use
|
||||
* case.
|
||||
*/
|
||||
transform?: (entry: ReadEntry) => any;
|
||||
/**
|
||||
* Call `chmod()` to ensure that extracted files match the entry's mode
|
||||
* field. Without this field set, all mode fields in archive entries are a
|
||||
* best effort attempt only.
|
||||
*
|
||||
* Setting this necessitates a call to the deprecated `process.umask()`
|
||||
* method to determine the default umask value, unless a `processUmask`
|
||||
* config is provided as well.
|
||||
*
|
||||
* If not set, tar will attempt to create file system entries with whatever
|
||||
* mode is provided, and let the implicit process `umask` apply normally, but
|
||||
* if a file already exists to be written to, then its existing mode will not
|
||||
* be modified.
|
||||
*
|
||||
* When setting `chmod: true`, it is highly recommend to set the
|
||||
* {@link TarOptions#processUmask} option as well, to avoid the call to the
|
||||
* deprecated (and thread-unsafe) `process.umask()` method.
|
||||
*/
|
||||
chmod?: boolean;
|
||||
/**
|
||||
* When setting the {@link TarOptions#chmod} option to `true`, you may
|
||||
* provide a value here to avoid having to call the deprecated and
|
||||
* thread-unsafe `process.umask()` method.
|
||||
*
|
||||
* This has no effect with `chmod` is not set to true, as mode values are not
|
||||
* set explicitly anyway. If `chmod` is set to `true`, and a value is not
|
||||
* provided here, then `process.umask()` must be called, which will result in
|
||||
* deprecation warnings.
|
||||
*
|
||||
* The most common values for this are `0o22` (resulting in directories
|
||||
* created with mode `0o755` and files with `0o644` by default) and `0o2`
|
||||
* (resulting in directores created with mode `0o775` and files `0o664`, so
|
||||
* they are group-writable).
|
||||
*/
|
||||
processUmask?: number;
|
||||
/**
|
||||
* When parsing/listing archives, `entry` streams are by default resumed
|
||||
* (set into "flowing" mode) immediately after the call to `onReadEntry()`.
|
||||
* Set `noResume: true` to suppress this behavior.
|
||||
*
|
||||
* Note that when this is set, the stream will never complete until the
|
||||
* data is consumed somehow.
|
||||
*
|
||||
* Set automatically in extract operations, since the entry is piped to
|
||||
* a file system entry right away. Only relevant when parsing.
|
||||
*/
|
||||
noResume?: boolean;
|
||||
/**
|
||||
* When creating, updating, or replacing within archives, this method will
|
||||
* be called with each WriteEntry that is created.
|
||||
*/
|
||||
onWriteEntry?: (entry: WriteEntry) => any;
|
||||
/**
|
||||
* When extracting or listing archives, this method will be called with
|
||||
* each entry that is not excluded by a `filter`.
|
||||
*
|
||||
* Important when listing archives synchronously from a file, because there
|
||||
* is otherwise no way to interact with the data!
|
||||
*/
|
||||
onReadEntry?: (entry: ReadEntry) => any;
|
||||
/**
|
||||
* Pack the targets of symbolic links rather than the link itself.
|
||||
*/
|
||||
follow?: boolean;
|
||||
/**
|
||||
* When creating archives, omit any metadata that is system-specific:
|
||||
* `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and
|
||||
* `nlink`. Note that `mtime` is still included, because this is necessary
|
||||
* for other time-based operations such as `tar.update`. Additionally, `mode`
|
||||
* is set to a "reasonable default" for mose unix systems, based on an
|
||||
* effective `umask` of `0o22`.
|
||||
*
|
||||
* This also defaults the `portable` option in the gzip configs when creating
|
||||
* a compressed archive, in order to produce deterministic archives that are
|
||||
* not operating-system specific.
|
||||
*/
|
||||
portable?: boolean;
|
||||
/**
|
||||
* When creating archives, do not recursively archive the contents of
|
||||
* directories. By default, archiving a directory archives all of its
|
||||
* contents as well.
|
||||
*/
|
||||
noDirRecurse?: boolean;
|
||||
/**
|
||||
* Suppress Pax extended headers when creating archives. Note that this means
|
||||
* long paths and linkpaths will be truncated, and large or negative numeric
|
||||
* values may be interpreted incorrectly.
|
||||
*/
|
||||
noPax?: boolean;
|
||||
/**
|
||||
* Set to a `Date` object to force a specific `mtime` value for everything
|
||||
* written to an archive.
|
||||
*
|
||||
* This is useful when creating archives that are intended to be
|
||||
* deterministic based on their contents, irrespective of the file's last
|
||||
* modification time.
|
||||
*
|
||||
* Overridden by `noMtime`.
|
||||
*/
|
||||
mtime?: Date;
|
||||
/**
|
||||
* A path portion to prefix onto the entries added to an archive.
|
||||
*/
|
||||
prefix?: string;
|
||||
/**
|
||||
* The mode to set on any created file archive, defaults to 0o666
|
||||
* masked by the process umask, often resulting in 0o644.
|
||||
*
|
||||
* This does *not* affect the mode fields of individual entries, or the
|
||||
* mode status of extracted entries on the filesystem.
|
||||
*/
|
||||
mode?: number;
|
||||
/**
|
||||
* A cache of mtime values, to avoid having to stat the same file repeatedly.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
mtimeCache?: Map<string, Date>;
|
||||
/**
|
||||
* maximum buffer size for `fs.read()` operations.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
maxReadSize?: number;
|
||||
/**
|
||||
* Filter modes of entries being unpacked, like `process.umask()`
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
umask?: number;
|
||||
/**
|
||||
* Default mode for directories. Used for all implicitly created directories,
|
||||
* and any directories in the archive that do not have a mode field.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
dmode?: number;
|
||||
/**
|
||||
* default mode for files
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
fmode?: number;
|
||||
/**
|
||||
* Map that tracks which directories already exist, for extraction
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
dirCache?: Map<string, boolean>;
|
||||
/**
|
||||
* maximum supported size of meta entries. Defaults to 1MB
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
maxMetaEntrySize?: number;
|
||||
/**
|
||||
* A Map object containing the device and inode value for any file whose
|
||||
* `nlink` value is greater than 1, to identify hard links when creating
|
||||
* archives.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
linkCache?: Map<LinkCacheKey, string>;
|
||||
/**
|
||||
* A map object containing the results of `fs.readdir()` calls.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
readdirCache?: Map<string, string[]>;
|
||||
/**
|
||||
* A cache of all `lstat` results, for use in creating archives.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
statCache?: Map<string, Stats>;
|
||||
/**
|
||||
* Number of concurrent jobs to run when creating archives.
|
||||
*
|
||||
* Defaults to 4.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
jobs?: number;
|
||||
/**
|
||||
* Automatically set to true on Windows systems.
|
||||
*
|
||||
* When extracting, causes behavior where filenames containing `<|>?:`
|
||||
* characters are converted to windows-compatible escape sequences in the
|
||||
* created filesystem entries.
|
||||
*
|
||||
* When packing, causes behavior where paths replace `\` with `/`, and
|
||||
* filenames containing the windows-compatible escaped forms of `<|>?:` are
|
||||
* converted to actual `<|>?:` characters in the archive.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
win32?: boolean;
|
||||
/**
|
||||
* For `WriteEntry` objects, the absolute path to the entry on the
|
||||
* filesystem. By default, this is `resolve(cwd, entry.path)`, but it can be
|
||||
* overridden explicitly.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
absolute?: string;
|
||||
/**
|
||||
* Used with Parser stream interface, to attach and take over when the
|
||||
* stream is completely parsed. If this is set, then the prefinish,
|
||||
* finish, and end events will not fire, and are the responsibility of
|
||||
* the ondone method to emit properly.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
ondone?: () => void;
|
||||
/**
|
||||
* Mostly for testing, but potentially useful in some cases.
|
||||
* Forcibly trigger a chown on every entry, no matter what.
|
||||
*/
|
||||
forceChown?: boolean;
|
||||
/**
|
||||
* ambiguous deprecated name for {@link onReadEntry}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
onentry?: (entry: ReadEntry) => any;
|
||||
}
|
||||
export type TarOptionsSync = TarOptions & {
|
||||
sync: true;
|
||||
};
|
||||
export type TarOptionsAsync = TarOptions & {
|
||||
sync?: false;
|
||||
};
|
||||
export type TarOptionsFile = TarOptions & {
|
||||
file: string;
|
||||
};
|
||||
export type TarOptionsNoFile = TarOptions & {
|
||||
file?: undefined;
|
||||
};
|
||||
export type TarOptionsSyncFile = TarOptionsSync & TarOptionsFile;
|
||||
export type TarOptionsAsyncFile = TarOptionsAsync & TarOptionsFile;
|
||||
export type TarOptionsSyncNoFile = TarOptionsSync & TarOptionsNoFile;
|
||||
export type TarOptionsAsyncNoFile = TarOptionsAsync & TarOptionsNoFile;
|
||||
export type LinkCacheKey = `${number}:${number}`;
|
||||
export interface TarOptionsWithAliases extends TarOptions {
|
||||
/**
|
||||
* The effective current working directory for this tar command
|
||||
*/
|
||||
C?: TarOptions['cwd'];
|
||||
/**
|
||||
* The tar file to be read and/or written. When this is set, a stream
|
||||
* is not returned. Asynchronous commands will return a promise indicating
|
||||
* when the operation is completed, and synchronous commands will return
|
||||
* immediately.
|
||||
*/
|
||||
f?: TarOptions['file'];
|
||||
/**
|
||||
* When creating a tar archive, this can be used to compress it as well.
|
||||
* Set to `true` to use the default gzip options, or customize them as
|
||||
* needed.
|
||||
*
|
||||
* When reading, if this is unset, then the compression status will be
|
||||
* inferred from the archive data. This is generally best, unless you are
|
||||
* sure of the compression settings in use to create the archive, and want to
|
||||
* fail if the archive doesn't match expectations.
|
||||
*/
|
||||
z?: TarOptions['gzip'];
|
||||
/**
|
||||
* When creating archives, preserve absolute and `..` paths in the archive,
|
||||
* rather than sanitizing them under the cwd.
|
||||
*
|
||||
* When extracting, allow absolute paths, paths containing `..`, and
|
||||
* extracting through symbolic links. By default, the root `/` is stripped
|
||||
* from absolute paths (eg, turning `/x/y/z` into `x/y/z`), paths containing
|
||||
* `..` are not extracted, and any file whose location would be modified by a
|
||||
* symbolic link is not extracted.
|
||||
*
|
||||
* **WARNING** This is almost always unsafe, and must NEVER be used on
|
||||
* archives from untrusted sources, such as user input, and every entry must
|
||||
* be validated to ensure it is safe to write. Even if the input is not
|
||||
* malicious, mistakes can cause a lot of damage!
|
||||
*/
|
||||
P?: TarOptions['preservePaths'];
|
||||
/**
|
||||
* When extracting, unlink files before creating them. Without this option,
|
||||
* tar overwrites existing files, which preserves existing hardlinks. With
|
||||
* this option, existing hardlinks will be broken, as will any symlink that
|
||||
* would affect the location of an extracted file.
|
||||
*/
|
||||
U?: TarOptions['unlink'];
|
||||
/**
|
||||
* When extracting, strip the specified number of path portions from the
|
||||
* entry path. For example, with `{strip: 2}`, the entry `a/b/c/d` would be
|
||||
* extracted to `{cwd}/c/d`.
|
||||
*/
|
||||
'strip-components'?: TarOptions['strip'];
|
||||
/**
|
||||
* When extracting, strip the specified number of path portions from the
|
||||
* entry path. For example, with `{strip: 2}`, the entry `a/b/c/d` would be
|
||||
* extracted to `{cwd}/c/d`.
|
||||
*/
|
||||
stripComponents?: TarOptions['strip'];
|
||||
/**
|
||||
* When extracting, keep the existing file on disk if it's newer than the
|
||||
* file in the archive.
|
||||
*/
|
||||
'keep-newer'?: TarOptions['newer'];
|
||||
/**
|
||||
* When extracting, keep the existing file on disk if it's newer than the
|
||||
* file in the archive.
|
||||
*/
|
||||
keepNewer?: TarOptions['newer'];
|
||||
/**
|
||||
* When extracting, keep the existing file on disk if it's newer than the
|
||||
* file in the archive.
|
||||
*/
|
||||
'keep-newer-files'?: TarOptions['newer'];
|
||||
/**
|
||||
* When extracting, keep the existing file on disk if it's newer than the
|
||||
* file in the archive.
|
||||
*/
|
||||
keepNewerFiles?: TarOptions['newer'];
|
||||
/**
|
||||
* When extracting, do not overwrite existing files at all.
|
||||
*/
|
||||
k?: TarOptions['keep'];
|
||||
/**
|
||||
* When extracting, do not overwrite existing files at all.
|
||||
*/
|
||||
'keep-existing'?: TarOptions['keep'];
|
||||
/**
|
||||
* When extracting, do not overwrite existing files at all.
|
||||
*/
|
||||
keepExisting?: TarOptions['keep'];
|
||||
/**
|
||||
* When extracting, do not set the `mtime` value for extracted entries to
|
||||
* match the `mtime` in the archive.
|
||||
*
|
||||
* When creating archives, do not store the `mtime` value in the entry. Note
|
||||
* that this prevents properly using other mtime-based features (such as
|
||||
* `tar.update` or the `newer` option) with the resulting archive.
|
||||
*/
|
||||
m?: TarOptions['noMtime'];
|
||||
/**
|
||||
* When extracting, do not set the `mtime` value for extracted entries to
|
||||
* match the `mtime` in the archive.
|
||||
*
|
||||
* When creating archives, do not store the `mtime` value in the entry. Note
|
||||
* that this prevents properly using other mtime-based features (such as
|
||||
* `tar.update` or the `newer` option) with the resulting archive.
|
||||
*/
|
||||
'no-mtime'?: TarOptions['noMtime'];
|
||||
/**
|
||||
* When extracting, set the `uid` and `gid` of extracted entries to the `uid`
|
||||
* and `gid` fields in the archive. Defaults to true when run as root, and
|
||||
* false otherwise.
|
||||
*
|
||||
* If false, then files and directories will be set with the owner and group
|
||||
* of the user running the process. This is similar to `-p` in `tar(1)`, but
|
||||
* ACLs and other system-specific data is never unpacked in this
|
||||
* implementation, and modes are set by default already.
|
||||
*/
|
||||
p?: TarOptions['preserveOwner'];
|
||||
/**
|
||||
* Pack the targets of symbolic links rather than the link itself.
|
||||
*/
|
||||
L?: TarOptions['follow'];
|
||||
/**
|
||||
* Pack the targets of symbolic links rather than the link itself.
|
||||
*/
|
||||
h?: TarOptions['follow'];
|
||||
/**
|
||||
* Deprecated option. Set explicitly false to set `chmod: true`. Ignored
|
||||
* if {@link TarOptions#chmod} is set to any boolean value.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
noChmod?: boolean;
|
||||
}
|
||||
export type TarOptionsWithAliasesSync = TarOptionsWithAliases & {
|
||||
sync: true;
|
||||
};
|
||||
export type TarOptionsWithAliasesAsync = TarOptionsWithAliases & {
|
||||
sync?: false;
|
||||
};
|
||||
export type TarOptionsWithAliasesFile = (TarOptionsWithAliases & {
|
||||
file: string;
|
||||
}) | (TarOptionsWithAliases & {
|
||||
f: string;
|
||||
});
|
||||
export type TarOptionsWithAliasesSyncFile = TarOptionsWithAliasesSync & TarOptionsWithAliasesFile;
|
||||
export type TarOptionsWithAliasesAsyncFile = TarOptionsWithAliasesAsync & TarOptionsWithAliasesFile;
|
||||
export type TarOptionsWithAliasesNoFile = TarOptionsWithAliases & {
|
||||
f?: undefined;
|
||||
file?: undefined;
|
||||
};
|
||||
export type TarOptionsWithAliasesSyncNoFile = TarOptionsWithAliasesSync & TarOptionsWithAliasesNoFile;
|
||||
export type TarOptionsWithAliasesAsyncNoFile = TarOptionsWithAliasesAsync & TarOptionsWithAliasesNoFile;
|
||||
export declare const isSyncFile: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
sync: true;
|
||||
} & {
|
||||
file: string;
|
||||
};
|
||||
export declare const isAsyncFile: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
sync?: false | undefined;
|
||||
} & {
|
||||
file: string;
|
||||
};
|
||||
export declare const isSyncNoFile: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
sync: true;
|
||||
} & {
|
||||
file?: undefined;
|
||||
};
|
||||
export declare const isAsyncNoFile: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
sync?: false | undefined;
|
||||
} & {
|
||||
file?: undefined;
|
||||
};
|
||||
export declare const isSync: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
sync: true;
|
||||
};
|
||||
export declare const isAsync: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
sync?: false | undefined;
|
||||
};
|
||||
export declare const isFile: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
file: string;
|
||||
};
|
||||
export declare const isNoFile: <O extends TarOptions>(o: O) => o is O & TarOptions & {
|
||||
file?: undefined;
|
||||
};
|
||||
export declare const dealias: (opt?: TarOptionsWithAliases) => TarOptions;
|
||||
//# sourceMappingURL=options.d.ts.map
|
||||
-1
File diff suppressed because one or more lines are too long
-66
@@ -1,66 +0,0 @@
|
||||
"use strict";
|
||||
// turn tar(1) style args like `C` into the more verbose things like `cwd`
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.dealias = exports.isNoFile = exports.isFile = exports.isAsync = exports.isSync = exports.isAsyncNoFile = exports.isSyncNoFile = exports.isAsyncFile = exports.isSyncFile = void 0;
|
||||
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'],
|
||||
['onentry', 'onReadEntry'],
|
||||
]);
|
||||
const isSyncFile = (o) => !!o.sync && !!o.file;
|
||||
exports.isSyncFile = isSyncFile;
|
||||
const isAsyncFile = (o) => !o.sync && !!o.file;
|
||||
exports.isAsyncFile = isAsyncFile;
|
||||
const isSyncNoFile = (o) => !!o.sync && !o.file;
|
||||
exports.isSyncNoFile = isSyncNoFile;
|
||||
const isAsyncNoFile = (o) => !o.sync && !o.file;
|
||||
exports.isAsyncNoFile = isAsyncNoFile;
|
||||
const isSync = (o) => !!o.sync;
|
||||
exports.isSync = isSync;
|
||||
const isAsync = (o) => !o.sync;
|
||||
exports.isAsync = isAsync;
|
||||
const isFile = (o) => !!o.file;
|
||||
exports.isFile = isFile;
|
||||
const isNoFile = (o) => !o.file;
|
||||
exports.isNoFile = isNoFile;
|
||||
const dealiasKey = (k) => {
|
||||
const d = argmap.get(k);
|
||||
if (d)
|
||||
return d;
|
||||
return k;
|
||||
};
|
||||
const dealias = (opt = {}) => {
|
||||
if (!opt)
|
||||
return {};
|
||||
const result = {};
|
||||
for (const [key, v] of Object.entries(opt)) {
|
||||
// TS doesn't know that aliases are going to always be the same type
|
||||
const k = dealiasKey(key);
|
||||
result[k] = v;
|
||||
}
|
||||
// affordance for deprecated noChmod -> chmod
|
||||
if (result.chmod === undefined && result.noChmod === false) {
|
||||
result.chmod = true;
|
||||
}
|
||||
delete result.noChmod;
|
||||
return result;
|
||||
};
|
||||
exports.dealias = dealias;
|
||||
//# sourceMappingURL=options.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-103
@@ -1,103 +0,0 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { type Stats } from 'fs';
|
||||
import { WriteEntry, WriteEntrySync, WriteEntryTar } from './write-entry.js';
|
||||
export declare class PackJob {
|
||||
path: string;
|
||||
absolute: string;
|
||||
entry?: WriteEntry | WriteEntryTar;
|
||||
stat?: Stats;
|
||||
readdir?: string[];
|
||||
pending: boolean;
|
||||
ignore: boolean;
|
||||
piped: boolean;
|
||||
constructor(path: string, absolute: string);
|
||||
}
|
||||
import { Minipass } from 'minipass';
|
||||
import * as zlib from 'minizlib';
|
||||
import { Yallist } from 'yallist';
|
||||
import { ReadEntry } from './read-entry.js';
|
||||
import { WarnEvent, type WarnData, type Warner } from './warn-method.js';
|
||||
declare const ONSTAT: unique symbol;
|
||||
declare const ENDED: unique symbol;
|
||||
declare const QUEUE: unique symbol;
|
||||
declare const CURRENT: unique symbol;
|
||||
declare const PROCESS: unique symbol;
|
||||
declare const PROCESSING: unique symbol;
|
||||
declare const PROCESSJOB: unique symbol;
|
||||
declare const JOBS: unique symbol;
|
||||
declare const JOBDONE: unique symbol;
|
||||
declare const ADDFSENTRY: unique symbol;
|
||||
declare const ADDTARENTRY: unique symbol;
|
||||
declare const STAT: unique symbol;
|
||||
declare const READDIR: unique symbol;
|
||||
declare const ONREADDIR: unique symbol;
|
||||
declare const PIPE: unique symbol;
|
||||
declare const ENTRY: unique symbol;
|
||||
declare const ENTRYOPT: unique symbol;
|
||||
declare const WRITEENTRYCLASS: unique symbol;
|
||||
declare const WRITE: unique symbol;
|
||||
declare const ONDRAIN: unique symbol;
|
||||
import { TarOptions } from './options.js';
|
||||
export declare class Pack extends Minipass<Buffer, ReadEntry | string, WarnEvent<Buffer>> implements Warner {
|
||||
opt: TarOptions;
|
||||
cwd: string;
|
||||
maxReadSize?: number;
|
||||
preservePaths: boolean;
|
||||
strict: boolean;
|
||||
noPax: boolean;
|
||||
prefix: string;
|
||||
linkCache: Exclude<TarOptions['linkCache'], undefined>;
|
||||
statCache: Exclude<TarOptions['statCache'], undefined>;
|
||||
file: string;
|
||||
portable: boolean;
|
||||
zip?: zlib.BrotliCompress | zlib.Gzip | zlib.ZstdCompress;
|
||||
readdirCache: Exclude<TarOptions['readdirCache'], undefined>;
|
||||
noDirRecurse: boolean;
|
||||
follow: boolean;
|
||||
noMtime: boolean;
|
||||
mtime?: Date;
|
||||
filter: Exclude<TarOptions['filter'], undefined>;
|
||||
jobs: number;
|
||||
[WRITEENTRYCLASS]: typeof WriteEntry | typeof WriteEntrySync;
|
||||
onWriteEntry?: (entry: WriteEntry) => void;
|
||||
[QUEUE]: Yallist<PackJob>;
|
||||
[JOBS]: number;
|
||||
[PROCESSING]: boolean;
|
||||
[ENDED]: boolean;
|
||||
constructor(opt?: TarOptions);
|
||||
[WRITE](chunk: Buffer): boolean;
|
||||
add(path: string | ReadEntry): this;
|
||||
end(cb?: () => void): this;
|
||||
end(path: string | ReadEntry, cb?: () => void): this;
|
||||
end(path: string | ReadEntry, encoding?: Minipass.Encoding, cb?: () => void): this;
|
||||
write(path: string | ReadEntry): boolean;
|
||||
[ADDTARENTRY](p: ReadEntry): void;
|
||||
[ADDFSENTRY](p: string): void;
|
||||
[STAT](job: PackJob): void;
|
||||
[ONSTAT](job: PackJob, stat: Stats): void;
|
||||
[READDIR](job: PackJob): void;
|
||||
[ONREADDIR](job: PackJob, entries: string[]): void;
|
||||
[PROCESS](): void;
|
||||
get [CURRENT](): PackJob | undefined;
|
||||
[JOBDONE](_job: PackJob): void;
|
||||
[PROCESSJOB](job: PackJob): void;
|
||||
[ENTRYOPT](job: PackJob): TarOptions;
|
||||
[ENTRY](job: PackJob): WriteEntry | undefined;
|
||||
[ONDRAIN](): void;
|
||||
[PIPE](job: PackJob): void;
|
||||
pause(): void;
|
||||
warn(code: string, message: string | Error, data?: WarnData): void;
|
||||
}
|
||||
export declare class PackSync extends Pack {
|
||||
sync: true;
|
||||
constructor(opt: TarOptions);
|
||||
pause(): void;
|
||||
resume(): void;
|
||||
[STAT](job: PackJob): void;
|
||||
[READDIR](job: PackJob): void;
|
||||
[PIPE](job: PackJob): void;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=pack.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/pack.ts"],"names":[],"mappings":"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"}
|
||||
-494
@@ -1,494 +0,0 @@
|
||||
"use strict";
|
||||
// A readable tar stream creator
|
||||
// Technically, this is a transform stream that you write paths into,
|
||||
// and tar format comes out of.
|
||||
// The `add()` method is like `write()` but returns this,
|
||||
// and end() return `this` as well, so you can
|
||||
// do `new Pack(opt).add('files').add('dir').end().pipe(output)
|
||||
// You could also do something like:
|
||||
// streamOfPaths().pipe(new Pack()).pipe(new fs.WriteStream('out.tar'))
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PackSync = exports.Pack = exports.PackJob = void 0;
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const write_entry_js_1 = require("./write-entry.js");
|
||||
class PackJob {
|
||||
path;
|
||||
absolute;
|
||||
entry;
|
||||
stat;
|
||||
readdir;
|
||||
pending = false;
|
||||
ignore = false;
|
||||
piped = false;
|
||||
constructor(path, absolute) {
|
||||
this.path = path || './';
|
||||
this.absolute = absolute;
|
||||
}
|
||||
}
|
||||
exports.PackJob = PackJob;
|
||||
const minipass_1 = require("minipass");
|
||||
const zlib = __importStar(require("minizlib"));
|
||||
const yallist_1 = require("yallist");
|
||||
const read_entry_js_1 = require("./read-entry.js");
|
||||
const warn_method_js_1 = require("./warn-method.js");
|
||||
const EOF = Buffer.alloc(1024);
|
||||
const ONSTAT = Symbol('onStat');
|
||||
const ENDED = Symbol('ended');
|
||||
const QUEUE = Symbol('queue');
|
||||
const CURRENT = Symbol('current');
|
||||
const PROCESS = Symbol('process');
|
||||
const PROCESSING = Symbol('processing');
|
||||
const PROCESSJOB = Symbol('processJob');
|
||||
const JOBS = Symbol('jobs');
|
||||
const JOBDONE = Symbol('jobDone');
|
||||
const ADDFSENTRY = Symbol('addFSEntry');
|
||||
const ADDTARENTRY = Symbol('addTarEntry');
|
||||
const STAT = Symbol('stat');
|
||||
const READDIR = Symbol('readdir');
|
||||
const ONREADDIR = Symbol('onreaddir');
|
||||
const PIPE = Symbol('pipe');
|
||||
const ENTRY = Symbol('entry');
|
||||
const ENTRYOPT = Symbol('entryOpt');
|
||||
const WRITEENTRYCLASS = Symbol('writeEntryClass');
|
||||
const WRITE = Symbol('write');
|
||||
const ONDRAIN = Symbol('ondrain');
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const normalize_windows_path_js_1 = require("./normalize-windows-path.js");
|
||||
class Pack extends minipass_1.Minipass {
|
||||
opt;
|
||||
cwd;
|
||||
maxReadSize;
|
||||
preservePaths;
|
||||
strict;
|
||||
noPax;
|
||||
prefix;
|
||||
linkCache;
|
||||
statCache;
|
||||
file;
|
||||
portable;
|
||||
zip;
|
||||
readdirCache;
|
||||
noDirRecurse;
|
||||
follow;
|
||||
noMtime;
|
||||
mtime;
|
||||
filter;
|
||||
jobs;
|
||||
[WRITEENTRYCLASS];
|
||||
onWriteEntry;
|
||||
// Note: we actually DO need a linked list here, because we
|
||||
// shift() to update the head of the list where we start, but still
|
||||
// while that happens, need to know what the next item in the queue
|
||||
// will be. Since we do multiple jobs in parallel, it's not as simple
|
||||
// as just an Array.shift(), since that would lose the information about
|
||||
// the next job in the list. We could add a .next field on the PackJob
|
||||
// class, but then we'd have to be tracking the tail of the queue the
|
||||
// whole time, and Yallist just does that for us anyway.
|
||||
[QUEUE];
|
||||
[JOBS] = 0;
|
||||
[PROCESSING] = false;
|
||||
[ENDED] = false;
|
||||
constructor(opt = {}) {
|
||||
//@ts-ignore
|
||||
super();
|
||||
this.opt = opt;
|
||||
this.file = opt.file || '';
|
||||
this.cwd = opt.cwd || process.cwd();
|
||||
this.maxReadSize = opt.maxReadSize;
|
||||
this.preservePaths = !!opt.preservePaths;
|
||||
this.strict = !!opt.strict;
|
||||
this.noPax = !!opt.noPax;
|
||||
this.prefix = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.prefix || '');
|
||||
this.linkCache = opt.linkCache || new Map();
|
||||
this.statCache = opt.statCache || new Map();
|
||||
this.readdirCache = opt.readdirCache || new Map();
|
||||
this.onWriteEntry = opt.onWriteEntry;
|
||||
this[WRITEENTRYCLASS] = write_entry_js_1.WriteEntry;
|
||||
if (typeof opt.onwarn === 'function') {
|
||||
this.on('warn', opt.onwarn);
|
||||
}
|
||||
this.portable = !!opt.portable;
|
||||
if (opt.gzip || opt.brotli || opt.zstd) {
|
||||
if ((opt.gzip ? 1 : 0) +
|
||||
(opt.brotli ? 1 : 0) +
|
||||
(opt.zstd ? 1 : 0) >
|
||||
1) {
|
||||
throw new TypeError('gzip, brotli, zstd are mutually exclusive');
|
||||
}
|
||||
if (opt.gzip) {
|
||||
if (typeof opt.gzip !== 'object') {
|
||||
opt.gzip = {};
|
||||
}
|
||||
if (this.portable) {
|
||||
opt.gzip.portable = true;
|
||||
}
|
||||
this.zip = new zlib.Gzip(opt.gzip);
|
||||
}
|
||||
if (opt.brotli) {
|
||||
if (typeof opt.brotli !== 'object') {
|
||||
opt.brotli = {};
|
||||
}
|
||||
this.zip = new zlib.BrotliCompress(opt.brotli);
|
||||
}
|
||||
if (opt.zstd) {
|
||||
if (typeof opt.zstd !== 'object') {
|
||||
opt.zstd = {};
|
||||
}
|
||||
this.zip = new zlib.ZstdCompress(opt.zstd);
|
||||
}
|
||||
/* c8 ignore next */
|
||||
if (!this.zip)
|
||||
throw new Error('impossible');
|
||||
const zip = this.zip;
|
||||
zip.on('data', chunk => super.write(chunk));
|
||||
zip.on('end', () => super.end());
|
||||
zip.on('drain', () => this[ONDRAIN]());
|
||||
this.on('resume', () => zip.resume());
|
||||
}
|
||||
else {
|
||||
this.on('drain', this[ONDRAIN]);
|
||||
}
|
||||
this.noDirRecurse = !!opt.noDirRecurse;
|
||||
this.follow = !!opt.follow;
|
||||
this.noMtime = !!opt.noMtime;
|
||||
if (opt.mtime)
|
||||
this.mtime = opt.mtime;
|
||||
this.filter =
|
||||
typeof opt.filter === 'function' ? opt.filter : () => true;
|
||||
this[QUEUE] = new yallist_1.Yallist();
|
||||
this[JOBS] = 0;
|
||||
this.jobs = Number(opt.jobs) || 4;
|
||||
this[PROCESSING] = false;
|
||||
this[ENDED] = false;
|
||||
}
|
||||
[WRITE](chunk) {
|
||||
return super.write(chunk);
|
||||
}
|
||||
add(path) {
|
||||
this.write(path);
|
||||
return this;
|
||||
}
|
||||
end(path, encoding, cb) {
|
||||
/* c8 ignore start */
|
||||
if (typeof path === 'function') {
|
||||
cb = path;
|
||||
path = undefined;
|
||||
}
|
||||
if (typeof encoding === 'function') {
|
||||
cb = encoding;
|
||||
encoding = undefined;
|
||||
}
|
||||
/* c8 ignore stop */
|
||||
if (path) {
|
||||
this.add(path);
|
||||
}
|
||||
this[ENDED] = true;
|
||||
this[PROCESS]();
|
||||
/* c8 ignore next */
|
||||
if (cb)
|
||||
cb();
|
||||
return this;
|
||||
}
|
||||
write(path) {
|
||||
if (this[ENDED]) {
|
||||
throw new Error('write after end');
|
||||
}
|
||||
if (path instanceof read_entry_js_1.ReadEntry) {
|
||||
this[ADDTARENTRY](path);
|
||||
}
|
||||
else {
|
||||
this[ADDFSENTRY](path);
|
||||
}
|
||||
return this.flowing;
|
||||
}
|
||||
[ADDTARENTRY](p) {
|
||||
const absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path_1.default.resolve(this.cwd, p.path));
|
||||
// in this case, we don't have to wait for the stat
|
||||
if (!this.filter(p.path, p)) {
|
||||
p.resume();
|
||||
}
|
||||
else {
|
||||
const job = new PackJob(p.path, absolute);
|
||||
job.entry = new write_entry_js_1.WriteEntryTar(p, this[ENTRYOPT](job));
|
||||
job.entry.on('end', () => this[JOBDONE](job));
|
||||
this[JOBS] += 1;
|
||||
this[QUEUE].push(job);
|
||||
}
|
||||
this[PROCESS]();
|
||||
}
|
||||
[ADDFSENTRY](p) {
|
||||
const absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path_1.default.resolve(this.cwd, p));
|
||||
this[QUEUE].push(new PackJob(p, absolute));
|
||||
this[PROCESS]();
|
||||
}
|
||||
[STAT](job) {
|
||||
job.pending = true;
|
||||
this[JOBS] += 1;
|
||||
const stat = this.follow ? 'stat' : 'lstat';
|
||||
fs_1.default[stat](job.absolute, (er, stat) => {
|
||||
job.pending = false;
|
||||
this[JOBS] -= 1;
|
||||
if (er) {
|
||||
this.emit('error', er);
|
||||
}
|
||||
else {
|
||||
this[ONSTAT](job, stat);
|
||||
}
|
||||
});
|
||||
}
|
||||
[ONSTAT](job, stat) {
|
||||
this.statCache.set(job.absolute, stat);
|
||||
job.stat = stat;
|
||||
// now we have the stat, we can filter it.
|
||||
if (!this.filter(job.path, stat)) {
|
||||
job.ignore = true;
|
||||
}
|
||||
this[PROCESS]();
|
||||
}
|
||||
[READDIR](job) {
|
||||
job.pending = true;
|
||||
this[JOBS] += 1;
|
||||
fs_1.default.readdir(job.absolute, (er, entries) => {
|
||||
job.pending = false;
|
||||
this[JOBS] -= 1;
|
||||
if (er) {
|
||||
return this.emit('error', er);
|
||||
}
|
||||
this[ONREADDIR](job, entries);
|
||||
});
|
||||
}
|
||||
[ONREADDIR](job, entries) {
|
||||
this.readdirCache.set(job.absolute, entries);
|
||||
job.readdir = entries;
|
||||
this[PROCESS]();
|
||||
}
|
||||
[PROCESS]() {
|
||||
if (this[PROCESSING]) {
|
||||
return;
|
||||
}
|
||||
this[PROCESSING] = true;
|
||||
for (let w = this[QUEUE].head; !!w && this[JOBS] < this.jobs; w = w.next) {
|
||||
this[PROCESSJOB](w.value);
|
||||
if (w.value.ignore) {
|
||||
const p = w.next;
|
||||
this[QUEUE].removeNode(w);
|
||||
w.next = p;
|
||||
}
|
||||
}
|
||||
this[PROCESSING] = false;
|
||||
if (this[ENDED] && !this[QUEUE].length && this[JOBS] === 0) {
|
||||
if (this.zip) {
|
||||
this.zip.end(EOF);
|
||||
}
|
||||
else {
|
||||
super.write(EOF);
|
||||
super.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
get [CURRENT]() {
|
||||
return this[QUEUE] && this[QUEUE].head && this[QUEUE].head.value;
|
||||
}
|
||||
[JOBDONE](_job) {
|
||||
this[QUEUE].shift();
|
||||
this[JOBS] -= 1;
|
||||
this[PROCESS]();
|
||||
}
|
||||
[PROCESSJOB](job) {
|
||||
if (job.pending) {
|
||||
return;
|
||||
}
|
||||
if (job.entry) {
|
||||
if (job === this[CURRENT] && !job.piped) {
|
||||
this[PIPE](job);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!job.stat) {
|
||||
const sc = this.statCache.get(job.absolute);
|
||||
if (sc) {
|
||||
this[ONSTAT](job, sc);
|
||||
}
|
||||
else {
|
||||
this[STAT](job);
|
||||
}
|
||||
}
|
||||
if (!job.stat) {
|
||||
return;
|
||||
}
|
||||
// filtered out!
|
||||
if (job.ignore) {
|
||||
return;
|
||||
}
|
||||
if (!this.noDirRecurse &&
|
||||
job.stat.isDirectory() &&
|
||||
!job.readdir) {
|
||||
const rc = this.readdirCache.get(job.absolute);
|
||||
if (rc) {
|
||||
this[ONREADDIR](job, rc);
|
||||
}
|
||||
else {
|
||||
this[READDIR](job);
|
||||
}
|
||||
if (!job.readdir) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// we know it doesn't have an entry, because that got checked above
|
||||
job.entry = this[ENTRY](job);
|
||||
if (!job.entry) {
|
||||
job.ignore = true;
|
||||
return;
|
||||
}
|
||||
if (job === this[CURRENT] && !job.piped) {
|
||||
this[PIPE](job);
|
||||
}
|
||||
}
|
||||
[ENTRYOPT](job) {
|
||||
return {
|
||||
onwarn: (code, msg, data) => this.warn(code, msg, data),
|
||||
noPax: this.noPax,
|
||||
cwd: this.cwd,
|
||||
absolute: job.absolute,
|
||||
preservePaths: this.preservePaths,
|
||||
maxReadSize: this.maxReadSize,
|
||||
strict: this.strict,
|
||||
portable: this.portable,
|
||||
linkCache: this.linkCache,
|
||||
statCache: this.statCache,
|
||||
noMtime: this.noMtime,
|
||||
mtime: this.mtime,
|
||||
prefix: this.prefix,
|
||||
onWriteEntry: this.onWriteEntry,
|
||||
};
|
||||
}
|
||||
[ENTRY](job) {
|
||||
this[JOBS] += 1;
|
||||
try {
|
||||
const e = new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job));
|
||||
return e
|
||||
.on('end', () => this[JOBDONE](job))
|
||||
.on('error', er => this.emit('error', er));
|
||||
}
|
||||
catch (er) {
|
||||
this.emit('error', er);
|
||||
}
|
||||
}
|
||||
[ONDRAIN]() {
|
||||
if (this[CURRENT] && this[CURRENT].entry) {
|
||||
this[CURRENT].entry.resume();
|
||||
}
|
||||
}
|
||||
// like .pipe() but using super, because our write() is special
|
||||
[PIPE](job) {
|
||||
job.piped = true;
|
||||
if (job.readdir) {
|
||||
job.readdir.forEach(entry => {
|
||||
const p = job.path;
|
||||
const base = p === './' ? '' : p.replace(/\/*$/, '/');
|
||||
this[ADDFSENTRY](base + entry);
|
||||
});
|
||||
}
|
||||
const source = job.entry;
|
||||
const zip = this.zip;
|
||||
/* c8 ignore start */
|
||||
if (!source)
|
||||
throw new Error('cannot pipe without source');
|
||||
/* c8 ignore stop */
|
||||
if (zip) {
|
||||
source.on('data', chunk => {
|
||||
if (!zip.write(chunk)) {
|
||||
source.pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
source.on('data', chunk => {
|
||||
if (!super.write(chunk)) {
|
||||
source.pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
pause() {
|
||||
if (this.zip) {
|
||||
this.zip.pause();
|
||||
}
|
||||
return super.pause();
|
||||
}
|
||||
warn(code, message, data = {}) {
|
||||
(0, warn_method_js_1.warnMethod)(this, code, message, data);
|
||||
}
|
||||
}
|
||||
exports.Pack = Pack;
|
||||
class PackSync extends Pack {
|
||||
sync = true;
|
||||
constructor(opt) {
|
||||
super(opt);
|
||||
this[WRITEENTRYCLASS] = write_entry_js_1.WriteEntrySync;
|
||||
}
|
||||
// pause/resume are no-ops in sync streams.
|
||||
pause() { }
|
||||
resume() { }
|
||||
[STAT](job) {
|
||||
const stat = this.follow ? 'statSync' : 'lstatSync';
|
||||
this[ONSTAT](job, fs_1.default[stat](job.absolute));
|
||||
}
|
||||
[READDIR](job) {
|
||||
this[ONREADDIR](job, fs_1.default.readdirSync(job.absolute));
|
||||
}
|
||||
// gotta get it all in this tick
|
||||
[PIPE](job) {
|
||||
const source = job.entry;
|
||||
const zip = this.zip;
|
||||
if (job.readdir) {
|
||||
job.readdir.forEach(entry => {
|
||||
const p = job.path;
|
||||
const base = p === './' ? '' : p.replace(/\/*$/, '/');
|
||||
this[ADDFSENTRY](base + entry);
|
||||
});
|
||||
}
|
||||
/* c8 ignore start */
|
||||
if (!source)
|
||||
throw new Error('Cannot pipe without source');
|
||||
/* c8 ignore stop */
|
||||
if (zip) {
|
||||
source.on('data', chunk => {
|
||||
zip.write(chunk);
|
||||
});
|
||||
}
|
||||
else {
|
||||
source.on('data', chunk => {
|
||||
super[WRITE](chunk);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.PackSync = PackSync;
|
||||
//# sourceMappingURL=pack.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-3
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { EventEmitter as EE } from 'events';
|
||||
import { BrotliDecompress, Unzip, ZstdDecompress } from 'minizlib';
|
||||
import { TarOptions } from './options.js';
|
||||
import { Pax } from './pax.js';
|
||||
import { ReadEntry } from './read-entry.js';
|
||||
import { type WarnData, type Warner } from './warn-method.js';
|
||||
declare const STATE: unique symbol;
|
||||
declare const WRITEENTRY: unique symbol;
|
||||
declare const READENTRY: unique symbol;
|
||||
declare const NEXTENTRY: unique symbol;
|
||||
declare const PROCESSENTRY: unique symbol;
|
||||
declare const EX: unique symbol;
|
||||
declare const GEX: unique symbol;
|
||||
declare const META: unique symbol;
|
||||
declare const EMITMETA: unique symbol;
|
||||
declare const BUFFER: unique symbol;
|
||||
declare const QUEUE: unique symbol;
|
||||
declare const ENDED: unique symbol;
|
||||
declare const EMITTEDEND: unique symbol;
|
||||
declare const EMIT: unique symbol;
|
||||
declare const UNZIP: unique symbol;
|
||||
declare const CONSUMECHUNK: unique symbol;
|
||||
declare const CONSUMECHUNKSUB: unique symbol;
|
||||
declare const CONSUMEBODY: unique symbol;
|
||||
declare const CONSUMEMETA: unique symbol;
|
||||
declare const CONSUMEHEADER: unique symbol;
|
||||
declare const CONSUMING: unique symbol;
|
||||
declare const BUFFERCONCAT: unique symbol;
|
||||
declare const MAYBEEND: unique symbol;
|
||||
declare const WRITING: unique symbol;
|
||||
declare const ABORTED: unique symbol;
|
||||
declare const SAW_VALID_ENTRY: unique symbol;
|
||||
declare const SAW_NULL_BLOCK: unique symbol;
|
||||
declare const SAW_EOF: unique symbol;
|
||||
declare const CLOSESTREAM: unique symbol;
|
||||
export type State = 'begin' | 'header' | 'ignore' | 'meta' | 'body';
|
||||
export declare class Parser extends EE implements Warner {
|
||||
file: string;
|
||||
strict: boolean;
|
||||
maxMetaEntrySize: number;
|
||||
filter: Exclude<TarOptions['filter'], undefined>;
|
||||
brotli?: TarOptions['brotli'];
|
||||
zstd?: TarOptions['zstd'];
|
||||
writable: true;
|
||||
readable: false;
|
||||
[QUEUE]: (ReadEntry | [string | symbol, any, any])[];
|
||||
[BUFFER]?: Buffer;
|
||||
[READENTRY]?: ReadEntry;
|
||||
[WRITEENTRY]?: ReadEntry;
|
||||
[STATE]: State;
|
||||
[META]: string;
|
||||
[EX]?: Pax;
|
||||
[GEX]?: Pax;
|
||||
[ENDED]: boolean;
|
||||
[UNZIP]?: false | Unzip | BrotliDecompress | ZstdDecompress;
|
||||
[ABORTED]: boolean;
|
||||
[SAW_VALID_ENTRY]?: boolean;
|
||||
[SAW_NULL_BLOCK]: boolean;
|
||||
[SAW_EOF]: boolean;
|
||||
[WRITING]: boolean;
|
||||
[CONSUMING]: boolean;
|
||||
[EMITTEDEND]: boolean;
|
||||
constructor(opt?: TarOptions);
|
||||
warn(code: string, message: string | Error, data?: WarnData): void;
|
||||
[CONSUMEHEADER](chunk: Buffer, position: number): void;
|
||||
[CLOSESTREAM](): void;
|
||||
[PROCESSENTRY](entry?: ReadEntry | [string | symbol, any, any]): boolean;
|
||||
[NEXTENTRY](): void;
|
||||
[CONSUMEBODY](chunk: Buffer, position: number): number;
|
||||
[CONSUMEMETA](chunk: Buffer, position: number): number;
|
||||
[EMIT](ev: string | symbol, data?: any, extra?: any): void;
|
||||
[EMITMETA](entry: ReadEntry): void;
|
||||
abort(error: Error): void;
|
||||
write(buffer: Uint8Array | string, cb?: (err?: Error | null) => void): boolean;
|
||||
write(str: string, encoding?: BufferEncoding, cb?: (err?: Error | null) => void): boolean;
|
||||
[BUFFERCONCAT](c: Buffer): void;
|
||||
[MAYBEEND](): void;
|
||||
[CONSUMECHUNK](chunk?: Buffer): void;
|
||||
[CONSUMECHUNKSUB](chunk: Buffer): void;
|
||||
end(cb?: () => void): this;
|
||||
end(data: string | Buffer, cb?: () => void): this;
|
||||
end(str: string, encoding?: BufferEncoding, cb?: () => void): this;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=parse.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/parse.ts"],"names":[],"mappings":"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"}
|
||||
-620
@@ -1,620 +0,0 @@
|
||||
"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 list 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
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Parser = void 0;
|
||||
const events_1 = require("events");
|
||||
const minizlib_1 = require("minizlib");
|
||||
const header_js_1 = require("./header.js");
|
||||
const pax_js_1 = require("./pax.js");
|
||||
const read_entry_js_1 = require("./read-entry.js");
|
||||
const warn_method_js_1 = require("./warn-method.js");
|
||||
const maxMetaEntrySize = 1024 * 1024;
|
||||
const gzipHeader = Buffer.from([0x1f, 0x8b]);
|
||||
const zstdHeader = Buffer.from([0x28, 0xb5, 0x2f, 0xfd]);
|
||||
const ZIP_HEADER_LEN = Math.max(gzipHeader.length, zstdHeader.length);
|
||||
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;
|
||||
class Parser extends events_1.EventEmitter {
|
||||
file;
|
||||
strict;
|
||||
maxMetaEntrySize;
|
||||
filter;
|
||||
brotli;
|
||||
zstd;
|
||||
writable = true;
|
||||
readable = false;
|
||||
[QUEUE] = [];
|
||||
[BUFFER];
|
||||
[READENTRY];
|
||||
[WRITEENTRY];
|
||||
[STATE] = 'begin';
|
||||
[META] = '';
|
||||
[EX];
|
||||
[GEX];
|
||||
[ENDED] = false;
|
||||
[UNZIP];
|
||||
[ABORTED] = false;
|
||||
[SAW_VALID_ENTRY];
|
||||
[SAW_NULL_BLOCK] = false;
|
||||
[SAW_EOF] = false;
|
||||
[WRITING] = false;
|
||||
[CONSUMING] = false;
|
||||
[EMITTEDEND] = false;
|
||||
constructor(opt = {}) {
|
||||
super();
|
||||
this.file = opt.file || '';
|
||||
// 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.zstd) && opt.brotli !== undefined ? opt.brotli
|
||||
: isTBR ? undefined
|
||||
: false;
|
||||
// zstd has magic bytes to identify it, but we also support explicit options
|
||||
// and file extension detection
|
||||
const isTZST = opt.file &&
|
||||
(opt.file.endsWith('.tar.zst') || opt.file.endsWith('.tzst'));
|
||||
this.zstd =
|
||||
!(opt.gzip || opt.brotli) && opt.zstd !== undefined ? opt.zstd
|
||||
: isTZST ? true
|
||||
: undefined;
|
||||
// have to set this so that streams are ok piping into it
|
||||
this.on('end', () => this[CLOSESTREAM]());
|
||||
if (typeof opt.onwarn === 'function') {
|
||||
this.on('warn', opt.onwarn);
|
||||
}
|
||||
if (typeof opt.onReadEntry === 'function') {
|
||||
this.on('entry', opt.onReadEntry);
|
||||
}
|
||||
}
|
||||
warn(code, message, data = {}) {
|
||||
(0, warn_method_js_1.warnMethod)(this, code, message, data);
|
||||
}
|
||||
[CONSUMEHEADER](chunk, position) {
|
||||
if (this[SAW_VALID_ENTRY] === undefined) {
|
||||
this[SAW_VALID_ENTRY] = false;
|
||||
}
|
||||
let header;
|
||||
try {
|
||||
header = new header_js_1.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) &&
|
||||
!/^(Global)?ExtendedHeader$/.test(type) &&
|
||||
header.linkpath) {
|
||||
this.warn('TAR_ENTRY_INVALID', 'linkpath forbidden', {
|
||||
header,
|
||||
});
|
||||
}
|
||||
else {
|
||||
const entry = (this[WRITEENTRY] = new read_entry_js_1.ReadEntry(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] = undefined;
|
||||
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]() {
|
||||
queueMicrotask(() => this.emit('close'));
|
||||
}
|
||||
[PROCESSENTRY](entry) {
|
||||
let go = true;
|
||||
if (!entry) {
|
||||
this[READENTRY] = undefined;
|
||||
go = false;
|
||||
}
|
||||
else if (Array.isArray(entry)) {
|
||||
const [ev, ...args] = entry;
|
||||
this.emit(ev, ...args);
|
||||
}
|
||||
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];
|
||||
/* c8 ignore start */
|
||||
if (!entry) {
|
||||
throw new Error('attempt to consume body without entry??');
|
||||
}
|
||||
const br = entry.blockRemain ?? 0;
|
||||
/* c8 ignore stop */
|
||||
const c = br >= chunk.length && position === 0 ?
|
||||
chunk
|
||||
: chunk.subarray(position, position + br);
|
||||
entry.write(c);
|
||||
if (!entry.blockRemain) {
|
||||
this[STATE] = 'header';
|
||||
this[WRITEENTRY] = undefined;
|
||||
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] && entry) {
|
||||
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_js_1.Pax.parse(this[META], this[EX], false);
|
||||
break;
|
||||
case 'GlobalExtendedHeader':
|
||||
this[GEX] = pax_js_1.Pax.parse(this[META], this[GEX], true);
|
||||
break;
|
||||
case 'NextFileHasLongPath':
|
||||
case 'OldGnuLongPath': {
|
||||
const ex = this[EX] ?? Object.create(null);
|
||||
this[EX] = ex;
|
||||
ex.path = this[META].replace(/\0.*/, '');
|
||||
break;
|
||||
}
|
||||
case 'NextFileHasLongLinkpath': {
|
||||
const ex = this[EX] || Object.create(null);
|
||||
this[EX] = ex;
|
||||
ex.linkpath = this[META].replace(/\0.*/, '');
|
||||
break;
|
||||
}
|
||||
/* c8 ignore start */
|
||||
default:
|
||||
throw new Error('unknown meta: ' + entry.type);
|
||||
/* c8 ignore stop */
|
||||
}
|
||||
}
|
||||
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, encoding, cb) {
|
||||
if (typeof encoding === 'function') {
|
||||
cb = encoding;
|
||||
encoding = undefined;
|
||||
}
|
||||
if (typeof chunk === 'string') {
|
||||
chunk = Buffer.from(chunk,
|
||||
/* c8 ignore next */
|
||||
typeof encoding === 'string' ? encoding : 'utf8');
|
||||
}
|
||||
if (this[ABORTED]) {
|
||||
/* c8 ignore next */
|
||||
cb?.();
|
||||
return false;
|
||||
}
|
||||
// first write, might be gzipped, zstd, or brotli compressed
|
||||
const needSniff = this[UNZIP] === undefined ||
|
||||
(this.brotli === undefined && this[UNZIP] === false);
|
||||
if (needSniff && chunk) {
|
||||
if (this[BUFFER]) {
|
||||
chunk = Buffer.concat([this[BUFFER], chunk]);
|
||||
this[BUFFER] = undefined;
|
||||
}
|
||||
if (chunk.length < ZIP_HEADER_LEN) {
|
||||
this[BUFFER] = chunk;
|
||||
/* c8 ignore next */
|
||||
cb?.();
|
||||
return true;
|
||||
}
|
||||
// look for gzip header
|
||||
for (let i = 0; this[UNZIP] === undefined && i < gzipHeader.length; i++) {
|
||||
if (chunk[i] !== gzipHeader[i]) {
|
||||
this[UNZIP] = false;
|
||||
}
|
||||
}
|
||||
// look for zstd header if gzip header not found
|
||||
let isZstd = false;
|
||||
if (this[UNZIP] === false && this.zstd !== false) {
|
||||
isZstd = true;
|
||||
for (let i = 0; i < zstdHeader.length; i++) {
|
||||
if (chunk[i] !== zstdHeader[i]) {
|
||||
isZstd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const maybeBrotli = this.brotli === undefined && !isZstd;
|
||||
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;
|
||||
/* c8 ignore next */
|
||||
cb?.();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if it's tar, it's pretty reliably not brotli, chances of
|
||||
// that happening are astronomical.
|
||||
try {
|
||||
new header_js_1.Header(chunk.subarray(0, 512));
|
||||
this.brotli = false;
|
||||
}
|
||||
catch (_) {
|
||||
this.brotli = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this[UNZIP] === undefined ||
|
||||
(this[UNZIP] === false && (this.brotli || isZstd))) {
|
||||
const ended = this[ENDED];
|
||||
this[ENDED] = false;
|
||||
this[UNZIP] =
|
||||
this[UNZIP] === undefined ? new minizlib_1.Unzip({})
|
||||
: isZstd ? new minizlib_1.ZstdDecompress({})
|
||||
: new minizlib_1.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;
|
||||
cb?.();
|
||||
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'));
|
||||
}
|
||||
/* c8 ignore next */
|
||||
cb?.();
|
||||
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] && chunk) {
|
||||
this[BUFFERCONCAT](chunk);
|
||||
}
|
||||
else if (!chunk && !this[BUFFER]) {
|
||||
this[MAYBEEND]();
|
||||
}
|
||||
else if (chunk) {
|
||||
this[CONSUMING] = true;
|
||||
if (this[BUFFER]) {
|
||||
this[BUFFERCONCAT](chunk);
|
||||
const c = this[BUFFER];
|
||||
this[BUFFER] = undefined;
|
||||
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] = undefined;
|
||||
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;
|
||||
/* c8 ignore start */
|
||||
default:
|
||||
throw new Error('invalid state: ' + this[STATE]);
|
||||
/* c8 ignore stop */
|
||||
}
|
||||
}
|
||||
if (position < length) {
|
||||
if (this[BUFFER]) {
|
||||
this[BUFFER] = Buffer.concat([
|
||||
chunk.subarray(position),
|
||||
this[BUFFER],
|
||||
]);
|
||||
}
|
||||
else {
|
||||
this[BUFFER] = chunk.subarray(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
end(chunk, encoding, cb) {
|
||||
if (typeof chunk === 'function') {
|
||||
cb = chunk;
|
||||
encoding = undefined;
|
||||
chunk = undefined;
|
||||
}
|
||||
if (typeof encoding === 'function') {
|
||||
cb = encoding;
|
||||
encoding = undefined;
|
||||
}
|
||||
if (typeof chunk === 'string') {
|
||||
chunk = Buffer.from(chunk, encoding);
|
||||
}
|
||||
if (cb)
|
||||
this.once('finish', cb);
|
||||
if (!this[ABORTED]) {
|
||||
if (this[UNZIP]) {
|
||||
/* c8 ignore start */
|
||||
if (chunk)
|
||||
this[UNZIP].write(chunk);
|
||||
/* c8 ignore stop */
|
||||
this[UNZIP].end();
|
||||
}
|
||||
else {
|
||||
this[ENDED] = true;
|
||||
if (this.brotli === undefined || this.zstd === undefined)
|
||||
chunk = chunk || Buffer.alloc(0);
|
||||
if (chunk)
|
||||
this.write(chunk);
|
||||
this[MAYBEEND]();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
exports.Parser = Parser;
|
||||
//# sourceMappingURL=parse.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
-11
@@ -1,11 +0,0 @@
|
||||
export type Reservation = {
|
||||
paths: string[];
|
||||
dirs: Set<string>;
|
||||
};
|
||||
export type Handler = (clear: () => void) => void;
|
||||
export declare class PathReservations {
|
||||
#private;
|
||||
reserve(paths: string[], fn: Handler): boolean;
|
||||
check(fn: Handler): boolean;
|
||||
}
|
||||
//# sourceMappingURL=path-reservations.d.ts.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"path-reservations.d.ts","sourceRoot":"","sources":["../../src/path-reservations.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;AAmBjD,qBAAa,gBAAgB;;IAY3B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO;IAgEpC,KAAK,CAAC,EAAE,EAAE,OAAO;CA8ElB"}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user