codify-plugin-lib 1.0.32 → 1.0.33
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/plugin.d.ts +2 -2
- package/dist/entities/plugin.js +20 -3
- package/dist/entities/resource.d.ts +2 -1
- package/dist/entities/resource.js +3 -1
- package/dist/index.js +0 -1
- package/dist/messages/handlers.js +6 -1
- package/package.json +2 -2
- package/src/entities/plugin.ts +21 -3
- package/src/entities/resource.test.ts +14 -14
- package/src/entities/resource.ts +5 -3
- package/src/index.ts +0 -2
- package/src/messages/handlers.ts +12 -5
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Resource } from './resource.js';
|
|
2
|
-
import { ApplyRequestData, PlanRequestData, PlanResponseData, ResourceConfig, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
|
|
2
|
+
import { ApplyRequestData, InitializeResponseData, PlanRequestData, PlanResponseData, ResourceConfig, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
|
|
3
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>>;
|
|
7
7
|
constructor(resources: Map<string, Resource<ResourceConfig>>);
|
|
8
|
-
|
|
8
|
+
initialize(): Promise<InitializeResponseData>;
|
|
9
9
|
validate(data: ValidateRequestData): Promise<ValidateResponseData>;
|
|
10
10
|
plan(data: PlanRequestData): Promise<PlanResponseData>;
|
|
11
11
|
apply(data: ApplyRequestData): Promise<void>;
|
package/dist/entities/plugin.js
CHANGED
|
@@ -5,17 +5,34 @@ export class Plugin {
|
|
|
5
5
|
this.resources = resources;
|
|
6
6
|
this.planStorage = new Map();
|
|
7
7
|
}
|
|
8
|
-
async
|
|
8
|
+
async initialize() {
|
|
9
|
+
for (const resource of this.resources.values()) {
|
|
10
|
+
await resource.onInitialize();
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
resourceDefinitions: [...this.resources.values()]
|
|
14
|
+
.map((r) => ({
|
|
15
|
+
type: r.getTypeId(),
|
|
16
|
+
dependencies: r.getDependencyTypeIds(),
|
|
17
|
+
}))
|
|
18
|
+
};
|
|
9
19
|
}
|
|
10
20
|
async validate(data) {
|
|
21
|
+
const totalErrors = [];
|
|
11
22
|
for (const config of data.configs) {
|
|
12
23
|
if (!this.resources.has(config.type)) {
|
|
13
24
|
throw new Error(`Resource type not found: ${config.type}`);
|
|
14
25
|
}
|
|
15
|
-
await this.resources.get(config.type).validate(config);
|
|
26
|
+
const error = await this.resources.get(config.type).validate(config);
|
|
27
|
+
if (error) {
|
|
28
|
+
totalErrors.push(error);
|
|
29
|
+
}
|
|
16
30
|
}
|
|
17
31
|
await this.crossValidateResources(data.configs);
|
|
18
|
-
return
|
|
32
|
+
return {
|
|
33
|
+
isValid: true,
|
|
34
|
+
errors: totalErrors.length !== 0 ? totalErrors : null,
|
|
35
|
+
};
|
|
19
36
|
}
|
|
20
37
|
async plan(data) {
|
|
21
38
|
if (!this.resources.has(data.type)) {
|
|
@@ -7,11 +7,12 @@ export declare abstract class Resource<T extends ResourceConfig> {
|
|
|
7
7
|
private statefulParameters;
|
|
8
8
|
constructor(dependencies?: Resource<any>[]);
|
|
9
9
|
abstract getTypeId(): string;
|
|
10
|
+
getDependencyTypeIds(): string[];
|
|
10
11
|
onInitialize(): Promise<void>;
|
|
11
12
|
plan(desiredConfig: T): Promise<Plan<T>>;
|
|
12
13
|
apply(plan: Plan<T>): Promise<void>;
|
|
13
14
|
protected registerStatefulParameter(parameter: StatefulParameter<T, keyof T>): void;
|
|
14
|
-
abstract validate(config: unknown): Promise<
|
|
15
|
+
abstract validate(config: unknown): Promise<string | undefined>;
|
|
15
16
|
abstract getCurrentConfig(desiredConfig: T): Promise<T | null>;
|
|
16
17
|
abstract calculateOperation(change: ParameterChange): ResourceOperation.MODIFY | ResourceOperation.RECREATE;
|
|
17
18
|
abstract applyCreate(plan: Plan<T>): Promise<void>;
|
|
@@ -7,9 +7,11 @@ export class Resource {
|
|
|
7
7
|
constructor(dependencies = []) {
|
|
8
8
|
this.dependencies = dependencies;
|
|
9
9
|
}
|
|
10
|
+
getDependencyTypeIds() {
|
|
11
|
+
return this.dependencies.map((d) => d.getTypeId());
|
|
12
|
+
}
|
|
10
13
|
async onInitialize() { }
|
|
11
14
|
async plan(desiredConfig) {
|
|
12
|
-
await this.validate(desiredConfig);
|
|
13
15
|
const currentConfig = await this.getCurrentConfig(desiredConfig);
|
|
14
16
|
if (!currentConfig) {
|
|
15
17
|
return Plan.create(ChangeSet.createForNullCurrentConfig(desiredConfig), desiredConfig);
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,6 @@ export * from './entities/stateful-parameter.js';
|
|
|
7
7
|
export * from './utils/test-utils.js';
|
|
8
8
|
export * from './utils/utils.js';
|
|
9
9
|
export async function runPlugin(plugin) {
|
|
10
|
-
await plugin.onInitialize();
|
|
11
10
|
const messageHandler = new MessageHandler(plugin);
|
|
12
11
|
process.on('message', (message) => messageHandler.onMessage(message));
|
|
13
12
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import addFormats from 'ajv-formats';
|
|
2
|
-
import {
|
|
2
|
+
import { ApplyRequestDataSchema, ApplyResponseDataSchema, InitializeRequestDataSchema, InitializeResponseDataSchema, IpcMessageSchema, MessageStatus, PlanRequestDataSchema, PlanResponseDataSchema, ResourceSchema, ValidateRequestDataSchema, ValidateResponseDataSchema } from 'codify-schemas';
|
|
3
3
|
import Ajv2020 from 'ajv/dist/2020.js';
|
|
4
4
|
const SupportedRequests = {
|
|
5
|
+
'initialize': {
|
|
6
|
+
requestValidator: InitializeRequestDataSchema,
|
|
7
|
+
responseValidator: InitializeResponseDataSchema,
|
|
8
|
+
handler: async (plugin) => plugin.initialize()
|
|
9
|
+
},
|
|
5
10
|
'validate': {
|
|
6
11
|
requestValidator: ValidateRequestDataSchema,
|
|
7
12
|
responseValidator: ValidateResponseDataSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codify-plugin-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.33",
|
|
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.
|
|
17
|
+
"codify-schemas": "1.0.28",
|
|
18
18
|
"@npmcli/promise-spawn": "^7.0.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
package/src/entities/plugin.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Resource } from './resource.js';
|
|
2
2
|
import {
|
|
3
3
|
ApplyRequestData,
|
|
4
|
+
InitializeResponseData,
|
|
4
5
|
PlanRequestData,
|
|
5
6
|
PlanResponseData,
|
|
6
7
|
ResourceConfig,
|
|
@@ -18,21 +19,38 @@ export class Plugin {
|
|
|
18
19
|
this.planStorage = new Map();
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
async
|
|
22
|
+
async initialize(): Promise<InitializeResponseData> {
|
|
23
|
+
for (const resource of this.resources.values()) {
|
|
24
|
+
await resource.onInitialize();
|
|
25
|
+
}
|
|
22
26
|
|
|
27
|
+
return {
|
|
28
|
+
resourceDefinitions: [...this.resources.values()]
|
|
29
|
+
.map((r) => ({
|
|
30
|
+
type: r.getTypeId(),
|
|
31
|
+
dependencies: r.getDependencyTypeIds(),
|
|
32
|
+
}))
|
|
33
|
+
}
|
|
23
34
|
}
|
|
24
35
|
|
|
25
36
|
async validate(data: ValidateRequestData): Promise<ValidateResponseData> {
|
|
37
|
+
const totalErrors = [];
|
|
26
38
|
for (const config of data.configs) {
|
|
27
39
|
if (!this.resources.has(config.type)) {
|
|
28
40
|
throw new Error(`Resource type not found: ${config.type}`);
|
|
29
41
|
}
|
|
30
42
|
|
|
31
|
-
await this.resources.get(config.type)!.validate(config);
|
|
43
|
+
const error = await this.resources.get(config.type)!.validate(config);
|
|
44
|
+
if (error) {
|
|
45
|
+
totalErrors.push(error);
|
|
46
|
+
}
|
|
32
47
|
}
|
|
33
48
|
|
|
34
49
|
await this.crossValidateResources(data.configs);
|
|
35
|
-
return
|
|
50
|
+
return {
|
|
51
|
+
isValid: true,
|
|
52
|
+
errors: totalErrors.length !== 0 ? totalErrors : null,
|
|
53
|
+
}
|
|
36
54
|
}
|
|
37
55
|
|
|
38
56
|
async plan(data: PlanRequestData): Promise<PlanResponseData> {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Resource } from './resource';
|
|
1
|
+
import { Resource } from './resource.js';
|
|
2
2
|
import { ParameterOperation, ResourceConfig, ResourceOperation } from 'codify-schemas';
|
|
3
|
-
import { ChangeSet, ParameterChange } from './change-set';
|
|
3
|
+
import { ChangeSet, ParameterChange } from './change-set.js';
|
|
4
4
|
import { spy } from 'sinon';
|
|
5
|
-
import { Plan } from './plan';
|
|
6
|
-
import { StatefulParameter } from './stateful-parameter';
|
|
7
|
-
import { describe,
|
|
5
|
+
import { Plan } from './plan.js';
|
|
6
|
+
import { StatefulParameter } from './stateful-parameter.js';
|
|
7
|
+
import { describe, expect, it } from 'vitest'
|
|
8
8
|
|
|
9
9
|
class TestResource extends Resource<TestConfig> {
|
|
10
10
|
applyCreate(plan: Plan<TestConfig>): Promise<void> {
|
|
@@ -27,12 +27,12 @@ class TestResource extends Resource<TestConfig> {
|
|
|
27
27
|
return ResourceOperation.MODIFY;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
async getCurrentConfig(): Promise<TestConfig> {
|
|
31
|
-
return
|
|
30
|
+
async getCurrentConfig(): Promise<TestConfig | null> {
|
|
31
|
+
return null;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
validate(config: ResourceConfig): Promise<
|
|
35
|
-
return
|
|
34
|
+
async validate(config: ResourceConfig): Promise<string | undefined> {
|
|
35
|
+
return undefined;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
getTypeId(): string {
|
|
@@ -127,7 +127,7 @@ describe('Resource tests', () => {
|
|
|
127
127
|
return ResourceOperation.MODIFY;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
async getCurrentConfig(): Promise<TestConfig> {
|
|
130
|
+
async getCurrentConfig(): Promise<TestConfig | null> {
|
|
131
131
|
return null;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -230,8 +230,8 @@ describe('Resource tests', () => {
|
|
|
230
230
|
return Promise.resolve(undefined);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
getCurrent(): Promise<TestConfig["propA"]> {
|
|
234
|
-
return
|
|
233
|
+
async getCurrent(): Promise<TestConfig["propA"]> {
|
|
234
|
+
return '';
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
|
|
@@ -298,8 +298,8 @@ describe('Resource tests', () => {
|
|
|
298
298
|
return Promise.resolve(undefined);
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
getCurrent(): Promise<TestConfig["propA"]> {
|
|
302
|
-
return
|
|
301
|
+
async getCurrent(): Promise<TestConfig["propA"]> {
|
|
302
|
+
return '';
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
|
package/src/entities/resource.ts
CHANGED
|
@@ -13,13 +13,15 @@ export abstract class Resource<T extends ResourceConfig> {
|
|
|
13
13
|
|
|
14
14
|
abstract getTypeId(): string;
|
|
15
15
|
|
|
16
|
+
getDependencyTypeIds(): string[] {
|
|
17
|
+
return this.dependencies.map((d) => d.getTypeId())
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
async onInitialize(): Promise<void> {}
|
|
17
21
|
|
|
18
22
|
// TODO: Add state in later.
|
|
19
23
|
// Calculate change set from current config -> state -> desired in the future
|
|
20
24
|
async plan(desiredConfig: T): Promise<Plan<T>> {
|
|
21
|
-
await this.validate(desiredConfig);
|
|
22
|
-
|
|
23
25
|
const currentConfig = await this.getCurrentConfig(desiredConfig);
|
|
24
26
|
if (!currentConfig) {
|
|
25
27
|
return Plan.create(ChangeSet.createForNullCurrentConfig(desiredConfig), desiredConfig);
|
|
@@ -114,7 +116,7 @@ export abstract class Resource<T extends ResourceConfig> {
|
|
|
114
116
|
this.statefulParameters.set(parameter.name as string, parameter);
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
abstract validate(config: unknown): Promise<
|
|
119
|
+
abstract validate(config: unknown): Promise<string | undefined>;
|
|
118
120
|
|
|
119
121
|
abstract getCurrentConfig(desiredConfig: T): Promise<T | null>;
|
|
120
122
|
|
package/src/index.ts
CHANGED
|
@@ -11,8 +11,6 @@ export * from './utils/test-utils.js'
|
|
|
11
11
|
export * from './utils/utils.js'
|
|
12
12
|
|
|
13
13
|
export async function runPlugin(plugin: Plugin) {
|
|
14
|
-
await plugin.onInitialize();
|
|
15
|
-
|
|
16
14
|
const messageHandler = new MessageHandler(plugin);
|
|
17
15
|
process.on('message', (message) => messageHandler.onMessage(message))
|
|
18
16
|
}
|
package/src/messages/handlers.ts
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import { Plugin } from '../entities/plugin.js';
|
|
2
2
|
import addFormats from 'ajv-formats';
|
|
3
3
|
import {
|
|
4
|
+
ApplyRequestDataSchema,
|
|
5
|
+
ApplyResponseDataSchema,
|
|
6
|
+
InitializeRequestDataSchema,
|
|
7
|
+
InitializeResponseDataSchema,
|
|
4
8
|
IpcMessage,
|
|
5
9
|
IpcMessageSchema,
|
|
6
|
-
ResourceSchema,
|
|
7
|
-
ValidateRequestDataSchema,
|
|
8
|
-
ValidateResponseDataSchema,
|
|
9
10
|
MessageStatus,
|
|
10
11
|
PlanRequestDataSchema,
|
|
11
12
|
PlanResponseDataSchema,
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
ResourceSchema,
|
|
14
|
+
ValidateRequestDataSchema,
|
|
15
|
+
ValidateResponseDataSchema
|
|
14
16
|
} from 'codify-schemas';
|
|
15
17
|
import Ajv2020, { SchemaObject, ValidateFunction } from 'ajv/dist/2020.js';
|
|
16
18
|
|
|
17
19
|
const SupportedRequests: Record<string, { requestValidator: SchemaObject; responseValidator: SchemaObject; handler: (plugin: Plugin, data: any) => Promise<unknown> }> = {
|
|
20
|
+
'initialize': {
|
|
21
|
+
requestValidator: InitializeRequestDataSchema,
|
|
22
|
+
responseValidator: InitializeResponseDataSchema,
|
|
23
|
+
handler: async (plugin: Plugin) => plugin.initialize()
|
|
24
|
+
},
|
|
18
25
|
'validate': {
|
|
19
26
|
requestValidator: ValidateRequestDataSchema,
|
|
20
27
|
responseValidator: ValidateResponseDataSchema,
|