codify-plugin-lib 1.0.128 → 1.0.130

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.
@@ -16,8 +16,8 @@ export declare class Plan<T extends StringIndexedObject> {
16
16
  * Ex: name, type, dependsOn etc. Metadata parameters
17
17
  */
18
18
  coreParameters: ResourceConfig;
19
- statefulMode: boolean;
20
- constructor(id: string, changeSet: ChangeSet<T>, resourceMetadata: ResourceConfig, statefulMode: boolean);
19
+ isStateful: boolean;
20
+ constructor(id: string, changeSet: ChangeSet<T>, coreParameters: ResourceConfig, isStateful: boolean);
21
21
  /**
22
22
  * The desired config that a plan will achieve after executing all the actions.
23
23
  */
@@ -28,13 +28,20 @@ export declare class Plan<T extends StringIndexedObject> {
28
28
  get currentConfig(): T | null;
29
29
  get resourceId(): string;
30
30
  static calculate<T extends StringIndexedObject>(params: {
31
- desiredParameters: Partial<T> | null;
32
- currentParametersArray: Partial<T>[] | null;
33
- stateParameters: Partial<T> | null;
34
- coreParameters: ResourceConfig;
31
+ desired: Partial<T> | null;
32
+ currentArray: Partial<T>[] | null;
33
+ state: Partial<T> | null;
34
+ core: ResourceConfig;
35
35
  settings: ParsedResourceSettings<T>;
36
- statefulMode: boolean;
36
+ isStateful: boolean;
37
37
  }): Plan<T>;
38
+ static fromResponse<T extends ResourceConfig>(data: ApplyRequestData['plan'], defaultValues?: Partial<Record<keyof T, unknown>>): Plan<T>;
39
+ /**
40
+ * The type (id) of the resource
41
+ *
42
+ * @return string
43
+ */
44
+ getResourceType(): string;
38
45
  /**
39
46
  * When multiples of the same resource are allowed, this matching function will match a given config with one of the
40
47
  * existing configs on the system. For example if there are multiple versions of Android Studios installed, we can use
@@ -44,13 +51,6 @@ export declare class Plan<T extends StringIndexedObject> {
44
51
  * @private
45
52
  */
46
53
  private static matchCurrentParameters;
47
- /**
48
- * The type (id) of the resource
49
- *
50
- * @return string
51
- */
52
- getResourceType(): string;
53
- static fromResponse<T extends ResourceConfig>(data: ApplyRequestData['plan'], defaultValues?: Partial<Record<keyof T, unknown>>): Plan<T>;
54
54
  /**
55
55
  * Only keep relevant params for the plan. We don't want to change settings that were not already
56
56
  * defined.
package/dist/plan/plan.js CHANGED
@@ -16,12 +16,12 @@ export class Plan {
16
16
  * Ex: name, type, dependsOn etc. Metadata parameters
17
17
  */
18
18
  coreParameters;
19
- statefulMode;
20
- constructor(id, changeSet, resourceMetadata, statefulMode) {
19
+ isStateful;
20
+ constructor(id, changeSet, coreParameters, isStateful) {
21
21
  this.id = id;
22
22
  this.changeSet = changeSet;
23
- this.coreParameters = resourceMetadata;
24
- this.statefulMode = statefulMode;
23
+ this.coreParameters = coreParameters;
24
+ this.isStateful = isStateful;
25
25
  }
26
26
  /**
27
27
  * The desired config that a plan will achieve after executing all the actions.
@@ -30,10 +30,7 @@ export class Plan {
30
30
  if (this.changeSet.operation === ResourceOperation.DESTROY) {
31
31
  return null;
32
32
  }
33
- return {
34
- ...this.coreParameters,
35
- ...this.changeSet.desiredParameters,
36
- };
33
+ return this.changeSet.desiredParameters;
37
34
  }
38
35
  /**
39
36
  * The current config that the plan is changing.
@@ -42,10 +39,7 @@ export class Plan {
42
39
  if (this.changeSet.operation === ResourceOperation.CREATE) {
43
40
  return null;
44
41
  }
45
- return {
46
- ...this.coreParameters,
47
- ...this.changeSet.currentParameters,
48
- };
42
+ return this.changeSet.currentParameters;
49
43
  }
50
44
  get resourceId() {
51
45
  return this.coreParameters.name
@@ -53,67 +47,36 @@ export class Plan {
53
47
  : this.coreParameters.type;
54
48
  }
55
49
  static calculate(params) {
56
- const { desiredParameters, currentParametersArray, stateParameters, coreParameters, settings, statefulMode } = params;
57
- const currentParameters = Plan.matchCurrentParameters({
58
- desiredParameters,
59
- currentParametersArray,
60
- stateParameters,
50
+ const { desired, currentArray, state, core, settings, isStateful } = params;
51
+ const current = Plan.matchCurrentParameters({
52
+ desired,
53
+ currentArray,
54
+ state,
61
55
  settings,
62
- statefulMode
56
+ isStateful
63
57
  });
64
58
  const filteredCurrentParameters = Plan.filterCurrentParams({
65
- desiredParameters,
66
- currentParameters,
67
- stateParameters,
59
+ desired,
60
+ current,
61
+ state,
68
62
  settings,
69
- statefulMode
63
+ isStateful
70
64
  });
71
65
  // Empty
72
- if (!filteredCurrentParameters && !desiredParameters) {
73
- return new Plan(uuidV4(), ChangeSet.empty(), coreParameters, statefulMode);
66
+ if (!filteredCurrentParameters && !desired) {
67
+ return new Plan(uuidV4(), ChangeSet.empty(), core, isStateful);
74
68
  }
75
69
  // CREATE
76
- if (!filteredCurrentParameters && desiredParameters) {
77
- return new Plan(uuidV4(), ChangeSet.create(desiredParameters), coreParameters, statefulMode);
70
+ if (!filteredCurrentParameters && desired) {
71
+ return new Plan(uuidV4(), ChangeSet.create(desired), core, isStateful);
78
72
  }
79
73
  // DESTROY
80
- if (filteredCurrentParameters && !desiredParameters) {
81
- return new Plan(uuidV4(), ChangeSet.destroy(filteredCurrentParameters), coreParameters, statefulMode);
74
+ if (filteredCurrentParameters && !desired) {
75
+ return new Plan(uuidV4(), ChangeSet.destroy(filteredCurrentParameters), core, isStateful);
82
76
  }
83
77
  // NO-OP, MODIFY or RE-CREATE
84
- const changeSet = ChangeSet.calculateModification(desiredParameters, filteredCurrentParameters, settings.parameterSettings);
85
- return new Plan(uuidV4(), changeSet, coreParameters, statefulMode);
86
- }
87
- /**
88
- * When multiples of the same resource are allowed, this matching function will match a given config with one of the
89
- * existing configs on the system. For example if there are multiple versions of Android Studios installed, we can use
90
- * the application name and location to match it to our desired configs name and location.
91
- *
92
- * @param params
93
- * @private
94
- */
95
- static matchCurrentParameters(params) {
96
- const { desiredParameters, currentParametersArray, stateParameters, settings, statefulMode } = params;
97
- if (!settings.allowMultiple) {
98
- return currentParametersArray?.[0] ?? null;
99
- }
100
- if (!currentParametersArray) {
101
- return null;
102
- }
103
- if (statefulMode) {
104
- return stateParameters
105
- ? settings.allowMultiple.matcher(stateParameters, currentParametersArray)
106
- : null;
107
- }
108
- return settings.allowMultiple.matcher(desiredParameters, currentParametersArray);
109
- }
110
- /**
111
- * The type (id) of the resource
112
- *
113
- * @return string
114
- */
115
- getResourceType() {
116
- return this.coreParameters.type;
78
+ const changeSet = ChangeSet.calculateModification(desired, filteredCurrentParameters, settings.parameterSettings);
79
+ return new Plan(uuidV4(), changeSet, core, isStateful);
117
80
  }
118
81
  // 2. Even if there was (maybe for testing reasons), the plan values should not be adjusted
119
82
  static fromResponse(data, defaultValues) {
@@ -124,7 +87,7 @@ export class Plan {
124
87
  return new Plan(uuidV4(), new ChangeSet(data.operation, data.parameters), {
125
88
  type: data.resourceType,
126
89
  name: data.resourceName,
127
- }, data.statefulMode);
90
+ }, data.isStateful);
128
91
  function addDefaultValues() {
129
92
  Object.entries(defaultValues ?? {})
130
93
  .forEach(([key, defaultValue]) => {
@@ -169,6 +132,37 @@ export class Plan {
169
132
  });
170
133
  }
171
134
  }
135
+ /**
136
+ * The type (id) of the resource
137
+ *
138
+ * @return string
139
+ */
140
+ getResourceType() {
141
+ return this.coreParameters.type;
142
+ }
143
+ /**
144
+ * When multiples of the same resource are allowed, this matching function will match a given config with one of the
145
+ * existing configs on the system. For example if there are multiple versions of Android Studios installed, we can use
146
+ * the application name and location to match it to our desired configs name and location.
147
+ *
148
+ * @param params
149
+ * @private
150
+ */
151
+ static matchCurrentParameters(params) {
152
+ const { desired, currentArray, state, settings, isStateful } = params;
153
+ if (!settings.allowMultiple) {
154
+ return currentArray?.[0] ?? null;
155
+ }
156
+ if (!currentArray) {
157
+ return null;
158
+ }
159
+ if (isStateful) {
160
+ return state
161
+ ? settings.allowMultiple.matcher(state, currentArray)
162
+ : null;
163
+ }
164
+ return settings.allowMultiple.matcher(desired, currentArray);
165
+ }
172
166
  /**
173
167
  * Only keep relevant params for the plan. We don't want to change settings that were not already
174
168
  * defined.
@@ -178,7 +172,7 @@ export class Plan {
178
172
  * or wants to set. If a parameter is not specified then it's not managed by Codify.
179
173
  */
180
174
  static filterCurrentParams(params) {
181
- const { desiredParameters: desired, currentParameters: current, stateParameters: state, settings, statefulMode } = params;
175
+ const { desired, current, state, settings, isStateful } = params;
182
176
  if (!current) {
183
177
  return null;
184
178
  }
@@ -188,7 +182,7 @@ export class Plan {
188
182
  }
189
183
  // For stateful mode, we're done after filtering by the keys of desired + state. Stateless mode
190
184
  // requires additional filtering for stateful parameter arrays and objects.
191
- if (statefulMode) {
185
+ if (isStateful) {
192
186
  return filteredCurrent;
193
187
  }
194
188
  // TODO: Add object handling here in addition to arrays in the future
@@ -200,7 +194,7 @@ export class Plan {
200
194
  if (!current) {
201
195
  return null;
202
196
  }
203
- if (statefulMode) {
197
+ if (isStateful) {
204
198
  const keys = new Set([...Object.keys(state ?? {}), ...Object.keys(desired ?? {})]);
205
199
  return Object.fromEntries(Object.entries(current)
206
200
  .filter(([k]) => keys.has(k)));
@@ -276,7 +270,7 @@ export class Plan {
276
270
  return {
277
271
  planId: this.id,
278
272
  operation: this.changeSet.operation,
279
- statefulMode: this.statefulMode,
273
+ isStateful: this.isStateful,
280
274
  resourceName: this.coreParameters.name,
281
275
  resourceType: this.coreParameters.type,
282
276
  parameters: this.changeSet.parameterChanges,
@@ -1,4 +1,4 @@
1
- import { ApplyRequestData, GetResourceInfoRequestData, GetResourceInfoResponseData, ImportRequestData, ImportResponseData, InitializeResponseData, PlanRequestData, PlanResponseData, ResourceConfig, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
1
+ import { ApplyRequestData, GetResourceInfoRequestData, GetResourceInfoResponseData, ImportRequestData, ImportResponseData, InitializeResponseData, PlanRequestData, PlanResponseData, ResourceConfig, ResourceJson, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
2
2
  import { Plan } from '../plan/plan.js';
3
3
  import { BackgroundPty } from '../pty/background-pty.js';
4
4
  import { Resource } from '../resource/resource.js';
@@ -18,5 +18,5 @@ export declare class Plugin {
18
18
  apply(data: ApplyRequestData): Promise<void>;
19
19
  kill(): Promise<void>;
20
20
  private resolvePlan;
21
- protected crossValidateResources(configs: ResourceConfig[]): Promise<void>;
21
+ protected crossValidateResources(resources: ResourceJson[]): Promise<void>;
22
22
  }
@@ -52,26 +52,28 @@ export class Plugin {
52
52
  };
53
53
  }
54
54
  async import(data) {
55
- if (!this.resourceControllers.has(data.config.type)) {
56
- throw new Error(`Cannot get info for resource ${data.config.type}, resource doesn't exist`);
55
+ const { core, parameters } = data;
56
+ if (!this.resourceControllers.has(core.type)) {
57
+ throw new Error(`Cannot get info for resource ${core.type}, resource doesn't exist`);
57
58
  }
58
59
  const result = await ptyLocalStorage.run(this.planPty, () => this.resourceControllers
59
- .get(data.config.type)
60
- ?.import(data.config));
60
+ .get(core.type)
61
+ ?.import(core, parameters));
61
62
  return {
62
- request: data.config,
63
+ request: data,
63
64
  result: result ?? [],
64
65
  };
65
66
  }
66
67
  async validate(data) {
67
68
  const validationResults = [];
68
69
  for (const config of data.configs) {
69
- if (!this.resourceControllers.has(config.type)) {
70
- throw new Error(`Resource type not found: ${config.type}`);
70
+ const { core, parameters } = config;
71
+ if (!this.resourceControllers.has(core.type)) {
72
+ throw new Error(`Resource type not found: ${core.type}`);
71
73
  }
72
74
  const validation = await this.resourceControllers
73
- .get(config.type)
74
- .validate(config);
75
+ .get(core.type)
76
+ .validate(core, parameters);
75
77
  validationResults.push(validation);
76
78
  }
77
79
  await this.crossValidateResources(data.configs);
@@ -80,11 +82,11 @@ export class Plugin {
80
82
  };
81
83
  }
82
84
  async plan(data) {
83
- const type = data.desired?.type ?? data.state?.type;
84
- if (!type || !this.resourceControllers.has(type)) {
85
+ const { type } = data.core;
86
+ if (!this.resourceControllers.has(type)) {
85
87
  throw new Error(`Resource type not found: ${type}`);
86
88
  }
87
- const plan = await ptyLocalStorage.run(this.planPty, async () => this.resourceControllers.get(type).plan(data.desired ?? null, data.state ?? null, data.isStateful));
89
+ const plan = await ptyLocalStorage.run(this.planPty, async () => this.resourceControllers.get(type).plan(data.core, data.desired ?? null, data.state ?? null, data.isStateful));
88
90
  this.planStorage.set(plan.id, plan);
89
91
  return plan.toResponse();
90
92
  }
@@ -101,7 +103,7 @@ export class Plugin {
101
103
  // Validate using desired/desired. If the apply was successful, no changes should be reported back.
102
104
  // Default back desired back to current if it is not defined (for destroys only)
103
105
  const validationPlan = await ptyLocalStorage.run(new BackgroundPty(), async () => {
104
- const result = await resource.plan(plan.desiredConfig, plan.desiredConfig ?? plan.currentConfig, plan.statefulMode);
106
+ const result = await resource.plan(plan.coreParameters, plan.desiredConfig, plan.desiredConfig ?? plan.currentConfig, plan.isStateful);
105
107
  await getPty().kill();
106
108
  return result;
107
109
  });
@@ -126,5 +128,6 @@ export class Plugin {
126
128
  const resource = this.resourceControllers.get(planRequest.resourceType);
127
129
  return Plan.fromResponse(planRequest, resource.parsedSettings.defaultValues);
128
130
  }
129
- async crossValidateResources(configs) { }
131
+ async crossValidateResources(resources) {
132
+ }
130
133
  }
@@ -1,13 +1,10 @@
1
- import { ResourceConfig, StringIndexedObject } from 'codify-schemas';
1
+ import { StringIndexedObject } from 'codify-schemas';
2
2
  import { StatefulParameterController } from '../stateful-parameter/stateful-parameter-controller.js';
3
3
  export declare class ConfigParser<T extends StringIndexedObject> {
4
4
  private readonly desiredConfig;
5
5
  private readonly stateConfig;
6
6
  private statefulParametersMap;
7
- constructor(desiredConfig: Partial<T> & ResourceConfig | null, stateConfig: Partial<T> & ResourceConfig | null, statefulParameters: Map<keyof T, StatefulParameterController<T, T[keyof T]>>);
8
- get coreParameters(): ResourceConfig;
9
- get desiredParameters(): Partial<T> | null;
10
- get stateParameters(): Partial<T> | null;
7
+ constructor(desiredConfig: Partial<T> | null, stateConfig: Partial<T> | null, statefulParameters: Map<keyof T, StatefulParameterController<T, T[keyof T]>>);
11
8
  get allParameters(): Partial<T>;
12
9
  get allNonStatefulParameters(): Partial<T>;
13
10
  get allStatefulParameters(): Partial<T>;
@@ -1,4 +1,3 @@
1
- import { splitUserConfig } from '../utils/utils.js';
2
1
  export class ConfigParser {
3
2
  desiredConfig;
4
3
  stateConfig;
@@ -8,34 +7,8 @@ export class ConfigParser {
8
7
  this.stateConfig = stateConfig;
9
8
  this.statefulParametersMap = statefulParameters;
10
9
  }
11
- get coreParameters() {
12
- const desiredCoreParameters = this.desiredConfig ? splitUserConfig(this.desiredConfig).coreParameters : undefined;
13
- const currentCoreParameters = this.stateConfig ? splitUserConfig(this.stateConfig).coreParameters : undefined;
14
- if (!desiredCoreParameters && !currentCoreParameters) {
15
- throw new Error(`Unable to parse resource core parameters from:
16
-
17
- Desired: ${JSON.stringify(this.desiredConfig, null, 2)}
18
-
19
- Current: ${JSON.stringify(this.stateConfig, null, 2)}`);
20
- }
21
- return desiredCoreParameters ?? currentCoreParameters;
22
- }
23
- get desiredParameters() {
24
- if (!this.desiredConfig) {
25
- return null;
26
- }
27
- const { parameters } = splitUserConfig(this.desiredConfig);
28
- return parameters;
29
- }
30
- get stateParameters() {
31
- if (!this.stateConfig) {
32
- return null;
33
- }
34
- const { parameters } = splitUserConfig(this.stateConfig);
35
- return parameters;
36
- }
37
10
  get allParameters() {
38
- return { ...this.desiredParameters, ...this.stateParameters };
11
+ return { ...this.desiredConfig, ...this.stateConfig };
39
12
  }
40
13
  get allNonStatefulParameters() {
41
14
  const { allParameters, statefulParametersMap, } = this;
@@ -1,5 +1,5 @@
1
1
  import { Ajv, ValidateFunction } from 'ajv';
2
- import { ResourceConfig, StringIndexedObject, ValidateResponseData } from 'codify-schemas';
2
+ import { ResourceConfig, ResourceJson, StringIndexedObject, ValidateResponseData } from 'codify-schemas';
3
3
  import { Plan } from '../plan/plan.js';
4
4
  import { ParsedResourceSettings } from './parsed-resource-settings.js';
5
5
  import { Resource } from './resource.js';
@@ -14,10 +14,10 @@ export declare class ResourceController<T extends StringIndexedObject> {
14
14
  protected schemaValidator?: ValidateFunction;
15
15
  constructor(resource: Resource<T>);
16
16
  initialize(): Promise<void>;
17
- validate(desiredConfig: Partial<T> & ResourceConfig): Promise<ValidateResponseData['resourceValidations'][0]>;
18
- plan(desiredConfig: Partial<T> & ResourceConfig | null, stateConfig?: Partial<T> & ResourceConfig | null, statefulMode?: boolean): Promise<Plan<T>>;
17
+ validate(core: ResourceConfig, parameters: Partial<T>): Promise<ValidateResponseData['resourceValidations'][0]>;
18
+ plan(core: ResourceConfig, desired: Partial<T> | null, state: Partial<T> | null, isStateful?: boolean): Promise<Plan<T>>;
19
19
  apply(plan: Plan<T>): Promise<void>;
20
- import(config: Partial<T> & ResourceConfig): Promise<(Partial<T> & ResourceConfig)[] | null>;
20
+ import(core: ResourceConfig, parameters: Partial<T>): Promise<Array<ResourceJson> | null>;
21
21
  private applyCreate;
22
22
  private applyModify;
23
23
  private applyDestroy;
@@ -1,7 +1,6 @@
1
1
  import { Ajv } from 'ajv';
2
2
  import { ParameterOperation, ResourceOperation } from 'codify-schemas';
3
3
  import { Plan } from '../plan/plan.js';
4
- import { splitUserConfig } from '../utils/utils.js';
5
4
  import { ConfigParser } from './config-parser.js';
6
5
  import { ParsedResourceSettings } from './parsed-resource-settings.js';
7
6
  export class ResourceController {
@@ -31,19 +30,17 @@ export class ResourceController {
31
30
  async initialize() {
32
31
  return this.resource.initialize();
33
32
  }
34
- async validate(desiredConfig) {
35
- const configToValidate = { ...desiredConfig };
36
- await this.applyTransformParameters(configToValidate);
37
- const { parameters, coreParameters } = splitUserConfig(configToValidate);
33
+ async validate(core, parameters) {
34
+ await this.applyTransformParameters(parameters);
38
35
  this.addDefaultValues(parameters);
39
36
  if (this.schemaValidator) {
40
37
  // Schema validator uses pre transformation parameters
41
- const isValid = this.schemaValidator(splitUserConfig(desiredConfig).parameters);
38
+ const isValid = this.schemaValidator(parameters);
42
39
  if (!isValid) {
43
40
  return {
44
41
  isValid: false,
45
- resourceName: coreParameters.name,
46
- resourceType: coreParameters.type,
42
+ resourceName: core.name,
43
+ resourceType: core.type,
47
44
  schemaValidationErrors: this.schemaValidator?.errors ?? [],
48
45
  };
49
46
  }
@@ -61,54 +58,54 @@ export class ResourceController {
61
58
  return {
62
59
  customValidationErrorMessage,
63
60
  isValid: false,
64
- resourceName: coreParameters.name,
65
- resourceType: coreParameters.type,
61
+ resourceName: core.name,
62
+ resourceType: core.type,
66
63
  schemaValidationErrors: this.schemaValidator?.errors ?? [],
67
64
  };
68
65
  }
69
66
  return {
70
67
  isValid: true,
71
- resourceName: coreParameters.name,
72
- resourceType: coreParameters.type,
68
+ resourceName: core.name,
69
+ resourceType: core.type,
73
70
  schemaValidationErrors: [],
74
71
  };
75
72
  }
76
- async plan(desiredConfig, stateConfig = null, statefulMode = false) {
77
- this.validatePlanInputs(desiredConfig, stateConfig, statefulMode);
78
- this.addDefaultValues(desiredConfig);
79
- await this.applyTransformParameters(desiredConfig);
80
- this.addDefaultValues(stateConfig);
81
- await this.applyTransformParameters(stateConfig);
73
+ async plan(core, desired, state, isStateful = false) {
74
+ this.validatePlanInputs(core, desired, state, isStateful);
75
+ this.addDefaultValues(desired);
76
+ await this.applyTransformParameters(desired);
77
+ this.addDefaultValues(state);
78
+ await this.applyTransformParameters(state);
82
79
  // Parse data from the user supplied config
83
- const parsedConfig = new ConfigParser(desiredConfig, stateConfig, this.parsedSettings.statefulParameters);
84
- const { coreParameters, desiredParameters, stateParameters, allParameters, allNonStatefulParameters, allStatefulParameters, } = parsedConfig;
80
+ const parsedConfig = new ConfigParser(desired, state, this.parsedSettings.statefulParameters);
81
+ const { allParameters, allNonStatefulParameters, allStatefulParameters, } = parsedConfig;
85
82
  // Refresh resource parameters. This refreshes the parameters that configure the resource itself
86
- const currentParametersArray = await this.refreshNonStatefulParameters(allNonStatefulParameters);
83
+ const currentArray = await this.refreshNonStatefulParameters(allNonStatefulParameters);
87
84
  // Short circuit here. If the resource is non-existent, there's no point checking stateful parameters
88
- if (currentParametersArray === null
89
- || currentParametersArray === undefined
85
+ if (currentArray === null
86
+ || currentArray === undefined
90
87
  || this.settings.allowMultiple // Stateful parameters are not supported currently if allowMultiple is true
91
- || currentParametersArray.length === 0
92
- || currentParametersArray.filter(Boolean).length === 0) {
88
+ || currentArray.length === 0
89
+ || currentArray.filter(Boolean).length === 0) {
93
90
  return Plan.calculate({
94
- desiredParameters,
95
- currentParametersArray,
96
- stateParameters,
97
- coreParameters,
91
+ desired,
92
+ currentArray,
93
+ state,
94
+ core,
98
95
  settings: this.parsedSettings,
99
- statefulMode,
96
+ isStateful,
100
97
  });
101
98
  }
102
99
  // Refresh stateful parameters. These parameters have state external to the resource. allowMultiple
103
100
  // does not work together with stateful parameters
104
101
  const statefulCurrentParameters = await this.refreshStatefulParameters(allStatefulParameters, allParameters);
105
102
  return Plan.calculate({
106
- desiredParameters,
107
- currentParametersArray: [{ ...currentParametersArray[0], ...statefulCurrentParameters }],
108
- stateParameters,
109
- coreParameters,
103
+ desired,
104
+ currentArray: [{ ...currentArray[0], ...statefulCurrentParameters }],
105
+ state,
106
+ core,
110
107
  settings: this.parsedSettings,
111
- statefulMode
108
+ isStateful
112
109
  });
113
110
  }
114
111
  async apply(plan) {
@@ -131,36 +128,35 @@ export class ResourceController {
131
128
  }
132
129
  }
133
130
  }
134
- async import(config) {
135
- this.addDefaultValues(config);
136
- await this.applyTransformParameters(config);
131
+ async import(core, parameters) {
132
+ this.addDefaultValues(parameters);
133
+ await this.applyTransformParameters(parameters);
137
134
  // Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
138
135
  const parametersToRefresh = this.settings.import?.refreshKeys
139
136
  ? {
140
137
  ...Object.fromEntries(this.settings.import?.refreshKeys.map((k) => [k, null])),
141
138
  ...this.settings.import?.defaultRefreshValues,
142
- ...config,
139
+ ...parameters,
143
140
  }
144
141
  : {
145
142
  ...Object.fromEntries(this.getAllParameterKeys().map((k) => [k, null])),
146
143
  ...this.settings.import?.defaultRefreshValues,
147
- ...config,
144
+ ...parameters,
148
145
  };
149
146
  // Parse data from the user supplied config
150
147
  const parsedConfig = new ConfigParser(parametersToRefresh, null, this.parsedSettings.statefulParameters);
151
- const { allNonStatefulParameters, allStatefulParameters, coreParameters, } = parsedConfig;
148
+ const { allNonStatefulParameters, allStatefulParameters, } = parsedConfig;
152
149
  const currentParametersArray = await this.refreshNonStatefulParameters(allNonStatefulParameters);
153
150
  if (currentParametersArray === null
154
151
  || currentParametersArray === undefined
155
152
  || this.settings.allowMultiple // Stateful parameters are not supported currently if allowMultiple is true
156
- || currentParametersArray.length === 0
157
153
  || currentParametersArray.filter(Boolean).length === 0) {
158
154
  return currentParametersArray
159
- ?.map((r) => ({ ...coreParameters, ...r }))
155
+ ?.map((r) => ({ core, parameters: r }))
160
156
  ?? null;
161
157
  }
162
158
  const statefulCurrentParameters = await this.refreshStatefulParameters(allStatefulParameters, parametersToRefresh);
163
- return [{ ...coreParameters, ...currentParametersArray[0], ...statefulCurrentParameters }];
159
+ return [{ core, parameters: { ...currentParametersArray[0], ...statefulCurrentParameters } }];
164
160
  }
165
161
  async applyCreate(plan) {
166
162
  await this.resource.create(plan);
@@ -233,10 +229,9 @@ ${JSON.stringify(refresh, null, 2)}
233
229
  config[key] = await inputTransformation(config[key], this.settings.parameterSettings[key]);
234
230
  }
235
231
  if (this.settings.inputTransformation) {
236
- const { parameters, coreParameters } = splitUserConfig(config);
237
- const transformed = await this.settings.inputTransformation(parameters);
232
+ const transformed = await this.settings.inputTransformation({ ...config });
238
233
  Object.keys(config).forEach((k) => delete config[k]);
239
- Object.assign(config, transformed, coreParameters);
234
+ Object.assign(config, transformed);
240
235
  }
241
236
  }
242
237
  addDefaultValues(config) {
@@ -272,11 +267,14 @@ ${JSON.stringify(refresh, null, 2)}
272
267
  }));
273
268
  return result;
274
269
  }
275
- validatePlanInputs(desired, current, statefulMode) {
270
+ validatePlanInputs(core, desired, current, isStateful) {
271
+ if (!core || !core.type) {
272
+ throw new Error('Core parameters type must be defined');
273
+ }
276
274
  if (!desired && !current) {
277
275
  throw new Error('Desired config and current config cannot both be missing');
278
276
  }
279
- if (!statefulMode && !desired) {
277
+ if (!isStateful && !desired) {
280
278
  throw new Error('Desired config must be provided in non-stateful mode');
281
279
  }
282
280
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.128",
3
+ "version": "1.0.130",
4
4
  "description": "Library plugin library",
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.58",
17
+ "codify-schemas": "1.0.61",
18
18
  "@npmcli/promise-spawn": "^7.0.1",
19
19
  "@homebridge/node-pty-prebuilt-multiarch": "^0.12.0-beta.5",
20
20
  "uuid": "^10.0.0",
@@ -12,7 +12,7 @@ describe('Test file for errors file', () => {
12
12
  type: 'homebrew',
13
13
  name: 'first'
14
14
  },
15
- statefulMode: true,
15
+ isStateful: true,
16
16
  })
17
17
 
18
18
  try {