This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../acorn/bin/acorn" "$@"
else
exec node "$basedir/../acorn/bin/acorn" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\acorn\bin\acorn" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args
} else {
& "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../acorn/bin/acorn" $args
} else {
& "node$exe" "$basedir/../acorn/bin/acorn" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../astring/bin/astring" "$@"
else
exec node "$basedir/../astring/bin/astring" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\astring\bin\astring" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../astring/bin/astring" $args
} else {
& "$basedir/node$exe" "$basedir/../astring/bin/astring" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../astring/bin/astring" $args
} else {
& "node$exe" "$basedir/../astring/bin/astring" $args
}
$ret=$LASTEXITCODE
}
exit $ret
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../color-support/bin.js" "$@"
else
exec node "$basedir/../color-support/bin.js" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\color-support\bin.js" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../color-support/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../color-support/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../color-support/bin.js" $args
} else {
& "node$exe" "$basedir/../color-support/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../he/bin/he" "$@"
else
exec node "$basedir/../he/bin/he" "$@"
fi
Generated Vendored
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\he\bin\he" %*
Generated Vendored
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../he/bin/he" $args
} else {
& "$basedir/node$exe" "$basedir/../he/bin/he" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../he/bin/he" $args
} else {
& "node$exe" "$basedir/../he/bin/he" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../knex/bin/cli.js" "$@"
else
exec node "$basedir/../knex/bin/cli.js" "$@"
fi
Generated Vendored
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\knex\bin\cli.js" %*
Generated Vendored
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../knex/bin/cli.js" $args
} else {
& "$basedir/node$exe" "$basedir/../knex/bin/cli.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../knex/bin/cli.js" $args
} else {
& "node$exe" "$basedir/../knex/bin/cli.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
else
exec node "$basedir/../mime/cli.js" "$@"
fi
Generated Vendored
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
Generated Vendored
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
} else {
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../mime/cli.js" $args
} else {
& "node$exe" "$basedir/../mime/cli.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../mkdirp/bin/cmd.js" "$@"
else
exec node "$basedir/../mkdirp/bin/cmd.js" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mkdirp\bin\cmd.js" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
} else {
& "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
} else {
& "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../mustache/bin/mustache" "$@"
else
exec node "$basedir/../mustache/bin/mustache" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mustache\bin\mustache" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../mustache/bin/mustache" $args
} else {
& "$basedir/node$exe" "$basedir/../mustache/bin/mustache" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../mustache/bin/mustache" $args
} else {
& "node$exe" "$basedir/../mustache/bin/mustache" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../node-gyp/bin/node-gyp.js" "$@"
else
exec node "$basedir/../node-gyp/bin/node-gyp.js" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\node-gyp\bin\node-gyp.js" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../node-gyp/bin/node-gyp.js" $args
} else {
& "$basedir/node$exe" "$basedir/../node-gyp/bin/node-gyp.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../node-gyp/bin/node-gyp.js" $args
} else {
& "node$exe" "$basedir/../node-gyp/bin/node-gyp.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" "$@"
else
exec node "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@mapbox\node-pre-gyp\bin\node-pre-gyp" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args
} else {
& "$basedir/node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args
} else {
& "node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args
}
$ret=$LASTEXITCODE
}
exit $ret
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../which/bin/node-which" "$@"
else
exec node "$basedir/../which/bin/node-which" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\which\bin\node-which" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../which/bin/node-which" $args
} else {
& "$basedir/node$exe" "$basedir/../which/bin/node-which" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../which/bin/node-which" $args
} else {
& "node$exe" "$basedir/../which/bin/node-which" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../nopt/bin/nopt.js" "$@"
else
exec node "$basedir/../nopt/bin/nopt.js" "$@"
fi
Generated Vendored
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nopt\bin\nopt.js" %*
Generated Vendored
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
} else {
& "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../nopt/bin/nopt.js" $args
} else {
& "node$exe" "$basedir/../nopt/bin/nopt.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../pino/bin.js" "$@"
else
exec node "$basedir/../pino/bin.js" "$@"
fi
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../pino-pretty/bin.js" "$@"
else
exec node "$basedir/../pino-pretty/bin.js" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\pino-pretty\bin.js" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../pino-pretty/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../pino-pretty/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../pino-pretty/bin.js" $args
} else {
& "node$exe" "$basedir/../pino-pretty/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\pino\bin.js" %*
Generated Vendored
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../pino/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../pino/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../pino/bin.js" $args
} else {
& "node$exe" "$basedir/../pino/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../resolve/bin/resolve" "$@"
else
exec node "$basedir/../resolve/bin/resolve" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\resolve\bin\resolve" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../resolve/bin/resolve" $args
} else {
& "$basedir/node$exe" "$basedir/../resolve/bin/resolve" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../resolve/bin/resolve" $args
} else {
& "node$exe" "$basedir/../resolve/bin/resolve" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../rimraf/bin.js" "$@"
else
exec node "$basedir/../rimraf/bin.js" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\rimraf\bin.js" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../rimraf/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../rimraf/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../rimraf/bin.js" $args
} else {
& "node$exe" "$basedir/../rimraf/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
Generated Vendored
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
else
exec node "$basedir/../semver/bin/semver.js" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
} else {
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
} else {
& "node$exe" "$basedir/../semver/bin/semver.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
+4201
View File
File diff suppressed because it is too large Load Diff
+9
View File
@@ -0,0 +1,9 @@
# The MIT License
Copyright 2022 Harminder Virk, contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+56
View File
@@ -0,0 +1,56 @@
<div align="center">
<img src="https://res.cloudinary.com/adonisjs/image/upload/q_100/v1558612869/adonis-readme_zscycu.jpg" width="600px">
</div>
<br />
<div align="center">
<h3>Command line framework of AdonisJS</h3>
<p> Ace is command line framework embedded into AdonisJS for creating CLI commands. AdonisJS is the <strong>only Node.js framework</strong> that allows creating CLI commands as part of the application codebase. </p>
</div>
<br />
<div align="center">
[![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] [![synk-image]][synk-url]
</div>
<div align="center">
<h3>
<a href="https://adonisjs.com">
Website
</a>
<span> | </span>
<a href="https://docs.adonisjs.com/guides/ace-commandline">
Guides
</a>
<span> | </span>
<a href="CONTRIBUTING.md">
Contributing
</a>
<span> | </span>
<a href="flow-chart.png">
Flow chart
</a>
</h3>
</div>
<div align="center">
<sub>Built with ❤︎ by <a href="https://twitter.com/AmanVirk1">Harminder Virk</a>
</div>
[gh-workflow-image]: https://img.shields.io/github/workflow/status/adonisjs/ace/test?style=for-the-badge
[gh-workflow-url]: https://github.com/adonisjs/ace/actions/workflows/test.yml "Github action"
[npm-image]: https://img.shields.io/npm/v/@adonisjs/ace/latest.svg?style=for-the-badge&logo=npm
[npm-url]: https://npmjs.org/package/@adonisjs/ace/v/latest "npm"
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[license-url]: LICENSE.md
[license-image]: https://img.shields.io/github/license/adonisjs/ace?style=for-the-badge
[synk-image]: https://img.shields.io/snyk/vulnerabilities/github/adonisjs/ace?label=Synk%20Vulnerabilities&style=for-the-badge
[synk-url]: https://snyk.io/test/github/adonisjs/ace?targetFile=package.json "synk"
+8
View File
@@ -0,0 +1,8 @@
export { Kernel } from './src/Kernel';
export { args } from './src/Decorators/args';
export { flags } from './src/Decorators/flags';
export { BaseCommand } from './src/BaseCommand';
export { handleError } from './src/utils/handleError';
export { ManifestLoader } from './src/Manifest/Loader';
export { ManifestGenerator } from './src/Manifest/Generator';
export { listDirectoryFiles } from './src/utils/listDirectoryFiles';
+27
View File
@@ -0,0 +1,27 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.listDirectoryFiles = exports.ManifestGenerator = exports.ManifestLoader = exports.handleError = exports.BaseCommand = exports.flags = exports.args = exports.Kernel = void 0;
var Kernel_1 = require("./src/Kernel");
Object.defineProperty(exports, "Kernel", { enumerable: true, get: function () { return Kernel_1.Kernel; } });
var args_1 = require("./src/Decorators/args");
Object.defineProperty(exports, "args", { enumerable: true, get: function () { return args_1.args; } });
var flags_1 = require("./src/Decorators/flags");
Object.defineProperty(exports, "flags", { enumerable: true, get: function () { return flags_1.flags; } });
var BaseCommand_1 = require("./src/BaseCommand");
Object.defineProperty(exports, "BaseCommand", { enumerable: true, get: function () { return BaseCommand_1.BaseCommand; } });
var handleError_1 = require("./src/utils/handleError");
Object.defineProperty(exports, "handleError", { enumerable: true, get: function () { return handleError_1.handleError; } });
var Loader_1 = require("./src/Manifest/Loader");
Object.defineProperty(exports, "ManifestLoader", { enumerable: true, get: function () { return Loader_1.ManifestLoader; } });
var Generator_1 = require("./src/Manifest/Generator");
Object.defineProperty(exports, "ManifestGenerator", { enumerable: true, get: function () { return Generator_1.ManifestGenerator; } });
var listDirectoryFiles_1 = require("./src/utils/listDirectoryFiles");
Object.defineProperty(exports, "listDirectoryFiles", { enumerable: true, get: function () { return listDirectoryFiles_1.listDirectoryFiles; } });
+148
View File
@@ -0,0 +1,148 @@
import { ParsedOptions } from 'getopts';
import { Prompt, FakePrompt } from '@poppinss/prompts';
import { instantiate } from '@poppinss/cliui/build/api';
import { ApplicationContract } from '@ioc:Adonis/Core/Application';
import { CommandArg, CommandFlag, KernelContract, CommandSettings, CommandContract, GeneratorContract } from '../Contracts';
/**
* Abstract base class other classes must extend
*/
export declare abstract class BaseCommand implements CommandContract {
application: ApplicationContract;
kernel: KernelContract;
/**
* Reference to the exit handler
*/
protected exitHandler?: () => void | Promise<void>;
/**
* Accepting AdonisJs application instance and kernel instance
*/
constructor(application: ApplicationContract, kernel: KernelContract);
/**
* Is the current command the main command executed from the
* CLI
*/
get isMain(): boolean;
/**
* Terminal is interactive
*/
get isInteractive(): boolean;
/**
* Command arguments
*/
static args: CommandArg[];
/**
* Command aliases
*/
static aliases: string[];
/**
* Command flags
*/
static flags: CommandFlag[];
/**
* Command name. The command will be registered using this name only. Make
* sure their aren't any spaces inside the command name.
*/
static commandName: string;
/**
* The description of the command displayed on the help screen.
* A good command will always have some description.
*/
static description: string;
/**
* Any settings a command wants to have. Helpful for third party
* tools to read the settings in lifecycle hooks and make
* certain decisions
*/
static settings: CommandSettings;
/**
* Whether or not the command has been booted
*/
static booted: boolean;
/**
* Boots the command by defining required static properties
*/
static boot(): void;
/**
* Define an argument directly on the command without using the decorator
*/
static $addArgument(options: Partial<CommandArg>): void;
/**
* Define a flag directly on the command without using the decorator
*/
static $addFlag(options: Partial<CommandFlag>): void;
/**
* Reference to cli ui
*/
ui: {
table: () => import("@poppinss/cliui/build/src/Table").Table;
tasks: {
(): import("@poppinss/cliui/build/src/Task/Manager").TaskManager;
verbose(): import("@poppinss/cliui/build/src/Task/Manager").TaskManager;
};
icons: {
tick: string;
cross: string;
bullet: string;
nodejs: string;
pointer: string;
info: string;
warning: string;
squareSmallFilled: string;
};
logger: import("@poppinss/cliui/build/src/Logger").Logger;
sticker: () => import("@poppinss/cliui/build/src/Instructions").Instructions;
instructions: () => import("@poppinss/cliui/build/src/Instructions").Instructions;
isInteractive: boolean;
supportsColors: boolean;
consoleRenderer: import("@poppinss/cliui/build/src/Renderer/Console").ConsoleRenderer;
testingRenderer: import("@poppinss/cliui/build/src/Renderer/Memory").MemoryRenderer;
};
/**
* Parsed options on the command. They only exist when the command
* is executed via kernel.
*/
parsed?: ParsedOptions;
/**
* The prompt for the command
*/
prompt: Prompt | FakePrompt;
/**
* Returns the instance of logger to log messages
*/
logger: import("@poppinss/cliui/build/src/Logger").Logger;
/**
* Reference to the colors
*/
colors: ReturnType<typeof instantiate>['logger']['colors'];
/**
* Generator instance to generate entity files
*/
generator: GeneratorContract;
/**
* Error raised by the command
*/
error?: any;
/**
* Command exit code
*/
exitCode?: number;
run?(...args: any[]): Promise<any>;
prepare?(...args: any[]): Promise<any>;
completed?(...args: any[]): Promise<any>;
/**
* Execute the command
*/
exec(): Promise<any>;
/**
* Register an onExit handler
*/
onExit(handler: () => void | Promise<void>): this;
/**
* Trigger exit
*/
exit(): Promise<void>;
/**
* Must be defined by the parent class
*/
handle?(...args: any[]): Promise<any>;
}
+195
View File
@@ -0,0 +1,195 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseCommand = void 0;
const prompts_1 = require("@poppinss/prompts");
const helpers_1 = require("@poppinss/utils/build/helpers");
const api_1 = require("@poppinss/cliui/build/api");
const utils_1 = require("@poppinss/utils");
const Generator_1 = require("../Generator");
/**
* Abstract base class other classes must extend
*/
class BaseCommand {
/**
* Accepting AdonisJs application instance and kernel instance
*/
constructor(application, kernel) {
this.application = application;
this.kernel = kernel;
/**
* Reference to cli ui
*/
this.ui = (0, api_1.instantiate)(this.kernel.isMockingConsoleOutput);
/**
* The prompt for the command
*/
this.prompt = this.kernel.isMockingConsoleOutput
? new prompts_1.FakePrompt()
: new prompts_1.Prompt();
/**
* Returns the instance of logger to log messages
*/
this.logger = this.ui.logger;
/**
* Reference to the colors
*/
this.colors = this.logger.colors;
/**
* Generator instance to generate entity files
*/
this.generator = new Generator_1.Generator(this);
}
/**
* Is the current command the main command executed from the
* CLI
*/
get isMain() {
return this.kernel.isMain(this);
}
/**
* Terminal is interactive
*/
get isInteractive() {
return this.kernel.isInteractive;
}
/**
* Boots the command by defining required static properties
*/
static boot() {
if (this.booted) {
return;
}
this.booted = true;
(0, utils_1.defineStaticProperty)(this, BaseCommand, {
propertyName: 'args',
defaultValue: [],
strategy: 'inherit',
});
(0, utils_1.defineStaticProperty)(this, BaseCommand, {
propertyName: 'aliases',
defaultValue: [],
strategy: 'inherit',
});
(0, utils_1.defineStaticProperty)(this, BaseCommand, {
propertyName: 'flags',
defaultValue: [],
strategy: 'inherit',
});
(0, utils_1.defineStaticProperty)(this, BaseCommand, {
propertyName: 'settings',
defaultValue: {},
strategy: 'inherit',
});
(0, utils_1.defineStaticProperty)(this, BaseCommand, {
propertyName: 'commandName',
defaultValue: '',
strategy: 'define',
});
(0, utils_1.defineStaticProperty)(this, BaseCommand, {
propertyName: 'description',
defaultValue: '',
strategy: 'define',
});
}
/**
* Define an argument directly on the command without using the decorator
*/
static $addArgument(options) {
if (!options.propertyName) {
throw new utils_1.Exception('"propertyName" is required to register a command argument', 500, 'E_MISSING_ARGUMENT_NAME');
}
const arg = Object.assign({
type: options.type || 'string',
propertyName: options.propertyName,
name: options.name || options.propertyName,
required: options.required === false ? false : true,
}, options);
this.args.push(arg);
}
/**
* Define a flag directly on the command without using the decorator
*/
static $addFlag(options) {
if (!options.propertyName) {
throw new utils_1.Exception('"propertyName" is required to register command flag', 500, 'E_MISSING_FLAG_NAME');
}
const flag = Object.assign({
name: options.name || helpers_1.string.snakeCase(options.propertyName).replace(/_/g, '-'),
propertyName: options.propertyName,
type: options.type || 'boolean',
}, options);
this.flags.push(flag);
}
/**
* Execute the command
*/
async exec() {
const hasRun = typeof this.run === 'function';
const hasHandle = typeof this.handle === 'function';
let commandResult;
/**
* Print depreciation warning
*/
if (hasHandle) {
process.emitWarning('DeprecationWarning', `${this.constructor.name}.handle() is deprecated. Define run() method instead`);
}
/**
* Run command and catch any raised exceptions
*/
try {
/**
* Run prepare method when exists on the command instance
*/
if (typeof this.prepare === 'function') {
await this.application.container.callAsync(this, 'prepare', []);
}
/**
* Execute the command handle or run method
*/
commandResult = await this.application.container.callAsync(this, hasRun ? 'run' : 'handle', []);
}
catch (error) {
this.error = error;
}
let errorHandled = false;
/**
* Run completed method when exists
*/
if (typeof this.completed === 'function') {
errorHandled = await this.application.container.callAsync(this, 'completed', []);
}
/**
* Throw error when error exists and the completed method didn't
* handled it
*/
if (this.error && !errorHandled) {
throw this.error;
}
return commandResult;
}
/**
* Register an onExit handler
*/
onExit(handler) {
this.exitHandler = handler;
return this;
}
/**
* Trigger exit
*/
async exit() {
if (typeof this.exitHandler === 'function') {
await this.exitHandler();
}
await this.kernel.exit(this);
}
}
exports.BaseCommand = BaseCommand;
+381
View File
@@ -0,0 +1,381 @@
import * as ui from '@poppinss/cliui';
import { ParsedOptions } from 'getopts';
import { PromptContract } from '@poppinss/prompts';
import { ApplicationContract, AppEnvironments } from '@ioc:Adonis/Core/Application';
/**
* Settings excepted by the command
*/
export declare type CommandSettings = {
loadApp?: boolean;
stayAlive?: boolean;
environment?: AppEnvironments;
} & {
[key: string]: any;
};
/**
* The types of flags can be defined on a command.
*/
export declare type FlagTypes = 'string' | 'number' | 'boolean' | 'array' | 'numArray';
/**
* The types of arguments can be defined on a command.
*/
export declare type ArgTypes = 'string' | 'spread';
/**
* The shape of command argument
*/
export declare type CommandArg = {
propertyName: string;
name: string;
type: ArgTypes;
required: boolean;
description?: string;
};
/**
* The shape of a command flag
*/
export declare type CommandFlag = {
propertyName: string;
name: string;
type: FlagTypes;
description?: string;
alias?: string;
};
/**
* The handler that handles the global
* flags
*/
export declare type GlobalFlagHandler = (value: any, parsed: ParsedOptions, command?: CommandConstructorContract) => any;
/**
* Shape of grouped commands. Required when displaying
* help
*/
export declare type CommandsGroup = {
group: string;
commands: SerializedCommand[];
}[];
/**
* The shared properties that exists on the command implementation
* as well as it's serialized version
*/
export declare type SerializedCommand = {
args: CommandArg[];
aliases: string[];
settings: CommandSettings;
flags: CommandFlag[];
commandName: string;
description: string;
};
/**
* Command constructor shape with it's static properties
*/
export interface CommandConstructorContract extends SerializedCommand {
new (application: ApplicationContract, kernel: KernelContract, ...args: any[]): CommandContract;
/**
* A boolean to know if the command has been booted or not. We initialize some
* static properties to the class during the boot process.
*/
booted: boolean;
/**
* Boot the command. You won't have to run this method by yourself. Ace will internally
* boot the commands by itself.
*/
boot(): void;
/**
* Add an argument directly on the command without using the decorator
*/
$addArgument(options: Partial<CommandArg>): void;
/**
* Add a flag directly on the command without using the decorator
*/
$addFlag(options: Partial<CommandFlag>): void;
}
/**
* The shape of command class
*/
export interface CommandContract {
parsed?: ParsedOptions;
error?: any;
exitCode?: number;
logger: typeof ui.logger;
prompt: PromptContract;
colors: typeof ui.logger.colors;
ui: typeof ui;
generator: GeneratorContract;
kernel: KernelContract;
/**
* The flag is set to true, when the command is executed as the main command
* from the terminal.
*
* However, set to false when command is executed programmatically.
*/
readonly isMain: boolean;
/**
* The flag is set to true, when the commandline is in interactive mode.
* Can be disabled manually via the kernel
*/
readonly isInteractive: boolean;
onExit(callback: () => Promise<void> | void): this;
exit(): Promise<void>;
exec(): Promise<any>;
handle?(...args: any[]): Promise<any>;
run?(...args: any[]): Promise<any>;
prepare?(...args: any[]): Promise<any>;
completed?(...args: any[]): Promise<any>;
}
/**
* Shape of the serialized command inside the manifest JSON file.
*/
export declare type ManifestCommand = SerializedCommand & {
commandPath: string;
};
/**
* Shape of defined aliases
*/
export declare type Aliases = {
[key: string]: string;
};
/**
* Shape of the manifest JSON file
*/
export declare type ManifestNode = {
commands: {
[command: string]: ManifestCommand;
};
aliases: Aliases;
};
/**
* Manifest loader interface
*/
export interface ManifestLoaderContract {
booted: boolean;
boot(): Promise<void>;
/**
* Returns the base path for a given command. Helps in loading
* the command relative from that path
*/
getCommandBasePath(commandName: string): string | undefined;
/**
* Returns manifest command node. One must load the command
* in order to use it
*/
getCommand(commandName: string): {
basePath: string;
command: ManifestCommand;
} | undefined;
/**
* Find if a command exists or not
*/
hasCommand(commandName: string): boolean;
/**
* Load command from the disk. Make sure to use [[hasCommand]] before
* calling this method
*/
loadCommand(commandName: string): Promise<CommandConstructorContract>;
/**
* Returns an array of manifest commands by concatenating the
* commands and aliases from all the manifest files
*/
getCommands(): {
commands: ManifestCommand[];
aliases: Aliases;
};
}
/**
* Callbacks for different style of hooks
*/
export declare type FindHookCallback = (command: SerializedCommand | null) => Promise<any> | any;
export declare type RunHookCallback = (command: CommandContract) => Promise<any> | any;
/**
* Shape of ace kernel
*/
export interface KernelContract {
/**
* The exit code to be used for exiting the process. One should use
* this to exit the process
*/
exitCode?: number;
/**
* Reference to the process error. It can come from the command, flags
* or any other intermediate code.
*/
error?: Error;
/**
* Reference to the default command. Feel free to overwrite it
*/
defaultCommand: CommandConstructorContract;
/**
* A map of locally registered commands
*/
commands: {
[name: string]: CommandConstructorContract;
};
/**
* Registered command aliases
*/
aliases: Aliases;
/**
* A map of global flags
*/
flags: {
[name: string]: CommandFlag & {
handler: GlobalFlagHandler;
};
};
/**
* Register before hooks
*/
before(action: 'run', callback: RunHookCallback): this;
before(action: 'find', callback: FindHookCallback): this;
before(action: 'run' | 'find', callback: RunHookCallback | FindHookCallback): this;
/**
* Register after hooks
*/
after(action: 'run', callback: RunHookCallback): this;
after(action: 'find', callback: FindHookCallback): this;
after(action: 'run' | 'find', callback: RunHookCallback | FindHookCallback): this;
/**
* Register a command directly via class
*/
register(commands: CommandConstructorContract[]): this;
/**
* Register a global flag
*/
flag(name: string, handler: GlobalFlagHandler, options: Partial<Exclude<CommandFlag, 'name' | 'propertyName'>>): this;
/**
* Register the manifest loader
*/
useManifest(manifestLoacder: ManifestLoaderContract): this;
/**
* Register an on exit callback listener. It should always
* exit the process
*/
onExit(callback: (kernel: this) => void | Promise<void>): this;
/**
* Preload the manifest file
*/
preloadManifest(): void;
/**
* Get command suggestions
*/
getSuggestions(name: string, distance?: number): string[];
/**
* Find a command using the command line `argv`
*/
find(argv: string[]): Promise<CommandConstructorContract | null>;
/**
* Run the default command
*/
runDefaultCommand(): Promise<any>;
/**
* Handle the command line argv to execute commands
*/
handle(args: string[]): Promise<any>;
/**
* Execute a command by its name and args
*/
exec(commandName: string, args: string[]): Promise<CommandContract>;
/**
* Print help for all commands or a given command
*/
printHelp(command?: CommandConstructorContract, commandsToAppend?: ManifestCommand[], aliasesToAppend?: Record<string, string>): void;
/**
* Find if a command is the main command. Main commands are executed
* directly from the terminal
*/
isMain(command: CommandContract): boolean;
/**
* Find if CLI process is interactive.
*/
isInteractive: boolean;
/**
* Toggle isInteractive state
*/
interactive(state: boolean): this;
/**
* Find if console output is mocked
*/
isMockingConsoleOutput: boolean;
/**
* Enforce mocking the console output. Command logs, tables, prompts
* will be mocked
*/
mockConsoleOutput(): this;
/**
* Trigger exit flow
*/
exit(command: CommandContract, error?: any): Promise<void>;
}
/**
* Template generator options
*/
export declare type GeneratorFileOptions = {
pattern?: 'pascalcase' | 'camelcase' | 'snakecase' | 'dashcase';
form?: 'singular' | 'plural';
formIgnoreList?: string[];
suffix?: string;
prefix?: string;
extname?: string;
};
/**
* Shape of the individual generator file
*/
export interface GeneratorFileContract {
state: 'persisted' | 'removed' | 'pending';
/**
* Define path to the stub template. You can also define inline text instead
* of relying on a template file, but do make sure to set `raw=true` inside
* the options when using inline text.
*/
stub(fileOrContents: string, options?: {
raw: boolean;
}): this;
/**
* Instruct to use mustache templating syntax, instead of template literals
*/
useMustache(): this;
/**
* The relative path to the destination directory.
*/
destinationDir(directory: string): this;
/**
* Define a custom application root. Otherwise `process.cwd()` is used.
*/
appRoot(directory: string): this;
/**
* Apply data to the stub
*/
apply(contents: any): this;
/**
* Get file properties as a JSON object
*/
toJSON(): {
filename: string;
filepath: string;
extension: string;
contents: string;
relativepath: string;
state: 'persisted' | 'removed' | 'pending';
};
}
/**
* Shape of the files generator
*/
export interface GeneratorContract {
/**
* Add a new file to the files generator. You can add multiple files
* together and they will be created when `run` is invoked.
*/
addFile(name: string, options?: GeneratorFileOptions): GeneratorFileContract;
/**
* Run the generator and create all files registered using `addFiles`
*/
run(): Promise<GeneratorFileContract[]>;
/**
* Clear the registered files from the generator
*/
clear(): void;
}
/**
* Filter function for filtering files during the `readdir` scan
*/
export declare type CommandsListFilterFn = ((name: string) => boolean) | string[];
+10
View File
@@ -0,0 +1,10 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
+12
View File
@@ -0,0 +1,12 @@
import { CommandArg } from '../Contracts';
export declare const args: {
/**
* Define argument that accepts string value
*/
string(options?: Partial<Omit<CommandArg, "type" | "propertyName">> | undefined): <TKey extends string, TTarget extends { [K in TKey]?: string | undefined; }>(target: TTarget, propertyName: TKey) => void;
/**
* Define argument that accepts multiple values. Must be
* the last argument.
*/
spread(options?: Partial<Omit<CommandArg, "type" | "propertyName">> | undefined): <TKey_1 extends string, TTarget_1 extends { [K_1 in TKey_1]?: string[] | undefined; }>(target: TTarget_1, propertyName: TKey_1) => void;
};
+37
View File
@@ -0,0 +1,37 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.args = void 0;
/**
* Adds arg to the list of command arguments with pre-defined
* type.
*/
function addArg(type, options) {
return function arg(target, propertyName) {
const Command = target.constructor;
Command.boot();
Command.$addArgument(Object.assign({ type, propertyName }, options));
};
}
exports.args = {
/**
* Define argument that accepts string value
*/
string(options) {
return addArg('string', options || {});
},
/**
* Define argument that accepts multiple values. Must be
* the last argument.
*/
spread(options) {
return addArg('spread', options || {});
},
};
+23
View File
@@ -0,0 +1,23 @@
import { CommandFlag } from '../Contracts';
export declare const flags: {
/**
* Create a flag that excepts string values
*/
string<T extends unknown>(options?: Partial<Omit<CommandFlag, "type" | "propertyName">> | undefined): <TKey extends string, TTarget extends { [K in TKey]: T; }>(target: TTarget, propertyName: TKey) => void;
/**
* Create a flag that excepts numeric values
*/
number<T_1 extends unknown>(options?: Partial<Omit<CommandFlag, "type" | "propertyName">> | undefined): <TKey_1 extends string, TTarget_1 extends { [K_1 in TKey_1]: T_1; }>(target: TTarget_1, propertyName: TKey_1) => void;
/**
* Create a flag that excepts boolean values
*/
boolean<T_2 extends unknown>(options?: Partial<Omit<CommandFlag, "type" | "propertyName">> | undefined): <TKey_2 extends string, TTarget_2 extends { [K_2 in TKey_2]: T_2; }>(target: TTarget_2, propertyName: TKey_2) => void;
/**
* Create a flag that excepts array of string values
*/
array<T_3 extends unknown>(options?: Partial<Omit<CommandFlag, "type" | "propertyName">> | undefined): <TKey_3 extends string, TTarget_3 extends { [K_3 in TKey_3]: T_3; }>(target: TTarget_3, propertyName: TKey_3) => void;
/**
* Create a flag that excepts array of numeric values
*/
numArray<T_4 extends unknown>(options?: Partial<Omit<CommandFlag, "type" | "propertyName">> | undefined): <TKey_4 extends string, TTarget_4 extends { [K_4 in TKey_4]: T_4; }>(target: TTarget_4, propertyName: TKey_4) => void;
};
+54
View File
@@ -0,0 +1,54 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.flags = void 0;
/**
* Pushes flag to the list of command flags with predefined
* types.
*/
function addFlag(type, options) {
return function flag(target, propertyName) {
const Command = target.constructor;
Command.boot();
Command.$addFlag(Object.assign({ type, propertyName }, options));
};
}
exports.flags = {
/**
* Create a flag that excepts string values
*/
string(options) {
return addFlag('string', options || {});
},
/**
* Create a flag that excepts numeric values
*/
number(options) {
return addFlag('number', options || {});
},
/**
* Create a flag that excepts boolean values
*/
boolean(options) {
return addFlag('boolean', options || {});
},
/**
* Create a flag that excepts array of string values
*/
array(options) {
return addFlag('array', options || {});
},
/**
* Create a flag that excepts array of numeric values
*/
numArray(options) {
return addFlag('numArray', options || {});
},
};
+58
View File
@@ -0,0 +1,58 @@
import { Exception } from '@poppinss/utils';
import { CommandConstructorContract } from '../Contracts';
/**
* Raised when a required argument is missing
*/
export declare class MissingArgumentException extends Exception {
command: CommandConstructorContract;
argumentName: string;
/**
* A required argument is missing
*/
static invoke(name: string, command: CommandConstructorContract): MissingArgumentException;
/**
* Handle itself
*/
handle(error: MissingArgumentException): void;
}
/**
* Raised when an the type of a flag is not as one of the excepted type
*/
export declare class InvalidFlagException extends Exception {
command?: CommandConstructorContract;
flagName: string;
expectedType: string;
/**
* Flag type validation failed.
*/
static invoke(prop: string, expected: string, command?: CommandConstructorContract): InvalidFlagException;
/**
* Handle itself
*/
handle(error: InvalidFlagException): void;
}
/**
* Raised when command is not registered with kernel
*/
export declare class InvalidCommandException extends Exception {
commandName: string;
suggestions: string[];
static invoke(commandName: string, suggestions: string[]): InvalidCommandException;
/**
* Handle itself
*/
handle(error: InvalidCommandException): void;
}
/**
* Raised when an unknown flag is defined
*/
export declare class UnknownFlagException extends Exception {
/**
* Unknown flag
*/
static invoke(prop: string): UnknownFlagException;
/**
* Handle itself
*/
handle(error: UnknownFlagException): void;
}
+118
View File
@@ -0,0 +1,118 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnknownFlagException = exports.InvalidCommandException = exports.InvalidFlagException = exports.MissingArgumentException = void 0;
const cliui_1 = require("@poppinss/cliui");
const utils_1 = require("@poppinss/utils");
/**
* Raised when a required argument is missing
*/
class MissingArgumentException extends utils_1.Exception {
/**
* A required argument is missing
*/
static invoke(name, command) {
const exception = new this(`Missing required argument "${name}"`, 500, 'E_MISSING_ARGUMENT');
exception.argumentName = name;
exception.command = command;
return exception;
}
/**
* Handle itself
*/
handle(error) {
cliui_1.logger.error(cliui_1.logger.colors.red(`Missing required argument "${error.argumentName}"`));
}
}
exports.MissingArgumentException = MissingArgumentException;
/**
* Raised when an the type of a flag is not as one of the excepted type
*/
class InvalidFlagException extends utils_1.Exception {
/**
* Flag type validation failed.
*/
static invoke(prop, expected, command) {
let article = 'a';
if (expected === 'number') {
expected = 'numeric';
}
if (expected === 'array') {
article = 'an';
expected = 'array of strings';
}
if (expected === 'numArray') {
article = 'an';
expected = 'array of numbers';
}
const exception = new this(`"${prop}" flag expects ${article} "${expected}" value`, 500, 'E_INVALID_FLAG');
exception.flagName = prop;
exception.command = command;
exception.expectedType = expected;
return exception;
}
/**
* Handle itself
*/
handle(error) {
cliui_1.logger.error(cliui_1.logger.colors.red(`Expected "--${error.flagName}" to be a valid "${error.expectedType}"`));
}
}
exports.InvalidFlagException = InvalidFlagException;
/**
* Raised when command is not registered with kernel
*/
class InvalidCommandException extends utils_1.Exception {
constructor() {
super(...arguments);
this.suggestions = [];
}
static invoke(commandName, suggestions) {
const exception = new this(`"${commandName}" is not a registered command`, 500, 'E_INVALID_COMMAND');
exception.commandName = commandName;
exception.suggestions = suggestions;
return exception;
}
/**
* Handle itself
*/
handle(error) {
cliui_1.logger.error(`"${error.commandName}" command not found`);
if (!error.suggestions.length) {
return;
}
cliui_1.logger.log('');
const suggestionLog = (0, cliui_1.sticker)().heading('Did you mean one of these?');
error.suggestions.forEach((commandName) => {
suggestionLog.add(cliui_1.logger.colors.yellow(commandName));
});
suggestionLog.render();
}
}
exports.InvalidCommandException = InvalidCommandException;
/**
* Raised when an unknown flag is defined
*/
class UnknownFlagException extends utils_1.Exception {
/**
* Unknown flag
*/
static invoke(prop) {
const exception = new this(`Unknown flag "${prop}"`, 500, 'E_INVALID_FLAG');
return exception;
}
/**
* Handle itself
*/
handle(error) {
cliui_1.logger.error(cliui_1.logger.colors.red(error.message));
}
}
exports.UnknownFlagException = UnknownFlagException;
+57
View File
@@ -0,0 +1,57 @@
import { GeneratorFileOptions, GeneratorFileContract } from '../Contracts';
/**
* Exposes the API to construct the output file content, path
* and template source.
*/
export declare class GeneratorFile implements GeneratorFileContract {
private name;
private options;
private stubContents;
private isStubRaw;
private templateData;
private customDestinationPath?;
private customAppRoot?;
private mustache;
state: 'persisted' | 'removed' | 'pending';
constructor(name: string, options?: GeneratorFileOptions);
/**
* Returns relative path for the file. Useful for
* printing log info
*/
private getFileRelativePath;
/**
* Set stub for the contents source. When `raw` is true, then string
* is considered as the raw content and not the file path.
*/
stub(fileOrContents: string, options?: {
raw: boolean;
}): this;
/**
* Optionally define destination directory from the project root.
*/
destinationDir(directory: string): this;
/**
* Define `appRoot`. This is just to shorten the logged
* file names. For example:
*/
appRoot(directory: string): this;
/**
* Instruct to use mustache
*/
useMustache(): this;
/**
* Variables for stub subsitution
*/
apply(contents: any): this;
/**
* Returns the file json
*/
toJSON(): {
filename: string;
filepath: string;
relativepath: string;
extension: string;
contents: any;
state: "persisted" | "removed" | "pending";
};
}
+129
View File
@@ -0,0 +1,129 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeneratorFile = void 0;
const path_1 = require("path");
const StringTransformer_1 = require("./StringTransformer");
const template_1 = require("../utils/template");
/**
* Exposes the API to construct the output file content, path
* and template source.
*/
class GeneratorFile {
constructor(name, options = {}) {
this.name = name;
this.options = options;
this.templateData = {};
this.mustache = false;
this.state = 'pending';
}
/**
* Returns relative path for the file. Useful for
* printing log info
*/
getFileRelativePath(filepath) {
if (this.customAppRoot) {
return filepath.replace(`${this.customAppRoot}${path_1.sep}`, '');
}
return filepath;
}
/**
* Set stub for the contents source. When `raw` is true, then string
* is considered as the raw content and not the file path.
*/
stub(fileOrContents, options) {
this.stubContents = fileOrContents;
this.isStubRaw = !!(options && options.raw);
return this;
}
/**
* Optionally define destination directory from the project root.
*/
destinationDir(directory) {
this.customDestinationPath = directory;
return this;
}
/**
* Define `appRoot`. This is just to shorten the logged
* file names. For example:
*/
appRoot(directory) {
this.customAppRoot = directory;
return this;
}
/**
* Instruct to use mustache
*/
useMustache() {
this.mustache = true;
return this;
}
/**
* Variables for stub subsitution
*/
apply(contents) {
this.templateData = contents;
return this;
}
/**
* Returns the file json
*/
toJSON() {
const extension = this.options.extname || '.ts';
const filename = new StringTransformer_1.StringTransformer((0, path_1.basename)(this.name))
.dropExtension()
.cleanSuffix(this.options.suffix)
.cleanPrefix(this.options.prefix)
.changeForm(this.options.form, this.options.formIgnoreList)
.addSuffix(this.options.suffix)
.addPrefix(this.options.prefix)
.changeCase(this.options.pattern)
.toValue();
const initialFilePath = this.name.replace((0, path_1.basename)(this.name), filename);
const appRoot = this.customAppRoot || process.cwd();
/**
* Computes the file absolute path, where the file will be created.
*
* 1. If `customDestinationPath` is not defined, we will merge the
* `appRoot` + `initialFilePath`.
*
* 2. If `customDestinationPath` is absolute, then we ignore the appRoot
* and merge `customDestinationPath` + `initialFilePath`
*
* 3. Otherwise we merge `appRoot` + `customDestinationPath` + `initialFilePath`.
*/
const filepath = this.customDestinationPath
? (0, path_1.isAbsolute)(this.customDestinationPath)
? (0, path_1.join)(this.customDestinationPath, initialFilePath)
: (0, path_1.join)(appRoot, this.customDestinationPath, initialFilePath)
: (0, path_1.join)(appRoot, initialFilePath);
/**
* Passing user values + the filename and extension
*/
const templateContents = Object.assign({ extension, filename }, this.templateData);
/**
* Contents of the template file
*/
const contents = this.stubContents
? this.isStubRaw
? (0, template_1.template)(this.stubContents, templateContents, undefined, this.mustache)
: (0, template_1.templateFromFile)(this.stubContents, templateContents, this.mustache)
: '';
return {
filename,
filepath: `${filepath}${extension}`,
relativepath: this.getFileRelativePath(`${filepath}${extension}`),
extension,
contents,
state: this.state,
};
}
}
exports.GeneratorFile = GeneratorFile;
+40
View File
@@ -0,0 +1,40 @@
/**
* Exposes the API to transform a string
*/
export declare class StringTransformer {
private input;
constructor(input: string);
/**
* Cleans suffix from the input.
*/
cleanSuffix(suffix?: string): this;
/**
* Cleans prefix from the input.
*/
cleanPrefix(prefix?: string): this;
/**
* Add suffix to the file name
*/
addSuffix(suffix?: string): this;
/**
* Add prefix to the file name
*/
addPrefix(prefix?: string): this;
/**
* Changes the name form by converting it to singular
* or plural case
*/
changeForm(form?: 'singular' | 'plural', ignoreList?: string[]): this;
/**
* Changes the input case
*/
changeCase(pattern?: 'pascalcase' | 'camelcase' | 'snakecase' | 'dashcase'): this;
/**
* Drops the extension from the input
*/
dropExtension(): this;
/**
* Returns the transformed value
*/
toValue(): string;
}
+114
View File
@@ -0,0 +1,114 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.StringTransformer = void 0;
const path_1 = require("path");
const helpers_1 = require("@poppinss/utils/build/helpers");
/**
* Exposes the API to transform a string
*/
class StringTransformer {
constructor(input) {
this.input = input;
}
/**
* Cleans suffix from the input.
*/
cleanSuffix(suffix) {
if (!suffix) {
return this;
}
this.input = this.input.replace(new RegExp(`[-_]?${suffix}$`, 'i'), '');
return this;
}
/**
* Cleans prefix from the input.
*/
cleanPrefix(prefix) {
if (!prefix) {
return this;
}
this.input = this.input.replace(new RegExp(`^${prefix}[-_]?`, 'i'), '');
return this;
}
/**
* Add suffix to the file name
*/
addSuffix(suffix) {
if (!suffix) {
return this;
}
this.input = `${this.input}_${suffix}`;
return this;
}
/**
* Add prefix to the file name
*/
addPrefix(prefix) {
if (!prefix) {
return this;
}
this.input = `${prefix}_${this.input}`;
return this;
}
/**
* Changes the name form by converting it to singular
* or plural case
*/
changeForm(form, ignoreList) {
if (!form) {
return this;
}
/**
* Do not change form when word is in ignore list
*/
if ((ignoreList || []).find((word) => word.toLowerCase() === this.input.toLowerCase())) {
return this;
}
this.input = form === 'singular' ? helpers_1.string.singularize(this.input) : helpers_1.string.pluralize(this.input);
return this;
}
/**
* Changes the input case
*/
changeCase(pattern) {
switch (pattern) {
case 'camelcase':
this.input = helpers_1.string.camelCase(this.input);
return this;
case 'pascalcase':
const camelCase = helpers_1.string.camelCase(this.input);
this.input = `${camelCase.charAt(0).toUpperCase()}${camelCase.slice(1)}`;
return this;
case 'snakecase':
this.input = helpers_1.string.snakeCase(this.input);
return this;
case 'dashcase':
this.input = helpers_1.string.dashCase(this.input);
return this;
default:
return this;
}
}
/**
* Drops the extension from the input
*/
dropExtension() {
this.input = this.input.replace(new RegExp(`${(0, path_1.extname)(this.input)}$`), '');
return this;
}
/**
* Returns the transformed value
*/
toValue() {
return this.input;
}
}
exports.StringTransformer = StringTransformer;
+25
View File
@@ -0,0 +1,25 @@
import { GeneratorFile } from './File';
import { GeneratorFileOptions, GeneratorContract, CommandContract } from '../Contracts';
/**
* Exposes the API to generate entity files, like project
* `Controllers`, `Models` and so on.
*/
export declare class Generator implements GeneratorContract {
private command;
private destinationDir?;
private files;
constructor(command: CommandContract, destinationDir?: string | undefined);
/**
* Add a new file to the files generator. You can add multiple files
* together and they will be created when `run` is invoked.
*/
addFile(name: string, options?: GeneratorFileOptions): GeneratorFile;
/**
* Run the generator and create all files registered using `addFiles`
*/
run(): Promise<GeneratorFile[]>;
/**
* Clear the registered files from the generator
*/
clear(): void;
}
+61
View File
@@ -0,0 +1,61 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Generator = void 0;
const fs_extra_1 = require("fs-extra");
const File_1 = require("./File");
/**
* Exposes the API to generate entity files, like project
* `Controllers`, `Models` and so on.
*/
class Generator {
constructor(command, destinationDir) {
this.command = command;
this.destinationDir = destinationDir;
this.files = [];
}
/**
* Add a new file to the files generator. You can add multiple files
* together and they will be created when `run` is invoked.
*/
addFile(name, options) {
const file = new File_1.GeneratorFile(name, options);
if (this.destinationDir) {
file.destinationDir(this.destinationDir);
}
this.files.push(file);
return file;
}
/**
* Run the generator and create all files registered using `addFiles`
*/
async run() {
for (let file of this.files) {
const fileJSON = file.toJSON();
const exists = await (0, fs_extra_1.pathExists)(fileJSON.filepath);
if (exists) {
this.command.logger.action('create').skipped(fileJSON.relativepath, 'File already exists');
}
else {
await (0, fs_extra_1.outputFile)(fileJSON.filepath, fileJSON.contents);
file.state = 'persisted';
this.command.logger.action('create').succeeded(fileJSON.relativepath);
}
}
return this.files;
}
/**
* Clear the registered files from the generator
*/
clear() {
this.files = [];
}
}
exports.Generator = Generator;
+10
View File
@@ -0,0 +1,10 @@
import { BaseCommand } from '../BaseCommand';
import { CommandContract } from '../Contracts';
/**
* The help command for print the help output
*/
export declare class HelpCommand extends BaseCommand implements CommandContract {
static commandName: string;
static description: string;
run(): Promise<void>;
}
+23
View File
@@ -0,0 +1,23 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelpCommand = void 0;
const BaseCommand_1 = require("../BaseCommand");
/**
* The help command for print the help output
*/
class HelpCommand extends BaseCommand_1.BaseCommand {
async run() {
this.kernel.printHelp();
}
}
exports.HelpCommand = HelpCommand;
HelpCommand.commandName = 'help';
HelpCommand.description = 'See help for all the commands';
+14
View File
@@ -0,0 +1,14 @@
/**
* Exposes the API to register and execute async hooks
*/
export declare class Hooks {
private hooks;
/**
* Register hook for a given action and lifecycle
*/
add(lifecycle: 'before' | 'after', action: string, handler: (...args: any[]) => void | Promise<void>): this;
/**
* Execute hooks for a given action and lifecycle
*/
execute(lifecycle: 'before' | 'after', action: string, data: any): Promise<void>;
}
+48
View File
@@ -0,0 +1,48 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hooks = void 0;
/**
* Exposes the API to register and execute async hooks
*/
class Hooks {
constructor() {
this.hooks = {
before: new Map(),
after: new Map(),
};
}
/**
* Register hook for a given action and lifecycle
*/
add(lifecycle, action, handler) {
const handlers = this.hooks[lifecycle].get(action);
if (handlers) {
handlers.push(handler);
}
else {
this.hooks[lifecycle].set(action, [handler]);
}
return this;
}
/**
* Execute hooks for a given action and lifecycle
*/
async execute(lifecycle, action, data) {
const handlers = this.hooks[lifecycle].get(action);
if (!handlers) {
return;
}
for (let handler of handlers) {
await handler(data);
}
}
}
exports.Hooks = Hooks;
+180
View File
@@ -0,0 +1,180 @@
import { ApplicationContract } from '@ioc:Adonis/Core/Application';
import { ManifestLoader } from '../Manifest/Loader';
import { CommandFlag, KernelContract, CommandContract, ManifestCommand, RunHookCallback, FindHookCallback, GlobalFlagHandler, CommandConstructorContract } from '../Contracts';
/**
* Ace kernel class is used to register, find and invoke commands by
* parsing `process.argv.splice(2)` value.
*/
export declare class Kernel implements KernelContract {
application: ApplicationContract;
/**
* Reference to hooks class to execute lifecycle
* hooks
*/
private hooks;
/**
* Reference to the manifest loader. If defined, we will give preference
* to the manifest files.
*/
private manifestLoader;
/**
* The command that started the process
*/
private entryCommand?;
/**
* The state of the kernel
*/
private state;
/**
* Exit handler for gracefully exiting the process
*/
private exitHandler;
/**
* Find if CLI process is interactive. This flag can be
* toggled programmatically
*/
isInteractive: boolean;
/**
* Find if console output is mocked
*/
isMockingConsoleOutput: boolean;
/**
* The default command that will be invoked when no command is
* defined
*/
defaultCommand: CommandConstructorContract;
/**
* List of registered commands
*/
commands: {
[name: string]: CommandConstructorContract;
};
aliases: {
[alias: string]: string;
};
/**
* List of registered flags
*/
flags: {
[name: string]: CommandFlag & {
handler: GlobalFlagHandler;
};
};
/**
* The exit code for the process
*/
exitCode?: number;
/**
* The error collected as part of the running commands or executing
* flags
*/
error?: any;
constructor(application: ApplicationContract);
/**
* Executing global flag handlers. The global flag handlers are
* not async as of now, but later we can look into making them
* async.
*/
private executeGlobalFlagsHandlers;
/**
* Returns an array of all registered commands
*/
private getAllCommandsAndAliases;
/**
* Processes the args and sets values on the command instance
*/
private processCommandArgsAndFlags;
/**
* Execute the main command. For calling commands within commands,
* one must call "kernel.exec".
*/
private execMain;
/**
* Handles exiting the process
*/
private exitProcess;
/**
* Register a before hook
*/
before(action: 'run', callback: RunHookCallback): this;
before(action: 'find', callback: FindHookCallback): this;
/**
* Register an after hook
*/
after(action: 'run', callback: RunHookCallback): this;
after(action: 'find', callback: FindHookCallback): this;
/**
* Register an array of command constructors
*/
register(commands: CommandConstructorContract[]): this;
/**
* Register a global flag. It can be defined in combination with
* any command.
*/
flag(name: string, handler: GlobalFlagHandler, options: Partial<Exclude<CommandFlag, 'name' | 'propertyName'>>): this;
/**
* Use manifest instance to lazy load commands
*/
useManifest(manifestLoader: ManifestLoader): this;
/**
* Register an exit handler
*/
onExit(callback: (kernel: this) => void | Promise<void>): this;
/**
* Returns an array of command names suggestions for a given name.
*/
getSuggestions(name: string, distance?: number): string[];
/**
* Preload the manifest file. Re-running this method twice will
* result in a noop
*/
preloadManifest(): Promise<void>;
/**
* Finds the command from the command line argv array. If command for
* the given name doesn't exists, then it will return `null`.
*
* Does executes the before and after hooks regardless of whether the
* command has been found or not
*/
find(argv: string[]): Promise<CommandConstructorContract | null>;
/**
* Run the default command. The default command doesn't accept
* and args or flags.
*/
runDefaultCommand(): Promise<any>;
/**
* Find if a command is the main command. Main commands are executed
* directly from the terminal.
*/
isMain(command: CommandContract): boolean;
/**
* Enforce mocking the console output. Command logs, tables, prompts
* will be mocked
*/
mockConsoleOutput(): this;
/**
* Toggle interactive state
*/
interactive(state: boolean): this;
/**
* Execute a command as a sub-command. Do not call "handle" and
* always use this method to invoke command programatically
*/
exec(commandName: string, args: string[]): Promise<CommandContract>;
/**
* Makes instance of a given command by processing command line arguments
* and setting them on the command instance
*/
handle(argv: string[]): Promise<void>;
/**
* Print the help screen for a given command or all commands/flags
*/
printHelp(command?: CommandConstructorContract, commandsToAppend?: ManifestCommand[], aliasesToAppend?: Record<string, string>): void;
/**
* Trigger kernel to exit the process. The call to this method
* is ignored when command is not same the `entryCommand`.
*
* In other words, subcommands cannot trigger exit
*/
exit(command: CommandContract, error?: any): Promise<void>;
}
+609
View File
@@ -0,0 +1,609 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Kernel = void 0;
const Hooks_1 = require("../Hooks");
const Parser_1 = require("../Parser");
const HelpCommand_1 = require("../HelpCommand");
const Exceptions_1 = require("../Exceptions");
const help_1 = require("../utils/help");
const validateCommand_1 = require("../utils/validateCommand");
const cliui_1 = require("@poppinss/cliui");
/**
* Ace kernel class is used to register, find and invoke commands by
* parsing `process.argv.splice(2)` value.
*/
class Kernel {
constructor(application) {
this.application = application;
/**
* Reference to hooks class to execute lifecycle
* hooks
*/
this.hooks = new Hooks_1.Hooks();
/**
* The state of the kernel
*/
this.state = 'idle';
/**
* Exit handler for gracefully exiting the process
*/
this.exitHandler = (kernel) => {
if (kernel.error && typeof kernel.error.handle === 'function') {
kernel.error.handle(kernel.error);
}
else if (kernel.error) {
cliui_1.logger.fatal(kernel.error);
}
process.exit(kernel.exitCode === undefined ? 0 : kernel.exitCode);
};
/**
* Find if CLI process is interactive. This flag can be
* toggled programmatically
*/
this.isInteractive = cliui_1.isInteractive;
/**
* Find if console output is mocked
*/
this.isMockingConsoleOutput = false;
/**
* The default command that will be invoked when no command is
* defined
*/
this.defaultCommand = HelpCommand_1.HelpCommand;
/**
* List of registered commands
*/
this.commands = {};
this.aliases = this.application.rcFile.commandsAliases;
/**
* List of registered flags
*/
this.flags = {};
}
/**
* Executing global flag handlers. The global flag handlers are
* not async as of now, but later we can look into making them
* async.
*/
executeGlobalFlagsHandlers(argv, command) {
const globalFlags = Object.keys(this.flags);
const parsedOptions = new Parser_1.Parser(this.flags).parse(argv, command);
globalFlags.forEach((name) => {
const value = parsedOptions[name];
/**
* Flag was not specified
*/
if (value === undefined) {
return;
}
/**
* Calling the handler
*/
this.flags[name].handler(parsedOptions[name], parsedOptions, command);
});
}
/**
* Returns an array of all registered commands
*/
getAllCommandsAndAliases() {
let commands = Object.keys(this.commands).map((name) => this.commands[name]);
let aliases = {};
/**
* Concat manifest commands when they exists
*/
if (this.manifestLoader && this.manifestLoader.booted) {
const { commands: manifestCommands, aliases: manifestAliases } = this.manifestLoader.getCommands();
commands = commands.concat(manifestCommands);
aliases = Object.assign(aliases, manifestAliases);
}
return {
commands,
aliases: Object.assign(aliases, this.aliases),
};
}
/**
* Processes the args and sets values on the command instance
*/
async processCommandArgsAndFlags(commandInstance, args) {
const parser = new Parser_1.Parser(this.flags);
const command = commandInstance.constructor;
/**
* Parse the command arguments. The `parse` method will raise exception if flag
* or arg is not
*/
const parsedOptions = parser.parse(args, command);
/**
* We validate the command arguments after the global flags have been
* executed. It is required, since flags may have nothing to do
* with the validaty of command itself
*/
command.args.forEach((arg, index) => {
parser.validateArg(arg, index, parsedOptions, command);
});
/**
* Creating a new command instance and setting
* parsed options on it.
*/
commandInstance.parsed = parsedOptions;
/**
* Setup command instance argument and flag
* properties.
*/
for (let i = 0; i < command.args.length; i++) {
const arg = command.args[i];
const defaultValue = commandInstance[arg.propertyName];
if (arg.type === 'spread') {
const value = parsedOptions._.slice(i);
/**
* Set the property value to arguments defined via the CLI
* If no arguments are supplied, then use the default value assigned to the class property
* If the default value is undefined, then assign an empty array
*/
commandInstance[arg.propertyName] = value.length
? value
: defaultValue !== undefined
? defaultValue
: [];
break;
}
else {
const value = parsedOptions._[i];
commandInstance[arg.propertyName] = value !== undefined ? value : defaultValue;
}
}
/**
* Set flag value on the command instance
*/
for (let flag of command.flags) {
const flagValue = parsedOptions[flag.name];
if (flagValue !== undefined) {
commandInstance[flag.propertyName] = flagValue;
}
}
}
/**
* Execute the main command. For calling commands within commands,
* one must call "kernel.exec".
*/
async execMain(commandName, args) {
const command = await this.find([commandName]);
/**
* Command not found. So execute global flags handlers and
* raise an exception
*/
if (!command) {
this.executeGlobalFlagsHandlers(args);
throw Exceptions_1.InvalidCommandException.invoke(commandName, this.getSuggestions(commandName));
}
/**
* Make an instance of the command
*/
const commandInstance = await this.application.container.makeAsync(command, [
this.application,
this,
]);
/**
* Execute global flags
*/
this.executeGlobalFlagsHandlers(args, command);
/**
* Process the arguments and flags for the command
*/
await this.processCommandArgsAndFlags(commandInstance, args);
/**
* Keep a reference to the entry command. So that we know if we
* want to entertain `.exit` or not
*/
this.entryCommand = commandInstance;
/**
* Execute before run hooks
*/
await this.hooks.execute('before', 'run', commandInstance);
/**
* Execute command
*/
return commandInstance.exec();
}
/**
* Handles exiting the process
*/
async exitProcess(error) {
/**
* Check for state to avoid exiting the process multiple times
*/
if (this.state === 'completed') {
return;
}
this.state = 'completed';
/**
* Re-assign error if entry command exists and has error
*/
if (!error && this.entryCommand && this.entryCommand.error) {
error = this.entryCommand.error;
}
/**
* Execute the after run hooks. Wrapping inside try/catch since this is the
* cleanup handler for the process and must handle all exceptions
*/
try {
if (this.entryCommand) {
await this.hooks.execute('after', 'run', this.entryCommand);
}
}
catch (hookError) {
error = hookError;
}
/**
* Assign error to the kernel instance
*/
if (error) {
this.error = error;
}
/**
* Figure out the exit code for the process
*/
const exitCode = error ? 1 : 0;
const commandExitCode = this.entryCommand && this.entryCommand.exitCode;
this.exitCode = commandExitCode === undefined ? exitCode : commandExitCode;
try {
await this.exitHandler(this);
}
catch (exitHandlerError) {
cliui_1.logger.warning('Expected exit handler to exit the process. Instead it raised an exception');
cliui_1.logger.fatal(exitHandlerError);
}
}
before(action, callback) {
this.hooks.add('before', action, callback);
return this;
}
after(action, callback) {
this.hooks.add('after', action, callback);
return this;
}
/**
* Register an array of command constructors
*/
register(commands) {
commands.forEach((command) => {
command.boot();
(0, validateCommand_1.validateCommand)(command);
this.commands[command.commandName] = command;
/**
* Registering command aliaes
*/
command.aliases.forEach((alias) => (this.aliases[alias] = command.commandName));
});
return this;
}
/**
* Register a global flag. It can be defined in combination with
* any command.
*/
flag(name, handler, options) {
this.flags[name] = Object.assign({
name,
propertyName: name,
handler,
type: 'boolean',
}, options);
return this;
}
/**
* Use manifest instance to lazy load commands
*/
useManifest(manifestLoader) {
this.manifestLoader = manifestLoader;
return this;
}
/**
* Register an exit handler
*/
onExit(callback) {
this.exitHandler = callback;
return this;
}
/**
* Returns an array of command names suggestions for a given name.
*/
getSuggestions(name, distance = 3) {
const leven = require('leven');
const { commands, aliases } = this.getAllCommandsAndAliases();
const suggestions = commands
.filter(({ commandName }) => leven(name, commandName) <= distance)
.map(({ commandName }) => commandName);
return suggestions.concat(Object.keys(aliases).filter((alias) => leven(name, alias) <= distance));
}
/**
* Preload the manifest file. Re-running this method twice will
* result in a noop
*/
async preloadManifest() {
/**
* Load manifest commands when instance of manifest loader exists.
*/
if (this.manifestLoader) {
await this.manifestLoader.boot();
}
}
/**
* Finds the command from the command line argv array. If command for
* the given name doesn't exists, then it will return `null`.
*
* Does executes the before and after hooks regardless of whether the
* command has been found or not
*/
async find(argv) {
/**
* ----------------------------------------------------------------------------
* Even though in `Unix` the command name may appear in between or at last, with
* ace we always want the command name to be the first argument. However, the
* arguments to the command itself can appear in any sequence. For example:
*
* Works
* - node ace make:controller foo
* - node ace make:controller --http foo
*
* Doesn't work
* - node ace foo make:controller
* ----------------------------------------------------------------------------
*/
const [commandName] = argv;
/**
* Command name from the registered aliases
*/
const aliasCommandName = this.aliases[commandName];
/**
* Manifest commands gets preference over manually registered commands.
*
* - We check the manifest loader is register
* - The manifest loader has the command
* - Or the manifest loader has the alias command
*/
const commandNode = this.manifestLoader
? this.manifestLoader.hasCommand(commandName)
? this.manifestLoader.getCommand(commandName)
: this.manifestLoader.hasCommand(aliasCommandName)
? this.manifestLoader.getCommand(aliasCommandName)
: undefined
: undefined;
if (commandNode) {
commandNode.command.aliases = commandNode.command.aliases || [];
if (aliasCommandName && !commandNode.command.aliases.includes(commandName)) {
commandNode.command.aliases.push(commandName);
}
await this.hooks.execute('before', 'find', commandNode.command);
const command = await this.manifestLoader.loadCommand(commandNode.command.commandName);
await this.hooks.execute('after', 'find', command);
return command;
}
else {
/**
* Try to find command inside manually registered command or fallback
* to null
*/
const command = this.commands[commandName] || this.commands[aliasCommandName] || null;
/**
* Share main command name as an alias with the command
*/
if (command) {
command.aliases = command.aliases || [];
if (aliasCommandName && !command.aliases.includes(commandName)) {
command.aliases.push(commandName);
}
}
/**
* Executing before and after together to be compatible
* with the manifest find before and after hooks
*/
await this.hooks.execute('before', 'find', command);
await this.hooks.execute('after', 'find', command);
return command;
}
}
/**
* Run the default command. The default command doesn't accept
* and args or flags.
*/
async runDefaultCommand() {
this.defaultCommand.boot();
(0, validateCommand_1.validateCommand)(this.defaultCommand);
/**
* Execute before/after find hooks
*/
await this.hooks.execute('before', 'find', this.defaultCommand);
await this.hooks.execute('after', 'find', this.defaultCommand);
/**
* Make the command instance using the container
*/
const commandInstance = await this.application.container.makeAsync(this.defaultCommand, [
this.application,
this,
]);
/**
* Execute before run hook
*/
await this.hooks.execute('before', 'run', commandInstance);
/**
* Keep a reference to the entry command
*/
this.entryCommand = commandInstance;
/**
* Execute the command
*/
return commandInstance.exec();
}
/**
* Find if a command is the main command. Main commands are executed
* directly from the terminal.
*/
isMain(command) {
return !!this.entryCommand && this.entryCommand === command;
}
/**
* Enforce mocking the console output. Command logs, tables, prompts
* will be mocked
*/
mockConsoleOutput() {
this.isMockingConsoleOutput = true;
return this;
}
/**
* Toggle interactive state
*/
interactive(state) {
this.isInteractive = state;
return this;
}
/**
* Execute a command as a sub-command. Do not call "handle" and
* always use this method to invoke command programatically
*/
async exec(commandName, args) {
const command = await this.find([commandName]);
/**
* Command not found.
*/
if (!command) {
throw Exceptions_1.InvalidCommandException.invoke(commandName, this.getSuggestions(commandName));
}
/**
* Make an instance of command and keep a reference of it as `this.entryCommand`
*/
const commandInstance = await this.application.container.makeAsync(command, [
this.application,
this,
]);
/**
* Process args and flags for the command
*/
await this.processCommandArgsAndFlags(commandInstance, args);
let commandError;
/**
* Wrapping the command execution inside a try/catch, so that
* we can run the after hooks regardless of success or
* failure
*/
try {
await this.hooks.execute('before', 'run', commandInstance);
await commandInstance.exec();
}
catch (error) {
commandError = error;
}
/**
* Execute after hooks
*/
await this.hooks.execute('after', 'run', commandInstance);
/**
* Re-throw error (if any)
*/
if (commandError) {
throw commandError;
}
return commandInstance;
}
/**
* Makes instance of a given command by processing command line arguments
* and setting them on the command instance
*/
async handle(argv) {
if (this.state !== 'idle') {
return;
}
this.state = 'running';
try {
/**
* Preload the manifest file to load the manifest files
*/
this.preloadManifest();
/**
* Branch 1
* Run default command and invoke the exit handler
*/
if (!argv.length) {
await this.runDefaultCommand();
await this.exitProcess();
return;
}
/**
* Branch 2
* No command has been mentioned and hence execute all the global flags
* invoke the exit handler
*/
const hasMentionedCommand = !argv[0].startsWith('-');
if (!hasMentionedCommand) {
this.executeGlobalFlagsHandlers(argv);
await this.exitProcess();
return;
}
/**
* Branch 3
* Execute the given command as the main command
*/
const [commandName, ...args] = argv;
await this.execMain(commandName, args);
/**
* Exit the process if there isn't any entry command
*/
if (!this.entryCommand) {
await this.exitProcess();
return;
}
const entryCommandConstructor = this.entryCommand.constructor;
/**
* Exit the process if entry command isn't a stayalive command. Stayalive
* commands should call `this.exit` to exit the process.
*/
if (!entryCommandConstructor.settings.stayAlive) {
await this.exitProcess();
}
}
catch (error) {
await this.exitProcess(error);
}
}
/**
* Print the help screen for a given command or all commands/flags
*/
printHelp(command, commandsToAppend, aliasesToAppend) {
let { commands, aliases } = this.getAllCommandsAndAliases();
/**
* Append additional commands and aliases for help screen only
*/
if (commandsToAppend) {
commands = commands.concat(commandsToAppend);
}
if (aliasesToAppend) {
aliases = Object.assign({}, aliases, aliasesToAppend);
}
if (command) {
(0, help_1.printHelpFor)(command, aliases);
}
else {
const flags = Object.keys(this.flags).map((name) => this.flags[name]);
(0, help_1.printHelp)(commands, flags, aliases);
}
}
/**
* Trigger kernel to exit the process. The call to this method
* is ignored when command is not same the `entryCommand`.
*
* In other words, subcommands cannot trigger exit
*/
async exit(command, error) {
if (command !== this.entryCommand) {
return;
}
await this.exitProcess(error);
}
}
exports.Kernel = Kernel;
+29
View File
@@ -0,0 +1,29 @@
/**
* Exposes the API to generate the ace manifest file. The manifest file
* contains the meta data of all the registered commands. This speeds
* up the boot cycle of ace
*/
export declare class ManifestGenerator {
private basePath;
private commands;
/**
* Here we keep track of processed command files to prevent loops. Mainly when using
* listDirectoryFiles to export command paths from directory and not excluding current file.
*/
private processedFiles;
constructor(basePath: string, commands: string[]);
/**
* Loads a given command from the disk. A command line can recursively
* exposed sub command paths. But they should be resolvable using
* the base path
*/
private loadCommand;
/**
* Loads all the commands from the disk recursively.
*/
private loadCommands;
/**
* Generates and writes the ace manifest file to the base path
*/
generate(): Promise<void>;
}
+96
View File
@@ -0,0 +1,96 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ManifestGenerator = void 0;
const fs_extra_1 = require("fs-extra");
const path_1 = require("path");
const utils_1 = require("@poppinss/utils");
const helpers_1 = require("@poppinss/utils/build/helpers");
const validateCommand_1 = require("../utils/validateCommand");
/**
* Exposes the API to generate the ace manifest file. The manifest file
* contains the meta data of all the registered commands. This speeds
* up the boot cycle of ace
*/
class ManifestGenerator {
constructor(basePath, commands) {
this.basePath = basePath;
this.commands = commands;
/**
* Here we keep track of processed command files to prevent loops. Mainly when using
* listDirectoryFiles to export command paths from directory and not excluding current file.
*/
this.processedFiles = new Set();
}
/**
* Loads a given command from the disk. A command line can recursively
* exposed sub command paths. But they should be resolvable using
* the base path
*/
async loadCommand(commandPath) {
if ((0, path_1.isAbsolute)(commandPath)) {
throw new utils_1.Exception('Absolute path to a command is not allowed when generating the manifest file');
}
const resolvedPath = (0, helpers_1.resolveFrom)(this.basePath, commandPath);
if (this.processedFiles.has(resolvedPath)) {
return [];
}
const commandOrSubCommandsPaths = (0, utils_1.esmRequire)(resolvedPath);
this.processedFiles.add(resolvedPath);
if (Array.isArray(commandOrSubCommandsPaths)) {
return this.loadCommands(commandOrSubCommandsPaths);
}
/**
* File export has command constructor
*/
(0, validateCommand_1.validateCommand)(commandOrSubCommandsPaths, commandPath);
return [
{
command: commandOrSubCommandsPaths,
commandPath,
},
];
}
/**
* Loads all the commands from the disk recursively.
*/
async loadCommands(commandPaths) {
let commands = [];
for (const commandPath of commandPaths) {
const command = await this.loadCommand(commandPath);
commands = commands.concat(command);
}
return commands;
}
/**
* Generates and writes the ace manifest file to the base path
*/
async generate() {
const commands = await this.loadCommands(this.commands);
const manifest = commands.reduce((result, { command, commandPath }) => {
const manifestNode = {
settings: command.settings || {},
commandPath: commandPath.replace(new RegExp(`${(0, path_1.extname)(commandPath)}$`), ''),
commandName: command.commandName,
description: command.description,
args: command.args,
aliases: command.aliases,
flags: command.flags,
};
result.commands[command.commandName] = manifestNode;
command.aliases.forEach((alias) => {
result.aliases[alias] = command.commandName;
});
return result;
}, { commands: {}, aliases: {} });
await (0, fs_extra_1.outputJSON)((0, path_1.join)(this.basePath, 'ace-manifest.json'), manifest, { spaces: 2 });
}
}
exports.ManifestGenerator = ManifestGenerator;
+57
View File
@@ -0,0 +1,57 @@
import { Aliases, ManifestCommand, ManifestLoaderContract, CommandConstructorContract } from '../Contracts';
/**
* The manifest loader exposes the API to load ace commands from one
* or more manifest files.
*/
export declare class ManifestLoader implements ManifestLoaderContract {
private files;
/**
* An array of defined manifest files
*/
private manifestFiles;
booted: boolean;
constructor(files: {
basePath: string;
manifestAbsPath: string;
}[]);
/**
* Loads the manifest file from the disk
*/
private loadManifestFile;
/**
* Returns the command manifest node for a give command
*/
private getCommandManifest;
/**
* Boot manifest loader to read all manifest files from the disk
*/
boot(): Promise<void>;
/**
* Returns base path for a given command
*/
getCommandBasePath(commandName: string): string | undefined;
/**
* Returns manifest command node. One must load the command
* in order to use it
*/
getCommand(commandName: string): {
basePath: string;
command: ManifestCommand;
} | undefined;
/**
* Find if a command exists or not
*/
hasCommand(commandName: string): boolean;
/**
* Load command from the disk. Make sure to use [[hasCommand]] before
* calling this method
*/
loadCommand(commandName: string): Promise<CommandConstructorContract>;
/**
* Returns an array of manifest commands
*/
getCommands(): {
commands: ManifestCommand[];
aliases: Aliases;
};
}
+112
View File
@@ -0,0 +1,112 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ManifestLoader = void 0;
const fs_extra_1 = require("fs-extra");
const utils_1 = require("@poppinss/utils");
const helpers_1 = require("@poppinss/utils/build/helpers");
const validateCommand_1 = require("../utils/validateCommand");
/**
* The manifest loader exposes the API to load ace commands from one
* or more manifest files.
*/
class ManifestLoader {
constructor(files) {
this.files = files;
/**
* An array of defined manifest files
*/
this.manifestFiles = [];
this.booted = false;
}
/**
* Loads the manifest file from the disk
*/
async loadManifestFile(file) {
const manifestCommands = await (0, fs_extra_1.readJSON)(file.manifestAbsPath);
/**
* Find if we are dealing with an old or the new manifest file
*/
const isNewManifestFile = manifestCommands['commands'] && manifestCommands['aliases'];
const commands = isNewManifestFile ? manifestCommands['commands'] : manifestCommands;
const aliases = isNewManifestFile ? manifestCommands['aliases'] : {};
return { basePath: file.basePath, commands, aliases };
}
/**
* Returns the command manifest node for a give command
*/
getCommandManifest(commandName) {
return this.manifestFiles.find(({ commands, aliases }) => {
const aliasCommandName = aliases[commandName];
return commands[commandName] || commands[aliasCommandName];
});
}
/**
* Boot manifest loader to read all manifest files from the disk
*/
async boot() {
if (this.booted) {
return;
}
this.booted = true;
this.manifestFiles = await Promise.all(this.files.map((file) => this.loadManifestFile(file)));
}
/**
* Returns base path for a given command
*/
getCommandBasePath(commandName) {
return this.getCommandManifest(commandName)?.basePath;
}
/**
* Returns manifest command node. One must load the command
* in order to use it
*/
getCommand(commandName) {
const manifestCommands = this.getCommandManifest(commandName);
if (!manifestCommands) {
return;
}
const aliasCommandName = manifestCommands.aliases[commandName];
const command = manifestCommands.commands[commandName] || manifestCommands.commands[aliasCommandName];
return {
basePath: manifestCommands.basePath,
command: command,
};
}
/**
* Find if a command exists or not
*/
hasCommand(commandName) {
return !!this.getCommandBasePath(commandName);
}
/**
* Load command from the disk. Make sure to use [[hasCommand]] before
* calling this method
*/
async loadCommand(commandName) {
const { basePath, command } = this.getCommand(commandName);
const commandConstructor = (0, utils_1.esmRequire)((0, helpers_1.resolveFrom)(basePath, command.commandPath));
(0, validateCommand_1.validateCommand)(commandConstructor);
return commandConstructor;
}
/**
* Returns an array of manifest commands
*/
getCommands() {
return this.manifestFiles.reduce((result, { commands, aliases }) => {
Object.keys(commands).forEach((commandName) => {
result.commands = result.commands.concat(commands[commandName]);
});
Object.assign(result.aliases, aliases);
return result;
}, { commands: [], aliases: {} });
}
}
exports.ManifestLoader = ManifestLoader;
+80
View File
@@ -0,0 +1,80 @@
import getopts from 'getopts';
import { CommandArg, CommandFlag, GlobalFlagHandler, CommandConstructorContract } from '../Contracts';
/**
* The job of the parser is to parse the command line values by taking
* the command `args`, `flags` and `globalFlags` into account.
*/
export declare class Parser {
private registeredFlags;
constructor(registeredFlags: {
[name: string]: CommandFlag & {
handler: GlobalFlagHandler;
};
});
/**
* Validate all the flags against the flags registered by the command
* or as global flags and disallow unknown flags.
*/
private scanForUnknownFlags;
/**
* Processes ace command flag to set the options for `getopts`.
* We just define the `alias` with getopts coz their default,
* string and boolean options produces the behavior we don't
* want.
*/
private preProcessFlag;
/**
* Casts a flag value to a boolean. The casting logic is driven
* by the behavior of "getopts"
*/
private castToBoolean;
/**
* Cast the value to a string. The casting logic is driven
* by the behavior of "getopts"
*
* - Convert numbers to string
* - Do not convert boolean to a string, since a flag without a value
* gets a boolean value, which is invalid
*/
private castToString;
/**
* Cast value to an array of string. The casting logic is driven
* by the behavior of "getopts"
*
* - Numeric values are converted to string of array
* - A string value is splitted by comma and trimmed.
* - An array is casted to an array of string values
*/
private castToArray;
/**
* Cast value to an array of numbers. The casting logic is driven
* by the behavior of "getopts".
*
* - Numeric values are wrapped to an array.
* - String is splitted by comma and each value is casted to a number
* - Each array value is casted to a number.
*/
private castToNumArray;
/**
* Cast value to a number. The casting logic is driven
* by the behavior of "getopts"
*
* - Boolean values are not allowed
* - A string is converted to a number
*/
private castToNumer;
/**
* Casts value of a flag to it's expected data type. These values
* are then later validated to ensure that casting was successful.
*/
processFlag(flag: CommandFlag, parsed: getopts.ParsedOptions, command?: CommandConstructorContract): void;
/**
* Validates the value to ensure that values are defined for
* required arguments.
*/
validateArg(arg: CommandArg, index: number, parsed: getopts.ParsedOptions, command: CommandConstructorContract): void;
/**
* Parses argv and executes the command and global flags handlers
*/
parse(argv: string[], command?: CommandConstructorContract): getopts.ParsedOptions;
}
+287
View File
@@ -0,0 +1,287 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
const getopts_1 = __importDefault(require("getopts"));
const Exceptions_1 = require("../Exceptions");
/**
* The job of the parser is to parse the command line values by taking
* the command `args`, `flags` and `globalFlags` into account.
*/
class Parser {
constructor(registeredFlags) {
this.registeredFlags = registeredFlags;
}
/**
* Validate all the flags against the flags registered by the command
* or as global flags and disallow unknown flags.
*/
scanForUnknownFlags(parsed, flagsAndAliases) {
Object.keys(parsed).forEach((key) => {
if (key === '_') {
return;
}
const hasFlag = flagsAndAliases.find((value) => value === key);
if (!hasFlag) {
throw Exceptions_1.UnknownFlagException.invoke(key);
}
});
}
/**
* Processes ace command flag to set the options for `getopts`.
* We just define the `alias` with getopts coz their default,
* string and boolean options produces the behavior we don't
* want.
*/
preProcessFlag(flag, options) {
/**
* Register alias (when exists)
*/
if (flag.alias) {
options.alias[flag.alias] = flag.name;
}
}
/**
* Casts a flag value to a boolean. The casting logic is driven
* by the behavior of "getopts"
*/
castToBoolean(value) {
if (typeof value === 'boolean') {
return value;
}
if (value === 'true' || value === '=true') {
return true;
}
return undefined;
}
/**
* Cast the value to a string. The casting logic is driven
* by the behavior of "getopts"
*
* - Convert numbers to string
* - Do not convert boolean to a string, since a flag without a value
* gets a boolean value, which is invalid
*/
castToString(value) {
if (typeof value === 'number') {
value = String(value);
}
if (typeof value === 'string' && value.trim()) {
return value;
}
return undefined;
}
/**
* Cast value to an array of string. The casting logic is driven
* by the behavior of "getopts"
*
* - Numeric values are converted to string of array
* - A string value is splitted by comma and trimmed.
* - An array is casted to an array of string values
*/
castToArray(value) {
if (typeof value === 'number') {
value = String(value);
}
if (typeof value === 'string') {
return value.split(',').filter((prop) => prop.trim());
}
if (Array.isArray(value)) {
/**
* This will also convert numeric values to a string. The behavior
* is same as string flag type.
*/
return value.map((prop) => String(prop));
}
return undefined;
}
/**
* Cast value to an array of numbers. The casting logic is driven
* by the behavior of "getopts".
*
* - Numeric values are wrapped to an array.
* - String is splitted by comma and each value is casted to a number
* - Each array value is casted to a number.
*/
castToNumArray(value) {
if (typeof value === 'number') {
return [value];
}
if (typeof value === 'string') {
return value.split(',').map((one) => Number(one));
}
if (Array.isArray(value)) {
return value.map((prop) => Number(prop));
}
return undefined;
}
/**
* Cast value to a number. The casting logic is driven
* by the behavior of "getopts"
*
* - Boolean values are not allowed
* - A string is converted to a number
*/
castToNumer(value) {
if (typeof value === 'number') {
return value;
}
if (typeof value === 'string') {
// Possibility of NaN here
return Number(value);
}
return undefined;
}
/**
* Casts value of a flag to it's expected data type. These values
* are then later validated to ensure that casting was successful.
*/
processFlag(flag, parsed, command) {
let value = parsed[flag.name];
/**
* Check for the value with the alias, if it undefined
* by the name
*/
if (value === undefined && flag.alias) {
value = parsed[flag.alias];
}
/**
* Still undefined??
*
* It is fine. Flags are optional anyways
*/
if (value === undefined) {
return;
}
/**
* Handle boolean values. It should be a valid boolean
* data type or a string value of `'true'`.
*/
if (flag.type === 'boolean') {
value = this.castToBoolean(value);
if (value === undefined) {
throw Exceptions_1.InvalidFlagException.invoke(flag.name, flag.type, command);
}
}
/**
* Handle string value. It should be a valid and not empty.
* Either remove the flag or provide a value
*/
if (flag.type === 'string') {
value = this.castToString(value);
if (value === undefined) {
throw Exceptions_1.InvalidFlagException.invoke(flag.name, flag.type, command);
}
}
/**
* Handle numeric values. The flag should have a value and
* a valid number.
*/
if (flag.type === 'number') {
value = this.castToNumer(value);
if (value === undefined || isNaN(value)) {
throw Exceptions_1.InvalidFlagException.invoke(flag.name, flag.type, command);
}
}
/**
* Parse the value to be an array of strings
*/
if (flag.type === 'array') {
value = this.castToArray(value);
if (!value || !value.length) {
throw Exceptions_1.InvalidFlagException.invoke(flag.name, flag.type, command);
}
}
/**
* Parse the value to be an array of numbers
*/
if (flag.type === 'numArray') {
value = this.castToNumArray(value);
if (!value || !value.length) {
throw Exceptions_1.InvalidFlagException.invoke(flag.name, flag.type, command);
}
/**
* Find if array has NaN values
*/
if (value.findIndex((one) => isNaN(one)) > -1) {
throw Exceptions_1.InvalidFlagException.invoke(flag.name, flag.type, command);
}
}
parsed[flag.name] = value;
if (flag.alias) {
parsed[flag.alias] = value;
}
}
/**
* Validates the value to ensure that values are defined for
* required arguments.
*/
validateArg(arg, index, parsed, command) {
const value = parsed._[index];
if (value === undefined && arg.required) {
throw Exceptions_1.MissingArgumentException.invoke(arg.name, command);
}
}
/**
* Parses argv and executes the command and global flags handlers
*/
parse(argv, command) {
let options = { alias: {}, boolean: [], default: {}, string: [] };
const flagsAndAliases = [];
const globalFlags = Object.keys(this.registeredFlags).map((name) => this.registeredFlags[name]);
/**
* Build options from global flags
*/
globalFlags.forEach((flag) => {
this.preProcessFlag(flag, options);
flagsAndAliases.push(flag.name);
flag.alias && flagsAndAliases.push(flag.alias);
});
/**
* Build options from command flags
*/
if (command) {
command.flags.forEach((flag) => {
this.preProcessFlag(flag, options);
flagsAndAliases.push(flag.name);
flag.alias && flagsAndAliases.push(flag.alias);
});
}
/**
* Parsing argv with the previously built options
*/
const parsed = (0, getopts_1.default)(argv, options);
/**
* Scan and report unknown flag as exception
*/
if (command) {
this.scanForUnknownFlags(parsed, flagsAndAliases);
}
/**
* Validating global flags (if any)
*/
globalFlags.forEach((flag) => {
this.processFlag(flag, parsed);
});
/**
* Validating command flags (if command is defined)
*/
if (command) {
command.flags.forEach((flag) => {
this.processFlag(flag, parsed);
});
}
return parsed;
}
}
exports.Parser = Parser;
+4
View File
@@ -0,0 +1,4 @@
/**
* Handles the command errors and prints them to the console.
*/
export declare function handleError(error: any, callback?: (error: any) => void | Promise<void>): void;
+28
View File
@@ -0,0 +1,28 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleError = void 0;
const cliui_1 = require("@poppinss/cliui");
/**
* Handles the command errors and prints them to the console.
*/
// eslint-disable-next-line no-shadow
function handleError(error, callback) {
if (typeof callback === 'function') {
callback(error);
}
else if (typeof error.handle === 'function') {
error.handle(error);
}
else {
cliui_1.logger.fatal(error);
}
}
exports.handleError = handleError;
+10
View File
@@ -0,0 +1,10 @@
import { Aliases, CommandFlag, SerializedCommand } from '../Contracts';
/**
* Prints help for all the commands by sorting them in alphabetical order
* and grouping them as per their namespace.
*/
export declare function printHelp(commands: SerializedCommand[], flags: CommandFlag[], aliases: Aliases): void;
/**
* Prints help for a single command
*/
export declare function printHelpFor(command: SerializedCommand, aliases: Aliases): void;
+270
View File
@@ -0,0 +1,270 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.printHelpFor = exports.printHelp = void 0;
const cliui_1 = require("@poppinss/cliui");
const term_size_1 = __importDefault(require("term-size"));
const sortAndGroupCommands_1 = require("./sortAndGroupCommands");
/**
* Converts a line to rows at a specific width
*/
function lineToRows(text, width) {
const rows = [];
let row = [];
let wordsCount = 0;
text.split(' ').forEach((word) => {
if (wordsCount + (word.length + 1) > width) {
/**
* Push the number of whitespace left after the existing current
* and the terminal space. We need to do this, coz we at times
* have whitespace when the upcoming word may break into next
* lines
*/
row.push(new Array(width - wordsCount + 1).join(' '));
/**
* Push the existing row to the rows
*/
rows.push(row.join(' '));
/**
* Row is empty now
*/
row = [];
/**
* Row has zero words
*/
wordsCount = 0;
}
/**
* Increase the words count + 1. The extra one is for the
* whitspace between the words
*/
wordsCount += word.length + 1;
/**
* Collect word inside the row
*/
row.push(word);
});
/**
* Handle the orphan row
*/
if (row.length) {
rows.push(row.join(' '));
}
return rows;
}
/**
* Converts the description to multiple lines fitting into
* a given column size
*/
function descriptionToRows(description, options) {
return lineToRows(description, options.descriptionColumnsSize)
.map((column, index) => {
return index > 0 ? `${new Array(options.nameColumnSize + 1).join(' ')}${column}` : column;
})
.join('');
}
/**
* Wraps the command arg inside `<>` or `[]` brackets based upon if it's
* required or not.
*/
function wrapArg(arg) {
const displayName = arg.type === 'spread' ? `...${arg.name}` : arg.name;
return arg.required ? `<${displayName}>` : `[${displayName}]`;
}
/**
* Returns an array of flags for displaying the help screen
*/
function getFlagsForDisplay(flags) {
return flags.map(({ name, type, alias, description }) => {
/**
* Display name is the way we want to display a single flag in the
* list of flags
*/
const displayName = alias ? `-${alias}, --${name}` : `--${name}`;
/**
* The type hints the user about the expectation on the flag type. We only
* print the type, when flag is not a boolean.
*/
let displayType = '';
switch (type) {
case 'array':
displayType = 'string[]';
break;
case 'numArray':
displayType = 'number[]';
break;
case 'string':
displayType = 'string';
break;
case 'boolean':
displayType = 'boolean';
break;
case 'number':
displayType = 'number';
break;
}
return {
displayName,
displayType,
description,
width: displayName.length + displayType.length,
};
});
}
/**
* Returns an array of args for displaying the help screen
*/
function getArgsForDisplay(args) {
return args.map(({ name, description }) => {
return {
displayName: name,
description: description,
width: name.length,
};
});
}
/**
* Returns an array of commands for display
*/
function getCommandsForDisplay(commands, aliases) {
return commands.map(({ commandName, description }) => {
const commandAliases = getCommandAliases(commandName, aliases);
const aliasesString = commandAliases.length ? ` [${commandAliases.join(', ')}]` : '';
return {
displayName: `${commandName}${aliasesString}`,
description,
width: commandName.length + aliasesString.length,
};
});
}
/**
* Returns the aliases for a given command
*/
function getCommandAliases(commandName, aliases) {
return Object.keys(aliases).reduce((commandAliases, alias) => {
if (aliases[alias] === commandName) {
commandAliases.push(alias);
}
return commandAliases;
}, []);
}
/**
* Prints help for all the commands by sorting them in alphabetical order
* and grouping them as per their namespace.
*/
function printHelp(commands, flags, aliases) {
const flagsList = getFlagsForDisplay(flags);
const commandsList = getCommandsForDisplay(commands, aliases);
/**
* Get width of longest command name.
*/
const maxWidth = Math.max.apply(Math, flagsList.concat(commandsList).map(({ width }) => width));
/**
* Size of the terminal columns. Max width is the width of the command
* name and the extra four is whitespace around the command name.
*
* This gives the columns size for the description section
*/
const descriptionColumnsSize = (0, term_size_1.default)().columns - (maxWidth + 4);
/**
* Sort commands and group them, so that we can print them as per
* the namespace they belongs to
*/
(0, sortAndGroupCommands_1.sortAndGroupCommands)(commands).forEach(({ group, commands: groupCommands }) => {
console.log('');
if (group === 'root') {
console.log(cliui_1.logger.colors.bold(cliui_1.logger.colors.yellow('Available commands')));
}
else {
console.log(cliui_1.logger.colors.bold(cliui_1.logger.colors.yellow(group)));
}
groupCommands.forEach(({ commandName, description }) => {
const commandAliases = getCommandAliases(commandName, aliases);
const aliasesString = commandAliases.length ? ` [${commandAliases.join(', ')}]` : '';
const displayName = `${commandName}${aliasesString}`;
const whiteSpace = ''.padEnd(maxWidth - displayName.length, ' ');
const descriptionRows = descriptionToRows(description, {
nameColumnSize: maxWidth + 4,
descriptionColumnsSize,
});
console.log(` ${cliui_1.logger.colors.green(displayName)} ${whiteSpace} ${cliui_1.logger.colors.dim(descriptionRows)}`);
});
});
if (flagsList.length) {
console.log('');
console.log(cliui_1.logger.colors.bold(cliui_1.logger.colors.yellow('Global Flags')));
flagsList.forEach(({ displayName, displayType, description = '', width }) => {
const whiteSpace = ''.padEnd(maxWidth - width, ' ');
const descriptionRows = descriptionToRows(description, {
nameColumnSize: maxWidth + 4,
descriptionColumnsSize,
});
console.log(` ${cliui_1.logger.colors.green(displayName)} ${cliui_1.logger.colors.dim(displayType)}${whiteSpace} ${cliui_1.logger.colors.dim(descriptionRows)}`);
});
}
}
exports.printHelp = printHelp;
/**
* Prints help for a single command
*/
function printHelpFor(command, aliases) {
if (command.description) {
console.log('');
console.log(command.description);
}
console.log('');
console.log(`${cliui_1.logger.colors.yellow('Usage:')} ${command.commandName} ${cliui_1.logger.colors.dim(command.args.map(wrapArg).join(' '))}`);
const flags = getFlagsForDisplay(command.flags);
const args = getArgsForDisplay(command.args);
/**
* Getting max width to keep flags and args symmetric
*/
const maxWidth = Math.max.apply(Math, flags.concat(args).map(({ width }) => width));
/**
* Size of the terminal columns. Max width is the width of the command
* name and the extra four is whitespace around the command name.
*
* This gives the columns size for the description section
*/
const descriptionColumnsSize = (0, term_size_1.default)().columns - (maxWidth + 5);
const commandAliases = getCommandAliases(command.commandName, aliases);
if (commandAliases.length) {
console.log('');
console.log(`${cliui_1.logger.colors.yellow('Aliases:')} ${cliui_1.logger.colors.green(commandAliases.join(', '))}`);
}
if (args.length) {
console.log('');
console.log(cliui_1.logger.colors.bold(cliui_1.logger.colors.yellow('Arguments')));
args.forEach(({ displayName, description = '', width }) => {
const whiteSpace = ''.padEnd(maxWidth - width, ' ');
const descriptionRow = descriptionToRows(description, {
nameColumnSize: maxWidth + 5,
descriptionColumnsSize,
});
console.log(` ${cliui_1.logger.colors.green(displayName)} ${whiteSpace} ${cliui_1.logger.colors.dim(descriptionRow)}`);
});
}
if (flags.length) {
console.log('');
console.log(cliui_1.logger.colors.bold(cliui_1.logger.colors.yellow('Flags')));
flags.forEach(({ displayName, displayType, description = '', width }) => {
const whiteSpace = ''.padEnd(maxWidth - width, ' ');
const descriptionRow = descriptionToRows(description, {
nameColumnSize: maxWidth + 5,
descriptionColumnsSize,
});
console.log(` ${cliui_1.logger.colors.green(displayName)} ${cliui_1.logger.colors.dim(displayType)}${whiteSpace} ${cliui_1.logger.colors.dim(descriptionRow)}`);
});
}
}
exports.printHelpFor = printHelpFor;
+6
View File
@@ -0,0 +1,6 @@
import { CommandsListFilterFn } from '../Contracts';
/**
* Returns an array of Javascript files inside the current directory in
* relative to the application root.
*/
export declare function listDirectoryFiles(scanDirectory: string, appRoot: string, filesToIgnore?: CommandsListFilterFn): string[];
+48
View File
@@ -0,0 +1,48 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.listDirectoryFiles = void 0;
const slash_1 = __importDefault(require("slash"));
const path_1 = require("path");
const helpers_1 = require("@poppinss/utils/build/helpers");
/**
* Checks if the file exists inside the array. Also an extension
* agnostic check is performed to handle `.ts` and `.js` files
* both
*/
function filesFilter(fileName, filesToIgnore) {
if (filesToIgnore.includes(fileName)) {
return true;
}
fileName = fileName.replace((0, path_1.extname)(fileName), '');
return filesToIgnore.includes(fileName);
}
/**
* Returns an array of Javascript files inside the current directory in
* relative to the application root.
*/
function listDirectoryFiles(scanDirectory, appRoot, filesToIgnore) {
return (0, helpers_1.fsReadAll)(scanDirectory)
.filter((name) => !name.endsWith('.json')) // remove .json files
.map((name) => {
const relativePath = (0, path_1.relative)(appRoot, (0, path_1.join)(scanDirectory, name));
return (0, slash_1.default)(relativePath.startsWith('../') ? relativePath : `./${relativePath}`);
})
.filter((name) => {
if (typeof filesToIgnore === 'function') {
return filesToIgnore(name);
}
return Array.isArray(filesToIgnore) ? !filesFilter(name, filesToIgnore) : true;
});
}
exports.listDirectoryFiles = listDirectoryFiles;
+7
View File
@@ -0,0 +1,7 @@
import { CommandsGroup, SerializedCommand } from '../Contracts';
/**
* Loops over the commands and converts them to an array of sorted groups with
* nested commands inside them. The grouping is done using the command
* namespace seperated with `:`. Example: `make:controller`
*/
export declare function sortAndGroupCommands(commands: SerializedCommand[]): CommandsGroup;
+67
View File
@@ -0,0 +1,67 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.sortAndGroupCommands = void 0;
/**
* Loops over the commands and converts them to an array of sorted groups with
* nested commands inside them. The grouping is done using the command
* namespace seperated with `:`. Example: `make:controller`
*/
function sortAndGroupCommands(commands) {
/**
* Create a group of commands using it's namespace
*/
const groupsLiteral = commands.reduce((result, command) => {
const tokens = command.commandName.split(':');
/**
* Use the command namespace or move it inside the `root` group when
* it is not namespaced.
*/
const group = tokens.length > 1 ? tokens.shift() : 'root';
result[group] = result[group] || [];
result[group].push(command);
return result;
}, {});
/**
* Convert the object literal groups and it's command to an
* array of sorted groups and commands
*/
return Object.keys(groupsLiteral)
.sort((prev, curr) => {
if (prev === 'root') {
return -1;
}
if (curr === 'root') {
return 1;
}
if (curr > prev) {
return -1;
}
if (curr < prev) {
return 1;
}
return 0;
})
.map((name) => {
return {
group: name,
commands: groupsLiteral[name].sort((prev, curr) => {
if (curr.commandName > prev.commandName) {
return -1;
}
if (curr.commandName < prev.commandName) {
return 1;
}
return 0;
}),
};
});
}
exports.sortAndGroupCommands = sortAndGroupCommands;
+10
View File
@@ -0,0 +1,10 @@
/**
* Process string as a template literal string and processes
* data
*/
export declare function template(tpl: string, data: Object, filename?: string, isMustache?: boolean): any;
/**
* Loads template file from the disk and process it contents
* using the [[template]] method
*/
export declare function templateFromFile(file: string, data: object, isMustache: boolean): string;
+56
View File
@@ -0,0 +1,56 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.templateFromFile = exports.template = void 0;
const vm_1 = require("vm");
const mustache_1 = __importDefault(require("mustache"));
const fs_1 = require("fs");
const STACK_REGEXP = /evalmachine\.<anonymous>:(\d+)(?::(\d+))?\n/;
const STACK_REGEXP_ALL = new RegExp(STACK_REGEXP.source, 'g');
/**
* Process string as a template literal string and processes
* data
*/
function template(tpl, data, filename = 'eval', isMustache = false) {
if (isMustache) {
return mustache_1.default.render(tpl, data);
}
try {
return (0, vm_1.runInNewContext)('`' + tpl + '`', data);
}
catch (error) {
const positions = error.stack.match(STACK_REGEXP_ALL);
if (!positions) {
throw error;
}
const position = [filename];
const tokens = positions.pop().match(STACK_REGEXP);
if (tokens[1]) {
position.push(tokens[1]);
}
if (tokens[2]) {
position.push(tokens[2]);
}
throw new Error(`Error in template ${position.join(':')}\n${error.message}`);
}
}
exports.template = template;
/**
* Loads template file from the disk and process it contents
* using the [[template]] method
*/
function templateFromFile(file, data, isMustache) {
const contents = (0, fs_1.readFileSync)(file, 'utf8');
return template(contents, data, file, isMustache);
}
exports.templateFromFile = templateFromFile;
+6
View File
@@ -0,0 +1,6 @@
import { CommandConstructorContract } from '../Contracts';
/**
* Validates the command static properties to ensure that all the
* values are correctly defined for a command to be executed.
*/
export declare function validateCommand(command: any, commandPath?: string): asserts command is CommandConstructorContract;
+60
View File
@@ -0,0 +1,60 @@
"use strict";
/*
* @adonisjs/ace
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateCommand = void 0;
const utils_1 = require("@poppinss/utils");
/**
* Validates the command static properties to ensure that all the
* values are correctly defined for a command to be executed.
*/
function validateCommand(command, commandPath) {
if (!command.name) {
throw new utils_1.Exception(`Invalid command"${commandPath ? ` ${commandPath}` : ''}". Make sure the command is exported using the "export default"`);
}
/**
* Ensure command has a name, a boot method and args property
*/
if (!command.commandName || typeof command.boot !== 'function') {
throw new utils_1.Exception(`Invalid command "${command.name}". Make sure to define the static property "commandName"`);
}
/**
* Boot command
*/
command.boot();
/**
* Ensure command has args and flags after the boot method
*/
if (!Array.isArray(command.args) || !Array.isArray(command.flags)) {
throw new utils_1.Exception(`Invalid command "${command.name}". Make sure it extends the BaseCommand`);
}
let optionalArg;
/**
* Validate for optional args and spread args
*/
command.args.forEach((arg, index) => {
/**
* Ensure optional arguments comes after required
* arguments
*/
if (optionalArg && arg.required) {
throw new utils_1.Exception(`Optional argument "${optionalArg.name}" must be after the required argument "${arg.name}"`);
}
/**
* Ensure spread arg is the last arg
*/
if (arg.type === 'spread' && command.args.length > index + 1) {
throw new utils_1.Exception(`Spread argument "${arg.name}" must be at last position`);
}
if (!arg.required) {
optionalArg = arg;
}
});
}
exports.validateCommand = validateCommand;
+9
View File
@@ -0,0 +1,9 @@
# The MIT License
Copyright 2021 Harminder Virk, contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
export * from './src/Helpers';
@@ -0,0 +1,25 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./src/Helpers"), exports);

Some files were not shown because too many files have changed in this diff Show More