From ba1802aa9b2058a8da0c1bdf18ad9546fb8dafb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Mon, 11 Aug 2025 15:33:55 +0200 Subject: [PATCH 01/16] feat: support new import endpoint fix: add jest tests to pipeline feat: display non-overridable conflicts --- .github/workflows/test.yml | 4 + jest.config.js | 11 + package-lock.json | 151 +- package.json | 10 +- src/tools/satisfiesMinimalVersion.test.ts | 24 + src/tools/satisfiesMinimalVersion.ts | 19 + src/ui/client/apiSchema.generated.ts | 9420 +++++++++++------ src/ui/client/client.ts | 4 + src/ui/views/Push/Push.tsx | 177 +- src/ui/views/Push/UnresolvedConflicts.css | 11 + .../views/Push/UnresolvedConflicts.css.d.ts | 6 + src/ui/views/Push/UnresolvedConflicts.tsx | 41 + src/ui/views/Push/usePush.ts | 219 + 13 files changed, 6653 insertions(+), 3444 deletions(-) create mode 100644 jest.config.js create mode 100644 src/tools/satisfiesMinimalVersion.test.ts create mode 100644 src/tools/satisfiesMinimalVersion.ts create mode 100644 src/ui/views/Push/UnresolvedConflicts.css create mode 100644 src/ui/views/Push/UnresolvedConflicts.css.d.ts create mode 100644 src/ui/views/Push/UnresolvedConflicts.tsx create mode 100644 src/ui/views/Push/usePush.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6c69aa6..b5fb454 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -70,6 +70,10 @@ jobs: - name: Install run: npm ci + + - name: Test + run: npm run test + - name: Cypress run run: npm run cy:run diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..86f88fb --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +const { createDefaultPreset } = require("ts-jest"); + +const tsJestTransformCfg = createDefaultPreset().transform; + +/** @type {import("jest").Config} **/ +module.exports = { + testEnvironment: "node", + transform: { + ...tsJestTransformCfg, + }, +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ed083d2..948e39f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "@create-figma-plugin/build": "^3.1.0", "@create-figma-plugin/tsconfig": "^3.1.0", "@figma/plugin-typings": "^1.89.0", - "@types/jest": "^29.4.0", + "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^5.48.1", "@typescript-eslint/parser": "^5.48.1", "colors": "^1.4.0", @@ -39,15 +39,16 @@ "eslint-config-preact": "^1.3.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.32.0", - "jest": "^29.3.1", + "jest": "^29.7.0", "nodemon": "^2.0.20", "openapi-typescript": "^6.1.0", "prettier": "^2.8.2", "serve": "^14.2.0", "svg-icon": "^0.8.2", "terminate": "^2.6.1", + "ts-jest": "^29.4.1", "ts-node": "^10.9.1", - "typescript": "^5.4.5" + "typescript": "^5.9.2" } }, "node_modules/@ampproject/remapping": { @@ -2749,10 +2750,11 @@ } }, "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -3948,6 +3950,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -7580,6 +7595,28 @@ "node": ">=0.10.0" } }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -8811,6 +8848,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -10183,6 +10221,13 @@ "node": ">= 0.6" } }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -13788,6 +13833,72 @@ "tree-kill": "cli.js" } }, + "node_modules/ts-jest": { + "version": "29.4.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.1.tgz", + "integrity": "sha512-SaeUtjfpg9Uqu8IbeDKtdaS0g8lS6FT6OzM3ezrDfErPJPHNDo/Ey+VFGP1bQIDfagYDLyRpd7O15XpG1Es2Uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.2", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -14086,10 +14197,11 @@ "dev": true }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14098,6 +14210,20 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -14674,6 +14800,13 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 896f55e..7bf8aab 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "build": "build-figma-plugin --typecheck --minify", "watch": "build-figma-plugin --typecheck --watch", - "schema": "openapi-typescript http://localhost:8080/v3/api-docs/Accessible%20with%20API%20key --output ./src/client/apiSchema.generated.ts", + "test": "npx jest", + "schema": "openapi-typescript \"http://localhost:8080/v3/api-docs/Accessible%20with%20Project%20API%20key%20(All)\" --output ./src/ui/client/apiSchema.generated.ts", "eslint": "eslint --ext .ts,.tsx,.js,.jsx src", "watch:web": "npm run --prefix web watch", "dev:web": "ts-node ./scripts/runAfterApp.ts \"npm run watch:web\"", @@ -23,7 +24,7 @@ "@create-figma-plugin/build": "^3.1.0", "@create-figma-plugin/tsconfig": "^3.1.0", "@figma/plugin-typings": "^1.89.0", - "@types/jest": "^29.4.0", + "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^5.48.1", "@typescript-eslint/parser": "^5.48.1", "colors": "^1.4.0", @@ -35,15 +36,16 @@ "eslint-config-preact": "^1.3.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.32.0", - "jest": "^29.3.1", + "jest": "^29.7.0", "nodemon": "^2.0.20", "openapi-typescript": "^6.1.0", "prettier": "^2.8.2", "serve": "^14.2.0", "svg-icon": "^0.8.2", "terminate": "^2.6.1", + "ts-jest": "^29.4.1", "ts-node": "^10.9.1", - "typescript": "^5.4.5" + "typescript": "^5.9.2" }, "dependencies": { "@codemirror/autocomplete": "^6.18.6", diff --git a/src/tools/satisfiesMinimalVersion.test.ts b/src/tools/satisfiesMinimalVersion.test.ts new file mode 100644 index 0000000..dafd55e --- /dev/null +++ b/src/tools/satisfiesMinimalVersion.test.ts @@ -0,0 +1,24 @@ +import { satisfiesMinimalVersion } from "./satisfiesMinimalVersion"; + +describe("checks platform version correctly", () => { + it("returns true if version is lower", () => { + expect(satisfiesMinimalVersion("v1.2.3", "v1.2.2")).toEqual(false); + expect(satisfiesMinimalVersion("v1.2.3", "v1.2.1")).toEqual(false); + expect(satisfiesMinimalVersion("v1.2.3", "v1.1.4")).toEqual(false); + expect(satisfiesMinimalVersion("v1.2.3", "v0.0.0")).toEqual(false); + }); + + it("returns true if version is higher", () => { + expect(satisfiesMinimalVersion("v1.2.3", "v1.2.3")).toEqual(true); + expect(satisfiesMinimalVersion("v1.2.3", "v1.2.4")).toEqual(true); + expect(satisfiesMinimalVersion("v1.2.3", "v1.4.2")).toEqual(true); + expect(satisfiesMinimalVersion("v1.2.3", "v2.0.0")).toEqual(true); + }); + + it("returns undefined if version is invalid", () => { + expect(satisfiesMinimalVersion("v1.2.3", "local")).toBeUndefined(); + expect(satisfiesMinimalVersion("v1.2.3", "??")).toBeUndefined(); + expect(satisfiesMinimalVersion("v1.2.3", "invalid")).toBeUndefined(); + expect(satisfiesMinimalVersion("v1.2.3", undefined)).toBeUndefined(); + }); +}); diff --git a/src/tools/satisfiesMinimalVersion.ts b/src/tools/satisfiesMinimalVersion.ts new file mode 100644 index 0000000..cec8e42 --- /dev/null +++ b/src/tools/satisfiesMinimalVersion.ts @@ -0,0 +1,19 @@ +const SEMVER_REGEX = /^v[0-9]+\.[0-9]+\.[0-9]+$/; + +export const satisfiesMinimalVersion = ( + requiredV: string, + currentV: string | undefined +) => { + if (!currentV || !SEMVER_REGEX.test(currentV)) { + return undefined; + } + const result = requiredV.localeCompare(currentV, "en", { + numeric: true, + sensitivity: "base", + }); + + if (result > 0) { + return false; + } + return true; +}; diff --git a/src/ui/client/apiSchema.generated.ts b/src/ui/client/apiSchema.generated.ts index 87c3c8b..b99a0fc 100644 --- a/src/ui/client/apiSchema.generated.ts +++ b/src/ui/client/apiSchema.generated.ts @@ -5,419 +5,441 @@ export interface paths { - "/v2/user": { + "/api/project/export/jsonZip": { /** - * Get user info - * @description Returns information about currently authenticated user. + * Export to ZIP of jsons + * @deprecated + * @description Exports data as ZIP of jsons */ - get: operations["getInfo_2"]; + get: operations["doExportJsonZip_1"]; }; - "/v2/projects/tasks/{taskNumber}/reopen": { - /** Reopen task */ - put: operations["reopenTask_1"]; + "/v2/api-keys/current": { + /** + * Get current API key info + * @description Returns info the API key which user currently authenticated with. Otherwise responds with 400 status code. + */ + get: operations["getCurrent_1"]; }; - "/v2/projects/tasks/{taskNumber}/keys/{keyId}": { + "/v2/api-keys/current-permissions": { /** - * Update task key - * @description Mark key as done, which updates task progress. + * Get current permission info + * @description Returns current PAK or PAT permissions for current user, api-key and project */ - put: operations["updateTaskKey_1"]; + get: operations["getCurrentPermissions"]; }; - "/v2/projects/tasks/{taskNumber}/keys": { - /** Get task keys */ - get: operations["getTaskKeys_1"]; - /** Add or remove task keys */ - put: operations["updateTaskKeys_1"]; + "/v2/auth-provider": { + /** Get current third party authentication provider */ + get: operations["getCurrentAuthProvider"]; + /** Initiate provider change to remove current third party authentication provider */ + delete: operations["deleteCurrentAuthProvider"]; }; - "/v2/projects/tasks/{taskNumber}/finish": { - /** Finish task */ - put: operations["finishTask_1"]; + "/v2/auth-provider/change": { + /** Get info about authentication provider which can replace the current one */ + get: operations["getChangedAuthProvider"]; + /** Accept change of the third party authentication provider */ + post: operations["acceptChangeAuthProvider"]; + /** Reject change of the third party authentication provider */ + delete: operations["rejectChangeAuthProvider"]; }; - "/v2/projects/tasks/{taskNumber}/close": { - /** Close task */ - put: operations["closeTask_1"]; + "/v2/image-upload": { + /** Upload an image for later use */ + post: operations["upload"]; }; - "/v2/projects/tasks/{taskNumber}": { - /** Get task */ - get: operations["getTask_1"]; - /** Update task */ - put: operations["updateTask_1"]; + "/v2/image-upload/{ids}": { + /** Delete uploaded images */ + delete: operations["delete_14"]; }; - "/v2/projects/namespaces/{id}": { - /** Update namespace */ - put: operations["update_2"]; + "/v2/notification": { + /** Gets notifications of the currently logged in user, newest is first. */ + get: operations["getNotifications"]; }; - "/v2/projects/keys/{id}/disabled-languages": { + "/v2/notification-settings": { /** - * Get disabled languages - * @description Returns languages, in which key is disabled + * Get notification settings + * @description Returns notification settings of the currently logged in user */ - get: operations["getDisabledLanguages_1"]; + get: operations["getNotificationsSettings"]; /** - * Set disabled languages - * @description Sets languages, in which key is disabled + * Save notification setting + * @description Saves new value for given parameters */ - put: operations["setDisabledLanguages_1"]; + put: operations["putNotificationSetting"]; }; - "/v2/projects/keys/{id}/complex-update": { + "/v2/notifications-mark-seen": { + /** Marks notifications of the currently logged in user with given IDs as seen. */ + put: operations["markNotificationsAsSeen"]; + }; + "/v2/organizations": { /** - * Edit key and related data - * @description Edits key name, translations, tags, screenshots, and other data + * Get all permitted organizations + * @description Returns all organizations, which is current user allowed to view */ - put: operations["complexEdit_1"]; + get: operations["getAll_12"]; + /** Create organization */ + post: operations["create_12"]; }; - "/v2/projects/keys/{id}": { - /** Get one key */ - get: operations["get_7"]; - /** Edit key name */ - put: operations["edit_1"]; + "/v2/organizations/{id}": { + /** Get one organization */ + get: operations["get_23"]; }; - "/v2/projects/tag-complex": { - /** Execute complex tag operation */ - put: operations["executeComplexTagOperation_1"]; + "/v2/organizations/{organizationId}/glossaries": { + /** Get all organization glossaries */ + get: operations["getAll_14"]; + /** Create glossary */ + post: operations["create_13"]; }; - "/v2/projects/keys/{keyId}/tags": { + "/v2/organizations/{organizationId}/glossaries-with-stats": { + /** Get all organization glossaries with some additional statistics */ + get: operations["getAllWithStats"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}": { + /** Get glossary */ + get: operations["get_20"]; + /** Update glossary */ + put: operations["update_8"]; + /** Delete glossary */ + delete: operations["delete_11"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/assigned-projects": { + /** Get all projects assigned to glossary */ + get: operations["getAssignedProjects"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/languages": { + /** Get all languages in use by the glossary */ + get: operations["getLanguages"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/terms": { + /** Get all glossary terms */ + get: operations["getAll_15"]; + /** Create a new glossary term */ + post: operations["create_14"]; + /** Batch delete multiple terms */ + delete: operations["deleteMultiple"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/terms/{termId}": { + /** Get glossary term */ + get: operations["get_21"]; + /** Update glossary term */ + put: operations["update_9"]; + /** Delete glossary term */ + delete: operations["delete_12"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/terms/{termId}/translations": { + /** Set a new glossary term translation for language */ + post: operations["update_12"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/terms/{termId}/translations/{languageTag}": { + /** Get glossary term translation for language */ + get: operations["get_22"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/termsIds": { + /** Get all glossary terms ids */ + get: operations["getAllIds"]; + }; + "/v2/organizations/{organizationId}/glossaries/{glossaryId}/termsWithTranslations": { + /** Get all glossary terms with translations */ + get: operations["getAllWithTranslations"]; + }; + "/v2/organizations/{organizationId}/machine-translation-credit-balance": { /** - * Tag key - * @description Tags a key with tag. If tag with provided name doesn't exist, it is created + * Get credit balance for organization + * @description Returns machine translation credit balance for organization */ - put: operations["tagKey_1"]; + get: operations["getOrganizationCredits"]; }; - "/v2/projects/import/result/languages/{languageId}/translations/{translationId}/resolve/set-override": { + "/v2/organizations/{slug}": { + /** Get organization by slug */ + get: operations["get_19"]; + }; + "/v2/pats/current": { /** - * Resolve conflict (override) - * @description Resolves translation conflict. The old translation will be overridden. + * Return current PAK + * @description Returns current Personal Access Token. If the request is not authenticated with a Personal Access Token, it will return 400 response status. */ - put: operations["resolveTranslationSetOverride_1"]; + get: operations["getCurrent"]; }; - "/v2/projects/import/result/languages/{languageId}/translations/{translationId}/resolve/set-keep-existing": { + "/v2/projects": { /** - * Resolve conflict (keep existing) - * @description Resolves translation conflict. The old translation will be kept. + * Get all permitted + * @description Returns all projects where current user has any permission */ - put: operations["resolveTranslationSetKeepExisting_1"]; - }; - "/v2/projects/import/result/languages/{languageId}/resolve-all/set-override": { + get: operations["getAll"]; /** - * Resolve all translation conflicts (override) - * @description Resolves all translation conflicts for provided language. The old translations will be overridden. + * Create project + * @description Creates a new project with languages and initial settings. */ - put: operations["resolveTranslationSetOverride_3"]; + post: operations["createProject"]; }; - "/v2/projects/import/result/languages/{languageId}/resolve-all/set-keep-existing": { + "/v2/projects/activity": { + /** Get project activity */ + get: operations["getActivity_1"]; + }; + "/v2/projects/activity/revisions/{revisionId}": { + /** Get one revision data */ + get: operations["getSingleRevision_1"]; + }; + "/v2/projects/batch-jobs": { + /** List batch operations */ + get: operations["list_1"]; + }; + "/v2/projects/batch-jobs/{id}": { + /** Get batch operation */ + get: operations["get_7"]; + }; + "/v2/projects/batch-jobs/{id}/cancel": { /** - * Resolve all translation conflicts (keep existing) - * @description Resolves all translation conflicts for provided language. The old translations will be kept. + * Stop batch operation + * @description Stops batch operation if possible. */ - put: operations["resolveTranslationSetKeepExisting_3"]; + put: operations["cancel_1"]; }; - "/v2/projects/import/result/languages/{importLanguageId}/select-existing/{existingLanguageId}": { + "/v2/projects/big-meta": { /** - * Pair existing language - * @description Sets existing language to pair with language to import. Data will be imported to selected existing language when applied. + * Store Big Meta + * @description Stores a bigMeta for a project */ - put: operations["selectExistingLanguage_1"]; + post: operations["store_3"]; }; - "/v2/projects/import/result/languages/{importLanguageId}/reset-existing": { + "/v2/projects/current-batch-jobs": { /** - * Reset existing language pairing - * @description Resets existing language paired with language to import. + * Get all running and pending batch operations + * @description Returns all running and pending batch operations. Completed batch operations are returned only if they are not older than 1 hour. If user doesn't have permission to view all batch operations, only their operations are returned. */ - put: operations["resetExistingLanguage_1"]; + get: operations["currentJobs_1"]; }; - "/v2/projects/import/result/files/{fileId}/select-namespace": { + "/v2/projects/export": { + /** Export data */ + get: operations["exportData_1"]; /** - * Select namespace - * @description Sets namespace for file to import. + * Export data (post) + * @description Exports data (post). Useful when exceeding allowed URL size. */ - put: operations["selectNamespace_1"]; + post: operations["exportPost_1"]; }; - "/v2/projects/import/apply-streaming": { + "/v2/projects/import": { /** - * Apply import (streaming) - * @description Imports the data prepared in previous step. Streams current status. + * Add files + * @description Prepares provided files to import. */ - put: operations["applyImportStreaming_1"]; - }; - "/v2/projects/import/apply": { + post: operations["addFiles_1"]; /** - * Apply import - * @description Imports the data prepared in previous step + * Delete + * @description Deletes prepared import data. */ - put: operations["applyImport_1"]; + delete: operations["cancelImport_1"]; }; "/v2/projects/import-settings": { /** * Get Import Settings * @description Returns import settings for the authenticated user and the project. */ - get: operations["get_11"]; + get: operations["get_5"]; /** * Set Import Settings * @description Stores import settings for the authenticated user and the project. */ put: operations["store_1"]; }; - "/v2/projects/batch-jobs/{id}/cancel": { + "/v2/projects/import/all-namespaces": { /** - * Stop batch operation - * @description Stops batch operation if possible. + * Get namespaces + * @description Returns all existing and imported namespaces */ - put: operations["cancel_1"]; - }; - "/v2/projects/translations/{translationId}/set-state/{state}": { - /** Set translation state */ - put: operations["setTranslationState_1"]; - }; - "/v2/projects/translations/{translationId}/comments/{commentId}/set-state/{state}": { - /** Set state of translation comment */ - put: operations["setState_1"]; - }; - "/v2/projects/translations/{translationId}/comments/{commentId}": { - /** Get one translation comment */ - get: operations["get_15"]; - /** Update translation comment */ - put: operations["update_6"]; - /** Delete translation comment */ - delete: operations["delete_9"]; + get: operations["getAllNamespaces_1"]; }; - "/v2/projects/translations/{translationId}/set-outdated-flag/{state}": { + "/v2/projects/import/apply": { /** - * Set outdated value - * @description Set's "outdated" flag indicating the base translation was changed without updating current translation. + * Apply import + * @description Imports the data prepared in previous step */ - put: operations["setOutdated_1"]; + put: operations["applyImport_1"]; }; - "/v2/projects/translations/{translationId}/dismiss-auto-translated-state": { + "/v2/projects/import/apply-streaming": { /** - * Dismiss auto-translated - * @description Removes "auto translated" indication + * Apply import (streaming) + * @description Imports the data prepared in previous step. Streams current status. */ - put: operations["dismissAutoTranslatedState_1"]; + put: operations["applyImportStreaming_1"]; }; - "/v2/projects/translations": { - /** Get translations in project */ - get: operations["getTranslations_1"]; + "/v2/projects/import/result": { /** - * Update translations for existing key - * @description Sets translations for existing key + * Get result + * @description Returns the result of preparation. */ - put: operations["setTranslations_1"]; + get: operations["getImportResult_1"]; + }; + "/v2/projects/import/result/files/{fileId}/select-namespace": { /** - * Create key or update translations - * @description Sets translations for existing key or creates new key and sets the translations to it. + * Select namespace + * @description Sets namespace for file to import. */ - post: operations["createOrUpdateTranslations_1"]; - }; - "/v2/projects/languages/{languageId}": { - /** Get one language */ - get: operations["get_17"]; - /** Update language */ - put: operations["editLanguage_1"]; - /** Delete specific language */ - delete: operations["deleteLanguage_3"]; + put: operations["selectNamespace_1"]; }; - "/v2/projects/keys/{keyId}/auto-translate": { + "/v2/projects/import/result/files/{importFileId}/issues": { /** - * Auto translates keys - * @description Uses enabled auto-translation methods. - * You need to set at least one of useMachineTranslation or useTranslationMemory to true. - * - * This will replace the the existing translation with the result obtained from specified source! + * Get file issues + * @description Returns issues for uploaded file. */ - put: operations["autoTranslate_1"]; + get: operations["getImportFileIssues_1"]; }; - "/v2/organizations/{id}": { - /** Get one organization */ - get: operations["get_20"]; - }; - "/v2/projects": { + "/v2/projects/import/result/languages/{importLanguageId}/reset-existing": { /** - * Get all permitted - * @description Returns all projects where current user has any permission + * Reset existing language pairing + * @description Resets existing language paired with language to import. */ - get: operations["getAll"]; + put: operations["resetExistingLanguage_1"]; + }; + "/v2/projects/import/result/languages/{importLanguageId}/select-existing/{existingLanguageId}": { /** - * Create project - * @description Creates a new project with languages and initial settings. + * Pair existing language + * @description Sets existing language to pair with language to import. Data will be imported to selected existing language when applied. */ - post: operations["createProject"]; - }; - "/v2/projects/tasks/create-multiple-tasks": { - /** Create multiple tasks */ - post: operations["createTasks_1"]; + put: operations["selectExistingLanguage_1"]; }; - "/v2/projects/tasks/calculate-scope": { - /** Calculate scope */ - post: operations["calculateScope_1"]; + "/v2/projects/import/result/languages/{languageId}": { + /** + * Get import language + * @description Returns language prepared to import. + */ + get: operations["getImportLanguage_1"]; + /** + * Delete language + * @description Deletes language prepared to import. + */ + delete: operations["deleteLanguage_1"]; }; - "/v2/projects/tasks": { - /** Get tasks */ - get: operations["getTasks_2"]; - /** Create task */ - post: operations["createTask_1"]; + "/v2/projects/import/result/languages/{languageId}/resolve-all/set-keep-existing": { + /** + * Resolve all translation conflicts (keep existing) + * @description Resolves all translation conflicts for provided language. The old translations will be kept. + */ + put: operations["resolveTranslationSetKeepExisting_3"]; }; - "/v2/projects/keys/info": { + "/v2/projects/import/result/languages/{languageId}/resolve-all/set-override": { /** - * Get key info - * @description Returns information about keys. (KeyData, Screenshots, Translation in specified language)If key is not found, it's not included in the response. + * Resolve all translation conflicts (override) + * @description Resolves all translation conflicts for provided language. The old translations will be overridden. */ - post: operations["getInfo_1"]; + put: operations["resolveTranslationSetOverride_3"]; }; - "/v2/projects/keys/import-resolvable": { + "/v2/projects/import/result/languages/{languageId}/translations": { /** - * Import keys (resolvable) - * @description Import's new keys with translations. Translations can be updated, when specified. + * Get translations + * @description Returns translations prepared to import. */ - post: operations["importKeys_1"]; + get: operations["getImportTranslations_1"]; }; - "/v2/projects/keys/import": { + "/v2/projects/import/result/languages/{languageId}/translations/{translationId}/resolve/set-keep-existing": { /** - * Import keys - * @description Imports new keys with translations. If key already exists, its translations and tags are not updated. + * Resolve conflict (keep existing) + * @description Resolves translation conflict. The old translation will be kept. */ - post: operations["importKeys_3"]; + put: operations["resolveTranslationSetKeepExisting_1"]; }; - "/v2/projects/keys/create": { - /** Create new key */ - post: operations["create_3"]; + "/v2/projects/import/result/languages/{languageId}/translations/{translationId}/resolve/set-override": { + /** + * Resolve conflict (override) + * @description Resolves translation conflict. The old translation will be overridden. + */ + put: operations["resolveTranslationSetOverride_1"]; }; "/v2/projects/keys": { /** Get all keys */ - get: operations["getAll_2"]; + get: operations["getAll_10"]; /** Create new key */ - post: operations["create_4"]; + post: operations["create_8"]; /** * Delete one or multiple keys (post) * @description Delete one or multiple keys by their IDs in request body. Useful for larger requests esxceeding allowed URL length. */ - delete: operations["delete_5"]; - }; - "/v2/projects/start-batch-job/untag-keys": { - /** Remove tags */ - post: operations["untagKeys_1"]; - }; - "/v2/projects/start-batch-job/tag-keys": { - /** Add tags */ - post: operations["tagKeys_1"]; - }; - "/v2/projects/start-batch-job/set-translation-state": { - /** Set translation state */ - post: operations["setTranslationState_3"]; + delete: operations["delete_7"]; }; - "/v2/projects/start-batch-job/set-keys-namespace": { - /** Set keys namespace */ - post: operations["setKeysNamespace_1"]; - }; - "/v2/projects/start-batch-job/pre-translate-by-tm": { - /** - * Pre-translate by TM - * @description Pre-translate provided keys to provided languages by TM. - */ - post: operations["translate_1"]; + "/v2/projects/keys/create": { + /** Create new key */ + post: operations["create_7"]; }; - "/v2/projects/start-batch-job/machine-translate": { + "/v2/projects/keys/import": { /** - * Machine Translation - * @description Translate provided keys to provided languages through primary MT provider. + * Import keys + * @description Imports new keys with translations. If key already exists, its translations and tags are not updated. */ - post: operations["machineTranslation_1"]; - }; - "/v2/projects/start-batch-job/delete-keys": { - /** Delete keys */ - post: operations["deleteKeys_1"]; + post: operations["importKeys_3"]; }; - "/v2/projects/start-batch-job/copy-translations": { + "/v2/projects/keys/import-resolvable": { /** - * Copy translation values - * @description Copy translation values from one language to other languages. + * Import keys (resolvable) + * @deprecated + * @description + * Import's new keys with translations. Translations can be updated, when specified. + * DEPRECATED: Use /v2/projects/{projectId}/single-step-import-resolvable instead. */ - post: operations["copyTranslations_1"]; + post: operations["importKeys_1"]; }; - "/v2/projects/start-batch-job/clear-translations": { + "/v2/projects/keys/info": { /** - * Clear translation values - * @description Clear translation values for provided keys in selected languages. + * Get key info + * @description Returns information about keys. (KeyData, Screenshots, Translation in specified language)If key is not found, it's not included in the response. */ - post: operations["clearTranslations_1"]; + post: operations["getInfo_1"]; }; - "/v2/projects/single-step-import": { + "/v2/projects/keys/search": { /** - * Single step import - * @description Unlike the /v2/projects/{projectId}/import endpoint, imports the data in single request by provided files and parameters. This is useful for automated importing via API or CLI. + * Search for keys + * @description This endpoint helps you to find desired key by keyName, base translation or translation in specified language. + * + * Sort is ignored for this request. */ - post: operations["doImport_1"]; + get: operations["searchForKey_1"]; }; - "/v2/projects/import": { - /** - * Add files - * @description Prepares provided files to import. - */ - post: operations["addFiles_1"]; + "/v2/projects/keys/select": { /** - * Delete - * @description Deletes prepared import data. + * Select keys + * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. */ - delete: operations["cancelImport_1"]; + get: operations["selectKeys_3"]; }; - "/v2/projects/export": { - /** Export data */ - get: operations["export_1"]; - /** - * Export data (post) - * @description Exports data (post). Useful when exceeding allowed URL size. - */ - post: operations["exportPost_1"]; + "/v2/projects/keys/{ids}": { + /** Delete one or multiple keys */ + delete: operations["delete_5"]; }; - "/v2/projects/big-meta": { - /** - * Store Big Meta - * @description Stores a bigMeta for a project - */ - post: operations["store_3"]; + "/v2/projects/keys/{id}": { + /** Get one key */ + get: operations["get_15"]; + /** Edit key name */ + put: operations["edit_1"]; }; - "/v2/projects/translations/{translationId}/comments": { - /** - * Get translation comments - * @description Returns translation comments of translation - */ - get: operations["getAll_6"]; - /** Create translation comment */ - post: operations["create_8"]; + "/v2/projects/keys/{id}/big-meta": { + /** Get Big Meta for key */ + get: operations["getBigMeta_1"]; }; - "/v2/projects/translations/create-comment": { + "/v2/projects/keys/{id}/complex-update": { /** - * Create translation comment - * @description Creates a translation comment. Empty translation is stored, when not exists. + * Edit key and related data + * @description Edits key name, translations, tags, screenshots, and other data */ - post: operations["create_10"]; + put: operations["complexEdit_1"]; }; - "/v2/projects/suggest/translation-memory": { + "/v2/projects/keys/{id}/disabled-languages": { /** - * Get suggestions from translation memory - * @description Suggests machine translations from translation memory. The result is always sorted by similarity, so sorting is not supported. + * Get disabled languages + * @description Returns languages, in which key is disabled */ - post: operations["suggestTranslationMemory_1"]; - }; - "/v2/projects/suggest/machine-translations-streaming": { + get: operations["getDisabledLanguages_1"]; /** - * Get machine translation suggestions (streaming) - * @description Suggests machine translations from enabled services. The results are streamed to the output in ndjson format. If an error occurs when for any service provider used, the error information is returned as a part of the result item, while the response has 200 status code. + * Set disabled languages + * @description Sets languages, in which key is disabled */ - post: operations["suggestMachineTranslationsStreaming_1"]; + put: operations["setDisabledLanguages_1"]; }; - "/v2/projects/suggest/machine-translations": { + "/v2/projects/keys/{keyId}/auto-translate": { /** - * Get machine translation suggestions - * @description Suggests machine translations from enabled services + * Auto translates keys + * @description Uses enabled auto-translation methods. + * You need to set at least one of useMachineTranslation or useTranslationMemory to true. + * + * This will replace the the existing translation with the result obtained from specified source! */ - post: operations["suggestMachineTranslations_1"]; - }; - "/v2/projects/languages": { - /** Get all languages */ - get: operations["getAll_8"]; - /** Create language */ - post: operations["createLanguage_1"]; + put: operations["autoTranslate_1"]; }; "/v2/projects/keys/{keyId}/screenshots": { /** Get screenshots */ @@ -425,83 +447,75 @@ export interface paths { /** Upload screenshot */ post: operations["uploadScreenshot"]; }; - "/v2/organizations": { + "/v2/projects/keys/{keyId}/screenshots/{ids}": { + /** Delete screenshots */ + delete: operations["deleteScreenshots"]; + }; + "/v2/projects/keys/{keyId}/tags": { /** - * Get all permitted organizations - * @description Returns all organizations, which is current user allowed to view + * Tag key + * @description Tags a key with tag. If tag with provided name doesn't exist, it is created */ - get: operations["getAll_10"]; - /** Create organization */ - post: operations["create_12"]; - }; - "/v2/image-upload": { - /** Upload an image for later use */ - post: operations["upload"]; - }; - "/v2/user-tasks": { - /** Get user tasks */ - get: operations["getTasks"]; + put: operations["tagKey_1"]; }; - "/v2/projects/used-namespaces": { + "/v2/projects/keys/{keyId}/tags/{tagId}": { /** - * Get used namespaces - * @description Returns all used project namespaces. Response contains default (null) namespace if used. + * Remove tag + * @description Removes tag with provided id from key with provided id */ - get: operations["getUsedNamespaces_1"]; + delete: operations["removeTag_1"]; }; - "/v2/projects/tasks/{taskNumber}/xlsx-report": { - /** - * Get report in XLSX - * @description Detailed statistics about the task results - */ - get: operations["getXlsxReport_1"]; + "/v2/projects/labels": { + /** Get available project labels */ + get: operations["getAll_4"]; + /** Create label */ + post: operations["createLabel_1"]; }; - "/v2/projects/tasks/{taskNumber}/per-user-report": { - /** - * Get report - * @description Detailed statistics for every assignee - */ - get: operations["getPerUserReport_1"]; + "/v2/projects/labels/ids": { + /** Get labels by ids */ + get: operations["getLabelsByIds_1"]; }; - "/v2/projects/tasks/{taskNumber}/blocking-tasks": { - /** - * Get blocking task numbers - * @description If the tasks is blocked by other tasks, it returns numbers of these tasks. - */ - get: operations["getBlockingTasks_1"]; + "/v2/projects/labels/{labelId}": { + /** Update label */ + put: operations["updateLabel_1"]; + /** Delete label */ + delete: operations["deleteLabel_1"]; }; - "/v2/projects/tasks/possible-assignees": { - get: operations["getPossibleAssignees_1"]; + "/v2/projects/language/{languageId}/key/{keyId}/suggestion": { + /** Get suggestions */ + get: operations["getSuggestions_1"]; + /** Create translation suggestion */ + post: operations["createSuggestion_1"]; }; - "/v2/projects/namespaces": { - /** Get namespaces */ - get: operations["getAllNamespaces_1"]; + "/v2/projects/language/{languageId}/key/{keyId}/suggestion/{suggestionId}": { + /** Delete suggestion */ + delete: operations["deleteSuggestion_1"]; }; - "/v2/projects/namespace-by-name/{name}": { - /** - * Get namespace by name - * @description Returns information about a namespace by its name - */ - get: operations["getByName_1"]; + "/v2/projects/language/{languageId}/key/{keyId}/suggestion/{suggestionId}/accept": { + /** Accept suggestion */ + put: operations["acceptSuggestion_1"]; }; - "/v2/projects/keys/search": { - /** - * Search for keys - * @description This endpoint helps you to find desired key by keyName, base translation or translation in specified language. - */ - get: operations["searchForKey_1"]; + "/v2/projects/language/{languageId}/key/{keyId}/suggestion/{suggestionId}/decline": { + /** Decline suggestion */ + put: operations["declineSuggestion_1"]; }; - "/v2/projects/activity/revisions/{revisionId}": { - /** Get one revision data */ - get: operations["getSingleRevision_1"]; + "/v2/projects/language/{languageId}/key/{keyId}/suggestion/{suggestionId}/reverse": { + /** Reverse suggestion */ + put: operations["reverseSuggestion_1"]; }; - "/v2/projects/activity": { - /** Get project activity */ - get: operations["getActivity_1"]; + "/v2/projects/languages": { + /** Get all languages */ + get: operations["getAll_8"]; + /** Create language */ + post: operations["createLanguage_1"]; }; - "/v2/projects/tags": { - /** Get tags */ - get: operations["getAll_4"]; + "/v2/projects/languages/{languageId}": { + /** Get one language */ + get: operations["get_13"]; + /** Update language */ + put: operations["editLanguage_1"]; + /** Delete specific language */ + delete: operations["deleteLanguage_3"]; }; "/v2/projects/my-batch-jobs": { /** @@ -510,151 +524,320 @@ export interface paths { */ get: operations["myList_1"]; }; - "/v2/projects/keys/{id}/big-meta": { - /** Get Big Meta for key */ - get: operations["getBigMeta_1"]; - }; - "/v2/projects/import/result/languages/{languageId}/translations": { - /** - * Get translations - * @description Returns translations prepared to import. - */ - get: operations["getImportTranslations_1"]; - }; - "/v2/projects/import/result/languages/{languageId}": { - /** - * Get import language - * @description Returns language prepared to import. - */ - get: operations["getImportLanguage_1"]; + "/v2/projects/namespace-by-name/{name}": { /** - * Delete language - * @description Deletes language prepared to import. + * Get namespace by name + * @description Returns information about a namespace by its name */ - delete: operations["deleteLanguage_1"]; + get: operations["getByName_1"]; }; - "/v2/projects/import/result/files/{importFileId}/issues": { - /** - * Get file issues - * @description Returns issues for uploaded file. - */ - get: operations["getImportFileIssues_1"]; + "/v2/projects/namespaces": { + /** Get namespaces */ + get: operations["getAllNamespaces_3"]; }; - "/v2/projects/import/result": { - /** - * Get result - * @description Returns the result of preparation. - */ - get: operations["getImportResult_1"]; + "/v2/projects/namespaces/{id}": { + /** Update namespace */ + put: operations["update_4"]; }; - "/v2/projects/import/all-namespaces": { + "/v2/projects/single-step-import": { /** - * Get namespaces - * @description Returns all existing and imported namespaces + * Single step import + * @description Unlike the /v2/projects/{projectId}/import endpoint, imports the data in single request by provided files and parameters. This is useful for automated importing via API or CLI. */ - get: operations["getAllNamespaces_3"]; + post: operations["singleStepFromFiles_1"]; }; - "/v2/projects/current-batch-jobs": { - /** - * Get all running and pending batch operations - * @description Returns all running and pending batch operations. Completed batch operations are returned only if they are not older than 1 hour. If user doesn't have permission to view all batch operations, only their operations are returned. - */ - get: operations["currentJobs_1"]; + "/v2/projects/single-step-import-resolvable": { + /** Single step import from body */ + post: operations["singleStepResolvableImport_1"]; }; - "/v2/projects/batch-jobs/{id}": { - /** Get batch operation */ - get: operations["get_13"]; + "/v2/projects/start-batch-job/ai-playground-translate": { + /** Translates via llm and stores result in AiPlaygroundResult */ + post: operations["aiPlaygroundTranslate_1"]; }; - "/v2/projects/batch-jobs": { - /** List batch operations */ - get: operations["list_4"]; + "/v2/projects/start-batch-job/assign-translation-label": { + /** Assign labels to translations */ + post: operations["assignTranslationLabel_1"]; }; - "/v2/projects/translations/{translationId}/history": { + "/v2/projects/start-batch-job/clear-translations": { /** - * Get translation history - * @description Sorting is not supported for supported. It is automatically sorted from newest to oldest. + * Clear translation values + * @description Clear translation values for provided keys in selected languages. */ - get: operations["getTranslationHistory_1"]; + post: operations["clearTranslations_1"]; }; - "/v2/projects/translations/{languages}": { + "/v2/projects/start-batch-job/copy-translations": { /** - * Get all translations - * @description Returns all translations for specified languages + * Copy translation values + * @description Copy translation values from one language to other languages. */ - get: operations["getAllTranslations_1"]; + post: operations["copyTranslations_1"]; }; - "/v2/projects/translations/select-all": { + "/v2/projects/start-batch-job/delete-keys": { + /** Delete keys */ + post: operations["deleteKeys_1"]; + }; + "/v2/projects/start-batch-job/machine-translate": { /** - * Select keys - * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. + * Machine Translation + * @description Translate provided keys to provided languages through primary MT provider. */ - get: operations["selectKeys_1"]; + post: operations["machineTranslation_1"]; }; - "/v2/projects/keys/select": { + "/v2/projects/start-batch-job/pre-translate-by-tm": { /** - * Select keys - * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. + * Pre-translate by TM + * @description Pre-translate provided keys to provided languages by TM. */ - get: operations["selectKeys_3"]; + post: operations["translate_1"]; }; - "/v2/projects/stats/daily-activity": { - /** Get project daily amount of events */ - get: operations["getProjectDailyActivity_1"]; + "/v2/projects/start-batch-job/set-keys-namespace": { + /** Set keys namespace */ + post: operations["setKeysNamespace_1"]; + }; + "/v2/projects/start-batch-job/set-translation-state": { + /** Set translation state */ + post: operations["setTranslationState_3"]; + }; + "/v2/projects/start-batch-job/tag-keys": { + /** Add tags */ + post: operations["tagKeys_1"]; + }; + "/v2/projects/start-batch-job/unassign-translation-label": { + /** Unassign labels from translations */ + post: operations["unassignTranslationLabel_1"]; + }; + "/v2/projects/start-batch-job/untag-keys": { + /** Remove tags */ + post: operations["untagKeys_1"]; }; "/v2/projects/stats": { /** Get project stats */ get: operations["getProjectStats_1"]; }; - "/v2/pats/current": { + "/v2/projects/stats/daily-activity": { + /** Get project daily amount of events */ + get: operations["getProjectDailyActivity_1"]; + }; + "/v2/projects/suggest/machine-translations": { /** - * Return current PAK - * @description Returns current Personal Access Token. If the request is not authenticated with a Personal Access Token, it will return 400 response status. + * Get machine translation suggestions + * @description Suggests machine translations from enabled services */ - get: operations["getCurrent"]; - }; - "/v2/organizations/{slug}": { - /** Get organization by slug */ - get: operations["get_19"]; + post: operations["suggestMachineTranslations_1"]; }; - "/v2/organizations/{organizationId}/machine-translation-credit-balance": { + "/v2/projects/suggest/machine-translations-streaming": { /** - * Get credit balance for organization - * @description Returns machine translation credit balance for organization + * Get machine translation suggestions (streaming) + * @description Suggests machine translations from enabled services. The results are streamed to the output in ndjson format. If an error occurs when for any service provider used, the error information is returned as a part of the result item, while the response has 200 status code. */ - get: operations["getOrganizationCredits"]; + post: operations["suggestMachineTranslationsStreaming_1"]; }; - "/v2/api-keys/current": { + "/v2/projects/suggest/translation-memory": { /** - * Get current API key info - * @description Returns info the API key which user currently authenticated with. Otherwise responds with 400 status code. + * Get suggestions from translation memory + * @description Suggests machine translations from translation memory. The result is always sorted by similarity, so sorting is not supported. */ - get: operations["getCurrent_1"]; + post: operations["suggestTranslationMemory_1"]; }; - "/v2/api-keys/current-permissions": { + "/v2/projects/tag-complex": { + /** Execute complex tag operation */ + put: operations["executeComplexTagOperation_1"]; + }; + "/v2/projects/tags": { + /** Get tags */ + get: operations["getAll_2"]; + }; + "/v2/projects/tasks": { + /** Get tasks */ + get: operations["getTasks_2"]; + /** Create task */ + post: operations["createTask_1"]; + }; + "/v2/projects/tasks/calculate-scope": { + /** Calculate scope */ + post: operations["calculateScope_1"]; + }; + "/v2/projects/tasks/create-multiple-tasks": { + /** Create multiple tasks */ + post: operations["createTasks_1"]; + }; + "/v2/projects/tasks/possible-assignees": { + get: operations["getPossibleAssignees_1"]; + }; + "/v2/projects/tasks/{taskNumber}": { + /** Get task */ + get: operations["getTask_1"]; + /** Update task */ + put: operations["updateTask_1"]; + }; + "/v2/projects/tasks/{taskNumber}/blocking-tasks": { /** - * Get current permission info - * @description Returns current PAK or PAT permissions for current user, api-key and project + * Get blocking task numbers + * @description If the tasks is blocked by other tasks, it returns numbers of these tasks. */ - get: operations["getCurrentPermissions"]; + get: operations["getBlockingTasks_1"]; }; - "/v2/projects/keys/{ids}": { - /** Delete one or multiple keys */ - delete: operations["delete_3"]; + "/v2/projects/tasks/{taskNumber}/cancel": { + /** Close task */ + put: operations["cancelTask_1"]; }; - "/v2/projects/keys/{keyId}/tags/{tagId}": { + "/v2/projects/tasks/{taskNumber}/close": { /** - * Remove tag - * @description Removes tag with provided id from key with provided id + * Close task + * @deprecated */ - delete: operations["removeTag_1"]; + put: operations["closeTask_1"]; }; - "/v2/projects/keys/{keyId}/screenshots/{ids}": { - /** Delete screenshots */ - delete: operations["deleteScreenshots"]; + "/v2/projects/tasks/{taskNumber}/finish": { + /** Finish task */ + put: operations["finishTask_1"]; }; - "/v2/image-upload/{ids}": { - /** Delete uploaded images */ - delete: operations["delete_12"]; + "/v2/projects/tasks/{taskNumber}/keys": { + /** Get task keys */ + get: operations["getTaskKeys_1"]; + /** Add or remove task keys */ + put: operations["updateTaskKeys_1"]; + }; + "/v2/projects/tasks/{taskNumber}/keys/{keyId}": { + /** + * Update task key + * @description Mark key as done, which updates task progress. + */ + put: operations["updateTaskKey_1"]; + }; + "/v2/projects/tasks/{taskNumber}/per-user-report": { + /** + * Get report + * @description Detailed statistics for every assignee + */ + get: operations["getPerUserReport_1"]; + }; + "/v2/projects/tasks/{taskNumber}/reopen": { + /** Reopen task */ + put: operations["reopenTask_1"]; + }; + "/v2/projects/tasks/{taskNumber}/xlsx-report": { + /** + * Get report in XLSX + * @description Detailed statistics about the task results + */ + get: operations["getXlsxReport_1"]; + }; + "/v2/projects/translations": { + /** Get translations in project */ + get: operations["getTranslations_1"]; + /** + * Update translations for existing key + * @description Sets translations for existing key + */ + put: operations["setTranslations_1"]; + /** + * Create key or update translations + * @description Sets translations for existing key or creates new key and sets the translations to it. + */ + post: operations["createOrUpdateTranslations_1"]; + }; + "/v2/projects/translations/create-comment": { + /** + * Create translation comment + * @description Creates a translation comment. Empty translation is stored, when not exists. + */ + post: operations["create_4"]; + }; + "/v2/projects/translations/label": { + /** Add label to translation by key and language id */ + put: operations["assignLabel_3"]; + }; + "/v2/projects/translations/select-all": { + /** + * Select keys + * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. + */ + get: operations["selectKeys_1"]; + }; + "/v2/projects/translations/{languages}": { + /** + * Get all translations + * @description Returns all translations for specified languages + */ + get: operations["getAllTranslations_1"]; + }; + "/v2/projects/translations/{translationId}/comments": { + /** + * Get translation comments + * @description Returns translation comments of translation + */ + get: operations["getAll_6"]; + /** Create translation comment */ + post: operations["create_2"]; + }; + "/v2/projects/translations/{translationId}/comments/{commentId}": { + /** Get one translation comment */ + get: operations["get_11"]; + /** Update translation comment */ + put: operations["update_2"]; + /** Delete translation comment */ + delete: operations["delete_3"]; + }; + "/v2/projects/translations/{translationId}/comments/{commentId}/set-state/{state}": { + /** Set state of translation comment */ + put: operations["setState_1"]; + }; + "/v2/projects/translations/{translationId}/dismiss-auto-translated-state": { + /** + * Dismiss auto-translated + * @description Removes "auto translated" indication + */ + put: operations["dismissAutoTranslatedState_1"]; + }; + "/v2/projects/translations/{translationId}/history": { + /** + * Get translation history + * @description Sorting is not supported for supported. It is automatically sorted from newest to oldest. + */ + get: operations["getTranslationHistory_1"]; + }; + "/v2/projects/translations/{translationId}/label/{labelId}": { + /** Add label to translation */ + put: operations["assignLabel_1"]; + /** Remove label from translation */ + delete: operations["unassignLabel_1"]; + }; + "/v2/projects/translations/{translationId}/set-outdated-flag/{state}": { + /** + * Set outdated value + * @description Set's "outdated" flag indicating the base translation was changed without updating current translation. + */ + put: operations["setOutdated_1"]; + }; + "/v2/projects/translations/{translationId}/set-state/{state}": { + /** Set translation state */ + put: operations["setTranslationState_1"]; + }; + "/v2/projects/used-namespaces": { + /** + * Get used namespaces + * @description Returns all used project namespaces. Response contains default (null) namespace if used. + */ + get: operations["getUsedNamespaces_1"]; + }; + "/v2/user": { + /** + * Get user info + * @description Returns information about currently authenticated user. + */ + get: operations["getInfo_2"]; + }; + "/v2/user-tasks": { + /** Get user tasks */ + get: operations["getTasks"]; + }; + "/v2/user/sso": { + /** + * Get information about SSO configuration + * @description Returns information about sso configuration affecting the user. + */ + get: operations["getSso"]; }; } @@ -662,70 +845,40 @@ export type webhooks = Record; export interface components { schemas: { - ErrorResponseTyped: { - /** @enum {string} */ - code: "unauthenticated" | "api_access_forbidden" | "api_key_not_found" | "invalid_api_key" | "invalid_project_api_key" | "project_api_key_expired" | "bad_credentials" | "mfa_enabled" | "invalid_otp_code" | "mfa_not_enabled" | "can_not_revoke_own_permissions" | "data_corrupted" | "invitation_code_does_not_exist_or_expired" | "language_tag_exists" | "language_name_exists" | "language_not_found" | "operation_not_permitted" | "registrations_not_allowed" | "project_not_found" | "resource_not_found" | "scope_not_found" | "key_exists" | "third_party_auth_error_message" | "third_party_auth_no_email" | "third_party_auth_no_sub" | "third_party_auth_unknown_error" | "email_already_verified" | "third_party_unauthorized" | "third_party_google_workspace_mismatch" | "username_already_exists" | "username_or_password_invalid" | "user_already_has_permissions" | "user_already_has_role" | "user_not_found" | "file_not_image" | "file_too_big" | "invalid_timestamp" | "email_not_verified" | "missing_callback_url" | "invalid_jwt_token" | "expired_jwt_token" | "general_jwt_error" | "cannot_find_suitable_address_part" | "address_part_not_unique" | "user_is_not_member_of_organization" | "organization_has_no_other_owner" | "user_has_no_project_access" | "user_is_organization_owner" | "cannot_set_your_own_permissions" | "user_is_organization_member" | "property_not_mutable" | "import_language_not_from_project" | "existing_language_not_selected" | "conflict_is_not_resolved" | "language_already_selected" | "cannot_parse_file" | "could_not_resolve_property" | "cannot_add_more_then_100_languages" | "no_languages_provided" | "language_with_base_language_tag_not_found" | "language_not_from_project" | "namespace_not_from_project" | "cannot_delete_base_language" | "key_not_from_project" | "max_screenshots_exceeded" | "translation_not_from_project" | "can_edit_only_own_comment" | "request_parse_error" | "filter_by_value_state_not_valid" | "import_has_expired" | "tag_not_from_project" | "translation_text_too_long" | "invalid_recaptcha_token" | "cannot_leave_owning_project" | "cannot_leave_project_with_organization_role" | "dont_have_direct_permissions" | "tag_too_log" | "too_many_uploaded_images" | "one_or_more_images_not_found" | "screenshot_not_of_key" | "service_not_found" | "too_many_requests" | "translation_not_found" | "out_of_credits" | "key_not_found" | "organization_not_found" | "cannot_find_base_language" | "base_language_not_found" | "no_exported_result" | "cannot_set_your_own_role" | "only_translate_review_or_view_permission_accepts_view_languages" | "oauth2_token_url_not_set" | "oauth2_user_url_not_set" | "email_already_invited_or_member" | "price_not_found" | "invoice_not_from_organization" | "invoice_not_found" | "plan_not_found" | "plan_not_available_any_more" | "no_auto_translation_method" | "cannot_translate_base_language" | "pat_not_found" | "invalid_pat" | "pat_expired" | "operation_unavailable_for_account_type" | "validation_email_is_not_valid" | "current_password_required" | "cannot_create_organization" | "wrong_current_password" | "wrong_param_type" | "expired_super_jwt_token" | "cannot_delete_your_own_account" | "cannot_sort_by_this_column" | "namespace_not_found" | "namespace_exists" | "invalid_authentication_method" | "unknown_sort_property" | "only_review_permission_accepts_state_change_languages" | "only_translate_or_review_permission_accepts_translate_languages" | "cannot_set_language_permissions_for_admin_scope" | "cannot_set_view_languages_without_translations_view_scope" | "cannot_set_translate_languages_without_translations_edit_scope" | "cannot_set_state_change_languages_without_translations_state_edit_scope" | "language_not_permitted" | "scopes_has_to_be_set" | "set_exactly_one_of_scopes_or_type" | "translation_exists" | "import_keys_error" | "provide_only_one_of_screenshots_and_screenshot_uploaded_image_ids" | "multiple_projects_not_supported" | "plan_translation_limit_exceeded" | "feature_not_enabled" | "license_key_not_found" | "cannot_set_view_languages_without_for_level_based_permissions" | "cannot_set_different_translate_and_state_change_languages_for_level_based_permissions" | "cannot_disable_your_own_account" | "subscription_not_found" | "invoice_does_not_have_usage" | "customer_not_found" | "subscription_not_active" | "organization_already_subscribed" | "organization_not_subscribed" | "license_key_used_by_another_instance" | "translation_spending_limit_exceeded" | "credit_spending_limit_exceeded" | "seats_spending_limit_exceeded" | "this_instance_is_already_licensed" | "big_meta_not_from_project" | "mt_service_not_enabled" | "project_not_selected" | "organization_not_selected" | "plan_has_subscribers" | "translation_failed" | "batch_job_not_found" | "key_exists_in_namespace" | "tag_is_blank" | "execution_failed_on_management_error" | "translation_api_rate_limit" | "cannot_finalize_activity" | "formality_not_supported_by_service" | "language_not_supported_by_service" | "rate_limited" | "pat_access_not_allowed" | "pak_access_not_allowed" | "cannot_modify_disabled_translation" | "azure_config_required" | "s3_config_required" | "content_storage_config_required" | "content_storage_test_failed" | "content_storage_config_invalid" | "invalid_connection_string" | "cannot_create_azure_storage_client" | "s3_access_key_required" | "azure_connection_string_required" | "s3_secret_key_required" | "cannot_store_file_to_content_storage" | "unexpected_error_while_publishing_to_content_storage" | "webhook_responded_with_non_200_status" | "unexpected_error_while_executing_webhook" | "content_storage_is_in_use" | "cannot_set_state_for_missing_translation" | "no_project_id_provided" | "license_key_not_provided" | "subscription_already_canceled" | "user_is_subscribed_to_paid_plan" | "cannot_create_free_plan_without_fixed_type" | "cannot_modify_plan_free_status" | "key_id_not_provided" | "free_self_hosted_seat_limit_exceeded" | "advanced_params_not_supported" | "plural_forms_not_found_for_language" | "nested_plurals_not_supported" | "message_is_not_plural" | "content_outside_plural_forms" | "invalid_plural_form" | "multiple_plurals_not_supported" | "custom_values_json_too_long" | "unsupported_po_message_format" | "plural_forms_data_loss" | "current_user_does_not_own_image" | "user_cannot_view_this_organization" | "user_is_not_owner_of_organization" | "pak_created_for_different_project" | "custom_slug_is_only_applicable_for_custom_storage" | "invalid_slug_format" | "batch_job_cancellation_timeout" | "import_failed" | "cannot_add_more_then_1000_languages" | "no_data_to_import" | "multiple_namespaces_mapped_to_single_file" | "multiple_mappings_for_same_file_language_name" | "multiple_mappings_for_null_file_language_name" | "too_many_mappings_for_file" | "missing_placeholder_in_template" | "tag_not_found" | "cannot_parse_encrypted_slack_login_data" | "slack_workspace_not_found" | "cannot_fetch_user_details_from_slack" | "slack_missing_scope" | "slack_not_connected_to_your_account" | "slack_invalid_command" | "slack_not_subscribed_yet" | "slack_connection_failed" | "tolgee_account_already_connected" | "slack_not_configured" | "slack_workspace_already_connected" | "slack_connection_error" | "email_verification_code_not_valid" | "cannot_subscribe_to_free_plan" | "plan_auto_assignment_only_for_free_plans" | "plan_auto_assignment_only_for_private_plans" | "plan_auto_assignment_organization_ids_not_in_for_organization_ids" | "task_not_found" | "task_not_finished" | "task_not_open"; - params?: Record[]; - }; - ErrorResponseBody: { - code: string; - params?: Record[]; - }; - Avatar: { - large: string; - thumbnail: string; - }; - PrivateUserAccountModel: { - /** Format: int64 */ - id: number; - username: string; - name?: string; - emailAwaitingVerification?: string; - mfaEnabled: boolean; - avatar?: components["schemas"]["Avatar"]; - /** @enum {string} */ - accountType: "LOCAL" | "MANAGED" | "THIRD_PARTY"; - /** @enum {string} */ - globalServerRole: "USER" | "ADMIN"; - deletable: boolean; - needsSuperJwtToken: boolean; + AcceptAuthProviderChangeRequest: { + id: string; }; - ComputedPermissionModel: { - permissionModel?: components["schemas"]["PermissionModel"]; - /** @enum {string} */ - origin: "ORGANIZATION_BASE" | "DIRECT" | "ORGANIZATION_OWNER" | "NONE" | "SERVER_ADMIN"; + ApiKeyPermissionsModel: { + project: components["schemas"]["SimpleProjectModel"]; /** - * @description The user's permission type. This field is null if uses granular permissions - * @enum {string} + * Format: int64 + * @description The API key's project id or the one provided as query param */ - type?: "NONE" | "VIEW" | "TRANSLATE" | "REVIEW" | "EDIT" | "MANAGE"; + projectId: number; /** - * @description List of languages user can view. If null, all languages view is permitted. + * @description Granted scopes to the user. When user has type permissions, this field contains permission scopes of the type. * @example [ - * 200001, - * 200004 + * "KEYS_EDIT", + * "TRANSLATIONS_VIEW" * ] */ - viewLanguageIds?: number[]; + scopes: ("translations.view" | "translations.edit" | "translations.suggest" | "keys.edit" | "screenshots.upload" | "screenshots.delete" | "screenshots.view" | "activity.view" | "languages.edit" | "admin" | "project.edit" | "members.view" | "members.edit" | "translation-comments.add" | "translation-comments.edit" | "translation-comments.set-state" | "translations.state-edit" | "keys.view" | "keys.delete" | "keys.create" | "batch-jobs.view" | "batch-jobs.cancel" | "translations.batch-by-tm" | "translations.batch-machine" | "content-delivery.manage" | "content-delivery.publish" | "webhooks.manage" | "tasks.view" | "tasks.edit" | "prompts.view" | "prompts.edit" | "translation-labels.manage" | "translation-labels.assign")[]; /** - * @description Granted scopes to the user. When user has type permissions, this field contains permission scopes of the type. + * @description List of languages user can change state to. If null, changing state of all language values is permitted. * @example [ - * "KEYS_EDIT", - * "TRANSLATIONS_VIEW" + * 200001, + * 200004 * ] */ - scopes: ("translations.view" | "translations.edit" | "keys.edit" | "screenshots.upload" | "screenshots.delete" | "screenshots.view" | "activity.view" | "languages.edit" | "admin" | "project.edit" | "members.view" | "members.edit" | "translation-comments.add" | "translation-comments.edit" | "translation-comments.set-state" | "translations.state-edit" | "keys.view" | "keys.delete" | "keys.create" | "batch-jobs.view" | "batch-jobs.cancel" | "translations.batch-by-tm" | "translations.batch-machine" | "content-delivery.manage" | "content-delivery.publish" | "webhooks.manage" | "tasks.view" | "tasks.edit")[]; + stateChangeLanguageIds?: number[]; /** - * @deprecated - * @description Deprecated (use translateLanguageIds). - * - * List of languages current user has TRANSLATE permission to. If null, all languages edition is permitted. + * @description List of languages user can suggest to. If null, suggesting to all languages is permitted. * @example [ * 200001, * 200004 * ] */ - permittedLanguageIds?: number[]; + suggestLanguageIds?: number[]; /** * @description List of languages user can translate to. If null, all languages editing is permitted. * @example [ @@ -735,71 +888,216 @@ export interface components { */ translateLanguageIds?: number[]; /** - * @description List of languages user can change state to. If null, changing state of all language values is permitted. + * @description The user's permission type. This field is null if user has assigned granular permissions or if returning API key's permissions + * @enum {string} + */ + type?: "NONE" | "VIEW" | "TRANSLATE" | "REVIEW" | "EDIT" | "MANAGE"; + /** + * @description List of languages user can view. If null, all languages view is permitted. * @example [ * 200001, * 200004 * ] */ - stateChangeLanguageIds?: number[]; + viewLanguageIds?: number[]; }; - LanguageModel: { + ApiKeyWithLanguagesModel: { + description: string; + /** Format: int64 */ + expiresAt?: number; /** Format: int64 */ id: number; + /** Format: int64 */ + lastUsedAt?: number; /** - * @description Language name in english - * @example Czech + * @deprecated + * @description Languages for which user has translate permission. */ - name: string; + permittedLanguageIds?: number[]; + /** Format: int64 */ + projectId: number; + projectName: string; + scopes: string[]; + userFullName?: string; + username?: string; + }; + AuthProviderDto: { + /** @enum {string} */ + authType?: "GOOGLE" | "GITHUB" | "OAUTH2" | "SSO" | "SSO_GLOBAL"; + id?: string; + ssoDomain?: string; + }; + /** @example Links to avatar images */ + Avatar: { + large: string; + thumbnail: string; + }; + BatchJobModel: { /** - * @description Language tag according to BCP 47 definition - * @example cs-CZ + * Format: int64 + * @description The activity revision id, that stores the activity details of the job */ - tag: string; + activityRevisionId?: number; + author?: components["schemas"]["SimpleUserAccountModel"]; /** - * @description Language name in this language - * @example čeština + * Format: int64 + * @description The time when the job created */ - originalName?: string; + createdAt: number; + /** @description If the job failed, this is the error message */ + errorMessage?: string; /** - * @description Language flag emoji as UTF-8 emoji - * @example 🇨🇿 + * Format: int64 + * @description Batch job id */ - flagEmoji?: string; + id: number; /** - * @description Whether is base language of project - * @example false + * Format: int32 + * @description Total items, that have been processed so far */ - base: boolean; - }; - NamespaceModel: { + progress: number; /** - * Format: int64 - * @description The id of namespace - * @example 10000048 + * @description Status of the batch job + * @enum {string} */ - id: number; - /** @example homepage */ - name: string; - }; - /** - * @description Current user's direct permission - * @example MANAGE - */ - PermissionModel: { + status: "PENDING" | "RUNNING" | "SUCCESS" | "FAILED" | "CANCELLED" | "DEBOUNCED"; /** - * @description Granted scopes to the user. When user has type permissions, this field contains permission scopes of the type. - * @example [ - * "KEYS_EDIT", - * "TRANSLATIONS_VIEW" - * ] + * Format: int32 + * @description Total items */ - scopes: ("translations.view" | "translations.edit" | "keys.edit" | "screenshots.upload" | "screenshots.delete" | "screenshots.view" | "activity.view" | "languages.edit" | "admin" | "project.edit" | "members.view" | "members.edit" | "translation-comments.add" | "translation-comments.edit" | "translation-comments.set-state" | "translations.state-edit" | "keys.view" | "keys.delete" | "keys.create" | "batch-jobs.view" | "batch-jobs.cancel" | "translations.batch-by-tm" | "translations.batch-machine" | "content-delivery.manage" | "content-delivery.publish" | "webhooks.manage" | "tasks.view" | "tasks.edit")[]; + totalItems: number; /** - * @description The user's permission type. This field is null if uses granular permissions + * @description Type of the batch job * @enum {string} */ - type?: "NONE" | "VIEW" | "TRANSLATE" | "REVIEW" | "EDIT" | "MANAGE"; + type: "AI_PLAYGROUND_TRANSLATE" | "PRE_TRANSLATE_BT_TM" | "MACHINE_TRANSLATE" | "AUTO_TRANSLATE" | "DELETE_KEYS" | "SET_TRANSLATIONS_STATE" | "CLEAR_TRANSLATIONS" | "COPY_TRANSLATIONS" | "TAG_KEYS" | "UNTAG_KEYS" | "SET_KEYS_NAMESPACE" | "AUTOMATION" | "BILLING_TRIAL_EXPIRATION_NOTICE" | "ASSIGN_TRANSLATION_LABEL" | "UNASSIGN_TRANSLATION_LABEL"; + /** + * Format: int64 + * @description The time when the job was last updated (status change) + */ + updatedAt: number; + }; + BigMetaDto: { + /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ + relatedKeysInOrder?: components["schemas"]["RelatedKeyDto"][]; + }; + CalculateScopeRequest: { + keys: number[]; + /** Format: int64 */ + languageId: number; + /** @enum {string} */ + type: "TRANSLATE" | "REVIEW"; + }; + ClearTranslationsRequest: { + keyIds: number[]; + languageIds: number[]; + }; + CollectionModelBatchJobModel: { + _embedded?: { + batchJobs?: components["schemas"]["BatchJobModel"][]; + }; + }; + CollectionModelGlossaryLanguageDto: { + _embedded?: { + glossaryLanguageDtoList?: components["schemas"]["GlossaryLanguageDto"][]; + }; + }; + CollectionModelImportNamespaceModel: { + _embedded?: { + namespaces?: components["schemas"]["ImportNamespaceModel"][]; + }; + }; + CollectionModelKeyWithBaseTranslationModel: { + _embedded?: { + keys?: components["schemas"]["KeyWithBaseTranslationModel"][]; + }; + }; + CollectionModelKeyWithDataModel: { + _embedded?: { + keys?: components["schemas"]["KeyWithDataModel"][]; + }; + }; + CollectionModelLanguageModel: { + _embedded?: { + languages?: components["schemas"]["LanguageModel"][]; + }; + }; + CollectionModelLong: { + _embedded?: { + longList?: number[]; + }; + }; + CollectionModelScreenshotModel: { + _embedded?: { + screenshots?: components["schemas"]["ScreenshotModel"][]; + }; + }; + CollectionModelSimpleProjectModel: { + _embedded?: { + projects?: components["schemas"]["SimpleProjectModel"][]; + }; + }; + CollectionModelUsedNamespaceModel: { + _embedded?: { + namespaces?: components["schemas"]["UsedNamespaceModel"][]; + }; + }; + ComplexEditKeyDto: { + /** @description Custom values of the key. If not provided, custom values won't be modified */ + custom?: { + [key: string]: Record; + }; + /** @description Description of the key. It's also used as a context for Tolgee AI translator */ + description?: string; + /** @description If key is pluralized. If it will be reflected in the editor. If null, value won't be modified. */ + isPlural?: boolean; + /** @description Name of the key */ + name: string; + namespace?: string; + /** @description The argument name for the plural. If null, value won't be modified. If isPlural is false, this value will be ignored. */ + pluralArgName?: string; + /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ + relatedKeysInOrder?: components["schemas"]["RelatedKeyDto"][]; + /** @description IDs of screenshots to delete */ + screenshotIdsToDelete?: number[]; + /** @description Ids of screenshots uploaded with /v2/image-upload endpoint */ + screenshotUploadedImageIds?: number[]; + screenshotsToAdd?: components["schemas"]["KeyScreenshotDto"][]; + /** @description Translation states to update, if not provided states won't be modified */ + states?: { + [key: string]: "TRANSLATED" | "REVIEWED"; + }; + /** @description Tags of the key. If not provided tags won't be modified */ + tags?: string[]; + /** @description Translations to update */ + translations?: { + [key: string]: string; + }; + /** @description If true, it will fail with 400 (with code plural_forms_data_loss) if plural is disabled and there are plural forms, which would be lost by the action. You can get rid of this warning by setting this value to false. */ + warnOnDataLoss?: boolean; + }; + ComplexTagKeysRequest: { + /** @description Include keys filtered by the provided key information */ + filterKeys?: components["schemas"]["KeyId"][]; + /** @description Exclude keys filtered by the provided key information */ + filterKeysNot?: components["schemas"]["KeyId"][]; + /** @description Include keys filtered by the provided tag information. This filter supports wildcards. For example, `draft-*` will match all tags starting with `draft-`. */ + filterTag?: string[]; + /** @description Exclude keys filtered by the provided tag information. This filter supports wildcards. For example, `draft-*` will match all tags starting with `draft-`. */ + filterTagNot?: string[]; + /** @description Specified tags will be added to filtered keys */ + tagFiltered?: string[]; + /** @description Specified tags will be added to keys not filtered by any of the specified filters. */ + tagOther?: string[]; + /** @description Specified tags will be removed from filtered keys. It supports wildcards. For example, `draft-*` will remove all tags starting with `draft-`. */ + untagFiltered?: string[]; + /** @description Specified tags will be removed from keys not filtered by any of the specified filters. It supports wildcards. For example, `draft-*` will remove all tags starting with `draft-`. */ + untagOther?: string[]; + }; + ComputedPermissionModel: { + /** @enum {string} */ + origin: "ORGANIZATION_BASE" | "DIRECT" | "ORGANIZATION_OWNER" | "NONE" | "SERVER_ADMIN"; + permissionModel?: components["schemas"]["PermissionModel"]; /** * @deprecated * @description Deprecated (use translateLanguageIds). @@ -812,442 +1110,419 @@ export interface components { */ permittedLanguageIds?: number[]; /** - * @description List of languages user can translate to. If null, all languages editing is permitted. + * @description Granted scopes to the user. When user has type permissions, this field contains permission scopes of the type. + * @example [ + * "KEYS_EDIT", + * "TRANSLATIONS_VIEW" + * ] + */ + scopes: ("translations.view" | "translations.edit" | "translations.suggest" | "keys.edit" | "screenshots.upload" | "screenshots.delete" | "screenshots.view" | "activity.view" | "languages.edit" | "admin" | "project.edit" | "members.view" | "members.edit" | "translation-comments.add" | "translation-comments.edit" | "translation-comments.set-state" | "translations.state-edit" | "keys.view" | "keys.delete" | "keys.create" | "batch-jobs.view" | "batch-jobs.cancel" | "translations.batch-by-tm" | "translations.batch-machine" | "content-delivery.manage" | "content-delivery.publish" | "webhooks.manage" | "tasks.view" | "tasks.edit" | "prompts.view" | "prompts.edit" | "translation-labels.manage" | "translation-labels.assign")[]; + /** + * @description List of languages user can change state to. If null, changing state of all language values is permitted. * @example [ * 200001, * 200004 * ] */ - translateLanguageIds?: number[]; + stateChangeLanguageIds?: number[]; /** - * @description List of languages user can view. If null, all languages view is permitted. + * @description List of languages user can suggest to. If null, suggesting to all languages is permitted. * @example [ * 200001, * 200004 * ] */ - viewLanguageIds?: number[]; + suggestLanguageIds?: number[]; /** - * @description List of languages user can change state to. If null, changing state of all language values is permitted. + * @description List of languages user can translate to. If null, all languages editing is permitted. * @example [ * 200001, * 200004 * ] */ - stateChangeLanguageIds?: number[]; + translateLanguageIds?: number[]; + /** + * @description The user's permission type. This field is null if uses granular permissions + * @enum {string} + */ + type?: "NONE" | "VIEW" | "TRANSLATE" | "REVIEW" | "EDIT" | "MANAGE"; + /** + * @description List of languages user can view. If null, all languages view is permitted. + * @example [ + * 200001, + * 200004 + * ] + */ + viewLanguageIds?: number[]; }; - ProjectModel: { + CopyTranslationRequest: { + keyIds: number[]; /** Format: int64 */ - id: number; - name: string; - description?: string; - slug?: string; - avatar?: components["schemas"]["Avatar"]; - organizationOwner?: components["schemas"]["SimpleOrganizationModel"]; - baseLanguage?: components["schemas"]["LanguageModel"]; - defaultNamespace?: components["schemas"]["NamespaceModel"]; - /** @enum {string} */ - organizationRole?: "MEMBER" | "OWNER"; - directPermission?: components["schemas"]["PermissionModel"]; - computedPermission: components["schemas"]["ComputedPermissionModel"]; - /** @description Whether to disable ICU placeholder visualization in the editor and it's support. */ - icuPlaceholders: boolean; + sourceLanguageId: number; + targetLanguageIds: number[]; }; - SimpleOrganizationModel: { - /** Format: int64 */ - id: number; - /** @example Beautiful organization */ + CreateGlossaryRequest: { + /** @description IDs of projects to be assigned to glossary */ + assignedProjectIds: number[]; + /** + * @description Language tag according to BCP 47 definition + * @example cs-CZ + */ + baseLanguageTag: string; + /** + * @description Glossary name + * @example My glossary + */ name: string; - /** @example btforg */ - slug: string; - /** @example This is a beautiful organization full of beautiful and clever people */ - description?: string; - basePermissions: components["schemas"]["PermissionModel"]; - avatar?: components["schemas"]["Avatar"]; - }; - SimpleUserAccountModel: { - /** Format: int64 */ - id: number; - username: string; - name?: string; - avatar?: components["schemas"]["Avatar"]; - deleted: boolean; }; - TaskModel: { - /** Format: int64 */ - number: number; - name: string; + CreateGlossaryTermWithTranslationRequest: { + /** + * @description A detailed explanation or definition of the glossary term + * @example It's trademark + */ description: string; - /** @enum {string} */ - type: "TRANSLATE" | "REVIEW"; - language: components["schemas"]["LanguageModel"]; - /** Format: int64 */ - dueDate?: number; - assignees: components["schemas"]["SimpleUserAccountModel"][]; - /** Format: int64 */ - totalItems: number; - /** Format: int64 */ - doneItems: number; - /** Format: int64 */ - baseWordCount: number; - /** Format: int64 */ - baseCharacterCount: number; - author?: components["schemas"]["SimpleUserAccountModel"]; - /** Format: int64 */ - createdAt?: number; - /** Format: int64 */ - closedAt?: number; - /** @enum {string} */ - state: "NEW" | "IN_PROGRESS" | "DONE" | "CLOSED"; - }; - UpdateTaskKeyRequest: { - done: boolean; + /** @description Specifies whether the term represents a shortened form of a word or phrase */ + flagAbbreviation: boolean; + /** @description When true, the term matching considers uppercase and lowercase characters as distinct */ + flagCaseSensitive: boolean; + /** @description When true, marks this term as prohibited or not recommended for use in translations */ + flagForbiddenTerm: boolean; + /** @description When true, this term will have the same translation across all target languages */ + flagNonTranslatable: boolean; + text: string; }; - UpdateTaskKeyResponse: { - /** @description Task key is marked as done */ - done: boolean; - /** @description Task progress is 100% */ - taskFinished: boolean; - }; - UpdateTaskKeysRequest: { - /** @description Keys to add to task */ - addKeys?: number[]; - /** @description Keys to remove from task */ - removeKeys?: number[]; - }; - UpdateTaskRequest: { - name: string; - description: string; + CreateKeyDto: { /** - * Format: int64 - * @description Due to date in epoch format (milliseconds). - * @example 1661172869000 + * @description Description of the key + * @example This key is used on homepage. It's a label of sign up button. */ - dueDate?: number; - assignees: number[]; - }; - UpdateNamespaceDto: { - name: string; - }; - SetDisabledLanguagesRequest: { - languageIds: number[]; - }; - CollectionModelLanguageModel: { - _embedded?: { - languages?: components["schemas"]["LanguageModel"][]; - }; - }; - ComplexEditKeyDto: { + description?: string; + /** @description If key is pluralized. If it will be reflected in the editor */ + isPlural: boolean; /** @description Name of the key */ name: string; namespace?: string; - /** @description Translations to update */ - translations?: { - [key: string]: string; - }; + /** @description The argument name for the plural. If null, value will be guessed from the values provided in translations. */ + pluralArgName?: string; + /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ + relatedKeysInOrder?: components["schemas"]["RelatedKeyDto"][]; + /** @description Ids of screenshots uploaded with /v2/image-upload endpoint */ + screenshotUploadedImageIds?: number[]; + screenshots?: components["schemas"]["KeyScreenshotDto"][]; /** @description Translation states to update, if not provided states won't be modified */ states?: { [key: string]: "TRANSLATED" | "REVIEWED"; }; - /** @description Tags of the key. If not provided tags won't be modified */ tags?: string[]; - /** @description IDs of screenshots to delete */ - screenshotIdsToDelete?: number[]; - /** @description Ids of screenshots uploaded with /v2/image-upload endpoint */ - screenshotUploadedImageIds?: number[]; - screenshotsToAdd?: components["schemas"]["KeyScreenshotDto"][]; - /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ - relatedKeysInOrder?: components["schemas"]["RelatedKeyDto"][]; - /** @description Description of the key. It's also used as a context for Tolgee AI translator */ - description?: string; - /** @description If key is pluralized. If it will be reflected in the editor. If null, value won't be modified. */ - isPlural?: boolean; - /** @description The argument name for the plural. If null, value won't be modified. If isPlural is false, this value will be ignored. */ - pluralArgName?: string; - /** @description If true, it will fail with 400 (with code plural_forms_data_loss) if plural is disabled and there are plural forms, which would be lost by the action. You can get rid of this warning by setting this value to false. */ - warnOnDataLoss?: boolean; - /** @description Custom values of the key. If not provided, custom values won't be modified */ - custom?: { - [key: string]: Record; + translations?: { + [key: string]: string; }; }; - KeyInScreenshotPositionDto: { - /** Format: int32 */ - x: number; - /** Format: int32 */ - y: number; - /** Format: int32 */ - width: number; - /** Format: int32 */ - height: number; + CreateMultipleTasksRequest: { + tasks: components["schemas"]["CreateTaskRequest"][]; }; - KeyScreenshotDto: { - text?: string; + CreateProjectRequest: { + /** @description Tag of one of created languages, to select it as base language. If not provided, first language will be selected as base. */ + baseLanguageTag?: string; + /** @description Whether to use ICU placeholder visualization in the editor and it's support. */ + icuPlaceholders: boolean; + languages: components["schemas"]["LanguageRequest"][]; + name: string; /** * Format: int64 - * @description Ids of screenshot uploaded with /v2/image-upload endpoint + * @description Organization to create the project in */ - uploadedImageId: number; - positions?: components["schemas"]["KeyInScreenshotPositionDto"][]; - }; - /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ - RelatedKeyDto: { - namespace?: string; - keyName: string; - }; - KeyInScreenshotModel: { - /** Format: int64 */ - keyId: number; - position?: components["schemas"]["KeyInScreenshotPosition"]; - keyName: string; - keyNamespace?: string; - originalText?: string; - }; - KeyInScreenshotPosition: { - /** Format: int32 */ - x: number; - /** Format: int32 */ - y: number; - /** Format: int32 */ - width: number; - /** Format: int32 */ - height: number; + organizationId: number; + /** @description Slug of your project used in url e.g. "/v2/projects/what-a-project". If not provided, it will be generated */ + slug?: string; }; - KeyWithDataModel: { + CreateTaskRequest: { + assignees: number[]; + description: string; /** * Format: int64 - * @description Id of key record - */ - id: number; - /** - * @description Name of key - * @example this_is_super_key - */ - name: string; - /** - * @description Namespace of key - * @example homepage - */ - namespace?: string; - /** - * @description Description of key - * @example This key is used on homepage. It's a label of sign up button. + * @description Due to date in epoch format (milliseconds). + * @example 1661172869000 */ - description?: string; + dueDate?: number; + keys: number[]; /** - * @description Translations object containing values updated in this request - * @example { - * "en": { - * "id": 100000003, - * "text": "This is super translation!" - * } - * } + * Format: int64 + * @description Id of language, this task is attached to. + * @example 1 */ - translations: { - [key: string]: components["schemas"]["TranslationModel"]; - }; - /** @description Tags of key */ - tags: components["schemas"]["TagModel"][]; - /** @description Screenshots of the key */ - screenshots: components["schemas"]["ScreenshotModel"][]; - /** @description If key is pluralized. If it will be reflected in the editor */ - isPlural: boolean; - /** @description The argument name for the plural */ - pluralArgName?: string; - /** @description Custom values of the key */ - custom: { - [key: string]: Record; - }; + languageId: number; + name?: string; + /** @enum {string} */ + type: "TRANSLATE" | "REVIEW"; }; - /** @description Screenshots of the key */ - ScreenshotModel: { + CreateTranslationSuggestionRequest: { + translation: string; + }; + CreateUpdateGlossaryTermResponse: { + term: components["schemas"]["SimpleGlossaryTermModel"]; + translation?: components["schemas"]["GlossaryTermTranslationModel"]; + }; + CreditBalanceModel: { /** Format: int64 */ - id: number; - /** - * @description File name, which may be downloaded from the screenshot path. - * - * When images are secured. Encrypted timestamp is appended to the filename. - */ - filename: string; + bucketSize: number; + /** Format: int64 */ + creditBalance: number; /** - * @description Thumbnail file name, which may be downloaded from the screenshot path. + * Format: int64 + * @deprecated + * @description Customers were able to buy extra credits separately in the past. * - * When images are secured. Encrypted timestamp is appended to the filename. + * This option is not available anymore and this field is kept only for backward compatibility purposes and is always 0. */ - thumbnail: string; - fileUrl: string; - thumbnailUrl: string; - /** Format: date-time */ - createdAt?: string; - keyReferences: components["schemas"]["KeyInScreenshotModel"][]; - location?: string; - /** Format: int32 */ - width?: number; - /** Format: int32 */ - height?: number; + extraCreditBalance: number; }; - /** @description Tags of key */ - TagModel: { - /** Format: int64 */ - id: number; - name: string; + DeleteKeysDto: { + /** @description IDs of keys to delete */ + ids: number[]; }; - /** - * @description Translations object containing values updated in this request - * @example { - * "en": { - * "id": 100000003, - * "text": "This is super translation!" - * } - * } - */ - TranslationModel: { - /** - * Format: int64 - * @description Id of translation record - */ - id: number; - /** @description Translation text */ - text?: string; - /** - * @description State of translation - * @enum {string} - */ - state: "UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED"; - /** @description Whether base language translation was changed after this translation was updated */ - outdated: boolean; - /** @description Was translated using Translation Memory or Machine translation service? */ - auto: boolean; - /** - * @description Which machine translation service was used to auto translate this - * @enum {string} - */ - mtProvider?: "GOOGLE" | "AWS" | "DEEPL" | "AZURE" | "BAIDU" | "TOLGEE"; + DeleteKeysRequest: { + keyIds: number[]; + }; + DeleteMultipleGlossaryTermsRequest: { + termIds: number[]; }; EditKeyDto: { - name: string; - namespace?: string; /** * @description Description of the key * @example This key is used on homepage. It's a label of sign up button. */ description?: string; - }; - KeyModel: { - /** - * Format: int64 - * @description Id of key record - */ - id: number; - /** - * @description Name of key - * @example this_is_super_key - */ name: string; - /** - * @description Namespace of key - * @example homepage - */ namespace?: string; - /** - * @description Description of key - * @example This key is used on homepage. It's a label of sign up button. - */ - description?: string; - /** @description Custom values of the key */ - custom?: { + }; + EntityDescriptionWithRelations: { + data: { [key: string]: Record; }; + entityClass: string; + /** Format: int64 */ + entityId: number; }; - ComplexTagKeysRequest: { - /** @description Include keys filtered by the provided key information */ - filterKeys?: components["schemas"]["KeyId"][]; - /** @description Exclude keys filtered by the provided key information */ - filterKeysNot?: components["schemas"]["KeyId"][]; - /** @description Include keys filtered by the provided tag information. This filter supports wildcards. For example, `draft-*` will match all tags starting with `draft-`. */ - filterTag?: string[]; - /** @description Exclude keys filtered by the provided tag information. This filter supports wildcards. For example, `draft-*` will match all tags starting with `draft-`. */ - filterTagNot?: string[]; - /** @description Specified tags will be added to filtered keys */ - tagFiltered?: string[]; - /** @description Specified tags will be removed from filtered keys. It supports wildcards. For example, `draft-*` will remove all tags starting with `draft-`. */ - untagFiltered?: string[]; - /** @description Specified tags will be added to keys not filtered by any of the specified filters. */ - tagOther?: string[]; - /** @description Specified tags will be removed from keys not filtered by any of the specified filters. It supports wildcards. For example, `draft-*` will remove all tags starting with `draft-`. */ - untagOther?: string[]; + ErrorResponseBody: { + code: string; + params?: Record[]; }; - /** @description Exclude keys filtered by the provided key information */ - KeyId: { - name?: string; - namespace?: string; - /** - * Format: int64 - * @description If key id is provided, name and namespace are ignored. - */ - id?: number; + ErrorResponseTyped: { + /** @enum {string} */ + code: "unauthenticated" | "api_access_forbidden" | "api_key_not_found" | "invalid_api_key" | "invalid_project_api_key" | "project_api_key_expired" | "bad_credentials" | "mfa_enabled" | "invalid_otp_code" | "mfa_not_enabled" | "can_not_revoke_own_permissions" | "data_corrupted" | "invitation_code_does_not_exist_or_expired" | "language_tag_exists" | "language_name_exists" | "language_not_found" | "operation_not_permitted" | "registrations_not_allowed" | "project_not_found" | "resource_not_found" | "scope_not_found" | "key_exists" | "third_party_auth_error_message" | "third_party_auth_no_email" | "third_party_auth_non_matching_email" | "third_party_auth_no_sub" | "third_party_auth_unknown_error" | "email_already_verified" | "third_party_unauthorized" | "third_party_google_workspace_mismatch" | "third_party_switch_initiated" | "third_party_switch_conflict" | "username_already_exists" | "username_or_password_invalid" | "user_already_has_permissions" | "user_already_has_role" | "user_not_found" | "file_not_image" | "file_too_big" | "invalid_timestamp" | "email_not_verified" | "missing_callback_url" | "invalid_jwt_token" | "expired_jwt_token" | "general_jwt_error" | "cannot_find_suitable_address_part" | "slug_not_unique" | "user_is_not_member_of_organization" | "organization_has_no_other_owner" | "user_has_no_project_access" | "user_is_organization_owner" | "cannot_set_your_own_permissions" | "user_is_organization_member" | "property_not_mutable" | "import_language_not_from_project" | "existing_language_not_selected" | "conflict_is_not_resolved" | "language_already_selected" | "cannot_parse_file" | "could_not_resolve_property" | "cannot_add_more_then_100_languages" | "no_languages_provided" | "language_with_base_language_tag_not_found" | "language_not_from_project" | "namespace_not_from_project" | "cannot_delete_base_language" | "key_not_from_project" | "max_screenshots_exceeded" | "translation_not_from_project" | "can_edit_only_own_comment" | "request_parse_error" | "filter_by_value_state_not_valid" | "import_has_expired" | "tag_not_from_project" | "translation_text_too_long" | "invalid_recaptcha_token" | "cannot_leave_owning_project" | "cannot_leave_project_with_organization_role" | "dont_have_direct_permissions" | "tag_too_log" | "too_many_uploaded_images" | "one_or_more_images_not_found" | "screenshot_not_of_key" | "service_not_found" | "too_many_requests" | "translation_not_found" | "out_of_credits" | "key_not_found" | "organization_not_found" | "cannot_find_base_language" | "base_language_not_found" | "no_exported_result" | "cannot_set_your_own_role" | "only_translate_review_or_view_permission_accepts_view_languages" | "oauth2_token_url_not_set" | "oauth2_user_url_not_set" | "email_already_invited_or_member" | "price_not_found" | "invoice_not_from_organization" | "invoice_not_found" | "plan_not_found" | "plan_not_available_any_more" | "no_auto_translation_method" | "cannot_translate_base_language" | "pat_not_found" | "invalid_pat" | "pat_expired" | "operation_unavailable_for_account_type" | "validation_email_is_not_valid" | "current_password_required" | "cannot_create_organization" | "wrong_current_password" | "wrong_param_type" | "user_missing_password" | "expired_super_jwt_token" | "cannot_delete_your_own_account" | "cannot_sort_by_this_column" | "namespace_not_found" | "namespace_exists" | "invalid_authentication_method" | "unknown_sort_property" | "only_review_permission_accepts_state_change_languages" | "only_translate_or_review_permission_accepts_translate_languages" | "cannot_set_language_permissions_for_admin_scope" | "cannot_set_view_languages_without_translations_view_scope" | "cannot_set_translate_languages_without_translations_edit_scope" | "cannot_set_state_change_languages_without_translations_state_edit_scope" | "language_not_permitted" | "scopes_has_to_be_set" | "set_exactly_one_of_scopes_or_type" | "translation_exists" | "import_keys_error" | "provide_only_one_of_screenshots_and_screenshot_uploaded_image_ids" | "multiple_projects_not_supported" | "plan_translation_limit_exceeded" | "feature_not_enabled" | "license_key_not_found" | "cannot_set_view_languages_without_for_level_based_permissions" | "cannot_set_different_translate_and_state_change_languages_for_level_based_permissions" | "cannot_disable_your_own_account" | "subscription_not_found" | "invoice_does_not_have_usage" | "customer_not_found" | "subscription_not_active" | "organization_already_subscribed" | "organization_not_subscribed" | "license_key_used_by_another_instance" | "translation_spending_limit_exceeded" | "credit_spending_limit_exceeded" | "seats_spending_limit_exceeded" | "this_instance_is_already_licensed" | "big_meta_not_from_project" | "mt_service_not_enabled" | "project_not_selected" | "organization_not_selected" | "plan_has_subscribers" | "translation_failed" | "batch_job_not_found" | "key_exists_in_namespace" | "tag_is_blank" | "execution_failed_on_management_error" | "translation_api_rate_limit" | "cannot_finalize_activity" | "formality_not_supported_by_service" | "language_not_supported_by_service" | "rate_limited" | "pat_access_not_allowed" | "pak_access_not_allowed" | "cannot_modify_disabled_translation" | "azure_config_required" | "s3_config_required" | "content_storage_config_required" | "content_storage_test_failed" | "content_storage_config_invalid" | "invalid_connection_string" | "cannot_create_azure_storage_client" | "s3_access_key_required" | "azure_connection_string_required" | "s3_secret_key_required" | "cannot_store_file_to_content_storage" | "unexpected_error_while_publishing_to_content_storage" | "webhook_responded_with_non_200_status" | "unexpected_error_while_executing_webhook" | "content_storage_is_in_use" | "cannot_set_state_for_missing_translation" | "no_project_id_provided" | "license_key_not_provided" | "subscription_already_canceled" | "user_is_subscribed_to_paid_plan" | "cannot_create_free_plan_without_fixed_type" | "cannot_modify_plan_free_status" | "key_id_not_provided" | "free_self_hosted_seat_limit_exceeded" | "advanced_params_not_supported" | "plural_forms_not_found_for_language" | "nested_plurals_not_supported" | "message_is_not_plural" | "content_outside_plural_forms" | "invalid_plural_form" | "multiple_plurals_not_supported" | "custom_values_json_too_long" | "unsupported_po_message_format" | "plural_forms_data_loss" | "current_user_does_not_own_image" | "user_cannot_view_this_organization" | "user_is_not_owner_of_organization" | "user_is_not_owner_or_maintainer_of_organization" | "pak_created_for_different_project" | "custom_slug_is_only_applicable_for_custom_storage" | "invalid_slug_format" | "batch_job_cancellation_timeout" | "import_failed" | "cannot_add_more_then_1000_languages" | "no_data_to_import" | "multiple_namespaces_mapped_to_single_file" | "multiple_mappings_for_same_file_language_name" | "multiple_mappings_for_null_file_language_name" | "too_many_mappings_for_file" | "missing_placeholder_in_template" | "tag_not_found" | "cannot_parse_encrypted_slack_login_data" | "slack_workspace_not_found" | "cannot_fetch_user_details_from_slack" | "slack_missing_scope" | "slack_not_connected_to_your_account" | "slack_invalid_command" | "slack_not_subscribed_yet" | "slack_connection_failed" | "tolgee_account_already_connected" | "slack_not_configured" | "slack_workspace_already_connected" | "slack_connection_error" | "email_verification_code_not_valid" | "cannot_subscribe_to_free_plan" | "plan_auto_assignment_only_for_free_plans" | "plan_auto_assignment_only_for_private_plans" | "task_not_found" | "task_not_finished" | "task_not_open" | "translation_agency_not_found" | "this_feature_is_not_implemented_in_oss" | "sso_token_exchange_failed" | "sso_user_info_retrieval_failed" | "sso_id_token_expired" | "sso_user_cannot_create_organization" | "sso_cant_verify_user" | "sso_auth_missing_domain" | "sso_domain_not_found_or_disabled" | "authentication_method_disabled" | "native_authentication_disabled" | "invitation_organization_mismatch" | "user_is_managed_by_organization" | "cannot_set_sso_provider_missing_fields" | "namespaces_cannot_be_disabled_when_namespace_exists" | "namespace_cannot_be_used_when_feature_is_disabled" | "sso_domain_not_allowed" | "sso_login_forced_for_this_account" | "use_sso_for_authentication_instead" | "date_has_to_be_in_the_future" | "custom_plan_and_plan_id_cannot_be_set_together" | "specify_plan_id_or_custom_plan" | "custom_plans_has_to_be_private" | "cannot_create_free_plan_with_prices" | "subscription_not_scheduled_for_cancellation" | "cannot_cancel_trial" | "cannot_update_without_modification" | "current_subscription_is_not_trialing" | "sorting_and_paging_is_not_supported_when_using_cursor" | "strings_metric_are_not_supported" | "plan_key_limit_exceeded" | "keys_spending_limit_exceeded" | "plan_seat_limit_exceeded" | "instance_not_using_license_key" | "invalid_path" | "llm_provider_not_found" | "llm_provider_error" | "prompt_not_found" | "llm_provider_not_returned_json" | "llm_template_parsing_error" | "llm_rate_limited" | "llm_provider_timeout" | "no_llm_provider_configured" | "glossary_not_found" | "glossary_term_not_found" | "glossary_term_translation_not_found" | "glossary_non_translatable_term_cannot_be_translated" | "llm_content_filter" | "llm_provider_empty_response" | "label_not_found" | "label_not_from_project" | "label_already_exists" | "filter_by_value_label_not_valid" | "suggestion_not_found" | "user_can_only_delete_his_suggestions" | "cannot_modify_reviewed_translation" | "cannot_modify_keys" | "expect_no_conflict_failed" | "suggestion_cant_be_plural" | "suggestion_must_be_plural" | "duplicate_suggestion"; + params?: Record[]; }; - TagKeyDto: { - name: string; + ExistenceEntityDescription: { + data: { + [key: string]: Record; + }; + entityClass: string; + /** Format: int64 */ + entityId: number; + exists?: boolean; + relations: { + [key: string]: components["schemas"]["EntityDescriptionWithRelations"]; + }; }; - SetFileNamespaceRequest: { - namespace?: string; + ExportParams: { + /** + * @description If true, HTML tags are escaped in the exported file. (Supported in the XLIFF format only). + * + * e.g. Key hello will be exported as <b>hello</b> + */ + escapeHtml: boolean; + /** + * @description This is a template that defines the structure of the resulting .zip file content. + * + * The template is a string that can contain the following placeholders: {namespace}, {languageTag}, + * {androidLanguageTag}, {snakeLanguageTag}, {extension}. + * + * For example, when exporting to JSON with the template `{namespace}/{languageTag}.{extension}`, + * the English translations of the `home` namespace will be stored in `home/en.json`. + * + * The `{snakeLanguageTag}` placeholder is the same as `{languageTag}` but in snake case. (e.g., en_US). + * + * The Android specific `{androidLanguageTag}` placeholder is the same as `{languageTag}` + * but in Android format. (e.g., en-rUS) + */ + fileStructureTemplate?: string; + /** @description Filter key IDs to be contained in export */ + filterKeyId?: number[]; + /** @description Filter key IDs not to be contained in export */ + filterKeyIdNot?: number[]; + /** @description Filter keys with prefix */ + filterKeyPrefix?: string; + /** @description Filter translations with namespace. By default, all namespaces everything are exported. To export default namespace, use empty string. */ + filterNamespace?: string[]; + /** @description Filter translations with state. By default, all states except untranslated is exported. */ + filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; + /** + * @description Filter keys tagged by. + * + * This filter works the same as `filterTagIn` but in this cases it accepts single tag only. + */ + filterTag?: string; + /** @description Filter keys tagged by one of provided tags */ + filterTagIn?: string[]; + /** @description Filter keys not tagged by one of provided tags */ + filterTagNotIn?: string[]; + /** + * @description Format to export to + * @enum {string} + */ + format: "JSON" | "JSON_TOLGEE" | "XLIFF" | "PO" | "APPLE_STRINGS_STRINGSDICT" | "APPLE_XLIFF" | "ANDROID_XML" | "COMPOSE_XML" | "FLUTTER_ARB" | "PROPERTIES" | "YAML_RUBY" | "YAML" | "JSON_I18NEXT" | "CSV" | "RESX_ICU" | "XLSX" | "APPLE_XCSTRINGS"; + /** + * @description Languages to be contained in export. + * + * If null, all languages are exported + * @example en + */ + languages?: string[]; + /** + * @description Message format to be used for export. + * + * e.g. PHP_PO: Hello %s, ICU: Hello {name}. + * + * This property is honored only for generic formats like JSON or YAML. + * For specific formats like `YAML_RUBY` it's ignored. + * @enum {string} + */ + messageFormat?: "C_SPRINTF" | "PHP_SPRINTF" | "JAVA_STRING_FORMAT" | "APPLE_SPRINTF" | "RUBY_SPRINTF" | "I18NEXT" | "ICU" | "PYTHON_PERCENT"; + /** + * @description Delimiter to structure file content. + * + * e.g. For key "home.header.title" would result in {"home": {"header": "title": {"Hello"}}} structure. + * + * When null, resulting file won't be structured. Works only for generic structured formats (e.g. JSON, YAML), + * specific formats like `YAML_RUBY` don't honor this parameter. + */ + structureDelimiter?: string; + /** + * @description If true, for structured formats (like JSON) arrays are supported. + * + * e.g. Key hello[0] will be exported as {"hello": ["..."]} + */ + supportArrays: boolean; + zip: boolean; }; - StreamingResponseBody: Record; - ImportSettingsRequest: { - /** @description If true, key descriptions will be overridden by the import */ - overrideKeyDescriptions: boolean; - /** @description If true, placeholders from other formats will be converted to ICU when possible */ - convertPlaceholdersToIcu: boolean; - /** @description If false, only updates keys, skipping the creation of new keys */ - createNewKeys: boolean; + GetKeysRequestDto: { + keys: components["schemas"]["KeyDefinitionDto"][]; + /** @description Tags to return language translations in */ + languageTags: string[]; }; - ImportSettingsModel: { - /** @description If false, only updates keys, skipping the creation of new keys */ - createNewKeys: boolean; - /** @description If true, key descriptions will be overridden by the import */ - overrideKeyDescriptions: boolean; - /** @description If true, placeholders from other formats will be converted to ICU when possible */ - convertPlaceholdersToIcu: boolean; + GlossaryLanguageDto: { + /** + * @description Indicates if this is the base (main) language of the glossary + * @example true + */ + base: boolean; + /** + * @description The language code (e.g., 'en' for English) + * @example en + */ + tag: string; }; - TranslationCommentModel: { + GlossaryModel: { /** - * Format: int64 - * @description Id of translation comment record + * @description Language tag for default translations for terms + * @example en */ + baseLanguageTag: string; + /** Format: int64 */ id: number; - /** @description Text of comment */ + name: string; + organizationOwner: components["schemas"]["SimpleOrganizationModel"]; + }; + GlossaryTermModel: { + description: string; + /** @description Specifies whether the term represents a shortened form of a word or phrase */ + flagAbbreviation: boolean; + /** @description When true, the term matching considers uppercase and lowercase characters as distinct */ + flagCaseSensitive: boolean; + /** @description When true, marks this term as prohibited or not recommended for use in translations */ + flagForbiddenTerm: boolean; + /** @description When true, this term has the same translation across all target languages */ + flagNonTranslatable: boolean; + glossary: components["schemas"]["GlossaryModel"]; + /** Format: int64 */ + id: number; + translations: components["schemas"]["GlossaryTermTranslationModel"][]; + }; + GlossaryTermTranslationModel: { + languageTag: string; text: string; + }; + ImageUploadInfoDto: { + location?: string; + }; + ImportAddFilesResultModel: { + errors: components["schemas"]["ErrorResponseBody"][]; + result?: components["schemas"]["PagedModelImportLanguageModel"]; + warnings: components["schemas"]["ErrorResponseBody"][]; + }; + ImportFileIssueModel: { + /** Format: int64 */ + id: number; + params: components["schemas"]["ImportFileIssueParamModel"][]; + /** @enum {string} */ + type: "KEY_IS_NOT_STRING" | "MULTIPLE_VALUES_FOR_KEY_AND_LANGUAGE" | "VALUE_IS_NOT_STRING" | "KEY_IS_EMPTY" | "VALUE_IS_EMPTY" | "PO_MSGCTXT_NOT_SUPPORTED" | "ID_ATTRIBUTE_NOT_PROVIDED" | "TARGET_NOT_PROVIDED" | "TRANSLATION_TOO_LONG" | "KEY_IS_BLANK" | "TRANSLATION_DEFINED_IN_ANOTHER_FILE" | "INVALID_CUSTOM_VALUES" | "DESCRIPTION_TOO_LONG"; + }; + ImportFileIssueParamModel: { + /** @enum {string} */ + type: "KEY_NAME" | "KEY_ID" | "LANGUAGE_ID" | "KEY_INDEX" | "VALUE" | "LINE" | "FILE_NODE_ORIGINAL" | "LANGUAGE_NAME"; + value?: string; + }; + /** @description Definition of mapping for each file to import. */ + ImportFileMapping: { + /** @description Name of the file to import. This is the name of the file provided in `files` request part or in uploaded archive. */ + fileName: string; /** - * @description State of translation + * @description Format of the file. If not provided, Tolgee will try to guess the format from the file name or file contents. + * + * It is recommended to provide these values to prevent any issues with format detection. * @enum {string} */ - state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; - author: components["schemas"]["SimpleUserAccountModel"]; + format?: "CSV_ICU" | "CSV_JAVA" | "CSV_PHP" | "CSV_RUBY" | "JSON_I18NEXT" | "JSON_ICU" | "JSON_JAVA" | "JSON_PHP" | "JSON_RUBY" | "JSON_C" | "PO_PHP" | "PO_C" | "PO_JAVA" | "PO_ICU" | "PO_RUBY" | "PO_PYTHON" | "STRINGS" | "STRINGSDICT" | "APPLE_XLIFF" | "APPLE_XCSTRINGS" | "PROPERTIES_ICU" | "PROPERTIES_JAVA" | "PROPERTIES_UNKNOWN" | "ANDROID_XML" | "COMPOSE_XML" | "FLUTTER_ARB" | "YAML_RUBY" | "YAML_JAVA" | "YAML_ICU" | "YAML_PHP" | "YAML_UNKNOWN" | "XLIFF_ICU" | "XLIFF_JAVA" | "XLIFF_PHP" | "XLIFF_RUBY" | "RESX_ICU" | "XLSX_ICU" | "XLSX_JAVA" | "XLSX_PHP" | "XLSX_RUBY"; /** - * Format: date-time - * @description Date when it was created + * @description The existing language tag in the Tolgee platform to which the imported language should be mapped. + * + * When null, Tolgee will try to guess the language from the file contents or file name. */ - createdAt: string; + languageTag?: string; /** - * Format: date-time - * @description Date when it was updated + * @description Tags of languages to be imported. When null, all languages from will be imported. + * + * This field is useful when the file contains multiple languages and you want to import only some of them. For example when importing Apple String Catalog (APPLE_XCSTRINGS), you might want only to import the base language. */ - updatedAt: string; + languageTagsToImport?: string[]; + /** @description Namespace to import the file to. If not provided, the key will be imported without namespace. */ + namespace?: string; }; - TranslationCommentDto: { - text: string; - /** @enum {string} */ - state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; + ImportKeysDto: { + keys: components["schemas"]["ImportKeysItemDto"][]; }; - SetTranslationsWithKeyDto: { + ImportKeysItemDto: { + /** + * @description Description of key + * @example This key is used on homepage. It's a label of sign up button. + */ + description?: string; /** * @description Key name to set translations for * @example what_a_key_to_translate */ - key: string; + name: string; /** @description The namespace of the key. (When empty or null default namespace will be used) */ namespace?: string; + /** + * @description Tags of the key + * @example [ + * "homepage", + * "user-profile" + * ] + */ + tags?: string[]; /** * @description Object mapping language tag to translation * @example { @@ -1258,202 +1533,130 @@ export interface components { translations: { [key: string]: string; }; + }; + ImportKeysResolvableDto: { + keys: components["schemas"]["ImportKeysResolvableItemDto"][]; + }; + ImportKeysResolvableItemDto: { /** - * @description List of languages to return translations for. - * - * If not provided, only modified translation will be provided. - * - * @example [ - * "en", - * "de", - * "fr" - * ] - */ - languagesToReturn?: string[]; - }; - SetTranslationsResponseModel: { - /** - * Format: int64 - * @description Id of key record - */ - keyId: number; - /** - * @description Name of key - * @example this_is_super_key - */ - keyName: string; - /** - * @description The namespace of the key - * @example homepage - */ - keyNamespace?: string; - keyIsPlural: boolean; - /** - * @description Translations object containing values updated in this request - * @example { - * "en": { - * "id": 100000003, - * "text": "This is super translation!" - * } - * } + * @description Key name to set translations for + * @example what_a_key_to_translate */ + name: string; + /** @description The namespace of the key. (When empty or null default namespace will be used) */ + namespace?: string; + screenshots?: components["schemas"]["KeyScreenshotDto"][]; + /** @description Object mapping language tag to translation */ translations: { - [key: string]: components["schemas"]["TranslationModel"]; + [key: string]: components["schemas"]["ImportTranslationResolvableDto"]; }; }; - LanguageRequest: { - /** - * @description Language name in english - * @example Czech - */ - name: string; - /** - * @description Language name in this language - * @example čeština - */ - originalName: string; - /** - * @description Language tag according to BCP 47 definition - * @example cs-CZ - */ - tag: string; - /** - * @description Language flag emoji as UTF-8 emoji - * @example 🇨🇿 - */ - flagEmoji?: string; - }; - OrganizationDto: { - /** @example Beautiful organization */ - name: string; - /** @example This is a beautiful organization full of beautiful and clever people */ - description?: string; - /** @example btforg */ - slug?: string; - }; - OrganizationModel: { + ImportLanguageModel: { + /** Format: int32 */ + conflictCount: number; + existingLanguageAbbreviation?: string; + /** Format: int64 */ + existingLanguageId?: number; + existingLanguageName?: string; + existingLanguageTag?: string; /** Format: int64 */ id: number; - /** @example Beautiful organization */ + /** Format: int64 */ + importFileId: number; + /** Format: int32 */ + importFileIssueCount: number; + importFileName: string; name: string; - /** @example btforg */ - slug: string; - /** @example This is a beautiful organization full of beautiful and clever people */ - description?: string; - basePermissions: components["schemas"]["PermissionModel"]; - /** - * @description The role of currently authorized user. - * - * Can be null when user has direct access to one of the projects owned by the organization. - * @enum {string} - */ - currentUserRole?: "MEMBER" | "OWNER"; - avatar?: components["schemas"]["Avatar"]; + namespace?: string; + /** Format: int32 */ + resolvedCount: number; + /** Format: int32 */ + totalCount: number; }; - CreateProjectRequest: { - name: string; - languages: components["schemas"]["LanguageRequest"][]; - /** @description Slug of your project used in url e.g. "/v2/projects/what-a-project". If not provided, it will be generated */ - slug?: string; + ImportNamespaceModel: { /** * Format: int64 - * @description Organization to create the project in + * @description The id of namespace. When null, namespace doesn't exist and will be created by import. + * @example 10000048 */ - organizationId: number; - /** @description Tag of one of created languages, to select it as base language. If not provided, first language will be selected as base. */ - baseLanguageTag?: string; - /** @description Whether to use ICU placeholder visualization in the editor and it's support. */ - icuPlaceholders: boolean; + id?: number; + /** @example homepage */ + name: string; }; - CreateMultipleTasksRequest: { - tasks: components["schemas"]["CreateTaskRequest"][]; + ImportResult: { + unresolvedConflicts?: components["schemas"]["SimpleImportConflictResult"][]; }; - CreateTaskRequest: { - name: string; - description: string; - /** @enum {string} */ - type: "TRANSLATE" | "REVIEW"; - /** - * Format: int64 - * @description Due to date in epoch format (milliseconds). - * @example 1661172869000 - */ - dueDate?: number; - /** - * Format: int64 - * @description Id of language, this task is attached to. - * @example 1 - */ - languageId: number; - assignees: number[]; - keys: number[]; + ImportSettingsModel: { + /** @description If true, placeholders from other formats will be converted to ICU when possible */ + convertPlaceholdersToIcu: boolean; + /** @description If false, only updates keys, skipping the creation of new keys */ + createNewKeys: boolean; + /** @description If true, key descriptions will be overridden by the import */ + overrideKeyDescriptions: boolean; }; - CalculateScopeRequest: { - /** Format: int64 */ - languageId: number; - /** @enum {string} */ - type: "TRANSLATE" | "REVIEW"; - keys: number[]; + ImportSettingsRequest: { + /** @description If true, placeholders from other formats will be converted to ICU when possible */ + convertPlaceholdersToIcu: boolean; + /** @description If false, only updates keys, skipping the creation of new keys */ + createNewKeys: boolean; + /** @description If true, key descriptions will be overridden by the import */ + overrideKeyDescriptions: boolean; }; - KeysScopeView: { - /** Format: int64 */ - keyCount: number; + ImportTranslationModel: { /** Format: int64 */ - characterCount: number; + conflictId?: number; + conflictText?: string; + /** @enum {string} */ + conflictType?: "CANNOT_EDIT_REVIEWED" | "CANNOT_EDIT_DISABLED" | "SHOULD_NOT_EDIT_REVIEWED"; + existingKeyIsPlural: boolean; /** Format: int64 */ - wordCount: number; + id: number; + isOverridable: boolean; + isPlural: boolean; + keyDescription?: string; /** Format: int64 */ - keyCountIncludingConflicts: number; - }; - GetKeysRequestDto: { - keys: components["schemas"]["KeyDefinitionDto"][]; - /** @description Tags to return language translations in */ - languageTags: string[]; - }; - KeyDefinitionDto: { - name: string; - namespace?: string; - }; - CollectionModelKeyWithDataModel: { - _embedded?: { - keys?: components["schemas"]["KeyWithDataModel"][]; - }; - }; - ImportKeysResolvableDto: { - keys: components["schemas"]["ImportKeysResolvableItemDto"][]; - }; - ImportKeysResolvableItemDto: { - /** - * @description Key name to set translations for - * @example what_a_key_to_translate - */ - name: string; - /** @description The namespace of the key. (When empty or null default namespace will be used) */ - namespace?: string; - screenshots?: components["schemas"]["KeyScreenshotDto"][]; - /** @description Object mapping language tag to translation */ - translations: { - [key: string]: components["schemas"]["ImportTranslationResolvableDto"]; - }; + keyId: number; + keyName: string; + override: boolean; + resolved: boolean; + text?: string; }; /** @description Object mapping language tag to translation */ ImportTranslationResolvableDto: { + /** + * @description Determines, how conflict is resolved. + * - KEEP: Translation is not changed + * - OVERRIDE: Translation is overridden + * - NEW: New translation is created + * - FORCE_OVERRIDE: Translation is updated, created or kept. + * + * @example OVERRIDE + * @enum {string} + */ + resolution: "KEEP" | "OVERRIDE" | "NEW" | "FORCE_OVERRIDE"; /** * @description Translation text * @example Hello! I am a translation! */ text: string; + }; + JwtAuthenticationResponse: { + accessToken?: string; + tokenType?: string; + }; + KeyDefinitionDto: { + name: string; + namespace?: string; + }; + /** @description Exclude keys filtered by the provided key information */ + KeyId: { /** - * @description Determines, how conflict is resolved. - * - * - KEEP: Translation is not changed - * - OVERRIDE: Translation is overridden - * - NEW: New translation is created) - * - * @example OVERRIDE - * @enum {string} + * Format: int64 + * @description If key id is provided, name and namespace are ignored. */ - resolution: "KEEP" | "OVERRIDE" | "NEW"; + id?: number; + name?: string; + namespace?: string; }; KeyImportResolvableResultModel: { /** @description List of keys */ @@ -1463,659 +1666,572 @@ export interface components { [key: string]: components["schemas"]["ScreenshotModel"]; }; }; - ImportKeysDto: { - keys: components["schemas"]["ImportKeysItemDto"][]; + KeyInScreenshotModel: { + /** Format: int64 */ + keyId: number; + keyName: string; + keyNamespace?: string; + originalText?: string; + position?: components["schemas"]["KeyInScreenshotPosition"]; }; - ImportKeysItemDto: { - /** - * @description Key name to set translations for - * @example what_a_key_to_translate - */ - name: string; - /** @description The namespace of the key. (When empty or null default namespace will be used) */ - namespace?: string; - /** - * @description Description of key - * @example This key is used on homepage. It's a label of sign up button. - */ - description?: string; - /** - * @description Object mapping language tag to translation - * @example { - * "en": "What a translated value!", - * "cs": "Jaká to přeložená hodnota!" - * } - */ - translations: { - [key: string]: string; - }; - /** - * @description Tags of the key - * @example [ - * "homepage", - * "user-profile" - * ] - */ - tags?: string[]; + KeyInScreenshotPosition: { + /** Format: int32 */ + height: number; + /** Format: int32 */ + width: number; + /** Format: int32 */ + x: number; + /** Format: int32 */ + y: number; }; - CreateKeyDto: { - /** @description Name of the key */ - name: string; - namespace?: string; - translations?: { - [key: string]: string; - }; - /** @description Translation states to update, if not provided states won't be modified */ - states?: { - [key: string]: "TRANSLATED" | "REVIEWED"; + KeyInScreenshotPositionDto: { + /** Format: int32 */ + height: number; + /** Format: int32 */ + width: number; + /** Format: int32 */ + x: number; + /** Format: int32 */ + y: number; + }; + KeyModel: { + /** @description Custom values of the key */ + custom?: { + [key: string]: Record; }; - tags?: string[]; - /** @description Ids of screenshots uploaded with /v2/image-upload endpoint */ - screenshotUploadedImageIds?: number[]; - screenshots?: components["schemas"]["KeyScreenshotDto"][]; - /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ - relatedKeysInOrder?: components["schemas"]["RelatedKeyDto"][]; /** - * @description Description of the key + * @description Description of key * @example This key is used on homepage. It's a label of sign up button. */ description?: string; - /** @description If key is pluralized. If it will be reflected in the editor */ - isPlural: boolean; - /** @description The argument name for the plural. If null, value will be guessed from the values provided in translations. */ - pluralArgName?: string; - }; - UntagKeysRequest: { - keyIds: number[]; - tags: string[]; - }; - BatchJobModel: { /** * Format: int64 - * @description Batch job id + * @description Id of key record */ id: number; /** - * @description Status of the batch job - * @enum {string} - */ - status: "PENDING" | "RUNNING" | "SUCCESS" | "FAILED" | "CANCELLED" | "DEBOUNCED"; - /** - * @description Type of the batch job - * @enum {string} - */ - type: "PRE_TRANSLATE_BT_TM" | "MACHINE_TRANSLATE" | "AUTO_TRANSLATE" | "DELETE_KEYS" | "SET_TRANSLATIONS_STATE" | "CLEAR_TRANSLATIONS" | "COPY_TRANSLATIONS" | "TAG_KEYS" | "UNTAG_KEYS" | "SET_KEYS_NAMESPACE" | "AUTOMATION"; - /** - * Format: int32 - * @description Total items, that have been processed so far - */ - progress: number; - /** - * Format: int32 - * @description Total items - */ - totalItems: number; - author?: components["schemas"]["SimpleUserAccountModel"]; - /** - * Format: int64 - * @description The time when the job created + * @description Name of key + * @example this_is_super_key */ - createdAt: number; + name: string; /** - * Format: int64 - * @description The time when the job was last updated (status change) + * @description Namespace of key + * @example homepage */ - updatedAt: number; + namespace?: string; + }; + KeyScreenshotDto: { + positions?: components["schemas"]["KeyInScreenshotPositionDto"][]; + text?: string; /** * Format: int64 - * @description The activity revision id, that stores the activity details of the job + * @description Ids of screenshot uploaded with /v2/image-upload endpoint */ - activityRevisionId?: number; - /** @description If the job failed, this is the error message */ - errorMessage?: string; - }; - TagKeysRequest: { - keyIds: number[]; - tags: string[]; - }; - SetTranslationsStateStateRequest: { - keyIds: number[]; - languageIds: number[]; - /** @enum {string} */ - state: "UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED"; + uploadedImageId: number; }; - SetKeysNamespaceRequest: { - keyIds: number[]; + KeySearchResultView: { + baseTranslation?: string; + description?: string; + /** Format: int64 */ + id: number; + name: string; namespace?: string; + translation?: string; }; - PreTranslationByTmRequest: { - keyIds: number[]; - targetLanguageIds: number[]; - }; - MachineTranslationRequest: { - keyIds: number[]; - targetLanguageIds: number[]; - }; - DeleteKeysRequest: { - keyIds: number[]; - }; - CopyTranslationRequest: { - keyIds: number[]; + KeySearchSearchResultModel: { + baseTranslation?: string; + description?: string; /** Format: int64 */ - sourceLanguageId: number; - targetLanguageIds: number[]; + id: number; + name: string; + namespace?: string; + translation?: string; + view?: components["schemas"]["KeySearchResultView"]; }; - ClearTranslationsRequest: { - keyIds: number[]; - languageIds: number[]; + /** @description Tasks related to this key */ + KeyTaskViewModel: { + done: boolean; + /** Format: int64 */ + languageId: number; + languageTag: string; + /** Format: int64 */ + number: number; + /** @enum {string} */ + type: "TRANSLATE" | "REVIEW"; + userAssigned: boolean; }; - /** @description Definition of mapping for each file to import. */ - ImportFileMapping: { - /** @description Name of the file to import. This is the name of the file provided in `files` request part or in uploaded archive. */ - fileName: string; - /** @description Namespace to import the file to. If not provided, the key will be imported without namespace. */ - namespace?: string; + KeyWithBaseTranslationModel: { /** - * @description Format of the file. If not provided, Tolgee will try to guess the format from the file name or file contents. - * - * It is recommended to provide these values to prevent any issues with format detection. - * @enum {string} + * @description Base translation + * @example This is translation */ - format?: "JSON_I18NEXT" | "JSON_ICU" | "JSON_JAVA" | "JSON_PHP" | "JSON_RUBY" | "JSON_C" | "PO_PHP" | "PO_C" | "PO_JAVA" | "PO_ICU" | "PO_RUBY" | "STRINGS" | "STRINGSDICT" | "APPLE_XLIFF" | "PROPERTIES_ICU" | "PROPERTIES_JAVA" | "PROPERTIES_UNKNOWN" | "ANDROID_XML" | "FLUTTER_ARB" | "YAML_RUBY" | "YAML_JAVA" | "YAML_ICU" | "YAML_PHP" | "YAML_UNKNOWN" | "XLIFF_ICU" | "XLIFF_JAVA" | "XLIFF_PHP" | "XLIFF_RUBY"; + baseTranslation?: string; /** - * @description The existing language tag in the Tolgee platform to which the imported language should be mapped. - * - * When null, Tolgee will try to guess the language from the file contents or file name. + * Format: int64 + * @description Id of key record */ - languageTag?: string; - }; - /** - * @description Maps the languages from imported files to languages existing in the Tolgee platform. - * - * Use this field only when your files contain multiple languages (e.g., XLIFF files). - * - * Otherwise, use the `languageTag` property of `fileMappings`. - * - * Example: In xliff files, there are `source-language` and `target-language` attributes defined on `file` element. Using this field you can map source and target values to languages stored in the Tolgee Platform. - */ - LanguageMapping: { + id: number; /** - * @description The language from the imported file. - * - * For xliff files, this is the `source-language` or the `target-language` attribute value of `file` element. - * @example en-US + * @description Name of key + * @example this_is_super_key */ - importLanguage: string; + name: string; /** - * @description The tag of language existing in the Tolgee platform to which the imported language should be mapped. - * @example en-US + * @description Namespace of key + * @example homepage */ - platformLanguageTag: string; + namespace?: string; }; - SingleStepImportRequest: { + KeyWithDataModel: { + /** @description Custom values of the key */ + custom: { + [key: string]: Record; + }; /** - * @description When importing files in structured formats (e.g., JSON, YAML), this field defines the delimiter which will be used in names of imported keys. - * @example . + * @description Description of key + * @example This key is used on homepage. It's a label of sign up button. */ - structureDelimiter?: string; + description?: string; /** - * @description Whether to override existing translation data. - * - * When set to `KEEP`, existing translations will be kept. - * - * When set to `OVERRIDE`, existing translations will be overwrote. - * - * When set to `NO_FORCE`, error will be thrown on conflict. - * @enum {string} + * Format: int64 + * @description Id of key record */ - forceMode: "OVERRIDE" | "KEEP" | "NO_FORCE"; + id: number; + /** @description If key is pluralized. If it will be reflected in the editor */ + isPlural: boolean; /** - * @description Maps the languages from imported files to languages existing in the Tolgee platform. - * - * Use this field only when your files contain multiple languages (e.g., XLIFF files). - * - * Otherwise, use the `languageTag` property of `fileMappings`. - * - * Example: In xliff files, there are `source-language` and `target-language` attributes defined on `file` element. Using this field you can map source and target values to languages stored in the Tolgee Platform. + * @description Name of key + * @example this_is_super_key */ - languageMappings?: components["schemas"]["LanguageMapping"][]; - /** @description If true, key descriptions will be overridden by the import */ - overrideKeyDescriptions: boolean; - /** @description If true, placeholders from other formats will be converted to ICU when possible */ - convertPlaceholdersToIcu: boolean; - /** @description If false, only updates keys, skipping the creation of new keys */ - createNewKeys: boolean; - /** @description Definition of mapping for each file to import. */ - fileMappings: components["schemas"]["ImportFileMapping"][]; - /** @description Keys created by this import will be tagged with these tags. It add tags only to new keys. The keys that already exist will not be tagged. */ - tagNewKeys: string[]; - /** @description If yes, keys from project that were not included in import will be deleted. */ - removeOtherKeys?: boolean; - }; - ImportAddFilesResultModel: { - errors: components["schemas"]["ErrorResponseBody"][]; - result?: components["schemas"]["PagedModelImportLanguageModel"]; - }; - ImportLanguageModel: { - /** Format: int64 */ - id: number; name: string; - /** Format: int64 */ - existingLanguageId?: number; - existingLanguageTag?: string; - existingLanguageAbbreviation?: string; - existingLanguageName?: string; - importFileName: string; - /** Format: int64 */ - importFileId: number; - /** Format: int32 */ - importFileIssueCount: number; + /** + * @description Namespace of key + * @example homepage + */ namespace?: string; - /** Format: int32 */ - totalCount: number; - /** Format: int32 */ - conflictCount: number; - /** Format: int32 */ - resolvedCount: number; - }; - PageMetadata: { - /** Format: int64 */ - size?: number; - /** Format: int64 */ - totalElements?: number; - /** Format: int64 */ - totalPages?: number; - /** Format: int64 */ - number?: number; - }; - PagedModelImportLanguageModel: { - _embedded?: { - languages?: components["schemas"]["ImportLanguageModel"][]; + /** @description The argument name for the plural */ + pluralArgName?: string; + /** @description Screenshots of the key */ + screenshots: components["schemas"]["ScreenshotModel"][]; + /** @description Tags of key */ + tags: components["schemas"]["TagModel"][]; + /** + * @description Translations object containing values updated in this request + * @example { + * "en": { + * "id": 100000003, + * "text": "This is super translation!" + * } + * } + */ + translations: { + [key: string]: components["schemas"]["TranslationModel"]; }; - page?: components["schemas"]["PageMetadata"]; }; - ExportParams: { + KeyWithTranslationsModel: { + /** @description There is a context available for this key */ + contextPresent: boolean; /** - * @description Languages to be contained in export. - * - * If null, all languages are exported - * @example en + * Format: int64 + * @description The time when the key was created */ - languages?: string[]; + createdAt: number; /** - * @description Format to export to - * @enum {string} + * @description The namespace of the key + * @example homepage */ - format: "JSON" | "JSON_TOLGEE" | "JSON_I18NEXT" | "XLIFF" | "PO" | "APPLE_STRINGS_STRINGSDICT" | "APPLE_XLIFF" | "ANDROID_XML" | "FLUTTER_ARB" | "PROPERTIES" | "YAML_RUBY" | "YAML"; + keyDescription?: string; /** - * @description Delimiter to structure file content. - * - * e.g. For key "home.header.title" would result in {"home": {"header": "title": {"Hello"}}} structure. - * - * When null, resulting file won't be structured. Works only for generic structured formats (e.g. JSON, YAML), - * specific formats like `YAML_RUBY` don't honor this parameter. + * Format: int64 + * @description Id of key record */ - structureDelimiter?: string; - /** @description Filter key IDs to be contained in export */ - filterKeyId?: number[]; - /** @description Filter key IDs not to be contained in export */ - filterKeyIdNot?: number[]; + keyId: number; /** - * @description Filter keys tagged by. - * - * This filter works the same as `filterTagIn` but in this cases it accepts single tag only. + * @description Is this key a plural? + * @example true */ - filterTag?: string; - /** @description Filter keys tagged by one of provided tags */ - filterTagIn?: string[]; - /** @description Filter keys not tagged by one of provided tags */ - filterTagNotIn?: string[]; - /** @description Filter keys with prefix */ - filterKeyPrefix?: string; - /** @description Filter translations with state. By default, all states except untranslated is exported. */ - filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; - /** @description Filter translations with namespace. By default, all namespaces everything are exported. To export default namespace, use empty string. */ - filterNamespace?: string[]; - zip: boolean; + keyIsPlural: boolean; /** - * @description Message format to be used for export. - * - * e.g. PHP_PO: Hello %s, ICU: Hello {name}. - * - * This property is honored only for generic formats like JSON or YAML. - * For specific formats like `YAML_RUBY` it's ignored. - * @enum {string} + * @description Name of key + * @example this_is_super_key */ - messageFormat?: "C_SPRINTF" | "PHP_SPRINTF" | "JAVA_STRING_FORMAT" | "APPLE_SPRINTF" | "RUBY_SPRINTF" | "I18NEXT" | "ICU"; + keyName: string; /** - * @description This is a template that defines the structure of the resulting .zip file content. - * - * The template is a string that can contain the following placeholders: {namespace}, {languageTag}, - * {androidLanguageTag}, {snakeLanguageTag}, {extension}. - * - * For example, when exporting to JSON with the template `{namespace}/{languageTag}.{extension}`, - * the English translations of the `home` namespace will be stored in `home/en.json`. - * - * The `{snakeLanguageTag}` placeholder is the same as `{languageTag}` but in snake case. (e.g., en_US). - * - * The Android specific `{androidLanguageTag}` placeholder is the same as `{languageTag}` - * but in Android format. (e.g., en-rUS) + * @description The namespace of the key + * @example homepage */ - fileStructureTemplate?: string; + keyNamespace?: string; /** - * @description If true, for structured formats (like JSON) arrays are supported. - * - * e.g. Key hello[0] will be exported as {"hello": ["..."]} + * Format: int64 + * @description The namespace id of the key + * @example 100000282 */ - supportArrays: boolean; - }; - BigMetaDto: { - /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ - relatedKeysInOrder?: components["schemas"]["RelatedKeyDto"][]; - }; - TranslationCommentWithLangKeyDto: { - /** Format: int64 */ - keyId: number; - /** Format: int64 */ - languageId: number; - text: string; - /** @enum {string} */ - state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; - }; - TranslationWithCommentModel: { - translation: components["schemas"]["TranslationModel"]; - comment: components["schemas"]["TranslationCommentModel"]; - }; - SuggestRequestDto: { + keyNamespaceId?: number; + /** + * @description The placeholder name for plural parameter + * @example value + */ + keyPluralArgName?: string; + /** @description Tags of key */ + keyTags: components["schemas"]["TagModel"][]; /** * Format: int64 - * @description Key Id to get results for. Use when key is stored already. + * @description Count of screenshots provided for the key + * @example 1 */ - keyId?: number; + screenshotCount: number; + /** @description Key screenshots. Not provided when API key hasn't screenshots.view scope permission. */ + screenshots?: components["schemas"]["ScreenshotModel"][]; + /** @description Tasks related to this key */ + tasks?: components["schemas"]["KeyTaskViewModel"][]; + /** + * @description Translations object + * @example + * { + * "en": { + * "id": 100000003, + * "text": "This is super translation!" + * "state": "TRANSLATED", + * "commentCount": 1 + * } + * } + */ + translations: { + [key: string]: components["schemas"]["TranslationViewModel"]; + }; + }; + KeysScopeView: { /** Format: int64 */ - targetLanguageId: number; - /** @description Text value of base translation. Useful, when base translation is not stored yet. */ - baseText?: string; - /** @description Whether base text is plural. This value is ignored if baseText is null. */ - isPlural?: boolean; - /** @description List of services to use. If null, then all enabled services are used. */ - services?: ("GOOGLE" | "AWS" | "DEEPL" | "AZURE" | "BAIDU" | "TOLGEE")[]; - plural?: boolean; + characterCount: number; + /** Format: int64 */ + keyCount: number; + /** Format: int64 */ + keyCountIncludingConflicts: number; + /** Format: int64 */ + wordCount: number; }; - PagedModelTranslationMemoryItemModel: { + KeysWithTranslationsPageModel: { _embedded?: { - translationMemoryItems?: components["schemas"]["TranslationMemoryItemModel"][]; + keys?: components["schemas"]["KeyWithTranslationsModel"][]; }; + /** + * @description Cursor to get next data + * @example eyJrZXlJZCI6eyJkaXJlY3Rpb24iOiJBU0MiLCJ2YWx1ZSI6IjEwMDAwMDAxMjAifX0= + */ + nextCursor?: string; page?: components["schemas"]["PageMetadata"]; + pagedModel?: components["schemas"]["PagedModelKeyWithTranslationsModel"]; + /** @description Provided languages data */ + selectedLanguages: components["schemas"]["LanguageModel"][]; }; - TranslationMemoryItemModel: { - targetText: string; - baseText: string; - keyName: string; - /** Format: float */ - similarity: number; + LabelModel: { + color: string; + description?: string; + /** Format: int64 */ + id: number; + name: string; }; - SuggestResultModel: { + LabelRequest: { /** - * @deprecated - * @description String translations provided by enabled services. (deprecated, use `result` instead) - * @example - * { - * "GOOGLE": "This was translated by Google", - * "TOLGEE": "This was translated by Tolgee Translator", - * } + * @description Hex color in format #RRGGBB. + * @example #FF5733 */ - machineTranslations?: { - [key: string]: string; - }; + color: string; + description?: string; + name: string; + }; + LabelTranslationsRequest: { + keyIds: number[]; + labelIds: number[]; + languageIds: number[]; + }; + /** + * @description Maps the languages from imported files to languages existing in the Tolgee platform. + * + * Use this field only when your files contain multiple languages (e.g., XLIFF files). + * + * Otherwise, use the `languageTag` property of `fileMappings`. + * + * Example: In xliff files, there are `source-language` and `target-language` attributes defined on `file` element. Using this field you can map source and target values to languages stored in the Tolgee Platform. + */ + LanguageMapping: { /** - * @description Results provided by enabled services. - * @example { - * "GOOGLE": { - * "output": "This was translated by Google", - * "contextDescription": null - * }, - * "TOLGEE": { - * "output": "This was translated by Tolgee Translator", - * "contextDescription": "This is an example in swagger" - * } - * } + * @description The language from the imported file. + * + * For xliff files, this is the `source-language` or the `target-language` attribute value of `file` element. + * @example en-US */ - result?: { - [key: string]: components["schemas"]["TranslationItemModel"]; - }; - /** @description If true, the base translation was empty and no translation was provided. */ - baseBlank: boolean; - }; - /** - * @description Results provided by enabled services. - * @example { - * "GOOGLE": { - * "output": "This was translated by Google", - * "contextDescription": null - * }, - * "TOLGEE": { - * "output": "This was translated by Tolgee Translator", - * "contextDescription": "This is an example in swagger" - * } - * } - */ - TranslationItemModel: { - output: string; - contextDescription?: string; - }; - ScreenshotInfoDto: { - text?: string; - positions?: components["schemas"]["KeyInScreenshotPositionDto"][]; - location?: string; - }; - ImageUploadInfoDto: { - location?: string; - }; - UploadedImageModel: { - /** Format: int64 */ - id: number; - filename: string; - fileUrl: string; - requestFilename: string; - /** Format: date-time */ - createdAt: string; - location?: string; - }; - PagedModelTaskWithProjectModel: { - _embedded?: { - tasks?: components["schemas"]["TaskWithProjectModel"][]; - }; - page?: components["schemas"]["PageMetadata"]; + importLanguage: string; + /** + * @description The tag of language existing in the Tolgee platform to which the imported language should be mapped. + * @example en-US + */ + platformLanguageTag: string; }; - SimpleProjectModel: { + LanguageModel: { + /** + * @description Whether is base language of project + * @example false + */ + base: boolean; + /** + * @description Language flag emoji as UTF-8 emoji + * @example 🇨🇿 + */ + flagEmoji?: string; /** Format: int64 */ id: number; + /** + * @description Language name in english + * @example Czech + */ name: string; - description?: string; - slug?: string; - avatar?: components["schemas"]["Avatar"]; - baseLanguage?: components["schemas"]["LanguageModel"]; - icuPlaceholders: boolean; + /** + * @description Language name in this language + * @example čeština + */ + originalName?: string; + /** + * @description Language tag according to BCP 47 definition + * @example cs-CZ + */ + tag: string; }; - TaskWithProjectModel: { - /** Format: int64 */ - number: number; + LanguageRequest: { + /** + * @description Language flag emoji as UTF-8 emoji + * @example 🇨🇿 + */ + flagEmoji?: string; + /** + * @description Language name in english + * @example Czech + */ name: string; - description: string; - /** @enum {string} */ - type: "TRANSLATE" | "REVIEW"; - language: components["schemas"]["LanguageModel"]; + /** + * @description Language name in this language + * @example čeština + */ + originalName: string; + /** + * @description Language tag according to BCP 47 definition + * @example cs-CZ + */ + tag: string; + }; + LanguageStatsModel: { + languageFlagEmoji?: string; /** Format: int64 */ - dueDate?: number; - assignees: components["schemas"]["SimpleUserAccountModel"][]; + languageId?: number; + languageName?: string; + languageOriginalName?: string; + languageTag?: string; /** Format: int64 */ - totalItems: number; + reviewedKeyCount: number; + /** Format: double */ + reviewedPercentage: number; /** Format: int64 */ - doneItems: number; + reviewedWordCount: number; /** Format: int64 */ - baseWordCount: number; + translatedKeyCount: number; + /** Format: double */ + translatedPercentage: number; /** Format: int64 */ - baseCharacterCount: number; - author?: components["schemas"]["SimpleUserAccountModel"]; + translatedWordCount: number; + /** Format: date-time */ + translationsUpdatedAt?: string; /** Format: int64 */ - createdAt?: number; + untranslatedKeyCount: number; + /** Format: double */ + untranslatedPercentage: number; /** Format: int64 */ - closedAt?: number; - /** @enum {string} */ - state: "NEW" | "IN_PROGRESS" | "DONE" | "CLOSED"; - project: components["schemas"]["SimpleProjectModel"]; + untranslatedWordCount: number; }; - PagedModelProjectModel: { - _embedded?: { - projects?: components["schemas"]["ProjectModel"][]; - }; - page?: components["schemas"]["PageMetadata"]; + MachineTranslationRequest: { + keyIds: number[]; + llmPrompt?: components["schemas"]["PromptDto"]; + targetLanguageIds: number[]; }; - CollectionModelUsedNamespaceModel: { - _embedded?: { - namespaces?: components["schemas"]["UsedNamespaceModel"][]; + ModifiedEntityModel: { + description?: { + [key: string]: Record; + }; + entityClass: string; + /** Format: int64 */ + entityId: number; + exists?: boolean; + modifications?: { + [key: string]: components["schemas"]["PropertyModification"]; + }; + relations?: { + [key: string]: components["schemas"]["ExistenceEntityDescription"]; }; }; - UsedNamespaceModel: { + NamespaceModel: { /** * Format: int64 - * @description The id of namespace. Null for default namespace. + * @description The id of namespace * @example 10000048 */ - id?: number; - /** - * @description Name of namespace. Null if default. - * @example homepage - */ - name?: string; + id: number; + /** @example homepage */ + name: string; }; - TaskPerUserReportModel: { - user: components["schemas"]["SimpleUserAccountModel"]; - /** Format: int64 */ - doneItems: number; - /** Format: int64 */ - baseCharacterCount: number; + NotificationModel: { + /** Format: date-time */ + createdAt?: string; /** Format: int64 */ - baseWordCount: number; + id: number; + linkedTask?: components["schemas"]["TaskModel"]; + originatingUser?: components["schemas"]["SimpleUserAccountModel"]; + project?: components["schemas"]["SimpleProjectModel"]; + /** @enum {string} */ + type: "TASK_ASSIGNED" | "TASK_FINISHED" | "TASK_CANCELED" | "MFA_ENABLED" | "MFA_DISABLED" | "PASSWORD_CHANGED"; }; - TaskKeysResponse: { - keys: number[]; + NotificationSettingGroupModel: { + email: boolean; + inApp: boolean; }; - PagedModelSimpleUserAccountModel: { - _embedded?: { - users?: components["schemas"]["SimpleUserAccountModel"][]; - }; - page?: components["schemas"]["PageMetadata"]; + NotificationSettingModel: { + accountSecurity: components["schemas"]["NotificationSettingGroupModel"]; + tasks: components["schemas"]["NotificationSettingGroupModel"]; }; - PagedModelTaskModel: { - _embedded?: { - tasks?: components["schemas"]["TaskModel"][]; - }; - page?: components["schemas"]["PageMetadata"]; + NotificationSettingsRequest: { + /** + * @example IN_APP + * @enum {string} + */ + channel: "IN_APP" | "EMAIL"; + /** + * @description True if the setting should be enabled, false for disabled + * @example false + */ + enabled: boolean; + /** + * @example TASKS + * @enum {string} + */ + group: "ACCOUNT_SECURITY" | "TASKS"; }; - PagedModelNamespaceModel: { - _embedded?: { - namespaces?: components["schemas"]["NamespaceModel"][]; - }; - page?: components["schemas"]["PageMetadata"]; + NotificationsMarkSeenRequest: { + /** + * @description Notification IDs to be marked as seen + * @example [ + * 1, + * 2, + * 3 + * ] + */ + notificationIds: number[]; }; - KeySearchResultView: { + OrganizationDto: { + /** @example This is a beautiful organization full of beautiful and clever people */ description?: string; + /** @example Beautiful organization */ name: string; + /** @example btforg */ + slug?: string; + }; + OrganizationModel: { + avatar?: components["schemas"]["Avatar"]; + basePermissions: components["schemas"]["PermissionModel"]; + /** + * @description The role of currently authorized user. + * + * Can be null when user has direct access to one of the projects owned by the organization. + * @enum {string} + */ + currentUserRole?: "MEMBER" | "OWNER" | "MAINTAINER"; + /** @example This is a beautiful organization full of beautiful and clever people */ + description?: string; /** Format: int64 */ id: number; - baseTranslation?: string; - namespace?: string; - translation?: string; - }; - KeySearchSearchResultModel: { - view?: components["schemas"]["KeySearchResultView"]; - description?: string; + /** @example Beautiful organization */ name: string; + /** @example btforg */ + slug: string; + }; + PageMetadata: { /** Format: int64 */ - id: number; - baseTranslation?: string; - namespace?: string; - translation?: string; + number?: number; + /** Format: int64 */ + size?: number; + /** Format: int64 */ + totalElements?: number; + /** Format: int64 */ + totalPages?: number; }; - PagedModelKeySearchSearchResultModel: { + PagedModelBatchJobModel: { _embedded?: { - keys?: components["schemas"]["KeySearchSearchResultModel"][]; + batchJobs?: components["schemas"]["BatchJobModel"][]; }; page?: components["schemas"]["PageMetadata"]; }; - PagedModelKeyModel: { + PagedModelImportFileIssueModel: { _embedded?: { - keys?: components["schemas"]["KeyModel"][]; + importFileIssues?: components["schemas"]["ImportFileIssueModel"][]; }; page?: components["schemas"]["PageMetadata"]; }; - EntityDescriptionWithRelations: { - entityClass: string; - /** Format: int64 */ - entityId: number; - data: { - [key: string]: Record; + PagedModelImportLanguageModel: { + _embedded?: { + languages?: components["schemas"]["ImportLanguageModel"][]; }; + page?: components["schemas"]["PageMetadata"]; }; - ExistenceEntityDescription: { - entityClass: string; - /** Format: int64 */ - entityId: number; - data: { - [key: string]: Record; - }; - relations: { - [key: string]: components["schemas"]["EntityDescriptionWithRelations"]; + PagedModelImportTranslationModel: { + _embedded?: { + translations?: components["schemas"]["ImportTranslationModel"][]; }; - exists?: boolean; + page?: components["schemas"]["PageMetadata"]; }; - ModifiedEntityModel: { - entityClass: string; - /** Format: int64 */ - entityId: number; - description?: { - [key: string]: Record; + PagedModelKeyModel: { + _embedded?: { + keys?: components["schemas"]["KeyModel"][]; }; - modifications?: { - [key: string]: components["schemas"]["PropertyModification"]; + page?: components["schemas"]["PageMetadata"]; + }; + PagedModelKeySearchSearchResultModel: { + _embedded?: { + keys?: components["schemas"]["KeySearchSearchResultModel"][]; }; - relations?: { - [key: string]: components["schemas"]["ExistenceEntityDescription"]; + page?: components["schemas"]["PageMetadata"]; + }; + PagedModelKeyWithTranslationsModel: { + _embedded?: { + keys?: components["schemas"]["KeyWithTranslationsModel"][]; }; - exists?: boolean; + page?: components["schemas"]["PageMetadata"]; }; - PropertyModification: { - old?: Record; - new?: Record; + PagedModelLabelModel: { + _embedded?: { + labels?: components["schemas"]["LabelModel"][]; + }; + page?: components["schemas"]["PageMetadata"]; }; - ProjectActivityAuthorModel: { - /** Format: int64 */ - id: number; - username?: string; - name?: string; - avatar?: components["schemas"]["Avatar"]; - deleted: boolean; + PagedModelLanguageModel: { + _embedded?: { + languages?: components["schemas"]["LanguageModel"][]; + }; + page?: components["schemas"]["PageMetadata"]; }; - ProjectActivityModel: { - /** Format: int64 */ - revisionId: number; - /** Format: int64 */ - timestamp: number; - /** @enum {string} */ - type: "UNKNOWN" | "SET_TRANSLATION_STATE" | "SET_TRANSLATIONS" | "DISMISS_AUTO_TRANSLATED_STATE" | "SET_OUTDATED_FLAG" | "TRANSLATION_COMMENT_ADD" | "TRANSLATION_COMMENT_DELETE" | "TRANSLATION_COMMENT_EDIT" | "TRANSLATION_COMMENT_SET_STATE" | "SCREENSHOT_DELETE" | "SCREENSHOT_ADD" | "KEY_TAGS_EDIT" | "KEY_NAME_EDIT" | "KEY_DELETE" | "CREATE_KEY" | "COMPLEX_EDIT" | "IMPORT" | "CREATE_LANGUAGE" | "EDIT_LANGUAGE" | "DELETE_LANGUAGE" | "HARD_DELETE_LANGUAGE" | "CREATE_PROJECT" | "EDIT_PROJECT" | "NAMESPACE_EDIT" | "BATCH_PRE_TRANSLATE_BY_TM" | "BATCH_MACHINE_TRANSLATE" | "AUTO_TRANSLATE" | "BATCH_CLEAR_TRANSLATIONS" | "BATCH_COPY_TRANSLATIONS" | "BATCH_SET_TRANSLATION_STATE" | "BATCH_TAG_KEYS" | "BATCH_UNTAG_KEYS" | "BATCH_SET_KEYS_NAMESPACE" | "AUTOMATION" | "CONTENT_DELIVERY_CONFIG_CREATE" | "CONTENT_DELIVERY_CONFIG_UPDATE" | "CONTENT_DELIVERY_CONFIG_DELETE" | "CONTENT_STORAGE_CREATE" | "CONTENT_STORAGE_UPDATE" | "CONTENT_STORAGE_DELETE" | "WEBHOOK_CONFIG_CREATE" | "WEBHOOK_CONFIG_UPDATE" | "WEBHOOK_CONFIG_DELETE" | "COMPLEX_TAG_OPERATION" | "TASKS_CREATE" | "TASK_CREATE" | "TASK_UPDATE" | "TASK_KEYS_UPDATE" | "TASK_FINISH" | "TASK_CLOSE" | "TASK_REOPEN" | "TASK_KEY_UPDATE"; - author?: components["schemas"]["ProjectActivityAuthorModel"]; - modifiedEntities?: { - [key: string]: components["schemas"]["ModifiedEntityModel"][]; + PagedModelNamespaceModel: { + _embedded?: { + namespaces?: components["schemas"]["NamespaceModel"][]; }; - meta?: { - [key: string]: Record; + page?: components["schemas"]["PageMetadata"]; + }; + PagedModelNotificationModel: { + _embedded?: { + notificationModelList?: components["schemas"]["NotificationModel"][]; }; - counts?: { - [key: string]: number; + page?: components["schemas"]["PageMetadata"]; + }; + PagedModelOrganizationModel: { + _embedded?: { + organizations?: components["schemas"]["OrganizationModel"][]; }; - params?: Record; + page?: components["schemas"]["PageMetadata"]; }; PagedModelProjectActivityModel: { _embedded?: { @@ -2123,112 +2239,59 @@ export interface components { }; page?: components["schemas"]["PageMetadata"]; }; - PagedModelTagModel: { + PagedModelProjectModel: { _embedded?: { - tags?: components["schemas"]["TagModel"][]; + projects?: components["schemas"]["ProjectModel"][]; }; page?: components["schemas"]["PageMetadata"]; }; - PagedModelBatchJobModel: { + PagedModelSimpleGlossaryModel: { _embedded?: { - batchJobs?: components["schemas"]["BatchJobModel"][]; + glossaries?: components["schemas"]["SimpleGlossaryModel"][]; }; page?: components["schemas"]["PageMetadata"]; }; - CreditBalanceModel: { - /** Format: int64 */ - creditBalance: number; - /** Format: int64 */ - bucketSize: number; - /** Format: int64 */ - extraCreditBalance: number; - }; - CollectionModelKeyWithBaseTranslationModel: { + PagedModelSimpleGlossaryTermModel: { _embedded?: { - keys?: components["schemas"]["KeyWithBaseTranslationModel"][]; + glossaryTerms?: components["schemas"]["SimpleGlossaryTermModel"][]; }; + page?: components["schemas"]["PageMetadata"]; }; - KeyWithBaseTranslationModel: { - /** - * Format: int64 - * @description Id of key record - */ - id: number; - /** - * @description Name of key - * @example this_is_super_key - */ - name: string; - /** - * @description Namespace of key - * @example homepage - */ - namespace?: string; - /** - * @description Base translation - * @example This is translation - */ - baseTranslation?: string; - }; - ImportTranslationModel: { - /** Format: int64 */ - id: number; - text?: string; - keyName: string; - /** Format: int64 */ - keyId: number; - keyDescription?: string; - /** Format: int64 */ - conflictId?: number; - conflictText?: string; - override: boolean; - resolved: boolean; - isPlural: boolean; - existingKeyIsPlural: boolean; - }; - PagedModelImportTranslationModel: { + PagedModelSimpleGlossaryTermWithTranslationsModel: { _embedded?: { - translations?: components["schemas"]["ImportTranslationModel"][]; + glossaryTerms?: components["schemas"]["SimpleGlossaryTermWithTranslationsModel"][]; }; page?: components["schemas"]["PageMetadata"]; }; - ImportFileIssueModel: { - /** Format: int64 */ - id: number; - /** @enum {string} */ - type: "KEY_IS_NOT_STRING" | "MULTIPLE_VALUES_FOR_KEY_AND_LANGUAGE" | "VALUE_IS_NOT_STRING" | "KEY_IS_EMPTY" | "VALUE_IS_EMPTY" | "PO_MSGCTXT_NOT_SUPPORTED" | "ID_ATTRIBUTE_NOT_PROVIDED" | "TARGET_NOT_PROVIDED" | "TRANSLATION_TOO_LONG" | "KEY_IS_BLANK" | "TRANSLATION_DEFINED_IN_ANOTHER_FILE" | "INVALID_CUSTOM_VALUES"; - params: components["schemas"]["ImportFileIssueParamModel"][]; - }; - ImportFileIssueParamModel: { - /** @enum {string} */ - type: "KEY_NAME" | "KEY_ID" | "LANGUAGE_ID" | "KEY_INDEX" | "VALUE" | "LINE" | "FILE_NODE_ORIGINAL" | "LANGUAGE_NAME"; - value?: string; + PagedModelSimpleGlossaryWithStatsModel: { + _embedded?: { + glossaries?: components["schemas"]["SimpleGlossaryWithStatsModel"][]; + }; + page?: components["schemas"]["PageMetadata"]; }; - PagedModelImportFileIssueModel: { + PagedModelSimpleUserAccountModel: { _embedded?: { - importFileIssues?: components["schemas"]["ImportFileIssueModel"][]; + users?: components["schemas"]["SimpleUserAccountModel"][]; }; page?: components["schemas"]["PageMetadata"]; }; - CollectionModelImportNamespaceModel: { + PagedModelTagModel: { _embedded?: { - namespaces?: components["schemas"]["ImportNamespaceModel"][]; + tags?: components["schemas"]["TagModel"][]; }; + page?: components["schemas"]["PageMetadata"]; }; - ImportNamespaceModel: { - /** - * Format: int64 - * @description The id of namespace. When null, namespace doesn't exist and will be created by import. - * @example 10000048 - */ - id?: number; - /** @example homepage */ - name: string; + PagedModelTaskModel: { + _embedded?: { + tasks?: components["schemas"]["TaskModel"][]; + }; + page?: components["schemas"]["PageMetadata"]; }; - CollectionModelBatchJobModel: { + PagedModelTaskWithProjectModel: { _embedded?: { - batchJobs?: components["schemas"]["BatchJobModel"][]; + tasks?: components["schemas"]["TaskWithProjectModel"][]; }; + page?: components["schemas"]["PageMetadata"]; }; PagedModelTranslationCommentModel: { _embedded?: { @@ -2242,333 +2305,2955 @@ export interface components { }; page?: components["schemas"]["PageMetadata"]; }; - TranslationHistoryModel: { - /** @description Modified fields */ - modifications?: { - [key: string]: components["schemas"]["PropertyModification"]; + PagedModelTranslationMemoryItemModel: { + _embedded?: { + translationMemoryItems?: components["schemas"]["TranslationMemoryItemModel"][]; + }; + page?: components["schemas"]["PageMetadata"]; + }; + PagedModelTranslationSuggestionModel: { + _embedded?: { + suggestions?: components["schemas"]["TranslationSuggestionModel"][]; + }; + page?: components["schemas"]["PageMetadata"]; + }; + PagedModelWithNextCursorNotificationModel: { + _embedded?: { + notificationModelList?: components["schemas"]["NotificationModel"][]; }; /** - * Format: int64 - * @description Unix timestamp of the revision + * @description Cursor to get next data + * @example eyJrZXlJZCI6eyJkaXJlY3Rpb24iOiJBU0MiLCJ2YWx1ZSI6IjEwMDAwMDAxMjAifX0= */ - timestamp: number; - author?: components["schemas"]["SimpleUserAccountModel"]; - /** @enum {string} */ - revisionType: "ADD" | "MOD" | "DEL"; - }; - SelectAllResponse: { - ids: number[]; + nextCursor?: string; + page?: components["schemas"]["PageMetadata"]; + pagedModel?: components["schemas"]["PagedModelNotificationModel"]; }; - /** @description Tasks related to this key */ - KeyTaskViewModel: { + PatWithUserModel: { /** Format: int64 */ - number: number; + createdAt: number; + description: string; /** Format: int64 */ - languageId: number; - languageTag: string; - done: boolean; - userAssigned: boolean; - /** @enum {string} */ - type: "TRANSLATE" | "REVIEW"; + expiresAt?: number; + /** Format: int64 */ + id: number; + /** Format: int64 */ + lastUsedAt?: number; + /** Format: int64 */ + updatedAt: number; + user: components["schemas"]["SimpleUserAccountModel"]; }; - KeyWithTranslationsModel: { - /** - * Format: int64 - * @description Id of key record - */ - keyId: number; - /** - * @description Name of key - * @example this_is_super_key - */ - keyName: string; + PermissionModel: { /** - * @description Is this key a plural? - * @example true + * @deprecated + * @description Deprecated (use translateLanguageIds). + * + * List of languages current user has TRANSLATE permission to. If null, all languages edition is permitted. + * @example [ + * 200001, + * 200004 + * ] */ - keyIsPlural: boolean; + permittedLanguageIds?: number[]; /** - * @description The placeholder name for plural parameter - * @example value + * @description Granted scopes to the user. When user has type permissions, this field contains permission scopes of the type. + * @example [ + * "KEYS_EDIT", + * "TRANSLATIONS_VIEW" + * ] */ - keyPluralArgName?: string; + scopes: ("translations.view" | "translations.edit" | "translations.suggest" | "keys.edit" | "screenshots.upload" | "screenshots.delete" | "screenshots.view" | "activity.view" | "languages.edit" | "admin" | "project.edit" | "members.view" | "members.edit" | "translation-comments.add" | "translation-comments.edit" | "translation-comments.set-state" | "translations.state-edit" | "keys.view" | "keys.delete" | "keys.create" | "batch-jobs.view" | "batch-jobs.cancel" | "translations.batch-by-tm" | "translations.batch-machine" | "content-delivery.manage" | "content-delivery.publish" | "webhooks.manage" | "tasks.view" | "tasks.edit" | "prompts.view" | "prompts.edit" | "translation-labels.manage" | "translation-labels.assign")[]; /** - * Format: int64 - * @description The namespace id of the key - * @example 100000282 + * @description List of languages user can change state to. If null, changing state of all language values is permitted. + * @example [ + * 200001, + * 200004 + * ] */ - keyNamespaceId?: number; + stateChangeLanguageIds?: number[]; /** - * @description The namespace of the key - * @example homepage + * @description List of languages user can suggest to. If null, suggesting to all languages is permitted. + * @example [ + * 200001, + * 200004 + * ] */ - keyNamespace?: string; + suggestLanguageIds?: number[]; /** - * @description The namespace of the key - * @example homepage + * @description List of languages user can translate to. If null, all languages editing is permitted. + * @example [ + * 200001, + * 200004 + * ] */ - keyDescription?: string; - /** @description Tags of key */ - keyTags: components["schemas"]["TagModel"][]; + translateLanguageIds?: number[]; /** - * Format: int64 - * @description Count of screenshots provided for the key - * @example 1 + * @description The user's permission type. This field is null if uses granular permissions + * @enum {string} */ - screenshotCount: number; - /** @description Key screenshots. Not provided when API key hasn't screenshots.view scope permission. */ - screenshots?: components["schemas"]["ScreenshotModel"][]; - /** @description There is a context available for this key */ - contextPresent: boolean; + type?: "NONE" | "VIEW" | "TRANSLATE" | "REVIEW" | "EDIT" | "MANAGE"; /** - * @description Translations object - * @example - * { - * "en": { - * "id": 100000003, - * "text": "This is super translation!" - * "state": "TRANSLATED", - * "commentCount": 1 - * } - * } + * @description List of languages user can view. If null, all languages view is permitted. + * @example [ + * 200001, + * 200004 + * ] */ - translations: { - [key: string]: components["schemas"]["TranslationViewModel"]; - }; - /** @description Tasks related to this key */ - tasks?: components["schemas"]["KeyTaskViewModel"][]; + viewLanguageIds?: number[]; }; - KeysWithTranslationsPageModel: { - _embedded?: { - keys?: components["schemas"]["KeyWithTranslationsModel"][]; + PreTranslationByTmRequest: { + keyIds: number[]; + targetLanguageIds: number[]; + }; + PrivateUserAccountModel: { + /** @enum {string} */ + accountType: "LOCAL" | "MANAGED" | "THIRD_PARTY"; + avatar?: components["schemas"]["Avatar"]; + deletable: boolean; + domain?: string; + emailAwaitingVerification?: string; + /** @enum {string} */ + globalServerRole: "USER" | "ADMIN"; + /** Format: int64 */ + id: number; + mfaEnabled: boolean; + name?: string; + needsSuperJwtToken: boolean; + /** @enum {string} */ + thirdPartyAuthType?: "GOOGLE" | "GITHUB" | "OAUTH2" | "SSO" | "SSO_GLOBAL"; + username: string; + }; + ProjectActivityAuthorModel: { + avatar?: components["schemas"]["Avatar"]; + deleted: boolean; + /** Format: int64 */ + id: number; + name?: string; + username?: string; + }; + ProjectActivityModel: { + author?: components["schemas"]["ProjectActivityAuthorModel"]; + counts?: { + [key: string]: number; }; - page?: components["schemas"]["PageMetadata"]; - /** @description Provided languages data */ - selectedLanguages: components["schemas"]["LanguageModel"][]; - /** - * @description Cursor to get next data - * @example eyJrZXlJZCI6eyJkaXJlY3Rpb24iOiJBU0MiLCJ2YWx1ZSI6IjEwMDAwMDAxMjAifX0= - */ - nextCursor?: string; + meta?: { + [key: string]: Record; + }; + modifiedEntities?: { + [key: string]: components["schemas"]["ModifiedEntityModel"][]; + }; + params?: Record; + /** Format: int64 */ + revisionId: number; + /** Format: int64 */ + timestamp: number; + /** @enum {string} */ + type: "UNKNOWN" | "SET_TRANSLATION_STATE" | "SET_TRANSLATIONS" | "DISMISS_AUTO_TRANSLATED_STATE" | "SET_OUTDATED_FLAG" | "TRANSLATION_COMMENT_ADD" | "TRANSLATION_COMMENT_DELETE" | "TRANSLATION_COMMENT_EDIT" | "TRANSLATION_COMMENT_SET_STATE" | "SCREENSHOT_DELETE" | "SCREENSHOT_ADD" | "KEY_TAGS_EDIT" | "KEY_NAME_EDIT" | "KEY_DELETE" | "CREATE_KEY" | "COMPLEX_EDIT" | "IMPORT" | "CREATE_LANGUAGE" | "EDIT_LANGUAGE" | "DELETE_LANGUAGE" | "HARD_DELETE_LANGUAGE" | "CREATE_PROJECT" | "EDIT_PROJECT" | "NAMESPACE_EDIT" | "BATCH_PRE_TRANSLATE_BY_TM" | "BATCH_MACHINE_TRANSLATE" | "AUTO_TRANSLATE" | "BATCH_CLEAR_TRANSLATIONS" | "BATCH_COPY_TRANSLATIONS" | "BATCH_SET_TRANSLATION_STATE" | "BATCH_TAG_KEYS" | "BATCH_UNTAG_KEYS" | "BATCH_SET_KEYS_NAMESPACE" | "BATCH_ASSIGN_TRANSLATION_LABEL" | "BATCH_UNASSIGN_TRANSLATION_LABEL" | "AUTOMATION" | "CONTENT_DELIVERY_CONFIG_CREATE" | "CONTENT_DELIVERY_CONFIG_UPDATE" | "CONTENT_DELIVERY_CONFIG_DELETE" | "CONTENT_STORAGE_CREATE" | "CONTENT_STORAGE_UPDATE" | "CONTENT_STORAGE_DELETE" | "WEBHOOK_CONFIG_CREATE" | "WEBHOOK_CONFIG_UPDATE" | "WEBHOOK_CONFIG_DELETE" | "COMPLEX_TAG_OPERATION" | "TASKS_CREATE" | "TASK_CREATE" | "TASK_UPDATE" | "TASK_KEYS_UPDATE" | "TASK_FINISH" | "TASK_CLOSE" | "TASK_REOPEN" | "TASK_KEY_UPDATE" | "ORDER_TRANSLATION" | "GLOSSARY_CREATE" | "GLOSSARY_UPDATE" | "GLOSSARY_DELETE" | "GLOSSARY_TERM_CREATE" | "GLOSSARY_TERM_UPDATE" | "GLOSSARY_TERM_DELETE" | "GLOSSARY_TERM_TRANSLATION_UPDATE" | "TRANSLATION_LABELS_EDIT" | "TRANSLATION_LABEL_ASSIGN" | "TRANSLATION_LABEL_CREATE" | "TRANSLATION_LABEL_UPDATE" | "TRANSLATION_LABEL_DELETE" | "CREATE_SUGGESTION" | "DECLINE_SUGGESTION" | "ACCEPT_SUGGESTION" | "REVERSE_SUGGESTION" | "DELETE_SUGGESTION"; }; - /** - * @description Translations object - * @example - * { - * "en": { - * "id": 100000003, - * "text": "This is super translation!" - * "state": "TRANSLATED", - * "commentCount": 1 - * } - * } - */ - TranslationViewModel: { - /** - * Format: int64 - * @description Id of translation record - */ + ProjectModel: { + avatar?: components["schemas"]["Avatar"]; + baseLanguage?: components["schemas"]["LanguageModel"]; + computedPermission: components["schemas"]["ComputedPermissionModel"]; + defaultNamespace?: components["schemas"]["NamespaceModel"]; + description?: string; + directPermission?: components["schemas"]["PermissionModel"]; + /** @description Whether to disable ICU placeholder visualization in the editor and it's support. */ + icuPlaceholders: boolean; + /** Format: int64 */ id: number; - /** @description Translation text */ - text?: string; + name: string; + organizationOwner?: components["schemas"]["SimpleOrganizationModel"]; + /** @enum {string} */ + organizationRole?: "MEMBER" | "OWNER" | "MAINTAINER"; + slug?: string; /** - * @description State of translation + * @description Suggestions for translations * @enum {string} */ - state: "UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED"; - /** @description Whether base language translation was changed after this translation was updated */ - outdated: boolean; - /** @description Was translated using Translation Memory or Machine translation service? */ - auto: boolean; + suggestionsMode: "DISABLED" | "ENABLED"; /** - * @description Which machine translation service was used to auto translate this + * @description Level of protection of translations * @enum {string} */ - mtProvider?: "GOOGLE" | "AWS" | "DEEPL" | "AZURE" | "BAIDU" | "TOLGEE"; - /** - * Format: int64 - * @description Count of translation comments - */ - commentCount: number; - /** - * Format: int64 - * @description Count of unresolved translation comments - */ - unresolvedCommentCount: number; - /** @description Was translation memory used to translate this? */ - fromTranslationMemory: boolean; + translationProtection: "NONE" | "PROTECT_REVIEWED"; + useNamespaces: boolean; }; - LanguageStatsModel: { - /** Format: int64 */ - languageId?: number; - languageTag?: string; - languageName?: string; - languageOriginalName?: string; - languageFlagEmoji?: string; + ProjectStatsModel: { /** Format: int64 */ - translatedKeyCount: number; + baseWordsCount: number; /** Format: int64 */ - translatedWordCount: number; - /** Format: double */ - translatedPercentage: number; + keyCount: number; + /** Format: int32 */ + languageCount: number; + languageStats: components["schemas"]["LanguageStatsModel"][]; /** Format: int64 */ - reviewedKeyCount: number; + membersCount: number; /** Format: int64 */ - reviewedWordCount: number; + projectId: number; /** Format: double */ reviewedPercentage: number; /** Format: int64 */ - untranslatedKeyCount: number; - /** Format: int64 */ - untranslatedWordCount: number; - /** Format: double */ - untranslatedPercentage: number; - }; - ProjectStatsModel: { - /** Format: int64 */ - projectId: number; - /** Format: int32 */ - languageCount: number; - /** Format: int64 */ - keyCount: number; + tagCount: number; /** Format: int64 */ taskCount: number; - /** Format: int64 */ - baseWordsCount: number; /** Format: double */ translatedPercentage: number; - /** Format: double */ - reviewedPercentage: number; - /** Format: int64 */ - membersCount: number; - /** Format: int64 */ - tagCount: number; - languageStats: components["schemas"]["LanguageStatsModel"][]; }; - PagedModelLanguageModel: { - _embedded?: { - languages?: components["schemas"]["LanguageModel"][]; - }; - page?: components["schemas"]["PageMetadata"]; + PromptDto: { + basicPromptOptions?: ("KEY_NAME" | "KEY_DESCRIPTION" | "KEY_CONTEXT" | "PROJECT_DESCRIPTION" | "LANGUAGE_NOTES" | "TM_SUGGESTIONS" | "SCREENSHOT" | "GLOSSARY")[]; + name: string; + providerName: string; + template?: string; }; - CollectionModelScreenshotModel: { - _embedded?: { - screenshots?: components["schemas"]["ScreenshotModel"][]; - }; + /** @description Modified fields */ + PropertyModification: { + new?: Record; + old?: Record; }; - PatWithUserModel: { - user: components["schemas"]["SimpleUserAccountModel"]; - description: string; + PublicSsoTenantModel: { + domain: string; + force: boolean; + global: boolean; + }; + /** @description Keys in the document used as a context for machine translation. Keys in the same order as they appear in the document. The order is important! We are using it for graph distance calculation. */ + RelatedKeyDto: { + keyName: string; + namespace?: string; + }; + ScreenshotInfoDto: { + location?: string; + positions?: components["schemas"]["KeyInScreenshotPositionDto"][]; + text?: string; + }; + /** @description Screenshots of the key */ + ScreenshotModel: { + /** Format: date-time */ + createdAt?: string; + fileUrl: string; + /** + * @description File name, which may be downloaded from the screenshot path. + * + * When images are secured. Encrypted timestamp is appended to the filename. + */ + filename: string; + /** Format: int32 */ + height?: number; /** Format: int64 */ id: number; - /** Format: int64 */ - expiresAt?: number; - /** Format: int64 */ - lastUsedAt?: number; - /** Format: int64 */ - createdAt: number; - /** Format: int64 */ - updatedAt: number; + keyReferences: components["schemas"]["KeyInScreenshotModel"][]; + location?: string; + middleSized?: string; + middleSizedUrl?: string; + /** + * @description Thumbnail file name, which may be downloaded from the screenshot path. + * + * When images are secured. Encrypted timestamp is appended to the filename. + */ + thumbnail: string; + thumbnailUrl: string; + /** Format: int32 */ + width?: number; }; - PagedModelOrganizationModel: { - _embedded?: { - organizations?: components["schemas"]["OrganizationModel"][]; + SelectAllResponse: { + ids: number[]; + }; + SetDisabledLanguagesRequest: { + languageIds: number[]; + }; + SetFileNamespaceRequest: { + namespace?: string; + }; + SetKeysNamespaceRequest: { + keyIds: number[]; + namespace?: string; + }; + SetTranslationsResponseModel: { + /** + * Format: int64 + * @description Id of key record + */ + keyId: number; + keyIsPlural: boolean; + /** + * @description Name of key + * @example this_is_super_key + */ + keyName: string; + /** + * @description The namespace of the key + * @example homepage + */ + keyNamespace?: string; + /** + * @description Translations object containing values updated in this request + * @example { + * "en": { + * "id": 100000003, + * "text": "This is super translation!" + * } + * } + */ + translations: { + [key: string]: components["schemas"]["TranslationModel"]; }; - page?: components["schemas"]["PageMetadata"]; }; - ApiKeyWithLanguagesModel: { + SetTranslationsStateStateRequest: { + keyIds: number[]; + languageIds: number[]; + /** @enum {string} */ + state: "UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED"; + }; + SetTranslationsWithKeyDto: { /** - * @deprecated - * @description Languages for which user has translate permission. + * @description Key name to set translations for + * @example what_a_key_to_translate */ - permittedLanguageIds?: number[]; + key: string; + /** + * @description List of languages to return translations for. + * + * If not provided, only modified translation will be provided. + * + * @example [ + * "en", + * "de", + * "fr" + * ] + */ + languagesToReturn?: string[]; + /** @description The namespace of the key. (When empty or null default namespace will be used) */ + namespace?: string; + /** + * @description Object mapping language tag to translation + * @example { + * "en": "What a translated value!", + * "cs": "Jaká to přeložená hodnota!" + * } + */ + translations: { + [key: string]: string; + }; + }; + SimpleGlossaryModel: { + /** + * @description Language tag for default translations for terms + * @example en + */ + baseLanguageTag: string; + /** Format: int64 */ + id: number; + name: string; + }; + SimpleGlossaryTermModel: { description: string; + /** @description Specifies whether the term represents a shortened form of a word or phrase */ + flagAbbreviation: boolean; + /** @description When true, the term matching considers uppercase and lowercase characters as distinct */ + flagCaseSensitive: boolean; + /** @description When true, marks this term as prohibited or not recommended for use in translations */ + flagForbiddenTerm: boolean; + /** @description When true, this term has the same translation across all target languages */ + flagNonTranslatable: boolean; /** Format: int64 */ id: number; - userFullName?: string; - projectName: string; - username?: string; - scopes: string[]; + }; + SimpleGlossaryTermWithTranslationsModel: { + /** + * @description A detailed explanation or definition of the glossary term + * @example It's trademark + */ + description: string; + /** @description Specifies whether the term represents a shortened form of a word or phrase */ + flagAbbreviation: boolean; + /** @description When true, the term matching considers uppercase and lowercase characters as distinct */ + flagCaseSensitive: boolean; + /** @description When true, marks this term as prohibited or not recommended for use in translations */ + flagForbiddenTerm: boolean; + /** @description When true, this term has the same translation across all target languages */ + flagNonTranslatable: boolean; /** Format: int64 */ - expiresAt?: number; + id: number; + translations: components["schemas"]["GlossaryTermTranslationModel"][]; + }; + SimpleGlossaryWithStatsModel: { + /** + * Format: int64 + * @description Total number of projects currently using this glossary + * @example 69 + */ + assignedProjectsCount: number; + /** + * @description The primary language code used for terms (e.g., 'en' for English) + * @example en + */ + baseLanguageTag: string; + /** + * @description The name of one project using this glossary (can be shown as a preview) + * @example My Project + */ + firstAssignedProjectName?: string; /** Format: int64 */ - projectId: number; + id: number; + name: string; + }; + SimpleImportConflictResult: { + isOverridable: boolean; + keyName: string; + keyNamespace?: string; + language: string; + }; + SimpleOrganizationModel: { + avatar?: components["schemas"]["Avatar"]; + basePermissions: components["schemas"]["PermissionModel"]; + /** @example This is a beautiful organization full of beautiful and clever people */ + description?: string; /** Format: int64 */ - lastUsedAt?: number; + id: number; + /** @example Beautiful organization */ + name: string; + /** @example btforg */ + slug: string; + }; + SimpleProjectModel: { + avatar?: components["schemas"]["Avatar"]; + baseLanguage?: components["schemas"]["LanguageModel"]; + description?: string; + icuPlaceholders: boolean; + /** Format: int64 */ + id: number; + name: string; + slug?: string; + }; + /** @description User who created the comment */ + SimpleUserAccountModel: { + avatar?: components["schemas"]["Avatar"]; + deleted: boolean; + /** Format: int64 */ + id: number; + name?: string; + username: string; + }; + SingleStepImportRequest: { + /** @description If true, placeholders from other formats will be converted to ICU when possible */ + convertPlaceholdersToIcu: boolean; + /** @description If false, only updates keys, skipping the creation of new keys */ + createNewKeys: boolean; + /** + * @description If `false`, import will apply all `non-failed` overrides and reports `unresolvedConflict` + * .If `true`, import will fail completely on unresolved conflict and won't apply any changes. Unresolved conflicts are reported in the `params` of the error response + */ + errorOnUnresolvedConflict?: boolean; + /** @description Definition of mapping for each file to import. */ + fileMappings: components["schemas"]["ImportFileMapping"][]; + /** + * @description Whether to override existing translation data. + * + * When set to `KEEP`, existing translations will be kept. + * When set to `NO_FORCE`, error will be thrown on conflict. + * When set to `OVERRIDE`, existing translations will be overwritten + * @enum {string} + */ + forceMode: "OVERRIDE" | "KEEP" | "NO_FORCE"; + /** + * @description Maps the languages from imported files to languages existing in the Tolgee platform. + * + * Use this field only when your files contain multiple languages (e.g., XLIFF files). + * + * Otherwise, use the `languageTag` property of `fileMappings`. + * + * Example: In xliff files, there are `source-language` and `target-language` attributes defined on `file` element. Using this field you can map source and target values to languages stored in the Tolgee Platform. + */ + languageMappings?: components["schemas"]["LanguageMapping"][]; + /** @description If true, key descriptions will be overridden by the import */ + overrideKeyDescriptions: boolean; + /** + * @description Some translations are forbidden or protected: + * + * When set to `RECOMMENDED` it will fail for DISABLED translations and protected REVIEWED translations. + * When set to `ALL` it will fail for DISABLED translations, but will try to update protected REVIEWED translations (fails only if user has no permission) + * + * @enum {string} + */ + overrideMode?: "RECOMMENDED" | "ALL"; + /** @description If yes, keys from project that were not included in import will be deleted (only within namespaces which are included in the import). */ + removeOtherKeys?: boolean; + /** + * @description When importing files in structured formats (e.g., JSON, YAML), this field defines the delimiter which will be used in names of imported keys. + * @example . + */ + structureDelimiter?: string; + /** @description Keys created by this import will be tagged with these tags. It add tags only to new keys. The keys that already exist will not be tagged. */ + tagNewKeys: string[]; + }; + /** @description List of keys to import */ + SingleStepImportResolvableItemRequest: { + /** + * @description Key name to set translations for + * @example what_a_key_to_translate + */ + name: string; + /** @description The namespace of the key. (When empty or null default namespace will be used) */ + namespace?: string; + screenshots?: components["schemas"]["KeyScreenshotDto"][]; + /** @description Object mapping language tag to translation */ + translations: { + [key: string]: components["schemas"]["SingleStepImportResolvableTranslationRequest"]; + }; + }; + SingleStepImportResolvableRequest: { + /** + * @description If `false`, import will apply all `non-failed` overrides and reports `unresolvedConflict` + * .If `true`, import will fail completely on unresolved conflict and won't apply any changes. Unresolved conflicts are reported in the `params` of the error response + */ + errorOnUnresolvedConflict?: boolean; + /** @description List of keys to import */ + keys: components["schemas"]["SingleStepImportResolvableItemRequest"][]; + /** + * @description Some translations are forbidden or protected: + * + * When set to `RECOMMENDED` it will fail for DISABLED translations and protected REVIEWED translations. + * When set to `ALL` it will fail for DISABLED translations, but will try to update protected REVIEWED translations (fails only if user has no permission) + * + * @enum {string} + */ + overrideMode?: "RECOMMENDED" | "ALL"; + }; + /** @description Object mapping language tag to translation */ + SingleStepImportResolvableTranslationRequest: { + /** + * @description + * To ensure the import doesn't override something that should not be (in case data have changed unexpectedly), + * you can specify what do you "expect": + * - EXPECT_NO_CONFLICT: There should be no conflict, if there is, import fails + * - OVERRIDE: New translation is applied over the existing in every case (Default) + * + * @example OVERRIDE + * @enum {string} + */ + resolution?: "EXPECT_NO_CONFLICT" | "OVERRIDE"; + /** + * @description Translation text + * @example Hello! I am a translation! + */ + text: string; + }; + StreamingResponseBody: Record; + SuggestRequestDto: { + /** @description Text value of base translation. Useful, when base translation is not stored yet. */ + baseText?: string; + /** @description Whether base text is plural. This value is ignored if baseText is null. */ + isPlural?: boolean; + /** + * Format: int64 + * @description Key Id to get results for. Use when key is stored already. + */ + keyId?: number; + plural?: boolean; + /** @description List of services to use. If null, then all enabled services are used. */ + services?: ("GOOGLE" | "AWS" | "DEEPL" | "AZURE" | "BAIDU" | "PROMPT")[]; + /** Format: int64 */ + targetLanguageId: number; + }; + SuggestResultModel: { + /** @description If true, the base translation was empty and no translation was provided. */ + baseBlank: boolean; + /** + * @deprecated + * @description String translations provided by enabled services. (deprecated, use `result` instead) + * @example + * { + * "GOOGLE": "This was translated by Google", + * "TOLGEE": "This was translated by Tolgee Translator", + * } + */ + machineTranslations?: { + [key: string]: string; + }; + /** + * @description Results provided by enabled services. + * @example { + * "GOOGLE": { + * "output": "This was translated by Google", + * "contextDescription": null + * }, + * "TOLGEE": { + * "output": "This was translated by Tolgee Translator", + * "contextDescription": "This is an example in swagger" + * } + * } + */ + result?: { + [key: string]: components["schemas"]["TranslationItemModel"]; + }; + }; + TagKeyDto: { + name: string; + }; + TagKeysRequest: { + keyIds: number[]; + tags: string[]; + }; + TagModel: { + /** Format: int64 */ + id: number; + name: string; + }; + TaskKeysResponse: { + keys: number[]; + }; + TaskModel: { + agency?: components["schemas"]["TranslationAgencySimpleModel"]; + assignees: components["schemas"]["SimpleUserAccountModel"][]; + author?: components["schemas"]["SimpleUserAccountModel"]; + /** Format: int64 */ + baseCharacterCount: number; + /** Format: int64 */ + baseWordCount: number; + /** Format: int64 */ + closedAt?: number; + /** Format: int64 */ + createdAt?: number; + description: string; + /** Format: int64 */ + doneItems: number; + /** Format: int64 */ + dueDate?: number; + language: components["schemas"]["LanguageModel"]; + name?: string; + /** Format: int64 */ + number: number; + /** @enum {string} */ + state: "NEW" | "IN_PROGRESS" | "FINISHED" | "CANCELED"; + /** Format: int64 */ + totalItems: number; + /** @enum {string} */ + type: "TRANSLATE" | "REVIEW"; + }; + TaskPerUserReportModel: { + /** Format: int64 */ + baseCharacterCount: number; + /** Format: int64 */ + baseWordCount: number; + /** Format: int64 */ + doneItems: number; + user: components["schemas"]["SimpleUserAccountModel"]; + }; + TaskWithProjectModel: { + agency?: components["schemas"]["TranslationAgencySimpleModel"]; + assignees: components["schemas"]["SimpleUserAccountModel"][]; + author?: components["schemas"]["SimpleUserAccountModel"]; + /** Format: int64 */ + baseCharacterCount: number; + /** Format: int64 */ + baseWordCount: number; + /** Format: int64 */ + closedAt?: number; + /** Format: int64 */ + createdAt?: number; + description: string; + /** Format: int64 */ + doneItems: number; + /** Format: int64 */ + dueDate?: number; + language: components["schemas"]["LanguageModel"]; + name?: string; + /** Format: int64 */ + number: number; + project: components["schemas"]["SimpleProjectModel"]; + /** @enum {string} */ + state: "NEW" | "IN_PROGRESS" | "FINISHED" | "CANCELED"; + /** Format: int64 */ + totalItems: number; + /** @enum {string} */ + type: "TRANSLATE" | "REVIEW"; + }; + TranslationAgencySimpleModel: { + avatar?: components["schemas"]["Avatar"]; + /** Format: int64 */ + id: number; + name: string; + url?: string; + }; + TranslationCommentDto: { + /** @enum {string} */ + state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; + text: string; + }; + TranslationCommentModel: { + author: components["schemas"]["SimpleUserAccountModel"]; + /** + * Format: date-time + * @description Date when it was created + */ + createdAt: string; + /** + * Format: int64 + * @description Id of translation comment record + */ + id: number; + /** + * @description State of translation + * @enum {string} + */ + state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; + /** @description Text of comment */ + text: string; + /** + * Format: date-time + * @description Date when it was updated + */ + updatedAt: string; + }; + TranslationCommentWithLangKeyDto: { + /** Format: int64 */ + keyId: number; + /** Format: int64 */ + languageId: number; + /** @enum {string} */ + state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; + text: string; + }; + TranslationHistoryModel: { + author?: components["schemas"]["SimpleUserAccountModel"]; + /** @description Modified fields */ + modifications?: { + [key: string]: components["schemas"]["PropertyModification"]; + }; + /** @enum {string} */ + revisionType: "ADD" | "MOD" | "DEL"; + /** + * Format: int64 + * @description Unix timestamp of the revision + */ + timestamp: number; + }; + /** + * @description Results provided by enabled services. + * @example { + * "GOOGLE": { + * "output": "This was translated by Google", + * "contextDescription": null + * }, + * "TOLGEE": { + * "output": "This was translated by Tolgee Translator", + * "contextDescription": "This is an example in swagger" + * } + * } + */ + TranslationItemModel: { + contextDescription?: string; + output: string; + }; + TranslationLabelRequest: { + /** Format: int64 */ + keyId: number; + /** Format: int64 */ + labelId: number; + /** Format: int64 */ + languageId: number; + }; + TranslationMemoryItemModel: { + baseText: string; + keyName: string; + /** Format: float */ + similarity: number; + targetText: string; + }; + TranslationModel: { + /** @description Was translated using Translation Memory or Machine translation service? */ + auto: boolean; + /** + * Format: int64 + * @description Id of translation record + */ + id: number; + /** + * @description Which machine translation service was used to auto translate this + * @enum {string} + */ + mtProvider?: "GOOGLE" | "AWS" | "DEEPL" | "AZURE" | "BAIDU" | "PROMPT"; + /** @description Whether base language translation was changed after this translation was updated */ + outdated: boolean; + /** + * @description State of translation + * @enum {string} + */ + state: "UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED"; + /** @description Translation text */ + text?: string; + }; + TranslationSuggestionAcceptResponse: { + accepted: components["schemas"]["TranslationSuggestionModel"]; + declined: number[]; + }; + TranslationSuggestionModel: { + author: components["schemas"]["SimpleUserAccountModel"]; + /** Format: date-time */ + createdAt: string; + /** Format: int64 */ + id: number; + isPlural: boolean; + /** Format: int64 */ + keyId: number; + /** Format: int64 */ + languageId: number; + /** @enum {string} */ + state: "ACTIVE" | "ACCEPTED" | "DECLINED"; + translation?: string; + /** Format: date-time */ + updatedAt: string; + }; + /** @description First suggestion */ + TranslationSuggestionSimpleModel: { + author: components["schemas"]["SimpleUserAccountModel"]; + /** Format: int64 */ + id: number; + isPlural: boolean; + /** @enum {string} */ + state: "ACTIVE" | "ACCEPTED" | "DECLINED"; + translation?: string; + }; + /** + * @description Translations object + * @example + * { + * "en": { + * "id": 100000003, + * "text": "This is super translation!" + * "state": "TRANSLATED", + * "commentCount": 1 + * } + * } + */ + TranslationViewModel: { + /** + * Format: int64 + * @description Number of active suggestions + */ + activeSuggestionCount: number; + /** @description Was translated using Translation Memory or Machine translation service? */ + auto: boolean; + /** + * Format: int64 + * @description Count of translation comments + */ + commentCount: number; + /** @description Was translation memory used to translate this? */ + fromTranslationMemory: boolean; + /** + * Format: int64 + * @description Id of translation record + */ + id?: number; + /** @description Labels assigned to this translation */ + labels?: components["schemas"]["LabelModel"][]; + /** + * @description Which machine translation service was used to auto translate this + * @enum {string} + */ + mtProvider?: "GOOGLE" | "AWS" | "DEEPL" | "AZURE" | "BAIDU" | "PROMPT"; + /** @description Whether base language translation was changed after this translation was updated */ + outdated: boolean; + /** + * @description State of translation + * @enum {string} + */ + state: "UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED"; + /** @description First suggestion */ + suggestions?: components["schemas"]["TranslationSuggestionSimpleModel"][]; + /** @description Translation text */ + text?: string; + /** + * Format: int64 + * @description Number of all suggestions + */ + totalSuggestionCount: number; + /** + * Format: int64 + * @description Count of unresolved translation comments + */ + unresolvedCommentCount: number; + }; + TranslationWithCommentModel: { + comment: components["schemas"]["TranslationCommentModel"]; + translation: components["schemas"]["TranslationModel"]; + }; + UntagKeysRequest: { + keyIds: number[]; + tags: string[]; + }; + UpdateGlossaryRequest: { + /** @description Projects assigned to glossary; when null, assigned projects will be kept unchanged. */ + assignedProjectIds?: number[]; + /** + * @description Language tag according to BCP 47 definition + * @example cs-CZ + */ + baseLanguageTag: string; + /** + * @description Glossary name + * @example My glossary + */ + name: string; + }; + UpdateGlossaryTermTranslationRequest: { + /** + * @description Language tag according to BCP 47 definition + * @example cs-CZ + */ + languageTag: string; + /** + * @description Translation text + * @example Translated text to language of languageTag + */ + text: string; + }; + UpdateGlossaryTermWithTranslationRequest: { + description?: string; + /** @description Specifies whether the term represents a shortened form of a word or phrase */ + flagAbbreviation?: boolean; + /** @description When true, the term matching considers uppercase and lowercase characters as distinct */ + flagCaseSensitive?: boolean; + /** @description When true, marks this term as prohibited or not recommended for use in translations */ + flagForbiddenTerm?: boolean; + /** @description When true, this term will have the same translation across all target languages */ + flagNonTranslatable?: boolean; + text?: string; + }; + UpdateNamespaceDto: { + name: string; + }; + UpdateTaskKeyRequest: { + done: boolean; + }; + UpdateTaskKeyResponse: { + /** @description Task key is marked as done */ + done: boolean; + /** @description Task progress is 100% */ + taskFinished: boolean; + }; + UpdateTaskKeysRequest: { + /** @description Keys to add to task */ + addKeys?: number[]; + /** @description Keys to remove from task */ + removeKeys?: number[]; + }; + UpdateTaskRequest: { + assignees: number[]; + description: string; + /** + * Format: int64 + * @description Due to date in epoch format (milliseconds). + * @example 1661172869000 + */ + dueDate?: number; + name?: string; + }; + UploadedImageModel: { + /** Format: date-time */ + createdAt: string; + fileUrl: string; + filename: string; + /** Format: int64 */ + id: number; + location?: string; + requestFilename: string; + }; + UsedNamespaceModel: { + /** + * Format: int64 + * @description The id of namespace. Null for default namespace. + * @example 10000048 + */ + id?: number; + /** + * @description Name of namespace. Null if default. + * @example homepage + */ + name?: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} + +export type $defs = Record; + +export type external = Record; + +export interface operations { + + /** + * Export to ZIP of jsons + * @deprecated + * @description Exports data as ZIP of jsons + */ + doExportJsonZip_1: { + responses: { + /** @description OK */ + 200: { + content: { + "application/zip": components["schemas"]["StreamingResponseBody"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Get current API key info + * @description Returns info the API key which user currently authenticated with. Otherwise responds with 400 status code. + */ + getCurrent_1: { + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["ApiKeyWithLanguagesModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Get current permission info + * @description Returns current PAK or PAT permissions for current user, api-key and project + */ + getCurrentPermissions: { + parameters: { + query?: { + /** @description Required when using with PAT */ + projectId?: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["ApiKeyPermissionsModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get current third party authentication provider */ + getCurrentAuthProvider: { + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["AuthProviderDto"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Initiate provider change to remove current third party authentication provider */ + deleteCurrentAuthProvider: { + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get info about authentication provider which can replace the current one */ + getChangedAuthProvider: { + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["AuthProviderDto"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Accept change of the third party authentication provider */ + acceptChangeAuthProvider: { + requestBody: { + content: { + "application/json": components["schemas"]["AcceptAuthProviderChangeRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["JwtAuthenticationResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Reject change of the third party authentication provider */ + rejectChangeAuthProvider: { + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Upload an image for later use */ + upload: { + requestBody?: { + content: { + "multipart/form-data": { + /** Format: binary */ + image: string; + info?: components["schemas"]["ImageUploadInfoDto"]; + }; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + "*/*": components["schemas"]["UploadedImageModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Delete uploaded images */ + delete_14: { + parameters: { + path: { + ids: number[]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Gets notifications of the currently logged in user, newest is first. */ + getNotifications: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + /** + * @description Filter by the `seen` parameter. + * + * no value = request everything + * + * true = only seen + * + * false = only unseen + */ + filterSeen?: boolean; + cursor?: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelWithNextCursorNotificationModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Get notification settings + * @description Returns notification settings of the currently logged in user + */ + getNotificationsSettings: { + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["NotificationSettingModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Save notification setting + * @description Saves new value for given parameters + */ + putNotificationSetting: { + requestBody: { + content: { + "application/json": components["schemas"]["NotificationSettingsRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Marks notifications of the currently logged in user with given IDs as seen. */ + markNotificationsAsSeen: { + requestBody: { + content: { + "application/json": components["schemas"]["NotificationsMarkSeenRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Get all permitted organizations + * @description Returns all organizations, which is current user allowed to view + */ + getAll_12: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + filterCurrentUserOwner?: boolean; + search?: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelOrganizationModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Create organization */ + create_12: { + requestBody: { + content: { + "application/json": components["schemas"]["OrganizationDto"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["OrganizationModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get one organization */ + get_23: { + parameters: { + path: { + id: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["OrganizationModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get all organization glossaries */ + getAll_14: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; + }; + path: { + organizationId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelSimpleGlossaryModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Create glossary */ + create_13: { + parameters: { + path: { + organizationId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateGlossaryRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["GlossaryModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get all organization glossaries with some additional statistics */ + getAllWithStats: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; + }; + path: { + organizationId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelSimpleGlossaryWithStatsModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get glossary */ + get_20: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["GlossaryModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Update glossary */ + update_8: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateGlossaryRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["GlossaryModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Delete glossary */ + delete_11: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get all projects assigned to glossary */ + getAssignedProjects: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["CollectionModelSimpleProjectModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get all languages in use by the glossary */ + getLanguages: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["CollectionModelGlossaryLanguageDto"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get all glossary terms */ + getAll_15: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; + languageTags?: string[]; + }; + path: { + organizationId: number; + glossaryId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelSimpleGlossaryTermModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Create a new glossary term */ + create_14: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateGlossaryTermWithTranslationRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["CreateUpdateGlossaryTermResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Batch delete multiple terms */ + deleteMultiple: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DeleteMultipleGlossaryTermsRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get glossary term */ + get_21: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + termId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["GlossaryTermModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Update glossary term */ + update_9: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + termId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateGlossaryTermWithTranslationRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["CreateUpdateGlossaryTermResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Delete glossary term */ + delete_12: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + termId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Set a new glossary term translation for language */ + update_12: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + termId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateGlossaryTermTranslationRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["GlossaryTermTranslationModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get glossary term translation for language */ + get_22: { + parameters: { + path: { + organizationId: number; + glossaryId: number; + termId: number; + languageTag: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["GlossaryTermTranslationModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get all glossary terms ids */ + getAllIds: { + parameters: { + query?: { + search?: string; + languageTags?: string[]; + }; + path: { + organizationId: number; + glossaryId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["CollectionModelLong"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get all glossary terms with translations */ + getAllWithTranslations: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; + languageTags?: string[]; + }; + path: { + organizationId: number; + glossaryId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelSimpleGlossaryTermWithTranslationsModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Get credit balance for organization + * @description Returns machine translation credit balance for organization + */ + getOrganizationCredits: { + parameters: { + path: { + organizationId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["CreditBalanceModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get organization by slug */ + get_19: { + parameters: { + path: { + slug: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["OrganizationModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Return current PAK + * @description Returns current Personal Access Token. If the request is not authenticated with a Personal Access Token, it will return 400 response status. + */ + getCurrent: { + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PatWithUserModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Get all permitted + * @description Returns all projects where current user has any permission + */ + getAll: { + parameters: { + query?: { + /** @description Filter projects by id */ + filterId?: number[]; + /** @description Filter projects without id */ + filterNotId?: number[]; + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelProjectModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Create project + * @description Creates a new project with languages and initial settings. + */ + createProject: { + requestBody: { + content: { + "application/json": components["schemas"]["CreateProjectRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["ProjectModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get project activity */ + getActivity_1: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelProjectActivityModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get one revision data */ + getSingleRevision_1: { + parameters: { + path: { + revisionId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["ProjectActivityModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** List batch operations */ + list_1: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["PagedModelBatchJobModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Get batch operation */ + get_7: { + parameters: { + path: { + id: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["BatchJobModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Stop batch operation + * @description Stops batch operation if possible. + */ + cancel_1: { + parameters: { + path: { + id: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; }; - ApiKeyPermissionsModel: { - /** - * Format: int64 - * @description The API key's project id or the one provided as query param - */ - projectId: number; - /** - * @description List of languages user can view. If null, all languages view is permitted. - * @example [ - * 200001, - * 200004 - * ] - */ - viewLanguageIds?: number[]; - /** - * @description List of languages user can translate to. If null, all languages editing is permitted. - * @example [ - * 200001, - * 200004 - * ] - */ - translateLanguageIds?: number[]; - /** - * @description List of languages user can change state to. If null, changing state of all language values is permitted. - * @example [ - * 200001, - * 200004 - * ] - */ - stateChangeLanguageIds?: number[]; - /** - * @description Granted scopes to the user. When user has type permissions, this field contains permission scopes of the type. - * @example [ - * "KEYS_EDIT", - * "TRANSLATIONS_VIEW" - * ] - */ - scopes: ("translations.view" | "translations.edit" | "keys.edit" | "screenshots.upload" | "screenshots.delete" | "screenshots.view" | "activity.view" | "languages.edit" | "admin" | "project.edit" | "members.view" | "members.edit" | "translation-comments.add" | "translation-comments.edit" | "translation-comments.set-state" | "translations.state-edit" | "keys.view" | "keys.delete" | "keys.create" | "batch-jobs.view" | "batch-jobs.cancel" | "translations.batch-by-tm" | "translations.batch-machine" | "content-delivery.manage" | "content-delivery.publish" | "webhooks.manage" | "tasks.view" | "tasks.edit")[]; - /** - * @description The user's permission type. This field is null if user has assigned granular permissions or if returning API key's permissions - * @enum {string} - */ - type?: "NONE" | "VIEW" | "TRANSLATE" | "REVIEW" | "EDIT" | "MANAGE"; - project: components["schemas"]["SimpleProjectModel"]; + }; + /** + * Store Big Meta + * @description Stores a bigMeta for a project + */ + store_3: { + requestBody: { + content: { + "application/json": components["schemas"]["BigMetaDto"]; + }; }; - DeleteKeysDto: { - /** @description IDs of keys to delete */ - ids: number[]; + responses: { + /** @description OK */ + 200: { + content: never; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; }; }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; -} - -export type $defs = Record; - -export type external = Record; - -export interface operations { - /** - * Get user info - * @description Returns information about currently authenticated user. + * Get all running and pending batch operations + * @description Returns all running and pending batch operations. Completed batch operations are returned only if they are not older than 1 hour. If user doesn't have permission to view all batch operations, only their operations are returned. */ - getInfo_2: { + currentJobs_1: { responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PrivateUserAccountModel"]; + "application/json": components["schemas"]["CollectionModelBatchJobModel"]; }; }; /** @description Bad Request */ @@ -2597,18 +5282,100 @@ export interface operations { }; }; }; - /** Reopen task */ - reopenTask_1: { + /** Export data */ + exportData_1: { parameters: { - path: { - taskNumber: number; + query?: { + /** + * @description Languages to be contained in export. + * + * If null, all languages are exported + * @example en + */ + languages?: string[]; + /** @description Format to export to */ + format?: "JSON" | "JSON_TOLGEE" | "XLIFF" | "PO" | "APPLE_STRINGS_STRINGSDICT" | "APPLE_XLIFF" | "ANDROID_XML" | "COMPOSE_XML" | "FLUTTER_ARB" | "PROPERTIES" | "YAML_RUBY" | "YAML" | "JSON_I18NEXT" | "CSV" | "RESX_ICU" | "XLSX" | "APPLE_XCSTRINGS"; + /** + * @description Delimiter to structure file content. + * + * e.g. For key "home.header.title" would result in {"home": {"header": "title": {"Hello"}}} structure. + * + * When null, resulting file won't be structured. Works only for generic structured formats (e.g. JSON, YAML), + * specific formats like `YAML_RUBY` don't honor this parameter. + */ + structureDelimiter?: string; + /** @description Filter key IDs to be contained in export */ + filterKeyId?: number[]; + /** @description Filter key IDs not to be contained in export */ + filterKeyIdNot?: number[]; + /** + * @description Filter keys tagged by. + * + * This filter works the same as `filterTagIn` but in this cases it accepts single tag only. + */ + filterTag?: string; + /** @description Filter keys tagged by one of provided tags */ + filterTagIn?: string[]; + /** @description Filter keys not tagged by one of provided tags */ + filterTagNotIn?: string[]; + /** @description Filter keys with prefix */ + filterKeyPrefix?: string; + /** @description Filter translations with state. By default, all states except untranslated is exported. */ + filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; + /** @description Filter translations with namespace. By default, all namespaces everything are exported. To export default namespace, use empty string. */ + filterNamespace?: string[]; + /** + * @description If false, it doesn't return zip of files, but it returns single file. + * + * This is possible only when single language is exported. Otherwise it returns "400 - Bad Request" response. + */ + zip?: boolean; + /** + * @description Message format to be used for export. + * + * e.g. PHP_PO: Hello %s, ICU: Hello {name}. + * + * This property is honored only for generic formats like JSON or YAML. + * For specific formats like `YAML_RUBY` it's ignored. + */ + messageFormat?: "C_SPRINTF" | "PHP_SPRINTF" | "JAVA_STRING_FORMAT" | "APPLE_SPRINTF" | "RUBY_SPRINTF" | "I18NEXT" | "ICU" | "PYTHON_PERCENT"; + /** + * @description This is a template that defines the structure of the resulting .zip file content. + * + * The template is a string that can contain the following placeholders: {namespace}, {languageTag}, + * {androidLanguageTag}, {snakeLanguageTag}, {extension}. + * + * For example, when exporting to JSON with the template `{namespace}/{languageTag}.{extension}`, + * the English translations of the `home` namespace will be stored in `home/en.json`. + * + * The `{snakeLanguageTag}` placeholder is the same as `{languageTag}` but in snake case. (e.g., en_US). + * + * The Android specific `{androidLanguageTag}` placeholder is the same as `{languageTag}` + * but in Android format. (e.g., en-rUS) + */ + fileStructureTemplate?: string; + /** + * @description If true, for structured formats (like JSON) arrays are supported. + * + * e.g. Key hello[0] will be exported as {"hello": ["..."]} + */ + supportArrays?: boolean; + /** + * @description If true, HTML tags are escaped in the exported file. (Supported in the XLIFF format only). + * + * e.g. Key hello will be exported as <b>hello</b> + */ + escapeHtml?: boolean; }; }; responses: { - /** @description OK */ + /** + * @description When multiple files are exported, they are zipped and returned as a single zip file. + * When a single file is exported, it is returned directly. + */ 200: { content: { - "application/json": components["schemas"]["TaskModel"]; + "application/*": unknown; }; }; /** @description Bad Request */ @@ -2638,26 +5405,77 @@ export interface operations { }; }; /** - * Update task key - * @description Mark key as done, which updates task progress. + * Export data (post) + * @description Exports data (post). Useful when exceeding allowed URL size. */ - updateTaskKey_1: { + exportPost_1: { + requestBody: { + content: { + "application/json": components["schemas"]["ExportParams"]; + }; + }; + responses: { + /** + * @description When multiple files are exported, they are zipped and returned as a single zip file. + * When a single file is exported, it is returned directly. + */ + 200: { + content: { + "application/*": unknown; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Add files + * @description Prepares provided files to import. + */ + addFiles_1: { parameters: { - path: { - taskNumber: number; - keyId: number; + query?: { + /** + * @description When importing files in structured formats (e.g., JSON, YAML), this field defines the delimiter which will be used in names of imported keys. + * @example . + */ + structureDelimiter?: string; }; }; - requestBody: { + requestBody?: { content: { - "application/json": components["schemas"]["UpdateTaskKeyRequest"]; + "multipart/form-data": { + files: string[]; + }; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["UpdateTaskKeyResponse"]; + "application/json": components["schemas"]["ImportAddFilesResultModel"]; }; }; /** @description Bad Request */ @@ -2686,19 +5504,15 @@ export interface operations { }; }; }; - /** Get task keys */ - getTaskKeys_1: { - parameters: { - path: { - taskNumber: number; - }; - }; + /** + * Delete + * @description Deletes prepared import data. + */ + cancelImport_1: { responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["TaskKeysResponse"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -2726,22 +5540,17 @@ export interface operations { }; }; }; - /** Add or remove task keys */ - updateTaskKeys_1: { - parameters: { - path: { - taskNumber: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["UpdateTaskKeysRequest"]; - }; - }; + /** + * Get Import Settings + * @description Returns import settings for the authenticated user and the project. + */ + get_5: { responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["ImportSettingsModel"]; + }; }; /** @description Bad Request */ 400: { @@ -2769,18 +5578,21 @@ export interface operations { }; }; }; - /** Finish task */ - finishTask_1: { - parameters: { - path: { - taskNumber: number; + /** + * Set Import Settings + * @description Stores import settings for the authenticated user and the project. + */ + store_1: { + requestBody: { + content: { + "application/json": components["schemas"]["ImportSettingsRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TaskModel"]; + "application/json": components["schemas"]["ImportSettingsModel"]; }; }; /** @description Bad Request */ @@ -2809,18 +5621,16 @@ export interface operations { }; }; }; - /** Close task */ - closeTask_1: { - parameters: { - path: { - taskNumber: number; - }; - }; + /** + * Get namespaces + * @description Returns all existing and imported namespaces + */ + getAllNamespaces_1: { responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TaskModel"]; + "application/json": components["schemas"]["CollectionModelImportNamespaceModel"]; }; }; /** @description Bad Request */ @@ -2849,19 +5659,21 @@ export interface operations { }; }; }; - /** Get task */ - getTask_1: { + /** + * Apply import + * @description Imports the data prepared in previous step + */ + applyImport_1: { parameters: { - path: { - taskNumber: number; + query?: { + /** @description Whether override or keep all translations with unresolved conflicts */ + forceMode?: "OVERRIDE" | "KEEP" | "NO_FORCE"; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["TaskModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -2889,23 +5701,22 @@ export interface operations { }; }; }; - /** Update task */ - updateTask_1: { + /** + * Apply import (streaming) + * @description Imports the data prepared in previous step. Streams current status. + */ + applyImportStreaming_1: { parameters: { - path: { - taskNumber: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["UpdateTaskRequest"]; + query?: { + /** @description Whether override or keep all translations with unresolved conflicts */ + forceMode?: "OVERRIDE" | "KEEP" | "NO_FORCE"; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TaskModel"]; + "application/x-ndjson": components["schemas"]["StreamingResponseBody"]; }; }; /** @description Bad Request */ @@ -2934,23 +5745,26 @@ export interface operations { }; }; }; - /** Update namespace */ - update_2: { + /** + * Get result + * @description Returns the result of preparation. + */ + getImportResult_1: { parameters: { - path: { - id: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["UpdateNamespaceDto"]; + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["NamespaceModel"]; + "application/json": components["schemas"]["PagedModelImportLanguageModel"]; }; }; /** @description Bad Request */ @@ -2980,21 +5794,24 @@ export interface operations { }; }; /** - * Get disabled languages - * @description Returns languages, in which key is disabled + * Select namespace + * @description Sets namespace for file to import. */ - getDisabledLanguages_1: { + selectNamespace_1: { parameters: { path: { - id: number; + fileId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SetFileNamespaceRequest"]; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["CollectionModelLanguageModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -3023,25 +5840,28 @@ export interface operations { }; }; /** - * Set disabled languages - * @description Sets languages, in which key is disabled + * Get file issues + * @description Returns issues for uploaded file. */ - setDisabledLanguages_1: { + getImportFileIssues_1: { parameters: { - path: { - id: number; + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SetDisabledLanguagesRequest"]; + path: { + importFileId: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["CollectionModelLanguageModel"]; + "application/json": components["schemas"]["PagedModelImportFileIssueModel"]; }; }; /** @description Bad Request */ @@ -3071,26 +5891,19 @@ export interface operations { }; }; /** - * Edit key and related data - * @description Edits key name, translations, tags, screenshots, and other data + * Reset existing language pairing + * @description Resets existing language paired with language to import. */ - complexEdit_1: { + resetExistingLanguage_1: { parameters: { path: { - id: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["ComplexEditKeyDto"]; + importLanguageId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["KeyWithDataModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -3118,19 +5931,21 @@ export interface operations { }; }; }; - /** Get one key */ - get_7: { + /** + * Pair existing language + * @description Sets existing language to pair with language to import. Data will be imported to selected existing language when applied. + */ + selectExistingLanguage_1: { parameters: { path: { - id: number; + importLanguageId: number; + existingLanguageId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["KeyModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -3158,23 +5973,21 @@ export interface operations { }; }; }; - /** Edit key name */ - edit_1: { + /** + * Get import language + * @description Returns language prepared to import. + */ + getImportLanguage_1: { parameters: { path: { - id: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["EditKeyDto"]; + languageId: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["KeyModel"]; + "application/json": components["schemas"]["ImportLanguageModel"]; }; }; /** @description Bad Request */ @@ -3203,11 +6016,14 @@ export interface operations { }; }; }; - /** Execute complex tag operation */ - executeComplexTagOperation_1: { - requestBody: { - content: { - "application/json": components["schemas"]["ComplexTagKeysRequest"]; + /** + * Delete language + * @description Deletes language prepared to import. + */ + deleteLanguage_1: { + parameters: { + path: { + languageId: number; }; }; responses: { @@ -3242,26 +6058,19 @@ export interface operations { }; }; /** - * Tag key - * @description Tags a key with tag. If tag with provided name doesn't exist, it is created + * Resolve all translation conflicts (keep existing) + * @description Resolves all translation conflicts for provided language. The old translations will be kept. */ - tagKey_1: { + resolveTranslationSetKeepExisting_3: { parameters: { path: { - keyId: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["TagKeyDto"]; + languageId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["TagModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -3290,14 +6099,13 @@ export interface operations { }; }; /** - * Resolve conflict (override) - * @description Resolves translation conflict. The old translation will be overridden. + * Resolve all translation conflicts (override) + * @description Resolves all translation conflicts for provided language. The old translations will be overridden. */ - resolveTranslationSetOverride_1: { + resolveTranslationSetOverride_3: { parameters: { path: { languageId: number; - translationId: number; }; }; responses: { @@ -3332,20 +6140,35 @@ export interface operations { }; }; /** - * Resolve conflict (keep existing) - * @description Resolves translation conflict. The old translation will be kept. + * Get translations + * @description Returns translations prepared to import. */ - resolveTranslationSetKeepExisting_1: { + getImportTranslations_1: { parameters: { + query?: { + /** @description Whether only translations, which are in conflict with existing translations should be returned */ + onlyConflicts?: boolean; + /** @description Whether only translations with unresolved conflictswith existing translations should be returned */ + onlyUnresolved?: boolean; + /** @description String to search in translation text or key */ + search?: string; + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + }; path: { languageId: number; - translationId: number; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["PagedModelImportTranslationModel"]; + }; }; /** @description Bad Request */ 400: { @@ -3374,13 +6197,14 @@ export interface operations { }; }; /** - * Resolve all translation conflicts (override) - * @description Resolves all translation conflicts for provided language. The old translations will be overridden. + * Resolve conflict (keep existing) + * @description Resolves translation conflict. The old translation will be kept. */ - resolveTranslationSetOverride_3: { + resolveTranslationSetKeepExisting_1: { parameters: { path: { languageId: number; + translationId: number; }; }; responses: { @@ -3415,13 +6239,14 @@ export interface operations { }; }; /** - * Resolve all translation conflicts (keep existing) - * @description Resolves all translation conflicts for provided language. The old translations will be kept. + * Resolve conflict (override) + * @description Resolves translation conflict. The old translation will be overridden. */ - resolveTranslationSetKeepExisting_3: { + resolveTranslationSetOverride_1: { parameters: { path: { languageId: number; + translationId: number; }; }; responses: { @@ -3455,21 +6280,24 @@ export interface operations { }; }; }; - /** - * Pair existing language - * @description Sets existing language to pair with language to import. Data will be imported to selected existing language when applied. - */ - selectExistingLanguage_1: { + /** Get all keys */ + getAll_10: { parameters: { - path: { - importLanguageId: number; - existingLanguageId: number; + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["PagedModelKeyModel"]; + }; }; /** @description Bad Request */ 400: { @@ -3497,20 +6325,19 @@ export interface operations { }; }; }; - /** - * Reset existing language pairing - * @description Resets existing language paired with language to import. - */ - resetExistingLanguage_1: { - parameters: { - path: { - importLanguageId: number; + /** Create new key */ + create_8: { + requestBody: { + content: { + "application/json": components["schemas"]["CreateKeyDto"]; }; }; responses: { - /** @description OK */ - 200: { - content: never; + /** @description Created */ + 201: { + content: { + "*/*": components["schemas"]["KeyWithDataModel"]; + }; }; /** @description Bad Request */ 400: { @@ -3539,18 +6366,13 @@ export interface operations { }; }; /** - * Select namespace - * @description Sets namespace for file to import. + * Delete one or multiple keys (post) + * @description Delete one or multiple keys by their IDs in request body. Useful for larger requests esxceeding allowed URL length. */ - selectNamespace_1: { - parameters: { - path: { - fileId: number; - }; - }; + delete_7: { requestBody: { content: { - "application/json": components["schemas"]["SetFileNamespaceRequest"]; + "application/json": components["schemas"]["DeleteKeysDto"]; }; }; responses: { @@ -3584,22 +6406,18 @@ export interface operations { }; }; }; - /** - * Apply import (streaming) - * @description Imports the data prepared in previous step. Streams current status. - */ - applyImportStreaming_1: { - parameters: { - query?: { - /** @description Whether override or keep all translations with unresolved conflicts */ - forceMode?: "OVERRIDE" | "KEEP" | "NO_FORCE"; + /** Create new key */ + create_7: { + requestBody: { + content: { + "application/json": components["schemas"]["CreateKeyDto"]; }; }; responses: { - /** @description OK */ - 200: { + /** @description Created */ + 201: { content: { - "application/x-ndjson": components["schemas"]["StreamingResponseBody"]; + "*/*": components["schemas"]["KeyWithDataModel"]; }; }; /** @description Bad Request */ @@ -3629,14 +6447,13 @@ export interface operations { }; }; /** - * Apply import - * @description Imports the data prepared in previous step + * Import keys + * @description Imports new keys with translations. If key already exists, its translations and tags are not updated. */ - applyImport_1: { - parameters: { - query?: { - /** @description Whether override or keep all translations with unresolved conflicts */ - forceMode?: "OVERRIDE" | "KEEP" | "NO_FORCE"; + importKeys_3: { + requestBody: { + content: { + "application/json": components["schemas"]["ImportKeysDto"]; }; }; responses: { @@ -3671,15 +6488,23 @@ export interface operations { }; }; /** - * Get Import Settings - * @description Returns import settings for the authenticated user and the project. + * Import keys (resolvable) + * @deprecated + * @description + * Import's new keys with translations. Translations can be updated, when specified. + * DEPRECATED: Use /v2/projects/{projectId}/single-step-import-resolvable instead. */ - get_11: { + importKeys_1: { + requestBody: { + content: { + "application/json": components["schemas"]["ImportKeysResolvableDto"]; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["ImportSettingsModel"]; + "application/json": components["schemas"]["KeyImportResolvableResultModel"]; }; }; /** @description Bad Request */ @@ -3709,20 +6534,20 @@ export interface operations { }; }; /** - * Set Import Settings - * @description Stores import settings for the authenticated user and the project. + * Get key info + * @description Returns information about keys. (KeyData, Screenshots, Translation in specified language)If key is not found, it's not included in the response. */ - store_1: { + getInfo_1: { requestBody: { content: { - "application/json": components["schemas"]["ImportSettingsRequest"]; + "application/json": components["schemas"]["GetKeysRequestDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["ImportSettingsModel"]; + "application/json": components["schemas"]["CollectionModelKeyWithDataModel"]; }; }; /** @description Bad Request */ @@ -3752,19 +6577,32 @@ export interface operations { }; }; /** - * Stop batch operation - * @description Stops batch operation if possible. + * Search for keys + * @description This endpoint helps you to find desired key by keyName, base translation or translation in specified language. + * + * Sort is ignored for this request. */ - cancel_1: { + searchForKey_1: { parameters: { - path: { - id: number; + query: { + /** @description Search query */ + search: string; + /** @description Language to search in */ + languageTag?: string; + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["PagedModelKeySearchSearchResultModel"]; + }; }; /** @description Bad Request */ 400: { @@ -3792,19 +6630,116 @@ export interface operations { }; }; }; - /** Set translation state */ - setTranslationState_1: { + /** + * Select keys + * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. + */ + selectKeys_3: { parameters: { - path: { - translationId: number; - state: "TRANSLATED" | "REVIEWED"; + query?: { + /** + * @description Translation state in the format: languageTag,state. You can use this parameter multiple times. + * + * When used with multiple states for same language it is applied with logical OR. + * + * When used with multiple languages, it is applied with logical AND. + */ + filterState?: string[]; + /** + * @description Languages to be contained in response. + * + * To add multiple languages, repeat this param (eg. ?languages=en&languages=de) + * @example en + */ + languages?: string[]; + /** @description String to search in key name or translation text */ + search?: string; + /** @description Selects key with provided names. Use this param multiple times to fetch more keys. */ + filterKeyName?: string[]; + /** @description Selects key with provided ID. Use this param multiple times to fetch more keys. */ + filterKeyId?: number[]; + /** @description Selects only keys for which the translation is missing in any returned language. It only filters for translations included in returned languages. */ + filterUntranslatedAny?: boolean; + /** @description Selects only keys, where translation is provided in any language */ + filterTranslatedAny?: boolean; + /** + * @description Selects only keys where the translation is missing for the specified language. The specified language must be included in the returned languages. Otherwise, this filter doesn't apply. + * @example en-US + */ + filterUntranslatedInLang?: string; + /** + * @description Selects only keys, where translation is provided in specified language + * @example en-US + */ + filterTranslatedInLang?: string; + /** + * @description Selects only keys, where translation was auto translated for specified languages. + * @example en-US + */ + filterAutoTranslatedInLang?: string[]; + /** @description Selects only keys with screenshots */ + filterHasScreenshot?: boolean; + /** @description Selects only keys without screenshots */ + filterHasNoScreenshot?: boolean; + /** + * @description Selects only keys with provided namespaces. + * + * To filter default namespace, set to empty string. + */ + filterNamespace?: string[]; + /** + * @description Selects only keys without provided namespaces. + * + * To filter default namespace, set to empty string. + */ + filterNoNamespace?: string[]; + /** @description Selects only keys with provided tag */ + filterTag?: string[]; + /** @description Selects only keys without provided tag */ + filterNoTag?: string[]; + /** + * @description Selects only keys, where translation in provided langs is in outdated state + * @example en-US + */ + filterOutdatedLanguage?: string[]; + /** + * @description Selects only keys, where translation in provided langs is not in outdated state + * @example en-US + */ + filterNotOutdatedLanguage?: string[]; + /** + * @description Selects only key affected by activity with specidfied revision ID + * @example 1234567 + */ + filterRevisionId?: number[]; + /** @description Select only keys which were not successfully translated by batch job with provided id */ + filterFailedKeysOfJob?: number; + /** @description Select only keys which are in specified task */ + filterTaskNumber?: number[]; + /** @description Filter task keys which are `not done` */ + filterTaskKeysNotDone?: boolean; + /** @description Filter task keys which are `done` */ + filterTaskKeysDone?: boolean; + /** @description Filter keys with unresolved comments in lang */ + filterHasUnresolvedCommentsInLang?: string[]; + /** @description Filter keys with any comments in lang */ + filterHasCommentsInLang?: string[]; + /** + * @description Filter key translations with labels + * @example labelId1,labelId2 + */ + filterLabel?: string[]; + /** @description Filter keys with any suggestions in lang */ + filterHasSuggestionsInLang?: string[]; + /** @description Filter keys with no suggestions in lang */ + filterHasNoSuggestionsInLang?: string[]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TranslationModel"]; + "application/json": components["schemas"]["SelectAllResponse"]; }; }; /** @description Bad Request */ @@ -3833,21 +6768,17 @@ export interface operations { }; }; }; - /** Set state of translation comment */ - setState_1: { + /** Delete one or multiple keys */ + delete_5: { parameters: { path: { - translationId: number; - commentId: number; - state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; + ids: number[]; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["TranslationCommentModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -3875,19 +6806,18 @@ export interface operations { }; }; }; - /** Get one translation comment */ + /** Get one key */ get_15: { parameters: { path: { - translationId: number; - commentId: number; + id: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TranslationCommentModel"]; + "application/json": components["schemas"]["KeyModel"]; }; }; /** @description Bad Request */ @@ -3916,24 +6846,23 @@ export interface operations { }; }; }; - /** Update translation comment */ - update_6: { + /** Edit key name */ + edit_1: { parameters: { path: { - commentId: number; - translationId: number; + id: number; }; }; requestBody: { content: { - "application/json": components["schemas"]["TranslationCommentDto"]; + "application/json": components["schemas"]["EditKeyDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TranslationCommentModel"]; + "application/json": components["schemas"]["KeyModel"]; }; }; /** @description Bad Request */ @@ -3962,18 +6891,19 @@ export interface operations { }; }; }; - /** Delete translation comment */ - delete_9: { + /** Get Big Meta for key */ + getBigMeta_1: { parameters: { path: { - translationId: number; - commentId: number; + id: number; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["CollectionModelKeyWithBaseTranslationModel"]; + }; }; /** @description Bad Request */ 400: { @@ -4002,21 +6932,25 @@ export interface operations { }; }; /** - * Set outdated value - * @description Set's "outdated" flag indicating the base translation was changed without updating current translation. + * Edit key and related data + * @description Edits key name, translations, tags, screenshots, and other data */ - setOutdated_1: { + complexEdit_1: { parameters: { path: { - translationId: number; - state: boolean; + id: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ComplexEditKeyDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TranslationModel"]; + "application/json": components["schemas"]["KeyWithDataModel"]; }; }; /** @description Bad Request */ @@ -4046,20 +6980,20 @@ export interface operations { }; }; /** - * Dismiss auto-translated - * @description Removes "auto translated" indication + * Get disabled languages + * @description Returns languages, in which key is disabled */ - dismissAutoTranslatedState_1: { + getDisabledLanguages_1: { parameters: { path: { - translationId: number; + id: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TranslationModel"]; + "application/json": components["schemas"]["CollectionModelLanguageModel"]; }; }; /** @description Bad Request */ @@ -4088,91 +7022,26 @@ export interface operations { }; }; }; - /** Get translations in project */ - getTranslations_1: { + /** + * Set disabled languages + * @description Sets languages, in which key is disabled + */ + setDisabledLanguages_1: { parameters: { - query?: { - /** @description Cursor to get next data */ - cursor?: string; - /** - * @description Translation state in the format: languageTag,state. You can use this parameter multiple times. - * - * When used with multiple states for same language it is applied with logical OR. - * - * When used with multiple languages, it is applied with logical AND. - */ - filterState?: string[]; - /** - * @description Languages to be contained in response. - * - * To add multiple languages, repeat this param (eg. ?languages=en&languages=de) - * @example en - */ - languages?: string[]; - /** @description String to search in key name or translation text */ - search?: string; - /** @description Selects key with provided names. Use this param multiple times to fetch more keys. */ - filterKeyName?: string[]; - /** @description Selects key with provided ID. Use this param multiple times to fetch more keys. */ - filterKeyId?: number[]; - /** @description Selects only keys for which the translation is missing in any returned language. It only filters for translations included in returned languages. */ - filterUntranslatedAny?: boolean; - /** @description Selects only keys, where translation is provided in any language */ - filterTranslatedAny?: boolean; - /** - * @description Selects only keys where the translation is missing for the specified language. The specified language must be included in the returned languages. Otherwise, this filter doesn't apply. - * @example en-US - */ - filterUntranslatedInLang?: string; - /** - * @description Selects only keys, where translation is provided in specified language - * @example en-US - */ - filterTranslatedInLang?: string; - /** @description Selects only keys with screenshots */ - filterHasScreenshot?: boolean; - /** @description Selects only keys without screenshots */ - filterHasNoScreenshot?: boolean; - /** - * @description Filter namespaces. - * - * To filter default namespace, set to empty string. - */ - filterNamespace?: string[]; - /** @description Selects only keys with provided tag */ - filterTag?: string[]; - /** - * @description Selects only keys, where translation in provided langs is in outdated state - * @example en-US - */ - filterOutdatedLanguage?: string[]; - /** - * @description Selects only keys, where translation in provided langs is not in outdated state - * @example en-US - */ - filterNotOutdatedLanguage?: string[]; - /** - * @description Selects only key affected by activity with specidfied revision ID - * @example 1234567 - */ - filterRevisionId?: number[]; - /** @description Select only keys which were not successfully translated by batch job with provided id */ - filterFailedKeysOfJob?: number; - /** @description Select only keys which are in specified task */ - filterTaskNumber?: number[]; - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; + path: { + id: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SetDisabledLanguagesRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["KeysWithTranslationsPageModel"]; + "application/json": components["schemas"]["CollectionModelLanguageModel"]; }; }; /** @description Bad Request */ @@ -4202,21 +7071,31 @@ export interface operations { }; }; /** - * Update translations for existing key - * @description Sets translations for existing key + * Auto translates keys + * @description Uses enabled auto-translation methods. + * You need to set at least one of useMachineTranslation or useTranslationMemory to true. + * + * This will replace the the existing translation with the result obtained from specified source! */ - setTranslations_1: { - requestBody: { - content: { - "application/json": components["schemas"]["SetTranslationsWithKeyDto"]; + autoTranslate_1: { + parameters: { + query?: { + /** + * @description Tags of languages to auto-translate. + * When no languages provided, it translates only untranslated languages. + */ + languages?: string[]; + useMachineTranslation?: boolean; + useTranslationMemory?: boolean; + }; + path: { + keyId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["SetTranslationsResponseModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -4244,21 +7123,18 @@ export interface operations { }; }; }; - /** - * Create key or update translations - * @description Sets translations for existing key or creates new key and sets the translations to it. - */ - createOrUpdateTranslations_1: { - requestBody: { - content: { - "application/json": components["schemas"]["SetTranslationsWithKeyDto"]; + /** Get screenshots */ + getKeyScreenshots: { + parameters: { + path: { + keyId: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["SetTranslationsResponseModel"]; + "application/json": components["schemas"]["CollectionModelScreenshotModel"]; }; }; /** @description Bad Request */ @@ -4287,18 +7163,27 @@ export interface operations { }; }; }; - /** Get one language */ - get_17: { + /** Upload screenshot */ + uploadScreenshot: { parameters: { path: { - languageId: number; + keyId: number; + }; + }; + requestBody?: { + content: { + "multipart/form-data": { + /** Format: binary */ + screenshot: string; + info?: components["schemas"]["ScreenshotInfoDto"]; + }; }; }; responses: { - /** @description OK */ - 200: { + /** @description Created */ + 201: { content: { - "application/json": components["schemas"]["LanguageModel"]; + "*/*": components["schemas"]["ScreenshotModel"]; }; }; /** @description Bad Request */ @@ -4327,24 +7212,18 @@ export interface operations { }; }; }; - /** Update language */ - editLanguage_1: { + /** Delete screenshots */ + deleteScreenshots: { parameters: { path: { - languageId: number; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["LanguageRequest"]; + ids: number[]; + keyId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["LanguageModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -4372,17 +7251,27 @@ export interface operations { }; }; }; - /** Delete specific language */ - deleteLanguage_3: { + /** + * Tag key + * @description Tags a key with tag. If tag with provided name doesn't exist, it is created + */ + tagKey_1: { parameters: { path: { - languageId: number; + keyId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TagKeyDto"]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["TagModel"]; + }; }; /** @description Bad Request */ 400: { @@ -4411,25 +7300,14 @@ export interface operations { }; }; /** - * Auto translates keys - * @description Uses enabled auto-translation methods. - * You need to set at least one of useMachineTranslation or useTranslationMemory to true. - * - * This will replace the the existing translation with the result obtained from specified source! + * Remove tag + * @description Removes tag with provided id from key with provided id */ - autoTranslate_1: { + removeTag_1: { parameters: { - query?: { - /** - * @description Tags of languages to auto-translate. - * When no languages provided, it translates only untranslated languages. - */ - languages?: string[]; - useMachineTranslation?: boolean; - useTranslationMemory?: boolean; - }; path: { keyId: number; + tagId: number; }; }; responses: { @@ -4463,18 +7341,24 @@ export interface operations { }; }; }; - /** Get one organization */ - get_20: { + /** Get available project labels */ + getAll_4: { parameters: { - path: { - id: number; + query?: { + search?: string; + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["OrganizationModel"]; + "application/json": components["schemas"]["PagedModelLabelModel"]; }; }; /** @description Bad Request */ @@ -4503,31 +7387,18 @@ export interface operations { }; }; }; - /** - * Get all permitted - * @description Returns all projects where current user has any permission - */ - getAll: { - parameters: { - query?: { - /** @description Filter projects by id */ - filterId?: number[]; - /** @description Filter projects without id */ - filterNotId?: number[]; - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - search?: string; + /** Create label */ + createLabel_1: { + requestBody: { + content: { + "application/json": components["schemas"]["LabelRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/hal+json": components["schemas"]["PagedModelProjectModel"]; + "application/json": components["schemas"]["LabelModel"]; }; }; /** @description Bad Request */ @@ -4556,21 +7427,18 @@ export interface operations { }; }; }; - /** - * Create project - * @description Creates a new project with languages and initial settings. - */ - createProject: { - requestBody: { - content: { - "application/json": components["schemas"]["CreateProjectRequest"]; + /** Get labels by ids */ + getLabelsByIds_1: { + parameters: { + query: { + id: number[]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["ProjectModel"]; + "application/json": components["schemas"]["LabelModel"][]; }; }; /** @description Bad Request */ @@ -4599,23 +7467,24 @@ export interface operations { }; }; }; - /** Create multiple tasks */ - createTasks_1: { + /** Update label */ + updateLabel_1: { parameters: { - query?: { - filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; - filterOutdated?: boolean; + path: { + labelId: number; }; }; requestBody: { content: { - "application/json": components["schemas"]["CreateMultipleTasksRequest"]; + "application/json": components["schemas"]["LabelRequest"]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["LabelModel"]; + }; }; /** @description Bad Request */ 400: { @@ -4643,25 +7512,17 @@ export interface operations { }; }; }; - /** Calculate scope */ - calculateScope_1: { + /** Delete label */ + deleteLabel_1: { parameters: { - query?: { - filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; - filterOutdated?: boolean; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["CalculateScopeRequest"]; + path: { + labelId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["KeysScopeView"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -4689,46 +7550,28 @@ export interface operations { }; }; }; - /** Get tasks */ - getTasks_2: { + /** Get suggestions */ + getSuggestions_1: { parameters: { query?: { - /** @description Filter tasks by state */ - filterState?: ("NEW" | "IN_PROGRESS" | "DONE" | "CLOSED")[]; - /** @description Filter tasks without state */ - filterNotState?: ("NEW" | "IN_PROGRESS" | "DONE" | "CLOSED")[]; - /** @description Filter tasks by assignee */ - filterAssignee?: number[]; - /** @description Filter tasks by type */ - filterType?: ("TRANSLATE" | "REVIEW")[]; - /** @description Filter tasks by id */ - filterId?: number[]; - /** @description Filter tasks without id */ - filterNotId?: number[]; - /** @description Filter tasks by project */ - filterProject?: number[]; - /** @description Filter tasks without project */ - filterNotProject?: number[]; - /** @description Filter tasks by language */ - filterLanguage?: number[]; - /** @description Filter tasks by key */ - filterKey?: number[]; - /** @description Exclude "done" tasks which are older than specified timestamp */ - filterDoneMinClosedAt?: number; /** @description Zero-based page index (0..N) */ page?: number; /** @description The size of the page to be returned */ size?: number; /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ sort?: string[]; - search?: string; + /** @description Filter by suggestion state */ + filterState?: ("ACTIVE" | "ACCEPTED" | "DECLINED")[]; + }; + path: { + keyId: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelTaskModel"]; + "application/json": components["schemas"]["PagedModelTranslationSuggestionModel"]; }; }; /** @description Bad Request */ @@ -4757,24 +7600,23 @@ export interface operations { }; }; }; - /** Create task */ - createTask_1: { + /** Create translation suggestion */ + createSuggestion_1: { parameters: { - query?: { - filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; - filterOutdated?: boolean; + path: { + keyId: number; }; }; requestBody: { content: { - "application/json": components["schemas"]["CreateTaskRequest"]; + "application/json": components["schemas"]["CreateTranslationSuggestionRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TaskModel"]; + "application/json": components["schemas"]["TranslationSuggestionModel"]; }; }; /** @description Bad Request */ @@ -4803,22 +7645,18 @@ export interface operations { }; }; }; - /** - * Get key info - * @description Returns information about keys. (KeyData, Screenshots, Translation in specified language)If key is not found, it's not included in the response. - */ - getInfo_1: { - requestBody: { - content: { - "application/json": components["schemas"]["GetKeysRequestDto"]; + /** Delete suggestion */ + deleteSuggestion_1: { + parameters: { + path: { + keyId: number; + suggestionId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["CollectionModelKeyWithDataModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -4846,21 +7684,22 @@ export interface operations { }; }; }; - /** - * Import keys (resolvable) - * @description Import's new keys with translations. Translations can be updated, when specified. - */ - importKeys_1: { - requestBody: { - content: { - "application/json": components["schemas"]["ImportKeysResolvableDto"]; + /** Accept suggestion */ + acceptSuggestion_1: { + parameters: { + query?: { + declineOther?: boolean; + }; + path: { + keyId: number; + suggestionId: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["KeyImportResolvableResultModel"]; + "application/json": components["schemas"]["TranslationSuggestionAcceptResponse"]; }; }; /** @description Bad Request */ @@ -4889,20 +7728,20 @@ export interface operations { }; }; }; - /** - * Import keys - * @description Imports new keys with translations. If key already exists, its translations and tags are not updated. - */ - importKeys_3: { - requestBody: { - content: { - "application/json": components["schemas"]["ImportKeysDto"]; + /** Decline suggestion */ + declineSuggestion_1: { + parameters: { + path: { + keyId: number; + suggestionId: number; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["TranslationSuggestionModel"]; + }; }; /** @description Bad Request */ 400: { @@ -4930,18 +7769,19 @@ export interface operations { }; }; }; - /** Create new key */ - create_3: { - requestBody: { - content: { - "application/json": components["schemas"]["CreateKeyDto"]; + /** Reverse suggestion */ + reverseSuggestion_1: { + parameters: { + path: { + keyId: number; + suggestionId: number; }; }; responses: { - /** @description Created */ - 201: { + /** @description OK */ + 200: { content: { - "*/*": components["schemas"]["KeyWithDataModel"]; + "application/json": components["schemas"]["TranslationSuggestionModel"]; }; }; /** @description Bad Request */ @@ -4970,8 +7810,8 @@ export interface operations { }; }; }; - /** Get all keys */ - getAll_2: { + /** Get all languages */ + getAll_8: { parameters: { query?: { /** @description Zero-based page index (0..N) */ @@ -4980,13 +7820,19 @@ export interface operations { size?: number; /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ sort?: string[]; + /** @description Filter languages by id */ + filterId?: number[]; + /** @description Filter languages without id */ + filterNotId?: number[]; + /** @description Filter languages by name or tag */ + search?: string; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelKeyModel"]; + "application/json": components["schemas"]["PagedModelLanguageModel"]; }; }; /** @description Bad Request */ @@ -5015,18 +7861,18 @@ export interface operations { }; }; }; - /** Create new key */ - create_4: { + /** Create language */ + createLanguage_1: { requestBody: { content: { - "application/json": components["schemas"]["CreateKeyDto"]; + "application/json": components["schemas"]["LanguageRequest"]; }; }; responses: { - /** @description Created */ - 201: { + /** @description OK */ + 200: { content: { - "*/*": components["schemas"]["KeyWithDataModel"]; + "application/json": components["schemas"]["LanguageModel"]; }; }; /** @description Bad Request */ @@ -5055,20 +7901,64 @@ export interface operations { }; }; }; - /** - * Delete one or multiple keys (post) - * @description Delete one or multiple keys by their IDs in request body. Useful for larger requests esxceeding allowed URL length. - */ - delete_5: { + /** Get one language */ + get_13: { + parameters: { + path: { + languageId: number; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["LanguageModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** Update language */ + editLanguage_1: { + parameters: { + path: { + languageId: number; + }; + }; requestBody: { content: { - "application/json": components["schemas"]["DeleteKeysDto"]; + "application/json": components["schemas"]["LanguageRequest"]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["LanguageModel"]; + }; }; /** @description Bad Request */ 400: { @@ -5096,19 +7986,17 @@ export interface operations { }; }; }; - /** Remove tags */ - untagKeys_1: { - requestBody: { - content: { - "application/json": components["schemas"]["UntagKeysRequest"]; + /** Delete specific language */ + deleteLanguage_3: { + parameters: { + path: { + languageId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["BatchJobModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -5136,18 +8024,26 @@ export interface operations { }; }; }; - /** Add tags */ - tagKeys_1: { - requestBody: { - content: { - "application/json": components["schemas"]["TagKeysRequest"]; + /** + * List user batch operations + * @description List all batch operations started by current user + */ + myList_1: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["BatchJobModel"]; + "application/json": components["schemas"]["PagedModelBatchJobModel"]; }; }; /** @description Bad Request */ @@ -5176,18 +8072,21 @@ export interface operations { }; }; }; - /** Set translation state */ - setTranslationState_3: { - requestBody: { - content: { - "application/json": components["schemas"]["SetTranslationsStateStateRequest"]; + /** + * Get namespace by name + * @description Returns information about a namespace by its name + */ + getByName_1: { + parameters: { + path: { + name: string; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["BatchJobModel"]; + "application/json": components["schemas"]["NamespaceModel"]; }; }; /** @description Bad Request */ @@ -5216,18 +8115,24 @@ export interface operations { }; }; }; - /** Set keys namespace */ - setKeysNamespace_1: { - requestBody: { - content: { - "application/json": components["schemas"]["SetKeysNamespaceRequest"]; + /** Get namespaces */ + getAllNamespaces_3: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["BatchJobModel"]; + "application/json": components["schemas"]["PagedModelNamespaceModel"]; }; }; /** @description Bad Request */ @@ -5256,21 +8161,23 @@ export interface operations { }; }; }; - /** - * Pre-translate by TM - * @description Pre-translate provided keys to provided languages by TM. - */ - translate_1: { + /** Update namespace */ + update_4: { + parameters: { + path: { + id: number; + }; + }; requestBody: { content: { - "application/json": components["schemas"]["PreTranslationByTmRequest"]; + "application/json": components["schemas"]["UpdateNamespaceDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["BatchJobModel"]; + "application/json": components["schemas"]["NamespaceModel"]; }; }; /** @description Bad Request */ @@ -5300,20 +8207,23 @@ export interface operations { }; }; /** - * Machine Translation - * @description Translate provided keys to provided languages through primary MT provider. + * Single step import + * @description Unlike the /v2/projects/{projectId}/import endpoint, imports the data in single request by provided files and parameters. This is useful for automated importing via API or CLI. */ - machineTranslation_1: { - requestBody: { + singleStepFromFiles_1: { + requestBody?: { content: { - "application/json": components["schemas"]["MachineTranslationRequest"]; + "multipart/form-data": { + files: string[]; + params: components["schemas"]["SingleStepImportRequest"]; + }; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["BatchJobModel"]; + "application/json": components["schemas"]["ImportResult"]; }; }; /** @description Bad Request */ @@ -5342,18 +8252,18 @@ export interface operations { }; }; }; - /** Delete keys */ - deleteKeys_1: { + /** Single step import from body */ + singleStepResolvableImport_1: { requestBody: { content: { - "application/json": components["schemas"]["DeleteKeysRequest"]; + "application/json": components["schemas"]["SingleStepImportResolvableRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["BatchJobModel"]; + "application/json": components["schemas"]["ImportResult"]; }; }; /** @description Bad Request */ @@ -5382,14 +8292,11 @@ export interface operations { }; }; }; - /** - * Copy translation values - * @description Copy translation values from one language to other languages. - */ - copyTranslations_1: { + /** Translates via llm and stores result in AiPlaygroundResult */ + aiPlaygroundTranslate_1: { requestBody: { content: { - "application/json": components["schemas"]["CopyTranslationRequest"]; + "application/json": components["schemas"]["MachineTranslationRequest"]; }; }; responses: { @@ -5425,14 +8332,11 @@ export interface operations { }; }; }; - /** - * Clear translation values - * @description Clear translation values for provided keys in selected languages. - */ - clearTranslations_1: { + /** Assign labels to translations */ + assignTranslationLabel_1: { requestBody: { content: { - "application/json": components["schemas"]["ClearTranslationsRequest"]; + "application/json": components["schemas"]["LabelTranslationsRequest"]; }; }; responses: { @@ -5469,22 +8373,21 @@ export interface operations { }; }; /** - * Single step import - * @description Unlike the /v2/projects/{projectId}/import endpoint, imports the data in single request by provided files and parameters. This is useful for automated importing via API or CLI. + * Clear translation values + * @description Clear translation values for provided keys in selected languages. */ - doImport_1: { - requestBody?: { + clearTranslations_1: { + requestBody: { content: { - "multipart/form-data": { - files: string[]; - params: components["schemas"]["SingleStepImportRequest"]; - }; + "application/json": components["schemas"]["ClearTranslationsRequest"]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["BatchJobModel"]; + }; }; /** @description Bad Request */ 400: { @@ -5513,31 +8416,20 @@ export interface operations { }; }; /** - * Add files - * @description Prepares provided files to import. + * Copy translation values + * @description Copy translation values from one language to other languages. */ - addFiles_1: { - parameters: { - query?: { - /** - * @description When importing files in structured formats (e.g., JSON, YAML), this field defines the delimiter which will be used in names of imported keys. - * @example . - */ - structureDelimiter?: string; - }; - }; - requestBody?: { + copyTranslations_1: { + requestBody: { content: { - "multipart/form-data": { - files: string[]; - }; + "application/json": components["schemas"]["CopyTranslationRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["ImportAddFilesResultModel"]; + "application/json": components["schemas"]["BatchJobModel"]; }; }; /** @description Bad Request */ @@ -5566,15 +8458,19 @@ export interface operations { }; }; }; - /** - * Delete - * @description Deletes prepared import data. - */ - cancelImport_1: { + /** Delete keys */ + deleteKeys_1: { + requestBody: { + content: { + "application/json": components["schemas"]["DeleteKeysRequest"]; + }; + }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["BatchJobModel"]; + }; }; /** @description Bad Request */ 400: { @@ -5592,101 +8488,31 @@ export interface operations { 403: { content: { "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; - }; - }; - /** @description Not Found */ - 404: { - content: { - "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; - }; - }; - }; - }; - /** Export data */ - export_1: { - parameters: { - query?: { - /** - * @description Languages to be contained in export. - * - * If null, all languages are exported - * @example en - */ - languages?: string[]; - /** @description Format to export to */ - format?: "JSON" | "JSON_TOLGEE" | "JSON_I18NEXT" | "XLIFF" | "PO" | "APPLE_STRINGS_STRINGSDICT" | "APPLE_XLIFF" | "ANDROID_XML" | "FLUTTER_ARB" | "PROPERTIES" | "YAML_RUBY" | "YAML"; - /** - * @description Delimiter to structure file content. - * - * e.g. For key "home.header.title" would result in {"home": {"header": "title": {"Hello"}}} structure. - * - * When null, resulting file won't be structured. Works only for generic structured formats (e.g. JSON, YAML), - * specific formats like `YAML_RUBY` don't honor this parameter. - */ - structureDelimiter?: string; - /** @description Filter key IDs to be contained in export */ - filterKeyId?: number[]; - /** @description Filter key IDs not to be contained in export */ - filterKeyIdNot?: number[]; - /** - * @description Filter keys tagged by. - * - * This filter works the same as `filterTagIn` but in this cases it accepts single tag only. - */ - filterTag?: string; - /** @description Filter keys tagged by one of provided tags */ - filterTagIn?: string[]; - /** @description Filter keys not tagged by one of provided tags */ - filterTagNotIn?: string[]; - /** @description Filter keys with prefix */ - filterKeyPrefix?: string; - /** @description Filter translations with state. By default, all states except untranslated is exported. */ - filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; - /** @description Filter translations with namespace. By default, all namespaces everything are exported. To export default namespace, use empty string. */ - filterNamespace?: string[]; - /** - * @description If false, it doesn't return zip of files, but it returns single file. - * - * This is possible only when single language is exported. Otherwise it returns "400 - Bad Request" response. - */ - zip?: boolean; - /** - * @description Message format to be used for export. - * - * e.g. PHP_PO: Hello %s, ICU: Hello {name}. - * - * This property is honored only for generic formats like JSON or YAML. - * For specific formats like `YAML_RUBY` it's ignored. - */ - messageFormat?: "C_SPRINTF" | "PHP_SPRINTF" | "JAVA_STRING_FORMAT" | "APPLE_SPRINTF" | "RUBY_SPRINTF" | "I18NEXT" | "ICU"; - /** - * @description This is a template that defines the structure of the resulting .zip file content. - * - * The template is a string that can contain the following placeholders: {namespace}, {languageTag}, - * {androidLanguageTag}, {snakeLanguageTag}, {extension}. - * - * For example, when exporting to JSON with the template `{namespace}/{languageTag}.{extension}`, - * the English translations of the `home` namespace will be stored in `home/en.json`. - * - * The `{snakeLanguageTag}` placeholder is the same as `{languageTag}` but in snake case. (e.g., en_US). - * - * The Android specific `{androidLanguageTag}` placeholder is the same as `{languageTag}` - * but in Android format. (e.g., en-rUS) - */ - fileStructureTemplate?: string; - /** - * @description If true, for structured formats (like JSON) arrays are supported. - * - * e.g. Key hello[0] will be exported as {"hello": ["..."]} - */ - supportArrays?: boolean; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + }; + }; + /** + * Machine Translation + * @description Translate provided keys to provided languages through primary MT provider. + */ + machineTranslation_1: { + requestBody: { + content: { + "application/json": components["schemas"]["MachineTranslationRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["StreamingResponseBody"]; + "application/json": components["schemas"]["BatchJobModel"]; }; }; /** @description Bad Request */ @@ -5716,20 +8542,20 @@ export interface operations { }; }; /** - * Export data (post) - * @description Exports data (post). Useful when exceeding allowed URL size. + * Pre-translate by TM + * @description Pre-translate provided keys to provided languages by TM. */ - exportPost_1: { + translate_1: { requestBody: { content: { - "application/json": components["schemas"]["ExportParams"]; + "application/json": components["schemas"]["PreTranslationByTmRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["StreamingResponseBody"]; + "application/json": components["schemas"]["BatchJobModel"]; }; }; /** @description Bad Request */ @@ -5758,20 +8584,19 @@ export interface operations { }; }; }; - /** - * Store Big Meta - * @description Stores a bigMeta for a project - */ - store_3: { + /** Set keys namespace */ + setKeysNamespace_1: { requestBody: { content: { - "application/json": components["schemas"]["BigMetaDto"]; + "application/json": components["schemas"]["SetKeysNamespaceRequest"]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["BatchJobModel"]; + }; }; /** @description Bad Request */ 400: { @@ -5799,29 +8624,18 @@ export interface operations { }; }; }; - /** - * Get translation comments - * @description Returns translation comments of translation - */ - getAll_6: { - parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - }; - path: { - translationId: number; + /** Set translation state */ + setTranslationState_3: { + requestBody: { + content: { + "application/json": components["schemas"]["SetTranslationsStateStateRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelTranslationCommentModel"]; + "application/json": components["schemas"]["BatchJobModel"]; }; }; /** @description Bad Request */ @@ -5850,23 +8664,18 @@ export interface operations { }; }; }; - /** Create translation comment */ - create_8: { - parameters: { - path: { - translationId: number; - }; - }; + /** Add tags */ + tagKeys_1: { requestBody: { content: { - "application/json": components["schemas"]["TranslationCommentDto"]; + "application/json": components["schemas"]["TagKeysRequest"]; }; }; responses: { - /** @description Created */ - 201: { + /** @description OK */ + 200: { content: { - "*/*": components["schemas"]["TranslationCommentModel"]; + "application/json": components["schemas"]["BatchJobModel"]; }; }; /** @description Bad Request */ @@ -5895,21 +8704,18 @@ export interface operations { }; }; }; - /** - * Create translation comment - * @description Creates a translation comment. Empty translation is stored, when not exists. - */ - create_10: { + /** Unassign labels from translations */ + unassignTranslationLabel_1: { requestBody: { content: { - "application/json": components["schemas"]["TranslationCommentWithLangKeyDto"]; + "application/json": components["schemas"]["LabelTranslationsRequest"]; }; }; responses: { - /** @description Created */ - 201: { + /** @description OK */ + 200: { content: { - "*/*": components["schemas"]["TranslationWithCommentModel"]; + "application/json": components["schemas"]["BatchJobModel"]; }; }; /** @description Bad Request */ @@ -5938,31 +8744,18 @@ export interface operations { }; }; }; - /** - * Get suggestions from translation memory - * @description Suggests machine translations from translation memory. The result is always sorted by similarity, so sorting is not supported. - */ - suggestTranslationMemory_1: { - parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - }; - }; + /** Remove tags */ + untagKeys_1: { requestBody: { content: { - "application/json": components["schemas"]["SuggestRequestDto"]; + "application/json": components["schemas"]["UntagKeysRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelTranslationMemoryItemModel"]; + "application/json": components["schemas"]["BatchJobModel"]; }; }; /** @description Bad Request */ @@ -5991,21 +8784,50 @@ export interface operations { }; }; }; - /** - * Get machine translation suggestions (streaming) - * @description Suggests machine translations from enabled services. The results are streamed to the output in ndjson format. If an error occurs when for any service provider used, the error information is returned as a part of the result item, while the response has 200 status code. - */ - suggestMachineTranslationsStreaming_1: { - requestBody: { - content: { - "application/json": components["schemas"]["SuggestRequestDto"]; + /** Get project stats */ + getProjectStats_1: { + responses: { + /** @description OK */ + 200: { + content: { + "application/json": components["schemas"]["ProjectStatsModel"]; + }; + }; + /** @description Bad Request */ + 400: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Unauthorized */ + 401: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Forbidden */ + 403: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; + }; + /** @description Not Found */ + 404: { + content: { + "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; + }; }; }; + }; + /** Get project daily amount of events */ + getProjectDailyActivity_1: { responses: { /** @description OK */ 200: { content: { - "application/x-ndjson": components["schemas"]["StreamingResponseBody"]; + "application/json": { + [key: string]: number; + }; }; }; /** @description Bad Request */ @@ -6077,27 +8899,21 @@ export interface operations { }; }; }; - /** Get all languages */ - getAll_8: { - parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - /** @description Filter languages by id */ - filterId?: number[]; - /** @description Filter languages without id */ - filterNotId?: number[]; + /** + * Get machine translation suggestions (streaming) + * @description Suggests machine translations from enabled services. The results are streamed to the output in ndjson format. If an error occurs when for any service provider used, the error information is returned as a part of the result item, while the response has 200 status code. + */ + suggestMachineTranslationsStreaming_1: { + requestBody: { + content: { + "application/json": components["schemas"]["SuggestRequestDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelLanguageModel"]; + "application/x-ndjson": components["schemas"]["StreamingResponseBody"]; }; }; /** @description Bad Request */ @@ -6126,18 +8942,31 @@ export interface operations { }; }; }; - /** Create language */ - createLanguage_1: { + /** + * Get suggestions from translation memory + * @description Suggests machine translations from translation memory. The result is always sorted by similarity, so sorting is not supported. + */ + suggestTranslationMemory_1: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + }; + }; requestBody: { content: { - "application/json": components["schemas"]["LanguageRequest"]; + "application/json": components["schemas"]["SuggestRequestDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["LanguageModel"]; + "application/json": components["schemas"]["PagedModelTranslationMemoryItemModel"]; }; }; /** @description Bad Request */ @@ -6166,19 +8995,17 @@ export interface operations { }; }; }; - /** Get screenshots */ - getKeyScreenshots: { - parameters: { - path: { - keyId: number; + /** Execute complex tag operation */ + executeComplexTagOperation_1: { + requestBody: { + content: { + "application/json": components["schemas"]["ComplexTagKeysRequest"]; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["CollectionModelScreenshotModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -6206,27 +9033,24 @@ export interface operations { }; }; }; - /** Upload screenshot */ - uploadScreenshot: { + /** Get tags */ + getAll_2: { parameters: { - path: { - keyId: number; - }; - }; - requestBody?: { - content: { - "multipart/form-data": { - /** Format: binary */ - screenshot: string; - info?: components["schemas"]["ScreenshotInfoDto"]; - }; + query?: { + search?: string; + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; }; }; responses: { - /** @description Created */ - 201: { + /** @description OK */ + 200: { content: { - "*/*": components["schemas"]["ScreenshotModel"]; + "application/json": components["schemas"]["PagedModelTagModel"]; }; }; /** @description Bad Request */ @@ -6255,20 +9079,40 @@ export interface operations { }; }; }; - /** - * Get all permitted organizations - * @description Returns all organizations, which is current user allowed to view - */ - getAll_10: { + /** Get tasks */ + getTasks_2: { parameters: { query?: { + /** @description Filter tasks by state */ + filterState?: ("NEW" | "IN_PROGRESS" | "FINISHED" | "CANCELED")[]; + /** @description Filter tasks without state */ + filterNotState?: ("NEW" | "IN_PROGRESS" | "FINISHED" | "CANCELED")[]; + /** @description Filter tasks by assignee */ + filterAssignee?: number[]; + /** @description Filter tasks by type */ + filterType?: ("TRANSLATE" | "REVIEW")[]; + /** @description Filter tasks by id */ + filterId?: number[]; + /** @description Filter tasks without id */ + filterNotId?: number[]; + /** @description Filter tasks by project */ + filterProject?: number[]; + /** @description Filter tasks without project */ + filterNotProject?: number[]; + /** @description Filter tasks by language */ + filterLanguage?: number[]; + /** @description Filter tasks by key */ + filterKey?: number[]; + /** @description Filter tasks by agency */ + filterAgency?: number[]; + /** @description Exclude tasks which were closed before specified timestamp */ + filterNotClosedBefore?: number; /** @description Zero-based page index (0..N) */ page?: number; /** @description The size of the page to be returned */ size?: number; /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ sort?: string[]; - filterCurrentUserOwner?: boolean; search?: string; }; }; @@ -6276,7 +9120,7 @@ export interface operations { /** @description OK */ 200: { content: { - "application/hal+json": components["schemas"]["PagedModelOrganizationModel"]; + "application/json": components["schemas"]["PagedModelTaskModel"]; }; }; /** @description Bad Request */ @@ -6305,18 +9149,24 @@ export interface operations { }; }; }; - /** Create organization */ - create_12: { + /** Create task */ + createTask_1: { + parameters: { + query?: { + filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; + filterOutdated?: boolean; + }; + }; requestBody: { content: { - "application/json": components["schemas"]["OrganizationDto"]; + "application/json": components["schemas"]["CreateTaskRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["OrganizationModel"]; + "application/json": components["schemas"]["TaskModel"]; }; }; /** @description Bad Request */ @@ -6345,22 +9195,24 @@ export interface operations { }; }; }; - /** Upload an image for later use */ - upload: { - requestBody?: { + /** Calculate scope */ + calculateScope_1: { + parameters: { + query?: { + filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; + filterOutdated?: boolean; + }; + }; + requestBody: { content: { - "multipart/form-data": { - /** Format: binary */ - image: string; - info?: components["schemas"]["ImageUploadInfoDto"]; - }; + "application/json": components["schemas"]["CalculateScopeRequest"]; }; }; responses: { - /** @description Created */ - 201: { + /** @description OK */ + 200: { content: { - "*/*": components["schemas"]["UploadedImageModel"]; + "application/json": components["schemas"]["KeysScopeView"]; }; }; /** @description Bad Request */ @@ -6389,47 +9241,23 @@ export interface operations { }; }; }; - /** Get user tasks */ - getTasks: { + /** Create multiple tasks */ + createTasks_1: { parameters: { query?: { - /** @description Filter tasks by state */ - filterState?: ("NEW" | "IN_PROGRESS" | "DONE" | "CLOSED")[]; - /** @description Filter tasks without state */ - filterNotState?: ("NEW" | "IN_PROGRESS" | "DONE" | "CLOSED")[]; - /** @description Filter tasks by assignee */ - filterAssignee?: number[]; - /** @description Filter tasks by type */ - filterType?: ("TRANSLATE" | "REVIEW")[]; - /** @description Filter tasks by id */ - filterId?: number[]; - /** @description Filter tasks without id */ - filterNotId?: number[]; - /** @description Filter tasks by project */ - filterProject?: number[]; - /** @description Filter tasks without project */ - filterNotProject?: number[]; - /** @description Filter tasks by language */ - filterLanguage?: number[]; - /** @description Filter tasks by key */ - filterKey?: number[]; - /** @description Exclude "done" tasks which are older than specified timestamp */ - filterDoneMinClosedAt?: number; - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - search?: string; + filterState?: ("UNTRANSLATED" | "TRANSLATED" | "REVIEWED" | "DISABLED")[]; + filterOutdated?: boolean; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateMultipleTasksRequest"]; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["PagedModelTaskWithProjectModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -6457,16 +9285,33 @@ export interface operations { }; }; }; - /** - * Get used namespaces - * @description Returns all used project namespaces. Response contains default (null) namespace if used. - */ - getUsedNamespaces_1: { + getPossibleAssignees_1: { + parameters: { + query?: { + /** @description Filter users by id */ + filterId?: number[]; + /** @description Filter only users that have at least following scopes */ + filterMinimalScope?: string; + /** @description Filter only users that can view language */ + filterViewLanguageId?: number; + /** @description Filter only users that can edit language */ + filterEditLanguageId?: number; + /** @description Filter only users that can edit state of language */ + filterStateLanguageId?: number; + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["CollectionModelUsedNamespaceModel"]; + "application/json": components["schemas"]["PagedModelSimpleUserAccountModel"]; }; }; /** @description Bad Request */ @@ -6495,11 +9340,8 @@ export interface operations { }; }; }; - /** - * Get report in XLSX - * @description Detailed statistics about the task results - */ - getXlsxReport_1: { + /** Get task */ + getTask_1: { parameters: { path: { taskNumber: number; @@ -6509,7 +9351,7 @@ export interface operations { /** @description OK */ 200: { content: { - "application/json": string; + "application/json": components["schemas"]["TaskModel"]; }; }; /** @description Bad Request */ @@ -6538,21 +9380,23 @@ export interface operations { }; }; }; - /** - * Get report - * @description Detailed statistics for every assignee - */ - getPerUserReport_1: { + /** Update task */ + updateTask_1: { parameters: { path: { taskNumber: number; }; }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateTaskRequest"]; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["TaskPerUserReportModel"][]; + "application/json": components["schemas"]["TaskModel"]; }; }; /** @description Bad Request */ @@ -6624,33 +9468,18 @@ export interface operations { }; }; }; - getPossibleAssignees_1: { + /** Close task */ + cancelTask_1: { parameters: { - query?: { - /** @description Filter users by id */ - filterId?: number[]; - /** @description Filter only users that have at least following scopes */ - filterMinimalScope?: string; - /** @description Filter only users that can view language */ - filterViewLanguageId?: number; - /** @description Filter only users that can edit language */ - filterEditLanguageId?: number; - /** @description Filter only users that can edit state of language */ - filterStateLanguageId?: number; - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - search?: string; + path: { + taskNumber: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelSimpleUserAccountModel"]; + "application/json": components["schemas"]["TaskModel"]; }; }; /** @description Bad Request */ @@ -6679,23 +9508,21 @@ export interface operations { }; }; }; - /** Get namespaces */ - getAllNamespaces_1: { + /** + * Close task + * @deprecated + */ + closeTask_1: { parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; + path: { + taskNumber: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelNamespaceModel"]; + "application/json": components["schemas"]["TaskModel"]; }; }; /** @description Bad Request */ @@ -6724,21 +9551,18 @@ export interface operations { }; }; }; - /** - * Get namespace by name - * @description Returns information about a namespace by its name - */ - getByName_1: { + /** Finish task */ + finishTask_1: { parameters: { path: { - name: string; + taskNumber: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["NamespaceModel"]; + "application/json": components["schemas"]["TaskModel"]; }; }; /** @description Bad Request */ @@ -6767,30 +9591,18 @@ export interface operations { }; }; }; - /** - * Search for keys - * @description This endpoint helps you to find desired key by keyName, base translation or translation in specified language. - */ - searchForKey_1: { + /** Get task keys */ + getTaskKeys_1: { parameters: { - query: { - /** @description Search query */ - search: string; - /** @description Language to search in */ - languageTag?: string; - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; + path: { + taskNumber: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelKeySearchSearchResultModel"]; + "application/json": components["schemas"]["TaskKeysResponse"]; }; }; /** @description Bad Request */ @@ -6819,19 +9631,22 @@ export interface operations { }; }; }; - /** Get one revision data */ - getSingleRevision_1: { + /** Add or remove task keys */ + updateTaskKeys_1: { parameters: { path: { - revisionId: number; + taskNumber: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateTaskKeysRequest"]; }; }; responses: { /** @description OK */ 200: { - content: { - "application/hal+json": components["schemas"]["ProjectActivityModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -6859,23 +9674,27 @@ export interface operations { }; }; }; - /** Get project activity */ - getActivity_1: { + /** + * Update task key + * @description Mark key as done, which updates task progress. + */ + updateTaskKey_1: { parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; + path: { + taskNumber: number; + keyId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["UpdateTaskKeyRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/hal+json": components["schemas"]["PagedModelProjectActivityModel"]; + "application/json": components["schemas"]["UpdateTaskKeyResponse"]; }; }; /** @description Bad Request */ @@ -6904,24 +9723,21 @@ export interface operations { }; }; }; - /** Get tags */ - getAll_4: { + /** + * Get report + * @description Detailed statistics for every assignee + */ + getPerUserReport_1: { parameters: { - query?: { - search?: string; - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; + path: { + taskNumber: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelTagModel"]; + "application/json": components["schemas"]["TaskPerUserReportModel"][]; }; }; /** @description Bad Request */ @@ -6950,26 +9766,18 @@ export interface operations { }; }; }; - /** - * List user batch operations - * @description List all batch operations started by current user - */ - myList_1: { + /** Reopen task */ + reopenTask_1: { parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; + path: { + taskNumber: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelBatchJobModel"]; + "application/json": components["schemas"]["TaskModel"]; }; }; /** @description Bad Request */ @@ -6998,18 +9806,21 @@ export interface operations { }; }; }; - /** Get Big Meta for key */ - getBigMeta_1: { + /** + * Get report in XLSX + * @description Detailed statistics about the task results + */ + getXlsxReport_1: { parameters: { path: { - id: number; + taskNumber: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["CollectionModelKeyWithBaseTranslationModel"]; + "application/json": string; }; }; /** @description Bad Request */ @@ -7038,19 +9849,108 @@ export interface operations { }; }; }; - /** - * Get translations - * @description Returns translations prepared to import. - */ - getImportTranslations_1: { + /** Get translations in project */ + getTranslations_1: { parameters: { query?: { - /** @description Whether only translations, which are in conflict with existing translations should be returned */ - onlyConflicts?: boolean; - /** @description Whether only translations with unresolved conflictswith existing translations should be returned */ - onlyUnresolved?: boolean; - /** @description String to search in translation text or key */ + /** @description Cursor to get next data */ + cursor?: string; + /** + * @description Translation state in the format: languageTag,state. You can use this parameter multiple times. + * + * When used with multiple states for same language it is applied with logical OR. + * + * When used with multiple languages, it is applied with logical AND. + */ + filterState?: string[]; + /** + * @description Languages to be contained in response. + * + * To add multiple languages, repeat this param (eg. ?languages=en&languages=de) + * @example en + */ + languages?: string[]; + /** @description String to search in key name or translation text */ search?: string; + /** @description Selects key with provided names. Use this param multiple times to fetch more keys. */ + filterKeyName?: string[]; + /** @description Selects key with provided ID. Use this param multiple times to fetch more keys. */ + filterKeyId?: number[]; + /** @description Selects only keys for which the translation is missing in any returned language. It only filters for translations included in returned languages. */ + filterUntranslatedAny?: boolean; + /** @description Selects only keys, where translation is provided in any language */ + filterTranslatedAny?: boolean; + /** + * @description Selects only keys where the translation is missing for the specified language. The specified language must be included in the returned languages. Otherwise, this filter doesn't apply. + * @example en-US + */ + filterUntranslatedInLang?: string; + /** + * @description Selects only keys, where translation is provided in specified language + * @example en-US + */ + filterTranslatedInLang?: string; + /** + * @description Selects only keys, where translation was auto translated for specified languages. + * @example en-US + */ + filterAutoTranslatedInLang?: string[]; + /** @description Selects only keys with screenshots */ + filterHasScreenshot?: boolean; + /** @description Selects only keys without screenshots */ + filterHasNoScreenshot?: boolean; + /** + * @description Selects only keys with provided namespaces. + * + * To filter default namespace, set to empty string. + */ + filterNamespace?: string[]; + /** + * @description Selects only keys without provided namespaces. + * + * To filter default namespace, set to empty string. + */ + filterNoNamespace?: string[]; + /** @description Selects only keys with provided tag */ + filterTag?: string[]; + /** @description Selects only keys without provided tag */ + filterNoTag?: string[]; + /** + * @description Selects only keys, where translation in provided langs is in outdated state + * @example en-US + */ + filterOutdatedLanguage?: string[]; + /** + * @description Selects only keys, where translation in provided langs is not in outdated state + * @example en-US + */ + filterNotOutdatedLanguage?: string[]; + /** + * @description Selects only key affected by activity with specidfied revision ID + * @example 1234567 + */ + filterRevisionId?: number[]; + /** @description Select only keys which were not successfully translated by batch job with provided id */ + filterFailedKeysOfJob?: number; + /** @description Select only keys which are in specified task */ + filterTaskNumber?: number[]; + /** @description Filter task keys which are `not done` */ + filterTaskKeysNotDone?: boolean; + /** @description Filter task keys which are `done` */ + filterTaskKeysDone?: boolean; + /** @description Filter keys with unresolved comments in lang */ + filterHasUnresolvedCommentsInLang?: string[]; + /** @description Filter keys with any comments in lang */ + filterHasCommentsInLang?: string[]; + /** + * @description Filter key translations with labels + * @example labelId1,labelId2 + */ + filterLabel?: string[]; + /** @description Filter keys with any suggestions in lang */ + filterHasSuggestionsInLang?: string[]; + /** @description Filter keys with no suggestions in lang */ + filterHasNoSuggestionsInLang?: string[]; /** @description Zero-based page index (0..N) */ page?: number; /** @description The size of the page to be returned */ @@ -7058,15 +9958,12 @@ export interface operations { /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ sort?: string[]; }; - path: { - languageId: number; - }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelImportTranslationModel"]; + "application/json": components["schemas"]["KeysWithTranslationsPageModel"]; }; }; /** @description Bad Request */ @@ -7096,20 +9993,20 @@ export interface operations { }; }; /** - * Get import language - * @description Returns language prepared to import. + * Update translations for existing key + * @description Sets translations for existing key */ - getImportLanguage_1: { - parameters: { - path: { - languageId: number; + setTranslations_1: { + requestBody: { + content: { + "application/json": components["schemas"]["SetTranslationsWithKeyDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["ImportLanguageModel"]; + "application/json": components["schemas"]["SetTranslationsResponseModel"]; }; }; /** @description Bad Request */ @@ -7139,19 +10036,21 @@ export interface operations { }; }; /** - * Delete language - * @description Deletes language prepared to import. + * Create key or update translations + * @description Sets translations for existing key or creates new key and sets the translations to it. */ - deleteLanguage_1: { - parameters: { - path: { - languageId: number; + createOrUpdateTranslations_1: { + requestBody: { + content: { + "application/json": components["schemas"]["SetTranslationsWithKeyDto"]; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["SetTranslationsResponseModel"]; + }; }; /** @description Bad Request */ 400: { @@ -7180,28 +10079,20 @@ export interface operations { }; }; /** - * Get file issues - * @description Returns issues for uploaded file. + * Create translation comment + * @description Creates a translation comment. Empty translation is stored, when not exists. */ - getImportFileIssues_1: { - parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - }; - path: { - importFileId: number; + create_4: { + requestBody: { + content: { + "application/json": components["schemas"]["TranslationCommentWithLangKeyDto"]; }; }; responses: { - /** @description OK */ - 200: { + /** @description Created */ + 201: { content: { - "application/json": components["schemas"]["PagedModelImportFileIssueModel"]; + "*/*": components["schemas"]["TranslationWithCommentModel"]; }; }; /** @description Bad Request */ @@ -7230,26 +10121,18 @@ export interface operations { }; }; }; - /** - * Get result - * @description Returns the result of preparation. - */ - getImportResult_1: { - parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; + /** Add label to translation by key and language id */ + assignLabel_3: { + requestBody: { + content: { + "application/json": components["schemas"]["TranslationLabelRequest"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelImportLanguageModel"]; + "application/json": components["schemas"]["LabelModel"]; }; }; /** @description Bad Request */ @@ -7277,17 +10160,117 @@ export interface operations { }; }; }; - }; - /** - * Get namespaces - * @description Returns all existing and imported namespaces - */ - getAllNamespaces_3: { + }; + /** + * Select keys + * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. + */ + selectKeys_1: { + parameters: { + query?: { + /** + * @description Translation state in the format: languageTag,state. You can use this parameter multiple times. + * + * When used with multiple states for same language it is applied with logical OR. + * + * When used with multiple languages, it is applied with logical AND. + */ + filterState?: string[]; + /** + * @description Languages to be contained in response. + * + * To add multiple languages, repeat this param (eg. ?languages=en&languages=de) + * @example en + */ + languages?: string[]; + /** @description String to search in key name or translation text */ + search?: string; + /** @description Selects key with provided names. Use this param multiple times to fetch more keys. */ + filterKeyName?: string[]; + /** @description Selects key with provided ID. Use this param multiple times to fetch more keys. */ + filterKeyId?: number[]; + /** @description Selects only keys for which the translation is missing in any returned language. It only filters for translations included in returned languages. */ + filterUntranslatedAny?: boolean; + /** @description Selects only keys, where translation is provided in any language */ + filterTranslatedAny?: boolean; + /** + * @description Selects only keys where the translation is missing for the specified language. The specified language must be included in the returned languages. Otherwise, this filter doesn't apply. + * @example en-US + */ + filterUntranslatedInLang?: string; + /** + * @description Selects only keys, where translation is provided in specified language + * @example en-US + */ + filterTranslatedInLang?: string; + /** + * @description Selects only keys, where translation was auto translated for specified languages. + * @example en-US + */ + filterAutoTranslatedInLang?: string[]; + /** @description Selects only keys with screenshots */ + filterHasScreenshot?: boolean; + /** @description Selects only keys without screenshots */ + filterHasNoScreenshot?: boolean; + /** + * @description Selects only keys with provided namespaces. + * + * To filter default namespace, set to empty string. + */ + filterNamespace?: string[]; + /** + * @description Selects only keys without provided namespaces. + * + * To filter default namespace, set to empty string. + */ + filterNoNamespace?: string[]; + /** @description Selects only keys with provided tag */ + filterTag?: string[]; + /** @description Selects only keys without provided tag */ + filterNoTag?: string[]; + /** + * @description Selects only keys, where translation in provided langs is in outdated state + * @example en-US + */ + filterOutdatedLanguage?: string[]; + /** + * @description Selects only keys, where translation in provided langs is not in outdated state + * @example en-US + */ + filterNotOutdatedLanguage?: string[]; + /** + * @description Selects only key affected by activity with specidfied revision ID + * @example 1234567 + */ + filterRevisionId?: number[]; + /** @description Select only keys which were not successfully translated by batch job with provided id */ + filterFailedKeysOfJob?: number; + /** @description Select only keys which are in specified task */ + filterTaskNumber?: number[]; + /** @description Filter task keys which are `not done` */ + filterTaskKeysNotDone?: boolean; + /** @description Filter task keys which are `done` */ + filterTaskKeysDone?: boolean; + /** @description Filter keys with unresolved comments in lang */ + filterHasUnresolvedCommentsInLang?: string[]; + /** @description Filter keys with any comments in lang */ + filterHasCommentsInLang?: string[]; + /** + * @description Filter key translations with labels + * @example labelId1,labelId2 + */ + filterLabel?: string[]; + /** @description Filter keys with any suggestions in lang */ + filterHasSuggestionsInLang?: string[]; + /** @description Filter keys with no suggestions in lang */ + filterHasNoSuggestionsInLang?: string[]; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["CollectionModelImportNamespaceModel"]; + "application/json": components["schemas"]["SelectAllResponse"]; }; }; /** @description Bad Request */ @@ -7317,55 +10300,50 @@ export interface operations { }; }; /** - * Get all running and pending batch operations - * @description Returns all running and pending batch operations. Completed batch operations are returned only if they are not older than 1 hour. If user doesn't have permission to view all batch operations, only their operations are returned. + * Get all translations + * @description Returns all translations for specified languages */ - currentJobs_1: { - responses: { - /** @description OK */ - 200: { - content: { - "application/json": components["schemas"]["CollectionModelBatchJobModel"]; - }; - }; - /** @description Bad Request */ - 400: { - content: { - "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; - }; - }; - /** @description Unauthorized */ - 401: { - content: { - "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; - }; - }; - /** @description Forbidden */ - 403: { - content: { - "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; - }; - }; - /** @description Not Found */ - 404: { - content: { - "application/json": components["schemas"]["ErrorResponseTyped"] | components["schemas"]["ErrorResponseBody"]; - }; - }; - }; - }; - /** Get batch operation */ - get_13: { + getAllTranslations_1: { parameters: { + query?: { + /** @description Namespace to return */ + ns?: string; + /** + * @description Delimiter to structure response content. + * + * e.g. For key "home.header.title" would result in {"home": {"header": {"title": "Hello"}}} structure. + * + * When null, resulting file will be a flat key-value object. + */ + structureDelimiter?: string; + /** + * @description Enables filtering of returned keys by their tags. + * Only keys with at least one provided tag will be returned. + * Optional, filtering is not applied if not specified. + * @example [ + * "productionReady", + * "nextRelease" + * ] + */ + filterTag?: string[]; + }; path: { - id: number; + /** + * @description Comma-separated language tags to return translations in. Languages you are not permitted to see will be silently dropped and not returned. + * @example [ + * "en", + * "de", + * "fr" + * ] + */ + languages: string[]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["BatchJobModel"]; + "application/json": string; }; }; /** @description Bad Request */ @@ -7394,8 +10372,11 @@ export interface operations { }; }; }; - /** List batch operations */ - list_4: { + /** + * Get translation comments + * @description Returns translation comments of translation + */ + getAll_6: { parameters: { query?: { /** @description Zero-based page index (0..N) */ @@ -7405,12 +10386,15 @@ export interface operations { /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ sort?: string[]; }; + path: { + translationId: number; + }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PagedModelBatchJobModel"]; + "application/json": components["schemas"]["PagedModelTranslationCommentModel"]; }; }; /** @description Bad Request */ @@ -7439,29 +10423,23 @@ export interface operations { }; }; }; - /** - * Get translation history - * @description Sorting is not supported for supported. It is automatically sorted from newest to oldest. - */ - getTranslationHistory_1: { + /** Create translation comment */ + create_2: { parameters: { - query?: { - /** @description Zero-based page index (0..N) */ - page?: number; - /** @description The size of the page to be returned */ - size?: number; - /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ - sort?: string[]; - }; path: { translationId: number; }; }; + requestBody: { + content: { + "application/json": components["schemas"]["TranslationCommentDto"]; + }; + }; responses: { - /** @description OK */ - 200: { + /** @description Created */ + 201: { content: { - "application/json": components["schemas"]["PagedModelTranslationHistoryModel"]; + "*/*": components["schemas"]["TranslationCommentModel"]; }; }; /** @description Bad Request */ @@ -7490,37 +10468,19 @@ export interface operations { }; }; }; - /** - * Get all translations - * @description Returns all translations for specified languages - */ - getAllTranslations_1: { + /** Get one translation comment */ + get_11: { parameters: { - query?: { - /** @description Namespace to return */ - ns?: string; - /** - * @description Delimiter to structure response content. - * - * e.g. For key "home.header.title" would result in {"home": {"header": {"title": "Hello"}}} structure. - * - * When null, resulting file will be a flat key-value object. - */ - structureDelimiter?: string; - }; path: { - /** - * @description Comma-separated language tags to return translations in. Languages you are not permitted to see will be silently dropped and not returned. - * @example en,de,fr - */ - languages: string[]; + translationId: number; + commentId: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": string; + "application/json": components["schemas"]["TranslationCommentModel"]; }; }; /** @description Bad Request */ @@ -7549,86 +10509,24 @@ export interface operations { }; }; }; - /** - * Select keys - * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. - */ - selectKeys_1: { + /** Update translation comment */ + update_2: { parameters: { - query?: { - /** - * @description Translation state in the format: languageTag,state. You can use this parameter multiple times. - * - * When used with multiple states for same language it is applied with logical OR. - * - * When used with multiple languages, it is applied with logical AND. - */ - filterState?: string[]; - /** - * @description Languages to be contained in response. - * - * To add multiple languages, repeat this param (eg. ?languages=en&languages=de) - * @example en - */ - languages?: string[]; - /** @description String to search in key name or translation text */ - search?: string; - /** @description Selects key with provided names. Use this param multiple times to fetch more keys. */ - filterKeyName?: string[]; - /** @description Selects key with provided ID. Use this param multiple times to fetch more keys. */ - filterKeyId?: number[]; - /** @description Selects only keys for which the translation is missing in any returned language. It only filters for translations included in returned languages. */ - filterUntranslatedAny?: boolean; - /** @description Selects only keys, where translation is provided in any language */ - filterTranslatedAny?: boolean; - /** - * @description Selects only keys where the translation is missing for the specified language. The specified language must be included in the returned languages. Otherwise, this filter doesn't apply. - * @example en-US - */ - filterUntranslatedInLang?: string; - /** - * @description Selects only keys, where translation is provided in specified language - * @example en-US - */ - filterTranslatedInLang?: string; - /** @description Selects only keys with screenshots */ - filterHasScreenshot?: boolean; - /** @description Selects only keys without screenshots */ - filterHasNoScreenshot?: boolean; - /** - * @description Filter namespaces. - * - * To filter default namespace, set to empty string. - */ - filterNamespace?: string[]; - /** @description Selects only keys with provided tag */ - filterTag?: string[]; - /** - * @description Selects only keys, where translation in provided langs is in outdated state - * @example en-US - */ - filterOutdatedLanguage?: string[]; - /** - * @description Selects only keys, where translation in provided langs is not in outdated state - * @example en-US - */ - filterNotOutdatedLanguage?: string[]; - /** - * @description Selects only key affected by activity with specidfied revision ID - * @example 1234567 - */ - filterRevisionId?: number[]; - /** @description Select only keys which were not successfully translated by batch job with provided id */ - filterFailedKeysOfJob?: number; - /** @description Select only keys which are in specified task */ - filterTaskNumber?: number[]; + path: { + commentId: number; + translationId: number; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TranslationCommentDto"]; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["SelectAllResponse"]; + "application/json": components["schemas"]["TranslationCommentModel"]; }; }; /** @description Bad Request */ @@ -7657,87 +10555,18 @@ export interface operations { }; }; }; - /** - * Select keys - * @description Returns all key IDs for specified filter values. This way, you can apply the same filter as in the translation view and get the resulting key IDs for future use. - */ - selectKeys_3: { + /** Delete translation comment */ + delete_3: { parameters: { - query?: { - /** - * @description Translation state in the format: languageTag,state. You can use this parameter multiple times. - * - * When used with multiple states for same language it is applied with logical OR. - * - * When used with multiple languages, it is applied with logical AND. - */ - filterState?: string[]; - /** - * @description Languages to be contained in response. - * - * To add multiple languages, repeat this param (eg. ?languages=en&languages=de) - * @example en - */ - languages?: string[]; - /** @description String to search in key name or translation text */ - search?: string; - /** @description Selects key with provided names. Use this param multiple times to fetch more keys. */ - filterKeyName?: string[]; - /** @description Selects key with provided ID. Use this param multiple times to fetch more keys. */ - filterKeyId?: number[]; - /** @description Selects only keys for which the translation is missing in any returned language. It only filters for translations included in returned languages. */ - filterUntranslatedAny?: boolean; - /** @description Selects only keys, where translation is provided in any language */ - filterTranslatedAny?: boolean; - /** - * @description Selects only keys where the translation is missing for the specified language. The specified language must be included in the returned languages. Otherwise, this filter doesn't apply. - * @example en-US - */ - filterUntranslatedInLang?: string; - /** - * @description Selects only keys, where translation is provided in specified language - * @example en-US - */ - filterTranslatedInLang?: string; - /** @description Selects only keys with screenshots */ - filterHasScreenshot?: boolean; - /** @description Selects only keys without screenshots */ - filterHasNoScreenshot?: boolean; - /** - * @description Filter namespaces. - * - * To filter default namespace, set to empty string. - */ - filterNamespace?: string[]; - /** @description Selects only keys with provided tag */ - filterTag?: string[]; - /** - * @description Selects only keys, where translation in provided langs is in outdated state - * @example en-US - */ - filterOutdatedLanguage?: string[]; - /** - * @description Selects only keys, where translation in provided langs is not in outdated state - * @example en-US - */ - filterNotOutdatedLanguage?: string[]; - /** - * @description Selects only key affected by activity with specidfied revision ID - * @example 1234567 - */ - filterRevisionId?: number[]; - /** @description Select only keys which were not successfully translated by batch job with provided id */ - filterFailedKeysOfJob?: number; - /** @description Select only keys which are in specified task */ - filterTaskNumber?: number[]; + path: { + translationId: number; + commentId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["SelectAllResponse"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -7765,15 +10594,20 @@ export interface operations { }; }; }; - /** Get project daily amount of events */ - getProjectDailyActivity_1: { + /** Set state of translation comment */ + setState_1: { + parameters: { + path: { + translationId: number; + commentId: number; + state: "RESOLUTION_NOT_NEEDED" | "NEEDS_RESOLUTION" | "RESOLVED"; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/hal+json": { - [key: string]: number; - }; + "application/json": components["schemas"]["TranslationCommentModel"]; }; }; /** @description Bad Request */ @@ -7802,13 +10636,21 @@ export interface operations { }; }; }; - /** Get project stats */ - getProjectStats_1: { + /** + * Dismiss auto-translated + * @description Removes "auto translated" indication + */ + dismissAutoTranslatedState_1: { + parameters: { + path: { + translationId: number; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/hal+json": components["schemas"]["ProjectStatsModel"]; + "application/json": components["schemas"]["TranslationModel"]; }; }; /** @description Bad Request */ @@ -7838,15 +10680,28 @@ export interface operations { }; }; /** - * Return current PAK - * @description Returns current Personal Access Token. If the request is not authenticated with a Personal Access Token, it will return 400 response status. + * Get translation history + * @description Sorting is not supported for supported. It is automatically sorted from newest to oldest. */ - getCurrent: { + getTranslationHistory_1: { + parameters: { + query?: { + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + }; + path: { + translationId: number; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["PatWithUserModel"]; + "application/json": components["schemas"]["PagedModelTranslationHistoryModel"]; }; }; /** @description Bad Request */ @@ -7875,18 +10730,19 @@ export interface operations { }; }; }; - /** Get organization by slug */ - get_19: { + /** Add label to translation */ + assignLabel_1: { parameters: { path: { - slug: string; + translationId: number; + labelId: number; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["OrganizationModel"]; + "application/json": components["schemas"]["LabelModel"]; }; }; /** @description Bad Request */ @@ -7915,22 +10771,18 @@ export interface operations { }; }; }; - /** - * Get credit balance for organization - * @description Returns machine translation credit balance for organization - */ - getOrganizationCredits: { + /** Remove label from translation */ + unassignLabel_1: { parameters: { path: { - organizationId: number; + translationId: number; + labelId: number; }; }; responses: { /** @description OK */ 200: { - content: { - "application/json": components["schemas"]["CreditBalanceModel"]; - }; + content: never; }; /** @description Bad Request */ 400: { @@ -7959,15 +10811,21 @@ export interface operations { }; }; /** - * Get current API key info - * @description Returns info the API key which user currently authenticated with. Otherwise responds with 400 status code. + * Set outdated value + * @description Set's "outdated" flag indicating the base translation was changed without updating current translation. */ - getCurrent_1: { + setOutdated_1: { + parameters: { + path: { + translationId: number; + state: boolean; + }; + }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["ApiKeyWithLanguagesModel"]; + "application/json": components["schemas"]["TranslationModel"]; }; }; /** @description Bad Request */ @@ -7996,22 +10854,19 @@ export interface operations { }; }; }; - /** - * Get current permission info - * @description Returns current PAK or PAT permissions for current user, api-key and project - */ - getCurrentPermissions: { + /** Set translation state */ + setTranslationState_1: { parameters: { - query?: { - /** @description Required when using with PAT */ - projectId?: number; + path: { + translationId: number; + state: "TRANSLATED" | "REVIEWED"; }; }; responses: { /** @description OK */ 200: { content: { - "application/json": components["schemas"]["ApiKeyPermissionsModel"]; + "application/json": components["schemas"]["TranslationModel"]; }; }; /** @description Bad Request */ @@ -8040,17 +10895,17 @@ export interface operations { }; }; }; - /** Delete one or multiple keys */ - delete_3: { - parameters: { - path: { - ids: number[]; - }; - }; + /** + * Get used namespaces + * @description Returns all used project namespaces. Response contains default (null) namespace if used. + */ + getUsedNamespaces_1: { responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["CollectionModelUsedNamespaceModel"]; + }; }; /** @description Bad Request */ 400: { @@ -8079,20 +10934,16 @@ export interface operations { }; }; /** - * Remove tag - * @description Removes tag with provided id from key with provided id + * Get user info + * @description Returns information about currently authenticated user. */ - removeTag_1: { - parameters: { - path: { - keyId: number; - tagId: number; - }; - }; + getInfo_2: { responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["PrivateUserAccountModel"]; + }; }; /** @description Bad Request */ 400: { @@ -8120,18 +10971,49 @@ export interface operations { }; }; }; - /** Delete screenshots */ - deleteScreenshots: { + /** Get user tasks */ + getTasks: { parameters: { - path: { - ids: number[]; - keyId: number; + query?: { + /** @description Filter tasks by state */ + filterState?: ("NEW" | "IN_PROGRESS" | "FINISHED" | "CANCELED")[]; + /** @description Filter tasks without state */ + filterNotState?: ("NEW" | "IN_PROGRESS" | "FINISHED" | "CANCELED")[]; + /** @description Filter tasks by assignee */ + filterAssignee?: number[]; + /** @description Filter tasks by type */ + filterType?: ("TRANSLATE" | "REVIEW")[]; + /** @description Filter tasks by id */ + filterId?: number[]; + /** @description Filter tasks without id */ + filterNotId?: number[]; + /** @description Filter tasks by project */ + filterProject?: number[]; + /** @description Filter tasks without project */ + filterNotProject?: number[]; + /** @description Filter tasks by language */ + filterLanguage?: number[]; + /** @description Filter tasks by key */ + filterKey?: number[]; + /** @description Filter tasks by agency */ + filterAgency?: number[]; + /** @description Exclude tasks which were closed before specified timestamp */ + filterNotClosedBefore?: number; + /** @description Zero-based page index (0..N) */ + page?: number; + /** @description The size of the page to be returned */ + size?: number; + /** @description Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. */ + sort?: string[]; + search?: string; }; }; responses: { /** @description OK */ 200: { - content: never; + content: { + "application/json": components["schemas"]["PagedModelTaskWithProjectModel"]; + }; }; /** @description Bad Request */ 400: { @@ -8159,16 +11041,20 @@ export interface operations { }; }; }; - /** Delete uploaded images */ - delete_12: { - parameters: { - path: { - ids: number[]; - }; - }; + /** + * Get information about SSO configuration + * @description Returns information about sso configuration affecting the user. + */ + getSso: { responses: { /** @description OK */ 200: { + content: { + "application/json": components["schemas"]["PublicSsoTenantModel"]; + }; + }; + /** @description No SSO configuration available for this user */ + 204: { content: never; }; /** @description Bad Request */ diff --git a/src/ui/client/client.ts b/src/ui/client/client.ts index 6483a93..e7e57c3 100644 --- a/src/ui/client/client.ts +++ b/src/ui/client/client.ts @@ -4,6 +4,8 @@ import { RequestParamsType, ResponseContent } from "./types"; import { globalState } from "../state/GlobalState"; import { errorToText } from "./errorCodes"; +export let API_VERSION: string | undefined; + type GlobalOptions = { apiUrl?: string; apiKey?: string; @@ -100,6 +102,8 @@ async function customFetch( throw new Error(message); } + const apiVersion = r.headers.get("x-tolgee-version"); + API_VERSION = apiVersion && apiVersion !== "??" ? apiVersion : undefined; return await getResObject(r); }) .catch((e) => { diff --git a/src/ui/views/Push/Push.tsx b/src/ui/views/Push/Push.tsx index 61dca45..cedcd64 100644 --- a/src/ui/views/Push/Push.tsx +++ b/src/ui/views/Push/Push.tsx @@ -11,28 +11,21 @@ import { VerticalSpace, } from "@create-figma-plugin/ui"; -import { components } from "@/ui/client/apiSchema.generated"; import { useApiMutation } from "@/ui/client/useQueryApi"; import { ActionsBottom } from "@/ui/components/ActionsBottom/ActionsBottom"; import { FullPageLoading } from "@/ui/components/FullPageLoading/FullPageLoading"; import { useGlobalActions, useGlobalState } from "@/ui/state/GlobalState"; -import { - getPushChanges, - KeyChanges, - KeyChangeValue, -} from "@/tools/getPushChanges"; +import { getPushChanges, KeyChanges } from "@/tools/getPushChanges"; import { TopBar } from "../../components/TopBar/TopBar"; import { Changes } from "./Changes"; -import { FrameScreenshot, NodeInfo } from "@/types"; +import { NodeInfo } from "@/types"; import { compareNs } from "@/tools/compareNs"; import { getScreenshotsEndpoint } from "@/main/endpoints/getScreenshots"; import { useConnectedNodes } from "@/ui/hooks/useConnectedNodes"; import { useSetNodesDataMutation } from "@/ui/hooks/useSetNodesDataMutation"; import { useAllTranslations } from "@/ui/hooks/useAllTranslations"; - -type ImportKeysResolvableItemDto = - components["schemas"]["ImportKeysResolvableItemDto"]; -type KeyScreenshotDto = components["schemas"]["KeyScreenshotDto"]; +import { usePush } from "./usePush"; +import { UnresolvedConflicts } from "./UnresolvedConflicts"; export const Push: FunctionalComponent = () => { const language = useGlobalState((c) => c.config!.language!); @@ -112,26 +105,11 @@ export const Push: FunctionalComponent = () => { method: "post", }); - const addNewTranslations = useApiMutation({ - url: "/v2/projects/keys/import", - method: "post", - }); - - const addTagsToKeys = useApiMutation({ - url: "/v2/projects/tag-complex", - method: "put", - }); - const uploadImage = useApiMutation({ url: "/v2/image-upload", method: "post", }); - const bigMeta = useApiMutation({ - url: "/v2/projects/big-meta", - method: "post", - }); - const handleGoBack = () => { setRoute("index"); }; @@ -154,149 +132,16 @@ export const Push: FunctionalComponent = () => { setRoute("index"); }; - const handleSubmit = async () => { - const keys: ImportKeysResolvableItemDto[] = []; + const { push, unresolvedConflicts } = usePush(setLoadingStatus); + const unresolvedConflictsSize = unresolvedConflicts?.length ?? 0; + const handleSubmit = async () => { if (!changes) { return; } try { - const screenshotsMap = new Map(); - const requiredScreenshots = uploadScreenshots ? changes.screenshots : []; - - for (const [i, screenshot] of requiredScreenshots.entries()) { - setLoadingStatus( - `Uploading images (${i + 1}/${requiredScreenshots.length})` - ); - const imageBlob = new Blob([screenshot.image.buffer], { - type: "image/png", - }); - const location = `figma-${screenshot.info.id}`; - const infoBlob = new Blob([JSON.stringify({ location })], { - type: "application/json", - }); - const data = await uploadImage.mutateAsync({ - content: { - "multipart/form-data": { - image: imageBlob as any, - info: infoBlob as any, - }, - }, - }); - screenshotsMap.set(screenshot, data.id); - } - - const mapScreenshots = (item: KeyChangeValue): KeyScreenshotDto[] => { - const result: KeyScreenshotDto[] = []; - if (uploadScreenshots) { - item.screenshots.forEach((screenshot) => { - const relevantNodes = screenshot.keys.filter( - ({ key, ns }) => key === item.key && compareNs(ns, item.ns) - ); - - result.push({ - text: item.newValue, - uploadedImageId: screenshotsMap.get(screenshot)!, - positions: relevantNodes.map(({ x, y, width, height }) => { - return { - x, - y, - width, - height, - }; - }), - }); - }); - } - return result; - }; - - setLoadingStatus("Updating keys"); - - changes.unchangedKeys.forEach((item) => { - keys.push({ - name: item.key, - namespace: item.ns || undefined, - screenshots: mapScreenshots(item), - translations: {}, - }); - }); - - changes.changedKeys.forEach((item) => { - keys.push({ - name: item.key, - namespace: item.ns || undefined, - screenshots: mapScreenshots(item), - translations: { - [language]: { - text: item.newValue, - resolution: "OVERRIDE", - }, - }, - }); - }); - - changes.newKeys.forEach((item) => { - keys.push({ - name: item.key, - namespace: item.ns || undefined, - screenshots: mapScreenshots(item), - translations: { - [language]: { text: item.newValue, resolution: "NEW" }, - }, - }); - }); - - await updateTranslations.mutateAsync({ - content: { - "application/json": { - keys, - }, - }, - }); - - // Add tags to keys - if ( - (tolgeeConfig?.addTags ?? false) && - tolgeeConfig?.tags && - tolgeeConfig.tags.length > 0 - ) { - await addTagsToKeys.mutateAsync({ - content: { - "application/json": { - tagFiltered: tolgeeConfig?.tags ?? [], - filterKeys: [ - ...changes.newKeys, - ...changes.unchangedKeys, - ...changes.changedKeys, - ].map((k) => ({ - name: k.key, - namespace: k.ns || undefined, - })), - }, - }, - }); - } - - if (tolgeeConfig?.updateScreenshots ?? true) { - for (const screenshot of changes.screenshots.values()) { - const relatedKeys = screenshot.keys - .map((data) => ({ - keyName: data.key, - namespace: data.ns || undefined, - })) - .slice(0, 100); - await bigMeta.mutateAsync({ - content: { - "application/json": { - relatedKeysInOrder: relatedKeys, - }, - }, - }); - } - } - + await push(changes, uploadScreenshots, language); connectNodes(); setSuccess(true); } catch (e) { @@ -360,11 +205,15 @@ export const Push: FunctionalComponent = () => { ) : success ? (
- Successfully updated {changesSize} key(s) + Successfully updated {changesSize - unresolvedConflictsSize}{" "} + key(s) {uploadScreenshots ? ` and uploaded ${screenshotCount} screenshot(s).` : "."}
+ {unresolvedConflicts && ( + + )} ) : ( - )} diff --git a/src/ui/views/Push/UnresolvedConflicts.css b/src/ui/views/Push/UnresolvedConflicts.css index 2a0a633..0474e14 100644 --- a/src/ui/views/Push/UnresolvedConflicts.css +++ b/src/ui/views/Push/UnresolvedConflicts.css @@ -8,4 +8,9 @@ display: grid; margin-top: 5px; margin-bottom: 20px; +} + +.styledHint { + display: grid; + gap: 10px; } \ No newline at end of file diff --git a/src/ui/views/Push/UnresolvedConflicts.css.d.ts b/src/ui/views/Push/UnresolvedConflicts.css.d.ts index b1da6f3..a953755 100644 --- a/src/ui/views/Push/UnresolvedConflicts.css.d.ts +++ b/src/ui/views/Push/UnresolvedConflicts.css.d.ts @@ -1,6 +1,7 @@ declare const styles: { readonly "conflicts": string; readonly "container": string; + readonly "styledHint": string; }; export = styles; diff --git a/src/ui/views/Push/UnresolvedConflicts.tsx b/src/ui/views/Push/UnresolvedConflicts.tsx index a04f64b..310d214 100644 --- a/src/ui/views/Push/UnresolvedConflicts.tsx +++ b/src/ui/views/Push/UnresolvedConflicts.tsx @@ -1,12 +1,14 @@ import { components } from "@/ui/client/apiSchema.generated"; import { h } from "preact"; import styles from "./UnresolvedConflicts.css"; +import { Button } from "@create-figma-plugin/ui"; type SimpleImportConflictResult = components["schemas"]["SimpleImportConflictResult"]; type Props = { conflicts: SimpleImportConflictResult[]; + onOverride: () => void; }; function renderKey(key: SimpleImportConflictResult, note?: string) { @@ -17,7 +19,7 @@ function renderKey(key: SimpleImportConflictResult, note?: string) { return `${`${key.keyName}`}${namespace}${renderedNote}`; } -export const UnresolvedConflicts = ({ conflicts }: Props) => { +export const UnresolvedConflicts = ({ conflicts, onOverride }: Props) => { const someOverridable = Boolean(conflicts.find((c) => c.isOverridable)); return ( @@ -31,9 +33,13 @@ export const UnresolvedConflicts = ({ conflicts }: Props) => { ))} {someOverridable && ( -
- HINT: Overridable translations can be updated with the "Override all" - setting +
+ You have permissions to override some translations (marked as + overridable), but it's not recommended, because these translations are + protected +
)}
diff --git a/src/ui/views/Push/usePush.ts b/src/ui/views/Push/usePush.ts index 9b8b605..9eb99a7 100644 --- a/src/ui/views/Push/usePush.ts +++ b/src/ui/views/Push/usePush.ts @@ -64,7 +64,8 @@ export function usePush(setLoadingStatus: (message?: string) => void) { async function push( changes: KeyChanges, uploadScreenshots: boolean, - language: string + language: string, + override: boolean ) { const screenshotsMap = new Map(); const requiredScreenshots = uploadScreenshots ? changes.screenshots : []; @@ -152,6 +153,7 @@ export function usePush(setLoadingStatus: (message?: string) => void) { "application/json": { errorOnUnresolvedConflict: false, keys, + overrideMode: override ? "ALL" : "RECOMMENDED", }, }, }); diff --git a/tsconfig.json b/tsconfig.json index a1d82b5..ced4e60 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "module": "commonjs", "noEmit": true, "baseUrl": "./src", + "resolveJsonModule": true, "paths": { "@/*": ["*"], "react": ["./node_modules/preact/compat"], From fc7c7ec162f2cda66186e22be979b6889304540e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 13:26:20 +0200 Subject: [PATCH 03/16] fix: remove conflicting dependency --- package-lock.json | 11 ----------- package.json | 1 - 2 files changed, 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index bfe2da6..cf5aec6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,6 @@ "colors": "^1.4.0", "concurrently": "^7.6.0", "cypress": "^14.3.3", - "cypress-iframe": "^1.0.1", "esbuild": "^0.17.8", "eslint": "^8.31.0", "eslint-config-preact": "^1.3.0", @@ -5191,16 +5190,6 @@ "node": "^18.0.0 || ^20.0.0 || >=22.0.0" } }, - "node_modules/cypress-iframe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cypress-iframe/-/cypress-iframe-1.0.1.tgz", - "integrity": "sha512-Ne+xkZmWMhfq3x6wbfzK/SzsVTCrJru3R3cLXsoSAZyfUtJDamXyaIieHXeea3pQDXF4wE2w4iUuvCYHhoD31g==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/cypress": "^1.1.0" - } - }, "node_modules/cypress/node_modules/ci-info": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", diff --git a/package.json b/package.json index f3a5d75..eccf7db 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "colors": "^1.4.0", "concurrently": "^7.6.0", "cypress": "^14.3.3", - "cypress-iframe": "^1.0.1", "esbuild": "^0.17.8", "eslint": "^8.31.0", "eslint-config-preact": "^1.3.0", From 782e79337c979d334216d23b450537c21812947d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 13:43:57 +0200 Subject: [PATCH 04/16] chore: remove cypress-iframe --- cypress/support/commands.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 5c4f264..dc82af3 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/no-namespace */ -import "cypress-iframe"; Cypress.Commands.add( "closestDcy", From 71a9fe2bdd6d714d9542666d7590c71553662f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 13:57:00 +0200 Subject: [PATCH 05/16] chore: remove cypress-iframe --- cypress/common/tools.ts | 2 +- cypress/e2e/copyView.cy.ts | 37 +++++++----- cypress/e2e/index.cy.ts | 34 ++++++----- cypress/e2e/language.cy.ts | 10 ++-- cypress/e2e/pageSetup.cy.ts | 15 +++-- cypress/e2e/pull.cy.ts | 26 ++++---- cypress/e2e/push.cy.ts | 2 +- cypress/e2e/settings.cy.ts | 102 +++++++++++++++++++------------- cypress/e2e/stringDetails.cy.ts | 22 ++++--- 9 files changed, 142 insertions(+), 108 deletions(-) diff --git a/cypress/common/tools.ts b/cypress/common/tools.ts index 7038d7d..fc18882 100644 --- a/cypress/common/tools.ts +++ b/cypress/common/tools.ts @@ -5,5 +5,5 @@ const ORIGIN = "http://localhost:3000"; export const visitWithState = (data: Partial) => { cy.visit(`${ORIGIN}${createShortcutUrl(data)}`); cy.wait(100); - cy.frameLoaded("#plugin_iframe"); + cy.iframeBody().should("exist"); }; diff --git a/cypress/e2e/copyView.cy.ts b/cypress/e2e/copyView.cy.ts index d5d2a6a..a246989 100644 --- a/cypress/e2e/copyView.cy.ts +++ b/cypress/e2e/copyView.cy.ts @@ -7,7 +7,7 @@ describe("Copy view", () => { config: PAGE_COPY, }); - cy.iframe().contains("Page copy - keys").should("be.visible"); + cy.iframeBody().contains("Page copy - keys").should("be.visible"); }); it("shows language if language set", () => { @@ -15,7 +15,7 @@ describe("Copy view", () => { config: PAGE_COPY_LANGUAGE, }); - cy.iframe().contains("Page copy - cs").should("be.visible"); + cy.iframeBody().contains("Page copy - cs").should("be.visible"); }); it("shows unconnected node correctly", () => { @@ -26,14 +26,14 @@ describe("Copy view", () => { allNodes: nodes, }); - cy.iframe().contains("Test node").should("be.visible"); + cy.iframeBody().contains("Test node").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_text") .contains("Test node") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_key") .contains("Not connected") .should("be.visible"); @@ -53,19 +53,21 @@ describe("Copy view", () => { allNodes: nodes, }); - cy.iframe().contains("Test node").should("be.visible"); + cy.iframeBody().contains("Test node").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_text") .contains("Test node") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_key") .contains("test_key") .should("be.visible"); - cy.iframe().findDcy("general_node_list_row_namespace").should("be.empty"); + cy.iframeBody() + .findDcy("general_node_list_row_namespace") + .should("be.empty"); }); it("shows connected node with namespace", () => { @@ -83,19 +85,19 @@ describe("Copy view", () => { allNodes: nodes, }); - cy.iframe().contains("Test node").should("be.visible"); + cy.iframeBody().contains("Test node").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_text") .contains("Test node") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_key") .contains("test_key") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_namespace") .contains("test_ns") .should("be.visible"); @@ -115,10 +117,13 @@ describe("Copy view", () => { allNodes: connectedCzech, }); - cy.iframe().contains("Na cestě").should("be.visible"); + cy.iframeBody().contains("Na cestě").should("be.visible"); - cy.iframe().findDcy("copy_view_pull_button").should("be.visible").click(); + cy.iframeBody() + .findDcy("copy_view_pull_button") + .should("be.visible") + .click(); - cy.iframe().contains("Na cestu").should("be.visible"); + cy.iframeBody().contains("Na cestu").should("be.visible"); }); }); diff --git a/cypress/e2e/index.cy.ts b/cypress/e2e/index.cy.ts index d10631f..13170e8 100644 --- a/cypress/e2e/index.cy.ts +++ b/cypress/e2e/index.cy.ts @@ -10,19 +10,19 @@ describe("Index", () => { allNodes: nodes, }); - cy.iframe().contains("Test node").should("be.visible"); + cy.iframeBody().contains("Test node").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_text") .contains("Test node") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_key") .find("input") .should("have.value", "test_key"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_namespace") .find("select") .should("have.value", ""); @@ -36,19 +36,19 @@ describe("Index", () => { allNodes: nodes, }); - cy.iframe().contains("Test node").should("be.visible"); + cy.iframeBody().contains("Test node").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_text") .contains("Test node") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_key") .find("input") .should("have.value", "test_key"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_namespace") .find("select") .should("not.exist"); @@ -64,19 +64,21 @@ describe("Index", () => { allNodes: nodes, }); - cy.iframe().contains("Test node").should("be.visible"); + cy.iframeBody().contains("Test node").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_text") .contains("Test node") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_key") .contains("test_key") .should("be.visible"); - cy.iframe().findDcy("general_node_list_row_namespace").should("be.empty"); + cy.iframeBody() + .findDcy("general_node_list_row_namespace") + .should("be.empty"); }); it("shows connected node with namespace", () => { @@ -94,19 +96,19 @@ describe("Index", () => { allNodes: nodes, }); - cy.iframe().contains("Test node").should("be.visible"); + cy.iframeBody().contains("Test node").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_text") .contains("Test node") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_key") .contains("test_key") .should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("general_node_list_row_namespace") .contains("test_ns") .should("be.visible"); diff --git a/cypress/e2e/language.cy.ts b/cypress/e2e/language.cy.ts index 3474e90..f3e9634 100644 --- a/cypress/e2e/language.cy.ts +++ b/cypress/e2e/language.cy.ts @@ -16,11 +16,11 @@ describe("Change language", () => { allNodes: nodes, }); - cy.frameLoaded("#plugin_iframe"); - cy.wait(100); - cy.iframe().findDcy("index_language_select").select("de"); + cy.iframeBody().findDcy("index_language_select").select("de"); - cy.iframe().contains("This action will replace translations in 1 text(s)"); - cy.iframe().findDcy("pull_submit_button").should("exist").click(); + cy.iframeBody().contains( + "This action will replace translations in 1 text(s)" + ); + cy.iframeBody().findDcy("pull_submit_button").should("exist").click(); }); }); diff --git a/cypress/e2e/pageSetup.cy.ts b/cypress/e2e/pageSetup.cy.ts index 76fa5bb..7307b1b 100644 --- a/cypress/e2e/pageSetup.cy.ts +++ b/cypress/e2e/pageSetup.cy.ts @@ -7,20 +7,25 @@ describe("Page setup", () => { config: NEW_PAGE, }); - cy.iframe().contains("Page setup").should("be.visible"); + cy.iframeBody().contains("Page setup").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("page_setup_button_save") .should("be.visible") .should("be.disabled"); - cy.iframe() + cy.iframeBody() .findDcy("page_setup_input_language") .should("be.visible") .select("cs"); - cy.iframe().findDcy("page_setup_button_save").should("be.visible").click(); + cy.iframeBody() + .findDcy("page_setup_button_save") + .should("be.visible") + .click(); - cy.iframe().contains("Select texts for translation").should("be.visible"); + cy.iframeBody() + .contains("Select texts for translation") + .should("be.visible"); }); }); diff --git a/cypress/e2e/pull.cy.ts b/cypress/e2e/pull.cy.ts index 1d6283a..7094a2d 100644 --- a/cypress/e2e/pull.cy.ts +++ b/cypress/e2e/pull.cy.ts @@ -16,12 +16,11 @@ describe("Pull", () => { allNodes: nodes, }); - cy.frameLoaded("#plugin_iframe"); - cy.iframe().contains("On the road").should("exist"); - cy.iframe().findDcy("index_pull_button").click(); + cy.iframeBody().contains("On the road").should("exist"); + cy.iframeBody().findDcy("index_pull_button").click(); - cy.iframe().contains("Everything up to date").should("be.visible"); - cy.iframe().findDcy("pull_ok_button").should("be.visible").click(); + cy.iframeBody().contains("Everything up to date").should("be.visible"); + cy.iframeBody().findDcy("pull_ok_button").should("be.visible").click(); }); it("pulling change", () => { @@ -43,20 +42,19 @@ describe("Pull", () => { allNodes: nodes, }); - cy.frameLoaded("#plugin_iframe"); - cy.iframe().contains("On the old road").should("exist"); - cy.iframe().findDcy("index_pull_button").click(); + cy.iframeBody().contains("On the old road").should("exist"); + cy.iframeBody().findDcy("index_pull_button").click(); - cy.iframe() + cy.iframeBody() .contains("This action will replace translations in 1") .should("be.visible"); - cy.iframe().contains("Missing keys").should("be.visible"); + cy.iframeBody().contains("Missing keys").should("be.visible"); - cy.iframe().contains("nonexistant-key").should("be.visible"); + cy.iframeBody().contains("nonexistant-key").should("be.visible"); - cy.iframe().findDcy("pull_submit_button").should("be.visible").click(); + cy.iframeBody().findDcy("pull_submit_button").should("be.visible").click(); - cy.iframe().contains("On the road").should("exist"); - cy.iframe().contains("Connected to nonexistant").should("exist"); + cy.iframeBody().contains("On the road").should("exist"); + cy.iframeBody().contains("Connected to nonexistant").should("exist"); }); }); diff --git a/cypress/e2e/push.cy.ts b/cypress/e2e/push.cy.ts index 7a6520a..7403e32 100644 --- a/cypress/e2e/push.cy.ts +++ b/cypress/e2e/push.cy.ts @@ -111,7 +111,7 @@ describe("Push", () => { cy.iframeBody().findDcy("push_finish_button").should("be.visible").click(); }); - it.only("doesn't override protected translation by default", () => { + it("doesn't override protected translation by default", () => { cy.wrap( (async () => { await createProject({ translationProtection: "PROTECT_REVIEWED" }); diff --git a/cypress/e2e/settings.cy.ts b/cypress/e2e/settings.cy.ts index ff5f375..0f013ea 100644 --- a/cypress/e2e/settings.cy.ts +++ b/cypress/e2e/settings.cy.ts @@ -7,35 +7,35 @@ describe("Settings", () => { config: {}, }); - cy.iframe().findDcy("top_bar_back_button").should("not.exist"); - cy.iframe().findDcy("settings_button_close").should("not.exist"); + cy.iframeBody().findDcy("top_bar_back_button").should("not.exist"); + cy.iframeBody().findDcy("settings_button_close").should("not.exist"); }); it("works when filling empty", () => { visitWithState({}); - cy.iframe() + cy.iframeBody() .findDcy("settings_input_api_url") .type(DEFAULT_CREDENTIALS.apiUrl); - cy.iframe() + cy.iframeBody() .findDcy("settings_input_api_key") .type(DEFAULT_CREDENTIALS.apiKey); - cy.iframe().findDcy("settings_button_validate").click(); + cy.iframeBody().findDcy("settings_button_validate").click(); - cy.iframe() + cy.iframeBody() .contains("examples was successfully connected") .should("be.visible"); - cy.iframe().contains("Current language").should("be.visible"); + cy.iframeBody().contains("Current language").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("settings_input_language") .should("be.visible") .select("en"); - cy.iframe().findDcy("settings_button_save").click(); + cy.iframeBody().findDcy("settings_button_save").click(); }); it("works when filling existing", () => { @@ -50,31 +50,34 @@ describe("Settings", () => { }, }); - cy.iframe().findDcy("index_settings_button").should("be.visible").click(); - cy.iframe().contains("Settings").should("be.visible"); + cy.iframeBody() + .findDcy("index_settings_button") + .should("be.visible") + .click(); + cy.iframeBody().contains("Settings").should("be.visible"); - cy.iframe().findDcy("settings_expandable_project").should("be.visible"); + cy.iframeBody().findDcy("settings_expandable_project").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("settings_input_api_url") .type(DEFAULT_CREDENTIALS.apiUrl); - cy.iframe() + cy.iframeBody() .findDcy("settings_input_api_key") .type(DEFAULT_CREDENTIALS.apiKey); - cy.iframe().findDcy("settings_button_validate").click(); + cy.iframeBody().findDcy("settings_button_validate").click(); - cy.iframe() + cy.iframeBody() .contains("examples was successfully connected") .should("be.visible"); - cy.iframe().contains("Current language").should("be.visible"); + cy.iframeBody().contains("Current language").should("be.visible"); - cy.iframe() + cy.iframeBody() .findDcy("settings_input_language") .should("be.visible") .select("en"); - cy.iframe().findDcy("settings_button_save").click(); + cy.iframeBody().findDcy("settings_button_save").click(); cy.contains("Select texts for translation").should("be.visible"); }); @@ -91,40 +94,52 @@ describe("Settings", () => { }, }); - cy.iframe().findDcy("index_settings_button").should("be.visible").click(); - cy.iframe().contains("Settings").should("be.visible"); - - cy.iframe().findDcy("settings_expandable_strings").should("exist").click(); - cy.iframe().findDcy("settings_checkbox_prefill_key_name").should("exist"); - cy.iframe().findDcy("settings_checkbox_prefill_key_name").click(); + cy.iframeBody() + .findDcy("index_settings_button") + .should("be.visible") + .click(); + cy.iframeBody().contains("Settings").should("be.visible"); + + cy.iframeBody() + .findDcy("settings_expandable_strings") + .should("exist") + .click(); + cy.iframeBody() + .findDcy("settings_checkbox_prefill_key_name") + .should("exist"); + cy.iframeBody().findDcy("settings_checkbox_prefill_key_name").click(); // Test key format editor - check if it exists first - cy.iframe().findDcy("global-editor").should("exist"); + cy.iframeBody().findDcy("global-editor").should("exist"); // Test variable casing dropdown - only if it's visible - cy.iframe().findDcy("settings_dropdown_variable_casing").should("exist"); + cy.iframeBody() + .findDcy("settings_dropdown_variable_casing") + .should("exist"); // Verify preview exists - cy.iframe().findDcy("settings_text_preview").should("not.exist"); + cy.iframeBody().findDcy("settings_text_preview").should("not.exist"); - cy.iframe().findDcy("global-editor").click(); + cy.iframeBody().findDcy("global-editor").click(); cy.wait(150); - cy.iframe().findDcy("global-editor").type("{enter}"); - cy.iframe().findDcy("settings_text_preview").should("exist"); + cy.iframeBody().findDcy("global-editor").type("{enter}"); + cy.iframeBody().findDcy("settings_text_preview").should("exist"); // Verify My Artboard is in the preview - cy.iframe() + cy.iframeBody() .findDcy("settings_text_preview") .should("contain", "My Artboard"); // Test ignore settings - only if they're visible - cy.iframe().findDcy("settings_checkbox_ignore_text_layers").should("exist"); + cy.iframeBody() + .findDcy("settings_checkbox_ignore_text_layers") + .should("exist"); // Test ignore prefix input - only if it's visible - cy.iframe().findDcy("settings_input_ignore_prefix").should("exist"); + cy.iframeBody().findDcy("settings_input_ignore_prefix").should("exist"); // Save settings - cy.iframe().findDcy("settings_button_save").click(); + cy.iframeBody().findDcy("settings_button_save").click(); cy.contains("Select texts for translation").should("be.visible"); }); @@ -139,19 +154,24 @@ describe("Settings", () => { pageInfo: true, }, }); - cy.iframe().findDcy("index_settings_button").should("be.visible").click(); - cy.iframe().contains("Settings").should("be.visible"); + cy.iframeBody() + .findDcy("index_settings_button") + .should("be.visible") + .click(); + cy.iframeBody().contains("Settings").should("be.visible"); - cy.iframe().findDcy("settings_expandable_push").should("exist").click(); + cy.iframeBody().findDcy("settings_expandable_push").should("exist").click(); // Test update screenshots checkbox - cy.iframe().findDcy("settings_checkbox_update_screenshots").should("exist"); + cy.iframeBody() + .findDcy("settings_checkbox_update_screenshots") + .should("exist"); // Test add tags checkbox - cy.iframe().findDcy("settings_checkbox_add_tags").should("exist"); + cy.iframeBody().findDcy("settings_checkbox_add_tags").should("exist"); // Save settings - cy.iframe().findDcy("settings_button_save").click(); + cy.iframeBody().findDcy("settings_button_save").click(); cy.contains("Select texts for translation").should("be.visible"); }); }); diff --git a/cypress/e2e/stringDetails.cy.ts b/cypress/e2e/stringDetails.cy.ts index 78751ca..ad8264f 100644 --- a/cypress/e2e/stringDetails.cy.ts +++ b/cypress/e2e/stringDetails.cy.ts @@ -21,13 +21,13 @@ describe("String details", () => { allNodes: nodes, }); - cy.iframe().contains("test_key").should("be.visible"); + cy.iframeBody().contains("test_key").should("be.visible"); - cy.iframe().findDcy("key_options_button").should("be.visible").click(); + cy.iframeBody().findDcy("key_options_button").should("be.visible").click(); - cy.iframe().findDcy("dropdown").should("be.visible"); + cy.iframeBody().findDcy("dropdown").should("be.visible"); - cy.iframe().findDcy("string_details_cy").should("be.visible"); + cy.iframeBody().findDcy("string_details_cy").should("be.visible"); }); it("should show the correct preview text", () => { @@ -46,7 +46,7 @@ describe("String details", () => { }); // Should show the key as preview text - cy.iframe() + cy.iframeBody() .findDcy("string_details_preview_text") .should("be.visible") .contains("Test node"); @@ -105,9 +105,11 @@ describe("String details", () => { allNodes: nodes, }); - cy.iframe().contains("Advanced text format detected").should("be.visible"); + cy.iframeBody() + .contains("Advanced text format detected") + .should("be.visible"); - cy.iframe().find('[class^="_warningContainer_"]').should("be.visible"); + cy.iframeBody().find('[class^="_warningContainer_"]').should("be.visible"); }); it("should show positive warning on plural keys", () => { @@ -127,9 +129,11 @@ describe("String details", () => { allNodes: nodes, }); - cy.iframe().contains("Advanced text format detected").should("be.visible"); + cy.iframeBody() + .contains("Advanced text format detected") + .should("be.visible"); - cy.iframe() + cy.iframeBody() .find('[class^="_warningNoticeContainer_"]') .should("be.visible"); }); From ddb9635f01f936708b945cbd6eb26209d42e2067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 14:17:15 +0200 Subject: [PATCH 06/16] chore: more retries --- cypress.config.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/cypress.config.mjs b/cypress.config.mjs index 17161e3..6c3b6a2 100644 --- a/cypress.config.mjs +++ b/cypress.config.mjs @@ -1,6 +1,7 @@ import { defineConfig } from "cypress"; export default defineConfig({ + retries: 3, e2e: { setupNodeEvents(on, config) { // implement node event listeners here From 17bc30bbec60c8362b3a1ee9b6b62bc415008089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 15:35:23 +0200 Subject: [PATCH 07/16] fix: make e2e more reliable --- cypress.config.mjs | 1 - cypress/common/tools.ts | 3 +-- cypress/e2e/push.cy.ts | 17 ++++++++++++----- cypress/support/commands.ts | 21 ++++++++++++++++++++- package-lock.json | 2 +- package.json | 2 +- 6 files changed, 35 insertions(+), 11 deletions(-) diff --git a/cypress.config.mjs b/cypress.config.mjs index 6c3b6a2..17161e3 100644 --- a/cypress.config.mjs +++ b/cypress.config.mjs @@ -1,7 +1,6 @@ import { defineConfig } from "cypress"; export default defineConfig({ - retries: 3, e2e: { setupNodeEvents(on, config) { // implement node event listeners here diff --git a/cypress/common/tools.ts b/cypress/common/tools.ts index fc18882..9b9e43e 100644 --- a/cypress/common/tools.ts +++ b/cypress/common/tools.ts @@ -4,6 +4,5 @@ const ORIGIN = "http://localhost:3000"; export const visitWithState = (data: Partial) => { cy.visit(`${ORIGIN}${createShortcutUrl(data)}`); - cy.wait(100); - cy.iframeBody().should("exist"); + cy.iframeReady(); }; diff --git a/cypress/e2e/push.cy.ts b/cypress/e2e/push.cy.ts index 7403e32..06af430 100644 --- a/cypress/e2e/push.cy.ts +++ b/cypress/e2e/push.cy.ts @@ -116,7 +116,6 @@ describe("Push", () => { (async () => { await createProject({ translationProtection: "PROTECT_REVIEWED" }); await markTitleAsReviewed(); - console.log({ pak }); })() ).then(() => { const nodes = [ @@ -130,7 +129,8 @@ describe("Push", () => { selectedNodes: nodes, allNodes: nodes, }); - cy.iframeBody().contains("On the road updated").should("exist"); + + cy.iframeBody().contains("On the road updated").should("be.visible"); cy.iframeBody().findDcy("index_push_button").should("be.visible").click(); cy.iframeBody() @@ -141,10 +141,17 @@ describe("Push", () => { cy.iframeBody().contains( "Successfully updated 0 key(s) and uploaded 0 screenshot(s)." ); - cy.iframeBody().contains("Some translations cannot be updated:"); - cy.iframeBody().contains("on-the-road-title (overridable)"); + cy.iframeBody() + .contains("Some translations cannot be updated:") + .should("be.visible"); + cy.iframeBody() + .contains("on-the-road-title (overridable)") + .should("be.visible"); - cy.iframeBody().findDcy("push-override-all-button").click(); + cy.iframeBody() + .findDcy("push-override-all-button") + .should("be.visible") + .click(); cy.iframeBody().findDcy("push-override-all-button").should("not.exist"); }); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index dc82af3..da5270d 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -33,10 +33,27 @@ declare global { * @example cy.iframeBody().find('button').click() */ iframeBody(): Chainable>; + + iframeReady(): void; } } } +Cypress.Commands.add("iframeReady", () => { + return cy + .get('iframe[data-cy="plugin_iframe"]', { timeout: 15000 }) + .should("be.visible") + .its("0.contentDocument") + .should("exist") + .then((doc: Document) => { + // Wait for readyState=complete AND #root present + // Both checks are retried by Cypress + cy.wrap(doc).its("readyState").should("eq", "complete"); + cy.wrap(doc.body).should("exist"); + cy.wrap(doc).find("#root", { timeout: 15000 }).should("exist"); + }); +}); + Cypress.Commands.add("iframeDocument", () => { return cy .get('iframe[data-cy="plugin_iframe"]') @@ -49,7 +66,9 @@ Cypress.Commands.add("iframeBody", () => { .iframeDocument() .its("body") .should("not.be.undefined") - .then((e) => cy.wrap(e as HTMLBodyElement)); + .then((e) => { + return cy.wrap(e as HTMLBodyElement); + }); }); // Export {} to ensure this file is treated as a module by TypeScript. diff --git a/package-lock.json b/package-lock.json index cf5aec6..4005a7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "@typescript-eslint/parser": "^5.48.1", "colors": "^1.4.0", "concurrently": "^7.6.0", - "cypress": "^14.3.3", + "cypress": "^14.5.4", "esbuild": "^0.17.8", "eslint": "^8.31.0", "eslint-config-preact": "^1.3.0", diff --git a/package.json b/package.json index eccf7db..55cf7c2 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "@typescript-eslint/parser": "^5.48.1", "colors": "^1.4.0", "concurrently": "^7.6.0", - "cypress": "^14.3.3", + "cypress": "^14.5.4", "esbuild": "^0.17.8", "eslint": "^8.31.0", "eslint-config-preact": "^1.3.0", From 0e9364985d930afb8a1b7b1aaf7b6e69d52338e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 15:54:14 +0200 Subject: [PATCH 08/16] chore: make e2e tests more resillient --- cypress/common/tools.ts | 2 ++ cypress/support/commands.ts | 1 + scripts/runAfterApp.ts | 69 ++++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/cypress/common/tools.ts b/cypress/common/tools.ts index 9b9e43e..6384c26 100644 --- a/cypress/common/tools.ts +++ b/cypress/common/tools.ts @@ -5,4 +5,6 @@ const ORIGIN = "http://localhost:3000"; export const visitWithState = (data: Partial) => { cy.visit(`${ORIGIN}${createShortcutUrl(data)}`); cy.iframeReady(); + cy.wait(200); + cy.iframeReady(); }; diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index da5270d..a590512 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -55,6 +55,7 @@ Cypress.Commands.add("iframeReady", () => { }); Cypress.Commands.add("iframeDocument", () => { + cy.iframeReady(); return cy .get('iframe[data-cy="plugin_iframe"]') .its("0.contentDocument") diff --git a/scripts/runAfterApp.ts b/scripts/runAfterApp.ts index 52c2bed..52deaf4 100644 --- a/scripts/runAfterApp.ts +++ b/scripts/runAfterApp.ts @@ -4,36 +4,24 @@ import colors from "colors"; import terminate from "terminate"; import http from "http"; +const PORT = 8080; + function systemColor(text: string) { return colors.grey(text); } -const afterArgs = process.argv.slice(2); - -const dockerComposeProcess = spawn( - "docker", - ["compose", "up", "--force-recreate"], - { - cwd: path.join(__dirname, "..", "cypress"), - } -); - -const appProcesses = [dockerComposeProcess]; +const appProcesses: ChildProcess[] = []; const afterProcesses: ChildProcess[] = []; -dockerComposeProcess.stdout.on("data", (data) => { - process.stdout.write(data); -}); - -dockerComposeProcess.stderr.pipe(process.stderr); +const afterArgs = process.argv.slice(2); function checkServerStatus(callback: () => void) { const MAX_RETRIES = 300; // 300 seconds timeout let retryCount = 0; const options = { host: "localhost", - port: 8080, + port: PORT, path: "/", // Or any other endpoint timeout: 2000, }; @@ -86,10 +74,6 @@ function runAfterProcesses() { } } -checkServerStatus(() => { - runAfterProcesses(); -}); - let isFinishing = false; async function finish(code: number) { if (isFinishing) { @@ -135,3 +119,46 @@ process.on("SIGINT", () => { appProcesses.forEach((p) => p.on("close", (code) => onChildFinish(getProcessName(p), code || 0)) ); + +async function main() { + let isRunning = false; + + try { + const response: any = await fetch( + `http://localhost:${PORT}/actuator/health` + ).then((r) => r.json()); + + if (response.status === "UP") { + console.log(`Backend already running on port ${PORT}`); + isRunning = true; + } + } catch { + // backend not running - continue + } + + if (!isRunning) { + const dockerComposeProcess = spawn( + "docker", + ["compose", "up", "--force-recreate"], + { + cwd: path.join(__dirname, "..", "cypress"), + } + ); + + appProcesses.push(dockerComposeProcess); + + dockerComposeProcess.stdout.on("data", (data) => { + process.stdout.write(data); + }); + + dockerComposeProcess.stderr.pipe(process.stderr); + + checkServerStatus(() => { + runAfterProcesses(); + }); + } else { + runAfterProcesses(); + } +} + +main(); From 5dcacd9cc9a043b57fe720e50486ca8a097113ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 16:54:11 +0200 Subject: [PATCH 09/16] chore: e2e tests --- cypress/e2e/push.cy.ts | 86 ++++++++++++++++++------------------- cypress/support/commands.ts | 1 - src/ui/views/Push/Push.tsx | 2 +- src/web/ui.tsx | 4 +- 4 files changed, 43 insertions(+), 50 deletions(-) diff --git a/cypress/e2e/push.cy.ts b/cypress/e2e/push.cy.ts index 06af430..ae86a31 100644 --- a/cypress/e2e/push.cy.ts +++ b/cypress/e2e/push.cy.ts @@ -13,12 +13,13 @@ let client: TolgeeClient; let pak: string; describe("Push", () => { - beforeEach(() => { - cy.wrap(createProject()); + beforeEach(async () => { + await createProject({ translationProtection: "PROTECT_REVIEWED" }); + await markTitleAsReviewed(); }); afterEach(() => { - // deleteProject(client); + deleteProject(client); }); it("shows differences correctly", () => { @@ -112,49 +113,44 @@ describe("Push", () => { }); it("doesn't override protected translation by default", () => { - cy.wrap( - (async () => { - await createProject({ translationProtection: "PROTECT_REVIEWED" }); - await markTitleAsReviewed(); - })() - ).then(() => { - const nodes = [ - createTestNode({ - text: "On the road updated", - key: "on-the-road-title", - }), - ]; - visitWithState({ - config: { ...getCredentials(), updateScreenshots: false }, - selectedNodes: nodes, - allNodes: nodes, - }); - - cy.iframeBody().contains("On the road updated").should("be.visible"); - - cy.iframeBody().findDcy("index_push_button").should("be.visible").click(); - cy.iframeBody() - .findDcy("push_finish_button") - .should("be.visible") - .click(); - - cy.iframeBody().contains( - "Successfully updated 0 key(s) and uploaded 0 screenshot(s)." - ); - cy.iframeBody() - .contains("Some translations cannot be updated:") - .should("be.visible"); - cy.iframeBody() - .contains("on-the-road-title (overridable)") - .should("be.visible"); - - cy.iframeBody() - .findDcy("push-override-all-button") - .should("be.visible") - .click(); - - cy.iframeBody().findDcy("push-override-all-button").should("not.exist"); + const nodes = [ + createTestNode({ + text: "On the road updated", + key: "on-the-road-title", + }), + ]; + visitWithState({ + config: { ...getCredentials(), updateScreenshots: false }, + selectedNodes: nodes, + allNodes: nodes, }); + + cy.iframeBody().contains("On the road updated").should("exist"); + + cy.iframeBody().findDcy("index_push_button").click(); + + cy.iframeBody().contains("Changed keys").should("be.visible"); + + cy.iframeBody().findDcy("push_submit_button").should("be.visible").click(); + + cy.iframeBody() + .contains("Successfully updated 0 key(s) and uploaded 0 screenshot(s).") + .should("exist"); + + cy.iframeBody() + .contains("Some translations cannot be updated:") + .should("exist"); + + cy.iframeBody().contains("on-the-road-title (overridable)").should("exist"); + + cy.iframeBody() + .findDcy("push-override-all-button") + .should("be.visible") + .click(); + + cy.iframeBody() + .contains("Successfully updated 1 key(s) and uploaded 0 screenshot(s).") + .should("exist"); }); function getCredentials() { diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index a590512..da5270d 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -55,7 +55,6 @@ Cypress.Commands.add("iframeReady", () => { }); Cypress.Commands.add("iframeDocument", () => { - cy.iframeReady(); return cy .get('iframe[data-cy="plugin_iframe"]') .its("0.contentDocument") diff --git a/src/ui/views/Push/Push.tsx b/src/ui/views/Push/Push.tsx index f5ce53c..de6d04e 100644 --- a/src/ui/views/Push/Push.tsx +++ b/src/ui/views/Push/Push.tsx @@ -184,7 +184,7 @@ export const Push: FunctionalComponent = () => { /> - + {errorMessage && !error ? ( }>{errorMessage} ) : isLoading || !changes ? ( diff --git a/src/web/ui.tsx b/src/web/ui.tsx index 6abfc3f..1d4f06e 100644 --- a/src/web/ui.tsx +++ b/src/web/ui.tsx @@ -9,6 +9,4 @@ const AppWrapper = () => { return ; }; -setTimeout(() => { - render(, document.getElementById("root")!); -}, 0); +render(, document.getElementById("root")!); From 71320f2c52f1b7f629912742d051073bb454518d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 17:51:30 +0200 Subject: [PATCH 10/16] feat: e2e tests reliability on next level --- cypress/common/tools.ts | 2 +- cypress/e2e/copyView.cy.ts | 84 +++++++------- cypress/e2e/index.cy.ts | 104 ++++++++--------- cypress/e2e/language.cy.ts | 14 ++- cypress/e2e/pageSetup.cy.ts | 28 ++--- cypress/e2e/pull.cy.ts | 32 +++--- cypress/e2e/push.cy.ts | 109 +++++++++--------- cypress/e2e/settings.cy.ts | 190 +++++++++++++++----------------- cypress/e2e/stringDetails.cy.ts | 82 +++++++------- cypress/support/commands.ts | 17 +-- scripts/runAfterApp.ts | 2 +- 11 files changed, 322 insertions(+), 342 deletions(-) diff --git a/cypress/common/tools.ts b/cypress/common/tools.ts index 6384c26..77214dc 100644 --- a/cypress/common/tools.ts +++ b/cypress/common/tools.ts @@ -5,6 +5,6 @@ const ORIGIN = "http://localhost:3000"; export const visitWithState = (data: Partial) => { cy.visit(`${ORIGIN}${createShortcutUrl(data)}`); cy.iframeReady(); - cy.wait(200); + cy.wait(100); cy.iframeReady(); }; diff --git a/cypress/e2e/copyView.cy.ts b/cypress/e2e/copyView.cy.ts index a246989..c8a84be 100644 --- a/cypress/e2e/copyView.cy.ts +++ b/cypress/e2e/copyView.cy.ts @@ -7,7 +7,9 @@ describe("Copy view", () => { config: PAGE_COPY, }); - cy.iframeBody().contains("Page copy - keys").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Page copy - keys").should("be.visible"); + }); }); it("shows language if language set", () => { @@ -15,7 +17,9 @@ describe("Copy view", () => { config: PAGE_COPY_LANGUAGE, }); - cy.iframeBody().contains("Page copy - cs").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Page copy - cs").should("be.visible"); + }); }); it("shows unconnected node correctly", () => { @@ -26,17 +30,17 @@ describe("Copy view", () => { allNodes: nodes, }); - cy.iframeBody().contains("Test node").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Test node").should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_text") - .contains("Test node") - .should("be.visible"); + cy.gcy("general_node_list_row_text") + .contains("Test node") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_key") - .contains("Not connected") - .should("be.visible"); + cy.gcy("general_node_list_row_key") + .contains("Not connected") + .should("be.visible"); + }); }); it("shows connected node correctly", () => { @@ -53,21 +57,19 @@ describe("Copy view", () => { allNodes: nodes, }); - cy.iframeBody().contains("Test node").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Test node").should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_text") - .contains("Test node") - .should("be.visible"); + cy.gcy("general_node_list_row_text") + .contains("Test node") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_key") - .contains("test_key") - .should("be.visible"); + cy.gcy("general_node_list_row_key") + .contains("test_key") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_namespace") - .should("be.empty"); + cy.gcy("general_node_list_row_namespace").should("be.empty"); + }); }); it("shows connected node with namespace", () => { @@ -85,22 +87,21 @@ describe("Copy view", () => { allNodes: nodes, }); - cy.iframeBody().contains("Test node").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Test node").should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_text") - .contains("Test node") - .should("be.visible"); + cy.gcy("general_node_list_row_text") + .contains("Test node") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_key") - .contains("test_key") - .should("be.visible"); + cy.gcy("general_node_list_row_key") + .contains("test_key") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_namespace") - .contains("test_ns") - .should("be.visible"); + cy.gcy("general_node_list_row_namespace") + .contains("test_ns") + .should("be.visible"); + }); }); it("pulls changes correctly", () => { @@ -117,13 +118,12 @@ describe("Copy view", () => { allNodes: connectedCzech, }); - cy.iframeBody().contains("Na cestě").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Na cestě").should("be.visible"); - cy.iframeBody() - .findDcy("copy_view_pull_button") - .should("be.visible") - .click(); + cy.gcy("copy_view_pull_button").should("be.visible").click(); - cy.iframeBody().contains("Na cestu").should("be.visible"); + cy.get("div").contains("Na cestu").should("be.visible"); + }); }); }); diff --git a/cypress/e2e/index.cy.ts b/cypress/e2e/index.cy.ts index 13170e8..946fd96 100644 --- a/cypress/e2e/index.cy.ts +++ b/cypress/e2e/index.cy.ts @@ -10,22 +10,21 @@ describe("Index", () => { allNodes: nodes, }); - cy.iframeBody().contains("Test node").should("be.visible"); - - cy.iframeBody() - .findDcy("general_node_list_row_text") - .contains("Test node") - .should("be.visible"); - - cy.iframeBody() - .findDcy("general_node_list_row_key") - .find("input") - .should("have.value", "test_key"); - - cy.iframeBody() - .findDcy("general_node_list_row_namespace") - .find("select") - .should("have.value", ""); + cy.iframeBody().within(() => { + cy.get("div").contains("Test node").should("be.visible"); + + cy.gcy("general_node_list_row_text") + .contains("Test node") + .should("be.visible"); + + cy.gcy("general_node_list_row_key") + .find("input") + .should("have.value", "test_key"); + + cy.gcy("general_node_list_row_namespace") + .find("select") + .should("have.value", ""); + }); }); it("hides namespace selector", () => { @@ -36,22 +35,21 @@ describe("Index", () => { allNodes: nodes, }); - cy.iframeBody().contains("Test node").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Test node").should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_text") - .contains("Test node") - .should("be.visible"); + cy.gcy("general_node_list_row_text") + .contains("Test node") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_key") - .find("input") - .should("have.value", "test_key"); + cy.gcy("general_node_list_row_key") + .find("input") + .should("have.value", "test_key"); - cy.iframeBody() - .findDcy("general_node_list_row_namespace") - .find("select") - .should("not.exist"); + cy.gcy("general_node_list_row_namespace") + .find("select") + .should("not.exist"); + }); }); it("shows connected node correctly", () => { @@ -64,21 +62,19 @@ describe("Index", () => { allNodes: nodes, }); - cy.iframeBody().contains("Test node").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("Test node").should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_text") - .contains("Test node") - .should("be.visible"); + cy.gcy("general_node_list_row_text") + .contains("Test node") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_key") - .contains("test_key") - .should("be.visible"); + cy.gcy("general_node_list_row_key") + .contains("test_key") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_namespace") - .should("be.empty"); + cy.gcy("general_node_list_row_namespace").should("be.empty"); + }); }); it("shows connected node with namespace", () => { @@ -95,22 +91,20 @@ describe("Index", () => { selectedNodes: nodes, allNodes: nodes, }); + cy.iframeBody().within(() => { + cy.get("div").contains("Test node").should("be.visible"); - cy.iframeBody().contains("Test node").should("be.visible"); + cy.gcy("general_node_list_row_text") + .contains("Test node") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_text") - .contains("Test node") - .should("be.visible"); + cy.gcy("general_node_list_row_key") + .contains("test_key") + .should("be.visible"); - cy.iframeBody() - .findDcy("general_node_list_row_key") - .contains("test_key") - .should("be.visible"); - - cy.iframeBody() - .findDcy("general_node_list_row_namespace") - .contains("test_ns") - .should("be.visible"); + cy.gcy("general_node_list_row_namespace") + .contains("test_ns") + .should("be.visible"); + }); }); }); diff --git a/cypress/e2e/language.cy.ts b/cypress/e2e/language.cy.ts index f3e9634..8c53de3 100644 --- a/cypress/e2e/language.cy.ts +++ b/cypress/e2e/language.cy.ts @@ -15,12 +15,14 @@ describe("Change language", () => { selectedNodes: [], allNodes: nodes, }); + cy.iframeBody().within(() => { + cy.gcy("index_language_select").should("have.value", "en"); // retried + cy.gcy("index_language_select").select("de"); - cy.iframeBody().findDcy("index_language_select").select("de"); - - cy.iframeBody().contains( - "This action will replace translations in 1 text(s)" - ); - cy.iframeBody().findDcy("pull_submit_button").should("exist").click(); + cy.get("div") + .contains("This action will replace translations in 1 text(s)") + .should("exist"); + cy.gcy("pull_submit_button").should("exist").click(); + }); }); }); diff --git a/cypress/e2e/pageSetup.cy.ts b/cypress/e2e/pageSetup.cy.ts index 7307b1b..d602001 100644 --- a/cypress/e2e/pageSetup.cy.ts +++ b/cypress/e2e/pageSetup.cy.ts @@ -6,26 +6,20 @@ describe("Page setup", () => { visitWithState({ config: NEW_PAGE, }); + cy.iframeBody().within(() => { + cy.get("div").contains("Page setup").should("be.visible"); - cy.iframeBody().contains("Page setup").should("be.visible"); + cy.gcy("page_setup_button_save") + .should("be.visible") + .should("be.disabled"); - cy.iframeBody() - .findDcy("page_setup_button_save") - .should("be.visible") - .should("be.disabled"); + cy.gcy("page_setup_input_language").should("be.visible").select("cs"); - cy.iframeBody() - .findDcy("page_setup_input_language") - .should("be.visible") - .select("cs"); + cy.gcy("page_setup_button_save").should("be.visible").click(); - cy.iframeBody() - .findDcy("page_setup_button_save") - .should("be.visible") - .click(); - - cy.iframeBody() - .contains("Select texts for translation") - .should("be.visible"); + cy.get("div") + .contains("Select texts for translation") + .should("be.visible"); + }); }); }); diff --git a/cypress/e2e/pull.cy.ts b/cypress/e2e/pull.cy.ts index 7094a2d..a4d33eb 100644 --- a/cypress/e2e/pull.cy.ts +++ b/cypress/e2e/pull.cy.ts @@ -16,11 +16,13 @@ describe("Pull", () => { allNodes: nodes, }); - cy.iframeBody().contains("On the road").should("exist"); - cy.iframeBody().findDcy("index_pull_button").click(); + cy.iframeBody().within(() => { + cy.get("div").contains("On the road").should("exist"); + cy.gcy("index_pull_button").click(); - cy.iframeBody().contains("Everything up to date").should("be.visible"); - cy.iframeBody().findDcy("pull_ok_button").should("be.visible").click(); + cy.get("div").contains("Everything up to date").should("be.visible"); + cy.gcy("pull_ok_button").should("be.visible").click(); + }); }); it("pulling change", () => { @@ -42,19 +44,21 @@ describe("Pull", () => { allNodes: nodes, }); - cy.iframeBody().contains("On the old road").should("exist"); - cy.iframeBody().findDcy("index_pull_button").click(); + cy.iframeBody().within(() => { + cy.get("div").contains("On the old road").should("exist"); + cy.gcy("index_pull_button").click(); - cy.iframeBody() - .contains("This action will replace translations in 1") - .should("be.visible"); - cy.iframeBody().contains("Missing keys").should("be.visible"); + cy.get("div") + .contains("This action will replace translations in 1") + .should("be.visible"); + cy.get("div").contains("Missing keys").should("be.visible"); - cy.iframeBody().contains("nonexistant-key").should("be.visible"); + cy.get("div").contains("nonexistant-key").should("be.visible"); - cy.iframeBody().findDcy("pull_submit_button").should("be.visible").click(); + cy.gcy("pull_submit_button").should("be.visible").click(); - cy.iframeBody().contains("On the road").should("exist"); - cy.iframeBody().contains("Connected to nonexistant").should("exist"); + cy.get("div").contains("On the road").should("exist"); + cy.get("div").contains("Connected to nonexistant").should("exist"); + }); }); }); diff --git a/cypress/e2e/push.cy.ts b/cypress/e2e/push.cy.ts index ae86a31..a3030c1 100644 --- a/cypress/e2e/push.cy.ts +++ b/cypress/e2e/push.cy.ts @@ -13,9 +13,13 @@ let client: TolgeeClient; let pak: string; describe("Push", () => { - beforeEach(async () => { - await createProject({ translationProtection: "PROTECT_REVIEWED" }); - await markTitleAsReviewed(); + beforeEach(() => { + return cy.wrap( + (async () => { + await createProject({ translationProtection: "PROTECT_REVIEWED" }); + await markTitleAsReviewed(); + })() + ); }); afterEach(() => { @@ -33,22 +37,19 @@ describe("Push", () => { allNodes: nodes, }); - cy.iframeBody().contains("New key").should("exist"); + cy.iframeBody().within(() => { + cy.get("div").contains("New key").should("exist"); - cy.iframeBody().findDcy("index_push_button").should("be.visible").click(); + cy.gcy("index_push_button").should("be.visible").click(); - cy.iframeBody().contains("New keys").should("exist"); + cy.get("div").contains("New keys").should("exist"); - cy.iframeBody() - .findDcy("changes_new_keys") - .contains("new_key") - .should("be.visible"); + cy.gcy("changes_new_keys").contains("new_key").should("be.visible"); - cy.iframeBody() - .findDcy("changes_changed_keys") - .contains("on-the-road-subtitle") - .should("be.visible"); - cy.wait; + cy.gcy("changes_changed_keys") + .contains("on-the-road-subtitle") + .should("be.visible"); + }); }); it("catches conflicts", () => { @@ -62,13 +63,15 @@ describe("Push", () => { allNodes: nodes, }); - cy.iframeBody().contains("First value").should("exist"); + cy.iframeBody().within(() => { + cy.get("div").contains("First value").should("exist"); - cy.iframeBody().findDcy("index_push_button").should("be.visible").click(); + cy.gcy("index_push_button").should("be.visible").click(); - cy.iframeBody() - .contains("There are multiple different translations for single key") - .should("exist"); + cy.get("div") + .contains("There are multiple different translations for single key") + .should("exist"); + }); }); it("pushes screenshot correctly", () => { @@ -81,17 +84,19 @@ describe("Push", () => { allNodes: nodes, }); - cy.iframeBody().contains("On the road").should("exist"); - cy.iframeBody().findDcy("index_push_button").should("be.visible").click(); + cy.iframeBody().within(() => { + cy.get("div").contains("On the road").should("exist"); + cy.gcy("index_push_button").should("be.visible").click(); - cy.iframeBody().contains("No changes necessary").should("be.visible"); - cy.iframeBody().findDcy("push_upload_screenshots_checkbox").should("exist"); - cy.iframeBody().findDcy("push_submit_button").should("be.visible").click(); + cy.get("div").contains("No changes necessary").should("be.visible"); + cy.gcy("push_upload_screenshots_checkbox").should("exist"); + cy.gcy("push_submit_button").should("be.visible").click(); - cy.iframeBody() - .contains("Successfully updated 0 key(s) and uploaded 1 screenshot(s).") - .should("be.visible"); - cy.iframeBody().findDcy("push_ok_button").should("be.visible").click(); + cy.get("div") + .contains("Successfully updated 0 key(s) and uploaded 1 screenshot(s).") + .should("be.visible"); + cy.gcy("push_ok_button").should("be.visible").click(); + }); }); it("doesn't push screenshot when disabled", () => { @@ -103,13 +108,14 @@ describe("Push", () => { selectedNodes: nodes, allNodes: nodes, }); + cy.iframeBody().within(() => { + cy.get("div").contains("On the road").should("exist"); + cy.gcy("index_push_button").should("be.visible").click(); - cy.iframeBody().contains("On the road").should("exist"); - cy.iframeBody().findDcy("index_push_button").should("be.visible").click(); + cy.get("div").contains("No changes necessary").should("be.visible"); - cy.iframeBody().contains("No changes necessary").should("be.visible"); - - cy.iframeBody().findDcy("push_finish_button").should("be.visible").click(); + cy.gcy("push_finish_button").should("be.visible").click(); + }); }); it("doesn't override protected translation by default", () => { @@ -125,32 +131,31 @@ describe("Push", () => { allNodes: nodes, }); - cy.iframeBody().contains("On the road updated").should("exist"); + cy.iframeBody().within(() => { + cy.get("div").contains("On the road updated").should("exist"); - cy.iframeBody().findDcy("index_push_button").click(); + cy.gcy("index_push_button").click(); - cy.iframeBody().contains("Changed keys").should("be.visible"); + cy.get("div").contains("Changed keys").should("be.visible"); - cy.iframeBody().findDcy("push_submit_button").should("be.visible").click(); + cy.gcy("push_submit_button").should("be.visible").click(); - cy.iframeBody() - .contains("Successfully updated 0 key(s) and uploaded 0 screenshot(s).") - .should("exist"); + cy.get("div") + .contains("Successfully updated 0 key(s) and uploaded 0 screenshot(s).") + .should("exist"); - cy.iframeBody() - .contains("Some translations cannot be updated:") - .should("exist"); + cy.get("div") + .contains("Some translations cannot be updated:") + .should("exist"); - cy.iframeBody().contains("on-the-road-title (overridable)").should("exist"); + cy.get("div").contains("on-the-road-title (overridable)").should("exist"); - cy.iframeBody() - .findDcy("push-override-all-button") - .should("be.visible") - .click(); + cy.gcy("push-override-all-button").should("be.visible").click(); - cy.iframeBody() - .contains("Successfully updated 1 key(s) and uploaded 0 screenshot(s).") - .should("exist"); + cy.get("div") + .contains("Successfully updated 1 key(s) and uploaded 0 screenshot(s).") + .should("exist"); + }); }); function getCredentials() { diff --git a/cypress/e2e/settings.cy.ts b/cypress/e2e/settings.cy.ts index 0f013ea..26709c6 100644 --- a/cypress/e2e/settings.cy.ts +++ b/cypress/e2e/settings.cy.ts @@ -7,35 +7,35 @@ describe("Settings", () => { config: {}, }); - cy.iframeBody().findDcy("top_bar_back_button").should("not.exist"); - cy.iframeBody().findDcy("settings_button_close").should("not.exist"); + cy.iframeBody().within(() => { + cy.gcy("top_bar_back_button").should("not.exist"); + cy.gcy("settings_button_close").should("not.exist"); + }); }); it("works when filling empty", () => { visitWithState({}); - cy.iframeBody() - .findDcy("settings_input_api_url") - .type(DEFAULT_CREDENTIALS.apiUrl); + cy.iframeBody().within(() => { + cy.gcy("settings_input_api_url").should("be.visible"); + + cy.wait(100); + cy.gcy("settings_input_api_url").type(DEFAULT_CREDENTIALS.apiUrl); - cy.iframeBody() - .findDcy("settings_input_api_key") - .type(DEFAULT_CREDENTIALS.apiKey); + cy.gcy("settings_input_api_key").type(DEFAULT_CREDENTIALS.apiKey); - cy.iframeBody().findDcy("settings_button_validate").click(); + cy.gcy("settings_button_validate").click(); - cy.iframeBody() - .contains("examples was successfully connected") - .should("be.visible"); + cy.get("div") + .contains("examples was successfully connected") + .should("be.visible"); - cy.iframeBody().contains("Current language").should("be.visible"); + cy.get("div").contains("Current language").should("be.visible"); - cy.iframeBody() - .findDcy("settings_input_language") - .should("be.visible") - .select("en"); + cy.gcy("settings_input_language").should("be.visible").select("en"); - cy.iframeBody().findDcy("settings_button_save").click(); + cy.gcy("settings_button_save").click(); + }); }); it("works when filling existing", () => { @@ -50,36 +50,30 @@ describe("Settings", () => { }, }); - cy.iframeBody() - .findDcy("index_settings_button") - .should("be.visible") - .click(); - cy.iframeBody().contains("Settings").should("be.visible"); + cy.iframeBody().within(() => { + cy.gcy("index_settings_button").should("be.visible").click(); + cy.get("div").contains("Settings").should("be.visible"); - cy.iframeBody().findDcy("settings_expandable_project").should("be.visible"); + cy.gcy("settings_expandable_project").should("be.visible"); - cy.iframeBody() - .findDcy("settings_input_api_url") - .type(DEFAULT_CREDENTIALS.apiUrl); - cy.iframeBody() - .findDcy("settings_input_api_key") - .type(DEFAULT_CREDENTIALS.apiKey); + cy.gcy("settings_input_api_url").type(DEFAULT_CREDENTIALS.apiUrl); + cy.gcy("settings_input_api_key").type(DEFAULT_CREDENTIALS.apiKey); - cy.iframeBody().findDcy("settings_button_validate").click(); + cy.gcy("settings_button_validate").click(); - cy.iframeBody() - .contains("examples was successfully connected") - .should("be.visible"); - cy.iframeBody().contains("Current language").should("be.visible"); + cy.get("div") + .contains("examples was successfully connected") + .should("be.visible"); + cy.get("div").contains("Current language").should("be.visible"); - cy.iframeBody() - .findDcy("settings_input_language") - .should("be.visible") - .select("en"); + cy.gcy("settings_input_language").should("be.visible").select("en"); - cy.iframeBody().findDcy("settings_button_save").click(); + cy.gcy("settings_button_save").click(); - cy.contains("Select texts for translation").should("be.visible"); + cy.get("div") + .contains("Select texts for translation") + .should("be.visible"); + }); }); it("tests strings settings configuration", () => { @@ -94,53 +88,43 @@ describe("Settings", () => { }, }); - cy.iframeBody() - .findDcy("index_settings_button") - .should("be.visible") - .click(); - cy.iframeBody().contains("Settings").should("be.visible"); - - cy.iframeBody() - .findDcy("settings_expandable_strings") - .should("exist") - .click(); - cy.iframeBody() - .findDcy("settings_checkbox_prefill_key_name") - .should("exist"); - cy.iframeBody().findDcy("settings_checkbox_prefill_key_name").click(); - - // Test key format editor - check if it exists first - cy.iframeBody().findDcy("global-editor").should("exist"); - - // Test variable casing dropdown - only if it's visible - cy.iframeBody() - .findDcy("settings_dropdown_variable_casing") - .should("exist"); - - // Verify preview exists - cy.iframeBody().findDcy("settings_text_preview").should("not.exist"); - - cy.iframeBody().findDcy("global-editor").click(); - cy.wait(150); - cy.iframeBody().findDcy("global-editor").type("{enter}"); - cy.iframeBody().findDcy("settings_text_preview").should("exist"); - - // Verify My Artboard is in the preview - cy.iframeBody() - .findDcy("settings_text_preview") - .should("contain", "My Artboard"); - - // Test ignore settings - only if they're visible - cy.iframeBody() - .findDcy("settings_checkbox_ignore_text_layers") - .should("exist"); - - // Test ignore prefix input - only if it's visible - cy.iframeBody().findDcy("settings_input_ignore_prefix").should("exist"); - - // Save settings - cy.iframeBody().findDcy("settings_button_save").click(); - cy.contains("Select texts for translation").should("be.visible"); + cy.iframeBody().within(() => { + cy.gcy("index_settings_button").should("be.visible").click(); + cy.get("div").contains("Settings").should("be.visible"); + + cy.gcy("settings_expandable_strings").should("exist").click(); + cy.gcy("settings_checkbox_prefill_key_name").should("exist"); + cy.gcy("settings_checkbox_prefill_key_name").click(); + + // Test key format editor - check if it exists first + cy.gcy("global-editor").should("exist"); + + // Test variable casing dropdown - only if it's visible + cy.gcy("settings_dropdown_variable_casing").should("exist"); + + // Verify preview exists + cy.gcy("settings_text_preview").should("not.exist"); + + cy.gcy("global-editor").click(); + cy.wait(150); + cy.gcy("global-editor").type("{enter}"); + cy.gcy("settings_text_preview").should("exist"); + + // Verify My Artboard is in the preview + cy.gcy("settings_text_preview").should("contain", "My Artboard"); + + // Test ignore settings - only if they're visible + cy.gcy("settings_checkbox_ignore_text_layers").should("exist"); + + // Test ignore prefix input - only if it's visible + cy.gcy("settings_input_ignore_prefix").should("exist"); + + // Save settings + cy.gcy("settings_button_save").click(); + cy.get("div") + .contains("Select texts for translation") + .should("be.visible"); + }); }); it("tests push settings configuration", () => { @@ -154,24 +138,24 @@ describe("Settings", () => { pageInfo: true, }, }); - cy.iframeBody() - .findDcy("index_settings_button") - .should("be.visible") - .click(); - cy.iframeBody().contains("Settings").should("be.visible"); - cy.iframeBody().findDcy("settings_expandable_push").should("exist").click(); + cy.iframeBody().within(() => { + cy.gcy("index_settings_button").should("be.visible").click(); + cy.get("div").contains("Settings").should("be.visible"); - // Test update screenshots checkbox - cy.iframeBody() - .findDcy("settings_checkbox_update_screenshots") - .should("exist"); + cy.gcy("settings_expandable_push").should("exist").click(); - // Test add tags checkbox - cy.iframeBody().findDcy("settings_checkbox_add_tags").should("exist"); + // Test update screenshots checkbox + cy.gcy("settings_checkbox_update_screenshots").should("exist"); - // Save settings - cy.iframeBody().findDcy("settings_button_save").click(); - cy.contains("Select texts for translation").should("be.visible"); + // Test add tags checkbox + cy.gcy("settings_checkbox_add_tags").should("exist"); + + // Save settings + cy.gcy("settings_button_save").click(); + cy.get("div") + .contains("Select texts for translation") + .should("be.visible"); + }); }); }); diff --git a/cypress/e2e/stringDetails.cy.ts b/cypress/e2e/stringDetails.cy.ts index ad8264f..cff2d58 100644 --- a/cypress/e2e/stringDetails.cy.ts +++ b/cypress/e2e/stringDetails.cy.ts @@ -21,13 +21,15 @@ describe("String details", () => { allNodes: nodes, }); - cy.iframeBody().contains("test_key").should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div").contains("test_key").should("be.visible"); - cy.iframeBody().findDcy("key_options_button").should("be.visible").click(); + cy.gcy("key_options_button").should("be.visible").click(); - cy.iframeBody().findDcy("dropdown").should("be.visible"); + cy.gcy("dropdown").should("be.visible"); - cy.iframeBody().findDcy("string_details_cy").should("be.visible"); + cy.gcy("string_details_cy").should("be.visible"); + }); }); it("should show the correct preview text", () => { @@ -45,11 +47,12 @@ describe("String details", () => { allNodes: nodes, }); - // Should show the key as preview text - cy.iframeBody() - .findDcy("string_details_preview_text") - .should("be.visible") - .contains("Test node"); + cy.iframeBody().within(() => { + // Should show the key as preview text + cy.gcy("string_details_preview_text") + .should("be.visible") + .contains("Test node"); + }); }); it("should react to key changes", async () => { @@ -67,25 +70,25 @@ describe("String details", () => { allNodes: nodes, }); - cy.iframeBody() - .find('[data-cy="string_details_input_key"]') - .should("have.value", "test_key"); + cy.iframeBody().within(() => { + cy.gcy('[data-cy="string_details_input_key"]').should( + "have.value", + "test_key" + ); - cy.iframeBody() - .find('[data-cy="string_details_input_key"]') - .type("new_key"); + cy.gcy('[data-cy="string_details_input_key"]').type("new_key"); - cy.iframeBody() - .find('[data-cy="string_details_input_key"]') - .should("have.value", "new_key"); + cy.gcy('[data-cy="string_details_input_key"]').should( + "have.value", + "new_key" + ); - cy.iframeBody().find('[data-cy="tooltip"]').click(); + cy.get('[data-cy="tooltip"]').click(); - cy.iframeBody() - .contains("You can use basic HTML tags") - .should("be.visible"); - - cy.wait(500); + cy.get("div") + .contains("You can use basic HTML tags") + .should("be.visible"); + }); }); it("should show negative warning on missmatched translation", () => { @@ -105,11 +108,13 @@ describe("String details", () => { allNodes: nodes, }); - cy.iframeBody() - .contains("Advanced text format detected") - .should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div") + .contains("Advanced text format detected") + .should("be.visible"); - cy.iframeBody().find('[class^="_warningContainer_"]').should("be.visible"); + cy.get('[class^="_warningContainer_"]').should("be.visible"); + }); }); it("should show positive warning on plural keys", () => { @@ -129,13 +134,13 @@ describe("String details", () => { allNodes: nodes, }); - cy.iframeBody() - .contains("Advanced text format detected") - .should("be.visible"); + cy.iframeBody().within(() => { + cy.get("div") + .contains("Advanced text format detected") + .should("be.visible"); - cy.iframeBody() - .find('[class^="_warningNoticeContainer_"]') - .should("be.visible"); + cy.get('[class^="_warningNoticeContainer_"]').should("be.visible"); + }); }); it("should not show warning on simple keys", () => { @@ -154,9 +159,10 @@ describe("String details", () => { selectedNodes: nodes, allNodes: nodes, }); - - cy.iframeBody() - .contains("Advanced text format detected") - .should("not.exist"); + cy.iframeBody().within(() => { + cy.get("div") + .contains("Advanced text format detected") + .should("not.exist"); + }); }); }); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index da5270d..537ee16 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -54,21 +54,12 @@ Cypress.Commands.add("iframeReady", () => { }); }); -Cypress.Commands.add("iframeDocument", () => { - return cy - .get('iframe[data-cy="plugin_iframe"]') - .its("0.contentDocument") - .should("exist"); -}); - Cypress.Commands.add("iframeBody", () => { return cy - .iframeDocument() - .its("body") - .should("not.be.undefined") - .then((e) => { - return cy.wrap(e as HTMLBodyElement); - }); + .get('iframe[data-cy="plugin_iframe"]', { timeout: 15000 }) + .should("be.visible") + .its("0.contentDocument.body") + .should("not.be.empty"); }); // Export {} to ensure this file is treated as a module by TypeScript. diff --git a/scripts/runAfterApp.ts b/scripts/runAfterApp.ts index 52deaf4..646fede 100644 --- a/scripts/runAfterApp.ts +++ b/scripts/runAfterApp.ts @@ -80,7 +80,7 @@ async function finish(code: number) { return true; } isFinishing = true; - const allProcesses = [...appProcesses, ...afterProcesses]; + const allProcesses = [...afterProcesses]; const runningProcesses = allProcesses.filter((p) => p.kill(0)); const childrenPending = runningProcesses.map( (p) => From 266bb586323c88a0cf7991fcd77801465c6bb1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 17:52:04 +0200 Subject: [PATCH 11/16] feat: e2e tests reliability on next level --- scripts/runAfterApp.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/runAfterApp.ts b/scripts/runAfterApp.ts index 646fede..e749f70 100644 --- a/scripts/runAfterApp.ts +++ b/scripts/runAfterApp.ts @@ -80,8 +80,7 @@ async function finish(code: number) { return true; } isFinishing = true; - const allProcesses = [...afterProcesses]; - const runningProcesses = allProcesses.filter((p) => p.kill(0)); + const runningProcesses = afterProcesses.filter((p) => p.kill(0)); const childrenPending = runningProcesses.map( (p) => new Promise((resolve, reject) => { From da2a8fc1356dc14bd4bcffa5f35947d8b6f51713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 18:05:38 +0200 Subject: [PATCH 12/16] chore: add retries in run mode --- cypress.config.mjs | 5 +++-- cypress/common/tools.ts | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cypress.config.mjs b/cypress.config.mjs index 17161e3..9b2cfd5 100644 --- a/cypress.config.mjs +++ b/cypress.config.mjs @@ -2,8 +2,9 @@ import { defineConfig } from "cypress"; export default defineConfig({ e2e: { - setupNodeEvents(on, config) { - // implement node event listeners here + retries: { + runMode: 2, + openMode: 0, }, }, }); diff --git a/cypress/common/tools.ts b/cypress/common/tools.ts index 77214dc..9b9e43e 100644 --- a/cypress/common/tools.ts +++ b/cypress/common/tools.ts @@ -5,6 +5,4 @@ const ORIGIN = "http://localhost:3000"; export const visitWithState = (data: Partial) => { cy.visit(`${ORIGIN}${createShortcutUrl(data)}`); cy.iframeReady(); - cy.wait(100); - cy.iframeReady(); }; From 91205ed83f57124805b624659c29c2631547069a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 19:32:07 +0200 Subject: [PATCH 13/16] chore: use different port for testing --- cypress/common/apiClient.ts | 2 +- cypress/docker-compose.yaml | 4 ++-- package.json | 2 +- scripts/runAfterApp.ts | 2 +- src/web/urlConfig.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cypress/common/apiClient.ts b/cypress/common/apiClient.ts index 9bf8ea7..f138aee 100644 --- a/cypress/common/apiClient.ts +++ b/cypress/common/apiClient.ts @@ -6,7 +6,7 @@ import { } from "@tginternal/client"; import { languagesTestData } from "./languageTestData"; -const API_URL = "http://localhost:8080"; +const API_URL = "http://localhost:22223"; export async function userLogin() { const loadable = await createTolgeeClient({ diff --git a/cypress/docker-compose.yaml b/cypress/docker-compose.yaml index ab0fa46..8b7fb04 100644 --- a/cypress/docker-compose.yaml +++ b/cypress/docker-compose.yaml @@ -4,12 +4,12 @@ services: container_name: tolgee_js_e2e_server image: tolgee/tolgee:latest ports: - - 8080:8080 + - 22223:8080 - 8092:8091 environment: - tolgee.authentication.enabled=true - tolgee.internal.controllerEnabled=true - - "tolgee.screenshots-url=http://localhost:8080/screenshots" + - "tolgee.screenshots-url=http://localhost:22223/screenshots" - tolgee.authentication.needs-email-verification=true - tolgee.authentication.registrations-allowed=true - tolgee.internal.fake-emails-sent=true diff --git a/package.json b/package.json index 55cf7c2..a4744ed 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build": "build-figma-plugin --typecheck --minify", "watch": "build-figma-plugin --typecheck --watch", "test": "npx jest", - "schema": "openapi-typescript \"http://localhost:8080/v3/api-docs/Accessible%20with%20Project%20API%20key%20(All)\" --output ./src/ui/client/apiSchema.generated.ts", + "schema": "openapi-typescript \"http://localhost:22223/v3/api-docs/Accessible%20with%20Project%20API%20key%20(All)\" --output ./src/ui/client/apiSchema.generated.ts", "eslint": "eslint --ext .ts,.tsx,.js,.jsx src", "watch:web": "npm run --prefix web watch", "dev:web": "ts-node ./scripts/runAfterApp.ts \"npm run watch:web\"", diff --git a/scripts/runAfterApp.ts b/scripts/runAfterApp.ts index e749f70..baf0ac4 100644 --- a/scripts/runAfterApp.ts +++ b/scripts/runAfterApp.ts @@ -4,7 +4,7 @@ import colors from "colors"; import terminate from "terminate"; import http from "http"; -const PORT = 8080; +const PORT = 22223; function systemColor(text: string) { return colors.grey(text); diff --git a/src/web/urlConfig.ts b/src/web/urlConfig.ts index ba37de7..e290b41 100644 --- a/src/web/urlConfig.ts +++ b/src/web/urlConfig.ts @@ -32,7 +32,7 @@ export function createShortcutLink(name: string, props: PluginInitialData) { } export const DEFAULT_CREDENTIALS = { - apiUrl: "http://localhost:8080", + apiUrl: "http://localhost:22223", apiKey: "examples-admin-imported-project-implicit", }; From 405acb25d659abd0602a366f13ba92f7167c22ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Thu, 14 Aug 2025 19:48:46 +0200 Subject: [PATCH 14/16] chore: use different port for fe --- cypress/common/tools.ts | 2 +- web/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/common/tools.ts b/cypress/common/tools.ts index 9b9e43e..308e1a6 100644 --- a/cypress/common/tools.ts +++ b/cypress/common/tools.ts @@ -1,6 +1,6 @@ import { createShortcutUrl, PluginData } from "@/web/urlConfig"; -const ORIGIN = "http://localhost:3000"; +const ORIGIN = "http://localhost:22224"; export const visitWithState = (data: Partial) => { cy.visit(`${ORIGIN}${createShortcutUrl(data)}`); diff --git a/web/package.json b/web/package.json index d41c808..c303ac2 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "scripts": { - "watch": "concurrently --kill-others \"npm run build\" \"serve --no-request-logging .\"", + "watch": "concurrently --kill-others \"npm run build\" \"serve --no-request-logging -p 22224 .\"", "build": "nodemon --exec \"build-figma-plugin --typecheck\" -e tsx,ts,css --watch ../src/ --watch src/" }, "figma-plugin": { From d3555bfb936e63d0c66a94cbbd47b27aad5b5298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Fri, 15 Aug 2025 12:55:18 +0200 Subject: [PATCH 15/16] chore: use newer api client --- cypress/common/apiClient.ts | 52 +++++++------------------------------ cypress/docker-compose.yaml | 3 +++ cypress/e2e/push.cy.ts | 4 +-- package-lock.json | 8 +++--- package.json | 2 +- 5 files changed, 19 insertions(+), 50 deletions(-) diff --git a/cypress/common/apiClient.ts b/cypress/common/apiClient.ts index f138aee..4e4f848 100644 --- a/cypress/common/apiClient.ts +++ b/cypress/common/apiClient.ts @@ -1,45 +1,9 @@ -import { - TolgeeClientProps, - TolgeeClient, - createTolgeeClient, - components, -} from "@tginternal/client"; +import { ApiClient, createApiClient, components } from "@tginternal/client"; import { languagesTestData } from "./languageTestData"; const API_URL = "http://localhost:22223"; -export async function userLogin() { - const loadable = await createTolgeeClient({ - baseUrl: API_URL, - autoThrow: true, - }).POST("/api/public/generatetoken", { - body: { username: "admin", password: "admin" }, - }); - - return loadable.data!.accessToken!; -} - -export function createClient( - userToken: string, - options?: Partial -) { - const client = createTolgeeClient({ - baseUrl: API_URL, - autoThrow: true, - ...options, - }); - - client.use({ - // @ts-ignore - onRequest({ request }) { - request.headers.set("Authorization", "Bearer " + userToken); - return undefined; - }, - }); - return client; -} - -export async function deleteProject(client: TolgeeClient | undefined) { +export async function deleteProject(client: ApiClient | undefined) { await client?.DELETE("/v2/projects/{projectId}", { params: { path: { projectId: client?.getProjectId() } }, parseAs: "stream", @@ -55,8 +19,10 @@ export async function createProjectWithClient( data: components["schemas"]["SingleStepImportResolvableRequest"], options?: Options ) { - const userToken = await userLogin(); - let client = createClient(userToken!); + const client = createApiClient({ + baseUrl: API_URL, + }); + await client.login({ username: "admin", password: "admin" }); const organizations = await client.GET("/v2/organizations"); const { languages, ...editOptions } = options ?? {}; @@ -69,7 +35,7 @@ export async function createProjectWithClient( }, }); - client = createClient(userToken, { projectId: project.data!.id }); + client.setProjectId(project.data!.id); await client.PUT("/v2/projects/{projectId}", { params: { @@ -107,7 +73,7 @@ export const DEFAULT_SCOPES = [ "translations.state-edit", ]; -export async function createPak(client: TolgeeClient, scopes = DEFAULT_SCOPES) { +export async function createPak(client: ApiClient, scopes = DEFAULT_SCOPES) { const apiKey = await client.POST("/v2/api-keys", { body: { projectId: client.getProjectId(), scopes }, }); @@ -115,7 +81,7 @@ export async function createPak(client: TolgeeClient, scopes = DEFAULT_SCOPES) { return apiKey.data!.key; } -export async function createPat(client: TolgeeClient) { +export async function createPat(client: ApiClient) { const apiKey = await client.POST("/v2/pats", { body: { description: "e2e test pat" }, }); diff --git a/cypress/docker-compose.yaml b/cypress/docker-compose.yaml index 8b7fb04..e578900 100644 --- a/cypress/docker-compose.yaml +++ b/cypress/docker-compose.yaml @@ -16,6 +16,9 @@ services: - tolgee.authentication.initialPassword=admin - tolgee.import.dir=/data/import-data - tolgee.import.create-implicit-api-key=true + - tolgee.rate-limits.global-limits=false + - tolgee.rate-limits.endpoint-limits=false + - tolgee.rate-limits.authentication-limits=false - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,address=*:8091,server=y,suspend=n volumes: - ./import-data:/data/import-data diff --git a/cypress/e2e/push.cy.ts b/cypress/e2e/push.cy.ts index a3030c1..9c7cd20 100644 --- a/cypress/e2e/push.cy.ts +++ b/cypress/e2e/push.cy.ts @@ -1,5 +1,5 @@ import { visitWithState } from "../common/tools"; -import { TolgeeClient } from "@tginternal/client"; +import { ApiClient } from "@tginternal/client"; import { createProjectWithClient, createPak, @@ -9,7 +9,7 @@ import { import { EXAMPLE_PROJECT } from "../common/exampleProject"; import { createTestNode, SIGNED_IN } from "@/web/urlConfig"; -let client: TolgeeClient; +let client: ApiClient; let pak: string; describe("Push", () => { diff --git a/package-lock.json b/package-lock.json index 4005a7a..b8124bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "@create-figma-plugin/build": "^3.1.0", "@create-figma-plugin/tsconfig": "^3.1.0", "@figma/plugin-typings": "^1.89.0", - "@tginternal/client": "^0.0.0-prerelease.a77861e", + "@tginternal/client": "^0.0.0-prerelease.6a2cb0b2b", "@types/cypress": "^0.1.6", "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^5.48.1", @@ -2624,9 +2624,9 @@ } }, "node_modules/@tginternal/client": { - "version": "0.0.0-prerelease.a77861e", - "resolved": "https://registry.npmjs.org/@tginternal/client/-/client-0.0.0-prerelease.a77861e.tgz", - "integrity": "sha512-+cuOK37//hSyC5V/kjc5u0RnSKc71GpF7dAPc6fFeS7h5pdcObKiLXjiMrnvbR7CD0Ic6NEuMKazNzzNof17Zg==", + "version": "0.0.0-prerelease.6a2cb0b2b", + "resolved": "https://registry.npmjs.org/@tginternal/client/-/client-0.0.0-prerelease.6a2cb0b2b.tgz", + "integrity": "sha512-8jY4rTCM7Rvj0XRfr+2UtUbII9LP/x+dWPjNkKQDT+obYpyIlMX6MWquP+HVNbgYvg0Prt2yZ7cJu0w5N7BCCg==", "dev": true, "dependencies": { "openapi-fetch": "^0.14.0" diff --git a/package.json b/package.json index a4744ed..5d30e74 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@create-figma-plugin/build": "^3.1.0", "@create-figma-plugin/tsconfig": "^3.1.0", "@figma/plugin-typings": "^1.89.0", - "@tginternal/client": "^0.0.0-prerelease.a77861e", + "@tginternal/client": "^0.0.0-prerelease.6a2cb0b2b", "@types/cypress": "^0.1.6", "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^5.48.1", From 454ed41ed93401f711711e374d7cfe88ffc482a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Gran=C3=A1t?= Date: Fri, 15 Aug 2025 13:27:49 +0200 Subject: [PATCH 16/16] chore: update --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b8124bb..20b6ce3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "@create-figma-plugin/build": "^3.1.0", "@create-figma-plugin/tsconfig": "^3.1.0", "@figma/plugin-typings": "^1.89.0", - "@tginternal/client": "^0.0.0-prerelease.6a2cb0b2b", + "@tginternal/client": "^0.0.0-prerelease.5758c456c", "@types/cypress": "^0.1.6", "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^5.48.1", @@ -2624,9 +2624,9 @@ } }, "node_modules/@tginternal/client": { - "version": "0.0.0-prerelease.6a2cb0b2b", - "resolved": "https://registry.npmjs.org/@tginternal/client/-/client-0.0.0-prerelease.6a2cb0b2b.tgz", - "integrity": "sha512-8jY4rTCM7Rvj0XRfr+2UtUbII9LP/x+dWPjNkKQDT+obYpyIlMX6MWquP+HVNbgYvg0Prt2yZ7cJu0w5N7BCCg==", + "version": "0.0.0-prerelease.5758c456c", + "resolved": "https://registry.npmjs.org/@tginternal/client/-/client-0.0.0-prerelease.5758c456c.tgz", + "integrity": "sha512-T3ji6ceUQGNDqnx1aBohyQ3SaJOOdj3m2AscHhUUu/F9SBgGMMRV+XmwH/ocaH1a9r5nmilZfmGKzASXWolMfw==", "dev": true, "dependencies": { "openapi-fetch": "^0.14.0" diff --git a/package.json b/package.json index 5d30e74..893ba05 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@create-figma-plugin/build": "^3.1.0", "@create-figma-plugin/tsconfig": "^3.1.0", "@figma/plugin-typings": "^1.89.0", - "@tginternal/client": "^0.0.0-prerelease.6a2cb0b2b", + "@tginternal/client": "^0.0.0-prerelease.5758c456c", "@types/cypress": "^0.1.6", "@types/jest": "^29.5.14", "@typescript-eslint/eslint-plugin": "^5.48.1",