@backstage/plugin-catalog-backend 1.12.4 → 1.13.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,68 +1,93 @@
1
1
  # @backstage/plugin-catalog-backend
2
2
 
3
- ## 1.12.4
3
+ ## 1.13.0-next.2
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - cec43bb2428a: Fixed validation of the `fullTextFilterFields` query parameter.
8
-
9
- ## 1.12.3
7
+ - acffa17027b6: Added some examples to the catalog OpenAPI definition
8
+ - 45947d3b2759: Fixes an issue where `order` was not a recognized parameter for the `/entities` endpoint.
9
+ - 814feeed7343: Update to handle invalid luxon values
10
+ - Updated dependencies
11
+ - @backstage/config@1.1.0-next.1
12
+ - @backstage/backend-tasks@0.5.8-next.2
13
+ - @backstage/backend-common@0.19.5-next.2
14
+ - @backstage/plugin-auth-node@0.3.0-next.2
15
+ - @backstage/plugin-catalog-node@1.4.4-next.2
16
+ - @backstage/plugin-permission-node@0.7.14-next.2
17
+ - @backstage/plugin-search-backend-module-catalog@0.1.7-next.2
18
+ - @backstage/integration@1.7.0-next.2
19
+ - @backstage/backend-plugin-api@0.6.3-next.2
20
+ - @backstage/catalog-model@1.4.2-next.1
21
+ - @backstage/plugin-permission-common@0.7.8-next.1
22
+ - @backstage/backend-openapi-utils@0.0.3
23
+ - @backstage/catalog-client@1.4.4-next.1
24
+ - @backstage/errors@1.2.1
25
+ - @backstage/types@1.1.0
26
+ - @backstage/plugin-catalog-common@1.0.16-next.1
27
+ - @backstage/plugin-events-node@0.2.12-next.2
28
+ - @backstage/plugin-scaffolder-common@1.4.1-next.1
29
+ - @backstage/plugin-search-common@1.2.6-next.1
10
30
 
11
- ### Patch Changes
31
+ ## 1.13.0-next.1
12
32
 
13
- - b0dbcb3eed4e: Fix issue with `catalogFileName` not being a required property for `/analyze-location`
33
+ ### Minor Changes
14
34
 
15
- ## 1.12.2
35
+ - 62f448edb0b5: Allow configuring the processing interval in your app-config, under the `catalog.processingInterval` key.
16
36
 
17
37
  ### Patch Changes
18
38
 
19
- - 97655cdf891f: Fix to the `limit` parameter on entity queries.
20
- - be5c0f4b7744: Update OpenAPI schema to relax the encoding validation of all request parameters.
39
+ - 1fd2109739c1: Changed the processing loop task pipeline implementation from recursive to iterative
40
+ - 0f8a97777489: Update OpenAPI schema to relax the encoding validation of all request parameters.
41
+ - 2d32d8a611e3: Fixed validation of the `fullTextFilterFields` query parameter.
42
+ - 618257f3e413: Fix issue with `catalogFileName` not being a required property for `/analyze-location`
21
43
  - Updated dependencies
22
- - @backstage/integration@1.6.2
23
- - @backstage/backend-common@0.19.4
24
- - @backstage/backend-tasks@0.5.7
25
- - @backstage/plugin-auth-node@0.2.19
26
- - @backstage/plugin-catalog-node@1.4.3
27
- - @backstage/plugin-permission-node@0.7.13
28
- - @backstage/plugin-search-backend-module-catalog@0.1.6
44
+ - @backstage/config@1.1.0-next.0
45
+ - @backstage/integration@1.7.0-next.1
46
+ - @backstage/backend-tasks@0.5.8-next.1
47
+ - @backstage/backend-common@0.19.5-next.1
48
+ - @backstage/backend-plugin-api@0.6.3-next.1
49
+ - @backstage/catalog-model@1.4.2-next.0
50
+ - @backstage/plugin-auth-node@0.3.0-next.1
51
+ - @backstage/plugin-permission-common@0.7.8-next.0
52
+ - @backstage/plugin-permission-node@0.7.14-next.1
53
+ - @backstage/plugin-search-backend-module-catalog@0.1.7-next.1
54
+ - @backstage/plugin-catalog-node@1.4.4-next.1
55
+ - @backstage/plugin-events-node@0.2.12-next.1
56
+ - @backstage/catalog-client@1.4.4-next.0
57
+ - @backstage/plugin-catalog-common@1.0.16-next.0
58
+ - @backstage/plugin-scaffolder-common@1.4.1-next.0
29
59
  - @backstage/backend-openapi-utils@0.0.3
30
- - @backstage/backend-plugin-api@0.6.2
31
- - @backstage/catalog-client@1.4.3
32
- - @backstage/catalog-model@1.4.1
33
- - @backstage/config@1.0.8
34
60
  - @backstage/errors@1.2.1
35
61
  - @backstage/types@1.1.0
36
- - @backstage/plugin-catalog-common@1.0.15
37
- - @backstage/plugin-events-node@0.2.11
38
- - @backstage/plugin-permission-common@0.7.7
39
- - @backstage/plugin-scaffolder-common@1.4.0
40
- - @backstage/plugin-search-common@1.2.5
62
+ - @backstage/plugin-search-common@1.2.6-next.0
41
63
 
42
- ## 1.12.1
64
+ ## 1.12.2-next.0
43
65
 
44
66
  ### Patch Changes
45
67
 
46
- - 550cef5818d9: Fix OpenAPI schema for the facets endpoint
68
+ - 149361e81622: Fix to the `limit` parameter on entity queries.
69
+ - 0198aa596fd9: Fixed a link to the frontend Backstage plugin that had pointed to itself.
70
+ - 41d1b2d628ea: Fix OpenAPI schema for the facets endpoint
71
+ - cfc3ca6ce060: Changes needed to support MySQL
47
72
  - Updated dependencies
48
- - @backstage/integration@1.6.1
49
- - @backstage/backend-common@0.19.3
50
- - @backstage/backend-tasks@0.5.6
51
- - @backstage/plugin-auth-node@0.2.18
52
- - @backstage/plugin-catalog-node@1.4.2
53
- - @backstage/plugin-permission-node@0.7.12
54
- - @backstage/plugin-search-backend-module-catalog@0.1.5
73
+ - @backstage/plugin-auth-node@0.3.0-next.0
74
+ - @backstage/backend-common@0.19.4-next.0
75
+ - @backstage/integration@1.7.0-next.0
76
+ - @backstage/backend-tasks@0.5.7-next.0
55
77
  - @backstage/backend-openapi-utils@0.0.3
56
- - @backstage/backend-plugin-api@0.6.1
78
+ - @backstage/backend-plugin-api@0.6.2-next.0
57
79
  - @backstage/catalog-client@1.4.3
58
80
  - @backstage/catalog-model@1.4.1
59
81
  - @backstage/config@1.0.8
60
82
  - @backstage/errors@1.2.1
61
83
  - @backstage/types@1.1.0
62
84
  - @backstage/plugin-catalog-common@1.0.15
63
- - @backstage/plugin-events-node@0.2.10
85
+ - @backstage/plugin-catalog-node@1.4.3-next.0
86
+ - @backstage/plugin-events-node@0.2.11-next.0
64
87
  - @backstage/plugin-permission-common@0.7.7
88
+ - @backstage/plugin-permission-node@0.7.13-next.0
65
89
  - @backstage/plugin-scaffolder-common@1.4.0
90
+ - @backstage/plugin-search-backend-module-catalog@0.1.6-next.0
66
91
  - @backstage/plugin-search-common@1.2.5
67
92
 
68
93
  ## 1.12.0
package/README.md CHANGED
@@ -86,5 +86,5 @@ some example entities.
86
86
 
87
87
  ## Links
88
88
 
89
- - [catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend)
89
+ - [catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog)
90
90
  is the frontend interface for this plugin.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend",
3
- "version": "1.12.4",
3
+ "version": "1.13.0-next.2",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/config.d.ts CHANGED
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { HumanDuration } from '@backstage/types';
18
+
17
19
  export interface Config {
18
20
  /**
19
21
  * Configuration options for the catalog plugin.
@@ -142,5 +144,30 @@ export interface Config {
142
144
  * "keep".
143
145
  */
144
146
  orphanStrategy?: 'keep' | 'delete';
147
+
148
+ /**
149
+ * The interval at which the catalog should process its entities.
150
+ *
151
+ * @remarks
152
+ *
153
+ * Example:
154
+ *
155
+ * ```yaml
156
+ * catalog:
157
+ * processingInterval: { minutes: 30 }
158
+ * ```
159
+ *
160
+ * Note that this is only a suggested minimum, and the actual interval may
161
+ * be longer. Internally, the catalog will scale up this number by a small
162
+ * factor and choose random numbers in that range to spread out the load. If
163
+ * the catalog is overloaded and cannot process all entities during the
164
+ * interval, the time taken between processing runs of any given entity may
165
+ * also be longer than specified here.
166
+ *
167
+ * Setting this value too low risks exhausting rate limits on external
168
+ * systems that are queried by processors, such as version control systems
169
+ * housing catalog-info files.
170
+ */
171
+ processingInterval?: HumanDuration;
145
172
  };
146
173
  }
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-f6d92180.cjs.js');
7
+ var CatalogBuilder = require('./cjs/CatalogBuilder-c40214f8.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');
@@ -36,6 +36,8 @@ require('@backstage/backend-openapi-utils');
36
36
  require('@backstage/plugin-auth-node');
37
37
  require('@backstage/plugin-permission-common');
38
38
  require('minimatch');
39
+ require('@backstage/config');
40
+ require('@backstage/types');
39
41
 
40
42
  const { conditions, createConditionalDecision } = pluginPermissionNode.createConditionExports({
41
43
  pluginId: "catalog",
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/permissions/conditionExports.ts","../src/service/CatalogPlugin.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 { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport { permissionRules } from './rules';\n\nconst { conditions, createConditionalDecision } = createConditionExports({\n pluginId: 'catalog',\n resourceType: RESOURCE_TYPE_CATALOG_ENTITY,\n rules: permissionRules,\n});\n\n/**\n * These conditions are used when creating conditional decisions for catalog\n * entities that are returned by authorization policies.\n *\n * @alpha\n */\nexport const catalogConditions = conditions;\n\n/**\n * `createCatalogConditionalDecision` can be used when authoring policies to\n * create conditional decisions. It requires a permission of type\n * `ResourcePermission<'catalog-entity'>` to be passed as the first parameter.\n * It's recommended that you use the provided `isResourcePermission` and\n * `isPermission` helper methods to narrow the type of the permission passed to\n * the handle method as shown below.\n *\n * ```\n * // MyAuthorizationPolicy.ts\n * ...\n * import { createCatalogPolicyDecision } from '@backstage/plugin-catalog-backend';\n * import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';\n *\n * class MyAuthorizationPolicy implements PermissionPolicy {\n * async handle(request, user) {\n * ...\n *\n * if (isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)) {\n * return createCatalogConditionalDecision(\n * request.permission,\n * { anyOf: [...insert conditions here...] }\n * );\n * }\n *\n * ...\n * }\n * ```\n *\n * @alpha\n */\nexport const createCatalogConditionalDecision = createConditionalDecision;\n","/*\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 */\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { CatalogBuilder } from './CatalogBuilder';\nimport {\n CatalogProcessingExtensionPoint,\n catalogProcessingExtensionPoint,\n} from '@backstage/plugin-catalog-node/alpha';\nimport {\n CatalogProcessor,\n EntityProvider,\n} from '@backstage/plugin-catalog-node';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { PlaceholderResolver } from '../modules';\n\nclass CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint {\n #processors = new Array<CatalogProcessor>();\n #entityProviders = new Array<EntityProvider>();\n #placeholderResolvers: Record<string, PlaceholderResolver> = {};\n\n addProcessor(\n ...processors: Array<CatalogProcessor | Array<CatalogProcessor>>\n ): void {\n this.#processors.push(...processors.flat());\n }\n\n addEntityProvider(\n ...providers: Array<EntityProvider | Array<EntityProvider>>\n ): void {\n this.#entityProviders.push(...providers.flat());\n }\n\n addPlaceholderResolver(key: string, resolver: PlaceholderResolver) {\n if (key in this.#placeholderResolvers)\n throw new Error(\n `A placeholder resolver for '${key}' has already been set up, please check your config.`,\n );\n this.#placeholderResolvers[key] = resolver;\n }\n\n get processors() {\n return this.#processors;\n }\n\n get entityProviders() {\n return this.#entityProviders;\n }\n\n get placeholderResolvers() {\n return this.#placeholderResolvers;\n }\n}\n\n/**\n * Catalog plugin\n * @alpha\n */\nexport const catalogPlugin = createBackendPlugin({\n pluginId: 'catalog',\n register(env) {\n const processingExtensions = new CatalogExtensionPointImpl();\n // plugins depending on this API will be initialized before this plugins init method is executed.\n env.registerExtensionPoint(\n catalogProcessingExtensionPoint,\n processingExtensions,\n );\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n httpRouter: coreServices.httpRouter,\n lifecycle: coreServices.lifecycle,\n scheduler: coreServices.scheduler,\n },\n async init({\n logger,\n config,\n reader,\n database,\n permissions,\n httpRouter,\n lifecycle,\n scheduler,\n }) {\n const winstonLogger = loggerToWinstonLogger(logger);\n const builder = await CatalogBuilder.create({\n config,\n reader,\n permissions,\n database,\n scheduler,\n logger: winstonLogger,\n });\n builder.addProcessor(...processingExtensions.processors);\n builder.addEntityProvider(...processingExtensions.entityProviders);\n Object.entries(processingExtensions.placeholderResolvers).forEach(\n ([key, resolver]) => builder.setPlaceholderResolver(key, resolver),\n );\n\n const { processingEngine, router } = await builder.build();\n\n await processingEngine.start();\n lifecycle.addShutdownHook(() => processingEngine.stop());\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createConditionExports","RESOURCE_TYPE_CATALOG_ENTITY","permissionRules","createBackendPlugin","catalogProcessingExtensionPoint","coreServices","loggerToWinstonLogger","CatalogBuilder"],"mappings":"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"}
1
+ {"version":3,"file":"alpha.cjs.js","sources":["../src/permissions/conditionExports.ts","../src/service/CatalogPlugin.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 { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport { permissionRules } from './rules';\n\nconst { conditions, createConditionalDecision } = createConditionExports({\n pluginId: 'catalog',\n resourceType: RESOURCE_TYPE_CATALOG_ENTITY,\n rules: permissionRules,\n});\n\n/**\n * These conditions are used when creating conditional decisions for catalog\n * entities that are returned by authorization policies.\n *\n * @alpha\n */\nexport const catalogConditions = conditions;\n\n/**\n * `createCatalogConditionalDecision` can be used when authoring policies to\n * create conditional decisions. It requires a permission of type\n * `ResourcePermission<'catalog-entity'>` to be passed as the first parameter.\n * It's recommended that you use the provided `isResourcePermission` and\n * `isPermission` helper methods to narrow the type of the permission passed to\n * the handle method as shown below.\n *\n * ```\n * // MyAuthorizationPolicy.ts\n * ...\n * import { createCatalogPolicyDecision } from '@backstage/plugin-catalog-backend';\n * import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';\n *\n * class MyAuthorizationPolicy implements PermissionPolicy {\n * async handle(request, user) {\n * ...\n *\n * if (isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)) {\n * return createCatalogConditionalDecision(\n * request.permission,\n * { anyOf: [...insert conditions here...] }\n * );\n * }\n *\n * ...\n * }\n * ```\n *\n * @alpha\n */\nexport const createCatalogConditionalDecision = createConditionalDecision;\n","/*\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 */\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { CatalogBuilder } from './CatalogBuilder';\nimport {\n CatalogProcessingExtensionPoint,\n catalogProcessingExtensionPoint,\n} from '@backstage/plugin-catalog-node/alpha';\nimport {\n CatalogProcessor,\n EntityProvider,\n} from '@backstage/plugin-catalog-node';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { PlaceholderResolver } from '../modules';\n\nclass CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint {\n #processors = new Array<CatalogProcessor>();\n #entityProviders = new Array<EntityProvider>();\n #placeholderResolvers: Record<string, PlaceholderResolver> = {};\n\n addProcessor(\n ...processors: Array<CatalogProcessor | Array<CatalogProcessor>>\n ): void {\n this.#processors.push(...processors.flat());\n }\n\n addEntityProvider(\n ...providers: Array<EntityProvider | Array<EntityProvider>>\n ): void {\n this.#entityProviders.push(...providers.flat());\n }\n\n addPlaceholderResolver(key: string, resolver: PlaceholderResolver) {\n if (key in this.#placeholderResolvers)\n throw new Error(\n `A placeholder resolver for '${key}' has already been set up, please check your config.`,\n );\n this.#placeholderResolvers[key] = resolver;\n }\n\n get processors() {\n return this.#processors;\n }\n\n get entityProviders() {\n return this.#entityProviders;\n }\n\n get placeholderResolvers() {\n return this.#placeholderResolvers;\n }\n}\n\n/**\n * Catalog plugin\n * @alpha\n */\nexport const catalogPlugin = createBackendPlugin({\n pluginId: 'catalog',\n register(env) {\n const processingExtensions = new CatalogExtensionPointImpl();\n // plugins depending on this API will be initialized before this plugins init method is executed.\n env.registerExtensionPoint(\n catalogProcessingExtensionPoint,\n processingExtensions,\n );\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n httpRouter: coreServices.httpRouter,\n lifecycle: coreServices.lifecycle,\n scheduler: coreServices.scheduler,\n },\n async init({\n logger,\n config,\n reader,\n database,\n permissions,\n httpRouter,\n lifecycle,\n scheduler,\n }) {\n const winstonLogger = loggerToWinstonLogger(logger);\n const builder = await CatalogBuilder.create({\n config,\n reader,\n permissions,\n database,\n scheduler,\n logger: winstonLogger,\n });\n builder.addProcessor(...processingExtensions.processors);\n builder.addEntityProvider(...processingExtensions.entityProviders);\n Object.entries(processingExtensions.placeholderResolvers).forEach(\n ([key, resolver]) => builder.setPlaceholderResolver(key, resolver),\n );\n\n const { processingEngine, router } = await builder.build();\n\n await processingEngine.start();\n lifecycle.addShutdownHook(() => processingEngine.stop());\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createConditionExports","RESOURCE_TYPE_CATALOG_ENTITY","permissionRules","createBackendPlugin","catalogProcessingExtensionPoint","coreServices","loggerToWinstonLogger","CatalogBuilder"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAM,EAAE,UAAA,EAAY,yBAA0B,EAAA,GAAIA,2CAAuB,CAAA;AAAA,EACvE,QAAU,EAAA,SAAA;AAAA,EACV,YAAc,EAAAC,kCAAA;AAAA,EACd,KAAO,EAAAC,8BAAA;AACT,CAAC,CAAA,CAAA;AAQM,MAAM,iBAAoB,GAAA,WAAA;AAiC1B,MAAM,gCAAmC,GAAA;;;;;;;;;;;;;;;ACjEhD,IAAA,WAAA,EAAA,gBAAA,EAAA,qBAAA,CAAA;AA+BA,MAAM,yBAAqE,CAAA;AAAA,EAA3E,WAAA,GAAA;AACE,IAAA,YAAA,CAAA,IAAA,EAAA,WAAA,EAAc,IAAI,KAAwB,EAAA,CAAA,CAAA;AAC1C,IAAA,YAAA,CAAA,IAAA,EAAA,gBAAA,EAAmB,IAAI,KAAsB,EAAA,CAAA,CAAA;AAC7C,IAAA,YAAA,CAAA,IAAA,EAAA,qBAAA,EAA6D,EAAC,CAAA,CAAA;AAAA,GAAA;AAAA,EAE9D,gBACK,UACG,EAAA;AACN,IAAA,YAAA,CAAA,IAAA,EAAK,WAAY,CAAA,CAAA,IAAA,CAAK,GAAG,UAAA,CAAW,MAAM,CAAA,CAAA;AAAA,GAC5C;AAAA,EAEA,qBACK,SACG,EAAA;AACN,IAAA,YAAA,CAAA,IAAA,EAAK,gBAAiB,CAAA,CAAA,IAAA,CAAK,GAAG,SAAA,CAAU,MAAM,CAAA,CAAA;AAAA,GAChD;AAAA,EAEA,sBAAA,CAAuB,KAAa,QAA+B,EAAA;AACjE,IAAA,IAAI,OAAO,YAAK,CAAA,IAAA,EAAA,qBAAA,CAAA;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,+BAA+B,GAAG,CAAA,oDAAA,CAAA;AAAA,OACpC,CAAA;AACF,IAAK,YAAA,CAAA,IAAA,EAAA,qBAAA,CAAA,CAAsB,GAAG,CAAI,GAAA,QAAA,CAAA;AAAA,GACpC;AAAA,EAEA,IAAI,UAAa,GAAA;AACf,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,WAAA,CAAA,CAAA;AAAA,GACd;AAAA,EAEA,IAAI,eAAkB,GAAA;AACpB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,gBAAA,CAAA,CAAA;AAAA,GACd;AAAA,EAEA,IAAI,oBAAuB,GAAA;AACzB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,qBAAA,CAAA,CAAA;AAAA,GACd;AACF,CAAA;AAnCE,WAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACA,gBAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACA,qBAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAuCK,MAAM,gBAAgBC,oCAAoB,CAAA;AAAA,EAC/C,QAAU,EAAA,SAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAM,MAAA,oBAAA,GAAuB,IAAI,yBAA0B,EAAA,CAAA;AAE3D,IAAI,GAAA,CAAA,sBAAA;AAAA,MACFC,uCAAA;AAAA,MACA,oBAAA;AAAA,KACF,CAAA;AAEA,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,MAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,UAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,SAAA;AAAA,QACrB,aAAaA,6BAAa,CAAA,WAAA;AAAA,QAC1B,UAAUA,6BAAa,CAAA,QAAA;AAAA,QACvB,YAAYA,6BAAa,CAAA,UAAA;AAAA,QACzB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,WAAWA,6BAAa,CAAA,SAAA;AAAA,OAC1B;AAAA,MACA,MAAM,IAAK,CAAA;AAAA,QACT,MAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,UAAA;AAAA,QACA,SAAA;AAAA,QACA,SAAA;AAAA,OACC,EAAA;AACD,QAAM,MAAA,aAAA,GAAgBC,oCAAsB,MAAM,CAAA,CAAA;AAClD,QAAM,MAAA,OAAA,GAAU,MAAMC,6BAAA,CAAe,MAAO,CAAA;AAAA,UAC1C,MAAA;AAAA,UACA,MAAA;AAAA,UACA,WAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAA;AAAA,UACA,MAAQ,EAAA,aAAA;AAAA,SACT,CAAA,CAAA;AACD,QAAQ,OAAA,CAAA,YAAA,CAAa,GAAG,oBAAA,CAAqB,UAAU,CAAA,CAAA;AACvD,QAAQ,OAAA,CAAA,iBAAA,CAAkB,GAAG,oBAAA,CAAqB,eAAe,CAAA,CAAA;AACjE,QAAO,MAAA,CAAA,OAAA,CAAQ,oBAAqB,CAAA,oBAAoB,CAAE,CAAA,OAAA;AAAA,UACxD,CAAC,CAAC,GAAK,EAAA,QAAQ,MAAM,OAAQ,CAAA,sBAAA,CAAuB,KAAK,QAAQ,CAAA;AAAA,SACnE,CAAA;AAEA,QAAA,MAAM,EAAE,gBAAkB,EAAA,MAAA,EAAW,GAAA,MAAM,QAAQ,KAAM,EAAA,CAAA;AAEzD,QAAA,MAAM,iBAAiB,KAAM,EAAA,CAAA;AAC7B,QAAA,SAAA,CAAU,eAAgB,CAAA,MAAM,gBAAiB,CAAA,IAAA,EAAM,CAAA,CAAA;AACvD,QAAA,UAAA,CAAW,IAAI,MAAM,CAAA,CAAA;AAAA,OACvB;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;;;;;"}
@@ -30,7 +30,9 @@ var pluginAuthNode = require('@backstage/plugin-auth-node');
30
30
  var alpha = require('@backstage/plugin-catalog-common/alpha');
31
31
  var pluginPermissionCommon = require('@backstage/plugin-permission-common');
32
32
  var minimatch = require('minimatch');
33
+ var config = require('@backstage/config');
33
34
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
35
+ var types = require('@backstage/types');
34
36
 
35
37
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
36
38
 
@@ -1504,37 +1506,71 @@ function startTaskPipeline(options) {
1504
1506
  if (lowWatermark >= highWatermark) {
1505
1507
  throw new Error("lowWatermark must be lower than highWatermark");
1506
1508
  }
1507
- let loading = false;
1508
- let stopped = false;
1509
- let inFlightCount = 0;
1510
- async function maybeLoadMore() {
1511
- if (stopped || loading || inFlightCount > lowWatermark) {
1512
- return;
1513
- }
1514
- loading = true;
1515
- const loadCount = highWatermark - inFlightCount;
1516
- const loadedItems = await loadTasks(loadCount);
1517
- loading = false;
1518
- inFlightCount += loadedItems.length;
1519
- loadedItems.forEach((item) => {
1520
- processTask(item).finally(() => {
1521
- if (stopped) {
1522
- return;
1509
+ const state = { inFlightCount: 0 };
1510
+ const abortController = new AbortController();
1511
+ const abortSignal = abortController.signal;
1512
+ const barrier = createBarrier({
1513
+ waitTimeoutMillis: pollingIntervalMs,
1514
+ signal: abortSignal
1515
+ });
1516
+ async function pipelineLoop() {
1517
+ while (!abortSignal.aborted) {
1518
+ if (state.inFlightCount <= lowWatermark) {
1519
+ const loadCount = highWatermark - state.inFlightCount;
1520
+ const loadedItems = await Promise.resolve().then(() => loadTasks(loadCount)).catch(() => {
1521
+ return [];
1522
+ });
1523
+ if (loadedItems.length && !abortSignal.aborted) {
1524
+ state.inFlightCount += loadedItems.length;
1525
+ for (const item of loadedItems) {
1526
+ Promise.resolve().then(() => processTask(item)).catch(() => {
1527
+ }).finally(() => {
1528
+ state.inFlightCount -= 1;
1529
+ barrier.release();
1530
+ });
1531
+ }
1523
1532
  }
1524
- inFlightCount -= 1;
1525
- maybeLoadMore();
1526
- });
1527
- });
1528
- if (loadedItems.length > 1) {
1529
- maybeLoadMore();
1533
+ }
1534
+ await barrier.wait();
1530
1535
  }
1531
1536
  }
1532
- const intervalId = setInterval(() => {
1533
- maybeLoadMore();
1534
- }, pollingIntervalMs);
1537
+ pipelineLoop().catch((error) => {
1538
+ throw new Error(`Unexpected error in processing pipeline loop`, error);
1539
+ });
1535
1540
  return () => {
1536
- stopped = true;
1537
- clearInterval(intervalId);
1541
+ abortController.abort();
1542
+ barrier.destroy();
1543
+ };
1544
+ }
1545
+ function createBarrier(options) {
1546
+ const { waitTimeoutMillis, signal } = options;
1547
+ const resolvers = /* @__PURE__ */ new Set();
1548
+ function wait() {
1549
+ if (signal.aborted || !(waitTimeoutMillis > 0)) {
1550
+ return Promise.resolve();
1551
+ }
1552
+ return new Promise((resolve) => {
1553
+ const timeoutHandle = setTimeout(done, waitTimeoutMillis);
1554
+ function done() {
1555
+ resolvers.delete(done);
1556
+ clearTimeout(timeoutHandle);
1557
+ resolve();
1558
+ }
1559
+ resolvers.add(done);
1560
+ });
1561
+ }
1562
+ function release() {
1563
+ const resolversToCall = new Set(resolvers);
1564
+ resolvers.clear();
1565
+ for (const resolver of resolversToCall) {
1566
+ resolver();
1567
+ }
1568
+ }
1569
+ signal.addEventListener("abort", release);
1570
+ return {
1571
+ wait,
1572
+ release,
1573
+ destroy: () => signal.removeEventListener("abort", release)
1538
1574
  };
1539
1575
  }
1540
1576
 
@@ -3621,6 +3657,14 @@ const spec = {
3621
3657
  items: {
3622
3658
  type: "string"
3623
3659
  }
3660
+ },
3661
+ examples: {
3662
+ "Get name and the entire relations collection": {
3663
+ value: ["metadata.name", "relations"]
3664
+ },
3665
+ "Get kind, name and namespace": {
3666
+ value: ["kind", "metadata.name", "metadata.namespace"]
3667
+ }
3624
3668
  }
3625
3669
  },
3626
3670
  filter: {
@@ -3634,6 +3678,16 @@ const spec = {
3634
3678
  items: {
3635
3679
  type: "string"
3636
3680
  }
3681
+ },
3682
+ examples: {
3683
+ "Get groups": {
3684
+ value: ["kind=group"]
3685
+ },
3686
+ "Get orphaned components": {
3687
+ value: [
3688
+ "kind=component,metadata.annotations.backstage.io/orphan=true"
3689
+ ]
3690
+ }
3637
3691
  }
3638
3692
  },
3639
3693
  offset: {
@@ -3672,7 +3726,15 @@ const spec = {
3672
3726
  }
3673
3727
  },
3674
3728
  explode: true,
3675
- style: "form"
3729
+ style: "form",
3730
+ examples: {
3731
+ "Order ascending by name": {
3732
+ value: ["metadata.name,asc"]
3733
+ },
3734
+ "Order descending by owner": {
3735
+ value: ["spec.owner,desc"]
3736
+ }
3737
+ }
3676
3738
  }
3677
3739
  },
3678
3740
  requestBodies: {},
@@ -4299,6 +4361,18 @@ const spec = {
4299
4361
  },
4300
4362
  {
4301
4363
  $ref: "#/components/parameters/after"
4364
+ },
4365
+ {
4366
+ name: "order",
4367
+ in: "query",
4368
+ allowReserved: true,
4369
+ required: false,
4370
+ schema: {
4371
+ type: "array",
4372
+ items: {
4373
+ type: "string"
4374
+ }
4375
+ }
4302
4376
  }
4303
4377
  ]
4304
4378
  }
@@ -4470,6 +4544,22 @@ const spec = {
4470
4544
  }
4471
4545
  }
4472
4546
  }
4547
+ },
4548
+ examples: {
4549
+ "Fetch Backstage entities": {
4550
+ value: {
4551
+ entityRefs: [
4552
+ "component:default/backstage",
4553
+ "api:default/backstage"
4554
+ ]
4555
+ }
4556
+ },
4557
+ "Fetch annotations for backstage entity": {
4558
+ value: {
4559
+ entityRefs: ["component:default/backstage"],
4560
+ fields: ["metadata.annotations"]
4561
+ }
4562
+ }
4473
4563
  }
4474
4564
  }
4475
4565
  }
@@ -4575,6 +4665,14 @@ const spec = {
4575
4665
  items: {
4576
4666
  type: "string"
4577
4667
  }
4668
+ },
4669
+ examples: {
4670
+ "Entities by kind": {
4671
+ value: ["kind"]
4672
+ },
4673
+ "Entities by spec type": {
4674
+ value: ["spec.type"]
4675
+ }
4578
4676
  }
4579
4677
  },
4580
4678
  {
@@ -6118,10 +6216,7 @@ class CatalogBuilder {
6118
6216
  __publicField(this, "processorsReplace");
6119
6217
  __publicField(this, "parser");
6120
6218
  __publicField(this, "onProcessingError");
6121
- __publicField(this, "processingInterval", createRandomProcessingInterval({
6122
- minSeconds: 100,
6123
- maxSeconds: 150
6124
- }));
6219
+ __publicField(this, "processingInterval");
6125
6220
  __publicField(this, "locationAnalyzer");
6126
6221
  __publicField(this, "permissionRules");
6127
6222
  __publicField(this, "allowedLocationType");
@@ -6139,6 +6234,9 @@ class CatalogBuilder {
6139
6234
  this.parser = void 0;
6140
6235
  this.permissionRules = Object.values(permissionRules);
6141
6236
  this.allowedLocationType = ["url"];
6237
+ this.processingInterval = CatalogBuilder.getDefaultProcessingInterval(
6238
+ env.config
6239
+ );
6142
6240
  }
6143
6241
  /**
6144
6242
  * Creates a catalog builder.
@@ -6341,7 +6439,7 @@ class CatalogBuilder {
6341
6439
  return this;
6342
6440
  }
6343
6441
  /**
6344
- * Enables the publishing of events for cloflicts in the DefaultProcessingDatabase
6442
+ * Enables the publishing of events for conflicts in the DefaultProcessingDatabase
6345
6443
  */
6346
6444
  setEventBroker(broker) {
6347
6445
  this.eventBroker = broker;
@@ -6618,6 +6716,26 @@ class CatalogBuilder {
6618
6716
  "https://backstage.io/docs/integrations/azure/org"
6619
6717
  );
6620
6718
  }
6719
+ static getDefaultProcessingInterval(config$1) {
6720
+ const processingIntervalKey = "catalog.processingInterval";
6721
+ if (!config$1.has(processingIntervalKey)) {
6722
+ return createRandomProcessingInterval({
6723
+ minSeconds: 100,
6724
+ maxSeconds: 150
6725
+ });
6726
+ }
6727
+ const duration = config.readDurationFromConfig(config$1, {
6728
+ key: processingIntervalKey
6729
+ });
6730
+ const seconds = Math.max(
6731
+ 1,
6732
+ Math.round(types.durationToMilliseconds(duration) / 1e3)
6733
+ );
6734
+ return createRandomProcessingInterval({
6735
+ minSeconds: seconds,
6736
+ maxSeconds: seconds * 1.5
6737
+ });
6738
+ }
6621
6739
  }
6622
6740
 
6623
6741
  exports.AnnotateLocationEntityProcessor = AnnotateLocationEntityProcessor;
@@ -6632,4 +6750,4 @@ exports.createCatalogPermissionRule = createCatalogPermissionRule;
6632
6750
  exports.createRandomProcessingInterval = createRandomProcessingInterval;
6633
6751
  exports.parseEntityYaml = parseEntityYaml;
6634
6752
  exports.permissionRules = permissionRules;
6635
- //# sourceMappingURL=CatalogBuilder-f6d92180.cjs.js.map
6753
+ //# sourceMappingURL=CatalogBuilder-c40214f8.cjs.js.map