11import * as fs from 'fs-extra' ;
22import { npm , yarn } from 'global-dirs' ;
33import path from 'path' ;
4+ import type { Entry , ZipFile as YauzlZipFile } from 'yauzl' ;
45import { ZipFile as YazlZipFile } from 'yazl' ;
56import type { CommandContext } from './types' ;
67import { translateOptions } from './utils' ;
@@ -61,14 +62,85 @@ function basename(fn: string): string | undefined {
6162 return m ?. [ 1 ] ;
6263}
6364
65+ function createOutputZip ( output : string ) {
66+ fs . ensureDirSync ( path . dirname ( output ) ) ;
67+ const zipfile = new YazlZipFile ( ) ;
68+ const writePromise = new Promise < void > ( ( resolve , reject ) => {
69+ zipfile . outputStream . on ( 'error' , reject ) ;
70+ zipfile . outputStream . pipe ( fs . createWriteStream ( output ) ) . on ( 'close' , ( ) => {
71+ resolve ( void 0 ) ;
72+ } ) ;
73+ } ) ;
74+ return { zipfile, writePromise } ;
75+ }
76+
77+ async function addBundlePatch (
78+ zipfile : YazlZipFile ,
79+ entry : Entry ,
80+ nextZipfile : YauzlZipFile ,
81+ diffFn : Diff ,
82+ originSource : Buffer | undefined ,
83+ ) {
84+ const newSource = await readEntry ( entry , nextZipfile ) ;
85+ zipfile . addBuffer (
86+ diffFn ( originSource , newSource ) ,
87+ `${ entry . fileName } .patch` ,
88+ zipOptionsForPatchEntry ( ) ,
89+ ) ;
90+ }
91+
92+ async function addFileFromZipEntry (
93+ zipfile : YazlZipFile ,
94+ entry : Entry ,
95+ nextZipfile : YauzlZipFile ,
96+ ) {
97+ const entryPrefix = await readEntryPrefix (
98+ entry ,
99+ nextZipfile ,
100+ ZIP_ENTRY_SNIFF_BYTES ,
101+ ) ;
102+ await new Promise < void > ( ( resolve , reject ) => {
103+ nextZipfile . openReadStream ( entry , ( err , readStream ) => {
104+ if ( err ) {
105+ return reject ( err ) ;
106+ }
107+ if ( ! readStream ) {
108+ return reject ( new Error ( `Unable to read zip entry: ${ entry . fileName } ` ) ) ;
109+ }
110+ zipfile . addReadStream (
111+ readStream ,
112+ entry . fileName ,
113+ zipOptionsForPayloadEntry ( entry . fileName , entryPrefix ) ,
114+ ) ;
115+ readStream . on ( 'error' , reject ) ;
116+ readStream . on ( 'end' , ( ) => {
117+ resolve ( void 0 ) ;
118+ } ) ;
119+ } ) ;
120+ } ) ;
121+ }
122+
123+ function finishDiffZip (
124+ zipfile : YazlZipFile ,
125+ writePromise : Promise < void > ,
126+ manifest : Record < string , unknown > ,
127+ ) {
128+ const diffManifest = Buffer . from ( JSON . stringify ( manifest ) ) ;
129+ zipfile . addBuffer (
130+ diffManifest ,
131+ '__diff.json' ,
132+ zipOptionsForManifestEntry ( diffManifest . length ) ,
133+ ) ;
134+ zipfile . end ( ) ;
135+ return writePromise ;
136+ }
137+
64138async function diffFromPPK (
65139 origin : string ,
66140 next : string ,
67141 output : string ,
68142 diffFn : Diff ,
69143) {
70- fs . ensureDirSync ( path . dirname ( output ) ) ;
71-
72144 const originEntries : EntryMap = { } ;
73145 const originMap : CrcMap = { } ;
74146
@@ -93,14 +165,7 @@ async function diffFromPPK(
93165
94166 const copies : CopyMap = { } ;
95167
96- const zipfile = new YazlZipFile ( ) ;
97-
98- const writePromise = new Promise < void > ( ( resolve , reject ) => {
99- zipfile . outputStream . on ( 'error' , reject ) ;
100- zipfile . outputStream . pipe ( fs . createWriteStream ( output ) ) . on ( 'close' , ( ) => {
101- resolve ( void 0 ) ;
102- } ) ;
103- } ) ;
168+ const { zipfile, writePromise } = createOutputZip ( output ) ;
104169
105170 const addedEntry : Record < string , true > = { } ;
106171
@@ -128,15 +193,7 @@ async function diffFromPPK(
128193 addEntry ( entry . fileName ) ;
129194 }
130195 } else if ( isPPKBundleFileName ( entry . fileName ) ) {
131- //console.log('Found bundle');
132- const newSource = await readEntry ( entry , nextZipfile ) ;
133- //console.log('Begin diff');
134- zipfile . addBuffer (
135- diffFn ( originSource , newSource ) ,
136- `${ entry . fileName } .patch` ,
137- zipOptionsForPatchEntry ( ) ,
138- ) ;
139- //console.log('End diff');
196+ await addBundlePatch ( zipfile , entry , nextZipfile , diffFn , originSource ) ;
140197 } else {
141198 // If same file.
142199 const originEntry = originEntries [ entry . fileName ] ;
@@ -162,33 +219,7 @@ async function diffFromPPK(
162219 addEntry ( basePath ) ;
163220 }
164221
165- const entryPrefix = await readEntryPrefix (
166- entry ,
167- nextZipfile ,
168- ZIP_ENTRY_SNIFF_BYTES ,
169- ) ;
170- await new Promise < void > ( ( resolve , reject ) => {
171- nextZipfile . openReadStream ( entry , ( err , readStream ) => {
172- if ( err ) {
173- return reject ( err ) ;
174- }
175- if ( ! readStream ) {
176- return reject (
177- new Error ( `Unable to read zip entry: ${ entry . fileName } ` ) ,
178- ) ;
179- }
180- zipfile . addReadStream (
181- readStream ,
182- entry . fileName ,
183- zipOptionsForPayloadEntry ( entry . fileName , entryPrefix ) ,
184- ) ;
185- readStream . on ( 'error' , reject ) ;
186- readStream . on ( 'end' , ( ) => {
187- //console.log('add finished');
188- resolve ( void 0 ) ;
189- } ) ;
190- } ) ;
191- } ) ;
222+ await addFileFromZipEntry ( zipfile , entry , nextZipfile ) ;
192223 }
193224 } ) ;
194225
@@ -201,15 +232,7 @@ async function diffFromPPK(
201232 }
202233 }
203234
204- //console.log({copies, deletes});
205- const diffManifest = Buffer . from ( JSON . stringify ( { copies, deletes } ) ) ;
206- zipfile . addBuffer (
207- diffManifest ,
208- '__diff.json' ,
209- zipOptionsForManifestEntry ( diffManifest . length ) ,
210- ) ;
211- zipfile . end ( ) ;
212- await writePromise ;
235+ await finishDiffZip ( zipfile , writePromise , { copies, deletes } ) ;
213236}
214237
215238async function diffFromPackage (
@@ -220,8 +243,6 @@ async function diffFromPackage(
220243 originBundleName : string ,
221244 transformPackagePath : ( v : string ) => string | undefined = ( v : string ) => v ,
222245) {
223- fs . ensureDirSync ( path . dirname ( output ) ) ;
224-
225246 const originEntries : Record < string , number > = { } ;
226247 const originMap : CrcMap = { } ;
227248
@@ -259,29 +280,14 @@ async function diffFromPackage(
259280
260281 const copies : CopyMap = { } ;
261282
262- const zipfile = new YazlZipFile ( ) ;
263-
264- const writePromise = new Promise < void > ( ( resolve , reject ) => {
265- zipfile . outputStream . on ( 'error' , reject ) ;
266- zipfile . outputStream . pipe ( fs . createWriteStream ( output ) ) . on ( 'close' , ( ) => {
267- resolve ( void 0 ) ;
268- } ) ;
269- } ) ;
283+ const { zipfile, writePromise } = createOutputZip ( output ) ;
270284
271285 await enumZipEntries ( next , async ( entry , nextZipfile ) => {
272286 if ( / \/ $ / . test ( entry . fileName ) ) {
273287 // Directory
274288 zipfile . addEmptyDirectory ( entry . fileName ) ;
275289 } else if ( isPPKBundleFileName ( entry . fileName ) ) {
276- //console.log('Found bundle');
277- const newSource = await readEntry ( entry , nextZipfile ) ;
278- //console.log('Begin diff');
279- zipfile . addBuffer (
280- diffFn ( originSource , newSource ) ,
281- `${ entry . fileName } .patch` ,
282- zipOptionsForPatchEntry ( ) ,
283- ) ;
284- //console.log('End diff');
290+ await addBundlePatch ( zipfile , entry , nextZipfile , diffFn , originSource ) ;
285291 } else {
286292 // If same file.
287293 if ( originEntries [ entry . fileName ] === entry . crc32 ) {
@@ -299,44 +305,11 @@ async function diffFromPackage(
299305 return ;
300306 }
301307
302- const entryPrefix = await readEntryPrefix (
303- entry ,
304- nextZipfile ,
305- ZIP_ENTRY_SNIFF_BYTES ,
306- ) ;
307- await new Promise < void > ( ( resolve , reject ) => {
308- nextZipfile . openReadStream ( entry , ( err , readStream ) => {
309- if ( err ) {
310- return reject ( err ) ;
311- }
312- if ( ! readStream ) {
313- return reject (
314- new Error ( `Unable to read zip entry: ${ entry . fileName } ` ) ,
315- ) ;
316- }
317- zipfile . addReadStream (
318- readStream ,
319- entry . fileName ,
320- zipOptionsForPayloadEntry ( entry . fileName , entryPrefix ) ,
321- ) ;
322- readStream . on ( 'error' , reject ) ;
323- readStream . on ( 'end' , ( ) => {
324- //console.log('add finished');
325- resolve ( void 0 ) ;
326- } ) ;
327- } ) ;
328- } ) ;
308+ await addFileFromZipEntry ( zipfile , entry , nextZipfile ) ;
329309 }
330310 } ) ;
331311
332- const diffManifest = Buffer . from ( JSON . stringify ( { copies, copiesCrc } ) ) ;
333- zipfile . addBuffer (
334- diffManifest ,
335- '__diff.json' ,
336- zipOptionsForManifestEntry ( diffManifest . length ) ,
337- ) ;
338- zipfile . end ( ) ;
339- await writePromise ;
312+ await finishDiffZip ( zipfile , writePromise , { copies, copiesCrc } ) ;
340313}
341314
342315type DiffCommandOptions = {
0 commit comments