Entity meta
The Entity and File models (see Entities & hierarchy) each have a nullable JSON column,
meta, for your own data. arocapi never puts meta in
an API response, so it can hold storage locations and internal flags.
| Column | Passed to | Typical use |
|---|---|---|
Entity.meta |
both storage halves, and your entityVisibilityFilter can query it |
Where the RO-Crate metadata is stored; visibility flags such as drafts. |
File.meta |
the storage backend’s content half |
Where the file’s bytes are stored. |
meta is typed as Prisma’s JsonValue, so narrow it before reading fields.
Storage keys
Section titled “Storage keys”Each reference storage backend reads a default Storage key from meta, unless you supply its locate option. Write
these keys when you index:
| Backend | Content | Metadata | Override |
|---|---|---|---|
DirectoryStorage |
File.meta.storagePath |
Entity.meta.storagePath |
locate.content(file, entity), locate.metadata(entity) |
EntityMetaMetadata |
none (Metadata only) | Entity.meta.rocrate, the RO-Crate metadata object itself |
key |
S3Storage |
File.meta.storageKey |
Entity.meta.storageKey |
locate.content(file, entity), locate.metadata(entity) |
OcflStorage |
File.meta.ocflObject + File.meta.ocflPath |
Entity.meta.ocflObject + Entity.meta.ocflPath (default ro-crate-metadata.json) |
locate.content(file, entity), locate.metadata(entity), returning { object, path } |
Keys are relative to the backend’s root or bucket. An absent key is a 404. A key that isn’t a string, null
included, or that is absolute or has a .. segment, is a 500. EntityMetaMetadata reads no key: the value is the
Metadata, and one that isn’t a JSON object is a 500. OCFL keys are an object id, which the storage layout maps and
isn’t checked for .., and a logical path inside its head version, not a path on disk. The root exports a TypeScript
type for each shape, such as DirectoryStorageMeta:
import type { DirectoryStorageMeta } from 'arocapi';import type { PrismaClient } from './generated/prisma/client.ts';
declare const prisma: PrismaClient;
// Index the item's crate and file with the keys DirectoryStorage reads, relative to its rootawait prisma.entity.update({ where: { id: 'https://example.org/item' }, data: { meta: { storagePath: 'item/ro-crate-metadata.json' } satisfies DirectoryStorageMeta },});await prisma.file.update({ where: { id: 'https://example.org/item/song.wav' }, data: { meta: { storagePath: 'item/song.wav' } satisfies DirectoryStorageMeta },});Visibility flags
Section titled “Visibility flags”A flag in Entity.meta can drive the visibility filters. Mirror it into your search
documents as a declared field with no role, for example draft: { type: 'boolean' }, so the search filter can match
the same entities. In Prisma, a plain not on a
JSON path also excludes rows where meta or the path is null, so match those explicitly:
import type { EntityVisibilityFilter, SearchVisibilityFilter } from 'arocapi';import { Prisma } from './generated/prisma/client.ts';
export const entityVisibilityFilter: EntityVisibilityFilter = () => ({ OR: [{ meta: { path: ['draft'], equals: Prisma.AnyNull } }, { meta: { path: ['draft'], not: true } }],});
// With draft declared as { type: 'boolean' } and indexed from meta.draftexport const searchVisibilityFilter: SearchVisibilityFilter<{ draft: { type: 'boolean' } }> = () => ({ draft: { not: true },});Prisma here is the namespace from your generated Prisma client. JSON path filters can’t use arocapi’s indexes; for
large repositories, store visibility flags in your own indexed columns.