@dg-eam/plugin-sdk
v1.6.0
Published
`@dg-eam/plugin-sdk` provides the supported interface for App Manager plugins. It supports `entry.editor` and `menu.page` placements.
Readme
App Manager Plugin SDK
@dg-eam/plugin-sdk provides the supported interface for App Manager plugins.
It supports entry.editor and menu.page placements.
SDK 1.6.0 adds environment role-based feature access and entry-change notifications.
These features require App Manager runtime 1.5.0; existing operations remain compatible with runtime 1.2.0 onward.
Both supportedPlacements and legacy locations manifests are supported.
Install
npm install --save-exact @dg-eam/[email protected]import { createPluginClient } from "@dg-eam/plugin-sdk";
const app = createPluginClient();
const session = await app.connect();CommonJS is also supported:
const { createPluginClient } = require("@dg-eam/plugin-sdk");Feature access and cross-tab updates
Declare features in plugin.json with id, label, optional description, defaultRoles, and optional capabilities.
Administrators map each feature to environment roles in placement settings. The default is ["admins"]; an empty array denies access.
Roles use stable IDs: admins, editors, publishers, viewers, and customRole1Users through customRole5Users.
await app.permissions.get();
const showSettings = app.permissions.can("settings");
const canEdit = app.hasCapability("entries:update");
const stopPermissions = app.onPermissionsChange(updateControls);
const stopEntries = app.onEntriesChange(refreshRecords);Capabilities attached to a denied feature are blocked server-side; grants never expand the user's data permissions. Features without capabilities control plugin UI. Unknown features deny access. Refresh permissions before configuration actions. Entry notifications contain no record data. Refetch through the SDK, defer during writes, and preserve unsaved fields. Keep focus refresh as a fallback; broadcasts only cross tabs on the same App Manager origin. Call both unsubscribe functions on teardown.
Static JavaScript
The package includes:
dist/eam-plugin-sdk.min.jsdist/eam-plugin-sdk.min.js.sha384
Copy the JavaScript file into the plugin bundle and use the matching SHA-384 value for Subresource Integrity:
<script
src="./vendor/eam-plugin-sdk.min.js"
integrity="sha384-COPY_THE_MATCHING_VALUE"
crossorigin="anonymous"
></script>const app = window.EAMPluginSDK.createPluginClient();
const session = await app.connect();Pin an exact SDK version for released plugins. The manifest must declare
sdk.minVersion as 1.2.0 or newer. Plugins using entries.setStatus require
SDK package 1.5.0 and manifest runtime 1.4.0 or newer. Build and test these
plugins with CLI 1.2.0 or newer.
Context and events
let context = session.context;
document.documentElement.dataset.theme = session.theme;
const stopTheme = app.onThemeChange(({ theme }) => {
document.documentElement.dataset.theme = theme;
});
const stopContext = app.onContextChange(({ context: nextContext }) => {
context = nextContext;
});
// On unmount:
stopTheme();
stopContext();
app.destroy();Operations
| Operation | Required permission |
| --- | --- |
| models.read | models:read |
| entries.list | entries:list |
| entries.read | entries:read |
| entries.create | entries:create |
| entries.update | entries:update |
| entries.setStatus | entries:status |
| media.pick | media:read |
| navigation.openEntry | None |
| ui.notify | None |
| ui.confirm | None |
| editor.setDirty | None |
Use the latest entry revision when saving:
const entry = await app.entries.read({
entryId: context.entry.id,
modelId: context.model.id,
includeLinked: true,
depth: 2,
});
await app.editor.setDirty(true);
await app.entries.update({
entryId: context.entry.id,
modelId: context.model.id,
revision: entry.revision,
data: { title: "Updated title" },
});
await app.editor.setDirty(false);Publish or unpublish an entry when the installation grants status access:
await app.entries.setStatus({
entryId: context.entry.id,
modelId: context.model.id,
status: "Published", // or "Draft"
});Create a draft entry inside an approved model scope:
const created = await app.entries.create({
modelId: "offerDefinition",
label: "World Cup annual offer",
data: {
title: { "en-US": "World Cup annual offer" },
},
});menu.page placements can approve multiple model scopes. Their ids are available
at session.context.configuration.menu.modelIds. Every model operation must use
one of those ids; App Manager rejects all other models.
Available event subscriptions:
onThemeChangeonContextChange
Security requirements
- Use SDK operations for App Manager data and navigation.
- Request only the permissions the plugin uses.
- Do not access the parent page, cookies, storage, or credentials.
- Do not include passwords, tokens, API keys, or other secrets in plugin files.
- External network calls must use explicitly approved, credential-free public endpoints.
These restrictions describe integrated and sandboxed external plugins. A Super Admin can approve a trusted external app when it requires its own authentication, cookies, storage, forms, popups, downloads, or network access. Trusted apps still cannot access the App Manager page or receive App Manager credentials. The SDK remains permission-controlled and is optional in trusted runtime mode.
Local testing and packaging
npx @dg-eam/[email protected] dev .
npx @dg-eam/[email protected] package .See the App Manager documentation under User > Developer > Documents > Plugin Documentation for manifests, deployment, UI tokens, and lifecycle guidance.
License
Copyright (c) 2026 DIAGNAL. All rights reserved. This SDK is proprietary and may be used only under applicable DIAGNAL terms or written authorization.
