UNPKG

@appsemble/utils

Version:

Utility functions used in Appsemble internally

117 lines 5.2 kB
import { iterApp, } from '@appsemble/lang-sdk'; import { normalize } from './normalize.js'; /** * Recursively find `string.format` remapper message IDs. * * @param obj The object to search. * @returns All message IDs found */ export function findMessageIds(obj) { if (!obj || typeof obj !== 'object') { return {}; } if (Array.isArray(obj)) { return Object.assign({}, ...obj.map((item) => findMessageIds(item))); } const entries = Object.entries(obj); // Remappers throw if multiple keys are defined, so this means it’s not a remapper. if (entries.length === 1) { const [[key, value]] = entries; if (key === 'string.format' && typeof value?.messageId === 'string') { return { [value.messageId]: value.template ?? '', ...findMessageIds(value.values) }; } if (key === 'translate' && typeof value === 'string') { return { [value]: '' }; } } return Object.assign({}, ...entries.map(([, value]) => findMessageIds(value))); } /** * Extract translatable message IDs from an app definition. * * @param app The app definition to extract message IDs from * @param onBlock A function to extract block messages. This is needed, because block messages may * be extracted based on different contexts. * @returns A list of message IDs */ export function extractAppMessages(app, onBlock) { const messages = { app: { name: app.name, description: app.description ?? '', ...Object.fromEntries(Object.entries(app.security?.roles ?? {}).flatMap(([role, roleDefinition]) => [ [`app.roles.${role}`, role], [`app.roles.${role}.description`, roleDefinition.description], ])), }, messageIds: {}, }; iterApp(app, { onBlock(block, prefix) { Object.assign(messages.messageIds, findMessageIds(block.header), findMessageIds(block.parameters)); if (onBlock) { const normalizedPrefix = prefix.map((entry, index) => index === 1 ? normalize(app.pages[entry].name) : entry); onBlock(block, normalizedPrefix); } }, onAction(action) { Object.assign(messages.messageIds, findMessageIds(action.remapBefore)); Object.assign(messages.messageIds, findMessageIds(action.remapAfter)); switch (action.type) { case 'condition': Object.assign(messages.messageIds, findMessageIds(action.if)); Object.assign(messages.messageIds, findMessageIds(action.then)); Object.assign(messages.messageIds, findMessageIds(action.else)); break; case 'dialog': Object.assign(messages.messageIds, findMessageIds(action.title)); break; case 'email': Object.assign(messages.messageIds, findMessageIds(action.attachments), findMessageIds(action.bcc), findMessageIds(action.body), findMessageIds(action.cc), findMessageIds(action.subject), findMessageIds(action.to)); break; case 'flow.to': Object.assign(messages.messageIds, findMessageIds(action.step)); break; case 'message': Object.assign(messages.messageIds, findMessageIds(action.body)); break; case 'request': case 'resource.count': case 'resource.create': case 'resource.delete': case 'resource.get': case 'resource.query': case 'resource.update': Object.assign(messages.messageIds, findMessageIds(action.body), findMessageIds(action.query), findMessageIds(action.url)); break; case 'share': Object.assign(messages.messageIds, findMessageIds(action.text), findMessageIds(action.title), findMessageIds(action.url)); break; default: } }, onPage(page) { const prefix = `pages.${normalize(page.name)}`; messages.app[prefix] = page.name; if (page.type === 'tabs' && Array.isArray(page.tabs)) { for (const [index, tab] of page.tabs.entries()) { messages.app[`${prefix}.tabs.${index}`] = (typeof tab.name === 'string' ? tab.name : '') ?? ''; } } if (page.type === 'flow') { for (const [index, step] of page.steps.entries()) { messages.app[`${prefix}.steps.${index}`] = (typeof step.name === 'string' ? step.name : '') ?? ''; } } if (page.type === 'loop') { messages.app[`${prefix}.steps.first`] = 'first'; messages.app[`${prefix}.steps`] = 'step'; messages.app[`${prefix}.steps.last`] = 'last'; } }, }); return messages; } //# sourceMappingURL=appMessages.js.map