@@ -2,8 +2,8 @@ package overlay
22
33import (
44 "fmt"
5- "github.com/speakeasy-api/jsonpath/pkg/jsonpath"
65 "github.com/speakeasy-api/jsonpath/pkg/jsonpath/config"
6+ "github.com/speakeasy-api/jsonpath/pkg/jsonpath/token"
77 "gopkg.in/yaml.v3"
88 "strings"
99)
@@ -14,9 +14,9 @@ func (o *Overlay) ApplyTo(root *yaml.Node) error {
1414 for _ , action := range o .Actions {
1515 var err error
1616 if action .Remove {
17- err = applyRemoveAction (root , action )
17+ err = o . applyRemoveAction (root , action , nil )
1818 } else {
19- err = applyUpdateAction (root , action , & []string {})
19+ err = o . applyUpdateAction (root , action , & []string {})
2020 }
2121
2222 if err != nil {
@@ -30,33 +30,46 @@ func (o *Overlay) ApplyTo(root *yaml.Node) error {
3030func (o * Overlay ) ApplyToStrict (root * yaml.Node ) (error , []string ) {
3131 multiError := []string {}
3232 warnings := []string {}
33+ hasFilterExpression := false
3334 for i , action := range o .Actions {
34- err := validateSelectorHasAtLeastOneTarget (root , action )
35+ tokens := token .NewTokenizer (action .Target , config .WithPropertyNameExtension ()).Tokenize ()
36+ for _ , tok := range tokens {
37+ if tok .Token == token .FILTER {
38+ hasFilterExpression = true
39+ }
40+ }
41+
42+ actionWarnings := []string {}
43+ err := o .validateSelectorHasAtLeastOneTarget (root , action )
3544 if err != nil {
3645 multiError = append (multiError , err .Error ())
3746 }
3847 if action .Remove {
39- err = applyRemoveAction (root , action )
48+ err = o . applyRemoveAction (root , action , & actionWarnings )
4049 } else {
41- actionWarnings := []string {}
42- err = applyUpdateAction (root , action , & actionWarnings )
43- for _ , warning := range actionWarnings {
44- warnings = append (warnings , fmt .Sprintf ("update action (%v / %v) target=%s: %s" , i + 1 , len (o .Actions ), action .Target , warning ))
45- }
50+ err = o .applyUpdateAction (root , action , & actionWarnings )
4651 }
52+ for _ , warning := range actionWarnings {
53+ warnings = append (warnings , fmt .Sprintf ("update action (%v / %v) target=%s: %s" , i + 1 , len (o .Actions ), action .Target , warning ))
54+ }
55+ }
56+
57+ if hasFilterExpression && ! o .UsesRFC9535 () {
58+ warnings = append (warnings , "overlay has a filter expression but lacks `x-speakeasy-jsonpath: rfc9535` extension. Deprecated jsonpath behaviour in use. See overlay.speakeasy.com for the implementation playground." )
4759 }
60+
4861 if len (multiError ) > 0 {
4962 return fmt .Errorf ("error applying overlay (strict): %v" , strings .Join (multiError , "," )), warnings
5063 }
5164 return nil , warnings
5265}
5366
54- func validateSelectorHasAtLeastOneTarget (root * yaml.Node , action Action ) error {
67+ func ( o * Overlay ) validateSelectorHasAtLeastOneTarget (root * yaml.Node , action Action ) error {
5568 if action .Target == "" {
5669 return nil
5770 }
5871
59- p , err := jsonpath .NewPath (action .Target )
72+ p , err := o .NewPath (action .Target , nil )
6073 if err != nil {
6174 return err
6275 }
@@ -70,14 +83,14 @@ func validateSelectorHasAtLeastOneTarget(root *yaml.Node, action Action) error {
7083 return nil
7184}
7285
73- func applyRemoveAction (root * yaml.Node , action Action ) error {
86+ func ( o * Overlay ) applyRemoveAction (root * yaml.Node , action Action , warnings * [] string ) error {
7487 if action .Target == "" {
7588 return nil
7689 }
7790
7891 idx := newParentIndex (root )
7992
80- p , err := jsonpath .NewPath (action .Target , config . WithPropertyNameExtension () )
93+ p , err := o .NewPath (action .Target , warnings )
8194 if err != nil {
8295 return err
8396 }
@@ -104,8 +117,13 @@ func removeNode(idx parentIndex, node *yaml.Node) {
104117 if child == node {
105118 switch parent .Kind {
106119 case yaml .MappingNode :
107- // we have to delete the key too
108- parent .Content = append (parent .Content [:i - 1 ], parent .Content [i + 1 :]... )
120+ if i % 2 == 1 {
121+ // if we select a value, we should delete the key too
122+ parent .Content = append (parent .Content [:i - 1 ], parent .Content [i + 1 :]... )
123+ } else {
124+ // if we select a key, we should delete the value
125+ parent .Content = append (parent .Content [:i ], parent .Content [i + 2 :]... )
126+ }
109127 return
110128 case yaml .SequenceNode :
111129 parent .Content = append (parent .Content [:i ], parent .Content [i + 1 :]... )
@@ -115,7 +133,7 @@ func removeNode(idx parentIndex, node *yaml.Node) {
115133 }
116134}
117135
118- func applyUpdateAction (root * yaml.Node , action Action , warnings * []string ) error {
136+ func ( o * Overlay ) applyUpdateAction (root * yaml.Node , action Action , warnings * []string ) error {
119137 if action .Target == "" {
120138 return nil
121139 }
@@ -124,7 +142,7 @@ func applyUpdateAction(root *yaml.Node, action Action, warnings *[]string) error
124142 return nil
125143 }
126144
127- p , err := jsonpath .NewPath (action .Target , config . WithPropertyNameExtension () )
145+ p , err := o .NewPath (action .Target , warnings )
128146 if err != nil {
129147 return err
130148 }
0 commit comments