5
5
"encoding"
6
6
"encoding/json"
7
7
"fmt"
8
- "path/filepath "
8
+ "github.com/klothoplatform/klotho/pkg/templateutils "
9
9
"reflect"
10
10
"regexp"
11
11
"strconv"
@@ -54,7 +54,7 @@ func (ctx DynamicValueContext) KB() TemplateKB {
54
54
}
55
55
56
56
func (ctx DynamicValueContext ) TemplateFunctions () template.FuncMap {
57
- return template.FuncMap {
57
+ return templateutils . WithCommonFuncs ( template.FuncMap {
58
58
"hasUpstream" : ctx .HasUpstream ,
59
59
"upstream" : ctx .Upstream ,
60
60
"layeredUpstream" : ctx .LayeredUpstream ,
@@ -73,41 +73,10 @@ func (ctx DynamicValueContext) TemplateFunctions() template.FuncMap {
73
73
74
74
"toJson" : ctx .toJson ,
75
75
76
- "split" : strings .Split ,
77
- "join" : strings .Join ,
78
- "basename" : filepath .Base ,
79
-
80
- "firstId" : firstId ,
81
- "filterIds" : filterIds ,
82
- "filterMatch" : filterMatch ,
83
- "mapString" : mapString ,
84
- "zipToMap" : zipToMap ,
85
- "keysToMapWithDefault" : keysToMapWithDefault ,
86
- "replace" : replaceRegex ,
87
- "hasSuffix" : func (s , suffix string ) bool {
88
- return strings .HasSuffix (s , suffix )
89
- },
90
- "toLower" : strings .ToLower ,
76
+ "firstId" : firstId ,
77
+ "filterIds" : filterIds ,
91
78
"sanitizeName" : sanitizeName ,
92
-
93
- "add" : add ,
94
- "sub" : sub ,
95
- "last" : last ,
96
- "makeSlice" : func () []any {
97
- return []any {}
98
- },
99
- "appendSlice" : func (slice []any , value any ) []any {
100
- return append (slice , value )
101
- },
102
- "sliceContains" : func (slice []any , value any ) bool {
103
- for _ , v := range slice {
104
- if v == value {
105
- return true
106
- }
107
- }
108
- return false
109
- },
110
- }
79
+ })
111
80
}
112
81
113
82
func (ctx DynamicValueContext ) Parse (tmpl string ) (* template.Template , error ) {
@@ -611,22 +580,6 @@ func (ctx DynamicValueContext) PathAncestorExists(path construct.PropertyPath, d
611
580
return len (path ) > depth
612
581
}
613
582
614
- // filterMatch returns a json array by filtering the values array with the regex pattern
615
- func filterMatch (pattern string , values []string ) ([]string , error ) {
616
- re , err := regexp .Compile (pattern )
617
- if err != nil {
618
- return nil , err
619
- }
620
-
621
- matches := make ([]string , 0 , len (values ))
622
- for _ , v := range values {
623
- if ok := re .MatchString (v ); ok {
624
- matches = append (matches , v )
625
- }
626
- }
627
- return matches , nil
628
- }
629
-
630
583
func filterIds (selector any , ids []construct.ResourceId ) ([]construct.ResourceId , error ) {
631
584
selId , err := TemplateArgToRID (selector )
632
585
if err != nil {
@@ -657,90 +610,6 @@ func firstId(selector any, ids []construct.ResourceId) (construct.ResourceId, er
657
610
return construct.ResourceId {}, fmt .Errorf ("no ids match selector" )
658
611
}
659
612
660
- // mapstring takes in a regex pattern and replacement as well as a json array of strings
661
- // roughly `unmarshal value | sed s/pattern/replace/g | marshal`
662
- func mapString (pattern , replace string , values []string ) ([]string , error ) {
663
- re , err := regexp .Compile (pattern )
664
- if err != nil {
665
- return nil , err
666
- }
667
-
668
- nv := make ([]string , len (values ))
669
- for i , v := range values {
670
- nv [i ] = re .ReplaceAllString (v , replace )
671
- }
672
- return nv , nil
673
- }
674
-
675
- // zipToMap returns a json map by zipping the keys and values arrays
676
- // Example: zipToMap(['a', 'b'], [1, 2]) => {"a": 1, "b": 2}
677
- func zipToMap (keys []string , valuesArg any ) (map [string ]any , error ) {
678
- // Have to use reflection here because technically, []string is not assignable to []any
679
- // thanks Go.
680
- valuesRefl := reflect .ValueOf (valuesArg )
681
- if valuesRefl .Kind () != reflect .Slice && valuesRefl .Kind () != reflect .Array {
682
- return nil , fmt .Errorf ("values is not a slice or array" )
683
- }
684
- if len (keys ) != valuesRefl .Len () {
685
- return nil , fmt .Errorf ("key length (%d) != value length (%d)" , len (keys ), valuesRefl .Len ())
686
- }
687
-
688
- m := make (map [string ]any )
689
- for i , k := range keys {
690
- m [k ] = valuesRefl .Index (i ).Interface ()
691
- }
692
- return m , nil
693
- }
694
-
695
- // keysToMapWithDefault returns a json map by mapping the keys array to the static defaultValue
696
- // Example keysToMapWithDefault(0, ['a', 'b']) => {"a": 0, "b": 0}
697
- func keysToMapWithDefault (defaultValue any , keys []string ) (map [string ]any , error ) {
698
- m := make (map [string ]any )
699
- for _ , k := range keys {
700
- m [k ] = defaultValue
701
- }
702
- return m , nil
703
- }
704
-
705
- func add (args ... int ) int {
706
- total := 0
707
- for _ , a := range args {
708
- total += a
709
- }
710
- return total
711
- }
712
-
713
- func sub (args ... int ) int {
714
- if len (args ) == 0 {
715
- return 0
716
- }
717
- total := args [0 ]
718
- for _ , a := range args [1 :] {
719
- total -= a
720
- }
721
- return total
722
- }
723
-
724
- func last (list any ) (any , error ) {
725
- v := reflect .ValueOf (list )
726
- if v .Kind () != reflect .Slice && v .Kind () != reflect .Array {
727
- return nil , fmt .Errorf ("list is not a slice or array, is %s" , v .Kind ())
728
- }
729
- if v .Len () == 0 {
730
- return nil , fmt .Errorf ("list is empty" )
731
- }
732
- return v .Index (v .Len () - 1 ).Interface (), nil
733
- }
734
-
735
- func replaceRegex (pattern , replace , value string ) (string , error ) {
736
- re , err := regexp .Compile (pattern )
737
- if err != nil {
738
- return "" , err
739
- }
740
- s := re .ReplaceAllString (value , replace )
741
- return s , nil
742
- }
743
-
744
613
// invalidNameCharacters matches characters that are not allowed in resource names. Basically,
745
614
// the same as [construct2.resourceNamePattern] except inverted.
746
615
var invalidNameCharacters = regexp .MustCompile (`[^a-zA-Z0-9_./\-:\[\]]` )
0 commit comments