@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
@@ -8,6 +8,7 @@ import {
8
8
  CREX_READMODEL_CACHE_PARTIES_TAG,
9
9
  CREX_READMODEL_CACHE_TAG
10
10
  } from "@c-rex/core/requests";
11
+ import { CrexLogger } from "@c-rex/core/logger";
11
12
  import { unstable_cache } from "next/cache";
12
13
 
13
14
  // src/base-server-request.ts
@@ -131,7 +132,106 @@ var READMODEL_CACHE_POLICY = {
131
132
  )
132
133
  };
133
134
 
135
+ // src/read-models/metadata-visibility-policy.ts
136
+ var CONTENT_LICENSE_CLASS_ID = "https://ids.c-crex.net/ns/iirds/ext#ContentLicense";
137
+ var METADATA_VISIBILITY_POLICY = {
138
+ parties: {
139
+ cacheFamily: "parties"
140
+ },
141
+ components: {
142
+ cacheFamily: "components"
143
+ },
144
+ informationSubjects: {
145
+ cacheFamily: "informationSubjects"
146
+ },
147
+ topicTypes: {
148
+ cacheFamily: "topicTypes"
149
+ },
150
+ documentTypes: {
151
+ cacheFamily: "documentTypes"
152
+ },
153
+ contentLifeCycleStatus: {
154
+ cacheFamily: "contentLifeCycleStatus"
155
+ },
156
+ applicableForTypes: {
157
+ cacheFamily: "documentTypes"
158
+ },
159
+ planningTimes: {
160
+ cacheFamily: "planningTimes"
161
+ },
162
+ functionalMetadata: {
163
+ cacheFamily: "functionalMetadata"
164
+ },
165
+ productFeatures: {
166
+ cacheFamily: "productFeatures"
167
+ },
168
+ productLifeCyclePhases: {
169
+ cacheFamily: "productLifeCyclePhases"
170
+ },
171
+ productMetadata: {
172
+ cacheFamily: "productMetadata"
173
+ },
174
+ productVariants: {
175
+ cacheFamily: "productVariants"
176
+ },
177
+ qualifications: {
178
+ cacheFamily: "qualifications",
179
+ deniedClassIds: [CONTENT_LICENSE_CLASS_ID]
180
+ },
181
+ supplies: {
182
+ cacheFamily: "supplies"
183
+ }
184
+ };
185
+ var runtimeSuppressedFamilies = /* @__PURE__ */ new Map();
186
+ var getMetadataCacheFamily = (property) => METADATA_VISIBILITY_POLICY[property]?.cacheFamily;
187
+ var isMetadataGroupDenied = (property, options) => {
188
+ const policy = METADATA_VISIBILITY_POLICY[property];
189
+ const classId = options.classId?.trim();
190
+ const partyRoleId = options.partyRoleId?.trim();
191
+ if (classId && policy?.deniedClassIds?.includes(classId)) {
192
+ return true;
193
+ }
194
+ if (partyRoleId && policy?.deniedPartyRoleIds?.includes(partyRoleId)) {
195
+ return true;
196
+ }
197
+ return false;
198
+ };
199
+ var suppressMetadataCacheFamilyRuntime = (family, entry) => {
200
+ runtimeSuppressedFamilies.set(family, {
201
+ family,
202
+ reason: "cache-overflow",
203
+ bytes: entry.bytes,
204
+ limitBytes: entry.limitBytes,
205
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
206
+ });
207
+ };
208
+ var clearMetadataCacheFamilyRuntimeSuppression = (family) => {
209
+ runtimeSuppressedFamilies.delete(family);
210
+ };
211
+ var isMetadataPropertyRuntimeSuppressed = (property) => {
212
+ const family = getMetadataCacheFamily(property);
213
+ return family ? runtimeSuppressedFamilies.has(family) : false;
214
+ };
215
+ var getRuntimeSuppressedMetadataFamilies = () => Array.from(runtimeSuppressedFamilies.values());
216
+ var resetRuntimeSuppressedMetadataFamiliesForTests = () => {
217
+ runtimeSuppressedFamilies.clear();
218
+ };
219
+
134
220
  // src/read-models/metadata-read-models.ts
221
+ var DEFAULT_METADATA_CACHE_MAX_BYTES = 15e5;
222
+ var resolveMetadataCacheMaxBytes = () => {
223
+ const value = Number(process.env.CREX_CACHE_METADATA_MAX_BYTES);
224
+ return Number.isFinite(value) && value > 0 ? value : DEFAULT_METADATA_CACHE_MAX_BYTES;
225
+ };
226
+ var measureSerializedBytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
227
+ var logCacheOverflow = async (family, bytes, limitBytes, cacheKey) => {
228
+ const logger = new CrexLogger();
229
+ await logger.log({
230
+ level: "warning",
231
+ category: "Scenario",
232
+ message: `[MetadataCacheOverflow] family=${family} bytes=${bytes} limitBytes=${limitBytes} cacheKey=${cacheKey}`
233
+ });
234
+ };
135
235
  var resolveLocalizedLabel = (labels, uiLanguage) => {
136
236
  if (!labels || labels.length === 0) return void 0;
137
237
  const normalizedUiLanguage = uiLanguage.trim().toLowerCase();
@@ -190,12 +290,39 @@ var toEntityRef = (entity, uiLanguage) => {
190
290
  const label = resolveLocalizedLabel(entity.labels || [], uiLanguage) || entity.shortId?.trim() || id;
191
291
  return { id, shortId: entity.shortId?.trim() || void 0, label };
192
292
  };
193
- var toClassRef = (classRef, uiLanguage) => {
293
+ var toClassRef = (classRef, uiLanguage, classLabelsById) => {
194
294
  const id = classRef?.id?.trim();
195
295
  if (!id) return void 0;
196
- const label = resolveLocalizedLabel(classRef?.labels || [], uiLanguage) || classRef?.shortId?.trim() || id;
296
+ const label = resolveLocalizedLabel(classRef?.labels || [], uiLanguage) || classLabelsById?.[id] || classRef?.shortId?.trim() || id;
197
297
  return { id, shortId: classRef?.shortId?.trim() || void 0, label };
198
298
  };
299
+ var isNotFoundError = (error) => {
300
+ if (!(error instanceof Error)) {
301
+ return false;
302
+ }
303
+ return error.message.includes("HTTP error! status: 404");
304
+ };
305
+ var resolveMissingClassLabels = async (items, uiLanguage) => {
306
+ const classIds = Array.from(new Set(
307
+ 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))
308
+ ));
309
+ const result = {};
310
+ await Promise.all(classIds.map(async (classId) => {
311
+ try {
312
+ const entity = await withServerRequestContext(
313
+ { skipCookieTokenLookup: true },
314
+ () => domainEntitiesGetByIdServer({ id: classId }, { Fields: ["labels"] })
315
+ );
316
+ result[classId] = resolveLocalizedLabel(entity.labels || [], uiLanguage);
317
+ } catch (error) {
318
+ if (!isNotFoundError(error)) {
319
+ throw error;
320
+ }
321
+ result[classId] = void 0;
322
+ }
323
+ }));
324
+ return result;
325
+ };
199
326
  var deriveParentIds = (entity) => {
200
327
  const directParents = (entity.parents || []).map((parent) => getRefId(parent)).filter((value) => Boolean(value));
201
328
  if (directParents.length > 0) {
@@ -204,10 +331,6 @@ var deriveParentIds = (entity) => {
204
331
  const ancestorParents = (entity.ancestors || []).map((path) => path[path.length - 1]).map((parent) => getRefId(parent)).filter((value) => Boolean(value));
205
332
  return Array.from(new Set(ancestorParents));
206
333
  };
207
- var deriveAncestorIds = (entity) => {
208
- const ids = (entity.ancestors || []).flatMap((path) => path).map((item) => getRefId(item)).filter((value) => Boolean(value));
209
- return Array.from(new Set(ids));
210
- };
211
334
  var buildTaxonomyTree = (items, options) => {
212
335
  const nodesById = {};
213
336
  const parentLinks = /* @__PURE__ */ new Map();
@@ -216,48 +339,13 @@ var buildTaxonomyTree = (items, options) => {
216
339
  if (!entityRef) continue;
217
340
  nodesById[entityRef.id] = {
218
341
  ...entityRef,
219
- classRef: toClassRef(item.class, options.uiLanguage),
220
- hasInformationUnits: item.hasInformationUnits === true || item.hasInformationUnitReferences === true,
221
- parentIds: deriveParentIds(item),
222
- ancestorIds: deriveAncestorIds(item),
223
- children: []
342
+ classRef: toClassRef(item.class, options.uiLanguage, options.classLabelsById),
343
+ parentIds: deriveParentIds(item)
224
344
  };
225
345
  }
226
346
  Object.values(nodesById).forEach((node) => {
227
347
  parentLinks.set(node.id, node.parentIds.filter((id) => Boolean(nodesById[id])));
228
348
  });
229
- if (options.includeOnlyUsed) {
230
- const keepIds = new Set(
231
- Object.values(nodesById).filter((node) => node.hasInformationUnits === true).map((node) => node.id)
232
- );
233
- let changed = true;
234
- while (changed) {
235
- changed = false;
236
- Array.from(keepIds).forEach((nodeId) => {
237
- const parentIds = parentLinks.get(nodeId) || [];
238
- parentIds.forEach((parentId) => {
239
- if (!keepIds.has(parentId)) {
240
- keepIds.add(parentId);
241
- changed = true;
242
- }
243
- });
244
- });
245
- }
246
- Object.keys(nodesById).forEach((nodeId) => {
247
- if (!keepIds.has(nodeId)) {
248
- delete nodesById[nodeId];
249
- parentLinks.delete(nodeId);
250
- }
251
- });
252
- }
253
- Object.values(nodesById).forEach((node) => {
254
- const parents = parentLinks.get(node.id) || [];
255
- parents.forEach((parentId) => {
256
- if (nodesById[parentId]) {
257
- nodesById[parentId].children.push(node);
258
- }
259
- });
260
- });
261
349
  const roots = Object.values(nodesById).filter((node) => (parentLinks.get(node.id) || []).length === 0);
262
350
  if (!options.groupRootsByClass) {
263
351
  return {
@@ -267,13 +355,12 @@ var buildTaxonomyTree = (items, options) => {
267
355
  };
268
356
  }
269
357
  const groupedRoots = /* @__PURE__ */ new Map();
358
+ const groupedRootCounts = /* @__PURE__ */ new Map();
270
359
  const ungroupedRootId = "class:ungrouped";
271
360
  groupedRoots.set(ungroupedRootId, {
272
361
  id: ungroupedRootId,
273
362
  label: "Ungrouped",
274
363
  parentIds: [],
275
- ancestorIds: [],
276
- children: [],
277
364
  isVirtualGroup: true
278
365
  });
279
366
  roots.forEach((root) => {
@@ -284,17 +371,12 @@ var buildTaxonomyTree = (items, options) => {
284
371
  shortId: root.classRef?.shortId,
285
372
  label: root.classRef?.label || "Ungrouped",
286
373
  parentIds: [],
287
- ancestorIds: [],
288
- children: [],
289
374
  isVirtualGroup: true
290
375
  });
291
376
  }
292
- groupedRoots.get(classId)?.children.push(root);
377
+ groupedRootCounts.set(classId, (groupedRootCounts.get(classId) || 0) + 1);
293
378
  });
294
- const groupedRootNodes = Array.from(groupedRoots.values()).filter((group) => group.children.length > 0).map((group) => ({
295
- ...group,
296
- children: [...group.children].sort((a, b) => a.label.localeCompare(b.label))
297
- })).sort((a, b) => a.label.localeCompare(b.label));
379
+ const groupedRootNodes = Array.from(groupedRoots.values()).filter((group) => (groupedRootCounts.get(group.id) || 0) > 0).sort((a, b) => a.label.localeCompare(b.label));
298
380
  return {
299
381
  roots: groupedRootNodes,
300
382
  nodesById,
@@ -307,15 +389,29 @@ var defaultTreeOptions = (uiLanguage) => ({
307
389
  });
308
390
  var createTaxonomyResolver = (options) => {
309
391
  const cached = unstable_cache(
310
- async (_queryKey, query, uiLanguage, readOptions) => {
392
+ async (_queryKey, query, uiLanguage) => {
311
393
  const items = await withServerRequestContext(
312
394
  { skipCookieTokenLookup: true },
313
395
  () => fetchAllPages(options.fetch, query)
314
396
  );
315
- return buildTaxonomyTree(items, {
397
+ const classLabelsById = await resolveMissingClassLabels(items, uiLanguage);
398
+ const result = buildTaxonomyTree(items, {
316
399
  ...defaultTreeOptions(uiLanguage),
317
- includeOnlyUsed: readOptions.includeOnlyUsed
400
+ classLabelsById
318
401
  });
402
+ const bytes = measureSerializedBytes(result);
403
+ const limitBytes = resolveMetadataCacheMaxBytes();
404
+ if (bytes > limitBytes) {
405
+ suppressMetadataCacheFamilyRuntime(options.cacheFamily, { bytes, limitBytes });
406
+ await logCacheOverflow(options.cacheFamily, bytes, limitBytes, options.cacheKey);
407
+ return {
408
+ roots: [],
409
+ nodesById: {},
410
+ generatedAt: result.generatedAt
411
+ };
412
+ }
413
+ clearMetadataCacheFamilyRuntimeSuppression(options.cacheFamily);
414
+ return result;
319
415
  },
320
416
  ["read-model", options.cacheKey],
321
417
  {
@@ -328,101 +424,116 @@ var createTaxonomyResolver = (options) => {
328
424
  ]
329
425
  }
330
426
  );
331
- return async (query, readOptions) => {
427
+ return async (query) => {
332
428
  const uiLanguage = resolveUiLanguage();
333
429
  const normalizedQuery = { ...options.defaultQuery, ...query || {} };
334
- const normalizedReadOptions = {
335
- includeOnlyUsed: readOptions?.includeOnlyUsed === true
336
- };
337
- const cacheKey = stableSerialize({ normalizedQuery, uiLanguage, normalizedReadOptions });
338
- return cached(cacheKey, normalizedQuery, uiLanguage, normalizedReadOptions);
430
+ const cacheKey = stableSerialize({ normalizedQuery, uiLanguage });
431
+ return cached(cacheKey, normalizedQuery, uiLanguage);
339
432
  };
340
433
  };
341
434
  var defaultMetadataQuery = {
342
435
  PageNumber: 1,
343
436
  PageSize: READMODEL_PAGE_SIZE,
344
- Fields: ["labels", "class", "hasInformationUnits"],
437
+ Fields: ["labels", "class"],
345
438
  Sort: ["shortId"]
346
439
  };
347
440
  var getCategoriesCached = createTaxonomyResolver({
348
441
  cacheKey: "categories",
442
+ cacheFamily: "informationSubjects",
349
443
  tags: [CREX_READMODEL_CACHE_INFORMATION_SUBJECTS_TAG],
350
- defaultQuery: defaultMetadataQuery,
444
+ defaultQuery: {
445
+ ...defaultMetadataQuery,
446
+ Fields: ["labels", "class", "parents", "ancestors", "ancestorsOrSelf"]
447
+ },
351
448
  fetch: categoriesGetAllServer
352
449
  });
353
450
  var getInformationSubjectsLegacyCached = createTaxonomyResolver({
354
451
  cacheKey: "information-subjects-legacy",
452
+ cacheFamily: "informationSubjects",
355
453
  tags: [CREX_READMODEL_CACHE_INFORMATION_SUBJECTS_TAG],
356
454
  defaultQuery: defaultMetadataQuery,
357
455
  fetch: informationSubjectsGetAllServer
358
456
  });
359
457
  var getDocumentTypesCached = createTaxonomyResolver({
360
458
  cacheKey: "document-types",
459
+ cacheFamily: "documentTypes",
361
460
  tags: [CREX_READMODEL_CACHE_DOCUMENT_TYPES_TAG],
362
461
  defaultQuery: defaultMetadataQuery,
363
462
  fetch: documentTypesGetAllServer
364
463
  });
365
464
  var getComponentsCached = createTaxonomyResolver({
366
465
  cacheKey: "components",
466
+ cacheFamily: "components",
367
467
  tags: [CREX_READMODEL_CACHE_COMPONENTS_TAG],
368
468
  defaultQuery: {
369
469
  ...defaultMetadataQuery,
370
- Fields: ["labels", "class", "parents", "ancestors", "ancestorsOrSelf", "hasInformationUnits"]
470
+ Fields: ["labels", "class", "parents", "ancestors", "ancestorsOrSelf"]
371
471
  },
372
472
  fetch: componentsGetAllServer
373
473
  });
374
474
  var getTopicTypesCached = createTaxonomyResolver({
375
475
  cacheKey: "topic-types",
476
+ cacheFamily: "topicTypes",
376
477
  defaultQuery: defaultMetadataQuery,
377
478
  fetch: topicTypesGetAllServer
378
479
  });
379
480
  var getContentLifeCycleStatusCached = createTaxonomyResolver({
380
481
  cacheKey: "content-life-cycle-status",
482
+ cacheFamily: "contentLifeCycleStatus",
381
483
  defaultQuery: defaultMetadataQuery,
382
484
  fetch: contentLifeCycleStatusGetAllServer
383
485
  });
384
486
  var getApplicableForTypesCached = createTaxonomyResolver({
385
487
  cacheKey: "applicable-for-types",
488
+ cacheFamily: "documentTypes",
386
489
  defaultQuery: defaultMetadataQuery,
387
490
  fetch: informationTypesGetAllServer
388
491
  });
389
492
  var getPlanningTimesCached = createTaxonomyResolver({
390
493
  cacheKey: "planning-times",
494
+ cacheFamily: "planningTimes",
391
495
  defaultQuery: defaultMetadataQuery,
392
496
  fetch: planningTimesGetAllServer
393
497
  });
394
498
  var getFunctionalMetadataCached = createTaxonomyResolver({
395
499
  cacheKey: "functional-metadata",
500
+ cacheFamily: "functionalMetadata",
396
501
  defaultQuery: defaultMetadataQuery,
397
502
  fetch: functionalMetadatasGetAllServer
398
503
  });
399
504
  var getProductFeaturesCached = createTaxonomyResolver({
400
505
  cacheKey: "product-features",
506
+ cacheFamily: "productFeatures",
401
507
  defaultQuery: defaultMetadataQuery,
402
508
  fetch: productFeaturesGetAllServer
403
509
  });
404
510
  var getProductLifeCyclePhasesCached = createTaxonomyResolver({
405
511
  cacheKey: "product-life-cycle-phases",
512
+ cacheFamily: "productLifeCyclePhases",
406
513
  defaultQuery: defaultMetadataQuery,
407
514
  fetch: productLifeCyclePhasesGetAllServer
408
515
  });
409
516
  var getProductMetadataCached = createTaxonomyResolver({
410
517
  cacheKey: "product-metadata",
518
+ cacheFamily: "productMetadata",
411
519
  defaultQuery: defaultMetadataQuery,
412
520
  fetch: productMetadataGetAllServer
413
521
  });
414
522
  var getProductVariantsCached = createTaxonomyResolver({
415
523
  cacheKey: "product-variants",
524
+ cacheFamily: "productVariants",
416
525
  defaultQuery: defaultMetadataQuery,
417
526
  fetch: productVariantsGetAllServer
418
527
  });
419
528
  var getQualificationsCached = createTaxonomyResolver({
420
529
  cacheKey: "qualifications",
530
+ cacheFamily: "qualifications",
421
531
  defaultQuery: defaultMetadataQuery,
422
532
  fetch: qualificationsGetAllServer
423
533
  });
424
534
  var getSuppliesCached = createTaxonomyResolver({
425
535
  cacheKey: "supplies",
536
+ cacheFamily: "supplies",
426
537
  defaultQuery: defaultMetadataQuery,
427
538
  fetch: suppliesGetAllServer
428
539
  });
@@ -435,6 +546,18 @@ var toRoleRef = (party, uiLanguage) => {
435
546
  label: resolveLocalizedLabel(role?.labels || [], uiLanguage) || role?.shortId?.trim() || "Unknown role"
436
547
  };
437
548
  };
549
+ var mergeRoleRef = (current, candidate) => {
550
+ if (current.id !== candidate.id) {
551
+ return current;
552
+ }
553
+ const preferCurrentLabel = current.label.trim().length > 0 && current.label !== "Unknown role";
554
+ const preferCurrentShortId = Boolean(current.shortId?.trim());
555
+ return {
556
+ id: current.id,
557
+ shortId: preferCurrentShortId ? current.shortId : candidate.shortId,
558
+ label: preferCurrentLabel ? current.label : candidate.label
559
+ };
560
+ };
438
561
  var getPartiesCached = unstable_cache(
439
562
  async (_queryKey, query, uiLanguage) => {
440
563
  const items = await withServerRequestContext(
@@ -446,15 +569,23 @@ var getPartiesCached = unstable_cache(
446
569
  const id = party.id?.trim();
447
570
  if (!id) return;
448
571
  const role = toRoleRef(party, uiLanguage);
449
- if (!groups.has(role.id)) {
572
+ const existingGroup = groups.get(role.id);
573
+ if (!existingGroup) {
450
574
  groups.set(role.id, { role, parties: [] });
575
+ } else {
576
+ const mergedRole = mergeRoleRef(existingGroup.role, role);
577
+ existingGroup.role = mergedRole;
578
+ existingGroup.parties.forEach((groupedParty) => {
579
+ groupedParty.role = mergedRole;
580
+ });
451
581
  }
452
582
  const label = resolveLocalizedLabel(party.labels || [], uiLanguage) || party.shortId?.trim() || id;
583
+ const resolvedRole = groups.get(role.id)?.role || role;
453
584
  groups.get(role.id)?.parties.push({
454
585
  id,
455
586
  shortId: party.shortId?.trim() || void 0,
456
587
  label,
457
- role,
588
+ role: resolvedRole,
458
589
  vcardId: party.vcard?.id?.trim() || void 0
459
590
  });
460
591
  });
@@ -472,17 +603,19 @@ var getPartiesCached = unstable_cache(
472
603
  tags: [CREX_API_CACHE_TAG, CREX_READMODEL_CACHE_TAG, CREX_READMODEL_CACHE_METADATA_TAG, CREX_READMODEL_CACHE_PARTIES_TAG]
473
604
  }
474
605
  );
475
- var getInformationSubjects = async (options) => {
476
- const readOptions = { includeOnlyUsed: options?.includeOnlyUsed === true };
606
+ var getInformationSubjects = async () => {
477
607
  try {
478
- const categories = await getCategoriesCached(void 0, readOptions);
608
+ const categories = await getCategoriesCached();
609
+ if (isMetadataPropertyRuntimeSuppressed("informationSubjects")) {
610
+ return categories;
611
+ }
479
612
  if (categories.roots.length > 0) {
480
613
  return categories;
481
614
  }
482
615
  } catch (error) {
483
616
  console.warn("[MetadataReadModels] Categories endpoint unavailable, falling back to InformationSubjects.", error);
484
617
  }
485
- return getInformationSubjectsLegacyCached(void 0, readOptions);
618
+ return getInformationSubjectsLegacyCached();
486
619
  };
487
620
  var getDocumentTypes = async () => {
488
621
  return getDocumentTypesCached();
@@ -496,8 +629,7 @@ var getParties = async () => {
496
629
  PageNumber: 1,
497
630
  PageSize: READMODEL_PAGE_SIZE,
498
631
  Fields: ["labels", "partyRole", "vcard", "class"],
499
- Sort: ["shortId"],
500
- Embed: ["vcard"]
632
+ Sort: ["shortId"]
501
633
  };
502
634
  return getPartiesCached(stableSerialize({ query, uiLanguage }), query, uiLanguage);
503
635
  };
@@ -696,8 +828,8 @@ var INFORMATION_UNIT_PROPERTY_PRESENTATION = {
696
828
  },
697
829
  applicableForTypes: {
698
830
  valueKind: "objectRefArray",
699
- facet: { supported: true, sectionStrategy: "class" },
700
- metadataDisplay: { supported: true, sectionStrategy: "class" }
831
+ facet: { supported: true, sectionStrategy: "none" },
832
+ metadataDisplay: { supported: true, sectionStrategy: "none" }
701
833
  },
702
834
  planningTimes: {
703
835
  valueKind: "objectRefArray",
@@ -754,23 +886,70 @@ var INFORMATION_UNIT_PROPERTY_PRESENTATION = {
754
886
  // src/read-models/metadata-presentation.ts
755
887
  import { unstable_cache as unstable_cache2 } from "next/cache";
756
888
  import { CREX_API_CACHE_TAG as CREX_API_CACHE_TAG2, CREX_READMODEL_CACHE_METADATA_TAG as CREX_READMODEL_CACHE_METADATA_TAG2, CREX_READMODEL_CACHE_TAG as CREX_READMODEL_CACHE_TAG2 } from "@c-rex/core/requests";
757
- var addTaxonomyNodeOverride = (node, map, sectionLabel) => {
758
- if (!node.shortId) return;
759
- map[node.shortId] = {
889
+ var UNKNOWN_SECTION_LABELS = {
890
+ en: {
891
+ components: "Unknown component",
892
+ informationSubjects: "Unknown information subject",
893
+ topicTypes: "Unknown topic type",
894
+ documentTypes: "Unknown document type",
895
+ contentLifeCycleStatus: "Unknown content life cycle status",
896
+ applicableForTypes: "Unknown document type",
897
+ planningTimes: "Unknown planning time",
898
+ functionalMetadata: "Unknown functional metadata",
899
+ productFeatures: "Unknown product feature",
900
+ productLifeCyclePhases: "Unknown product life cycle phase",
901
+ productMetadata: "Unknown product metadata",
902
+ productVariants: "Unknown product variant",
903
+ qualifications: "Unknown qualification",
904
+ supplies: "Unknown supply"
905
+ },
906
+ de: {
907
+ components: "Unbekannte Komponente",
908
+ informationSubjects: "Unbekanntes Informationsthema",
909
+ topicTypes: "Unbekannter Topictyp",
910
+ documentTypes: "Unbekannte Dokumentart",
911
+ contentLifeCycleStatus: "Unbekannter Inhaltslebenszyklusstatus",
912
+ applicableForTypes: "Unbekannte Dokumentart",
913
+ planningTimes: "Unbekannte Planungszeit",
914
+ functionalMetadata: "Unbekannte funktionale Metadaten",
915
+ productFeatures: "Unbekanntes Produktmerkmal",
916
+ productLifeCyclePhases: "Unbekannte Produktlebenszyklusphase",
917
+ productMetadata: "Unbekannte Produktmetadaten",
918
+ productVariants: "Unbekannte Produktvariante",
919
+ qualifications: "Unbekannte Qualifikation",
920
+ supplies: "Unbekannter Lieferumfang"
921
+ }
922
+ };
923
+ var resolveUnknownSectionLabel = (property, uiLanguage) => {
924
+ const normalizedLanguage = uiLanguage.toLowerCase();
925
+ const baseLanguage = normalizedLanguage.split("-")[0];
926
+ return UNKNOWN_SECTION_LABELS[baseLanguage]?.[property] || UNKNOWN_SECTION_LABELS.en[property] || "Unknown metadata";
927
+ };
928
+ var addTaxonomyNodePresentation = (node, map, sectionLabel, options) => {
929
+ const presentation = {
760
930
  label: node.label,
761
- sectionLabel
931
+ sectionLabel,
932
+ hidden: options?.hidden
762
933
  };
934
+ if (node.shortId) {
935
+ map[node.shortId] = presentation;
936
+ }
937
+ if (node.id) {
938
+ map[node.id] = presentation;
939
+ }
763
940
  };
764
- var createClassSectionOverrides = (nodes, options) => {
765
- const overrides = {};
941
+ var createClassSectionPresentation = (property, nodes, uiLanguage, options) => {
942
+ const presentation = {};
943
+ const unknownSectionLabel = resolveUnknownSectionLabel(property, uiLanguage);
766
944
  Object.values(nodes).forEach((node) => {
767
945
  const classId = node.classRef?.id?.trim();
768
- const sectionLabel = node.classRef?.label || (classId ? options?.classLabelsById?.[classId] : void 0);
769
- addTaxonomyNodeOverride(node, overrides, sectionLabel);
946
+ const hidden = isMetadataGroupDenied(property, { classId });
947
+ const sectionLabel = node.classRef?.label || (classId ? options?.classLabelsById?.[classId] : void 0) || unknownSectionLabel;
948
+ addTaxonomyNodePresentation(node, presentation, sectionLabel, { hidden });
770
949
  });
771
- return overrides;
950
+ return presentation;
772
951
  };
773
- var resolveMissingClassLabels = async (nodes, uiLanguage) => {
952
+ var resolveMissingClassLabels2 = async (nodes, uiLanguage) => {
774
953
  const classIds = Array.from(
775
954
  new Set(
776
955
  Object.values(nodes).map((node) => node.classRef?.id?.trim()).filter((value) => Boolean(value))
@@ -808,7 +987,7 @@ var resolveLocalizedLabel2 = (labels, uiLanguage) => {
808
987
  if (english) return english;
809
988
  return normalized[0]?.value;
810
989
  };
811
- var isNotFoundError = (error) => {
990
+ var isNotFoundError2 = (error) => {
812
991
  if (!(error instanceof Error)) {
813
992
  return false;
814
993
  }
@@ -825,7 +1004,7 @@ var getDomainEntitySectionLabelUncached = async (id, uiLanguage) => {
825
1004
  );
826
1005
  return resolveLocalizedLabel2(entity.labels || [], uiLanguage);
827
1006
  } catch (error) {
828
- if (isNotFoundError(error)) {
1007
+ if (isNotFoundError2(error)) {
829
1008
  return void 0;
830
1009
  }
831
1010
  throw error;
@@ -850,7 +1029,7 @@ var getDomainEntitySectionLabel = async (id, uiLanguage) => {
850
1029
  inFlightDomainEntityLabelRequests.set(inFlightKey, promise);
851
1030
  return promise;
852
1031
  };
853
- var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", options) => {
1032
+ var getMetadataFacetPresentation = async (properties, uiLanguage = "en-US", options) => {
854
1033
  const defaultProperties = Object.keys(INFORMATION_UNIT_PROPERTY_PRESENTATION).filter((property) => INFORMATION_UNIT_PROPERTY_PRESENTATION[property].facet.supported);
855
1034
  const propertySet = new Set(properties && properties.length > 0 ? properties : defaultProperties);
856
1035
  const result = {};
@@ -858,7 +1037,10 @@ var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", op
858
1037
  components: getComponents,
859
1038
  informationSubjects: getInformationSubjects,
860
1039
  documentTypes: getDocumentTypes,
861
- applicableForTypes: getApplicableForTypes,
1040
+ // API facets for `applicableForTypes` contain document type refs.
1041
+ // Resolve them through DocumentTypes so section labels come from the
1042
+ // referenced object class instead of the predicate label.
1043
+ applicableForTypes: getDocumentTypes,
862
1044
  planningTimes: getPlanningTimes,
863
1045
  functionalMetadata: getFunctionalMetadata,
864
1046
  contentLifeCycleStatus: getContentLifeCycleStatus,
@@ -876,43 +1058,56 @@ var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", op
876
1058
  const config = INFORMATION_UNIT_PROPERTY_PRESENTATION[property];
877
1059
  if (!config?.facet.supported) continue;
878
1060
  if (config.facet.sectionStrategy === "partyRole" && property === "parties") {
1061
+ if (isMetadataPropertyRuntimeSuppressed("parties")) {
1062
+ continue;
1063
+ }
879
1064
  partiesTask = (async () => {
880
1065
  const parties = await getParties();
881
- const partyOverrides = {};
1066
+ const partyPresentation = {};
882
1067
  parties.groups.forEach((group) => {
1068
+ const hidden = isMetadataGroupDenied("parties", { partyRoleId: group.role.id });
883
1069
  const sectionLabel = group.role.label;
884
1070
  group.parties.forEach((party) => {
885
1071
  if (!party.shortId) return;
886
- partyOverrides[party.shortId] = {
1072
+ partyPresentation[party.shortId] = {
887
1073
  label: party.label,
888
- sectionLabel
1074
+ sectionLabel,
1075
+ hidden
889
1076
  };
1077
+ if (party.id) {
1078
+ partyPresentation[party.id] = {
1079
+ label: party.label,
1080
+ sectionLabel,
1081
+ hidden
1082
+ };
1083
+ }
890
1084
  });
891
1085
  });
892
- result.parties = partyOverrides;
1086
+ result.parties = partyPresentation;
893
1087
  })();
894
1088
  continue;
895
1089
  }
896
1090
  if (config.facet.sectionStrategy === "class") {
1091
+ if (isMetadataPropertyRuntimeSuppressed(property)) {
1092
+ continue;
1093
+ }
897
1094
  const resolver = classResolvers[property];
898
1095
  if (!resolver) continue;
899
1096
  classTasks.push(
900
1097
  (async () => {
901
- const taxonomy = property === "informationSubjects" && options?.includeOnlyUsedByProperty?.informationSubjects === true ? await getInformationSubjects({ includeOnlyUsed: true }) : await resolver();
1098
+ const taxonomy = await resolver();
902
1099
  if (property === "topicTypes" || property === "contentLifeCycleStatus") {
903
1100
  const domainEntityId = property === "topicTypes" ? TOPIC_TYPE_DOMAIN_ENTITY_ID : CONTENT_LIFECYCLE_STATUS_DOMAIN_ENTITY_ID;
904
- const sectionLabel = await getDomainEntitySectionLabel(domainEntityId, uiLanguage);
905
- const overrides = createClassSectionOverrides(taxonomy.nodesById);
906
- if (sectionLabel) {
907
- Object.values(overrides).forEach((entry) => {
908
- entry.sectionLabel = sectionLabel;
909
- });
910
- }
911
- result[property] = overrides;
1101
+ const sectionLabel = await getDomainEntitySectionLabel(domainEntityId, uiLanguage) || resolveUnknownSectionLabel(property, uiLanguage);
1102
+ const presentation = createClassSectionPresentation(property, taxonomy.nodesById, uiLanguage);
1103
+ Object.values(presentation).forEach((entry) => {
1104
+ entry.sectionLabel = sectionLabel;
1105
+ });
1106
+ result[property] = presentation;
912
1107
  return;
913
1108
  }
914
- const classLabelsById = await resolveMissingClassLabels(taxonomy.nodesById, uiLanguage);
915
- result[property] = createClassSectionOverrides(taxonomy.nodesById, { classLabelsById });
1109
+ const classLabelsById = await resolveMissingClassLabels2(taxonomy.nodesById, uiLanguage);
1110
+ result[property] = createClassSectionPresentation(property, taxonomy.nodesById, uiLanguage, { classLabelsById });
916
1111
  })()
917
1112
  );
918
1113
  }
@@ -920,9 +1115,50 @@ var getMetadataFacetLabelOverrides = async (properties, uiLanguage = "en-US", op
920
1115
  await Promise.all([...classTasks, ...partiesTask ? [partiesTask] : []]);
921
1116
  return result;
922
1117
  };
1118
+ var getMetadataFacetLabelOverrides = getMetadataFacetPresentation;
923
1119
 
924
- // src/read-models/metadata-display.ts
925
- import { getFileRenditionGroups, resolvePreferredLanguage, sortAndDeduplicateLanguages } from "@c-rex/utils";
1120
+ // src/read-models/metadata-display-builder.ts
1121
+ var DEFAULT_IGNORED_FORMATS = [
1122
+ "application/xhtml+xml",
1123
+ "application/json",
1124
+ "application/llm+xml",
1125
+ "text/html"
1126
+ ];
1127
+ var normalizeLanguageCode = (value) => {
1128
+ const trimmed = value.trim();
1129
+ if (!trimmed) return trimmed;
1130
+ const [rawLang, rawCountry, ...rest] = trimmed.split("-");
1131
+ const lang = (rawLang || "").toLowerCase();
1132
+ if (!rawCountry) return lang;
1133
+ const country = rawCountry.toUpperCase();
1134
+ const suffix = rest.length > 0 ? `-${rest.join("-")}` : "";
1135
+ return `${lang}-${country}${suffix}`;
1136
+ };
1137
+ var sortAndDeduplicateLanguages = (languages) => {
1138
+ const normalized = languages.map((item) => (item || "").trim()).filter((item) => item.length > 0).map((item) => normalizeLanguageCode(item));
1139
+ return Array.from(new Set(normalized)).sort((a, b) => a.localeCompare(b));
1140
+ };
1141
+ var resolvePreferredLanguage = (languages, uiLanguage) => {
1142
+ if (!languages || languages.length === 0) return void 0;
1143
+ const normalizedUiLanguage = normalizeLanguageCode(uiLanguage);
1144
+ const baseLanguage = normalizedUiLanguage.split("-")[0];
1145
+ const normalized = sortAndDeduplicateLanguages(languages);
1146
+ const exact = normalized.find((item) => item === normalizedUiLanguage);
1147
+ if (exact) return exact;
1148
+ const base = normalized.find((item) => item === baseLanguage || item.startsWith(`${baseLanguage}-`));
1149
+ if (base) return base;
1150
+ const english = normalized.find((item) => item === "en" || item === "en-US" || item.startsWith("en-"));
1151
+ if (english) return english;
1152
+ return normalized[0];
1153
+ };
1154
+ var getFirstLinkByRel = (item, rel) => item.links?.find((link) => link.rel === rel)?.href;
1155
+ var hasRenderableFileRenditions = (renditions) => {
1156
+ if (!renditions || renditions.length === 0) return false;
1157
+ return renditions.some((item) => {
1158
+ if (!item.format || DEFAULT_IGNORED_FORMATS.includes(item.format)) return false;
1159
+ return Boolean(getFirstLinkByRel(item, "download") || getFirstLinkByRel(item, "view"));
1160
+ });
1161
+ };
926
1162
  var resolveLiteralLabel = (labels, uiLanguage) => {
927
1163
  if (!labels || labels.length === 0) return void 0;
928
1164
  const language = uiLanguage || "en";
@@ -939,6 +1175,9 @@ var resolveLiteralLabel = (labels, uiLanguage) => {
939
1175
  var resolveObjectRefLabel = (item, uiLanguage) => {
940
1176
  return resolveLiteralLabel(item.labels || [], uiLanguage) || item.shortId || item.id || void 0;
941
1177
  };
1178
+ var resolveObjectRefClassLabel = (item, uiLanguage) => {
1179
+ return resolveLiteralLabel(item.class?.labels || [], uiLanguage) || item.class?.shortId || item.class?.id || void 0;
1180
+ };
942
1181
  var asObjectRefArray = (value) => {
943
1182
  if (!Array.isArray(value)) return [];
944
1183
  return value.filter((item) => Boolean(item && typeof item === "object"));
@@ -947,29 +1186,27 @@ var asLiteralArray = (value) => {
947
1186
  if (!Array.isArray(value)) return [];
948
1187
  return value.filter((item) => Boolean(item && typeof item === "object"));
949
1188
  };
950
- var shouldUseOverrides = (strategy) => {
1189
+ var shouldUseFacetPresentation = (strategy) => {
951
1190
  return strategy === "class" || strategy === "partyRole";
952
1191
  };
953
- var getMetadataDisplayRows = async (data, options) => {
954
- const includeProperties = options.includeProperties || Object.keys(INFORMATION_UNIT_PROPERTY_PRESENTATION);
955
- const uiLanguage = options.uiLanguage;
956
- const preferredTitle = resolveLiteralLabel(data.titles || [], uiLanguage) || resolveLiteralLabel(data.labels || [], uiLanguage);
957
- const objectRefProperties = includeProperties.filter((key) => {
1192
+ var resolveFacetPresentationProperties = (includeProperties) => {
1193
+ return includeProperties.filter((key) => {
958
1194
  const config = INFORMATION_UNIT_PROPERTY_PRESENTATION[key];
959
1195
  if (!config?.metadataDisplay?.supported) return false;
960
- return config.valueKind === "objectRefArray" || config.valueKind === "objectRef";
1196
+ if (config.valueKind !== "objectRefArray" && config.valueKind !== "objectRef") return false;
1197
+ return shouldUseFacetPresentation(config.metadataDisplay.sectionStrategy);
961
1198
  });
962
- const overrideProperties = objectRefProperties.filter(
963
- (key) => shouldUseOverrides(INFORMATION_UNIT_PROPERTY_PRESENTATION[key].metadataDisplay.sectionStrategy)
964
- );
965
- const labelOverrides = options.overrides || (overrideProperties.length > 0 ? await getMetadataFacetLabelOverrides(overrideProperties, uiLanguage) : {});
1199
+ };
1200
+ var resolveOverrideProperties = resolveFacetPresentationProperties;
1201
+ var buildMetadataDisplayRows = (data, options) => {
1202
+ const uiLanguage = options.uiLanguage;
1203
+ const preferredTitle = resolveLiteralLabel(data.titles || [], uiLanguage) || resolveLiteralLabel(data.labels || [], uiLanguage);
966
1204
  const rows = [];
967
- for (const key of includeProperties) {
1205
+ for (const key of options.includeProperties) {
968
1206
  const config = INFORMATION_UNIT_PROPERTY_PRESENTATION[key];
969
1207
  if (!config?.metadataDisplay?.supported) continue;
970
- if (key === "labels") {
971
- continue;
972
- }
1208
+ if (isMetadataPropertyRuntimeSuppressed(key)) continue;
1209
+ if (key === "labels") continue;
973
1210
  if (key === "titles") {
974
1211
  if (preferredTitle) {
975
1212
  rows.push({
@@ -1008,7 +1245,7 @@ var getMetadataDisplayRows = async (data, options) => {
1008
1245
  continue;
1009
1246
  }
1010
1247
  if (config.valueKind === "stringArray") {
1011
- const values = Array.from(new Set(value.map((item) => String(item)).filter((item) => item.length > 0)));
1248
+ const values = Array.from(new Set(value.map((item) => String(item)).filter(Boolean)));
1012
1249
  if (values.length > 0) {
1013
1250
  rows.push({
1014
1251
  key,
@@ -1021,8 +1258,7 @@ var getMetadataDisplayRows = async (data, options) => {
1021
1258
  continue;
1022
1259
  }
1023
1260
  if (config.valueKind === "literalArray") {
1024
- const literals = asLiteralArray(value);
1025
- const preferred = resolveLiteralLabel(literals, uiLanguage);
1261
+ const preferred = resolveLiteralLabel(asLiteralArray(value), uiLanguage);
1026
1262
  if (preferred) {
1027
1263
  rows.push({
1028
1264
  key,
@@ -1035,8 +1271,7 @@ var getMetadataDisplayRows = async (data, options) => {
1035
1271
  continue;
1036
1272
  }
1037
1273
  if (config.valueKind === "objectRef") {
1038
- const ref = value;
1039
- const label = resolveObjectRefLabel(ref, uiLanguage);
1274
+ const label = resolveObjectRefLabel(value, uiLanguage);
1040
1275
  if (label) {
1041
1276
  rows.push({
1042
1277
  key,
@@ -1051,26 +1286,28 @@ var getMetadataDisplayRows = async (data, options) => {
1051
1286
  if (config.valueKind === "objectRefArray") {
1052
1287
  const refs = asObjectRefArray(value);
1053
1288
  if (refs.length === 0) continue;
1054
- const grouped = /* @__PURE__ */ new Map();
1055
- const strategy = config.metadataDisplay.sectionStrategy;
1289
+ const groupedValues = /* @__PURE__ */ new Map();
1056
1290
  refs.forEach((ref) => {
1057
1291
  const shortId = ref.shortId || "";
1058
- const override = shortId ? labelOverrides[key]?.[shortId] : void 0;
1059
- const label = override?.label || resolveObjectRefLabel(ref, uiLanguage);
1060
- if (!label) return;
1061
- const section = strategy === "none" ? key : override?.sectionLabel || key;
1062
- if (!grouped.has(section)) grouped.set(section, []);
1063
- grouped.get(section)?.push(label);
1292
+ const presentationMap = (options.presentation || options.overrides)?.[key];
1293
+ const presentationItem = (shortId ? presentationMap?.[shortId] : void 0) || (ref.id ? presentationMap?.[ref.id] : void 0);
1294
+ if (presentationItem?.hidden) return;
1295
+ if (isMetadataGroupDenied(key, { classId: ref.class?.id })) return;
1296
+ const valueLabel = presentationItem?.label || resolveObjectRefLabel(ref, uiLanguage);
1297
+ if (!valueLabel) return;
1298
+ const sectionLabel = config.metadataDisplay.sectionStrategy === "none" ? key : presentationItem?.sectionLabel || resolveObjectRefClassLabel(ref, uiLanguage) || key;
1299
+ const existing = groupedValues.get(sectionLabel) || /* @__PURE__ */ new Set();
1300
+ existing.add(valueLabel);
1301
+ groupedValues.set(sectionLabel, existing);
1064
1302
  });
1065
- Array.from(grouped.entries()).sort((a, b) => a[0].localeCompare(b[0])).forEach(([section, values]) => {
1066
- const uniqueValues = Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));
1067
- if (uniqueValues.length === 0) return;
1068
- const isDirect = section !== key;
1303
+ Array.from(groupedValues.entries()).sort(([left], [right]) => left.localeCompare(right)).forEach(([sectionLabel, valueSet]) => {
1304
+ const values = Array.from(valueSet).sort((a, b) => a.localeCompare(b));
1305
+ if (values.length === 0) return;
1069
1306
  rows.push({
1070
1307
  key,
1071
- label: section,
1072
- labelSource: isDirect ? "direct" : "translationKey",
1073
- values: uniqueValues,
1308
+ label: sectionLabel,
1309
+ labelSource: sectionLabel === key ? "translationKey" : "direct",
1310
+ values,
1074
1311
  valueType: "text"
1075
1312
  });
1076
1313
  });
@@ -1079,7 +1316,7 @@ var getMetadataDisplayRows = async (data, options) => {
1079
1316
  if (config.valueKind === "renditionArray") {
1080
1317
  const renditions = Array.isArray(value) ? value.filter((item) => Boolean(item && typeof item === "object")) : [];
1081
1318
  if (renditions.length === 0) continue;
1082
- if (getFileRenditionGroups({ renditions }).length === 0) continue;
1319
+ if (!hasRenderableFileRenditions(renditions)) continue;
1083
1320
  rows.push({
1084
1321
  key,
1085
1322
  label: "files",
@@ -1093,6 +1330,18 @@ var getMetadataDisplayRows = async (data, options) => {
1093
1330
  return rows;
1094
1331
  };
1095
1332
 
1333
+ // src/read-models/metadata-display.ts
1334
+ var getMetadataDisplayRows = async (data, options) => {
1335
+ const includeProperties = options.includeProperties || Object.keys(INFORMATION_UNIT_PROPERTY_PRESENTATION);
1336
+ const presentationProperties = resolveFacetPresentationProperties(includeProperties);
1337
+ const facetPresentation = options.presentation || options.overrides || (presentationProperties.length > 0 ? await getMetadataFacetPresentation(presentationProperties, options.uiLanguage) : {});
1338
+ return buildMetadataDisplayRows(data, {
1339
+ uiLanguage: options.uiLanguage,
1340
+ includeProperties,
1341
+ presentation: facetPresentation
1342
+ });
1343
+ };
1344
+
1096
1345
  // src/read-models/version-availability.ts
1097
1346
  import { CREX_API_CACHE_TAG as CREX_API_CACHE_TAG3, CREX_READMODEL_CACHE_METADATA_TAG as CREX_READMODEL_CACHE_METADATA_TAG3, CREX_READMODEL_CACHE_TAG as CREX_READMODEL_CACHE_TAG3 } from "@c-rex/core/requests";
1098
1347
  import { resolvePreferredLanguage as resolvePreferredLanguage2 } from "@c-rex/utils";
@@ -1226,7 +1475,9 @@ var resolveFacetTags = (options) => {
1226
1475
  toInformationUnitPropertyKeys(options?.includeProperties),
1227
1476
  toInformationUnitPropertyKeys(options?.excludeProperties)
1228
1477
  );
1229
- const tagSet = new Set(runtimeScoped);
1478
+ const tagSet = new Set(
1479
+ runtimeScoped.filter((property) => !isMetadataPropertyRuntimeSuppressed(property))
1480
+ );
1230
1481
  (facetConfig?.extraTags || []).forEach((tag) => tagSet.add(tag));
1231
1482
  (options?.extraTags || []).forEach((tag) => tagSet.add(tag));
1232
1483
  return Array.from(tagSet);
@@ -1244,12 +1495,15 @@ var resolveMetadataDisplayProperties = (options) => {
1244
1495
  profileScoped,
1245
1496
  toInformationUnitPropertyKeys(options?.includeProperties),
1246
1497
  toInformationUnitPropertyKeys(options?.excludeProperties)
1247
- );
1498
+ ).filter((property) => !isMetadataPropertyRuntimeSuppressed(property));
1248
1499
  };
1249
1500
  export {
1250
1501
  INFORMATION_UNIT_PROPERTY_PRESENTATION,
1251
1502
  METADATA_VIEW_PROFILES,
1503
+ METADATA_VISIBILITY_POLICY,
1252
1504
  READMODEL_CACHE_POLICY,
1505
+ buildMetadataDisplayRows,
1506
+ clearMetadataCacheFamilyRuntimeSuppression,
1253
1507
  getApplicableForTypes,
1254
1508
  getAvailableLanguagesByVersionOf,
1255
1509
  getComponents,
@@ -1257,8 +1511,10 @@ export {
1257
1511
  getDocumentTypes,
1258
1512
  getFunctionalMetadata,
1259
1513
  getInformationSubjects,
1514
+ getMetadataCacheFamily,
1260
1515
  getMetadataDisplayRows,
1261
1516
  getMetadataFacetLabelOverrides,
1517
+ getMetadataFacetPresentation,
1262
1518
  getMetadataPropertyResolvers,
1263
1519
  getParties,
1264
1520
  getPlanningTimes,
@@ -1267,9 +1523,19 @@ export {
1267
1523
  getProductMetadata,
1268
1524
  getProductVariants,
1269
1525
  getQualifications,
1526
+ getRuntimeSuppressedMetadataFamilies,
1270
1527
  getSupplies,
1271
1528
  getTopicTypes,
1529
+ isMetadataGroupDenied,
1530
+ isMetadataPropertyRuntimeSuppressed,
1531
+ resetRuntimeSuppressedMetadataFamiliesForTests,
1532
+ resolveFacetPresentationProperties,
1272
1533
  resolveFacetTags,
1273
- resolveMetadataDisplayProperties
1534
+ resolveLiteralLabel,
1535
+ resolveMetadataDisplayProperties,
1536
+ resolveObjectRefClassLabel,
1537
+ resolveObjectRefLabel,
1538
+ resolveOverrideProperties,
1539
+ suppressMetadataCacheFamilyRuntime
1274
1540
  };
1275
1541
  //# sourceMappingURL=index.mjs.map