@backstage/plugin-catalog-backend 1.12.3 → 1.13.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 CHANGED
@@ -1,62 +1,65 @@
1
1
  # @backstage/plugin-catalog-backend
2
2
 
3
- ## 1.12.3
3
+ ## 1.13.0-next.1
4
4
 
5
- ### Patch Changes
6
-
7
- - b0dbcb3eed4e: Fix issue with `catalogFileName` not being a required property for `/analyze-location`
5
+ ### Minor Changes
8
6
 
9
- ## 1.12.2
7
+ - 62f448edb0b5: Allow configuring the processing interval in your app-config, under the `catalog.processingInterval` key.
10
8
 
11
9
  ### Patch Changes
12
10
 
13
- - 97655cdf891f: Fix to the `limit` parameter on entity queries.
14
- - be5c0f4b7744: Update OpenAPI schema to relax the encoding validation of all request parameters.
11
+ - 1fd2109739c1: Changed the processing loop task pipeline implementation from recursive to iterative
12
+ - 0f8a97777489: Update OpenAPI schema to relax the encoding validation of all request parameters.
13
+ - 2d32d8a611e3: Fixed validation of the `fullTextFilterFields` query parameter.
14
+ - 618257f3e413: Fix issue with `catalogFileName` not being a required property for `/analyze-location`
15
15
  - Updated dependencies
16
- - @backstage/integration@1.6.2
17
- - @backstage/backend-common@0.19.4
18
- - @backstage/backend-tasks@0.5.7
19
- - @backstage/plugin-auth-node@0.2.19
20
- - @backstage/plugin-catalog-node@1.4.3
21
- - @backstage/plugin-permission-node@0.7.13
22
- - @backstage/plugin-search-backend-module-catalog@0.1.6
16
+ - @backstage/config@1.1.0-next.0
17
+ - @backstage/integration@1.7.0-next.1
18
+ - @backstage/backend-tasks@0.5.8-next.1
19
+ - @backstage/backend-common@0.19.5-next.1
20
+ - @backstage/backend-plugin-api@0.6.3-next.1
21
+ - @backstage/catalog-model@1.4.2-next.0
22
+ - @backstage/plugin-auth-node@0.3.0-next.1
23
+ - @backstage/plugin-permission-common@0.7.8-next.0
24
+ - @backstage/plugin-permission-node@0.7.14-next.1
25
+ - @backstage/plugin-search-backend-module-catalog@0.1.7-next.1
26
+ - @backstage/plugin-catalog-node@1.4.4-next.1
27
+ - @backstage/plugin-events-node@0.2.12-next.1
28
+ - @backstage/catalog-client@1.4.4-next.0
29
+ - @backstage/plugin-catalog-common@1.0.16-next.0
30
+ - @backstage/plugin-scaffolder-common@1.4.1-next.0
23
31
  - @backstage/backend-openapi-utils@0.0.3
24
- - @backstage/backend-plugin-api@0.6.2
25
- - @backstage/catalog-client@1.4.3
26
- - @backstage/catalog-model@1.4.1
27
- - @backstage/config@1.0.8
28
32
  - @backstage/errors@1.2.1
29
33
  - @backstage/types@1.1.0
30
- - @backstage/plugin-catalog-common@1.0.15
31
- - @backstage/plugin-events-node@0.2.11
32
- - @backstage/plugin-permission-common@0.7.7
33
- - @backstage/plugin-scaffolder-common@1.4.0
34
- - @backstage/plugin-search-common@1.2.5
34
+ - @backstage/plugin-search-common@1.2.6-next.0
35
35
 
36
- ## 1.12.1
36
+ ## 1.12.2-next.0
37
37
 
38
38
  ### Patch Changes
39
39
 
40
- - 550cef5818d9: Fix OpenAPI schema for the facets endpoint
40
+ - 149361e81622: Fix to the `limit` parameter on entity queries.
41
+ - 0198aa596fd9: Fixed a link to the frontend Backstage plugin that had pointed to itself.
42
+ - 41d1b2d628ea: Fix OpenAPI schema for the facets endpoint
43
+ - cfc3ca6ce060: Changes needed to support MySQL
41
44
  - Updated dependencies
42
- - @backstage/integration@1.6.1
43
- - @backstage/backend-common@0.19.3
44
- - @backstage/backend-tasks@0.5.6
45
- - @backstage/plugin-auth-node@0.2.18
46
- - @backstage/plugin-catalog-node@1.4.2
47
- - @backstage/plugin-permission-node@0.7.12
48
- - @backstage/plugin-search-backend-module-catalog@0.1.5
45
+ - @backstage/plugin-auth-node@0.3.0-next.0
46
+ - @backstage/backend-common@0.19.4-next.0
47
+ - @backstage/integration@1.7.0-next.0
48
+ - @backstage/backend-tasks@0.5.7-next.0
49
49
  - @backstage/backend-openapi-utils@0.0.3
50
- - @backstage/backend-plugin-api@0.6.1
50
+ - @backstage/backend-plugin-api@0.6.2-next.0
51
51
  - @backstage/catalog-client@1.4.3
52
52
  - @backstage/catalog-model@1.4.1
53
53
  - @backstage/config@1.0.8
54
54
  - @backstage/errors@1.2.1
55
55
  - @backstage/types@1.1.0
56
56
  - @backstage/plugin-catalog-common@1.0.15
57
- - @backstage/plugin-events-node@0.2.10
57
+ - @backstage/plugin-catalog-node@1.4.3-next.0
58
+ - @backstage/plugin-events-node@0.2.11-next.0
58
59
  - @backstage/plugin-permission-common@0.7.7
60
+ - @backstage/plugin-permission-node@0.7.13-next.0
59
61
  - @backstage/plugin-scaffolder-common@1.4.0
62
+ - @backstage/plugin-search-backend-module-catalog@0.1.6-next.0
60
63
  - @backstage/plugin-search-common@1.2.5
61
64
 
62
65
  ## 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.3",
3
+ "version": "1.13.0-next.1",
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-adc8f2ef.cjs.js');
7
+ var CatalogBuilder = require('./cjs/CatalogBuilder-e344ff09.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":"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"}
@@ -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
 
@@ -3374,15 +3410,6 @@ function basicEntityFilter(items) {
3374
3410
  return { anyOf: [{ allOf: Object.values(filtersByKey) }] };
3375
3411
  }
3376
3412
 
3377
- function parseStringParam(param, ctx) {
3378
- if (param === void 0) {
3379
- return void 0;
3380
- }
3381
- if (typeof param !== "string") {
3382
- throw new errors.InputError(`Invalid ${ctx}, not a string`);
3383
- }
3384
- return param;
3385
- }
3386
3413
  function parseStringsParam(param, ctx) {
3387
3414
  if (param === void 0) {
3388
3415
  return void 0;
@@ -3489,22 +3516,10 @@ function isOrder(order) {
3489
3516
  return ["asc", "desc"].includes(order);
3490
3517
  }
3491
3518
 
3492
- function parseFullTextFilterFields(params) {
3493
- const fullTextFilterFields = parseStringParam(
3494
- params.fullTextFilterFields,
3495
- "fullTextFilterFields"
3496
- );
3497
- if (!fullTextFilterFields) {
3498
- return void 0;
3499
- }
3500
- return fullTextFilterFields.split(",");
3501
- }
3502
-
3503
3519
  function parseQueryEntitiesParams(params) {
3504
3520
  const fields = parseEntityTransformParams(params);
3505
- const cursor = parseStringParam(params.cursor, "cursor");
3506
- if (cursor) {
3507
- const decodedCursor = decodeCursor(cursor);
3521
+ if (params.cursor) {
3522
+ const decodedCursor = decodeCursor(params.cursor);
3508
3523
  const response2 = {
3509
3524
  cursor: decodedCursor,
3510
3525
  fields
@@ -3512,19 +3527,14 @@ function parseQueryEntitiesParams(params) {
3512
3527
  return response2;
3513
3528
  }
3514
3529
  const filter = parseEntityFilterParams(params);
3515
- const fullTextFilterTerm = parseStringParam(
3516
- params.fullTextFilterTerm,
3517
- "fullTextFilterTerm"
3518
- );
3519
- const fullTextFilterFields = parseFullTextFilterFields(params);
3520
3530
  const orderFields = parseEntityOrderFieldParams(params);
3521
3531
  const response = {
3522
3532
  fields,
3523
3533
  filter,
3524
3534
  orderFields,
3525
3535
  fullTextFilter: {
3526
- term: fullTextFilterTerm || "",
3527
- fields: fullTextFilterFields
3536
+ term: params.fullTextFilterTerm || "",
3537
+ fields: params.fullTextFilterFields
3528
3538
  }
3529
3539
  };
3530
3540
  return response;
@@ -6144,10 +6154,7 @@ class CatalogBuilder {
6144
6154
  __publicField(this, "processorsReplace");
6145
6155
  __publicField(this, "parser");
6146
6156
  __publicField(this, "onProcessingError");
6147
- __publicField(this, "processingInterval", createRandomProcessingInterval({
6148
- minSeconds: 100,
6149
- maxSeconds: 150
6150
- }));
6157
+ __publicField(this, "processingInterval");
6151
6158
  __publicField(this, "locationAnalyzer");
6152
6159
  __publicField(this, "permissionRules");
6153
6160
  __publicField(this, "allowedLocationType");
@@ -6165,6 +6172,9 @@ class CatalogBuilder {
6165
6172
  this.parser = void 0;
6166
6173
  this.permissionRules = Object.values(permissionRules);
6167
6174
  this.allowedLocationType = ["url"];
6175
+ this.processingInterval = CatalogBuilder.getDefaultProcessingInterval(
6176
+ env.config
6177
+ );
6168
6178
  }
6169
6179
  /**
6170
6180
  * Creates a catalog builder.
@@ -6367,7 +6377,7 @@ class CatalogBuilder {
6367
6377
  return this;
6368
6378
  }
6369
6379
  /**
6370
- * Enables the publishing of events for cloflicts in the DefaultProcessingDatabase
6380
+ * Enables the publishing of events for conflicts in the DefaultProcessingDatabase
6371
6381
  */
6372
6382
  setEventBroker(broker) {
6373
6383
  this.eventBroker = broker;
@@ -6644,6 +6654,26 @@ class CatalogBuilder {
6644
6654
  "https://backstage.io/docs/integrations/azure/org"
6645
6655
  );
6646
6656
  }
6657
+ static getDefaultProcessingInterval(config$1) {
6658
+ const processingIntervalKey = "catalog.processingInterval";
6659
+ if (!config$1.has(processingIntervalKey)) {
6660
+ return createRandomProcessingInterval({
6661
+ minSeconds: 100,
6662
+ maxSeconds: 150
6663
+ });
6664
+ }
6665
+ const duration = config.readDurationFromConfig(config$1, {
6666
+ key: processingIntervalKey
6667
+ });
6668
+ const seconds = Math.max(
6669
+ 1,
6670
+ Math.round(types.durationToMilliseconds(duration) / 1e3)
6671
+ );
6672
+ return createRandomProcessingInterval({
6673
+ minSeconds: seconds,
6674
+ maxSeconds: seconds * 1.5
6675
+ });
6676
+ }
6647
6677
  }
6648
6678
 
6649
6679
  exports.AnnotateLocationEntityProcessor = AnnotateLocationEntityProcessor;
@@ -6658,4 +6688,4 @@ exports.createCatalogPermissionRule = createCatalogPermissionRule;
6658
6688
  exports.createRandomProcessingInterval = createRandomProcessingInterval;
6659
6689
  exports.parseEntityYaml = parseEntityYaml;
6660
6690
  exports.permissionRules = permissionRules;
6661
- //# sourceMappingURL=CatalogBuilder-adc8f2ef.cjs.js.map
6691
+ //# sourceMappingURL=CatalogBuilder-e344ff09.cjs.js.map