Skip to content

gaslamp


Variable: FlameWright

const FlameWright: object

Factory functions and schema utilities for composing type validators.

The "Wright" in FlameWright means craftsman — this object is the craftsman that builds Flame schemas used by FlameFrame for validation.

Combines the roles of FlameFactory and FlameForge from v1 into a single object. Factory methods create parameterized validators; schema methods build and compose object validators.

Factory

arrayOf, mapOf, recordOf, enumOf, instanceOf, inRange, anyOf, nullable

Schema

fromSchema, partial, extend

Type Declaration

Flame

arrayOf

readonly arrayOf: \<T>(guard) => (value) => value is T[]

Create a validator for arrays of a specific element type.

Type Parameters
T

T

Parameters
guard

Flame\<T>

Validator for each array element

Returns

Type guard that checks if value is an array of T

(value) => value is T[]

Example
TypeScript
const isStringArray = FlameWright.arrayOf(FlameGuards.isString);
isStringArray(["a", "b"]); // true
isStringArray([1, 2]);     // false

mapOf

readonly mapOf: \<K, V>(keyGuard, valueGuard) => (value) => value is Map<K, V>

Create a validator for Maps with specific key and value types.

Type Parameters
K

K

V

V

Parameters
keyGuard

Flame\<K>

Validator for each Map key

valueGuard

Flame\<V>

Validator for each Map value

Returns

Type guard that checks if value is Map<K, V>

(value) => value is Map<K, V>

Example
TypeScript
const isIndex = FlameWright.mapOf(FlameGuards.isString, FlameGuards.isNumber);
isIndex(new Map([["a", 1]])); // true
isIndex(new Map([[1, "a"]])); // false

recordOf

readonly recordOf: \<V>(valueGuard) => (value) => value is Record<string, V>

Create a validator for plain objects with string keys and specific value types.

Type Parameters
V

V

Parameters
valueGuard

Flame\<V>

Validator for each object value

Returns

Type guard that checks if value is Record<string, V>

(value) => value is Record<string, V>

Example
TypeScript
const isStringRecord = FlameWright.recordOf(FlameGuards.isString);
isStringRecord({ a: "x", b: "y" }); // true
isStringRecord({ a: 1 });            // false

enumOf

readonly enumOf: \<T>(values) => (value) => value is T

Create a validator that checks membership in a fixed set of literal values.

Type Parameters
T

T extends string | number

Parameters
values

readonly T[]

Allowed values (use as const to preserve literal types)

Returns

Type guard that checks if value is one of T

(value) => value is T

Example
TypeScript
const isStatus = FlameWright.enumOf(["active", "inactive"] as const);
isStatus("active");   // true
isStatus("deleted");  // false

instanceOf

readonly instanceOf: \<T>(ctor) => Flame\<T>

Create a validator that checks if a value is an instance of a constructor.

Type Parameters
T

T

Parameters
ctor

(...args) => T

Constructor function to check against

Returns

Flame\<T>

Type guard that checks if value is an instance of T

Remarks

GAS Limitation: This guard uses instanceof, which may return false when the value was created in a different script context. This is a known limitation in Google Apps Script when working across script boundaries (e.g., library scripts, container-bound scripts, or different property values).

For built-in types, prefer type-specific guards:

  • Use FlameGuards.isValidDate instead of instanceOf(Date)
  • Use FlameGuards.isMap instead of instanceOf(Map)
  • Use FlameGuards.isArray instead of instanceOf(Array)

These alternatives use Object.prototype.toString and are safe across script boundaries.

Example
TypeScript
// Avoid (may fail across script boundaries):
const isDate = FlameWright.instanceOf(Date);

// Prefer instead:
const isDate = FlameGuards.isValidDate;

inRange

readonly inRange: (min, max?) => Flame\<number>

Create a validator for numbers within an inclusive range. If max is omitted, only checks that the value is >= min.

Parameters
min

number

Minimum allowed value (inclusive)

max?

number

Maximum allowed value (inclusive, optional)

Returns

Flame\<number>

Type guard that checks if value is a number in range

Example
TypeScript
const isPercent = FlameWright.inRange(0, 100);
isPercent(50);  // true
isPercent(101); // false

const isPositive = FlameWright.inRange(0);
isPositive(999); // true

anyOf

readonly anyOf: \<T>(guards) => Flame\<T>

Create a validator that passes if any of the given guards pass (union type).

Type Parameters
T

T

Parameters
guards

Flame\<T>[]

Array of validators to try

Returns

Flame\<T>

Type guard that passes if at least one guard passes

Example
TypeScript
const isStringOrNumber = FlameWright.anyOf([
  FlameGuards.isString,
  FlameGuards.isNumber,
]);
isStringOrNumber("a"); // true
isStringOrNumber(1);   // true
isStringOrNumber(null); // false

nullable

readonly nullable: \<T>(guard) => Flame\<T | null>

Create a validator that accepts the original type or null.

Type Parameters
T

T

Parameters
guard

Flame\<T>

Validator for the non-null case

Returns

Flame\<T | null>

Type guard that checks if value is T | null

Example
TypeScript
const nullableString = FlameWright.nullable(FlameGuards.isString);
nullableString(null);  // true
nullableString("abc"); // true
nullableString(123);   // false

fromSchema

readonly fromSchema: \<T>(schema) => Flame\<T>

Create a type guard from an object schema.

Type Parameters
T

T extends Record\<string, unknown>

Parameters
schema

FlameRecord\<T>

Object mapping each key to its Flame validator

Returns

Flame\<T>

Type guard that checks if value matches the schema shape

Example
TypeScript
const isUser = FlameWright.fromSchema({
  name: FlameGuards.isString,
  age: FlameGuards.isNumber,
});
isUser({ name: "Alice", age: 30 }); // true
isUser({ name: "Bob" });            // false (age missing)

partial

readonly partial: \<T>(schema) => FlameRecord\<Partial\<T>>

Make all fields of a schema optional (allow undefined for each key).

Type Parameters
T

T extends Record\<string, unknown>

Parameters
schema

FlameRecord\<T>

Original schema to make partial

Returns

FlameRecord\<Partial\<T>>

New schema where each field accepts T[K] | undefined

Remarks

Creates a new schema validator that accepts objects where any field may be undefined. Use fromSchema(partial(schema)) to validate objects with optional fields.

Example
TypeScript
const userSchema = {
  name: FlameGuards.isString,
  age: FlameGuards.isNumber,
};
const partialUser = FlameWright.partial(userSchema);
const isPartialUser = FlameWright.fromSchema(partialUser);

isPartialUser({ name: "Alice" });           // true (age is optional)
isPartialUser({});                          // true (all fields optional)
isPartialUser({ name: "Bob", age: 30 });    // true
isPartialUser({ name: "Charlie", age: "thirty" }); // false (age invalid)

extend

readonly extend: \<A, B>(base, extra) => FlameRecord\<A & B>

Merge two schemas into one combined schema.

Type Parameters
A

A extends Record\<string, unknown>

B

B extends Record\<string, unknown>

Parameters
base

FlameRecord\<A>

Base schema

extra

FlameRecord\<B>

Additional schema to merge in

Returns

FlameRecord\<A & B>

Combined schema with all fields from both

Remarks

If the same key appears in both schemas, the value from extra takes precedence (shallow merge). This allows extending or overriding validators from a base schema.

Example
TypeScript
const nameSchema = { name: FlameGuards.isString };
const ageSchema  = { age: FlameGuards.isNumber };
const isUser = FlameWright.fromSchema(
  FlameWright.extend(nameSchema, ageSchema)
);
isUser({ name: "Alice", age: 30 }); // true

// Overriding a validator
const strictAge = { age: FlameWright.inRange(0, 150) };
const isStrictUser = FlameWright.fromSchema(
  FlameWright.extend(nameSchema, strictAge)
);
isStrictUser({ name: "Alice", age: 30 });   // true
isStrictUser({ name: "Bob", age: 999 });    // false (age out of range)

Example

TypeScript
// Factory: typed array validator
const isStringArray = FlameWright.arrayOf(FlameGuards.isString);
isStringArray(["a", "b"]); // true

// Schema: object validator
const isUser = FlameWright.fromSchema({
  name: FlameGuards.isString,
  age: FlameGuards.isNumber,
});
isUser({ name: "Alice", age: 30 }); // true

See

FlameGuards - Predefined guards to use as arguments

Since

0.37.0