CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-xyo-network--payload-model

Core payload modeling capabilities for the XYO Protocol 2.0 ecosystem, offering TypeScript interfaces and types for defining, validating, and manipulating payloads within the XYO blockchain network.

Overview
Eval results
Files

type-guards.mddocs/

Type Guards and Validation

Runtime validation functions for payload structure verification and type narrowing, including schema-specific type guards and comprehensive validation utilities for ensuring payload integrity.

Capabilities

Basic Payload Validation

Core functions for validating payload structure and type narrowing at runtime.

/**
 * Type guard to check if a value is any valid payload
 * @param value - Value to check
 * @returns True if value is a payload with schema property
 */
function isAnyPayload(value: unknown): value is Payload;

/**
 * Type assertion factory for any payload
 * @param value - Value to assert as payload
 * @returns Value cast as Payload or throws error
 */
function asAnyPayload(value: unknown): Payload;

/**
 * Higher-order function to create type guards for specific schemas
 * @param schema - Array of schema strings to validate against
 * @returns Type guard function for the specified schemas
 */
function isPayload<T extends Payload>(schema: string[]): (value: unknown) => value is T;

/**
 * Higher-order function to create type assertion factories for specific schemas
 * @param schema - Array of schema strings to validate against
 * @returns Type assertion function for the specified schemas
 */
function asPayload<T extends Payload>(schema: string[]): (value: unknown) => T;

Usage Examples:

import { isAnyPayload, asAnyPayload, isPayload } from "@xyo-network/payload-model";

// Check if value is any payload
const data: unknown = { schema: "network.example.test", message: "hello" };

if (isAnyPayload(data)) {
  // TypeScript knows data is a Payload
  console.log(data.schema);
}

// Create specific schema validators
const isUserPayload = isPayload<UserPayload>(["network.example.user"]);
const isProductPayload = isPayload<ProductPayload>(["network.example.product"]);

// Validate multiple schemas
const isValidPayload = isPayload([
  "network.example.user",
  "network.example.product",
  "network.example.order"
]);

const unknownPayload: unknown = {
  schema: "network.example.user",
  name: "Alice",
  email: "alice@example.com"
};

if (isUserPayload(unknownPayload)) {
  // TypeScript knows this is UserPayload
  console.log(unknownPayload.name);
}

// Type assertion
try {
  const payload = asAnyPayload(data);
  console.log("Valid payload:", payload.schema);
} catch (error) {
  console.error("Invalid payload");
}

Schema-Specific Type Guards

Advanced type guards for specific schema validation and type narrowing with enhanced type safety.

/**
 * Creates a type guard for a specific schema type
 * @param schema - The schema string to validate against
 * @returns Type guard function that narrows to the specific payload type
 */
function isPayloadOfSchemaType<T extends Payload | never = never>(
  schema: T['schema']
): (x?: unknown | null) => x is T;

/**
 * Creates a type guard for payloads with sources metadata
 * @param schema - The schema string to validate against
 * @returns Type guard function for payload with sources
 */
function isPayloadOfSchemaTypeWithSources<T extends Payload | never = never>(
  schema: T['schema']
): (x?: unknown | null) => x is WithSources<T>;

/**
 * Creates a negated type guard (returns true if NOT the specified schema)
 * @param schema - The schema string to validate against
 * @returns Type guard function that returns true if payload is NOT the specified schema
 */
function notPayloadOfSchemaType<T extends Payload | never = never>(
  schema: T['schema']
): (x?: unknown | null) => x is T;

Usage Examples:

import { 
  isPayloadOfSchemaType, 
  isPayloadOfSchemaTypeWithSources,
  notPayloadOfSchemaType 
} from "@xyo-network/payload-model";

// Define specific payload types
const UserSchema = "network.example.user" as const;
const ProductSchema = "network.example.product" as const;

interface UserPayload extends Payload {
  schema: typeof UserSchema;
  name: string;
  email: string;
}

interface ProductPayload extends Payload {
  schema: typeof ProductSchema;
  name: string;
  price: number;
}

// Create schema-specific type guards
const isUserPayload = isPayloadOfSchemaType<UserPayload>(UserSchema);
const isProductPayload = isPayloadOfSchemaType<ProductPayload>(ProductSchema);
const isUserWithSources = isPayloadOfSchemaTypeWithSources<UserPayload>(UserSchema);

// Usage in filtering
const payloads: Payload[] = [
  { schema: UserSchema, name: "Alice", email: "alice@example.com" },
  { schema: ProductSchema, name: "Laptop", price: 999 },
  { schema: UserSchema, name: "Bob", email: "bob@example.com" }
];

// Filter to specific payload types
const userPayloads = payloads.filter(isUserPayload);
const productPayloads = payloads.filter(isProductPayload);

// Type narrowing in conditionals
const unknownPayload: unknown = { 
  schema: UserSchema, 
  name: "Charlie", 
  email: "charlie@example.com" 
};

if (isUserPayload(unknownPayload)) {
  // TypeScript knows this is UserPayload
  console.log(`User: ${unknownPayload.name} (${unknownPayload.email})`);
}

// Check for payloads with sources
const payloadWithSources: unknown = {
  schema: UserSchema,
  name: "David",
  email: "david@example.com",
  $sources: ["0x123..."]
};

if (isUserWithSources(payloadWithSources)) {
  // TypeScript knows this has $sources array
  console.log(`User with ${payloadWithSources.$sources.length} sources`);
}

// Negated validation
const nonUserPayloads = payloads.filter(notPayloadOfSchemaType(UserSchema));

Schema Validation

Direct schema validation functions for string-based schema checking.

/**
 * Type guard to validate schema string format
 * @param value - Value to check as schema
 * @returns True if value matches schema regex pattern
 */
function isSchema(value: unknown): value is Schema;

/**
 * Type assertion for schema strings
 * @param value - Value to assert as schema
 * @returns Value cast as Schema or throws error
 */
function asSchema(value: unknown): Schema;

Usage Examples:

import { isSchema, asSchema } from "@xyo-network/payload-model";

// Validate schema format
const possibleSchema = "network.example.test";

if (isSchema(possibleSchema)) {
  // TypeScript knows this is a valid Schema
  console.log("Valid schema:", possibleSchema);
}

// Schema format validation
const schemas = [
  "network.xyo.payload",           // Valid
  "network.example.user",          // Valid  
  "invalid.schema.format.123",     // May be invalid depending on regex
  "network..empty.segment",        // Invalid
  "UPPERCASE.SCHEMA"               // Invalid (must be lowercase)
];

const validSchemas = schemas.filter(isSchema);
console.log("Valid schemas:", validSchemas);

// Type assertion
try {
  const schema = asSchema("network.example.valid");
  console.log("Schema:", schema);
} catch (error) {
  console.error("Invalid schema format");
}

// Dynamic schema validation
function createPayload(schemaStr: string, data: any) {
  if (isSchema(schemaStr)) {
    return {
      schema: schemaStr,
      ...data
    };
  }
  throw new Error("Invalid schema format");
}

Validation Utilities

Additional validation utilities for working with payload collections and advanced validation scenarios.

/**
 * Type assertion factory that creates validation functions
 */
const AsObjectFactory: {
  create<T>(guard: (value: unknown) => value is T): (value: unknown) => T;
  createOptional<T>(guard: (value: unknown) => value is T): (value: unknown) => T | undefined;
};

Usage Examples:

import { AsObjectFactory, isPayloadOfSchemaType } from "@xyo-network/payload-model";

// Create custom assertion functions
const UserSchema = "network.example.user" as const;
interface UserPayload extends Payload {
  schema: typeof UserSchema;
  name: string;
  email: string;
}

const isUserPayload = isPayloadOfSchemaType<UserPayload>(UserSchema);
const asUserPayload = AsObjectFactory.create(isUserPayload);
const asOptionalUserPayload = AsObjectFactory.createOptional(isUserPayload);

// Use assertions
const data: unknown = {
  schema: UserSchema,
  name: "Alice",
  email: "alice@example.com"
};

try {
  const userPayload = asUserPayload(data);
  console.log("User:", userPayload.name);
} catch (error) {
  console.error("Not a valid user payload");
}

// Optional assertion (returns undefined instead of throwing)
const optionalUser = asOptionalUserPayload(data);
if (optionalUser) {
  console.log("Optional user:", optionalUser.name);
}

// Process arrays with validation
const payloadData: unknown[] = [
  { schema: UserSchema, name: "Alice", email: "alice@example.com" },
  { schema: "network.example.product", name: "Laptop", price: 999 },
  { invalid: "data" }
];

const validUsers = payloadData
  .map(asOptionalUserPayload)
  .filter((user): user is UserPayload => user !== undefined);

console.log("Valid users:", validUsers.length);

Advanced Usage Patterns

Payload Type Discrimination

import { 
  isPayloadOfSchemaType, 
  Payload 
} from "@xyo-network/payload-model";

// Define multiple payload types
const UserSchema = "network.example.user" as const;
const ProductSchema = "network.example.product" as const;
const OrderSchema = "network.example.order" as const;

interface UserPayload extends Payload {
  schema: typeof UserSchema;
  name: string;
  email: string;
}

interface ProductPayload extends Payload {
  schema: typeof ProductSchema;
  name: string;
  price: number;
}

interface OrderPayload extends Payload {
  schema: typeof OrderSchema;
  userId: string;
  productIds: string[];
  total: number;
}

// Create discriminated union
type AppPayload = UserPayload | ProductPayload | OrderPayload;

// Create type guards
const isUserPayload = isPayloadOfSchemaType<UserPayload>(UserSchema);
const isProductPayload = isPayloadOfSchemaType<ProductPayload>(ProductSchema);
const isOrderPayload = isPayloadOfSchemaType<OrderPayload>(OrderSchema);

// Process different payload types
function processPayload(payload: AppPayload) {
  if (isUserPayload(payload)) {
    return `User: ${payload.name}`;
  } else if (isProductPayload(payload)) {
    return `Product: ${payload.name} - $${payload.price}`;
  } else if (isOrderPayload(payload)) {
    return `Order: ${payload.productIds.length} items - $${payload.total}`;
  }
  
  // TypeScript ensures exhaustive checking
  const _exhaustiveCheck: never = payload;
  return _exhaustiveCheck;
}

Types Reference

Type Guard Functions

  • isAnyPayload(value): Check if value is any payload
  • isPayload<T>(schemas): Create schema-specific type guard
  • isPayloadOfSchemaType<T>(schema): Create single schema type guard
  • isPayloadOfSchemaTypeWithSources<T>(schema): Type guard with sources validation
  • notPayloadOfSchemaType<T>(schema): Negated schema type guard
  • isSchema(value): Validate schema string format

Assertion Functions

  • asAnyPayload(value): Assert value as any payload
  • asPayload<T>(schemas): Create schema-specific assertion
  • asSchema(value): Assert value as schema string

Utility Functions

  • AsObjectFactory.create<T>(guard): Create assertion function from type guard
  • AsObjectFactory.createOptional<T>(guard): Create optional assertion function

Install with Tessl CLI

npx tessl i tessl/npm-xyo-network--payload-model

docs

bundles-queries.md

core-payload-types.md

index.md

storage-metadata.md

type-guards.md

utility-types.md

validation-errors.md

tile.json