@hestia-earth/pipeline-utils 0.13.18 → 0.13.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,128 @@
1
+ import { Db } from 'mongodb';
2
+ import { Aggregation, File, User, FileStatus, Reconciliation, Setting, SettingKey, Migration, MigrationType } from '@hestia-earth/api';
3
+ export declare const transaction: <T>(query: (db: Db) => Promise<T>, defaultValue?: T) => Promise<T>;
4
+ export declare const idsQuery: (ids: string[]) => any;
5
+ export declare const getAggregations: <U extends keyof Aggregation>(conditions: {
6
+ filename?: any;
7
+ filepath?: any;
8
+ validatedAt?: any;
9
+ status?: any;
10
+ pipelineStatus?: any;
11
+ readonly nodeType?: any;
12
+ readonly productId?: any;
13
+ readonly countryId?: any;
14
+ readonly startYear?: any;
15
+ readonly endYear?: any;
16
+ id?: any;
17
+ createdAt?: any;
18
+ updatedAt?: any;
19
+ }, props: U[], limit?: number) => Promise<Pick<Aggregation, U>[]>;
20
+ export declare const upsertAggregation: (filepath: string, data?: Partial<Aggregation>) => Promise<import("mongodb").UpdateWriteOpResult>;
21
+ export declare const removeAggregations: (ids: string[]) => Promise<import("mongodb").DeleteWriteOpResultObject>;
22
+ export declare const removeAggregationsByTerms: (termId: string | string[]) => Promise<import("mongodb").DeleteWriteOpResultObject>;
23
+ export declare const getFiles: <U extends keyof File>(conditions: {
24
+ filename?: any;
25
+ filepath?: any;
26
+ folder?: any;
27
+ user?: any;
28
+ assignedUsers?: any;
29
+ authorizedUsers?: any;
30
+ contentType?: any;
31
+ archived?: any;
32
+ status?: any;
33
+ pipelineStatus?: any;
34
+ userValidatedAt?: any;
35
+ validatedAt?: any;
36
+ schemaVersion?: any;
37
+ schemaOutdated?: any;
38
+ glossaryOutdated?: any;
39
+ comments?: any;
40
+ todos?: any;
41
+ metadata?: any;
42
+ isPrivate?: any;
43
+ skipValidation?: any;
44
+ study?: any;
45
+ fromDraft?: any;
46
+ readonly isOwner?: any;
47
+ readonly isAuthorized?: any;
48
+ readonly isAssignedToMe?: any;
49
+ readonly isValidated?: any;
50
+ readonly isDraft?: any;
51
+ readonly originalPath?: any;
52
+ readonly hestiaPath?: any;
53
+ readonly progressPath?: any;
54
+ readonly studyPath?: any;
55
+ readonly dataPath?: any;
56
+ readonly dataProgressPath?: any;
57
+ readonly dataCsvPath?: any;
58
+ readonly dataRecalculatedCsvPath?: any;
59
+ readonly logPath?: any;
60
+ readonly errorPath?: any;
61
+ id?: any;
62
+ createdAt?: any;
63
+ updatedAt?: any;
64
+ }, props: U[], limit?: number) => Promise<Pick<File, U>[]>;
65
+ export declare const getFile: (filepath: string) => Promise<Partial<File>>;
66
+ export declare const updateFile: (filepath: string, data?: Partial<File>) => Promise<import("mongodb").UpdateWriteOpResult>;
67
+ export declare const updateFiles: (ids: string[], data?: Partial<File>) => Promise<import("mongodb").UpdateWriteOpResult>;
68
+ export declare const countUserFiles: (userId: string, statuses?: FileStatus[]) => Promise<number>;
69
+ export declare const getUsers: <U extends keyof User>(conditions: {
70
+ email?: any;
71
+ firstName?: any;
72
+ lastName?: any;
73
+ displayName?: any;
74
+ password?: any;
75
+ token?: any;
76
+ role?: any;
77
+ maxUploads?: any;
78
+ maxApiCalls?: any;
79
+ dataPrivate?: any;
80
+ validFilesCount?: any;
81
+ emailNotificationsSuccess?: any;
82
+ emailNotificationsFailure?: any;
83
+ emailNotificationsFeedback?: any;
84
+ autoSubmitPrivateSubmissions?: any;
85
+ confirmToken?: any;
86
+ confirmedAt?: any;
87
+ lastActiveAt?: any;
88
+ scopusID?: any;
89
+ googleID?: any;
90
+ linkedInID?: any;
91
+ orcid?: any;
92
+ website?: any;
93
+ city?: any;
94
+ country?: any;
95
+ primaryInstitution?: any;
96
+ readonly admin?: any;
97
+ readonly name?: any;
98
+ readonly actorId?: any;
99
+ id?: any;
100
+ createdAt?: any;
101
+ updatedAt?: any;
102
+ }, props: U[], limit?: number) => Promise<Pick<User, U>[]>;
103
+ export declare const getUser: (userId: string) => Promise<Partial<User>>;
104
+ export declare const getUserFromFilepath: (filepath?: string) => Promise<Partial<User>>;
105
+ export declare const updateUser: (userId: string, data?: Partial<User>) => Promise<import("mongodb").UpdateWriteOpResult>;
106
+ export interface RawReconciliation extends Reconciliation {
107
+ _id: string;
108
+ }
109
+ export declare const getReconciliation: ({ id, ...query }?: Partial<Reconciliation> & {
110
+ id?: string;
111
+ }) => Promise<RawReconciliation>;
112
+ export declare const getReconciliations: (query?: {}, projection?: {}) => Promise<RawReconciliation[]>;
113
+ export declare const updateReconciliation: ({ id, ...query }?: Partial<Reconciliation> & {
114
+ id?: string;
115
+ }, data?: Partial<Reconciliation>) => Promise<import("mongodb").UpdateWriteOpResult>;
116
+ export declare const updateReconciliations: (data: Partial<Reconciliation>[]) => Promise<import("mongodb").BulkWriteResult>;
117
+ export declare const upsertReconciliation: (filter: Partial<Reconciliation>, data?: Partial<Reconciliation>) => Promise<import("mongodb").UpdateWriteOpResult>;
118
+ export declare const getMigrations: <U extends keyof Migration>(type: MigrationType, conditions: {
119
+ filenames?: any;
120
+ type?: any;
121
+ id?: any;
122
+ createdAt?: any;
123
+ updatedAt?: any;
124
+ }, props: U[], limit?: number) => Promise<Pick<Migration, U>[]>;
125
+ export declare const addMigration: (type: MigrationType, filenames: string[]) => Promise<import("mongodb").InsertOneWriteOpResult<any>>;
126
+ export declare const getSetting: (key: SettingKey) => Promise<Setting>;
127
+ export declare const updateSetting: (key: SettingKey, data: Partial<Setting>) => Promise<import("mongodb").UpdateWriteOpResult>;
128
+ export declare const setMaintenance: (enabled: boolean) => Promise<import("mongodb").UpdateWriteOpResult>;
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setMaintenance = exports.updateSetting = exports.getSetting = exports.addMigration = exports.getMigrations = exports.upsertReconciliation = exports.updateReconciliations = exports.updateReconciliation = exports.getReconciliations = exports.getReconciliation = exports.updateUser = exports.getUserFromFilepath = exports.getUser = exports.getUsers = exports.countUserFiles = exports.updateFiles = exports.updateFile = exports.getFile = exports.getFiles = exports.removeAggregationsByTerms = exports.removeAggregations = exports.upsertAggregation = exports.getAggregations = exports.idsQuery = exports.transaction = void 0;
4
+ const mongodb_1 = require("mongodb");
5
+ const api_1 = require("@hestia-earth/api");
6
+ const log_1 = require("./log");
7
+ const slack_1 = require("./slack");
8
+ const utils_1 = require("./utils");
9
+ const transaction = async (query, defaultValue = null) => {
10
+ try {
11
+ const client = await mongodb_1.MongoClient.connect(process.env.MONGODB_URL, {
12
+ poolSize: 1,
13
+ useUnifiedTopology: true
14
+ });
15
+ const res = await query(client.db());
16
+ await client.close();
17
+ return res;
18
+ }
19
+ catch (err) {
20
+ (0, log_1.error)(err);
21
+ return defaultValue;
22
+ }
23
+ };
24
+ exports.transaction = transaction;
25
+ const propsToProjection = (props) => Object.fromEntries(props.map(p => [p, true]));
26
+ const idsQuery = (ids) => ({ _id: { $in: ids.map(v => new mongodb_1.ObjectID(v)) } });
27
+ exports.idsQuery = idsQuery;
28
+ const getAggregations = (conditions, props, limit = 0) => (0, exports.transaction)(db => db.collection('aggregations').find(conditions).project(propsToProjection(props)).limit(limit).toArray(), []);
29
+ exports.getAggregations = getAggregations;
30
+ const upsertAggregation = (filepath, data = {}) => {
31
+ const filename = (0, api_1.filenameFromPath)(filepath);
32
+ const folder = filepath.split('/')[1];
33
+ return (0, exports.transaction)(db => db.collection('aggregations').updateOne({ filepath }, {
34
+ $set: { ...data, folder, filepath, filename, updatedAt: new Date() },
35
+ $setOnInsert: { createdAt: new Date() }
36
+ }, { upsert: true }));
37
+ };
38
+ exports.upsertAggregation = upsertAggregation;
39
+ const removeAggregations = (ids) => (0, exports.transaction)(db => db.collection('aggregations').deleteMany({
40
+ _id: { $in: ids }
41
+ }));
42
+ exports.removeAggregations = removeAggregations;
43
+ const aggregationMatchTerms = (termId) => {
44
+ const ids = Array.isArray(termId) ? termId : [termId];
45
+ return ids.map(id => `(^${api_1.aggregationFolder}\/cycle-${id}-.*)`).join('|');
46
+ };
47
+ const removeAggregationsByTerms = (termId) => (0, exports.transaction)(db => db.collection('aggregations').deleteMany({ filepath: { $regex: aggregationMatchTerms(termId) } }));
48
+ exports.removeAggregationsByTerms = removeAggregationsByTerms;
49
+ const filepathSearch = (filepath) => {
50
+ const [filename] = filepath.split('.');
51
+ return {
52
+ filepath: {
53
+ $in: Object.values(api_1.SupportedExtensions).map(ext => `${filename}.${ext}`)
54
+ }
55
+ };
56
+ };
57
+ const getFiles = (conditions, props, limit = 0) => (0, exports.transaction)(db => db.collection('files').find(conditions).project(propsToProjection(props)).limit(limit).toArray(), []);
58
+ exports.getFiles = getFiles;
59
+ const getFile = (filepath) => (0, exports.transaction)(db => db.collection('files').findOne(filepathSearch(filepath)), {});
60
+ exports.getFile = getFile;
61
+ const updateFile = (filepath, data = {}) => (0, exports.transaction)(db => db.collection('files').updateOne(filepathSearch(filepath), { $set: data }));
62
+ exports.updateFile = updateFile;
63
+ const updateFiles = (ids, data = {}) => (0, exports.transaction)(db => db.collection('files').updateMany({ _id: { $in: ids.map(id => new mongodb_1.ObjectId(id)) } }, { $set: data }));
64
+ exports.updateFiles = updateFiles;
65
+ const matchExt = (ext) => ({ filename: { $regex: new RegExp(`.${ext}$`) } });
66
+ const countUserFiles = (userId, statuses) => (0, exports.transaction)(db => db.collection('files').countDocuments({
67
+ user: new mongodb_1.ObjectId(userId),
68
+ $and: [
69
+ {
70
+ $or: [
71
+ matchExt(api_1.SupportedExtensions.json),
72
+ matchExt(api_1.SupportedExtensions.csv),
73
+ matchExt(api_1.SupportedExtensions.xls),
74
+ matchExt(api_1.SupportedExtensions.xlsx)
75
+ ].filter(Boolean)
76
+ },
77
+ (statuses === null || statuses === void 0 ? void 0 : statuses.length)
78
+ ? {
79
+ $or: statuses.map(status => ({ status }))
80
+ }
81
+ : null
82
+ ].filter(Boolean)
83
+ }));
84
+ exports.countUserFiles = countUserFiles;
85
+ const getUsers = (conditions, props, limit = 0) => (0, exports.transaction)(db => db.collection('users').find(conditions).project(propsToProjection(props)).limit(limit).toArray(), []);
86
+ exports.getUsers = getUsers;
87
+ const getUser = (userId) => (0, exports.transaction)(db => db.collection('users').findOne({ _id: new mongodb_1.ObjectId(userId) }), {});
88
+ exports.getUser = getUser;
89
+ const getUserFromFilepath = async (filepath) => {
90
+ const userId = filepath ? (0, api_1.rootFolderFromPath)(filepath) : null;
91
+ return !userId || (0, api_1.isFolderUpload)(userId) ? {} : await (0, exports.getUser)(userId);
92
+ };
93
+ exports.getUserFromFilepath = getUserFromFilepath;
94
+ const updateUser = (userId, data = {}) => (0, exports.transaction)(db => db.collection('users').updateOne({ _id: new mongodb_1.ObjectId(userId) }, { $set: data }));
95
+ exports.updateUser = updateUser;
96
+ const getReconciliation = ({ id, ...query } = { id: undefined }) => (0, exports.transaction)(db => db.collection('reconciliations').findOne({ ...(id ? { _id: new mongodb_1.ObjectId(id) } : {}), ...query }));
97
+ exports.getReconciliation = getReconciliation;
98
+ const getReconciliations = (query = {}, projection = {}) => (0, exports.transaction)(db => db.collection('reconciliations').find(query, projection).toArray(), []);
99
+ exports.getReconciliations = getReconciliations;
100
+ const updateReconciliation = ({ id, ...query } = { id: undefined }, data = {}) => (0, exports.transaction)(db => db
101
+ .collection('reconciliations')
102
+ .updateOne({ ...(id ? { _id: new mongodb_1.ObjectId(id) } : {}), ...query }, { $set: { ...data, updatedAt: new Date() } }));
103
+ exports.updateReconciliation = updateReconciliation;
104
+ const updateReconciliations = async (data) => data.length
105
+ ? await (0, exports.transaction)(db => {
106
+ const bulk = db.collection('reconciliations').initializeUnorderedBulkOp();
107
+ data.forEach(({ id, level, details, error: err }) => {
108
+ bulk.find({ _id: new mongodb_1.ObjectId(id) }).updateOne({ $set: { level, details, err, updatedAt: new Date() } });
109
+ });
110
+ return bulk.execute();
111
+ })
112
+ : null;
113
+ exports.updateReconciliations = updateReconciliations;
114
+ const upsertReconciliation = (filter, data = {}) => (0, exports.transaction)(db => db
115
+ .collection('reconciliations')
116
+ .updateOne(filter, { $set: { ...data, updatedAt: new Date() }, $setOnInsert: { createdAt: new Date() } }, { upsert: true }));
117
+ exports.upsertReconciliation = upsertReconciliation;
118
+ const getMigrations = (type, conditions, props, limit = 0) => (0, exports.transaction)(db => db
119
+ .collection('migrations')
120
+ .find({
121
+ ...conditions,
122
+ type
123
+ })
124
+ .project(propsToProjection(props))
125
+ .limit(limit)
126
+ .toArray(), []);
127
+ exports.getMigrations = getMigrations;
128
+ const addMigration = (type, filenames) => (0, exports.transaction)(db => db.collection('migrations').insertOne({
129
+ type,
130
+ filenames,
131
+ createdAt: new Date(),
132
+ updatedAt: new Date()
133
+ }));
134
+ exports.addMigration = addMigration;
135
+ const getSetting = (key) => (0, exports.transaction)(db => db.collection('settings').findOne({ key }));
136
+ exports.getSetting = getSetting;
137
+ const updateSetting = (key, data) => (0, exports.transaction)(db => db.collection('settings').updateOne({ key }, { $set: data }, { upsert: true }));
138
+ exports.updateSetting = updateSetting;
139
+ const maintenanceMessage = {
140
+ true: 'Server is under maintenance, please do not use API or Website',
141
+ false: 'Maintenance ended'
142
+ };
143
+ const setMaintenance = async (enabled) => {
144
+ var _a;
145
+ const message = maintenanceMessage[`${enabled}`];
146
+ const fullMessage = `
147
+ ${message}
148
+
149
+ *API*: ${utils_1.baseUrl.replace('www', 'api')}
150
+ *Website*: ${utils_1.baseUrl}
151
+ `.trim();
152
+ const setting = await (0, exports.getSetting)(api_1.SettingKey.maintenanceEnabled);
153
+ const existingThread = setting ? (_a = setting.metadata) === null || _a === void 0 ? void 0 : _a.slackThreadTs : null;
154
+ const ts = enabled
155
+ ?
156
+ await (0, slack_1.sendMessage)({ text: fullMessage })
157
+ : existingThread
158
+ ?
159
+ await (0, slack_1.replyMessage)(existingThread, { text: message })
160
+ :
161
+ null;
162
+ return await (0, exports.updateSetting)(api_1.SettingKey.maintenanceEnabled, {
163
+ value: enabled,
164
+ metadata: { slackThreadTs: enabled ? ts : null }
165
+ });
166
+ };
167
+ exports.setMaintenance = setMaintenance;
168
+ //# sourceMappingURL=mongodb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongodb.js","sourceRoot":"","sources":["../src/mongodb.ts"],"names":[],"mappings":"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"}
package/dist/s3.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
+ /// <reference types="node" />
3
4
  import * as AWS from 'aws-sdk';
4
5
  import { Observable } from 'rxjs';
5
6
  export declare const isS3Mode: boolean;
@@ -0,0 +1,4 @@
1
+ import { ChatPostMessageArguments } from '@slack/web-api';
2
+ export declare const errorsChannel: string;
3
+ export declare const sendMessage: (args: Omit<ChatPostMessageArguments, 'channel'>, timeout?: number) => Promise<string>;
4
+ export declare const replyMessage: (thread_ts: string, args: Omit<ChatPostMessageArguments, 'channel' | 'thread_ts'>) => Promise<string>;
package/dist/slack.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.replyMessage = exports.sendMessage = exports.errorsChannel = void 0;
4
+ const web_api_1 = require("@slack/web-api");
5
+ const token = process.env.SLACK_TOKEN;
6
+ const channel = process.env.SLACK_CHANNEL;
7
+ exports.errorsChannel = process.env.SLACK_CHANNEL_ERRORS;
8
+ const sendMessage = async (args, timeout = 0) => {
9
+ const client = new web_api_1.WebClient(token, {
10
+ retryConfig: { retries: 0 },
11
+ timeout: Math.max(timeout, 3000)
12
+ });
13
+ return (await client.chat.postMessage({
14
+ channel,
15
+ link_names: true,
16
+ ...args
17
+ })).ts;
18
+ };
19
+ exports.sendMessage = sendMessage;
20
+ const replyMessage = async (thread_ts, args) => thread_ts ? await (0, exports.sendMessage)({ thread_ts, ...args }) : null;
21
+ exports.replyMessage = replyMessage;
22
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":";;;AAAA,4CAAqE;AAErE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;AACtC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AAC7B,QAAA,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;AAEvD,MAAM,WAAW,GAAG,KAAK,EAAE,IAA+C,EAAE,OAAO,GAAG,CAAC,EAAE,EAAE;IAChG,MAAM,MAAM,GAAG,IAAI,mBAAS,CAAC,KAAK,EAAE;QAClC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;QAC3B,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;KACjC,CAAC,CAAC;IACH,OAAO,CACL,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;QAC5B,OAAO;QACP,UAAU,EAAE,IAAI;QAChB,GAAG,IAAI;KACD,CAAC,CACV,CAAC,EAAE,CAAC;AACP,CAAC,CAAC;AAZW,QAAA,WAAW,eAYtB;AAEK,MAAM,YAAY,GAAG,KAAK,EAAE,SAAiB,EAAE,IAA6D,EAAE,EAAE,CACrH,SAAS,CAAC,CAAC,CAAC,MAAM,IAAA,mBAAW,EAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AADlD,QAAA,YAAY,gBACsC"}
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { S3EventRecord, SNSEventRecord } from 'aws-lambda';
2
2
  import { IFunctionParam } from './s3';
3
+ export declare const baseUrl: string;
3
4
  export declare const recordToFunctionParam: (event: SNSEventRecord | S3EventRecord) => IFunctionParam;
4
5
  export declare const functionParamToS3Record: ({ bucket, key, timestamp }: IFunctionParam) => Partial<S3EventRecord>;
5
6
  export declare const functionParamToSNSRecord: ({ bucket, key, timestamp }: IFunctionParam) => Partial<SNSEventRecord>;
package/dist/utils.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.byteSize = exports.stripBOM = exports.prependWithKey = exports.refToSchemaType = exports.isEmpty = exports.spliceAndProcess = exports.returnError = exports.returnResponse = exports.functionParamToSNSRecord = exports.functionParamToS3Record = exports.recordToFunctionParam = void 0;
3
+ exports.byteSize = exports.stripBOM = exports.prependWithKey = exports.refToSchemaType = exports.isEmpty = exports.spliceAndProcess = exports.returnError = exports.returnResponse = exports.functionParamToSNSRecord = exports.functionParamToS3Record = exports.recordToFunctionParam = exports.baseUrl = void 0;
4
4
  const utils_1 = require("@hestia-earth/utils");
5
5
  const log_1 = require("./log");
6
+ exports.baseUrl = process.env.DOMAIN || '';
6
7
  const recordToFunctionParam = (event) => (0, utils_1.reduceUndefinedValues)('Sns' in event
7
8
  ? {
8
9
  ...JSON.parse(event.Sns.Message),
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hestia-earth/pipeline-utils",
3
- "version": "0.13.18",
3
+ "version": "0.13.19",
4
4
  "description": "Utilities for running pipelines",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -29,11 +29,14 @@
29
29
  "homepage": "https://gitlab.com/hestia-earth/hestia-pipeline-utils#readme",
30
30
  "dependencies": {
31
31
  "@elastic/elasticsearch": "7.13.0",
32
- "aws-sdk": "^2.1302.0",
32
+ "@slack/web-api": "^7.7.0",
33
+ "aws-sdk": "^2.1692.0",
33
34
  "axios": "^1.4.0",
35
+ "bson": "^4.7.2",
34
36
  "lodash.get": "^4.4.0",
35
37
  "lodash.pick": "^4.4.0",
36
38
  "memory-cache": "^0.2.0",
39
+ "mongodb": "^3.7.4",
37
40
  "rxjs": "^6.6.7"
38
41
  },
39
42
  "peerDependencies": {
@@ -55,7 +58,8 @@
55
58
  "@types/lodash.get": "^4.4.9",
56
59
  "@types/lodash.pick": "^4.4.9",
57
60
  "@types/mocha": "^10.0.6",
58
- "@types/node": "^16.18.68",
61
+ "@types/mongodb": "^3.6.20",
62
+ "@types/node": "^18.19.64",
59
63
  "@typescript-eslint/eslint-plugin": "^5.62.0",
60
64
  "@typescript-eslint/parser": "^5.62.0",
61
65
  "chai": "^4.3.10",
package/src/mongodb.ts ADDED
@@ -0,0 +1,278 @@
1
+ import { MongoClient, Db, ObjectId, ObjectID } from 'mongodb';
2
+ import {
3
+ Aggregation,
4
+ File,
5
+ User,
6
+ SupportedExtensions,
7
+ rootFolderFromPath,
8
+ isFolderUpload,
9
+ FileStatus,
10
+ Reconciliation,
11
+ filenameFromPath,
12
+ aggregationFolder,
13
+ Setting,
14
+ SettingKey,
15
+ Migration,
16
+ MigrationType
17
+ } from '@hestia-earth/api';
18
+
19
+ import { error } from './log';
20
+ import { sendMessage, replyMessage } from './slack';
21
+ import { baseUrl } from './utils';
22
+
23
+ export const transaction = async <T>(query: (db: Db) => Promise<T>, defaultValue: T = null) => {
24
+ try {
25
+ const client = await MongoClient.connect(process.env.MONGODB_URL, {
26
+ poolSize: 1,
27
+ useUnifiedTopology: true
28
+ });
29
+ const res = await query(client.db());
30
+ await client.close();
31
+ return res;
32
+ } catch (err) {
33
+ error(err);
34
+ return defaultValue;
35
+ }
36
+ };
37
+
38
+ const propsToProjection = <T>(props: T[]) => Object.fromEntries(props.map(p => [p, true]));
39
+
40
+ export const idsQuery = (ids: string[]): any => ({ _id: { $in: ids.map(v => new ObjectID(v)) } });
41
+
42
+ // --- Aggregations
43
+
44
+ export const getAggregations = <U extends keyof Aggregation>(
45
+ conditions: { [key in keyof Partial<Aggregation>]: any },
46
+ props: U[],
47
+ limit = 0
48
+ ): Promise<Pick<Aggregation, U>[]> =>
49
+ transaction(
50
+ db => db.collection('aggregations').find(conditions).project(propsToProjection(props)).limit(limit).toArray(),
51
+ [] as Pick<Aggregation, U>[]
52
+ );
53
+
54
+ export const upsertAggregation = (filepath: string, data: Partial<Aggregation> = {}) => {
55
+ const filename = filenameFromPath(filepath);
56
+ const folder = filepath.split('/')[1];
57
+ return transaction(db =>
58
+ db.collection('aggregations').updateOne(
59
+ { filepath },
60
+ {
61
+ $set: { ...data, folder, filepath, filename, updatedAt: new Date() },
62
+ $setOnInsert: { createdAt: new Date() }
63
+ },
64
+ { upsert: true }
65
+ )
66
+ );
67
+ };
68
+
69
+ export const removeAggregations = (ids: string[]) =>
70
+ transaction(db =>
71
+ db.collection('aggregations').deleteMany({
72
+ _id: { $in: ids }
73
+ })
74
+ );
75
+
76
+ const aggregationMatchTerms = (termId: string | string[]) => {
77
+ const ids = Array.isArray(termId) ? termId : [termId];
78
+ return ids.map(id => `(^${aggregationFolder}\/cycle-${id}-.*)`).join('|');
79
+ };
80
+
81
+ export const removeAggregationsByTerms = (termId: string | string[]) =>
82
+ transaction(db => db.collection('aggregations').deleteMany({ filepath: { $regex: aggregationMatchTerms(termId) } }));
83
+
84
+ // --- Files
85
+
86
+ const filepathSearch = (filepath: string) => {
87
+ const [filename] = filepath.split('.');
88
+ return {
89
+ filepath: {
90
+ $in: Object.values(SupportedExtensions).map(ext => `${filename}.${ext}`)
91
+ }
92
+ };
93
+ };
94
+
95
+ export const getFiles = <U extends keyof File>(
96
+ conditions: { [key in keyof Partial<File>]: any },
97
+ props: U[],
98
+ limit = 0
99
+ ): Promise<Pick<File, U>[]> =>
100
+ transaction(
101
+ db => db.collection('files').find(conditions).project(propsToProjection(props)).limit(limit).toArray(),
102
+ [] as Pick<File, U>[]
103
+ );
104
+
105
+ export const getFile = (filepath: string): Promise<Partial<File>> =>
106
+ transaction(db => db.collection('files').findOne(filepathSearch(filepath)), {} as Partial<File>);
107
+
108
+ export const updateFile = (filepath: string, data: Partial<File> = {}) =>
109
+ transaction(db => db.collection('files').updateOne(filepathSearch(filepath), { $set: data }));
110
+
111
+ export const updateFiles = (ids: string[], data: Partial<File> = {}) =>
112
+ transaction(db =>
113
+ db.collection('files').updateMany({ _id: { $in: ids.map(id => new ObjectId(id)) } }, { $set: data })
114
+ );
115
+
116
+ const matchExt = (ext: SupportedExtensions) => ({ filename: { $regex: new RegExp(`.${ext}$`) } });
117
+
118
+ export const countUserFiles = (userId: string, statuses?: FileStatus[]) =>
119
+ transaction(db =>
120
+ db.collection('files').countDocuments({
121
+ user: new ObjectId(userId),
122
+ $and: [
123
+ {
124
+ $or: [
125
+ matchExt(SupportedExtensions.json),
126
+ matchExt(SupportedExtensions.csv),
127
+ matchExt(SupportedExtensions.xls),
128
+ matchExt(SupportedExtensions.xlsx)
129
+ ].filter(Boolean)
130
+ },
131
+ statuses?.length
132
+ ? {
133
+ $or: statuses.map(status => ({ status }))
134
+ }
135
+ : null
136
+ ].filter(Boolean)
137
+ })
138
+ );
139
+
140
+ // --- Users
141
+
142
+ export const getUsers = <U extends keyof User>(
143
+ conditions: { [key in keyof Partial<User>]: any },
144
+ props: U[],
145
+ limit = 0
146
+ ): Promise<Pick<User, U>[]> =>
147
+ transaction(
148
+ db => db.collection('users').find(conditions).project(propsToProjection(props)).limit(limit).toArray(),
149
+ [] as Pick<User, U>[]
150
+ );
151
+
152
+ export const getUser = (userId: string): Promise<Partial<User>> =>
153
+ transaction(db => db.collection('users').findOne({ _id: new ObjectId(userId) }), {} as Partial<User>);
154
+
155
+ export const getUserFromFilepath = async (filepath?: string) => {
156
+ const userId = filepath ? rootFolderFromPath(filepath) : null;
157
+ return !userId || isFolderUpload(userId) ? ({} as Partial<User>) : await getUser(userId);
158
+ };
159
+
160
+ export const updateUser = (userId: string, data: Partial<User> = {}) =>
161
+ transaction(db => db.collection('users').updateOne({ _id: new ObjectId(userId) }, { $set: data }));
162
+
163
+ // --- Reconciliation
164
+
165
+ export interface RawReconciliation extends Reconciliation {
166
+ _id: string;
167
+ }
168
+
169
+ export const getReconciliation = (
170
+ { id, ...query }: Partial<Reconciliation> & { id?: string } = { id: undefined }
171
+ ): Promise<RawReconciliation> =>
172
+ transaction(db => db.collection('reconciliations').findOne({ ...(id ? { _id: new ObjectId(id) } : {}), ...query }));
173
+
174
+ export const getReconciliations = (query = {}, projection = {}): Promise<RawReconciliation[]> =>
175
+ transaction(db => db.collection('reconciliations').find(query, projection).toArray(), []);
176
+
177
+ export const updateReconciliation = (
178
+ { id, ...query }: Partial<Reconciliation> & { id?: string } = { id: undefined },
179
+ data: Partial<Reconciliation> = {}
180
+ ) =>
181
+ transaction(db =>
182
+ db
183
+ .collection('reconciliations')
184
+ .updateOne({ ...(id ? { _id: new ObjectId(id) } : {}), ...query }, { $set: { ...data, updatedAt: new Date() } })
185
+ );
186
+
187
+ export const updateReconciliations = async (data: Partial<Reconciliation>[]) =>
188
+ data.length
189
+ ? await transaction(db => {
190
+ const bulk = db.collection('reconciliations').initializeUnorderedBulkOp();
191
+
192
+ data.forEach(({ id, level, details, error: err }) => {
193
+ bulk.find({ _id: new ObjectId(id) }).updateOne({ $set: { level, details, err, updatedAt: new Date() } });
194
+ });
195
+ return bulk.execute();
196
+ })
197
+ : null;
198
+
199
+ export const upsertReconciliation = (filter: Partial<Reconciliation>, data: Partial<Reconciliation> = {}) =>
200
+ transaction(db =>
201
+ db
202
+ .collection('reconciliations')
203
+ .updateOne(
204
+ filter,
205
+ { $set: { ...data, updatedAt: new Date() }, $setOnInsert: { createdAt: new Date() } },
206
+ { upsert: true }
207
+ )
208
+ );
209
+
210
+ // --- Migrations
211
+
212
+ export const getMigrations = <U extends keyof Migration>(
213
+ type: MigrationType,
214
+ conditions: { [key in keyof Partial<Migration>]: any },
215
+ props: U[],
216
+ limit = 0
217
+ ): Promise<Pick<Migration, U>[]> =>
218
+ transaction(
219
+ db =>
220
+ db
221
+ .collection('migrations')
222
+ .find({
223
+ ...conditions,
224
+ type
225
+ })
226
+ .project(propsToProjection(props))
227
+ .limit(limit)
228
+ .toArray(),
229
+ [] as Pick<Migration, U>[]
230
+ );
231
+
232
+ export const addMigration = (type: MigrationType, filenames: string[]) =>
233
+ transaction(db =>
234
+ db.collection('migrations').insertOne({
235
+ type,
236
+ filenames,
237
+ createdAt: new Date(),
238
+ updatedAt: new Date()
239
+ })
240
+ );
241
+
242
+ // --- Settings
243
+
244
+ export const getSetting = (key: SettingKey): Promise<Setting> =>
245
+ transaction(db => db.collection('settings').findOne({ key }));
246
+
247
+ export const updateSetting = (key: SettingKey, data: Partial<Setting>) =>
248
+ transaction(db => db.collection('settings').updateOne({ key }, { $set: data }, { upsert: true }));
249
+
250
+ const maintenanceMessage = {
251
+ true: 'Server is under maintenance, please do not use API or Website',
252
+ false: 'Maintenance ended'
253
+ };
254
+
255
+ export const setMaintenance = async (enabled: boolean) => {
256
+ const message = maintenanceMessage[`${enabled}`];
257
+ const fullMessage = `
258
+ ${message}
259
+
260
+ *API*: ${baseUrl.replace('www', 'api')}
261
+ *Website*: ${baseUrl}
262
+ `.trim();
263
+ const setting = await getSetting(SettingKey.maintenanceEnabled);
264
+ const existingThread = setting ? setting.metadata?.slackThreadTs : null;
265
+ const ts = enabled
266
+ ? // setting is turned on, create new thread
267
+ await sendMessage({ text: fullMessage })
268
+ : existingThread
269
+ ? // setting is turned off and thread exists, reply to it
270
+ await replyMessage(existingThread, { text: message })
271
+ : // setting is turned off and no thread exists, ignore
272
+ null;
273
+
274
+ return await updateSetting(SettingKey.maintenanceEnabled, {
275
+ value: enabled,
276
+ metadata: { slackThreadTs: enabled ? ts : null }
277
+ });
278
+ };
package/src/slack.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { WebClient, ChatPostMessageArguments } from '@slack/web-api';
2
+
3
+ const token = process.env.SLACK_TOKEN;
4
+ const channel = process.env.SLACK_CHANNEL;
5
+ export const errorsChannel = process.env.SLACK_CHANNEL_ERRORS;
6
+
7
+ export const sendMessage = async (args: Omit<ChatPostMessageArguments, 'channel'>, timeout = 0) => {
8
+ const client = new WebClient(token, {
9
+ retryConfig: { retries: 0 },
10
+ timeout: Math.max(timeout, 3000)
11
+ });
12
+ return (
13
+ await client.chat.postMessage({
14
+ channel,
15
+ link_names: true,
16
+ ...args
17
+ } as any)
18
+ ).ts;
19
+ };
20
+
21
+ export const replyMessage = async (thread_ts: string, args: Omit<ChatPostMessageArguments, 'channel' | 'thread_ts'>) =>
22
+ thread_ts ? await sendMessage({ thread_ts, ...args }) : null;
package/src/utils.ts CHANGED
@@ -4,6 +4,8 @@ import { reduceUndefinedValues } from '@hestia-earth/utils';
4
4
  import { IFunctionParam } from './s3';
5
5
  import { error } from './log';
6
6
 
7
+ export const baseUrl = process.env.DOMAIN || '';
8
+
7
9
  export const recordToFunctionParam = (event: SNSEventRecord | S3EventRecord): IFunctionParam =>
8
10
  reduceUndefinedValues(
9
11
  'Sns' in event