fixes the structure of data connector (#91)

This commit is contained in:
Dogukan Karatas
2025-01-06 16:10:49 +01:00
committed by GitHub
parent ca34cd3adc
commit 6618e5654b
7 changed files with 10 additions and 348 deletions
+9 -15
View File
@@ -1,16 +1,16 @@
{
"folders": [
{
"name": "👀 powerbi-visual",
"path": "src/powerbi-visual"
"name": "🏠 root",
"path": "."
},
{
"name": "➡️ powerbi-data-connector",
"path": "src/powerbi-data-connector"
},
{
"name": "🏠 root",
"path": "."
"name": "👀 powerbi-visual",
"path": "src/powerbi-visual"
}
],
"settings": {
@@ -36,25 +36,19 @@
"typings": true,
"dist": true,
"wepbpack.statistics.dev.html": true,
"wepbpack.statistics.html": true,
"wepbpack.statistics.html": true
},
"json.schemas": [
{
"fileMatch": [
"/pbiviz.json"
],
"fileMatch": ["/pbiviz.json"],
"url": "./src/powerbi-visual/node_modules/powerbi-visuals-api/schema.pbiviz.json"
},
{
"fileMatch": [
"/capabilities.json"
],
"fileMatch": ["/capabilities.json"],
"url": "./src/powerbi-visual/node_modules/powerbi-visuals-api/schema.capabilities.json"
},
{
"fileMatch": [
"/dependencies.json"
],
"fileMatch": ["/dependencies.json"],
"url": "./src/powerbi-visual/node_modules/powerbi-visuals-api/schema.dependencies.json"
}
]
@@ -66,4 +60,4 @@
"powerquery.vscode-powerquery-sdk"
]
}
}
}
@@ -5,6 +5,7 @@
GetStructuredData = Extension.LoadFunction("GetStructuredData.pqm"),
GetRawData = Extension.LoadFunction("GetRawData.pqm"),
GetModel = Extension.LoadFunction("GetModel.pqm"),
// the logic for importing functions from other files
Extension.LoadFunction = (fileName as text) =>
let
@@ -36,7 +37,6 @@
),
// add navigation table metadata directly
tableType = Value.Type(source),
newTableType = Type.AddTableKey(tableType, {"Name"}, true) meta [
NavigationTable.NameColumn = "Name",
@@ -44,7 +44,6 @@
Documentation.Name = "Speckle Model"
],
// convert to navigation table
navTable = Value.ReplaceType(source, newTableType)
in
@@ -1,87 +0,0 @@
// function for getting model information through graphql query
(url as text) as record =>
let
// Import the parser function
Parser = Extension.LoadFunction("Parser.pqm"),
// the logic for importing functions from other files
Extension.LoadFunction = (fileName as text) =>
let
binary = Extension.Contents(fileName),
asText = Text.FromBinary(binary)
in
try
Expression.Evaluate(asText, #shared)
catch (e) =>
error
[
Reason = "Extension.LoadFunction Failure",
Message.Format = "Loading '#{0}' failed - '#{1}': '#{2}'",
Message.Parameters = {fileName, e[Reason], e[Message]},
Detail = [File = fileName, Error = e]
],
// Get parsed URL components
parsedUrl = Parser(url),
server = parsedUrl[baseUrl],
projectId = parsedUrl[projectId],
modelId = parsedUrl[modelId],
// Get API key if available
apiKey = try Extension.CurrentCredential()[Key] otherwise null,
// GraphQL query to get model info including root object id
query = "query ($projectId: String!, $modelId: String!) {
project(id: $projectId) {
model(id: $modelId) {
id
name
versions {
items {
id
referencedObject
}
}
}
}
}",
variables = [
projectId = projectId,
modelId = modelId
],
// Make the API request
Source = Web.Contents(
Text.Combine({server, "graphql"}, "/"),
[
Headers = [
#"Method" = "POST",
#"Content-Type" = "application/json",
#"Authorization" = if apiKey = null then "" else Text.Format("Bearer #{0}", {apiKey})
],
ManualStatusHandling = {400, 401, 403},
Content = Json.FromValue([
query = query,
variables = variables
])
]
),
// Parse the response
JsonResponse = Json.Document(Source),
// Extract needed information
result = if Record.HasFields(JsonResponse, {"errors"}) then
error JsonResponse[errors]{0}[message]
else if JsonResponse[data]?[project]?[model] = null then
error "Model not found or access denied. Please check your authentication and model ID."
else
[
modelId = JsonResponse[data][project][model][id],
modelName = JsonResponse[data][project][model][name],
versionId = JsonResponse[data][project][model][versions][items]{0}[id],
rootObjectId = JsonResponse[data][project][model][versions][items]{0}[referencedObject]
]
in
result
@@ -1,65 +0,0 @@
// function for getting the user info with graphql query
let
// import the parser function from Parser.pqm file
Parser = Extension.LoadFunction("Parser.pqm"),
// the logic for importing functions from other files
Extension.LoadFunction = (fileName as text) =>
let
binary = Extension.Contents(fileName),
asText = Text.FromBinary(binary)
in
try
Expression.Evaluate(asText, #shared)
catch (e) =>
error
[
Reason = "Extension.LoadFunction Failure",
Message.Format = "Loading '#{0}' failed - '#{1}': '#{2}'",
Message.Parameters = {fileName, e[Reason], e[Message]},
Detail = [File = fileName, Error = e]
]
in
(url as text) as record =>
let
// get base server URL using the imported function
parsedUrl = Parser(url),
server = parsedUrl[baseUrl],
apiKey = try Extension.CurrentCredential()[Key] otherwise null,
query = "query {
activeUser {
email
name
}
serverInfo {
name
company
version
}
}",
Source = Web.Contents(
Text.Combine({server, "graphql"}, "/"),
[
Headers = [
#"Method" = "POST",
#"Content-Type" = "application/json",
#"Authorization" = if apiKey = null then "" else Text.Format("Bearer #{0}", {apiKey})
],
ManualStatusHandling = {400},
Content = Json.FromValue([query = query])
]
),
JsonResponse = Json.Document(Source)
in
if Record.HasFields(JsonResponse, {"errors"}) then
error JsonResponse[errors]{0}[message]
else
[
UserEmail = JsonResponse[data][activeUser][email],
UserName = JsonResponse[data][activeUser][name],
ServerName = JsonResponse[data][serverInfo][name],
ServerCompany = JsonResponse[data][serverInfo][company],
ServerVersion = JsonResponse[data][serverInfo][version]
]
@@ -1,20 +0,0 @@
// function for parsing the url into base url, project id and model id
(url as text) as record =>
let
urlParts = Uri.Parts(url),
baseUrl = Text.Combine({urlParts[Scheme], "://", urlParts[Host]}),
pathSegments = List.Select(Text.Split(urlParts[Path], "/"), each _ <> ""),
// extract project and model IDs if they exist
projectId = if List.Count(pathSegments) >= 2 and pathSegments{0} = "projects"
then pathSegments{1} else null,
modelId = if List.Count(pathSegments) >= 4 and pathSegments{2} = "models"
then pathSegments{3} else null
in
[
baseUrl = baseUrl,
projectId = projectId,
modelId = modelId
]
@@ -1,61 +0,0 @@
// function for getting object data
(url as text) as table =>
let
// Import the parser function and getModel
Parser = Extension.LoadFunction("Parser.pqm"),
GetModel = Extension.LoadFunction("GetModel.pqm"),
// the logic for importing functions from other files
Extension.LoadFunction = (fileName as text) =>
let
binary = Extension.Contents(fileName),
asText = Text.FromBinary(binary)
in
try
Expression.Evaluate(asText, #shared)
catch (e) =>
error
[
Reason = "Extension.LoadFunction Failure",
Message.Format = "Loading '#{0}' failed - '#{1}': '#{2}'",
Message.Parameters = {fileName, e[Reason], e[Message]},
Detail = [File = fileName, Error = e]
],
// Get parsed URL components and model info
parsedUrl = Parser(url),
server = parsedUrl[baseUrl],
modelInfo = GetModel(url),
// Get API key if available
apiKey = try Extension.CurrentCredential()[Key] otherwise null,
// Make the API request to objects endpoint
Source = Web.Contents(
Text.Combine({server, "objects", parsedUrl[projectId], modelInfo[rootObjectId]}, "/"),
[
Headers = [
#"Authorization" = if apiKey = null then "" else Text.Format("Bearer #{0}", {apiKey})
],
ManualStatusHandling = {400, 401, 403}
]
),
// Parse the response and return the raw JSON
JsonResponse = Json.Document(Source),
ConvertedToTable = Table.FromList(
JsonResponse,
Splitter.SplitByNothing(),
{"viewer_data"},
null,
ExtraValues.Error
),
ExpandedTable = Table.AddColumn(
ConvertedToTable,
"speckle_id",
each Record.Field([viewer_data], "id"),
type text
)
in
ExpandedTable
@@ -1,98 +0,0 @@
// Function for getting structured object data
(url as text) as table =>
let
// Import the parser function and getModel
Parser = Extension.LoadFunction("Parser.pqm"),
GetModel = Extension.LoadFunction("GetModel.pqm"),
// the logic for importing functions from other files
Extension.LoadFunction = (fileName as text) =>
let
binary = Extension.Contents(fileName),
asText = Text.FromBinary(binary)
in
try
Expression.Evaluate(asText, #shared)
catch (e) =>
error
[
Reason = "Extension.LoadFunction Failure",
Message.Format = "Loading '#{0}' failed - '#{1}': '#{2}'",
Message.Parameters = {fileName, e[Reason], e[Message]},
Detail = [File = fileName, Error = e]
],
// Get parsed URL components and model info
parsedUrl = Parser(url),
server = parsedUrl[baseUrl],
modelInfo = GetModel(url),
// Get API key if available
apiKey = try Extension.CurrentCredential()[Key] otherwise null,
// Make the API request to objects endpoint
Source = Web.Contents(
Text.Combine({server, "objects", parsedUrl[projectId], modelInfo[rootObjectId]}, "/"),
[
Headers = [
#"Authorization" = if apiKey = null then "" else Text.Format("Bearer #{0}", {apiKey})
],
ManualStatusHandling = {400, 401, 403}
]
),
// Parse the JSON response
JsonResponse = Json.Document(Source),
// Convert list to table
ConvertedToTable = Table.FromList(
JsonResponse,
Splitter.SplitByNothing(),
null,
null,
ExtraValues.Error
),
// Expand initial record
ExpandedTable = Table.ExpandRecordColumn(
ConvertedToTable,
"Column1",
{
"id",
"name",
"type",
"units",
"version",
"elements",
"profile",
"material",
"__closure",
"properties",
"displayValue",
"data",
"speckle_type",
"applicationId",
"collectionType",
"renderMaterialProxies",
"totalChildrenCount"
}
),
// Remove rows where applicationId is null
FilteredTable = Table.SelectRows(ExpandedTable, each [applicationId] <> null),
// Create data column by combining all other columns except applicationId and speckle_type
FinalTable = Table.FromRecords(
List.Transform(
Table.ToRecords(FilteredTable),
each [
speckle_id = [id],
speckle_type = [speckle_type],
data = Record.RemoveFields(
_,
{"id", "speckle_type", "collectionType", "displayValue", "totalChildrenCount", "renderMaterialProxies", "data", "__closure"}
)
]
)
)
in
FinalTable