UNPKG

@crowdin/app-project-module

Version:

Module that generates for you all common endpoints for serving standalone Crowdin App

568 lines (567 loc) 31.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = handle; const types_1 = require("../types"); const util_1 = require("../util"); const subscription_1 = require("../util/subscription"); const normalize_module_1 = require("../util/normalize-module"); const api_1 = require("./api/api"); const util_2 = require("./workflow-step-type/util"); const index_1 = require("./automation-action/util/index"); const ai_request_processors_1 = require("./ai-request-processors"); const key_1 = require("./advisor-inspector/key"); function normalizeEnvironments(environments) { if (Array.isArray(environments)) { return environments; } return [environments]; } function handle(config) { const modules = {}; if (config.projectIntegration) { // prevent possible overrides of the other modules config.projectIntegration = Object.assign(Object.assign({}, config.projectIntegration), { key: config.identifier + '-int' }); modules['project-integrations'] = [ Object.assign({ key: config.projectIntegration.key, name: config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config, config.projectIntegration, '/integration'), url: '/' }, (!!config.projectIntegration.environments && { environments: normalizeEnvironments(config.projectIntegration.environments), })), ]; } if (config.customFileFormat) { config.customFileFormat = config.customFileFormat.map((item) => (Object.assign({}, item))); const items = config.customFileFormat; const isSingle = items.length === 1; modules['custom-file-format'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'ff', item, index, isSingle }); item.key = key; return { key, type: item.type, stringsExport: !!item.stringsExport, multilingual: !!item.multilingual, customSrxSupported: !!item.customSrxSupported, extensions: item.extensions, signaturePatterns: item.signaturePatterns, multilingualExport: item.multilingualExport, url: isSingle ? '/file/process' : `/file/${key}/process`, }; }); } if (config.filePreImport) { config.filePreImport = config.filePreImport.map((item) => (Object.assign({}, item))); const items = config.filePreImport; const isSingle = items.length === 1; modules['file-pre-import'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'pri', item, index, isSingle }); item.key = key; return { key, signaturePatterns: item.signaturePatterns, url: isSingle ? '/pre-import' : `/pre-import/${key}`, }; }); } if (config.filePostImport) { config.filePostImport = config.filePostImport.map((item) => (Object.assign({}, item))); const items = config.filePostImport; const isSingle = items.length === 1; modules['file-post-import'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'poi', item, index, isSingle }); item.key = key; return { key, signaturePatterns: item.signaturePatterns, url: isSingle ? '/post-import' : `/post-import/${key}`, }; }); } if (config.filePreExport) { config.filePreExport = config.filePreExport.map((item) => (Object.assign({}, item))); const items = config.filePreExport; const isSingle = items.length === 1; modules['file-pre-export'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'pre', item, index, isSingle }); item.key = key; return { key, signaturePatterns: item.signaturePatterns, url: isSingle ? '/pre-export' : `/pre-export/${key}`, }; }); } if (config.filePostExport) { config.filePostExport = config.filePostExport.map((item) => (Object.assign({}, item))); const items = config.filePostExport; const isSingle = items.length === 1; modules['file-post-export'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'poe', item, index, isSingle }); item.key = key; return { key, signaturePatterns: item.signaturePatterns, url: isSingle ? '/post-export' : `/post-export/${key}`, }; }); } if (config.fileTranslationsAlignmentExport) { config.fileTranslationsAlignmentExport = config.fileTranslationsAlignmentExport.map((item) => (Object.assign({}, item))); const items = config.fileTranslationsAlignmentExport; const isSingle = items.length === 1; modules['file-translations-alignment'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'ftae', item, index, isSingle }); item.key = key; return { key, signaturePatterns: item.signaturePatterns, url: isSingle ? '/translations-alignment' : `/translations-alignment/${key}`, }; }); } if (config.customMT) { config.customMT = config.customMT.map((item) => (Object.assign({}, item))); const items = config.customMT; const isSingle = items.length === 1; modules['custom-mt'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'mt', item, index, isSingle }); item.key = key; return Object.assign(Object.assign(Object.assign(Object.assign({ key, name: config.name, logo: (0, util_1.getLogoUrl)(config, item, isSingle ? '/mt' : `/mt-${key}`), url: isSingle ? '/mt/translate' : `/mt/${key}/translate`, withContext: !!item.withContext }, ((0, util_1.isDefined)(item.splitStringsIntoChunks) && { splitStringsIntoChunks: item.splitStringsIntoChunks, })), ((0, util_1.isDefined)(item.batchSize) && { batchSize: item.batchSize, })), ((0, util_1.isDefined)(item.maskEntities) && { maskEntities: item.maskEntities, })), (!!item.environments && { environments: normalizeEnvironments(item.environments), })); }); } if (config.organizationMenu) { config.organizationMenu = config.organizationMenu.map((item) => (Object.assign({}, item))); const items = config.organizationMenu; const isSingle = items.length === 1; modules['organization-menu'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'resources', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/organization-menu' : `/organization-menu-${key}`; return { key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/resources' : `/organization-menu-${key}`), }; }); } if (config.organizationSettingsMenu) { config.organizationSettingsMenu = config.organizationSettingsMenu.map((item) => (Object.assign({}, item))); const items = config.organizationSettingsMenu; const isSingle = items.length === 1; modules['organization-settings-menu'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'organization-settings-menu', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/organization-settings' : `/organization-settings-${key}`; return { key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/organization-settings' : `/organization-settings-${key}`), }; }); } if (config.profileResourcesMenu) { config.profileResourcesMenu = config.profileResourcesMenu.map((item) => (Object.assign({}, item))); const items = config.profileResourcesMenu; const isSingle = items.length === 1; modules['profile-resources-menu'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'profile-resources-menu', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/profile-resources' : `/profile-resources-${key}`; return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/profile-resources' : `/profile-resources-${key}`) }, (!!item.environments && { environments: normalizeEnvironments(item.environments), })); }); } if (config.profileSettingsMenu) { config.profileSettingsMenu = config.profileSettingsMenu.map((item) => (Object.assign({}, item))); const items = config.profileSettingsMenu; const isSingle = items.length === 1; modules['profile-settings-menu'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'profile-settings-menu', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/profile-settings' : `/profile-settings-${key}`; return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), icon: (0, util_1.getLogoUrl)(config, item, isSingle ? '/profile-settings' : `/profile-settings-${key}`) }, (!!item.environments && { environments: normalizeEnvironments(item.environments), })); }); } if (config.editorRightPanel) { config.editorRightPanel = config.editorRightPanel.map((item) => (Object.assign({}, item))); const items = config.editorRightPanel; const isSingle = items.length === 1; modules['editor-right-panel'] = items.map((item, index) => { var _a; const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'editor-panels', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/editor-panels' : `/editor-panels-${key}`; return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), supportsMultipleStrings: (_a = item.supportsMultipleStrings) !== null && _a !== void 0 ? _a : false, modes: item.modes }, (!!item.environments && { environments: normalizeEnvironments(item.environments), })); }); } if (config.projectMenu) { config.projectMenu = config.projectMenu.map((item) => (Object.assign({}, item))); const items = config.projectMenu; const isSingle = items.length === 1; modules['project-menu'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'project-menu', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/project-menu' : `/project-menu-${key}`; return Object.assign({ key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html') }, (!!item.environments && { environments: normalizeEnvironments(item.environments), })); }); } if (config.projectMenuCrowdsource) { config.projectMenuCrowdsource = config.projectMenuCrowdsource.map((item) => (Object.assign({}, item))); const items = config.projectMenuCrowdsource; const isSingle = items.length === 1; modules['project-menu-crowdsource'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'project-menu-crowdsource', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/project-menu-crowdsource' : `/project-menu-crowdsource-${key}`; return { key, name: item.name || config.name, url: basePath + '/' + (item.fileName || 'index.html'), }; }); } if (config.projectTools) { config.projectTools = config.projectTools.map((item) => (Object.assign({}, item))); const items = config.projectTools; const isSingle = items.length === 1; modules['project-tools'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'tools', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/tools' : `/tools-${key}`; return Object.assign({ key, name: item.name || config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config, item, isSingle ? '/tools' : `/tools-${key}`), url: basePath + '/' + (item.fileName || 'index.html') }, (!!item.environments && { environments: normalizeEnvironments(item.environments), })); }); } if (config.projectReports) { config.projectReports = config.projectReports.map((item) => (Object.assign({}, item))); const items = config.projectReports; const isSingle = items.length === 1; modules['project-reports'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'project-reports', item, index, isSingle, }); item.key = key; const basePath = isSingle ? '/reports' : `/reports-${key}`; return { key, name: item.name || config.name, description: config.description, logo: (0, util_1.getLogoUrl)(config, item, isSingle ? '/reports' : `/reports-${key}`), url: basePath + '/' + (item.fileName || 'index.html'), }; }); } if (config.modal) { const modals = config.modal.map((modal, index) => { const moduleKey = modal.key || `${config.identifier}-modal-${index}`; return Object.assign({ key: moduleKey, name: modal.name || config.name, url: modal.url || `/modal-${moduleKey}/` + (modal.fileName || 'index.html') }, (!!modal.environments && { environments: normalizeEnvironments(modal.environments) })); }); modules['modal'] = modals; } if (config.chat) { const chats = config.chat.map((chat, i) => { const moduleKey = chat.key || `${config.identifier}-chat-${i}`; return Object.assign({ key: moduleKey, name: chat.name || config.name, url: chat.url || `/chat-${moduleKey}/` + (chat.fileName || 'index.html') }, (!!chat.environments && { environments: normalizeEnvironments(chat.environments) })); }); modules['chat'] = chats; } if (config.contextMenu) { const contextMenus = config.contextMenu.map((contextMenu, index) => { const moduleKey = contextMenu.key || `${config.identifier}-context-menu-${index}`; return Object.assign({ key: moduleKey, name: contextMenu.name || config.name, description: config.description, options: Object.assign(Object.assign({ location: contextMenu.location, type: contextMenu.type }, (contextMenu.module && contextMenu.moduleKey ? { module: { [contextMenu.module]: contextMenu.moduleKey, }, } : {})), { url: `/context-${moduleKey}/` + (contextMenu.fileName || 'index.html') }), signaturePatterns: contextMenu.signaturePatterns }, (!!contextMenu.environments && { environments: normalizeEnvironments(contextMenu.environments), })); }); modules['context-menu'] = contextMenus; } if (config.api) { modules['api'] = (0, api_1.getApiManifest)(config, config.api); } if (config.customSpellchecker) { config.customSpellchecker = config.customSpellchecker.map((item) => (Object.assign({}, item))); const items = config.customSpellchecker; const isSingle = items.length === 1; modules['custom-spellchecker'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'spellchecker', item, index, isSingle, }); item.key = key; const base = isSingle ? '/spellchecker' : `/spellchecker/${key}`; const uiModule = item.settingsUiModule; return Object.assign(Object.assign({ key, name: item.name || config.name, description: item.description || config.description, listSupportedLanguagesUrl: `${base}/languages`, checkSpellingUrl: `${base}/spellcheck` }, (!!item.environments && { environments: normalizeEnvironments(item.environments), })), (uiModule ? { url: `${base}/settings/` + (uiModule.fileName || 'index.html') } : {})); }); } if (config.aiProvider) { config.aiProvider = config.aiProvider.map((item) => (Object.assign({}, item))); const items = config.aiProvider; const isSingle = items.length === 1; modules['ai-provider'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'aiprovider', item, index, isSingle, }); item.key = key; const base = isSingle ? '/ai-provider' : `/ai-provider/${key}`; const logoPath = isSingle ? '/aiprovider' : `/aiprovider-${key}`; const settingsBase = isSingle ? '' : `/${key}`; const uiModule = item.settingsUiModule; return Object.assign(Object.assign({ key, name: item.name || config.name, description: item.description || config.description, logo: (0, util_1.getLogoUrl)(config, item, logoPath), chatCompletionsUrl: `${base}/completions`, modelsUrl: `${base}/models` }, (!!item.environments && { environments: normalizeEnvironments(item.environments), })), (uiModule ? { url: `/settings${settingsBase}/` + (uiModule.fileName || 'index.html') } : {})); }); } [ ...Object.values(ai_request_processors_1.AiRequestProcessorModuleWithoutStream), ...Object.values(ai_request_processors_1.AiRequestProcessorModuleWithStream), ].forEach((moduleType) => { const moduleValue = config[moduleType]; if (!moduleValue) { return; } const moduleSlug = (0, ai_request_processors_1.generateModuleSlugFromType)(moduleType); config[moduleType] = moduleValue.map((item) => (Object.assign({}, item))); const items = config[moduleType]; const isSingle = items.length === 1; modules[moduleSlug] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: moduleSlug, item, index, isSingle, }); item.key = key; return { key, processorUrl: isSingle ? '/ai-request-processor/' + moduleSlug : `/ai-request-processor/${moduleSlug}/${key}`, }; }); }); if (config.aiPromptProvider) { config.aiPromptProvider = config.aiPromptProvider.map((item) => (Object.assign({}, item))); const items = config.aiPromptProvider; const isSingle = items.length === 1; modules['ai-prompt-provider'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'ai-prompt-provider', item, index, isSingle, }); item.key = key; const base = isSingle ? '/prompt-provider' : `/prompt-provider/${key}`; const logoPath = isSingle ? '/ai-prompt-provider' : `/ai-prompt-provider-${key}`; return Object.assign(Object.assign(Object.assign(Object.assign({ key, name: item.name || config.name, logo: (0, util_1.getLogoUrl)(config, item, logoPath), compileUrl: `${base}/compile` }, ((0, util_1.isDefined)(item.allowRetryOnQaIssues) && { allowRetryOnQaIssues: item.allowRetryOnQaIssues, })), (item.actions ? { actions: item.actions } : {})), (item.status ? { statusUrl: `${base}/status` } : {})), (item.formSchema || item.uiPath ? { configuratorUrl: `${base}/settings/` + (item.fileName || 'index.html') } : {})); }); } if (config.webhooks) { // prevent possible overrides of the other modules config.webhooks = config.webhooks.map((webhook) => (Object.assign({}, webhook))); const webhooks = config.webhooks; modules['webhook'] = []; for (let i = 0; i < webhooks.length; i++) { webhooks[i].key = config.identifier + '-' + 'webhook-' + i; modules['webhook'].push({ key: webhooks[i].key, url: '/webhooks', events: webhooks[i].events, }); } } if (config.externalQaCheck) { config.externalQaCheck = config.externalQaCheck.map((item) => (Object.assign({}, item))); const items = config.externalQaCheck; const isSingle = items.length === 1; modules['external-qa-check'] = items.map((item, index) => { const key = (0, normalize_module_1.resolveInstanceKey)({ identifier: config.identifier, suffix: 'qa-check', item, index, isSingle, }); item.key = key; const base = isSingle ? '/qa-check' : `/qa-check/${key}`; const uiModule = item.settingsUiModule; return Object.assign(Object.assign({ key, name: item.name || config.name, description: item.description || config.description, runQaCheckUrl: `${base}/validate` }, (item.batchSize ? { getBatchSizeUrl: `${base}/batch-size` } : {})), (uiModule ? { url: `${base}/settings/` + (uiModule.fileName || 'index.html') } : {})); }); } if (config.advisorInspector) { config.advisorInspector = config.advisorInspector.map((item) => (Object.assign({}, item))); const items = config.advisorInspector; const isSingle = items.length === 1; modules['advisor-inspector'] = items.map((item, index) => { const key = (0, key_1.resolveAdvisorInspectorKey)(config, item, index, isSingle); item.key = key; const base = `/advisor-inspector/${key}`; const hasIframe = !!(item.uiPath || item.formSchema); return Object.assign(Object.assign(Object.assign(Object.assign({ key, name: item.name || config.name, title: item.title }, (item.summary && { summary: item.summary })), { severity: item.severity, category: item.category, refreshPolicy: item.refreshPolicy, recheckUrl: `${base}/recheck` }), (hasIframe && { url: `${base}/iframe/${item.fileName || 'index.html'}`, })), (item.environments && { environments: normalizeEnvironments(item.environments) })); }); } if (config.workflowStepType) { // prevent possible overrides of the other modules config.workflowStepType = config.workflowStepType.map((workflowStep) => (Object.assign({}, workflowStep))); const workflowSteps = config.workflowStepType; modules['workflow-step-type'] = []; for (const workflowStep of workflowSteps) { if (!workflowStep.key) { workflowStep.key = config.identifier + '-' + (0, util_2.getWorkflowStepKey)(workflowStep); } const uiModule = workflowStep === null || workflowStep === void 0 ? void 0 : workflowStep.settingsUiModule; modules['workflow-step-type'].push(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ key: workflowStep.key, name: workflowStep.name || config.name }, (workflowStep.imageUrl || workflowStep.imagePath ? { logo: (0, util_1.getLogoUrl)(config, workflowStep, `-${workflowStep.key}`) } : {})), { description: workflowStep.description || config.description, boundaries: workflowStep.boundaries }), (workflowStep.editorMode ? { editorMode: workflowStep.editorMode } : {})), { updateSettingsUrl: (0, util_2.getWorkflowStepUrl)('/workflow-step/settings', workflowStep), deleteSettingsUrl: (0, util_2.getWorkflowStepUrl)('/workflow-step/delete', workflowStep) }), ((uiModule === null || uiModule === void 0 ? void 0 : uiModule.formSchema) ? { url: `${(0, util_2.getWorkflowStepUrl)('/workflow-step', workflowStep)}/${uiModule.fileName || 'index.html'}`, } : {}))); } } if (config.automationAction) { // prevent possible overrides of the other modules config.automationAction = config.automationAction.map((automationAction) => (Object.assign({}, automationAction))); const automationActions = config.automationAction; modules['automation-action'] = []; for (const automationAction of automationActions) { if (!automationAction.key) { automationAction.key = config.identifier + '-' + (0, index_1.getAutomationActionKey)(automationAction); } const uiModule = automationAction.settingsUiModule; modules['automation-action'].push(Object.assign(Object.assign(Object.assign(Object.assign({ key: automationAction.key, name: automationAction.name || config.name, description: automationAction.description || config.description }, (automationAction.outputSchema ? { outputSchemaUrl: (0, index_1.getAutomationActionUrl)('/automation-action/output-schema', automationAction) } : {})), (automationAction.inputSchema ? { inputSchemaUrl: (0, index_1.getAutomationActionUrl)('/automation-action/input-schema', automationAction) } : {})), { validateSettingsUrl: (0, index_1.getAutomationActionUrl)('/automation-action/validate-settings', automationAction), executeUrl: (0, index_1.getAutomationActionUrl)('/automation-action/execute', automationAction), invocationWaitMode: automationAction.invocationWaitMode || 'sync' }), (uiModule ? { url: (0, index_1.getAutomationActionUrl)('/automation-action', automationAction) } : {}))); } } if (config.authGuard) { // prevent possible overrides of the other modules config.authGuard = config.authGuard.map((authGuard) => (Object.assign({}, authGuard))); const authGuards = config.authGuard; modules['auth-guard'] = []; for (let i = 0; i < authGuards.length; i++) { if (!authGuards[i].key) { authGuards[i].key = config.identifier + '-auth-guard-' + i; } const options = authGuards[i].options || {}; const manifestEntry = { key: authGuards[i].key, name: authGuards[i].name || config.name, url: '/auth-guard/verify', }; if (authGuards[i].description) { manifestEntry.description = authGuards[i].description; } if (options.type || options.applyToAdmin !== undefined || options.url) { manifestEntry.options = Object.assign(Object.assign(Object.assign({}, (options.type && { type: options.type })), (options.applyToAdmin !== undefined && { applyToAdmin: options.applyToAdmin })), (options.url && { url: options.url })); } modules['auth-guard'].push(manifestEntry); } } const events = { installed: '/installed', uninstall: '/uninstall', }; if (!(0, subscription_1.isAppFree)(config)) { events['subscription_paid'] = '/subscription-paid'; } return (_req, res) => { const manifest = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ identifier: config.identifier, name: config.name, logo: (0, util_1.getLogoUrl)(config), baseUrl: config.baseUrl, authentication: { type: config.authenticationType || types_1.AuthenticationType.APP, clientId: config.clientId, }, restrictAiToSameApp: config.restrictAiToSameApp }, (config.stringBasedAvailable !== undefined && { stringBasedAvailable: config.stringBasedAvailable })), (config.agent && { agent: config.agent })), { events, scopes: config.scopes ? config.scopes : [types_1.Scope.PROJECTS] }), (config.defaultPermissions && { default_permissions: config.defaultPermissions })), { modules }); res.send(manifest); }; }