codify-plugin-lib 1.0.176 → 1.0.178
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/messages/sender.d.ts +1 -0
- package/dist/messages/sender.js +10 -0
- package/dist/plugin/plugin.js +1 -1
- package/dist/resource/resource-controller.d.ts +2 -2
- package/dist/resource/resource-controller.js +20 -13
- package/dist/resource/resource.d.ts +1 -1
- package/package.json +2 -2
- package/src/messages/sender.ts +13 -0
- package/src/plugin/plugin.ts +2 -1
- package/src/resource/resource-controller.ts +21 -13
- package/src/resource/resource.ts +1 -1
- package/dist/entities/change-set.d.ts +0 -24
- package/dist/entities/change-set.js +0 -152
- package/dist/entities/errors.d.ts +0 -4
- package/dist/entities/errors.js +0 -7
- package/dist/entities/plan-types.d.ts +0 -25
- package/dist/entities/plan-types.js +0 -1
- package/dist/entities/plan.d.ts +0 -15
- package/dist/entities/plan.js +0 -127
- package/dist/entities/plugin.d.ts +0 -16
- package/dist/entities/plugin.js +0 -80
- package/dist/entities/resource-options.d.ts +0 -31
- package/dist/entities/resource-options.js +0 -76
- package/dist/entities/resource-types.d.ts +0 -11
- package/dist/entities/resource-types.js +0 -1
- package/dist/entities/resource.d.ts +0 -42
- package/dist/entities/resource.js +0 -303
- package/dist/entities/stateful-parameter.d.ts +0 -29
- package/dist/entities/stateful-parameter.js +0 -46
- package/dist/entities/transform-parameter.d.ts +0 -4
- package/dist/entities/transform-parameter.js +0 -2
- package/dist/pty/vitest.config.d.ts +0 -2
- package/dist/pty/vitest.config.js +0 -11
- package/dist/resource/stateful-parameter.d.ts +0 -165
- package/dist/resource/stateful-parameter.js +0 -94
- package/dist/utils/spawn-2.d.ts +0 -5
- package/dist/utils/spawn-2.js +0 -7
- package/dist/utils/spawn.d.ts +0 -29
- package/dist/utils/spawn.js +0 -124
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
declare class CodifyCliSenderImpl {
|
|
5
5
|
private readonly validateIpcMessageV2;
|
|
6
6
|
requestPressKeyToContinuePrompt(message?: string): Promise<void>;
|
|
7
|
+
getCodifyCliCredentials(): Promise<string>;
|
|
7
8
|
private sendAndWaitForResponse;
|
|
8
9
|
}
|
|
9
10
|
export declare const CodifyCliSender: CodifyCliSenderImpl;
|
package/dist/messages/sender.js
CHANGED
|
@@ -17,6 +17,16 @@ class CodifyCliSenderImpl {
|
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
|
+
async getCodifyCliCredentials() {
|
|
21
|
+
const data = await this.sendAndWaitForResponse({
|
|
22
|
+
cmd: MessageCmd.CODIFY_CREDENTIALS_REQUEST,
|
|
23
|
+
data: {},
|
|
24
|
+
});
|
|
25
|
+
if (typeof data.data !== 'string') {
|
|
26
|
+
throw new Error('Expected string back from credentials request');
|
|
27
|
+
}
|
|
28
|
+
return data.data;
|
|
29
|
+
}
|
|
20
30
|
async sendAndWaitForResponse(message) {
|
|
21
31
|
return new Promise((resolve) => {
|
|
22
32
|
const requestId = nanoid(8);
|
package/dist/plugin/plugin.js
CHANGED
|
@@ -140,7 +140,7 @@ export class Plugin {
|
|
|
140
140
|
// Validate using desired/desired. If the apply was successful, no changes should be reported back.
|
|
141
141
|
// Default back desired back to current if it is not defined (for destroys only)
|
|
142
142
|
const validationPlan = await ptyLocalStorage.run(new BackgroundPty(), async () => {
|
|
143
|
-
const result = await resource.plan(plan.coreParameters, plan.desiredConfig, plan.desiredConfig ?? plan.currentConfig, plan.isStateful);
|
|
143
|
+
const result = await resource.plan(plan.coreParameters, plan.desiredConfig, plan.desiredConfig ?? plan.currentConfig, plan.isStateful, 'validationPlan');
|
|
144
144
|
await getPty().kill();
|
|
145
145
|
return result;
|
|
146
146
|
});
|
|
@@ -16,7 +16,7 @@ export declare class ResourceController<T extends StringIndexedObject> {
|
|
|
16
16
|
initialize(): Promise<void>;
|
|
17
17
|
validate(core: ResourceConfig, parameters: Partial<T>): Promise<ValidateResponseData['resourceValidations'][0]>;
|
|
18
18
|
match(resource: ResourceJson, array: Array<ResourceJson>): Promise<ResourceJson | undefined>;
|
|
19
|
-
plan(core: ResourceConfig, desired: Partial<T> | null, state: Partial<T> | null, isStateful?: boolean): Promise<Plan<T>>;
|
|
19
|
+
plan(core: ResourceConfig, desired: Partial<T> | null, state: Partial<T> | null, isStateful?: boolean, commandType?: string): Promise<Plan<T>>;
|
|
20
20
|
planDestroy(core: ResourceConfig, parameters: Partial<T>): Promise<Plan<T>>;
|
|
21
21
|
apply(plan: Plan<T>): Promise<void>;
|
|
22
22
|
import(core: ResourceConfig, parameters: Partial<T>, autoSearchAll?: boolean): Promise<Array<ResourceJson> | null>;
|
|
@@ -24,7 +24,7 @@ export declare class ResourceController<T extends StringIndexedObject> {
|
|
|
24
24
|
private applyModify;
|
|
25
25
|
private applyDestroy;
|
|
26
26
|
private validateRefreshResults;
|
|
27
|
-
private
|
|
27
|
+
private applyTransformations;
|
|
28
28
|
private addDefaultValues;
|
|
29
29
|
private removeDefaultValues;
|
|
30
30
|
private refreshNonStatefulParameters;
|
|
@@ -33,13 +33,20 @@ export class ResourceController {
|
|
|
33
33
|
}
|
|
34
34
|
async validate(core, parameters) {
|
|
35
35
|
const originalParameters = structuredClone(parameters);
|
|
36
|
-
await this.
|
|
36
|
+
await this.applyTransformations(parameters, undefined, true);
|
|
37
37
|
this.addDefaultValues(parameters);
|
|
38
38
|
if (this.schemaValidator) {
|
|
39
39
|
// Schema validator uses pre transformation parameters
|
|
40
40
|
const isValid = this.schemaValidator(
|
|
41
41
|
// @ts-expect-error Non esm package
|
|
42
|
-
cleanDeep(originalParameters, {
|
|
42
|
+
cleanDeep(originalParameters, {
|
|
43
|
+
nullValues: true,
|
|
44
|
+
undefinedValues: true,
|
|
45
|
+
emptyArrays: false,
|
|
46
|
+
emptyStrings: false,
|
|
47
|
+
emptyObjects: false,
|
|
48
|
+
NaNValues: false
|
|
49
|
+
}));
|
|
43
50
|
if (!isValid) {
|
|
44
51
|
return {
|
|
45
52
|
isValid: false,
|
|
@@ -96,26 +103,26 @@ export class ResourceController {
|
|
|
96
103
|
const originalParams = structuredClone(resource.parameters);
|
|
97
104
|
const paramsToMatch = structuredClone(resourceToMatch.parameters);
|
|
98
105
|
this.addDefaultValues(originalParams);
|
|
99
|
-
await this.
|
|
106
|
+
await this.applyTransformations(originalParams);
|
|
100
107
|
this.addDefaultValues(paramsToMatch);
|
|
101
|
-
await this.
|
|
108
|
+
await this.applyTransformations(paramsToMatch);
|
|
102
109
|
const match = parameterMatcher(originalParams, paramsToMatch);
|
|
103
110
|
if (match) {
|
|
104
111
|
return resourceToMatch;
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
114
|
}
|
|
108
|
-
async plan(core, desired, state, isStateful = false) {
|
|
115
|
+
async plan(core, desired, state, isStateful = false, commandType = 'plan') {
|
|
109
116
|
this.validatePlanInputs(core, desired, state, isStateful);
|
|
110
117
|
const context = {
|
|
111
|
-
commandType:
|
|
118
|
+
commandType: commandType,
|
|
112
119
|
isStateful,
|
|
113
120
|
originalDesiredConfig: structuredClone(desired),
|
|
114
121
|
};
|
|
115
122
|
this.addDefaultValues(desired);
|
|
116
|
-
await this.
|
|
123
|
+
await this.applyTransformations(desired);
|
|
117
124
|
this.addDefaultValues(state);
|
|
118
|
-
await this.
|
|
125
|
+
await this.applyTransformations(state);
|
|
119
126
|
// Parse data from the user supplied config
|
|
120
127
|
const parsedConfig = new ConfigParser(desired, state, this.parsedSettings.statefulParameters);
|
|
121
128
|
const { allParameters, allNonStatefulParameters, allStatefulParameters, } = parsedConfig;
|
|
@@ -149,7 +156,7 @@ export class ResourceController {
|
|
|
149
156
|
}
|
|
150
157
|
async planDestroy(core, parameters) {
|
|
151
158
|
this.addDefaultValues(parameters);
|
|
152
|
-
await this.
|
|
159
|
+
await this.applyTransformations(parameters);
|
|
153
160
|
// Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
|
|
154
161
|
const parametersToRefresh = this.settings.importAndDestroy?.refreshKeys
|
|
155
162
|
? {
|
|
@@ -204,7 +211,7 @@ export class ResourceController {
|
|
|
204
211
|
return results.filter(Boolean).flat();
|
|
205
212
|
}
|
|
206
213
|
this.addDefaultValues(parameters);
|
|
207
|
-
await this.
|
|
214
|
+
await this.applyTransformations(parameters);
|
|
208
215
|
// Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
|
|
209
216
|
const parametersToRefresh = this.getParametersToRefreshForImport(parameters, context);
|
|
210
217
|
// Parse data from the user supplied config
|
|
@@ -220,7 +227,7 @@ export class ResourceController {
|
|
|
220
227
|
const resultParametersArray = currentParametersArray
|
|
221
228
|
?.map((r, idx) => ({ ...r, ...statefulCurrentParameters[idx] }));
|
|
222
229
|
for (const result of resultParametersArray) {
|
|
223
|
-
await this.
|
|
230
|
+
await this.applyTransformations(result, { original: context.originalDesiredConfig });
|
|
224
231
|
this.removeDefaultValues(result, parameters);
|
|
225
232
|
}
|
|
226
233
|
return resultParametersArray?.map((r) => ({ core, parameters: r }));
|
|
@@ -285,7 +292,7 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
285
292
|
`);
|
|
286
293
|
}
|
|
287
294
|
}
|
|
288
|
-
async
|
|
295
|
+
async applyTransformations(config, reverse, skipConfigTransformation = false) {
|
|
289
296
|
if (!config) {
|
|
290
297
|
return;
|
|
291
298
|
}
|
|
@@ -297,7 +304,7 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
297
304
|
? await inputTransformation.from(config[key], reverse.original?.[key])
|
|
298
305
|
: await inputTransformation.to(config[key]);
|
|
299
306
|
}
|
|
300
|
-
if (this.settings.transformation) {
|
|
307
|
+
if (this.settings.transformation && !skipConfigTransformation) {
|
|
301
308
|
const transformed = reverse
|
|
302
309
|
? await this.settings.transformation.from({ ...config }, reverse.original)
|
|
303
310
|
: await this.settings.transformation.to({ ...config });
|
|
@@ -4,7 +4,7 @@ import { CreatePlan, DestroyPlan, ModifyPlan } from '../plan/plan-types.js';
|
|
|
4
4
|
import { ResourceSettings } from './resource-settings.js';
|
|
5
5
|
export interface RefreshContext<T extends StringIndexedObject> {
|
|
6
6
|
isStateful: boolean;
|
|
7
|
-
commandType: 'destroy' | 'import' | 'plan';
|
|
7
|
+
commandType: 'destroy' | 'import' | 'plan' | 'validationPlan';
|
|
8
8
|
originalDesiredConfig: Partial<T> | null;
|
|
9
9
|
}
|
|
10
10
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codify-plugin-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.178",
|
|
4
4
|
"description": "Library plugin library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"ajv": "^8.12.0",
|
|
18
18
|
"ajv-formats": "^2.1.1",
|
|
19
|
-
"codify-schemas": "1.0.
|
|
19
|
+
"codify-schemas": "1.0.77",
|
|
20
20
|
"@npmcli/promise-spawn": "^7.0.1",
|
|
21
21
|
"@homebridge/node-pty-prebuilt-multiarch": "^0.12.0-beta.5",
|
|
22
22
|
"uuid": "^10.0.0",
|
package/src/messages/sender.ts
CHANGED
|
@@ -21,6 +21,19 @@ class CodifyCliSenderImpl {
|
|
|
21
21
|
})
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
async getCodifyCliCredentials(): Promise<string> {
|
|
25
|
+
const data = await this.sendAndWaitForResponse(<IpcMessageV2>{
|
|
26
|
+
cmd: MessageCmd.CODIFY_CREDENTIALS_REQUEST,
|
|
27
|
+
data: {},
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
if (typeof data.data !== 'string') {
|
|
31
|
+
throw new Error('Expected string back from credentials request');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return data.data;
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
private async sendAndWaitForResponse(message: IpcMessageV2): Promise<IpcMessageV2> {
|
|
25
38
|
return new Promise((resolve) => {
|
|
26
39
|
const requestId = nanoid(8);
|
package/src/plugin/plugin.ts
CHANGED
|
@@ -59,14 +59,21 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
59
59
|
parameters: Partial<T>,
|
|
60
60
|
): Promise<ValidateResponseData['resourceValidations'][0]> {
|
|
61
61
|
const originalParameters = structuredClone(parameters);
|
|
62
|
-
await this.
|
|
62
|
+
await this.applyTransformations(parameters, undefined, true);
|
|
63
63
|
this.addDefaultValues(parameters);
|
|
64
64
|
|
|
65
65
|
if (this.schemaValidator) {
|
|
66
66
|
// Schema validator uses pre transformation parameters
|
|
67
67
|
const isValid = this.schemaValidator(
|
|
68
68
|
// @ts-expect-error Non esm package
|
|
69
|
-
cleanDeep(originalParameters, {
|
|
69
|
+
cleanDeep(originalParameters, {
|
|
70
|
+
nullValues: true,
|
|
71
|
+
undefinedValues: true,
|
|
72
|
+
emptyArrays: false,
|
|
73
|
+
emptyStrings: false,
|
|
74
|
+
emptyObjects: false,
|
|
75
|
+
NaNValues: false
|
|
76
|
+
})
|
|
70
77
|
);
|
|
71
78
|
|
|
72
79
|
if (!isValid) {
|
|
@@ -136,10 +143,10 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
136
143
|
const paramsToMatch = structuredClone(resourceToMatch.parameters) as Partial<T>;
|
|
137
144
|
|
|
138
145
|
this.addDefaultValues(originalParams);
|
|
139
|
-
await this.
|
|
146
|
+
await this.applyTransformations(originalParams);
|
|
140
147
|
|
|
141
148
|
this.addDefaultValues(paramsToMatch);
|
|
142
|
-
await this.
|
|
149
|
+
await this.applyTransformations(paramsToMatch);
|
|
143
150
|
|
|
144
151
|
const match = parameterMatcher(originalParams, paramsToMatch);
|
|
145
152
|
if (match) {
|
|
@@ -153,19 +160,20 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
153
160
|
desired: Partial<T> | null,
|
|
154
161
|
state: Partial<T> | null,
|
|
155
162
|
isStateful = false,
|
|
163
|
+
commandType = 'plan',
|
|
156
164
|
): Promise<Plan<T>> {
|
|
157
165
|
this.validatePlanInputs(core, desired, state, isStateful);
|
|
158
166
|
const context: RefreshContext<T> = {
|
|
159
|
-
commandType: 'plan',
|
|
167
|
+
commandType: commandType as 'plan' | 'validationPlan',
|
|
160
168
|
isStateful,
|
|
161
169
|
originalDesiredConfig: structuredClone(desired),
|
|
162
170
|
};
|
|
163
171
|
|
|
164
172
|
this.addDefaultValues(desired);
|
|
165
|
-
await this.
|
|
173
|
+
await this.applyTransformations(desired);
|
|
166
174
|
|
|
167
175
|
this.addDefaultValues(state);
|
|
168
|
-
await this.
|
|
176
|
+
await this.applyTransformations(state);
|
|
169
177
|
|
|
170
178
|
// Parse data from the user supplied config
|
|
171
179
|
const parsedConfig = new ConfigParser(desired, state, this.parsedSettings.statefulParameters)
|
|
@@ -213,7 +221,7 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
213
221
|
parameters: Partial<T>
|
|
214
222
|
): Promise<Plan<T>> {
|
|
215
223
|
this.addDefaultValues(parameters);
|
|
216
|
-
await this.
|
|
224
|
+
await this.applyTransformations(parameters);
|
|
217
225
|
|
|
218
226
|
// Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
|
|
219
227
|
const parametersToRefresh = this.settings.importAndDestroy?.refreshKeys
|
|
@@ -290,7 +298,7 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
290
298
|
}
|
|
291
299
|
|
|
292
300
|
this.addDefaultValues(parameters);
|
|
293
|
-
await this.
|
|
301
|
+
await this.applyTransformations(parameters);
|
|
294
302
|
|
|
295
303
|
// Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
|
|
296
304
|
const parametersToRefresh = this.getParametersToRefreshForImport(parameters, context);
|
|
@@ -317,7 +325,7 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
317
325
|
?.map((r, idx) => ({ ...r, ...statefulCurrentParameters[idx] }))
|
|
318
326
|
|
|
319
327
|
for (const result of resultParametersArray) {
|
|
320
|
-
await this.
|
|
328
|
+
await this.applyTransformations(result, { original: context.originalDesiredConfig });
|
|
321
329
|
this.removeDefaultValues(result, parameters);
|
|
322
330
|
}
|
|
323
331
|
|
|
@@ -400,9 +408,9 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
400
408
|
}
|
|
401
409
|
}
|
|
402
410
|
|
|
403
|
-
private async
|
|
411
|
+
private async applyTransformations(config: Partial<T> | null, reverse?: {
|
|
404
412
|
original: Partial<T> | null
|
|
405
|
-
}): Promise<void> {
|
|
413
|
+
}, skipConfigTransformation = false): Promise<void> {
|
|
406
414
|
if (!config) {
|
|
407
415
|
return;
|
|
408
416
|
}
|
|
@@ -417,7 +425,7 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
417
425
|
: await inputTransformation.to(config[key]);
|
|
418
426
|
}
|
|
419
427
|
|
|
420
|
-
if (this.settings.transformation) {
|
|
428
|
+
if (this.settings.transformation && !skipConfigTransformation) {
|
|
421
429
|
const transformed = reverse
|
|
422
430
|
? await this.settings.transformation.from({ ...config }, reverse.original)
|
|
423
431
|
: await this.settings.transformation.to({ ...config })
|
package/src/resource/resource.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { ResourceSettings } from './resource-settings.js';
|
|
|
6
6
|
|
|
7
7
|
export interface RefreshContext<T extends StringIndexedObject> {
|
|
8
8
|
isStateful: boolean;
|
|
9
|
-
commandType: 'destroy' | 'import' | 'plan';
|
|
9
|
+
commandType: 'destroy' | 'import' | 'plan' | 'validationPlan';
|
|
10
10
|
originalDesiredConfig: Partial<T> | null;
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { ParameterOperation, ResourceOperation, StringIndexedObject } from 'codify-schemas';
|
|
2
|
-
import { ParameterOptions } from './plan-types.js';
|
|
3
|
-
export interface ParameterChange<T extends StringIndexedObject> {
|
|
4
|
-
name: keyof T & string;
|
|
5
|
-
operation: ParameterOperation;
|
|
6
|
-
previousValue: any | null;
|
|
7
|
-
newValue: any | null;
|
|
8
|
-
}
|
|
9
|
-
export declare class ChangeSet<T extends StringIndexedObject> {
|
|
10
|
-
operation: ResourceOperation;
|
|
11
|
-
parameterChanges: Array<ParameterChange<T>>;
|
|
12
|
-
constructor(operation: ResourceOperation, parameterChanges: Array<ParameterChange<T>>);
|
|
13
|
-
get desiredParameters(): T;
|
|
14
|
-
get currentParameters(): T;
|
|
15
|
-
static calculateParameterChangeSet<T extends StringIndexedObject>(desired: T | null, current: T | null, options: {
|
|
16
|
-
statefulMode: boolean;
|
|
17
|
-
parameterOptions?: Record<keyof T, ParameterOptions>;
|
|
18
|
-
}): ParameterChange<T>[];
|
|
19
|
-
static combineResourceOperations(prev: ResourceOperation, next: ResourceOperation): ResourceOperation;
|
|
20
|
-
static isSame(desired: unknown, current: unknown, options?: ParameterOptions): boolean;
|
|
21
|
-
private static calculateStatefulModeChangeSet;
|
|
22
|
-
private static calculateStatelessModeChangeSet;
|
|
23
|
-
private static addDefaultValues;
|
|
24
|
-
}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { ParameterOperation, ResourceOperation } from 'codify-schemas';
|
|
2
|
-
export class ChangeSet {
|
|
3
|
-
operation;
|
|
4
|
-
parameterChanges;
|
|
5
|
-
constructor(operation, parameterChanges) {
|
|
6
|
-
this.operation = operation;
|
|
7
|
-
this.parameterChanges = parameterChanges;
|
|
8
|
-
}
|
|
9
|
-
get desiredParameters() {
|
|
10
|
-
return this.parameterChanges
|
|
11
|
-
.reduce((obj, pc) => ({
|
|
12
|
-
...obj,
|
|
13
|
-
[pc.name]: pc.newValue,
|
|
14
|
-
}), {});
|
|
15
|
-
}
|
|
16
|
-
get currentParameters() {
|
|
17
|
-
return this.parameterChanges
|
|
18
|
-
.reduce((obj, pc) => ({
|
|
19
|
-
...obj,
|
|
20
|
-
[pc.name]: pc.previousValue,
|
|
21
|
-
}), {});
|
|
22
|
-
}
|
|
23
|
-
static calculateParameterChangeSet(desired, current, options) {
|
|
24
|
-
if (options.statefulMode) {
|
|
25
|
-
return ChangeSet.calculateStatefulModeChangeSet(desired, current, options.parameterOptions);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
return ChangeSet.calculateStatelessModeChangeSet(desired, current, options.parameterOptions);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
static combineResourceOperations(prev, next) {
|
|
32
|
-
const orderOfOperations = [
|
|
33
|
-
ResourceOperation.NOOP,
|
|
34
|
-
ResourceOperation.MODIFY,
|
|
35
|
-
ResourceOperation.RECREATE,
|
|
36
|
-
ResourceOperation.CREATE,
|
|
37
|
-
ResourceOperation.DESTROY,
|
|
38
|
-
];
|
|
39
|
-
const indexPrev = orderOfOperations.indexOf(prev);
|
|
40
|
-
const indexNext = orderOfOperations.indexOf(next);
|
|
41
|
-
return orderOfOperations[Math.max(indexPrev, indexNext)];
|
|
42
|
-
}
|
|
43
|
-
static isSame(desired, current, options) {
|
|
44
|
-
if (options?.isEqual) {
|
|
45
|
-
return options.isEqual(desired, current);
|
|
46
|
-
}
|
|
47
|
-
if (Array.isArray(desired) && Array.isArray(current)) {
|
|
48
|
-
const sortedDesired = desired.map((x) => x).sort();
|
|
49
|
-
const sortedCurrent = current.map((x) => x).sort();
|
|
50
|
-
if (sortedDesired.length !== sortedCurrent.length) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
if (options?.isElementEqual) {
|
|
54
|
-
return sortedDesired.every((value, index) => options.isElementEqual(value, sortedCurrent[index]));
|
|
55
|
-
}
|
|
56
|
-
return JSON.stringify(sortedDesired) === JSON.stringify(sortedCurrent);
|
|
57
|
-
}
|
|
58
|
-
return desired === current;
|
|
59
|
-
}
|
|
60
|
-
static calculateStatefulModeChangeSet(desired, current, parameterOptions) {
|
|
61
|
-
const parameterChangeSet = new Array();
|
|
62
|
-
const _desired = Object.fromEntries(Object.entries(desired ?? {}).filter(([, v]) => v != null));
|
|
63
|
-
const _current = Object.fromEntries(Object.entries(current ?? {}).filter(([, v]) => v != null));
|
|
64
|
-
this.addDefaultValues(_desired, parameterOptions);
|
|
65
|
-
for (const [k, v] of Object.entries(_current)) {
|
|
66
|
-
if (_desired[k] == null) {
|
|
67
|
-
parameterChangeSet.push({
|
|
68
|
-
name: k,
|
|
69
|
-
previousValue: v,
|
|
70
|
-
newValue: null,
|
|
71
|
-
operation: ParameterOperation.REMOVE,
|
|
72
|
-
});
|
|
73
|
-
delete _current[k];
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
if (!ChangeSet.isSame(_desired[k], _current[k], parameterOptions?.[k])) {
|
|
77
|
-
parameterChangeSet.push({
|
|
78
|
-
name: k,
|
|
79
|
-
previousValue: v,
|
|
80
|
-
newValue: _desired[k],
|
|
81
|
-
operation: ParameterOperation.MODIFY,
|
|
82
|
-
});
|
|
83
|
-
delete _current[k];
|
|
84
|
-
delete _desired[k];
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
parameterChangeSet.push({
|
|
88
|
-
name: k,
|
|
89
|
-
previousValue: v,
|
|
90
|
-
newValue: _desired[k],
|
|
91
|
-
operation: ParameterOperation.NOOP,
|
|
92
|
-
});
|
|
93
|
-
delete _current[k];
|
|
94
|
-
delete _desired[k];
|
|
95
|
-
}
|
|
96
|
-
if (Object.keys(_current).length !== 0) {
|
|
97
|
-
throw Error('Diff algorithm error');
|
|
98
|
-
}
|
|
99
|
-
for (const [k, v] of Object.entries(_desired)) {
|
|
100
|
-
parameterChangeSet.push({
|
|
101
|
-
name: k,
|
|
102
|
-
previousValue: null,
|
|
103
|
-
newValue: v,
|
|
104
|
-
operation: ParameterOperation.ADD,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
return parameterChangeSet;
|
|
108
|
-
}
|
|
109
|
-
static calculateStatelessModeChangeSet(desired, current, parameterOptions) {
|
|
110
|
-
const parameterChangeSet = new Array();
|
|
111
|
-
const _desired = Object.fromEntries(Object.entries(desired ?? {}).filter(([, v]) => v != null));
|
|
112
|
-
const _current = Object.fromEntries(Object.entries(current ?? {}).filter(([, v]) => v != null));
|
|
113
|
-
this.addDefaultValues(_desired, parameterOptions);
|
|
114
|
-
for (const [k, v] of Object.entries(_desired)) {
|
|
115
|
-
if (_current[k] == null) {
|
|
116
|
-
parameterChangeSet.push({
|
|
117
|
-
name: k,
|
|
118
|
-
previousValue: null,
|
|
119
|
-
newValue: v,
|
|
120
|
-
operation: ParameterOperation.ADD,
|
|
121
|
-
});
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
if (!ChangeSet.isSame(_desired[k], _current[k], parameterOptions?.[k])) {
|
|
125
|
-
parameterChangeSet.push({
|
|
126
|
-
name: k,
|
|
127
|
-
previousValue: _current[k],
|
|
128
|
-
newValue: _desired[k],
|
|
129
|
-
operation: ParameterOperation.MODIFY,
|
|
130
|
-
});
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
parameterChangeSet.push({
|
|
134
|
-
name: k,
|
|
135
|
-
previousValue: v,
|
|
136
|
-
newValue: v,
|
|
137
|
-
operation: ParameterOperation.NOOP,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
return parameterChangeSet;
|
|
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
|
-
}
|
|
152
|
-
}
|
package/dist/entities/errors.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Plan } from './plan.js';
|
|
2
|
-
import { StringIndexedObject } from 'codify-schemas';
|
|
3
|
-
export interface ParameterOptions {
|
|
4
|
-
modifyOnChange?: boolean;
|
|
5
|
-
isEqual?: (desired: any, current: any) => boolean;
|
|
6
|
-
isElementEqual?: (desired: any, current: any) => boolean;
|
|
7
|
-
default?: unknown;
|
|
8
|
-
isStatefulParameter?: boolean;
|
|
9
|
-
}
|
|
10
|
-
export interface PlanOptions<T> {
|
|
11
|
-
statefulMode: boolean;
|
|
12
|
-
parameterOptions?: Record<keyof T, ParameterOptions>;
|
|
13
|
-
}
|
|
14
|
-
export interface CreatePlan<T extends StringIndexedObject> extends Plan<T> {
|
|
15
|
-
desiredConfig: T;
|
|
16
|
-
currentConfig: null;
|
|
17
|
-
}
|
|
18
|
-
export interface DestroyPlan<T extends StringIndexedObject> extends Plan<T> {
|
|
19
|
-
desiredConfig: null;
|
|
20
|
-
currentConfig: T;
|
|
21
|
-
}
|
|
22
|
-
export interface ModifyPlan<T extends StringIndexedObject> extends Plan<T> {
|
|
23
|
-
desiredConfig: T;
|
|
24
|
-
currentConfig: T;
|
|
25
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/entities/plan.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { ChangeSet } from './change-set.js';
|
|
2
|
-
import { ApplyRequestData, PlanResponseData, ResourceConfig, StringIndexedObject } from 'codify-schemas';
|
|
3
|
-
import { PlanOptions } from './plan-types.js';
|
|
4
|
-
export declare class Plan<T extends StringIndexedObject> {
|
|
5
|
-
id: string;
|
|
6
|
-
changeSet: ChangeSet<T>;
|
|
7
|
-
resourceMetadata: ResourceConfig;
|
|
8
|
-
constructor(id: string, changeSet: ChangeSet<T>, resourceMetadata: ResourceConfig);
|
|
9
|
-
static create<T extends StringIndexedObject>(desiredParameters: Partial<T> | null, currentParameters: Partial<T> | null, resourceMetadata: ResourceConfig, options: PlanOptions<T>): Plan<T>;
|
|
10
|
-
getResourceType(): string;
|
|
11
|
-
static fromResponse<T extends ResourceConfig>(data: ApplyRequestData['plan'], defaultValues?: Partial<Record<keyof T, unknown>>): Plan<T>;
|
|
12
|
-
get desiredConfig(): T | null;
|
|
13
|
-
get currentConfig(): T | null;
|
|
14
|
-
toResponse(): PlanResponseData;
|
|
15
|
-
}
|