@@ -67,9 +67,9 @@ export interface ResourceSettings<T extends StringIndexedObject> {
6767 inputTransformation ?: ( desired : Partial < T > ) => Promise < unknown > | unknown ;
6868
6969 /**
70- * Customize the import behavior of the resource. By default, <code>codify import</code> will call `refresh()` with
71- * every parameter set to null and return the result of the refresh as the imported config. It looks for required parameters
72- * in the schema and will prompt the user for these values before performing the import.
70+ * Customize the import and destory behavior of the resource. By default, <code>codify import</code> and <code>codify destroy</code> will call
71+ * `refresh()` with every parameter set to null and return the result of the refresh as the imported config. It looks for required parameters
72+ * in the schema and will prompt the user for these values before performing the import or destroy .
7373 *
7474 * <b>Example:</b><br>
7575 * Resource `alias` with parameters
@@ -85,7 +85,7 @@ export interface ResourceSettings<T extends StringIndexedObject> {
8585 * { type: 'alias', alias: 'user-input', value: 'git push' }
8686 * ```
8787 */
88- import ?: {
88+ importAndDestroy ?: {
8989
9090 /**
9191 * Customize the required parameters needed to import this resource. By default, the `requiredParameters` are taken
@@ -96,7 +96,7 @@ export interface ResourceSettings<T extends StringIndexedObject> {
9696 * the required parameters change the behaviour of the refresh (for example for the `alias` resource, the `alias` parmaeter
9797 * chooses which alias the resource is managing).
9898 *
99- * See {@link import } for more information on how importing works.
99+ * See {@link importAndDestroy } for more information on how importing works.
100100 */
101101 requiredParameters ?: Array < Partial < keyof T > > ;
102102
@@ -107,14 +107,14 @@ export interface ResourceSettings<T extends StringIndexedObject> {
107107 * By default all parameters (except for {@link requiredParameters }) are passed in with the value `null`. The passed
108108 * in value can be customized using {@link defaultRefreshValues}
109109 *
110- * See {@link import } for more information on how importing works.
110+ * See {@link importAndDestroy } for more information on how importing works.
111111 */
112112 refreshKeys ?: Array < Partial < keyof T > > ;
113113
114114 /**
115115 * Customize the value that is passed into refresh when importing. This must only contain keys found in {@link refreshKeys}.
116116 *
117- * See {@link import } for more information on how importing works.
117+ * See {@link importAndDestroy } for more information on how importing works.
118118 */
119119 defaultRefreshValues ?: Partial < T >
120120 }
@@ -233,6 +233,12 @@ export interface ArrayParameterSetting extends DefaultParameterSetting {
233233 * Defaults to true.
234234 */
235235 filterInStatelessMode ?: ( ( desired : any [ ] , current : any [ ] ) => any [ ] ) | boolean ,
236+
237+ /**
238+ * The type of the array item. See {@link ParameterSettingType} for the available options. This value
239+ * is mainly used to determine the equality method when performing diffing.
240+ */
241+ itemType ?: ParameterSettingType ,
236242}
237243
238244/**
@@ -273,10 +279,7 @@ export function resolveEqualsFn(parameter: ParameterSetting): (desired: unknown,
273279 const isEqual = resolveFnFromEqualsFnOrString ( parameter . isEqual ) ;
274280
275281 if ( parameter . type === 'array' ) {
276- const arrayParameter = parameter as ArrayParameterSetting ;
277- const isElementEqual = resolveFnFromEqualsFnOrString ( arrayParameter . isElementEqual ) ;
278-
279- return isEqual ?? areArraysEqual . bind ( areArraysEqual , isElementEqual )
282+ return isEqual ?? areArraysEqual . bind ( areArraysEqual , resolveElementEqualsFn ( parameter as ArrayParameterSetting ) )
280283 }
281284
282285 if ( parameter . type === 'stateful' ) {
@@ -286,6 +289,21 @@ export function resolveEqualsFn(parameter: ParameterSetting): (desired: unknown,
286289 return isEqual ?? ParameterEqualsDefaults [ parameter . type as ParameterSettingType ] ?? ( ( ( a , b ) => a === b ) ) ;
287290}
288291
292+ export function resolveElementEqualsFn ( parameter : ArrayParameterSetting ) : ( desired : unknown , current : unknown ) => boolean {
293+ if ( parameter . isElementEqual ) {
294+ const elementEq = resolveFnFromEqualsFnOrString ( parameter . isElementEqual ) ;
295+ if ( elementEq ) {
296+ return elementEq ;
297+ }
298+ }
299+
300+ if ( parameter . itemType && ParameterEqualsDefaults [ parameter . itemType ] ) {
301+ return ParameterEqualsDefaults [ parameter . itemType ] !
302+ }
303+
304+ return ( a , b ) => a === b ;
305+ }
306+
289307// This resolves the fn if it is a string.
290308// A string can be specified to use a default equals method
291309export function resolveFnFromEqualsFnOrString (
@@ -312,10 +330,26 @@ const ParameterTransformationDefaults: Partial<Record<ParameterSettingType, (inp
312330 : a ;
313331 } ,
314332 'string' : String ,
333+ // TODO: Add a array parameter itemType parameter
334+ // 'array': (arr: unknown[]) => arr.map((i) => (parameter as ArrayParameterSetting).itemType ? ParameterTransformationDefaults[])
315335}
316336
317337export function resolveParameterTransformFn (
318338 parameter : ParameterSetting
319339) : ( ( input : any , parameter : ParameterSetting ) => Promise < any > | any ) | undefined {
340+
341+ if ( parameter . type === 'array'
342+ && ( parameter as ArrayParameterSetting ) . itemType
343+ && ParameterTransformationDefaults [ ( parameter as ArrayParameterSetting ) . itemType ! ]
344+ && ! parameter . inputTransformation
345+ ) {
346+ const itemType = ( parameter as ArrayParameterSetting ) . itemType ! ;
347+ const itemTransformation = ParameterTransformationDefaults [ itemType ] ! ;
348+
349+ return ( input : unknown [ ] , parameter ) => {
350+ return input . map ( ( i ) => itemTransformation ( i , parameter ) )
351+ }
352+ }
353+
320354 return parameter . inputTransformation ?? ParameterTransformationDefaults [ parameter . type as ParameterSettingType ] ?? undefined ;
321355}
0 commit comments