codify-plugin-lib 1.0.157 → 1.0.159
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/plan/plan.js +2 -2
- package/dist/resource/resource-controller.d.ts +1 -0
- package/dist/resource/resource-controller.js +26 -20
- package/dist/resource/resource-settings.d.ts +10 -1
- package/dist/resource/resource-settings.js +9 -4
- package/package.json +1 -1
- package/src/plan/plan.ts +2 -2
- package/src/resource/resource-controller.ts +37 -27
- package/src/resource/resource-settings.ts +21 -4
package/dist/plan/plan.js
CHANGED
|
@@ -189,8 +189,8 @@ export class Plan {
|
|
|
189
189
|
return null;
|
|
190
190
|
}
|
|
191
191
|
// For stateful mode, we're done after filtering by the keys of desired + state. Stateless mode
|
|
192
|
-
// requires additional filtering for stateful parameter arrays and objects.
|
|
193
|
-
if (isStateful
|
|
192
|
+
// requires additional filtering for stateful parameter arrays and objects.
|
|
193
|
+
if (isStateful) {
|
|
194
194
|
return filteredCurrent;
|
|
195
195
|
}
|
|
196
196
|
// TODO: Add object handling here in addition to arrays in the future
|
|
@@ -193,22 +193,7 @@ export class ResourceController {
|
|
|
193
193
|
this.addDefaultValues(parameters);
|
|
194
194
|
await this.applyTransformParameters(parameters);
|
|
195
195
|
// Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
|
|
196
|
-
const parametersToRefresh = this.
|
|
197
|
-
? {
|
|
198
|
-
...Object.fromEntries(this.settings.importAndDestroy?.refreshKeys.map((k) => [k, null])),
|
|
199
|
-
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
200
|
-
...parameters,
|
|
201
|
-
...(Object.fromEntries(// If a default value was used, but it was also declared in the defaultRefreshValues, prefer the defaultRefreshValue instead
|
|
202
|
-
Object.entries(parameters).filter(([k, v]) => this.parsedSettings.defaultValues[k] !== undefined
|
|
203
|
-
&& v === this.parsedSettings.defaultValues[k]
|
|
204
|
-
&& context.originalDesiredConfig?.[k] === undefined
|
|
205
|
-
&& this.settings.importAndDestroy?.defaultRefreshValues?.[k] !== undefined).map(([k]) => [k, this.settings.importAndDestroy.defaultRefreshValues[k]])))
|
|
206
|
-
}
|
|
207
|
-
: {
|
|
208
|
-
...Object.fromEntries(this.getAllParameterKeys().map((k) => [k, null])),
|
|
209
|
-
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
210
|
-
...parameters,
|
|
211
|
-
};
|
|
196
|
+
const parametersToRefresh = this.getParametersToRefreshForImport(parameters, context);
|
|
212
197
|
// Parse data from the user supplied config
|
|
213
198
|
const parsedConfig = new ConfigParser(parametersToRefresh, null, this.parsedSettings.statefulParameters);
|
|
214
199
|
const { allParameters, allNonStatefulParameters, allStatefulParameters, } = parsedConfig;
|
|
@@ -222,7 +207,7 @@ export class ResourceController {
|
|
|
222
207
|
const resultParametersArray = currentParametersArray
|
|
223
208
|
?.map((r, idx) => ({ ...r, ...statefulCurrentParameters[idx] }));
|
|
224
209
|
for (const result of resultParametersArray) {
|
|
225
|
-
await this.applyTransformParameters(result,
|
|
210
|
+
await this.applyTransformParameters(result, { original: parameters });
|
|
226
211
|
this.removeDefaultValues(result, parameters);
|
|
227
212
|
}
|
|
228
213
|
return resultParametersArray?.map((r) => ({ core, parameters: r }));
|
|
@@ -287,7 +272,7 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
287
272
|
`);
|
|
288
273
|
}
|
|
289
274
|
}
|
|
290
|
-
async applyTransformParameters(config, reverse
|
|
275
|
+
async applyTransformParameters(config, reverse) {
|
|
291
276
|
if (!config) {
|
|
292
277
|
return;
|
|
293
278
|
}
|
|
@@ -296,12 +281,12 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
296
281
|
continue;
|
|
297
282
|
}
|
|
298
283
|
config[key] = reverse
|
|
299
|
-
? await inputTransformation.from(config[key])
|
|
284
|
+
? await inputTransformation.from(config[key], reverse.original)
|
|
300
285
|
: await inputTransformation.to(config[key]);
|
|
301
286
|
}
|
|
302
287
|
if (this.settings.transformation) {
|
|
303
288
|
const transformed = reverse
|
|
304
|
-
? await this.settings.transformation.from({ ...config })
|
|
289
|
+
? await this.settings.transformation.from({ ...config }, reverse.original)
|
|
305
290
|
: await this.settings.transformation.to({ ...config });
|
|
306
291
|
Object.keys(config).forEach((k) => delete config[k]);
|
|
307
292
|
Object.assign(config, transformed);
|
|
@@ -373,4 +358,25 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
373
358
|
? Object.keys(this.settings.schema?.properties)
|
|
374
359
|
: Object.keys(this.parsedSettings.parameterSettings);
|
|
375
360
|
}
|
|
361
|
+
getParametersToRefreshForImport(parameters, context) {
|
|
362
|
+
if (this.settings.importAndDestroy?.refreshMapper) {
|
|
363
|
+
return this.settings.importAndDestroy?.refreshMapper(parameters, context);
|
|
364
|
+
}
|
|
365
|
+
return this.settings.importAndDestroy?.refreshKeys
|
|
366
|
+
? {
|
|
367
|
+
...Object.fromEntries(this.settings.importAndDestroy?.refreshKeys.map((k) => [k, null])),
|
|
368
|
+
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
369
|
+
...parameters,
|
|
370
|
+
...(Object.fromEntries(// If a default value was used, but it was also declared in the defaultRefreshValues, prefer the defaultRefreshValue instead
|
|
371
|
+
Object.entries(parameters).filter(([k, v]) => this.parsedSettings.defaultValues[k] !== undefined
|
|
372
|
+
&& v === this.parsedSettings.defaultValues[k]
|
|
373
|
+
&& context.originalDesiredConfig?.[k] === undefined
|
|
374
|
+
&& this.settings.importAndDestroy?.defaultRefreshValues?.[k] !== undefined).map(([k]) => [k, this.settings.importAndDestroy.defaultRefreshValues[k]])))
|
|
375
|
+
}
|
|
376
|
+
: {
|
|
377
|
+
...Object.fromEntries(this.getAllParameterKeys().map((k) => [k, null])),
|
|
378
|
+
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
379
|
+
...parameters,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
376
382
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { JSONSchemaType } from 'ajv';
|
|
2
2
|
import { StringIndexedObject } from 'codify-schemas';
|
|
3
3
|
import { ArrayStatefulParameter, StatefulParameter } from '../stateful-parameter/stateful-parameter.js';
|
|
4
|
+
import { RefreshContext } from './resource.js';
|
|
4
5
|
export interface InputTransformation {
|
|
5
6
|
to: (input: any) => Promise<any> | any;
|
|
6
|
-
from: (current: any) => Promise<any> | any;
|
|
7
|
+
from: (current: any, original: any) => Promise<any> | any;
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
9
10
|
* The configuration and settings for a resource.
|
|
@@ -122,6 +123,14 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
122
123
|
* See {@link importAndDestroy} for more information on how importing works.
|
|
123
124
|
*/
|
|
124
125
|
defaultRefreshValues?: Partial<T>;
|
|
126
|
+
/**
|
|
127
|
+
* A custom function that maps the input to what gets passed to refresh for imports. If this is set, then refreshKeys and
|
|
128
|
+
* defaultRefreshValues are ignored.
|
|
129
|
+
*
|
|
130
|
+
* @param input
|
|
131
|
+
* @param context
|
|
132
|
+
*/
|
|
133
|
+
refreshMapper?: (input: Partial<T>, context: RefreshContext<T>) => Partial<T>;
|
|
125
134
|
};
|
|
126
135
|
}
|
|
127
136
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import isObjectsEqual from 'lodash.isequal';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { addVariablesToPath, areArraysEqual, resolvePathWithVariables,
|
|
3
|
+
import { addVariablesToPath, areArraysEqual, resolvePathWithVariables, untildify } from '../utils/utils.js';
|
|
4
4
|
const ParameterEqualsDefaults = {
|
|
5
5
|
'boolean': (a, b) => Boolean(a) === Boolean(b),
|
|
6
6
|
'directory': (a, b) => {
|
|
@@ -54,7 +54,12 @@ export function resolveFnFromEqualsFnOrString(fnOrString) {
|
|
|
54
54
|
const ParameterTransformationDefaults = {
|
|
55
55
|
'directory': {
|
|
56
56
|
to: (a) => path.resolve(resolvePathWithVariables((untildify(String(a))))),
|
|
57
|
-
from: (a) =>
|
|
57
|
+
from: (a, original) => {
|
|
58
|
+
if (ParameterEqualsDefaults.directory(a, original)) {
|
|
59
|
+
return original;
|
|
60
|
+
}
|
|
61
|
+
return addVariablesToPath(String(a));
|
|
62
|
+
},
|
|
58
63
|
},
|
|
59
64
|
'string': {
|
|
60
65
|
to: String,
|
|
@@ -83,8 +88,8 @@ export function resolveParameterTransformFn(parameter) {
|
|
|
83
88
|
to(input) {
|
|
84
89
|
return input.map((i) => itemTransformation.to(i));
|
|
85
90
|
},
|
|
86
|
-
from(input) {
|
|
87
|
-
return input.map((i) => itemTransformation.from(i));
|
|
91
|
+
from(input, original) {
|
|
92
|
+
return input.map((i) => itemTransformation.from(i, original));
|
|
88
93
|
}
|
|
89
94
|
};
|
|
90
95
|
}
|
package/package.json
CHANGED
package/src/plan/plan.ts
CHANGED
|
@@ -312,8 +312,8 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
314
|
// For stateful mode, we're done after filtering by the keys of desired + state. Stateless mode
|
|
315
|
-
// requires additional filtering for stateful parameter arrays and objects.
|
|
316
|
-
if (isStateful
|
|
315
|
+
// requires additional filtering for stateful parameter arrays and objects.
|
|
316
|
+
if (isStateful) {
|
|
317
317
|
return filteredCurrent;
|
|
318
318
|
}
|
|
319
319
|
|
|
@@ -274,29 +274,7 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
274
274
|
await this.applyTransformParameters(parameters);
|
|
275
275
|
|
|
276
276
|
// Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
|
|
277
|
-
const parametersToRefresh = this.
|
|
278
|
-
? {
|
|
279
|
-
...Object.fromEntries(
|
|
280
|
-
this.settings.importAndDestroy?.refreshKeys.map((k) => [k, null])
|
|
281
|
-
),
|
|
282
|
-
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
283
|
-
...parameters,
|
|
284
|
-
...(Object.fromEntries( // If a default value was used, but it was also declared in the defaultRefreshValues, prefer the defaultRefreshValue instead
|
|
285
|
-
Object.entries(parameters).filter(([k, v]) =>
|
|
286
|
-
this.parsedSettings.defaultValues[k] !== undefined
|
|
287
|
-
&& v === this.parsedSettings.defaultValues[k]
|
|
288
|
-
&& context.originalDesiredConfig?.[k] === undefined
|
|
289
|
-
&& this.settings.importAndDestroy?.defaultRefreshValues?.[k] !== undefined
|
|
290
|
-
).map(([k]) => [k, this.settings.importAndDestroy!.defaultRefreshValues![k]])
|
|
291
|
-
))
|
|
292
|
-
}
|
|
293
|
-
: {
|
|
294
|
-
...Object.fromEntries(
|
|
295
|
-
this.getAllParameterKeys().map((k) => [k, null])
|
|
296
|
-
),
|
|
297
|
-
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
298
|
-
...parameters,
|
|
299
|
-
};
|
|
277
|
+
const parametersToRefresh = this.getParametersToRefreshForImport(parameters, context);
|
|
300
278
|
|
|
301
279
|
// Parse data from the user supplied config
|
|
302
280
|
const parsedConfig = new ConfigParser(parametersToRefresh, null, this.parsedSettings.statefulParameters)
|
|
@@ -320,11 +298,13 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
320
298
|
?.map((r, idx) => ({ ...r, ...statefulCurrentParameters[idx] }))
|
|
321
299
|
|
|
322
300
|
for (const result of resultParametersArray) {
|
|
323
|
-
await this.applyTransformParameters(result,
|
|
301
|
+
await this.applyTransformParameters(result, { original: parameters });
|
|
324
302
|
this.removeDefaultValues(result, parameters);
|
|
325
303
|
}
|
|
326
304
|
|
|
327
305
|
return resultParametersArray?.map((r) => ({ core, parameters: r }))
|
|
306
|
+
|
|
307
|
+
|
|
328
308
|
}
|
|
329
309
|
|
|
330
310
|
private async applyCreate(plan: Plan<T>): Promise<void> {
|
|
@@ -403,7 +383,7 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
403
383
|
}
|
|
404
384
|
}
|
|
405
385
|
|
|
406
|
-
private async applyTransformParameters(config: Partial<T> | null, reverse
|
|
386
|
+
private async applyTransformParameters(config: Partial<T> | null, reverse?: { original: Partial<T> }): Promise<void> {
|
|
407
387
|
if (!config) {
|
|
408
388
|
return;
|
|
409
389
|
}
|
|
@@ -414,13 +394,13 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
414
394
|
}
|
|
415
395
|
|
|
416
396
|
(config as Record<string, unknown>)[key] = reverse
|
|
417
|
-
? await inputTransformation.from(config[key])
|
|
397
|
+
? await inputTransformation.from(config[key], reverse.original)
|
|
418
398
|
: await inputTransformation.to(config[key]);
|
|
419
399
|
}
|
|
420
400
|
|
|
421
401
|
if (this.settings.transformation) {
|
|
422
402
|
const transformed = reverse
|
|
423
|
-
? await this.settings.transformation.from({ ...config })
|
|
403
|
+
? await this.settings.transformation.from({ ...config }, reverse.original)
|
|
424
404
|
: await this.settings.transformation.to({ ...config })
|
|
425
405
|
|
|
426
406
|
Object.keys(config).forEach((k) => delete config[k])
|
|
@@ -523,5 +503,35 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
523
503
|
? Object.keys((this.settings.schema as any)?.properties)
|
|
524
504
|
: Object.keys(this.parsedSettings.parameterSettings);
|
|
525
505
|
}
|
|
506
|
+
|
|
507
|
+
private getParametersToRefreshForImport(parameters: Partial<T>, context: RefreshContext<T>): Partial<T> {
|
|
508
|
+
if (this.settings.importAndDestroy?.refreshMapper) {
|
|
509
|
+
return this.settings.importAndDestroy?.refreshMapper(parameters, context);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
return this.settings.importAndDestroy?.refreshKeys
|
|
513
|
+
? {
|
|
514
|
+
...Object.fromEntries(
|
|
515
|
+
this.settings.importAndDestroy?.refreshKeys.map((k) => [k, null])
|
|
516
|
+
),
|
|
517
|
+
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
518
|
+
...parameters,
|
|
519
|
+
...(Object.fromEntries( // If a default value was used, but it was also declared in the defaultRefreshValues, prefer the defaultRefreshValue instead
|
|
520
|
+
Object.entries(parameters).filter(([k, v]) =>
|
|
521
|
+
this.parsedSettings.defaultValues[k] !== undefined
|
|
522
|
+
&& v === this.parsedSettings.defaultValues[k]
|
|
523
|
+
&& context.originalDesiredConfig?.[k] === undefined
|
|
524
|
+
&& this.settings.importAndDestroy?.defaultRefreshValues?.[k] !== undefined
|
|
525
|
+
).map(([k]) => [k, this.settings.importAndDestroy!.defaultRefreshValues![k]])
|
|
526
|
+
))
|
|
527
|
+
}
|
|
528
|
+
: {
|
|
529
|
+
...Object.fromEntries(
|
|
530
|
+
this.getAllParameterKeys().map((k) => [k, null])
|
|
531
|
+
),
|
|
532
|
+
...this.settings.importAndDestroy?.defaultRefreshValues,
|
|
533
|
+
...parameters,
|
|
534
|
+
};
|
|
535
|
+
}
|
|
526
536
|
}
|
|
527
537
|
|
|
@@ -5,10 +5,12 @@ import path from 'node:path';
|
|
|
5
5
|
|
|
6
6
|
import { ArrayStatefulParameter, StatefulParameter } from '../stateful-parameter/stateful-parameter.js';
|
|
7
7
|
import { addVariablesToPath, areArraysEqual, resolvePathWithVariables, tildify, untildify } from '../utils/utils.js';
|
|
8
|
+
import { or } from 'ajv/dist/compile/codegen/index.js';
|
|
9
|
+
import { RefreshContext } from './resource.js';
|
|
8
10
|
|
|
9
11
|
export interface InputTransformation {
|
|
10
12
|
to: (input: any) => Promise<any> | any;
|
|
11
|
-
from: (current: any) => Promise<any> | any;
|
|
13
|
+
from: (current: any, original: any) => Promise<any> | any;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -141,6 +143,15 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
141
143
|
* See {@link importAndDestroy} for more information on how importing works.
|
|
142
144
|
*/
|
|
143
145
|
defaultRefreshValues?: Partial<T>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* A custom function that maps the input to what gets passed to refresh for imports. If this is set, then refreshKeys and
|
|
149
|
+
* defaultRefreshValues are ignored.
|
|
150
|
+
*
|
|
151
|
+
* @param input
|
|
152
|
+
* @param context
|
|
153
|
+
*/
|
|
154
|
+
refreshMapper?: (input: Partial<T>, context: RefreshContext<T>) => Partial<T>
|
|
144
155
|
}
|
|
145
156
|
}
|
|
146
157
|
|
|
@@ -369,7 +380,13 @@ export function resolveFnFromEqualsFnOrString(
|
|
|
369
380
|
const ParameterTransformationDefaults: Partial<Record<ParameterSettingType, InputTransformation>> = {
|
|
370
381
|
'directory': {
|
|
371
382
|
to: (a: unknown) => path.resolve(resolvePathWithVariables((untildify(String(a))))),
|
|
372
|
-
from: (a: unknown) =>
|
|
383
|
+
from: (a: unknown, original) => {
|
|
384
|
+
if (ParameterEqualsDefaults.directory!(a, original)) {
|
|
385
|
+
return original;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return addVariablesToPath(String(a))
|
|
389
|
+
},
|
|
373
390
|
},
|
|
374
391
|
'string': {
|
|
375
392
|
to: String,
|
|
@@ -406,8 +423,8 @@ export function resolveParameterTransformFn(
|
|
|
406
423
|
to(input: unknown[]) {
|
|
407
424
|
return input.map((i) => itemTransformation.to(i))
|
|
408
425
|
},
|
|
409
|
-
from(input: unknown[]) {
|
|
410
|
-
return input.map((i) => itemTransformation.from(i))
|
|
426
|
+
from(input: unknown[], original) {
|
|
427
|
+
return input.map((i) => itemTransformation.from(i, original))
|
|
411
428
|
}
|
|
412
429
|
}
|
|
413
430
|
}
|