import _Vue from "vue" ; import axios from 'axios' ; import VueI18n from 'vue-i18n' ; import { Store } from "vuex" ; import Vue from 'vue' ; import { INodeTranslationHeaders , IRootState } from '@/Interface' ; import { deriveMiddleKey , isNestedInCollectionLike , normalize , insertOptionsAndValues , } from "./utils" ; const englishBaseText = require ( './locales/en' ) ; Vue . use ( VueI18n ) ; export function I18nPlugin ( vue , store ) { const i18n = new I18nClass ( store ) ; Object . defineProperty ( vue , '$locale' , { get ( ) { return i18n ; } , } ) ; Object . defineProperty ( vue . prototype , '$locale' , { get ( ) { return i18n ; } , } ) ; } export class I18nClass { $store : Store < IRootState > ; constructor ( store ) { this . $store = store ; } private get i18n ( ) : VueI18n { return i18nInstance ; } exists ( key ) { return this . i18n . te ( key ) ; } shortNodeType ( longNodeType ) { return longNodeType . replace ( 'n8n-nodes-base.' , '' ) ; } /**
     * Render a string of base text, i.e. a string with a fixed path to the localized value. Optionally allows for [interpolation](https://kazupon.github.io/vue-i18n/guide/formatting.html#named-formatting) when the localized value contains a string between curly braces.
     */ baseText ( key , options ? ) { return this . i18n . t ( key , options && options . interpolate ) . toString ( ) ; } /**
     * Render a string of dynamic text, i.e. a string with a constructed path to the localized value.
     */ private dynamicRender ( { key , fallback } ) { return this . i18n . te ( key ) ? this . i18n . t ( key ) . toString ( ) : fallback ; } /**
     * Render a string of header text (a node's name and description),
     * used variously in the nodes panel, under the node icon, etc.
     */ headerText ( arg ) { return this . dynamicRender ( arg ) ; } /**
     * Namespace for methods to render text in the credentials details modal.
     */ credText ( ) { const credentialType = this . $store . getters . activeCredentialType ; const credentialPrefix = `n8n-nodes-base.credentials.${ credentialType }` ; const context = this ; return { /**
             * Display name for a top-level param.
             */ inputLabelDisplayName ( { name : parameterName , displayName } ) { if ( [ 'clientId' , 'clientSecret' ] . includes ( parameterName ) ) { return context . dynamicRender ( { key : `reusableDynamicText.oauth2.${ parameterName }` , fallback : displayName , } ) ; } return context . dynamicRender ( { key : `${ credentialPrefix }.${ parameterName }.displayName` , fallback : displayName , } ) ; } , /**
             * Description (tooltip text) for an input label param.
             */ inputLabelDescription ( { name : parameterName , description } ) { return context . dynamicRender ( { key : `${ credentialPrefix }.${ parameterName }.description` , fallback : description , } ) ; } , /**
             * Display name for an option inside an `options` or `multiOptions` param.
             */ optionsOptionDisplayName ( { name : parameterName } , { value : optionName , name : displayName } ) { return context . dynamicRender ( { key : `${ credentialPrefix }.${ parameterName }.options.${ optionName }.displayName` , fallback : displayName , } ) ; } , /**
             * Description for an option inside an `options` or `multiOptions` param.
             */ optionsOptionDescription ( { name : parameterName } , { value : optionName , description } ) { return context . dynamicRender ( { key : `${ credentialPrefix }.${ parameterName }.options.${ optionName }.description` , fallback : description , } ) ; } , /**
             * Placeholder for a `string` or `collection` or `fixedCollection` param.
             * - For a `string` parameter, the placeholder is unselectable greyed-out sample text.
             * - For a `collection` or `fixedCollection` parameter, the placeholder is the button text.
             */ placeholder ( { name : parameterName , displayName } ) { return context . dynamicRender ( { key : `${ credentialPrefix }.${ parameterName }.placeholder` , fallback : displayName , } ) ; } , } ; } /**
     * Namespace for methods to render text in the node details view,
     * except for `eventTriggerDescription`.
     */ nodeText ( ) { const activeNode = this . $store . getters . activeNode ; const nodeType = activeNode ? this . shortNodeType ( activeNode . type ) : '' ; const initialKey = `n8n-nodes-base.nodes.${ nodeType }.nodeView` ; const context = this ; return { /**
             * Display name for an input label, whether top-level or nested.
             */ inputLabelDisplayName ( parameter , path ) { const middleKey = deriveMiddleKey ( path , parameter ) ; return context . dynamicRender ( { key : `${ initialKey }.${ middleKey }.displayName` , fallback : parameter . displayName , } ) ; } , /**
             * Description (tooltip text) for an input label, whether top-level or nested.
             */ inputLabelDescription ( parameter , path ) { const middleKey = deriveMiddleKey ( path , parameter ) ; return context . dynamicRender ( { key : `${ initialKey }.${ middleKey }.description` , fallback : parameter . description , } ) ; } , /**
             * Placeholder for an input label or `collection` or `fixedCollection` param,
             * whether top-level or nested.
             * - For an input label, the placeholder is unselectable greyed-out sample text.
             * - For a `collection` or `fixedCollection`, the placeholder is the button text.
             */ placeholder ( parameter , path ) { let middleKey = parameter . name ; if ( isNestedInCollectionLike ( path ) ) { const pathSegments = normalize ( path ) . split ( '.' ) ; middleKey = insertOptionsAndValues ( pathSegments ) . join ( '.' ) ; } return context . dynamicRender ( { key : `${ initialKey }.${ middleKey }.placeholder` , fallback : parameter . placeholder , } ) ; } , /**
             * Display name for an option inside an `options` or `multiOptions` param,
             * whether top-level or nested.
             */ optionsOptionDisplayName ( parameter , { value : optionName , name : displayName } , path ) { let middleKey = parameter . name ; if ( isNestedInCollectionLike ( path ) ) { const pathSegments = normalize ( path ) . split ( '.' ) ; middleKey = insertOptionsAndValues ( pathSegments ) . join ( '.' ) ; } return context . dynamicRender ( { key : `${ initialKey }.${ middleKey }.options.${ optionName }.displayName` , fallback : displayName , } ) ; } , /**
             * Description for an option inside an `options` or `multiOptions` param,
             * whether top-level or nested.
             */ optionsOptionDescription ( parameter , { value : optionName , description } , path ) { let middleKey = parameter . name ; if ( isNestedInCollectionLike ( path ) ) { const pathSegments = normalize ( path ) . split ( '.' ) ; middleKey = insertOptionsAndValues ( pathSegments ) . join ( '.' ) ; } return context . dynamicRender ( { key : `${ initialKey }.${ middleKey }.options.${ optionName }.description` , fallback : description , } ) ; } , /**
             * Display name for an option in the dropdown menu of a `collection` or
             * fixedCollection` param. No nesting support since `collection` cannot
             * be nested in a `collection` or in a `fixedCollection`.
             */ collectionOptionDisplayName ( parameter , { name : optionName , displayName } , path ) { let middleKey = parameter . name ; if ( isNestedInCollectionLike ( path ) ) { const pathSegments = normalize ( path ) . split ( '.' ) ; middleKey = insertOptionsAndValues ( pathSegments ) . join ( '.' ) ; } return context . dynamicRender ( { key : `${ initialKey }.${ middleKey }.options.${ optionName }.displayName` , fallback : displayName , } ) ; } , /**
             * Text for a button to add another option inside a `collection` or
             * `fixedCollection` param having `multipleValues: true`.
             */ multipleValueButtonText ( { name : parameterName , typeOptions : { multipleValueButtonText } } ) { return context . dynamicRender ( { key : `${ initialKey }.${ parameterName }.multipleValueButtonText` , fallback : multipleValueButtonText , } ) ; } , eventTriggerDescription ( nodeType , eventTriggerDescription ) { return context . dynamicRender ( { key : `n8n-nodes-base.nodes.${ nodeType }.nodeView.eventTriggerDescription` , fallback : eventTriggerDescription , } ) ; } , } ; } } const i18nInstance = new VueI18n ( { locale : 'en' , fallbackLocale : 'en' , messages : { en : englishBaseText } , silentTranslationWarn : true , } ) ; const loadedLanguages = [ 'en' ] ; function setLanguage ( language ) { i18nInstance . locale = language ; axios . defaults . headers . common [ 'Accept-Language' ] = language ; document ! . querySelector ( 'html' ) ! . setAttribute ( 'lang' , language ) ; return language ; } export async function loadLanguage ( language ? ) { if ( ! language ) return Promise . resolve ( ) ; if ( i18nInstance . locale === language ) { return Promise . resolve ( setLanguage ( language ) ) ; } if ( loadedLanguages . includes ( language ) ) { return Promise . resolve ( setLanguage ( language ) ) ; } const { numberFormats , ... rest } = require ( `./locales/${ language }.json` ) ; i18nInstance . setLocaleMessage ( language , rest ) ; if ( numberFormats ) { i18nInstance . setNumberFormat ( language , numberFormats ) ; } loadedLanguages . push ( language ) ; setLanguage ( language ) ; } /**
 * Add a node translation to the i18n instance's `messages` object.
 */ export function addNodeTranslation ( nodeTranslation , language ) { const oldNodesBase = i18nInstance . messages [ language ] [ 'n8n-nodes-base' ] || { } ; const updatedNodes = { ... oldNodesBase . nodes , ... nodeTranslation , } ; const newNodesBase = { 'n8n-nodes-base' : Object . assign ( oldNodesBase , { nodes : updatedNodes } ) , } ; i18nInstance . setLocaleMessage ( language , Object . assign ( i18nInstance . messages [ language ] , newNodesBase ) ) ; } /**
 * Add a credential translation to the i18n instance's `messages` object.
 */ export function addCredentialTranslation ( nodeCredentialTranslation , language ) { const oldNodesBase = i18nInstance . messages [ language ] [ 'n8n-nodes-base' ] || { } ; const updatedCredentials = { ... oldNodesBase . credentials , ... nodeCredentialTranslation , } ; const newNodesBase = { 'n8n-nodes-base' : Object . assign ( oldNodesBase , { credentials : updatedCredentials } ) , } ; i18nInstance . setLocaleMessage ( language , Object . assign ( i18nInstance . messages [ language ] , newNodesBase ) ) ; } /**
 * Add a node's header strings to the i18n instance's `messages` object.
 */ export function addHeaders ( headers , language ) { i18nInstance . setLocaleMessage ( language , Object . assign ( i18nInstance . messages [ language ] , { headers } ) ) ; }