Skip to content

Commit

Permalink
Adds Frontend2 URL Support for single model urls (#58)
Browse files Browse the repository at this point in the history
* feat: Adds FE2 Url support for single model urls

* fix: Minor formatting changes
  • Loading branch information
AlanRynne authored Nov 9, 2023
1 parent da1f0c7 commit 9a5c128
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 32 deletions.
17 changes: 13 additions & 4 deletions Speckle.pq
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Speckle = [
Label = "Speckle.xyz",
StartLogin = (clientApplication, dataSourcePath, state, display) =>
let
server = Text.Combine({Uri.Parts(dataSourcePath)[Scheme], "://", Uri.Parts(dataSourcePath)[Host]})
server = Text.Combine(
{Uri.Parts(dataSourcePath)[Scheme], "://", Uri.Parts(dataSourcePath)[Host]}
)
in
[
LoginUri = Text.Combine({server, "authn", "verify", AuthAppId, state}, "/"),
Expand All @@ -25,7 +27,9 @@ Speckle = [
],
FinishLogin = (clientApplication, dataSourcePath, context, callbackUri, state) =>
let
server = Text.Combine({Uri.Parts(dataSourcePath)[Scheme], "://", Uri.Parts(dataSourcePath)[Host]}),
server = Text.Combine(
{Uri.Parts(dataSourcePath)[Scheme], "://", Uri.Parts(dataSourcePath)[Host]}
),
Parts = Uri.Parts(callbackUri)[Query],
Source = Web.Contents(
Text.Combine({server, "auth", "token"}, "/"),
Expand Down Expand Up @@ -53,7 +57,9 @@ Speckle = [
],
Refresh = (dataSourcePath, refreshToken) =>
let
server = Text.Combine({Uri.Parts(dataSourcePath)[Scheme], "://", Uri.Parts(dataSourcePath)[Host]}),
server = Text.Combine(
{Uri.Parts(dataSourcePath)[Scheme], "://", Uri.Parts(dataSourcePath)[Host]}
),
Source = Web.Contents(
Text.Combine({server, "auth", "token"}, "/"),
[
Expand Down Expand Up @@ -159,7 +165,10 @@ shared Speckle.Api.Fetch = Value.ReplaceType(
);

// Parses a stream url and returns a record with the type and values
shared Speckle.ParseUrl = Speckle.LoadFunction("ParseStreamUrl.pqm");
[DataSource.Kind = "Speckle"]
shared Speckle.ParseUrl = Value.ReplaceType(
Speckle.LoadFunction("ParseStreamUrl.pqm"), type function (url as Uri.Type) as record
);

// [DataSource.Kind = "Speckle"]
// shared Speckle.Api.REST.GetObject = Value.ReplaceType(
Expand Down
2 changes: 1 addition & 1 deletion Speckle.query.pq
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Use this file to write queries to test your data connector
let result = Speckle.GetByUrl("https://latest.speckle.dev/streams/4e51c4025f/commits/766c20c5fb") in result
let result = Speckle.GetByUrl("https://app.speckle.systems/projects/e2988234fb/models/60b2300470@b1f31a351a") in result
32 changes: 32 additions & 0 deletions speckle/api/Api.GetModel.pqm
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
let
Speckle.Api.Fetch = Extension.LoadFunction("Api.Fetch.pqm"),
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
(server as text, projectId as text, modelId as text) =>
let
query = "query Project($projectId: String!, $modelId: String!) {
project(id: $projectId) {
model(id: $modelId) {
name
}
}
}",
variables = [
projectId = projectId,
modelId = modelId
]
in
// Read receipts should fail gracefully no matter what
try Speckle.Api.Fetch(server, query, variables)[project][model] otherwise null
78 changes: 51 additions & 27 deletions speckle/helpers/ParseStreamUrl.pqm
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
(url as text) as record =>
let
// Get server and streamId, and branchName / commitId / objectid from the input url
server = Text.Combine({Uri.Parts(url)[Scheme], "://", Uri.Parts(url)[Host]}),
segments = Text.Split(Text.AfterDelimiter(Uri.Parts(url)[Path], "/", 0), "/"),
streamId = segments{1},
branchName = if (List.Count(segments) = 4 and segments{2} = "branches") then segments{3} else null,
commitId = if (List.Count(segments) = 4 and segments{2} = "commits") then segments{3} else null,
objectId = if (List.Count(segments) = 4 and segments{2} = "objects") then segments{3} else null,
urlType =
if (commitId <> null) then
"Commit"
else if (objectId <> null) then
"Object"
else if (branchName <> null) then
"Branch"
else
"Stream"
in
[
urlType = urlType,
server = server,
id = streamId,
branch = branchName,
commit = commitId,
object = objectId
]
let
GetModel = Extension.LoadFunction("Api.GetModel.pqm"),
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 server and streamId, and branchName / commitId / objectid from the input url
server = Text.Combine({Uri.Parts(url)[Scheme], "://", Uri.Parts(url)[Host]}),
segments = Text.Split(Text.AfterDelimiter(Uri.Parts(url)[Path], "/", 0), "/"),
streamId = segments{1},
modelList = if (List.Count(segments) = 4 and segments{2} = "models") then segments{3} else null,
firstModel = Text.Split(modelList, ","){0},
modelAndVersion = Text.Split(firstModel, "@"),
modelId = modelAndVersion{0},
versionId = if (List.Count(modelAndVersion) > 1) then modelAndVersion{1} else null,
model = if (modelId <> null) then GetModel(server, streamId, modelId) else null,
branchName = if (List.Count(segments) = 4 and segments{2} = "branches") then segments{3} else null,
commitId = if (List.Count(segments) = 4 and segments{2} = "commits") then segments{3} else null,
objectId = if (List.Count(segments) = 4 and segments{2} = "objects") then segments{3} else null,
modelOrBranchName = if (model <> null) then model[name] else branchName,
commitOrVersion = if (versionId <> null) then versionId else commitId,
urlType =
if (commitOrVersion <> null) then
"Commit"
else if (objectId <> null) then
"Object"
else if (modelOrBranchName <> null) then
"Branch"
else
"Stream"
in
[
urlType = urlType,
server = server,
id = streamId,
branch = modelOrBranchName,
commit = commitOrVersion,
object = objectId
]

0 comments on commit 9a5c128

Please sign in to comment.