84 lines
2.8 KiB
JavaScript
84 lines
2.8 KiB
JavaScript
import { API } from "api"
|
|
import { JSONUtils } from "@budibase/frontend-core"
|
|
import TableFetch from "@budibase/frontend-core/src/fetch/TableFetch.js"
|
|
import ViewFetch from "@budibase/frontend-core/src/fetch/ViewFetch.js"
|
|
import QueryFetch from "@budibase/frontend-core/src/fetch/QueryFetch.js"
|
|
import RelationshipFetch from "@budibase/frontend-core/src/fetch/RelationshipFetch.js"
|
|
import NestedProviderFetch from "@budibase/frontend-core/src/fetch/NestedProviderFetch.js"
|
|
import FieldFetch from "@budibase/frontend-core/src/fetch/FieldFetch.js"
|
|
import JSONArrayFetch from "@budibase/frontend-core/src/fetch/JSONArrayFetch.js"
|
|
|
|
/**
|
|
* 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.
|
|
* @param datasource the datasource to fetch the schema for
|
|
* @param options options for enriching the schema
|
|
*/
|
|
export const fetchDatasourceSchema = async (
|
|
datasource,
|
|
options = { enrichRelationships: false }
|
|
) => {
|
|
const handler = {
|
|
table: TableFetch,
|
|
view: ViewFetch,
|
|
query: QueryFetch,
|
|
link: RelationshipFetch,
|
|
provider: NestedProviderFetch,
|
|
field: FieldFetch,
|
|
jsonarray: JSONArrayFetch,
|
|
}[datasource?.type]
|
|
if (!handler) {
|
|
return null
|
|
}
|
|
const instance = new handler({ API })
|
|
|
|
// Get the datasource definition and then schema
|
|
const definition = await instance.getDefinition(datasource)
|
|
let schema = instance.getSchema(datasource, definition)
|
|
if (!schema) {
|
|
return null
|
|
}
|
|
|
|
// Check for any JSON fields so we can add any top level properties
|
|
let jsonAdditions = {}
|
|
Object.keys(schema).forEach(fieldKey => {
|
|
const fieldSchema = schema[fieldKey]
|
|
if (fieldSchema?.type === "json") {
|
|
const jsonSchema = JSONUtils.convertJSONSchemaToTableSchema(fieldSchema, {
|
|
squashObjects: true,
|
|
})
|
|
Object.keys(jsonSchema).forEach(jsonKey => {
|
|
jsonAdditions[`${fieldKey}.${jsonKey}`] = {
|
|
type: jsonSchema[jsonKey].type,
|
|
nestedJSON: true,
|
|
}
|
|
})
|
|
}
|
|
})
|
|
schema = { ...schema, ...jsonAdditions }
|
|
|
|
// Check for any relationship fields if required
|
|
if (options?.enrichRelationships && definition.sql) {
|
|
let relationshipAdditions = {}
|
|
for (let fieldKey of Object.keys(schema)) {
|
|
const fieldSchema = schema[fieldKey]
|
|
if (fieldSchema?.type === "link") {
|
|
const linkSchema = await fetchDatasourceSchema({
|
|
type: "table",
|
|
tableId: fieldSchema?.tableId,
|
|
})
|
|
Object.keys(linkSchema || {}).forEach(linkKey => {
|
|
relationshipAdditions[`${fieldKey}.${linkKey}`] = {
|
|
type: linkSchema[linkKey].type,
|
|
}
|
|
})
|
|
}
|
|
}
|
|
schema = { ...schema, ...relationshipAdditions }
|
|
}
|
|
|
|
// Ensure schema structure is correct
|
|
return instance.enrichSchema(schema)
|
|
}
|