@@ -21,12 +21,69 @@ import (
21
21
"encoding/json"
22
22
"fmt"
23
23
"maps"
24
+ "net/url"
25
+ "strings"
24
26
25
27
"github.com/firebase/genkit/go/core"
26
- coreresource "github.com/firebase/genkit/go/core/resource"
27
28
"github.com/firebase/genkit/go/internal/registry"
29
+ "github.com/yosida95/uritemplate/v3"
28
30
)
29
31
32
+ // normalizeURI normalizes a URI for template matching by removing query parameters,
33
+ // fragments, and trailing slashes from the path.
34
+ func normalizeURI (rawURI string ) string {
35
+ // Parse the URI
36
+ u , err := url .Parse (rawURI )
37
+ if err != nil {
38
+ // If parsing fails, return the original URI
39
+ return rawURI
40
+ }
41
+
42
+ // Remove query parameters and fragment
43
+ u .RawQuery = ""
44
+ u .Fragment = ""
45
+
46
+ // Remove trailing slash from path (but not from the root path)
47
+ if len (u .Path ) > 1 && strings .HasSuffix (u .Path , "/" ) {
48
+ u .Path = strings .TrimSuffix (u .Path , "/" )
49
+ }
50
+
51
+ return u .String ()
52
+ }
53
+
54
+ // matches checks if a URI matches the given URI template.
55
+ func matches (templateStr , uri string ) (bool , error ) {
56
+ template , err := uritemplate .New (templateStr )
57
+ if err != nil {
58
+ return false , fmt .Errorf ("invalid URI template %q: %w" , templateStr , err )
59
+ }
60
+
61
+ normalizedURI := normalizeURI (uri )
62
+ values := template .Match (normalizedURI )
63
+ return len (values ) > 0 , nil
64
+ }
65
+
66
+ // extractVariables extracts variables from a URI using the given URI template.
67
+ func extractVariables (templateStr , uri string ) (map [string ]string , error ) {
68
+ template , err := uritemplate .New (templateStr )
69
+ if err != nil {
70
+ return nil , fmt .Errorf ("invalid URI template %q: %w" , templateStr , err )
71
+ }
72
+
73
+ normalizedURI := normalizeURI (uri )
74
+ values := template .Match (normalizedURI )
75
+ if len (values ) == 0 {
76
+ return nil , fmt .Errorf ("URI %q does not match template" , uri )
77
+ }
78
+
79
+ // Convert uritemplate.Values to string map
80
+ result := make (map [string ]string )
81
+ for name , value := range values {
82
+ result [name ] = value .String ()
83
+ }
84
+ return result , nil
85
+ }
86
+
30
87
// ResourceInput represents the input to a resource function.
31
88
type ResourceInput struct {
32
89
URI string `json:"uri"` // The resource URI
@@ -75,10 +132,6 @@ func DefineResource(r *registry.Registry, name string, opts *ResourceOptions, fn
75
132
metadata := implementResource (name , opts )
76
133
resourceAction := core .DefineAction (r , name , core .ActionTypeResource , metadata , fn )
77
134
resource := & resource {Action : resourceAction }
78
-
79
- // Register the resource wrapper so ListResources can find it
80
- r .RegisterValue (fmt .Sprintf ("resource/%s" , name ), resource )
81
-
82
135
return resource
83
136
}
84
137
@@ -143,11 +196,11 @@ func (r *resource) Matches(uri string) bool {
143
196
144
197
// Check template
145
198
if template , ok := resourceMeta ["template" ].(string ); ok && template != "" {
146
- matcher , err := coreresource . NewTemplateMatcher (template )
199
+ matches , err := matches (template , uri )
147
200
if err != nil {
148
201
return false
149
202
}
150
- return matcher . Matches ( uri )
203
+ return matches
151
204
}
152
205
153
206
return false
@@ -171,11 +224,7 @@ func (r *resource) ExtractVariables(uri string) (map[string]string, error) {
171
224
172
225
// Extract from template
173
226
if template , ok := resourceMeta ["template" ].(string ); ok && template != "" {
174
- matcher , err := coreresource .NewTemplateMatcher (template )
175
- if err != nil {
176
- return nil , fmt .Errorf ("invalid template %q: %w" , template , err )
177
- }
178
- return matcher .ExtractVariables (uri )
227
+ return extractVariables (template , uri )
179
228
}
180
229
181
230
return nil , fmt .Errorf ("no URI or template found in resource metadata" )
0 commit comments