@overpunch/sanity-type-foundry-utilities
v1.6.1
Published
Sanity Studio utilities for type foundry projects — Utilities desk, Fingerprint Reader for font forensics, and font metadata tools. Supports Sanity v3 through v6.
Readme
@overpunch/sanity-type-foundry-utilities
Nine safety-locked content utilities for Sanity Studio — bulk-edit, export, clean assets, and trace delivered fonts back to their order from an embedded fingerprint. Drops a single Utilities desk into any type-foundry studio, so you stop re-implementing migration, forensics, and bulk-edit tools in every project.
Overview
The whole suite mounts as one Sanity tool via UtilitiesDesk(): a searchable sidebar (with favorites and recent-ops history) that hosts every utility, grouped by category. Destructive operations are guarded by danger-mode locks and confirmation dialogs for safety.
Architecture
UtilitiesDesk() registers a single tool that hosts all nine utilities. They share the Studio's useClient() content client; the Fingerprint Reader additionally calls your lookupOrder function to resolve a fingerprint to its originating order, and Get Font Data uses fontkit for OpenType metadata.
The diagram below renders natively on GitHub for anyone with access to this (private) repository. Note that the npm registry page does not render Mermaid, and the SVG fallback beneath it is served from
raw.githubusercontent.com— which returns 404 for a private repo. On the npm page this section currently shows a broken image and a raw Mermaid code block. See Known documentation gaps.
flowchart TB
config["sanity.config.ts<br/>tools: [ UtilitiesDesk(config) ]"] --> desk
subgraph desk["UtilitiesDesk() — single Utilities tool"]
direction TB
nav["Searchable sidebar<br/>+ favorites + recent ops<br/>+ global Danger Mode lock"]
subgraph dm["Data Management"]
export["Export Data"]
sadd["Search & Add Data"]
sdel["Search & Delete"]
dup["Duplicate & Rename"]
end
subgraph at["Asset Tools"]
assets["Delete Unused Assets"]
end
subgraph dev["Development Tools"]
fp["Fingerprint Reader"]
fd["Get Font Data"]
weak["Convert to Weak References"]
slug["Convert IDs to Slug"]
end
nav --- dm
nav --- at
nav --- dev
end
client["useClient()<br/>Sanity content client"] --> desk
fp -. "config.fingerprintReader.lookupOrder(fingerprint, client)" .-> order["Originating order<br/>(rendered via renderOrder)"]
fd -. fontkit .-> meta["OpenType metadata"]Installation
npm install @overpunch/sanity-type-foundry-utilitiesLocal Development
When developing the utilities package locally, you can use npm link to avoid publishing after every change. This creates a symlink so your Sanity project points directly to your local development folder.
Setup Once
# 1. In the sanity-type-foundry-utilities directory
cd /path/to/sanity-type-foundry-utilities
npm link
# 2. In your Sanity project directory
cd /path/to/your-project/sanity
npm link @overpunch/sanity-type-foundry-utilitiesNow any changes you make to the utilities package will be instantly available in your Sanity studio (Vite will hot-reload automatically).
When Done Developing
# Unlink and return to the published version
cd /path/to/your-project/sanity
npm unlink @overpunch/sanity-type-foundry-utilities
npm install @overpunch/sanity-type-foundry-utilities@latestDevelopment Workflow
- Make changes to utility components in
components/ - Save the file — Vite hot-reloads instantly
- Test in your linked Sanity studio
- When ready to release:
- Bump version:
npm version patch(orminor/major) - Publish:
npm publish - Update consuming projects:
npm install @overpunch/sanity-type-foundry-utilities@latest
- Bump version:
Usage
Basic Usage
Import and use the utilities desk in your Sanity config:
import { UtilitiesDesk } from '@overpunch/sanity-type-foundry-utilities';
// In your sanity.config.js
export default defineConfig({
// ... other config
tools: [UtilitiesDesk()]
});Configuring the Fingerprint Reader
The Fingerprint Reader reads the embedded DS-… fingerprint from any delivered font (TTF, OTF, WOFF, WOFF2) or CSS file. To turn that fingerprint into its originating order, pass a fingerprintReader config to UtilitiesDesk(). Without it, the reader still extracts the fingerprint — it just won't look anything up.
import { UtilitiesDesk } from '@overpunch/sanity-type-foundry-utilities';
export default defineConfig({
// ... other config
tools: [
UtilitiesDesk({
fingerprintReader: {
// Resolve a fingerprint to its order. `client` is the Studio's Sanity client.
// Return the order (any shape) or null if no match.
lookupOrder: async (fingerprint, client) => {
return client.fetch(
`*[_type == "order" && fingerprint == $fp][0]`,
{ fp: fingerprint }
);
},
// Optional: custom renderer for the matched order.
// Defaults to an object inspector when omitted.
renderOrder: (order) => `Order ${order.orderNumber} — ${order.customerEmail}`
}
})
]
});| Config key | Type | Description |
|---|---|---|
| fingerprintReader.lookupOrder | async (fingerprint, client) => order \| null | Resolves an extracted fingerprint to its originating order. Optional — omit to disable order lookup. |
| fingerprintReader.renderOrder | (order) => ReactNode | Optional renderer for the matched order. Defaults to an object inspector. |
Available Components
All utility components are exported individually if you need custom implementations:
import {
ConvertIdsToSlug,
ConvertToWeakReferences,
DangerModeWarning,
DeleteUnusedAssets,
DuplicateAndRename,
ExportData,
FingerprintReader,
GetFontData,
SearchAddData,
SearchAndDelete,
UtilitiesDesk
} from '@overpunch/sanity-type-foundry-utilities';Utilities Included
At a glance — every utility lives under the single Utilities desk, grouped by category:
| Category | Utility | What it does |
|---|---|---|
| Data Management | Export Data | Export documents to CSV or JSON, with optional reference population. |
| Data Management | Search & Add Data | Bulk add/replace field data (Full Replace · Find & Replace · Prepend · Append · Transform). |
| Data Management | Search & Delete | Find and permanently delete documents matching criteria, with confirmation dialogs. |
| Data Management | Duplicate & Rename | Copy field values to new field names across documents of a type. |
| Asset Tools | Delete Unused Assets | Scan for unreferenced images/files and bulk-delete with preview thumbnails. |
| Development Tools | Fingerprint Reader | Read the embedded fingerprint from a delivered font/CSS and look up its originating order. |
| Development Tools | Get Font Data | Analyze uploaded fonts with fontkit — metadata and OpenType properties. |
| Development Tools | Convert to Weak References | Transform strong document references into weak references. |
| Development Tools | Convert IDs to Slug | Migrate auto-generated document IDs to slug-based IDs, updating all references. |
The detailed descriptions below match the order shown in the desk:
1. Convert IDs to Slug
Converts font document IDs from auto-generated to slug-based IDs, updating all references across your content.
2. Convert to Weak References
Transforms strong document references into weak references across matching documents.
3. Delete Unused Assets
Scans for unreferenced image and file assets and allows bulk deletion with preview thumbnails.
4. Duplicate and Rename
Copies field values to new field names across all documents of a specific type.
5. Export Data
Exports documents to CSV or JSON formats with optional reference population.
6. Fingerprint Reader
Reads embedded fingerprint data from font files (WOFF2, TTF, OTF) and looks up the originating Sanity order. See Configuring the Fingerprint Reader to wire up the order lookup.
7. Get Font Data
Analyzes uploaded font files using fontkit, displaying metadata and OpenType properties.
8. Search & Add Data
Bulk add or replace field data with multiple modes:
- Full Replace
- Find & Replace
- Prepend
- Append
- Transform (toLowerCase, toUpperCase, trim)
9. Search & Delete
Searches for and deletes documents matching specific criteria with confirmation dialogs.
Safety Features
- Danger Mode Locks: Destructive operations require unlocking danger mode
- Warning Modals: 48-hour suppression option for danger mode warnings
- Confirmation Dialogs: Double confirmation for bulk delete operations
- Preview Features: See what will be affected before taking action
Compatibility
| Requirement | Supported | Declared peer range |
|---|---|---|
| Sanity Studio | v3 · v4 · v5 · v6 | sanity >=3 <7 |
| React | 18 · 19 | react ^18 \|\| ^19 |
| @sanity/ui | v2 · v3 · v4 | >=2 <5 |
| @sanity/icons | v2 · v3 · v4 · v5 | >=2 <6 |
| fontkit | v2+ — optional, only needed for GetFontData and UtilitiesDesk | ^2.0.0 |
Why @sanity/ui stops at <5 even though Sanity goes to v6
This is not a mistake in the peer range: Studio v6 ships @sanity/ui v4, not v5. The @sanity/ui cap tracks that library's own major, which lags the Studio's major. >=2 <5 is exactly right for a package that supports Studio v3 through v6.
How one build spans four Studio majors
Two upstream breaking changes had to be absorbed:
@sanity/uiv4 movedTooltip,Menu,MenuButton,MenuItem,Code,Popover,Autocomplete,ToastanduseToastout of the package root and into subpath entries.@sanity/iconsv5 removed every named*Iconexport.
The trap is that both packages still declare the removed names in their .d.ts files, typed never. So import { Tooltip } from '@sanity/ui' type-checks, compiles, passes CI — and is undefined at runtime. A green build proves the code links, not that it renders.
This package therefore imports no @sanity/ui or @sanity/icons symbol directly. Every component imports from @overpunch/sanity-ui-compat (root for UI, /icons for icons), which resolves the installed namespace at runtime:
import { Stack, Card, Button } from '@overpunch/sanity-ui-compat'
import { TrashIcon, LockIcon } from '@overpunch/sanity-ui-compat/icons'If you are patching this package, keep it that way — swapping these for direct named imports reintroduces the silent runtime failure.
Verification status
Honest accounting of what "v3–v6" rests on:
- ✅ Peer ranges declared and consistent across the
@overpunchplugin family. - ✅
npm run build(esbuild → ESM) succeeds. - ✅
npm test— 53 tests across 5 files passing (vitest). - ✅ Running in three in-house Studios (Darden, TDF, MCKL).
- ⚠️
npm run typecheckcurrently reports 16 pre-existing errors (tsconfiglibpredatesString.replaceAll, missingfontkittypes,ObjectInspectorprop strictness, and@sanity/uiv4StackPropsnot declaring thespacespelling the compat translates at runtime). These do not block the build, which strips types. - ❌ Not exercised in a running Sanity v6 Studio beyond those in-house Studios. Treat v6 as supported-by-construction, not certified.
Known documentation gaps
Two things a maintainer needs to resolve — recorded here rather than left as silent breakage:
The npm page shows a broken architecture image. This repository is private, but the package is published publicly on npm.
raw.githubusercontent.comreturns 404 for private repos, so the SVG fallback cannot load for npm visitors (and neither can the repository link below). Fix by either making the repo public, or removing the image and relying on the Mermaid block for internal readers.No screenshot of the Utilities desk. Sanity Studio UI cannot be captured headlessly, so this needs a manual grab. Two shots would carry most of the value:
assets/desk.png— the Utilities desk with its searchable sidebar and category grouping.assets/danger-mode.png— a destructive utility with the danger-mode lock engaged.
Save under
assets/(already excluded from the npm tarball via thefilesallowlist) and embed with an absolute URL — noting gap 1 applies until the repo is public.
Links
- npm: https://www.npmjs.com/package/@overpunch/sanity-type-foundry-utilities
- Repository: https://github.com/over-punch/sanity-type-foundry-utilities (private — Liiift Studio org access required)
- Publishing & integration guide: SETUP.md
License
MIT © Liiift Studio. Maintained for internal Liiift Studio foundry projects.
Support
For issues or questions, please contact the Liiift Studio development team.
