@backstage/plugin-catalog-backend 1.4.0-next.3 → 1.4.1-next.0

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 CHANGED
@@ -1,5 +1,63 @@
1
1
  # @backstage/plugin-catalog-backend
2
2
 
3
+ ## 1.4.1-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 8cb6e10105: Fixed a bug where entities provided without a location key would always replace existing entities, rather than updating them.
8
+ - 63296ebcd4: Allow Placeholder value to be any value, not only string.
9
+ - 74022e0163: Make sure to stitch entities correctly after deletion, to ensure that their relations are updated.
10
+ - Updated dependencies
11
+ - @backstage/catalog-model@1.1.2-next.0
12
+ - @backstage/backend-plugin-api@0.1.3-next.0
13
+ - @backstage/catalog-client@1.1.1-next.0
14
+ - @backstage/plugin-catalog-node@1.1.1-next.0
15
+ - @backstage/plugin-scaffolder-common@1.2.1-next.0
16
+ - @backstage/backend-common@0.15.2-next.0
17
+ - @backstage/plugin-permission-node@0.6.6-next.0
18
+ - @backstage/config@1.0.3-next.0
19
+ - @backstage/errors@1.1.2-next.0
20
+ - @backstage/integration@1.3.2-next.0
21
+ - @backstage/types@1.0.0
22
+ - @backstage/plugin-catalog-common@1.0.7-next.0
23
+ - @backstage/plugin-permission-common@0.6.5-next.0
24
+ - @backstage/plugin-search-common@1.0.2-next.0
25
+
26
+ ## 1.4.0
27
+
28
+ ### Minor Changes
29
+
30
+ - dd395335bc: Allow unknown typed location from being registered via the location service by configuration settings
31
+ - 651c9d6800: The search index now does retain fields that have a very long value, but in the form of just a null. This makes it possible to at least filter for their existence.
32
+ - 6e63bc43f2: Added the `refresh` function to the Connection of the entity providers.
33
+
34
+ ### Patch Changes
35
+
36
+ - eadf56bbbf: Bump `git-url-parse` version to `^13.0.0`
37
+ - 07dda0b746: Add optional value to `hasAnnotation` permission rule
38
+ - 243533ecdc: Added support to mysql on some raw queries
39
+ - ce77e78c93: Fixes a bug to be able to utilize refresh keys after the entity is loaded from cache
40
+ - 667d917488: Updated dependency `msw` to `^0.47.0`.
41
+ - 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`.
42
+ - bf5e9030eb: Updated dependency `msw` to `^0.45.0`.
43
+ - 679f7c5e95: Include entity ref into error message when catalog policies fail
44
+ - 06e2b077a1: Limit the length of error messages that get written to the database and logs - to prevent performance issues
45
+ - 62788b2ee8: The experimental `CatalogProcessingExtensionPoint` now accepts multiple providers and processors at once.
46
+ - Updated dependencies
47
+ - @backstage/backend-plugin-api@0.1.2
48
+ - @backstage/backend-common@0.15.1
49
+ - @backstage/plugin-permission-node@0.6.5
50
+ - @backstage/plugin-catalog-node@1.1.0
51
+ - @backstage/integration@1.3.1
52
+ - @backstage/catalog-client@1.1.0
53
+ - @backstage/catalog-model@1.1.1
54
+ - @backstage/config@1.0.2
55
+ - @backstage/errors@1.1.1
56
+ - @backstage/plugin-permission-common@0.6.4
57
+ - @backstage/plugin-scaffolder-common@1.2.0
58
+ - @backstage/plugin-catalog-common@1.0.6
59
+ - @backstage/plugin-search-common@1.0.1
60
+
3
61
  ## 1.4.0-next.3
4
62
 
5
63
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend",
3
- "version": "1.4.0-next.3",
3
+ "version": "1.4.1-next.0",
4
4
  "main": "../dist/index.cjs.js",
5
5
  "types": "../dist/index.alpha.d.ts"
6
6
  }
@@ -326,7 +326,7 @@ export declare class CatalogBuilder {
326
326
  * @alpha
327
327
  */
328
328
  export declare const catalogConditions: Conditions< {
329
- hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [annotation: string]>;
329
+ hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [annotation: string, value?: string | undefined]>;
330
330
  hasLabel: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [label: string]>;
331
331
  hasMetadata: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
332
332
  hasSpec: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
@@ -603,7 +603,7 @@ export declare function parseEntityYaml(data: Buffer, location: LocationSpec): I
603
603
  * @alpha
604
604
  */
605
605
  export declare const permissionRules: {
606
- hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [annotation: string]>;
606
+ hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [annotation: string, value?: string | undefined]>;
607
607
  hasLabel: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [label: string]>;
608
608
  hasMetadata: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
609
609
  hasSpec: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
package/dist/index.cjs.js CHANGED
@@ -608,7 +608,7 @@ class PlaceholderProcessor {
608
608
  const resolverKey = keys[0].substr(1);
609
609
  const resolverValue = data[keys[0]];
610
610
  const resolver = this.options.resolvers[resolverKey];
611
- if (!resolver || typeof resolverValue !== "string") {
611
+ if (!resolver) {
612
612
  return [data, false];
613
613
  }
614
614
  const read = async (url) => {
@@ -830,13 +830,16 @@ const hasAnnotation = createCatalogPermissionRule({
830
830
  name: "HAS_ANNOTATION",
831
831
  description: "Allow entities which are annotated with the specified annotation",
832
832
  resourceType: pluginCatalogCommon.RESOURCE_TYPE_CATALOG_ENTITY,
833
- apply: (resource, annotation) => {
834
- var _a;
835
- return !!((_a = resource.metadata.annotations) == null ? void 0 : _a.hasOwnProperty(annotation));
833
+ apply: (resource, annotation, value) => {
834
+ var _a, _b;
835
+ return !!((_a = resource.metadata.annotations) == null ? void 0 : _a.hasOwnProperty(annotation)) && (value === void 0 ? true : ((_b = resource.metadata.annotations) == null ? void 0 : _b[annotation]) === value);
836
836
  },
837
- toQuery: (annotation) => ({
837
+ toQuery: (annotation, value) => value === void 0 ? {
838
838
  key: `metadata.annotations.${annotation}`
839
- })
839
+ } : {
840
+ key: `metadata.annotations.${annotation}`,
841
+ values: [value]
842
+ }
840
843
  });
841
844
 
842
845
  const isEntityKind = createCatalogPermissionRule({
@@ -1869,6 +1872,7 @@ class DefaultProcessingDatabase {
1869
1872
  );
1870
1873
  }
1871
1874
  async createDelta(tx, options) {
1875
+ var _a, _b;
1872
1876
  if (options.type === "delta") {
1873
1877
  return {
1874
1878
  toAdd: [],
@@ -1911,7 +1915,7 @@ class DefaultProcessingDatabase {
1911
1915
  const upsertItem = { deferred: item.deferred, hash: item.hash };
1912
1916
  if (!oldRef) {
1913
1917
  toAdd.push(upsertItem);
1914
- } else if (oldRef.locationKey !== item.deferred.locationKey) {
1918
+ } else if (((_a = oldRef == null ? void 0 : oldRef.locationKey) != null ? _a : void 0) !== ((_b = item.deferred.locationKey) != null ? _b : void 0)) {
1915
1919
  toRemove.push(item.ref);
1916
1920
  toAdd.push(upsertItem);
1917
1921
  } else if (oldRef.oldEntityHash !== item.hash) {
@@ -2029,7 +2033,7 @@ function startTaskPipeline(options) {
2029
2033
 
2030
2034
  const CACHE_TTL = 5;
2031
2035
  class DefaultCatalogProcessingEngine {
2032
- constructor(logger, processingDatabase, orchestrator, stitcher, createHash, pollingIntervalMs = 1e3, onProcessingError) {
2036
+ constructor(logger, processingDatabase, orchestrator, stitcher, createHash, pollingIntervalMs = 1e3, onProcessingError, tracker = progressTracker()) {
2033
2037
  this.logger = logger;
2034
2038
  this.processingDatabase = processingDatabase;
2035
2039
  this.orchestrator = orchestrator;
@@ -2037,7 +2041,7 @@ class DefaultCatalogProcessingEngine {
2037
2041
  this.createHash = createHash;
2038
2042
  this.pollingIntervalMs = pollingIntervalMs;
2039
2043
  this.onProcessingError = onProcessingError;
2040
- this.tracker = progressTracker();
2044
+ this.tracker = tracker;
2041
2045
  }
2042
2046
  async start() {
2043
2047
  if (this.stopFunc) {
@@ -2440,8 +2444,9 @@ function parseFilter(filter, query, db, negate = false) {
2440
2444
  });
2441
2445
  }
2442
2446
  class DefaultEntitiesCatalog {
2443
- constructor(database) {
2447
+ constructor(database, stitcher) {
2444
2448
  this.database = database;
2449
+ this.stitcher = stitcher;
2445
2450
  }
2446
2451
  async entities(request) {
2447
2452
  const db = this.database;
@@ -2493,13 +2498,22 @@ class DefaultEntitiesCatalog {
2493
2498
  }
2494
2499
  async removeEntityByUid(uid) {
2495
2500
  await this.database("refresh_state").update({
2496
- result_hash: "child-was-deleted"
2501
+ result_hash: "child-was-deleted",
2502
+ next_update_at: this.database.fn.now()
2497
2503
  }).whereIn("entity_ref", function parents(builder) {
2498
2504
  return builder.from("refresh_state").innerJoin("refresh_state_references", {
2499
2505
  "refresh_state_references.target_entity_ref": "refresh_state.entity_ref"
2500
2506
  }).where("refresh_state.entity_id", "=", uid).select("refresh_state_references.source_entity_ref");
2501
2507
  });
2508
+ const relationPeers = await this.database.from("relations").innerJoin("refresh_state", {
2509
+ "refresh_state.entity_ref": "relations.target_entity_ref"
2510
+ }).where("relations.originating_entity_id", "=", uid).andWhere("refresh_state.entity_id", "!=", uid).select({ ref: "relations.target_entity_ref" }).union(
2511
+ (other) => other.from("relations").innerJoin("refresh_state", {
2512
+ "refresh_state.entity_ref": "relations.source_entity_ref"
2513
+ }).where("relations.originating_entity_id", "=", uid).andWhere("refresh_state.entity_id", "!=", uid).select({ ref: "relations.source_entity_ref" })
2514
+ );
2502
2515
  await this.database("refresh_state").where("entity_id", uid).delete();
2516
+ await this.stitcher.stitch(new Set(relationPeers.map((p) => p.ref)));
2503
2517
  }
2504
2518
  async entityAncestry(rootRef) {
2505
2519
  const [rootRow] = await this.database("refresh_state").leftJoin("final_entities", {
@@ -4047,7 +4061,11 @@ class CatalogBuilder {
4047
4061
  parser,
4048
4062
  policy
4049
4063
  });
4050
- const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog(dbClient);
4064
+ const stitcher = new Stitcher(dbClient, logger);
4065
+ const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog(
4066
+ dbClient,
4067
+ stitcher
4068
+ );
4051
4069
  let permissionEvaluator;
4052
4070
  if ("authorizeConditional" in permissions) {
4053
4071
  permissionEvaluator = permissions;
@@ -4085,7 +4103,6 @@ class CatalogBuilder {
4085
4103
  permissions: pluginCatalogCommon.catalogPermissions,
4086
4104
  rules: this.permissionRules
4087
4105
  });
4088
- const stitcher = new Stitcher(dbClient, logger);
4089
4106
  const locationStore = new DefaultLocationStore(dbClient);
4090
4107
  const configLocationProvider = new ConfigLocationEntityProvider(config);
4091
4108
  const entityProviders = lodash__default["default"].uniqBy(