profile
viewpoint
Matteo Collina mcollina @nearform In the clouds above Italy Technical Director @nearform, TSC member @nodejs, IoT Expert, Conference Speaker, Ph.D.

davidmarkclements/0x 1748

🔥 single-command flamegraph profiling 🔥

delvedor/find-my-way 605

A crazy fast HTTP router

davidmarkclements/v8-perf 248

Exploring v8 performance characteristics in Node across v8 versions 5.1, 5.8, 5.9, 6.0 and 6.1

davidmarkclements/fast-safe-stringify 190

Safely and quickly serialize JavaScript objects

davidmarkclements/overload-protection 159

Load detection and shedding capabilities for http, express, restify and koa

davidmarkclements/fast-redact 131

very fast object redaction

andreareginato/conference_site 24

A conference site that can be used for your next big event

davidmarkclements/proffer 11

Realtime V8 Tick Profiler

starteddavidedantonio/fastify-axios

started time in 11 hours

issue commentnodejs/node

Disable __proto__

cc @nodejs/tsc @nodejs/security @nodejs/v8

mcollina

comment created time in 11 hours

issue openednodejs/node

Disable __proto__

There have been quite a few CVE related to __proto__ in the last while. I think it would be good to have a flag to enable/disable it.

A quick example:

const payload = '{"__proto__": null}'
const a = {}
console.log("Before : " + a) // this works
Object.assign(a, JSON.parse(payload))
console.log("After : " + a) // this crashes

(It's not strictly related to JSON, as it can also apply to multipart data or other serialization format).

Some vulnerabilities:

  • https://www.npmjs.com/advisories/1480
  • https://snyk.io/vuln/npm:hoek:20180212
  • https://www.npmjs.com/advisories/577
  • (There are probably way more)

I don't know if this is fixable / manageable on our side (vs V8), but __proto__ still causes significant vulnerabilities.


Note that there are some modules to help with this, including https://github.com/hapijs/bourne.

created time in 11 hours

pull request commentmcollina/avvio

Actually rejects when await app.after() or await app.register()

This is needed to solve https://github.com/fastify/fastify/pull/2114.

mcollina

comment created time in 14 hours

pull request commentmcollina/avvio

Actually rejects when await app.after() or await app.register()

cc @Eomm please check

mcollina

comment created time in 14 hours

PR opened mcollina/avvio

Reviewers
Actually rejects when await app.after() or await app.register()

In #95, I thought I did this. Turns out I was missing a critical change, this is it.

+59 -44

0 comment

4 changed files

pr created time in 14 hours

create barnchmcollina/avvio

branch : fix-nested-error

created branch time in 14 hours

issue openedfastify/fastify

Add docs for explaining the concept of object shapes

Using the decorator defines the shape of request objects. See https://mathiasbynens.be/notes/shapes-ics

Originally posted by @jsumners in https://github.com/fastify/fastify/issues/2115#issuecomment-590562376

created time in 15 hours

issue commentmcollina/cloneable-readable

How to pass a cloned stream to multiple functions that return a promise

You can clone a stream before it starts. Create all your clones and pass them around, they will all start at the same time.

kaykhan

comment created time in 15 hours

pull request commentmoscajs/aedes-persistence

Upgrade github checkout actions & support node>=8

let’s do that

gnought

comment created time in 15 hours

Pull request review commentfastify/fastify

Bumped avvio to 7.0.0-alpha.1

 test('awaitable register and after', async t => {  test('awaitable after error handling', async t => {   const fastify = Fastify()-  let first = false-  let second = false-  let third = false -  // Note that this does not throw in case of error,-  // all errors are currently collected to ready() because it's-  // not really possible to do anything about them.-  await fastify.register(async (instance, opts, next) => {-    first = true-    throw new Error('kaboom')+  const e = new Error('kaboom')++  // TODO this should throw for some reason, and it's not.+  await fastify.register(async (instance, opts) => {+    throw e   })-  t.is(first, true) -  fastify.register(async (instance, opts, next) => {-    second = true+  fastify.register(async (instance, opts) => {+    t.fail('should not be executed')

you need a npm install, it’s a fixed dependency update

mcollina

comment created time in 16 hours

issue closedmcollina/cloneable-readable

How to pass a cloned stream to multiple functions that return a promise

I have a stream which is an image. I want to upload the image to s3 and also upload the image to a different third party service.

describe("StorageModule", () => {

    let stream;
 
    it("should upload file to s3", async () => {

        const s3storageModule = new StorageModule();

        imageStream = cloneable(fs.createReadStream(process.cwd() + "/test/resources/" + "id/front.jpg"));

        const response = await s3storageModule.upload(key, imageStream.clone());

        expect(response.Location).to.equal(`${s3BaseUrl}/${key}`)

    });


    it("should submit image to 3rd party", async () => {

        const response = await sessionServie.document(imageStream.clone());
        expect(response.status).equal(202);

    });
});

Above i have 2 test cases the first submits the stream to s3 and the second submits a clone of the stream to the third party service that returns a promise.

However the second test fails with

Error: already started at Cloneable.clone (node_modules/cloneable-readable/index.js:48:11)

closed time in 17 hours

kaykhan

issue commentmcollina/cloneable-readable

How to pass a cloned stream to multiple functions that return a promise

That will not be possible as the stream is already consumed when the first test finishes. If you want to do something like that, the two test would have to be executed in parallel.

kaykhan

comment created time in 17 hours

Pull request review commentpinojs/pino

Add serializers for core log components

 const wildcardFirstSym = Symbol('pino.wildcardFirst') // public symbols, no need to use the same pino // version for these const serializersSym = Symbol.for('pino.serializers')-const wildcardGsym = Symbol.for('pino.*')

I would use https://nodejs.org/api/util.html#util_util_deprecate_fn_msg_code.

See https://github.com/pinojs/pino/commit/bcaacba70c232986253c4f1888ca64a695f36749#diff-04e6fb630166e65e0231f8c63a731aa0L425.

delvedor

comment created time in 18 hours

pull request commentmoscajs/aedes

WIP: Replace websocket-stream with ws

Decoding of PROXY must happen before decoding the websocket protocol. From my understanding the approach @gnought is suggesting will not work with the most common proxies (haproxy for example).

robertsLando

comment created time in 20 hours

issue commentfastify/fastify

FST_ERR_DEC_ALREADY_PRESENT: The decorator 'xxx' has already been added!

@jsumners we should really link that from the docs.

wiredmartian

comment created time in 21 hours

Pull request review commentmqttjs/MQTT.js

chore: migration from Travis CI to Github Actions

+name: Node.js CI++on: [push]

this needs to be on pr as well.

YoDaMa

comment created time in a day

pull request commentfastify/fastify

fix: make .register() compatible with eslint rule

We recommend to use a linter.

Disabling no-misused-promise rule?

That's my recommendation yes.

jeiea

comment created time in a day

pull request commentmqttjs/MQTT.js

feat: connection error handler

I don't know why Travis is not working anymore here. I would recommend moving to Github actions.

YoDaMa

comment created time in a day

Pull request review commentmqttjs/MQTT.js

feat: support SNI on TLS

 describe('MqttSecureClient', function () {         done()       })     })++    it.only('should support SNI on the TLS connection', function (done) {

This should not have landed as it has a only still in the tests.

YoDaMa

comment created time in a day

issue closedfastify/fastify

FST_ERR_DEC_ALREADY_PRESENT: The decorator 'xxx' has already been added!

I'm trying to decorate a request with the current user's data from the jwt auth token;

server.addHook("preHandler", async (request, reply, done) => {
    let { userId, email } = await request.jwtVerify();
    userId = AESEncryption.decrypt(userId);
    server.decorateRequest("currentUser", {
        userId: userId,
        email: email
    });
    done();
});

PROBLEM

The first request GET works, but when I make the same request again, I get this error:

{
    "statusCode": 500,
    "code": "FST_ERR_DEC_ALREADY_PRESENT",
    "error": "Internal Server Error",
    "message": "FST_ERR_DEC_ALREADY_PRESENT: The decorator 'currentUser' has already been added!"
}

Environments node version: 11.15 fastify version: 2.11 os: Linux

closed time in a day

wiredmartian

issue openedfastify/fastify

Make decorate* methods throw after server is started.

🚀 Feature Proposal

In https://github.com/fastify/fastify/issues/2115, the reporter is trying to decorate the global request object within a route. This is not supported by Fastify, and we should throw if server.decorate(), server.decorateRequest() or server.decorateReply() are called after .ready().

created time in a day

PR opened fastify/fastify

Reviewers
Bumped avvio to 7.0.0-alpha.1

Updated, and it still shows some bugs in Avvio.

+10 -18

0 comment

2 changed files

pr created time in a day

create barnchfastify/fastify

branch : avvio-alpha-7.0.0-alpha.1

created branch time in a day

pull request commentfastify/fastify

Validation and serialization

Can you please update the PR description to match the current status of this PR? I'd also like to see a migration guide.

Eomm

comment created time in a day

issue commentnodejs/TSC

Node.js Technical Steering Committee (TSC) Meeting 2020-02-26

I'd like to invite @lpinca to talk about https://github.com/nodejs/node/issues/31317.

mhdawson

comment created time in a day

Pull request review commentpinojs/pino

Add serializers for core log components

 function child (bindings) {       instance[serializersSym][bks] = bindings.serializers[bks]     }   } else instance[serializersSym] = serializers+  if (bindings.hasOwnProperty('formatters')) {+    instance[formattersSym] = {+      level: bindings.formatters.level || formatters.level,+      bindings: bindings.formatters.bindings || resetChildingsFormatter,+      log: bindings.formatters.log || formatters.log+    }+  } else {+    instance[formattersSym] = {+      level: formatters.level,+      bindings: resetChildingsFormatter,+      log: formatters.log+    }

Instead of creating two objects at two separate lines, could you wrap them in a single factory? It would help in them having the same shape.

delvedor

comment created time in 2 days

Pull request review commentpinojs/pino

Add serializers for core log components

 test('produces labels for custom levels', async ({ is }) => { test('setting changeLevelName does not affect labels when told to', async ({ is }) => {   const instance = pino(     {-      useLevelLabels: true,-      changeLevelName: 'priority'

Can we keep supporting the changeLevelName in the default formatter with a deprecation warning?

delvedor

comment created time in 2 days

Pull request review commentpinojs/pino

Add serializers for core log components

 const wildcardFirstSym = Symbol('pino.wildcardFirst') // public symbols, no need to use the same pino // version for these const serializersSym = Symbol.for('pino.serializers')-const wildcardGsym = Symbol.for('pino.*')

I would like to retain support of the wildcard symbol and deprecate it.

delvedor

comment created time in 2 days

pull request commentnearform/fastify-auth0-verify

Update example in README.md

Thanks!

mattmazzola

comment created time in 2 days

push eventnearform/fastify-auth0-verify

Matt Mazzola

commit sha f2f782d40a465df98efbaa1c8f3892ec39883f7c

Update README.md (#6) I was trying to use this package but the example given seems wrong. It says: > Register as a plugin, providing one or more of the following options But I didn't see where those options where provided. Perhaps they were Environment variables. Anyways, I think it would be clearer if they were added as shown above.

view details

push time in 2 days

PR merged nearform/fastify-auth0-verify

Update example in README.md

I was trying to use this package but the example given seems wrong. It says:

Register as a plugin, providing one or more of the following options

But I didn't see where those options where provided. Perhaps they were Environment variables.

Anyways, I think it would be clearer if they were explicitly added as shown above. Then consumer can change them to environment variables. Maybe it works in different way I didn't understand.

+4 -1

0 comment

1 changed file

mattmazzola

pr closed time in 2 days

Pull request review commentnearform/trail

Fastify support

+'use strict'++const fp = require('fastify-plugin')+const { TrailsManager } = require('@nearform/trail-core')+const { get } = require('lodash')+const Ajv = require('ajv')++const { errorsMessages } = require('./schemas/errors')++const environment = get(process, 'env.NODE_ENV', 'development')++function getCustomErrorMessage (schema, path, message) {+  // Convert a schema path like '#/properties/who/anyOf' to a ref addressing+  // the custom error type, e.g. 'properties.who.meta.errorType'+  const ref = path+    .substring(path.indexOf('/') + 1, path.lastIndexOf('/'))+    .replace(/\//g, '.')+    .concat('.meta.errorType')+  const errorType = get(schema, ref)+  return errorType ? errorsMessages[errorType] : message+}++function formatReasons (error, schema) {+  const { validation } = error+  return validation.reduce((reasons, item) => {+    const {+      dataPath,+      schemaPath,+      keyword,+      message,+      params+    } = item+    const name = dataPath.slice(1)+    switch (keyword) {+      case 'required':+        if (!schemaPath.includes('anyOf')) {+          reasons[params.missingProperty] = errorsMessages['any.required']+        }+        break+      case 'additionalProperties':+        reasons[params.additionalProperty] = errorsMessages['object.unknown']+        break+      default:+        reasons[name] = getCustomErrorMessage(schema, schemaPath, message)+    }+    return reasons+  }, {})+}++const formatStack = error => get(error, 'stack', '')+  .split('\n')+  .filter((s, i) => i > 0)+  .map(s => s.trim().replace(/^at /, ''))++const validationContextMessages = {+  querystring: 'Invalid input data.',+  body: 'Invalid input data.'+}++function formatValidationErrorResponse (error, context) {+  const { validationContext } = error+  const schema = context.schema[validationContext]+  return {+    statusCode: 422,+    error: 'Unprocessable Entity',+    message: validationContextMessages[validationContext],+    reasons: formatReasons(error, schema)+  }+}++async function trail (server, options) {+  const trailsManager = new TrailsManager(undefined, options.pool)++  server.decorate('trailCore', trailsManager)+  server.decorateReply('trailCore', trailsManager)++  server.addHook('onClose', async instance => {+    await trailsManager.close()+  })++  const ajv = new Ajv({ allErrors: true })++  server.schemaCompiler = schema => {+    const spec = typeof schema.valueOf === 'function' ? schema.valueOf() : schema+    return ajv.compile(spec)+  }++  server.setErrorHandler((error, request, reply) => {+    if (error.validation) {+      const response = formatValidationErrorResponse(error, reply.context)+      return reply.code(response.statusCode).send(response)+    }++    const code = error.isBoom ? error.output.statusCode : (error.statusCode || 500)++    if (error.message === 'Unexpected end of JSON input') { // Body was an invalid JSON+      error = {+        statusCode: 400,+        error: 'Bad Request',+        message: errorsMessages['json.format']+      }+    } else if (code === 500) { // Add the stack+      const stack = environment !== 'production' ? formatStack(error) : undefined+      error = {+        statusCode: 500,+        error: 'Internal Server Error',+        message: `[${error.code || error.name}] ${error.message}`,+        stack+      }+    }+    reply.code(code).send(error)+  })++  await server.register(require('./routes/trails'))+}++module.exports = fp(trail, { name: 'trail-fastify-plugin' })

I don't think you need fp here.

juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { get } = require('lodash')

Have you tried looking into https://github.com/fastify/fastify-swagger instead?

juliangoacher

comment created time in 2 days

created tagfastify/fastify-plugin

tagv1.6.1

Plugin helper for Fastify

created time in 2 days

release fastify/fastify-plugin

v1.6.1

released time in 2 days

push eventfastify/fastify-plugin

Matteo Collina

commit sha b9a7ede1ccc61006d47bfa5b9670be6ad2645876

Bumped v1.6.1

view details

push time in 2 days

push eventfastify/fastify-plugin

Matteo Collina

commit sha df58357135c6c230536b67a4727c0f40b0530d83

Updated deps

view details

push time in 2 days

delete branch fastify/fastify-plugin

delete branch : error-name

delete time in 2 days

push eventfastify/fastify-plugin

Manuel Spigolon

commit sha 03cdeeec6de3c3c5f4b2287eb612068d9a7d8acb

Error name (#84) * Update index.js * fix tests * fix code * fix options null

view details

push time in 2 days

PR merged fastify/fastify-plugin

Error name

FIxes #83

Is this a major due to the error output?

Checklist

  • [x] run npm run test and npm run benchmark
  • [x] tests and/or benchmarks are included
  • [ ] documentation is changed or added
  • [x] commit message and code follows Code of conduct
+25 -7

0 comment

2 changed files

Eomm

pr closed time in 2 days

issue closedfastify/fastify-plugin

Better error output

🚀 Feature Proposal

Add the plugin name to the output of the errors

Motivation

Right now if a module need a fastify version the error is this one:

Error: fastify-plugin - expected '<2.12.0' fastify version, '2.12.0' is installed

But I don't know which plugin is throwing the error

Example

Error: fastify-module-name - expected '<2.12.0' fastify version, '2.12.0' is installed

closed time in 2 days

Eomm

pull request commentnearform/trail

Fastify support

CI is failing, would you mind you fixing it?

juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { get } = require('lodash')

use strict is missing.

What's this file purpose, I'm a bit lost.

juliangoacher

comment created time in 2 days

push eventfastify/fastify

Mohamed Akram

commit sha 093947b75dfbb5da784c3714550d4d7ecf9a340f

http2: fix req.hostname not set (#2113) * http2: fix req.hostname not set * Update lib/route.js Co-Authored-By: Matteo Collina <matteo.collina@gmail.com> Co-authored-by: Matteo Collina <matteo.collina@gmail.com>

view details

push time in 2 days

PR merged fastify/fastify

http2: fix req.hostname not set

Fixes #2112

Checklist

  • [x] run npm run test and npm run benchmark
  • [x] tests and/or benchmarks are included
  • [x] commit message and code follows Code of conduct
+16 -1

0 comment

2 changed files

mohd-akram

pr closed time in 2 days

issue closedfastify/fastify

request.hostname isn't set when using HTTP2

🐛 Bug Report

request.hostname isn't set when using HTTP2.

To Reproduce

index.js:

module.exports = async function (fastify, opts) {
  fastify.get('/', async (req, r) => r.send(`hostname: ${req.hostname}\n`));
};
module.exports.options = { http2: true };

Expected behavior

Running fastify start -o index.js and curl --http2-prior-knowledge http://localhost:3000 gives:

hostname: localhost:3000

Actual behavior

hostname: undefined

Your Environment

  • node version: v13.9.0
  • fastify version: 2.11.0
  • os: Windows

closed time in 2 days

mohd-akram

pull request commentnearform/trail

Fastify support

The Fastify plugin uses the exact same unit tests as the Hapi plugin, except for one unit test for invalid HTTP headers.

How are those hooked up? Can you send a couple of links?

juliangoacher

comment created time in 2 days

Pull request review commentfastify/fastify

http2: fix req.hostname not set

 function buildRouting (options) {      req.id = req.headers[requestIdHeader] || genReqId(req)     req.originalUrl = req.url-    var hostname = req.headers.host+    var hostname = req.headers[':authority'] || req.headers.host

Would you mind to invert those?

    var hostname = req.headers.host || req.headers[':authority']
mohd-akram

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { notFound } = require('@hapi/boom')+const S = require('fluent-schema')++const { errorsSchemas } = require('../schemas/errors')+const { spec, trailSchema } = require('../schemas/trails')+const { addApiRoute, generateSpec } = require('../api')++module.exports = async function (fastify, options, done) {+  for (const path of ['/trails/openapi.json', '/trails/swagger.json']) {+    fastify.route({+      method: 'GET',+      path,+      handler (request, reply) {+        return reply.send(spec)+      }+    })+  }++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails',+    async handler (request, reply) {+      const { from, to, who, what, subject, page, pageSize, sort } = request.query+      const results = await reply.trailCore.search({ from, to, who, what, subject, page, pageSize, sort })+      reply.send(results)+    },+    schema: {+      query: trailSchema.search,+      response: {+        200: S.array()+          .description('The search results.')+          .items(trailSchema.response),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Search audit trails.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/enumerate',+    async handler (request, reply) {+      const { from, to, type, page, pageSize, desc } = request.query+      const results = await reply.trailCore.enumerate({ from, to, type, page, pageSize, desc })+      reply.send(results)+    },+    schema: {+      query: trailSchema.enumerate,+      response: {+        200: S.array()+          .description('The enumeration results.')+          .items(S.string().description('A trail who, what or subject id')),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Enumerate audit trails ids.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'POST',+    path: '/trails',+    async handler (request, reply) {+      const id = await reply.trailCore.insert(request.body)+      const trail = await reply.trailCore.get(id)+      reply.code(201).send(trail)+    },+    schema: {+      headers: S.object()+        .additionalProperties(true)+        .prop('content-type', S.string().const('application/json')),+      body: trailSchema.request,+      response: {+        201: trailSchema.response.description('The newly created audit trail.'),+        400: errorsSchemas['400'],+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Create a new audit trail.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/:id',+    async handler (request, reply) {+      const { id } = request.params+      const trail = await reply.trailCore.get(id)++      if (!trail) throw notFound(`Trail with id ${id} not found.`)++      return reply.send(trail)+    },+    schema: {+      params: trailSchema.params,+      response: {+        200: trailSchema.response.description('The requested audit trail.'),+        400: errorsSchemas['400'],+        404: errorsSchemas['404'],+        500: errorsSchemas['500']+      }+    },+    config: {+      auth: false,+      description: 'Get a audit trail.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'PUT',+    path: '/trails/:id',+    async handler (request, reply) {+      const { id } = request.params+      const updated = await reply.trailCore.update(id, request.body)++      if (!updated) throw notFound(`Trail with id ${id} not found.`)++      const trail = await reply.trailCore.get(id)+      reply.code(202).send(trail)+    },+    schema: {+      headers: S.object()+        .prop('content-type', S.string().const('application/json'))+        .additionalProperties(true),+      params: trailSchema.params,+      body: trailSchema.request,+      response: {+        202: trailSchema.response.description('The updated audit trail.'),+        400: errorsSchemas['400'],+        404: errorsSchemas['404'],+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      auth: false,+      description: 'Update a audit trail.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'DELETE',+    path: '/trails/:id',+    async handler (request, reply) {+      const { id } = request.params+      const deleted = await reply.trailCore.delete(id)++      if (!deleted) throw notFound(`Trail with id ${id} not found.`)++      reply.code(204).send()+    },+    schema: {+      params: trailSchema.params,+      response: {+        204: S.object().maxProperties(0).description('The trail has been deleted successfully.'),+        400: errorsSchemas['400'],+        404: errorsSchemas['404'],+        500: errorsSchemas['500']+      }+    },+    config: {+      auth: false,+      description: 'Delete a audit trail.',+      tags: ['api', 'trails']+    }+  })++  // Add tagged routes to the swagger.json+  generateSpec(spec, 'trails')++  done()
juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { notFound } = require('@hapi/boom')+const S = require('fluent-schema')++const { errorsSchemas } = require('../schemas/errors')+const { spec, trailSchema } = require('../schemas/trails')+const { addApiRoute, generateSpec } = require('../api')++module.exports = async function (fastify, options, done) {+  for (const path of ['/trails/openapi.json', '/trails/swagger.json']) {+    fastify.route({+      method: 'GET',+      path,+      handler (request, reply) {+        return reply.send(spec)+      }+    })+  }++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails',+    async handler (request, reply) {+      const { from, to, who, what, subject, page, pageSize, sort } = request.query+      const results = await reply.trailCore.search({ from, to, who, what, subject, page, pageSize, sort })+      reply.send(results)+    },+    schema: {+      query: trailSchema.search,+      response: {+        200: S.array()+          .description('The search results.')+          .items(trailSchema.response),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Search audit trails.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/enumerate',+    async handler (request, reply) {+      const { from, to, type, page, pageSize, desc } = request.query+      const results = await reply.trailCore.enumerate({ from, to, type, page, pageSize, desc })+      reply.send(results)+    },+    schema: {+      query: trailSchema.enumerate,+      response: {+        200: S.array()+          .description('The enumeration results.')+          .items(S.string().description('A trail who, what or subject id')),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Enumerate audit trails ids.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'POST',+    path: '/trails',+    async handler (request, reply) {+      const id = await reply.trailCore.insert(request.body)+      const trail = await reply.trailCore.get(id)+      reply.code(201).send(trail)+    },+    schema: {+      headers: S.object()+        .additionalProperties(true)+        .prop('content-type', S.string().const('application/json')),+      body: trailSchema.request,+      response: {+        201: trailSchema.response.description('The newly created audit trail.'),+        400: errorsSchemas['400'],+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Create a new audit trail.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/:id',+    async handler (request, reply) {+      const { id } = request.params+      const trail = await reply.trailCore.get(id)++      if (!trail) throw notFound(`Trail with id ${id} not found.`)++      return reply.send(trail)+    },+    schema: {+      params: trailSchema.params,+      response: {+        200: trailSchema.response.description('The requested audit trail.'),+        400: errorsSchemas['400'],+        404: errorsSchemas['404'],+        500: errorsSchemas['500']+      }+    },+    config: {+      auth: false,+      description: 'Get a audit trail.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'PUT',+    path: '/trails/:id',+    async handler (request, reply) {+      const { id } = request.params+      const updated = await reply.trailCore.update(id, request.body)++      if (!updated) throw notFound(`Trail with id ${id} not found.`)++      const trail = await reply.trailCore.get(id)+      reply.code(202).send(trail)
      reply.code(202)
      return send(trail)
juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const S = require('fluent-schema')

add use strict at the top.

juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { notFound } = require('@hapi/boom')+const S = require('fluent-schema')++const { errorsSchemas } = require('../schemas/errors')+const { spec, trailSchema } = require('../schemas/trails')+const { addApiRoute, generateSpec } = require('../api')++module.exports = async function (fastify, options, done) {
module.exports = async function (fastify, options) {
juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { notFound } = require('@hapi/boom')+const S = require('fluent-schema')++const { errorsSchemas } = require('../schemas/errors')+const { spec, trailSchema } = require('../schemas/trails')+const { addApiRoute, generateSpec } = require('../api')++module.exports = async function (fastify, options, done) {+  for (const path of ['/trails/openapi.json', '/trails/swagger.json']) {+    fastify.route({+      method: 'GET',+      path,+      handler (request, reply) {+        return reply.send(spec)+      }+    })+  }++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails',+    async handler (request, reply) {+      const { from, to, who, what, subject, page, pageSize, sort } = request.query+      const results = await reply.trailCore.search({ from, to, who, what, subject, page, pageSize, sort })+      reply.send(results)+    },+    schema: {+      query: trailSchema.search,+      response: {+        200: S.array()+          .description('The search results.')+          .items(trailSchema.response),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Search audit trails.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/enumerate',+    async handler (request, reply) {+      const { from, to, type, page, pageSize, desc } = request.query+      const results = await reply.trailCore.enumerate({ from, to, type, page, pageSize, desc })+      reply.send(results)+    },+    schema: {+      query: trailSchema.enumerate,+      response: {+        200: S.array()+          .description('The enumeration results.')+          .items(S.string().description('A trail who, what or subject id')),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Enumerate audit trails ids.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'POST',+    path: '/trails',+    async handler (request, reply) {+      const id = await reply.trailCore.insert(request.body)+      const trail = await reply.trailCore.get(id)+      reply.code(201).send(trail)+    },+    schema: {+      headers: S.object()+        .additionalProperties(true)+        .prop('content-type', S.string().const('application/json')),+      body: trailSchema.request,+      response: {+        201: trailSchema.response.description('The newly created audit trail.'),+        400: errorsSchemas['400'],+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Create a new audit trail.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/:id',+    async handler (request, reply) {+      const { id } = request.params+      const trail = await reply.trailCore.get(id)++      if (!trail) throw notFound(`Trail with id ${id} not found.`)++      return reply.send(trail)
      return trail
juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { notFound } = require('@hapi/boom')+const S = require('fluent-schema')++const { errorsSchemas } = require('../schemas/errors')+const { spec, trailSchema } = require('../schemas/trails')+const { addApiRoute, generateSpec } = require('../api')++module.exports = async function (fastify, options, done) {+  for (const path of ['/trails/openapi.json', '/trails/swagger.json']) {+    fastify.route({+      method: 'GET',+      path,+      handler (request, reply) {+        return reply.send(spec)+      }+    })+  }++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails',+    async handler (request, reply) {+      const { from, to, who, what, subject, page, pageSize, sort } = request.query+      const results = await reply.trailCore.search({ from, to, who, what, subject, page, pageSize, sort })+      reply.send(results)+    },+    schema: {+      query: trailSchema.search,+      response: {+        200: S.array()+          .description('The search results.')+          .items(trailSchema.response),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Search audit trails.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/enumerate',+    async handler (request, reply) {+      const { from, to, type, page, pageSize, desc } = request.query+      const results = await reply.trailCore.enumerate({ from, to, type, page, pageSize, desc })+      reply.send(results)+    },+    schema: {+      query: trailSchema.enumerate,+      response: {+        200: S.array()+          .description('The enumeration results.')+          .items(S.string().description('A trail who, what or subject id')),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Enumerate audit trails ids.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'POST',+    path: '/trails',+    async handler (request, reply) {+      const id = await reply.trailCore.insert(request.body)+      const trail = await reply.trailCore.get(id)+      reply.code(201).send(trail)
      reply.code(201)
      return trail
juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const fp = require('fastify-plugin')+const { TrailsManager } = require('@nearform/trail-core')+const { get } = require('lodash')+const Ajv = require('ajv')++const { errorsMessages } = require('./schemas/errors')++const environment = get(process, 'env.NODE_ENV', 'development')++function getCustomErrorMessage (schema, path, message) {+  // Convert a schema path like '#/properties/who/anyOf' to a ref addressing+  // the custom error type, e.g. 'properties.who.meta.errorType'+  const ref = path+    .substring(path.indexOf('/') + 1, path.lastIndexOf('/'))+    .replace(/\//g, '.')+    .concat('.meta.errorType')+  const errorType = get(schema, ref)+  return errorType ? errorsMessages[errorType] : message+}++function formatReasons (error, schema) {+  const { validation } = error+  return validation.reduce((reasons, item) => {+    const {+      dataPath,+      schemaPath,+      keyword,+      message,+      params+    } = item+    const name = dataPath.slice(1)+    switch (keyword) {+      case 'required':+        if (!schemaPath.includes('anyOf')) {+          reasons[params.missingProperty] = errorsMessages['any.required']+        }+        break+      case 'additionalProperties':+        reasons[params.additionalProperty] = errorsMessages['object.unknown']+        break+      default:+        reasons[name] = getCustomErrorMessage(schema, schemaPath, message)+    }+    return reasons+  }, {})+}++const formatStack = error => get(error, 'stack', '')+  .split('\n')+  .filter((s, i) => i > 0)+  .map(s => s.trim().replace(/^at /, ''))++const validationContextMessages = {+  querystring: 'Invalid input data.',+  body: 'Invalid input data.'+}++function formatValidationErrorResponse (error, context) {+  const { validationContext } = error+  const schema = context.schema[validationContext]+  return {+    statusCode: 422,+    error: 'Unprocessable Entity',+    message: validationContextMessages[validationContext],+    reasons: formatReasons(error, schema)+  }+}++async function trail (server, options) {+  const trailsManager = new TrailsManager(undefined, options.pool)++  server.decorate('trailCore', trailsManager)+  server.decorateReply('trailCore', trailsManager)++  server.addHook('onClose', async (instance, done) => {+    await trailsManager.close()+    done()+  })++  const ajv = new Ajv({ allErrors: true })

why is this needed?

juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { notFound } = require('@hapi/boom')+const S = require('fluent-schema')++const { errorsSchemas } = require('../schemas/errors')+const { spec, trailSchema } = require('../schemas/trails')+const { addApiRoute, generateSpec } = require('../api')++module.exports = async function (fastify, options, done) {+  for (const path of ['/trails/openapi.json', '/trails/swagger.json']) {+    fastify.route({+      method: 'GET',+      path,+      handler (request, reply) {+        return reply.send(spec)+      }+    })+  }++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails',+    async handler (request, reply) {+      const { from, to, who, what, subject, page, pageSize, sort } = request.query+      const results = await reply.trailCore.search({ from, to, who, what, subject, page, pageSize, sort })+      reply.send(results)+    },+    schema: {+      query: trailSchema.search,+      response: {+        200: S.array()+          .description('The search results.')+          .items(trailSchema.response),+        422: errorsSchemas['422'],+        500: errorsSchemas['500']+      }+    },+    config: {+      description: 'Search audit trails.',+      tags: ['api', 'trails']+    }+  })++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails/enumerate',+    async handler (request, reply) {+      const { from, to, type, page, pageSize, desc } = request.query+      const results = await reply.trailCore.enumerate({ from, to, type, page, pageSize, desc })+      reply.send(results)
      return results
juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const { notFound } = require('@hapi/boom')+const S = require('fluent-schema')++const { errorsSchemas } = require('../schemas/errors')+const { spec, trailSchema } = require('../schemas/trails')+const { addApiRoute, generateSpec } = require('../api')++module.exports = async function (fastify, options, done) {+  for (const path of ['/trails/openapi.json', '/trails/swagger.json']) {+    fastify.route({+      method: 'GET',+      path,+      handler (request, reply) {+        return reply.send(spec)+      }+    })+  }++  addApiRoute(fastify, 'trails', {+    method: 'GET',+    path: '/trails',+    async handler (request, reply) {+      const { from, to, who, what, subject, page, pageSize, sort } = request.query+      const results = await reply.trailCore.search({ from, to, who, what, subject, page, pageSize, sort })+      reply.send(results)
      return results
juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+const fp = require('fastify-plugin')+const { TrailsManager } = require('@nearform/trail-core')+const { get } = require('lodash')+const Ajv = require('ajv')++const { errorsMessages } = require('./schemas/errors')++const environment = get(process, 'env.NODE_ENV', 'development')++function getCustomErrorMessage (schema, path, message) {+  // Convert a schema path like '#/properties/who/anyOf' to a ref addressing+  // the custom error type, e.g. 'properties.who.meta.errorType'+  const ref = path+    .substring(path.indexOf('/') + 1, path.lastIndexOf('/'))+    .replace(/\//g, '.')+    .concat('.meta.errorType')+  const errorType = get(schema, ref)+  return errorType ? errorsMessages[errorType] : message+}++function formatReasons (error, schema) {+  const { validation } = error+  return validation.reduce((reasons, item) => {+    const {+      dataPath,+      schemaPath,+      keyword,+      message,+      params+    } = item+    const name = dataPath.slice(1)+    switch (keyword) {+      case 'required':+        if (!schemaPath.includes('anyOf')) {+          reasons[params.missingProperty] = errorsMessages['any.required']+        }+        break+      case 'additionalProperties':+        reasons[params.additionalProperty] = errorsMessages['object.unknown']+        break+      default:+        reasons[name] = getCustomErrorMessage(schema, schemaPath, message)+    }+    return reasons+  }, {})+}++const formatStack = error => get(error, 'stack', '')+  .split('\n')+  .filter((s, i) => i > 0)+  .map(s => s.trim().replace(/^at /, ''))++const validationContextMessages = {+  querystring: 'Invalid input data.',+  body: 'Invalid input data.'+}++function formatValidationErrorResponse (error, context) {+  const { validationContext } = error+  const schema = context.schema[validationContext]+  return {+    statusCode: 422,+    error: 'Unprocessable Entity',+    message: validationContextMessages[validationContext],+    reasons: formatReasons(error, schema)+  }+}++async function trail (server, options) {+  const trailsManager = new TrailsManager(undefined, options.pool)++  server.decorate('trailCore', trailsManager)+  server.decorateReply('trailCore', trailsManager)++  server.addHook('onClose', async (instance, done) => {+    await trailsManager.close()+    done()

remove done here and in the function signature.

juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+# @nearform/trail-fastify-plugin++[![npm][npm-badge]][npm-url]++trail-fastify-plugin is a plugin to add the trail REST API to a [Fastify][fastify] server.++## Install++To install via npm:++```+npm install @nearform/trail-fastify-plugin+```++## Usage++```javascript+const main = async function() {+  import Fastify from 'fastify'+  const fastify = Fastify()++  fastify.register(require('@nearform/trail-fastify-plugin'))++  await fastify.ready()

this await fastify.ready() call is not needed

juliangoacher

comment created time in 2 days

Pull request review commentnearform/trail

Fastify support

+# @nearform/trail-fastify-plugin++[![npm][npm-badge]][npm-url]++trail-fastify-plugin is a plugin to add the trail REST API to a [Fastify][fastify] server.++## Install++To install via npm:++```+npm install @nearform/trail-fastify-plugin+```++## Usage++```javascript+const main = async function() {+  import Fastify from 'fastify'

This is not valid JavaScript. Please use require at the top of the file.

juliangoacher

comment created time in 2 days

issue commentfastify/fastify

request.hostname isn't set when using HTTP2

We are currently relying only on the host header in https://github.com/fastify/fastify/blob/6f79a90703078451f4571ac3e08b815a26753503/lib/route.js#L310. However I think it's a different header in h2. From https://tools.ietf.org/html/rfc7540#section-8.1.2.3:

To ensure that the HTTP/1.1 request line can be reproduced accurately, this pseudo-header field MUST be omitted when translating from an HTTP/1.1 request that has a request target in origin or asterisk form (see [RFC7230], Section 5.3). Clients that generate HTTP/2 requests directly SHOULD use the ":authority" pseudo-header field instead of the Host header field. An intermediary that converts an HTTP/2 request to HTTP/1.1 MUST create a Host header field if one is not present in a request by copying the value of the ":authority" pseudo-header field.

I think we should get that value from the :authority header.

Would you mind to send a PR?

mohd-akram

comment created time in 2 days

issue commentfastify/fastify-swagger

SwaggerUi with PKCE

Thanks for reporting. Would you like yo send a PR to add the functionality you need? Thanks

samaysar

comment created time in 2 days

Pull request review commentfastify/fastify

Validation and serialization

+'use strict'++const Ajv = require('ajv')+const fastJsonStringify = require('fast-json-stringify')++function ValidatorSelector () {+  const validatorPool = new Map()++  return (externalSchemas, options, cache) => {+    const externals = JSON.stringify(externalSchemas)+    const ajvConfig = JSON.stringify(options.customOptions)

I mean that you can treat it as every other encapsulated properties.

Eomm

comment created time in 2 days

issue commentmcollina/autocannon

support custom TCP protocol

autocannon is a http/1.1 load tester. Il 23 feb 2020, 18:40 +0100, Jerik Chan notifications@github.com, ha scritto:

Can it support TCP protocol?such as 'grpc'、'thrift'、'protobuf' and so on. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

jerikchan

comment created time in 2 days

push eventfastify/fastify

Manuel Spigolon

commit sha 6f79a90703078451f4571ac3e08b815a26753503

fix: multiple route same schema (#2108) * Revert "Workaround for using one schema for multiple routes (#2044)" This reverts commit 62f21b1211dab665cccca4dec966169ae548ba1b. * fix regression

view details

push time in 2 days

PR merged fastify/fastify

fix: multiple route same schema bugfix v2.x

Fixes #2104 Related #2044

This PR revert the #2044 fix and implement it in a different way but the same test cannot pass because when the user adopts the querystring alias (aka query) we modified the original object adding the querystring parameter. The previous test was a deepEquals check with the original object Now it is a deepEquals with the original object plus the querystring field.

So I think this PR is more in line with the older versions of fastify compared to v2.12

This is a "nice" edge case.. I will keep it in mind for the future during the reviews 😅

Checklist

  • [x] run npm run test and npm run benchmark
  • [x] tests and/or benchmarks are included
  • [ ] documentation is changed or added
  • [x] commit message and code follows Code of conduct
+60 -23

1 comment

4 changed files

Eomm

pr closed time in 2 days

issue closedfastify/fastify

PR-2044 (one schema for multiple routes) introduce breaking change behavior on routes schema resolve.

💥 Regression Report

PR https://github.com/fastify/fastify/pull/2044 breaks https://github.com/SkeLLLa/fastify-oas and probably related to https://github.com/fastify/fastify-swagger/issues/224

Consider you have fastify onRoute hook and save the routes like

const myRouteData = []

fastify.addHook('onRoute', (route) => {
  myRouteData.push(route);
});

Earlier after .ready() method is finished his job, e.g. await app.ready(), in schema in route object was resolved to actual schema objects.

E.g. if you referenced schemas by id

{
  query: 'mySchema#'
}

after app is ready you could expect an object in route.schema.querystring.

However now it's not resolved and still is a string.

Last working version

Worked up to version: 2.11.0

Stopped working in version: 2.12.0

To Reproduce

Steps to reproduce the behaviour:

  1. Add schema with fastify.addSchema
  2. Reference that schema in route

Paste your code here:

const routes = []
fastify.addHook('onRoute', (route) => {
    // here route.schema should be an object
  routes.push(route)
});
await fastify.ready()
// iterate over routes and check if `body`, `params`, etc. are not strings.

Expected behavior

It expects that route.schema.[body,querystring,params,headers] will be an resolved object after app is ready. However after that PR it is a string (when schema ids are used)

Your Environment

  • node version: 12
  • fastify version: >=2.12.0
  • os: Linux
  • any other relevant information

closed time in 2 days

SkeLLLa

Pull request review commentmoscajs/aedes

Add a non-blocking concurrent connection test

 const net = require('net') const Faketimers = require('@sinonjs/fake-timers') const aedes = require('../') +test('connect 500 concurrent clients', function (t) {+  t.plan(3)++  const broker = aedes()+  const server = net.createServer(broker.handle)+  const total = 500

l think their problem was due to the ulimits on their system rather than Aedes. I would like Aedes tests to pass on a vanilla system (200 is ok, ad 256 is the limit on Mac).

There is nothing we can prove on our side for these errors.

gnought

comment created time in 3 days

Pull request review commentfastify/fastify

Validation and serialization

+'use strict'++const Ajv = require('ajv')+const fastJsonStringify = require('fast-json-stringify')++function ValidatorSelector () {+  const validatorPool = new Map()++  return (externalSchemas, options, cache) => {+    const externals = JSON.stringify(externalSchemas)+    const ajvConfig = JSON.stringify(options.customOptions)

Why don’t you clear the cache for the current plugin if the relevant set methods are called?

Eomm

comment created time in 3 days

pull request commentfastify/fastify

fix: make .register() compatible with eslint rule

A couple of notes:

  1. is perfectly valid to have an async function without an await if the caller expects to be returned a Promise. This is the fastify case. I’m not sure if you can instruct eslint to behave.

  2. I would actually discourage the use of that eslint rule. Use async if the caller can handle a Promise as a return value.

Regarding your comment, I think it should focus on calling .ready() to start up the application.

jeiea

comment created time in 3 days

Pull request review commentfastify/fastify

Validation and serialization

+'use strict'++const Ajv = require('ajv')+const fastJsonStringify = require('fast-json-stringify')++function ValidatorCompiler (externalSchemas, options, cache) {+  // This instance of Ajv is private+  // it should not be customized or used+  const ajv = new Ajv(Object.assign({+    coerceTypes: true,+    useDefaults: true,+    removeAdditional: true,+    allErrors: true,+    nullable: true+  }, options.customOptions, { cache }))++  if (options.plugins && options.plugins.length > 0) {+    for (const plugin of options.plugins) {+      plugin[0](ajv, plugin[1])+    }+  }++  Object.values(externalSchemas).forEach(s => ajv.addSchema(s))

Where are those JSON.stringify?

Eomm

comment created time in 3 days

Pull request review commentmoscajs/aedes

Add a non-blocking concurrent connection test

 const net = require('net') const Faketimers = require('@sinonjs/fake-timers') const aedes = require('../') +test('connect 500 concurrent clients', function (t) {+  t.plan(3)++  const broker = aedes()+  const server = net.createServer(broker.handle)+  const total = 500

can we just do 100 instead? 500 might fail on some OS

gnought

comment created time in 3 days

issue commentfastify/fastify-swagger

Using `oneOf` in headers results in documentation not rendering properly

I have no idea if what you are proposing is feasible.

wolfejw86

comment created time in 4 days

Pull request review commentfastify/fastify

Note explaining the importance of inject, listen, or ready

 tap.test('GET `/` route', t => { ```  ### Testing with a running server-Fastify can also be tested after starting the server with `fastify.listen()` or after initializing routes and plugins with `fastify.ready()`.+Fastify can also be tested after starting the server with `fastify.listen()` or after initializing routes and plugins with `fastify.ready()`. ++Note: `fastify.inject`, `fastify.listen`, or `fastify.ready` must be invoked before the callback of `fastify.register(plugin).after(callback)` will execute.

What do you mean exactly? I’m not sure this is clear. Maybe can you add an example as well?

chanced

comment created time in 4 days

issue closedmcollina/fastify-gql

File Upload

Hey, thanks for this great tool.

I'm having difficulties to integrate an upload service. These are the packages installed:

"fastify": "2.12.0",
"fastify-gql": "3.0.6",
"fastify-cors": "3.0.1",
"fastify-multipart": "1.0.5",
"graphql": "14.6.0",
"graphql-upload": "10.0.0",

and setup my server as:


import fastify = require('fastify');
import GQL = require('fastify-gql');
import cors = require('fastify-cors');
import multipart = require('fastify-multipart');

const app = fastify();

app.register(cors, { origin: '*' });

app.register(multipart, { addToBody: true });

// schema and context come from my graqphl implementation
app.register(GQL, {
    path: '/',
    schema,
    context,
    graphiql: process.env.NODE_ENV !== 'production' && 'playground'
});

const port = 4000;
app.listen(port, () => console.log(`🚀  Server ready at http://localhost:${port}`));

But every time I try to upload i get this error Must provide Source. Received: undefined as if the server does not recognize the post with multipart/form-data.

Thanks for any help!

closed time in 4 days

artecoop

issue commentmcollina/fastify-gql

File Upload

Closing then!

artecoop

comment created time in 4 days

issue commentmcollina/fastify-gql

Support for Automatic Persisted Queries

What is the best way to set those from your point of view? A JSON file with the query/sha combination?

guigaoliveira

comment created time in 4 days

Pull request review commentmoscajs/aedes

Enhanced retain.js tests by fake timers

 test('reconnected subscriber will not receive retained messages when QoS 0 and c test('new QoS 0 subscribers receive QoS 0 retained messages when clean', function (t) {   t.plan(9) +  const clock = Faketimers.createClock()

You’d probably need to uninstall the fake timer

gnought

comment created time in 4 days

pull request commentfastify/fastify

fix: make .register()'s parameter inferable

await app.register has landed in the next branch, which in time will be released as v3. It is not ready yet, and it will not land on v2.

jeiea

comment created time in 4 days

issue closedmcollina/fastify-gql

Caching query results?

I'm using the fastify-caching npm package to cache requests, however large queries still takes 300ms to return to client, where the same query with express and memory-cache package take around 60 after being cached. So how can i efficiently cache the query results with fastify? :)

closed time in 4 days

GimignanoF

issue commentmcollina/fastify-gql

Caching query results?

Thanks!

GimignanoF

comment created time in 4 days

issue commentfastify/fastify-swagger

Using `oneOf` in headers results in documentation not rendering properly

How would you implement that?

wolfejw86

comment created time in 4 days

push eventmcollina/avvio

Matteo Collina

commit sha fba94f7cd1572cf400d38bcd64a7c37bf2a46f46

Bumped v7.0.0-alpha.1

view details

push time in 5 days

push eventmcollina/avvio

Matteo Collina

commit sha ca09364b8b97f809a9d23ddc124560f12cb89ed7

Avoid deadlocks when using then and returning self. Fixes #94

view details

Matteo Collina

commit sha ebcf02e53234711d6177b83fc899a26e22bfb111

Merge branch 'next' of github.com:mcollina/avvio into next

view details

push time in 5 days

issue commentfastify/fastify

PR-2044 (one schema for multiple routes) introduce breaking change behavior on routes schema resolve.

@SkeLLLa would you like to send a PR? I'm a bit lost on what is the proposed fix for this.

SkeLLLa

comment created time in 5 days

created tagfastify/fast-json-stringify

tagv1.16.4

2x faster than JSON.stringify()

created time in 5 days

release fastify/fast-json-stringify

v1.16.4

released time in 5 days

push eventfastify/fast-json-stringify

Matteo Collina

commit sha 2e992e9c7b77ac0e15f92a01e2f942a626dc6153

Bumped v1.16.4

view details

push time in 5 days

push eventfastify/fast-json-stringify

Luciano Leggieri

commit sha 9c51c10bd4a4675dc2bea2dbd35c38085a4d4510

pass full schema to buildObject if $ref is defined at the top level (#209)

view details

push time in 5 days

PR merged fastify/fast-json-stringify

pass full schema to buildObject if $ref is defined at the top level

Was getting the error Cannot find reference 'definitions' and it is because the schema variable is replaced on line 80, so the original schema definition is lost.

Adding results of benchmark run:

FJS creation x 45,686 ops/sec ±2.46% (80 runs sampled)
JSTR creation x 122,116 ops/sec ±1.14% (89 runs sampled)
CJS creation x 123,350 ops/sec ±1.10% (91 runs sampled)
JSON.stringify array x 3,565 ops/sec ±2.88% (83 runs sampled)
fast-json-stringify array x 5,443 ops/sec ±2.29% (81 runs sampled)
fast-json-stringify-uglified array x 5,363 ops/sec ±2.79% (79 runs sampled)
json-strify array x 49,040,148 ops/sec ±1.25% (91 runs sampled)
compile-json-stringify array x 5,675 ops/sec ±2.28% (82 runs sampled)
JSON.stringify long string x 12,497 ops/sec ±1.91% (86 runs sampled)
fast-json-stringify long string x 12,755 ops/sec ±1.51% (87 runs sampled)
fast-json-stringify-uglified long string x 13,061 ops/sec ±0.69% (93 runs sampled)
json-strify long string x 234,092 ops/sec ±1.34% (90 runs sampled)
compile-json-stringify long string x 13,186 ops/sec ±0.50% (93 runs sampled)
JSON.stringify short string x 4,441,831 ops/sec ±1.63% (91 runs sampled)
fast-json-stringify short string x 24,149,449 ops/sec ±0.99% (90 runs sampled)
fast-json-stringify-uglified short string x 24,403,066 ops/sec ±0.31% (92 runs sampled)
json-strify short string x 46,378,790 ops/sec ±1.35% (88 runs sampled)
compile-json-stringify short string x 26,290,438 ops/sec ±1.51% (91 runs sampled)
JSON.stringify obj x 1,816,270 ops/sec ±1.56% (89 runs sampled)
fast-json-stringify obj x 6,093,148 ops/sec ±2.48% (84 runs sampled)
fast-json-stringify-uglified obj x 6,450,704 ops/sec ±1.99% (88 runs sampled)
json-strify obj x 44,277,015 ops/sec ±2.70% (85 runs sampled)
compile-json-stringify obj x 6,507,869 ops/sec ±1.47% (89 runs sampled)

Checklist

  • [X] run npm run test and npm run benchmark
  • [X] tests and/or benchmarks are included
  • [ ] documentation is changed or added
  • [X] commit message and code follows Code of conduct
+37 -1

0 comment

2 changed files

lukiano

pr closed time in 5 days

issue commentfastify/fastify-swagger

Using `oneOf` in headers results in documentation not rendering properly

Thanks for reporting. Would you like to send a PR to fix this?

wolfejw86

comment created time in 5 days

Pull request review commentpinojs/pino

Add serializers for core log components

 const defaultOptions = {   serializers: Object.assign(Object.create(null), {     err: defaultErrorSerializer   }),+  formatters: Object.assign(Object.create(null), {

They are way faster.

delvedor

comment created time in 5 days

issue commentnodejs/admin

Additional org owned by Node.js project for package maintenance team

Definitely +1.

We might want to change how the package-maintenance team is chartered (or actually not chartered right now).

My concerns are about moderation and governance. Would the new org still be moderated by our moderation team? What is the role of the Node.js TSC?

mhdawson

comment created time in 5 days

Pull request review commentdelvedor/find-my-way

No match path param with ignoreTrailingSlash

+'use strict'++const t = require('tap')+const FindMyWay = require('../')++const noop = function () {}++t.test('issue-145', (t) => {+  t.plan(4)++  const findMyWay = FindMyWay({ ignoreTrailingSlash: true })++  findMyWay.on('GET', '/a/b', noop)+  findMyWay.on('GET', '/a/:pam/c', noop)

Instead of using noop, can you please use named functions so that we can assert the right one matched?

Eomm

comment created time in 5 days

delete branch mcollina/avvio

delete branch : await-fixes

delete time in 5 days

push eventmcollina/avvio

Matteo Collina

commit sha f64da9a3d4b771e50991c24a8eddb7d620f540e0

Await fixes (#95) * Avoid deadlocks when using then and returning self. Fixes #94 * Reject promises in cases of error when await app.register() or .after()

view details

push time in 5 days

PR merged mcollina/avvio

Reviewers
Await fixes

This PR changes substantially how our await app.register() and await app.after() works. Essentially, it's impossible to "skip error and continue", as we were doing before. Instead, this makes the promise reject.

Fixes #93 Fixes #94

+130 -28

1 comment

4 changed files

mcollina

pr closed time in 5 days

issue openednearform/node-clinic-doctor

Recommend allocation sampling for memory leaks

Schermata 2020-02-20 alle 09 15 25 Schermata 2020-02-20 alle 09 15 11

I recommend we update doctor text for memory leaks to recommend the use of "allocation sampling". It works like a charm to identify the function that is allocating the most memory. I would also recommend doing an updated version of https://www.nearform.com/blog/how-to-self-detect-a-memory-leak-in-node/.

cc @jasnell @dberesford

created time in 5 days

issue commentnodejs/node

Recent behavior change of buffered write callbacks

Hey fellow @nodejs/tsc members, @lpinca is asking our opinion in this regard. In https://github.com/nodejs/node/pull/29028 and https://github.com/nodejs/node/pull/30596, he would have objected to them landing, and he is asking if we should do a revert. The changes landed on Node 13.

Note that both PRs were approved by @jasnell @addaleax and myself. I've added this to discuss in the next meeting.

lpinca

comment created time in 6 days

more