Initial commit
This commit is contained in:
commit
0c01712341
193
.gitignore
vendored
Normal file
193
.gitignore
vendored
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
# ---> JetBrains
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
# ---> Node
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
/lib
|
||||||
|
/exbuild
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
40
.idea/codeStyles/Project.xml
Normal file
40
.idea/codeStyles/Project.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<JSCodeStyleSettings version="0">
|
||||||
|
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
|
||||||
|
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||||
|
<option name="USE_DOUBLE_QUOTES" value="false" />
|
||||||
|
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||||
|
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
|
||||||
|
<option name="OBJECT_LITERAL_WRAP" value="2" />
|
||||||
|
</JSCodeStyleSettings>
|
||||||
|
<TypeScriptCodeStyleSettings version="0">
|
||||||
|
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
|
||||||
|
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||||
|
<option name="USE_DOUBLE_QUOTES" value="false" />
|
||||||
|
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||||
|
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
|
||||||
|
<option name="OBJECT_LITERAL_WRAP" value="2" />
|
||||||
|
</TypeScriptCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="JavaScript">
|
||||||
|
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||||
|
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||||
|
<option name="METHOD_CALL_CHAIN_WRAP" value="2" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="3" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="3" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="TypeScript">
|
||||||
|
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||||
|
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||||
|
<option name="METHOD_CALL_CHAIN_WRAP" value="2" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="3" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="3" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
10
.idea/extollo.iml
Normal file
10
.idea/extollo.iml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="di" />
|
||||||
|
<orderEntry type="module" module-name="lib" />
|
||||||
|
</component>
|
||||||
|
</module>
|
10
.idea/modules.xml
Normal file
10
.idea/modules.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/../di/.idea/di.iml" filepath="$PROJECT_DIR$/../di/.idea/di.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/extollo.iml" filepath="$PROJECT_DIR$/.idea/extollo.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/../extollo_lib/.idea/lib.iml" filepath="$PROJECT_DIR$/../extollo_lib/.idea/lib.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
7
.idea/vcs.xml
Normal file
7
.idea/vcs.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/../extollo_lib" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
0
CONTRIBUTING.md
Normal file
0
CONTRIBUTING.md
Normal file
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright © 2021 Garrett Mills
|
||||||
|
|
||||||
|
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.
|
31
README.md
Normal file
31
README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<center>
|
||||||
|
<br>
|
||||||
|
<img alt="The Extollo logo" src="https://static.garrettmills.dev/sites/extollo/docs/assets/logo/svg/Extollo-Icon-and-Text-LIGHT-Final.svg" height="150">
|
||||||
|
<br><br>
|
||||||
|
<b>extollo</b> - (v. <em>latin</em>) - to lift up, to elevate
|
||||||
|
<br><br>
|
||||||
|
Extollo is a <a href="https://www.gnu.org/philosophy/floss-and-foss.en.html" target="_blank">free & libre</a> application framework in TypeScript.
|
||||||
|
</center>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
Built on principles of modularity, strict-typing, inversion-of-control, and developer ergonomics, Extollo enables developers to build maintainable, scalable, and expressive applications.
|
||||||
|
|
||||||
|
Node.js provides an excellent platform for quickly getting an application up and running, but this loose minimalism can lead to larger, more unweildy code-bases as your application grows. Extollo fixes this by providing an opinionated, robust framework and first-party modules that provide, among other things:
|
||||||
|
|
||||||
|
- Type-based dependency injection
|
||||||
|
- Strongly-typed ORM with an expressive query-builder and models
|
||||||
|
- Customizable session & caching interfaces
|
||||||
|
- Modular, pre-compiled, nest-able routes
|
||||||
|
- First-party, extensible command line tools
|
||||||
|
- Unit-based application structure
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
Writing an application with Extollo is very straightforward if you are familiar with Node.js/TypeScript, or similar frameworks like Laravel.
|
||||||
|
|
||||||
|
Check out the [Getting Started](https://extollo.garrettmills.dev/pages/Documentation/Getting-Started.html) page on the documentation site for more information.
|
||||||
|
|
||||||
|
## License & Philosophy
|
||||||
|
The Extollo project is, and will always be, free & libre software. The framework itself is open-source available [here](https://code.garrettmills.dev/Extollo), and is licensed under the terms of the MIT license. See the LICENSE file for more information.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
Have an improvement or fix to Extollo? Contributors are always welcome. See the CONTRIBUTING.md file for next steps.
|
140
ex
Executable file
140
ex
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
ENV_NODE="$(which node)"
|
||||||
|
ENV_PNPM="$(which pnpm)"
|
||||||
|
|
||||||
|
LOGO=" _
|
||||||
|
/ /\ ______ _ _ _
|
||||||
|
/ / \ | ____| | | | | |
|
||||||
|
/ / /\ \ | |__ __ _| |_ ___ | | | ___
|
||||||
|
/ / /\ \ \ | __| \ \/ / __/ _ \| | |/ _ \\
|
||||||
|
/ / / \ \_\ | |____ > <| || (_) | | | (_) |
|
||||||
|
\/_/ \/_/ |______/_/\_\\\__\___/|_|_|\___/
|
||||||
|
"
|
||||||
|
|
||||||
|
# Author: Tasos Latsas
|
||||||
|
|
||||||
|
# spinner.sh
|
||||||
|
#
|
||||||
|
# Display an awesome 'spinner' while running your long shell commands
|
||||||
|
#
|
||||||
|
# Do *NOT* call _spinner function directly.
|
||||||
|
# Use {start,stop}_spinner wrapper functions
|
||||||
|
|
||||||
|
# usage:
|
||||||
|
# 1. source this script in your's
|
||||||
|
# 2. start the spinner:
|
||||||
|
# start_spinner [display-message-here]
|
||||||
|
# 3. run your command
|
||||||
|
# 4. stop the spinner:
|
||||||
|
# stop_spinner [your command's exit status]
|
||||||
|
#
|
||||||
|
# Also see: test.sh
|
||||||
|
|
||||||
|
|
||||||
|
function _spinner() {
|
||||||
|
# $1 start/stop
|
||||||
|
#
|
||||||
|
# on start: $2 display message
|
||||||
|
# on stop : $2 process exit status
|
||||||
|
# $3 spinner function pid (supplied from stop_spinner)
|
||||||
|
|
||||||
|
local on_success="DONE"
|
||||||
|
local on_fail="FAIL"
|
||||||
|
local white="\e[1;37m"
|
||||||
|
local green="\e[1;32m"
|
||||||
|
local red="\e[1;31m"
|
||||||
|
local nc="\e[0m"
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
start)
|
||||||
|
# calculate the column where spinner and status msg will be displayed
|
||||||
|
let column=$(tput cols)-${#2}-8
|
||||||
|
# display message and position the cursor in $column column
|
||||||
|
echo -ne ${2}
|
||||||
|
printf "%${column}s"
|
||||||
|
|
||||||
|
# start spinner
|
||||||
|
i=1
|
||||||
|
sp='\|/-'
|
||||||
|
delay=${SPINNER_DELAY:-0.15}
|
||||||
|
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
printf "\b${sp:i++%${#sp}:1}"
|
||||||
|
sleep $delay
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
if [[ -z ${3} ]]; then
|
||||||
|
echo "spinner is not running.."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
kill $3 > /dev/null 2>&1
|
||||||
|
|
||||||
|
# inform the user uppon success or failure
|
||||||
|
echo -en "\b["
|
||||||
|
if [[ $2 -eq 0 ]]; then
|
||||||
|
echo -en "${green}${on_success}${nc}"
|
||||||
|
else
|
||||||
|
echo -en "${red}${on_fail}${nc}"
|
||||||
|
fi
|
||||||
|
echo -e "]"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "invalid argument, try {start/stop}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function start_spinner {
|
||||||
|
# $1 : msg to display
|
||||||
|
_spinner "start" "${1}" &
|
||||||
|
# set global spinner pid
|
||||||
|
_sp_pid=$!
|
||||||
|
disown
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop_spinner {
|
||||||
|
# $1 : command exit status
|
||||||
|
_spinner "stop" $1 $_sp_pid
|
||||||
|
unset _sp_pid
|
||||||
|
}
|
||||||
|
|
||||||
|
function echoRun() {
|
||||||
|
echo ""
|
||||||
|
echo "+ $@"
|
||||||
|
echo ""
|
||||||
|
"$@"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ ! -d "./node_modules" ]; then
|
||||||
|
echo "$LOGO"
|
||||||
|
echo "+----------------------------------------+"
|
||||||
|
echo "| Docs: https://extollo.garrettmills.dev |"
|
||||||
|
echo "+----------------------------------------+"
|
||||||
|
echo ""
|
||||||
|
echo "Welcome to Extollo! Let's set things up for the first time..."
|
||||||
|
|
||||||
|
if [ ! -x "$ENV_PNPM" ]; then
|
||||||
|
echo "Please install PNPM to use Extollo."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echoRun "$ENV_PNPM" i
|
||||||
|
|
||||||
|
if [ ! -f "./.env" ]; then
|
||||||
|
echoRun cp example.env .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
printf "\033[32m✓\033[39m Looks like you're all set up! Run this command again to access the Extollo CLI.\n"
|
||||||
|
else
|
||||||
|
start_spinner "Building your app..."
|
||||||
|
"$ENV_PNPM" run build > /dev/null
|
||||||
|
stop_spinner 0
|
||||||
|
"$ENV_NODE" --experimental-repl-await ./lib/cli.js $@
|
||||||
|
fi
|
4
example.env
Normal file
4
example.env
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
DEBUG_MODE=true
|
||||||
|
EXTOLLO_LOGGING_LEVEL=6
|
||||||
|
DATABASE_PASSWORD=extollo
|
||||||
|
DATABASE_HOST=db01.platform.local
|
51
package.json
Normal file
51
package.json
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "@extollo/extollo",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "The framework lifts up your code.",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"types": "lib/index.d.ts",
|
||||||
|
"directories": {
|
||||||
|
"lib": "lib"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@extollo/lib": "^0.9.0",
|
||||||
|
"copyfiles": "^2.4.1",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"ts-expose-internals": "^4.5.4",
|
||||||
|
"ts-patch": "^2.0.1",
|
||||||
|
"ts-to-zod": "^1.8.0",
|
||||||
|
"typescript": "^4.3.2",
|
||||||
|
"zod": "^3.11.6"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"build": "excc -c package.json -t tsconfig.json",
|
||||||
|
"app": "pnpm run build && node lib/index.js",
|
||||||
|
"cli": "pnpm run build && node lib/cli.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib/**/*"
|
||||||
|
],
|
||||||
|
"prepare": "npm run build",
|
||||||
|
"postversion": "git push && git push --tags",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://code.garrettmills.dev/extollo/extollo"
|
||||||
|
},
|
||||||
|
"author": "garrettmills <shout@garrettmills.dev>",
|
||||||
|
"license": "MIT",
|
||||||
|
"extollo": {
|
||||||
|
"cc": {
|
||||||
|
"zodify": [
|
||||||
|
"src/app/types"
|
||||||
|
],
|
||||||
|
"non-source": [
|
||||||
|
".env",
|
||||||
|
"src/app/resources"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@extollo/cc": "^0.6.0"
|
||||||
|
}
|
||||||
|
}
|
2686
pnpm-lock.yaml
Normal file
2686
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
46
src/Units.extollo.ts
Normal file
46
src/Units.extollo.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
Config,
|
||||||
|
Controllers,
|
||||||
|
HTTPServer,
|
||||||
|
Files,
|
||||||
|
Middlewares,
|
||||||
|
Routing,
|
||||||
|
Unit,
|
||||||
|
Database,
|
||||||
|
Models,
|
||||||
|
CommandLine,
|
||||||
|
Internationalization,
|
||||||
|
Authentication,
|
||||||
|
Discovery,
|
||||||
|
ValidationUnit,
|
||||||
|
Migrations,
|
||||||
|
Queueables,
|
||||||
|
Redis,
|
||||||
|
Bus,
|
||||||
|
} from '@extollo/lib'
|
||||||
|
import {AppUnit} from './app/AppUnit'
|
||||||
|
|
||||||
|
Error.stackTraceLimit = 500
|
||||||
|
|
||||||
|
export const Units = [
|
||||||
|
Config,
|
||||||
|
Redis,
|
||||||
|
Queueables,
|
||||||
|
Bus,
|
||||||
|
ValidationUnit,
|
||||||
|
Files,
|
||||||
|
CommandLine,
|
||||||
|
Controllers,
|
||||||
|
Middlewares,
|
||||||
|
Database,
|
||||||
|
Models,
|
||||||
|
Migrations,
|
||||||
|
Internationalization,
|
||||||
|
Authentication,
|
||||||
|
|
||||||
|
AppUnit,
|
||||||
|
|
||||||
|
Routing,
|
||||||
|
Discovery,
|
||||||
|
HTTPServer,
|
||||||
|
] as (typeof Unit)[]
|
9
src/app/AppUnit.ts
Normal file
9
src/app/AppUnit.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import {ORMUser, Singleton, Unit} from '@extollo/lib'
|
||||||
|
import {User} from './models/User.model'
|
||||||
|
|
||||||
|
@Singleton()
|
||||||
|
export class AppUnit extends Unit {
|
||||||
|
async up(): Promise<void> {
|
||||||
|
this.container().registerStaticOverride(ORMUser, User)
|
||||||
|
}
|
||||||
|
}
|
5
src/app/configs/app.config.ts
Normal file
5
src/app/configs/app.config.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { env } from '@extollo/lib'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: env('APP_NAME', 'Extollo'),
|
||||||
|
}
|
21
src/app/configs/auth.config.ts
Normal file
21
src/app/configs/auth.config.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import {AuthenticationConfig, CoreIDLoginProvider, OAuth2LoginProviderConfig, ORMUserRepository, env} from '@extollo/lib'
|
||||||
|
|
||||||
|
const authConfig: AuthenticationConfig = {
|
||||||
|
storage: ORMUserRepository,
|
||||||
|
providers: {
|
||||||
|
coreid: {
|
||||||
|
driver: CoreIDLoginProvider,
|
||||||
|
config: {
|
||||||
|
default: true,
|
||||||
|
displayName: 'Starship CoreID',
|
||||||
|
clientId: env('COREID_CLIENT_ID'),
|
||||||
|
clientSecret: env('COREID_CLIENT_SECRET'),
|
||||||
|
loginUrl: env('COREID_BASE', '') + '/auth/service/oauth2/authorize?client_id=%c&redirect_uri=%r',
|
||||||
|
tokenUrl: env('COREID_BASE', '') + '/auth/service/oauth2/redeem',
|
||||||
|
userUrl: env('COREID_BASE', '') + '/api/v1/auth/users/me',
|
||||||
|
} as OAuth2LoginProviderConfig,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default authConfig
|
14
src/app/configs/database.config.ts
Normal file
14
src/app/configs/database.config.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { env } from "@extollo/lib";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
connections: {
|
||||||
|
default: {
|
||||||
|
user: env('DATABASE_USERNAME', 'extollo'),
|
||||||
|
password: env('DATABASE_PASSWORD'),
|
||||||
|
host: env('DATABASE_HOST', 'localhost'),
|
||||||
|
port: env('DATABASE_PORT', 5432),
|
||||||
|
database: env('DATABASE_NAME', 'extollo'),
|
||||||
|
dialect: env('DATABASE_DIALECT', 'postgres'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
5
src/app/configs/lang/common.config.ts
Normal file
5
src/app/configs/lang/common.config.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { env } from "@extollo/lib"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
app_name: env('APP_NAME', 'Extollo'),
|
||||||
|
}
|
6
src/app/configs/lang/en_US.config.ts
Normal file
6
src/app/configs/lang/en_US.config.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import {env} from '@extollo/lib'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
welcome_to_extollo: 'Welcome to Extollo!',
|
||||||
|
viewed_page_num_times: 'You have viewed this page :num: times.',
|
||||||
|
}
|
24
src/app/configs/oauth2.config.ts
Normal file
24
src/app/configs/oauth2.config.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {OAuth2Client, OAuth2Scope, env, /*uuid4*/} from '@extollo/lib'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
secret: env('OAUTH2_SECRET'),
|
||||||
|
scopes: {
|
||||||
|
'user-info': {
|
||||||
|
id: 'user-info',
|
||||||
|
name: 'user-info',
|
||||||
|
description: 'access basic information about your account',
|
||||||
|
},
|
||||||
|
} as {[key: string]: OAuth2Scope},
|
||||||
|
clients: {
|
||||||
|
// 'test-1': {
|
||||||
|
// id: 'test-1',
|
||||||
|
// display: 'Test 1',
|
||||||
|
// secret: env('TEST_CLIENT_SECRET', uuid4()),
|
||||||
|
// allowedFlows: ['code'],
|
||||||
|
// allowedScopeIds: ['user-info'],
|
||||||
|
// allowedRedirectUris: [
|
||||||
|
// 'http://localhost:1234/callback',
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
} as {[key: string]: OAuth2Client},
|
||||||
|
}
|
66
src/app/configs/server.config.ts
Normal file
66
src/app/configs/server.config.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import {
|
||||||
|
env,
|
||||||
|
basePath,
|
||||||
|
ORMSession,
|
||||||
|
LocalFilesystem,
|
||||||
|
LocalFilesystemConfig,
|
||||||
|
RedisCache,
|
||||||
|
CacheQueue,
|
||||||
|
BusConnectorConfig, QueueConfig, SyncQueue
|
||||||
|
} from "@extollo/lib"
|
||||||
|
import {LogRequest} from "../http/middlewares/LogRequest.middleware";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
debug: env('DEBUG_MODE', false),
|
||||||
|
|
||||||
|
session: {
|
||||||
|
/* The implementation of @extollo/lib.Session that serves as the session backend. */
|
||||||
|
driver: ORMSession,
|
||||||
|
},
|
||||||
|
|
||||||
|
bus: {
|
||||||
|
connectors: [
|
||||||
|
{type: 'redis'},
|
||||||
|
] as BusConnectorConfig[],
|
||||||
|
},
|
||||||
|
|
||||||
|
queue: {
|
||||||
|
driver: CacheQueue,
|
||||||
|
} as QueueConfig,
|
||||||
|
|
||||||
|
cache: {
|
||||||
|
driver: RedisCache,
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here, you can define various filesystem drivers that can be used in
|
||||||
|
* your application to store/retrieve files.
|
||||||
|
*
|
||||||
|
* The key in the object is the 'name' of the filesystem as it will be
|
||||||
|
* fetched in code. For example, if you have a `fubar: { ... }` item,
|
||||||
|
* then you can retrieve that filesystem using the Files service like
|
||||||
|
* so:
|
||||||
|
*
|
||||||
|
* files.getFilesystem('fubar') // => Filesystem { ... }
|
||||||
|
*/
|
||||||
|
filesystems: {
|
||||||
|
default: {
|
||||||
|
/* If true, this will serve as the default filesystem for modules in your application. */
|
||||||
|
isDefault: true,
|
||||||
|
|
||||||
|
/* The implementation of @extollo/lib.Filesystem that serves as the backend. */
|
||||||
|
driver: LocalFilesystem,
|
||||||
|
|
||||||
|
/* The config required by the filesystem driver. */
|
||||||
|
config: {
|
||||||
|
baseDir: basePath('..', 'uploads').toLocal,
|
||||||
|
} as LocalFilesystemConfig,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
middleware: {
|
||||||
|
global: {
|
||||||
|
pre: [LogRequest],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
26
src/app/http/controllers/main/Home.controller.ts
Normal file
26
src/app/http/controllers/main/Home.controller.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import {Controller, view, Session, Inject, Injectable, Locale, Validator} from '@extollo/lib'
|
||||||
|
import {UserLogin} from "../../../types/UserLogin";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class Home extends Controller {
|
||||||
|
@Inject()
|
||||||
|
protected readonly session!: Session;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
protected readonly locale!: Locale;
|
||||||
|
|
||||||
|
public welcome() {
|
||||||
|
this.session.set('app_visits', this.session.get('app_visits', 0) + 1)
|
||||||
|
|
||||||
|
const valid = new Promise<UserLogin>(() => {})
|
||||||
|
|
||||||
|
return view('@extollo:welcome', {
|
||||||
|
app_visits: this.session.get('app_visits'),
|
||||||
|
locale: this.locale.helper(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public test() {
|
||||||
|
return new Validator<UserLogin>()
|
||||||
|
}
|
||||||
|
}
|
11
src/app/http/middlewares/LogRequest.middleware.ts
Normal file
11
src/app/http/middlewares/LogRequest.middleware.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import {Inject, Injectable, Logging, Middleware} from '@extollo/lib'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LogRequest extends Middleware {
|
||||||
|
@Inject()
|
||||||
|
protected readonly logging!: Logging
|
||||||
|
|
||||||
|
public async apply() {
|
||||||
|
this.logging.info(`Incoming request: ${this.request.method} @ ${this.request.path}`)
|
||||||
|
}
|
||||||
|
}
|
13
src/app/http/routes/app.routes.ts
Normal file
13
src/app/http/routes/app.routes.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import {Route, SessionAuthMiddleware, AuthRequiredMiddleware} from '@extollo/lib'
|
||||||
|
import {Home} from '../controllers/main/Home.controller'
|
||||||
|
|
||||||
|
Route.group('/', () => {
|
||||||
|
Route.get('/')
|
||||||
|
.calls<Home>(Home, home => home.welcome)
|
||||||
|
})
|
||||||
|
|
||||||
|
Route.group('', () => {
|
||||||
|
Route.get('/dash')
|
||||||
|
.pre(AuthRequiredMiddleware)
|
||||||
|
.calls<Home>(Home, home => home.welcome)
|
||||||
|
}).pre(SessionAuthMiddleware)
|
15
src/app/jobs/LogMessage.job.ts
Normal file
15
src/app/jobs/LogMessage.job.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import {Inject, Injectable, Logging, BaseJob} from '@extollo/lib'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export default class LogMessage extends BaseJob {
|
||||||
|
@Inject()
|
||||||
|
protected readonly logging!: Logging
|
||||||
|
|
||||||
|
async execute(): Promise<void> {
|
||||||
|
this.logging.info('Executing LogMessage...')
|
||||||
|
await new Promise<void>(res => {
|
||||||
|
setTimeout(() => res(), 3000)
|
||||||
|
})
|
||||||
|
this.logging.success('The LogMessage job has executed!')
|
||||||
|
}
|
||||||
|
}
|
5
src/app/models/User.model.ts
Normal file
5
src/app/models/User.model.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import {ORMUser} from '@extollo/lib'
|
||||||
|
|
||||||
|
export class User extends ORMUser {
|
||||||
|
|
||||||
|
}
|
6
src/app/resources/views/welcome.pug
Normal file
6
src/app/resources/views/welcome.pug
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
html
|
||||||
|
head
|
||||||
|
title !{locale('app_name')}
|
||||||
|
body
|
||||||
|
h1 !{locale('welcome_to_extollo')}
|
||||||
|
h2 !{locale('viewed_page_num_times', { interp: { num: app_visits } })}
|
14
src/app/types/UserLogin.ts
Normal file
14
src/app/types/UserLogin.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
export interface UserLogin {
|
||||||
|
/**
|
||||||
|
* @minLength 1
|
||||||
|
* @maxLength 100
|
||||||
|
*/
|
||||||
|
username: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @minLength 1
|
||||||
|
* @maxLength 100
|
||||||
|
*/
|
||||||
|
password: string,
|
||||||
|
}
|
43
src/bootstrap.ts
Normal file
43
src/bootstrap.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import {Application, CommandLineApplication} from '@extollo/lib'
|
||||||
|
import {Units} from './Units.extollo'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper functions to bootstrap the Application instance for different uses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the base application with no final-target unit.
|
||||||
|
*/
|
||||||
|
export function base(): Application {
|
||||||
|
const app = Application.getApplication()
|
||||||
|
app.scaffold(__dirname, Units.slice(0, -1))
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the application with the final unit replaced with the CommandLineApplication
|
||||||
|
* for use on the CLI.
|
||||||
|
*/
|
||||||
|
export function cli(): Application {
|
||||||
|
const app = Application.getApplication()
|
||||||
|
app.forceStartupMessage = false
|
||||||
|
|
||||||
|
const units = [...Units]
|
||||||
|
|
||||||
|
units.reverse()
|
||||||
|
CommandLineApplication.setReplacement(units[0])
|
||||||
|
units[0] = CommandLineApplication
|
||||||
|
units.reverse()
|
||||||
|
|
||||||
|
app.scaffold(__dirname, units)
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the application as it should be run normally.
|
||||||
|
*/
|
||||||
|
export function app(): Application {
|
||||||
|
const app = Application.getApplication()
|
||||||
|
app.scaffold(__dirname, Units)
|
||||||
|
return app
|
||||||
|
}
|
15
src/cli.ts
Normal file
15
src/cli.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env -S node --experimental-repl-await
|
||||||
|
import {globalRegistry} from '@extollo/lib'
|
||||||
|
import {cli} from './bootstrap'
|
||||||
|
|
||||||
|
globalRegistry.run(async () => {
|
||||||
|
/*
|
||||||
|
* The Application
|
||||||
|
* -----------------------------------------------------
|
||||||
|
* The application instance is a global inversion of control container that
|
||||||
|
* ties your entire application together. The app container manages services
|
||||||
|
* and lifecycle.
|
||||||
|
*/
|
||||||
|
const app = cli()
|
||||||
|
await app.run()
|
||||||
|
})
|
13
src/index.ts
Normal file
13
src/index.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import {globalRegistry} from '@extollo/lib'
|
||||||
|
import {app} from './bootstrap'
|
||||||
|
|
||||||
|
globalRegistry.run(async () => {
|
||||||
|
/*
|
||||||
|
* The Application
|
||||||
|
* -----------------------------------------------------
|
||||||
|
* The application instance is a global inversion of control container that
|
||||||
|
* ties your entire application together. The app container manages services
|
||||||
|
* and lifecycle.
|
||||||
|
*/
|
||||||
|
await app().run()
|
||||||
|
})
|
13
tsconfig.json
Normal file
13
tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es6",
|
||||||
|
"module": "commonjs",
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./lib",
|
||||||
|
"strict": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true
|
||||||
|
},
|
||||||
|
"include": ["src"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user