import * as stream from 'stream'; import { CacheMode, LoggerFn } from '@cubejs-backend/shared'; import type { SqlFiltersResponse } from '@cubejs-backend/native'; import type { Application as ExpressApplication, ErrorRequestHandler, RequestHandler, Response as ExpressResponse } from 'express'; import { QueryType, ApiScopes } from './types/strings'; import { BaseRequest, RequestContext, ExtendedRequestContext, Request, QueryRewriteFn, SecurityContextExtractorFn, ExtendContextFn, ResponseResultFn, QueryRequest, SqlApiRequest, MetaResponseResultFn, RequestQuery, QueryConvertRequest } from './types/request'; import { CheckAuthInternalOptions, JWTOptions, CheckAuthFn, ContextToApiScopesFn } from './types/auth'; import { Query, NormalizedQuery } from './types/query'; import { UserBackgroundContext, ApiGatewayOptions } from './types/gateway'; import { RequestLoggerMiddlewareFn, ContextRejectionMiddlewareFn, ContextAcceptorFn } from './interfaces'; import { SubscriptionServer, WebSocketSendMessageFn } from './ws/subscription-server'; import { SQLServer, SQLServerConstructorOptions } from './sql-server'; type HandleErrorOptions = { e: any; res: ResponseResultFn; context?: any; query?: any; /** The redacted twin of `query`, for the log sink to swap in when log redaction is on */ redactedQuery?: any; requestStarted?: Date; }; type PreparedCheckAuthFn = (ctx: any, authorization?: string) => Promise<{ securityContext: any; }>; declare class ApiGateway { protected readonly apiSecret: string; /** * It actually returns a Promise */ protected readonly compilerApi: (ctx: RequestContext) => Promise; /** * It actually returns a Promise */ protected readonly adapterApi: (ctx: RequestContext) => Promise; protected readonly logger: LoggerFn; protected readonly options: ApiGatewayOptions; protected readonly refreshScheduler: any; protected readonly scheduledRefreshContexts: ApiGatewayOptions['scheduledRefreshContexts']; protected readonly scheduledRefreshTimeZones: ApiGatewayOptions['scheduledRefreshTimeZones']; protected readonly basePath: string; protected readonly queryRewrite: QueryRewriteFn; protected readonly subscriptionStore: any; protected readonly devServer: boolean; protected readonly enforceSecurityChecks: boolean; protected readonly standalone: boolean; protected readonly extendContext?: ExtendContextFn; protected readonly dataSourceStorage: any; readonly checkAuthFn: PreparedCheckAuthFn; readonly checkAuthSystemFn: PreparedCheckAuthFn; readonly contextToApiScopesFn: ContextToApiScopesFn; readonly contextToApiScopesDefFn: ContextToApiScopesFn; protected readonly requestLoggerMiddleware: RequestLoggerMiddlewareFn; protected readonly securityContextExtractor: SecurityContextExtractorFn; protected readonly contextRejectionMiddleware: ContextRejectionMiddlewareFn; protected readonly wsContextAcceptor: ContextAcceptorFn; protected readonly releaseListeners: (() => any)[]; protected readonly playgroundAuthSecret?: string; protected readonly apiSecrets?: string[]; protected readonly event: (name: string, props?: object) => void; protected readonly sqlServer: SQLServer; constructor(apiSecret: string, /** * It actually returns a Promise */ compilerApi: (ctx: RequestContext) => Promise, /** * It actually returns a Promise */ adapterApi: (ctx: RequestContext) => Promise, logger: LoggerFn, options: ApiGatewayOptions); getSQLServer(): SQLServer; protected createSQLServerInstance(options: SQLServerConstructorOptions): SQLServer; initApp(app: ExpressApplication): void; protected enableNativeApiGateway(app: ExpressApplication): void; initSubscriptionServer(sendMessage: WebSocketSendMessageFn): SubscriptionServer; protected duration(requestStarted: any): any; private filterVisibleItemsInMeta; /** * Recursively filters a (possibly nested) view group so that only visible * views are exposed. A view group is dropped (returns null) when neither it * nor any of its nested groups contains a visible view, preventing leaks of * restricted view names. */ private filterVisibleViewGroup; meta({ context, res, includeCompilerId, onlyCompilerId, onlyViews }: { context: RequestContext; res: MetaResponseResultFn; includeCompilerId?: boolean; onlyCompilerId?: boolean; onlyViews?: boolean; }): Promise; metaExtended({ context, res, onlyViews }: { context: ExtendedRequestContext; res: ResponseResultFn; onlyViews?: boolean; }): Promise; getPreAggregations({ cacheOnly, metaOnly, context, res }: { cacheOnly?: boolean; metaOnly?: boolean; context: RequestContext; res: ResponseResultFn; }): Promise; getPreAggregationPartitions({ query, context, res }: { query: any; context: RequestContext; res: ResponseResultFn; }): Promise; getPreAggregationPreview({ query, context, res }: { query: any; context: RequestContext; res: ResponseResultFn; }): Promise; buildPreAggregations({ query, context, res }: { query: any; context: RequestContext; res: ResponseResultFn; }): Promise; /** * Entry point for the `/cubejs-system/v1/pre-aggregations/jobs` endpoint. * Post object example: * ``` * { * "action": "post", * "selector": { * "contexts": [ * {"securityContext": {"tenant": "t1"}}, * {"securityContext": {"tenant": "t2"}} * ], * "timezones": ["UTC"], * "dataSources": ["default"], * "cubes": ["Events"], * "preAggregations": ["Events.TemporaryData"] * } * } * // or * { * "action": "get", * "tokens": [ * "ec1232ea3356f04f8be313fecf3deb4d", * "48b75d5c466fa579c936dc451f498f69", * "76509837091396dc204abb1016c48e75", * "52264769f81f6ff62062a93d6f6fbdb2" * ] * } * // or * { * "action": "get", * "resType": "object", * "tokens": [ * "ec1232ea3356f04f8be313fecf3deb4d", * "48b75d5c466fa579c936dc451f498f69", * "76509837091396dc204abb1016c48e75", * "52264769f81f6ff62062a93d6f6fbdb2" * ] * } * ``` */ private preAggregationsJobs; /** * Post pre-aggregations build jobs entry point. */ private preAggregationsJobsPOST; /** * Add pre-aggregations build job. Returns added jobs ids. */ private postPreAggregationsBuildJobs; /** * Get pre-aggregations build jobs entry point. */ private preAggregationsJobsGET; /** * Returns PreAggJob status if it still in queue, false otherwise. */ private getPreAggJobQueueStatus; /** * Returns PreAggJob execution status. */ private getPreAggJobResultStatus; getPreAggregationsInQueue({ context, res }: { context: RequestContext; res: ResponseResultFn; }): Promise; cancelPreAggregationsFromQueue({ query, context, res }: { query: any; context: RequestContext; res: ResponseResultFn; }): Promise; cancelQuery({ requestId, context, res }: { requestId: string; context: RequestContext; res: ResponseResultFn; }): Promise; /** * Convert incoming query parameter (JSON fetched from the HTTP) to * an array of query type and array of normalized queries. */ protected getNormalizedQueries(inputQuery: Record | Record[], context: RequestContext, persistent?: boolean, memberExpressions?: boolean, cacheMode?: CacheMode): Promise<[QueryType, NormalizedQuery[], NormalizedQuery[]]>; protected sql4sql({ query, disablePostProcessing, context, res, }: { query: string; disablePostProcessing: boolean; } & BaseRequest): Promise; /** * An in-band `{ status: 'error' }` is a 400; `in_band_or_thrown` in the * native layer decides which failures are in-band. */ protected resSqlFilters(result: SqlFiltersResponse, res: ResponseResultFn, { query, context, requestStarted }: { query: string; context: any; requestStarted: Date; }): Promise; protected getSqlFilters({ query, context, res, }: { query: string; } & BaseRequest): Promise; /** * Rewrites the filters of a SQL API query with exactly one of `add`, `set`, * `delete` or `replace`. The semantics live in cubesql's `sql_filters` and are * documented at `reference/core-data-apis/rest-api/reference.mdx`. */ protected modifySqlFilters({ query, add, set, delete: deleteFilters, replace, context, res, }: { query: string; add?: unknown; set?: unknown; delete?: unknown; replace?: unknown; } & BaseRequest): Promise; sql({ query, context, res, memberToAlias, exportAnnotatedSql, memberExpressions, expressionParams, disableExternalPreAggregations, disableLimitEnforcing, }: QueryRequest): Promise; /** * Resolves member paths through the data model's joins, so a path through a * join alias can be told apart from a time dimension with a granularity. */ protected memberPathResolver(context: RequestContext, compilerApi?: any): Promise<((path: string) => any) | undefined>; /** * The member paths a query names, in its raw or normalized form. Only * `order` may name a time dimension with a granularity. */ private memberPaths; /** * Whether the query names a member by a path longer than `cube.member`, * which takes the data model to read. */ protected hasLongMemberPaths(query: Query | NormalizedQuery): boolean; /** * A member path is a cube or a cube instance reached through join aliases, * and a member; other join paths are not part of the query format. */ protected checkMemberPaths(query: NormalizedQuery, resolve?: (path: string) => any): NormalizedQuery; protected granularitySplitter(resolve?: (path: string) => any): ((path: string) => { dimension: any; granularity: any; } | null | undefined) | undefined; protected memberTarget(resolve?: (path: string) => any): ((path: string) => any) | undefined; private hasExpressionsInQuery; private parseMemberExpressionsInQuery; private parseMemberExpression; private evalMemberExpressionsInQuery; private evalMemberExpression; /** * Which of `queries` a Cube Store pre-aggregation would serve, in order: cubesql asks * before it renders SQL for Cube Store. Matching only, with the normalization `sql` gets. */ preAggregationMatch({ queries, context, res }: { queries: Query[]; context: RequestContext; res: ResponseResultFn; }): Promise; sqlGenerators({ context, res }: { context: RequestContext; res: ResponseResultFn; }): Promise; protected createSecurityContextExtractor(options?: JWTOptions): SecurityContextExtractorFn; protected coerceForSqlQuery(query: any, context: Readonly): any; protected convertQuery({ payload, context, res }: QueryConvertRequest): Promise; protected dryRun({ query, context, res }: QueryRequest): Promise; /** * Returns an array of sqlQuery objects for specified normalized * queries. * @internal */ private getSqlQueriesInternal; private sanitizeSqlQuery; private sanitizeQueryForLogging; /** * Execute query and return adapter's result. * @internal */ private getSqlResponseInternal; /** * Wraps the adapter's response in unified ResultWrapper if it comes from * a common driver (not a Cubestore's one, cause Cubestore Driver internally creates ResultWrapper) * @param res Adapter's response * @private */ private wrapAdapterQueryResultIfNeeded; /** * Prepare adapter's result and other transform parameters for a final * result object. * @internal */ private prepareResultTransformData; /** * Returns stream object which will be used to stream results from * the data source if applicable, returns `null` otherwise. */ stream(context: RequestContext, query: Query): Promise; /** * Data queries APIs (`/load`, `/subscribe`) entry point. Used by * `CubejsApi#load` and `CubejsApi#subscribe` methods to fetch the * data. */ load(request: QueryRequest): Promise; sqlApiLoad(request: SqlApiRequest): Promise; subscribe({ query, context, res, subscribe, subscriptionState, queryType, apiType }: { query: any; context: any; res: any; subscribe: any; subscriptionState: any; queryType: any; apiType: any; }): Promise; protected resToResultFn(res: ExpressResponse): (message: any, { status }?: { status?: number; }) => Promise; protected parseQueryParam(query: RequestQuery | 'undefined'): Query | Query[]; protected getCompilerApi(context: RequestContext): Promise; protected getAdapterApi(context: RequestContext): Promise; contextByReq(req: Request, securityContext: any, requestId: string): Promise; protected handleErrorMiddleware: ErrorRequestHandler; /** * The redacted twin of a SQL API statement for the log sink, the same one * cubesql attaches to its own events. Nothing when redaction is off or when * the body carried no statement (validation failed on it). */ private redactedSqlForLog; protected exposedRequestId(context?: any): string | undefined; handleError({ e, context, query, redactedQuery, res, requestStarted }: HandleErrorOptions): void; protected wrapCheckAuth(fn: CheckAuthFn): PreparedCheckAuthFn; protected createDefaultCheckAuth(options?: JWTOptions, internalOptions?: CheckAuthInternalOptions): PreparedCheckAuthFn; protected createCheckAuthFn(options: ApiGatewayOptions): PreparedCheckAuthFn; protected createCheckAuthSystemFn(): PreparedCheckAuthFn; protected createContextToApiScopesFn(options: ApiGatewayOptions): ContextToApiScopesFn; protected assertApiScope(scope: ApiScopes, securityContext?: any): Promise; protected extractAuthorizationHeaderWithSchema(req: Request): string | undefined; protected checkAuthWrapper(checkAuthFn: PreparedCheckAuthFn, req: Request, res: ExpressResponse, next: any): Promise; protected checkAuth: RequestHandler; protected checkAuthSystemMiddleware: RequestHandler; protected requestContextMiddleware: RequestHandler; protected requestLogger: RequestHandler; protected logNetworkUsage: RequestHandler; protected compareDateRangeTransformer(query: any): any; log(event: { type: string; [key: string]: any; }, context?: Partial): void; protected healthResponse(res: ExpressResponse, health: 'HEALTH' | 'DOWN'): void; protected createSystemContextHandler: (basePath: string) => RequestHandler; private logProbeError; protected readiness: RequestHandler; protected liveness: RequestHandler; release(): void; } export { type UserBackgroundContext, type ApiGatewayOptions, ApiGateway, }; //# sourceMappingURL=gateway.d.ts.map