Skip to content

Commit 9bf8e80

Browse files
committed
feat: Changed parameter inputTransformations to have to: and from: so they can be mapped back
1 parent 28bd520 commit 9bf8e80

File tree

4 files changed

+70
-30
lines changed

4 files changed

+70
-30
lines changed

src/resource/parsed-resource-settings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
141141
return Object.fromEntries(
142142
Object.entries(this.settings.parameterSettings)
143143
.filter(([_, v]) => resolveParameterTransformFn(v!) !== undefined)
144-
.map(([k, v]) => [k, resolveParameterTransformFn(v!)] as const)
144+
.map(([k, v]) => [k, resolveParameterTransformFn(v!)!.to] as const)
145145
) as Record<keyof T, (a: unknown) => unknown>;
146146
});
147147
}

src/resource/resource-settings.test.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -852,16 +852,25 @@ describe('Resource parameter tests', () => {
852852
parameterSettings: {
853853
propD: {
854854
type: 'array',
855-
inputTransformation: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
855+
inputTransformation: {
856+
to: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
857+
Object.entries(h)
858+
.map(([k, v]) => [
859+
k,
860+
typeof v === 'boolean'
861+
? (v ? 'yes' : 'no') // The file takes 'yes' or 'no' instead of booleans
862+
: v,
863+
])
864+
)
865+
),
866+
from: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
856867
Object.entries(h)
857868
.map(([k, v]) => [
858869
k,
859-
typeof v === 'boolean'
860-
? (v ? 'yes' : 'no') // The file takes 'yes' or 'no' instead of booleans
861-
: v,
870+
v === 'yes',
862871
])
863-
)
864-
)
872+
))
873+
}
865874
}
866875
}
867876
}
@@ -909,16 +918,25 @@ describe('Resource parameter tests', () => {
909918
getSettings(): any {
910919
return {
911920
type: 'array',
912-
inputTransformation: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
921+
inputTransformation: {
922+
to: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
923+
Object.entries(h)
924+
.map(([k, v]) => [
925+
k,
926+
typeof v === 'boolean'
927+
? (v ? 'yes' : 'no') // The file takes 'yes' or 'no' instead of booleans
928+
: v,
929+
])
930+
)
931+
),
932+
from: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
913933
Object.entries(h)
914934
.map(([k, v]) => [
915935
k,
916-
typeof v === 'boolean'
917-
? (v ? 'yes' : 'no') // The file takes 'yes' or 'no' instead of booleans
918-
: v,
936+
v === 'yes',
919937
])
920-
)
921-
)
938+
))
939+
}
922940
}
923941
}
924942

src/resource/resource-settings.ts

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import isObjectsEqual from 'lodash.isequal'
33
import path from 'node:path';
44

55
import { ArrayStatefulParameter, StatefulParameter } from '../stateful-parameter/stateful-parameter.js';
6-
import { areArraysEqual, untildify } from '../utils/utils.js';
6+
import { areArraysEqual, tildify, untildify } from '../utils/utils.js';
7+
8+
export interface InputTransformation {
9+
to: (input: any) => Promise<any> | any;
10+
from: (current: any) => Promise<any> | any;
11+
}
712

813
/**
914
* The configuration and settings for a resource.
@@ -166,12 +171,13 @@ export interface DefaultParameterSetting {
166171
default?: unknown;
167172

168173
/**
169-
* A transformation of the input value for this parameter. This transformation is only applied to the desired parameter
170-
* value supplied by the user.
174+
* A transformation of the input value for this parameter. Two transformations need to be provided: to (from desired to
175+
* the internal type), and from (from the internal type back to desired). All transformations need to be bi-directional
176+
* to support imports properly
171177
*
172178
* @param input The original parameter value from the desired config.
173179
*/
174-
inputTransformation?: (input: any) => Promise<any> | any;
180+
inputTransformation?: InputTransformation;
175181

176182
/**
177183
* Customize the equality comparison for a parameter. This is used in the diffing algorithm for generating the plan.
@@ -321,22 +327,29 @@ export function resolveFnFromEqualsFnOrString(
321327
return fnOrString as ((a: unknown, b: unknown) => boolean) | undefined;
322328
}
323329

324-
const ParameterTransformationDefaults: Partial<Record<ParameterSettingType, (input: any, parameter: ParameterSetting) => Promise<any> | any>> = {
325-
'directory': (a: unknown) => path.resolve(untildify(String(a))),
326-
'stateful': (a: unknown, b: ParameterSetting) => {
327-
const sp = b as StatefulParameterSetting;
328-
return (sp.definition?.getSettings()?.inputTransformation)
329-
? (sp.definition.getSettings().inputTransformation!(a))
330-
: a;
330+
const ParameterTransformationDefaults: Partial<Record<ParameterSettingType, InputTransformation>> = {
331+
'directory': {
332+
to: (a: unknown) => path.resolve(untildify(String(a))),
333+
from: (a: unknown) => tildify(String(a)),
331334
},
332-
'string': String,
333-
// TODO: Add a array parameter itemType parameter
334-
// 'array': (arr: unknown[]) => arr.map((i) => (parameter as ArrayParameterSetting).itemType ? ParameterTransformationDefaults[])
335+
'string': {
336+
to: String,
337+
from: String,
338+
}
335339
}
336340

337341
export function resolveParameterTransformFn(
338342
parameter: ParameterSetting
339-
): ((input: any, parameter: ParameterSetting) => Promise<any> | any) | undefined {
343+
): InputTransformation | undefined {
344+
345+
if (parameter.type === 'stateful' && !parameter.inputTransformation) {
346+
const sp = (parameter as StatefulParameterSetting).definition.getSettings();
347+
if (sp.inputTransformation) {
348+
return (parameter as StatefulParameterSetting).definition?.getSettings()?.inputTransformation
349+
}
350+
351+
return sp.type ? ParameterTransformationDefaults[sp.type] : undefined;
352+
}
340353

341354
if (parameter.type === 'array'
342355
&& (parameter as ArrayParameterSetting).itemType
@@ -346,8 +359,13 @@ export function resolveParameterTransformFn(
346359
const itemType = (parameter as ArrayParameterSetting).itemType!;
347360
const itemTransformation = ParameterTransformationDefaults[itemType]!;
348361

349-
return (input: unknown[], parameter) => {
350-
return input.map((i) => itemTransformation(i, parameter))
362+
return {
363+
to(input: unknown[]) {
364+
return input.map((i) => itemTransformation.to(i))
365+
},
366+
from(input: unknown[]) {
367+
return input.map((i) => itemTransformation.from(i))
368+
}
351369
}
352370
}
353371

src/utils/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ export function untildify(pathWithTilde: string) {
3333
return homeDirectory ? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) : pathWithTilde;
3434
}
3535

36+
export function tildify(pathWithTilde: string) {
37+
return homeDirectory ? pathWithTilde.replace(homeDirectory, '~') : pathWithTilde;
38+
}
39+
3640
export function areArraysEqual(
3741
isElementEqual: ((desired: unknown, current: unknown) => boolean) | undefined,
3842
desired: unknown,

0 commit comments

Comments
 (0)