@contentstack/datasync-manager 2.1.2 → 2.2.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.
- package/dist/api.js +9 -8
- package/dist/core/index.js +29 -28
- package/dist/core/inet.js +9 -8
- package/dist/core/plugins.js +7 -6
- package/dist/core/process.js +3 -2
- package/dist/core/q.js +12 -11
- package/dist/core/token-management.js +6 -5
- package/dist/index.js +69 -6
- package/dist/util/fs.js +7 -6
- package/dist/util/index.js +15 -11
- package/dist/util/messages.js +157 -0
- package/dist/util/unprocessible.js +4 -3
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -15,6 +15,7 @@ const path_1 = require("path");
|
|
|
15
15
|
const querystring_1 = require("querystring");
|
|
16
16
|
const sanitize_url_1 = require("@braintree/sanitize-url");
|
|
17
17
|
const fs_1 = require("./util/fs");
|
|
18
|
+
const messages_1 = require("./util/messages");
|
|
18
19
|
const debug = (0, debug_1.default)('api');
|
|
19
20
|
let MAX_RETRY_LIMIT;
|
|
20
21
|
let RETRY_DELAY_BASE = 200; // Default base delay in milliseconds
|
|
@@ -71,7 +72,7 @@ const get = (req, RETRY = 1) => {
|
|
|
71
72
|
timeout: TIMEOUT, // Configurable timeout to prevent socket hang ups
|
|
72
73
|
};
|
|
73
74
|
try {
|
|
74
|
-
debug(
|
|
75
|
+
debug(messages_1.MESSAGES.API.REQUEST(options.method, options.path));
|
|
75
76
|
let timeDelay;
|
|
76
77
|
let body = '';
|
|
77
78
|
const httpRequest = (0, https_1.request)(options, (response) => {
|
|
@@ -79,13 +80,13 @@ const get = (req, RETRY = 1) => {
|
|
|
79
80
|
.setEncoding('utf-8')
|
|
80
81
|
.on('data', (chunk) => body += chunk)
|
|
81
82
|
.on('end', () => {
|
|
82
|
-
debug(
|
|
83
|
+
debug(messages_1.MESSAGES.API.STATUS(response.statusCode));
|
|
83
84
|
if (response.statusCode >= 200 && response.statusCode <= 399) {
|
|
84
85
|
return resolve(JSON.parse(body));
|
|
85
86
|
}
|
|
86
87
|
else if (response.statusCode === 429) {
|
|
87
88
|
timeDelay = Math.pow(Math.SQRT2, RETRY) * RETRY_DELAY_BASE;
|
|
88
|
-
debug(
|
|
89
|
+
debug(messages_1.MESSAGES.API.RATE_LIMIT(options.path, timeDelay));
|
|
89
90
|
return setTimeout(() => {
|
|
90
91
|
return (0, exports.get)(req, RETRY)
|
|
91
92
|
.then(resolve)
|
|
@@ -95,7 +96,7 @@ const get = (req, RETRY = 1) => {
|
|
|
95
96
|
else if (response.statusCode >= 500) {
|
|
96
97
|
// retry, with delay
|
|
97
98
|
timeDelay = Math.pow(Math.SQRT2, RETRY) * RETRY_DELAY_BASE;
|
|
98
|
-
debug(
|
|
99
|
+
debug(messages_1.MESSAGES.API.RETRY(options.path, timeDelay));
|
|
99
100
|
RETRY++;
|
|
100
101
|
return setTimeout(() => {
|
|
101
102
|
return (0, exports.get)(req, RETRY)
|
|
@@ -104,25 +105,25 @@ const get = (req, RETRY = 1) => {
|
|
|
104
105
|
}, timeDelay);
|
|
105
106
|
}
|
|
106
107
|
else {
|
|
107
|
-
debug(
|
|
108
|
+
debug(messages_1.MESSAGES.API.REQUEST_FAILED(options));
|
|
108
109
|
return reject(body);
|
|
109
110
|
}
|
|
110
111
|
});
|
|
111
112
|
});
|
|
112
113
|
// Set socket timeout to handle socket hang ups
|
|
113
114
|
httpRequest.setTimeout(options.timeout, () => {
|
|
114
|
-
debug(
|
|
115
|
+
debug(messages_1.MESSAGES.API.REQUEST_TIMEOUT(options.path));
|
|
115
116
|
httpRequest.destroy();
|
|
116
117
|
reject(new Error('Request timeout'));
|
|
117
118
|
});
|
|
118
119
|
// Enhanced error handling for socket hang ups and connection resets
|
|
119
120
|
httpRequest.on('error', (error) => {
|
|
120
121
|
var _a;
|
|
121
|
-
debug(
|
|
122
|
+
debug(messages_1.MESSAGES.API.REQUEST_ERROR(options.path, error === null || error === void 0 ? void 0 : error.message, error === null || error === void 0 ? void 0 : error.code));
|
|
122
123
|
// Handle socket hang up and connection reset errors with retry
|
|
123
124
|
if (((error === null || error === void 0 ? void 0 : error.code) === 'ECONNRESET' || ((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('socket hang up'))) && RETRY <= MAX_RETRY_LIMIT) {
|
|
124
125
|
timeDelay = Math.pow(Math.SQRT2, RETRY) * RETRY_DELAY_BASE;
|
|
125
|
-
debug(
|
|
126
|
+
debug(messages_1.MESSAGES.API.SOCKET_HANGUP_RETRY(options.path, timeDelay, RETRY, MAX_RETRY_LIMIT));
|
|
126
127
|
RETRY++;
|
|
127
128
|
return setTimeout(() => {
|
|
128
129
|
return (0, exports.get)(req, RETRY)
|
package/dist/core/index.js
CHANGED
|
@@ -51,6 +51,7 @@ const api_1 = require("../api");
|
|
|
51
51
|
const fs_1 = require("../util/fs");
|
|
52
52
|
const index_1 = require("../util/index");
|
|
53
53
|
const logger_1 = require("../util/logger");
|
|
54
|
+
const messages_1 = require("../util/messages");
|
|
54
55
|
const promise_map_1 = require("../util/promise.map");
|
|
55
56
|
const inet_1 = require("./inet");
|
|
56
57
|
const q_1 = require("./q");
|
|
@@ -77,14 +78,14 @@ const init = (contentStore, assetStore) => {
|
|
|
77
78
|
config = (0, __1.getConfig)();
|
|
78
79
|
Q = new q_1.Q(contentStore, assetStore, config);
|
|
79
80
|
(0, api_1.init)(config.contentstack);
|
|
80
|
-
debug(
|
|
81
|
+
debug(messages_1.MESSAGES.SYNC_CORE.START);
|
|
81
82
|
return new Promise((resolve, reject) => {
|
|
82
83
|
try {
|
|
83
84
|
Contentstack = config.contentstack;
|
|
84
85
|
const checkPointConfig = config.checkpoint;
|
|
85
86
|
const paths = config.paths;
|
|
86
87
|
const environment = Contentstack.environment || process.env.NODE_ENV || 'development';
|
|
87
|
-
debug(
|
|
88
|
+
debug(messages_1.MESSAGES.SYNC_CORE.ENVIRONMENT(environment));
|
|
88
89
|
const request = {
|
|
89
90
|
qs: {
|
|
90
91
|
environment,
|
|
@@ -134,22 +135,22 @@ const loadCheckpoint = (checkPointConfig, paths) => {
|
|
|
134
135
|
}
|
|
135
136
|
// Set sync token if checkpoint is found
|
|
136
137
|
if (checkpoint) {
|
|
137
|
-
debug(
|
|
138
|
+
debug(messages_1.MESSAGES.SYNC_CORE.TOKEN_FOUND, checkpoint);
|
|
138
139
|
Contentstack.sync_token = checkpoint.token;
|
|
139
|
-
debug(
|
|
140
|
+
debug(messages_1.MESSAGES.SYNC_CORE.TOKEN_USING, Contentstack.sync_token);
|
|
140
141
|
}
|
|
141
142
|
};
|
|
142
143
|
function readHiddenFile(filePath) {
|
|
143
144
|
try {
|
|
144
145
|
if (!fs.existsSync(filePath)) {
|
|
145
|
-
logger_1.logger.error(
|
|
146
|
+
logger_1.logger.error(messages_1.MESSAGES.SYNC_CORE.FILE_NOT_FOUND(filePath));
|
|
146
147
|
return;
|
|
147
148
|
}
|
|
148
149
|
const data = fs.readFileSync(filePath, "utf8");
|
|
149
150
|
return JSON.parse(data);
|
|
150
151
|
}
|
|
151
152
|
catch (err) {
|
|
152
|
-
logger_1.logger.error(
|
|
153
|
+
logger_1.logger.error(messages_1.MESSAGES.SYNC_CORE.FILE_READ_ERROR(err));
|
|
153
154
|
return undefined;
|
|
154
155
|
}
|
|
155
156
|
}
|
|
@@ -170,8 +171,8 @@ exports.pop = pop;
|
|
|
170
171
|
*/
|
|
171
172
|
const poke = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
172
173
|
try {
|
|
173
|
-
debug(
|
|
174
|
-
logger_1.logger.info(
|
|
174
|
+
debug(messages_1.MESSAGES.SYNC_CORE.POKE_INVOKED);
|
|
175
|
+
logger_1.logger.info(messages_1.MESSAGES.SYNC_CORE.POKE_NOTIFICATION);
|
|
175
176
|
if (!flag.lockdown) {
|
|
176
177
|
flag.WQ = true;
|
|
177
178
|
return yield check();
|
|
@@ -179,7 +180,7 @@ const poke = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
179
180
|
return null;
|
|
180
181
|
}
|
|
181
182
|
catch (error) {
|
|
182
|
-
debug(
|
|
183
|
+
debug(messages_1.MESSAGES.SYNC_CORE.POKE_ERROR, error);
|
|
183
184
|
throw error;
|
|
184
185
|
}
|
|
185
186
|
});
|
|
@@ -190,12 +191,12 @@ exports.poke = poke;
|
|
|
190
191
|
*/
|
|
191
192
|
const check = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
192
193
|
try {
|
|
193
|
-
debug(
|
|
194
|
+
debug(messages_1.MESSAGES.SYNC_CORE.CHECK_CALLED(flag.SQ, flag.WQ));
|
|
194
195
|
if (!flag.SQ && flag.WQ) {
|
|
195
196
|
flag.WQ = false;
|
|
196
197
|
flag.SQ = true;
|
|
197
198
|
yield sync();
|
|
198
|
-
debug(
|
|
199
|
+
debug(messages_1.MESSAGES.SYNC_CORE.CHECK_COMPLETE(config.syncManager.cooloff));
|
|
199
200
|
setTimeout(() => {
|
|
200
201
|
flag.SQ = false;
|
|
201
202
|
emitter.emit('check');
|
|
@@ -204,11 +205,11 @@ const check = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
204
205
|
}
|
|
205
206
|
catch (error) {
|
|
206
207
|
logger_1.logger.error(error);
|
|
207
|
-
debug(
|
|
208
|
+
debug(messages_1.MESSAGES.SYNC_CORE.CHECK_ERROR, error);
|
|
208
209
|
check().then(() => {
|
|
209
|
-
debug(
|
|
210
|
+
debug(messages_1.MESSAGES.SYNC_CORE.CHECK_RECOVERED);
|
|
210
211
|
}).catch((error) => {
|
|
211
|
-
debug(
|
|
212
|
+
debug(messages_1.MESSAGES.SYNC_CORE.CHECK_FAILED, error);
|
|
212
213
|
});
|
|
213
214
|
throw error;
|
|
214
215
|
}
|
|
@@ -218,9 +219,9 @@ const check = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
218
219
|
*/
|
|
219
220
|
const sync = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
220
221
|
try {
|
|
221
|
-
debug(
|
|
222
|
+
debug(messages_1.MESSAGES.SYNC_CORE.SYNC_STARTED);
|
|
222
223
|
const tokenObject = yield (0, token_management_1.getToken)();
|
|
223
|
-
debug(
|
|
224
|
+
debug(messages_1.MESSAGES.SYNC_CORE.SYNC_TOKEN_OBJECT, tokenObject);
|
|
224
225
|
const token = tokenObject;
|
|
225
226
|
const request = {
|
|
226
227
|
qs: {
|
|
@@ -232,7 +233,7 @@ const sync = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
232
233
|
return yield fire(request);
|
|
233
234
|
}
|
|
234
235
|
catch (error) {
|
|
235
|
-
debug(
|
|
236
|
+
debug(messages_1.MESSAGES.SYNC_CORE.SYNC_ERROR, error);
|
|
236
237
|
throw error;
|
|
237
238
|
}
|
|
238
239
|
});
|
|
@@ -240,7 +241,7 @@ const sync = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
240
241
|
* @description Used to lockdown the 'sync' process in case of exceptions
|
|
241
242
|
*/
|
|
242
243
|
const lock = () => {
|
|
243
|
-
debug(
|
|
244
|
+
debug(messages_1.MESSAGES.SYNC_CORE.SYNC_LOCKED);
|
|
244
245
|
flag.lockdown = true;
|
|
245
246
|
};
|
|
246
247
|
exports.lock = lock;
|
|
@@ -248,7 +249,7 @@ exports.lock = lock;
|
|
|
248
249
|
* @description Used to unlock the 'sync' process in case of errors/exceptions
|
|
249
250
|
*/
|
|
250
251
|
const unlock = (refire) => {
|
|
251
|
-
debug(
|
|
252
|
+
debug(messages_1.MESSAGES.SYNC_CORE.SYNC_UNLOCKED, refire);
|
|
252
253
|
flag.lockdown = false;
|
|
253
254
|
if (typeof refire === 'boolean' && refire) {
|
|
254
255
|
flag.WQ = true;
|
|
@@ -266,7 +267,7 @@ exports.unlock = unlock;
|
|
|
266
267
|
* @param {Object} req - Contentstack sync API request object
|
|
267
268
|
*/
|
|
268
269
|
const fire = (req) => {
|
|
269
|
-
debug(
|
|
270
|
+
debug(messages_1.MESSAGES.SYNC_CORE.FIRE_CALLED(req));
|
|
270
271
|
flag.SQ = true;
|
|
271
272
|
return new Promise((resolve, reject) => {
|
|
272
273
|
return (0, api_1.get)(req).then((response) => {
|
|
@@ -275,7 +276,7 @@ const fire = (req) => {
|
|
|
275
276
|
delete req.qs.sync_token;
|
|
276
277
|
delete req.path;
|
|
277
278
|
const syncResponse = response;
|
|
278
|
-
debug(
|
|
279
|
+
debug(messages_1.MESSAGES.SYNC_CORE.FIRE_COMPLETE(syncResponse.items.length));
|
|
279
280
|
if (syncResponse.items.length) {
|
|
280
281
|
return (0, index_1.filterItems)(syncResponse, config).then(() => {
|
|
281
282
|
if (syncResponse.items.length === 0) {
|
|
@@ -310,7 +311,7 @@ const fire = (req) => {
|
|
|
310
311
|
});
|
|
311
312
|
return (0, promise_map_1.map)(contentTypeUids, (uid) => {
|
|
312
313
|
return new Promise((mapResolve, mapReject) => {
|
|
313
|
-
debug(
|
|
314
|
+
debug(messages_1.MESSAGES.SYNC_CORE.API_CALL_CT(uid));
|
|
314
315
|
return (0, api_1.get)({
|
|
315
316
|
path: `${Contentstack.apis.content_types}${uid}`,
|
|
316
317
|
qs: {
|
|
@@ -331,7 +332,7 @@ const fire = (req) => {
|
|
|
331
332
|
err.code = 'ICTC';
|
|
332
333
|
return mapReject(err);
|
|
333
334
|
}).catch((error) => {
|
|
334
|
-
debug(
|
|
335
|
+
debug(messages_1.MESSAGES.SYNC_CORE.ERROR_MAP, error);
|
|
335
336
|
if ((0, inet_1.netConnectivityIssues)(error)) {
|
|
336
337
|
flag.SQ = false;
|
|
337
338
|
}
|
|
@@ -347,11 +348,11 @@ const fire = (req) => {
|
|
|
347
348
|
flag.SQ = false;
|
|
348
349
|
}
|
|
349
350
|
// Errorred while fetching content type schema
|
|
350
|
-
debug(
|
|
351
|
+
debug(messages_1.MESSAGES.SYNC_CORE.ERROR_MAP_RESOLVE, error);
|
|
351
352
|
return reject(error);
|
|
352
353
|
});
|
|
353
354
|
}).catch((processError) => {
|
|
354
|
-
debug(
|
|
355
|
+
debug(messages_1.MESSAGES.SYNC_CORE.ERROR_FILTER_ITEMS, processError);
|
|
355
356
|
return reject(processError);
|
|
356
357
|
});
|
|
357
358
|
}
|
|
@@ -359,7 +360,7 @@ const fire = (req) => {
|
|
|
359
360
|
.then(resolve)
|
|
360
361
|
.catch(reject);
|
|
361
362
|
}).catch((error) => {
|
|
362
|
-
debug(
|
|
363
|
+
debug(messages_1.MESSAGES.SYNC_CORE.ERROR_FIRE, error);
|
|
363
364
|
if ((0, inet_1.netConnectivityIssues)(error)) {
|
|
364
365
|
flag.SQ = false;
|
|
365
366
|
}
|
|
@@ -387,7 +388,7 @@ const postProcess = (req, resp) => {
|
|
|
387
388
|
// re-fire!
|
|
388
389
|
req.qs[name] = resp[name];
|
|
389
390
|
if (flag.lockdown) {
|
|
390
|
-
logger_1.logger.log(
|
|
391
|
+
logger_1.logger.log(messages_1.MESSAGES.SYNC_CORE.CHECKPOINT_LOCKDOWN);
|
|
391
392
|
flag.requestCache = {
|
|
392
393
|
params: req,
|
|
393
394
|
reject,
|
|
@@ -399,7 +400,7 @@ const postProcess = (req, resp) => {
|
|
|
399
400
|
flag.SQ = false;
|
|
400
401
|
return resolve('');
|
|
401
402
|
}
|
|
402
|
-
debug(
|
|
403
|
+
debug(messages_1.MESSAGES.SYNC_CORE.REFIRE_CALLED(req));
|
|
403
404
|
return fire(req)
|
|
404
405
|
.then(resolve)
|
|
405
406
|
.catch(reject);
|
package/dist/core/inet.js
CHANGED
|
@@ -14,6 +14,7 @@ const dns_socket_1 = __importDefault(require("dns-socket"));
|
|
|
14
14
|
const events_1 = require("events");
|
|
15
15
|
const index_1 = require("../index");
|
|
16
16
|
const logger_1 = require("../util/logger");
|
|
17
|
+
const messages_1 = require("../util/messages");
|
|
17
18
|
const index_2 = require("./index");
|
|
18
19
|
const emitter = new events_1.EventEmitter();
|
|
19
20
|
const debug = (0, debug_1.default)('inet');
|
|
@@ -36,7 +37,7 @@ const init = () => {
|
|
|
36
37
|
port = sm.inet.port;
|
|
37
38
|
dns = sm.inet.dns;
|
|
38
39
|
currentTimeout = sm.inet.retryTimeout;
|
|
39
|
-
debug(
|
|
40
|
+
debug(messages_1.MESSAGES.INET.INITIATED(currentTimeout));
|
|
40
41
|
// start checking for net connectivity, 30 seconds after the app has started
|
|
41
42
|
setTimeout(exports.checkNetConnectivity, currentTimeout);
|
|
42
43
|
};
|
|
@@ -46,13 +47,13 @@ const checkNetConnectivity = () => {
|
|
|
46
47
|
retries: sm.inet.retries,
|
|
47
48
|
timeout: sm.inet.timeout,
|
|
48
49
|
});
|
|
49
|
-
debug(
|
|
50
|
+
debug(messages_1.MESSAGES.INET.CHECKING);
|
|
50
51
|
socket.query(query, port, dns, (err) => {
|
|
51
52
|
if (err) {
|
|
52
|
-
debug(
|
|
53
|
+
debug(messages_1.MESSAGES.INET.CHECK_FAILED(err));
|
|
53
54
|
disconnected = true;
|
|
54
55
|
return socket.destroy(() => {
|
|
55
|
-
debug(
|
|
56
|
+
debug(messages_1.MESSAGES.INET.CLEANUP_ERROR);
|
|
56
57
|
emitter.emit('disconnected', currentTimeout += sm.inet.retryIncrement);
|
|
57
58
|
});
|
|
58
59
|
}
|
|
@@ -61,7 +62,7 @@ const checkNetConnectivity = () => {
|
|
|
61
62
|
}
|
|
62
63
|
disconnected = false;
|
|
63
64
|
return socket.destroy(() => {
|
|
64
|
-
debug(
|
|
65
|
+
debug(messages_1.MESSAGES.INET.CLEANUP_SUCCESS);
|
|
65
66
|
emitter.emit('ok');
|
|
66
67
|
});
|
|
67
68
|
});
|
|
@@ -79,11 +80,11 @@ const netConnectivityIssues = (error) => {
|
|
|
79
80
|
exports.netConnectivityIssues = netConnectivityIssues;
|
|
80
81
|
emitter.on('ok', () => {
|
|
81
82
|
currentTimeout = sm.inet.retryTimeout;
|
|
82
|
-
debug(
|
|
83
|
+
debug(messages_1.MESSAGES.INET.PINGING(sm.inet.host, sm.inet.timeout));
|
|
83
84
|
setTimeout(exports.checkNetConnectivity, sm.inet.timeout);
|
|
84
85
|
});
|
|
85
86
|
emitter.on('disconnected', (timeout) => {
|
|
86
|
-
logger_1.logger.warn(
|
|
87
|
-
debug(
|
|
87
|
+
logger_1.logger.warn(messages_1.MESSAGES.INET.DISCONNECTED);
|
|
88
|
+
debug(messages_1.MESSAGES.INET.PINGING(sm.inet.host, timeout));
|
|
88
89
|
setTimeout(exports.checkNetConnectivity, timeout);
|
|
89
90
|
});
|
package/dist/core/plugins.js
CHANGED
|
@@ -12,6 +12,7 @@ exports.load = void 0;
|
|
|
12
12
|
const debug_1 = __importDefault(require("debug"));
|
|
13
13
|
const lodash_1 = require("lodash");
|
|
14
14
|
const index_1 = require("../util/index");
|
|
15
|
+
const messages_1 = require("../util/messages");
|
|
15
16
|
const validations_1 = require("../util/validations");
|
|
16
17
|
const debug = (0, debug_1.default)('plugins');
|
|
17
18
|
const pluginMethods = ['beforeSync', 'afterSync'];
|
|
@@ -21,7 +22,7 @@ const pluginMethods = ['beforeSync', 'afterSync'];
|
|
|
21
22
|
* @returns {Object} pluginInstance - An instance of plugins, with valid registered methods
|
|
22
23
|
*/
|
|
23
24
|
const load = (config) => {
|
|
24
|
-
debug(
|
|
25
|
+
debug(messages_1.MESSAGES.PLUGINS.LOAD_CALLED);
|
|
25
26
|
try {
|
|
26
27
|
const pluginInstances = {
|
|
27
28
|
external: {},
|
|
@@ -56,19 +57,19 @@ const load = (config) => {
|
|
|
56
57
|
else {
|
|
57
58
|
pluginInstances.external[pluginMethod].push(Plugin[pluginMethod]);
|
|
58
59
|
}
|
|
59
|
-
debug(
|
|
60
|
+
debug(messages_1.MESSAGES.PLUGINS.METHOD_LOADED(pluginMethod, pluginName));
|
|
60
61
|
}
|
|
61
62
|
else {
|
|
62
|
-
debug(
|
|
63
|
+
debug(messages_1.MESSAGES.PLUGINS.METHOD_NOT_FOUND(pluginMethod, pluginName));
|
|
63
64
|
}
|
|
64
65
|
});
|
|
65
66
|
});
|
|
66
|
-
debug(
|
|
67
|
+
debug(messages_1.MESSAGES.PLUGINS.LOAD_SUCCESS);
|
|
67
68
|
return pluginInstances;
|
|
68
69
|
}
|
|
69
70
|
catch (error) {
|
|
70
|
-
debug(
|
|
71
|
-
throw new Error(
|
|
71
|
+
debug(messages_1.MESSAGES.PLUGINS.LOAD_ERROR, error);
|
|
72
|
+
throw new Error(messages_1.MESSAGES.PLUGINS.LOAD_ERROR_DETAIL(error === null || error === void 0 ? void 0 : error.message));
|
|
72
73
|
}
|
|
73
74
|
};
|
|
74
75
|
exports.load = load;
|
package/dist/core/process.js
CHANGED
|
@@ -12,6 +12,7 @@ exports.configure = void 0;
|
|
|
12
12
|
*/
|
|
13
13
|
const index_1 = require("../index");
|
|
14
14
|
const logger_1 = require("../util/logger");
|
|
15
|
+
const messages_1 = require("../util/messages");
|
|
15
16
|
const index_2 = require("./index");
|
|
16
17
|
/**
|
|
17
18
|
* @description Handles process exit. Stops the current application and manages a graceful shutdown
|
|
@@ -21,7 +22,7 @@ const handleExit = (signal) => {
|
|
|
21
22
|
(0, index_2.lock)();
|
|
22
23
|
const { syncManager } = (0, index_1.getConfig)();
|
|
23
24
|
const killDuration = (process.env.KILLDURATION) ? calculateKillDuration() : syncManager.processTimeout;
|
|
24
|
-
logger_1.logger.info(
|
|
25
|
+
logger_1.logger.info(messages_1.MESSAGES.PROCESS.SHUTDOWN(signal, killDuration));
|
|
25
26
|
setTimeout(abort, killDuration);
|
|
26
27
|
};
|
|
27
28
|
/**
|
|
@@ -32,7 +33,7 @@ const handleExit = (signal) => {
|
|
|
32
33
|
* @param {Object} error - Unhandled error object
|
|
33
34
|
*/
|
|
34
35
|
const unhandledErrors = (error) => {
|
|
35
|
-
logger_1.logger.error(
|
|
36
|
+
logger_1.logger.error(messages_1.MESSAGES.PROCESS.UNHANDLED_ERROR);
|
|
36
37
|
logger_1.logger.error(error);
|
|
37
38
|
(0, index_2.lock)();
|
|
38
39
|
setTimeout(() => {
|
package/dist/core/q.js
CHANGED
|
@@ -24,6 +24,7 @@ const lodash_1 = require("lodash");
|
|
|
24
24
|
const _1 = require(".");
|
|
25
25
|
const index_1 = require("../util/index");
|
|
26
26
|
const logger_1 = require("../util/logger");
|
|
27
|
+
const messages_1 = require("../util/messages");
|
|
27
28
|
const series_1 = require("../util/series");
|
|
28
29
|
const unprocessible_1 = require("../util/unprocessible");
|
|
29
30
|
const plugins_1 = require("./plugins");
|
|
@@ -59,7 +60,7 @@ class Q extends events_1.EventEmitter {
|
|
|
59
60
|
this.on('push', this.push);
|
|
60
61
|
this.on('unshift', this.unshift);
|
|
61
62
|
instance = this;
|
|
62
|
-
debug(
|
|
63
|
+
debug(messages_1.MESSAGES.QUEUE.CONSTRUCTOR);
|
|
63
64
|
}
|
|
64
65
|
return instance;
|
|
65
66
|
}
|
|
@@ -69,7 +70,7 @@ class Q extends events_1.EventEmitter {
|
|
|
69
70
|
this.iLock = true;
|
|
70
71
|
(0, _1.lock)();
|
|
71
72
|
}
|
|
72
|
-
debug(
|
|
73
|
+
debug(messages_1.MESSAGES.QUEUE.CONTENT_TYPE_RECEIVED(data._content_type_uid, data._type));
|
|
73
74
|
this.emit('next');
|
|
74
75
|
}
|
|
75
76
|
/**
|
|
@@ -82,7 +83,7 @@ class Q extends events_1.EventEmitter {
|
|
|
82
83
|
this.iLock = true;
|
|
83
84
|
(0, _1.lock)();
|
|
84
85
|
}
|
|
85
|
-
debug(
|
|
86
|
+
debug(messages_1.MESSAGES.QUEUE.CONTENT_TYPE_RECEIVED(data._content_type_uid, data._type));
|
|
86
87
|
this.emit('next');
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
@@ -95,7 +96,7 @@ class Q extends events_1.EventEmitter {
|
|
|
95
96
|
try {
|
|
96
97
|
notify('error', obj);
|
|
97
98
|
logger_1.logger.error(obj);
|
|
98
|
-
debug(
|
|
99
|
+
debug(messages_1.MESSAGES.QUEUE.ERROR_HANDLER_CALLED(obj));
|
|
99
100
|
if (typeof obj.checkpoint !== 'undefined') {
|
|
100
101
|
yield (0, token_management_1.saveToken)(obj.checkpoint.name, obj.checkpoint.token);
|
|
101
102
|
}
|
|
@@ -105,7 +106,7 @@ class Q extends events_1.EventEmitter {
|
|
|
105
106
|
}
|
|
106
107
|
catch (error) {
|
|
107
108
|
// probably, the context could change
|
|
108
|
-
logger_1.logger.error(
|
|
109
|
+
logger_1.logger.error(messages_1.MESSAGES.QUEUE.ERROR_IN_HANDLER);
|
|
109
110
|
logger_1.logger.error(error);
|
|
110
111
|
that.inProgress = false;
|
|
111
112
|
that.emit('next');
|
|
@@ -125,7 +126,7 @@ class Q extends events_1.EventEmitter {
|
|
|
125
126
|
(0, _1.unlock)(true);
|
|
126
127
|
this.iLock = false;
|
|
127
128
|
}
|
|
128
|
-
debug(
|
|
129
|
+
debug(messages_1.MESSAGES.QUEUE.NEXT_CALLED(this.inProgress, this.q.length));
|
|
129
130
|
if (!this.inProgress && this.q.length) {
|
|
130
131
|
this.inProgress = true;
|
|
131
132
|
const item = this.q.shift();
|
|
@@ -170,7 +171,7 @@ class Q extends events_1.EventEmitter {
|
|
|
170
171
|
checkpoint = data._checkpoint;
|
|
171
172
|
delete data._checkpoint;
|
|
172
173
|
}
|
|
173
|
-
debug(
|
|
174
|
+
debug(messages_1.MESSAGES.QUEUE.EXECUTING(data));
|
|
174
175
|
const beforeSyncInternalPlugins = [];
|
|
175
176
|
// re-initializing everytime with const.. avoids memory leaks
|
|
176
177
|
const beforeSyncPlugins = [];
|
|
@@ -208,15 +209,15 @@ class Q extends events_1.EventEmitter {
|
|
|
208
209
|
});
|
|
209
210
|
yield Promise.all(beforeSyncPlugins);
|
|
210
211
|
}
|
|
211
|
-
debug(
|
|
212
|
+
debug(messages_1.MESSAGES.QUEUE.BEFORE_PLUGINS);
|
|
212
213
|
yield this.contentStore[action](data);
|
|
213
|
-
debug(
|
|
214
|
+
debug(messages_1.MESSAGES.QUEUE.ACTION_COMPLETE(action));
|
|
214
215
|
if (typeof schema !== 'undefined') {
|
|
215
216
|
if (branch)
|
|
216
217
|
schema.branch = branch;
|
|
217
218
|
yield this.contentStore.updateContentType(schema);
|
|
218
219
|
}
|
|
219
|
-
debug(
|
|
220
|
+
debug(messages_1.MESSAGES.QUEUE.CONNECTOR_CALLED);
|
|
220
221
|
if (this.syncManager.serializePlugins) {
|
|
221
222
|
this.pluginInstances.external.afterSync.forEach((method) => {
|
|
222
223
|
afterSyncPlugins.push(() => method(action, transformedData, transformedSchema));
|
|
@@ -232,7 +233,7 @@ class Q extends events_1.EventEmitter {
|
|
|
232
233
|
if (typeof checkpoint !== 'undefined') {
|
|
233
234
|
yield (0, token_management_1.saveToken)(checkpoint.name, checkpoint.token);
|
|
234
235
|
}
|
|
235
|
-
debug(
|
|
236
|
+
debug(messages_1.MESSAGES.QUEUE.AFTER_PLUGINS);
|
|
236
237
|
logger_1.logger.log(`${type}: { content_type: '${contentType}', ${(locale) ? `locale: '${locale}',` : ''} uid: '${uid}'} was completed successfully!`);
|
|
237
238
|
this.inProgress = false;
|
|
238
239
|
this.emit('next', data);
|
|
@@ -22,6 +22,7 @@ const debug_1 = __importDefault(require("debug"));
|
|
|
22
22
|
const index_1 = require("../index");
|
|
23
23
|
const fs_1 = require("../util/fs");
|
|
24
24
|
const index_2 = require("../util/index");
|
|
25
|
+
const messages_1 = require("../util/messages");
|
|
25
26
|
const debug = (0, debug_1.default)('token-management');
|
|
26
27
|
let counter = 0;
|
|
27
28
|
/**
|
|
@@ -36,12 +37,12 @@ const getToken = () => {
|
|
|
36
37
|
const token = config.paths.token;
|
|
37
38
|
let data = {};
|
|
38
39
|
if ((0, fs_1.existsSync)(checkpoint)) {
|
|
39
|
-
debug(
|
|
40
|
+
debug(messages_1.MESSAGES.TOKEN.CHECKPOINT_READ(checkpoint));
|
|
40
41
|
const contents = yield (0, fs_1.readFile)(checkpoint);
|
|
41
42
|
data = JSON.parse(contents);
|
|
42
43
|
}
|
|
43
44
|
else if ((0, fs_1.existsSync)(token)) {
|
|
44
|
-
debug(
|
|
45
|
+
debug(messages_1.MESSAGES.TOKEN.TOKEN_READ(token));
|
|
45
46
|
const contents = yield (0, fs_1.readFile)(token);
|
|
46
47
|
data = JSON.parse(contents);
|
|
47
48
|
}
|
|
@@ -60,7 +61,7 @@ exports.getToken = getToken;
|
|
|
60
61
|
* @param {String} type - Token type
|
|
61
62
|
*/
|
|
62
63
|
const saveToken = (name, token) => {
|
|
63
|
-
debug(
|
|
64
|
+
debug(messages_1.MESSAGES.TOKEN.SAVE_TOKEN(name));
|
|
64
65
|
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
66
|
try {
|
|
66
67
|
const config = (0, index_1.getConfig)();
|
|
@@ -88,7 +89,7 @@ const saveToken = (name, token) => {
|
|
|
88
89
|
counter++;
|
|
89
90
|
return `${config.paths.ledger}-${counter}`;
|
|
90
91
|
});
|
|
91
|
-
debug(
|
|
92
|
+
debug(messages_1.MESSAGES.TOKEN.LEDGER_CHECK(file, (0, fs_1.existsSync)(file)));
|
|
92
93
|
if (!(0, fs_1.existsSync)(file)) {
|
|
93
94
|
yield (0, fs_1.writeFile)(file, JSON.stringify([obj]));
|
|
94
95
|
}
|
|
@@ -113,7 +114,7 @@ exports.saveToken = saveToken;
|
|
|
113
114
|
* @param {String} type - Token type
|
|
114
115
|
*/
|
|
115
116
|
const saveCheckpoint = (name, token) => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
|
-
debug(
|
|
117
|
+
debug(messages_1.MESSAGES.TOKEN.SAVE_CHECKPOINT(name));
|
|
117
118
|
const config = (0, index_1.getConfig)();
|
|
118
119
|
const path = config.paths.checkpoint;
|
|
119
120
|
const data = {
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "notifications", { enumerable: true, get: functio
|
|
|
29
29
|
const build_paths_1 = require("./util/build-paths");
|
|
30
30
|
const index_2 = require("./util/index");
|
|
31
31
|
const logger_1 = require("./util/logger");
|
|
32
|
+
const messages_1 = require("./util/messages");
|
|
32
33
|
const validations_1 = require("./util/validations");
|
|
33
34
|
const debug = (0, debug_1.default)('sm:index');
|
|
34
35
|
let assetStoreInstance;
|
|
@@ -146,23 +147,25 @@ const start = (config = {}) => {
|
|
|
146
147
|
(0, logger_1.setLogger)();
|
|
147
148
|
(0, process_1.configure)();
|
|
148
149
|
return assetStore.start(appConfig).then((assetInstance) => {
|
|
149
|
-
debug(
|
|
150
|
+
debug(messages_1.MESSAGES.INDEX.ASSET_STORE_INIT);
|
|
150
151
|
(0, validations_1.validateAssetStoreInstance)(assetInstance);
|
|
151
152
|
assetStoreInstance = assetInstance;
|
|
152
153
|
return contentStore.start(assetInstance, appConfig);
|
|
153
154
|
}).then((contentStoreInstance) => {
|
|
154
|
-
debug(
|
|
155
|
+
debug(messages_1.MESSAGES.INDEX.CONTENT_STORE_INIT);
|
|
155
156
|
(0, validations_1.validateContentStoreInstance)(contentStoreInstance);
|
|
156
157
|
appConfig = (0, index_2.formatSyncFilters)(appConfig);
|
|
157
158
|
return (0, index_1.init)(contentStoreInstance, assetStoreInstance);
|
|
158
159
|
}).then(() => {
|
|
159
|
-
debug(
|
|
160
|
+
debug(messages_1.MESSAGES.INDEX.SYNC_MANAGER_INIT);
|
|
160
161
|
listener.register(index_1.poke);
|
|
161
162
|
// start checking for inet 10 secs after the app has started
|
|
162
163
|
(0, inet_1.init)();
|
|
163
164
|
return listener.start(appConfig);
|
|
164
|
-
}).then(() => {
|
|
165
|
-
|
|
165
|
+
}).then((webhookServer) => {
|
|
166
|
+
// Set up webhook listener monitoring and fallback mechanism
|
|
167
|
+
setupWebhookMonitoring(webhookServer);
|
|
168
|
+
logger_1.logger.info(messages_1.MESSAGES.INDEX.SYNC_UTILITY_STARTED);
|
|
166
169
|
return resolve('');
|
|
167
170
|
}).catch(reject);
|
|
168
171
|
}
|
|
@@ -180,7 +183,7 @@ exports.start = start;
|
|
|
180
183
|
*/
|
|
181
184
|
const debugNotifications = (action) => {
|
|
182
185
|
return (item) => {
|
|
183
|
-
debug(
|
|
186
|
+
debug(messages_1.MESSAGES.INDEX.NOTIFICATION(action, item));
|
|
184
187
|
};
|
|
185
188
|
};
|
|
186
189
|
exports.debugNotifications = debugNotifications;
|
|
@@ -189,3 +192,63 @@ q_1.notifications
|
|
|
189
192
|
.on('unpublish', (0, exports.debugNotifications)('unpublish'))
|
|
190
193
|
.on('delete', (0, exports.debugNotifications)('delete'))
|
|
191
194
|
.on('error', (0, exports.debugNotifications)('error'));
|
|
195
|
+
/**
|
|
196
|
+
* Set up webhook listener monitoring and fallback polling mechanism
|
|
197
|
+
* @param {object} webhookServer The webhook server instance
|
|
198
|
+
*/
|
|
199
|
+
function setupWebhookMonitoring(webhookServer) {
|
|
200
|
+
const FALLBACK_POLL_INTERVAL = 60000; // 1 minute fallback polling
|
|
201
|
+
let fallbackTimer = null;
|
|
202
|
+
let webhookHealthy = true;
|
|
203
|
+
debug('Webhook monitoring initialized. Server:', !!webhookServer, 'Healthy:', webhookHealthy);
|
|
204
|
+
// Start fallback polling when webhook is unhealthy
|
|
205
|
+
const startFallbackPolling = () => {
|
|
206
|
+
if (fallbackTimer)
|
|
207
|
+
return; // Already running
|
|
208
|
+
logger_1.logger.info(`Starting fallback polling every ${FALLBACK_POLL_INTERVAL}ms`);
|
|
209
|
+
fallbackTimer = setInterval(() => {
|
|
210
|
+
debug('Fallback polling: triggering sync check');
|
|
211
|
+
try {
|
|
212
|
+
(0, index_1.poke)().catch((error) => {
|
|
213
|
+
debug('Fallback polling error:', error);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
debug('Fallback polling exception:', error);
|
|
218
|
+
}
|
|
219
|
+
}, FALLBACK_POLL_INTERVAL);
|
|
220
|
+
};
|
|
221
|
+
// Stop fallback polling when webhook is healthy
|
|
222
|
+
const stopFallbackPolling = () => {
|
|
223
|
+
if (fallbackTimer) {
|
|
224
|
+
clearInterval(fallbackTimer);
|
|
225
|
+
fallbackTimer = null;
|
|
226
|
+
logger_1.logger.info('Fallback polling stopped');
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
// Webhook activity is tracked via events, no need to wrap poke function
|
|
230
|
+
// Handle process cleanup
|
|
231
|
+
const cleanup = () => {
|
|
232
|
+
if (fallbackTimer) {
|
|
233
|
+
clearInterval(fallbackTimer);
|
|
234
|
+
fallbackTimer = null;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
process.on('SIGINT', cleanup);
|
|
238
|
+
process.on('SIGTERM', cleanup);
|
|
239
|
+
process.on('exit', cleanup);
|
|
240
|
+
// Handle webhook server events if available
|
|
241
|
+
if (listener.getEventEmitter) {
|
|
242
|
+
const webhookEmitter = listener.getEventEmitter();
|
|
243
|
+
webhookEmitter.on('server-error', (error) => {
|
|
244
|
+
logger_1.logger.warn('Webhook server error detected:', error.message);
|
|
245
|
+
webhookHealthy = false;
|
|
246
|
+
startFallbackPolling();
|
|
247
|
+
});
|
|
248
|
+
webhookEmitter.on('reconnect-success', () => {
|
|
249
|
+
logger_1.logger.info('Webhook server reconnected successfully');
|
|
250
|
+
webhookHealthy = true;
|
|
251
|
+
stopFallbackPolling();
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
package/dist/util/fs.js
CHANGED
|
@@ -16,6 +16,7 @@ Object.defineProperty(exports, "existsSync", { enumerable: true, get: function (
|
|
|
16
16
|
const mkdirp_1 = require("mkdirp");
|
|
17
17
|
const path_1 = require("path");
|
|
18
18
|
const write_file_atomic_1 = __importDefault(require("write-file-atomic"));
|
|
19
|
+
const messages_1 = require("./messages");
|
|
19
20
|
const debug = Debug('sm:util-fs');
|
|
20
21
|
/**
|
|
21
22
|
* @description A wrapper around nodejs fs module's 'writeFile()'
|
|
@@ -24,7 +25,7 @@ const debug = Debug('sm:util-fs');
|
|
|
24
25
|
* @returns {Promise} Returns a promise
|
|
25
26
|
*/
|
|
26
27
|
const writeFile = (filePath, data) => {
|
|
27
|
-
debug(
|
|
28
|
+
debug(messages_1.MESSAGES.FS.WRITE_FILE(filePath));
|
|
28
29
|
return new Promise((resolve, reject) => {
|
|
29
30
|
try {
|
|
30
31
|
const fileDirectory = (0, path_1.dirname)(filePath);
|
|
@@ -50,7 +51,7 @@ exports.writeFile = writeFile;
|
|
|
50
51
|
* @returns {Promise} Returns a promise
|
|
51
52
|
*/
|
|
52
53
|
const readFile = (filePath) => {
|
|
53
|
-
debug(
|
|
54
|
+
debug(messages_1.MESSAGES.FS.READ_FILE(filePath));
|
|
54
55
|
return new Promise((resolve, reject) => {
|
|
55
56
|
try {
|
|
56
57
|
return (0, fs_1.stat)(filePath, (error, stats) => {
|
|
@@ -65,7 +66,7 @@ const readFile = (filePath) => {
|
|
|
65
66
|
return resolve(data);
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
|
-
const err = new Error(
|
|
69
|
+
const err = new Error(messages_1.MESSAGES.FS.INVALID_READ(filePath));
|
|
69
70
|
err.code = 'IOORF';
|
|
70
71
|
return reject(err);
|
|
71
72
|
});
|
|
@@ -82,11 +83,11 @@ exports.readFile = readFile;
|
|
|
82
83
|
* @returns {String} Returns the data that's been read
|
|
83
84
|
*/
|
|
84
85
|
const readFileSync = (filePath) => {
|
|
85
|
-
debug(
|
|
86
|
+
debug(messages_1.MESSAGES.FS.READ_FILE_SYNC(filePath));
|
|
86
87
|
if ((0, fs_1.existsSync)(filePath)) {
|
|
87
88
|
return (0, fs_1.readFileSync)(filePath, { encoding: 'utf-8' });
|
|
88
89
|
}
|
|
89
|
-
const err = new Error(
|
|
90
|
+
const err = new Error(messages_1.MESSAGES.FS.INVALID_READ(filePath));
|
|
90
91
|
err.code = 'IOORFS';
|
|
91
92
|
throw err;
|
|
92
93
|
};
|
|
@@ -97,7 +98,7 @@ exports.readFileSync = readFileSync;
|
|
|
97
98
|
* @returns {String} Returns a promise
|
|
98
99
|
*/
|
|
99
100
|
const mkdir = (path) => {
|
|
100
|
-
debug(
|
|
101
|
+
debug(messages_1.MESSAGES.FS.MKDIR(path));
|
|
101
102
|
return (0, mkdirp_1.mkdirp)(path)
|
|
102
103
|
.then(() => '')
|
|
103
104
|
.catch(error => Promise.reject(error));
|
package/dist/util/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.getSchema = exports.filterUnwantedKeys = exports.normalizePluginPath = exports.getOrSetRTEMarkdownAssets = exports.getFile = exports.markCheckpoint = exports.formatItems = exports.groupItems = exports.formatSyncFilters = exports.filterItems = void 0;
|
|
20
|
+
exports.getSchema = exports.filterUnwantedKeys = exports.normalizePluginPath = exports.getOrSetRTEMarkdownAssets = exports.getFile = exports.markCheckpoint = exports.formatItems = exports.groupItems = exports.formatSyncFilters = exports.filterItems = exports.MESSAGES = void 0;
|
|
21
21
|
const debug_1 = __importDefault(require("debug"));
|
|
22
22
|
const lodash_1 = require("lodash");
|
|
23
23
|
const marked_1 = __importDefault(require("marked"));
|
|
@@ -25,10 +25,14 @@ const path_1 = require("path");
|
|
|
25
25
|
const index_1 = require("../index");
|
|
26
26
|
const fs_1 = require("./fs");
|
|
27
27
|
const logger_1 = require("./logger");
|
|
28
|
+
const messages_1 = require("./messages");
|
|
28
29
|
const unprocessible_1 = require("./unprocessible");
|
|
29
30
|
const validations_1 = require("./validations");
|
|
30
31
|
const helper_1 = require("./../plugins/helper");
|
|
31
32
|
const debug = (0, debug_1.default)('util:index');
|
|
33
|
+
// Re-export messages for convenience
|
|
34
|
+
var messages_2 = require("./messages");
|
|
35
|
+
Object.defineProperty(exports, "MESSAGES", { enumerable: true, get: function () { return messages_2.MESSAGES; } });
|
|
32
36
|
const formattedAssetType = '_assets';
|
|
33
37
|
const formattedContentType = '_content_types';
|
|
34
38
|
const assetType = 'sys_assets';
|
|
@@ -176,8 +180,8 @@ const formatItems = (items, config) => {
|
|
|
176
180
|
items[i]._content_type_uid = formattedContentType;
|
|
177
181
|
break;
|
|
178
182
|
default:
|
|
179
|
-
logger_1.logger.error(
|
|
180
|
-
logger_1.logger.error(
|
|
183
|
+
logger_1.logger.error(messages_1.MESSAGES.UTIL.ITEM_TYPE_MISMATCH);
|
|
184
|
+
logger_1.logger.error(messages_1.MESSAGES.UTIL.ITEM_SERIALIZED(items[i]));
|
|
181
185
|
// remove the element from items[i]s
|
|
182
186
|
items[i].splice(i, 1);
|
|
183
187
|
i--;
|
|
@@ -197,7 +201,7 @@ const markCheckpoint = (groupedItems, syncResponse) => {
|
|
|
197
201
|
const tokenValue = syncResponse[tokenName];
|
|
198
202
|
const contentTypeUids = Object.keys(groupedItems);
|
|
199
203
|
if (contentTypeUids.length === 1 && contentTypeUids[0] === '_assets') {
|
|
200
|
-
debug(
|
|
204
|
+
debug(messages_1.MESSAGES.UTIL.ONLY_ASSETS(contentTypeUids[0]));
|
|
201
205
|
const items = groupedItems[contentTypeUids[0]];
|
|
202
206
|
// find the last item, add checkpoint to it
|
|
203
207
|
items[items.length - 1]._checkpoint = {
|
|
@@ -206,7 +210,7 @@ const markCheckpoint = (groupedItems, syncResponse) => {
|
|
|
206
210
|
};
|
|
207
211
|
}
|
|
208
212
|
else if (contentTypeUids.length === 1 && contentTypeUids[0] === '_content_types') {
|
|
209
|
-
debug(
|
|
213
|
+
debug(messages_1.MESSAGES.UTIL.ONLY_CT_EVENTS(contentTypeUids[0]));
|
|
210
214
|
const items = groupedItems[contentTypeUids[0]];
|
|
211
215
|
// find the last item, add checkpoint to it
|
|
212
216
|
items[items.length - 1]._checkpoint = {
|
|
@@ -215,7 +219,7 @@ const markCheckpoint = (groupedItems, syncResponse) => {
|
|
|
215
219
|
};
|
|
216
220
|
}
|
|
217
221
|
else if (contentTypeUids.length === 2 && (contentTypeUids.indexOf('_assets') !== -1 && contentTypeUids.indexOf('_content_types'))) {
|
|
218
|
-
debug(
|
|
222
|
+
debug(messages_1.MESSAGES.UTIL.ASSETS_AND_CT(contentTypeUids[1]));
|
|
219
223
|
const items = groupedItems[contentTypeUids[1]];
|
|
220
224
|
// find the last item, add checkpoint to it
|
|
221
225
|
items[items.length - 1]._checkpoint = {
|
|
@@ -225,7 +229,7 @@ const markCheckpoint = (groupedItems, syncResponse) => {
|
|
|
225
229
|
}
|
|
226
230
|
else {
|
|
227
231
|
const lastContentTypeUid = contentTypeUids[contentTypeUids.length - 1];
|
|
228
|
-
debug(
|
|
232
|
+
debug(messages_1.MESSAGES.UTIL.MIXED_CT(lastContentTypeUid));
|
|
229
233
|
const entries = groupedItems[lastContentTypeUid];
|
|
230
234
|
entries[entries.length - 1]._checkpoint = {
|
|
231
235
|
name: tokenName,
|
|
@@ -257,7 +261,7 @@ const getFile = (file, rotate) => {
|
|
|
257
261
|
return resolve(file);
|
|
258
262
|
}
|
|
259
263
|
else {
|
|
260
|
-
return reject(new Error(
|
|
264
|
+
return reject(new Error(messages_1.MESSAGES.UTIL.FILE_NOT_TYPE(file)));
|
|
261
265
|
}
|
|
262
266
|
});
|
|
263
267
|
}
|
|
@@ -395,13 +399,13 @@ const normalizePluginPath = (config, plugin, isInternal) => {
|
|
|
395
399
|
if (plugin.path && typeof plugin.path === 'string' && plugin.path.length > 0) {
|
|
396
400
|
if ((0, path_1.isAbsolute)(plugin.path)) {
|
|
397
401
|
if (!(0, fs_1.existsSync)(plugin.path)) {
|
|
398
|
-
throw new Error(
|
|
402
|
+
throw new Error(messages_1.MESSAGES.UTIL.PLUGIN_PATH_NOT_EXIST(plugin.path));
|
|
399
403
|
}
|
|
400
404
|
return plugin.path;
|
|
401
405
|
}
|
|
402
406
|
pluginPath = (0, path_1.resolve)((0, path_1.join)((0, helper_1.sanitizePath)(config.paths.baseDir), (0, helper_1.sanitizePath)(plugin.name), 'index.js'));
|
|
403
407
|
if (!(0, fs_1.existsSync)(pluginPath)) {
|
|
404
|
-
throw new Error(
|
|
408
|
+
throw new Error(messages_1.MESSAGES.UTIL.PLUGIN_PATH_NOT_EXIST(pluginPath));
|
|
405
409
|
}
|
|
406
410
|
return pluginPath;
|
|
407
411
|
}
|
|
@@ -413,7 +417,7 @@ const normalizePluginPath = (config, plugin, isInternal) => {
|
|
|
413
417
|
}
|
|
414
418
|
pluginPath = (0, path_1.resolve)((0, path_1.join)((0, helper_1.sanitizePath)(config.paths.plugin), (0, helper_1.sanitizePath)(plugin.name), 'index.js'));
|
|
415
419
|
if (!(0, fs_1.existsSync)(pluginPath)) {
|
|
416
|
-
throw new Error(
|
|
420
|
+
throw new Error(messages_1.MESSAGES.UTIL.UNABLE_TO_FIND_PLUGIN(plugin));
|
|
417
421
|
}
|
|
418
422
|
return pluginPath;
|
|
419
423
|
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Contentstack DataSync Manager
|
|
4
|
+
* Centralized Messages and Logging Constants
|
|
5
|
+
* Copyright (c) 2025 Contentstack LLC
|
|
6
|
+
* MIT Licensed
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ERROR_CODES = exports.LOG_LEVELS = exports.MESSAGES = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* @description Centralized messages for logging and error handling
|
|
12
|
+
* This file contains all user-facing messages, debug logs, and error messages
|
|
13
|
+
* for consistency and easier maintenance.
|
|
14
|
+
*/
|
|
15
|
+
exports.MESSAGES = {
|
|
16
|
+
// Network connectivity messages (inet.ts)
|
|
17
|
+
INET: {
|
|
18
|
+
INITIATED: (timeout) => `inet initiated. Waiting ${timeout} ms before checking connectivity.`,
|
|
19
|
+
CHECKING: 'Checking network connectivity...',
|
|
20
|
+
CHECK_FAILED: (err) => `Network connectivity check failed: ${err}`,
|
|
21
|
+
CLEANUP_SUCCESS: 'Network check successful. Cleaning up connection.',
|
|
22
|
+
CLEANUP_ERROR: 'Network check failed. Cleaning up connection.',
|
|
23
|
+
PINGING: (host, timeout) => `Pinging ${host} in ${timeout} ms`,
|
|
24
|
+
DISCONNECTED: 'The network connection was lost.',
|
|
25
|
+
},
|
|
26
|
+
// Process management messages (process.ts)
|
|
27
|
+
PROCESS: {
|
|
28
|
+
SHUTDOWN: (signal, duration) => `Received ${signal}. Shutting down the process in ${duration} ms.`,
|
|
29
|
+
UNHANDLED_ERROR: 'An unexpected error occurred. Locking the process for 10 seconds to recover.',
|
|
30
|
+
},
|
|
31
|
+
// API messages (api.ts)
|
|
32
|
+
API: {
|
|
33
|
+
REQUEST: (method, path) => `${method.toUpperCase()}: ${path}`,
|
|
34
|
+
STATUS: (code) => `Status: ${code}.`,
|
|
35
|
+
RATE_LIMIT: (path, delay) => `API rate limit exceeded. Retrying ${path} after a ${delay} ms delay.`,
|
|
36
|
+
RETRY: (path, delay) => `Retrying ${path} after a ${delay} ms delay.`,
|
|
37
|
+
REQUEST_FAILED: (options) => `Request failed.\n${JSON.stringify(options)}`,
|
|
38
|
+
REQUEST_TIMEOUT: (path) => `Request timeout for ${path || 'unknown'}`,
|
|
39
|
+
REQUEST_ERROR: (path, message, code) => `Request error for ${path || 'unknown'}: ${message || 'Unknown error'} (${code || 'NO_CODE'})`,
|
|
40
|
+
SOCKET_HANGUP_RETRY: (path, delay, attempt, max) => `Socket hang up detected. Retrying ${path || 'unknown'} with ${delay} ms delay (attempt ${attempt}/${max})`,
|
|
41
|
+
},
|
|
42
|
+
// Plugin messages (plugins.ts)
|
|
43
|
+
PLUGINS: {
|
|
44
|
+
LOAD_CALLED: 'Initializing plugin load...',
|
|
45
|
+
METHOD_LOADED: (method, name) => `${method} loaded from ${name} successfully!`,
|
|
46
|
+
METHOD_NOT_FOUND: (method, name) => `${method} not found in ${name}.`,
|
|
47
|
+
LOAD_SUCCESS: 'All plugins loaded successfully.',
|
|
48
|
+
LOAD_ERROR: 'An error occurred while loading plugins.',
|
|
49
|
+
LOAD_ERROR_DETAIL: (message) => `Failed to load plugins: ${message}`,
|
|
50
|
+
},
|
|
51
|
+
// Sync core messages (core/index.ts)
|
|
52
|
+
SYNC_CORE: {
|
|
53
|
+
START: 'Sync core: Start invoked.',
|
|
54
|
+
ENVIRONMENT: (env) => `Current environment: ${env}`,
|
|
55
|
+
TOKEN_FOUND: 'Sync token found in the checkpoint file:',
|
|
56
|
+
TOKEN_USING: 'Using sync token:',
|
|
57
|
+
FILE_NOT_FOUND: (path) => `File not found: ${path}`,
|
|
58
|
+
FILE_READ_ERROR: (err) => `An error occurred while reading the file: ${err}`,
|
|
59
|
+
POKE_INVOKED: 'Poke command invoked.',
|
|
60
|
+
POKE_NOTIFICATION: 'Received "contentstack sync" notification.',
|
|
61
|
+
POKE_ERROR: 'Error during poke operation.',
|
|
62
|
+
CHECK_CALLED: (sqStatus, wqStatus) => `Check initiated. SQ status: ${sqStatus}, WQ status: ${wqStatus}.`,
|
|
63
|
+
CHECK_COMPLETE: (cooloff) => `Sync completed. SQ flag updated. Cooloff duration: ${cooloff}.`,
|
|
64
|
+
CHECK_ERROR: 'Error during check operation.',
|
|
65
|
+
CHECK_RECOVERED: 'Check recovered from errors.',
|
|
66
|
+
CHECK_FAILED: 'Check failed due to an error.',
|
|
67
|
+
SYNC_STARTED: 'Sync process started.',
|
|
68
|
+
SYNC_TOKEN_OBJECT: 'Token object received for sync.',
|
|
69
|
+
SYNC_ERROR: 'Error during sync operation.',
|
|
70
|
+
SYNC_LOCKED: 'Contentstack sync is locked.',
|
|
71
|
+
SYNC_UNLOCKED: 'Contentstack sync is unlocked.',
|
|
72
|
+
FIRE_CALLED: (req) => `Fire operation triggered with: ${JSON.stringify(req)}`,
|
|
73
|
+
FIRE_COMPLETE: (itemCount) => `Fire operation completed. Items received: ${itemCount}.`,
|
|
74
|
+
API_CALL_CT: (uid) => `API call initiated for content type: ${uid}.`,
|
|
75
|
+
ERROR_MAP: 'Error [map]: Failed to fetch content type schema.',
|
|
76
|
+
ERROR_MAP_RESOLVE: 'Error [mapResolve]: Unable to resolve mapping.',
|
|
77
|
+
ERROR_FILTER_ITEMS: 'Error [filterItems]: Unable to filter items.',
|
|
78
|
+
ERROR_FIRE: 'Error during fire operation.',
|
|
79
|
+
REFIRE_CALLED: (req) => `Re-fire operation triggered with: ${JSON.stringify(req)}`,
|
|
80
|
+
CHECKPOINT_LOCKDOWN: 'Checkpoint: lockdown has been invoked',
|
|
81
|
+
},
|
|
82
|
+
// Main index messages (index.ts)
|
|
83
|
+
INDEX: {
|
|
84
|
+
ASSET_STORE_INIT: 'Asset store instance initialized successfully.',
|
|
85
|
+
CONTENT_STORE_INIT: 'Content store instance initialized successfully.',
|
|
86
|
+
SYNC_MANAGER_INIT: 'Sync manager initialized successfully.',
|
|
87
|
+
SYNC_UTILITY_STARTED: 'Contentstack sync utility started successfully.',
|
|
88
|
+
NOTIFICATION: (action, item) => `Notification received: ${action} – ${JSON.stringify(item)}`,
|
|
89
|
+
},
|
|
90
|
+
// Token management messages (token-management.ts)
|
|
91
|
+
TOKEN: {
|
|
92
|
+
CHECKPOINT_READ: (path) => `Checkpoint read from file: ${path}`,
|
|
93
|
+
TOKEN_READ: (path) => `Token retrieved: ${path}`,
|
|
94
|
+
SAVE_TOKEN: (name) => `Saving token with name: ${name}`,
|
|
95
|
+
SAVE_CHECKPOINT: (name) => `Saving checkpoint token with name: ${name}`,
|
|
96
|
+
LEDGER_CHECK: (file, exists) => `Ledger file check: ${file} exists? → ${exists}`,
|
|
97
|
+
},
|
|
98
|
+
// Queue messages (q.ts)
|
|
99
|
+
QUEUE: {
|
|
100
|
+
CONSTRUCTOR: 'Core \'Q\' constructor initiated.',
|
|
101
|
+
CONTENT_TYPE_RECEIVED: (ctUid, type) => `Received content type '${ctUid}' for '${type}'`,
|
|
102
|
+
ERROR_HANDLER_CALLED: (obj) => `Error handler invoked with: ${JSON.stringify(obj)}`,
|
|
103
|
+
ERROR_IN_HANDLER: 'An error occurred in the error handler.',
|
|
104
|
+
NEXT_CALLED: (inProgress, qLength) => `Calling 'next'. Current progress status: ${inProgress}, Queue length: ${qLength}.`,
|
|
105
|
+
EXECUTING: (data) => `Executing queue item: ${JSON.stringify(data)}`,
|
|
106
|
+
BEFORE_PLUGINS: 'Before-action plugins executed successfully.',
|
|
107
|
+
ACTION_COMPLETE: (action) => `Completed '${action}' on connector successfully.`,
|
|
108
|
+
CONNECTOR_CALLED: 'Connector instance invoked successfully.',
|
|
109
|
+
AFTER_PLUGINS: 'After-action plugins executed successfully.',
|
|
110
|
+
},
|
|
111
|
+
// File system messages (fs.ts)
|
|
112
|
+
FS: {
|
|
113
|
+
WRITE_FILE: (path) => `Writing file to: ${path}`,
|
|
114
|
+
READ_FILE: (path) => `Reading file from: ${path}`,
|
|
115
|
+
READ_FILE_SYNC: (path) => `Reading file synchronously from: ${path}`,
|
|
116
|
+
MKDIR: (path) => `Creating directory: ${path}`,
|
|
117
|
+
INVALID_READ: (path) => `Invalid 'read' operation on file. Expected ${path} to be of type 'file'!`,
|
|
118
|
+
},
|
|
119
|
+
// Utility messages (util/index.ts)
|
|
120
|
+
UTIL: {
|
|
121
|
+
ITEM_TYPE_MISMATCH: 'The item\'s type did not match any expected case.',
|
|
122
|
+
ITEM_SERIALIZED: (item) => `Serialized item: ${JSON.stringify(item)}`,
|
|
123
|
+
ONLY_ASSETS: (lastCt) => `Only assets were found in the SYNC API response. Last content type: ${lastCt}.`,
|
|
124
|
+
ONLY_CT_EVENTS: (lastCt) => `Only content type events were found in the SYNC API response. Last content type: ${lastCt}.`,
|
|
125
|
+
ASSETS_AND_CT: (lastCt) => `Assets and content types were found in the SYNC API response. Last content type: ${lastCt}.`,
|
|
126
|
+
MIXED_CT: (lastCt) => `Mixed content types were found in the SYNC API response. Last content type: ${lastCt}.`,
|
|
127
|
+
FILE_NOT_TYPE: (file) => `${file} is not of type file`,
|
|
128
|
+
UNABLE_TO_FIND_PLUGIN: (plugin) => `Unable to find plugin: ${JSON.stringify(plugin)}`,
|
|
129
|
+
PLUGIN_PATH_NOT_EXIST: (path) => `${path} does not exist!`,
|
|
130
|
+
},
|
|
131
|
+
// Unprocessible items messages (unprocessible.ts)
|
|
132
|
+
UNPROCESSIBLE: {
|
|
133
|
+
WRITE_FAILED: (data, file, error) => `Failed to write data to ${file}: ${JSON.stringify(data)}. Error: ${error}`,
|
|
134
|
+
READ_FAILED: (path) => `Failed to read file from: ${path}`,
|
|
135
|
+
WRITE_OBJECT_FAILED: (file, data, error) => `Failed to write object to ${file}: ${JSON.stringify(data)}. Error: ${error}`,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* @description Logger level constants
|
|
140
|
+
*/
|
|
141
|
+
exports.LOG_LEVELS = {
|
|
142
|
+
DEBUG: 'debug',
|
|
143
|
+
INFO: 'info',
|
|
144
|
+
WARN: 'warn',
|
|
145
|
+
ERROR: 'error',
|
|
146
|
+
LOG: 'log',
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* @description Error codes
|
|
150
|
+
*/
|
|
151
|
+
exports.ERROR_CODES = {
|
|
152
|
+
ILLEGAL_CONTENT_TYPE_CALL: 'ICTC',
|
|
153
|
+
INVALID_OPERATION_ON_READ_FILE: 'IOORF',
|
|
154
|
+
INVALID_OPERATION_ON_READ_FILE_SYNC: 'IOORFS',
|
|
155
|
+
MAX_RETRY_LIMIT_EXCEEDED: 'Max retry limit exceeded!',
|
|
156
|
+
REQUEST_TIMEOUT: 'Request timeout',
|
|
157
|
+
};
|
|
@@ -20,6 +20,7 @@ const index_1 = require("../index");
|
|
|
20
20
|
const fs_1 = require("./fs");
|
|
21
21
|
const index_2 = require("./index");
|
|
22
22
|
const logger_1 = require("./logger");
|
|
23
|
+
const messages_1 = require("./messages");
|
|
23
24
|
const counter = {
|
|
24
25
|
failed: 0,
|
|
25
26
|
filtered: 0,
|
|
@@ -75,18 +76,18 @@ const saveFilteredItems = (items, name, token) => {
|
|
|
75
76
|
loggedItems.push(objDetails);
|
|
76
77
|
return (0, fs_1.writeFile)(file, JSON.stringify(loggedItems)).then(resolve).catch((error) => {
|
|
77
78
|
// failed to log failed items
|
|
78
|
-
logger_1.logger.error(
|
|
79
|
+
logger_1.logger.error(messages_1.MESSAGES.UNPROCESSIBLE.WRITE_FAILED(loggedItems, file, error));
|
|
79
80
|
logger_1.logger.error(error);
|
|
80
81
|
return resolve('');
|
|
81
82
|
});
|
|
82
83
|
}).catch((error) => {
|
|
83
|
-
logger_1.logger.error(
|
|
84
|
+
logger_1.logger.error(messages_1.MESSAGES.UNPROCESSIBLE.READ_FAILED(file));
|
|
84
85
|
logger_1.logger.error(error);
|
|
85
86
|
return resolve('');
|
|
86
87
|
});
|
|
87
88
|
}
|
|
88
89
|
return (0, fs_1.writeFile)(file, JSON.stringify([objDetails])).then(resolve).catch((error) => {
|
|
89
|
-
logger_1.logger.error(
|
|
90
|
+
logger_1.logger.error(messages_1.MESSAGES.UNPROCESSIBLE.WRITE_OBJECT_FAILED(file, objDetails, error));
|
|
90
91
|
logger_1.logger.error(error);
|
|
91
92
|
return resolve('');
|
|
92
93
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/datasync-manager",
|
|
3
3
|
"author": "Contentstack LLC <support@contentstack.com>",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.2.0",
|
|
5
5
|
"description": "The primary module of Contentstack DataSync. Syncs Contentstack data with your server using Contentstack Sync API",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"dependencies": {
|