codify-plugin-lib 1.0.54 → 1.0.55
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/entities/change-set.d.ts +1 -0
- package/dist/entities/change-set.js +12 -0
- package/dist/entities/plan-types.d.ts +1 -0
- package/dist/entities/resource.d.ts +0 -1
- package/dist/entities/resource.js +2 -15
- package/package.json +1 -1
- package/src/entities/change-set.ts +15 -0
- package/src/entities/plan-types.ts +2 -0
- package/src/entities/resource-parameters.test.ts +1 -1
- package/src/entities/resource.test.ts +29 -3
- package/src/entities/resource.ts +2 -24
|
@@ -20,4 +20,5 @@ export declare class ChangeSet<T extends StringIndexedObject> {
|
|
|
20
20
|
static isSame(desired: unknown, current: unknown, options?: ParameterOptions): boolean;
|
|
21
21
|
private static calculateStatefulModeChangeSet;
|
|
22
22
|
private static calculateStatelessModeChangeSet;
|
|
23
|
+
private static addDefaultValues;
|
|
23
24
|
}
|
|
@@ -61,6 +61,7 @@ export class ChangeSet {
|
|
|
61
61
|
const parameterChangeSet = new Array();
|
|
62
62
|
const _desired = { ...desired };
|
|
63
63
|
const _current = { ...current };
|
|
64
|
+
this.addDefaultValues(_desired, parameterOptions);
|
|
64
65
|
for (const [k, v] of Object.entries(_current)) {
|
|
65
66
|
if (_desired[k] == null) {
|
|
66
67
|
parameterChangeSet.push({
|
|
@@ -109,6 +110,7 @@ export class ChangeSet {
|
|
|
109
110
|
const parameterChangeSet = new Array();
|
|
110
111
|
const _desired = { ...desired };
|
|
111
112
|
const _current = { ...current };
|
|
113
|
+
this.addDefaultValues(_desired, parameterOptions);
|
|
112
114
|
for (const [k, v] of Object.entries(_desired)) {
|
|
113
115
|
if (_current[k] == null) {
|
|
114
116
|
parameterChangeSet.push({
|
|
@@ -137,4 +139,14 @@ export class ChangeSet {
|
|
|
137
139
|
}
|
|
138
140
|
return parameterChangeSet;
|
|
139
141
|
}
|
|
142
|
+
static addDefaultValues(obj, options) {
|
|
143
|
+
Object.entries(options ?? {})
|
|
144
|
+
.filter(([, option]) => option.default !== undefined)
|
|
145
|
+
.map(([name, option]) => [name, option.default])
|
|
146
|
+
.forEach(([key, defaultValue]) => {
|
|
147
|
+
if (obj[key] === undefined) {
|
|
148
|
+
obj[key] = defaultValue;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
140
152
|
}
|
|
@@ -3,6 +3,7 @@ export interface ParameterOptions {
|
|
|
3
3
|
planOperation?: ResourceOperation.MODIFY | ResourceOperation.RECREATE;
|
|
4
4
|
isEqual?: (desired: any, current: any) => boolean;
|
|
5
5
|
isElementEqual?: (desired: any, current: any) => boolean;
|
|
6
|
+
default?: unknown;
|
|
6
7
|
isStatefulParameter?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export interface PlanOptions<T> {
|
|
@@ -29,7 +29,6 @@ export declare abstract class Resource<T extends StringIndexedObject> {
|
|
|
29
29
|
private _applyModify;
|
|
30
30
|
private _applyDestroy;
|
|
31
31
|
private validateRefreshResults;
|
|
32
|
-
private applyDefaultValueToRefreshResults;
|
|
33
32
|
private applyTransformParameters;
|
|
34
33
|
private addDefaultValues;
|
|
35
34
|
private refreshResourceParameters;
|
|
@@ -142,10 +142,8 @@ export class Resource {
|
|
|
142
142
|
if (!refresh) {
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
|
-
const desiredKeys = new Set(
|
|
146
|
-
|
|
147
|
-
const refreshKeys = new Set([...Object.keys(refresh)]
|
|
148
|
-
.filter((key) => this.defaultValues[key] === undefined));
|
|
145
|
+
const desiredKeys = new Set(desiredMap.keys());
|
|
146
|
+
const refreshKeys = new Set(Object.keys(refresh));
|
|
149
147
|
if (!setsEqual(desiredKeys, refreshKeys)) {
|
|
150
148
|
throw new Error(`Resource ${this.typeId}
|
|
151
149
|
refresh() must return back exactly the keys that were provided
|
|
@@ -153,16 +151,6 @@ Missing: ${[...desiredKeys].filter((k) => !refreshKeys.has(k))};
|
|
|
153
151
|
Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`);
|
|
154
152
|
}
|
|
155
153
|
}
|
|
156
|
-
applyDefaultValueToRefreshResults(refresh) {
|
|
157
|
-
if (!refresh) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
for (const [key, defaultValue] of Object.entries(this.defaultValues)) {
|
|
161
|
-
if (refresh[key] === undefined) {
|
|
162
|
-
refresh[key] = defaultValue;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
154
|
async applyTransformParameters(transformParameters, desired) {
|
|
167
155
|
const orderedEntries = [...Object.entries(transformParameters)]
|
|
168
156
|
.sort(([keyA], [keyB]) => this.transformParameterOrder.get(keyA) - this.transformParameterOrder.get(keyB));
|
|
@@ -191,7 +179,6 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`);
|
|
|
191
179
|
const entriesToRefresh = new Map(Object.entries(resourceParameters));
|
|
192
180
|
const currentParameters = await this.refresh(entriesToRefresh);
|
|
193
181
|
this.validateRefreshResults(currentParameters, entriesToRefresh);
|
|
194
|
-
this.applyDefaultValueToRefreshResults(currentParameters);
|
|
195
182
|
return currentParameters;
|
|
196
183
|
}
|
|
197
184
|
async refreshStatefulParameters(statefulParametersConfig, isStatefulMode) {
|
package/package.json
CHANGED
|
@@ -126,6 +126,8 @@ export class ChangeSet<T extends StringIndexedObject> {
|
|
|
126
126
|
const _desired = { ...desired };
|
|
127
127
|
const _current = { ...current };
|
|
128
128
|
|
|
129
|
+
this.addDefaultValues(_desired, parameterOptions);
|
|
130
|
+
|
|
129
131
|
for (const [k, v] of Object.entries(_current)) {
|
|
130
132
|
if (_desired[k] == null) {
|
|
131
133
|
parameterChangeSet.push({
|
|
@@ -191,6 +193,8 @@ export class ChangeSet<T extends StringIndexedObject> {
|
|
|
191
193
|
const _desired = { ...desired };
|
|
192
194
|
const _current = { ...current };
|
|
193
195
|
|
|
196
|
+
this.addDefaultValues(_desired, parameterOptions);
|
|
197
|
+
|
|
194
198
|
for (const [k, v] of Object.entries(_desired)) {
|
|
195
199
|
if (_current[k] == null) {
|
|
196
200
|
parameterChangeSet.push({
|
|
@@ -224,5 +228,16 @@ export class ChangeSet<T extends StringIndexedObject> {
|
|
|
224
228
|
|
|
225
229
|
return parameterChangeSet;
|
|
226
230
|
}
|
|
231
|
+
|
|
232
|
+
private static addDefaultValues<T extends StringIndexedObject>(obj: Record<string, unknown>, options?: Record<keyof T, ParameterOptions>) {
|
|
233
|
+
Object.entries(options ?? {})
|
|
234
|
+
.filter(([, option]) => option.default !== undefined)
|
|
235
|
+
.map(([name, option]) => [name, option.default] as const)
|
|
236
|
+
.forEach(([key, defaultValue]) => {
|
|
237
|
+
if (obj[key] === undefined) {
|
|
238
|
+
obj[key] = defaultValue;
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
}
|
|
227
242
|
|
|
228
243
|
}
|
|
@@ -27,7 +27,7 @@ class TestParameter extends StatefulParameter<TestConfig, string> {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
describe('Resource
|
|
30
|
+
describe('Resource parameter tests', () => {
|
|
31
31
|
it('supports the creation of stateful parameters', async () => {
|
|
32
32
|
|
|
33
33
|
const statefulParameter = new class extends TestParameter {
|
|
@@ -26,7 +26,7 @@ export class TestResource extends Resource<TestConfig> {
|
|
|
26
26
|
return Promise.resolve(undefined);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
29
|
+
async refresh(keys: Map<string, unknown>): Promise<Partial<TestConfig> | null> {
|
|
30
30
|
return {
|
|
31
31
|
propA: 'a',
|
|
32
32
|
propB: 10,
|
|
@@ -329,8 +329,12 @@ describe('Resource tests', () => {
|
|
|
329
329
|
});
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
-
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
333
|
-
|
|
332
|
+
async refresh(keys: Map<string, unknown>): Promise<Partial<TestConfig> | null> {
|
|
333
|
+
expect(keys.has('propE')).to.be.true;
|
|
334
|
+
|
|
335
|
+
return {
|
|
336
|
+
propE: keys.get('propE'),
|
|
337
|
+
};
|
|
334
338
|
}
|
|
335
339
|
}
|
|
336
340
|
|
|
@@ -340,6 +344,28 @@ describe('Resource tests', () => {
|
|
|
340
344
|
expect(plan.changeSet.operation).to.eq(ResourceOperation.NOOP);
|
|
341
345
|
})
|
|
342
346
|
|
|
347
|
+
it('Allows default values to be added even when refresh returns null', async () => {
|
|
348
|
+
const resource = new class extends TestResource {
|
|
349
|
+
constructor() {
|
|
350
|
+
super({
|
|
351
|
+
type: 'type',
|
|
352
|
+
parameterOptions: {
|
|
353
|
+
propE: { default: 'propEDefault' }
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const plan = await resource.plan({ type: 'resource'})
|
|
364
|
+
expect(plan.currentConfig.propE).to.eq(null);
|
|
365
|
+
expect(plan.desiredConfig.propE).to.eq('propEDefault');
|
|
366
|
+
expect(plan.changeSet.operation).to.eq(ResourceOperation.CREATE);
|
|
367
|
+
})
|
|
368
|
+
|
|
343
369
|
it('Allows default values to be added (ignore default value if already present)', async () => {
|
|
344
370
|
const resource = new class extends TestResource {
|
|
345
371
|
constructor() {
|
package/src/entities/resource.ts
CHANGED
|
@@ -211,15 +211,8 @@ export abstract class Resource<T extends StringIndexedObject> {
|
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
const desiredKeys = new Set<keyof T>(
|
|
215
|
-
|
|
216
|
-
.filter((key) => this.defaultValues[key] === undefined)
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
const refreshKeys = new Set(
|
|
220
|
-
[...Object.keys(refresh)]
|
|
221
|
-
.filter((key) => this.defaultValues[key] === undefined)
|
|
222
|
-
) as Set<keyof T>;
|
|
214
|
+
const desiredKeys = new Set<keyof T>(desiredMap.keys());
|
|
215
|
+
const refreshKeys = new Set(Object.keys(refresh)) as Set<keyof T>;
|
|
223
216
|
|
|
224
217
|
if (!setsEqual(desiredKeys, refreshKeys)) {
|
|
225
218
|
throw new Error(
|
|
@@ -231,19 +224,6 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`
|
|
|
231
224
|
}
|
|
232
225
|
}
|
|
233
226
|
|
|
234
|
-
private applyDefaultValueToRefreshResults(refresh: Partial<T> | null) {
|
|
235
|
-
if (!refresh) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
for (const [key, defaultValue] of Object.entries(this.defaultValues)) {
|
|
240
|
-
if (refresh[key] === undefined) {
|
|
241
|
-
// @ts-ignore
|
|
242
|
-
refresh[key] = defaultValue;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
227
|
private async applyTransformParameters(transformParameters: Partial<T>, desired: Partial<T>): Promise<void> {
|
|
248
228
|
const orderedEntries = [...Object.entries(transformParameters)]
|
|
249
229
|
.sort(([keyA], [keyB]) => this.transformParameterOrder.get(keyA)! - this.transformParameterOrder.get(keyB)!)
|
|
@@ -281,8 +261,6 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`
|
|
|
281
261
|
const currentParameters = await this.refresh(entriesToRefresh);
|
|
282
262
|
|
|
283
263
|
this.validateRefreshResults(currentParameters, entriesToRefresh);
|
|
284
|
-
this.applyDefaultValueToRefreshResults(currentParameters);
|
|
285
|
-
|
|
286
264
|
return currentParameters;
|
|
287
265
|
}
|
|
288
266
|
|