@crowdin/app-project-module 0.42.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ import { CrowdinClientRequest, CustomSpellcheckerModule } from '../../models';
4
+ export default function handle(customSpellchecker: CustomSpellcheckerModule): (req: CrowdinClientRequest | import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const util_1 = require("../../util");
13
+ const logger_1 = require("../../util/logger");
14
+ function handle(customSpellchecker) {
15
+ return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
+ try {
17
+ const data = yield customSpellchecker.getSupportedLanguage({
18
+ client: req.crowdinApiClient,
19
+ context: req.crowdinContext,
20
+ });
21
+ res.send({ data });
22
+ }
23
+ catch (e) {
24
+ req.logError(e);
25
+ res.send({ error: { message: (0, logger_1.getErrorMessage)(e) } });
26
+ }
27
+ }));
28
+ }
29
+ exports.default = handle;
@@ -0,0 +1,4 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ import { CrowdinClientRequest, CustomSpellcheckerModule } from '../../models';
4
+ export default function handle(customSpellchecker: CustomSpellcheckerModule): (req: CrowdinClientRequest | import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const util_1 = require("../../util");
13
+ const logger_1 = require("../../util/logger");
14
+ function handle(customSpellchecker) {
15
+ return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
+ const body = req.body;
17
+ (0, logger_1.log)('Received request for custom spellcheck');
18
+ (0, logger_1.log)(`Language ${body.language}, Payload ${JSON.stringify(body, null, 2)}`);
19
+ try {
20
+ const response = yield customSpellchecker.runSpellCheck({
21
+ client: req.crowdinApiClient,
22
+ context: req.crowdinContext,
23
+ language: body.language,
24
+ texts: body.texts,
25
+ });
26
+ res.send({ data: response.texts, error: response.error ? { message: response.error } : undefined });
27
+ }
28
+ catch (e) {
29
+ req.logError(e);
30
+ res.send({ error: { message: (0, logger_1.getErrorMessage)(e) } });
31
+ }
32
+ }));
33
+ }
34
+ exports.default = handle;
@@ -198,6 +198,12 @@ function handle(config) {
198
198
  if (config.api) {
199
199
  modules['api'] = (0, api_1.getApiManifest)(config, config.api);
200
200
  }
201
+ if (config.customSpellchecker) {
202
+ const uiModule = config.customSpellchecker.settingsUiModule;
203
+ modules['custom-spellchecker'] = [
204
+ Object.assign({ key: config.identifier + '-spellchecker', name: config.customSpellchecker.name || config.name, description: config.customSpellchecker.description || config.description, listSupportedLanguagesUrl: '/languages', checkSpellingUrl: '/spellcheck', environments: config.customSpellchecker.environments }, (uiModule ? { url: '/settings/' + (uiModule.fileName || 'index.html') } : {})),
205
+ ];
206
+ }
201
207
  const events = {
202
208
  installed: '/installed',
203
209
  uninstall: '/uninstall',
package/out/index.js CHANGED
@@ -70,6 +70,8 @@ const user_errors_1 = __importDefault(require("./handlers/integration/user-error
70
70
  const manifest_1 = __importDefault(require("./handlers/manifest"));
71
71
  const subscription_paid_1 = __importDefault(require("./handlers/subscription-paid"));
72
72
  const uninstall_1 = __importDefault(require("./handlers/uninstall"));
73
+ const get_languages_list_1 = __importDefault(require("./handlers/custom-spell-check/get-languages-list"));
74
+ const spell_check_1 = __importDefault(require("./handlers/custom-spell-check/spell-check"));
73
75
  const crowdin_client_1 = __importStar(require("./middlewares/crowdin-client"));
74
76
  const integration_credentials_1 = __importDefault(require("./middlewares/integration-credentials"));
75
77
  const json_response_1 = __importDefault(require("./middlewares/json-response"));
@@ -285,6 +287,13 @@ function addCrowdinEndpoints(app, clientConfig) {
285
287
  }
286
288
  (0, api_1.addSwagerApiDocumentation)(app, config);
287
289
  }
290
+ if (config.customSpellchecker) {
291
+ if (config.customSpellchecker.settingsUiModule) {
292
+ app.use('/settings', (0, ui_module_1.default)(config, config.customSpellchecker.settingsUiModule.allowUnauthorized), (0, render_ui_module_1.default)(config.customSpellchecker.settingsUiModule));
293
+ }
294
+ app.get('/languages', json_response_1.default, (0, crowdin_client_1.default)(config), (0, get_languages_list_1.default)(config.customSpellchecker));
295
+ app.post('/spellcheck', json_response_1.default, (0, crowdin_client_1.default)(config), (0, spell_check_1.default)(config.customSpellchecker));
296
+ }
288
297
  if (Object.keys(config).some((moduleKey) => {
289
298
  const moduleConfig = config[moduleKey];
290
299
  return typeof moduleConfig === 'object' && moduleConfig.hasOwnProperty('formSchema');
@@ -164,6 +164,7 @@ export interface ClientConfig extends ImagePath {
164
164
  * Not necessary to configure if environment variables AWS_REGION and AWS_TMP_BUCKET_NAME are properly set.
165
165
  */
166
166
  awsConfig?: AWSConfig;
167
+ customSpellchecker?: CustomSpellcheckerModule;
167
168
  }
168
169
  export type Config = ClientConfig & {
169
170
  baseUrl: string;
@@ -933,6 +934,60 @@ export interface ApiModule {
933
934
  endpoints?: ApiEndpoints[];
934
935
  docFile?: string;
935
936
  }
937
+ export interface CustomSpellCheckRequest {
938
+ language: string;
939
+ texts: string[];
940
+ }
941
+ export type SpellCheckCategory = 'typography' | 'casing' | 'grammar' | 'typos' | 'punctuation' | 'confused_words' | 'redundancy' | 'style' | 'gender_neutrality' | 'semantics' | 'colloquialisms' | 'wikipedia' | 'barbarism' | 'misc';
942
+ export interface SupportedLanguage {
943
+ code: string;
944
+ name: string;
945
+ }
946
+ export interface SpellCheckMatch {
947
+ category: SpellCheckCategory;
948
+ message: string;
949
+ shortMessage: string;
950
+ offset: number;
951
+ length: number;
952
+ replacements: string[];
953
+ }
954
+ export interface CustomSpellCheckResponse {
955
+ texts: {
956
+ text: string;
957
+ matches: SpellCheckMatch[];
958
+ }[];
959
+ error?: string;
960
+ }
961
+ export interface CustomSpellcheckerModule extends Environments {
962
+ /**
963
+ * module description
964
+ */
965
+ description?: string;
966
+ /**
967
+ * module name
968
+ */
969
+ name?: string;
970
+ /**
971
+ * Settings UI module
972
+ */
973
+ settingsUiModule?: UiModule;
974
+ /**
975
+ * function to get list of supported languages that are supports by current spellchecker
976
+ */
977
+ getSupportedLanguage: ({ client, context, }: {
978
+ client: Crowdin;
979
+ context: CrowdinContextInfo;
980
+ }) => Promise<SupportedLanguage[]>;
981
+ /**
982
+ * function to check spelling
983
+ */
984
+ runSpellCheck: ({ client, context, language, texts, }: {
985
+ client: Crowdin;
986
+ context: CrowdinContextInfo;
987
+ language: string;
988
+ texts: string[];
989
+ }) => Promise<CustomSpellCheckResponse>;
990
+ }
936
991
  export interface Logger {
937
992
  enabled: boolean;
938
993
  log?: (message: string, context?: CrowdinContextInfo) => void;
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "description": "Module that generates for you all common endpoints for serving standalone Crowdin App",
5
5
  "main": "out/index.js",
6
6
  "types": "out/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc -p ./ && cp -R views out && cp -R static out && cp logo.png out && rollup -c rollup.config.mjs",
9
9
  "build-main": "tsc -p ./ && cp -R views out && cp -R static out && cp logo.png out",
10
+ "watch-main": "tsc --watch -p ./ && cp -R views out && cp -R static out && cp logo.png out",
10
11
  "lint": "eslint --fix \"{src,tests}/**/*.{js,ts}\"",
11
12
  "prettier": "prettier --config .prettierrc src/**/*.ts --write",
12
13
  "lint-ci": "eslint \"{src,tests}/**/*.{js,ts}\"",