codify-plugin-lib 1.0.133 → 1.0.135
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 +3 -4
- package/dist/resource/parsed-resource-settings.js +1 -3
- package/dist/resource/resource-controller.js +7 -8
- package/dist/resource/resource-settings.d.ts +1 -8
- package/package.json +1 -1
- package/src/resource/parsed-resource-settings.ts +5 -6
- package/src/resource/resource-controller.test.ts +86 -3
- package/src/resource/resource-controller.ts +8 -9
- package/src/resource/resource-settings.test.ts +0 -68
- package/src/resource/resource-settings.ts +1 -9
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JSONSchemaType } from 'ajv';
|
|
2
2
|
import { StringIndexedObject } from 'codify-schemas';
|
|
3
3
|
import { StatefulParameterController } from '../stateful-parameter/stateful-parameter-controller.js';
|
|
4
|
-
import { ArrayParameterSetting, DefaultParameterSetting,
|
|
4
|
+
import { ArrayParameterSetting, DefaultParameterSetting, InputTransformation, ResourceSettings } from './resource-settings.js';
|
|
5
5
|
export interface ParsedStatefulParameterSetting extends DefaultParameterSetting {
|
|
6
6
|
type: 'stateful';
|
|
7
7
|
controller: StatefulParameterController<any, unknown>;
|
|
@@ -18,21 +18,20 @@ export type ParsedParameterSetting = {
|
|
|
18
18
|
export declare class ParsedResourceSettings<T extends StringIndexedObject> implements ResourceSettings<T> {
|
|
19
19
|
private cache;
|
|
20
20
|
id: string;
|
|
21
|
-
schema?: JSONSchemaType<T | any
|
|
21
|
+
schema?: Partial<JSONSchemaType<T | any>>;
|
|
22
22
|
allowMultiple?: {
|
|
23
23
|
matcher?: (desired: Partial<T>, current: Partial<T>[]) => Partial<T>;
|
|
24
24
|
requiredParameters?: string[];
|
|
25
25
|
} | boolean;
|
|
26
26
|
removeStatefulParametersBeforeDestroy?: boolean | undefined;
|
|
27
27
|
dependencies?: string[] | undefined;
|
|
28
|
-
inputTransformation?: ((desired: Partial<T>) => unknown) | undefined;
|
|
29
28
|
private settings;
|
|
30
29
|
constructor(settings: ResourceSettings<T>);
|
|
31
30
|
get typeId(): string;
|
|
32
31
|
get statefulParameters(): Map<keyof T, StatefulParameterController<T, T[keyof T]>>;
|
|
33
32
|
get parameterSettings(): Record<keyof T, ParsedParameterSetting>;
|
|
34
33
|
get defaultValues(): Partial<Record<keyof T, unknown>>;
|
|
35
|
-
get inputTransformations(): Partial<Record<keyof T,
|
|
34
|
+
get inputTransformations(): Partial<Record<keyof T, InputTransformation>>;
|
|
36
35
|
get statefulParameterOrder(): Map<keyof T, number>;
|
|
37
36
|
private validateSettings;
|
|
38
37
|
private validateParameterEqualsFn;
|
|
@@ -7,7 +7,6 @@ export class ParsedResourceSettings {
|
|
|
7
7
|
allowMultiple;
|
|
8
8
|
removeStatefulParametersBeforeDestroy;
|
|
9
9
|
dependencies;
|
|
10
|
-
inputTransformation;
|
|
11
10
|
settings;
|
|
12
11
|
constructor(settings) {
|
|
13
12
|
this.settings = settings;
|
|
@@ -16,7 +15,6 @@ export class ParsedResourceSettings {
|
|
|
16
15
|
this.allowMultiple = settings.allowMultiple;
|
|
17
16
|
this.removeStatefulParametersBeforeDestroy = settings.removeStatefulParametersBeforeDestroy;
|
|
18
17
|
this.dependencies = settings.dependencies;
|
|
19
|
-
this.inputTransformation = settings.inputTransformation;
|
|
20
18
|
this.validateSettings();
|
|
21
19
|
}
|
|
22
20
|
get typeId() {
|
|
@@ -83,7 +81,7 @@ export class ParsedResourceSettings {
|
|
|
83
81
|
}
|
|
84
82
|
return Object.fromEntries(Object.entries(this.settings.parameterSettings)
|
|
85
83
|
.filter(([_, v]) => resolveParameterTransformFn(v) !== undefined)
|
|
86
|
-
.map(([k, v]) => [k, resolveParameterTransformFn(v)
|
|
84
|
+
.map(([k, v]) => [k, resolveParameterTransformFn(v)]));
|
|
87
85
|
});
|
|
88
86
|
}
|
|
89
87
|
get statefulParameterOrder() {
|
|
@@ -174,7 +174,9 @@ export class ResourceController {
|
|
|
174
174
|
?? null;
|
|
175
175
|
}
|
|
176
176
|
const statefulCurrentParameters = await this.refreshStatefulParameters(allStatefulParameters, parametersToRefresh);
|
|
177
|
-
|
|
177
|
+
const resultParameters = { ...currentParametersArray[0], ...statefulCurrentParameters };
|
|
178
|
+
await this.applyTransformParameters(resultParameters, true);
|
|
179
|
+
return [{ core, parameters: resultParameters }];
|
|
178
180
|
}
|
|
179
181
|
async applyCreate(plan) {
|
|
180
182
|
await this.resource.create(plan);
|
|
@@ -236,7 +238,7 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
236
238
|
`);
|
|
237
239
|
}
|
|
238
240
|
}
|
|
239
|
-
async applyTransformParameters(config) {
|
|
241
|
+
async applyTransformParameters(config, reverse = false) {
|
|
240
242
|
if (!config) {
|
|
241
243
|
return;
|
|
242
244
|
}
|
|
@@ -244,12 +246,9 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
244
246
|
if (config[key] === undefined || !inputTransformation) {
|
|
245
247
|
continue;
|
|
246
248
|
}
|
|
247
|
-
config[key] =
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const transformed = await this.settings.inputTransformation({ ...config });
|
|
251
|
-
Object.keys(config).forEach((k) => delete config[k]);
|
|
252
|
-
Object.assign(config, transformed);
|
|
249
|
+
config[key] = reverse
|
|
250
|
+
? await inputTransformation.from(config[key])
|
|
251
|
+
: await inputTransformation.to(config[key]);
|
|
253
252
|
}
|
|
254
253
|
}
|
|
255
254
|
addDefaultValues(config) {
|
|
@@ -16,7 +16,7 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
16
16
|
/**
|
|
17
17
|
* Schema to validate user configs with. Must be in the format JSON Schema draft07
|
|
18
18
|
*/
|
|
19
|
-
schema?: JSONSchemaType<T | any
|
|
19
|
+
schema?: Partial<JSONSchemaType<T | any>>;
|
|
20
20
|
/**
|
|
21
21
|
* Allow multiple of the same resource to unique. Set truthy if
|
|
22
22
|
* multiples are allowed, for example for applications, there can be multiple copy of the same application installed
|
|
@@ -60,13 +60,6 @@ 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
|
-
inputTransformation?: (desired: Partial<T>) => Promise<unknown> | unknown;
|
|
70
63
|
/**
|
|
71
64
|
* Customize the import and destory behavior of the resource. By default, <code>codify import</code> and <code>codify destroy</code> will call
|
|
72
65
|
* `refresh()` with every parameter set to null and return the result of the refresh as the imported config. It looks for required parameters
|
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@ import { StatefulParameterController } from '../stateful-parameter/stateful-para
|
|
|
5
5
|
import {
|
|
6
6
|
ArrayParameterSetting,
|
|
7
7
|
DefaultParameterSetting,
|
|
8
|
+
InputTransformation,
|
|
8
9
|
ParameterSetting,
|
|
9
10
|
resolveElementEqualsFn,
|
|
10
11
|
resolveEqualsFn,
|
|
@@ -35,7 +36,7 @@ export type ParsedParameterSetting =
|
|
|
35
36
|
export class ParsedResourceSettings<T extends StringIndexedObject> implements ResourceSettings<T> {
|
|
36
37
|
private cache = new Map<string, unknown>();
|
|
37
38
|
id!: string;
|
|
38
|
-
schema?: JSONSchemaType<T | any
|
|
39
|
+
schema?: Partial<JSONSchemaType<T | any>>;
|
|
39
40
|
allowMultiple?: {
|
|
40
41
|
matcher?: (desired: Partial<T>, current: Partial<T>[]) => Partial<T>;
|
|
41
42
|
requiredParameters?: string[]
|
|
@@ -43,7 +44,6 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
|
|
|
43
44
|
|
|
44
45
|
removeStatefulParametersBeforeDestroy?: boolean | undefined;
|
|
45
46
|
dependencies?: string[] | undefined;
|
|
46
|
-
inputTransformation?: ((desired: Partial<T>) => unknown) | undefined;
|
|
47
47
|
private settings: ResourceSettings<T>;
|
|
48
48
|
|
|
49
49
|
constructor(settings: ResourceSettings<T>) {
|
|
@@ -53,7 +53,6 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
|
|
|
53
53
|
this.allowMultiple = settings.allowMultiple;
|
|
54
54
|
this.removeStatefulParametersBeforeDestroy = settings.removeStatefulParametersBeforeDestroy;
|
|
55
55
|
this.dependencies = settings.dependencies;
|
|
56
|
-
this.inputTransformation = settings.inputTransformation;
|
|
57
56
|
|
|
58
57
|
this.validateSettings();
|
|
59
58
|
}
|
|
@@ -136,7 +135,7 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
|
|
|
136
135
|
});
|
|
137
136
|
}
|
|
138
137
|
|
|
139
|
-
get inputTransformations(): Partial<Record<keyof T,
|
|
138
|
+
get inputTransformations(): Partial<Record<keyof T, InputTransformation>> {
|
|
140
139
|
return this.getFromCacheOrCreate('inputTransformations', () => {
|
|
141
140
|
if (!this.settings.parameterSettings) {
|
|
142
141
|
return {};
|
|
@@ -145,8 +144,8 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
|
|
|
145
144
|
return Object.fromEntries(
|
|
146
145
|
Object.entries(this.settings.parameterSettings)
|
|
147
146
|
.filter(([_, v]) => resolveParameterTransformFn(v!) !== undefined)
|
|
148
|
-
.map(([k, v]) => [k, resolveParameterTransformFn(v!)
|
|
149
|
-
) as Record<keyof T,
|
|
147
|
+
.map(([k, v]) => [k, resolveParameterTransformFn(v!)] as const)
|
|
148
|
+
) as Record<keyof T, InputTransformation>;
|
|
150
149
|
});
|
|
151
150
|
}
|
|
152
151
|
|
|
@@ -7,7 +7,7 @@ import { CreatePlan, DestroyPlan, ModifyPlan } from '../plan/plan-types.js';
|
|
|
7
7
|
import { ParameterChange } from '../plan/change-set.js';
|
|
8
8
|
import { ResourceController } from './resource-controller.js';
|
|
9
9
|
import { TestConfig, testPlan, TestResource, TestStatefulParameter } from '../utils/test-utils.test.js';
|
|
10
|
-
import { untildify } from '../utils/utils.js';
|
|
10
|
+
import { tildify, untildify } from '../utils/utils.js';
|
|
11
11
|
import { ArrayStatefulParameter, StatefulParameter } from '../stateful-parameter/stateful-parameter.js';
|
|
12
12
|
import { Plan } from '../plan/plan.js';
|
|
13
13
|
|
|
@@ -20,9 +20,8 @@ describe('Resource tests', () => {
|
|
|
20
20
|
id: 'type',
|
|
21
21
|
dependencies: ['homebrew', 'python'],
|
|
22
22
|
parameterSettings: {
|
|
23
|
-
propA: { canModify: true, inputTransformation: (input) => untildify(input) },
|
|
23
|
+
propA: { canModify: true, inputTransformation: { to: (input) => untildify(input), from: (input) => tildify(input) } },
|
|
24
24
|
},
|
|
25
|
-
inputTransformation: (config) => ({ propA: config.propA, propC: config.propB }),
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
|
|
@@ -535,4 +534,88 @@ describe('Resource tests', () => {
|
|
|
535
534
|
expect(parameter1.modify.calledOnce).to.be.true;
|
|
536
535
|
expect(parameter2.addItem.calledOnce).to.be.true;
|
|
537
536
|
});
|
|
537
|
+
|
|
538
|
+
it('Applies reverse input transformations for imports', async () => {
|
|
539
|
+
const resource = new class extends TestResource {
|
|
540
|
+
getSettings(): ResourceSettings<TestConfig> {
|
|
541
|
+
return {
|
|
542
|
+
id: 'resourceType',
|
|
543
|
+
parameterSettings: {
|
|
544
|
+
propD: {
|
|
545
|
+
type: 'array',
|
|
546
|
+
inputTransformation: {
|
|
547
|
+
to: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
|
|
548
|
+
Object.entries(h)
|
|
549
|
+
.map(([k, v]) => [
|
|
550
|
+
k,
|
|
551
|
+
typeof v === 'boolean'
|
|
552
|
+
? (v ? 'yes' : 'no') // The file takes 'yes' or 'no' instead of booleans
|
|
553
|
+
: v,
|
|
554
|
+
])
|
|
555
|
+
)
|
|
556
|
+
),
|
|
557
|
+
from: (hosts: Record<string, unknown>[]) => hosts.map((h) => Object.fromEntries(
|
|
558
|
+
Object.entries(h)
|
|
559
|
+
.map(([k, v]) => [
|
|
560
|
+
k,
|
|
561
|
+
v === 'yes' || v === 'no'
|
|
562
|
+
? (v === 'yes')
|
|
563
|
+
: v,
|
|
564
|
+
])
|
|
565
|
+
))
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
async refresh(parameters: Partial<TestConfig>): Promise<Partial<TestConfig> | null> {
|
|
573
|
+
return {
|
|
574
|
+
propD: [
|
|
575
|
+
{
|
|
576
|
+
Host: 'new.com',
|
|
577
|
+
AddKeysToAgent: true,
|
|
578
|
+
IdentityFile: 'id_ed25519'
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
Host: 'github.com',
|
|
582
|
+
AddKeysToAgent: true,
|
|
583
|
+
UseKeychain: true,
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
Match: 'User bob,joe,phil',
|
|
587
|
+
PasswordAuthentication: true,
|
|
588
|
+
}
|
|
589
|
+
],
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
const controller = new ResourceController(resource);
|
|
595
|
+
const plan = await controller.import({ type: 'resourceType' }, {});
|
|
596
|
+
|
|
597
|
+
expect(plan![0]).toMatchObject({
|
|
598
|
+
'core': {
|
|
599
|
+
'type': 'resourceType'
|
|
600
|
+
},
|
|
601
|
+
'parameters': {
|
|
602
|
+
'propD': [
|
|
603
|
+
{
|
|
604
|
+
'Host': 'new.com',
|
|
605
|
+
'AddKeysToAgent': true,
|
|
606
|
+
'IdentityFile': 'id_ed25519'
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
'Host': 'github.com',
|
|
610
|
+
'AddKeysToAgent': true,
|
|
611
|
+
'UseKeychain': true
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
'Match': 'User bob,joe,phil',
|
|
615
|
+
'PasswordAuthentication': true
|
|
616
|
+
}
|
|
617
|
+
]
|
|
618
|
+
}
|
|
619
|
+
})
|
|
620
|
+
})
|
|
538
621
|
});
|
|
@@ -254,7 +254,10 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
const statefulCurrentParameters = await this.refreshStatefulParameters(allStatefulParameters, parametersToRefresh);
|
|
257
|
-
|
|
257
|
+
const resultParameters = { ...currentParametersArray[0], ...statefulCurrentParameters };
|
|
258
|
+
|
|
259
|
+
await this.applyTransformParameters(resultParameters, true);
|
|
260
|
+
return [{ core, parameters: resultParameters }];
|
|
258
261
|
}
|
|
259
262
|
|
|
260
263
|
private async applyCreate(plan: Plan<T>): Promise<void> {
|
|
@@ -333,7 +336,7 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
333
336
|
}
|
|
334
337
|
}
|
|
335
338
|
|
|
336
|
-
private async applyTransformParameters(config: Partial<T> | null): Promise<void> {
|
|
339
|
+
private async applyTransformParameters(config: Partial<T> | null, reverse = false): Promise<void> {
|
|
337
340
|
if (!config) {
|
|
338
341
|
return;
|
|
339
342
|
}
|
|
@@ -343,13 +346,9 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
343
346
|
continue;
|
|
344
347
|
}
|
|
345
348
|
|
|
346
|
-
(config as Record<string, unknown>)[key] =
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
if (this.settings.inputTransformation) {
|
|
350
|
-
const transformed = await this.settings.inputTransformation({ ...config })
|
|
351
|
-
Object.keys(config).forEach((k) => delete config[k])
|
|
352
|
-
Object.assign(config, transformed);
|
|
349
|
+
(config as Record<string, unknown>)[key] = reverse
|
|
350
|
+
? await inputTransformation.from(config[key])
|
|
351
|
+
: await inputTransformation.to(config[key]);
|
|
353
352
|
}
|
|
354
353
|
}
|
|
355
354
|
|
|
@@ -564,74 +564,6 @@ 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
|
-
inputTransformation: (desired) => ({
|
|
573
|
-
propA: 'propA',
|
|
574
|
-
propB: 10,
|
|
575
|
-
})
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
580
|
-
return {
|
|
581
|
-
propA: 'propA',
|
|
582
|
-
propB: 10,
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
const controller = new ResourceController(resource);
|
|
588
|
-
const plan = await controller.plan({ type: 'resourceType' }, { propC: 'abc' } as any, null, false);
|
|
589
|
-
|
|
590
|
-
expect(resource.refresh.called).to.be.true;
|
|
591
|
-
expect(resource.refresh.getCall(0).firstArg['propA']).to.exist;
|
|
592
|
-
expect(resource.refresh.getCall(0).firstArg['propB']).to.exist;
|
|
593
|
-
expect(resource.refresh.getCall(0).firstArg['propC']).to.not.exist;
|
|
594
|
-
|
|
595
|
-
expect(plan.desiredConfig?.propA).to.eq('propA');
|
|
596
|
-
expect(plan.desiredConfig?.propB).to.eq(10);
|
|
597
|
-
expect(plan.desiredConfig?.propC).to.be.undefined;
|
|
598
|
-
|
|
599
|
-
expect(plan.changeSet.operation).to.eq(ResourceOperation.NOOP);
|
|
600
|
-
})
|
|
601
|
-
|
|
602
|
-
it('Supports transform parameters for state parameters', async () => {
|
|
603
|
-
const resource = spy(new class extends TestResource {
|
|
604
|
-
getSettings(): ResourceSettings<TestConfig> {
|
|
605
|
-
return {
|
|
606
|
-
id: 'resourceType',
|
|
607
|
-
inputTransformation: (desired) => ({
|
|
608
|
-
propA: 'propA',
|
|
609
|
-
propB: 10,
|
|
610
|
-
})
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
615
|
-
return {
|
|
616
|
-
propA: 'propA',
|
|
617
|
-
propB: 10,
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
const controller = new ResourceController(resource);
|
|
623
|
-
const plan = await controller.plan({ type: 'resourceType' }, null, { propC: 'abc' }, true);
|
|
624
|
-
|
|
625
|
-
expect(resource.refresh.called).to.be.true;
|
|
626
|
-
expect(resource.refresh.getCall(0).firstArg['propA']).to.exist;
|
|
627
|
-
expect(resource.refresh.getCall(0).firstArg['propB']).to.exist;
|
|
628
|
-
expect(resource.refresh.getCall(0).firstArg['propC']).to.not.exist;
|
|
629
|
-
|
|
630
|
-
expect(plan.currentConfig?.propA).to.eq('propA');
|
|
631
|
-
expect(plan.currentConfig?.propB).to.eq(10);
|
|
632
|
-
expect(plan.currentConfig?.propC).to.be.undefined;
|
|
633
|
-
})
|
|
634
|
-
|
|
635
567
|
it('Allows import required parameters customization', () => {
|
|
636
568
|
const resource = new class extends TestResource {
|
|
637
569
|
getSettings(): ResourceSettings<TestConfig> {
|
|
@@ -24,7 +24,7 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
24
24
|
/**
|
|
25
25
|
* Schema to validate user configs with. Must be in the format JSON Schema draft07
|
|
26
26
|
*/
|
|
27
|
-
schema?: JSONSchemaType<T | any
|
|
27
|
+
schema?: Partial<JSONSchemaType<T | any>>;
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Allow multiple of the same resource to unique. Set truthy if
|
|
@@ -75,14 +75,6 @@ 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
|
-
inputTransformation?: (desired: Partial<T>) => Promise<unknown> | unknown;
|
|
85
|
-
|
|
86
78
|
/**
|
|
87
79
|
* Customize the import and destory behavior of the resource. By default, <code>codify import</code> and <code>codify destroy</code> will call
|
|
88
80
|
* `refresh()` with every parameter set to null and return the result of the refresh as the imported config. It looks for required parameters
|