UNPKG

@baqhub/sdk

Version:

The official JavaScript SDK for the BAQ federated app platform.

334 lines (333 loc) 22.4 kB
import * as IO from "../helpers/io.js"; import { AnyBlobLink } from "../model/links/blobLink.js"; import { AuthenticationState } from "../model/local/authenticationState.js"; import { Query, SingleQuery } from "../model/query/query.js"; import { AppRecord } from "../model/recordTypes/appRecord.js"; import { EntityRecord, EntityRecordServerEndpoint } from "../model/recordTypes/entityRecord.js"; import { ServerCredentialsRecord } from "../model/recordTypes/serverCredentialsRecord.js"; import { AnyRecord, NoContentRecord, RAnyEventRecord, RAnyRecord } from "../model/records/record.js"; import { HttpAuthorizationBuilder } from "./http.js"; type HttpBearerBuilder = (url: string, expiresAt: number) => string; type TSRecord<K extends keyof any, T> = { [P in K]: T; }; interface BuildClientOptions { getEntityRecord: (signal: AbortSignal) => Promise<EntityRecord>; authorizationBuilder?: HttpAuthorizationBuilder; bearerBuilder?: HttpBearerBuilder; } export interface GetRecordOptions { query?: SingleQuery; signal?: AbortSignal; } export interface Client extends ReturnType<typeof buildClientBase> { } export type BlobUrlBuilder = (record: AnyRecord, blob: AnyBlobLink, expiresInSeconds?: number) => string; declare function buildClientBase(clientOptions: BuildClientOptions): { expandUrlTemplate: (endpoint: EntityRecordServerEndpoint, values: TSRecord<string, string>, signal: AbortSignal | undefined) => Promise<string>; getEntityRecord: (signal?: AbortSignal) => Promise<EntityRecord>; getEntityRecordSync: () => EntityRecord; getRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, entity: string, recordId: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecordVersion: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, entity: string, recordId: string, versionHash: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getOwnRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, recordId: string, options?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: Query<IO.TypeOf<M>>, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; getMoreRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: string, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; recordEventSource: <Q extends AnyRecord, R extends IO.Type<Q, unknown, unknown> | IO.Type<NoContentRecord, unknown, unknown> | IO.Type<Q | NoContentRecord, unknown, unknown>>(recordModel: R, onRecord: (record: IO.TypeOf<R>) => void, query: Query<Q>, signal: AbortSignal) => Promise<void>; postRecord: <K extends RAnyRecord, R extends RAnyEventRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; postAppRecord: (record: AppRecord, credentialsRecord: ServerCredentialsRecord, signal?: AbortSignal) => Promise<readonly [Uint8Array<ArrayBufferLike>, AppRecord]>; putRecord: <K extends RAnyRecord, R extends RAnyRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; deleteRecord: <K extends RAnyRecord>(knownModel: K, record: NoContentRecord, signal?: AbortSignal) => Promise<{ readonly record: NoContentRecord; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; discover: (entity: string, signal?: AbortSignal) => Promise<EntityRecord>; uploadBlob: (blob: Blob, signal?: AbortSignal) => Promise<import("../model/response/blobResponse.js").BlobResponse>; downloadBlob: (record: AnyRecord, blob: AnyBlobLink, signal?: AbortSignal) => Promise<Blob>; blobUrlBuilderFor: (entityRecord: EntityRecord) => BlobUrlBuilder; blobUrlBuilder: () => Promise<BlobUrlBuilder>; }; declare function buildClientFromUrl(entityRecordUrl: string): { expandUrlTemplate: (endpoint: EntityRecordServerEndpoint, values: TSRecord<string, string>, signal: AbortSignal | undefined) => Promise<string>; getEntityRecord: (signal?: AbortSignal) => Promise<EntityRecord>; getEntityRecordSync: () => EntityRecord; getRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, entity: string, recordId: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecordVersion: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, entity: string, recordId: string, versionHash: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getOwnRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, recordId: string, options?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: Query<IO.TypeOf<M>>, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; getMoreRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: string, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; recordEventSource: <Q extends AnyRecord, R extends IO.Type<Q, unknown, unknown> | IO.Type<NoContentRecord, unknown, unknown> | IO.Type<Q | NoContentRecord, unknown, unknown>>(recordModel: R, onRecord: (record: IO.TypeOf<R>) => void, query: Query<Q>, signal: AbortSignal) => Promise<void>; postRecord: <K extends RAnyRecord, R extends RAnyEventRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; postAppRecord: (record: AppRecord, credentialsRecord: ServerCredentialsRecord, signal?: AbortSignal) => Promise<readonly [Uint8Array<ArrayBufferLike>, AppRecord]>; putRecord: <K extends RAnyRecord, R extends RAnyRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; deleteRecord: <K extends RAnyRecord>(knownModel: K, record: NoContentRecord, signal?: AbortSignal) => Promise<{ readonly record: NoContentRecord; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; discover: (entity: string, signal?: AbortSignal) => Promise<EntityRecord>; uploadBlob: (blob: Blob, signal?: AbortSignal) => Promise<import("../model/response/blobResponse.js").BlobResponse>; downloadBlob: (record: AnyRecord, blob: AnyBlobLink, signal?: AbortSignal) => Promise<Blob>; blobUrlBuilderFor: (entityRecord: EntityRecord) => BlobUrlBuilder; blobUrlBuilder: () => Promise<BlobUrlBuilder>; }; declare function buildClientFromEntity(entity: string): { expandUrlTemplate: (endpoint: EntityRecordServerEndpoint, values: TSRecord<string, string>, signal: AbortSignal | undefined) => Promise<string>; getEntityRecord: (signal?: AbortSignal) => Promise<EntityRecord>; getEntityRecordSync: () => EntityRecord; getRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, entity: string, recordId: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecordVersion: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, entity: string, recordId: string, versionHash: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getOwnRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, recordId: string, options?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: Query<IO.TypeOf<M>>, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; getMoreRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: string, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; recordEventSource: <Q extends AnyRecord, R extends IO.Type<Q, unknown, unknown> | IO.Type<NoContentRecord, unknown, unknown> | IO.Type<Q | NoContentRecord, unknown, unknown>>(recordModel: R, onRecord: (record: IO.TypeOf<R>) => void, query: Query<Q>, signal: AbortSignal) => Promise<void>; postRecord: <K extends RAnyRecord, R extends RAnyEventRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; postAppRecord: (record: AppRecord, credentialsRecord: ServerCredentialsRecord, signal?: AbortSignal) => Promise<readonly [Uint8Array<ArrayBufferLike>, AppRecord]>; putRecord: <K extends RAnyRecord, R extends RAnyRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; deleteRecord: <K extends RAnyRecord>(knownModel: K, record: NoContentRecord, signal?: AbortSignal) => Promise<{ readonly record: NoContentRecord; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; discover: (entity: string, signal?: AbortSignal) => Promise<EntityRecord>; uploadBlob: (blob: Blob, signal?: AbortSignal) => Promise<import("../model/response/blobResponse.js").BlobResponse>; downloadBlob: (record: AnyRecord, blob: AnyBlobLink, signal?: AbortSignal) => Promise<Blob>; blobUrlBuilderFor: (entityRecord: EntityRecord) => BlobUrlBuilder; blobUrlBuilder: () => Promise<BlobUrlBuilder>; }; declare function buildClientFromRecord(entityRecord: EntityRecord): { expandUrlTemplate: (endpoint: EntityRecordServerEndpoint, values: TSRecord<string, string>, signal: AbortSignal | undefined) => Promise<string>; getEntityRecord: (signal?: AbortSignal) => Promise<EntityRecord>; getEntityRecordSync: () => EntityRecord; getRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, entity: string, recordId: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecordVersion: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, entity: string, recordId: string, versionHash: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getOwnRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, recordId: string, options?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: Query<IO.TypeOf<M>>, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; getMoreRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: string, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; recordEventSource: <Q extends AnyRecord, R extends IO.Type<Q, unknown, unknown> | IO.Type<NoContentRecord, unknown, unknown> | IO.Type<Q | NoContentRecord, unknown, unknown>>(recordModel: R, onRecord: (record: IO.TypeOf<R>) => void, query: Query<Q>, signal: AbortSignal) => Promise<void>; postRecord: <K extends RAnyRecord, R extends RAnyEventRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; postAppRecord: (record: AppRecord, credentialsRecord: ServerCredentialsRecord, signal?: AbortSignal) => Promise<readonly [Uint8Array<ArrayBufferLike>, AppRecord]>; putRecord: <K extends RAnyRecord, R extends RAnyRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; deleteRecord: <K extends RAnyRecord>(knownModel: K, record: NoContentRecord, signal?: AbortSignal) => Promise<{ readonly record: NoContentRecord; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; discover: (entity: string, signal?: AbortSignal) => Promise<EntityRecord>; uploadBlob: (blob: Blob, signal?: AbortSignal) => Promise<import("../model/response/blobResponse.js").BlobResponse>; downloadBlob: (record: AnyRecord, blob: AnyBlobLink, signal?: AbortSignal) => Promise<Blob>; blobUrlBuilderFor: (entityRecord: EntityRecord) => BlobUrlBuilder; blobUrlBuilder: () => Promise<BlobUrlBuilder>; }; declare function buildAuthenticatedClient(state: AuthenticationState): { expandUrlTemplate: (endpoint: EntityRecordServerEndpoint, values: TSRecord<string, string>, signal: AbortSignal | undefined) => Promise<string>; getEntityRecord: (signal?: AbortSignal) => Promise<EntityRecord>; getEntityRecordSync: () => EntityRecord; getRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, entity: string, recordId: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecordVersion: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, entity: string, recordId: string, versionHash: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getOwnRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, recordId: string, options?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: Query<IO.TypeOf<M>>, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; getMoreRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: string, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; recordEventSource: <Q extends AnyRecord, R extends IO.Type<Q, unknown, unknown> | IO.Type<NoContentRecord, unknown, unknown> | IO.Type<Q | NoContentRecord, unknown, unknown>>(recordModel: R, onRecord: (record: IO.TypeOf<R>) => void, query: Query<Q>, signal: AbortSignal) => Promise<void>; postRecord: <K extends RAnyRecord, R extends RAnyEventRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; postAppRecord: (record: AppRecord, credentialsRecord: ServerCredentialsRecord, signal?: AbortSignal) => Promise<readonly [Uint8Array<ArrayBufferLike>, AppRecord]>; putRecord: <K extends RAnyRecord, R extends RAnyRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; deleteRecord: <K extends RAnyRecord>(knownModel: K, record: NoContentRecord, signal?: AbortSignal) => Promise<{ readonly record: NoContentRecord; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; discover: (entity: string, signal?: AbortSignal) => Promise<EntityRecord>; uploadBlob: (blob: Blob, signal?: AbortSignal) => Promise<import("../model/response/blobResponse.js").BlobResponse>; downloadBlob: (record: AnyRecord, blob: AnyBlobLink, signal?: AbortSignal) => Promise<Blob>; blobUrlBuilderFor: (entityRecord: EntityRecord) => BlobUrlBuilder; blobUrlBuilder: () => Promise<BlobUrlBuilder>; }; declare function discover(entity: string, signal?: AbortSignal): Promise<{ expandUrlTemplate: (endpoint: EntityRecordServerEndpoint, values: TSRecord<string, string>, signal: AbortSignal | undefined) => Promise<string>; getEntityRecord: (signal?: AbortSignal) => Promise<EntityRecord>; getEntityRecordSync: () => EntityRecord; getRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, entity: string, recordId: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecordVersion: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, entity: string, recordId: string, versionHash: string, { query, signal }?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getOwnRecord: <K extends RAnyRecord, M extends RAnyEventRecord>(knownModel: K, model: M, recordId: string, options?: GetRecordOptions) => Promise<{ readonly record: IO.TypeOf<M>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; getRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: Query<IO.TypeOf<M>>, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; getMoreRecords: <K extends RAnyRecord, M extends RAnyRecord>(knownModel: K, model: M, query: string, signal?: AbortSignal) => Promise<{ readonly pageSize: number; readonly records: readonly IO.TypeOf<M>[]; readonly linkedRecords: readonly IO.TypeOf<K>[]; } & { readonly nextPage?: string | undefined; }>; recordEventSource: <Q extends AnyRecord, R extends IO.Type<Q, unknown, unknown> | IO.Type<NoContentRecord, unknown, unknown> | IO.Type<Q | NoContentRecord, unknown, unknown>>(recordModel: R, onRecord: (record: IO.TypeOf<R>) => void, query: Query<Q>, signal: AbortSignal) => Promise<void>; postRecord: <K extends RAnyRecord, R extends RAnyEventRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; postAppRecord: (record: AppRecord, credentialsRecord: ServerCredentialsRecord, signal?: AbortSignal) => Promise<readonly [Uint8Array<ArrayBufferLike>, AppRecord]>; putRecord: <K extends RAnyRecord, R extends RAnyRecord>(knownModel: K, recordModel: R, record: IO.TypeOf<R>, signal?: AbortSignal) => Promise<{ readonly record: IO.TypeOf<R>; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; deleteRecord: <K extends RAnyRecord>(knownModel: K, record: NoContentRecord, signal?: AbortSignal) => Promise<{ readonly record: NoContentRecord; readonly linkedRecords: readonly IO.TypeOf<K>[]; }>; discover: (entity: string, signal?: AbortSignal) => Promise<EntityRecord>; uploadBlob: (blob: Blob, signal?: AbortSignal) => Promise<import("../model/response/blobResponse.js").BlobResponse>; downloadBlob: (record: AnyRecord, blob: AnyBlobLink, signal?: AbortSignal) => Promise<Blob>; blobUrlBuilderFor: (entityRecord: EntityRecord) => BlobUrlBuilder; blobUrlBuilder: () => Promise<BlobUrlBuilder>; }>; export declare const Client: { ofUrl: typeof buildClientFromUrl; ofEntity: typeof buildClientFromEntity; ofRecord: typeof buildClientFromRecord; authenticated: typeof buildAuthenticatedClient; discover: typeof discover; }; export {};