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

@driimus/dynamodb-data-marshaller

v0.11.1

Published

A schema-based data marshaller for Amazon DynamoDB

Downloads

8

Readme

Amazon DynamoDB Data Marshaller

Apache 2 License

This library provides an marshallItem and unmarshallItem functions that convert native JavaScript values to DynamoDB AttributeValues and back again, respectively, based on a defined schema. While many JavaScript values map cleanly to DynamoDB data types and vice versa, schemas allow you to losslessly persist any JavaScript type, including dates, class instances, and empty strings.

Getting started

To use the data marshaller, begin by defining a schema that describes the relationship between your application's domain objects and their serialized form in a DynamoDB table:

const schema = {
  foo: { type: 'Binary' },
  bar: { type: 'Boolean' },
  baz: { type: 'String' },
  quux: {
    type: 'Document',
    members: {
      fizz: { type: 'Set', memberType: 'String' },
      buzz: {
        type: 'Tuple',
        members: [
          {
            type: 'List',
            memberType: { type: 'Set', memberType: 'Number' },
          },
          {
            type: 'Map',
            memberType: { type: 'Date' },
          },
        ],
      },
    },
  },
};

This schema may be used to marshall JavaScript values to DynamoDB attribute values:

import { marshallItem } from '@driimus/dynamodb-data-marshaller';

const marshalled = marshallItem(schema, {
  foo: Uint8Array.from([0xde, 0xad, 0xbe, 0xef]),
  bar: false,
  baz: '',
  quux: {
    fizz: new Set(['a', 'b', 'c']),
    buzz: [
      [new Set([1, 2, 3]), new Set([2, 3, 4]), new Set([3, 4, 5])],
      new Map([
        ['now', new Date()],
        ['then', new Date(0)],
      ]),
    ],
  },
});

The schema can also be used to unmarshall DynamoDB attribute values back to their original JavaScript representation:

import { unmarshallItem } from '@driimus/dynamodb-data-marshaller';

const unmarshalled = unmarshallItem(schema, {
  foo: { B: Uint8Array.from([0xde, 0xad, 0xbe, 0xef]) },
  bar: { BOOL: false },
  baz: { NULL: true },
  quux: {
    fizz: { SS: ['a', 'b', 'c'] },
    buzz: {
      L: [
        (L: [{ NS: ['1', '2', '3'] }, { NS: ['2', '3', '4'] }, { NS: ['3', '4', '5'] }]),
        (M: {
          now: { N: '1507189047' },
          then: { N: '0' },
        }),
      ],
    },
  },
});

Specifying keys

DynamoDB tables must define a hash key and may optionally define a range key. In DynamoDB documentation, these keys are sometimes referred to as partition and sort keys, respectively. To declare a property to be a key, add a keyType property to its property schema (example taken from the DynamoDB developer guide):

// Table model taken from http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html
const gameScores = {
  UserId: {
    type: 'String',
    keyType: 'HASH',
  },
  GameTitle: {
    type: 'String',
    keyType: 'RANGE',
  },
  TopScore: { type: 'Number' },
  TopScoreDateTime: { type: 'Date' },
  Wins: { type: 'Number' },
  Losses: { type: 'Number' },
};

The keyType attribute may only be used in types that are serialized as strings, numbers, or binary attributes. In addition to 'String', 'Number', and 'Binary' properties, it may be used on 'Date' and 'Custom' properties.

Index keys are specified using an object mapping index names to the key type as which the value is used in a given index. To continue with the gameScores example given above, you could add the index key declarations described in the DynamoDB Global Secondary Index developer guide as follows:

const gameScores = {
  UserId: {
    type: 'String',
    keyType: 'HASH',
  },
  GameTitle: {
    type: 'String',
    keyType: 'RANGE',
    indexKeyConfigurations: {
      GameTitleIndex: 'HASH',
    },
  },
  TopScore: {
    type: 'Number',
    indexKeyConfigurations: {
      GameTitleIndex: 'RANGE',
    },
  },
  TopScoreDateTime: { type: 'Date' },
  Wins: { type: 'Number' },
  Losses: { type: 'Number' },
};

Supplying defaults

Any property schema may define a defaultProvider function to be called when a field is undefined in the input provided to marshallItem. This function must return a raw JavaScript value and should not return an already-marshalled DynamoDB AttributeValue shape.

const uuidV4 = require('uuid/v4');

const schema = {
  key: {
    type: 'String',
    defaultProvider: uuidV4,
    keyType: 'HASH',
  },
  // ...
};

Supported types

Any

Will be marshalled and unmarshalled using the @driimus/dynamodb-auto-marshaller package, which detects the type of a given value at runtime.

Example

const anyProperty = {
  type: 'Any',
  // optionally, you may specify configuration options for the
  // @driimus/dynamodb-auto-marshaller package's Marshaller class:
  unwrapNumbers: false,
  onInvalid: 'omit',
  onEmpty: 'nullify',
};

Binary

Used for ArrayBuffer and ArrayBufferView objects, as well as Node.JS buffers.

May be used as a table or index key.

Example

const binaryProperty = { type: 'Binary' };

Boolean

Used for true/false values.

Example

const booleanProperty = { type: 'Boolean' };

Collection

Denotes a list of untyped items. The constituent items will be marshalled and unmarshalled using the @driimus/dynamodb-auto-marshaller.

Example

const collectionProperty = {
  type: 'Collection',
  // optionally, you may specify configuration options for the
  // @driimus/dynamodb-auto-marshaller package's Marshaller class:
  unwrapNumbers: false,
  onInvalid: 'omit',
  onEmpty: 'nullify',
};

Custom

Allows the use of bespoke marshalling and unmarshalling functions. The type definition for a 'Custom' property must include a marshall function that converts the type's JavaScript representation to a DynamoDB AttributeValue and an unmarshall function that converts the AttributeValue back to a JavaScript value.

May be used as a table or index key.

Example

// This custom property handles strings
const customProperty = {
  type: 'Custom',
  marshall(input) {
    return { S: input };
  },
  unmarshall(persistedValue) {
    return persistedValue.S;
  },
};

Date

Used for time data. Dates will be serialized to DynamoDB as epoch timestamps for easy integration with DynamoDB's time-to-live feature. As a result, timezone information will not be persisted.

May be used as a table or index key.

Example

const dateProperty = { type: 'Date' };

Document

Used for object values that have their own schema and (optionally) constructor.

Example

class MyCustomDocument {
    method() {
        // pass
    }

    get computedProperty() {
        // pass
    }
}

class documentSchema = {
    fizz: {type: 'String'},
    buzz: {type: 'Number'},
    pop: {type: 'Date'}
}

const documentProperty = {
    type: 'Document',
    members: documentSchema,
    // optionally, you may specify a constructor to use to create the object
    // that will underlie unmarshalled instances. If not specified,
    // Object.create(null) will be used.
    valueConstructor: MyCustomDocument
};

Hash

Used for objects with string keys and untyped values.

Example

const collectionProperty = {
  type: 'Hash',
  // optionally, you may specify configuration options for the
  // @driimus/dynamodb-auto-marshaller package's Marshaller class:
  unwrapNumbers: false,
  onInvalid: 'omit',
  onEmpty: 'nullify',
};

List

Used for arrays or iterable objects whose elements are all of the same type.

Example

const listOfStrings = {
  type: 'List',
  memberType: { type: 'String' },
};

Map

Used for Map objects whose values are all of the same type.

Example

const mapOfStrings = {
  type: 'Map',
  memberType: { type: 'String' },
};

Null

Used to serialize null. Often used as a sigil value.

Example

const nullProperty = { type: 'Null' };

Number

Used to serialize numbers.

May be used as a table or index key.

Example

const numberProperty = { type: 'Number' };

Set

Used to serialize sets whose values are all of the same type. DynamoDB allows sets of numbers, sets of strings, and sets of binary values.

Example

const binarySetProperty = { type: 'Set', memberType: 'Binary' };
const numberSetProperty = { type: 'Set', memberType: 'Number' };
const stringSetProperty = { type: 'Set', memberType: 'String' };

String

Used to serialize strings.

May be used as a table or index key.

Example

const stringProperty = { type: 'String' };

Tuple

Used to store arrays that have a specific length and sequence of elements.

Example

const tupleProperty = {
  type: 'Tuple',
  members: [{ type: 'Boolean' }, { type: 'String' }],
};