codify-plugin-lib 1.0.37 → 1.0.39
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.d.ts +17 -9
- package/dist/entities/change-set.js +91 -36
- package/dist/entities/plan-types.d.ts +11 -0
- package/dist/entities/plan-types.js +1 -0
- package/dist/entities/plan.d.ts +10 -7
- package/dist/entities/plan.js +53 -8
- package/dist/entities/plugin.js +9 -8
- package/dist/entities/resource-types.d.ts +24 -0
- package/dist/entities/resource-types.js +1 -0
- package/dist/entities/resource.d.ts +20 -15
- package/dist/entities/resource.js +137 -62
- package/dist/entities/stateful-parameter.d.ts +22 -8
- package/dist/entities/stateful-parameter.js +33 -0
- package/dist/entities/test.d.ts +1 -0
- package/dist/entities/test.js +22 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/utils/common-types.d.ts +3 -0
- package/dist/utils/common-types.js +1 -0
- package/dist/utils/utils.d.ts +6 -0
- package/dist/utils/utils.js +15 -0
- package/package.json +2 -2
- package/src/entities/change-set.test.ts +24 -36
- package/src/entities/change-set.ts +138 -47
- package/src/entities/plan-types.ts +26 -0
- package/src/entities/plan.ts +87 -16
- package/src/entities/plugin.ts +11 -9
- package/src/entities/resource-parameters.test.ts +159 -0
- package/src/entities/resource-types.ts +47 -0
- package/src/entities/resource.test.ts +77 -215
- package/src/entities/resource.ts +203 -91
- package/src/entities/stateful-parameter.ts +56 -8
- package/src/index.ts +3 -0
- package/src/utils/utils.ts +21 -0
|
@@ -1,63 +1,54 @@
|
|
|
1
1
|
import { Resource } from './resource.js';
|
|
2
|
-
import {
|
|
3
|
-
import { ChangeSet, ParameterChange } from './change-set.js';
|
|
2
|
+
import { ResourceOperation, StringIndexedObject } from 'codify-schemas';
|
|
4
3
|
import { spy } from 'sinon';
|
|
5
4
|
import { Plan } from './plan.js';
|
|
6
|
-
import { StatefulParameter } from './stateful-parameter.js';
|
|
7
5
|
import { describe, expect, it } from 'vitest'
|
|
6
|
+
import { ResourceConfiguration, ValidationResult } from './resource-types.js';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
export interface TestConfig extends StringIndexedObject {
|
|
9
|
+
propA: string;
|
|
10
|
+
propB: number;
|
|
11
|
+
propC?: string;
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
export class TestResource extends Resource<TestConfig> {
|
|
15
|
+
constructor(options: ResourceConfiguration<TestConfig>) {
|
|
16
|
+
super(options);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
applyCreate(plan: Plan<TestConfig>): Promise<void> {
|
|
19
20
|
return Promise.resolve(undefined);
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
applyDestroy(plan: Plan<TestConfig>): Promise<void> {
|
|
23
24
|
return Promise.resolve(undefined);
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async validate(config: ResourceConfig): Promise<string | undefined> {
|
|
35
|
-
return undefined;
|
|
27
|
+
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
28
|
+
return {
|
|
29
|
+
propA: 'a',
|
|
30
|
+
propB: 10,
|
|
31
|
+
propC: 'c',
|
|
32
|
+
};
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
return
|
|
35
|
+
async validate(config: unknown): Promise<ValidationResult> {
|
|
36
|
+
return {
|
|
37
|
+
isValid: true
|
|
38
|
+
}
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
interface TestConfig extends ResourceConfig {
|
|
44
|
-
propA: string;
|
|
45
|
-
propB: number;
|
|
46
|
-
propC?: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
42
|
describe('Resource tests', () => {
|
|
50
43
|
it('plans correctly', async () => {
|
|
51
44
|
const resource = new class extends TestResource {
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
constructor() {
|
|
46
|
+
super({ type: 'type' });
|
|
54
47
|
}
|
|
55
48
|
|
|
56
|
-
async
|
|
49
|
+
async refresh(): Promise<TestConfig> {
|
|
57
50
|
return {
|
|
58
|
-
|
|
59
|
-
name: 'name',
|
|
60
|
-
propA: "propABefore",
|
|
51
|
+
propA: 'propABefore',
|
|
61
52
|
propB: 10,
|
|
62
53
|
};
|
|
63
54
|
}
|
|
@@ -71,20 +62,20 @@ describe('Resource tests', () => {
|
|
|
71
62
|
propB: 10,
|
|
72
63
|
})
|
|
73
64
|
|
|
74
|
-
expect(result.
|
|
65
|
+
expect(result.desiredConfig).to.deep.eq({
|
|
75
66
|
type: 'type',
|
|
76
67
|
name: 'name',
|
|
77
68
|
propA: 'propA',
|
|
78
69
|
propB: 10,
|
|
79
70
|
});
|
|
80
|
-
expect(result.changeSet.operation).to.eq(ResourceOperation.
|
|
71
|
+
expect(result.changeSet.operation).to.eq(ResourceOperation.RECREATE);
|
|
81
72
|
expect(result.changeSet.parameterChanges[0]).to.deep.eq({
|
|
82
73
|
name: 'propA',
|
|
83
74
|
previousValue: 'propABefore',
|
|
84
75
|
newValue: 'propA',
|
|
85
76
|
operation: 'modify'
|
|
86
77
|
})
|
|
87
|
-
expect(result.changeSet.parameterChanges[1]).to.deep.eq(
|
|
78
|
+
expect(result.changeSet.parameterChanges[1]).to.deep.eq({
|
|
88
79
|
name: 'propB',
|
|
89
80
|
previousValue: 10,
|
|
90
81
|
newValue: 10,
|
|
@@ -92,25 +83,19 @@ describe('Resource tests', () => {
|
|
|
92
83
|
})
|
|
93
84
|
})
|
|
94
85
|
|
|
95
|
-
it('
|
|
86
|
+
it('creates the resource if it doesnt exist', async () => {
|
|
96
87
|
const resource = new class extends TestResource {
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
constructor() {
|
|
89
|
+
super({ type: 'type' });
|
|
99
90
|
}
|
|
100
91
|
|
|
101
|
-
async
|
|
102
|
-
return
|
|
103
|
-
type: 'type',
|
|
104
|
-
name: 'name',
|
|
105
|
-
propA: "propABefore",
|
|
106
|
-
propB: 10,
|
|
107
|
-
propC: 'somethingBefore'
|
|
108
|
-
};
|
|
92
|
+
async refresh(): Promise<TestConfig | null> {
|
|
93
|
+
return null;
|
|
109
94
|
}
|
|
110
95
|
}
|
|
111
96
|
|
|
112
97
|
const resourceSpy = spy(resource);
|
|
113
|
-
await resourceSpy.plan({
|
|
98
|
+
const result = await resourceSpy.plan({
|
|
114
99
|
type: 'type',
|
|
115
100
|
name: 'name',
|
|
116
101
|
propA: 'propA',
|
|
@@ -118,45 +103,41 @@ describe('Resource tests', () => {
|
|
|
118
103
|
propC: 'somethingAfter'
|
|
119
104
|
})
|
|
120
105
|
|
|
121
|
-
expect(
|
|
106
|
+
expect(result.changeSet.operation).to.eq(ResourceOperation.CREATE);
|
|
107
|
+
expect(result.changeSet.parameterChanges.length).to.eq(3);
|
|
122
108
|
})
|
|
123
109
|
|
|
124
|
-
it('
|
|
110
|
+
it('handles empty parameters', async () => {
|
|
125
111
|
const resource = new class extends TestResource {
|
|
126
|
-
|
|
127
|
-
|
|
112
|
+
constructor() {
|
|
113
|
+
super({ type: 'type' });
|
|
128
114
|
}
|
|
129
115
|
|
|
130
|
-
async
|
|
116
|
+
async refresh(): Promise<Partial<TestConfig> | null> {
|
|
131
117
|
return null;
|
|
132
118
|
}
|
|
133
119
|
}
|
|
134
120
|
|
|
135
121
|
const resourceSpy = spy(resource);
|
|
136
|
-
const result = await resourceSpy.plan({
|
|
137
|
-
type: 'type',
|
|
138
|
-
name: 'name',
|
|
139
|
-
propA: 'propA',
|
|
140
|
-
propB: 10,
|
|
141
|
-
propC: 'somethingAfter'
|
|
142
|
-
})
|
|
122
|
+
const result = await resourceSpy.plan({ type: 'type' })
|
|
143
123
|
|
|
144
124
|
expect(result.changeSet.operation).to.eq(ResourceOperation.CREATE);
|
|
145
|
-
expect(result.changeSet.parameterChanges.length).to.eq(
|
|
125
|
+
expect(result.changeSet.parameterChanges.length).to.eq(0);
|
|
146
126
|
})
|
|
147
127
|
|
|
148
128
|
it('chooses the create apply properly', async () => {
|
|
149
129
|
const resource = new class extends TestResource {
|
|
150
|
-
|
|
151
|
-
|
|
130
|
+
constructor() {
|
|
131
|
+
super({ type: 'resource' });
|
|
152
132
|
}
|
|
153
133
|
}
|
|
154
134
|
|
|
155
135
|
const resourceSpy = spy(resource);
|
|
156
136
|
const result = await resourceSpy.apply(
|
|
157
|
-
Plan.create(
|
|
158
|
-
|
|
159
|
-
{ type: 'resource'
|
|
137
|
+
Plan.create<TestConfig>(
|
|
138
|
+
{ type: 'resource', propA: 'a', propB: 0 },
|
|
139
|
+
{ type: 'resource' },
|
|
140
|
+
{ statefulMode: false },
|
|
160
141
|
)
|
|
161
142
|
)
|
|
162
143
|
|
|
@@ -165,186 +146,67 @@ describe('Resource tests', () => {
|
|
|
165
146
|
|
|
166
147
|
it('chooses the destroy apply properly', async () => {
|
|
167
148
|
const resource = new class extends TestResource {
|
|
168
|
-
|
|
169
|
-
|
|
149
|
+
constructor() {
|
|
150
|
+
super({ type: 'resource' });
|
|
170
151
|
}
|
|
171
152
|
}
|
|
172
153
|
|
|
173
154
|
const resourceSpy = spy(resource);
|
|
174
155
|
const result = await resourceSpy.apply(
|
|
175
|
-
Plan.create(
|
|
176
|
-
|
|
177
|
-
{ type: 'resource', propA: 'a', propB: 0 }
|
|
156
|
+
Plan.create<TestConfig>(
|
|
157
|
+
{ type: 'resource' },
|
|
158
|
+
{ type: 'resource', propA: 'a', propB: 0 },
|
|
159
|
+
{ statefulMode: true },
|
|
178
160
|
)
|
|
179
161
|
)
|
|
180
162
|
|
|
181
163
|
expect(resourceSpy.applyDestroy.calledOnce).to.be.true;
|
|
182
164
|
})
|
|
183
165
|
|
|
184
|
-
it('
|
|
166
|
+
it('Defaults parameter changes to recreate', async () => {
|
|
185
167
|
const resource = new class extends TestResource {
|
|
186
|
-
getTypeId(): string {
|
|
187
|
-
return 'resource'
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const resourceSpy = spy(resource);
|
|
192
|
-
const result = await resourceSpy.apply(
|
|
193
|
-
Plan.create(
|
|
194
|
-
new ChangeSet(ResourceOperation.MODIFY, [
|
|
195
|
-
{
|
|
196
|
-
name: 'propA',
|
|
197
|
-
newValue: 'a',
|
|
198
|
-
previousValue: 'b',
|
|
199
|
-
operation: ParameterOperation.ADD,
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
name: 'propB',
|
|
203
|
-
newValue: 0,
|
|
204
|
-
previousValue: -1,
|
|
205
|
-
operation: ParameterOperation.ADD,
|
|
206
|
-
},
|
|
207
|
-
]),
|
|
208
|
-
{ type: 'resource', propA: 'a', propB: 0 }
|
|
209
|
-
)
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
expect(resourceSpy.applyModify.calledOnce).to.be.true;
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
it('supports the creation of stateful parameters', async () => {
|
|
216
|
-
const statefulParameter = new class implements StatefulParameter<TestConfig, 'propA'> {
|
|
217
|
-
get name(): "propA" {
|
|
218
|
-
return 'propA';
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
applyAdd(parameterChange: ParameterChange, plan: Plan<TestConfig>): Promise<void> {
|
|
222
|
-
return Promise.resolve(undefined);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
applyModify(parameterChange: ParameterChange, plan: Plan<TestConfig>): Promise<void> {
|
|
226
|
-
return Promise.resolve(undefined);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
applyRemove(parameterChange: ParameterChange, plan: Plan<TestConfig>): Promise<void> {
|
|
230
|
-
return Promise.resolve(undefined);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
async getCurrent(): Promise<TestConfig["propA"]> {
|
|
234
|
-
return '';
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const statefulParameterSpy = spy(statefulParameter);
|
|
239
|
-
|
|
240
|
-
const resource = new class extends TestResource {
|
|
241
|
-
|
|
242
168
|
constructor() {
|
|
243
|
-
super();
|
|
244
|
-
this.registerStatefulParameter(statefulParameterSpy)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
getTypeId(): string {
|
|
248
|
-
return 'resource'
|
|
169
|
+
super({ type: 'resource' });
|
|
249
170
|
}
|
|
250
171
|
}
|
|
251
172
|
|
|
252
173
|
const resourceSpy = spy(resource);
|
|
253
174
|
const result = await resourceSpy.apply(
|
|
254
|
-
Plan.create(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
newValue: 'a',
|
|
259
|
-
previousValue: null,
|
|
260
|
-
operation: ParameterOperation.ADD,
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
name: 'propB',
|
|
264
|
-
newValue: 0,
|
|
265
|
-
previousValue: null,
|
|
266
|
-
operation: ParameterOperation.ADD,
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
name: 'propC',
|
|
270
|
-
newValue: 'b',
|
|
271
|
-
previousValue: null,
|
|
272
|
-
operation: ParameterOperation.ADD,
|
|
273
|
-
},
|
|
274
|
-
]),
|
|
275
|
-
{ type: 'resource', propA: 'a', propB: 0, propC: 'b' }
|
|
175
|
+
Plan.create<TestConfig>(
|
|
176
|
+
{ type: 'resource', propA: 'a', propB: 0 },
|
|
177
|
+
{ type: 'resource', propA: 'b', propB: -1 },
|
|
178
|
+
{ statefulMode: true },
|
|
276
179
|
)
|
|
277
180
|
);
|
|
278
181
|
|
|
279
|
-
expect(
|
|
182
|
+
expect(resourceSpy.applyDestroy.calledOnce).to.be.true;
|
|
280
183
|
expect(resourceSpy.applyCreate.calledOnce).to.be.true;
|
|
281
184
|
})
|
|
282
185
|
|
|
283
|
-
it('
|
|
284
|
-
const statefulParameter = new class implements StatefulParameter<TestConfig, 'propA'> {
|
|
285
|
-
get name(): "propA" {
|
|
286
|
-
return 'propA';
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
applyAdd(parameterChange: ParameterChange, plan: Plan<TestConfig>): Promise<void> {
|
|
290
|
-
return Promise.resolve(undefined);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
applyModify(parameterChange: ParameterChange, plan: Plan<TestConfig>): Promise<void> {
|
|
294
|
-
return Promise.resolve(undefined);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
applyRemove(parameterChange: ParameterChange, plan: Plan<TestConfig>): Promise<void> {
|
|
298
|
-
return Promise.resolve(undefined);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
async getCurrent(): Promise<TestConfig["propA"]> {
|
|
302
|
-
return '';
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const statefulParameterSpy = spy(statefulParameter);
|
|
307
|
-
|
|
186
|
+
it('Allows modification of parameter behavior to allow modify for parameters', async () => {
|
|
308
187
|
const resource = new class extends TestResource {
|
|
309
|
-
|
|
310
188
|
constructor() {
|
|
311
|
-
super(
|
|
312
|
-
|
|
189
|
+
super({
|
|
190
|
+
type: 'resource',
|
|
191
|
+
parameterConfigurations: {
|
|
192
|
+
propA: { planOperation: ResourceOperation.MODIFY },
|
|
193
|
+
propB: { planOperation: ResourceOperation.MODIFY },
|
|
194
|
+
}
|
|
195
|
+
});
|
|
313
196
|
}
|
|
314
197
|
|
|
315
|
-
|
|
316
|
-
return '
|
|
198
|
+
async refresh(): Promise<TestConfig | null> {
|
|
199
|
+
return { propA: 'b', propB: -1 };
|
|
317
200
|
}
|
|
318
201
|
}
|
|
319
202
|
|
|
203
|
+
const plan = await resource.plan({ type: 'resource', propA: 'a', propB: 0 })
|
|
204
|
+
|
|
320
205
|
const resourceSpy = spy(resource);
|
|
321
206
|
const result = await resourceSpy.apply(
|
|
322
|
-
|
|
323
|
-
new ChangeSet(ResourceOperation.MODIFY, [
|
|
324
|
-
{
|
|
325
|
-
name: 'propA',
|
|
326
|
-
newValue: 'a',
|
|
327
|
-
previousValue: 'b',
|
|
328
|
-
operation: ParameterOperation.MODIFY,
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
name: 'propB',
|
|
332
|
-
newValue: 0,
|
|
333
|
-
previousValue: null,
|
|
334
|
-
operation: ParameterOperation.ADD,
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
name: 'propC',
|
|
338
|
-
newValue: 'b',
|
|
339
|
-
previousValue: 'b',
|
|
340
|
-
operation: ParameterOperation.NOOP,
|
|
341
|
-
},
|
|
342
|
-
]),
|
|
343
|
-
{ type: 'resource', propA: 'a', propB: 0, propC: 'b' }
|
|
344
|
-
)
|
|
207
|
+
plan
|
|
345
208
|
);
|
|
346
209
|
|
|
347
|
-
expect(
|
|
348
|
-
expect(resourceSpy.applyModify.calledOnce).to.be.true;
|
|
210
|
+
expect(resourceSpy.applyModify.calledTwice).to.be.true;
|
|
349
211
|
})
|
|
350
|
-
})
|
|
212
|
+
});
|