codify-plugin-lib 1.0.135 → 1.0.137
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/dist/resource/parsed-resource-settings.d.ts +1 -0
- package/dist/resource/parsed-resource-settings.js +2 -0
- package/dist/resource/resource-controller.js +7 -0
- package/dist/resource/resource-settings.d.ts +17 -1
- package/dist/resource/resource-settings.js +9 -6
- package/package.json +1 -1
- package/src/resource/parsed-resource-settings.ts +2 -0
- package/src/resource/resource-controller.test.ts +95 -2
- package/src/resource/resource-controller.ts +9 -0
- package/src/resource/resource-settings.test.ts +83 -3
- package/src/resource/resource-settings.ts +29 -7
|
@@ -25,6 +25,7 @@ export declare class ParsedResourceSettings<T extends StringIndexedObject> imple
|
|
|
25
25
|
} | boolean;
|
|
26
26
|
removeStatefulParametersBeforeDestroy?: boolean | undefined;
|
|
27
27
|
dependencies?: string[] | undefined;
|
|
28
|
+
transformation?: InputTransformation;
|
|
28
29
|
private settings;
|
|
29
30
|
constructor(settings: ResourceSettings<T>);
|
|
30
31
|
get typeId(): string;
|
|
@@ -7,6 +7,7 @@ export class ParsedResourceSettings {
|
|
|
7
7
|
allowMultiple;
|
|
8
8
|
removeStatefulParametersBeforeDestroy;
|
|
9
9
|
dependencies;
|
|
10
|
+
transformation;
|
|
10
11
|
settings;
|
|
11
12
|
constructor(settings) {
|
|
12
13
|
this.settings = settings;
|
|
@@ -15,6 +16,7 @@ export class ParsedResourceSettings {
|
|
|
15
16
|
this.allowMultiple = settings.allowMultiple;
|
|
16
17
|
this.removeStatefulParametersBeforeDestroy = settings.removeStatefulParametersBeforeDestroy;
|
|
17
18
|
this.dependencies = settings.dependencies;
|
|
19
|
+
this.transformation = settings.transformation;
|
|
18
20
|
this.validateSettings();
|
|
19
21
|
}
|
|
20
22
|
get typeId() {
|
|
@@ -250,6 +250,13 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
250
250
|
? await inputTransformation.from(config[key])
|
|
251
251
|
: await inputTransformation.to(config[key]);
|
|
252
252
|
}
|
|
253
|
+
if (this.settings.transformation) {
|
|
254
|
+
const transformed = reverse
|
|
255
|
+
? await this.settings.transformation.from({ ...config })
|
|
256
|
+
: await this.settings.transformation.to({ ...config });
|
|
257
|
+
Object.keys(config).forEach((k) => delete config[k]);
|
|
258
|
+
Object.assign(config, transformed);
|
|
259
|
+
}
|
|
253
260
|
}
|
|
254
261
|
addDefaultValues(config) {
|
|
255
262
|
if (!config) {
|
|
@@ -60,6 +60,13 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
60
60
|
* and applying any input transformations. Use parameter settings to define stateful parameters as well.
|
|
61
61
|
*/
|
|
62
62
|
parameterSettings?: Partial<Record<keyof T, ParameterSetting>>;
|
|
63
|
+
/**
|
|
64
|
+
* A config level transformation that is only applied to the user supplied desired config. This transformation is allowed
|
|
65
|
+
* to add, remove or modify keys as well as values. Changing this transformation for existing libraries will mess up existing states.
|
|
66
|
+
*
|
|
67
|
+
* @param desired
|
|
68
|
+
*/
|
|
69
|
+
transformation?: InputTransformation;
|
|
63
70
|
/**
|
|
64
71
|
* Customize the import and destory behavior of the resource. By default, <code>codify import</code> and <code>codify destroy</code> will call
|
|
65
72
|
* `refresh()` with every parameter set to null and return the result of the refresh as the imported config. It looks for required parameters
|
|
@@ -144,7 +151,7 @@ export interface DefaultParameterSetting {
|
|
|
144
151
|
*
|
|
145
152
|
* @param input The original parameter value from the desired config.
|
|
146
153
|
*/
|
|
147
|
-
|
|
154
|
+
transformation?: InputTransformation;
|
|
148
155
|
/**
|
|
149
156
|
* Customize the equality comparison for a parameter. This is used in the diffing algorithm for generating the plan.
|
|
150
157
|
* This value will override the pre-set equality function from the type. Return true if the desired value is
|
|
@@ -165,6 +172,15 @@ export interface DefaultParameterSetting {
|
|
|
165
172
|
* 2. AWS profile secret keys that can be updated without the re-installation of AWS CLI
|
|
166
173
|
*/
|
|
167
174
|
canModify?: boolean;
|
|
175
|
+
/**
|
|
176
|
+
* This option allows the plan to skip this parameter entirely as it is used for setting purposes only. The value
|
|
177
|
+
* of this parameter is used to configure the resource or other parameters.
|
|
178
|
+
*
|
|
179
|
+
* Examples:
|
|
180
|
+
* 1. homebrew.onlyPlanUserInstalled option will tell homebrew to filter by --installed-on-request. But the value,
|
|
181
|
+
* of the parameter itself (true or false) does not have an impact on the plan
|
|
182
|
+
*/
|
|
183
|
+
setting?: boolean;
|
|
168
184
|
}
|
|
169
185
|
/**
|
|
170
186
|
* Array type specific settings. See {@link DefaultParameterSetting } for a full list of options.
|
|
@@ -7,10 +7,13 @@ const ParameterEqualsDefaults = {
|
|
|
7
7
|
'number': (a, b) => Number(a) === Number(b),
|
|
8
8
|
'string': (a, b) => String(a) === String(b),
|
|
9
9
|
'version': (desired, current) => String(current).includes(String(desired)),
|
|
10
|
-
'setting': () => true,
|
|
11
10
|
'object': isObjectsEqual,
|
|
12
11
|
};
|
|
13
12
|
export function resolveEqualsFn(parameter) {
|
|
13
|
+
// Setting parameters do not impact the plan
|
|
14
|
+
if (parameter.setting) {
|
|
15
|
+
return () => true;
|
|
16
|
+
}
|
|
14
17
|
const isEqual = resolveFnFromEqualsFnOrString(parameter.isEqual);
|
|
15
18
|
if (parameter.type === 'array') {
|
|
16
19
|
return isEqual ?? areArraysEqual.bind(areArraysEqual, resolveElementEqualsFn(parameter));
|
|
@@ -54,17 +57,17 @@ const ParameterTransformationDefaults = {
|
|
|
54
57
|
}
|
|
55
58
|
};
|
|
56
59
|
export function resolveParameterTransformFn(parameter) {
|
|
57
|
-
if (parameter.type === 'stateful' && !parameter.
|
|
60
|
+
if (parameter.type === 'stateful' && !parameter.transformation) {
|
|
58
61
|
const sp = parameter.definition.getSettings();
|
|
59
|
-
if (sp.
|
|
60
|
-
return parameter.definition?.getSettings()?.
|
|
62
|
+
if (sp.transformation) {
|
|
63
|
+
return parameter.definition?.getSettings()?.transformation;
|
|
61
64
|
}
|
|
62
65
|
return sp.type ? ParameterTransformationDefaults[sp.type] : undefined;
|
|
63
66
|
}
|
|
64
67
|
if (parameter.type === 'array'
|
|
65
68
|
&& parameter.itemType
|
|
66
69
|
&& ParameterTransformationDefaults[parameter.itemType]
|
|
67
|
-
&& !parameter.
|
|
70
|
+
&& !parameter.transformation) {
|
|
68
71
|
const itemType = parameter.itemType;
|
|
69
72
|
const itemTransformation = ParameterTransformationDefaults[itemType];
|
|
70
73
|
return {
|
|
@@ -76,5 +79,5 @@ export function resolveParameterTransformFn(parameter) {
|
|
|
76
79
|
}
|
|
77
80
|
};
|
|
78
81
|
}
|
|
79
|
-
return parameter.
|
|
82
|
+
return parameter.transformation ?? ParameterTransformationDefaults[parameter.type] ?? undefined;
|
|
80
83
|
}
|
package/package.json
CHANGED
|
@@ -44,6 +44,7 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
|
|
|
44
44
|
|
|
45
45
|
removeStatefulParametersBeforeDestroy?: boolean | undefined;
|
|
46
46
|
dependencies?: string[] | undefined;
|
|
47
|
+
transformation?: InputTransformation;
|
|
47
48
|
private settings: ResourceSettings<T>;
|
|
48
49
|
|
|
49
50
|
constructor(settings: ResourceSettings<T>) {
|
|
@@ -53,6 +54,7 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
|
|
|
53
54
|
this.allowMultiple = settings.allowMultiple;
|
|
54
55
|
this.removeStatefulParametersBeforeDestroy = settings.removeStatefulParametersBeforeDestroy;
|
|
55
56
|
this.dependencies = settings.dependencies;
|
|
57
|
+
this.transformation = settings.transformation;
|
|
56
58
|
|
|
57
59
|
this.validateSettings();
|
|
58
60
|
}
|
|
@@ -20,7 +20,10 @@ describe('Resource tests', () => {
|
|
|
20
20
|
id: 'type',
|
|
21
21
|
dependencies: ['homebrew', 'python'],
|
|
22
22
|
parameterSettings: {
|
|
23
|
-
propA: {
|
|
23
|
+
propA: {
|
|
24
|
+
canModify: true,
|
|
25
|
+
transformation: { to: (input) => untildify(input), from: (input) => tildify(input) }
|
|
26
|
+
},
|
|
24
27
|
},
|
|
25
28
|
}
|
|
26
29
|
}
|
|
@@ -543,7 +546,7 @@ describe('Resource tests', () => {
|
|
|
543
546
|
parameterSettings: {
|
|
544
547
|
propD: {
|
|
545
548
|
type: 'array',
|
|
546
|
-
|
|
549
|
+
transformation: {
|
|
547
550
|
to: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
|
|
548
551
|
Object.entries(h)
|
|
549
552
|
.map(([k, v]) => [
|
|
@@ -618,4 +621,94 @@ describe('Resource tests', () => {
|
|
|
618
621
|
}
|
|
619
622
|
})
|
|
620
623
|
})
|
|
624
|
+
|
|
625
|
+
it('Applies reverse input transformations for imports (object level)', async () => {
|
|
626
|
+
const resource = new class extends TestResource {
|
|
627
|
+
getSettings(): ResourceSettings<TestConfig> {
|
|
628
|
+
return {
|
|
629
|
+
id: 'resourceType',
|
|
630
|
+
parameterSettings: {
|
|
631
|
+
propD: {
|
|
632
|
+
type: 'array',
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
transformation: {
|
|
636
|
+
to: (input: any) => ({
|
|
637
|
+
...input,
|
|
638
|
+
propD: input.propD?.map((h) => Object.fromEntries(
|
|
639
|
+
Object.entries(h)
|
|
640
|
+
.map(([k, v]) => [
|
|
641
|
+
k,
|
|
642
|
+
typeof v === 'boolean'
|
|
643
|
+
? (v ? 'yes' : 'no') // The file takes 'yes' or 'no' instead of booleans
|
|
644
|
+
: v,
|
|
645
|
+
])
|
|
646
|
+
)
|
|
647
|
+
)
|
|
648
|
+
}),
|
|
649
|
+
from: (output: any) => ({
|
|
650
|
+
...output,
|
|
651
|
+
propD: output.propD?.map((h) => Object.fromEntries(
|
|
652
|
+
Object.entries(h)
|
|
653
|
+
.map(([k, v]) => [
|
|
654
|
+
k,
|
|
655
|
+
v === 'yes' || v === 'no'
|
|
656
|
+
? (v === 'yes')
|
|
657
|
+
: v,
|
|
658
|
+
])
|
|
659
|
+
))
|
|
660
|
+
})
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
async refresh(parameters: Partial<TestConfig>): Promise<Partial<TestConfig> | null> {
|
|
666
|
+
return {
|
|
667
|
+
propD: [
|
|
668
|
+
{
|
|
669
|
+
Host: 'new.com',
|
|
670
|
+
AddKeysToAgent: true,
|
|
671
|
+
IdentityFile: 'id_ed25519'
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
Host: 'github.com',
|
|
675
|
+
AddKeysToAgent: true,
|
|
676
|
+
UseKeychain: true,
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
Match: 'User bob,joe,phil',
|
|
680
|
+
PasswordAuthentication: true,
|
|
681
|
+
}
|
|
682
|
+
],
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const controller = new ResourceController(resource);
|
|
688
|
+
const plan = await controller.import({ type: 'resourceType' }, {});
|
|
689
|
+
|
|
690
|
+
expect(plan![0]).toMatchObject({
|
|
691
|
+
'core': {
|
|
692
|
+
'type': 'resourceType'
|
|
693
|
+
},
|
|
694
|
+
'parameters': {
|
|
695
|
+
'propD': [
|
|
696
|
+
{
|
|
697
|
+
'Host': 'new.com',
|
|
698
|
+
'AddKeysToAgent': true,
|
|
699
|
+
'IdentityFile': 'id_ed25519'
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
'Host': 'github.com',
|
|
703
|
+
'AddKeysToAgent': true,
|
|
704
|
+
'UseKeychain': true
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
'Match': 'User bob,joe,phil',
|
|
708
|
+
'PasswordAuthentication': true
|
|
709
|
+
}
|
|
710
|
+
]
|
|
711
|
+
}
|
|
712
|
+
})
|
|
713
|
+
})
|
|
621
714
|
});
|
|
@@ -350,6 +350,15 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
350
350
|
? await inputTransformation.from(config[key])
|
|
351
351
|
: await inputTransformation.to(config[key]);
|
|
352
352
|
}
|
|
353
|
+
|
|
354
|
+
if (this.settings.transformation) {
|
|
355
|
+
const transformed = reverse
|
|
356
|
+
? await this.settings.transformation.from({ ...config })
|
|
357
|
+
: await this.settings.transformation.to({ ...config })
|
|
358
|
+
|
|
359
|
+
Object.keys(config).forEach((k) => delete config[k])
|
|
360
|
+
Object.assign(config, transformed);
|
|
361
|
+
}
|
|
353
362
|
}
|
|
354
363
|
|
|
355
364
|
private addDefaultValues(config: Partial<T> | null): void {
|
|
@@ -564,6 +564,86 @@ describe('Resource parameter tests', () => {
|
|
|
564
564
|
expect(timestampC).to.be.lessThan(timestampA as any);
|
|
565
565
|
})
|
|
566
566
|
|
|
567
|
+
it('Supports transform parameters', async () => {
|
|
568
|
+
const resource = spy(new class extends TestResource {
|
|
569
|
+
getSettings(): ResourceSettings<TestConfig> {
|
|
570
|
+
return {
|
|
571
|
+
id: 'resourceType',
|
|
572
|
+
transformation: {
|
|
573
|
+
to: (desired) => ({
|
|
574
|
+
propA: 'propA',
|
|
575
|
+
propB: 10,
|
|
576
|
+
}),
|
|
577
|
+
from: (current) => ({
|
|
578
|
+
propA: 'propA',
|
|
579
|
+
propB: 10,
|
|
580
|
+
})
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
586
|
+
return {
|
|
587
|
+
propA: 'propA',
|
|
588
|
+
propB: 10,
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
const controller = new ResourceController(resource);
|
|
594
|
+
const plan = await controller.plan({ type: 'resourceType' }, { propC: 'abc' } as any, null, false);
|
|
595
|
+
|
|
596
|
+
expect(resource.refresh.called).to.be.true;
|
|
597
|
+
expect(resource.refresh.getCall(0).firstArg['propA']).to.exist;
|
|
598
|
+
expect(resource.refresh.getCall(0).firstArg['propB']).to.exist;
|
|
599
|
+
expect(resource.refresh.getCall(0).firstArg['propC']).to.not.exist;
|
|
600
|
+
|
|
601
|
+
expect(plan.desiredConfig?.propA).to.eq('propA');
|
|
602
|
+
expect(plan.desiredConfig?.propB).to.eq(10);
|
|
603
|
+
expect(plan.desiredConfig?.propC).to.be.undefined;
|
|
604
|
+
|
|
605
|
+
expect(plan.changeSet.operation).to.eq(ResourceOperation.NOOP);
|
|
606
|
+
})
|
|
607
|
+
|
|
608
|
+
it('Supports transform parameters for state parameters', async () => {
|
|
609
|
+
const resource = spy(new class extends TestResource {
|
|
610
|
+
getSettings(): ResourceSettings<TestConfig> {
|
|
611
|
+
return {
|
|
612
|
+
id: 'resourceType',
|
|
613
|
+
transformation: {
|
|
614
|
+
to: (desired) => ({
|
|
615
|
+
propA: 'propA',
|
|
616
|
+
propB: 10,
|
|
617
|
+
}),
|
|
618
|
+
from: (desired) => ({
|
|
619
|
+
propA: 'propA',
|
|
620
|
+
propB: 10,
|
|
621
|
+
})
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
627
|
+
return {
|
|
628
|
+
propA: 'propA',
|
|
629
|
+
propB: 10,
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
const controller = new ResourceController(resource);
|
|
635
|
+
const plan = await controller.plan({ type: 'resourceType' }, null, { propC: 'abc' }, true);
|
|
636
|
+
|
|
637
|
+
expect(resource.refresh.called).to.be.true;
|
|
638
|
+
expect(resource.refresh.getCall(0).firstArg['propA']).to.exist;
|
|
639
|
+
expect(resource.refresh.getCall(0).firstArg['propB']).to.exist;
|
|
640
|
+
expect(resource.refresh.getCall(0).firstArg['propC']).to.not.exist;
|
|
641
|
+
|
|
642
|
+
expect(plan.currentConfig?.propA).to.eq('propA');
|
|
643
|
+
expect(plan.currentConfig?.propB).to.eq(10);
|
|
644
|
+
expect(plan.currentConfig?.propC).to.be.undefined;
|
|
645
|
+
})
|
|
646
|
+
|
|
567
647
|
it('Allows import required parameters customization', () => {
|
|
568
648
|
const resource = new class extends TestResource {
|
|
569
649
|
getSettings(): ResourceSettings<TestConfig> {
|
|
@@ -616,7 +696,7 @@ describe('Resource parameter tests', () => {
|
|
|
616
696
|
return {
|
|
617
697
|
id: 'resourceType',
|
|
618
698
|
parameterSettings: {
|
|
619
|
-
propA: { type: '
|
|
699
|
+
propA: { type: 'string', setting: true },
|
|
620
700
|
propB: { type: 'number' }
|
|
621
701
|
}
|
|
622
702
|
}
|
|
@@ -784,7 +864,7 @@ describe('Resource parameter tests', () => {
|
|
|
784
864
|
parameterSettings: {
|
|
785
865
|
propD: {
|
|
786
866
|
type: 'array',
|
|
787
|
-
|
|
867
|
+
transformation: {
|
|
788
868
|
to: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
|
|
789
869
|
Object.entries(h)
|
|
790
870
|
.map(([k, v]) => [
|
|
@@ -850,7 +930,7 @@ describe('Resource parameter tests', () => {
|
|
|
850
930
|
getSettings(): any {
|
|
851
931
|
return {
|
|
852
932
|
type: 'array',
|
|
853
|
-
|
|
933
|
+
transformation: {
|
|
854
934
|
to: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
|
|
855
935
|
Object.entries(h)
|
|
856
936
|
.map(([k, v]) => [
|
|
@@ -75,6 +75,14 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
75
75
|
*/
|
|
76
76
|
parameterSettings?: Partial<Record<keyof T, ParameterSetting>>;
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* A config level transformation that is only applied to the user supplied desired config. This transformation is allowed
|
|
80
|
+
* to add, remove or modify keys as well as values. Changing this transformation for existing libraries will mess up existing states.
|
|
81
|
+
*
|
|
82
|
+
* @param desired
|
|
83
|
+
*/
|
|
84
|
+
transformation?: InputTransformation;
|
|
85
|
+
|
|
78
86
|
/**
|
|
79
87
|
* Customize the import and destory behavior of the resource. By default, <code>codify import</code> and <code>codify destroy</code> will call
|
|
80
88
|
* `refresh()` with every parameter set to null and return the result of the refresh as the imported config. It looks for required parameters
|
|
@@ -181,7 +189,7 @@ export interface DefaultParameterSetting {
|
|
|
181
189
|
*
|
|
182
190
|
* @param input The original parameter value from the desired config.
|
|
183
191
|
*/
|
|
184
|
-
|
|
192
|
+
transformation?: InputTransformation;
|
|
185
193
|
|
|
186
194
|
/**
|
|
187
195
|
* Customize the equality comparison for a parameter. This is used in the diffing algorithm for generating the plan.
|
|
@@ -204,6 +212,16 @@ export interface DefaultParameterSetting {
|
|
|
204
212
|
* 2. AWS profile secret keys that can be updated without the re-installation of AWS CLI
|
|
205
213
|
*/
|
|
206
214
|
canModify?: boolean
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* This option allows the plan to skip this parameter entirely as it is used for setting purposes only. The value
|
|
218
|
+
* of this parameter is used to configure the resource or other parameters.
|
|
219
|
+
*
|
|
220
|
+
* Examples:
|
|
221
|
+
* 1. homebrew.onlyPlanUserInstalled option will tell homebrew to filter by --installed-on-request. But the value,
|
|
222
|
+
* of the parameter itself (true or false) does not have an impact on the plan
|
|
223
|
+
*/
|
|
224
|
+
setting?: boolean
|
|
207
225
|
}
|
|
208
226
|
|
|
209
227
|
/**
|
|
@@ -281,11 +299,15 @@ const ParameterEqualsDefaults: Partial<Record<ParameterSettingType, (a: unknown,
|
|
|
281
299
|
'number': (a: unknown, b: unknown) => Number(a) === Number(b),
|
|
282
300
|
'string': (a: unknown, b: unknown) => String(a) === String(b),
|
|
283
301
|
'version': (desired: unknown, current: unknown) => String(current).includes(String(desired)),
|
|
284
|
-
'setting': () => true,
|
|
285
302
|
'object': isObjectsEqual,
|
|
286
303
|
}
|
|
287
304
|
|
|
288
305
|
export function resolveEqualsFn(parameter: ParameterSetting): (desired: unknown, current: unknown) => boolean {
|
|
306
|
+
// Setting parameters do not impact the plan
|
|
307
|
+
if (parameter.setting) {
|
|
308
|
+
return () => true;
|
|
309
|
+
}
|
|
310
|
+
|
|
289
311
|
const isEqual = resolveFnFromEqualsFnOrString(parameter.isEqual);
|
|
290
312
|
|
|
291
313
|
if (parameter.type === 'array') {
|
|
@@ -346,10 +368,10 @@ export function resolveParameterTransformFn(
|
|
|
346
368
|
parameter: ParameterSetting
|
|
347
369
|
): InputTransformation | undefined {
|
|
348
370
|
|
|
349
|
-
if (parameter.type === 'stateful' && !parameter.
|
|
371
|
+
if (parameter.type === 'stateful' && !parameter.transformation) {
|
|
350
372
|
const sp = (parameter as StatefulParameterSetting).definition.getSettings();
|
|
351
|
-
if (sp.
|
|
352
|
-
return (parameter as StatefulParameterSetting).definition?.getSettings()?.
|
|
373
|
+
if (sp.transformation) {
|
|
374
|
+
return (parameter as StatefulParameterSetting).definition?.getSettings()?.transformation
|
|
353
375
|
}
|
|
354
376
|
|
|
355
377
|
return sp.type ? ParameterTransformationDefaults[sp.type] : undefined;
|
|
@@ -358,7 +380,7 @@ export function resolveParameterTransformFn(
|
|
|
358
380
|
if (parameter.type === 'array'
|
|
359
381
|
&& (parameter as ArrayParameterSetting).itemType
|
|
360
382
|
&& ParameterTransformationDefaults[(parameter as ArrayParameterSetting).itemType!]
|
|
361
|
-
&& !parameter.
|
|
383
|
+
&& !parameter.transformation
|
|
362
384
|
) {
|
|
363
385
|
const itemType = (parameter as ArrayParameterSetting).itemType!;
|
|
364
386
|
const itemTransformation = ParameterTransformationDefaults[itemType]!;
|
|
@@ -373,5 +395,5 @@ export function resolveParameterTransformFn(
|
|
|
373
395
|
}
|
|
374
396
|
}
|
|
375
397
|
|
|
376
|
-
return parameter.
|
|
398
|
+
return parameter.transformation ?? ParameterTransformationDefaults[parameter.type as ParameterSettingType] ?? undefined;
|
|
377
399
|
}
|