This commit is contained in:
Adria Navarro 2025-01-08 14:27:13 +01:00
parent 819ca2129e
commit 10fca945d2
12 changed files with 60 additions and 30 deletions

View File

@ -100,7 +100,9 @@ export default class CustomFetch extends DataFetch<
return this.enrichCustomData(this.parseCustomData(datasource?.data)) return this.enrichCustomData(this.parseCustomData(datasource?.data))
} }
async getDefinition(datasource: CustomDatasource) { async getDefinition() {
const { datasource } = this.options
// Try and work out the schema from the array provided // Try and work out the schema from the array provided
const schema: CustomDefinition = {} const schema: CustomDefinition = {}
const data = this.getCustomData(datasource) const data = this.getCustomData(datasource)

View File

@ -11,6 +11,7 @@ import {
SortType, SortType,
TableSchema, TableSchema,
UISearchFilter, UISearchFilter,
ViewSchema,
} from "@budibase/types" } from "@budibase/types"
import { APIClient } from "../api/types" import { APIClient } from "../api/types"
@ -210,10 +211,10 @@ export default abstract class DataFetch<
* Fetches a fresh set of data from the server, resetting pagination * Fetches a fresh set of data from the server, resetting pagination
*/ */
async getInitialData() { async getInitialData() {
const { datasource, filter, paginate } = this.options const { filter, paginate } = this.options
// Fetch datasource definition and extract sort properties if configured // Fetch datasource definition and extract sort properties if configured
const definition = await this.getDefinition(datasource) const definition = await this.getDefinition()
// Determine feature flags // Determine feature flags
const features = await this.determineFeatureFlags() const features = await this.determineFeatureFlags()
@ -351,19 +352,19 @@ export default abstract class DataFetch<
/** /**
* Gets the definition for this datasource. * Gets the definition for this datasource.
* @param datasource
* @return {object} the definition * @return {object} the definition
*/ */
abstract getDefinition( abstract getDefinition(): Promise<TDefinition | null>
datasource: TDatasource | null
): Promise<TDefinition | null>
/** /**
* Gets the schema definition for a datasource. * Gets the schema definition for a datasource.
* @param definition the datasource definition * @param definition the datasource definition
* @return {object} the schema * @return {object} the schema
*/ */
getSchema(definition: TDefinition | null): Record<string, any> | undefined { getSchema(
definition: TDefinition | null
): ViewSchema | Record<string, any> | undefined {
return definition?.schema ?? undefined return definition?.schema ?? undefined
} }

View File

@ -19,9 +19,9 @@ export default class FieldFetch extends DataFetch<
FieldDatasource, FieldDatasource,
FieldDefinition FieldDefinition
> { > {
async getDefinition( async getDefinition(): Promise<FieldDefinition | null> {
datasource: FieldDatasource const { datasource } = this.options
): Promise<FieldDefinition | null> {
// Field sources have their schema statically defined // Field sources have their schema statically defined
let schema let schema
if (datasource.fieldType === "attachment") { if (datasource.fieldType === "attachment") {

View File

@ -1,8 +1,10 @@
import FieldFetch, { FieldDatasource } from "./FieldFetch" import FieldFetch from "./FieldFetch"
import { getJSONArrayDatasourceSchema } from "../utils/json" import { getJSONArrayDatasourceSchema } from "../utils/json"
export default class JSONArrayFetch extends FieldFetch { export default class JSONArrayFetch extends FieldFetch {
async getDefinition(datasource: FieldDatasource) { async getDefinition() {
const { datasource } = this.options
// JSON arrays need their table definitions fetched. // JSON arrays need their table definitions fetched.
// We can then extract their schema as a subset of the table schema. // We can then extract their schema as a subset of the table schema.
try { try {

View File

@ -17,7 +17,9 @@ export default class NestedProviderFetch extends DataFetch<
NestedProviderDatasource, NestedProviderDatasource,
NestedProviderDefinition NestedProviderDefinition
> { > {
async getDefinition(datasource: NestedProviderDatasource) { async getDefinition() {
const { datasource } = this.options
// Nested providers should already have exposed their own schema // Nested providers should already have exposed their own schema
return { return {
schema: datasource?.value?.schema, schema: datasource?.value?.schema,

View File

@ -1,11 +1,13 @@
import FieldFetch, { FieldDatasource } from "./FieldFetch" import FieldFetch from "./FieldFetch"
import { import {
getJSONArrayDatasourceSchema, getJSONArrayDatasourceSchema,
generateQueryArraySchemas, generateQueryArraySchemas,
} from "../utils/json" } from "../utils/json"
export default class QueryArrayFetch extends FieldFetch { export default class QueryArrayFetch extends FieldFetch {
async getDefinition(datasource: FieldDatasource) { async getDefinition() {
const { datasource } = this.options
if (!datasource?.tableId) { if (!datasource?.tableId) {
return null return null
} }

View File

@ -18,7 +18,7 @@ interface QueryDatasource {
export default class QueryFetch extends DataFetch<QueryDatasource, Query> { export default class QueryFetch extends DataFetch<QueryDatasource, Query> {
async determineFeatureFlags() { async determineFeatureFlags() {
const definition = await this.getDefinition(this.options.datasource) const definition = await this.getDefinition()
const supportsPagination = const supportsPagination =
!!definition?.fields?.pagination?.type && !!definition?.fields?.pagination?.type &&
!!definition?.fields?.pagination?.location && !!definition?.fields?.pagination?.location &&
@ -26,7 +26,9 @@ export default class QueryFetch extends DataFetch<QueryDatasource, Query> {
return { supportsPagination } return { supportsPagination }
} }
async getDefinition(datasource: QueryDatasource) { async getDefinition() {
const { datasource } = this.options
if (!datasource?._id) { if (!datasource?._id) {
return null return null
} }

View File

@ -12,7 +12,9 @@ export default class RelationshipFetch extends DataFetch<
RelationshipDatasource, RelationshipDatasource,
Table Table
> { > {
async getDefinition(datasource: RelationshipDatasource) { async getDefinition() {
const { datasource } = this.options
if (!datasource?.tableId) { if (!datasource?.tableId) {
return null return null
} }

View File

@ -11,7 +11,9 @@ export default class TableFetch extends DataFetch<UITable, Table> {
} }
} }
async getDefinition(datasource: UITable) { async getDefinition() {
const { datasource } = this.options
if (!datasource?.tableId) { if (!datasource?.tableId) {
return null return null
} }

View File

@ -4,7 +4,9 @@ import DataFetch from "./DataFetch"
type ViewV1 = View & { name: string } type ViewV1 = View & { name: string }
export default class ViewFetch extends DataFetch<ViewV1, Table> { export default class ViewFetch extends DataFetch<ViewV1, Table> {
async getDefinition(datasource: ViewV1) { async getDefinition() {
const { datasource } = this.options
if (!datasource?.tableId) { if (!datasource?.tableId) {
return null return null
} }

View File

@ -12,7 +12,9 @@ export default class ViewV2Fetch extends DataFetch<UIView, ViewV2> {
} }
} }
async getDefinition(datasource: UIView) { async getDefinition() {
const { datasource } = this.options
try { try {
const res = await this.API.viewV2.fetchDefinition(datasource.id) const res = await this.API.viewV2.fetchDefinition(datasource.id)
return res?.data return res?.data

View File

@ -10,7 +10,6 @@ import UserFetch from "./UserFetch.js"
import GroupUserFetch from "./GroupUserFetch" import GroupUserFetch from "./GroupUserFetch"
import CustomFetch from "./CustomFetch" import CustomFetch from "./CustomFetch"
import QueryArrayFetch from "./QueryArrayFetch.js" import QueryArrayFetch from "./QueryArrayFetch.js"
import { UIDatasource } from "@budibase/types"
import { APIClient } from "../api/types.js" import { APIClient } from "../api/types.js"
const DataFetchMap = { const DataFetchMap = {
@ -39,12 +38,16 @@ export const fetchData = ({ API, datasource, options }: any) => {
// Creates an empty fetch instance with no datasource configured, so no data // Creates an empty fetch instance with no datasource configured, so no data
// will initially be loaded // will initially be loaded
const createEmptyFetchInstance = ({ const createEmptyFetchInstance = <
TDatasource extends {
type: keyof typeof DataFetchMap
}
>({
API, API,
datasource, datasource,
}: { }: {
API: APIClient API: APIClient
datasource: any datasource: TDatasource
}) => { }) => {
const handler = DataFetchMap[datasource?.type as keyof typeof DataFetchMap] const handler = DataFetchMap[datasource?.type as keyof typeof DataFetchMap]
if (!handler) { if (!handler) {
@ -54,25 +57,33 @@ const createEmptyFetchInstance = ({
} }
// Fetches the definition of any type of datasource // Fetches the definition of any type of datasource
export const getDatasourceDefinition = async ({ export const getDatasourceDefinition = async <
TDatasource extends {
type: keyof typeof DataFetchMap
}
>({
API, API,
datasource, datasource,
}: { }: {
API: APIClient API: APIClient
datasource: any datasource: TDatasource
}) => { }) => {
const instance = createEmptyFetchInstance({ API, datasource }) const instance = createEmptyFetchInstance({ API, datasource })
return await instance?.getDefinition(datasource) return await instance?.getDefinition()
} }
// Fetches the schema of any type of datasource // Fetches the schema of any type of datasource
export const getDatasourceSchema = ({ export const getDatasourceSchema = <
TDatasource extends {
type: keyof typeof DataFetchMap
}
>({
API, API,
datasource, datasource,
definition, definition,
}: { }: {
API: APIClient API: APIClient
datasource: UIDatasource datasource: TDatasource
definition?: any definition?: any
}) => { }) => {
const instance = createEmptyFetchInstance({ API, datasource }) const instance = createEmptyFetchInstance({ API, datasource })