@mhmdhammoud/meritt-utils 1.5.2 → 1.5.4
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/.github/workflows/npm-publish.yml +67 -26
- package/.github/workflows/push.yml +73 -19
- package/.prettierrc +8 -0
- package/dist/__tests__/logger.test.js +17 -7
- package/dist/lib/cypto.d.ts +1 -1
- package/dist/lib/elastic-transport.d.ts +27 -0
- package/dist/lib/elastic-transport.js +137 -0
- package/dist/lib/logger.js +28 -18
- package/dist/lib/pdf.d.ts +1 -1
- package/dist/lib/pdf.js +2 -1
- package/eslint.config.mjs +64 -0
- package/package.json +16 -10
- package/src/__tests__/colorful.test.ts +1 -1
- package/src/__tests__/formatter.test.ts +1 -1
- package/src/__tests__/logger.test.ts +2 -2
- package/src/lib/elastic-transport.ts +203 -0
- package/src/lib/imagefull.ts +1 -1
- package/src/lib/index.ts +6 -6
- package/src/lib/logger.ts +25 -15
- package/src/lib/pdf.ts +2 -2
- package/src/utilities/index.ts +1 -1
- package/.eslintignore +0 -2
- package/.eslintrc.js +0 -28
|
@@ -3,41 +3,82 @@ name: NPM Publish on Release
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches: [master]
|
|
6
|
+
|
|
6
7
|
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout code
|
|
12
|
+
uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Setup Node.js
|
|
15
|
+
uses: actions/setup-node@v4
|
|
16
|
+
with:
|
|
17
|
+
node-version: '20'
|
|
18
|
+
cache: 'npm'
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: npm ci
|
|
22
|
+
|
|
23
|
+
- name: Run type check
|
|
24
|
+
run: npm run test:types
|
|
25
|
+
|
|
26
|
+
- name: Run linting
|
|
27
|
+
run: npm run lint
|
|
28
|
+
|
|
29
|
+
- name: Run tests
|
|
30
|
+
run: npm test
|
|
31
|
+
|
|
7
32
|
build:
|
|
33
|
+
needs: test
|
|
8
34
|
runs-on: ubuntu-latest
|
|
9
35
|
steps:
|
|
10
|
-
-
|
|
11
|
-
|
|
36
|
+
- name: Checkout code
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- name: Setup Node.js
|
|
40
|
+
uses: actions/setup-node@v4
|
|
12
41
|
with:
|
|
13
|
-
node-version:
|
|
14
|
-
|
|
42
|
+
node-version: '20'
|
|
43
|
+
cache: 'npm'
|
|
44
|
+
|
|
45
|
+
- name: Install dependencies
|
|
46
|
+
run: npm ci
|
|
47
|
+
|
|
48
|
+
- name: Build project
|
|
49
|
+
run: npm run build
|
|
50
|
+
|
|
51
|
+
- name: Upload build artifacts
|
|
52
|
+
uses: actions/upload-artifact@v4
|
|
53
|
+
with:
|
|
54
|
+
name: dist
|
|
55
|
+
path: dist/
|
|
15
56
|
|
|
16
57
|
publish-npm:
|
|
17
|
-
needs: build
|
|
58
|
+
needs: [test, build]
|
|
18
59
|
runs-on: ubuntu-latest
|
|
60
|
+
if: success()
|
|
19
61
|
steps:
|
|
20
|
-
-
|
|
21
|
-
|
|
62
|
+
- name: Checkout code
|
|
63
|
+
uses: actions/checkout@v4
|
|
64
|
+
|
|
65
|
+
- name: Setup Node.js
|
|
66
|
+
uses: actions/setup-node@v4
|
|
22
67
|
with:
|
|
23
|
-
node-version:
|
|
68
|
+
node-version: '20'
|
|
24
69
|
registry-url: https://registry.npmjs.org/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
steps:
|
|
33
|
-
- name: Notify by Email
|
|
34
|
-
uses: dawidd6/action-send-mail@v2
|
|
70
|
+
cache: 'npm'
|
|
71
|
+
|
|
72
|
+
- name: Install dependencies
|
|
73
|
+
run: npm ci
|
|
74
|
+
|
|
75
|
+
- name: Download build artifacts
|
|
76
|
+
uses: actions/download-artifact@v4
|
|
35
77
|
with:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
from: Github Action
|
|
78
|
+
name: dist
|
|
79
|
+
path: dist/
|
|
80
|
+
|
|
81
|
+
- name: Publish to NPM
|
|
82
|
+
run: npm publish
|
|
83
|
+
env:
|
|
84
|
+
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
|
|
@@ -1,29 +1,83 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: CI Pipeline
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
push:
|
|
4
5
|
branches: [dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [dev, master]
|
|
8
|
+
|
|
5
9
|
jobs:
|
|
6
|
-
|
|
10
|
+
lint-and-test:
|
|
7
11
|
runs-on: ubuntu-latest
|
|
8
12
|
steps:
|
|
9
|
-
-
|
|
10
|
-
|
|
13
|
+
- name: Checkout code
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Setup Node.js
|
|
17
|
+
uses: actions/setup-node@v4
|
|
11
18
|
with:
|
|
12
|
-
node-version:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
node-version: '20'
|
|
20
|
+
cache: 'npm'
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: npm ci
|
|
24
|
+
|
|
25
|
+
- name: Run type check
|
|
26
|
+
run: npm run test:types
|
|
27
|
+
|
|
28
|
+
- name: Run linting
|
|
29
|
+
run: npm run lint
|
|
30
|
+
|
|
31
|
+
- name: Run tests with coverage
|
|
32
|
+
run: npm run test:coverage
|
|
33
|
+
|
|
34
|
+
- name: Upload coverage reports
|
|
35
|
+
uses: actions/upload-artifact@v4
|
|
36
|
+
if: always()
|
|
37
|
+
with:
|
|
38
|
+
name: coverage-report
|
|
39
|
+
path: coverage/
|
|
40
|
+
|
|
41
|
+
build:
|
|
42
|
+
needs: lint-and-test
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
steps:
|
|
45
|
+
- name: Checkout code
|
|
46
|
+
uses: actions/checkout@v4
|
|
47
|
+
|
|
48
|
+
- name: Setup Node.js
|
|
49
|
+
uses: actions/setup-node@v4
|
|
50
|
+
with:
|
|
51
|
+
node-version: '20'
|
|
52
|
+
cache: 'npm'
|
|
53
|
+
|
|
54
|
+
- name: Install dependencies
|
|
55
|
+
run: npm ci
|
|
56
|
+
|
|
57
|
+
- name: Build project
|
|
58
|
+
run: npm run build
|
|
59
|
+
|
|
60
|
+
- name: Upload build artifacts
|
|
61
|
+
uses: actions/upload-artifact@v4
|
|
62
|
+
with:
|
|
63
|
+
name: dist
|
|
64
|
+
path: dist/
|
|
65
|
+
|
|
66
|
+
security-audit:
|
|
17
67
|
runs-on: ubuntu-latest
|
|
18
68
|
steps:
|
|
19
|
-
- name:
|
|
20
|
-
uses:
|
|
69
|
+
- name: Checkout code
|
|
70
|
+
uses: actions/checkout@v4
|
|
71
|
+
|
|
72
|
+
- name: Setup Node.js
|
|
73
|
+
uses: actions/setup-node@v4
|
|
21
74
|
with:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
75
|
+
node-version: '20'
|
|
76
|
+
cache: 'npm'
|
|
77
|
+
|
|
78
|
+
- name: Install dependencies
|
|
79
|
+
run: npm ci
|
|
80
|
+
|
|
81
|
+
- name: Run security audit
|
|
82
|
+
run: npm audit --audit-level=moderate
|
|
83
|
+
|
package/.prettierrc
ADDED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
const logger_1 = __importStar(require("../lib/logger"));
|
|
27
37
|
const pino_1 = require("pino");
|
package/dist/lib/cypto.d.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elasticsearch transport for Pino with connection lifecycle resilience.
|
|
3
|
+
*
|
|
4
|
+
* Based on pino-elasticsearch with a fix for GitHub issue #140:
|
|
5
|
+
* When maxRetries are exceeded and Elasticsearch nodes are DEAD, the bulk helper
|
|
6
|
+
* destroys the splitter stream, causing logs to stop permanently until restart.
|
|
7
|
+
*
|
|
8
|
+
* This implementation overrides splitter.destroy to BOTH resurrect the connection
|
|
9
|
+
* pool AND reinitialize the bulk handler, so logging continues after ES recovers.
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/pinojs/pino-elasticsearch/issues/140
|
|
12
|
+
* @see https://github.com/pinojs/pino-elasticsearch/issues/72
|
|
13
|
+
*/
|
|
14
|
+
import type { ClientOptions } from '@elastic/elasticsearch';
|
|
15
|
+
export interface ElasticTransportOptions extends Pick<ClientOptions, 'node' | 'auth' | 'cloud' | 'caFingerprint' | 'Connection' | 'ConnectionPool' | 'maxRetries' | 'requestTimeout'> {
|
|
16
|
+
sniffOnConnectionFault?: boolean;
|
|
17
|
+
index?: string | ((logTime: string) => string);
|
|
18
|
+
flushBytes?: number;
|
|
19
|
+
'flush-bytes'?: number;
|
|
20
|
+
flushInterval?: number;
|
|
21
|
+
'flush-interval'?: number;
|
|
22
|
+
esVersion?: number;
|
|
23
|
+
'es-version'?: number;
|
|
24
|
+
rejectUnauthorized?: boolean;
|
|
25
|
+
tls?: ClientOptions['tls'];
|
|
26
|
+
}
|
|
27
|
+
export declare const createElasticTransport: (opts?: ElasticTransportOptions) => NodeJS.ReadWriteStream;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Elasticsearch transport for Pino with connection lifecycle resilience.
|
|
4
|
+
*
|
|
5
|
+
* Based on pino-elasticsearch with a fix for GitHub issue #140:
|
|
6
|
+
* When maxRetries are exceeded and Elasticsearch nodes are DEAD, the bulk helper
|
|
7
|
+
* destroys the splitter stream, causing logs to stop permanently until restart.
|
|
8
|
+
*
|
|
9
|
+
* This implementation overrides splitter.destroy to BOTH resurrect the connection
|
|
10
|
+
* pool AND reinitialize the bulk handler, so logging continues after ES recovers.
|
|
11
|
+
*
|
|
12
|
+
* @see https://github.com/pinojs/pino-elasticsearch/issues/140
|
|
13
|
+
* @see https://github.com/pinojs/pino-elasticsearch/issues/72
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.createElasticTransport = void 0;
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
18
|
+
const split = require('split2');
|
|
19
|
+
const elasticsearch_1 = require("@elastic/elasticsearch");
|
|
20
|
+
function setDateTimeString(value) {
|
|
21
|
+
if (value !== null && typeof value === 'object' && 'time' in value) {
|
|
22
|
+
const t = value.time;
|
|
23
|
+
if ((typeof t === 'string' && t.length > 0) ||
|
|
24
|
+
(typeof t === 'number' && t >= 0)) {
|
|
25
|
+
return new Date(t).toISOString();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return new Date().toISOString();
|
|
29
|
+
}
|
|
30
|
+
function getIndexName(index, time) {
|
|
31
|
+
if (typeof index === 'function') {
|
|
32
|
+
return index(time);
|
|
33
|
+
}
|
|
34
|
+
return index.replace('%{DATE}', time.substring(0, 10));
|
|
35
|
+
}
|
|
36
|
+
function initializeBulkHandler(opts, client, splitter) {
|
|
37
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
38
|
+
const esVersion = Number((_b = (_a = opts.esVersion) !== null && _a !== void 0 ? _a : opts['es-version']) !== null && _b !== void 0 ? _b : 7);
|
|
39
|
+
const index = (_c = opts.index) !== null && _c !== void 0 ? _c : 'pino';
|
|
40
|
+
const buildIndexName = typeof index === 'function' ? index : null;
|
|
41
|
+
const opType = esVersion >= 7 ? undefined : undefined;
|
|
42
|
+
// CRITICAL FIX (issue #140): When bulk helper destroys stream after retries exhausted,
|
|
43
|
+
// we must BOTH resurrect the pool AND reinitialize the bulk handler so logging continues.
|
|
44
|
+
// connectionPool.resurrect exists at runtime (elastic-transport) but may not be in types
|
|
45
|
+
const pool = client.connectionPool;
|
|
46
|
+
const splitterWithDestroy = splitter;
|
|
47
|
+
splitterWithDestroy.destroy = function () {
|
|
48
|
+
if (typeof pool.resurrect === 'function') {
|
|
49
|
+
pool.resurrect({ name: 'elasticsearch-js' });
|
|
50
|
+
}
|
|
51
|
+
// Reinitialize bulk handler - without this, logging stops permanently until restart
|
|
52
|
+
initializeBulkHandler(opts, client, splitter);
|
|
53
|
+
};
|
|
54
|
+
const indexName = (time = new Date().toISOString()) => buildIndexName ? buildIndexName(time) : getIndexName(index, time);
|
|
55
|
+
const bulkInsert = client.helpers.bulk({
|
|
56
|
+
datasource: splitter,
|
|
57
|
+
flushBytes: (_e = (_d = opts.flushBytes) !== null && _d !== void 0 ? _d : opts['flush-bytes']) !== null && _e !== void 0 ? _e : 1000,
|
|
58
|
+
flushInterval: (_g = (_f = opts.flushInterval) !== null && _f !== void 0 ? _f : opts['flush-interval']) !== null && _g !== void 0 ? _g : 3000,
|
|
59
|
+
refreshOnCompletion: indexName(),
|
|
60
|
+
onDocument(doc) {
|
|
61
|
+
var _a, _b;
|
|
62
|
+
const d = doc;
|
|
63
|
+
const date = (_b = (_a = d.time) !== null && _a !== void 0 ? _a : d['@timestamp']) !== null && _b !== void 0 ? _b : new Date().toISOString();
|
|
64
|
+
if (opType === 'create') {
|
|
65
|
+
d['@timestamp'] = date;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
index: {
|
|
69
|
+
_index: indexName(date),
|
|
70
|
+
op_type: opType,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
onDrop(doc) {
|
|
75
|
+
const error = new Error('Dropped document');
|
|
76
|
+
error.document = doc;
|
|
77
|
+
splitter.emit('insertError', error);
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
bulkInsert.then((stats) => splitter.emit('insert', stats), (err) => splitter.emit('error', err));
|
|
81
|
+
}
|
|
82
|
+
const createElasticTransport = (opts = {}) => {
|
|
83
|
+
const splitter = split(function (line) {
|
|
84
|
+
let value;
|
|
85
|
+
try {
|
|
86
|
+
value = JSON.parse(line);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
this.emit('unknown', line, error);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (typeof value === 'boolean') {
|
|
93
|
+
this.emit('unknown', line, 'Boolean value ignored');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (value === null) {
|
|
97
|
+
this.emit('unknown', line, 'Null value ignored');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (typeof value !== 'object') {
|
|
101
|
+
value = { data: value, time: setDateTimeString(value) };
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const obj = value;
|
|
105
|
+
if (obj['@timestamp'] === undefined) {
|
|
106
|
+
;
|
|
107
|
+
obj.time = setDateTimeString(obj);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return value;
|
|
111
|
+
}, { autoDestroy: true });
|
|
112
|
+
const clientOpts = {
|
|
113
|
+
node: opts.node,
|
|
114
|
+
auth: opts.auth,
|
|
115
|
+
cloud: opts.cloud,
|
|
116
|
+
tls: { rejectUnauthorized: opts.rejectUnauthorized, ...opts.tls },
|
|
117
|
+
maxRetries: opts.maxRetries,
|
|
118
|
+
requestTimeout: opts.requestTimeout,
|
|
119
|
+
sniffOnConnectionFault: opts.sniffOnConnectionFault,
|
|
120
|
+
};
|
|
121
|
+
if (opts.caFingerprint) {
|
|
122
|
+
clientOpts.caFingerprint = opts.caFingerprint;
|
|
123
|
+
}
|
|
124
|
+
if (opts.Connection) {
|
|
125
|
+
clientOpts.Connection = opts.Connection;
|
|
126
|
+
}
|
|
127
|
+
if (opts.ConnectionPool) {
|
|
128
|
+
clientOpts.ConnectionPool = opts.ConnectionPool;
|
|
129
|
+
}
|
|
130
|
+
const client = new elasticsearch_1.Client(clientOpts);
|
|
131
|
+
client.diagnostic.on('resurrect', () => {
|
|
132
|
+
initializeBulkHandler(opts, client, splitter);
|
|
133
|
+
});
|
|
134
|
+
initializeBulkHandler(opts, client, splitter);
|
|
135
|
+
return splitter;
|
|
136
|
+
};
|
|
137
|
+
exports.createElasticTransport = createElasticTransport;
|
package/dist/lib/logger.js
CHANGED
|
@@ -15,21 +15,28 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
28
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.isValidLogLevel =
|
|
36
|
+
exports.isValidLogLevel = isValidLogLevel;
|
|
30
37
|
const pino_1 = require("pino");
|
|
31
38
|
const dotenv = __importStar(require("dotenv"));
|
|
32
|
-
const
|
|
39
|
+
const elastic_transport_1 = require("./elastic-transport");
|
|
33
40
|
dotenv.config();
|
|
34
41
|
/**
|
|
35
42
|
* Pino logger backend - singleton
|
|
@@ -48,8 +55,13 @@ let shutdownHandlersRegistered = false;
|
|
|
48
55
|
* @throws Error if required environment variables are missing.
|
|
49
56
|
*/
|
|
50
57
|
function validateElasticsearchEnv() {
|
|
51
|
-
const required = [
|
|
52
|
-
|
|
58
|
+
const required = [
|
|
59
|
+
'ELASTICSEARCH_NODE',
|
|
60
|
+
'ELASTICSEARCH_USERNAME',
|
|
61
|
+
'ELASTICSEARCH_PASSWORD',
|
|
62
|
+
'SERVER_NICKNAME',
|
|
63
|
+
];
|
|
64
|
+
const missing = required.filter((key) => !process.env[key]);
|
|
53
65
|
if (missing.length > 0) {
|
|
54
66
|
throw new Error(`Missing required Elasticsearch environment variables: ${missing.join(', ')}`);
|
|
55
67
|
}
|
|
@@ -175,9 +187,8 @@ function getLogger(elasticConfig) {
|
|
|
175
187
|
if (elasticConfig) {
|
|
176
188
|
Object.assign(esConfig, elasticConfig);
|
|
177
189
|
}
|
|
178
|
-
// Create transport
|
|
179
|
-
|
|
180
|
-
esTransport = (0, pino_elasticsearch_1.default)(esConfig);
|
|
190
|
+
// Create transport with connection lifecycle fix (pino-elasticsearch #140)
|
|
191
|
+
esTransport = (0, elastic_transport_1.createElasticTransport)(esConfig);
|
|
181
192
|
// Handle Elasticsearch connection errors
|
|
182
193
|
esTransport.on('error', (err) => {
|
|
183
194
|
console.error('[Logger] Elasticsearch transport error:', err.message);
|
|
@@ -220,7 +231,6 @@ function isValidLogLevel(level) {
|
|
|
220
231
|
}
|
|
221
232
|
return true;
|
|
222
233
|
}
|
|
223
|
-
exports.isValidLogLevel = isValidLogLevel;
|
|
224
234
|
/**
|
|
225
235
|
* Logger Wrapper.
|
|
226
236
|
* Wraps a Pino logger instance and provides logging methods.
|
package/dist/lib/pdf.d.ts
CHANGED
package/dist/lib/pdf.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// import { AxiosInstance } from '../utilities'
|
|
3
4
|
/*
|
|
4
5
|
Author : Mustafa Halabi https://github.com/mustafahalabi
|
|
5
6
|
Date : 2023-06-24
|
|
@@ -18,7 +19,7 @@ class Pdf {
|
|
|
18
19
|
* // => 'Hello-World'
|
|
19
20
|
* ```
|
|
20
21
|
* */
|
|
21
|
-
this.getBase64Images = (
|
|
22
|
+
this.getBase64Images = (_url) => {
|
|
22
23
|
return '';
|
|
23
24
|
};
|
|
24
25
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import eslint from '@eslint/js'
|
|
3
|
+
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
|
|
4
|
+
import globals from 'globals'
|
|
5
|
+
import tseslint from 'typescript-eslint'
|
|
6
|
+
|
|
7
|
+
export default tseslint.config(
|
|
8
|
+
{
|
|
9
|
+
ignores: [
|
|
10
|
+
'eslint.config.mjs',
|
|
11
|
+
'dist/**',
|
|
12
|
+
'node_modules/**',
|
|
13
|
+
'coverage/**',
|
|
14
|
+
'*.d.ts',
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
eslint.configs.recommended,
|
|
18
|
+
...tseslint.configs.recommendedTypeChecked,
|
|
19
|
+
eslintPluginPrettierRecommended,
|
|
20
|
+
{
|
|
21
|
+
languageOptions: {
|
|
22
|
+
globals: {
|
|
23
|
+
...globals.node,
|
|
24
|
+
},
|
|
25
|
+
sourceType: 'module',
|
|
26
|
+
parserOptions: {
|
|
27
|
+
projectService: true,
|
|
28
|
+
tsconfigRootDir: import.meta.dirname,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
rules: {
|
|
34
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
35
|
+
'@typescript-eslint/no-floating-promises': 'warn',
|
|
36
|
+
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
37
|
+
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
38
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
39
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
40
|
+
'@typescript-eslint/no-unsafe-call': 'off',
|
|
41
|
+
'@typescript-eslint/ban-ts-comment': 'off',
|
|
42
|
+
'@typescript-eslint/require-await': 'off',
|
|
43
|
+
'@typescript-eslint/await-thenable': 'off',
|
|
44
|
+
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
|
|
45
|
+
'@typescript-eslint/no-base-to-string': 'off',
|
|
46
|
+
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
|
47
|
+
'@typescript-eslint/no-unused-vars': [
|
|
48
|
+
'error',
|
|
49
|
+
{
|
|
50
|
+
argsIgnorePattern: '^_',
|
|
51
|
+
varsIgnorePattern: '^_',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
'no-console': 'error',
|
|
55
|
+
'prettier/prettier': ['error', { semi: false }],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
files: ['src/lib/logger.ts'],
|
|
60
|
+
rules: {
|
|
61
|
+
'no-console': 'off',
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mhmdhammoud/meritt-utils",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"private": false,
|
|
@@ -25,25 +25,31 @@
|
|
|
25
25
|
"test:coverage": "jest --coverage"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
30
|
-
"
|
|
31
|
-
"eslint": "^
|
|
32
|
-
"eslint-plugin-
|
|
33
|
-
"
|
|
28
|
+
"@eslint/js": "^9.31.0",
|
|
29
|
+
"@types/jest": "^29.5.12",
|
|
30
|
+
"eslint": "^9.31.0",
|
|
31
|
+
"eslint-config-prettier": "^10.1.8",
|
|
32
|
+
"eslint-plugin-prettier": "^5.5.3",
|
|
33
|
+
"eslint-plugin-tsdoc": "^0.5.2",
|
|
34
|
+
"globals": "^16.0.0",
|
|
35
|
+
"husky": "^9.1.6",
|
|
34
36
|
"jest": "^29.7.0",
|
|
35
37
|
"pino-pretty": "^10.3.1",
|
|
38
|
+
"prettier": "^3.3.3",
|
|
36
39
|
"ts-jest": "^29.1.1",
|
|
37
|
-
"ts-node-dev": "^
|
|
38
|
-
"typescript": "^
|
|
40
|
+
"ts-node-dev": "^2.0.0",
|
|
41
|
+
"typescript": "^5.3.3",
|
|
42
|
+
"typescript-eslint": "^8.20.0"
|
|
39
43
|
},
|
|
40
44
|
"author": "Mhmdhammoud",
|
|
41
45
|
"license": "ISC",
|
|
42
46
|
"dependencies": {
|
|
47
|
+
"@elastic/elasticsearch": "^8.17.0",
|
|
43
48
|
"axios": "^1.4.0",
|
|
44
49
|
"dotenv": "^16.4.1",
|
|
45
50
|
"imagesloaded": "^5.0.0",
|
|
46
51
|
"pino": "^8.19.0",
|
|
47
|
-
"pino-elasticsearch": "^8.0.0"
|
|
52
|
+
"pino-elasticsearch": "^8.0.0",
|
|
53
|
+
"split2": "^4.2.0"
|
|
48
54
|
}
|
|
49
55
|
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elasticsearch transport for Pino with connection lifecycle resilience.
|
|
3
|
+
*
|
|
4
|
+
* Based on pino-elasticsearch with a fix for GitHub issue #140:
|
|
5
|
+
* When maxRetries are exceeded and Elasticsearch nodes are DEAD, the bulk helper
|
|
6
|
+
* destroys the splitter stream, causing logs to stop permanently until restart.
|
|
7
|
+
*
|
|
8
|
+
* This implementation overrides splitter.destroy to BOTH resurrect the connection
|
|
9
|
+
* pool AND reinitialize the bulk handler, so logging continues after ES recovers.
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/pinojs/pino-elasticsearch/issues/140
|
|
12
|
+
* @see https://github.com/pinojs/pino-elasticsearch/issues/72
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
16
|
+
const split = require('split2') as (
|
|
17
|
+
fn: (line: string) => unknown,
|
|
18
|
+
opts?: { autoDestroy?: boolean }
|
|
19
|
+
) => NodeJS.ReadWriteStream
|
|
20
|
+
import { Readable } from 'stream'
|
|
21
|
+
import { Client } from '@elastic/elasticsearch'
|
|
22
|
+
import type { ClientOptions } from '@elastic/elasticsearch'
|
|
23
|
+
|
|
24
|
+
export interface ElasticTransportOptions extends Pick<
|
|
25
|
+
ClientOptions,
|
|
26
|
+
| 'node'
|
|
27
|
+
| 'auth'
|
|
28
|
+
| 'cloud'
|
|
29
|
+
| 'caFingerprint'
|
|
30
|
+
| 'Connection'
|
|
31
|
+
| 'ConnectionPool'
|
|
32
|
+
| 'maxRetries'
|
|
33
|
+
| 'requestTimeout'
|
|
34
|
+
> {
|
|
35
|
+
sniffOnConnectionFault?: boolean
|
|
36
|
+
index?: string | ((logTime: string) => string)
|
|
37
|
+
flushBytes?: number
|
|
38
|
+
'flush-bytes'?: number
|
|
39
|
+
flushInterval?: number
|
|
40
|
+
'flush-interval'?: number
|
|
41
|
+
esVersion?: number
|
|
42
|
+
'es-version'?: number
|
|
43
|
+
rejectUnauthorized?: boolean
|
|
44
|
+
tls?: ClientOptions['tls']
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface LogDocument {
|
|
48
|
+
time?: string
|
|
49
|
+
'@timestamp'?: string
|
|
50
|
+
[k: string]: unknown
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function setDateTimeString(value: unknown): string {
|
|
54
|
+
if (value !== null && typeof value === 'object' && 'time' in value) {
|
|
55
|
+
const t = (value as { time: unknown }).time
|
|
56
|
+
if (
|
|
57
|
+
(typeof t === 'string' && t.length > 0) ||
|
|
58
|
+
(typeof t === 'number' && t >= 0)
|
|
59
|
+
) {
|
|
60
|
+
return new Date(t).toISOString()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return new Date().toISOString()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getIndexName(
|
|
67
|
+
index: string | ((logTime: string) => string),
|
|
68
|
+
time: string
|
|
69
|
+
): string {
|
|
70
|
+
if (typeof index === 'function') {
|
|
71
|
+
return index(time)
|
|
72
|
+
}
|
|
73
|
+
return index.replace('%{DATE}', time.substring(0, 10))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function initializeBulkHandler(
|
|
77
|
+
opts: ElasticTransportOptions,
|
|
78
|
+
client: Client,
|
|
79
|
+
splitter: NodeJS.ReadWriteStream
|
|
80
|
+
): void {
|
|
81
|
+
const esVersion = Number(opts.esVersion ?? opts['es-version'] ?? 7)
|
|
82
|
+
const index = opts.index ?? 'pino'
|
|
83
|
+
const buildIndexName = typeof index === 'function' ? index : null
|
|
84
|
+
const opType = esVersion >= 7 ? undefined : undefined
|
|
85
|
+
|
|
86
|
+
// CRITICAL FIX (issue #140): When bulk helper destroys stream after retries exhausted,
|
|
87
|
+
// we must BOTH resurrect the pool AND reinitialize the bulk handler so logging continues.
|
|
88
|
+
// connectionPool.resurrect exists at runtime (elastic-transport) but may not be in types
|
|
89
|
+
const pool = client.connectionPool as {
|
|
90
|
+
resurrect?: (opts: { name: string }) => void
|
|
91
|
+
}
|
|
92
|
+
const splitterWithDestroy = splitter as NodeJS.ReadWriteStream & {
|
|
93
|
+
destroy: (err?: Error) => void
|
|
94
|
+
}
|
|
95
|
+
splitterWithDestroy.destroy = function () {
|
|
96
|
+
if (typeof pool.resurrect === 'function') {
|
|
97
|
+
pool.resurrect({ name: 'elasticsearch-js' })
|
|
98
|
+
}
|
|
99
|
+
// Reinitialize bulk handler - without this, logging stops permanently until restart
|
|
100
|
+
initializeBulkHandler(opts, client, splitter)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const indexName = (time = new Date().toISOString()) =>
|
|
104
|
+
buildIndexName ? buildIndexName(time) : getIndexName(index as string, time)
|
|
105
|
+
|
|
106
|
+
const bulkInsert = client.helpers.bulk({
|
|
107
|
+
datasource: splitter as unknown as Readable,
|
|
108
|
+
flushBytes: opts.flushBytes ?? opts['flush-bytes'] ?? 1000,
|
|
109
|
+
flushInterval: opts.flushInterval ?? opts['flush-interval'] ?? 3000,
|
|
110
|
+
refreshOnCompletion: indexName(),
|
|
111
|
+
onDocument(doc: unknown) {
|
|
112
|
+
const d = doc as LogDocument
|
|
113
|
+
const date = d.time ?? d['@timestamp'] ?? new Date().toISOString()
|
|
114
|
+
if (opType === 'create') {
|
|
115
|
+
d['@timestamp'] = date
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
index: {
|
|
119
|
+
_index: indexName(date),
|
|
120
|
+
op_type: opType,
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
onDrop(doc: unknown) {
|
|
125
|
+
const error = new Error('Dropped document') as Error & {
|
|
126
|
+
document: unknown
|
|
127
|
+
}
|
|
128
|
+
error.document = doc
|
|
129
|
+
splitter.emit('insertError', error)
|
|
130
|
+
},
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
bulkInsert.then(
|
|
134
|
+
(stats) => splitter.emit('insert', stats),
|
|
135
|
+
(err) => splitter.emit('error', err)
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const createElasticTransport = (
|
|
140
|
+
opts: ElasticTransportOptions = {}
|
|
141
|
+
): NodeJS.ReadWriteStream => {
|
|
142
|
+
const splitter = split(
|
|
143
|
+
function (this: NodeJS.ReadWriteStream, line: string) {
|
|
144
|
+
let value: unknown
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
value = JSON.parse(line) as unknown
|
|
148
|
+
} catch (error) {
|
|
149
|
+
this.emit('unknown', line, error)
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (typeof value === 'boolean') {
|
|
154
|
+
this.emit('unknown', line, 'Boolean value ignored')
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
if (value === null) {
|
|
158
|
+
this.emit('unknown', line, 'Null value ignored')
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
if (typeof value !== 'object') {
|
|
162
|
+
value = { data: value, time: setDateTimeString(value) }
|
|
163
|
+
} else {
|
|
164
|
+
const obj = value as Record<string, unknown>
|
|
165
|
+
if (obj['@timestamp'] === undefined) {
|
|
166
|
+
;(obj as LogDocument).time = setDateTimeString(obj)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return value
|
|
170
|
+
},
|
|
171
|
+
{ autoDestroy: true }
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
const clientOpts: ClientOptions = {
|
|
175
|
+
node: opts.node,
|
|
176
|
+
auth: opts.auth,
|
|
177
|
+
cloud: opts.cloud,
|
|
178
|
+
tls: { rejectUnauthorized: opts.rejectUnauthorized, ...opts.tls },
|
|
179
|
+
maxRetries: opts.maxRetries,
|
|
180
|
+
requestTimeout: opts.requestTimeout,
|
|
181
|
+
sniffOnConnectionFault: opts.sniffOnConnectionFault,
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (opts.caFingerprint) {
|
|
185
|
+
clientOpts.caFingerprint = opts.caFingerprint
|
|
186
|
+
}
|
|
187
|
+
if (opts.Connection) {
|
|
188
|
+
clientOpts.Connection = opts.Connection
|
|
189
|
+
}
|
|
190
|
+
if (opts.ConnectionPool) {
|
|
191
|
+
clientOpts.ConnectionPool = opts.ConnectionPool
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const client = new Client(clientOpts)
|
|
195
|
+
|
|
196
|
+
client.diagnostic.on('resurrect', () => {
|
|
197
|
+
initializeBulkHandler(opts, client, splitter)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
initializeBulkHandler(opts, client, splitter)
|
|
201
|
+
|
|
202
|
+
return splitter
|
|
203
|
+
}
|
package/src/lib/imagefull.ts
CHANGED
package/src/lib/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export {default as Crypto} from './cypto'
|
|
2
|
-
export {default as Formatter} from './formatter'
|
|
3
|
-
export {default as Pdf} from './formatter'
|
|
4
|
-
export {default as Colorful} from './colorful'
|
|
5
|
-
export {default as ImageFull} from './imagefull'
|
|
6
|
-
export {default as Logger} from './logger'
|
|
1
|
+
export { default as Crypto } from './cypto'
|
|
2
|
+
export { default as Formatter } from './formatter'
|
|
3
|
+
export { default as Pdf } from './formatter'
|
|
4
|
+
export { default as Colorful } from './colorful'
|
|
5
|
+
export { default as ImageFull } from './imagefull'
|
|
6
|
+
export { default as Logger } from './logger'
|
package/src/lib/logger.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {Logger as PinoLogger, pino, stdTimeFunctions} from 'pino'
|
|
1
|
+
import { Logger as PinoLogger, pino, stdTimeFunctions } from 'pino'
|
|
2
2
|
import * as dotenv from 'dotenv'
|
|
3
|
-
import
|
|
4
|
-
import {LOG_LEVEL, LogEvent, ElasticConfig} from '../types'
|
|
3
|
+
import { createElasticTransport } from './elastic-transport'
|
|
4
|
+
import { LOG_LEVEL, LogEvent, ElasticConfig } from '../types'
|
|
5
5
|
|
|
6
6
|
dotenv.config()
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ let pinoLogger: PinoLogger
|
|
|
13
13
|
/**
|
|
14
14
|
* Elasticsearch transport instance - kept for cleanup
|
|
15
15
|
*/
|
|
16
|
-
let esTransport:
|
|
16
|
+
let esTransport: NodeJS.ReadWriteStream | null = null
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Flag to track if shutdown handlers are registered
|
|
@@ -25,8 +25,13 @@ let shutdownHandlersRegistered = false
|
|
|
25
25
|
* @throws Error if required environment variables are missing.
|
|
26
26
|
*/
|
|
27
27
|
function validateElasticsearchEnv(): void {
|
|
28
|
-
const required = [
|
|
29
|
-
|
|
28
|
+
const required = [
|
|
29
|
+
'ELASTICSEARCH_NODE',
|
|
30
|
+
'ELASTICSEARCH_USERNAME',
|
|
31
|
+
'ELASTICSEARCH_PASSWORD',
|
|
32
|
+
'SERVER_NICKNAME',
|
|
33
|
+
]
|
|
34
|
+
const missing = required.filter((key) => !process.env[key])
|
|
30
35
|
|
|
31
36
|
if (missing.length > 0) {
|
|
32
37
|
throw new Error(
|
|
@@ -43,7 +48,11 @@ function validateElasticsearchEnv(): void {
|
|
|
43
48
|
* @returns The parsed integer or the default value.
|
|
44
49
|
* @throws Error if the value is not a valid number.
|
|
45
50
|
*/
|
|
46
|
-
function parseIntEnv(
|
|
51
|
+
function parseIntEnv(
|
|
52
|
+
envValue: string | undefined,
|
|
53
|
+
defaultValue: number,
|
|
54
|
+
varName: string
|
|
55
|
+
): number {
|
|
47
56
|
if (!envValue) {
|
|
48
57
|
return defaultValue
|
|
49
58
|
}
|
|
@@ -177,8 +186,8 @@ function getLogger(elasticConfig?: ElasticConfig): PinoLogger {
|
|
|
177
186
|
index: process.env.SERVER_NICKNAME,
|
|
178
187
|
node: process.env.ELASTICSEARCH_NODE,
|
|
179
188
|
auth: {
|
|
180
|
-
username: process.env.ELASTICSEARCH_USERNAME
|
|
181
|
-
password: process.env.ELASTICSEARCH_PASSWORD
|
|
189
|
+
username: process.env.ELASTICSEARCH_USERNAME,
|
|
190
|
+
password: process.env.ELASTICSEARCH_PASSWORD,
|
|
182
191
|
},
|
|
183
192
|
// Configurable flush settings
|
|
184
193
|
flushInterval: flushIntervalMs,
|
|
@@ -193,18 +202,19 @@ function getLogger(elasticConfig?: ElasticConfig): PinoLogger {
|
|
|
193
202
|
Object.assign(esConfig, elasticConfig)
|
|
194
203
|
}
|
|
195
204
|
|
|
196
|
-
// Create transport
|
|
197
|
-
|
|
198
|
-
esTransport = pinoElastic(esConfig as PinoElasticOptions)
|
|
205
|
+
// Create transport with connection lifecycle fix (pino-elasticsearch #140)
|
|
206
|
+
esTransport = createElasticTransport(esConfig)
|
|
199
207
|
|
|
200
208
|
// Handle Elasticsearch connection errors
|
|
201
|
-
esTransport.on('error', (err) => {
|
|
209
|
+
esTransport.on('error', (err: Error) => {
|
|
202
210
|
console.error('[Logger] Elasticsearch transport error:', err.message)
|
|
203
|
-
console.error(
|
|
211
|
+
console.error(
|
|
212
|
+
'[Logger] Logs may not be reaching Kibana. Check Elasticsearch connection.'
|
|
213
|
+
)
|
|
204
214
|
})
|
|
205
215
|
|
|
206
216
|
// Handle insert errors (document indexing failures)
|
|
207
|
-
esTransport.on('insertError', (err) => {
|
|
217
|
+
esTransport.on('insertError', (err: Error) => {
|
|
208
218
|
console.error('[Logger] Elasticsearch insert error:', err.message)
|
|
209
219
|
console.error('[Logger] Some logs failed to index to Elasticsearch.')
|
|
210
220
|
})
|
package/src/lib/pdf.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {AxiosInstance} from '../utilities'
|
|
1
|
+
// import { AxiosInstance } from '../utilities'
|
|
2
2
|
/*
|
|
3
3
|
Author : Mustafa Halabi https://github.com/mustafahalabi
|
|
4
4
|
Date : 2023-06-24
|
|
@@ -16,7 +16,7 @@ class Pdf {
|
|
|
16
16
|
* // => 'Hello-World'
|
|
17
17
|
* ```
|
|
18
18
|
* */
|
|
19
|
-
getBase64Images = (
|
|
19
|
+
getBase64Images = (_url: string): string => {
|
|
20
20
|
return ''
|
|
21
21
|
}
|
|
22
22
|
}
|
package/src/utilities/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {default as AxiosInstance} from './axios'
|
|
1
|
+
export { default as AxiosInstance } from './axios'
|
package/.eslintignore
DELETED
package/.eslintrc.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
plugins: ['@typescript-eslint/eslint-plugin', 'eslint-plugin-tsdoc'],
|
|
3
|
-
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
|
4
|
-
parser: '@typescript-eslint/parser',
|
|
5
|
-
parserOptions: {
|
|
6
|
-
project: './tsconfig.json',
|
|
7
|
-
tsconfigRootDir: __dirname,
|
|
8
|
-
ecmaVersion: 2018,
|
|
9
|
-
sourceType: 'module',
|
|
10
|
-
},
|
|
11
|
-
rules: {
|
|
12
|
-
'tsdoc/syntax': 'warn',
|
|
13
|
-
'@typescript-eslint/ban-ts-comment': 'off',
|
|
14
|
-
'@typescript-eslint/ban-types': 'off',
|
|
15
|
-
'@typescript-eslint/no-namespace': 'off',
|
|
16
|
-
'@typescript-eslint/no-unused-vars': [
|
|
17
|
-
'warn',
|
|
18
|
-
{
|
|
19
|
-
vars: 'all',
|
|
20
|
-
args: 'after-used',
|
|
21
|
-
ignoreRestSiblings: true,
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
|
-
'@typescript-eslint/no-explicit-any': 'off',
|
|
25
|
-
'no-async-promise-executor': 'off',
|
|
26
|
-
},
|
|
27
|
-
root: true,
|
|
28
|
-
}
|