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