@crowdin/app-project-module 0.28.11 → 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 +8 -1
  15. package/out/middlewares/crowdin-client.js +5 -0
  16. package/out/models/index.d.ts +56 -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
@@ -0,0 +1,227 @@
1
+ /**
2
+ * @openapi
3
+ * components:
4
+ * schemas:
5
+ * CrowdinFiles:
6
+ * type: array
7
+ * example: [{id: 1, name: Landing pages}, {id: 2, parentId: 1, name: Home Page, type: json}]
8
+ * items:
9
+ * anyOf:
10
+ * - properties:
11
+ * id:
12
+ * type: string
13
+ * name:
14
+ * type: string
15
+ * - properties:
16
+ * id:
17
+ * type: string
18
+ * parentId:
19
+ * type: string
20
+ * name:
21
+ * type: string
22
+ * type:
23
+ * type: string
24
+ * IntegrationFiles:
25
+ * type: array
26
+ * example: [{id: 1, name: Landing pages, parent_id: 0, node_type: 0}, {name: Intro, id: 73291251883, parentId: Landing pages, type: json, node_type: 1}]
27
+ * items:
28
+ * anyOf:
29
+ * - properties:
30
+ * id:
31
+ * type: string
32
+ * name:
33
+ * type: string
34
+ * parent_id:
35
+ * type: string
36
+ * node_type:
37
+ * type: string
38
+ * - properties:
39
+ * name:
40
+ * type: string
41
+ * id:
42
+ * type: string
43
+ * parentId:
44
+ * type: string
45
+ * type:
46
+ * type: string
47
+ * node_type:
48
+ * type: string
49
+ * UpdateCrowdinFiles:
50
+ * title: 'Update files'
51
+ * required:
52
+ * - projectId
53
+ * - files
54
+ * properties:
55
+ * projectId:
56
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
57
+ * type: integer
58
+ * example: 12
59
+ * files:
60
+ * $ref: '#/components/schemas/IntegrationFiles'
61
+ * uploadTranslations:
62
+ * description: 'Upload exist translation from integration'
63
+ * type: boolean
64
+ * default: false
65
+ * example: true
66
+ * FileLanguagePair:
67
+ * title: 'Update files'
68
+ * required:
69
+ * - projectId
70
+ * - files
71
+ * properties:
72
+ * projectId:
73
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
74
+ * type: integer
75
+ * example: 12
76
+ * files:
77
+ * type: object
78
+ * example:
79
+ * 102: ['uk', 'de']
80
+ * additionalProperties:
81
+ * type: array
82
+ * items:
83
+ * type: string
84
+ * UpdateResponse:
85
+ * type: object
86
+ * items:
87
+ * anyOf:
88
+ * - properties:
89
+ * message:
90
+ * type: string
91
+ * example: 'File 102 Not Found'
92
+ * SettingsData:
93
+ * type: object
94
+ * example: {syncType: 0, schedule: 0, condition: 0}
95
+ * additionalProperties:
96
+ * type: string
97
+ * UpdateSettingsData:
98
+ * title: 'Update Application Settings'
99
+ * required:
100
+ * - projectId
101
+ * - config
102
+ * properties:
103
+ * projectId:
104
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
105
+ * type: integer
106
+ * example: 12
107
+ * config:
108
+ * $ref: '#/components/schemas/SettingsData'
109
+ * SettingsResponse:
110
+ * $ref: '#/components/schemas/SettingsData'
111
+ * CrowdinSyncSettingsResponse:
112
+ * type: object
113
+ * example:
114
+ * 102: ['uk', 'de']
115
+ * additionalProperties:
116
+ * type: array
117
+ * items:
118
+ * type: string
119
+ * IntegrationSyncSettingsResponse:
120
+ * type: array
121
+ * items:
122
+ * type: object
123
+ * properties:
124
+ * name:
125
+ * type: string
126
+ * id:
127
+ * type: string
128
+ * parentId:
129
+ * type: string
130
+ * type:
131
+ * type: string
132
+ * node_type:
133
+ * type: string
134
+ * schedule:
135
+ * type: boolean
136
+ * UpdateSyncSettingsData:
137
+ * title: 'Update Application Sync Settings'
138
+ * required:
139
+ * - projectId
140
+ * - provider
141
+ * - files
142
+ * properties:
143
+ * projectId:
144
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
145
+ * type: integer
146
+ * example: 12
147
+ * provider:
148
+ * type: string
149
+ * enum:
150
+ * - crowdin
151
+ * - integration
152
+ * files:
153
+ * oneOf:
154
+ * - { $ref: '#/components/schemas/CrowdinSyncSettingsResponse' }
155
+ * - { $ref: '#/components/schemas/IntegrationSyncSettingsResponse' }
156
+ * FileProgress:
157
+ * title: 'Language Translation Progress'
158
+ * description: 'Language Translation File Progress Response Model'
159
+ * type: object
160
+ * properties:
161
+ * languageId:
162
+ * type: string
163
+ * example: af
164
+ * eTag:
165
+ * type: string
166
+ * example: fd0ea167420ef1687fd16635b9fb67a3
167
+ * words:
168
+ * properties:
169
+ * total:
170
+ * type: integer
171
+ * example: 7249
172
+ * translated:
173
+ * type: integer
174
+ * example: 3651
175
+ * approved:
176
+ * type: integer
177
+ * example: 3637
178
+ * type: object
179
+ * phrases:
180
+ * properties:
181
+ * total:
182
+ * type: integer
183
+ * example: 3041
184
+ * translated:
185
+ * type: integer
186
+ * example: 2631
187
+ * approved:
188
+ * type: integer
189
+ * example: 2622
190
+ * type: object
191
+ * translationProgress:
192
+ * type: integer
193
+ * example: 86
194
+ * approvalProgress:
195
+ * type: integer
196
+ * example: 86
197
+ * LoginFieldsResponse:
198
+ * example: [{ name: 'email', description: 'User email' }, { name: 'password', description: 'User password' }]
199
+ * type: object
200
+ * Login:
201
+ * title: 'Login'
202
+ * required:
203
+ * - projectId
204
+ * - credentials
205
+ * properties:
206
+ * projectId:
207
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
208
+ * type: integer
209
+ * example: 12
210
+ * credentials:
211
+ * $ref: '#/components/schemas/LoginData'
212
+ * LoginData:
213
+ * type: object
214
+ * example: { email: 'user@crowdin.com', password: 'password' }
215
+ * additionalProperties:
216
+ * type: string
217
+ *
218
+ * parameters:
219
+ * ProjectId:
220
+ * name: projectId
221
+ * in: query
222
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
223
+ * required: true
224
+ * schema:
225
+ * type: integer
226
+ * example: 12
227
+ */
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ /**
3
+ * @openapi
4
+ * components:
5
+ * schemas:
6
+ * CrowdinFiles:
7
+ * type: array
8
+ * example: [{id: 1, name: Landing pages}, {id: 2, parentId: 1, name: Home Page, type: json}]
9
+ * items:
10
+ * anyOf:
11
+ * - properties:
12
+ * id:
13
+ * type: string
14
+ * name:
15
+ * type: string
16
+ * - properties:
17
+ * id:
18
+ * type: string
19
+ * parentId:
20
+ * type: string
21
+ * name:
22
+ * type: string
23
+ * type:
24
+ * type: string
25
+ * IntegrationFiles:
26
+ * type: array
27
+ * example: [{id: 1, name: Landing pages, parent_id: 0, node_type: 0}, {name: Intro, id: 73291251883, parentId: Landing pages, type: json, node_type: 1}]
28
+ * items:
29
+ * anyOf:
30
+ * - properties:
31
+ * id:
32
+ * type: string
33
+ * name:
34
+ * type: string
35
+ * parent_id:
36
+ * type: string
37
+ * node_type:
38
+ * type: string
39
+ * - properties:
40
+ * name:
41
+ * type: string
42
+ * id:
43
+ * type: string
44
+ * parentId:
45
+ * type: string
46
+ * type:
47
+ * type: string
48
+ * node_type:
49
+ * type: string
50
+ * UpdateCrowdinFiles:
51
+ * title: 'Update files'
52
+ * required:
53
+ * - projectId
54
+ * - files
55
+ * properties:
56
+ * projectId:
57
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
58
+ * type: integer
59
+ * example: 12
60
+ * files:
61
+ * $ref: '#/components/schemas/IntegrationFiles'
62
+ * uploadTranslations:
63
+ * description: 'Upload exist translation from integration'
64
+ * type: boolean
65
+ * default: false
66
+ * example: true
67
+ * FileLanguagePair:
68
+ * title: 'Update files'
69
+ * required:
70
+ * - projectId
71
+ * - files
72
+ * properties:
73
+ * projectId:
74
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
75
+ * type: integer
76
+ * example: 12
77
+ * files:
78
+ * type: object
79
+ * example:
80
+ * 102: ['uk', 'de']
81
+ * additionalProperties:
82
+ * type: array
83
+ * items:
84
+ * type: string
85
+ * UpdateResponse:
86
+ * type: object
87
+ * items:
88
+ * anyOf:
89
+ * - properties:
90
+ * message:
91
+ * type: string
92
+ * example: 'File 102 Not Found'
93
+ * SettingsData:
94
+ * type: object
95
+ * example: {syncType: 0, schedule: 0, condition: 0}
96
+ * additionalProperties:
97
+ * type: string
98
+ * UpdateSettingsData:
99
+ * title: 'Update Application Settings'
100
+ * required:
101
+ * - projectId
102
+ * - config
103
+ * properties:
104
+ * projectId:
105
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
106
+ * type: integer
107
+ * example: 12
108
+ * config:
109
+ * $ref: '#/components/schemas/SettingsData'
110
+ * SettingsResponse:
111
+ * $ref: '#/components/schemas/SettingsData'
112
+ * CrowdinSyncSettingsResponse:
113
+ * type: object
114
+ * example:
115
+ * 102: ['uk', 'de']
116
+ * additionalProperties:
117
+ * type: array
118
+ * items:
119
+ * type: string
120
+ * IntegrationSyncSettingsResponse:
121
+ * type: array
122
+ * items:
123
+ * type: object
124
+ * properties:
125
+ * name:
126
+ * type: string
127
+ * id:
128
+ * type: string
129
+ * parentId:
130
+ * type: string
131
+ * type:
132
+ * type: string
133
+ * node_type:
134
+ * type: string
135
+ * schedule:
136
+ * type: boolean
137
+ * UpdateSyncSettingsData:
138
+ * title: 'Update Application Sync Settings'
139
+ * required:
140
+ * - projectId
141
+ * - provider
142
+ * - files
143
+ * properties:
144
+ * projectId:
145
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
146
+ * type: integer
147
+ * example: 12
148
+ * provider:
149
+ * type: string
150
+ * enum:
151
+ * - crowdin
152
+ * - integration
153
+ * files:
154
+ * oneOf:
155
+ * - { $ref: '#/components/schemas/CrowdinSyncSettingsResponse' }
156
+ * - { $ref: '#/components/schemas/IntegrationSyncSettingsResponse' }
157
+ * FileProgress:
158
+ * title: 'Language Translation Progress'
159
+ * description: 'Language Translation File Progress Response Model'
160
+ * type: object
161
+ * properties:
162
+ * languageId:
163
+ * type: string
164
+ * example: af
165
+ * eTag:
166
+ * type: string
167
+ * example: fd0ea167420ef1687fd16635b9fb67a3
168
+ * words:
169
+ * properties:
170
+ * total:
171
+ * type: integer
172
+ * example: 7249
173
+ * translated:
174
+ * type: integer
175
+ * example: 3651
176
+ * approved:
177
+ * type: integer
178
+ * example: 3637
179
+ * type: object
180
+ * phrases:
181
+ * properties:
182
+ * total:
183
+ * type: integer
184
+ * example: 3041
185
+ * translated:
186
+ * type: integer
187
+ * example: 2631
188
+ * approved:
189
+ * type: integer
190
+ * example: 2622
191
+ * type: object
192
+ * translationProgress:
193
+ * type: integer
194
+ * example: 86
195
+ * approvalProgress:
196
+ * type: integer
197
+ * example: 86
198
+ * LoginFieldsResponse:
199
+ * example: [{ name: 'email', description: 'User email' }, { name: 'password', description: 'User password' }]
200
+ * type: object
201
+ * Login:
202
+ * title: 'Login'
203
+ * required:
204
+ * - projectId
205
+ * - credentials
206
+ * properties:
207
+ * projectId:
208
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
209
+ * type: integer
210
+ * example: 12
211
+ * credentials:
212
+ * $ref: '#/components/schemas/LoginData'
213
+ * LoginData:
214
+ * type: object
215
+ * example: { email: 'user@crowdin.com', password: 'password' }
216
+ * additionalProperties:
217
+ * type: string
218
+ *
219
+ * parameters:
220
+ * ProjectId:
221
+ * name: projectId
222
+ * in: query
223
+ * description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
224
+ * required: true
225
+ * schema:
226
+ * type: integer
227
+ * example: 12
228
+ */
@@ -1,3 +1,4 @@
1
- import { Config, CronJob, IntegrationLogic } from '../models';
1
+ import { Config, CronJob, IntegrationLogic, Provider, IntegrationRequest } from '../models';
2
2
  export declare function runJob(config: Config, integration: IntegrationLogic, job: CronJob): Promise<void>;
3
3
  export declare function filesCron(config: Config, integration: IntegrationLogic, period: string): Promise<void>;
4
+ export declare function createOrUpdateSyncSettings(config: Config, req: IntegrationRequest, files: any, provider: Provider, onlyCreate?: boolean): Promise<void>;
package/out/util/cron.js CHANGED
@@ -32,13 +32,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.filesCron = exports.runJob = void 0;
35
+ exports.createOrUpdateSyncSettings = exports.filesCron = exports.runJob = void 0;
36
36
  const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
37
37
  const _1 = require(".");
38
38
  const models_1 = require("../models");
39
39
  const storage_1 = require("../storage");
40
40
  const connection_1 = require("./connection");
41
41
  const defaults_1 = require("./defaults");
42
+ const file_snapshot_1 = require("./file-snapshot");
42
43
  function runJob(config, integration, job) {
43
44
  return __awaiter(this, void 0, void 0, function* () {
44
45
  (0, _1.log)(`Starting cron job with expression [${job.expression}]`, config.logger);
@@ -72,7 +73,9 @@ function filesCron(config, integration, period) {
72
73
  (0, _1.log)(`Starting files cron job with period [${period}]`, config.logger);
73
74
  const syncSettingsList = yield (0, storage_1.getStorage)().getAllSyncSettingsByType('schedule');
74
75
  yield Promise.all(syncSettingsList.map((syncSettings) => __awaiter(this, void 0, void 0, function* () {
76
+ var _a;
75
77
  const files = JSON.parse(syncSettings.files);
78
+ let newFiles = [];
76
79
  const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(syncSettings.crowdinId);
77
80
  const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(syncSettings.integrationId);
78
81
  if (!crowdinCredentials || !integrationCredentials) {
@@ -92,10 +95,24 @@ function filesCron(config, integration, period) {
92
95
  return;
93
96
  }
94
97
  const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
98
+ const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
95
99
  //split invocation into chunks to avoid expiration issues
96
100
  const chunkSize = 10;
97
- if (syncSettings.provider === 'crowdin') {
98
- const crowdinFiles = files;
101
+ if ((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[syncSettings.provider]) {
102
+ newFiles = yield (0, file_snapshot_1.getAllNewFiles)({
103
+ config,
104
+ integration,
105
+ crowdinApiClient: crowdinClient,
106
+ crowdinId: crowdinCredentials.id,
107
+ integrationCredentials: apiCredentials,
108
+ integrationId: integrationCredentials.id,
109
+ projectId,
110
+ integrationSettings: intConfig,
111
+ syncSettings,
112
+ });
113
+ }
114
+ if (syncSettings.provider === models_1.Provider.CROWDIN) {
115
+ const crowdinFiles = yield skipFoldersFromIntegrationRequest(config, integration, projectId, Object.assign(Object.assign({}, files), newFiles), crowdinClient);
99
116
  const onlyTranslated = +intConfig.condition === models_1.SyncCondition.TRANSLATED;
100
117
  const onlyApproved = +intConfig.condition === models_1.SyncCondition.APPROVED;
101
118
  const all = +intConfig.condition === models_1.SyncCondition.ALL || intConfig.condition === undefined;
@@ -118,15 +135,20 @@ function filesCron(config, integration, period) {
118
135
  const { client } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
119
136
  yield integration.updateIntegration(projectId, client, apiCredentials, filesChunk, rootFolder, intConfig);
120
137
  }
138
+ if (newFiles) {
139
+ yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(Object.assign(Object.assign({}, files), newFiles)), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
140
+ const currentFileSnapshot = yield (0, file_snapshot_1.getCrowdinSnapshot)(config, integration, crowdinClient, projectId, intConfig);
141
+ yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(currentFileSnapshot), syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
142
+ }
121
143
  (0, _1.log)(`updateIntegration task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
122
144
  }
123
145
  else {
124
- const intFiles = files.map((file) => ({
125
- id: file.id,
126
- name: file.name,
127
- parentId: file.parent_id,
128
- type: file.type,
129
- }));
146
+ const allIntFiles = [...files, ...newFiles].map((file) => (Object.assign({ id: file.id, name: file.name, parentId: file.parent_id || file.parentId,
147
+ // eslint-disable-next-line @typescript-eslint/camelcase
148
+ parent_id: file.parent_id || file.parentId,
149
+ // eslint-disable-next-line @typescript-eslint/camelcase
150
+ node_type: file.nodeType || file.node_type }, (file.type ? { type: file.type } : {}))));
151
+ const intFiles = allIntFiles.filter((file) => 'type' in file);
130
152
  (0, _1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}. Files ${intFiles.length}`, config.logger);
131
153
  for (let i = 0; i < intFiles.length; i += chunkSize) {
132
154
  const chunk = intFiles.slice(i, i + chunkSize);
@@ -134,6 +156,12 @@ function filesCron(config, integration, period) {
134
156
  const { client } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
135
157
  yield integration.updateCrowdin(projectId, client, apiCredentials, chunk, rootFolder, intConfig);
136
158
  }
159
+ const newSyncSettingsFiels = allIntFiles.map((file) => (Object.assign(Object.assign({}, file), { schedule: true, sync: false })));
160
+ if (newFiles) {
161
+ yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(newSyncSettingsFiels), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
162
+ const currentFileSnapshot = yield (0, file_snapshot_1.getIntegrationSnapshot)(integration, apiCredentials, intConfig);
163
+ yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(currentFileSnapshot), syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
164
+ }
137
165
  (0, _1.log)(`updateCrowdin task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
138
166
  }
139
167
  })));
@@ -194,3 +222,42 @@ function getOnlyTranslatedOrApprovedFiles(config, projectId, crowdinFiles, crowd
194
222
  return filteredFiles;
195
223
  });
196
224
  }
225
+ function skipFoldersFromIntegrationRequest(config, integration, projectId, crowdinFiles, crowdinClient) {
226
+ var _a;
227
+ return __awaiter(this, void 0, void 0, function* () {
228
+ let folders;
229
+ if ((_a = config.projectIntegration) === null || _a === void 0 ? void 0 : _a.withRootFolder) {
230
+ const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
231
+ if (rootFolder) {
232
+ folders = (yield crowdinClient.sourceFilesApi.withFetchAll().listProjectDirectories(projectId, {
233
+ directoryId: rootFolder.id,
234
+ })).data;
235
+ }
236
+ }
237
+ else {
238
+ folders = (yield crowdinClient.sourceFilesApi.withFetchAll().listProjectDirectories(projectId)).data;
239
+ }
240
+ if (folders) {
241
+ for (const fileId of Object.keys(crowdinFiles)) {
242
+ if (folders.find((folder) => folder.data.id === +fileId)) {
243
+ delete crowdinFiles[fileId];
244
+ }
245
+ }
246
+ }
247
+ return crowdinFiles;
248
+ });
249
+ }
250
+ function createOrUpdateSyncSettings(config, req, files, provider, onlyCreate = false) {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ const existingSettings = yield (0, storage_1.getStorage)().getSyncSettings(req.crowdinContext.clientId, req.crowdinContext.crowdinId, 'schedule', provider);
253
+ if (!existingSettings) {
254
+ (0, _1.log)(`Saving sync settings for type schedule and provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
255
+ yield (0, storage_1.getStorage)().saveSyncSettings(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, 'schedule', provider);
256
+ }
257
+ else if (!onlyCreate) {
258
+ (0, _1.log)(`Updating sync settings for type schedule and provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
259
+ yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, 'schedule', provider);
260
+ }
261
+ });
262
+ }
263
+ exports.createOrUpdateSyncSettings = createOrUpdateSyncSettings;
@@ -128,7 +128,7 @@ function applyIntegrationModuleDefaults(config, integration) {
128
128
  return { [fileId]: progress.data.map((e) => e.data) };
129
129
  });
130
130
  }
131
- if (!integration.loginForm) {
131
+ if (!integration.oauthLogin && !integration.loginForm) {
132
132
  integration.loginForm = {
133
133
  fields: [
134
134
  {
@@ -142,6 +142,7 @@ function applyIntegrationModuleDefaults(config, integration) {
142
142
  if (integration.withCronSync || integration.webhooks) {
143
143
  const getUserSettings = integration.getConfiguration;
144
144
  integration.getConfiguration = (projectId, crowdinClient, integrationCredentials) => __awaiter(this, void 0, void 0, function* () {
145
+ var _b, _c;
145
146
  let fields = [];
146
147
  if (getUserSettings) {
147
148
  fields = yield getUserSettings(projectId, crowdinClient, integrationCredentials);
@@ -175,7 +176,7 @@ function applyIntegrationModuleDefaults(config, integration) {
175
176
  helpText: 'Set the frequency for pushing sources and translations',
176
177
  type: 'select',
177
178
  defaultValue: '0',
178
- dependencySettings: "[{'#syncType-settings':{'type':'equal','value':['1']} }]",
179
+ dependencySettings: JSON.stringify([{ '#syncType-settings': { type: 'equal', value: ['1'] } }]),
179
180
  options: [
180
181
  {
181
182
  value: '0',
@@ -210,6 +211,26 @@ function applyIntegrationModuleDefaults(config, integration) {
210
211
  label: 'Webhooks',
211
212
  });
212
213
  }
214
+ if ((_b = integration.syncNewElements) === null || _b === void 0 ? void 0 : _b.crowdin) {
215
+ defaultSettings.push({
216
+ key: 'new-crowdin-files',
217
+ label: 'Sync new items from Crowdin',
218
+ type: 'checkbox',
219
+ dependencySettings: JSON.stringify([
220
+ { '#syncType-settings': { type: 'equal', value: ['1', '2'] } },
221
+ ]),
222
+ });
223
+ }
224
+ if ((_c = integration.syncNewElements) === null || _c === void 0 ? void 0 : _c.integration) {
225
+ defaultSettings.push({
226
+ key: 'new-integration-files',
227
+ label: `Sync new items from ${config.name}`,
228
+ type: 'checkbox',
229
+ dependencySettings: JSON.stringify([
230
+ { '#syncType-settings': { type: 'equal', value: ['1', '2'] } },
231
+ ]),
232
+ });
233
+ }
213
234
  return [
214
235
  ...defaultSettings,
215
236
  {
@@ -217,7 +238,9 @@ function applyIntegrationModuleDefaults(config, integration) {
217
238
  label: 'Files export settings',
218
239
  type: 'select',
219
240
  defaultValue: '0',
220
- dependencySettings: "[{'#syncType-settings':{'type':'equal','value':['1','2']}}]",
241
+ dependencySettings: JSON.stringify([
242
+ { '#syncType-settings': { type: 'equal', value: ['1', '2'] } },
243
+ ]),
221
244
  options: [
222
245
  {
223
246
  value: '0',
@@ -0,0 +1,7 @@
1
+ import { Config, GetAllNewFilesArgs, IntegrationLogic, IntegrationRequest, Provider, TreeItem, UpdateIntegrationRequest } from '../models';
2
+ import Crowdin from '@crowdin/crowdin-api-client';
3
+ export declare function getFileDiff(currentFiles: TreeItem[], savedFiles: TreeItem[]): TreeItem[];
4
+ export declare function getAllNewFiles(args: GetAllNewFilesArgs): Promise<TreeItem[] | UpdateIntegrationRequest>;
5
+ export declare function getCrowdinSnapshot(config: Config, integration: IntegrationLogic, crowdinApiClient: Crowdin, projectId: number, integrationSettings: any): Promise<TreeItem[]>;
6
+ export declare function getIntegrationSnapshot(integration: IntegrationLogic, integrationCredentials: any, integrationSettings: any): Promise<TreeItem[]>;
7
+ export declare function createOrUpdateFileSnapshot(config: Config, integration: IntegrationLogic, req: IntegrationRequest, provider: Provider): Promise<void>;