Socket
Socket
Sign inDemoInstall

projection-utils

Package Overview
Dependencies
Maintainers
20
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

projection-utils

Utilities to work with projections (e.g. mongo)


Version published
Weekly downloads
12K
increased by0.7%
Maintainers
20
Weekly downloads
 
Created
Source

projection-utils

A set of utilities for working with MongoDB-style projections.

Notably, this project exposes a ProjectionFieldSet class that tracks, merges, and intersects multi-level projections.

We do not support symmetric or asymmetric diffing of field sets, as the semantics are not well-defined on mongo projections. A field set that contains users minus a field set that contains users.accessToken would need new syntax to represent the fields under users that aren't accessToken, or would need knowledge of all existant fields under the users subdocument. It's better to handle this yourself, using intersect, and a whitelist of permitted fields.

ProjectionFieldSet

Basic usage:

const permittedFields = ProjectionFieldSet.fromDotted(
  ['users.id', 'users.email', 'share', 'content']);

const desiredFields = ProjectionFieldSet.fromDotted(
  ['users', 'users.accessToken', 'share', 'invalid']);

// The fields we want, where they're permitted.
const selectedFields = permittedFields.intersect(desiredFields);

// Add fields that we need for server-side business logic.
const mandatoryFields = ProjectionFieldSet.fromDotted(
  ['internalVersion']);

const queryFields = selectedFields.union(mandatoryFields);
const projection = queryFields.toMongo();
// => {'users.id': 1, 'users.email': 1, share: 1, internalVersion: 1}

Constructor usage:

// Equivalent to the first fromDotted invocation in the previous example.
const permittedFields = new ProjectionFieldSet([
  ['users', 'id'],
  ['users', 'email'],
  ['share'],
  ['content'],
]);

Iterate over paths:

for (const path of permittedFields) {
  // path is the array containing the parts of the path, e.g.:
  // ['users', 'email']
}

// Or just convert to an Array:
const fields = Array.from(permittedFields);

Enumerate dot-joined paths:

const dotJoined = Array.from(queryFields.toDotted());
// => ['users.id', 'users.email', 'share', 'internalVersion']

Check for field containment, and partial field containment:

queryFields.contains(['users']);
// => false, because only some of the fields in users are included

// equivalent to the above
queryFields.containsDotted('users');

// produces the set of fields that are included under the users field
Array.from(queryFields.get(['users']));
// => [['users', 'id'], ['users', 'email']]

Array.from(queryFields.getDotted('users'));
// => ['users.id', 'users.email']

// both produce no items
Array.from(queryFields.get(['invalid']));
Array.from(queryFields.getDotted('invalid'));
// => []

// exclude the users prefix
Array.from(queryFields.get('users', false));
// => [['id'], ['email']]

Array.from(queryFields.getDotted('users', false));
// => ['id', 'email']

Explicitly expand the set of fields:

// Add users.name to queryFields. Unlike intersect and union, this mutates the
// ProjectionFieldSet instead of making a new instance.
queryFields.widen(['users', 'name']);
queryFields.toMongo();
// => {'users.id': 1, 'users.email': 1, 'users.name': 1, share: 1, internalVersion: 1}

// Expand queryFields to include all fields of users (even accessToken - take
// care when ordering operations on ProjectionFieldSets, as an intersect won't
// forbid a set of fields being added to the produced ProjectionFieldSet.
queryFields.widen(['users']);
queryFields.toMongo();
// => {users: 1, share: 1, internalVersion: 1}

Note that field sets can be singular. Unioning with a singular value yields a singular value, and intersecting with a singular value yields the non-singular value. For example:

// This is distinct from new ProjectionFieldSet([]) (and
// new ProjectionFieldSet()), which yield an empty fieldset, rather than a
// singular fieldset.
const singular = new ProjectionFieldSet([[]]);

singular.union(singular);
// => copy of singular

singular.intersect(singular);
// => copy of singular

singular.union(mandatoryFields);
// => copy of singular

singular.intersect(mandatoryFields);
// => copy of mandatoryFields

const empty = new ProjectionFieldSet([]);

empty.union(empty);
// => copy of empty

empty.intersect(empty);
// => copy of empty

empty.union(mandatoryFields);
// => copy of mandatoryFields

empty.intersect(mandatoryFields);
// => copy of empty


singular.union(empty);
// => copy of singular

singular.intersect(empty);
// => copy of empty

Keywords

FAQs

Package last updated on 09 Jul 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc