codify-plugin-lib 1.0.28 → 1.0.29
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.js +13 -17
- package/dist/entities/plan.d.ts +1 -1
- package/dist/entities/plan.js +3 -7
- package/dist/entities/plugin.d.ts +2 -2
- package/dist/entities/plugin.js +1 -5
- package/dist/entities/resource.d.ts +3 -3
- package/dist/entities/resource.js +19 -23
- package/dist/entities/stateful-parameter.d.ts +2 -2
- package/dist/entities/stateful-parameter.js +1 -5
- package/dist/index.d.ts +8 -7
- package/dist/index.js +10 -27
- package/dist/messages/handlers.d.ts +1 -1
- package/dist/messages/handlers.js +16 -23
- package/dist/utils/test-utils.d.ts +1 -1
- package/dist/utils/test-utils.js +1 -5
- package/dist/utils/utils.d.ts +2 -4
- package/dist/utils/utils.js +8 -23
- package/package.json +7 -13
- package/src/entities/change-set.test.ts +1 -1
- package/src/entities/plan.ts +1 -1
- package/src/entities/plugin.ts +2 -2
- package/src/entities/resource.test.ts +1 -2
- package/src/entities/resource.ts +7 -7
- package/src/entities/stateful-parameter.ts +2 -2
- package/src/index.test.ts +1 -1
- package/src/index.ts +9 -8
- package/src/messages/handlers.test.ts +2 -2
- package/src/messages/handlers.ts +7 -6
- package/src/utils/test-utils.test.ts +13 -13
- package/src/utils/utils.ts +4 -28
- package/tsconfig.json +1 -1
- package/.mocharc.json +0 -11
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.ChangeSet = void 0;
|
|
4
|
-
const codify_schemas_1 = require("codify-schemas");
|
|
5
|
-
class ChangeSet {
|
|
1
|
+
import { ParameterOperation, ResourceOperation } from 'codify-schemas';
|
|
2
|
+
export class ChangeSet {
|
|
6
3
|
operation;
|
|
7
4
|
parameterChanges;
|
|
8
5
|
constructor(operation, parameterChanges) {
|
|
@@ -15,12 +12,12 @@ class ChangeSet {
|
|
|
15
12
|
.map(([k, v]) => {
|
|
16
13
|
return {
|
|
17
14
|
name: k,
|
|
18
|
-
operation:
|
|
15
|
+
operation: ParameterOperation.ADD,
|
|
19
16
|
previousValue: null,
|
|
20
17
|
newValue: v,
|
|
21
18
|
};
|
|
22
19
|
});
|
|
23
|
-
return new ChangeSet(
|
|
20
|
+
return new ChangeSet(ResourceOperation.CREATE, parameterChangeSet);
|
|
24
21
|
}
|
|
25
22
|
static calculateParameterChangeSet(prev, next) {
|
|
26
23
|
const parameterChangeSet = new Array();
|
|
@@ -34,7 +31,7 @@ class ChangeSet {
|
|
|
34
31
|
name: k,
|
|
35
32
|
previousValue: v,
|
|
36
33
|
newValue: null,
|
|
37
|
-
operation:
|
|
34
|
+
operation: ParameterOperation.REMOVE,
|
|
38
35
|
});
|
|
39
36
|
delete filteredPrev[k];
|
|
40
37
|
continue;
|
|
@@ -44,7 +41,7 @@ class ChangeSet {
|
|
|
44
41
|
name: k,
|
|
45
42
|
previousValue: v,
|
|
46
43
|
newValue: filteredNext[k],
|
|
47
|
-
operation:
|
|
44
|
+
operation: ParameterOperation.MODIFY,
|
|
48
45
|
});
|
|
49
46
|
delete filteredPrev[k];
|
|
50
47
|
delete filteredNext[k];
|
|
@@ -54,7 +51,7 @@ class ChangeSet {
|
|
|
54
51
|
name: k,
|
|
55
52
|
previousValue: v,
|
|
56
53
|
newValue: filteredNext[k],
|
|
57
|
-
operation:
|
|
54
|
+
operation: ParameterOperation.NOOP,
|
|
58
55
|
});
|
|
59
56
|
delete filteredPrev[k];
|
|
60
57
|
delete filteredNext[k];
|
|
@@ -67,18 +64,18 @@ class ChangeSet {
|
|
|
67
64
|
name: k,
|
|
68
65
|
previousValue: null,
|
|
69
66
|
newValue: v,
|
|
70
|
-
operation:
|
|
67
|
+
operation: ParameterOperation.ADD,
|
|
71
68
|
});
|
|
72
69
|
}
|
|
73
70
|
return parameterChangeSet;
|
|
74
71
|
}
|
|
75
72
|
static combineResourceOperations(prev, next) {
|
|
76
73
|
const orderOfOperations = [
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
ResourceOperation.NOOP,
|
|
75
|
+
ResourceOperation.MODIFY,
|
|
76
|
+
ResourceOperation.RECREATE,
|
|
77
|
+
ResourceOperation.CREATE,
|
|
78
|
+
ResourceOperation.DESTROY,
|
|
82
79
|
];
|
|
83
80
|
const indexPrev = orderOfOperations.indexOf(prev);
|
|
84
81
|
const indexNext = orderOfOperations.indexOf(next);
|
|
@@ -93,4 +90,3 @@ class ChangeSet {
|
|
|
93
90
|
return a === b;
|
|
94
91
|
}
|
|
95
92
|
}
|
|
96
|
-
exports.ChangeSet = ChangeSet;
|
package/dist/entities/plan.d.ts
CHANGED
package/dist/entities/plan.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.Plan = void 0;
|
|
4
|
-
const crypto_1 = require("crypto");
|
|
5
|
-
class Plan {
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
export class Plan {
|
|
6
3
|
id;
|
|
7
4
|
changeSet;
|
|
8
5
|
resourceConfig;
|
|
@@ -12,7 +9,7 @@ class Plan {
|
|
|
12
9
|
this.resourceConfig = resourceConfig;
|
|
13
10
|
}
|
|
14
11
|
static create(changeSet, resourceConfig) {
|
|
15
|
-
return new Plan(
|
|
12
|
+
return new Plan(randomUUID(), changeSet, resourceConfig);
|
|
16
13
|
}
|
|
17
14
|
getResourceType() {
|
|
18
15
|
return this.resourceConfig.type;
|
|
@@ -27,4 +24,3 @@ class Plan {
|
|
|
27
24
|
};
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
|
-
exports.Plan = Plan;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Resource } from './resource';
|
|
1
|
+
import { Resource } from './resource.js';
|
|
2
2
|
import { ApplyRequestData, PlanRequestData, PlanResponseData, ResourceConfig, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
|
|
3
|
-
import { Plan } from './plan';
|
|
3
|
+
import { Plan } from './plan.js';
|
|
4
4
|
export declare class Plugin {
|
|
5
5
|
resources: Map<string, Resource<ResourceConfig>>;
|
|
6
6
|
planStorage: Map<string, Plan<ResourceConfig>>;
|
package/dist/entities/plugin.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Plugin = void 0;
|
|
4
|
-
class Plugin {
|
|
1
|
+
export class Plugin {
|
|
5
2
|
resources;
|
|
6
3
|
planStorage;
|
|
7
4
|
constructor(resources) {
|
|
@@ -42,4 +39,3 @@ class Plugin {
|
|
|
42
39
|
}
|
|
43
40
|
async crossValidateResources(configs) { }
|
|
44
41
|
}
|
|
45
|
-
exports.Plugin = Plugin;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ResourceConfig, ResourceOperation } from 'codify-schemas';
|
|
2
|
-
import { ParameterChange } from './change-set';
|
|
3
|
-
import { Plan } from './plan';
|
|
4
|
-
import { StatefulParameter } from './stateful-parameter';
|
|
2
|
+
import { ParameterChange } from './change-set.js';
|
|
3
|
+
import { Plan } from './plan.js';
|
|
4
|
+
import { StatefulParameter } from './stateful-parameter.js';
|
|
5
5
|
export declare abstract class Resource<T extends ResourceConfig> {
|
|
6
6
|
private dependencies;
|
|
7
7
|
private statefulParameters;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const change_set_1 = require("./change-set");
|
|
6
|
-
const plan_1 = require("./plan");
|
|
7
|
-
class Resource {
|
|
1
|
+
import { ParameterOperation, ResourceOperation } from 'codify-schemas';
|
|
2
|
+
import { ChangeSet } from './change-set.js';
|
|
3
|
+
import { Plan } from './plan.js';
|
|
4
|
+
export class Resource {
|
|
8
5
|
dependencies;
|
|
9
6
|
statefulParameters = new Map();
|
|
10
7
|
constructor(dependencies = []) {
|
|
@@ -15,7 +12,7 @@ class Resource {
|
|
|
15
12
|
await this.validate(desiredConfig);
|
|
16
13
|
const currentConfig = await this.getCurrentConfig(desiredConfig);
|
|
17
14
|
if (!currentConfig) {
|
|
18
|
-
return
|
|
15
|
+
return Plan.create(ChangeSet.createForNullCurrentConfig(desiredConfig), desiredConfig);
|
|
19
16
|
}
|
|
20
17
|
const desiredConfigStatefulParameters = [...this.statefulParameters.values()]
|
|
21
18
|
.filter((sp) => desiredConfig[sp.name] !== undefined);
|
|
@@ -25,25 +22,25 @@ class Resource {
|
|
|
25
22
|
currentConfig[statefulParameter.name] = parameterCurrentStatus;
|
|
26
23
|
}
|
|
27
24
|
}
|
|
28
|
-
const parameterChangeSet =
|
|
25
|
+
const parameterChangeSet = ChangeSet.calculateParameterChangeSet(currentConfig, desiredConfig);
|
|
29
26
|
const resourceOperation = parameterChangeSet
|
|
30
|
-
.filter((change) => change.operation !==
|
|
27
|
+
.filter((change) => change.operation !== ParameterOperation.NOOP)
|
|
31
28
|
.reduce((operation, curr) => {
|
|
32
29
|
const newOperation = !this.statefulParameters.has(curr.name)
|
|
33
30
|
? this.calculateOperation(curr)
|
|
34
|
-
:
|
|
35
|
-
return
|
|
36
|
-
},
|
|
37
|
-
return
|
|
31
|
+
: ResourceOperation.MODIFY;
|
|
32
|
+
return ChangeSet.combineResourceOperations(operation, newOperation);
|
|
33
|
+
}, ResourceOperation.NOOP);
|
|
34
|
+
return Plan.create(new ChangeSet(resourceOperation, parameterChangeSet), desiredConfig);
|
|
38
35
|
}
|
|
39
36
|
async apply(plan) {
|
|
40
37
|
if (plan.getResourceType() !== this.getTypeId()) {
|
|
41
38
|
throw new Error(`Internal error: Plan set to wrong resource during apply. Expected ${this.getTypeId()} but got: ${plan.getResourceType()}`);
|
|
42
39
|
}
|
|
43
40
|
switch (plan.changeSet.operation) {
|
|
44
|
-
case
|
|
41
|
+
case ResourceOperation.MODIFY: {
|
|
45
42
|
const parameterChanges = plan.changeSet.parameterChanges
|
|
46
|
-
.filter((c) => c.operation !==
|
|
43
|
+
.filter((c) => c.operation !== ParameterOperation.NOOP);
|
|
47
44
|
const statelessParameterChanges = parameterChanges.filter((pc) => !this.statefulParameters.has(pc.name));
|
|
48
45
|
if (statelessParameterChanges.length > 0) {
|
|
49
46
|
await this.applyModify(plan);
|
|
@@ -52,15 +49,15 @@ class Resource {
|
|
|
52
49
|
for (const parameterChange of statefulParameterChanges) {
|
|
53
50
|
const statefulParameter = this.statefulParameters.get(parameterChange.name);
|
|
54
51
|
switch (parameterChange.operation) {
|
|
55
|
-
case
|
|
52
|
+
case ParameterOperation.ADD: {
|
|
56
53
|
await statefulParameter.applyAdd(parameterChange, plan);
|
|
57
54
|
break;
|
|
58
55
|
}
|
|
59
|
-
case
|
|
56
|
+
case ParameterOperation.MODIFY: {
|
|
60
57
|
await statefulParameter.applyModify(parameterChange, plan);
|
|
61
58
|
break;
|
|
62
59
|
}
|
|
63
|
-
case
|
|
60
|
+
case ParameterOperation.REMOVE: {
|
|
64
61
|
await statefulParameter.applyRemove(parameterChange, plan);
|
|
65
62
|
break;
|
|
66
63
|
}
|
|
@@ -68,7 +65,7 @@ class Resource {
|
|
|
68
65
|
}
|
|
69
66
|
return;
|
|
70
67
|
}
|
|
71
|
-
case
|
|
68
|
+
case ResourceOperation.CREATE: {
|
|
72
69
|
await this.applyCreate(plan);
|
|
73
70
|
const statefulParameterChanges = plan.changeSet.parameterChanges
|
|
74
71
|
.filter((pc) => this.statefulParameters.has(pc.name));
|
|
@@ -78,12 +75,11 @@ class Resource {
|
|
|
78
75
|
}
|
|
79
76
|
return;
|
|
80
77
|
}
|
|
81
|
-
case
|
|
82
|
-
case
|
|
78
|
+
case ResourceOperation.RECREATE: return this.applyRecreate(plan);
|
|
79
|
+
case ResourceOperation.DESTROY: return this.applyDestroy(plan);
|
|
83
80
|
}
|
|
84
81
|
}
|
|
85
82
|
registerStatefulParameter(parameter) {
|
|
86
83
|
this.statefulParameters.set(parameter.name, parameter);
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
|
-
exports.Resource = Resource;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ParameterChange } from './change-set';
|
|
2
|
-
import { Plan } from './plan';
|
|
1
|
+
import { ParameterChange } from './change-set.js';
|
|
2
|
+
import { Plan } from './plan.js';
|
|
3
3
|
import { ResourceConfig } from 'codify-schemas';
|
|
4
4
|
export declare abstract class StatefulParameter<T extends ResourceConfig, K extends keyof T> {
|
|
5
5
|
abstract get name(): K;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Plugin } from './entities/plugin';
|
|
2
|
-
export * from './entities/resource';
|
|
3
|
-
export * from './entities/plugin';
|
|
4
|
-
export * from './entities/change-set';
|
|
5
|
-
export * from './entities/plan';
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './utils/utils';
|
|
1
|
+
import { Plugin } from './entities/plugin.js';
|
|
2
|
+
export * from './entities/resource.js';
|
|
3
|
+
export * from './entities/plugin.js';
|
|
4
|
+
export * from './entities/change-set.js';
|
|
5
|
+
export * from './entities/plan.js';
|
|
6
|
+
export * from './entities/stateful-parameter.js';
|
|
7
|
+
export * from './utils/test-utils.js';
|
|
8
|
+
export * from './utils/utils.js';
|
|
8
9
|
export declare function runPlugin(plugin: Plugin): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.runPlugin = void 0;
|
|
18
|
-
const handlers_1 = require("./messages/handlers");
|
|
19
|
-
__exportStar(require("./entities/resource"), exports);
|
|
20
|
-
__exportStar(require("./entities/plugin"), exports);
|
|
21
|
-
__exportStar(require("./entities/change-set"), exports);
|
|
22
|
-
__exportStar(require("./entities/plan"), exports);
|
|
23
|
-
__exportStar(require("./utils/test-utils"), exports);
|
|
24
|
-
__exportStar(require("./utils/utils"), exports);
|
|
25
|
-
async function runPlugin(plugin) {
|
|
1
|
+
import { MessageHandler } from './messages/handlers.js';
|
|
2
|
+
export * from './entities/resource.js';
|
|
3
|
+
export * from './entities/plugin.js';
|
|
4
|
+
export * from './entities/change-set.js';
|
|
5
|
+
export * from './entities/plan.js';
|
|
6
|
+
export * from './entities/stateful-parameter.js';
|
|
7
|
+
export * from './utils/test-utils.js';
|
|
8
|
+
export * from './utils/utils.js';
|
|
9
|
+
export async function runPlugin(plugin) {
|
|
26
10
|
await plugin.onInitialize();
|
|
27
|
-
const messageHandler = new
|
|
11
|
+
const messageHandler = new MessageHandler(plugin);
|
|
28
12
|
process.on('message', (message) => messageHandler.onMessage(message));
|
|
29
13
|
}
|
|
30
|
-
exports.runPlugin = runPlugin;
|
|
@@ -1,44 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MessageHandler = void 0;
|
|
7
|
-
const _2020_1 = __importDefault(require("ajv/dist/2020"));
|
|
8
|
-
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
9
|
-
const codify_schemas_1 = require("codify-schemas");
|
|
1
|
+
import Ajv from 'ajv';
|
|
2
|
+
import addFormats from 'ajv-formats';
|
|
3
|
+
import { IpcMessageSchema, ResourceSchema, ValidateRequestDataSchema, ValidateResponseDataSchema, MessageStatus, PlanRequestDataSchema, PlanResponseDataSchema, ApplyRequestDataSchema, ApplyResponseDataSchema } from 'codify-schemas';
|
|
10
4
|
const SupportedRequests = {
|
|
11
5
|
'validate': {
|
|
12
|
-
requestValidator:
|
|
13
|
-
responseValidator:
|
|
6
|
+
requestValidator: ValidateRequestDataSchema,
|
|
7
|
+
responseValidator: ValidateResponseDataSchema,
|
|
14
8
|
handler: async (plugin, data) => plugin.validate(data)
|
|
15
9
|
},
|
|
16
10
|
'plan': {
|
|
17
|
-
requestValidator:
|
|
18
|
-
responseValidator:
|
|
11
|
+
requestValidator: PlanRequestDataSchema,
|
|
12
|
+
responseValidator: PlanResponseDataSchema,
|
|
19
13
|
handler: async (plugin, data) => plugin.plan(data)
|
|
20
14
|
},
|
|
21
15
|
'apply': {
|
|
22
|
-
requestValidator:
|
|
23
|
-
responseValidator:
|
|
16
|
+
requestValidator: ApplyRequestDataSchema,
|
|
17
|
+
responseValidator: ApplyResponseDataSchema,
|
|
24
18
|
handler: async (plugin, data) => {
|
|
25
19
|
await plugin.apply(data);
|
|
26
20
|
return null;
|
|
27
21
|
}
|
|
28
22
|
}
|
|
29
23
|
};
|
|
30
|
-
class MessageHandler {
|
|
24
|
+
export class MessageHandler {
|
|
31
25
|
ajv;
|
|
32
26
|
plugin;
|
|
33
27
|
messageSchemaValidator;
|
|
34
28
|
requestValidators;
|
|
35
29
|
responseValidators;
|
|
36
30
|
constructor(plugin) {
|
|
37
|
-
this.ajv = new
|
|
38
|
-
|
|
39
|
-
this.ajv.addSchema(
|
|
31
|
+
this.ajv = new Ajv.default({ strict: true, code: { esm: true } });
|
|
32
|
+
addFormats.default(this.ajv);
|
|
33
|
+
this.ajv.addSchema(ResourceSchema);
|
|
40
34
|
this.plugin = plugin;
|
|
41
|
-
this.messageSchemaValidator = this.ajv.compile(
|
|
35
|
+
this.messageSchemaValidator = this.ajv.compile(IpcMessageSchema);
|
|
42
36
|
this.requestValidators = new Map(Object.entries(SupportedRequests)
|
|
43
37
|
.map(([k, v]) => [k, this.ajv.compile(v.requestValidator)]));
|
|
44
38
|
this.responseValidators = new Map(Object.entries(SupportedRequests)
|
|
@@ -62,7 +56,7 @@ class MessageHandler {
|
|
|
62
56
|
catch (e) {
|
|
63
57
|
process.send({
|
|
64
58
|
cmd: message.cmd + '_Response',
|
|
65
|
-
status:
|
|
59
|
+
status: MessageStatus.ERROR,
|
|
66
60
|
data: e.message,
|
|
67
61
|
});
|
|
68
62
|
return;
|
|
@@ -73,7 +67,7 @@ class MessageHandler {
|
|
|
73
67
|
}
|
|
74
68
|
process.send({
|
|
75
69
|
cmd: message.cmd + '_Response',
|
|
76
|
-
status:
|
|
70
|
+
status: MessageStatus.SUCCESS,
|
|
77
71
|
data: result,
|
|
78
72
|
});
|
|
79
73
|
}
|
|
@@ -81,4 +75,3 @@ class MessageHandler {
|
|
|
81
75
|
return this.messageSchemaValidator(message);
|
|
82
76
|
}
|
|
83
77
|
}
|
|
84
|
-
exports.MessageHandler = MessageHandler;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import { ChildProcess } from 'child_process';
|
|
3
3
|
export declare class CodifyTestUtils {
|
|
4
4
|
static sendMessageToProcessAwaitResponse(process: ChildProcess, message: any): Promise<any>;
|
package/dist/utils/test-utils.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CodifyTestUtils = void 0;
|
|
4
|
-
class CodifyTestUtils {
|
|
1
|
+
export class CodifyTestUtils {
|
|
5
2
|
static sendMessageToProcessAwaitResponse(process, message) {
|
|
6
3
|
return new Promise((resolve, reject) => {
|
|
7
4
|
process.on('message', (response) => {
|
|
@@ -18,4 +15,3 @@ class CodifyTestUtils {
|
|
|
18
15
|
});
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
exports.CodifyTestUtils = CodifyTestUtils;
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import { SpawnOptions } from 'child_process';
|
|
3
3
|
export declare enum SpawnStatus {
|
|
4
4
|
SUCCESS = "success",
|
|
@@ -12,8 +12,6 @@ type CodifySpawnOptions = {
|
|
|
12
12
|
cwd?: string;
|
|
13
13
|
stdioString?: boolean;
|
|
14
14
|
} & SpawnOptions;
|
|
15
|
-
export declare function codifySpawn(cmd: string, args?: string[], opts?: Omit<CodifySpawnOptions, 'stdio' | 'stdioString'>
|
|
16
|
-
throws?: boolean;
|
|
17
|
-
}, extras?: Record<any, any>): Promise<SpawnResult>;
|
|
15
|
+
export declare function codifySpawn(cmd: string, args?: string[], opts?: Omit<CodifySpawnOptions, 'stdio' | 'stdioString' | 'shell'>, extras?: Record<any, any>): Promise<SpawnResult>;
|
|
18
16
|
export declare function isDebug(): boolean;
|
|
19
17
|
export {};
|
package/dist/utils/utils.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.isDebug = exports.codifySpawn = exports.SpawnStatus = void 0;
|
|
7
|
-
const promise_spawn_1 = __importDefault(require("@npmcli/promise-spawn"));
|
|
8
|
-
var SpawnStatus;
|
|
1
|
+
import promiseSpawn from '@npmcli/promise-spawn';
|
|
2
|
+
export var SpawnStatus;
|
|
9
3
|
(function (SpawnStatus) {
|
|
10
4
|
SpawnStatus["SUCCESS"] = "success";
|
|
11
5
|
SpawnStatus["ERROR"] = "error";
|
|
12
|
-
})(SpawnStatus || (
|
|
13
|
-
async function codifySpawn(cmd, args, opts, extras) {
|
|
6
|
+
})(SpawnStatus || (SpawnStatus = {}));
|
|
7
|
+
export async function codifySpawn(cmd, args, opts, extras) {
|
|
14
8
|
try {
|
|
15
|
-
const result = await (
|
|
9
|
+
const result = await promiseSpawn(cmd, args ?? [], { ...opts, stdio: 'pipe', stdioString: true, shell: true }, extras);
|
|
16
10
|
if (isDebug()) {
|
|
17
11
|
console.log(`codifySpawn result for: ${cmd}`);
|
|
18
12
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -25,22 +19,13 @@ async function codifySpawn(cmd, args, opts, extras) {
|
|
|
25
19
|
data: status === SpawnStatus.SUCCESS ? result.stdout : result.stderr
|
|
26
20
|
};
|
|
27
21
|
}
|
|
28
|
-
catch (
|
|
29
|
-
const shouldThrow = opts?.throws ?? true;
|
|
30
|
-
if (isDebug() || shouldThrow) {
|
|
31
|
-
console.error(`CodifySpawn Error for command ${cmd} ${args}`, error);
|
|
32
|
-
}
|
|
33
|
-
if (shouldThrow) {
|
|
34
|
-
throw error;
|
|
35
|
-
}
|
|
22
|
+
catch (e) {
|
|
36
23
|
return {
|
|
37
24
|
status: SpawnStatus.ERROR,
|
|
38
|
-
data:
|
|
25
|
+
data: e,
|
|
39
26
|
};
|
|
40
27
|
}
|
|
41
28
|
}
|
|
42
|
-
|
|
43
|
-
function isDebug() {
|
|
29
|
+
export function isDebug() {
|
|
44
30
|
return process.env.DEBUG != null && process.env.DEBUG.includes('codify');
|
|
45
31
|
}
|
|
46
|
-
exports.isDebug = isDebug;
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codify-plugin-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.29",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
7
8
|
"scripts": {
|
|
8
|
-
"test": "
|
|
9
|
+
"test": "vitest",
|
|
9
10
|
"prepublish": "tsc"
|
|
10
11
|
},
|
|
11
12
|
"keywords": [],
|
|
@@ -14,30 +15,23 @@
|
|
|
14
15
|
"dependencies": {
|
|
15
16
|
"ajv": "^8.12.0",
|
|
16
17
|
"ajv-formats": "^2.1.1",
|
|
17
|
-
"codify-schemas": "
|
|
18
|
+
"codify-schemas": "../codify-schemas",
|
|
18
19
|
"@npmcli/promise-spawn": "^7.0.1"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
22
|
"@oclif/prettier-config": "^0.2.1",
|
|
22
23
|
"@oclif/test": "^3",
|
|
23
24
|
"@types/npmcli__promise-spawn": "^6.0.3",
|
|
24
|
-
"@types/chai": "^4",
|
|
25
|
-
"@types/chai-as-promised": "^7.1.7",
|
|
26
|
-
"@types/mocha": "^9.0.0",
|
|
27
25
|
"@types/node": "^18",
|
|
28
26
|
"@types/semver": "^7.5.4",
|
|
29
27
|
"@types/sinon": "^17.0.3",
|
|
30
|
-
"@types/sinon-chai": "^3.2.12",
|
|
31
|
-
"chai": "^4",
|
|
32
28
|
"chai-as-promised": "^7.1.1",
|
|
29
|
+
"vitest": "^1.4.0",
|
|
30
|
+
"vitest-mock-extended": "^1.3.1",
|
|
31
|
+
"sinon": "^17.0.1",
|
|
33
32
|
"eslint": "^8.51.0",
|
|
34
33
|
"eslint-config-oclif": "^5",
|
|
35
34
|
"eslint-config-oclif-typescript": "^3",
|
|
36
|
-
"mocha": "^10",
|
|
37
|
-
"mock-fs": "^5.2.0",
|
|
38
|
-
"sinon": "^17.0.1",
|
|
39
|
-
"sinon-chai": "^3.7.0",
|
|
40
|
-
"oclif": "^4.0.0",
|
|
41
35
|
"shx": "^0.3.3",
|
|
42
36
|
"ts-node": "^10.9.1",
|
|
43
37
|
"tsc-watch": "^6.0.4",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChangeSet } from './change-set';
|
|
2
|
-
import { expect } from 'chai';
|
|
3
2
|
import { ParameterOperation, ResourceOperation } from 'codify-schemas';
|
|
3
|
+
import { describe, it, expect } from 'vitest';
|
|
4
4
|
|
|
5
5
|
describe('Change set tests', () => {
|
|
6
6
|
it ('Correctly diffs two resource configs (modify)', () => {
|
package/src/entities/plan.ts
CHANGED
package/src/entities/plugin.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Resource } from './resource';
|
|
1
|
+
import { Resource } from './resource.js';
|
|
2
2
|
import {
|
|
3
3
|
ApplyRequestData,
|
|
4
4
|
PlanRequestData,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
ValidateRequestData,
|
|
8
8
|
ValidateResponseData
|
|
9
9
|
} from 'codify-schemas';
|
|
10
|
-
import { Plan } from './plan';
|
|
10
|
+
import { Plan } from './plan.js';
|
|
11
11
|
|
|
12
12
|
export class Plugin {
|
|
13
13
|
planStorage: Map<string, Plan<ResourceConfig>>;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { describe } from 'mocha';
|
|
2
1
|
import { Resource } from './resource';
|
|
3
2
|
import { ParameterOperation, ResourceConfig, ResourceOperation } from 'codify-schemas';
|
|
4
3
|
import { ChangeSet, ParameterChange } from './change-set';
|
|
5
4
|
import { spy } from 'sinon';
|
|
6
|
-
import { expect } from 'chai';
|
|
7
5
|
import { Plan } from './plan';
|
|
8
6
|
import { StatefulParameter } from './stateful-parameter';
|
|
7
|
+
import { describe, it, expect } from 'vitest'
|
|
9
8
|
|
|
10
9
|
class TestResource extends Resource<TestConfig> {
|
|
11
10
|
applyCreate(plan: Plan<TestConfig>): Promise<void> {
|
package/src/entities/resource.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ParameterOperation, ResourceConfig, ResourceOperation } from 'codify-schemas';
|
|
2
|
-
import { ChangeSet, ParameterChange } from './change-set';
|
|
3
|
-
import { Plan } from './plan';
|
|
4
|
-
import { StatefulParameter } from './stateful-parameter';
|
|
2
|
+
import { ChangeSet, ParameterChange } from './change-set.js';
|
|
3
|
+
import { Plan } from './plan.js';
|
|
4
|
+
import { StatefulParameter } from './stateful-parameter.js';
|
|
5
5
|
|
|
6
6
|
export abstract class Resource<T extends ResourceConfig> {
|
|
7
7
|
|
|
@@ -65,14 +65,14 @@ export abstract class Resource<T extends ResourceConfig> {
|
|
|
65
65
|
switch (plan.changeSet.operation) {
|
|
66
66
|
case ResourceOperation.MODIFY: {
|
|
67
67
|
const parameterChanges = plan.changeSet.parameterChanges
|
|
68
|
-
.filter((c) => c.operation !== ParameterOperation.NOOP);
|
|
68
|
+
.filter((c: ParameterChange) => c.operation !== ParameterOperation.NOOP);
|
|
69
69
|
|
|
70
|
-
const statelessParameterChanges = parameterChanges.filter((pc) => !this.statefulParameters.has(pc.name))
|
|
70
|
+
const statelessParameterChanges = parameterChanges.filter((pc: ParameterChange) => !this.statefulParameters.has(pc.name))
|
|
71
71
|
if (statelessParameterChanges.length > 0) {
|
|
72
72
|
await this.applyModify(plan);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const statefulParameterChanges = parameterChanges.filter((pc) => this.statefulParameters.has(pc.name))
|
|
75
|
+
const statefulParameterChanges = parameterChanges.filter((pc: ParameterChange) => this.statefulParameters.has(pc.name))
|
|
76
76
|
for (const parameterChange of statefulParameterChanges) {
|
|
77
77
|
const statefulParameter = this.statefulParameters.get(parameterChange.name)!;
|
|
78
78
|
switch (parameterChange.operation) {
|
|
@@ -96,7 +96,7 @@ export abstract class Resource<T extends ResourceConfig> {
|
|
|
96
96
|
case ResourceOperation.CREATE: {
|
|
97
97
|
await this.applyCreate(plan);
|
|
98
98
|
const statefulParameterChanges = plan.changeSet.parameterChanges
|
|
99
|
-
.filter((pc) => this.statefulParameters.has(pc.name))
|
|
99
|
+
.filter((pc: ParameterChange) => this.statefulParameters.has(pc.name))
|
|
100
100
|
|
|
101
101
|
for (const parameterChange of statefulParameterChanges) {
|
|
102
102
|
const statefulParameter = this.statefulParameters.get(parameterChange.name)!;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ParameterChange } from './change-set';
|
|
2
|
-
import { Plan } from './plan';
|
|
1
|
+
import { ParameterChange } from './change-set.js';
|
|
2
|
+
import { Plan } from './plan.js';
|
|
3
3
|
import { ResourceConfig } from 'codify-schemas';
|
|
4
4
|
|
|
5
5
|
export abstract class StatefulParameter<T extends ResourceConfig, K extends keyof T> {
|
package/src/index.test.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { Plugin } from './entities/plugin';
|
|
2
|
-
import { MessageHandler } from './messages/handlers';
|
|
1
|
+
import { Plugin } from './entities/plugin.js';
|
|
2
|
+
import { MessageHandler } from './messages/handlers.js';
|
|
3
3
|
|
|
4
|
-
export * from './entities/resource'
|
|
5
|
-
export * from './entities/plugin'
|
|
6
|
-
export * from './entities/change-set'
|
|
7
|
-
export * from './entities/plan'
|
|
8
|
-
export * from './
|
|
9
|
-
export * from './utils/utils'
|
|
4
|
+
export * from './entities/resource.js'
|
|
5
|
+
export * from './entities/plugin.js'
|
|
6
|
+
export * from './entities/change-set.js'
|
|
7
|
+
export * from './entities/plan.js'
|
|
8
|
+
export * from './entities/stateful-parameter.js'
|
|
10
9
|
|
|
10
|
+
export * from './utils/test-utils.js'
|
|
11
|
+
export * from './utils/utils.js'
|
|
11
12
|
|
|
12
13
|
export async function runPlugin(plugin: Plugin) {
|
|
13
14
|
await plugin.onInitialize();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MessageHandler } from './handlers';
|
|
2
|
-
import { createStubInstance } from 'sinon';
|
|
3
2
|
import { Plugin } from '../entities/plugin';
|
|
4
|
-
import { expect } from '
|
|
3
|
+
import { describe, it, expect } from 'vitest';
|
|
4
|
+
import { createStubInstance } from 'sinon';
|
|
5
5
|
|
|
6
6
|
describe('Message handler tests', () => {
|
|
7
7
|
it('handles plan requests', async () => {
|
package/src/messages/handlers.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Plugin } from '../entities/plugin';
|
|
1
|
+
import Ajv, { SchemaObject, ValidateFunction } from 'ajv';
|
|
2
|
+
import { Plugin } from '../entities/plugin.js';
|
|
3
3
|
import addFormats from 'ajv-formats';
|
|
4
4
|
import {
|
|
5
5
|
IpcMessage,
|
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
MessageStatus,
|
|
11
11
|
PlanRequestDataSchema,
|
|
12
12
|
PlanResponseDataSchema,
|
|
13
|
-
ApplyRequestDataSchema,
|
|
13
|
+
ApplyRequestDataSchema,
|
|
14
|
+
ApplyResponseDataSchema
|
|
14
15
|
} from 'codify-schemas';
|
|
15
16
|
|
|
16
17
|
const SupportedRequests: Record<string, { requestValidator: SchemaObject; responseValidator: SchemaObject; handler: (plugin: Plugin, data: any) => Promise<unknown> }> = {
|
|
@@ -35,15 +36,15 @@ const SupportedRequests: Record<string, { requestValidator: SchemaObject; respon
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
export class MessageHandler {
|
|
38
|
-
private ajv:
|
|
39
|
+
private ajv: any;
|
|
39
40
|
private readonly plugin: Plugin;
|
|
40
41
|
private messageSchemaValidator: ValidateFunction;
|
|
41
42
|
private requestValidators: Map<string, ValidateFunction>;
|
|
42
43
|
private responseValidators: Map<string, ValidateFunction>;
|
|
43
44
|
|
|
44
45
|
constructor(plugin: Plugin) {
|
|
45
|
-
this.ajv = new
|
|
46
|
-
addFormats(this.ajv);
|
|
46
|
+
this.ajv = new Ajv.default({ strict: true, code: { esm: true } });
|
|
47
|
+
addFormats.default(this.ajv);
|
|
47
48
|
this.ajv.addSchema(ResourceSchema);
|
|
48
49
|
this.plugin = plugin;
|
|
49
50
|
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import { describe, it } from 'mocha';
|
|
2
1
|
import { EventEmitter } from 'node:events';
|
|
3
2
|
import { ChildProcess } from 'node:child_process';
|
|
4
|
-
|
|
5
3
|
import { Readable } from 'stream';
|
|
6
4
|
import { mock } from 'node:test';
|
|
7
|
-
import { expect } from '@oclif/test';
|
|
8
5
|
import { AssertionError } from 'chai';
|
|
9
6
|
import { CodifyTestUtils } from './test-utils';
|
|
10
|
-
import
|
|
11
|
-
import chaiAsPromised = require('chai-as-promised');
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
12
8
|
|
|
13
9
|
describe('Test Utils tests', async () => {
|
|
14
10
|
|
|
15
|
-
before(() => {
|
|
16
|
-
chai.use(chaiAsPromised);
|
|
17
|
-
})
|
|
18
|
-
|
|
19
11
|
const mockChildProcess = () => {
|
|
20
12
|
const process = new ChildProcess();
|
|
21
13
|
process.stdout = new EventEmitter() as Readable;
|
|
@@ -39,14 +31,22 @@ describe('Test Utils tests', async () => {
|
|
|
39
31
|
const process = mockChildProcess();
|
|
40
32
|
|
|
41
33
|
try {
|
|
42
|
-
await Promise.all([
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
const result = await Promise.all([
|
|
35
|
+
(async () => {
|
|
36
|
+
await sleep(30);
|
|
37
|
+
process.emit('message', { cmd: 'messageResult', data: 'data' })
|
|
38
|
+
})(),
|
|
39
|
+
CodifyTestUtils.sendMessageToProcessAwaitResponse(process, { cmd: 'message', data: 'data' }),
|
|
46
40
|
]);
|
|
41
|
+
|
|
42
|
+
expect(result[1]).to.deep.eq({ cmd: 'messageResult', data: 'data' })
|
|
47
43
|
} catch (e) {
|
|
48
44
|
console.log(e);
|
|
49
45
|
throw new AssertionError('Failed to receive message');
|
|
50
46
|
}
|
|
51
47
|
});
|
|
52
48
|
});
|
|
49
|
+
|
|
50
|
+
async function sleep(ms: number) {
|
|
51
|
+
return new Promise((resolve, reject) => setTimeout(resolve, ms))
|
|
52
|
+
}
|
package/src/utils/utils.ts
CHANGED
|
@@ -16,32 +16,17 @@ type CodifySpawnOptions = {
|
|
|
16
16
|
stdioString?: boolean;
|
|
17
17
|
} & SpawnOptions
|
|
18
18
|
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
* @param cmd Command to run. Ex: `rm -rf`
|
|
22
|
-
* @param args Optional additional arguments to append
|
|
23
|
-
* @param opts Standard options for node spawn. Additional argument:
|
|
24
|
-
* throws determines if a shell will throw a JS error. Defaults to true
|
|
25
|
-
* @param extras From PromiseSpawn
|
|
26
|
-
*
|
|
27
|
-
* @see promiseSpawn
|
|
28
|
-
* @see spawn
|
|
29
|
-
*
|
|
30
|
-
* @returns SpawnResult { status: SUCCESS | ERROR; data: string }
|
|
31
|
-
*/
|
|
32
19
|
export async function codifySpawn(
|
|
33
20
|
cmd: string,
|
|
34
21
|
args?: string[],
|
|
35
|
-
opts?: Omit<CodifySpawnOptions, 'stdio' | 'stdioString'
|
|
22
|
+
opts?: Omit<CodifySpawnOptions, 'stdio' | 'stdioString' | 'shell'>,
|
|
36
23
|
extras?: Record<any, any>,
|
|
37
24
|
): Promise<SpawnResult> {
|
|
38
25
|
try {
|
|
39
|
-
// TODO: Need to benchmark the effects of using sh vs zsh for shell.
|
|
40
|
-
// Seems like zsh shells run slower
|
|
41
26
|
const result = await promiseSpawn(
|
|
42
27
|
cmd,
|
|
43
28
|
args ?? [],
|
|
44
|
-
{ ...opts, stdio: 'pipe', stdioString: true, shell:
|
|
29
|
+
{ ...opts, stdio: 'pipe', stdioString: true, shell: true },
|
|
45
30
|
extras,
|
|
46
31
|
);
|
|
47
32
|
|
|
@@ -58,19 +43,10 @@ export async function codifySpawn(
|
|
|
58
43
|
status,
|
|
59
44
|
data: status === SpawnStatus.SUCCESS ? result.stdout : result.stderr
|
|
60
45
|
}
|
|
61
|
-
} catch (
|
|
62
|
-
const shouldThrow = opts?.throws ?? true;
|
|
63
|
-
if (isDebug() || shouldThrow) {
|
|
64
|
-
console.error(`CodifySpawn Error for command ${cmd} ${args}`, error);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (shouldThrow) {
|
|
68
|
-
throw error;
|
|
69
|
-
}
|
|
70
|
-
|
|
46
|
+
} catch (e) {
|
|
71
47
|
return {
|
|
72
48
|
status: SpawnStatus.ERROR,
|
|
73
|
-
data:
|
|
49
|
+
data: e as string,
|
|
74
50
|
}
|
|
75
51
|
}
|
|
76
52
|
}
|
package/tsconfig.json
CHANGED