/** * Common shared utilities, interfaces, etc. */ import { ApiBlockType, ApiRelationshipType } from "./api-models/base"; import { ApiBlock } from "./api-models/document"; import { ApiDocumentMetadata } from "./api-models/response"; /** * Generic typing for a concrete class constructor to support TypeScript Mixins pattern * * (could use `abstract new` to type abstract base clasess) * * See: https://www.typescriptlang.org/docs/handbook/mixins.html */ export type Constructor = new (...args: any[]) => T; /** * Base class for all classes which wrap over an actual Textract API object. * * Exposes the underlying object for access as `dict`. */ export declare class ApiObjectWrapper { _dict: T; constructor(dict: T); /** * Raw underlying Amazon Textract API object that this parsed item wraps */ get dict(): T; } /** * Basic properties exposed by all classes which wrap over a Textract API `Block` object. */ export interface IApiBlockWrapper { /** * Raw underlying Amazon Textract API `Block` object that this parsed item wraps */ get dict(): T; /** * Unique ID of the underlying Amazon Textract API `Block` object that this parsed item wraps */ get id(): string; /** * Type of underlying Amazon Textract API `Block` object that this parsed item wraps */ get blockType(): ApiBlockType; /** * Dynamic accessor for the unique Block IDs of all CHILD relationships from this Block */ get childBlockIds(): string[]; /** * Fetch the unique Block IDs of this block's `Relationships`, filtered by type(s) * @param relType Only keep IDs corresponding to relations of this type (or list of types) */ relatedBlockIdsByRelType(relType: ApiRelationshipType | ApiRelationshipType[]): string[]; } export interface IWithText { /** * Return the text content of this element (and any child content) * * Unlike `.str()`, this includes only the actual text content and no semantic information. */ get text(): string; } /** * Configurations for filtering rendering (e.g. HTML) by block type * * This interface is designed for general compatibility with `IBlockTypeFilterOpts`, but where the * concept of `onUnexpectedBlockType` may not be applicable. */ export interface IRenderOpts { /** * *Only* render blocks of the given type(s) * * By default, all blocks are returned unless otherwise documented. If you specify this filter, * you probably want to include *at least* ApiBlockType.Line and ApiBlockType.Word! */ includeBlockTypes?: ApiBlockType | ApiBlockType[] | Set | null; /** * Block types to omit from the results */ skipBlockTypes?: ApiBlockType[] | Set | null; } /** * Convenience method to check whether a block type filter spec allows a particular BlockType * * Useful for handling un-normalized arguments where e.g. the whole filter spec may be null, or the * specifiers haven't been normalized to `Set`s. * * @param filterOpts An (un-normalized) filter specification for methods like listContent * @param blockType The block type of interest * @returns false if the block type is explicitly disallowed by skip or include rules, else true */ export declare function doesFilterAllowBlockType(filterOpts: IRenderOpts | null | undefined, blockType: ApiBlockType): boolean; export interface IRenderable extends IWithText { /** * Return a best-effort semantic HTML representation of this element and its content * * @param opts Optional configuration for filtering rendering to certain content types */ html(opts?: IRenderOpts): string; /** * Return a text representation of this element and its content * * Unlike `.text`, this may include additional characters to try and communicate the type of the * element for an overall representation of a page. */ str(): string; } /** * Base for classes which wrap over a Textract API 'Block' object. */ export declare class ApiBlockWrapper extends ApiObjectWrapper implements IApiBlockWrapper { get id(): string; get blockType(): ApiBlockType; get childBlockIds(): string[]; relatedBlockIdsByRelType(relType: ApiRelationshipType | ApiRelationshipType[]): string[]; } /** * Parsed TRP object representing a document metadata descriptor from a Textract API result * * You'll usually create this via `TextractDocument`, `TextractExpense`, `TextractIdentity` * classes, etc - rather than directly. */ export declare class DocumentMetadata extends ApiObjectWrapper { /** * Number of pages in the document, according to the Amazon Textract DocumentMetadata field */ get nPages(): number; } /** * Configuration options for iterating nested lists */ export interface INestedListOpts { /** * Include nested children (true) or top-level items only (false) */ deep?: boolean; } /** * Utility function to create an iterable from a collection * * Input is a collection *fetching function*, rather than a direct collection, in case a user * re-uses the iterable after the parent object is mutated. For example: * * @example * const iterWords = line.iterWords(); // Implemented with getIterable(() => this._words) * let words = [...iterWords]; * line._words = []; * let words = [...iterWords]; // Should return [] as expected */ export declare function getIterable(collectionFetcher: () => T[]): Iterable; /** * Configuration options for escaping text for HTML */ export interface IEscapeHtmlOpts { /** * Set true if escaping within an element attribute * * For standard text nodes, there's no need to escape single or double quotes * @default false; */ forAttr?: boolean; } /** * Escape a document text string for use in HTML (TextNodes only by default) * @param str Raw text to be escaped * @returns Escaped string ready to be used in a HTML document */ export declare function escapeHtml(str: string, { forAttr }?: IEscapeHtmlOpts): string; /** * Configuration options for indenting text */ export interface IIndentOpts { /** * The character/string that should be used to indent text. * * We default to 1x tab (rather than e.g. 2x spaces) to minimize token count for LLM use-cases * * @default "\t" */ character?: string; /** * The number of times the indent `character` should be repeated. * * We default to 1x tab (rather than e.g. 2x spaces) to minimize token count for LLM use-cases * * @default 1 */ count?: number; /** * Whether indentation should also be applied to empty & whitespace-only lines. * @default false */ includeEmptyLines?: boolean; /** * Set true to skip the first line of text when applying indentation * @default false */ skipFirstLine?: boolean; } /** * Indent all lines of `text` by a certain amount */ export declare function indent(text: string, { character, count, includeEmptyLines, skipFirstLine }?: IIndentOpts): string; /** * Statistical methods for aggregating multiple scores/numbers into one representative value * * Different use-cases may wish to use different aggregations: For example summarizing OCR * confidence for a whole page or region based on the individual words/lines. */ export declare const enum AggregationMethod { GeometricMean = "GEOMEAN", Max = "MAX", Mean = "MEAN", Min = "MIN", Mode = "MODE" } /** * Get the most common value in an Iterable of numbers * * @returns The most common value, or null if `arr` was empty. */ export declare function modalAvg(arr: Iterable): number | null; /** * Summarize an Iterable of numbers using a statistic of your choice * * If `arr` is empty, this function will return `null`. */ export declare function aggregate(arr: Iterable, aggMethod: AggregationMethod): number | null; /** * Extract the maximum value and the first index where it appears from an array of numbers * * If `arr` is empty or no elements are numeric, this function will return a value of `-Infinity` * and an index of `-1`. */ export declare function argMax(arr: number[]): { maxValue: number; maxIndex: number; }; /** * Possible actions to take when encountering a missing Block referenced in results * * "error" throws an error, "warn" logs a warning, and falsy values silently ignore. * * TODO: Could/should we introduce a callback option one day? */ export type ActionOnMissingBlock = "error" | "warn" | null; /** * Possible actions to take when encountering an unexpected Block type in results * * "error" throws an error, "warn" logs a warning, and falsy values silently ignore. * * TODO: Could/should we introduce a callback option one day? */ export type ActionOnUnexpectedBlockType = "error" | "warn" | null; /** * Configuration options for filtering collections of Textract API "Block"s by type */ export interface IBlockTypeFilterOpts { /** * Only return API Blocks of the given type(s) * * By default, all blocks are returned unless otherwise documented. */ includeBlockTypes?: ApiBlockType | ApiBlockType[] | Set | null; /** * Action to take on encountering a Block of unexpected BlockType * * Set "error" to throw an error, "warn" to log a warning, or falsy to skip silently. */ onUnexpectedBlockType?: ActionOnUnexpectedBlockType; /** * Block types to silently skip/ignore in the results */ skipBlockTypes?: ApiBlockType[] | Set | null; } /** * Configuration options for handling data inconsistency in underlying Textract results */ export interface IMissingBlockOpts { /** * Action to take on encountering a Block of unexpected BlockType * * Set "error" to throw an error, "warn" to log a warning, or null/falsy to skip silently. */ onMissingBlockId?: ActionOnMissingBlock; } /** * Normalize an optional Set-like or individual-object parameter to a Set */ export declare function normalizeOptionalSet | null | undefined>(raw: TArg): T extends null ? null : T extends undefined ? undefined : Set; /** * Polyfill for Set.intersection() which is not available in all our target runtimes * * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/intersection */ export declare function setIntersection(a: Set, b: Set): Set; /** * Polyfill for Set.union() which is not available in all our target runtimes * * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/union */ export declare function setUnion(a: Set, b: Set): Set; /** * Interface for a (TextractDocument-like) object that can query Textract Blocks * * Unlike `IBlockManager` (below), implementers of `IDocBlocks` can only query underlying API Block * objects - and not their associated parsed TRP items. * * This interface is used to avoid circular references in child classes which need to reference some * TextractDocument-like parent, before the actual TextractDocument class is defined. */ export interface IDocBlocks { /** * Retrieve an underlying Amazon Textract API `Block` response object by its unique ID */ getBlockById: { (blockId: string): ApiBlock | undefined; }; /** * List all underlying Amazon Textract API `Block` objects managed by this parser */ listBlocks: { (): ApiBlock[]; }; } /** * Interface for a (Page-like) object that can query Textract Blocks and their parsed wrapper items * * This interface extends `IDocBlocks` to also support looking up parsed TRP items by underlying * `Block` ID. It's used to avoid circular references in child classes which need to reference some * Page-like parent, before the actual Page class is defined. */ export interface IBlockManager extends IDocBlocks { /** * Return a parsed TRP.js object corresponding to an API Block * * The return value is *nearly* always some subtype of `ApiBlockWrapper`, except that for form * fields we return the overall `Field` object instead of the `FieldKey`. * * @param blockId Unique ID of the API Block for which a parsed object should be fetched * @param allowBlockTypes Optional restriction on acceptable ApiBlockType(s) to return * @throws If no parsed object exists for the block ID, or it doesn't match `allowBlockTypes` */ getItemByBlockId(blockId: string, allowBlockTypes?: ApiBlockType | ApiBlockType[] | null): IApiBlockWrapper; /** * Register a newly parsed ApiBlockWrapper for a particular block ID * * In cases where a BlockManager devolves parsing certain block types down to an intermediate * layer (e.g. QueryInstance parsing related QueryResult blocks) - the lower parser should use * this function to register the created items with the block manager to allow later retrieval. * * @param blockId Unique ID of the API Block for which a parsed object should be registered * @param allowBlockTypes Optional restriction on acceptable ApiBlockType(s) to return * @throws If no parsed object exists for the block ID, or it doesn't match `allowBlockTypes` */ registerParsedItem(blockId: string, item: IApiBlockWrapper): void; } /** * Interface for objects that track a reference to the Page on which they're defined */ export interface IWithParentPage { /** * Parsed TRP.js `Page` that this object is a member of */ parentPage: TPage; } /** * Interface for usually (API block wrapper) objects that can traverse related parsed objects * * TODO: Should we enforce/guarantee related items are also `I{Hosted?}ApiBlockWrapper`s? */ export interface IWithRelatedItems> { /** * Iterate through directly related Blocks' parsed wrapper items, with optional filters * * This low-level method traverses the `Relationships` of the wrapped block, but looks up the * linked block IDs to return the actual parsed wrapper items for each target - since that's * usually what you'll want to work with anyway. * * @param relType Type(s) of relationships to consider * @param opts Options for filtering the returned items */ iterRelatedItemsByRelType(relType: ApiRelationshipType | ApiRelationshipType[], opts?: IBlockTypeFilterOpts): Iterable; /** * List directly related Blocks' parsed wrapper items, with optional filters * * This low-level method traverses the `Relationships` of the wrapped block, but looks up the * linked block IDs to return the actual parsed wrapper items for each target - since that's * usually what you'll want to work with anyway. * * @param relType Type(s) of relationships to consider * @param opts Options for filtering the returned items */ listRelatedItemsByRelType(relType: ApiRelationshipType | ApiRelationshipType[], opts?: IBlockTypeFilterOpts): TRelated[]; } /** * INTERNAL shared implementation for iterRelatedBlocksByRelType * * Iterate through Blocks related to `me` by a given `relType`, optionally filtering related blocks * by type. * * @param relType The type of relationship to iterate through * @param opts Filtering options and unexpected/missing block behaviour config * @param me Block wrapper from which relations should be traversed * @param host IDocBlocks that can be used to look up related blocks */ export declare function _implIterRelatedBlocksByRelType(relType: ApiRelationshipType | ApiRelationshipType[], { includeBlockTypes, onMissingBlockId, onUnexpectedBlockType, skipBlockTypes, }: (IBlockTypeFilterOpts & IMissingBlockOpts) | undefined, me: IApiBlockWrapper, host: IDocBlocks): Iterable; /** * INTERNAL shared implementation for iterRelatedItemsByRelType * * Most block wrappers will inherit this method via `PageHostedApiBlockWrapper`, but `Page` itself * cannot: Because currently `Page` is the block manager for its own block. This layer lets us * provide the `IWithRelatedItems` interface on `Page` without duplication. * * TODO: Maybe we should make Page more like a regular block, and TextractDocument the manager? * * @param relType The type of relationship to iterate through * @param opts Filtering options and unexpected/missing block behaviour config * @param me Block wrapper from which relations should be traversed * @param host IBlockManager that can be used to look up related blocks + parsed items */ export declare function _implIterRelatedItemsByRelType(relType: ApiRelationshipType | ApiRelationshipType[], opts: (IBlockTypeFilterOpts & IMissingBlockOpts) | undefined, me: IApiBlockWrapper, host: IBlockManager): Iterable>; /** * INTERNAL shared implementation for listRelatedBlocksByRelType * * List Blocks related to `me` by a given `relType`, optionally filtering related blocks by type. * * @param relType The type of relationship to list targets for * @param opts Filtering options and unexpected/missing block behaviour config * @param me Block wrapper from which relations should be traversed * @param host IDocBlocks that can be used to look up related blocks */ export declare function _implListRelatedBlocksByRelType(relType: ApiRelationshipType | ApiRelationshipType[], { includeBlockTypes, onMissingBlockId, onUnexpectedBlockType, skipBlockTypes, }: (IBlockTypeFilterOpts & IMissingBlockOpts) | undefined, me: IApiBlockWrapper, host: IDocBlocks): ApiBlock[]; /** * INTERNAL shared implementation for listRelatedItemsByRelType * * Most block wrappers will inherit this method via `PageHostedApiBlockWrapper`, but `Page` itself * cannot: Because currently `Page` is the block manager for its own block. This layer lets us * provide the `IWithRelatedItems` interface on `Page` without duplication. * * TODO: Maybe we should make Page more like a regular block, and TextractDocument the manager? * * @param relType The type of relationship to list targets for * @param opts Filtering options and unexpected/missing block behaviour config * @param me Block wrapper from which relations should be traversed * @param host IBlockManager that can be used to look up related blocks + parsed items */ export declare function _implListRelatedItemsByRelType(relType: ApiRelationshipType | ApiRelationshipType[], opts: (IBlockTypeFilterOpts & IMissingBlockOpts) | undefined, me: IApiBlockWrapper, host: IBlockManager): IApiBlockWrapper[]; /** * Base interface for classes which wrap over a Textract API `Block` *and* are parent doc/page-aware * * Holding a reference to the hosting page/document allows direct lookup of related parsed objects. */ export interface IHostedApiBlockWrapper extends ApiBlockWrapper, IWithParentPage, IWithRelatedItems> { } /** * Base class for an item parser wrapping Textract `Block` object, that tracks its parent page * * Items derived from this base automatically register themselves with the parent page on construct */ export declare class PageHostedApiBlockWrapper extends ApiBlockWrapper implements IHostedApiBlockWrapper { _parentPage: TPage; constructor(dict: TBlock, parentPage: TPage); get parentPage(): TPage; iterRelatedItemsByRelType(relType: ApiRelationshipType | ApiRelationshipType[], opts?: IBlockTypeFilterOpts): Iterable>; listRelatedItemsByRelType(relType: ApiRelationshipType | ApiRelationshipType[], opts?: IBlockTypeFilterOpts): IApiBlockWrapper[]; }