UNPKG

@proofkit/fmodata

Version:
116 lines (115 loc) 7.4 kB
import { QueryOptions } from 'odata-query'; import { ExecutionContext, ExecutableBuilder, WithSystemFields, Result, InferSchemaType, ExecuteOptions, ConditionallyWithODataAnnotations, ExtractSchemaFromOccurrence } from '../types.js'; import { Filter } from '../filter-types.js'; import { TableOccurrence } from './table-occurrence.js'; import { BaseTable } from './base-table.js'; import { FFetchOptions } from '@fetchkit/ffetch'; import { StandardSchemaV1 } from '@standard-schema/spec'; type ExtractNavigationNames<O extends TableOccurrence<any, any, any, any> | undefined> = O extends TableOccurrence<any, any, infer Nav, any> ? Nav extends Record<string, any> ? keyof Nav & string : never : never; type ResolveNavigationItem<T> = T extends () => infer R ? R : T; type FindNavigationTarget<O extends TableOccurrence<any, any, any, any> | undefined, Name extends string> = O extends TableOccurrence<any, any, infer Nav, any> ? Nav extends Record<string, any> ? Name extends keyof Nav ? ResolveNavigationItem<Nav[Name]> : TableOccurrence<BaseTable<Record<string, StandardSchemaV1>, any, any, any>, any, any, any> : TableOccurrence<BaseTable<Record<string, StandardSchemaV1>, any, any, any>, any, any, any> : TableOccurrence<BaseTable<Record<string, StandardSchemaV1>, any, any, any>, any, any, any>; type GetTargetSchemaType<O extends TableOccurrence<any, any, any, any> | undefined, Rel extends string> = [FindNavigationTarget<O, Rel>] extends [ TableOccurrence<infer BT, any, any, any> ] ? [BT] extends [BaseTable<infer S, any, any, any>] ? [S] extends [Record<string, StandardSchemaV1>] ? InferSchemaType<S> : Record<string, any> : Record<string, any> : Record<string, any>; export type ExpandedRelations = Record<string, { schema: any; selected: any; }>; export type QueryReturnType<T extends Record<string, any>, Selected extends keyof T, SingleMode extends "exact" | "maybe" | false, IsCount extends boolean, Expands extends ExpandedRelations> = IsCount extends true ? number : SingleMode extends "exact" ? Pick<T, Selected> & { [K in keyof Expands]: Pick<Expands[K]["schema"], Expands[K]["selected"]>[]; } : SingleMode extends "maybe" ? (Pick<T, Selected> & { [K in keyof Expands]: Pick<Expands[K]["schema"], Expands[K]["selected"]>[]; }) | null : (Pick<T, Selected> & { [K in keyof Expands]: Pick<Expands[K]["schema"], Expands[K]["selected"]>[]; })[]; export declare class QueryBuilder<T extends Record<string, any>, Selected extends keyof T = keyof T, SingleMode extends "exact" | "maybe" | false = false, IsCount extends boolean = false, Occ extends TableOccurrence<any, any, any, any> | undefined = undefined, Expands extends ExpandedRelations = {}> implements ExecutableBuilder<QueryReturnType<T, Selected, SingleMode, IsCount, Expands>> { private queryOptions; private expandConfigs; private singleMode; private isCountMode; private occurrence?; private tableName; private databaseName; private context; private isNavigate?; private navigateRecordId?; private navigateRelation?; private navigateSourceTableName?; private navigateBaseRelation?; private databaseUseEntityIds; constructor(config: { occurrence?: Occ; tableName: string; databaseName: string; context: ExecutionContext; databaseUseEntityIds?: boolean; }); /** * Helper to merge database-level useEntityIds with per-request options */ private mergeExecuteOptions; /** * Helper to conditionally strip OData annotations based on options */ private stripODataAnnotationsIfNeeded; /** * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name * @param useEntityIds - Optional override for entity ID usage */ private getTableId; select<K extends keyof T>(...fields: K[]): QueryBuilder<T, K, SingleMode, IsCount, Occ, Expands>; /** * Transforms our filter format to odata-query's expected format * - Arrays of operators are converted to AND conditions * - Single operator objects pass through as-is * - Shorthand values are handled by odata-query */ private transformFilter; filter(filter: Filter<ExtractSchemaFromOccurrence<Occ>>): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands>; orderBy(orderBy: QueryOptions<T>["orderBy"]): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands>; top(count: number): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands>; skip(count: number): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands>; /** * Formats select fields for use in query strings. * - Transforms field names to FMFIDs if using entity IDs * - Wraps "id" fields in double quotes * - URL-encodes special characters but preserves spaces */ private formatSelectFields; /** * Builds expand validation configs from internal expand configurations. * These are used to validate expanded navigation properties. */ private buildExpandValidationConfigs; /** * Builds OData expand query string from expand configurations. * Handles nested expands recursively. * Transforms relation names to FMTIDs if using entity IDs. */ private buildExpandString; expand<Rel extends ExtractNavigationNames<Occ> | (string & {}), TargetOcc extends FindNavigationTarget<Occ, Rel> = FindNavigationTarget<Occ, Rel>, TargetSchema extends GetTargetSchemaType<Occ, Rel> = GetTargetSchemaType<Occ, Rel>, TargetSelected extends keyof TargetSchema = keyof TargetSchema>(relation: Rel, callback?: (builder: QueryBuilder<TargetSchema, keyof TargetSchema, false, false, TargetOcc extends TableOccurrence<any, any, any, any> ? TargetOcc : undefined>) => QueryBuilder<WithSystemFields<TargetSchema>, TargetSelected, any, any, any>): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands & { [K in Rel]: { schema: TargetSchema; selected: TargetSelected; }; }>; single(): QueryBuilder<T, Selected, "exact", IsCount, Occ, Expands>; maybeSingle(): QueryBuilder<T, Selected, "maybe", IsCount, Occ, Expands>; count(): QueryBuilder<T, Selected, SingleMode, true, Occ, Expands>; execute<EO extends ExecuteOptions>(options?: RequestInit & FFetchOptions & EO): Promise<Result<IsCount extends true ? number : SingleMode extends "exact" ? ConditionallyWithODataAnnotations<Pick<T, Selected> & { [K in keyof Expands]: Pick<Expands[K]["schema"], Expands[K]["selected"]>[]; }, EO["includeODataAnnotations"] extends true ? true : false> : SingleMode extends "maybe" ? ConditionallyWithODataAnnotations<Pick<T, Selected> & { [K in keyof Expands]: Pick<Expands[K]["schema"], Expands[K]["selected"]>[]; }, EO["includeODataAnnotations"] extends true ? true : false> | null : ConditionallyWithODataAnnotations<Pick<T, Selected> & { [K in keyof Expands]: Pick<Expands[K]["schema"], Expands[K]["selected"]>[]; }, EO["includeODataAnnotations"] extends true ? true : false>[]>>; getQueryString(): string; getRequestConfig(): { method: string; url: string; body?: any; }; toRequest(baseUrl: string): Request; processResponse(response: Response, options?: ExecuteOptions): Promise<Result<QueryReturnType<T, Selected, SingleMode, IsCount, Expands>>>; } export {};