Compare commits

...

1 Commits

Author SHA1 Message Date
bimgeek 92aaeebaa3 Speckle.Versions.List function 2025-10-15 16:35:48 +03:00
2 changed files with 157 additions and 0 deletions
+6
View File
@@ -148,6 +148,12 @@ shared Speckle.GetWorkspace = Value.ReplaceType(
type function (url as Uri.Type) as record
);
[DataSource.Kind = "Speckle"]
shared Speckle.Versions.List = Value.ReplaceType(
Speckle.LoadFunction("Versions.List.pqm"),
type function (url as Uri.Type) as table
);
shared Speckle.Objects.Properties = Value.ReplaceType(
Speckle.LoadFunction("Objects.Properties.pqm"),
type function (inputRecord as any, optional filterKeys as list, optional parentPath as text, optional existingFields as list) as record
@@ -0,0 +1,151 @@
// function for listing all versions of a model
(url as text) as table =>
let
// import required functions
ApiFetch = Extension.LoadFunction("Api.Fetch.pqm"),
Parser = Extension.LoadFunction("Parser.pqm"),
CheckPermissions = Extension.LoadFunction("CheckPermissions.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]
],
// parse the URL to extract necessary components
parsedUrl = Parser(url),
server = parsedUrl[baseUrl],
projectId = parsedUrl[projectId],
modelId = parsedUrl[modelId],
// validate that both projectId and modelId exist
urlValidation = if projectId = null or modelId = null then
error [
Reason = "Invalid URL",
Message = "The URL must contain both a project ID and a model ID. Federated models are not supported.",
Detail = [
URL = url,
ProjectId = projectId,
ModelId = modelId,
IsFederated = parsedUrl[isFederated]
]
]
else
null,
// check if user has permission to load the model
permissionCheck = CheckPermissions(url),
// if not authorized, throw an error with the message from the server
authCheck = if not permissionCheck[authorized] then
error [
Reason = "Permission denied",
Message = Text.Format(
"#{0} (Error code: #{1})",
{permissionCheck[message], permissionCheck[code]}
),
Detail = [
URL = url,
Code = permissionCheck[code]
]
]
else
null,
// GraphQL query to get all versions
query = "query Query($projectId: String!, $modelId: String!, $limit: Int!) {
project(id: $projectId) {
model(id: $modelId) {
versions(limit: $limit) {
items {
id
message
createdAt
referencedObject
}
}
}
}
}",
// variables for the GraphQL query
variables = [
projectId = projectId,
modelId = modelId,
limit = 100
],
// make the API request
result = try ApiFetch(server, query, variables) otherwise
error [
Reason = "API Request Failed",
Message = "Failed to fetch versions from the Speckle server",
Detail = [
Server = server,
ProjectId = projectId,
ModelId = modelId
]
],
// validate response structure
responseValidation = if not (Record.HasFields(result, {"project"}) and
Record.HasFields(result[project], {"model"}) and
Record.HasFields(result[project][model], {"versions"}) and
Record.HasFields(result[project][model][versions], {"items"})) then
error [
Reason = "Invalid Response",
Message = "Server returned unexpected response structure",
Detail = [Result = result]
]
else
null,
// extract versions items
versionItems = result[project][model][versions][items],
// transform into table with Version ID, Version Message, Timestamp, Version Object ID, and Version URL
versionsTable = Table.FromRecords(
List.Transform(
versionItems,
each [
#"Version ID" = [id],
#"Version Message" = if [message] = null then "" else [message],
#"Timestamp" = [createdAt],
#"Version Object ID" = [referencedObject],
#"Version URL" = Text.Combine({
server,
"/projects/",
projectId,
"/models/",
modelId,
"@",
[id]
})
]
)
),
// set column types for better Power BI integration
typedTable = Table.TransformColumnTypes(
versionsTable,
{
{"Version ID", type text},
{"Version Message", type text},
{"Timestamp", type datetimezone},
{"Version Object ID", type text},
{"Version URL", type text}
}
)
in
typedTable