@node-cli/bundlesize 2.1.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,100 +1,38 @@
1
1
  #!/usr/bin/env node
2
+ /* istanbul ignore file */ import { STDOUT, reportStats } from "./utilities.js";
2
3
  import { Logger } from "@node-cli/logger";
3
- import bytes from "bytes";
4
4
  import { config } from "./parse.js";
5
5
  import fs from "fs-extra";
6
- import { glob } from "glob";
7
- import { gzipSizeFromFileSync } from "gzip-size";
8
- import path from "node:path";
9
- import { statSync } from "node:fs";
10
- const STDOUT = "stdout";
11
- const CWD = process.cwd();
12
6
  const flags = config.flags;
13
- const configurationFile = path.join(CWD, flags.configuration);
14
- const outputFile = flags.output === "" || flags.output === undefined ? STDOUT : path.join(CWD, flags.output);
15
- const prefix = flags.prefix || Date.now().toString();
16
- const currentResults = {};
17
7
  const log = new Logger({
18
8
  boring: flags.boring
19
9
  });
20
- let failed = false;
21
- if (flags.configuration === "") {
22
- log.error("Please provide a configuration file");
23
- process.exit(0);
24
- }
25
- if (fs.existsSync(configurationFile) === false) {
26
- log.error("Invalid or missing configuration file!");
27
- process.exit(0);
28
- }
29
10
  try {
30
- const configuration = await import(configurationFile).then((m)=>m.default);
31
- for (const artifact of configuration){
32
- const rootPath = artifact.path.startsWith("/") ? "" : path.dirname(configurationFile);
33
- const artifactPath = path.dirname(artifact.path);
34
- const globReplace = "+([a-zA-Z0-9])";
35
- const hasHash = artifact.path.includes("<hash>");
36
- /**
37
- * if the artifact.path has the string <hash> in it,
38
- * then we need to check for other characters:
39
- * - Double stars ** are allowed.
40
- * - Single stars * are not allowed.
41
- */ if (hasHash && /(?<!\*)\*(?!\*)/.test(artifact.path)) {
42
- log.error(`Invalid path: ${artifact.path}.`);
43
- log.error("Single stars (*) are not allowed when using the special keyword <hash>");
44
- process.exit(1);
45
- }
46
- const fileGlob = path.join(rootPath, artifact.path.replace("<hash>", globReplace));
47
- const files = glob.sync(fileGlob);
48
- if (files.length === 0) {
49
- log.error(`File not found: ${fileGlob}`);
50
- process.exit(1);
51
- }
52
- if (files.length > 1 && hasHash) {
53
- log.error(`Multiple files found for: ${artifact.path}.`);
54
- log.error("Please use a more specific path when using the special keyword <hash>.");
55
- process.exit(1);
56
- }
57
- for (const file of files){
58
- const fileSize = statSync(file).size;
59
- const fileSizeGzip = gzipSizeFromFileSync(file);
60
- const passed = fileSizeGzip < bytes(artifact.limit);
61
- if (passed === false) {
62
- failed = true;
63
- }
64
- let index = hasHash ? artifact.path : path.join(artifactPath, path.basename(file));
65
- currentResults[index] = {
66
- fileSize,
67
- fileSizeGzip,
68
- limit: artifact.limit,
69
- passed
70
- };
71
- }
11
+ const result = await reportStats({
12
+ flags
13
+ });
14
+ if (result.exitMessage !== "") {
15
+ log.error(result.exitMessage);
16
+ process.exit(result.exitCode);
72
17
  }
73
- let existingResults = {};
74
- if (outputFile !== STDOUT) {
18
+ if (result.outputFile === STDOUT) {
19
+ log.info(`Configuration: ${flags.configuration}`);
20
+ log.info(`Output: ${result.outputFile}`);
21
+ log.info(`Output prefix: ${result.prefix}`);
22
+ log.log(result.data);
23
+ } else {
75
24
  try {
76
- existingResults = fs.readJsonSync(outputFile);
77
- } catch {
78
- // nothing to declare officer
25
+ fs.outputJsonSync(result.outputFile, result.data, {
26
+ spaces: 2
27
+ });
28
+ } catch (error) {
29
+ log.error(`Failed to write to file: ${error.message}`);
30
+ process.exit(1);
79
31
  }
80
32
  }
81
- existingResults[prefix] = currentResults;
82
- if (outputFile !== STDOUT) {
83
- fs.outputJsonSync(outputFile, existingResults, {
84
- spaces: 2
85
- });
86
- }
87
- if (outputFile === STDOUT) {
88
- log.info(`Configuration: ${flags.configuration}`);
89
- log.info(`Output: ${outputFile}`);
90
- log.info(`Output prefix: ${prefix}`);
91
- log.log(`\n${JSON.stringify(currentResults, undefined, 2)}`);
92
- }
33
+ process.exit(result.exitCode);
93
34
  } catch (error) {
94
35
  log.error(error);
95
- process.exit(0);
96
- }
97
- if (failed && flags.silent === false) {
98
36
  process.exit(1);
99
37
  }
100
38
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bundlesize.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Logger } from \"@node-cli/logger\";\nimport bytes from \"bytes\";\nimport { config } from \"./parse.js\";\nimport fs from \"fs-extra\";\nimport { glob } from \"glob\";\nimport { gzipSizeFromFileSync } from \"gzip-size\";\nimport path from \"node:path\";\nimport { statSync } from \"node:fs\";\n\nconst STDOUT = \"stdout\";\nconst CWD = process.cwd();\n\nconst flags = config.flags;\nconst configurationFile = path.join(CWD, flags.configuration);\nconst outputFile =\n\tflags.output === \"\" || flags.output === undefined\n\t\t? STDOUT\n\t\t: path.join(CWD, flags.output);\nconst prefix = flags.prefix || Date.now().toString();\nconst currentResults = {};\nconst log = new Logger({\n\tboring: flags.boring,\n});\n\nlet failed = false;\n\nif (flags.configuration === \"\") {\n\tlog.error(\"Please provide a configuration file\");\n\tprocess.exit(0);\n}\n\nif (fs.existsSync(configurationFile) === false) {\n\tlog.error(\"Invalid or missing configuration file!\");\n\tprocess.exit(0);\n}\n\ntry {\n\tconst configuration = await import(configurationFile).then((m) => m.default);\n\n\tfor (const artifact of configuration) {\n\t\tconst rootPath = artifact.path.startsWith(\"/\")\n\t\t\t? \"\"\n\t\t\t: path.dirname(configurationFile);\n\t\tconst artifactPath = path.dirname(artifact.path);\n\t\tconst globReplace = \"+([a-zA-Z0-9])\";\n\t\tconst hasHash = artifact.path.includes(\"<hash>\");\n\n\t\t/**\n\t\t * if the artifact.path has the string <hash> in it,\n\t\t * then we need to check for other characters:\n\t\t * - Double stars ** are allowed.\n\t\t * - Single stars * are not allowed.\n\t\t */\n\t\tif (hasHash && /(?<!\\*)\\*(?!\\*)/.test(artifact.path)) {\n\t\t\tlog.error(`Invalid path: ${artifact.path}.`);\n\t\t\tlog.error(\n\t\t\t\t\"Single stars (*) are not allowed when using the special keyword <hash>\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst fileGlob = path.join(\n\t\t\trootPath,\n\t\t\tartifact.path.replace(\"<hash>\", globReplace),\n\t\t);\n\t\tconst files = glob.sync(fileGlob);\n\n\t\tif (files.length === 0) {\n\t\t\tlog.error(`File not found: ${fileGlob}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (files.length > 1 && hasHash) {\n\t\t\tlog.error(`Multiple files found for: ${artifact.path}.`);\n\t\t\tlog.error(\n\t\t\t\t\"Please use a more specific path when using the special keyword <hash>.\",\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tfor (const file of files) {\n\t\t\tconst fileSize = statSync(file).size;\n\t\t\tconst fileSizeGzip = gzipSizeFromFileSync(file);\n\t\t\tconst passed = fileSizeGzip < bytes(artifact.limit);\n\n\t\t\tif (passed === false) {\n\t\t\t\tfailed = true;\n\t\t\t}\n\t\t\tlet index = hasHash\n\t\t\t\t? artifact.path\n\t\t\t\t: path.join(artifactPath, path.basename(file));\n\n\t\t\tcurrentResults[index] = {\n\t\t\t\tfileSize,\n\t\t\t\tfileSizeGzip,\n\t\t\t\tlimit: artifact.limit,\n\t\t\t\tpassed,\n\t\t\t};\n\t\t}\n\t}\n\n\tlet existingResults = {};\n\tif (outputFile !== STDOUT) {\n\t\ttry {\n\t\t\texistingResults = fs.readJsonSync(outputFile);\n\t\t} catch {\n\t\t\t// nothing to declare officer\n\t\t}\n\t}\n\texistingResults[prefix] = currentResults;\n\tif (outputFile !== STDOUT) {\n\t\tfs.outputJsonSync(outputFile, existingResults, { spaces: 2 });\n\t}\n\n\tif (outputFile === STDOUT) {\n\t\tlog.info(`Configuration: ${flags.configuration}`);\n\t\tlog.info(`Output: ${outputFile}`);\n\t\tlog.info(`Output prefix: ${prefix}`);\n\t\tlog.log(`\\n${JSON.stringify(currentResults, undefined, 2)}`);\n\t}\n} catch (error) {\n\tlog.error(error);\n\tprocess.exit(0);\n}\n\nif (failed && flags.silent === false) {\n\tprocess.exit(1);\n}\n"],"names":["Logger","bytes","config","fs","glob","gzipSizeFromFileSync","path","statSync","STDOUT","CWD","process","cwd","flags","configurationFile","join","configuration","outputFile","output","undefined","prefix","Date","now","toString","currentResults","log","boring","failed","error","exit","existsSync","then","m","default","artifact","rootPath","startsWith","dirname","artifactPath","globReplace","hasHash","includes","test","fileGlob","replace","files","sync","length","file","fileSize","size","fileSizeGzip","passed","limit","index","basename","existingResults","readJsonSync","outputJsonSync","spaces","info","JSON","stringify","silent"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/bundlesize.ts"],"sourcesContent":["#!/usr/bin/env node\n/* istanbul ignore file */\n\nimport { STDOUT, reportStats } from \"./utilities.js\";\n\nimport { Logger } from \"@node-cli/logger\";\nimport { config } from \"./parse.js\";\nimport fs from \"fs-extra\";\n\nconst flags = config.flags;\n\nconst log = new Logger({\n\tboring: flags.boring,\n});\n\ntry {\n\tconst result = await reportStats({ flags });\n\n\tif (result.exitMessage !== \"\") {\n\t\tlog.error(result.exitMessage);\n\t\tprocess.exit(result.exitCode);\n\t}\n\n\tif (result.outputFile === STDOUT) {\n\t\tlog.info(`Configuration: ${flags.configuration}`);\n\t\tlog.info(`Output: ${result.outputFile}`);\n\t\tlog.info(`Output prefix: ${result.prefix}`);\n\t\tlog.log(result.data);\n\t} else {\n\t\ttry {\n\t\t\tfs.outputJsonSync(result.outputFile, result.data, { spaces: 2 });\n\t\t} catch (error) {\n\t\t\tlog.error(`Failed to write to file: ${error.message}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\tprocess.exit(result.exitCode);\n} catch (error) {\n\tlog.error(error);\n\tprocess.exit(1);\n}\n"],"names":["STDOUT","reportStats","Logger","config","fs","flags","log","boring","result","exitMessage","error","process","exit","exitCode","outputFile","info","configuration","prefix","data","outputJsonSync","spaces","message"],"mappings":";AACA,wBAAwB,GAExB,SAASA,MAAM,EAAEC,WAAW,QAAQ,iBAAiB;AAErD,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,MAAM,QAAQ,aAAa;AACpC,OAAOC,QAAQ,WAAW;AAE1B,MAAMC,QAAQF,OAAOE,KAAK;AAE1B,MAAMC,MAAM,IAAIJ,OAAO;IACtBK,QAAQF,MAAME,MAAM;AACrB;AAEA,IAAI;IACH,MAAMC,SAAS,MAAMP,YAAY;QAAEI;IAAM;IAEzC,IAAIG,OAAOC,WAAW,KAAK,IAAI;QAC9BH,IAAII,KAAK,CAACF,OAAOC,WAAW;QAC5BE,QAAQC,IAAI,CAACJ,OAAOK,QAAQ;IAC7B;IAEA,IAAIL,OAAOM,UAAU,KAAKd,QAAQ;QACjCM,IAAIS,IAAI,CAAC,CAAC,eAAe,EAAEV,MAAMW,aAAa,CAAC,CAAC;QAChDV,IAAIS,IAAI,CAAC,CAAC,QAAQ,EAAEP,OAAOM,UAAU,CAAC,CAAC;QACvCR,IAAIS,IAAI,CAAC,CAAC,eAAe,EAAEP,OAAOS,MAAM,CAAC,CAAC;QAC1CX,IAAIA,GAAG,CAACE,OAAOU,IAAI;IACpB,OAAO;QACN,IAAI;YACHd,GAAGe,cAAc,CAACX,OAAOM,UAAU,EAAEN,OAAOU,IAAI,EAAE;gBAAEE,QAAQ;YAAE;QAC/D,EAAE,OAAOV,OAAO;YACfJ,IAAII,KAAK,CAAC,CAAC,yBAAyB,EAAEA,MAAMW,OAAO,CAAC,CAAC;YACrDV,QAAQC,IAAI,CAAC;QACd;IACD;IACAD,QAAQC,IAAI,CAACJ,OAAOK,QAAQ;AAC7B,EAAE,OAAOH,OAAO;IACfJ,IAAII,KAAK,CAACA;IACVC,QAAQC,IAAI,CAAC;AACd"}
package/dist/defaults.js CHANGED
@@ -1,4 +1,4 @@
1
- export const defaultFlags = {
1
+ /* istanbul ignore file */ export const defaultFlags = {
2
2
  boring: false,
3
3
  configuration: "",
4
4
  silent: false
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/defaults.ts"],"sourcesContent":["export const defaultFlags = {\n\tboring: false,\n\tconfiguration: \"\",\n\tsilent: false,\n};\n"],"names":["defaultFlags","boring","configuration","silent"],"mappings":"AAAA,OAAO,MAAMA,eAAe;IAC3BC,QAAQ;IACRC,eAAe;IACfC,QAAQ;AACT,EAAE"}
1
+ {"version":3,"sources":["../src/defaults.ts"],"sourcesContent":["/* istanbul ignore file */\n\nexport const defaultFlags = {\n\tboring: false,\n\tconfiguration: \"\",\n\tsilent: false,\n};\n"],"names":["defaultFlags","boring","configuration","silent"],"mappings":"AAAA,wBAAwB,GAExB,OAAO,MAAMA,eAAe;IAC3BC,QAAQ;IACRC,eAAe;IACfC,QAAQ;AACT,EAAE"}
package/dist/index.d.ts CHANGED
@@ -5,3 +5,4 @@
5
5
  export * from "./bundlesize";
6
6
  export * from "./defaults";
7
7
  export * from "./parse";
8
+ export * from "./utilities";
@@ -0,0 +1,13 @@
1
+ type ReportStats = {
2
+ pass: boolean;
3
+ exitCode: number;
4
+ exitMessage: string;
5
+ outputFile: string;
6
+ prefix: string;
7
+ data: Record<string, unknown>;
8
+ };
9
+ export declare const STDOUT = "stdout";
10
+ export declare const reportStats: ({ flags }: {
11
+ flags: any;
12
+ }) => Promise<ReportStats>;
13
+ export {};
@@ -0,0 +1,96 @@
1
+ import bytes from "bytes";
2
+ import fs from "fs-extra";
3
+ import { glob } from "glob";
4
+ import { gzipSizeFromFileSync } from "gzip-size";
5
+ import path from "node:path";
6
+ import { statSync } from "node:fs";
7
+ export const STDOUT = "stdout";
8
+ const CWD = process.cwd();
9
+ export const reportStats = async ({ flags })=>{
10
+ const result = {
11
+ pass: true,
12
+ exitCode: 0,
13
+ exitMessage: "",
14
+ outputFile: "",
15
+ prefix: "",
16
+ data: {}
17
+ };
18
+ let failed = false;
19
+ const configurationFile = flags.configuration.startsWith("/") ? flags.configuration : path.join(CWD, flags.configuration);
20
+ const outputFile = flags.output === "" || flags.output === undefined ? STDOUT : path.join(CWD, flags.output);
21
+ const prefix = flags.prefix || "0.0.0";
22
+ const currentResults = {};
23
+ if (flags.configuration === "") {
24
+ result.exitMessage = "Please provide a configuration file";
25
+ result.exitCode = 1;
26
+ return result;
27
+ }
28
+ if (fs.existsSync(configurationFile) === false) {
29
+ result.exitMessage = "Invalid or missing configuration file!";
30
+ result.exitCode = 1;
31
+ return result;
32
+ }
33
+ const configuration = await import(configurationFile).then((m)=>m.default);
34
+ for (const artifact of configuration){
35
+ const rootPath = artifact.path.startsWith("/") ? "" : path.dirname(configurationFile);
36
+ const artifactPath = path.dirname(artifact.path);
37
+ const globReplace = "+([a-zA-Z0-9_-])";
38
+ const hasHash = artifact.path.includes("<hash>");
39
+ /**
40
+ * if the artifact.path has the string <hash> in it,
41
+ * then we need to check for other characters:
42
+ * - Double stars ** are allowed.
43
+ * - Single stars * are not allowed.
44
+ */ if (hasHash && /(?<!\*)\*(?!\*)/.test(artifact.path)) {
45
+ result.exitCode = 1;
46
+ result.exitMessage = `Invalid path: ${artifact.path}.\nSingle stars (*) are not allowed when using the special keyword <hash>`;
47
+ return result;
48
+ }
49
+ const fileGlob = path.join(rootPath, artifact.path.replace("<hash>", globReplace));
50
+ const files = glob.sync(fileGlob);
51
+ if (files.length === 0) {
52
+ result.exitCode = 1;
53
+ result.exitMessage = `File not found: ${fileGlob}`;
54
+ return result;
55
+ }
56
+ if (files.length > 1 && hasHash) {
57
+ result.exitCode = 1;
58
+ result.exitMessage = `Multiple files found for: ${artifact.path}.\nPlease use a more specific path when using the special keyword <hash>.`;
59
+ return result;
60
+ }
61
+ for (const file of files){
62
+ const fileSize = statSync(file).size;
63
+ const fileSizeGzip = gzipSizeFromFileSync(file);
64
+ const passed = fileSizeGzip < bytes(artifact.limit);
65
+ if (passed === false) {
66
+ result.pass = false;
67
+ failed = true;
68
+ }
69
+ let index = hasHash ? artifact.path : path.join(artifactPath, path.basename(file));
70
+ currentResults[index] = {
71
+ fileSize,
72
+ fileSizeGzip,
73
+ limit: artifact.limit,
74
+ passed
75
+ };
76
+ }
77
+ }
78
+ let existingResults = {};
79
+ if (outputFile !== STDOUT) {
80
+ try {
81
+ existingResults = fs.readJsonSync(outputFile);
82
+ } catch {
83
+ /**
84
+ * There are no existing results, so we can ignore this error,
85
+ * and simply write the current results to the output file.
86
+ */ }
87
+ }
88
+ existingResults[prefix] = currentResults;
89
+ result.prefix = prefix;
90
+ result.outputFile = outputFile;
91
+ result.exitCode = failed && flags.silent === false ? 1 : 0;
92
+ result.data = existingResults;
93
+ return result;
94
+ };
95
+
96
+ //# sourceMappingURL=utilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utilities.ts"],"sourcesContent":["import bytes from \"bytes\";\nimport fs from \"fs-extra\";\nimport { glob } from \"glob\";\nimport { gzipSizeFromFileSync } from \"gzip-size\";\nimport path from \"node:path\";\nimport { statSync } from \"node:fs\";\n\ntype Artifact = {\n\tpath: string;\n\tlimit: string;\n};\n\ntype ReportStats = {\n\tpass: boolean;\n\texitCode: number;\n\texitMessage: string;\n\toutputFile: string;\n\tprefix: string;\n\tdata: Record<string, unknown>;\n};\n\nexport const STDOUT = \"stdout\";\nconst CWD = process.cwd();\n\nexport const reportStats = async ({ flags }): Promise<ReportStats> => {\n\tconst result = {\n\t\tpass: true,\n\t\texitCode: 0,\n\t\texitMessage: \"\",\n\t\toutputFile: \"\",\n\t\tprefix: \"\",\n\t\tdata: {},\n\t};\n\tlet failed = false;\n\tconst configurationFile = flags.configuration.startsWith(\"/\")\n\t\t? flags.configuration\n\t\t: path.join(CWD, flags.configuration);\n\n\tconst outputFile =\n\t\tflags.output === \"\" || flags.output === undefined\n\t\t\t? STDOUT\n\t\t\t: path.join(CWD, flags.output);\n\tconst prefix = flags.prefix || \"0.0.0\";\n\tconst currentResults = {};\n\n\tif (flags.configuration === \"\") {\n\t\tresult.exitMessage = \"Please provide a configuration file\";\n\t\tresult.exitCode = 1;\n\t\treturn result;\n\t}\n\n\tif (fs.existsSync(configurationFile) === false) {\n\t\tresult.exitMessage = \"Invalid or missing configuration file!\";\n\t\tresult.exitCode = 1;\n\t\treturn result;\n\t}\n\tconst configuration: Artifact[] = await import(configurationFile).then(\n\t\t(m) => m.default,\n\t);\n\n\tfor (const artifact of configuration) {\n\t\tconst rootPath = artifact.path.startsWith(\"/\")\n\t\t\t? \"\"\n\t\t\t: path.dirname(configurationFile);\n\t\tconst artifactPath = path.dirname(artifact.path);\n\t\tconst globReplace = \"+([a-zA-Z0-9_-])\";\n\t\tconst hasHash = artifact.path.includes(\"<hash>\");\n\n\t\t/**\n\t\t * if the artifact.path has the string <hash> in it,\n\t\t * then we need to check for other characters:\n\t\t * - Double stars ** are allowed.\n\t\t * - Single stars * are not allowed.\n\t\t */\n\t\tif (hasHash && /(?<!\\*)\\*(?!\\*)/.test(artifact.path)) {\n\t\t\tresult.exitCode = 1;\n\t\t\tresult.exitMessage = `Invalid path: ${artifact.path}.\\nSingle stars (*) are not allowed when using the special keyword <hash>`;\n\t\t\treturn result;\n\t\t}\n\n\t\tconst fileGlob = path.join(\n\t\t\trootPath,\n\t\t\tartifact.path.replace(\"<hash>\", globReplace),\n\t\t);\n\t\tconst files = glob.sync(fileGlob);\n\n\t\tif (files.length === 0) {\n\t\t\tresult.exitCode = 1;\n\t\t\tresult.exitMessage = `File not found: ${fileGlob}`;\n\t\t\treturn result;\n\t\t}\n\n\t\tif (files.length > 1 && hasHash) {\n\t\t\tresult.exitCode = 1;\n\t\t\tresult.exitMessage = `Multiple files found for: ${artifact.path}.\\nPlease use a more specific path when using the special keyword <hash>.`;\n\t\t\treturn result;\n\t\t}\n\n\t\tfor (const file of files) {\n\t\t\tconst fileSize = statSync(file).size;\n\t\t\tconst fileSizeGzip = gzipSizeFromFileSync(file);\n\t\t\tconst passed = fileSizeGzip < bytes(artifact.limit);\n\n\t\t\tif (passed === false) {\n\t\t\t\tresult.pass = false;\n\t\t\t\tfailed = true;\n\t\t\t}\n\t\t\tlet index = hasHash\n\t\t\t\t? artifact.path\n\t\t\t\t: path.join(artifactPath, path.basename(file));\n\n\t\t\tcurrentResults[index] = {\n\t\t\t\tfileSize,\n\t\t\t\tfileSizeGzip,\n\t\t\t\tlimit: artifact.limit,\n\t\t\t\tpassed,\n\t\t\t};\n\t\t}\n\t}\n\n\tlet existingResults = {};\n\tif (outputFile !== STDOUT) {\n\t\ttry {\n\t\t\texistingResults = fs.readJsonSync(outputFile);\n\t\t} catch {\n\t\t\t/**\n\t\t\t * There are no existing results, so we can ignore this error,\n\t\t\t * and simply write the current results to the output file.\n\t\t\t */\n\t\t}\n\t}\n\texistingResults[prefix] = currentResults;\n\n\tresult.prefix = prefix;\n\tresult.outputFile = outputFile;\n\tresult.exitCode = failed && flags.silent === false ? 1 : 0;\n\tresult.data = existingResults;\n\treturn result;\n};\n"],"names":["bytes","fs","glob","gzipSizeFromFileSync","path","statSync","STDOUT","CWD","process","cwd","reportStats","flags","result","pass","exitCode","exitMessage","outputFile","prefix","data","failed","configurationFile","configuration","startsWith","join","output","undefined","currentResults","existsSync","then","m","default","artifact","rootPath","dirname","artifactPath","globReplace","hasHash","includes","test","fileGlob","replace","files","sync","length","file","fileSize","size","fileSizeGzip","passed","limit","index","basename","existingResults","readJsonSync","silent"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-cli/bundlesize",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "description": "Simple CLI tool that checks file(s) size and report if limits have been reached",
@@ -19,7 +19,11 @@
19
19
  "build:types": "tsc",
20
20
  "clean": "rimraf dist types coverage",
21
21
  "lint": "prettier --write \"src/*.ts\" && eslint --fix \"src/*.ts\"",
22
- "stats": "bundlesize -c bundlesize.config.js",
22
+ "stats": "bundlesize -c bundlesize.config.js -p \"$npm_package_version\"",
23
+ "stats:diff": "bundlesize -t diff",
24
+ "test": "cross-env-shell NODE_OPTIONS=--experimental-vm-modules jest",
25
+ "test:coverage": "npm run test -- --coverage",
26
+ "test:watch": "npm run test -- --watch",
23
27
  "watch": "swc --watch --out-dir dist src"
24
28
  },
25
29
  "dependencies": {
@@ -33,5 +37,5 @@
33
37
  "publishConfig": {
34
38
  "access": "public"
35
39
  },
36
- "gitHead": "feee529dafbd7b992827d3e749300cda51c8c8b1"
40
+ "gitHead": "e7e1567e048693bb1665e6402291df2d16cfe69e"
37
41
  }