UNPKG

@crowdin/app-project-module

Version:

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

505 lines (504 loc) 14.4 kB
import Crowdin from '@crowdin/crowdin-api-client'; import { JwtPayload, VerifyOptions } from '@crowdin/crowdin-apps-functions'; import { Request } from 'express'; import { ContextContent } from './modules/context-menu/types'; import { CustomMTLogic } from './modules/custom-mt/types'; import { CustomSpellcheckerModule } from './modules/custom-spell-check/types'; import { EditorPanels } from './modules/editor-right-panel/types'; import { CustomFileFormatLogic, FilePostExportLogic, FilePostImportLogic, FilePreExportLogic, FilePreImportLogic } from './modules/file-processing/types'; import { IntegrationLogic } from './modules/integration/types'; import { Storage } from './storage'; import { MySQLStorageConfig } from './storage/mysql'; import { PostgreStorageConfig } from './storage/postgre'; import { ApiModule } from './modules/api/types'; import { LogErrorFunction, LogFunction } from './util/logger'; import { AiProviderModule } from './modules/ai-provider/types'; import { AiPromptProviderModule } from './modules/ai-prompt-provider/types'; import { AiTool, AiToolWidget } from './modules/ai-tools/types'; import { ExternalQaCheckModule } from './modules/external-qa-check/types'; import { Webhook } from './modules/webhooks/types'; import { WorkflowStepTypeModule } from './modules/workflow-step-type/types'; import { AiRequestProcessorModule, AiStreamProcessorModule } from './modules/ai-request-processors/types'; export interface ClientConfig extends ImagePath { /** * Authentication Crowdin App type: "authorization_code", "crowdin_app", "crowdin_agent". Default: "crowdin_app" */ authenticationType?: AuthenticationType; /** * Crowdin Agent information: name, username, avatarUrl */ agent?: Agent; /** * client id that we received when registering the app */ clientId?: string; /** * client secret that we received when registering the app */ clientSecret?: string; /** * Secret to encrypt/decrypt credentials (by default @clientSecret will be used) */ cryptoSecret?: string; /** * Options to validate Crowdin JWT token */ jwtValidationOptions?: VerifyOptions; /** * https url where an app is reachable from the internet (e.g. the one that ngrok generates for us) */ baseUrl?: string; /** * define custom Crowdin urls (e.g. to work against local Crowdin server) */ crowdinUrls?: CrowdinUrls; /** * define custom User Agent in requests to Crowdin */ crowdinApiUserAgent?: string; /** * Set of scopes requested by this app (default 'project') */ scopes?: Scope[]; /** * app name */ name: string; /** * app identifier */ identifier: string; /** * app description */ description: string; /** * link to the app's description/detail page */ detailPage?: string; /** * Set default app permissions */ defaultPermissions?: DefaultPermissions; /** * port where to start express application */ port?: number; /** * folder where module will create sqlite db file to persist credentials (e.g. {@example __dirname}) */ dbFolder?: string; /** * migrate from SQLite to PostgreSQL */ migrateToPostgreFromSQLite?: boolean; /** * config to configure PostgreSQL as a storage */ postgreConfig?: PostgreStorageConfig; /** * config to configure MySQL as a storage */ mysqlConfig?: MySQLStorageConfig; /** * integration module logic */ projectIntegration?: IntegrationLogic & ImagePath & Environments; /** * custom file format module logic */ customFileFormat?: CustomFileFormatLogic; /** * custom MT module logic */ customMT?: CustomMTLogic & ImagePath & Environments; /** * resources module */ profileResourcesMenu?: UiModule & ImagePath & Environments; /** * profile-settings-menu module */ profileSettingsMenu?: UiModule & ImagePath & Environments; /** * organization-menu module */ organizationMenu?: UiModule & ImagePath; /** * organization-settings-menu module */ organizationSettingsMenu?: UiModule & ImagePath; /** * editor-right-panel module */ editorRightPanel?: EditorPanels & Environments; /** * project menu module */ projectMenu?: UiModule & Environments; /** * project menu crowdsource module */ projectMenuCrowdsource?: UiModule; /** * tools module */ projectTools?: UiModule & ImagePath & Environments; /** * reports module */ projectReports?: UiModule & ImagePath; /** * API module */ api?: ApiModule; /** * context menu module */ contextMenu?: ContextModule | ContextModule[]; /** * modal module */ modal?: ModalModule | ModalModule[]; /** * Install hook */ onInstall?: ({ organization, userId, client, }: { organization: string; userId: number; client: Crowdin; }) => Promise<void>; /** * Uninstall hook for cleanup logic */ onUninstall?: (organization: string, allCredentials: { settings?: any; credentials: any; }[]) => Promise<void>; /** * Error interceptor (can be used to log error in centralized place) */ onError?: (error: any, context?: CrowdinContextInfo) => void; /** * Disable global error handling of unhandledRejection and uncaughtException events */ disableGlobalErrorHandling?: boolean; /** * Configuration to log everything that are happening in the app */ logger?: Logger; /** * Enable status page with optional db and filesystem checks */ enableStatusPage?: { database?: boolean; filesystem?: boolean; rateLimit?: number; }; /** * Configuration of app pricing */ pricing?: Pricing; filePreImport?: FilePreImportLogic; filePostImport?: FilePostImportLogic; filePreExport?: FilePreExportLogic; filePostExport?: FilePostExportLogic; /** * Disable formatting logs */ disableLogsFormatter?: boolean; /** * AWS configuration for uploading big files to temporary bucket. Used with customFileFormat and file processors modules. * * Not necessary to configure if environment variables AWS_REGION and AWS_TMP_BUCKET_NAME are properly set. */ awsConfig?: AWSConfig; customSpellchecker?: CustomSpellcheckerModule; /** * ai provider module */ aiProvider?: AiProviderModule & ImagePath; /** * ai prompt provider module */ aiPromptProvider?: AiPromptProviderModule & ImagePath; /** * ai request pre-compile processor module */ aiRequestPreCompile?: AiRequestProcessorModule; /** * ai request post-compile processor module */ aiRequestPostCompile?: AiRequestProcessorModule; /** * ai request pre-parse processor module */ aiRequestPreParse?: AiStreamProcessorModule; /** * ai request post-parse processor module */ aiRequestPostParse?: AiRequestProcessorModule; /** * AI tool_calls modules */ aiTools?: AiTool | AiTool[]; /** * AI tool_calls modules with UI widgets */ aiToolsWidget?: AiToolWidget | AiToolWidget[]; /** * qa check module */ externalQaCheck?: ExternalQaCheckModule & ImagePath; /** * webhook modules */ webhooks?: Webhook | Webhook[]; /** * workflow step modules */ workflowStepType?: WorkflowStepTypeModule | WorkflowStepTypeModule[]; /** * property that tells backend that AiProvider and AiPromptProvider modules can cooperate only with each one */ restrictAiToSameApp?: boolean; } export interface Environments { environments?: Environment | Environment[]; } type Environment = 'crowdin' | 'crowdin-enterprise'; export type Config = ClientConfig & { baseUrl: string; clientId: string; clientSecret: string; port: number; dbFolder: string; imagePath: string; }; export type UnauthorizedConfig = Omit<Config, 'clientId' | 'clientSecret'> & { clientId?: string; clientSecret?: string; }; export declare enum AuthenticationType { CODE = "authorization_code", APP = "crowdin_app", AGENT = "crowdin_agent", NONE = "none" } export interface Agent { name?: string; username: string; avatarUrl?: string; } export interface CrowdinUrls { apiUrl?: string; accountUrl?: string; subscriptionUrl?: string; } export declare enum Scope { ALL_SCOPES = "all", NOTIFICATIONS = "notification", TRANSLATION_MEMORIES = "tm", MACHINE_TRANSLATION_ENGINES = "mt", GLOSSARIES = "glossary", USERS = "user", TEAMS = "team", GROUPS = "group", PROJECTS = "project", TASKS = "project.task", REPORTS = "project.report", TRANSLATION_STATUS = "project.status", SOURCE_FILES_AND_STRINGS = "project.source", WEBHOOKS = "project.webhook", ORGANIZATION_WEBHOOKS = "webhook", TRANSLATIONS = "project.translation", SCREENSHOTS = "project.screenshot", SECURITY_LOGS = "security-log", VENDORS = "vendor", FIELDS = "field", AI = "ai", AI_PROVIDERS = "ai.provider", AI_PROMPTS = "ai.prompt", AI_PROXIES = "ai.proxy", APPLICATIONS = "application" } export interface CrowdinClientRequest extends Request { crowdinApiClient: Crowdin; crowdinContext: CrowdinContextInfo; subscriptionInfo?: SubscriptionInfo; logInfo: LogFunction; logError: LogErrorFunction; isApiCall?: boolean; } export interface CrowdinCredentials { id: string; appSecret: string; domain?: string; userId: number; agentId?: number; organizationId: number; baseUrl: string; accessToken: string; refreshToken: string; expire: string; type: AccountType; } export declare enum AccountType { NORMAL = "normal", ENTERPRISE = "enterprise" } export interface CrowdinContextInfo { jwtPayload: JwtPayload; crowdinId: string; clientId: string; appIdentifier: string; } export declare enum SubscriptionInfoType { TRIAL = "trial", SUBSCRIPTION = "subscription" } export interface SubscriptionInfo { expired: boolean; subscribeLink?: string; daysLeft?: number; type?: SubscriptionInfoType; } export declare enum EditorMode { ASSETS = "assets", REVIEW = "review", TRANSLATE = "TRANSLATE", PROOFREAD = "proofread", COMFORTABLE = "comfortable", SIDE_BY_SIDE = "side-by-side", MULTILINGUAL = "multilingual" } interface ModuleContent { /** * relative URL to the content page of the module */ url?: string; } export interface CrowdinAppUtilities extends CrowdinMetadataStore { establishCrowdinConnection: (authRequest: string | CrowdinClientRequest, moduleKey: string[] | string | undefined) => Promise<{ context: CrowdinContextInfo; client?: Crowdin; }>; encryptCrowdinConnection: (data: { crowdinId: string; extra: Record<string, any>; }) => string; dencryptCrowdinConnection: (hash: string, autoRenew?: boolean) => Promise<{ client: Crowdin; extra: Record<string, any>; }>; storage: Storage; } export interface CrowdinMetadataStore { saveMetadata: (id: string, metadata: any, crowdinId: string) => Promise<void>; getMetadata: (id: string) => Promise<any | undefined>; deleteMetadata: (id: string) => Promise<void>; /** * Settings that users manage in the integration module */ getUserSettings: (clientId: string) => Promise<any | undefined>; } export interface UiModule extends ModuleKey { /** * Form schema for react-jsonschema-doc to be used as front-end * https://rjsf-team.github.io/react-jsonschema-form/docs */ formSchema?: object; /** * URL to custom endpoint that can be used instead of default one to save form data. * Endpoint should accept POST requests. */ formPostDataUrl?: string; /** * URL to custom endpoint that can be used instead of default one to retrieve form data. * Endpoint should accept GET requests. */ formGetDataUrl?: string; /** * Additional attributes for react-jsonschema-doc */ formUiSchema?: object; /** * path to ui folder (e.g. {@example join(__dirname, 'public')}) */ uiPath?: string; /** * page name (default index.html) */ fileName?: string; /** * Module name */ name?: string; /** * Temporary property. Indicates if passwords should be masked. Will be dropped when all existing apps will migrate. */ maskPasswords?: boolean; } export interface ModuleKey { /** * key to identify module */ key?: string; } export interface ImagePath { /** * path to app logo (e.g. {@example join(__dirname, 'logo.png')}) */ imagePath?: string; } export interface Logger { enabled: boolean; log?: (message: string, context?: CrowdinContextInfo) => void; } export interface Pricing { planType: 'free' | 'recurring'; trial?: number; trialCrowdin?: number; trialEnterprise?: number; cachingSeconds?: number; infoDisplayDaysThreshold?: number; } export declare enum UserPermissions { OWNER = "owner", MANAGERS = "managers", ALL_MEMBERS = "all", GUESTS = "guests", RESTRICTED = "restricted" } export declare enum ProjectPermissions { OWN = "own", RESTRICTED = "restricted" } export interface DefaultPermissions { user?: UserPermissions; project?: ProjectPermissions; } export interface AWSConfig { /** * AWS bucket name for temporary files */ tmpBucketName?: string; /** * AWS region */ region?: string; } export interface SignaturePatterns { fileName?: string; fileContent?: string; } export declare enum storageFiles { SQLITE = "app.sqlite", SQLITE_BACKUP = "backup_app.sqlite", DUMP = "dump_table_%s.sql" } export interface ModalModule extends ModuleContent, UiModule, Environments { } export interface ContextModule extends ContextContent, UiModule, Environments { } export {};