Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F102487667
command.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
Fri, Feb 21, 05:50
Size
15 KB
Mime Type
text/x-java
Expires
Sun, Feb 23, 05:50 (2 d)
Engine
blob
Format
Raw Data
Handle
24332133
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
command.js
View Options
import
{
assertNotStrictEqual
,
}
from
'./typings/common-types.js'
;
import
{
isPromise
}
from
'./utils/is-promise.js'
;
import
{
applyMiddleware
,
commandMiddlewareFactory
,
}
from
'./middleware.js'
;
import
{
parseCommand
}
from
'./parse-command.js'
;
import
{
isYargsInstance
,
}
from
'./yargs-factory.js'
;
import
whichModule
from
'./utils/which-module.js'
;
const
DEFAULT_MARKER
=
/(^\*)|(^\$0)/
;
export
function
command
(
yargs
,
usage
,
validation
,
globalMiddleware
=
[],
shim
)
{
const
self
=
{};
let
handlers
=
{};
let
aliasMap
=
{};
let
defaultCommand
;
self
.
addHandler
=
function
addHandler
(
cmd
,
description
,
builder
,
handler
,
commandMiddleware
,
deprecated
)
{
let
aliases
=
[];
const
middlewares
=
commandMiddlewareFactory
(
commandMiddleware
);
handler
=
handler
||
(()
=>
{
});
if
(
Array
.
isArray
(
cmd
))
{
if
(
isCommandAndAliases
(
cmd
))
{
[
cmd
,
...
aliases
]
=
cmd
;
}
else
{
for
(
const
command
of
cmd
)
{
self
.
addHandler
(
command
);
}
}
}
else
if
(
isCommandHandlerDefinition
(
cmd
))
{
let
command
=
Array
.
isArray
(
cmd
.
command
)
||
typeof
cmd
.
command
===
'string'
?
cmd
.
command
:
moduleName
(
cmd
);
if
(
cmd
.
aliases
)
command
=
[].
concat
(
command
).
concat
(
cmd
.
aliases
);
self
.
addHandler
(
command
,
extractDesc
(
cmd
),
cmd
.
builder
,
cmd
.
handler
,
cmd
.
middlewares
,
cmd
.
deprecated
);
return
;
}
else
if
(
isCommandBuilderDefinition
(
builder
))
{
self
.
addHandler
([
cmd
].
concat
(
aliases
),
description
,
builder
.
builder
,
builder
.
handler
,
builder
.
middlewares
,
builder
.
deprecated
);
return
;
}
if
(
typeof
cmd
===
'string'
)
{
const
parsedCommand
=
parseCommand
(
cmd
);
aliases
=
aliases
.
map
(
alias
=>
parseCommand
(
alias
).
cmd
);
let
isDefault
=
false
;
const
parsedAliases
=
[
parsedCommand
.
cmd
].
concat
(
aliases
).
filter
(
c
=>
{
if
(
DEFAULT_MARKER
.
test
(
c
))
{
isDefault
=
true
;
return
false
;
}
return
true
;
});
if
(
parsedAliases
.
length
===
0
&&
isDefault
)
parsedAliases
.
push
(
'$0'
);
if
(
isDefault
)
{
parsedCommand
.
cmd
=
parsedAliases
[
0
];
aliases
=
parsedAliases
.
slice
(
1
);
cmd
=
cmd
.
replace
(
DEFAULT_MARKER
,
parsedCommand
.
cmd
);
}
aliases
.
forEach
(
alias
=>
{
aliasMap
[
alias
]
=
parsedCommand
.
cmd
;
});
if
(
description
!==
false
)
{
usage
.
command
(
cmd
,
description
,
isDefault
,
aliases
,
deprecated
);
}
handlers
[
parsedCommand
.
cmd
]
=
{
original
:
cmd
,
description
,
handler
,
builder
:
builder
||
{},
middlewares
,
deprecated
,
demanded
:
parsedCommand
.
demanded
,
optional
:
parsedCommand
.
optional
,
};
if
(
isDefault
)
defaultCommand
=
handlers
[
parsedCommand
.
cmd
];
}
};
self
.
addDirectory
=
function
addDirectory
(
dir
,
context
,
req
,
callerFile
,
opts
)
{
opts
=
opts
||
{};
if
(
typeof
opts
.
recurse
!==
'boolean'
)
opts
.
recurse
=
false
;
if
(
!
Array
.
isArray
(
opts
.
extensions
))
opts
.
extensions
=
[
'js'
];
const
parentVisit
=
typeof
opts
.
visit
===
'function'
?
opts
.
visit
:
(
o
)
=>
o
;
opts
.
visit
=
function
visit
(
obj
,
joined
,
filename
)
{
const
visited
=
parentVisit
(
obj
,
joined
,
filename
);
if
(
visited
)
{
if
(
~
context
.
files
.
indexOf
(
joined
))
return
visited
;
context
.
files
.
push
(
joined
);
self
.
addHandler
(
visited
);
}
return
visited
;
};
shim
.
requireDirectory
({
require
:
req
,
filename
:
callerFile
},
dir
,
opts
);
};
function
moduleName
(
obj
)
{
const
mod
=
whichModule
(
obj
);
if
(
!
mod
)
throw
new
Error
(
`
No
command
name
given
for
module
:
$
{
shim
.
inspect
(
obj
)}
`
);
return
commandFromFilename
(
mod
.
filename
);
}
function
commandFromFilename
(
filename
)
{
return
shim
.
path
.
basename
(
filename
,
shim
.
path
.
extname
(
filename
));
}
function
extractDesc
({
describe
,
description
,
desc
,
})
{
for
(
const
test
of
[
describe
,
description
,
desc
])
{
if
(
typeof
test
===
'string'
||
test
===
false
)
return
test
;
assertNotStrictEqual
(
test
,
true
,
shim
);
}
return
false
;
}
self
.
getCommands
=
()
=>
Object
.
keys
(
handlers
).
concat
(
Object
.
keys
(
aliasMap
));
self
.
getCommandHandlers
=
()
=>
handlers
;
self
.
hasDefaultCommand
=
()
=>
!!
defaultCommand
;
self
.
runCommand
=
function
runCommand
(
command
,
yargs
,
parsed
,
commandIndex
)
{
let
aliases
=
parsed
.
aliases
;
const
commandHandler
=
handlers
[
command
]
||
handlers
[
aliasMap
[
command
]]
||
defaultCommand
;
const
currentContext
=
yargs
.
getContext
();
let
numFiles
=
currentContext
.
files
.
length
;
const
parentCommands
=
currentContext
.
commands
.
slice
();
let
innerArgv
=
parsed
.
argv
;
let
positionalMap
=
{};
if
(
command
)
{
currentContext
.
commands
.
push
(
command
);
currentContext
.
fullCommands
.
push
(
commandHandler
.
original
);
}
const
builder
=
commandHandler
.
builder
;
if
(
isCommandBuilderCallback
(
builder
))
{
const
builderOutput
=
builder
(
yargs
.
reset
(
parsed
.
aliases
));
const
innerYargs
=
isYargsInstance
(
builderOutput
)
?
builderOutput
:
yargs
;
if
(
shouldUpdateUsage
(
innerYargs
))
{
innerYargs
.
getUsageInstance
()
.
usage
(
usageFromParentCommandsCommandHandler
(
parentCommands
,
commandHandler
),
commandHandler
.
description
);
}
innerArgv
=
innerYargs
.
_parseArgs
(
null
,
null
,
true
,
commandIndex
);
aliases
=
innerYargs
.
parsed
.
aliases
;
}
else
if
(
isCommandBuilderOptionDefinitions
(
builder
))
{
const
innerYargs
=
yargs
.
reset
(
parsed
.
aliases
);
if
(
shouldUpdateUsage
(
innerYargs
))
{
innerYargs
.
getUsageInstance
()
.
usage
(
usageFromParentCommandsCommandHandler
(
parentCommands
,
commandHandler
),
commandHandler
.
description
);
}
Object
.
keys
(
commandHandler
.
builder
).
forEach
(
key
=>
{
innerYargs
.
option
(
key
,
builder
[
key
]);
});
innerArgv
=
innerYargs
.
_parseArgs
(
null
,
null
,
true
,
commandIndex
);
aliases
=
innerYargs
.
parsed
.
aliases
;
}
if
(
!
yargs
.
_hasOutput
())
{
positionalMap
=
populatePositionals
(
commandHandler
,
innerArgv
,
currentContext
);
}
const
middlewares
=
globalMiddleware
.
slice
(
0
)
.
concat
(
commandHandler
.
middlewares
);
applyMiddleware
(
innerArgv
,
yargs
,
middlewares
,
true
);
if
(
!
yargs
.
_hasOutput
())
{
yargs
.
_runValidation
(
innerArgv
,
aliases
,
positionalMap
,
yargs
.
parsed
.
error
,
!
command
);
}
if
(
commandHandler
.
handler
&&
!
yargs
.
_hasOutput
())
{
yargs
.
_setHasOutput
();
const
populateDoubleDash
=
!!
yargs
.
getOptions
().
configuration
[
'populate--'
];
yargs
.
_postProcess
(
innerArgv
,
populateDoubleDash
);
innerArgv
=
applyMiddleware
(
innerArgv
,
yargs
,
middlewares
,
false
);
let
handlerResult
;
if
(
isPromise
(
innerArgv
))
{
handlerResult
=
innerArgv
.
then
(
argv
=>
commandHandler
.
handler
(
argv
));
}
else
{
handlerResult
=
commandHandler
.
handler
(
innerArgv
);
}
const
handlerFinishCommand
=
yargs
.
getHandlerFinishCommand
();
if
(
isPromise
(
handlerResult
))
{
yargs
.
getUsageInstance
().
cacheHelpMessage
();
handlerResult
.
then
(
value
=>
{
if
(
handlerFinishCommand
)
{
handlerFinishCommand
(
value
);
}
})
.
catch
(
error
=>
{
try
{
yargs
.
getUsageInstance
().
fail
(
null
,
error
);
}
catch
(
err
)
{
}
})
.
then
(()
=>
{
yargs
.
getUsageInstance
().
clearCachedHelpMessage
();
});
}
else
{
if
(
handlerFinishCommand
)
{
handlerFinishCommand
(
handlerResult
);
}
}
}
if
(
command
)
{
currentContext
.
commands
.
pop
();
currentContext
.
fullCommands
.
pop
();
}
numFiles
=
currentContext
.
files
.
length
-
numFiles
;
if
(
numFiles
>
0
)
currentContext
.
files
.
splice
(
numFiles
*
-
1
,
numFiles
);
return
innerArgv
;
};
function
shouldUpdateUsage
(
yargs
)
{
return
(
!
yargs
.
getUsageInstance
().
getUsageDisabled
()
&&
yargs
.
getUsageInstance
().
getUsage
().
length
===
0
);
}
function
usageFromParentCommandsCommandHandler
(
parentCommands
,
commandHandler
)
{
const
c
=
DEFAULT_MARKER
.
test
(
commandHandler
.
original
)
?
commandHandler
.
original
.
replace
(
DEFAULT_MARKER
,
''
).
trim
()
:
commandHandler
.
original
;
const
pc
=
parentCommands
.
filter
(
c
=>
{
return
!
DEFAULT_MARKER
.
test
(
c
);
});
pc
.
push
(
c
);
return
`
$0
$
{
pc
.
join
(
' '
)}
`
;
}
self
.
runDefaultBuilderOn
=
function
(
yargs
)
{
assertNotStrictEqual
(
defaultCommand
,
undefined
,
shim
);
if
(
shouldUpdateUsage
(
yargs
))
{
const
commandString
=
DEFAULT_MARKER
.
test
(
defaultCommand
.
original
)
?
defaultCommand
.
original
:
defaultCommand
.
original
.
replace
(
/^[^[\]<>]*/
,
'$0 '
);
yargs
.
getUsageInstance
().
usage
(
commandString
,
defaultCommand
.
description
);
}
const
builder
=
defaultCommand
.
builder
;
if
(
isCommandBuilderCallback
(
builder
))
{
builder
(
yargs
);
}
else
if
(
!
isCommandBuilderDefinition
(
builder
))
{
Object
.
keys
(
builder
).
forEach
(
key
=>
{
yargs
.
option
(
key
,
builder
[
key
]);
});
}
};
function
populatePositionals
(
commandHandler
,
argv
,
context
)
{
argv
.
_
=
argv
.
_
.
slice
(
context
.
commands
.
length
);
const
demanded
=
commandHandler
.
demanded
.
slice
(
0
);
const
optional
=
commandHandler
.
optional
.
slice
(
0
);
const
positionalMap
=
{};
validation
.
positionalCount
(
demanded
.
length
,
argv
.
_
.
length
);
while
(
demanded
.
length
)
{
const
demand
=
demanded
.
shift
();
populatePositional
(
demand
,
argv
,
positionalMap
);
}
while
(
optional
.
length
)
{
const
maybe
=
optional
.
shift
();
populatePositional
(
maybe
,
argv
,
positionalMap
);
}
argv
.
_
=
context
.
commands
.
concat
(
argv
.
_
.
map
(
a
=>
''
+
a
));
postProcessPositionals
(
argv
,
positionalMap
,
self
.
cmdToParseOptions
(
commandHandler
.
original
));
return
positionalMap
;
}
function
populatePositional
(
positional
,
argv
,
positionalMap
)
{
const
cmd
=
positional
.
cmd
[
0
];
if
(
positional
.
variadic
)
{
positionalMap
[
cmd
]
=
argv
.
_
.
splice
(
0
).
map
(
String
);
}
else
{
if
(
argv
.
_
.
length
)
positionalMap
[
cmd
]
=
[
String
(
argv
.
_
.
shift
())];
}
}
function
postProcessPositionals
(
argv
,
positionalMap
,
parseOptions
)
{
const
options
=
Object
.
assign
({},
yargs
.
getOptions
());
options
.
default
=
Object
.
assign
(
parseOptions
.
default
,
options
.
default
);
for
(
const
key
of
Object
.
keys
(
parseOptions
.
alias
))
{
options
.
alias
[
key
]
=
(
options
.
alias
[
key
]
||
[]).
concat
(
parseOptions
.
alias
[
key
]);
}
options
.
array
=
options
.
array
.
concat
(
parseOptions
.
array
);
options
.
config
=
{};
const
unparsed
=
[];
Object
.
keys
(
positionalMap
).
forEach
(
key
=>
{
positionalMap
[
key
].
map
(
value
=>
{
if
(
options
.
configuration
[
'unknown-options-as-args'
])
options
.
key
[
key
]
=
true
;
unparsed
.
push
(
`
--
$
{
key
}
`
);
unparsed
.
push
(
value
);
});
});
if
(
!
unparsed
.
length
)
return
;
const
config
=
Object
.
assign
({},
options
.
configuration
,
{
'populate--'
:
true
,
});
const
parsed
=
shim
.
Parser
.
detailed
(
unparsed
,
Object
.
assign
({},
options
,
{
configuration
:
config
,
}));
if
(
parsed
.
error
)
{
yargs
.
getUsageInstance
().
fail
(
parsed
.
error
.
message
,
parsed
.
error
);
}
else
{
const
positionalKeys
=
Object
.
keys
(
positionalMap
);
Object
.
keys
(
positionalMap
).
forEach
(
key
=>
{
positionalKeys
.
push
(...
parsed
.
aliases
[
key
]);
});
Object
.
keys
(
parsed
.
argv
).
forEach
(
key
=>
{
if
(
positionalKeys
.
indexOf
(
key
)
!==
-
1
)
{
if
(
!
positionalMap
[
key
])
positionalMap
[
key
]
=
parsed
.
argv
[
key
];
argv
[
key
]
=
parsed
.
argv
[
key
];
}
});
}
}
self
.
cmdToParseOptions
=
function
(
cmdString
)
{
const
parseOptions
=
{
array
:
[],
default
:
{},
alias
:
{},
demand
:
{},
};
const
parsed
=
parseCommand
(
cmdString
);
parsed
.
demanded
.
forEach
(
d
=>
{
const
[
cmd
,
...
aliases
]
=
d
.
cmd
;
if
(
d
.
variadic
)
{
parseOptions
.
array
.
push
(
cmd
);
parseOptions
.
default
[
cmd
]
=
[];
}
parseOptions
.
alias
[
cmd
]
=
aliases
;
parseOptions
.
demand
[
cmd
]
=
true
;
});
parsed
.
optional
.
forEach
(
o
=>
{
const
[
cmd
,
...
aliases
]
=
o
.
cmd
;
if
(
o
.
variadic
)
{
parseOptions
.
array
.
push
(
cmd
);
parseOptions
.
default
[
cmd
]
=
[];
}
parseOptions
.
alias
[
cmd
]
=
aliases
;
});
return
parseOptions
;
};
self
.
reset
=
()
=>
{
handlers
=
{};
aliasMap
=
{};
defaultCommand
=
undefined
;
return
self
;
};
const
frozens
=
[];
self
.
freeze
=
()
=>
{
frozens
.
push
({
handlers
,
aliasMap
,
defaultCommand
,
});
};
self
.
unfreeze
=
()
=>
{
const
frozen
=
frozens
.
pop
();
assertNotStrictEqual
(
frozen
,
undefined
,
shim
);
({
handlers
,
aliasMap
,
defaultCommand
}
=
frozen
);
};
return
self
;
}
export
function
isCommandBuilderDefinition
(
builder
)
{
return
(
typeof
builder
===
'object'
&&
!!
builder
.
builder
&&
typeof
builder
.
handler
===
'function'
);
}
function
isCommandAndAliases
(
cmd
)
{
if
(
cmd
.
every
(
c
=>
typeof
c
===
'string'
))
{
return
true
;
}
else
{
return
false
;
}
}
export
function
isCommandBuilderCallback
(
builder
)
{
return
typeof
builder
===
'function'
;
}
function
isCommandBuilderOptionDefinitions
(
builder
)
{
return
typeof
builder
===
'object'
;
}
export
function
isCommandHandlerDefinition
(
cmd
)
{
return
typeof
cmd
===
'object'
&&
!
Array
.
isArray
(
cmd
);
}
Event Timeline
Log In to Comment