First commit
This commit is contained in:
2
node_modules/avvio/.gitattributes
generated
vendored
Normal file
2
node_modules/avvio/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Set default behavior to automatically convert line endings
|
||||
* text=auto eol=lf
|
||||
13
node_modules/avvio/.github/dependabot.yml
generated
vendored
Normal file
13
node_modules/avvio/.github/dependabot.yml
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
4
node_modules/avvio/.github/release-drafter.yml
generated
vendored
Normal file
4
node_modules/avvio/.github/release-drafter.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
template: |
|
||||
## What’s Changed
|
||||
|
||||
$CHANGES
|
||||
3
node_modules/avvio/.github/tests_checker.yml
generated
vendored
Normal file
3
node_modules/avvio/.github/tests_checker.yml
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
comment: 'Could you please add tests to make sure this change works as expected?',
|
||||
fileExtensions: ['.php', '.ts', '.js', '.c', '.cs', '.cpp', '.rb', '.java']
|
||||
testDir: 'test'
|
||||
24
node_modules/avvio/.github/workflows/ci.yml
generated
vendored
Normal file
24
node_modules/avvio/.github/workflows/ci.yml
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- next
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v4.2.1
|
||||
with:
|
||||
lint: true
|
||||
license-check: true
|
||||
node-versions: '["14", "16", "18", "20", "21", "22"]'
|
||||
7
node_modules/avvio/.taprc
generated
vendored
Normal file
7
node_modules/avvio/.taprc
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
ts: false
|
||||
jsx: false
|
||||
flow: false
|
||||
check-coverage: false
|
||||
|
||||
files:
|
||||
- test/**/*test.js
|
||||
24
node_modules/avvio/LICENSE
generated
vendored
Normal file
24
node_modules/avvio/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 The Fastify Team
|
||||
Copyright (c) 2016-2020 Matteo Collina
|
||||
|
||||
The Fastify team members are listed at https://github.com/fastify/fastify#team.
|
||||
|
||||
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.
|
||||
688
node_modules/avvio/README.md
generated
vendored
Normal file
688
node_modules/avvio/README.md
generated
vendored
Normal file
@@ -0,0 +1,688 @@
|
||||
# avvio
|
||||
|
||||

|
||||
[](https://www.npmjs.com/package/avvio)
|
||||
[](https://standardjs.com/)
|
||||
|
||||
Asynchronous bootstrapping is hard, different things can go wrong, *error handling* and *load order* just to name a few. The aim of this module is to make it simple.
|
||||
|
||||
`avvio` is fully *reentrant* and *graph-based*. You can load
|
||||
components/plugins *within* plugins, and be still sure that things will
|
||||
happen in the right order. At the end of the loading, your application will start.
|
||||
|
||||
* [Install](#install)
|
||||
* [Example](#example)
|
||||
* [API](#api)
|
||||
* [Acknowledgements](#acknowledgements)
|
||||
* [License](#license)
|
||||
|
||||
<a name="install"></a>
|
||||
## Install
|
||||
|
||||
To install `avvio`, simply use npm:
|
||||
|
||||
```
|
||||
npm i avvio
|
||||
```
|
||||
|
||||
<a name="example"></a>
|
||||
## Example
|
||||
|
||||
The example below can be found [here][example] and run using `node example.js`.
|
||||
It demonstrates how to use `avvio` to load functions / plugins in order.
|
||||
|
||||
|
||||
```js
|
||||
'use strict'
|
||||
|
||||
const app = require('avvio')()
|
||||
|
||||
app
|
||||
.use(first, { hello: 'world' })
|
||||
.after((err, cb) => {
|
||||
console.log('after first and second')
|
||||
cb()
|
||||
})
|
||||
|
||||
app.use(third)
|
||||
|
||||
app.ready(function (err) {
|
||||
// the error must be handled somehow
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
console.log('application booted!')
|
||||
})
|
||||
|
||||
function first (instance, opts, cb) {
|
||||
console.log('first loaded', opts)
|
||||
instance.use(second)
|
||||
cb()
|
||||
}
|
||||
|
||||
function second (instance, opts, cb) {
|
||||
console.log('second loaded')
|
||||
process.nextTick(cb)
|
||||
}
|
||||
|
||||
// async/await or Promise support
|
||||
async function third (instance, opts) {
|
||||
console.log('third loaded')
|
||||
}
|
||||
```
|
||||
|
||||
<a name="api"></a>
|
||||
## API
|
||||
|
||||
* <a href="#constructor"><code><b>avvio()</b></code></a>
|
||||
* <a href="#use"><code>instance.<b>use()</b></code></a>
|
||||
* <a href="#after"><code>instance.<b>after()</b></code></a>
|
||||
* <a href="#await-after"><code>await instance.<b>after()</b></code></a>
|
||||
* <a href="#ready"><code>instance.<b>ready()</b></code></a>
|
||||
* <a href="#start"><code>instance.<b>start()</b></code></a>
|
||||
* <a href="#override"><code>instance.<b>override()</b></code></a>
|
||||
* <a href="#onClose"><code>instance.<b>onClose()</b></code></a>
|
||||
* <a href="#close"><code>instance.<b>close()</b></code></a>
|
||||
* <a href="#express"><code>avvio.<b>express()</b></code></a>
|
||||
* <a href="#toJSON"><code>avvio.<b>toJSON()</b></code></a>
|
||||
* <a href="#prettyPrint"><code>avvio.<b>prettyPrint()</b></code></a>
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="constructor"></a>
|
||||
|
||||
### avvio([instance], [options], [started])
|
||||
|
||||
Starts the avvio sequence.
|
||||
As the name suggests, `instance` is the object representing your application.
|
||||
Avvio will add the functions `use`, `after` and `ready` to the instance.
|
||||
|
||||
```js
|
||||
const server = {}
|
||||
|
||||
require('avvio')(server)
|
||||
|
||||
server.use(function first (s, opts, cb) {
|
||||
// s is the same of server
|
||||
s.use(function second (s, opts, cb) {
|
||||
cb()
|
||||
})
|
||||
cb()
|
||||
}).after(function (err, cb) {
|
||||
// after first and second are finished
|
||||
cb()
|
||||
})
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
* `expose`: a key/value property to change how `use`, `after` and `ready` are exposed.
|
||||
* `autostart`: do not start loading plugins automatically, but wait for
|
||||
a call to [`.start()`](#start) or [`.ready()`](#ready).
|
||||
* `timeout`: the number of millis to wait for a plugin to load after which
|
||||
it will error with code `ERR_AVVIO_PLUGIN_TIMEOUT`. Default
|
||||
`0` (disabled).
|
||||
|
||||
Events:
|
||||
|
||||
* `'start'` when the application starts
|
||||
* `'preReady'` fired before the ready queue is run
|
||||
|
||||
The `avvio` function can also be used as a
|
||||
constructor to inherit from.
|
||||
```js
|
||||
function Server () {}
|
||||
const app = require('avvio')(new Server())
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
// your code
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
// you app can start
|
||||
})
|
||||
```
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="use"></a>
|
||||
|
||||
### app.use(func, [optsOrFunc]) => Thenable
|
||||
|
||||
Loads one or more functions asynchronously.
|
||||
|
||||
The function **must** have the signature: `instance, options, done`
|
||||
|
||||
However, if the function returns a `Promise` (i.e. `async`), the above function signature is not required.
|
||||
|
||||
Plugin example:
|
||||
```js
|
||||
function plugin (server, opts, done) {
|
||||
done()
|
||||
}
|
||||
|
||||
app.use(plugin)
|
||||
```
|
||||
`done` should be called only once, when your plugin is ready to go. Additional
|
||||
calls to `done` are ignored.
|
||||
|
||||
`use` returns a thenable wrapped instance on which `use` is called, to support a chainable API that can also be awaited.
|
||||
|
||||
This way, async/await is also supported and `use` can be awaited instead of using `after`.
|
||||
|
||||
Example using `after`:
|
||||
|
||||
```js
|
||||
async function main () {
|
||||
console.log('begin')
|
||||
app.use(async function (server, opts) {
|
||||
await sleep(10)
|
||||
console.log('this first')
|
||||
})
|
||||
app.after(async (err) => {
|
||||
if (err) throw err
|
||||
console.log('then this')
|
||||
})
|
||||
await app.ready()
|
||||
console.log('ready')
|
||||
}
|
||||
main().catch((err) => console.error(err))
|
||||
```
|
||||
|
||||
Example using `await after`:
|
||||
|
||||
|
||||
```js
|
||||
async function main () {
|
||||
console.log('begin')
|
||||
app.use(async function (server, opts) {
|
||||
await sleep(10)
|
||||
console.log('this first')
|
||||
})
|
||||
await app.after()
|
||||
console.log('then this')
|
||||
await app.ready()
|
||||
console.log('ready')
|
||||
}
|
||||
main().catch((err) => console.error(err))
|
||||
```
|
||||
|
||||
Example using `await use`:
|
||||
|
||||
```js
|
||||
async function main () {
|
||||
console.log('begin')
|
||||
await app.use(async function (server, opts) {
|
||||
await sleep(10)
|
||||
console.log('this first')
|
||||
})
|
||||
console.log('then this')
|
||||
await app.ready()
|
||||
console.log('ready')
|
||||
}
|
||||
main().catch((err) => console.error(err))
|
||||
```
|
||||
|
||||
A function that returns the options argument instead of an object is supported as well:
|
||||
|
||||
```js
|
||||
function first (server, opts, done) {
|
||||
server.foo = 'bar'
|
||||
done()
|
||||
}
|
||||
|
||||
function second (server, opts, done) {
|
||||
console.log(opts.foo === 'bar') // Evaluates to true
|
||||
done()
|
||||
}
|
||||
|
||||
/**
|
||||
* If the options argument is a function, it has access to the parent
|
||||
* instance via the first positional variable
|
||||
*/
|
||||
const func = parent => {
|
||||
return {
|
||||
foo: parent.foo
|
||||
}
|
||||
}
|
||||
|
||||
app.use(first)
|
||||
app.use(second, func)
|
||||
```
|
||||
|
||||
This is useful in cases where an injected variable from a plugin needs to be made available to another.
|
||||
|
||||
It is also possible to use [esm](https://nodejs.org/api/esm.html) with `import('./file.mjs')`:
|
||||
|
||||
```js
|
||||
import boot from 'avvio'
|
||||
|
||||
const app = boot()
|
||||
app.use(import('./fixtures/esm.mjs'))
|
||||
```
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="error-handling"></a>
|
||||
#### Error handling
|
||||
|
||||
In order to handle errors in the loading plugins, you must use the
|
||||
`.ready()` method, like so:
|
||||
|
||||
```js
|
||||
app.use(function (instance, opts, done) {
|
||||
done(new Error('error'))
|
||||
}, opts)
|
||||
|
||||
app.ready(function (err) {
|
||||
if (err) throw err
|
||||
})
|
||||
```
|
||||
|
||||
When an error happens, the loading of plugins will stop until there is
|
||||
an [`after`](#after) callback specified. Otherwise, it will be handled
|
||||
in [`ready`](#ready).
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="after"></a>
|
||||
|
||||
### app.after(func(error, [context], [done]))
|
||||
|
||||
Calls a function after all the previously defined plugins are loaded, including
|
||||
all their dependencies. The `'start'` event is not emitted yet.
|
||||
|
||||
Note: `await after` can be used as an awaitable alternative to `after(func)`, or `await use` can be also as a shorthand for `use(plugin); await after()`.
|
||||
|
||||
The callback changes based on the parameters you give:
|
||||
1. If no parameter is given to the callback and there is an error, that error will be passed to the next error handler.
|
||||
2. If one parameter is given to the callback, that parameter will be the `error` object.
|
||||
3. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
|
||||
4. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` and the third the `done` callback.
|
||||
|
||||
In the "no parameter" and "one parameter" variants, the callback can return a `Promise`.
|
||||
|
||||
```js
|
||||
const server = {}
|
||||
const app = require('avvio')(server)
|
||||
|
||||
...
|
||||
// after with one parameter
|
||||
app.after(function (err) {
|
||||
if (err) throw err
|
||||
})
|
||||
|
||||
// after with two parameter
|
||||
app.after(function (err, done) {
|
||||
if (err) throw err
|
||||
done()
|
||||
})
|
||||
|
||||
// after with three parameters
|
||||
app.after(function (err, context, done) {
|
||||
if (err) throw err
|
||||
assert.equal(context, server)
|
||||
done()
|
||||
})
|
||||
|
||||
// async after with one parameter
|
||||
app.after(async function (err) {
|
||||
await sleep(10)
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
|
||||
// async after with no parameter
|
||||
app.after(async function () {
|
||||
await sleep(10)
|
||||
})
|
||||
```
|
||||
|
||||
`done` must be called only once.
|
||||
|
||||
If called with a function, it returns the instance on which `after` is called, to support a chainable API.
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="await-after"></a>
|
||||
|
||||
### await app.after() | app.after() => Promise
|
||||
|
||||
Calling after with no function argument loads any plugins previously registered via `use` and returns a promise, which resolves when all plugins registered so far have loaded.
|
||||
|
||||
```js
|
||||
async function main () {
|
||||
app.use(async function (server, opts) {
|
||||
await sleep(10)
|
||||
console.log('this first')
|
||||
})
|
||||
app.use(async function (server, opts) {
|
||||
await sleep(10)
|
||||
console.log('this second')
|
||||
})
|
||||
console.log('before after')
|
||||
await app.after()
|
||||
console.log('after after')
|
||||
app.use(async function (server, opts) {
|
||||
await sleep(10)
|
||||
console.log('this third')
|
||||
})
|
||||
await app.ready()
|
||||
console.log('ready')
|
||||
}
|
||||
main().catch((err) => console.error(err))
|
||||
```
|
||||
|
||||
Unlike `after` and `use`, `await after` is *not* chainable.
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="ready"></a>
|
||||
|
||||
### app.ready([func(error, [context], [done])])
|
||||
|
||||
Calls a function after all the plugins and `after` call are completed, but before `'start'` is emitted. `ready` callbacks are executed one at a time.
|
||||
|
||||
The callback changes based on the parameters you give:
|
||||
1. If no parameter is given to the callback and there is an error, that error will be passed to the next error handler.
|
||||
2. If one parameter is given to the callback, that parameter will be the `error` object.
|
||||
3. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
|
||||
4. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.
|
||||
|
||||
If no callback is provided `ready` will return a Promise that is resolved or rejected once plugins and `after` calls are completed. On success `context` is provided to the `.then` callback, if an error occurs it is provided to the `.catch` callback.
|
||||
|
||||
```js
|
||||
const server = {}
|
||||
const app = require('avvio')(server)
|
||||
...
|
||||
// ready with one parameter
|
||||
app.ready(function (err) {
|
||||
if (err) throw err
|
||||
})
|
||||
|
||||
// ready with two parameter
|
||||
app.ready(function (err, done) {
|
||||
if (err) throw err
|
||||
done()
|
||||
})
|
||||
|
||||
// ready with three parameters
|
||||
app.ready(function (err, context, done) {
|
||||
if (err) throw err
|
||||
assert.equal(context, server)
|
||||
done()
|
||||
})
|
||||
|
||||
// ready with Promise
|
||||
app.ready()
|
||||
.then(() => console.log('Ready'))
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
// await ready from an async function.
|
||||
async function main () [
|
||||
try {
|
||||
await app.ready()
|
||||
console.log('Ready')
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`done` must be called only once.
|
||||
|
||||
The callback form of this function has no return value.
|
||||
|
||||
If `autostart: false` is passed as an option, calling `.ready()` will
|
||||
also start the boot sequence.
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="start"></a>
|
||||
|
||||
### app.start()
|
||||
|
||||
Start the boot sequence, if it was not started yet.
|
||||
Returns the `app` instance.
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="express"></a>
|
||||
|
||||
### avvio.express(app)
|
||||
|
||||
Same as:
|
||||
|
||||
```js
|
||||
const app = express()
|
||||
const avvio = require('avvio')
|
||||
|
||||
avvio(app, {
|
||||
expose: {
|
||||
use: 'load'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
-------------------------------------------------------
|
||||
<a name="override"></a>
|
||||
|
||||
### app.override(server, plugin, options)
|
||||
|
||||
Allows overriding the instance of the server for each loading plugin.
|
||||
It allows the creation of an inheritance chain for the server instances.
|
||||
The first parameter is the server instance and the second is the plugin function while the third is the options object that you give to use.
|
||||
|
||||
```js
|
||||
const assert = require('node:assert')
|
||||
const server = { count: 0 }
|
||||
const app = require('avvio')(server)
|
||||
|
||||
console.log(app !== server, 'override must be set on the Avvio instance')
|
||||
|
||||
app.override = function (s, fn, opts) {
|
||||
// create a new instance with the
|
||||
// server as the prototype
|
||||
const res = Object.create(s)
|
||||
res.count = res.count + 1
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s1, opts, cb) {
|
||||
assert(s1 !== server)
|
||||
assert(Object.prototype.isPrototypeOf.call(server, s1))
|
||||
assert(s1.count === 1)
|
||||
s1.use(second)
|
||||
cb()
|
||||
|
||||
function second (s2, opts, cb) {
|
||||
assert(s2 !== s1)
|
||||
assert(Object.prototype.isPrototypeOf.isPrototypeOf.call(s1, s2))
|
||||
assert(s2.count === 2)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
```
|
||||
-------------------------------------------------------
|
||||
|
||||
<a name="onClose"></a>
|
||||
### app.onClose(func([context], [done]))
|
||||
|
||||
Registers a new callback that will be fired once then `close` api is called.
|
||||
|
||||
The callback changes basing on the parameters you give:
|
||||
1. If one parameter is given to the callback, that parameter will be the `context`.
|
||||
2. If zero or one parameter is given, the callback may return a promise
|
||||
3. If two parameters are given to the callback, the first will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, the second will be the `done` callback.
|
||||
|
||||
```js
|
||||
const server = {}
|
||||
const app = require('avvio')(server)
|
||||
...
|
||||
// onClose with one parameter
|
||||
app.onClose(function (context) {
|
||||
// ...
|
||||
})
|
||||
|
||||
// onClose with one parameter, returning a promise
|
||||
app.onClose(function (context) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// ...
|
||||
})
|
||||
})
|
||||
|
||||
// async onClose with one parameter
|
||||
app.onClose(async function (context) {
|
||||
// ...
|
||||
await ...
|
||||
})
|
||||
|
||||
|
||||
// onClose with two parameter
|
||||
app.onClose(function (context, done) {
|
||||
// ...
|
||||
done()
|
||||
})
|
||||
```
|
||||
|
||||
If the callback returns a promise, the next onClose callback and the close callback will not run until the promise is either resolved or rejected.
|
||||
|
||||
`done` must be called only once.
|
||||
Returns the instance on which `onClose` is called, to support a chainable API.
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
<a name="close"></a>
|
||||
### app.close(func(error, [context], [done]))
|
||||
|
||||
Starts the shutdown procedure, the callback is called once all the registered callbacks with `onClose` has been executed.
|
||||
|
||||
The callback changes based on the parameters you give:
|
||||
1. If one parameter is given to the callback, that parameter will be the `error` object.
|
||||
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
|
||||
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.
|
||||
|
||||
If no callback is provided `close` will return a Promise.
|
||||
|
||||
```js
|
||||
const server = {}
|
||||
const app = require('avvio')(server)
|
||||
...
|
||||
// close with one parameter
|
||||
app.close(function (err) {
|
||||
if (err) throw err
|
||||
})
|
||||
|
||||
// close with two parameter
|
||||
app.close(function (err, done) {
|
||||
if (err) throw err
|
||||
done()
|
||||
})
|
||||
|
||||
// close with three parameters
|
||||
app.close(function (err, context, done) {
|
||||
if (err) throw err
|
||||
assert.equal(context, server)
|
||||
done()
|
||||
})
|
||||
|
||||
// close with Promise
|
||||
app.close()
|
||||
.then(() => console.log('Closed'))
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
`done` must be called only once.
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
<a name="toJSON"></a>
|
||||
|
||||
### avvio.toJSON()
|
||||
|
||||
Return a JSON tree representing the state of the plugins and the loading time.
|
||||
Call it on `preReady` to get the complete tree.
|
||||
|
||||
```js
|
||||
const avvio = require('avvio')()
|
||||
avvio.on('preReady', () => {
|
||||
avvio.toJSON()
|
||||
})
|
||||
```
|
||||
|
||||
The output is like this:
|
||||
```json
|
||||
{
|
||||
"label": "root",
|
||||
"start": 1550245184665,
|
||||
"nodes": [
|
||||
{
|
||||
"parent": "root",
|
||||
"start": 1550245184665,
|
||||
"label": "first",
|
||||
"nodes": [
|
||||
{
|
||||
"parent": "first",
|
||||
"start": 1550245184708,
|
||||
"label": "second",
|
||||
"nodes": [],
|
||||
"stop": 1550245184709,
|
||||
"diff": 1
|
||||
}
|
||||
],
|
||||
"stop": 1550245184709,
|
||||
"diff": 44
|
||||
},
|
||||
{
|
||||
"parent": "root",
|
||||
"start": 1550245184709,
|
||||
"label": "third",
|
||||
"nodes": [],
|
||||
"stop": 1550245184709,
|
||||
"diff": 0
|
||||
}
|
||||
],
|
||||
"stop": 1550245184709,
|
||||
"diff": 44
|
||||
}
|
||||
```
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
<a name="prettyPrint"></a>
|
||||
|
||||
### avvio.prettyPrint()
|
||||
|
||||
This method will return a printable string with the tree returned by the `toJSON()` method.
|
||||
|
||||
```js
|
||||
const avvio = require('avvio')()
|
||||
avvio.on('preReady', () => {
|
||||
console.log(avvio.prettyPrint())
|
||||
})
|
||||
```
|
||||
|
||||
The output will be like:
|
||||
|
||||
```
|
||||
avvio 56 ms
|
||||
├── first 52 ms
|
||||
├── second 1 ms
|
||||
└── third 2 ms
|
||||
```
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
This project was kindly sponsored by [nearForm](https://nearform.com).
|
||||
|
||||
## License
|
||||
|
||||
Copyright Matteo Collina 2016-2020, Licensed under [MIT][].
|
||||
|
||||
[MIT]: ./LICENSE
|
||||
[example]: ./examples/example.js
|
||||
614
node_modules/avvio/boot.js
generated
vendored
Normal file
614
node_modules/avvio/boot.js
generated
vendored
Normal file
@@ -0,0 +1,614 @@
|
||||
'use strict'
|
||||
|
||||
const fastq = require('fastq')
|
||||
const EE = require('node:events').EventEmitter
|
||||
const inherits = require('node:util').inherits
|
||||
const {
|
||||
AVV_ERR_EXPOSE_ALREADY_DEFINED,
|
||||
AVV_ERR_CALLBACK_NOT_FN,
|
||||
AVV_ERR_ROOT_PLG_BOOTED,
|
||||
AVV_ERR_READY_TIMEOUT,
|
||||
AVV_ERR_ATTRIBUTE_ALREADY_DEFINED
|
||||
} = require('./lib/errors')
|
||||
const {
|
||||
kAvvio,
|
||||
kIsOnCloseHandler
|
||||
} = require('./lib/symbols')
|
||||
const { TimeTree } = require('./lib/time-tree')
|
||||
const { Plugin } = require('./lib/plugin')
|
||||
const { debug } = require('./lib/debug')
|
||||
const { validatePlugin } = require('./lib/validate-plugin')
|
||||
const { isBundledOrTypescriptPlugin } = require('./lib/is-bundled-or-typescript-plugin')
|
||||
const { isPromiseLike } = require('./lib/is-promise-like')
|
||||
const { thenify } = require('./lib/thenify')
|
||||
const { executeWithThenable } = require('./lib/execute-with-thenable')
|
||||
|
||||
function Boot (server, opts, done) {
|
||||
if (typeof server === 'function' && arguments.length === 1) {
|
||||
done = server
|
||||
opts = {}
|
||||
server = null
|
||||
}
|
||||
|
||||
if (typeof opts === 'function') {
|
||||
done = opts
|
||||
opts = {}
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
opts.autostart = opts.autostart !== false
|
||||
opts.timeout = Number(opts.timeout) || 0
|
||||
opts.expose = opts.expose || {}
|
||||
|
||||
if (!new.target) {
|
||||
return new Boot(server, opts, done)
|
||||
}
|
||||
|
||||
this._server = server || this
|
||||
this._opts = opts
|
||||
|
||||
if (server) {
|
||||
this._expose()
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Array<Plugin>}
|
||||
*/
|
||||
this._current = []
|
||||
|
||||
this._error = null
|
||||
|
||||
this._lastUsed = null
|
||||
|
||||
this.setMaxListeners(0)
|
||||
|
||||
if (done) {
|
||||
this.once('start', done)
|
||||
}
|
||||
|
||||
this.started = false
|
||||
this.booted = false
|
||||
this.pluginTree = new TimeTree()
|
||||
|
||||
this._readyQ = fastq(this, callWithCbOrNextTick, 1)
|
||||
this._readyQ.pause()
|
||||
this._readyQ.drain = () => {
|
||||
this.emit('start')
|
||||
// nooping this, we want to emit start only once
|
||||
this._readyQ.drain = noop
|
||||
}
|
||||
|
||||
this._closeQ = fastq(this, closeWithCbOrNextTick, 1)
|
||||
this._closeQ.pause()
|
||||
this._closeQ.drain = () => {
|
||||
this.emit('close')
|
||||
// nooping this, we want to emit close only once
|
||||
this._closeQ.drain = noop
|
||||
}
|
||||
|
||||
this._doStart = null
|
||||
|
||||
const instance = this
|
||||
this._root = new Plugin(fastq(this, this._loadPluginNextTick, 1), function root (server, opts, done) {
|
||||
instance._doStart = done
|
||||
opts.autostart && instance.start()
|
||||
}, opts, false, 0)
|
||||
|
||||
this._trackPluginLoading(this._root)
|
||||
|
||||
this._loadPlugin(this._root, (err) => {
|
||||
debug('root plugin ready')
|
||||
try {
|
||||
this.emit('preReady')
|
||||
this._root = null
|
||||
} catch (preReadyError) {
|
||||
err = err || this._error || preReadyError
|
||||
}
|
||||
|
||||
if (err) {
|
||||
this._error = err
|
||||
if (this._readyQ.length() === 0) {
|
||||
throw err
|
||||
}
|
||||
} else {
|
||||
this.booted = true
|
||||
}
|
||||
this._readyQ.resume()
|
||||
})
|
||||
}
|
||||
|
||||
inherits(Boot, EE)
|
||||
|
||||
Boot.prototype.start = function () {
|
||||
this.started = true
|
||||
|
||||
// we need to wait any call to use() to happen
|
||||
process.nextTick(this._doStart)
|
||||
return this
|
||||
}
|
||||
|
||||
// allows to override the instance of a server, given a plugin
|
||||
Boot.prototype.override = function (server, func, opts) {
|
||||
return server
|
||||
}
|
||||
|
||||
Boot.prototype[kAvvio] = true
|
||||
|
||||
// load a plugin
|
||||
Boot.prototype.use = function (plugin, opts) {
|
||||
this._lastUsed = this._addPlugin(plugin, opts, false)
|
||||
return this
|
||||
}
|
||||
|
||||
Boot.prototype._loadRegistered = function () {
|
||||
const plugin = this._current[0]
|
||||
const weNeedToStart = !this.started && !this.booted
|
||||
|
||||
// if the root plugin is not loaded, let's resume that
|
||||
// so one can use after() before calling ready
|
||||
if (weNeedToStart) {
|
||||
process.nextTick(() => this._root.queue.resume())
|
||||
}
|
||||
|
||||
if (!plugin) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return plugin.loadedSoFar()
|
||||
}
|
||||
|
||||
Object.defineProperty(Boot.prototype, 'then', { get: thenify })
|
||||
|
||||
Boot.prototype._addPlugin = function (pluginFn, opts, isAfter) {
|
||||
if (isBundledOrTypescriptPlugin(pluginFn)) {
|
||||
pluginFn = pluginFn.default
|
||||
}
|
||||
validatePlugin(pluginFn)
|
||||
opts = opts || {}
|
||||
|
||||
if (this.booted) {
|
||||
throw new AVV_ERR_ROOT_PLG_BOOTED()
|
||||
}
|
||||
|
||||
// we always add plugins to load at the current element
|
||||
const current = this._current[0]
|
||||
|
||||
let timeout = this._opts.timeout
|
||||
|
||||
if (!current.loaded && current.timeout > 0) {
|
||||
const delta = Date.now() - current.startTime
|
||||
// We need to decrease it by 3ms to make sure the internal timeout
|
||||
// is triggered earlier than the parent
|
||||
timeout = current.timeout - (delta + 3)
|
||||
}
|
||||
|
||||
const plugin = new Plugin(fastq(this, this._loadPluginNextTick, 1), pluginFn, opts, isAfter, timeout)
|
||||
this._trackPluginLoading(plugin)
|
||||
|
||||
if (current.loaded) {
|
||||
throw new Error(plugin.name, current.name)
|
||||
}
|
||||
|
||||
// we add the plugin to be loaded at the end of the current queue
|
||||
current.enqueue(plugin, (err) => { err && (this._error = err) })
|
||||
|
||||
return plugin
|
||||
}
|
||||
|
||||
Boot.prototype._expose = function _expose () {
|
||||
const instance = this
|
||||
const server = instance._server
|
||||
const {
|
||||
use: useKey = 'use',
|
||||
after: afterKey = 'after',
|
||||
ready: readyKey = 'ready',
|
||||
onClose: onCloseKey = 'onClose',
|
||||
close: closeKey = 'close'
|
||||
} = this._opts.expose
|
||||
|
||||
if (server[useKey]) {
|
||||
throw new AVV_ERR_EXPOSE_ALREADY_DEFINED(useKey, 'use')
|
||||
}
|
||||
server[useKey] = function (fn, opts) {
|
||||
instance.use(fn, opts)
|
||||
return this
|
||||
}
|
||||
|
||||
if (server[afterKey]) {
|
||||
throw new AVV_ERR_EXPOSE_ALREADY_DEFINED(afterKey, 'after')
|
||||
}
|
||||
server[afterKey] = function (func) {
|
||||
if (typeof func !== 'function') {
|
||||
return instance._loadRegistered()
|
||||
}
|
||||
instance.after(encapsulateThreeParam(func, this))
|
||||
return this
|
||||
}
|
||||
|
||||
if (server[readyKey]) {
|
||||
throw new AVV_ERR_EXPOSE_ALREADY_DEFINED(readyKey, 'ready')
|
||||
}
|
||||
server[readyKey] = function (func) {
|
||||
if (func && typeof func !== 'function') {
|
||||
throw new AVV_ERR_CALLBACK_NOT_FN(readyKey, typeof func)
|
||||
}
|
||||
return instance.ready(func ? encapsulateThreeParam(func, this) : undefined)
|
||||
}
|
||||
|
||||
if (server[onCloseKey]) {
|
||||
throw new AVV_ERR_EXPOSE_ALREADY_DEFINED(onCloseKey, 'onClose')
|
||||
}
|
||||
server[onCloseKey] = function (func) {
|
||||
if (typeof func !== 'function') {
|
||||
throw new AVV_ERR_CALLBACK_NOT_FN(onCloseKey, typeof func)
|
||||
}
|
||||
instance.onClose(encapsulateTwoParam(func, this))
|
||||
return this
|
||||
}
|
||||
|
||||
if (server[closeKey]) {
|
||||
throw new AVV_ERR_EXPOSE_ALREADY_DEFINED(closeKey, 'close')
|
||||
}
|
||||
server[closeKey] = function (func) {
|
||||
if (func && typeof func !== 'function') {
|
||||
throw new AVV_ERR_CALLBACK_NOT_FN(closeKey, typeof func)
|
||||
}
|
||||
|
||||
if (func) {
|
||||
instance.close(encapsulateThreeParam(func, this))
|
||||
return this
|
||||
}
|
||||
|
||||
// this is a Promise
|
||||
return instance.close()
|
||||
}
|
||||
|
||||
if (server.then) {
|
||||
throw new AVV_ERR_ATTRIBUTE_ALREADY_DEFINED('then')
|
||||
}
|
||||
Object.defineProperty(server, 'then', { get: thenify.bind(instance) })
|
||||
|
||||
server[kAvvio] = true
|
||||
}
|
||||
|
||||
Boot.prototype.after = function (func) {
|
||||
if (!func) {
|
||||
return this._loadRegistered()
|
||||
}
|
||||
|
||||
this._addPlugin(_after.bind(this), {}, true)
|
||||
|
||||
function _after (s, opts, done) {
|
||||
callWithCbOrNextTick.call(this, func, done)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Boot.prototype.onClose = function (func) {
|
||||
// this is used to distinguish between onClose and close handlers
|
||||
// because they share the same queue but must be called with different signatures
|
||||
|
||||
if (typeof func !== 'function') {
|
||||
throw new AVV_ERR_CALLBACK_NOT_FN('onClose', typeof func)
|
||||
}
|
||||
|
||||
func[kIsOnCloseHandler] = true
|
||||
this._closeQ.unshift(func, (err) => { err && (this._error = err) })
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Boot.prototype.close = function (func) {
|
||||
let promise
|
||||
|
||||
if (func) {
|
||||
if (typeof func !== 'function') {
|
||||
throw new AVV_ERR_CALLBACK_NOT_FN('close', typeof func)
|
||||
}
|
||||
} else {
|
||||
promise = new Promise(function (resolve, reject) {
|
||||
func = function (err) {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.ready(() => {
|
||||
this._error = null
|
||||
this._closeQ.push(func)
|
||||
process.nextTick(this._closeQ.resume.bind(this._closeQ))
|
||||
})
|
||||
|
||||
return promise
|
||||
}
|
||||
|
||||
Boot.prototype.ready = function (func) {
|
||||
if (func) {
|
||||
if (typeof func !== 'function') {
|
||||
throw new AVV_ERR_CALLBACK_NOT_FN('ready', typeof func)
|
||||
}
|
||||
this._readyQ.push(func)
|
||||
queueMicrotask(this.start.bind(this))
|
||||
return
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this._readyQ.push(readyPromiseCB)
|
||||
this.start()
|
||||
|
||||
/**
|
||||
* The `encapsulateThreeParam` let callback function
|
||||
* bind to the right server instance.
|
||||
* In promises we need to track the last server
|
||||
* instance loaded, the first one in the _current queue.
|
||||
*/
|
||||
const relativeContext = this._current[0].server
|
||||
|
||||
function readyPromiseCB (err, context, done) {
|
||||
// the context is always binded to the root server
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(relativeContext)
|
||||
}
|
||||
process.nextTick(done)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Plugin} plugin
|
||||
* @returns {void}
|
||||
*/
|
||||
Boot.prototype._trackPluginLoading = function (plugin) {
|
||||
const parentName = this._current[0]?.name || null
|
||||
plugin.once('start', (serverName, funcName, time) => {
|
||||
const nodeId = this.pluginTree.start(parentName || null, funcName, time)
|
||||
plugin.once('loaded', (serverName, funcName, time) => {
|
||||
this.pluginTree.stop(nodeId, time)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Boot.prototype.prettyPrint = function () {
|
||||
return this.pluginTree.prettyPrint()
|
||||
}
|
||||
|
||||
Boot.prototype.toJSON = function () {
|
||||
return this.pluginTree.toJSON()
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback LoadPluginCallback
|
||||
* @param {Error} [err]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load a plugin
|
||||
*
|
||||
* @param {Plugin} plugin
|
||||
* @param {LoadPluginCallback} callback
|
||||
*/
|
||||
Boot.prototype._loadPlugin = function (plugin, callback) {
|
||||
const instance = this
|
||||
if (isPromiseLike(plugin.func)) {
|
||||
plugin.func.then((fn) => {
|
||||
if (typeof fn.default === 'function') {
|
||||
fn = fn.default
|
||||
}
|
||||
plugin.func = fn
|
||||
this._loadPlugin(plugin, callback)
|
||||
}, callback)
|
||||
return
|
||||
}
|
||||
|
||||
const last = instance._current[0]
|
||||
|
||||
// place the plugin at the top of _current
|
||||
instance._current.unshift(plugin)
|
||||
|
||||
if (instance._error && !plugin.isAfter) {
|
||||
debug('skipping loading of plugin as instance errored and it is not an after', plugin.name)
|
||||
process.nextTick(execCallback)
|
||||
return
|
||||
}
|
||||
|
||||
let server = (last && last.server) || instance._server
|
||||
|
||||
if (!plugin.isAfter) {
|
||||
// Skip override for after
|
||||
try {
|
||||
server = instance.override(server, plugin.func, plugin.options)
|
||||
} catch (overrideErr) {
|
||||
debug('override errored', plugin.name)
|
||||
return execCallback(overrideErr)
|
||||
}
|
||||
}
|
||||
|
||||
plugin.exec(server, execCallback)
|
||||
|
||||
function execCallback (err) {
|
||||
plugin.finish(err, (err) => {
|
||||
instance._current.shift()
|
||||
callback(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delays plugin loading until the next tick to ensure any bound `_after` callbacks have a chance
|
||||
* to run prior to executing the next plugin
|
||||
*/
|
||||
Boot.prototype._loadPluginNextTick = function (plugin, callback) {
|
||||
process.nextTick(this._loadPlugin.bind(this), plugin, callback)
|
||||
}
|
||||
|
||||
function noop () { }
|
||||
|
||||
function callWithCbOrNextTick (func, cb) {
|
||||
const context = this._server
|
||||
const err = this._error
|
||||
|
||||
// with this the error will appear just in the next after/ready callback
|
||||
this._error = null
|
||||
if (func.length === 0) {
|
||||
this._error = err
|
||||
executeWithThenable(func, [], cb)
|
||||
} else if (func.length === 1) {
|
||||
executeWithThenable(func, [err], cb)
|
||||
} else {
|
||||
if (this._opts.timeout === 0) {
|
||||
const wrapCb = (err) => {
|
||||
this._error = err
|
||||
cb(this._error)
|
||||
}
|
||||
|
||||
if (func.length === 2) {
|
||||
func(err, wrapCb)
|
||||
} else {
|
||||
func(err, context, wrapCb)
|
||||
}
|
||||
} else {
|
||||
timeoutCall.call(this, func, err, context, cb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function timeoutCall (func, rootErr, context, cb) {
|
||||
const name = func.unwrappedName ?? func.name
|
||||
debug('setting up ready timeout', name, this._opts.timeout)
|
||||
let timer = setTimeout(() => {
|
||||
debug('timed out', name)
|
||||
timer = null
|
||||
const toutErr = new AVV_ERR_READY_TIMEOUT(name)
|
||||
toutErr.fn = func
|
||||
this._error = toutErr
|
||||
cb(toutErr)
|
||||
}, this._opts.timeout)
|
||||
|
||||
if (func.length === 2) {
|
||||
func(rootErr, timeoutCb.bind(this))
|
||||
} else {
|
||||
func(rootErr, context, timeoutCb.bind(this))
|
||||
}
|
||||
|
||||
function timeoutCb (err) {
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
this._error = err
|
||||
cb(this._error)
|
||||
} else {
|
||||
// timeout has been triggered
|
||||
// can not call cb twice
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function closeWithCbOrNextTick (func, cb) {
|
||||
const context = this._server
|
||||
const isOnCloseHandler = func[kIsOnCloseHandler]
|
||||
if (func.length === 0 || func.length === 1) {
|
||||
let promise
|
||||
if (isOnCloseHandler) {
|
||||
promise = func(context)
|
||||
} else {
|
||||
promise = func(this._error)
|
||||
}
|
||||
if (promise && typeof promise.then === 'function') {
|
||||
debug('resolving close/onClose promise')
|
||||
promise.then(
|
||||
() => process.nextTick(cb),
|
||||
(e) => process.nextTick(cb, e))
|
||||
} else {
|
||||
process.nextTick(cb)
|
||||
}
|
||||
} else if (func.length === 2) {
|
||||
if (isOnCloseHandler) {
|
||||
func(context, cb)
|
||||
} else {
|
||||
func(this._error, cb)
|
||||
}
|
||||
} else {
|
||||
if (isOnCloseHandler) {
|
||||
func(context, cb)
|
||||
} else {
|
||||
func(this._error, context, cb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function encapsulateTwoParam (func, that) {
|
||||
return _encapsulateTwoParam.bind(that)
|
||||
function _encapsulateTwoParam (context, cb) {
|
||||
let res
|
||||
if (func.length === 0) {
|
||||
res = func()
|
||||
if (res && res.then) {
|
||||
res.then(function () {
|
||||
process.nextTick(cb)
|
||||
}, cb)
|
||||
} else {
|
||||
process.nextTick(cb)
|
||||
}
|
||||
} else if (func.length === 1) {
|
||||
res = func(this)
|
||||
|
||||
if (res && res.then) {
|
||||
res.then(function () {
|
||||
process.nextTick(cb)
|
||||
}, cb)
|
||||
} else {
|
||||
process.nextTick(cb)
|
||||
}
|
||||
} else {
|
||||
func(this, cb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function encapsulateThreeParam (func, that) {
|
||||
const wrapped = _encapsulateThreeParam.bind(that)
|
||||
wrapped.unwrappedName = func.name
|
||||
return wrapped
|
||||
function _encapsulateThreeParam (err, cb) {
|
||||
let res
|
||||
if (!func) {
|
||||
process.nextTick(cb)
|
||||
} else if (func.length === 0) {
|
||||
res = func()
|
||||
if (res && res.then) {
|
||||
res.then(function () {
|
||||
process.nextTick(cb, err)
|
||||
}, cb)
|
||||
} else {
|
||||
process.nextTick(cb, err)
|
||||
}
|
||||
} else if (func.length === 1) {
|
||||
res = func(err)
|
||||
if (res && res.then) {
|
||||
res.then(function () {
|
||||
process.nextTick(cb)
|
||||
}, cb)
|
||||
} else {
|
||||
process.nextTick(cb)
|
||||
}
|
||||
} else if (func.length === 2) {
|
||||
func(err, cb)
|
||||
} else {
|
||||
func(err, this, cb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Boot
|
||||
module.exports.express = function (app) {
|
||||
return Boot(app, {
|
||||
expose: {
|
||||
use: 'load'
|
||||
}
|
||||
})
|
||||
}
|
||||
72
node_modules/avvio/examples/example.js
generated
vendored
Normal file
72
node_modules/avvio/examples/example.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
'use strict'
|
||||
|
||||
const avvio = require('..')()
|
||||
|
||||
function a (instance, opts, cb) {
|
||||
(opts.use || []).forEach(_ => { instance.use(_, { use: opts.subUse || [] }) })
|
||||
setTimeout(cb, 10)
|
||||
}
|
||||
const pointer = a
|
||||
|
||||
function b (instance, opts, cb) {
|
||||
(opts.use || []).forEach(_ => { instance.use(_, { use: opts.subUse || [] }) })
|
||||
setTimeout(cb, 20)
|
||||
}
|
||||
|
||||
function c (instance, opts, cb) {
|
||||
(opts.use || []).forEach(_ => { instance.use(_, { use: opts.subUse || [] }) })
|
||||
setTimeout(cb, 30)
|
||||
}
|
||||
|
||||
avvio
|
||||
.use(first, { hello: 'world' })
|
||||
.use(duplicate, { count: 0 })
|
||||
.use(function a (instance, opts, cb) {
|
||||
instance.use(pointer, { use: [b], subUse: [c] })
|
||||
.use(b)
|
||||
setTimeout(cb, 42)
|
||||
})
|
||||
.after(function (err, cb) {
|
||||
if (err) {
|
||||
console.log('something bad happened')
|
||||
console.log(err)
|
||||
}
|
||||
console.log('after first and second')
|
||||
cb()
|
||||
})
|
||||
.use(duplicate, { count: 4 })
|
||||
.use(third)
|
||||
.ready(function (err) {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
console.log('application booted!')
|
||||
})
|
||||
|
||||
avvio.on('preReady', () => {
|
||||
console.log(avvio.prettyPrint())
|
||||
})
|
||||
|
||||
function first (instance, opts, cb) {
|
||||
console.log('first loaded', opts)
|
||||
instance.use(second)
|
||||
setTimeout(cb, 42)
|
||||
}
|
||||
|
||||
function second (instance, opts, cb) {
|
||||
console.log('second loaded')
|
||||
process.nextTick(cb)
|
||||
}
|
||||
|
||||
function third (instance, opts, cb) {
|
||||
console.log('third loaded')
|
||||
cb()
|
||||
}
|
||||
|
||||
function duplicate (instance, opts, cb) {
|
||||
console.log('duplicate loaded', opts.count)
|
||||
if (opts.count > 0) {
|
||||
instance.use(duplicate, { count: opts.count - 1 })
|
||||
}
|
||||
setTimeout(cb, 20)
|
||||
}
|
||||
92
node_modules/avvio/index.d.ts
generated
vendored
Normal file
92
node_modules/avvio/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
declare function avvio(done?: Function): avvio.Avvio<null>;
|
||||
declare function avvio<I>(
|
||||
instance: I,
|
||||
options?: avvio.Options,
|
||||
done?: Function
|
||||
): avvio.Avvio<I>;
|
||||
|
||||
/**
|
||||
* Typescript cannot manage changes related to options "expose"
|
||||
* because undefined before runtime
|
||||
*/
|
||||
declare namespace avvio {
|
||||
type context<I> = I extends null ? Avvio<I> : mixedInstance<I>;
|
||||
type mixedInstance<I> = I & Server<I>;
|
||||
|
||||
interface Options {
|
||||
expose?: {
|
||||
use?: string;
|
||||
after?: string;
|
||||
ready?: string;
|
||||
close?: string;
|
||||
onClose?: string;
|
||||
};
|
||||
autostart?: boolean;
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
interface Plugin<O, I> {
|
||||
(server: context<I>, options: O, done: (err?: Error) => void): unknown;
|
||||
}
|
||||
|
||||
interface Server<I> {
|
||||
use: Use<I>;
|
||||
after: After<I>;
|
||||
ready: Ready<I>;
|
||||
close: Close<I>;
|
||||
onClose: OnClose<I>;
|
||||
}
|
||||
|
||||
interface Avvio<I> extends EventEmitter, Server<I> {
|
||||
on(event: "start", listener: () => void): this;
|
||||
on(event: "preReady", listener: () => void): this;
|
||||
on(event: "close", listener: () => void): this;
|
||||
|
||||
start(): this;
|
||||
|
||||
toJSON(): Object;
|
||||
|
||||
prettyPrint(): string;
|
||||
|
||||
override: (
|
||||
server: context<I>,
|
||||
fn: Plugin<any, I>,
|
||||
options: any
|
||||
) => context<I>;
|
||||
|
||||
started: boolean;
|
||||
booted: boolean;
|
||||
}
|
||||
|
||||
// Avvio methods
|
||||
interface After<I, C = context<I>> {
|
||||
(fn: (err: Error) => void): C;
|
||||
(fn: (err: Error, done: Function) => void): C;
|
||||
(fn: (err: Error, context: C, done: Function) => void): C;
|
||||
}
|
||||
|
||||
interface Use<I, C = context<I>> {
|
||||
<O>(fn: avvio.Plugin<O, I>, options?: O | ((server: C) => O)): C;
|
||||
}
|
||||
|
||||
interface Ready<I, C = context<I>> {
|
||||
(): Promise<C>;
|
||||
(callback: (err?: Error) => void): void;
|
||||
(callback: (err: Error, done: Function) => void): void;
|
||||
(callback: (err: Error, context: C, done: Function) => void): void;
|
||||
}
|
||||
|
||||
interface Close<I, C = context<I>> {
|
||||
(fn: (err: Error) => void): void;
|
||||
(fn: (err: Error, done: Function) => void): void;
|
||||
(fn: (err: Error, context: C, done: Function) => void): void;
|
||||
}
|
||||
|
||||
interface OnClose<I, C = context<I>> {
|
||||
(fn: (context: C, done: Function) => void): C;
|
||||
}
|
||||
}
|
||||
|
||||
export = avvio;
|
||||
45
node_modules/avvio/lib/create-promise.js
generated
vendored
Normal file
45
node_modules/avvio/lib/create-promise.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @callback PromiseResolve
|
||||
* @param {any|PromiseLike<any>} value
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback PromiseReject
|
||||
* @param {any} reason
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef PromiseObject
|
||||
* @property {Promise} promise
|
||||
* @property {PromiseResolve} resolve
|
||||
* @property {PromiseReject} reject
|
||||
*/
|
||||
|
||||
/**
|
||||
* @returns {PromiseObject}
|
||||
*/
|
||||
function createPromise () {
|
||||
/**
|
||||
* @type {PromiseObject}
|
||||
*/
|
||||
const obj = {
|
||||
resolve: null,
|
||||
reject: null,
|
||||
promise: null
|
||||
}
|
||||
|
||||
obj.promise = new Promise((resolve, reject) => {
|
||||
obj.resolve = resolve
|
||||
obj.reject = reject
|
||||
})
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createPromise
|
||||
}
|
||||
19
node_modules/avvio/lib/debug.js
generated
vendored
Normal file
19
node_modules/avvio/lib/debug.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict'
|
||||
|
||||
const { debuglog } = require('node:util')
|
||||
|
||||
/**
|
||||
* @callback DebugLogger
|
||||
* @param {string} msg
|
||||
* @param {...unknown} param
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {DebugLogger}
|
||||
*/
|
||||
const debug = debuglog('avvio')
|
||||
|
||||
module.exports = {
|
||||
debug
|
||||
}
|
||||
38
node_modules/avvio/lib/errors.js
generated
vendored
Normal file
38
node_modules/avvio/lib/errors.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict'
|
||||
|
||||
const { createError } = require('@fastify/error')
|
||||
|
||||
module.exports = {
|
||||
AVV_ERR_EXPOSE_ALREADY_DEFINED: createError(
|
||||
'AVV_ERR_EXPOSE_ALREADY_DEFINED',
|
||||
"'%s' is already defined, specify an expose option for '%s'"
|
||||
),
|
||||
AVV_ERR_ATTRIBUTE_ALREADY_DEFINED: createError(
|
||||
'AVV_ERR_ATTRIBUTE_ALREADY_DEFINED',
|
||||
"'%s' is already defined"
|
||||
),
|
||||
AVV_ERR_CALLBACK_NOT_FN: createError(
|
||||
'AVV_ERR_CALLBACK_NOT_FN',
|
||||
"Callback for '%s' hook is not a function. Received: '%s'"
|
||||
),
|
||||
AVV_ERR_PLUGIN_NOT_VALID: createError(
|
||||
'AVV_ERR_PLUGIN_NOT_VALID',
|
||||
"Plugin must be a function or a promise. Received: '%s'"
|
||||
),
|
||||
AVV_ERR_ROOT_PLG_BOOTED: createError(
|
||||
'AVV_ERR_ROOT_PLG_BOOTED',
|
||||
'Root plugin has already booted'
|
||||
),
|
||||
AVV_ERR_PARENT_PLG_LOADED: createError(
|
||||
'AVV_ERR_PARENT_PLG_LOADED',
|
||||
"Impossible to load '%s' plugin because the parent '%s' was already loaded"
|
||||
),
|
||||
AVV_ERR_READY_TIMEOUT: createError(
|
||||
'AVV_ERR_READY_TIMEOUT',
|
||||
"Plugin did not start in time: '%s'. You may have forgotten to call 'done' function or to resolve a Promise"
|
||||
),
|
||||
AVV_ERR_PLUGIN_EXEC_TIMEOUT: createError(
|
||||
'AVV_ERR_PLUGIN_EXEC_TIMEOUT',
|
||||
"Plugin did not start in time: '%s'. You may have forgotten to call 'done' function or to resolve a Promise"
|
||||
)
|
||||
}
|
||||
28
node_modules/avvio/lib/execute-with-thenable.js
generated
vendored
Normal file
28
node_modules/avvio/lib/execute-with-thenable.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict'
|
||||
const { isPromiseLike } = require('./is-promise-like')
|
||||
const { kAvvio } = require('./symbols')
|
||||
|
||||
/**
|
||||
* @callback ExecuteWithThenableCallback
|
||||
* @param {Error} error
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Function} func
|
||||
* @param {Array<any>} args
|
||||
* @param {ExecuteWithThenableCallback} [callback]
|
||||
*/
|
||||
function executeWithThenable (func, args, callback) {
|
||||
const result = func.apply(func, args)
|
||||
if (isPromiseLike(result) && !result[kAvvio]) {
|
||||
// process promise but not avvio mock thenable
|
||||
result.then(() => process.nextTick(callback), (error) => process.nextTick(callback, error))
|
||||
} else if (callback) {
|
||||
process.nextTick(callback)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
executeWithThenable
|
||||
}
|
||||
34
node_modules/avvio/lib/get-plugin-name.js
generated
vendored
Normal file
34
node_modules/avvio/lib/get-plugin-name.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
|
||||
// this symbol is assigned by fastify-plugin
|
||||
const { kPluginMeta } = require('./symbols')
|
||||
|
||||
/**
|
||||
* @param {function} plugin
|
||||
* @param {object} [options]
|
||||
* @param {string} [options.name]
|
||||
* @returns {string}
|
||||
*/
|
||||
function getPluginName (plugin, options) {
|
||||
// use explicit function metadata if set
|
||||
if (plugin[kPluginMeta] && plugin[kPluginMeta].name) {
|
||||
return plugin[kPluginMeta].name
|
||||
}
|
||||
|
||||
// use explicit name option if set
|
||||
if (options && options.name) {
|
||||
return options.name
|
||||
}
|
||||
|
||||
// determine from the function
|
||||
if (plugin.name) {
|
||||
return plugin.name
|
||||
} else {
|
||||
// takes the first two lines of the function if nothing else works
|
||||
return plugin.toString().split('\n').slice(0, 2).map(s => s.trim()).join(' -- ')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getPluginName
|
||||
}
|
||||
23
node_modules/avvio/lib/is-bundled-or-typescript-plugin.js
generated
vendored
Normal file
23
node_modules/avvio/lib/is-bundled-or-typescript-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* bundled or typescript plugin
|
||||
* @typedef {object} BundledOrTypescriptPlugin
|
||||
* @property {function} default
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} maybeBundledOrTypescriptPlugin
|
||||
* @returns {plugin is BundledOrTypescriptPlugin}
|
||||
*/
|
||||
function isBundledOrTypescriptPlugin (maybeBundledOrTypescriptPlugin) {
|
||||
return (
|
||||
maybeBundledOrTypescriptPlugin !== null &&
|
||||
typeof maybeBundledOrTypescriptPlugin === 'object' &&
|
||||
typeof maybeBundledOrTypescriptPlugin.default === 'function'
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isBundledOrTypescriptPlugin
|
||||
}
|
||||
17
node_modules/avvio/lib/is-promise-like.js
generated
vendored
Normal file
17
node_modules/avvio/lib/is-promise-like.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @param {any} maybePromiseLike
|
||||
* @returns {maybePromiseLike is PromiseLike}
|
||||
*/
|
||||
function isPromiseLike (maybePromiseLike) {
|
||||
return (
|
||||
maybePromiseLike !== null &&
|
||||
typeof maybePromiseLike === 'object' &&
|
||||
typeof maybePromiseLike.then === 'function'
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isPromiseLike
|
||||
}
|
||||
277
node_modules/avvio/lib/plugin.js
generated
vendored
Normal file
277
node_modules/avvio/lib/plugin.js
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
'use strict'
|
||||
|
||||
const { EventEmitter } = require('node:events')
|
||||
const { inherits } = require('node:util')
|
||||
const { debug } = require('./debug')
|
||||
const { createPromise } = require('./create-promise')
|
||||
const { AVV_ERR_PLUGIN_EXEC_TIMEOUT } = require('./errors')
|
||||
const { getPluginName } = require('./get-plugin-name')
|
||||
const { isPromiseLike } = require('./is-promise-like')
|
||||
|
||||
/**
|
||||
* @param {*} queue
|
||||
* @param {*} func
|
||||
* @param {*} options
|
||||
* @param {boolean} isAfter
|
||||
* @param {number} [timeout]
|
||||
*/
|
||||
function Plugin (queue, func, options, isAfter, timeout) {
|
||||
this.queue = queue
|
||||
this.func = func
|
||||
this.options = options
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.isAfter = isAfter
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.timeout = timeout
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.started = false
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = getPluginName(func, options)
|
||||
|
||||
this.queue.pause()
|
||||
|
||||
/**
|
||||
* @type {Error|null}
|
||||
*/
|
||||
this._error = null
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.loaded = false
|
||||
|
||||
this._promise = null
|
||||
|
||||
this.startTime = null
|
||||
}
|
||||
|
||||
inherits(Plugin, EventEmitter)
|
||||
|
||||
/**
|
||||
* @callback ExecCallback
|
||||
* @param {Error|null} execErr
|
||||
* @returns
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} server
|
||||
* @param {ExecCallback} callback
|
||||
* @returns
|
||||
*/
|
||||
Plugin.prototype.exec = function (server, callback) {
|
||||
debug('exec', this.name)
|
||||
|
||||
this.server = server
|
||||
const func = this.func
|
||||
const name = this.name
|
||||
let completed = false
|
||||
|
||||
this.options = typeof this.options === 'function' ? this.options(this.server) : this.options
|
||||
|
||||
let timer = null
|
||||
|
||||
/**
|
||||
* @param {Error} [execErr]
|
||||
*/
|
||||
const done = (execErr) => {
|
||||
if (completed) {
|
||||
debug('loading complete', name)
|
||||
return
|
||||
}
|
||||
|
||||
this._error = execErr
|
||||
|
||||
if (execErr) {
|
||||
debug('exec errored', name)
|
||||
} else {
|
||||
debug('exec completed', name)
|
||||
}
|
||||
|
||||
completed = true
|
||||
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
|
||||
callback(execErr)
|
||||
}
|
||||
|
||||
if (this.timeout > 0) {
|
||||
debug('setting up timeout', name, this.timeout)
|
||||
timer = setTimeout(function () {
|
||||
debug('timed out', name)
|
||||
timer = null
|
||||
const readyTimeoutErr = new AVV_ERR_PLUGIN_EXEC_TIMEOUT(name)
|
||||
// TODO Remove reference to function
|
||||
readyTimeoutErr.fn = func
|
||||
done(readyTimeoutErr)
|
||||
}, this.timeout)
|
||||
}
|
||||
|
||||
this.started = true
|
||||
this.startTime = Date.now()
|
||||
this.emit('start', this.server ? this.server.name : null, this.name, Date.now())
|
||||
|
||||
const maybePromiseLike = func(this.server, this.options, done)
|
||||
|
||||
if (isPromiseLike(maybePromiseLike)) {
|
||||
debug('exec: resolving promise', name)
|
||||
|
||||
maybePromiseLike.then(
|
||||
() => process.nextTick(done),
|
||||
(e) => process.nextTick(done, e))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
Plugin.prototype.loadedSoFar = function () {
|
||||
debug('loadedSoFar', this.name)
|
||||
|
||||
if (this.loaded) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
const setup = () => {
|
||||
this.server.after((afterErr, callback) => {
|
||||
this._error = afterErr
|
||||
this.queue.pause()
|
||||
|
||||
if (this._promise) {
|
||||
if (afterErr) {
|
||||
debug('rejecting promise', this.name, afterErr)
|
||||
this._promise.reject(afterErr)
|
||||
} else {
|
||||
debug('resolving promise', this.name)
|
||||
this._promise.resolve()
|
||||
}
|
||||
this._promise = null
|
||||
}
|
||||
|
||||
process.nextTick(callback, afterErr)
|
||||
})
|
||||
this.queue.resume()
|
||||
}
|
||||
|
||||
let res
|
||||
|
||||
if (!this._promise) {
|
||||
this._promise = createPromise()
|
||||
res = this._promise.promise
|
||||
|
||||
if (!this.server) {
|
||||
this.on('start', setup)
|
||||
} else {
|
||||
setup()
|
||||
}
|
||||
} else {
|
||||
res = Promise.resolve()
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback EnqueueCallback
|
||||
* @param {Error|null} enqueueErr
|
||||
* @param {Plugin} result
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Plugin} plugin
|
||||
* @param {EnqueueCallback} callback
|
||||
*/
|
||||
Plugin.prototype.enqueue = function (plugin, callback) {
|
||||
debug('enqueue', this.name, plugin.name)
|
||||
|
||||
this.emit('enqueue', this.server ? this.server.name : null, this.name, Date.now())
|
||||
this.queue.push(plugin, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback FinishCallback
|
||||
* @param {Error|null} finishErr
|
||||
* @returns
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @param {Error|null} err
|
||||
* @param {FinishCallback} callback
|
||||
* @returns
|
||||
*/
|
||||
Plugin.prototype.finish = function (err, callback) {
|
||||
debug('finish', this.name, err)
|
||||
|
||||
const done = () => {
|
||||
if (this.loaded) {
|
||||
return
|
||||
}
|
||||
|
||||
debug('loaded', this.name)
|
||||
this.emit('loaded', this.server ? this.server.name : null, this.name, Date.now())
|
||||
this.loaded = true
|
||||
|
||||
callback(err)
|
||||
}
|
||||
|
||||
if (err) {
|
||||
if (this._promise) {
|
||||
this._promise.reject(err)
|
||||
this._promise = null
|
||||
}
|
||||
done()
|
||||
return
|
||||
}
|
||||
|
||||
const check = () => {
|
||||
debug('check', this.name, this.queue.length(), this.queue.running(), this._promise)
|
||||
if (this.queue.length() === 0 && this.queue.running() === 0) {
|
||||
if (this._promise) {
|
||||
const wrap = () => {
|
||||
debug('wrap')
|
||||
queueMicrotask(check)
|
||||
}
|
||||
this._promise.resolve()
|
||||
this._promise.promise.then(wrap, wrap)
|
||||
this._promise = null
|
||||
} else {
|
||||
done()
|
||||
}
|
||||
} else {
|
||||
debug('delayed', this.name)
|
||||
// finish when the queue of nested plugins to load is empty
|
||||
this.queue.drain = () => {
|
||||
debug('drain', this.name)
|
||||
this.queue.drain = noop
|
||||
|
||||
// we defer the check, as a safety net for things
|
||||
// that might be scheduled in the loading callback
|
||||
queueMicrotask(check)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
queueMicrotask(check)
|
||||
|
||||
// we start loading the dependents plugins only once
|
||||
// the current level is finished
|
||||
this.queue.resume()
|
||||
}
|
||||
|
||||
function noop () {}
|
||||
|
||||
module.exports = {
|
||||
Plugin
|
||||
}
|
||||
26
node_modules/avvio/lib/symbols.js
generated
vendored
Normal file
26
node_modules/avvio/lib/symbols.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict'
|
||||
|
||||
// Internal Symbols
|
||||
const kAvvio = Symbol('avvio.Boot')
|
||||
const kIsOnCloseHandler = Symbol('isOnCloseHandler')
|
||||
const kThenifyDoNotWrap = Symbol('avvio.ThenifyDoNotWrap')
|
||||
const kUntrackNode = Symbol('avvio.TimeTree.untrackNode')
|
||||
const kTrackNode = Symbol('avvio.TimeTree.trackNode')
|
||||
const kGetParent = Symbol('avvio.TimeTree.getParent')
|
||||
const kGetNode = Symbol('avvio.TimeTree.getNode')
|
||||
const kAddNode = Symbol('avvio.TimeTree.addNode')
|
||||
|
||||
// Public Symbols
|
||||
const kPluginMeta = Symbol.for('plugin-meta')
|
||||
|
||||
module.exports = {
|
||||
kAvvio,
|
||||
kIsOnCloseHandler,
|
||||
kThenifyDoNotWrap,
|
||||
kUntrackNode,
|
||||
kTrackNode,
|
||||
kGetParent,
|
||||
kGetNode,
|
||||
kAddNode,
|
||||
kPluginMeta
|
||||
}
|
||||
60
node_modules/avvio/lib/thenify.js
generated
vendored
Normal file
60
node_modules/avvio/lib/thenify.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
'use strict'
|
||||
|
||||
const { debug } = require('./debug')
|
||||
const { kThenifyDoNotWrap } = require('./symbols')
|
||||
|
||||
/**
|
||||
* @callback PromiseConstructorLikeResolve
|
||||
* @param {any} value
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback PromiseConstructorLikeReject
|
||||
* @param {reason} error
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback PromiseConstructorLike
|
||||
* @param {PromiseConstructorLikeResolve} resolve
|
||||
* @param {PromiseConstructorLikeReject} reject
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @returns {PromiseConstructorLike}
|
||||
*/
|
||||
function thenify () {
|
||||
// If the instance is ready, then there is
|
||||
// nothing to await. This is true during
|
||||
// await server.ready() as ready() resolves
|
||||
// with the server, end we will end up here
|
||||
// because of automatic promise chaining.
|
||||
if (this.booted) {
|
||||
debug('thenify returning undefined because we are already booted')
|
||||
return
|
||||
}
|
||||
|
||||
// Calling resolve(this._server) would fetch the then
|
||||
// property on the server, which will lead it here.
|
||||
// If we do not break the recursion, we will loop
|
||||
// forever.
|
||||
if (this[kThenifyDoNotWrap]) {
|
||||
this[kThenifyDoNotWrap] = false
|
||||
return
|
||||
}
|
||||
|
||||
debug('thenify')
|
||||
return (resolve, reject) => {
|
||||
const p = this._loadRegistered()
|
||||
return p.then(() => {
|
||||
this[kThenifyDoNotWrap] = true
|
||||
return resolve(this._server)
|
||||
}, reject)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
thenify
|
||||
}
|
||||
200
node_modules/avvio/lib/time-tree.js
generated
vendored
Normal file
200
node_modules/avvio/lib/time-tree.js
generated
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
'use strict'
|
||||
|
||||
const {
|
||||
kUntrackNode,
|
||||
kTrackNode,
|
||||
kGetParent,
|
||||
kGetNode,
|
||||
kAddNode
|
||||
} = require('./symbols')
|
||||
|
||||
/**
|
||||
* Node of the TimeTree
|
||||
* @typedef {object} TimeTreeNode
|
||||
* @property {string} id
|
||||
* @property {string|null} parent
|
||||
* @property {string} label
|
||||
* @property {Array<TimeTreeNode>} nodes
|
||||
* @property {number} start
|
||||
* @property {number|undefined} stop
|
||||
* @property {number|undefined} diff
|
||||
*/
|
||||
|
||||
class TimeTree {
|
||||
constructor () {
|
||||
/**
|
||||
* @type {TimeTreeNode|null} root
|
||||
* @public
|
||||
*/
|
||||
this.root = null
|
||||
|
||||
/**
|
||||
* @type {Map<string, TimeTreeNode>} tableId
|
||||
* @public
|
||||
*/
|
||||
this.tableId = new Map()
|
||||
|
||||
/**
|
||||
* @type {Map<string, Array<TimeTreeNode>>} tableLabel
|
||||
* @public
|
||||
*/
|
||||
this.tableLabel = new Map()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TimeTreeNode} node
|
||||
*/
|
||||
[kTrackNode] (node) {
|
||||
this.tableId.set(node.id, node)
|
||||
if (this.tableLabel.has(node.label)) {
|
||||
this.tableLabel.get(node.label).push(node)
|
||||
} else {
|
||||
this.tableLabel.set(node.label, [node])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TimeTreeNode} node
|
||||
*/
|
||||
[kUntrackNode] (node) {
|
||||
this.tableId.delete(node.id)
|
||||
|
||||
const labelNode = this.tableLabel.get(node.label)
|
||||
labelNode.pop()
|
||||
|
||||
if (labelNode.length === 0) {
|
||||
this.tableLabel.delete(node.label)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} parent
|
||||
* @returns {TimeTreeNode}
|
||||
*/
|
||||
[kGetParent] (parent) {
|
||||
if (parent === null) {
|
||||
return null
|
||||
} else if (this.tableLabel.has(parent)) {
|
||||
const parentNode = this.tableLabel.get(parent)
|
||||
return parentNode[parentNode.length - 1]
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} nodeId
|
||||
* @returns {TimeTreeNode}
|
||||
*/
|
||||
[kGetNode] (nodeId) {
|
||||
return this.tableId.get(nodeId)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} parent
|
||||
* @param {string} label
|
||||
* @param {number} start
|
||||
* @returns {TimeTreeNode["id"]}
|
||||
*/
|
||||
[kAddNode] (parent, label, start) {
|
||||
const parentNode = this[kGetParent](parent)
|
||||
const isRoot = parentNode === null
|
||||
|
||||
if (isRoot) {
|
||||
this.root = {
|
||||
parent: null,
|
||||
id: 'root',
|
||||
label,
|
||||
nodes: [],
|
||||
start,
|
||||
stop: null,
|
||||
diff: -1
|
||||
}
|
||||
this[kTrackNode](this.root)
|
||||
return this.root.id
|
||||
}
|
||||
|
||||
const nodeId = `${label}-${Math.random()}`
|
||||
/**
|
||||
* @type {TimeTreeNode}
|
||||
*/
|
||||
const childNode = {
|
||||
parent,
|
||||
id: nodeId,
|
||||
label,
|
||||
nodes: [],
|
||||
start,
|
||||
stop: null,
|
||||
diff: -1
|
||||
}
|
||||
parentNode.nodes.push(childNode)
|
||||
this[kTrackNode](childNode)
|
||||
return nodeId
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} parent
|
||||
* @param {string} label
|
||||
* @param {number|undefined} start
|
||||
* @returns {TimeTreeNode["id"]}
|
||||
*/
|
||||
start (parent, label, start = Date.now()) {
|
||||
return this[kAddNode](parent, label, start)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} nodeId
|
||||
* @param {number|undefined} stop
|
||||
*/
|
||||
stop (nodeId, stop = Date.now()) {
|
||||
const node = this[kGetNode](nodeId)
|
||||
if (node) {
|
||||
node.stop = stop
|
||||
node.diff = (node.stop - node.start) || 0
|
||||
this[kUntrackNode](node)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {TimeTreeNode}
|
||||
*/
|
||||
toJSON () {
|
||||
return Object.assign({}, this.root)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
prettyPrint () {
|
||||
return prettyPrintTimeTree(this.toJSON())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TimeTreeNode} obj
|
||||
* @param {string|undefined} prefix
|
||||
* @returns {string}
|
||||
*/
|
||||
function prettyPrintTimeTree (obj, prefix = '') {
|
||||
let result = prefix
|
||||
|
||||
const nodesCount = obj.nodes.length
|
||||
const lastIndex = nodesCount - 1
|
||||
result += `${obj.label} ${obj.diff} ms\n`
|
||||
|
||||
for (let i = 0; i < nodesCount; ++i) {
|
||||
const node = obj.nodes[i]
|
||||
const prefix_ = prefix + (i === lastIndex ? ' ' : '│ ')
|
||||
|
||||
result += prefix
|
||||
result += (i === lastIndex ? '└─' : '├─')
|
||||
result += (node.nodes.length === 0 ? '─ ' : '┬ ')
|
||||
result += prettyPrintTimeTree(node, prefix_).slice(prefix.length + 2)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
TimeTree
|
||||
}
|
||||
26
node_modules/avvio/lib/validate-plugin.js
generated
vendored
Normal file
26
node_modules/avvio/lib/validate-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict'
|
||||
|
||||
const { AVV_ERR_PLUGIN_NOT_VALID } = require('./errors')
|
||||
|
||||
/**
|
||||
* @param {any} maybePlugin
|
||||
* @throws {AVV_ERR_PLUGIN_NOT_VALID}
|
||||
*
|
||||
* @returns {asserts plugin is Function|PromiseLike}
|
||||
*/
|
||||
function validatePlugin (maybePlugin) {
|
||||
// validate if plugin is a function or Promise
|
||||
if (!(maybePlugin && (typeof maybePlugin === 'function' || typeof maybePlugin.then === 'function'))) {
|
||||
if (Array.isArray(maybePlugin)) {
|
||||
throw new AVV_ERR_PLUGIN_NOT_VALID('array')
|
||||
} else if (maybePlugin === null) {
|
||||
throw new AVV_ERR_PLUGIN_NOT_VALID('null')
|
||||
} else {
|
||||
throw new AVV_ERR_PLUGIN_NOT_VALID(typeof maybePlugin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validatePlugin
|
||||
}
|
||||
52
node_modules/avvio/package.json
generated
vendored
Normal file
52
node_modules/avvio/package.json
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "avvio",
|
||||
"version": "8.4.0",
|
||||
"description": "Asynchronous bootstrapping of Node applications",
|
||||
"main": "boot.js",
|
||||
"type": "commonjs",
|
||||
"scripts": {
|
||||
"lint": "standard",
|
||||
"lint:fix": "standard --fix",
|
||||
"test": "npm run test:unit && npm run test:typescript",
|
||||
"test:unit": "tap",
|
||||
"test:typescript": "tsc --project ./test/types/tsconfig.json"
|
||||
},
|
||||
"precommit": [
|
||||
"lint",
|
||||
"test"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fastify/avvio.git"
|
||||
},
|
||||
"keywords": [
|
||||
"async",
|
||||
"boot",
|
||||
"delayed",
|
||||
"open"
|
||||
],
|
||||
"author": "Matteo Collina <hello@matteocollina.com>",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Tomas Della Vedova",
|
||||
"url": "http://delved.org"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/fastify/avvio/issues"
|
||||
},
|
||||
"homepage": "https://github.com/fastify/avvio#readme",
|
||||
"devDependencies": {
|
||||
"@fastify/pre-commit": "^2.0.2",
|
||||
"@types/node": "^20.1.0",
|
||||
"express": "^4.17.1",
|
||||
"standard": "^17.0.0",
|
||||
"tap": "^16.0.0",
|
||||
"typescript": "^5.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/error": "^3.3.0",
|
||||
"fastq": "^1.17.1"
|
||||
}
|
||||
}
|
||||
864
node_modules/avvio/test/after-and-ready.test.js
generated
vendored
Normal file
864
node_modules/avvio/test/after-and-ready.test.js
generated
vendored
Normal file
@@ -0,0 +1,864 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('boot a plugin and then execute a call after that', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = boot()
|
||||
let pluginLoaded = false
|
||||
let afterCalled = false
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.notOk(afterCalled, 'after not called')
|
||||
pluginLoaded = true
|
||||
done()
|
||||
})
|
||||
|
||||
app.after(function (err, cb) {
|
||||
t.error(err)
|
||||
t.ok(pluginLoaded, 'afterred!')
|
||||
afterCalled = true
|
||||
cb()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(afterCalled, 'after called')
|
||||
t.ok(pluginLoaded, 'plugin loaded')
|
||||
})
|
||||
})
|
||||
|
||||
test('after without a done callback', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = boot()
|
||||
let pluginLoaded = false
|
||||
let afterCalled = false
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.notOk(afterCalled, 'after not called')
|
||||
pluginLoaded = true
|
||||
done()
|
||||
})
|
||||
|
||||
app.after(function (err) {
|
||||
t.error(err)
|
||||
t.ok(pluginLoaded, 'afterred!')
|
||||
afterCalled = true
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(afterCalled, 'after called')
|
||||
t.ok(pluginLoaded, 'plugin loaded')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify when a afterred call happens', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done()
|
||||
})
|
||||
|
||||
app.after(function (err, cb) {
|
||||
t.error(err)
|
||||
t.pass('afterred finished')
|
||||
cb()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('internal after', (t) => {
|
||||
t.plan(18)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
let afterCalled = false
|
||||
|
||||
app.use(first)
|
||||
app.use(third)
|
||||
|
||||
function first (s, opts, done) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second)
|
||||
s.after(function (err, cb) {
|
||||
t.error(err)
|
||||
t.notOk(afterCalled, 'after was not called')
|
||||
afterCalled = true
|
||||
cb()
|
||||
})
|
||||
done()
|
||||
}
|
||||
|
||||
function second (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(afterCalled, 'after was not called')
|
||||
secondLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
function third (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(afterCalled, 'after was called')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
thirdLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(afterCalled, 'after was called')
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('ready adds at the end of the queue', (t) => {
|
||||
t.plan(14)
|
||||
|
||||
const app = boot()
|
||||
let pluginLoaded = false
|
||||
let afterCalled = false
|
||||
let readyCalled = false
|
||||
|
||||
app.ready(function (err, cb) {
|
||||
t.error(err)
|
||||
t.ok(pluginLoaded, 'after the plugin')
|
||||
t.ok(afterCalled, 'after after')
|
||||
readyCalled = true
|
||||
process.nextTick(cb)
|
||||
})
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.notOk(afterCalled, 'after not called')
|
||||
t.notOk(readyCalled, 'ready not called')
|
||||
pluginLoaded = true
|
||||
|
||||
app.ready(function (err) {
|
||||
t.error(err)
|
||||
t.ok(readyCalled, 'after the first ready')
|
||||
t.ok(afterCalled, 'after the after callback')
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
app.after(function (err, cb) {
|
||||
t.error(err)
|
||||
t.ok(pluginLoaded, 'executing after!')
|
||||
t.notOk(readyCalled, 'ready not called')
|
||||
afterCalled = true
|
||||
cb()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(afterCalled, 'after called')
|
||||
t.ok(pluginLoaded, 'plugin loaded')
|
||||
t.ok(readyCalled, 'ready called')
|
||||
})
|
||||
})
|
||||
|
||||
test('if the after/ready callback has two parameters, the first one must be the context', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done()
|
||||
})
|
||||
|
||||
app.after(function (err, context, cb) {
|
||||
t.error(err)
|
||||
t.equal(server, context)
|
||||
cb()
|
||||
})
|
||||
|
||||
app.ready(function (err, context, cb) {
|
||||
t.error(err)
|
||||
t.equal(server, context)
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
test('if the after/ready async, the returns must be the context generated', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server', index: 0 }
|
||||
const app = boot(server)
|
||||
app.override = function (old) {
|
||||
return { ...old, index: old.index + 1 }
|
||||
}
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
s.use(function (s, opts, done) {
|
||||
s.ready().then(itself => t.same(itself, s, 'deep deep'))
|
||||
done()
|
||||
})
|
||||
s.ready().then(itself => t.same(itself, s, 'deep'))
|
||||
done()
|
||||
})
|
||||
|
||||
app.ready().then(itself => t.same(itself, server, 'outer'))
|
||||
})
|
||||
|
||||
test('if the after/ready callback, the returns must be the context generated', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server', index: 0 }
|
||||
const app = boot(server)
|
||||
app.override = function (old) {
|
||||
return { ...old, index: old.index + 1 }
|
||||
}
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
s.use(function (s, opts, done) {
|
||||
s.ready((_, itself, done) => {
|
||||
t.same(itself, s, 'deep deep')
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
s.ready((_, itself, done) => {
|
||||
t.same(itself, s, 'deep')
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
app.ready((_, itself, done) => {
|
||||
t.same(itself, server, 'outer')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('error should come in the first after - one parameter', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
})
|
||||
|
||||
app.after(function (err) {
|
||||
t.ok(err instanceof Error)
|
||||
t.equal(err.message, 'err')
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('error should come in the first after - two parameters', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
})
|
||||
|
||||
app.after(function (err, cb) {
|
||||
t.ok(err instanceof Error)
|
||||
t.equal(err.message, 'err')
|
||||
cb()
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('error should come in the first after - three parameter', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
})
|
||||
|
||||
app.after(function (err, context, cb) {
|
||||
t.ok(err instanceof Error)
|
||||
t.equal(err.message, 'err')
|
||||
t.equal(context, server)
|
||||
cb()
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('error should come in the first ready - one parameter', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.ok(err instanceof Error)
|
||||
t.equal(err.message, 'err')
|
||||
})
|
||||
})
|
||||
|
||||
test('error should come in the first ready - two parameters', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
})
|
||||
|
||||
app.ready(function (err, cb) {
|
||||
t.ok(err instanceof Error)
|
||||
t.equal(err.message, 'err')
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
test('error should come in the first ready - three parameters', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
})
|
||||
|
||||
app.ready(function (err, context, cb) {
|
||||
t.ok(err instanceof Error)
|
||||
t.equal(err.message, 'err')
|
||||
t.equal(context, server)
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
test('if `use` has a callback with more then one parameter, the error must not reach ready', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.ok(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('if `use` has a callback without parameters, the error must reach ready', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
done(new Error('err'))
|
||||
}, () => {})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.ok(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('should pass the errors from after to ready', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const server = {}
|
||||
const app = boot(server, {})
|
||||
|
||||
server.use(function (s, opts, done) {
|
||||
t.equal(s, server, 'the first argument is the server')
|
||||
t.same(opts, {}, 'no options')
|
||||
done()
|
||||
}).after((err, done) => {
|
||||
t.error(err)
|
||||
done(new Error('some error'))
|
||||
})
|
||||
|
||||
server.onClose(() => {
|
||||
t.ok('onClose called')
|
||||
})
|
||||
|
||||
server.ready(err => {
|
||||
t.equal(err.message, 'some error')
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
server.close(() => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('after no encapsulation', t => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
app.override = function (s, fn, opts) {
|
||||
s = Object.create(s)
|
||||
return s
|
||||
}
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.test = true
|
||||
instance.after(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.after(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('ready no encapsulation', t => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
app.override = function (s, fn, opts) {
|
||||
s = Object.create(s)
|
||||
return s
|
||||
}
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.test = true
|
||||
instance.ready(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.ready(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('after encapsulation with a server', t => {
|
||||
t.plan(4)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
app.override = function (s, fn, opts) {
|
||||
s = Object.create(s)
|
||||
return s
|
||||
}
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.test = true
|
||||
instance.after(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.ok(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.after(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('ready encapsulation with a server', t => {
|
||||
t.plan(4)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
app.override = function (s, fn, opts) {
|
||||
s = Object.create(s)
|
||||
return s
|
||||
}
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.test = true
|
||||
instance.ready(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.ok(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.ready(function (err, i, done) {
|
||||
t.error(err)
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('after should passthrough the errors', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = boot()
|
||||
let pluginLoaded = false
|
||||
let afterCalled = false
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.notOk(afterCalled, 'after not called')
|
||||
pluginLoaded = true
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
app.after(function () {
|
||||
t.ok(pluginLoaded, 'afterred!')
|
||||
afterCalled = true
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.ok(err)
|
||||
t.ok(afterCalled, 'after called')
|
||||
t.ok(pluginLoaded, 'plugin loaded')
|
||||
})
|
||||
})
|
||||
|
||||
test('stop loading plugins if it errors', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
app.use(function second (server, opts, done) {
|
||||
t.fail('this should never be called')
|
||||
})
|
||||
|
||||
app.ready((err) => {
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
})
|
||||
|
||||
test('keep loading if there is an .after', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
app.after(function (err) {
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
|
||||
app.use(function second (server, opts, done) {
|
||||
t.pass('second called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.ready((err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('do not load nested plugin if parent errors', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
|
||||
server.use(function second (_, opts, done) {
|
||||
t.fail('this should never be called')
|
||||
})
|
||||
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
app.after(function (err) {
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
|
||||
app.use(function third (server, opts, done) {
|
||||
t.pass('third called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.ready((err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('.after nested', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function outer (app, opts, done) {
|
||||
app.use(function first (app, opts, done) {
|
||||
t.pass('first called')
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
app.after(function (err) {
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
|
||||
app.use(function second (app, opts, done) {
|
||||
t.pass('second called')
|
||||
done()
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
app.ready((err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('nested error', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function outer (app, opts, done) {
|
||||
app.use(function first (app, opts, done) {
|
||||
t.pass('first called')
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
app.use(function second (app, opts, done) {
|
||||
t.fail('this should never be called')
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
app.after(function (err) {
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
|
||||
app.use(function third (server, opts, done) {
|
||||
t.pass('third called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.ready((err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('preReady event', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
const order = [1, 2]
|
||||
|
||||
app.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.use(function second (server, opts, done) {
|
||||
t.pass('second called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 1)
|
||||
})
|
||||
|
||||
app.ready(() => {
|
||||
t.equal(order.shift(), 2)
|
||||
})
|
||||
})
|
||||
|
||||
test('preReady event (multiple)', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const app = boot()
|
||||
const order = [1, 2, 3, 4]
|
||||
|
||||
app.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.use(function second (server, opts, done) {
|
||||
t.pass('second called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 1)
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 2)
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 3)
|
||||
})
|
||||
|
||||
app.ready(() => {
|
||||
t.equal(order.shift(), 4)
|
||||
})
|
||||
})
|
||||
|
||||
test('preReady event (nested)', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const app = boot()
|
||||
const order = [1, 2, 3, 4]
|
||||
|
||||
app.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.use(function second (server, opts, done) {
|
||||
t.pass('second called')
|
||||
|
||||
server.on('preReady', () => {
|
||||
t.equal(order.shift(), 3)
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 1)
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 2)
|
||||
})
|
||||
|
||||
app.ready(() => {
|
||||
t.equal(order.shift(), 4)
|
||||
})
|
||||
})
|
||||
|
||||
test('preReady event (errored)', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = boot()
|
||||
const order = [1, 2, 3]
|
||||
|
||||
app.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
app.use(function second (server, opts, done) {
|
||||
t.fail('We should not be here')
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 1)
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.equal(order.shift(), 2)
|
||||
})
|
||||
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(order.shift(), 3)
|
||||
})
|
||||
})
|
||||
|
||||
test('after return self', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const app = boot()
|
||||
let pluginLoaded = false
|
||||
let afterCalled = false
|
||||
let second = false
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.notOk(afterCalled, 'after not called')
|
||||
pluginLoaded = true
|
||||
done()
|
||||
})
|
||||
|
||||
app.after(function () {
|
||||
t.ok(pluginLoaded, 'afterred!')
|
||||
afterCalled = true
|
||||
// happens with after(() => app.use(..))
|
||||
return app
|
||||
})
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.ok(afterCalled, 'after called')
|
||||
second = true
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(afterCalled, 'after called')
|
||||
t.ok(pluginLoaded, 'plugin loaded')
|
||||
t.ok(second, 'second plugin loaded')
|
||||
})
|
||||
})
|
||||
|
||||
test('after 1 param swallows errors with server and timeout', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = {}
|
||||
boot(server, { autostart: false, timeout: 1000 })
|
||||
|
||||
server.use(function first (server, opts, done) {
|
||||
t.pass('first called')
|
||||
done(new Error('kaboom'))
|
||||
})
|
||||
|
||||
server.use(function second (server, opts, done) {
|
||||
t.fail('We should not be here')
|
||||
})
|
||||
|
||||
server.after(function (err) {
|
||||
t.ok(err)
|
||||
})
|
||||
|
||||
server.ready(function (err) {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
32
node_modules/avvio/test/after-pass-through.test.js
generated
vendored
Normal file
32
node_modules/avvio/test/after-pass-through.test.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('proper support for after with a passed async function in wrapped mode', (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(5)
|
||||
|
||||
const e = new Error('kaboom')
|
||||
|
||||
app.use(function (f, opts) {
|
||||
return Promise.reject(e)
|
||||
}).after(function (err, cb) {
|
||||
t.equal(err, e)
|
||||
cb(err)
|
||||
}).after(function () {
|
||||
t.pass('this is just called')
|
||||
}).after(function (err, cb) {
|
||||
t.equal(err, e)
|
||||
cb(err)
|
||||
})
|
||||
|
||||
app.ready().then(() => {
|
||||
t.fail('this should not be called')
|
||||
}).catch(err => {
|
||||
t.ok(err)
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
})
|
||||
20
node_modules/avvio/test/after-self-promise.test.js
generated
vendored
Normal file
20
node_modules/avvio/test/after-self-promise.test.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('after does not await itself', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
app.use(async (app) => {
|
||||
t.pass('plugin init')
|
||||
})
|
||||
app.after(() => app)
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
24
node_modules/avvio/test/after-throw.test.js
generated
vendored
Normal file
24
node_modules/avvio/test/after-throw.test.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('catched error by Promise.reject', (t) => {
|
||||
const app = boot()
|
||||
t.plan(2)
|
||||
|
||||
t.threw = function (err) {
|
||||
t.equal(err.message, 'kaboom2')
|
||||
}
|
||||
|
||||
app.use(function (f, opts) {
|
||||
return Promise.reject(new Error('kaboom'))
|
||||
}).after(function (err) {
|
||||
t.equal(err.message, 'kaboom')
|
||||
throw new Error('kaboom2')
|
||||
})
|
||||
|
||||
app.ready(function () {
|
||||
t.fail('the ready callback should never be called')
|
||||
})
|
||||
})
|
||||
90
node_modules/avvio/test/after-use-after.test.js
generated
vendored
Normal file
90
node_modules/avvio/test/after-use-after.test.js
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
const app = {}
|
||||
|
||||
boot(app)
|
||||
|
||||
test('multi after', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
app.use(function (f, opts, cb) {
|
||||
cb()
|
||||
}).after(() => {
|
||||
t.pass('this is just called')
|
||||
|
||||
app.use(function (f, opts, cb) {
|
||||
t.pass('this is just called')
|
||||
cb()
|
||||
})
|
||||
}).after(function () {
|
||||
t.pass('this is just called')
|
||||
app.use(function (f, opts, cb) {
|
||||
t.pass('this is just called')
|
||||
cb()
|
||||
})
|
||||
}).after(function (err, cb) {
|
||||
t.pass('this is just called')
|
||||
cb(err)
|
||||
})
|
||||
|
||||
app.ready().then(() => {
|
||||
t.pass('ready')
|
||||
}).catch(() => {
|
||||
t.fail('this should not be called')
|
||||
})
|
||||
})
|
||||
|
||||
test('after grouping - use called after after called', (t) => {
|
||||
t.plan(9)
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
const TEST_VALUE = {}
|
||||
const OTHER_TEST_VALUE = {}
|
||||
const NEW_TEST_VALUE = {}
|
||||
|
||||
const sO = (fn) => {
|
||||
fn[Symbol.for('skip-override')] = true
|
||||
return fn
|
||||
}
|
||||
|
||||
app.use(sO(function (f, options, next) {
|
||||
f.test = TEST_VALUE
|
||||
|
||||
next()
|
||||
}))
|
||||
|
||||
app.after(function (err, f, done) {
|
||||
t.error(err)
|
||||
t.equal(f.test, TEST_VALUE)
|
||||
|
||||
f.test2 = OTHER_TEST_VALUE
|
||||
done()
|
||||
})
|
||||
|
||||
app.use(sO(function (f, options, next) {
|
||||
t.equal(f.test, TEST_VALUE)
|
||||
t.equal(f.test2, OTHER_TEST_VALUE)
|
||||
|
||||
f.test3 = NEW_TEST_VALUE
|
||||
|
||||
next()
|
||||
}))
|
||||
|
||||
app.after(function (err, f, done) {
|
||||
t.error(err)
|
||||
t.equal(f.test, TEST_VALUE)
|
||||
t.equal(f.test2, OTHER_TEST_VALUE)
|
||||
t.equal(f.test3, NEW_TEST_VALUE)
|
||||
done()
|
||||
})
|
||||
|
||||
app.ready().then(() => {
|
||||
t.pass('ready')
|
||||
}).catch((e) => {
|
||||
console.log(e)
|
||||
t.fail('this should not be called')
|
||||
})
|
||||
})
|
||||
325
node_modules/avvio/test/async-await.test.js
generated
vendored
Normal file
325
node_modules/avvio/test/async-await.test.js
generated
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: off */
|
||||
|
||||
const { test } = require('tap')
|
||||
const sleep = function (ms) {
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(resolve, ms)
|
||||
})
|
||||
}
|
||||
|
||||
const boot = require('..')
|
||||
|
||||
test('one level', async (t) => {
|
||||
t.plan(14)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
|
||||
app.use(first)
|
||||
app.use(third)
|
||||
|
||||
async function first (s, opts) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second)
|
||||
}
|
||||
|
||||
async function second (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
secondLoaded = true
|
||||
}
|
||||
|
||||
async function third (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
thirdLoaded = true
|
||||
}
|
||||
|
||||
const readyContext = await app.ready()
|
||||
|
||||
t.equal(app, readyContext)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
test('multiple reentrant plugin loading', async (t) => {
|
||||
t.plan(31)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
let fourthLoaded = false
|
||||
let fifthLoaded = false
|
||||
|
||||
app.use(first)
|
||||
app.use(fifth)
|
||||
|
||||
async function first (s, opts) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second)
|
||||
}
|
||||
|
||||
async function second (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
secondLoaded = true
|
||||
s.use(third)
|
||||
await sleep(10)
|
||||
s.use(fourth)
|
||||
}
|
||||
|
||||
async function third (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
thirdLoaded = true
|
||||
}
|
||||
|
||||
async function fourth (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
fourthLoaded = true
|
||||
}
|
||||
|
||||
async function fifth (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
fifthLoaded = true
|
||||
}
|
||||
|
||||
await app.ready()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
t.ok(fifthLoaded, 'fifth is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
test('async ready plugin registration (errored)', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(async (server, opts) => {
|
||||
await sleep(10)
|
||||
throw new Error('kaboom')
|
||||
})
|
||||
|
||||
try {
|
||||
await app.ready()
|
||||
t.fail('we should not be here')
|
||||
} catch (err) {
|
||||
t.equal(err.message, 'kaboom')
|
||||
}
|
||||
})
|
||||
|
||||
test('after', async (t) => {
|
||||
t.plan(15)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
|
||||
app.use(first)
|
||||
|
||||
async function first (s, opts) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
firstLoaded = true
|
||||
s.after(second)
|
||||
s.after(third)
|
||||
}
|
||||
|
||||
async function second (err) {
|
||||
t.error(err)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
await sleep(10)
|
||||
secondLoaded = true
|
||||
}
|
||||
|
||||
async function third () {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
await sleep(10)
|
||||
thirdLoaded = true
|
||||
}
|
||||
|
||||
const readyContext = await app.ready()
|
||||
|
||||
t.equal(app, readyContext)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
test('after wrapped', async (t) => {
|
||||
t.plan(15)
|
||||
|
||||
const app = {}
|
||||
boot(app)
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
|
||||
app.use(first)
|
||||
|
||||
async function first (s, opts) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
firstLoaded = true
|
||||
s.after(second)
|
||||
s.after(third)
|
||||
}
|
||||
|
||||
async function second (err) {
|
||||
t.error(err)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
await sleep(10)
|
||||
secondLoaded = true
|
||||
}
|
||||
|
||||
async function third () {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
await sleep(10)
|
||||
thirdLoaded = true
|
||||
}
|
||||
|
||||
const readyContext = await app.ready()
|
||||
|
||||
t.equal(app, readyContext)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
test('promise plugins', async (t) => {
|
||||
t.plan(14)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
|
||||
app.use(first())
|
||||
app.use(third())
|
||||
|
||||
async function first () {
|
||||
return async function (s, opts) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second())
|
||||
}
|
||||
}
|
||||
|
||||
async function second () {
|
||||
return async function (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
secondLoaded = true
|
||||
}
|
||||
}
|
||||
|
||||
async function third () {
|
||||
return async function (s, opts) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
thirdLoaded = true
|
||||
}
|
||||
}
|
||||
|
||||
const readyContext = await app.ready()
|
||||
|
||||
t.equal(app, readyContext)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
test('skip override with promise', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s, func) {
|
||||
t.pass('override called')
|
||||
|
||||
if (func[Symbol.for('skip-override')]) {
|
||||
return s
|
||||
}
|
||||
return Object.create(s)
|
||||
}
|
||||
|
||||
app.use(first())
|
||||
|
||||
async function first () {
|
||||
async function fn (s, opts) {
|
||||
t.equal(s, server)
|
||||
t.notOk(Object.prototype.isPrototypeOf.call(server, s))
|
||||
}
|
||||
|
||||
fn[Symbol.for('skip-override')] = true
|
||||
|
||||
return fn
|
||||
}
|
||||
})
|
||||
|
||||
test('ready queue error', async (t) => {
|
||||
const app = boot()
|
||||
app.use(first)
|
||||
|
||||
async function first (s, opts) {}
|
||||
|
||||
app.ready(function (_, worker, done) {
|
||||
const error = new Error('kaboom')
|
||||
done(error)
|
||||
})
|
||||
|
||||
await t.rejects(app.ready(), { message: 'kaboom' })
|
||||
})
|
||||
449
node_modules/avvio/test/await-after.test.js
generated
vendored
Normal file
449
node_modules/avvio/test/await-after.test.js
generated
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
const { promisify } = require('node:util')
|
||||
const sleep = promisify(setTimeout)
|
||||
const fs = require('node:fs').promises
|
||||
const path = require('node:path')
|
||||
|
||||
test('await after - nested plugins with same tick callbacks', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
let secondLoaded = false
|
||||
|
||||
app.use(async (app) => {
|
||||
t.pass('plugin init')
|
||||
app.use(async () => {
|
||||
t.pass('plugin2 init')
|
||||
await sleep(1)
|
||||
secondLoaded = true
|
||||
})
|
||||
})
|
||||
await app.after()
|
||||
t.pass('reachable')
|
||||
t.equal(secondLoaded, true)
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await after without server', async (t) => {
|
||||
const app = boot()
|
||||
|
||||
let secondLoaded = false
|
||||
|
||||
app.use(async (app) => {
|
||||
t.pass('plugin init')
|
||||
app.use(async () => {
|
||||
t.pass('plugin2 init')
|
||||
await sleep(1)
|
||||
secondLoaded = true
|
||||
})
|
||||
})
|
||||
await app.after()
|
||||
t.pass('reachable')
|
||||
t.equal(secondLoaded, true)
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await after with cb functions', async (t) => {
|
||||
const app = boot()
|
||||
let secondLoaded = false
|
||||
let record = ''
|
||||
|
||||
app.use(async (app) => {
|
||||
t.pass('plugin init')
|
||||
record += 'plugin|'
|
||||
app.use(async () => {
|
||||
t.pass('plugin2 init')
|
||||
record += 'plugin2|'
|
||||
await sleep(1)
|
||||
secondLoaded = true
|
||||
})
|
||||
})
|
||||
await app.after(() => {
|
||||
record += 'after|'
|
||||
})
|
||||
t.pass('reachable')
|
||||
t.equal(secondLoaded, true)
|
||||
record += 'ready'
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
t.equal(record, 'plugin|plugin2|after|ready')
|
||||
})
|
||||
|
||||
test('await after - nested plugins with future tick callbacks', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(4)
|
||||
|
||||
app.use((f, opts, cb) => {
|
||||
t.pass('plugin init')
|
||||
app.use((f, opts, cb) => {
|
||||
t.pass('plugin2 init')
|
||||
setImmediate(cb)
|
||||
})
|
||||
setImmediate(cb)
|
||||
})
|
||||
await app.after()
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await after - nested async function plugins', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(5)
|
||||
|
||||
app.use(async (f, opts) => {
|
||||
t.pass('plugin init')
|
||||
await app.use(async (f, opts) => {
|
||||
t.pass('plugin2 init')
|
||||
})
|
||||
t.pass('reachable')
|
||||
})
|
||||
await app.after()
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await after - promise resolves to undefined', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(4)
|
||||
|
||||
app.use(async (f, opts, cb) => {
|
||||
app.use((f, opts, cb) => {
|
||||
t.pass('plugin init')
|
||||
cb()
|
||||
})
|
||||
const instance = await app.after()
|
||||
t.equal(instance, undefined)
|
||||
})
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await after - promise returning function plugins + promise chaining', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(6)
|
||||
|
||||
app.use((f, opts) => {
|
||||
t.pass('plugin init')
|
||||
return app.use((f, opts) => {
|
||||
t.pass('plugin2 init')
|
||||
return Promise.resolve()
|
||||
}).then((f2) => {
|
||||
t.equal(f2, f)
|
||||
return 'test'
|
||||
}).then((val) => {
|
||||
t.equal(val, 'test')
|
||||
})
|
||||
})
|
||||
await app.after()
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await after - error handling, async throw', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
const e = new Error('kaboom')
|
||||
|
||||
app.use(async (f, opts) => {
|
||||
throw Error('kaboom')
|
||||
})
|
||||
|
||||
await t.rejects(app.after(), e)
|
||||
|
||||
await t.rejects(() => app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await after - error handling, async throw, nested', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
const e = new Error('kaboom')
|
||||
|
||||
app.use(async (f, opts) => {
|
||||
app.use(async (f, opts) => {
|
||||
throw e
|
||||
})
|
||||
})
|
||||
|
||||
await t.rejects(app.after())
|
||||
await t.rejects(() => app.ready(), e)
|
||||
})
|
||||
|
||||
test('await after - error handling, same tick cb err', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
app.use((f, opts, cb) => {
|
||||
cb(Error('kaboom'))
|
||||
})
|
||||
await t.rejects(app.after())
|
||||
await t.rejects(app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await after - error handling, same tick cb err, nested', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
app.use((f, opts, cb) => {
|
||||
app.use((f, opts, cb) => {
|
||||
cb(Error('kaboom'))
|
||||
})
|
||||
cb()
|
||||
})
|
||||
|
||||
await t.rejects(app.after())
|
||||
await t.rejects(app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await after - error handling, future tick cb err', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
app.use((f, opts, cb) => {
|
||||
setImmediate(() => { cb(Error('kaboom')) })
|
||||
})
|
||||
|
||||
await t.rejects(app.after())
|
||||
await t.rejects(app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await after - error handling, future tick cb err, nested', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
app.use((f, opts, cb) => {
|
||||
app.use((f, opts, cb) => {
|
||||
setImmediate(() => { cb(Error('kaboom')) })
|
||||
})
|
||||
cb()
|
||||
})
|
||||
await t.rejects(app.after(), Error('kaboom'))
|
||||
await t.rejects(app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await after complex scenario', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
t.plan(16)
|
||||
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
let fourthLoaded = false
|
||||
|
||||
app.use(first)
|
||||
await app.after()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
app.use(second)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
app.use(third)
|
||||
await app.after()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
await app.ready()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
|
||||
async function first () {
|
||||
firstLoaded = true
|
||||
}
|
||||
|
||||
async function second () {
|
||||
secondLoaded = true
|
||||
}
|
||||
|
||||
async function third (app) {
|
||||
thirdLoaded = true
|
||||
app.use(fourth)
|
||||
}
|
||||
|
||||
async function fourth () {
|
||||
fourthLoaded = true
|
||||
}
|
||||
})
|
||||
|
||||
test('without autostart and sync/async plugin mix', async (t) => {
|
||||
const app = {}
|
||||
boot(app, { autostart: false })
|
||||
t.plan(21)
|
||||
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
let fourthLoaded = false
|
||||
|
||||
app.use(first)
|
||||
await app.after()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
|
||||
app.use(second)
|
||||
await app.after()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
|
||||
await sleep(10)
|
||||
|
||||
app.use(third)
|
||||
await app.after()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
|
||||
app.use(fourth)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
|
||||
await app.after()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
|
||||
await app.ready()
|
||||
|
||||
async function first () {
|
||||
firstLoaded = true
|
||||
}
|
||||
|
||||
async function second () {
|
||||
const contents = await fs.readFile(path.join(__dirname, 'fixtures', 'dummy.txt'), 'utf-8')
|
||||
t.equal(contents, 'hello, world!')
|
||||
secondLoaded = true
|
||||
}
|
||||
|
||||
async function third () {
|
||||
await sleep(10)
|
||||
thirdLoaded = true
|
||||
}
|
||||
|
||||
function fourth (server, opts, done) {
|
||||
fourthLoaded = true
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
test('without autostart', async (t) => {
|
||||
const app = {}
|
||||
boot(app, { autostart: false })
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
|
||||
app.use(async function first (app) {
|
||||
firstLoaded = true
|
||||
app.use(async () => {
|
||||
await sleep(1)
|
||||
secondLoaded = true
|
||||
})
|
||||
})
|
||||
|
||||
await app.after()
|
||||
t.equal(firstLoaded, true)
|
||||
t.equal(secondLoaded, true)
|
||||
|
||||
await app.use(async () => {
|
||||
thirdLoaded = true
|
||||
})
|
||||
|
||||
t.equal(thirdLoaded, true)
|
||||
|
||||
await app.ready()
|
||||
})
|
||||
|
||||
test('without autostart and with override', async (t) => {
|
||||
const app = {}
|
||||
const _ = boot(app, { autostart: false })
|
||||
let count = 0
|
||||
|
||||
_.override = function (s) {
|
||||
const res = Object.create(s)
|
||||
res.count = ++count
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(async function first (app) {
|
||||
t.equal(app.count, 1)
|
||||
app.use(async (app) => {
|
||||
t.equal(app.count, 2)
|
||||
await app.after()
|
||||
})
|
||||
})
|
||||
|
||||
await app.after()
|
||||
|
||||
await app.use(async (app) => {
|
||||
t.equal(app.count, 3)
|
||||
})
|
||||
|
||||
await app.ready()
|
||||
})
|
||||
|
||||
test('stop processing after errors', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot()
|
||||
|
||||
try {
|
||||
await app.use(async function first (app) {
|
||||
t.pass('first should be loaded')
|
||||
throw new Error('kaboom')
|
||||
})
|
||||
} catch (e) {
|
||||
t.equal(e.message, 'kaboom')
|
||||
}
|
||||
})
|
||||
31
node_modules/avvio/test/await-self.test.js
generated
vendored
Normal file
31
node_modules/avvio/test/await-self.test.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('await self', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.equal(await app, app)
|
||||
})
|
||||
|
||||
test('await self three times', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.equal(await app, app)
|
||||
t.equal(await app, app)
|
||||
t.equal(await app, app)
|
||||
})
|
||||
|
||||
test('await self within plugin', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
app.use(async (f) => {
|
||||
t.equal(await f, f)
|
||||
})
|
||||
|
||||
t.equal(await app, app)
|
||||
})
|
||||
294
node_modules/avvio/test/await-use.test.js
generated
vendored
Normal file
294
node_modules/avvio/test/await-use.test.js
generated
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { promisify } = require('node:util')
|
||||
const sleep = promisify(setTimeout)
|
||||
const boot = require('..')
|
||||
|
||||
test('await use - nested plugins with same tick callbacks', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(4)
|
||||
|
||||
await app.use((f, opts, cb) => {
|
||||
t.pass('plugin init')
|
||||
app.use((f, opts, cb) => {
|
||||
t.pass('plugin2 init')
|
||||
cb()
|
||||
})
|
||||
cb()
|
||||
})
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await use - nested plugins with future tick callbacks', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(4)
|
||||
|
||||
await app.use((f, opts, cb) => {
|
||||
t.pass('plugin init')
|
||||
app.use((f, opts, cb) => {
|
||||
t.pass('plugin2 init')
|
||||
setImmediate(cb)
|
||||
})
|
||||
setImmediate(cb)
|
||||
})
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await use - nested async function plugins', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(5)
|
||||
|
||||
await app.use(async (f, opts) => {
|
||||
t.pass('plugin init')
|
||||
await app.use(async (f, opts) => {
|
||||
t.pass('plugin2 init')
|
||||
})
|
||||
t.pass('reachable')
|
||||
})
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await use - promise returning function plugins + promise chaining', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(6)
|
||||
|
||||
await app.use((f, opts) => {
|
||||
t.pass('plugin init')
|
||||
return app.use((f, opts) => {
|
||||
t.pass('plugin2 init')
|
||||
return Promise.resolve()
|
||||
}).then(() => {
|
||||
t.pass('reachable')
|
||||
return 'test'
|
||||
}).then((val) => {
|
||||
t.equal(val, 'test')
|
||||
})
|
||||
})
|
||||
t.pass('reachable')
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
test('await use - await and use chaining', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(3)
|
||||
|
||||
app.use(async (f, opts, cb) => {
|
||||
await app.use(async (f, opts) => {
|
||||
t.pass('plugin init')
|
||||
}).use(async (f, opts) => {
|
||||
t.pass('plugin2 init')
|
||||
})
|
||||
})
|
||||
|
||||
await app.ready()
|
||||
t.pass('reachable')
|
||||
})
|
||||
|
||||
function thenableRejects (t, thenable, err, msg) {
|
||||
return t.rejects(async () => { await thenable }, err, msg)
|
||||
}
|
||||
|
||||
test('await use - error handling, async throw', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
await thenableRejects(t, app.use(async (f, opts) => {
|
||||
throw Error('kaboom')
|
||||
}), Error('kaboom'))
|
||||
|
||||
await t.rejects(app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await use - error handling, async throw, nested', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
await thenableRejects(t, app.use(async function a (f, opts) {
|
||||
await app.use(async function b (f, opts) {
|
||||
throw Error('kaboom')
|
||||
})
|
||||
}, Error('kaboom')), 'b')
|
||||
|
||||
t.rejects(() => app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await use - error handling, same tick cb err', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
await thenableRejects(t, app.use((f, opts, cb) => {
|
||||
cb(Error('kaboom'))
|
||||
}), Error('kaboom'))
|
||||
|
||||
t.rejects(() => app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await use - error handling, same tick cb err, nested', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
await thenableRejects(t, app.use((f, opts, cb) => {
|
||||
app.use((f, opts, cb) => {
|
||||
cb(Error('kaboom'))
|
||||
})
|
||||
cb()
|
||||
}), Error('kaboom'))
|
||||
|
||||
t.rejects(() => app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await use - error handling, future tick cb err', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
await thenableRejects(t, app.use((f, opts, cb) => {
|
||||
setImmediate(() => { cb(Error('kaboom')) })
|
||||
}), Error('kaboom'))
|
||||
|
||||
t.rejects(() => app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('await use - error handling, future tick cb err, nested', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
t.plan(2)
|
||||
|
||||
await thenableRejects(t, app.use((f, opts, cb) => {
|
||||
app.use((f, opts, cb) => {
|
||||
setImmediate(() => { cb(Error('kaboom')) })
|
||||
})
|
||||
cb()
|
||||
}), Error('kaboom'))
|
||||
|
||||
t.rejects(() => app.ready(), Error('kaboom'))
|
||||
})
|
||||
|
||||
test('mixed await use and non-awaited use ', async (t) => {
|
||||
const app = {}
|
||||
boot(app)
|
||||
t.plan(16)
|
||||
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
let fourthLoaded = false
|
||||
|
||||
await app.use(first)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
app.use(second)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
await app.use(third)
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
await app.ready()
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
|
||||
async function first () {
|
||||
firstLoaded = true
|
||||
}
|
||||
|
||||
async function second () {
|
||||
secondLoaded = true
|
||||
}
|
||||
|
||||
async function third (app) {
|
||||
thirdLoaded = true
|
||||
app.use(fourth)
|
||||
}
|
||||
|
||||
async function fourth () {
|
||||
fourthLoaded = true
|
||||
}
|
||||
})
|
||||
|
||||
test('await use - mix of same and future tick callbacks', async (t) => {
|
||||
const app = {}
|
||||
boot(app, { autostart: false })
|
||||
let record = ''
|
||||
|
||||
t.plan(4)
|
||||
|
||||
await app.use(async function plugin0 () {
|
||||
t.pass('plugin0 init')
|
||||
record += 'plugin0|'
|
||||
})
|
||||
await app.use(async function plugin1 () {
|
||||
t.pass('plugin1 init')
|
||||
await sleep(500)
|
||||
record += 'plugin1|'
|
||||
})
|
||||
await sleep(1)
|
||||
await app.use(async function plugin2 () {
|
||||
t.pass('plugin2 init')
|
||||
await sleep(500)
|
||||
record += 'plugin2|'
|
||||
})
|
||||
record += 'ready'
|
||||
t.equal(record, 'plugin0|plugin1|plugin2|ready')
|
||||
})
|
||||
|
||||
test('await use - fork the promise chain', (t) => {
|
||||
t.plan(3)
|
||||
const app = {}
|
||||
boot(app, { autostart: false })
|
||||
|
||||
async function setup () {
|
||||
let set = false
|
||||
await app.use(async function plugin0 () {
|
||||
t.pass('plugin0 init')
|
||||
await sleep(500)
|
||||
set = true
|
||||
})
|
||||
t.equal(set, true)
|
||||
}
|
||||
setup()
|
||||
|
||||
app.ready((err, done) => {
|
||||
t.error(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
439
node_modules/avvio/test/basic.test.js
generated
vendored
Normal file
439
node_modules/avvio/test/basic.test.js
generated
vendored
Normal file
@@ -0,0 +1,439 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('boot an empty app', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
app.on('start', () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('start returns app', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({}, { autostart: false })
|
||||
app
|
||||
.start()
|
||||
.ready((err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('boot an app with a plugin', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
let after = false
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
t.equal(server, app, 'the first argument is the server')
|
||||
t.same(opts, {}, 'no options')
|
||||
t.ok(after, 'delayed execution')
|
||||
done()
|
||||
})
|
||||
|
||||
after = true
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('boot an app with a promisified plugin', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
let after = false
|
||||
|
||||
app.use(function (server, opts) {
|
||||
t.equal(server, app, 'the first argument is the server')
|
||||
t.same(opts, {}, 'no options')
|
||||
t.ok(after, 'delayed execution')
|
||||
return Promise.resolve()
|
||||
})
|
||||
|
||||
after = true
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('boot an app with a plugin and a callback /1', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot(() => {
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
t.pass('plugin loaded')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('boot an app with a plugin and a callback /2', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot({}, () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
t.pass('plugin loaded')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('boot a plugin with a custom server', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const server = {}
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.equal(s, server, 'the first argument is the server')
|
||||
t.same(opts, {}, 'no options')
|
||||
done()
|
||||
})
|
||||
|
||||
app.onClose(() => {
|
||||
t.ok('onClose called')
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(() => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('custom instance should inherits avvio methods /1', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const server = {}
|
||||
const app = boot(server, {})
|
||||
|
||||
server.use(function (s, opts, done) {
|
||||
t.equal(s, server, 'the first argument is the server')
|
||||
t.same(opts, {}, 'no options')
|
||||
done()
|
||||
}).after(() => {
|
||||
t.ok('after called')
|
||||
})
|
||||
|
||||
server.onClose(() => {
|
||||
t.ok('onClose called')
|
||||
})
|
||||
|
||||
server.ready(() => {
|
||||
t.ok('ready called')
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
server.close(() => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('custom instance should inherits avvio methods /2', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const server = {}
|
||||
const app = new boot(server, {}) // eslint-disable-line new-cap
|
||||
|
||||
server.use(function (s, opts, done) {
|
||||
t.equal(s, server, 'the first argument is the server')
|
||||
t.same(opts, {}, 'no options')
|
||||
done()
|
||||
}).after(() => {
|
||||
t.ok('after called')
|
||||
})
|
||||
|
||||
server.onClose(() => {
|
||||
t.ok('onClose called')
|
||||
})
|
||||
|
||||
server.ready(() => {
|
||||
t.ok('ready called')
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
server.close(() => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('boot a plugin with options', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = {}
|
||||
const app = boot(server)
|
||||
const myOpts = {
|
||||
hello: 'world'
|
||||
}
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.equal(s, server, 'the first argument is the server')
|
||||
t.same(opts, myOpts, 'passed options')
|
||||
done()
|
||||
}, myOpts)
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('boot a plugin with a function that returns the options', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const server = {}
|
||||
const app = boot(server)
|
||||
const myOpts = {
|
||||
hello: 'world'
|
||||
}
|
||||
const myOptsAsFunc = parent => {
|
||||
t.equal(parent, server)
|
||||
return parent.myOpts
|
||||
}
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
s.myOpts = opts
|
||||
done()
|
||||
}, myOpts)
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
t.equal(s, server, 'the first argument is the server')
|
||||
t.same(opts, myOpts, 'passed options via function accessing parent injected variable')
|
||||
done()
|
||||
}, myOptsAsFunc)
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('throw on non-function use', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
t.throws(() => {
|
||||
app.use({})
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/mcollina/avvio/issues/20
|
||||
test('ready and nextTick', (t) => {
|
||||
const app = boot()
|
||||
process.nextTick(() => {
|
||||
app.ready(() => {
|
||||
t.end()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/mcollina/avvio/issues/20
|
||||
test('promises and microtask', (t) => {
|
||||
const app = boot()
|
||||
Promise.resolve()
|
||||
.then(() => {
|
||||
app.ready(function () {
|
||||
t.end()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('always loads nested plugins after the current one', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const server = {}
|
||||
const app = boot(server)
|
||||
|
||||
let second = false
|
||||
|
||||
app.use(function (s, opts, done) {
|
||||
app.use(function (s, opts, done) {
|
||||
second = true
|
||||
done()
|
||||
})
|
||||
t.notOk(second)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(second)
|
||||
})
|
||||
})
|
||||
|
||||
test('promise long resolve', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot()
|
||||
|
||||
setTimeout(function () {
|
||||
t.throws(() => {
|
||||
app.use((s, opts, done) => {
|
||||
done()
|
||||
})
|
||||
}, 'root plugin has already booted')
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.notOk(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('do not autostart', (t) => {
|
||||
const app = boot(null, {
|
||||
autostart: false
|
||||
})
|
||||
app.on('start', () => {
|
||||
t.fail()
|
||||
})
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('start with ready', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot(null, {
|
||||
autostart: false
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass()
|
||||
})
|
||||
|
||||
app.ready(function (err) {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('load a plugin after start()', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
let startCalled = false
|
||||
const app = boot(null, {
|
||||
autostart: false
|
||||
})
|
||||
|
||||
app.use((s, opts, done) => {
|
||||
t.ok(startCalled)
|
||||
done()
|
||||
})
|
||||
|
||||
// we use a timer because
|
||||
// it is more reliable than
|
||||
// nextTick and setImmediate
|
||||
// this almost always will come
|
||||
// after those are completed
|
||||
setTimeout(() => {
|
||||
app.start()
|
||||
startCalled = true
|
||||
}, 2)
|
||||
})
|
||||
|
||||
test('booted should be set before ready', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.ready(function (err) {
|
||||
t.error(err)
|
||||
t.equal(app.booted, true)
|
||||
})
|
||||
})
|
||||
|
||||
test('start should be emitted after ready resolves', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
let ready = false
|
||||
|
||||
app.ready().then(function () {
|
||||
ready = true
|
||||
})
|
||||
|
||||
app.on('start', function () {
|
||||
t.equal(ready, true)
|
||||
})
|
||||
})
|
||||
|
||||
test('throws correctly if registering after ready', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.ready(function () {
|
||||
t.throws(() => {
|
||||
app.use((a, b, done) => done())
|
||||
}, 'root plugin has already booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('preReady errors must be managed', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use((f, opts, cb) => {
|
||||
cb()
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
throw new Error('boom')
|
||||
})
|
||||
|
||||
app.ready(err => {
|
||||
t.pass('ready function is called')
|
||||
t.equal(err.message, 'boom')
|
||||
})
|
||||
})
|
||||
|
||||
test('preReady errors do not override plugin\'s errors', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use((f, opts, cb) => {
|
||||
cb(new Error('baam'))
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.pass('preReady is executed')
|
||||
throw new Error('boom')
|
||||
})
|
||||
|
||||
app.ready(err => {
|
||||
t.pass('ready function is called')
|
||||
t.equal(err.message, 'baam')
|
||||
})
|
||||
})
|
||||
|
||||
test('support faux modules', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
let after = false
|
||||
|
||||
// Faux modules are modules built with TypeScript
|
||||
// or Babel that they export a .default property.
|
||||
app.use({
|
||||
default: function (server, opts, done) {
|
||||
t.equal(server, app, 'the first argument is the server')
|
||||
t.same(opts, {}, 'no options')
|
||||
t.ok(after, 'delayed execution')
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
after = true
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
113
node_modules/avvio/test/callbacks.test.js
generated
vendored
Normal file
113
node_modules/avvio/test/callbacks.test.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('reentrant', (t) => {
|
||||
t.plan(7)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
|
||||
app
|
||||
.use(first)
|
||||
.after(() => {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
|
||||
function first (s, opts, done) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second)
|
||||
done()
|
||||
}
|
||||
|
||||
function second (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
secondLoaded = true
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
test('reentrant with callbacks deferred', (t) => {
|
||||
t.plan(11)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
|
||||
app.use(first)
|
||||
|
||||
function first (s, opts, done) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second)
|
||||
setTimeout(() => {
|
||||
try {
|
||||
s.use(third)
|
||||
} catch (err) {
|
||||
t.equal(err.message, 'Root plugin has already booted')
|
||||
}
|
||||
}, 500)
|
||||
done()
|
||||
}
|
||||
|
||||
function second (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
secondLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
function third (s, opts, done) {
|
||||
thirdLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('multiple loading time', t => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
|
||||
function a (instance, opts, done) {
|
||||
(opts.use || []).forEach(_ => { instance.use(_, { use: opts.subUse || [] }) })
|
||||
setTimeout(done, 10)
|
||||
}
|
||||
const pointer = a
|
||||
|
||||
function b (instance, opts, done) {
|
||||
(opts.use || []).forEach(_ => { instance.use(_, { use: opts.subUse || [] }) })
|
||||
setTimeout(done, 20)
|
||||
}
|
||||
|
||||
function c (instance, opts, done) {
|
||||
(opts.use || []).forEach(_ => { instance.use(_, { use: opts.subUse || [] }) })
|
||||
setTimeout(done, 30)
|
||||
}
|
||||
|
||||
app
|
||||
.use(function a (instance, opts, done) {
|
||||
instance.use(pointer, { use: [b], subUse: [c] })
|
||||
.use(b)
|
||||
setTimeout(done, 0)
|
||||
})
|
||||
.after(() => {
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
26
node_modules/avvio/test/catch-override-exception.test.js
generated
vendored
Normal file
26
node_modules/avvio/test/catch-override-exception.test.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('catch exceptions in parent.override', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const server = {}
|
||||
|
||||
const app = boot(server, {
|
||||
autostart: false
|
||||
})
|
||||
app.override = function () {
|
||||
throw Error('catch it')
|
||||
}
|
||||
|
||||
app
|
||||
.use(function () {})
|
||||
.start()
|
||||
|
||||
app.ready(function (err) {
|
||||
t.type(err, Error)
|
||||
t.match(err, /catch it/)
|
||||
})
|
||||
})
|
||||
67
node_modules/avvio/test/chainable.test.js
generated
vendored
Normal file
67
node_modules/avvio/test/chainable.test.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('chainable standalone', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const readyResult = boot()
|
||||
.use(function (ctx, opts, done) {
|
||||
t.pass('1st plugin')
|
||||
done()
|
||||
}).after(function (err, done) {
|
||||
t.error(err)
|
||||
t.pass('2nd after')
|
||||
done()
|
||||
}).ready(function () {
|
||||
t.pass('we are ready')
|
||||
})
|
||||
t.equal(readyResult, undefined)
|
||||
})
|
||||
|
||||
test('chainable automatically binded', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
const readyResult = app
|
||||
.use(function (ctx, opts, done) {
|
||||
t.pass('1st plugin')
|
||||
done()
|
||||
}).after(function (err, done) {
|
||||
t.error(err)
|
||||
t.pass('2nd after')
|
||||
done()
|
||||
}).ready(function () {
|
||||
t.pass('we are ready')
|
||||
})
|
||||
t.equal(readyResult, undefined)
|
||||
})
|
||||
|
||||
test('chainable standalone with server', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const server = {}
|
||||
boot(server, {
|
||||
expose: {
|
||||
use: 'register'
|
||||
}
|
||||
})
|
||||
|
||||
const readyResult = server.register(function (ctx, opts, done) {
|
||||
t.pass('1st plugin')
|
||||
done()
|
||||
}).after(function (err, done) {
|
||||
t.error(err)
|
||||
t.pass('2nd after')
|
||||
done()
|
||||
}).register(function (ctx, opts, done) {
|
||||
t.pass('3rd plugin')
|
||||
done()
|
||||
}).ready(function () {
|
||||
t.pass('we are ready')
|
||||
})
|
||||
t.equal(readyResult, undefined)
|
||||
})
|
||||
544
node_modules/avvio/test/close.test.js
generated
vendored
Normal file
544
node_modules/avvio/test/close.test.js
generated
vendored
Normal file
@@ -0,0 +1,544 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
const { AVV_ERR_CALLBACK_NOT_FN } = require('../lib/errors')
|
||||
|
||||
test('boot an app with a plugin', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
let last = false
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
app.onClose(() => {
|
||||
t.ok('onClose called')
|
||||
t.notOk(last)
|
||||
last = true
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(() => {
|
||||
t.ok(last)
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose arguments', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function (server, opts, next) {
|
||||
server.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
t.equal(server, instance)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.use(function (server, opts, next) {
|
||||
server.onClose((instance) => {
|
||||
t.ok('called')
|
||||
t.equal(server, instance)
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(() => {
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose arguments - fastify encapsulation test case', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s, fn, opts) {
|
||||
s = Object.create(s)
|
||||
return s
|
||||
}
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.test = true
|
||||
instance.onClose((i, done) => {
|
||||
t.ok(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
t.notOk(instance.test)
|
||||
instance.onClose((i, done) => {
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.notOk(app.test)
|
||||
app.close(() => {
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose arguments - fastify encapsulation test case / 2', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s, fn, opts) {
|
||||
s = Object.create(s)
|
||||
return s
|
||||
}
|
||||
|
||||
server.use(function (instance, opts, next) {
|
||||
instance.test = true
|
||||
instance.onClose((i, done) => {
|
||||
t.ok(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
server.use(function (instance, opts, next) {
|
||||
t.notOk(instance.test)
|
||||
instance.onClose((i, done) => {
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.notOk(server.test)
|
||||
try {
|
||||
server.close()
|
||||
t.pass()
|
||||
} catch (err) {
|
||||
t.fail(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose arguments - encapsulation test case no server', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.override = function (s, fn, opts) {
|
||||
s = Object.create(s)
|
||||
return s
|
||||
}
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.test = true
|
||||
instance.onClose((i, done) => {
|
||||
t.notOk(i.test)
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
t.notOk(instance.test)
|
||||
instance.onClose((i) => {
|
||||
t.notOk(i.test)
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.notOk(app.test)
|
||||
app.close(() => {
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose should handle errors', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done(new Error('some error'))
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(err => {
|
||||
t.equal(err.message, 'some error')
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('#54 close handlers should receive same parameters when queue is not empty', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const context = { test: true }
|
||||
const app = boot(context)
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
done()
|
||||
})
|
||||
app.on('start', () => {
|
||||
app.close((err, done) => {
|
||||
t.equal(err, null)
|
||||
t.pass('Closed in the correct order')
|
||||
setImmediate(done)
|
||||
})
|
||||
app.close(err => {
|
||||
t.equal(err, null)
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
app.close(err => {
|
||||
t.equal(err, null)
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose should handle errors / 2', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done(new Error('some error'))
|
||||
})
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(err => {
|
||||
t.equal(err.message, 'some error')
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('close arguments', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close((err, instance, done) => {
|
||||
t.error(err)
|
||||
t.equal(instance, app)
|
||||
done()
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('close event', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const app = boot()
|
||||
let last = false
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(() => {
|
||||
t.notOk(last)
|
||||
last = true
|
||||
})
|
||||
})
|
||||
|
||||
app.on('close', () => {
|
||||
t.ok(last)
|
||||
t.pass('event fired')
|
||||
})
|
||||
})
|
||||
|
||||
test('close order', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const app = boot()
|
||||
const order = [1, 2, 3, 4]
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
app.onClose(() => {
|
||||
t.equal(order.shift(), 3)
|
||||
})
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
app.onClose(() => {
|
||||
t.equal(order.shift(), 2)
|
||||
})
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
app.onClose(() => {
|
||||
t.equal(order.shift(), 1)
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(() => {
|
||||
t.equal(order.shift(), 4)
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('close without a cb', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done()
|
||||
})
|
||||
|
||||
app.close()
|
||||
})
|
||||
|
||||
test('onClose with 0 parameters', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.onClose(function () {
|
||||
t.ok('called')
|
||||
t.equal(arguments.length, 0)
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.close(err => {
|
||||
t.error(err)
|
||||
t.pass('Closed')
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose with 1 parameter', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.use(function (instance, opts, next) {
|
||||
instance.onClose(function (context) {
|
||||
t.equal(arguments.length, 1)
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.close(err => {
|
||||
t.error(err)
|
||||
t.pass('Closed')
|
||||
})
|
||||
})
|
||||
|
||||
test('close passing not a function', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done()
|
||||
})
|
||||
|
||||
t.throws(() => app.close({}), { message: 'not a function' })
|
||||
})
|
||||
|
||||
test('close passing not a function', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done()
|
||||
})
|
||||
|
||||
t.throws(() => app.close({}), { message: 'not a function' })
|
||||
})
|
||||
|
||||
test('close passing not a function when wrapping', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = {}
|
||||
boot(app)
|
||||
|
||||
app.onClose((instance, done) => {
|
||||
t.ok('called')
|
||||
done()
|
||||
})
|
||||
|
||||
t.throws(() => app.close({}), { message: 'not a function' })
|
||||
})
|
||||
|
||||
test('close should trigger ready()', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot(null, {
|
||||
autostart: false
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
// this will be emitted after the
|
||||
// callback in close() is fired
|
||||
t.pass('started')
|
||||
})
|
||||
|
||||
app.close(() => {
|
||||
t.pass('closed')
|
||||
})
|
||||
})
|
||||
|
||||
test('close without a cb returns a promise', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
app.close().then(() => {
|
||||
t.pass('promise resolves')
|
||||
})
|
||||
})
|
||||
|
||||
test('close without a cb returns a promise when attaching to a server', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const server = {}
|
||||
boot(server)
|
||||
server.close().then(() => {
|
||||
t.pass('promise resolves')
|
||||
})
|
||||
})
|
||||
|
||||
test('close with async onClose handlers', t => {
|
||||
t.plan(7)
|
||||
|
||||
const app = boot()
|
||||
const order = [1, 2, 3, 4, 5, 6]
|
||||
|
||||
app.onClose(() => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 5)
|
||||
})
|
||||
})
|
||||
|
||||
app.onClose(() => {
|
||||
t.equal(order.shift(), 4)
|
||||
})
|
||||
|
||||
app.onClose(instance => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 3)
|
||||
})
|
||||
})
|
||||
|
||||
app.onClose(async instance => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 2)
|
||||
})
|
||||
})
|
||||
|
||||
app.onClose(async () => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 1)
|
||||
})
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(() => {
|
||||
t.equal(order.shift(), 6)
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose callback must be a function', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app.use(function (server, opts, done) {
|
||||
t.throws(() => app.onClose({}), new AVV_ERR_CALLBACK_NOT_FN('onClose', 'object'))
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('close custom server with async onClose handlers', t => {
|
||||
t.plan(7)
|
||||
|
||||
const server = {}
|
||||
const app = boot(server)
|
||||
const order = [1, 2, 3, 4, 5, 6]
|
||||
|
||||
server.onClose(() => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 5)
|
||||
})
|
||||
})
|
||||
|
||||
server.onClose(() => {
|
||||
t.equal(order.shift(), 4)
|
||||
})
|
||||
|
||||
server.onClose(instance => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 3)
|
||||
})
|
||||
})
|
||||
|
||||
server.onClose(async instance => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 2)
|
||||
})
|
||||
})
|
||||
|
||||
server.onClose(async () => {
|
||||
return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
|
||||
t.equal(order.shift(), 1)
|
||||
})
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
app.close(() => {
|
||||
t.equal(order.shift(), 6)
|
||||
t.pass('Closed in the correct order')
|
||||
})
|
||||
})
|
||||
})
|
||||
26
node_modules/avvio/test/errors.test.js
generated
vendored
Normal file
26
node_modules/avvio/test/errors.test.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const errors = require('../lib/errors')
|
||||
|
||||
test('Correct codes of AvvioErrors', t => {
|
||||
const testcases = [
|
||||
'AVV_ERR_EXPOSE_ALREADY_DEFINED',
|
||||
'AVV_ERR_ATTRIBUTE_ALREADY_DEFINED',
|
||||
'AVV_ERR_CALLBACK_NOT_FN',
|
||||
'AVV_ERR_PLUGIN_NOT_VALID',
|
||||
'AVV_ERR_ROOT_PLG_BOOTED',
|
||||
'AVV_ERR_PARENT_PLG_LOADED',
|
||||
'AVV_ERR_READY_TIMEOUT',
|
||||
'AVV_ERR_PLUGIN_EXEC_TIMEOUT'
|
||||
]
|
||||
|
||||
t.plan(testcases.length + 1)
|
||||
// errors.js exposes errors and the createError fn
|
||||
t.equal(testcases.length, Object.keys(errors).length)
|
||||
|
||||
for (const testcase of testcases) {
|
||||
const error = new errors[testcase]()
|
||||
t.equal(error.code, testcase)
|
||||
}
|
||||
})
|
||||
12
node_modules/avvio/test/esm.mjs
generated
vendored
Normal file
12
node_modules/avvio/test/esm.mjs
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { test } from 'tap'
|
||||
import boot from '../boot.js'
|
||||
|
||||
test('support import', async (t) => {
|
||||
const app = boot()
|
||||
|
||||
app.use(import('./fixtures/esm.mjs'))
|
||||
|
||||
await app.ready()
|
||||
|
||||
t.equal(app.loaded, true)
|
||||
})
|
||||
14
node_modules/avvio/test/esm.test.js
generated
vendored
Normal file
14
node_modules/avvio/test/esm.test.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
|
||||
test('support esm import', (t) => {
|
||||
import('./esm.mjs').then(() => {
|
||||
t.pass('esm is supported')
|
||||
t.end()
|
||||
}).catch((err) => {
|
||||
process.nextTick(() => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
})
|
||||
23
node_modules/avvio/test/events-listeners.test.js
generated
vendored
Normal file
23
node_modules/avvio/test/events-listeners.test.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
const noop = () => {}
|
||||
|
||||
test('boot a plugin and then execute a call after that', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
process.on('warning', (warning) => {
|
||||
t.fail('we should not get a warning', warning)
|
||||
})
|
||||
|
||||
const app = boot()
|
||||
// eslint-disable-next-line no-var
|
||||
for (var i = 0; i < 12; i++) {
|
||||
app.on('preReady', noop)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
t.pass('Everything ok')
|
||||
}, 500)
|
||||
})
|
||||
80
node_modules/avvio/test/expose.test.js
generated
vendored
Normal file
80
node_modules/avvio/test/expose.test.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
const { AVV_ERR_EXPOSE_ALREADY_DEFINED, AVV_ERR_ATTRIBUTE_ALREADY_DEFINED } = require('../lib/errors')
|
||||
const { kAvvio } = require('../lib/symbols')
|
||||
|
||||
for (const key of ['use', 'after', 'ready', 'onClose', 'close']) {
|
||||
test('throws if ' + key + ' is by default already there', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = {}
|
||||
app[key] = () => { }
|
||||
|
||||
t.throws(() => boot(app), new AVV_ERR_EXPOSE_ALREADY_DEFINED(key, key))
|
||||
})
|
||||
|
||||
test('throws if ' + key + ' is already there', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const app = {}
|
||||
app['cust' + key] = () => { }
|
||||
|
||||
t.throws(() => boot(app, { expose: { [key]: 'cust' + key } }), new AVV_ERR_EXPOSE_ALREADY_DEFINED('cust' + key, key))
|
||||
})
|
||||
|
||||
test('support expose for ' + key, (t) => {
|
||||
const app = {}
|
||||
app[key] = () => { }
|
||||
|
||||
const expose = {}
|
||||
expose[key] = 'muahah'
|
||||
|
||||
boot(app, {
|
||||
expose
|
||||
})
|
||||
|
||||
t.end()
|
||||
})
|
||||
}
|
||||
|
||||
test('set the kAvvio to true on the server', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const server = {}
|
||||
boot(server)
|
||||
|
||||
t.ok(server[kAvvio])
|
||||
})
|
||||
|
||||
test('.then()', t => {
|
||||
t.plan(3)
|
||||
|
||||
t.test('.then() can not be overwritten', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const server = {
|
||||
then: () => {}
|
||||
}
|
||||
t.throws(() => boot(server), AVV_ERR_ATTRIBUTE_ALREADY_DEFINED('then'))
|
||||
})
|
||||
|
||||
t.test('.then() is a function', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const server = {}
|
||||
boot(server)
|
||||
|
||||
t.type(server.then, 'function')
|
||||
})
|
||||
|
||||
t.test('.then() can not be overwritten', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const server = {}
|
||||
boot(server)
|
||||
|
||||
t.throws(() => { server.then = 'invalid' }, TypeError('Cannot set property then of #<Object> which has only a getter'))
|
||||
})
|
||||
})
|
||||
52
node_modules/avvio/test/express.test.js
generated
vendored
Normal file
52
node_modules/avvio/test/express.test.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const express = require('express')
|
||||
const http = require('node:http')
|
||||
const boot = require('..')
|
||||
|
||||
test('express support', (t) => {
|
||||
const app = express()
|
||||
|
||||
boot.express(app)
|
||||
// It does:
|
||||
//
|
||||
// boot(app, {
|
||||
// expose: {
|
||||
// use: 'load'
|
||||
// }
|
||||
// })
|
||||
|
||||
t.plan(2)
|
||||
|
||||
let loaded = false
|
||||
let server
|
||||
|
||||
app.load(function (app, opts, done) {
|
||||
loaded = true
|
||||
app.use(function (req, res) {
|
||||
res.end('hello world')
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
app.after((cb) => {
|
||||
t.ok(loaded, 'plugin loaded')
|
||||
server = app.listen(0, cb)
|
||||
t.teardown(server.close.bind(server))
|
||||
})
|
||||
|
||||
app.ready(() => {
|
||||
http.get(`http://localhost:${server.address().port}`).on('response', function (res) {
|
||||
let data = ''
|
||||
res.on('data', function (chunk) {
|
||||
data += chunk
|
||||
})
|
||||
|
||||
res.on('end', function () {
|
||||
t.equal(data, 'hello world')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
1
node_modules/avvio/test/fixtures/dummy.txt
generated
vendored
Normal file
1
node_modules/avvio/test/fixtures/dummy.txt
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
hello, world!
|
||||
3
node_modules/avvio/test/fixtures/esm.mjs
generated
vendored
Normal file
3
node_modules/avvio/test/fixtures/esm.mjs
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default async function (app) {
|
||||
app.loaded = true
|
||||
}
|
||||
5
node_modules/avvio/test/fixtures/plugin-no-next.js
generated
vendored
Normal file
5
node_modules/avvio/test/fixtures/plugin-no-next.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = function noNext (app, opts, next) {
|
||||
// no call to next
|
||||
}
|
||||
16
node_modules/avvio/test/gh-issues/bug-205.test.js
generated
vendored
Normal file
16
node_modules/avvio/test/gh-issues/bug-205.test.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('../..')
|
||||
|
||||
test('should print the time tree', (t) => {
|
||||
t.plan(2)
|
||||
const app = boot()
|
||||
|
||||
app.use(function first (instance, opts, cb) {
|
||||
const out = instance.prettyPrint().split('\n')
|
||||
t.equal(out[0], 'root -1 ms')
|
||||
t.equal(out[1], '└── first -1 ms')
|
||||
cb()
|
||||
})
|
||||
})
|
||||
55
node_modules/avvio/test/lib/create-promise.test.js
generated
vendored
Normal file
55
node_modules/avvio/test/lib/create-promise.test.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { createPromise } = require('../../lib/create-promise')
|
||||
|
||||
test('createPromise() returns an object', (t) => {
|
||||
t.plan(3)
|
||||
t.type(createPromise(), 'object')
|
||||
t.equal(Array.isArray(createPromise()), false)
|
||||
t.notOk(Array.isArray(createPromise() !== null))
|
||||
})
|
||||
|
||||
test('createPromise() returns an attribute with attribute resolve', (t) => {
|
||||
t.plan(1)
|
||||
t.ok('resolve' in createPromise())
|
||||
})
|
||||
|
||||
test('createPromise() returns an attribute with attribute reject', (t) => {
|
||||
t.plan(1)
|
||||
t.ok('reject' in createPromise())
|
||||
})
|
||||
|
||||
test('createPromise() returns an attribute with attribute createPromise', (t) => {
|
||||
t.plan(1)
|
||||
t.ok('promise' in createPromise())
|
||||
})
|
||||
|
||||
test('when resolve is called, createPromise attribute is resolved', (t) => {
|
||||
t.plan(1)
|
||||
const p = createPromise()
|
||||
|
||||
p.promise
|
||||
.then(() => {
|
||||
t.pass()
|
||||
})
|
||||
.catch(() => {
|
||||
t.fail()
|
||||
})
|
||||
p.resolve()
|
||||
})
|
||||
|
||||
test('when reject is called, createPromise attribute is rejected', (t) => {
|
||||
t.plan(1)
|
||||
const p = createPromise()
|
||||
|
||||
p.promise
|
||||
.then(() => {
|
||||
t.fail()
|
||||
})
|
||||
.catch(() => {
|
||||
t.pass()
|
||||
})
|
||||
|
||||
p.reject()
|
||||
})
|
||||
82
node_modules/avvio/test/lib/execute-with-thenable.test.js
generated
vendored
Normal file
82
node_modules/avvio/test/lib/execute-with-thenable.test.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { executeWithThenable } = require('../../lib/execute-with-thenable')
|
||||
const { kAvvio } = require('../../lib/symbols')
|
||||
|
||||
test('executeWithThenable', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
t.test('passes the arguments to the function', (t) => {
|
||||
t.plan(5)
|
||||
|
||||
executeWithThenable((...args) => {
|
||||
t.equal(args.length, 3)
|
||||
t.equal(args[0], 1)
|
||||
t.equal(args[1], 2)
|
||||
t.equal(args[2], 3)
|
||||
}, [1, 2, 3], (err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('function references this to itself', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const func = function () {
|
||||
t.equal(this, func)
|
||||
}
|
||||
executeWithThenable(func, [], (err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('handle resolving Promise of func', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fn = function () {
|
||||
return Promise.resolve(42)
|
||||
}
|
||||
|
||||
executeWithThenable(fn, [], (err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('handle rejecting Promise of func', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fn = function () {
|
||||
return Promise.reject(new Error('Arbitrary Error'))
|
||||
}
|
||||
|
||||
executeWithThenable(fn, [], (err) => {
|
||||
t.equal(err.message, 'Arbitrary Error')
|
||||
})
|
||||
})
|
||||
|
||||
t.test('dont handle avvio mocks PromiseLike results but use callback if provided', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fn = function () {
|
||||
const result = Promise.resolve(42)
|
||||
result[kAvvio] = true
|
||||
}
|
||||
|
||||
executeWithThenable(fn, [], (err) => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('dont handle avvio mocks Promises and if no callback is provided', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fn = function () {
|
||||
t.pass(1)
|
||||
const result = Promise.resolve(42)
|
||||
result[kAvvio] = true
|
||||
}
|
||||
|
||||
executeWithThenable(fn, [])
|
||||
})
|
||||
})
|
||||
67
node_modules/avvio/test/lib/get-plugin-name.test.js
generated
vendored
Normal file
67
node_modules/avvio/test/lib/get-plugin-name.test.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { getPluginName } = require('../../lib/get-plugin-name')
|
||||
const { kPluginMeta } = require('../../lib/symbols')
|
||||
|
||||
test('getPluginName of function', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
t.equal(getPluginName(function aPlugin () { }), 'aPlugin')
|
||||
})
|
||||
|
||||
test('getPluginName of async function', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
t.equal(getPluginName(async function aPlugin () { }), 'aPlugin')
|
||||
})
|
||||
|
||||
test('getPluginName of arrow function without name', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
t.equal(getPluginName(() => { }), '() => { }')
|
||||
t.equal(getPluginName(() => { return 'random' }), '() => { return \'random\' }')
|
||||
})
|
||||
|
||||
test('getPluginName of arrow function assigned to variable', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const namedArrowFunction = () => { }
|
||||
t.equal(getPluginName(namedArrowFunction), 'namedArrowFunction')
|
||||
})
|
||||
|
||||
test("getPluginName based on Symbol 'plugin-meta' /1", (t) => {
|
||||
t.plan(1)
|
||||
|
||||
function plugin () {
|
||||
|
||||
}
|
||||
|
||||
plugin[kPluginMeta] = {}
|
||||
t.equal(getPluginName(plugin), 'plugin')
|
||||
})
|
||||
|
||||
test("getPluginName based on Symbol 'plugin-meta' /2", (t) => {
|
||||
t.plan(1)
|
||||
|
||||
function plugin () {
|
||||
|
||||
}
|
||||
|
||||
plugin[kPluginMeta] = {
|
||||
name: 'fastify-non-existent'
|
||||
}
|
||||
t.equal(getPluginName(plugin), 'fastify-non-existent')
|
||||
})
|
||||
|
||||
test('getPluginName if null is provided as options', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
t.equal(getPluginName(function a () {}, null), 'a')
|
||||
})
|
||||
|
||||
test('getPluginName if name is provided in options', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
t.equal(getPluginName(function defaultName () {}, { name: 'providedName' }), 'providedName')
|
||||
})
|
||||
20
node_modules/avvio/test/lib/is-bundled-or-typescript-plugin.test.js
generated
vendored
Normal file
20
node_modules/avvio/test/lib/is-bundled-or-typescript-plugin.test.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { isBundledOrTypescriptPlugin } = require('../../lib/is-bundled-or-typescript-plugin')
|
||||
|
||||
test('isBundledOrTypescriptPlugin', (t) => {
|
||||
t.plan(9)
|
||||
|
||||
t.equal(isBundledOrTypescriptPlugin(1), false)
|
||||
t.equal(isBundledOrTypescriptPlugin('function'), false)
|
||||
t.equal(isBundledOrTypescriptPlugin({}), false)
|
||||
t.equal(isBundledOrTypescriptPlugin([]), false)
|
||||
t.equal(isBundledOrTypescriptPlugin(null), false)
|
||||
|
||||
t.equal(isBundledOrTypescriptPlugin(function () {}), false)
|
||||
t.equal(isBundledOrTypescriptPlugin(new Promise((resolve) => resolve)), false)
|
||||
t.equal(isBundledOrTypescriptPlugin(Promise.resolve()), false)
|
||||
|
||||
t.equal(isBundledOrTypescriptPlugin({ default: () => {} }), true)
|
||||
})
|
||||
20
node_modules/avvio/test/lib/is-promise-like.test.js
generated
vendored
Normal file
20
node_modules/avvio/test/lib/is-promise-like.test.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { isPromiseLike } = require('../../lib/is-promise-like')
|
||||
|
||||
test('isPromiseLike', (t) => {
|
||||
t.plan(9)
|
||||
|
||||
t.equal(isPromiseLike(1), false)
|
||||
t.equal(isPromiseLike('function'), false)
|
||||
t.equal(isPromiseLike({}), false)
|
||||
t.equal(isPromiseLike([]), false)
|
||||
t.equal(isPromiseLike(null), false)
|
||||
|
||||
t.equal(isPromiseLike(function () {}), false)
|
||||
t.equal(isPromiseLike(new Promise((resolve) => resolve)), true)
|
||||
t.equal(isPromiseLike(Promise.resolve()), true)
|
||||
|
||||
t.equal(isPromiseLike({ then: () => {} }), true)
|
||||
})
|
||||
123
node_modules/avvio/test/lib/thenify.test.js
generated
vendored
Normal file
123
node_modules/avvio/test/lib/thenify.test.js
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
'use strict'
|
||||
|
||||
const { test, mock } = require('tap')
|
||||
const { kThenifyDoNotWrap } = require('../../lib/symbols')
|
||||
|
||||
test('thenify', (t) => {
|
||||
t.plan(7)
|
||||
|
||||
t.test('return undefined if booted', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const { thenify } = mock('../../lib/thenify', {
|
||||
'../../lib/debug': {
|
||||
debug: (message) => { t.equal(message, 'thenify returning undefined because we are already booted') }
|
||||
}
|
||||
})
|
||||
const result = thenify.call({
|
||||
booted: true
|
||||
})
|
||||
t.equal(result, undefined)
|
||||
})
|
||||
|
||||
t.test('return undefined if kThenifyDoNotWrap is true', (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const { thenify } = require('../../lib/thenify')
|
||||
const result = thenify.call({
|
||||
[kThenifyDoNotWrap]: true
|
||||
})
|
||||
t.equal(result, undefined)
|
||||
})
|
||||
|
||||
t.test('return PromiseConstructorLike if kThenifyDoNotWrap is false', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const { thenify } = mock('../../lib/thenify', {
|
||||
'../../lib/debug': {
|
||||
debug: (message) => { t.equal(message, 'thenify') }
|
||||
}
|
||||
})
|
||||
const promiseContructorLike = thenify.call({
|
||||
[kThenifyDoNotWrap]: false
|
||||
})
|
||||
|
||||
t.type(promiseContructorLike, 'function')
|
||||
t.equal(promiseContructorLike.length, 2)
|
||||
})
|
||||
|
||||
t.test('return PromiseConstructorLike', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const { thenify } = mock('../../lib/thenify', {
|
||||
'../../lib/debug': {
|
||||
debug: (message) => { t.equal(message, 'thenify') }
|
||||
}
|
||||
})
|
||||
const promiseContructorLike = thenify.call({})
|
||||
|
||||
t.type(promiseContructorLike, 'function')
|
||||
t.equal(promiseContructorLike.length, 2)
|
||||
})
|
||||
|
||||
t.test('resolve should return _server', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const { thenify } = require('../../lib/thenify')
|
||||
|
||||
const server = {
|
||||
_loadRegistered: () => {
|
||||
return Promise.resolve()
|
||||
},
|
||||
_server: 'server'
|
||||
}
|
||||
const promiseContructorLike = thenify.call(server)
|
||||
|
||||
promiseContructorLike(function (value) {
|
||||
t.equal(value, 'server')
|
||||
}, function (reason) {
|
||||
t.error(reason)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('resolving should set kThenifyDoNotWrap to true', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const { thenify } = require('../../lib/thenify')
|
||||
|
||||
const server = {
|
||||
_loadRegistered: () => {
|
||||
return Promise.resolve()
|
||||
},
|
||||
[kThenifyDoNotWrap]: false,
|
||||
_server: 'server'
|
||||
}
|
||||
const promiseContructorLike = thenify.call(server)
|
||||
|
||||
promiseContructorLike(function (value) {
|
||||
t.equal(server[kThenifyDoNotWrap], true)
|
||||
}, function (reason) {
|
||||
t.error(reason)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('rejection should pass through to reject', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const { thenify } = require('../../lib/thenify')
|
||||
|
||||
const server = {
|
||||
_loadRegistered: () => {
|
||||
return Promise.reject(new Error('Arbitrary rejection'))
|
||||
},
|
||||
_server: 'server'
|
||||
}
|
||||
const promiseContructorLike = thenify.call(server)
|
||||
|
||||
promiseContructorLike(function (value) {
|
||||
t.error(value)
|
||||
}, function (reason) {
|
||||
t.equal(reason.message, 'Arbitrary rejection')
|
||||
})
|
||||
})
|
||||
})
|
||||
391
node_modules/avvio/test/lib/time-tree.test.js
generated
vendored
Normal file
391
node_modules/avvio/test/lib/time-tree.test.js
generated
vendored
Normal file
@@ -0,0 +1,391 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { TimeTree } = require('../../lib/time-tree')
|
||||
|
||||
test('TimeTree is constructed with a root attribute, set to null', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
t.equal(tree.root, null)
|
||||
})
|
||||
|
||||
test('TimeTree is constructed with an empty tableId-Map', t => {
|
||||
t.plan(2)
|
||||
|
||||
const tree = new TimeTree()
|
||||
t.ok(tree.tableId instanceof Map)
|
||||
t.equal(tree.tableId.size, 0)
|
||||
})
|
||||
|
||||
test('TimeTree is constructed with an empty tableLabel-Map', t => {
|
||||
t.plan(2)
|
||||
|
||||
const tree = new TimeTree()
|
||||
t.ok(tree.tableLabel instanceof Map)
|
||||
t.equal(tree.tableLabel.size, 0)
|
||||
})
|
||||
|
||||
test('TimeTree#toJSON dumps the content of the TimeTree', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
t.same(tree.toJSON(), {})
|
||||
})
|
||||
|
||||
test('TimeTree#toJSON is creating new instances of its content, ensuring being immutable', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
t.not(tree.toJSON(), tree.toJSON())
|
||||
})
|
||||
|
||||
test('TimeTree#start is adding a node with correct shape, root-node', t => {
|
||||
t.plan(15)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
|
||||
const rootNode = tree.root
|
||||
|
||||
t.equal(Object.keys(rootNode).length, 7)
|
||||
t.ok('parent' in rootNode)
|
||||
t.equal(rootNode.parent, null)
|
||||
t.ok('id' in rootNode)
|
||||
t.type(rootNode.id, 'string')
|
||||
t.ok('label' in rootNode)
|
||||
t.type(rootNode.label, 'string')
|
||||
t.ok('nodes' in rootNode)
|
||||
t.ok(Array.isArray(rootNode.nodes))
|
||||
t.ok('start' in rootNode)
|
||||
t.ok(Number.isInteger(rootNode.start))
|
||||
t.ok('stop' in rootNode)
|
||||
t.type(rootNode.stop, 'null')
|
||||
t.ok('diff' in rootNode)
|
||||
t.type(rootNode.diff, 'number')
|
||||
})
|
||||
|
||||
test('TimeTree#start is adding a node with correct shape, child-node', t => {
|
||||
t.plan(16)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
|
||||
const rootNode = tree.root
|
||||
|
||||
t.equal(rootNode.nodes.length, 1)
|
||||
|
||||
const childNode = rootNode.nodes[0]
|
||||
|
||||
t.equal(Object.keys(childNode).length, 7)
|
||||
t.ok('parent' in childNode)
|
||||
t.type(childNode.parent, 'string')
|
||||
t.ok('id' in childNode)
|
||||
t.type(childNode.id, 'string')
|
||||
t.ok('label' in childNode)
|
||||
t.type(childNode.label, 'string')
|
||||
t.ok('nodes' in childNode)
|
||||
t.ok(Array.isArray(childNode.nodes))
|
||||
t.ok('start' in childNode)
|
||||
t.ok(Number.isInteger(childNode.start))
|
||||
t.ok('stop' in childNode)
|
||||
t.type(childNode.stop, 'null')
|
||||
t.ok('diff' in childNode)
|
||||
t.type(childNode.diff, 'number')
|
||||
})
|
||||
|
||||
test('TimeTree#start is adding a root element when parent is null', t => {
|
||||
t.plan(9)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
|
||||
const rootNode = tree.root
|
||||
|
||||
t.type(rootNode, 'object')
|
||||
t.equal(Object.keys(rootNode).length, 7)
|
||||
t.equal(rootNode.parent, null)
|
||||
t.equal(rootNode.id, 'root')
|
||||
t.equal(rootNode.label, 'root')
|
||||
t.ok(Array.isArray(rootNode.nodes))
|
||||
t.equal(rootNode.nodes.length, 0)
|
||||
t.ok(Number.isInteger(rootNode.start))
|
||||
t.type(rootNode.diff, 'number')
|
||||
})
|
||||
|
||||
test('TimeTree#start is adding a root element when parent does not exist', t => {
|
||||
t.plan(9)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start('invalid', 'root')
|
||||
|
||||
const rootNode = tree.root
|
||||
|
||||
t.type(rootNode, 'object')
|
||||
t.equal(Object.keys(rootNode).length, 7)
|
||||
t.equal(rootNode.parent, null)
|
||||
t.equal(rootNode.id, 'root')
|
||||
t.equal(rootNode.label, 'root')
|
||||
t.ok(Array.isArray(rootNode.nodes))
|
||||
t.equal(rootNode.nodes.length, 0)
|
||||
t.ok(Number.isInteger(rootNode.start))
|
||||
t.type(rootNode.diff, 'number')
|
||||
})
|
||||
|
||||
test('TimeTree#start parameter start can override automatically generated start time', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root', 1337)
|
||||
|
||||
t.ok(tree.root.start, 1337)
|
||||
})
|
||||
|
||||
test('TimeTree#start returns id of root, when adding a root node /1', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
t.equal(tree.start(null, 'root'), 'root')
|
||||
})
|
||||
|
||||
test('TimeTree#start returns id of root, when adding a root node /2', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
t.equal(tree.start(null, '/'), 'root')
|
||||
})
|
||||
|
||||
test('TimeTree#start returns id of child, when adding a child node', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
t.match(tree.start('root', 'child'), /^child-[0-9.]+$/)
|
||||
})
|
||||
|
||||
test('TimeTree tracks node ids /1', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
|
||||
t.equal(tree.tableId.size, 2)
|
||||
t.ok(tree.tableId.has('root'))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[0].id))
|
||||
})
|
||||
|
||||
test('TimeTree tracks node ids /2', t => {
|
||||
t.plan(4)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('child', 'grandchild')
|
||||
|
||||
t.equal(tree.tableId.size, 3)
|
||||
t.ok(tree.tableId.has('root'))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[0].id))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[0].nodes[0].id))
|
||||
})
|
||||
|
||||
test('TimeTree tracks node ids /3', t => {
|
||||
t.plan(4)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'child')
|
||||
|
||||
t.equal(tree.tableId.size, 3)
|
||||
t.ok(tree.tableId.has('root'))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[0].id))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[1].id))
|
||||
})
|
||||
|
||||
test('TimeTree tracks node labels /1', t => {
|
||||
t.plan(4)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'sibling')
|
||||
|
||||
t.equal(tree.tableLabel.size, 3)
|
||||
t.ok(tree.tableLabel.has('root'))
|
||||
t.ok(tree.tableLabel.has('child'))
|
||||
t.ok(tree.tableLabel.has('sibling'))
|
||||
})
|
||||
|
||||
test('TimeTree tracks node labels /2', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'child')
|
||||
|
||||
t.equal(tree.tableLabel.size, 2)
|
||||
t.ok(tree.tableLabel.has('root'))
|
||||
t.ok(tree.tableLabel.has('child'))
|
||||
})
|
||||
|
||||
test('TimeTree#stop returns undefined', t => {
|
||||
t.plan(1)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
|
||||
t.type(tree.stop('root'), 'undefined')
|
||||
})
|
||||
|
||||
test('TimeTree#stop sets stop value of node', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
t.type(tree.root.stop, 'null')
|
||||
|
||||
tree.stop('root')
|
||||
t.type(tree.root.stop, 'number')
|
||||
t.ok(Number.isInteger(tree.root.stop))
|
||||
})
|
||||
|
||||
test('TimeTree#stop parameter stop is used as stop value of node', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
t.type(tree.root.stop, 'null')
|
||||
|
||||
tree.stop('root', 1337)
|
||||
t.type(tree.root.stop, 'number')
|
||||
t.equal(tree.root.stop, 1337)
|
||||
})
|
||||
|
||||
test('TimeTree#stop calculates the diff', t => {
|
||||
t.plan(4)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root', 1)
|
||||
t.type(tree.root.diff, 'number')
|
||||
t.equal(tree.root.diff, -1)
|
||||
tree.stop('root', 5)
|
||||
|
||||
t.type(tree.root.diff, 'number')
|
||||
t.equal(tree.root.diff, 4)
|
||||
})
|
||||
|
||||
test('TimeTree#stop does nothing when node is not found', t => {
|
||||
t.plan(2)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
t.type(tree.root.stop, 'null')
|
||||
|
||||
tree.stop('invalid')
|
||||
t.type(tree.root.stop, 'null')
|
||||
})
|
||||
|
||||
test('TimeTree untracks node ids /1', t => {
|
||||
t.plan(2)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
|
||||
tree.stop(tree.root.nodes[0].id)
|
||||
t.equal(tree.tableId.size, 1)
|
||||
t.ok(tree.tableId.has('root'))
|
||||
})
|
||||
|
||||
test('TimeTree untracks node ids /2', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('child', 'grandchild')
|
||||
|
||||
tree.stop(tree.root.nodes[0].nodes[0].id)
|
||||
|
||||
t.equal(tree.tableId.size, 2)
|
||||
t.ok(tree.tableId.has('root'))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[0].id))
|
||||
})
|
||||
|
||||
test('TimeTree untracks node ids /3', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'child')
|
||||
|
||||
tree.stop(tree.root.nodes[0].id)
|
||||
|
||||
t.equal(tree.tableId.size, 2)
|
||||
t.ok(tree.tableId.has('root'))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[1].id))
|
||||
})
|
||||
|
||||
test('TimeTree untracks node ids /4', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'child')
|
||||
|
||||
tree.stop(tree.root.nodes[1].id)
|
||||
|
||||
t.equal(tree.tableId.size, 2)
|
||||
t.ok(tree.tableId.has('root'))
|
||||
t.ok(tree.tableId.has(tree.root.nodes[0].id))
|
||||
})
|
||||
|
||||
test('TimeTree untracks node labels /1', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'sibling')
|
||||
|
||||
tree.stop(tree.root.nodes[1].id)
|
||||
|
||||
t.equal(tree.tableLabel.size, 2)
|
||||
t.ok(tree.tableLabel.has('root'))
|
||||
t.ok(tree.tableLabel.has('child'))
|
||||
})
|
||||
|
||||
test('TimeTree untracks node labels /2', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'sibling')
|
||||
|
||||
tree.stop(tree.root.nodes[0].id)
|
||||
|
||||
t.equal(tree.tableLabel.size, 2)
|
||||
t.ok(tree.tableLabel.has('root'))
|
||||
t.ok(tree.tableLabel.has('sibling'))
|
||||
})
|
||||
|
||||
test('TimeTree does not untrack label if used by other node', t => {
|
||||
t.plan(3)
|
||||
|
||||
const tree = new TimeTree()
|
||||
tree.start(null, 'root')
|
||||
tree.start('root', 'child')
|
||||
tree.start('root', 'child')
|
||||
|
||||
tree.stop(tree.root.nodes[0].id)
|
||||
|
||||
t.equal(tree.tableLabel.size, 2)
|
||||
t.ok(tree.tableLabel.has('root'))
|
||||
t.ok(tree.tableLabel.has('child'))
|
||||
})
|
||||
19
node_modules/avvio/test/lib/validate-plugin.test.js
generated
vendored
Normal file
19
node_modules/avvio/test/lib/validate-plugin.test.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { validatePlugin } = require('../../lib/validate-plugin')
|
||||
const { AVV_ERR_PLUGIN_NOT_VALID } = require('../../lib/errors')
|
||||
|
||||
test('validatePlugin', (t) => {
|
||||
t.plan(8)
|
||||
|
||||
t.throws(() => validatePlugin(1), new AVV_ERR_PLUGIN_NOT_VALID('number'))
|
||||
t.throws(() => validatePlugin('function'), new AVV_ERR_PLUGIN_NOT_VALID('string'))
|
||||
t.throws(() => validatePlugin({}), new AVV_ERR_PLUGIN_NOT_VALID('object'))
|
||||
t.throws(() => validatePlugin([]), new AVV_ERR_PLUGIN_NOT_VALID('array'))
|
||||
t.throws(() => validatePlugin(null), new AVV_ERR_PLUGIN_NOT_VALID('null'))
|
||||
|
||||
t.doesNotThrow(() => validatePlugin(function () {}))
|
||||
t.doesNotThrow(() => validatePlugin(new Promise((resolve) => resolve)))
|
||||
t.doesNotThrow(() => validatePlugin(Promise.resolve()))
|
||||
})
|
||||
112
node_modules/avvio/test/load-plugin.test.js
generated
vendored
Normal file
112
node_modules/avvio/test/load-plugin.test.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict'
|
||||
|
||||
const fastq = require('fastq')
|
||||
const boot = require('..')
|
||||
const { test } = require('tap')
|
||||
const { Plugin } = require('../lib/plugin')
|
||||
|
||||
test('successfully load a plugin with sync function', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), function (instance, opts, done) {
|
||||
done()
|
||||
}, false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err, undefined)
|
||||
})
|
||||
})
|
||||
|
||||
test('catch an error when loading a plugin with sync function', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), function (instance, opts, done) {
|
||||
done(Error('ArbitraryError'))
|
||||
}, false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err.message, 'ArbitraryError')
|
||||
})
|
||||
})
|
||||
|
||||
test('successfully load a plugin with async function', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), async function (instance, opts) { }, false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err, undefined)
|
||||
})
|
||||
})
|
||||
|
||||
test('catch an error when loading a plugin with async function', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), async function (instance, opts) {
|
||||
throw Error('ArbitraryError')
|
||||
}, false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err.message, 'ArbitraryError')
|
||||
})
|
||||
})
|
||||
|
||||
test('successfully load a plugin when function is a Promise, which resolves to a function', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), new Promise(resolve => resolve(function (instance, opts, done) {
|
||||
done()
|
||||
})), false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err, undefined)
|
||||
})
|
||||
})
|
||||
|
||||
test('catch an error when loading a plugin when function is a Promise, which resolves to a function', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), new Promise(resolve => resolve(function (instance, opts, done) {
|
||||
done(Error('ArbitraryError'))
|
||||
})), false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err.message, 'ArbitraryError')
|
||||
})
|
||||
})
|
||||
|
||||
test('successfully load a plugin when function is a Promise, which resolves to a function, which is wrapped in default', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), new Promise(resolve => resolve({
|
||||
default: function (instance, opts, done) {
|
||||
done()
|
||||
}
|
||||
})), false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err, undefined)
|
||||
})
|
||||
})
|
||||
|
||||
test('catch an error when loading a plugin when function is a Promise, which resolves to a function, which is wrapped in default', (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), new Promise(resolve => resolve({
|
||||
default: function (instance, opts, done) {
|
||||
done(Error('ArbitraryError'))
|
||||
}
|
||||
})), false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err.message, 'ArbitraryError')
|
||||
})
|
||||
})
|
||||
33
node_modules/avvio/test/on-ready-timeout-await.test.js
generated
vendored
Normal file
33
node_modules/avvio/test/on-ready-timeout-await.test.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: off */
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('../boot')
|
||||
|
||||
test('onReadyTimeout', async (t) => {
|
||||
const app = boot({}, {
|
||||
timeout: 10, // 10 ms
|
||||
autostart: false
|
||||
})
|
||||
|
||||
app.use(function one (innerApp, opts, next) {
|
||||
t.pass('loaded')
|
||||
innerApp.ready(function readyNoResolve (err, done) {
|
||||
t.notOk(err)
|
||||
t.pass('first ready called')
|
||||
// Do not call done() to timeout
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
await app.start()
|
||||
|
||||
try {
|
||||
await app.ready()
|
||||
t.fail('should throw')
|
||||
} catch (err) {
|
||||
t.equal(err.message, 'Plugin did not start in time: \'readyNoResolve\'. You may have forgotten to call \'done\' function or to resolve a Promise')
|
||||
// And not Plugin did not start in time: 'bound _encapsulateThreeParam'. You may have forgotten to call 'done' function or to resolve a Promise
|
||||
}
|
||||
})
|
||||
374
node_modules/avvio/test/override.test.js
generated
vendored
Normal file
374
node_modules/avvio/test/override.test.js
generated
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: off */
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('custom inheritance', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s) {
|
||||
t.equal(s, server)
|
||||
|
||||
const res = Object.create(s)
|
||||
res.b = 42
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s, opts, cb) {
|
||||
t.not(s, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s))
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
test('custom inheritance multiple levels', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const server = { count: 0 }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s) {
|
||||
const res = Object.create(s)
|
||||
res.count = res.count + 1
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s1, opts, cb) {
|
||||
t.not(s1, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s1))
|
||||
t.equal(s1.count, 1)
|
||||
s1.use(second)
|
||||
|
||||
cb()
|
||||
|
||||
function second (s2, opts, cb) {
|
||||
t.not(s2, s1)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(s1, s2))
|
||||
t.equal(s2.count, 2)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('custom inheritance multiple levels twice', (t) => {
|
||||
t.plan(10)
|
||||
|
||||
const server = { count: 0 }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s) {
|
||||
const res = Object.create(s)
|
||||
res.count = res.count + 1
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s1, opts, cb) {
|
||||
t.not(s1, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s1))
|
||||
t.equal(s1.count, 1)
|
||||
s1.use(second)
|
||||
s1.use(third)
|
||||
let prev
|
||||
|
||||
cb()
|
||||
|
||||
function second (s2, opts, cb) {
|
||||
prev = s2
|
||||
t.not(s2, s1)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(s1, s2))
|
||||
t.equal(s2.count, 2)
|
||||
cb()
|
||||
}
|
||||
|
||||
function third (s3, opts, cb) {
|
||||
t.not(s3, s1)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(s1, s3))
|
||||
t.notOk(Object.prototype.isPrototypeOf.call(prev, s3))
|
||||
t.equal(s3.count, 2)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('custom inheritance multiple levels with multiple heads', (t) => {
|
||||
t.plan(13)
|
||||
|
||||
const server = { count: 0 }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s) {
|
||||
const res = Object.create(s)
|
||||
res.count = res.count + 1
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s1, opts, cb) {
|
||||
t.not(s1, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s1))
|
||||
t.equal(s1.count, 1)
|
||||
s1.use(second)
|
||||
|
||||
cb()
|
||||
|
||||
function second (s2, opts, cb) {
|
||||
t.not(s2, s1)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(s1, s2))
|
||||
t.equal(s2.count, 2)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
|
||||
app.use(function third (s1, opts, cb) {
|
||||
t.not(s1, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s1))
|
||||
t.equal(s1.count, 1)
|
||||
s1.use(fourth)
|
||||
|
||||
cb()
|
||||
|
||||
function fourth (s2, opts, cb) {
|
||||
t.not(s2, s1)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(s1, s2))
|
||||
t.equal(s2.count, 2)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
|
||||
app.ready(function () {
|
||||
t.equal(server.count, 0)
|
||||
})
|
||||
})
|
||||
|
||||
test('fastify test case', (t) => {
|
||||
t.plan(7)
|
||||
|
||||
const noop = () => {}
|
||||
|
||||
function build () {
|
||||
const app = boot(server, {})
|
||||
app.override = function (s) {
|
||||
return Object.create(s)
|
||||
}
|
||||
|
||||
server.add = function (name, fn, cb) {
|
||||
if (this[name]) return cb(new Error('already existent'))
|
||||
this[name] = fn
|
||||
cb()
|
||||
}
|
||||
|
||||
return server
|
||||
|
||||
function server (req, res) {}
|
||||
}
|
||||
|
||||
const instance = build()
|
||||
t.ok(instance.add)
|
||||
t.ok(instance.use)
|
||||
|
||||
instance.use((i, opts, cb) => {
|
||||
t.not(i, instance)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(instance, i))
|
||||
|
||||
i.add('test', noop, (err) => {
|
||||
t.error(err)
|
||||
t.ok(i.test)
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
instance.ready(() => {
|
||||
t.notOk(instance.test)
|
||||
})
|
||||
})
|
||||
|
||||
test('override should pass also the plugin function', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s, fn) {
|
||||
t.type(fn, 'function')
|
||||
t.equal(fn, first)
|
||||
return s
|
||||
}
|
||||
|
||||
app.use(first)
|
||||
|
||||
function first (s, opts, cb) {
|
||||
t.equal(s, server)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
|
||||
test('skip override - fastify test case', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s, func) {
|
||||
if (func[Symbol.for('skip-override')]) {
|
||||
return s
|
||||
}
|
||||
return Object.create(s)
|
||||
}
|
||||
|
||||
first[Symbol.for('skip-override')] = true
|
||||
app.use(first)
|
||||
|
||||
function first (s, opts, cb) {
|
||||
t.equal(s, server)
|
||||
t.notOk(Object.prototype.isPrototypeOf.call(server, s))
|
||||
cb()
|
||||
}
|
||||
})
|
||||
|
||||
test('override can receive options object', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const options = { hello: 'world' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s, fn, opts) {
|
||||
t.equal(s, server)
|
||||
t.same(opts, options)
|
||||
|
||||
const res = Object.create(s)
|
||||
res.b = 42
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s, opts, cb) {
|
||||
t.not(s, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s))
|
||||
cb()
|
||||
}, options)
|
||||
})
|
||||
|
||||
test('override can receive options function', (t) => {
|
||||
t.plan(8)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const options = { hello: 'world' }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s, fn, opts) {
|
||||
t.equal(s, server)
|
||||
if (typeof opts !== 'function') {
|
||||
t.same(opts, options)
|
||||
}
|
||||
|
||||
const res = Object.create(s)
|
||||
res.b = 42
|
||||
res.bar = 'world'
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s, opts, cb) {
|
||||
t.not(s, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s))
|
||||
s.foo = 'bar'
|
||||
cb()
|
||||
}, options)
|
||||
|
||||
app.use(function second (s, opts, cb) {
|
||||
t.notOk(s.foo)
|
||||
t.same(opts, { hello: 'world' })
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s))
|
||||
cb()
|
||||
}, p => ({ hello: p.bar }))
|
||||
})
|
||||
|
||||
test('after trigger override', t => {
|
||||
t.plan(8)
|
||||
|
||||
const server = { count: 0 }
|
||||
const app = boot(server)
|
||||
|
||||
let overrideCalls = 0
|
||||
app.override = function (s, fn, opts) {
|
||||
overrideCalls++
|
||||
const res = Object.create(s)
|
||||
res.count = res.count + 1
|
||||
return res
|
||||
}
|
||||
|
||||
app
|
||||
.use(function first (s, opts, cb) {
|
||||
t.equal(s.count, 1, 'should trigger override')
|
||||
cb()
|
||||
})
|
||||
.after(function () {
|
||||
t.equal(overrideCalls, 1, 'after with 0 parameter should not trigger override')
|
||||
})
|
||||
.after(function (err) {
|
||||
if (err) throw err
|
||||
t.equal(overrideCalls, 1, 'after with 1 parameter should not trigger override')
|
||||
})
|
||||
.after(function (err, done) {
|
||||
if (err) throw err
|
||||
t.equal(overrideCalls, 1, 'after with 2 parameters should not trigger override')
|
||||
done()
|
||||
})
|
||||
.after(function (err, context, done) {
|
||||
if (err) throw err
|
||||
t.equal(overrideCalls, 1, 'after with 3 parameters should not trigger override')
|
||||
done()
|
||||
})
|
||||
.after(async function () {
|
||||
t.equal(overrideCalls, 1, 'async after with 0 parameter should not trigger override')
|
||||
})
|
||||
.after(async function (err) {
|
||||
if (err) throw err
|
||||
t.equal(overrideCalls, 1, 'async after with 1 parameter should not trigger override')
|
||||
})
|
||||
.after(async function (err, context) {
|
||||
if (err) throw err
|
||||
t.equal(overrideCalls, 1, 'async after with 2 parameters should not trigger override')
|
||||
})
|
||||
})
|
||||
|
||||
test('custom inheritance override in after', (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const server = { count: 0 }
|
||||
const app = boot(server)
|
||||
|
||||
app.override = function (s) {
|
||||
const res = Object.create(s)
|
||||
res.count = res.count + 1
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s1, opts, cb) {
|
||||
t.not(s1, server)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(server, s1))
|
||||
t.equal(s1.count, 1)
|
||||
s1.after(() => {
|
||||
s1.use(second)
|
||||
})
|
||||
|
||||
cb()
|
||||
|
||||
function second (s2, opts, cb) {
|
||||
t.not(s2, s1)
|
||||
t.ok(Object.prototype.isPrototypeOf.call(s1, s2))
|
||||
t.equal(s2.count, 2)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
})
|
||||
84
node_modules/avvio/test/plugin-loaded-so-far.test.js
generated
vendored
Normal file
84
node_modules/avvio/test/plugin-loaded-so-far.test.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const fastq = require('fastq')
|
||||
const boot = require('..')
|
||||
const { Plugin } = require('../lib/plugin')
|
||||
|
||||
test('loadedSoFar resolves a Promise, if plugin.loaded is set to true', async (t) => {
|
||||
t.plan(1)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), function (instance, opts, done) {
|
||||
done()
|
||||
}, false, 0)
|
||||
|
||||
plugin.loaded = true
|
||||
|
||||
await t.resolves(plugin.loadedSoFar())
|
||||
})
|
||||
|
||||
test('loadedSoFar resolves a Promise, if plugin was loaded by avvio', async (t) => {
|
||||
t.plan(2)
|
||||
const app = boot({})
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), function (instance, opts, done) {
|
||||
done()
|
||||
}, false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function (err) {
|
||||
t.equal(err, undefined)
|
||||
})
|
||||
|
||||
await app.ready()
|
||||
|
||||
await t.resolves(plugin.loadedSoFar())
|
||||
})
|
||||
|
||||
test('loadedSoFar resolves a Promise, if .after() has no error', async t => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
|
||||
app.after = function (callback) {
|
||||
callback(null, () => {})
|
||||
}
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), function (instance, opts, done) {
|
||||
done()
|
||||
}, false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function () {})
|
||||
|
||||
await t.resolves(plugin.loadedSoFar())
|
||||
})
|
||||
|
||||
test('loadedSoFar rejects a Promise, if .after() has an error', async t => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
|
||||
app.after = function (fn) {
|
||||
fn(new Error('ArbitraryError'), () => {})
|
||||
}
|
||||
|
||||
const plugin = new Plugin(fastq(app, app._loadPluginNextTick, 1), function (instance, opts, done) {
|
||||
done()
|
||||
}, false, 0)
|
||||
|
||||
app._loadPlugin(plugin, function () {})
|
||||
|
||||
await t.rejects(plugin.loadedSoFar(), new Error('ArbitraryError'))
|
||||
})
|
||||
|
||||
test('loadedSoFar resolves a Promise, if Plugin is attached to avvio after it the Plugin was instantiated', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const plugin = new Plugin(fastq(null, null, 1), function (instance, opts, done) {
|
||||
done()
|
||||
}, false, 0)
|
||||
|
||||
const promise = plugin.loadedSoFar()
|
||||
|
||||
plugin.server = boot()
|
||||
plugin.emit('start')
|
||||
await t.resolves(promise)
|
||||
})
|
||||
69
node_modules/avvio/test/plugin-name.test.js
generated
vendored
Normal file
69
node_modules/avvio/test/plugin-name.test.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
const { kPluginMeta } = require('../lib/symbols')
|
||||
|
||||
test('plugins get a name from the plugin metadata if it is set', async (t) => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
|
||||
const func = (app, opts, next) => next()
|
||||
func[kPluginMeta] = { name: 'a-test-plugin' }
|
||||
app.use(func)
|
||||
await app.ready()
|
||||
|
||||
t.match(app.toJSON(), {
|
||||
label: 'root',
|
||||
nodes: [
|
||||
{ label: 'a-test-plugin' }
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
test('plugins get a name from the options if theres no metadata', async (t) => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
|
||||
function testPlugin (app, opts, next) { next() }
|
||||
app.use(testPlugin, { name: 'test registration options name' })
|
||||
await app.ready()
|
||||
|
||||
t.match(app.toJSON(), {
|
||||
label: 'root',
|
||||
nodes: [
|
||||
{ label: 'test registration options name' }
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
test('plugins get a name from the function name if theres no name in the options and no metadata', async (t) => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
|
||||
function testPlugin (app, opts, next) { next() }
|
||||
app.use(testPlugin)
|
||||
await app.ready()
|
||||
|
||||
t.match(app.toJSON(), {
|
||||
label: 'root',
|
||||
nodes: [
|
||||
{ label: 'testPlugin' }
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
test('plugins get a name from the function source if theres no other option', async (t) => {
|
||||
t.plan(1)
|
||||
const app = boot()
|
||||
|
||||
app.use((app, opts, next) => next())
|
||||
await app.ready()
|
||||
|
||||
t.match(app.toJSON(), {
|
||||
label: 'root',
|
||||
nodes: [
|
||||
{ label: '(app, opts, next) => next()' }
|
||||
]
|
||||
})
|
||||
})
|
||||
33
node_modules/avvio/test/plugin-timeout-await.test.js
generated
vendored
Normal file
33
node_modules/avvio/test/plugin-timeout-await.test.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: off */
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('do not load', async (t) => {
|
||||
const app = boot({}, { timeout: 10 })
|
||||
|
||||
app.use(first)
|
||||
|
||||
async function first (s, opts) {
|
||||
await s.use(second)
|
||||
}
|
||||
|
||||
async function second (s, opts) {
|
||||
await s.use(third)
|
||||
}
|
||||
|
||||
function third (s, opts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// no resolve
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
await app.start()
|
||||
t.fail('should throw')
|
||||
} catch (err) {
|
||||
t.equal(err.message, 'Plugin did not start in time: \'third\'. You may have forgotten to call \'done\' function or to resolve a Promise')
|
||||
}
|
||||
})
|
||||
218
node_modules/avvio/test/plugin-timeout.test.js
generated
vendored
Normal file
218
node_modules/avvio/test/plugin-timeout.test.js
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
const message = (name) => `Plugin did not start in time: '${name}'. You may have forgotten to call 'done' function or to resolve a Promise`
|
||||
|
||||
test('timeout without calling next - callbacks', (t) => {
|
||||
t.plan(4)
|
||||
const app = boot({}, {
|
||||
timeout: 10 // 10 ms
|
||||
})
|
||||
app.use(one)
|
||||
function one (app, opts, next) {
|
||||
// do not call next on purpose
|
||||
}
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(err.fn, one)
|
||||
t.equal(err.message, message('one'))
|
||||
t.equal(err.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
|
||||
})
|
||||
})
|
||||
|
||||
test('timeout without calling next - promises', (t) => {
|
||||
t.plan(4)
|
||||
const app = boot({}, {
|
||||
timeout: 10 // 10 ms
|
||||
})
|
||||
app.use(two)
|
||||
function two (app, opts) {
|
||||
return new Promise(function (resolve) {
|
||||
// do not call resolve on purpose
|
||||
})
|
||||
}
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(err.fn, two)
|
||||
t.equal(err.message, message('two'))
|
||||
t.equal(err.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
|
||||
})
|
||||
})
|
||||
|
||||
test('timeout without calling next - use file as name', (t) => {
|
||||
t.plan(3)
|
||||
const app = boot({}, {
|
||||
timeout: 10 // 10 ms
|
||||
})
|
||||
app.use(require('./fixtures/plugin-no-next'))
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(err.message, message('noNext'))
|
||||
t.equal(err.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
|
||||
})
|
||||
})
|
||||
|
||||
test('timeout without calling next - use code as name', (t) => {
|
||||
t.plan(3)
|
||||
const app = boot({}, {
|
||||
timeout: 10 // 10 ms
|
||||
})
|
||||
app.use(function (app, opts, next) {
|
||||
// do not call next on purpose - code as name
|
||||
})
|
||||
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(err.message, message('function (app, opts, next) { -- // do not call next on purpose - code as name'))
|
||||
t.equal(err.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
|
||||
})
|
||||
})
|
||||
|
||||
test('does not keep going', (t) => {
|
||||
t.plan(2)
|
||||
const app = boot({}, {
|
||||
timeout: 10 // 10 ms
|
||||
})
|
||||
app.use(function three (app, opts, next) {
|
||||
next(new Error('kaboom'))
|
||||
})
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
})
|
||||
|
||||
test('throw in override without autostart', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const server = { my: 'server' }
|
||||
const app = boot(server, {
|
||||
timeout: 10,
|
||||
autostart: false
|
||||
})
|
||||
|
||||
app.override = function (s) {
|
||||
throw new Error('kaboom')
|
||||
}
|
||||
|
||||
app.use(function (s, opts, cb) {
|
||||
t.fail('this is never reached')
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(err.message, 'kaboom')
|
||||
})
|
||||
}, 20)
|
||||
})
|
||||
|
||||
test('timeout without calling next in ready and ignoring the error', (t) => {
|
||||
t.plan(11)
|
||||
const app = boot({}, {
|
||||
timeout: 10, // 10 ms
|
||||
autostart: false
|
||||
})
|
||||
|
||||
let preReady = false
|
||||
|
||||
app.use(function one (app, opts, next) {
|
||||
t.pass('loaded')
|
||||
app.ready(function readyOk (err, done) {
|
||||
t.notOk(err)
|
||||
t.pass('first ready called')
|
||||
done()
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.pass('preReady should be called')
|
||||
preReady = true
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('start should be called')
|
||||
})
|
||||
|
||||
app.ready(function onReadyWithoutDone (err, done) {
|
||||
t.pass('wrong ready called')
|
||||
t.ok(preReady, 'preReady already called')
|
||||
t.notOk(err)
|
||||
// done() // Don't call done
|
||||
})
|
||||
|
||||
app.ready(function onReadyTwo (err) {
|
||||
t.ok(err)
|
||||
t.equal(err.message, message('onReadyWithoutDone'))
|
||||
t.equal(err.code, 'AVV_ERR_READY_TIMEOUT')
|
||||
// don't rethrow the error
|
||||
})
|
||||
|
||||
app.start()
|
||||
})
|
||||
|
||||
test('timeout without calling next in ready and rethrowing the error', (t) => {
|
||||
t.plan(11)
|
||||
const app = boot({}, {
|
||||
timeout: 10, // 10 ms
|
||||
autostart: true
|
||||
})
|
||||
|
||||
app.use(function one (app, opts, next) {
|
||||
t.pass('loaded')
|
||||
app.ready(function readyOk (err, done) {
|
||||
t.ok(err)
|
||||
t.equal(err.message, message('onReadyWithoutDone'))
|
||||
t.equal(err.code, 'AVV_ERR_READY_TIMEOUT')
|
||||
done(err)
|
||||
})
|
||||
next()
|
||||
})
|
||||
|
||||
app.on('preReady', () => {
|
||||
t.pass('preReady should be called')
|
||||
})
|
||||
|
||||
app.on('start', () => {
|
||||
t.pass('start should be called in any case')
|
||||
})
|
||||
|
||||
app.ready(function onReadyWithoutDone (err, done) {
|
||||
t.pass('wrong ready called')
|
||||
t.notOk(err)
|
||||
// done() // Don't call done
|
||||
})
|
||||
|
||||
app.ready(function onReadyTwo (err, done) {
|
||||
t.ok(err)
|
||||
t.equal(err.message, message('onReadyWithoutDone'))
|
||||
t.equal(err.code, 'AVV_ERR_READY_TIMEOUT')
|
||||
done(err)
|
||||
})
|
||||
|
||||
app.start()
|
||||
})
|
||||
|
||||
test('nested timeout do not crash - await', (t) => {
|
||||
t.plan(4)
|
||||
const app = boot({}, {
|
||||
timeout: 10 // 10 ms
|
||||
})
|
||||
app.use(one)
|
||||
async function one (app, opts) {
|
||||
await app.use(two)
|
||||
}
|
||||
|
||||
function two (app, opts, next) {
|
||||
// do not call next on purpose
|
||||
}
|
||||
app.ready((err) => {
|
||||
t.ok(err)
|
||||
t.equal(err.fn, two)
|
||||
t.equal(err.message, message('two'))
|
||||
t.equal(err.code, 'AVV_ERR_PLUGIN_EXEC_TIMEOUT')
|
||||
})
|
||||
})
|
||||
75
node_modules/avvio/test/pretty-print.test.js
generated
vendored
Normal file
75
node_modules/avvio/test/pretty-print.test.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('pretty print', t => {
|
||||
t.plan(19)
|
||||
|
||||
const app = boot()
|
||||
app
|
||||
.use(first)
|
||||
.use(duplicate, { count: 3 })
|
||||
.use(second).after(afterUse).after(after)
|
||||
.use(duplicate, { count: 2 })
|
||||
.use(third).after(after)
|
||||
.use(duplicate, { count: 1 })
|
||||
|
||||
const linesExpected = [/^root \d+ ms$/,
|
||||
/^├── first \d+ ms$/,
|
||||
/^├─┬ duplicate \d+ ms$/,
|
||||
/^│ └─┬ duplicate \d+ ms$/,
|
||||
/^│ {3}└─┬ duplicate \d+ ms$/,
|
||||
/^│ {5}└── duplicate \d+ ms$/,
|
||||
/^├── second \d+ ms$/,
|
||||
/^├─┬ bound _after \d+ ms$/,
|
||||
/^│ └── afterInsider \d+ ms$/,
|
||||
/^├── bound _after \d+ ms$/,
|
||||
/^├─┬ duplicate \d+ ms$/,
|
||||
/^│ └─┬ duplicate \d+ ms$/,
|
||||
/^│ {3}└── duplicate \d+ ms$/,
|
||||
/^├── third \d+ ms$/,
|
||||
/^├── bound _after \d+ ms$/,
|
||||
/^└─┬ duplicate \d+ ms$/,
|
||||
/^ {2}└── duplicate \d+ ms$/,
|
||||
''
|
||||
]
|
||||
|
||||
app.on('preReady', function show () {
|
||||
const print = app.prettyPrint()
|
||||
const lines = print.split('\n')
|
||||
|
||||
t.equal(lines.length, linesExpected.length)
|
||||
lines.forEach((l, i) => {
|
||||
t.match(l, linesExpected[i])
|
||||
})
|
||||
})
|
||||
|
||||
function first (s, opts, done) {
|
||||
done()
|
||||
}
|
||||
function second (s, opts, done) {
|
||||
done()
|
||||
}
|
||||
function third (s, opts, done) {
|
||||
done()
|
||||
}
|
||||
function after (err, cb) {
|
||||
cb(err)
|
||||
}
|
||||
function afterUse (err, cb) {
|
||||
app.use(afterInsider)
|
||||
cb(err)
|
||||
}
|
||||
|
||||
function afterInsider (s, opts, done) {
|
||||
done()
|
||||
}
|
||||
|
||||
function duplicate (instance, opts, cb) {
|
||||
if (opts.count > 0) {
|
||||
instance.use(duplicate, { count: opts.count - 1 })
|
||||
}
|
||||
setTimeout(cb, 20)
|
||||
}
|
||||
})
|
||||
124
node_modules/avvio/test/reentrant.test.js
generated
vendored
Normal file
124
node_modules/avvio/test/reentrant.test.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('one level', (t) => {
|
||||
t.plan(13)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
|
||||
app.use(first)
|
||||
app.use(third)
|
||||
|
||||
function first (s, opts, done) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second)
|
||||
done()
|
||||
}
|
||||
|
||||
function second (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
secondLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
function third (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
thirdLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
|
||||
test('multiple reentrant plugin loading', (t) => {
|
||||
t.plan(31)
|
||||
|
||||
const app = boot()
|
||||
let firstLoaded = false
|
||||
let secondLoaded = false
|
||||
let thirdLoaded = false
|
||||
let fourthLoaded = false
|
||||
let fifthLoaded = false
|
||||
|
||||
app.use(first)
|
||||
app.use(fifth)
|
||||
|
||||
function first (s, opts, done) {
|
||||
t.notOk(firstLoaded, 'first is not loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
firstLoaded = true
|
||||
s.use(second)
|
||||
done()
|
||||
}
|
||||
|
||||
function second (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.notOk(secondLoaded, 'second is not loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
secondLoaded = true
|
||||
s.use(third)
|
||||
s.use(fourth)
|
||||
done()
|
||||
}
|
||||
|
||||
function third (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.notOk(thirdLoaded, 'third is not loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
thirdLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
function fourth (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
fourthLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
function fifth (s, opts, done) {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
t.notOk(fifthLoaded, 'fifth is not loaded')
|
||||
fifthLoaded = true
|
||||
done()
|
||||
}
|
||||
|
||||
app.on('start', () => {
|
||||
t.ok(firstLoaded, 'first is loaded')
|
||||
t.ok(secondLoaded, 'second is loaded')
|
||||
t.ok(thirdLoaded, 'third is loaded')
|
||||
t.ok(fourthLoaded, 'fourth is loaded')
|
||||
t.ok(fifthLoaded, 'fifth is loaded')
|
||||
t.pass('booted')
|
||||
})
|
||||
})
|
||||
151
node_modules/avvio/test/to-json.test.js
generated
vendored
Normal file
151
node_modules/avvio/test/to-json.test.js
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('to json', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const app = boot()
|
||||
app
|
||||
.use(one)
|
||||
.use(two)
|
||||
.use(three)
|
||||
|
||||
const outJson = {
|
||||
id: 'root',
|
||||
label: 'root',
|
||||
start: /\d+/,
|
||||
nodes: []
|
||||
}
|
||||
|
||||
app.on('preReady', function show () {
|
||||
const json = app.toJSON()
|
||||
outJson.stop = /\d*/
|
||||
outJson.diff = /\d*/
|
||||
t.match(json, outJson)
|
||||
})
|
||||
|
||||
function one (s, opts, done) {
|
||||
const json = app.toJSON()
|
||||
outJson.nodes.push({
|
||||
id: /.+/,
|
||||
parent: outJson.label,
|
||||
label: 'one',
|
||||
start: /\d+/
|
||||
})
|
||||
t.match(json, outJson)
|
||||
done()
|
||||
}
|
||||
function two (s, opts, done) {
|
||||
const json = app.toJSON()
|
||||
outJson.nodes.push({
|
||||
id: /.+/,
|
||||
parent: outJson.label,
|
||||
label: 'two',
|
||||
start: /\d+/
|
||||
})
|
||||
t.match(json, outJson)
|
||||
done()
|
||||
}
|
||||
function three (s, opts, done) {
|
||||
const json = app.toJSON()
|
||||
outJson.nodes.push({
|
||||
id: /.+/,
|
||||
parent: outJson.label,
|
||||
label: 'three',
|
||||
start: /\d+/
|
||||
})
|
||||
t.match(json, outJson)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
test('to json multi-level hierarchy', (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const server = { name: 'asd', count: 0 }
|
||||
const app = boot(server)
|
||||
|
||||
const outJson = {
|
||||
id: 'root',
|
||||
label: 'root',
|
||||
start: /\d+/,
|
||||
nodes: [
|
||||
{
|
||||
id: /.+/,
|
||||
parent: 'root',
|
||||
start: /\d+/,
|
||||
label: 'first',
|
||||
nodes: [
|
||||
{
|
||||
id: /.+/,
|
||||
parent: 'first',
|
||||
start: /\d+/,
|
||||
label: 'second',
|
||||
nodes: [],
|
||||
stop: /\d+/,
|
||||
diff: /\d+/
|
||||
},
|
||||
{
|
||||
id: /.+/,
|
||||
parent: 'first',
|
||||
start: /\d+/,
|
||||
label: 'third',
|
||||
nodes: [
|
||||
{
|
||||
id: /.+/,
|
||||
parent: 'third',
|
||||
start: /\d+/,
|
||||
label: 'fourth',
|
||||
nodes: [],
|
||||
stop: /\d+/,
|
||||
diff: /\d+/
|
||||
}
|
||||
],
|
||||
stop: /\d+/,
|
||||
diff: /\d+/
|
||||
}
|
||||
],
|
||||
stop: /\d+/,
|
||||
diff: /\d+/
|
||||
}
|
||||
],
|
||||
stop: /\d+/,
|
||||
diff: /\d+/
|
||||
}
|
||||
|
||||
app.on('preReady', function show () {
|
||||
const json = app.toJSON()
|
||||
t.match(json, outJson)
|
||||
})
|
||||
|
||||
app.override = function (s) {
|
||||
const res = Object.create(s)
|
||||
res.count = res.count + 1
|
||||
res.name = 'qwe'
|
||||
return res
|
||||
}
|
||||
|
||||
app.use(function first (s1, opts, cb) {
|
||||
s1.use(second)
|
||||
s1.use(third)
|
||||
cb()
|
||||
|
||||
function second (s2, opts, cb) {
|
||||
t.equal(s2.count, 2)
|
||||
cb()
|
||||
}
|
||||
|
||||
function third (s3, opts, cb) {
|
||||
s3.use(fourth)
|
||||
t.equal(s3.count, 2)
|
||||
cb()
|
||||
}
|
||||
|
||||
function fourth (s4, opts, cb) {
|
||||
t.equal(s4.count, 3)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
})
|
||||
22
node_modules/avvio/test/twice-done.test.js
generated
vendored
Normal file
22
node_modules/avvio/test/twice-done.test.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const boot = require('..')
|
||||
|
||||
test('calling done twice does not throw error', (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const app = boot()
|
||||
|
||||
app
|
||||
.use(twiceDone)
|
||||
.ready((err) => {
|
||||
t.notOk(err, 'no error')
|
||||
})
|
||||
|
||||
function twiceDone (s, opts, done) {
|
||||
done()
|
||||
done()
|
||||
t.pass('did not throw')
|
||||
}
|
||||
})
|
||||
411
node_modules/avvio/test/types/index.ts
generated
vendored
Normal file
411
node_modules/avvio/test/types/index.ts
generated
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
import * as avvio from "../../";
|
||||
|
||||
{
|
||||
// avvio with no argument
|
||||
const app = avvio();
|
||||
|
||||
app.override = (server, fn, options) => server;
|
||||
|
||||
app.use(
|
||||
(server, opts, done) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.on;
|
||||
server.start;
|
||||
server.override;
|
||||
server.onClose;
|
||||
server.close;
|
||||
|
||||
opts.mySuper;
|
||||
|
||||
done();
|
||||
},
|
||||
{ mySuper: "option" }
|
||||
);
|
||||
|
||||
app.use(async (server, options) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.on;
|
||||
server.start;
|
||||
server.override;
|
||||
server.onClose;
|
||||
server.close;
|
||||
});
|
||||
|
||||
app.use(async (server, options) => {},
|
||||
(server) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.on;
|
||||
server.start;
|
||||
server.override;
|
||||
server.onClose;
|
||||
server.close;
|
||||
});
|
||||
|
||||
app.after(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.after((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.after((err: Error, context: avvio.context<null>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
app.ready().then(context => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
});
|
||||
|
||||
app.ready(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.ready((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.ready((err: Error, context: avvio.context<null>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
app.close(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.close((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.close((err: Error, context: avvio.context<null>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
app.onClose((context, done) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
// avvio with done
|
||||
const app = avvio(() => undefined);
|
||||
|
||||
app.use(
|
||||
(server, opts, done) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.on;
|
||||
server.start;
|
||||
server.override;
|
||||
server.onClose;
|
||||
server.close;
|
||||
|
||||
opts.mySuper;
|
||||
|
||||
done();
|
||||
},
|
||||
{ mySuper: "option" }
|
||||
);
|
||||
|
||||
app.use(async (server, options) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.on;
|
||||
server.start;
|
||||
server.override;
|
||||
server.onClose;
|
||||
server.close;
|
||||
});
|
||||
|
||||
app.use(async (server, options) => {},
|
||||
(server) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.on;
|
||||
server.start;
|
||||
server.override;
|
||||
server.onClose;
|
||||
server.close;
|
||||
});
|
||||
|
||||
app.after(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.after((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.after((err: Error, context: avvio.context<null>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
app.ready().then(context => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
});
|
||||
|
||||
app.ready(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.ready((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.ready((err: Error, context: avvio.context<null>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
app.close(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.close((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.close((err: Error, context: avvio.context<null>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
app.onClose((context, done) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.on;
|
||||
context.start;
|
||||
context.override;
|
||||
context.onClose;
|
||||
context.close;
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const server = { typescriptIs: "amazing" };
|
||||
// avvio with server
|
||||
const app = avvio(server);
|
||||
|
||||
app.use(
|
||||
(server, opts, done) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.typescriptIs;
|
||||
|
||||
opts.mySuper;
|
||||
|
||||
done();
|
||||
},
|
||||
{ mySuper: "option" }
|
||||
);
|
||||
|
||||
app.use(async (server, options) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.typescriptIs;
|
||||
});
|
||||
|
||||
app.use(async (server, options) => {},
|
||||
((server) => {
|
||||
server.use;
|
||||
server.after;
|
||||
server.ready;
|
||||
server.typescriptIs;
|
||||
}));
|
||||
|
||||
app.after(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.after((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.after(
|
||||
(err: Error, context: avvio.context<typeof server>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.typescriptIs;
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
app.ready().then(context => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.typescriptIs;
|
||||
});
|
||||
|
||||
app.ready(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.ready((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.ready(
|
||||
(err: Error, context: avvio.context<typeof server>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.close;
|
||||
context.onClose;
|
||||
context.typescriptIs;
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
app.close(err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
app.close((err: Error, done: Function) => {
|
||||
done();
|
||||
});
|
||||
|
||||
app.close(
|
||||
(err: Error, context: avvio.context<typeof server>, done: Function) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.close;
|
||||
context.onClose;
|
||||
context.typescriptIs;
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
app.onClose((context, done) => {
|
||||
context.use;
|
||||
context.after;
|
||||
context.ready;
|
||||
context.close;
|
||||
context.onClose;
|
||||
context.typescriptIs;
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const server = { hello: "world" };
|
||||
const options = {
|
||||
autostart: false,
|
||||
expose: { after: "after", ready: "ready", use: "use", close: "close", onClose : "onClose" },
|
||||
timeout: 50000
|
||||
};
|
||||
// avvio with server and options
|
||||
const app = avvio(server, options);
|
||||
}
|
||||
|
||||
{
|
||||
const server = { hello: "world" };
|
||||
const options = {
|
||||
autostart: false,
|
||||
expose: { after: "after", ready: "ready", use: "use" }
|
||||
};
|
||||
// avvio with server, options and done callback
|
||||
const app = avvio(server, options, () => undefined);
|
||||
}
|
||||
|
||||
{
|
||||
const app = avvio();
|
||||
const plugin: avvio.Plugin<any, any> = async (): Promise<void> => {};
|
||||
const promise = plugin(app, {}, undefined as any);
|
||||
(promise instanceof Promise);
|
||||
}
|
||||
9
node_modules/avvio/test/types/tsconfig.json
generated
vendored
Normal file
9
node_modules/avvio/test/types/tsconfig.json
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"noEmit": true,
|
||||
"strict": true
|
||||
},
|
||||
"files": ["./index.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user