@budibase/frontend-core 3.2.37 → 3.2.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/api/configs.ts +2 -2
- package/src/api/index.ts +4 -8
- package/src/api/types.ts +2 -3
- package/src/api/views.ts +12 -2
- package/src/api/viewsV2.ts +9 -4
- package/src/components/grid/lib/{renderers.js → renderers.ts} +14 -4
- package/src/components/grid/lib/{websocket.js → websocket.ts} +6 -4
- package/src/components/grid/stores/config.ts +1 -1
- package/src/components/grid/stores/datasource.ts +12 -10
- package/src/components/grid/stores/rows.ts +5 -4
- package/src/constants.ts +2 -2
- package/src/fetch/{CustomFetch.js → CustomFetch.ts} +24 -12
- package/src/fetch/{DataFetch.js → DataFetch.ts} +158 -94
- package/src/fetch/FieldFetch.ts +67 -0
- package/src/fetch/{GroupUserFetch.js → GroupUserFetch.ts} +21 -5
- package/src/fetch/{JSONArrayFetch.js → JSONArrayFetch.ts} +5 -3
- package/src/fetch/NestedProviderFetch.ts +40 -0
- package/src/fetch/{QueryArrayFetch.js → QueryArrayFetch.ts} +12 -6
- package/src/fetch/{QueryFetch.js → QueryFetch.ts} +27 -9
- package/src/fetch/RelationshipFetch.ts +49 -0
- package/src/fetch/{TableFetch.js → TableFetch.ts} +27 -5
- package/src/fetch/{UserFetch.js → UserFetch.ts} +31 -14
- package/src/fetch/ViewFetch.ts +51 -0
- package/src/fetch/{ViewV2Fetch.js → ViewV2Fetch.ts} +46 -24
- package/src/fetch/index.ts +93 -0
- package/src/index.ts +2 -1
- package/src/utils/json.d.ts +23 -0
- package/src/utils/utils.js +3 -0
- package/src/components/grid/lib/utils.js +0 -32
- package/src/fetch/FieldFetch.js +0 -44
- package/src/fetch/NestedProviderFetch.js +0 -21
- package/src/fetch/RelationshipFetch.js +0 -20
- package/src/fetch/ViewFetch.js +0 -23
- package/src/fetch/index.js +0 -57
- /package/src/components/grid/lib/{constants.js → constants.ts} +0 -0
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import DataFetch from "./DataFetch
|
|
1
|
+
import DataFetch from "./DataFetch"
|
|
2
2
|
import { Helpers } from "@budibase/bbui"
|
|
3
|
+
import { ExecuteQueryRequest, Query } from "@budibase/types"
|
|
3
4
|
import { get } from "svelte/store"
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
interface QueryDatasource {
|
|
7
|
+
type: "query"
|
|
8
|
+
_id: string
|
|
9
|
+
fields: Record<string, any> & {
|
|
10
|
+
pagination?: {
|
|
11
|
+
type: string
|
|
12
|
+
location: string
|
|
13
|
+
pageParam: string
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
queryParams?: Record<string, string>
|
|
17
|
+
parameters: { name: string; default: string }[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default class QueryFetch extends DataFetch<QueryDatasource, Query> {
|
|
21
|
+
async determineFeatureFlags() {
|
|
22
|
+
const definition = await this.getDefinition()
|
|
7
23
|
const supportsPagination =
|
|
8
24
|
!!definition?.fields?.pagination?.type &&
|
|
9
25
|
!!definition?.fields?.pagination?.location &&
|
|
@@ -11,7 +27,9 @@ export default class QueryFetch extends DataFetch {
|
|
|
11
27
|
return { supportsPagination }
|
|
12
28
|
}
|
|
13
29
|
|
|
14
|
-
async getDefinition(
|
|
30
|
+
async getDefinition() {
|
|
31
|
+
const { datasource } = this.options
|
|
32
|
+
|
|
15
33
|
if (!datasource?._id) {
|
|
16
34
|
return null
|
|
17
35
|
}
|
|
@@ -40,17 +58,17 @@ export default class QueryFetch extends DataFetch {
|
|
|
40
58
|
const type = definition?.fields?.pagination?.type
|
|
41
59
|
|
|
42
60
|
// Set the default query params
|
|
43
|
-
|
|
44
|
-
for (
|
|
61
|
+
const parameters = Helpers.cloneDeep(datasource.queryParams || {})
|
|
62
|
+
for (const param of datasource?.parameters || []) {
|
|
45
63
|
if (!parameters[param.name]) {
|
|
46
64
|
parameters[param.name] = param.default
|
|
47
65
|
}
|
|
48
66
|
}
|
|
49
67
|
|
|
50
68
|
// Add pagination to query if supported
|
|
51
|
-
|
|
69
|
+
const queryPayload: ExecuteQueryRequest = { parameters }
|
|
52
70
|
if (paginate && supportsPagination) {
|
|
53
|
-
const requestCursor = type === "page" ? parseInt(cursor || 1) : cursor
|
|
71
|
+
const requestCursor = type === "page" ? parseInt(cursor || "1") : cursor
|
|
54
72
|
queryPayload.pagination = { page: requestCursor, limit }
|
|
55
73
|
}
|
|
56
74
|
|
|
@@ -65,7 +83,7 @@ export default class QueryFetch extends DataFetch {
|
|
|
65
83
|
if (paginate && supportsPagination) {
|
|
66
84
|
if (type === "page") {
|
|
67
85
|
// For "page number" pagination, increment the existing page number
|
|
68
|
-
nextCursor = queryPayload.pagination
|
|
86
|
+
nextCursor = queryPayload.pagination!.page! + 1
|
|
69
87
|
hasNextPage = data?.length === limit && limit > 0
|
|
70
88
|
} else {
|
|
71
89
|
// For "cursor" pagination, the cursor should be in the response
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Table } from "@budibase/types"
|
|
2
|
+
import DataFetch from "./DataFetch"
|
|
3
|
+
|
|
4
|
+
interface RelationshipDatasource {
|
|
5
|
+
type: "link"
|
|
6
|
+
tableId: string
|
|
7
|
+
rowId: string
|
|
8
|
+
rowTableId: string
|
|
9
|
+
fieldName: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default class RelationshipFetch extends DataFetch<
|
|
13
|
+
RelationshipDatasource,
|
|
14
|
+
Table
|
|
15
|
+
> {
|
|
16
|
+
async getDefinition() {
|
|
17
|
+
const { datasource } = this.options
|
|
18
|
+
|
|
19
|
+
if (!datasource?.tableId) {
|
|
20
|
+
return null
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return await this.API.fetchTableDefinition(datasource.tableId)
|
|
24
|
+
} catch (error: any) {
|
|
25
|
+
this.store.update(state => ({
|
|
26
|
+
...state,
|
|
27
|
+
error,
|
|
28
|
+
}))
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async getData() {
|
|
34
|
+
const { datasource } = this.options
|
|
35
|
+
if (!datasource?.rowId || !datasource?.rowTableId) {
|
|
36
|
+
return { rows: [] }
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const res = await this.API.fetchRelationshipData(
|
|
40
|
+
datasource.rowTableId,
|
|
41
|
+
datasource.rowId,
|
|
42
|
+
datasource.fieldName
|
|
43
|
+
)
|
|
44
|
+
return { rows: res }
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return { rows: [] }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { get } from "svelte/store"
|
|
2
|
-
import DataFetch from "./DataFetch
|
|
3
|
-
import { SortOrder } from "@budibase/types"
|
|
2
|
+
import DataFetch from "./DataFetch"
|
|
3
|
+
import { SortOrder, Table } from "@budibase/types"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
interface TableDatasource {
|
|
6
|
+
type: "table"
|
|
7
|
+
tableId: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default class TableFetch extends DataFetch<TableDatasource, Table> {
|
|
11
|
+
async determineFeatureFlags() {
|
|
7
12
|
return {
|
|
8
13
|
supportsSearch: true,
|
|
9
14
|
supportsSort: true,
|
|
@@ -11,6 +16,23 @@ export default class TableFetch extends DataFetch {
|
|
|
11
16
|
}
|
|
12
17
|
}
|
|
13
18
|
|
|
19
|
+
async getDefinition() {
|
|
20
|
+
const { datasource } = this.options
|
|
21
|
+
|
|
22
|
+
if (!datasource?.tableId) {
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return await this.API.fetchTableDefinition(datasource.tableId)
|
|
27
|
+
} catch (error: any) {
|
|
28
|
+
this.store.update(state => ({
|
|
29
|
+
...state,
|
|
30
|
+
error,
|
|
31
|
+
}))
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
14
36
|
async getData() {
|
|
15
37
|
const { datasource, limit, sortColumn, sortOrder, sortType, paginate } =
|
|
16
38
|
this.options
|
|
@@ -23,7 +45,7 @@ export default class TableFetch extends DataFetch {
|
|
|
23
45
|
query,
|
|
24
46
|
limit,
|
|
25
47
|
sort: sortColumn,
|
|
26
|
-
sortOrder: sortOrder
|
|
48
|
+
sortOrder: sortOrder ?? SortOrder.ASCENDING,
|
|
27
49
|
sortType,
|
|
28
50
|
paginate,
|
|
29
51
|
bookmark: cursor,
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import { get } from "svelte/store"
|
|
2
|
-
import DataFetch from "./DataFetch
|
|
2
|
+
import DataFetch, { DataFetchParams } from "./DataFetch"
|
|
3
3
|
import { TableNames } from "../constants"
|
|
4
4
|
import { utils } from "@budibase/shared-core"
|
|
5
|
+
import { SearchFilters, SearchUsersRequest } from "@budibase/types"
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
interface UserFetchQuery {
|
|
8
|
+
appId: string
|
|
9
|
+
paginated: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface UserDatasource {
|
|
13
|
+
type: "user"
|
|
14
|
+
tableId: TableNames.USERS
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface UserDefinition {}
|
|
18
|
+
|
|
19
|
+
export default class UserFetch extends DataFetch<
|
|
20
|
+
UserDatasource,
|
|
21
|
+
UserDefinition,
|
|
22
|
+
UserFetchQuery
|
|
23
|
+
> {
|
|
24
|
+
constructor(opts: DataFetchParams<UserDatasource, UserFetchQuery>) {
|
|
8
25
|
super({
|
|
9
26
|
...opts,
|
|
10
27
|
datasource: {
|
|
28
|
+
type: "user",
|
|
11
29
|
tableId: TableNames.USERS,
|
|
12
30
|
},
|
|
13
31
|
})
|
|
14
32
|
}
|
|
15
33
|
|
|
16
|
-
determineFeatureFlags() {
|
|
34
|
+
async determineFeatureFlags() {
|
|
17
35
|
return {
|
|
18
36
|
supportsSearch: true,
|
|
19
37
|
supportsSort: false,
|
|
@@ -22,9 +40,7 @@ export default class UserFetch extends DataFetch {
|
|
|
22
40
|
}
|
|
23
41
|
|
|
24
42
|
async getDefinition() {
|
|
25
|
-
return {
|
|
26
|
-
schema: {},
|
|
27
|
-
}
|
|
43
|
+
return { schema: {} }
|
|
28
44
|
}
|
|
29
45
|
|
|
30
46
|
async getData() {
|
|
@@ -32,15 +48,16 @@ export default class UserFetch extends DataFetch {
|
|
|
32
48
|
const { cursor, query } = get(this.store)
|
|
33
49
|
|
|
34
50
|
// Convert old format to new one - we now allow use of the lucene format
|
|
35
|
-
const { appId, paginated, ...rest } = query
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
const { appId, paginated, ...rest } = query
|
|
52
|
+
|
|
53
|
+
const finalQuery: SearchFilters = utils.isSupportedUserSearch(rest)
|
|
54
|
+
? rest
|
|
55
|
+
: {}
|
|
39
56
|
|
|
40
57
|
try {
|
|
41
|
-
const opts = {
|
|
42
|
-
bookmark: cursor,
|
|
43
|
-
query: finalQuery,
|
|
58
|
+
const opts: SearchUsersRequest = {
|
|
59
|
+
bookmark: cursor ?? undefined,
|
|
60
|
+
query: finalQuery ?? undefined,
|
|
44
61
|
appId: appId,
|
|
45
62
|
paginate: paginated || paginate,
|
|
46
63
|
limit,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Table } from "@budibase/types"
|
|
2
|
+
import DataFetch from "./DataFetch"
|
|
3
|
+
|
|
4
|
+
type ViewV1Datasource = {
|
|
5
|
+
type: "view"
|
|
6
|
+
name: string
|
|
7
|
+
tableId: string
|
|
8
|
+
calculation: string
|
|
9
|
+
field: string
|
|
10
|
+
groupBy: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default class ViewFetch extends DataFetch<ViewV1Datasource, Table> {
|
|
14
|
+
async getDefinition() {
|
|
15
|
+
const { datasource } = this.options
|
|
16
|
+
|
|
17
|
+
if (!datasource?.tableId) {
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
return await this.API.fetchTableDefinition(datasource.tableId)
|
|
22
|
+
} catch (error: any) {
|
|
23
|
+
this.store.update(state => ({
|
|
24
|
+
...state,
|
|
25
|
+
error,
|
|
26
|
+
}))
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getSchema(definition: Table) {
|
|
32
|
+
const { datasource } = this.options
|
|
33
|
+
return definition?.views?.[datasource.name]?.schema
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async getData() {
|
|
37
|
+
const { datasource } = this.options
|
|
38
|
+
try {
|
|
39
|
+
const res = await this.API.fetchViewData(datasource.name, {
|
|
40
|
+
calculation: datasource.calculation,
|
|
41
|
+
field: datasource.field,
|
|
42
|
+
groupBy: datasource.groupBy,
|
|
43
|
+
tableId: datasource.tableId,
|
|
44
|
+
})
|
|
45
|
+
return { rows: res || [] }
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error(error, { datasource })
|
|
48
|
+
return { rows: [] }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
import { ViewV2Type } from "@budibase/types"
|
|
2
|
-
import DataFetch from "./DataFetch
|
|
1
|
+
import { SortOrder, ViewV2Enriched, ViewV2Type } from "@budibase/types"
|
|
2
|
+
import DataFetch from "./DataFetch"
|
|
3
3
|
import { get } from "svelte/store"
|
|
4
|
+
import { helpers } from "@budibase/shared-core"
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
interface ViewDatasource {
|
|
7
|
+
type: "viewV2"
|
|
8
|
+
id: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default class ViewV2Fetch extends DataFetch<
|
|
12
|
+
ViewDatasource,
|
|
13
|
+
ViewV2Enriched
|
|
14
|
+
> {
|
|
15
|
+
async determineFeatureFlags() {
|
|
7
16
|
return {
|
|
8
17
|
supportsSearch: true,
|
|
9
18
|
supportsSort: true,
|
|
@@ -11,18 +20,13 @@ export default class ViewV2Fetch extends DataFetch {
|
|
|
11
20
|
}
|
|
12
21
|
}
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
23
|
+
async getDefinition() {
|
|
24
|
+
const { datasource } = this.options
|
|
17
25
|
|
|
18
|
-
async getDefinition(datasource) {
|
|
19
|
-
if (!datasource?.id) {
|
|
20
|
-
return null
|
|
21
|
-
}
|
|
22
26
|
try {
|
|
23
27
|
const res = await this.API.viewV2.fetchDefinition(datasource.id)
|
|
24
28
|
return res?.data
|
|
25
|
-
} catch (error) {
|
|
29
|
+
} catch (error: any) {
|
|
26
30
|
this.store.update(state => ({
|
|
27
31
|
...state,
|
|
28
32
|
error,
|
|
@@ -42,8 +46,10 @@ export default class ViewV2Fetch extends DataFetch {
|
|
|
42
46
|
|
|
43
47
|
// If this is a calculation view and we have no calculations, return nothing
|
|
44
48
|
if (
|
|
45
|
-
definition
|
|
46
|
-
!Object.values(definition.schema || {}).some(
|
|
49
|
+
definition?.type === ViewV2Type.CALCULATION &&
|
|
50
|
+
!Object.values(definition.schema || {}).some(
|
|
51
|
+
helpers.views.isCalculationField
|
|
52
|
+
)
|
|
47
53
|
) {
|
|
48
54
|
return {
|
|
49
55
|
rows: [],
|
|
@@ -56,25 +62,41 @@ export default class ViewV2Fetch extends DataFetch {
|
|
|
56
62
|
// If sort/filter params are not defined, update options to store the
|
|
57
63
|
// params built in to this view. This ensures that we can accurately
|
|
58
64
|
// compare old and new params and skip a redundant API call.
|
|
59
|
-
if (!sortColumn && definition
|
|
65
|
+
if (!sortColumn && definition?.sort?.field) {
|
|
60
66
|
this.options.sortColumn = definition.sort.field
|
|
61
|
-
this.options.sortOrder = definition.sort.order
|
|
67
|
+
this.options.sortOrder = definition.sort.order || SortOrder.ASCENDING
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
try {
|
|
65
|
-
const
|
|
66
|
-
|
|
71
|
+
const request = {
|
|
72
|
+
query,
|
|
67
73
|
paginate,
|
|
68
74
|
limit,
|
|
69
75
|
bookmark: cursor,
|
|
70
76
|
sort: sortColumn,
|
|
71
|
-
sortOrder: sortOrder
|
|
77
|
+
sortOrder: sortOrder,
|
|
72
78
|
sortType,
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
}
|
|
80
|
+
if (paginate) {
|
|
81
|
+
const res = await this.API.viewV2.fetch(datasource.id, {
|
|
82
|
+
...request,
|
|
83
|
+
paginate,
|
|
84
|
+
})
|
|
85
|
+
return {
|
|
86
|
+
rows: res?.rows || [],
|
|
87
|
+
hasNextPage: res?.hasNextPage || false,
|
|
88
|
+
cursor: res?.bookmark || null,
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
const res = await this.API.viewV2.fetch(datasource.id, {
|
|
92
|
+
...request,
|
|
93
|
+
paginate,
|
|
94
|
+
})
|
|
95
|
+
return {
|
|
96
|
+
rows: res?.rows || [],
|
|
97
|
+
hasNextPage: false,
|
|
98
|
+
cursor: null,
|
|
99
|
+
}
|
|
78
100
|
}
|
|
79
101
|
} catch (error) {
|
|
80
102
|
return {
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import TableFetch from "./TableFetch"
|
|
2
|
+
import ViewFetch from "./ViewFetch"
|
|
3
|
+
import ViewV2Fetch from "./ViewV2Fetch"
|
|
4
|
+
import QueryFetch from "./QueryFetch"
|
|
5
|
+
import RelationshipFetch from "./RelationshipFetch"
|
|
6
|
+
import NestedProviderFetch from "./NestedProviderFetch"
|
|
7
|
+
import FieldFetch from "./FieldFetch"
|
|
8
|
+
import JSONArrayFetch from "./JSONArrayFetch"
|
|
9
|
+
import UserFetch from "./UserFetch"
|
|
10
|
+
import GroupUserFetch from "./GroupUserFetch"
|
|
11
|
+
import CustomFetch from "./CustomFetch"
|
|
12
|
+
import QueryArrayFetch from "./QueryArrayFetch"
|
|
13
|
+
import { APIClient } from "../api/types"
|
|
14
|
+
|
|
15
|
+
export type DataFetchType = keyof typeof DataFetchMap
|
|
16
|
+
|
|
17
|
+
export const DataFetchMap = {
|
|
18
|
+
table: TableFetch,
|
|
19
|
+
view: ViewFetch,
|
|
20
|
+
viewV2: ViewV2Fetch,
|
|
21
|
+
query: QueryFetch,
|
|
22
|
+
link: RelationshipFetch,
|
|
23
|
+
user: UserFetch,
|
|
24
|
+
groupUser: GroupUserFetch,
|
|
25
|
+
custom: CustomFetch,
|
|
26
|
+
|
|
27
|
+
// Client specific datasource types
|
|
28
|
+
provider: NestedProviderFetch,
|
|
29
|
+
field: FieldFetch<"field">,
|
|
30
|
+
jsonarray: JSONArrayFetch,
|
|
31
|
+
queryarray: QueryArrayFetch,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Constructs a new fetch model for a certain datasource
|
|
35
|
+
export const fetchData = ({ API, datasource, options }: any) => {
|
|
36
|
+
const Fetch = DataFetchMap[datasource?.type as DataFetchType] || TableFetch
|
|
37
|
+
const fetch = new Fetch({ API, datasource, ...options })
|
|
38
|
+
|
|
39
|
+
// Initially fetch data but don't bother waiting for the result
|
|
40
|
+
fetch.getInitialData()
|
|
41
|
+
|
|
42
|
+
return fetch
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Creates an empty fetch instance with no datasource configured, so no data
|
|
46
|
+
// will initially be loaded
|
|
47
|
+
const createEmptyFetchInstance = <TDatasource extends { type: DataFetchType }>({
|
|
48
|
+
API,
|
|
49
|
+
datasource,
|
|
50
|
+
}: {
|
|
51
|
+
API: APIClient
|
|
52
|
+
datasource: TDatasource
|
|
53
|
+
}) => {
|
|
54
|
+
const handler = DataFetchMap[datasource?.type as DataFetchType]
|
|
55
|
+
if (!handler) {
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
58
|
+
return new handler({
|
|
59
|
+
API,
|
|
60
|
+
datasource: null as never,
|
|
61
|
+
query: null as any,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Fetches the definition of any type of datasource
|
|
66
|
+
export const getDatasourceDefinition = async <
|
|
67
|
+
TDatasource extends { type: DataFetchType }
|
|
68
|
+
>({
|
|
69
|
+
API,
|
|
70
|
+
datasource,
|
|
71
|
+
}: {
|
|
72
|
+
API: APIClient
|
|
73
|
+
datasource: TDatasource
|
|
74
|
+
}) => {
|
|
75
|
+
const instance = createEmptyFetchInstance({ API, datasource })
|
|
76
|
+
return await instance?.getDefinition()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Fetches the schema of any type of datasource
|
|
80
|
+
export const getDatasourceSchema = <
|
|
81
|
+
TDatasource extends { type: DataFetchType }
|
|
82
|
+
>({
|
|
83
|
+
API,
|
|
84
|
+
datasource,
|
|
85
|
+
definition,
|
|
86
|
+
}: {
|
|
87
|
+
API: APIClient
|
|
88
|
+
datasource: TDatasource
|
|
89
|
+
definition?: any
|
|
90
|
+
}) => {
|
|
91
|
+
const instance = createEmptyFetchInstance({ API, datasource })
|
|
92
|
+
return instance?.getSchema(definition)
|
|
93
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { createAPIClient } from "./api"
|
|
2
|
-
export { fetchData } from "./fetch"
|
|
2
|
+
export { fetchData, DataFetchMap } from "./fetch"
|
|
3
|
+
export type { DataFetchType } from "./fetch"
|
|
3
4
|
export * as Constants from "./constants"
|
|
4
5
|
export * from "./stores"
|
|
5
6
|
export * from "./utils"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { JsonFieldMetadata, QuerySchema } from "@budibase/types"
|
|
2
|
+
|
|
3
|
+
type Schema = Record<string, QuerySchema | string>
|
|
4
|
+
|
|
5
|
+
declare module "./json" {
|
|
6
|
+
export const getJSONArrayDatasourceSchema: (
|
|
7
|
+
tableSchema: Schema,
|
|
8
|
+
datasource: any
|
|
9
|
+
) => Record<string, { type: string; name: string; prefixKeys: string }>
|
|
10
|
+
|
|
11
|
+
export const generateQueryArraySchemas: (
|
|
12
|
+
schema: Schema,
|
|
13
|
+
nestedSchemaFields?: Record<string, Schema>
|
|
14
|
+
) => Schema
|
|
15
|
+
|
|
16
|
+
export const convertJSONSchemaToTableSchema: (
|
|
17
|
+
jsonSchema: JsonFieldMetadata,
|
|
18
|
+
options: {
|
|
19
|
+
squashObjects?: boolean
|
|
20
|
+
prefixKeys?: string
|
|
21
|
+
}
|
|
22
|
+
) => Record<string, { type: string; name: string; prefixKeys: string }>
|
|
23
|
+
}
|
package/src/utils/utils.js
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// TODO: remove when all stores are typed
|
|
2
|
-
|
|
3
|
-
import { GeneratedIDPrefix, CellIDSeparator } from "./constants"
|
|
4
|
-
import { Helpers } from "@budibase/bbui"
|
|
5
|
-
|
|
6
|
-
export const parseCellID = cellId => {
|
|
7
|
-
if (!cellId) {
|
|
8
|
-
return { rowId: undefined, field: undefined }
|
|
9
|
-
}
|
|
10
|
-
const parts = cellId.split(CellIDSeparator)
|
|
11
|
-
const field = parts.pop()
|
|
12
|
-
return { rowId: parts.join(CellIDSeparator), field }
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const getCellID = (rowId, fieldName) => {
|
|
16
|
-
return `${rowId}${CellIDSeparator}${fieldName}`
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const parseEventLocation = e => {
|
|
20
|
-
return {
|
|
21
|
-
x: e.clientX ?? e.touches?.[0]?.clientX,
|
|
22
|
-
y: e.clientY ?? e.touches?.[0]?.clientY,
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const generateRowID = () => {
|
|
27
|
-
return `${GeneratedIDPrefix}${Helpers.uuid()}`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const isGeneratedRowID = id => {
|
|
31
|
-
return id?.startsWith(GeneratedIDPrefix)
|
|
32
|
-
}
|
package/src/fetch/FieldFetch.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import DataFetch from "./DataFetch.js"
|
|
2
|
-
|
|
3
|
-
export default class FieldFetch extends DataFetch {
|
|
4
|
-
async getDefinition(datasource) {
|
|
5
|
-
// Field sources have their schema statically defined
|
|
6
|
-
let schema
|
|
7
|
-
if (datasource.fieldType === "attachment") {
|
|
8
|
-
schema = {
|
|
9
|
-
url: {
|
|
10
|
-
type: "string",
|
|
11
|
-
},
|
|
12
|
-
name: {
|
|
13
|
-
type: "string",
|
|
14
|
-
},
|
|
15
|
-
}
|
|
16
|
-
} else if (datasource.fieldType === "array") {
|
|
17
|
-
schema = {
|
|
18
|
-
value: {
|
|
19
|
-
type: "string",
|
|
20
|
-
},
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return { schema }
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async getData() {
|
|
27
|
-
const { datasource } = this.options
|
|
28
|
-
|
|
29
|
-
// These sources will be available directly from context
|
|
30
|
-
const data = datasource?.value || []
|
|
31
|
-
let rows
|
|
32
|
-
if (Array.isArray(data) && data[0] && typeof data[0] !== "object") {
|
|
33
|
-
rows = data.map(value => ({ value }))
|
|
34
|
-
} else {
|
|
35
|
-
rows = data
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
rows: rows || [],
|
|
40
|
-
hasNextPage: false,
|
|
41
|
-
cursor: null,
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import DataFetch from "./DataFetch.js"
|
|
2
|
-
|
|
3
|
-
export default class NestedProviderFetch extends DataFetch {
|
|
4
|
-
async getDefinition(datasource) {
|
|
5
|
-
// Nested providers should already have exposed their own schema
|
|
6
|
-
return {
|
|
7
|
-
schema: datasource?.value?.schema,
|
|
8
|
-
primaryDisplay: datasource?.value?.primaryDisplay,
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async getData() {
|
|
13
|
-
const { datasource } = this.options
|
|
14
|
-
// Pull the rows from the existing data provider
|
|
15
|
-
return {
|
|
16
|
-
rows: datasource?.value?.rows || [],
|
|
17
|
-
hasNextPage: false,
|
|
18
|
-
cursor: null,
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import DataFetch from "./DataFetch.js"
|
|
2
|
-
|
|
3
|
-
export default class RelationshipFetch extends DataFetch {
|
|
4
|
-
async getData() {
|
|
5
|
-
const { datasource } = this.options
|
|
6
|
-
if (!datasource?.rowId || !datasource?.rowTableId) {
|
|
7
|
-
return { rows: [] }
|
|
8
|
-
}
|
|
9
|
-
try {
|
|
10
|
-
const res = await this.API.fetchRelationshipData(
|
|
11
|
-
datasource.rowTableId,
|
|
12
|
-
datasource.rowId,
|
|
13
|
-
datasource.fieldName
|
|
14
|
-
)
|
|
15
|
-
return { rows: res }
|
|
16
|
-
} catch (error) {
|
|
17
|
-
return { rows: [] }
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
package/src/fetch/ViewFetch.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import DataFetch from "./DataFetch.js"
|
|
2
|
-
|
|
3
|
-
export default class ViewFetch extends DataFetch {
|
|
4
|
-
getSchema(datasource, definition) {
|
|
5
|
-
return definition?.views?.[datasource.name]?.schema
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
async getData() {
|
|
9
|
-
const { datasource } = this.options
|
|
10
|
-
try {
|
|
11
|
-
const res = await this.API.fetchViewData(datasource.name, {
|
|
12
|
-
calculation: datasource.calculation,
|
|
13
|
-
field: datasource.field,
|
|
14
|
-
groupBy: datasource.groupBy,
|
|
15
|
-
tableId: datasource.tableId,
|
|
16
|
-
})
|
|
17
|
-
return { rows: res || [] }
|
|
18
|
-
} catch (error) {
|
|
19
|
-
console.error(error)
|
|
20
|
-
return { rows: [] }
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|