@backstage/plugin-catalog-backend 1.6.0-next.0 → 1.6.0-next.1
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/CHANGELOG.md +48 -0
- package/alpha/package.json +1 -1
- package/dist/index.alpha.d.ts +7 -1
- package/dist/index.beta.d.ts +6 -0
- package/dist/index.cjs.js +39 -31
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/package.json +19 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-backend
|
|
2
2
|
|
|
3
|
+
## 1.6.0-next.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c395abb5b2: The catalog no longer stops after the first processor `validateEntityKind`
|
|
8
|
+
method returns `true` when validating entity kind shapes. Instead, it continues
|
|
9
|
+
through all registered processors that have this method, and requires that _at
|
|
10
|
+
least one_ of them returned true.
|
|
11
|
+
|
|
12
|
+
The old behavior of stopping early made it harder to extend existing core kinds
|
|
13
|
+
with additional fields, since the `BuiltinKindsEntityProcessor` is always
|
|
14
|
+
present at the top of the processing chain and ensures that your additional
|
|
15
|
+
validation code would never be run.
|
|
16
|
+
|
|
17
|
+
This is technically a breaking change, although it should not affect anybody
|
|
18
|
+
under normal circumstances, except if you had problematic validation code that
|
|
19
|
+
you were unaware that it was not being run. That code may now start to exhibit
|
|
20
|
+
those problems.
|
|
21
|
+
|
|
22
|
+
If you need to disable this new behavior, `CatalogBuilder` as used in your
|
|
23
|
+
`packages/backend/src/plugins/catalog.ts` file now has a
|
|
24
|
+
`useLegacySingleProcessorValidation()` method to go back to the old behavior.
|
|
25
|
+
|
|
26
|
+
```diff
|
|
27
|
+
const builder = await CatalogBuilder.create(env);
|
|
28
|
+
+builder.useLegacySingleProcessorValidation();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- 2a8e3cc0b5: Optimize `Stitcher` process to be more memory efficient
|
|
34
|
+
- 5b3e2afa45: Fixed deprecated use of `substr` into `substring`.
|
|
35
|
+
- Updated dependencies
|
|
36
|
+
- @backstage/backend-common@0.17.0-next.1
|
|
37
|
+
- @backstage/types@1.0.2-next.1
|
|
38
|
+
- @backstage/backend-plugin-api@0.1.5-next.1
|
|
39
|
+
- @backstage/plugin-catalog-node@1.2.2-next.1
|
|
40
|
+
- @backstage/plugin-permission-node@0.7.2-next.1
|
|
41
|
+
- @backstage/config@1.0.5-next.1
|
|
42
|
+
- @backstage/integration@1.4.1-next.1
|
|
43
|
+
- @backstage/catalog-client@1.2.0-next.1
|
|
44
|
+
- @backstage/catalog-model@1.1.4-next.1
|
|
45
|
+
- @backstage/errors@1.1.4-next.1
|
|
46
|
+
- @backstage/plugin-catalog-common@1.0.9-next.1
|
|
47
|
+
- @backstage/plugin-permission-common@0.7.2-next.1
|
|
48
|
+
- @backstage/plugin-scaffolder-common@1.2.3-next.1
|
|
49
|
+
- @backstage/plugin-search-common@1.1.2-next.1
|
|
50
|
+
|
|
3
51
|
## 1.6.0-next.0
|
|
4
52
|
|
|
5
53
|
### Minor Changes
|
package/alpha/package.json
CHANGED
package/dist/index.alpha.d.ts
CHANGED
|
@@ -177,6 +177,7 @@ export declare class CatalogBuilder {
|
|
|
177
177
|
private locationAnalyzer;
|
|
178
178
|
private readonly permissionRules;
|
|
179
179
|
private allowedLocationType;
|
|
180
|
+
private legacySingleProcessorValidation;
|
|
180
181
|
/**
|
|
181
182
|
* Creates a catalog builder.
|
|
182
183
|
*/
|
|
@@ -306,13 +307,18 @@ export declare class CatalogBuilder {
|
|
|
306
307
|
* @param permissionRules - Additional permission rules
|
|
307
308
|
* @alpha
|
|
308
309
|
*/
|
|
309
|
-
addPermissionRules(...permissionRules: Array<CatalogPermissionRule | Array<CatalogPermissionRule>>):
|
|
310
|
+
addPermissionRules(...permissionRules: Array<CatalogPermissionRule | Array<CatalogPermissionRule>>): this;
|
|
310
311
|
/**
|
|
311
312
|
* Sets up the allowed location types from being registered via the location service.
|
|
312
313
|
*
|
|
313
314
|
* @param allowedLocationTypes - the allowed location types
|
|
314
315
|
*/
|
|
315
316
|
setAllowedLocationTypes(allowedLocationTypes: string[]): CatalogBuilder;
|
|
317
|
+
/**
|
|
318
|
+
* Enables the legacy behaviour of canceling validation early whenever only a
|
|
319
|
+
* single processor declares an entity kind to be valid.
|
|
320
|
+
*/
|
|
321
|
+
useLegacySingleProcessorValidation(): this;
|
|
316
322
|
/**
|
|
317
323
|
* Wires up and returns all of the component parts of the catalog
|
|
318
324
|
*/
|
package/dist/index.beta.d.ts
CHANGED
|
@@ -177,6 +177,7 @@ export declare class CatalogBuilder {
|
|
|
177
177
|
private locationAnalyzer;
|
|
178
178
|
private readonly permissionRules;
|
|
179
179
|
private allowedLocationType;
|
|
180
|
+
private legacySingleProcessorValidation;
|
|
180
181
|
/**
|
|
181
182
|
* Creates a catalog builder.
|
|
182
183
|
*/
|
|
@@ -305,6 +306,11 @@ export declare class CatalogBuilder {
|
|
|
305
306
|
* @param allowedLocationTypes - the allowed location types
|
|
306
307
|
*/
|
|
307
308
|
setAllowedLocationTypes(allowedLocationTypes: string[]): CatalogBuilder;
|
|
309
|
+
/**
|
|
310
|
+
* Enables the legacy behaviour of canceling validation early whenever only a
|
|
311
|
+
* single processor declares an entity kind to be valid.
|
|
312
|
+
*/
|
|
313
|
+
useLegacySingleProcessorValidation(): this;
|
|
308
314
|
/**
|
|
309
315
|
* Wires up and returns all of the component parts of the catalog
|
|
310
316
|
*/
|
package/dist/index.cjs.js
CHANGED
|
@@ -601,7 +601,7 @@ class PlaceholderProcessor {
|
|
|
601
601
|
} else if (keys.length !== 1) {
|
|
602
602
|
return [data, false];
|
|
603
603
|
}
|
|
604
|
-
const resolverKey = keys[0].
|
|
604
|
+
const resolverKey = keys[0].substring(1);
|
|
605
605
|
const resolverValue = data[keys[0]];
|
|
606
606
|
const resolver = this.options.resolvers[resolverKey];
|
|
607
607
|
if (!resolver) {
|
|
@@ -2930,13 +2930,16 @@ class DefaultCatalogProcessingOrchestrator {
|
|
|
2930
2930
|
e
|
|
2931
2931
|
);
|
|
2932
2932
|
}
|
|
2933
|
-
let
|
|
2933
|
+
let valid = false;
|
|
2934
2934
|
for (const processor of this.options.processors) {
|
|
2935
2935
|
if (processor.validateEntityKind) {
|
|
2936
2936
|
try {
|
|
2937
|
-
|
|
2938
|
-
if (
|
|
2939
|
-
|
|
2937
|
+
const thisValid = await processor.validateEntityKind(entity);
|
|
2938
|
+
if (thisValid) {
|
|
2939
|
+
valid = true;
|
|
2940
|
+
if (this.options.legacySingleProcessorValidation) {
|
|
2941
|
+
break;
|
|
2942
|
+
}
|
|
2940
2943
|
}
|
|
2941
2944
|
} catch (e) {
|
|
2942
2945
|
throw new errors.InputError(
|
|
@@ -2946,7 +2949,7 @@ class DefaultCatalogProcessingOrchestrator {
|
|
|
2946
2949
|
}
|
|
2947
2950
|
}
|
|
2948
2951
|
}
|
|
2949
|
-
if (!
|
|
2952
|
+
if (!valid) {
|
|
2950
2953
|
throw new errors.InputError(
|
|
2951
2954
|
`No processor recognized the entity ${context.entityRef} as valid, possibly caused by a foreign kind or apiVersion`
|
|
2952
2955
|
);
|
|
@@ -3159,22 +3162,24 @@ class Stitcher {
|
|
|
3159
3162
|
hash: "",
|
|
3160
3163
|
stitch_ticket: ticket
|
|
3161
3164
|
}).onConflict("entity_id").merge(["stitch_ticket"]);
|
|
3162
|
-
const
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3165
|
+
const [processedResult, relationsResult] = await Promise.all([
|
|
3166
|
+
this.database.with("incoming_references", function incomingReferences(builder) {
|
|
3167
|
+
return builder.from("refresh_state_references").where({ target_entity_ref: entityRef }).count({ count: "*" });
|
|
3168
|
+
}).select({
|
|
3169
|
+
entityId: "refresh_state.entity_id",
|
|
3170
|
+
processedEntity: "refresh_state.processed_entity",
|
|
3171
|
+
errors: "refresh_state.errors",
|
|
3172
|
+
incomingReferenceCount: "incoming_references.count",
|
|
3173
|
+
previousHash: "final_entities.hash"
|
|
3174
|
+
}).from("refresh_state").where({ "refresh_state.entity_ref": entityRef }).crossJoin(this.database.raw("incoming_references")).leftOuterJoin("final_entities", {
|
|
3175
|
+
"final_entities.entity_id": "refresh_state.entity_id"
|
|
3176
|
+
}),
|
|
3177
|
+
this.database.distinct({
|
|
3178
|
+
relationType: "type",
|
|
3179
|
+
relationTarget: "target_entity_ref"
|
|
3180
|
+
}).from("relations").where({ source_entity_ref: entityRef }).orderBy("relationType", "asc").orderBy("relationTarget", "asc")
|
|
3181
|
+
]);
|
|
3182
|
+
if (!processedResult.length) {
|
|
3178
3183
|
this.logger.error(
|
|
3179
3184
|
`Unable to stitch ${entityRef}, item does not exist in refresh state table`
|
|
3180
3185
|
);
|
|
@@ -3186,7 +3191,7 @@ class Stitcher {
|
|
|
3186
3191
|
errors,
|
|
3187
3192
|
incomingReferenceCount,
|
|
3188
3193
|
previousHash
|
|
3189
|
-
} =
|
|
3194
|
+
} = processedResult[0];
|
|
3190
3195
|
if (!processedEntity) {
|
|
3191
3196
|
this.logger.debug(
|
|
3192
3197
|
`Unable to stitch ${entityRef}, the entity has not yet been processed`
|
|
@@ -3214,11 +3219,7 @@ class Stitcher {
|
|
|
3214
3219
|
}));
|
|
3215
3220
|
}
|
|
3216
3221
|
}
|
|
3217
|
-
|
|
3218
|
-
result,
|
|
3219
|
-
(r) => `${r.relationType}:${r.relationTarget}`
|
|
3220
|
-
);
|
|
3221
|
-
entity.relations = uniqueRelationRows.filter((row) => row.relationType).map((row) => ({
|
|
3222
|
+
entity.relations = relationsResult.filter((row) => row.relationType).map((row) => ({
|
|
3222
3223
|
type: row.relationType,
|
|
3223
3224
|
targetRef: row.relationTarget
|
|
3224
3225
|
}));
|
|
@@ -3330,8 +3331,8 @@ function parseEntityFilterString(filterString) {
|
|
|
3330
3331
|
const filtersByKey = {};
|
|
3331
3332
|
for (const statement of statements) {
|
|
3332
3333
|
const equalsIndex = statement.indexOf("=");
|
|
3333
|
-
const key = equalsIndex === -1 ? statement : statement.
|
|
3334
|
-
const value = equalsIndex === -1 ? void 0 : statement.
|
|
3334
|
+
const key = equalsIndex === -1 ? statement : statement.substring(0, equalsIndex).trim();
|
|
3335
|
+
const value = equalsIndex === -1 ? void 0 : statement.substring(equalsIndex + 1).trim();
|
|
3335
3336
|
if (!key) {
|
|
3336
3337
|
throw new errors.InputError(
|
|
3337
3338
|
`Invalid filter, '${statement}' is not a valid statement (expected a string on the form a=b or a= or a)`
|
|
@@ -4057,6 +4058,7 @@ class CatalogBuilder {
|
|
|
4057
4058
|
maxSeconds: 150
|
|
4058
4059
|
});
|
|
4059
4060
|
this.locationAnalyzer = void 0;
|
|
4061
|
+
this.legacySingleProcessorValidation = false;
|
|
4060
4062
|
this.env = env;
|
|
4061
4063
|
this.entityPolicies = [];
|
|
4062
4064
|
this.entityPoliciesReplace = false;
|
|
@@ -4138,11 +4140,16 @@ class CatalogBuilder {
|
|
|
4138
4140
|
}
|
|
4139
4141
|
addPermissionRules(...permissionRules) {
|
|
4140
4142
|
this.permissionRules.push(...permissionRules.flat());
|
|
4143
|
+
return this;
|
|
4141
4144
|
}
|
|
4142
4145
|
setAllowedLocationTypes(allowedLocationTypes) {
|
|
4143
4146
|
this.allowedLocationType = allowedLocationTypes;
|
|
4144
4147
|
return this;
|
|
4145
4148
|
}
|
|
4149
|
+
useLegacySingleProcessorValidation() {
|
|
4150
|
+
this.legacySingleProcessorValidation = true;
|
|
4151
|
+
return this;
|
|
4152
|
+
}
|
|
4146
4153
|
async build() {
|
|
4147
4154
|
var _a, _b;
|
|
4148
4155
|
const { config, database, logger, permissions } = this.env;
|
|
@@ -4167,7 +4174,8 @@ class CatalogBuilder {
|
|
|
4167
4174
|
rulesEnforcer,
|
|
4168
4175
|
logger,
|
|
4169
4176
|
parser,
|
|
4170
|
-
policy
|
|
4177
|
+
policy,
|
|
4178
|
+
legacySingleProcessorValidation: this.legacySingleProcessorValidation
|
|
4171
4179
|
});
|
|
4172
4180
|
const stitcher = new Stitcher(dbClient, logger);
|
|
4173
4181
|
const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog(
|