terser 5.16.4 → 5.16.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.16.5
4
+
5
+ - Correctly handle AST transform functions that mutate children arrays
6
+ - Don't mutate the options object passed to Terser (#1342)
7
+ - Do not treat BigInt like a number
8
+
3
9
  ## v5.16.4
4
10
 
5
11
  - Keep `(defaultArg = undefined) => ...`, because default args don't count for function length
package/bin/terser.mjs ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ import "../tools/exit.cjs";
6
+
7
+ import fs from "fs";
8
+ import path from "path";
9
+ import program from "commander";
10
+
11
+ import { run_cli } from "../lib/cli.js";
12
+
13
+ const packageJson = {
14
+ name: "terser",
15
+ version: "experimental module CLI"
16
+ };
17
+
18
+ run_cli({ program, packageJson, fs, path }).catch((error) => {
19
+ console.error(error);
20
+ process.exitCode = 1;
21
+ });
@@ -101,36 +101,20 @@ function return_null() { return null; }
101
101
 
102
102
  var MAP = (function() {
103
103
  function MAP(a, tw, allow_splicing = true) {
104
- // Loop but try not to build a new array
104
+ const new_a = [];
105
+
105
106
  for (let i = 0; i < a.length; ++i) {
106
107
  let item = a[i];
107
108
  let ret = item.transform(tw, allow_splicing);
108
109
 
109
- if (ret !== item) {
110
- const a1 = a.slice(0, i);
111
-
112
- // Looks like something was transformed. Change the loop.
113
- if (ret instanceof AST_Node) {
114
- a1.push(ret);
115
- } else if (ret instanceof Splice) {
116
- a1.push(...ret.v);
117
- }
118
-
119
- while ((item = a[++i])) {
120
- const ret = item.transform(tw, true);
121
-
122
- if (ret instanceof AST_Node) {
123
- a1.push(ret);
124
- } else if (ret instanceof Splice) {
125
- a1.push(...ret.v);
126
- }
127
- }
128
-
129
- return a1;
110
+ if (ret instanceof AST_Node) {
111
+ new_a.push(ret);
112
+ } else if (ret instanceof Splice) {
113
+ new_a.push(...ret.v);
130
114
  }
131
115
  }
132
116
 
133
- return a;
117
+ return new_a;
134
118
  }
135
119
 
136
120
  MAP.splice = function(val) { return new Splice(val); };
@@ -13367,7 +13351,7 @@ const unary_side_effects = makePredicate("delete ++ --");
13367
13351
  def_is_number(AST_Number, return_true);
13368
13352
  const unary = makePredicate("+ - ~ ++ --");
13369
13353
  def_is_number(AST_Unary, function() {
13370
- return unary.has(this.operator);
13354
+ return unary.has(this.operator) && !(this.expression instanceof AST_BigInt);
13371
13355
  });
13372
13356
  const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
13373
13357
  def_is_number(AST_Binary, function(compressor) {
@@ -30011,10 +29995,13 @@ async function minify(files, options, _fs_module) {
30011
29995
  if (options.format.spidermonkey) {
30012
29996
  result.ast = toplevel.to_mozilla_ast();
30013
29997
  }
29998
+ let format_options;
30014
29999
  if (!HOP(options.format, "code") || options.format.code) {
30015
- if (!options.format.ast) {
30000
+ // Make a shallow copy so that we can modify without mutating the user's input.
30001
+ format_options = {...options.format};
30002
+ if (!format_options.ast) {
30016
30003
  // Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
30017
- options.format._destroy_ast = true;
30004
+ format_options._destroy_ast = true;
30018
30005
 
30019
30006
  walk(toplevel, node => {
30020
30007
  if (node instanceof AST_Scope) {
@@ -30034,17 +30021,17 @@ async function minify(files, options, _fs_module) {
30034
30021
  if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
30035
30022
  throw new Error("original source content unavailable");
30036
30023
  }
30037
- options.format.source_map = await SourceMap({
30024
+ format_options.source_map = await SourceMap({
30038
30025
  file: options.sourceMap.filename,
30039
30026
  orig: options.sourceMap.content,
30040
30027
  root: options.sourceMap.root,
30041
30028
  files: options.sourceMap.includeSources ? files : null,
30042
30029
  });
30043
30030
  }
30044
- delete options.format.ast;
30045
- delete options.format.code;
30046
- delete options.format.spidermonkey;
30047
- var stream = OutputStream(options.format);
30031
+ delete format_options.ast;
30032
+ delete format_options.code;
30033
+ delete format_options.spidermonkey;
30034
+ var stream = OutputStream(format_options);
30048
30035
  toplevel.print(stream);
30049
30036
  result.code = stream.get();
30050
30037
  if (options.sourceMap) {
@@ -30052,7 +30039,7 @@ async function minify(files, options, _fs_module) {
30052
30039
  configurable: true,
30053
30040
  enumerable: true,
30054
30041
  get() {
30055
- const map = options.format.source_map.getEncoded();
30042
+ const map = format_options.source_map.getEncoded();
30056
30043
  return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
30057
30044
  },
30058
30045
  set(value) {
@@ -30062,7 +30049,7 @@ async function minify(files, options, _fs_module) {
30062
30049
  });
30063
30050
  }
30064
30051
  });
30065
- result.decoded_map = options.format.source_map.getDecoded();
30052
+ result.decoded_map = format_options.source_map.getDecoded();
30066
30053
  if (options.sourceMap.url == "inline") {
30067
30054
  var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
30068
30055
  result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
@@ -30077,8 +30064,8 @@ async function minify(files, options, _fs_module) {
30077
30064
  options.nameCache.props = cache_to_json(options.mangle.properties.cache);
30078
30065
  }
30079
30066
  }
30080
- if (options.format && options.format.source_map) {
30081
- options.format.source_map.destroy();
30067
+ if (format_options && format_options.source_map) {
30068
+ format_options.source_map.destroy();
30082
30069
  }
30083
30070
  if (timings) {
30084
30071
  timings.end = Date.now();
@@ -45,6 +45,7 @@ import {
45
45
  AST_Array,
46
46
  AST_Arrow,
47
47
  AST_Assign,
48
+ AST_BigInt,
48
49
  AST_Binary,
49
50
  AST_Block,
50
51
  AST_BlockStatement,
@@ -171,7 +172,7 @@ export const unary_side_effects = makePredicate("delete ++ --");
171
172
  def_is_number(AST_Number, return_true);
172
173
  const unary = makePredicate("+ - ~ ++ --");
173
174
  def_is_number(AST_Unary, function() {
174
- return unary.has(this.operator);
175
+ return unary.has(this.operator) && !(this.expression instanceof AST_BigInt);
175
176
  });
176
177
  const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
177
178
  def_is_number(AST_Binary, function(compressor) {
package/lib/minify.js CHANGED
@@ -280,10 +280,13 @@ async function minify(files, options, _fs_module) {
280
280
  if (options.format.spidermonkey) {
281
281
  result.ast = toplevel.to_mozilla_ast();
282
282
  }
283
+ let format_options;
283
284
  if (!HOP(options.format, "code") || options.format.code) {
284
- if (!options.format.ast) {
285
+ // Make a shallow copy so that we can modify without mutating the user's input.
286
+ format_options = {...options.format};
287
+ if (!format_options.ast) {
285
288
  // Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
286
- options.format._destroy_ast = true;
289
+ format_options._destroy_ast = true;
287
290
 
288
291
  walk(toplevel, node => {
289
292
  if (node instanceof AST_Scope) {
@@ -303,17 +306,17 @@ async function minify(files, options, _fs_module) {
303
306
  if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
304
307
  throw new Error("original source content unavailable");
305
308
  }
306
- options.format.source_map = await SourceMap({
309
+ format_options.source_map = await SourceMap({
307
310
  file: options.sourceMap.filename,
308
311
  orig: options.sourceMap.content,
309
312
  root: options.sourceMap.root,
310
313
  files: options.sourceMap.includeSources ? files : null,
311
314
  });
312
315
  }
313
- delete options.format.ast;
314
- delete options.format.code;
315
- delete options.format.spidermonkey;
316
- var stream = OutputStream(options.format);
316
+ delete format_options.ast;
317
+ delete format_options.code;
318
+ delete format_options.spidermonkey;
319
+ var stream = OutputStream(format_options);
317
320
  toplevel.print(stream);
318
321
  result.code = stream.get();
319
322
  if (options.sourceMap) {
@@ -321,7 +324,7 @@ async function minify(files, options, _fs_module) {
321
324
  configurable: true,
322
325
  enumerable: true,
323
326
  get() {
324
- const map = options.format.source_map.getEncoded();
327
+ const map = format_options.source_map.getEncoded();
325
328
  return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
326
329
  },
327
330
  set(value) {
@@ -331,7 +334,7 @@ async function minify(files, options, _fs_module) {
331
334
  });
332
335
  }
333
336
  });
334
- result.decoded_map = options.format.source_map.getDecoded();
337
+ result.decoded_map = format_options.source_map.getDecoded();
335
338
  if (options.sourceMap.url == "inline") {
336
339
  var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
337
340
  result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
@@ -346,8 +349,8 @@ async function minify(files, options, _fs_module) {
346
349
  options.nameCache.props = cache_to_json(options.mangle.properties.cache);
347
350
  }
348
351
  }
349
- if (options.format && options.format.source_map) {
350
- options.format.source_map.destroy();
352
+ if (format_options && format_options.source_map) {
353
+ format_options.source_map.destroy();
351
354
  }
352
355
  if (timings) {
353
356
  timings.end = Date.now();
@@ -99,36 +99,20 @@ function return_null() { return null; }
99
99
 
100
100
  var MAP = (function() {
101
101
  function MAP(a, tw, allow_splicing = true) {
102
- // Loop but try not to build a new array
102
+ const new_a = [];
103
+
103
104
  for (let i = 0; i < a.length; ++i) {
104
105
  let item = a[i];
105
106
  let ret = item.transform(tw, allow_splicing);
106
107
 
107
- if (ret !== item) {
108
- const a1 = a.slice(0, i);
109
-
110
- // Looks like something was transformed. Change the loop.
111
- if (ret instanceof AST_Node) {
112
- a1.push(ret);
113
- } else if (ret instanceof Splice) {
114
- a1.push(...ret.v);
115
- }
116
-
117
- while ((item = a[++i])) {
118
- const ret = item.transform(tw, true);
119
-
120
- if (ret instanceof AST_Node) {
121
- a1.push(ret);
122
- } else if (ret instanceof Splice) {
123
- a1.push(...ret.v);
124
- }
125
- }
126
-
127
- return a1;
108
+ if (ret instanceof AST_Node) {
109
+ new_a.push(ret);
110
+ } else if (ret instanceof Splice) {
111
+ new_a.push(...ret.v);
128
112
  }
129
113
  }
130
114
 
131
- return a;
115
+ return new_a;
132
116
  }
133
117
 
134
118
  MAP.splice = function(val) { return new Splice(val); };
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "homepage": "https://terser.org",
5
5
  "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
6
6
  "license": "BSD-2-Clause",
7
- "version": "5.16.4",
7
+ "version": "5.16.5",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },