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.
Runtime validation functions for payload structure verification and type narrowing, including schema-specific type guards and comprehensive validation utilities for ensuring payload integrity.
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");
}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));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");
}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);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;
}isAnyPayload(value): Check if value is any payloadisPayload<T>(schemas): Create schema-specific type guardisPayloadOfSchemaType<T>(schema): Create single schema type guardisPayloadOfSchemaTypeWithSources<T>(schema): Type guard with sources validationnotPayloadOfSchemaType<T>(schema): Negated schema type guardisSchema(value): Validate schema string formatasAnyPayload(value): Assert value as any payloadasPayload<T>(schemas): Create schema-specific assertionasSchema(value): Assert value as schema stringAsObjectFactory.create<T>(guard): Create assertion function from type guardAsObjectFactory.createOptional<T>(guard): Create optional assertion functionInstall with Tessl CLI
npx tessl i tessl/npm-xyo-network--payload-model