diff --git a/pkg/transformers/builder/transformer_builder.go b/pkg/transformers/builder/transformer_builder.go index afbe7600..7d6fe5da 100644 --- a/pkg/transformers/builder/transformer_builder.go +++ b/pkg/transformers/builder/transformer_builder.go @@ -204,5 +204,58 @@ func (b *TransformerBuilder) New(cfg *transformers.Config) (t transformers.Trans if err := transformers.ValidateParameters(cfg.Parameters, paramNames); err != nil { return nil, err } - return transformer.BuildFn(cfg) + tr, err := transformer.BuildFn(cfg) + if err != nil { + return nil, err + } + + postCreateParam, err := b.getPostCreateParam(tr) + if err != nil { + return nil, err + } + + if err := tr.PostCreate(postCreateParam); err != nil { + return nil, err + } + return tr, nil +} + +func (b *TransformerBuilder) getPostCreateParam(tr transformers.Transformer) (any, error) { + switch tr.Type() { + case transformers.Template: + templateTr, ok := tr.(*transformers.TemplateTransformer) + if !ok { + return nil, fmt.Errorf("expected TemplateTransformer, got %T", tr) + } + funcMap, err := b.getTemplatePostCreateParam(templateTr.RequiredTransformers) + if err != nil { + return nil, err + } + return funcMap, nil + case transformers.JSON, transformers.Hstore: + // do the same + } + return nil, nil +} + +func (b *TransformerBuilder) getTemplatePostCreateParam(required map[string]transformers.Config) (map[string]any, error) { + funcMap := make(map[string]any, len(required)) + for name, config := range required { + if config.Name == transformers.Template { + // TODO: do check the same for json and hstore + return nil, fmt.Errorf("recursive template transformer is not allowed") + } + tr, err := b.New(&config) + if err != nil { + return nil, err + } + funcMap[name] = func(val any) (any, error) { + res, err := tr.Transform(nil, transformers.Value{TransformValue: val}) + if err != nil { + return nil, fmt.Errorf("error executing transformer %s: %w", name, err) + } + return res, nil + } + } + return funcMap, nil } diff --git a/pkg/transformers/email_transformer.go b/pkg/transformers/email_transformer.go index c383ac24..280b08f2 100644 --- a/pkg/transformers/email_transformer.go +++ b/pkg/transformers/email_transformer.go @@ -148,6 +148,10 @@ func NewEmailTransformer(params ParameterValues) (*EmailTransformer, error) { }, nil } +func (st *EmailTransformer) PostCreate(_ any) error { + return nil +} + func (st *EmailTransformer) Transform(_ context.Context, v Value) (any, error) { switch str := v.TransformValue.(type) { case string: diff --git a/pkg/transformers/greenmask/greenmask_boolean_transformer.go b/pkg/transformers/greenmask/greenmask_boolean_transformer.go index 0ac87dc5..51fc4e65 100644 --- a/pkg/transformers/greenmask/greenmask_boolean_transformer.go +++ b/pkg/transformers/greenmask/greenmask_boolean_transformer.go @@ -40,6 +40,10 @@ func NewBooleanTransformer(params transformers.ParameterValues) (*BooleanTransfo }, nil } +func (bt *BooleanTransformer) PostCreate(param any) error { + return nil +} + func (bt *BooleanTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/greenmask/greenmask_choice_transformer.go b/pkg/transformers/greenmask/greenmask_choice_transformer.go index 94d338ed..eee1829c 100644 --- a/pkg/transformers/greenmask/greenmask_choice_transformer.go +++ b/pkg/transformers/greenmask/greenmask_choice_transformer.go @@ -68,6 +68,10 @@ func NewChoiceTransformer(params transformers.ParameterValues) (*ChoiceTransform }, nil } +func (t *ChoiceTransformer) PostCreate(param any) error { + return nil +} + func (t *ChoiceTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/greenmask/greenmask_date_transformer.go b/pkg/transformers/greenmask/greenmask_date_transformer.go index d58622c8..f6da523a 100644 --- a/pkg/transformers/greenmask/greenmask_date_transformer.go +++ b/pkg/transformers/greenmask/greenmask_date_transformer.go @@ -94,6 +94,10 @@ func NewDateTransformer(params transformers.ParameterValues) (*DateTransformer, }, nil } +func (t *DateTransformer) PostCreate(param any) error { + return nil +} + func (t *DateTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/greenmask/greenmask_firstname_transformer.go b/pkg/transformers/greenmask/greenmask_firstname_transformer.go index 21af8518..3852b672 100644 --- a/pkg/transformers/greenmask/greenmask_firstname_transformer.go +++ b/pkg/transformers/greenmask/greenmask_firstname_transformer.go @@ -64,6 +64,10 @@ func NewFirstNameTransformer(params, dynamicParams transformers.ParameterValues) }, nil } +func (fnt *FirstNameTransformer) PostCreate(param any) error { + return nil +} + func (fnt *FirstNameTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/greenmask/greenmask_float_transformer.go b/pkg/transformers/greenmask/greenmask_float_transformer.go index 6a0786b0..a29aaf86 100644 --- a/pkg/transformers/greenmask/greenmask_float_transformer.go +++ b/pkg/transformers/greenmask/greenmask_float_transformer.go @@ -89,6 +89,10 @@ func NewFloatTransformer(params transformers.ParameterValues) (*FloatTransformer }, nil } +func (ft *FloatTransformer) PostCreate(param any) error { + return nil +} + func (ft *FloatTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/greenmask/greenmask_integer_transformer.go b/pkg/transformers/greenmask/greenmask_integer_transformer.go index df6f90cb..8ea1b5e9 100644 --- a/pkg/transformers/greenmask/greenmask_integer_transformer.go +++ b/pkg/transformers/greenmask/greenmask_integer_transformer.go @@ -112,6 +112,10 @@ func NewIntegerTransformer(params transformers.ParameterValues) (*IntegerTransfo }, nil } +func (t *IntegerTransformer) PostCreate(param any) error { + return nil +} + // Transform converts the input value to a byte slice, passes it through the underlying // RandomInt64Transformer, and returns the transformed value as an int64. // Supported input types are int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, and byte. diff --git a/pkg/transformers/greenmask/greenmask_string_transformer.go b/pkg/transformers/greenmask/greenmask_string_transformer.go index d95e997e..4e41e20f 100644 --- a/pkg/transformers/greenmask/greenmask_string_transformer.go +++ b/pkg/transformers/greenmask/greenmask_string_transformer.go @@ -85,6 +85,10 @@ func NewStringTransformer(params transformers.ParameterValues) (*StringTransform }, nil } +func (st *StringTransformer) PostCreate(param any) error { + return nil +} + func (st *StringTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/greenmask/greenmask_timestamp_transformer.go b/pkg/transformers/greenmask/greenmask_timestamp_transformer.go index a11bff6f..73182ecd 100644 --- a/pkg/transformers/greenmask/greenmask_timestamp_transformer.go +++ b/pkg/transformers/greenmask/greenmask_timestamp_transformer.go @@ -105,6 +105,10 @@ func NewUTCTimestampTransformer(params transformers.ParameterValues) (*UTCTimest }, nil } +func (t *UTCTimestampTransformer) PostCreate(param any) error { + return nil +} + func (t *UTCTimestampTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go b/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go index 590f1653..325a5565 100644 --- a/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go +++ b/pkg/transformers/greenmask/greenmask_unix_timestamp_transformer.go @@ -90,6 +90,10 @@ func NewUnixTimestampTransformer(params transformers.ParameterValues) (*UnixTime }, nil } +func (t *UnixTimestampTransformer) PostCreate(param any) error { + return nil +} + func (t *UnixTimestampTransformer) Type() transformers.TransformerType { return transformers.GreenmaskUnixTimestamp } diff --git a/pkg/transformers/greenmask/greenmask_uuid_transformer.go b/pkg/transformers/greenmask/greenmask_uuid_transformer.go index 01401f39..3706ba98 100644 --- a/pkg/transformers/greenmask/greenmask_uuid_transformer.go +++ b/pkg/transformers/greenmask/greenmask_uuid_transformer.go @@ -43,6 +43,10 @@ func NewUUIDTransformer(params transformers.ParameterValues) (*UUIDTransformer, }, nil } +func (ut *UUIDTransformer) PostCreate(param any) error { + return nil +} + func (ut *UUIDTransformer) Transform(_ context.Context, value transformers.Value) (any, error) { var toTransform []byte switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/hstore_transformer.go b/pkg/transformers/hstore_transformer.go index 693ba87e..bbe11620 100644 --- a/pkg/transformers/hstore_transformer.go +++ b/pkg/transformers/hstore_transformer.go @@ -9,7 +9,6 @@ import ( "fmt" "text/template" - "github.com/Masterminds/sprig/v3" greenmasktoolkit "github.com/eminano/greenmask/pkg/toolkit" "github.com/jackc/pgx/v5/pgtype" ) @@ -54,7 +53,6 @@ func NewHstoreTransformer(params ParameterValues) (*HstoreTransformer, error) { if o.valueTemplate != "" { tmpl, err := template.New(fmt.Sprintf("op[%d] %s %s", idx, o.operation, o.key)). Funcs(greenmasktoolkit.FuncMap()). - Funcs(sprig.FuncMap()). Parse(o.valueTemplate) if err != nil { return nil, fmt.Errorf("hstore_transformer: error parsing template op[%d] with key \"%s\": %w", idx, o.key, err) @@ -70,6 +68,10 @@ func NewHstoreTransformer(params ParameterValues) (*HstoreTransformer, error) { }, nil } +func (t *HstoreTransformer) PostCreate(_ any) error { + return nil // TODO: implement +} + func (t *HstoreTransformer) Transform(_ context.Context, value Value) (any, error) { var err error var toTransform pgtype.Hstore diff --git a/pkg/transformers/instrumentation/instrumented_transformer.go b/pkg/transformers/instrumentation/instrumented_transformer.go index 68c6631f..a7ed1828 100644 --- a/pkg/transformers/instrumentation/instrumented_transformer.go +++ b/pkg/transformers/instrumentation/instrumented_transformer.go @@ -47,6 +47,10 @@ func NewTransformer(t transformers.Transformer, instrumentation *otel.Instrument return transformer, nil } +func (i *Transformer) PostCreate(param any) error { + return i.inner.PostCreate(param) +} + func (i *Transformer) Transform(ctx context.Context, v transformers.Value) (res any, err error) { ctx, span := otel.StartSpan(ctx, i.tracer, "transformer.Transform", trace.WithAttributes(i.typeAttribute())) defer otel.CloseSpan(span, err) diff --git a/pkg/transformers/json_transformer.go b/pkg/transformers/json_transformer.go index 9059c3b9..d4b59584 100644 --- a/pkg/transformers/json_transformer.go +++ b/pkg/transformers/json_transformer.go @@ -10,7 +10,6 @@ import ( "slices" "text/template" - "github.com/Masterminds/sprig/v3" greenmasktoolkit "github.com/eminano/greenmask/pkg/toolkit" "github.com/xataio/pgstream/internal/json" ) @@ -58,7 +57,6 @@ func NewJSONTransformer(params ParameterValues) (*JSONTransformer, error) { if o.valueTemplate != "" { tmpl, err := template.New(fmt.Sprintf("op[%d] %s %s", idx, o.operation, o.path)). Funcs(greenmasktoolkit.FuncMap()). - Funcs(sprig.FuncMap()). Parse(o.valueTemplate) if err != nil { return nil, fmt.Errorf("json_transformer: error parsing template op[%d] with path \"%s\": %w", idx, o.path, err) @@ -74,6 +72,10 @@ func NewJSONTransformer(params ParameterValues) (*JSONTransformer, error) { }, nil } +func (jt *JSONTransformer) PostCreate(_ any) error { + return nil // TODO: implement +} + func (jt *JSONTransformer) Transform(_ context.Context, value Value) (any, error) { var err error var toTransform []byte diff --git a/pkg/transformers/literal_string_transformer.go b/pkg/transformers/literal_string_transformer.go index 5568f1af..cc3ab1df 100644 --- a/pkg/transformers/literal_string_transformer.go +++ b/pkg/transformers/literal_string_transformer.go @@ -42,6 +42,10 @@ func NewLiteralStringTransformer(params ParameterValues) (*LiteralStringTransfor }, nil } +func (lst *LiteralStringTransformer) PostCreate(_ any) error { + return nil +} + func (lst *LiteralStringTransformer) Transform(_ context.Context, value Value) (any, error) { return lst.literal, nil } diff --git a/pkg/transformers/masking_transformer.go b/pkg/transformers/masking_transformer.go index 08890f4f..751703d2 100644 --- a/pkg/transformers/masking_transformer.go +++ b/pkg/transformers/masking_transformer.go @@ -130,6 +130,10 @@ func NewMaskingTransformer(params ParameterValues) (*MaskingTransformer, error) }, nil } +func (t *MaskingTransformer) PostCreate(_ any) error { + return nil +} + // Transform applies the masking function to the input value and returns the masked value. func (t *MaskingTransformer) Transform(_ context.Context, value Value) (any, error) { switch val := value.TransformValue.(type) { diff --git a/pkg/transformers/mocks/mock_transformer.go b/pkg/transformers/mocks/mock_transformer.go index 6c3ba4dc..7b212fed 100644 --- a/pkg/transformers/mocks/mock_transformer.go +++ b/pkg/transformers/mocks/mock_transformer.go @@ -13,6 +13,10 @@ type Transformer struct { CompatibleTypesFn func() []transformers.SupportedDataType } +func (m *Transformer) PostCreate(param any) error { + return nil +} + func (m *Transformer) Transform(_ context.Context, val transformers.Value) (any, error) { return m.TransformFn(val) } diff --git a/pkg/transformers/neosync/neosync_email_transformer.go b/pkg/transformers/neosync/neosync_email_transformer.go index 18a4ac3b..d69130b1 100644 --- a/pkg/transformers/neosync/neosync_email_transformer.go +++ b/pkg/transformers/neosync/neosync_email_transformer.go @@ -142,6 +142,10 @@ func NewEmailTransformer(params transformers.ParameterValues) (*EmailTransformer }, nil } +func (t *EmailTransformer) PostCreate(param any) error { + return nil +} + func (t *EmailTransformer) CompatibleTypes() []transformers.SupportedDataType { return emailCompatibleTypes } diff --git a/pkg/transformers/neosync/neosync_firstname_transformer.go b/pkg/transformers/neosync/neosync_firstname_transformer.go index 8a803fb4..abe58e63 100644 --- a/pkg/transformers/neosync/neosync_firstname_transformer.go +++ b/pkg/transformers/neosync/neosync_firstname_transformer.go @@ -86,6 +86,10 @@ func NewFirstNameTransformer(params transformers.ParameterValues) (*FirstNameTra }, nil } +func (t *FirstNameTransformer) PostCreate(param any) error { + return nil +} + func (t *FirstNameTransformer) Transform(ctx context.Context, value transformers.Value) (any, error) { transformedValue, err := t.transformer.Transform(ctx, value) if err != nil { diff --git a/pkg/transformers/neosync/neosync_fullname_transformer.go b/pkg/transformers/neosync/neosync_fullname_transformer.go index 6bd0bd52..13d71450 100644 --- a/pkg/transformers/neosync/neosync_fullname_transformer.go +++ b/pkg/transformers/neosync/neosync_fullname_transformer.go @@ -97,6 +97,10 @@ func NewFullNameTransformer(params transformers.ParameterValues) (*FullNameTrans }, nil } +func (t *FullNameTransformer) PostCreate(param any) error { + return nil +} + func (t *FullNameTransformer) Transform(ctx context.Context, value transformers.Value) (any, error) { var retVal string maxLength := t.maxLength diff --git a/pkg/transformers/neosync/neosync_lastname_transformer.go b/pkg/transformers/neosync/neosync_lastname_transformer.go index 17166401..fb647e1f 100644 --- a/pkg/transformers/neosync/neosync_lastname_transformer.go +++ b/pkg/transformers/neosync/neosync_lastname_transformer.go @@ -85,6 +85,10 @@ func NewLastNameTransformer(params transformers.ParameterValues) (*LastNameTrans }, nil } +func (t *LastNameTransformer) PostCreate(param any) error { + return nil +} + func (t *LastNameTransformer) Transform(ctx context.Context, value transformers.Value) (any, error) { transformedValue, err := t.transformer.Transform(ctx, value) if err != nil { diff --git a/pkg/transformers/neosync/neosync_string_transformer.go b/pkg/transformers/neosync/neosync_string_transformer.go index f52353ee..75c7f2a7 100644 --- a/pkg/transformers/neosync/neosync_string_transformer.go +++ b/pkg/transformers/neosync/neosync_string_transformer.go @@ -80,6 +80,10 @@ func NewStringTransformer(params transformers.ParameterValues) (*StringTransform }, nil } +func (t *StringTransformer) PostCreate(param any) error { + return nil +} + func (t *StringTransformer) CompatibleTypes() []transformers.SupportedDataType { return stringCompatibleTypes } diff --git a/pkg/transformers/pg_anonymizer_transformer.go b/pkg/transformers/pg_anonymizer_transformer.go index 3c2a18dd..5e55582a 100644 --- a/pkg/transformers/pg_anonymizer_transformer.go +++ b/pkg/transformers/pg_anonymizer_transformer.go @@ -369,6 +369,10 @@ func NewPGAnonymizerTransformer(params ParameterValues) (*PGAnonymizerTransforme return t, nil } +func (t *PGAnonymizerTransformer) PostCreate(_ any) error { + return nil +} + func (t *PGAnonymizerTransformer) Transform(ctx context.Context, value Value) (any, error) { query, args := t.buildParameterizedQuery(value.TransformValue, value.TransformType) diff --git a/pkg/transformers/phone_number_transformer.go b/pkg/transformers/phone_number_transformer.go index d827481a..9fcd697f 100644 --- a/pkg/transformers/phone_number_transformer.go +++ b/pkg/transformers/phone_number_transformer.go @@ -115,6 +115,10 @@ func NewPhoneNumberTransformer(params, dynamicParams ParameterValues) (*PhoneNum }, nil } +func (t *PhoneNumberTransformer) PostCreate(_ any) error { + return nil +} + func (t *PhoneNumberTransformer) Transform(_ context.Context, value Value) (any, error) { switch v := value.TransformValue.(type) { case string: diff --git a/pkg/transformers/string_transformer.go b/pkg/transformers/string_transformer.go index cbef2fb8..6e172801 100644 --- a/pkg/transformers/string_transformer.go +++ b/pkg/transformers/string_transformer.go @@ -27,6 +27,10 @@ func NewStringTransformer(params ParameterValues) (*StringTransformer, error) { return &StringTransformer{}, nil } +func (st *StringTransformer) PostCreate(_ any) error { + return nil +} + func (st *StringTransformer) Transform(_ context.Context, v Value) (any, error) { switch str := v.TransformValue.(type) { case string: diff --git a/pkg/transformers/template_transformer.go b/pkg/transformers/template_transformer.go index 7fe42cb0..a2f60a44 100644 --- a/pkg/transformers/template_transformer.go +++ b/pkg/transformers/template_transformer.go @@ -9,17 +9,21 @@ import ( "strings" "text/template" - "github.com/Masterminds/sprig/v3" greenmasktoolkit "github.com/eminano/greenmask/pkg/toolkit" ) type TemplateTransformer struct { - template *template.Template + template *template.Template + templateStr string + RequiredTransformers map[string]Config } var ( - errTemplateMustBeProvided = errors.New("template_transformer: template parameter must be provided") - templateCompatibleTypes = []SupportedDataType{ + errTemplateMustBeProvided = errors.New("template_transformer: template parameter must be provided") + errExposedNameMustBeProvided = errors.New("template_transformer: template_function_name must be provided in the functions array elements") + errTransformerNameMustBeProvided = errors.New("template_transformer: name must be provided in the functions array elements") + errTransformerParamsMustBeProvided = errors.New("template_transformer: parameters must be provided in the functions array elements") + templateCompatibleTypes = []SupportedDataType{ StringDataType, ByteArrayDataType, } @@ -31,6 +35,13 @@ var ( Dynamic: false, Required: true, }, + { + Name: "functions", + SupportedType: "array", + Default: nil, + Dynamic: false, + Required: false, + }, } ) @@ -43,11 +54,27 @@ func NewTemplateTransformer(params ParameterValues) (*TemplateTransformer, error return nil, errTemplateMustBeProvided } - tmpl, err := template.New("").Funcs(greenmasktoolkit.FuncMap()).Funcs(sprig.FuncMap()).Parse(templateStr) + requiredTransformers, err := getRequiredTransformersConfig(params) + if err != nil { + return nil, fmt.Errorf("template_transformer: error getting required transformers config: %w", err) + } + + return &TemplateTransformer{templateStr: templateStr, RequiredTransformers: requiredTransformers}, nil +} + +func (t *TemplateTransformer) PostCreate(param any) error { + funcMap, ok := param.(map[string]any) + if !ok { + return fmt.Errorf("template_transformer: expected map[string]any for PostCreate parameter, got %T", param) + } + + tmpl, err := template.New("").Funcs(greenmasktoolkit.FuncMap()).Funcs(funcMap).Parse(t.templateStr) if err != nil { - return nil, fmt.Errorf("template_transformer: error parsing template: %w", err) + return fmt.Errorf("template_transformer: error parsing template: %w", err) } - return &TemplateTransformer{template: tmpl}, nil + + t.template = tmpl + return nil } func (t *TemplateTransformer) Transform(_ context.Context, value Value) (any, error) { @@ -76,3 +103,54 @@ func TemplateTransformerDefinition() *Definition { Parameters: templateParams, } } + +func getRequiredTransformersConfig(params ParameterValues) (map[string]Config, error) { + arrayAny, _, err := FindParameter[[]any](params, "functions") + if err != nil { + return nil, fmt.Errorf("functions must be an array: %w", err) + } + if len(arrayAny) == 0 { + return nil, nil + } + + requiredTransformersConfig := make(map[string]Config, len(arrayAny)) + for _, valAny := range arrayAny { + val, ok := valAny.(map[string]any) + if !ok { + return nil, fmt.Errorf("invalid element type in functions array, got %T: %w", valAny, ErrInvalidParameters) + } + + exposedName, found, err := FindParameter[string](val, "template_function_name") + if err != nil { + return nil, fmt.Errorf("template_function_name must be a string: %w", err) + } + if !found { + return nil, errExposedNameMustBeProvided + } + if _, found := requiredTransformersConfig[exposedName]; found { + return nil, fmt.Errorf("duplicate template_function_name found: %s", exposedName) + } + + transformerName, found, err := FindParameter[string](val, "name") + if err != nil { + return nil, fmt.Errorf("name must be a string: %w", err) + } + if !found { + return nil, errTransformerNameMustBeProvided + } + + transformerParams, found, err := FindParameter[map[string]any](val, "parameters") + if err != nil { + return nil, fmt.Errorf("parameters must be a map: %w", err) + } + if !found { + return nil, errTransformerParamsMustBeProvided + } + + requiredTransformersConfig[exposedName] = Config{ + Name: TransformerType(transformerName), + Parameters: transformerParams, + } + } + return requiredTransformersConfig, nil +} diff --git a/pkg/transformers/transformer.go b/pkg/transformers/transformer.go index 0dec75cf..b7bb1f36 100644 --- a/pkg/transformers/transformer.go +++ b/pkg/transformers/transformer.go @@ -12,6 +12,7 @@ type Transformer interface { Transform(context.Context, Value) (any, error) CompatibleTypes() []SupportedDataType Type() TransformerType + PostCreate(any) error Close() error } diff --git a/transformers-definition.json b/transformers-definition.json index aca3eb22..04a5685a 100644 --- a/transformers-definition.json +++ b/transformers-definition.json @@ -906,6 +906,13 @@ "default": null, "dynamic": false, "required": true + }, + { + "name": "functions", + "supported_type": "array", + "default": null, + "dynamic": false, + "required": false } ] }