codify-plugin-lib 1.0.107 → 1.0.108

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.
@@ -2,11 +2,13 @@ import { Plugin } from '../plugin/plugin.js';
2
2
  export declare class MessageHandler {
3
3
  private ajv;
4
4
  private readonly plugin;
5
- private messageSchemaValidator;
5
+ private messageSchemaValidatorV1;
6
+ private messageSchemaValidatorV2;
6
7
  private requestValidators;
7
8
  private responseValidators;
8
9
  constructor(plugin: Plugin);
9
10
  onMessage(message: unknown): Promise<void>;
10
11
  private validateMessage;
12
+ private validateMessageV2;
11
13
  private handleErrors;
12
14
  }
@@ -1,6 +1,6 @@
1
1
  import { Ajv } from 'ajv';
2
2
  import addFormats from 'ajv-formats';
3
- import { ApplyRequestDataSchema, ApplyResponseDataSchema, GetResourceInfoRequestDataSchema, GetResourceInfoResponseDataSchema, ImportRequestDataSchema, ImportResponseDataSchema, InitializeRequestDataSchema, InitializeResponseDataSchema, IpcMessageSchema, MessageStatus, PlanRequestDataSchema, PlanResponseDataSchema, ResourceSchema, ValidateRequestDataSchema, ValidateResponseDataSchema } from 'codify-schemas';
3
+ import { ApplyRequestDataSchema, ApplyResponseDataSchema, GetResourceInfoRequestDataSchema, GetResourceInfoResponseDataSchema, ImportRequestDataSchema, ImportResponseDataSchema, InitializeRequestDataSchema, InitializeResponseDataSchema, IpcMessageSchema, IpcMessageV2Schema, MessageStatus, PlanRequestDataSchema, PlanResponseDataSchema, ResourceSchema, ValidateRequestDataSchema, ValidateResponseDataSchema } from 'codify-schemas';
4
4
  import { SudoError } from '../errors.js';
5
5
  const SupportedRequests = {
6
6
  'initialize': {
@@ -40,7 +40,8 @@ const SupportedRequests = {
40
40
  export class MessageHandler {
41
41
  ajv;
42
42
  plugin;
43
- messageSchemaValidator;
43
+ messageSchemaValidatorV1;
44
+ messageSchemaValidatorV2;
44
45
  requestValidators;
45
46
  responseValidators;
46
47
  constructor(plugin) {
@@ -48,7 +49,8 @@ export class MessageHandler {
48
49
  addFormats.default(this.ajv);
49
50
  this.ajv.addSchema(ResourceSchema);
50
51
  this.plugin = plugin;
51
- this.messageSchemaValidator = this.ajv.compile(IpcMessageSchema);
52
+ this.messageSchemaValidatorV1 = this.ajv.compile(IpcMessageSchema);
53
+ this.messageSchemaValidatorV2 = this.ajv.compile(IpcMessageV2Schema);
52
54
  this.requestValidators = new Map(Object.entries(SupportedRequests)
53
55
  .map(([k, v]) => [k, this.ajv.compile(v.requestValidator)]));
54
56
  this.responseValidators = new Map(Object.entries(SupportedRequests)
@@ -56,8 +58,8 @@ export class MessageHandler {
56
58
  }
57
59
  async onMessage(message) {
58
60
  try {
59
- if (!this.validateMessage(message)) {
60
- throw new Error(`Plugin: ${this.plugin}. Message is malformed: ${JSON.stringify(this.messageSchemaValidator.errors, null, 2)}`);
61
+ if (!this.validateMessageV2(message) && !this.validateMessage(message)) {
62
+ throw new Error(`Plugin: ${this.plugin}. Message is malformed: ${JSON.stringify(this.messageSchemaValidatorV1.errors, null, 2)}`);
61
63
  }
62
64
  if (!this.requestValidators.has(message.cmd)) {
63
65
  throw new Error(`Plugin: ${this.plugin}. Unsupported message: ${message.cmd}`);
@@ -74,6 +76,8 @@ export class MessageHandler {
74
76
  process.send({
75
77
  cmd: message.cmd + '_Response',
76
78
  data: result,
79
+ // @ts-expect-error TS2239
80
+ requestId: message.requestId || undefined,
77
81
  status: MessageStatus.SUCCESS,
78
82
  });
79
83
  }
@@ -82,7 +86,10 @@ export class MessageHandler {
82
86
  }
83
87
  }
84
88
  validateMessage(message) {
85
- return this.messageSchemaValidator(message);
89
+ return this.messageSchemaValidatorV1(message);
90
+ }
91
+ validateMessageV2(message) {
92
+ return this.messageSchemaValidatorV2(message);
86
93
  }
87
94
  handleErrors(message, e) {
88
95
  if (!message) {
@@ -91,11 +98,13 @@ export class MessageHandler {
91
98
  if (!message.hasOwnProperty('cmd')) {
92
99
  return;
93
100
  }
94
- // @ts-ignore
101
+ // @ts-expect-error TS2239
95
102
  const cmd = message.cmd + '_Response';
96
103
  if (e instanceof SudoError) {
97
104
  return process.send?.({
98
105
  cmd,
106
+ // @ts-expect-error TS2239
107
+ requestId: message.requestId || undefined,
99
108
  data: `Plugin: '${this.plugin.name}'. Forbidden usage of sudo for command '${e.command}'. Please contact the plugin developer to fix this.`,
100
109
  status: MessageStatus.ERROR,
101
110
  });
@@ -103,6 +112,8 @@ export class MessageHandler {
103
112
  const isDebug = process.env.DEBUG?.includes('*') ?? false;
104
113
  process.send?.({
105
114
  cmd,
115
+ // @ts-expect-error TS2239
116
+ requestId: message.requestId || undefined,
106
117
  data: isDebug ? e.stack : e.message,
107
118
  status: MessageStatus.ERROR,
108
119
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.107",
3
+ "version": "1.0.108",
4
4
  "description": "Library plugin library",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -14,7 +14,7 @@
14
14
  "dependencies": {
15
15
  "ajv": "^8.12.0",
16
16
  "ajv-formats": "^2.1.1",
17
- "codify-schemas": "1.0.52",
17
+ "codify-schemas": "1.0.53",
18
18
  "@npmcli/promise-spawn": "^7.0.1",
19
19
  "uuid": "^10.0.0",
20
20
  "lodash.isequal": "^4.5.0"
@@ -207,7 +207,6 @@ describe('Message handler tests', () => {
207
207
  it('handles errors for apply (destroy)', async () => {
208
208
  const resource = new TestResource()
209
209
  const plugin = testPlugin(resource);
210
-
211
210
  const handler = new MessageHandler(plugin);
212
211
 
213
212
  process.send = (message) => {
@@ -228,6 +227,71 @@ describe('Message handler tests', () => {
228
227
  }
229
228
  }
230
229
  })).rejects.to.not.throw;
230
+
231
+ process.send = undefined;
232
+ })
233
+
234
+ it('Supports ipc message v2 (success)', async () => {
235
+ const resource = new TestResource()
236
+ const plugin = testPlugin(resource);
237
+ const handler = new MessageHandler(plugin);
238
+
239
+ process.send = (message) => {
240
+ console.log(message)
241
+ expect(message).toMatchObject({
242
+ cmd: 'plan_Response',
243
+ requestId: 'abcdef',
244
+ status: MessageStatus.SUCCESS,
245
+ })
246
+ return true;
247
+ }
248
+
249
+ await expect(handler.onMessage({
250
+ cmd: 'plan',
251
+ requestId: 'abcdef',
252
+ data: {
253
+ desired: {
254
+ type: 'type',
255
+ name: 'name',
256
+ prop1: 'A',
257
+ prop2: 'B',
258
+ },
259
+ isStateful: false,
260
+ }
261
+ })).resolves.to.eq(undefined);
262
+
263
+ process.send = undefined;
264
+ })
265
+
266
+ it('Supports ipc message v2 (error)', async () => {
267
+ const resource = new TestResource()
268
+ const plugin = testPlugin(resource);
269
+ const handler = new MessageHandler(plugin);
270
+
271
+ process.send = (message) => {
272
+ expect(message).toMatchObject({
273
+ cmd: 'apply_Response',
274
+ requestId: 'abcdef',
275
+ status: MessageStatus.ERROR,
276
+ })
277
+ return true;
278
+ }
279
+
280
+ await expect(handler.onMessage({
281
+ cmd: 'apply', // Supposed to be a plan so that's why it throws
282
+ requestId: 'abcdef',
283
+ data: {
284
+ desired: {
285
+ type: 'type',
286
+ name: 'name',
287
+ prop1: 'A',
288
+ prop2: 'B',
289
+ },
290
+ isStateful: false,
291
+ }
292
+ })).resolves.to.eq(undefined);
293
+
294
+ process.send = undefined;
231
295
  })
232
296
  });
233
297
 
@@ -11,6 +11,8 @@ import {
11
11
  InitializeResponseDataSchema,
12
12
  IpcMessage,
13
13
  IpcMessageSchema,
14
+ IpcMessageV2,
15
+ IpcMessageV2Schema,
14
16
  MessageStatus,
15
17
  PlanRequestDataSchema,
16
18
  PlanResponseDataSchema,
@@ -61,7 +63,8 @@ const SupportedRequests: Record<string, { handler: (plugin: Plugin, data: any) =
61
63
  export class MessageHandler {
62
64
  private ajv: Ajv;
63
65
  private readonly plugin: Plugin;
64
- private messageSchemaValidator: ValidateFunction;
66
+ private messageSchemaValidatorV1: ValidateFunction;
67
+ private messageSchemaValidatorV2: ValidateFunction;
65
68
  private requestValidators: Map<string, ValidateFunction>;
66
69
  private responseValidators: Map<string, ValidateFunction>;
67
70
 
@@ -71,7 +74,9 @@ export class MessageHandler {
71
74
  this.ajv.addSchema(ResourceSchema);
72
75
  this.plugin = plugin;
73
76
 
74
- this.messageSchemaValidator = this.ajv.compile(IpcMessageSchema);
77
+ this.messageSchemaValidatorV1 = this.ajv.compile(IpcMessageSchema);
78
+ this.messageSchemaValidatorV2 = this.ajv.compile(IpcMessageV2Schema);
79
+
75
80
  this.requestValidators = new Map(
76
81
  Object.entries(SupportedRequests)
77
82
  .map(([k, v]) => [k, this.ajv.compile(v.requestValidator)])
@@ -84,8 +89,8 @@ export class MessageHandler {
84
89
 
85
90
  async onMessage(message: unknown): Promise<void> {
86
91
  try {
87
- if (!this.validateMessage(message)) {
88
- throw new Error(`Plugin: ${this.plugin}. Message is malformed: ${JSON.stringify(this.messageSchemaValidator.errors, null, 2)}`);
92
+ if (!this.validateMessageV2(message) && !this.validateMessage(message)) {
93
+ throw new Error(`Plugin: ${this.plugin}. Message is malformed: ${JSON.stringify(this.messageSchemaValidatorV1.errors, null, 2)}`);
89
94
  }
90
95
 
91
96
  if (!this.requestValidators.has(message.cmd)) {
@@ -107,6 +112,8 @@ export class MessageHandler {
107
112
  process.send!({
108
113
  cmd: message.cmd + '_Response',
109
114
  data: result,
115
+ // @ts-expect-error TS2239
116
+ requestId: message.requestId || undefined,
110
117
  status: MessageStatus.SUCCESS,
111
118
  })
112
119
 
@@ -116,7 +123,11 @@ export class MessageHandler {
116
123
  }
117
124
 
118
125
  private validateMessage(message: unknown): message is IpcMessage {
119
- return this.messageSchemaValidator(message);
126
+ return this.messageSchemaValidatorV1(message);
127
+ }
128
+
129
+ private validateMessageV2(message: unknown): message is IpcMessageV2 {
130
+ return this.messageSchemaValidatorV2(message);
120
131
  }
121
132
 
122
133
  private handleErrors(message: unknown, e: Error) {
@@ -128,12 +139,14 @@ export class MessageHandler {
128
139
  return;
129
140
  }
130
141
 
131
- // @ts-ignore
142
+ // @ts-expect-error TS2239
132
143
  const cmd = message.cmd + '_Response';
133
144
 
134
145
  if (e instanceof SudoError) {
135
146
  return process.send?.({
136
147
  cmd,
148
+ // @ts-expect-error TS2239
149
+ requestId: message.requestId || undefined,
137
150
  data: `Plugin: '${this.plugin.name}'. Forbidden usage of sudo for command '${e.command}'. Please contact the plugin developer to fix this.`,
138
151
  status: MessageStatus.ERROR,
139
152
  })
@@ -143,6 +156,8 @@ export class MessageHandler {
143
156
 
144
157
  process.send?.({
145
158
  cmd,
159
+ // @ts-expect-error TS2239
160
+ requestId: message.requestId || undefined,
146
161
  data: isDebug ? e.stack : e.message,
147
162
  status: MessageStatus.ERROR,
148
163
  })