Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F87781301
cli.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Oct 14, 22:22
Size
18 KB
Mime Type
text/x-java
Expires
Wed, Oct 16, 22:22 (2 d)
Engine
blob
Format
Raw Data
Handle
21653030
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
cli.js
View Options
import
{
minify
,
_default_options
}
from
"../main.js"
;
import
{
parse
}
from
"./parse.js"
;
import
{
AST_Assign
,
AST_Array
,
AST_Constant
,
AST_Node
,
AST_PropAccess
,
AST_RegExp
,
AST_Sequence
,
AST_Symbol
,
AST_Token
,
walk
}
from
"./ast.js"
;
import
{
OutputStream
}
from
"./output.js"
;
export
async
function
run_cli
({
program
,
packageJson
,
fs
,
path
})
{
const
skip_keys
=
new
Set
([
"cname"
,
"parent_scope"
,
"scope"
,
"uses_eval"
,
"uses_with"
]);
var
files
=
{};
var
options
=
{
compress
:
false
,
mangle
:
false
};
const
default_options
=
await
_default_options
();
program
.
version
(
packageJson
.
name
+
" "
+
packageJson
.
version
);
program
.
parseArgv
=
program
.
parse
;
program
.
parse
=
undefined
;
if
(
process
.
argv
.
includes
(
"ast"
))
program
.
helpInformation
=
describe_ast
;
else
if
(
process
.
argv
.
includes
(
"options"
))
program
.
helpInformation
=
function
()
{
var
text
=
[];
for
(
var
option
in
default_options
)
{
text
.
push
(
"--"
+
(
option
===
"sourceMap"
?
"source-map"
:
option
)
+
" options:"
);
text
.
push
(
format_object
(
default_options
[
option
]));
text
.
push
(
""
);
}
return
text
.
join
(
"\n"
);
};
program
.
option
(
"-p, --parse <options>"
,
"Specify parser options."
,
parse_js
());
program
.
option
(
"-c, --compress [options]"
,
"Enable compressor/specify compressor options."
,
parse_js
());
program
.
option
(
"-m, --mangle [options]"
,
"Mangle names/specify mangler options."
,
parse_js
());
program
.
option
(
"--mangle-props [options]"
,
"Mangle properties/specify mangler options."
,
parse_js
());
program
.
option
(
"-f, --format [options]"
,
"Format options."
,
parse_js
());
program
.
option
(
"-b, --beautify [options]"
,
"Alias for --format beautify=true."
,
parse_js
());
program
.
option
(
"-o, --output <file>"
,
"Output file (default STDOUT)."
);
program
.
option
(
"--comments [filter]"
,
"Preserve copyright comments in the output."
);
program
.
option
(
"--config-file <file>"
,
"Read minify() options from JSON file."
);
program
.
option
(
"-d, --define <expr>[=value]"
,
"Global definitions."
,
parse_js
(
"define"
));
program
.
option
(
"--ecma <version>"
,
"Specify ECMAScript release: 5, 2015, 2016 or 2017..."
);
program
.
option
(
"-e, --enclose [arg[,...][:value[,...]]]"
,
"Embed output in a big function with configurable arguments and values."
);
program
.
option
(
"--ie8"
,
"Support non-standard Internet Explorer 8."
);
program
.
option
(
"--keep-classnames"
,
"Do not mangle/drop class names."
);
program
.
option
(
"--keep-fnames"
,
"Do not mangle/drop function names. Useful for code relying on Function.prototype.name."
);
program
.
option
(
"--module"
,
"Input is an ES6 module"
);
program
.
option
(
"--name-cache <file>"
,
"File to hold mangled name mappings."
);
program
.
option
(
"--rename"
,
"Force symbol expansion."
);
program
.
option
(
"--no-rename"
,
"Disable symbol expansion."
);
program
.
option
(
"--safari10"
,
"Support non-standard Safari 10."
);
program
.
option
(
"--source-map [options]"
,
"Enable source map/specify source map options."
,
parse_js
());
program
.
option
(
"--timings"
,
"Display operations run time on STDERR."
);
program
.
option
(
"--toplevel"
,
"Compress and/or mangle variables in toplevel scope."
);
program
.
option
(
"--wrap <name>"
,
"Embed everything as a function with “exports” corresponding to “name” globally."
);
program
.
arguments
(
"[files...]"
).
parseArgv
(
process
.
argv
);
if
(
program
.
configFile
)
{
options
=
JSON
.
parse
(
read_file
(
program
.
configFile
));
}
if
(
!
program
.
output
&&
program
.
sourceMap
&&
program
.
sourceMap
.
url
!=
"inline"
)
{
fatal
(
"ERROR: cannot write source map to STDOUT"
);
}
[
"compress"
,
"enclose"
,
"ie8"
,
"mangle"
,
"module"
,
"safari10"
,
"sourceMap"
,
"toplevel"
,
"wrap"
].
forEach
(
function
(
name
)
{
if
(
name
in
program
)
{
options
[
name
]
=
program
[
name
];
}
});
if
(
"ecma"
in
program
)
{
if
(
program
.
ecma
!=
(
program
.
ecma
|
0
))
fatal
(
"ERROR: ecma must be an integer"
);
const
ecma
=
program
.
ecma
|
0
;
if
(
ecma
>
5
&&
ecma
<
2015
)
options
.
ecma
=
ecma
+
2009
;
else
options
.
ecma
=
ecma
;
}
if
(
program
.
beautify
||
program
.
format
)
{
if
(
program
.
beautify
&&
program
.
format
)
{
fatal
(
"Please only specify one of --beautify or --format"
);
}
if
(
program
.
beautify
)
{
options
.
format
=
typeof
program
.
beautify
==
"object"
?
program
.
beautify
:
{};
if
(
!
(
"beautify"
in
options
.
format
))
{
options
.
format
.
beautify
=
true
;
}
}
if
(
program
.
format
)
{
options
.
format
=
typeof
program
.
format
==
"object"
?
program
.
format
:
{};
}
}
if
(
program
.
comments
)
{
if
(
typeof
options
.
format
!=
"object"
)
options
.
format
=
{};
options
.
format
.
comments
=
typeof
program
.
comments
==
"string"
?
(
program
.
comments
==
"false"
?
false
:
program
.
comments
)
:
"some"
;
}
if
(
program
.
define
)
{
if
(
typeof
options
.
compress
!=
"object"
)
options
.
compress
=
{};
if
(
typeof
options
.
compress
.
global_defs
!=
"object"
)
options
.
compress
.
global_defs
=
{};
for
(
var
expr
in
program
.
define
)
{
options
.
compress
.
global_defs
[
expr
]
=
program
.
define
[
expr
];
}
}
if
(
program
.
keepClassnames
)
{
options
.
keep_classnames
=
true
;
}
if
(
program
.
keepFnames
)
{
options
.
keep_fnames
=
true
;
}
if
(
program
.
mangleProps
)
{
if
(
program
.
mangleProps
.
domprops
)
{
delete
program
.
mangleProps
.
domprops
;
}
else
{
if
(
typeof
program
.
mangleProps
!=
"object"
)
program
.
mangleProps
=
{};
if
(
!
Array
.
isArray
(
program
.
mangleProps
.
reserved
))
program
.
mangleProps
.
reserved
=
[];
}
if
(
typeof
options
.
mangle
!=
"object"
)
options
.
mangle
=
{};
options
.
mangle
.
properties
=
program
.
mangleProps
;
}
if
(
program
.
nameCache
)
{
options
.
nameCache
=
JSON
.
parse
(
read_file
(
program
.
nameCache
,
"{}"
));
}
if
(
program
.
output
==
"ast"
)
{
options
.
format
=
{
ast
:
true
,
code
:
false
};
}
if
(
program
.
parse
)
{
if
(
!
program
.
parse
.
acorn
&&
!
program
.
parse
.
spidermonkey
)
{
options
.
parse
=
program
.
parse
;
}
else
if
(
program
.
sourceMap
&&
program
.
sourceMap
.
content
==
"inline"
)
{
fatal
(
"ERROR: inline source map only works with built-in parser"
);
}
}
if
(
~
program
.
rawArgs
.
indexOf
(
"--rename"
))
{
options
.
rename
=
true
;
}
else
if
(
!
program
.
rename
)
{
options
.
rename
=
false
;
}
let
convert_path
=
name
=>
name
;
if
(
typeof
program
.
sourceMap
==
"object"
&&
"base"
in
program
.
sourceMap
)
{
convert_path
=
function
()
{
var
base
=
program
.
sourceMap
.
base
;
delete
options
.
sourceMap
.
base
;
return
function
(
name
)
{
return
path
.
relative
(
base
,
name
);
};
}();
}
let
filesList
;
if
(
options
.
files
&&
options
.
files
.
length
)
{
filesList
=
options
.
files
;
delete
options
.
files
;
}
else
if
(
program
.
args
.
length
)
{
filesList
=
program
.
args
;
}
if
(
filesList
)
{
simple_glob
(
filesList
).
forEach
(
function
(
name
)
{
files
[
convert_path
(
name
)]
=
read_file
(
name
);
});
}
else
{
await
new
Promise
((
resolve
)
=>
{
var
chunks
=
[];
process
.
stdin
.
setEncoding
(
"utf8"
);
process
.
stdin
.
on
(
"data"
,
function
(
chunk
)
{
chunks
.
push
(
chunk
);
}).
on
(
"end"
,
function
()
{
files
=
[
chunks
.
join
(
""
)
];
resolve
();
});
process
.
stdin
.
resume
();
});
}
await
run_cli
();
function
convert_ast
(
fn
)
{
return
AST_Node
.
from_mozilla_ast
(
Object
.
keys
(
files
).
reduce
(
fn
,
null
));
}
async
function
run_cli
()
{
var
content
=
program
.
sourceMap
&&
program
.
sourceMap
.
content
;
if
(
content
&&
content
!==
"inline"
)
{
options
.
sourceMap
.
content
=
read_file
(
content
,
content
);
}
if
(
program
.
timings
)
options
.
timings
=
true
;
try
{
if
(
program
.
parse
)
{
if
(
program
.
parse
.
acorn
)
{
files
=
convert_ast
(
function
(
toplevel
,
name
)
{
return
require
(
"acorn"
).
parse
(
files
[
name
],
{
ecmaVersion
:
2018
,
locations
:
true
,
program
:
toplevel
,
sourceFile
:
name
,
sourceType
:
options
.
module
||
program
.
parse
.
module
?
"module"
:
"script"
});
});
}
else
if
(
program
.
parse
.
spidermonkey
)
{
files
=
convert_ast
(
function
(
toplevel
,
name
)
{
var
obj
=
JSON
.
parse
(
files
[
name
]);
if
(
!
toplevel
)
return
obj
;
toplevel
.
body
=
toplevel
.
body
.
concat
(
obj
.
body
);
return
toplevel
;
});
}
}
}
catch
(
ex
)
{
fatal
(
ex
);
}
let
result
;
try
{
result
=
await
minify
(
files
,
options
);
}
catch
(
ex
)
{
if
(
ex
.
name
==
"SyntaxError"
)
{
print_error
(
"Parse error at "
+
ex
.
filename
+
":"
+
ex
.
line
+
","
+
ex
.
col
);
var
col
=
ex
.
col
;
var
lines
=
files
[
ex
.
filename
].
split
(
/\r?\n/
);
var
line
=
lines
[
ex
.
line
-
1
];
if
(
!
line
&&
!
col
)
{
line
=
lines
[
ex
.
line
-
2
];
col
=
line
.
length
;
}
if
(
line
)
{
var
limit
=
70
;
if
(
col
>
limit
)
{
line
=
line
.
slice
(
col
-
limit
);
col
=
limit
;
}
print_error
(
line
.
slice
(
0
,
80
));
print_error
(
line
.
slice
(
0
,
col
).
replace
(
/\S/g
,
" "
)
+
"^"
);
}
}
if
(
ex
.
defs
)
{
print_error
(
"Supported options:"
);
print_error
(
format_object
(
ex
.
defs
));
}
fatal
(
ex
);
return
;
}
if
(
program
.
output
==
"ast"
)
{
if
(
!
options
.
compress
&&
!
options
.
mangle
)
{
result
.
ast
.
figure_out_scope
({});
}
console
.
log
(
JSON
.
stringify
(
result
.
ast
,
function
(
key
,
value
)
{
if
(
value
)
switch
(
key
)
{
case
"thedef"
:
return
symdef
(
value
);
case
"enclosed"
:
return
value
.
length
?
value
.
map
(
symdef
)
:
undefined
;
case
"variables"
:
case
"functions"
:
case
"globals"
:
return
value
.
size
?
collect_from_map
(
value
,
symdef
)
:
undefined
;
}
if
(
skip_keys
.
has
(
key
))
return
;
if
(
value
instanceof
AST_Token
)
return
;
if
(
value
instanceof
Map
)
return
;
if
(
value
instanceof
AST_Node
)
{
var
result
=
{
_class
:
"AST_"
+
value
.
TYPE
};
if
(
value
.
block_scope
)
{
result
.
variables
=
value
.
block_scope
.
variables
;
result
.
functions
=
value
.
block_scope
.
functions
;
result
.
enclosed
=
value
.
block_scope
.
enclosed
;
}
value
.
CTOR
.
PROPS
.
forEach
(
function
(
prop
)
{
result
[
prop
]
=
value
[
prop
];
});
return
result
;
}
return
value
;
},
2
));
}
else
if
(
program
.
output
==
"spidermonkey"
)
{
try
{
const
minified
=
await
minify
(
result
.
code
,
{
compress
:
false
,
mangle
:
false
,
format
:
{
ast
:
true
,
code
:
false
}
});
console
.
log
(
JSON
.
stringify
(
minified
.
ast
.
to_mozilla_ast
(),
null
,
2
));
}
catch
(
ex
)
{
fatal
(
ex
);
return
;
}
}
else
if
(
program
.
output
)
{
fs
.
writeFileSync
(
program
.
output
,
result
.
code
);
if
(
options
.
sourceMap
&&
options
.
sourceMap
.
url
!==
"inline"
&&
result
.
map
)
{
fs
.
writeFileSync
(
program
.
output
+
".map"
,
result
.
map
);
}
}
else
{
console
.
log
(
result
.
code
);
}
if
(
program
.
nameCache
)
{
fs
.
writeFileSync
(
program
.
nameCache
,
JSON
.
stringify
(
options
.
nameCache
));
}
if
(
result
.
timings
)
for
(
var
phase
in
result
.
timings
)
{
print_error
(
"- "
+
phase
+
": "
+
result
.
timings
[
phase
].
toFixed
(
3
)
+
"s"
);
}
}
function
fatal
(
message
)
{
if
(
message
instanceof
Error
)
message
=
message
.
stack
.
replace
(
/^\S*?Error:/
,
"ERROR:"
);
print_error
(
message
);
process
.
exit
(
1
);
}
// A file glob function that only supports "*" and "?" wildcards in the basename.
// Example: "foo/bar/*baz??.*.js"
// Argument `glob` may be a string or an array of strings.
// Returns an array of strings. Garbage in, garbage out.
function
simple_glob
(
glob
)
{
if
(
Array
.
isArray
(
glob
))
{
return
[].
concat
.
apply
([],
glob
.
map
(
simple_glob
));
}
if
(
glob
&&
glob
.
match
(
/[*?]/
))
{
var
dir
=
path
.
dirname
(
glob
);
try
{
var
entries
=
fs
.
readdirSync
(
dir
);
}
catch
(
ex
)
{}
if
(
entries
)
{
var
pattern
=
"^"
+
path
.
basename
(
glob
)
.
replace
(
/[.+^$[\]\\(){}]/g
,
"\\$&"
)
.
replace
(
/\*/g
,
"[^/\\\\]*"
)
.
replace
(
/\?/g
,
"[^/\\\\]"
)
+
"$"
;
var
mod
=
process
.
platform
===
"win32"
?
"i"
:
""
;
var
rx
=
new
RegExp
(
pattern
,
mod
);
var
results
=
entries
.
filter
(
function
(
name
)
{
return
rx
.
test
(
name
);
}).
map
(
function
(
name
)
{
return
path
.
join
(
dir
,
name
);
});
if
(
results
.
length
)
return
results
;
}
}
return
[
glob
];
}
function
read_file
(
path
,
default_value
)
{
try
{
return
fs
.
readFileSync
(
path
,
"utf8"
);
}
catch
(
ex
)
{
if
((
ex
.
code
==
"ENOENT"
||
ex
.
code
==
"ENAMETOOLONG"
)
&&
default_value
!=
null
)
return
default_value
;
fatal
(
ex
);
}
}
function
parse_js
(
flag
)
{
return
function
(
value
,
options
)
{
options
=
options
||
{};
try
{
walk
(
parse
(
value
,
{
expression
:
true
}),
node
=>
{
if
(
node
instanceof
AST_Assign
)
{
var
name
=
node
.
left
.
print_to_string
();
var
value
=
node
.
right
;
if
(
flag
)
{
options
[
name
]
=
value
;
}
else
if
(
value
instanceof
AST_Array
)
{
options
[
name
]
=
value
.
elements
.
map
(
to_string
);
}
else
if
(
value
instanceof
AST_RegExp
)
{
value
=
value
.
value
;
options
[
name
]
=
new
RegExp
(
value
.
source
,
value
.
flags
);
}
else
{
options
[
name
]
=
to_string
(
value
);
}
return
true
;
}
if
(
node
instanceof
AST_Symbol
||
node
instanceof
AST_PropAccess
)
{
var
name
=
node
.
print_to_string
();
options
[
name
]
=
true
;
return
true
;
}
if
(
!
(
node
instanceof
AST_Sequence
))
throw
node
;
function
to_string
(
value
)
{
return
value
instanceof
AST_Constant
?
value
.
getValue
()
:
value
.
print_to_string
({
quote_keys
:
true
});
}
});
}
catch
(
ex
)
{
if
(
flag
)
{
fatal
(
"Error parsing arguments for '"
+
flag
+
"': "
+
value
);
}
else
{
options
[
value
]
=
null
;
}
}
return
options
;
};
}
function
symdef
(
def
)
{
var
ret
=
(
1
e6
+
def
.
id
)
+
" "
+
def
.
name
;
if
(
def
.
mangled_name
)
ret
+=
" "
+
def
.
mangled_name
;
return
ret
;
}
function
collect_from_map
(
map
,
callback
)
{
var
result
=
[];
map
.
forEach
(
function
(
def
)
{
result
.
push
(
callback
(
def
));
});
return
result
;
}
function
format_object
(
obj
)
{
var
lines
=
[];
var
padding
=
""
;
Object
.
keys
(
obj
).
map
(
function
(
name
)
{
if
(
padding
.
length
<
name
.
length
)
padding
=
Array
(
name
.
length
+
1
).
join
(
" "
);
return
[
name
,
JSON
.
stringify
(
obj
[
name
])
];
}).
forEach
(
function
(
tokens
)
{
lines
.
push
(
" "
+
tokens
[
0
]
+
padding
.
slice
(
tokens
[
0
].
length
-
2
)
+
tokens
[
1
]);
});
return
lines
.
join
(
"\n"
);
}
function
print_error
(
msg
)
{
process
.
stderr
.
write
(
msg
);
process
.
stderr
.
write
(
"\n"
);
}
function
describe_ast
()
{
var
out
=
OutputStream
({
beautify
:
true
});
function
doitem
(
ctor
)
{
out
.
print
(
"AST_"
+
ctor
.
TYPE
);
const
props
=
ctor
.
SELF_PROPS
.
filter
(
prop
=>
!
/^\$/
.
test
(
prop
));
if
(
props
.
length
>
0
)
{
out
.
space
();
out
.
with_parens
(
function
()
{
props
.
forEach
(
function
(
prop
,
i
)
{
if
(
i
)
out
.
space
();
out
.
print
(
prop
);
});
});
}
if
(
ctor
.
documentation
)
{
out
.
space
();
out
.
print_string
(
ctor
.
documentation
);
}
if
(
ctor
.
SUBCLASSES
.
length
>
0
)
{
out
.
space
();
out
.
with_block
(
function
()
{
ctor
.
SUBCLASSES
.
forEach
(
function
(
ctor
)
{
out
.
indent
();
doitem
(
ctor
);
out
.
newline
();
});
});
}
}
doitem
(
AST_Node
);
return
out
+
"\n"
;
}
}
Event Timeline
Log In to Comment