Add support for nested provider, field and jsonarray datasource types in new data fetch model
This commit is contained in:
parent
9de896e526
commit
1eac218d6e
|
@ -0,0 +1,44 @@
|
||||||
|
import DataFetch from "./DataFetch.js"
|
||||||
|
|
||||||
|
export default class FieldFetch extends DataFetch {
|
||||||
|
static async getDefinition(datasource) {
|
||||||
|
// Field sources have their schema statically defined
|
||||||
|
let schema
|
||||||
|
if (datasource.fieldType === "attachment") {
|
||||||
|
schema = {
|
||||||
|
url: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else if (datasource.fieldType === "array") {
|
||||||
|
schema = {
|
||||||
|
value: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { schema }
|
||||||
|
}
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const { datasource } = this.options
|
||||||
|
|
||||||
|
// These sources will be available directly from context
|
||||||
|
const data = datasource?.value || []
|
||||||
|
let rows = []
|
||||||
|
if (Array.isArray(data) && data[0] && typeof data[0] !== "object") {
|
||||||
|
rows = data.map(value => ({ value }))
|
||||||
|
} else {
|
||||||
|
rows = data
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
rows: rows || [],
|
||||||
|
hasNextPage: false,
|
||||||
|
cursor: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import FieldFetch from "./FieldFetch.js"
|
||||||
|
import { fetchTableDefinition } from "api"
|
||||||
|
import { getJSONArrayDatasourceSchema } from "builder/src/builderStore/jsonUtils"
|
||||||
|
|
||||||
|
export default class JSONArrayFetch extends FieldFetch {
|
||||||
|
static async getDefinition(datasource) {
|
||||||
|
// JSON arrays need their table definitions fetched.
|
||||||
|
// We can then extract their schema as a subset of the table schema.
|
||||||
|
const table = await fetchTableDefinition(datasource.tableId)
|
||||||
|
const schema = getJSONArrayDatasourceSchema(table?.schema, datasource)
|
||||||
|
return { schema }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
import DataFetch from "./DataFetch.js"
|
||||||
|
|
||||||
|
export default class NestedProviderFetch extends DataFetch {
|
||||||
|
static async getDefinition(datasource) {
|
||||||
|
// Nested providers should already have exposed their own schema
|
||||||
|
return {
|
||||||
|
schema: datasource?.value?.schema,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const { datasource } = this.options
|
||||||
|
// Pull the rows from the existing data provider
|
||||||
|
return {
|
||||||
|
rows: datasource?.value?.rows || [],
|
||||||
|
hasNextPage: false,
|
||||||
|
cursor: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,12 +2,18 @@ import TableFetch from "./TableFetch.js"
|
||||||
import ViewFetch from "./ViewFetch.js"
|
import ViewFetch from "./ViewFetch.js"
|
||||||
import QueryFetch from "./QueryFetch.js"
|
import QueryFetch from "./QueryFetch.js"
|
||||||
import RelationshipFetch from "./RelationshipFetch.js"
|
import RelationshipFetch from "./RelationshipFetch.js"
|
||||||
|
import NestedProviderFetch from "./NestedProviderFetch.js"
|
||||||
|
import FieldFetch from "./FieldFetch.js"
|
||||||
|
import JSONArrayFetch from "./JSONArrayFetch.js"
|
||||||
|
|
||||||
const DataFetchMap = {
|
const DataFetchMap = {
|
||||||
table: TableFetch,
|
table: TableFetch,
|
||||||
view: ViewFetch,
|
view: ViewFetch,
|
||||||
query: QueryFetch,
|
query: QueryFetch,
|
||||||
link: RelationshipFetch,
|
link: RelationshipFetch,
|
||||||
|
provider: NestedProviderFetch,
|
||||||
|
field: FieldFetch,
|
||||||
|
jsonarray: JSONArrayFetch,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchData = (datasource, options) => {
|
export const fetchData = (datasource, options) => {
|
||||||
|
|
|
@ -1,83 +1,53 @@
|
||||||
import {
|
import { convertJSONSchemaToTableSchema } from "builder/src/builderStore/jsonUtils"
|
||||||
convertJSONSchemaToTableSchema,
|
|
||||||
getJSONArrayDatasourceSchema,
|
|
||||||
} from "builder/src/builderStore/jsonUtils"
|
|
||||||
import { fetchTableDefinition } from "api"
|
|
||||||
import TableFetch from "./fetch/TableFetch.js"
|
import TableFetch from "./fetch/TableFetch.js"
|
||||||
import ViewFetch from "./fetch/ViewFetch.js"
|
import ViewFetch from "./fetch/ViewFetch.js"
|
||||||
import QueryFetch from "./fetch/QueryFetch.js"
|
import QueryFetch from "./fetch/QueryFetch.js"
|
||||||
|
import RelationshipFetch from "./fetch/RelationshipFetch.js"
|
||||||
|
import NestedProviderFetch from "./fetch/NestedProviderFetch.js"
|
||||||
|
import FieldFetch from "./fetch/FieldFetch.js"
|
||||||
|
import JSONArrayFetch from "./fetch/JSONArrayFetch.js"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the schema of any kind of datasource.
|
* Fetches the schema of any kind of datasource.
|
||||||
|
* All datasource fetch classes implement their own functionality to get the
|
||||||
|
* schema of a datasource of their respective types.
|
||||||
*/
|
*/
|
||||||
export const fetchDatasourceSchema = async datasource => {
|
export const fetchDatasourceSchema = async datasource => {
|
||||||
const type = datasource?.type
|
|
||||||
let schema
|
|
||||||
|
|
||||||
// Nested providers should already have exposed their own schema
|
|
||||||
if (type === "provider") {
|
|
||||||
schema = datasource.value?.schema
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field sources have their schema statically defined
|
|
||||||
if (type === "field") {
|
|
||||||
if (datasource.fieldType === "attachment") {
|
|
||||||
schema = {
|
|
||||||
url: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else if (datasource.fieldType === "array") {
|
|
||||||
schema = {
|
|
||||||
value: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSON arrays need their table definitions fetched.
|
|
||||||
// We can then extract their schema as a subset of the table schema.
|
|
||||||
if (type === "jsonarray") {
|
|
||||||
const table = await fetchTableDefinition(datasource.tableId)
|
|
||||||
schema = getJSONArrayDatasourceSchema(table?.schema, datasource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// All normal datasource schema can use their corresponding implementations
|
|
||||||
// in the data fetch classes
|
|
||||||
const handler = {
|
const handler = {
|
||||||
table: TableFetch,
|
table: TableFetch,
|
||||||
link: TableFetch,
|
|
||||||
view: ViewFetch,
|
view: ViewFetch,
|
||||||
query: QueryFetch,
|
query: QueryFetch,
|
||||||
}[type]
|
link: RelationshipFetch,
|
||||||
if (handler) {
|
provider: NestedProviderFetch,
|
||||||
const definition = await handler.getDefinition(datasource)
|
field: FieldFetch,
|
||||||
schema = handler.getSchema(datasource, definition)
|
jsonarray: JSONArrayFetch,
|
||||||
|
}[datasource?.type]
|
||||||
|
if (!handler) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the datasource definition and then schema
|
||||||
|
const definition = await handler.getDefinition(datasource)
|
||||||
|
const schema = handler.getSchema(datasource, definition)
|
||||||
|
if (!schema) {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for any JSON fields so we can add any top level properties
|
// Check for any JSON fields so we can add any top level properties
|
||||||
if (schema) {
|
let jsonAdditions = {}
|
||||||
let jsonAdditions = {}
|
Object.keys(schema).forEach(fieldKey => {
|
||||||
Object.keys(schema).forEach(fieldKey => {
|
const fieldSchema = schema[fieldKey]
|
||||||
const fieldSchema = schema[fieldKey]
|
if (fieldSchema?.type === "json") {
|
||||||
if (fieldSchema?.type === "json") {
|
const jsonSchema = convertJSONSchemaToTableSchema(fieldSchema, {
|
||||||
const jsonSchema = convertJSONSchemaToTableSchema(fieldSchema, {
|
squashObjects: true,
|
||||||
squashObjects: true,
|
})
|
||||||
})
|
Object.keys(jsonSchema).forEach(jsonKey => {
|
||||||
Object.keys(jsonSchema).forEach(jsonKey => {
|
jsonAdditions[`${fieldKey}.${jsonKey}`] = {
|
||||||
jsonAdditions[`${fieldKey}.${jsonKey}`] = {
|
type: jsonSchema[jsonKey].type,
|
||||||
type: jsonSchema[jsonKey].type,
|
nestedJSON: true,
|
||||||
nestedJSON: true,
|
}
|
||||||
}
|
})
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
})
|
return { ...schema, ...jsonAdditions }
|
||||||
return { ...schema, ...jsonAdditions }
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue