codify-plugin-lib 1.0.75 → 1.0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- import { Resource } from './resource.js';
2
1
  import { ApplyRequestData, InitializeResponseData, PlanRequestData, PlanResponseData, ResourceConfig, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
3
2
  import { Plan } from './plan.js';
3
+ import { Resource } from './resource.js';
4
4
  export declare class Plugin {
5
5
  name: string;
6
6
  resources: Map<string, Resource<ResourceConfig>>;
@@ -1,5 +1,5 @@
1
- import { Plan } from './plan.js';
2
1
  import { splitUserConfig } from '../utils/utils.js';
2
+ import { Plan } from './plan.js';
3
3
  export class Plugin {
4
4
  name;
5
5
  resources;
@@ -20,8 +20,8 @@ export class Plugin {
20
20
  return {
21
21
  resourceDefinitions: [...this.resources.values()]
22
22
  .map((r) => ({
23
- type: r.typeId,
24
23
  dependencies: r.dependencies,
24
+ type: r.typeId,
25
25
  }))
26
26
  };
27
27
  }
@@ -53,7 +53,7 @@ export class Plugin {
53
53
  }
54
54
  async apply(data) {
55
55
  if (!data.planId && !data.plan) {
56
- throw new Error(`For applies either plan or planId must be supplied`);
56
+ throw new Error('For applies either plan or planId must be supplied');
57
57
  }
58
58
  const plan = this.resolvePlan(data);
59
59
  const resource = this.resources.get(plan.getResourceType());
@@ -63,7 +63,7 @@ export class Plugin {
63
63
  await resource.apply(plan);
64
64
  }
65
65
  resolvePlan(data) {
66
- const { planId, plan: planRequest } = data;
66
+ const { plan: planRequest, planId } = data;
67
67
  if (planId) {
68
68
  if (!this.planStorage.has(planId)) {
69
69
  throw new Error(`Plan with id: ${planId} was not found`);
@@ -74,7 +74,7 @@ export class Plugin {
74
74
  throw new Error('Malformed plan. Resource type must be supplied or resource type was not found');
75
75
  }
76
76
  const resource = this.resources.get(planRequest.resourceType);
77
- return Plan.fromResponse(data.plan, resource.defaultValues);
77
+ return Plan.fromResponse(planRequest, resource.defaultValues);
78
78
  }
79
79
  async crossValidateResources(configs) { }
80
80
  }
@@ -1,22 +1,22 @@
1
1
  import { StringIndexedObject } from 'codify-schemas';
2
+ import { ParameterOptions } from './plan-types.js';
3
+ import { ResourceParameterOptions } from './resource-types.js';
2
4
  import { StatefulParameter } from './stateful-parameter.js';
3
5
  import { TransformParameter } from './transform-parameter.js';
4
- import { ResourceParameterOptions } from './resource-types.js';
5
- import { ParameterOptions } from './plan-types.js';
6
6
  export interface ResourceOptions<T extends StringIndexedObject> {
7
- type: string;
8
- schema?: unknown;
9
7
  callStatefulParameterRemoveOnDestroy?: boolean;
10
8
  dependencies?: string[];
11
9
  parameterOptions?: Partial<Record<keyof T, ResourceParameterOptions | ResourceStatefulParameterOptions<T> | ResourceTransformParameterOptions<T>>>;
10
+ schema?: unknown;
11
+ type: string;
12
12
  }
13
13
  export interface ResourceStatefulParameterOptions<T extends StringIndexedObject> {
14
- statefulParameter: StatefulParameter<T, T[keyof T]>;
15
14
  order?: number;
15
+ statefulParameter: StatefulParameter<T, T[keyof T]>;
16
16
  }
17
17
  export interface ResourceTransformParameterOptions<T extends StringIndexedObject> {
18
- transformParameter: TransformParameter<T>;
19
18
  order?: number;
19
+ transformParameter: TransformParameter<T>;
20
20
  }
21
21
  export declare class ResourceOptionsParser<T extends StringIndexedObject> {
22
22
  private options;
@@ -27,15 +27,13 @@ export class ResourceOptionsParser {
27
27
  const resourceParameters = Object.fromEntries([...this.resourceParameters.entries()]
28
28
  .map(([name, value]) => ([name, { ...value, isStatefulParameter: false }])));
29
29
  const statefulParameters = [...this.statefulParameters.entries()]
30
- ?.reduce((obj, sp) => {
31
- return {
32
- ...obj,
33
- [sp[0]]: {
34
- ...sp[1].options,
35
- isStatefulParameter: true,
36
- }
37
- };
38
- }, {});
30
+ ?.reduce((obj, sp) => ({
31
+ ...obj,
32
+ [sp[0]]: {
33
+ ...sp[1].options,
34
+ isStatefulParameter: true,
35
+ }
36
+ }), {});
39
37
  return {
40
38
  ...resourceParameters,
41
39
  ...statefulParameters,
@@ -1,5 +1,4 @@
1
- import Ajv from 'ajv';
2
- import { ValidateFunction } from 'ajv/dist/2020.js';
1
+ import { Ajv, ValidateFunction } from 'ajv';
3
2
  import { ResourceConfig, StringIndexedObject, ValidateResponseData } from 'codify-schemas';
4
3
  import { ParameterChange } from './change-set.js';
5
4
  import { Plan } from './plan.js';
@@ -19,7 +18,7 @@ export declare abstract class Resource<T extends StringIndexedObject> {
19
18
  readonly parameterOptions: Record<keyof T, ParameterOptions>;
20
19
  readonly options: ResourceOptions<T>;
21
20
  readonly defaultValues: Partial<Record<keyof T, unknown>>;
22
- protected ajv?: Ajv.default;
21
+ protected ajv?: Ajv;
23
22
  protected schemaValidator?: ValidateFunction;
24
23
  protected constructor(options: ResourceOptions<T>);
25
24
  onInitialize(): Promise<void>;
@@ -1,4 +1,4 @@
1
- import Ajv2020 from 'ajv/dist/2020.js';
1
+ import { Ajv } from 'ajv';
2
2
  import { ParameterOperation, ResourceOperation, } from 'codify-schemas';
3
3
  import { setsEqual, splitUserConfig } from '../utils/utils.js';
4
4
  import { Plan } from './plan.js';
@@ -21,7 +21,7 @@ export class Resource {
21
21
  this.dependencies = options.dependencies ?? [];
22
22
  this.options = options;
23
23
  if (this.options.schema) {
24
- this.ajv = new Ajv2020.default({
24
+ this.ajv = new Ajv({
25
25
  allErrors: true,
26
26
  strict: true,
27
27
  strictRequired: false,
@@ -1,30 +1,30 @@
1
+ import { Ajv } from 'ajv';
1
2
  import addFormats from 'ajv-formats';
2
3
  import { ApplyRequestDataSchema, ApplyResponseDataSchema, InitializeRequestDataSchema, InitializeResponseDataSchema, IpcMessageSchema, MessageStatus, PlanRequestDataSchema, PlanResponseDataSchema, ResourceSchema, ValidateRequestDataSchema, ValidateResponseDataSchema } from 'codify-schemas';
3
- import Ajv2020 from 'ajv/dist/2020.js';
4
4
  import { SudoError } from '../entities/errors.js';
5
5
  const SupportedRequests = {
6
+ 'apply': {
7
+ async handler(plugin, data) {
8
+ await plugin.apply(data);
9
+ return null;
10
+ },
11
+ requestValidator: ApplyRequestDataSchema,
12
+ responseValidator: ApplyResponseDataSchema
13
+ },
6
14
  'initialize': {
15
+ handler: async (plugin) => plugin.initialize(),
7
16
  requestValidator: InitializeRequestDataSchema,
8
- responseValidator: InitializeResponseDataSchema,
9
- handler: async (plugin) => plugin.initialize()
10
- },
11
- 'validate': {
12
- requestValidator: ValidateRequestDataSchema,
13
- responseValidator: ValidateResponseDataSchema,
14
- handler: async (plugin, data) => plugin.validate(data)
17
+ responseValidator: InitializeResponseDataSchema
15
18
  },
16
19
  'plan': {
20
+ handler: async (plugin, data) => plugin.plan(data),
17
21
  requestValidator: PlanRequestDataSchema,
18
- responseValidator: PlanResponseDataSchema,
19
- handler: async (plugin, data) => plugin.plan(data)
22
+ responseValidator: PlanResponseDataSchema
20
23
  },
21
- 'apply': {
22
- requestValidator: ApplyRequestDataSchema,
23
- responseValidator: ApplyResponseDataSchema,
24
- handler: async (plugin, data) => {
25
- await plugin.apply(data);
26
- return null;
27
- }
24
+ 'validate': {
25
+ handler: async (plugin, data) => plugin.validate(data),
26
+ requestValidator: ValidateRequestDataSchema,
27
+ responseValidator: ValidateResponseDataSchema
28
28
  }
29
29
  };
30
30
  export class MessageHandler {
@@ -34,7 +34,7 @@ export class MessageHandler {
34
34
  requestValidators;
35
35
  responseValidators;
36
36
  constructor(plugin) {
37
- this.ajv = new Ajv2020.default({ strict: true, strictRequired: false });
37
+ this.ajv = new Ajv({ strict: true, strictRequired: false });
38
38
  addFormats.default(this.ajv);
39
39
  this.ajv.addSchema(ResourceSchema);
40
40
  this.plugin = plugin;
@@ -63,12 +63,12 @@ export class MessageHandler {
63
63
  }
64
64
  process.send({
65
65
  cmd: message.cmd + '_Response',
66
- status: MessageStatus.SUCCESS,
67
66
  data: result,
67
+ status: MessageStatus.SUCCESS,
68
68
  });
69
69
  }
70
- catch (e) {
71
- this.handleErrors(message, e);
70
+ catch (error) {
71
+ this.handleErrors(message, error);
72
72
  }
73
73
  }
74
74
  validateMessage(message) {
@@ -85,15 +85,15 @@ export class MessageHandler {
85
85
  if (e instanceof SudoError) {
86
86
  return process.send?.({
87
87
  cmd,
88
- status: MessageStatus.ERROR,
89
88
  data: `Plugin: '${this.plugin.name}'. Forbidden usage of sudo for command '${e.command}'. Please contact the plugin developer to fix this.`,
89
+ status: MessageStatus.ERROR,
90
90
  });
91
91
  }
92
92
  const isDebug = process.env.DEBUG?.includes('*') ?? false;
93
93
  process.send?.({
94
94
  cmd,
95
- status: MessageStatus.ERROR,
96
95
  data: isDebug ? e.stack : e.message,
96
+ status: MessageStatus.ERROR,
97
97
  });
98
98
  }
99
99
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.75",
3
+ "version": "1.0.76",
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.44",
17
+ "codify-schemas": "1.0.45",
18
18
  "@npmcli/promise-spawn": "^7.0.1"
19
19
  },
20
20
  "devDependencies": {
@@ -1,4 +1,3 @@
1
- import { Resource } from './resource.js';
2
1
  import {
3
2
  ApplyRequestData,
4
3
  InitializeResponseData,
@@ -8,8 +7,10 @@ import {
8
7
  ValidateRequestData,
9
8
  ValidateResponseData
10
9
  } from 'codify-schemas';
11
- import { Plan } from './plan.js';
10
+
12
11
  import { splitUserConfig } from '../utils/utils.js';
12
+ import { Plan } from './plan.js';
13
+ import { Resource } from './resource.js';
13
14
 
14
15
  export class Plugin {
15
16
  planStorage: Map<string, Plan<any>>;
@@ -37,8 +38,8 @@ export class Plugin {
37
38
  return {
38
39
  resourceDefinitions: [...this.resources.values()]
39
40
  .map((r) => ({
40
- type: r.typeId,
41
41
  dependencies: r.dependencies,
42
+ type: r.typeId,
42
43
  }))
43
44
  }
44
45
  }
@@ -83,7 +84,7 @@ export class Plugin {
83
84
 
84
85
  async apply(data: ApplyRequestData): Promise<void> {
85
86
  if (!data.planId && !data.plan) {
86
- throw new Error(`For applies either plan or planId must be supplied`);
87
+ throw new Error('For applies either plan or planId must be supplied');
87
88
  }
88
89
 
89
90
  const plan = this.resolvePlan(data);
@@ -97,7 +98,7 @@ export class Plugin {
97
98
  }
98
99
 
99
100
  private resolvePlan(data: ApplyRequestData): Plan<ResourceConfig> {
100
- const { planId, plan: planRequest } = data;
101
+ const { plan: planRequest, planId } = data;
101
102
 
102
103
  if (planId) {
103
104
  if (!this.planStorage.has(planId)) {
@@ -112,7 +113,7 @@ export class Plugin {
112
113
  }
113
114
 
114
115
  const resource = this.resources.get(planRequest.resourceType)!;
115
- return Plan.fromResponse(data.plan, resource.defaultValues);
116
+ return Plan.fromResponse(planRequest, resource.defaultValues);
116
117
  }
117
118
 
118
119
  protected async crossValidateResources(configs: ResourceConfig[]): Promise<void> {}
@@ -1,21 +1,12 @@
1
1
  import { StringIndexedObject } from 'codify-schemas';
2
+
3
+ import { ParameterOptions } from './plan-types.js';
4
+ import { ResourceParameterOptions } from './resource-types.js';
2
5
  import { StatefulParameter } from './stateful-parameter.js';
3
6
  import { TransformParameter } from './transform-parameter.js';
4
- import { ResourceParameterOptions } from './resource-types.js';
5
- import { ParameterOptions } from './plan-types.js';
6
7
 
7
8
  export interface ResourceOptions<T extends StringIndexedObject> {
8
9
 
9
- /**
10
- * The id of the resource.
11
- */
12
- type: string;
13
-
14
- /**
15
- * Schema to validate user configs with. Must be in the format JSON Schema 2020-12
16
- */
17
- schema?: unknown
18
-
19
10
  /**
20
11
  * If true, statefulParameter.applyRemove() will be called before resource destruction.
21
12
  * Defaults to false.
@@ -36,16 +27,26 @@ export interface ResourceOptions<T extends StringIndexedObject> {
36
27
  | ResourceStatefulParameterOptions<T>
37
28
  | ResourceTransformParameterOptions<T>
38
29
  >>
30
+
31
+ /**
32
+ * Schema to validate user configs with. Must be in the format JSON Schema draft07
33
+ */
34
+ schema?: unknown
35
+
36
+ /**
37
+ * The id of the resource.
38
+ */
39
+ type: string;
39
40
  }
40
41
 
41
42
  export interface ResourceStatefulParameterOptions<T extends StringIndexedObject> {
42
- statefulParameter: StatefulParameter<T, T[keyof T]>;
43
43
  order?: number;
44
+ statefulParameter: StatefulParameter<T, T[keyof T]>;
44
45
  }
45
46
 
46
47
  export interface ResourceTransformParameterOptions<T extends StringIndexedObject> {
47
- transformParameter: TransformParameter<T>;
48
48
  order?: number;
49
+ transformParameter: TransformParameter<T>;
49
50
  }
50
51
 
51
52
  export class ResourceOptionsParser<T extends StringIndexedObject> {
@@ -90,15 +91,13 @@ export class ResourceOptionsParser<T extends StringIndexedObject> {
90
91
  );
91
92
 
92
93
  const statefulParameters = [...this.statefulParameters.entries()]
93
- ?.reduce((obj, sp) => {
94
- return {
94
+ ?.reduce((obj, sp) => ({
95
95
  ...obj,
96
96
  [sp[0]]: {
97
97
  ...sp[1].options,
98
98
  isStatefulParameter: true,
99
99
  }
100
- }
101
- }, {} as Record<keyof T, ParameterOptions>)
100
+ }), {} as Record<keyof T, ParameterOptions>)
102
101
 
103
102
  return {
104
103
  ...resourceParameters,
@@ -1,5 +1,4 @@
1
- import Ajv from 'ajv';
2
- import Ajv2020, { ValidateFunction } from 'ajv/dist/2020.js';
1
+ import { Ajv, ValidateFunction } from 'ajv';
3
2
  import {
4
3
  ParameterOperation,
5
4
  ResourceConfig,
@@ -38,7 +37,7 @@ export abstract class Resource<T extends StringIndexedObject> {
38
37
  readonly options: ResourceOptions<T>;
39
38
  readonly defaultValues: Partial<Record<keyof T, unknown>>;
40
39
 
41
- protected ajv?: Ajv.default;
40
+ protected ajv?: Ajv;
42
41
  protected schemaValidator?: ValidateFunction;
43
42
 
44
43
  protected constructor(options: ResourceOptions<T>) {
@@ -47,7 +46,7 @@ export abstract class Resource<T extends StringIndexedObject> {
47
46
  this.options = options;
48
47
 
49
48
  if (this.options.schema) {
50
- this.ajv = new Ajv2020.default({
49
+ this.ajv = new Ajv({
51
50
  allErrors: true,
52
51
  strict: true,
53
52
  strictRequired: false,
@@ -25,10 +25,13 @@ describe('Message handler tests', () => {
25
25
  await handler.onMessage({
26
26
  cmd: 'plan',
27
27
  data: {
28
- type: 'resourceType',
29
- name: 'name',
30
- prop1: 'A',
31
- prop2: 'B',
28
+ desired: {
29
+ type: 'resourceType',
30
+ name: 'name',
31
+ prop1: 'A',
32
+ prop2: 'B',
33
+ },
34
+ isStateful: false,
32
35
  }
33
36
  })
34
37
  } catch (e) {}
@@ -165,7 +168,10 @@ describe('Message handler tests', () => {
165
168
  expect(async () => await handler.onMessage({
166
169
  cmd: 'plan',
167
170
  data: {
168
- type: 'resourceA'
171
+ desired: {
172
+ type: 'resourceA'
173
+ },
174
+ isStateful: false,
169
175
  }
170
176
  })).rejects.to.not.throw;
171
177
 
@@ -1,4 +1,4 @@
1
- import { Plugin } from '../entities/plugin.js';
1
+ import { Ajv, SchemaObject, ValidateFunction } from 'ajv';
2
2
  import addFormats from 'ajv-formats';
3
3
  import {
4
4
  ApplyRequestDataSchema,
@@ -14,44 +14,45 @@ import {
14
14
  ValidateRequestDataSchema,
15
15
  ValidateResponseDataSchema
16
16
  } from 'codify-schemas';
17
- import Ajv2020, { SchemaObject, ValidateFunction } from 'ajv/dist/2020.js';
17
+
18
18
  import { SudoError } from '../entities/errors.js';
19
+ import { Plugin } from '../entities/plugin.js';
19
20
 
20
- const SupportedRequests: Record<string, { requestValidator: SchemaObject; responseValidator: SchemaObject; handler: (plugin: Plugin, data: any) => Promise<unknown> }> = {
21
+ const SupportedRequests: Record<string, { handler: (plugin: Plugin, data: any) => Promise<unknown>; requestValidator: SchemaObject; responseValidator: SchemaObject }> = {
22
+ 'apply': {
23
+ async handler(plugin: Plugin, data: any) {
24
+ await plugin.apply(data);
25
+ return null;
26
+ },
27
+ requestValidator: ApplyRequestDataSchema,
28
+ responseValidator: ApplyResponseDataSchema
29
+ },
21
30
  'initialize': {
31
+ handler: async (plugin: Plugin) => plugin.initialize(),
22
32
  requestValidator: InitializeRequestDataSchema,
23
- responseValidator: InitializeResponseDataSchema,
24
- handler: async (plugin: Plugin) => plugin.initialize()
25
- },
26
- 'validate': {
27
- requestValidator: ValidateRequestDataSchema,
28
- responseValidator: ValidateResponseDataSchema,
29
- handler: async (plugin: Plugin, data: any) => plugin.validate(data)
33
+ responseValidator: InitializeResponseDataSchema
30
34
  },
31
35
  'plan': {
36
+ handler: async (plugin: Plugin, data: any) => plugin.plan(data),
32
37
  requestValidator: PlanRequestDataSchema,
33
- responseValidator: PlanResponseDataSchema,
34
- handler: async (plugin: Plugin, data: any) => plugin.plan(data)
38
+ responseValidator: PlanResponseDataSchema
35
39
  },
36
- 'apply': {
37
- requestValidator: ApplyRequestDataSchema,
38
- responseValidator: ApplyResponseDataSchema,
39
- handler: async (plugin: Plugin, data: any) => {
40
- await plugin.apply(data);
41
- return null;
42
- }
40
+ 'validate': {
41
+ handler: async (plugin: Plugin, data: any) => plugin.validate(data),
42
+ requestValidator: ValidateRequestDataSchema,
43
+ responseValidator: ValidateResponseDataSchema
43
44
  }
44
45
  }
45
46
 
46
47
  export class MessageHandler {
47
- private ajv: Ajv2020.default;
48
+ private ajv: Ajv;
48
49
  private readonly plugin: Plugin;
49
50
  private messageSchemaValidator: ValidateFunction;
50
51
  private requestValidators: Map<string, ValidateFunction>;
51
52
  private responseValidators: Map<string, ValidateFunction>;
52
53
 
53
54
  constructor(plugin: Plugin) {
54
- this.ajv = new Ajv2020.default({ strict: true, strictRequired: false });
55
+ this.ajv = new Ajv({ strict: true, strictRequired: false });
55
56
  addFormats.default(this.ajv);
56
57
  this.ajv.addSchema(ResourceSchema);
57
58
  this.plugin = plugin;
@@ -91,12 +92,12 @@ export class MessageHandler {
91
92
 
92
93
  process.send!({
93
94
  cmd: message.cmd + '_Response',
94
- status: MessageStatus.SUCCESS,
95
95
  data: result,
96
+ status: MessageStatus.SUCCESS,
96
97
  })
97
98
 
98
- } catch (e: unknown) {
99
- this.handleErrors(message, e as Error);
99
+ } catch (error: unknown) {
100
+ this.handleErrors(message, error as Error);
100
101
  }
101
102
  }
102
103
 
@@ -119,8 +120,8 @@ export class MessageHandler {
119
120
  if (e instanceof SudoError) {
120
121
  return process.send?.({
121
122
  cmd,
122
- status: MessageStatus.ERROR,
123
123
  data: `Plugin: '${this.plugin.name}'. Forbidden usage of sudo for command '${e.command}'. Please contact the plugin developer to fix this.`,
124
+ status: MessageStatus.ERROR,
124
125
  })
125
126
  }
126
127
 
@@ -128,8 +129,8 @@ export class MessageHandler {
128
129
 
129
130
  process.send?.({
130
131
  cmd,
131
- status: MessageStatus.ERROR,
132
132
  data: isDebug ? e.stack : e.message,
133
+ status: MessageStatus.ERROR,
133
134
  })
134
135
  }
135
136
  }