@murumets-ee/media 0.51.0 → 0.52.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"usage-CVAqkS6h.mjs","names":[],"sources":["../src/usage.ts"],"sourcesContent":["/**\n * Media usage lookup — finds all entity references to a media item.\n *\n * Delegates to the universal entity_refs tracking table (populated at write time\n * by AdminClient). One indexed query instead of scanning every table.\n *\n * Used by delete protection (409 Conflict) and the usage API endpoint.\n */\n\nimport 'server-only'\n\nimport type { ToolkitApp } from '@murumets-ee/core'\nimport { findEntityUsages } from '@murumets-ee/entity/refs'\n\nexport interface MediaUsage {\n entityName: string\n entityId: string\n fieldName: string\n /** 'field' = entity column, 'block' = `field.blockTree()` field */\n context: 'field' | 'block'\n}\n\n/**\n * Find all entities that reference a given media ID.\n *\n * @param mediaId - UUID of the media item to check\n * @param app - Toolkit app (provides db + entity registry)\n * @returns Array of usage records (empty if unreferenced)\n */\nexport async function findMediaUsages(\n mediaId: string,\n app: ToolkitApp,\n): Promise<MediaUsage[]> {\n const usages = await findEntityUsages('media', mediaId, app.db.readOnly)\n\n // Derive context from the source field: a usage whose field is a\n // `field.blockTree()` slot is media referenced from inside a block tree.\n // (Block-tree ref-extraction itself is tracked separately — see the\n // entity_refs blockTree gap; until that lands no usage will actually carry\n // a blockTree source field, so this stays forward-compatible.)\n return usages.map((usage) => {\n let context: 'field' | 'block' = 'field'\n const entity = app.entities.get(usage.sourceEntity)\n if (entity) {\n const fieldConfig = entity.allFields[usage.sourceField]\n if (fieldConfig && fieldConfig.type === 'blockTree') {\n context = 'block'\n }\n }\n\n return {\n entityName: usage.sourceEntity,\n entityId: usage.sourceId,\n fieldName: usage.sourceField,\n context,\n }\n })\n}\n"],"mappings":"gFA6BA,eAAsB,EACpB,EACA,EACuB,CAQvB,OAAO,MAPc,EAAiB,QAAS,EAAS,EAAI,GAAG,QAAQ,EAAA,CAOzD,IAAK,GAAU,CAC3B,IAAI,EAA6B,QAC3B,EAAS,EAAI,SAAS,IAAI,EAAM,YAAY,EAClD,GAAI,EAAQ,CACV,IAAM,EAAc,EAAO,UAAU,EAAM,aACvC,GAAe,EAAY,OAAS,cACtC,EAAU,QAEd,CAEA,MAAO,CACL,WAAY,EAAM,aAClB,SAAU,EAAM,SAChB,UAAW,EAAM,YACjB,SACF,CACF,CAAC,CACH"}
1
+ {"version":3,"file":"usage-CVAqkS6h.mjs","names":[],"sources":["../src/usage.ts"],"sourcesContent":["/**\n * Media usage lookup — finds all entity references to a media item.\n *\n * Delegates to the universal entity_refs tracking table (populated at write time\n * by AdminClient). One indexed query instead of scanning every table.\n *\n * Used by delete protection (409 Conflict) and the usage API endpoint.\n */\n\nimport 'server-only'\n\nimport type { ToolkitApp } from '@murumets-ee/core'\nimport { findEntityUsages } from '@murumets-ee/entity/refs'\n\nexport interface MediaUsage {\n entityName: string\n entityId: string\n fieldName: string\n /** 'field' = entity column, 'block' = `field.blockTree()` field */\n context: 'field' | 'block'\n}\n\n/**\n * Find all entities that reference a given media ID.\n *\n * @param mediaId - UUID of the media item to check\n * @param app - Toolkit app (provides db + entity registry)\n * @returns Array of usage records (empty if unreferenced)\n */\nexport async function findMediaUsages(\n mediaId: string,\n app: ToolkitApp,\n): Promise<MediaUsage[]> {\n const usages = await findEntityUsages('media', mediaId, app.db.readOnly)\n\n // Derive context from the source field: a usage whose field is a\n // `field.blockTree()` slot is media referenced from inside a block tree.\n //\n // This branch was dead until editor PR24. `extractRefs` matched only\n // `LinkValue`-shaped values inside a block tree, and `field.media()` stores a\n // `MediaRef` — no `kind` — so no usage ever carried a blockTree source field\n // and an image used only inside a block reported as used NOWHERE. It now\n // does, which is also why delete-protection fires for it.\n //\n // 🔴 `blockTreeShape: true` json columns (`site_layout`'s four chrome\n // regions) index too, and land in the `'field'` bucket rather than\n // `'block'` — the switch is on the field TYPE, and theirs is `json`. That\n // under-reports the CONTEXT of a chrome usage while reporting the usage\n // itself correctly, which is the safe direction: the panel says \"used by\n // site_layout.headerBlocks\", which is true and actionable.\n return usages.map((usage) => {\n let context: 'field' | 'block' = 'field'\n const entity = app.entities.get(usage.sourceEntity)\n if (entity) {\n const fieldConfig = entity.allFields[usage.sourceField]\n if (fieldConfig && fieldConfig.type === 'blockTree') {\n context = 'block'\n }\n }\n\n return {\n entityName: usage.sourceEntity,\n entityId: usage.sourceId,\n fieldName: usage.sourceField,\n context,\n }\n })\n}\n"],"mappings":"gFA6BA,eAAsB,EACpB,EACA,EACuB,CAkBvB,OAAO,MAjBc,EAAiB,QAAS,EAAS,EAAI,GAAG,QAAQ,EAAA,CAiBzD,IAAK,GAAU,CAC3B,IAAI,EAA6B,QAC3B,EAAS,EAAI,SAAS,IAAI,EAAM,YAAY,EAClD,GAAI,EAAQ,CACV,IAAM,EAAc,EAAO,UAAU,EAAM,aACvC,GAAe,EAAY,OAAS,cACtC,EAAU,QAEd,CAEA,MAAO,CACL,WAAY,EAAM,aAClB,SAAU,EAAM,SAChB,UAAW,EAAM,YACjB,SACF,CACF,CAAC,CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"usage.mjs","names":[],"sources":["../src/usage.ts"],"sourcesContent":["/**\n * Media usage lookup — finds all entity references to a media item.\n *\n * Delegates to the universal entity_refs tracking table (populated at write time\n * by AdminClient). One indexed query instead of scanning every table.\n *\n * Used by delete protection (409 Conflict) and the usage API endpoint.\n */\n\nimport 'server-only'\n\nimport type { ToolkitApp } from '@murumets-ee/core'\nimport { findEntityUsages } from '@murumets-ee/entity/refs'\n\nexport interface MediaUsage {\n entityName: string\n entityId: string\n fieldName: string\n /** 'field' = entity column, 'block' = `field.blockTree()` field */\n context: 'field' | 'block'\n}\n\n/**\n * Find all entities that reference a given media ID.\n *\n * @param mediaId - UUID of the media item to check\n * @param app - Toolkit app (provides db + entity registry)\n * @returns Array of usage records (empty if unreferenced)\n */\nexport async function findMediaUsages(\n mediaId: string,\n app: ToolkitApp,\n): Promise<MediaUsage[]> {\n const usages = await findEntityUsages('media', mediaId, app.db.readOnly)\n\n // Derive context from the source field: a usage whose field is a\n // `field.blockTree()` slot is media referenced from inside a block tree.\n // (Block-tree ref-extraction itself is tracked separately — see the\n // entity_refs blockTree gap; until that lands no usage will actually carry\n // a blockTree source field, so this stays forward-compatible.)\n return usages.map((usage) => {\n let context: 'field' | 'block' = 'field'\n const entity = app.entities.get(usage.sourceEntity)\n if (entity) {\n const fieldConfig = entity.allFields[usage.sourceField]\n if (fieldConfig && fieldConfig.type === 'blockTree') {\n context = 'block'\n }\n }\n\n return {\n entityName: usage.sourceEntity,\n entityId: usage.sourceId,\n fieldName: usage.sourceField,\n context,\n }\n })\n}\n"],"mappings":"gFA6BA,eAAsB,EACpB,EACA,EACuB,CAQvB,OAAO,MAPc,EAAiB,QAAS,EAAS,EAAI,GAAG,QAAQ,EAAA,CAOzD,IAAK,GAAU,CAC3B,IAAI,EAA6B,QAC3B,EAAS,EAAI,SAAS,IAAI,EAAM,YAAY,EAClD,GAAI,EAAQ,CACV,IAAM,EAAc,EAAO,UAAU,EAAM,aACvC,GAAe,EAAY,OAAS,cACtC,EAAU,QAEd,CAEA,MAAO,CACL,WAAY,EAAM,aAClB,SAAU,EAAM,SAChB,UAAW,EAAM,YACjB,SACF,CACF,CAAC,CACH"}
1
+ {"version":3,"file":"usage.mjs","names":[],"sources":["../src/usage.ts"],"sourcesContent":["/**\n * Media usage lookup — finds all entity references to a media item.\n *\n * Delegates to the universal entity_refs tracking table (populated at write time\n * by AdminClient). One indexed query instead of scanning every table.\n *\n * Used by delete protection (409 Conflict) and the usage API endpoint.\n */\n\nimport 'server-only'\n\nimport type { ToolkitApp } from '@murumets-ee/core'\nimport { findEntityUsages } from '@murumets-ee/entity/refs'\n\nexport interface MediaUsage {\n entityName: string\n entityId: string\n fieldName: string\n /** 'field' = entity column, 'block' = `field.blockTree()` field */\n context: 'field' | 'block'\n}\n\n/**\n * Find all entities that reference a given media ID.\n *\n * @param mediaId - UUID of the media item to check\n * @param app - Toolkit app (provides db + entity registry)\n * @returns Array of usage records (empty if unreferenced)\n */\nexport async function findMediaUsages(\n mediaId: string,\n app: ToolkitApp,\n): Promise<MediaUsage[]> {\n const usages = await findEntityUsages('media', mediaId, app.db.readOnly)\n\n // Derive context from the source field: a usage whose field is a\n // `field.blockTree()` slot is media referenced from inside a block tree.\n //\n // This branch was dead until editor PR24. `extractRefs` matched only\n // `LinkValue`-shaped values inside a block tree, and `field.media()` stores a\n // `MediaRef` — no `kind` — so no usage ever carried a blockTree source field\n // and an image used only inside a block reported as used NOWHERE. It now\n // does, which is also why delete-protection fires for it.\n //\n // 🔴 `blockTreeShape: true` json columns (`site_layout`'s four chrome\n // regions) index too, and land in the `'field'` bucket rather than\n // `'block'` — the switch is on the field TYPE, and theirs is `json`. That\n // under-reports the CONTEXT of a chrome usage while reporting the usage\n // itself correctly, which is the safe direction: the panel says \"used by\n // site_layout.headerBlocks\", which is true and actionable.\n return usages.map((usage) => {\n let context: 'field' | 'block' = 'field'\n const entity = app.entities.get(usage.sourceEntity)\n if (entity) {\n const fieldConfig = entity.allFields[usage.sourceField]\n if (fieldConfig && fieldConfig.type === 'blockTree') {\n context = 'block'\n }\n }\n\n return {\n entityName: usage.sourceEntity,\n entityId: usage.sourceId,\n fieldName: usage.sourceField,\n context,\n }\n })\n}\n"],"mappings":"gFA6BA,eAAsB,EACpB,EACA,EACuB,CAkBvB,OAAO,MAjBc,EAAiB,QAAS,EAAS,EAAI,GAAG,QAAQ,EAAA,CAiBzD,IAAK,GAAU,CAC3B,IAAI,EAA6B,QAC3B,EAAS,EAAI,SAAS,IAAI,EAAM,YAAY,EAClD,GAAI,EAAQ,CACV,IAAM,EAAc,EAAO,UAAU,EAAM,aACvC,GAAe,EAAY,OAAS,cACtC,EAAU,QAEd,CAEA,MAAO,CACL,WAAY,EAAM,aAClB,SAAU,EAAM,SAChB,UAAW,EAAM,YACjB,SACF,CACF,CAAC,CACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@murumets-ee/media",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -61,13 +61,13 @@
61
61
  "sharp": "^0.34.5",
62
62
  "tailwind-merge": "^2.6.0",
63
63
  "zod": "^3.24.1",
64
- "@murumets-ee/core": "0.51.0",
65
- "@murumets-ee/db": "0.51.0",
66
- "@murumets-ee/entity": "0.51.0",
67
- "@murumets-ee/logging": "0.51.0",
68
- "@murumets-ee/settings": "0.51.0",
69
- "@murumets-ee/storage": "0.51.0",
70
- "@murumets-ee/ui": "0.51.0"
64
+ "@murumets-ee/core": "0.52.0",
65
+ "@murumets-ee/db": "0.52.0",
66
+ "@murumets-ee/entity": "0.52.0",
67
+ "@murumets-ee/settings": "0.52.0",
68
+ "@murumets-ee/logging": "0.52.0",
69
+ "@murumets-ee/storage": "0.52.0",
70
+ "@murumets-ee/ui": "0.52.0"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "lucide-react": ">=0.400.0 <1",