npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

express-typed-query

v1.0.27

Published

Converts query strings(qs) to Javascript typed objects including dates and malformed JSON

Downloads

7

Readme

Express Typed Query

Exhausted from double checking types passed to your data layer? Well this simple package leverages the power of qs and parses your query sting to usable types. Use real types when exchanging parameters without JSON serialization. Make sure your users can get the data they need in the most flexible way possible. Converts query strings to Javascript typed objects including dates and malformed JSON.

Github

NPM

Install

npm

npm install express-typed-query

yarn

yarn add express-typed-query

pnpm

pnpm add express-typed-query

Usage

Global

MJS / TS

import express from 'express';
import etq from 'express-typed-query';

const app = express();

// Global Middleware
etq.configure(app, etqOptions);

// ...app middleware and routes...

// OR

// Route Middleware
etq.configure(app, { global: false, ...etqOptions });
const router = express.Router();
const options = { ... };

etq.register(router.get('/path', (req, res, next) => { ... }), options);

// ...app middleware and routes...
import express from 'express';
import { configure, register, init } from 'express-typed-query';

const app = express();

// Global Middleware
configure(app, options);

// ...app middleware and routes...

// OR

// Route Middleware
etq.configure(app, { global: false, ...etqOptions });
const router = express.Router();
const options = { disable: <true/false>, global: <true/false> };

register(router.get('/path', (req, res, next) => { ... }), options);

// ...app middleware and routes...

CommonJs

const express = require('express');
const etq = require('express-typed-query');

const app = express();

// Global Middleware
etq.configure(app, options);

// ...app middleware and routes...

// OR

// Route Middleware
etq.configure(app, { global: false, ...etqOptions });
const router = express.Router();
const options = { disable: <true/false>, global: <true/false> };

register(router.get('/path', (req, res, next) => { ... }), options);

// ...app middleware and routes...
const express = require('express');
const { configure } = require('express-typed-query');

const app = express();

// Global Middleware
configure(app, options);

// ...app middleware and routes...

// OR

// Route Middleware
etq.configure(app, { global: false, ...etqOptions });
const router = express.Router();
const options = { disable: <true/false>, global: <true/false> };

register(router.get('/path', (req, res, next) => { ... }), options);

// ...app middleware and routes...

Options (IOptions)

Global vs Middleware (TGlobal)

The global pattern is used by default which will implement the query parser as a function using the set and get methods on the Express app object. Keep in mind that this config must occur before any app.use calls.

This will only allow you to disable keys at a global level. If you have keys for specific endpoints, whose key/value pairs should not be parsed you'll have to set the global option to false.

See examples/global.ts for examples run pnpm run serve:global

When disabling the global parser, you'll need to register routes that will be ignored. See the examples/routes.ts for route middleware examples. pnpm run serve:routes

middleware ({ global: false }) (TMiddlewareOption)

When disabling the global options this will allow you to register a middleware to run before and/or after the parsing of a query. When using a middleware the init function must be called in order to prevent the default parser from performing parsing on any middlewares used to manipulate the request or response object.

import express from 'express';
import etq from 'express-type-query';

const app = express();
const router = express.Router();

etq.init();

// Will be added to the stack and called before query parsing.
app.use((req, res, next) => {});

// Middleware
const before = (request, response, next) => {
  // do work before parsing
};

const after = (request, response, next) => {
  // do work after parsing
};

// Only run before
const middlewares = before;
const middlewares = [before];
// Run before and after
const middlewares = [before, after];
// Only run after
const middlewares = [null, after];

// Route handler
const handler = app.get('/get', () => {});

etq.configure(handler, { middleware: middlewares });

qsOptions (TQsParseOptions)

If you'd like to override the qs parser's behavior you can use this option which

Logging (TLogging)

This package uses JavaScript console logging by default. You can provide a log level to adjust what is logged using the log level option. The default level is "error" if no option is provided.

level (TLevel)

Setting the log level

const options = { logging: { level: 'debug' } };

logString (TLogString)

You can provide a string or function that will be prepended to all logs output by this module. The default log string function is

const options = {
  logging: {
    logString: (logLevel: string) => `${new Date().toISOString()} [${logLevel.toUpperCase()}] -`
  }
};

tag (TTag)

By default tagging is off. If you'd like to distinguish logs created by this package pass the tag logging option. This will prepend '' to the front of all log messages output by the package.

const options = {
  logging: {
    tag: true
  }
};

logger (ILogger)

If you'd like to provide your own logger. This will override all of the prior logging settings set. It must have the following level methods in order of precedence:

error 0
warn  1
info  2
debug 3
trace 4
const options = { logging: { logger: <Logger> } };

Dates (TDates)

If you'd like dates to be parsed from strings you can use the following option

const options = { dates: true };

This option will try parse date strings that are parsable into date objects.

Hail Mary (THailMary)

Sometimes complex JSON queries may have mistakes or incorrect quotes. Using the hailMary flag will try replace all quotes in a string that appears to contain JSON and attempt to parse it. This operation is risky as it makes assumptions regarding the string. If it fails an error will be thrown indicating it was unable to be parsed.

If the hailMary flag is not set the original string will be parsed back and error handling will be required by the caller.

const options = { hailMary: true };

Input
const qs = 'filter={string: "string", boolean: true, number: 1, float: 1.11, null: null, array: ["string", true, 1, 1.11, null] }';

Output
const output = { filter: {
  string: 'string',
  boolean: true,
  number: 1,
  float: 1.11,
  null: null,
  array: [
    'string',
    true,
    1,
    1.11
  ]
}}

disable (TDisable)

In some cases we have keys that should always remain in the type they are set. For example when using a q parameter ?q="1234" that would be parsed to a number and when searching on a text field we'd run into issues. You can pass in an array of keys to instruct the parser to disable parsing and return the original value at a global level.

const options: Options = { disable: ['q'] };

Parameter Parsing

Utilizing terms from the Open API 3.1.0 spec, this module will parse form and deepObjects using the explode settings to convert each to their respective representation.

Repeated Keys keys=x&keys=y

Primitive types with repeated keys will be parsed to their associated type for instance

Input
'?id=1&id=2&name=John&name=Doe'

Output
{
  id: [1, 2],
  name: ["John", "Doe"]
}

Array Keys keys[]=x&key[]=y

This format ensures a key/value intended to be an array will be interpreted as such.

Input
'?id[]=1&name[]=John'

Output
{
  id: [1],
  name: ["John"]
}

If we use the repeated key syntax and the API is expecting an array as in the following example:

Input
'?id=1&name=John'

Output
{
  id: 1,
  name: "John"
}

It results in more processing by the route to handle the case where the data layer is expecting an array.

Deep Objects

Leveraging Open API terminology again, we can nest arrays of objects as follows

Input
'?user[a]={ "id": 1, name: "John" }'

Output
{ user: { a: { id: 1, name: 'John' } }}

Using Examples

Run the following commands to use the examples

pnpm install

<!-- Global -->
pnpm serve-global

<!-- Middleware -->
pnpm serve-routes