@c-rex/services 0.3.0-build.39 → 0.3.0-build.40

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.
Files changed (33) hide show
  1. package/dist/index.d.mts +3 -1
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.js +430 -147
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +411 -143
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/metadata-visibility-policy.d.mts +29 -0
  8. package/dist/metadata-visibility-policy.d.ts +29 -0
  9. package/dist/metadata-visibility-policy.js +129 -0
  10. package/dist/metadata-visibility-policy.js.map +1 -0
  11. package/dist/metadata-visibility-policy.mjs +95 -0
  12. package/dist/metadata-visibility-policy.mjs.map +1 -0
  13. package/dist/read-models/index.d.mts +17 -39
  14. package/dist/read-models/index.d.ts +17 -39
  15. package/dist/read-models/index.js +430 -149
  16. package/dist/read-models/index.js.map +1 -1
  17. package/dist/read-models/index.mjs +410 -144
  18. package/dist/read-models/index.mjs.map +1 -1
  19. package/dist/read-models/metadata-display-builder.d.mts +34 -0
  20. package/dist/read-models/metadata-display-builder.d.ts +34 -0
  21. package/dist/read-models/metadata-display-builder.js +521 -0
  22. package/dist/read-models/metadata-display-builder.js.map +1 -0
  23. package/dist/read-models/metadata-display-builder.mjs +489 -0
  24. package/dist/read-models/metadata-display-builder.mjs.map +1 -0
  25. package/dist/read-models/metadata-presentation-config.js +2 -2
  26. package/dist/read-models/metadata-presentation-config.js.map +1 -1
  27. package/dist/read-models/metadata-presentation-config.mjs +2 -2
  28. package/dist/read-models/metadata-presentation-config.mjs.map +1 -1
  29. package/dist/read-models/metadata-view-profile.js +63 -4
  30. package/dist/read-models/metadata-view-profile.js.map +1 -1
  31. package/dist/read-models/metadata-view-profile.mjs +63 -4
  32. package/dist/read-models/metadata-view-profile.mjs.map +1 -1
  33. package/package.json +19 -1
@@ -22,7 +22,10 @@ var read_models_exports = {};
22
22
  __export(read_models_exports, {
23
23
  INFORMATION_UNIT_PROPERTY_PRESENTATION: () => INFORMATION_UNIT_PROPERTY_PRESENTATION,
24
24
  METADATA_VIEW_PROFILES: () => METADATA_VIEW_PROFILES,
25
+ METADATA_VISIBILITY_POLICY: () => METADATA_VISIBILITY_POLICY,
25
26
  READMODEL_CACHE_POLICY: () => READMODEL_CACHE_POLICY,
27
+ buildMetadataDisplayRows: () => buildMetadataDisplayRows,
28
+ clearMetadataCacheFamilyRuntimeSuppression: () => clearMetadataCacheFamilyRuntimeSuppression,
26
29
  getApplicableForTypes: () => getApplicableForTypes,
27
30
  getAvailableLanguagesByVersionOf: () => getAvailableLanguagesByVersionOf,
28
31
  getComponents: () => getComponents,
@@ -30,8 +33,10 @@ __export(read_models_exports, {
30
33
  getDocumentTypes: () => getDocumentTypes,
31
34
  getFunctionalMetadata: () => getFunctionalMetadata,
32
35
  getInformationSubjects: () => getInformationSubjects,
36
+ getMetadataCacheFamily: () => getMetadataCacheFamily,
33
37
  getMetadataDisplayRows: () => getMetadataDisplayRows,
34
38
  getMetadataFacetLabelOverrides: () => getMetadataFacetLabelOverrides,
39
+ getMetadataFacetPresentation: () => getMetadataFacetPresentation,
35
40
  getMetadataPropertyResolvers: () => getMetadataPropertyResolvers,
36
41
  getParties: () => getParties,
37
42
  getPlanningTimes: () => getPlanningTimes,
@@ -40,15 +45,26 @@ __export(read_models_exports, {
40
45
  getProductMetadata: () => getProductMetadata,
41
46
  getProductVariants: () => getProductVariants,
42
47
  getQualifications: () => getQualifications,
48
+ getRuntimeSuppressedMetadataFamilies: () => getRuntimeSuppressedMetadataFamilies,
43
49
  getSupplies: () => getSupplies,
44
50
  getTopicTypes: () => getTopicTypes,
51
+ isMetadataGroupDenied: () => isMetadataGroupDenied,
52
+ isMetadataPropertyRuntimeSuppressed: () => isMetadataPropertyRuntimeSuppressed,
53
+ resetRuntimeSuppressedMetadataFamiliesForTests: () => resetRuntimeSuppressedMetadataFamiliesForTests,
54
+ resolveFacetPresentationProperties: () => resolveFacetPresentationProperties,
45
55
  resolveFacetTags: () => resolveFacetTags,
46
- resolveMetadataDisplayProperties: () => resolveMetadataDisplayProperties
56
+ resolveLiteralLabel: () => resolveLiteralLabel,
57
+ resolveMetadataDisplayProperties: () => resolveMetadataDisplayProperties,
58
+ resolveObjectRefClassLabel: () => resolveObjectRefClassLabel,
59
+ resolveObjectRefLabel: () => resolveObjectRefLabel,
60
+ resolveOverrideProperties: () => resolveOverrideProperties,
61
+ suppressMetadataCacheFamilyRuntime: () => suppressMetadataCacheFamilyRuntime
47
62
  });
48
63
  module.exports = __toCommonJS(read_models_exports);
49
64
 
50
65
  // src/read-models/metadata-read-models.ts
51
66
  var import_requests2 = require("@c-rex/core/requests");
67
+ var import_logger = require("@c-rex/core/logger");
52
68
  var import_cache = require("next/cache");
53
69
 
54
70
  // src/base-server-request.ts
@@ -172,7 +188,106 @@ var READMODEL_CACHE_POLICY = {
172
188
  )
173
189
  };
174
190
 
191
+ // src/read-models/metadata-visibility-policy.ts
192
+ var CONTENT_LICENSE_CLASS_ID = "https://ids.c-crex.net/ns/iirds/ext#ContentLicense";
193
+ var METADATA_VISIBILITY_POLICY = {
194
+ parties: {
195
+ cacheFamily: "parties"
196
+ },
197
+ components: {
198
+ cacheFamily: "components"
199
+ },
200
+ informationSubjects: {
201
+ cacheFamily: "informationSubjects"
202
+ },
203
+ topicTypes: {
204
+ cacheFamily: "topicTypes"
205
+ },
206
+ documentTypes: {
207
+ cacheFamily: "documentTypes"
208
+ },
209
+ contentLifeCycleStatus: {
210
+ cacheFamily: "contentLifeCycleStatus"
211
+ },
212
+ applicableForTypes: {
213
+ cacheFamily: "documentTypes"
214
+ },
215
+ planningTimes: {
216
+ cacheFamily: "planningTimes"
217
+ },
218
+ functionalMetadata: {
219
+ cacheFamily: "functionalMetadata"
220
+ },
221
+ productFeatures: {
222
+ cacheFamily: "productFeatures"
223
+ },
224
+ productLifeCyclePhases: {
225
+ cacheFamily: "productLifeCyclePhases"
226
+ },
227
+ productMetadata: {
228
+ cacheFamily: "productMetadata"
229
+ },
230
+ productVariants: {
231
+ cacheFamily: "productVariants"
232
+ },
233
+ qualifications: {
234
+ cacheFamily: "qualifications",
235
+ deniedClassIds: [CONTENT_LICENSE_CLASS_ID]
236
+ },
237
+ supplies: {
238
+ cacheFamily: "supplies"
239
+ }
240
+ };
241
+ var runtimeSuppressedFamilies = /* @__PURE__ */ new Map();
242
+ var getMetadataCacheFamily = (property) => METADATA_VISIBILITY_POLICY[property]?.cacheFamily;
243
+ var isMetadataGroupDenied = (property, options) => {
244
+ const policy = METADATA_VISIBILITY_POLICY[property];
245
+ const classId = options.classId?.trim();
246
+ const partyRoleId = options.partyRoleId?.trim();
247
+ if (classId && policy?.deniedClassIds?.includes(classId)) {
248
+ return true;
249
+ }
250
+ if (partyRoleId && policy?.deniedPartyRoleIds?.includes(partyRoleId)) {
251
+ return true;
252
+ }
253
+ return false;
254
+ };
255
+ var suppressMetadataCacheFamilyRuntime = (family, entry) => {
256
+ runtimeSuppressedFamilies.set(family, {
257
+ family,
258
+ reason: "cache-overflow",
259
+ bytes: entry.bytes,
260
+ limitBytes: entry.limitBytes,
261
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
262
+ });
263
+ };
264
+ var clearMetadataCacheFamilyRuntimeSuppression = (family) => {
265
+ runtimeSuppressedFamilies.delete(family);
266
+ };
267
+ var isMetadataPropertyRuntimeSuppressed = (property) => {
268
+ const family = getMetadataCacheFamily(property);
269
+ return family ? runtimeSuppressedFamilies.has(family) : false;
270
+ };
271
+ var getRuntimeSuppressedMetadataFamilies = () => Array.from(runtimeSuppressedFamilies.values());
272
+ var resetRuntimeSuppressedMetadataFamiliesForTests = () => {
273
+ runtimeSuppressedFamilies.clear();
274
+ };
275
+
175
276
  // src/read-models/metadata-read-models.ts
277
+ var DEFAULT_METADATA_CACHE_MAX_BYTES = 15e5;
278
+ var resolveMetadataCacheMaxBytes = () => {
279
+ const value = Number(process.env.CREX_CACHE_METADATA_MAX_BYTES);
280
+ return Number.isFinite(value) && value > 0 ? value : DEFAULT_METADATA_CACHE_MAX_BYTES;
281
+ };
282
+ var measureSerializedBytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
283
+ var logCacheOverflow = async (family, bytes, limitBytes, cacheKey) => {
284
+ const logger = new import_logger.CrexLogger();
285
+ await logger.log({
286
+ level: "warning",
287
+ category: "Scenario",
288
+ message: `[MetadataCacheOverflow] family=${family} bytes=${bytes} limitBytes=${limitBytes} cacheKey=${cacheKey}`
289
+ });
290
+ };
176
291
  var resolveLocalizedLabel = (labels, uiLanguage) => {
177
292
  if (!labels || labels.length === 0) return void 0;
178
293
  const normalizedUiLanguage = uiLanguage.trim().toLowerCase();
@@ -231,12 +346,39 @@ var toEntityRef = (entity, uiLanguage) => {
231
346
  const label = resolveLocalizedLabel(entity.labels || [], uiLanguage) || entity.shortId?.trim() || id;
232
347
  return { id, shortId: entity.shortId?.trim() || void 0, label };
233
348
  };
234
- var toClassRef = (classRef, uiLanguage) => {
349
+ var toClassRef = (classRef, uiLanguage, classLabelsById) => {
235
350
  const id = classRef?.id?.trim();
236
351
  if (!id) return void 0;
237
- const label = resolveLocalizedLabel(classRef?.labels || [], uiLanguage) || classRef?.shortId?.trim() || id;
352
+ const label = resolveLocalizedLabel(classRef?.labels || [], uiLanguage) || classLabelsById?.[id] || classRef?.shortId?.trim() || id;
238
353
  return { id, shortId: classRef?.shortId?.trim() || void 0, label };
239
354
  };
355
+ var isNotFoundError = (error) => {
356
+ if (!(error instanceof Error)) {
357
+ return false;
358
+ }
359
+ return error.message.includes("HTTP error! status: 404");
360
+ };
361
+ var resolveMissingClassLabels = async (items, uiLanguage) => {
362
+ const classIds = Array.from(new Set(
363
+ items.map((item) => item.class?.id?.trim()).filter((id) => Boolean(id)).filter((id) => !resolveLocalizedLabel(items.find((item) => item.class?.id?.trim() === id)?.class?.labels || [], uiLanguage))
364
+ ));
365
+ const result = {};
366
+ await Promise.all(classIds.map(async (classId) => {
367
+ try {
368
+ const entity = await withServerRequestContext(
369
+ { skipCookieTokenLookup: true },
370
+ () => domainEntitiesGetByIdServer({ id: classId }, { Fields: ["labels"] })
371
+ );
372
+ result[classId] = resolveLocalizedLabel(entity.labels || [], uiLanguage);
373
+ } catch (error) {
374
+ if (!isNotFoundError(error)) {
375
+ throw error;
376
+ }
377
+ result[classId] = void 0;
378
+ }
379
+ }));
380
+ return result;
381
+ };
240
382
  var deriveParentIds = (entity) => {
241
383
  const directParents = (entity.parents || []).map((parent) => getRefId(parent)).filter((value) => Boolean(value));
242
384
  if (directParents.length > 0) {
@@ -245,10 +387,6 @@ var deriveParentIds = (entity) => {
245
387
  const ancestorParents = (entity.ancestors || []).map((path) => path[path.length - 1]).map((parent) => getRefId(parent)).filter((value) => Boolean(value));
246
388
  return Array.from(new Set(ancestorParents));
247
389
  };
248
- var deriveAncestorIds = (entity) => {
249
- const ids = (entity.ancestors || []).flatMap((path) => path).map((item) => getRefId(item)).filter((value) => Boolean(value));
250
- return Array.from(new Set(ids));
251
- };
252
390
  var buildTaxonomyTree = (items, options) => {
253
391
  const nodesById = {};
254
392
  const parentLinks = /* @__PURE__ */ new Map();
@@ -257,48 +395,13 @@ var buildTaxonomyTree = (items, options) => {
257
395
  if (!entityRef) continue;
258
396
  nodesById[entityRef.id] = {
259
397
  ...entityRef,
260
- classRef: toClassRef(item.class, options.uiLanguage),
261
- hasInformationUnits: item.hasInformationUnits === true || item.hasInformationUnitReferences === true,
262
- parentIds: deriveParentIds(item),
263
- ancestorIds: deriveAncestorIds(item),
264
- children: []
398
+ classRef: toClassRef(item.class, options.uiLanguage, options.classLabelsById),
399
+ parentIds: deriveParentIds(item)
265
400
  };
266
401
  }
267
402
  Object.values(nodesById).forEach((node) => {
268
403
  parentLinks.set(node.id, node.parentIds.filter((id) => Boolean(nodesById[id])));
269
404
  });
270
- if (options.includeOnlyUsed) {
271
- const keepIds = new Set(
272
- Object.values(nodesById).filter((node) => node.hasInformationUnits === true).map((node) => node.id)
273
- );
274
- let changed = true;
275
- while (changed) {
276
- changed = false;
277
- Array.from(keepIds).forEach((nodeId) => {
278
- const parentIds = parentLinks.get(nodeId) || [];
279
- parentIds.forEach((parentId) => {
280
- if (!keepIds.has(parentId)) {
281
- keepIds.add(parentId);
282
- changed = true;
283
- }
284
- });
285
- });
286
- }
287
- Object.keys(nodesById).forEach((nodeId) => {
288
- if (!keepIds.has(nodeId)) {
289
- delete nodesById[nodeId];
290
- parentLinks.delete(nodeId);
291
- }
292
- });
293
- }
294
- Object.values(nodesById).forEach((node) => {
295
- const parents = parentLinks.get(node.id) || [];
296
- parents.forEach((parentId) => {
297
- if (nodesById[parentId]) {
298
- nodesById[parentId].children.push(node);
299
- }
300
- });
301
- });
302
405
  const roots = Object.values(nodesById).filter((node) => (parentLinks.get(node.id) || []).length === 0);
303
406
  if (!options.groupRootsByClass) {
304
407
  return {
@@ -308,13 +411,12 @@ var buildTaxonomyTree = (items, options) => {
308
411
  };
309
412
  }
310
413
  const groupedRoots = /* @__PURE__ */ new Map();
414
+ const groupedRootCounts = /* @__PURE__ */ new Map();
311
415
  const ungroupedRootId = "class:ungrouped";
312
416
  groupedRoots.set(ungroupedRootId, {
313
417
  id: ungroupedRootId,
314
418
  label: "Ungrouped",
315
419
  parentIds: [],
316
- ancestorIds: [],
317
- children: [],
318
420
  isVirtualGroup: true
319
421
  });
320
422
  roots.forEach((root) => {
@@ -325,17 +427,12 @@ var buildTaxonomyTree = (items, options) => {
325
427
  shortId: root.classRef?.shortId,
326
428
  label: root.classRef?.label || "Ungrouped",
327
429
  parentIds: [],
328
- ancestorIds: [],
329
- children: [],
330
430
  isVirtualGroup: true
331
431
  });
332
432
  }
333
- groupedRoots.get(classId)?.children.push(root);
433
+ groupedRootCounts.set(classId, (groupedRootCounts.get(classId) || 0) + 1);
334
434
  });
335
- const groupedRootNodes = Array.from(groupedRoots.values()).filter((group) => group.children.length > 0).map((group) => ({
336
- ...group,
337
- children: [...group.children].sort((a, b) => a.label.localeCompare(b.label))
338
- })).sort((a, b) => a.label.localeCompare(b.label));
435
+ const groupedRootNodes = Array.from(groupedRoots.values()).filter((group) => (groupedRootCounts.get(group.id) || 0) > 0).sort((a, b) => a.label.localeCompare(b.label));
339
436
  return {
340
437
  roots: groupedRootNodes,
341
438
  nodesById,
@@ -348,15 +445,29 @@ var defaultTreeOptions = (uiLanguage) => ({
348
445
  });
349
446
  var createTaxonomyResolver = (options) => {
350
447
  const cached = (0, import_cache.unstable_cache)(
351
- async (_queryKey, query, uiLanguage, readOptions) => {
448
+ async (_queryKey, query, uiLanguage) => {
352
449
  const items = await withServerRequestContext(
353
450
  { skipCookieTokenLookup: true },
354
451
  () => fetchAllPages(options.fetch, query)
355
452
  );
356
- return buildTaxonomyTree(items, {
453
+ const classLabelsById = await resolveMissingClassLabels(items, uiLanguage);
454
+ const result = buildTaxonomyTree(items, {
357
455
  ...defaultTreeOptions(uiLanguage),
358
- includeOnlyUsed: readOptions.includeOnlyUsed
456
+ classLabelsById
359
457
  });
458
+ const bytes = measureSerializedBytes(result);
459
+ const limitBytes = resolveMetadataCacheMaxBytes();
460
+ if (bytes > limitBytes) {
461
+ suppressMetadataCacheFamilyRuntime(options.cacheFamily, { bytes, limitBytes });
462
+ await logCacheOverflow(options.cacheFamily, bytes, limitBytes, options.cacheKey);
463
+ return {
464
+ roots: [],
465
+ nodesById: {},
466
+ generatedAt: result.generatedAt
467
+ };
468
+ }
469
+ clearMetadataCacheFamilyRuntimeSuppression(options.cacheFamily);
470
+ return result;
360
471
  },
361
472
  ["read-model", options.cacheKey],
362
473
  {
@@ -369,101 +480,116 @@ var createTaxonomyResolver = (options) => {
369
480
  ]
370
481
  }
371
482
  );
372
- return async (query, readOptions) => {
483
+ return async (query) => {
373
484
  const uiLanguage = resolveUiLanguage();
374
485
  const normalizedQuery = { ...options.defaultQuery, ...query || {} };
375
- const normalizedReadOptions = {
376
- includeOnlyUsed: readOptions?.includeOnlyUsed === true
377
- };
378
- const cacheKey = stableSerialize({ normalizedQuery, uiLanguage, normalizedReadOptions });
379
- return cached(cacheKey, normalizedQuery, uiLanguage, normalizedReadOptions);
486
+ const cacheKey = stableSerialize({ normalizedQuery, uiLanguage });
487
+ return cached(cacheKey, normalizedQuery, uiLanguage);
380
488
  };
381
489
  };
382
490
  var defaultMetadataQuery = {
383
491
  PageNumber: 1,
384
492
  PageSize: READMODEL_PAGE_SIZE,
385
- Fields: ["labels", "class", "hasInformationUnits"],
493
+ Fields: ["labels", "class"],
386
494
  Sort: ["shortId"]
387
495
  };
388
496
  var getCategoriesCached = createTaxonomyResolver({
389
497
  cacheKey: "categories",
498
+ cacheFamily: "informationSubjects",
390
499
  tags: [import_requests2.CREX_READMODEL_CACHE_INFORMATION_SUBJECTS_TAG],
391
- defaultQuery: defaultMetadataQuery,
500
+ defaultQuery: {
501
+ ...defaultMetadataQuery,
502
+ Fields: ["labels", "class", "parents", "ancestors", "ancestorsOrSelf"]
503
+ },
392
504
  fetch: categoriesGetAllServer
393
505
  });
394
506
  var getInformationSubjectsLegacyCached = createTaxonomyResolver({
395
507
  cacheKey: "information-subjects-legacy",
508
+ cacheFamily: "informationSubjects",
396
509
  tags: [import_requests2.CREX_READMODEL_CACHE_INFORMATION_SUBJECTS_TAG],
397
510
  defaultQuery: defaultMetadataQuery,
398
511
  fetch: informationSubjectsGetAllServer
399
512
  });
400
513
  var getDocumentTypesCached = createTaxonomyResolver({
401
514
  cacheKey: "document-types",
515
+ cacheFamily: "documentTypes",
402
516
  tags: [import_requests2.CREX_READMODEL_CACHE_DOCUMENT_TYPES_TAG],
403
517
  defaultQuery: defaultMetadataQuery,
404
518
  fetch: documentTypesGetAllServer
405
519
  });
406
520
  var getComponentsCached = createTaxonomyResolver({
407
521
  cacheKey: "components",
522
+ cacheFamily: "components",
408
523
  tags: [import_requests2.CREX_READMODEL_CACHE_COMPONENTS_TAG],
409
524
  defaultQuery: {
410
525
  ...defaultMetadataQuery,
411
- Fields: ["labels", "class", "parents", "ancestors", "ancestorsOrSelf", "hasInformationUnits"]
526
+ Fields: ["labels", "class", "parents", "ancestors", "ancestorsOrSelf"]
412
527
  },
413
528
  fetch: componentsGetAllServer
414
529
  });
415
530
  var getTopicTypesCached = createTaxonomyResolver({
416
531
  cacheKey: "topic-types",
532
+ cacheFamily: "topicTypes",
417
533
  defaultQuery: defaultMetadataQuery,
418
534
  fetch: topicTypesGetAllServer
419
535
  });
420
536
  var getContentLifeCycleStatusCached = createTaxonomyResolver({
421
537
  cacheKey: "content-life-cycle-status",
538
+ cacheFamily: "contentLifeCycleStatus",
422
539
  defaultQuery: defaultMetadataQuery,
423
540
  fetch: contentLifeCycleStatusGetAllServer
424
541
  });
425
542
  var getApplicableForTypesCached = createTaxonomyResolver({
426
543
  cacheKey: "applicable-for-types",
544
+ cacheFamily: "documentTypes",
427
545
  defaultQuery: defaultMetadataQuery,
428
546
  fetch: informationTypesGetAllServer
429
547
  });
430
548
  var getPlanningTimesCached = createTaxonomyResolver({
431
549
  cacheKey: "planning-times",
550
+ cacheFamily: "planningTimes",
432
551
  defaultQuery: defaultMetadataQuery,
433
552
  fetch: planningTimesGetAllServer
434
553
  });
435
554
  var getFunctionalMetadataCached = createTaxonomyResolver({
436
555
  cacheKey: "functional-metadata",
556
+ cacheFamily: "functionalMetadata",
437
557
  defaultQuery: defaultMetadataQuery,
438
558
  fetch: functionalMetadatasGetAllServer
439
559
  });
440
560
  var getProductFeaturesCached = createTaxonomyResolver({
441
561
  cacheKey: "product-features",
562
+ cacheFamily: "productFeatures",
442
563
  defaultQuery: defaultMetadataQuery,
443
564
  fetch: productFeaturesGetAllServer
444
565
  });
445
566
  var getProductLifeCyclePhasesCached = createTaxonomyResolver({
446
567
  cacheKey: "product-life-cycle-phases",
568
+ cacheFamily: "productLifeCyclePhases",
447
569
  defaultQuery: defaultMetadataQuery,
448
570
  fetch: productLifeCyclePhasesGetAllServer
449
571
  });
450
572
  var getProductMetadataCached = createTaxonomyResolver({
451
573
  cacheKey: "product-metadata",
574
+ cacheFamily: "productMetadata",
452
575
  defaultQuery: defaultMetadataQuery,
453
576
  fetch: productMetadataGetAllServer
454
577
  });
455
578
  var getProductVariantsCached = createTaxonomyResolver({
456
579
  cacheKey: "product-variants",
580
+ cacheFamily: "productVariants",
457
581
  defaultQuery: defaultMetadataQuery,
458
582
  fetch: productVariantsGetAllServer
459
583
  });
460
584
  var getQualificationsCached = createTaxonomyResolver({
461
585
  cacheKey: "qualifications",
586
+ cacheFamily: "qualifications",
462
587
  defaultQuery: defaultMetadataQuery,
463
588
  fetch: qualificationsGetAllServer
464
589
  });
465
590
  var getSuppliesCached = createTaxonomyResolver({
466
591
  cacheKey: "supplies",
592
+ cacheFamily: "supplies",
467
593
  defaultQuery: defaultMetadataQuery,
468
594
  fetch: suppliesGetAllServer
469
595
  });
@@ -476,6 +602,18 @@ var toRoleRef = (party, uiLanguage) => {
476
602
  label: resolveLocalizedLabel(role?.labels || [], uiLanguage) || role?.shortId?.trim() || "Unknown role"
477
603
  };
478
604
  };
605
+ var mergeRoleRef = (current, candidate) => {
606
+ if (current.id !== candidate.id) {
607
+ return current;
608
+ }
609
+ const preferCurrentLabel = current.label.trim().length > 0 && current.label !== "Unknown role";
610
+ const preferCurrentShortId = Boolean(current.shortId?.trim());
611
+ return {
612
+ id: current.id,
613
+ shortId: preferCurrentShortId ? current.shortId : candidate.shortId,
614
+ label: preferCurrentLabel ? current.label : candidate.label
615
+ };
616
+ };
479
617
  var getPartiesCached = (0, import_cache.unstable_cache)(
480
618
  async (_queryKey, query, uiLanguage) => {
481
619
  const items = await withServerRequestContext(
@@ -487,15 +625,23 @@ var getPartiesCached = (0, import_cache.unstable_cache)(
487
625
  const id = party.id?.trim();
488
626
  if (!id) return;
489
627
  const role = toRoleRef(party, uiLanguage);
490
- if (!groups.has(role.id)) {
628
+ const existingGroup = groups.get(role.id);
629
+ if (!existingGroup) {
491
630
  groups.set(role.id, { role, parties: [] });
631
+ } else {
632
+ const mergedRole = mergeRoleRef(existingGroup.role, role);
633
+ existingGroup.role = mergedRole;
634
+ existingGroup.parties.forEach((groupedParty) => {
635
+ groupedParty.role = mergedRole;
636
+ });
492
637
  }
493
638
  const label = resolveLocalizedLabel(party.labels || [], uiLanguage) || party.shortId?.trim() || id;
639
+ const resolvedRole = groups.get(role.id)?.role || role;
494
640
  groups.get(role.id)?.parties.push({
495
641
  id,
496
642
  shortId: party.shortId?.trim() || void 0,
497
643
  label,
498
- role,
644
+ role: resolvedRole,
499
645
  vcardId: party.vcard?.id?.trim() || void 0
500
646
  });
501
647
  });
@@ -513,17 +659,19 @@ var getPartiesCached = (0, import_cache.unstable_cache)(
513
659
  tags: [import_requests2.CREX_API_CACHE_TAG, import_requests2.CREX_READMODEL_CACHE_TAG, import_requests2.CREX_READMODEL_CACHE_METADATA_TAG, import_requests2.CREX_READMODEL_CACHE_PARTIES_TAG]
514
660
  }
515
661
  );
516
- var getInformationSubjects = async (options) => {
517
- const readOptions = { includeOnlyUsed: options?.includeOnlyUsed === true };
662
+ var getInformationSubjects = async () => {
518
663
  try {
519
- const categories = await getCategoriesCached(void 0, readOptions);
664
+ const categories = await getCategoriesCached();
665
+ if (isMetadataPropertyRuntimeSuppressed("informationSubjects")) {
666
+ return categories;
667
+ }
520
668
  if (categories.roots.length > 0) {
521
669
  return categories;
522
670
  }
523
671
  } catch (error) {
524
672
  console.warn("[MetadataReadModels] Categories endpoint unavailable, falling back to InformationSubjects.", error);
525
673
  }
526
- return getInformationSubjectsLegacyCached(void 0, readOptions);
674
+ return getInformationSubjectsLegacyCached();
527
675
  };
528
676
  var getDocumentTypes = async () => {
529
677
  return getDocumentTypesCached();
@@ -537,8 +685,7 @@ var getParties = async () => {
537
685
  PageNumber: 1,
538
686
  PageSize: READMODEL_PAGE_SIZE,
539
687
  Fields: ["labels", "partyRole", "vcard", "class"],
540
- Sort: ["shortId"],
541
- Embed: ["vcard"]
688
+ Sort: ["shortId"]
542
689
  };
543
690
  return getPartiesCached(stableSerialize({ query, uiLanguage }), query, uiLanguage);
544
691
  };
@@ -737,8 +884,8 @@ var INFORMATION_UNIT_PROPERTY_PRESENTATION = {
737
884
  },
738
885
  applicableForTypes: {
739
886
  valueKind: "objectRefArray",
740
- facet: { supported: true, sectionStrategy: "class" },
741
- metadataDisplay: { supported: true, sectionStrategy: "class" }
887
+ facet: { supported: true, sectionStrategy: "none" },
888
+ metadataDisplay: { supported: true, sectionStrategy: "none" }
742
889
  },
743
890
  planningTimes: {
744
891
  valueKind: "objectRefArray",
@@ -795,23 +942,70 @@ var INFORMATION_UNIT_PROPERTY_PRESENTATION = {
795
942
  // src/read-models/metadata-presentation.ts
796
943
  var import_cache2 = require("next/cache");
797
944
  var import_requests3 = require("@c-rex/core/requests");
798
- var addTaxonomyNodeOverride = (node, map, sectionLabel) => {
799
- if (!node.shortId) return;
800
- map[node.shortId] = {
945
+ var UNKNOWN_SECTION_LABELS = {
946
+ en: {
947
+ components: "Unknown component",
948
+ informationSubjects: "Unknown information subject",
949
+ topicTypes: "Unknown topic type",
950
+ documentTypes: "Unknown document type",
951
+ contentLifeCycleStatus: "Unknown content life cycle status",
952
+ applicableForTypes: "Unknown document type",
953
+ planningTimes: "Unknown planning time",
954
+ functionalMetadata: "Unknown functional metadata",
955
+ productFeatures: "Unknown product feature",
956
+ productLifeCyclePhases: "Unknown product life cycle phase",
957
+ productMetadata: "Unknown product metadata",
958
+ productVariants: "Unknown product variant",
959
+ qualifications: "Unknown qualification",
960
+ supplies: "Unknown supply"
961
+ },
962
+ de: {
963
+ components: "Unbekannte Komponente",
964
+ informationSubjects: "Unbekanntes Informationsthema",
965
+ topicTypes: "Unbekannter Topictyp",
966
+ documentTypes: "Unbekannte Dokumentart",
967
+ contentLifeCycleStatus: "Unbekannter Inhaltslebenszyklusstatus",
968
+ applicableForTypes: "Unbekannte Dokumentart",
969
+ planningTimes: "Unbekannte Planungszeit",
970
+ functionalMetadata: "Unbekannte funktionale Metadaten",
971
+ productFeatures: "Unbekanntes Produktmerkmal",
972
+ productLifeCyclePhases: "Unbekannte Produktlebenszyklusphase",
973
+ productMetadata: "Unbekannte Produktmetadaten",
974
+ productVariants: "Unbekannte Produktvariante",
975
+ qualifications: "Unbekannte Qualifikation",
976
+ supplies: "Unbekannter Lieferumfang"
977
+ }
978
+ };
979
+ var resolveUnknownSectionLabel = (property, uiLanguage) => {
980
+ const normalizedLanguage = uiLanguage.toLowerCase();
981
+ const baseLanguage = normalizedLanguage.split("-")[0];
982
+ return UNKNOWN_SECTION_LABELS[baseLanguage]?.[property] || UNKNOWN_SECTION_LABELS.en[property] || "Unknown metadata";
983
+ };
984
+ var addTaxonomyNodePresentation = (node, map, sectionLabel, options) => {
985
+ const presentation = {
801
986
  label: node.label,
802
- sectionLabel
987
+ sectionLabel,
988
+ hidden: options?.hidden
803
989
  };
990
+ if (node.shortId) {
991
+ map[node.shortId] = presentation;
992
+ }
993
+ if (node.id) {
994
+ map[node.id] = presentation;
995
+ }
804
996
  };
805
- var createClassSectionOverrides = (nodes, options) => {
806
- const overrides = {};
997
+ var createClassSectionPresentation = (property, nodes, uiLanguage, options) => {
998
+ const presentation = {};
999
+ const unknownSectionLabel = resolveUnknownSectionLabel(property, uiLanguage);
807
1000
  Object.values(nodes).forEach((node) => {
808
1001
  const classId = node.classRef?.id?.trim();
809
- const sectionLabel = node.classRef?.label || (classId ? options?.classLabelsById?.[classId] : void 0);
810
- addTaxonomyNodeOverride(node, overrides, sectionLabel);
1002
+ const hidden = isMetadataGroupDenied(property, { classId });
1003
+ const sectionLabel = node.classRef?.label || (classId ? options?.classLabelsById?.[classId] : void 0) || unknownSectionLabel;
1004
+ addTaxonomyNodePresentation(node, presentation, sectionLabel, { hidden });
811
1005
  });
812
- return overrides;
1006
+ return presentation;
813
1007
  };
814
- var resolveMissingClassLabels = async (nodes, uiLanguage) => {
1008
+ var resolveMissingClassLabels2 = async (nodes, uiLanguage) => {
815
1009
  const classIds = Array.from(
816
1010
  new Set(
817
1011
  Object.values(nodes).map((node) => node.classRef?.id?.trim()).filter((value) => Boolean(value))
@@ -849,7 +1043,7 @@ var resolveLocalizedLabel2 = (labels, uiLanguage) => {
849
1043
  if (english) return english;
850
1044
  return normalized[0]?.value;
851
1045
  };
852
- var isNotFoundError = (error) => {
1046
+ var isNotFoundError2 = (error) => {
853
1047
  if (!(error instanceof Error)) {
854
1048
  return false;
855
1049
  }
@@ -866,7 +1060,7 @@ var getDomainEntitySectionLabelUncached = async (id, uiLanguage) => {
866
1060
  );
867
1061
  return resolveLocalizedLabel2(entity.labels || [], uiLanguage);
868
1062
  } catch (error) {
869
- if (isNotFoundError(error)) {
1063
+ if (isNotFoundError2(error)) {
870
1064
  return void 0;
871
1065
  }
872
1066
  throw error;
@@ -891,7 +1085,7 @@ var getDomainEntitySectionLabel = async (id, uiLanguage) => {
891
1085
  inFlightDomainEntityLabelRequests.set(inFlightKey, promise);
892
1086
  return promise;
893
1087
  };
894
- var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", options) => {
1088
+ var getMetadataFacetPresentation = async (properties, uiLanguage = "en-US", options) => {
895
1089
  const defaultProperties = Object.keys(INFORMATION_UNIT_PROPERTY_PRESENTATION).filter((property) => INFORMATION_UNIT_PROPERTY_PRESENTATION[property].facet.supported);
896
1090
  const propertySet = new Set(properties && properties.length > 0 ? properties : defaultProperties);
897
1091
  const result = {};
@@ -899,7 +1093,10 @@ var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", op
899
1093
  components: getComponents,
900
1094
  informationSubjects: getInformationSubjects,
901
1095
  documentTypes: getDocumentTypes,
902
- applicableForTypes: getApplicableForTypes,
1096
+ // API facets for `applicableForTypes` contain document type refs.
1097
+ // Resolve them through DocumentTypes so section labels come from the
1098
+ // referenced object class instead of the predicate label.
1099
+ applicableForTypes: getDocumentTypes,
903
1100
  planningTimes: getPlanningTimes,
904
1101
  functionalMetadata: getFunctionalMetadata,
905
1102
  contentLifeCycleStatus: getContentLifeCycleStatus,
@@ -917,43 +1114,56 @@ var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", op
917
1114
  const config = INFORMATION_UNIT_PROPERTY_PRESENTATION[property];
918
1115
  if (!config?.facet.supported) continue;
919
1116
  if (config.facet.sectionStrategy === "partyRole" && property === "parties") {
1117
+ if (isMetadataPropertyRuntimeSuppressed("parties")) {
1118
+ continue;
1119
+ }
920
1120
  partiesTask = (async () => {
921
1121
  const parties = await getParties();
922
- const partyOverrides = {};
1122
+ const partyPresentation = {};
923
1123
  parties.groups.forEach((group) => {
1124
+ const hidden = isMetadataGroupDenied("parties", { partyRoleId: group.role.id });
924
1125
  const sectionLabel = group.role.label;
925
1126
  group.parties.forEach((party) => {
926
1127
  if (!party.shortId) return;
927
- partyOverrides[party.shortId] = {
1128
+ partyPresentation[party.shortId] = {
928
1129
  label: party.label,
929
- sectionLabel
1130
+ sectionLabel,
1131
+ hidden
930
1132
  };
1133
+ if (party.id) {
1134
+ partyPresentation[party.id] = {
1135
+ label: party.label,
1136
+ sectionLabel,
1137
+ hidden
1138
+ };
1139
+ }
931
1140
  });
932
1141
  });
933
- result.parties = partyOverrides;
1142
+ result.parties = partyPresentation;
934
1143
  })();
935
1144
  continue;
936
1145
  }
937
1146
  if (config.facet.sectionStrategy === "class") {
1147
+ if (isMetadataPropertyRuntimeSuppressed(property)) {
1148
+ continue;
1149
+ }
938
1150
  const resolver = classResolvers[property];
939
1151
  if (!resolver) continue;
940
1152
  classTasks.push(
941
1153
  (async () => {
942
- const taxonomy = property === "informationSubjects" && options?.includeOnlyUsedByProperty?.informationSubjects === true ? await getInformationSubjects({ includeOnlyUsed: true }) : await resolver();
1154
+ const taxonomy = await resolver();
943
1155
  if (property === "topicTypes" || property === "contentLifeCycleStatus") {
944
1156
  const domainEntityId = property === "topicTypes" ? TOPIC_TYPE_DOMAIN_ENTITY_ID : CONTENT_LIFECYCLE_STATUS_DOMAIN_ENTITY_ID;
945
- const sectionLabel = await getDomainEntitySectionLabel(domainEntityId, uiLanguage);
946
- const overrides = createClassSectionOverrides(taxonomy.nodesById);
947
- if (sectionLabel) {
948
- Object.values(overrides).forEach((entry) => {
949
- entry.sectionLabel = sectionLabel;
950
- });
951
- }
952
- result[property] = overrides;
1157
+ const sectionLabel = await getDomainEntitySectionLabel(domainEntityId, uiLanguage) || resolveUnknownSectionLabel(property, uiLanguage);
1158
+ const presentation = createClassSectionPresentation(property, taxonomy.nodesById, uiLanguage);
1159
+ Object.values(presentation).forEach((entry) => {
1160
+ entry.sectionLabel = sectionLabel;
1161
+ });
1162
+ result[property] = presentation;
953
1163
  return;
954
1164
  }
955
- const classLabelsById = await resolveMissingClassLabels(taxonomy.nodesById, uiLanguage);
956
- result[property] = createClassSectionOverrides(taxonomy.nodesById, { classLabelsById });
1165
+ const classLabelsById = await resolveMissingClassLabels2(taxonomy.nodesById, uiLanguage);
1166
+ result[property] = createClassSectionPresentation(property, taxonomy.nodesById, uiLanguage, { classLabelsById });
957
1167
  })()
958
1168
  );
959
1169
  }
@@ -961,13 +1171,54 @@ var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", op
961
1171
  await Promise.all([...classTasks, ...partiesTask ? [partiesTask] : []]);
962
1172
  return result;
963
1173
  };
1174
+ var getMetadataFacetLabelOverrides = getMetadataFacetPresentation;
964
1175
 
965
- // src/read-models/metadata-display.ts
966
- var import_utils = require("@c-rex/utils");
1176
+ // src/read-models/metadata-display-builder.ts
1177
+ var DEFAULT_IGNORED_FORMATS = [
1178
+ "application/xhtml+xml",
1179
+ "application/json",
1180
+ "application/llm+xml",
1181
+ "text/html"
1182
+ ];
1183
+ var normalizeLanguageCode = (value) => {
1184
+ const trimmed = value.trim();
1185
+ if (!trimmed) return trimmed;
1186
+ const [rawLang, rawCountry, ...rest] = trimmed.split("-");
1187
+ const lang = (rawLang || "").toLowerCase();
1188
+ if (!rawCountry) return lang;
1189
+ const country = rawCountry.toUpperCase();
1190
+ const suffix = rest.length > 0 ? `-${rest.join("-")}` : "";
1191
+ return `${lang}-${country}${suffix}`;
1192
+ };
1193
+ var sortAndDeduplicateLanguages = (languages) => {
1194
+ const normalized = languages.map((item) => (item || "").trim()).filter((item) => item.length > 0).map((item) => normalizeLanguageCode(item));
1195
+ return Array.from(new Set(normalized)).sort((a, b) => a.localeCompare(b));
1196
+ };
1197
+ var resolvePreferredLanguage = (languages, uiLanguage) => {
1198
+ if (!languages || languages.length === 0) return void 0;
1199
+ const normalizedUiLanguage = normalizeLanguageCode(uiLanguage);
1200
+ const baseLanguage = normalizedUiLanguage.split("-")[0];
1201
+ const normalized = sortAndDeduplicateLanguages(languages);
1202
+ const exact = normalized.find((item) => item === normalizedUiLanguage);
1203
+ if (exact) return exact;
1204
+ const base = normalized.find((item) => item === baseLanguage || item.startsWith(`${baseLanguage}-`));
1205
+ if (base) return base;
1206
+ const english = normalized.find((item) => item === "en" || item === "en-US" || item.startsWith("en-"));
1207
+ if (english) return english;
1208
+ return normalized[0];
1209
+ };
1210
+ var getFirstLinkByRel = (item, rel) => item.links?.find((link) => link.rel === rel)?.href;
1211
+ var hasRenderableFileRenditions = (renditions) => {
1212
+ if (!renditions || renditions.length === 0) return false;
1213
+ return renditions.some((item) => {
1214
+ if (!item.format || DEFAULT_IGNORED_FORMATS.includes(item.format)) return false;
1215
+ return Boolean(getFirstLinkByRel(item, "download") || getFirstLinkByRel(item, "view"));
1216
+ });
1217
+ };
967
1218
  var resolveLiteralLabel = (labels, uiLanguage) => {
968
1219
  if (!labels || labels.length === 0) return void 0;
969
1220
  const language = uiLanguage || "en";
970
- const preferred = (0, import_utils.resolvePreferredLanguage)(
1221
+ const preferred = resolvePreferredLanguage(
971
1222
  labels.map((item) => item.language || ""),
972
1223
  language
973
1224
  );
@@ -980,6 +1231,9 @@ var resolveLiteralLabel = (labels, uiLanguage) => {
980
1231
  var resolveObjectRefLabel = (item, uiLanguage) => {
981
1232
  return resolveLiteralLabel(item.labels || [], uiLanguage) || item.shortId || item.id || void 0;
982
1233
  };
1234
+ var resolveObjectRefClassLabel = (item, uiLanguage) => {
1235
+ return resolveLiteralLabel(item.class?.labels || [], uiLanguage) || item.class?.shortId || item.class?.id || void 0;
1236
+ };
983
1237
  var asObjectRefArray = (value) => {
984
1238
  if (!Array.isArray(value)) return [];
985
1239
  return value.filter((item) => Boolean(item && typeof item === "object"));
@@ -988,29 +1242,27 @@ var asLiteralArray = (value) => {
988
1242
  if (!Array.isArray(value)) return [];
989
1243
  return value.filter((item) => Boolean(item && typeof item === "object"));
990
1244
  };
991
- var shouldUseOverrides = (strategy) => {
1245
+ var shouldUseFacetPresentation = (strategy) => {
992
1246
  return strategy === "class" || strategy === "partyRole";
993
1247
  };
994
- var getMetadataDisplayRows = async (data, options) => {
995
- const includeProperties = options.includeProperties || Object.keys(INFORMATION_UNIT_PROPERTY_PRESENTATION);
996
- const uiLanguage = options.uiLanguage;
997
- const preferredTitle = resolveLiteralLabel(data.titles || [], uiLanguage) || resolveLiteralLabel(data.labels || [], uiLanguage);
998
- const objectRefProperties = includeProperties.filter((key) => {
1248
+ var resolveFacetPresentationProperties = (includeProperties) => {
1249
+ return includeProperties.filter((key) => {
999
1250
  const config = INFORMATION_UNIT_PROPERTY_PRESENTATION[key];
1000
1251
  if (!config?.metadataDisplay?.supported) return false;
1001
- return config.valueKind === "objectRefArray" || config.valueKind === "objectRef";
1252
+ if (config.valueKind !== "objectRefArray" && config.valueKind !== "objectRef") return false;
1253
+ return shouldUseFacetPresentation(config.metadataDisplay.sectionStrategy);
1002
1254
  });
1003
- const overrideProperties = objectRefProperties.filter(
1004
- (key) => shouldUseOverrides(INFORMATION_UNIT_PROPERTY_PRESENTATION[key].metadataDisplay.sectionStrategy)
1005
- );
1006
- const labelOverrides = options.overrides || (overrideProperties.length > 0 ? await getMetadataFacetLabelOverrides(overrideProperties, uiLanguage) : {});
1255
+ };
1256
+ var resolveOverrideProperties = resolveFacetPresentationProperties;
1257
+ var buildMetadataDisplayRows = (data, options) => {
1258
+ const uiLanguage = options.uiLanguage;
1259
+ const preferredTitle = resolveLiteralLabel(data.titles || [], uiLanguage) || resolveLiteralLabel(data.labels || [], uiLanguage);
1007
1260
  const rows = [];
1008
- for (const key of includeProperties) {
1261
+ for (const key of options.includeProperties) {
1009
1262
  const config = INFORMATION_UNIT_PROPERTY_PRESENTATION[key];
1010
1263
  if (!config?.metadataDisplay?.supported) continue;
1011
- if (key === "labels") {
1012
- continue;
1013
- }
1264
+ if (isMetadataPropertyRuntimeSuppressed(key)) continue;
1265
+ if (key === "labels") continue;
1014
1266
  if (key === "titles") {
1015
1267
  if (preferredTitle) {
1016
1268
  rows.push({
@@ -1026,7 +1278,7 @@ var getMetadataDisplayRows = async (data, options) => {
1026
1278
  const value = data[key];
1027
1279
  if (value === null || value === void 0) continue;
1028
1280
  if (key === "languages") {
1029
- const languages = (0, import_utils.sortAndDeduplicateLanguages)(value || []);
1281
+ const languages = sortAndDeduplicateLanguages(value || []);
1030
1282
  if (languages.length > 0) {
1031
1283
  rows.push({
1032
1284
  key,
@@ -1049,7 +1301,7 @@ var getMetadataDisplayRows = async (data, options) => {
1049
1301
  continue;
1050
1302
  }
1051
1303
  if (config.valueKind === "stringArray") {
1052
- const values = Array.from(new Set(value.map((item) => String(item)).filter((item) => item.length > 0)));
1304
+ const values = Array.from(new Set(value.map((item) => String(item)).filter(Boolean)));
1053
1305
  if (values.length > 0) {
1054
1306
  rows.push({
1055
1307
  key,
@@ -1062,8 +1314,7 @@ var getMetadataDisplayRows = async (data, options) => {
1062
1314
  continue;
1063
1315
  }
1064
1316
  if (config.valueKind === "literalArray") {
1065
- const literals = asLiteralArray(value);
1066
- const preferred = resolveLiteralLabel(literals, uiLanguage);
1317
+ const preferred = resolveLiteralLabel(asLiteralArray(value), uiLanguage);
1067
1318
  if (preferred) {
1068
1319
  rows.push({
1069
1320
  key,
@@ -1076,8 +1327,7 @@ var getMetadataDisplayRows = async (data, options) => {
1076
1327
  continue;
1077
1328
  }
1078
1329
  if (config.valueKind === "objectRef") {
1079
- const ref = value;
1080
- const label = resolveObjectRefLabel(ref, uiLanguage);
1330
+ const label = resolveObjectRefLabel(value, uiLanguage);
1081
1331
  if (label) {
1082
1332
  rows.push({
1083
1333
  key,
@@ -1092,26 +1342,28 @@ var getMetadataDisplayRows = async (data, options) => {
1092
1342
  if (config.valueKind === "objectRefArray") {
1093
1343
  const refs = asObjectRefArray(value);
1094
1344
  if (refs.length === 0) continue;
1095
- const grouped = /* @__PURE__ */ new Map();
1096
- const strategy = config.metadataDisplay.sectionStrategy;
1345
+ const groupedValues = /* @__PURE__ */ new Map();
1097
1346
  refs.forEach((ref) => {
1098
1347
  const shortId = ref.shortId || "";
1099
- const override = shortId ? labelOverrides[key]?.[shortId] : void 0;
1100
- const label = override?.label || resolveObjectRefLabel(ref, uiLanguage);
1101
- if (!label) return;
1102
- const section = strategy === "none" ? key : override?.sectionLabel || key;
1103
- if (!grouped.has(section)) grouped.set(section, []);
1104
- grouped.get(section)?.push(label);
1348
+ const presentationMap = (options.presentation || options.overrides)?.[key];
1349
+ const presentationItem = (shortId ? presentationMap?.[shortId] : void 0) || (ref.id ? presentationMap?.[ref.id] : void 0);
1350
+ if (presentationItem?.hidden) return;
1351
+ if (isMetadataGroupDenied(key, { classId: ref.class?.id })) return;
1352
+ const valueLabel = presentationItem?.label || resolveObjectRefLabel(ref, uiLanguage);
1353
+ if (!valueLabel) return;
1354
+ const sectionLabel = config.metadataDisplay.sectionStrategy === "none" ? key : presentationItem?.sectionLabel || resolveObjectRefClassLabel(ref, uiLanguage) || key;
1355
+ const existing = groupedValues.get(sectionLabel) || /* @__PURE__ */ new Set();
1356
+ existing.add(valueLabel);
1357
+ groupedValues.set(sectionLabel, existing);
1105
1358
  });
1106
- Array.from(grouped.entries()).sort((a, b) => a[0].localeCompare(b[0])).forEach(([section, values]) => {
1107
- const uniqueValues = Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));
1108
- if (uniqueValues.length === 0) return;
1109
- const isDirect = section !== key;
1359
+ Array.from(groupedValues.entries()).sort(([left], [right]) => left.localeCompare(right)).forEach(([sectionLabel, valueSet]) => {
1360
+ const values = Array.from(valueSet).sort((a, b) => a.localeCompare(b));
1361
+ if (values.length === 0) return;
1110
1362
  rows.push({
1111
1363
  key,
1112
- label: section,
1113
- labelSource: isDirect ? "direct" : "translationKey",
1114
- values: uniqueValues,
1364
+ label: sectionLabel,
1365
+ labelSource: sectionLabel === key ? "translationKey" : "direct",
1366
+ values,
1115
1367
  valueType: "text"
1116
1368
  });
1117
1369
  });
@@ -1120,7 +1372,7 @@ var getMetadataDisplayRows = async (data, options) => {
1120
1372
  if (config.valueKind === "renditionArray") {
1121
1373
  const renditions = Array.isArray(value) ? value.filter((item) => Boolean(item && typeof item === "object")) : [];
1122
1374
  if (renditions.length === 0) continue;
1123
- if ((0, import_utils.getFileRenditionGroups)({ renditions }).length === 0) continue;
1375
+ if (!hasRenderableFileRenditions(renditions)) continue;
1124
1376
  rows.push({
1125
1377
  key,
1126
1378
  label: "files",
@@ -1134,9 +1386,21 @@ var getMetadataDisplayRows = async (data, options) => {
1134
1386
  return rows;
1135
1387
  };
1136
1388
 
1389
+ // src/read-models/metadata-display.ts
1390
+ var getMetadataDisplayRows = async (data, options) => {
1391
+ const includeProperties = options.includeProperties || Object.keys(INFORMATION_UNIT_PROPERTY_PRESENTATION);
1392
+ const presentationProperties = resolveFacetPresentationProperties(includeProperties);
1393
+ const facetPresentation = options.presentation || options.overrides || (presentationProperties.length > 0 ? await getMetadataFacetPresentation(presentationProperties, options.uiLanguage) : {});
1394
+ return buildMetadataDisplayRows(data, {
1395
+ uiLanguage: options.uiLanguage,
1396
+ includeProperties,
1397
+ presentation: facetPresentation
1398
+ });
1399
+ };
1400
+
1137
1401
  // src/read-models/version-availability.ts
1138
1402
  var import_requests4 = require("@c-rex/core/requests");
1139
- var import_utils2 = require("@c-rex/utils");
1403
+ var import_utils = require("@c-rex/utils");
1140
1404
  var import_cache3 = require("next/cache");
1141
1405
  var stableSerialize2 = (value) => {
1142
1406
  const normalize = (input) => {
@@ -1157,7 +1421,7 @@ var normalizeVersionItems = (items, uiLanguage) => {
1157
1421
  items.forEach((item) => {
1158
1422
  const shortId = item.shortId?.trim();
1159
1423
  if (!shortId) return;
1160
- const language = (0, import_utils2.resolvePreferredLanguage)(item.languages, uiLanguage);
1424
+ const language = (0, import_utils.resolvePreferredLanguage)(item.languages, uiLanguage);
1161
1425
  if (!language) return;
1162
1426
  uniqueByShortId.set(shortId, {
1163
1427
  shortId,
@@ -1267,7 +1531,9 @@ var resolveFacetTags = (options) => {
1267
1531
  toInformationUnitPropertyKeys(options?.includeProperties),
1268
1532
  toInformationUnitPropertyKeys(options?.excludeProperties)
1269
1533
  );
1270
- const tagSet = new Set(runtimeScoped);
1534
+ const tagSet = new Set(
1535
+ runtimeScoped.filter((property) => !isMetadataPropertyRuntimeSuppressed(property))
1536
+ );
1271
1537
  (facetConfig?.extraTags || []).forEach((tag) => tagSet.add(tag));
1272
1538
  (options?.extraTags || []).forEach((tag) => tagSet.add(tag));
1273
1539
  return Array.from(tagSet);
@@ -1285,13 +1551,16 @@ var resolveMetadataDisplayProperties = (options) => {
1285
1551
  profileScoped,
1286
1552
  toInformationUnitPropertyKeys(options?.includeProperties),
1287
1553
  toInformationUnitPropertyKeys(options?.excludeProperties)
1288
- );
1554
+ ).filter((property) => !isMetadataPropertyRuntimeSuppressed(property));
1289
1555
  };
1290
1556
  // Annotate the CommonJS export names for ESM import in node:
1291
1557
  0 && (module.exports = {
1292
1558
  INFORMATION_UNIT_PROPERTY_PRESENTATION,
1293
1559
  METADATA_VIEW_PROFILES,
1560
+ METADATA_VISIBILITY_POLICY,
1294
1561
  READMODEL_CACHE_POLICY,
1562
+ buildMetadataDisplayRows,
1563
+ clearMetadataCacheFamilyRuntimeSuppression,
1295
1564
  getApplicableForTypes,
1296
1565
  getAvailableLanguagesByVersionOf,
1297
1566
  getComponents,
@@ -1299,8 +1568,10 @@ var resolveMetadataDisplayProperties = (options) => {
1299
1568
  getDocumentTypes,
1300
1569
  getFunctionalMetadata,
1301
1570
  getInformationSubjects,
1571
+ getMetadataCacheFamily,
1302
1572
  getMetadataDisplayRows,
1303
1573
  getMetadataFacetLabelOverrides,
1574
+ getMetadataFacetPresentation,
1304
1575
  getMetadataPropertyResolvers,
1305
1576
  getParties,
1306
1577
  getPlanningTimes,
@@ -1309,9 +1580,19 @@ var resolveMetadataDisplayProperties = (options) => {
1309
1580
  getProductMetadata,
1310
1581
  getProductVariants,
1311
1582
  getQualifications,
1583
+ getRuntimeSuppressedMetadataFamilies,
1312
1584
  getSupplies,
1313
1585
  getTopicTypes,
1586
+ isMetadataGroupDenied,
1587
+ isMetadataPropertyRuntimeSuppressed,
1588
+ resetRuntimeSuppressedMetadataFamiliesForTests,
1589
+ resolveFacetPresentationProperties,
1314
1590
  resolveFacetTags,
1315
- resolveMetadataDisplayProperties
1591
+ resolveLiteralLabel,
1592
+ resolveMetadataDisplayProperties,
1593
+ resolveObjectRefClassLabel,
1594
+ resolveObjectRefLabel,
1595
+ resolveOverrideProperties,
1596
+ suppressMetadataCacheFamilyRuntime
1316
1597
  });
1317
1598
  //# sourceMappingURL=index.js.map