Commit 852df420 authored by Bryan Tong's avatar Bryan Tong

Merge branch 'update-420' into 'master'

Update for upcoming 4.2.0 release

See merge request !36
parents ad19f4a0 26dbaac2
......@@ -9,12 +9,7 @@ const https = require('https')
const Parser = require('kado/lib/Parser')
const showdown = require('showdown')
const Validate = require('kado/lib/Validate')
const sha1Exp = /^[0-9a-f]{40}$/
const opt = GetOpt.getInstance(process.argv)
const op = opt.opts()
const docRoot = fs.path.join(__dirname, 'main/views')
let foldersCreated = 0
const startTime = new Date()
const highlightExp = new RegExp('<pre>(<code[^>]+?>)(.+?)</code></pre>', 'igs')
const highlightExt = () => {
return [{
......@@ -39,10 +34,52 @@ const highlightExtension = highlightExt()
Assert.isType('Array', highlightExtension)
Assert.isType('Function', highlightExtension[0].filter)
showdown.extension('highlight', highlightExt)
const convert = new showdown.Converter({
extensions: ['highlight'],
let uriMaps = {}
const re1 = new RegExp('^([./].*/)([^/]+\\.md)$')
const linkfixExp = new RegExp('( href=")([^"]+)(")', 'igs')
const linkfixExt = () => {
return [{
type: 'output',
filter: (text, converter) => {
let part = null
do {
part = linkfixExp.exec(text)
if (part) {
const part1 = text.slice(0, part.index) + part[1]
const part2 = part[3] + text.slice(part.index + part[0].length)
const href = Parser.htmlUnescape(part[2])
const m = href.match(re1)
if (m && m[1] && m[2]) {
for (const uri of Object.keys(converter.uriMap).sort().filter((v) => v.indexOf('/' + m[2]) > -1)) {
const newHref = ['/', '/'].join(converter.uriMap[uri][0])
text = `${part1}${newHref}${part2}`
}
}
}
} while (part)
return text
}
}]
}
const linkfixExtension = linkfixExt()
Assert.isType('Array', linkfixExtension)
Assert.isType('Function', linkfixExtension[0].filter)
showdown.extension('linkfix', linkfixExt)
const converterOpts = {
extensions: ['highlight', 'linkfix'],
tables: true
})
}
const sha1Exp = /^[0-9a-f]{40}$/
const opt = GetOpt.getInstance(process.argv)
const op = opt.opts()
const docRoot = fs.path.join(__dirname, 'main/views')
const subs = ['article', 'doc', 'guide', 'info']
let foldersCreated = 0
const startTime = new Date()
if (op.help || op.h) {
console.log('build <options> <arguments>')
console.log(' -h --help Display help menu')
......@@ -59,6 +96,7 @@ if (!op.i || op.info) {
console.log('No document information defined, exiting!')
process.exit(1)
}
function getRemoteFile (url) {
return new Promise((resolve, reject) => {
function remoteFileErrorHandler (e) {
......@@ -118,12 +156,29 @@ function compareContent (base, against) {
hashAgainst: sha1Against
}
}
function infoToUriMaps (info) {
const uriMaps = {}
for (const v in info) {
if (!Object.prototype.hasOwnProperty.call(info, v)) continue
const doc = info[v]
uriMaps[v] = {}
for (const sub of subs) {
if (typeof doc[sub] === 'object') {
for (const name of Object.keys(doc[sub])) {
if (!uriMaps[v][doc[sub][name]]) uriMaps[v][doc[sub][name]] = []
uriMaps[v][doc[sub][name]].push([sub, name].join('/'))
}
}
}
}
return uriMaps
}
let pending = 0
let skipped = 0
let written = 0
let bytesReceived = 0
let bytesWritten = 0
function processDocuments (vInfo, type) {
function processDocuments (vInfo, type, v) {
const docPromises = []
if (!vInfo.docMap) vInfo.docMap = {}
for (const name in vInfo[type]) {
......@@ -145,6 +200,8 @@ function processDocuments (vInfo, type) {
const promise = getRemoteFile(doc.remoteRawUrl)
.then((text) => {
bytesReceived += text.length
const convert = new showdown.Converter(converterOpts)
convert.uriMap = uriMaps[v]
html = convert.makeHtml(text)
// now retrieve the locally saved content so we can compare
const promises = []
......@@ -209,6 +266,7 @@ try {
const infoFile = op.i || op.info
Assert.isOk(fs.exists(infoFile), 'Information file does not exist')
const info = JSON.parse(fs.readFileSync(infoFile))
uriMaps = infoToUriMaps(info)
let versionsProcessed = 0
const promises = []
for (const v in info) {
......@@ -223,10 +281,9 @@ try {
vInfo.baseVersion = pkg.version.split('.')[0]
if (vInfo.latest === true) info.latestVersion = vInfo.docVersion
const queue = []
if (vInfo.article) queue.push(processDocuments(vInfo, 'article'))
if (vInfo.doc) queue.push(processDocuments(vInfo, 'doc'))
if (vInfo.guide) queue.push(processDocuments(vInfo, 'guide'))
if (vInfo.info) queue.push(processDocuments(vInfo, 'info'))
for (const sub of subs) {
if (vInfo[sub]) queue.push(processDocuments(vInfo, sub, v))
}
return Promise.all(queue)
})
promises.push(promise)
......@@ -235,7 +292,7 @@ try {
.then(() => {
if (op.u || op.update) {
fs.writeFileSync(
fs.path.join(docRoot, 'info.json'), JSON.stringify(info)
fs.path.join(docRoot, 'info.json'), JSON.stringify(info, null, ' ')
)
console.log('Updated information file.')
}
......
{
"v4": {
"remoteUrl": "https://git.nullivex.com/nullivex/kado/tree/master/",
"remoteBaseUrl": "https://git.nullivex.com/nullivex/kado/blob/master",
"remoteRawUrl": "https://git.nullivex.com/nullivex/kado/raw/master",
"remoteUrl": "https://git.nullivex.com/kado/kado/tree/master/",
"remoteBaseUrl": "https://git.nullivex.com/kado/kado/blob/master",
"remoteRawUrl": "https://git.nullivex.com/kado/kado/raw/master",
"latest": true,
"article": {
"kado-4-released": "/doc/article/Kado4Released.md",
"kado-4.2-released": "/doc/article/Kado4.2Released.md",
"thesis": "/doc/article/Thesis.md",
"upgrading-from-kado-3": "/doc/article/UpgradingFromKado3.md"
},
"doc": {
"application": "/doc/Application.md",
"asset": "/doc/Asset.md",
"assert": "/doc/Assert.md",
"asset": "/doc/Asset.md",
"child-process": "/doc/ChildProcess.md",
"cluster": "/doc/Cluster.md",
"command": "/doc/Command.md",
......@@ -36,13 +37,18 @@
"mapper": "/doc/Mapper.md",
"message": "/doc/Message.md",
"mime": "/doc/Mime.md",
"model": "/doc/Model.md",
"module": "/doc/Module.md",
"mustache": "/doc/Mustache.md",
"navigation": "/doc/Navigation.md",
"parser": "/doc/Parser.md",
"path-exp": "/doc/PathExp.md",
"permission": "/doc/Permission.md",
"profiler": "/doc/Profiler.md",
"query": "/doc/Query.md",
"query-cache": "/doc/QueryCache.md",
"router": "/doc/Router.md",
"schema": "/doc/Schema.md",
"search": "/doc/Search.md",
"session": "/doc/Session.md",
"test-runner": "/doc/TestRunner.md",
......@@ -51,11 +57,11 @@
"view": "/doc/View.md"
},
"guide": {
"advanced-techniques": "/doc/guide/AdvancedTechniques.md",
"build-admin-panel": "/doc/guide/BuildAdminPanel.md",
"database-work-flow": "/doc/guide/DatabaseWorkFlow.md",
"getting-started": "/doc/guide/GettingStarted.md",
"hello-world": "/doc/guide/HelloWorld.md",
"introduction": "/doc/guide/Introduction.md",
"make-simple-website": "/doc/guide/MakeSimpleWebsite.md",
"quick-start": "/doc/guide/QuickStart.md",
"views-rendering": "/doc/guide/ViewsRendering.md",
......
{{#docVersion.v4}}
<h3>Articles</h3>
<ul class="list-simple">
<li><a href="/article/kado-4.2-released/">Kado 4.2 Released</a></li>
<li><a href="/article/kado-4-released/">Kado 4 Released</a></li>
<li><a href="/article/upgrading-from-kado-3/">Upgrading from Kado 3</a></li>
</ul>
......@@ -13,13 +14,13 @@
<li><a href="/guide/database-work-flow/">Database Work Flows</a></li>
<li><a href="/guide/working-with-email/">Working with Email</a></li>
<li><a href="/guide/views-rendering/">Views and Rendering</a></li>
<li><a href="/guide/advanced-techniques/">Advanced Techniques</a></li>
<li><a href="/guide/writing-tests/">Writing Tests</a></li>
</ul>
<h3>API</h3>
<ul class="list-simple">
<li><a href="/doc/application/">Application</a></li>
<li><a href="/doc/asset/">Asset</a></li>
<li><a href="/doc/assert/">Assert</a></li>
<li><a href="/doc/asset/">Asset</a></li>
<li><a href="/doc/child-process/">ChildProcess</a></li>
<li><a href="/doc/cluster/">Cluster</a></li>
<li><a href="/doc/command/">Command</a></li>
......@@ -41,15 +42,20 @@
<li><a href="/doc/lifecycle/">Lifecycle</a></li>
<li><a href="/doc/log/">Log</a></li>
<li><a href="/doc/mapper/">Mapper</a></li>
<li><a href="/doc/mime/">Mime</a></li>
<li><a href="/doc/message/">Message</a></li>
<li><a href="/doc/mime/">Mime</a></li>
<li><a href="/doc/model/">Model</a></li>
<li><a href="/doc/module/">Module</a></li>
<li><a href="/doc/mustache/">Mustache</a></li>
<li><a href="/doc/navigation/">Navigation</a></li>
<li><a href="/doc/parser/">Parser</a></li>
<li><a href="/doc/path-exp/">PathExp</a></li>
<li><a href="/doc/permission/">Permission</a></li>
<li><a href="/doc/profiler/">Profiler</a></li>
<li><a href="/doc/query/">Query</a></li>
<li><a href="/doc/query-cache/">QueryCache</a></li>
<li><a href="/doc/router/">Router</a></li>
<li><a href="/doc/schema/">Schema</a></li>
<li><a href="/doc/search/">Search</a></li>
<li><a href="/doc/session/">Session</a></li>
<li><a href="/doc/test-runner/">TestRunner</a></li>
......
......@@ -26,8 +26,8 @@ the <strong>Guides</strong> section at the left. The guides link together to for
by step introduction into using Kado 4 in your application.</p>
<h2 id="builtintesting">Built in Testing</h2>
<p>Kado 4 is proud to announce the ability to write and run tests directly using
the included <a href="../TestRunner.md">TestRunner</a> library. Also see the
<a href="../guide/WritingTests.md">Writing Tests</a> guide to gain more understanding
the included <a href="/doc/test-runner/">TestRunner</a> library. Also see the
<a href="/guide/writing-tests/">Writing Tests</a> guide to gain more understanding
on constructing test suites.</p>
<h2 id="opendevelopmentwithgitlab">Open Development with Gitlab</h2>
<p>All our coding is done openly on <a href="https://git.nullivex.com/kado/kado">Gitlab</a>
......
<h1 id="kado42released">Kado 4.2 Released</h1>
<p><em>By Bryan Tong 4/15/20</em></p>
<p>Our new release of Kado has been in development for a little over one month.
However, it feels like we have done years of work! This release is jam packed
with essentials for creating Websites, API Servers, CLI applications and
whatever else you might imagine. Chances are you can probably build it with
Kado 4.2.</p>
<p>Here is an overview of the primary additions:</p>
<ul>
<li>Add new Model.js for creating and working with Database records.</li>
<li>Add new Mustache.js for string templating.</li>
<li>Add new MySQL database engine.</li>
<li>Add new Query.js for building queries for databases.</li>
<li>Add new QueryCache.js for caching queries from a database in a database.</li>
<li>Add new Schema.js for building tables for databases.</li>
<li>Validate.isType upgraded to be more consistent and predictable.</li>
<li>Parser adds <code>requestBody</code> parser to assist with input decoding.</li>
<li>Router adds <code>res.json()</code> for JSON output.</li>
<li>Router adds <code>res.redirect()</code> for location changes.</li>
<li>Router adds <code>res.sendFile()</code> for sending files.</li>
<li>Session adds <code>SessionStoreSQL</code> for SQL backed sessions from databases.
Add <code>HyperText.Proxy</code> to HyperText.js which provides an HTTP reverse proxy.</li>
</ul>
<p>There are more! See our <a href="/info/changelog/">CHANGELOG</a></p>
<p>As our team continues to build new applications on Kado 4 we are continuously
evaluating and engineering the development of Kado. This means we use Kado every
day on our own projects and work diligently to improve developer efficiency. We
also believe all these factors combined make Kado "fun" to develop against.</p>
<p>That is all for the hype, now get out there and see what Kado 4.2 can do for
you!</p>
<p>Sincerely,</p>
<p>The Kado Team</p>
\ No newline at end of file
......@@ -13,7 +13,7 @@ release of Kado version 3. Please keep in mind there will be no more Kado 3
releases on NPM. Now on with the upgrade notes.</p>
<p>Kado 4 is a major improvement over Kado 3 and you will not find many
similarities between the two. Kado 4 is an entirely new approach to solving
the problem originally presented in our <a href="./Thesis.md">Thesis</a>. We have looked
the problem originally presented in our <a href="/article/thesis/">Thesis</a>. We have looked
backwards into how to write high quality libraries that are used for C++ and
other languages. Afterwards, we came to a new conclusion on how the Kado
functionality should be presented to the end user.</p>
......
......@@ -54,7 +54,7 @@ lot easier to see Kado up and running.</p>
<pre><code>$ node app kado generate
</code></pre>
<p>Create a new module within your Kado application see
<a href="./Module.md">Module Guide</a> for more information. |</p>
<a href="/doc/module/">Module Guide</a> for more information. |</p>
<pre><code>$ node app staff create --email sample@kado.org --password sample --name Kado
</code></pre>
<p>Create a new staff member with the email <code>sample@kado.org</code> password <code>sample</code> and
......
......@@ -9,8 +9,8 @@ It all starts with a module generator that will ask questions and then create a
working module for you to edit into perfection.</p>
<h2 id="modulecreation">Module Creation</h2>
<p>To create a module first create an app by either
<a href="./InstallTheDemo.md">installing the demo</a> or by following the
<a href="./GettingStarted.md">getting-started</a> guide. Once complete, issue the following
<a href="/guide/install-the-demo/">installing the demo</a> or by following the
<a href="/guide/getting-started/">getting-started</a> guide. Once complete, issue the following
command to start the module generation process.</p>
<pre><code>$ node app kado generate
</code></pre>
......
......@@ -55,7 +55,7 @@ return boolean <code>true</code> or throw.</p>
</ul>
<h3 id="assertbelowceiling"><code>Assert.below(ceiling)</code></h3>
<ul>
<li><code>ceiling</code> {number} value for upper limit </li>
<li><code>ceiling</code> {number} value for upper limit</li>
<li>Returns: {boolean} <code>true</code> when below the <code>ceiling</code></li>
</ul>
<h3 id="assertequalagainst"><code>Assert.equal(against)</code></h3>
......@@ -190,7 +190,7 @@ than provided milliseconds to be considered valid.</p>
</ul>
<h3 id="staticassertcatchv1v2msgmethod"><code>static Assert.catch(v1, v2, msg, method)</code></h3>
<ul>
<li><code>v1</code> {mixed} first argument to <code>method</code> </li>
<li><code>v1</code> {mixed} first argument to <code>method</code></li>
<li><code>v2</code> {mixed} second argument to <code>method</code></li>
<li><code>msg</code> {mixed} compare this to <code>Error.message</code> when caught.</li>
<li><code>method</code> {string} class method to execute in try/catch</li>
......
......@@ -99,10 +99,64 @@ process.</p>
<li><code>options</code> {object} Runtime options to configure the cluster</li>
<li>Return {Cluster} new cluster management object</li>
</ul>
<h3 id="clusterismaster">Cluster.isMaster()</h3>
<ul>
<p>Available Options:</p>
<ul>
<li><code>count</code> {number} the number of workers to start
NOTE: By default the system will start 1 worker during development and will
automatically grow to all available CPUs + 1 in production. This is controlled
with the environment variable <code>NODE_ENV=production</code>. To change to manual
behavior simply pass any number to the <code>count</code> option.</li>
<li><code>delayHeartbeat</code> {number} how many ms before each heartbeat check,
default: 5000</li>
<li><code>delayRespawn</code> {number} how many ms before respawning a failed process,
default: 1000</li>
<li><code>disableMaster</code> {boolean} disable the master process and force single user
mode.</li>
<li><code>silent</code> {boolean} Control output to parent's stdio.
Default: false</li>
<li><code>maxConnections</code> {number} When workers serve more than this many connections
they automatically respawn. 0 is the default which is OFF.</li>
<li><code>recycleTimeout</code> {number} Time in ms before forcibly killing a worker being
recycled. Default is <code>null</code> which is no timeout.</li>
<li><code>stopTimeout</code> {number} Time in ms before forcibly killing a worker to
stop the application. Default is <code>5000</code></li>
<li><code>respawnTimeout</code> {number} Time in ms to wait for a respawned process to come
online, default is <code>5000</code></li>
<li><code>startTimeout</code> {number} Time in ms to wait for a process to start on
application start. Default is <code>5000</code></li>
<li><code>watchTimeout</code> {number} The time to wait before restarting on a watched
file change. Default is <code>5000</code></li>
<li><code>path</code> {string} The path to the worker program file. By default it calls back
into itself. Use an if statement to separate master from worker.</li>
<li><code>cluster</code> {object} Any of the settings from <a href="https://nodejs.org/dist/latest-v13.x/docs/api/cluster.html#cluster_cluster_settings">cluster settings</a></li>
</ul>
<h3 id="clusterismasteroptions">Cluster.isMaster(options)</h3>
<ul>
<li><code>options</code> {Object} containing options about the isMaster check.</li>
<li>Return {boolean} <code>true</code> when this process is the master</li>
</ul>
<p>Available Options</p>
<ul>
<li><code>maxArguments</code> {number} the maximum length of <code>process.argv</code> to enable cluster
support. When <code>process.argv</code> has more arguments than <code>maxArguments</code> {boolean}
<code>false</code> is returned which should trigger single worker mode in standard setups
and cause the command to be executed within the original process. This results
in a lean single process CLI applet by using a single check on the argv length.</li>
</ul>
<p>NOTE: This will always return false when <code>disableMaster</code> is set to true which
enables single process mode.</p>
<p>Example Usage for Development:</p>
<pre><code class="js language-js"><span class="hljs-keyword">const</span> <span class="hljs-keyword">Cluster</span> = require('kado/lib/<span class="hljs-keyword">Cluster</span>')
<span class="hljs-keyword">const</span> <span class="hljs-keyword">cluster</span> = <span class="hljs-keyword">Cluster</span>.getInstance()
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">cluster</span>.isMaster()) {
<span class="hljs-comment">// watch files, set process title, start other children</span>
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">// worker operations, listening routing, cli processing etc</span>
}
</code></pre>
<p>The above code provides a single process system in development and a fully
concurrent ready for load system in production. The scaling in this example is
fully automatic.</p>
<h3 id="clusterisworker">Cluster.isWorker()</h3>
<ul>
<li>Return {boolean} <code>true</code> when this process is the worker</li>
......
......@@ -54,7 +54,7 @@ Return {string} name of the command requested for removal.</li>
<li>Return {string} name of the command added.</li>
</ul>
<p>This actually uses the <code>Command</code> library to setup the new command
based on te options and is a shortcut for.</p>
based on the options and is a shortcut for.</p>
<pre><code class="js language-js"><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">CommandSerer</span>.</span></span>add<span class="hljs-constructor">Command('<span class="hljs-params">someModule</span>','<span class="hljs-params">someCommand</span>',<span class="hljs-params">new</span> Command()</span>)
</code></pre>
<h3 id="commandserverruncommand">CommandServer.run(command)</h3>
......
......@@ -10,16 +10,16 @@ through the <code>parse()</code> method.</p>
</code></pre>
<h2 id="classcommand">Class Command</h2>
<p>This class is a super class that is extended by the command section
within the <code>kado-ui</code> core object. Let us take a look at that usage snippet.</p>
within the <code>Application</code> core object. Let us take a look at that usage snippet.</p>
<pre><code class="js language-js">const <span class="hljs-type">CommandSuper</span> = require('./<span class="hljs-type">Command</span>')
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Command</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">CommandSuper</span> </span>{
constructor(){
constructor () {
<span class="hljs-keyword">super</span>()
<span class="hljs-keyword">this</span>.name = name
<span class="hljs-keyword">this</span>.options = options
<span class="hljs-keyword">this</span>.version = that.version
}
action(opts){
action (opts) {
<span class="hljs-keyword">return</span> options.action.call(<span class="hljs-keyword">this</span>,opts)
}
}
......@@ -35,9 +35,9 @@ which could be defined in a number of ways.</p>
<pre><code class="js language-js">const <span class="hljs-keyword">options</span> = {
<span class="hljs-keyword">description</span>: <span class="hljs-string">'Some command description'</span>,
<span class="hljs-keyword">options</span>: [
{definition: <span class="hljs-string">'-s, --something &lt;s&gt;'</span>, <span class="hljs-keyword">description</span>: <span class="hljs-string">'Some thing'</span>}
{ definition: <span class="hljs-string">'-s, --something &lt;s&gt;'</span>, <span class="hljs-keyword">description</span>: <span class="hljs-string">'Some thing'</span> }
],
action: (opts)=&gt;{
action: (opts) =&gt; {
<span class="hljs-keyword">return</span> Promise.resolve(opts)
}
}
......
......@@ -8,7 +8,7 @@
<p>This library manages Database connections that are stored through
instances registered to this library.</p>
<h2 id="classdatabase">Class: Database</h2>
<p><code>Database</code> extends <code>Connect</code> see <a href="./Connect.md">Connect.md</a> for more engine
<p><code>Database</code> extends <code>Connect</code> see <a href="/doc/connect/">Connect.md</a> for more engine
management and more.</p>
<h3 id="staticdatabasequeryoptionsconfigprofiler">static Database.queryOptions(config, profiler)</h3>
<ul>
......@@ -45,9 +45,32 @@ connections <code>connect()</code> method.</li>
<p>Note: when no <code>name</code> is provided all connections will be closed.</p>
<h2 id="classdatabaseengine">Class: DatabaseEngine</h2>
<p><code>DatabaseEngine</code> extends <code>ConnectEngine</code> see
<a href="./ConnectEngine.md">ConnectEngine.md</a> for more engine management and more.</p>
<a href="/doc/connect-engine/">ConnectEngine.md</a> for more engine management and more.</p>
<h3 id="databaseengineconnect">DatabaseEngine.connect()</h3>
<p>Must be extended and used to connect to underlying database.</p>
<h3 id="databaseengineclose">DatabaseEngine.close()</h3>
<p>By default will try and call <code>engine.close()</code> and then call
<code>ConnectEngine.resetEngine()</code>. Which should be sufficient for most underlays.</p>
\ No newline at end of file
<code>ConnectEngine.resetEngine()</code>. Which should be sufficient for most underlays.</p>
<h2 id="classdatabasemysql">Class: DatabaseMySQL</h2>
<p><code>DatabaseMySQL</code> extends <code>DatabaseEngine</code> extends <code>ConnectEngine</code> and implements
a relationship with the JavaScript <code>mysql2</code> driver available on NPM and Github.</p>
<p>See the <a href="https://github.com/sidorares/node-mysql2">mysql2 package</a></p>
<p>To use this engine it should be required at application startup. Example:</p>
<pre><code class="js language-js"><span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">'kado'</span>).getInstance()
<span class="hljs-keyword">const</span> MySQL = <span class="hljs-built_in">require</span>(<span class="hljs-string">'kado/lib/Database'</span>).MySQL
<span class="hljs-keyword">const</span> mysqlConfig = { <span class="hljs-attr">host</span>: <span class="hljs-string">'localhost'</span>, <span class="hljs-attr">user</span>: <span class="hljs-string">'test'</span>, <span class="hljs-attr">database</span>: <span class="hljs-string">'test'</span> }
app.database.addEngine(<span class="hljs-string">'mysql'</span>, <span class="hljs-keyword">new</span> MySQL(mysqlConfig))
</code></pre>
<h3 id="databasemysqlconstructoroptions">DatabaseMySQL.constructor(options)</h3>
<ul>
<li><code>options</code> {Object} containing connection options.</li>
<li>Return {DatabaseMySQL} new driver instance ready to be passed to the
<code>app.database.addEngine()</code> call.</li>
</ul>
<p>The currently supported options are:</p>
<ul>
<li><code>host</code> {string} hostname of the database server, default <code>localhost</code></li>
<li><code>user</code> {string} the username used to identify the connection</li>
<li><code>password</code> {string} the password used to authenticate the connection</li>
<li><code>database</code> {string} the database desired to select after connecting</li>
</ul>
\ No newline at end of file
......@@ -8,7 +8,7 @@
<p>This library provides a register for Email handlers to register and receive
email messages through the system.</p>
<h2 id="classemail">Class: Email</h2>
<p><code>Email</code> extends <code>Connect</code> see <a href="./Connect.md">Connect.md</a> for more engine
<p><code>Email</code> extends <code>Connect</code> see <a href="/doc/connect/">Connect.md</a> for more engine
management and more.</p>
<h3 id="staticemailgetinstance">static Email.getInstance()</h3>
<ul>
......@@ -27,6 +27,6 @@ Return {Promise} that resolves when the message is sent.</li>
<p>Note: when no <code>name</code> is provided all handlers are executed.</p>
<h2 id="classemailengine">Class: EmailEngine</h2>
<p><code>EmailEngine</code> extends <code>ConnectEngine</code> see
<a href="./ConnectEngine.md">ConnectEngine.md</a> for more engine management and more.</p>
<a href="/doc/connect-engine/">ConnectEngine.md</a> for more engine management and more.</p>
<h3 id="emailenginesend">EmailEngine.send()</h3>
<p>Must be extended and used to send to underlying email system.</p>
\ No newline at end of file
......@@ -12,7 +12,7 @@ used for tracking user behavior such as database changes etc.</p>
<p>Note: This is not to be confused with the core Node.JS <code>EventEmitter</code> which
serves a much different programmable purpose.</p>
<h2 id="classevent">Class: Event</h2>
<p><code>Event</code> extends <code>Connect</code> see <a href="./Connect.md">Connect.md</a> for more engine
<p><code>Event</code> extends <code>Connect</code> see <a href="/doc/connect/">Connect.md</a> for more engine
management and more.</p>
<h3 id="staticeventgetinstance">static Event.getInstance()</h3>
<ul>
......@@ -98,6 +98,6 @@ handler can read.</li>
</ul>
<h2 id="classeventengine">Class: EventEngine</h2>
<p><code>EventEngine</code> extends <code>ConnectEngine</code> see
<a href="./ConnectEngine.md">ConnectEngine.md</a> for more engine management and more.</p>
<a href="/doc/connect-engine/">ConnectEngine.md</a> for more engine management and more.</p>
<h3 id="eventengineevent">EventEngine.event()</h3>
<p>Must be extended and used to send to underlying event system.</p>
\ No newline at end of file
......@@ -11,7 +11,7 @@ within the system.</p>
<p>There is a <code>HyperTextEngine</code> library that provides the needed implementation to
setup traditional web servers into this abstraction layer.</p>
<h2 id="classhypertext">Class: HyperText</h2>
<p><code>HyperText</code> extends <code>Connect</code> see <a href="./Connect.md">Connect.md</a> for more engine
<p><code>HyperText</code> extends <code>Connect</code> see <a href="/doc/connect/">Connect.md</a> for more engine
management and more.</p>
<h3 id="statichypertextgetinstance">static HyperText.getInstance()</h3>
<ul>
......@@ -29,7 +29,7 @@ management and more.</p>
</ul>
<h2 id="classhypertextengine">Class: HyperTextEngine</h2>
<p><code>HyperTextEngine</code> extends <code>ConnectEngine</code> see
<a href="./ConnectEngine.md">ConnectEngine.md</a> for more engine management and more.</p>
<a href="/doc/connect-engine/">ConnectEngine.md</a> for more engine management and more.</p>
<h3 id="hypertextenginestart">HyperTextEngine.start()</h3>
<p>Must be extended and used to start the underlying server.</p>
<h3 id="hypertextenginestop">HyperTextEngine.stop()</h3>
......@@ -51,8 +51,8 @@ HTTP web server for use with <code>Application</code></p>
</ul>
<h3 id="hypertextserversethosthost">HyperTextServer.setHost(host)</h3>
<ul>
<li><code>host</code> {string} or <code>null</code>, host to listen on such as <code>localhost</code> or
<code>127.0.0.1</code>.</li>
<li><code>host</code> {string|Array} or <code>null</code>, host to listen on such as <code>localhost</code> or
<code>127.0.0.1</code>. When an array of hosts is given, each on will be listened on.</li>
<li>Return {HyperTextServer} this instance</li>
</ul>
<h3 id="hypertextserversetportport">HyperTextServer.setPort(port)</h3>
......@@ -121,4 +121,22 @@ an instance of <code>StaticServer</code> instantiated with <code>root</code> and
<li><code>res</code> {Response} An HTTP Response object.</li>
<li>Return {Promise} resolved when either a file is found or the stack should
continue.</li>
</ul>
<h2 id="classproxy">Class: Proxy</h2>
<h3 id="staticproxypassreqresoptions">static Proxy.pass(req, res, options)</h3>
<ul>
<li><code>req</code> {IncomingMessage} request object from an HTTP(s) request</li>
<li><code>res</code> {ServerResponse} response object from an HTTP(s) request</li>
<li><code>options</code> {Object} options controlling the proxy request</li>
<li>Return {Promise} resolved when request is handled.</li>
</ul>
<p>Available options:</p>
<ul>
<li><code>host</code> {string} the hostname or IP address to request from</li>
<li><code>port</code> {string} the port of the host to connect to</li>
<li><code>ssl</code> {boolean} enable HTTPS requests</li>
<li><code>rejectUnauthorized</code> {boolean} set <code>true</code> to trust invalid SSL hosts.</li>
<li><code>referrer</code> {string} A referrer to pass, otherwise uses <code>req.referer</code></li>
<li><code>method</code> {string} The type of request to make defaults to <code>req.method</code></li>
<li><code>maxRedirects</code> {number} Maximum times to follow redirects, default: 8</li>
</ul>
\ No newline at end of file
......@@ -8,7 +8,7 @@
<p>This library provides logging abstraction to use different log transports
for system level log messages.</p>
<h2 id="classlog">Class: Log</h2>
<p><code>Log</code> extends <code>Connect</code> see <a href="./Connect.md">Connect.md</a> for more engine
<p><code>Log</code> extends <code>Connect</code> see <a href="/doc/connect/">Connect.md</a> for more engine
management and more.</p>
<h3 id="staticlogappendfilepathdata">static Log.appendFile(path, data)</h3>
<ul>
......@@ -32,4 +32,4 @@ management and more.</p>
</ul>
<h2 id="classlogengine">Class: LogEngine</h2>
<p><code>LogEngine</code> extends <code>ConnectEngine</code> see
<a href="./ConnectEngine.md">ConnectEngine.md</a> for more engine management and more.</p>
\ No newline at end of file
<a href="/doc/connect-engine/">ConnectEngine.md</a> for more engine management and more.</p>
\ No newline at end of file
......@@ -8,7 +8,7 @@
<p>This library provides a register for Message handlers that may register to both
send and receive messages through the system.</p>
<h2 id="classmessage">Class: Message</h2>
<p><code>Message</code> extends <code>Connect</code> see <a href="./Connect.md">Connect.md</a> for more engine
<p><code>Message</code> extends <code>Connect</code> see <a href="/doc/connect/">Connect.md</a> for more engine
management and more.</p>
<h3 id="staticmessagegetinstance">static Message.getInstance()</h3>
<ul>
......@@ -27,6 +27,6 @@ Return {Promise} that resolves when the message is sent.</li>
<p>Note: when no <code>name</code> is provided all handlers are executed.</p>
<h2 id="classmessageengine">Class: MessageEngine</h2>
<p><code>MessageEngine</code> extends <code>ConnectEngine</code> see
<a href="./ConnectEngine.md">ConnectEngine.md</a> for more engine management and more.</p>
<a href="/doc/connect-engine/">ConnectEngine.md</a> for more engine management and more.</p>
<h3 id="messageenginesend">MessageEngine.send()</h3>
<p>Must be extended and used to send to underlying message system.</p>
\ No newline at end of file
<h1 id="model">Model</h1>
<p><em>Introduced in 4.2.0</em></p>