codify-plugin-lib 1.0.151 → 1.0.152
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/plugin/plugin.js +2 -16
- package/dist/resource/resource-controller.d.ts +1 -0
- package/dist/resource/resource-controller.js +31 -0
- package/dist/resource/resource-settings.d.ts +1 -1
- package/package.json +1 -1
- package/src/plugin/plugin.ts +2 -21
- package/src/resource/resource-controller.ts +42 -0
- package/src/resource/resource-settings.ts +1 -1
package/dist/plugin/plugin.js
CHANGED
|
@@ -39,6 +39,7 @@ export class Plugin {
|
|
|
39
39
|
const resource = this.resourceControllers.get(data.type);
|
|
40
40
|
const schema = resource.settings.schema;
|
|
41
41
|
const requiredPropertyNames = (resource.settings.importAndDestroy?.requiredParameters
|
|
42
|
+
?? (typeof resource.settings.allowMultiple === 'object' ? resource.settings.allowMultiple.identifyingParameters : null)
|
|
42
43
|
?? schema?.required
|
|
43
44
|
?? undefined);
|
|
44
45
|
const allowMultiple = resource.settings.allowMultiple !== undefined
|
|
@@ -64,22 +65,7 @@ export class Plugin {
|
|
|
64
65
|
if (!resource) {
|
|
65
66
|
throw new Error(`Resource of type ${resourceConfig.core.type} could not be found for match`);
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
-
return { match: array.find((r) => r.core.type === resourceConfig.core.type) };
|
|
69
|
-
}
|
|
70
|
-
const parameterMatcher = resource?.parsedSettings.matcher;
|
|
71
|
-
const match = array.find((r) => {
|
|
72
|
-
if (resourceConfig.core.type !== r.core.type) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
// If the user specifies the same name for the resource and it's not auto-generated (a number) then it's the same resource
|
|
76
|
-
if (resourceConfig.core.name === r.core.name
|
|
77
|
-
&& resourceConfig.core.name
|
|
78
|
-
&& Number.isInteger(Number.parseInt(resourceConfig.core.name, 10))) {
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
return parameterMatcher(resourceConfig.parameters, r.parameters);
|
|
82
|
-
});
|
|
68
|
+
const match = await resource.match(resourceConfig, array);
|
|
83
69
|
return { match };
|
|
84
70
|
}
|
|
85
71
|
async import(data) {
|
|
@@ -15,6 +15,7 @@ export declare class ResourceController<T extends StringIndexedObject> {
|
|
|
15
15
|
constructor(resource: Resource<T>);
|
|
16
16
|
initialize(): Promise<void>;
|
|
17
17
|
validate(core: ResourceConfig, parameters: Partial<T>): Promise<ValidateResponseData['resourceValidations'][0]>;
|
|
18
|
+
match(resource: ResourceJson, array: Array<ResourceJson>): Promise<ResourceJson | undefined>;
|
|
18
19
|
plan(core: ResourceConfig, desired: Partial<T> | null, state: Partial<T> | null, isStateful?: boolean): Promise<Plan<T>>;
|
|
19
20
|
planDestroy(core: ResourceConfig, parameters: Partial<T>): Promise<Plan<T>>;
|
|
20
21
|
apply(plan: Plan<T>): Promise<void>;
|
|
@@ -71,6 +71,37 @@ export class ResourceController {
|
|
|
71
71
|
schemaValidationErrors: [],
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
+
async match(resource, array) {
|
|
75
|
+
if (resource.core.type !== this.typeId) {
|
|
76
|
+
throw new Error(`Unknown type passed into match method: ${resource.core.type} for ${this.typeId}`);
|
|
77
|
+
}
|
|
78
|
+
if (!this.parsedSettings.allowMultiple) {
|
|
79
|
+
return array.find((r) => r.core.type === resource.core.type);
|
|
80
|
+
}
|
|
81
|
+
const { name, type } = resource.core;
|
|
82
|
+
const parameterMatcher = this.parsedSettings.matcher;
|
|
83
|
+
for (const resourceToMatch of array) {
|
|
84
|
+
if (type !== resourceToMatch.core.type) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
// If the user specifies the same name for the resource and it's not auto-generated (a number) then it's the same resource
|
|
88
|
+
if (name === resourceToMatch.core.name
|
|
89
|
+
&& name
|
|
90
|
+
&& Number.isInteger(Number.parseInt(name, 10))) {
|
|
91
|
+
return resourceToMatch;
|
|
92
|
+
}
|
|
93
|
+
const originalParams = structuredClone(resource.parameters);
|
|
94
|
+
const paramsToMatch = structuredClone(resourceToMatch.parameters);
|
|
95
|
+
this.addDefaultValues(originalParams);
|
|
96
|
+
await this.applyTransformParameters(originalParams);
|
|
97
|
+
this.addDefaultValues(paramsToMatch);
|
|
98
|
+
await this.applyTransformParameters(paramsToMatch);
|
|
99
|
+
const match = parameterMatcher(originalParams, paramsToMatch);
|
|
100
|
+
if (match) {
|
|
101
|
+
return resourceToMatch;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
74
105
|
async plan(core, desired, state, isStateful = false) {
|
|
75
106
|
this.validatePlanInputs(core, desired, state, isStateful);
|
|
76
107
|
this.addDefaultValues(desired);
|
|
@@ -96,7 +96,7 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
96
96
|
preventImport?: boolean;
|
|
97
97
|
/**
|
|
98
98
|
* Customize the required parameters needed to import this resource. By default, the `requiredParameters` are taken
|
|
99
|
-
* from the
|
|
99
|
+
* from the identifyingParameters for allowMultiple. The `requiredParameters` parameter must be declared if a complex required is declared in
|
|
100
100
|
* the schema (contains `oneOf`, `anyOf`, `allOf`, `if`, `then`, `else`).
|
|
101
101
|
* <br>
|
|
102
102
|
* The user will be prompted for the required parameters before the import starts. This is done because for most resources
|
package/package.json
CHANGED
package/src/plugin/plugin.ts
CHANGED
|
@@ -70,6 +70,7 @@ export class Plugin {
|
|
|
70
70
|
const schema = resource.settings.schema as JSONSchemaType<any> | undefined;
|
|
71
71
|
const requiredPropertyNames = (
|
|
72
72
|
resource.settings.importAndDestroy?.requiredParameters
|
|
73
|
+
?? (typeof resource.settings.allowMultiple === 'object' ? resource.settings.allowMultiple.identifyingParameters : null)
|
|
73
74
|
?? schema?.required
|
|
74
75
|
?? undefined
|
|
75
76
|
) as any;
|
|
@@ -101,27 +102,7 @@ export class Plugin {
|
|
|
101
102
|
throw new Error(`Resource of type ${resourceConfig.core.type} could not be found for match`);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
return { match: array.find((r) => r.core.type === resourceConfig.core.type) }
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const parameterMatcher = resource?.parsedSettings.matcher;
|
|
109
|
-
const match = array.find((r) => {
|
|
110
|
-
if (resourceConfig.core.type !== r.core.type) {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// If the user specifies the same name for the resource and it's not auto-generated (a number) then it's the same resource
|
|
115
|
-
if (resourceConfig.core.name === r.core.name
|
|
116
|
-
&& resourceConfig.core.name
|
|
117
|
-
&& Number.isInteger(Number.parseInt(resourceConfig.core.name, 10))
|
|
118
|
-
) {
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return parameterMatcher(resourceConfig.parameters, r.parameters);
|
|
123
|
-
});
|
|
124
|
-
|
|
105
|
+
const match = await resource.match(resourceConfig, array);
|
|
125
106
|
return { match }
|
|
126
107
|
}
|
|
127
108
|
|
|
@@ -102,6 +102,48 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
async match(resource: ResourceJson, array: Array<ResourceJson>): Promise<ResourceJson | undefined> {
|
|
106
|
+
if (resource.core.type !== this.typeId) {
|
|
107
|
+
throw new Error(`Unknown type passed into match method: ${resource.core.type} for ${this.typeId}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!this.parsedSettings.allowMultiple) {
|
|
111
|
+
return array.find((r) => r.core.type === resource.core.type)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
const { name, type } = resource.core;
|
|
116
|
+
const parameterMatcher = this.parsedSettings.matcher;
|
|
117
|
+
|
|
118
|
+
for (const resourceToMatch of array) {
|
|
119
|
+
if (type !== resourceToMatch.core.type) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// If the user specifies the same name for the resource and it's not auto-generated (a number) then it's the same resource
|
|
124
|
+
if (name === resourceToMatch.core.name
|
|
125
|
+
&& name
|
|
126
|
+
&& Number.isInteger(Number.parseInt(name, 10))
|
|
127
|
+
) {
|
|
128
|
+
return resourceToMatch;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const originalParams = structuredClone(resource.parameters) as Partial<T>;
|
|
132
|
+
const paramsToMatch = structuredClone(resourceToMatch.parameters) as Partial<T>;
|
|
133
|
+
|
|
134
|
+
this.addDefaultValues(originalParams);
|
|
135
|
+
await this.applyTransformParameters(originalParams);
|
|
136
|
+
|
|
137
|
+
this.addDefaultValues(paramsToMatch);
|
|
138
|
+
await this.applyTransformParameters(paramsToMatch);
|
|
139
|
+
|
|
140
|
+
const match = parameterMatcher(originalParams, paramsToMatch);
|
|
141
|
+
if (match) {
|
|
142
|
+
return resourceToMatch;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
105
147
|
async plan(
|
|
106
148
|
core: ResourceConfig,
|
|
107
149
|
desired: Partial<T> | null,
|
|
@@ -113,7 +113,7 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
115
|
* Customize the required parameters needed to import this resource. By default, the `requiredParameters` are taken
|
|
116
|
-
* from the
|
|
116
|
+
* from the identifyingParameters for allowMultiple. The `requiredParameters` parameter must be declared if a complex required is declared in
|
|
117
117
|
* the schema (contains `oneOf`, `anyOf`, `allOf`, `if`, `then`, `else`).
|
|
118
118
|
* <br>
|
|
119
119
|
* The user will be prompted for the required parameters before the import starts. This is done because for most resources
|