From 07ec25de2c936edaedbe630826d4ff0a84653e22 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Mon, 18 May 2026 16:57:26 +0200 Subject: [PATCH] fix(catalog-backend): move generateStableHash out of shared util to fix Storybook build (#34284) * fix(catalog-backend): move generateStableHash out of shared util to fix Storybook build The util.ts file mixed Node.js-only code (createHash from node:crypto) with pure constants. Since InMemoryCatalogClient reaches into buildEntitySearch via a relative import, and buildEntitySearch imports from util.ts, the node:crypto dependency leaked into Vite's browser bundle causing the Storybook build to fail. Signed-off-by: benjdlambert * add changeset Signed-off-by: benjdlambert --------- Signed-off-by: benjdlambert --- .changeset/fix-storybook-crypto-import.md | 5 +++++ .../database/operations/stitcher/performStitching.ts | 10 +++++++++- .../src/database/operations/stitcher/util.ts | 10 ---------- 3 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 .changeset/fix-storybook-crypto-import.md diff --git a/.changeset/fix-storybook-crypto-import.md b/.changeset/fix-storybook-crypto-import.md new file mode 100644 index 0000000000..5460b0f5b9 --- /dev/null +++ b/.changeset/fix-storybook-crypto-import.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Moved `generateStableHash` out of shared utility file to avoid pulling `node:crypto` into browser bundles diff --git a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts index a1e08de597..ff5df8ce9d 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/performStitching.ts @@ -18,11 +18,14 @@ import { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from '@backstage/catalog-client import { ANNOTATION_EDIT_URL, ANNOTATION_VIEW_URL, + Entity, EntityRelation, } from '@backstage/catalog-model'; import { AlphaEntity, EntityStatusItem } from '@backstage/catalog-model/alpha'; import { SerializedError } from '@backstage/errors'; import { Knex } from 'knex'; +import { createHash } from 'node:crypto'; +import stableStringify from 'fast-json-stable-stringify'; import { StitchingStrategy } from '../../../stitching/types'; import { DbFinalEntitiesRow, @@ -32,12 +35,17 @@ import { import { buildEntitySearch } from './buildEntitySearch'; import { markDeferredStitchCompleted } from './markDeferredStitchCompleted'; import { syncSearchRows } from './syncSearchRows'; -import { generateStableHash } from './util'; import { LoggerService, isDatabaseConflictError, } from '@backstage/backend-plugin-api'; +function generateStableHash(entity: Entity) { + return createHash('sha1') + .update(stableStringify({ ...entity })) + .digest('hex'); +} + // See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js const scriptProtocolPattern = // eslint-disable-next-line no-control-regex diff --git a/plugins/catalog-backend/src/database/operations/stitcher/util.ts b/plugins/catalog-backend/src/database/operations/stitcher/util.ts index bac099514a..998e255c33 100644 --- a/plugins/catalog-backend/src/database/operations/stitcher/util.ts +++ b/plugins/catalog-backend/src/database/operations/stitcher/util.ts @@ -14,10 +14,6 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; -import { createHash } from 'node:crypto'; -import stableStringify from 'fast-json-stable-stringify'; - // The number of items that are sent per batch to the database layer, when // doing .batchInsert calls to knex. This needs to be low enough to not cause // errors in the underlying engine due to exceeding query limits, but large @@ -29,9 +25,3 @@ export const BATCH_SIZE = 50; // COALESCE, JS dedup keys). It cannot appear in real entity metadata values // since they are human-readable strings. export const NULL_SENTINEL = '\x01'; - -export function generateStableHash(entity: Entity) { - return createHash('sha1') - .update(stableStringify({ ...entity })) - .digest('hex'); -}