|
1 | 1 | 'use strict'
|
2 | 2 |
|
3 | 3 | const fs = require('./wrapped-fs')
|
| 4 | +const os = require('os') |
4 | 5 | const path = require('path')
|
5 |
| -const tmp = require('tmp-promise') |
6 |
| -const UINT64 = require('cuint').UINT64 |
| 6 | +const { promisify } = require('util') |
| 7 | +const stream = require('stream') |
7 | 8 |
|
8 |
| -const UINT32_MAX = 4294967295 |
| 9 | +const UINT32_MAX = 2 ** 32 - 1 |
| 10 | + |
| 11 | +const pipeline = promisify(stream.pipeline) |
9 | 12 |
|
10 | 13 | class Filesystem {
|
11 | 14 | constructor (src) {
|
12 | 15 | this.src = path.resolve(src)
|
13 | 16 | this.header = { files: {} }
|
14 |
| - this.offset = UINT64(0) |
| 17 | + this.offset = BigInt(0) |
15 | 18 | }
|
16 | 19 |
|
17 | 20 | searchNodeFromDirectory (p) {
|
@@ -57,48 +60,36 @@ class Filesystem {
|
57 | 60 | return Promise.resolve()
|
58 | 61 | }
|
59 | 62 |
|
60 |
| - const handler = (resolve, reject) => { |
61 |
| - const size = file.transformed ? file.transformed.stat.size : file.stat.size |
62 |
| - |
63 |
| - // JavaScript can not precisely present integers >= UINT32_MAX. |
64 |
| - if (size > UINT32_MAX) { |
65 |
| - const error = new Error(`${p}: file size can not be larger than 4.2GB`) |
66 |
| - if (reject) { |
67 |
| - return reject(error) |
68 |
| - } else { |
69 |
| - throw error |
70 |
| - } |
71 |
| - } |
| 63 | + let size |
72 | 64 |
|
73 |
| - node.size = size |
74 |
| - node.offset = this.offset.toString() |
75 |
| - if (process.platform !== 'win32' && (file.stat.mode & 0o100)) { |
76 |
| - node.executable = true |
| 65 | + const transformed = options.transform && options.transform(p) |
| 66 | + if (transformed) { |
| 67 | + const tmpdir = await fs.mkdtemp(path.join(os.tmpdir(), 'asar-')) |
| 68 | + const tmpfile = path.join(tmpdir, path.basename(p)) |
| 69 | + const out = fs.createWriteStream(tmpfile) |
| 70 | + const readStream = fs.createReadStream(p) |
| 71 | + |
| 72 | + await pipeline(readStream, transformed, out) |
| 73 | + file.transformed = { |
| 74 | + path: tmpfile, |
| 75 | + stat: await fs.lstat(tmpfile) |
77 | 76 | }
|
78 |
| - this.offset.add(UINT64(size)) |
| 77 | + size = file.transformed.stat.size |
| 78 | + } else { |
| 79 | + size = file.stat.size |
| 80 | + } |
79 | 81 |
|
80 |
| - return resolve ? resolve() : Promise.resolve() |
| 82 | + // JavaScript cannot precisely present integers >= UINT32_MAX. |
| 83 | + if (size > UINT32_MAX) { |
| 84 | + throw new Error(`${p}: file size can not be larger than 4.2GB`) |
81 | 85 | }
|
82 | 86 |
|
83 |
| - const transformed = options.transform && options.transform(p) |
84 |
| - if (transformed) { |
85 |
| - const tmpfile = await tmp.file() |
86 |
| - return new Promise((resolve, reject) => { |
87 |
| - const out = fs.createWriteStream(tmpfile.path) |
88 |
| - const stream = fs.createReadStream(p) |
89 |
| - |
90 |
| - stream.pipe(transformed).pipe(out) |
91 |
| - return out.on('close', async () => { |
92 |
| - file.transformed = { |
93 |
| - path: tmpfile.path, |
94 |
| - stat: await fs.lstat(tmpfile.path) |
95 |
| - } |
96 |
| - return handler(resolve, reject) |
97 |
| - }) |
98 |
| - }) |
99 |
| - } else { |
100 |
| - return handler() |
| 87 | + node.size = size |
| 88 | + node.offset = this.offset.toString() |
| 89 | + if (process.platform !== 'win32' && (file.stat.mode & 0o100)) { |
| 90 | + node.executable = true |
101 | 91 | }
|
| 92 | + this.offset += BigInt(size) |
102 | 93 | }
|
103 | 94 |
|
104 | 95 | insertLink (p) {
|
|
0 commit comments