@crowdin/app-project-module 0.28.10 → 0.29.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.
Files changed (40) hide show
  1. package/out/handlers/crowdin-file-progress.js +1 -1
  2. package/out/handlers/crowdin-update.js +7 -2
  3. package/out/handlers/crowdin-webhook.js +4 -3
  4. package/out/handlers/integration-update.js +5 -0
  5. package/out/handlers/integration-webhook.js +2 -1
  6. package/out/handlers/main.js +1 -0
  7. package/out/handlers/manifest.js +4 -0
  8. package/out/handlers/settings-save.js +11 -0
  9. package/out/handlers/settings.d.ts +4 -0
  10. package/out/handlers/settings.js +22 -0
  11. package/out/handlers/sync-settings-save.d.ts +2 -2
  12. package/out/handlers/sync-settings-save.js +8 -11
  13. package/out/handlers/sync-settings.js +1 -1
  14. package/out/index.js +18 -1
  15. package/out/middlewares/crowdin-client.js +5 -0
  16. package/out/models/index.d.ts +64 -3
  17. package/out/models/index.js +14 -1
  18. package/out/static/js/dependent.js +1 -2
  19. package/out/storage/index.d.ts +8 -5
  20. package/out/storage/mysql.d.ts +4 -1
  21. package/out/storage/mysql.js +35 -1
  22. package/out/storage/postgre.d.ts +4 -1
  23. package/out/storage/postgre.js +35 -1
  24. package/out/storage/sqlite.d.ts +4 -1
  25. package/out/storage/sqlite.js +33 -1
  26. package/out/util/api/api.d.ts +6 -0
  27. package/out/util/api/api.js +452 -0
  28. package/out/util/api/base.d.ts +7 -0
  29. package/out/util/api/base.js +8 -0
  30. package/out/util/api/components.d.ts +227 -0
  31. package/out/util/api/components.js +228 -0
  32. package/out/util/cron.d.ts +2 -1
  33. package/out/util/cron.js +76 -9
  34. package/out/util/defaults.js +26 -3
  35. package/out/util/file-snapshot.d.ts +7 -0
  36. package/out/util/file-snapshot.js +144 -0
  37. package/out/util/webhooks.d.ts +4 -3
  38. package/out/util/webhooks.js +29 -5
  39. package/out/views/main.handlebars +140 -8
  40. package/package.json +5 -1
@@ -99,6 +99,16 @@ class PostgreStorage {
99
99
  data varchar
100
100
  )
101
101
  `);
102
+ yield client.query(`
103
+ create table if not exists files_snapshot
104
+ (
105
+ id serial primary key,
106
+ integration_id varchar not null,
107
+ crowdin_id varchar not null,
108
+ files varchar,
109
+ provider varchar not null
110
+ )
111
+ `);
102
112
  });
103
113
  }
104
114
  saveCrowdinCredentials(credentials) {
@@ -159,6 +169,7 @@ class PostgreStorage {
159
169
  yield client.query('DELETE FROM crowdin_credentials where id = $1', [id]);
160
170
  yield client.query('DELETE FROM integration_credentials where crowdin_id = $1', [id]);
161
171
  yield client.query('DELETE FROM sync_settings WHERE crowdin_id = $1', [id]);
172
+ yield client.query('DELETE FROM files_snapshot WHERE crowdin_id = $1', [id]);
162
173
  }));
163
174
  });
164
175
  }
@@ -208,6 +219,7 @@ class PostgreStorage {
208
219
  yield this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
209
220
  yield client.query('DELETE FROM integration_credentials where id = $1', [id]);
210
221
  yield client.query('DELETE FROM sync_settings where integration_id = $1', [id]);
222
+ yield client.query('DELETE FROM files_snapshot where integration_id = $1', [id]);
211
223
  }));
212
224
  });
213
225
  }
@@ -217,6 +229,7 @@ class PostgreStorage {
217
229
  yield this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
218
230
  yield client.query('DELETE FROM integration_credentials where crowdin_id = $1', [crowdinId]);
219
231
  yield client.query('DELETE FROM sync_settings where crowdin_id = $1', [crowdinId]);
232
+ yield client.query('DELETE FROM files_snapshot where crowdin_id = $1', [crowdinId]);
220
233
  }));
221
234
  });
222
235
  }
@@ -283,7 +296,28 @@ class PostgreStorage {
283
296
  return __awaiter(this, void 0, void 0, function* () {
284
297
  yield this.dbPromise;
285
298
  return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
286
- const res = yield client.query('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId", type FROM sync_settings WHERE integration_id = $1 AND crowdin_id = $2 AND type = $3 AND provider = $4', [integrationId, crowdinId, type, provider]);
299
+ const res = yield client.query('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId", type, provider FROM sync_settings WHERE integration_id = $1 AND crowdin_id = $2 AND type = $3 AND provider = $4', [integrationId, crowdinId, type, provider]);
300
+ return res === null || res === void 0 ? void 0 : res.rows[0];
301
+ }));
302
+ });
303
+ }
304
+ saveFilesSnapshot(files, integrationId, crowdinId, provider) {
305
+ return __awaiter(this, void 0, void 0, function* () {
306
+ yield this.dbPromise;
307
+ yield this.executeQuery((client) => client.query('INSERT INTO files_snapshot(integration_id, crowdin_id, files, provider) VALUES ($1, $2, $3, $4)', [files, integrationId, crowdinId, provider]));
308
+ });
309
+ }
310
+ updateFilesSnapshot(files, integrationId, crowdinId, provider) {
311
+ return __awaiter(this, void 0, void 0, function* () {
312
+ yield this.dbPromise;
313
+ yield this.executeQuery((client) => client.query('UPDATE files_snapshot SET files = $1 WHERE integration_id = $2 AND crowdin_id = $3 AND provider = $4', [files, integrationId, crowdinId, provider]));
314
+ });
315
+ }
316
+ getFilesSnapshot(integrationId, crowdinId, provider) {
317
+ return __awaiter(this, void 0, void 0, function* () {
318
+ yield this.dbPromise;
319
+ return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
320
+ const res = yield client.query('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId" FROM files_snapshot WHERE integration_id = $1 AND crowdin_id = $2 AND provider = $3', [integrationId, crowdinId, provider]);
287
321
  return res === null || res === void 0 ? void 0 : res.rows[0];
288
322
  }));
289
323
  });
@@ -1,5 +1,5 @@
1
1
  import { Storage } from '.';
2
- import { CrowdinCredentials, IntegrationCredentials, IntegrationSyncSettings } from '../models';
2
+ import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings } from '../models';
3
3
  export interface SQLiteStorageConfig {
4
4
  dbFolder: string;
5
5
  }
@@ -37,4 +37,7 @@ export declare class SQLiteStorage implements Storage {
37
37
  saveSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
38
38
  updateSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
39
39
  getSyncSettings(integrationId: string, crowdinId: string, type: string, provider: string): Promise<IntegrationSyncSettings | undefined>;
40
+ saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
41
+ updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
42
+ getFilesSnapshot(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationFilesSnapshot | undefined>;
40
43
  }
@@ -169,6 +169,16 @@ class SQLiteStorage {
169
169
  id varchar not null primary key,
170
170
  data varchar null
171
171
  );
172
+ `, []);
173
+ yield this._run(`
174
+ create table if not exists files_snapshot
175
+ (
176
+ id integer not null primary key autoincrement,
177
+ integration_id varchar not null,
178
+ crowdin_id varchar not null,
179
+ files varchar null,
180
+ provider varchar not null
181
+ );
172
182
  `, []);
173
183
  this._res && this._res();
174
184
  // TODO: temporary code
@@ -222,6 +232,7 @@ class SQLiteStorage {
222
232
  yield this.run('DELETE FROM crowdin_credentials where id = ?', [id]);
223
233
  yield this.run('DELETE FROM integration_credentials where crowdin_id = ?', [id]);
224
234
  yield this.run('DELETE FROM sync_settings WHERE crowdin_id = ?', [id]);
235
+ yield this.run('DELETE FROM files_snapshot WHERE crowdin_id = ?', [id]);
225
236
  });
226
237
  }
227
238
  saveIntegrationCredentials(id, credentials, crowdinId) {
@@ -252,12 +263,14 @@ class SQLiteStorage {
252
263
  return __awaiter(this, void 0, void 0, function* () {
253
264
  yield this.run('DELETE FROM integration_credentials where id = ?', [id]);
254
265
  yield this.run('DELETE FROM sync_settings where integration_id = ?', [id]);
266
+ yield this.run('DELETE FROM files_snapshot where integration_id = ?', [id]);
255
267
  });
256
268
  }
257
269
  deleteAllIntegrationCredentials(crowdinId) {
258
270
  return __awaiter(this, void 0, void 0, function* () {
259
271
  yield this.run('DELETE FROM integration_credentials where crowdin_id = ?', [crowdinId]);
260
272
  yield this.run('DELETE FROM sync_settings where crowdin_id = ?', [crowdinId]);
273
+ yield this.run('DELETE FROM files_snapshot where crowdin_id = ?', [crowdinId]);
261
274
  });
262
275
  }
263
276
  saveMetadata(id, metadata) {
@@ -298,7 +311,26 @@ class SQLiteStorage {
298
311
  }
299
312
  getSyncSettings(integrationId, crowdinId, type, provider) {
300
313
  return __awaiter(this, void 0, void 0, function* () {
301
- const row = yield this.get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type FROM sync_settings WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [integrationId, crowdinId, type, provider]);
314
+ const row = yield this.get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type, provider FROM sync_settings WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [integrationId, crowdinId, type, provider]);
315
+ if (row) {
316
+ return row;
317
+ }
318
+ });
319
+ }
320
+ saveFilesSnapshot(files, integrationId, crowdinId, provider) {
321
+ return this.run('INSERT INTO files_snapshot(files, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)', [
322
+ files,
323
+ integrationId,
324
+ crowdinId,
325
+ provider,
326
+ ]);
327
+ }
328
+ updateFilesSnapshot(files, integrationId, crowdinId, provider) {
329
+ return this.run('UPDATE files_snapshot SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND provider = ? ', [files, integrationId, crowdinId, provider]);
330
+ }
331
+ getFilesSnapshot(integrationId, crowdinId, provider) {
332
+ return __awaiter(this, void 0, void 0, function* () {
333
+ const row = yield this.get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, provider FROM files_snapshot WHERE integration_id = ? AND crowdin_id = ? AND provider = ?', [integrationId, crowdinId, provider]);
302
334
  if (row) {
303
335
  return row;
304
336
  }
@@ -0,0 +1,6 @@
1
+ import { ApiEndpoints, ApiModule, Config, CrowdinClientRequest, CrowdinContextInfo } from '../../models';
2
+ import { Express } from 'express';
3
+ export declare function getApiManifest(config: Config, apiModule: ApiModule): ApiEndpoints[];
4
+ export declare function updateCrowdinContext(req: CrowdinClientRequest, context: CrowdinContextInfo): CrowdinContextInfo;
5
+ export declare function addDefaultApiEndpoints(app: Express, config: Config): void;
6
+ export declare function addSwagerApiDocumentation(app: Express, config: Config): void;
@@ -0,0 +1,452 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addSwagerApiDocumentation = exports.addDefaultApiEndpoints = exports.updateCrowdinContext = exports.getApiManifest = void 0;
7
+ const models_1 = require("../../models");
8
+ const redoc_express_1 = __importDefault(require("redoc-express"));
9
+ const swagger_jsdoc_1 = __importDefault(require("swagger-jsdoc"));
10
+ const json_response_1 = __importDefault(require("../../middlewares/json-response"));
11
+ const crowdin_client_1 = __importDefault(require("../../middlewares/crowdin-client"));
12
+ const integration_credentials_1 = __importDefault(require("../../middlewares/integration-credentials"));
13
+ const crowdin_files_1 = __importDefault(require("../../handlers/crowdin-files"));
14
+ const integration_data_1 = __importDefault(require("../../handlers/integration-data"));
15
+ const crowdin_file_progress_1 = __importDefault(require("../../handlers/crowdin-file-progress"));
16
+ const crowdin_update_1 = __importDefault(require("../../handlers/crowdin-update"));
17
+ const sync_settings_1 = __importDefault(require("../../handlers/sync-settings"));
18
+ const sync_settings_save_1 = __importDefault(require("../../handlers/sync-settings-save"));
19
+ const settings_save_1 = __importDefault(require("../../handlers/settings-save"));
20
+ const settings_1 = __importDefault(require("../../handlers/settings"));
21
+ const integration_update_1 = __importDefault(require("../../handlers/integration-update"));
22
+ const path_1 = __importDefault(require("path"));
23
+ const integration_login_1 = __importDefault(require("../../handlers/integration-login"));
24
+ function getApiManifest(config, apiModule) {
25
+ const apiModuleManifest = [];
26
+ if (apiModule.endpoints) {
27
+ const userEndpoints = getUsersApiManifest(apiModule.endpoints);
28
+ apiModuleManifest.push(...userEndpoints);
29
+ }
30
+ if (apiModule.default) {
31
+ const defaultEndpoints = getDefaultApiEndpointsManifest(config);
32
+ apiModuleManifest.push(...defaultEndpoints);
33
+ }
34
+ return apiModuleManifest;
35
+ }
36
+ exports.getApiManifest = getApiManifest;
37
+ function generateModuleKey(moduleName) {
38
+ return moduleName.toLowerCase().split(' ').join('-') + '-api';
39
+ }
40
+ function getUsersApiManifest(endpoints) {
41
+ const apiModuleManifest = [];
42
+ for (const endpoint of endpoints) {
43
+ apiModuleManifest.push(Object.assign({ key: generateModuleKey(endpoint.name), name: endpoint.name, url: endpoint.url, method: endpoint.method, description: endpoint.description }, (endpoint.documentationUrl ? { documentationUrl: endpoint.documentationUrl } : {})));
44
+ }
45
+ return apiModuleManifest;
46
+ }
47
+ function getDefaultApiEndpointsManifest(config) {
48
+ var _a;
49
+ const apiModuleManifest = [
50
+ {
51
+ key: 'crowdin-files-api',
52
+ name: 'Get Crowdin Files',
53
+ url: '/crowdin-files',
54
+ method: models_1.RequestMethods.GET,
55
+ description: 'Get a list of synced files',
56
+ documentationUrl: '/api-docs#tag/Files/operation/crowdin.files',
57
+ },
58
+ {
59
+ key: 'crowdin-files-api',
60
+ name: 'File Translation Progress',
61
+ url: '/file-progress',
62
+ method: models_1.RequestMethods.GET,
63
+ description: 'Get file translation progress',
64
+ documentationUrl: '/api-docs#tag/Files/operation/file.progress',
65
+ },
66
+ {
67
+ key: 'integration-files-api',
68
+ name: 'Get Integration Files',
69
+ url: '/integration-files',
70
+ method: models_1.RequestMethods.GET,
71
+ description: 'Get integration data',
72
+ documentationUrl: '/api-docs#tag/Files/operation/integration.files',
73
+ },
74
+ {
75
+ key: 'crowdin-update-api',
76
+ name: 'Update Crowdin',
77
+ url: '/crowdin-update',
78
+ method: models_1.RequestMethods.POST,
79
+ description: 'Update crowdin data',
80
+ documentationUrl: '/api-docs#tag/Files/operation/crowdin.update',
81
+ },
82
+ {
83
+ key: 'integration-update-api',
84
+ name: 'Update Integration',
85
+ url: '/integration-update',
86
+ method: models_1.RequestMethods.POST,
87
+ description: 'Update integration data',
88
+ documentationUrl: '/api-docs#tag/Files/operation/integration.update',
89
+ },
90
+ {
91
+ key: 'settings-api',
92
+ name: 'Get App Settings',
93
+ url: '/settings',
94
+ method: models_1.RequestMethods.GET,
95
+ documentationUrl: '/api-docs#tag/Settings/operation/settings.get',
96
+ },
97
+ {
98
+ key: 'settings-update-api',
99
+ name: 'Update App Settings',
100
+ url: '/settings',
101
+ method: models_1.RequestMethods.POST,
102
+ documentationUrl: '/api-docs#tag/Settings/operation/settings.update',
103
+ },
104
+ {
105
+ key: 'sync-settings-api',
106
+ name: 'Get Sync Settings',
107
+ url: '/sync-settings',
108
+ method: models_1.RequestMethods.GET,
109
+ documentationUrl: '/api-docs#tag/Settings/operation/sync.settings.get',
110
+ },
111
+ {
112
+ key: 'sync-settings-update-api',
113
+ name: 'Update Sync Settings',
114
+ url: '/sync-settings',
115
+ method: models_1.RequestMethods.POST,
116
+ documentationUrl: '/api-docs#tag/Settings/operation/sync.settings.update',
117
+ },
118
+ ];
119
+ if ((_a = config.projectIntegration) === null || _a === void 0 ? void 0 : _a.loginForm) {
120
+ apiModuleManifest.push({
121
+ key: 'login-data',
122
+ name: 'Get Login Fields',
123
+ url: '/login-fields',
124
+ method: models_1.RequestMethods.GET,
125
+ documentationUrl: '/api-docs#tag/Login/operation/integration.fields',
126
+ }, {
127
+ key: 'login',
128
+ name: 'Login',
129
+ url: '/login',
130
+ method: models_1.RequestMethods.POST,
131
+ documentationUrl: '/api-docs#tag/Login/operation/integration.login',
132
+ });
133
+ }
134
+ return apiModuleManifest;
135
+ }
136
+ function updateCrowdinContext(req, context) {
137
+ var _a, _b, _c;
138
+ if ((_a = req.body) === null || _a === void 0 ? void 0 : _a.projectId) {
139
+ if (context.clientId.includes('undefined')) {
140
+ context.clientId = `${context.jwtPayload.domain || context.jwtPayload.context.organization_id}__${(_b = req.body) === null || _b === void 0 ? void 0 : _b.projectId}__${context.jwtPayload.sub}`;
141
+ }
142
+ // eslint-disable-next-line @typescript-eslint/camelcase
143
+ context.jwtPayload.context.project_id = (_c = req.body) === null || _c === void 0 ? void 0 : _c.projectId;
144
+ }
145
+ return context;
146
+ }
147
+ exports.updateCrowdinContext = updateCrowdinContext;
148
+ function getFormFields(fields) {
149
+ const formFields = [];
150
+ for (const field of fields) {
151
+ if (field === null || field === void 0 ? void 0 : field.key) {
152
+ formFields.push({
153
+ name: field.label,
154
+ key: field.key,
155
+ });
156
+ }
157
+ }
158
+ return formFields;
159
+ }
160
+ function addDefaultApiEndpoints(app, config) {
161
+ if (config.projectIntegration) {
162
+ /**
163
+ * @openapi
164
+ * /crowdin-files:
165
+ * get:
166
+ * summary: List Crowdin Files
167
+ * operationId: crowdin.files
168
+ * tags:
169
+ * - 'Files'
170
+ * parameters:
171
+ * - $ref: '#/components/parameters/ProjectId'
172
+ * responses:
173
+ * 200:
174
+ * description: 'Project files list'
175
+ * content:
176
+ * application/json:
177
+ * schema:
178
+ * properties:
179
+ * data:
180
+ * $ref: '#/components/schemas/CrowdinFiles'
181
+ */
182
+ app.get('/crowdin-files', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, crowdin_files_1.default)(config, config.projectIntegration));
183
+ /**
184
+ * @openapi
185
+ * /file-progress:
186
+ * get:
187
+ * tags:
188
+ * - 'Files'
189
+ * summary: 'Get File Progress'
190
+ * operationId: file.progress
191
+ * parameters:
192
+ * - $ref: '#/components/parameters/ProjectId'
193
+ * -
194
+ * name: fileId
195
+ * in: query
196
+ * required: true
197
+ * description: 'Filter branch by name. Get via [List Crowdin Files](#operation/crowdin.files)'
198
+ * schema:
199
+ * type: integer
200
+ * example: 102
201
+ * responses:
202
+ * 200:
203
+ * description: 'File translation progress'
204
+ * content:
205
+ * application/json:
206
+ * schema:
207
+ * properties:
208
+ * data:
209
+ * $ref: '#/components/schemas/FileProgress'
210
+ */
211
+ app.get('/file-progress', (0, crowdin_client_1.default)(config), (0, crowdin_file_progress_1.default)(config, config.projectIntegration));
212
+ /**
213
+ * @openapi
214
+ * /integration-files:
215
+ * get:
216
+ * summary: 'List Integration Files'
217
+ * operationId: integration.files
218
+ * tags:
219
+ * - 'Files'
220
+ * parameters:
221
+ * - $ref: '#/components/parameters/ProjectId'
222
+ * responses:
223
+ * 200:
224
+ * description: 'Integration files list'
225
+ * content:
226
+ * application/json:
227
+ * schema:
228
+ * properties:
229
+ * data:
230
+ * $ref: '#/components/schemas/IntegrationFiles'
231
+ *
232
+ */
233
+ app.get('/integration-files', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, integration_data_1.default)(config, config.projectIntegration));
234
+ /**
235
+ * @openapi
236
+ * /crowdin-update:
237
+ * post:
238
+ * tags:
239
+ * - 'Files'
240
+ * summary: 'Update Crowdin Files'
241
+ * operationId: crowdin.update
242
+ * requestBody:
243
+ * content:
244
+ * application/json:
245
+ * schema:
246
+ * $ref: '#/components/schemas/UpdateCrowdinFiles'
247
+ * responses:
248
+ * 200:
249
+ * content:
250
+ * application/json:
251
+ * schema:
252
+ * properties:
253
+ * data:
254
+ * $ref: '#/components/schemas/UpdateResponse'
255
+ */
256
+ app.post('/crowdin-update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, crowdin_update_1.default)(config, config.projectIntegration));
257
+ /**
258
+ * @openapi
259
+ * /integration-update:
260
+ * post:
261
+ * tags:
262
+ * - 'Files'
263
+ * summary: 'Update Integration Files'
264
+ * operationId: integration.update
265
+ * requestBody:
266
+ * content:
267
+ * application/json:
268
+ * schema:
269
+ * $ref: '#/components/schemas/FileLanguagePair'
270
+ * responses:
271
+ * 200:
272
+ * content:
273
+ * application/json:
274
+ * schema:
275
+ * properties:
276
+ * data:
277
+ * $ref: '#/components/schemas/UpdateResponse'
278
+ */
279
+ app.post('/integration-update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, integration_update_1.default)(config, config.projectIntegration));
280
+ /**
281
+ * @openapi
282
+ * /settings:
283
+ * get:
284
+ * tags:
285
+ * - 'Settings'
286
+ * summary: 'Get Application Settings'
287
+ * operationId: settings.get
288
+ * parameters:
289
+ * - $ref: '#/components/parameters/ProjectId'
290
+ * responses:
291
+ * 200:
292
+ * description: 'File translation progress'
293
+ * content:
294
+ * application/json:
295
+ * schema:
296
+ * properties:
297
+ * data:
298
+ * $ref: '#/components/schemas/SettingsResponse'
299
+ */
300
+ app.get('/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, settings_1.default)(config));
301
+ /**
302
+ * @openapi
303
+ * /settings:
304
+ * post:
305
+ * tags:
306
+ * - 'Settings'
307
+ * summary: 'Update Application Settings'
308
+ * operationId: settings.update
309
+ * requestBody:
310
+ * content:
311
+ * application/json:
312
+ * schema:
313
+ * $ref: '#/components/schemas/UpdateSettingsData'
314
+ * responses:
315
+ * 204:
316
+ * description: 'Application Settings was successfully update'
317
+ */
318
+ app.post('/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, settings_save_1.default)(config, config.projectIntegration));
319
+ /**
320
+ * @openapi
321
+ * /sync-settings:
322
+ * get:
323
+ * tags:
324
+ * - 'Settings'
325
+ * summary: 'Get Sync Settings'
326
+ * operationId: sync.settings.get
327
+ * parameters:
328
+ * - $ref: '#/components/parameters/ProjectId'
329
+ * - name: provider
330
+ * in: query
331
+ * required: true
332
+ * schema:
333
+ * type: string
334
+ * enum:
335
+ * - crowdin
336
+ * - integration
337
+ * responses:
338
+ * 200:
339
+ * description: 'Application Sync Settings'
340
+ * content:
341
+ * application/json:
342
+ * schema:
343
+ * properties:
344
+ * data:
345
+ * oneOf:
346
+ * - { $ref: '#/components/schemas/CrowdinSyncSettingsResponse' }
347
+ * - { $ref: '#/components/schemas/IntegrationSyncSettingsResponse' }
348
+ */
349
+ app.get('/sync-settings', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, sync_settings_1.default)(config));
350
+ /**
351
+ * @openapi
352
+ * /sync-settings:
353
+ * post:
354
+ * tags:
355
+ * - 'Settings'
356
+ * summary: 'Update Sync Settings'
357
+ * operationId: sync.settings.update
358
+ * requestBody:
359
+ * content:
360
+ * application/json:
361
+ * schema:
362
+ * $ref: '#/components/schemas/UpdateSyncSettingsData'
363
+ * responses:
364
+ * 204:
365
+ * description: 'Application Sync Settings was successfully update'
366
+ */
367
+ app.post('/sync-settings', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, config.projectIntegration), (0, sync_settings_save_1.default)(config, config.projectIntegration));
368
+ if (config.projectIntegration.loginForm) {
369
+ /**
370
+ * @openapi
371
+ * /login-fields:
372
+ * get:
373
+ * tags:
374
+ * - 'Login'
375
+ * summary: 'Integration Login Form Fields'
376
+ * operationId: integration.fields
377
+ * responses:
378
+ * 200:
379
+ * description: 'File translation progress'
380
+ * content:
381
+ * application/json:
382
+ * schema:
383
+ * properties:
384
+ * data:
385
+ * $ref: '#/components/schemas/LoginFieldsResponse'
386
+ */
387
+ app.get('/login-fields', json_response_1.default, (0, crowdin_client_1.default)(config), (req, res) => {
388
+ var _a;
389
+ let fields = [];
390
+ if ((_a = config.projectIntegration) === null || _a === void 0 ? void 0 : _a.loginForm.fields) {
391
+ fields = getFormFields(config === null || config === void 0 ? void 0 : config.projectIntegration.loginForm.fields);
392
+ }
393
+ res.send({ fields });
394
+ });
395
+ /**
396
+ * @openapi
397
+ * /login:
398
+ * post:
399
+ * tags:
400
+ * - 'Login'
401
+ * summary: 'Integration Login'
402
+ * operationId: integration.login
403
+ * requestBody:
404
+ * content:
405
+ * application/json:
406
+ * schema:
407
+ * $ref: '#/components/schemas/Login'
408
+ * responses:
409
+ * 204:
410
+ * description: 'Login successful'
411
+ */
412
+ app.post('/login', (0, crowdin_client_1.default)(config, false, false), (0, integration_login_1.default)(config, config.projectIntegration));
413
+ }
414
+ }
415
+ }
416
+ exports.addDefaultApiEndpoints = addDefaultApiEndpoints;
417
+ function addSwagerApiDocumentation(app, config) {
418
+ var _a, _b;
419
+ const options = {
420
+ swaggerDefinition: {
421
+ openapi: '3.0.0',
422
+ info: {
423
+ title: `${config.name} Application API`,
424
+ version: '1.0.0',
425
+ 'x-logo': {
426
+ url: 'https://support.crowdin.com/assets/crowdin-logo.svg',
427
+ },
428
+ },
429
+ servers: [
430
+ {
431
+ url: `{protocol}//{host}/api/v2/applications/${config.identifier}/api`,
432
+ },
433
+ ],
434
+ },
435
+ apis: [path_1.default.resolve(__dirname, './base.js'), path_1.default.resolve(__dirname, './components.js'), __filename],
436
+ };
437
+ if ((_a = config.api) === null || _a === void 0 ? void 0 : _a.docFile) {
438
+ options.apis.push(config.api.docFile);
439
+ }
440
+ const swaggerSpec = (0, swagger_jsdoc_1.default)(options);
441
+ // remove Login info from doc
442
+ if (!((_b = config.projectIntegration) === null || _b === void 0 ? void 0 : _b.loginForm)) {
443
+ delete swaggerSpec.paths['/login'];
444
+ delete swaggerSpec.paths['/login-fields'];
445
+ delete swaggerSpec.components.schemas['Login'];
446
+ delete swaggerSpec.components.schemas['LoginData'];
447
+ swaggerSpec.tags = swaggerSpec.tags.filter((tag) => tag.name !== 'Login');
448
+ }
449
+ app.get('/api-docs/swagger.json', (req, res) => res.send(swaggerSpec));
450
+ app.use('/api-docs', (0, redoc_express_1.default)({ title: '', specUrl: '/api-docs/swagger.json' }));
451
+ }
452
+ exports.addSwagerApiDocumentation = addSwagerApiDocumentation;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @openapi
3
+ * tags:
4
+ * - name: 'Files'
5
+ * - name: 'Settings'
6
+ * - name: 'Login'
7
+ */
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * @openapi
4
+ * tags:
5
+ * - name: 'Files'
6
+ * - name: 'Settings'
7
+ * - name: 'Login'
8
+ */