@backstage/plugin-catalog-backend 1.17.0-next.0 → 1.17.0-next.2

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,59 @@
1
1
  # @backstage/plugin-catalog-backend
2
2
 
3
+ ## 1.17.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 9aac2b0: Use `--cwd` as the first `yarn` argument
8
+ - Updated dependencies
9
+ - @backstage/repo-tools@0.6.0-next.2
10
+ - @backstage/backend-common@0.21.0-next.2
11
+ - @backstage/plugin-search-backend-module-catalog@0.1.14-next.2
12
+ - @backstage/backend-plugin-api@0.6.10-next.2
13
+ - @backstage/backend-tasks@0.5.15-next.2
14
+ - @backstage/plugin-auth-node@0.4.4-next.2
15
+ - @backstage/plugin-permission-node@0.7.21-next.2
16
+ - @backstage/backend-openapi-utils@0.1.3-next.2
17
+ - @backstage/plugin-catalog-node@1.6.2-next.2
18
+ - @backstage/plugin-events-node@0.2.19-next.2
19
+ - @backstage/config@1.1.1
20
+ - @backstage/catalog-client@1.6.0-next.1
21
+ - @backstage/catalog-model@1.4.4-next.0
22
+ - @backstage/errors@1.2.3
23
+ - @backstage/integration@1.9.0-next.0
24
+ - @backstage/types@1.1.1
25
+ - @backstage/plugin-catalog-common@1.0.21-next.0
26
+ - @backstage/plugin-permission-common@0.7.12
27
+
28
+ ## 1.17.0-next.1
29
+
30
+ ### Minor Changes
31
+
32
+ - 43dad25: Add API to get location by entity
33
+
34
+ ### Patch Changes
35
+
36
+ - 89b674c: Minor performance improvement for `queryEntities` when the limit is 0.
37
+ - efa8160: Rollback the change for wildcard discovery, this fixes a bug with the `AzureUrlReader` not working with wildcard paths
38
+ - Updated dependencies
39
+ - @backstage/catalog-model@1.4.4-next.0
40
+ - @backstage/catalog-client@1.6.0-next.1
41
+ - @backstage/backend-plugin-api@0.6.10-next.1
42
+ - @backstage/backend-common@0.21.0-next.1
43
+ - @backstage/integration@1.9.0-next.0
44
+ - @backstage/backend-openapi-utils@0.1.3-next.1
45
+ - @backstage/backend-tasks@0.5.15-next.1
46
+ - @backstage/config@1.1.1
47
+ - @backstage/errors@1.2.3
48
+ - @backstage/types@1.1.1
49
+ - @backstage/plugin-auth-node@0.4.4-next.1
50
+ - @backstage/plugin-catalog-common@1.0.21-next.0
51
+ - @backstage/plugin-catalog-node@1.6.2-next.1
52
+ - @backstage/plugin-events-node@0.2.19-next.1
53
+ - @backstage/plugin-permission-common@0.7.12
54
+ - @backstage/plugin-permission-node@0.7.21-next.1
55
+ - @backstage/plugin-search-backend-module-catalog@0.1.14-next.1
56
+
3
57
  ## 1.17.0-next.0
4
58
 
5
59
  ### Minor Changes
package/README.md CHANGED
@@ -27,7 +27,7 @@ restoring the plugin, if you previously removed it.
27
27
 
28
28
  ```bash
29
29
  # From your Backstage root directory
30
- yarn add --cwd packages/backend @backstage/plugin-catalog-backend
30
+ yarn --cwd packages/backend add @backstage/plugin-catalog-backend
31
31
  ```
32
32
 
33
33
  ### Adding the plugin to your `packages/backend`
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend",
3
- "version": "1.17.0-next.0",
3
+ "version": "1.17.0-next.2",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/dist/alpha.cjs.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var alpha = require('@backstage/plugin-catalog-common/alpha');
6
6
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
7
- var CatalogBuilder = require('./cjs/CatalogBuilder-5a2a16bf.cjs.js');
7
+ var CatalogBuilder = require('./cjs/CatalogBuilder-2dd9e66c.cjs.js');
8
8
  var backendPluginApi = require('@backstage/backend-plugin-api');
9
9
  var alpha$1 = require('@backstage/plugin-catalog-node/alpha');
10
10
  var backendCommon = require('@backstage/backend-common');
@@ -668,7 +668,7 @@ class UrlReaderProcessor {
668
668
  return true;
669
669
  }
670
670
  async doRead(location, etag) {
671
- const { pathname: filepath } = new URL(location);
671
+ const { filepath } = parseGitUrl__default["default"](location);
672
672
  if (filepath == null ? void 0 : filepath.match(/[*?]/)) {
673
673
  const limiter = limiterFactory__default["default"](5);
674
674
  const response = await this.options.reader.search(location, { etag });
@@ -947,6 +947,30 @@ class DefaultLocationStore {
947
947
  removed: [{ entity, locationKey: getEntityLocationRef(entity) }]
948
948
  });
949
949
  }
950
+ async getLocationByEntity(entityRef) {
951
+ const entityRefString = catalogModel.stringifyEntityRef(entityRef);
952
+ const [entity] = await this.db("refresh_state").where({ entity_ref: entityRefString }).select("entity_id").limit(1);
953
+ if (!entity) {
954
+ throw new errors.NotFoundError(`found no entity for ref ${entityRefString}`);
955
+ }
956
+ const [locationKeyValue] = await this.db("search").where({
957
+ entity_id: entity.entity_id,
958
+ key: `metadata.annotations.${catalogModel.ANNOTATION_ORIGIN_LOCATION}`
959
+ }).select("value").limit(1);
960
+ if (!locationKeyValue) {
961
+ throw new errors.NotFoundError(
962
+ `found no origin annotation for ref ${entityRefString}`
963
+ );
964
+ }
965
+ const { type, target } = catalogModel.parseLocationRef(entityRefString);
966
+ const [location] = await this.db("locations").where({ type, target }).select().limit(1);
967
+ if (!location) {
968
+ throw new errors.NotFoundError(
969
+ `Found no location with type ${type} and target ${target}`
970
+ );
971
+ }
972
+ return location;
973
+ }
950
974
  get connection() {
951
975
  if (!this._connection) {
952
976
  throw new Error("location store is not initialized");
@@ -2133,6 +2157,9 @@ class DefaultLocationService {
2133
2157
  deleteLocation(id) {
2134
2158
  return this.store.deleteLocation(id);
2135
2159
  }
2160
+ getLocationByEntity(entityRef) {
2161
+ return this.store.getLocationByEntity(catalogModel.parseEntityRef(entityRef));
2162
+ }
2136
2163
  async processEntities(unprocessedEntities) {
2137
2164
  const entities = [];
2138
2165
  while (unprocessedEntities.length) {
@@ -2559,7 +2586,7 @@ class DefaultEntitiesCatalog {
2559
2586
  ]).limit(isFetchingBackwards ? limit : limit + 1);
2560
2587
  countQuery.count("search.entity_id", { as: "count" });
2561
2588
  const [rows, [{ count }]] = await Promise.all([
2562
- dbQuery,
2589
+ limit > 0 ? dbQuery : [],
2563
2590
  // for performance reasons we invoke the countQuery
2564
2591
  // only on the first request.
2565
2592
  // The result is then embedded into the cursor
@@ -5271,6 +5298,62 @@ const spec = {
5271
5298
  ]
5272
5299
  }
5273
5300
  },
5301
+ "/locations/by-entity/{kind}/{namespace}/{name}": {
5302
+ get: {
5303
+ operationId: "getLocationByEntity",
5304
+ description: "Get a location for entity.",
5305
+ responses: {
5306
+ "200": {
5307
+ description: "Ok",
5308
+ content: {
5309
+ "application/json": {
5310
+ schema: {
5311
+ $ref: "#/components/schemas/Location"
5312
+ }
5313
+ }
5314
+ }
5315
+ },
5316
+ default: {
5317
+ $ref: "#/components/responses/ErrorResponse"
5318
+ }
5319
+ },
5320
+ security: [
5321
+ {},
5322
+ {
5323
+ JWT: []
5324
+ }
5325
+ ],
5326
+ parameters: [
5327
+ {
5328
+ in: "path",
5329
+ name: "kind",
5330
+ required: true,
5331
+ allowReserved: true,
5332
+ schema: {
5333
+ type: "string"
5334
+ }
5335
+ },
5336
+ {
5337
+ in: "path",
5338
+ name: "namespace",
5339
+ required: true,
5340
+ allowReserved: true,
5341
+ schema: {
5342
+ type: "string"
5343
+ }
5344
+ },
5345
+ {
5346
+ in: "path",
5347
+ name: "name",
5348
+ required: true,
5349
+ allowReserved: true,
5350
+ schema: {
5351
+ type: "string"
5352
+ }
5353
+ }
5354
+ ]
5355
+ }
5356
+ },
5274
5357
  "/analyze-location": {
5275
5358
  post: {
5276
5359
  operationId: "AnalyzeLocation",
@@ -5598,6 +5681,17 @@ async function createRouter(options) {
5598
5681
  )
5599
5682
  });
5600
5683
  res.status(204).end();
5684
+ }).get("/locations/by-entity/:kind/:namespace/:name", async (req, res) => {
5685
+ const { kind, namespace, name } = req.params;
5686
+ const output = await locationService.getLocationByEntity(
5687
+ { kind, namespace, name },
5688
+ {
5689
+ authorizationToken: pluginAuthNode.getBearerTokenFromAuthorizationHeader(
5690
+ req.header("authorization")
5691
+ )
5692
+ }
5693
+ );
5694
+ res.status(200).json(output);
5601
5695
  });
5602
5696
  }
5603
5697
  if (locationAnalyzer) {
@@ -6319,6 +6413,16 @@ class AuthorizedLocationService {
6319
6413
  }
6320
6414
  return this.locationService.deleteLocation(id);
6321
6415
  }
6416
+ async getLocationByEntity(entityRef, options) {
6417
+ const authorizationResponse = (await this.permissionApi.authorize(
6418
+ [{ permission: alpha.catalogLocationReadPermission }],
6419
+ { token: options == null ? void 0 : options.authorizationToken }
6420
+ ))[0];
6421
+ if (authorizationResponse.result === pluginPermissionCommon.AuthorizeResult.DENY) {
6422
+ throw new errors.NotFoundError();
6423
+ }
6424
+ return this.locationService.getLocationByEntity(entityRef);
6425
+ }
6322
6426
  }
6323
6427
 
6324
6428
  async function deleteWithEagerPruningOfChildren(options) {
@@ -7253,4 +7357,4 @@ exports.createCatalogPermissionRule = createCatalogPermissionRule;
7253
7357
  exports.createRandomProcessingInterval = createRandomProcessingInterval;
7254
7358
  exports.parseEntityYaml = parseEntityYaml;
7255
7359
  exports.permissionRules = permissionRules;
7256
- //# sourceMappingURL=CatalogBuilder-5a2a16bf.cjs.js.map
7360
+ //# sourceMappingURL=CatalogBuilder-2dd9e66c.cjs.js.map