ondc-code-generator 0.8.4 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,10 +5,85 @@ package validationutils
5
5
  import (
6
6
  "fmt"
7
7
  "strings"
8
+ "sync"
8
9
 
9
10
  "github.com/AsaiYusuke/jsonpath"
10
11
  )
11
12
 
13
+ // Global cache for parsed JSONPath functions
14
+ var (
15
+ pathParserCache = make(map[string]func(interface{}) ([]interface{}, error))
16
+ parserCacheMu sync.RWMutex
17
+ cacheHits uint64
18
+ cacheMisses uint64
19
+ statsMu sync.Mutex
20
+ )
21
+
22
+ // getOrParseJSONPath retrieves a cached parser or parses and caches a new one
23
+ func getOrParseJSONPath(path string) (func(interface{}) ([]interface{}, error), error) {
24
+ // Try to get from cache first (read lock for fast concurrent reads)
25
+ parserCacheMu.RLock()
26
+ parser, exists := pathParserCache[path]
27
+ parserCacheMu.RUnlock()
28
+
29
+ if exists {
30
+ // Cache hit - use existing parser
31
+ statsMu.Lock()
32
+ cacheHits++
33
+ statsMu.Unlock()
34
+ return parser, nil
35
+ }
36
+
37
+ // Cache miss - need to parse
38
+ statsMu.Lock()
39
+ cacheMisses++
40
+ statsMu.Unlock()
41
+
42
+ // Acquire write lock to add to cache
43
+ parserCacheMu.Lock()
44
+ defer parserCacheMu.Unlock()
45
+
46
+ // Double-check after acquiring write lock (another goroutine might have added it)
47
+ if parser, exists := pathParserCache[path]; exists {
48
+ return parser, nil
49
+ }
50
+
51
+ // Parse the JSONPath expression
52
+ parser, err := jsonpath.Parse(path)
53
+ if err != nil {
54
+ return nil, fmt.Errorf("failed to parse JSONPath %s: %w", path, err)
55
+ }
56
+
57
+ // Cache it for future use
58
+ pathParserCache[path] = parser
59
+ return parser, nil
60
+ }
61
+
62
+ // GetParserCacheStats returns cache statistics
63
+ func GetParserCacheStats() (hits, misses uint64, size int) {
64
+ statsMu.Lock()
65
+ h, m := cacheHits, cacheMisses
66
+ statsMu.Unlock()
67
+
68
+ parserCacheMu.RLock()
69
+ s := len(pathParserCache)
70
+ parserCacheMu.RUnlock()
71
+
72
+ return h, m, s
73
+ }
74
+
75
+ // ClearParserCache clears the cache (useful for testing)
76
+ func ClearParserCache() {
77
+ parserCacheMu.Lock()
78
+ pathParserCache = make(map[string]func(interface{}) ([]interface{}, error))
79
+ parserCacheMu.Unlock()
80
+
81
+ statsMu.Lock()
82
+ cacheHits = 0
83
+ cacheMisses = 0
84
+ statsMu.Unlock()
85
+ }
86
+
12
87
  // isListOfStringsOrNull checks if the variable is a slice containing only strings or nil values
13
88
  func isListOfStringsOrNull(variable interface{}) bool {
14
89
  slice, ok := variable.([]interface{})
@@ -29,10 +104,30 @@ func isListOfStringsOrNull(variable interface{}) bool {
29
104
 
30
105
  // GetJsonPath queries a payload using JSONPath and returns the results
31
106
  func GetJsonPath(payload interface{}, path string, flattenResult bool) []interface{} {
32
- resolvedPath, resolvedData, err := resolveJSONPathData(path, payload)
33
- output, err := jsonpath.Retrieve(resolvedPath, resolvedData)
107
+ resolvedPath, resolvedData, err := resolveJSONPathData(path, payload)
34
108
  if err != nil {
35
- fmt.Printf("Error retrieving JSONPath %s: %v\n", path, err)
109
+ // fmt.Printf("Error resolving JSONPath %s: %v\n", path, err)
110
+ return []interface{}{}
111
+ }
112
+
113
+ // Get or parse the JSONPath - uses cache if available
114
+ parser, err := getOrParseJSONPath(resolvedPath)
115
+ if err != nil {
116
+ // fmt.Printf("Error parsing JSONPath %s: %v\n", resolvedPath, err)
117
+ return []interface{}{}
118
+ }
119
+
120
+ // Execute the parsed JSONPath function
121
+ result, err := parser(resolvedData)
122
+ if err != nil {
123
+ // fmt.Printf("Error retrieving JSONPath %s: %v\n", resolvedPath, err)
124
+ return []interface{}{}
125
+ }
126
+
127
+ // Result is already []interface{}
128
+ output := result
129
+
130
+ if len(output) == 0 {
36
131
  return []interface{}{}
37
132
  }
38
133
 
@@ -48,9 +143,6 @@ func GetJsonPath(payload interface{}, path string, flattenResult bool) []interfa
48
143
  output = flattenSlice(output)
49
144
  }
50
145
 
51
- if len(output) == 0 {
52
- return []interface{}{}
53
- }
54
146
  return output
55
147
  }
56
148
 
@@ -67,17 +159,15 @@ func flattenSlice(slice []interface{}) []interface{} {
67
159
  return result
68
160
  }
69
161
 
70
-
71
-
72
162
  func resolveJSONPathData(path string, data interface{}) (string, interface{}, error) {
73
- if input, ok := data.(ValidationInput); ok {
74
- if strings.HasPrefix(path, "$._EXTERNAL._SELF") {
75
- resolvedPath := strings.Replace(path, "$._EXTERNAL._SELF", "$", 1)
76
- return resolvedPath, input.ExternalData["_SELF"], nil
77
- }else if( strings.HasPrefix(path, "$._EXTERNAL")){
163
+ if input, ok := data.(ValidationInput); ok {
164
+ if strings.HasPrefix(path, "$._EXTERNAL._SELF") {
165
+ resolvedPath := strings.Replace(path, "$._EXTERNAL._SELF", "$", 1)
166
+ return resolvedPath, input.ExternalData["_SELF"], nil
167
+ } else if strings.HasPrefix(path, "$._EXTERNAL") {
78
168
  resolvedPath := strings.Replace(path, "$._EXTERNAL", "$", 1)
79
169
  return resolvedPath, input.ExternalData, nil
80
170
  }
81
- }
82
- return path, data, nil
83
- }
171
+ }
172
+ return path, data, nil
173
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ondc-code-generator",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "generate code from build.yaml ",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",