From db222ea399e8d141e2fa702fef5faf1735272fcb Mon Sep 17 00:00:00 2001 From: Kristina Fefelova Date: Thu, 25 Sep 2025 14:37:07 +0400 Subject: [PATCH 1/6] Init translate service Signed-off-by: Kristina Fefelova --- common/config/rush/pnpm-lock.yaml | 39 ++++++++++++++++ communication | 2 +- dev/docker-compose.yaml | 15 ++++++ pods/server/package.json | 1 + rush.json | 5 ++ services/translate/.eslintrc.js | 7 +++ services/translate/.npmignore | 4 ++ services/translate/Dockerfile | 6 +++ services/translate/config/rig.json | 4 ++ services/translate/jest.config.js | 7 +++ services/translate/package.json | 68 +++++++++++++++++++++++++++ services/translate/src/config.ts | 35 ++++++++++++++ services/translate/src/index.ts | 75 ++++++++++++++++++++++++++++++ services/translate/src/main.ts | 0 services/translate/src/utils.ts | 0 services/translate/tsconfig.json | 12 +++++ 16 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 services/translate/.eslintrc.js create mode 100644 services/translate/.npmignore create mode 100644 services/translate/Dockerfile create mode 100644 services/translate/config/rig.json create mode 100644 services/translate/jest.config.js create mode 100644 services/translate/package.json create mode 100644 services/translate/src/config.ts create mode 100644 services/translate/src/index.ts create mode 100644 services/translate/src/main.ts create mode 100644 services/translate/src/utils.ts create mode 100644 services/translate/tsconfig.json diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 6da4fa70b1f..ef86116d796 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -955,6 +955,9 @@ importers: '@rush-temp/pod-telegram-bot': specifier: file:./projects/pod-telegram-bot.tgz version: file:projects/pod-telegram-bot.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(encoding@0.1.13)(gcp-metadata@5.3.0(encoding@0.1.13))(snappy@7.2.2)(socks@2.8.3) + '@rush-temp/pod-translate': + specifier: file:./projects/pod-translate.tgz + version: file:projects/pod-translate.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9)) '@rush-temp/pod-worker': specifier: file:./projects/pod-worker.tgz version: file:projects/pod-worker.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(webpack-cli@5.1.4) @@ -5524,6 +5527,10 @@ packages: resolution: {integrity: sha512-JxdvigAw/njFUV7DoAoepnhVtYX3vvIuL4cvHy4ZpK5LYx6PjxP5AOcUD3dTb/WZXDAnZAc6APKpAKgmHA5UXQ==, tarball: file:projects/pod-telegram.tgz} version: 0.0.0 + '@rush-temp/pod-translate@file:projects/pod-translate.tgz': + resolution: {integrity: sha512-fqxgqmjuyGmxvqaFcaDGxdUVsXHQpWfbxOrQVIxUkcLTdKxGIyoYh9R4RVLJBSq08QKuAR8Mi+qyktRZbkNkSA==, tarball: file:projects/pod-translate.tgz} + version: 0.0.0 + '@rush-temp/pod-worker@file:projects/pod-worker.tgz': resolution: {integrity: sha512-6sP8dB+Kv5PnITQ4XVHj9ZHrGXy/7Xbp3VbhdJhVZqvYusL19i2iRQ+RBmuVKeKH/94YIFoRoHn/Y7LDAYCNgQ==, tarball: file:projects/pod-worker.tgz} version: 0.0.0 @@ -25922,6 +25929,38 @@ snapshots: - ts-node - utf-8-validate + '@rush-temp/pod-translate@file:projects/pod-translate.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))': + dependencies: + '@tsconfig/node16': 1.0.4 + '@types/jest': 29.5.12 + '@types/node': 22.15.29 + '@types/uuid': 8.3.4 + '@types/ws': 8.5.11 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.3))(eslint@8.56.0)(typescript@5.8.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.8.3) + dotenv: 16.0.3 + esbuild: 0.25.9 + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.3))(eslint@8.56.0)(typescript@5.8.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.8.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-node: 11.1.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3)) + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.25.9)(jest@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3)))(typescript@5.8.3) + ts-node: 10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@swc/core' + - '@swc/wasm' + - babel-jest + - babel-plugin-macros + - node-notifier + - supports-color + '@rush-temp/pod-worker@file:projects/pod-worker.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(webpack-cli@5.1.4)': dependencies: '@temporalio/worker': 1.12.3(esbuild@0.25.9)(webpack-cli@5.1.4) diff --git a/communication b/communication index 86473f96ce5..7afc4f0c882 160000 --- a/communication +++ b/communication @@ -1 +1 @@ -Subproject commit 86473f96ce5027e2dacf528280de68eca48595fc +Subproject commit 7afc4f0c88244cdfb13efc1093766e088bcc1d6c diff --git a/dev/docker-compose.yaml b/dev/docker-compose.yaml index 42ba98f2dc1..53428510d9b 100644 --- a/dev/docker-compose.yaml +++ b/dev/docker-compose.yaml @@ -561,6 +561,21 @@ services: - QUEUE_CONFIG=${QUEUE_CONFIG} - QUEUE_REGION=cockroach restart: unless-stopped + translate: + image: hardcoreeng/translate + extra_hosts: + - 'huly.local:host-gateway' + depends_on: + redpanda: + condition: service_started + account: + condition: service_started + environment: + - SECRET=secret + - ACCOUNTS_URL=http://huly.local:3000 + - QUEUE_CONFIG=${QUEUE_CONFIG} + - QUEUE_REGION=cockroach + restart: unless-stopped backup-cockroach: image: hardcoreeng/backup extra_hosts: diff --git a/pods/server/package.json b/pods/server/package.json index f982a4e8001..04c990f9bca 100644 --- a/pods/server/package.json +++ b/pods/server/package.json @@ -71,6 +71,7 @@ "@hcengineering/notification": "^0.6.23", "@hcengineering/platform": "^0.6.11", "@hcengineering/pod-telegram-bot": "^0.6.0", + "@hcengineering/pod-translate": "^0.6.0", "@hcengineering/postgres": "^0.6.0", "@hcengineering/rpc": "^0.6.5", "@hcengineering/server": "^0.6.4", diff --git a/rush.json b/rush.json index ee83a730624..52705fede1f 100644 --- a/rush.json +++ b/rush.json @@ -2615,6 +2615,11 @@ "packageName": "@hcengineering/hulylake-client", "projectFolder": "packages/hulylake-client", "shouldPublish": false + }, + { + "packageName": "@hcengineering/pod-translate", + "projectFolder": "services/translate", + "shouldPublish": false } ] } diff --git a/services/translate/.eslintrc.js b/services/translate/.eslintrc.js new file mode 100644 index 00000000000..72235dc2833 --- /dev/null +++ b/services/translate/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/services/translate/.npmignore b/services/translate/.npmignore new file mode 100644 index 00000000000..e3ec093c383 --- /dev/null +++ b/services/translate/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/services/translate/Dockerfile b/services/translate/Dockerfile new file mode 100644 index 00000000000..4f2f62f5d60 --- /dev/null +++ b/services/translate/Dockerfile @@ -0,0 +1,6 @@ +FROM hardcoreeng/base-slim:v20250916 +WORKDIR /usr/src/app + +COPY bundle/bundle.js ./ + +CMD [ "node", "bundle.js" ] diff --git a/services/translate/config/rig.json b/services/translate/config/rig.json new file mode 100644 index 00000000000..0110930f55e --- /dev/null +++ b/services/translate/config/rig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig" +} diff --git a/services/translate/jest.config.js b/services/translate/jest.config.js new file mode 100644 index 00000000000..2cfd408b679 --- /dev/null +++ b/services/translate/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/services/translate/package.json b/services/translate/package.json new file mode 100644 index 00000000000..dfe10cf44dc --- /dev/null +++ b/services/translate/package.json @@ -0,0 +1,68 @@ +{ + "name": "@hcengineering/pod-translate", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "files": [ + "lib/**/*", + "types/**/*", + "tsconfig.json" + ], + "author": "Hardcore Engineering Inc.", + "scripts": { + "build": "compile", + "build:watch": "compile", + "test": "jest --passWithNoTests --silent", + "_phase:bundle": "rushx bundle", + "_phase:docker-build": "rushx docker:build", + "_phase:docker-staging": "rushx docker:staging", + "bundle": "node ../../common/scripts/esbuild.js", + "docker:build": "../../common/scripts/docker_build.sh hardcoreeng/translate .", + "docker:tbuild": "docker build -t hardcoreeng/translate . --platform=linux/amd64 && ../../common/scripts/docker_tag_push.sh hardcoreeng/translate", + "docker:staging": "../../common/scripts/docker_tag.sh hardcoreeng/translate staging", + "docker:push": "../../common/scripts/docker_tag.sh hardcoreeng/translate", + "run-local": "cross-env ts-node src/index.ts", + "format": "format src", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@tsconfig/node16": "^1.0.4", + "@types/node": "^22.15.29", + "@types/ws": "^8.5.11", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@hcengineering/platform-rig": "^0.6.0", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "@types/uuid": "^8.3.1", + "@typescript-eslint/parser": "^6.11.0", + "esbuild": "^0.25.9", + "eslint": "^8.54.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "prettier": "^3.1.0", + "ts-node": "^10.8.0", + "typescript": "^5.8.3" + }, + "dependencies": { + "@hcengineering/account-client": "^0.6.0", + "@hcengineering/analytics": "^0.6.0", + "@hcengineering/analytics-service": "^0.6.0", + "@hcengineering/api-client": "^0.6.0", + "@hcengineering/card": "^0.6.0", + "@hcengineering/core": "^0.6.32", + "@hcengineering/kafka": "^0.6.0", + "@hcengineering/measurements": "^0.6.0", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/server-core": "^0.6.1", + "@hcengineering/server-token": "^0.6.11", + "dotenv": "~16.0.0" + } +} diff --git a/services/translate/src/config.ts b/services/translate/src/config.ts new file mode 100644 index 00000000000..8d6710f8240 --- /dev/null +++ b/services/translate/src/config.ts @@ -0,0 +1,35 @@ +// +// Copyright © 2025 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +import { config as dotenvConfig } from 'dotenv' + +dotenvConfig() + +export interface Config { + Secret: string + QueueConfig: string + QueueRegion: string + AccountsUrl: string + ServiceId: string +} + +const config: Config = { + Secret: process.env.SECRET ?? 'secret', + QueueConfig: process.env.QUEUE_CONFIG ?? '', + QueueRegion: process.env.QUEUE_REGION ?? '', + AccountsUrl: process.env.ACCOUNTS_URL ?? '', + ServiceId: process.env.SERVICE_ID ?? 'translate' +} + +export default config diff --git a/services/translate/src/index.ts b/services/translate/src/index.ts new file mode 100644 index 00000000000..83cd047e5e0 --- /dev/null +++ b/services/translate/src/index.ts @@ -0,0 +1,75 @@ +// +// Copyright © 2025 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { configureAnalytics, createOpenTelemetryMetricsContext, SplitLogger } from '@hcengineering/analytics-service' +import { initStatisticsContext, QueueTopic } from '@hcengineering/server-core' +import { newMetrics } from '@hcengineering/measurements' +import { join } from 'path' +import { getPlatformQueue } from '@hcengineering/kafka' +import { Analytics } from '@hcengineering/analytics' +import { setMetadata } from '@hcengineering/platform' +import serverToken from '@hcengineering/server-token' +import { Tx } from '@hcengineering/core' + +import config from './config' + +async function main (): Promise { + configureAnalytics(config.ServiceId, process.env.VERSION ?? '0.7.0') + const ctx = initStatisticsContext(config.ServiceId, { + factory: () => + createOpenTelemetryMetricsContext( + config.ServiceId, + {}, + {}, + newMetrics(), + new SplitLogger(config.ServiceId, { + root: join(process.cwd(), 'logs'), + enableConsole: (process.env.ENABLE_CONSOLE ?? 'true') === 'true' + }) + ) + }) + + Analytics.setTag('application', config.ServiceId) + setMetadata(serverToken.metadata.Secret, config.Secret) + setMetadata(serverToken.metadata.Service, config.ServiceId) + + const queue = getPlatformQueue(config.ServiceId, config.QueueRegion) + + const consumer = queue.createConsumer(ctx, QueueTopic.Tx, queue.getClientId(), async (ct, message) => { + const ws = message.workspace + const record = message.value + + console.log(ws, record) + }) + + const shutdown = (): void => { + void Promise.all([consumer.close()]).then(() => { + process.exit() + }) + } + + process.once('SIGINT', shutdown) + process.once('SIGTERM', shutdown) + process.on('uncaughtException', (error: any) => { + ctx.error('Uncaught exception', { error }) + }) + process.on('unhandledRejection', (error: any) => { + ctx.error('Unhandled rejection', { error }) + }) +} + +void main().catch((err) => { + console.error(err) +}) diff --git a/services/translate/src/main.ts b/services/translate/src/main.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/services/translate/src/utils.ts b/services/translate/src/utils.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/services/translate/tsconfig.json b/services/translate/tsconfig.json new file mode 100644 index 00000000000..b5ae22f6e46 --- /dev/null +++ b/services/translate/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "lib", "dist", "types", "bundle"] +} \ No newline at end of file From 7c04a78ff7c9fd796740184e2b1f65fa344d8d1b Mon Sep 17 00:00:00 2001 From: Kristina Fefelova Date: Tue, 30 Sep 2025 09:46:02 +0400 Subject: [PATCH 2/6] Add auto translate service Signed-off-by: Kristina Fefelova --- common/config/rush/pnpm-lock.yaml | 222 +++++------------ communication | 2 +- dev/docker-compose.yaml | 1 + models/contact/package.json | 1 + models/contact/src/index.ts | 25 +- models/contact/src/plugin.ts | 3 +- .../communication-resources/src/actions.ts | 48 ++-- .../src/components/MessagesList.svelte | 6 +- .../src/components/message/MessageBody.svelte | 45 +++- .../message/MessageContentViewer.svelte | 48 ++-- .../message/MessagePresenter.svelte | 38 ++- plugins/communication-resources/src/stores.ts | 31 +-- plugins/contact-assets/lang/cs.json | 7 +- plugins/contact-assets/lang/de.json | 7 +- plugins/contact-assets/lang/en.json | 7 +- plugins/contact-assets/lang/es.json | 7 +- plugins/contact-assets/lang/fr.json | 7 +- plugins/contact-assets/lang/it.json | 7 +- plugins/contact-assets/lang/ja.json | 9 +- plugins/contact-assets/lang/pt.json | 7 +- plugins/contact-assets/lang/ru.json | 7 +- plugins/contact-assets/lang/zh.json | 7 +- .../src/components/LanguageEditor.svelte | 73 ++++++ .../src/components/LanguageIcon.svelte | 33 +++ .../src/components/LanguagePresenter.svelte | 27 ++ .../components/LanguagesArrayEditor.svelte | 74 ++++++ .../src/components/LanguagesPopup.svelte | 60 +++++ .../src/components/TranslationSettings.svelte | 82 ++++++ plugins/contact-resources/src/index.ts | 5 +- plugins/contact-resources/src/plugin.ts | 7 +- plugins/contact-resources/src/translation.ts | 78 ++++++ plugins/contact/package.json | 1 + plugins/contact/src/index.ts | 12 +- services/translate/package.json | 10 +- services/translate/src/config.ts | 38 ++- services/translate/src/conroller.ts | 233 ++++++++++++++++++ services/translate/src/index.ts | 38 ++- services/translate/src/main.ts | 0 services/translate/src/storage.ts | 150 +++++++++++ services/translate/src/utils.ts | 98 ++++++++ 40 files changed, 1302 insertions(+), 259 deletions(-) create mode 100644 plugins/contact-resources/src/components/LanguageEditor.svelte create mode 100644 plugins/contact-resources/src/components/LanguageIcon.svelte create mode 100644 plugins/contact-resources/src/components/LanguagePresenter.svelte create mode 100644 plugins/contact-resources/src/components/LanguagesArrayEditor.svelte create mode 100644 plugins/contact-resources/src/components/LanguagesPopup.svelte create mode 100644 plugins/contact-resources/src/components/TranslationSettings.svelte create mode 100644 plugins/contact-resources/src/translation.ts create mode 100644 services/translate/src/conroller.ts delete mode 100644 services/translate/src/main.ts create mode 100644 services/translate/src/storage.ts diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index ef86116d796..1c791584ca6 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -34,9 +34,6 @@ importers: '@faker-js/faker': specifier: ^8.4.1 version: 8.4.1 - '@hcengineering/communication-yaml': - specifier: ^0.1.0 - version: 0.1.195(typescript@5.8.3) '@hocuspocus/provider': specifier: ^2.15.2 version: 2.15.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)(y-protocols@1.0.6(yjs@13.6.23))(yjs@13.6.23) @@ -957,7 +954,7 @@ importers: version: file:projects/pod-telegram-bot.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(encoding@0.1.13)(gcp-metadata@5.3.0(encoding@0.1.13))(snappy@7.2.2)(socks@2.8.3) '@rush-temp/pod-translate': specifier: file:./projects/pod-translate.tgz - version: file:projects/pod-translate.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9)) + version: file:projects/pod-translate.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(ws@8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.24.2) '@rush-temp/pod-worker': specifier: file:./projects/pod-worker.tgz version: file:projects/pod-worker.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(webpack-cli@5.1.4) @@ -2014,6 +2011,9 @@ importers: form-data: specifier: ^4.0.0 version: 4.0.0 + franc-min: + specifier: ^6.2.0 + version: 6.2.0 gaxios: specifier: ^5.0.1 version: 5.1.3(encoding@0.1.13) @@ -2170,9 +2170,6 @@ importers: on-headers: specifier: ^1.0.2 version: 1.0.2 - openai: - specifier: ^4.56.0 - version: 4.56.0(encoding@0.1.13)(zod@3.24.2) openid-client: specifier: ~5.7.0 version: 5.7.0 @@ -3060,56 +3057,6 @@ packages: engines: {node: '>=6'} hasBin: true - '@hcengineering/analytics@0.7.242': - resolution: {integrity: sha512-lmNwY7FxXA9zQ4XsszWP0mjWR9fF0JhfUMvKtpJOeDgyGzH+o/ak1snN82s5x3SsuaHSM47mjo56OFQY6T8UFQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/analytics/0.7.242/5c0f56b0659f0592c4369ee839b3882856ffbec4} - - '@hcengineering/card@0.7.242': - resolution: {integrity: sha512-nnoDBBzymcJvwtk10uNy/bhkI12lSyIB4+GU+BmEnO+T/5/8iqk06ZVliop6ksmjlElSRn/QYV9EmZfB+Zsp5w==, tarball: https://npm.pkg.github.com/download/@hcengineering/card/0.7.242/471fe338fb94d1f99fd8a3ffe9b7f910441e48d1} - - '@hcengineering/communication-sdk-types@0.1.195': - resolution: {integrity: sha512-7c3o+qZ+4iJWDnJX6Yq6g62ZaybZO7uJf/jxfaoT0Ee1jtxgrltjXzWAJEK5LVpXzNN6oacVWxe7+W6vlZ6bQg==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-sdk-types/0.1.195/0adc1fcb52eb9ee69619808acba5e78e9a9aaa40} - peerDependencies: - typescript: ^5.6.3 - - '@hcengineering/communication-shared@0.1.195': - resolution: {integrity: sha512-i0Iq3Kil8IhbW9wS1MnzIjzmbNSP4ycZdsTZ61phKOYpShqDi0WubwMLmRzttnTHMLMTkuw77nXpHDuQCEsIrQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-shared/0.1.195/66db0b6e5c74227f07f791ad7a62d686b83561f2} - peerDependencies: - typescript: ^5.6.3 - - '@hcengineering/communication-types@0.1.195': - resolution: {integrity: sha512-a22nIhEZEGKVeY4pALG4OHROW3E6SKMDslyo1TNI9QR+upca/aX/gZxorc+HzLe3fkhj2BWkrDj3didGBBmJZQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-types/0.1.195/4bace160ae375c32f9c3e0b1814ce73944ec9829} - peerDependencies: - typescript: ^5.6.3 - - '@hcengineering/communication-yaml@0.1.195': - resolution: {integrity: sha512-vJrD8fYMYCOBJciYPV1oOy7z+4r80x4oG4ZFwYc/gMKe2J93z7uZajfBFSHfdhAH0iesIzykr1Ybk2DnL9+7Kw==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-yaml/0.1.195/d5864f390f1371f13cde0de387e792bef598c429} - peerDependencies: - typescript: ^5.6.3 - - '@hcengineering/core@0.7.242': - resolution: {integrity: sha512-fWxbCbPAyyh84oLIslxS2vdHb8uDcNqNDy1aRZcEarGEN7mdNPNCqok543D5KCqwXD/Wbegi7+Snx425T9U0Vw==, tarball: https://npm.pkg.github.com/download/@hcengineering/core/0.7.242/18e0bb24c985778998b7faef17776049c1e84782} - - '@hcengineering/measurements@0.7.242': - resolution: {integrity: sha512-azd72WdoMdQvpvkvUS7C3uIV9QCqk/wND8IWFfPJdzWA+tkGzsmkWw2jBI+l8M0T2WOerpozGiNxGTFfiC/U/Q==, tarball: https://npm.pkg.github.com/download/@hcengineering/measurements/0.7.242/b48fcc2c171a4282e6a71f7cd040703173d09c4f} - - '@hcengineering/platform@0.7.242': - resolution: {integrity: sha512-IbKw9w2I57IWsLMLo91s8+6gJoMqXwU0v4+0g0PgL0PVf5GNB/TMy2mWwP1FO26TzPa2awmeZm8TImDX1OjtPQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/platform/0.7.242/03295880d68708362268f4a1fff83546aa0ad371} - - '@hcengineering/preference@0.7.242': - resolution: {integrity: sha512-a5YaKxplzaGsc94ywaH1RL2OTirGYhRryCeBpIeUTwRDq+nSTKmnEkPFmxvGj+u47yKyXI+XSdAhpZawRiBhqA==, tarball: https://npm.pkg.github.com/download/@hcengineering/preference/0.7.242/60c05c79abe301623cd1fdf75edc9cbd09a59ed1} - - '@hcengineering/tags@0.7.242': - resolution: {integrity: sha512-MYHE9nb+sKqG4aZkQZimSLm/F7j2nCmTOeq55FRMBqGvFNyJ9iU/+vd7WfQkWMVN+9BdTnVEV4+6IAjgAFD11Q==, tarball: https://npm.pkg.github.com/download/@hcengineering/tags/0.7.242/0ef7f6034822a53e39dcb3f4c7f114636b33f6ae} - - '@hcengineering/theme@0.7.242': - resolution: {integrity: sha512-n5V3xWc7j9UabPm9z7mkt1OYKA8efonTggB0PH0g8FnErukebt1i1csjzeENqE/T7XaT47DqGj/6ZbiyU9vf4A==, tarball: https://npm.pkg.github.com/download/@hcengineering/theme/0.7.242/e78e29b3d0e4a400d90960f7135620087ab35a72} - - '@hcengineering/ui@0.7.242': - resolution: {integrity: sha512-8msNyxXOHUJKWAEao9GzNK0Z46OtTk+y3eFR07r6CYPOYzKjRnVPNZMfeEx81WsKxGMxj7HDxqV1XHEQiHYAAg==, tarball: https://npm.pkg.github.com/download/@hcengineering/ui/0.7.242/cbc28e51c81490fed8ddc8b8d0ce45ab59ff951f} - - '@hcengineering/view@0.7.242': - resolution: {integrity: sha512-qp7mBJ+bKIaH4NiLy34VU1I5jwDia6ezcPtV9SwqK8fl8s+QXWp75KAa7lMVtZZBM07nTLg5qJZNq4oyuIWIow==, tarball: https://npm.pkg.github.com/download/@hcengineering/view/0.7.242/ac007500e9b7b457546cfd4fd66fa3a23a4be3bc} - '@hocuspocus/common@2.15.2': resolution: {integrity: sha512-wU1wxXNnQQMXyeL3mdSDYiQsm/r/QyJVjjQhF7sUBrLnjdsN7bA1cvfcSvJBr1ymrMSeYRmUL3UlQmEHEOaP7w==} @@ -4624,7 +4571,7 @@ packages: version: 0.0.0 '@rush-temp/communication-client-query@file:projects/communication-client-query.tgz': - resolution: {integrity: sha512-6OA/sAql1ZLhhDX9J2yZOAEgfXqSxYh6yxpH/YGrC3PfYyhVAoe7piCjpB+JpKR5wL1kzpl1eP7Bj0IEq2jNJQ==, tarball: file:projects/communication-client-query.tgz} + resolution: {integrity: sha512-+68bXbpIU6XTujL5Dj3pFCdFelV7mE+Ln6zZEvf2NPHhAcJqy3+KjHQyIbytnWhCFsGyk+HE3S08ps6Kl6TKtw==, tarball: file:projects/communication-client-query.tgz} version: 0.0.0 '@rush-temp/communication-cockroach@file:projects/communication-cockroach.tgz': @@ -4632,7 +4579,7 @@ packages: version: 0.0.0 '@rush-temp/communication-query@file:projects/communication-query.tgz': - resolution: {integrity: sha512-MGyVKHjVsubVphvZfGCiHLqMaXiItQvbP8YxoWOXkDdg9OoUwg8u46f6QJD8j6I9E4LorKNGPxhXU4pJzdgxBQ==, tarball: file:projects/communication-query.tgz} + resolution: {integrity: sha512-KMDSFpLNW1ekFoAf+BbRxPeRYnMUjYu+l80F+fgtvkKsX/6oKtb6xRhQyVh4EQiRlQBaMV//1b2d7cBwuF5HDw==, tarball: file:projects/communication-query.tgz} version: 0.0.0 '@rush-temp/communication-resources@file:projects/communication-resources.tgz': @@ -4648,11 +4595,11 @@ packages: version: 0.0.0 '@rush-temp/communication-server@file:projects/communication-server.tgz': - resolution: {integrity: sha512-Yghkuyu3fA3Thmzo36T1nu62wgMI8GHQUTV7fj0dN12/Mi20JckxRSZDVKRnmRGhNqrzbj/O3DXAM02QpDIeAQ==, tarball: file:projects/communication-server.tgz} + resolution: {integrity: sha512-5tUXiwQ2Lf6j6y7h9+4qws7Wfi+m3ZnDNM5rochY3t4rzSccOJioVH5S85blTnYHstionXoNLuhRm0xJiJDELw==, tarball: file:projects/communication-server.tgz} version: 0.0.0 '@rush-temp/communication-shared@file:projects/communication-shared.tgz': - resolution: {integrity: sha512-SustnNpr/eopCXmm0ZahvUZXZPcD7psSWM+CkWVwiPlLVPGWMVUURFOcnC94F3OhY+7qu9N0Rgr3gDvr4VKXWA==, tarball: file:projects/communication-shared.tgz} + resolution: {integrity: sha512-/ZUh5sviGQkQGJnOe6ImJHpKCcn7xNyyMeOcl4Tr3TqXjsH+uOQ0MAFI0Ul4f1LI+dGIrp1QsZWSVWvEVprRQQ==, tarball: file:projects/communication-shared.tgz} version: 0.0.0 '@rush-temp/communication-types@file:projects/communication-types.tgz': @@ -4952,7 +4899,7 @@ packages: version: 0.0.0 '@rush-temp/love-resources@file:projects/love-resources.tgz': - resolution: {integrity: sha512-uB1RrbistrQwA5PIld+dgw+QnpTtS5i6wdiSAemCBe2ay5hTKExnmINPrgM/p7FEkya2sq3IVZXzric/ZYwnng==, tarball: file:projects/love-resources.tgz} + resolution: {integrity: sha512-d/rTH5piCl8x3YfKoZ2yIWklH/MU9h8WrccgwV9VS3a1lYQ2i6l+JVpO/hdMGTN6llF3REFNnMYndfcu8Siy4w==, tarball: file:projects/love-resources.tgz} version: 0.0.0 '@rush-temp/love@file:projects/love.tgz': @@ -5508,7 +5455,7 @@ packages: version: 0.0.0 '@rush-temp/pod-server@file:projects/pod-server.tgz': - resolution: {integrity: sha512-z4m5kjmQbBtpRI+5G9R5oylh5Z6IuWrTpC82zkrShOHVYLnLwKwDciVN5bbfAlISdb59ThXyiOzIA5Dr/gfl8g==, tarball: file:projects/pod-server.tgz} + resolution: {integrity: sha512-3n0/hgmREmz0totaUlNjkuPuS+kGz5ekL8OO3z/HsQyI/2vDx+p3O0DsDga2m1fGt296awP3MP/iqQIWwFPcNw==, tarball: file:projects/pod-server.tgz} version: 0.0.0 '@rush-temp/pod-sign@file:projects/pod-sign.tgz': @@ -5528,7 +5475,7 @@ packages: version: 0.0.0 '@rush-temp/pod-translate@file:projects/pod-translate.tgz': - resolution: {integrity: sha512-fqxgqmjuyGmxvqaFcaDGxdUVsXHQpWfbxOrQVIxUkcLTdKxGIyoYh9R4RVLJBSq08QKuAR8Mi+qyktRZbkNkSA==, tarball: file:projects/pod-translate.tgz} + resolution: {integrity: sha512-dcTbf1onpRiJ824qYEwOT1Vefkg1TAHR7IEPagUfADhv3pI06MFT4ZeVwuYZJDuI8tHlvaWejCaCWB+Ddwr/qg==, tarball: file:projects/pod-translate.tgz} version: 0.0.0 '@rush-temp/pod-worker@file:projects/pod-worker.tgz': @@ -6156,7 +6103,7 @@ packages: version: 0.0.0 '@rush-temp/tool@file:projects/tool.tgz': - resolution: {integrity: sha512-RQFbb0YGcuuAzNtGrbYDMyFE5VKDEsPA+bylES+hRUvKKBou2icVHwzDbFWrdSwGwfrr0ZhXVFQfTwSKOM18Bw==, tarball: file:projects/tool.tgz} + resolution: {integrity: sha512-FwR6SJSyoZvzT/0uIoItaG+S6N+ofaqtNJ4ZXRJ8f454jzOGrzjgjL+BupOX+xJCY4w9zNfpMOIke7e9LPX5pA==, tarball: file:projects/tool.tgz} version: 0.0.0 '@rush-temp/tracker-assets@file:projects/tracker-assets.tgz': @@ -8331,6 +8278,9 @@ packages: code-red@1.0.4: resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + collect-v8-coverage@1.0.2: resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} @@ -9924,6 +9874,9 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + franc-min@6.2.0: + resolution: {integrity: sha512-1uDIEUSlUZgvJa2AKYR/dmJC66v/PvGQ9mWfI9nOr/kPpMFyvswK0gPXOwpYJYiYD008PpHLkGfG58SPjQJFxw==} + fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -11798,6 +11751,9 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + n-gram@2.0.2: + resolution: {integrity: sha512-S24aGsn+HLBxUGVAUFOwGpKs7LBcG4RudKU//eWzt/mQ97/NMKQxDWHyHx63UNWk/OOdihgmzoETn1tf5nQDzQ==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -12056,6 +12012,18 @@ packages: zod: optional: true + openai@5.23.0: + resolution: {integrity: sha512-Cfq155NHzI7VWR67LUNJMIgPZy2oSh7Fld/OKhxq648BiUjELAvcge7g30xJ6vAfwwXf6TVK0KKuN+3nmIJG/A==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.23.8 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true @@ -13825,6 +13793,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trigram-utils@2.0.1: + resolution: {integrity: sha512-nfWIXHEaB+HdyslAfMxSqWKDdmqY9I32jS7GnqpdWQnLH89r6A5sdk3fDVYqGAZ0CrT8ovAFSAo6HRiWcWNIGQ==} + triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} engines: {node: '>= 14.0.0'} @@ -15651,100 +15622,6 @@ snapshots: protobufjs: 7.5.3 yargs: 17.7.2 - '@hcengineering/analytics@0.7.242': - dependencies: - '@hcengineering/platform': 0.7.242 - - '@hcengineering/card@0.7.242': - dependencies: - '@hcengineering/core': 0.7.242 - '@hcengineering/platform': 0.7.242 - '@hcengineering/preference': 0.7.242 - '@hcengineering/ui': 0.7.242 - '@hcengineering/view': 0.7.242 - - '@hcengineering/communication-sdk-types@0.1.195(typescript@5.8.3)': - dependencies: - '@hcengineering/communication-types': 0.1.195(typescript@5.8.3) - '@hcengineering/core': 0.7.242 - typescript: 5.8.3 - - '@hcengineering/communication-shared@0.1.195(typescript@5.8.3)': - dependencies: - '@hcengineering/communication-sdk-types': 0.1.195(typescript@5.8.3) - '@hcengineering/communication-types': 0.1.195(typescript@5.8.3) - typescript: 5.8.3 - - '@hcengineering/communication-types@0.1.195(typescript@5.8.3)': - dependencies: - '@hcengineering/card': 0.7.242 - '@hcengineering/core': 0.7.242 - '@hcengineering/tags': 0.7.242 - typescript: 5.8.3 - - '@hcengineering/communication-yaml@0.1.195(typescript@5.8.3)': - dependencies: - '@hcengineering/communication-shared': 0.1.195(typescript@5.8.3) - '@hcengineering/communication-types': 0.1.195(typescript@5.8.3) - js-yaml: 4.1.0 - typescript: 5.8.3 - - '@hcengineering/core@0.7.242': - dependencies: - '@hcengineering/analytics': 0.7.242 - '@hcengineering/measurements': 0.7.242 - '@hcengineering/platform': 0.7.242 - fast-equals: 5.2.2 - - '@hcengineering/measurements@0.7.242': {} - - '@hcengineering/platform@0.7.242': - dependencies: - intl-messageformat: 10.7.14 - - '@hcengineering/preference@0.7.242': - dependencies: - '@hcengineering/core': 0.7.242 - '@hcengineering/platform': 0.7.242 - '@hcengineering/ui': 0.7.242 - - '@hcengineering/tags@0.7.242': - dependencies: - '@hcengineering/core': 0.7.242 - '@hcengineering/platform': 0.7.242 - '@hcengineering/ui': 0.7.242 - '@hcengineering/view': 0.7.242 - - '@hcengineering/theme@0.7.242': - dependencies: - '@hcengineering/analytics': 0.7.242 - '@hcengineering/platform': 0.7.242 - svelte: 4.2.20 - - '@hcengineering/ui@0.7.242': - dependencies: - '@hcengineering/analytics': 0.7.242 - '@hcengineering/core': 0.7.242 - '@hcengineering/platform': 0.7.242 - '@hcengineering/theme': 0.7.242 - autolinker: 4.0.0 - blurhash: 2.0.5 - date-fns: 2.30.0 - date-fns-tz: 2.0.0(date-fns@2.30.0) - dompurify: 3.2.3 - emojibase: 16.0.0 - emojibase-regex: 16.0.0 - fast-equals: 5.2.2 - plyr: 3.7.8 - svelte: 4.2.20 - - '@hcengineering/view@0.7.242': - dependencies: - '@hcengineering/core': 0.7.242 - '@hcengineering/platform': 0.7.242 - '@hcengineering/preference': 0.7.242 - '@hcengineering/ui': 0.7.242 - '@hocuspocus/common@2.15.2': dependencies: lib0: 0.2.99 @@ -19239,7 +19116,6 @@ snapshots: '@rush-temp/communication-query@file:projects/communication-query.tgz(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3))': dependencies: - '@hcengineering/communication-yaml': 0.1.195(typescript@5.8.3) '@types/uuid': 8.3.4 '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.3))(eslint@8.56.0)(typescript@5.8.3) '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.8.3) @@ -19352,7 +19228,6 @@ snapshots: '@rush-temp/communication-server@file:projects/communication-server.tgz(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3))': dependencies: - '@hcengineering/communication-yaml': 0.1.195(typescript@5.8.3) '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.3))(eslint@8.56.0)(typescript@5.8.3) '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.8.3) esbuild: 0.25.9 @@ -19362,6 +19237,7 @@ snapshots: eslint-plugin-import: 2.29.1(eslint@8.56.0) eslint-plugin-n: 15.7.0(eslint@8.56.0) eslint-plugin-promise: 6.1.1(eslint@8.56.0) + franc-min: 6.2.0 jest: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3)) prettier: 3.2.5 typescript: 5.8.3 @@ -25929,7 +25805,7 @@ snapshots: - ts-node - utf-8-validate - '@rush-temp/pod-translate@file:projects/pod-translate.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))': + '@rush-temp/pod-translate@file:projects/pod-translate.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(ws@8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.24.2)': dependencies: '@tsconfig/node16': 1.0.4 '@types/jest': 29.5.12 @@ -25947,6 +25823,7 @@ snapshots: eslint-plugin-node: 11.1.0(eslint@8.56.0) eslint-plugin-promise: 6.1.1(eslint@8.56.0) jest: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3)) + openai: 5.23.0(ws@8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.24.2) prettier: 3.2.5 ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.25.9)(jest@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3)))(typescript@5.8.3) ts-node: 10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3) @@ -25960,6 +25837,8 @@ snapshots: - babel-plugin-macros - node-notifier - supports-color + - ws + - zod '@rush-temp/pod-worker@file:projects/pod-worker.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@swc/core@1.13.5)(babel-jest@29.7.0(@babel/core@7.23.9))(webpack-cli@5.1.4)': dependencies: @@ -30466,7 +30345,6 @@ snapshots: eslint-plugin-promise: 6.1.1(eslint@8.56.0) fast-equals: 5.2.2 jest: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.15.29)(typescript@5.8.3)) - js-yaml: 4.1.0 libphonenumber-js: 1.10.56 mime-types: 2.1.35 mongodb: 6.16.0(gcp-metadata@5.3.0(encoding@0.1.13))(snappy@7.2.2)(socks@2.8.3) @@ -33634,6 +33512,8 @@ snapshots: estree-walker: 3.0.3 periscopic: 3.1.0 + collapse-white-space@2.1.0: {} + collect-v8-coverage@1.0.2: {} color-convert@1.9.3: @@ -35537,6 +35417,10 @@ snapshots: fraction.js@4.3.7: {} + franc-min@6.2.0: + dependencies: + trigram-utils: 2.0.1 + fresh@0.5.2: {} fs-extra@10.1.0: @@ -37794,6 +37678,8 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + n-gram@2.0.2: {} + nanoid@3.3.11: {} napi-macros@2.0.0: @@ -38052,6 +37938,11 @@ snapshots: transitivePeerDependencies: - encoding + openai@5.23.0(ws@8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.24.2): + optionalDependencies: + ws: 8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4) + zod: 3.24.2 + opener@1.5.2: {} openid-client@5.7.0: @@ -40045,6 +39936,11 @@ snapshots: tree-kill@1.2.2: {} + trigram-utils@2.0.1: + dependencies: + collapse-white-space: 2.1.0 + n-gram: 2.0.2 + triple-beam@1.4.1: {} truncate-utf8-bytes@1.0.2: diff --git a/communication b/communication index 7afc4f0c882..2b0e3ab7fbe 160000 --- a/communication +++ b/communication @@ -1 +1 @@ -Subproject commit 7afc4f0c88244cdfb13efc1093766e088bcc1d6c +Subproject commit 2b0e3ab7fbee6e0a4f78b5d92af752e8a4de2508 diff --git a/dev/docker-compose.yaml b/dev/docker-compose.yaml index 53428510d9b..bb9a293b3d0 100644 --- a/dev/docker-compose.yaml +++ b/dev/docker-compose.yaml @@ -573,6 +573,7 @@ services: environment: - SECRET=secret - ACCOUNTS_URL=http://huly.local:3000 + - HULYLAKE_URL=http://huly.local:8096 - QUEUE_CONFIG=${QUEUE_CONFIG} - QUEUE_REGION=cockroach restart: unless-stopped diff --git a/models/contact/package.json b/models/contact/package.json index c3c5b3ccaaf..96278ca9bdb 100644 --- a/models/contact/package.json +++ b/models/contact/package.json @@ -50,6 +50,7 @@ "@hcengineering/model-view": "^0.6.0", "@hcengineering/model-workbench": "^0.6.1", "@hcengineering/model-card": "^0.6.0", + "@hcengineering/model-preference": "^0.6.0", "@hcengineering/notification": "^0.6.23", "@hcengineering/platform": "^0.6.11", "@hcengineering/setting": "^0.6.17", diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts index 70459acd782..94271f2b9f0 100644 --- a/models/contact/src/index.ts +++ b/models/contact/src/index.ts @@ -33,7 +33,8 @@ import { type PersonSpace, type SocialIdentity, type Status, - type SocialIdentityProvider + type SocialIdentityProvider, + type Translation } from '@hcengineering/contact' import { AccountRole, @@ -90,6 +91,7 @@ import { type AnyComponent } from '@hcengineering/ui/src/types' import { type Action } from '@hcengineering/view' import contact from './plugin' import { PaletteColorIndexes } from '@hcengineering/ui/src/colors' +import preference, { TPreference } from '@hcengineering/model-preference' export { contactId } from '@hcengineering/contact' export { contactOperation } from './migration' @@ -291,6 +293,14 @@ export class TUserRole extends TDoc implements UserRole { role!: Ref } +@Model(contact.class.Translation, preference.class.Preference) +export class TTranslation extends TPreference implements Translation { + declare attachedTo: Ref + enabled!: boolean + translateTo?: string + dontTranslate!: string[] +} + export function createModel (builder: Builder): void { builder.createModel( TAvatarProvider, @@ -306,7 +316,8 @@ export function createModel (builder: Builder): void { TMember, TContactsTab, TPersonSpace, - TUserRole + TUserRole, + TTranslation ) builder.mixin(contact.class.PersonSpace, core.class.Class, core.mixin.TxAccessLevel, { @@ -1405,4 +1416,14 @@ export function createModel (builder: Builder): void { isCustom: true, readonly: true }) + + builder.createDoc(setting.class.SettingsCategory, core.space.Model, { + name: 'translation', + label: contact.string.AutoTranslation, + icon: view.icon.Translate, + component: contact.component.TranslationSettings, + group: 'settings-account', + role: AccountRole.Guest, + order: 1600 + }) } diff --git a/models/contact/src/plugin.ts b/models/contact/src/plugin.ts index 74eaacf87c0..5414d33bd8f 100644 --- a/models/contact/src/plugin.ts +++ b/models/contact/src/plugin.ts @@ -58,7 +58,8 @@ export default mergeIds(contactId, contact, { EmployeeFilter: '' as AnyComponent, EmployeeFilterValuePresenter: '' as AnyComponent, ChannelIcon: '' as AnyComponent, - PersonPreviewPresenter: '' as AnyComponent + PersonPreviewPresenter: '' as AnyComponent, + TranslationSettings: '' as AnyComponent }, string: { SearchEmployee: '' as IntlString, diff --git a/plugins/communication-resources/src/actions.ts b/plugins/communication-resources/src/actions.ts index 300cf81bcdc..b76884afa57 100644 --- a/plugins/communication-resources/src/actions.ts +++ b/plugins/communication-resources/src/actions.ts @@ -42,7 +42,13 @@ import aiBot from '@hcengineering/ai-bot' import CreateCardFromMessagePopup from './components/CreateCardFromMessagePopup.svelte' import { isCardAllowedForCommunications, showForbidden, toggleReaction, toMarkup } from './utils' -import { isMessageTranslating, messageEditingStore, threadCreateMessageStore, translateMessagesStore } from './stores' +import { + isMessageTranslating, + messageEditingStore, + showOriginalMessagesStore, + threadCreateMessageStore, + translateMessagesStore +} from './stores' export const addReaction: MessageActionFunction = async (message, card: Card, evt, onOpen, onClose) => { if (!isCardAllowedForCommunications(card)) { @@ -151,34 +157,41 @@ export const canReplyInThread: MessageActionVisibilityTester = (message: Message } export const translateMessage: MessageActionFunction = async (message: Message): Promise => { - if (isMessageTranslating(message.id)) return - const result = get(translateMessagesStore).get(message.id) + if (isMessageTranslating(message.cardId, message.id)) return + const result = get(translateMessagesStore).find((it) => it.cardId === message.cardId && it.messageId === message.id) - if (result?.result != null) { - translateMessagesStore.update((store) => { - store.set(message.id, { ...result, shown: true }) - return store - }) + if (result != null) { + showOriginalMessagesStore.update((store) => + store.filter(([cId, mId]) => cId !== message.cardId || mId !== message.id) + ) return } translateMessagesStore.update((store) => { - store.set(message.id, { inProgress: true, shown: false }) + store.push({ inProgress: true, messageId: message.id, cardId: message.cardId }) return store }) const markup = toMarkup(message.content) - const response = await aiTranslate(markup, get(languageStore)) + const lang = get(languageStore) + const response = message?.translates?.[lang] ?? (await aiTranslate(markup, lang))?.text if (response !== undefined) { translateMessagesStore.update((store) => { - store.set(message.id, { inProgress: false, result: response.text, shown: true }) - return store + return store.map((it) => { + if (it.cardId === message.cardId && it.messageId === message.id) { + return { + ...it, + inProgress: false, + result: response + } + } + return it + }) }) } else { translateMessagesStore.update((store) => { - store.delete(message.id) - return store + return store.filter((it) => it.cardId !== message.cardId || it.messageId !== message.id) }) } } @@ -191,10 +204,9 @@ export const canTranslateMessage: MessageActionVisibilityTester = (message: Mess export const showOriginalMessage: MessageActionFunction = async (message: Message): Promise => { const messageId = message.id - translateMessagesStore.update((store) => { - const status = store.get(messageId) - if (status == null) return store - store.set(messageId, { ...status, shown: false }) + + showOriginalMessagesStore.update((store) => { + store.push([message.cardId, messageId]) return store }) } diff --git a/plugins/communication-resources/src/components/MessagesList.svelte b/plugins/communication-resources/src/components/MessagesList.svelte index 259a06b44b6..419b0fca673 100644 --- a/plugins/communication-resources/src/components/MessagesList.svelte +++ b/plugins/communication-resources/src/components/MessagesList.svelte @@ -31,6 +31,7 @@ import { createEventDispatcher, onDestroy, onMount, tick } from 'svelte' import { MessagesNavigationAnchors } from '@hcengineering/communication' import { deviceOptionsStore as deviceInfo, isAppFocusedStore } from '@hcengineering/ui' + import { translationStore } from '@hcengineering/contact-resources' import { createMessagesObserver, getGroupDay, groupMessagesByDay, MessagesGroup } from '../messages' import MessagesGroupPresenter from './message/MessagesGroupPresenter.svelte' @@ -101,6 +102,8 @@ readNotifications(new Date()) } + $: translation = $translationStore + $: reinit(position) $: query.query( @@ -123,7 +126,8 @@ autoExpand: true, threads: true, attachments: true, - reactions: true + reactions: true, + language: translation?.enabled === true ? translation?.translateTo : undefined } ) diff --git a/plugins/communication-resources/src/components/message/MessageBody.svelte b/plugins/communication-resources/src/components/message/MessageBody.svelte index e896569990a..38f4f3f45c1 100644 --- a/plugins/communication-resources/src/components/message/MessageBody.svelte +++ b/plugins/communication-resources/src/components/message/MessageBody.svelte @@ -14,9 +14,9 @@ --> {#if compact || hideHeader} @@ -102,12 +137,12 @@ (