Plugin SDK overview
What a plugin does
Section titled “What a plugin does”UniBox is not an inventory database. Your inventory lives in a system you already run, and that system stays the source of truth. UniBox binds a physical box to an opaque QR code, then lets you scan, search and find things. A plugin is the adapter that lets UniBox read one kind of inventory system: it signs in, lists containers (places), lists the items in them, and optionally searches.
A plugin only reads. Creating, editing and deleting inventory stays in the source system.
The boundary
Section titled “The boundary”┌────────────────────────┐ normalized types ┌─────────────────────┐│ UniBox app │ ◄─────────────────── │ Your plugin ││ scanning, search, │ InventoryContainer │ talks HTTP; knows ││ cache, camera, labels │ InventoryItem │ the remote API │└────────────────────────┘ IntegrationError └──────────┬──────────┘ │ its own DTOs │ stay in here ┌──────────▼──────────┐ │ Your inventory │ │ system │ └─────────────────────┘The rule that makes this work: nothing specific to your system may leave the plugin. The app never sees a remote DTO,
an endpoint path, a raw fetch error, or a provider-specific field name. The plugin maps everything to the SDK’s normalized
types, and everything else in UniBox consumes only those.
| Crosses the boundary | Never crosses it |
|---|---|
InventoryContainer, InventoryItem, search results |
Remote DTOs or class instances |
IntegrationError with a normalized code |
Raw exceptions, HTTP libraries’ error objects |
metadata: plain JSON data you choose to keep |
Functions, class instances, anything that is not JSON |
| A setup form described as data (the manifest) | Your own UI for connecting |
The contract test suite enforces this: it fails a plugin whose results carry unknown fields, class instances, or non-JSON metadata.
The pieces
Section titled “The pieces”| Piece | What it is | Page |
|---|---|---|
| Manifest | Name, capabilities and the setup form, as data | Manifest and setup |
| Runtime | The connection and the read operations | The runtime |
| Domain types | The normalized shapes you return | Domain types |
| Errors | One vocabulary for everything that can go wrong | Errors |
| Context | HTTP, secure storage, cache, logger, clock | Services and context |
| Contract suite | The behavioural tests every plugin must pass | Testing |
How a plugin is added today
Section titled “How a plugin is added today”Plugins are compile-time registrations: you build a plugin package and register it when the app is assembled. There is no runtime loading of third-party plugins yet. A plugin package depends only on the SDK, never on UniBox’s core or on another plugin.
import { createIntegrationRegistry } from '@unibox-cam/integration-sdk'import { shelfiePlugin } from '@unibox-cam/integration-example'
const registry = createIntegrationRegistry()registry.register(shelfiePlugin) // throws if the same id is registered twiceReady to build one? Follow the tutorial.