@@ -8,9 +8,6 @@ import Piscina from 'piscina';
8
8
import micromatch from 'micromatch' ;
9
9
import { loadConfig } from './configLoader.js' ;
10
10
import { uploadSnapshot } from './uploadSnapshot.js' ;
11
- import { calculateSizeDiff } from './sizeDiff.js' ;
12
- import { renderMarkdownReportContent , renderMarkdownReport } from './renderMarkdownReport.js' ;
13
- import { fetchSnapshot } from './fetchSnapshot.js' ;
14
11
15
12
/**
16
13
* @typedef {import('./sizeDiff.js').SizeSnapshot } SizeSnapshot
@@ -114,215 +111,6 @@ async function run(argv) {
114
111
}
115
112
}
116
113
117
- /**
118
- * Resolves a file path that can be relative or absolute
119
- * @param {string } filePath - The file path to resolve
120
- * @returns {string } The resolved absolute path
121
- */
122
- function resolveFilePath ( filePath ) {
123
- if ( path . isAbsolute ( filePath ) ) {
124
- return filePath ;
125
- }
126
- return path . resolve ( rootDir , filePath ) ;
127
- }
128
-
129
- /**
130
- * Checks if a string is a URL
131
- * @param {string } str - The string to check
132
- * @returns {boolean } Whether the string is a URL
133
- */
134
- function isUrl ( str ) {
135
- try {
136
- // eslint-disable-next-line no-new
137
- new URL ( str ) ;
138
- return true ;
139
- } catch {
140
- return false ;
141
- }
142
- }
143
-
144
- /**
145
- * Loads a snapshot from a URL (http:, https:, or file: scheme)
146
- * @param {string } source - The source URL
147
- * @returns {Promise<SizeSnapshot> } The loaded snapshot
148
- */
149
- async function loadSnapshot ( source ) {
150
- // Check if it's a valid URL
151
- if ( ! isUrl ( source ) ) {
152
- throw new Error ( `Invalid URL: ${ source } . Use file:, http:, or https: schemes.` ) ;
153
- }
154
-
155
- if ( source . startsWith ( 'file:' ) ) {
156
- // Handle file: URL
157
- // Remove file: prefix and handle the rest as a file path
158
- // For file:///absolute/path
159
- let filePath = source . substring ( source . indexOf ( 'file:' ) + 5 ) ;
160
-
161
- // Remove leading slashes for absolute paths on this machine
162
- while (
163
- filePath . startsWith ( '/' ) &&
164
- ! path . isAbsolute ( filePath . substring ( 1 ) ) &&
165
- filePath . length > 1
166
- ) {
167
- filePath = filePath . substring ( 1 ) ;
168
- }
169
-
170
- // Now resolve the path
171
- filePath = resolveFilePath ( filePath ) ;
172
-
173
- try {
174
- return await fse . readJSON ( filePath ) ;
175
- } catch ( /** @type {any } */ error ) {
176
- throw new Error ( `Failed to read snapshot from ${ filePath } : ${ error . message } ` ) ;
177
- }
178
- }
179
-
180
- // HTTP/HTTPS URL - fetch directly
181
- const response = await fetch ( source ) ;
182
- if ( ! response . ok ) {
183
- throw new Error ( `Failed to fetch snapshot from ${ source } : ${ response . statusText } ` ) ;
184
- }
185
- const body = await response . json ( ) ;
186
- return body ;
187
- }
188
-
189
- /**
190
- * Handler for the diff command
191
- * @param {DiffCommandArgs } argv - Command line arguments
192
- */
193
- async function diffHandler ( argv ) {
194
- const { base, head = 'file:./size-snapshot.json' , output, reportUrl } = argv ;
195
-
196
- if ( ! base ) {
197
- console . error ( 'The --base option is required' ) ;
198
- process . exit ( 1 ) ;
199
- }
200
-
201
- try {
202
- // Load snapshots
203
- // eslint-disable-next-line no-console
204
- console . log ( `Loading base snapshot from ${ base } ...` ) ;
205
- const baseSnapshot = await loadSnapshot ( base ) ;
206
-
207
- // eslint-disable-next-line no-console
208
- console . log ( `Loading head snapshot from ${ head } ...` ) ;
209
- const headSnapshot = await loadSnapshot ( head ) ;
210
-
211
- // Calculate diff
212
- const comparison = calculateSizeDiff ( baseSnapshot , headSnapshot ) ;
213
-
214
- // Output
215
- if ( output === 'markdown' ) {
216
- // Generate markdown with optional report URL
217
- let markdownContent = renderMarkdownReportContent ( comparison ) ;
218
-
219
- // Add report URL if provided
220
- if ( reportUrl ) {
221
- markdownContent += `\n\n[Details of bundle changes](${ reportUrl } )` ;
222
- }
223
-
224
- // eslint-disable-next-line no-console
225
- console . log ( markdownContent ) ;
226
- } else {
227
- // Default JSON output
228
- // eslint-disable-next-line no-console
229
- console . log ( JSON . stringify ( comparison , null , 2 ) ) ;
230
- }
231
- } catch ( /** @type {any } */ error ) {
232
- console . error ( `Error: ${ error . message } ` ) ;
233
- process . exit ( 1 ) ;
234
- }
235
- }
236
-
237
- /**
238
- * Fetches GitHub PR information
239
- * @param {string } owner - Repository owner
240
- * @param {string } repo - Repository name
241
- * @param {number } prNumber - Pull request number
242
- * @returns {Promise<PrInfo> } PR information
243
- */
244
- async function fetchPrInfo ( owner , repo , prNumber ) {
245
- const url = `https://api.github.com/repos/${ owner } /${ repo } /pulls/${ prNumber } ` ;
246
-
247
- try {
248
- // eslint-disable-next-line no-console
249
- console . log ( `Fetching PR info from ${ url } ...` ) ;
250
- const response = await fetch ( url ) ;
251
-
252
- if ( ! response . ok ) {
253
- throw new Error ( `GitHub API request failed: ${ response . statusText } (${ response . status } )` ) ;
254
- }
255
-
256
- return await response . json ( ) ;
257
- } catch ( /** @type {any } */ error ) {
258
- console . error ( `Failed to fetch PR info: ${ error . message } ` ) ;
259
- throw error ;
260
- }
261
- }
262
-
263
- /**
264
- * Handler for the pr command
265
- * @param {PrCommandArgs } argv - Command line arguments
266
- */
267
- async function prHandler ( argv ) {
268
- const { prNumber, circleci, output } = argv ;
269
-
270
- try {
271
- // Load the config to get the repository information
272
- const config = await loadConfig ( rootDir ) ;
273
-
274
- if ( ! config . upload ) {
275
- throw new Error (
276
- 'Upload is not configured. Please enable it in your bundle-size-checker config.' ,
277
- ) ;
278
- }
279
-
280
- // Extract owner and repo from repository config
281
- const [ owner , repo ] = config . upload . repo . split ( '/' ) ;
282
-
283
- if ( ! owner || ! repo ) {
284
- throw new Error (
285
- `Invalid repository format in config: ${ config . upload . repo } . Expected format: "owner/repo"` ,
286
- ) ;
287
- }
288
-
289
- // Fetch PR information from GitHub
290
- const prInfo = await fetchPrInfo ( owner , repo , prNumber ) ;
291
-
292
- // Generate the report
293
- // eslint-disable-next-line no-console
294
- console . log ( 'Generating bundle size report...' ) ;
295
- const report = await renderMarkdownReport ( prInfo , circleci ) ;
296
-
297
- // Output
298
- if ( output === 'markdown' ) {
299
- // eslint-disable-next-line no-console
300
- console . log ( report ) ;
301
- } else {
302
- // For JSON we need to load the snapshots and calculate differences
303
- const baseCommit = prInfo . base . sha ;
304
- const prCommit = prInfo . head . sha ;
305
-
306
- // eslint-disable-next-line no-console
307
- console . log ( `Fetching base snapshot for commit ${ baseCommit } ...` ) ;
308
- // eslint-disable-next-line no-console
309
- console . log ( `Fetching PR snapshot for commit ${ prCommit } ...` ) ;
310
-
311
- const [ baseSnapshot , prSnapshot ] = await Promise . all ( [
312
- fetchSnapshot ( config . upload . repo , baseCommit ) . catch ( ( ) => ( { } ) ) ,
313
- fetchSnapshot ( config . upload . repo , prCommit ) . catch ( ( ) => ( { } ) ) ,
314
- ] ) ;
315
-
316
- const comparison = calculateSizeDiff ( baseSnapshot , prSnapshot ) ;
317
- // eslint-disable-next-line no-console
318
- console . log ( JSON . stringify ( comparison , null , 2 ) ) ;
319
- }
320
- } catch ( /** @type {any } */ error ) {
321
- console . error ( `Error: ${ error . message } ` ) ;
322
- process . exit ( 1 ) ;
323
- }
324
- }
325
-
326
114
yargs ( process . argv . slice ( 2 ) )
327
115
// @ts -expect-error
328
116
. command ( {
@@ -365,62 +153,6 @@ yargs(process.argv.slice(2))
365
153
} ,
366
154
handler : run ,
367
155
} )
368
- // @ts -expect-error
369
- . command ( {
370
- command : 'diff' ,
371
- describe : 'Compare two bundle size snapshots' ,
372
- builder : ( cmdYargs ) => {
373
- return cmdYargs
374
- . option ( 'base' , {
375
- describe : 'Base snapshot URL (file:, http:, or https: scheme)' ,
376
- type : 'string' ,
377
- demandOption : true ,
378
- } )
379
- . option ( 'head' , {
380
- describe :
381
- 'Head snapshot URL (file:, http:, or https: scheme), defaults to file:./size-snapshot.json' ,
382
- type : 'string' ,
383
- default : 'file:./size-snapshot.json' ,
384
- } )
385
- . option ( 'output' , {
386
- alias : 'o' ,
387
- describe : 'Output format (json or markdown)' ,
388
- type : 'string' ,
389
- choices : [ 'json' , 'markdown' ] ,
390
- default : 'json' ,
391
- } )
392
- . option ( 'reportUrl' , {
393
- describe : 'URL to the detailed report (optional)' ,
394
- type : 'string' ,
395
- } ) ;
396
- } ,
397
- handler : diffHandler ,
398
- } )
399
- // @ts -expect-error
400
- . command ( {
401
- command : 'pr <prNumber>' ,
402
- describe : 'Generate a bundle size report for a GitHub pull request' ,
403
- builder : ( cmdYargs ) => {
404
- return cmdYargs
405
- . positional ( 'prNumber' , {
406
- describe : 'GitHub pull request number' ,
407
- type : 'number' ,
408
- demandOption : true ,
409
- } )
410
- . option ( 'output' , {
411
- alias : 'o' ,
412
- describe : 'Output format (json or markdown)' ,
413
- type : 'string' ,
414
- choices : [ 'json' , 'markdown' ] ,
415
- default : 'markdown' , // Default to markdown for PR reports
416
- } )
417
- . option ( 'circleci' , {
418
- describe : 'CircleCI build number for the report URL (optional)' ,
419
- type : 'string' ,
420
- } ) ;
421
- } ,
422
- handler : prHandler ,
423
- } )
424
156
. help ( )
425
157
. strict ( true )
426
158
. version ( false )
0 commit comments