@moongait/dam-picker
v0.2.1
Published
Embeddable web component for selecting assets from MoonDAM. Built with [Lit](https://lit.dev/).
Readme
@moongait/dam-picker
Embeddable web component for selecting assets from MoonDAM. Built with Lit.
Inline file-manager UI that lets users browse folders, preview and select assets, and receive signed imgproxy URLs ready for use. Also supports single-file download, batch ZIP download, copy-URL, upload, tag, and folder management (permission-gated).
Features
- Browse & preview — folder tree, breadcrumb nav, side preview panel with image fill-to-viewport
- Select — single or multi-select (via
multi-selectattribute) - Download — signed original for the current asset; multi-selection bundles into a ZIP (hand-rolled store-mode encoder, no external deps)
- Copy URL — writes a signed imgproxy URL to the clipboard
- Upload — drag-drop or click, with post-upload RLS validation
- Manage — create subfolders, tag assets, delete (all permission-gated by folder role)
- Auth — API key → short-lived JWT exchange, auto-refresh on 401
Install
npm install @moongait/dam-pickerUsage
Via npm (bundled apps)
import '@moongait/dam-picker'Via CDN (plain HTML)
<script type="module" src="https://cdn.jsdelivr.net/npm/@moongait/dam-picker/dist/dam-picker.js"></script>Add the element
<dam-picker
supabase-url="https://your-project.supabase.co"
supabase-anon-key="your-anon-key"
api-key="dk_your_api_key_here"
></dam-picker>Listen for events
const picker = document.querySelector('dam-picker')
// User confirmed a selection (single-select: on "Use asset"; multi-select: on "Use Selected")
picker.addEventListener('dam-picker:select', (e) => {
const { assets, transforms } = e.detail
console.log(assets[0].transformedUrl) // signed imgproxy URL
})
// Auth / network / permission error
picker.addEventListener('dam-picker:error', (e) => {
console.error(e.detail.code, e.detail.message)
})Attributes
| Attribute | Type | Default | Description |
| ------------------ | --------- | ------- | ------------------------------------------------ |
| supabase-url | string | '' | Supabase project URL |
| supabase-anon-key| string | '' | Supabase anon/public key |
| api-key | string | '' | API key (auto-exchanges for a short-lived JWT) |
| folder-id | string | '' | Pre-select a folder on open |
| multi-select | boolean | false | Allow selecting multiple assets |
| transforms | string | '' | Image transforms, e.g. "w:800,h:600,f:webp,q:80" |
Events
| Event | Detail | Description |
| -------------------- | ------------------------------------ | ---------------------------------- |
| dam-picker:select | { assets: DamAsset[], transforms } | User confirmed selection |
| dam-picker:error | { code, message } | Auth, network, or permission error |
DamAsset
interface DamAsset {
id: string
name: string
storage_path: string
mime_type: string
size_bytes: number
width: number | null
height: number | null
url: string // raw storage path
transformedUrl: string // signed imgproxy URL with transforms applied
}Authentication
The picker authenticates via API key. Your app passes an api-key attribute, and the picker auto-exchanges it for a short-lived JWT (15 min) via the exchange-token Edge Function. When the token expires, the picker re-exchanges automatically.
Generate API keys via the admin app (Users & Access page) or directly in Supabase Studio.
<dam-picker
supabase-url="https://your-project.supabase.co"
supabase-anon-key="your-anon-key"
api-key="dk_your_api_key_here"
></dam-picker>If the API key is invalid or expired, the picker emits a dam-picker:error event with code: 'auth_expired'.
Permissions
Access is granted per-folder. A user can hold different roles in different folders (e.g. owner on /marketing, viewer on /engineering). The picker reads the role on the current folder and enables/disables controls accordingly.
| Capability | Viewer | Editor | Owner | | ------------------------------- | :----: | :----: | :---: | | Browse folder | ✓ | ✓ | ✓ | | Preview assets | ✓ | ✓ | ✓ | | Select / "Use" asset | ✓ | ✓ | ✓ | | Download / Copy URL | ✓ | ✓ | ✓ | | Upload assets | — | ✓ | ✓ | | Create subfolders | — | ✓ | ✓ | | Add / remove tags | — | ✓ | ✓ | | Delete assets | — | — | ✓ | | Delete folder | — | — | ✓ |
Users flagged as admin in profiles.is_admin bypass these checks and see all folders with full control. Grants are managed in the admin app.
Publishing to npm
Release checklist (run from packages/dam-picker):
# 1. Bump version (follow semver: patch/minor/major).
# --no-git-tag-version keeps the bump local so we can create a monorepo-style tag in step 6.
pnpm version patch --no-git-tag-version # 0.2.0 → 0.2.1
# or: pnpm version minor --no-git-tag-version # 0.2.0 → 0.3.0
# or: pnpm version major --no-git-tag-version # 0.2.0 → 1.0.0
# 2. Clean build + verify bundle
rm -rf dist && pnpm build
ls -lh dist/ # sanity check: dam-picker.js + .d.ts present
# 3. Dry-run the publish to see what gets shipped
npm publish --dry-run --access public
# 4. Login if needed (first time or after token expiry)
npm whoami || npm login
# 5. Publish
npm publish --access public
# 6. Commit + tag + push
git add package.json
git commit -m "release: dam-picker v$(node -p "require('./package.json').version")"
git tag "dam-picker@$(node -p "require('./package.json').version")"
git push && git push --tagsAfter publish:
- jsdelivr/unpkg CDNs pick up the new version within a few minutes.
- Verify:
curl -I https://cdn.jsdelivr.net/npm/@moongait/dam-picker@<version>/dist/dam-picker.js - Downstream apps pinning
^0.2.0get the update on next install; host apps using the CDN URL should bump the version in their<script src>tag if they pin a specific version.
Before releasing
- Run
pnpm exec tsc --noEmit— no new type errors. - Run
pnpm build— bundle size should stay under ~20KB gzipped (hard limit: the picker is meant to be lightweight; flag PRs that push it above). - Test against a live Supabase stack via the dev harness (
pnpm dev) or the admin-app E2E path. - Update this README if you changed public attributes, events, or the
DamAssetshape — those are the API contract.
Development
pnpm dev # starts Vite dev server with index.html test harness