@camunda8/sdk
Version:
[](https://www.npmjs.com/package/@camunda8/sdk)
152 lines (151 loc) • 6.1 kB
TypeScript
/**
* This is a custom JSON Parser that handles lossless parsing of int64 numbers by using the lossless-json library.
*
* This is motivated by the use of int64 for Camunda 8 Entity keys, which are not supported by JavaScript's Number type.
* Variables could also contain unsafe large integers if an external system sends them to the broker.
*
* It converts all JSON numbers to lossless numbers, then converts them back to the correct type based on the metadata
* of a Dto class - fields decorated with `@Int64` are converted to a `string`, fields decorated with `@BigIntValue` are
* converted to `bigint`. All other numbers are converted to `number`. Throws if a number cannot be safely converted.
*
* It also handles nested Dtos by using the `@ChildDto` decorator.
*
* Update: added an optional `key` parameter to support the Camunda 8 REST API's use of an array under a key, e.g. { jobs : Job[] }
*
* Note: the parser uses DTO classes that extend the LosslessDto class to perform mappings of numeric types. However, only the type of
* the annotated numerics is type-checked at runtime. Fields of other types are not checked.
*
* More details on the design here: https://github.com/camunda/camunda-8-js-sdk/issues/81#issuecomment-2022213859
*
* See this article to understand why this is necessary: https://jsoneditoronline.org/indepth/parse/why-does-json-parse-corrupt-large-numbers/
*/
import 'reflect-metadata';
/**
* Decorate Dto string fields as `@Int64String` to specify that the JSON number property should be parsed as a string.
* @example
* ```typescript
* class MyDto extends LosslessDto {
* @Int64String
* int64NumberField!: string
* @BigIntValue
* bigintField!: bigint
* @ChildDto(MyChildDto)
* childDtoField!: MyChildDto
* normalField!: string
* normalNumberField!: number
* maybePresentField?: string
* }
* ```
*/
export declare function Int64String(target: any, propertyKey: string | symbol): void;
/**
* Decorate Dto string fields as `@Int64StringArray` to specify that the array of JSON numbers should be parsed as an array of strings.
* @example
* ```typescript
* class Dto extends LosslessDto {
* message!: string
* userId!: number
* @Int64StringArray
* sendTo!: string[]
* }
*/
export declare function Int64StringArray(target: any, propertyKey: string | symbol): void;
/**
* Decorate Dto bigint fields as `@BigIntValue` to specify that the JSON number property should be parsed as a bigint.
* @example
* ```typescript
* class MyDto extends LosslessDto {
* @Int64String
* int64NumberField!: string
* @BigIntValue
* bigintField!: bigint
* @ChildDto(MyChildDto)
* childDtoField!: MyChildDto
* normalField!: string
* normalNumberField!: number
* maybePresentField?: string
* }
* ```
*/
export declare function BigIntValue(target: any, propertKey: string | symbol): void;
/**
* Decorate Dto bigint fields as `@BigIntValueArray` to specify that the JSON number property should be parsed as a bigint.
* @example
* ```typescript
* class MyDto extends LosslessDto {
* @Int64String
* int64NumberField!: string
* @BigIntValueArray
* bigintField!: bigint[]
* @ChildDto(MyChildDto)
* childDtoField!: MyChildDto
* normalField!: string
* normalNumberField!: number
* maybePresentField?: string
* }
* ```
*/
export declare function BigIntValueArray(target: any, propertKey: string | symbol): void;
/**
* Decorate a Dto object field as `@ChildDto` to specify that the JSON object property should be parsed as a child Dto.
* @example
* ```typescript
*
* class MyChildDto extends LosslessDto {
* someField!: string
* }
*
* class MyDto extends LosslessDto {
* @Int64String
* int64NumberField!: string
* @BigIntValue
* bigintField!: bigint
* @ChildDto(MyChildDto)
* childDtoField!: MyChildDto
* normalField!: string
* normalNumberField!: number
* maybePresentField?: string
* }
*/
export declare function ChildDto(childClass: any): (target: any, propertyKey: string | symbol) => void;
/**
* Extend the `LosslessDto` class with your own Dto classes to enable lossless parsing of JSON `int64` values.
* These are Java `long` numbers with values that are not supported by JavaScript's `Number` type.
* The SDK uses the lossless-json library to parse all JSON numbers as `LosslessNumber` type.
* This allows us to safely parse large numbers without losing precision.
* Decorate fields with `@Int64String` or `@BigIntValue` to specify how known `int64` JSON numbers should be parsed
* — either as a string or a bigint.
*
* Prior to Camunda 8.7, the REST API returned entity keys as `int64` numbers. From 8.7, the broker returns them as strings. LosslessDtos are
* used to normalise this difference. It can also be used to parse large numbers in headers and variables, enabling lossless parsing of
* large numbers in applications that use the SDK.
* @example
* This example is a Dto class that handles two int64 fields, decoding one as a `string` and one as a `bigint`.
* It also has a child Dto field and some normal fields.
* The child Dto is parsed as a `LosslessDto`, so it can also have `int64` fields. For more complex Dtos, see the implementations in the SDK.
* ```typescript
* class MyDto extends LosslessDto {
* @Int64String
* int64NumberField: string
* @BigIntValue
* bigintField: bigint
* @ChildDto(MyChildDto)
* childDtoField: MyChildDto
* normalField: string
* normalNumberField: number
* }
* ```
*/
export declare class LosslessDto {
}
/**
* losslessParse uses lossless-json parse to deserialize JSON.
* With no Dto, the parser will throw if it encounters an int64 number that cannot be safely represented as a JS number.
*
* @param json the JSON string to parse
* @param dto an annotated Dto class to parse the JSON string with
*/
export declare function losslessParse<T = any>(json: string, dto?: {
new (...args: any[]): T;
}, keyToParse?: string): T;
export declare function losslessStringify<T extends LosslessDto>(obj: T, isTopLevel?: boolean): string;