Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
replace.js227 linesDownload Raw Back to commonjs
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3    return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.replace = void 0;
7// tar -r
8const fs_minipass_1 = require("@isaacs/fs-minipass");
9const node_fs_1 = __importDefault(require("node:fs"));
10const node_path_1 = __importDefault(require("node:path"));
11const header_js_1 = require("./header.js");
12const list_js_1 = require("./list.js");
13const make_command_js_1 = require("./make-command.js");
14const options_js_1 = require("./options.js");
15const pack_js_1 = require("./pack.js");
16// starting at the head of the file, read a Header
17// If the checksum is invalid, that's our position to start writing
18// If it is, jump forward by the specified size (round up to 512)
19// and try again.
20// Write the new Pack stream starting there.
21const replaceSync = (opt, files) => {
22    const p = new pack_js_1.PackSync(opt);
23    let threw = true;
24    let fd;
25    let position;
26    try {
27        try {
28            fd = node_fs_1.default.openSync(opt.file, 'r+');
29        }
30        catch (er) {
31            if (er?.code === 'ENOENT') {
32                fd = node_fs_1.default.openSync(opt.file, 'w+');
33            }
34            else {
35                throw er;
36            }
37        }
38        const st = node_fs_1.default.fstatSync(fd);
39        const headBuf = Buffer.alloc(512);
40        POSITION: for (position = 0; position < st.size; position += 512) {
41            for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) {
42                bytes = node_fs_1.default.readSync(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos);
43                if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) {
44                    throw new Error('cannot append to compressed archives');
45                }
46                if (!bytes) {
47                    break POSITION;
48                }
49            }
50            const h = new header_js_1.Header(headBuf);
51            if (!h.cksumValid) {
52                break;
53            }
54            const entryBlockSize = 512 * Math.ceil((h.size || 0) / 512);
55            if (position + entryBlockSize + 512 > st.size) {
56                break;
57            }
58            // the 512 for the header we just parsed will be added as well
59            // also jump ahead all the blocks for the body
60            position += entryBlockSize;
61            if (opt.mtimeCache && h.mtime) {
62                opt.mtimeCache.set(String(h.path), h.mtime);
63            }
64        }
65        threw = false;
66        streamSync(opt, p, position, fd, files);
67    }
68    finally {
69        if (threw) {
70            try {
71                node_fs_1.default.closeSync(fd);
72            }
73            catch { }
74        }
75    }
76};
77const streamSync = (opt, p, position, fd, files) => {
78    const stream = new fs_minipass_1.WriteStreamSync(opt.file, {
79        fd: fd,
80        start: position,
81    });
82    p.pipe(stream);
83    addFilesSync(p, files);
84};
85const replaceAsync = (opt, files) => {
86    files = Array.from(files);
87    const p = new pack_js_1.Pack(opt);
88    const getPos = (fd, size, cb_) => {
89        const cb = (er, pos) => {
90            if (er) {
91                node_fs_1.default.close(fd, _ => cb_(er));
92            }
93            else {
94                cb_(null, pos);
95            }
96        };
97        let position = 0;
98        if (size === 0) {
99            return cb(null, 0);
100        }
101        let bufPos = 0;
102        const headBuf = Buffer.alloc(512);
103        const onread = (er, bytes) => {
104            if (er || bytes === undefined) {
105                return cb(er);
106            }
107            bufPos += bytes;
108            if (bufPos < 512 && bytes) {
109                return node_fs_1.default.read(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos, onread);
110            }
111            if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) {
112                return cb(new Error('cannot append to compressed archives'));
113            }
114            // truncated header
115            if (bufPos < 512) {
116                return cb(null, position);
117            }
118            const h = new header_js_1.Header(headBuf);
119            if (!h.cksumValid) {
120                return cb(null, position);
121            }
122            /* c8 ignore next */
123            const entryBlockSize = 512 * Math.ceil((h.size ?? 0) / 512);
124            if (position + entryBlockSize + 512 > size) {
125                return cb(null, position);
126            }
127            position += entryBlockSize + 512;
128            if (position >= size) {
129                return cb(null, position);
130            }
131            if (opt.mtimeCache && h.mtime) {
132                opt.mtimeCache.set(String(h.path), h.mtime);
133            }
134            bufPos = 0;
135            node_fs_1.default.read(fd, headBuf, 0, 512, position, onread);
136        };
137        node_fs_1.default.read(fd, headBuf, 0, 512, position, onread);
138    };
139    const promise = new Promise((resolve, reject) => {
140        p.on('error', reject);
141        let flag = 'r+';
142        const onopen = (er, fd) => {
143            if (er && er.code === 'ENOENT' && flag === 'r+') {
144                flag = 'w+';
145                return node_fs_1.default.open(opt.file, flag, onopen);
146            }
147            if (er || !fd) {
148                return reject(er);
149            }
150            node_fs_1.default.fstat(fd, (er, st) => {
151                if (er) {
152                    return node_fs_1.default.close(fd, () => reject(er));
153                }
154                getPos(fd, st.size, (er, position) => {
155                    if (er) {
156                        return reject(er);
157                    }
158                    const stream = new fs_minipass_1.WriteStream(opt.file, {
159                        fd: fd,
160                        start: position,
161                    });
162                    p.pipe(stream);
163                    stream.on('error', reject);
164                    stream.on('close', resolve);
165                    addFilesAsync(p, files);
166                });
167            });
168        };
169        node_fs_1.default.open(opt.file, flag, onopen);
170    });
171    return promise;
172};
173const addFilesSync = (p, files) => {
174    files.forEach(file => {
175        if (file.charAt(0) === '@') {
176            (0, list_js_1.list)({
177                file: node_path_1.default.resolve(p.cwd, file.slice(1)),
178                sync: true,
179                noResume: true,
180                onReadEntry: entry => p.add(entry),
181            });
182        }
183        else {
184            p.add(file);
185        }
186    });
187    p.end();
188};
189const addFilesAsync = async (p, files) => {
190    for (const file of files) {
191        if (file.charAt(0) === '@') {
192            await (0, list_js_1.list)({
193                file: node_path_1.default.resolve(String(p.cwd), file.slice(1)),
194                noResume: true,
195                onReadEntry: entry => p.add(entry),
196            });
197        }
198        else {
199            p.add(file);
200        }
201    }
202    p.end();
203};
204exports.replace = (0, make_command_js_1.makeCommand)(replaceSync, replaceAsync,
205/* c8 ignore start */
206() => {
207    throw new TypeError('file is required');
208}, () => {
209    throw new TypeError('file is required');
210},
211/* c8 ignore stop */
212(opt, entries) => {
213    if (!(0, options_js_1.isFile)(opt)) {
214        throw new TypeError('file is required');
215    }
216    if (opt.gzip ||
217        opt.brotli ||
218        opt.zstd ||
219        opt.file.endsWith('.br') ||
220        opt.file.endsWith('.tbr')) {
221        throw new TypeError('cannot append to compressed archives');
222    }
223    if (!entries?.length) {
224        throw new TypeError('no paths specified to add/replace');
225    }
226});
227//# sourceMappingURL=replace.js.map
codekingpro/portable-devtools · Team Ai