xscrape
Version:
A flexible and powerful library designed to extract and transform data from HTML documents using user-defined schemas
36 lines (35 loc) • 1.9 kB
text/typescript
import { StandardSchemaV1 } from "@standard-schema/spec";
//#region src/types/extract.d.ts
type ExtractObjectShape<T> = NonNullable<T> extends readonly unknown[] ? never : NonNullable<T> extends object ? NonNullable<T> : never;
interface ExtractNode {
attr(name: string): string | undefined;
html(): string | undefined;
text(): string;
}
type ExtractValueCallback<T = unknown> = (node: ExtractNode, key: string, object: Record<string, unknown>) => T | undefined;
interface ExtractDescriptor<T = unknown> {
selector: string;
value?: string | ExtractValueCallback<T> | ExtractConfig<ExtractObjectShape<T>>;
}
type ExtractField<T = unknown> = string | ExtractDescriptor<T> | (T extends readonly (infer Item)[] ? [string | ExtractDescriptor<NonNullable<Item>>] : never);
type ExtractShape<T> = [T] extends [never] ? Record<string, unknown> : NonNullable<T> extends object ? NonNullable<T> : Record<string, unknown>;
type ExtractConfig<T = Record<string, unknown>> = { [K in keyof ExtractShape<T>]: ExtractField<ExtractShape<T>[K]> };
//#endregion
//#region src/types/main.d.ts
interface ScraperConfig<S extends StandardSchemaV1, R extends StandardSchemaV1.InferOutput<S> = StandardSchemaV1.InferOutput<S>> {
extract: ExtractConfig<StandardSchemaV1.InferOutput<S>>;
schema: S;
transform?: (data: StandardSchemaV1.InferOutput<S>) => Promise<R> | R;
}
type ScraperResult<T> = {
data: T;
error?: undefined;
} | {
data?: undefined;
error: unknown;
};
//#endregion
//#region src/index.d.ts
declare function defineScraper<S extends StandardSchemaV1, R extends StandardSchemaV1.InferOutput<S> = StandardSchemaV1.InferOutput<S>>(config: ScraperConfig<S, R>): (html: string) => Promise<ScraperResult<R>>;
//#endregion
export { type ExtractConfig, type ExtractDescriptor, type ExtractField, type ExtractNode, type ExtractValueCallback, type ScraperConfig, type ScraperResult, defineScraper };