UNPKG

inngest

Version:

Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.

196 lines (168 loc) 8.12 kB
/** * This is a rip of the `Jsonify` type from the `type-fest` package. It's used * to represent to users how a value will be serialized and deserialized as it * passes to and from an Inngest Server. * * We do not use the `type-fest` package directly due to some version * compatibility issues: * * - `inngest` supports `typescript@>=4.7` * - `type-fest@4` supports `typescript@>=5.1`, so the maximum version we can * use is `type-fest@3` * - `type-fest@3` is not compatible with `typescript@5.4` */ import { type IsAny, type IsLiteral, type IsNever, type IsUnknown, type KnownKeys, type Simplify } from "./types.js"; type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol; type NeverToNull<T> = IsNever<T> extends true ? null : T; type UnknownArray = readonly unknown[]; type JsonifyList<T extends UnknownArray> = T extends readonly [] ? [] : T extends readonly [infer F, ...infer R] ? [NeverToNull<Jsonify<F>>, ...JsonifyList<R>] : IsUnknown<T[number]> extends true ? [] : Array<T[number] extends NotJsonable ? null : Jsonify<T[number]>>; type FilterJsonableKeys<T extends object> = { [Key in keyof T]: T[Key] extends NotJsonable ? never : Key; }[keyof T]; /** JSON serialize objects (not including arrays) and classes. */ type JsonifyObject<T extends object> = { [Key in keyof Pick<T, FilterJsonableKeys<T>>]: Jsonify<T[Key]>; }; /** Matches the hidden `Infinity` type. Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript. @see NegativeInfinity */ export type PositiveInfinity = 1e999; /** Matches the hidden `-Infinity` type. Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript. @see PositiveInfinity */ export type NegativeInfinity = -1e999; /** Matches a JSON object. This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`. */ export type JsonObject = { [Key in string]: JsonValue; } & { [Key in string]?: JsonValue | undefined; }; /** Matches a JSON array. */ export type JsonArray = JsonValue[] | readonly JsonValue[]; /** Matches any valid JSON primitive value. */ export type JsonPrimitive = string | number | boolean | null; /** Matches any valid JSON value. @see `Jsonify` if you need to transform a type to one that is assignable to `JsonValue`. */ export type JsonValue = JsonPrimitive | JsonObject | JsonArray; declare const emptyObjectSymbol: unique symbol; /** Represents a strictly empty plain object, the `{}` value. When you annotate something as the type `{}`, it can be anything except `null` and `undefined`. This means that you cannot use `{}` to represent an empty plain object ([read more](https://stackoverflow.com/questions/47339869/typescript-empty-object-and-any-difference/52193484#52193484)). @example ``` import type {EmptyObject} from 'type-fest'; // The following illustrates the problem with `{}`. const foo1: {} = {}; // Pass const foo2: {} = []; // Pass const foo3: {} = 42; // Pass const foo4: {} = {a: 1}; // Pass // With `EmptyObject` only the first case is valid. const bar1: EmptyObject = {}; // Pass const bar2: EmptyObject = 42; // Fail const bar3: EmptyObject = []; // Fail const bar4: EmptyObject = {a: 1}; // Fail ``` Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<never, never>` do not work. See {@link https://github.com/sindresorhus/type-fest/issues/395}. */ export type EmptyObject = { [emptyObjectSymbol]?: never; }; /** Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`. */ export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array; type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol ? never : Type[Key] extends symbol ? never : { name: string; } extends Type[Key] ? Key : [(...arguments_: any[]) => any] extends [Type[Key]] ? never : Key; /** Returns the required keys. */ type FilterDefinedKeys<T extends object> = Exclude<{ [Key in keyof T]: IsAny<T[Key]> extends true ? Key : IsUnknown<T[Key]> extends true ? Key : undefined extends T[Key] ? never : T[Key] extends undefined ? never : BaseKeyFilter<T, Key>; }[keyof T], undefined>; /** Returns the optional keys. */ type FilterOptionalKeys<T extends object> = Exclude<{ [Key in keyof T]: IsAny<T[Key]> extends true ? never : undefined extends T[Key] ? T[Key] extends undefined ? never : BaseKeyFilter<T, Key> : never; }[keyof T], undefined>; /** For an object T, if it has any properties that are a union with `undefined`, make those into optional properties instead. @example ``` type User = { firstName: string; lastName: string | undefined; }; type OptionalizedUser = UndefinedToOptional<User>; //=> { // firstName: string; // lastName?: string; // } ``` */ export type UndefinedToOptional<T extends object> = Simplify<{ [Key in keyof Pick<T, FilterDefinedKeys<T>>]: T[Key]; } & { [Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>; }>; /** Transform a type to one that is assignable to the `JsonValue` type. This includes: 1. Transforming JSON `interface` to a `type` that is assignable to `JsonValue`. 2. Transforming non-JSON value that is *jsonable* to a type that is assignable to `JsonValue`, where *jsonable* means the non-JSON value implements the `.toJSON()` method that returns a value that is assignable to `JsonValue`. @remarks An interface cannot be structurally compared to `JsonValue` because an interface can be re-opened to add properties that may not be satisfy `JsonValue`. @example ``` import type {Jsonify, JsonValue} from 'type-fest'; interface Geometry { type: 'Point' | 'Polygon'; coordinates: [number, number]; } const point: Geometry = { type: 'Point', coordinates: [1, 1] }; const problemFn = (data: JsonValue) => { // Does something with data }; problemFn(point); // Error: type Geometry is not assignable to parameter of type JsonValue because it is an interface const fixedFn = <T>(data: Jsonify<T>) => { // Does something with data }; fixedFn(point); // Good: point is assignable. Jsonify<T> transforms Geometry into value assignable to JsonValue fixedFn(new Date()); // Error: As expected, Date is not assignable. Jsonify<T> cannot transforms Date into value assignable to JsonValue ``` Non-JSON values such as `Date` implement `.toJSON()`, so they can be transformed to a value assignable to `JsonValue`: @example ``` import type {Jsonify} from 'type-fest'; const time = { timeValue: new Date() }; // `Jsonify<typeof time>` is equivalent to `{timeValue: string}` const timeJson = JSON.parse(JSON.stringify(time)) as Jsonify<typeof time>; ``` {@link https://github.com/Microsoft/TypeScript/issues/1897#issuecomment-710744173} */ export type Jsonify<T> = IsAny<T> extends true ? any : IsUnknown<T> extends true ? unknown : T extends PositiveInfinity | NegativeInfinity ? null : T extends JsonPrimitive ? T : T extends { toJSON(): infer J; } ? (() => J) extends () => JsonValue ? J : Jsonify<J> : T extends Number ? number : T extends String ? string : T extends Boolean ? boolean : T extends Map<any, any> | Set<any> ? EmptyObject : T extends TypedArray ? Record<string, number> : T extends NotJsonable ? never : T extends UnknownArray ? JsonifyList<T> : T extends object ? IsLiteral<keyof T> extends true ? JsonifyObject<UndefinedToOptional<T>> : Simplify<JsonifyObject<UndefinedToOptional<T>> & JsonifyObject<UndefinedToOptional<Pick<T, KnownKeys<T>>>>> : never; export {}; //# sourceMappingURL=jsonify.d.ts.map