forked from tsai/budibase
5 changed files with 119 additions and 66 deletions
@ -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, |
|||
} |
|||
} |
|||
} |
|||
@ -1,83 +1,53 @@ |
|||
import { |
|||
convertJSONSchemaToTableSchema, |
|||
getJSONArrayDatasourceSchema, |
|||
} from "builder/src/builderStore/jsonUtils" |
|||
import { fetchTableDefinition } from "api" |
|||
import { convertJSONSchemaToTableSchema } from "builder/src/builderStore/jsonUtils" |
|||
import TableFetch from "./fetch/TableFetch.js" |
|||
import ViewFetch from "./fetch/ViewFetch.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. |
|||
* All datasource fetch classes implement their own functionality to get the |
|||
* schema of a datasource of their respective types. |
|||
*/ |
|||
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 = { |
|||
table: TableFetch, |
|||
link: TableFetch, |
|||
view: ViewFetch, |
|||
query: QueryFetch, |
|||
}[type] |
|||
if (handler) { |
|||
const definition = await handler.getDefinition(datasource) |
|||
schema = handler.getSchema(datasource, definition) |
|||
link: RelationshipFetch, |
|||
provider: NestedProviderFetch, |
|||
field: FieldFetch, |
|||
jsonarray: JSONArrayFetch, |
|||
}[datasource?.type] |
|||
if (!handler) { |
|||
return null |
|||
} |
|||
|
|||
// Check for any JSON fields so we can add any top level properties
|
|||
if (schema) { |
|||
let jsonAdditions = {} |
|||
Object.keys(schema).forEach(fieldKey => { |
|||
const fieldSchema = schema[fieldKey] |
|||
if (fieldSchema?.type === "json") { |
|||
const jsonSchema = convertJSONSchemaToTableSchema(fieldSchema, { |
|||
squashObjects: true, |
|||
}) |
|||
Object.keys(jsonSchema).forEach(jsonKey => { |
|||
jsonAdditions[`${fieldKey}.${jsonKey}`] = { |
|||
type: jsonSchema[jsonKey].type, |
|||
nestedJSON: true, |
|||
} |
|||
}) |
|||
} |
|||
}) |
|||
return { ...schema, ...jsonAdditions } |
|||
// Get the datasource definition and then schema
|
|||
const definition = await handler.getDefinition(datasource) |
|||
const schema = handler.getSchema(datasource, definition) |
|||
if (!schema) { |
|||
return null |
|||
} |
|||
|
|||
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 = convertJSONSchemaToTableSchema(fieldSchema, { |
|||
squashObjects: true, |
|||
}) |
|||
Object.keys(jsonSchema).forEach(jsonKey => { |
|||
jsonAdditions[`${fieldKey}.${jsonKey}`] = { |
|||
type: jsonSchema[jsonKey].type, |
|||
nestedJSON: true, |
|||
} |
|||
}) |
|||
} |
|||
}) |
|||
return { ...schema, ...jsonAdditions } |
|||
} |
|||
|
|||
Loading…
Reference in new issue