/** * Validates a datetime string against RFC 3339/ISO 8601 format. * Timezone is required; whole seconds minimum with optional fractional precision. * @see https://atproto.com/specs/lexicon - datetime format * @param {string} value - The datetime string to validate * @returns {boolean} True if valid datetime format */ export function isValidDatetime(value: string): boolean; /** * Validates a handle identifier. * Handles are DNS hostnames with specific constraints: * - Max 253 characters total * - At least 2 labels separated by periods * - Labels: 1-63 chars, alphanumeric and hyphens, can't start/end with hyphen * - TLD can't start with digit; certain TLDs are disallowed * @see https://atproto.com/specs/handle * @param {string} value - The handle to validate * @returns {boolean} True if valid handle format */ export function isValidHandle(value: string): boolean; /** * Validates a Decentralized Identifier (DID). * DIDs follow the pattern: did:[method]:[identifier] * - Starts with lowercase "did:" * - Method: 1+ lowercase letters, followed by ":" * - Identifier: alphanumeric, period, underscore, colon, hyphen, percent-encoded * - Max 2048 characters (AT Protocol limit) * @see https://atproto.com/specs/did * @param {string} value - The DID to validate * @returns {boolean} True if valid DID format */ export function isValidDid(value: string): boolean; /** * Validates a generic URI per RFC 3986. * Scheme is case-insensitive; uppercase accepted for robustness. * Max 8192 characters. * @see https://atproto.com/specs/lexicon - uri format * @param {string} value - The URI to validate * @returns {boolean} True if valid URI format */ export function isValidUri(value: string): boolean; /** * Validates an AT Protocol URI (at://). * Structure: at://AUTHORITY[/COLLECTION[/RKEY]] * - Authority: valid handle or DID (required) * - Collection: valid NSID (optional) * - Record key: valid record-key (optional) * Max 8KB. * @see https://atproto.com/specs/at-uri-scheme * @param {string} value - The AT-URI to validate * @returns {boolean} True if valid AT-URI format */ export function isValidAtUri(value: string): boolean; /** * Validates a Timestamp Identifier (TID). * TIDs are 64-bit integers encoded as 13-character base32-sortable strings. * - Exactly 13 characters * - First char: [234567abcdefghij] (top bit always 0) * - All chars: base32-sortable alphabet (234567abcdefghijklmnopqrstuvwxyz) * @see https://atproto.com/specs/tid * @param {string} value - The TID to validate * @returns {boolean} True if valid TID format */ export function isValidTid(value: string): boolean; /** * Validates a record key. * Record keys can contain: a-z, A-Z, 0-9, period, hyphen, underscore, colon, tilde. * Max 512 characters. Cannot be "." or "..". * @see https://atproto.com/specs/lexicon - record-key format * @param {string} value - The record key to validate * @returns {boolean} True if valid record key format */ export function isValidRecordKey(value: string): boolean; /** * Validates a Content Identifier (CID). * AT Protocol only blesses CIDv1 format (rejects CIDv0 "Qm" prefix). * - 8-256 characters * - Alphanumeric only * - No "Qmb" prefix (CIDv0) * @see https://atproto.com/specs/data-model - CID/Link section * @param {string} value - The CID to validate * @returns {boolean} True if valid CID format */ export function isValidCid(value: string): boolean; /** * Validates a BCP-47 language tag. * Simplified validation: 2-3 letter primary subtag with optional subtags. * Supports grandfathered "i-" prefixed tags. * @see https://atproto.com/specs/lexicon - language format * @param {string} value - The language tag to validate * @returns {boolean} True if valid language tag format */ export function isValidLanguageTag(value: string): boolean; /** * Validates a Namespaced Identifier (NSID). * Structure: reversed-domain.name (e.g., "app.bsky.feed.post") * - Max 317 characters, minimum 3 segments * - Authority (domain): max 253 chars, at least 2 segments, handle-like rules * - Name segment: 1-63 chars, letters and digits only, must start with lowercase letter * @see https://atproto.com/specs/nsid * @param {string} value - The NSID to validate * @returns {boolean} True if valid NSID format */ export function isValidNsid(value: string): boolean; /** * Validates an AT Protocol identifier (handle or DID). * @see https://atproto.com/specs/lexicon - at-identifier format * @param {string} value - The identifier to validate * @returns {boolean} True if valid handle or DID */ export function isValidAtIdentifier(value: string): boolean; /** * Validate lexicon schemas are well-formed. * Validates each definition in each lexicon against the Lexicon specification. * @see https://atproto.com/specs/lexicon * @param {Lexicon[]} lexicons - Array of lexicon JSON objects * @returns {null | Object} null if valid, errors by NSID if invalid * @example * const errors = validateLexicons([myLexicon]); * if (errors) { * console.error('Invalid lexicons:', errors); * } */ export function validateLexicons(lexicons: Lexicon[]): null | { [x: string]: string[]; }; /** * Validate a record against a lexicon schema. * The collection NSID must match a lexicon with a "record" type main definition. * @see https://atproto.com/specs/lexicon - Record type * @param {Lexicon[]} lexicons - Array of lexicon JSON objects * @param {string} collection - NSID of the collection (e.g., "app.bsky.feed.post") * @param {object} record - The record data to validate * @returns {null | {path: string, message: string}} null if valid, error if invalid * @example * const error = validateRecord(lexicons, 'app.bsky.feed.post', postData); * if (error) { * console.error(`Validation error at ${error.path}: ${error.message}`); * } */ export function validateRecord(lexicons: Lexicon[], collection: string, record: object): null | { path: string; message: string; }; export function defineLexicon(lex: T): T; export type LexiconFormat = "datetime" | "uri" | "at-uri" | "did" | "handle" | "at-identifier" | "nsid" | "cid" | "language" | "tid" | "record-key"; export type LexiconStringSchema = { type: "string"; description?: string | undefined; minLength?: number | undefined; maxLength?: number | undefined; minGraphemes?: number | undefined; maxGraphemes?: number | undefined; format?: LexiconFormat | undefined; enum?: string[] | undefined; const?: string | undefined; knownValues?: string[] | undefined; default?: string | undefined; }; export type LexiconIntegerSchema = { type: "integer"; description?: string | undefined; minimum?: number | undefined; maximum?: number | undefined; enum?: number[] | undefined; const?: number | undefined; default?: number | undefined; }; export type LexiconBooleanSchema = { type: "boolean"; description?: string | undefined; const?: boolean | undefined; default?: boolean | undefined; }; export type LexiconObjectSchema = { type: "object"; description?: string | undefined; properties?: { [x: string]: LexiconSchema; } | undefined; required?: string[] | undefined; nullable?: string[] | undefined; }; export type LexiconArraySchema = { type: "array"; description?: string | undefined; items: LexiconSchema; minLength?: number | undefined; maxLength?: number | undefined; }; export type LexiconRefSchema = { type: "ref"; description?: string | undefined; ref: string; }; export type LexiconUnionSchema = { type: "union"; description?: string | undefined; refs: string[]; closed?: boolean | undefined; }; export type LexiconBlobSchema = { type: "blob"; description?: string | undefined; accept?: string[] | undefined; maxSize?: number | undefined; }; export type LexiconBytesSchema = { type: "bytes"; description?: string | undefined; minLength?: number | undefined; maxLength?: number | undefined; }; export type LexiconTokenSchema = { type: "token"; description?: string | undefined; }; export type LexiconUnknownSchema = { type: "unknown"; description?: string | undefined; }; export type LexiconCidLinkSchema = { type: "cid-link"; description?: string | undefined; }; export type LexiconNullSchema = { type: "null"; description?: string | undefined; }; export type LexiconSchema = LexiconStringSchema | LexiconIntegerSchema | LexiconBooleanSchema | LexiconObjectSchema | LexiconArraySchema | LexiconRefSchema | LexiconUnionSchema | LexiconBlobSchema | LexiconBytesSchema | LexiconTokenSchema | LexiconUnknownSchema | LexiconCidLinkSchema | LexiconNullSchema; export type LexiconBody = { description?: string | undefined; encoding: string; schema?: LexiconSchema | undefined; }; export type LexiconMessage = { description?: string | undefined; schema?: LexiconSchema | undefined; }; export type LexiconRecordDef = { type: "record"; description?: string | undefined; key?: string | undefined; record: LexiconObjectSchema; }; export type LexiconParamsDef = { type: "params"; description?: string | undefined; properties?: { [x: string]: LexiconSchema; } | undefined; required?: string[] | undefined; }; export type LexiconQueryDef = { type: "query"; description?: string | undefined; parameters?: LexiconObjectSchema | undefined; output?: LexiconBody | undefined; errors?: object[] | undefined; }; export type LexiconProcedureDef = { type: "procedure"; description?: string | undefined; parameters?: LexiconObjectSchema | undefined; input?: LexiconBody | undefined; output?: LexiconBody | undefined; errors?: object[] | undefined; }; export type LexiconSubscriptionDef = { type: "subscription"; description?: string | undefined; parameters?: LexiconObjectSchema | undefined; message?: LexiconMessage | undefined; errors?: object[] | undefined; }; export type LexiconDef = LexiconRecordDef | LexiconQueryDef | LexiconProcedureDef | LexiconSubscriptionDef | LexiconParamsDef | LexiconSchema; export type Lexicon = { lexicon: 1; id: string; revision?: number | undefined; description?: string | undefined; defs: { [x: string]: LexiconDef; }; }; export type ValidationContext = { lexicons: Lexicon[]; currentLexicon: string; path?: string | undefined; }; export type ValidationError = { path: string; message: string; };