Skip to main content

Parser

Given an input of any type and a mode, validates that it respects the schema and applies transformations:

import { Parser } from 'dynamodb-toolbox/schema/actions/parse'

const validPokemon = pokemonSchema
.build(Parser)
.parse(pokemon)

The default mode is put, but you can switch it to update or key if needed:

const validKey = pokemonSchema.build(Parser).parse(
key,
// Additional options
{ mode: 'key' }
)

In DynamoDB-Toolbox, parsing is done in 4 steps:

Example

Here are step-by-step parsing examples:

☝️ Schema
const now = () => new Date().toISOString()

const pokemonSchema = schema({
// key attributes
pokemonClass: string()
.key()
.transform(prefix('POKEMON'))
.savedAs('partitionKey'),
pokemonId: string().key().savedAs('sortKey'),

// timestamps
created: string().default(now),
updated: string()
.required('always')
.putDefault(now)
.updateDefault(now),

// other attributes
name: string().optional(),
level: number().default(1)
}).and(prevSchema => ({
levelPlusOne: number().link<typeof prevSchema>(
({ level }) => level + 1
)
}))
🔎 'put' mode
{
"pokemonClass": "pikachu",
"pokemonId": "123",
"name": "Pikachu"
}
🔎 'key' mode
{
"pokemonClass": "pikachu",
"pokemonId": "123",
}
+ (Only key attributes are required)
🔎 'update' mode
{
"pokemonClass": "bulbasaur",
"pokemonId": "123",
"name": "PlantyDino",
}

Methods

parse(...)

(input: unknown, options?: ParseValueOptions) => ParsingResults<SCHEMA>

Parses an input of any type:

const parsedValue = pokemonSchema.build(Parser).parse(input)

You can provide options as a second argument. Available options:

OptionTypeDefaultDescription
fillbooleantrueWhether to complete the input (with defaults and links) prior to validation or not.
transformbooleantrueWhether to transform the input (with savedAs and transform) after validation or not.
modeput, key or updateputThe mode of the parsing: Impacts which default and link should be used, as well as requiredness during validation.
parseExtension(internal)-Dependency injection required to parse extended syntax ($get, $add etc.) when using the update mode (check example below).
Examples
const pokemon = {
pokemonId: 'pikachu1',
name: 'Pikachu',
types: ['Electric'],
...
}

const validPokemon = pokemonSchema.build(Parser).parse(pokemon)

You can use the TransformedValue generic type (or ValidValue if transform is set to false) to explicitly type an object as a parsing output object:

import type { TransformedValue } from 'dynamodb-toolbox/schema'

const parsedKey: TransformedValue<
typeof pokemonSchema,
// 👇 Optional options
{ mode: 'key' }
// ❌ Throws a type error
> = { invalid: 'input' }

reparse(...)

(input: InputValue<SCHEMA>, options?: ParseValueOptions) => ParsingResults<SCHEMA>

Similar to .parse, but with the input correctly typed (taking the mode into account) instead of unknown:

pokemonSchema
.build(Parser)
// ❌ Throws a type error
.reparse({ invalid: 'input' })

You can use the InputValue generic type (or ValidValue if fill is set to false) to explicitly type an object as a parsing input object:

import type { InputValue } from 'dynamodb-toolbox/schema'

const keyInput: InputValue<
typeof pokemonSchema,
// 👇 Optional options
{ mode: 'key' }
// ❌ Throws a type error
> = { invalid: 'input' }

start(...)

(input: unknown, options?: ParseValueOptions) => Generator<ParsingResults<SCHEMA>>

Similar to .parse, but returns the underlying Generator to inspect the intermediate results of the parsing steps:

Examples
const parsingGenerator = pokemonSchema
.build(Parser)
.start(pokemon)

const defaultedPokemon = parsingGenerator.next().value
const linkedPokemon = parsingGenerator.next().value
const parsedPokemon = parsingGenerator.next().value
const transformedPokemon = parsingGenerator.next().value

validate(...)

(input: unknown, options?: ValidationOptions) => boolean

Runs only the parsing step of the parsing workflow on the provided input. Returns true if the input is valid, catches any parsing error and returns false otherwise:

const isValid = pokemonSchema.build(Parser).validate(input)

Note that .validate(...) acts as a type guard:

if (pokemonSchema.build(Parser).validate(input)) {
// 🙌 Typed as `Pokemon`!
const { level, name } = input
...
}

Available options:

OptionTypeDefaultDescription
modeput, key or updateputThe mode of the parsing: Impacts requiredness during validation.
parseExtension(internal)-Dependency injection required to parse extended syntax ($get, $add etc.) when using the update mode (check example below).
Examples
const pokemon = {
pokemonId: 'pikachu1',
name: 'Pikachu',
types: ['Electric'],
...
}

const isValid = pokemonSchema.build(Parser).validate(pokemon)