ondc-code-generator 0.6.21 → 0.7.0
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.
- package/.github/copilot-instructions.md +128 -0
- package/GOLANG_IMPLEMENTATION.md +156 -0
- package/README.md +4 -1
- package/alpha/possible-json-paths.json +3734 -0
- package/dist/generator/config-compiler.js +6 -0
- package/dist/generator/generators/golang/go-ast.d.ts +1 -0
- package/dist/generator/generators/golang/go-ast.js +60 -0
- package/dist/generator/generators/golang/go-generator.d.ts +23 -0
- package/dist/generator/generators/golang/go-generator.js +511 -0
- package/dist/generator/generators/golang/templates/api-test.mustache +48 -0
- package/dist/generator/generators/golang/templates/json-normalizer.mustache +46 -0
- package/dist/generator/generators/golang/templates/json-path-utils.mustache +21 -0
- package/dist/generator/generators/golang/templates/storage-templates/api-save.mustache +30 -0
- package/dist/generator/generators/golang/templates/storage-templates/index.mustache +41 -0
- package/dist/generator/generators/golang/templates/storage-templates/save-utils.mustache +37 -0
- package/dist/generator/generators/golang/templates/storage-templates/storage-helpers.mustache +51 -0
- package/dist/generator/generators/golang/templates/storage-templates/storage-interface.mustache +96 -0
- package/dist/generator/generators/golang/templates/storage-templates/storage-types.mustache +15 -0
- package/dist/generator/generators/golang/templates/test-config.mustache +39 -0
- package/dist/generator/generators/golang/templates/test-object.mustache +39 -0
- package/dist/generator/generators/golang/templates/validation-code.mustache +51 -0
- package/dist/generator/generators/golang/templates/validation-utils.mustache +246 -0
- package/dist/generator/generators/python/py-generator.js +1 -1
- package/dist/generator/generators/python/templates/json-path-utils.mustache +16 -1
- package/dist/generator/generators/python/templates/storage-templates/api-save.mustache +1 -1
- package/dist/generator/generators/typescript/templates/json-path-utils.mustache +25 -7
- package/dist/generator/generators/typescript/templates/storage-templates/api-save.mustache +1 -1
- package/dist/generator/generators/typescript/ts-generator.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.test.js +7 -1
- package/dist/types/compiler-types.d.ts +2 -1
- package/dist/types/compiler-types.js +1 -0
- package/dist/utils/fs-utils.js +40 -0
- package/package.json +2 -2
- package/sample.md +273 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
package utils
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"strings"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// NormalizeKeys converts all keys in a JSON object to snake_case
|
|
9
|
+
func NormalizeKeys(data interface{}) interface{} {
|
|
10
|
+
switch v := data.(type) {
|
|
11
|
+
case map[string]interface{}:
|
|
12
|
+
normalized := make(map[string]interface{})
|
|
13
|
+
for key, value := range v {
|
|
14
|
+
normalizedKey := toSnakeCase(key)
|
|
15
|
+
normalized[normalizedKey] = NormalizeKeys(value)
|
|
16
|
+
}
|
|
17
|
+
return normalized
|
|
18
|
+
case []interface{}:
|
|
19
|
+
normalized := make([]interface{}, len(v))
|
|
20
|
+
for i, value := range v {
|
|
21
|
+
normalized[i] = NormalizeKeys(value)
|
|
22
|
+
}
|
|
23
|
+
return normalized
|
|
24
|
+
default:
|
|
25
|
+
return v
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// toSnakeCase converts a string to snake_case
|
|
30
|
+
func toSnakeCase(s string) string {
|
|
31
|
+
var result strings.Builder
|
|
32
|
+
for i, r := range s {
|
|
33
|
+
if i > 0 && r >= 'A' && r <= 'Z' {
|
|
34
|
+
result.WriteRune('_')
|
|
35
|
+
}
|
|
36
|
+
result.WriteRune(r)
|
|
37
|
+
}
|
|
38
|
+
return strings.ToLower(result.String())
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// FromJSON parses JSON bytes into interface{}
|
|
42
|
+
func FromJSON(data []byte) (interface{}, error) {
|
|
43
|
+
var result interface{}
|
|
44
|
+
err := json.Unmarshal(data, &result)
|
|
45
|
+
return result, err
|
|
46
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package utils
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"github.com/PaesslerAG/jsonpath"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
// GetJSONPath extracts values from a JSON object using JSONPath
|
|
8
|
+
func GetJSONPath(data interface{}, path string) []interface{} {
|
|
9
|
+
result, err := jsonpath.Get(path, data)
|
|
10
|
+
if err != nil {
|
|
11
|
+
return []interface{}{}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// If result is already a slice, return it
|
|
15
|
+
if slice, ok := result.([]interface{}); ok {
|
|
16
|
+
return slice
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Otherwise, wrap the single result in a slice
|
|
20
|
+
return []interface{}{result}
|
|
21
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
package storageactions
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"L1_validations/interfaces"
|
|
5
|
+
"L1_validations/types"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// Store_{{action}} saves data for the {{action}} action
|
|
9
|
+
func Store_{{action}}(uniquePrefix string, payload map[string]interface{}, store interfaces.StorageInterface, config types.StorageConfig) error {
|
|
10
|
+
{{#storeActions}}
|
|
11
|
+
if err := SaveFunction(payload, uniquePrefix, "{{{key}}}", "{{{value}}}", "{{action}}", store, config); err != nil {
|
|
12
|
+
return err
|
|
13
|
+
}
|
|
14
|
+
{{/storeActions}}
|
|
15
|
+
return nil
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// LoadFor_{{action}} loads data for the {{action}} action
|
|
19
|
+
func LoadFor_{{action}}(uniquePrefix string, store interfaces.StorageInterface) (map[string]interface{}, error) {
|
|
20
|
+
result := make(map[string]interface{})
|
|
21
|
+
|
|
22
|
+
{{#loadActions}}
|
|
23
|
+
{{{key}}}Data, err := LoadFunction(store, uniquePrefix, "{{{key}}}")
|
|
24
|
+
if err == nil {
|
|
25
|
+
result["{{{key}}}"] = {{{key}}}Data
|
|
26
|
+
}
|
|
27
|
+
{{/loadActions}}
|
|
28
|
+
|
|
29
|
+
return result, nil
|
|
30
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package storageactions
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"L1_validations/interfaces"
|
|
6
|
+
"L1_validations/types"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// Perform{{functionName}}Save saves validation data based on the action
|
|
10
|
+
func Perform{{functionName}}Save(action, uniquePrefix string, payload map[string]interface{}, store interfaces.StorageInterface, config *types.StorageConfig) error {
|
|
11
|
+
completeConfig := types.DefaultStorageConfig()
|
|
12
|
+
if config != nil {
|
|
13
|
+
if config.RetryAttempts > 0 {
|
|
14
|
+
completeConfig.RetryAttempts = config.RetryAttempts
|
|
15
|
+
}
|
|
16
|
+
if config.RetryDelayMs > 0 {
|
|
17
|
+
completeConfig.RetryDelayMs = config.RetryDelayMs
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
switch action {
|
|
22
|
+
{{#actions}}
|
|
23
|
+
case "{{{action}}}":
|
|
24
|
+
return Store_{{{action}}}(uniquePrefix, payload, store, completeConfig)
|
|
25
|
+
{{/actions}}
|
|
26
|
+
default:
|
|
27
|
+
return fmt.Errorf("action not found: %s", action)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Perform{{functionName}}Load loads validation data based on the action
|
|
32
|
+
func Perform{{functionName}}Load(action, uniquePrefix string, store interfaces.StorageInterface) (map[string]interface{}, error) {
|
|
33
|
+
switch action {
|
|
34
|
+
{{#actions}}
|
|
35
|
+
case "{{{action}}}":
|
|
36
|
+
return LoadFor_{{{action}}}(uniquePrefix, store)
|
|
37
|
+
{{/actions}}
|
|
38
|
+
default:
|
|
39
|
+
return nil, fmt.Errorf("action not found: %s", action)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
package utils
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"time"
|
|
6
|
+
"L1_validations/interfaces"
|
|
7
|
+
"L1_validations/types"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// SaveData saves data to storage with retry logic
|
|
11
|
+
func SaveData(uniquePrefix, key, saveData string, store interfaces.StorageInterface, config types.StorageConfig) error {
|
|
12
|
+
finalKey := key
|
|
13
|
+
retryTimes := config.RetryAttempts
|
|
14
|
+
delayMs := config.RetryDelayMs
|
|
15
|
+
attempts := 0
|
|
16
|
+
|
|
17
|
+
for attempts < retryTimes {
|
|
18
|
+
err := store.SaveKey(uniquePrefix, finalKey, saveData)
|
|
19
|
+
if err == nil {
|
|
20
|
+
return nil
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
attempts++
|
|
24
|
+
if attempts >= retryTimes {
|
|
25
|
+
return err
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
time.Sleep(time.Duration(delayMs) * time.Millisecond)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return fmt.Errorf("failed to save data after %d attempts", retryTimes)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// CreateKey creates a composite key from prefix and key
|
|
35
|
+
func CreateKey(uniquePrefix, key string) string {
|
|
36
|
+
return fmt.Sprintf("%s:%s", uniquePrefix, key)
|
|
37
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package storageactions
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"time"
|
|
6
|
+
"L1_validations/utils"
|
|
7
|
+
"L1_validations/interfaces"
|
|
8
|
+
"L1_validations/types"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// SaveFunction saves a value from payload at specified path to storage
|
|
12
|
+
func SaveFunction(payload map[string]interface{}, uniquePrefix, key, path, action string, store interfaces.StorageInterface, config types.StorageConfig) error {
|
|
13
|
+
if path == "" || key == "_SELF" {
|
|
14
|
+
return nil
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
value := utils.GetJSONPath(payload, path)
|
|
18
|
+
|
|
19
|
+
data := map[string]interface{}{
|
|
20
|
+
"stored_from": action + "_action",
|
|
21
|
+
"key_path": path,
|
|
22
|
+
"value": value,
|
|
23
|
+
"timestamp": time.Now().Format(time.RFC3339),
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
dataBytes, err := json.Marshal(data)
|
|
27
|
+
if err != nil {
|
|
28
|
+
return err
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return utils.SaveData(uniquePrefix, key, string(dataBytes), store, config)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// LoadFunction loads a value from storage by key
|
|
35
|
+
func LoadFunction(store interfaces.StorageInterface, uniquePrefix, key string) (interface{}, error) {
|
|
36
|
+
value, err := store.GetKey(uniquePrefix, key)
|
|
37
|
+
if err != nil {
|
|
38
|
+
return []interface{}{}, nil
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var data map[string]interface{}
|
|
42
|
+
if err := json.Unmarshal([]byte(value), &data); err != nil {
|
|
43
|
+
return []interface{}{}, nil
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if val, ok := data["value"]; ok {
|
|
47
|
+
return val, nil
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return []interface{}{}, nil
|
|
51
|
+
}
|
package/dist/generator/generators/golang/templates/storage-templates/storage-interface.mustache
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
package interfaces
|
|
2
|
+
|
|
3
|
+
// StorageInterface provides a standardized abstraction layer for storage operations
|
|
4
|
+
// that can be implemented by different storage backends (Redis, Memory, File, etc.).
|
|
5
|
+
//
|
|
6
|
+
// All operations return errors for failure cases.
|
|
7
|
+
// Keys are strings and values are stored as strings.
|
|
8
|
+
// Implementations should handle serialization/deserialization as needed.
|
|
9
|
+
// Prefix-based operations allow for namespacing and bulk operations.
|
|
10
|
+
//
|
|
11
|
+
// Example implementation:
|
|
12
|
+
//
|
|
13
|
+
// type RedisStorage struct {
|
|
14
|
+
// client *redis.Client
|
|
15
|
+
// }
|
|
16
|
+
//
|
|
17
|
+
// func (r *RedisStorage) SaveKey(uniquePrefix, key, value string) error {
|
|
18
|
+
// fullKey := fmt.Sprintf("%s:%s", uniquePrefix, key)
|
|
19
|
+
// return r.client.Set(ctx, fullKey, value, 0).Err()
|
|
20
|
+
// }
|
|
21
|
+
type StorageInterface interface {
|
|
22
|
+
// SaveKey saves a key-value pair to storage with a unique prefix for namespacing.
|
|
23
|
+
//
|
|
24
|
+
// Parameters:
|
|
25
|
+
// - uniquePrefix: A unique identifier/namespace prefix to prevent key collisions
|
|
26
|
+
// - key: The unique identifier for the stored value within the prefix namespace
|
|
27
|
+
// - value: The string value to store
|
|
28
|
+
//
|
|
29
|
+
// Returns an error if the operation fails.
|
|
30
|
+
//
|
|
31
|
+
// Example:
|
|
32
|
+
// err := storage.SaveKey("app1", "session:abc123", sessionDataJSON)
|
|
33
|
+
SaveKey(uniquePrefix, key, value string) error
|
|
34
|
+
|
|
35
|
+
// GetKey retrieves a value by its key from storage within a specific namespace.
|
|
36
|
+
//
|
|
37
|
+
// Parameters:
|
|
38
|
+
// - uniquePrefix: The unique identifier/namespace prefix used when storing
|
|
39
|
+
// - key: The unique identifier for the value to retrieve within the prefix namespace
|
|
40
|
+
//
|
|
41
|
+
// Returns the stored value or an error if the key does not exist.
|
|
42
|
+
//
|
|
43
|
+
// Example:
|
|
44
|
+
// sessionData, err := storage.GetKey("app1", "session:abc123")
|
|
45
|
+
GetKey(uniquePrefix, key string) (string, error)
|
|
46
|
+
|
|
47
|
+
// DeleteKey removes a key-value pair from storage within a specific namespace.
|
|
48
|
+
//
|
|
49
|
+
// Parameters:
|
|
50
|
+
// - uniquePrefix: The unique identifier/namespace prefix used when storing
|
|
51
|
+
// - key: The unique identifier for the value to delete within the prefix namespace
|
|
52
|
+
//
|
|
53
|
+
// Returns an error if the operation fails.
|
|
54
|
+
//
|
|
55
|
+
// Example:
|
|
56
|
+
// err := storage.DeleteKey("app1", "session:abc123")
|
|
57
|
+
DeleteKey(uniquePrefix, key string) error
|
|
58
|
+
|
|
59
|
+
// ListKeys returns all keys within a specific namespace/prefix.
|
|
60
|
+
//
|
|
61
|
+
// Parameters:
|
|
62
|
+
// - uniquePrefix: The unique identifier/namespace prefix to list keys from
|
|
63
|
+
//
|
|
64
|
+
// Returns an array of keys within that namespace or an error.
|
|
65
|
+
//
|
|
66
|
+
// Example:
|
|
67
|
+
// app1Keys, err := storage.ListKeys("app1")
|
|
68
|
+
// // Returns keys like: ["session:abc123", "user:456", "config:settings"]
|
|
69
|
+
ListKeys(uniquePrefix string) ([]string, error)
|
|
70
|
+
|
|
71
|
+
// ClearStorage removes all stored data from the storage backend.
|
|
72
|
+
//
|
|
73
|
+
// WARNING: This operation is destructive and cannot be undone.
|
|
74
|
+
// Use with caution, especially in production environments.
|
|
75
|
+
//
|
|
76
|
+
// Returns an error if the operation fails.
|
|
77
|
+
//
|
|
78
|
+
// Example:
|
|
79
|
+
// err := storage.ClearStorage() // All data is now removed
|
|
80
|
+
ClearStorage() error
|
|
81
|
+
|
|
82
|
+
// KeyExists checks if a key exists in storage within a specific namespace.
|
|
83
|
+
//
|
|
84
|
+
// Parameters:
|
|
85
|
+
// - uniquePrefix: The unique identifier/namespace prefix to check within
|
|
86
|
+
// - key: The unique identifier to check for existence within the prefix namespace
|
|
87
|
+
//
|
|
88
|
+
// Returns true if the key exists, false otherwise, or an error.
|
|
89
|
+
//
|
|
90
|
+
// Example:
|
|
91
|
+
// exists, err := storage.KeyExists("app1", "user:123")
|
|
92
|
+
// if exists {
|
|
93
|
+
// userData, _ := storage.GetKey("app1", "user:123")
|
|
94
|
+
// }
|
|
95
|
+
KeyExists(uniquePrefix, key string) (bool, error)
|
|
96
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package types
|
|
2
|
+
|
|
3
|
+
// StorageConfig holds configuration for storage retry behavior
|
|
4
|
+
type StorageConfig struct {
|
|
5
|
+
RetryAttempts int // Number of retry attempts for failed operations
|
|
6
|
+
RetryDelayMs int // Delay in milliseconds between retry attempts
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// DefaultStorageConfig returns the default storage configuration
|
|
10
|
+
func DefaultStorageConfig() StorageConfig {
|
|
11
|
+
return StorageConfig{
|
|
12
|
+
RetryAttempts: 3,
|
|
13
|
+
RetryDelayMs: 1000,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
package types
|
|
2
|
+
|
|
3
|
+
import "L1_validations/interfaces"
|
|
4
|
+
|
|
5
|
+
// ValidationConfig holds configuration for validation execution
|
|
6
|
+
type ValidationConfig struct {
|
|
7
|
+
OnlyInvalid bool `json:"only_invalid"`
|
|
8
|
+
StandardLogs bool `json:"standard_logs"`
|
|
9
|
+
Debug bool `json:"_debug"`
|
|
10
|
+
HideParentErrors bool `json:"hide_parent_errors"`
|
|
11
|
+
StateFullValidations bool `json:"state_full_validations"`
|
|
12
|
+
Store interfaces.StorageInterface `json:"-"`
|
|
13
|
+
StorageConfig *StorageConfig `json:"storage_config,omitempty"`
|
|
14
|
+
UniqueKey string `json:"unique_key,omitempty"`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ValidationInput is the input structure for validation functions
|
|
18
|
+
type ValidationInput struct {
|
|
19
|
+
Payload map[string]interface{} `json:"payload"`
|
|
20
|
+
ExternalData map[string]interface{} `json:"external_data"`
|
|
21
|
+
Config ValidationConfig `json:"config"`
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// ValidationOutput represents a single validation result
|
|
25
|
+
type ValidationOutput struct {
|
|
26
|
+
TestName string `json:"test_name,omitempty"`
|
|
27
|
+
Valid bool `json:"valid"`
|
|
28
|
+
Code int `json:"code"`
|
|
29
|
+
Description string `json:"description,omitempty"`
|
|
30
|
+
DebugInfo map[string]interface{} `json:"_debug_info,omitempty"`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ExternalData structure
|
|
34
|
+
type ExternalData struct {
|
|
35
|
+
{{#externalData}}
|
|
36
|
+
{{name}} interface{} `json:"{{name}}"`
|
|
37
|
+
{{/externalData}}
|
|
38
|
+
Self interface{} `json:"_SELF"`
|
|
39
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
func {{name}}(input types.ValidationInput) []types.ValidationOutput {
|
|
2
|
+
scope := utils.GetJSONPath(input.Payload, "{{{scopePath}}}")
|
|
3
|
+
subResults := []types.ValidationOutput{}
|
|
4
|
+
valid := true
|
|
5
|
+
|
|
6
|
+
for _, testObjRaw := range scope {
|
|
7
|
+
testObj, ok := testObjRaw.(map[string]interface{})
|
|
8
|
+
if !ok {
|
|
9
|
+
continue
|
|
10
|
+
}
|
|
11
|
+
testObj["_EXTERNAL"] = input.ExternalData
|
|
12
|
+
|
|
13
|
+
{{#variables}}
|
|
14
|
+
{{name}} {{#isAssignment}}={{/isAssignment}}{{^isAssignment}}:={{/isAssignment}} {{{value}}}
|
|
15
|
+
{{^isAssignment}}utils.UNUSED({{name}}){{/isAssignment}}
|
|
16
|
+
{{/variables}}
|
|
17
|
+
|
|
18
|
+
{{#hasContinue}}
|
|
19
|
+
skipCheck := {{{skipCheckStatement}}}
|
|
20
|
+
if skipCheck {
|
|
21
|
+
continue
|
|
22
|
+
}
|
|
23
|
+
{{/hasContinue}}
|
|
24
|
+
|
|
25
|
+
{{{validationCode}}}
|
|
26
|
+
// delete(testObj, "_EXTERNAL")
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return append([]types.ValidationOutput{
|
|
30
|
+
{
|
|
31
|
+
TestName: "{{testName}}",
|
|
32
|
+
Valid: valid,
|
|
33
|
+
Code: func() int { if valid { return {{successCode}} } else { return {{errorCode}} } }(),
|
|
34
|
+
DebugInfo: map[string]interface{}{
|
|
35
|
+
"fed_config": `{{{TEST_OBJECT}}}`,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
}, subResults...)
|
|
39
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{{#isNested}}
|
|
2
|
+
testFunctions := []func(types.ValidationInput) []types.ValidationOutput{
|
|
3
|
+
{{#names}}
|
|
4
|
+
{{name}},
|
|
5
|
+
{{/names}}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
allResults := []types.ValidationOutput{}
|
|
9
|
+
for _, fn := range testFunctions {
|
|
10
|
+
subResult := fn(input)
|
|
11
|
+
allResults = append(allResults, subResult...)
|
|
12
|
+
}
|
|
13
|
+
subResults = allResults
|
|
14
|
+
valid = true
|
|
15
|
+
for _, r := range subResults {
|
|
16
|
+
if !r.Valid {
|
|
17
|
+
valid = false
|
|
18
|
+
break
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
{{/isNested}}
|
|
23
|
+
|
|
24
|
+
{{^isNested}}
|
|
25
|
+
|
|
26
|
+
{{#isStateFull}}
|
|
27
|
+
validate := true
|
|
28
|
+
if input.Config.StateFullValidations {
|
|
29
|
+
validate = {{{returnStatement}}}
|
|
30
|
+
}
|
|
31
|
+
{{/isStateFull}}
|
|
32
|
+
|
|
33
|
+
{{^isStateFull}}
|
|
34
|
+
validate := {{{returnStatement}}}
|
|
35
|
+
{{/isStateFull}}
|
|
36
|
+
|
|
37
|
+
if !validate {
|
|
38
|
+
return []types.ValidationOutput{
|
|
39
|
+
{
|
|
40
|
+
TestName: "{{testName}}",
|
|
41
|
+
Valid: false,
|
|
42
|
+
Code: {{errorCode}},
|
|
43
|
+
Description: `{{{errorDescription}}}`,
|
|
44
|
+
DebugInfo: map[string]interface{}{
|
|
45
|
+
"fed_config": `{{{TEST_OBJECT}}}`,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
{{/isNested}}
|