Query API typing.
This commit is contained in:
parent
3446b1c678
commit
23d9808cb6
|
@ -4,26 +4,38 @@ import { save as saveDatasource } from "../datasource"
|
|||
import { RestImporter } from "./import"
|
||||
import { invalidateCachedVariable } from "../../../threads/utils"
|
||||
import env from "../../../environment"
|
||||
import { events, context, utils, constants } from "@budibase/backend-core"
|
||||
import { constants, context, events, utils } from "@budibase/backend-core"
|
||||
import sdk from "../../../sdk"
|
||||
import { QueryEvent, QueryEventParameters } from "../../../threads/definitions"
|
||||
import {
|
||||
ConfigType,
|
||||
Query,
|
||||
UserCtx,
|
||||
SessionCookie,
|
||||
JsonFieldSubType,
|
||||
QueryResponse,
|
||||
QuerySchema,
|
||||
FieldType,
|
||||
CreateDatasourceRequest,
|
||||
Datasource,
|
||||
ExecuteQueryRequest,
|
||||
ExecuteQueryResponse,
|
||||
ExecuteV2QueryResponse,
|
||||
ExecuteV1QueryResponse,
|
||||
FetchQueriesResponse,
|
||||
FieldType,
|
||||
FindQueryResponse,
|
||||
ImportRestQueryRequest,
|
||||
ImportRestQueryResponse,
|
||||
JsonFieldSubType,
|
||||
PreviewQueryRequest,
|
||||
PreviewQueryResponse,
|
||||
Query,
|
||||
QueryResponse,
|
||||
QuerySchema,
|
||||
SaveQueryRequest,
|
||||
SaveQueryResponse,
|
||||
SessionCookie,
|
||||
SourceName,
|
||||
UserCtx,
|
||||
DeleteQueryResponse,
|
||||
} from "@budibase/types"
|
||||
import { ValidQueryNameRegex, utils as JsonUtils } from "@budibase/shared-core"
|
||||
import { utils as JsonUtils, ValidQueryNameRegex } from "@budibase/shared-core"
|
||||
import { findHBSBlocks } from "@budibase/string-templates"
|
||||
import { ObjectId } from "mongodb"
|
||||
import { merge } from "lodash"
|
||||
|
||||
const Runner = new Thread(ThreadType.QUERY, {
|
||||
timeoutMs: env.QUERY_THREAD_TIMEOUT,
|
||||
|
@ -43,11 +55,13 @@ function validateQueryInputs(parameters: QueryEventParameters) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function fetch(ctx: UserCtx) {
|
||||
export async function fetch(ctx: UserCtx<void, FetchQueriesResponse>) {
|
||||
ctx.body = await sdk.queries.fetch()
|
||||
}
|
||||
|
||||
const _import = async (ctx: UserCtx) => {
|
||||
const _import = async (
|
||||
ctx: UserCtx<ImportRestQueryRequest, ImportRestQueryResponse>
|
||||
) => {
|
||||
const body = ctx.request.body
|
||||
const data = body.data
|
||||
|
||||
|
@ -58,9 +72,9 @@ const _import = async (ctx: UserCtx) => {
|
|||
if (!body.datasourceId) {
|
||||
// construct new datasource
|
||||
const info: any = await importer.getInfo()
|
||||
let datasource = {
|
||||
let datasource: Datasource = {
|
||||
type: "datasource",
|
||||
source: "REST",
|
||||
source: SourceName.REST,
|
||||
config: {
|
||||
url: info.url,
|
||||
defaultHeaders: [],
|
||||
|
@ -69,8 +83,14 @@ const _import = async (ctx: UserCtx) => {
|
|||
name: info.name,
|
||||
}
|
||||
// save the datasource
|
||||
const datasourceCtx = { ...ctx }
|
||||
datasourceCtx.request.body.datasource = datasource
|
||||
const datasourceCtx: UserCtx<CreateDatasourceRequest> = merge(ctx, {
|
||||
request: {
|
||||
body: {
|
||||
datasource,
|
||||
tablesFilter: [],
|
||||
},
|
||||
},
|
||||
})
|
||||
await saveDatasource(datasourceCtx)
|
||||
datasourceId = datasourceCtx.body.datasource._id
|
||||
} else {
|
||||
|
@ -88,7 +108,7 @@ const _import = async (ctx: UserCtx) => {
|
|||
}
|
||||
export { _import as import }
|
||||
|
||||
export async function save(ctx: UserCtx<Query, Query>) {
|
||||
export async function save(ctx: UserCtx<SaveQueryRequest, SaveQueryResponse>) {
|
||||
const db = context.getAppDB()
|
||||
const query: Query = ctx.request.body
|
||||
|
||||
|
@ -119,10 +139,9 @@ export async function save(ctx: UserCtx<Query, Query>) {
|
|||
query._rev = response.rev
|
||||
|
||||
ctx.body = query
|
||||
ctx.message = `Query ${query.name} saved successfully.`
|
||||
}
|
||||
|
||||
export async function find(ctx: UserCtx) {
|
||||
export async function find(ctx: UserCtx<void, FindQueryResponse>) {
|
||||
const queryId = ctx.params.queryId
|
||||
ctx.body = await sdk.queries.find(queryId)
|
||||
}
|
||||
|
@ -335,7 +354,7 @@ export async function preview(
|
|||
async function execute(
|
||||
ctx: UserCtx<
|
||||
ExecuteQueryRequest,
|
||||
ExecuteQueryResponse | Record<string, any>[]
|
||||
ExecuteV2QueryResponse | ExecuteV1QueryResponse
|
||||
>,
|
||||
opts: any = { rowsOnly: false, isAutomation: false }
|
||||
) {
|
||||
|
@ -390,19 +409,21 @@ async function execute(
|
|||
}
|
||||
|
||||
export async function executeV1(
|
||||
ctx: UserCtx<ExecuteQueryRequest, Record<string, any>[]>
|
||||
ctx: UserCtx<ExecuteQueryRequest, ExecuteV1QueryResponse>
|
||||
) {
|
||||
return execute(ctx, { rowsOnly: true, isAutomation: false })
|
||||
}
|
||||
|
||||
export async function executeV2(
|
||||
ctx: UserCtx<
|
||||
ExecuteQueryRequest,
|
||||
ExecuteQueryResponse | Record<string, any>[]
|
||||
>,
|
||||
{ isAutomation }: { isAutomation?: boolean } = {}
|
||||
ctx: UserCtx<ExecuteQueryRequest, ExecuteV2QueryResponse>
|
||||
) {
|
||||
return execute(ctx, { rowsOnly: false, isAutomation })
|
||||
return execute(ctx, { rowsOnly: false })
|
||||
}
|
||||
|
||||
export async function executeV2AsAutomation(
|
||||
ctx: UserCtx<ExecuteQueryRequest, ExecuteV2QueryResponse>
|
||||
) {
|
||||
return execute(ctx, { rowsOnly: false, isAutomation: true })
|
||||
}
|
||||
|
||||
const removeDynamicVariables = async (queryId: string) => {
|
||||
|
@ -426,14 +447,14 @@ const removeDynamicVariables = async (queryId: string) => {
|
|||
}
|
||||
}
|
||||
|
||||
export async function destroy(ctx: UserCtx) {
|
||||
export async function destroy(ctx: UserCtx<void, DeleteQueryResponse>) {
|
||||
const db = context.getAppDB()
|
||||
const queryId = ctx.params.queryId as string
|
||||
await removeDynamicVariables(queryId)
|
||||
const query = await db.get<Query>(queryId)
|
||||
const datasource = await sdk.datasources.get(query.datasourceId)
|
||||
await db.remove(ctx.params.queryId, ctx.params.revId)
|
||||
ctx.message = `Query deleted.`
|
||||
ctx.body = { message: `Query deleted.` }
|
||||
ctx.status = 200
|
||||
await events.query.deleted(datasource, query)
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ router
|
|||
"/api/v2/queries/:queryId",
|
||||
paramResource("queryId"),
|
||||
authorized(PermissionType.QUERY, PermissionLevel.WRITE),
|
||||
queryController.executeV2 as any
|
||||
queryController.executeV2
|
||||
)
|
||||
|
||||
export default router
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
ExecuteQueryStepInputs,
|
||||
ExecuteQueryStepOutputs,
|
||||
} from "@budibase/types"
|
||||
import { executeV2AsAutomation } from "../../api/controllers/query"
|
||||
|
||||
export const definition: AutomationStepDefinition = {
|
||||
name: "External Data Connector",
|
||||
|
@ -94,7 +95,7 @@ export async function run({
|
|||
})
|
||||
|
||||
try {
|
||||
await queryController.executeV2(ctx, { isAutomation: true })
|
||||
await queryController.executeV2AsAutomation(ctx)
|
||||
const { data, ...rest } = ctx.body
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
Query,
|
||||
ExecuteQueryRequest,
|
||||
ExecuteQueryResponse,
|
||||
ExecuteV2QueryResponse,
|
||||
PreviewQueryRequest,
|
||||
PreviewQueryResponse,
|
||||
} from "@budibase/types"
|
||||
|
@ -17,8 +17,8 @@ export class QueryAPI extends TestAPI {
|
|||
queryId: string,
|
||||
body?: ExecuteQueryRequest,
|
||||
expectations?: Expectations
|
||||
): Promise<ExecuteQueryResponse> => {
|
||||
return await this._post<ExecuteQueryResponse>(
|
||||
): Promise<ExecuteV2QueryResponse> => {
|
||||
return await this._post<ExecuteV2QueryResponse>(
|
||||
`/api/v2/queries/${queryId}`,
|
||||
{
|
||||
body,
|
||||
|
|
|
@ -12,3 +12,4 @@ export * from "./automation"
|
|||
export * from "./component"
|
||||
export * from "./integration"
|
||||
export * from "./metadata"
|
||||
export * from "./query"
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import {
|
||||
Datasource,
|
||||
Query,
|
||||
QueryPreview,
|
||||
QuerySchema,
|
||||
} from "../../../documents"
|
||||
|
||||
export type FetchQueriesResponse = Query[]
|
||||
|
||||
export interface SaveQueryRequest extends Query {}
|
||||
export interface SaveQueryResponse extends Query {}
|
||||
|
||||
export interface ImportRestQueryRequest {
|
||||
datasourceId: string
|
||||
data: string
|
||||
datasource: Datasource
|
||||
}
|
||||
export interface ImportRestQueryResponse {
|
||||
errorQueries: Query[]
|
||||
queries: Query[]
|
||||
datasourceId: string
|
||||
}
|
||||
|
||||
export interface FindQueryResponse extends Query {}
|
||||
|
||||
export interface PreviewQueryRequest extends QueryPreview {}
|
||||
|
||||
export interface PreviewQueryResponse {
|
||||
rows: any[]
|
||||
nestedSchemaFields: { [key: string]: { [key: string]: string | QuerySchema } }
|
||||
schema: { [key: string]: string | QuerySchema }
|
||||
info: any
|
||||
extra: any
|
||||
}
|
||||
|
||||
export interface ExecuteQueryRequest {
|
||||
parameters?: Record<string, string>
|
||||
pagination?: any
|
||||
}
|
||||
export type ExecuteV1QueryResponse = Record<string, any>[]
|
||||
export interface ExecuteV2QueryResponse {
|
||||
data: Record<string, any>[]
|
||||
}
|
||||
|
||||
export interface DeleteQueryResponse {
|
||||
message: string
|
||||
}
|
|
@ -13,7 +13,6 @@ export * from "./searchFilter"
|
|||
export * from "./cookies"
|
||||
export * from "./automation"
|
||||
export * from "./layout"
|
||||
export * from "./query"
|
||||
export * from "./role"
|
||||
export * from "./plugins"
|
||||
export * from "./apikeys"
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import { QueryPreview, QuerySchema } from "../../documents"
|
||||
|
||||
export interface PreviewQueryRequest extends QueryPreview {}
|
||||
|
||||
export interface PreviewQueryResponse {
|
||||
rows: any[]
|
||||
nestedSchemaFields: { [key: string]: { [key: string]: string | QuerySchema } }
|
||||
schema: { [key: string]: string | QuerySchema }
|
||||
info: any
|
||||
extra: any
|
||||
}
|
||||
|
||||
export interface ExecuteQueryRequest {
|
||||
parameters?: Record<string, string>
|
||||
pagination?: any
|
||||
}
|
||||
|
||||
export interface ExecuteQueryResponse {
|
||||
data: Record<string, any>[]
|
||||
}
|
Loading…
Reference in New Issue