codify-plugin-lib 1.0.70 → 1.0.71

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.
@@ -1,13 +1,13 @@
1
+ import Ajv from 'ajv';
2
+ import { ValidateFunction } from 'ajv/dist/2020.js';
1
3
  import { ResourceConfig, StringIndexedObject } from 'codify-schemas';
2
4
  import { ParameterChange } from './change-set.js';
3
5
  import { Plan } from './plan.js';
4
- import { StatefulParameter } from './stateful-parameter.js';
5
- import { ResourceParameterOptions, ValidationResult } from './resource-types.js';
6
6
  import { CreatePlan, DestroyPlan, ModifyPlan, ParameterOptions } from './plan-types.js';
7
- import { TransformParameter } from './transform-parameter.js';
8
7
  import { ResourceOptions } from './resource-options.js';
9
- import Ajv from 'ajv';
10
- import { ValidateFunction } from 'ajv/dist/2020.js';
8
+ import { ResourceParameterOptions, ValidationResult } from './resource-types.js';
9
+ import { StatefulParameter } from './stateful-parameter.js';
10
+ import { TransformParameter } from './transform-parameter.js';
11
11
  export declare abstract class Resource<T extends StringIndexedObject> {
12
12
  readonly typeId: string;
13
13
  readonly statefulParameters: Map<keyof T, StatefulParameter<T, T[keyof T]>>;
@@ -36,7 +36,7 @@ export declare abstract class Resource<T extends StringIndexedObject> {
36
36
  private refreshStatefulParameters;
37
37
  private validatePlanInputs;
38
38
  validate(parameters: Partial<T>): Promise<ValidationResult>;
39
- abstract refresh(values: Partial<T>): Promise<Partial<T> | null>;
39
+ abstract refresh(parameters: Partial<T>): Promise<Partial<T> | null>;
40
40
  abstract applyCreate(plan: CreatePlan<T>): Promise<void>;
41
41
  applyModify(pc: ParameterChange<T>, plan: ModifyPlan<T>): Promise<void>;
42
42
  abstract applyDestroy(plan: DestroyPlan<T>): Promise<void>;
@@ -1,8 +1,8 @@
1
+ import Ajv2020 from 'ajv/dist/2020.js';
1
2
  import { ParameterOperation, ResourceOperation, } from 'codify-schemas';
2
- import { Plan } from './plan.js';
3
3
  import { setsEqual, splitUserConfig } from '../utils/utils.js';
4
+ import { Plan } from './plan.js';
4
5
  import { ResourceOptionsParser } from './resource-options.js';
5
- import Ajv2020 from 'ajv/dist/2020.js';
6
6
  export class Resource {
7
7
  typeId;
8
8
  statefulParameters;
@@ -42,8 +42,8 @@ export class Resource {
42
42
  const isValid = this.schemaValidator(parameters);
43
43
  if (!isValid) {
44
44
  return {
45
- isValid: false,
46
45
  errors: this.schemaValidator?.errors ?? [],
46
+ isValid: false,
47
47
  };
48
48
  }
49
49
  }
@@ -52,13 +52,13 @@ export class Resource {
52
52
  async plan(desiredConfig, currentConfig = null, statefulMode = false) {
53
53
  this.validatePlanInputs(desiredConfig, currentConfig, statefulMode);
54
54
  const planOptions = {
55
- statefulMode,
56
55
  parameterOptions: this.parameterOptions,
56
+ statefulMode,
57
57
  };
58
58
  this.addDefaultValues(desiredConfig);
59
59
  await this.applyTransformParameters(desiredConfig);
60
60
  const parsedConfig = new ConfigParser(desiredConfig, currentConfig, this.statefulParameters, this.transformParameters);
61
- const { desiredParameters, resourceMetadata, nonStatefulParameters, statefulParameters, } = parsedConfig;
61
+ const { desiredParameters, nonStatefulParameters, resourceMetadata, statefulParameters, } = parsedConfig;
62
62
  const currentParameters = await this.refreshNonStatefulParameters(nonStatefulParameters);
63
63
  if (currentParameters == null) {
64
64
  return Plan.create(desiredParameters, null, resourceMetadata, planOptions);
@@ -167,21 +167,20 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`);
167
167
  throw new Error(`Transform parameter ${key} is attempting to override existing values ${JSON.stringify(transformedValue, null, 2)}`);
168
168
  }
169
169
  delete desired[key];
170
- Object.entries(transformedValue).forEach(([tvKey, tvValue]) => {
170
+ for (const [tvKey, tvValue] of Object.entries(transformedValue)) {
171
171
  desired[tvKey] = tvValue;
172
- });
172
+ }
173
173
  }
174
174
  }
175
175
  addDefaultValues(desired) {
176
176
  if (!desired) {
177
177
  return;
178
178
  }
179
- Object.entries(this.defaultValues)
180
- .forEach(([key, defaultValue]) => {
179
+ for (const [key, defaultValue] of Object.entries(this.defaultValues)) {
181
180
  if (defaultValue !== undefined && desired[key] === undefined) {
182
181
  desired[key] = defaultValue;
183
182
  }
184
- });
183
+ }
185
184
  }
186
185
  async refreshNonStatefulParameters(resourceParameters) {
187
186
  const currentParameters = await this.refresh(resourceParameters);
@@ -269,18 +268,14 @@ ${JSON.stringify(currentMetadata, null, 2)}`);
269
268
  get parameters() {
270
269
  const desiredParameters = this.desiredConfig ? splitUserConfig(this.desiredConfig).parameters : undefined;
271
270
  const currentParameters = this.currentConfig ? splitUserConfig(this.currentConfig).parameters : undefined;
272
- return { ...(desiredParameters ?? {}), ...(currentParameters ?? {}) };
271
+ return { ...desiredParameters, ...currentParameters };
273
272
  }
274
273
  get nonStatefulParameters() {
275
- const parameters = this.parameters;
276
- return Object.fromEntries([
277
- ...Object.entries(parameters).filter(([key]) => !(this.statefulParametersMap.has(key) || this.transformParametersMap.has(key))),
278
- ]);
274
+ const { parameters } = this;
275
+ return Object.fromEntries(Object.entries(parameters).filter(([key]) => !(this.statefulParametersMap.has(key) || this.transformParametersMap.has(key))));
279
276
  }
280
277
  get statefulParameters() {
281
- const parameters = this.parameters;
282
- return Object.fromEntries([
283
- ...Object.entries(parameters).filter(([key]) => this.statefulParametersMap.has(key)),
284
- ]);
278
+ const { parameters } = this;
279
+ return Object.fromEntries(Object.entries(parameters).filter(([key]) => this.statefulParametersMap.has(key)));
285
280
  }
286
281
  }
@@ -39,8 +39,8 @@ export function isDebug() {
39
39
  export function splitUserConfig(config) {
40
40
  const resourceMetadata = {
41
41
  type: config.type,
42
- ...(config.name && { name: config.name }),
43
- ...(config.dependsOn && { dependsOn: config.dependsOn }),
42
+ ...(config.name ? { name: config.name } : {}),
43
+ ...(config.dependsOn ? { dependsOn: config.dependsOn } : {}),
44
44
  };
45
45
  const { type, name, dependsOn, ...parameters } = config;
46
46
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.70",
3
+ "version": "1.0.71",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -14,7 +14,7 @@
14
14
  "dependencies": {
15
15
  "ajv": "^8.12.0",
16
16
  "ajv-formats": "^2.1.1",
17
- "codify-schemas": "1.0.38",
17
+ "codify-schemas": "1.0.39",
18
18
  "@npmcli/promise-spawn": "^7.0.1"
19
19
  },
20
20
  "devDependencies": {
@@ -121,6 +121,28 @@ describe('Plan entity tests', () => {
121
121
  .every((pc) => pc.operation === ParameterOperation.ADD)
122
122
  ).to.be.true;
123
123
  })
124
+
125
+ it('Returns the original resource names', () => {
126
+ const resource = createResource();
127
+
128
+ const plan = Plan.create(
129
+ {
130
+ propA: 'propA',
131
+ },
132
+ {
133
+ propA: 'propA2',
134
+ },
135
+ {
136
+ type: 'type',
137
+ name: 'name1'
138
+ }, { statefulMode: false });
139
+
140
+ expect(plan.toResponse()).toMatchObject({
141
+ resourceType: 'type',
142
+ resourceName: 'name1',
143
+ operation: ResourceOperation.RECREATE
144
+ })
145
+ })
124
146
  })
125
147
 
126
148
  function createResource(): Resource<any> {
@@ -1,14 +1,15 @@
1
+ import Ajv from 'ajv';
2
+ import Ajv2020, { ValidateFunction } from 'ajv/dist/2020.js';
1
3
  import { ParameterOperation, ResourceConfig, ResourceOperation, StringIndexedObject, } from 'codify-schemas';
4
+
5
+ import { setsEqual, splitUserConfig } from '../utils/utils.js';
2
6
  import { ParameterChange } from './change-set.js';
3
7
  import { Plan } from './plan.js';
4
- import { StatefulParameter } from './stateful-parameter.js';
5
- import { ResourceParameterOptions, ValidationResult } from './resource-types.js';
6
- import { setsEqual, splitUserConfig } from '../utils/utils.js';
7
8
  import { CreatePlan, DestroyPlan, ModifyPlan, ParameterOptions, PlanOptions } from './plan-types.js';
8
- import { TransformParameter } from './transform-parameter.js';
9
9
  import { ResourceOptions, ResourceOptionsParser } from './resource-options.js';
10
- import Ajv from 'ajv';
11
- import Ajv2020, { ValidateFunction } from 'ajv/dist/2020.js';
10
+ import { ResourceParameterOptions, ValidationResult } from './resource-types.js';
11
+ import { StatefulParameter } from './stateful-parameter.js';
12
+ import { TransformParameter } from './transform-parameter.js';
12
13
 
13
14
  /**
14
15
  * Description of resource here
@@ -65,8 +66,8 @@ export abstract class Resource<T extends StringIndexedObject> {
65
66
 
66
67
  if (!isValid) {
67
68
  return {
68
- isValid: false,
69
69
  errors: this.schemaValidator?.errors ?? [],
70
+ isValid: false,
70
71
  }
71
72
  }
72
73
  }
@@ -84,8 +85,8 @@ export abstract class Resource<T extends StringIndexedObject> {
84
85
  this.validatePlanInputs(desiredConfig, currentConfig, statefulMode);
85
86
 
86
87
  const planOptions: PlanOptions<T> = {
87
- statefulMode,
88
88
  parameterOptions: this.parameterOptions,
89
+ statefulMode,
89
90
  }
90
91
 
91
92
  this.addDefaultValues(desiredConfig);
@@ -95,8 +96,8 @@ export abstract class Resource<T extends StringIndexedObject> {
95
96
  const parsedConfig = new ConfigParser(desiredConfig, currentConfig, this.statefulParameters, this.transformParameters)
96
97
  const {
97
98
  desiredParameters,
98
- resourceMetadata,
99
99
  nonStatefulParameters,
100
+ resourceMetadata,
100
101
  statefulParameters,
101
102
  } = parsedConfig;
102
103
 
@@ -133,13 +134,16 @@ export abstract class Resource<T extends StringIndexedObject> {
133
134
  case ResourceOperation.CREATE: {
134
135
  return this._applyCreate(plan); // TODO: Add new parameters value so that apply
135
136
  }
137
+
136
138
  case ResourceOperation.MODIFY: {
137
139
  return this._applyModify(plan);
138
140
  }
141
+
139
142
  case ResourceOperation.RECREATE: {
140
143
  await this._applyDestroy(plan);
141
144
  return this._applyCreate(plan);
142
145
  }
146
+
143
147
  case ResourceOperation.DESTROY: {
144
148
  return this._applyDestroy(plan);
145
149
  }
@@ -185,11 +189,13 @@ export abstract class Resource<T extends StringIndexedObject> {
185
189
  await statefulParameter.applyAdd(parameterChange.newValue, plan);
186
190
  break;
187
191
  }
192
+
188
193
  case ParameterOperation.MODIFY: {
189
194
  // TODO: When stateful mode is added in the future. Dynamically choose if deletes are allowed
190
195
  await statefulParameter.applyModify(parameterChange.newValue, parameterChange.previousValue, false, plan);
191
196
  break;
192
197
  }
198
+
193
199
  case ParameterOperation.REMOVE: {
194
200
  await statefulParameter.applyRemove(parameterChange.previousValue, plan);
195
201
  break;
@@ -256,10 +262,10 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`
256
262
  delete desired[key];
257
263
 
258
264
  // Add the new transformed values
259
- Object.entries(transformedValue).forEach(([tvKey, tvValue]) => {
265
+ for (const [tvKey, tvValue] of Object.entries(transformedValue)) {
260
266
  // @ts-ignore
261
267
  desired[tvKey] = tvValue;
262
- })
268
+ }
263
269
  }
264
270
  }
265
271
 
@@ -268,13 +274,12 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`
268
274
  return;
269
275
  }
270
276
 
271
- Object.entries(this.defaultValues)
272
- .forEach(([key, defaultValue]) => {
277
+ for (const [key, defaultValue] of Object.entries(this.defaultValues)) {
273
278
  if (defaultValue !== undefined && desired[key as any] === undefined) {
274
279
  // @ts-ignore
275
280
  desired[key] = defaultValue;
276
281
  }
277
- });
282
+ }
278
283
  }
279
284
 
280
285
  private async refreshNonStatefulParameters(resourceParameters: Partial<T>): Promise<Partial<T> | null> {
@@ -343,7 +348,7 @@ Additional: ${[...refreshKeys].filter(k => !desiredKeys.has(k))};`
343
348
  }
344
349
  };
345
350
 
346
- abstract refresh(values: Partial<T>): Promise<Partial<T> | null>;
351
+ abstract refresh(parameters: Partial<T>): Promise<Partial<T> | null>;
347
352
 
348
353
  abstract applyCreate(plan: CreatePlan<T>): Promise<void>;
349
354
 
@@ -407,22 +412,22 @@ ${JSON.stringify(currentMetadata, null, 2)}`);
407
412
  const desiredParameters = this.desiredConfig ? splitUserConfig(this.desiredConfig).parameters : undefined;
408
413
  const currentParameters = this.currentConfig ? splitUserConfig(this.currentConfig).parameters : undefined;
409
414
 
410
- return { ...(desiredParameters ?? {}), ...(currentParameters ?? {}) } as Partial<T>;
415
+ return { ...desiredParameters, ...currentParameters } as Partial<T>;
411
416
  }
412
417
 
413
418
  get nonStatefulParameters(): Partial<T> {
414
- const parameters = this.parameters;
419
+ const { parameters } = this;
415
420
 
416
- return Object.fromEntries([
417
- ...Object.entries(parameters).filter(([key]) => !(this.statefulParametersMap.has(key) || this.transformParametersMap.has(key))),
418
- ]) as Partial<T>;
421
+ return Object.fromEntries(
422
+ Object.entries(parameters).filter(([key]) => !(this.statefulParametersMap.has(key) || this.transformParametersMap.has(key)))
423
+ ) as Partial<T>;
419
424
  }
420
425
 
421
426
  get statefulParameters(): Partial<T> {
422
- const parameters = this.parameters;
427
+ const { parameters } = this;
423
428
 
424
- return Object.fromEntries([
425
- ...Object.entries(parameters).filter(([key]) => this.statefulParametersMap.has(key)),
426
- ]) as Partial<T>;
429
+ return Object.fromEntries(
430
+ Object.entries(parameters).filter(([key]) => this.statefulParametersMap.has(key))
431
+ ) as Partial<T>;
427
432
  }
428
433
  }
@@ -0,0 +1,29 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { splitUserConfig } from './utils.js';
3
+
4
+ describe('Utils tests', () => {
5
+ it('Can split a config correctly', () => {
6
+ const { parameters, resourceMetadata } = splitUserConfig({
7
+ type: 'type',
8
+ name: 'name',
9
+ dependsOn: ['a', 'b', 'c'],
10
+ propA: 'propA',
11
+ propB: 'propB',
12
+ propC: 'propC',
13
+ propD: 'propD',
14
+ })
15
+
16
+ expect(resourceMetadata).toMatchObject({
17
+ type: 'type',
18
+ name: 'name',
19
+ dependsOn: ['a', 'b', 'c'],
20
+ })
21
+
22
+ expect(parameters).toMatchObject({
23
+ propA: 'propA',
24
+ propB: 'propB',
25
+ propC: 'propC',
26
+ propD: 'propD',
27
+ })
28
+ })
29
+ })
@@ -85,8 +85,8 @@ export function splitUserConfig<T extends StringIndexedObject>(
85
85
  ): { parameters: T; resourceMetadata: ResourceConfig} {
86
86
  const resourceMetadata = {
87
87
  type: config.type,
88
- ...(config.name && { name: config.name }),
89
- ...(config.dependsOn && { dependsOn: config.dependsOn }),
88
+ ...(config.name ? { name: config.name } : {}),
89
+ ...(config.dependsOn ? { dependsOn: config.dependsOn } : {}),
90
90
  };
91
91
 
92
92
  const { type, name, dependsOn, ...parameters } = config;
@@ -1 +0,0 @@
1
- export {};
@@ -1,22 +0,0 @@
1
- import { Resource } from './resource.js';
2
- class Test extends Resource {
3
- validate(config) {
4
- throw new Error('Method not implemented.');
5
- }
6
- async refresh(keys) {
7
- const result = {};
8
- if (keys.has('propA')) {
9
- result['propA'] = 'abc';
10
- }
11
- return result;
12
- }
13
- applyCreate(plan) {
14
- throw new Error('Method not implemented.');
15
- }
16
- applyModify(parameterName, newValue, previousValue, plan) {
17
- throw new Error('Method not implemented.');
18
- }
19
- applyDestroy(plan) {
20
- throw new Error('Method not implemented.');
21
- }
22
- }
@@ -1,3 +0,0 @@
1
- export interface StringIndexedObject {
2
- [x: string]: unknown;
3
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- import { ChildProcess } from 'child_process';
3
- export declare class CodifyTestUtils {
4
- static sendMessageToProcessAwaitResponse(process: ChildProcess, message: any): Promise<any>;
5
- }
@@ -1,17 +0,0 @@
1
- export class CodifyTestUtils {
2
- static sendMessageToProcessAwaitResponse(process, message) {
3
- return new Promise((resolve, reject) => {
4
- process.on('message', (response) => {
5
- resolve(response);
6
- });
7
- process.on('error', (err) => reject(err));
8
- process.on('exit', (code) => {
9
- if (code != 0) {
10
- reject('Exit code is not 0');
11
- }
12
- resolve(code);
13
- });
14
- process.send(message);
15
- });
16
- }
17
- }