@backstage/plugin-catalog-backend 3.8.0-next.1 → 3.8.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,39 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-backend
|
|
2
2
|
|
|
3
|
+
## 3.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8f20cc2: `/entities/by-query` now accepts a `totalItems` parameter (`'include'` or `'exclude'`, default `'include'`) that controls whether the response's `totalItems` count is computed. Pass `'exclude'` to skip the count entirely when the caller doesn't need it — useful for cursor-paginated user interfaces that only display the count cosmetically. The accepted values list is forward-compatible: future modes (e.g. approximate counts) can be added without breaking existing callers.
|
|
8
|
+
|
|
9
|
+
The internal `QueryEntitiesInitialRequest.skipTotalItems` option has been replaced by `totalItems: 'include' | 'exclude'`. Note that `skipTotalItems` was never exposed as a REST API parameter, so this is only a TypeScript-level change affecting direct callers of `EntitiesCatalog.queryEntities`.
|
|
10
|
+
|
|
11
|
+
Sort field keys are now lowercased before comparing against `search.key`, fixing silent mismatches for camelCase field names. The `NULLS LAST` ordering clause has been removed since NULL sort values are already excluded by the `WHERE` clause.
|
|
12
|
+
|
|
13
|
+
- dc7678c: Removed the immediate mode stitching strategy. All stitching now uses the deferred mode, which processes entities asynchronously via a worker queue. If your configuration includes `catalog.stitchingStrategy.mode: 'immediate'`, it will be ignored with a deprecation warning. The `pollingInterval` and `stitchTimeout` settings continue to work as before.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 9698738: Dropped the legacy `search_entity_id_idx` index which is now redundant with the covering unique index on `(entity_id, key, value)`. The old index caused the query planner to choose an inefficient scan pattern for catalog list queries with multiple sort fields, leading to severely degraded performance on large catalogs.
|
|
18
|
+
- ccfa4f1: Optimized `entitiesBatch` on PostgreSQL to use `= ANY(array)` instead of `WHERE IN ($1, $2, ...)`. This produces a single stable query plan regardless of batch size, instead of up to 200 different plans that pollute the query plan cache. On PostgreSQL, batching is no longer needed so all entity refs are fetched in a single query.
|
|
19
|
+
- 750b310: `HAS_LABEL` and `HAS_ANNOTATION` permission rules are now case insensitive.
|
|
20
|
+
- 24775dc: Added a migration that tunes PostgreSQL automatic vacuum thresholds on the `search`, `final_entities`, `relations`, and `refresh_state_references` tables, and fixes column statistics for `entity_id` in the `search` table. This prevents the query planner from falling back to sequential scans when table maintenance falls behind, keeping catalog queries fast on large installations.
|
|
21
|
+
- 39c5fbb: Added extended multi-column statistics on `(key, value)` in the `search` table (PostgreSQL only). This tells the query planner about the correlation between the `key` and `value` columns, fixing severe row count estimation errors on compound filter queries. Without this, the planner could choose to materialize and sort thousands of rows instead of using the LIMIT short-circuit index scan — causing 10-40x slower catalog list views when multiple filters are active.
|
|
22
|
+
- 4829e89: Split the `queryEntities` list and count into separate queries instead of a multi-reference CTE. When the `filtered` CTE was referenced twice (once for the count, once for the data), PostgreSQL refused to inline it, forcing full materialization of the filtered set before applying `LIMIT`. By running the count as a standalone query, the list CTE is only referenced once, allowing the planner to short-circuit on `LIMIT` and return the first page in milliseconds instead of waiting for the full filtered set to materialize.
|
|
23
|
+
|
|
24
|
+
The standalone count query also fixes a pre-existing bug where `totalItems` was inflated for entities with multi-valued sort fields (e.g. tags). The old CTE-based count counted search rows, so an entity with 3 tags would be counted 3 times. The new count uses `EXISTS` to count distinct entities, aligning `totalItems` with the number of entities actually reachable through cursor pagination.
|
|
25
|
+
|
|
26
|
+
- 774d698: Fixed a race condition in the stitch queue and entity processing claim logic where `SELECT FOR UPDATE SKIP LOCKED` row locks were released before the subsequent timestamp bump, allowing multiple workers to claim the same rows. Both the select and update now run inside a single transaction for MySQL and PostgreSQL.
|
|
27
|
+
- 0b8b677: Improved stitch queue semantics to prevent overlapping stitches for the same entity. New stitch requests that arrive while a stitch is in progress now only update the ticket (not the timestamp), so the in-progress worker is not interrupted. When the worker completes and detects a pending re-stitch, the queue entry becomes immediately eligible for pickup instead of waiting for the timeout period.
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/catalog-client@1.16.0
|
|
30
|
+
- @backstage/integration@2.0.3
|
|
31
|
+
- @backstage/backend-plugin-api@1.9.2
|
|
32
|
+
- @backstage/backend-openapi-utils@0.6.10
|
|
33
|
+
- @backstage/plugin-catalog-node@2.2.2
|
|
34
|
+
- @backstage/plugin-events-node@0.4.23
|
|
35
|
+
- @backstage/plugin-permission-node@0.11.1
|
|
36
|
+
|
|
3
37
|
## 3.8.0-next.1
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
|
@@ -12,7 +12,21 @@ const hasAnnotation = pluginPermissionNode.createPermissionRule({
|
|
|
12
12
|
annotation: v3.z.string().describe("Name of the annotation to match on"),
|
|
13
13
|
value: v3.z.string().optional().describe("Value of the annotation to match on")
|
|
14
14
|
}),
|
|
15
|
-
apply: (resource, { annotation, value }) =>
|
|
15
|
+
apply: (resource, { annotation, value }) => {
|
|
16
|
+
if (!resource.metadata.annotations) return false;
|
|
17
|
+
const isExactKeyMatch = !!resource.metadata.annotations?.hasOwnProperty(annotation) && (value === void 0 ? true : resource.metadata.annotations?.[annotation] === value);
|
|
18
|
+
if (isExactKeyMatch) return true;
|
|
19
|
+
const normalizedAnnotation = annotation.toLocaleLowerCase("en-US");
|
|
20
|
+
const normalizedValue = value?.toLocaleLowerCase("en-US");
|
|
21
|
+
for (const [key, val] of Object.entries(resource.metadata.annotations)) {
|
|
22
|
+
if (key.toLocaleLowerCase("en-US") === normalizedAnnotation) {
|
|
23
|
+
if (normalizedValue === void 0 || val.toLocaleLowerCase("en-US") === normalizedValue) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
},
|
|
16
30
|
toQuery: ({ annotation, value }) => value === void 0 ? {
|
|
17
31
|
key: `metadata.annotations.${annotation}`
|
|
18
32
|
} : {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hasAnnotation.cjs.js","sources":["../../../src/permissions/rules/hasAnnotation.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { catalogEntityPermissionResourceRef } from '@backstage/plugin-catalog-node/alpha';\nimport { createPermissionRule } from '@backstage/plugin-permission-node';\nimport { z } from 'zod/v3';\n\n/**\n * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which\n * filters for the presence of an annotation on a given entity.\n *\n * If a value is given, it filters for the annotation value, too.\n *\n * @alpha\n */\nexport const hasAnnotation = createPermissionRule({\n name: 'HAS_ANNOTATION',\n description: 'Allow entities with the specified annotation',\n resourceRef: catalogEntityPermissionResourceRef,\n paramsSchema: z.object({\n annotation: z.string().describe('Name of the annotation to match on'),\n value: z\n .string()\n .optional()\n .describe('Value of the annotation to match on'),\n }),\n apply: (resource, { annotation, value })
|
|
1
|
+
{"version":3,"file":"hasAnnotation.cjs.js","sources":["../../../src/permissions/rules/hasAnnotation.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { catalogEntityPermissionResourceRef } from '@backstage/plugin-catalog-node/alpha';\nimport { createPermissionRule } from '@backstage/plugin-permission-node';\nimport { z } from 'zod/v3';\n\n/**\n * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which\n * filters for the presence of an annotation on a given entity.\n *\n * If a value is given, it filters for the annotation value, too.\n *\n * @alpha\n */\nexport const hasAnnotation = createPermissionRule({\n name: 'HAS_ANNOTATION',\n description: 'Allow entities with the specified annotation',\n resourceRef: catalogEntityPermissionResourceRef,\n paramsSchema: z.object({\n annotation: z.string().describe('Name of the annotation to match on'),\n value: z\n .string()\n .optional()\n .describe('Value of the annotation to match on'),\n }),\n apply: (resource, { annotation, value }) => {\n if (!resource.metadata.annotations) return false;\n\n // exact key match\n const isExactKeyMatch =\n !!resource.metadata.annotations?.hasOwnProperty(annotation) &&\n (value === undefined\n ? true\n : resource.metadata.annotations?.[annotation] === value);\n\n if (isExactKeyMatch) return true;\n\n // case-insensitive matching if exact match is not found\n const normalizedAnnotation = annotation.toLocaleLowerCase('en-US');\n const normalizedValue = value?.toLocaleLowerCase('en-US');\n\n for (const [key, val] of Object.entries(resource.metadata.annotations)) {\n if (key.toLocaleLowerCase('en-US') === normalizedAnnotation) {\n if (\n normalizedValue === undefined ||\n val.toLocaleLowerCase('en-US') === normalizedValue\n ) {\n return true;\n }\n }\n }\n return false;\n },\n toQuery: ({ annotation, value }) =>\n value === undefined\n ? {\n key: `metadata.annotations.${annotation}`,\n }\n : {\n key: `metadata.annotations.${annotation}`,\n values: [value],\n },\n});\n"],"names":["createPermissionRule","catalogEntityPermissionResourceRef","z"],"mappings":";;;;;;AA4BO,MAAM,gBAAgBA,yCAAA,CAAqB;AAAA,EAChD,IAAA,EAAM,gBAAA;AAAA,EACN,WAAA,EAAa,8CAAA;AAAA,EACb,WAAA,EAAaC,wCAAA;AAAA,EACb,YAAA,EAAcC,KAAE,MAAA,CAAO;AAAA,IACrB,UAAA,EAAYA,IAAA,CAAE,MAAA,EAAO,CAAE,SAAS,oCAAoC,CAAA;AAAA,IACpE,OAAOA,IAAA,CACJ,MAAA,GACA,QAAA,EAAS,CACT,SAAS,qCAAqC;AAAA,GAClD,CAAA;AAAA,EACD,OAAO,CAAC,QAAA,EAAU,EAAE,UAAA,EAAY,OAAM,KAAM;AAC1C,IAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,WAAA,EAAa,OAAO,KAAA;AAG3C,IAAA,MAAM,kBACJ,CAAC,CAAC,QAAA,CAAS,QAAA,CAAS,aAAa,cAAA,CAAe,UAAU,CAAA,KACzD,KAAA,KAAU,SACP,IAAA,GACA,QAAA,CAAS,QAAA,CAAS,WAAA,GAAc,UAAU,CAAA,KAAM,KAAA,CAAA;AAEtD,IAAA,IAAI,iBAAiB,OAAO,IAAA;AAG5B,IAAA,MAAM,oBAAA,GAAuB,UAAA,CAAW,iBAAA,CAAkB,OAAO,CAAA;AACjE,IAAA,MAAM,eAAA,GAAkB,KAAA,EAAO,iBAAA,CAAkB,OAAO,CAAA;AAExD,IAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,WAAW,CAAA,EAAG;AACtE,MAAA,IAAI,GAAA,CAAI,iBAAA,CAAkB,OAAO,CAAA,KAAM,oBAAA,EAAsB;AAC3D,QAAA,IACE,oBAAoB,MAAA,IACpB,GAAA,CAAI,iBAAA,CAAkB,OAAO,MAAM,eAAA,EACnC;AACA,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAAA,EACA,SAAS,CAAC,EAAE,YAAY,KAAA,EAAM,KAC5B,UAAU,MAAA,GACN;AAAA,IACE,GAAA,EAAK,wBAAwB,UAAU,CAAA;AAAA,GACzC,GACA;AAAA,IACE,GAAA,EAAK,wBAAwB,UAAU,CAAA,CAAA;AAAA,IACvC,MAAA,EAAQ,CAAC,KAAK;AAAA;AAExB,CAAC;;;;"}
|
|
@@ -12,7 +12,21 @@ const hasLabel = pluginPermissionNode.createPermissionRule({
|
|
|
12
12
|
label: v3.z.string().describe("Name of the label to match on"),
|
|
13
13
|
value: v3.z.string().optional().describe("Value of the label to match on")
|
|
14
14
|
}),
|
|
15
|
-
apply: (resource, { label, value }) =>
|
|
15
|
+
apply: (resource, { label, value }) => {
|
|
16
|
+
if (!resource.metadata.labels) return false;
|
|
17
|
+
const isExactKeyMatch = !!resource.metadata.labels?.hasOwnProperty(label) && (value === void 0 ? true : resource.metadata.labels?.[label] === value);
|
|
18
|
+
if (isExactKeyMatch) return true;
|
|
19
|
+
const normalizedLabel = label.toLocaleLowerCase("en-US");
|
|
20
|
+
const normalizedValue = value?.toLocaleLowerCase("en-US");
|
|
21
|
+
for (const [key, val] of Object.entries(resource.metadata.labels)) {
|
|
22
|
+
if (key.toLocaleLowerCase("en-US") === normalizedLabel) {
|
|
23
|
+
if (normalizedValue === void 0 || val.toLocaleLowerCase("en-US") === normalizedValue) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
},
|
|
16
30
|
toQuery: ({ label, value }) => value === void 0 ? {
|
|
17
31
|
key: `metadata.labels.${label}`
|
|
18
32
|
} : {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hasLabel.cjs.js","sources":["../../../src/permissions/rules/hasLabel.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { catalogEntityPermissionResourceRef } from '@backstage/plugin-catalog-node/alpha';\nimport { createPermissionRule } from '@backstage/plugin-permission-node';\nimport { z } from 'zod/v3';\n\n/**\n * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which\n * filters for entities with a specified label in its metadata.\n * @alpha\n */\nexport const hasLabel = createPermissionRule({\n name: 'HAS_LABEL',\n description: 'Allow entities with the specified label',\n resourceRef: catalogEntityPermissionResourceRef,\n paramsSchema: z.object({\n label: z.string().describe('Name of the label to match on'),\n value: z.string().optional().describe('Value of the label to match on'),\n }),\n apply: (resource, { label, value })
|
|
1
|
+
{"version":3,"file":"hasLabel.cjs.js","sources":["../../../src/permissions/rules/hasLabel.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { catalogEntityPermissionResourceRef } from '@backstage/plugin-catalog-node/alpha';\nimport { createPermissionRule } from '@backstage/plugin-permission-node';\nimport { z } from 'zod/v3';\n\n/**\n * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which\n * filters for entities with a specified label in its metadata.\n * @alpha\n */\nexport const hasLabel = createPermissionRule({\n name: 'HAS_LABEL',\n description: 'Allow entities with the specified label',\n resourceRef: catalogEntityPermissionResourceRef,\n paramsSchema: z.object({\n label: z.string().describe('Name of the label to match on'),\n value: z.string().optional().describe('Value of the label to match on'),\n }),\n apply: (resource, { label, value }) => {\n if (!resource.metadata.labels) return false;\n\n // exact key match\n const isExactKeyMatch =\n !!resource.metadata.labels?.hasOwnProperty(label) &&\n (value === undefined\n ? true\n : resource.metadata.labels?.[label] === value);\n\n if (isExactKeyMatch) return true;\n\n // case-insensitive matching if exact match is not found\n const normalizedLabel = label.toLocaleLowerCase('en-US');\n const normalizedValue = value?.toLocaleLowerCase('en-US');\n\n for (const [key, val] of Object.entries(resource.metadata.labels)) {\n if (key.toLocaleLowerCase('en-US') === normalizedLabel) {\n if (\n normalizedValue === undefined ||\n val.toLocaleLowerCase('en-US') === normalizedValue\n ) {\n return true;\n }\n }\n }\n return false;\n },\n toQuery: ({ label, value }) =>\n value === undefined\n ? {\n key: `metadata.labels.${label}`,\n }\n : {\n key: `metadata.labels.${label}`,\n values: [value],\n },\n});\n"],"names":["createPermissionRule","catalogEntityPermissionResourceRef","z"],"mappings":";;;;;;AAyBO,MAAM,WAAWA,yCAAA,CAAqB;AAAA,EAC3C,IAAA,EAAM,WAAA;AAAA,EACN,WAAA,EAAa,yCAAA;AAAA,EACb,WAAA,EAAaC,wCAAA;AAAA,EACb,YAAA,EAAcC,KAAE,MAAA,CAAO;AAAA,IACrB,KAAA,EAAOA,IAAA,CAAE,MAAA,EAAO,CAAE,SAAS,+BAA+B,CAAA;AAAA,IAC1D,OAAOA,IAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,gCAAgC;AAAA,GACvE,CAAA;AAAA,EACD,OAAO,CAAC,QAAA,EAAU,EAAE,KAAA,EAAO,OAAM,KAAM;AACrC,IAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ,OAAO,KAAA;AAGtC,IAAA,MAAM,kBACJ,CAAC,CAAC,QAAA,CAAS,QAAA,CAAS,QAAQ,cAAA,CAAe,KAAK,CAAA,KAC/C,KAAA,KAAU,SACP,IAAA,GACA,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,KAAK,CAAA,KAAM,KAAA,CAAA;AAE5C,IAAA,IAAI,iBAAiB,OAAO,IAAA;AAG5B,IAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,iBAAA,CAAkB,OAAO,CAAA;AACvD,IAAA,MAAM,eAAA,GAAkB,KAAA,EAAO,iBAAA,CAAkB,OAAO,CAAA;AAExD,IAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAAG;AACjE,MAAA,IAAI,GAAA,CAAI,iBAAA,CAAkB,OAAO,CAAA,KAAM,eAAA,EAAiB;AACtD,QAAA,IACE,oBAAoB,MAAA,IACpB,GAAA,CAAI,iBAAA,CAAkB,OAAO,MAAM,eAAA,EACnC;AACA,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAAA,EACA,SAAS,CAAC,EAAE,OAAO,KAAA,EAAM,KACvB,UAAU,MAAA,GACN;AAAA,IACE,GAAA,EAAK,mBAAmB,KAAK,CAAA;AAAA,GAC/B,GACA;AAAA,IACE,GAAA,EAAK,mBAAmB,KAAK,CAAA,CAAA;AAAA,IAC7B,MAAA,EAAQ,CAAC,KAAK;AAAA;AAExB,CAAC;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-catalog-backend",
|
|
3
|
-
"version": "3.8.0
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "The Backstage backend plugin that provides the Backstage catalog",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "backend-plugin",
|
|
@@ -76,20 +76,20 @@
|
|
|
76
76
|
"test": "backstage-cli package test"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@backstage/backend-openapi-utils": "0.6.10
|
|
80
|
-
"@backstage/backend-plugin-api": "1.9.2
|
|
81
|
-
"@backstage/catalog-client": "1.16.0
|
|
82
|
-
"@backstage/catalog-model": "1.9.0",
|
|
83
|
-
"@backstage/config": "1.3.8",
|
|
84
|
-
"@backstage/errors": "1.3.1",
|
|
85
|
-
"@backstage/filter-predicates": "0.1.3",
|
|
86
|
-
"@backstage/integration": "2.0.3
|
|
87
|
-
"@backstage/plugin-catalog-common": "1.1.10",
|
|
88
|
-
"@backstage/plugin-catalog-node": "2.2.2
|
|
89
|
-
"@backstage/plugin-events-node": "0.4.23
|
|
90
|
-
"@backstage/plugin-permission-common": "0.9.9",
|
|
91
|
-
"@backstage/plugin-permission-node": "0.11.1
|
|
92
|
-
"@backstage/types": "1.2.2",
|
|
79
|
+
"@backstage/backend-openapi-utils": "^0.6.10",
|
|
80
|
+
"@backstage/backend-plugin-api": "^1.9.2",
|
|
81
|
+
"@backstage/catalog-client": "^1.16.0",
|
|
82
|
+
"@backstage/catalog-model": "^1.9.0",
|
|
83
|
+
"@backstage/config": "^1.3.8",
|
|
84
|
+
"@backstage/errors": "^1.3.1",
|
|
85
|
+
"@backstage/filter-predicates": "^0.1.3",
|
|
86
|
+
"@backstage/integration": "^2.0.3",
|
|
87
|
+
"@backstage/plugin-catalog-common": "^1.1.10",
|
|
88
|
+
"@backstage/plugin-catalog-node": "^2.2.2",
|
|
89
|
+
"@backstage/plugin-events-node": "^0.4.23",
|
|
90
|
+
"@backstage/plugin-permission-common": "^0.9.9",
|
|
91
|
+
"@backstage/plugin-permission-node": "^0.11.1",
|
|
92
|
+
"@backstage/types": "^1.2.2",
|
|
93
93
|
"@opentelemetry/api": "^1.9.0",
|
|
94
94
|
"ajv": "^8.10.0",
|
|
95
95
|
"ajv-errors": "^3.0.0",
|
|
@@ -112,12 +112,12 @@
|
|
|
112
112
|
"zod-validation-error": "^4.0.2"
|
|
113
113
|
},
|
|
114
114
|
"devDependencies": {
|
|
115
|
-
"@backstage/backend-defaults": "0.17.3
|
|
116
|
-
"@backstage/backend-test-utils": "1.11.4
|
|
117
|
-
"@backstage/cli": "0.36.3
|
|
118
|
-
"@backstage/plugin-catalog-backend-module-logs": "0.1.23
|
|
119
|
-
"@backstage/plugin-scaffolder-common": "2.2.1
|
|
120
|
-
"@backstage/repo-tools": "0.17.3
|
|
115
|
+
"@backstage/backend-defaults": "^0.17.3",
|
|
116
|
+
"@backstage/backend-test-utils": "^1.11.4",
|
|
117
|
+
"@backstage/cli": "^0.36.3",
|
|
118
|
+
"@backstage/plugin-catalog-backend-module-logs": "^0.1.23",
|
|
119
|
+
"@backstage/plugin-scaffolder-common": "^2.2.1",
|
|
120
|
+
"@backstage/repo-tools": "^0.17.3",
|
|
121
121
|
"@types/core-js": "^2.5.4",
|
|
122
122
|
"@types/express": "^4.17.6",
|
|
123
123
|
"@types/git-url-parse": "^9.0.0",
|