fastify / fastify-autoload Goto Github PK
View Code? Open in Web Editor NEWRequire all plugins in a directory
License: MIT License
Require all plugins in a directory
License: MIT License
A clear and concise description of what the bug is.
unable to run fastify server when importing fastify-autoload
Steps to reproduce the behavior:
npm install --save fastify-autoload
const autoload = require('fastify-autoload')
const fastify = require('fastify')
const path = require('path')
const autoload = require('fastify-autoload')
const app= fastify({ logger: true })
const startFastify = async () => {
try {
await app.listen(3333);
app.log.info(`server listening on ${app.server.address().port}`);
} catch (err) {
app.log.error(err);
process.exit(1);
}
};
startFastify();
A clear and concise description of what you expected to happen.
server should start
// Paste the expected results here
Fastify plugin module support dependencies section. If some plugins wrapped with fastify-plugin registered through autoload, then it checks only plugins, that are loaded through autoload. However it ignores plugins that are previously loaded with fastify.register.
Is that correct behaviour? Or it should check Symbol(registered-plugin)
in fastify instance as well?
3.20.2
3.8.1
16.6.1
macOS
11.5.2
Hey, I want to use this plugin in TypeScript without ts-node
. Instead, I'm piping the project via @swc/register
to NodeJS. But when the project starts, it shows:
Error: fastify-autoload cannot import plugin at 'xxx/xx.ts'. To fix this error compile TypeScript to JavaScript or use 'ts-node' to run your app.
I can apply a hacky workaround with this
Object.assign(process, { [Symbol.for('ts-node.register.instance')]: undefined });
Do we really need this plugin to check if it runs in TypeScript anyway? Seems a bit redundant...
@swc/register
to transpile the project by running
node -r tsconfig-paths/register -r @swc/register server/index.ts
No response
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'foo')
})
if "foo" contains .js files but not index.js nor package.json to define an entry point, the following error is thrown:
(node:4277) UnhandledPromiseRejectionWarning: Error: Cannot find module '/api/services/orders'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:582:15)
at Function.Module._load (internal/modules/cjs/loader.js:508:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at steed.map (/api/node_modules/fastify-autoload/index.js:77:26)
at ResultsHolder.release (/api/node_modules/fastparallel/parallel.js:185:9)
at SingleCaller.release (/api/node_modules/fastparallel/parallel.js:157:17)
at fs.readdir (/api/node_modules/fastify-autoload/index.js:47:13)
at FSReqWrap.args [as oncomplete] (fs.js:140:20)
#33 addresses this issue by loading .js files within a folder.
3.20.2
3.8.0
16.4.2
macOS
11.4
There seems to be a logic bug here that assumes indexDirent
doesn't exist just because a package.json
is present.
Lines 138 to 162 in ce2a45e
I'm working in a TypeScript monorepo and am trying to minimize directory nesting. Loading __dirname
seemed to work, but when I started to use workspaces and added a package.json
to my api/
, the autoloader stopped working.
If I understand the intent behind the code, I think it should be this, seeing as we may not have returned on line 154.
// Contains package.json but no index.js file?
const packageDirent = list.find((dirent) => dirent.name === 'package.json')
if (packageDirent && !indexDirent) {
throw new Error(`fastify-autoload cannot import plugin at '${dir}'. To fix this error rename the main entry file to 'index.js' (or .cjs, .mjs, .ts).`)
}
package.json
in a directoryindex.(j|t)s
in that directoryIf you remove the package.json
it works again.
The autoloader should not throw if there is an index file and a package file.
Given these files.
api/
βββ auth
β βββ sign-in.ts
βββ create-api.ts # export const autoload = false
βββ index.ts # export const autoload = false
βββ package.json
βββ tsconfig.json
βββ typings
βββ fastify
βββ index.d.ts
/* api/create-api.ts */
await api.register(fastifyAutoload, {
dir: __dirname
})
In
Lines 21 to 30 in 41983a1
Given import()
is async, it's possible to parallelize it so they would load faster.
As titled, only a few lines are missing
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 97.96 | 95.45 | 100 | 97.89 | |
index.js | 97.96 | 95.45 | 100 | 97.89 | 96,149 |
----------|----------|----------|----------|----------|-------------------|
Tl;DR: Can't get the autoPrefix thing to work with TS files & ts-node.
I've tried to use autoPrefix two ways with TypeScript files, and I cannot seem to find a way to it to work as expected.
I tried to add the options.prefix to the Autoload call, like so
// server.ts
import * as Fastify from 'fastify';
import * as Autload from 'autoload';
import { join } from 'path';
const fastify = Fastify();
fastify.register(Autoload, {
dir: join(process.cwd(), 'services'),
includeTypeScript: true,
options: {
prefix: '/api'
}
}
fastify.listen(3000, '0.0.0.0', (err, address)=> {
if(err) {
console.error(err);
process.exit();
}
console.log(`Listening on ${address}`);
})
// services/user.ts
module.exports = (fastify, opts, next)=>{
fastify.get('/user', (req, reply)=> { reply.send('hi'); });
next();
}
This only adds in the /user
route, and not /api/user
Basically the same server.ts setup, minus the options object.
// services/user.ts
module.exports = (fastify, opts, next) => {
fastify.get('/user', (r, reply)=>{reply.send('hi'); })
next();
}
module.exports.autoPrefix = '/api';
In both cases /api/user
is not found, but /user
is.
Any tips on how to fix this? I'd be happy to submit a pull request for the documentation once I have a solution.
3.0.0
^3.7.1
14.17.1
macOS
10.15.7
Using a second+ param with routeParams
option does not work, while using a second+ param inside a file work.
Example: route: /abc/_id1/def/_id2:
GET
http://locahost:3000/abc/ worksGET
http://locahost:3000/abc/1/ worksGET
http://locahost:3000/abc/1/def/1 does not worksGET
http://locahost:3000/abc/1/def/_id2 works(temporary?) Solution:
It works correctly if instead of creating a _id2
directory I use :id2
in my file in my def
folder.
fastify.get('/:id2', async function (request, reply) {
return reply.code(200);
})
routeParams
to trueExpecting the second+ _
folder is a param.
In the README there is the following example:
// index.js
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'services'),
options: {}
})
// /services/items/get.js
module.exports = function (f, opts, next) {
f.get('/:id', (request, reply) => {
reply.send({ answer: 42 })
})
next()
}
// /services/items/list.js
module.exports = function (f, opts, next) {
f.get('/', (request, reply) => {
reply.send([0, 1, 2])
})
next()
}
My test:
index.ts
server.register(AutoLoad, {
dir: path.join(__dirname, 'modules/routes/v1'),
options: { prefix: '/v1' },
includeTypeScript: true
})
modules/routes/v1/domains/index.ts
module.exports = (server, opts, next) => {
server.route({
url: "/:url",
logLevel: "warn",
method: ["GET"],
schema: {
params: {
id: { type: 'string', maxLength: 2 },
},
response: {}
},
handler: async (request, reply) => {
return reply.send({ url: request.params.id, works: true });
}
});
next();
};
Generated route:
GET /v1/:url
Looking at the README, I was under the impression that this would load routes using the directories path. Am I doing something wrong or I interpreted that the wrong way?
I removed the fastify-plugin route and converted it to a more standard one, but it didn't change anything it seems.
I like to keep my tests in the same folder as the original files.
services/healthz.js
services/healthz.test.js
Is it possible to ignore *.test.js
files from autoloading?
We should support automatic routes for route params, as example /user/:userId/cart
βββ routes
β βββ user
β β βββ _userId
β β βββ cart.js
βββ package.json
βββ app.js
I would recommend we convert _
to :
on loading.
An option in the plugin for wrapping the export in a fastify-plugin
.
It'd make all my plugins cleaner by just having an option to specific if it needs to be wrapped or not.
requiring fastify-plugin
in each plugin file is annoying and tedious, this would clean lots of code up a bit and wouldn't affect existing code.
module.exports = async function (app, options) {
...
}
module.exports.wrap = true
A valid plugin declaration is not working since fastify-autoload
only checks if plugin.autoConfig
is defined, but export default plugin
compiles to exports.default =
in JS.
Checking the code there are already places where fastify-autoload searches for plugin.default
property (L169).
Declare a new fastify plugin written like this in TS:
import { FastifyInstance, FastifyError } from 'fastify'
import fp from 'fastify-plugin'
import nano, { ServerScope, Configuration } from 'nano'
function couchDB(
fastify: FastifyInstance,
options: Configuration,
next: (err?: FastifyError | undefined) => void,
) {
console.log(options)
const couch = nano(options)
fastify.decorate('couch', couch)
next()
}
couchDB.autoConfig = {
url: 'http://localhost:5984',
}
export default fp(couchDB)
declare module 'fastify' {
interface FastifyInstance {
couch: ServerScope
}
}
This compiles to:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
const nano_1 = __importDefault(require("nano"));
function couchDB(fastify, options, next) {
console.log(options);
const couch = nano_1.default(options);
fastify.decorate('couch', couch);
next();
}
couchDB.autoConfig = {
url: 'http://localhost:5984',
};
exports.default = fastify_plugin_1.default(couchDB);
As you can see the module lacks of module.exports
and just have exports.default
.
An alternative method to fix this bug could be using the "legacy" export =
syntax in TS.
import { FastifyInstance, FastifyError } from 'fastify'
import fp from 'fastify-plugin'
import nano, { ServerScope, Configuration } from 'nano'
function couchDB(
fastify: FastifyInstance,
options: Configuration,
next: (err?: FastifyError | undefined) => void,
) {
console.log(options)
const couch = nano(options)
fastify.decorate('couch', couch)
next()
}
couchDB.autoConfig = {
url: 'http://localhost:5984',
}
export = fp(couchDB)
declare module 'fastify' {
interface FastifyInstance {
couch: ServerScope
}
}
that compiles to:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
const nano_1 = __importDefault(require("nano"));
function couchDB(fastify, options, next) {
console.log(options);
const couch = nano_1.default(options);
fastify.decorate('couch', couch);
next();
}
couchDB.autoConfig = {
url: 'http://localhost:5984',
};
module.exports = fastify_plugin_1.default(couchDB);
//# sourceMappingURL=couchdb.js.map
However many developers don't even know this syntax exists or, even worse, what it does. In addition to that, if it remains like this, fastify-autoload will force developers to use two different export methods, depending if or not the plugin will be autoloaded by fastify-autoload.
The plugin.autoConfig
, when declared on plugin.default.autoConfig
is added to the options and passed to the plugin.
I was following @mcollina tutorial for Fastify, and I faced with an error related to fastify-autoload plugin:
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:781:11)
at Loader.resolve (internal/modules/esm/loader.js:85:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:229:28)
at Loader.import (internal/modules/esm/loader.js:164:28)
at importModuleDynamically (internal/modules/cjs/loader.js:1199:27)
at exports.importModuleDynamicallyCallback (internal/process/esm_loader.js:30:14)
at loadPlugin (C:\Users\amis\Desktop\fastify3-test\node_modules\fastify-autoload\index.js:117:5)
at C:\Users\amis\Desktop\fastify3-test\node_modules\fastify-autoload\index.js:27:12
at Array.map (<anonymous>)
at fastifyAutoload (C:\Users\amis\Desktop\fastify3-test\node_modules\fastify-autoload\index.js:26:29) {
code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'
}
I'm running Node v14.7.0 on Windows 10.
This is how the app looks like:
import fastify from 'fastify'
import autoload from 'fastify-autoload'
import { join } from 'desm'
export default function (opts) {
const app = fastify(opts)
app.register(autoload, {
dir: join(import.meta.url, 'routes')
})
return app
}
export default async function (app) {
app.get('/', async function (req, rep) {
return { hello: 'world' }
})
}
I'm using this plugin to load plugins from 2 different directories. Plugins and routes. One of the plugins calls setErrorHandler
. the routes set attachValidation: true
, but the error handler is never passed back an validation information
I can tell that is is a validation error based on the message, but the actual validation errors are never attached
Error: account is required!
at Object.$main (eval at build (/home/esatterwhite/dev/logdna/accounts-service/node_modules/fast-json-stringify/index.js:149:20), <anonymous>:133:15)
at serialize (/home/esatterwhite/dev/logdna/accounts-service/node_modules/fastify/lib/validation.js:132:41)
at preserializeHookEnd (/home/esatterwhite/dev/logdna/accounts-service/node_modules/fastify/lib/reply.js:306:15)
at preserializeHook (/home/esatterwhite/dev/logdna/accounts-service/node_modules/fastify/lib/reply.js:293:5)
at _Reply.Reply.send (/home/esatterwhite/dev/logdna/accounts-service/node_modules/fastify/lib/reply.js:146:7)
at /home/esatterwhite/dev/logdna/accounts-service/node_modules/fastify/lib/wrapThenable.js:27:15
at processTicksAndRejections (internal/process/task_queues.js:97:5)
βββ plugins
βΒ Β βββ health-check.js
βΒ Β βββ http-404.js
βΒ Β βββ http-error.js
βΒ Β βββ load-fastify-schema.js
βΒ Β βββ route-map.js
βΒ Β βββ swagger.js
βββ README.md
βββ routes
βΒ Β βββ v1
βΒ Β βββ account
βΒ Β βββ post-account.js
βββ index.js
const path = require('path')
const fastify = require('fastify')
const Autoload = require('fastify-autoload')
const server = fastify({logger: log})
server.register(AutoLoad, {
dir: path.join(__dirname, 'plugins')
})
server.register(AutoLoad, {
dir: path.join(__dirname, 'routes', 'v1')
, options: {prefix: 'v1/'}
})
module.exports = server
if (require.main === module) {
process.once('SIGTERM', onSignal)
process.once('SIGINT', onSignal)
startup()
.catch(/* istanbul ignore next */(err) => {
server.log.error(err, 'server failed to start')
process.nextTick(() => {
throw err
})
})
}
async function startup() {
await server.ready()
await server.listen(3000)
server.log.debug(server.printRoutes())
}
async function onSignal(signal) {
server.log.info(`system signal received ${signal}`)
try {
await server.close()
} catch (err) {
/* istanbul ignore next */
server.log.error(err, {err})
}
}
const fluent = require('fluent-schema')
module.exports = {
path: '/'
, method: 'POST'
, attachValidation: true
, schema: {
body: fluent
.object()
.prop('status', fluent.string().enum(['trial'])).valueOf()
}
, handler: async (req, res) => {
return {foo: 'bar'}
}
}
'use strict'
const {STATUS_CODES} = require('http')
const plugin = require('fastify-plugin')
const EINTERNAL = 'EINTERNAL'
module.exports = plugin(httpError, {
name: '@answerbook/fastify-http-error'
, fastify: '>=2.0.0'
})
function httpError(fastify, opts, next) {
fastify.setErrorHandler((err, req, res) => {
consol.log('validation', req.validationError)
const log = req.log
const {statusCode = 500} = err
const fn = statusCode >= 500
? log.error.bind(log)
: log.warn.bind(log)
fn(err)
res
.code(statusCode)
.type('application/json')
.send({
message: STATUS_CODES[statusCode]
, code: err.code || EINTERNAL
, status: statusCode
})
})
fastify.log.debug('[plugin]: http-error loaded')
next()
}
Validation errors should be attached to the error or request
When using includeTypeScript: true
, fastify-autload will attempt to load type definition files (.d.ts
), causing syntax errors, such as Cannot use import statement outside a module.
This happens when Node is started into a directory built from TypeScript sources into a set of .js
& .d.ts
files.
Reproduction repository available here:
https://github.com/franky47/fastify-autoload-65
Since Node.js cannot understand type definition files, and they contain no runtime code, I believe the extension .d.ts
should be ignored, even when includeTypeScript
is true.
Allow an option dirNameRoutePrefixing
Default to true
as per current behaviour. When set to false
any index.js files in folders registering routes will not auto prefix routes registration with directory name.
The reason is migration from fastify v2. People will not be expecting routes registered in subfolders to change.
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'routes'),
dirNameRoutePrefixing: false,
options: Object.assign({}, opts)
})
why files other index.js don't work?
I have a list-item.js file and there is a route in the file that has autoload register,
but the route cannot be accessed by the browser and autoload
From the doc:
Each script file within a directory is treated as a plugin unless the directory contains an index file (e.g. index.js). In that case only the index file will be loaded.
In practice this is true only when the directory containing the index.js doesn't include other sub-directories. In this case the others plugins in the parent-directory and in the sub-directories are also loaded.
I don't know if its a bug or if the documentation isn't up-to-date. IMO adding a sub-directory shouldn't change the way the others plugins in the parent directory are handled.
Thanks!
typescript module:
import fp from 'fastify-plugin'
import IFastifyInstance from '@airpay-sz/admin-common/dist/ts/types/IFastifyInstance'
export default fp(
(fastify: IFastifyInstance) => {
fastify.decorate('timestamp', function() {
return Date.now()
})
},
{
name: 'fastify-timestamp'
}
)
tsc to js code
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
exports = fastify_plugin_1.default((fastify) => {
fastify.decorate('timestamp', function () {
return Date.now();
});
}, {
fastify: '>=2.x',
name: 'fastify-timestamp'
});
the js code can't be load by fastify-plugin, because the plugin is an object
Boot.prototype.use = function (plugin, opts) {
if (typeof plugin === 'function') { // the plugin is an object
this._addPlugin(plugin, opts, false)
} else {
throw new Error('plugin must be a function')
}
return this
}
so fastify-autoload module need to update
if (plugin.autoload !== false) {
// need to check the plugin whether or not the function
fastify.register(plugin, pluginOptions)
}
Yes. It doesn't seem to have been reported
Create a new project using fastify-cli and add a new plugin under the plugins directory.
fastify generate new-project
npm test
npm start
Duplicate plugins/support.js and name it as new_support.js. Change the decorated function name to someOtherSupport.
npm test
fails with error "Duplicate plugin: anonymous". However, npm start
does not cause any error.
When running tests, it seems like the plugin name is 'anonymous', but when running the app it takes the name of the file.
Tests should behave same way as application start.
Before the support for subdirectory loading, we only loaded top-level directory index.js
files,
since v3 we have the ability to load automatically from subdirectories.
I saw a PR that would add a recursive
option to configure loading subdirectories or not (#72).
Loading of subdirectories was actually fixed in #76, but I could not find a similar option implemented.
The motivation is for upgrading the autoloader with an existing file structure that was not built for loading plugins recursively.
All our modules are defined at the top-level and we have other (non-fastify) code in there.
Example directory structure:
modules
βββ auth
βΒ Β βββ controller.js
βΒ Β βββ handlers.js
βΒ Β βββ index.js
βΒ Β βββ schemas
βΒ Β βββ index.js
βΒ Β βββ login
βΒ Β βββ register
βββ root.js
This issue here is that it will try to load schemas/index.js
as a Fastify plugin.
I believe the initial proposal of having a recursive
option when setting up the autoloader was a good idea.
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'modules'),
recursive: false
})
Right now we're solving this by having a really big ignorePattern
RegEx but that won't scale very well. π
SyntaxError: Invalid or unexpected token
steed.map (node_modules/fastify-autoload/index.js:41:28)
ResultsHolder.release (node_modules/fastparallel/parallel.js:185:9)
SingleCaller.release (node_modules/fastparallel/parallel.js:157:17)
fs.stat (node_modules/fastify-autoload/index.js:23:9)
Plugins in sub-directories are not respecting dependency chains.
Given the following code/directory tree myPluginFoo
throws an error stating that myPluginBar
has not been registered:
await server.register(autoLoad, {
dir: path.join(__dirname, 'plugins'),
maxDepth: 1,
ignorePattern: /__tests__/,
});
βββ plugins
β βββ myPluginFoo // has a dep on myPluginBar
β β βββ index.js
| βββ myPluginBar.js
Given the following code with a bit of a shim, dependencies work as expected (note we're disabling maxDepth
):
await server.register(autoLoad, {
dir: path.join(__dirname, 'plugins'),
maxDepth: 0,
ignorePattern: /__tests__/,
});
// myFooShim.js
export { default } from './myPluginFoo
βββ plugins
β βββ myPluginFoo // has a dep on myPluginBar
β | βββ index.js
| βββ myFooShim.js
| βββ myPluginBar.js
This regression was highlighted during an upgrade from fastify-autoload
3.3 -> 3.5.0
12.7.0
to 12.7.1
.π¨ View failing branch.
This version is covered by your current version range and after updating it in your project the build failed.
@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
Node 12 has landed EcmaScript Modules support in a shape that would resemble the final result. IMHO itβs time to test this module and make sure that we can load native .mjs files.
We might need to refactor certain parts, but I think itβs worthwhile - we can also use this to open issue against Node core and provide feedbacks on modules themselves.
I can't commit changes since tests are failing on master
.
HEAD is now at fee5f88 update package (#53)
Sites/fastify-autoload [master] Β» npm run test
> [email protected] test /Users/patrick/Sites/fastify-autoload
> standard | snazzy && tap test/*.js && npm run typescript
test/basic.js ....................................... 47/47
test/dependency.js .................................. 22/22
test/error.js ......................................... 1/2
not ok should match pattern provided
found: >-
Unexpected token '}' at
/Users/patrick/Sites/fastify-autoload/test/error/lib/a.js:6
pattern: '/Unexpected token \} at .*\/test\/error\/lib\/a.js:6/'
at:
line: 14
column: 5
file: test/error.js
stack: |
test/error.js:14:5
Object._encapsulateThreeParam (node_modules/avvio/boot.js:408:13)
Boot.callWithCbOrNextTick (node_modules/avvio/boot.js:339:5)
release (node_modules/fastq/queue.js:127:16)
Object.resume (node_modules/fastq/queue.js:61:7)
node_modules/avvio/boot.js:155:20
node_modules/avvio/plugin.js:178:7
done (node_modules/avvio/plugin.js:136:5)
check (node_modules/avvio/plugin.js:147:7)
source: |
t.match(err.message, /Unexpected token \} at .*\/test\/error\/lib\/a.js:6/)
total ............................................... 70/71
70 passing (2s)
1 failing
Tests should pass.
According to the docs routes in folders will be prefixed with the folder name automatically. I can't confirm this behavior with fastify 2.7.1 and fastify-autoload 1.0.0
Hi there,
I use predefined template generated by fastify-cli
, and I want to add fastify-cors
via fastify-autoload
situated in plugins
folder, but have no idea how to do it in right way :(.
Can you share the example how to do it?
when using fastify-autoload with router in the root directory with no path fastify.get('/')
and prefix option
app.js
server.register(autoload, {
dir: path.join(__dirname, 'dir'),
options: { prefix: 'v1/' }
})
dir/index.js
module.exports = async (server, opts) => {
server.get('/', async (req, reply) => {
reply.send({ works: true })
})
}
register only
/v1 /v1/
Reference: #100
We discover that our tests not cover some tools, so, is important to create tests that cover ts-node
and ts-node-dev
tool.
It would be really handy to be able to set a few lifecycle hooks for each folder. This would be really handy to add authentication for a specific folder folder for example.
Say we have plugin-a
& plugin-b
in ./plugins
directory. And plugin-b
is added as a dependencies
in plugin-a
.
With this an error is thrown, because plugin-a
is getting loaded before the plugin-b
. This happens due to the plugin files being read in the alphabetic order.
It would be good if fastify-autoload
is smart enough to load the plugins in order they're being used.
Unfortunately they both break the tests, could somebody from @fastify/typescript take a look?
2.19.0
to 2.19.1
.π¨ View failing branch.
This version is covered by your current version range and after updating it in your project the build failed.
@typescript-eslint/eslint-plugin is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
The new version differs by 5 commits.
1c8f0df
chore: publish v2.19.1
4c12dac
fix(typescript-estree): ts returning wrong file with project references (#1575)
e9cf734
docs(eslint-plugin): fix typo in readme
10d86b1
docs(eslint-plugin): [no-dupe-class-members] fix typo (#1566)
4670aab
fix(eslint-plugin): [unbound-method] blacklist a few unbound natives (#1562)
See the full diff
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
So this plugin are creating a decorators name based on folders but. what if I want the nested decorators?
are there any options?
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'models'),
options: Object.assign({}, opts)
})
directory
models/
βββ pets/
β βββ index.js
βββ users/
β βββ index.js
and can access it with. fastify.models.pets
? can I do that ? Or i just create the decorator and then
fastify.decorate('conf', {
users: theServiceUsers,
pets: theServicePets,
})
Especially when using typescript, some end up running fastify through a bundler and treeshaking etc. It would be nice if some method was exposed to resolve everything immediately so that it can also be run through the bundler too.
Currently, using a bundler with fastify-autoload results in either not bundling the autoloaded routes or having to do a bunch of otherwise unnecessary internal virtual module resolution.
import autoLoad from 'fastify-autoload'
export default const resolved = autoLoad.resolve(options)
In Fastify-Autoload 1.x jest tests + typescript worked with fastify-autoload with seemingly no issue as long as the includeTypescript: true
configuration was passed. With the new version it appears that has been removed in favor of automatically supporting ts-node. I don't 100% know everything about ts-jest but I do not believe it uses ts-node and yet it worked before. It seems like this should still work.
Steps to reproduce the behavior:
clone this repo - https://github.com/wolfejw86/fastify-typescript-starter
run npm install
run npm run test
see that fasitify-autoload is working correctly in https://github.com/wolfejw86/fastify-typescript-starter/blob/master/src/app.ts
In the same repo - upgrade fastify-swagger, fastify, fastify-plugin, and fastify-autoload all to the latest version by switching to the branch in progress(the 3.0 migration for fastify + typescript).
git checkout fastify-upgrade
npm install
npm run test
Notice fastify-autoload will no longer load any plugins.
fastify-autoload cannot import plugin at '/Users/johnwolfe/Desktop/repositories/fastify-typescript-starter/src/plugins/globalErrorHandler.ts'. To fix this error compile TypeScript to JavaScript or use 'ts-node' to run your app.
at findPlugins (node_modules/fastify-autoload/index.js:87:15)
at fastifyAutoload (node_modules/fastify-autoload/index.js:19:19)
Edit:
Additionally if I hardcode this line:
It mostly works, but doesn't load an EDIT: it works fine - I did not correctly understand the new behavior of how autoload plugin handles nested foldersindex.ts
file in the services folder from:
I am waiting for EDIT: It loads all modules correctly according to how Autoload uses nested folders as pathnames now.fastify.ready()
but it seems like it's firing before the second call to the autoload plugin has finished resolving or something.
Any help is appreciated :)
A way to define plugins as objects.
Less code to write for simple plugins, smaller, compact format when it makes sense.
export default {
decorate: {
helper () {
console.log('helper')
}
},
decorateRequest: {
$placeholder: null
},
async onRequest (req) {
req.$placeholder = 'something'
},
}
With fastify-plugin
:
export default {
encapsulate: true,
decorate: {
helper () {
console.log('helper')
}
},
decorateRequest: {
$placeholder: null
},
async onRequest (req) {
req.$placeholder = 'something'
},
}
support a filter options which could be just a func which helps exclude or include specified plugins
Line 124 in 67d78db
Hello, dependencies loading are not respected because it seems that plugin[Symbol.for('plugin-meta')]
is always undefined
.
To create my plugins I'm using [email protected]
.
For instance when I print plugin
in some of my code I get:
{
default: [Function: connectDynamoDB] {
[Symbol(skip-override)]: true,
[Symbol(fastify.display-name)]: 'dynamodb-connector',
[Symbol(plugin-meta)]: {
name: 'dynamodb-connector',
fastify: '2.x',
decorators: [Object],
dependencies: [Array]
}
}
}
Therefore I believe we should change to const pluginMeta = plugin.default[Symbol.for('plugin-meta')] || {}
.
Does it make sense to fix this and publish a v1.2.3
?
Although, I'm not sure it is still possible (cc. @mcollina).
To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:
.travis.yml
If youβre interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.
Greenkeeper has checked the engines
key in any package.json
file, the .nvmrc
file, and the .travis.yml
file, if present.
engines
was only updated if it defined a single version, not a range..nvmrc
was updated to Node.js 10.travis.yml
was only changed if there was a root-level node_js
that didnβt already include Node.js 10, such as node
or lts/*
. In this case, the new version was appended to the list. We didnβt touch job or matrix configurations because these tend to be quite specific and complex, and itβs difficult to infer what the intentions were.For many simpler .travis.yml
configurations, this PR should suffice as-is, but depending on what youβre doing it may require additional work or may not be applicable at all. Weβre also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, Iβm a humble robot and wonβt feel rejected π€
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
Add the ability to customize the order in which fastify-autoload registers plugins, plugins
can export an additional property called priority
.
module.exports = async function () {}
module.exports.priority = 'plugin'
autoload will then sort all the plugins based on their priority and register them, the plugins should be sorted like:
plugin
decorator
hook
service
similar to how fastify docs recommends how to order the register calls to load your plugins.
This would make fastify-autoload more developer friendly.
For example we have the following few plugins:
shared/constants.js
const fp = require('fastify-plugin')
async function constants () {
// .....
}
module.exports = fp(constants)
module.exports.priority = 'decorator'
shared/authHooks.js
const fp = require('fastify-plugin')
async function authHooks () {
// ....
}
module.exports = fp(authHook)
module.exports.priority = 'hook'
app.js
const path = require('path')
const Fastify = require('fastify')
const autoload = require('autoload')
const app = Fastify({ logger: false })
app.register(autoload, { dir: path.join(__dirname, 'shared') })
app.listen(8080)
Here autoload will always register the decorator plugin before the hooks plugin.
This file contains the routes.
module.exports = function (app, options, done) {
app.get('/users', (request, reply) => {
reply.send({ data: 'users' })
})
done()
}
app.register(autoload, {
dir: path.join(__dirname, 'projects'),
dirNameRoutePrefix: false,
options: {
prefix: '/projects/:id'
}
})
/projects/:id//users
There are two //
before users
.
This is happening because the index.js
file is in subfolder xyz
. I have tested it by creating one more subfolder inside xyz
and put index.js
file inside it. The url i get then /projects/:id///users
. This time three /
.
If I set dirNameRoutePrefix: true
then I do not get extra /
but then it add the folder name in url that i do not want.
/projects/:id/users
Given the tree:
Only the file a
is loaded and the other directories are ignored
In this example, I would register
every folder and put all the files in the same context.
This lets the user organize the application in a more flexible structure where the URLs (except some prefix-override) is mapped to the project tree
fastify.register(require('fastify-autoload'), {
dir: x,
recursive: true // as rm -rf π
})
We're migrating an API to fastify and somehow the boilerplate
module.exports = function (fastify, opts, next) {
fastify.route({
method: 'GET',
url: '/',
handler
})
}
feels a bit clunky. I'd like to propose just the route content in a file:
module.exports = {
method: 'GET',
url: '/',
handler
}
For most cases this is totally sufficient. If additional config/options are required, a regular plugin/route function can be exported.
As mentioned above, the plugin structure feels a bit clunky in each and every file.
The default type is a function and the new proposal would be an object (method is always required anyway), so I'm thinking somewhere along the lines of (https://github.com/fastify/fastify-autoload/blob/master/index.js#L110):
const content = require(file)
let plugin
if (content && typeof content === 'object' && content.method) {
plugin = function (fastify, opts, next) {
fastify.route(content)
next()
}
} else {
plugin = content
}
This is non-breaking, but to be safe it could also be flagged with an new option "wrapRoutes" or something like that.
I'm testing this locally, but I'm currently getting an error when running npm test
?
test/error.js ......................................... 1/2
not ok should match pattern provided
found: >-
Unexpected token '}' at
/Users/patrick/Sites/fastify-autoload/test/error/lib/a.js:6
pattern: '/Unexpected token \} at .*\/test\/error\/lib\/a.js:6/'
at:
line: 14
column: 5
file: test/error.js
stack: |
test/error.js:14:5
Object._encapsulateThreeParam (node_modules/avvio/boot.js:408:13)
Boot.callWithCbOrNextTick (node_modules/avvio/boot.js:339:5)
release (node_modules/fastq/queue.js:127:16)
Object.resume (node_modules/fastq/queue.js:61:7)
node_modules/avvio/boot.js:155:20
node_modules/avvio/plugin.js:178:7
done (node_modules/avvio/plugin.js:136:5)
check (node_modules/avvio/plugin.js:147:7)
source: |
t.match(err.message, /Unexpected token \} at .*\/test\/error\/lib\/a.js:6/)
In npm 7, environment variables like npm_package_devDependencies*
environment variables are no longer present, and so this check that fastify-autoload performs to determine whether ts-jest is present is no longer working.
Would it be possible to expose typescriptSupport
as a configuration option, so that there's an escape hatch in circumstances where detection does not work?
npm run typescript:jest
in this packageThe tests should pass, but instead, the same error described in this issue occurs.
I upgraded from version 3.4.2 to 3.5.0 and influenced the operation of other plugins.
This is my structure:
https://github.com/YuriFontella/fastify-api
Branch | Build failing π¨ |
---|---|
Dependency | standard |
Current Version | 12.0.0 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
standard is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
The new version differs by 8 commits.
6e28e31
authors
b8741d0
12.0.1
7839edf
changelog
523c15e
Merge pull request #1190 from Gerhut/patch-1
9ee4d0f
Silently pass in node 4
e1560df
fix readme translation links
5fc2231
fix changelog
0a910f2
lock config versions
See the full diff
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.