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.
@@ -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([...desiredMap.keys()]
146
- .filter((key) => this.defaultValues[key] === undefined));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.54",
3
+ "version": "1.0.55",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -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
  }
@@ -17,6 +17,8 @@ export interface ParameterOptions {
17
17
 
18
18
  isElementEqual?: (desired: any, current: any) => boolean;
19
19
 
20
+ default?: unknown,
21
+
20
22
  isStatefulParameter?: boolean;
21
23
  }
22
24
 
@@ -27,7 +27,7 @@ class TestParameter extends StatefulParameter<TestConfig, string> {
27
27
  }
28
28
  }
29
29
 
30
- describe('Resource parameters tests', () => {
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
- return {};
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() {
@@ -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
- [...desiredMap.keys()]
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