Resource Mapper
PropertyResourceMapper lets users map a remote resource's field schema to custom values. It supports two modes: manual mode (a dynamic form where each field gets a typed input, with the field list fetched live from an API) and auto mode (a free-form JSON editor with expression support for programmatic mapping).
PropertyResourceMapper
interface PropertyResourceMapper extends PropertyBase {
type: "resource_mapper"
/** Name of the method in resource_mapping used to fetch available fields. */
mapping_method: string
/** Default value. */
default?: ResourceMapperValue | null
}| Field | Type | Description |
|---|---|---|
type | "resource_mapper" | Property type identifier |
mapping_method | string | References a method in ToolDefinition.resource_mapping |
default | ResourceMapperValue | Optional default value |
NOTE
resource_mapper is only supported in Tool parameters.
ResourceMapperValue
The value stored at runtime for a resource_mapper parameter:
interface ResourceMapperValue {
__type__: "resource_mapper"
/** The mode that was active when this value was set. */
mapping_mode: "manual" | "auto"
/**
* Manual mode: Record<fieldId, fieldValue> — one entry per mapped field.
* Auto mode: a JSON object or a string (an expression or input that could not be parsed as an object).
*/
value: Record<string, unknown> | string | null
}ToolResourceMappingField
The structure of each field returned by a resource_mapping callback:
interface ToolResourceMappingField {
/** Unique field identifier, used as the key in the mapped value. */
id: string
/** Human-readable label shown in the UI; falls back to id if not set. */
display_name?: I18nText | null
/** Field value type — determines which input component is rendered in manual mode. */
type: "string" | "number" | "integer" | "boolean" | "object" | "array"
/** Whether the field is required. Required fields cannot be removed in manual mode. */
required?: boolean | null
/** Optional field-level hint shown next to the input field in manual mode. */
ui?: {
hint?: I18nText | null
} | null
}resource_mapping Callback
Implement a method in ToolDefinition.resource_mapping whose key matches mapping_method. This function is called when the mapper mounts and whenever an upstream parameter referenced by depends_on changes:
type ToolResourceMappingFunction = (input: {
args: {
/** Current tool parameters, used to query the target resource's schema. */
parameters: Record<string, unknown>
credentials: Record<string, InputArgsCredential>
}
}) => Promise<{
/** List of available fields the user can map. */
fields: Array<ToolResourceMappingField>
/** Optional message shown when the field list is empty. */
empty_fields_notice?: I18nText | null
}>Register the function in ToolDefinition.resource_mapping:
const myTool: ToolDefinition = {
name: "my-tool",
parameters: [ /* ... */ ],
resource_mapping: {
map_record_fields: async ({ args }) => {
const token = args.credentials["my-credential"].api_key
const tableId = extractResourceLocator(args.parameters.table)
if (!tableId) {
return {
fields: [],
empty_fields_notice: { en_US: "Select a table first.", zh_Hans: "请先选择一张表。" },
}
}
const schema = await apiClient.getTableSchema(token, tableId)
return {
fields: schema.columns.map(col => ({
id: col.id,
display_name: { en_US: col.name },
type: col.dataType,
required: col.required,
ui: {
hint: col.description ? { en_US: col.description } : null,
},
})),
}
},
},
invoke: async ({ args }) => { /* ... */ },
}depends_on Cascading
IMPORTANT
When the available fields depend on another parameter (e.g., columns of a selected table), always declare depends_on on the mapper. This causes the UI to re-fetch the field schema and reset the mapping when the referenced parameter changes.
In the schema, depends_on is only supported on resource_locator and resource_mapper. The upstream parameters it references should be string, number / integer, boolean, or resource_locator properties.
const fieldsParam: PropertyResourceMapper = {
name: "fields",
type: "resource_mapper",
display_name: { en_US: "Fields", zh_Hans: "字段" },
required: true,
depends_on: ["workspace", "table"], // Re-fetch when either changes
mapping_method: "map_record_fields",
}Read upstream parameters from parameters in the resource_mapping callback to determine which schema to query:
resource_mapping: {
map_record_fields: async ({ args }) => {
const tableId = extractResourceLocator(args.parameters.table)
if (!tableId) return { fields: [], empty_fields_notice: { en_US: "Select a table first.", zh_Hans: "请先选择一张表。" } }
// Fetch and return the schema for that table
},
},Using extractResourceMapper
The SDK provides a helper to extract the field mapping object from a ResourceMapperValue:
import { extractResourceMapper } from "@choiceopen/atomemo-plugin-sdk-js"
invoke: async ({ args }) => {
const { parameters } = args
// Returns Record<string, unknown> | null
const fieldValues = extractResourceMapper(parameters.fields)
if (fieldValues) {
// { "name": "Alice", "age": 30, "active": true }
await apiClient.createRecord(fieldValues)
}
}| Parameter | Type | Description |
|---|---|---|
value | unknown | Raw parameter value (validated internally via Zod) |
Returns Record<string, unknown> | null. Throws an error when:
- The value fails schema validation
- The value is a plain string (a string in
ResourceMapperValue.valuerepresents an expression or input that could not be parsed as an object — if the tool receives a string, the expression was not successfully evaluated to an object, or the editor input was an invalid JSON object)
UI Behavior
The field renders as a block with a mapping mode selector:
Manual Mode
The UI calls
resource_mappingon mount (and when anydepends_onparameter changes) to load available fields.Each field renders as a typed input row with a remove button (×):
Field type Input component stringText input number/integerNumber input booleanToggle switch object/arrayJSON code editor Required fields cannot be removed.
If a field definition includes
ui.hint, the hint is shown below that field's input row.An Add Field dropdown lists all optional fields that have been removed, allowing the user to restore them.
If no fields are available, the
empty_fields_noticereturned by the callback is displayed.
Auto Mode
Renders a JSON code editor with expression input enabled (support_expression is always on). The user provides the complete mapping as a JSON object or an expression string.