Working with Data Sources
Working with Data Sources
Applications are only as useful as the data they reach. The Application Designer connects to the systems your business already runs on, and gates every call so apps can only touch what they are allowed to.
Source types
- Lookup tables — structured reference and operational data managed in DataMagik.
- ODBC / SQL queries — saved queries against external databases through the platform connector.
- Scripts — V8 scripts that run server-side to fetch, transform, or write data and call other systems.
- Serial series — traceability series your app can preview and generate from.
- Printers — declared printers your app can submit labels and documents to.
Behind these, the platform also reaches Plex Manufacturing Cloud data sources and external REST APIs (from scripts), with credentials managed centrally — secrets are never hardcoded in an app.
Declared resources
An app may only use resources it declares. This single list powers two things at once: the autocomplete surface while you build, and the server-side authorization on every request at runtime. Undeclared resources are refused (not_declared).
For layout apps you grant data sources in the designer. For SPA apps you declare them in dm.config.json, giving each an alias:
{
"appId": 123,
"sources": [
{ "sourceId": 17, "type": "lookup_table", "alias": "parts" },
{ "sourceId": 7, "type": "odbc_query", "alias": "openOrders" },
{ "sourceId": 42, "type": "script", "alias": "postReceipt" }
],
"serialSeries": [{ "seriesId": 3, "alias": "lotSerial" }],
"printers": [{ "printerId": 11, "alias": "line1Zebra" }]
}
Aliases must be valid JavaScript identifiers and unique across all categories — they share one registry. You can declare them interactively with dm add; see Installing & Using the CLI.
Using a source in SPA code
After declaring sources and running dm typegen, every alias is typed and autocompletes:
import { dm } from './dm.generated';
await dm.init();
const rows = await dm.data.query('parts'); // typed rows
const ok = await dm.scripts.run('postReceipt', { poNumber: 'PO-1', quantity: 5 });
const sn = await dm.serials.generate('lotSerial', { PART: 'P-100' });
await dm.print.submit('line1Zebra', { format: 'zpl', data: label });
See the full surface in The App SDK Reference, and how access is enforced in Permissions & Access Control.